Skip to content

Commit a4aa5ea

Browse files
c1728p90xc0170
authored andcommitted
Add v8m MPU
Add a driver for the v8m MPU.
1 parent fb7e7e9 commit a4aa5ea

File tree

1 file changed

+125
-0
lines changed

1 file changed

+125
-0
lines changed

hal/mpu/mbed_mpu_v8m.c

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
/* mbed Microcontroller Library
2+
* Copyright (c) 2018 ARM Limited
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
#include "hal/mpu_api.h"
17+
#include "cmsis.h"
18+
19+
#if ((__ARM_ARCH_8M_BASE__ == 1U) || (__ARM_ARCH_8M_MAIN__ == 1U)) && \
20+
defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U)
21+
22+
#if !DEVICE_MPU
23+
#error "Device has v8m MPU but it is not enabled. Add 'MPU' to device_has in targets.json"
24+
#endif
25+
26+
void mbed_mpu_init()
27+
{
28+
mbed_mpu_enable_ram_xn(false);
29+
}
30+
31+
void mbed_mpu_free()
32+
{
33+
mbed_mpu_enable_ram_xn(false);
34+
}
35+
36+
void mbed_mpu_enable_ram_xn(bool enable)
37+
{
38+
// Flush memory writes before configuring the MPU.
39+
__DSB();
40+
41+
const uint32_t regions = (MPU->TYPE & MPU_TYPE_DREGION_Msk) >> MPU_TYPE_DREGION_Pos;
42+
43+
// Disable the MCU
44+
MPU->CTRL = 0;
45+
46+
// Reset all mapping
47+
for (uint32_t i = 0; i < regions; i++) {
48+
ARM_MPU_ClrRegionEx(MPU, i);
49+
}
50+
51+
if (!enable) {
52+
return;
53+
}
54+
55+
/*
56+
* ARMv8m memory map:
57+
*
58+
* Start End Name Executable by default Default cache Mbed MPU protection
59+
* 0x00000000 - 0x1FFFFFFF Code Yes WT, WA
60+
* 0x20000000 - 0x3FFFFFFF SRAM Yes WB, WA, RA Execute disabled
61+
* 0x40000000 - 0x5FFFFFFF Peripheral No
62+
* 0x60000000 - 0x7FFFFFFF RAM Yes WB, WA, RA Execute disabled
63+
* 0x80000000 - 0x9FFFFFFF RAM Yes WT, RA Execute disabled
64+
* 0xA0000000 - 0xBFFFFFFF Device No
65+
* 0xC0000000 - 0xDFFFFFFF Device No
66+
* 0xE0000000 - 0xFFFFFFFF System No
67+
*/
68+
69+
if (regions >= 3) {
70+
uint32_t region;
71+
uint8_t outer;
72+
uint8_t inner;
73+
74+
region = 0;
75+
MPU->RNR = region;
76+
outer = 0xF; // Write-Back, Non-transient, Read-allocate, Write-allocate
77+
outer = 0xF; // Write-Back, Non-transient, Read-allocate, Write-allocate
78+
ARM_MPU_SetMemAttrEx(MPU, region, (outer << 4) | (inner << 0));
79+
MPU->RBAR = (0x20000000 & MPU_RBAR_BASE_Msk) | // Start address is 0x20000000
80+
(0 << MPU_RBAR_SH_Pos) | // Not shareable
81+
(1 << MPU_RBAR_AP_Pos) | // RW allowed by all privilege levels
82+
(1 << MPU_RBAR_XN_Pos); // Execute Never enabled
83+
MPU->RLAR = (0x3FFFFFFF & MPU_RLAR_LIMIT_Msk) | // Last address is 0x3FFFFFFF
84+
(region << MPU_RLAR_AttrIndx_Pos) | // Attribute index - configured to be the same as the region number
85+
(1 << MPU_RLAR_EN_Pos); // Enable region
86+
87+
region = 1;
88+
MPU->RNR = region;
89+
outer = 0xF; // Write-Back, Non-transient, Read-allocate, Write-allocate
90+
outer = 0xF; // Write-Back, Non-transient, Read-allocate, Write-allocate
91+
ARM_MPU_SetMemAttrEx(MPU, region, (outer << 4) | (inner << 0));
92+
MPU->RBAR = (0x60000000 & MPU_RBAR_BASE_Msk) | // Start address is 0x60000000
93+
(0 << MPU_RBAR_SH_Pos) | // Not shareable
94+
(1 << MPU_RBAR_AP_Pos) | // RW allowed by all privilege levels
95+
(1 << MPU_RBAR_XN_Pos); // Execute Never enabled
96+
MPU->RLAR = (0x7FFFFFFF & MPU_RLAR_LIMIT_Msk) | // Last address is 0x7FFFFFFF
97+
(region << MPU_RLAR_AttrIndx_Pos) | // Attribute index - configured to be the same as the region number
98+
(1 << MPU_RLAR_EN_Pos); // Enable region
99+
100+
region = 2;
101+
MPU->RNR = region;
102+
outer = 0xA; // Write-Through, Non-transient, Read-allocate
103+
inner = 0xA; // Write-Through, Non-transient, Read-allocate
104+
ARM_MPU_SetMemAttrEx(MPU, region, (outer << 4) | (inner << 0));
105+
MPU->RBAR = (0x80000000 & MPU_RBAR_BASE_Msk) | // Start address is 0x80000000
106+
(0 << MPU_RBAR_SH_Pos) | // Not shareable
107+
(1 << MPU_RBAR_AP_Pos) | // RW allowed by all privilege levels
108+
(1 << MPU_RBAR_XN_Pos); // Execute Never enabled
109+
MPU->RLAR = (0x9FFFFFFF & MPU_RLAR_LIMIT_Msk) | // Last address is 0x9FFFFFFF
110+
(region << MPU_RLAR_AttrIndx_Pos) | // Attribute index - configured to be the same as the region number
111+
(1 << MPU_RLAR_EN_Pos); // Enable region
112+
}
113+
114+
// Enable the MPU
115+
MPU->CTRL =
116+
(1 << MPU_CTRL_PRIVDEFENA_Pos) | // Use the default memory map for unmapped addresses
117+
(1 << MPU_CTRL_HFNMIENA_Pos) | // Keep MPU turned on for faults
118+
(1 << MPU_CTRL_ENABLE_Pos); // Enable MPU
119+
120+
// Ensure changes take effect
121+
__ISB();
122+
__DSB();
123+
}
124+
125+
#endif

0 commit comments

Comments
 (0)