Important Announcement
PubHTML5 Scheduled Server Maintenance on (GMT) Sunday, June 26th, 2:00 am - 8:00 am.
PubHTML5 site will be inoperative during the times indicated!

Home Explore Andrew N Sloss, Dominic System and Chris Wright,” ARM System Developers Guide”, Elsevier,

Andrew N Sloss, Dominic System and Chris Wright,” ARM System Developers Guide”, Elsevier,

Published by Demo 1, 2021-07-03 06:41:10

Description: Andrew N Sloss, Dominic System and Chris Wright,” ARM System Developers Guide”, Elsevier,

Search

Read the Text Version

12.8 Summary 459 There are two policies available when writing data to cache memory. If the controller only updates cache memory, it is a writeback policy. If the cache controller writes to both the cache and main memory, it is a writethrough policy. There are two policies a cache controller uses to allocate a cache line on a cache miss. A read-allocate policy allocates a cache line when data is read from main memory. A write-allocate policy allocates a cache line on a write to main memory. ARM uses the term clean to mean forcing a copyback of data in the D-cache to main memory. ARM uses the term flush to mean invalidating the contents of a cache. Cache lockdown is a feature provided by some ARM cores. The lockdown feature allows code and data to be loaded into cache and marked as exempt from eviction. We also provided example code showing how to clean and flush ARM cached cores, and to lock code and data in cache.

13.1 Protected Regions 13.1.1 Overlapping Regions 13.1.2 Background Regions 13.2 Initializing the MPU, Caches, and Write Buffer 13.2.1 Defining Region Size and Location 13.2.2 Access Permission 13.2.3 Setting Region Cache and Write Buffer Attributes 13.2.4 Enabling Regions and the MPU 13.3 Demonstration of an MPU system 13.3.1 System Requirements 13.3.2 Assigning Regions Using a Memory Map 13.3.3 Initializing the MPU 13.3.4 Initializing and Configuring a Region 13.3.5 Putting It All Together, Initializing the MPU 13.3.6 A Protected Context Switch 13.3.7 mpuSLOS 13.4 Summary

13C h a p t e r Memory Protection Units Some embedded systems use a multitasking operating or control system and must ensure that a running task does not disrupt the operation of other tasks. The shielding of system resources and other tasks from unwanted access is called protection and is the subject of this chapter. There are two methods to control access to system resources, unprotected and protected. An unprotected system relies solely on software to protect the system resources. A protected system relies on both hardware and software to protect the system resources. The choice of method used by the control system depends on the capability of the processor and the requirements of the control system. An unprotected embedded system has no hardware dedicated to enforcing the use of memory and peripheral devices during operation. In these systems, each task must cooperate with all other tasks when accessing system resources because any task could corrupt the state of another task. This cooperative scheme may result in task failure when one task ignores the access limits of another task’s environment. An example of a task failure that might occur in an unprotected system involves reading and writing to a serial port register for communication. If one task is using the port, there is no way to prevent another task from using the same port. Successful use of the port must be coordinated through a system call that provides access to the port. An unauthorized access by a task working around these calls can easily disrupt communications through 461

462 Chapter 13 Memory Protection Units the port. The undesirable use of the resource could be unintentional, or it could be hostile in nature. In contrast, a protected system has dedicated hardware to check and restrict access to system resources. It can enforce resource ownership. Tasks are required to behave by a set of rules defined by the operating environment and enforced by hardware, which grants special privileges to the programs that monitor and control resources at the hardware level. A protected system is proactive in preventing one task from using the resources of another. The use of hardware to actively monitor the system provides better protection than cooperatively enforced software routines. ARM provides several processors equipped with hardware that actively protects system resources, either through a memory protection unit (MPU) or a memory management unit (MMU). A processor core with an MPU, the subject of this chapter, provides hardware protection over several software-designated regions. A processor core with an MMU, the subject of the next chapter, provides hardware protection and adds a virtual memory capability. In a protected system, there are two major classes of resource that need monitoring: the memory system and peripheral devices. Since ARM peripherals are generally memory mapped, the MPU uses the same method to protect both resources. An ARM MPU uses regions to manage system protection. A region is a set of attributes associated with an area of memory. The processor core holds these attributes in several CP15 registers and identifies each region by a number, which ranges between zero and seven. A region’s memory boundaries are configured using two attributes, the starting address and its length, which can be any power of two between 4 KB and 4 GB. In addition, the operation system assigns additional attributes to these regions: access rights and the cache and write buffer policies. The access to a region in memory is set as read-write, read-only, or no access and is subject to additional rights based on the current processor mode, which is either privileged or user. A region also has a cache write policy, which controls cache and write buffer attributes. For example, one region can be set to access memory using a writethrough policy, while another operates as noncached and nonbuffered. When the processor accesses a region in main memory, the MPU compares the region’s access permission attributes with the current processor mode to determine what action it will take. If the request satisfies the region access criteria, the core is allowed to read or write to main memory. However, if the memory request results in a memory access violation, the MPU will generate an abort signal. The abort signal is routed to the processor core, where it responds to the abort signal by taking an exception and vectoring to the abort handler. The abort handler then determines the abort type as either a prefetch or data abort, and based on the abort type the handler branches to the appropriate service routine. To implement a protected system, the control system defines several regions to different areas in main memory. A region may be created once and last for the life of the embedded system or may be created temporarily to satisfy the needs of a specific operation and then removed. How to assign and create regions is the subject of the next section.

13.1 Protected Regions 463 13.1 Protected Regions There are currently four ARM cores that contain an MPU; the ARM740T, ARM940T, ARM946E-S, and the ARM1026EJ-S. The ARM740T, ARM946E-S, and ARM1026EJ-S each contain 8 protection regions; the ARM940T contains 16 (see Table 13.1). The ARM740T, ARM946E-S, and ARM1026EJ-S have unified instruction and data regions—the data region and instruction region are defined using the same register that sets the size and starting address. The memory access permission and cache policies are config- ured independently for instruction and data access in the ARM946E-S and ARM1026EJ-S cores; in the ARM740T the same access permission and cache policies are assigned to both instruction and data memory. Regions are independent of whether the core has a Von Neumann or Harvard architecture. Each region is referenced by an identifying number between zero and seven. Because the ARM940T has separate regions to control instruction and data memory, the core can maintain different region sizes and starting addresses for instruction and data regions. The separation of instruction and data regions results in eight additional regions in this cached core. Although the identifying region numbers in an ARM940T still range from zero to seven, each region number has a pair of regions, one data region and one instruction region. There are several rules that govern regions: 1. Regions can overlap other regions. 2. Regions are assigned a priority number that is independent of the privilege assigned to the region. 3. When regions overlap, the attributes of the region with the highest priority number take precedence over the other regions. The priority only applies over the addresses within the areas that overlap. 4. A region’s starting address must be a multiple of its size. 5. A region’s size can be any power of two between 4 KB and 4 GB—in other words, any of the following values: 4 KB, 8 KB, 16 KB, 32 KB, 64 KB, . . . , 2 GB, 4 GB. Table 13.1 Summary of ARM cores with protection units. ARM core Number of Separate instruction Separate configuration of regions and data regions instruction and data regions ARM740T ARM940T 8 no no ARM946E-S 16 yes yes ARM1026EJ-S 8 no yes 8 no yes

464 Chapter 13 Memory Protection Units 6. Accessing an area of main memory outside of a defined region results in an abort. The MPU generates a prefetch abort if the core was fetching an instruction or a data abort if the memory request was for data. 13.1.1 Overlapping Regions Overlapping regions occur when some portion of the memory space assigned to one region is also in the memory space assigned to another region. Overlapping regions provide a greater flexibility when assigning access permission than nonoverlapping regions. For an example of overlapping regions, suppose a small embedded system has 256 KB of available memory starting at address 0x00000000 and must protect a privileged system area from user mode reads and writes. The privileged area code, data, and stacks fit in a 32 KB region starting, with the vector table, at 0x00000000. The remaining memory is assigned to user space. With overlapping regions, the system uses two regions, a 256 KB user region and a 32 KB privileged region (see Figure 13.1). The privileged region 1 is given the higher number because its attributes must take precedence over the user region 0. 13.1.2 Background Regions Another useful feature provided by overlapping regions is a background region—a low- priority region used to assign the same attributes to a large memory area. Other regions with higher priority are then placed over this background region to change the attributes of a smaller subset of the defined background region. So the higher-priority region is changing a subset of the background region attributes. A background region can shield several dormant 256 KB Region 0 (User access) 0x0000 32 KB Region 1 (Privileged access) Figure 13.1 Creating regions that overlap.

13.2 Initializing the MPU, Caches, and Write Buffer 465 Task 3 Task 3 Task 3 Region 3 Task 2 Task 2 Region 3 Task 1 Task 2 Task 1 Region 3 Region 0 Region 0 Task 1 Region 0 Task 1 Task 2 running running Task 3 running (User access) (Privileged access) Figure 13.2 Using a background region to control task access. memory areas from unwanted access while another part of the background region is active under a different region’s control. For example, if an embedded system defines a large privileged background region, it can lay a smaller unprivileged region over this background. The location of the smaller region can be moved over different areas of the background region to reveal different user spaces. When the system moves the smaller user region from one location to another, the previously covered area becomes protected by the background region. So the user region is acting as a window allowing access to different parts of the privileged background but has user-level attributes (see Figure 13.2). Figure 13.2 shows a simple three-task protection scheme. Region 3 defines the protection attributes of the active task, and the background region 0 controls access to the other tasks when they are dormant. When task 1 is running, the background region protects tasks 2 and 3 from task 1. When task 2 is running, tasks 1 and 3 are protected. Finally, when Task 3 is running, tasks 1 and 2 are protected. The reason this works is that region 3 has higher priority than region 0, even though region 0 has higher privilege. We use a background region in the example code at the end of this chapter to demonstrate a simple multitasking protection scheme. 13.2 Initializing the MPU, Caches, and Write Buffer In order to initialize the MPU, caches, and write buffer, the control system must define the protection regions required during the target operation.

466 Chapter 13 Memory Protection Units Table 13.2 Coprocessor registers that control the MPU. Function Primary register Secondary registers System control c1 c0 Region cache attributes c2 c0 Region write buffer attributes c3 c0 Region access permissions c5 c0 Region size and location c6 c0 to c7 At a minimum the control system must define at least one data region and one instruc- tion region before it can enable the protection unit. The protection unit must be enabled before or at the same time as the caches and write buffer are enabled. The control system configures the MPU by setting primary CP15 registers c1, c2, c3, c5, and c6. Table 13.2 lists the primary registers needed to control the operation of the MPU. Register c1 is the primary control register. Configuring registers c2 and c3 sets the cache and write buffer attributes of regions. Register c5 controls region access permissions. There are 8 or 16 secondary registers in register c6 that define the location and size of each region. There are other configuration registers in the ARM740T, ARM940T, ARM946E-S, and ARM1026EJ-S, but their use does not involve the basic operation of the MPU. To review the use of coprocessor 15 registers, refer to Section 3.5.2. The following steps are required to initialize the MPU, caches, and write buffer: 1. Define the size and location of the instruction and data regions using CP15:c6. 2. Set the access permission for each region using CP15:c5. 3. Set the cache and write buffer attributes for each region using CP15:c2 for cache and CP15:c3 for the write buffer. 4. Enable the caches and the MPU using CP15:c1. For each of these steps, there is a chapter section that follows describing the coprocessor 15 commands needed to configure each register. There is also example code showing the commands used in a routine that completes the step in the initialization process. 13.2.1 Defining Region Size and Location To define the size and address range of each region, the embedded system writes to one of the eight secondary registers, CP15:c6:c0:0 to CP15:c6:c7:0. Each secondary coprocessor register number maps to the corresponding region number identifier.

13.2 Initializing the MPU, Caches, and Write Buffer 467 Base address SBZ N E 31 12 11 65 10 Figure 13.3 CP15:c6 register format setting size and location of a region. Table 13.3 Bit field description of registers CP15:c6:c0 to CP15:c6:c7. Field name Bit fields Comments Base address [31:12] Address greater than 4 KB must be a multiple of the size represented in [5:1] SBZ [11:6] Value “should be zero” N [5:1] Size of region is 2N +1, where 11 ≤ N ≤ 31 E [0] Region enable, 1 = enable, 0 = disable The starting address for each region must be aligned on an address that is a multiple of its size. For example, if a region is 128 KB in size, it can start at any address multiple of 0x20000. The size of a region can be any power of two from 4 KB to 4 GB. The bit fields and the format of the eight secondary registers CP15:c6:c0 to CP15:c6:c7 are shown in Figure 13.3 and Table 13.3. The starting address is stored in the top bit field [31:20] and must be a multiple of the size bit field [5:1]. The E field bit [0] enables or disables the region; that is, a region can be defined and disabled so that its attributes are not enforced until the enable bit is set. The unused bits in the CP15:c6 secondary registers should be set to zero. To define the size of a region, you can use the formula, size = 2N +1 or look up the value in Table 13.4 . To set the size, place the exponent value N in the size bit field of the CP15:c6 register. The value of N is limited by the hardware design to be any integer between 11 and 31, representing 4 KB to 4 GB. The binary value provides the exact bit field for the size entry. Once you have determined the size of a region, the starting address of the region can be any integer value times the size calculated from the formula, or if you like, taken from Table 13.4. The region size and starting address are determined by the memory map of your system and the areas the control system must protect. The demonstration system at the end of this chapter shows how to set up regions given a system memory map. The ARM740T, ARM946E-S, and ARM1026EJ-S processors each have eight regions. To set the size and location of a region requires a write to a secondary register in CP15:c6:cX. For example, the instruction syntax needed to set the location and size of region 3 to start

468 Chapter 13 Memory Protection Units Table 13.4 Region size encoding. Size Decimal value Binary value 4 KB 11 01011 8 KB 12 01100 16 KB 13 01101 32 KB 14 01110 64 KB 15 01111 128 KB 16 10000 256 KB 17 10001 512 KB 18 10010 1 MB 19 10011 2 MB 20 10100 4 MB 21 10101 8 MB 22 10110 16 MB 23 10111 32 MB 24 11000 64 MB 25 11001 128 MB 26 11010 256 MB 27 11011 512 MB 28 11100 1 GB 29 11101 2 GB 30 11110 4 GB 31 11111 at 0x300000 with a size of 256 KB is MOV r1, #0x300000 ; set starting address ORR r1, r1, #0x11 << 1 ; set size to 256 KB MCR p15, 0, r1, c6, c3, 0 The core register r1 is filled with the required bit field data; then it is written to the CP15 secondary register using an MCR instruction. The ARM940T has eight instruction regions and eight data regions. The regions require an additional opcode2 modifier to select either the instruction or data region. Opcode2 is zero for data regions and one for instruction regions. For example, to read the size and location of data and instruction region 5 requires two MRC instructions, one for the instruction region and one for the data region. The instructions needed to read the size and starting location of the regions are MRC p15, 0, r2, c6, c5, 0 ; r2 = base/size Data Region 5 MRC p15, 0, r3, c6, c5, 1 ; r3 = base/size Inst Region 5

13.2 Initializing the MPU, Caches, and Write Buffer 469 The first instruction loads core register r2 with the size and starting address of data region 5, and the second instruction loads core register r3 with the size and starting address of instruction region 5. The ARM940T is the only processor core that has separate instruction and data regions. Example The following example code shows how to set the starting address, size of a region, and the 13.1 enable bit. The routine regionSet has the following C prototype: void regionSet(unsigned region, unsigned address, unsigned sizeN, unsigned enable); The routine has four unsigned integer inputs: the region to configure, the starting address of the region, the encoded sizeN of the region, and whether the region is enabled or disabled. It is a good idea to disable a region while changing its attributes and then reenabling it when the changes are complete. To make the routine work for all four available versions of an MPU processor, we unified the ARM940T region space by configuring the instruction and data regions with the size and starting address information. To do this, we wrote a macro called SET_REGION with two parts, one for the ARM940T and one for the other cores. This allows the same routine to support the four MPU cores. #if defined( __TARGET_CPU_ARM940T) #define SET_REGION(REGION) \\ /* set Data region base & size */ \\ __asm{MCR p15, 0, c6f, c6, c ## REGION, 0 } \\ /* set Instruction region base & size */ \\ __asm{MCR p15, 0, c6f, c6, c ## REGION, 1 } #endif #if defined(__TARGET_CPU_ARM946E_S) | \\ defined(__TARGET_CPU_ARM1026EJ_S) #define SET_REGION(REGION_NUMBER) \\ /* set region base & size */ \\ __asm{MCR p15, 0, c6f, c6, c ## REGION_NUMBER, 0 } #endif void regionSet(unsigned region, unsigned address, unsigned sizeN, unsigned enable) { unsigned int c6f; c6f = enable | (sizeN << 1) | address; switch (region)

470 Chapter 13 Memory Protection Units { case 0: { SET_REGION(0); break;} case 1: { SET_REGION(1); break;} } case 2: { SET_REGION(2); break;} } case 3: { SET_REGION(3); break;} case 4: { SET_REGION(4); break;} case 5: { SET_REGION(5); break;} case 6: { SET_REGION(6); break;} case 7: { SET_REGION(7); break;} default: { break; } The code starts by merging the region attributes of starting address, sizeN, and enable into an unsigned integer named c6f. The routine then branches to one of eight regionSet routines created using the macro SET_REGION, which sets the region’s starting address, size, and enable state by writing to CP15:c6 secondary register for the region defined. ■ 13.2.2 Access Permission There are two sets of access permission schemes available, a standard set and an extended set. All four cores support the standard set, which provides four levels of permission. The newer ARM946E-S and ARM1026EJ-S support an extended set, which adds an additional two levels of permission (see Table 13.5). The extended set AP (access permission) bit field encoding supports 12 additional permission values. Only two of these bits have been allocated to date. Using an undefined encoding results in unpredictable behavior. Table 13.5 CP15 register 5 access permissions. Supervisor User Standard AP value encoding Extended AP value encoding No access no access 00 0000 Read/write no access 01 0001 Read/write read only 10 0010 Read/write read/write 11 0011 Unpredictable unpredictable — 0100 Read only no access — 0101 Read only read only — 0110 Unpredictable unpredictable — 0111 Unpredictable unpredictable — 1000 to 1111

13.2 Initializing the MPU, Caches, and Write Buffer 471 Table 13.6 Bit field assignments for the standard and extended access permission registers CP15:c5. Standard AP Extended AP Region Field name Bit field Field name Bit field 0 AP0 [1:0] eAP0 [3:0] 1 AP1 [3:2] eAP1 [7:4] 2 AP2 [5:4] eAP2 [11:8] 3 AP3 [7:6] eAP3 [15:12] 4 AP4 [9:8] eAP4 [19:16] 5 AP5 [11:10] eAP5 [23:20] 6 AP6 [13:12] eAP6 [27:24] 7 AP7 [15:14] eAP7 [31:28] CP15:c5:c0 standard instruction region AP CP15:c5:c1 standard data region AP AP7 AP6 AP5 AP4 AP3 AP2 AP1 AP0 31 161514131211 10 9 8 7 6 5 4 3 2 1 0 CP15:c5:c2 extended instruction region AP CP15:c5:c3 extended data region AP eAP7 eAP6 eAP5 eAP4 eAP3 eAP2 eAP1 eAP0 31 28 27 24 23 20 19 16 15 1211 8 7 4 3 0 Figure 13.4 CP15 register 5 access permission register formats. To assign access permission to a region requires a write to a secondary register in CP15:c5. Secondary registers CP15:c5:c0:0 and CP15:c5:c0:1 configure standard AP, and secondary registers CP15:c5:c0:2 or CP15:c5:c0:3 configure extended AP. Table 13.6 and Figure 13.4 show the register’s permission bit assignments for the AP registers. Processors that support extended permission can also run software written for standard permission. The type of permission in effect depends on the last write to a CP15 AP register: If the last written AP register was a standard AP register, then the core is using standard permission; if the last written AP register was an extended AP register, then the core uses extended permission. This works because a write to the standard AP registers also updates the extended AP registers, meaning that the high bits [2:3] of the extended AP region entry are cleared.

472 Chapter 13 Memory Protection Units When using standard AP, each region has two bits in registers CP15:c5:c0:0 and CP15:c5:c0:1. CP15:c5:c0:0 sets the AP for data, and CP15:c5:c0:1 sets the instruction region. To read the standard AP for instruction and data memory requires reading two registers. The following two MRC instruction sequence places AP information for data region memory in core register r1 and AP information for instruction region in register r2: MRC p15, 0, r1, c5, c0, 0 ; Std AP Data Regions MRC p15, 0, r2, c5, c0, 1 ; Std AP Inst Regions When using extended AP, each region uses four bits in registers CP15:c5:c0:2 and CP15:c5:c0:3. The core stores instruction information for the eight regions in a single register and the data information in another register. CP15:c5:c0:2 sets the AP for the data region, and CP15:c5:c0:3 sets the AP for the instruction region. Obtaining the instruction and data region extended AP requires reading two registers. The following two-instruction sequence places region data AP in core register r3 and region instruction AP in register r4: MRC p15, 0, r3, c5, c0, 2 ; Extended AP Data Regions MRC p15, 0, r4, c5, c0, 3 ; Extended AP Inst Regions We supply two examples to demonstrate using access permissions, one for standard AP and the other for extended AP. These examples use the inline assembler to read and write to the CP15 registers. We provide two standard AP routines, regionSetISAP and regionSetDSAP, to set the standard AP bits for a region. They are called from C using the following function prototype: void regionSetISAP(unsigned region, unsigned ap); void regionSetDSAP(unsigned region, unsigned ap); The first parameter is the region number, and the second is the two-bit value defining the standard AP for the instruction or data memory controlled by the region. Example The two routines are identical with the exception that they read and write to different CP15:c5 secondary registers; one writes to the instruction register, and the other to the data 13.2 register. The routine does a simple read-modify-write operation on the CP15:c5 register to set the AP of the specified region, leaving the remaining regions intact. void regionSetISAP(unsigned region, unsigned ap) { unsigned c5f, shift; shift = 2*region; /* load standard D AP */ __asm{ MRC p15, 0, c5f, c5, c0, 1 }

13.2 Initializing the MPU, Caches, and Write Buffer 473 c5f = c5f &∼ (0x3 << shift); /* clear old AP bits */ c5f = c5f | (ap << shift); /* set new AP bits */ __asm{ MCR p15, 0, c5f, c5, c0, 1 } /* store standard D AP */ } void regionSetDSAP(unsigned region, unsigned ap) { unsigned c5f, shift; shift = 2*region; /* set bit field width */ __asm { MRC p15, 0, c5f, c5, c0, 0 } /* load standard I AP */ c5f = c5f &∼ (0x3 << shift); /* clear old AP bits */ c5f = c5f | (ap << shift); /* set new AP bits */ __asm { MCR p15, 0, c5f, c5, c0, 0 } /* store standard I AP */ } The routine sets the specified region permissions by clearing its AP bits using a shifted mask value and then setting the AP bit field with the ap input parameter. The AP bit field location is calculated as the region size times the number of bits in the permission bit field; this is the shift variable. The value of the bit field is set by shifting the ap value and using an OR to modify the c5f core register. ■ We provide two extended AP routines, regionSetIEAP and regionSetDEAP, to set the extended AP bits for a region. They have the following C function prototypes: void regionSetIEAP(unsigned region, unsigned ap); void regionSetDEAP(unsigned region, unsigned ap); The first parameter is the region number, and the second is the four-bit value representing the extended AP for the instruction or data memory controlled by the region. Example The two routines are identical to the standard AP routines with the exception that they 13.3 read and write to different CP15:c5 secondary registers and they have a four-bit-wide AP bit field. void regionSetIEAP(unsigned region, unsigned ap) { unsigned c5f, shift; shift = 4*region; /* set bit field width */ __asm{ MRC p15, 0, c5f, c5, c0, 3 } /* load extended D AP */ c5f = c5f &∼ (0xf shift); /* clear old AP bits */ c5f = c5f | (ap shift); /* set new AP bits */ __asm{ MCR p15, 0, c5f, c5, c0, 3 } /* store extended D AP */ }

474 Chapter 13 Memory Protection Units void regionSetDEAP(unsigned region, unsigned ap) { unsigned c5f, shift; shift = 4*region; /* set bit field width */ __asm{ MRC p15, 0, c5f, c5, c0, 2 } /* load extended I AP */ c5f = c5f &∼ (0xf << shift); /* clear old AP bits */ c5f = c5f | (ap << shift); /* set new AP bits */ __asm{ MCR p15, 0, c5f, c5, c0, 2 } /* store extended I AP */ } Each routine sets the specified region permissions by clearing its AP bits using a shifted mask value and then setting the AP bit field with the ap input parameter. The AP bit field location is calculated as the region size times the number of bits in the permission bit field; this is the shift variable. The value of the bit field is set by shifting the ap value and using an OR to modify the c5f core register. ■ 13.2.3 Setting Region Cache and Write Buffer Attributes Three CP15 registers control the cache and write buffer attributes for each core. Two registers, CP15:c2:c0:0 and CP15:c2:c0:1, hold the D-cache and I-cache region attributes. A third, CP15:c3:c0:0, holds the region write buffer attributes and applies to memory data regions. (Refer to Figure 13.5 and Table 13.7 for details.) Register CP15:c2:c0:1 contains the cache configuration data for all eight instruction regions, and register CP15:c2:c0:0 contains all eight data regions. Both registers use the same bit field encoding. The cache bit determines if the cache is enabled for a given address within the region. In the ARM740T and ARM940T, the cache is always searched, regardless of the state of the CP15:c2:c0:0—D-cache c7 c6 c5 c4 c3 c2 c1 c0 CP15:c2:c0:1—I-cache 76543210 SBZ 31 CP15:c3:c0:0—write buffer SBZ b7 b6 b5 b4 b3 b2 b1 b0 31 7 6 5 4 3 2 1 0 SBZ = “should be zero” Figure 13.5 CP15:c2 cache and CP15:c3 write buffer region registers.

13.2 Initializing the MPU, Caches, and Write Buffer 475 Table 13.7 Bit field assignments for CP15:c2 and CP15:c3 registers. Region cache fields Region write buffer fields Region Field name Bit fields Field name Bit fields 0 c0 [0] b0 [0] 1 c1 [1] b1 [1] 2 c2 [2] b2 [2] 3 c3 [3] b3 [3] 4 c4 [4] b4 [4] 5 c5 [5] b5 [5] 6 c6 [6] b6 [6] 7 c7 [7] b7 [7] cache bit. If the controller finds a valid cache entry, it will use the cached data over data in external memory. Because of this cache behavior, you need to flush and possibly clean the cache in a region where the cache policy changes from cached to noncached. Consequently, the MPU control system must always flush the cache when changing the cache policy from writethrough to noncached. It must always clean and flush the cache when changing the cache policy from writeback to noncached. It must also clean the cache when changing the cache policy from writeback to writethrough. See Chapter 12 for routines to clean and/or flush the cache. In the ARM946E-S, if the cache bit is clear, information physically in cache will not be returned from the cache, and an external memory access is performed instead. This design lightens the requirement to flush the cache when it is disabled. However, the cleaning rules for the old region still apply. The eight region write buffer bits in the register CP15:c3:c0:0 enable or disable the write buffer for each region (again see Figure 13.5). When configuring data regions, the region cache and write buffer bits together deter- mine the policy of the region. The write buffer bit has two uses; it enables or disables the write buffer for a region and sets the region cache write policy. The region cache bit controls the purpose of the write buffer bit. When the cache bit is zero, the buffer bit enables the write buffer when its value is one and disables the write buffer when its value is zero. When the cache bit is set to one, the cache and write buffer are both enabled and the buffer bit determines the cache write policy. The region uses a writethrough policy if the buffer bit is zero and a writeback policy if the buffer bit is set. Table 13.8 gives a tabular view of the various states of the cache and write buffer bits and their meanings. For more details on writeback and writethrough policies, see Section 12.3.1. We supply two routines to demonstrate enabling and disabling the caches and write buffer. The two routines use the inline assembler to read and write to the CP15 registers. We combine control of the cache and write buffer into a single routine call to simplify system configuration. We reference both the data cache and write buffer bits by the write

476 Chapter 13 Memory Protection Units Table 13.8 Control of the cache and write buffer. Instruction cache Data cache Cache bit Region Cache bit Buffer bit Region attribute CP15:c2:c0:1 attribute CP15:c2:c0:0 CP15:c3:c0:0 0 not cached 0 0 NCNB (not cached, not buffered) 1 cached 0 1 NCB (not cached, buffered) 1 0 WT (cached, writethrough) 1 1 WB (cached, writeback) policy they control, and the instruction cache bit stands alone. From a system view, merging the state of the caches and write buffer into a single value for each region makes it easier to group region information into a region control block (discussed in Section 13.3.3). The set cache and buffer routine, called regionSetCB, is shown in Example 13.4 and has the following C function prototype: void regionSetCB(unsigned region, unsigned CB); The routine has two input parameters. The first parameter, region, is the region number, and the second, CB, combines the region instruction cache attributes and the data cache and write buffer attributes. The second parameter has a format that uses the lower three bits of the unsigned integer: the instruction cache bit in bit [3], the data cache bit in bit [1], and the data buffer bit in bit [0]. Example The routine sequentially sets the data write buffer bit, the data cache bit, and the instruction 13.4 cache bit. To do this, for each bit it reads the CP15 register, clears the old bit value, sets the new bit value, and writes the value back into the CP15 register. void regionSetCB(unsigned region, unsigned CB) { unsigned c3f, tempCB; tempCB = CB; __asm{MRC p15, 0, c3f, c3, c0, 0 } /* load buffer register */ c3f = c3f &∼ (0x1 << region); /* clear old buffer bit */ c3f = c3f | ((tempCB & 0x1) << region); /* set new buffer bit */ __asm{MCR p15, 0, c3f, c3, c0, 0 } /* store buffer info */ tempCB = CB >> 0x1; /* shift to D-cache bit */ __asm{MRC p15, 0, c3f, c2, c0, 0 } /* load D-cache register */

13.2 Initializing the MPU, Caches, and Write Buffer 477 c3f = c3f &∼ (0x1 << region); /* clear old D-cache bit */ c3f = c3f | ((tempCB & 0x1) << region); /* set new D-cache bit */ __asm{MCR p15, 0, c3f, c2, c0, 0 } /* store D-cache info */ tempCB = CB >> 0x2; /* shift to I-cache bit */ __asm{MRC p15, 0, c3f, c2, c0, 1 } /* load I-cache register */ c3f = c3f &∼ (0x1 << region); /* clear old I-cache bit */ c3f = c3f | ((tempCB & 0x1) << region); /* set new I-cache bit */ __asm{MCR p15, 0, c3f, c2, c0, 1 } /* store I-cache info */ } ■ 13.2.4 Enabling Regions and the MPU There are two steps left in the initialization process. The first is to enable active regions, and the second is to turn on the protection unit hardware by enabling the MPU, caches, and write buffer. To enable a region, the control system can reuse the routine regionSet presented in Section 13.2.1. The multiple use of regionSet is shown in Example 13.6 at the end of the chapter. To enable the MPU, caches, and write buffer requires modifying bit values in CP15:c1:c0:0, the system control register. The location of the MPU, cache, and write buffer bits in CP15:c1:c0 are the same in the ARM940T, ARM946E-S, and ARM1026EJ-S processors, which makes enabling a configured MPU the same for the three cores. The enable bit locations are shown in Figure 13.6 and Table 13.9. The CP15:c1:c0 register has configuration bits not shown in Figure 13.6; the purpose and location of these bits are processor specific and are not a part of the protection system. We use the routine changeControl, shown in Example 13.5, to enable the MPU and caches. However, the routine changeControl can change any set of values in the CP15:c1:c0:0 register. It has the following C function prototype: void controlSet(unsigned value, unsigned mask); The first parameter passed is an unsigned integer containing the bit values to change. The second parameter is used to select the bits you want changed: A bit value of 1 changes the I CM 31 12 11 10 9 8 7 6 5 4 3 2 1 0 Figure 13.6 Memory protection unit control bits in the CP15:c1:c0 control register.

478 Chapter 13 Memory Protection Units Table 13.9 Protection unit enable bits in CP15 control register 1. Bit Function enabled Value 0 MPU 0 = disabled, 1 = enabled 2 data cache 0 = disabled, 1 = enabled 12 instruction cache 0 = disabled, 1 = enabled bit in the control register, and a 0 leaves the bit value unchanged, regardless of the bit state in the first parameter. For example, to enable the MPU and I-cache, and disable the D-cache, set bit [12] to 1, bit [2] to 0, and bit [0] to 1. The value of the first parameter should be 0x00001001; the remaining unchanged bits should be zero. To select only bit [12], bit [2], and bit [0] as the values to change, set the mask value to 0x00001005. Example This routine reads the control register and places the value in a holding register. Then it clears all the changing bits using the mask input and assigns them the desired state using 13.5 the value input. The routine completes by writing the new control values to the CP15:c1:c0 register. void controlSet(unsigned value, unsigned mask) { unsigned int c1f; __asm{ MRC p15, 0, c1f, c1, c0, 0 } /* read control register */ c1f = c1f &∼ mask; } /* mask off bit that change */ c1f = c1f | value; /* set bits that change */ __asm{ MCR p15, 0, c1f, c1, c0, 0 /* write control register */ } ■ 13.3 Demonstration of an MPU system We have provided a set of routines to use as building blocks to initialize and control a protected system. This section uses the routines described to initialize and control a simple protected system using a fixed memory map. Here is a demonstration that uses the examples presented in the previous sections of this chapter to create a functional protection system. It provides an infrastructure that enables the running of three tasks in a simple protected multi-tasking system. We believe it provides a suitable demonstration of the concepts underlying the ARM MPU hardware. It is written in C and uses standard access permission.

13.3 Demonstration of an MPU system 479 13.3.1 System Requirements The demonstration system has the following hardware characteristics: ■ An ARM core with an MPU ■ 256 KB of physical memory starting at 0x0 and ending at 0x40000 ■ Several memory-mapped peripherals spaced over several megabytes from 0x10000000 to 0x12000000 In this demonstration, all the memory-mapped peripherals are considered a single area of memory that needs protection (see Table 13.10). The demonstration system has the following software components: ■ The system software is less than 64 KB in size. It includes the vector table, exception handlers, and data stacks to support the exceptions. The system software must be inaccessible from user mode; that is, a user mode task must make a system call to run code or access data in this region. ■ There is shared software that is less than 64 KB in size. It contains commonly used libraries and data space for messaging between user tasks. ■ There are three user tasks that control independent functions in the system. These tasks are less than 32 KB in size. When these tasks are running, they must be protected from access by the other two tasks. The software is linked to place the software components within the regions assigned to them. Table 13.10 shows the software memory map for the example. The system software has system-level access permission. The shared software area is accessible by the entire system. The task software areas contain user-level tasks. Table 13.10 Memory map of example protection system. Function Access level Starting address Size Region Protect memory-mapped peripheral devices system 0x10000000 2 MB 4 Protected system system 0x00000000 4 GB 1 Shared system user 0x00010000 64 KB 2 User task 1 user 0x00020000 32 KB 3 User task 2 user 0x00028000 32 KB 3 User task 3 user 0x00030000 32 KB 3

480 Chapter 13 Memory Protection Units 0xFFFFFFFF Devices Region 4 User access 0x11000000 I/O Privileged access 0x10000000 0x00038000 Task 3 Region 3 Task 3 stack base Running task is 0x00030000 Task 2 Task 2 stack base assigned region 3 0x00028000 Task 1 Task 1 stack base 0x00020000 System Region 2 0x00010000 shared 0x00000000 System FIQ stack base protected IRQ stack base Supervisor stack base Region 1 Undef stack base Abort stack base Figure 13.7 Region assignment and memory map of demonstration protection system. 13.3.2 Assigning Regions Using a Memory Map The last column of Table 13.10 shows the four regions we assigned to the memory areas. The regions are defined using the starting address listed in the table and the size of the code and data blocks. A memory map showing the region layout is provided in Figure 13.7. Region 1 is a background region that covers the entire addressable memory space. It is a privileged region (i.e., no user mode access is permitted). The instruction cache is enabled, and the data cache operates with a writethrough policy. This region has the lowest region priority because it is the region with the lowest assigned number. The primary function of region 1 is to restrict access to the 64 KB space between 0x0 and 0x10000, the protected system area. Region 1 has two secondary functions: it acts as a background region and as a protection region for dormant user tasks. As a background region it ensures the entire memory space by default is assigned system-level access; this is done to prevent a user task from accessing spare or unused memory locations. As a user

13.3 Demonstration of an MPU system 481 task protection region, it protects dormant tasks from misconduct by the running task (see Figure 13.7). Region 2 controls access to shared system resources. It has a starting address of 0x10000 and is 64 KB in length. It maps directly over the shared memory space of the shared system code. Region 2 lies on top of a portion of protected region 1 and will take precedence over protected region 1 because it has a higher region number. Region 2 permits both user and system level memory access. Region 3 controls the memory area and attributes of a running task. When control transfers from one task to another, as during a context switch, the operating system redefines region 3 so that it overlays the memory area of the running task. When region 3 is relocated over the new task, it exposes the previous task to the attributes of region 1. The previous task becomes part of region 1, and the running task is a new region 3. The running task cannot access the previous task because it is protected by the attributes of region 1. Region 4 is the memory-mapped peripheral system space. The primary purpose of this region is to establish the area as not cached and not buffered. We don’t want input, output, or control registers subject to the stale data issues caused by caching, or the time or sequence issues involved when using buffered writes (see Chapter 12 for details on using I/O devices with caches and write buffers). 13.3.3 Initializing the MPU To organize the initialization process we created a datatype called Region; it is a structure whose members hold the attributes of a region used during system operation. This Region structure is not required when using the MPU; it is simply a design convenience created to support the demonstration software. For this demonstration, we call the set of these data structures a region control block (RCB). The initialization software uses the information stored in the RCB to configure the regions in the MPU. Note that there can be more Region structures defined in the RCB than physical regions. For example, region 3 is the only region used for tasks, yet there are three Region structures that use region 3, one for each user task. The typedef for the structure is typedef struct { unsigned int number; unsigned int type; unsigned int baseaddress; unsigned int size; unsigned int IAP; unsigned int DAP; unsigned int CB; } Region;

482 Chapter 13 Memory Protection Units There are eight values in the Region structure. The first two values describe character- istics of the Region itself: they are the MPU region number assigned to the Region, and the type of access permission used, either STANDARD or EXTENDED. The remaining four members of the structure are attributes of the specified region: the region starting address, baseaddress; region size, SIZE; access permissions, IAP and DAP; and cache and buffer configuration, CB. The six Region structures in the RCB are /* REGION NUMBER, APTYPE */ /* START ADDRESS, SIZE, IAP, DAP, CB */ Region peripheralRegion = {PERIPH, STANDARD, 0x10000000, SIZE_1M, RONA, RWNA, ccb}; Region kernelRegion = {KERNEL, STANDARD, 0x00000000, SIZE_4G, RONA, RWNA, CWT}; Region sharedRegion = {SHARED, STANDARD, 0x00010000, SIZE_64K, RORO, RWRW, CWT}; Region task1Region = {TASK, STANDARD, 0x00020000, SIZE_32K, RORO, RWRW, CWT}; Region task2Region = {TASK, STANDARD, 0x00028000, SIZE_32K, RORO, RWRW, CWT}; Region task3Region = {TASK, STANDARD, 0x00030000, SIZE_32K, RORO, RWRW, CWT}; We created a set of macros to make entries in the RCB more humanly readable; they are shown in Figure 13.8. Most notably, we enter access permission to data and instruction memory using a simple combination of four letters. The first two letters represent system access permission, and the second two letters represent user access. The two letters for system and user access can be read/write (RW), read-only (RO), or no access (NA). We also mapped the cache and buffer information to an instruction cache and a data cache policy attribute. The first letter is C or c and enables or disables the instruction cache for the region. The last two letters determine the data cache policy and write buffer control. The values can be WT for writethrough or WB for writeback. The letters c and b are also supported and are manual configurations of the cache and buffer bits. Cb is an alias of WT, and CB is an alias of WB. cB means not cached and buffered, and finally cb means not cached and not buffered. 13.3.4 Initializing and Configuring a Region Next we provide the routine configRegion, which takes a single Region structure entry in the RCB to populate the CP15 registers with data describing the region. The routine follows the initialization steps listed in Section 13.3.3. The input to the routine is a pointer to the RCB of a region. Within the routine, members of the Region are

13.3 Demonstration of an MPU system 483 /* Region Number Assignment */ #define BACKGROUND 0 #define KERNEL 1 #define TASK 2 #define SHARED 3 #define PERIPH 4 /* Region Type Assignment */ #define STANDARD 0 #define EXTENDED 1 #define DISABLE 0 /* Access Permissions */ #define NANA 0 #define RWNA 1 #define RWRO 2 #define RWRW 3 #define RONA 5 #define RORO 6 /* Region Size */ #define SIZE_4G 31 #define SIZE_2G 30 #define SIZE_1G 29 #define SIZE_512M 28 #define SIZE_256M 27 #define SIZE_128M 26 #define SIZE_64M 25 #define SIZE_32M 24 #define SIZE_16M 23 #define SIZE_8M 22 #define SIZE_4M 21 #define SIZE_2M 20 #define SIZE_1M 19 #define SIZE_512K 18 #define SIZE_256K 17 #define SIZE_128K 16 #define SIZE_64K 15 #define SIZE_32K 14 Figure 13.8 Defined macros used in the demonstration example.

484 Chapter 13 Memory Protection Units #define SIZE_16K 13 #define SIZE_8K 12 #define SIZE_4K 11 /* CB = ICache[2], DCache[1], Write Buffer[0] */ /* ICache[2], WB[1:0] = writeback, WT[1:0] = writethrough */ #define CCB 7 #define CWB 7 #define CCb 6 #define CWT 6 #define CcB 5 #define Ccb 4 #define cCB 3 #define cWB 3 #define cCb 2 #define cWT 2 #define ccB 1 #define ccb 0 /* Region enable */ #define R_ENABLE 1 #define R_DISABLE 0 Figure 13.8 Defined macros used in the demonstration example. (Continued.) used as data inputs in the initialization process. The routine has the following C function prototype: void configRegion(Region *region); Example This example initializes the MPU, caches, and write buffer for the protected system. The routines presented earlier in this chapter are used in the initialization process. We imple- 13.6 ment the steps first listed in Section 13.2 to initialize the MPU, caches, and write buffer. The steps are labeled as comments in the example code. Executing this example initializes the MPU. void configRegion(Region *region) { /* Step 1 - Define the size and location of the instruction */ /* and data regions using CP15:c6 */


Like this book? You can publish your book online for free in a few minutes!
Create your own flipbook