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

📄 mmu800lib.c

📁 VxWorks BSP框架源代码包含头文件和驱动
💻 C
📖 第 1 页 / 共 3 页
字号:
/* mmu800Lib.c - mmu library for PowerPC 800 serie *//* Copyright 1984-1999 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01n,21may02,dtr  Changing mmu segment cache properties copyback<->writhrough                 must rely on user to have the 4MB aligned SEGMENT in a known		 safe cache state. mmu800StateSet cannot make any other                  assumption.01m,16may02,dtr  Fix mmu800TransTblDelete. Ignores global descriptors. SPR 7746301l,03may02,dtr  Fixes to cache flush and tlbie for l1descriptor updates.01k,25apr02,pch  SPR 74926: don't connect to unused vector		 SPR 67973: add exception message for MMU config failure01j,24apr02,dtr  Fixing function mmu800StateGet/Set and tidying up                  TransTblDelete. Also getting mmu800Show routine to work in		 a useful manner. Some additions for cache.01i,22mar02,dtr  Adding in write set/unset to mmu800StateSet.01h,06nov01,dtr  Putting in full 32-bit branch support for exception handler.01g,09apr99,tpr  Surrounded L1/L2 tables update with intLock/Unlock(SPR #26522)01f,05feb97,tpr  replaced reserved by field.reserved (SPR #7783).01e,10nov96,tpr  removed debug function from the normal compilation.01d,29oct96,tam	 added missing modification history entries; added a few		 extra comments.01c,24jun96,tpr	 remove MI_CTR and MD_CTR init; move init to sysALib.s.01b,18jun96,tpr	 changed mmu860XXX() name by mmu800XXX()		 correct mmu800lib.h file name.01a,27apr96,tpr	 written.*//*DESCRIPTION:mmu800Lib.c provides the architecture dependent routines that directlycontrol the memory management unit for the PowerPC 800 serie.  It provides routines that are called by the higher level architecture independent routines in vmLib.c or vmBaseLib.cNote :The 8xx CPU has two levels of descriptors for the MMU TLB's:L1Desc covers 4MB SEGMENTS (1024 L2Descriptors * PAGE_SIZE )L2Desc covers PAGES (4096 Bytes fixed)The L1 has writethrough/copyback cache,guarded.The L2 has cache inhibit,access(R/W,R/O),valid.These are the only attributes which you can manipulate.eg Setting a page as guarded means you actually are setting the segment which contains that page to be guarded.*//* 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/mmu800Lib.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 *	mmu800TransTblCreate ();LOCAL STATUS		mmu800TransTblDelete (MMU_TRANS_TBL *transTbl);LOCAL STATUS		mmu800Enable (BOOL enable);LOCAL STATUS		mmu800StateSet (MMU_TRANS_TBL *transTbl, void *pageAddr,				     UINT stateMask, UINT state);LOCAL STATUS		mmu800StateGet (MMU_TRANS_TBL *transTbl, void *pageAddr,				     UINT *state);LOCAL STATUS		mmu800PageMap (MMU_TRANS_TBL *transTbl,				     void * virtualAddress, void *physPage);LOCAL STATUS		mmu800GlobalPageMap (void * virtualAddress,				    void * physPage);LOCAL STATUS		mmu800Translate (MMU_TRANS_TBL * transTbl,				      void * virtAddress, void ** physAddress);LOCAL void		mmu800CurrentSet (MMU_TRANS_TBL * transTbl);LOCAL STATUS		mmu800TransTblInit (MMU_TRANS_TBL * pNewTransTbl);LOCAL LEVEL_1_DESC *	mmu800Lvl1DescAddrGet (MMU_TRANS_TBL *	pTransTbl,				    void * effectiveAddr);LOCAL STATUS		mmu800Lvl2DescAddrGet (MMU_TRANS_TBL * pTransTbl,				void * effectiveAddr,				LEVEL_2_DESC ** ppLvl2Desc);LOCAL void		mmu800Lvl1DescUpdate (LEVEL_1_DESC * pLvl1Desc,				LEVEL_1_DESC lvl1Desc);LOCAL void		mmu800Lvl2DescUpdate (LEVEL_2_DESC * pLvl2Desc,				LEVEL_2_DESC lvl2Desc);LOCAL BOOL		mmu800IsOn (int mmuType);IMPORT void	mmuPpcTlbie ();IMPORT void	mmuPpcAEnable ();IMPORT void	mmuPpcADisable ();IMPORT void     mmuPpcMiApSet(UINT32);IMPORT void     mmuPpcMdApSet(UINT32);IMPORT void     mmuPpcMCasidSet(UINT32);IMPORT void     mmuPpcMTwbSet(LEVEL_1_DESC*);IMPORT void	mmuPpcInstTlbMissHandler();IMPORT void	mmuPpcDataTlbMissHandler();IMPORT void	mmuPpcDataTlbErrorHandler();IMPORT void	mmuPpcInstTlbMissHandlerLongJump();IMPORT void	mmuPpcDataTlbMissHandlerLongJump();IMPORT void	mmuPpcDataTlbErrorHandlerLongJump();IMPORT void     mmuPpcTlbInvalidateAll();IMPORT UINT32   vxMsrGet();STATUS cacheArchFlush      (CACHE_TYPE, void *, size_t);IMPORT STATE_TRANS_TUPLE *	mmuStateTransArray;IMPORT int			mmuStateTransArraySize;IMPORT MMU_LIB_FUNCS		mmuLibFuncs;IMPORT int			mmuPageBlockSize;IMPORT BOOL	                excExtendedVectors;/* * a translation table to hold the descriptors for the global transparent * translation of physical to virtual memory */MMU_TRANS_TBL	mmuGlobalTransTbl;	/* global translation table */	LOCAL u_int	mmu800Selected;		/* mmu type selected */LOCAL MMU_LIB_FUNCS mmuLibFuncsLocal =    {    mmu800LibInit,    mmu800TransTblCreate,    mmu800TransTblDelete,    mmu800Enable,    mmu800StateSet,    mmu800StateGet,    mmu800PageMap,    mmu800GlobalPageMap,    mmu800Translate,    mmu800CurrentSet    };/******************************************************************************** mmu800LibInit - MMU library initialization** RETURNS: OK, or ERROR if <mmuType> is incorrect or memory allocation failed. */STATUS mmu800LibInit     (    int 	mmuType		/* data and/or instruction MMU to initialize */    )    {       /* The excVectorHandler for each mmu exception can be long branch or short 	 branch. The short branch can address 24 bit range. The long branch 	 32 bit range */        /* This long branch stub does the following :	 	mtspr M_TW,r18          * save r18 	mfcr  r18          	stw   r18,-0x4(r1)	* save condition register on stack 0x4	mfctr r18	stw   r18,-0x8(r1)      * save counter register on stack 0x8 	lis   r18, HI(mmuXXXHandler)	ori   r18, r18, LO(mmuXXXHandler)	mtctr r18		* jump to mmu handler *	bctr	Note: r18 and cr are restored at the end of this routine 	*/    UINT32 excHandMmu[] = {0x7e5fc3a6,   /* mtspr M_TW,r18 -  save r18*/        			   0x7e400026,   /* mfcr r18 -  move cr to r18 */       			   0x9241fffc,   /* save condition register onto stack */       			   0x7e4902a6,   /*  mfctr r18 -  move ctr to r18 */       			   0x9241fff8,   /*  save ctr onto stack */       			   0x3e400000,   /* lis p0,HI(xxHandler) */       			   0x62520000,   /* ori p0,p0,LO(xxHandler)*/       			   0x7e4903a6,   /* load ctr with Handler address*/       			   0x4e800420};  /* branch handler */    /* 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, "8xx MMU config failed: either enable I or D MMU, "			  "or remove MMU support\n");	return (ERROR);	}    /* save the Data and/or Instruction MMU selected */    mmu800Selected =  mmuType;        /* initialize the exception table */    if (!excExtendedVectors) 	{	if (mmuType & MMU_INST)	    {	    * (int *) _EXC_OFF_INST_MISS = 0x48000002 |			(((int) mmuPpcInstTlbMissHandler) & 0x03ffffff);	    CACHE_TEXT_UPDATE((void *)_EXC_OFF_INST_MISS, sizeof(int));	    }	if (mmuType & MMU_DATA)	    {	    * (int *) _EXC_OFF_DATA_MISS = 0x48000002 |			(((int) mmuPpcDataTlbMissHandler) & 0x03ffffff);	    CACHE_TEXT_UPDATE((void *)_EXC_OFF_DATA_MISS, sizeof(int));	    * (int *) _EXC_OFF_DATA_ERROR = 0x48000002 |			(((int) mmuPpcDataTlbErrorHandler) & 0x03ffffff);	    CACHE_TEXT_UPDATE((void *)_EXC_OFF_DATA_ERROR, 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 + 0x14)		|= MSW((int) mmuPpcInstTlbMissHandlerLongJump);	    *(int*)(_EXC_OFF_INST_MISS + 0x18)		|= LSW((int) mmuPpcInstTlbMissHandlerLongJump);	    CACHE_TEXT_UPDATE((void *)_EXC_OFF_INST_MISS, sizeof(excHandMmu));	    }	if (mmuType & MMU_DATA)	    {	    memcpy ((void*)_EXC_OFF_DATA_MISS, &excHandMmu[0],			sizeof(excHandMmu));	    *(int*)(_EXC_OFF_DATA_MISS + 0x14)		|= MSW((int) mmuPpcDataTlbMissHandlerLongJump);	    *(int*)(_EXC_OFF_DATA_MISS + 0x18)		|= LSW((int) mmuPpcDataTlbMissHandlerLongJump);	    CACHE_TEXT_UPDATE((void *)_EXC_OFF_DATA_MISS, sizeof(excHandMmu));	    memcpy ((void*)_EXC_OFF_DATA_ERROR, &excHandMmu[0],			sizeof(excHandMmu));	    *(int*)(_EXC_OFF_DATA_ERROR + 0x14)		|= MSW((int) mmuPpcDataTlbErrorHandlerLongJump);	    *(int*)(_EXC_OFF_DATA_ERROR + 0x18)		|= LSW((int) mmuPpcDataTlbErrorHandlerLongJump);	    CACHE_TEXT_UPDATE((void *)_EXC_OFF_DATA_ERROR, sizeof(excHandMmu));	    }	}   /* allocate a piece of memory to handle the level 1 Table */    mmuGlobalTransTbl.l1TblPtr.pL1Desc =			(LEVEL_1_DESC *) memalign (PAGE_SIZE, PAGE_SIZE);    /* check the memory allocation */    if (mmuGlobalTransTbl.l1TblPtr.pL1Desc == NULL)	return (ERROR);    /* invalided all enties in the table */    memset ((void *) mmuGlobalTransTbl.l1TblPtr.pL1Desc, 0x00, PAGE_SIZE);    /* initialize the Instruction MMU Access Protection Register */    mmuPpcMiApSet (0xffffffff);    /* initialize the Data MMU Access Protection Register */    mmuPpcMdApSet (0xffffffff);    /* initialize the Instruction MMU Control register */    mmuPpcMCasidSet (0);    mmuPpcTlbInvalidateAll();    /* 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);    }/******************************************************************************** mmu800MemPagesWriteEnable - 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 mmu800MemPagesWriteEnable    (    MMU_TRANS_TBL * pTransTbl    )    {    return (OK);    }/******************************************************************************** mmu800MemPagesWriteDisable - 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 mmu800MemPagesWriteDisable    (    MMU_TRANS_TBL * pTransTbl    )    {    }/******************************************************************************** mmu800TransTblCreate - create a new translation table.** RETURNS: address of new object or NULL if allocation failed.*/LOCAL MMU_TRANS_TBL * mmu800TransTblCreate     (    )    {    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);    /*      * initilialize the new translation table.      * If the initialization falls then free the memory and return the NULL     * pointer.     */    if (mmu800TransTblInit (pNewTransTbl) == ERROR)	{	free ((char *) pNewTransTbl);	return (NULL);	}    /* return the new translation table created */    return (pNewTransTbl);    }/******************************************************************************** mmu800TransTblInit - initialize a new translation table ** Initialize a new translation table.  The level 1 table is copyed from the* global translation mmuPpcGlobalTransTbl, so that we* will share the global virtual memory with all* other translation tables.* * RETURNS: OK or ERROR if unable to allocate memory. 

⌨️ 快捷键说明

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