This is an automated email from the ASF dual-hosted git repository.

pkarashchenko pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new 73678c4839 xtensa/esp32: Allow allocation of user data in SPI RAM
73678c4839 is described below

commit 73678c4839285f4af6a4a920757085cb73fc0d69
Author: Gustavo Henrique Nihei <gustavo.ni...@espressif.com>
AuthorDate: Mon Jun 6 17:34:51 2022 -0300

    xtensa/esp32: Allow allocation of user data in SPI RAM
    
    Signed-off-by: Gustavo Henrique Nihei <gustavo.ni...@espressif.com>
---
 arch/xtensa/src/esp32/Kconfig                      | 20 +++++-
 arch/xtensa/src/esp32/chip_macros.h                | 14 +++-
 arch/xtensa/src/esp32/esp32_allocateheap.c         | 76 +++++++++------------
 arch/xtensa/src/esp32/esp32_psram.c                |  4 ++
 arch/xtensa/src/esp32/esp32_userspace.c            | 78 ++++++++++++++++++++++
 .../esp32/common/scripts/protected.template.ld     | 12 ++++
 6 files changed, 157 insertions(+), 47 deletions(-)

diff --git a/arch/xtensa/src/esp32/Kconfig b/arch/xtensa/src/esp32/Kconfig
index dd34818a57..94869aedde 100644
--- a/arch/xtensa/src/esp32/Kconfig
+++ b/arch/xtensa/src/esp32/Kconfig
@@ -624,7 +624,7 @@ config ESP32_SPI3
 config ESP32_SPIRAM
        bool "SPI RAM Support"
        default n
-       select ARCH_HAVE_HEAP2
+       select ARCH_HAVE_HEAP2 if !ESP32_USER_DATA_EXTMEM
        select XTENSA_IMEM_USE_SEPARATE_HEAP
 
 if ESP32_SPIRAM && SMP
@@ -1362,7 +1362,7 @@ endchoice # ESP32_SPIRAM_SPEED
 
 config ESP32_SPIRAM_BOOT_INIT
        bool "Initialize SPI RAM during startup"
-       depends on ESP32_SPIRAM
+       depends on ESP32_SPIRAM && !ESP32_USER_DATA_EXTMEM
        default y
        ---help---
                If this is enabled, the SPI RAM will be enabled during initial
@@ -1894,6 +1894,22 @@ config ESP32_USER_IMAGE_OFFSET
        ---help---
                Offset in SPI Flash for flashing the User application firmware 
image.
 
+config ESP32_USER_DATA_EXTMEM
+       bool "Allocate user data in SPI RAM (READ HELP FIRST)"
+       default n
+       depends on ESP32_SPIRAM && EXPERIMENTAL
+       ---help---
+               Allocate all data from User application firmware image in the 
external
+               SPI RAM.
+
+               Enabling this configuration comes with the restriction of 
running the Userspace
+               with high privilege (same as Kernel space), which in turn makes 
the execution
+               under Protected Mode not really protected.
+
+               This feature is intended to allow experimentation of Protected 
Mode on ESP32 and
+               should not be used in production. Protected mode on ESP32 is 
only supported with
+               PSRAM disabled.
+
 endif
 
 source "arch/xtensa/src/esp32/Kconfig.security"
diff --git a/arch/xtensa/src/esp32/chip_macros.h 
b/arch/xtensa/src/esp32/chip_macros.h
index e5fe6a7c89..b42c098121 100644
--- a/arch/xtensa/src/esp32/chip_macros.h
+++ b/arch/xtensa/src/esp32/chip_macros.h
@@ -57,8 +57,18 @@
 
 /* Definitions for the PIDs reserved for Kernel and Userspace */
 
-#define PIDCTRL_PID_KERNEL              0   /* Privileged */
-#define PIDCTRL_PID_USER                5   /* Non-privileged */
+#  define PIDCTRL_PID_KERNEL            0   /* Privileged */
+
+#ifdef CONFIG_ESP32_USER_DATA_EXTMEM
+
+/* Allocating user data in External RAM is currently limited to only using
+ * privileged PIDs (0 and 1).
+ */
+
+#  define PIDCTRL_PID_USER              1   /* Privileged */
+#else
+#  define PIDCTRL_PID_USER              5   /* Non-privileged */
+#endif
 
 /* Macros for privilege handling with the PID Controller peripheral */
 
diff --git a/arch/xtensa/src/esp32/esp32_allocateheap.c 
b/arch/xtensa/src/esp32/esp32_allocateheap.c
index 6146f55cb0..484340affa 100644
--- a/arch/xtensa/src/esp32/esp32_allocateheap.c
+++ b/arch/xtensa/src/esp32/esp32_allocateheap.c
@@ -49,6 +49,12 @@
  * Pre-processor Definitions
  ****************************************************************************/
 
+#ifdef CONFIG_BUILD_PROTECTED
+#  define MM_ADDREGION kmm_addregion
+#else
+#  define MM_ADDREGION umm_addregion
+#endif
+
 /****************************************************************************
  * Public Functions
  ****************************************************************************/
@@ -75,6 +81,11 @@ void up_allocate_heap(void **heap_start, size_t *heap_size)
   uintptr_t utop  = USERSPACE->us_heapend;
   size_t    usize = utop - ubase;
 
+#if defined(CONFIG_ESP32_USER_DATA_EXTMEM) && \
+    defined(CONFIG_ESP32_SPIRAM_BANKSWITCH_ENABLE)
+  usize -= esp_himem_reserved_area_size();
+#endif
+
   minfo("Heap: start=%" PRIxPTR " end=%" PRIxPTR " size=%zu\n",
         ubase, utop, usize);
 
@@ -84,9 +95,6 @@ void up_allocate_heap(void **heap_start, size_t *heap_size)
 
   *heap_start = (void *)ubase;
   *heap_size  = usize;
-
-  /* Allow user-mode access to the user heap memory */
-
 #else
   board_autoled_on(LED_HEAPALLOCATE);
 
@@ -160,66 +168,48 @@ void xtensa_add_region(void)
   availregions = 2;
 #endif
 
-#ifdef CONFIG_ESP32_SPIRAM
+#if defined(CONFIG_ESP32_SPIRAM) && !defined(CONFIG_BUILD_PROTECTED)
   availregions++;
 #endif
 
   if (nregions < availregions)
     {
       mwarn("Some memory regions are left unused!\n");
-      mwarn("Increase CONFIG_MM_NREGIONS to add them to the heap\n");
+      mwarn("Increase CONFIG_MM_REGIONS to add them to the heap\n");
     }
 
-#ifndef CONFIG_SMP
-  start = (void *)(HEAP_REGION2_START + XTENSA_IMEM_REGION_SIZE);
-  size  = (size_t)(uintptr_t)_eheap - (size_t)start;
-#ifdef CONFIG_BUILD_PROTECTED
-  kmm_addregion(start, size);
-#else
-  umm_addregion(start, size);
-#endif
-#else
+#ifdef CONFIG_SMP
   start = (void *)HEAP_REGION2_START;
   size  = (size_t)(HEAP_REGION2_END - HEAP_REGION2_START);
-#ifdef CONFIG_BUILD_PROTECTED
-  kmm_addregion(start, size);
-#else
-  umm_addregion(start, size);
+  MM_ADDREGION(start, size);
 #endif
 
-  start = (void *)HEAP_REGION3_START + XTENSA_IMEM_REGION_SIZE;
+  /* Skip internal heap region if CONFIG_XTENSA_IMEM_USE_SEPARATE_HEAP is
+   * enabled.
+   */
+
+  start = (void *)ESP32_IMEM_START + XTENSA_IMEM_REGION_SIZE;
   size  = (size_t)(uintptr_t)_eheap - (size_t)start;
-#ifdef CONFIG_BUILD_PROTECTED
-  kmm_addregion(start, size);
-#else
-  umm_addregion(start, size);
-#endif
-#endif
+  MM_ADDREGION(start, size);
 
 #ifndef CONFIG_ESP32_BLE
   start = (void *)HEAP_REGION0_START;
   size  = (size_t)(HEAP_REGION0_END - HEAP_REGION0_START);
-#ifdef CONFIG_BUILD_PROTECTED
-  kmm_addregion(start, size);
+  MM_ADDREGION(start, size);
+#endif
+
+#if defined(CONFIG_ESP32_SPIRAM) && defined(CONFIG_ARCH_HAVE_HEAP2)
+#ifdef CONFIG_XTENSA_EXTMEM_BSS
+  start = (void *)(_ebss_extmem);
+  size = CONFIG_HEAP2_SIZE - (size_t)(_ebss_extmem - _sbss_extmem);
 #else
-  umm_addregion(start, size);
+  start = (void *)CONFIG_HEAP2_BASE;
+  size = CONFIG_HEAP2_SIZE;
 #endif
+#ifdef CONFIG_ESP32_SPIRAM_BANKSWITCH_ENABLE
+  size -= esp_himem_reserved_area_size();
 #endif
-
-#ifdef CONFIG_ESP32_SPIRAM
-#  if defined(CONFIG_HEAP2_BASE) && defined(CONFIG_HEAP2_SIZE)
-#    ifdef CONFIG_XTENSA_EXTMEM_BSS
-      start = _ebss_extmem;
-      size = CONFIG_HEAP2_SIZE - (_ebss_extmem - _sbss_extmem);
-#    else
-      start = (void *)CONFIG_HEAP2_BASE;
-      size = CONFIG_HEAP2_SIZE;
-#    endif
-#  ifdef CONFIG_ESP32_SPIRAM_BANKSWITCH_ENABLE
-    size -= esp_himem_reserved_area_size();
-#  endif
-    umm_addregion(start, size);
-#  endif
+  MM_ADDREGION(start, size);
 #endif
 }
 #endif
diff --git a/arch/xtensa/src/esp32/esp32_psram.c 
b/arch/xtensa/src/esp32/esp32_psram.c
index 7ecda4981f..16e42b01aa 100644
--- a/arch/xtensa/src/esp32/esp32_psram.c
+++ b/arch/xtensa/src/esp32/esp32_psram.c
@@ -715,7 +715,9 @@ psram_cmd_recv_start(psram_spi_num_t spi_num,
 
   while (getreg32(SPI_EXT2_REG(0)) != 0);
 
+#ifndef CONFIG_ESP32_USER_DATA_EXTMEM
   modifyreg32(DPORT_HOST_INF_SEL_REG, 0, 1 << 14);
+#endif
 
   /* Start send data */
 
@@ -723,7 +725,9 @@ psram_cmd_recv_start(psram_spi_num_t spi_num,
 
   while ((getreg32(SPI_CMD_REG(spi_num)) & SPI_USR));
 
+#ifndef CONFIG_ESP32_USER_DATA_EXTMEM
   modifyreg32(DPORT_HOST_INF_SEL_REG, 1 << 14, 0);
+#endif
 
   /* recover spi mode */
 
diff --git a/arch/xtensa/src/esp32/esp32_userspace.c 
b/arch/xtensa/src/esp32/esp32_userspace.c
index fdf9e30d19..a30555c6e4 100644
--- a/arch/xtensa/src/esp32/esp32_userspace.c
+++ b/arch/xtensa/src/esp32/esp32_userspace.c
@@ -36,6 +36,9 @@
 #include "chip.h"
 #include "xtensa.h"
 #include "xtensa_attr.h"
+#ifdef CONFIG_ESP32_USER_DATA_EXTMEM
+#include "esp32_spiram.h"
+#endif
 #include "esp32_userspace.h"
 #include "hardware/esp32_dport.h"
 #include "hardware/esp32_pid.h"
@@ -188,6 +191,49 @@ static noinline_function IRAM_ATTR void 
configure_flash_mmu(void)
   cache_read_enable(0);
 }
 
+/****************************************************************************
+ * Name: configure_sram_mmu
+ *
+ * Description:
+ *   Configure the External SRAM MMU and Cache for enabling access to the
+ *   data of the userspace image.
+ *
+ * Input Parameters:
+ *   None.
+ *
+ * Returned Value:
+ *   None.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_ESP32_USER_DATA_EXTMEM
+static noinline_function IRAM_ATTR void configure_sram_mmu(void)
+{
+#ifdef CONFIG_SMP
+  uint32_t regval;
+#endif
+
+  /* Enable external RAM in MMU */
+
+  ASSERT(cache_sram_mmu_set(0, PIDCTRL_PID_KERNEL, SOC_EXTRAM_DATA_LOW, 0,
+                            32, 128) == 0);
+  ASSERT(cache_sram_mmu_set(0, PIDCTRL_PID_USER, SOC_EXTRAM_DATA_LOW, 0,
+                            32, 128) == 0);
+
+  /* Flush and enable icache for APP CPU */
+
+#ifdef CONFIG_SMP
+  regval  = getreg32(DPORT_APP_CACHE_CTRL1_REG);
+  regval &= ~(1 << DPORT_APP_CACHE_MASK_DRAM1);
+  putreg32(regval, DPORT_APP_CACHE_CTRL1_REG);
+  ASSERT(cache_sram_mmu_set(1, PIDCTRL_PID_KERNEL, SOC_EXTRAM_DATA_LOW, 0,
+                            32, 128) == 0);
+  ASSERT(cache_sram_mmu_set(1, PIDCTRL_PID_USER, SOC_EXTRAM_DATA_LOW, 0,
+                            32, 128) == 0);
+#endif
+}
+#endif
+
 /****************************************************************************
  * Name: map_flash
  *
@@ -322,6 +368,24 @@ static void configure_mpu(void)
   REG_SET_FIELD(DPORT_IMMU_TABLE14_REG, DPORT_IMMU_TABLE14, 0x0e);
   REG_SET_FIELD(DPORT_IMMU_TABLE15_REG, DPORT_IMMU_TABLE15, 0x0f);
 
+#ifdef CONFIG_ESP32_USER_DATA_EXTMEM
+  REG_SET_FIELD(DPORT_DMMU_TABLE0_REG,  DPORT_DMMU_TABLE0,  0x00);
+  REG_SET_FIELD(DPORT_DMMU_TABLE1_REG,  DPORT_DMMU_TABLE1,  0x01);
+  REG_SET_FIELD(DPORT_DMMU_TABLE2_REG,  DPORT_DMMU_TABLE2,  0x02);
+  REG_SET_FIELD(DPORT_DMMU_TABLE3_REG,  DPORT_DMMU_TABLE3,  0x03);
+  REG_SET_FIELD(DPORT_DMMU_TABLE4_REG,  DPORT_DMMU_TABLE4,  0x04);
+  REG_SET_FIELD(DPORT_DMMU_TABLE5_REG,  DPORT_DMMU_TABLE5,  0x05);
+  REG_SET_FIELD(DPORT_DMMU_TABLE6_REG,  DPORT_DMMU_TABLE6,  0x06);
+  REG_SET_FIELD(DPORT_DMMU_TABLE7_REG,  DPORT_DMMU_TABLE7,  0x07);
+  REG_SET_FIELD(DPORT_DMMU_TABLE8_REG,  DPORT_DMMU_TABLE8,  0x08);
+  REG_SET_FIELD(DPORT_DMMU_TABLE9_REG,  DPORT_DMMU_TABLE9,  0x09);
+  REG_SET_FIELD(DPORT_DMMU_TABLE10_REG, DPORT_DMMU_TABLE10, 0x0a);
+  REG_SET_FIELD(DPORT_DMMU_TABLE11_REG, DPORT_DMMU_TABLE11, 0x0b);
+  REG_SET_FIELD(DPORT_DMMU_TABLE12_REG, DPORT_DMMU_TABLE12, 0x0c);
+  REG_SET_FIELD(DPORT_DMMU_TABLE13_REG, DPORT_DMMU_TABLE13, 0x0d);
+  REG_SET_FIELD(DPORT_DMMU_TABLE14_REG, DPORT_DMMU_TABLE14, 0x0e);
+  REG_SET_FIELD(DPORT_DMMU_TABLE15_REG, DPORT_DMMU_TABLE15, 0x0f);
+#else
   REG_SET_FIELD(DPORT_DMMU_TABLE0_REG,  DPORT_DMMU_TABLE0,  0x00);
   REG_SET_FIELD(DPORT_DMMU_TABLE1_REG,  DPORT_DMMU_TABLE1,  0x01);
   REG_SET_FIELD(DPORT_DMMU_TABLE2_REG,  DPORT_DMMU_TABLE2,  0x02);
@@ -338,6 +402,7 @@ static void configure_mpu(void)
   REG_SET_FIELD(DPORT_DMMU_TABLE13_REG, DPORT_DMMU_TABLE13, 0x5d);
   REG_SET_FIELD(DPORT_DMMU_TABLE14_REG, DPORT_DMMU_TABLE14, 0x5e);
   REG_SET_FIELD(DPORT_DMMU_TABLE15_REG, DPORT_DMMU_TABLE15, 0x5f);
+#endif
 
   /* Configure interrupt vector addresses in PID Controller */
 
@@ -399,6 +464,19 @@ void esp32_userspace(void)
 
   configure_flash_mmu();
 
+#ifdef CONFIG_ESP32_USER_DATA_EXTMEM
+  if (esp_spiram_init() != OK)
+    {
+      mwarn("SPI RAM initialization failed!\n");
+
+      PANIC();
+    }
+
+  /* Configure the SRAM MMU for enabling access to the userspace image */
+
+  configure_sram_mmu();
+#endif
+
   /* Clear all of userspace .bss */
 
   DEBUGASSERT(USERSPACE->us_bssstart != 0 && USERSPACE->us_bssend != 0 &&
diff --git a/boards/xtensa/esp32/common/scripts/protected.template.ld 
b/boards/xtensa/esp32/common/scripts/protected.template.ld
index 80ebe214db..5862de63b7 100644
--- a/boards/xtensa/esp32/common/scripts/protected.template.ld
+++ b/boards/xtensa/esp32/common/scripts/protected.template.ld
@@ -73,6 +73,17 @@ MEMORY
    * the amount of RAM available to the NuttX Kernel.
    */
 
+#ifdef CONFIG_ESP32_USER_DATA_EXTMEM
+  /* Physically located in External RAM */
+  UDRAM (RW)   : org = 0x3f800000, len = 0x400000
+
+  /* Physically located in SRAM2 */
+  KDRAM_0 (RW) : org = 0x3ffb0000 + CONFIG_ESP32_BT_RESERVE_DRAM,
+                 len = 0x30000 - CONFIG_ESP32_BT_RESERVE_DRAM
+
+  /* Physically located in SRAM1 */
+  KDRAM_1 (RW) : org = 0x3ffe0000, len = 0x20000
+#else
   /* Physically located in SRAM2 */
   KDRAM_0 (RW) : org = 0x3ffb0000 + CONFIG_ESP32_BT_RESERVE_DRAM,
                  len = 0x18000 - CONFIG_ESP32_BT_RESERVE_DRAM
@@ -80,6 +91,7 @@ MEMORY
 
   /* Physically located in SRAM1 */
   KDRAM_1 (RW) : org = 0x3ffe0000, len = 0x20000
+#endif
 
   /* Flash mapped constant data */
 

Reply via email to