2525#include "loader.h"
2626#include "wolfboot/wolfboot.h"
2727
28+ extern unsigned int _start_text ;
2829extern unsigned int _stored_data ;
2930extern unsigned int _start_data ;
3031extern unsigned int _end_data ;
@@ -35,6 +36,130 @@ extern uint32_t *END_STACK;
3536
3637extern void main (void );
3738
39+ #ifndef WOLFBOOT_NO_MPU
40+ #define MPU_BASE (0xE000ED90)
41+ #define MPU_TYPE *((volatile uint32_t *)(MPU_BASE + 0x00))
42+ #define MPU_CTRL *((volatile uint32_t *)(MPU_BASE + 0x04))
43+ #define MPU_RNR *((volatile uint32_t *)(MPU_BASE + 0x08))
44+ #define MPU_RBAR *((volatile uint32_t *)(MPU_BASE + 0x0C))
45+ #define MPU_RASR *((volatile uint32_t *)(MPU_BASE + 0x10))
46+
47+ #define MPU_RASR_ENABLE (1 << 0)
48+ #define MPU_RASR_ATTR_XN (1 << 28)
49+ #define MPU_RASR_ATTR_AP (7 << 24)
50+ #define MPU_RASR_ATTR_AP_PNO_UNO (0 << 24)
51+ #define MPU_RASR_ATTR_AP_PRW_UNO (1 << 24)
52+ #define MPU_RASR_ATTR_AP_PRW_URO (2 << 24)
53+ #define MPU_RASR_ATTR_AP_PRW_URW (3 << 24)
54+ #define MPU_RASR_ATTR_AP_PRO_UNO (5 << 24)
55+ #define MPU_RASR_ATTR_AP_PRO_URO (6 << 24)
56+ #define MPU_RASR_ATTR_TEX (7 << 19)
57+ #define MPU_RASR_ATTR_S (1 << 18)
58+ #define MPU_RASR_ATTR_C (1 << 17)
59+ #define MPU_RASR_ATTR_B (1 << 16)
60+ #define MPU_RASR_ATTR_SCB (7 << 16)
61+
62+ static int mpu_is_on = 0 ;
63+
64+ static void mpu_setaddr (int region , uint32_t addr )
65+ {
66+ MPU_RNR = region ;
67+ MPU_RBAR = addr ;
68+ }
69+
70+ static void mpu_setattr (int region , uint32_t attr )
71+ {
72+ MPU_RNR = region ;
73+ MPU_RASR = attr ;
74+ }
75+
76+ static void mpu_on (void )
77+ {
78+ if (mpu_is_on )
79+ return ;
80+ if (MPU_TYPE == 0 )
81+ return ;
82+ MPU_CTRL = 1 ;
83+ mpu_is_on = 1 ;
84+ }
85+
86+ #define MPUSIZE_8K (0x0c << 1)
87+ #define MPUSIZE_16K (0x0d << 1)
88+ #define MPUSIZE_32K (0x0e << 1)
89+ #define MPUSIZE_64K (0x0f << 1)
90+ /* ... */
91+ #define MPUSIZE_256M (0x1b << 1)
92+ #define MPUSIZE_512M (0x1c << 1)
93+ #define MPUSIZE_1G (0x1d << 1)
94+ #define MPUSIZE_4G (0x1f << 1)
95+ #define MPUSIZE_ERR (0xff << 1)
96+ static uint32_t mpusize (uint32_t size )
97+ {
98+ if (size <= (8 * 1024 ))
99+ return MPUSIZE_8K ;
100+ if (size <= (16 * 1024 ))
101+ return MPUSIZE_16K ;
102+ if (size <= (32 * 1024 ))
103+ return MPUSIZE_32K ;
104+ if (size <= (64 * 1024 ))
105+ return MPUSIZE_64K ;
106+ return MPUSIZE_ERR ;
107+ }
108+
109+ static void mpu_init (void )
110+ {
111+ uint32_t wolfboot_flash_size = (uint32_t )& _stored_data - (uint32_t )& _start_text ;
112+ uint32_t wolfboot_mpusize ;
113+ uint32_t ram_base = (uint32_t )(& _start_data );
114+ uint32_t flash_base = (uint32_t )(& _start_text );
115+ if (MPU_TYPE == 0 )
116+ return ;
117+
118+ /* Read access to address space with XN */
119+ mpu_setaddr (0 , 0 );
120+ mpu_setattr (0 , MPUSIZE_4G | MPU_RASR_ENABLE | MPU_RASR_ATTR_SCB | MPU_RASR_ATTR_AP_PRO_UNO | MPU_RASR_ATTR_XN );
121+
122+ wolfboot_mpusize = mpusize (wolfboot_flash_size );
123+ if (wolfboot_mpusize == MPUSIZE_ERR )
124+ return ;
125+
126+ /* Text in Read-only memory */
127+ mpu_setaddr (1 , flash_base );
128+ mpu_setattr (1 , wolfboot_mpusize | MPU_RASR_ENABLE | MPU_RASR_ATTR_SCB | MPU_RASR_ATTR_AP_PRO_UNO );
129+
130+ /* Data in r/w memory */
131+ mpu_setaddr (2 , ram_base );
132+ #ifdef RAM_CODE
133+ mpu_setattr (2 , MPUSIZE_64K | MPU_RASR_ENABLE | MPU_RASR_ATTR_SCB | MPU_RASR_ATTR_AP_PRW_UNO );
134+ #else
135+ mpu_setattr (2 , MPUSIZE_64K | MPU_RASR_ENABLE | MPU_RASR_ATTR_SCB | MPU_RASR_ATTR_AP_PRW_UNO | MPU_RASR_ATTR_XN );
136+ #endif
137+
138+ /* Peripherals 0x40000000:0x5FFFFFFF (512MB)*/
139+ mpu_setaddr (5 , 0x40000000 );
140+ mpu_setattr (5 , MPUSIZE_512M | MPU_RASR_ENABLE | MPU_RASR_ATTR_S | MPU_RASR_ATTR_B | MPU_RASR_ATTR_AP_PRW_UNO | MPU_RASR_ATTR_XN );
141+
142+ /* External peripherals 0xA0000000:0xCFFFFFFF (1GB)*/
143+ mpu_setaddr (6 , 0xA0000000 );
144+ mpu_setattr (6 , MPUSIZE_1G | MPU_RASR_ENABLE | MPU_RASR_ATTR_S | MPU_RASR_ATTR_B | MPU_RASR_ATTR_AP_PRW_UNO | MPU_RASR_ATTR_XN );
145+
146+ /* System control 0xE0000000:0xEFFFFFF */
147+ mpu_setaddr (7 , 0xE0000000 );
148+ mpu_setattr (7 , MPUSIZE_256M | MPU_RASR_ENABLE | MPU_RASR_ATTR_S | MPU_RASR_ATTR_B | MPU_RASR_ATTR_AP_PRW_UNO | MPU_RASR_ATTR_XN );
149+ mpu_on ();
150+
151+ }
152+
153+ static void mpu_off (void )
154+ {
155+ mpu_is_on = 0 ;
156+ MPU_CTRL = 0 ;
157+ }
158+ #else /* NO MPU */
159+ #define mpu_init () do{}while(0)
160+ #define mpu_off () do{}while(0)
161+ #endif /* NO MPU */
162+
38163
39164void isr_reset (void ) {
40165 register unsigned int * src , * dst ;
@@ -62,6 +187,7 @@ void isr_reset(void) {
62187 dst ++ ;
63188 }
64189
190+ mpu_init ();
65191 /* Run the program! */
66192 main ();
67193}
@@ -94,7 +220,7 @@ static uint32_t app_end_stack;
94220
95221void RAMFUNCTION do_boot (const uint32_t * app_offset )
96222{
97-
223+ mpu_off ();
98224#ifndef NO_VTOR
99225 /* Disable interrupts */
100226 asm volatile ("cpsid i" );
@@ -125,19 +251,19 @@ typedef void(*NMIHANDLER)(void);
125251__attribute__ ((section (".isr_vector" )))
126252void (* const IV [])(void ) =
127253{
128- (void (* )(void ))(& END_STACK ),
129- isr_reset , // Reset
130- isr_NMI , // NMI
131- isr_fault , // HardFault
132- isr_fault , // MemFault
133- isr_fault , // BusFault
134- isr_fault , // UsageFault
135- 0 , 0 , 0 , 0 , // 4x reserved
136- isr_empty , // SVC
137- isr_empty , // DebugMonitor
138- 0 , // reserved
139- isr_empty , // PendSV
140- isr_empty , // SysTick
254+ (void (* )(void ))(& END_STACK ),
255+ isr_reset , // Reset
256+ isr_NMI , // NMI
257+ isr_fault , // HardFault
258+ isr_fault , // MemFault
259+ isr_fault , // BusFault
260+ isr_fault , // UsageFault
261+ 0 , 0 , 0 , 0 , // 4x reserved
262+ isr_empty , // SVC
263+ isr_empty , // DebugMonitor
264+ 0 , // reserved
265+ isr_empty , // PendSV
266+ isr_empty , // SysTick
141267
142268 isr_empty ,
143269 isr_empty ,
0 commit comments