Skip to content

Commit 213cfce

Browse files
authored
Merge pull request #41 from AniruddhaKanhere/AddSESIPDemo_MPU
Add sesip demo for MPU
2 parents e6f3e20 + 56dec39 commit 213cfce

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+8966
-46
lines changed

examples/evkbmimxrt1060/bootloader/main.c

-1
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,6 @@ int main( void )
5959
#endif
6060

6161
/* Init board hardware. */
62-
BOARD_ConfigMPU();
6362
BOARD_InitBootPins();
6463
BOARD_InitBootClocks();
6564
BOARD_InitDebugConsole();

examples/evkbmimxrt1060/bootloader/sblconfig.h

+1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
/* secure */
3838

3939
#define COMPONENT_MCUBOOT_SECURE
40+
//#define CONFIG_BOOT_SIGNATURE_TYPE_ROM
4041
#define CONFIG_BOOT_SIGNATURE
4142
#define CONFIG_BOOT_SIGNATURE_TYPE_RSA
4243
#define CONFIG_BOOT_SIGNATURE_TYPE_RSA_LEN 2048

examples/evkbmimxrt1060/bootloader/signing_pub_key.c

+1
Original file line numberDiff line numberDiff line change
@@ -43,3 +43,4 @@ const unsigned char ecdsa_pub_key[] = { 0x00 };
4343
const unsigned int ecdsa_pub_key_len = 0;
4444

4545
#endif /* if defined( MCUBOOT_SIGN_RSA ) */
46+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,362 @@
1+
/*
2+
* FreeRTOS version 202012.00-LTS
3+
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
4+
*
5+
* Permission is hereby granted, free of charge, to any person obtaining a copy of
6+
* this software and associated documentation files (the "Software"), to deal in
7+
* the Software without restriction, including without limitation the rights to
8+
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9+
* the Software, and to permit persons to whom the Software is furnished to do so,
10+
* subject to the following conditions:
11+
*
12+
* The above copyright notice and this permission notice shall be included in all
13+
* copies or substantial portions of the Software.
14+
*
15+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17+
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18+
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19+
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20+
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21+
*
22+
* http://www.FreeRTOS.org
23+
* http://aws.amazon.com/freertos
24+
*
25+
* 1 tab == 4 spaces!
26+
*/
27+
28+
/**
29+
* @brief Demonstration of Memory Protection Unit functionalities.
30+
* Demo creates two restricted tasks read-only task and and a read write task.
31+
* To find more about create restricted task API, see: https://www.freertos.org/xTaskCreateRestricted.html.
32+
* Read-only task has read only access to a shared memory region, while Read-Write task has both read and write
33+
* access to it. Read-only task sets a global flag to one and then try to write to the shared memory region, which generates
34+
* hard fault by MPU. The hard fault handler implemented in this demo handles the exception gracefully by setting the global
35+
* flag back to zero and skipping to the next instruction in the task. The read only task verifies that flag is reset to zero to confirm
36+
* that the memory fault was raised and handled gracefully.
37+
*/
38+
39+
/* FreeRTOS include. */
40+
#include "FreeRTOS.h"
41+
42+
/* Task API include. */
43+
#include "task.h"
44+
45+
/* Contains PRINTF APIs. */
46+
#include "fsl_debug_console.h"
47+
48+
/**
49+
* @brief Flag to enable or disable memory fault injection.
50+
* To enable, set the flag to 1. Enabling this will cause the read-only task to write to a shared memory region
51+
* thereby causing a hard fault.
52+
*/
53+
#define INJECT_TEST_MEMORY_FAULT ( 0 )
54+
55+
/**
56+
* @brief Size of the shared memory between the restricted tasks.
57+
*/
58+
#define SHARED_MEMORY_SIZE 32
59+
60+
/**
61+
* @brief Size of the memory region used by the Read only task and hard fault handler.
62+
*/
63+
#define MIN_REGION_SIZE 32
64+
65+
/**
66+
* @brief Stack size of the restricted tasks.
67+
*/
68+
#define RESTRICTED_TASK_STACK_SIZE 128
69+
70+
/*
71+
* @brief Macro to override printf funtion to run it in privileged mode.
72+
* NXP PRINTF code resides somewhere in RAM that could be provided as accessible region, but it's simpler to
73+
* just run it as privileged */
74+
#define MPU_PRINTF( ... ) \
75+
{ \
76+
BaseType_t xRunningPrivileged = xPortRaisePrivilege(); \
77+
PRINTF( __VA_ARGS__ ); \
78+
vPortResetPrivilege( xRunningPrivileged ); \
79+
}
80+
81+
82+
/* For readability. Read about Hardfault Entry in ARMv7 docs for more details */
83+
typedef struct
84+
{
85+
uint32_t r0;
86+
uint32_t r1;
87+
uint32_t r2;
88+
uint32_t r3;
89+
uint32_t r12;
90+
uint32_t lr;
91+
uint32_t return_address;
92+
uint32_t xPSR;
93+
} HardFaultStack_t;
94+
95+
96+
/**
97+
* @brief Calls the port specific code to raise the privilege.
98+
*
99+
* @return pdFALSE if privilege was raised, pdTRUE otherwise.
100+
*/
101+
extern BaseType_t xPortRaisePrivilege(void);
102+
103+
/**
104+
* @brief Calls the port specific code to reset the privilege.
105+
* If xRunningPrivileged is pdFALSE, calls the port specific
106+
* code to reset the privilege, otherwise does nothing.
107+
*
108+
* @param[in] xRunningPrivileged Whether running in privelged mode or not.
109+
*/
110+
extern void vPortResetPrivilege(BaseType_t xRunningPrivileged);
111+
112+
/**
113+
* @brief Function used to dump the MPU memory regions allocated by linker script.
114+
*/
115+
void printRegions(void);
116+
117+
/**
118+
* @brief The Read write restricted task.
119+
* Task loops and keeps writing to the shared memory region. Since task has both read and write access it should
120+
* not cause a memory fault.
121+
*
122+
* @param[in] pvParameters Parameters to the task.
123+
*/
124+
static void prvRWAccessTask(void* pvParameters);
125+
126+
/**
127+
* @brief The read only task
128+
* Task loops and reads from the shared memory region. If INJECT_TEST_MEMORY_FAULT is set to 1, task also writes to
129+
* shared memory region. Using hard fault handler it recovers from the hard fault and prints the memory access violation
130+
* to the console.
131+
*
132+
* @param[in] pvParameters Parameters to the task.
133+
*/
134+
static void prvROAccessTask(void* pvParameters);
135+
136+
/**
137+
* @brief Memory regions used by the linker script.
138+
*/
139+
extern uint32_t __privileged_functions_start__[];
140+
extern uint32_t __privileged_functions_end__[];
141+
extern uint32_t __FLASH_segment_start__[];
142+
extern uint32_t __FLASH_segment_end__[];
143+
extern uint32_t __privileged_data_start__[];
144+
extern uint32_t __privileged_data_end__[];
145+
extern uint32_t __syscalls_flash_start__[];
146+
extern uint32_t __syscalls_flash_end__[];
147+
extern uint32_t __SRAM_segment_start__[];
148+
extern uint32_t __SRAM_segment_end__[];
149+
150+
151+
/**
152+
* @brief Shared memory area used between the restricted tasks.
153+
*/
154+
static uint8_t ucSharedMemory[SHARED_MEMORY_SIZE] __attribute__((aligned(SHARED_MEMORY_SIZE)));
155+
156+
/**
157+
* @brief Statically allocated stack for Read-write access restristed task.
158+
*/
159+
static StackType_t xRWAccessTaskStack[RESTRICTED_TASK_STACK_SIZE] __attribute__((aligned(RESTRICTED_TASK_STACK_SIZE * sizeof(StackType_t))));
160+
161+
/*
162+
* @brief The memory region shared between Read only task and hard fault handler.
163+
*
164+
* This is how RO task communicates to handler that it intentionally memory faulted.
165+
* Note, handlers run priviliged thus will have access)
166+
* Also note, 32B is minimum valid size for region*/
167+
static volatile uint8_t ucROTaskFaultTracker[MIN_REGION_SIZE] __attribute__((aligned(MIN_REGION_SIZE))) = { 0 };
168+
169+
/**
170+
* @brief Statically allocated stack for Read-only access restristed task.
171+
*/
172+
static StackType_t xROAccessTaskStack[RESTRICTED_TASK_STACK_SIZE] __attribute__((aligned(RESTRICTED_TASK_STACK_SIZE * sizeof(StackType_t))));
173+
174+
/* ------------------------------------------------------------------------------- */
175+
176+
void printRegions(void)
177+
{
178+
uint32_t* tmp = NULL;
179+
180+
tmp = __privileged_functions_start__;
181+
tmp = __privileged_functions_end__;
182+
tmp = __FLASH_segment_start__;
183+
tmp = __FLASH_segment_end__;
184+
tmp = __privileged_data_start__;
185+
tmp = __privileged_data_end__;
186+
187+
(void)tmp;
188+
189+
PRINTF("\r\n");
190+
PRINTF("privileged functions: %08x - %08x\r\n", __privileged_functions_start__, __privileged_functions_end__);
191+
PRINTF("privileged data: %08x - %08x\r\n", __privileged_data_start__, __privileged_data_end__);
192+
PRINTF("system calls: %08x - %08x\r\n", __syscalls_flash_start__, __syscalls_flash_end__);
193+
PRINTF("flash segment: %08x - %08x\r\n", __FLASH_segment_start__, __FLASH_segment_end__);
194+
PRINTF("sram segment: %08x - %08x\r\n", __SRAM_segment_start__, __SRAM_segment_end__);
195+
PRINTF("\r\n");
196+
}
197+
198+
static void prvRWAccessTask(void* pvParameters)
199+
{
200+
/* Unused parameters. */
201+
(void)pvParameters;
202+
203+
ucSharedMemory[0] = 0;
204+
205+
while (1)
206+
{
207+
ucSharedMemory[0] = 1;
208+
MPU_PRINTF("Ran RW task\r\n");
209+
210+
vTaskDelay(pdMS_TO_TICKS(8000));
211+
}
212+
}
213+
214+
static void prvROAccessTask(void* pvParameters)
215+
{
216+
uint8_t ucVal;
217+
218+
/* Unused parameters. */
219+
(void)pvParameters;
220+
ucROTaskFaultTracker[0] = 0;
221+
222+
for (; ; )
223+
{
224+
/* This task has RO access to ucSharedMemory and therefore it can read
225+
* it but cannot modify it. */
226+
ucVal = ucSharedMemory[0];
227+
228+
/* Silent compiler warnings about unused variables. */
229+
(void)ucVal;
230+
231+
#if ( INJECT_TEST_MEMORY_FAULT == 1 )
232+
ucROTaskFaultTracker[0] = 1;
233+
234+
MPU_PRINTF("Triggering memory violation...\r\n");
235+
236+
/* Illegal access to generate Memory Fault. */
237+
ucSharedMemory[0] = 0;
238+
239+
/* Ensure that the above line did generate MemFault and the fault
240+
* handler did clear the ucROTaskFaultTracker[ 0 ]. */
241+
if (ucROTaskFaultTracker[0] == 0)
242+
{
243+
MPU_PRINTF("Access Violation handled.\r\n");
244+
}
245+
else
246+
{
247+
MPU_PRINTF("Error: Access violation should have triggered a fault\r\n");
248+
}
249+
#endif /* ifdef INJECT_TEST_MEMORY_FAULT */
250+
MPU_PRINTF("Ran RO task\r\n");
251+
252+
vTaskDelay(pdMS_TO_TICKS(5000));
253+
}
254+
}
255+
256+
void xCreateRestrictedTasks(BaseType_t xPriority)
257+
{
258+
/* Create restricted tasks */
259+
TaskParameters_t xRWAccessTaskParameters =
260+
{
261+
.pvTaskCode = prvRWAccessTask,
262+
.pcName = "RWAccess",
263+
.usStackDepth = RESTRICTED_TASK_STACK_SIZE,
264+
.pvParameters = NULL,
265+
.uxPriority = xPriority,
266+
.puxStackBuffer = xRWAccessTaskStack,
267+
.xRegions =
268+
{
269+
{ ucSharedMemory, SHARED_MEMORY_SIZE, portMPU_REGION_READ_WRITE | portMPU_REGION_EXECUTE_NEVER },
270+
{ 0, 0, 0 },
271+
{ 0, 0, 0 },
272+
}
273+
};
274+
275+
xTaskCreateRestricted(&(xRWAccessTaskParameters), NULL);
276+
277+
TaskParameters_t xROAccessTaskParameters =
278+
{
279+
.pvTaskCode = prvROAccessTask,
280+
.pcName = "ROAccess",
281+
.usStackDepth = RESTRICTED_TASK_STACK_SIZE,
282+
.pvParameters = NULL,
283+
.uxPriority = xPriority,
284+
.puxStackBuffer = xROAccessTaskStack,
285+
.xRegions =
286+
{
287+
{ ucSharedMemory, SHARED_MEMORY_SIZE, portMPU_REGION_PRIVILEGED_READ_WRITE_UNPRIV_READ_ONLY | portMPU_REGION_EXECUTE_NEVER },
288+
{ (void*)ucROTaskFaultTracker, SHARED_MEMORY_SIZE, portMPU_REGION_READ_WRITE | portMPU_REGION_EXECUTE_NEVER },
289+
{ 0, 0, 0 }
290+
/*{ 0x20000500, 0x100, portMPU_REGION_READ_WRITE }, */
291+
}
292+
};
293+
xTaskCreateRestricted(&(xROAccessTaskParameters), NULL);
294+
}
295+
296+
297+
/* ------------------------------------------------------------------------------- */
298+
299+
/**
300+
* @brief The hard fault handler defined by the demo.
301+
* Function takes in hardfaulted stack address, finds out the next instructions to skip to,
302+
* resets the shared flag to zero for read-only task and then skips the stack pointer to the next
303+
* instruction to be executed.
304+
*/
305+
portDONT_DISCARD void vHandleMemoryFault(uint32_t* pulFaultStackAddress)
306+
{
307+
uint32_t ulPC;
308+
uint16_t usOffendingInstruction;
309+
310+
HardFaultStack_t* const xFaultStack = (HardFaultStack_t*)pulFaultStackAddress;
311+
312+
/* Read program counter. */
313+
ulPC = xFaultStack->return_address;
314+
315+
if (ucROTaskFaultTracker[0] == 1)
316+
{
317+
/* Read the offending instruction. */
318+
usOffendingInstruction = *(uint16_t*)ulPC;
319+
320+
/* From ARM docs:
321+
* If the value of bits[15:11] of the halfword being decoded is one of
322+
* the following, the halfword is the first halfword of a 32-bit
323+
* instruction:
324+
* - 0b11101.
325+
* - 0b11110.
326+
* - 0b11111.
327+
* Otherwise, the halfword is a 16-bit instruction.
328+
*/
329+
330+
/* Extract bits[15:11] of the offending instruction. */
331+
usOffendingInstruction = usOffendingInstruction & 0xF800;
332+
usOffendingInstruction = (usOffendingInstruction >> 11);
333+
334+
/* Increment to next instruction, depending on current instruction size (32-bit or 16-bit) */
335+
if ((usOffendingInstruction == 0x001F) ||
336+
(usOffendingInstruction == 0x001E) ||
337+
(usOffendingInstruction == 0x001D))
338+
{
339+
ulPC += 4;
340+
}
341+
else
342+
{
343+
ulPC += 2;
344+
}
345+
346+
/* Indicate to RO task its expected fault was handled */
347+
ucROTaskFaultTracker[0] = 0;
348+
349+
/* Resume execution after offending instruction from RO task */
350+
xFaultStack->return_address = ulPC;
351+
352+
PRINTF("Expected memory violation caught by handler...\r\n", ulPC);
353+
}
354+
else
355+
{
356+
PRINTF("Memory Access Violation. Inst @ %x\r\n", ulPC);
357+
358+
while (1)
359+
{
360+
}
361+
}
362+
}

0 commit comments

Comments
 (0)