📄 mmulib.c
字号:
if (mmuEnabled) \ { \ cacheDClearDisable (); \ mmuADisable (); /* switch off MPU */ \ } \ } #define MMU_LOCK(oldLevel) \ { \ if (mmuEnabled) \ { \ mmuAEnable (cacheArchState); \ } \ intIFUnlock (oldLevel); \ } #endif /* (!ARM_HAS_MPU) *//* forward declarations */LOCAL MMU_TRANS_TBL * mmuTransTblCreate (void);LOCAL STATUS mmuTransTblDelete (MMU_TRANS_TBL *transTbl);LOCAL STATUS mmuEnable (BOOL enable);LOCAL STATUS mmuStateGet (MMU_TRANS_TBL *transTbl, void *pageAddr, UINT *state);LOCAL STATUS mmuPageMap (MMU_TRANS_TBL *transTbl, void *virtAddr, void *physPage); #if (ARM_HAS_MPU)LOCAL STATUS mmuGlobalPageMap (void *virtAddr, void *physPage, UINT len); #elseLOCAL STATUS mmuGlobalPageMap (void *virtAddr, void *physPage); #endifLOCAL STATUS mmuTranslate (MMU_TRANS_TBL *transTbl, void *virtAddr, void **physAddress);LOCAL void mmuCurrentSet (MMU_TRANS_TBL *transTbl); #if (!ARM_HAS_MPU)LOCAL STATUS mmuStateSet (MMU_TRANS_TBL *transTbl, void *pageAddr, UINT stateMask, UINT state);LOCAL STATUS mmuPteGet (MMU_TRANS_TBL *pTransTbl, void *virtAddr, PTE **result);LOCAL STATUS mmuVirtualPageCreate (MMU_TRANS_TBL *thisTbl, void *virtPageAddr);LOCAL void * mmuDummy (void * address); #else /* (!ARM_HAS_MPU) */LOCAL STATUS mmuStateSetRegion (MMU_TRANS_TBL *transTbl, void *pageAddr, UINT stateMask, UINT state, UINT32 size); #endif /* (!ARM_HAS_MPU) *//* For the new architectures, this is local to this file */LOCAL STATUS mmuLibInit (int pageSize); #if (!ARM_HAS_MPU)/* * The following is not called by the higher level routines, but is * used internally to make setting the state of multiple pages easier. */LOCAL STATUS mmuStateSetMultiple (MMU_TRANS_TBL *transTbl, void *pageAddr, UINT stateMask, UINT state, int cnt); #endif /* (!ARM_HAS_MPU) *//* Used internally as well */LOCAL STATUS mmuTransTblInit (MMU_TRANS_TBL *newTransTbl);/* globals */ #if (!ARM_HAS_MPU)/* * We're using generic libraries now so these are local to * this file, and should not be accessed by users. They are set to the * function pointers passed in as parameters to mmuLibInstall(). */LOCAL void * (* _func_armVirtToPhys) (void *) = NULL;LOCAL void * (* _func_armPhysToVirt) (void *) = NULL;/* locals *//* the memory partition id for the memory source for the page tables etc. */LOCAL PART_ID mmuPageSource = NULL;/* * The global memory translation table: * a translation table to hold the descriptors for the global transparent * translation of physical to virtual memory */LOCAL MMU_TRANS_TBL mmuGlobalTransTbl;/* * Array of booleans used to keep track of sections of virtual memory defined * as global. It could be declared as BOOL *, but save space by declaring it * as UINT8 *. It could even be done as a bit array. */LOCAL UINT8 * globalPageBlock;/* * A pointer to an array , "mini-heap", of 256 second level page tables * (1 KB) beginning on a mmuPageSize boundary. */LOCAL UINT8 *mmuSecondLevelMiniHeap = NULL;/* * The index into the current mini-heap. */LOCAL UINT32 mmuSecondLevelMiniHeap_Index = 0;/* * The max number of second level tables within * a mini-heap. This is set to a default value in * mmuLibInit. It can be set by the bsp prior to * mmuLibInit being called. The actual size of the mini-heap * is calculated back from this value. */#define mmuSecondLevelMiniHeap_Max FN(mmu,SecondLevelMiniHeap_Max)UINT32 mmuSecondLevelMiniHeap_Max = 0;/* * Actual size, in bytes, of the allocated mini-heap. * calculated in mmuLibInit after mmuSecondLevelMiniHeap_Max * is established. */LOCAL UINT32 mmuSecondLevelMiniHeap_Size = 0;/* * Size in bytes of a second level page table. */ #define L2_PTE_SIZE 1024/* * Number of L2 Pte entries per page. */ #define L2_PTE_PER_PAGE (mmuPageSize / L2_PTE_SIZE )/* * Default size of the mini-heap. */ #define PAGES_PER_MINI_HEAP 4 #endif /* !ARM_HAS_MPU */LOCAL int mmuPageSize; /* size of MMU pages in bytes */LOCAL BOOL mmuEnabled;/* * The table used to define the mapping between the architecture-independent * values (VM_*) and the architecture-specific values (MMU_*) */LOCAL STATE_TRANS_TUPLE mmuStateTransArrayLocal [] = { {VM_STATE_MASK_VALID, MMU_STATE_MASK_VALID, VM_STATE_VALID, MMU_STATE_VALID}, {VM_STATE_MASK_VALID, MMU_STATE_MASK_VALID, VM_STATE_VALID_NOT, MMU_STATE_VALID_NOT},#if (!ARM_HAS_MPU) /* current MPUs do not allow us to mark pages as read-only from SVC code */ {VM_STATE_MASK_WRITABLE, MMU_STATE_MASK_WRITABLE, VM_STATE_WRITABLE, MMU_STATE_WRITABLE}, {VM_STATE_MASK_WRITABLE, MMU_STATE_MASK_WRITABLE, VM_STATE_WRITABLE_NOT, MMU_STATE_WRITABLE_NOT},#endif {VM_STATE_MASK_CACHEABLE, MMU_STATE_MASK_CACHEABLE, VM_STATE_CACHEABLE, MMU_STATE_CACHEABLE}, {VM_STATE_MASK_CACHEABLE, MMU_STATE_MASK_CACHEABLE, VM_STATE_CACHEABLE_NOT, MMU_STATE_CACHEABLE_NOT},#if (ARMMMU == ARMMMU_XSCALE) {VM_STATE_MASK_EX_CACHEABLE, MMU_STATE_MASK_EX_CACHEABLE, VM_STATE_EX_CACHEABLE, MMU_STATE_EX_CACHEABLE}, {VM_STATE_MASK_EX_CACHEABLE, MMU_STATE_MASK_EX_CACHEABLE, VM_STATE_EX_CACHEABLE_NOT, MMU_STATE_EX_CACHEABLE_NOT},#endif {VM_STATE_MASK_BUFFERABLE, MMU_STATE_MASK_CACHEABLE, VM_STATE_BUFFERABLE, MMU_STATE_BUFFERABLE}, {VM_STATE_MASK_BUFFERABLE, MMU_STATE_MASK_CACHEABLE, VM_STATE_BUFFERABLE_NOT, MMU_STATE_BUFFERABLE_NOT},#if (ARMMMU == ARMMMU_XSCALE) {VM_STATE_MASK_EX_BUFFERABLE, MMU_STATE_MASK_EX_CACHEABLE, VM_STATE_EX_BUFFERABLE, MMU_STATE_EX_BUFFERABLE}, {VM_STATE_MASK_EX_BUFFERABLE, MMU_STATE_MASK_EX_CACHEABLE, VM_STATE_EX_BUFFERABLE_NOT, MMU_STATE_EX_BUFFERABLE_NOT},#endif#if ARMCACHE_HAS_WRITETHROUGH {VM_STATE_MASK_CACHEABLE, MMU_STATE_MASK_CACHEABLE, VM_STATE_CACHEABLE_WRITETHROUGH, MMU_STATE_CACHEABLE_WRITETHROUGH},#endif#if ((ARMMMU == ARMMMU_SA1100) || (ARMMMU == ARMMMU_SA1500)) {VM_STATE_MASK_CACHEABLE, MMU_STATE_MASK_CACHEABLE, VM_STATE_CACHEABLE_MINICACHE, MMU_STATE_CACHEABLE_MINICACHE},#endif#if (ARMMMU == ARMMMU_XSCALE) {VM_STATE_MASK_EX_CACHEABLE, MMU_STATE_MASK_EX_CACHEABLE, VM_STATE_CACHEABLE_MINICACHE, MMU_STATE_CACHEABLE_MINICACHE},#endif };LOCAL MMU_LIB_FUNCS mmuLibFuncsLocal = { mmuLibInit, mmuTransTblCreate, mmuTransTblDelete, mmuEnable,#if (ARM_HAS_MPU) mmuStateSetRegion,#else mmuStateSet,#endif mmuStateGet, mmuPageMap, mmuGlobalPageMap, mmuTranslate, mmuCurrentSet };#endif /* (ARMMMU != ARMMMU_NONE) */IMPORT STATE_TRANS_TUPLE *mmuStateTransArray;IMPORT int mmuStateTransArraySize;IMPORT MMU_LIB_FUNCS mmuLibFuncs;IMPORT int mmuPageBlockSize;IMPORT int ffsMsb (UINT32 val);IMPORT int ffsLsb (UINT32 val);#if (!ARM_HAS_MPU)IMPORT PART_ID (* _func_armPageSource) (void);#endif /* !ARM_HAS_MPU *//* * Variable used to keep desired cache enable state: layout as MMUCR * (variously I, Z, W and C bits for different cache/MMUs). This is * used by mmuALib when enabling the MMU, to enable the appropriate cache * features that cannot be enabled when the MMU is disabled. See * cacheArchEnable(). For example, we must disable the D-cache, * write-buffer and branch-prediction when disabling the MMU on most * cache/MMUs and need to know what to turn back on when the MMU is * re-enabled.*/IMPORT UINT32 cacheArchState;/* * The function pointer is declared in a different module, and does not * have a unique-ified name. This is the function pointer that is set to * point to the initialization routine of the appropriate variant of this * file. */IMPORT FUNCPTR sysMmuLibInit;/********************************************************************************* mmuLibInstall - install specific ARM MMU library function pointers** This routine is provided as a hook so that calling this routine* selects the specific MMU library. It also allows any virtual <->* physical address translation routines provide by the BSP to be passed* to the MMU library as parameters rather than as global data.** INTERNAL* This routine is called (from sysHwInit0()), before sysHwInit has been* called, and before BSS has been cleared.** RETURNS: N/A**/void mmuLibInstall ( void * (physToVirt) (void *), void * (virtToPhys) (void *) ) { static BOOL initialized = FALSE; /* protect against being called twice */ if (initialized) return; /* * Set the function pointers appropriate for the type of MMU. On 710a, * we must use the versions of these routines that use a soft-copy * of the MMU Control Register. */#if (ARMMMU == ARMMMU_710A) mmuCrGet = mmuSoftCrGet; mmuModifyCr = mmuModifySoftCr;#else mmuCrGet = mmuHardCrGet; mmuModifyCr = mmuModifyHardCr;#endif#if (!ARM_HAS_MPU) _func_armPhysToVirt = physToVirt; _func_armVirtToPhys = virtToPhys;#endif /* (!ARM_HAS_MPU) */ sysMmuLibInit = mmuLibInit; initialized = TRUE; return; }/******************************************************************************** mmuLibInit - initialize MMU handling module (ARM)** Build a dummy translation table that will hold the page table entries* for the global translation table. The MMU remains disabled upon* completion. Note that this routine is global so that it may be referred to* in usrConfig.c to pull in the correct mmuLib for the specific architecture.** RETURNS: OK, or ERROR.** ERRNO:* S_mmuLib_INVALID_PAGE_SIZE*/LOCAL STATUS mmuLibInit ( int pageSize /* system pageSize (must be 4096) */ ) {#if (ARMMMU != ARMMMU_NONE) static BOOL initialized = FALSE;#if (!ARM_HAS_MPU) LEVEL_1_DESC * pL1;#endif /* protect against being called twice */ if (initialized) return OK;#if (!ARM_HAS_MPU) /* * If the BSP has not specified a routine to set a memory partition to * obtain pages from, then initialize mmuPageSource to the system memory * partition. */ if (_func_armPageSource == NULL) mmuPageSource = memSysPartId; else mmuPageSource = _func_armPageSource (); /* * If the BSP has not specified routines for address translation, then * assume that virtual and physical addresses for page table entries * will be identical. Install dummy translation routine. */ if (_func_armPhysToVirt == NULL) _func_armPhysToVirt = mmuDummy; if (_func_armVirtToPhys == NULL) _func_armVirtToPhys = mmuDummy;#endif /* !ARM_HAS_MPU */ /* initialize the data objects that are shared with vmLib.c */ mmuStateTransArray = &mmuStateTransArrayLocal [0];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -