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

📄 mmupro36lib.c

📁 VXWORKS源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
    /* modify the directory table entry to point to the new page table */    pDte = &pDirectoryTable 	   [((UINT) virtPageAddr & (DIR_PTR_BITS | DIR_BITS)) >> DIR_INDEX];        pDte->field.page = (UINT) pPageTable >> ADDR_TO_PAGE;    pDte->field.present = 1;    pDte->field.rw = 1;    /* write protect the directory pointer table and the directory table */    for (ix = 0; ix < nDirPages; ix++)	{        mmuStateSet (&mmuGlobalTransTbl, 		     (void *) ((UINT32)pDirectoryTable + (mmuPageSize * ix)),		     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/write_protected* MMU_STATE_CACHEABLE 	MMU_STATE_CACHEABLE_NOT	 notcachable/cachable* 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;    INT32 oldIntLev = 0;    BOOL wasEnabled;    if (mmuPteGet (transTbl, pageAddr, &pPte) != OK)	return (ERROR);    /* modify the PTE with mmu turned off and interrupts locked out */    MMU_WP_UNLOCK (wasEnabled, oldIntLev);    pPte->bits[0] = (pPte->bits[0] & ~stateMask) | (state & stateMask);    MMU_WP_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/write_protected* MMU_STATE_CACHEABLE 	MMU_STATE_CACHEABLE_NOT	 notcachable/cachable* 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, 	/* tranlation 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[0];     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;    INT32 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);	}    if (mmuPageSize != PAGE_SIZE_4KB)        (UINT)physPage &= ADDR_TO_PAGEBASE;     MMU_WP_UNLOCK (wasEnabled, oldIntLev);    pPte->field.page   = (UINT)physPage >> ADDR_TO_PAGE;    MMU_WP_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;    INT32 oldIntLev = 0;    BOOL wasEnabled;    BOOL status = mmuPteGet (&mmuGlobalTransTbl, virtualAddress, &pPte);    int ix;    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);        ix = ((UINT) virtualAddress & (DIR_PTR_BITS | DIR_BITS)) >> DIR_INDEX;        globalPageBlock [ix] = (UINT8) TRUE;	        mmuStateSet (&mmuGlobalTransTbl, globalPageBlock,    	             MMU_STATE_MASK_WRITABLE, MMU_STATE_WRITABLE_NOT);	}    if (mmuPageSize != PAGE_SIZE_4KB)	(UINT)physPage &= ADDR_TO_PAGEBASE;    MMU_WP_UNLOCK (wasEnabled, oldIntLev);    pPte->field.page = (UINT)physPage >> ADDR_TO_PAGE;    MMU_WP_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[0] & PTE_TO_ADDR_4KB) + 			        ((UINT)virtAddress & OFFSET_BITS_4KB));    else        *physAddress = (void *)((UINT)(pPte->bits[0] & PTE_TO_ADDR_2MB) + 			        ((UINT)virtAddress & OFFSET_BITS_2MB));    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 */    )     {    INT32 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 ();		/* LOCK INTERRUPTS */    mmuCurrentTransTbl = transTbl;    mmuPro36PdbrSet (transTbl);    intUnlock (oldLev);			/* UNLOCK INTERRUPTS */    }/******************************************************************************** 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    )    {    PTE * pDirectoryTable;    void * thisPage;    INT32 ix;    pDirectoryTable = (PTE *)(transTbl->pDirectoryTable->bits[0] & PDP_TO_ADDR);    if (mmuPageSize == PAGE_SIZE_4KB)        for (ix = 0; ix < ((PD_SIZE * 4) / sizeof(PTE)); ix++)	    {	    thisPage = (void *)(pDirectoryTable[ix].bits[0] & PTE_TO_ADDR_4KB);	    if ((int)thisPage != (0xffffffff & PTE_TO_ADDR_4KB))	        mmuStateSet (transTbl, thisPage, MMU_STATE_MASK_WRITABLE,			     MMU_STATE_WRITABLE_NOT);	    }    for (ix = 0; ix < nDirPages; ix++)	{	thisPage = (void *)((UINT)pDirectoryTable + (mmuPageSize * ix));        mmuStateSet (transTbl, thisPage, MMU_STATE_MASK_WRITABLE, 		     MMU_STATE_WRITABLE_NOT);	}    mmuStateSet (transTbl, transTbl->pDirectoryTable, MMU_STATE_MASK_WRITABLE, 		 MMU_STATE_WRITABLE_NOT);    }/******************************************************************************** mmuPro36PageMap - map 36bit physical memory page to virtual memory page** The 36bit 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. */STATUS mmuPro36PageMap     (    MMU_TRANS_TBL * transTbl, 	/* translation table */    void * virtualAddress, 	/* 32bit virtual address */    LL_INT physPage		/* 36bit physical address */    )    {    PTE *    pPte;    BOOL     wasEnabled;    INT32    oldIntLev = 0;    UINT32 * pPhysPage = (UINT32 *)&physPage;    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);	}    if (mmuPageSize != PAGE_SIZE_4KB)        pPhysPage[0] &= ADDR_TO_PAGEBASE;     MMU_WP_UNLOCK (wasEnabled, oldIntLev);    pPte->field.page   = pPhysPage[0] >> ADDR_TO_PAGE;    pPte->field.page36 = pPhysPage[1] & 0x0000000f;    MMU_WP_LOCK (wasEnabled, oldIntLev);    MMU_TLB_FLUSH ();    cacheArchClearEntry (DATA_CACHE, pPte);    return (OK);    }/******************************************************************************** mmuPro36Translate - translate a virtual address to a 36bit physical address** Traverse the translation table and extract the 36bit 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.*/STATUS mmuPro36Translate     (    MMU_TRANS_TBL * transTbl, 		/* translation table */    void * virtAddress,			/* 32bit virtual address */    LL_INT * physAddress		/* place to return 36bit result */    )    {    PTE *    pPte;    UINT32 * pPhysAddr = (UINT32 *) physAddress;    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)        pPhysAddr[0] = (UINT32)(pPte->bits[0] & PTE_TO_ADDR_4KB) + 		       ((UINT32)virtAddress & OFFSET_BITS_4KB);    else        pPhysAddr[0] = (UINT32)(pPte->bits[0] & PTE_TO_ADDR_2MB) + 		       ((UINT32)virtAddress & OFFSET_BITS_2MB);    pPhysAddr[1] = pPte->bits[1];    return (OK);    }

⌨️ 快捷键说明

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