ICARUS OS (Intelligent Cooperative Architecture for Real-time Unified Systems) 0.1.0
Preemptive Real-Time Operating System for ARM Cortex-M7
Loading...
Searching...
No Matches
mpu.c
Go to the documentation of this file.
1
38#include "bsp/mpu.h"
39#include "stm32h7xx.h"
40
41/* ============================================================================
42 * MPU CONFIGURATION
43 * ========================================================================= */
44
64void MPU_Config(void)
65{
66 MPU_Region_InitTypeDef r = {0};
67
68 HAL_MPU_Disable();
69
70 /* ---- Region 0: ITCM 64KB base — RO+exec for all ---- */
71 /* Kernel functions in ITCM - read-only prevents code modification */
72 /* Note: ARM MPU cannot prevent unprivileged EXECUTION of privileged code */
73 /* Protection relies on exception mechanism (SVC/PendSV only via instructions) */
74 r.Enable = MPU_REGION_ENABLE;
75 r.Number = MPU_REGION_ITCM_BASE;
76 r.BaseAddress = BSP_ITCM_BASE;
77 r.Size = MPU_REGION_SIZE_64KB;
78 r.AccessPermission = MPU_REGION_PRIV_RO_URO; /* Read-only for all */
79 r.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
80 r.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
81 r.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
82 r.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
83 r.TypeExtField = MPU_TEX_LEVEL1;
84 r.SubRegionDisable = 0x00;
85 HAL_MPU_ConfigRegion(&r);
86
87 /* ---- Region 1: QSPI 8MB flash — Priv+User RO+exec, cacheable ---- */
88 r.Enable = MPU_REGION_ENABLE;
89 r.Number = MPU_REGION_QSPI_FLASH;
90 r.BaseAddress = QSPI_BASE;
91 r.Size = MPU_REGION_SIZE_8MB;
92 r.AccessPermission = MPU_REGION_PRIV_RO_URO;
93 r.IsBufferable = MPU_ACCESS_BUFFERABLE;
94 r.IsCacheable = MPU_ACCESS_CACHEABLE;
95 r.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
96 r.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
97 r.TypeExtField = MPU_TEX_LEVEL1;
98 r.SubRegionDisable = 0x00;
99 HAL_MPU_ConfigRegion(&r);
100
101 /* ---- Region 2: Internal Flash 128K — Priv+User RO+exec ---- */
102 r.Enable = MPU_REGION_ENABLE;
103 r.Number = MPU_REGION_FLASH;
104 r.BaseAddress = BSP_FLASH_BASE;
105 r.Size = MPU_REGION_SIZE_128KB;
106 r.AccessPermission = MPU_REGION_PRIV_RO_URO;
107 r.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
108 r.IsCacheable = MPU_ACCESS_CACHEABLE;
109 r.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
110 r.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
111 r.TypeExtField = MPU_TEX_LEVEL1;
112 r.SubRegionDisable = 0x00;
113 HAL_MPU_ConfigRegion(&r);
114
115 /* ---- Region 3: Upper DTCM 64KB — Priv+User RW (OBC hot data) ---- */
116 /* Region 5 (DTCM 128KB PRIV_RW) disables subregions 4-7 so this */
117 /* lower-numbered region takes effect for the upper half. */
118 /* OBC application data tagged DTCM_DATA_OBC lands here for zero */
119 /* wait-state access from unprivileged task code. */
120 r.Enable = MPU_REGION_ENABLE;
121 r.Number = MPU_REGION_DTCM_OBC;
122 r.BaseAddress = BSP_DTCM_OBC_BASE;
123 r.Size = MPU_REGION_SIZE_64KB;
124 r.AccessPermission = MPU_REGION_FULL_ACCESS;
125 r.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
126 r.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
127 r.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
128 r.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
129 r.TypeExtField = MPU_TEX_LEVEL1;
130 r.SubRegionDisable = 0x00;
131 HAL_MPU_ConfigRegion(&r);
132
133 /* ---- Region 4: Task data (dynamic, configured per context switch) ---- */
134 /* Left unconfigured here — set by MPU_ConfigureTaskData() */
135
136 /* ---- Region 5: DTCM 128K — PRIV_RW (kernel data, lower 64K only) ---- */
137 /* Kernel data (.dtcm_priv) lives in the lower 64KB (subregions 0-3). */
138 /* Subregions 4-7 disabled so Region 3 (FULL_ACCESS) governs the upper */
139 /* 64KB where OBC application hot data (.dtcm_obc) is placed. */
140 r.Enable = MPU_REGION_ENABLE;
141 r.Number = MPU_REGION_DTCM;
142 r.BaseAddress = BSP_DTCM_BASE;
143 r.Size = MPU_REGION_SIZE_128KB;
144 r.AccessPermission = MPU_REGION_PRIV_RW;
145 r.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
146 r.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
147 r.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
148 r.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
149 r.TypeExtField = MPU_TEX_LEVEL1;
150 r.SubRegionDisable = 0xF0;
151 HAL_MPU_ConfigRegion(&r);
152
153 /* ---- Region 6: RAM_D1 512K — Priv+User Full Access ---- */
154 /* Stacks, .data, .bss, heap, task stacks/data pools. */
155 r.Enable = MPU_REGION_ENABLE;
156 r.Number = MPU_REGION_RAM_D1;
157 r.BaseAddress = BSP_RAM_D1_BASE;
158 r.Size = MPU_REGION_SIZE_512KB;
159 r.AccessPermission = MPU_REGION_FULL_ACCESS;
160 r.IsBufferable = MPU_ACCESS_BUFFERABLE;
161 r.IsCacheable = MPU_ACCESS_CACHEABLE;
162 r.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
163 r.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
164 r.TypeExtField = MPU_TEX_LEVEL1;
165 r.SubRegionDisable = 0x00;
166 HAL_MPU_ConfigRegion(&r);
167
168 /* ---- Region 7: Peripherals 512MB — Priv+User Full Access, Device ---- */
169 /* GPIO, USB, SPI, I2C, UART, etc. */
170 r.Enable = MPU_REGION_ENABLE;
171 r.Number = MPU_REGION_PERIPH;
172 r.BaseAddress = BSP_PERIPH_BASE;
173 r.Size = MPU_REGION_SIZE_512MB;
174 r.AccessPermission = MPU_REGION_FULL_ACCESS;
175 r.IsBufferable = MPU_ACCESS_BUFFERABLE;
176 r.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
177 r.IsShareable = MPU_ACCESS_SHAREABLE;
178 r.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
179 r.TypeExtField = MPU_TEX_LEVEL0;
180 r.SubRegionDisable = 0x00;
181 HAL_MPU_ConfigRegion(&r);
182
183 /* Enable MPU with privileged default map as background fallback. */
184 /* MPU_PRIVILEGED_DEFAULT blocks unprivileged access to SCS (0xE000E000)*/
185 /* — NVIC, SCB, SysTick, MPU registers — forcing SVC for those writes. */
186 HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
187
188 /* Memory barriers required after MPU configuration (ARM Cortex-M7)
189 * DSB: Ensure all memory accesses complete before MPU change takes effect
190 * ISB: Flush instruction pipeline to ensure new MPU config is used */
191 __DSB();
192 __ISB();
193}
194
195/* ============================================================================
196 * DYNAMIC TASK DATA REGION
197 * ========================================================================= */
198
204void MPU_ConfigureTaskData(uint32_t task_data_base)
205{
206 MPU_Region_InitTypeDef r = {0};
207
208 r.Enable = MPU_REGION_ENABLE;
209 r.Number = MPU_REGION_TASK_DATA;
210 r.BaseAddress = task_data_base;
211 r.Size = TASK_DATA_SIZE_MPU;
212 r.AccessPermission = MPU_REGION_FULL_ACCESS;
213 r.IsCacheable = MPU_ACCESS_CACHEABLE;
214 r.IsBufferable = MPU_ACCESS_BUFFERABLE;
215 r.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
216 r.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
217 r.TypeExtField = MPU_TEX_LEVEL0;
218 r.SubRegionDisable = 0x00;
219
220 HAL_MPU_ConfigRegion(&r);
221
222 /* Memory barriers required after MPU reconfiguration (ARM Cortex-M7)
223 * DSB: Ensure all memory accesses complete before MPU change takes effect
224 * ISB: Flush instruction pipeline to ensure new MPU config is used */
225 __DSB();
226 __ISB();
227}
#define BSP_DTCM_BASE
DTCM RAM base address (128KB, zero wait-state data)
Definition mpu.h:31
#define BSP_DTCM_OBC_BASE
Upper DTCM for OBC application hot data (64KB, unprivileged RW)
Definition mpu.h:35
#define BSP_FLASH_BASE
Internal Flash base address (128KB)
Definition mpu.h:50
#define BSP_RAM_D1_BASE
AXI SRAM (RAM_D1) base address (512KB)
Definition mpu.h:38
#define BSP_ITCM_BASE
ITCM RAM base address (64KB, zero wait-state code)
Definition mpu.h:27
#define BSP_PERIPH_BASE
Peripheral base address (512MB)
Definition mpu.h:58
void MPU_ConfigureTaskData(uint32_t task_data_base)
Configure MPU region 4 for the current task's data section.
Definition mpu.c:204
void MPU_Config(void)
Configure Memory Protection Unit regions.
Definition mpu.c:64
#define MPU_REGION_DTCM
Definition mpu.h:69
#define MPU_REGION_FLASH
Definition mpu.h:66
#define MPU_REGION_ITCM_BASE
Definition mpu.h:64
#define MPU_REGION_PERIPH
Definition mpu.h:71
#define MPU_REGION_QSPI_FLASH
Definition mpu.h:65
#define MPU_REGION_TASK_DATA
Definition mpu.h:68
#define TASK_DATA_SIZE_MPU
Definition mpu.h:101
#define MPU_REGION_DTCM_OBC
Definition mpu.h:67
#define MPU_REGION_RAM_D1
Definition mpu.h:70