Skip to content

Conversation

@sylvioalves
Copy link
Contributor

Summary

  • Add infrastructure for SoC-specific PMP regions via iterable sections
  • Enable PMP and userspace support for ESP32-C6

Description

This PR introduces a mechanism for RISC-V SoCs to define custom PMP regions
that are automatically programmed during PMP initialization. This is needed
for SoCs like ESP32-C6 where code execution spans multiple memory regions
(SoC ROM, IRAM, flash) that all need PMP coverage for userspace to work.

Changes

arch/riscv (generic infrastructure):

  • Add struct pmp_soc_region and PMP_SOC_REGION_DEFINE() macro to pmp.h
  • Add linker snippet pmp.ld for iterable section collection
  • Iterate over SoC-defined regions in z_riscv_pmp_init()

soc/espressif/esp32c6:

  • Define PMP regions for SoC ROM (0x40000000) and IRAM text section
  • Enable PMP_NO_LOCK_GLOBAL (required because PMP init runs from IRAM
    while the main rom region is in flash-mapped memory)
  • Add userspace linker support in default.ld
  • Add soc_rom device tree node for ROM region address/size

@sylvioalves
Copy link
Contributor Author

This PR can be split in 2 if mandatory to make it clear about riscv arch changes and soc itself. However, combining it here gives a better view of the SoC dependency. I gently ask the riscv maintainers to check the PMP memory changes and suggest alternatives if needed. Thanks!

@sylvioalves sylvioalves force-pushed the feature/esp32c6-pmp-userspace branch from 9d1944a to 809d527 Compare December 12, 2025 21:04
Add infrastructure for SoCs to define additional PMP regions
that need protection beyond the standard ROM region. This uses
iterable sections to collect region definitions at link time.

The PMP_SOC_REGION_DEFINE macro allows SoCs to register memory
regions with specific permissions. These regions become global
PMP entries shared between M-mode and U-mode.

Signed-off-by: Sylvio Alves <sylvio.alves@espressif.com>
Add device tree node for ESP32-C6 SoC ROM at 0x40000000.
This 320KB ROM contains libc and utility functions used by
the application. PMP protection is configured separately
via PMP_SOC_REGION_DEFINE in pmp_regions.c.

Signed-off-by: Sylvio Alves <sylvio.alves@espressif.com>
Add linker script support for CONFIG_USERSPACE:
- MPU alignment macros for PMP granularity
- User stacks section in noinit area
- Application shared memory partitions
- Kernel object sections (text, rom, data, priv-stacks)
- ROM region size symbol for PMP configuration

Signed-off-by: Sylvio Alves <sylvio.alves@espressif.com>
Enable RISC-V PMP for ESP32-C6 and configure appropriate defaults:
- 16 PMP slots available on hardware
- Unlocked global entries for XIP flash execution
- MEM_ATTR subsystem for device tree memory regions

Define SoC-specific PMP regions:
- SoC ROM (0x40000000): libc functions, R+X
- IRAM text: interrupt handlers and critical code, R+X

Signed-off-by: Sylvio Alves <sylvio.alves@espressif.com>
@sylvioalves sylvioalves force-pushed the feature/esp32c6-pmp-userspace branch from 809d527 to b25ae26 Compare December 12, 2025 21:10
@sonarqubecloud
Copy link

@fkokosinski
Copy link
Member

arch/riscv (generic infrastructure):

Question: have you considered using memory region with attributes? See e.g. here: https://github.com/zephyrproject-rtos/zephyr/blob/main/tests/arch/riscv/pmp/mem-attr-entries/memattr_mapping.overlay

@sylvioalves
Copy link
Contributor Author

arch/riscv (generic infrastructure):

Question: have you considered using memory region with attributes? See e.g. here: https://github.com/zephyrproject-rtos/zephyr/blob/main/tests/arch/riscv/pmp/mem-attr-entries/memattr_mapping.overlay

Hi, that was my initial approach before adding the custom PMP region. See, IRAM and DRAM share the same physical memory region (internal SRAM), but need different PMP permissions:

  1. IRAM text (has kernel code) needs R+X (read + execute, no write)
  2. DRAM data needs R+W (read + write, no execute)

With memory-attr overlays, you define static memory regions in DTS, but ESP32-C6's IRAM text section boundaries (_iram_text_start, _iram_text_end) are only known at link time - they depend on what code gets placed in IRAM.

The other way around is to add the whole dram/iram with memory attributes, but that isn't correct. Thoughts?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: Boards/SoCs area: RISCV RISCV Architecture (32-bit & 64-bit) platform: ESP32 Espressif ESP32

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants