From ab57ef2139e11d9eb597e7657e4d5b4d8ed49bb8 Mon Sep 17 00:00:00 2001 From: Lucas Tamborrino Date: Tue, 8 Jul 2025 14:54:49 -0300 Subject: [PATCH 1/5] soc: esp32c6: Improve shared memory Improve shared memory usage among HP and LP Core Signed-off-by: Lucas Tamborrino --- soc/espressif/esp32c6/default_lpcore.ld | 6 +++--- soc/espressif/esp32c6/hpcore_init_ulp.c | 4 +++- soc/espressif/esp32c6/memory.h | 3 ++- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/soc/espressif/esp32c6/default_lpcore.ld b/soc/espressif/esp32c6/default_lpcore.ld index bb5f0d049765..3fc7941c1eeb 100644 --- a/soc/espressif/esp32c6/default_lpcore.ld +++ b/soc/espressif/esp32c6/default_lpcore.ld @@ -24,9 +24,9 @@ _aligned_coproc_mem = ALIGNED_COPROC_MEM; _vector_table_org = LPSRAM_IRAM_START; _vector_table_len = 0x80; _ram_org = _vector_table_org + _vector_table_len; -_ram_len = _aligned_coproc_mem - _vector_table_len - ULP_SHARED_MEM; -_shared_mem_org = _ram_org + _ram_len; -_shared_mem_len = ULP_SHARED_MEM; +_ram_len = _aligned_coproc_mem - _vector_table_len - ULP_SHARED_MEM_SIZE; +_shared_mem_org = ULP_SHARED_MEM_ADDR; +_shared_mem_len = ULP_SHARED_MEM_SIZE; ENTRY(reset_vector) diff --git a/soc/espressif/esp32c6/hpcore_init_ulp.c b/soc/espressif/esp32c6/hpcore_init_ulp.c index 6ba9ed643174..e1c7f96beb78 100644 --- a/soc/espressif/esp32c6/hpcore_init_ulp.c +++ b/soc/espressif/esp32c6/hpcore_init_ulp.c @@ -10,13 +10,15 @@ #include "ulp_lp_core.h" #include "lp_core_uart.h" #include +#include LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL); void IRAM_ATTR lp_core_image_init(void) { const uint32_t lpcore_img_off = FIXED_PARTITION_OFFSET(slot0_lpcore_partition); - const uint32_t lpcore_img_size = 0x4000; + const uint32_t lpcore_img_size = + DT_REG_SIZE(DT_NODELABEL(sramlp)) - DT_REG_SIZE(DT_NODELABEL(shmlp)); int ret = 0; LOG_INF("Getting LPU image at %p, size %d", (void *)lpcore_img_off, lpcore_img_size); diff --git a/soc/espressif/esp32c6/memory.h b/soc/espressif/esp32c6/memory.h index c9f5dd853028..891b8b6593b8 100644 --- a/soc/espressif/esp32c6/memory.h +++ b/soc/espressif/esp32c6/memory.h @@ -7,7 +7,8 @@ /* LP-SRAM (16kB) memory */ #define LPSRAM_IRAM_START DT_REG_ADDR(DT_NODELABEL(sramlp)) #define LPSRAM_SIZE DT_REG_SIZE(DT_NODELABEL(sramlp)) -#define ULP_SHARED_MEM DT_REG_SIZE(DT_NODELABEL(shmlp)) +#define ULP_SHARED_MEM_SIZE DT_REG_SIZE(DT_NODELABEL(shmlp)) +#define ULP_SHARED_MEM_ADDR DT_REG_ADDR(DT_NODELABEL(shmlp)) #define ULP_COPROC_RESERVE_MEM (0x4000) /* HP-SRAM (512kB) memory */ From 2d431815eec4e9e138b51f3a12ed45e5f0d72c07 Mon Sep 17 00:00:00 2001 From: Lucas Tamborrino Date: Tue, 8 Jul 2025 14:56:07 -0300 Subject: [PATCH 2/5] dt-bindings: Add LP Core interrupt source Add LP Core interrupt source Signed-off-by: Lucas Tamborrino --- .../dt-bindings/interrupt-controller/esp-esp32c6-intmux.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/include/zephyr/dt-bindings/interrupt-controller/esp-esp32c6-intmux.h b/include/zephyr/dt-bindings/interrupt-controller/esp-esp32c6-intmux.h index fc89526d7bd8..a125105823d5 100644 --- a/include/zephyr/dt-bindings/interrupt-controller/esp-esp32c6-intmux.h +++ b/include/zephyr/dt-bindings/interrupt-controller/esp-esp32c6-intmux.h @@ -91,4 +91,11 @@ #define ESP_INTR_FLAG_SHARED (1<<8) /* Interrupt can be shared between ISRs */ +/* LP Core intmux */ +#define LP_CORE_IO_INTR_SOURCE 0 +#define LP_CORE_I2C_INTR_SOURCE 1 +#define LP_CORE_UART_INTR_SOURCE 2 +#define LP_CORE_TIMER_INTR_SOURCE 3 +#define LP_CORE_PMU_INTR_SOURCE 5 + #endif /* ZEPHYR_INCLUDE_DT_BINDINGS_INTERRUPT_CONTROLLER_ESP32C6_INTMUX_H_ */ From 4367cab69bf72b19427b14b1a2537137c2786f86 Mon Sep 17 00:00:00 2001 From: Lucas Tamborrino Date: Tue, 8 Jul 2025 14:58:06 -0300 Subject: [PATCH 3/5] drivers: intc: esp32: don't build for ESP32C6 LP Core Espressif's interrupt controller drive should not build for ESP32C6 LP Core since it's behavior is different. Add proper condition for that. Signed-off-by: Lucas Tamborrino --- drivers/interrupt_controller/Kconfig.esp32 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/interrupt_controller/Kconfig.esp32 b/drivers/interrupt_controller/Kconfig.esp32 index 35699cce56fa..3f0a61cac0bd 100644 --- a/drivers/interrupt_controller/Kconfig.esp32 +++ b/drivers/interrupt_controller/Kconfig.esp32 @@ -5,7 +5,7 @@ config INTC_ESP32 bool "Interrupt allocator for Espressif SoCs" - default y + default y if !SOC_ESP32C6_LPCORE depends on SOC_FAMILY_ESPRESSIF_ESP32 help Enable custom interrupt allocator for Espressif SoCs based on Xtensa From 88abf3e9e57d3ad1d85cff3d25162c4ed195b1df Mon Sep 17 00:00:00 2001 From: Lucas Tamborrino Date: Tue, 8 Jul 2025 15:00:28 -0300 Subject: [PATCH 4/5] drivers: mbox: espressif: add esp32c6 support Add support for esp32c6 HP and LP Core Signed-off-by: Lucas Tamborrino --- drivers/mbox/mbox_esp32.c | 41 ++++++++++++++++--- .../espressif/esp32c6/esp32c6_common.dtsi | 17 +++++++- .../espressif/esp32c6/esp32c6_lpcore.dtsi | 26 +++++++++++- west.yml | 2 +- 4 files changed, 76 insertions(+), 10 deletions(-) diff --git a/drivers/mbox/mbox_esp32.c b/drivers/mbox/mbox_esp32.c index bbdb64dd6590..71326fd09b57 100644 --- a/drivers/mbox/mbox_esp32.c +++ b/drivers/mbox/mbox_esp32.c @@ -1,11 +1,20 @@ /* * Copyright (c) 2024 Felipe Neves. + * Copyright (c) 2025 Espressif Systems (Shanghai) Co., Ltd. * * SPDX-License-Identifier: Apache-2.0 */ #define DT_DRV_COMPAT espressif_mbox_esp32 +#if !defined(CONFIG_SOC_SERIES_ESP32C6) #include "soc/dport_reg.h" +#else +#include +#include +#include +#include +#endif + #include "soc/gpio_periph.h" #include @@ -64,12 +73,16 @@ IRAM_ATTR static void esp32_mbox_isr(const struct device *dev) DPORT_WRITE_PERI_REG(DPORT_CPU_INTR_FROM_CPU_0_REG, 0); #elif defined(CONFIG_SOC_SERIES_ESP32S3) WRITE_PERI_REG(SYSTEM_CPU_INTR_FROM_CPU_0_REG, 0); +#elif defined(CONFIG_SOC_ESP32C6_HPCORE) + SET_PERI_REG_MASK(PMU_HP_INT_CLR_REG, PMU_SW_INT_CLR); #endif } else { #if defined(CONFIG_SOC_SERIES_ESP32) DPORT_WRITE_PERI_REG(DPORT_CPU_INTR_FROM_CPU_1_REG, 0); #elif defined(CONFIG_SOC_SERIES_ESP32S3) WRITE_PERI_REG(SYSTEM_CPU_INTR_FROM_CPU_1_REG, 0); +#elif defined(CONFIG_SOC_ESP32C6_LPCORE) + ulp_lp_core_sw_intr_clear(); #endif } @@ -116,23 +129,26 @@ static int esp32_mbox_send(const struct device *dev, mbox_channel_id_t channel, /* Only the lower 16bits of id are used */ dev_data->control->dest_cpu_msg_id[dev_data->other_core_id] = (uint16_t)(channel & 0xFFFF); + atomic_set(&dev_data->control->lock, ESP32_MBOX_LOCK_FREE_VAL); + /* Generate interrupt in the remote core */ if (dev_data->this_core_id == 0) { - atomic_set(&dev_data->control->lock, ESP32_MBOX_LOCK_FREE_VAL); LOG_DBG("Generating interrupt on remote CPU 1 from CPU 0"); #if defined(CONFIG_SOC_SERIES_ESP32) DPORT_WRITE_PERI_REG(DPORT_CPU_INTR_FROM_CPU_1_REG, DPORT_CPU_INTR_FROM_CPU_1); #elif defined(CONFIG_SOC_SERIES_ESP32S3) WRITE_PERI_REG(SYSTEM_CPU_INTR_FROM_CPU_1_REG, SYSTEM_CPU_INTR_FROM_CPU_1); +#elif defined(CONFIG_SOC_ESP32C6_HPCORE) + ulp_lp_core_sw_intr_trigger(); #endif - } else { - atomic_set(&dev_data->control->lock, ESP32_MBOX_LOCK_FREE_VAL); LOG_DBG("Generating interrupt on remote CPU 0 from CPU 1"); #if defined(CONFIG_SOC_SERIES_ESP32) DPORT_WRITE_PERI_REG(DPORT_CPU_INTR_FROM_CPU_0_REG, DPORT_CPU_INTR_FROM_CPU_0); #elif defined(CONFIG_SOC_SERIES_ESP32S3) WRITE_PERI_REG(SYSTEM_CPU_INTR_FROM_CPU_0_REG, SYSTEM_CPU_INTR_FROM_CPU_0); +#elif defined(CONFIG_SOC_ESP32C6_LPCORE) + ulp_lp_core_wakeup_main_processor(); #endif } @@ -196,7 +212,11 @@ static int esp32_mbox_init(const struct device *dev) struct esp32_mbox_config *cfg = (struct esp32_mbox_config *)dev->config; int ret; +#if defined(CONFIG_SOC_ESP32C6_LPCORE) + data->this_core_id = 1; +#else data->this_core_id = esp_core_id(); +#endif data->other_core_id = (data->this_core_id == 0) ? 1 : 0; LOG_DBG("Size of MBOX shared memory: %d", data->shm_size); @@ -206,29 +226,40 @@ static int esp32_mbox_init(const struct device *dev) /* pro_cpu is responsible to initialize the lock of shared memory */ if (data->this_core_id == 0) { +#if !defined(CONFIG_SOC_ESP32C6_LPCORE) ret = esp_intr_alloc(cfg->irq_source_pro_cpu, ESP_PRIO_TO_FLAGS(cfg->irq_priority_pro_cpu) | ESP_INT_FLAGS_CHECK(cfg->irq_flags_pro_cpu) | ESP_INTR_FLAG_IRAM, (intr_handler_t)esp32_mbox_isr, (void *)dev, NULL); +#endif +#if defined(CONFIG_SOC_ESP32C6_HPCORE) + SET_PERI_REG_MASK(PMU_HP_INT_ENA_REG, PMU_SW_INT_ENA); +#endif atomic_set(&data->control->lock, ESP32_MBOX_LOCK_FREE_VAL); } else { /* app_cpu wait for initialization from pro_cpu, then takes it, * after that releases */ +#if defined(CONFIG_SOC_ESP32C6_LPCORE) + ret = 0; + ulp_lp_core_intr_set_handler(cfg->irq_source_app_cpu, + (void (*)(void *))esp32_mbox_isr, (void *)dev); + ulp_lp_core_intr_enable(); + ulp_lp_core_sw_intr_enable(true); +#else ret = esp_intr_alloc(cfg->irq_source_app_cpu, ESP_PRIO_TO_FLAGS(cfg->irq_priority_app_cpu) | ESP_INT_FLAGS_CHECK(cfg->irq_flags_app_cpu) | ESP_INTR_FLAG_IRAM, (intr_handler_t)esp32_mbox_isr, (void *)dev, NULL); - +#endif LOG_DBG("Waiting CPU0 to sync"); while (!atomic_cas(&data->control->lock, ESP32_MBOX_LOCK_FREE_VAL, data->this_core_id)) { } atomic_set(&data->control->lock, ESP32_MBOX_LOCK_FREE_VAL); - LOG_DBG("Synchronization done"); } diff --git a/dts/riscv/espressif/esp32c6/esp32c6_common.dtsi b/dts/riscv/espressif/esp32c6/esp32c6_common.dtsi index c77c03b4af38..3f40749fe166 100644 --- a/dts/riscv/espressif/esp32c6/esp32c6_common.dtsi +++ b/dts/riscv/espressif/esp32c6/esp32c6_common.dtsi @@ -106,11 +106,24 @@ reg = <0x50000000 DT_SIZE_K(16)>; zephyr,memory-region = "SRAMLP "; - shmlp: memory@0 { - reg = <0x0 0x10>; + shmlp: memory@50003fe0 { + reg = <0x50003fe0 0x10>; }; }; + mbox0: mbox@50003ff0 { + compatible = "espressif,mbox-esp32"; + reg = <0x50003ff0 0x8>; + status = "disabled"; + shared-memory = <&shmlp>; + shared-memory-size = <0x10>; + interrupts = + , + ; + interrupt-parent = <&intc>; + #mbox-cells = <1>; + }; + intc: interrupt-controller@60010000 { compatible = "espressif,esp32-intc"; #address-cells = <0>; diff --git a/dts/riscv/espressif/esp32c6/esp32c6_lpcore.dtsi b/dts/riscv/espressif/esp32c6/esp32c6_lpcore.dtsi index ed33ded78371..248d8e763548 100644 --- a/dts/riscv/espressif/esp32c6/esp32c6_lpcore.dtsi +++ b/dts/riscv/espressif/esp32c6/esp32c6_lpcore.dtsi @@ -41,11 +41,33 @@ compatible = "mmio-sram"; reg = <0x50000000 DT_SIZE_K(16)>; - shmlp: memory@0 { - reg = <0x0 0x10>; + shmlp: memory@50003fb0{ + reg = <0x50003fb0 0x50>; }; }; + mbox0: mbox@50003ff0 { + compatible = "espressif,mbox-esp32"; + reg = <0x50003ff0 0x8>; + status = "disabled"; + shared-memory = <&shmlp>; + shared-memory-size = <0x40>; + interrupts = + , + ; + interrupt-parent = <&intc>; + #mbox-cells = <1>; + }; + + intc: interrupt-controller@50000008 { + compatible = "espressif,esp32-intc"; + #address-cells = <0>; + #interrupt-cells = <3>; + interrupt-controller; + reg = <0x50000008 DT_SIZE_K(4)>; + status = "okay"; + }; + flash: flash-controller@60002000 { compatible = "espressif,esp32-flash-controller"; reg = <0x60002000 0x1000>; diff --git a/west.yml b/west.yml index 1482b3b3e42c..bf3299a7ca84 100644 --- a/west.yml +++ b/west.yml @@ -169,7 +169,7 @@ manifest: groups: - hal - name: hal_espressif - revision: f3453bdeced28642424692aae32cce4eec3f2d7f + revision: pull/464/head path: modules/hal/espressif west-commands: west/west-commands.yml groups: From eb6845f221199fd2f0e0f5814b508bdb6852b7cf Mon Sep 17 00:00:00 2001 From: Lucas Tamborrino Date: Tue, 8 Jul 2025 15:01:42 -0300 Subject: [PATCH 5/5] samples: mbox: Add support for ESP32C6 Add mbox sample support for ESP32C6 HP and LP Core Signed-off-by: Lucas Tamborrino --- samples/drivers/mbox/CMakeLists.txt | 1 + samples/drivers/mbox/Kconfig.sysbuild | 1 + .../mbox/boards/esp32c6_devkitc_hpcore.conf | 2 ++ .../boards/esp32c6_devkitc_hpcore.overlay | 26 +++++++++++++++++++ samples/drivers/mbox/remote/CMakeLists.txt | 1 + .../boards/esp32c6_devkitc_lpcore.overlay | 26 +++++++++++++++++++ 6 files changed, 57 insertions(+) create mode 100644 samples/drivers/mbox/boards/esp32c6_devkitc_hpcore.conf create mode 100644 samples/drivers/mbox/boards/esp32c6_devkitc_hpcore.overlay create mode 100644 samples/drivers/mbox/remote/boards/esp32c6_devkitc_lpcore.overlay diff --git a/samples/drivers/mbox/CMakeLists.txt b/samples/drivers/mbox/CMakeLists.txt index 696b2317aa7c..9ee27d4be85a 100644 --- a/samples/drivers/mbox/CMakeLists.txt +++ b/samples/drivers/mbox/CMakeLists.txt @@ -23,6 +23,7 @@ if(CONFIG_BOARD_NRF5340DK_NRF5340_CPUAPP OR CONFIG_BOARD_MCX_N9XX_EVK_MCXN947_CPU0 OR CONFIG_BOARD_ESP32_DEVKITC_ESP32_PROCPU OR CONFIG_BOARD_ESP32S3_DEVKITM_ESP32S3_PROCPU OR + CONFIG_BOARD_ESP32C6_DEVKITC_ESP32C6_HPCORE OR CONFIG_BOARD_NRF54H20DK_NRF54H20_CPUAPP OR CONFIG_BOARD_NRF54H20DK_NRF54H20_CPURAD OR CONFIG_BOARD_NRF54L09PDK_NRF54L09_CPUAPP OR diff --git a/samples/drivers/mbox/Kconfig.sysbuild b/samples/drivers/mbox/Kconfig.sysbuild index 97402056c14e..38c10855e8e1 100644 --- a/samples/drivers/mbox/Kconfig.sysbuild +++ b/samples/drivers/mbox/Kconfig.sysbuild @@ -27,5 +27,6 @@ config REMOTE_BOARD default "stm32h747i_disco/stm32h747xx/m4" if $(BOARD) = "stm32h747i_disco" default "esp32_devkitc/esp32/appcpu" if "$(BOARD)${BOARD_QUALIFIERS}" = "esp32_devkitc/esp32/procpu" default "esp32s3_devkitm/esp32s3/appcpu" if "$(BOARD)${BOARD_QUALIFIERS}" = "esp32s3_devkitm/esp32s3/procpu" + default "esp32c6_devkitc/esp32c6/lpcore" if "$(BOARD)${BOARD_QUALIFIERS}" = "esp32c6_devkitc/esp32c6/hpcore" default "bl54l15_dvk/nrf54l15/cpuflpr" if "$(BOARD)${BOARD_QUALIFIERS}" = "bl54l15_dvk/nrf54l15/cpuapp" default "bl54l15u_dvk/nrf54l15/cpuflpr" if $(BOARD) = "bl54l15u_dvk" diff --git a/samples/drivers/mbox/boards/esp32c6_devkitc_hpcore.conf b/samples/drivers/mbox/boards/esp32c6_devkitc_hpcore.conf new file mode 100644 index 000000000000..50c03bd4caa5 --- /dev/null +++ b/samples/drivers/mbox/boards/esp32c6_devkitc_hpcore.conf @@ -0,0 +1,2 @@ +CONFIG_ULP_COPROC_ENABLED=y +CONFIG_DEBUG_OPTIMIZATIONS=y diff --git a/samples/drivers/mbox/boards/esp32c6_devkitc_hpcore.overlay b/samples/drivers/mbox/boards/esp32c6_devkitc_hpcore.overlay new file mode 100644 index 000000000000..a597cd0f12a7 --- /dev/null +++ b/samples/drivers/mbox/boards/esp32c6_devkitc_hpcore.overlay @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2025 Espressif Systems (Shanghai) Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + chosen { + zephyr,ipc_shm = &shmlp; + zephyr,ipc = &mbox0; + }; + + mbox-consumer { + compatible = "vnd,mbox-consumer"; + mboxes = <&mbox0 0>, <&mbox0 1>; + mbox-names = "tx", "rx"; + }; +}; + +&mbox0 { + status = "okay"; +}; + +&lp_uart { + status = "okay"; +}; diff --git a/samples/drivers/mbox/remote/CMakeLists.txt b/samples/drivers/mbox/remote/CMakeLists.txt index 48df8f0cb5b2..3336846cdaf7 100644 --- a/samples/drivers/mbox/remote/CMakeLists.txt +++ b/samples/drivers/mbox/remote/CMakeLists.txt @@ -21,6 +21,7 @@ if(CONFIG_BOARD_NRF5340DK_NRF5340_CPUNET OR CONFIG_BOARD_MCX_N9XX_EVK_MCXN947_CPU1 OR CONFIG_BOARD_ESP32_DEVKITC_ESP32_APPCPU OR CONFIG_BOARD_ESP32S3_DEVKITM_ESP32S3_APPCPU OR + CONFIG_BOARD_ESP32C6_DEVKITC_ESP32C6_LPCORE OR CONFIG_BOARD_NRF54H20DK_NRF54H20_CPUPPR OR CONFIG_BOARD_NRF54H20DK_NRF54H20_CPUFLPR OR CONFIG_BOARD_NRF54H20DK_NRF54H20_CPUAPP OR diff --git a/samples/drivers/mbox/remote/boards/esp32c6_devkitc_lpcore.overlay b/samples/drivers/mbox/remote/boards/esp32c6_devkitc_lpcore.overlay new file mode 100644 index 000000000000..4717edbd985c --- /dev/null +++ b/samples/drivers/mbox/remote/boards/esp32c6_devkitc_lpcore.overlay @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2024 Felipe Neves. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + chosen { + zephyr,ipc_shm = &shmlp; + zephyr,ipc = &mbox0; + }; + + mbox-consumer { + compatible = "vnd,mbox-consumer"; + mboxes = <&mbox0 1>, <&mbox0 0>; + mbox-names = "tx", "rx"; + }; +}; + +&mbox0 { + status = "okay"; +}; + +&lp_uart { + status = "okay"; +};