arch/xtensa: enable SPIRAM test during boot of ESP32|S3

This commit is contained in:
Filipe Cavalcanti
2024-12-23 11:53:30 -03:00
committed by Xiang Xiao
parent eeef185558
commit 75aa80dba8
6 changed files with 85 additions and 10 deletions
+56
View File
@@ -282,6 +282,62 @@ void IRAM_ATTR esp_spiram_init_cache(void)
#endif #endif
} }
/* Simple RAM test. Writes a word every 32 bytes. Takes about a second
* to complete for 4MiB. Returns OK when RAM seems OK, ERROR when test
* fails. WARNING: Do not run this before the 2nd cpu has been initialized
* (in a two-core system) or after the heap allocator has taken ownership
* of the memory.
*/
int esp_spiram_test(void)
{
volatile int *spiram = (volatile int *)PRO_DRAM1_START_ADDR;
/* Set size value to 4 MB which is related to psize argument on
* cache_sram_mmu_set() calls. In this SoC, psize is 32 Mbit.
*/
size_t s = 4 * 1024 * 1024;
size_t p;
int errct = 0;
int initial_err = -1;
for (p = 0; p < (s / sizeof(int)); p += 8)
{
spiram[p] = p ^ 0xaaaaaaaa;
}
for (p = 0; p < (s / sizeof(int)); p += 8)
{
if (spiram[p] != (p ^ 0xaaaaaaaa))
{
errct++;
if (errct == 1)
{
initial_err = p * sizeof(int);
}
if (errct < 4)
{
merr("SPI SRAM error@%p:%08x/%08x \n", &spiram[p], spiram[p],
p ^ 0xaaaaaaaa);
}
}
}
if (errct != 0)
{
merr("SPI SRAM memory test fail. %d/%d writes failed, first @ %X\n",
errct, s / 32, initial_err + SOC_EXTRAM_DATA_LOW);
return ERROR;
}
else
{
minfo("SPI SRAM memory test OK!");
return OK;
}
}
int esp_spiram_get_chip_size(void) int esp_spiram_get_chip_size(void)
{ {
int psram_size; int psram_size;
+2 -2
View File
@@ -118,10 +118,10 @@ void esp_spiram_init_cache(void);
* stuff in SPI RAM. * stuff in SPI RAM.
* *
* return: * return:
* true on success, false on failed memory test * OK on success, ERROR on failed memory test
*/ */
bool esp_spiram_test(void); int esp_spiram_test(void);
/* Description Add the initialized SPI RAM to the heap allocator. */ /* Description Add the initialized SPI RAM to the heap allocator. */
+5
View File
@@ -257,6 +257,11 @@ static noreturn_function void __esp32_start(void)
else else
{ {
esp_spiram_init_cache(); esp_spiram_init_cache();
if (esp_spiram_test() != OK)
{
ets_printf("SPIRAM test failed\n");
PANIC();
}
} }
/* Set external memory bss section to zero */ /* Set external memory bss section to zero */
+9 -4
View File
@@ -387,7 +387,7 @@ int IRAM_ATTR cache_dbus_mmu_map(int vaddr, int paddr, int num)
* map the virtual address range. * map the virtual address range.
*/ */
void IRAM_ATTR esp_spiram_init_cache(void) int IRAM_ATTR esp_spiram_init_cache(void)
{ {
uint32_t regval; uint32_t regval;
uint32_t psram_size; uint32_t psram_size;
@@ -417,6 +417,7 @@ void IRAM_ATTR esp_spiram_init_cache(void)
mwarn("Invalid target vaddr = 0x%x, change vaddr to: 0x%x\n", mwarn("Invalid target vaddr = 0x%x, change vaddr to: 0x%x\n",
target_mapped_vaddr_start, g_mapped_vaddr_start); target_mapped_vaddr_start, g_mapped_vaddr_start);
target_mapped_vaddr_start = g_mapped_vaddr_start; target_mapped_vaddr_start = g_mapped_vaddr_start;
ret = ERROR;
} }
if (target_mapped_vaddr_end > if (target_mapped_vaddr_end >
@@ -426,6 +427,7 @@ void IRAM_ATTR esp_spiram_init_cache(void)
SPIRAM_VADDR_MAP_SIZE, SPIRAM_VADDR_MAP_SIZE,
g_mapped_vaddr_start + mapped_vaddr_size); g_mapped_vaddr_start + mapped_vaddr_size);
target_mapped_vaddr_end = g_mapped_vaddr_start + mapped_vaddr_size; target_mapped_vaddr_end = g_mapped_vaddr_start + mapped_vaddr_size;
ret = ERROR;
} }
ASSERT(target_mapped_vaddr_end > target_mapped_vaddr_start); ASSERT(target_mapped_vaddr_end > target_mapped_vaddr_start);
@@ -442,6 +444,7 @@ void IRAM_ATTR esp_spiram_init_cache(void)
g_mapped_size = mapped_vaddr_size; g_mapped_size = mapped_vaddr_size;
mwarn("Virtual address not enough for PSRAM, only %d size is mapped!", mwarn("Virtual address not enough for PSRAM, only %d size is mapped!",
g_mapped_size); g_mapped_size);
ret = ERROR;
} }
else else
{ {
@@ -475,6 +478,8 @@ void IRAM_ATTR esp_spiram_init_cache(void)
g_allocable_vaddr_start = g_mapped_vaddr_start; g_allocable_vaddr_start = g_mapped_vaddr_start;
g_allocable_vaddr_end = g_mapped_vaddr_start + g_mapped_size; g_allocable_vaddr_end = g_mapped_vaddr_start + g_mapped_size;
return ret;
} }
/* Simple RAM test. Writes a word every 32 bytes. Takes about a second /* Simple RAM test. Writes a word every 32 bytes. Takes about a second
@@ -484,7 +489,7 @@ void IRAM_ATTR esp_spiram_init_cache(void)
* of the memory. * of the memory.
*/ */
bool esp_spiram_test(void) int esp_spiram_test(void)
{ {
volatile int *spiram = (volatile int *)g_mapped_vaddr_start; volatile int *spiram = (volatile int *)g_mapped_vaddr_start;
@@ -520,12 +525,12 @@ bool esp_spiram_test(void)
{ {
merr("SPI SRAM memory test fail. %d/%d writes failed, first @ %X\n", merr("SPI SRAM memory test fail. %d/%d writes failed, first @ %X\n",
errct, s / 32, initial_err + SOC_EXTRAM_DATA_LOW); errct, s / 32, initial_err + SOC_EXTRAM_DATA_LOW);
return false; return ERROR;
} }
else else
{ {
minfo("SPI SRAM memory test OK!"); minfo("SPI SRAM memory test OK!");
return true; return OK;
} }
} }
+2 -2
View File
@@ -70,7 +70,7 @@ int esp_spiram_init(void);
* Attention this function must be called with flash cache disabled. * Attention this function must be called with flash cache disabled.
*/ */
void esp_spiram_init_cache(void); int esp_spiram_init_cache(void);
/* Memory test for SPI RAM. Should be called after SPI RAM is /* Memory test for SPI RAM. Should be called after SPI RAM is
* initialized and (in case of a dual-core system) the app CPU is online. * initialized and (in case of a dual-core system) the app CPU is online.
@@ -80,7 +80,7 @@ void esp_spiram_init_cache(void);
* Return true on success, false on failed memory test * Return true on success, false on failed memory test
*/ */
bool esp_spiram_test(void); int esp_spiram_test(void);
/* Add the initialized SPI RAM to the heap allocator. */ /* Add the initialized SPI RAM to the heap allocator. */
+11 -2
View File
@@ -401,8 +401,17 @@ noinstrument_function void noreturn_function IRAM_ATTR __esp32s3_start(void)
} }
else else
{ {
esp_spiram_init_cache(); if (esp_spiram_init_cache() != OK)
esp_spiram_test(); {
ets_printf("SPIRAM init cache failed\n");
PANIC();
}
if (esp_spiram_test() != OK)
{
ets_printf("SPIRAM test failed\n");
PANIC();
}
} }
#endif #endif