📄 vmbaselib.c
字号:
* architecture-specific code, not break it up into pages. */ archIndepState = thisDesc->initialState; archDepState = vmStateTransTbl [archIndepState]; archIndepStateMask = VM_STATE_MASK_CACHEABLE | VM_STATE_MASK_VALID | VM_STATE_MASK_WRITABLE | VM_STATE_MASK_BUFFERABLE | VM_STATE_MASK_EX_CACHEABLE | VM_STATE_MASK_EX_BUFFERABLE | VM_STATE_MASK_MEM_COHERENCY | VM_STATE_MASK_GUARDED; archDepStateMask = vmMaskTransTbl [archIndepStateMask]; if (MMU_STATE_SET (sysVmContext.mmuTransTbl, thisPage, archDepStateMask, archDepState, thisDesc->len) == ERROR) return NULL;#endif /* !defined(BUILD_MPU_LIB) */ } currentContext = &sysVmContext; MMU_CURRENT_SET (sysVmContext.mmuTransTbl); if (enable) if (MMU_ENABLE (TRUE) == ERROR) return (NULL); return (&sysVmContext); }/****************************************************************************** vmBaseContextInit - initializer for VM_CONTEXT.** This routine may be used to initialize static definitions of VM_CONTEXT** RETURNS: OK, or ERROR if the translation table could not be created.*/LOCAL STATUS vmBaseContextInit ( VM_CONTEXT *context ) { objCoreInit (&context->objCore, (CLASS_ID) vmContextClassId); semMInit (&context->sem, mutexOptionsVmBaseLib); context->mmuTransTbl = MMU_TRANS_TBL_CREATE (); if (context->mmuTransTbl == NULL) return (ERROR); return (OK); }/****************************************************************************** vmBaseGlobalMap - map physical to virtual in shared global virtual memory** vmBaseGlobalMap maps physical pages to virtual space that is shared by all* virtual memory contexts. Calls to vmBaseGlobalMap should be made before any* virtual memory contexts are created to insure that the shared global mappings* will be included in all virtual memory contexts. Mappings created with * vmBaseGlobalMap after virtual memory contexts are created are not guaranteed * to appear in all virtual memory contexts.** RETURNS: OK, or ERROR if virtualAddr or physical page addresses are not on* page boundaries, len is not a multiple of page size, or mapping failed.*/LOCAL STATUS vmBaseGlobalMap ( void *virtualAddr, void *physicalAddr, UINT len ) { int pageSize = vmPageSize; char *thisVirtPage = (char *) virtualAddr; char *thisPhysPage = (char *) physicalAddr;#if !defined(BUILD_MPU_LIB) FAST UINT numBytesProcessed = 0;#endif if (!vmLibInfo.vmBaseLibInstalled) return (ERROR); if (((UINT) thisVirtPage % pageSize) != 0) { errno = S_vmLib_NOT_PAGE_ALIGNED; return (ERROR); } if ((!mmuPhysAddrShift) && (((UINT) thisPhysPage % pageSize) != 0)) { errno = S_vmLib_NOT_PAGE_ALIGNED; return (ERROR); } if ((len % pageSize) != 0) { errno = S_vmLib_NOT_PAGE_ALIGNED; return (ERROR); }#if !defined(BUILD_MPU_LIB) while (numBytesProcessed < len) { if (MMU_GLOBAL_PAGE_MAP (thisVirtPage, thisPhysPage) == ERROR) return (ERROR); thisVirtPage += pageSize; thisPhysPage += (mmuPhysAddrShift ? 1 : pageSize); numBytesProcessed += pageSize; }#else /* !defined(BUILD_MPU_LIB) */ /* * On an MPU, we need to pass the whole region on to the * architecture-specific code, not break it up into pages. */ if (MMU_GLOBAL_PAGE_MAP (thisVirtPage, thisPhysPage, len) == ERROR) return ERROR;#endif /* !defined(BUILD_MPU_LIB) */ return (OK); }/****************************************************************************** vmBaseStateSet - change the state of a block of virtual memory** This routine changes the state of a block of virtual memory. Each page* of virtual memory has at least three elements of state information:* validity, writability, and cacheability. Specific architectures may* define additional state information; see vmLib.h for additional* architecture-specific states. Memory accesses to a page marked as* invalid will result in an exception. Pages may be invalidated to prevent* them from being corrupted by invalid references. Pages may be defined as* read-only or writable, depending on the state of the writable bits.* Memory accesses to pages marked as not-cacheable will always result in a* memory cycle, bypassing the cache. This is useful for multiprocessing,* multiple bus masters, and hardware control registers.** The following states are provided and may be or'ed together in the * state parameter: ** .TS* tab(|);* l0 l0 l .* VM_STATE_VALID | VM_STATE_VALID_NOT | valid/invalid* VM_STATE_WRITABLE | VM_STATE_WRITABLE_NOT | writable/write-protected* VM_STATE_CACHEABLE | VM_STATE_CACHEABLE_NOT | cacheable/not-cacheable* .TE** Additionally, the following masks are provided so that only specific* states may be set. These may be or'ed together in the `stateMask' parameter. ** VM_STATE_MASK_VALID* VM_STATE_MASK_WRITABLE* VM_STATE_MASK_CACHEABLE** If <context> is specified as NULL, the current context is used.** This routine is callable from interrupt level.** RETURNS: OK, or ERROR if the validation fails, <pVirtual> is not on a page* boundary, <len> is not a multiple of the page size, or the* architecture-dependent state set fails for the specified virtual address.** ERRNO:* S_vmLib_NOT_PAGE_ALIGNED,* S_vmLib_BAD_STATE_PARAM,* S_vmLib_BAD_MASK_PARAM**/STATUS vmBaseStateSet ( VM_CONTEXT_ID context, /* context - NULL == currentContext */ void *pVirtual, /* virtual address to modify state of */ int len, /* len of virtual space to modify state of */ UINT stateMask, /* state mask */ UINT state /* state */ ) { FAST int pageSize = vmPageSize; FAST char *thisPage = (char *) pVirtual;#if !defined(BUILD_MPU_LIB) FAST UINT numBytesProcessed = 0;#endif UINT archDepState; UINT archDepStateMask; STATUS retVal = OK; if (!vmLibInfo.vmBaseLibInstalled) return (ERROR); if (context == NULL) context = currentContext; if (OBJ_VERIFY (context, vmContextClassId) != OK) return (ERROR); if (((UINT) thisPage % pageSize) != 0) { errno = S_vmLib_NOT_PAGE_ALIGNED; return (ERROR); } if ((len % pageSize) != 0) { errno = S_vmLib_NOT_PAGE_ALIGNED; return (ERROR); } if (state > NUM_PAGE_STATES) { errno = S_vmLib_BAD_STATE_PARAM; return (ERROR); } if (stateMask > NUM_PAGE_STATES) { errno = S_vmLib_BAD_MASK_PARAM; return (ERROR); } /* get the architecture dependent states and state masks */ archDepState = vmStateTransTbl [state]; archDepStateMask = vmMaskTransTbl [stateMask]; /* call mmuStateSet to do the actual work */#if !defined(BUILD_MPU_LIB) while (numBytesProcessed < (UINT)len) { if (MMU_STATE_SET (context->mmuTransTbl, thisPage, archDepStateMask, archDepState) == ERROR) { retVal = ERROR; break; } thisPage += pageSize; numBytesProcessed += pageSize; }#else /* !defined(BUILD_MPU_LIB) */ /* * On an MPU, we need to pass the whole region on to the * architecture-specific code, not break it up into pages. */ if (MMU_STATE_SET (context->mmuTransTbl, thisPage, archDepStateMask, archDepState, len) == ERROR) retVal = ERROR;#endif /*!defined(BUILD_MPU_LIB) */ return (retVal); }/****************************************************************************** vmBaseEnable - enable/disable virtual memory** vmBaseEnable turns virtual memory on and off. ** RETURNS: OK, or ERROR if validation failed, or architecture-dependent * code failed.*/LOCAL STATUS vmBaseEnable ( BOOL enable /* TRUE == enable MMU, FALSE == disable MMU */ ) { return (MMU_ENABLE (enable)); }/****************************************************************************** vmBasePageSizeGet - return the page size** This routine returns the architecture-dependent page size.** This routine is callable from interrupt level.** RETURNS: The page size of the current architecture. **/int vmBasePageSizeGet (void) { return (vmPageSize); }/****************************************************************************** vmBaseTranslate - translate a virtual address to a physical address** vmBaseTranslate may be used to retrieve the mapping information for a* virtual address from the page translation tables. If the given * virtual address has never been mapped, either the returned status will* be ERROR, or, the returned status will be OK, but the returned physical* address will be -1.* If context is specified as NULL, the current context is used.* This routine is callable from interrupt level.** RETURNS: OK, or validation failed, or translation failed.*/LOCAL STATUS vmBaseTranslate ( VM_CONTEXT_ID context, /* context - NULL == currentContext */ void *virtualAddr, /* virtual address */ void **physicalAddr /* place to put result */ ) { STATUS retVal; if (context == NULL) context = currentContext; if (OBJ_VERIFY (context, vmContextClassId) != OK) return (ERROR); retVal = MMU_TRANSLATE (context->mmuTransTbl, virtualAddr, physicalAddr); return (retVal); }#endif /* (CPU_FAMILY != MIPS) */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -