?? mmu40lib.c
字號:
/* reset the transparent translation registers */ if (enable && firstTime) { cacheClear (DATA_CACHE, NULL, ENTIRE_CACHE); /* from Heurikon */ __asm__ ("movel #0, d0; " ".word 0x4e7b, 0x0004; " /* movec d0, ITT0 */ ".word 0x4e7b, 0x0005; " /* movec d0, ITT1 */ ".word 0x4e7b, 0x0006; " /* movec d0, DTT0 */ ".word 0x4e7b, 0x0007; " /* movec d0, DTT1 */ : /* outputs */ : /* inputs */ : "d0" /* temps */ ); firstTime = FALSE; } return (OK); }/******************************************************************************** mmuStateSet - set state of virtual memory page** mmuStateSet is used to modify the state bits of the pte for the given* virtual page. The following states are provided:** MMU_STATE_VALID MMU_STATE_VALID_NOT vailid/invalid* MMU_STATE_WRITABLE MMU_STATE_WRITABLE_NOT writable/writeprotected* MMU_STATE_CACHEABLE MMU_STATE_CACHEABLE_NOT notcachable/cachable** these may be or'ed together in the state parameter. The 68040 and 68060* provides several caching modes, so the following cache states are provided* which may be substituted for MMU_STATE_CACHEABLE/MMU_STATE_CACHEABLE_NOT:** MMU_STATE_CACHEABLE_WRITETHROUGH * MMU_STATE_CACHEABLE_COPYBACK * MMU_STATE_CACHEABLE_NOT_SERIAL (MC68040 only)* MMU_STATE_CACHEABLE_NOT_NON_SERIAL (MC68040 only)* MMU_STATE_CACHEABLE_NOT_PRECISE (MC68060 only)* MMU_STATE_CACHEABLE_NOT_IMPRECISE (MC68060 only)** MMU_STATE_CACHEABLE is equivalent to MMU_STATE_CACHEABLE_COPYBACK, and* MMU_STATE_CACHEABLE_NOT is equivalent to MMU_STATE_CACHEABLE_NOT_SERIAL or* MMU_STATE_CACHEABLE_NOT_PRECISE.* See the MC68040 or MC68060 32-bit Microprocessor User's Manual for* additional information.* * Additionally, masks are provided so that only specific states may be set:** MMU_STATE_MASK_VALID* MMU_STATE_MASK_WRITABLE* MMU_STATE_MASK_CACHEABLE** These may be or'ed together in the stateMask parameter. ** Accesses to a virtual page marked as invalid will result in a bus error.** RETURNS: OK or ERROR if virtual page does not exist.*/LOCAL STATUS mmuStateSet ( MMU_TRANS_TBL *transTbl, /* translation table */ void *pageAddr, /* page whose state to modify */ UINT stateMask, /* mask of which state bits to modify */ UINT state /* new state bit values */ ) { PAGE_DESC *pageDesc; FAST UINT *pageDescBits; FAST int oldIntLev; if (mmuPageDescGet (transTbl, pageAddr, &pageDesc) != OK) return (ERROR); /* modify the pte with mmu turned off and interrupts locked out */ pageDescBits = (UINT *) pageDesc; /* XXX can't dynamically turn mmu on and off if virtual stack */ /* only way is if you make mmuEnable inline and guarantee that this code is in physical memory */ if (mmuEnabled) { oldIntLev = intLock (); mmuEnableInline(FALSE); *pageDescBits = (*pageDescBits & ~stateMask) | (state & stateMask); mmuEnableInline(TRUE); intUnlock (oldIntLev); } else *pageDescBits = (*pageDescBits & ~stateMask) | (state & stateMask); mmuATCFlush (pageAddr); cacheClear (DATA_CACHE, (void *) pageDescBits, sizeof (*pageDescBits)); return (OK); }/******************************************************************************** mmuStateGet - get state of virtual memory page** mmuStateGet is used to retrieve the state bits of the pte for the given* virtual page. The following states are provided:** VM_STATE_VALID VM_STATE_VALID_NOT vailid/invalid* VM_STATE_WRITABLE VM_STATE_WRITABLE_NOT writable/writeprotected* VM_STATE_CACHEABLE VM_STATE_CACHEABLE_NOT notcachable/cachable** these are or'ed together in the returned state. Additionally, masks* are provided so that specific states may be extracted from the returned state:** VM_STATE_MASK_VALID * VM_STATE_MASK_WRITABLE* VM_STATE_MASK_CACHEABLE** RETURNS: OK or ERROR if virtual page does not exist.*/LOCAL STATUS mmuStateGet ( MMU_TRANS_TBL *transTbl, /* tranlation table */ void *pageAddr, /* page whose state we're querying */ UINT *state /* place to return state value */ ) { PAGE_DESC *pageDesc; FAST UINT *pageDescBits; if (mmuPageDescGet (transTbl, pageAddr, &pageDesc) != OK) return (ERROR); pageDescBits = (UINT *) pageDesc; *state = *pageDescBits; return (OK); }/******************************************************************************** mmuPageMap - map physical memory page to virtual memory page** The physical page address is entered into the pte corresponding to the* given virtual page. The state of a newly mapped page is undefined. ** RETURNS: OK or ERROR if translation table creation failed. */LOCAL STATUS mmuPageMap ( MMU_TRANS_TBL *transTbl, /* translation table */ void *virtualAddress, /* virtual address */ void *physPage /* physical address */ ) { PAGE_DESC *pageDesc; if (mmuPageDescGet (transTbl, virtualAddress, &pageDesc) != OK) { /* build the translation table for the virtual address */ if (mmuVirtualPageCreate (transTbl, virtualAddress) != OK) return (ERROR); if (mmuPageDescGet (transTbl, virtualAddress, &pageDesc) != OK) return (ERROR); } mmuMemPagesWriteEnable (transTbl); if (mmuPageSize == PAGE_SIZE_4K) pageDesc->pageSize4k.addr = (UINT) physPage >> 12; else pageDesc->pageSize8k.addr = (UINT) physPage >> 13; mmuMemPagesWriteDisable (transTbl); mmuATCFlush (virtualAddress); cacheClear (DATA_CACHE, pageDesc, sizeof (*pageDesc)); return (OK); }/******************************************************************************** mmuGlobalPageMap - map physical memory page to global virtual memory page** mmuGlobalPageMap is used to map physical pages into global virtual memory* that is shared by all virtual memory contexts. The translation tables* for this section of the virtual space are shared by all virtual memory* contexts.** RETURNS: OK or ERROR if no pte for given virtual page.*/LOCAL STATUS mmuGlobalPageMap ( void *virtualAddress, /* virtual address */ void *physPage /* physical address */ ) { PAGE_DESC *pageDesc; if (mmuPageDescGet (&mmuGlobalTransTbl, virtualAddress, &pageDesc) != OK) { /* build the translation table for the virtual address */ if (mmuVirtualPageCreate (&mmuGlobalTransTbl, virtualAddress) != OK) return (ERROR); if (mmuPageDescGet(&mmuGlobalTransTbl, virtualAddress, &pageDesc) != OK) return (ERROR); } mmuMemPagesWriteEnable (&mmuGlobalTransTbl); if (mmuPageSize == PAGE_SIZE_4K) pageDesc->pageSize4k.addr = (UINT) physPage >> 12; else pageDesc->pageSize8k.addr = (UINT) physPage >> 13; mmuMemPagesWriteDisable (&mmuGlobalTransTbl); mmuATCFlush (virtualAddress); cacheClear (DATA_CACHE, pageDesc, sizeof (*pageDesc)); return (OK); }/******************************************************************************** mmuTranslate - translate a virtual address to a physical address** Traverse the translation table and extract the physical address for the* given virtual address from the pte corresponding to the virtual address.** RETURNS: OK or ERROR if no pte for given virtual address.*/LOCAL STATUS mmuTranslate ( MMU_TRANS_TBL *transTbl, /* translation table */ void *virtAddress, /* virtual address */ void **physAddress /* place to return result */ ) { PAGE_DESC *pageDesc; UINT dt; if (mmuPageDescGet (transTbl, virtAddress, &pageDesc) != OK) { errno = S_mmuLib_NO_DESCRIPTOR; return (ERROR); } dt = pageDesc->generic.pdt; if (dt == PDT_INVALID) { errno = S_mmuLib_INVALID_DESCRIPTOR; return (ERROR); } if (mmuPageSize == PAGE_SIZE_4K) *physAddress = (void *) ((UINT) pageDesc->pageSize4k.addr << 12); else *physAddress = (void *) ((UINT) pageDesc->pageSize8k.addr << 13); /* add offset into page */ *physAddress = (void *) (((UINT) *physAddress) + ((mmuPageSize == PAGE_SIZE_4K) ? ((unsigned) virtAddress & 0xfff) : ((unsigned) virtAddress & 0x1fff))); return (OK); }/******************************************************************************** mmuCurrentSet - change active translation table** mmuCurrent set is used to change the virtual memory context.* Load the CRP (root pointer) register with the given translation table.**/LOCAL void mmuCurrentSet ( MMU_TRANS_TBL *transTbl /* new active tranlation table */ ) { FAST int oldLev; static BOOL firstTime = TRUE; if (firstTime) { /* write protect all the pages containing the ptes allocated for * the global translation table. Need to do this cause when this * memory is allocated, the global trans tbl doesn't exist yet, * so the state sets fail. */ mmuMemPagesWriteDisable (&mmuGlobalTransTbl); mmuMemPagesWriteDisable (transTbl); firstTime = FALSE; } oldLev = intLock (); localCrp.addr = ((unsigned int) transTbl->pLevel1) >> 9 ; /* movel localCrp, d0; movec d0, srp */ __asm__ ("movel %0, d0; .word 0x4e7b, 0x0807" : : "r" (localCrp): "d0" ); mmuCurrentTransTbl = transTbl; /* flush the address translation cache cause we're in a new context */ __asm__ (".word 0xf518"); /* pflusha */ intUnlock (oldLev); }/******************************************************************************** mmuATCFlush - flush an entry from the address translation cache**/LOCAL void mmuATCFlush ( void *addr ) { __asm__ ( "movel %0, a0; " "movel #1, d0; " ".word 0x4e7b, 0x0001; " /* movec d0, srp */ ".word 0xf508; " /* pflush a0 */ "movel #5, d0; " ".word 0x4e7b, 0x0001; " /* movec d0, srp */ ".word 0xf508; " /* pflush a0 */ : /* outputs */ : "r" (addr) /* inputs */ : "d0", "a0" /* temps */ ); }
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -