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

📄 mmu405lib.c

📁 VxWorks BSP框架源代码包含头文件和驱动
💻 C
📖 第 1 页 / 共 3 页
字号:
/* mmu405Lib.c - mmu library for PowerPC 405 series *//* Copyright 1984-2002 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01e,25apr02,pch  SPR 74926: don't connect to unused vector01d,17apr02,jtp  use common identifier names with PPC44001c,07dec01,jtp  SPR #67973 add exception message for MMU config failure01b,22nov00,s_m  changes due to changed prototype of mmuPpcTlbSearch01a,17jul00,sm 	 written.*//*DESCRIPTION:mmu405Lib.c provides the architecture dependent routines that directlycontrol the memory management unit for the PowerPC 405 series.  It provides routines that are called by the higher level architecture independent routines in vmLib.c or vmBaseLib.c.*//* 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/mmu405Lib.h"/* defines */#define PAGE_SIZE	4096		/* page size of 4K *//* locals */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 MMU_TRANS_TBL *	mmu405TransTblCreate ();LOCAL STATUS		mmu405TransTblDelete (MMU_TRANS_TBL *transTbl);LOCAL STATUS		mmu405Enable (BOOL enable);LOCAL STATUS		mmu405StateSet (MMU_TRANS_TBL *transTbl, void *pageAddr,				     UINT stateMask, UINT state);LOCAL STATUS		mmu405StateGet (MMU_TRANS_TBL *transTbl, void *pageAddr,				     UINT *state);LOCAL STATUS		mmu405PageMap (MMU_TRANS_TBL *transTbl,				     void * virtualAddress, void *physPage);LOCAL STATUS		mmu405GlobalPageMap (void * virtualAddress,				    void * physPage);LOCAL STATUS		mmu405Translate (MMU_TRANS_TBL * transTbl,				      void * virtAddress, void ** physAddress);LOCAL void		mmu405CurrentSet (MMU_TRANS_TBL * transTbl);LOCAL STATUS		mmu405TransTblInit (MMU_TRANS_TBL * pNewTransTbl);LOCAL LEVEL_1_DESC *	mmu405Lvl1DescAddrGet (MMU_TRANS_TBL *	pTransTbl,				    void * effectiveAddr);LOCAL STATUS		mmu405Lvl2DescAddrGet (MMU_TRANS_TBL * pTransTbl,				void * effectiveAddr,				LEVEL_2_DESC ** ppLvl2Desc);LOCAL void		mmu405Lvl1DescUpdate (LEVEL_1_DESC * pLvl1Desc,				LEVEL_1_DESC lvl1Desc);LOCAL void		mmu405Lvl2DescUpdate (LEVEL_2_DESC * pLvl2Desc,				LEVEL_2_DESC lvl2Desc);LOCAL BOOL		mmu405IsOn (int mmuType);LOCAL UINT8 		mmu405GetNewPid (MMU_TRANS_TBL *transTbl);LOCAL void 		mmu405FreePid (UINT8 pid);LOCAL void 		mmu405Tlbie (MMU_TRANS_TBL *pTransTbl, void * effAddr);IMPORT void		mmuPpcPidSet (UINT8 pid);IMPORT UINT32		mmuPpcPidGet (void);IMPORT void		mmuPpcTlbInvalidateAll (void);IMPORT void 		mmuPpcZprSet (UINT32 zprVal);IMPORT UINT32 		mmuPpcTlbReadEntryHi (UINT32 index);IMPORT UINT32		mmuPpcTlbReadEntryLo (UINT32 index);IMPORT int	 		mmuPpcTlbSearch (void * effAddr);IMPORT void 		mmuPpcTlbWriteEntryHi (UINT32 index, UINT32 tlbhi);IMPORT void 		mmuPpcTlbWriteEntryLo (UINT32 index, UINT32 tlblo);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;/* * 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 256 translation table pointers is allocated to store upto * 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];/* the global map's PID index into above array (should be equal to 1) */UINT8	mmuGlobalMapPid;/* tlb replacement counter: we use a round-robin strategy to determine * which tlb entry to replace. The following variable is used by the * TLB miss handlers to determine which TLB (0..63) to replace in the * event of a TLB miss. */UINT32	mmuPpcTlbNext;#ifdef DEBUG_MISS_HANDLERUINT32	mmuPpcITlbMisses;UINT32	mmuPpcITlbMissArray[256];UINT32	mmuPpcDTlbMisses;UINT32	mmuPpcDTlbMissArray[256];UINT32	mmuPpcITlbErrors;UINT32	mmuPpcDTlbErrors;#endif /* DEBUG_MISS_HANDLER */LOCAL UINT32	mmu405Selected;		/* mmu type selected */LOCAL MMU_LIB_FUNCS mmuLibFuncsLocal =    {    mmu405LibInit,    mmu405TransTblCreate,    mmu405TransTblDelete,    mmu405Enable,    mmu405StateSet,    mmu405StateGet,    mmu405PageMap,    mmu405GlobalPageMap,    mmu405Translate,    mmu405CurrentSet    };/******************************************************************************** mmu405LibInit - MMU library initialization** RETURNS: OK, or ERROR if <mmuType> is incorrect or memory allocation failed. */STATUS mmu405LibInit     (    int 	mmuType		/* data and/or instruction MMU to initialize */    )    {    /* 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, "405 MMU config failed: either enable I or D MMU, "			  "or remove MMU support\n");	return (ERROR);	}    /* save the Data and/or Instruction MMU selected */    mmu405Selected =  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, "405 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, "405 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));    /* get a PID element for the global map */    mmuGlobalMapPid = mmu405GetNewPid (&mmuGlobalTransTbl);    if (mmuGlobalMapPid == 0) /* no free PIDs ! */	    return (ERROR);    mmuGlobalTransTbl.pid = mmuGlobalMapPid;   /* allocate a piece of memory to handle the level 1 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.    */    mmuGlobalTransTbl.l1TblPtr.pL1Desc =			(LEVEL_1_DESC *) memalign (PAGE_SIZE, PAGE_SIZE);    /* check the memory allocation */    if (mmuGlobalTransTbl.l1TblPtr.pL1Desc == NULL)    {    	mmu405FreePid (mmuGlobalMapPid);	return (ERROR);    }    /* invalidate all entries in the table */    memset ((void *) mmuGlobalTransTbl.l1TblPtr.pL1Desc, 0x00, PAGE_SIZE);    /* initialize the PID register , and invalidate all TLB entries */    mmuPpcPidSet (mmuGlobalMapPid);    mmuPpcTlbInvalidateAll();    /* initialize the Zone protection register so that for all zones     * access is controlled by EX and WR for both user and supervisor     * states.     */    mmuPpcZprSet (MMU_ZPR_INIT_VAL);    /* initialize the data objects that are shared with vmLib.c */    mmuStateTransArray = &mmuStateTransArrayLocal [0];    mmuStateTransArraySize =		sizeof (mmuStateTransArrayLocal) / sizeof (STATE_TRANS_TUPLE);    mmuLibFuncs = mmuLibFuncsLocal;    /* initialize the TLB replacement counter to zero. */    mmuPpcTlbNext = 0;    mmuPageBlockSize = PAGE_SIZE;    return (OK);    }#if FALSE/******************************************************************************** mmu405MemPagesWriteEnable - 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 mmu405MemPagesWriteEnable    (    MMU_TRANS_TBL * pTransTbl    )    {    int ix;    LEVEL_1_DESC lvl1Desc;    /* we need to enable writes on the level 1 page table and each level 2     * page table. The level 1 page table is PAGE_SIZE in size, whereas     * the level 2 page table is 2 * PAGE_SIZE in size.     */    /* write enable the level 1 page table */    mmu405StateSet (pTransTbl, (void *)pTransTbl->l1TblPtr.pL1Desc, 		    MMU_STATE_MASK_WRITABLE, MMU_STATE_WRITABLE);    /* go thru the L 1 table and write enable each L 2 table */    for (ix = 0 ; ix < MMU_LVL_2_DESC_NB; ix++)	{	lvl1Desc = * (pTransTbl->l1TblPtr.pL1Desc + ix);	if (lvl1Desc.field.v)	    {	    mmu405StateSet (pTransTbl, (void *)(lvl1Desc.field.l2ba << 2),		    MMU_STATE_MASK_WRITABLE, MMU_STATE_WRITABLE);	    mmu405StateSet (pTransTbl, (void *)((lvl1Desc.field.l2ba << 2) + 						PAGE_SIZE),		    MMU_STATE_MASK_WRITABLE, MMU_STATE_WRITABLE);	    }	}    return (OK);    }#endif/******************************************************************************** mmu405MemPagesWriteDisable - 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.** RETURNS: N/A*/LOCAL void mmu405MemPagesWriteDisable    (    MMU_TRANS_TBL * pTransTbl    )    {    int ix;    LEVEL_1_DESC lvl1Desc;    /* we need to disable writes on the level 1 page table and each level 2     * page table. The level 1 page table is PAGE_SIZE in size, whereas     * the level 2 page table is 2 * PAGE_SIZE in size.     */    /* write protect the level 1 page table */    mmu405StateSet (pTransTbl, (void *)pTransTbl->l1TblPtr.pL1Desc, 		    MMU_STATE_MASK_WRITABLE, MMU_STATE_WRITABLE_NOT);    /* go thru the L 1 table and write protect each L 2 table */    for (ix = 0 ; ix < MMU_LVL_2_DESC_NB; ix++)	{	lvl1Desc = * (pTransTbl->l1TblPtr.pL1Desc + ix);	if (lvl1Desc.field.v)	    {	    mmu405StateSet (pTransTbl, (void *)(lvl1Desc.field.l2ba << 2),		    MMU_STATE_MASK_WRITABLE, MMU_STATE_WRITABLE_NOT);	    }	}    }/******************************************************************************** mmu405TransTblCreate - create a new translation table.** RETURNS: address of new object or NULL if allocation failed.*/LOCAL MMU_TRANS_TBL * mmu405TransTblCreate     (    )    {    MMU_TRANS_TBL *	pNewTransTbl;    /* 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 = mmu405GetNewPid (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 (mmu405TransTblInit (pNewTransTbl) == ERROR)	{	free ((char *) pNewTransTbl);	return (NULL);	}    /* return the new translation table created */    return (pNewTransTbl);    }/******************************************************************************

⌨️ 快捷键说明

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