diff options
Diffstat (limited to 'py/emitglue.c')
| -rw-r--r-- | py/emitglue.c | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/py/emitglue.c b/py/emitglue.c index 0ef708a3f..09b48682f 100644 --- a/py/emitglue.c +++ b/py/emitglue.c @@ -108,6 +108,31 @@ void mp_emit_glue_assign_native(mp_raw_code_t *rc, mp_raw_code_kind_t kind, void assert(kind == MP_CODE_NATIVE_PY || kind == MP_CODE_NATIVE_VIPER || kind == MP_CODE_NATIVE_ASM); + // Some architectures require flushing/invalidation of the I/D caches, + // so that the generated native code which was created in data RAM will + // be available for execution from instruction RAM. + #if MICROPY_EMIT_THUMB || MICROPY_EMIT_INLINE_THUMB + #if __ICACHE_PRESENT == 1 + // Flush D-cache, so the code emitted is stored in RAM. + MP_HAL_CLEAN_DCACHE(fun_data, fun_len); + // Invalidate I-cache, so the newly-created code is reloaded from RAM. + SCB_InvalidateICache(); + #endif + #elif MICROPY_EMIT_ARM + #if (defined(__linux__) && defined(__GNUC__)) || __ARM_ARCH == 7 + __builtin___clear_cache(fun_data, (uint8_t *)fun_data + fun_len); + #elif defined(__arm__) + // Flush I-cache and D-cache. + asm volatile ( + "0:" + "mrc p15, 0, r15, c7, c10, 3\n" // test and clean D-cache + "bne 0b\n" + "mov r0, #0\n" + "mcr p15, 0, r0, c7, c7, 0\n" // invalidate I-cache and D-cache + : : : "r0", "cc"); + #endif + #endif + rc->kind = kind; rc->scope_flags = scope_flags; rc->n_pos_args = n_pos_args; |
