19
19
#include <hal/nrf_gpio.h>
20
20
#endif
21
21
22
+ #include <zephyr/linker/linker-defs.h>
23
+ #define CLEANUP_RAM_GAP_START ((int)__ramfunc_region_start)
24
+ #define CLEANUP_RAM_GAP_END ((int)__ramfunc_end)
25
+ #define CLEANUP_RAM_FIRST_START (CONFIG_SRAM_BASE_ADDRESS)
26
+ #define CLEANUP_RAM_FIRST_SIZE (CLEANUP_RAM_GAP_START)
27
+ #define CLEANUP_RAM_SECOND_START (CLEANUP_RAM_GAP_END)
28
+ #define CLEANUP_RAM_SECOND_SIZE (CONFIG_SRAM_SIZE * 1024 - CLEANUP_RAM_GAP_END)
29
+
30
+ #if defined(CONFIG_SB_DISABLE_NEXT_W )
31
+ #include <hal/nrf_rramc.h>
32
+ #define RRAMC_REGION_FOR_NEXT_W 4
33
+ #define NRF_RRAM_REGION_SIZE_UNIT 0x400
34
+ #define NRF_RRAM_REGION_ADDRESS_RESOLUTION 0x400
35
+ #define NEXT_W_SIZE_KB (PM_MCUBOOT_SIZE / NRF_RRAM_REGION_SIZE_UNIT)
36
+
37
+ BUILD_ASSERT ((PM_MCUBOOT_ADDRESS % NRF_RRAM_REGION_ADDRESS_RESOLUTION ) == 0 ,
38
+ "Start of protected region is not aligned" );
39
+
40
+ BUILD_ASSERT ((PM_MCUBOOT_SIZE % NRF_RRAM_REGION_SIZE_UNIT ) == 0 ,
41
+ "Size of protected region is not aligned" );
42
+
43
+ BUILD_ASSERT (NEXT_W_SIZE_KB < 31 ,
44
+ "Size of requested protection is too big" );
45
+
46
+ static int disable_next_w (void )
47
+ {
48
+ nrf_rramc_region_config_t config = {
49
+ .address = PM_MCUBOOT_ADDRESS ,
50
+ .permissions = NRF_RRAMC_REGION_PERM_READ_MASK |
51
+ NRF_RRAMC_REGION_PERM_EXECUTE_MASK ,
52
+ .writeonce = false,
53
+ .lock = false,
54
+ .size_kb = NEXT_W_SIZE_KB ,
55
+ };
56
+
57
+ nrf_rramc_region_config_set (NRF_RRAMC , RRAMC_REGION_FOR_NEXT_W , & config );
58
+ nrf_rramc_region_config_get (NRF_RRAMC , RRAMC_REGION_FOR_NEXT_W , & config );
59
+ if (config .permissions & (NRF_RRAMC_REGION_PERM_WRITE_MASK )) {
60
+ return - ENOSPC ;
61
+ }
62
+ if (config .size_kb != NEXT_W_SIZE_KB ) {
63
+ return - ENOSPC ;
64
+ }
65
+
66
+ return 0 ;
67
+ }
68
+
69
+ #endif
70
+
22
71
#if defined(CONFIG_SB_DISABLE_SELF_RWX )
23
72
/* Disabling R_X has to be done while running from RAM for obvious reasons.
24
73
* Moreover as a last step before jumping to application it must work even after
29
78
*/
30
79
#include <hal/nrf_rramc.h>
31
80
32
- #define FUNCTION_BUFFER_LEN 64
33
81
#define RRAMC_REGION_RWX_LSB 0
34
82
#define RRAMC_REGION_RWX_WIDTH 3
35
83
#define RRAMC_REGION_TO_LOCK_ADDR NRF_RRAMC->REGION[3].CONFIG
36
84
#define RRAMC_REGION_TO_LOCK_ADDR_H (((uint32_t)(&(RRAMC_REGION_TO_LOCK_ADDR))) >> 16)
37
85
#define RRAMC_REGION_TO_LOCK_ADDR_L (((uint32_t)(&(RRAMC_REGION_TO_LOCK_ADDR))) & 0x0000fffful)
38
- static uint8_t ram_exec_buf [FUNCTION_BUFFER_LEN ];
39
86
#endif /* CONFIG_SB_DISABLE_SELF_RWX */
40
87
88
+ static void __ramfunc jump_in (uint32_t * vector_table )
89
+ {
90
+ __asm__ volatile (
91
+
92
+ /* vector_table[1] -> r0 */
93
+ " mov r0, %0\n"
94
+ #ifdef CONFIG_SB_CLEANUP_RAM
95
+ /* Base to write -> r1 */
96
+ " mov r1, %1\n"
97
+ /* Size to write -> r2 */
98
+ " mov r2, %2\n"
99
+ /* Value to write -> r3 */
100
+ " movw r3, %5\n"
101
+ "clear_first:\n"
102
+ " str r3, [r1]\n"
103
+ " add r1, r1, #4\n"
104
+ " sub r2, r2, #4\n"
105
+ " cbz r2, clear_next\n"
106
+ " b clear_first\n"
107
+ "clear_next:\n"
108
+ /* Base to write -> r1 */
109
+ " mov r1, %3\n"
110
+ /* Size to write -> r2 */
111
+ " mov r2, %4\n"
112
+ "clear_second:\n"
113
+ " str r3, [r1]\n"
114
+ " add r1, r1, #4\n"
115
+ " sub r2, r2, #4\n"
116
+ " cbz r2, out\n"
117
+ " b clear_second\n"
118
+ "out:\n"
119
+ " dsb\n"
120
+ #endif /* CONFIG_SB_CLEANUP_RAM */
121
+
122
+ #ifdef CONFIG_SB_DISABLE_SELF_RWX
123
+ ".thumb_func \n "
124
+ "bootconf_disable_rwx :\n "
125
+ " mov r0 , %0 \n "
126
+ " movw r1 , %6 \n "
127
+ " movt r1 , %7 \n "
128
+ " ldr r2 , [r1 ]\n "
129
+ /* Size of the region should be set at this point
130
+ * by provisioning through BOOTCONF.
131
+ * If not, set it according partition size.
132
+ */
133
+ " ands r4 , r2 , %12 \n "
134
+ " cbnz r4 , rrclear_rwx \n "
135
+ " movt r2 , %8 \n "
136
+ " rrclear_rwx :\n "
137
+ " bfc r2 , %9 , %10 \n "
138
+ /* Disallow further modifications */
139
+ " orr r2 , %11 \n "
140
+ " str r2 , [r1 ]\n "
141
+ " dsb \n "
142
+ /* Next assembly line is important for current function */
143
+
144
+ #endif /* CONFIG_SB_DISABLE_SELF_RWX */
145
+
146
+ /* Jump to reset vector of an app */
147
+ " bx r0 \n "
148
+ :
149
+ : " r " (vector_table),
150
+ " i " (CLEANUP_RAM_FIRST_START),
151
+ " i " (CLEANUP_RAM_FIRST_SIZE),
152
+ " r " (CLEANUP_RAM_SECOND_START),
153
+ " r " (CLEANUP_RAM_SECOND_SIZE),
154
+ " i " (0),
155
+ #ifdef CONFIG_SB_DISABLE_SELF_RWX
156
+ " i " (RRAMC_REGION_TO_LOCK_ADDR_L),
157
+ " i " (RRAMC_REGION_TO_LOCK_ADDR_H),
158
+ " i " (CONFIG_PM_PARTITION_SIZE_B0_IMAGE / 1024),
159
+ " i " (RRAMC_REGION_RWX_LSB),
160
+ " i " (RRAMC_REGION_RWX_WIDTH),
161
+ " i " (RRAMC_REGION_CONFIG_LOCK_Msk),
162
+ " i " (RRAMC_REGION_CONFIG_SIZE_Msk)
163
+ #endif /* CONFIG_SB_DISABLE_SELF_RWX */
164
+ : " r0 ", " r1 ", " r2 ", " r3 ", " r4 ", " r5 ", " memory "
165
+ );
166
+ }
167
+
41
168
#ifdef CONFIG_UART_NRFX_UARTE
42
169
static void uninit_used_uarte (NRF_UARTE_Type * p_reg )
43
170
{
@@ -163,6 +290,13 @@ void bl_boot(const struct fw_info *fw_info)
163
290
VTOR = fw_info -> address ;
164
291
uint32_t * vector_table = (uint32_t * )fw_info -> address ;
165
292
293
+ #if defined(CONFIG_SB_DISABLE_NEXT_W )
294
+ if (disable_next_w ()) {
295
+ printk ("Unable to disable writes on next stage." );
296
+ return ;
297
+ }
298
+ #endif
299
+
166
300
#if defined(CONFIG_BUILTIN_STACK_GUARD ) && \
167
301
defined(CONFIG_CPU_CORTEX_M_HAS_SPLIM )
168
302
/* Reset limit registers to avoid inflicting stack overflow on image
@@ -175,96 +309,7 @@ void bl_boot(const struct fw_info *fw_info)
175
309
__set_MSP (vector_table [0 ]);
176
310
__set_PSP (0 );
177
311
178
- __asm__ volatile (
179
- /* vector_table[1] -> r0 */
180
- " mov r0, %0\n"
181
- #ifdef CONFIG_SB_CLEANUP_RAM
182
- /* Base to write -> r1 */
183
- " mov r1, %1\n"
184
- /* Size to write -> r2 */
185
- " mov r2, %2\n"
186
- /* Value to write -> r3 */
187
- " movw r3, %3\n"
188
- "clear:\n"
189
- " str r3, [r1]\n"
190
- " add r1, r1, #4\n"
191
- " sub r2, r2, #4\n"
192
- " cbz r2, out\n"
193
- " b clear\n"
194
- "out:\n"
195
- " dsb\n"
196
- #endif /* CONFIG_SB_CLEANUP_RAM */
197
-
198
- #ifdef CONFIG_SB_DISABLE_SELF_RWX
199
- /* FUNCTION_BUFFER_LEN */
200
- " movw r4, %4\n"
201
- /* Address of ram_exec_buf goes to r2 */
202
- " mov r2, %5\n"
203
- " movw r3, :lower16:bootconf_disable_rwx\n"
204
- " movt r3, :upper16:bootconf_disable_rwx\n"
205
- /* Adjust address for thumb */
206
- " and r3, #0xfffffffe\n"
207
- /* Address of ram_exec_buf also goes to r5 */
208
- " mov r5, %5\n"
209
- /* Adjust buffer address for thumb */
210
- " orr r5, #0x1\n"
211
- /* End of the copy address in r4 */
212
- " add r4, r2\n"
213
- "ram_cpy:\n"
214
- /* Read and increment */
215
- " ldrb r1, [r3], #1\n"
216
- /* Write and increment */
217
- " strb r1, [r2], #1\n"
218
- /* Check if end address is reached */
219
- " cmp r2, r4\n"
220
- " bne ram_cpy\n"
221
- " dsb\n"
222
- /* Jump to ram */
223
- " bx r5\n"
224
- /* CODE_UNREACHABLE */
225
-
226
- ".thumb_func\n"
227
- "bootconf_disable_rwx:\n"
228
- " movw r1, %6\n"
229
- " movt r1, %7\n"
230
- " ldr r2, [r1]\n"
231
- /* Size of the region should be set at this point
232
- * by provisioning through BOOTCONF.
233
- * If not, set it according partition size.
234
- */
235
- " ands r4, r2, %12\n"
236
- " cbnz r4, clear_rwx\n"
237
- " movt r2, %8\n"
238
- "clear_rwx:\n"
239
- " bfc r2, %9, %10\n"
240
- /* Disallow further modifications */
241
- " orr r2, %11\n"
242
- " str r2, [r1]\n"
243
- " dsb\n"
244
- /* Next assembly line is important for current function */
245
-
246
- #endif /* CONFIG_SB_DISABLE_SELF_RWX */
247
-
248
- /* Jump to reset vector of an app */
249
- " bx r0 \n "
250
- :
251
- : "r" (vector_table [1 ]),
252
- "i" (CONFIG_SRAM_BASE_ADDRESS ),
253
- "i" (CONFIG_SRAM_SIZE * 1024 ),
254
- "i" (0 )
255
- #ifdef CONFIG_SB_DISABLE_SELF_RWX
256
- , "i" (FUNCTION_BUFFER_LEN ),
257
- "r" (ram_exec_buf ),
258
- "i" (RRAMC_REGION_TO_LOCK_ADDR_L ),
259
- "i" (RRAMC_REGION_TO_LOCK_ADDR_H ),
260
- "i" (CONFIG_PM_PARTITION_SIZE_B0_IMAGE / 1024 ),
261
- "i" (RRAMC_REGION_RWX_LSB ),
262
- "i" (RRAMC_REGION_RWX_WIDTH ),
263
- "i" (RRAMC_REGION_CONFIG_LOCK_Msk ),
264
- "i" (RRAMC_REGION_CONFIG_SIZE_Msk )
265
- #endif /* CONFIG_SB_DISABLE_SELF_RWX */
266
- : "r0" , "r1" , "r2" , "r3" , "r4" , "r5" , "memory"
267
- );
312
+ jump_in ((vector_table [1 ]));
268
313
269
314
CODE_UNREACHABLE ;
270
315
}
0 commit comments