From ce6c86672bd89fc61b10b9d635591140b844d368 Mon Sep 17 00:00:00 2001 From: Li Shuai Date: Wed, 17 Jul 2019 10:05:18 +0800 Subject: [PATCH 1/2] cache_err_int: Add cache error interrupt panic --- components/esp32s2beta/cache_err_int.c | 19 +++-- components/esp32s2beta/cpu_start.c | 2 +- components/esp32s2beta/panic.c | 102 ++++++++++++++++++++++++- 3 files changed, 111 insertions(+), 12 deletions(-) diff --git a/components/esp32s2beta/cache_err_int.c b/components/esp32s2beta/cache_err_int.c index 2b263cc275..914be97b85 100644 --- a/components/esp32s2beta/cache_err_int.c +++ b/components/esp32s2beta/cache_err_int.c @@ -52,15 +52,18 @@ void esp_cache_err_int_init(void) // interrupt is connected to PRO CPU and invalid access happens on the APP // 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_CACHE_IA_INT_PRO_DRAM1 | - DPORT_CACHE_IA_INT_PRO_DROM0 | - DPORT_CACHE_IA_INT_PRO_IROM0 | - DPORT_CACHE_IA_INT_PRO_IRAM0 | - DPORT_CACHE_IA_INT_PRO_IRAM1); -#endif + DPORT_MMU_ENTRY_FAULT_INT_ENA | + DPORT_DCACHE_REJECT_INT_ENA | + DPORT_DCACHE_WRITE_FLASH_INT_ENA | + DPORT_DC_PRELOAD_SIZE_FAULT_INT_ENA | + DPORT_DC_SYNC_SIZE_FAULT_INT_ENA | + 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); } diff --git a/components/esp32s2beta/cpu_start.c b/components/esp32s2beta/cpu_start.c index 7fdb0f47fe..63379a21bc 100644 --- a/components/esp32s2beta/cpu_start.c +++ b/components/esp32s2beta/cpu_start.c @@ -315,7 +315,7 @@ void start_cpu0_default(void) //Initialize the interrupt watch dog for CPU0. //esp_int_wdt_cpu_init(); #endif - //esp_cache_err_int_init(); + esp_cache_err_int_init(); esp_crosscore_int_init(); spi_flash_init(); /* init default OS-aware flash access critical section */ diff --git a/components/esp32s2beta/panic.c b/components/esp32s2beta/panic.c index b98cc05822..f536731e02 100644 --- a/components/esp32s2beta/panic.c +++ b/components/esp32s2beta/panic.c @@ -190,6 +190,96 @@ static void setFirstBreakpoint(uint32_t pc) ::"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. //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. @@ -209,7 +299,7 @@ void panicHandler(XtExcFrame *frame) "Coprocessor exception", "Interrupt wdt timeout on CPU0", "Interrupt wdt timeout on CPU1", - "Cache disabled but cached memory region accessed", + "Cache exception", }; const char *reason = reasons[0]; //The panic reason is stored in the EXCCAUSE register. @@ -242,7 +332,6 @@ void panicHandler(XtExcFrame *frame) panicPutStr(" panic'ed ("); panicPutStr(reason); panicPutStr(")\r\n"); -#ifdef PANIC_COMPLETE_IN_ESP32C if (frame->exccause == PANIC_RSN_DEBUGEXCEPTION) { int debugRsn; asm("rsr.debugcause %0":"=r"(debugRsn)); @@ -281,6 +370,10 @@ void panicHandler(XtExcFrame *frame) } panicPutStr("\r\n"); } + else if (frame->exccause == PANIC_RSN_CACHEERR) { + panicPutStr(" ^~~~~~~~~~~~~~~\r\n"); + printCacheError(); + } if (esp_cpu_in_ocd_debug_mode()) { disableAllWdts(); @@ -299,7 +392,6 @@ void panicHandler(XtExcFrame *frame) setFirstBreakpoint(frame->pc); return; } -#endif commonErrorHandler(frame); } @@ -405,6 +497,8 @@ void esp_panic_wdt_stop(void) 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) @@ -421,6 +515,8 @@ static void esp_panic_dig_reset(void) } } +#endif + static void putEntry(uint32_t pc, uint32_t sp) { if (pc & 0x80000000) { From eb4c0ef8b2af145ba2aae454911f7d9bd4a55dfb Mon Sep 17 00:00:00 2001 From: Li Shuai Date: Wed, 31 Jul 2019 13:49:21 +0800 Subject: [PATCH 2/2] cache_err_int: Modify cache error interrupt panic code format --- components/esp32s2beta/panic.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/components/esp32s2beta/panic.c b/components/esp32s2beta/panic.c index f536731e02..f68c379410 100644 --- a/components/esp32s2beta/panic.c +++ b/components/esp32s2beta/panic.c @@ -197,7 +197,7 @@ static inline void printCacheError(void) 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))) + switch (status[0] & BIT(i)) { case DPORT_IC_SYNC_SIZE_FAULT_ST: vaddr = REG_READ(DPORT_PRO_ICACHE_MEM_SYNC0_REG); @@ -230,7 +230,7 @@ static inline void printCacheError(void) default: break; } - switch (status[1] & (1 << (i&0x1f))) + switch (status[1] & BIT(i)) { case DPORT_DC_SYNC_SIZE_FAULT_ST: vaddr = REG_READ(DPORT_PRO_DCACHE_MEM_SYNC0_REG); @@ -369,8 +369,7 @@ void panicHandler(XtExcFrame *frame) panicPutStr("DebugIntr "); } panicPutStr("\r\n"); - } - else if (frame->exccause == PANIC_RSN_CACHEERR) { + } else if (frame->exccause == PANIC_RSN_CACHEERR) { panicPutStr(" ^~~~~~~~~~~~~~~\r\n"); printCacheError(); }