diff --git a/components/bootloader_support/src/bootloader_common_loader.c b/components/bootloader_support/src/bootloader_common_loader.c index ea26dedd75..dc33aa7bd1 100644 --- a/components/bootloader_support/src/bootloader_common_loader.c +++ b/components/bootloader_support/src/bootloader_common_loader.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -24,6 +24,7 @@ #include "bootloader_sha.h" #include "sys/param.h" #include "bootloader_flash_priv.h" +#include "esp_rom_caps.h" #define ESP_PARTITION_HASH_LEN 32 /* SHA-256 digest length */ #define IS_MAX_REV_SET(max_chip_rev_full) (((max_chip_rev_full) != 65535) && ((max_chip_rev_full) != 0)) @@ -212,7 +213,12 @@ void bootloader_common_update_rtc_retain_mem(esp_partition_pos_t* partition, boo rtc_retain_mem_t* bootloader_common_get_rtc_retain_mem(void) { #ifdef BOOTLOADER_BUILD + +#if ESP_ROM_HAS_LP_ROM + #define RTC_RETAIN_MEM_ADDR (SOC_RTC_DRAM_LOW) +#else #define RTC_RETAIN_MEM_ADDR (SOC_RTC_DRAM_HIGH - sizeof(rtc_retain_mem_t)) +#endif //ESP_ROM_HAS_LP_ROM static rtc_retain_mem_t *const s_bootloader_retain_mem = (rtc_retain_mem_t *)RTC_RETAIN_MEM_ADDR; return s_bootloader_retain_mem; #else @@ -221,4 +227,5 @@ rtc_retain_mem_t* bootloader_common_get_rtc_retain_mem(void) #endif // !BOOTLOADER_BUILD } + #endif // CONFIG_BOOTLOADER_RESERVE_RTC_MEM diff --git a/components/esp_hw_support/port/esp32p4/cpu_region_protect.c b/components/esp_hw_support/port/esp32p4/cpu_region_protect.c index 98f62ccaf0..cfed9a0f0c 100644 --- a/components/esp_hw_support/port/esp32p4/cpu_region_protect.c +++ b/components/esp_hw_support/port/esp32p4/cpu_region_protect.c @@ -209,6 +209,7 @@ void esp_cpu_configure_region_protection(void) // 6. LP memory #if CONFIG_ESP_SYSTEM_PMP_IDRAM_SPLIT && !BOOTLOADER_BUILD + extern int _rtc_text_start; extern int _rtc_text_end; /* Reset the corresponding PMP config because PMP_ENTRY_SET only sets the given bits * Bootloader might have given extra permissions and those won't be cleared @@ -218,13 +219,9 @@ void esp_cpu_configure_region_protection(void) PMP_ENTRY_CFG_RESET(11); PMP_ENTRY_CFG_RESET(12); PMP_ENTRY_SET(9, SOC_RTC_IRAM_LOW, NONE); -#if CONFIG_ULP_COPROC_RESERVE_MEM - // First part of LP mem is reserved for coprocessor - PMP_ENTRY_SET(10, SOC_RTC_IRAM_LOW + CONFIG_ULP_COPROC_RESERVE_MEM, PMP_TOR | RW); -#else // CONFIG_ULP_COPROC_RESERVE_MEM - // Repeat same previous entry, to ensure next entry has correct base address (TOR) - PMP_ENTRY_SET(10, SOC_RTC_IRAM_LOW, NONE); -#endif // !CONFIG_ULP_COPROC_RESERVE_MEM + // First part of LP mem is reserved for RTC reserved mem (shared between bootloader and app) + // as well as memory for ULP coprocessor + PMP_ENTRY_SET(10, (int)&_rtc_text_start, PMP_TOR | RW); PMP_ENTRY_SET(11, (int)&_rtc_text_end, PMP_TOR | RX); PMP_ENTRY_SET(12, SOC_RTC_IRAM_HIGH, PMP_TOR | RW); #else diff --git a/components/esp_system/ld/esp32p4/memory.ld.in b/components/esp_system/ld/esp32p4/memory.ld.in index 668d908a97..775ae8ab94 100644 --- a/components/esp_system/ld/esp32p4/memory.ld.in +++ b/components/esp_system/ld/esp32p4/memory.ld.in @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -31,6 +31,11 @@ #define IDROM_SEG_SIZE (CONFIG_MMU_PAGE_SIZE << 10) #endif +#define LP_ROM_DRAM_START 0x5010fa80 // Value taken from ROM elf, includes LP ROM stack +#define LP_RAM_END 0x50110000 +#define LP_ROM_DRAM_SIZE (LP_RAM_END - LP_ROM_DRAM_START) + + MEMORY { /** @@ -73,10 +78,10 @@ MEMORY * lp ram memory (RWX). Persists over deep sleep. // TODO: IDF-5667 */ #if CONFIG_ULP_COPROC_ENABLED - lp_ram_seg(RW) : org = 0x50108000 + CONFIG_ULP_COPROC_RESERVE_MEM, - len = 0x8000 - CONFIG_ULP_COPROC_RESERVE_MEM - RESERVE_RTC_MEM + lp_ram_seg(RW) : org = 0x50108000 + RESERVE_RTC_MEM + CONFIG_ULP_COPROC_RESERVE_MEM, + len = 0x8000 - CONFIG_ULP_COPROC_RESERVE_MEM - RESERVE_RTC_MEM - LP_ROM_DRAM_SIZE #else - lp_ram_seg(RW) : org = 0x50108000 , len = 0x8000 - RESERVE_RTC_MEM + lp_ram_seg(RW) : org = 0x50108000 + RESERVE_RTC_MEM, len = 0x8000 - RESERVE_RTC_MEM #endif // CONFIG_ULP_COPROC_ENABLED /* We reduced the size of lp_ram_seg by RESERVE_RTC_MEM value. @@ -85,8 +90,9 @@ MEMORY - (lower addr) rtc timer data (s_rtc_timer_retain_mem, see esp_clk.c files). - (higher addr) bootloader rtc data (s_bootloader_retain_mem, when a Kconfig option is on). The aim of this is to keep data that will not be moved around and have a fixed address. + This segment is placed at the beginning of LP RAM, as the end of LP RAM is occupied by LP ROM stack/data */ - lp_reserved_seg(RW) : org = 0x50108000 + 0x8000 - RESERVE_RTC_MEM, len = RESERVE_RTC_MEM + lp_reserved_seg(RW) : org = 0x50108000, len = RESERVE_RTC_MEM } /* Heap ends at top of dram0_0_seg */ diff --git a/components/esp_system/ld/esp32p4/sections.ld.in b/components/esp_system/ld/esp32p4/sections.ld.in index 9c5b373825..2f0ff2d0f0 100644 --- a/components/esp_system/ld/esp32p4/sections.ld.in +++ b/components/esp_system/ld/esp32p4/sections.ld.in @@ -18,7 +18,12 @@ SECTIONS */ .rtc.text : { - ALIGNED_SYMBOL(4, _rtc_fast_start) + /* Align the start of RTC code region as per PMP granularity + * this ensures we do not overwrite the permissions for the previous + * region (ULP mem/RTC reserved) regardless of their end alignment + */ + ALIGNED_SYMBOL(_esp_pmp_align_size, _rtc_fast_start) + ALIGNED_SYMBOL(_esp_pmp_align_size, _rtc_text_start) arrays[rtc_text] mapping[rtc_text] @@ -119,20 +124,21 @@ SECTIONS { ALIGNED_SYMBOL(4, _rtc_reserved_start) + KEEP(*(.bootloader_data_rtc_mem .bootloader_data_rtc_mem.*)) + *(.rtc_timer_data_in_rtc_mem .rtc_timer_data_in_rtc_mem.*) + /** * New data can only be added here to ensure existing data are not moved. - * Because data have adhered to the end of the segment and code is relied + * Because data have adhered to the beginning of the segment and code is relied * on it. * >> put new data here << */ - *(.rtc_timer_data_in_rtc_mem .rtc_timer_data_in_rtc_mem.*) - KEEP(*(.bootloader_data_rtc_mem .bootloader_data_rtc_mem.*)) - _rtc_reserved_end = ABSOLUTE(.); } > rtc_reserved_seg _rtc_reserved_length = _rtc_reserved_end - _rtc_reserved_start; + _rtc_ulp_memory_start = _rtc_reserved_start + LENGTH(rtc_reserved_seg); ASSERT((_rtc_reserved_length <= LENGTH(rtc_reserved_seg)), "RTC reserved segment data does not fit.") diff --git a/components/esp_system/ld/ld.common b/components/esp_system/ld/ld.common index b62c14f7a3..ca35c79094 100644 --- a/components/esp_system/ld/ld.common +++ b/components/esp_system/ld/ld.common @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -41,6 +41,8 @@ #define _esp_mmu_page_size CONFIG_MMU_PAGE_SIZE #endif +#define ALIGN_UP(SIZE, AL) (((SIZE) + (AL - 1)) & ~(AL - 1)) + #if CONFIG_SOC_RTC_MEM_SUPPORTED #if CONFIG_BOOTLOADER_RESERVE_RTC_MEM #ifdef CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC @@ -57,9 +59,15 @@ #if CONFIG_IDF_TARGET_ESP32 #define RESERVE_RTC_MEM (RTC_TIMER_RESERVE_RTC) + #elif CONFIG_ESP_ROM_HAS_LP_ROM && CONFIG_ULP_COPROC_ENABLED + /* RTC Reserved is placed before ULP memory, expand it to make sure the ULP start address + has the required alignment */ + #define ULP_ALIGNMENT_REQ_BYTES 256 + #define RESERVE_RTC_MEM ALIGN_UP(ESP_BOOTLOADER_RESERVE_RTC + RTC_TIMER_RESERVE_RTC, ULP_ALIGNMENT_REQ_BYTES) #else #define RESERVE_RTC_MEM (ESP_BOOTLOADER_RESERVE_RTC + RTC_TIMER_RESERVE_RTC) #endif + #endif // SOC_RTC_MEM_SUPPORTED #define QUOTED_STRING(STRING) #STRING diff --git a/components/heap/port/esp32p4/memory_layout.c b/components/heap/port/esp32p4/memory_layout.c index 9b5135f814..79357938c0 100644 --- a/components/heap/port/esp32p4/memory_layout.c +++ b/components/heap/port/esp32p4/memory_layout.c @@ -47,11 +47,11 @@ enum { /** * Defined the attributes and allocation priority of each memory on the chip, * The heap allocator will traverse all types of memory types in column High Priority Matching and match the specified caps at first, - * if no memory caps matched or the allocation is failed, it will go to columns Medium Priorty Matching and Low Priority Matching + * if no memory caps matched or the allocation is failed, it will go to columns Medium Priority Matching and Low Priority Matching * in turn to continue matching. */ const soc_memory_type_desc_t soc_memory_types[SOC_MEMORY_TYPE_NUM] = { - /* Mem Type Name | High Priority Matching | Medium Priorty Matching | Low Priority Matching */ + /* Mem Type Name | High Priority Matching | Medium Priority Matching | Low Priority Matching */ [SOC_MEMORY_TYPE_L2MEM] = { "RAM", { MALLOC_L2MEM_BASE_CAPS, 0, 0 }}, [SOC_MEMORY_TYPE_SPIRAM] = { "SPIRAM", { MALLOC_CAP_SPIRAM, ESP32P4_MEM_COMMON_CAPS, 0 }}, [SOC_MEMORY_TYPE_TCM] = { "TCM", { MALLOC_CAP_TCM, ESP32P4_MEM_COMMON_CAPS | MALLOC_CAP_INTERNAL, 0 }}, @@ -74,6 +74,12 @@ const size_t soc_memory_type_count = sizeof(soc_memory_types) / sizeof(soc_memor #define APP_USABLE_DIRAM_END (SOC_ROM_STACK_START - SOC_ROM_STACK_SIZE) // 0x4ff3cfc0 - 0x2000 = 0x4ff3afc0 #define STARTUP_DATA_SIZE (SOC_DRAM_HIGH - CONFIG_CACHE_L2_CACHE_SIZE - APP_USABLE_DIRAM_END) // 0x4ffc0000 - 0x20000/0x40000/0x80000 - 0x4ff3afc0 = 0x65040 / 0x45040 / 0x5040 +#if CONFIG_ULP_COPROC_ENABLED +#define APP_USABLE_LP_RAM_SIZE 0x8000 - LP_ROM_DRAM_SIZE +#else +#define APP_USABLE_LP_RAM_SIZE 0x8000 +#endif //CONFIG_ULP_COPROC_ENABLED + const soc_memory_region_t soc_memory_regions[] = { #ifdef CONFIG_SPIRAM { SOC_EXTRAM_LOW, SOC_EXTRAM_SIZE, SOC_MEMORY_TYPE_SPIRAM, 0, false}, //PSRAM, if available @@ -81,7 +87,7 @@ const soc_memory_region_t soc_memory_regions[] = { { SOC_DRAM_LOW, APP_USABLE_DIRAM_END - SOC_DRAM_LOW, SOC_MEMORY_TYPE_L2MEM, SOC_IRAM_LOW, false}, { APP_USABLE_DIRAM_END, STARTUP_DATA_SIZE, SOC_MEMORY_TYPE_L2MEM, APP_USABLE_DIRAM_END, true}, #ifdef CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP - { 0x50108000, 0x8000, SOC_MEMORY_TYPE_RTCRAM, 0, false}, //LPRAM + { 0x50108000, APP_USABLE_LP_RAM_SIZE, SOC_MEMORY_TYPE_RTCRAM, 0, false}, //LPRAM #endif { 0x30100000, 0x2000, SOC_MEMORY_TYPE_TCM, 0, false}, }; @@ -92,6 +98,7 @@ const size_t soc_memory_region_count = sizeof(soc_memory_regions) / sizeof(soc_m extern int _data_start_low, _data_start_high, _heap_start_low, _heap_start_high, _iram_start, _iram_end, _rtc_force_slow_end; extern int _tcm_text_start, _tcm_data_end; extern int _rtc_reserved_start, _rtc_reserved_end; +extern int _rtc_ulp_memory_start; /** * Reserved memory regions. @@ -112,8 +119,10 @@ SOC_RESERVE_MEMORY_REGION((intptr_t)&_tcm_text_start, (intptr_t)&_tcm_data_end, SOC_RESERVE_MEMORY_REGION( SOC_EXTRAM_LOW, SOC_EXTRAM_HIGH, extram_region); #endif -#ifdef CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP -SOC_RESERVE_MEMORY_REGION(SOC_RTC_DRAM_LOW, (intptr_t)&_rtc_force_slow_end, rtcram_data); -#endif +#ifdef CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP SOC_RESERVE_MEMORY_REGION((intptr_t)&_rtc_reserved_start, (intptr_t)&_rtc_reserved_end, rtc_reserved_data); +/* This includes any memory reserved for ULP RAM */ +SOC_RESERVE_MEMORY_REGION((intptr_t)&_rtc_reserved_end, (intptr_t)&_rtc_force_slow_end, rtcram_data); + +#endif diff --git a/components/soc/esp32p4/include/soc/soc.h b/components/soc/esp32p4/include/soc/soc.h index a54594832e..5c564db301 100644 --- a/components/soc/esp32p4/include/soc/soc.h +++ b/components/soc/esp32p4/include/soc/soc.h @@ -227,6 +227,10 @@ #define SOC_ROM_STACK_START 0x4ff3cfc0 #define SOC_ROM_STACK_SIZE 0x2000 +#define LP_ROM_DRAM_START 0x5010fa80 // Value taken from ROM elf, includes LP ROM stack +#define LP_RAM_END 0x50110000 +#define LP_ROM_DRAM_SIZE (LP_RAM_END - LP_ROM_DRAM_START) + //On RISC-V CPUs, the interrupt sources are all external interrupts, whose type, source and priority are configured by SW. //There is no HW NMI conception. SW should controlled the masked levels through INT_THRESH_REG. diff --git a/components/ulp/Kconfig b/components/ulp/Kconfig index ff6f236867..1c7f7c2913 100644 --- a/components/ulp/Kconfig +++ b/components/ulp/Kconfig @@ -34,7 +34,7 @@ menu "Ultra Low Power (ULP) Co-processor" default 4096 if !IDF_TARGET_ESP32 range 32 8176 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3 range 32 16352 if IDF_TARGET_ESP32C5 || IDF_TARGET_ESP32C6 - range 32 32768 if IDF_TARGET_ESP32P4 + range 32 31088 if IDF_TARGET_ESP32P4 # Some memory are reserved for ROM/RTC reserved help Bytes of memory to reserve for ULP Co-processor firmware & data. Data is reserved at the beginning of RTC slow memory. diff --git a/components/ulp/cmake/CMakeLists.txt b/components/ulp/cmake/CMakeLists.txt index 92b7560f6e..dceac3f78d 100644 --- a/components/ulp/cmake/CMakeLists.txt +++ b/components/ulp/cmake/CMakeLists.txt @@ -36,6 +36,7 @@ list(REMOVE_DUPLICATES component_includes) list(APPEND ULP_PREPROCESSOR_ARGS ${component_includes}) list(APPEND ULP_PREPROCESSOR_ARGS -I${COMPONENT_DIR}) list(APPEND ULP_PREPROCESSOR_ARGS -I${sdkconfig_dir}) +list(APPEND ULP_PREPROCESSOR_ARGS -I${IDF_PATH}/components/esp_system/ld) target_include_directories(${ULP_APP_NAME} PRIVATE ${COMPONENT_INCLUDES}) diff --git a/components/ulp/ld/lp_core_riscv.ld b/components/ulp/ld/lp_core_riscv.ld index a3a069c892..4ecab5b34a 100644 --- a/components/ulp/ld/lp_core_riscv.ld +++ b/components/ulp/ld/lp_core_riscv.ld @@ -1,18 +1,26 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #include "sdkconfig.h" #include "soc/soc.h" +#include "ld.common" + +#if CONFIG_ESP_ROM_HAS_LP_ROM +/* With LP-ROM memory layout is different due to LP ROM stack/data */ +#define ULP_MEM_START_ADDRESS SOC_RTC_DRAM_LOW + RESERVE_RTC_MEM +#else +#define ULP_MEM_START_ADDRESS (SOC_RTC_DRAM_LOW) +#endif ENTRY(reset_vector) MEMORY { /*first 128byte for exception/interrupt vectors*/ - vector_table(RX) : ORIGIN = SOC_RTC_DRAM_LOW, LENGTH = 0x80 - ram(RWX) : ORIGIN = SOC_RTC_DRAM_LOW + 0x80, LENGTH = CONFIG_ULP_COPROC_RESERVE_MEM - 0x80 - CONFIG_ULP_SHARED_MEM + vector_table(RX) : ORIGIN = ULP_MEM_START_ADDRESS , LENGTH = 0x80 + ram(RWX) : ORIGIN = ULP_MEM_START_ADDRESS + 0x80, LENGTH = CONFIG_ULP_COPROC_RESERVE_MEM - 0x80 - CONFIG_ULP_SHARED_MEM } SECTIONS diff --git a/components/ulp/lp_core/lp_core.c b/components/ulp/lp_core/lp_core.c index d35265d0bd..9db3684d5a 100644 --- a/components/ulp/lp_core/lp_core.c +++ b/components/ulp/lp_core/lp_core.c @@ -24,6 +24,10 @@ #define LP_CORE_RCC_ATOMIC() #endif +#if ESP_ROM_HAS_LP_ROM +extern uint32_t _rtc_ulp_memory_start; +#endif //ESP_ROM_HAS_LP_ROM + const static char* TAG = "ulp-lp-core"; #define WAKEUP_SOURCE_MAX_NUMBER 5 @@ -60,13 +64,13 @@ esp_err_t ulp_lp_core_run(ulp_lp_core_cfg_t* cfg) /* If we have a LP ROM we boot from it, before jumping to the app code */ intptr_t boot_addr; if (cfg->skip_lp_rom_boot) { - boot_addr = (intptr_t)RTC_SLOW_MEM; + boot_addr = (intptr_t)(&_rtc_ulp_memory_start); } else { boot_addr = SOC_LP_ROM_LOW; } lp_core_ll_set_boot_address(boot_addr); - lp_core_ll_set_app_boot_address((intptr_t)RTC_SLOW_MEM); + lp_core_ll_set_app_boot_address((intptr_t)(&_rtc_ulp_memory_start)); #endif //ESP_ROM_HAS_LP_ROM LP_CORE_RCC_ATOMIC() { @@ -128,8 +132,11 @@ esp_err_t ulp_lp_core_load_binary(const uint8_t* program_binary, size_t program_ /* Turn off LP CPU before loading binary */ ulp_lp_core_stop(); - - uint8_t* base = (uint8_t*) RTC_SLOW_MEM; +#if ESP_ROM_HAS_LP_ROM + uint32_t* base = (uint32_t*)&_rtc_ulp_memory_start; +#else + uint32_t* base = RTC_SLOW_MEM; +#endif //Start by clearing memory reserved with zeros, this will also will initialize the bss: hal_memset(base, 0, CONFIG_ULP_COPROC_RESERVE_MEM); diff --git a/tools/test_apps/.build-test-rules.yml b/tools/test_apps/.build-test-rules.yml index 8d57882fb4..1805aa5d24 100644 --- a/tools/test_apps/.build-test-rules.yml +++ b/tools/test_apps/.build-test-rules.yml @@ -212,6 +212,12 @@ tools/test_apps/system/ram_loadable_app: - if: IDF_TARGET in ["esp32p4"] temporary: true reason: TBD # TODO: IDF-8994 + +tools/test_apps/system/rtc_mem_reserve: + enable: + - if: IDF_TARGET in ["esp32p4"] + reason: only P4 has a potential conflict due to using rtc mem for lp rom data/stack + tools/test_apps/system/startup: disable: - if: CONFIG_NAME == "main_task_cpu1" and IDF_TARGET not in ["esp32", "esp32s3"] diff --git a/tools/test_apps/system/rtc_mem_reserve/CMakeLists.txt b/tools/test_apps/system/rtc_mem_reserve/CMakeLists.txt new file mode 100644 index 0000000000..cf1729f249 --- /dev/null +++ b/tools/test_apps/system/rtc_mem_reserve/CMakeLists.txt @@ -0,0 +1,9 @@ +# The following lines of boilerplate have to be in your project's +# CMakeLists in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.5) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) + +set(COMPONENTS main) + +project(test_rtc_memory_reserve) diff --git a/tools/test_apps/system/rtc_mem_reserve/README.md b/tools/test_apps/system/rtc_mem_reserve/README.md new file mode 100644 index 0000000000..909282018f --- /dev/null +++ b/tools/test_apps/system/rtc_mem_reserve/README.md @@ -0,0 +1,2 @@ +| Supported Targets | ESP32-P4 | +| ----------------- | -------- | diff --git a/tools/test_apps/system/rtc_mem_reserve/main/CMakeLists.txt b/tools/test_apps/system/rtc_mem_reserve/main/CMakeLists.txt new file mode 100644 index 0000000000..e0ba362263 --- /dev/null +++ b/tools/test_apps/system/rtc_mem_reserve/main/CMakeLists.txt @@ -0,0 +1,24 @@ +idf_component_register(SRCS "rtc_mem_reserve_test_main.c" + INCLUDE_DIRS "." + REQUIRES ulp bootloader_support unity esp_mm) + +# +# ULP support additions to component CMakeLists.txt. +# +# 1. The ULP app name must be unique (if multiple components use ULP). +set(ulp_app_name ulp_${COMPONENT_NAME}) +# +# 2. Specify all C and Assembly source files. +# Files should be placed into a separate directory (in this case, ulp/), +# which should not be added to COMPONENT_SRCS. +set(ulp_sources "ulp/main.c") + +# +# 3. List all the component source files which include automatically +# generated ULP export file, ${ulp_app_name}.h: +set(ulp_exp_dep_srcs ${app_sources}) + +# +# 4. Call function to build ULP binary and embed in project using the argument +# values above. +ulp_embed_binary(${ulp_app_name} "${ulp_sources}" "${ulp_exp_dep_srcs}") diff --git a/tools/test_apps/system/rtc_mem_reserve/main/rtc_mem_reserve_test_main.c b/tools/test_apps/system/rtc_mem_reserve/main/rtc_mem_reserve_test_main.c new file mode 100644 index 0000000000..8cc712e07d --- /dev/null +++ b/tools/test_apps/system/rtc_mem_reserve/main/rtc_mem_reserve_test_main.c @@ -0,0 +1,123 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +/* + * This is an integration test for bootloader RTC reserve memory + ULP + * These both rely on the same RTC memory region, so we need to make sure they don't + * cause any conflict. + */ + +#include "sdkconfig.h" +#include +#include +#include +#include "bootloader_common.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "ulp_lp_core.h" +#include "ulp_main.h" +#include "unity.h" +#include "unity_test_runner.h" +#include "esp_cache.h" + +#define TEST_MAGIC_VALUE_A 0x42987561 +#define TEST_MAGIC_VALUE_B 0x32234701 +#define TEST_MAGIC_VALUE_C 0x62312178 +#define UNINITIALIZED_HEAP_VAL 0xCECECECE // From CONFIG_HEAP_POISONING_COMPREHENSIVE + +extern const uint8_t ulp_main_bin_start[] asm("_binary_ulp_main_bin_start"); +extern const uint8_t ulp_main_bin_end[] asm("_binary_ulp_main_bin_end"); + +extern rtc_retain_mem_t* bootloader_common_get_rtc_retain_mem(void); + +#define ULP_SLEEP_DURATION_US 10000 +#define HEAP_ALLOC_SIZE 0x1000 + +static void init_ulp_program(void) +{ + esp_err_t err = ulp_lp_core_load_binary(ulp_main_bin_start, (ulp_main_bin_end - ulp_main_bin_start)); + ESP_ERROR_CHECK(err); + + /* Start the program */ + ulp_lp_core_cfg_t cfg = { + .wakeup_source = ULP_LP_CORE_WAKEUP_SOURCE_LP_TIMER, + .lp_timer_sleep_duration_us = ULP_SLEEP_DURATION_US, + }; + + err = ulp_lp_core_run(&cfg); + ESP_ERROR_CHECK(err); +} + +static volatile RTC_DATA_ATTR uint32_t rtc_data_var = TEST_MAGIC_VALUE_B; +static volatile RTC_IRAM_ATTR uint32_t rtc_text_var = TEST_MAGIC_VALUE_C; + +static bool ulp_is_running(uint32_t *counter_variable) +{ + uint32_t start_cnt = *counter_variable; + + /* Wait a few ULP wakeup cycles to ensure ULP has run */ + vTaskDelay((5 * ULP_SLEEP_DURATION_US / 1000) / portTICK_PERIOD_MS); + + uint32_t end_cnt = *counter_variable; + printf("start run count: %" PRIu32 ", end run count %" PRIu32 "\n", start_cnt, end_cnt); + + /* If the ulp is running the counter should have been incremented */ + return (start_cnt != end_cnt); +} + +TEST_CASE("ULP do not corrupt RTC memory used by APP", "[rtc_mem_reserve]") +{ + rtc_retain_mem_t* mem = bootloader_common_get_rtc_retain_mem(); + uint32_t* _rtc_vars = (uint32_t*) mem->custom; + uint32_t *rtc_heap = heap_caps_malloc(HEAP_ALLOC_SIZE, MALLOC_CAP_RTCRAM); + + printf("Checking RTC reserve memory at %p\n", _rtc_vars); + printf("Checking RTC heap memory at %p\n", rtc_heap); + printf("Checking RTC data var at %p\n", &rtc_data_var); + printf("Checking RTC text var at %p\n", &rtc_text_var); + + TEST_ASSERT_EACH_EQUAL_HEX(TEST_MAGIC_VALUE_A, _rtc_vars, CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC_SIZE / sizeof(uint32_t)); + TEST_ASSERT_EQUAL(TEST_MAGIC_VALUE_B, rtc_data_var); + TEST_ASSERT_EQUAL(TEST_MAGIC_VALUE_C, rtc_text_var); + TEST_ASSERT_EACH_EQUAL_HEX(UNINITIALIZED_HEAP_VAL, rtc_heap, HEAP_ALLOC_SIZE / sizeof(uint32_t)); + + init_ulp_program(); + + // Let the ULP run for a few times to see + // if it corrupts the RTC memory or not + TEST_ASSERT(ulp_is_running(&ulp_run_counter)); + + TEST_ASSERT_EACH_EQUAL_HEX(TEST_MAGIC_VALUE_A, _rtc_vars, CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC_SIZE / sizeof(uint32_t)); + TEST_ASSERT_EQUAL(TEST_MAGIC_VALUE_B, rtc_data_var); + TEST_ASSERT_EQUAL(TEST_MAGIC_VALUE_C, rtc_text_var); + TEST_ASSERT_EACH_EQUAL_HEX(UNINITIALIZED_HEAP_VAL, rtc_heap, HEAP_ALLOC_SIZE / sizeof(uint32_t)); +} + +void app_main(void) +{ + rtc_retain_mem_t* mem = bootloader_common_get_rtc_retain_mem(); + uint32_t* _rtc_vars = (uint32_t*) mem->custom; + + esp_reset_reason_t reset_reason = esp_reset_reason(); + printf("RTC reserve memory placed at %p\n", _rtc_vars); + printf("RTC data var placed at %p\n", &rtc_data_var); + + if (reset_reason == ESP_RST_POWERON) { + printf("First boot, set RTC values and restart\n"); + for(int i = 0; i < CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC_SIZE / sizeof(uint32_t); i++) { + _rtc_vars[i] = TEST_MAGIC_VALUE_A; + } + + TEST_ASSERT_EACH_EQUAL_HEX(TEST_MAGIC_VALUE_A, _rtc_vars, CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC_SIZE / sizeof(uint32_t)); + TEST_ASSERT_EQUAL(TEST_MAGIC_VALUE_B, rtc_data_var); + TEST_ASSERT_EQUAL(TEST_MAGIC_VALUE_C, rtc_text_var); + + esp_restart(); + } + + unity_run_menu(); + +} diff --git a/tools/test_apps/system/rtc_mem_reserve/main/ulp/main.c b/tools/test_apps/system/rtc_mem_reserve/main/ulp/main.c new file mode 100644 index 0000000000..1f9ac62a4c --- /dev/null +++ b/tools/test_apps/system/rtc_mem_reserve/main/ulp/main.c @@ -0,0 +1,19 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +#include +#include "ulp_lp_core.h" +#include "ulp_lp_core_utils.h" + +/* this variable will be exported as a public symbol, visible from main CPU: */ +volatile uint32_t run_counter = 0; + +int main (void) +{ + run_counter++; + + /* ulp_lp_core_halt() is called automatically when main exits */ + return 0; +} diff --git a/tools/test_apps/system/rtc_mem_reserve/pytest_rtc_mem_reserve.py b/tools/test_apps/system/rtc_mem_reserve/pytest_rtc_mem_reserve.py new file mode 100644 index 0000000000..3a4e4de34a --- /dev/null +++ b/tools/test_apps/system/rtc_mem_reserve/pytest_rtc_mem_reserve.py @@ -0,0 +1,10 @@ +# SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: CC0-1.0 +import pytest +from pytest_embedded import Dut + + +@pytest.mark.esp32p4 +@pytest.mark.generic +def test_rtc_mem_reserve(dut: Dut) -> None: + dut.run_all_single_board_cases() diff --git a/tools/test_apps/system/rtc_mem_reserve/sdkconfig.defaults b/tools/test_apps/system/rtc_mem_reserve/sdkconfig.defaults new file mode 100644 index 0000000000..2c40a0923d --- /dev/null +++ b/tools/test_apps/system/rtc_mem_reserve/sdkconfig.defaults @@ -0,0 +1,10 @@ +CONFIG_BOOTLOADER_RESERVE_RTC_SIZE=0x10 +CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC=y +CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC_SIZE=0x200 +CONFIG_ESP_TASK_WDT_EN=n +CONFIG_HEAP_POISONING_COMPREHENSIVE=y + +# Enable ULP +CONFIG_ULP_COPROC_ENABLED=y +CONFIG_ULP_COPROC_TYPE_LP_CORE=y +CONFIG_ULP_COPROC_RESERVE_MEM=4096