📄 mmuppclib.c
字号:
/* mmuPpcLib.c - mmu library for PowerPc *//* Copyright 1984-2002 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01n,12sep02,pch SPR 80274: add support for PPC750FX additional BAT registers01m,27may02,kab Extra BAT only available on PPC60401l,30apr02,mil Fixed mmuPpcTranslate() to contain page offset (SPR #76143).01k,28apr02,pcs Add MPC 7x5/74x5 extra bat support01j,25apr02,pch SPR 74926: don't connect to unused vector SPR 67973: add exception message for MMU config failure01i,14nov01,dtr Addition of full 32bit branch for mmu excection vectors.01h,29oct98,elg added some variables declarations in mmuArchVars.c01g,18aug98,tpr added PowerPC EC 603 support.01f,20dec96,tpr replaced cacheDisable()0 by cacheDisableFromMmu().01e,25jul96,tpr removed bug with PTE address get function (SPR #6582).01d,23feb96,tpr added documentation + code clean up.01c,14feb96,tpr slipt PPC603 and PPC604.01b,10oct95,kvk enclosed 603 specific stuff for itself.01a,08sep95,tpr written.*//*DESCRIPTION:*//* includes */#include "vxWorks.h"#include "errno.h"#include "cacheLib.h"#include "vmLib.h"#include "sysLib.h"#include "string.h"#include "stdlib.h"#include "intLib.h"#include "private/memPartLibP.h"#include "private/vmLibP.h"#include "arch/ppc/excPpcLib.h"#include "arch/ppc/ivPpc.h"#include "arch/ppc/mmuPpcLib.h"#include "arch/ppc/mmuArchVars.h"/* defines */#define PAGE_SIZE 4096 /* page size of 4K *//* typedefs */typedef struct hashTabInfo { UINT hashTabOrgMask; UINT hastTabMask; UINT pteTabMinSize; } HASH_TAB_INFO ;/* externals */IMPORT u_int mmuPpcSrGet ();IMPORT void mmuPpcSrSet ();IMPORT void mmuPpcTlbie ();IMPORT void mmuPpcAEnable ();IMPORT void mmuPpcADisable ();IMPORT void mmuPpcSdr1Set ();IMPORT u_int mmuPpcSdr1Get ();IMPORT void mmuPpcBatInit (int * pSysBatDesc);#if (CPU == PPC604)IMPORT void mmuPpcExtraBatInit (int * pSysBatDesc);IMPORT void mmuPpcExtraBatEnableMPC74x5(void);IMPORT void mmuPpcExtraBatEnableMPC7x5(void);#endif /* PPC604 */IMPORT void mmuPpcTlbInvalidateAll(void);IMPORT STATUS cacheArchEnable (CACHE_TYPE cache);IMPORT STATUS cacheArchDisableFromMmu (CACHE_TYPE cache);#if ((CPU == PPC603) || (CPU == PPCEC603))IMPORT void mmuPpcInstMissHandler();IMPORT void mmuPpcDataLoadMissHandler();IMPORT void mmuPpcDataStoreMissHandler();IMPORT void mmuPpcInstMissHandlerLongJump();IMPORT void mmuPpcDataLoadMissHandlerLongJump();IMPORT void mmuPpcDataStoreMissHandlerLongJump();#endif /* ((CPU == PPC603) || (CPU == PPCEC603)) */IMPORT STATE_TRANS_TUPLE * mmuStateTransArray;IMPORT int mmuStateTransArraySize;IMPORT MMU_LIB_FUNCS mmuLibFuncs;IMPORT int mmuPageBlockSize;IMPORT BOOL cacheIToEnable;IMPORT BOOL cacheDToEnable;IMPORT BOOL excExtendedVectors;/* locals */FUNCPTR _pSysBatInitFunc = NULL;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}, {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}, {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}, {VM_STATE_MASK_CACHEABLE, MMU_STATE_MASK_CACHEABLE, VM_STATE_CACHEABLE_WRITETHROUGH, MMU_STATE_CACHEABLE_WRITETHROUGH}, {VM_STATE_MASK_MEM_COHERENCY, MMU_STATE_MASK_MEM_COHERENCY, VM_STATE_MEM_COHERENCY, MMU_STATE_MEM_COHERENCY}, {VM_STATE_MASK_MEM_COHERENCY, MMU_STATE_MASK_MEM_COHERENCY, VM_STATE_MEM_COHERENCY_NOT, MMU_STATE_MEM_COHERENCY_NOT}, {VM_STATE_MASK_GUARDED, MMU_STATE_MASK_GUARDED, VM_STATE_GUARDED, MMU_STATE_GUARDED}, {VM_STATE_MASK_GUARDED, MMU_STATE_MASK_GUARDED, VM_STATE_GUARDED_NOT, MMU_STATE_GUARDED_NOT}, };LOCAL HASH_TAB_INFO mmuPpcHashTabInfo[] = { {MMU_SDR1_HTABORG_8M, MMU_SDR1_HTABMASK_8M, MMU_PTE_MIN_SIZE_8M}, {MMU_SDR1_HTABORG_16M, MMU_SDR1_HTABMASK_16M, MMU_PTE_MIN_SIZE_16M}, {MMU_SDR1_HTABORG_32M, MMU_SDR1_HTABMASK_32M, MMU_PTE_MIN_SIZE_32M}, {MMU_SDR1_HTABORG_64M, MMU_SDR1_HTABMASK_64M, MMU_PTE_MIN_SIZE_64M}, {MMU_SDR1_HTABORG_128M, MMU_SDR1_HTABMASK_128M, MMU_PTE_MIN_SIZE_128M}, {MMU_SDR1_HTABORG_256M, MMU_SDR1_HTABMASK_256M, MMU_PTE_MIN_SIZE_256M}, {MMU_SDR1_HTABORG_512M, MMU_SDR1_HTABMASK_512M, MMU_PTE_MIN_SIZE_512M}, {MMU_SDR1_HTABORG_1G, MMU_SDR1_HTABMASK_1G, MMU_PTE_MIN_SIZE_1G}, {MMU_SDR1_HTABORG_2G, MMU_SDR1_HTABMASK_2G, MMU_PTE_MIN_SIZE_2G}, {MMU_SDR1_HTABORG_4G, MMU_SDR1_HTABMASK_4G, MMU_PTE_MIN_SIZE_4G}, };LOCAL int mmuPpcHashTabInfoNumEnt = NELEMENTS (mmuPpcHashTabInfo);/* * a translation table to hold the descriptors for the global transparent * translation of physical to virtual memory */LOCAL MMU_TRANS_TBL mmuGlobalTransTbl; /* global translation table */ LOCAL u_int mmuPpcSelected; /* mmu type selected *//* forward declarations */LOCAL MMU_TRANS_TBL * mmuPpcTransTblCreate ();LOCAL STATUS mmuPpcTransTblDelete (MMU_TRANS_TBL *transTbl);LOCAL STATUS mmuPpcEnable (BOOL enable);LOCAL STATUS mmuPpcStateSet (MMU_TRANS_TBL *transTbl, void *pageAddr, UINT stateMask, UINT state);LOCAL STATUS mmuPpcStateGet (MMU_TRANS_TBL *transTbl, void *pageAddr, UINT *state);LOCAL STATUS mmuPpcPageMap (MMU_TRANS_TBL *transTbl, void * virtualAddress, void *physPage);LOCAL STATUS mmuPpcGlobalPageMap (void * virtualAddress, void * physPage);LOCAL STATUS mmuPpcTranslate (MMU_TRANS_TBL * transTbl, void * virtAddress, void ** physAddress);LOCAL void mmuPpcCurrentSet (MMU_TRANS_TBL * transTbl);LOCAL void mmuPpcPtegAddrGet (MMU_TRANS_TBL * pTransTbl, void * effectiveAddr, PTEG ** ppPteg1, PTEG ** ppPteg2, u_int * pVirtualSegId, u_int * abbrevPageIndex);LOCAL void mmuPpcPteUpdate (PTE * pteAddr, PTE * pteVal);LOCAL STATUS mmuPpcTransTblInit (MMU_TRANS_TBL * pNewTransTbl);LOCAL STATUS mmuPpcPteGet (MMU_TRANS_TBL * pTransTbl, void * effectiveAddr, PTE ** ppPte);#if (CPU == PPC604)void mmuPpcBatInitMPC74x5 (UINT32 *pSysBatDesc);void mmuPpcBatInitMPC7x5 (UINT32 *pSysBatDesc);#endif /* PPC604 */LOCAL MMU_LIB_FUNCS mmuLibFuncsLocal = { mmuPpcLibInit, mmuPpcTransTblCreate, mmuPpcTransTblDelete, mmuPpcEnable, mmuPpcStateSet, mmuPpcStateGet, mmuPpcPageMap, mmuPpcGlobalPageMap, mmuPpcTranslate, mmuPpcCurrentSet };/******************************************************************************** mmuPpcLibInit - initialize module**/STATUS mmuPpcLibInit ( int mmuType, /* data and/or instruction mmu */ int * pPhysMemDesc, /* physical memory desciption */ int elementNb, /* element nbr in physical mem desc */ int * pSysBatDesc /* bat register description */ ) { u_int entryNb; /* entry number */ u_int memSize = 0; /* total memorie size */ SR srVal; u_int position; PHYS_MEM_DESC * pMemDesc;#if ((CPU == PPC603) || (CPU == PPCEC603)) UINT32 excHandMmu[] = {0x7c0802a6, /* mflr r0 - save link register */ 0x3c200000, /* lis r1,HI(mmuXxxHandler) */ 0x60210000, /* ori r1,r1,LO(mmuXxxHandler) */ 0x7c2803a6, /* mtlr r1 - load link register */ 0x4e800021}; /* blrl */#endif /* ((CPU == PP603) || (CPU == PPCEC603)) */ /* check if the MMU type to initialize is coherent */ if (!(mmuType & MMU_INST) && !(mmuType & MMU_DATA)) { /* * too soon in boot process to print a string, so store one in the * exception message area. */ strcpy(sysExcMsg, "6xx MMU config failed: either enable I or D MMU, " "or remove MMU support\n"); return (ERROR); } /* save the Data and/or Instruction MMU selected */ mmuPpcSelected = mmuType; /* initiliaze the BAT register */ if (pSysBatDesc != NULL) { if( _pSysBatInitFunc == NULL) { mmuPpcBatInit (pSysBatDesc); } else { (*_pSysBatInitFunc) (pSysBatDesc); } mmuPpcTlbInvalidateAll(); }#if ((CPU == PPC603) || (CPU == PPCEC603)) /* initialize the exception table */ if (!excExtendedVectors) { if (mmuType & MMU_INST) { * (int *) _EXC_OFF_INST_MISS = 0x48000002 | (((int) mmuPpcInstMissHandler) & 0x03ffffff); CACHE_TEXT_UPDATE((void *)_EXC_OFF_INST_MISS, sizeof(int)); } if (mmuType & MMU_DATA) { * (int *) _EXC_OFF_LOAD_MISS = 0x48000002 | (((int) mmuPpcDataLoadMissHandler) & 0x03ffffff); CACHE_TEXT_UPDATE((void *)_EXC_OFF_LOAD_MISS, sizeof(int)); * (int *) _EXC_OFF_STORE_MISS = 0x48000002 | (((int) mmuPpcDataStoreMissHandler) & 0x03ffffff); CACHE_TEXT_UPDATE((void *)_EXC_OFF_STORE_MISS, sizeof(int)); } } else { /* * Copy to each vector standard long branch stub, * and load exact handler address into each stub. */ if (mmuType & MMU_INST) { memcpy ((void*)_EXC_OFF_INST_MISS, &excHandMmu[0], sizeof(excHandMmu)); *(int*)(_EXC_OFF_INST_MISS + 0x4) |= MSW((int) mmuPpcInstMissHandlerLongJump); *(int*)(_EXC_OFF_INST_MISS + 0x8) |= LSW((int) mmuPpcInstMissHandlerLongJump); CACHE_TEXT_UPDATE((void *)_EXC_OFF_INST_MISS, sizeof(excHandMmu)); } if (mmuType & MMU_DATA) { memcpy ((void*)_EXC_OFF_LOAD_MISS, &excHandMmu[0], sizeof(excHandMmu)); *(int*)(_EXC_OFF_LOAD_MISS + 0x4) |= MSW((int) mmuPpcDataLoadMissHandlerLongJump); *(int*)(_EXC_OFF_LOAD_MISS + 0x8) |= LSW((int) mmuPpcDataLoadMissHandlerLongJump); CACHE_TEXT_UPDATE((void *)_EXC_OFF_LOAD_MISS, sizeof(excHandMmu)); memcpy ((void*)_EXC_OFF_STORE_MISS, &excHandMmu[0], sizeof(excHandMmu)); *(int*)(_EXC_OFF_STORE_MISS + 0x4) |= MSW((int) mmuPpcDataStoreMissHandlerLongJump); *(int*)(_EXC_OFF_STORE_MISS + 0x8) |= LSW((int) mmuPpcDataStoreMissHandlerLongJump); CACHE_TEXT_UPDATE((void *)_EXC_OFF_STORE_MISS, sizeof(excHandMmu)); } }#endif /* ((CPU == PP603) || (CPU == PPCEC603)) */ /* initialize the Segment Registers */ srVal.bit.t = 0; srVal.bit.ks = 1; srVal.bit.kp = 1; srVal.bit.n = 0; srVal.bit.vsid = 0; for (entryNb = 0; entryNb < 16; entryNb++) /* XXX TPR to fix */ { mmuPpcSrSet (entryNb, srVal.value); srVal.bit.vsid += 0x100; } pMemDesc = (PHYS_MEM_DESC *) pPhysMemDesc; /* * compute the total size of memory to map by reading the * sysPhysMemDesc[] table. */ for (entryNb = 0; entryNb < sysPhysMemDescNumEnt; entryNb++) { memSize += sysPhysMemDesc[entryNb].len; } /* */ memSize = (memSize - 1) / 0x800000 ; position = 0; do memSize = memSize >> 1; while ((++position < mmuPpcHashTabInfoNumEnt) & (memSize != 0)); mmuGlobalTransTbl.hTabOrg = mmuPpcHashTabInfo[position].hashTabOrgMask; mmuGlobalTransTbl.hTabMask = mmuPpcHashTabInfo[position].hastTabMask; mmuGlobalTransTbl.pteTableSize = mmuPpcHashTabInfo[position].pteTabMinSize; /* * allocate memory to save PTEs * The mimimum size depends of the total memory to map. */ mmuGlobalTransTbl.hTabOrg &= (u_int) memalign (mmuGlobalTransTbl.pteTableSize, mmuGlobalTransTbl.pteTableSize); /* invalided all PTE in the table */ memset ((void *) mmuGlobalTransTbl.hTabOrg, 0x00, mmuGlobalTransTbl.pteTableSize); /* initialize the data objects that are shared with vmLib.c */ mmuStateTransArray = &mmuStateTransArrayLocal [0]; mmuStateTransArraySize = sizeof (mmuStateTransArrayLocal) / sizeof (STATE_TRANS_TUPLE); mmuLibFuncs = mmuLibFuncsLocal; mmuPageBlockSize = PAGE_SIZE; return (OK); }#if FALSE/******************************************************************************** mmuPpcMemPagesWriteEnable - write enable the memory holding PTEs** Each translation table has a linked list of physical pages that contain its* table and page descriptors. Before you can write into any descriptor, you* must write enable the page it is contained in. This routine enables all* the pages used by a given translation table.**/LOCAL STATUS mmuPpcMemPagesWriteEnable ( MMU_TRANS_TBL * pTransTbl ) { u_int thisPage; thisPage = pTransTbl->hTabOrg; while (thisPage < (pTransTbl->hTabOrg + pTransTbl->pteTableSize)) { if (mmuPpcStateSet (pTransTbl, (void *) thisPage, MMU_STATE_MASK_WRITABLE, MMU_STATE_WRITABLE) == ERROR) return (ERROR) ; thisPage += PAGE_SIZE; } return (OK); }#endif /* FALSE *//******************************************************************************** mmuPpcMemPagesWriteDisable - write disable memory holding PTEs** Memory containing translation table descriptors is marked as read only* to protect the descriptors from being corrupted. This routine write protects* all the memory used to contain a given translation table's descriptors.**/LOCAL void mmuPpcMemPagesWriteDisable ( MMU_TRANS_TBL * pTransTbl
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -