soc: espressif: esp32c6: Add LP Core
Add ULP Coprocessor support for ESP32C6. Signed-off-by: Lucas Tamborrino <lucas.tamborrino@espressif.com>
This commit is contained in:
parent
cc282e56e8
commit
0b9e4e013a
14 changed files with 642 additions and 66 deletions
|
@ -105,7 +105,8 @@ static void esp32_clock_perip_init(void)
|
|||
soc_reset_reason_t rst_reason = esp_rom_get_reset_reason(0);
|
||||
|
||||
if ((rst_reason != RESET_REASON_CPU0_MWDT0) && (rst_reason != RESET_REASON_CPU0_MWDT1) &&
|
||||
(rst_reason != RESET_REASON_CPU0_SW) && (rst_reason != RESET_REASON_CPU0_RTC_WDT)) {
|
||||
(rst_reason != RESET_REASON_CPU0_SW) && (rst_reason != RESET_REASON_CPU0_RTC_WDT) &&
|
||||
(rst_reason != RESET_REASON_CPU0_JTAG)) {
|
||||
|
||||
periph_ll_disable_clk_set_rst(PERIPH_UART1_MODULE);
|
||||
periph_ll_disable_clk_set_rst(PERIPH_I2C0_MODULE);
|
||||
|
|
|
@ -76,9 +76,15 @@
|
|||
};
|
||||
|
||||
sramlp: memory@50000000 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "zephyr,memory-region", "mmio-sram";
|
||||
reg = <0x50000000 DT_SIZE_K(16)>;
|
||||
zephyr,memory-region = "SRAMLP ";
|
||||
|
||||
shmlp: memory@0 {
|
||||
reg = <0x0 0x10>;
|
||||
};
|
||||
};
|
||||
|
||||
intc: interrupt-controller@60010000 {
|
||||
|
|
63
dts/riscv/espressif/esp32c6/esp32c6_lpcore.dtsi
Normal file
63
dts/riscv/espressif/esp32c6/esp32c6_lpcore.dtsi
Normal file
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* Copyright (c) 2025 Espressif Systems (Shanghai) Co., Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <mem.h>
|
||||
#include <freq.h>
|
||||
#include <zephyr/dt-bindings/gpio/gpio.h>
|
||||
#include <zephyr/dt-bindings/interrupt-controller/esp-esp32c6-intmux.h>
|
||||
#include <zephyr/dt-bindings/clock/esp32c6_clock.h>
|
||||
#include <dt-bindings/pinctrl/esp32c6-pinctrl.h>
|
||||
|
||||
/ {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
cpus {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
cpu0: cpu@0 {
|
||||
device_type = "cpu";
|
||||
compatible = "espressif,riscv";
|
||||
riscv,isa = "rv32imac_zicsr_zifencei";
|
||||
reg = <0>;
|
||||
clock-source = <ESP32_RTC_FAST_CLK_SRC_XTAL_D2>;
|
||||
clock-frequency = <DT_FREQ_M(20)>;
|
||||
xtal-freq = <DT_FREQ_M(40)>;
|
||||
};
|
||||
};
|
||||
|
||||
soc {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "simple-bus";
|
||||
ranges;
|
||||
|
||||
sramlp: memory@50000000 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "mmio-sram";
|
||||
reg = <0x50000000 DT_SIZE_K(16)>;
|
||||
|
||||
shmlp: memory@0 {
|
||||
reg = <0x0 0x10>;
|
||||
};
|
||||
};
|
||||
|
||||
flash: flash-controller@60002000 {
|
||||
compatible = "espressif,esp32-flash-controller";
|
||||
reg = <0x60002000 0x1000>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
flash0: flash@0 {
|
||||
compatible = "soc-nv-flash";
|
||||
erase-block-size = <4096>;
|
||||
write-block-size = <4>;
|
||||
/* Flash size is specified in SOC/SIP dtsi */
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
12
dts/riscv/espressif/esp32c6/esp32c6_lpcore_wroom_n4.dtsi
Normal file
12
dts/riscv/espressif/esp32c6/esp32c6_lpcore_wroom_n4.dtsi
Normal file
|
@ -0,0 +1,12 @@
|
|||
/*
|
||||
* Copyright (c) 2025 Espressif Systems (Shanghai) Co., Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "esp32c6_lpcore.dtsi"
|
||||
|
||||
/* 4MB flash */
|
||||
&flash0 {
|
||||
reg = <0x0 DT_SIZE_M(4)>;
|
||||
};
|
|
@ -13,28 +13,28 @@
|
|||
#define ESP32_CLK_SRC_RC_FAST 2U
|
||||
|
||||
/* Supported CPU frequencies */
|
||||
#define ESP32_CLK_CPU_PLL_80M 80000000
|
||||
#define ESP32_CLK_CPU_PLL_160M 160000000
|
||||
#define ESP32_CLK_CPU_PLL_80M 80000000
|
||||
#define ESP32_CLK_CPU_PLL_160M 160000000
|
||||
#define ESP32_CLK_CPU_RC_FAST_FREQ 17500000
|
||||
|
||||
/* Supported XTAL Frequencies */
|
||||
#define ESP32_CLK_XTAL_32M 32000000
|
||||
#define ESP32_CLK_XTAL_40M 40000000
|
||||
#define ESP32_CLK_XTAL_32M 32000000
|
||||
#define ESP32_CLK_XTAL_40M 40000000
|
||||
|
||||
/* Supported RTC fast clock sources */
|
||||
#define ESP32_RTC_FAST_CLK_SRC_RC_FAST 0
|
||||
#define ESP32_RTC_FAST_CLK_SRC_XTAL_D2 1
|
||||
|
||||
/* Supported RTC slow clock frequencies */
|
||||
#define ESP32_RTC_SLOW_CLK_SRC_RC_SLOW 0
|
||||
#define ESP32_RTC_SLOW_CLK_SRC_XTAL32K 1
|
||||
#define ESP32_RTC_SLOW_CLK_SRC_RC32K 2
|
||||
#define ESP32_RTC_SLOW_CLK_32K_EXT_OSC 9
|
||||
#define ESP32_RTC_SLOW_CLK_SRC_RC_SLOW 0
|
||||
#define ESP32_RTC_SLOW_CLK_SRC_XTAL32K 1
|
||||
#define ESP32_RTC_SLOW_CLK_SRC_RC32K 2
|
||||
#define ESP32_RTC_SLOW_CLK_32K_EXT_OSC 9
|
||||
|
||||
/* RTC slow clock frequencies */
|
||||
#define ESP32_RTC_SLOW_CLK_SRC_RC_SLOW_FREQ 136000
|
||||
#define ESP32_RTC_SLOW_CLK_SRC_XTAL32K_FREQ 32768
|
||||
#define ESP32_RTC_SLOW_CLK_SRC_RC32K_FREQ 32768
|
||||
#define ESP32_RTC_SLOW_CLK_SRC_RC_SLOW_FREQ 136000
|
||||
#define ESP32_RTC_SLOW_CLK_SRC_XTAL32K_FREQ 32768
|
||||
#define ESP32_RTC_SLOW_CLK_SRC_RC32K_FREQ 32768
|
||||
|
||||
/* Modules IDs
|
||||
* These IDs are actually offsets in CLK and RST Control registers.
|
||||
|
@ -44,44 +44,49 @@
|
|||
* Basic Modules
|
||||
* Registers: DPORT_PERIP_CLK_EN_REG, DPORT_PERIP_RST_EN_REG
|
||||
*/
|
||||
#define ESP32_LEDC_MODULE 0
|
||||
#define ESP32_UART0_MODULE 1
|
||||
#define ESP32_UART1_MODULE 2
|
||||
#define ESP32_USB_MODULE 3
|
||||
#define ESP32_I2C0_MODULE 4
|
||||
#define ESP32_I2S1_MODULE 5
|
||||
#define ESP32_TIMG0_MODULE 6
|
||||
#define ESP32_TIMG1_MODULE 7
|
||||
#define ESP32_UHCI0_MODULE 8
|
||||
#define ESP32_RMT_MODULE 9
|
||||
#define ESP32_PCNT_MODULE 10
|
||||
#define ESP32_SPI_MODULE 11
|
||||
#define ESP32_SPI2_MODULE 12
|
||||
#define ESP32_TWAI0_MODULE 13
|
||||
#define ESP32_TWAI1_MODULE 14
|
||||
#define ESP32_RNG_MODULE 15
|
||||
#define ESP32_RSA_MODULE 16
|
||||
#define ESP32_AES_MODULE 17
|
||||
#define ESP32_SHA_MODULE 18
|
||||
#define ESP32_ECC_MODULE 19
|
||||
#define ESP32_HMAC_MODULE 20
|
||||
#define ESP32_DS_MODULE 21
|
||||
#define ESP32_SDIO_SLAVE_MODULE 22
|
||||
#define ESP32_GDMA_MODULE 23
|
||||
#define ESP32_MCPWM0_MODULE 24
|
||||
#define ESP32_ETM_MODULE 25
|
||||
#define ESP32_PARLIO_MODULE 26
|
||||
#define ESP32_SYSTIMER_MODULE 27
|
||||
#define ESP32_SARADC_MODULE 28
|
||||
#define ESP32_TEMPSENSOR_MODULE 29
|
||||
#define ESP32_REGDMA_MODULE 30
|
||||
#define ESP32_LP_I2C0_MODULE 31
|
||||
#define ESP32_LEDC_MODULE 0
|
||||
#define ESP32_UART0_MODULE 1
|
||||
#define ESP32_UART1_MODULE 2
|
||||
#define ESP32_USB_MODULE 3
|
||||
#define ESP32_I2C0_MODULE 4
|
||||
#define ESP32_I2S1_MODULE 5
|
||||
#define ESP32_TIMG0_MODULE 6
|
||||
#define ESP32_TIMG1_MODULE 7
|
||||
#define ESP32_UHCI0_MODULE 8
|
||||
#define ESP32_RMT_MODULE 9
|
||||
#define ESP32_PCNT_MODULE 10
|
||||
#define ESP32_SPI_MODULE 11
|
||||
#define ESP32_SPI2_MODULE 12
|
||||
#define ESP32_TWAI0_MODULE 13
|
||||
#define ESP32_TWAI1_MODULE 14
|
||||
#define ESP32_RNG_MODULE 15
|
||||
#define ESP32_RSA_MODULE 16
|
||||
#define ESP32_AES_MODULE 17
|
||||
#define ESP32_SHA_MODULE 18
|
||||
#define ESP32_ECC_MODULE 19
|
||||
#define ESP32_HMAC_MODULE 20
|
||||
#define ESP32_DS_MODULE 21
|
||||
#define ESP32_SDIO_SLAVE_MODULE 22
|
||||
#define ESP32_GDMA_MODULE 23
|
||||
#define ESP32_MCPWM0_MODULE 24
|
||||
#define ESP32_ETM_MODULE 25
|
||||
#define ESP32_PARLIO_MODULE 26
|
||||
#define ESP32_SYSTIMER_MODULE 27
|
||||
#define ESP32_SARADC_MODULE 28
|
||||
#define ESP32_TEMPSENSOR_MODULE 29
|
||||
#define ESP32_ASSIST_DEBUG_MODULE 30
|
||||
/* LP peripherals */
|
||||
#define ESP32_LP_I2C0_MODULE 31
|
||||
#define ESP32_LP_UART0_MODULE 32
|
||||
/* Peripherals clock managed by the modem_clock driver must be listed last */
|
||||
#define ESP32_WIFI_MODULE 32
|
||||
#define ESP32_BT_MODULE 33
|
||||
#define ESP32_IEEE802154_MODULE 34
|
||||
#define ESP32_COEX_MODULE 35
|
||||
#define ESP32_PHY_MODULE 36
|
||||
#define ESP32_MODULE_MAX 37
|
||||
#define ESP32_WIFI_MODULE 33
|
||||
#define ESP32_BT_MODULE 34
|
||||
#define ESP32_IEEE802154_MODULE 35
|
||||
#define ESP32_COEX_MODULE 36
|
||||
#define ESP32_PHY_MODULE 37
|
||||
#define ESP32_ANA_I2C_MASTER_MODULE 38
|
||||
#define ESP32_MODEM_ETM_MODULE 39
|
||||
#define ESP32_MODEM_ADC_COMMON_FE_MODULE 40
|
||||
#define ESP32_MODULE_MAX 41
|
||||
|
||||
#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_ESP32C6_H_ */
|
||||
|
|
|
@ -62,4 +62,6 @@ config RTC_CLK_CAL_CYCLES
|
|||
If the crystal could not start, it will be switched to internal RC.
|
||||
endmenu
|
||||
|
||||
rsource "Kconfig.ulp"
|
||||
|
||||
endif # SOC_FAMILY_ESPRESSIF_ESP32
|
||||
|
|
85
soc/espressif/Kconfig.ulp
Normal file
85
soc/espressif/Kconfig.ulp
Normal file
|
@ -0,0 +1,85 @@
|
|||
# Copyright (c) 2025 Espressif Systems (Shanghai) Co., Ltd.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
menu "Ultra Low Power (ULP) Coprocessor"
|
||||
|
||||
config ULP_COPROC_ENABLED
|
||||
bool "Ultra Low Power (ULP) Coprocessor"
|
||||
help
|
||||
Enable this feature if you plan to use the ULP Coprocessor.
|
||||
Once this option is enabled, further ULP co-processor configuration will appear in the menu.
|
||||
|
||||
choice ULP_COPROC_TYPE
|
||||
prompt "ULP Coprocessor type"
|
||||
depends on ULP_COPROC_ENABLED
|
||||
default ULP_COPROC_TYPE_LP_CORE if SOC_SERIES_ESP32C6
|
||||
help
|
||||
Choose the ULP Coprocessor type: ULP FSM (Finite State Machine) or ULP RISC-V.
|
||||
|
||||
config ULP_COPROC_TYPE_FSM
|
||||
bool "ULP FSM (Finite State Machine)"
|
||||
depends on SOC_SERIES_ESP32 || SOC_SERIES_ESP32S2 || SOC_SERIES_ESP32S3
|
||||
|
||||
config ULP_COPROC_TYPE_RISCV
|
||||
bool "ULP RISC-V"
|
||||
depends on SOC_SERIES_ESP32S2 || SOC_SERIES_ESP32S3
|
||||
|
||||
config ULP_COPROC_TYPE_LP_CORE
|
||||
bool "LP core RISC-V"
|
||||
depends on SOC_SERIES_ESP32C6
|
||||
endchoice
|
||||
|
||||
menu "ULP RISC-V Settings"
|
||||
depends on ULP_COPROC_TYPE_RISCV
|
||||
|
||||
config ULP_RISCV_INTERRUPT_ENABLE
|
||||
bool "ULP RISC-V interrupts"
|
||||
help
|
||||
Turn on this setting to enabled interrupts on the ULP RISC-V core.
|
||||
|
||||
endmenu
|
||||
|
||||
menu "ULP Debugging Options"
|
||||
|
||||
config ULP_PANIC_OUTPUT_ENABLE
|
||||
bool "Panic handler outputs to LP UART"
|
||||
depends on ULP_COPROC_TYPE_LP_CORE
|
||||
help
|
||||
Set this option to enable panic handler functionality. If this option is
|
||||
enabled then the LP Core will output a panic dump over LP UART,
|
||||
similar to what the main core does. Output depends on LP UART already being
|
||||
initialized and configured.
|
||||
Disabling this option will reduce the LP core binary size by not
|
||||
linking in panic handler functionality.
|
||||
|
||||
config ULP_HP_UART_CONSOLE_PRINT
|
||||
bool "Route lp_core_printf to the console HP-UART"
|
||||
depends on ULP_COPROC_TYPE_LP_CORE
|
||||
help
|
||||
Set this option to route lp_core_printf to the console HP-UART.
|
||||
This allows you to easily view print outputs from the LP core, without
|
||||
having to connect to the LP-UART. This option comes with the following
|
||||
limitations:
|
||||
|
||||
1. There is no mutual exclusion between the HP-Core and the LP-Core accessing
|
||||
the HP-UART, which means that if both cores are logging heavily the output
|
||||
strings might get mangled together.
|
||||
2. The HP-UART can only work while the HP-Core is running, which means that
|
||||
if the HP-Core is in deep sleep, the LP-Core will not be able to print to the
|
||||
console HP-UART.
|
||||
|
||||
Due to these limitations it is only recommended to use this option for easy debugging.
|
||||
For more serious use-cases you should use the LP-UART.
|
||||
|
||||
config ULP_NORESET_UNDER_DEBUG
|
||||
bool "Avoid resetting LP core when debugger is attached"
|
||||
depends on ULP_COPROC_TYPE_LP_CORE
|
||||
default y
|
||||
help
|
||||
Enable this feature to avoid resetting LP core in sleep mode when debugger is attached,
|
||||
otherwise configured HW breakpoints and dcsr.ebreak* bits will be missed.
|
||||
This is a workaround until it will be fixed in HW.
|
||||
|
||||
endmenu
|
||||
|
||||
endmenu # Ultra Low Power (ULP) Coprocessor
|
131
soc/espressif/esp32c6/default_lpcore.ld
Normal file
131
soc/espressif/esp32c6/default_lpcore.ld
Normal file
|
@ -0,0 +1,131 @@
|
|||
/*
|
||||
* Copyright (c) 2025 Espressif Systems (Shanghai) Co., Ltd.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <zephyr/devicetree.h>
|
||||
#include <zephyr/linker/sections.h>
|
||||
#include <zephyr/linker/linker-defs.h>
|
||||
#include <zephyr/linker/linker-tool.h>
|
||||
|
||||
#include "memory.h"
|
||||
|
||||
#define ALIGN_DOWN(SIZE, AL) (SIZE & ~(AL - 1))
|
||||
/* Ensure the end where the shared memory starts is aligned to 8 bytes
|
||||
if updating this also update the same in ulp_lp_core_memory_shared.c
|
||||
*/
|
||||
#define ALIGNED_COPROC_MEM ALIGN_DOWN(ULP_COPROC_RESERVE_MEM, 0x8)
|
||||
|
||||
#define RODATA_REGION ram
|
||||
#define RAMABLE_REGION ram
|
||||
#define ROMABLE_REGION ram
|
||||
|
||||
/* User available memory segments */
|
||||
_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;
|
||||
|
||||
ENTRY(reset_vector)
|
||||
|
||||
MEMORY
|
||||
{
|
||||
/*first 128byte for exception/interrupt vectors*/
|
||||
vector_table(RX) : ORIGIN = _vector_table_org , LENGTH = _vector_table_len
|
||||
ram(RWX) : ORIGIN = _ram_org, LENGTH = _ram_len
|
||||
shared_mem_ram(RW) : ORIGIN = _shared_mem_org, LENGTH = _shared_mem_len
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.vector.text :
|
||||
{
|
||||
__mtvec_base = .;
|
||||
KEEP (*(.init.vector .init.vector.*))
|
||||
} > vector_table
|
||||
|
||||
. = ORIGIN(ram);
|
||||
|
||||
.text ALIGN(4):
|
||||
{
|
||||
*(.text.vectors) /* Default reset vector must link to offset 0x80 */
|
||||
__text_region_start = ABSOLUTE(.);
|
||||
*(.text)
|
||||
*(.text*)
|
||||
__text_region_end = ABSOLUTE(.);
|
||||
} >ram
|
||||
|
||||
#include <zephyr/linker/rel-sections.ld>
|
||||
|
||||
.rodata ALIGN(4):
|
||||
{
|
||||
__rodata_region_start = ABSOLUTE(.);
|
||||
*(.rodata .srodata)
|
||||
*(.rodata* .srodata*)
|
||||
__rodata_region_end = .;
|
||||
|
||||
} > ram
|
||||
|
||||
#include <zephyr/linker/common-rom/common-rom-kernel-devices.ld>
|
||||
|
||||
.rodata.end ALIGN(4):
|
||||
{
|
||||
_rodata_reserved_end = ABSOLUTE(.);
|
||||
} > ram
|
||||
|
||||
.data ALIGN(4):
|
||||
{
|
||||
_image_ram_start = ABSOLUTE(.);
|
||||
*(.data)
|
||||
*(.data*)
|
||||
*(.sdata)
|
||||
*(.sdata*)
|
||||
|
||||
} > ram
|
||||
|
||||
#include <snippets-data-sections.ld>
|
||||
#include <zephyr/linker/common-ram.ld>
|
||||
#include <snippets-ram-sections.ld>
|
||||
|
||||
.data.end ALIGN(4):
|
||||
{
|
||||
_image_ram_end = ABSOLUTE(.);
|
||||
} > ram
|
||||
|
||||
.data.noinit (NOLOAD):
|
||||
{
|
||||
. = ALIGN(4);
|
||||
*(.noinit)
|
||||
*(.noinit.*)
|
||||
. = ALIGN(4);
|
||||
} > ram
|
||||
|
||||
.bss ALIGN(4) :
|
||||
{
|
||||
*(.bss)
|
||||
*(.bss*)
|
||||
*(.sbss)
|
||||
*(.sbss*)
|
||||
PROVIDE(end = .);
|
||||
_heap_sentry = .;
|
||||
} >ram
|
||||
|
||||
#include <zephyr/linker/ram-end.ld>
|
||||
|
||||
__stack_top = ORIGIN(ram) + LENGTH(ram);
|
||||
|
||||
#include <zephyr/linker/debug-sections.ld>
|
||||
SECTION_PROLOGUE(.riscv.attributes, 0,)
|
||||
{
|
||||
KEEP(*(.riscv.attributes))
|
||||
KEEP(*(.gnu.attributes))
|
||||
}
|
||||
|
||||
. = ORIGIN(shared_mem_ram);
|
||||
.shared_mem (ALIGN(4)) :
|
||||
{
|
||||
KEEP(*(.shared_mem))
|
||||
} > shared_mem_ram
|
||||
}
|
47
soc/espressif/esp32c6/hpcore_init_ulp.c
Normal file
47
soc/espressif/esp32c6/hpcore_init_ulp.c
Normal file
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright (c) 2025 Espressif Systems (Shanghai) Co., Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr/kernel.h>
|
||||
#include "bootloader_flash_priv.h"
|
||||
#include <zephyr/storage/flash_map.h>
|
||||
#include "ulp_lp_core.h"
|
||||
#include "lp_core_uart.h"
|
||||
#include <zephyr/logging/log.h>
|
||||
|
||||
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;
|
||||
int ret = 0;
|
||||
|
||||
LOG_INF("Getting LPU image at %p, size %d", (void *)lpcore_img_off, lpcore_img_size);
|
||||
|
||||
const uint8_t *data = (const uint8_t *)bootloader_mmap(lpcore_img_off, lpcore_img_size);
|
||||
|
||||
ret = ulp_lp_core_load_binary(data, lpcore_img_size);
|
||||
if (ret) {
|
||||
LOG_ERR("Failed to load LP core image: %d", ret);
|
||||
}
|
||||
|
||||
LOG_INF("LP core image loaded");
|
||||
|
||||
/* Set LP core wakeup source as the HP CPU */
|
||||
ulp_lp_core_cfg_t cfg = {
|
||||
.wakeup_source = ULP_LP_CORE_WAKEUP_SOURCE_HP_CPU,
|
||||
};
|
||||
|
||||
ret = ulp_lp_core_run(&cfg);
|
||||
if (ret) {
|
||||
LOG_ERR("Failed to start LP core: %d", ret);
|
||||
}
|
||||
}
|
||||
|
||||
void soc_late_init_hook(void)
|
||||
{
|
||||
lp_core_image_init();
|
||||
}
|
|
@ -5,15 +5,18 @@
|
|||
#pragma once
|
||||
|
||||
/* LP-SRAM (16kB) memory */
|
||||
#define LPSRAM_IRAM_START DT_REG_ADDR(DT_NODELABEL(sramlp))
|
||||
#define LPSRAM_SIZE DT_REG_SIZE(DT_NODELABEL(sramlp))
|
||||
#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_COPROC_RESERVE_MEM (0x4000)
|
||||
|
||||
/* HP-SRAM (512kB) memory */
|
||||
#define HPSRAM_START DT_REG_ADDR(DT_NODELABEL(sramhp))
|
||||
#define HPSRAM_SIZE DT_REG_SIZE(DT_NODELABEL(sramhp))
|
||||
#define HPSRAM_DRAM_START HPSRAM_START
|
||||
#define HPSRAM_IRAM_START HPSRAM_START
|
||||
#define HPSRAM_START DT_REG_ADDR(DT_NODELABEL(sramhp))
|
||||
#define HPSRAM_SIZE DT_REG_SIZE(DT_NODELABEL(sramhp))
|
||||
#define HPSRAM_DRAM_START HPSRAM_START
|
||||
#define HPSRAM_IRAM_START HPSRAM_START
|
||||
/* ICache size is fixed to 32KB on ESP32-C6 */
|
||||
#define ICACHE_SIZE 0x8000
|
||||
#define ICACHE_SIZE 0x8000
|
||||
|
||||
/** Simplified memory map for the bootloader.
|
||||
* Make sure the bootloader can load into main memory without overwriting itself.
|
||||
|
@ -27,13 +30,13 @@
|
|||
* buffers area (0x4087c610).
|
||||
*/
|
||||
|
||||
#define DRAM_BUFFERS_START 0x4086ad08
|
||||
#define DRAM_BUFFERS_END 0x4087c610
|
||||
#define DRAM_STACK_START DRAM_BUFFERS_END
|
||||
#define DRAM_ROM_BSS_DATA_START 0x4087e610
|
||||
#define DRAM_BUFFERS_START 0x4086ad08
|
||||
#define DRAM_BUFFERS_END 0x4087c610
|
||||
#define DRAM_STACK_START DRAM_BUFFERS_END
|
||||
#define DRAM_ROM_BSS_DATA_START 0x4087e610
|
||||
|
||||
/* Set the limit for the application runtime dynamic allocations */
|
||||
#define DRAM_RESERVED_START DRAM_BUFFERS_END
|
||||
#define DRAM_RESERVED_START DRAM_BUFFERS_END
|
||||
|
||||
/* For safety margin between bootloader data section and startup stacks */
|
||||
#define BOOTLOADER_STACK_OVERHEAD 0x0
|
||||
|
@ -49,14 +52,14 @@
|
|||
|
||||
/* Start of the lower region is determined by region size and the end of the higher region */
|
||||
#define BOOTLOADER_IRAM_LOADER_SEG_START (BOOTLOADER_USER_SRAM_END - BOOTLOADER_IRAM_LOADER_SEG_LEN)
|
||||
#define BOOTLOADER_IRAM_SEG_START (BOOTLOADER_IRAM_LOADER_SEG_START - BOOTLOADER_IRAM_SEG_LEN)
|
||||
#define BOOTLOADER_DRAM_SEG_START (BOOTLOADER_IRAM_SEG_START - BOOTLOADER_DRAM_SEG_LEN)
|
||||
#define BOOTLOADER_IRAM_SEG_START (BOOTLOADER_IRAM_LOADER_SEG_START - BOOTLOADER_IRAM_SEG_LEN)
|
||||
#define BOOTLOADER_DRAM_SEG_START (BOOTLOADER_IRAM_SEG_START - BOOTLOADER_DRAM_SEG_LEN)
|
||||
|
||||
/* Flash */
|
||||
#ifdef CONFIG_FLASH_SIZE
|
||||
#define FLASH_SIZE CONFIG_FLASH_SIZE
|
||||
#define FLASH_SIZE CONFIG_FLASH_SIZE
|
||||
#else
|
||||
#define FLASH_SIZE 0x400000
|
||||
#define FLASH_SIZE 0x400000
|
||||
#endif
|
||||
|
||||
/* Cached memory */
|
||||
|
|
32
soc/espressif/esp32c6/soc_lpcore.c
Normal file
32
soc/espressif/esp32c6/soc_lpcore.c
Normal file
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "soc/soc_caps.h"
|
||||
#include "esp_rom_caps.h"
|
||||
#include "rom/ets_sys.h"
|
||||
#include "ulp_lp_core_utils.h"
|
||||
#include "ulp_lp_core_lp_timer_shared.h"
|
||||
#include "ulp_lp_core_memory_shared.h"
|
||||
#include "ulp_lp_core_print.h"
|
||||
#include <soc.h>
|
||||
#include <kernel_internal.h>
|
||||
|
||||
extern void main(void);
|
||||
|
||||
/* Initialize lp core related system functions before calling user's main*/
|
||||
void lp_core_startup(void)
|
||||
{
|
||||
#if CONFIG_ULP_HP_UART_CONSOLE_PRINT && ESP_ROM_HAS_LP_ROM
|
||||
ets_install_putc1(lp_core_print_char);
|
||||
#endif
|
||||
|
||||
ulp_lp_core_update_wakeup_cause();
|
||||
|
||||
/* Start Zephyr */
|
||||
z_cstart();
|
||||
|
||||
CODE_UNREACHABLE;
|
||||
}
|
25
soc/espressif/esp32c6/start_lpcore.S
Normal file
25
soc/espressif/esp32c6/start_lpcore.S
Normal file
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
.section .text.vectors
|
||||
.global reset_vector
|
||||
|
||||
/* The reset vector, jumps to startup code */
|
||||
reset_vector:
|
||||
|
||||
/* _vector_table: Only 256-byte aligned addresses are allowed */
|
||||
la t0, _vector_table
|
||||
csrw mtvec, t0
|
||||
|
||||
j __start
|
||||
|
||||
__start:
|
||||
|
||||
/* setup the stack pointer */
|
||||
la sp, __stack_top
|
||||
call lp_core_startup
|
||||
loop:
|
||||
j loop
|
22
soc/espressif/esp32c6/vector_table_lpcore.S
Normal file
22
soc/espressif/esp32c6/vector_table_lpcore.S
Normal file
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
.section .init.vector,"ax"
|
||||
|
||||
.global _vector_table
|
||||
.type _vector_table, @function
|
||||
_vector_table:
|
||||
.option push
|
||||
.option norvc
|
||||
|
||||
.rept 30
|
||||
j _panic_handler
|
||||
.endr
|
||||
j _interrupt_handler // All interrupts are routed to mtvec + 4*30, i.e. the 31st entry
|
||||
j _panic_handler
|
||||
|
||||
.option pop
|
||||
.size _vector_table, .-_vector_table
|
142
soc/espressif/esp32c6/vectors_lpcore.S
Normal file
142
soc/espressif/esp32c6/vectors_lpcore.S
Normal file
|
@ -0,0 +1,142 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "riscv/rvruntime-frames.h"
|
||||
#include <soc/soc_caps.h>
|
||||
|
||||
.equ SAVE_REGS, 32
|
||||
.equ CONTEXT_SIZE, (SAVE_REGS * 4)
|
||||
/* Macro which first allocates space on the stack to save general
|
||||
* purpose registers, and then save them. GP register is excluded.
|
||||
* The default size allocated on the stack is CONTEXT_SIZE, but it
|
||||
* can be overridden. */
|
||||
.macro save_general_regs cxt_size=CONTEXT_SIZE
|
||||
addi sp, sp, -\cxt_size
|
||||
sw ra, RV_STK_RA(sp)
|
||||
sw tp, RV_STK_TP(sp)
|
||||
sw t0, RV_STK_T0(sp)
|
||||
sw t1, RV_STK_T1(sp)
|
||||
sw t2, RV_STK_T2(sp)
|
||||
sw s0, RV_STK_S0(sp)
|
||||
sw s1, RV_STK_S1(sp)
|
||||
sw a0, RV_STK_A0(sp)
|
||||
sw a1, RV_STK_A1(sp)
|
||||
sw a2, RV_STK_A2(sp)
|
||||
sw a3, RV_STK_A3(sp)
|
||||
sw a4, RV_STK_A4(sp)
|
||||
sw a5, RV_STK_A5(sp)
|
||||
sw a6, RV_STK_A6(sp)
|
||||
sw a7, RV_STK_A7(sp)
|
||||
sw s2, RV_STK_S2(sp)
|
||||
sw s3, RV_STK_S3(sp)
|
||||
sw s4, RV_STK_S4(sp)
|
||||
sw s5, RV_STK_S5(sp)
|
||||
sw s6, RV_STK_S6(sp)
|
||||
sw s7, RV_STK_S7(sp)
|
||||
sw s8, RV_STK_S8(sp)
|
||||
sw s9, RV_STK_S9(sp)
|
||||
sw s10, RV_STK_S10(sp)
|
||||
sw s11, RV_STK_S11(sp)
|
||||
sw t3, RV_STK_T3(sp)
|
||||
sw t4, RV_STK_T4(sp)
|
||||
sw t5, RV_STK_T5(sp)
|
||||
sw t6, RV_STK_T6(sp)
|
||||
.endm
|
||||
|
||||
.macro save_mepc
|
||||
csrr t0, mepc
|
||||
sw t0, RV_STK_MEPC(sp)
|
||||
.endm
|
||||
|
||||
/* Restore the general purpose registers (excluding gp) from the context on
|
||||
* the stack. The context is then deallocated. The default size is CONTEXT_SIZE
|
||||
* but it can be overridden. */
|
||||
.macro restore_general_regs cxt_size=CONTEXT_SIZE
|
||||
lw ra, RV_STK_RA(sp)
|
||||
lw tp, RV_STK_TP(sp)
|
||||
lw t0, RV_STK_T0(sp)
|
||||
lw t1, RV_STK_T1(sp)
|
||||
lw t2, RV_STK_T2(sp)
|
||||
lw s0, RV_STK_S0(sp)
|
||||
lw s1, RV_STK_S1(sp)
|
||||
lw a0, RV_STK_A0(sp)
|
||||
lw a1, RV_STK_A1(sp)
|
||||
lw a2, RV_STK_A2(sp)
|
||||
lw a3, RV_STK_A3(sp)
|
||||
lw a4, RV_STK_A4(sp)
|
||||
lw a5, RV_STK_A5(sp)
|
||||
lw a6, RV_STK_A6(sp)
|
||||
lw a7, RV_STK_A7(sp)
|
||||
lw s2, RV_STK_S2(sp)
|
||||
lw s3, RV_STK_S3(sp)
|
||||
lw s4, RV_STK_S4(sp)
|
||||
lw s5, RV_STK_S5(sp)
|
||||
lw s6, RV_STK_S6(sp)
|
||||
lw s7, RV_STK_S7(sp)
|
||||
lw s8, RV_STK_S8(sp)
|
||||
lw s9, RV_STK_S9(sp)
|
||||
lw s10, RV_STK_S10(sp)
|
||||
lw s11, RV_STK_S11(sp)
|
||||
lw t3, RV_STK_T3(sp)
|
||||
lw t4, RV_STK_T4(sp)
|
||||
lw t5, RV_STK_T5(sp)
|
||||
lw t6, RV_STK_T6(sp)
|
||||
addi sp,sp, \cxt_size
|
||||
.endm
|
||||
|
||||
.macro restore_mepc
|
||||
lw t0, RV_STK_MEPC(sp)
|
||||
csrw mepc, t0
|
||||
.endm
|
||||
|
||||
|
||||
/* _panic_handler: handle all exception */
|
||||
.section .text.handlers,"ax"
|
||||
.global _panic_handler
|
||||
.type _panic_handler, @function
|
||||
_panic_handler:
|
||||
save_general_regs RV_STK_FRMSZ
|
||||
save_mepc
|
||||
|
||||
addi t0, sp, RV_STK_FRMSZ /* Restore sp with the value when trap happened */
|
||||
|
||||
/* Save CSRs */
|
||||
sw t0, RV_STK_SP(sp)
|
||||
csrr t0, mstatus
|
||||
sw t0, RV_STK_MSTATUS(sp)
|
||||
csrr t0, mcause
|
||||
sw t0, RV_STK_MCAUSE(sp)
|
||||
csrr t0, mtvec
|
||||
sw t0, RV_STK_MTVEC(sp)
|
||||
csrr t0, mhartid
|
||||
sw t0, RV_STK_MHARTID(sp)
|
||||
csrr t0, mtval
|
||||
sw t0, RV_STK_MTVAL(sp)
|
||||
|
||||
csrr a1, mcause /* Exception cause */
|
||||
|
||||
mv a0, sp /* RvExcFrame *regs */
|
||||
call ulp_lp_core_panic_handler
|
||||
_end:
|
||||
j _end /* loop forever */
|
||||
|
||||
|
||||
/* _interrupt_handler: handle all interrupt */
|
||||
.section .text.handlers,"ax"
|
||||
.global _interrupt_handler
|
||||
.type _interrupt_handler, @function
|
||||
_interrupt_handler:
|
||||
/* Save registers & mepc to stack */
|
||||
save_general_regs
|
||||
save_mepc
|
||||
|
||||
call ulp_lp_core_intr_handler
|
||||
|
||||
/* Restore registers & mepc from stack */
|
||||
restore_mepc
|
||||
restore_general_regs
|
||||
/* Exit, this will also re-enable the interrupts */
|
||||
mret
|
Loading…
Add table
Add a link
Reference in a new issue