⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mmue500lib.c

📁 VxWorks BSP框架源代码包含头文件和驱动
💻 C
📖 第 1 页 / 共 3 页
字号:
/* mmuE500Lib.c - mmu library for PowerPC e500Core series *//* Copyright 2001-2002 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01d,30jul03,dtr  Removing some gloabals no longer required.01c,07jan03,dtr  Adding static TLB entry support.01b,02dec02,dtr  Adding cache support.01a,05nov02,pcs  Remove debug sim_printf*//*DESCRIPTION:*//* includes */#include "vxWorks.h"#include "cacheLib.h"#include "errno.h"#include "intLib.h"#include "stdlib.h"#include "stdio.h"#include "string.h"#include "vmLib.h"#include "sysLib.h"#include "private/memPartLibP.h"#include "private/vmLibP.h"#include "arch/ppc/excPpcLib.h"#include "arch/ppc/vxPpcLib.h"#include "arch/ppc/mmuArchVars.h"#include "arch/ppc/mmuE500Lib.h"/* defines *//* typedefs *//* externals */IMPORT void	mmuPpcPidSet (UINT8 pid);IMPORT UINT32	mmuPpcPidGet (void);IMPORT void	mmuPpcMmucrSet (UINT32 pid);IMPORT UINT32	mmuPpcMmucrGet (void);IMPORT UINT32 	mmuPpcTlbReadEntryWord0 (UINT32 index);IMPORT UINT32	mmuPpcTlbReadEntryWord1 (UINT32 index);IMPORT UINT32	mmuPpcTlbReadEntryWord2 (UINT32 index);IMPORT void 	mmuPpcTlbWriteEntryWord0 (UINT32 word0);IMPORT void 	mmuPpcTlbWriteEntryWord1 (UINT32 word1);IMPORT void 	mmuPpcTlbWriteEntryWord2 (UINT32 word2);IMPORT void 	mmuPpcTlbWriteExecute(UINT32 mas0reg);IMPORT int      mmuPpcE500Tlbie (MMU_TRANS_TBL *pTransTbl,void * effAddr);IMPORT void	mmuPpcAEnable ();IMPORT void	mmuPpcADisable ();IMPORT void	mmuPpcInstTlbMissHandler();IMPORT void	mmuPpcDataTlbMissHandler();IMPORT STATE_TRANS_TUPLE *	mmuStateTransArray;IMPORT int			mmuStateTransArraySize;IMPORT MMU_LIB_FUNCS		mmuLibFuncs;IMPORT int			mmuPageBlockSize;IMPORT BOOL	cacheIToEnable;IMPORT BOOL	cacheDToEnable;IMPORT STATUS	cacheArchEnable (CACHE_TYPE cache);IMPORT STATUS	cacheArchFlush(CACHE_TYPE cache, void *address, size_t bytes);IMPORT STATUS	cacheArchDisableFromMmu (CACHE_TYPE  cache);IMPORT void     mmuE500TlbDynamicInvalidate();IMPORT void     mmuE500TlbStaticInvalidate();/* globals *//* * a translation table to hold the descriptors for the global transparent * translation of physical to virtual memory */MMU_TRANS_TBL * mmuGlobalTransTbl;	/* global translation table */	TLB_ENTRY_DESC *mmuE500StaticTlbArray;/* * An array of 256 translation table pointers is allocated to store up to 255 * (entry 0 unused) unique address maps.  This array is indexed by the PID * value. A value of -1 denotes an unused entry. */MMU_TRANS_TBL *	mmuAddrMapArray [MMU_ADDR_MAP_ARRAY_SIZE];/* locals *//* * This table is used to map vmLib per-page mapping attributes to * the architecture-specific values stored in the TLB.  Omission of * a vmLib attribute combination implies that that combination is not * supported in the architecture-specific MMU library. */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_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 UINT32	mmuE500Selected;		/* mmu type selected *//* forward declarations */LOCAL MMU_TRANS_TBL *	mmuE500TransTblCreate ();LOCAL STATUS		mmuE500TransTblDelete (MMU_TRANS_TBL *transTbl);LOCAL STATUS		mmuE500Enable (BOOL enable);LOCAL STATUS		mmuE500StateSet (MMU_TRANS_TBL *transTbl, void *pageAddr,				     UINT stateMask, UINT state);LOCAL STATUS		mmuE500StateGet (MMU_TRANS_TBL *transTbl, void *pageAddr,				     UINT *state);LOCAL STATUS		mmuE500PageMap (MMU_TRANS_TBL *transTbl,				     void * virtualAddress, void *physPage);LOCAL STATUS		mmuE500GlobalPageMap (void * virtualAddress,				    void * physPage);LOCAL STATUS		mmuE500Translate (MMU_TRANS_TBL * transTbl,				      void * virtAddress, void ** physAddress);LOCAL void		mmuE500CurrentSet (MMU_TRANS_TBL * transTbl);LOCAL STATUS		mmuE500TransTblInit (MMU_TRANS_TBL * pNewTransTbl);LOCAL LEVEL_1_DESC *	mmuE500Lvl1DescAddrGet (MMU_TRANS_TBL *	pTransTbl,				    void * effectiveAddr);LOCAL STATUS		mmuE500Lvl2DescAddrGet (MMU_TRANS_TBL * pTransTbl,				void * effectiveAddr,				LEVEL_2_DESC ** ppLvl2Desc);LOCAL void		mmuE500Lvl1DescUpdate (LEVEL_1_DESC * pLvl1Desc,				LEVEL_1_DESC lvl1Desc);LOCAL STATUS		mmuE500Lvl1DescInit (MMU_TRANS_TBL * pTransTbl,				LEVEL_1_DESC * pLvl1Desc, void * effectiveAddr);LOCAL void		mmuE500Lvl2DescUpdate (LEVEL_2_DESC * pLvl2Desc,				LEVEL_2_DESC lvl2Desc);LOCAL BOOL		mmuE500IsOn (int mmuType);LOCAL UINT8 		mmuE500PidAlloc (MMU_TRANS_TBL *transTbl);LOCAL void 		mmuE500PidFree (UINT8 pid);LOCAL void              mmuE500MemPagesWriteDisable ( MMU_TRANS_TBL * pTransTbl); void	                mmuE500TlbStaticInit (int numDescs, 				              TLB_ENTRY_DESC *pTlbDesc, 				              BOOL cacheAllow);/* locals (need forward declarations) */LOCAL MMU_LIB_FUNCS mmuLibFuncsLocal =    {    mmuE500LibInit,    mmuE500TransTblCreate,    mmuE500TransTblDelete,    mmuE500Enable,    mmuE500StateSet,    mmuE500StateGet,    mmuE500PageMap,    mmuE500GlobalPageMap,    mmuE500Translate,    mmuE500CurrentSet    };/******************************************************************************** mmuE500LibInit - MMU library initialization** This routine initializes data structures used to store mmu page tables* so that subsequent page mapping operations can be performed, and so that* the TLB miss handler exceptions can consult the data structures with* meaningful results.** The staticTlbNum argument specifies how many static TLB entries are* defined in the pStaticTlbDesc array.  TLB indices lower than* staticTlbNum are used for static page mapping.  staticTlbNum also* specifies the lowest TLB index that the mmuE500Lib is allowed to use* for dynamic page mapping.** RETURNS: OK, or ERROR if <mmuType> is incorrect or memory allocation*	failed.*/STATUS mmuE500LibInit    (    int 	mmuType,		/* data and/or instr. MMU to init */    int		staticTlbNum,		/* number of static TLB Entries */    TLB_ENTRY_DESC * pStaticTlbDesc	/* array of static TLB descriptions */    )    {    /* 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, "e500 MMU config failed: either enable I or D MMU, "			  "or remove MMU support\n");	return (ERROR);	}    /* save the Data and/or Instruction MMU selected */    mmuE500Selected = mmuType;    /* initialize the exception table:     * 	At the exception offset, we put a branch instruction (0x48000002)     *  OR'ed with the address of the TLB miss handler.     */    if (mmuType & MMU_INST)	{	if ((UINT32)mmuPpcInstTlbMissHandler > 0x03fffffc)	    {	    strcpy(sysExcMsg, "e500 MMU config failed: TLB miss handler "				"is too far from the vector table\n");	    return (ERROR);	    }	* (int *) _EXC_OFF_INST_MISS = 0x48000002 |			(((int) mmuPpcInstTlbMissHandler) & 0x03fffffc);	CACHE_TEXT_UPDATE((void *)_EXC_OFF_INST_MISS, sizeof(int));	}    if (mmuType & MMU_DATA)	{	if ((UINT32)mmuPpcDataTlbMissHandler > 0x03fffffc)	    {	    strcpy(sysExcMsg, "e500 MMU config failed: TLB miss handler "				"is too far from the vector table\n");	    return (ERROR);	    }	* (int *) _EXC_OFF_DATA_MISS = 0x48000002 |			(((int) mmuPpcDataTlbMissHandler) & 0x03fffffc);	CACHE_TEXT_UPDATE((void *)_EXC_OFF_DATA_MISS, sizeof(int));	}    /* initialize the address map array: a value of -1 denotes an       unused element. */    memset ((void *) mmuAddrMapArray, (int)MMU_ADDR_MAP_ARRAY_INV,				    sizeof (mmuAddrMapArray));    /* Remove old CAM TLB1 entries, leave TLB0 entries as required for mem access*/    mmuE500TlbStaticInvalidate(); /* Just CAMS TLBSEL = 1 */    /* set up the static TLB entries with caching on */    mmuE500TlbStaticInit(staticTlbNum, pStaticTlbDesc, TRUE);    /* create the global translation table */    mmuGlobalTransTbl = mmuE500TransTblCreate();    if (mmuGlobalTransTbl == NULL)	{	strcpy(sysExcMsg, "e500 MMU config failed: could not allocate "	    "global trans table\n");	return (ERROR);	}    /* initialize the PID register (it won't be accessed until MSR[IS,DS]     * gets set later) and invalidate all dynamic TLB entries     */    mmuPpcPidSet (mmuGlobalTransTbl->pid);    /* initialize the data objects that are shared with vmLib.c */    mmuStateTransArray = &mmuStateTransArrayLocal [0];    mmuStateTransArraySize =		sizeof (mmuStateTransArrayLocal) / sizeof (STATE_TRANS_TUPLE);    mmuLibFuncs = mmuLibFuncsLocal;    mmuPageBlockSize = MMU_PAGE_SIZE;    /* Invalidate all dynamic TLB entries before MMU is enabled */    mmuE500TlbDynamicInvalidate();        return (OK);    }/******************************************************************************** mmuE500TransTblCreate - create a new translation table.** RETURNS: address of new object or NULL if allocation failed.*/LOCAL MMU_TRANS_TBL * mmuE500TransTblCreate (void)    {    MMU_TRANS_TBL *	pNewTransTbl;		/* new translation table */    /* allocate a piece of memory to save the new translation table */    pNewTransTbl = (MMU_TRANS_TBL *) malloc (sizeof (MMU_TRANS_TBL));    /* if the memory can not allocated then return the NULL pointer */    if (pNewTransTbl == NULL)    {	return (NULL);    }    /* get a free PID for the new translation table */    pNewTransTbl->pid = mmuE500PidAlloc (pNewTransTbl);    if (pNewTransTbl->pid == 0) /* no free PIDs ! */	{	free ((char *) pNewTransTbl);	return (NULL);	}    /*     * initialize the new translation table.     * If the initialization fails then free the memory and return the NULL     * pointer.     */    if (mmuE500TransTblInit (pNewTransTbl) == ERROR)	{	free ((char *) pNewTransTbl);	return (NULL);	}    /* return the new translation table created */    return (pNewTransTbl);    }/******************************************************************************** mmuE500TransTblInit - initialize a new translation table** Initialize a new translation table.  The level 1 table is copied from the* global translation mmuGlobalTransTbl, so that we will share the global* virtual memory with all other translation tables.** RETURNS: OK, or ERROR if unable to allocate memory.*/LOCAL STATUS mmuE500TransTblInit    (    MMU_TRANS_TBL * pNewTransTbl	/* translation table to initialize */    )    {    /*     * Allocate memory space for a new Level 1 descriptor table.  This memory     * needs to be page aligned because, we write protect all the page tables     * later, and we don't want other variables sharing a page with the page     * table itself.     */    pNewTransTbl->l1TblPtr.pL1Desc =	(LEVEL_1_DESC *) memalign (MMU_PAGE_SIZE, MMU_PAGE_SIZE);    /* if the memory cannot be allocated then return ERROR */    if (pNewTransTbl->l1TblPtr.pL1Desc == NULL)	return (ERROR);    /* invalidate all entries in the table */    memset ((void *) pNewTransTbl->l1TblPtr.pL1Desc, 0x00, MMU_PAGE_SIZE);    if (mmuGlobalTransTbl != NULL)	{	/* copy the global level 1 descriptor table to the new table */	memcpy ((void *) pNewTransTbl->l1TblPtr.pL1Desc,	    (void *) mmuGlobalTransTbl->l1TblPtr.pL1Desc, MMU_PAGE_SIZE);	}    /* In AE, would page protect the new L1 descriptor table here */    return (OK);    }/******************************************************************************** mmuE500TransTblDelete - delete a translation table.** This routine deletes a translation table.** RETURNS: OK always.*/LOCAL STATUS mmuE500TransTblDelete    (    MMU_TRANS_TBL * pTransTbl		/* translation table to be deleted */    )    {    LEVEL_1_DESC 	lvl1Desc;	/* level 1 descriptor */    UINT32		ix;    /* free the PID element for this translation table */    mmuE500PidFree (pTransTbl->pid);    /* free level 2 page tables */    for (ix = 0 ; ix < MMU_LVL_2_DESC_NB; ix++)	{	lvl1Desc = * (pTransTbl->l1TblPtr.pL1Desc + ix);	if (lvl1Desc.field.v)	    free ((void *) (lvl1Desc.l1desc & MMU_LVL_1_L2BA_MSK));	}    /* free the level 1 table */    free ((void *) pTransTbl->l1TblPtr.pL1Desc);    return (OK);    }/******************************************************************************** mmuE500Enable - turn mmu on or off** On the PPCE500, the MMU is always on, so turning it off is a misnomer.* Instead, this function changes the MSR[IS,DS] values, which change which TLB* entries match -- either the static ones that emulate 'real mode', or the ones* that provide dynamic mmu page mapping.** RETURNS: OK*/LOCAL STATUS mmuE500Enable    (    BOOL enable			/* TRUE to enable, FALSE to disable MMU */    )    {    int lockKey;		/* lock key for intUnlock() */    /* lock the interrupt */    lockKey = intLock ();    if (enable)	{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -