diff --git a/components/bootloader/subproject/main/ld/esp32s2/bootloader.ld b/components/bootloader/subproject/main/ld/esp32s2/bootloader.ld index 25721f2d93..7a0be854a5 100644 --- a/components/bootloader/subproject/main/ld/esp32s2/bootloader.ld +++ b/components/bootloader/subproject/main/ld/esp32s2/bootloader.ld @@ -5,8 +5,8 @@ MEMORY { - iram_loader_seg (RWX) : org = 0x40050000, len = 0x4000 /* 16KB, SRAM Block_14 */ - iram_seg (RWX) : org = 0x40054000, len = 0x4000 /* 16KB, SRAM Block_15 */ + iram_seg (RWX) : org = 0x40050000, len = 0x4000 /* 16KB, SRAM Block_14 */ + iram_loader_seg (RWX) : org = 0x40054000, len = 0x4000 /* 16KB, SRAM Block_15 */ dram_seg (RW) : org = 0x3FFE8000, len = 0x2800 /* 10KB, Top of SRAM Block_16, and before ROM data and stack */ } diff --git a/components/esp32s2/Kconfig b/components/esp32s2/Kconfig index ccbe51872c..1bb1b845f5 100644 --- a/components/esp32s2/Kconfig +++ b/components/esp32s2/Kconfig @@ -244,6 +244,10 @@ menu "ESP32S2-specific" bool default "n" + config ESP32S2_MEMMAP_TRACEMEM_TWOBANKS + bool + default "n" + config ESP32S2_TRAX bool "Use TRAX tracing feature" default "n" diff --git a/components/esp32s2/ld/esp32s2.ld b/components/esp32s2/ld/esp32s2.ld index 34b5adfcb1..b742f3336b 100644 --- a/components/esp32s2/ld/esp32s2.ld +++ b/components/esp32s2/ld/esp32s2.ld @@ -26,16 +26,16 @@ #define RAM_IRAM_START 0x40020000 #define RAM_DRAM_START 0x3FFB0000 -#define DATA_RAM_END 0x3FFF0000 /* start address of bootloader */ + +#define DATA_RAM_END 0x3FFE4000 /* 2nd stage bootloader iram_loader_seg starts at block 15 */ #define IRAM_ORG (RAM_IRAM_START + CONFIG_ESP32S2_INSTRUCTION_CACHE_SIZE \ + CONFIG_ESP32S2_DATA_CACHE_SIZE) -#define IRAM_SIZE 0x18000 #define DRAM_ORG (RAM_DRAM_START + CONFIG_ESP32S2_INSTRUCTION_CACHE_SIZE \ - + CONFIG_ESP32S2_DATA_CACHE_SIZE \ - + IRAM_SIZE) -#define DRAM_SIZE DATA_RAM_END - DRAM_ORG + + CONFIG_ESP32S2_DATA_CACHE_SIZE) + +#define I_D_RAM_SIZE DATA_RAM_END - DRAM_ORG MEMORY { @@ -44,8 +44,9 @@ MEMORY are connected to the data port of the CPU and eg allow bytewise access. */ /* IRAM for CPU.*/ - iram0_0_seg (RX) : org = IRAM_ORG, len = IRAM_SIZE + iram0_0_seg (RX) : org = IRAM_ORG, len = I_D_RAM_SIZE +#ifdef CONFIG_APP_BUILD_USE_FLASH_SECTIONS /* Even though the segment name is iram, it is actually mapped to flash */ iram0_2_seg (RX) : org = 0x40080020, len = 0x780000-0x20 @@ -57,15 +58,18 @@ MEMORY 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 bootloader and ROM bss/data/stack. */ - dram0_0_seg (RW) : org = DRAM_ORG, len = DRAM_SIZE + dram0_0_seg (RW) : org = DRAM_ORG, len = I_D_RAM_SIZE +#ifdef CONFIG_APP_BUILD_USE_FLASH_SECTIONS /* Flash mapped constant data */ drom0_0_seg (R) : org = 0x3F000020, len = 0x3f0000-0x20 /* (See iram0_2_seg for meaning of 0x20 offset in the above.) */ +#endif // CONFIG_APP_BUILD_USE_FLASH_SECTIONS /* RTC fast memory (executable). Persists over deep sleep. */ @@ -84,11 +88,7 @@ MEMORY _static_data_end = _bss_end; -/* Heap ends at top of dram0_0_seg - ROM data mappings start from 0x3FFFC000, - 0x3FFF4000...0x3FFFC000 can be reserved for trace memory mapping -*/ -_heap_end = 0x3FFFC000 - CONFIG_ESP32S2_TRACEMEM_RESERVE_DRAM; +_heap_end = 0x40000000; _data_seg_org = ORIGIN(rtc_data_seg); @@ -101,3 +101,15 @@ REGION_ALIAS("rtc_data_location", rtc_slow_seg ); #else REGION_ALIAS("rtc_data_location", rtc_data_seg ); #endif + +#ifdef 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 + +#ifdef 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 diff --git a/components/esp32s2/ld/esp32s2.project.ld.in b/components/esp32s2/ld/esp32s2.project.ld.in index 39c55462fd..ecb804cd1d 100644 --- a/components/esp32s2/ld/esp32s2.project.ld.in +++ b/components/esp32s2/ld/esp32s2.project.ld.in @@ -164,8 +164,10 @@ SECTIONS _iram_end = ABSOLUTE(.); } > iram0_0_seg - ASSERT(((_iram_text_end - ORIGIN(iram0_0_seg)) <= LENGTH(iram0_0_seg)), - "IRAM0 segment data does not fit.") + .dram0_reserved_for_iram (NOLOAD): + { + . = ORIGIN(dram0_0_seg) + _iram_end - _iram_start; + } > dram0_0_seg .dram0.data : { @@ -243,9 +245,6 @@ SECTIONS _heap_start = ABSOLUTE(.); } > dram0_0_seg - ASSERT(((_bss_end - ORIGIN(dram0_0_seg)) <= LENGTH(dram0_0_seg)), - "DRAM segment data does not fit.") - /* When modifying the alignment, update tls_section_alignment in pxPortInitialiseStack */ .flash.rodata : ALIGN(0x10) { @@ -307,7 +306,7 @@ SECTIONS *(.tbss.*) _thread_local_end = ABSOLUTE(.); . = ALIGN(4); - } >drom0_0_seg + } >default_rodata_seg .flash.text : { @@ -329,5 +328,25 @@ SECTIONS the flash.text segment. */ _flash_cache_start = ABSOLUTE(0); - } >iram0_2_seg + } >default_code_seg + + /* Marks the end of IRAM code segment */ + .iram0.text_end (NOLOAD) : + { + . = ALIGN (4); + _iram_end = ABSOLUTE(.); + } > iram0_0_seg + + /* Marks the end of data, bss and possibly rodata */ + .dram0.heap_start (NOLOAD) : + { + . = ALIGN (8); + _heap_start = ABSOLUTE(.); + } > dram0_0_seg } + +ASSERT(((_iram_text_end - ORIGIN(iram0_0_seg)) <= LENGTH(iram0_0_seg)), + "IRAM0 segment data does not fit.") + +ASSERT(((_heap_start - _data_start) <= LENGTH(dram0_0_seg)), + "DRAM segment data does not fit.") diff --git a/components/soc/esp32/soc_memory_layout.c b/components/soc/esp32/soc_memory_layout.c index d8ba94d905..1a9144fc81 100644 --- a/components/soc/esp32/soc_memory_layout.c +++ b/components/soc/esp32/soc_memory_layout.c @@ -177,4 +177,13 @@ SOC_RESERVE_MEMORY_REGION(0x3fffc000, 0x40000000, trace_mem); //Reserve trace me SOC_RESERVE_MEMORY_REGION(SOC_EXTRAM_DATA_LOW, SOC_EXTRAM_DATA_LOW + RESERVE_SPIRAM_SIZE, spi_ram); //SPI RAM gets added later if needed, in spiram.c; reserve it for now #endif +extern int _data_start, _heap_start, _iram_start, _iram_end; +// Static data region. DRAM used by data+bss and possibly rodata +SOC_RESERVE_MEMORY_REGION((intptr_t)&_data_start, (intptr_t)&_heap_start, dram_data); + +// IRAM code region +// ESP32 has an IRAM-only region 0x4008_0000 - 0x4009_FFFF, reserve the used part +SOC_RESERVE_MEMORY_REGION((intptr_t)&_iram_start, (intptr_t)&_iram_end, iram_code); + + #endif /* BOOTLOADER_BUILD */ diff --git a/components/soc/esp32s2/interrupts.c b/components/soc/esp32s2/interrupts.c index 10856a3d4a..d84a9dac57 100644 --- a/components/soc/esp32s2/interrupts.c +++ b/components/soc/esp32s2/interrupts.c @@ -70,36 +70,44 @@ const char * const esp_isr_names[ETS_MAX_INTR_SOURCE] = { [52] = "I2C_EXT0", [53] = "I2C_EXT1", [54] = "RSA", - [55] = "SPI1_DMA", - [56] = "SPI2_DMA", - [57] = "SPI3_DMA", - [58] = "WDT", - [59] = "TIMER1", - [60] = "TIMER2", - [61] = "TG0_T0_EDGE", - [62] = "TG0_T1_EDGE", - [63] = "TG0_WDT_EDGE", - [64] = "TG0_LACT_EDGE", - [65] = "TG1_T0_EDGE", - [66] = "TG1_T1_EDGE", - [67] = "TG1_WDT_EDGE", - [68] = "TG1_LACT_EDGE", - [69] = "CACHE_IA", - [70] = "SYSTIMER_TARGET0", - [71] = "SYSTIMER_TARGET1", - [72] = "SYSTIMER_TARGET2", - [73] = "ASSIST_DEBUG", - [74] = "PMS_PRO_IRAM0_ILG", - [75] = "PMS_PRO_DRAM0_ILG", - [76] = "PMS_PRO_DPORT_ILG", - [77] = "PMS_PRO_AHB_ILG", - [78] = "PMS_PRO_CACHE_ILG", - [79] = "PMS_DMA_APB_I_ILG", - [80] = "PMS_DMA_RX_I_ILG", - [81] = "PMS_DMA_TX_I_ILG", - [82] = "SPI0_REJECT_CACHE", - [83] = "SPI1_REJECT_CPU", + [55] = "SHA", + [56] = "AES", + [57] = "SPI2_DMA", + [58] = "SPI3_DMA", + [59] = "WDT", + [60] = "TIMER1", + [61] = "TIMER2", + [62] = "TG0_T0_EDGE", + [63] = "TG0_T1_EDGE", + [64] = "TG0_WDT_EDGE", + [65] = "TG0_LACT_EDGE", + [66] = "TG1_T0_EDGE", + [67] = "TG1_T1_EDGE", + [68] = "TG1_WDT_EDGE", + [69] = "TG1_LACT_EDGE", + [70] = "CACHE_IA", + [71] = "SYSTIMER_TARGET0", + [72] = "SYSTIMER_TARGET1", + [73] = "SYSTIMER_TARGET2", + [74] = "ASSIST_DEBUG", + [75] = "PMS_PRO_IRAM0_ILG", + [76] = "PMS_PRO_DRAM0_ILG", + [77] = "PMS_PRO_DPORT_ILG", + [78] = "PMS_PRO_AHB_ILG", + [79] = "PMS_PRO_CACHE_ILG", + [80] = "PMS_DMA_APB_I_ILG", + [81] = "PMS_DMA_RX_I_ILG", + [82] = "PMS_DMA_TX_I_ILG", + [83] = "SPI0_REJECT_CACHE", [84] = "DMA_COPY", [85] = "SPI4_DMA", [86] = "SPI4", + [87] = "ICACHE_PRELOAD", + [88] = "DCACHE_PRELOAD", + [89] = "APB_ADC", + [90] = "CRYPTO_DMA", + [91] = "CPU_PERI_ERR", + [92] = "APB_PERI_ERR", + [93] = "DCACHE_SYNC", + [94] = "ICACHE_SYNC", }; diff --git a/components/soc/esp32s2/soc_memory_layout.c b/components/soc/esp32s2/soc_memory_layout.c index d9a84288d7..b3ad22e435 100644 --- a/components/soc/esp32s2/soc_memory_layout.c +++ b/components/soc/esp32s2/soc_memory_layout.c @@ -109,6 +109,8 @@ const size_t soc_memory_region_count = sizeof(soc_memory_regions)/sizeof(soc_mem extern int _dram0_rtos_reserved_start; +extern int _data_start, _heap_start, _iram_start, _iram_end; + /* Reserved memory regions These are removed from the soc_memory_regions array when heaps are created. @@ -116,11 +118,21 @@ extern int _dram0_rtos_reserved_start; //ROM data region SOC_RESERVE_MEMORY_REGION((intptr_t)&_dram0_rtos_reserved_start, SOC_BYTE_ACCESSIBLE_HIGH, rom_data_region); -// TODO: soc_memory_layout: handle trace memory regions - IDF-750 +// Static data region. DRAM used by data+bss and possibly rodata +SOC_RESERVE_MEMORY_REGION((intptr_t)&_data_start, (intptr_t)&_heap_start, dram_data); + +// ESP32S2 has a big D/IRAM region, the part used by code is reserved +// The address of the D/I bus are in the same order, directly shift IRAM address to get reserved DRAM address +#define I_D_OFFSET (SOC_IRAM_LOW - SOC_DRAM_LOW) +SOC_RESERVE_MEMORY_REGION((intptr_t)&_iram_start - I_D_OFFSET, (intptr_t)&_iram_end - I_D_OFFSET, iram_code); #ifdef CONFIG_SPIRAM SOC_RESERVE_MEMORY_REGION( SOC_EXTRAM_DATA_LOW, SOC_EXTRAM_DATA_HIGH, extram_data_region); //SPI RAM gets added later if needed, in spiram.c; reserve it for now #endif - +// Blocks 19 and 20 may be reserved for the trace memory +#if CONFIG_ESP32S2_TRACEMEM_RESERVE_DRAM > 0 +SOC_RESERVE_MEMORY_REGION(0x3fffc000 - CONFIG_ESP32S2_TRACEMEM_RESERVE_DRAM, 0x3fffc000, trace_mem); #endif + +#endif // BOOTLOADER_BUILD diff --git a/components/soc/src/memory_layout_utils.c b/components/soc/src/memory_layout_utils.c index a96b1c4b80..8a739ff8b1 100644 --- a/components/soc/src/memory_layout_utils.c +++ b/components/soc/src/memory_layout_utils.c @@ -26,20 +26,10 @@ static const char *TAG = "memory_layout"; extern soc_reserved_region_t soc_reserved_memory_region_start; extern soc_reserved_region_t soc_reserved_memory_region_end; -/* -These variables have the start and end of the data and static IRAM -area used by the program. Defined in the linker script. -*/ -extern int _data_start, _heap_start, _iram_start, _iram_end; - -/* static DRAM & IRAM chunks */ -static const size_t EXTRA_RESERVED_REGIONS = 2; - static size_t s_get_num_reserved_regions(void) { - return ( ( &soc_reserved_memory_region_end - - &soc_reserved_memory_region_start ) + - EXTRA_RESERVED_REGIONS ); + return ( &soc_reserved_memory_region_end + - &soc_reserved_memory_region_start ); } size_t soc_get_available_memory_region_max_count(void) @@ -63,26 +53,7 @@ static int s_compare_reserved_regions(const void *a, const void *b) */ static void s_prepare_reserved_regions(soc_reserved_region_t *reserved, size_t count) { - memcpy(reserved + EXTRA_RESERVED_REGIONS, - &soc_reserved_memory_region_start, - (count - EXTRA_RESERVED_REGIONS) * sizeof(soc_reserved_region_t)); - - /* Add the EXTRA_RESERVED_REGIONS at the beginning */ - reserved[0].start = (intptr_t)&_data_start; /* DRAM used by data+bss and possibly rodata */ - reserved[0].end = (intptr_t)&_heap_start; -#if CONFIG_IDF_TARGET_ESP32 - //ESP32 has a IRAM-only region 0x4008_0000 - 0x4009_FFFF, protect the used part - reserved[1].start = (intptr_t)&_iram_start; /* IRAM used by code */ - reserved[1].end = (intptr_t)&_iram_end; -#elif CONFIG_IDF_TARGET_ESP32S2 - //ESP32S2 has a big D/IRAM region, the part used by code is reserved - //The address of the D/I bus are in the same order, directly shift IRAM address to get reserved DRAM address - const uint32_t i_d_offset = SOC_IRAM_LOW - SOC_DRAM_LOW; - reserved[1].start = (intptr_t)&_iram_start - i_d_offset; /* IRAM used by code */ - reserved[1].end = (intptr_t)&_iram_end - i_d_offset; -#else -# error chip not implemented! -#endif + memcpy(reserved, &soc_reserved_memory_region_start, count * sizeof(soc_reserved_region_t)); /* Sort by starting address */ qsort(reserved, count, sizeof(soc_reserved_region_t), s_compare_reserved_regions); diff --git a/examples/system/sysview_tracing/CMakeLists.txt b/examples/system/sysview_tracing/CMakeLists.txt index 85173a8b6d..8c11f89459 100644 --- a/examples/system/sysview_tracing/CMakeLists.txt +++ b/examples/system/sysview_tracing/CMakeLists.txt @@ -2,6 +2,5 @@ # in this exact order for cmake to work correctly cmake_minimum_required(VERSION 3.5) -set(SUPPORTED_TARGETS esp32) include($ENV{IDF_PATH}/tools/cmake/project.cmake) project(sysview_tracing) diff --git a/examples/system/sysview_tracing/README.md b/examples/system/sysview_tracing/README.md index 91329c6fe6..e15d435b34 100644 --- a/examples/system/sysview_tracing/README.md +++ b/examples/system/sysview_tracing/README.md @@ -119,11 +119,15 @@ NOTE: In order to run this example you need OpenOCD version `v0.10.0-esp32-20181 Using this file GDB will connect to the target, reset it, and start tracing when it hit breakpoint at `app_main`. Trace data will be saved to `/tmp/sysview_example.svdat`. + **Note:** if running the example on ESP32-S2, modify the command name in gdbinit file from `esp32 sysview` to `esp32_s2 sysview`. + 6. Run GDB using the following command from the project root directory: ``` xtensa-esp32-elf-gdb -x gdbinit build/sysview_tracing.elf - ``` + ``` + + **Note:** Replace `xtensa-esp32-elf-gdb` with `xtensa-esp32s2-elf-gdb` if running the example on ESP32-S2. 7. When program prints the last message, interrupt its execution (e.g. by pressing `CTRL+C`) and type the following command in GDB console to stop tracing: diff --git a/examples/system/sysview_tracing_heap_log/CMakeLists.txt b/examples/system/sysview_tracing_heap_log/CMakeLists.txt index c2ff26776e..39a10b5524 100644 --- a/examples/system/sysview_tracing_heap_log/CMakeLists.txt +++ b/examples/system/sysview_tracing_heap_log/CMakeLists.txt @@ -2,6 +2,5 @@ # in this exact order for cmake to work correctly cmake_minimum_required(VERSION 3.5) -set(SUPPORTED_TARGETS esp32) include($ENV{IDF_PATH}/tools/cmake/project.cmake) project(sysview_tracing_heap_log) diff --git a/examples/system/sysview_tracing_heap_log/README.md b/examples/system/sysview_tracing_heap_log/README.md index 12caee37ff..f628b5041b 100644 --- a/examples/system/sysview_tracing_heap_log/README.md +++ b/examples/system/sysview_tracing_heap_log/README.md @@ -40,6 +40,9 @@ To run the example and collect trace data: ``` xtensa-esp32-elf-gdb -x gdbinit build/sysview_tracing_heap_log.elf ``` + + **Note**: if running the example on ESP32-S2, modify the command name in gdbinit file from `esp32 sysview` to `esp32_s2 sysview`, and run `xtensa-esp32s2-elf-gdb` instead of `xtensa-esp32-elf-gdb`. + 2. When program stops at `heap_trace_stop` quit GDB. 3. Open trace data file in SystemView tool.