What Two Registers Can Be Used To Provide A Simple Form Of Memory Protection?
Joseph Yiu , in The Definitive Guide to the ARM Cortex-M3 (Second Edition), 2010
13.iii Setting Up the MPU
The MPU register might look complicated, merely as long as you have a clear thought of the retentivity regions that are required for your application, it should not exist hard. Typically, y'all demand to take the following retentiveness regions:
- •
-
Programme lawmaking for privileged programs (for example, Bone kernel and exception handlers)
- •
-
Program code for user programs
- •
-
Data retention for privileged and user programs in various retentiveness regions (e.one thousand., information and stack of the application situated in the SRAM (Static Random Admission Memory) retentivity region--0x20000000 to 0x3FFFFFFF)
- •
-
Other peripherals
Information technology is not necessary to set up a region for the memory in the private peripheral bus range. The MPU automatically recognizes the private peripheral jitney retentivity addresses and allows privileged software to perform data accesses in this region.
For Cortex-M3 products, almost memory regions tin exist set up with TEX = b000, C = 1, B = 1. System devices such as the Nested Vectored Interrupt Controller (NVIC) should be strongly ordered, and peripheral regions tin can be programmed as shared devices (TEX = b000, C = 0, B = 1). However, if you lot desire to brand certain that whatsoever bus faults occurring in the region are precise charabanc faults, yous should use a strongly ordered memory aspect (TEX = b000, C = 0, B = 0) so that write buffering is disabled. However, doing then can reduce system performance.
For users of a Cortex Microcontroller Software Interface Standard (CMSIS) compliant device driver, the MPU registers can be accessed using the post-obit register names as shown in Table xiii.x. A simple flow for an MPU setup routine is shown in Figure thirteen.3 on page 220.
Table 13.10. MPU Register Names in CMSIS
| Register Names | MPU Register | Address |
|---|---|---|
| MPU->Type | MPU Blazon annals | 0xE000ED90 |
| MPU->CTRL | MPU Control register | 0xE000ED94 |
| MPU->RNR | MPU Region Number register | 0xE000ED98 |
| MPU->RBAR | MPU Region Base Accost register | 0xE000ED9C |
| MPU->RASR | MPU Region Attribute and Size annals | 0xE000EDA0 |
| MPU->RBAR_A1 | MPU Allonym 1 Region Base of operations Address register | 0xE000EDA4 |
| MPU->RBAR_A2 | MPU Alias two Region Base Address register | 0xE000EDAC |
| MPU->RBAR_A3 | MPU Alias 3 Region Base Address register | 0xE000EDB4 |
| MPU->RASR_A1 | MPU Alias ane Region Aspect and Size register | 0xE000EDA8 |
| MPU->RASR_A2 | MPU Alias ii Region Attribute and Size annals | 0xE000EDB0 |
| MPU->RASR_A3 | MPU Allonym 3 Region Attribute and Size register | 0xE000EDB8 |
FIGURE 13.3. Instance Steps to Set Up the MPU.
Before the MPU is enabled and if the vector table is relocated to RAM, remember to set up the error handler for the memory management mistake in the vector table, and enable the retentiveness management fault in the Organisation Handler Control and State register. They are needed to permit the retentivity management fault handler to exist executed if an MPU violation takes place.
For a simple instance of only four required regions, the MPU setup lawmaking (without the region checking and enabling) looks like this:
MPU->RNR = 0; // MPU Region Number Annals
// select region 0
MPU->RBAR = 0x00000000; // MPU Region Base of operations Accost Register
// Base Address = 0x00000000
MPU->RASR = 0x0307002F; // Region Attribute and Size Annals
// R/W, TEX=0,Southward=1,C=1,B=1, 16MB, Enable=1
MPU->RNR = 1; // select region one
MPU->RBAR = 0x20000000; // Base Address = 0x20000000
MPU->RASR = 0x03070033; // R/W, TEX=0,Southward=1,C=1,B=1, 64MB, Enable=1
MPU->RNR = 2; // select region 2
MPU->RBAR = 0x40000000; // Base Address = 0x40000000
MPU->RASR = 0x03050033; // R/W, TEX=0,S=ane,C=0,B=1, 64MB, Enable=1
MPU->RNR = 3; // select region three
MPU->RBAR = 0xA0000000; // Base Address = 0xA0000000
MPU->RASR = 0x01040027; // Privileged R/West, TEX=0,S=1,C=0,B=0,
// 1MB, Enable=1
MPU->CTRL = ane; // MPU Control annals – Enable MPU
This can also be coded in associates language:
LDR R0,=0xE000ED98 ; Region number register
MOV R1,#0 ; Select region 0
STR R1, [R0]
LDR R1,=0x00000000 ; Base Address = 0x00000000
STR R1, [R0, #4] ; MPU Region Base Address Register
LDR R1,=0x0307002F ; R/Westward, TEX=0,Due south=ane,C=ane,B=1, 16MB, Enable=1
STR R1, [R0, #8] ; MPU Region Aspect and Size Register
MOV R1,#1 ; Select region 1
STR R1, [R0]
LDR R1,=0x20000000 ; Base Address = 0x20000000
STR R1, [R0, #iv] ; MPU Region Base Address Register
LDR R1,=0x03070033 ; R/West, TEX=0,Due south=1,C=1,B=ane, 64MB, Enable=1
STR R1, [R0, #8] ; MPU Region Attribute and Size Register
MOV R1,#two ; Select region 2
STR R1, [R0]
LDR R1,=0x40000000 ; Base Accost = 0x40000000
STR R1, [R0, #4] ; MPU Region Base of operations Address Register
LDR R1,=0x03050033 ; R/W, TEX=0,S=1,C=0,B=1, 64MB, Enable=1
STR R1, [R0, #8] ; MPU Region Aspect and Size Register
MOV R1,#3 ; Select region 3
STR R1, [R0]
LDR R1,=0xA0000000 ; Base Address = 0xA0000000
STR R1, [R0, #4] ; MPU Region Base Address Annals
LDR R1,=0x01040027 ; Privileged R/W, TEX=0,Southward=1,C=0,B=0, 1MB,
; Enable=1
STR R1, [R0, #8] ; MPU Region Attribute and Size Register
MOV R1,#1 ; Enable MPU
STR R1, [R0,#-4] ; MPU Command annals
; (0xE000ED98-four=0xE000ED94)
This provides four regions:
- •
-
Code: 0x00000000–0x00FFFFFF (16 MB), total admission, cacheable
- •
-
Information: 0x20000000–0x02003FFFF (64 MB), full admission, cacheable
- •
-
Peripheral: 0x40000000–0x5FFFFFFF (64 MB), full admission, shared device
- •
-
External device: 0xA0000000–0xA00FFFFF (1 MB), privileged access, strongly ordered, XN
By combining region selection and writing to the base accost annals, we tin shorten the lawmaking to this:
MPU->RBAR = 0x00000010; // MPU Region Base of operations Accost Register
// Base of operations Accost = 0x00000000, valid, region 0
MPU->RASR = 0x0307002F; // Region Attribute and Size Register
// R/W, TEX=0,Southward=ane,C=1,B=one, 16MB, Enable=1
MPU->RBAR = 0x20000011; // Base Address = 0x20000000, valid, region ane
MPU->RASR = 0x03070033; // R/West, TEX=0,S=i,C=1,B=one, 64MB, Enable=one
MPU->RBAR = 0x40000012; // Base Address = 0x40000000, valid, region 2
MPU->RASR = 0x03050033; // R/West, TEX=0,S=1,C=0,B=1, 64MB, Enable=1
MPU->RBAR = 0xA0000013; // Base of operations Address = 0xA0000000, valid, region 3
MPU->RASR = 0x01040027; // Privileged R/West, TEX=0,Due south=i,C=0,B=0,
// 1MB, Enable=1
MPU->CTRL = one; // MPU Command annals – Enable MPU
Or, in assembly:
LDR R0,=0xE000ED9C ; Region Base of operations Address annals
LDR R1,=0x00000010 ; Base of operations Address = 0x00000000, region 0,
; valid=i
STR R1, [R0, #0] ; MPU Region Base Address Register
LDR R1,=0x0307002F ; R/W, TEX=0,S=1,C=1,B=1, 16MB, Enable=one
STR R1, [R0, #iv] ; MPU Region Attribute and Size Register
LDR R1,=0x20000011 ; Base of operations Accost = 0x20000000, region 1,
; valid=1
STR R1, [R0, #0] ; MPU Region Base Address Register
LDR R1,=0x03070033 ; R/W, TEX=0,Due south=1,C=ane,B=i, 64MB, Enable=1
STR R1, [R0, #4] ; MPU Region Attribute and Size Annals
LDR R1,=0x40000012 ; Base Address = 0x40000000, region 2,
; valid=1
STR R1, [R0, #0] ; MPU Region Base of operations Address Register
LDR R1,=0x03050033 ; R/West, TEX=0,S=1,C=0,B=one, 64MB, Enable=one
STR R1, [R0, #4] ; MPU Region Attribute and Size Register
LDR R1,=0xA0000013 ; Base Address = 0xA0000000, region 3,
; valid=one
STR R1, [R0, #0] ; MPU Region Base of operations Address Register
LDR R1,=0x01040027 ; R/W, TEX=0,Due south=ane,C=0,B=0, 1MB, Enable=1
STR R1, [R0, #4] ; MPU Region Aspect and Size Register
MOV R1,#ane ; Enable MPU
STR R1, [R0,#-eight] ; MPU Control register
; (0xE000ED9C-8=0xE000ED94)
We've shortened the lawmaking quite a bit. Even so, you can make further enhancements to create even faster setup code. This is done using MPU aliased annals addresses (see Table D.34 in Appendix D). The aliased register addresses follow the MPU Region Attribute and Size registers and are aliased to the MPU Base Accost register and the MPU Region Aspect and Size register. They produce a continuous address of eight words, making it possible to use Load/Store Multiple (LDM and STM) instructions:
LDR R0,=0xE000ED9C ; Region Base Address register
LDR R1,=MPUconfig ; Table of predefined MPU setup variables
LDMIA R1!, {R2, R3, R4, R5} ; Read 4 words from table
STMIA R0!, {R2, R3, R4, R5} ; write 4 words to MPU
LDMIA R1!, {R2, R3, R4, R5} ; Read adjacent 4 words from tabular array
STMIA R0!, {R2, R3, R4, R5} ; write next 4 words to MPU
B MPUconfigEnd
Align 4 ; This is needed to brand sure the following table
; is give-and-take aligned
MPUconfig ; and then that we can utilize load multiple teaching
DCD 0x00000010 ; Base Accost = 0x00000000, region 0,
; valid=i
DCD 0x0307002F ; R/Due west, TEX=0,S=ane,C=1,B=1, 16MB, Enable=i
DCD 0x20000011 ; Base Address = 0x08000000, region 1,
; valid=i
DCD 0x03070033 ; R/W, TEX=0,S=1,C=ane,B=i, 64MB, Enable=1
DCD 0x40000012 ; Base Address = 0x40000000, region 2,
; valid=1
DCD 0x03050033 ; R/West, TEX=0,Due south=1,C=0,B=i, 64MB, Enable=i
DCD 0xA0000013 ; Base Address = 0xA0000000, region 3,
; valid=i
DCD 0x01040027 ; R/West, TEX=0,S=one,C=0,B=0, 1MB, Enable=ane
MPUconfigEnd
LDR R0,=0xE000ED94; MPU Control register
MOV R1,#1 ; Enable MPU
STR R1, [R0]
This solution, of course, tin be used merely if all the required information is known beforehand. Otherwise, a more generic approach has to be used. One way to handle this is to use a subroutine (MpuRegionSetup) that can ready up a region based on a number of input parameters and and then call it several times to gear up different regions:
void MpuRegionSetup(unsigned int addr, unsigned int region,
unsigned int size, unsigned int ap, unsigned int MemAttrib,
unsigned int srd, unsigned int XN, unsigned int enable)
{ // Setup procedure for each region
MPU->RBAR = (addr & 0xFFFFFFE0) | (region & 0xF) | 0x10;
MPU->RASR = ((XN & 0x1)<<28) | ((ap & 0x7)<<24) |
((MemAttrib & 0x3F)<<16) | ((srd&0xFF)<<8) |
((size & 0x1F)<<1)| (enable & 0x1);
return;
}
void MpuRegionDisable(unsigned int region)
{ // Role to disable an unused region
MPU->RBAR = (region & 0xF) | 0x10;
MPU->RASR = 0; // disable
return;
}
void MpuSetup(void)
{ // Setup the whole MPU
MPU->CTRL = 0; // Disable MPU first
MpuRegionSetup(0x00000000, 0, 0x17, 3, vii, 0, 0, 1); // Region 0,16M
MpuRegionSetup(0x20000000, 1, 0x19, 3, seven, 0, 0, i); // Region 1,64M
MpuRegionSetup(0x40000000, two, 0x19, iii, five, 0, 0, 1); // Region 2,64M
MpuRegionSetup(0xA0000000, three, 0x13, 1, 4, 0, 0, one); // Region 3, 1M
MpuRegionDisable(iv); // Disable unused region four
MpuRegionDisable(5); // Disable unused region v
MpuRegionDisable(6); // Disable unused region 6
MpuRegionDisable(7); // Disable unused region 7
MPU->CTRL = 1; // Enable MPU
render;
}
In this instance, nosotros included a subroutine that is used to disable a region that is not used. This is necessary if you lot do not know whether a region has been programmed previously. If an unused region is previously programmed to be enabled, it needs to be disabled then that information technology doesn't affect the new configuration.
The MPU setup routines can be rewritten in assembly equally
MpuSetup ; A subroutine to setup the MPU by calling subroutines that
; setup regions
Button {R0-R6,LR}
LDR R0,=0xE000ED94 ; MPU Control Annals
MOV R1,#0
STR R1,[R0] ; Disable MPU
; --- Region #0 ---
LDR R0,=0x00000000 ; Region 0: Base Address = 0x00000000
MOV R1,#0x0 ; Region 0: Region number = 0
MOV R2,#0x17 ; Region 0: Size = 0x17 (16MB)
MOV R3,#0x3 ; Region 0: AP = 0x3 (full access)
MOV R4,#0x7 ; Region 0: MemAttrib = 0x7
MOV R5,#0x0 ; Region 0: Sub R disable = 0
MOV R6,#0x1 ; Region 0: {XN, Enable} = 0,ane
BL MpuRegionSetup
; --- Region #1 ---
LDR R0,=0x20000000 ; Region one: Base Accost = 0x20000000
MOV R1,#0x1 ; Region 1: Region number = 1
MOV R2,#0x19 ; Region 1: Size = 0x19 (64MB)
MOV R3,#0x3 ; Region i: AP = 0x3 (total
admission)
MOV R4,#0x7 ; Region 1: MemAttrib = 0x7
MOV R5,#0x0 ; Region one: Sub R disable = 0
MOV R6,#0x1 ; Region one: {XN, Enable} = 0,ane
BL MpuRegionSetup
... ; setup for region #2 and #three
; --- Region #4-#vii Disable ---
MOV R0,#4
BL MpuRegionDisable
MOV R0,#5
BL MpuRegionDisable
MOV R0,#6
BL MpuRegionDisable
MOV R0,#7
BL MpuRegionDisable
LDR R0,=0xE000ED94 ; MPU Control Register
MOV R1,#one
STR R1,[R0] ; Enable MPU
Pop {R0-R6,PC} ; Return
MpuRegionSetup
; MPU region setup subroutine
; Input R0 : Base of operations Address
; R1 : Region number
; R2 : Size
; R3 : AP (access permission)
; R4 : MemAttrib ({TEX[2:0], S, C, B})
; R5 : Sub region disable
; R6 : {XN,Enable}
PUSH {R0-R1, LR}
BIC R0, R0, #0x1F ; Articulate unused bits in accost
BFI R0, R1, #0, #4 ; Insert region number to R0[3:0]
ORR R0, R0, #0x10 ; Prepare valid chip
LDR R1,=0xE000ED9C ; MPU Region Base Accost Annals
STR R0,[R1] ; Gear up base address reg
AND R0, R6, #0x01 ; Get Enable chip
UBFX R1, R6, #1, #ane ; Get XN flake
BFI R0, R1, #28, #1 ; Insert XN to R0[28]
BFI R0, R2, #i , #v ; Insert Region Size field (R2[4:0]) to
; R0[five:1]
BFI R0, R3, #24, #iii ; Insert AP fields (R3[2:0]) to R0[26:24]
BFI R0, R4, #16, #vi ; Insert memattrib field (R4[5:0]) to
; R0[21:16]
BFI R0, R5, #8, #8 ; Insert subregion disable (SRD) fields
; to R0[fifteen:8]
LDR R1,=0xE000EDA0 ; MPU Region Base Size and Attribute
; Annals
STR R0,[R1] ; Fix base attribute and size reg
POP {R0-R1, PC} ; Return
MpuRegionDisable
; Subroutine to disable unused region
; Input R0 : Region number
Button {R1, LR}
AND R0, R0, #0xF ; Clear unused bits in Region Number
ORR R0, R0, #0x10 ; Fix valid bit
LDR R1,=0xE000ED9C ; MPU Region Base of operations Address Annals
STR R0,[R1]
MOV R0, #0
LDR R1,=0xE000EDA0 ; MPU Region Base of operations Size and Attribute
; Register
STR R0,[R1] ; Set up base attribute and size reg to 0
; (disabled)
POP {R1, PC} ; Return
The example shows the application of the Bit Field Insert (BFI) pedagogy in the Cortex-M3. This tin can greatly simplify bit-field merging operations.
Source: https://www.sciencedirect.com/topics/computer-science/memory-protection
Posted by: simsarries.blogspot.com

0 Response to "What Two Registers Can Be Used To Provide A Simple Form Of Memory Protection?"
Post a Comment