diff --git a/core/config.h b/core/config.h index f33290f0d..b6198811e 100644 --- a/core/config.h +++ b/core/config.h @@ -461,4 +461,15 @@ #define WASM_CONFIGURABLE_BOUNDS_CHECKS 0 #endif +/* Some chip cannot support external ram with rwx attr at the same time, + it has to map it into 2 spaces of idbus and dbus, code in dbus can be + read/written and read/executed in ibus. so there are 2 steps to execute + the code, first, copy&do relocaiton in dbus space, and second execute + it in ibus space, since in the 2 spaces the contents are the same, + so we call it bus mirror. + */ +#ifndef WASM_MEM_DUAL_BUS_MIRROR +#define WASM_MEM_DUAL_BUS_MIRROR 0 +#endif + #endif /* end of _CONFIG_H_ */ diff --git a/core/iwasm/aot/aot_loader.c b/core/iwasm/aot/aot_loader.c index 2f4dcd31a..50e36f9ee 100644 --- a/core/iwasm/aot/aot_loader.c +++ b/core/iwasm/aot/aot_loader.c @@ -3013,6 +3013,9 @@ create_sections(AOTModule *module, const uint8 *buf, uint32 size, uint32 section_size; uint64 total_size; uint8 *aot_text; +#if (WASM_MEM_DUAL_BUS_MIRROR != 0) + uint8 *mirrored_text; +#endif if (!resolve_execute_mode(buf, size, &is_indirect_mode, error_buf, error_buf_size)) { @@ -3071,8 +3074,17 @@ create_sections(AOTModule *module, const uint8 *buf, uint32 size, bh_assert((uintptr_t)aot_text < INT32_MAX); #endif #endif + +#if (WASM_MEM_DUAL_BUS_MIRROR != 0) + mirrored_text = os_get_dbus_mirror(aot_text); + bh_assert(mirrored_text != NULL); + bh_memcpy_s(mirrored_text, (uint32)total_size, + section->section_body, (uint32)section_size); + os_dcache_flush(); +#else bh_memcpy_s(aot_text, (uint32)total_size, section->section_body, (uint32)section_size); +#endif section->section_body = aot_text; destroy_aot_text = true; diff --git a/core/iwasm/aot/arch/aot_reloc_xtensa.c b/core/iwasm/aot/arch/aot_reloc_xtensa.c index 3327c396f..6ca6a0859 100644 --- a/core/iwasm/aot/arch/aot_reloc_xtensa.c +++ b/core/iwasm/aot/arch/aot_reloc_xtensa.c @@ -207,6 +207,10 @@ apply_relocation(AOTModule *module, uint8 *target_section_addr, case R_XTENSA_32: { uint8 *insn_addr = target_section_addr + reloc_offset; +#if (WASM_MEM_DUAL_BUS_MIRROR != 0) + insn_addr = os_get_dbus_mirror((void *)insn_addr); + bh_assert(insn_addr != NULL); +#endif int32 initial_addend; /* (S + A) */ if ((intptr_t)insn_addr & 3) { @@ -265,6 +269,11 @@ apply_relocation(AOTModule *module, uint8 *target_section_addr, return false; } +#if (WASM_MEM_DUAL_BUS_MIRROR != 0) + insn_addr = os_get_dbus_mirror((void *)insn_addr); + bh_assert(insn_addr != NULL); + l32r_insn = (l32r_insn_t *)insn_addr; +#endif imm16 = (int16)(relative_offset >> 2); /* write back the imm16 to the l32r instruction */ @@ -285,7 +294,6 @@ apply_relocation(AOTModule *module, uint8 *target_section_addr, #if __GNUC__ >= 9 #pragma GCC diagnostic pop #endif - break; } diff --git a/core/shared/platform/include/platform_api_vmcore.h b/core/shared/platform/include/platform_api_vmcore.h index c2f03c9e5..15fc1d387 100644 --- a/core/shared/platform/include/platform_api_vmcore.h +++ b/core/shared/platform/include/platform_api_vmcore.h @@ -129,6 +129,11 @@ os_munmap(void *addr, size_t size); int os_mprotect(void *addr, size_t size, int prot); +#if (WASM_MEM_DUAL_BUS_MIRROR != 0) +void * +os_get_dbus_mirror(void *ibus); +#endif + /** * Flush cpu data cache, in some CPUs, after applying relocation to the * AOT code, the code may haven't been written back to the cpu data cache, diff --git a/core/shared/platform/nuttx/nuttx_platform.c b/core/shared/platform/nuttx/nuttx_platform.c index 9cb123e01..0bd1f6808 100644 --- a/core/shared/platform/nuttx/nuttx_platform.c +++ b/core/shared/platform/nuttx/nuttx_platform.c @@ -10,6 +10,46 @@ #include #endif +#if defined(CONFIG_ARCH_CHIP_ESP32S3) +/* + * TODO: Move these methods below the operating system level + */ +#define MEM_DUAL_BUS_OFFSET (0x42000000 - 0x3C000000) +#define IRAM0_CACHE_ADDRESS_LOW 0x42000000 +#define IRAM0_CACHE_ADDRESS_HIGH 0x44000000 +#define IRAM_ATTR locate_data(".iram1") + +#define in_ibus_ext(addr) \ + (((uint32)addr >= IRAM0_CACHE_ADDRESS_LOW) \ + && ((uint32)addr < IRAM0_CACHE_ADDRESS_HIGH)) +void IRAM_ATTR +bus_sync(void) +{ + extern void cache_writeback_all(void); + extern uint32_t Cache_Disable_ICache(void); + extern void Cache_Enable_ICache(uint32_t autoload); + + irqstate_t flags; + uint32_t preload; + + flags = enter_critical_section(); + + cache_writeback_all(); + preload = Cache_Disable_ICache(); + Cache_Enable_ICache(preload); + + leave_critical_section(flags); +} +#else +#define MEM_DUAL_BUS_OFFSET (0) +#define IRAM0_CACHE_ADDRESS_LOW (0) +#define IRAM0_CACHE_ADDRESS_HIGH (0) +#define in_ibus_ext(addr) (0) +static void +bus_sync(void) +{} +#endif + int bh_platform_init() { @@ -47,6 +87,10 @@ os_dumps_proc_mem_info(char *out, unsigned int size) void * os_mmap(void *hint, size_t size, int prot, int flags) { +#if (WASM_MEM_DUAL_BUS_MIRROR != 0) + void *i_addr, *d_addr; +#endif + #if defined(CONFIG_ARCH_USE_TEXT_HEAP) if ((prot & MMAP_PROT_EXEC) != 0) { return up_textheap_memalign(sizeof(void *), size); @@ -55,6 +99,17 @@ os_mmap(void *hint, size_t size, int prot, int flags) if ((uint64)size >= UINT32_MAX) return NULL; + +#if (WASM_MEM_DUAL_BUS_MIRROR != 0) + if ((prot & MMAP_PROT_EXEC) != 0) { + d_addr = malloc((uint32)size); + if (d_addr == NULL) { + return NULL; + } + i_addr = (void *)((uint8 *)d_addr + MEM_DUAL_BUS_OFFSET); + return in_ibus_ext(i_addr) ? i_addr : d_addr; + } +#endif return malloc((uint32)size); } @@ -67,7 +122,14 @@ os_munmap(void *addr, size_t size) return; } #endif - return free(addr); + +#if (WASM_MEM_DUAL_BUS_MIRROR != 0) + if (in_ibus_ext(addr)) { + free((void *)((uint8 *)addr - MEM_DUAL_BUS_OFFSET)); + return; + } +#endif + free(addr); } int @@ -78,7 +140,22 @@ os_mprotect(void *addr, size_t size, int prot) void os_dcache_flush() -{} +{ + bus_sync(); +} + +#if (WASM_MEM_DUAL_BUS_MIRROR != 0) +void * +os_get_dbus_mirror(void *ibus) +{ + if (in_ibus_ext(ibus)) { + return (void *)((uint8 *)ibus - MEM_DUAL_BUS_OFFSET); + } + else { + return ibus; + } +} +#endif /* If AT_FDCWD is provided, maybe we have openat family */ #if !defined(AT_FDCWD) diff --git a/product-mini/platforms/nuttx/wamr.mk b/product-mini/platforms/nuttx/wamr.mk index 1844dc54b..2a0cec58c 100644 --- a/product-mini/platforms/nuttx/wamr.mk +++ b/product-mini/platforms/nuttx/wamr.mk @@ -141,6 +141,12 @@ else CFLAGS += -DWASM_ENABLE_WORD_ALIGN_READ=0 endif +ifeq ($(CONFIG_INTERPRETERS_WAMR_MEM_DUAL_BUS_MIRROR),y) +CFLAGS += -DWASM_MEM_DUAL_BUS_MIRROR=1 +else +CFLAGS += -DWASM_MEM_DUAL_BUS_MIRROR=0 +endif + ifeq ($(CONFIG_INTERPRETERS_WAMR_FAST), y) CFLAGS += -DWASM_ENABLE_FAST_INTERP=1 CFLAGS += -DWASM_ENABLE_INTERP=1