fix(system): esp32p4: fix mepc when load/store failure occurred
This commit is contained in:
@@ -155,6 +155,20 @@ extern "C" {
|
||||
#define TDATA1_HIT_S (20)
|
||||
|
||||
|
||||
/********************************************************
|
||||
Espressif's bus error exceptions registers and fields
|
||||
********************************************************/
|
||||
|
||||
#define MEXSTATUS 0x7E1
|
||||
#define MHINT 0x7C5
|
||||
|
||||
#define LDPC0 0xBE0
|
||||
#define LDPC1 0xBE1
|
||||
|
||||
#define STPC0 0xBF0
|
||||
#define STPC1 0xBF1
|
||||
#define STPC2 0xBF2
|
||||
|
||||
/* RISC-V CSR macros
|
||||
* Adapted from https://github.com/michaeljclark/riscv-probe/blob/master/libfemto/include/arch/riscv/machine.h
|
||||
*/
|
||||
|
||||
@@ -138,12 +138,12 @@ FORCE_INLINE_ATTR void rv_utils_intr_global_disable(void)
|
||||
* and `interrupt_intc.h`.
|
||||
*/
|
||||
|
||||
#if SOC_CPU_HAS_FPU
|
||||
|
||||
/* ------------------------------------------------- FPU Related ----------------------------------------------------
|
||||
*
|
||||
* ------------------------------------------------------------------------------------------------------------------ */
|
||||
|
||||
#if SOC_CPU_HAS_FPU
|
||||
|
||||
FORCE_INLINE_ATTR bool rv_utils_enable_fpu(void)
|
||||
{
|
||||
/* Set mstatus[14:13] to 0b01 to start the floating-point unit initialization */
|
||||
@@ -172,6 +172,48 @@ FORCE_INLINE_ATTR void rv_utils_disable_fpu(void)
|
||||
*
|
||||
* ------------------------------------------------------------------------------------------------------------------ */
|
||||
|
||||
#if SOC_ASYNCHRONOUS_BUS_ERROR_MODE
|
||||
|
||||
FORCE_INLINE_ATTR uintptr_t rv_utils_asynchronous_bus_get_error_pc(void)
|
||||
{
|
||||
uint32_t error_pc;
|
||||
uint32_t mcause, mexstatus;
|
||||
|
||||
mexstatus = RV_READ_CSR(MEXSTATUS);
|
||||
/* MEXSTATUS: Bit 8: Indicates that a load/store access fault (MCAUSE=5/7)
|
||||
* is due to bus-error exception. If this bit is not cleared before exiting
|
||||
* the exception handler, it will trigger a bus error again.
|
||||
* Since we have not mechanisms to recover a normal program execution after
|
||||
* load/store error appears, do nothing. */
|
||||
if ((mexstatus & BIT(8)) == 0) {
|
||||
return 0;
|
||||
}
|
||||
mcause = RV_READ_CSR(mcause) & 0xFF;
|
||||
if (mcause == 5) { /* Load access fault */
|
||||
/* Get the oldest PC at which the load instruction failed */
|
||||
error_pc = RV_READ_CSR(LDPC1);
|
||||
if (error_pc == 0) {
|
||||
error_pc = RV_READ_CSR(LDPC0);
|
||||
}
|
||||
} else if (mcause == 7) { /* Store access fault */
|
||||
/* Get the oldest PC at which the store instruction failed */
|
||||
error_pc = RV_READ_CSR(STPC2);
|
||||
if (error_pc == 0) {
|
||||
error_pc = RV_READ_CSR(STPC1);
|
||||
if (error_pc == 0) {
|
||||
error_pc = RV_READ_CSR(STPC0);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
/* Bit 0: Valid bit indicating that this CSR holds the PC (program counter).
|
||||
* Clear this bit */
|
||||
return error_pc & ~(1);
|
||||
}
|
||||
|
||||
#endif // SOC_ASYNCHRONOUS_BUS_ERROR_MODE
|
||||
|
||||
/* ---------------------------------------------------- Debugging ------------------------------------------------------
|
||||
*
|
||||
* ------------------------------------------------------------------------------------------------------------------ */
|
||||
|
||||
Reference in New Issue
Block a user