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

📄 mmu30lib.c

📁 VxWorks BSP框架源代码包含头文件和驱动
💻 C
📖 第 1 页 / 共 3 页
字号:
    localTc.tia = NUM_TIA_BITS;    localTc.tib = NUM_TIB_BITS;    localTc.tic = 0;    localTc.tid = 0;    /* initialize the static data structure that mmuCurrentSet uses to load      * the crp.      */    localCrp.lu = 1;    localCrp.limit = 0;    localCrp.zero = 0;     localCrp.dt = DT_VALID_4_BYTE;     /* we assume a 8192 byte page size */    if (pageSize != 8192)	{	errno = S_mmuLib_INVALID_PAGE_SIZE;	return (ERROR);	}    mmuEnabled = FALSE;    mmuPageSize = pageSize;    /* allocate the global page block array to keep track of which parts     * of virtual memory are handled by the global translation tables.     * Allocate on page boundry so we can write protect it.     */    globalPageBlock = 	(BOOL *) memPartAlignedAlloc (mmuPageSource, pageSize, pageSize);    bzero ((char *) globalPageBlock, pageSize);    /* build a dummy translation table which will hold the pte's for     * global memory.  All real translation tables will point to this     * one for controling the state of the global virtual memory       */    lstInit (&mmuGlobalTransTbl.memFreePageList);    mmuGlobalTransTbl.memBlocksUsedArray = 	calloc (MMU_BLOCKS_USED_SIZE, sizeof (void *));    if (mmuGlobalTransTbl.memBlocksUsedArray == NULL)	return (ERROR);    mmuGlobalTransTbl.memBlocksUsedIndex = 0;    mmuGlobalTransTbl.memBlocksUsedSize  = MMU_BLOCKS_USED_SIZE;    /* allocate a page to hold the upper level descriptor array */    mmuGlobalTransTbl.pUpperLevelTable = pUpperLevelTable = 	(PTE *) mmuPageAlloc (&mmuGlobalTransTbl);    if (pUpperLevelTable == NULL)	return (ERROR);    /* invalidate all the upper level descriptors */    for (i = 0; i < (1 << NUM_TIA_BITS) ;i++)	{	pUpperLevelTable[i].pte.sftd.addr = -1;	pUpperLevelTable[i].pte.sftd.u = 0; 	pUpperLevelTable[i].pte.sftd.wp = 0; 	pUpperLevelTable[i].pte.sftd.dt = DT_INVALID; 	}    return (OK);    }/******************************************************************************** mmuPteGet - get the pte for a given page** mmuPteGet traverses a translation table and returns the (physical) address of* the pte for the given virtual address.** RETURNS: OK or ERROR if there is no virtual space for the given address **/LOCAL STATUS mmuPteGet     (    MMU_TRANS_TBL *pTransTbl, 	/* translation table */    void *virtAddr,		/* virtual address */     PTE **result		/* result is returned here */    )    {    PTE *upperLevelPte;    PTE *lowerLevelPteTable;    int lowerLevelPteTableIndex;    upperLevelPte = 	   &pTransTbl->pUpperLevelTable [(UINT) virtAddr / PAGE_BLOCK_SIZE];        lowerLevelPteTable = (PTE *) upperLevelPte->pte.sftd.addr;     if ((UINT) lowerLevelPteTable == 0xfffffff) /* -1 in 28 bits */	return (ERROR);    lowerLevelPteTable = (PTE *)((UINT)lowerLevelPteTable << 4);    lowerLevelPteTableIndex =        ((UINT) virtAddr >> NUM_PAGE_OFFSET_BITS) & ((1 << NUM_TIB_BITS) - 1);    *result = &lowerLevelPteTable[lowerLevelPteTableIndex];    return (OK);    }/******************************************************************************** mmuTransTblCreate - create a new translation table.** create a 68k translation table.  Allocates space for the MMU_TRANS_TBL* data structure and calls mmuTransTblInit on that object.  ** RETURNS: address of new object or NULL if allocation failed,*          or NULL if initialization failed.*/LOCAL MMU_TRANS_TBL *mmuTransTblCreate     (    )    {    MMU_TRANS_TBL *newTransTbl;    newTransTbl = (MMU_TRANS_TBL *) malloc (sizeof (MMU_TRANS_TBL));    if (newTransTbl == NULL)	return (NULL);    if (mmuTransTblInit (newTransTbl) == ERROR)	{	free ((char *) newTransTbl);	return (NULL);	}    return (newTransTbl);    }/******************************************************************************** mmuTransTblInit - initialize a new translation table ** Initialize a new translation table.  The upper level is copyed from the* global translation mmuGlobalTransTbl, so that we* will share the global virtual memory with all* other translation tables.* * RETURNS: OK or ERROR if unable to allocate memory for upper level.*/LOCAL STATUS mmuTransTblInit     (    MMU_TRANS_TBL *newTransTbl		/* translation table to be inited */    )    {    FAST PTE *pUpperLevelTable;    lstInit (&newTransTbl->memFreePageList);    newTransTbl->memBlocksUsedArray = 	calloc (MMU_BLOCKS_USED_SIZE, sizeof (void *));    if (newTransTbl->memBlocksUsedArray == NULL)	return (ERROR);    newTransTbl->memBlocksUsedIndex = 0;    newTransTbl->memBlocksUsedSize  = MMU_BLOCKS_USED_SIZE;    /* allocate a page to hold the upper level descriptor array */    newTransTbl->pUpperLevelTable = pUpperLevelTable = 	(PTE *) mmuPageAlloc (newTransTbl);    if (pUpperLevelTable == NULL)	return (ERROR);    /* copy the upperlevel table from mmuGlobalTransTbl,     * so we get the global virtual memory      */    bcopy ((char *) mmuGlobalTransTbl.pUpperLevelTable, 	   (char *) pUpperLevelTable, mmuPageSize);    /* write protect virtual memory pointing to the the upper level table in      * the global translation table to insure that it can't be corrupted      */    mmuStateSet (&mmuGlobalTransTbl, (void *) pUpperLevelTable, 		 MMU_STATE_MASK_WRITABLE, MMU_STATE_WRITABLE_NOT);    return (OK);    }/******************************************************************************** mmuTransTblDelete - delete a translation table.* * mmuTransTblDelete deallocates all the memory used to store the translation* table entries.  It does not deallocate physical pages mapped into the* virtual memory space.** RETURNS: OK**/LOCAL STATUS mmuTransTblDelete     (    MMU_TRANS_TBL *transTbl		/* translation table to be deleted */    )    {    FAST int i;    /* write enable the physical page containing the upper level pte */    mmuStateSet (&mmuGlobalTransTbl, transTbl->pUpperLevelTable, 		 MMU_STATE_MASK_WRITABLE, MMU_STATE_WRITABLE);    /* free all the blocks of pages in memBlocksUsedArray */    for (i = 0; i < transTbl->memBlocksUsedIndex; i++)	free (transTbl->memBlocksUsedArray[i]);    free (transTbl->memBlocksUsedArray);    /* free the translation table data structure */    free (transTbl);        return (OK);    }/******************************************************************************** mmuVirtualPageCreate - set up translation tables for a virtual page** simply check if there's already a lower level sfpd array that has a* pte for the given virtual page.  If there isn't, create one.** RETURNS OK or ERROR if couldn't allocate space for lower level sfpd array.*/LOCAL STATUS mmuVirtualPageCreate     (    MMU_TRANS_TBL *thisTbl, 		/* translation table */    void *virtPageAddr			/* virtual addr to create */    )    {    PTE *upperLevelPte;    FAST PTE *lowerLevelPteTable;    FAST UINT i;    PTE *dummy;    if (mmuPteGet (thisTbl, virtPageAddr, &dummy) == OK)	return (OK);    lowerLevelPteTable = (PTE *) mmuPageAlloc (thisTbl);    if (lowerLevelPteTable == NULL)	return (ERROR);    /* invalidate every page in the new page block */    for (i = 0; i < (1 << NUM_TIB_BITS); i++)	{	lowerLevelPteTable[i].pte.sfpd.fields.addr = -1;	lowerLevelPteTable[i].pte.sfpd.fields.ci = 0;	lowerLevelPteTable[i].pte.sfpd.fields.m = 0; 	lowerLevelPteTable[i].pte.sfpd.fields.u = 0; 	lowerLevelPteTable[i].pte.sfpd.fields.wp = 0; 	lowerLevelPteTable[i].pte.sfpd.fields.dt = DT_INVALID; 	}    /* write protect the new physical page containing the pte's       for this new page block */    mmuStateSet (&mmuGlobalTransTbl, lowerLevelPteTable,    		 MMU_STATE_MASK_WRITABLE, MMU_STATE_WRITABLE_NOT);     /* unlock the physical page containing the upper level pte,       so we can modify it */    mmuStateSet (&mmuGlobalTransTbl, thisTbl->pUpperLevelTable, 		 MMU_STATE_MASK_WRITABLE, MMU_STATE_WRITABLE);    upperLevelPte = 	    &thisTbl->pUpperLevelTable [(UINT) virtPageAddr / PAGE_BLOCK_SIZE];        /* modify the upperLevel pte to point to the new lowerLevel pte */    upperLevelPte->pte.sftd.addr = (UINT) lowerLevelPteTable >> 4;    upperLevelPte->pte.sftd.dt = DT_VALID_4_BYTE;    /* write protect the upper level pte table */    mmuStateSet (&mmuGlobalTransTbl, thisTbl->pUpperLevelTable, 		     MMU_STATE_MASK_WRITABLE, MMU_STATE_WRITABLE_NOT);    mmuATCFlush (virtPageAddr);    return (OK);    }/******************************************************************************** mmuEnable - turn mmu on or off** RETURNS: OK*/LOCAL STATUS mmuEnable     (    BOOL enable			/* TRUE to enable, FALSE to disable MMU */    )    {    FAST int oldIntLev;    /* lock out interrupts to protect kludgey static data structure */    oldIntLev = intLock ();      localTc.enable = enable;    __asm__ ("pmove _localTc, tc");    mmuEnabled = enable;    intUnlock (oldIntLev);    return (OK);    }/******************************************************************************** mmuOn - turn mmu on ** This routine assumes that interrupts are locked out.  It is called internally* to enable the mmu after it has been disabled for a short period of time* to access internal data structs.** RETURNS: OK*/LOCAL void mmuOn     (    )    {    localTc.enable = TRUE;    __asm__ ("pmove _localTc, tc");     }/******************************************************************************** mmuOff - turn mmu off ** This routine assumes that interrupts are locked out.  It is called internally* to disable the mmu for a short period of time* to access internal data structs.** RETURNS: OK*/LOCAL void mmuOff     (    )    {    localTc.enable = FALSE;    __asm__ ("pmove _localTc, tc");     }/******************************************************************************** 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.  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 */    )

⌨️ 快捷键说明

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