soc_memory_layout.c 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. // Copyright 2010-2016 Espressif Systems (Shanghai) PTE LTD
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. // http://www.apache.org/licenses/LICENSE-2.0
  7. //
  8. // Unless required by applicable law or agreed to in writing, software
  9. // distributed under the License is distributed on an "AS IS" BASIS,
  10. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  11. // See the License for the specific language governing permissions and
  12. // limitations under the License.
  13. #ifndef BOOTLOADER_BUILD
  14. #include <stdlib.h>
  15. #include <stdint.h>
  16. #include "soc/soc.h"
  17. #include "soc/soc_memory_layout.h"
  18. #include "esp_heap_caps.h"
  19. #include "sdkconfig.h"
  20. /* Memory layout for ESP32 SoC */
  21. /*
  22. Memory type descriptors. These describe the capabilities of a type of memory in the SoC. Each type of memory
  23. map consist of one or more regions in the address space.
  24. Each type contains an array of prioritised capabilities; types with later entries are only taken if earlier
  25. ones can't fulfill the memory request.
  26. The prioritised capabilities work roughly like this:
  27. - For a normal malloc (MALLOC_CAP_DEFAULT), give away the DRAM-only memory first, then pass off any dual-use IRAM regions,
  28. finally eat into the application memory.
  29. - For a malloc where 32-bit-aligned-only access is okay, first allocate IRAM, then DRAM, finally application IRAM.
  30. - Application mallocs (PIDx) will allocate IRAM first, if possible, then DRAM.
  31. - Most other malloc caps only fit in one region anyway.
  32. */
  33. const soc_memory_type_desc_t soc_memory_types[] = {
  34. //Type 0: Plain ole D-port RAM
  35. { "DRAM", { MALLOC_CAP_8BIT|MALLOC_CAP_DEFAULT, MALLOC_CAP_INTERNAL|MALLOC_CAP_DMA|MALLOC_CAP_32BIT, 0 }, false, false},
  36. //Type 1: Plain ole D-port RAM which has an alias on the I-port
  37. //(This DRAM is also the region used by ROM during startup)
  38. { "D/IRAM", { 0, MALLOC_CAP_DMA|MALLOC_CAP_8BIT|MALLOC_CAP_INTERNAL|MALLOC_CAP_DEFAULT, MALLOC_CAP_32BIT|MALLOC_CAP_EXEC }, true, true},
  39. //Type 2: IRAM
  40. { "IRAM", { MALLOC_CAP_EXEC|MALLOC_CAP_32BIT|MALLOC_CAP_INTERNAL, 0, 0 }, false, false},
  41. //Type 3-8: PID 2-7 IRAM
  42. { "PID2IRAM", { MALLOC_CAP_PID2|MALLOC_CAP_INTERNAL, 0, MALLOC_CAP_EXEC|MALLOC_CAP_32BIT }, false, false},
  43. { "PID3IRAM", { MALLOC_CAP_PID3|MALLOC_CAP_INTERNAL, 0, MALLOC_CAP_EXEC|MALLOC_CAP_32BIT }, false, false},
  44. { "PID4IRAM", { MALLOC_CAP_PID4|MALLOC_CAP_INTERNAL, 0, MALLOC_CAP_EXEC|MALLOC_CAP_32BIT }, false, false},
  45. { "PID5IRAM", { MALLOC_CAP_PID5|MALLOC_CAP_INTERNAL, 0, MALLOC_CAP_EXEC|MALLOC_CAP_32BIT }, false, false},
  46. { "PID6IRAM", { MALLOC_CAP_PID6|MALLOC_CAP_INTERNAL, 0, MALLOC_CAP_EXEC|MALLOC_CAP_32BIT }, false, false},
  47. { "PID7IRAM", { MALLOC_CAP_PID7|MALLOC_CAP_INTERNAL, 0, MALLOC_CAP_EXEC|MALLOC_CAP_32BIT }, false, false},
  48. //Type 9-14: PID 2-7 DRAM
  49. { "PID2DRAM", { MALLOC_CAP_PID2|MALLOC_CAP_INTERNAL, MALLOC_CAP_8BIT, MALLOC_CAP_32BIT|MALLOC_CAP_DEFAULT }, false, false},
  50. { "PID3DRAM", { MALLOC_CAP_PID3|MALLOC_CAP_INTERNAL, MALLOC_CAP_8BIT, MALLOC_CAP_32BIT|MALLOC_CAP_DEFAULT }, false, false},
  51. { "PID4DRAM", { MALLOC_CAP_PID4|MALLOC_CAP_INTERNAL, MALLOC_CAP_8BIT, MALLOC_CAP_32BIT|MALLOC_CAP_DEFAULT }, false, false},
  52. { "PID5DRAM", { MALLOC_CAP_PID5|MALLOC_CAP_INTERNAL, MALLOC_CAP_8BIT, MALLOC_CAP_32BIT|MALLOC_CAP_DEFAULT }, false, false},
  53. { "PID6DRAM", { MALLOC_CAP_PID6|MALLOC_CAP_INTERNAL, MALLOC_CAP_8BIT, MALLOC_CAP_32BIT|MALLOC_CAP_DEFAULT }, false, false},
  54. { "PID7DRAM", { MALLOC_CAP_PID7|MALLOC_CAP_INTERNAL, MALLOC_CAP_8BIT, MALLOC_CAP_32BIT|MALLOC_CAP_DEFAULT }, false, false},
  55. #ifdef CONFIG_SPIRAM
  56. //Type 15: SPI SRAM data
  57. { "SPIRAM", { MALLOC_CAP_SPIRAM|MALLOC_CAP_DEFAULT, 0, MALLOC_CAP_8BIT|MALLOC_CAP_32BIT}, false, false},
  58. #endif
  59. };
  60. const size_t soc_memory_type_count = sizeof(soc_memory_types)/sizeof(soc_memory_type_desc_t);
  61. #if CONFIG_SPIRAM_SIZE == -1
  62. // Assume we need to reserve 4MB in the auto-detection case
  63. #define RESERVE_SPIRAM_SIZE (4*1024*1024)
  64. #else
  65. #define RESERVE_SPIRAM_SIZE CONFIG_SPIRAM_SIZE
  66. #endif
  67. /*
  68. Region descriptors. These describe all regions of memory available, and map them to a type in the above type.
  69. Because of requirements in the coalescing code which merges adjacent regions, this list should always be sorted
  70. from low to high start address.
  71. */
  72. const soc_memory_region_t soc_memory_regions[] = {
  73. #ifdef CONFIG_SPIRAM
  74. { SOC_EXTRAM_DATA_LOW, RESERVE_SPIRAM_SIZE, 15, 0}, //SPI SRAM, if available
  75. #endif
  76. { 0x3FFAE000, 0x2000, 0, 0}, //pool 16 <- used for rom code
  77. { 0x3FFB0000, 0x8000, 0, 0}, //pool 15 <- if BT is enabled, used as BT HW shared memory
  78. { 0x3FFB8000, 0x8000, 0, 0}, //pool 14 <- if BT is enabled, used data memory for BT ROM functions.
  79. { 0x3FFC0000, 0x2000, 0, 0}, //pool 10-13, mmu page 0
  80. { 0x3FFC2000, 0x2000, 0, 0}, //pool 10-13, mmu page 1
  81. { 0x3FFC4000, 0x2000, 0, 0}, //pool 10-13, mmu page 2
  82. { 0x3FFC6000, 0x2000, 0, 0}, //pool 10-13, mmu page 3
  83. { 0x3FFC8000, 0x2000, 0, 0}, //pool 10-13, mmu page 4
  84. { 0x3FFCA000, 0x2000, 0, 0}, //pool 10-13, mmu page 5
  85. { 0x3FFCC000, 0x2000, 0, 0}, //pool 10-13, mmu page 6
  86. { 0x3FFCE000, 0x2000, 0, 0}, //pool 10-13, mmu page 7
  87. { 0x3FFD0000, 0x2000, 0, 0}, //pool 10-13, mmu page 8
  88. { 0x3FFD2000, 0x2000, 0, 0}, //pool 10-13, mmu page 9
  89. { 0x3FFD4000, 0x2000, 0, 0}, //pool 10-13, mmu page 10
  90. { 0x3FFD6000, 0x2000, 0, 0}, //pool 10-13, mmu page 11
  91. { 0x3FFD8000, 0x2000, 0, 0}, //pool 10-13, mmu page 12
  92. { 0x3FFDA000, 0x2000, 0, 0}, //pool 10-13, mmu page 13
  93. { 0x3FFDC000, 0x2000, 0, 0}, //pool 10-13, mmu page 14
  94. { 0x3FFDE000, 0x2000, 0, 0}, //pool 10-13, mmu page 15
  95. { 0x3FFE0000, 0x4000, 1, 0x400BC000}, //pool 9 blk 1
  96. { 0x3FFE4000, 0x4000, 1, 0x400B8000}, //pool 9 blk 0
  97. { 0x3FFE8000, 0x8000, 1, 0x400B0000}, //pool 8 <- can be remapped to ROM, used for MAC dump
  98. { 0x3FFF0000, 0x8000, 1, 0x400A8000}, //pool 7 <- can be used for MAC dump
  99. { 0x3FFF8000, 0x4000, 1, 0x400A4000}, //pool 6 blk 1 <- can be used as trace memory
  100. { 0x3FFFC000, 0x4000, 1, 0x400A0000}, //pool 6 blk 0 <- can be used as trace memory
  101. { 0x40070000, 0x8000, 2, 0}, //pool 0
  102. { 0x40078000, 0x8000, 2, 0}, //pool 1
  103. { 0x40080000, 0x2000, 2, 0}, //pool 2-5, mmu page 0
  104. { 0x40082000, 0x2000, 2, 0}, //pool 2-5, mmu page 1
  105. { 0x40084000, 0x2000, 2, 0}, //pool 2-5, mmu page 2
  106. { 0x40086000, 0x2000, 2, 0}, //pool 2-5, mmu page 3
  107. { 0x40088000, 0x2000, 2, 0}, //pool 2-5, mmu page 4
  108. { 0x4008A000, 0x2000, 2, 0}, //pool 2-5, mmu page 5
  109. { 0x4008C000, 0x2000, 2, 0}, //pool 2-5, mmu page 6
  110. { 0x4008E000, 0x2000, 2, 0}, //pool 2-5, mmu page 7
  111. { 0x40090000, 0x2000, 2, 0}, //pool 2-5, mmu page 8
  112. { 0x40092000, 0x2000, 2, 0}, //pool 2-5, mmu page 9
  113. { 0x40094000, 0x2000, 2, 0}, //pool 2-5, mmu page 10
  114. { 0x40096000, 0x2000, 2, 0}, //pool 2-5, mmu page 11
  115. { 0x40098000, 0x2000, 2, 0}, //pool 2-5, mmu page 12
  116. { 0x4009A000, 0x2000, 2, 0}, //pool 2-5, mmu page 13
  117. { 0x4009C000, 0x2000, 2, 0}, //pool 2-5, mmu page 14
  118. { 0x4009E000, 0x2000, 2, 0}, //pool 2-5, mmu page 15
  119. };
  120. const size_t soc_memory_region_count = sizeof(soc_memory_regions)/sizeof(soc_memory_region_t);
  121. /* Reserved memory regions
  122. These are removed from the soc_memory_regions array when heaps are created.
  123. */
  124. SOC_RESERVE_MEMORY_REGION(SOC_CACHE_PRO_LOW, SOC_CACHE_PRO_HIGH, cpu0_cache);
  125. #ifndef CONFIG_FREERTOS_UNICORE
  126. SOC_RESERVE_MEMORY_REGION(SOC_CACHE_APP_LOW, SOC_CACHE_APP_HIGH, cpu1_cache);
  127. #endif
  128. /* Warning: The ROM stack is located in the 0x3ffe0000 area. We do not specifically disable that area here because
  129. after the scheduler has started, the ROM stack is not used anymore by anything. We handle it instead by not allowing
  130. any mallocs memory regions with the startup_stack flag set (these are the IRAM/DRAM region) until the
  131. scheduler has started.
  132. The 0x3ffe0000 region also contains static RAM for various ROM functions. The following lines
  133. reserve the regions for UART and ETSC, so these functions are usable. Libraries like xtos, which are
  134. not usable in FreeRTOS anyway, are commented out in the linker script so they cannot be used; we
  135. do not disable their memory regions here and they will be used as general purpose heap memory.
  136. Enabling the heap allocator for this region but disabling allocation here until FreeRTOS is started up
  137. is a somewhat risky action in theory, because on initializing the allocator, the multi_heap implementation
  138. will go and write metadata at the start and end of all regions. For the ESP32, these linked
  139. list entries happen to end up in a region that is not touched by the stack; they can be placed safely there.
  140. */
  141. SOC_RESERVE_MEMORY_REGION(0x3ffe0000, 0x3ffe0440, rom_pro_data); //Reserve ROM PRO data region
  142. #ifndef CONFIG_FREERTOS_UNICORE
  143. SOC_RESERVE_MEMORY_REGION(0x3ffe3f20, 0x3ffe4350, rom_app_data); //Reserve ROM APP data region
  144. #endif
  145. SOC_RESERVE_MEMORY_REGION(0x3ffae000, 0x3ffae6e0, rom_data);
  146. #if CONFIG_ESP32_MEMMAP_TRACEMEM
  147. #if CONFIG_ESP32_MEMMAP_TRACEMEM_TWOBANKS
  148. SOC_RESERVE_MEMORY_REGION(0x3fff8000, 0x40000000, trace_mem); //Reserve trace mem region, 32K for both cpu
  149. #else
  150. SOC_RESERVE_MEMORY_REGION(0x3fffc000, 0x40000000, trace_mem); //Reserve trace mem region, 16K (upper-half) for pro cpu
  151. #endif
  152. #endif
  153. #ifdef CONFIG_SPIRAM
  154. 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
  155. #endif
  156. #endif /* BOOTLOADER_BUILD */