summaryrefslogtreecommitdiff
path: root/py/emitglue.c
diff options
context:
space:
mode:
Diffstat (limited to 'py/emitglue.c')
-rw-r--r--py/emitglue.c25
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;