aboutsummaryrefslogtreecommitdiff
path: root/pw_cpu_exception_armv7m
diff options
context:
space:
mode:
authorArmando Montanez <amontanez@google.com>2020-09-10 12:08:49 -0700
committerCQ Bot Account <commit-bot@chromium.org>2020-09-11 00:38:25 +0000
commit4159d1e3497d81fc49a124a3ab7936f606ae6739 (patch)
tree81f662b4255074350703c1caea2efe57ab3f5710 /pw_cpu_exception_armv7m
parent133eb7dc55505fde3212a61a333cd2e83acfbac6 (diff)
downloadpigweed-4159d1e3497d81fc49a124a3ab7936f606ae6739.tar.gz
pw_cpu_exception_armv7m: Capture HFSR and SHCSR
Captures the HFSR and SHCSR registers in the cpu state block. Change-Id: Ibe50cf88b5c2472b01e1b8221441f5769aac56b6 Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/17884 Reviewed-by: Ewout van Bekkum <ewout@google.com> Commit-Queue: Armando Montanez <amontanez@google.com>
Diffstat (limited to 'pw_cpu_exception_armv7m')
-rw-r--r--pw_cpu_exception_armv7m/cpu_state.cc4
-rw-r--r--pw_cpu_exception_armv7m/entry.cc14
-rw-r--r--pw_cpu_exception_armv7m/exception_entry_test.cc3
-rw-r--r--pw_cpu_exception_armv7m/proto_dump.cc10
-rw-r--r--pw_cpu_exception_armv7m/public/pw_cpu_exception_armv7m/cpu_state.h2
-rw-r--r--pw_cpu_exception_armv7m/pw_cpu_exception_armv7m_protos/cpu_state.proto4
6 files changed, 29 insertions, 8 deletions
diff --git a/pw_cpu_exception_armv7m/cpu_state.cc b/pw_cpu_exception_armv7m/cpu_state.cc
index d54bbe0b8..bec977e7e 100644
--- a/pw_cpu_exception_armv7m/cpu_state.cc
+++ b/pw_cpu_exception_armv7m/cpu_state.cc
@@ -51,6 +51,8 @@ void ToString(const pw_CpuExceptionState& cpu_state,
_PW_FORMAT_REGISTER(extended, mmfar);
_PW_FORMAT_REGISTER(extended, bfar);
_PW_FORMAT_REGISTER(extended, icsr);
+ _PW_FORMAT_REGISTER(extended, hfsr);
+ _PW_FORMAT_REGISTER(extended, shcsr);
_PW_FORMAT_REGISTER(extended, control);
// General purpose registers.
@@ -92,6 +94,8 @@ void LogCpuState(const pw_CpuExceptionState& cpu_state) {
_PW_LOG_REGISTER(extended, mmfar);
_PW_LOG_REGISTER(extended, bfar);
_PW_LOG_REGISTER(extended, icsr);
+ _PW_LOG_REGISTER(extended, hfsr);
+ _PW_LOG_REGISTER(extended, shcsr);
_PW_LOG_REGISTER(extended, control);
// General purpose registers.
diff --git a/pw_cpu_exception_armv7m/entry.cc b/pw_cpu_exception_armv7m/entry.cc
index a247dee59..77d5c4368 100644
--- a/pw_cpu_exception_armv7m/entry.cc
+++ b/pw_cpu_exception_armv7m/entry.cc
@@ -39,14 +39,18 @@ constexpr uint32_t kExcReturnStackMask = (0x1u << 2);
constexpr uint32_t kExcReturnBasicFrameMask = (0x1u << 4);
// Memory mapped registers. (ARMv7-M Section B3.2.2, Table B3-4)
-volatile uint32_t& arm_v7m_icsr =
- *reinterpret_cast<volatile uint32_t*>(0xE000ED04u);
volatile uint32_t& arm_v7m_cfsr =
*reinterpret_cast<volatile uint32_t*>(0xE000ED28u);
volatile uint32_t& arm_v7m_mmfar =
*reinterpret_cast<volatile uint32_t*>(0xE000ED34u);
volatile uint32_t& arm_v7m_bfar =
*reinterpret_cast<volatile uint32_t*>(0xE000ED38u);
+volatile uint32_t& arm_v7m_icsr =
+ *reinterpret_cast<volatile uint32_t*>(0xE000ED04u);
+volatile uint32_t& arm_v7m_hfsr =
+ *reinterpret_cast<volatile uint32_t*>(0xE000ED2Cu);
+volatile uint32_t& arm_v7m_shcsr =
+ *reinterpret_cast<volatile uint32_t*>(0xE000ED24u);
// If the CPU fails to capture some registers, the captured struct members will
// be populated with this value. The only registers that this value should be
@@ -167,9 +171,11 @@ extern "C" {
PW_USED void pw_PackageAndHandleCpuException(pw_CpuExceptionState* cpu_state) {
// Capture memory mapped registers.
cpu_state->extended.cfsr = arm_v7m_cfsr;
- cpu_state->extended.icsr = arm_v7m_icsr;
- cpu_state->extended.bfar = arm_v7m_bfar;
cpu_state->extended.mmfar = arm_v7m_mmfar;
+ cpu_state->extended.bfar = arm_v7m_bfar;
+ cpu_state->extended.icsr = arm_v7m_icsr;
+ cpu_state->extended.hfsr = arm_v7m_hfsr;
+ cpu_state->extended.shcsr = arm_v7m_shcsr;
// CPU may have automatically pushed state to the program stack. If it did,
// the values can be copied into in the pw_CpuExceptionState struct that is
diff --git a/pw_cpu_exception_armv7m/exception_entry_test.cc b/pw_cpu_exception_armv7m/exception_entry_test.cc
index 3000833cd..7cf22268d 100644
--- a/pw_cpu_exception_armv7m/exception_entry_test.cc
+++ b/pw_cpu_exception_armv7m/exception_entry_test.cc
@@ -570,6 +570,7 @@ void TestingExceptionHandler(pw_CpuExceptionState* state) {
// Clear HFSR forced (nested) hard fault mask if set. This will only be
// set by the nested fault test.
+ EXPECT_EQ(state->extended.hfsr, arm_v7m_hfsr);
if (arm_v7m_hfsr & kForcedHardfaultMask) {
arm_v7m_hfsr = kForcedHardfaultMask;
}
@@ -607,6 +608,8 @@ void TestingExceptionHandler(pw_CpuExceptionState* state) {
return;
}
+ EXPECT_EQ(state->extended.shcsr, arm_v7m_shcsr);
+
// If an unexpected exception occurred, just enter an infinite loop.
while (true) {
}
diff --git a/pw_cpu_exception_armv7m/proto_dump.cc b/pw_cpu_exception_armv7m/proto_dump.cc
index e77c6878c..894b2c06b 100644
--- a/pw_cpu_exception_armv7m/proto_dump.cc
+++ b/pw_cpu_exception_armv7m/proto_dump.cc
@@ -23,16 +23,18 @@ Status DumpCpuStateProto(protobuf::Encoder& dest,
armv7m::ArmV7mCpuState::Encoder state_encoder(&dest);
// Special and mem-mapped registers.
- state_encoder.WriteCfsr(cpu_state.extended.cfsr);
state_encoder.WritePc(cpu_state.base.pc);
state_encoder.WriteLr(cpu_state.base.lr);
state_encoder.WritePsr(cpu_state.base.psr);
+ state_encoder.WriteMsp(cpu_state.extended.msp);
+ state_encoder.WritePsp(cpu_state.extended.psp);
+ state_encoder.WriteExcReturn(cpu_state.extended.exc_return);
+ state_encoder.WriteCfsr(cpu_state.extended.cfsr);
state_encoder.WriteMmfar(cpu_state.extended.mmfar);
state_encoder.WriteBfar(cpu_state.extended.bfar);
state_encoder.WriteIcsr(cpu_state.extended.icsr);
- state_encoder.WriteExcReturn(cpu_state.extended.exc_return);
- state_encoder.WriteMsp(cpu_state.extended.msp);
- state_encoder.WritePsp(cpu_state.extended.psp);
+ state_encoder.WriteHfsr(cpu_state.extended.hfsr);
+ state_encoder.WriteShcsr(cpu_state.extended.shcsr);
state_encoder.WriteControl(cpu_state.extended.control);
// General purpose registers.
diff --git a/pw_cpu_exception_armv7m/public/pw_cpu_exception_armv7m/cpu_state.h b/pw_cpu_exception_armv7m/public/pw_cpu_exception_armv7m/cpu_state.h
index f38b949ba..23158c87b 100644
--- a/pw_cpu_exception_armv7m/public/pw_cpu_exception_armv7m/cpu_state.h
+++ b/pw_cpu_exception_armv7m/public/pw_cpu_exception_armv7m/cpu_state.h
@@ -68,6 +68,8 @@ PW_PACKED(struct) ArmV7mExtraRegisters {
uint32_t mmfar;
uint32_t bfar;
uint32_t icsr;
+ uint32_t hfsr;
+ uint32_t shcsr;
// Special registers.
uint32_t exc_return;
uint32_t msp;
diff --git a/pw_cpu_exception_armv7m/pw_cpu_exception_armv7m_protos/cpu_state.proto b/pw_cpu_exception_armv7m/pw_cpu_exception_armv7m_protos/cpu_state.proto
index 77deab8f2..a557d0ea0 100644
--- a/pw_cpu_exception_armv7m/pw_cpu_exception_armv7m_protos/cpu_state.proto
+++ b/pw_cpu_exception_armv7m/pw_cpu_exception_armv7m_protos/cpu_state.proto
@@ -26,6 +26,8 @@ message ArmV7mCpuState {
optional uint32 mmfar = 8;
optional uint32 bfar = 9;
optional uint32 icsr = 10;
+ optional uint32 hfsr = 25;
+ optional uint32 shcsr = 26;
optional uint32 control = 11;
// General purpose registers.
@@ -42,4 +44,6 @@ message ArmV7mCpuState {
optional uint32 r10 = 22;
optional uint32 r11 = 23;
optional uint32 r12 = 24;
+
+ // Next tag: 27
}