Jelajahi Sumber

ESP-IDF platform supports to load AOT to PSRAM and run it (#2385)

dongheng 2 tahun lalu
induk
melakukan
ada7e3fe88

+ 68 - 5
core/shared/platform/esp-idf/espidf_memmap.c

@@ -5,16 +5,34 @@
 
 #include "platform_api_vmcore.h"
 #include "platform_api_extension.h"
+#if (WASM_MEM_DUAL_BUS_MIRROR != 0)
+#include "soc/mmu.h"
+#include "rom/cache.h"
+
+#define MEM_DUAL_BUS_OFFSET (IRAM0_CACHE_ADDRESS_LOW - DRAM0_CACHE_ADDRESS_LOW)
+
+#define in_ibus_ext(addr)                      \
+    (((uint32)addr >= IRAM0_CACHE_ADDRESS_LOW) \
+     && ((uint32)addr < IRAM0_CACHE_ADDRESS_HIGH))
+
+static portMUX_TYPE s_spinlock = portMUX_INITIALIZER_UNLOCKED;
+#endif
 
 void *
 os_mmap(void *hint, size_t size, int prot, int flags)
 {
     if (prot & MMAP_PROT_EXEC) {
+#if (WASM_MEM_DUAL_BUS_MIRROR != 0)
+        uint32_t mem_caps = MALLOC_CAP_SPIRAM;
+#else
+        uint32_t mem_caps = MALLOC_CAP_EXEC;
+#endif
+
         // Memory allocation with MALLOC_CAP_EXEC will return 4-byte aligned
         // Reserve extra 4 byte to fixup alignment and size for the pointer to
         // the originally allocated address
         void *buf_origin =
-            heap_caps_malloc(size + 4 + sizeof(uintptr_t), MALLOC_CAP_EXEC);
+            heap_caps_malloc(size + 4 + sizeof(uintptr_t), mem_caps);
         if (!buf_origin) {
             return NULL;
         }
@@ -25,19 +43,35 @@ os_mmap(void *hint, size_t size, int prot, int flags)
 
         uintptr_t *addr_field = buf_fixed - sizeof(uintptr_t);
         *addr_field = (uintptr_t)buf_origin;
+#if (WASM_MEM_DUAL_BUS_MIRROR != 0)
+        return buf_fixed + MEM_DUAL_BUS_OFFSET;
+#else
         return buf_fixed;
+#endif
     }
     else {
-        return os_malloc(size);
+#if (WASM_MEM_DUAL_BUS_MIRROR != 0)
+        uint32_t mem_caps = MALLOC_CAP_SPIRAM;
+#else
+        uint32_t mem_caps = MALLOC_CAP_8BIT;
+#endif
+        return heap_caps_malloc(size, mem_caps);
     }
 }
 
 void
 os_munmap(void *addr, size_t size)
 {
+    char *ptr = (char *)addr;
+
+#if (WASM_MEM_DUAL_BUS_MIRROR != 0)
+    if (in_ibus_ext(ptr)) {
+        ptr -= MEM_DUAL_BUS_OFFSET;
+    }
+#endif
     // We don't need special handling of the executable allocations
     // here, free() of esp-idf handles it properly
-    return os_free(addr);
+    return os_free(ptr);
 }
 
 int
@@ -47,5 +81,34 @@ os_mprotect(void *addr, size_t size, int prot)
 }
 
 void
-os_dcache_flush()
-{}
+#if (WASM_MEM_DUAL_BUS_MIRROR != 0)
+    IRAM_ATTR
+#endif
+    os_dcache_flush()
+{
+#if (WASM_MEM_DUAL_BUS_MIRROR != 0)
+    uint32_t preload;
+    extern void Cache_WriteBack_All(void);
+
+    portENTER_CRITICAL(&s_spinlock);
+
+    Cache_WriteBack_All();
+    preload = Cache_Disable_ICache();
+    Cache_Enable_ICache(preload);
+
+    portEXIT_CRITICAL(&s_spinlock);
+#endif
+}
+
+#if (WASM_MEM_DUAL_BUS_MIRROR != 0)
+void *
+os_get_dbus_mirror(void *ibus)
+{
+    if (in_ibus_ext(ibus)) {
+        return (void *)((char *)ibus - MEM_DUAL_BUS_OFFSET);
+    }
+    else {
+        return ibus;
+    }
+}
+#endif

+ 6 - 0
core/shared/platform/esp-idf/shared_platform.cmake

@@ -11,3 +11,9 @@ include_directories(${PLATFORM_SHARED_DIR}/../include)
 file (GLOB_RECURSE source_all ${PLATFORM_SHARED_DIR}/*.c)
 
 set (PLATFORM_SHARED_SOURCE ${source_all} ${PLATFORM_COMMON_MATH_SOURCE})
+
+# If enable PSRAM of ESP32-S3, it had better to put AOT into PSRAM, so that
+# users can use SRAM to for Wi-Fi/BLE and peripheral driver.
+if(CONFIG_ESP32S3_SPIRAM_SUPPORT)
+    add_definitions(-DWASM_MEM_DUAL_BUS_MIRROR=1)
+endif()

+ 3 - 1
product-mini/platforms/esp-idf/build_and_run.sh

@@ -5,14 +5,16 @@
 
 ESP32_TARGET="esp32"
 ESP32C3_TARGET="esp32c3"
+ESP32S3_TARGET="esp32s3"
 
 usage ()
 {
         echo "USAGE:"
-        echo "$0 $ESP32_TARGET|$ESP32C3_TARGET"
+        echo "$0 $ESP32_TARGET|$ESP32C3_TARGET|$ESP32S3_TARGET"
         echo "Example:"
         echo "        $0 $ESP32_TARGET"
         echo "        $0 $ESP32C3_TARGET"
+        echo "        $0 $ESP32S3_TARGET"
         exit 1
 }
 

+ 7 - 1
product-mini/platforms/esp-idf/main/main.c

@@ -12,6 +12,12 @@
 
 #include "esp_log.h"
 
+#ifdef CONFIG_IDF_TARGET_ESP32S3
+#define IWASM_MAIN_STACK_SIZE 5120
+#else
+#define IWASM_MAIN_STACK_SIZE 4096
+#endif
+
 #define LOG_TAG "wamr"
 
 static void *
@@ -146,7 +152,7 @@ app_main(void)
     pthread_attr_t tattr;
     pthread_attr_init(&tattr);
     pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_JOINABLE);
-    pthread_attr_setstacksize(&tattr, 4096);
+    pthread_attr_setstacksize(&tattr, IWASM_MAIN_STACK_SIZE);
 
     res = pthread_create(&t, &tattr, iwasm_main, (void *)NULL);
     assert(res == 0);