add better fault identification for Cortex-M3/M33/M4/M7 hardfault handlers, add fault description registers to SCB_Type

This commit is contained in:
ardnew
2020-11-05 18:04:40 -06:00
committed by Ron Evans
parent b1d24a72c1
commit 30bee3afef
4 changed files with 463 additions and 70 deletions
+1 -1
View File
@@ -1,4 +1,4 @@
// +build cortexm,!nxp
// +build atsamd21 nrf51
package runtime
+31 -34
View File
@@ -1,22 +1,19 @@
// +build nxp
// +build cortexm,!atsamd21,!nrf51
package runtime
import (
"device/nxp"
"device/arm"
"unsafe"
)
const (
SystemControl_CFSR_KnownFault = nxp.HardFault_CFSR_IACCVIOL |
nxp.HardFault_CFSR_DACCVIOL | nxp.HardFault_CFSR_MUNSTKERR |
nxp.HardFault_CFSR_MSTKERR | nxp.HardFault_CFSR_MLSPERR |
nxp.HardFault_CFSR_IBUSERR | nxp.HardFault_CFSR_PRECISERR |
nxp.HardFault_CFSR_IMPRECISERR | nxp.HardFault_CFSR_UNSTKERR |
nxp.HardFault_CFSR_STKERR | nxp.HardFault_CFSR_LSPERR |
nxp.HardFault_CFSR_UNDEFINSTR | nxp.HardFault_CFSR_INVSTATE |
nxp.HardFault_CFSR_INVPC | nxp.HardFault_CFSR_NOCP |
nxp.HardFault_CFSR_UNALIGNED | nxp.HardFault_CFSR_DIVBYZERO
SCB_CFSR_KnownFault = arm.SCB_CFSR_IACCVIOL | arm.SCB_CFSR_DACCVIOL |
arm.SCB_CFSR_MUNSTKERR | arm.SCB_CFSR_MSTKERR | arm.SCB_CFSR_MLSPERR |
arm.SCB_CFSR_IBUSERR | arm.SCB_CFSR_PRECISERR | arm.SCB_CFSR_IMPRECISERR |
arm.SCB_CFSR_UNSTKERR | arm.SCB_CFSR_STKERR | arm.SCB_CFSR_LSPERR |
arm.SCB_CFSR_UNDEFINSTR | arm.SCB_CFSR_INVSTATE | arm.SCB_CFSR_INVPC |
arm.SCB_CFSR_NOCP | arm.SCB_CFSR_UNALIGNED | arm.SCB_CFSR_DIVBYZERO
)
// See runtime_cortexm_hardfault.go
@@ -113,7 +110,7 @@ func handleHardFault(sp *interruptStack) {
// GetFaultStatus reads the System Control Block Configurable Fault Status
// Register and returns it as a FaultStatus.
func GetFaultStatus() FaultStatus {
return FaultStatus(nxp.SystemControl.CFSR.Get())
return FaultStatus(arm.SCB.CFSR.Get())
}
type FaultStatus uint32
@@ -127,7 +124,7 @@ func (fs FaultStatus) Usage() UsageFaultStatus { return UsageFaultStatus(fs) }
// Unknown returns true if the cause of the fault is not know
func (fs FaultStatus) Unknown() bool {
return fs&SystemControl_CFSR_KnownFault == 0
return fs&SCB_CFSR_KnownFault == 0
}
// InstructionAccessViolation: the processor attempted an instruction fetch from
@@ -140,7 +137,7 @@ func (fs FaultStatus) Unknown() bool {
// the faulting instruction. The processor has not written a fault address to
// the MMAR."
func (fs MemFaultStatus) InstructionAccessViolation() bool {
return fs&nxp.HardFault_CFSR_IACCVIOL != 0
return fs&arm.SCB_CFSR_IACCVIOL != 0
}
// DataAccessViolation: the processor attempted a load or store at a location
@@ -150,7 +147,7 @@ func (fs MemFaultStatus) InstructionAccessViolation() bool {
// the faulting instruction. The processor has loaded the MMAR with the address
// of the attempted access."
func (fs MemFaultStatus) DataAccessViolation() bool {
return fs&nxp.HardFault_CFSR_DACCVIOL != 0
return fs&arm.SCB_CFSR_DACCVIOL != 0
}
// WhileUnstackingException: unstack for an exception return has caused one or
@@ -161,7 +158,7 @@ func (fs MemFaultStatus) DataAccessViolation() bool {
// the SP from the failing return, and has not performed a new save. The
// processor has not written a fault address to the MMAR."
func (fs MemFaultStatus) WhileUnstackingException() bool {
return fs&nxp.HardFault_CFSR_MUNSTKERR != 0
return fs&arm.SCB_CFSR_MUNSTKERR != 0
}
// WileStackingException: stacking for an exception entry has caused one or more
@@ -171,13 +168,13 @@ func (fs MemFaultStatus) WhileUnstackingException() bool {
// area on the stack might be incorrect. The processor has not written a fault
// address to the MMAR."
func (fs MemFaultStatus) WileStackingException() bool {
return fs&nxp.HardFault_CFSR_MSTKERR != 0
return fs&arm.SCB_CFSR_MSTKERR != 0
}
// DuringFPLazyStatePres: A MemManage fault occurred during floating-point lazy
// state preservation
func (fs MemFaultStatus) DuringFPLazyStatePres() bool {
return fs&nxp.HardFault_CFSR_MLSPERR != 0
return fs&arm.SCB_CFSR_MLSPERR != 0
}
// InstructionBusError: instruction bus error
@@ -189,13 +186,13 @@ func (fs MemFaultStatus) DuringFPLazyStatePres() bool {
// When the processor sets this bit is 1, it does not write a fault address to
// the BFAR."
func (fs BusFaultStatus) InstructionBusError() bool {
return fs&nxp.HardFault_CFSR_IBUSERR != 0
return fs&arm.SCB_CFSR_IBUSERR != 0
}
// PreciseDataBusError: a data bus error has occurred, and the PC value stacked
// for the exception return points to the instruction that caused the fault
func (fs BusFaultStatus) PreciseDataBusError() bool {
return fs&nxp.HardFault_CFSR_PRECISERR != 0
return fs&arm.SCB_CFSR_PRECISERR != 0
}
// ImpreciseDataBusError: a data bus error has occurred, but the return address
@@ -211,7 +208,7 @@ func (fs BusFaultStatus) PreciseDataBusError() bool {
// enters the handler for the imprecise BusFault, the handler detects both
// IMPRECISERR set to 1 and one of the precise fault status bits set to 1."
func (fs BusFaultStatus) ImpreciseDataBusError() bool {
return fs&nxp.HardFault_CFSR_IMPRECISERR != 0
return fs&arm.SCB_CFSR_IMPRECISERR != 0
}
// WhileUnstackingException: unstack for an exception return has caused one or
@@ -222,7 +219,7 @@ func (fs BusFaultStatus) ImpreciseDataBusError() bool {
// does not adjust the SP from the failing return, does not performed a new
// save, and does not write a fault address to the BFAR."
func (fs BusFaultStatus) WhileUnstackingException() bool {
return fs&nxp.HardFault_CFSR_UNSTKERR != 0
return fs&arm.SCB_CFSR_UNSTKERR != 0
}
// WhileStackingException: stacking for an exception entry has caused one or
@@ -232,13 +229,13 @@ func (fs BusFaultStatus) WhileUnstackingException() bool {
// values in the context area on the stack might be incorrect. The processor
// does not write a fault address to the BFAR."
func (fs BusFaultStatus) WhileStackingException() bool {
return fs&nxp.HardFault_CFSR_STKERR != 0
return fs&arm.SCB_CFSR_STKERR != 0
}
// DuringFPLazyStatePres: A bus fault occurred during floating-point lazy state
// preservation
func (fs BusFaultStatus) DuringFPLazyStatePres() bool {
return fs&nxp.HardFault_CFSR_LSPERR != 0
return fs&arm.SCB_CFSR_LSPERR != 0
}
// UndefinedInstruction: the processor has attempted to execute an undefined
@@ -249,7 +246,7 @@ func (fs BusFaultStatus) DuringFPLazyStatePres() bool {
//
// An undefined instruction is an instruction that the processor cannot decode."
func (fs UsageFaultStatus) UndefinedInstruction() bool {
return fs&nxp.HardFault_CFSR_UNDEFINSTR != 0
return fs&arm.SCB_CFSR_UNDEFINSTR != 0
}
// IllegalUseOfEPSR: the processor has attempted to execute an instruction that
@@ -260,7 +257,7 @@ func (fs UsageFaultStatus) UndefinedInstruction() bool {
//
// This bit is not set to 1 if an undefined instruction uses the EPSR."
func (fs UsageFaultStatus) IllegalUseOfEPSR() bool {
return fs&nxp.HardFault_CFSR_INVSTATE != 0
return fs&arm.SCB_CFSR_INVSTATE != 0
}
// IllegalExceptionReturn: the processor has attempted an illegal load of
@@ -269,13 +266,13 @@ func (fs UsageFaultStatus) IllegalUseOfEPSR() bool {
// "When this bit is set to 1, the PC value stacked for the exception return
// points to the instruction that tried to perform the illegal load of the PC."
func (fs UsageFaultStatus) IllegalExceptionReturn() bool {
return fs&nxp.HardFault_CFSR_INVPC != 0
return fs&arm.SCB_CFSR_INVPC != 0
}
// AttemptedToAccessCoprocessor: the processor has attempted to access a
// coprocessor
func (fs UsageFaultStatus) AttemptedToAccessCoprocessor() bool {
return fs&nxp.HardFault_CFSR_NOCP != 0
return fs&arm.SCB_CFSR_NOCP != 0
}
// UnalignedMemoryAccess: the processor has made an unaligned memory access
@@ -286,7 +283,7 @@ func (fs UsageFaultStatus) AttemptedToAccessCoprocessor() bool {
// Unaligned LDM, STM, LDRD, and STRD instructions always fault irrespective of
// the setting of UNALIGN_TRP."
func (fs UsageFaultStatus) UnalignedMemoryAccess() bool {
return fs&nxp.HardFault_CFSR_UNALIGNED != 0
return fs&arm.SCB_CFSR_UNALIGNED != 0
}
// DivideByZero: the processor has executed an SDIV or UDIV instruction with a
@@ -298,7 +295,7 @@ func (fs UsageFaultStatus) UnalignedMemoryAccess() bool {
// Enable trapping of divide by zero by setting the DIV_0_TRP bit in the CCR to
// 1."
func (fs UsageFaultStatus) DivideByZero() bool {
return fs&nxp.HardFault_CFSR_DIVBYZERO != 0
return fs&arm.SCB_CFSR_DIVBYZERO != 0
}
// Address returns the MemManage Fault Address Register if the fault status
@@ -309,10 +306,10 @@ func (fs UsageFaultStatus) DivideByZero() bool {
// problems on return to a stacked active MemManage fault handler whose MMAR
// value has been overwritten."
func (fs MemFaultStatus) Address() (uintptr, bool) {
if fs&nxp.HardFault_CFSR_MMARVALID == 0 {
if fs&arm.SCB_CFSR_MMARVALID == 0 {
return 0, false
} else {
return uintptr(nxp.SystemControl.MMFAR.Get()), true
return uintptr(arm.SCB.MMFAR.Get()), true
}
}
@@ -328,9 +325,9 @@ func (fs MemFaultStatus) Address() (uintptr, bool) {
// returning to a stacked active BusFault handler whose BFAR value has been
// overwritten.""
func (fs BusFaultStatus) Address() (uintptr, bool) {
if fs&nxp.HardFault_CFSR_BFARVALID == 0 {
if fs&arm.SCB_CFSR_BFARVALID == 0 {
return 0, false
} else {
return uintptr(nxp.SystemControl.BFAR.Get()), true
return uintptr(arm.SCB.BFAR.Get()), true
}
}