soc: espressif: keep RTC data after deep-sleep

This PR includes changes in all Espressif's SoCs to enable
keeping data in RTC memory after deep-sleep.

Signed-off-by: Sylvio Alves <sylvio.alves@espressif.com>
This commit is contained in:
Sylvio Alves 2025-01-07 11:49:09 -03:00 committed by Benjamin Cabé
commit 5d05e28fce
7 changed files with 376 additions and 215 deletions

View file

@ -48,16 +48,13 @@ user_sram_size = (user_sram_end - user_sram_org);
#undef SECTION_PROLOGUE
#define SECTION_PROLOGUE SECTION_DATA_PROLOGUE
/* TODO: add RTC support */
#define RESERVE_RTC_MEM 0
/* Global symbols required for espressif hal build */
MEMORY
{
#ifdef CONFIG_BOOTLOADER_MCUBOOT
mcuboot_hdr (R): org = 0x0, len = 0x20
metadata (R): org = 0x20, len = 0x20
FLASH (R): org = 0x40, len = FLASH_SIZE - 0x40
metadata (R): org = 0x20, len = 0x60
FLASH (R): org = 0x80, len = FLASH_SIZE - 0x80
#else
/* Make safety margin in the FLASH memory size so the
* (esp_img_header + (n*esp_seg_headers)) would fit */
@ -70,10 +67,19 @@ MEMORY
drom0_0_seg(R): org = DROM_SEG_ORG, len = DROM_SEG_LEN
lp_ram_seg(RW): org = LPSRAM_IRAM_START,
len = 0x2000 - RESERVE_RTC_MEM
len = 0x4000 - CONFIG_RESERVE_RTC_MEM
lp_reserved_seg(RW) : org = LPSRAM_IRAM_START + 0x2000 - RESERVE_RTC_MEM,
len = RESERVE_RTC_MEM
/* We reduced the size of lp_ram_seg by CONFIG_RESERVE_RTC_MEM value.
It reserves the amount of LP memory that we use for this memory segment.
This segment is intended for keeping:
- (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.
*/
#if (CONFIG_RESERVE_RTC_MEM > 0)
lp_reserved_seg(RW) : org = LPSRAM_IRAM_START + 0x4000 - CONFIG_RESERVE_RTC_MEM,
len = CONFIG_RESERVE_RTC_MEM
#endif
#ifdef CONFIG_GEN_ISR_TABLES
IDT_LIST(RW): org = 0x3ebfe010, len = 0x2000
@ -90,7 +96,6 @@ 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 );
REGION_ALIAS("rtc_reserved_seg", lp_reserved_seg );
/* Default entry point: */
ENTRY(CONFIG_KERNEL_ENTRY)
@ -133,6 +138,26 @@ SECTIONS
LONG(ADDR(.dram0.data))
LONG(LOADADDR(.dram0.data))
LONG(LOADADDR(.dram0.end) - LOADADDR(.dram0.data))
/* LP_IRAM metadata:
* 8. Destination address (VMA) for LP_IRAM region
* 9. Flash offset (LMA) for start of LP_IRAM region
* 10. Size of RTC region
*/
LONG(ADDR(.rtc.text))
LONG(LOADADDR(.rtc.text))
LONG(SIZEOF(.rtc.text))
/* LP_DATA metadata:
* 11. Destination address (VMA) for LP_DATA region
* 12. Flash offset (LMA) for start of LP_DATA region
* 13. Size of RTC region
*/
LONG(ADDR(.rtc.data))
LONG(LOADADDR(.rtc.data))
LONG(SIZEOF(.rtc.data))
} > metadata
#endif /* CONFIG_BOOTLOADER_MCUBOOT */
@ -150,12 +175,10 @@ SECTIONS
_rtc_fast_start = ABSOLUTE(.);
_rtc_text_start = ABSOLUTE(.);
*(.rtc.entry.text)
*(.rtc.literal .rtc.text)
*rtc_wake_stub*.o(.literal .text .literal.* .text.*)
*(.rtc.literal .rtc.literal.* .rtc.text .rtc.text.*)
. = ALIGN(4);
_rtc_text_end = ABSOLUTE(.);
} GROUP_DATA_LINK_IN(rtc_iram_seg, ROMABLE_REGION)
} GROUP_DATA_LINK_IN(lp_ram_seg, ROMABLE_REGION)
/* This section located in RTC FAST Memory area.
* It holds data marked with RTC_FAST_ATTR attribute.
@ -167,9 +190,9 @@ SECTIONS
_rtc_force_fast_start = ABSOLUTE(.);
*(.rtc.force_fast .rtc.force_fast.*)
. = ALIGN(4) ;
. = ALIGN(4);
_rtc_force_fast_end = ABSOLUTE(.);
} GROUP_DATA_LINK_IN(rtc_data_seg, ROMABLE_REGION)
} GROUP_DATA_LINK_IN(lp_ram_seg, ROMABLE_REGION)
/* RTC data section holds data marked with
* RTC_DATA_ATTR, RTC_RODATA_ATTR attributes.
@ -177,34 +200,31 @@ SECTIONS
.rtc.data :
{
_rtc_data_start = ABSOLUTE(.);
*(.rtc.data)
*(.rtc.rodata)
*(.rtc.data .rtc.data.*)
*(.rtc.rodata .rtc.rodata.*)
_rtc_data_end = ABSOLUTE(.);
} GROUP_DATA_LINK_IN(rtc_iram_seg, ROMABLE_REGION)
} GROUP_DATA_LINK_IN(lp_ram_seg, ROMABLE_REGION)
.rtc.bss (NOLOAD) :
{
_rtc_bss_start = ABSOLUTE(.);
*(.rtc.data)
*(.rtc.rodata)
*(.rtc.bss .rtc.bss.*)
_rtc_bss_end = ABSOLUTE(.);
} GROUP_LINK_IN(rtc_iram_seg)
} GROUP_LINK_IN(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):
.rtc_noinit (NOLOAD) :
{
. = ALIGN(4);
_rtc_noinit_start = ABSOLUTE(.);
*(.rtc_noinit .rtc_noinit.*)
. = ALIGN(4) ;
_rtc_noinit_end = ABSOLUTE(.);
} GROUP_LINK_IN(rtc_slow_seg)
} GROUP_LINK_IN(lp_ram_seg)
/* This section located in RTC SLOW Memory area.
* It holds data marked with RTC_SLOW_ATTR attribute.
@ -217,24 +237,21 @@ SECTIONS
*(.rtc.force_slow .rtc.force_slow.*)
. = ALIGN(4);
_rtc_force_slow_end = ABSOLUTE(.);
} GROUP_DATA_LINK_IN(rtc_slow_seg, ROMABLE_REGION)
} GROUP_DATA_LINK_IN(lp_ram_seg, ROMABLE_REGION)
/**
* This section holds RTC data that should have fixed addresses.
* The data are not initialized at power-up and are retained during deep sleep.
*/
.rtc_reserved (NOLOAD):
#if (CONFIG_RESERVE_RTC_MEM > 0)
.rtc_reserved (NOLOAD) :
{
. = ALIGN(4);
_rtc_reserved_start = ABSOLUTE(.);
/* 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 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(.);
} GROUP_LINK_IN(rtc_reserved_seg)
} GROUP_LINK_IN(lp_reserved_seg)
#endif
/* Get size of rtc slow data based on rtc_data_location alias */
_rtc_slow_length = (_rtc_force_slow_end - _rtc_data_start);