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

📄 mmulib.c

📁 vxworks5.5.1源代码。完整源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* mmuLib.c - MMU library for Advanced RISC Machines Ltd. ARM processors *//* Copyright 1996-2002 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01v,07nov02,jb   Fix for SPR 8250001u,07nov02,jb   Conforming to coding standard01t,22oct02,rec  SPR 81285 - set default cache state to writethrough01s,06may02,to   reworked previous change01r,03may02,to   fix D-cache incoherency (SPR#76622)01q,13nov01,to   hand over global variables to mmuArchVars.c,         localize mmuPageSize, some merge from AE,         initialise (UK) -> initialize (US), etc.01q,02oct01,jpd  clarified some conditional code.01p,26jul01,scm  add extended small page table support for XScale...01o,25jul01,scm  add support for MMU_STATE_CACHEABLE_WRITETHROUGH for                 XScale...01n,23jul01,scm  change XScale name to conform to coding standards...01m,11dec00,scm  replace references to SA2 with XScale01l,06sep00,scm  add sa2 support...01k,10sep99,jpd  fixed mmu(Global)PageMap() bug when pages remapped (SPR #27199)01j,15feb99,jpd  added support for ARM740T, ARM720T, ARM920T.01i,21jan99,cdp  removed some more support for old ARM libraries.01h,20jan99,cdp  removed support for old ARM libraries.01g,04dec98,jpd  added support for ARM 940T, SA-1500; removed mmuIntLock();            cdp  added support for generic ARM ARCH3/ARCH4.01g,03feb99,wsl  add errno code to comment for mmuLibInit().01f,09mar98.jpd  further changes for SA-1100 and similar CPUs.01e,26jan98,jpd  cope with SA-1100: mark page tables uncacheable, add use of         routines provided by BSP to convert VA<->PA.01d,27oct97,kkk  took out "***EOF***" line from end of file.01c,18sep97,jpd  defer setting of cacheDataEnabled to when MMU is turned on.         Protect more operations from FIQ, where possible01b,18feb97,jpd  comments/documentation reviewed.01a,28oct96,jpd  written, based on Am29K version 01c.*//*DESCRIPTION:mmuLib.c provides the architecture dependent routines that directly controlthe memory management unit.  It provides 10 routines that are called by thehigher level architecture independent routines in vmLib.c:mmuLibInit - initialize modulemmuTransTblCreate - create a new translation tablemmuTransTblDelete - delete a translation table.mmuEnable - turn MMU on or offmmuStateSet - set state of virtual memory pagemmuStateGet - get state of virtual memory pagemmuPageMap - map physical memory page to virtual memory pagemmuGlobalPageMap - map physical memory page to global virtual memory pagemmuTranslate - translate a virtual address to a physical addressmmuCurrentSet - change active translation tableApplications using the MMU will never call these routines directly; thevisible interface is supported in vmLib.c.INTERNALAlthough this library contains code written for the ARM810 CPU, atthe time of writing, this code has not been tested fully on that CPU.YOU HAVE BEEN WARNED.PAGE TABLE STYLE MMUSmmuLib supports the creation and maintenance of multiple translation tables,one of which is the active translation table when the MMU is enabled.  Notethat VxWorks does not include a translation table as part of the taskcontext; individual tasks do not reside in private virtual memory.  However,we include the facilities to create multiple translation tables so that theuser may create "private" virtual memory contexts and switch them in anapplication specific manner.  New translation tables are created with a callto mmuTransTblCreate, and installed as the active translation table withmmuCurrentSet.  Translation tables are modified and potentially augmentedwith calls to mmuPageMap and mmuStateSet. The state of portions of thetranslation table can be read with calls to mmuStateGet and mmuTranslate.The traditional VxWorks architecture and design philosophy requires that allobjects and operating systems resources be visible and accessible to allagents (tasks, isrs, watchdog timers, etc) in the system.  This hastraditionally been ensured by the fact that all objects and data structuresreside in physical memory; thus, a data structure created by one agent maybe accessed by any other agent using the same pointer (object identifiers inVxWorks are often pointers to data structures.) This creates a potentialproblem if you have multiple virtual memory contexts.  For example, if asemaphore is created in one virtual memory context, you must guarantee thatthat semaphore will be visible in all virtual memory contexts if thesemaphore is to be accessed at interrupt level, when a virtual memorycontext other than the one in which it was created may be active. Anotherexample is that code loaded using the incremental loader from the shell mustbe accessible in all virtual memory contexts, since code is shared by allagents in the system.This problem is resolved by maintaining a global "transparent" mapping ofvirtual to physical memory for all the contiguous segments of physicalmemory (on board memory, i/o space, sections of VME space, etc) that isshared by all translation tables; all available physical memory appears atthe same address in virtual memory in all virtual memory contexts. Thistechnique provides an environment that allows resources that rely on aglobally accessible physical address to run without modification in a systemwith multiple virtual memory contexts.An additional requirement is that modifications made to the state of globalvirtual memory in one translation table appear in all translation tables.For example, memory containing the text segment is made read only (to avoidaccidental corruption) by setting the appropriate writable bits in thetranslation table entries corresponding to the virtual memory containing thetext segment.  This state information must be shared by all virtual memorycontexts, so that no matter what translation table is active, the textsegment is protected from corruption.  The mechanism that implements thisfeature is architecture dependent, but usually entails building a section ofa translation table that corresponds to the global memory, that is shared byall other translation tables.  Thus, when changes to the state of the globalmemory are made in one translation table, the changes are reflected in allother translation tables.mmuLib provides a separate call for constructing global virtual memory -mmuGlobalPageMap - which creates translation table entries that are sharedby all translation tables.  Initialization code in usrConfig makes calls tovmGlobalMap (which in turn calls mmuGlobalPageMap) to set up globaltransparent virtual memory for all available physical memory.  All callsmade to mmuGlobalPageMap must occur before any virtual memory contexts arecreated; changes made to global virtual memory after virtual memory contextsare created are not guaranteed to be reflected in all virtual memorycontexts.Most MMU architectures will dedicate some fixed amount of virtual memory toa minimal section of the translation table (a "segment", or "block").  Thiscreates a problem in that the user may map a small section of virtual memoryinto the global translation tables, and then attempt to use the virtualmemory after this section as private virtual memory.  The problem is thatthe translation table entries for this virtual memory are contained in theglobal translation tables, and are thus shared by all translation tables.This condition is detected by vmMap, and an error is returned, thus, thelower level routines in mmuLib.c (mmuPageMap, mmuGlobalPageMap) need notperform any error checking.If supporting VxVMI, a global variable called mmuPageBlockSize shouldbe defined which is equal to the minimum virtual segment size.This module supports the ARM MMU with a two level translation table:                                            TTBR                                             |                                             |    LEVEL 1                 -------------------------------------    PAGE DESCRIPTORS        |L1PD |L1PD |L1PD |L1PD |L1PD |L1PD | ...                            -------------------------------------                               |     |     |     |     |     |                               |     |     |     |     |     |                      ----------     |     v     v     v     v                      |              |    NULL  NULL  NULL  NULL                      |              |                      |              -------------------------                      |                                      |                      v                                      vLEVEL2   -------------------------------      -------------------------------PAGE     | PTE | PTE | PTE | PTE | PTE | ...  | PTE | PTE | PTE | PTE | PTE | ..DESCRIP. -------------------------------      -------------------------------(256/table) |     |                              |     |            |     ----  ...                      |     ----  ...            |        |                           |        |            v        v                           v        v          ----     ----                         ----     ----         |page|   |page|                       |page|   |page|          ----     ----                         ----     ----The Translation Table Base Register (TTBR) points to the top level whichconsists of an array of first-level page descriptors (LEVEL_1_PAGE_DESC).These point to arrays of 256 Level 2 Page Table Entries (PTE),which in turn point to pages.To implement global virtual memory, a separate translation table calledmmuGlobalTransTbl is created when the module is initialized.  Calls tommuGlobalPageMap will augment and modify this translation table.  When newtranslation tables are created, memory for the top level array of Level 1 tabledescriptors is allocated and initialized by duplicating the pointers inmmuGlobalTransTbl's top level level 1 table descriptor array.  Thus, thenew translation table will use the globaltranslation table's state information for portions of virtual memory that aredefined as global.  Here's a picture to illustrate:       GLOBAL TRANS TBL		        NEW TRANS TBL                root				     root                 |                                    |                 |                                    |                 v                                    vLEVEL 1  -------------------                  -------------------TABLE    |L1PD |L1PD |L1PD |...               |L1PD |L1PD |L1PD |...DESC.    -------------------                  -------------------            |     |                              |     |            o-------------------------------------     |            |     |                                    |            |     ------------                         |            |                |                         |            |                o--------------------------            |                |            v                vLEVEL2   -------------      ------------TABLE    | PTE | PTE |...  | PTE | PTE |...DESCRIP. -------------      ------------(256/table) |     |           |     |            |     ----  ...   |     ----  ...            |        |        |        |            v        v        v        v          ----     ----       ----     ----         |page|   |page|     |page|   |page|          ----     ----       ----     ----Note that with this scheme, the global memory granularity is 1MB.  Eachtime you map a section of global virtual memory, you dedicate at least1MB of the virtual space to global virtual memory that will be sharedby all virtual memory contexts.The physical memory that holds these data structures is obtained fromthe system memory manager via memPartAlignedAlloc to ensure that thememory is page aligned.  We want to protect this memory from beingcorrupted, so we write protect the descriptors that we set up in theglobal translation that correspond to the memory containing thetranslation table data structures.  This creates a "chicken and theegg" paradox, in that the only way we can modify these data structuresis through virtual memory that is now write protected, and we can'twrite enable it because the page descriptors for that memory are inwrite protected memory (confused yet?). So, you will notice thatanywhere that page descriptors are modified, we do so by locking outinterrupts, momentarily disabling the MMU protection, accessing thememory, enabling the MMU protection, and then re-enabling interrupts(see mmuStateSet, for example.)USER MODIFIABLE OPTIONS:1) Alternate memory source - A customer has special purpose hardware that   includes separate static RAM for the MMU's translation tables.   Thus, they require the ability to specify an alternate source of   memory other than the system memory partition.  The global function   pointer _func_armPageSource should be set by the BSP to point to a   routine that returns a memory partition id that describes memory to   be used as the source for translation table memory.  If this   function pointer is NULL, the system memory partition will be used.   The BSP must modify the function pointer before mmuLibInit is   called.2) The BSP cannot support an address mapping where virtual and physical   addresses are the same, particularly for those areas containing page   tables. In this case, the BSP must provide mapping functions to   convert between virtual and physical addresses and set the function   pointers _func_armVirtToPhys and _func_armPhysToVirt to point to   these functions. If these function pointers are NULL, it is assumed   that virtual addresses are equal to physical addresses in the   initial mapping.  The BSP must modify the function pointers before   mmuLibInit is called.MEMORY PROTECTION UNITS (MPUS)This library also supports Memory Protection Units (MPUs).  It is notpossible to support as flexible an interface as on page-table-styleMMUs and, in particular, VxVMI is not supported on MPUs.  Essentiallythe same interfaces are supported as for vmBaseLib on page-table-styleMMUs.On the ARM940T/740T MPUs, there is no mapping from virtual to physicaladdresses, so in VxWorks terms, the virtual and physical addresses mustbe the same.  Both the instruction and data spaces may be partitionedinto a maximum of eight regions, where each region is specified by abase address and a size.  In addition, the regions must have analignment equal to their size with a minimum region size of 4 kbytes.On 740T, there is only one set of regions defining the combinedinstruction and data regions.  On the 940T, we make the instruction anddata region definitions the same in the MPU registers (the user justspecifies one set).  The regions may have overlapping definitions, andthere is a priority ordering from the highest (region 7) to the lowest(region 0).  We allocate them in order from 0 upwards, so the user mayexert control over the priority of those regions.  When a region isdeleted, we shuffle any higher region definitions down, so that newregions are always allocated at higher priority to existing regions.The MPU cannot make regions read-only from code executing in SVC mode,so we do not allow areas to be marked as read-only.Only one context can be created, which is the "global" context.  Callsto mmuPageMap and mmuGlobalPageMap become NOPs as all pages are"mapped" all of the time (if no region is created for an address rangethen it is treated as though it had been mapped in, but marked asinvalid).  All the work is really done from mmuStateSetRegion() whichis the analogue of mmuStateSet for page-table-style MMUs.  This routinetries to allocate regions in the MPU according to the parametersgiven.  The strategy is currently quite simple, but copes with some ofthe obvious cases, like marking a bit of RAM as non-cacheable and thenmarking it as cacheable again (this causes a new region to be created,then deleted when the area is returned to the state of the rest ofRAM).  Attempts to create identical regions are ignored, as areattempts to create a region that is a subset of a region whose statematches.SEE ALSO: vmLib.I "ARM Architecture Reference Manual,".I "ARM 710A Data Sheet,".I "ARM 810 Data Sheet,".I "Digital Semiconductor SA-110 Microprocessor Technical Reference Manual.".I "Digital Semiconductor SA-1100 Microprocessor Technical Reference Manual,".I "Digital Semiconductor SA-1500 Mediaprocessor Data Sheet,".I "ARM 940T Technical Reference Manual,".I "ARM 740T Data Sheet,".I "ARM 720T Data Sheet,".I "ARM 920T Technical Reference Manual,"*/#include "vxWorks.h"#if !defined(ARMMMU)    #error ARMMMU not defined#endif#include "string.h"#include "stdlib.h"#include "memLib.h"#include "private/memPartLibP.h"#include "private/vmLibP.h"#include "arch/arm/mmuArmLib.h"#include "arch/arm/intArmLib.h"#include "mmuLib.h"#include "errno.h"#include "cacheLib.h"#define LOG_MSG(X0, X1, X2, X3, X4, X5, X6)			\	{							\	    if (_func_logMsg != NULL)				\		_func_logMsg(X0, X1, X2, X3, X4, X5, X6);	\	}#undef DEBUG#ifdef  DEBUG    #define LOCAL    #include "private/funcBindP.h"		/* for _func_logMsg */    #define MMU_DEBUG_OFF		0x0000    #define MMU_DEBUG_MPU		0x0001int mmuDebug = MMU_DEBUG_MPU;    #define MMU_LOG_MSG(FLG, X0, X1, X2, X3, X4, X5, X6)	\	{						\	    if (mmuDebug & FLG)				\		LOG_MSG(X0, X1, X2, X3, X4, X5, X6);	\	}#else /* DEBUG */    #define MMU_LOG_MSG(FLG, X0, X1, X2, X3, X4, X5, X6)#endif /* DEBUG */#if (ARMMMU != ARMMMU_NONE)/* externals *//* defines *//* * On page-table style MMUs, MMU_UNLOCK and MMU_LOCK are used to access * page table entries that are in virtual memory that has been * write-protected to protect it from being corrupted. Note that these * macros no longer check to see if the MMU was enabled before overriding * the MMU protection, as they do not need to switch the MMU off. * * On MPU-style MMUs, they are used to access region definitions within * the MPU registers. These cannot be done atomically, as the parts of a * region's definitions reside within different registers. So, the MPU * must be switched off while the region definitions are changed. */    #if (!ARM_HAS_MPU)        #define MMU_UNLOCK(oldLevel)					\    {								\    oldLevel = intIFLock ();	/* disable IRQs and FIQs */	\    mmuDacrSet (0x3);		/* override MMU protection */	\    }        #define MMU_LOCK(oldLevel)					\    {								\    mmuDacrSet (0x1);		/* restore MMU protection */	\    intIFUnlock (oldLevel);	/* restore IRQs and FIQs */	\    }    #else /* !ARM_HAS_MPU */        #define MMU_UNLOCK(oldLevel)				\    {							\    oldLevel = intIFLock ();				\

⌨️ 快捷键说明

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