diff --git a/components/esp_system/Kconfig b/components/esp_system/Kconfig index e3f1a51d6e..255bb490b6 100644 --- a/components/esp_system/Kconfig +++ b/components/esp_system/Kconfig @@ -91,6 +91,7 @@ menu "ESP System Settings" default y if IDF_TARGET_ESP32C3 default y if IDF_TARGET_ESP32S3 default y if IDF_TARGET_ESP32H2 + default y if IDF_TARGET_ESP32C6 depends on !IDF_TARGET_ESP32C2 config ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP @@ -301,6 +302,7 @@ menu "ESP System Settings" default 1 if IDF_TARGET_ESP32 default 20 if IDF_TARGET_ESP32C2 default 21 if IDF_TARGET_ESP32C3 + default 16 if IDF_TARGET_ESP32C6 default 43 help This GPIO is used for console UART TX output in the ESP-IDF Bootloader and the app (including @@ -316,6 +318,7 @@ menu "ESP System Settings" default 3 if IDF_TARGET_ESP32 default 19 if IDF_TARGET_ESP32C2 default 20 if IDF_TARGET_ESP32C3 + default 17 if IDF_TARGET_ESP32C6 default 44 help This GPIO is used for UART RX input in the ESP-IDF Bootloader and the app (including diff --git a/components/esp_system/crosscore_int.c b/components/esp_system/crosscore_int.c index 4aae2a2540..9f7535c785 100644 --- a/components/esp_system/crosscore_int.c +++ b/components/esp_system/crosscore_int.c @@ -21,7 +21,7 @@ #if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 #include "soc/dport_reg.h" -#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32C2 +#else #include "soc/system_reg.h" #endif @@ -29,7 +29,7 @@ #define REASON_FREQ_SWITCH BIT(1) #define REASON_GDB_CALL BIT(3) -#if !CONFIG_IDF_TARGET_ESP32C3 && !CONFIG_IDF_TARGET_ESP32H2 && !IDF_TARGET_ESP32C2 +#if !CONFIG_IDF_TARGET_ESP32C3 && !CONFIG_IDF_TARGET_ESP32H2 && !IDF_TARGET_ESP32C2 && !IDF_TARGET_ESP32C6 #define REASON_PRINT_BACKTRACE BIT(2) #define REASON_TWDT_ABORT BIT(4) #endif @@ -66,7 +66,7 @@ static void IRAM_ATTR esp_crosscore_isr(void *arg) { } else { WRITE_PERI_REG(SYSTEM_CPU_INTR_FROM_CPU_1_REG, 0); } -#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32C2 +#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C6 WRITE_PERI_REG(SYSTEM_CPU_INTR_FROM_CPU_0_REG, 0); #endif @@ -145,7 +145,7 @@ static void IRAM_ATTR esp_crosscore_int_send(int core_id, uint32_t reason_mask) } else { WRITE_PERI_REG(SYSTEM_CPU_INTR_FROM_CPU_1_REG, SYSTEM_CPU_INTR_FROM_CPU_1); } -#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32C2 +#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C6 WRITE_PERI_REG(SYSTEM_CPU_INTR_FROM_CPU_0_REG, SYSTEM_CPU_INTR_FROM_CPU_0); #endif } @@ -165,7 +165,7 @@ void IRAM_ATTR esp_crosscore_int_send_gdb_call(int core_id) esp_crosscore_int_send(core_id, REASON_GDB_CALL); } -#if !CONFIG_IDF_TARGET_ESP32C3 && !CONFIG_IDF_TARGET_ESP32H2 && !IDF_TARGET_ESP32C2 +#if !CONFIG_IDF_TARGET_ESP32C3 && !CONFIG_IDF_TARGET_ESP32H2 && !IDF_TARGET_ESP32C2 && !IDF_TARGET_ESP32C6 void IRAM_ATTR esp_crosscore_int_send_print_backtrace(int core_id) { esp_crosscore_int_send(core_id, REASON_PRINT_BACKTRACE); diff --git a/components/esp_system/esp_system.c b/components/esp_system/esp_system.c index 30f657871b..d8c473a95e 100644 --- a/components/esp_system/esp_system.c +++ b/components/esp_system/esp_system.c @@ -11,7 +11,6 @@ #include "freertos/task.h" #include "esp_cpu.h" #include "soc/rtc.h" -#include "soc/rtc_cntl_reg.h" #include "esp_private/panic_internal.h" #include "esp_rom_uart.h" #include "esp_rom_sys.h" diff --git a/components/esp_system/fpga_overrides.c b/components/esp_system/fpga_overrides.c index 70f5fa3850..b46ceaad98 100644 --- a/components/esp_system/fpga_overrides.c +++ b/components/esp_system/fpga_overrides.c @@ -9,7 +9,21 @@ #include "soc/system_reg.h" #endif // not CONFIG_IDF_TARGET_ESP32 #include "soc/rtc.h" -#include "soc/rtc_cntl_reg.h" +#if CONFIG_IDF_TARGET_ESP32 +#include "esp32/rom/rtc.h" +#elif CONFIG_IDF_TARGET_ESP32S2 +#include "esp32s2/rom/rtc.h" +#elif CONFIG_IDF_TARGET_ESP32S3 +#include "esp32s3/rom/rtc.h" +#elif CONFIG_IDF_TARGET_ESP32C3 +#include "esp32c3/rom/rtc.h" +#elif CONFIG_IDF_TARGET_ESP32H2 +#include "esp32h2/rom/rtc.h" +#elif CONFIG_IDF_TARGET_ESP32C2 +#include "esp32c2/rom/rtc.h" +#elif CONFIG_IDF_TARGET_ESP32C6 +#include "esp32c6/rom/rtc.h" +#endif #include "esp_log.h" #include "esp_rom_sys.h" #include "esp_rom_uart.h" @@ -17,13 +31,6 @@ static const char *TAG = "fpga"; -#ifdef CONFIG_IDF_TARGET_ESP32 -#include "esp32/rom/rtc.h" -#endif -#ifdef CONFIG_IDF_TARGET_ESP32S2 -#include "esp32s2/rom/rtc.h" -#endif - extern void ets_update_cpu_frequency(uint32_t ticks_per_us); static void s_warn(void) @@ -42,13 +49,13 @@ void bootloader_clock_configure(void) #elif CONFIG_IDF_TARGET_ESP32H2 uint32_t apb_freq_hz = 32000000; #else - uint32_t apb_freq_hz = 40000000; + uint32_t apb_freq_hz = CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ * 1000000; #endif // CONFIG_IDF_TARGET_ESP32S2 ets_update_cpu_frequency(apb_freq_hz / 1000000); #ifdef RTC_APB_FREQ_REG REG_WRITE(RTC_APB_FREQ_REG, (apb_freq_hz >> 12) | ((apb_freq_hz >> 12) << 16)); #endif - REG_WRITE(RTC_CNTL_STORE4_REG, (xtal_freq_mhz) | ((xtal_freq_mhz) << 16)); + REG_WRITE(RTC_XTAL_FREQ_REG, (xtal_freq_mhz) | ((xtal_freq_mhz) << 16)); } /* Placed in IRAM since test_apps expects it to be */ diff --git a/components/esp_system/include/esp_private/crosscore_int.h b/components/esp_system/include/esp_private/crosscore_int.h index 0acdbb8159..5a37780911 100644 --- a/components/esp_system/include/esp_private/crosscore_int.h +++ b/components/esp_system/include/esp_private/crosscore_int.h @@ -50,7 +50,7 @@ void esp_crosscore_int_send_freq_switch(int core_id); void esp_crosscore_int_send_gdb_call(int core_id); -#if !CONFIG_IDF_TARGET_ESP32C3 && !CONFIG_IDF_TARGET_ESP32H2 && !CONFIG_IDF_TARGET_ESP32C2 +#if !CONFIG_IDF_TARGET_ESP32C3 && !CONFIG_IDF_TARGET_ESP32H2 && !CONFIG_IDF_TARGET_ESP32C2 && !CONFIG_IDF_TARGET_ESP32C6 /** * Send an interrupt to a CPU indicating it should print its current backtrace * diff --git a/components/esp_system/ld/esp32c6/memory.ld.in b/components/esp_system/ld/esp32c6/memory.ld.in index e69de29bb2..95178e726b 100644 --- a/components/esp_system/ld/esp32c6/memory.ld.in +++ b/components/esp_system/ld/esp32c6/memory.ld.in @@ -0,0 +1,149 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * ESP32-C6 Linker Script Memory Layout + * This file describes the memory layout (memory blocks) by virtual memory addresses. + * This linker script is passed through the C preprocessor to include configuration options. + * Please use preprocessor features sparingly! + * Restrict to simple macros with numeric values, and/or #if/#endif blocks. + */ + +#include "sdkconfig.h" +#include "ld.common" + +#ifdef CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC +#define ESP_BOOTLOADER_RESERVE_RTC (CONFIG_BOOTLOADER_RESERVE_RTC_SIZE + CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC_SIZE) +#elif defined(CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP) +#define ESP_BOOTLOADER_RESERVE_RTC (CONFIG_BOOTLOADER_RESERVE_RTC_SIZE) +#else +#define ESP_BOOTLOADER_RESERVE_RTC 0 +#endif + +/** + * physical memory is mapped twice to the vritual address (IRAM and DRAM). + * `I_D_SRAM_OFFSET` is the offset between the two locations of the same physical memory + */ +#define SRAM_IRAM_START 0x40800000 +#define SRAM_DRAM_START 0x40800000 + +#define I_D_SRAM_OFFSET (SRAM_IRAM_START - SRAM_DRAM_START) +#define SRAM_DRAM_END 0x40880000 - I_D_SRAM_OFFSET /* 2nd stage bootloader iram_loader_seg start address */ + +#define SRAM_IRAM_ORG (SRAM_IRAM_START) +#define SRAM_DRAM_ORG (SRAM_DRAM_START) + +#define I_D_SRAM_SIZE SRAM_DRAM_END - SRAM_DRAM_ORG + +#if CONFIG_APP_BUILD_USE_FLASH_SECTIONS +/* + * IDRAM0_2_SEG_SIZE_DEFAULT is used when page size is 64KB + */ +#define IDRAM0_2_SEG_SIZE (CONFIG_MMU_PAGE_SIZE << 8) +#endif + +#if CONFIG_ESP32C6_USE_FIXED_STATIC_RAM_SIZE +ASSERT((CONFIG_ESP32C6_FIXED_STATIC_RAM_SIZE <= I_D_SRAM_SIZE), "Fixed static ram data does not fit.") +#define DRAM0_0_SEG_LEN CONFIG_ESP3C6_FIXED_STATIC_RAM_SIZE +#else +#define DRAM0_0_SEG_LEN I_D_SRAM_SIZE +#endif // CONFIG_ESP32C6_USE_FIXED_STATIC_RAM_SIZE +MEMORY +{ + /** + * All these values assume the flash cache is on, and have the blocks this uses subtracted from the length + * of the various regions. The 'data access port' dram/drom regions map to the same iram/irom regions but + * are connected to the data port of the CPU and eg allow byte-wise access. + */ + + /* IRAM for PRO CPU. */ + iram0_0_seg (RX) : org = SRAM_IRAM_ORG, len = I_D_SRAM_SIZE + +#if CONFIG_APP_BUILD_USE_FLASH_SECTIONS + /* Flash mapped instruction data */ + iram0_2_seg (RX) : org = 0x42000020, len = (IDRAM0_2_SEG_SIZE >> 1) -0x20 + + /** + * (0x20 offset above is a convenience for the app binary image generation. + * Flash cache has 64KB pages. The .bin file which is flashed to the chip + * has a 0x18 byte file header, and each segment has a 0x08 byte segment + * header. Setting this offset makes it simple to meet the flash cache MMU's + * constraint that (paddr % 64KB == vaddr % 64KB).) + */ +#endif // CONFIG_APP_BUILD_USE_FLASH_SECTIONS + + /** + * Shared data RAM, excluding memory reserved for ROM bss/data/stack. + * Enabling Bluetooth & Trace Memory features in menuconfig will decrease the amount of RAM available. + */ + dram0_0_seg (RW) : org = SRAM_DRAM_ORG, len = DRAM0_0_SEG_LEN + +#if CONFIG_APP_BUILD_USE_FLASH_SECTIONS + /* Flash mapped constant data */ + drom0_0_seg (R) : org = 0x42000020 + (IDRAM0_2_SEG_SIZE >> 1), len = (IDRAM0_2_SEG_SIZE >> 1)-0x20 + + /* (See iram0_2_seg for meaning of 0x20 offset in the above.) */ +#endif // CONFIG_APP_BUILD_USE_FLASH_SECTIONS + + /** + * lp ram memory (RWX). Persists over deep sleep. // TODO: IDF-5667 + */ +#if CONFIG_ULP_COPROC_ENABLED + lp_ram_seg(RW) : org = 0x50000000 + CONFIG_ULP_COPROC_RESERVE_MEM, + len = 0x4000 - CONFIG_ULP_COPROC_RESERVE_MEM +#else + lp_ram_seg(RW) : org = 0x50000000 , len = 0x4000 +#endif // CONFIG_ULP_COPROC_ENABLED + +} + +#if CONFIG_ESP32C6_USE_FIXED_STATIC_RAM_SIZE +/* static data ends at defined address */ +_static_data_end = 0x40820000 + DRAM0_0_SEG_LEN; +#else +_static_data_end = _bss_end; +#endif // CONFIG_ESP32C6_USE_FIXED_STATIC_RAM_SIZE + +/* Heap ends at top of dram0_0_seg */ +_heap_end = 0x40000000; + +_data_seg_org = ORIGIN(rtc_data_seg); + +/** + * The lines below define location alias for .rtc.data section + * C6 has no distinguished LP(RTC) fast and slow memory sections, instead, there is a unified LP_RAM section + * Thus, the following region segments are not configurable like on other targets + */ +REGION_ALIAS("rtc_iram_seg", lp_ram_seg ); +REGION_ALIAS("rtc_data_seg", rtc_iram_seg ); +REGION_ALIAS("rtc_slow_seg", rtc_iram_seg ); +REGION_ALIAS("rtc_data_location", rtc_iram_seg ); + +#if CONFIG_APP_BUILD_USE_FLASH_SECTIONS + REGION_ALIAS("default_code_seg", iram0_2_seg); +#else + REGION_ALIAS("default_code_seg", iram0_0_seg); +#endif // CONFIG_APP_BUILD_USE_FLASH_SECTIONS + +#if CONFIG_APP_BUILD_USE_FLASH_SECTIONS + REGION_ALIAS("default_rodata_seg", drom0_0_seg); +#else + REGION_ALIAS("default_rodata_seg", dram0_0_seg); +#endif // CONFIG_APP_BUILD_USE_FLASH_SECTIONS + +/** + * If rodata default segment is placed in `drom0_0_seg`, then flash's first rodata section must + * also be first in the segment. + */ +#if CONFIG_APP_BUILD_USE_FLASH_SECTIONS + ASSERT(_flash_rodata_dummy_start == ORIGIN(default_rodata_seg), + ".flash_rodata_dummy section must be placed at the beginning of the rodata segment.") +#endif + +#if CONFIG_ESP_SYSTEM_USE_EH_FRAME + ASSERT ((__eh_frame_end > __eh_frame), "Error: eh_frame size is null!"); + ASSERT ((__eh_frame_hdr_end > __eh_frame_hdr), "Error: eh_frame_hdr size is null!"); +#endif diff --git a/components/esp_system/ld/esp32c6/sections.ld.in b/components/esp_system/ld/esp32c6/sections.ld.in new file mode 100644 index 0000000000..b32633a5e5 --- /dev/null +++ b/components/esp_system/ld/esp32c6/sections.ld.in @@ -0,0 +1,410 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* Default entry point */ +ENTRY(call_start_cpu0); + +SECTIONS +{ + /** + * RTC fast memory holds RTC wake stub code, + * including from any source file named rtc_wake_stub*.c + */ + .rtc.text : + { + . = ALIGN(4); + _rtc_fast_start = ABSOLUTE(.); + + mapping[rtc_text] + + *rtc_wake_stub*.*(.literal .text .literal.* .text.*) + *(.rtc_text_end_test) + + /* 16B padding for possible CPU prefetch and 4B alignment for PMS split lines */ + . += _esp_memprot_prefetch_pad_size; + . = ALIGN(4); + + _rtc_text_end = ABSOLUTE(.); + } > lp_ram_seg + + /** + * This section located in RTC FAST Memory area. + * It holds data marked with RTC_FAST_ATTR attribute. + * See the file "esp_attr.h" for more information. + */ + .rtc.force_fast : + { + . = ALIGN(4); + _rtc_force_fast_start = ABSOLUTE(.); + + mapping[rtc_force_fast] + + *(.rtc.force_fast .rtc.force_fast.*) + . = ALIGN(4) ; + _rtc_force_fast_end = ABSOLUTE(.); + } > lp_ram_seg + + /** + * RTC data section holds RTC wake stub + * data/rodata, including from any source file + * named rtc_wake_stub*.c and the data marked with + * RTC_DATA_ATTR, RTC_RODATA_ATTR attributes. + */ + .rtc.data : + { + _rtc_data_start = ABSOLUTE(.); + + mapping[rtc_data] + + *rtc_wake_stub*.*(.data .rodata .data.* .rodata.* .bss .bss.*) + _rtc_data_end = ABSOLUTE(.); + } > lp_ram_seg + + /* RTC bss, from any source file named rtc_wake_stub*.c */ + .rtc.bss (NOLOAD) : + { + _rtc_bss_start = ABSOLUTE(.); + *rtc_wake_stub*.*(.bss .bss.*) + *rtc_wake_stub*.*(COMMON) + + mapping[rtc_bss] + + _rtc_bss_end = ABSOLUTE(.); + } > lp_ram_seg + + /** + * This section holds data that should not be initialized at power up + * and will be retained during deep sleep. + * User data marked with RTC_NOINIT_ATTR will be placed + * into this section. See the file "esp_attr.h" for more information. + */ + .rtc_noinit (NOLOAD): + { + . = ALIGN(4); + _rtc_noinit_start = ABSOLUTE(.); + *(.rtc_noinit .rtc_noinit.*) + . = ALIGN(4) ; + _rtc_noinit_end = ABSOLUTE(.); + } > lp_ram_seg + + /** + * This section located in RTC SLOW Memory area. + * It holds data marked with RTC_SLOW_ATTR attribute. + * See the file "esp_attr.h" for more information. + */ + .rtc.force_slow : + { + . = ALIGN(4); + _rtc_force_slow_start = ABSOLUTE(.); + *(.rtc.force_slow .rtc.force_slow.*) + . = ALIGN(4) ; + _rtc_force_slow_end = ABSOLUTE(.); + } > lp_ram_seg + + /* Get size of rtc slow data based on rtc_data_location alias */ + _rtc_slow_length = (ORIGIN(rtc_slow_seg) == ORIGIN(rtc_data_location)) + ? (_rtc_force_slow_end - _rtc_data_start) + : (_rtc_force_slow_end - _rtc_force_slow_start); + + _rtc_fast_length = (ORIGIN(rtc_slow_seg) == ORIGIN(rtc_data_location)) + ? (_rtc_force_fast_end - _rtc_fast_start) + : (_rtc_noinit_end - _rtc_fast_start); + + ASSERT((_rtc_slow_length <= LENGTH(rtc_slow_seg)), + "RTC_SLOW segment data does not fit.") + + ASSERT((_rtc_fast_length <= LENGTH(rtc_data_seg)), + "RTC_FAST segment data does not fit.") + + .iram0.text : + { + _iram_start = ABSOLUTE(.); + /* Vectors go to start of IRAM */ + ASSERT(ABSOLUTE(.) % 0x100 == 0, "vector address must be 256 byte aligned"); + KEEP(*(.exception_vectors.text)); + . = ALIGN(4); + + _invalid_pc_placeholder = ABSOLUTE(.); + + /* Code marked as running out of IRAM */ + _iram_text_start = ABSOLUTE(.); + + mapping[iram0_text] + + } > iram0_0_seg + + /* Marks the end of IRAM code segment */ + .iram0.text_end (NOLOAD) : + { + /* ESP32-C6 memprot requires 16B padding for possible CPU prefetch and 512B alignment for PMS split lines */ + . += _esp_memprot_prefetch_pad_size; + . = ALIGN(_esp_memprot_align_size); + /* iram_end_test section exists for use by memprot unit tests only */ + *(.iram_end_test) + _iram_text_end = ABSOLUTE(.); + } > iram0_0_seg + + .iram0.data : + { + . = ALIGN(16); + _iram_data_start = ABSOLUTE(.); + + mapping[iram0_data] + + _iram_data_end = ABSOLUTE(.); + } > iram0_0_seg + + .iram0.bss (NOLOAD) : + { + . = ALIGN(16); + _iram_bss_start = ABSOLUTE(.); + + mapping[iram0_bss] + + _iram_bss_end = ABSOLUTE(.); + . = ALIGN(16); + _iram_end = ABSOLUTE(.); + } > iram0_0_seg + + /** + * This section is required to skip .iram0.text area because iram0_0_seg and + * dram0_0_seg reflect the same address space on different buses. + */ + .dram0.dummy (NOLOAD): + { + . = ORIGIN(dram0_0_seg) + _iram_end - _iram_start; + } > dram0_0_seg + + .dram0.data : + { + _data_start = ABSOLUTE(.); + *(.gnu.linkonce.d.*) + *(.data1) + __global_pointer$ = . + 0x800; + *(.sdata) + *(.sdata.*) + *(.gnu.linkonce.s.*) + *(.gnu.linkonce.s2.*) + *(.jcr) + + mapping[dram0_data] + + _data_end = ABSOLUTE(.); + . = ALIGN(4); + } > dram0_0_seg + + /** + * This section holds data that should not be initialized at power up. + * The section located in Internal SRAM memory region. The macro _NOINIT + * can be used as attribute to place data into this section. + * See the "esp_attr.h" file for more information. + */ + .noinit (NOLOAD): + { + . = ALIGN(4); + _noinit_start = ABSOLUTE(.); + *(.noinit .noinit.*) + . = ALIGN(4) ; + _noinit_end = ABSOLUTE(.); + } > dram0_0_seg + + /* Shared RAM */ + .dram0.bss (NOLOAD) : + { + . = ALIGN (8); + _bss_start = ABSOLUTE(.); + + mapping[dram0_bss] + + *(.dynsbss) + *(.sbss) + *(.sbss.*) + *(.gnu.linkonce.sb.*) + *(.scommon) + *(.sbss2) + *(.sbss2.*) + *(.gnu.linkonce.sb2.*) + *(.dynbss) + *(.share.mem) + *(.gnu.linkonce.b.*) + + . = ALIGN (8); + _bss_end = ABSOLUTE(.); + } > dram0_0_seg + + ASSERT(((_bss_end - ORIGIN(dram0_0_seg)) <= LENGTH(dram0_0_seg)), "DRAM segment data does not fit.") + + .flash.text : + { + _stext = .; + _instruction_reserved_start = ABSOLUTE(.); + _text_start = ABSOLUTE(.); + + mapping[flash_text] + + *(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) + *(.irom0.text) /* catch stray ICACHE_RODATA_ATTR */ + *(.fini.literal) + *(.fini) + *(.gnu.version) + + /** CPU will try to prefetch up to 16 bytes of + * of instructions. This means that any configuration (e.g. MMU, PMS) must allow + * safe access to up to 16 bytes after the last real instruction, add + * dummy bytes to ensure this + */ + . += _esp_flash_mmap_prefetch_pad_size; + + _text_end = ABSOLUTE(.); + _instruction_reserved_end = ABSOLUTE(.); + _etext = .; + + /** + * Similar to _iram_start, this symbol goes here so it is + * resolved by addr2line in preference to the first symbol in + * the flash.text segment. + */ + _flash_cache_start = ABSOLUTE(0); + } > default_code_seg + + /** + * This dummy section represents the .flash.text section but in default_rodata_seg. + * Thus, it must have its alignment and (at least) its size. + */ + .flash_rodata_dummy (NOLOAD): + { + _flash_rodata_dummy_start = .; + /* Start at the same alignment constraint than .flash.text */ + . = ALIGN(ALIGNOF(.flash.text)); + /* Create an empty gap as big as .flash.text section */ + . = . + SIZEOF(.flash.text); + /* Prepare the alignment of the section above. Few bytes (0x20) must be + * added for the mapping header. */ + . = ALIGN(0x10000) + 0x20; + _rodata_reserved_start = .; + } > default_rodata_seg + + .flash.appdesc : ALIGN(0x10) + { + _rodata_start = ABSOLUTE(.); + + *(.rodata_desc .rodata_desc.*) /* Should be the first. App version info. DO NOT PUT ANYTHING BEFORE IT! */ + *(.rodata_custom_desc .rodata_custom_desc.*) /* Should be the second. Custom app version info. DO NOT PUT ANYTHING BEFORE IT! */ + + /* Create an empty gap within this section. Thanks to this, the end of this + * section will match .flash.rodata's begin address. Thus, both sections + * will be merged when creating the final bin image. */ + . = ALIGN(ALIGNOF(.flash.rodata)); + } >default_rodata_seg + + .flash.rodata : ALIGN(0x10) + { + _flash_rodata_start = ABSOLUTE(.); + + mapping[flash_rodata] + + *(.irom1.text) /* catch stray ICACHE_RODATA_ATTR */ + *(.gnu.linkonce.r.*) + *(.rodata1) + __XT_EXCEPTION_TABLE_ = ABSOLUTE(.); + *(.xt_except_table) + *(.gcc_except_table .gcc_except_table.*) + *(.gnu.linkonce.e.*) + *(.gnu.version_r) + . = (. + 7) & ~ 3; + /* + * C++ constructor and destructor tables + * Don't include anything from crtbegin.o or crtend.o, as IDF doesn't use toolchain crt. + * + * RISC-V gcc is configured with --enable-initfini-array so it emits an .init_array section instead. + * But the init_priority sections will be sorted for iteration in ascending order during startup. + * The rest of the init_array sections is sorted for iteration in descending order during startup, however. + * Hence a different section is generated for the init_priority functions which is iterated in + * ascending order during startup. The corresponding code can be found in startup.c. + */ + __init_priority_array_start = ABSOLUTE(.); + KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array.*)) + __init_priority_array_end = ABSOLUTE(.); + __init_array_start = ABSOLUTE(.); + KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array)) + __init_array_end = ABSOLUTE(.); + KEEP (*crtbegin.*(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.*) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + /* C++ exception handlers table: */ + __XT_EXCEPTION_DESCS_ = ABSOLUTE(.); + *(.xt_except_desc) + *(.gnu.linkonce.h.*) + __XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.); + *(.xt_except_desc_end) + *(.dynamic) + *(.gnu.version_d) + /* Addresses of memory regions reserved via SOC_RESERVE_MEMORY_REGION() */ + soc_reserved_memory_region_start = ABSOLUTE(.); + KEEP (*(.reserved_memory_address)) + soc_reserved_memory_region_end = ABSOLUTE(.); + /* System init functions registered via ESP_SYSTEM_INIT_FN */ + _esp_system_init_fn_array_start = ABSOLUTE(.); + KEEP (*(SORT_BY_INIT_PRIORITY(.esp_system_init_fn.*))) + _esp_system_init_fn_array_end = ABSOLUTE(.); + _rodata_end = ABSOLUTE(.); + /* Literals are also RO data. */ + _lit4_start = ABSOLUTE(.); + *(*.lit4) + *(.lit4.*) + *(.gnu.linkonce.lit4.*) + _lit4_end = ABSOLUTE(.); + . = ALIGN(4); + _thread_local_start = ABSOLUTE(.); + *(.tdata) + *(.tdata.*) + *(.tbss) + *(.tbss.*) + _thread_local_end = ABSOLUTE(.); + _rodata_reserved_end = ABSOLUTE(.); + . = ALIGN(ALIGNOF(.eh_frame)); + } > default_rodata_seg + + /* Keep this section shall be at least aligned on 4 */ + .eh_frame : ALIGN(8) + { + __eh_frame = ABSOLUTE(.); + KEEP (*(.eh_frame)) + __eh_frame_end = ABSOLUTE(.); + /* Guarantee that this section and the next one will be merged by making + * them adjacent. */ + . = ALIGN(ALIGNOF(.eh_frame_hdr)); + } > default_rodata_seg + + /* To avoid any exception in C++ exception frame unwinding code, this section + * shall be aligned on 8. */ + .eh_frame_hdr : ALIGN(8) + { + __eh_frame_hdr = ABSOLUTE(.); + KEEP (*(.eh_frame_hdr)) + __eh_frame_hdr_end = ABSOLUTE(.); + } > default_rodata_seg + + .flash.rodata_noload (NOLOAD) : + { + . = ALIGN (4); + mapping[rodata_noload] + } > default_rodata_seg + + /* Marks the end of data, bss and possibly rodata */ + .dram0.heap_start (NOLOAD) : + { + . = ALIGN (16); + _heap_start = ABSOLUTE(.); + } > dram0_0_seg +} + +ASSERT(((_iram_end - ORIGIN(iram0_0_seg)) <= LENGTH(iram0_0_seg)), + "IRAM0 segment data does not fit.") + +ASSERT(((_heap_start - ORIGIN(dram0_0_seg)) <= LENGTH(dram0_0_seg)), + "DRAM segment data does not fit.") diff --git a/components/esp_system/panic.c b/components/esp_system/panic.c index d060f48bfb..51a1801f46 100644 --- a/components/esp_system/panic.c +++ b/components/esp_system/panic.c @@ -61,7 +61,11 @@ bool g_panic_abort = false; static char *s_panic_abort_details = NULL; +#if CONFIG_IDF_TARGET_ESP32C6 // TODO: IDF-5653 +static wdt_hal_context_t rtc_wdt_ctx = {.inst = WDT_RWDT, .rwdt_dev = &LP_WDT}; +#else static wdt_hal_context_t rtc_wdt_ctx = {.inst = WDT_RWDT, .rwdt_dev = &RTCCNTL}; +#endif #if !CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT diff --git a/components/esp_system/port/arch/riscv/panic_arch.c b/components/esp_system/port/arch/riscv/panic_arch.c index 3afa68ae6e..2fb3bd0dda 100644 --- a/components/esp_system/port/arch/riscv/panic_arch.c +++ b/components/esp_system/port/arch/riscv/panic_arch.c @@ -76,6 +76,7 @@ static inline bool test_and_print_register_bits(const uint32_t status, */ static inline void print_cache_err_details(const void *frame) { +#if !CONFIG_IDF_TARGET_ESP32C6 // TODO: IDF-5657 /* Define the array that contains the status (bits) to test on the register * EXTMEM_CORE0_ACS_CACHE_INT_ST_REG. each bit is accompanied by a small * message. @@ -148,6 +149,7 @@ static inline void print_cache_err_details(const void *frame) panic_print_str("\r\n"); } } +#endif } diff --git a/components/esp_system/port/brownout.c b/components/esp_system/port/brownout.c index c700f79d7d..3d146ce00d 100644 --- a/components/esp_system/port/brownout.c +++ b/components/esp_system/port/brownout.c @@ -76,7 +76,11 @@ void esp_brownout_init(void) brownout_hal_config(&cfg); brownout_hal_intr_clear(); +#if CONFIG_IDF_TARGET_ESP32C6 // TODO: IDF-5645 + rtc_isr_register(rtc_brownout_isr_handler, NULL, LP_ANALOG_PERI_LP_ANA_BOD_MODE0_LP_INT_ENA_M, RTC_INTR_FLAG_IRAM); +#else rtc_isr_register(rtc_brownout_isr_handler, NULL, RTC_CNTL_BROWN_OUT_INT_ENA_M, RTC_INTR_FLAG_IRAM); +#endif brownout_hal_intr_enable(true); #else // brownout without interrupt diff --git a/components/esp_system/port/cpu_start.c b/components/esp_system/port/cpu_start.c index abd5dc8f59..ebc7d03cd7 100644 --- a/components/esp_system/port/cpu_start.c +++ b/components/esp_system/port/cpu_start.c @@ -47,6 +47,10 @@ #include "esp32c3/rom/cache.h" #include "esp32c3/rom/secure_boot.h" #include "esp_memprot.h" +#elif CONFIG_IDF_TARGET_ESP32C6 +#include "esp32c6/rtc.h" +#include "esp32c6/rom/cache.h" +#include "esp_memprot.h" #elif CONFIG_IDF_TARGET_ESP32H2 #include "esp32h2/rtc.h" #include "esp32h2/rom/cache.h" @@ -287,7 +291,11 @@ void IRAM_ATTR call_start_cpu0(void) || rst_reas[1] == RESET_REASON_CORE_RTC_WDT || rst_reas[1] == RESET_REASON_CORE_MWDT0 #endif ) { +#if CONFIG_IDF_TARGET_ESP32C6 // TODO: IDF-5653 + wdt_hal_context_t rtc_wdt_ctx = {.inst = WDT_RWDT, .rwdt_dev = &LP_WDT}; +#else wdt_hal_context_t rtc_wdt_ctx = {.inst = WDT_RWDT, .rwdt_dev = &RTCCNTL}; +#endif wdt_hal_write_protect_disable(&rtc_wdt_ctx); wdt_hal_disable(&rtc_wdt_ctx); wdt_hal_write_protect_enable(&rtc_wdt_ctx); @@ -341,7 +349,7 @@ void IRAM_ATTR call_start_cpu0(void) esp_restart(); } -#if CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32C2 +#if CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C6 /* Configure the Cache MMU size for instruction and rodata in flash. */ extern uint32_t Cache_Set_IDROM_MMU_Size(uint32_t irom_size, uint32_t drom_size); extern int _rodata_reserved_start; @@ -354,7 +362,7 @@ void IRAM_ATTR call_start_cpu0(void) #endif Cache_Set_IDROM_MMU_Size(cache_mmu_irom_size, CACHE_DROM_MMU_MAX_END - cache_mmu_irom_size); -#endif // CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32C2 +#endif // CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C6 #if CONFIG_ESPTOOLPY_OCT_FLASH bool efuse_opflash_en = efuse_ll_get_flash_type(); @@ -473,7 +481,7 @@ void IRAM_ATTR call_start_cpu0(void) #endif #if CONFIG_IDF_TARGET_ESP32C2 -// TODO : IDF-4194 +// TODO : IDF-5020 #if CONFIG_ESP32C2_INSTRUCTION_CACHE_WRAP extern void esp_enable_cache_wrap(uint32_t icache_wrap_enable); esp_enable_cache_wrap(1); diff --git a/components/esp_system/port/soc/esp32c6/CMakeLists.txt b/components/esp_system/port/soc/esp32c6/CMakeLists.txt index e69de29bb2..d77109f3b5 100644 --- a/components/esp_system/port/soc/esp32c6/CMakeLists.txt +++ b/components/esp_system/port/soc/esp32c6/CMakeLists.txt @@ -0,0 +1,12 @@ +set(srcs "clk.c" + "reset_reason.c" + "system_internal.c" + "cache_err_int.c" + "../../arch/riscv/expression_with_stack.c" + "../../arch/riscv/expression_with_stack_asm.S" + "../../arch/riscv/panic_arch.c" + "../../arch/riscv/debug_stubs.c") + +add_prefix(srcs "${CMAKE_CURRENT_LIST_DIR}/" ${srcs}) + +target_sources(${COMPONENT_LIB} PRIVATE ${srcs}) diff --git a/components/esp_system/port/soc/esp32c6/Kconfig.cpu b/components/esp_system/port/soc/esp32c6/Kconfig.cpu index e69de29bb2..414e4377f3 100644 --- a/components/esp_system/port/soc/esp32c6/Kconfig.cpu +++ b/components/esp_system/port/soc/esp32c6/Kconfig.cpu @@ -0,0 +1,21 @@ +choice ESP_DEFAULT_CPU_FREQ_MHZ + prompt "CPU frequency" + default ESP_DEFAULT_CPU_FREQ_MHZ_40 if IDF_ENV_FPGA + default ESP_DEFAULT_CPU_FREQ_MHZ_160 + help + CPU frequency to be set on application startup. + + config ESP_DEFAULT_CPU_FREQ_MHZ_40 + bool "40 MHz" + depends on IDF_ENV_FPGA + config ESP_DEFAULT_CPU_FREQ_MHZ_80 + bool "80 MHz" + config ESP_DEFAULT_CPU_FREQ_MHZ_160 + bool "160 MHz" +endchoice + +config ESP_DEFAULT_CPU_FREQ_MHZ + int + default 40 if ESP_DEFAULT_CPU_FREQ_MHZ_40 + default 80 if ESP_DEFAULT_CPU_FREQ_MHZ_80 + default 160 if ESP_DEFAULT_CPU_FREQ_MHZ_160 diff --git a/components/esp_system/port/soc/esp32c6/Kconfig.system b/components/esp_system/port/soc/esp32c6/Kconfig.system index e69de29bb2..1427bb2521 100644 --- a/components/esp_system/port/soc/esp32c6/Kconfig.system +++ b/components/esp_system/port/soc/esp32c6/Kconfig.system @@ -0,0 +1,45 @@ +menu "Brownout Detector" + config ESP_BROWNOUT_DET + bool "Hardware brownout detect & reset" + depends on !IDF_ENV_FPGA + default y + help + The ESP32-C6 has a built-in brownout detector which can detect if the voltage is lower than + a specific value. If this happens, it will reset the chip in order to prevent unintended + behaviour. + + choice ESP_BROWNOUT_DET_LVL_SEL + prompt "Brownout voltage level" + depends on ESP_BROWNOUT_DET + default ESP_BROWNOUT_DET_LVL_SEL_7 + help + The brownout detector will reset the chip when the supply voltage is approximately + below this level. Note that there may be some variation of brownout voltage level + between each chip. + + #The voltage levels here are estimates, more work needs to be done to figure out the exact voltages + #of the brownout threshold levels. + config ESP_BROWNOUT_DET_LVL_SEL_7 + bool "2.51V" + config ESP_BROWNOUT_DET_LVL_SEL_6 + bool "2.64V" + config ESP_BROWNOUT_DET_LVL_SEL_5 + bool "2.76V" + config ESP_BROWNOUT_DET_LVL_SEL_4 + bool "2.92V" + config ESP_BROWNOUT_DET_LVL_SEL_3 + bool "3.10V" + config ESP_BROWNOUT_DET_LVL_SEL_2 + bool "3.27V" + endchoice + + config ESP_BROWNOUT_DET_LVL + int + default 2 if ESP_BROWNOUT_DET_LVL_SEL_2 + default 3 if ESP_BROWNOUT_DET_LVL_SEL_3 + default 4 if ESP_BROWNOUT_DET_LVL_SEL_4 + default 5 if ESP_BROWNOUT_DET_LVL_SEL_5 + default 6 if ESP_BROWNOUT_DET_LVL_SEL_6 + default 7 if ESP_BROWNOUT_DET_LVL_SEL_7 + +endmenu diff --git a/components/esp_system/port/soc/esp32c6/cache_err_int.c b/components/esp_system/port/soc/esp32c6/cache_err_int.c new file mode 100644 index 0000000000..44ac5fb759 --- /dev/null +++ b/components/esp_system/port/soc/esp32c6/cache_err_int.c @@ -0,0 +1,81 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + The cache has an interrupt that can be raised as soon as an access to a cached + region (flash) is done without the cache being enabled. We use that here + to panic the CPU, which from a debugging perspective is better than grabbing bad + data from the bus. +*/ +#include "esp_rom_sys.h" +#include "esp_attr.h" +#include "esp_log.h" +#include "esp_intr_alloc.h" +#include "soc/periph_defs.h" +#include "riscv/interrupt.h" +#include "hal/cache_ll.h" + +static const char *TAG = "CACHE_ERR"; + +void esp_cache_err_int_init(void) +{ + ESP_EARLY_LOGW(TAG, "esp_cache_err_int_init() has not been implemented yet"); +#if 0 // TODO: IDF-5656 + const uint32_t core_id = 0; + + /* Disable cache interrupts if enabled. */ + ESP_INTR_DISABLE(ETS_CACHEERR_INUM); + + /** + * Bind all cache errors to ETS_CACHEERR_INUM interrupt. we will deal with + * them in handler by different types + * I) Cache access error + * 1. dbus trying to write to icache + * 2. dbus authentication fail + * 3. cpu access icache while dbus is disabled [1] + * 4. ibus authentication fail + * 5. ibus trying to write icache + * 6. cpu access icache while ibus is disabled + * II) Cache illegal error + * 1. dbus counter overflow + * 2. ibus counter overflow + * 3. mmu entry fault + * 4. icache preload configurations fault + * 5. icache sync configuration fault + * + * [1]: On ESP32C6 boards, the caches are shared but buses are still + * distinct. So, we have an ibus and a dbus sharing the same cache. + * This error can occur if the dbus performs a request but the icache + * (or simply cache) is disabled. + */ + esp_rom_route_intr_matrix(core_id, ETS_CACHE_IA_INTR_SOURCE, ETS_CACHEERR_INUM); + esp_rom_route_intr_matrix(core_id, ETS_CACHE_CORE0_ACS_INTR_SOURCE, ETS_CACHEERR_INUM); + + /* Set the type and priority to cache error interrupts. */ + esprv_intc_int_set_type(BIT(ETS_CACHEERR_INUM), INTR_TYPE_LEVEL); + esprv_intc_int_set_priority(ETS_CACHEERR_INUM, SOC_INTERRUPT_LEVEL_MEDIUM); + + ESP_DRAM_LOGV(TAG, "access error intr clr & ena mask is: 0x%x", CACHE_LL_L1_ACCESS_EVENT_MASK); + /* On the hardware side, start by clearing all the bits reponsible for cache access error */ + cache_ll_l1_clear_access_error_intr(0, CACHE_LL_L1_ACCESS_EVENT_MASK); + /* Then enable cache access error interrupts. */ + cache_ll_l1_enable_access_error_intr(0, CACHE_LL_L1_ACCESS_EVENT_MASK); + + /* Same goes for cache illegal error: start by clearing the bits and then + * set them back. */ + ESP_DRAM_LOGV(TAG, "illegal error intr clr & ena mask is: 0x%x", CACHE_LL_L1_ILG_EVENT_MASK); + cache_ll_l1_clear_illegal_error_intr(0, CACHE_LL_L1_ILG_EVENT_MASK); + cache_ll_l1_enable_illegal_error_intr(0, CACHE_LL_L1_ILG_EVENT_MASK); + + /* Enable the interrupts for cache error. */ + ESP_INTR_ENABLE(ETS_CACHEERR_INUM); +#endif +} + +int IRAM_ATTR esp_cache_err_get_cpuid(void) +{ + return 0; +} diff --git a/components/esp_system/port/soc/esp32c6/clk.c b/components/esp_system/port/soc/esp32c6/clk.c new file mode 100644 index 0000000000..f27a26561f --- /dev/null +++ b/components/esp_system/port/soc/esp32c6/clk.c @@ -0,0 +1,305 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include "sdkconfig.h" +#include "esp_attr.h" +#include "esp_log.h" +#include "esp_clk_internal.h" +#include "esp32c6/rom/ets_sys.h" +#include "esp32c6/rom/uart.h" +// #include "soc/system_reg.h" +#include "soc/soc.h" +#include "soc/rtc.h" +#include "soc/rtc_periph.h" +#include "soc/i2s_reg.h" +#include "esp_cpu.h" +#include "hal/wdt_hal.h" +#include "esp_private/periph_ctrl.h" +#include "esp_private/esp_clk.h" +#include "bootloader_clock.h" +// #include "soc/syscon_reg.h" +#include "esp_rom_uart.h" +#include "esp_rom_sys.h" + +/* Number of cycles to wait from the 32k XTAL oscillator to consider it running. + * Larger values increase startup delay. Smaller values may cause false positive + * detection (i.e. oscillator runs for a few cycles and then stops). + */ +#define SLOW_CLK_CAL_CYCLES CONFIG_RTC_CLK_CAL_CYCLES + +#define MHZ (1000000) + +/* Lower threshold for a reasonably-looking calibration value for a 32k XTAL. + * The ideal value (assuming 32768 Hz frequency) is 1000000/32768*(2**19) = 16*10^6. + */ +#define MIN_32K_XTAL_CAL_VAL 15000000L + +/* Indicates that this 32k oscillator gets input from external oscillator, rather + * than a crystal. + */ +#define EXT_OSC_FLAG BIT(3) + +/* This is almost the same as soc_rtc_slow_clk_src_t, except that we define + * an extra enum member for the external 32k oscillator. + * For convenience, lower 2 bits should correspond to soc_rtc_slow_clk_src_t values. + */ +typedef enum { + SLOW_CLK_RTC = SOC_RTC_SLOW_CLK_SRC_RC_SLOW, //!< Internal 150 kHz RC oscillator + SLOW_CLK_32K_XTAL = SOC_RTC_SLOW_CLK_SRC_XTAL32K, //!< External 32 kHz XTAL + SLOW_CLK_8MD256 = SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256, //!< Internal 8 MHz RC oscillator, divided by 256 + SLOW_CLK_32K_EXT_OSC = SOC_RTC_SLOW_CLK_SRC_XTAL32K | EXT_OSC_FLAG //!< External 32k oscillator connected to 32K_XP pin +} slow_clk_sel_t; + +static void select_rtc_slow_clk(slow_clk_sel_t slow_clk); + +static const char *TAG = "clk"; + + + __attribute__((weak)) void esp_clk_init(void) +{ +#if !CONFIG_IDF_ENV_FPGA + rtc_config_t cfg = RTC_CONFIG_DEFAULT(); + soc_reset_reason_t rst_reas; + rst_reas = esp_rom_get_reset_reason(0); + if (rst_reas == RESET_REASON_CHIP_POWER_ON) { + cfg.cali_ocode = 1; + } + rtc_init(cfg); + + assert(rtc_clk_xtal_freq_get() == RTC_XTAL_FREQ_40M); + + bool rc_fast_d256_is_enabled = rtc_clk_8md256_enabled(); + rtc_clk_8m_enable(true, rc_fast_d256_is_enabled); + rtc_clk_fast_src_set(SOC_RTC_FAST_CLK_SRC_RC_FAST); +#endif + +#ifdef CONFIG_BOOTLOADER_WDT_ENABLE + // WDT uses a SLOW_CLK clock source. After a function select_rtc_slow_clk a frequency of this source can changed. + // If the frequency changes from 150kHz to 32kHz, then the timeout set for the WDT will increase 4.6 times. + // Therefore, for the time of frequency change, set a new lower timeout value (1.6 sec). + // This prevents excessive delay before resetting in case the supply voltage is drawdown. + // (If frequency is changed from 150kHz to 32kHz then WDT timeout will increased to 1.6sec * 150/32 = 7.5 sec). + wdt_hal_context_t rtc_wdt_ctx = {.inst = WDT_RWDT, .rwdt_dev = &LP_WDT}; // TODO: IDF-5653 + uint32_t stage_timeout_ticks = (uint32_t)(1600ULL * rtc_clk_slow_freq_get_hz() / 1000ULL); + wdt_hal_write_protect_disable(&rtc_wdt_ctx); + wdt_hal_feed(&rtc_wdt_ctx); + //Bootloader has enabled RTC WDT until now. We're only modifying timeout, so keep the stage and timeout action the same + wdt_hal_config_stage(&rtc_wdt_ctx, WDT_STAGE0, stage_timeout_ticks, WDT_STAGE_ACTION_RESET_RTC); + wdt_hal_write_protect_enable(&rtc_wdt_ctx); +#endif + +#if defined(CONFIG_RTC_CLK_SRC_EXT_CRYS) + select_rtc_slow_clk(SLOW_CLK_32K_XTAL); +#elif defined(CONFIG_RTC_CLK_SRC_EXT_OSC) + select_rtc_slow_clk(SLOW_CLK_32K_EXT_OSC); +#elif defined(CONFIG_RTC_CLK_SRC_INT_8MD256) + select_rtc_slow_clk(SLOW_CLK_8MD256); +#else + select_rtc_slow_clk(SLOW_CLK_RTC); +#endif + +#ifdef CONFIG_BOOTLOADER_WDT_ENABLE + // After changing a frequency WDT timeout needs to be set for new frequency. + stage_timeout_ticks = (uint32_t)((uint64_t)CONFIG_BOOTLOADER_WDT_TIME_MS * rtc_clk_slow_freq_get_hz() / 1000); + wdt_hal_write_protect_disable(&rtc_wdt_ctx); + wdt_hal_feed(&rtc_wdt_ctx); + wdt_hal_config_stage(&rtc_wdt_ctx, WDT_STAGE0, stage_timeout_ticks, WDT_STAGE_ACTION_RESET_RTC); + wdt_hal_write_protect_enable(&rtc_wdt_ctx); +#endif + + rtc_cpu_freq_config_t old_config, new_config; + rtc_clk_cpu_freq_get_config(&old_config); + const uint32_t old_freq_mhz = old_config.freq_mhz; + const uint32_t new_freq_mhz = CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ; + + bool res = rtc_clk_cpu_freq_mhz_to_config(new_freq_mhz, &new_config); + assert(res); + + // Wait for UART TX to finish, otherwise some UART output will be lost + // when switching APB frequency + esp_rom_uart_tx_wait_idle(CONFIG_ESP_CONSOLE_UART_NUM); + + if (res) { + rtc_clk_cpu_freq_set_config(&new_config); + } + + // Re calculate the ccount to make time calculation correct. + esp_cpu_set_cycle_count( (uint64_t)esp_cpu_get_cycle_count() * new_freq_mhz / old_freq_mhz ); +} + +static void select_rtc_slow_clk(slow_clk_sel_t slow_clk) +{ + ESP_EARLY_LOGW(TAG, "select_rtc_slow_clk() has not been implemented yet"); +#if 0 // TODO: IDF-5645 + soc_rtc_slow_clk_src_t rtc_slow_clk_src = slow_clk & RTC_CNTL_ANA_CLK_RTC_SEL_V; + uint32_t cal_val = 0; + /* number of times to repeat 32k XTAL calibration + * before giving up and switching to the internal RC + */ + int retry_32k_xtal = 3; + + do { + if (rtc_slow_clk_src == SOC_RTC_SLOW_CLK_SRC_XTAL32K) { + /* 32k XTAL oscillator needs to be enabled and running before it can + * be used. Hardware doesn't have a direct way of checking if the + * oscillator is running. Here we use rtc_clk_cal function to count + * the number of main XTAL cycles in the given number of 32k XTAL + * oscillator cycles. If the 32k XTAL has not started up, calibration + * will time out, returning 0. + */ + ESP_EARLY_LOGD(TAG, "waiting for 32k oscillator to start up"); + if (slow_clk == SLOW_CLK_32K_XTAL) { + rtc_clk_32k_enable(true); + } else if (slow_clk == SLOW_CLK_32K_EXT_OSC) { + rtc_clk_32k_enable_external(); + } + // When SLOW_CLK_CAL_CYCLES is set to 0, clock calibration will not be performed at startup. + if (SLOW_CLK_CAL_CYCLES > 0) { + cal_val = rtc_clk_cal(RTC_CAL_32K_XTAL, SLOW_CLK_CAL_CYCLES); + if (cal_val == 0 || cal_val < MIN_32K_XTAL_CAL_VAL) { + if (retry_32k_xtal-- > 0) { + continue; + } + ESP_EARLY_LOGW(TAG, "32 kHz XTAL not found, switching to internal 150 kHz oscillator"); + rtc_slow_clk_src = SOC_RTC_SLOW_CLK_SRC_RC_SLOW; + } + } + } else if (rtc_slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256) { + rtc_clk_8m_enable(true, true); + } + rtc_clk_slow_src_set(rtc_slow_clk_src); + + if (SLOW_CLK_CAL_CYCLES > 0) { + /* TODO: 32k XTAL oscillator has some frequency drift at startup. + * Improve calibration routine to wait until the frequency is stable. + */ + cal_val = rtc_clk_cal(RTC_CAL_RTC_MUX, SLOW_CLK_CAL_CYCLES); + } else { + const uint64_t cal_dividend = (1ULL << RTC_CLK_CAL_FRACT) * 1000000ULL; + cal_val = (uint32_t) (cal_dividend / rtc_clk_slow_freq_get_hz()); + } + } while (cal_val == 0); + ESP_EARLY_LOGD(TAG, "RTC_SLOW_CLK calibration value: %d", cal_val); + esp_clk_slowclk_cal_set(cal_val); +#endif +} + +void rtc_clk_select_rtc_slow_clk(void) +{ + select_rtc_slow_clk(SLOW_CLK_32K_XTAL); +} + +/* This function is not exposed as an API at this point. + * All peripheral clocks are default enabled after chip is powered on. + * This function disables some peripheral clocks when cpu starts. + * These peripheral clocks are enabled when the peripherals are initialized + * and disabled when they are de-initialized. + */ +__attribute__((weak)) void esp_perip_clk_init(void) +{ + ESP_EARLY_LOGW(TAG, "esp_perip_clk_init() has not been implemented yet"); +#if 0 // TODO: IDF-5658 + uint32_t common_perip_clk, hwcrypto_perip_clk, wifi_bt_sdio_clk = 0; + uint32_t common_perip_clk1 = 0; + + soc_reset_reason_t rst_reason = esp_rom_get_reset_reason(0); + + /* For reason that only reset CPU, do not disable the clocks + * that have been enabled before reset. + */ + if (rst_reason == RESET_REASON_CPU0_MWDT0 || rst_reason == RESET_REASON_CPU0_SW || + rst_reason == RESET_REASON_CPU0_RTC_WDT || rst_reason == RESET_REASON_CPU0_MWDT1) { + common_perip_clk = ~READ_PERI_REG(SYSTEM_PERIP_CLK_EN0_REG); + hwcrypto_perip_clk = ~READ_PERI_REG(SYSTEM_PERIP_CLK_EN1_REG); + wifi_bt_sdio_clk = ~READ_PERI_REG(SYSTEM_WIFI_CLK_EN_REG); + } else { + common_perip_clk = SYSTEM_WDG_CLK_EN | + SYSTEM_I2S0_CLK_EN | +#if CONFIG_ESP_CONSOLE_UART_NUM != 0 + SYSTEM_UART_CLK_EN | +#endif +#if CONFIG_ESP_CONSOLE_UART_NUM != 1 + SYSTEM_UART1_CLK_EN | +#endif + SYSTEM_SPI2_CLK_EN | + SYSTEM_I2C_EXT0_CLK_EN | + SYSTEM_UHCI0_CLK_EN | + SYSTEM_RMT_CLK_EN | + SYSTEM_LEDC_CLK_EN | + SYSTEM_TIMERGROUP1_CLK_EN | + SYSTEM_SPI3_CLK_EN | + SYSTEM_SPI4_CLK_EN | + SYSTEM_TWAI_CLK_EN | + SYSTEM_I2S1_CLK_EN | + SYSTEM_SPI2_DMA_CLK_EN | + SYSTEM_SPI3_DMA_CLK_EN; + + common_perip_clk1 = 0; + hwcrypto_perip_clk = SYSTEM_CRYPTO_AES_CLK_EN | + SYSTEM_CRYPTO_SHA_CLK_EN | + SYSTEM_CRYPTO_RSA_CLK_EN; + wifi_bt_sdio_clk = SYSTEM_WIFI_CLK_WIFI_EN | + SYSTEM_WIFI_CLK_BT_EN_M | + SYSTEM_WIFI_CLK_UNUSED_BIT5 | + SYSTEM_WIFI_CLK_UNUSED_BIT12; + } + + //Reset the communication peripherals like I2C, SPI, UART, I2S and bring them to known state. + common_perip_clk |= SYSTEM_I2S0_CLK_EN | +#if CONFIG_ESP_CONSOLE_UART_NUM != 0 + SYSTEM_UART_CLK_EN | +#endif +#if CONFIG_ESP_CONSOLE_UART_NUM != 1 + SYSTEM_UART1_CLK_EN | +#endif + SYSTEM_SPI2_CLK_EN | + SYSTEM_I2C_EXT0_CLK_EN | + SYSTEM_UHCI0_CLK_EN | + SYSTEM_RMT_CLK_EN | + SYSTEM_UHCI1_CLK_EN | + SYSTEM_SPI3_CLK_EN | + SYSTEM_SPI4_CLK_EN | + SYSTEM_I2C_EXT1_CLK_EN | + SYSTEM_I2S1_CLK_EN | + SYSTEM_SPI2_DMA_CLK_EN | + SYSTEM_SPI3_DMA_CLK_EN; + common_perip_clk1 = 0; + + /* Change I2S clock to audio PLL first. Because if I2S uses 160MHz clock, + * the current is not reduced when disable I2S clock. + */ + // TOCK(check replacement) + // REG_SET_FIELD(I2S_CLKM_CONF_REG(0), I2S_CLK_SEL, I2S_CLK_AUDIO_PLL); + // REG_SET_FIELD(I2S_CLKM_CONF_REG(1), I2S_CLK_SEL, I2S_CLK_AUDIO_PLL); + + /* Disable some peripheral clocks. */ + CLEAR_PERI_REG_MASK(SYSTEM_PERIP_CLK_EN0_REG, common_perip_clk); + SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN0_REG, common_perip_clk); + + CLEAR_PERI_REG_MASK(SYSTEM_PERIP_CLK_EN1_REG, common_perip_clk1); + SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN1_REG, common_perip_clk1); + + /* Disable hardware crypto clocks. */ + CLEAR_PERI_REG_MASK(SYSTEM_PERIP_CLK_EN1_REG, hwcrypto_perip_clk); + SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN1_REG, hwcrypto_perip_clk); + + /* Disable WiFi/BT/SDIO clocks. */ + CLEAR_PERI_REG_MASK(SYSTEM_WIFI_CLK_EN_REG, wifi_bt_sdio_clk); + SET_PERI_REG_MASK(SYSTEM_WIFI_CLK_EN_REG, SYSTEM_WIFI_CLK_EN); + + /* Set WiFi light sleep clock source to RTC slow clock */ + REG_SET_FIELD(SYSTEM_BT_LPCK_DIV_INT_REG, SYSTEM_BT_LPCK_DIV_NUM, 0); + CLEAR_PERI_REG_MASK(SYSTEM_BT_LPCK_DIV_FRAC_REG, SYSTEM_LPCLK_SEL_8M); + SET_PERI_REG_MASK(SYSTEM_BT_LPCK_DIV_FRAC_REG, SYSTEM_LPCLK_SEL_RTC_SLOW); + + /* Enable RNG clock. */ + periph_module_enable(PERIPH_RNG_MODULE); +#endif +} diff --git a/components/esp_system/port/soc/esp32c6/reset_reason.c b/components/esp_system/port/soc/esp32c6/reset_reason.c new file mode 100644 index 0000000000..bd82c8a3d3 --- /dev/null +++ b/components/esp_system/port/soc/esp32c6/reset_reason.c @@ -0,0 +1,110 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "esp_system.h" +#include "esp_rom_sys.h" +#include "esp_private/system_internal.h" +#include "soc/rtc_periph.h" +#include "esp32c6/rom/rtc.h" + +static void esp_reset_reason_clear_hint(void); + +static esp_reset_reason_t s_reset_reason; + +static esp_reset_reason_t get_reset_reason(soc_reset_reason_t rtc_reset_reason, esp_reset_reason_t reset_reason_hint) +{ + switch (rtc_reset_reason) { + case RESET_REASON_CHIP_POWER_ON: + return ESP_RST_POWERON; + + case RESET_REASON_CPU0_SW: + case RESET_REASON_CORE_SW: + if (reset_reason_hint == ESP_RST_PANIC || + reset_reason_hint == ESP_RST_BROWNOUT || + reset_reason_hint == ESP_RST_TASK_WDT || + reset_reason_hint == ESP_RST_INT_WDT) { + return reset_reason_hint; + } + return ESP_RST_SW; + + case RESET_REASON_CORE_DEEP_SLEEP: + return ESP_RST_DEEPSLEEP; + + case RESET_REASON_CORE_MWDT0: + return ESP_RST_TASK_WDT; + + case RESET_REASON_CORE_MWDT1: + return ESP_RST_INT_WDT; + + case RESET_REASON_CORE_RTC_WDT: + case RESET_REASON_SYS_RTC_WDT: + case RESET_REASON_SYS_SUPER_WDT: + case RESET_REASON_CPU0_RTC_WDT: + case RESET_REASON_CPU0_MWDT0: + case RESET_REASON_CPU0_MWDT1: + return ESP_RST_WDT; + + case RESET_REASON_SYS_BROWN_OUT: + return ESP_RST_BROWNOUT; + + default: + return ESP_RST_UNKNOWN; + } +} + +static void __attribute__((constructor)) esp_reset_reason_init(void) +{ + esp_reset_reason_t hint = esp_reset_reason_get_hint(); + s_reset_reason = get_reset_reason(esp_rom_get_reset_reason(PRO_CPU_NUM), hint); + if (hint != ESP_RST_UNKNOWN) { + esp_reset_reason_clear_hint(); + } +} + +esp_reset_reason_t esp_reset_reason(void) +{ + return s_reset_reason; +} + +/* Reset reason hint is stored in RTC_RESET_CAUSE_REG, a.k.a. RTC_CNTL_STORE6_REG, + * a.k.a. RTC_ENTRY_ADDR_REG. It is safe to use this register both for the + * deep sleep wake stub entry address and for reset reason hint, since wake stub + * is only used for deep sleep reset, and in this case the reason provided by + * esp_rom_get_reset_reason is unambiguous. + * + * Same layout is used as for RTC_APB_FREQ_REG (a.k.a. RTC_CNTL_STORE5_REG): + * the value is replicated in low and high half-words. In addition to that, + * MSB is set to 1, which doesn't happen when RTC_CNTL_STORE6_REG contains + * deep sleep wake stub address. + */ + +#define RST_REASON_BIT 0x80000000 +#define RST_REASON_MASK 0x7FFF +#define RST_REASON_SHIFT 16 + +/* in IRAM, can be called from panic handler */ +void IRAM_ATTR esp_reset_reason_set_hint(esp_reset_reason_t hint) +{ + assert((hint & (~RST_REASON_MASK)) == 0); + uint32_t val = hint | (hint << RST_REASON_SHIFT) | RST_REASON_BIT; + REG_WRITE(RTC_RESET_CAUSE_REG, val); +} + +/* in IRAM, can be called from panic handler */ +esp_reset_reason_t IRAM_ATTR esp_reset_reason_get_hint(void) +{ + uint32_t reset_reason_hint = REG_READ(RTC_RESET_CAUSE_REG); + uint32_t high = (reset_reason_hint >> RST_REASON_SHIFT) & RST_REASON_MASK; + uint32_t low = reset_reason_hint & RST_REASON_MASK; + if ((reset_reason_hint & RST_REASON_BIT) == 0 || high != low) { + return ESP_RST_UNKNOWN; + } + return (esp_reset_reason_t) low; +} +static inline void esp_reset_reason_clear_hint(void) +{ + REG_WRITE(RTC_RESET_CAUSE_REG, 0); +} diff --git a/components/esp_system/port/soc/esp32c6/system_internal.c b/components/esp_system/port/soc/esp32c6/system_internal.c new file mode 100644 index 0000000000..274460853e --- /dev/null +++ b/components/esp_system/port/soc/esp32c6/system_internal.c @@ -0,0 +1,120 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "sdkconfig.h" +#include "esp_system.h" +#include "esp_private/system_internal.h" +#include "esp_attr.h" +#include "esp_log.h" +#include "esp_rom_sys.h" +#include "riscv/riscv_interrupts.h" +#include "riscv/interrupt.h" +#include "esp_rom_uart.h" +#include "soc/gpio_reg.h" +#include "esp_cpu.h" +#include "soc/rtc.h" +#include "soc/rtc_periph.h" +#include "soc/uart_reg.h" +#include "hal/wdt_hal.h" +#include "esp_private/cache_err_int.h" + +#include "esp32c6/rom/cache.h" +#include "esp32c6/rom/rtc.h" +#include "soc/pcr_reg.h" + +/* "inner" restart function for after RTOS, interrupts & anything else on this + * core are already stopped. Stalls other core, resets hardware, + * triggers restart. +*/ +void IRAM_ATTR esp_restart_noos(void) +{ + // Disable interrupts + riscv_global_interrupts_disable(); + // Enable RTC watchdog for 1 second + wdt_hal_context_t rtc_wdt_ctx; + wdt_hal_init(&rtc_wdt_ctx, WDT_RWDT, 0, false); + uint32_t stage_timeout_ticks = (uint32_t)(1000ULL * rtc_clk_slow_freq_get_hz() / 1000ULL); + wdt_hal_write_protect_disable(&rtc_wdt_ctx); + wdt_hal_config_stage(&rtc_wdt_ctx, WDT_STAGE0, stage_timeout_ticks, WDT_STAGE_ACTION_RESET_SYSTEM); + wdt_hal_config_stage(&rtc_wdt_ctx, WDT_STAGE1, stage_timeout_ticks, WDT_STAGE_ACTION_RESET_RTC); + //Enable flash boot mode so that flash booting after restart is protected by the RTC WDT. + wdt_hal_set_flashboot_en(&rtc_wdt_ctx, true); + wdt_hal_write_protect_enable(&rtc_wdt_ctx); + + // C6 is a single core SoC, no need to reset and stall the other CPU + + // Disable TG0/TG1 watchdogs + wdt_hal_context_t wdt0_context = {.inst = WDT_MWDT0, .mwdt_dev = &TIMERG0}; + wdt_hal_write_protect_disable(&wdt0_context); + wdt_hal_disable(&wdt0_context); + wdt_hal_write_protect_enable(&wdt0_context); + + wdt_hal_context_t wdt1_context = {.inst = WDT_MWDT1, .mwdt_dev = &TIMERG1}; + wdt_hal_write_protect_disable(&wdt1_context); + wdt_hal_disable(&wdt1_context); + wdt_hal_write_protect_enable(&wdt1_context); + + // Flush any data left in UART FIFOs + esp_rom_uart_tx_wait_idle(0); + esp_rom_uart_tx_wait_idle(1); + // Disable cache + Cache_Disable_ICache(); + + // 2nd stage bootloader reconfigures SPI flash signals. + // Reset them to the defaults expected by ROM. + WRITE_PERI_REG(GPIO_FUNC0_IN_SEL_CFG_REG, 0x30); + // TODO: IDF-5659 + // WRITE_PERI_REG(GPIO_FUNC1_IN_SEL_CFG_REG, 0x30); + // WRITE_PERI_REG(GPIO_FUNC2_IN_SEL_CFG_REG, 0x30); + // WRITE_PERI_REG(GPIO_FUNC3_IN_SEL_CFG_REG, 0x30); + // WRITE_PERI_REG(GPIO_FUNC4_IN_SEL_CFG_REG, 0x30); + // WRITE_PERI_REG(GPIO_FUNC5_IN_SEL_CFG_REG, 0x30); + + // Reset wifi/bluetooth/ethernet/sdio (bb/mac) + // Moved to module internal + // SET_PERI_REG_MASK(SYSTEM_CORE_RST_EN_REG, + // SYSTEM_WIFIBB_RST | SYSTEM_FE_RST | // TODO: IDF-5680 (esp_phy) + // SYSTEM_WIFIMAC_RST | // TODO: IDF-5679 (esp_wifi) + // SYSTEM_SDIO_RST | // SDIO_HINF_HINF_SDIO_RST? + // SYSTEM_EMAC_RST | SYSTEM_MACPWR_RST | // TODO: IDF-5325 (ethernet) + // SYSTEM_BTBB_RST | SYSTEM_BTBB_REG_RST | // TODO: IDF-5727 (bt) + // SYSTEM_RW_BTMAC_RST | SYSTEM_RW_BTLP_RST | SYSTEM_RW_BTMAC_REG_RST | SYSTEM_RW_BTLP_REG_RST); + // REG_WRITE(SYSTEM_CORE_RST_EN_REG, 0); + + // Set Peripheral clk rst + SET_PERI_REG_MASK(PCR_TIMERGROUP0_CONF_REG, PCR_TG0_RST_EN); + SET_PERI_REG_MASK(PCR_TIMERGROUP1_CONF_REG, PCR_TG1_RST_EN); + SET_PERI_REG_MASK(PCR_MSPI_CONF_REG, PCR_MSPI_RST_EN); + SET_PERI_REG_MASK(PCR_UART0_CONF_REG, PCR_UART0_RST_EN); + SET_PERI_REG_MASK(PCR_UART1_CONF_REG, PCR_UART1_RST_EN); + SET_PERI_REG_MASK(PCR_SYSTIMER_CONF_REG, PCR_SYSTIMER_RST_EN); + SET_PERI_REG_MASK(PCR_GDMA_CONF_REG, PCR_GDMA_RST_EN); + SET_PERI_REG_MASK(PCR_SDIO_SLAVE_CONF_REG, PCR_SDIO_SLAVE_RST_EN); + SET_PERI_REG_MASK(PCR_MODEM_APB_CONF_REG, PCR_MODEM_RST_EN); + + // Clear Peripheral clk rst + CLEAR_PERI_REG_MASK(PCR_TIMERGROUP0_CONF_REG, PCR_TG0_RST_EN); + CLEAR_PERI_REG_MASK(PCR_TIMERGROUP1_CONF_REG, PCR_TG1_RST_EN); + CLEAR_PERI_REG_MASK(PCR_MSPI_CONF_REG, PCR_MSPI_RST_EN); + CLEAR_PERI_REG_MASK(PCR_UART0_CONF_REG, PCR_UART0_RST_EN); + CLEAR_PERI_REG_MASK(PCR_UART1_CONF_REG, PCR_UART1_RST_EN); + CLEAR_PERI_REG_MASK(PCR_SYSTIMER_CONF_REG, PCR_SYSTIMER_RST_EN); + CLEAR_PERI_REG_MASK(PCR_GDMA_CONF_REG, PCR_GDMA_RST_EN); + CLEAR_PERI_REG_MASK(PCR_SDIO_SLAVE_CONF_REG, PCR_SDIO_SLAVE_RST_EN); + CLEAR_PERI_REG_MASK(PCR_MODEM_APB_CONF_REG, PCR_MODEM_RST_EN); + + // Set CPU back to XTAL source, no PLL, same as hard reset +#if !CONFIG_IDF_ENV_FPGA + rtc_clk_cpu_freq_set_xtal(); +#endif + + // Reset PRO CPU + esp_rom_software_reset_cpu(0); + while (true) { + ; + } +} diff --git a/components/esp_system/startup.c b/components/esp_system/startup.c index 0feda4e9f5..8d1efa93fe 100644 --- a/components/esp_system/startup.c +++ b/components/esp_system/startup.c @@ -459,7 +459,11 @@ static void start_cpu0_default(void) // Now that the application is about to start, disable boot watchdog #ifndef CONFIG_BOOTLOADER_WDT_DISABLE_IN_USER_CODE +#if CONFIG_IDF_TARGET_ESP32C6 // TODO: IDF-5653 + wdt_hal_context_t rtc_wdt_ctx = {.inst = WDT_RWDT, .rwdt_dev = &LP_WDT}; +#else wdt_hal_context_t rtc_wdt_ctx = {.inst = WDT_RWDT, .rwdt_dev = &RTCCNTL}; +#endif wdt_hal_write_protect_disable(&rtc_wdt_ctx); wdt_hal_disable(&rtc_wdt_ctx); wdt_hal_write_protect_enable(&rtc_wdt_ctx); diff --git a/components/esp_system/system_time.c b/components/esp_system/system_time.c index 075f54dfa8..f6b9839089 100644 --- a/components/esp_system/system_time.c +++ b/components/esp_system/system_time.c @@ -25,6 +25,8 @@ #include "esp32h2/rtc.h" #elif CONFIG_IDF_TARGET_ESP32C2 #include "esp32c2/rtc.h" +#elif CONFIG_IDF_TARGET_ESP32C6 +#include "esp32c6/rtc.h" #endif #include "esp_private/startup_internal.h" diff --git a/components/esp_timer/src/esp_timer.c b/components/esp_timer/src/esp_timer.c index 3ca19f642f..1c7ca76263 100644 --- a/components/esp_timer/src/esp_timer.c +++ b/components/esp_timer/src/esp_timer.c @@ -34,6 +34,8 @@ #include "esp32h2/rtc.h" #elif CONFIG_IDF_TARGET_ESP32C2 #include "esp32c2/rtc.h" +#elif CONFIG_IDF_TARGET_ESP32C6 +#include "esp32c6/rtc.h" #endif #include "sdkconfig.h" diff --git a/components/esp_timer/src/ets_timer_legacy.c b/components/esp_timer/src/ets_timer_legacy.c index 841f8d04f1..d03aa7cbcd 100644 --- a/components/esp_timer/src/ets_timer_legacy.c +++ b/components/esp_timer/src/ets_timer_legacy.c @@ -34,6 +34,8 @@ #include "esp32c2/rom/ets_sys.h" #elif CONFIG_IDF_TARGET_ESP32H2 #include "esp32h2/rom/ets_sys.h" +#elif CONFIG_IDF_TARGET_ESP32C6 +#include "esp32c6/rom/ets_sys.h" #endif /* We abuse 'timer_arg' field of ETSTimer structure to hold a pointer to esp_timer */ diff --git a/components/esp_timer/src/system_time.c b/components/esp_timer/src/system_time.c index 6387422c86..ddc5949a0e 100644 --- a/components/esp_timer/src/system_time.c +++ b/components/esp_timer/src/system_time.c @@ -29,6 +29,8 @@ #include "esp32h2/rtc.h" #elif CONFIG_IDF_TARGET_ESP32C2 #include "esp32c2/rtc.h" +#elif CONFIG_IDF_TARGET_ESP32C6 +#include "esp32c6/rtc.h" #endif __attribute__((unused)) static const char* TAG = "system_time"; diff --git a/components/esp_timer/test/test_ets_timer.c b/components/esp_timer/test/test_ets_timer.c index b72e4fdf9e..15ba842ece 100644 --- a/components/esp_timer/test/test_ets_timer.c +++ b/components/esp_timer/test/test_ets_timer.c @@ -26,6 +26,8 @@ #include "esp32h2/rom/ets_sys.h" #elif CONFIG_IDF_TARGET_ESP32C2 #include "esp32c2/rom/ets_sys.h" +#elif CONFIG_IDF_TARGET_ESP32C6 +#include "esp32c6/rom/ets_sys.h" #endif static void test_correct_delay_timer_func(void* arg) diff --git a/components/freertos/FreeRTOS-Kernel-SMP/portable/riscv/include/freertos/portmacro.h b/components/freertos/FreeRTOS-Kernel-SMP/portable/riscv/include/freertos/portmacro.h index f5a4057296..bce9f42258 100644 --- a/components/freertos/FreeRTOS-Kernel-SMP/portable/riscv/include/freertos/portmacro.h +++ b/components/freertos/FreeRTOS-Kernel-SMP/portable/riscv/include/freertos/portmacro.h @@ -9,7 +9,7 @@ #include "sdkconfig.h" #include #include "spinlock.h" -#include "soc/interrupt_core0_reg.h" +#include "soc/interrupt_reg.h" #include "esp_macros.h" #include "esp_cpu.h" #include "esp_private/crosscore_int.h" diff --git a/components/freertos/FreeRTOS-Kernel/portable/port_systick.c b/components/freertos/FreeRTOS-Kernel/portable/port_systick.c index 9031ef81bd..2c12f72f89 100644 --- a/components/freertos/FreeRTOS-Kernel/portable/port_systick.c +++ b/components/freertos/FreeRTOS-Kernel/portable/port_systick.c @@ -16,7 +16,6 @@ #include "sdkconfig.h" #ifdef CONFIG_FREERTOS_SYSTICK_USES_SYSTIMER #include "soc/periph_defs.h" -#include "soc/system_reg.h" #include "hal/systimer_hal.h" #include "hal/systimer_ll.h" #endif diff --git a/components/freertos/FreeRTOS-Kernel/portable/riscv/include/freertos/portmacro.h b/components/freertos/FreeRTOS-Kernel/portable/riscv/include/freertos/portmacro.h index d719560520..0a31a1a6b1 100644 --- a/components/freertos/FreeRTOS-Kernel/portable/riscv/include/freertos/portmacro.h +++ b/components/freertos/FreeRTOS-Kernel/portable/riscv/include/freertos/portmacro.h @@ -43,7 +43,7 @@ #include #include #include "spinlock.h" -#include "soc/interrupt_core0_reg.h" +#include "soc/interrupt_reg.h" #include "esp_macros.h" #include "esp_attr.h" #include "esp_cpu.h" diff --git a/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in index ad0ee7c066..3d05f821e8 100644 --- a/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in @@ -31,10 +31,6 @@ config SOC_EFUSE_KEY_PURPOSE_FIELD bool default y -config SOC_EFUSE_HAS_EFUSE_RST_BUG - bool - default y - config SOC_RTC_FAST_MEM_SUPPORTED bool default y diff --git a/components/soc/esp32c6/include/soc/soc_caps.h b/components/soc/esp32c6/include/soc/soc_caps.h index 129e7f7234..ed64d6dab6 100644 --- a/components/soc/esp32c6/include/soc/soc_caps.h +++ b/components/soc/esp32c6/include/soc/soc_caps.h @@ -37,7 +37,6 @@ #define SOC_SUPPORTS_SECURE_DL_MODE 1 //#define SOC_RISCV_COPROC_SUPPORTED 1 // TODO: IDF-5816 #define SOC_EFUSE_KEY_PURPOSE_FIELD 1 -#define SOC_EFUSE_HAS_EFUSE_RST_BUG 1 #define SOC_RTC_FAST_MEM_SUPPORTED 1 #define SOC_RTC_MEM_SUPPORTED 1 // #define SOC_I2S_SUPPORTED 1 // TODO: IDF-5314 diff --git a/components/ulp/ulp_common/ulp_common.c b/components/ulp/ulp_common/ulp_common.c index caa48115e8..32307ba729 100644 --- a/components/ulp/ulp_common/ulp_common.c +++ b/components/ulp/ulp_common/ulp_common.c @@ -9,10 +9,10 @@ #include "ulp_common.h" #include "esp_private/esp_clk.h" #include "soc/rtc.h" -#include "soc/rtc_cntl_reg.h" -#include "soc/sens_reg.h" +#include "soc/rtc_cntl_periph.h" #if CONFIG_IDF_TARGET_ESP32 +#include "soc/sens_reg.h" #define ULP_FSM_PREPARE_SLEEP_CYCLES 2 /*!< Cycles spent by FSM preparing ULP for sleep */ #define ULP_FSM_WAKEUP_SLEEP_CYCLES 2 /*!< Cycles spent by FSM waking up ULP from sleep */ #endif