cache_err_int: Add cache error interrupt panic
This commit is contained in:
parent
35147119f1
commit
ce6c86672b
|
@ -52,15 +52,18 @@ void esp_cache_err_int_init(void)
|
||||||
// interrupt is connected to PRO CPU and invalid access happens on the APP
|
// interrupt is connected to PRO CPU and invalid access happens on the APP
|
||||||
// CPU.
|
// CPU.
|
||||||
|
|
||||||
// TODO: implement cache error access interrupt for esp32s2beta - IDF-752
|
|
||||||
#if 0
|
|
||||||
DPORT_SET_PERI_REG_MASK(DPORT_PRO_CACHE_IA_INT_EN_REG,
|
DPORT_SET_PERI_REG_MASK(DPORT_PRO_CACHE_IA_INT_EN_REG,
|
||||||
DPORT_CACHE_IA_INT_PRO_DRAM1 |
|
DPORT_MMU_ENTRY_FAULT_INT_ENA |
|
||||||
DPORT_CACHE_IA_INT_PRO_DROM0 |
|
DPORT_DCACHE_REJECT_INT_ENA |
|
||||||
DPORT_CACHE_IA_INT_PRO_IROM0 |
|
DPORT_DCACHE_WRITE_FLASH_INT_ENA |
|
||||||
DPORT_CACHE_IA_INT_PRO_IRAM0 |
|
DPORT_DC_PRELOAD_SIZE_FAULT_INT_ENA |
|
||||||
DPORT_CACHE_IA_INT_PRO_IRAM1);
|
DPORT_DC_SYNC_SIZE_FAULT_INT_ENA |
|
||||||
#endif
|
DPORT_ICACHE_REJECT_INT_ENA |
|
||||||
|
DPORT_IC_PRELOAD_SIZE_FAULT_INT_ENA |
|
||||||
|
DPORT_IC_SYNC_SIZE_FAULT_INT_ENA |
|
||||||
|
DPORT_CACHE_DBG_INT_CLR |
|
||||||
|
DPORT_CACHE_DBG_EN);
|
||||||
|
|
||||||
ESP_INTR_ENABLE(ETS_CACHEERR_INUM);
|
ESP_INTR_ENABLE(ETS_CACHEERR_INUM);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -315,7 +315,7 @@ void start_cpu0_default(void)
|
||||||
//Initialize the interrupt watch dog for CPU0.
|
//Initialize the interrupt watch dog for CPU0.
|
||||||
//esp_int_wdt_cpu_init();
|
//esp_int_wdt_cpu_init();
|
||||||
#endif
|
#endif
|
||||||
//esp_cache_err_int_init();
|
esp_cache_err_int_init();
|
||||||
esp_crosscore_int_init();
|
esp_crosscore_int_init();
|
||||||
spi_flash_init();
|
spi_flash_init();
|
||||||
/* init default OS-aware flash access critical section */
|
/* init default OS-aware flash access critical section */
|
||||||
|
|
|
@ -190,6 +190,96 @@ static void setFirstBreakpoint(uint32_t pc)
|
||||||
::"r"(pc):"a3", "a4");
|
::"r"(pc):"a3", "a4");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void printCacheError(void)
|
||||||
|
{
|
||||||
|
uint32_t vaddr = 0, size = 0;
|
||||||
|
uint32_t status[2];
|
||||||
|
status[0] = REG_READ(DPORT_CACHE_DBG_STATUS0_REG);
|
||||||
|
status[1] = REG_READ(DPORT_CACHE_DBG_STATUS1_REG);
|
||||||
|
for (int i = 0; i < 32; i++) {
|
||||||
|
switch (status[0] & (1 << (i&0x1f)))
|
||||||
|
{
|
||||||
|
case DPORT_IC_SYNC_SIZE_FAULT_ST:
|
||||||
|
vaddr = REG_READ(DPORT_PRO_ICACHE_MEM_SYNC0_REG);
|
||||||
|
size = REG_READ(DPORT_PRO_ICACHE_MEM_SYNC1_REG);
|
||||||
|
panicPutStr("Icache sync parameter configuration error, the error address and size is 0x");
|
||||||
|
panicPutHex(vaddr);
|
||||||
|
panicPutStr("(0x");
|
||||||
|
panicPutHex(size);
|
||||||
|
panicPutStr(")\r\n");
|
||||||
|
break;
|
||||||
|
case DPORT_IC_PRELOAD_SIZE_FAULT_ST:
|
||||||
|
vaddr = REG_READ(DPORT_PRO_ICACHE_PRELOAD_ADDR_REG);
|
||||||
|
size = REG_READ(DPORT_PRO_ICACHE_PRELOAD_SIZE_REG);
|
||||||
|
panicPutStr("Icache preload parameter configuration error, the error address and size is 0x");
|
||||||
|
panicPutHex(vaddr);
|
||||||
|
panicPutStr("(0x");
|
||||||
|
panicPutHex(size);
|
||||||
|
panicPutStr(")\r\n");
|
||||||
|
break;
|
||||||
|
case DPORT_ICACHE_REJECT_ST:
|
||||||
|
vaddr = REG_READ(DPORT_PRO_ICACHE_REJECT_VADDR_REG);
|
||||||
|
panicPutStr("Icache reject error occurred while accessing the address 0x");
|
||||||
|
panicPutHex(vaddr);
|
||||||
|
|
||||||
|
if (REG_READ(DPORT_PRO_CACHE_MMU_ERROR_CONTENT_REG) & DPORT_MMU_INVALID) {
|
||||||
|
panicPutStr(" (invalid mmu entry)");
|
||||||
|
}
|
||||||
|
panicPutStr("\r\n");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
switch (status[1] & (1 << (i&0x1f)))
|
||||||
|
{
|
||||||
|
case DPORT_DC_SYNC_SIZE_FAULT_ST:
|
||||||
|
vaddr = REG_READ(DPORT_PRO_DCACHE_MEM_SYNC0_REG);
|
||||||
|
size = REG_READ(DPORT_PRO_DCACHE_MEM_SYNC1_REG);
|
||||||
|
panicPutStr("Dcache sync parameter configuration error, the error address and size is 0x");
|
||||||
|
panicPutHex(vaddr);
|
||||||
|
panicPutStr("(0x");
|
||||||
|
panicPutHex(size);
|
||||||
|
panicPutStr(")\r\n");
|
||||||
|
break;
|
||||||
|
case DPORT_DC_PRELOAD_SIZE_FAULT_ST:
|
||||||
|
vaddr = REG_READ(DPORT_PRO_DCACHE_PRELOAD_ADDR_REG);
|
||||||
|
size = REG_READ(DPORT_PRO_DCACHE_PRELOAD_SIZE_REG);
|
||||||
|
panicPutStr("Dcache preload parameter configuration error, the error address and size is 0x");
|
||||||
|
panicPutHex(vaddr);
|
||||||
|
panicPutStr("(0x");
|
||||||
|
panicPutHex(size);
|
||||||
|
panicPutStr(")\r\n");
|
||||||
|
break;
|
||||||
|
case DPORT_DCACHE_WRITE_FLASH_ST:
|
||||||
|
panicPutStr("Write back error occurred while dcache tries to write back to flash\r\n");
|
||||||
|
break;
|
||||||
|
case DPORT_DCACHE_REJECT_ST:
|
||||||
|
vaddr = REG_READ(DPORT_PRO_DCACHE_REJECT_VADDR_REG);
|
||||||
|
panicPutStr("Dcache reject error occurred while accessing the address 0x");
|
||||||
|
panicPutHex(vaddr);
|
||||||
|
|
||||||
|
if (REG_READ(DPORT_PRO_CACHE_MMU_ERROR_CONTENT_REG) & DPORT_MMU_INVALID) {
|
||||||
|
panicPutStr(" (invalid mmu entry)");
|
||||||
|
}
|
||||||
|
panicPutStr("\r\n");
|
||||||
|
break;
|
||||||
|
case DPORT_MMU_ENTRY_FAULT_ST:
|
||||||
|
vaddr = REG_READ(DPORT_PRO_CACHE_MMU_ERROR_VADDR_REG);
|
||||||
|
panicPutStr("MMU entry fault error occurred while accessing the address 0x");
|
||||||
|
panicPutHex(vaddr);
|
||||||
|
|
||||||
|
if (REG_READ(DPORT_PRO_CACHE_MMU_ERROR_CONTENT_REG) & DPORT_MMU_INVALID) {
|
||||||
|
panicPutStr(" (invalid mmu entry)");
|
||||||
|
}
|
||||||
|
panicPutStr("\r\n");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
panicPutStr("\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
//When interrupt watchdog happen in one core, both cores will be interrupted.
|
//When interrupt watchdog happen in one core, both cores will be interrupted.
|
||||||
//The core which doesn't trigger the interrupt watchdog will save the frame and return.
|
//The core which doesn't trigger the interrupt watchdog will save the frame and return.
|
||||||
//The core which triggers the interrupt watchdog will use the saved frame, and dump frames for both cores.
|
//The core which triggers the interrupt watchdog will use the saved frame, and dump frames for both cores.
|
||||||
|
@ -209,7 +299,7 @@ void panicHandler(XtExcFrame *frame)
|
||||||
"Coprocessor exception",
|
"Coprocessor exception",
|
||||||
"Interrupt wdt timeout on CPU0",
|
"Interrupt wdt timeout on CPU0",
|
||||||
"Interrupt wdt timeout on CPU1",
|
"Interrupt wdt timeout on CPU1",
|
||||||
"Cache disabled but cached memory region accessed",
|
"Cache exception",
|
||||||
};
|
};
|
||||||
const char *reason = reasons[0];
|
const char *reason = reasons[0];
|
||||||
//The panic reason is stored in the EXCCAUSE register.
|
//The panic reason is stored in the EXCCAUSE register.
|
||||||
|
@ -242,7 +332,6 @@ void panicHandler(XtExcFrame *frame)
|
||||||
panicPutStr(" panic'ed (");
|
panicPutStr(" panic'ed (");
|
||||||
panicPutStr(reason);
|
panicPutStr(reason);
|
||||||
panicPutStr(")\r\n");
|
panicPutStr(")\r\n");
|
||||||
#ifdef PANIC_COMPLETE_IN_ESP32C
|
|
||||||
if (frame->exccause == PANIC_RSN_DEBUGEXCEPTION) {
|
if (frame->exccause == PANIC_RSN_DEBUGEXCEPTION) {
|
||||||
int debugRsn;
|
int debugRsn;
|
||||||
asm("rsr.debugcause %0":"=r"(debugRsn));
|
asm("rsr.debugcause %0":"=r"(debugRsn));
|
||||||
|
@ -281,6 +370,10 @@ void panicHandler(XtExcFrame *frame)
|
||||||
}
|
}
|
||||||
panicPutStr("\r\n");
|
panicPutStr("\r\n");
|
||||||
}
|
}
|
||||||
|
else if (frame->exccause == PANIC_RSN_CACHEERR) {
|
||||||
|
panicPutStr(" ^~~~~~~~~~~~~~~\r\n");
|
||||||
|
printCacheError();
|
||||||
|
}
|
||||||
|
|
||||||
if (esp_cpu_in_ocd_debug_mode()) {
|
if (esp_cpu_in_ocd_debug_mode()) {
|
||||||
disableAllWdts();
|
disableAllWdts();
|
||||||
|
@ -299,7 +392,6 @@ void panicHandler(XtExcFrame *frame)
|
||||||
setFirstBreakpoint(frame->pc);
|
setFirstBreakpoint(frame->pc);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
commonErrorHandler(frame);
|
commonErrorHandler(frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -405,6 +497,8 @@ void esp_panic_wdt_stop(void)
|
||||||
WRITE_PERI_REG(RTC_CNTL_WDTWPROTECT_REG, 0);
|
WRITE_PERI_REG(RTC_CNTL_WDTWPROTECT_REG, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if CONFIG_ESP32S2_PANIC_PRINT_REBOOT || CONFIG_ESP32S2_PANIC_SILENT_REBOOT
|
||||||
|
|
||||||
static void esp_panic_dig_reset(void) __attribute__((noreturn));
|
static void esp_panic_dig_reset(void) __attribute__((noreturn));
|
||||||
|
|
||||||
static void esp_panic_dig_reset(void)
|
static void esp_panic_dig_reset(void)
|
||||||
|
@ -421,6 +515,8 @@ static void esp_panic_dig_reset(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
static void putEntry(uint32_t pc, uint32_t sp)
|
static void putEntry(uint32_t pc, uint32_t sp)
|
||||||
{
|
{
|
||||||
if (pc & 0x80000000) {
|
if (pc & 0x80000000) {
|
||||||
|
|
Loading…
Reference in a new issue