From d5db8f04613b6a7e6f3d55dd8d618e8ccdaecdfa Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 22 Apr 2025 11:50:34 +1000 Subject: [PATCH] nrf: Use correct IRAM address for native code execution on nRF52. On nRF52, the physical SRAM is mapped to 0x20000000 for data access and 0x00800000 for instruction access. So, while native code is allocated and written using addresses in the 0x20000000 range, it must execute from the 0x00800000 range. This commit makes this work correctly on nRF52 MCUs by adjusting the address. Signed-off-by: Damien George --- ports/nrf/main.c | 14 ++++++++++++++ ports/nrf/mpconfigport.h | 12 +++++++++++- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/ports/nrf/main.c b/ports/nrf/main.c index 99ed39895..784a031ce 100644 --- a/ports/nrf/main.c +++ b/ports/nrf/main.c @@ -39,6 +39,7 @@ #include "py/stackctrl.h" #include "py/gc.h" #include "py/compile.h" +#include "py/persistentcode.h" #include "extmod/modmachine.h" #include "shared/runtime/pyexec.h" #include "readline.h" @@ -369,3 +370,16 @@ void MP_WEAK __assert_func(const char *file, int line, const char *func, const c printf("Assertion '%s' failed, at file %s:%d\n", expr, file, line); __fatal_error("Assertion failed"); } + +#if MICROPY_EMIT_MACHINE_CODE +void *nrf_native_code_commit(void *buf, unsigned int len, void *reloc) { + (void)len; + if (reloc) { + // Native code in RAM must execute from the IRAM region at 0x00800000, and so relocations + // to text must also point to this region. The MICROPY_MAKE_POINTER_CALLABLE macro will + // adjust the `buf` address from RAM to IRAM. + mp_native_relocate(reloc, buf, (uintptr_t)MICROPY_MAKE_POINTER_CALLABLE(buf) & ~1); + } + return buf; +} +#endif diff --git a/ports/nrf/mpconfigport.h b/ports/nrf/mpconfigport.h index 7cc8a66d9..8c5c03006 100644 --- a/ports/nrf/mpconfigport.h +++ b/ports/nrf/mpconfigport.h @@ -320,7 +320,17 @@ // type definitions for the specific machine -#define MICROPY_MAKE_POINTER_CALLABLE(p) ((void *)((mp_uint_t)(p) | 1)) +#if defined(NRF52832) || defined(NRF52840) +// On nRF52, the physical SRAM is mapped to 0x20000000 for data access and 0x00800000 +// for instruction access. So convert addresses to make them executable. +#define MICROPY_PERSISTENT_CODE_TRACK_FUN_DATA (1) +#define MICROPY_PERSISTENT_CODE_TRACK_BSS_RODATA (0) +#define MICROPY_MAKE_POINTER_CALLABLE(p) ((void *)(((uintptr_t)(p) - 0x20000000 + 0x00800000) | 1)) +void *nrf_native_code_commit(void *, unsigned int, void *); +#define MP_PLAT_COMMIT_EXEC(buf, len, reloc) nrf_native_code_commit(buf, len, reloc) +#else +#define MICROPY_MAKE_POINTER_CALLABLE(p) ((void *)((uintptr_t)(p) | 1)) +#endif #define MP_SSIZE_MAX (0x7fffffff)