--- np2/i386c/ia32/paging.c 2005/03/12 12:32:54 1.28 +++ np2/i386c/ia32/paging.c 2011/12/21 18:07:57 1.34 @@ -1,5 +1,3 @@ -/* $Id: paging.c,v 1.28 2005/03/12 12:32:54 monaka Exp $ */ - /* * Copyright (c) 2003-2004 NONAKA Kimihiro * All rights reserved. @@ -30,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 | @@ -73,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 | | @@ -157,17 +155,17 @@ static const UINT8 page_access_bit[32] = /* *-- - * 32bit ʪÍý¥¢¥É¥ì¥¹ 4k ¥Ú¡¼¥¸ + * 32bit í饥íð¬å¤¤åã²å¦®å⥱ 4k åãÔ妾å⥯ * - * ¡¦ô§¥Ò¡¦¡Ö¡£¥ò¡¦¡Ö¡¦¥Î¡¦ø§¥± + * å㥧åã¶å¤¤å㥵åâ¡Öåã²å¦®å⥱ * 31 22 21 12 11 0 * +------------------------+----------------------+--------------------------+ - * | ¡¦¥ì¡£¥·¡¦¥¯¡£¥ò¡¦¥Ì¡¦¡×¡¦ø§¥Ã¡¦¥Í¡¦ | ¥Ú¡¼¥¸¡¦¥Æ¡¼¥Ö¥ë | ¥ª¥Õ¥»¥Ã¥È | + * | åãÔ妾å⥯å㥵åã®å¤¥åã¥ãåâ¥Ãåã°å¦¬ | åãÔ妾å⥯å㥵åã¬å¦¾åãÌ妭 | å⥧åãÊ夽åã¦å¥è | * +------------------------+----------------------+--------------------------+ * | | | * +-----------+ +-----------+ +----------+ * | | | - * | ¡¦¥ì¡£¥·¡¦¥¯¡£¥ò¡¦¥Ì¡¦¡×¡¦ø§¥Ã¡¦¥Í¡¦ | ¥Ú¡¼¥¸¡¦¥Æ¡¼¥Ö¥ë ¥Ú¡¼¥¸ | + * | ¥Ú¡¼¥¸¡¦¥Ç¥£¥ì¥¯¥È¥ê | ¥Ú¡¼¥¸¡¦¥Æ¡¼¥Ö¥ë ¥Ú¡¼¥¸ | * | +--------------------+ | +-------------------+ +------------------+ | * | | | | | | | | | * | | | | +-------------------+ | | | @@ -179,18 +177,19 @@ static const UINT8 page_access_bit[32] = * | | | | | | | | * +>+--------------------+ +>+-------------------+ +>+------------------+ * | - * +- CR3() + * +- CR3(ʪÍý¥¢¥É¥ì¥¹) */ -static UINT32 MEMCALL paging(const UINT32 laddr, const int ucrw) GCC_ATTR_REGPARM; -#if defined(IA32_SUPPORT_TLB) -static void MEMCALL tlb_update(const UINT32 laddr, const UINT entry, const int ucrw) GCC_ATTR_REGPARM; -#endif +static UINT32 MEMCALL paging(const UINT32 laddr, const int ucrw); +static void MEMCALL tlb_update(const UINT32 laddr, const UINT entry, const int ucrw); + +#define PAGE_SIZE 0x1000 +#define PAGE_MASK (PAGE_SIZE - 1) UINT8 MEMCALL cpu_memory_access_la_RMW_b(UINT32 laddr, UINT32 (*func)(UINT32, void *), void *arg) { - const int ucrw = CPU_PAGE_WRITE|CPU_PAGE_DATA|CPU_STAT_USER_MODE; + const int ucrw = CPU_PAGE_WRITE_DATA|CPU_STAT_USER_MODE; UINT32 result, value; UINT32 paddr; @@ -205,12 +204,12 @@ cpu_memory_access_la_RMW_b(UINT32 laddr, UINT16 MEMCALL cpu_memory_access_la_RMW_w(UINT32 laddr, UINT32 (*func)(UINT32, void *), void *arg) { - const int ucrw = CPU_PAGE_WRITE|CPU_PAGE_DATA|CPU_STAT_USER_MODE; + const int ucrw = CPU_PAGE_WRITE_DATA|CPU_STAT_USER_MODE; UINT32 result, value; UINT32 paddr[2]; paddr[0] = paging(laddr, ucrw); - if ((laddr + 1) & 0x00000fff) { + if ((laddr + 1) & PAGE_MASK) { value = cpu_memoryread_w(paddr[0]); result = (*func)(value, arg); cpu_memorywrite_w(paddr[0], (UINT16)result); @@ -228,13 +227,13 @@ cpu_memory_access_la_RMW_w(UINT32 laddr, UINT32 MEMCALL cpu_memory_access_la_RMW_d(UINT32 laddr, UINT32 (*func)(UINT32, void *), void *arg) { - const int ucrw = CPU_PAGE_WRITE|CPU_PAGE_DATA|CPU_STAT_USER_MODE; + const int ucrw = CPU_PAGE_WRITE_DATA|CPU_STAT_USER_MODE; UINT32 result, value; UINT32 paddr[2]; UINT remain; paddr[0] = paging(laddr, ucrw); - remain = 0x1000 - (laddr & 0x00000fff); + remain = PAGE_SIZE - (laddr & PAGE_MASK); if (remain >= 4) { value = cpu_memoryread_d(paddr[0]); result = (*func)(value, arg); @@ -294,7 +293,7 @@ cpu_linear_memory_read_w(UINT32 laddr, c UINT16 value; paddr[0] = paging(laddr, ucrw); - if ((laddr + 1) & 0x00000fff) { + if ((laddr + 1) & PAGE_MASK) { return cpu_memoryread_w(paddr[0]); } else { paddr[1] = paging(laddr + 1, ucrw); @@ -312,7 +311,7 @@ cpu_linear_memory_read_d(UINT32 laddr, c UINT remain; paddr[0] = paging(laddr, ucrw); - remain = 0x1000 - (laddr & 0x00000fff); + remain = PAGE_SIZE - (laddr & PAGE_MASK); if (remain >= 4) { return cpu_memoryread_d(paddr[0]); } else { @@ -352,7 +351,7 @@ cpu_linear_memory_read_q(UINT32 laddr, c UINT remain; paddr[0] = paging(laddr, ucrw); - remain = 0x1000 - (laddr & 0x00000fff); + remain = PAGE_SIZE - (laddr & PAGE_MASK); if (remain >= 8) { return cpu_memoryread_q(paddr[0]); } else { @@ -375,7 +374,7 @@ cpu_linear_memory_read_q(UINT32 laddr, c 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] + 1) << 56; + value += (UINT64)cpu_memoryread(paddr[1] + 2) << 56; break; case 4: @@ -421,7 +420,7 @@ cpu_linear_memory_read_f(UINT32 laddr, c UINT i, j; paddr[0] = paging(laddr, ucrw); - remain = 0x1000 - (laddr & 0x00000fff); + remain = PAGE_SIZE - (laddr & PAGE_MASK); if (remain >= 10) { return cpu_memoryread_f(paddr[0]); } else { @@ -439,7 +438,7 @@ cpu_linear_memory_read_f(UINT32 laddr, c void MEMCALL cpu_linear_memory_write_b(UINT32 laddr, UINT8 value, const int user_mode) { - const int ucrw = CPU_PAGE_WRITE|CPU_PAGE_DATA|user_mode; + const int ucrw = CPU_PAGE_WRITE_DATA|user_mode; UINT32 paddr; paddr = paging(laddr, ucrw); @@ -449,11 +448,11 @@ cpu_linear_memory_write_b(UINT32 laddr, void MEMCALL cpu_linear_memory_write_w(UINT32 laddr, UINT16 value, const int user_mode) { - const int ucrw = CPU_PAGE_WRITE|CPU_PAGE_DATA|user_mode; + const int ucrw = CPU_PAGE_WRITE_DATA|user_mode; UINT32 paddr[2]; paddr[0] = paging(laddr, ucrw); - if ((laddr + 1) & 0x00000fff) { + if ((laddr + 1) & PAGE_MASK) { cpu_memorywrite_w(paddr[0], value); } else { paddr[1] = paging(laddr + 1, ucrw); @@ -465,12 +464,12 @@ cpu_linear_memory_write_w(UINT32 laddr, void MEMCALL cpu_linear_memory_write_d(UINT32 laddr, UINT32 value, const int user_mode) { - const int ucrw = CPU_PAGE_WRITE|CPU_PAGE_DATA|user_mode; + const int ucrw = CPU_PAGE_WRITE_DATA|user_mode; UINT32 paddr[2]; UINT remain; paddr[0] = paging(laddr, ucrw); - remain = 0x1000 - (laddr & 0x00000fff); + remain = PAGE_SIZE - (laddr & PAGE_MASK); if (remain >= 4) { cpu_memorywrite_d(paddr[0], value); } else { @@ -499,12 +498,12 @@ cpu_linear_memory_write_d(UINT32 laddr, void MEMCALL cpu_linear_memory_write_q(UINT32 laddr, UINT64 value, const int user_mode) { - const int ucrw = CPU_PAGE_WRITE|CPU_PAGE_DATA|user_mode; + const int ucrw = CPU_PAGE_WRITE_DATA|user_mode; UINT32 paddr[2]; UINT remain; paddr[0] = paging(laddr, ucrw); - remain = 0x1000 - (laddr & 0x00000fff); + remain = PAGE_SIZE - (laddr & PAGE_MASK); if (remain >= 8) { cpu_memorywrite_q(paddr[0], value); } else { @@ -518,6 +517,7 @@ cpu_linear_memory_write_q(UINT32 laddr, 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; @@ -560,13 +560,13 @@ cpu_linear_memory_write_q(UINT32 laddr, void MEMCALL cpu_linear_memory_write_f(UINT32 laddr, const REG80 *value, const int user_mode) { - const int ucrw = CPU_PAGE_WRITE|CPU_PAGE_DATA|user_mode; + const int ucrw = CPU_PAGE_WRITE_DATA|user_mode; UINT32 paddr[2]; UINT remain; UINT i, j; paddr[0] = paging(laddr, ucrw); - remain = 0x1000 - (laddr & 0x00000fff); + remain = PAGE_SIZE - (laddr & PAGE_MASK); if (remain >= 10) { cpu_memorywrite_f(paddr[0], value); } else { @@ -582,7 +582,7 @@ cpu_linear_memory_write_f(UINT32 laddr, void MEMCALL -cpu_memory_access_la_region(UINT32 laddr, UINT length, const int ucrw, BYTE *data) +cpu_memory_access_la_region(UINT32 laddr, UINT length, const int ucrw, UINT8 *data) { UINT32 paddr; UINT remain; /* page remain */ @@ -591,7 +591,7 @@ cpu_memory_access_la_region(UINT32 laddr if (length == 0) return; - remain = 0x1000 - (laddr & 0x00000fff); + remain = PAGE_SIZE - (laddr & PAGE_MASK); for (;;) { if (!CPU_STAT_PAGING) { paddr = laddr; @@ -615,35 +615,16 @@ cpu_memory_access_la_region(UINT32 laddr remain -= r; if (remain <= 0) { /* next page */ - remain += 0x1000; + remain += PAGE_SIZE; } } } -void MEMCALL -paging_check(UINT32 laddr, UINT length, const int ucrw) +UINT32 MEMCALL +laddr2paddr(const UINT32 laddr, const int ucrw) { - UINT32 paddr; - UINT remain; /* page remain */ - UINT r; - - remain = 0x1000 - (laddr & 0x00000fff); - for (;;) { - paddr = paging(laddr, ucrw); - r = (remain > length) ? length : remain; - - length -= r; - if (length == 0) - break; - - laddr += r; - remain -= r; - if (remain <= 0) { - /* next page */ - remain += 0x1000; - } - } + return paging(laddr, ucrw); } static UINT32 MEMCALL @@ -656,13 +637,11 @@ paging(const UINT32 laddr, const int ucr UINT32 pte; /* page table entry */ UINT bit; UINT err; -#if defined(IA32_SUPPORT_TLB) TLB_ENTRY_T *ep; ep = tlb_lookup(laddr, ucrw); if (ep != NULL) - return ep->paddr + (laddr & 0xfff); -#endif + return ep->paddr + (laddr & PAGE_MASK); pde_addr = CPU_STAT_PDE_BASE + ((laddr >> 20) & 0xffc); pde = cpu_memoryread_d(pde_addr); @@ -693,7 +672,7 @@ paging(const UINT32 laddr, const int ucr } /* make physical address */ - paddr = (pte & CPU_PTE_BASEADDR_MASK) + (laddr & 0x00000fff); + paddr = (pte & CPU_PTE_BASEADDR_MASK) + (laddr & PAGE_MASK); bit = ucrw & (CPU_PAGE_WRITE|CPU_PAGE_USER_MODE); bit |= (pde & pte & (CPU_PTE_WRITABLE|CPU_PTE_USER_MODE)); @@ -718,9 +697,8 @@ paging(const UINT32 laddr, const int ucr cpu_memorywrite_d(pte_addr, pte); } -#if defined(IA32_SUPPORT_TLB) tlb_update(laddr, pte, (bit & (CPU_PTE_WRITABLE|CPU_PTE_USER_MODE)) + ((ucrw & CPU_PAGE_CODE) >> 1)); -#endif + return paddr; pf_exception: @@ -731,8 +709,6 @@ pf_exception: return 0; /* compiler happy */ } - -#if defined(IA32_SUPPORT_TLB) /* * TLB */ @@ -758,7 +734,7 @@ do { \ #if (CPU_FEATURES & CPU_FEATURE_PGE) == CPU_FEATURE_PGE #define TLB_IS_GLOBAL(ep) ((ep)->tag & TLB_ENTRY_TAG_GLOBAL) #else -#define TLB_IS_GLOBAL(ep) FALSE +#define TLB_IS_GLOBAL(ep) 0 #endif #define TLB_SET_TAG_FLAGS(ep, entry, bit) \ @@ -804,7 +780,7 @@ tlb_init(void) memset(tlb, 0, sizeof(tlb)); #if defined(IA32_PROFILE_TLB) - memset(tlb_profile, 0, sizeof(tlb_profile)); + memset(&tlb_profile, 0, sizeof(tlb_profile)); #endif /* IA32_PROFILE_TLB */ } @@ -921,4 +897,3 @@ tlb_update(const UINT32 laddr, const UIN } ep->memp = NULL; } -#endif /* IA32_SUPPORT_TLB */