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

📄 mmu30lib.c

📁 VxWorks BSP框架源代码包含头文件和驱动
💻 C
📖 第 1 页 / 共 3 页
字号:
    {    PTE *pagePte;    volatile int oldIntLev;  /* volatile hushes warnings */    BOOL wasEnabled;    if (mmuPteGet (transTbl, pageAddr, &pagePte) != OK)	return (ERROR);    /* modify the pte with mmu turned off and interrupts locked out */    /* 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  */    MMU_UNLOCK (wasEnabled, oldIntLev);    pagePte->pte.sfpd.bits = 	(pagePte->pte.sfpd.bits & ~stateMask) | (state & stateMask);    MMU_LOCK (wasEnabled, oldIntLev);    mmuATCFlush (pageAddr);    cacheArchClearEntry (DATA_CACHE, pagePte);    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:** 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 are or'ed together in the returned state.  Additionally, masks* are provided so that specific states may be extracted from the returned state:** MMU_STATE_MASK_VALID * MMU_STATE_MASK_WRITABLE* MMU_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 */    )    {    PTE *pagePte;    if (mmuPteGet (transTbl, pageAddr, &pagePte) != OK)	return (ERROR);    *state = pagePte->pte.sfpd.bits;     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 */    )    {    PTE *pagePte;    volatile int oldIntLev;  /* volatile hushes warnings */    FAST UINT addr = (UINT)physPage >> 8;     BOOL wasEnabled;    if (mmuPteGet (transTbl, virtualAddress, &pagePte) != OK)	{	/* build the translation table for the virtual address */	if (mmuVirtualPageCreate (transTbl, virtualAddress) != OK)	    return (ERROR);	if (mmuPteGet (transTbl, virtualAddress, &pagePte) != OK)	    return (ERROR);	}    MMU_UNLOCK (wasEnabled, oldIntLev);    pagePte->pte.sfpd.fields.addr = addr;     MMU_LOCK (wasEnabled, oldIntLev);    mmuATCFlush (virtualAddress);    cacheArchClearEntry (DATA_CACHE, pagePte);    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 */    )    {    PTE *pagePte;    volatile int oldIntLev;  /* volatile hushes warnings */    FAST UINT addr = (UINT)physPage >> 8;     BOOL wasEnabled;    if (mmuPteGet (&mmuGlobalTransTbl, virtualAddress, &pagePte) != OK)	{	/* build the translation table for the virtual address */	if (mmuVirtualPageCreate (&mmuGlobalTransTbl, virtualAddress) != OK)	    return (ERROR);	if (mmuPteGet (&mmuGlobalTransTbl, virtualAddress, &pagePte) != OK)	    return (ERROR);	/* the globalPageBlock array is write protected */	mmuStateSet (&mmuGlobalTransTbl, globalPageBlock, 		     MMU_STATE_MASK_WRITABLE, MMU_STATE_WRITABLE);	globalPageBlock [(unsigned) virtualAddress / PAGE_BLOCK_SIZE] = TRUE;		mmuStateSet (&mmuGlobalTransTbl, globalPageBlock, 		     MMU_STATE_MASK_WRITABLE, MMU_STATE_WRITABLE_NOT);	}    MMU_UNLOCK (wasEnabled, oldIntLev);    pagePte->pte.sfpd.fields.addr = addr;     MMU_LOCK (wasEnabled, oldIntLev);    mmuATCFlush (virtualAddress);    cacheArchClearEntry (DATA_CACHE, pagePte);    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 */    )    {    PTE *pagePte;    UINT dt;    if (mmuPteGet (transTbl, virtAddress, &pagePte) != OK)	{	errno = S_mmuLib_NO_DESCRIPTOR; 	return (ERROR);	}    *physAddress = (PTE *) pagePte->pte.sfpd.fields.addr;     dt = pagePte->pte.sfpd.fields.dt;    if (dt == DT_INVALID)	{	errno = S_mmuLib_INVALID_DESCRIPTOR; 	return (ERROR);	}    *physAddress = (void *) ((UINT) *physAddress << 8);    /* add offset into page */    *physAddress += (unsigned) virtAddress & ((1 << NUM_PAGE_OFFSET_BITS) - 1);    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)	{	mmuMemPagesWriteDisable (&mmuGlobalTransTbl);	mmuMemPagesWriteDisable (transTbl);	firstTime = FALSE;	}    oldLev = intLock ();    localCrp.ta = ((unsigned int) transTbl->pUpperLevelTable) >> 4 ;    __asm__("pmove _localCrp, crp");    mmuCurrentTransTbl = transTbl;    /* the address translation cache is automatically flushed when the     * crp register is loaded by the pmove instruction ONLY if the fd bit     * of the opcode is zero.  Thus, this is dependent on the assembler     * implementation, so we flush the atc explicitly.     */    /* flush the address translation cache cause we're in a new context */    __asm__("pflusha");    intUnlock (oldLev);    }/******************************************************************************** mmuATCFlush - flush an entry from the address translation cache**/LOCAL void mmuATCFlush     (    void *addr    )    {    __asm__ ("movel a6@(8)  ,a0");    /* pflush 0,#0, a0 */    __asm__ (".word 0xf010");    __asm__ (".word 0x3810");    }/******************************************************************************** mmuMemPagesWriteDisable - write disable memory holding a table's descriptors** 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.**/LOCAL void mmuMemPagesWriteDisable    (    MMU_TRANS_TBL *transTbl    )    {    void *thisPage;    int i;    for (i = 0; i < (1 << NUM_TIA_BITS) ;i++)	{	thisPage = (void *) (transTbl->pUpperLevelTable[i].pte.sftd.addr << 4);	if (thisPage != (void *) 0xfffffff0)	    mmuStateSet (transTbl, thisPage, MMU_STATE_MASK_WRITABLE,			 MMU_STATE_WRITABLE_NOT);	}    mmuStateSet (transTbl, transTbl->pUpperLevelTable, MMU_STATE_MASK_WRITABLE, 		 MMU_STATE_MASK_WRITABLE);    }/******************************************************************************** mmuPageAlloc - allocate a page of physical memory**/LOCAL char *mmuPageAlloc     (    MMU_TRANS_TBL *thisTbl    )    {    char *pPage;    int i;    if ((pPage = (char *) lstGet (&thisTbl->memFreePageList)) == NULL)	{	pPage = memPartAlignedAlloc (mmuPageSource,				     mmuPageSize * mmuNumPagesInFreeList,				     mmuPageSize); 	if (pPage == NULL)	    return (NULL);	if (thisTbl->memBlocksUsedIndex >= thisTbl->memBlocksUsedSize)	    {	    void *newArray;	    /* realloc the array */	    thisTbl->memBlocksUsedSize *= 2;	    newArray = realloc (thisTbl->memBlocksUsedArray, 			        sizeof (void *) * thisTbl->memBlocksUsedSize);	    if (newArray == NULL)		{		thisTbl->memBlocksUsedSize /= 2;		return (NULL);			}	    thisTbl->memBlocksUsedArray = (void **) newArray;	    }	thisTbl->memBlocksUsedArray [thisTbl->memBlocksUsedIndex++] = 	      (void *) pPage; 	for (i = 0; i < mmuNumPagesInFreeList; i++, pPage += mmuPageSize)	    lstAdd (&thisTbl->memFreePageList, (NODE *) pPage);	pPage = (char *) lstGet (&thisTbl->memFreePageList);	}    return (pPage);    }#if FALSE// left here for debugging only/* EXPERIMENTAL STUFF */LOCAL char *addrBuf;LOCAL PTE *ptestResult;LOCAL MMU_SR copyOfSr;/******************************************************************************** mmuPtest - use the ptest instruction to traverse the translation table**/LOCAL void mmuPtest     (    char *addr,     int level    )    {    addrBuf = addr;    if (level == 0)	{	__asm__ ("movel _addrBuf, a0");	__asm__ ("ptestr #1,a0@,#7,a1");	__asm__ ("movel a1, _ptestResult");	__asm__ ("pmove psr, _copyOfSr");	}    else	{	__asm__ ("movel _addrBuf, a0");	__asm__ ("ptestr #1,a0@,#1,a1");	__asm__ ("movel a1, _ptestResult");	__asm__ ("pmove psr, _copyOfSr");	}    printf ("mmu status register:\n");    printf ("  bus error = %d\n", copyOfSr.b);    printf ("  limit violation = %d\n", copyOfSr.l);    printf ("  supervisor only = %d\n", copyOfSr.s);    printf ("  write protected = %d\n", copyOfSr.w);    printf ("  invalid         = %d\n", copyOfSr.i);    printf ("  modified        = %d\n", copyOfSr.m);    printf ("  transparent     = %d\n", copyOfSr.t);    printf ("  num levels      = %d\n", copyOfSr.n);    printf ("descriptor address = %x\n", ptestResult);    printf ("  addr          = %x\n", ptestResult->pte.sfpd.fields.addr);    printf ("  cache inhibit = %x\n", ptestResult->pte.sfpd.fields.ci);    printf ("  modified      = %x\n", ptestResult->pte.sfpd.fields.m);    printf ("  u/l           = %x\n", ptestResult->pte.sfpd.fields.u);    printf ("  write protect = %x\n", ptestResult->pte.sfpd.fields.wp);    printf ("  desc type     = %x\n", ptestResult->pte.sfpd.fields.dt);    }#endif

⌨️ 快捷键说明

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