?? vmlib.c
字號:
/* vmLib.c - architecture-independent virtual memory support library (VxVMI Option) *//* Copyright 1984-2001 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------02a,02apr02,dtr Adding PPC860.01z,16nov01,to declare global variables in vmData.c to avoid getting multiple vm*Lib.o pulled01y,26jul01,scm add extended small page table support for XScale...01x,03mar00,zl merged SH support into T201w,30mar99,jdi doc: fixed table formatting that refgen can't handle.01v,14mar99,jdi doc: removed refs to config.h and/or configAll.h (SPR 25663).01u,21feb99,jdi doc: listed errnos.01t,02jul96,ms replaced "%" with "NOT_PAGE_ALIGNED" to fix SPR 6833.01s,04mar96,ms made null for PPC.01r,13sep93,caf made null for MIPS.01s,18nov93,edm changed BOOL mmuPhysAddrShifted to int mmuPhysAddrShift.01r,05apr93,edm added support for physical addresses->page number option.01q,19feb93,jdi doc: add VxVMI option label and Availability section.01p,12feb93,jdi doc tweaks.01o,12feb93,rdc changed scheme for sharing data structures with mmuLib. Doc.01n,09feb93,rdc added vmTextPageProtect. 01m,21oct92,jdi doc change as per pme.01l,19oct92,jcf cleanup. fixed vmLibInit.01k,14oct92,jdi made vmContextInit() NOMANUAL.01j,02oct92,jdi documentation cleanup.01i,01oct92,jcf added cacheFuncsSet() to attach mmu to cache support.01h,22sep92,rdc changed NUM_PAGE_STATES to 256. changed globalPageBlockArray to be type UINT8 instead of BOOL.01g,23aug92,jcf cleanup.01f,30jul92,rdc added pointer to vmTranslate routine to vmLibInfo. 01e,27jul92,rdc moved "vmLib.c" to "vmBaseLib.c", and installed the unbundled vmLib.c here.01d,21jul92,rdc took out mutex in vmStateSet so callable from int level.01c,13jul92,rdc changed reference to vmLib.h to vmLibP.h.01b,09jul92,rdc changed indirect routine pointer configuration.01a,08jul92,rdc written.*//*DESCRIPTIONThis library provides an architecture-independent interface to the CPU'smemory management unit (MMU). Although vmLib is implemented witharchitecture-specific libraries, application code need never referencedirectly the architecture-dependent code in these libraries.A fundamental goal in the design of vmLib was to permit transparentbackward compatibility with previous versions of VxWorks that did not usethe MMU. System designers may opt to disable the MMU because of timingconstraints, and some architectures do not support MMUs; therefore VxWorksfunctionality must not be dependent on the MMU. The resulting designpermits a transparent configuration with no change in the programmingenvironment (but the addition of several protection features, such as textsegment protection) and the ability to disable virtual memory in systemsthat require it.The vmLib library provides a mechanism for creating virtual memory contexts,vmContextCreate(). These contexts are not automatically created for individual tasks, but may be created dynamically by tasks, and swapped in and out in an application specific manner. All virtual memory contexts share a global transparent mapping of virtualto physical memory for all of local memory and the local hardware devicespace (defined in sysLib.c for each board port in the `sysPhysMemDesc'data structure). When the system is initialized, all of local physicalmemory is accessible at the same address in virtual memory (this is donewith calls to vmGlobalMap().) Modifications made to this global mappingin one virtual memory context appear in all virtual memory contexts. Forexample, if the exception vector table (which resides at address 0 inphysical memory) is made read only by calling vmStateSet() on virtualaddress 0, the vector table will be read only in all virtual memorycontexts.Private virtual memory can also be created. When physical pages aremapped to virtual memory that is not in the global transparent region,this memory becomes accessible only in the context in which it wasmapped. (The physical pages will also be accessible in the transparenttranslation at the physical address, unless the virtual pages in theglobal transparent translation region are explicitly invalidated.) Statechanges (writability, validity, etc.) to a section of private virtualmemory in a virtual memory context do not appear in other contexts. Tofacilitate the allocation of regions of virtual space, vmGlobalInfoGet()returns a pointer to an array of booleans describing which portions of thevirtual address space are devoted to global memory. Each successive arrayelement corresponds to contiguous regions of virtual memory the size ofwhich is architecture-dependent and which may be obtained with a call tovmPageBlockSizeGet(). If the boolean array element is true, thecorresponding region of virtual memory, a "page block", is reserved forglobal virtual memory and should not be used for private virtual memory.(If vmMap() is called to map virtual memory previously defined as global,the routine will return an error.)All the state information for a block of virtual memory can be set in asingle call to vmStateSet(). It performs parameter checking and checksthe validity of the specified virtual memory context. It may also be usedto set architecture-dependent state information. See vmLib.h for additionalarchitecture-dependent state information.The routine vmContextShow() in vmShow displays the virtual memory contextfor a specified context. For more information, see the manual entry forthis routine.CONFIGURATION:Full MMU support (vmLib, and optionally, vmShow) is included in VxWorkswhen the configuration macro INCLUDE_MMU_FULL is defined. If theconfiguration macro INCLUDE_MMU_BASIC is also defined, the default isfull MMU support (unbundled).The sysLib.c library contains a data structure called `sysPhysMemDesc',which is an array of PHYS_MEM_DESC structures. Each element of the arraydescribes a contiguous section of physical memory. The description ofthis memory includes its physical address, the virtual address where itshould be mapped (typically, this is the same as the physical address, butnot necessarily so), an initial state for the memory, and a mask definingwhich state bits in the state value are to be set. Default configurationsare defined for each board support package (BSP), but these mappings maybe changed to suit user-specific system configurations. For example, theuser may need to map additional VME space where the backplane networkinterface data structures appear.INTERNALMutual exclusion is provided in all operations that modify and examinetranslation tables; routines in mmuLib need not provide mutual exclusionmechanisms for translation tables.AVAILABILITYThis library and vmShow are distributed as the unbundled virtual memorysupport option, VxVMI. A scaled down version, vmBaseLib, isprovided with VxWorks for systems that do not permit optional use of theMMU, or for architectures that require certain features of the MMU toperform optimally (in particular, architectures that rely heavily oncaching, but do not support bus snooping, and thus require the ability tomark interprocessor communications buffers as non-cacheable.) Mostroutines in vmBaseLib are referenced internally by VxWorks; they are notcallable by application code.INCLUDE FILES: vmLib.h SEE ALSO: sysLib, vmShow,.pG "Virtual Memory"*/#include "vxWorks.h"#if (CPU_FAMILY != MIPS) && ((CPU_FAMILY!=PPC) || (CPU==PPC860))#include "private/vmLibP.h"#include "stdlib.h"#include "mmuLib.h"#include "private/classLibP.h"#include "private/objLibP.h"#include "errno.h"#include "cacheLib.h"#include "sysLib.h"#include "private/semLibP.h" /* macros and defines *//* detect if addr is in global virtual memory */#define ADDR_IN_GLOBAL_SPACE(vAddr) (globalPageBlockArray[(unsigned) vAddr / mmuPageBlockSize])/* compute if page is aligned without using "%" (SPR 6833) */#define NOT_PAGE_ALIGNED(addr) (((UINT)(addr)) & ((UINT)vmPageSize - 1))/* macros to reference mmuLib routines indirectly through mmuLibFunc table */#define MMU_LIB_INIT (*(mmuLibFuncs.mmuLibInit))#define MMU_TRANS_TBL_CREATE (*(mmuLibFuncs.mmuTransTblCreate))#define MMU_TRANS_TBL_DELETE (*(mmuLibFuncs.mmuTransTblDelete))#define MMU_ENABLE (*(mmuLibFuncs.mmuEnable))#define MMU_STATE_SET (*(mmuLibFuncs.mmuStateSet))#define MMU_STATE_GET (*(mmuLibFuncs.mmuStateGet))#define MMU_PAGE_MAP (*(mmuLibFuncs.mmuPageMap))#define MMU_GLOBAL_PAGE_MAP (*(mmuLibFuncs.mmuGlobalPageMap))#define MMU_TRANSLATE (*(mmuLibFuncs.mmuTranslate))#define MMU_CURRENT_SET (*(mmuLibFuncs.mmuCurrentSet))IMPORT int mmuPageBlockSize; /* initialized by mmuLib.c */IMPORT STATE_TRANS_TUPLE *mmuStateTransArray; /* initialized by mmuLib.c */IMPORT int mmuStateTransArraySize; /* initialized by mmuLib.c */IMPORT MMU_LIB_FUNCS mmuLibFuncs; /* initialized by mmuLib.c */IMPORT int mmuPhysAddrShift; /* see vmData.c *//* imports */IMPORT void sysInit ();IMPORT void etext ();/* class declaration */LOCAL VM_CONTEXT_CLASS vmContextClass;VM_CONTEXT_CLASS_ID vmContextClassId = &vmContextClass;/* state translation tables - these tables are initialized in vmLibInit, * and are used to translate between architecture-independent and architecture * dependent states. arch indep. state info uses 8 bits - 2^8=256 possible * states */#define NUM_PAGE_STATES 256/* locals */LOCAL UINT vmStateTransTbl[NUM_PAGE_STATES];LOCAL UINT vmMaskTransTbl[NUM_PAGE_STATES];LOCAL LIST vmContextList; /* XXX delete ? */LOCAL int vmPageSize;LOCAL VM_CONTEXT sysVmContext; /* initial vm context */LOCAL VM_CONTEXT * currentContext = NULL;LOCAL SEMAPHORE globalMemMutex;/* globals */UINT8 *globalPageBlockArray;int mutexOptionsVmLib = SEM_Q_PRIORITY |SEM_DELETE_SAFE | SEM_INVERSION_SAFE;LOCAL STATUS vmTextPageProtect (void *textPageAddr, BOOL protect);/********************************************************************************* vmLibInit - initialize the virtual memory support module (VxVMI Option)** This routine initializes the virtual memory context class.* It is called only once during system initialization.** AVAILABILITY* This routine is distributed as a component of the unbundled virtual memory* support option, VxVMI.** RETURNS: OK.*/STATUS vmLibInit ( int pageSize /* size of page */ ) { int i; int j; UINT newState; UINT newMask; int arraySize; if (vmLibInfo.vmLibInstalled) /* only install vmLib once */ return (OK); if (pageSize == 0) return (ERROR); /* check for reasonable parameter */ vmPageSize = pageSize; classInit ((OBJ_CLASS *) &vmContextClass.coreClass, sizeof (VM_CONTEXT), OFFSET(VM_CONTEXT, objCore), (FUNCPTR) vmContextCreate, NULL, NULL); /* initialize the mutual exclusion semaphore that protects the global * memory mappings. */ semMInit (&globalMemMutex, mutexOptionsVmLib); /* initialize the page state translation table. This table is used to * translate betseen architecture-independent state values and architecture * dependent state values */ for (i = 0; i < NUM_PAGE_STATES; i++) { newState = 0; for (j = 0; j < mmuStateTransArraySize; j++) { STATE_TRANS_TUPLE *thisTuple = &mmuStateTransArray[j]; UINT archIndepState = thisTuple->archIndepState; UINT archDepState = thisTuple->archDepState; UINT archIndepMask = thisTuple->archIndepMask; if ((i & archIndepMask) == archIndepState) newState |= archDepState; } vmStateTransTbl [i] = newState; } /* initialize the page state mask translation table. This table is used to * translate betseen architecture-independent state masks and architecture * dependent state masks */ for (i = 0; i < NUM_PAGE_STATES; i++) { newMask = 0; for (j = 0; j < mmuStateTransArraySize; j++) { STATE_TRANS_TUPLE *thisTuple = &mmuStateTransArray[j]; UINT archIndepMask = thisTuple->archIndepMask; UINT archDepMask = thisTuple->archDepMask; if ((i & archIndepMask) == archIndepMask) newMask |= archDepMask; } vmMaskTransTbl [i] = newMask; } /* allocate memory for global page block array to keep track of which * sections of virtual memory are reserved for global virtual memory. * number of page blocks in virtual space = (2**32)/pageBlockSize. */ /* what we really want is: 2^32/mmuPageBlockSize, but we can't represent 2^32, so we assume mmuPageBlockSize is even, and divide everything by 2 so we can do 32 bit arithmatic */ arraySize = (UINT) 0x80000000 / (mmuPageBlockSize / 2); globalPageBlockArray = (UINT8 *) calloc (arraySize, sizeof (UINT8)); if (globalPageBlockArray == NULL) return (ERROR); lstInit (&vmContextList); /* XXX not currently used */ vmLibInfo.pVmStateSetRtn = vmStateSet; vmLibInfo.pVmStateGetRtn = vmStateGet; vmLibInfo.pVmEnableRtn = vmEnable; vmLibInfo.pVmPageSizeGetRtn = vmPageSizeGet; vmLibInfo.pVmTranslateRtn = vmTranslate; vmLibInfo.pVmTextProtectRtn = vmTextPageProtect; vmLibInfo.vmLibInstalled = TRUE; cacheMmuAvailable = TRUE; cacheFuncsSet (); /* update cache funtion pointers */ return (OK); }/********************************************************************************* vmGlobalMapInit - initialize global mapping (VxVMI Option)** This routine is a convenience routine that creates and installs a virtual* memory context with global mappings defined for each contiguous memory* segment defined in the physical memory descriptor array passed as an* argument. The context ID returned becomes the current virtual memory* context. ** The physical memory descriptor also contains state information* used to initialize the state information in the MMU's translation table* for that memory segment. The following state bits may be or'ed together:** .TS* tab(|);* l2 l2 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, mask bits are or'ed together in the `initialStateMask' structure* element to describe which state bits are being specified in the `initialState'* structure element:** VM_STATE_MASK_VALID* VM_STATE_MASK_WRITABLE* VM_STATE_MASK_CACHEABLE** If the <enable> parameter is TRUE, the MMU is enabled upon return. * The vmGlobalMapInit() routine should be called only after vmLibInit() has been* called.** AVAILABILITY* This routine is distributed as a component of the unbundled virtual memory* support option, VxVMI.** RETURNS: A pointer to a newly created virtual memory context, or* NULL if the memory cannot be mapped.*/VM_CONTEXT_ID vmGlobalMapInit ( PHYS_MEM_DESC *pMemDescArray, /* pointer to array of mem descs */ int numDescArrayElements, /* num of elements in pMemDescArray */ BOOL enable /* enable virtual memory */ ) { int i; PHYS_MEM_DESC *thisDesc; /* set up global transparent mapping of physical to virtual memory */ for (i = 0; i < numDescArrayElements; i++) { thisDesc = &pMemDescArray[i]; /* map physical directly to virtual and set initial state */ if (vmGlobalMap ((void *) thisDesc->virtualAddr, (void *) thisDesc->physicalAddr, thisDesc->len) == ERROR) { return (NULL); } } /* create default virtual memory context */ if (vmContextInit (&sysVmContext) == ERROR) { return (NULL); }
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -