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

📄 mmupro32lib.c

📁 VXWORKS源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
        /* 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); 	}    else        pPageTable = (PTE *) ((int)virtPageAddr & ADDR_TO_PAGEBASE);    /* 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 & DIR_BITS) >> DIR_INDEX];        /* modify the directory table entry to point to the new page table */    pDte->field.page = (UINT) pPageTable >> ADDR_TO_PAGE;    pDte->field.present = 1;    pDte->field.rw = 1;    /* write protect the directory table */    mmuStateSet (&mmuGlobalTransTbl, thisTbl->pDirectoryTable, 		  MMU_STATE_MASK_WRITABLE, MMU_STATE_WRITABLE_NOT);    /* defer the TLB flush to the mmuCurrentSet() at init time */    if (!firstTime)        {        MMU_TLB_FLUSH ();        }    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	 valid/invalid* MMU_STATE_WRITABLE 	MMU_STATE_WRITABLE_NOT	 writable/writeprotected* MMU_STATE_CACHEABLE 	MMU_STATE_CACHEABLE_NOT	 cacheable/not_cacheable* MMU_STATE_WBACK 	MMU_STATE_WBACK_NOT      write_back/write_through* MMU_STATE_GLOBAL    	MMU_STATE_GLOBAL_NOT     global/not_global** 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* MMU_STATE_MASK_WBACK* MMU_STATE_MASK_GLOBAL** These may be or'ed together in the stateMask parameter.  ** Accesses to a virtual page marked as invalid will result in a page fault.** 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 */    )    {    PTE *pPte;    int oldIntLev = 0;    BOOL wasEnabled;    if (mmuPteGet (transTbl, pageAddr, &pPte) != OK)	return (ERROR);    /* modify the pte with MMU turned off and interrupts locked out */    MMU_UNLOCK (wasEnabled, oldIntLev);    pPte->bits = (pPte->bits & ~stateMask) | (state & stateMask);    MMU_LOCK (wasEnabled, oldIntLev);    /* defer the TLB and Cache flush to the mmuCurrentSet() */    if (!firstTime)        {        MMU_TLB_FLUSH ();        cacheArchClearEntry (DATA_CACHE, pPte);	}    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	 valid/invalid* MMU_STATE_WRITABLE 	MMU_STATE_WRITABLE_NOT	 writable/writeprotected* MMU_STATE_CACHEABLE 	MMU_STATE_CACHEABLE_NOT	 cacheable/not_cacheable* MMU_STATE_WBACK 	MMU_STATE_WBACK_NOT      write_back/write_through* MMU_STATE_GLOBAL    	MMU_STATE_GLOBAL_NOT     global/not_global** 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* MMU_STATE_MASK_WBACK* MMU_STATE_MASK_GLOBAL** RETURNS: OK or ERROR if virtual page does not exist.*/LOCAL STATUS mmuStateGet     (    MMU_TRANS_TBL *transTbl, 	/* translation table */    void *pageAddr, 		/* page whose state we're querying */    UINT *state			/* place to return state value */    )    {    PTE *pPte;    if (mmuPteGet (transTbl, pageAddr, &pPte) != OK)	return (ERROR);    *state = pPte->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 *pPte;    int oldIntLev = 0;    BOOL wasEnabled;    BOOL status = mmuPteGet (transTbl, virtualAddress, &pPte);    if ((mmuPageSize == PAGE_SIZE_4KB) && (status != OK))	{	/* build the translation table for the virtual address */	if (mmuVirtualPageCreate (transTbl, virtualAddress) != OK)	    return (ERROR);	if (mmuPteGet (transTbl, virtualAddress, &pPte) != OK)	    return (ERROR);	}    MMU_UNLOCK (wasEnabled, oldIntLev);    if (mmuPageSize == PAGE_SIZE_4MB)        (int)physPage &= ADDR_TO_PAGEBASE;    pPte->field.page = (UINT)physPage >> ADDR_TO_PAGE;     MMU_LOCK (wasEnabled, oldIntLev);    MMU_TLB_FLUSH ();    cacheArchClearEntry (DATA_CACHE, pPte);    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 *pPte;    int oldIntLev = 0;    BOOL wasEnabled;    BOOL status = mmuPteGet (&mmuGlobalTransTbl, virtualAddress, &pPte);    if ((mmuPageSize == PAGE_SIZE_4KB) && (status != OK))	{	/* build the translation table for the virtual address */	if (mmuVirtualPageCreate (&mmuGlobalTransTbl, virtualAddress) != OK)	    return (ERROR);	if (mmuPteGet (&mmuGlobalTransTbl, virtualAddress, &pPte) != OK)	    return (ERROR);	/* the globalPageBlock array is write protected */	mmuStateSet (&mmuGlobalTransTbl, globalPageBlock, 		     MMU_STATE_MASK_WRITABLE, MMU_STATE_WRITABLE);	globalPageBlock [((UINT) virtualAddress & DIR_BITS) >> DIR_INDEX] =			TRUE;		mmuStateSet (&mmuGlobalTransTbl, globalPageBlock, 		     MMU_STATE_MASK_WRITABLE, MMU_STATE_WRITABLE_NOT);	}    MMU_UNLOCK (wasEnabled, oldIntLev);    if (mmuPageSize == PAGE_SIZE_4MB)        (int)physPage &= ADDR_TO_PAGEBASE;    pPte->field.page = (UINT)physPage >> ADDR_TO_PAGE;     MMU_LOCK (wasEnabled, oldIntLev);    /* defer the TLB and Cache flush to the mmuCurrentSet() */    if (!firstTime)        {        MMU_TLB_FLUSH ();        cacheArchClearEntry (DATA_CACHE, pPte);	}    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 *pPte;    if (mmuPteGet (transTbl, virtAddress, &pPte) != OK)	{	errno = S_mmuLib_NO_DESCRIPTOR; 	return (ERROR);	}    if (pPte->field.present == 0)	{	errno = S_mmuLib_INVALID_DESCRIPTOR; 	return (ERROR);	}    /* add offset into page */    if (mmuPageSize == PAGE_SIZE_4KB)        *physAddress = (void *)((UINT)(pPte->bits & PTE_TO_ADDR_4KB) + 			        ((UINT)virtAddress & OFFSET_BITS_4KB));    else        *physAddress = (void *)((UINT)(pPte->bits & PTE_TO_ADDR_4MB) + 			        ((UINT)virtAddress & OFFSET_BITS_4MB));    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 translation table */    )     {    FAST int oldLev;    if (firstTime)	{	mmuMemPagesWriteDisable (&mmuGlobalTransTbl);	mmuMemPagesWriteDisable (transTbl);	/* perform the deferred TLB and Cache flush */        /* MMU_TLB_FLUSH (); */	/* done by following mmuPro32PdbrSet () */        if (sysProcessor != X86CPU_386)            WRS_ASM ("wbinvd");	/* flush the entire cache */	firstTime = FALSE;	}    oldLev = intLock ();    mmuCurrentTransTbl = transTbl;    mmuPro32PdbrSet (transTbl);    intUnlock (oldLev);    }/******************************************************************************** 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 ix;    if (mmuPageSize == PAGE_SIZE_4KB)        for (ix = 0; ix < (PD_SIZE / sizeof(PTE)); ix++)	    {	    thisPage = (void *) (transTbl->pDirectoryTable[ix].bits & 				 PTE_TO_ADDR_4KB);	    if ((int)thisPage != (0xffffffff & PTE_TO_ADDR_4KB))	        mmuStateSet (transTbl, thisPage, MMU_STATE_MASK_WRITABLE,			     MMU_STATE_WRITABLE_NOT);	    }    mmuStateSet (transTbl, transTbl->pDirectoryTable, MMU_STATE_MASK_WRITABLE, 		 MMU_STATE_WRITABLE_NOT);    }

⌨️ 快捷键说明

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