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

📄 mmui86lib.c

📁 VXWORKS源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
 * mismatch in virtual/physical address space, or the called out function's  * disapearance.  It is guaranteed that this code is in physical memory. */#define MMU_ON() \    do { int tempReg; WRS_ASM ("movl %%cr0,%0; orl $0x80010000,%0; \    movl %0,%%cr0; jmp 0f; 0:" : "=r" (tempReg) : : "memory"); } while (0)#define MMU_OFF() \    do { int tempReg; WRS_ASM ("movl %%cr0,%0; andl $0x7ffeffff,%0; \    movl %0,%%cr0; jmp 0f; 0:" : "=r" (tempReg) : : "memory"); } while (0)#define MMU_UNLOCK(wasEnabled, oldLevel) \    do { if (((wasEnabled) = mmuI86Enabled) == TRUE) \	{INT_LOCK (oldLevel); MMU_OFF (); } \    } while (0)#define MMU_LOCK(wasEnabled, oldLevel) \    do { if ((wasEnabled) == TRUE) \        {MMU_ON (); INT_UNLOCK (oldLevel);} \    } while (0)/* inline version of mmuI86TLBFlush() */#define	MMU_TLB_FLUSH() \    do { int tempReg; WRS_ASM ("pushfl; cli; movl %%cr3,%0; \    movl %0,%%cr3; jmp 0f; 0: popfl; " : "=r" (tempReg) : : "memory"); \    } while (0)/******************************************************************************** mmuI86LibInit - initialize module** Build a dummy translation table that will hold the page table entries* for the global translation table.  The MMU remains disabled upon* completion.** RETURNS: OK if no error, ERROR otherwise** ERRNO: S_mmuLib_INVALID_PAGE_SIZE*/STATUS mmuI86LibInit     (    int pageSize	/* system pageSize (must be 4096 for i86) */    )    {    PTE *pDirectoryTable;    int i;    /* initialize the data objects that are shared with vmLib.c */    mmuStateTransArray = &mmuStateTransArrayLocal [0];    mmuStateTransArraySize =          sizeof (mmuStateTransArrayLocal) / sizeof (STATE_TRANS_TUPLE);    mmuLibFuncs = mmuLibFuncsLocal;    mmuPageBlockSize = PAGE_BLOCK_SIZE;    /* we assume a 4096 byte page size */    if (pageSize != PAGE_SIZE)	{	errno = S_mmuLib_INVALID_PAGE_SIZE;	return (ERROR);	}    mmuI86Enabled = 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 *) memalign (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       */    /* allocate a page to hold the directory table */    mmuGlobalTransTbl.pDirectoryTable = pDirectoryTable = 	(PTE *) memalign (pageSize, pageSize);    if (pDirectoryTable == NULL)	return (ERROR);    /* invalidate all the directory table entries */    for (i = 0; i < (PAGE_SIZE / sizeof(PTE)) ;i++)	{	pDirectoryTable[i].field.present	= 0;	pDirectoryTable[i].field.rw		= 0;	pDirectoryTable[i].field.us		= 0;	pDirectoryTable[i].field.pwt		= 0;	pDirectoryTable[i].field.pcd		= 0;	pDirectoryTable[i].field.access		= 0;	pDirectoryTable[i].field.dirty		= 0;	pDirectoryTable[i].field.zero		= 0;	pDirectoryTable[i].field.avail		= 0;	pDirectoryTable[i].field.page		= -1;	}    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 *pDte;    PTE *pPageTable;    pDte = &pTransTbl->pDirectoryTable [(UINT) virtAddr >> DIRECTORY_INDEX];    pPageTable = (PTE *) (pDte->bits & PTE_TO_ADDR);     if ((UINT) pPageTable == 0xfffff000)	return (ERROR);    *result = &pPageTable[((UINT) virtAddr & TABLE_BITS) >> TABLE_INDEX];    return (OK);    }/******************************************************************************** mmuTransTblCreate - create a new translation table.** create a i86 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 directory table 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 directory table.*/LOCAL STATUS mmuTransTblInit     (    MMU_TRANS_TBL *newTransTbl		/* translation table to be inited */    )    {    FAST PTE *pDirectoryTable;    /* allocate a page to hold the directory table */    newTransTbl->pDirectoryTable = pDirectoryTable = 	(PTE *) memalign (mmuPageSize, mmuPageSize);    if (pDirectoryTable == NULL)	return (ERROR);    /* copy the directory table from mmuGlobalTransTbl,     * so we get the global virtual memory      */    bcopy ((char *) mmuGlobalTransTbl.pDirectoryTable, 	   (char *) pDirectoryTable, mmuPageSize);    /* write protect virtual memory pointing to the the directory table in      * the global translation table to insure that it can't be corrupted      */    mmuStateSet (&mmuGlobalTransTbl, (void *) pDirectoryTable, 		 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;    FAST PTE *pDte = transTbl->pDirectoryTable;    FAST PTE *pPageTable;    /* write enable the physical page containing the directory table */    mmuStateSet (&mmuGlobalTransTbl, transTbl->pDirectoryTable, 		 MMU_STATE_MASK_WRITABLE, MMU_STATE_WRITABLE);    /* deallocate only non-global page blocks */    for (i = 0; i < (PAGE_SIZE / sizeof(PTE)); i++, pDte++)	if ((pDte->field.present == 1) && !globalPageBlock[i]) 	    {	    pPageTable = (PTE *) (pDte->bits & PTE_TO_ADDR);	    mmuStateSet (&mmuGlobalTransTbl, pPageTable,			 MMU_STATE_MASK_WRITABLE, MMU_STATE_WRITABLE);	    free (pPageTable);	    }    /* free the page holding the directory table */    free (transTbl->pDirectoryTable);    /* 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 page table 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 a page table.*/LOCAL STATUS mmuVirtualPageCreate     (    MMU_TRANS_TBL *thisTbl, 		/* translation table */    void *virtPageAddr			/* virtual addr to create */    )    {    PTE *pDte;    FAST PTE *pPageTable;    FAST UINT i;    PTE *dummy;    if (mmuPteGet (thisTbl, virtPageAddr, &dummy) == OK)	return (OK);    pPageTable = (PTE *) memalign (mmuPageSize, mmuPageSize);    if (pPageTable == NULL)	return (ERROR);    /* invalidate every page in the new page block */    for (i = 0; i < (PAGE_SIZE / sizeof(PTE)); i++)	{	pPageTable[i].field.present	= 0;	pPageTable[i].field.rw		= 0;	pPageTable[i].field.us		= 0;	pPageTable[i].field.pwt		= 0;	pPageTable[i].field.pcd		= 0;	pPageTable[i].field.access	= 0;	pPageTable[i].field.dirty	= 0;	pPageTable[i].field.zero	= 0;	pPageTable[i].field.avail	= 0;	pPageTable[i].field.page	= -1;	}    /* write protect the new physical page containing the pte's       for this new page block */    mmuStateSet (&mmuGlobalTransTbl, pPageTable,    		 MMU_STATE_MASK_WRITABLE, MMU_STATE_WRITABLE_NOT);     /* unlock the physical page containing the directory table,       so we can modify it */    mmuStateSet (&mmuGlobalTransTbl, thisTbl->pDirectoryTable, 		 MMU_STATE_MASK_WRITABLE, MMU_STATE_WRITABLE);    pDte = &thisTbl->pDirectoryTable [(UINT) virtPageAddr >> DIRECTORY_INDEX];    

⌨️ 快捷键说明

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