--- np2/i386c/ia32/paging.c 2011/12/16 09:05:42 1.33 +++ np2/i386c/ia32/paging.c 2012/01/23 06:01:44 1.38 @@ -28,25 +28,25 @@ #include "ia32.mcr" /* - * ¡¦¥ì¡£¥·¡¦¥¯¡¦¥æ¡¦¥¥¡¦ö§¥Í¥Û浡¼ + * åãÔ妾å⥯åãÊ夫å㥩åã°æ¥»¶ç¡¢ * - * 4-31: ͽÌóºÑ¤ß - * 3: RSVD: 0 = ¥Õ¥©¥ë¥È¤Î¸¶°ø¤ÏͽÌó¥Ó¥Ã¥È°ãÈ¿¤Ç¤Ï¤Ê¤«¤Ã¤¿¡¥ - * 1 = ¥Ú¡¼¥¸¡¦¥Õ¥©¥ë¥È¤Î¸¶°ø¤Ï¡¤°ãÈ¿¤È¥Þ¡¼¥¯¤µ¤ì¤¿ PTE ¤Þ¤¿¤Ï - * PDE ¤ÎͽÌó¥Ó¥Ã¥È°ÌÃ֤Τ¦¤Á°ì¤Ä¤Ç¡¤1 ¤¬¸¡½Ð¤µ¤ì¤¿¤³¤È¤Ç¤¢¤ë¡¥ - * 2: U/S: 0 = ¥Õ¥©¥ë¥È¤Î¸¶°ø¤È¤Ê¤Ã¤¿¥¢¥¯¥»¥¹¤Ï¥×¥í¥»¥Ã¥µ¤¬¥¹¡¼¥Ñ¥Ð¥¤¥¶¡¦ - * ¥â¡¼¥É¤Ç¼Â¹ÔÃæ¤Ë¹Ô¤ï¤ì¤¿¡¥ - * 1 = ¥Õ¥©¥ë¥È¤Î¸¶°ø¤È¤Ê¤Ã¤¿¥¢¥¯¥»¥¹¤Ï¥×¥í¥»¥Ã¥µ¤¬¥æ¡¼¥¶¡¦¥â¡¼¥É¤Ç - * ¼Â¹ÔÃæ¤Ë¹Ô¤ï¤ì¤¿¡¥ - * 1: W/R: 0 = ¥Õ¥©¥ë¥È¤Î¸¶°ø¤È¤Ê¤Ã¤¿¥¢¥¯¥»¥¹¤¬ÆÉ¤ß¼è¤ê¤Ç¤¢¤Ã¤¿¡¥ - * 1 = ¥Õ¥©¥ë¥È¤Î¸¶°ø¤È¤Ê¤Ã¤¿¥¢¥¯¥»¥¹¤¬½ñ¤­¹þ¤ß¤Ç¤¢¤Ã¤¿¡¥ - * 0: P: 0 = ¥Õ¥©¥ë¥È¤Î¸¶°ø¤¬ÉԺߥڡ¼¥¸¤Ç¤¢¤Ã¤¿¡¥ - * 1 = ¥Õ¥©¥ë¥È¤Î¸¶°ø¤¬¥Ú¡¼¥¸¡¦¥ì¥Ù¥ëÊݸî°ãÈ¿¤Ç¤¢¤Ã¤¿¡¥ + * 4-31: äººÑ¤ß + * 3: RSVD: 0 = ¥Õ¥©¥ë¥È¤Î¸¶°ø¤ÏͽÌó¥Ó¥Ã¥È°ãÈ¿¤Ç¤Ï¤Ê¤«¤Ã¤¿¡¥ + * 1 = ¥Ú¡¼¥¸¡¦¥Õ¥©¥ë¥È¤Î¸¶°ø¤Ï¡¤°ãÈ¿¤È¥Þ¡¼¥¯¤µ¤ì¤¿ PTE ¤Þ¤¿¤Ï + * PDE ¤ÎͽÌó¥Ó¥Ã¥È°ÌÃ֤Τ¦¤Á°ì¤Ä¤Ç¡¤1 ¤¬¸¡½Ð¤µ¤ì¤¿¤³¤È¤Ç¤¢¤ë¡¥ + * 2: U/S: 0 = ¥Õ¥©¥ë¥È¤Î¸¶°ø¤È¤Ê¤Ã¤¿¥¢¥¯¥»¥¹¤Ï¥×¥í¥»¥Ã¥µ¤¬¥¹¡¼¥Ñ¥Ð¥¤¥¶¡¦ + * ¥â¡¼¥É¤Ç¼Â¹ÔÃæ¤Ë¹Ô¤ï¤ì¤¿¡¥ + * 1 = ¥Õ¥©¥ë¥È¤Î¸¶°ø¤È¤Ê¤Ã¤¿¥¢¥¯¥»¥¹¤Ï¥×¥í¥»¥Ã¥µ¤¬¥æ¡¼¥¶¡¦¥â¡¼¥É¤Ç + * ¼Â¹ÔÃæ¤Ë¹Ô¤ï¤ì¤¿¡¥ + * 1: W/R: 0 = ¥Õ¥©¥ë¥È¤Î¸¶°ø¤È¤Ê¤Ã¤¿¥¢¥¯¥»¥¹¤¬ÆÉ¤ß¼è¤ê¤Ç¤¢¤Ã¤¿¡¥ + * 1 = ¥Õ¥©¥ë¥È¤Î¸¶°ø¤È¤Ê¤Ã¤¿¥¢¥¯¥»¥¹¤¬½ñ¤­¹þ¤ß¤Ç¤¢¤Ã¤¿¡¥ + * 0: P: 0 = ¥Õ¥©¥ë¥È¤Î¸¶°ø¤¬ÉԺߥڡ¼¥¸¤Ç¤¢¤Ã¤¿¡¥ + * 1 = ¥Õ¥©¥ë¥È¤Î¸¶°ø¤¬¥Ú¡¼¥¸¡¦¥ì¥Ù¥ëÊݸî°ãÈ¿¤Ç¤¢¤Ã¤¿¡¥ */ /* - * ²¼´¬ 4.12. ¥Ú¡¼¥¸Êݸî¤È¥»¥°¥á¥ó¥ÈÊݸî¤ÎÁȤ߹ç¤ï¤» - * ¡Öɽ 4-2. ¥Ú¡¼¥¸¡¦¥Ç¥£¥ì¥¯¥È¥ê¤È¥Ú¡¼¥¸¡¦¥Æ¡¼¥Ö¥ë¤ÎÊݸî¤ÎÁȤ߹ç¤ï¤»¡× + * ä¸ 4.12. ¥Ú¡¼¥¸Êݸî¤È¥»¥°¥á¥ó¥ÈÊݸî¤ÎÁȤ߹ç¤ï¤» + * ¡Öɽ 4-2. ¥Ú¡¼¥¸¡¦¥Ç¥£¥ì¥¯¥È¥ê¤È¥Ú¡¼¥¸¡¦¥Æ¡¼¥Ö¥ë¤ÎÊݸî¤ÎÁȤ߹ç¤ï¤»¡× * * +------------+------------+------------+ * | PDE | PTE | merge | @@ -71,11 +71,11 @@ * | s | rw | s | rw | s | rw | * +-----+------+-----+------+-----+------+ * - * ¡Ö¥£ rw/p : CR0 ¡¢¥Û WP ¡¦¥â¡¦¥Æ¡¦¥Í¡¢¥ã ON ¡¢¥Û¥»ø»î¦¥Ò¡¢¥Þ ro + * ãॵ rw/p : CR0 åá¥ç WP åãÆå¥ãåã°å¡ì ON åá¥çꢥ¨éð°å¢­åá¥Ã ro */ /* - * ¡¦â§ä§ô§¡Ö¡¦¥Ã¡¦¥µ¡¦¥±/PxE(¥»ê·¥å¥µ¥¤¥»¥Í)/CPL/CR0 ¡¢¥Í¡¦¥ì¡£¥·¡¦¥¯¡¦¡Ö¡¦¥Ã¡¦¥µ¡¦¥±¥¯¡Ö¡¢¥Û¥¨¥ê¥­¥¯ + * åã¡£åã¡Öå㥧åâ¡Öåâ¥Ãå⥵å⥱/PxE(躴ꥣÐç½âí奡)/CPL/CR0 åᥣåãÔ妾å⥯åâ¡Öåâ¥Ãå⥵å⥱쪥¥åá¥çñö¡ÖèÁ * * +-----+-----+-----+-----+-----+---+ * | CR0 | CPL | PxE | PxE | ope | | @@ -155,17 +155,17 @@ static const UINT8 page_access_bit[32] = /* *-- - * 32bit ʪÍý¥¢¥É¥ì¥¹ 4k ¥Ú¡¼¥¸ + * 32bit í饥íð¬å¤¤åã²å¦®å⥱ 4k åãÔ妾å⥯ * - * ¡¦ô§¥Ò¡¦¡Ö¡£¥ò¡¦¡Ö¡¦¥Î¡¦ø§¥± + * å㥧åã¶å¤¤å㥵åâ¡Öåã²å¦®å⥱ * 31 22 21 12 11 0 * +------------------------+----------------------+--------------------------+ - * | ¡¦¥ì¡£¥·¡¦¥¯¡£¥ò¡¦¥Ì¡¦¡×¡¦ø§¥Ã¡¦¥Í¡¦ | ¥Ú¡¼¥¸¡¦¥Æ¡¼¥Ö¥ë | ¥ª¥Õ¥»¥Ã¥È | + * | åãÔ妾å⥯å㥵åã®å¤¥åã¥ãåâ¥Ãåã°å¦¬ | åãÔ妾å⥯å㥵åã¬å¦¾åãÌ妭 | å⥧åãÊ夽åã¦å¥è | * +------------------------+----------------------+--------------------------+ * | | | * +-----------+ +-----------+ +----------+ * | | | - * | ¡¦¥ì¡£¥·¡¦¥¯¡£¥ò¡¦¥Ì¡¦¡×¡¦ø§¥Ã¡¦¥Í¡¦ | ¥Ú¡¼¥¸¡¦¥Æ¡¼¥Ö¥ë ¥Ú¡¼¥¸ | + * | ¥Ú¡¼¥¸¡¦¥Ç¥£¥ì¥¯¥È¥ê | ¥Ú¡¼¥¸¡¦¥Æ¡¼¥Ö¥ë ¥Ú¡¼¥¸ | * | +--------------------+ | +-------------------+ +------------------+ | * | | | | | | | | | * | | | | +-------------------+ | | | @@ -177,412 +177,654 @@ static const UINT8 page_access_bit[32] = * | | | | | | | | * +>+--------------------+ +>+-------------------+ +>+------------------+ * | - * +- CR3() + * +- CR3(ʪÍý¥¢¥É¥ì¥¹) */ -static UINT32 MEMCALL paging(const UINT32 laddr, const int ucrw); -static void MEMCALL tlb_update(const UINT32 laddr, const UINT entry, const int ucrw); +/* TLB */ +struct tlb_entry { + UINT32 tag; /* linear address */ +#define TLB_ENTRY_TAG_VALID (1 << 0) +/* pde & pte & CPU_PTE_WRITABLE (1 << 1) */ +/* pde & pte & CPU_PTE_USER_MODE (1 << 2) */ +#define TLB_ENTRY_TAG_DIRTY CPU_PTE_DIRTY /* (1 << 6) */ +#define TLB_ENTRY_TAG_GLOBAL CPU_PTE_GLOBAL_PAGE /* (1 << 8) */ +#define TLB_ENTRY_TAG_MAX_SHIFT 12 + UINT32 paddr; /* physical address */ +}; +static void MEMCALL tlb_update(UINT32 laddr, UINT entry, int ucrw); -#define PAGE_SIZE 0x1000 -#define PAGE_MASK (PAGE_SIZE - 1) +/* paging */ +static UINT32 MEMCALL paging(UINT32 laddr, int ucrw); +/* + * linear memory access + */ +/* RMW */ UINT8 MEMCALL -cpu_memory_access_la_RMW_b(UINT32 laddr, UINT32 (*func)(UINT32, void *), void *arg) +cpu_memory_access_la_RMW_b(UINT32 laddr, UINT32 (CPUCALL *func)(UINT32, void *), void *arg) { - const int ucrw = CPU_PAGE_WRITE_DATA|CPU_STAT_USER_MODE; - UINT32 result, value; + const int ucrw = CPU_PAGE_WRITE_DATA | CPU_STAT_USER_MODE; + struct tlb_entry *ep; UINT32 paddr; + UINT32 result; + UINT8 value; + + /* TLB */ + ep = tlb_lookup(laddr, ucrw); + if (ep != NULL) { + paddr = ep->paddr + (laddr & CPU_PAGE_MASK); + goto onepage; + } + /* paging */ paddr = paging(laddr, ucrw); +onepage: value = cpu_memoryread(paddr); result = (*func)(value, arg); cpu_memorywrite(paddr, (UINT8)result); - return value; } UINT16 MEMCALL -cpu_memory_access_la_RMW_w(UINT32 laddr, UINT32 (*func)(UINT32, void *), void *arg) +cpu_memory_access_la_RMW_w(UINT32 laddr, UINT32 (CPUCALL *func)(UINT32, void *), void *arg) { - const int ucrw = CPU_PAGE_WRITE_DATA|CPU_STAT_USER_MODE; - UINT32 result, value; + const int ucrw = CPU_PAGE_WRITE_DATA | CPU_STAT_USER_MODE; + struct tlb_entry *ep[2]; UINT32 paddr[2]; + UINT32 result; + UINT16 value; + + /* TLB */ + ep[0] = tlb_lookup(laddr, ucrw); + if (ep[0] != NULL) { + paddr[0] = ep[0]->paddr + (laddr & CPU_PAGE_MASK); + if ((laddr + 1) & CPU_PAGE_MASK) + goto onepage; + + ep[1] = tlb_lookup(laddr + 1, ucrw); + if (ep[1] != NULL) { + paddr[1] = ep[1]->paddr + (laddr & CPU_PAGE_MASK); + goto separate; + } + } + /* paging */ paddr[0] = paging(laddr, ucrw); - if ((laddr + 1) & PAGE_MASK) { + if ((laddr + 1) & CPU_PAGE_MASK) { +onepage: value = cpu_memoryread_w(paddr[0]); result = (*func)(value, arg); cpu_memorywrite_w(paddr[0], (UINT16)result); - } else { - paddr[1] = paging(laddr + 1, ucrw); - value = cpu_memoryread_b(paddr[0]); - value += (UINT16)cpu_memoryread_b(paddr[1]) << 8; - result = (*func)(value, arg); - cpu_memorywrite(paddr[0], (UINT8)result); - cpu_memorywrite(paddr[1], (UINT8)(result >> 8)); + return value; } + + paddr[1] = paging(laddr + 1, ucrw); +separate: + value = cpu_memoryread_b(paddr[0]); + value += (UINT16)cpu_memoryread_b(paddr[1]) << 8; + result = (*func)(value, arg); + cpu_memorywrite(paddr[0], (UINT8)result); + cpu_memorywrite(paddr[1], (UINT8)(result >> 8)); return value; } UINT32 MEMCALL -cpu_memory_access_la_RMW_d(UINT32 laddr, UINT32 (*func)(UINT32, void *), void *arg) +cpu_memory_access_la_RMW_d(UINT32 laddr, UINT32 (CPUCALL *func)(UINT32, void *), void *arg) { - const int ucrw = CPU_PAGE_WRITE_DATA|CPU_STAT_USER_MODE; - UINT32 result, value; + const int ucrw = CPU_PAGE_WRITE_DATA | CPU_STAT_USER_MODE; + struct tlb_entry *ep[2]; UINT32 paddr[2]; - UINT remain; + UINT32 result; + UINT32 value; + int remain; + + /* TLB */ + ep[0] = tlb_lookup(laddr, ucrw); + if (ep[0] != NULL) { + paddr[0] = ep[0]->paddr + (laddr & CPU_PAGE_MASK); + remain = CPU_PAGE_SIZE - (laddr & CPU_PAGE_MASK); + if (remain >= 4) + goto onepage; + + ep[1] = tlb_lookup(laddr + remain, ucrw); + if (ep[1] != NULL) { + paddr[1] = ep[1]->paddr + (laddr & CPU_PAGE_MASK); + goto separate; + } + } + /* paging */ paddr[0] = paging(laddr, ucrw); - remain = PAGE_SIZE - (laddr & PAGE_MASK); + remain = CPU_PAGE_SIZE - (laddr & CPU_PAGE_MASK); if (remain >= 4) { +onepage: value = cpu_memoryread_d(paddr[0]); result = (*func)(value, arg); cpu_memorywrite_d(paddr[0], result); - } else { - paddr[1] = paging(laddr + remain, ucrw); - switch (remain) { - case 3: - value = cpu_memoryread(paddr[0]); - value += (UINT32)cpu_memoryread_w(paddr[0] + 1) << 8; - value += (UINT32)cpu_memoryread(paddr[1]) << 24; - result = (*func)(value, arg); - cpu_memorywrite(paddr[0], (UINT8)result); - cpu_memorywrite_w(paddr[0] + 1, (UINT16)(result >> 8)); - cpu_memorywrite(paddr[1], (UINT8)(result >> 24)); - break; + return value; + } - case 2: - value = cpu_memoryread_w(paddr[0]); - value += (UINT32)cpu_memoryread_w(paddr[1]) << 16; - result = (*func)(value, arg); - cpu_memorywrite_w(paddr[0], (UINT16)result); - cpu_memorywrite_w(paddr[1], (UINT16)(result >> 16)); - break; + paddr[1] = paging(laddr + remain, ucrw); +separate: + switch (remain) { + case 3: + value = cpu_memoryread(paddr[0]); + value += (UINT32)cpu_memoryread_w(paddr[0] + 1) << 8; + value += (UINT32)cpu_memoryread(paddr[1]) << 24; + result = (*func)(value, arg); + cpu_memorywrite(paddr[0], (UINT8)result); + cpu_memorywrite_w(paddr[0] + 1, (UINT16)(result >> 8)); + cpu_memorywrite(paddr[1], (UINT8)(result >> 24)); + break; - case 1: - value = cpu_memoryread(paddr[0]); - value += (UINT32)cpu_memoryread_w(paddr[1]) << 8; - value += (UINT32)cpu_memoryread(paddr[1] + 2) << 24; - result = (*func)(value, arg); - cpu_memorywrite(paddr[0], (UINT8)result); - cpu_memorywrite_w(paddr[1], (UINT16)(result >> 8)); - cpu_memorywrite(paddr[1] + 2, (UINT8)(result >> 24)); - break; + case 2: + value = cpu_memoryread_w(paddr[0]); + value += (UINT32)cpu_memoryread_w(paddr[1]) << 16; + result = (*func)(value, arg); + cpu_memorywrite_w(paddr[0], (UINT16)result); + cpu_memorywrite_w(paddr[1], (UINT16)(result >> 16)); + break; - default: - ia32_panic("cpu_memory_access_la_RMW_d(): out of range (remain = %d)\n", remain); - return (UINT32)-1; - } + case 1: + value = cpu_memoryread(paddr[0]); + value += (UINT32)cpu_memoryread_w(paddr[1]) << 8; + value += (UINT32)cpu_memoryread(paddr[1] + 2) << 24; + result = (*func)(value, arg); + cpu_memorywrite(paddr[0], (UINT8)result); + cpu_memorywrite_w(paddr[1], (UINT16)(result >> 8)); + cpu_memorywrite(paddr[1] + 2, (UINT8)(result >> 24)); + break; + + default: + ia32_panic("cpu_memory_access_la_RMW_d: out of range (remain=%d)\n", remain); + value = 0; /* XXX compiler happy */ + break; } return value; } +/* read */ UINT8 MEMCALL -cpu_linear_memory_read_b(UINT32 laddr, const int ucrw) +cpu_linear_memory_read_b(UINT32 laddr, int ucrw) { + struct tlb_entry *ep; UINT32 paddr; + /* TLB */ + ep = tlb_lookup(laddr, ucrw); + if (ep != NULL) { + paddr = ep->paddr + (laddr & CPU_PAGE_MASK); + return cpu_memoryread(paddr); + } + + /* paging */ paddr = paging(laddr, ucrw); return cpu_memoryread(paddr); } UINT16 MEMCALL -cpu_linear_memory_read_w(UINT32 laddr, const int ucrw) +cpu_linear_memory_read_w(UINT32 laddr, int ucrw) { + struct tlb_entry *ep[2]; UINT32 paddr[2]; UINT16 value; + /* TLB */ + ep[0] = tlb_lookup(laddr, ucrw); + if (ep[0] != NULL) { + paddr[0] = ep[0]->paddr + (laddr & CPU_PAGE_MASK); + if ((laddr + 1) & CPU_PAGE_MASK) + return cpu_memoryread_w(paddr[0]); + + ep[1] = tlb_lookup(laddr + 1, ucrw); + if (ep[1] != NULL) { + paddr[1] = ep[1]->paddr; + goto separate; + } + } + + /* paging */ paddr[0] = paging(laddr, ucrw); - if ((laddr + 1) & PAGE_MASK) { + if ((laddr + 1) & CPU_PAGE_MASK) return cpu_memoryread_w(paddr[0]); - } else { - paddr[1] = paging(laddr + 1, ucrw); - value = cpu_memoryread_b(paddr[0]); - value += (UINT16)cpu_memoryread_b(paddr[1]) << 8; - return value; - } + + paddr[1] = paging(laddr + 1, ucrw); +separate: + value = cpu_memoryread_b(paddr[0]); + value += (UINT16)cpu_memoryread_b(paddr[1]) << 8; + return value; } UINT32 MEMCALL -cpu_linear_memory_read_d(UINT32 laddr, const int ucrw) +cpu_linear_memory_read_d(UINT32 laddr, int ucrw) { + struct tlb_entry *ep[2]; UINT32 paddr[2]; UINT32 value; UINT remain; + /* TLB */ + ep[0] = tlb_lookup(laddr, ucrw); + if (ep[0] != NULL) { + paddr[0] = ep[0]->paddr + (laddr & CPU_PAGE_MASK); + remain = CPU_PAGE_SIZE - (laddr & CPU_PAGE_MASK); + if (remain >= sizeof(value)) + return cpu_memoryread_d(paddr[0]); + + ep[1] = tlb_lookup(laddr + remain, ucrw); + if (ep[1] != NULL) { + paddr[1] = ep[1]->paddr; + goto separate; + } + } + + /* paging */ paddr[0] = paging(laddr, ucrw); - remain = PAGE_SIZE - (laddr & PAGE_MASK); - if (remain >= 4) { + remain = CPU_PAGE_SIZE - (laddr & CPU_PAGE_MASK); + if (remain >= sizeof(value)) return cpu_memoryread_d(paddr[0]); - } else { - paddr[1] = paging(laddr + remain, ucrw); - switch (remain) { - case 3: - value = cpu_memoryread(paddr[0]); - value += (UINT32)cpu_memoryread_w(paddr[0] + 1) << 8; - value += (UINT32)cpu_memoryread(paddr[1]) << 24; - break; - case 2: - value = cpu_memoryread_w(paddr[0]); - value += (UINT32)cpu_memoryread_w(paddr[1]) << 16; - break; + paddr[1] = paging(laddr + remain, ucrw); +separate: + switch (remain) { + case 3: + value = cpu_memoryread(paddr[0]); + value += (UINT32)cpu_memoryread_w(paddr[0] + 1) << 8; + value += (UINT32)cpu_memoryread(paddr[1]) << 24; + break; - case 1: - value = cpu_memoryread(paddr[0]); - value += (UINT32)cpu_memoryread_w(paddr[1]) << 8; - value += (UINT32)cpu_memoryread(paddr[1] + 2) << 24; - break; + case 2: + value = cpu_memoryread_w(paddr[0]); + value += (UINT32)cpu_memoryread_w(paddr[1]) << 16; + break; - default: - ia32_panic("cpu_linear_memory_read_d(): out of range (remain = %d)\n", remain); - value = (UINT32)-1; - break; - } - return value; + case 1: + value = cpu_memoryread(paddr[0]); + value += (UINT32)cpu_memoryread_w(paddr[1]) << 8; + value += (UINT32)cpu_memoryread(paddr[1] + 2) << 24; + break; + + default: + ia32_panic("cpu_linear_memory_read_d: out of range (remain=%d)\n", remain); + value = 0; /* XXX compiler happy */ + break; } + return value; } UINT64 MEMCALL -cpu_linear_memory_read_q(UINT32 laddr, const int ucrw) +cpu_linear_memory_read_q(UINT32 laddr, int ucrw) { + struct tlb_entry *ep[2]; UINT32 paddr[2]; UINT64 value; UINT remain; + /* TLB */ + ep[0] = tlb_lookup(laddr, ucrw); + if (ep[0] != NULL) { + paddr[0] = ep[0]->paddr + (laddr & CPU_PAGE_MASK); + remain = CPU_PAGE_SIZE - (laddr & CPU_PAGE_MASK); + if (remain >= sizeof(value)) + return cpu_memoryread_d(paddr[0]); + + ep[1] = tlb_lookup(laddr + remain, ucrw); + if (ep[1] != NULL) { + paddr[1] = ep[1]->paddr; + goto separate; + } + } + + /* paging */ paddr[0] = paging(laddr, ucrw); - remain = PAGE_SIZE - (laddr & PAGE_MASK); - if (remain >= 8) { + remain = CPU_PAGE_SIZE - (laddr & CPU_PAGE_MASK); + if (remain >= sizeof(value)) return cpu_memoryread_q(paddr[0]); - } else { - paddr[1] = paging(laddr + remain, ucrw); - switch (remain) { - case 7: - value = cpu_memoryread(paddr[0]); - value += (UINT64)cpu_memoryread_w(paddr[0] + 1) << 8; - value += (UINT64)cpu_memoryread_d(paddr[0] + 3) << 24; - value += (UINT64)cpu_memoryread(paddr[1]) << 56; - break; - case 6: - value = cpu_memoryread_w(paddr[0]); - value += (UINT64)cpu_memoryread_d(paddr[0] + 2) << 16; - value += (UINT64)cpu_memoryread_w(paddr[1]) << 48; - break; + paddr[1] = paging(laddr + remain, ucrw); +separate: + switch (remain) { + case 7: + value = cpu_memoryread(paddr[0]); + value += (UINT64)cpu_memoryread_w(paddr[0] + 1) << 8; + value += (UINT64)cpu_memoryread_d(paddr[0] + 3) << 24; + value += (UINT64)cpu_memoryread(paddr[1]) << 56; + break; - case 5: - value = cpu_memoryread(paddr[0]); - value += (UINT64)cpu_memoryread_d(paddr[0] + 1) << 8; - value += (UINT64)cpu_memoryread_w(paddr[1]) << 40; - value += (UINT64)cpu_memoryread(paddr[1] + 2) << 56; - break; - - case 4: - value = cpu_memoryread_d(paddr[0]); - value += (UINT64)cpu_memoryread_d(paddr[1]) << 32; - break; - - case 3: - value = cpu_memoryread(paddr[0]); - value += (UINT64)cpu_memoryread_w(paddr[0] + 1) << 8; - value += (UINT64)cpu_memoryread_d(paddr[1]) << 24; - value += (UINT64)cpu_memoryread(paddr[1] + 4) << 56; - break; + case 6: + value = cpu_memoryread_w(paddr[0]); + value += (UINT64)cpu_memoryread_d(paddr[0] + 2) << 16; + value += (UINT64)cpu_memoryread_w(paddr[1]) << 48; + break; + + case 5: + value = cpu_memoryread(paddr[0]); + value += (UINT64)cpu_memoryread_d(paddr[0] + 1) << 8; + value += (UINT64)cpu_memoryread_w(paddr[1]) << 40; + value += (UINT64)cpu_memoryread(paddr[1] + 2) << 56; + break; - case 2: - value = cpu_memoryread_w(paddr[0]); - value += (UINT64)cpu_memoryread_d(paddr[1]) << 16; - value += (UINT64)cpu_memoryread_w(paddr[1] + 4) << 48; - break; + case 4: + value = cpu_memoryread_d(paddr[0]); + value += (UINT64)cpu_memoryread_d(paddr[1]) << 32; + break; - case 1: - value = cpu_memoryread(paddr[0]); - value += (UINT64)cpu_memoryread_d(paddr[1]) << 8; - value += (UINT64)cpu_memoryread_w(paddr[1] + 4) << 40; - value += (UINT64)cpu_memoryread(paddr[1] + 6) << 56; - break; + case 3: + value = cpu_memoryread(paddr[0]); + value += (UINT64)cpu_memoryread_w(paddr[0] + 1) << 8; + value += (UINT64)cpu_memoryread_d(paddr[1]) << 24; + value += (UINT64)cpu_memoryread(paddr[1] + 4) << 56; + break; - default: - ia32_panic("cpu_linear_memory_read_q(): out of range (remain = %d)\n", remain); - value = (UINT64)-1; - break; - } + case 2: + value = cpu_memoryread_w(paddr[0]); + value += (UINT64)cpu_memoryread_d(paddr[1]) << 16; + value += (UINT64)cpu_memoryread_w(paddr[1] + 4) << 48; + break; + + case 1: + value = cpu_memoryread(paddr[0]); + value += (UINT64)cpu_memoryread_d(paddr[1]) << 8; + value += (UINT64)cpu_memoryread_w(paddr[1] + 4) << 40; + value += (UINT64)cpu_memoryread(paddr[1] + 6) << 56; + break; + + default: + ia32_panic("cpu_linear_memory_read_q: out of range (remain=%d)\n", remain); + value = 0; /* XXX compiler happy */ + break; } return value; } REG80 MEMCALL -cpu_linear_memory_read_f(UINT32 laddr, const int ucrw) +cpu_linear_memory_read_f(UINT32 laddr, int ucrw) { + struct tlb_entry *ep[2]; UINT32 paddr[2]; REG80 value; UINT remain; UINT i, j; + /* TLB */ + ep[0] = tlb_lookup(laddr, ucrw); + if (ep[0] != NULL) { + paddr[0] = ep[0]->paddr + (laddr & CPU_PAGE_MASK); + remain = CPU_PAGE_SIZE - (laddr & CPU_PAGE_MASK); + if (remain >= sizeof(value)) + return cpu_memoryread_f(paddr[0]); + + ep[1] = tlb_lookup(laddr + remain, ucrw); + if (ep[1] != NULL) { + paddr[1] = ep[1]->paddr; + goto separate; + } + } + + /* paging */ paddr[0] = paging(laddr, ucrw); - remain = PAGE_SIZE - (laddr & PAGE_MASK); - if (remain >= 10) { + remain = CPU_PAGE_SIZE - (laddr & CPU_PAGE_MASK); + if (remain >= sizeof(value)) return cpu_memoryread_f(paddr[0]); - } else { - paddr[1] = paging(laddr + remain, ucrw); - for (i = 0; i < remain; ++i) { - value.b[i] = cpu_memoryread(paddr[0] + i); - } - for (j = 0; i < 10; ++i, ++j) { - value.b[i] = cpu_memoryread(paddr[1] + j); - } - return value; + + paddr[1] = paging(laddr + remain, ucrw); +separate: + for (i = 0; i < remain; ++i) { + value.b[i] = cpu_memoryread(paddr[0] + i); } + for (j = 0; i < 10; ++i, ++j) { + value.b[i] = cpu_memoryread(paddr[1] + j); + } + return value; } +/* write */ void MEMCALL -cpu_linear_memory_write_b(UINT32 laddr, UINT8 value, const int user_mode) +cpu_linear_memory_write_b(UINT32 laddr, UINT8 value, int ucrw) { - const int ucrw = CPU_PAGE_WRITE_DATA|user_mode; + struct tlb_entry *ep; UINT32 paddr; + /* TLB */ + ep = tlb_lookup(laddr, ucrw); + if (ep != NULL) { + paddr = ep->paddr + (laddr & CPU_PAGE_MASK); + cpu_memorywrite(paddr, value); + return; + } + + /* paging */ paddr = paging(laddr, ucrw); cpu_memorywrite(paddr, value); } void MEMCALL -cpu_linear_memory_write_w(UINT32 laddr, UINT16 value, const int user_mode) +cpu_linear_memory_write_w(UINT32 laddr, UINT16 value, int ucrw) { - const int ucrw = CPU_PAGE_WRITE_DATA|user_mode; + struct tlb_entry *ep[2]; UINT32 paddr[2]; + /* TLB */ + ep[0] = tlb_lookup(laddr, ucrw); + if (ep[0] != NULL) { + paddr[0] = ep[0]->paddr + (laddr & CPU_PAGE_MASK); + if ((laddr + 1) & CPU_PAGE_MASK) { + cpu_memorywrite_w(paddr[0], value); + return; + } + + ep[1] = tlb_lookup(laddr + 1, ucrw); + if (ep[1] != NULL) { + paddr[1] = ep[1]->paddr; + goto separate; + } + } + + /* paging */ paddr[0] = paging(laddr, ucrw); - if ((laddr + 1) & PAGE_MASK) { + if ((laddr + 1) & CPU_PAGE_MASK) { cpu_memorywrite_w(paddr[0], value); - } else { - paddr[1] = paging(laddr + 1, ucrw); - cpu_memorywrite(paddr[0], (UINT8)value); - cpu_memorywrite(paddr[1], (UINT8)(value >> 8)); + return; } + + paddr[1] = paging(laddr + 1, ucrw); +separate: + cpu_memorywrite(paddr[0], (UINT8)value); + cpu_memorywrite(paddr[1], (UINT8)(value >> 8)); } void MEMCALL -cpu_linear_memory_write_d(UINT32 laddr, UINT32 value, const int user_mode) +cpu_linear_memory_write_d(UINT32 laddr, UINT32 value, int ucrw) { - const int ucrw = CPU_PAGE_WRITE_DATA|user_mode; + struct tlb_entry *ep[2]; UINT32 paddr[2]; UINT remain; + /* TLB */ + ep[0] = tlb_lookup(laddr, ucrw); + if (ep[0] != NULL) { + paddr[0] = ep[0]->paddr + (laddr & CPU_PAGE_MASK); + remain = CPU_PAGE_SIZE - (laddr & CPU_PAGE_MASK); + if (remain >= sizeof(value)) { + cpu_memorywrite_d(paddr[0], value); + return; + } + + ep[1] = tlb_lookup(laddr + remain, ucrw); + if (ep[1] != NULL) { + paddr[1] = ep[1]->paddr; + goto separate; + } + } + + /* paging */ paddr[0] = paging(laddr, ucrw); - remain = PAGE_SIZE - (laddr & PAGE_MASK); - if (remain >= 4) { + remain = CPU_PAGE_SIZE - (laddr & CPU_PAGE_MASK); + if (remain >= sizeof(value)) { cpu_memorywrite_d(paddr[0], value); - } else { - paddr[1] = paging(laddr + remain, ucrw); - switch (remain) { - case 3: - cpu_memorywrite(paddr[0], (UINT8)value); - cpu_memorywrite_w(paddr[0] + 1, (UINT16)(value >> 8)); - cpu_memorywrite(paddr[1], (UINT8)(value >> 24)); - break; + return; + } - case 2: - cpu_memorywrite_w(paddr[0], (UINT16)value); - cpu_memorywrite_w(paddr[1], (UINT16)(value >> 16)); - break; + paddr[1] = paging(laddr + remain, ucrw); +separate: + switch (remain) { + case 3: + cpu_memorywrite(paddr[0], (UINT8)value); + cpu_memorywrite_w(paddr[0] + 1, (UINT16)(value >> 8)); + cpu_memorywrite(paddr[1], (UINT8)(value >> 24)); + break; + + case 2: + cpu_memorywrite_w(paddr[0], (UINT16)value); + cpu_memorywrite_w(paddr[1], (UINT16)(value >> 16)); + break; - case 1: - cpu_memorywrite(paddr[0], (UINT8)value); - cpu_memorywrite_w(paddr[1], (UINT16)(value >> 8)); - cpu_memorywrite(paddr[1] + 2, (UINT8)(value >> 24)); - break; - } + case 1: + cpu_memorywrite(paddr[0], (UINT8)value); + cpu_memorywrite_w(paddr[1], (UINT16)(value >> 8)); + cpu_memorywrite(paddr[1] + 2, (UINT8)(value >> 24)); + break; + + default: + ia32_panic("cpu_linear_memory_write_d: out of range (remain=%d)\n", remain); + break; } } void MEMCALL -cpu_linear_memory_write_q(UINT32 laddr, UINT64 value, const int user_mode) +cpu_linear_memory_write_q(UINT32 laddr, UINT64 value, int ucrw) { - const int ucrw = CPU_PAGE_WRITE_DATA|user_mode; + struct tlb_entry *ep[2]; UINT32 paddr[2]; UINT remain; - paddr[0] = paging(laddr, ucrw); - remain = PAGE_SIZE - (laddr & PAGE_MASK); - if (remain >= 8) { - cpu_memorywrite_q(paddr[0], value); - } else { - paddr[1] = paging(laddr + remain, ucrw); - switch (remain) { - case 7: - cpu_memorywrite(paddr[0], (UINT8)value); - cpu_memorywrite_w(paddr[0] + 1, (UINT16)(value >> 8)); - cpu_memorywrite_d(paddr[0] + 3, (UINT32)(value >> 24)); - cpu_memorywrite(paddr[1], (UINT8)(value >> 56)); - break; + /* TLB */ + ep[0] = tlb_lookup(laddr, ucrw); + if (ep[0] != NULL) { + paddr[0] = ep[0]->paddr + (laddr & CPU_PAGE_MASK); + remain = CPU_PAGE_SIZE - (laddr & CPU_PAGE_MASK); + if (remain >= sizeof(value)) { + cpu_memorywrite_q(paddr[0], value); + return; + } - case 6: - cpu_memorywrite_w(paddr[0], (UINT16)value); - cpu_memorywrite_d(paddr[0] + 2, (UINT32)(value >> 16)); - cpu_memorywrite_w(paddr[1], (UINT16)(value >> 48)); - break; + ep[1] = tlb_lookup(laddr + remain, ucrw); + if (ep[1] != NULL) { + paddr[1] = ep[1]->paddr; + goto separate; + } + } - case 5: - cpu_memorywrite(paddr[0], (UINT8)value); - cpu_memorywrite_d(paddr[0] + 1, (UINT32)(value >> 8)); - cpu_memorywrite_w(paddr[1], (UINT16)(value >> 40)); - cpu_memorywrite(paddr[1] + 2, (UINT8)(value >> 56)); - break; + /* paging */ + paddr[0] = paging(laddr, ucrw); + remain = CPU_PAGE_SIZE - (laddr & CPU_PAGE_MASK); + if (remain >= sizeof(value)) { + cpu_memorywrite_q(paddr[0], value); + return; + } - case 4: - cpu_memorywrite_d(paddr[0], (UINT32)value); - cpu_memorywrite_d(paddr[1], (UINT32)(value >> 32)); - break; + paddr[1] = paging(laddr + remain, ucrw); +separate: + switch (remain) { + case 7: + cpu_memorywrite(paddr[0], (UINT8)value); + cpu_memorywrite_w(paddr[0] + 1, (UINT16)(value >> 8)); + cpu_memorywrite_d(paddr[0] + 3, (UINT32)(value >> 24)); + cpu_memorywrite(paddr[1], (UINT8)(value >> 56)); + break; + + case 6: + cpu_memorywrite_w(paddr[0], (UINT16)value); + cpu_memorywrite_d(paddr[0] + 2, (UINT32)(value >> 16)); + cpu_memorywrite_w(paddr[1], (UINT16)(value >> 48)); + break; - case 3: - cpu_memorywrite(paddr[0], (UINT8)value); - cpu_memorywrite_w(paddr[0] + 1, (UINT16)(value >> 8)); - cpu_memorywrite_d(paddr[1], (UINT32)(value >> 24)); - cpu_memorywrite(paddr[1] + 4, (UINT8)(value >> 56)); - break; + case 5: + cpu_memorywrite(paddr[0], (UINT8)value); + cpu_memorywrite_d(paddr[0] + 1, (UINT32)(value >> 8)); + cpu_memorywrite_w(paddr[1], (UINT16)(value >> 40)); + cpu_memorywrite(paddr[1] + 2, (UINT8)(value >> 56)); + break; + + case 4: + cpu_memorywrite_d(paddr[0], (UINT32)value); + cpu_memorywrite_d(paddr[1], (UINT32)(value >> 32)); + break; - case 2: - cpu_memorywrite_w(paddr[0], (UINT16)value); - cpu_memorywrite_d(paddr[1], (UINT32)(value >> 16)); - cpu_memorywrite_w(paddr[1] + 4, (UINT16)(value >> 48)); - break; + case 3: + cpu_memorywrite(paddr[0], (UINT8)value); + cpu_memorywrite_w(paddr[0] + 1, (UINT16)(value >> 8)); + cpu_memorywrite_d(paddr[1], (UINT32)(value >> 24)); + cpu_memorywrite(paddr[1] + 4, (UINT8)(value >> 56)); + break; + + case 2: + cpu_memorywrite_w(paddr[0], (UINT16)value); + cpu_memorywrite_d(paddr[1], (UINT32)(value >> 16)); + cpu_memorywrite_w(paddr[1] + 4, (UINT16)(value >> 48)); + break; - case 1: - cpu_memorywrite(paddr[0], (UINT8)value); - cpu_memorywrite_d(paddr[1], (UINT32)(value >> 8)); - cpu_memorywrite_w(paddr[1] + 4, (UINT16)(value >> 40)); - cpu_memorywrite(paddr[1] + 6, (UINT8)(value >> 56)); - break; - } + case 1: + cpu_memorywrite(paddr[0], (UINT8)value); + cpu_memorywrite_d(paddr[1], (UINT32)(value >> 8)); + cpu_memorywrite_w(paddr[1] + 4, (UINT16)(value >> 40)); + cpu_memorywrite(paddr[1] + 6, (UINT8)(value >> 56)); + break; + + default: + ia32_panic("cpu_linear_memory_write_q: out of range (remain=%d)\n", remain); + break; } } void MEMCALL -cpu_linear_memory_write_f(UINT32 laddr, const REG80 *value, const int user_mode) +cpu_linear_memory_write_f(UINT32 laddr, const REG80 *value, int ucrw) { - const int ucrw = CPU_PAGE_WRITE_DATA|user_mode; + struct tlb_entry *ep[2]; UINT32 paddr[2]; UINT remain; UINT i, j; - paddr[0] = paging(laddr, ucrw); - remain = PAGE_SIZE - (laddr & PAGE_MASK); - if (remain >= 10) { - cpu_memorywrite_f(paddr[0], value); - } else { - paddr[1] = paging(laddr + remain, ucrw); - for (i = 0; i < remain; ++i) { - cpu_memorywrite(paddr[0] + i, value->b[i]); + /* TLB */ + ep[0] = tlb_lookup(laddr, ucrw); + if (ep[0] != NULL) { + paddr[0] = ep[0]->paddr + (laddr & CPU_PAGE_MASK); + remain = CPU_PAGE_SIZE - (laddr & CPU_PAGE_MASK); + if (remain >= sizeof(value)) { + cpu_memorywrite_f(paddr[0], value); + return; } - for (j = 0; i < 10; ++i, ++j) { - cpu_memorywrite(paddr[1] + j, value->b[i]); + + ep[1] = tlb_lookup(laddr + remain, ucrw); + if (ep[1] != NULL) { + paddr[1] = ep[1]->paddr; + goto separate; } } -} + /* paging */ + paddr[0] = paging(laddr, ucrw); + remain = CPU_PAGE_SIZE - (laddr & CPU_PAGE_MASK); + if (remain >= sizeof(value)) { + cpu_memorywrite_f(paddr[0], value); + return; + } + + paddr[1] = paging(laddr + remain, ucrw); +separate: + for (i = 0; i < remain; ++i) { + cpu_memorywrite(paddr[0] + i, value->b[i]); + } + for (j = 0; i < 10; ++i, ++j) { + cpu_memorywrite(paddr[1] + j, value->b[i]); + } +} +/* + * linear address memory access function + */ void MEMCALL -cpu_memory_access_la_region(UINT32 laddr, UINT length, const int ucrw, UINT8 *data) +cpu_memory_access_la_region(UINT32 laddr, UINT length, int ucrw, UINT8 *data) { UINT32 paddr; UINT remain; /* page remain */ @@ -591,7 +833,7 @@ cpu_memory_access_la_region(UINT32 laddr if (length == 0) return; - remain = PAGE_SIZE - (laddr & PAGE_MASK); + remain = CPU_PAGE_SIZE - (laddr & CPU_PAGE_MASK); for (;;) { if (!CPU_STAT_PAGING) { paddr = laddr; @@ -615,20 +857,23 @@ cpu_memory_access_la_region(UINT32 laddr remain -= r; if (remain <= 0) { /* next page */ - remain += PAGE_SIZE; + remain += CPU_PAGE_SIZE; } } } UINT32 MEMCALL -laddr2paddr(const UINT32 laddr, const int ucrw) +laddr2paddr(UINT32 laddr, int ucrw) { return paging(laddr, ucrw); } +/* + * paging + */ static UINT32 MEMCALL -paging(const UINT32 laddr, const int ucrw) +paging(UINT32 laddr, int ucrw) { UINT32 paddr; /* physical address */ UINT32 pde_addr; /* page directory entry address */ @@ -637,11 +882,11 @@ paging(const UINT32 laddr, const int ucr UINT32 pte; /* page table entry */ UINT bit; UINT err; - TLB_ENTRY_T *ep; + struct tlb_entry *ep; ep = tlb_lookup(laddr, ucrw); if (ep != NULL) - return ep->paddr + (laddr & PAGE_MASK); + return ep->paddr + (laddr & CPU_PAGE_MASK); pde_addr = CPU_STAT_PDE_BASE + ((laddr >> 20) & 0xffc); pde = cpu_memoryread_d(pde_addr); @@ -672,7 +917,7 @@ paging(const UINT32 laddr, const int ucr } /* make physical address */ - paddr = (pte & CPU_PTE_BASEADDR_MASK) + (laddr & PAGE_MASK); + paddr = (pte & CPU_PTE_BASEADDR_MASK) + (laddr & CPU_PAGE_MASK); bit = ucrw & (CPU_PAGE_WRITE|CPU_PAGE_USER_MODE); bit |= (pde & pte & (CPU_PTE_WRITABLE|CPU_PTE_USER_MODE)); @@ -697,7 +942,7 @@ paging(const UINT32 laddr, const int ucr cpu_memorywrite_d(pte_addr, pte); } - tlb_update(laddr, pte, (bit & (CPU_PTE_WRITABLE|CPU_PTE_USER_MODE)) + ((ucrw & CPU_PAGE_CODE) >> 1)); + tlb_update(laddr, pte, (bit & (CPU_PTE_WRITABLE|CPU_PTE_USER_MODE)) + ((ucrw & CPU_PAGE_CODE) ? 1 : 0)); return paddr; @@ -712,9 +957,6 @@ pf_exception: /* * TLB */ -#define TLB_GET_PADDR(ep, addr) ((ep)->paddr + ((addr) & ~CPU_PTE_BASEADDR_MASK)) -#define TLB_SET_PADDR(ep, addr) ((ep)->paddr = (addr) & CPU_PTE_BASEADDR_MASK) - #define TLB_TAG_SHIFT TLB_ENTRY_TAG_MAX_SHIFT #define TLB_TAG_MASK (~((1 << TLB_TAG_SHIFT) - 1)) #define TLB_GET_TAG_ADDR(ep) ((ep)->tag & TLB_TAG_MASK) @@ -749,60 +991,34 @@ do { \ #define TLB_ENTRY_MASK (NENTRY - 1) typedef struct { - TLB_ENTRY_T entry[NENTRY]; -} TLB_T; - -static TLB_T tlb[NTLB]; - -#if defined(IA32_PROFILE_TLB) -/* profiling */ -typedef struct { - UINT64 tlb_hits; - UINT64 tlb_misses; - UINT64 tlb_lookups; - UINT64 tlb_updates; - UINT64 tlb_flushes; - UINT64 tlb_global_flushes; - UINT64 tlb_entry_flushes; -} TLB_PROFILE_T; - -static TLB_PROFILE_T tlb_profile; - -#define PROFILE_INC(v) tlb_profile.v++ -#else /* !IA32_PROFILE_TLB */ -#define PROFILE_INC(v) -#endif /* IA32_PROFILE_TLB */ - + struct tlb_entry entry[NENTRY]; +} tlb_t; +static tlb_t tlb[NTLB]; void tlb_init(void) { memset(tlb, 0, sizeof(tlb)); -#if defined(IA32_PROFILE_TLB) - memset(&tlb_profile, 0, sizeof(tlb_profile)); -#endif /* IA32_PROFILE_TLB */ } void MEMCALL tlb_flush(BOOL allflush) { - TLB_ENTRY_T *ep; + struct tlb_entry *ep; int i; int n; if (allflush) { - PROFILE_INC(tlb_global_flushes); - } else { - PROFILE_INC(tlb_flushes); + tlb_init(); + return; } for (n = 0; n < NTLB; n++) { for (i = 0; i < NENTRY ; i++) { ep = &tlb[n].entry[i]; - if (TLB_IS_VALID(ep) && (allflush || !TLB_IS_GLOBAL(ep))) { + if (TLB_IS_VALID(ep) && !TLB_IS_GLOBAL(ep)) { TLB_SET_INVALID(ep); - PROFILE_INC(tlb_entry_flushes); } } } @@ -811,12 +1027,10 @@ tlb_flush(BOOL allflush) void MEMCALL tlb_flush_page(UINT32 laddr) { - TLB_ENTRY_T *ep; + struct tlb_entry *ep; int idx; int n; - PROFILE_INC(tlb_flushes); - idx = (laddr >> TLB_ENTRY_SHIFT) & TLB_ENTRY_MASK; for (n = 0; n < NTLB; n++) { @@ -824,23 +1038,20 @@ tlb_flush_page(UINT32 laddr) if (TLB_IS_VALID(ep)) { if ((laddr & TLB_TAG_MASK) == TLB_GET_TAG_ADDR(ep)) { TLB_SET_INVALID(ep); - PROFILE_INC(tlb_entry_flushes); } } } } -TLB_ENTRY_T * MEMCALL -tlb_lookup(const UINT32 laddr, const int ucrw) +struct tlb_entry * MEMCALL +tlb_lookup(UINT32 laddr, int ucrw) { - TLB_ENTRY_T *ep; + struct tlb_entry *ep; UINT bit; int idx; int n; - PROFILE_INC(tlb_lookups); - - n = (ucrw & CPU_PAGE_CODE) >> 1; + n = (ucrw & CPU_PAGE_CODE) ? 1 : 0; idx = (laddr >> TLB_ENTRY_SHIFT) & TLB_ENTRY_MASK; ep = &tlb[n].entry[idx]; @@ -856,44 +1067,27 @@ tlb_lookup(const UINT32 laddr, const int #endif { if (!(ucrw & CPU_PAGE_WRITE) || TLB_IS_DIRTY(ep)) { - PROFILE_INC(tlb_hits); return ep; } } } } - PROFILE_INC(tlb_misses); return NULL; } static void MEMCALL -tlb_update(const UINT32 laddr, const UINT entry, const int bit) +tlb_update(UINT32 laddr, UINT entry, int bit) { - TLB_ENTRY_T *ep; - UINT32 pos; + struct tlb_entry *ep; int idx; int n; - PROFILE_INC(tlb_updates); - n = bit & 1; idx = (laddr >> TLB_ENTRY_SHIFT) & TLB_ENTRY_MASK; ep = &tlb[n].entry[idx]; TLB_SET_VALID(ep); TLB_SET_TAG_ADDR(ep, laddr); - TLB_SET_PADDR(ep, entry); TLB_SET_TAG_FLAGS(ep, entry, bit); - - if (ep->paddr < CPU_MEMREADMAX) { - ep->memp = mem + ep->paddr; - return; - } else if (ep->paddr >= USE_HIMEM) { - pos = (ep->paddr & CPU_ADRSMASK) - 0x100000; - if (pos < CPU_EXTMEMSIZE) { - ep->memp = CPU_EXTMEM + pos; - return; - } - } - ep->memp = NULL; + ep->paddr = entry & CPU_PTE_BASEADDR_MASK; }