memory_layout.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. /*
  2. * SPDX-FileCopyrightText: 2010-2023 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #include <stdlib.h>
  7. #include <stdint.h>
  8. #include "soc/soc.h"
  9. #include "heap_memory_layout.h"
  10. #include "esp_heap_caps.h"
  11. #include "sdkconfig.h"
  12. #ifdef CONFIG_ESP32_IRAM_AS_8BIT_ACCESSIBLE_MEMORY
  13. #define MALLOC_IRAM_CAP MALLOC_CAP_EXEC|MALLOC_CAP_32BIT|MALLOC_CAP_IRAM_8BIT
  14. #else
  15. #define MALLOC_IRAM_CAP MALLOC_CAP_EXEC|MALLOC_CAP_32BIT
  16. #endif
  17. /* Memory layout for ESP32 SoC */
  18. /*
  19. Memory type descriptors. These describe the capabilities of a type of memory in the SoC. Each type of memory
  20. map consist of one or more regions in the address space.
  21. Each type contains an array of prioritised capabilities; types with later entries are only taken if earlier
  22. ones can't fulfill the memory request.
  23. The prioritised capabilities work roughly like this:
  24. - For a normal malloc (MALLOC_CAP_DEFAULT), give away the DRAM-only memory first, then pass off any dual-use IRAM regions,
  25. finally eat into the application memory.
  26. - For a malloc where 32-bit-aligned-only access is okay, first allocate IRAM, then DRAM, finally application IRAM.
  27. - Application mallocs (PIDx) will allocate IRAM first, if possible, then DRAM.
  28. - Most other malloc caps only fit in one region anyway.
  29. */
  30. enum {
  31. SOC_MEMORY_TYPE_DRAM = 0,
  32. SOC_MEMORY_TYPE_DIRAM = 1,
  33. SOC_MEMORY_TYPE_IRAM = 2,
  34. SOC_MEMORY_TYPE_SPIRAM = 3,
  35. SOC_MEMORY_TYPE_RTCRAM = 4,
  36. SOC_MEMORY_TYPE_NUM,
  37. };
  38. const soc_memory_type_desc_t soc_memory_types[] = {
  39. //Type 0: Plain ole D-port RAM
  40. [SOC_MEMORY_TYPE_DRAM] = { "DRAM", { MALLOC_CAP_8BIT|MALLOC_CAP_DEFAULT, MALLOC_CAP_INTERNAL|MALLOC_CAP_DMA|MALLOC_CAP_32BIT, 0 }},
  41. //Type 1: Plain ole D-port RAM which has an alias on the I-port
  42. //(This DRAM is also the region used by ROM during startup, and decrease the allocation priority to avoid MALLOC_CAP_EXEC memory running out too soon)
  43. [SOC_MEMORY_TYPE_DIRAM] = { "D/IRAM", { 0, MALLOC_CAP_DMA|MALLOC_CAP_8BIT|MALLOC_CAP_INTERNAL|MALLOC_CAP_DEFAULT, MALLOC_CAP_32BIT|MALLOC_CAP_EXEC }},
  44. //Type 2: IRAM
  45. [SOC_MEMORY_TYPE_IRAM] = { "IRAM", { MALLOC_CAP_INTERNAL|MALLOC_IRAM_CAP, 0, 0 }},
  46. //Type 3: SPI SRAM data
  47. [SOC_MEMORY_TYPE_SPIRAM] = { "SPIRAM", { MALLOC_CAP_SPIRAM|MALLOC_CAP_DEFAULT, 0, MALLOC_CAP_8BIT|MALLOC_CAP_32BIT}},
  48. //Type 4: RTC Fast RAM
  49. [SOC_MEMORY_TYPE_RTCRAM] = { "RTCRAM", { MALLOC_CAP_RTCRAM, MALLOC_CAP_8BIT|MALLOC_CAP_DEFAULT, MALLOC_CAP_INTERNAL|MALLOC_CAP_32BIT|MALLOC_CAP_EXEC }},
  50. };
  51. const size_t soc_memory_type_count = sizeof(soc_memory_types)/sizeof(soc_memory_type_desc_t);
  52. /*
  53. Region descriptors. These describe all regions of memory available, and map them to a type in the above type.
  54. Because of requirements in the coalescing code which merges adjacent regions, this list should always be sorted
  55. from low to high start address.
  56. */
  57. const soc_memory_region_t soc_memory_regions[] = {
  58. #ifdef CONFIG_SPIRAM
  59. { SOC_EXTRAM_DATA_LOW, SOC_EXTRAM_DATA_SIZE, SOC_MEMORY_TYPE_SPIRAM, 0, false}, //SPI SRAM, if available
  60. #endif
  61. { 0x3FFAE000, 0x2000, SOC_MEMORY_TYPE_DRAM, 0, false}, //pool 16 <- used for rom code
  62. { 0x3FFB0000, 0x8000, SOC_MEMORY_TYPE_DRAM, 0, false}, //pool 15 <- if BT is enabled, used as BT HW shared memory
  63. { 0x3FFB8000, 0x8000, SOC_MEMORY_TYPE_DRAM, 0, false}, //pool 14 <- if BT is enabled, used data memory for BT ROM functions.
  64. { 0x3FFC0000, 0x2000, SOC_MEMORY_TYPE_DRAM, 0, false}, //pool 10-13, mmu page 0
  65. { 0x3FFC2000, 0x2000, SOC_MEMORY_TYPE_DRAM, 0, false}, //pool 10-13, mmu page 1
  66. { 0x3FFC4000, 0x2000, SOC_MEMORY_TYPE_DRAM, 0, false}, //pool 10-13, mmu page 2
  67. { 0x3FFC6000, 0x2000, SOC_MEMORY_TYPE_DRAM, 0, false}, //pool 10-13, mmu page 3
  68. { 0x3FFC8000, 0x2000, SOC_MEMORY_TYPE_DRAM, 0, false}, //pool 10-13, mmu page 4
  69. { 0x3FFCA000, 0x2000, SOC_MEMORY_TYPE_DRAM, 0, false}, //pool 10-13, mmu page 5
  70. { 0x3FFCC000, 0x2000, SOC_MEMORY_TYPE_DRAM, 0, false}, //pool 10-13, mmu page 6
  71. { 0x3FFCE000, 0x2000, SOC_MEMORY_TYPE_DRAM, 0, false}, //pool 10-13, mmu page 7
  72. { 0x3FFD0000, 0x2000, SOC_MEMORY_TYPE_DRAM, 0, false}, //pool 10-13, mmu page 8
  73. { 0x3FFD2000, 0x2000, SOC_MEMORY_TYPE_DRAM, 0, false}, //pool 10-13, mmu page 9
  74. { 0x3FFD4000, 0x2000, SOC_MEMORY_TYPE_DRAM, 0, false}, //pool 10-13, mmu page 10
  75. { 0x3FFD6000, 0x2000, SOC_MEMORY_TYPE_DRAM, 0, false}, //pool 10-13, mmu page 11
  76. { 0x3FFD8000, 0x2000, SOC_MEMORY_TYPE_DRAM, 0, false}, //pool 10-13, mmu page 12
  77. { 0x3FFDA000, 0x2000, SOC_MEMORY_TYPE_DRAM, 0, false}, //pool 10-13, mmu page 13
  78. { 0x3FFDC000, 0x2000, SOC_MEMORY_TYPE_DRAM, 0, false}, //pool 10-13, mmu page 14
  79. { 0x3FFDE000, 0x2000, SOC_MEMORY_TYPE_DRAM, 0, false}, //pool 10-13, mmu page 15
  80. { 0x3FFE0000, 0x4000, SOC_MEMORY_TYPE_DIRAM, 0x400BC000,true}, //pool 9 blk 1
  81. { 0x3FFE4000, 0x4000, SOC_MEMORY_TYPE_DIRAM, 0x400B8000,true}, //pool 9 blk 0
  82. { 0x3FFE8000, 0x8000, SOC_MEMORY_TYPE_DIRAM, 0x400B0000,true}, //pool 8 <- can be remapped to ROM, used for MAC dump
  83. { 0x3FFF0000, 0x8000, SOC_MEMORY_TYPE_DIRAM, 0x400A8000,true}, //pool 7 <- can be used for MAC dump
  84. { 0x3FFF8000, 0x4000, SOC_MEMORY_TYPE_DIRAM, 0x400A4000,true}, //pool 6 blk 1 <- can be used as trace memory
  85. { 0x3FFFC000, 0x4000, SOC_MEMORY_TYPE_DIRAM, 0x400A0000,true}, //pool 6 blk 0 <- can be used as trace memory
  86. { 0x40070000, 0x8000, SOC_MEMORY_TYPE_IRAM, 0, false}, //pool 0
  87. { 0x40078000, 0x8000, SOC_MEMORY_TYPE_IRAM, 0, false}, //pool 1
  88. { 0x40080000, 0x2000, SOC_MEMORY_TYPE_IRAM, 0, false}, //pool 2-5, mmu page 0
  89. { 0x40082000, 0x2000, SOC_MEMORY_TYPE_IRAM, 0, false}, //pool 2-5, mmu page 1
  90. { 0x40084000, 0x2000, SOC_MEMORY_TYPE_IRAM, 0, false}, //pool 2-5, mmu page 2
  91. { 0x40086000, 0x2000, SOC_MEMORY_TYPE_IRAM, 0, false}, //pool 2-5, mmu page 3
  92. { 0x40088000, 0x2000, SOC_MEMORY_TYPE_IRAM, 0, false}, //pool 2-5, mmu page 4
  93. { 0x4008A000, 0x2000, SOC_MEMORY_TYPE_IRAM, 0, false}, //pool 2-5, mmu page 5
  94. { 0x4008C000, 0x2000, SOC_MEMORY_TYPE_IRAM, 0, false}, //pool 2-5, mmu page 6
  95. { 0x4008E000, 0x2000, SOC_MEMORY_TYPE_IRAM, 0, false}, //pool 2-5, mmu page 7
  96. { 0x40090000, 0x2000, SOC_MEMORY_TYPE_IRAM, 0, false}, //pool 2-5, mmu page 8
  97. { 0x40092000, 0x2000, SOC_MEMORY_TYPE_IRAM, 0, false}, //pool 2-5, mmu page 9
  98. { 0x40094000, 0x2000, SOC_MEMORY_TYPE_IRAM, 0, false}, //pool 2-5, mmu page 10
  99. { 0x40096000, 0x2000, SOC_MEMORY_TYPE_IRAM, 0, false}, //pool 2-5, mmu page 11
  100. { 0x40098000, 0x2000, SOC_MEMORY_TYPE_IRAM, 0, false}, //pool 2-5, mmu page 12
  101. { 0x4009A000, 0x2000, SOC_MEMORY_TYPE_IRAM, 0, false}, //pool 2-5, mmu page 13
  102. { 0x4009C000, 0x2000, SOC_MEMORY_TYPE_IRAM, 0, false}, //pool 2-5, mmu page 14
  103. { 0x4009E000, 0x2000, SOC_MEMORY_TYPE_IRAM, 0, false}, //pool 2-5, mmu page 15
  104. #ifdef CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP
  105. { SOC_RTC_DRAM_LOW, 0x2000, SOC_MEMORY_TYPE_RTCRAM, 0, false}, //RTC Fast Memory
  106. #endif
  107. };
  108. const size_t soc_memory_region_count = sizeof(soc_memory_regions)/sizeof(soc_memory_region_t);
  109. /* Reserved memory regions
  110. These are removed from the soc_memory_regions array when heaps are created.
  111. */
  112. SOC_RESERVE_MEMORY_REGION(SOC_CACHE_PRO_LOW, SOC_CACHE_PRO_HIGH, cpu0_cache);
  113. #ifndef CONFIG_FREERTOS_UNICORE
  114. SOC_RESERVE_MEMORY_REGION(SOC_CACHE_APP_LOW, SOC_CACHE_APP_HIGH, cpu1_cache);
  115. #endif
  116. /* Warning: The ROM stack is located in the 0x3ffe0000 area. We do not specifically disable that area here because
  117. after the scheduler has started, the ROM stack is not used anymore by anything. We handle it instead by not allowing
  118. any mallocs memory regions with the startup_stack flag set (these are the IRAM/DRAM region) until the
  119. scheduler has started.
  120. The 0x3ffe0000 region also contains static RAM for various ROM functions. The following lines
  121. reserve the regions for UART and ETSC, so these functions are usable. Libraries like xtos, which are
  122. not usable in FreeRTOS anyway, are commented out in the linker script so they cannot be used; we
  123. do not disable their memory regions here and they will be used as general purpose heap memory.
  124. Enabling the heap allocator for this region but disabling allocation here until FreeRTOS is started up
  125. is a somewhat risky action in theory, because on initializing the allocator, the multi_heap implementation
  126. will go and write metadata at the start and end of all regions. For the ESP32, these linked
  127. list entries happen to end up in a region that is not touched by the stack; they can be placed safely there.
  128. */
  129. SOC_RESERVE_MEMORY_REGION(0x3ffe0000, 0x3ffe0440, rom_pro_data); //Reserve ROM PRO data region
  130. #ifndef CONFIG_FREERTOS_UNICORE
  131. SOC_RESERVE_MEMORY_REGION(0x3ffe3f20, 0x3ffe4350, rom_app_data); //Reserve ROM APP data region
  132. #endif
  133. SOC_RESERVE_MEMORY_REGION(0x3ffae000, 0x3ffae6e0, rom_data);
  134. #if CONFIG_ESP32_MEMMAP_TRACEMEM
  135. #if CONFIG_ESP32_MEMMAP_TRACEMEM_TWOBANKS
  136. SOC_RESERVE_MEMORY_REGION(0x3fff8000, 0x40000000, trace_mem); //Reserve trace mem region, 32K for both cpu
  137. #else
  138. SOC_RESERVE_MEMORY_REGION(0x3fffc000, 0x40000000, trace_mem); //Reserve trace mem region, 16K (upper-half) for pro cpu
  139. #endif
  140. #endif
  141. #ifdef CONFIG_SPIRAM
  142. /* Reserve the whole possible SPIRAM region here, spiram.c will add some or all of this
  143. * memory to heap depending on the actual SPIRAM chip size. */
  144. SOC_RESERVE_MEMORY_REGION(SOC_EXTRAM_DATA_LOW, SOC_EXTRAM_DATA_HIGH, spi_ram);
  145. #endif
  146. extern int _data_start, _heap_start, _heap_end, _iram_start, _iram_end, _rtc_force_fast_end, _rtc_noinit_end;
  147. extern int _rtc_fast_reserved_start, _rtc_fast_reserved_end;
  148. extern int _rtc_slow_reserved_start, _rtc_slow_reserved_end;
  149. // Static data region. DRAM used by data+bss and possibly rodata
  150. SOC_RESERVE_MEMORY_REGION((intptr_t)&_data_start, (intptr_t)&_heap_start, dram_data);
  151. // IRAM code region
  152. // ESP32 has an IRAM-only region 0x4008_0000 - 0x4009_FFFF, reserve the used part
  153. SOC_RESERVE_MEMORY_REGION((intptr_t)&_iram_start, (intptr_t)&_iram_end, iram_code);
  154. // If IRAM spans into SRAM1 due to CONFIG_ESP_SYSTEM_ESP32_SRAM1_REGION_AS_IRAM, reserve the corresponding part of DRAM
  155. #ifdef CONFIG_ESP_SYSTEM_ESP32_SRAM1_REGION_AS_IRAM
  156. SOC_RESERVE_MEMORY_REGION((intptr_t) &_heap_end, 0x40000000, sram1_iram);
  157. #endif
  158. // RTC Fast RAM region
  159. #ifdef CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP
  160. #ifdef CONFIG_ESP32_RTCDATA_IN_FAST_MEM
  161. SOC_RESERVE_MEMORY_REGION(SOC_RTC_DRAM_LOW, (intptr_t)&_rtc_noinit_end, rtcram_data);
  162. #else
  163. SOC_RESERVE_MEMORY_REGION(SOC_RTC_DRAM_LOW, (intptr_t)&_rtc_force_fast_end, rtcram_data);
  164. #endif
  165. #endif
  166. SOC_RESERVE_MEMORY_REGION((intptr_t)&_rtc_fast_reserved_start, (intptr_t)&_rtc_fast_reserved_end, rtc_fast_reserved_data);
  167. SOC_RESERVE_MEMORY_REGION((intptr_t)&_rtc_slow_reserved_start, (intptr_t)&_rtc_slow_reserved_end, rtc_reserved_data);