当前位置:网站首页>Armv8m (cortex M33) MPU actual combat
Armv8m (cortex M33) MPU actual combat
2022-04-23 13:08:00 【MyeDy】
List of articles
1 MPU
armv8m Upper MPU Yes 8 individual region, every last region All have starting addresses , End address , Access rights and memory properties . every last region Have separate properties .
This article only uses secure MPU As an example to explain MPU.
armv8m Upper MPU and armv7m Of MPU It's a little different , v8m Of MPU I won't support it overlap, If an address appears in two different places at the same time region in , It can lead to bus fault.
1.1 Memory attributes summary
Memory Type | Shareability | Other attributes | Description |
---|---|---|---|
Device-nGnRnE | Sharable | - | Used to access memory mapped peripherals.All accesses to DevicenGnRnE memory occur in program order. All regions are assumed to be shared |
Device-nGnRE | Sharable | - | Used to access memory mapped peripherals.Weaker ordering thanDevice-nGnRnE. |
Device-nGRE | Sharable | - | Used to access memory mapped peripherals.Weaker ordering thanDevice-nGnRE. |
Device-GRE | Sharable | - | Used to access memory mapped peripherals.Weaker ordering thanDevice-nGRE. |
Normal | Sharable | Non-cacheable Write-Through Cacheable Write-Back Cacheable | Normal memory that is shared between several processors. |
Normal | Non-Shareable | Non-cacheable Write-Through Cacheable Write-Back Cacheable | Normal memory that only a single processor uses. |
1.2 MPU register
Address | Name | Access Type | Reset Value |
---|---|---|---|
0xE000ED90 | MPU_TYPE | RO | The value of this register is fixed , Depending on SOC Realization |
0xE000ED94 | MPU_CTRL | RW | 0x00000000 |
0xE000ED98 | MPU_RNR | RW | Unknown |
0xE000ED9C | MPU_RBAR | RW | Unknown |
0xE000EDA0 | MPU_RLAR | RW | Unknown |
0xE000EDA4 | MPU_RBAR_A<n> | RW | Unknown |
0xE000EDA8 | MPU_RBAR_A<n> | RW | Unknown |
0xE000EDC0 | MPU_MAIR0 | RW | Unknown |
0xE000EDC4 | MPU_MAIR1 | RW | Unknown |
1.2.1 MPU Type Register
MPU_TYPE Registers are used to represent MPU Whether it exists and how many it supports region.
Bits | Name | Function |
---|---|---|
[31:16] | - | Keep a |
[15:8] | REGION | 0x0-MPU No, region Support 0x8 At present MPU Support 8 individual REGION |
[7:1] | - | Keep a |
[0] | SEPARATE | 0 |
1.2.2 MPU Control Register
MPU_CTRL be used for
- Can make MPU
- Can make backgroup map
- Can make NMI in MPU Whether it works
Bits | Name | Function |
---|---|---|
[31:3] | - | Keep a |
[2] | PRIVDEFENA | Enable the use of software privileges default memory map 0 - close default memory map. Any access is not in region Everything described in will produce bus fault. 1 - Can make default memory map, When it is enabled , The visit is not in region in memory Will use the default memory map |
[1] | HFNMIENA | send HardFault and NMI Time can MPU stay 0 - stay HardFault and NMI when , MPU Invalid 1 - stay HardFault and NMI when , MPU Still valid |
[0] | ENABLE | Can make MPU 0 - close MPU 1 - open MPU |
1.2.3 MPU Region Number Register
MPU_RNR Used for selection region, During a visit to MPU_RBAR and MPU_RLAR Before , You have to write MPU_RNR Choose region
Bits | Name | Function |
---|---|---|
[31:8] | - | Keep a |
[7:0]REGION | REGION Indexes , If you choose REGION1, Set to 1 |
1.2.4 MPU Region Base Address Register
MPU_RBAR Defined MPU region From
Bits | Name | Function |
---|---|---|
[31:5] | BASE | REGION Base address |
[4:3] | SH | Defined Normal Of Shareability attribute 0b00 Non-shareable. 0b01 UNPREDICATABLE 0b10 Outer shareable. 0b11 Inner shareable |
[2:1] | AP | Access properties 0b00 Privilege level code is readable and writable . 0b01 Privilege level code is readable and writable 0b10 Privilege level code is read-only . 0b11 All code is read-only |
[0] | XN | 0 Executable Memory 1 Unenforceable Memory |
1.2.5 MPU Region Limit Address Register
MPU_RLAR Defined REGION The upper limit address and REGION Attribute selection
Bits | Name | Function |
---|---|---|
[31:5] | LIMIT | REGION Upper limit address |
[4] | - | Keep a |
[3:1] | AttrIndx | Attribute index number |
[0] | EN | 0 Do not enable REGION 1 Can make REGION |
1.2.6 MPU Memory Attribute Indirection Registers 0 and 1
MPU_MAIR0
Bits | Name | Function |
---|---|---|
[31:24] | Attr3 | REGION3 attribute |
[23:16] | Attr2 | REGION2 attribute |
[15:8] | Attr1 | REGION1 attribute |
[7:0] | Attr0 | REGION0 attribute |
MPU_MAIR1
Bits | Name | Function |
---|---|---|
[31:24] | Attr7 | REGION7 attribute |
[23:16] | Attr6 | REGION6 attribute |
[15:8] | Attr5 | REGION5 attribute |
[7:0] | Attr4 | REGION4 attribute |
every last REGION attribute MARI_ATTR Occupy 8 position , If MAIR_ATTR[7:4] by 0: that MAIR_ATTR The definition is as follows :
Bits | Name | Function |
---|---|---|
[3:2] | Device | 0b00 Device-nGnRnE 0b01 Device-nGnRE 0b10 Device-nGRE 0b11 Device-GRE |
If MAIR_ATTR[7:4] Not for 0, that MAIR_ATTR The definition is as follows
Bits | Name | Function |
---|---|---|
[7:4] | Outer | Outer attributes. Specifies the Outer memory attributes. The possible values of this field are: 0b0000 -Device memory. 00RW -Normal memory, Outer write-through transient (RW is not 00). 0b0100 -Normal memory, Outer non-cacheable. 01RW-Normal memory, Outer write-back transient (RW is not 00).10RW Normal memory, Outer write-through non-transient. 11RW -Normal memory, Outer write-back non-transient. R and W specify the outer read and write allocation policy: 0 = do not allocate, 1 = allocate. |
[3:0] | Inner | Inner attributes. Specifies the Inner memory attributes. The possible values of this field are: 0b0000 -UNPREDICTABLE. 00RW- Normal memory, Inner write-through transient (RW is not 00). 0b0100- Normal memory, Inner non-cacheable. 01RW -Normal memory, Inner write-back transient (RW is not 00). 10RW -Normal memory, Inner write-through non-transient. 11RW -Normal memory, Inner write-back non-transient. R and W specify the outer read and write allocation policy: 0 = do not allocate, 1 = allocate. |
2 MPU Code
2.1 Environment building
Code git
MPS2 Development board manual
install qemu-system-arm, Make sure there are... Under this version cortex m33 Simulation board of
mps2-an385 ARM MPS2 with AN385 FPGA image for Cortex-M3
mps2-an505 ARM MPS2 with AN505 FPGA image for Cortex-M33
mps2-an511 ARM MPS2 with AN511 DesignStart FPGA image for Cortex-M3
mps2-an521 ARM MPS2 with AN521 FPGA image for dual Cortex-M33
Install the toolchain armv8l-linux-gnueabihf-
Run the command :
make;make qemu
log:
qemu-system-arm -machine mps2-an505 -cpu cortex-m33 \
-m 4096 \
-nographic \
-kernel kernel.elf
qemu-system-arm: invalid accelerator kvm
qemu-system-arm: falling back to tcg
hello cortex m33
test_func_print entry
test_armv8m_xn:mpu setup done
default_exception_handler entry
2.2 MPU Source code
2.2.1 armv8m_mpu.h
#ifndef _ARMV8M_MPU_H_
#define _ARMV8M_MPU_H_
#include <stdint.h>
#include <stdbool.h>
typedef struct armv8m_mpu_tag {
volatile uint32_t mpu_type;
volatile uint32_t mpu_ctrl;
volatile uint32_t mpu_rnr;
volatile uint32_t mpu_rbar;
volatile uint32_t mpu_rlar;
volatile uint32_t reserved[7];
volatile uint32_t mpu_mair0;
volatile uint32_t mpu_mair1;
} armv8m_mpu_t;
#define MPU_CTRL_ENABLE_SHITF 0UL
#define MPU_CTRL_ENABLE_MASK (1UL << MPU_CTRL_ENABLE_SHITF)
#define MPU_CTRL_HFNMIENA_SHIFT 1UL
#define MPU_CTRL_HFNMIENA_MASK (1UL << MPU_CTRL_HFNMIENA_SHIFT)
#define MPU_CTRL_PRIVDEFENA_SHIFT 2UL
#define MPU_CTRL_PRIVDEFENA_MASK (1UL << MPU_CTRL_PRIVDEFENA_SHIFT)
#define MPU_RNR_REGION_SHIFT 0UL
#define MPU_RNR_REGION_MASK (0xFFUL << MPU_RNR_REGION_SHIFT)
#define MPU_CTRL_RBAR_BASE_SHIFT 0x5UL
#define MPU_CTRL_RBAR_BASE_MASK 0xFFFFFFE0UL
#define MPU_CTRL_RBAR_SH_SHIFT 3UL
#define MPU_CTRL_RBAR_SH_MASK (0x3UL << MPU_CTRL_RBAR_SH_SHIFT)
#define MPU_CTRL_RBAR_AP_SHIFT 1UL
#define MPU_CTRL_RBAR_AP_MASK (0x3UL << MPU_CTRL_RBAR_AP_SHIFT)
#define MPU_CTRL_RBAR_XN_SHIFT 0UL
#define MPU_CTRL_RBAR_XN_MASK (1UL << MPU_CTRL_RBAR_XN_SHIFT)
#define MPU_CTRL_RLAR_LIMIT_SHIFT 5UL
#define MPU_CTRL_RLAR_LIMIT_MASK 0xFFFFFFE0UL
#define MPU_CTRL_RLAR_ATTRIDX_SHIFT 1UL
#define MPU_CTRL_RLAR_ATTRIDX_MASK (0x7UL << MPU_CTRL_RLAR_ATTRIDX_SHIFT)
#define MPU_CTRL_RLAR_EN_SHIFT 0UL
#define MPU_CTRL_RLAR_EN_MASK (1UL << MPU_CTRL_RLAR_EN_SHIFT)
#define REGION_NON_SHAREABLE 0
#define REGION_UNPREDICTABLE 1
#define REGION_OUTER_SHAREABLE 2
#define REGION_INNER_SHAREABLE 3
#define REGION_RW_PRIV_ONLY 0
#define REGION_RW_ANY 1
#define REGION_RO_PRIV_ONLY 2
#define REGION_RO_ANY 3
#define REGION_X 0
#define REGION_XN 1
#define REGION_DISABLE 0
#define REGION_EN 1
static inline void mpu_disable(armv8m_mpu_t *mpu)
{
mpu->mpu_ctrl &= ~MPU_CTRL_ENABLE_MASK;
__asm("dsb");
__asm("isb");
}
static inline void mpu_enable(armv8m_mpu_t *mpu)
{
mpu->mpu_ctrl |= MPU_CTRL_ENABLE_MASK;
__asm("dsb");
__asm("isb");
}
static inline void mpu_hfnmiena_enable(armv8m_mpu_t *mpu)
{
mpu->mpu_ctrl |= MPU_CTRL_HFNMIENA_MASK;
}
static inline void mpu_hfnmiena_disable(armv8m_mpu_t *mpu)
{
mpu->mpu_ctrl &= ~MPU_CTRL_HFNMIENA_MASK;
}
static inline void mpu_privdefena_enable(armv8m_mpu_t *mpu)
{
mpu->mpu_ctrl |= MPU_CTRL_PRIVDEFENA_MASK;
}
static inline void mpu_privdefena_disable(armv8m_mpu_t *mpu)
{
mpu->mpu_ctrl &= ~MPU_CTRL_PRIVDEFENA_MASK;
}
static inline void mpu_select_region(armv8m_mpu_t *mpu, uint8_t region)
{
mpu->mpu_rnr |= ((region << MPU_RNR_REGION_SHIFT) & MPU_RNR_REGION_MASK);
}
static inline void mpu_set_region_base(armv8m_mpu_t *mpu, uint32_t base,
uint8_t share_att, uint8_t ap_att, uint32_t is_xn)
{
mpu->mpu_rbar = 0;
mpu->mpu_rbar = (base & MPU_CTRL_RBAR_BASE_MASK) |
((share_att << MPU_CTRL_RBAR_SH_SHIFT) & MPU_CTRL_RBAR_SH_MASK) |
((ap_att << MPU_CTRL_RBAR_AP_SHIFT) & MPU_CTRL_RBAR_AP_MASK) |
(is_xn & MPU_CTRL_RBAR_XN_MASK);
}
static inline void mpu_set_region_limit(armv8m_mpu_t *mpu, uint32_t limit,
uint8_t att_idx, uint8_t en)
{
mpu->mpu_rlar = 0;
mpu->mpu_rlar = (limit & MPU_CTRL_RLAR_LIMIT_MASK) |
((att_idx << MPU_CTRL_RLAR_ATTRIDX_SHIFT) & MPU_CTRL_RLAR_ATTRIDX_MASK) |
(en & MPU_CTRL_RLAR_EN_MASK);
}
mpu->mpu_mair1 &= ~(0xFF << ((idx - 4) * 8));
mpu->mpu_mair1 |= (attr << ((idx - 4) * 8));
}
}
#endif
2.2.2 read-only region test
// test MPU Whether to shut down region Write permissions
void test_armv8m_mpu_write()
{
volatile uint32_t *temp_addr = (volatile uint32_t *)0x30001000UL;
// close MPU Can be before Memory To read and write
easy_printf("0x30001000:%x\n", *temp_addr);
*temp_addr = 0x1;
easy_printf("0x30001000:%x\n", *temp_addr);
armv8m_mpu_t *mpu = (armv8m_mpu_t *)0xE000ED90;
mpu_disable(mpu); // close MPU
mpu_select_region(mpu, 0); // Set up region0
// Set up region0 Base address 0x30000000, Read only, not executable
mpu_set_region_base(mpu, 0x30000000UL, REGION_NON_SHAREABLE, REGION_RO_PRIV_ONLY, REGION_XN);
// Set up region0 Cap of 0x30001FFFF, region0 Use attr0, And enable region
mpu_set_region_limit(mpu, 0x30001FFFUL, 0, REGION_EN);
// Set up region0 The attribute is device memory
mpu_set_region_attr(mpu, 0, 0); /*device memory*/
// open MPU
mpu_hfnmiena_disable(mpu);
mpu_privdefena_enable(mpu);
mpu_enable(mpu);
easy_printf("%s:mpu setup done\n", __func__);
// open MPU Post test whether it has write permission
easy_printf("0x30001000:%x\n", *temp_addr);
// When the program is executed to this point, it will trigger hard fault
*temp_addr = 0x2;
easy_printf("0x30001000:%x\n", *temp_addr);
easy_printf("%s done\n", __func__);
}
perform log:
qemu-system-arm: invalid accelerator kvm
qemu-system-arm: falling back to tcg
hello cortex m33
0x30001000:00000000
0x30001000:00000001
test_armv8m_mpu_write:mpu setup done
0x30001000:00000001
default_exception_handler entry
2.2.3 Address overlap test
oid test_armv8m_mpu_overlap()
{
volatile uint32_t *temp_addr = (volatile uint32_t *)0x30001000UL;
easy_printf("0x30001000:%x\n", *temp_addr);
*temp_addr = 0x1;
easy_printf("0x30001000:%x\n", *temp_addr);
armv8m_mpu_t *mpu = (armv8m_mpu_t *)0xE000ED90;
mpu_disable(mpu);
// Set up region0:0x30000000 - 0x30001FFF
// Can read but write , Unenforceable ,device memory
mpu_select_region(mpu, 0);
mpu_set_region_base(mpu, 0x30000000UL, REGION_NON_SHAREABLE, REGION_RW_PRIV_ONLY, REGION_XN);
mpu_set_region_limit(mpu, 0x30001FFFUL, 0, REGION_EN);
mpu_set_region_attr(mpu, 0, 0); /*device memory*/
// Set up region1:0x30001000 - 0x30001FFF
// Can read but write , Unenforceable ,device memory
mpu_select_region(mpu, 1);
mpu_set_region_base(mpu, 0x30001000UL, REGION_NON_SHAREABLE, REGION_RW_PRIV_ONLY, REGION_XN);
mpu_set_region_limit(mpu, 0x30001FFFUL, 1, REGION_EN);
mpu_set_region_attr(mpu, 0, 1); /*device memory*/
// open MPU
mpu_hfnmiena_disable(mpu);
mpu_privdefena_enable(mpu);
mpu_enable(mpu);
easy_printf("%s:mpu setup done\n", __func__);
// open MPU after , because 0x30001000 The address of is region0 and region1 Overlap in , Accessing this address triggers hard fault
// When the code executes this sentence, an exception will be triggered
easy_printf("0x30001000:%x\n", *temp_addr);
easy_printf("%s done\n", __func__);
}
qemu-system-arm: invalid accelerator kvm
qemu-system-arm: falling back to tcg
hello cortex m33
0x30001000:00000000
0x30001000:00000001
test_armv8m_mpu_overlap:mpu setup done
default_exception_handler entry
2.2.4 Perform a permission test
void test_func_print()
{
easy_printf("%s entry\n", __func__);
}
void test_armv8m_xn()
{
/* Inject code at 0x30001000 */
// stay 0x300001000 Address injection code test_func
typedef void (*test_func_t)(void);
volatile uint32_t *temp_addr = (volatile uint32_t *)0x30001000UL;
test_func_t test_f = (test_func_t )0x30001001;//Thumb Instruction set , So the function call The address should be added when 1
/* 1000041c <test_func>: 1000041c: b500 push {lr} 1000041e: 4801 ldr r0, [pc, #4] ; (10000424 <test_func+0x8>) 10000420: 4780 blx r0 10000422: bd00 pop {pc} 10000424: 100005eb andne r0, r0, fp, ror #11 //100005eb yes test_func_print The address of */
*temp_addr++ = 0x4801b500;
*temp_addr++ = 0xbd004780;
*temp_addr++ = 0x100005eb;
// Can make MPU Can be executed before 0x30001000 Situated test_func
test_f();
// Can make MPU region0:0x30000000 - 0x300010000
// read-only , Unenforceable ,device memory
armv8m_mpu_t *mpu = (armv8m_mpu_t *)0xE000ED90;
mpu_disable(mpu);
mpu_select_region(mpu, 0);
mpu_set_region_base(mpu, 0x30000100UL, REGION_NON_SHAREABLE, REGION_RO_PRIV_ONLY, REGION_XN);
mpu_set_region_limit(mpu, 0x30001FFFUL, 0, REGION_EN);
mpu_set_region_attr(mpu, 0, 0); /*device memory*/
mpu_hfnmiena_disable(mpu);
mpu_privdefena_enable(mpu);
mpu_enable(mpu);
easy_printf("%s:mpu setup done\n", __func__);
// Can make MPU Cannot be executed after 0x30001000 Of test_func, So when the code executes here, it will trigger hardfault
test_f();
}
log
qemu-system-arm: invalid accelerator kvm
qemu-system-arm: falling back to tcg
hello cortex m33
test_func_print entry
test_armv8m_xn:mpu setup done
default_exception_handler entry
版权声明
本文为[MyeDy]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/04/202204230612365570.html
边栏推荐
- JMeter operation redis
- decast id.var measure.var数据拆分与合并
- Important knowledge of transport layer (interview, retest, final)
- The use of dcast and melt in R language is simple and easy to understand
- Importerror after tensorflow installation: DLL load failed: the specified module cannot be found, and the domestic installation is slow
- [untitled] make a 0-99 counter, P1 7 connected to key, P2 connected to nixie tube section, common anode nixie tube, P3 0,P3. 1. Connect the nixie tube bit code. Each time you press the key, the nixie
- Nodejs + websocket cycle small case
- Embrace the new blue ocean of machine vision and hope to open a new "Ji" encounter for the development of digital economy
- STD:: shared of smart pointer_ ptr、std::unique_ ptr
- (1) Openjuterpyrab comparison scheme
猜你喜欢
8086 of x86 architecture
PC starts multiple wechat at one time
Mui + hbuilder + h5api simulate pop-up payment style
31. Next arrangement
filter()遍历Array异常友好
在 pytorch 中加载和使用图像分类数据集 Fashion-MNIST
three.js文字模糊问题
Kernel error: no rule to make target 'Debian / canonical certs pem‘, needed by ‘certs/x509_ certificate_ list‘
Use Proteus to simulate STM32 ultrasonic srf04 ranging! Code+Proteus
nodejs + mysql 实现简单注册功能(小demo)
随机推荐
Mui wechat payment pit
8086 of x86 architecture
jmeter操作redis
Mui + hbuilder + h5api simulate pop-up payment style
Melt reshape decast long data short data length conversion data cleaning row column conversion
Huawei cloud MVP email
Go language slicing operation
MySQL basic statement query
Go language array operation
Mysql8 installation
async void 導致程序崩潰
three. JS text ambiguity problem
MySQL5.5安装教程
AUTOSAR from introduction to mastery 100 lectures (51) - AUTOSAR network management
31. Next arrangement
Hanlp word splitter (via spark)
100 lectures on practical application cases of Excel (VIII) - report connection function of Excel
Introducing vant components on demand
SSM整合之pom.xml
解决虚拟机中Oracle每次要设置ip的问题