@@ -148,6 +148,30 @@ K_SEM_DEFINE(boot_log_sem, 1, 1);
148
148
#include <nrf_cleanup.h>
149
149
#endif
150
150
151
+ #include <zephyr/linker/linker-defs.h>
152
+ #define CLEANUP_RAM_GAP_START ((int)__ramfunc_region_start)
153
+ #define CLEANUP_RAM_GAP_END ((int)__ramfunc_end)
154
+ #define CLEANUP_RAM_GAP_SIZE ((int) (__ramfunc_end - __ramfunc_region_start))
155
+
156
+ #if defined(CONFIG_MCUBOOT_DISABLE_SELF_RWX )
157
+ /* Disabling R_X has to be done while running from RAM for obvious reasons.
158
+ * Moreover as a last step before jumping to application it must work even after
159
+ * RAM has been cleared, therefore we are using custom RAM function relocator.
160
+ * This relocator runs after RAM cleanup.
161
+ * Size of the relocated 'locking' function isn't known but it doesn't matter
162
+ * as long as at least entire aforementioned function is copied to RAM.
163
+ */
164
+ #include <hal/nrf_rramc.h>
165
+
166
+ #define RRAMC_REGION_RWX_LSB 0
167
+ #define RRAMC_REGION_RWX_WIDTH 3
168
+ #define RRAMC_REGION_TO_LOCK_ADDR NRF_RRAMC->REGION[4].CONFIG
169
+ #define RRAMC_REGION_TO_LOCK_ADDR_H (((uint32_t)(&(RRAMC_REGION_TO_LOCK_ADDR))) >> 16)
170
+ #define RRAMC_REGION_TO_LOCK_ADDR_L (((uint32_t)(&(RRAMC_REGION_TO_LOCK_ADDR))) & 0x0000fffful)
171
+ #endif /* CONFIG_MCUBOOT_DISABLE_SELF_RWX */
172
+
173
+
174
+
151
175
BOOT_LOG_MODULE_REGISTER (mcuboot );
152
176
153
177
void os_heap_init (void );
@@ -163,6 +187,84 @@ struct arm_vector_table {
163
187
uint32_t reset ;
164
188
};
165
189
190
+ static void __ramfunc jump_in (uint32_t vector_table )
191
+ {
192
+ __asm__ volatile (
193
+
194
+ /* vector_table[1] -> r0 */
195
+ " mov r0, %0\n"
196
+ #ifdef CONFIG_MCUBOOT_CLEANUP_RAM
197
+ /* Base to write -> r1 */
198
+ " mov r1, %1\n"
199
+ /* Size to write -> r2 */
200
+ " mov r2, %2\n"
201
+ /* Value to write -> r3 */
202
+ " movw r3, %5\n"
203
+ /* gap start */
204
+ " mov r4, %3\n"
205
+ /* gap size */
206
+ " mov r5, %4\n"
207
+ "clear_first:\n"
208
+ " subs r6, r4, r1 \n"
209
+ " cbnz r6, skip_gap \n"
210
+ " add r1, r5 \n"
211
+ " skip_gap: \n"
212
+ " str r3, [r1]\n"
213
+ " add r1, r1, #1\n"
214
+ " sub r2, r2, #1\n"
215
+ " cbz r2, out\n"
216
+ " b clear_first\n"
217
+ "out:\n"
218
+ " dsb\n"
219
+ #ifdef CONFIG_MCUBOOT_INFINITE_LOOP_AFTER_RAM_CLEANUP
220
+ " b out\n"
221
+ #endif /*CONFIG_MCUBOOT_INFINITE_LOOP_AFTER_RAM_CLEANUP */
222
+ #endif /* CONFIG_MCUBOOT_CLEANUP_RAM */
223
+ #ifdef CONFIG_MCUBOOT_DISABLE_SELF_RWX
224
+ ".thumb_func \n "
225
+ "region_disable_rwx :\n "
226
+ " movw r1 , %6 \n "
227
+ " movt r1 , %7 \n "
228
+ " ldr r2 , [r1 ]\n "
229
+ /* Size of the region should be set at this point
230
+ * by NSIB's DISABLE_NEXT_W.
231
+ * If not, set it according partition size.
232
+ */
233
+ " ands r4 , r2 , %12 \n "
234
+ " cbnz r4 , clear_rwx \n "
235
+ " movt r2 , %8 \n "
236
+ " clear_rwx :\n "
237
+ " bfc r2 , %9 , %10 \n "
238
+ /* Disallow further modifications */
239
+ " orr r2 , %11 \n "
240
+ " str r2 , [r1 ]\n "
241
+ " dsb \n "
242
+ /* Next assembly line is important for current function */
243
+
244
+ #endif /* CONFIG_MCUBOOT_DISABLE_SELF_RWX */
245
+
246
+ /* Jump to reset vector of an app */
247
+ " bx r0 \n "
248
+ :
249
+ : " r " (vector_table),
250
+ " r " (CONFIG_SRAM_BASE_ADDRESS),
251
+ " i " (CONFIG_SRAM_SIZE * 1024),
252
+ " r " (CLEANUP_RAM_GAP_START),
253
+ " r " (CLEANUP_RAM_GAP_SIZE),
254
+ " i " (0xaa)
255
+ #ifdef CONFIG_MCUBOOT_DISABLE_SELF_RWX
256
+ ," i " (RRAMC_REGION_TO_LOCK_ADDR_L),
257
+ " i " (RRAMC_REGION_TO_LOCK_ADDR_H),
258
+ " i " (CONFIG_PM_PARTITION_SIZE_B0_IMAGE / 1024),
259
+ " i " (RRAMC_REGION_RWX_LSB),
260
+ " i " (RRAMC_REGION_RWX_WIDTH),
261
+ " i " (RRAMC_REGION_CONFIG_LOCK_Msk),
262
+ " i " (RRAMC_REGION_CONFIG_SIZE_Msk)
263
+ #endif /* CONFIG_MCUBOOT_DISABLE_SELF_RWX */
264
+ : " r0 ", " r1 ", " r2 ", " r3 ", " r4 ", " r5 ", " memory "
265
+ );
266
+ }
267
+
166
268
static void do_boot (struct boot_rsp * rsp )
167
269
{
168
270
/* vt is static as it shall not land on the stack,
@@ -276,37 +378,7 @@ static void do_boot(struct boot_rsp *rsp)
276
378
__set_CONTROL (0x00 ); /* application will configures core on its own */
277
379
__ISB ();
278
380
#endif
279
- #if CONFIG_MCUBOOT_CLEANUP_RAM
280
- __asm__ volatile (
281
- /* vt->reset -> r0 */
282
- " mov r0, %0\n"
283
- /* base to write -> r1 */
284
- " mov r1, %1\n"
285
- /* size to write -> r2 */
286
- " mov r2, %2\n"
287
- /* value to write -> r3 */
288
- " mov r3, %3\n"
289
- "clear:\n"
290
- " str r3, [r1]\n"
291
- " add r1, r1, #4\n"
292
- " sub r2, r2, #4\n"
293
- " cbz r2, out\n"
294
- " b clear\n"
295
- "out:\n"
296
- " dsb\n"
297
- #if CONFIG_MCUBOOT_INFINITE_LOOP_AFTER_RAM_CLEANUP
298
- " b out\n"
299
- #endif /*CONFIG_MCUBOOT_INFINITE_LOOP_AFTER_RAM_CLEANUP */
300
- /* jump to reset vector of an app */
301
- " bx r0\n"
302
- :
303
- : "r" (vt -> reset ), "i" (CONFIG_SRAM_BASE_ADDRESS ),
304
- "i" (CONFIG_SRAM_SIZE * 1024 ), "i" (0 )
305
- : "r0" , "r1" , "r2" , "r3" , "memory"
306
- );
307
- #else
308
- ((void (* )(void ))vt -> reset )();
309
- #endif
381
+ jump_in (vt -> reset );
310
382
}
311
383
312
384
#elif defined(CONFIG_XTENSA ) || defined(CONFIG_RISCV )
0 commit comments