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

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

commit e66bcd4ecc19410a782404099686fa6144efa32f
Author: Marco Casaroli <[email protected]>
AuthorDate: Wed Oct 21 20:53:28 2026 +0200

    xtensa/esp32s3: Give all of the PSRAM to the page pool in the kernel build.
    
    In the kernel build the internal SRAM is the memory of the kernel and the
    PSRAM is the memory of the processes.  But the boot mapped the whole
    PSRAM into the kernel and took back only the share of the page pool, and
    the pool was a part of the PSRAM: in kernel_oct 4 MB of 8, in kernel_n8r2
    1.5 MB of 2.  Nothing used the rest, and it stayed mapped in the kernel.
    
    Take the whole boot-time mapping of the PSRAM away after the checks, and
    let the pool start at the second page and go to the end of the PSRAM:
    127 pages in kernel_oct and 31 pages in kernel_n8r2.  The first page
    stays out, because the page allocator returns the physical address 0 for
    "no page".  Tell at boot how much of the PSRAM the pool does not use.
    
    Assisted-by: Claude Code:claude-opus-5-5
    Signed-off-by: Marco Casaroli <[email protected]>
---
 arch/xtensa/src/esp32s3/Kconfig                       |  6 +++++-
 arch/xtensa/src/esp32s3/esp32s3_addrenv.h             | 15 ++++++++-------
 arch/xtensa/src/esp32s3/esp32s3_addrenv_utils.c       | 10 +++++-----
 arch/xtensa/src/esp32s3/esp32s3_pgalloc.c             | 19 +++++++++++++------
 .../esp32s3-devkit/configs/kernel_n8r2/defconfig      |  4 ++--
 .../esp32s3-devkit/configs/kernel_oct/defconfig       |  4 ++--
 6 files changed, 35 insertions(+), 23 deletions(-)

diff --git a/arch/xtensa/src/esp32s3/Kconfig b/arch/xtensa/src/esp32s3/Kconfig
index 67f4f1a2770..3ede25e15a4 100644
--- a/arch/xtensa/src/esp32s3/Kconfig
+++ b/arch/xtensa/src/esp32s3/Kconfig
@@ -361,7 +361,11 @@ config ESP32S3_PGPOOL_SCRATCH
 
                The pool itself is described by ARCH_PGPOOL_PBASE and
                ARCH_PGPOOL_SIZE as usual.  Only ARCH_PGPOOL_VBASE does not 
apply,
-               because there is no permanent virtual mapping to name.
+               because there is no permanent virtual mapping to name.  The 
kernel
+               keeps to the internal SRAM: after the boot it has no mapping of 
the
+               PSRAM at all, so the pool should hold all of the PSRAM.  The 
first
+               page cannot be in it, because to the page allocator the physical
+               address 0 means "no page": the pool starts at 0x10000.
 
 menu "ESP32-S3 Peripheral Selection"
 
diff --git a/arch/xtensa/src/esp32s3/esp32s3_addrenv.h 
b/arch/xtensa/src/esp32s3/esp32s3_addrenv.h
index 1242d0de18a..90955c49506 100644
--- a/arch/xtensa/src/esp32s3/esp32s3_addrenv.h
+++ b/arch/xtensa/src/esp32s3/esp32s3_addrenv.h
@@ -206,15 +206,16 @@ void esp32s3_pgwipe(uintptr_t paddr);
  * Name: esp32s3_pgpool_unmap
  *
  * Description:
- *   Tear down the boot-time cache-MMU mapping of the page pool, leaving the
- *   pool reachable only a page at a time through esp32s3_pgmap().  Called
- *   once, from up_allocate_pgheap(), after its consistency checks -- which
- *   have to run first, since they ask the cache MMU where the pool actually
- *   is rather than deriving it.
+ *   Tear down the boot-time cache-MMU mapping of the PSRAM, leaving the
+ *   pool reachable only a page at a time through esp32s3_pgmap() and the
+ *   rest of the PSRAM not reachable at all.  Called once, from
+ *   up_allocate_pgheap(), after its consistency checks -- which have to run
+ *   first, since they ask the cache MMU where the pool actually is rather
+ *   than deriving it.
  *
  * Input Parameters:
- *   vbase - Virtual base the boot-time mapping put the pool at.
- *   size  - Size of the pool in bytes.
+ *   vbase - Virtual base of the boot-time mapping of the PSRAM.
+ *   size  - Size of that mapping in bytes.
  *
  ****************************************************************************/
 
diff --git a/arch/xtensa/src/esp32s3/esp32s3_addrenv_utils.c 
b/arch/xtensa/src/esp32s3/esp32s3_addrenv_utils.c
index f473835933d..615395df3c3 100644
--- a/arch/xtensa/src/esp32s3/esp32s3_addrenv_utils.c
+++ b/arch/xtensa/src/esp32s3/esp32s3_addrenv_utils.c
@@ -180,11 +180,11 @@ void esp32s3_pgpool_unmap(uintptr_t vbase, size_t size)
 {
   uint32_t cache_state;
 
-  /* Take away the boot-time mapping of the pool in one go.  esp32s3_spiram.c
-   * mapped the whole PSRAM device; only the pool's share of that window is
-   * withdrawn, because the rest maps no page a process will ever own and is
-   * the aperture a kernel-side PSRAM allocation (a loaded library's text
-   * heap, say) would have to come from.
+  /* Take away the boot-time mapping of the PSRAM in one go.
+   * esp32s3_spiram.c mapped the whole PSRAM device; up_allocate_pgheap()
+   * withdraws all of that window, the pool and what the pool does not use:
+   * in the kernel build the PSRAM is the memory of the processes, and the
+   * kernel keeps to the internal SRAM.
    *
    * Write back before invalidating the entries: this runs after the PSRAM
    * memory test, which leaves the window's lines dirty.
diff --git a/arch/xtensa/src/esp32s3/esp32s3_pgalloc.c 
b/arch/xtensa/src/esp32s3/esp32s3_pgalloc.c
index b52d47ba0e4..4ff275ddc9c 100644
--- a/arch/xtensa/src/esp32s3/esp32s3_pgalloc.c
+++ b/arch/xtensa/src/esp32s3/esp32s3_pgalloc.c
@@ -247,14 +247,21 @@ void up_allocate_pgheap(void **heap_start, size_t 
*heap_size)
 
     check_windows_clear(MMU_ENTRY_OF(ramstart), MMU_ENTRY_OF(ramend - 1));
 
-    /* Everything above has been established while the pool was still
-     * mapped, which is the only time it can be.  Now take that mapping
-     * away: from here the kernel reaches a pool page only through
-     * esp32s3_pgmap(), and an unprivileged task reaches one only if it is
-     * its own.
+    if (ESP32S3_PGPOOL_SIZE < ramend - ramstart)
+      {
+        _info("PSRAM: %zu bytes are not in the page pool and stay "
+              "unused\n", (size_t)(ramend - ramstart) - ESP32S3_PGPOOL_SIZE);
+      }
+
+    /* Everything above has been established while the PSRAM was still
+     * mapped, which is the only time it can be.  Now take the whole mapping
+     * away, not only the pool's share: the internal SRAM is the kernel's
+     * memory and the PSRAM is the memory of the processes.  From here the
+     * kernel reaches a pool page only through esp32s3_pgmap(), and an
+     * unprivileged task reaches one only if it is its own.
      */
 
-    esp32s3_pgpool_unmap(poolvbase, ESP32S3_PGPOOL_SIZE);
+    esp32s3_pgpool_unmap(ramstart, ramend - ramstart);
   }
 #endif
 
diff --git a/boards/xtensa/esp32s3/esp32s3-devkit/configs/kernel_n8r2/defconfig 
b/boards/xtensa/esp32s3/esp32s3-devkit/configs/kernel_n8r2/defconfig
index 6c53f22dd16..6bd38610284 100644
--- a/boards/xtensa/esp32s3/esp32s3-devkit/configs/kernel_n8r2/defconfig
+++ b/boards/xtensa/esp32s3/esp32s3-devkit/configs/kernel_n8r2/defconfig
@@ -27,8 +27,8 @@ CONFIG_ARCH_KMAP_NPAGES=2
 CONFIG_ARCH_KMAP_VBASE=0x3d400000
 CONFIG_ARCH_MINIMAL_VECTORTABLE_DYNAMIC=y
 CONFIG_ARCH_NUSER_INTERRUPTS=2
-CONFIG_ARCH_PGPOOL_PBASE=0x80000
-CONFIG_ARCH_PGPOOL_SIZE=1572864
+CONFIG_ARCH_PGPOOL_PBASE=0x10000
+CONFIG_ARCH_PGPOOL_SIZE=2031616
 CONFIG_ARCH_STACKDUMP=y
 CONFIG_ARCH_TEXT_NPAGES=2
 CONFIG_ARCH_TEXT_VBASE=0x42c00000
diff --git a/boards/xtensa/esp32s3/esp32s3-devkit/configs/kernel_oct/defconfig 
b/boards/xtensa/esp32s3/esp32s3-devkit/configs/kernel_oct/defconfig
index 975ecb9fbf3..05712d96157 100644
--- a/boards/xtensa/esp32s3/esp32s3-devkit/configs/kernel_oct/defconfig
+++ b/boards/xtensa/esp32s3/esp32s3-devkit/configs/kernel_oct/defconfig
@@ -27,8 +27,8 @@ CONFIG_ARCH_KMAP_NPAGES=2
 CONFIG_ARCH_KMAP_VBASE=0x3d400000
 CONFIG_ARCH_MINIMAL_VECTORTABLE_DYNAMIC=y
 CONFIG_ARCH_NUSER_INTERRUPTS=2
-CONFIG_ARCH_PGPOOL_PBASE=0x350000
-CONFIG_ARCH_PGPOOL_SIZE=4194304
+CONFIG_ARCH_PGPOOL_PBASE=0x10000
+CONFIG_ARCH_PGPOOL_SIZE=8323072
 CONFIG_ARCH_STACKDUMP=y
 CONFIG_ARCH_TEXT_NPAGES=8
 CONFIG_ARCH_TEXT_VBASE=0x42c00000

Reply via email to