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

📄 mmu40lib.c

📁 VxWorks BSP框架源代码包含头文件和驱动
💻 C
📖 第 1 页 / 共 4 页
字号:
    /* reset the transparent translation registers */    if (enable && firstTime)	{	cacheClear (DATA_CACHE, NULL, ENTIRE_CACHE);	/* from Heurikon */	__asm__ ("movel #0, d0; "		 ".word 0x4e7b, 0x0004; "   /* movec d0, ITT0 */		 ".word 0x4e7b, 0x0005; "   /* movec d0, ITT1 */		 ".word 0x4e7b, 0x0006; "   /* movec d0, DTT0 */		 ".word 0x4e7b, 0x0007; "   /* movec d0, DTT1 */		 :		/* outputs */		 :		/* inputs */		 : "d0"		/* temps */		 );	firstTime = FALSE;	}    return (OK);    }/******************************************************************************** mmuStateSet - set state of virtual memory page** mmuStateSet is used to modify the state bits of the pte for the given* virtual page.  The following states are provided:** MMU_STATE_VALID       MMU_STATE_VALID_NOT      vailid/invalid* MMU_STATE_WRITABLE    MMU_STATE_WRITABLE_NOT   writable/writeprotected* MMU_STATE_CACHEABLE   MMU_STATE_CACHEABLE_NOT  notcachable/cachable** these may be or'ed together in the state parameter.  The 68040 and 68060* provides several caching modes, so the following cache states are provided* which may be substituted for MMU_STATE_CACHEABLE/MMU_STATE_CACHEABLE_NOT:** MMU_STATE_CACHEABLE_WRITETHROUGH          * MMU_STATE_CACHEABLE_COPYBACK             * MMU_STATE_CACHEABLE_NOT_SERIAL		(MC68040 only)* MMU_STATE_CACHEABLE_NOT_NON_SERIAL		(MC68040 only)* MMU_STATE_CACHEABLE_NOT_PRECISE		(MC68060 only)* MMU_STATE_CACHEABLE_NOT_IMPRECISE		(MC68060 only)** MMU_STATE_CACHEABLE is equivalent to MMU_STATE_CACHEABLE_COPYBACK, and* MMU_STATE_CACHEABLE_NOT is equivalent to MMU_STATE_CACHEABLE_NOT_SERIAL or* MMU_STATE_CACHEABLE_NOT_PRECISE.* See the MC68040 or MC68060 32-bit Microprocessor User's Manual for* additional information.* * Additionally, masks are provided so that only specific states may be set:** MMU_STATE_MASK_VALID* MMU_STATE_MASK_WRITABLE* MMU_STATE_MASK_CACHEABLE** These may be or'ed together in the stateMask parameter.  ** Accesses to a virtual page marked as invalid will result in a bus error.** RETURNS: OK or ERROR if virtual page does not exist.*/LOCAL STATUS mmuStateSet     (    MMU_TRANS_TBL *transTbl, 	/* translation table */    void *pageAddr,		/* page whose state to modify */     UINT stateMask,		/* mask of which state bits to modify */    UINT state			/* new state bit values */    )    {    PAGE_DESC *pageDesc;    FAST UINT *pageDescBits;    FAST int oldIntLev;    if (mmuPageDescGet (transTbl, pageAddr, &pageDesc) != OK)	return (ERROR);    /* modify the pte with mmu turned off and interrupts locked out */    pageDescBits = (UINT *) pageDesc;    /* XXX can't dynamically turn mmu on and off if virtual stack */    /* only way is if you make mmuEnable inline and guarantee that this       code is in physical memory  */    if (mmuEnabled)	{	oldIntLev = intLock ();  	mmuEnableInline(FALSE);	*pageDescBits = (*pageDescBits & ~stateMask) | (state & stateMask);	mmuEnableInline(TRUE);	intUnlock (oldIntLev);	}    else	*pageDescBits = (*pageDescBits & ~stateMask) | (state & stateMask);    mmuATCFlush (pageAddr);    cacheClear (DATA_CACHE, (void *) pageDescBits, sizeof (*pageDescBits));    return (OK);    }/******************************************************************************** mmuStateGet - get state of virtual memory page** mmuStateGet is used to retrieve the state bits of the pte for the given* virtual page.  The following states are provided:** VM_STATE_VALID 	VM_STATE_VALID_NOT	 vailid/invalid* VM_STATE_WRITABLE 	VM_STATE_WRITABLE_NOT	 writable/writeprotected* VM_STATE_CACHEABLE 	VM_STATE_CACHEABLE_NOT	 notcachable/cachable** these are or'ed together in the returned state.  Additionally, masks* are provided so that specific states may be extracted from the returned state:** VM_STATE_MASK_VALID * VM_STATE_MASK_WRITABLE* VM_STATE_MASK_CACHEABLE** RETURNS: OK or ERROR if virtual page does not exist.*/LOCAL STATUS mmuStateGet     (    MMU_TRANS_TBL *transTbl, 	/* tranlation table */    void *pageAddr, 		/* page whose state we're querying */    UINT *state			/* place to return state value */    )    {    PAGE_DESC *pageDesc;    FAST UINT *pageDescBits;    if (mmuPageDescGet (transTbl, pageAddr, &pageDesc) != OK)	return (ERROR);    pageDescBits = (UINT *) pageDesc;    *state = *pageDescBits;     return (OK);    }/******************************************************************************** mmuPageMap - map physical memory page to virtual memory page** The physical page address is entered into the pte corresponding to the* given virtual page.  The state of a newly mapped page is undefined. ** RETURNS: OK or ERROR if translation table creation failed. */LOCAL STATUS mmuPageMap     (    MMU_TRANS_TBL *transTbl, 	/* translation table */    void *virtualAddress, 	/* virtual address */    void *physPage		/* physical address */    )    {    PAGE_DESC *pageDesc;    if (mmuPageDescGet (transTbl, virtualAddress, &pageDesc) != OK)	{	/* build the translation table for the virtual address */	if (mmuVirtualPageCreate (transTbl, virtualAddress) != OK)	    return (ERROR);	if (mmuPageDescGet (transTbl, virtualAddress, &pageDesc) != OK)	    return (ERROR);	}    mmuMemPagesWriteEnable (transTbl);    if (mmuPageSize == PAGE_SIZE_4K)	pageDesc->pageSize4k.addr = (UINT) physPage >> 12;    else	pageDesc->pageSize8k.addr = (UINT) physPage >> 13;    mmuMemPagesWriteDisable (transTbl);    mmuATCFlush (virtualAddress);    cacheClear (DATA_CACHE, pageDesc, sizeof (*pageDesc));    return (OK);    }/******************************************************************************** mmuGlobalPageMap - map physical memory page to global virtual memory page** mmuGlobalPageMap is used to map physical pages into global virtual memory* that is shared by all virtual memory contexts.  The translation tables* for this section of the virtual space are shared by all virtual memory* contexts.** RETURNS: OK or ERROR if no pte for given virtual page.*/LOCAL STATUS mmuGlobalPageMap     (    void *virtualAddress, 	/* virtual address */    void *physPage		/* physical address */    )    {    PAGE_DESC *pageDesc;    if (mmuPageDescGet (&mmuGlobalTransTbl, virtualAddress, &pageDesc) != OK)	{	/* build the translation table for the virtual address */	if (mmuVirtualPageCreate (&mmuGlobalTransTbl, virtualAddress) != OK)	    return (ERROR);	if (mmuPageDescGet(&mmuGlobalTransTbl, virtualAddress, &pageDesc) != OK)	    return (ERROR);	}    mmuMemPagesWriteEnable (&mmuGlobalTransTbl);    if (mmuPageSize == PAGE_SIZE_4K)	pageDesc->pageSize4k.addr = (UINT) physPage >> 12;    else	pageDesc->pageSize8k.addr = (UINT) physPage >> 13;    mmuMemPagesWriteDisable (&mmuGlobalTransTbl);    mmuATCFlush (virtualAddress);    cacheClear (DATA_CACHE, pageDesc, sizeof (*pageDesc));    return (OK);    }/******************************************************************************** mmuTranslate - translate a virtual address to a physical address** Traverse the translation table and extract the physical address for the* given virtual address from the pte corresponding to the virtual address.** RETURNS: OK or ERROR if no pte for given virtual address.*/LOCAL STATUS mmuTranslate     (    MMU_TRANS_TBL *transTbl, 		/* translation table */    void *virtAddress, 			/* virtual address */    void **physAddress			/* place to return result */    )    {    PAGE_DESC *pageDesc;    UINT dt;    if (mmuPageDescGet (transTbl, virtAddress, &pageDesc) != OK)	{	errno = S_mmuLib_NO_DESCRIPTOR; 	return (ERROR);	}    dt = pageDesc->generic.pdt;    if (dt == PDT_INVALID)	{	errno = S_mmuLib_INVALID_DESCRIPTOR; 	return (ERROR);	}    if (mmuPageSize == PAGE_SIZE_4K)	*physAddress = 	     (void *) ((UINT) pageDesc->pageSize4k.addr << 12);    else	*physAddress = 	     (void *) ((UINT) pageDesc->pageSize8k.addr << 13);    /* add offset into page */    *physAddress = (void *) (((UINT) *physAddress) + 		   ((mmuPageSize == PAGE_SIZE_4K) ? 		   ((unsigned) virtAddress & 0xfff) :		   ((unsigned) virtAddress & 0x1fff)));     return (OK);    }/******************************************************************************** mmuCurrentSet - change active translation table** mmuCurrent set is used to change the virtual memory context.* Load the CRP (root pointer) register with the given translation table.**/LOCAL void mmuCurrentSet     (    MMU_TRANS_TBL *transTbl	/* new active tranlation table */    )     {    FAST int oldLev;    static BOOL firstTime = TRUE;    if (firstTime)	{	/* write protect all the pages containing the ptes allocated for	 * the global translation table.  Need to do this cause when this	 * memory is allocated, the global trans tbl doesn't exist yet,	 * so the state sets fail.	 */	mmuMemPagesWriteDisable (&mmuGlobalTransTbl);	mmuMemPagesWriteDisable (transTbl);	firstTime = FALSE;	}    oldLev = intLock ();    localCrp.addr = ((unsigned int) transTbl->pLevel1) >> 9 ;    /* movel localCrp, d0; movec d0, srp */    __asm__ ("movel %0, d0; .word 0x4e7b, 0x0807" : : "r" (localCrp): "d0" );     mmuCurrentTransTbl = transTbl;    /* flush the address translation cache cause we're in a new context */    __asm__ (".word 0xf518");	/* pflusha */    intUnlock (oldLev);    }/******************************************************************************** mmuATCFlush - flush an entry from the address translation cache**/LOCAL void mmuATCFlush     (    void *addr    )    {    __asm__ (	    "movel %0, a0; "	    "movel #1, d0; "	    ".word 0x4e7b, 0x0001; "	/* movec d0, srp */	    ".word 0xf508; "		/* pflush a0 */	    "movel #5, d0; "	    ".word 0x4e7b, 0x0001; "	/* movec d0, srp */	    ".word 0xf508; "		/* pflush a0 */	    :			/* outputs */	    : "r" (addr)	/* inputs */	    : "d0", "a0"	/* temps */	    );    }

⌨️ 快捷键说明

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