1 // Copyright 2019 The Pigweed Authors
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
7 // https://www.apache.org/licenses/LICENSE-2.0
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
15 #include "pw_cpu_exception_armv7m/cpu_state.h"
21 #include "pw_cpu_exception/support.h"
22 #include "pw_log/log.h"
23 #include "pw_string/string_builder.h"
25 namespace pw::cpu_exception {
27 std::span<const uint8_t> RawFaultingCpuState(
28 const pw_CpuExceptionState& cpu_state) {
29 return std::span(reinterpret_cast<const uint8_t*>(&cpu_state),
33 // Using this function adds approximately 100 bytes to binary size.
34 void ToString(const pw_CpuExceptionState& cpu_state,
35 const std::span<char>& dest) {
36 StringBuilder builder(dest);
37 const ArmV7mFaultRegisters& base = cpu_state.base;
38 const ArmV7mExtraRegisters& extended = cpu_state.extended;
40 #define _PW_FORMAT_REGISTER(state_section, name) \
41 builder.Format("%s=0x%08" PRIx32 "\n", #name, state_section.name)
44 _PW_FORMAT_REGISTER(base, pc);
45 _PW_FORMAT_REGISTER(base, lr);
46 _PW_FORMAT_REGISTER(base, psr);
47 _PW_FORMAT_REGISTER(extended, msp);
48 _PW_FORMAT_REGISTER(extended, psp);
49 _PW_FORMAT_REGISTER(extended, exc_return);
50 _PW_FORMAT_REGISTER(extended, cfsr);
51 _PW_FORMAT_REGISTER(extended, mmfar);
52 _PW_FORMAT_REGISTER(extended, bfar);
53 _PW_FORMAT_REGISTER(extended, icsr);
54 _PW_FORMAT_REGISTER(extended, hfsr);
55 _PW_FORMAT_REGISTER(extended, shcsr);
56 _PW_FORMAT_REGISTER(extended, control);
58 // General purpose registers.
59 _PW_FORMAT_REGISTER(base, r0);
60 _PW_FORMAT_REGISTER(base, r1);
61 _PW_FORMAT_REGISTER(base, r2);
62 _PW_FORMAT_REGISTER(base, r3);
63 _PW_FORMAT_REGISTER(extended, r4);
64 _PW_FORMAT_REGISTER(extended, r5);
65 _PW_FORMAT_REGISTER(extended, r6);
66 _PW_FORMAT_REGISTER(extended, r7);
67 _PW_FORMAT_REGISTER(extended, r8);
68 _PW_FORMAT_REGISTER(extended, r9);
69 _PW_FORMAT_REGISTER(extended, r10);
70 _PW_FORMAT_REGISTER(extended, r11);
71 _PW_FORMAT_REGISTER(base, r12);
73 #undef _PW_FORMAT_REGISTER
76 // Using this function adds approximately 100 bytes to binary size.
77 void LogCpuState(const pw_CpuExceptionState& cpu_state) {
78 const ArmV7mFaultRegisters& base = cpu_state.base;
79 const ArmV7mExtraRegisters& extended = cpu_state.extended;
81 PW_LOG_INFO("Captured CPU state:");
83 #define _PW_LOG_REGISTER(state_section, name) \
84 PW_LOG_INFO(" %-10s 0x%08" PRIx32, #name, state_section.name)
87 _PW_LOG_REGISTER(base, pc);
88 _PW_LOG_REGISTER(base, lr);
89 _PW_LOG_REGISTER(base, psr);
90 _PW_LOG_REGISTER(extended, msp);
91 _PW_LOG_REGISTER(extended, psp);
92 _PW_LOG_REGISTER(extended, exc_return);
93 _PW_LOG_REGISTER(extended, cfsr);
94 _PW_LOG_REGISTER(extended, mmfar);
95 _PW_LOG_REGISTER(extended, bfar);
96 _PW_LOG_REGISTER(extended, icsr);
97 _PW_LOG_REGISTER(extended, hfsr);
98 _PW_LOG_REGISTER(extended, shcsr);
99 _PW_LOG_REGISTER(extended, control);
101 // General purpose registers.
102 _PW_LOG_REGISTER(base, r0);
103 _PW_LOG_REGISTER(base, r1);
104 _PW_LOG_REGISTER(base, r2);
105 _PW_LOG_REGISTER(base, r3);
106 _PW_LOG_REGISTER(extended, r4);
107 _PW_LOG_REGISTER(extended, r5);
108 _PW_LOG_REGISTER(extended, r6);
109 _PW_LOG_REGISTER(extended, r7);
110 _PW_LOG_REGISTER(extended, r8);
111 _PW_LOG_REGISTER(extended, r9);
112 _PW_LOG_REGISTER(extended, r10);
113 _PW_LOG_REGISTER(extended, r11);
114 _PW_LOG_REGISTER(base, r12);
116 #undef _PW_LOG_REGISTER
119 } // namespace pw::cpu_exception