From 953f44b46e07b5efef3a63c1eea424d66608a0da Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Wed, 13 Jul 2022 10:51:19 -0500 Subject: [PATCH] Fix spiram limit calculation on esp32 esp32 places the psram start at SOC_EXTRAM_DATA_LOW and it can extend up to SOC_EXTRAM_DATA_SIZE. This is different than esp32-s2 and later, which place the end at EXTRAM_DATA_HIGH and the limitation of SOC_EXTRAM_DATA_SIZE was not previously identified as important. Additionally, the esp32 has a reserved area within himem which was not being accounted for. With this change, the Feather ESP32 V2 feather can be used via thonny, and the other "quick memory corruption tests" I was performing also all succeed instead of failing. Before this change, the incorrect address being used for spiram was 0x3fa00000..0x3fc00000 (2MiB). Now, it's 0x3f800000..0x3f9c0000 (1.75MiB) due to the reserved area and the changed start address. This is intended to be a no-effect change for other espressif chips besides original esp32. --- ports/espressif/supervisor/port.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/ports/espressif/supervisor/port.c b/ports/espressif/supervisor/port.c index f9d978c5b4..f2288ebcb0 100644 --- a/ports/espressif/supervisor/port.c +++ b/ports/espressif/supervisor/port.c @@ -89,6 +89,17 @@ #ifdef CONFIG_SPIRAM #include "esp32/spiram.h" +#ifdef CONFIG_IDF_TARGET_ESP32 +#include "esp32/himem.h" +#else +#define esp_himem_reserved_area_size() (0) +#endif + +static size_t spiram_size_usable_for_malloc(void) { + /* SPIRAM chip may be larger than the size we can map into address space */ + size_t s = MIN(esp_spiram_get_size(), SOC_EXTRAM_DATA_SIZE); + return s - esp_himem_reserved_area_size(); +} #endif // Heap sizes for when there is no external RAM for CircuitPython to use @@ -209,8 +220,12 @@ safe_mode_t port_init(void) { #ifdef CONFIG_SPIRAM if (esp_spiram_is_initialized()) { - size_t spiram_size = esp_spiram_get_size(); + size_t spiram_size = spiram_size_usable_for_malloc(); + #ifdef CONFIG_IDF_TARGET_ESP32 + heap = (uint32_t *)SOC_EXTRAM_DATA_LOW; + #else heap = (uint32_t *)(SOC_EXTRAM_DATA_HIGH - spiram_size); + #endif heap_size = spiram_size / sizeof(uint32_t); } #endif