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

📄 mmu440lib.c

📁 VxWorks BSP框架源代码包含头文件和驱动
💻 C
📖 第 1 页 / 共 4 页
字号:
/* mmu440Lib.c - mmu library for PowerPC 440 series *//* Copyright 2001-2003 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01e,30jan03,jtp  SPR 85792 support caching by allowing no selected MMUs01d,02jan03,jtp  SPR 82770 move mmuPpcSelected to mmuArchVars.c01c,08may02,pch  fix copy/paste error in previous checkin:		 this is a 440, not a 405.01b,25apr02,pch  SPR 74926: don't connect to unused vector01a,17apr02,jtp	 written.*//*DESCRIPTION:mmu440Lib.c provides the architecture dependent routines that directlycontrol the memory management unit for the PowerPC 440 series.  Itprovides routines that are called by the higher level architectureindependent routines in vmLib.c or vmBaseLib.c.The PPC440 is a BookE Specification processor.  BookE Memory ManagementUnits (MMU) are always on, and cannot be turned off.  The PPC440GPcontains a cache of 64 virtual-to-physical page mappings in aTranslation Lookaside Buffer (TLB) cache.  Each cache entry can beaddressed with a TLB Entry index.Lower-numbered TLB indexes are used to set up a static mapping ofmemory.  Typically large blocks of memory (256MB chunks) are mapped viaeach static TLB entry. The lowest TLB entries set the Translation Space(TS) field of the TLB entries to 0. These entries are used when the MSRregister IS and/or DS fields are set to '0', and are used to emulateconventional 'real mode' access.  In the bootrom, romInit.s isresponsible for initializing a bare-bones static mapping.Once booted, a description of the desired static TLB mappings is passedin to mmu440LibInit, and it reinitializes the static TLB entries,overwriting the ones established by romInit. A few of these entries havethe TS field set to 1, for use when the vmLib is 'enabled', and are usedto map program addresses to physical addresses that cannot be expressedin a 32 bit pointer. Once initialized, these lower-numbered TLB entriesare largely left unperturbed by the mmu440Lib.Higher-numbered TLB indexes are used by the 440 MMU library todynamically map memory.  The minimum usable TLB index is defined by theBSP and passed in as an argument to mmu440LibInit during systeminitialization.  All the pages mapped by this library set the TS(Translation Space) field of the TLB entries to 1.  These entries areused when the MSR IS and/or DS fields are set to '1'. The blocks ofmemory mapped are 4KB (MMU_PAGE_SIZE) in size. As a result, the TLBcache entries can only map a small fraction of the available programaddress space and the TLB Miss handler recycles them as needed in around-robin fashion.This implementation supports the use of multiple program address spaces.TLB Entries with a TID field of 0 (causing them to match all programaddress spaces) are used for the static mapping. TLB Entries withnon-zero TID fields are used for dynamic mapping.  The global transtable (used for the kernel's initial vm context) uses a TID of 2, andsubsequent trans tables are given a copy of the global trans table's L1table as they are created.Cache library interaction: The Book E specification and the PPC440GPimplementation do not provide a means to set global cache enable/disablewithout manipulating individual TLB entries.  Therefore, as in thePPC60X series kernels, changes to the cacheability of individual blocksand pages of memory are deferred to this MMU library: enabling the cacherequires the MMU library.Furthermore, since cacheability is controlled by a single pair of bits(W, I) on a per-TLB basis, the cacheability of instructions versus datawithin the same virtual address mapping cannot be independentlycontrolled. In the PPC440 the selections for data and instruction cacheenablement and mode must be identical.Lastly, the MMU library may be configured but neither I nor D MMUselected for enablement. This permits the MMU libary to set up thestatic TLB mappings and enable the cache on them, but it does notmake use of the dynamic TLB entries. This may be desired for someapplications.For more details on the 440's cache implementation, see cache440ALib.s.*//* 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/mmu440Lib.h"/* defines *//* typedefs *//* * The MMUCR register is important for TLB entry search, read and write: * *   Search: sts and stid fields are used by tlbsx instruction. *   Read: stid field is set by a tlbre 0 instruction *   Write: stid field is used by tlbwe 0 instruction */typedef union    {    struct	{	UINT32	rsvd1:7;	UINT32	swoa:1;		/* Store W/O Allocate */	UINT32	rsvd2:1;	UINT32	u1te:1;		/* U1 Transient Enable */	UINT32	u2swoae:1;	/* U2 Store W/O Allocate Enable */	UINT32	rsvd3:1;	UINT32	dulxe:1;	/* Data Cache Unlock Exc Enable */	UINT32	iulxe:1;	/* Instr Cache Unlock Exc Enable */	UINT32	rsvd4:1;	UINT32	sts:1;		/* Search Translation Space */	UINT32	rsvd5:8;	UINT32	stid:8;		/* Search Translation ID */	} field;    UINT32 word;    } MMUCR_REG;/* 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 int	mmuPpcTlbSearch (void * effAddr);IMPORT void 	mmuPpcTlbWriteEntryWord0 (UINT32 index, UINT32 word0);IMPORT void 	mmuPpcTlbWriteEntryWord1 (UINT32 index, UINT32 word1);IMPORT void 	mmuPpcTlbWriteEntryWord2 (UINT32 index, UINT32 word2);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	cache440ToEnable;STATUS		cache440Enable (CACHE_TYPE cache);IMPORT STATUS	cacheArchFlush(CACHE_TYPE cache, void *address, size_t bytes);IMPORT UINT32	mmuPpcSelected;		/* mmu type selected *//* 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 */	/* * 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];/* * TLB replacement counter: mmuPpcTlbNext is used by the page fill exception * handler.  We use a round-robin strategy to determine which TLB entry to * replace.  mmuPpcTlbMin provides a minimum value, so that assigned Tlbs are * selected from mmuPpcTlbMin up to mmuPpcTlbMax. */UINT32	mmuPpcTlbNext;UINT32	mmuPpcTlbMin;UINT32	mmuPpcTlbMax;#ifdef DEBUG_MISS_HANDLERUINT32	mmuPpcITlbMisses;UINT32	mmuPpcITlbMissArray[256];UINT32	mmuPpcDTlbMisses;UINT32	mmuPpcDTlbMissArray[256];UINT32	mmuPpcITlbErrors;UINT32	mmuPpcDTlbErrors;#endif /* DEBUG_MISS_HANDLER *//* * pointer to array of static TLB entries, used mostly in conjunction * with the cache library to enable/disable caching */TLB_ENTRY_DESC *mmu440StaticTlbArray;/* 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}    };/* forward declarations */LOCAL MMU_TRANS_TBL *	mmu440TransTblCreate ();LOCAL STATUS		mmu440TransTblDelete (MMU_TRANS_TBL *transTbl);LOCAL STATUS		mmu440Enable (BOOL enable);LOCAL STATUS		mmu440StateSet (MMU_TRANS_TBL *transTbl, void *pageAddr,				     UINT stateMask, UINT state);LOCAL STATUS		mmu440StateGet (MMU_TRANS_TBL *transTbl, void *pageAddr,				     UINT *state);LOCAL STATUS		mmu440PageMap (MMU_TRANS_TBL *transTbl,				     void * virtualAddress, void *physPage);LOCAL STATUS		mmu440GlobalPageMap (void * virtualAddress,				    void * physPage);LOCAL STATUS		mmu440Translate (MMU_TRANS_TBL * transTbl,				      void * virtAddress, void ** physAddress);LOCAL void		mmu440CurrentSet (MMU_TRANS_TBL * transTbl);LOCAL STATUS		mmu440TransTblInit (MMU_TRANS_TBL * pNewTransTbl);LOCAL LEVEL_1_DESC *	mmu440Lvl1DescAddrGet (MMU_TRANS_TBL *	pTransTbl,				    void * effectiveAddr);LOCAL STATUS		mmu440Lvl2DescAddrGet (MMU_TRANS_TBL * pTransTbl,				void * effectiveAddr,				LEVEL_2_DESC ** ppLvl2Desc);LOCAL void		mmu440Lvl1DescUpdate (LEVEL_1_DESC * pLvl1Desc,				LEVEL_1_DESC lvl1Desc);LOCAL STATUS		mmu440Lvl1DescInit (MMU_TRANS_TBL * pTransTbl,				LEVEL_1_DESC * pLvl1Desc, void * effectiveAddr);LOCAL void		mmu440Lvl2DescUpdate (LEVEL_2_DESC * pLvl2Desc,				LEVEL_2_DESC lvl2Desc);LOCAL BOOL		mmu440IsOn (int mmuType);LOCAL UINT8 		mmu440PidAlloc (MMU_TRANS_TBL *transTbl);LOCAL void 		mmu440PidFree (UINT8 pid);LOCAL void 		mmu440Tlbie (MMU_TRANS_TBL *pTransTbl, void * effAddr);LOCAL void		mmu440TlbDynamicInvalidate (void);LOCAL void		mmu440TlbStaticInit (int numDescs, TLB_ENTRY_DESC *				pTlbDesc, BOOL cacheAllow);/* locals (need forward declarations) */LOCAL MMU_LIB_FUNCS mmuLibFuncsLocal =    {    mmu440LibInit,    mmu440TransTblCreate,    mmu440TransTblDelete,    mmu440Enable,    mmu440StateSet,    mmu440StateGet,    mmu440PageMap,    mmu440GlobalPageMap,    mmu440Translate,    mmu440CurrentSet    };/******************************************************************************** mmu440LibInit - 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 mmu440Lib is allowed to use* for dynamic page mapping.** RETURNS: OK, or ERROR if <mmuType> is incorrect or memory allocation*	failed.*/STATUS mmu440LibInit    (    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 */    )    {    /* save the Data and/or Instruction MMU selected */    mmuPpcSelected = mmuType;    /* set up the static TLB entries with caching off */    mmu440TlbStaticInit(staticTlbNum, pStaticTlbDesc, FALSE);    /* initialize the TLB replacement counter to the minimum tlb index */    mmuPpcTlbMin = staticTlbNum;    mmuPpcTlbMax = N_TLB_ENTRIES;    mmuPpcTlbNext = mmuPpcTlbMin;    mmu440StaticTlbArray = pStaticTlbDesc;    /* 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, "440 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, "440 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));    /* create the global translation table */    mmuGlobalTransTbl = mmu440TransTblCreate();    if (mmuGlobalTransTbl == NULL)	{	strcpy(sysExcMsg, "440 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);    mmu440TlbDynamicInvalidate();    /* 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;    /* if caching turnon was delayed until mmu inited, do it now */    if (cache440ToEnable == TRUE)	{	cache440Enable(0);	cache440ToEnable = FALSE;	}    return (OK);    }#if FALSE/******************************************************************************** mmu440MemPagesWriteEnable - 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 mmu440MemPagesWriteEnable    (    MMU_TRANS_TBL * pTransTbl		/* Translation table to enable */    )    {

⌨️ 快捷键说明

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