Skip to content

Commit

Permalink
Bring up WAMR on esp32-s3 device (#2348)
Browse files Browse the repository at this point in the history
esp32-s3's instruction memory and data memory can be accessed through mutual mirroring way,
so we define a new feature named as WASM_MEM_DUAL_BUS_MIRROR.
  • Loading branch information
dongsheng28849455 authored Jul 20, 2023
1 parent 57abdfd commit fbe072c
Show file tree
Hide file tree
Showing 6 changed files with 122 additions and 3 deletions.
11 changes: 11 additions & 0 deletions core/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -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_ */
12 changes: 12 additions & 0 deletions core/iwasm/aot/aot_loader.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)) {
Expand Down Expand Up @@ -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;

Expand Down
10 changes: 9 additions & 1 deletion core/iwasm/aot/arch/aot_reloc_xtensa.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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 */
Expand All @@ -285,7 +294,6 @@ apply_relocation(AOTModule *module, uint8 *target_section_addr,
#if __GNUC__ >= 9
#pragma GCC diagnostic pop
#endif

break;
}

Expand Down
5 changes: 5 additions & 0 deletions core/shared/platform/include/platform_api_vmcore.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
81 changes: 79 additions & 2 deletions core/shared/platform/nuttx/nuttx_platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,46 @@
#include <nuttx/arch.h>
#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()
{
Expand Down Expand Up @@ -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);
Expand All @@ -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);
}

Expand All @@ -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
Expand All @@ -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)
Expand Down
6 changes: 6 additions & 0 deletions product-mini/platforms/nuttx/wamr.mk
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit fbe072c

Please sign in to comment.