📄 mmu800lib.c
字号:
/* update the Level 2 descriptor in table */ mmu800Lvl2DescUpdate (pLvl2Desc, lvl2Desc); mmuPpcTlbie(effectiveAddr); return (OK); }/******************************************************************************** mmu800GlobalPageMap - map physical memory page to global virtual memory page** mmuPpcGlobalPageMap 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 mmu800GlobalPageMap ( void * effectiveAddr, /* effective address */ void * physicalAddr /* physical address */ ) { return (mmu800PageMap (&mmuGlobalTransTbl, effectiveAddr, physicalAddr)); }/******************************************************************************** mmu800Translate - translate a virtual address to a physical address** Traverse the translation table and extract the physical address for the* given virtual address from the level 2 descriptor corresponding to the* virtual address.** RETURNS: OK or ERROR if no level 2 descriptor found for given virtual address.*/LOCAL STATUS mmu800Translate ( MMU_TRANS_TBL * pTransTbl, /* translation table */ void * effectiveAddr, /* effective address */ void ** physicalAddr /* where to place the result */ ) { LEVEL_2_DESC * pLvl2Desc; /* Level 2 descriptor address */ EFFECTIVE_ADDR effAddr; /* effective address */ REAL_ADDRESS realAddr; /* real address */ /* * find the level 2 descriptor corresponding to the <effectiveAddr> * in the translation table pointed to by the <pTransTbl> structure. * If this level 2 descriptor cannot be found then return ERROR. */ if (mmu800Lvl2DescAddrGet (pTransTbl, effectiveAddr, &pLvl2Desc) != OK) { errno = S_mmuLib_NO_DESCRIPTOR; return (ERROR); } /* check if the level 2 descriptor found is valid. If not return ERROR */ if (!pLvl2Desc->v) { errno = S_mmuLib_NO_DESCRIPTOR; return (ERROR); } effAddr = * ((EFFECTIVE_ADDR *) &effectiveAddr); /* build the real address */ realAddr.rpn = pLvl2Desc->rpn; realAddr.po = effAddr.po; * physicalAddr = realAddr.realAddr; return (OK); }/******************************************************************************** mmu800CurrentSet - change active translation table** This function changes the virtual memory context by loading the M_TWB* register with the level 1 table pointer saved in the translation* table structure pointed to by <pTransTbl>.** RETURNS: N/A**/void mmu800CurrentSet ( MMU_TRANS_TBL * pTransTbl /* new active tranlation table */ ) { FAST int lockKey; /* intLock lock key */ static BOOL firstTime = TRUE; /* first time call flag */ if (firstTime) { /* * write protect all the pages containing the descriptors allocated for * the global translation table. Need to do this because when this * memory is allocated, the global translation table doesn't exist yet. */ mmu800MemPagesWriteDisable (&mmuGlobalTransTbl); mmu800MemPagesWriteDisable (pTransTbl); firstTime = FALSE; } lockKey = intLock (); /* * save the level 1 table pointer in the M_TWB register via * mmu800MTwbSet(). If one or both MMUs are turned on then disable * the MMU, set the M_TWB register and re-enable the MMU. */ if (mmu800IsOn (MMU_INST) || mmu800IsOn (MMU_DATA)) { mmu800Enable (FALSE); /* disable the MMU */ mmuPpcMTwbSet (pTransTbl->l1TblPtr.pL1Desc); mmu800Enable (TRUE); /* re-enable the MMU */ } else { mmuPpcMTwbSet (pTransTbl->l1TblPtr.pL1Desc); } mmuPpcTlbInvalidateAll(); intUnlock (lockKey); }/********************************************************************************* mmu800Lvl2DescAddrGet - get the address of a level 2 Desciptor* * This routine finds the address of a level 2 desciptor corresponding to the* <effectiveAddr> in the translation table pointed to by <pTransTbl> structure.* If a matching level 2 Descriptor existe, the routine save the level 2* desciptor address at the address pointed to by <ppLvl2Desc>.* If any level 2 Descriptor matching the <effectiveAddr> is not found then* the function return ERROR.** RETURNS: OK or ERROR.*/LOCAL STATUS mmu800Lvl2DescAddrGet ( MMU_TRANS_TBL * pTransTbl, /* translation table */ void * effectiveAddr, /* effective address */ LEVEL_2_DESC ** ppLvl2Desc /* where to save the lvl 2 desc addr */ ) { LEVEL_1_DESC * pLvl1Desc; /* level 1 descriptor address */ LEVEL_2_TBL_PTR lvl2TblPtr; /* level 2 table pointer */ EFFECTIVE_ADDR effAddr; /* effective address */ /* get address of the level 1 descriptor */ pLvl1Desc = mmu800Lvl1DescAddrGet (pTransTbl, effectiveAddr); /* * check the valid bit. If the level 1 descriptor is not valid than * the level 2 descriptor doesn't exit. In this case return ERROR. */ if (!pLvl1Desc->v) return (ERROR); effAddr.effAddr = effectiveAddr; /* * build the Level 2 descriptor address corresponding to the effective * address pointed to by <effectiveAddr>. */ lvl2TblPtr.l2tb = pLvl1Desc->l2ba; lvl2TblPtr.l2index = effAddr.l2index; lvl2TblPtr.field.reserved = 0; /* * save the level 2 descriptor address at the address * pointed to by <ppLvl2Desc>. */ * ppLvl2Desc = lvl2TblPtr.pL2Desc; return (OK); } /********************************************************************************* mmu800Lvl1DescAddrGet - get the address of a level 1 descriptor ** This function returns the address of the level 1 descriptor corresponding* to the effective address pointed to by <effectiveAddr>. ** RETRUNS: always the address of the level 1 descriptor**/LOCAL LEVEL_1_DESC * mmu800Lvl1DescAddrGet ( MMU_TRANS_TBL * pTransTbl, /* translation table */ void * effectiveAddr /* effective address */ ) { LEVEL_1_TBL_PTR lvl1TblPtr; EFFECTIVE_ADDR effAddr; effAddr = * ((EFFECTIVE_ADDR *) &effectiveAddr); /* * build the Level 1 descriptor address corresponding to the effective * address pointed to by <effectiveAddr>. */ lvl1TblPtr.l1tb = pTransTbl->l1TblPtr.l1tb; lvl1TblPtr.l1index = effAddr.l1index; lvl1TblPtr.field.reserved = 0; return (lvl1TblPtr.pL1Desc); }/********************************************************************************* mmu800Lvl1DescUpdate - update a level 1 descriptor ** This function updates a level 1 desciptor. The addess of the level 1* descriptor is handled by <pLvl1Desc> and the new value of the level 1* descriptor by <lvl1Desc>.** RETURNS: N/A*/LOCAL void mmu800Lvl1DescUpdate ( LEVEL_1_DESC * pLvl1Desc, /* Level 1 descriptor address */ LEVEL_1_DESC lvl1Desc /* Level 1 descriptor */ ) { UINT32 key; if (mmu800IsOn (MMU_INST) || mmu800IsOn (MMU_DATA)) { key = intLock(); /* lock interrupt */ mmu800Enable (FALSE); /* disable the mmu */ pLvl1Desc->l1desc = lvl1Desc.l1desc; /* update the descriptor */ mmu800Enable (TRUE); /* enable the MMU */ intUnlock(key); /* re-enable interrupt */ } else { pLvl1Desc->l1desc = lvl1Desc.l1desc; /* update the descriptor */ } }/********************************************************************************* mmu800Lvl2DescUpdate - update a level 2 descriptor ** This function updates a level 2 desciptor. The addess of the level 2* descriptor is handled by <pLvl2Desc> and the new value of the level 2* descriptor by <lvl2Desc>.** RETURNS: N/A*/LOCAL void mmu800Lvl2DescUpdate ( LEVEL_2_DESC * pLvl2Desc, /* Level 2 descriptor address */ LEVEL_2_DESC lvl2Desc /* Level 2 descriptor */ ) { UINT32 key; if (mmu800IsOn (MMU_INST) || mmu800IsOn (MMU_DATA)) { key = intLock(); /* lock interrupt */ mmu800Enable (FALSE); /* disable the mmu */ pLvl2Desc->l2desc = lvl2Desc.l2desc; /* update the descriptor */ mmu800Enable (TRUE); /* enable the MMU */ intUnlock(key); /* re-enable interrupt */ } else { pLvl2Desc->l2desc = lvl2Desc.l2desc; /* update the descriptor */ } }/********************************************************************************* mmu800IsOn - return the state of the MMU** This function returns TRUE if the MMU selected by <mmuType> is on.** RETURNS: TRUE or FALSE**/LOCAL BOOL mmu800IsOn ( int mmuType /* MMU type to return the state of */ ) { switch (mmuType) { case MMU_INST: /* Instruction MMU to test */ return (vxMsrGet () & _PPC_MSR_DR); break; case MMU_DATA: /* Data MUU to test */ return (vxMsrGet () & _PPC_MSR_IR); break; default: /* default value */ return (FALSE); } }/********************************************************************************* mmu800Show - show the level 1 and 2 desciptor for and effective address** NOTE: For MMU library debug only */void mmu800Show ( MMU_TRANS_TBL * pTransTbl, /* translation table */ void * effectiveAddr /* effective address */ ) { LEVEL_1_DESC * pLvl1Desc; /* level 1 descriptor address */ LEVEL_2_DESC * pLvl2Desc; /* level 2 descriptor address */ LEVEL_1_DESC lvl1Desc; /* level 1 descriptor address */ LEVEL_2_DESC lvl2Desc; /* level 2 descriptor address */ if (pTransTbl==NULL) pTransTbl=&mmuGlobalTransTbl; /* get the level 1 descriptor address */ pLvl1Desc = mmu800Lvl1DescAddrGet (pTransTbl, effectiveAddr); lvl1Desc.l1desc = pLvl1Desc->l1desc; printf ("Level 1:"); printf ("l2ba = 0x%x\n", lvl1Desc.l2ba); printf ("apg = 0x%x\n", lvl1Desc.apg); printf ("g = %d\n", lvl1Desc.g); printf ("ps = 0x%x\n", lvl1Desc.ps); printf ("wt = %d\n", lvl1Desc.wt); printf ("v = %d\n", lvl1Desc.v); if (mmu800Lvl2DescAddrGet (pTransTbl, effectiveAddr, &pLvl2Desc) != OK) return ; lvl2Desc.l2desc=pLvl2Desc->l2desc; printf ("Level 2:"); printf ("rpn = 0x%x\n", lvl2Desc.rpn); printf ("pp1 = 0x%x\n", lvl2Desc.pp); printf ("ppe = 0x%x\n", lvl2Desc.ppe); printf ("c = 0x%x\n", lvl2Desc.c); printf ("spv = 0x%x\n", lvl2Desc.spv); printf ("sps = %d\n", lvl2Desc.sps); printf ("sh = %d\n", lvl2Desc.sh); printf ("ci = %d\n", lvl2Desc.ci); printf ("v = %d\n", lvl2Desc.v); }#if FALSEvoid mmu800TlbShow () { int ix; int dbcam; int dbram0; int dbram1; int ddbcam; int ddbram0; int ddbram1; for (ix=0; ix<32; ix++) { mmuPpcMiCtrSet (ix << 8); dbcam = mmuPpcMiDbcamGet(); dbram0 = mmuPpcMiDbram0Get(); dbram1 = mmuPpcMiDbram1Get(); ddbcam = mmuPpcMdDbcamGet(); ddbram0 = mmuPpcMdDbram0Get(); ddbram1 = mmuPpcMdDbram1Get(); printf ("ix = %d dbcam = 0x%x dbram0 = 0x%x dbram1 = 0x%x\n", ix, dbcam, dbram0, dbram1); printf ("ix = %d ddbcam = 0x%x ddbram0 = 0x%x ddbram1 = 0x%x\n", ix, ddbcam, ddbram0, ddbram1); } }#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -