ATLAS Offline Software
arm_helpers.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
3 */
12 #if defined(__aarch64__) && defined(__linux)
13 
14 
15 #include "arm_helpers.h"
16 #include "CxxUtils/SealDebug.h"
17 #include <iterator>
18 #include <unistd.h>
19 #include <stdio.h>
20 #include <asm/sigcontext.h>
21 
22 namespace {
23 
24 
25 // ESR decoding logic adapted from the linux kernel ---
26 // arch/arm64/kernel/traps.c
27 // arch/arm64/mm/fault.c
28 // arch/arm64/include/asm/esr.h
29 
30 static constexpr uint32_t ESR_ELx_EC_SHIFT = 26;
31 static constexpr uint32_t ESR_ELx_EC_MASK = 0x3Ful << ESR_ELx_EC_SHIFT;
32 inline uint32_t ESR_ELx_EC (uint32_t esr) {
33  return (esr & ESR_ELx_EC_MASK) >> ESR_ELx_EC_SHIFT;
34 }
35 
36 static constexpr uint32_t ESR_ELx_IL_SHIFT = 25;
37 static constexpr uint32_t ESR_ELx_IL = 1ul << ESR_ELx_IL_SHIFT;
38 static constexpr uint32_t ESR_ELx_ISS_MASK = ESR_ELx_IL - 1;
39 
40 // Shared ISS field definitions for Data/Instruction aborts.
41 static constexpr uint32_t ESR_ELx_SET_SHIFT = 11;
42 static constexpr uint32_t ESR_ELx_SET_MASK = 3ul << ESR_ELx_SET_SHIFT;
43 static constexpr uint32_t ESR_ELx_FnV_SHIFT = 10;
44 static constexpr uint32_t ESR_ELx_FnV = 1ul << ESR_ELx_FnV_SHIFT;
45 static constexpr uint32_t ESR_ELx_EA_SHIFT = 9;
46 static constexpr uint32_t ESR_ELx_EA = 1ul << ESR_ELx_EA_SHIFT;
47 static constexpr uint32_t ESR_ELx_S1PTW_SHIFT = 7;
48 static constexpr uint32_t ESR_ELx_S1PTW = 1ul << ESR_ELx_S1PTW_SHIFT;
49 
50 // ISS field definitions for Data Aborts.
51 static constexpr uint32_t ESR_ELx_ISV_SHIFT = 24;
52 static constexpr uint32_t ESR_ELx_ISV = 1ul << ESR_ELx_ISV_SHIFT;
53 static constexpr uint32_t ESR_ELx_SAS_SHIFT = 22;
54 static constexpr uint32_t ESR_ELx_SAS = 3ul << ESR_ELx_SAS_SHIFT;
55 static constexpr uint32_t ESR_ELx_SSE_SHIFT = 21;
56 static constexpr uint32_t ESR_ELx_SSE = 1ul << ESR_ELx_SSE_SHIFT;
57 static constexpr uint32_t ESR_ELx_SRT_SHIFT = 16;
58 static constexpr uint32_t ESR_ELx_SRT_MASK = 0x1Ful << ESR_ELx_SRT_SHIFT;
59 static constexpr uint32_t ESR_ELx_SF_SHIFT = 15;
60 static constexpr uint32_t ESR_ELx_SF = 1u << ESR_ELx_SF_SHIFT;
61 static constexpr uint32_t ESR_ELx_AR_SHIFT = 14;
62 static constexpr uint32_t ESR_ELx_AR = 1u << ESR_ELx_AR_SHIFT;
63 static constexpr uint32_t ESR_ELx_CM_SHIFT = 8;
64 static constexpr uint32_t ESR_ELx_CM = 1u << ESR_ELx_CM_SHIFT;
65 
66 // ISS field definitions shared by different classes.
67 static constexpr uint32_t ESR_ELx_WNR_SHIFT = 6;
68 static constexpr uint32_t ESR_ELx_WNR = 1u << ESR_ELx_WNR_SHIFT;
69 
70 
71 static const char* const esr_class_str[] =
72 {
73  "Unknown/Uncategorized", // 0x00: ESR_ELx_EC_UNKNOWN
74  "WFI/WFE", // 0x01: ESR_ELx_EC_WFx
75  "UNRECOGNIZED EC", // 0x02
76  "CP15 MCR/MRC", // 0x03: SR_ELx_EC_CP15_32
77  "CP15 MCRR/MRRC", // 0x04: ESR_ELx_EC_CP15_64
78  "CP14 MCR/MRC", // 0x05: ESR_ELx_EC_CP14_MR
79  "CP14 LDC/STC", // 0x06: ESR_ELx_EC_CP14_LS
80  "ASIMD", // 0x07: ESR_ELx_EC_FP_ASIMD
81  "CP10 MRC/VMRS", // 0x08: ESR_ELx_EC_CP10_ID
82  "UNRECOGNIZED EC", // 0x09
83  "UNRECOGNIZED EC", // 0x0a
84  "UNRECOGNIZED EC", // 0x0b
85  "CP14 MCRR/MRRC", // 0x0c: ESR_ELx_EC_CP14_64
86  "UNRECOGNIZED EC", // 0x0d
87  "PSTATE.IL", // 0x0e: ESR_ELx_EC_ILL
88  "UNRECOGNIZED EC", // 0x0f
89  "UNRECOGNIZED EC", // 0x10
90  "SVC (AArch32)", // 0x11: ESR_ELx_EC_SVC32
91  "HVC (AArch32)", // 0x12: ESR_ELx_EC_HVC32
92  "SMC (AArch32)", // 0x13: ESR_ELx_EC_SMC32
93  "UNRECOGNIZED EC", // 0x14
94  "SVC (AArch64)", // 0x15: ESR_ELx_EC_SVC64
95  "HVC (AArch64)", // 0x16: ESR_ELx_EC_HVC64
96  "SMC (AArch64)", // 0x17: ESR_ELx_EC_SMC64
97  "MSR/MRS (AArch64)", // 0x18: ESR_ELx_EC_SYS64
98  "SVE", // 0x19: ESR_ELx_EC_SVE
99  "UNRECOGNIZED EC", // 0x1a
100  "UNRECOGNIZED EC", // 0x1b
101  "UNRECOGNIZED EC", // 0x1c
102  "UNRECOGNIZED EC", // 0x1d
103  "UNRECOGNIZED EC", // 0x1e
104  "EL3 IMP DEF", // 0x1f: ESR_ELx_EC_IMP_DEF
105  "IABT (lower EL)", // 0x20: ESR_ELx_EC_IABT_LOW
106  "IABT (current EL)", // 0x21: ESR_ELx_EC_IABT_CUR
107  "PC Alignment", // 0x22: ESR_ELx_EC_PC_ALIGN
108  "UNRECOGNIZED EC", // 0x23
109  "DABT (lower EL)", // 0x24: ESR_ELx_EC_DABT_LOW
110  "DABT (current EL)", // 0x25: ESR_ELx_EC_DABT_CUR
111  "SP Alignment", // 0x26: ESR_ELx_EC_SP_ALIGN
112  "UNRECOGNIZED EC", // 0x27
113  "FP (AArch32)", // 0x28: ESR_ELx_EC_FP_EXC32
114  "UNRECOGNIZED EC", // 0x29
115  "UNRECOGNIZED EC", // 0x2a
116  "UNRECOGNIZED EC", // 0x2b
117  "FP (AArch64)", // 0x2c: ESR_ELx_EC_FP_EXC64
118  "UNRECOGNIZED EC", // 0x2d
119  "UNRECOGNIZED EC", // 0x2e
120  "SError", // 0x2f: ESR_ELx_EC_SERROR
121  "Breakpoint (lower EL)", // 0x30: ESR_ELx_EC_BREAKPT_LOW
122  "Breakpoint (current EL)", // 0x31: ESR_ELx_EC_BREAKPT_CUR
123  "Software Step (lower EL)", // 0x32: ESR_ELx_EC_SOFTSTP_LOW
124  "Software Step (current EL)", // 0x33: ESR_ELx_EC_SOFTSTP_CUR
125  "Watchpoint (lower EL)", // 0x34: ESR_ELx_EC_WATCHPT_LOW
126  "Watchpoint (current EL)", // 0x35: ESR_ELx_EC_WATCHPT_CUR
127  "UNRECOGNIZED EC", // 0x36
128  "UNRECOGNIZED EC", // 0x37
129  "BKPT (AArch32)", // 0x38: ESR_ELx_EC_BKPT32
130  "UNRECOGNIZED EC", // 0x39
131  "Vector catch (AArch32)", // 0x3a: ESR_ELx_EC_VECTOR32
132  "UNRECOGNIZED EC", // 0x3b
133  "BRK (AArch64)", // 0x3c: ESR_ELx_EC_BRK64
134 };
135 
136 static constexpr uint32_t ESR_ELx_EC_DABT_LOW = 0x24;
137 static constexpr uint32_t ESR_ELx_EC_DABT_CUR = 0x25;
138 
139 
140 
141 const char* esr_get_class_string (uint32_t esr)
142 {
143  uint32_t code = ESR_ELx_EC(esr);
144  if (code >= std::size (esr_class_str))
145  return esr_class_str[2]; // UNRECOGNIZED EC
146  return esr_class_str[code];
147 }
148 
149 
150 inline bool esr_is_data_abort(uint32_t esr)
151 {
152  const uint32_t ec = ESR_ELx_EC(esr);
153  return ec == ESR_ELx_EC_DABT_LOW || ec == ESR_ELx_EC_DABT_CUR;
154 }
155 
156 
157 void esr_data_abort_decode (IOFD fd,
158  char* buf, unsigned int buf_size,
159  uint32_t esr)
160 {
161  if (esr & ESR_ELx_ISV) {
162  MYWRITE (fd, buf, snprintf (buf, buf_size,
163  "\n Access size = %u byte(s)",
164  1u << ((esr & ESR_ELx_SAS) >> ESR_ELx_SAS_SHIFT)));
165  MYWRITE (fd, buf, snprintf (buf, buf_size,
166  "\n SSE = %u, SRT = %u",
167  (esr & ESR_ELx_SSE) >> ESR_ELx_SSE_SHIFT,
168  (esr & ESR_ELx_SRT_MASK) >> ESR_ELx_SRT_SHIFT));
169  MYWRITE (fd, buf, snprintf (buf, buf_size,
170  "\n SF = %u, AR = %u",
171  (esr & ESR_ELx_SF) >> ESR_ELx_SF_SHIFT,
172  (esr & ESR_ELx_AR) >> ESR_ELx_AR_SHIFT));
173  } else {
174  MYWRITE (fd, buf, snprintf (buf, buf_size,
175  "\n ISV = 0, ISS = 0x%08x",
176  esr & ESR_ELx_ISS_MASK));
177  }
178 
179  MYWRITE (fd, buf, snprintf (buf, buf_size,
180  "\n CM = %u, WnR = %u",
181  (esr & ESR_ELx_CM) >> ESR_ELx_CM_SHIFT,
182  (esr & ESR_ELx_WNR) >> ESR_ELx_WNR_SHIFT));
183 }
184 
185 
186 } // anonymous namespace
187 
188 
189 namespace CxxUtils {
190 
191 
192 void aarch64_dump_fpsimd (IOFD fd,
193  char* buf, unsigned int buf_size,
194  const fpsimd_context& ctx)
195 {
196  MYWRITE (fd, buf, snprintf (buf, buf_size,
197  "\n"
198  "\n fpsr: %08x fpcr: %08x",
199  ctx.fpsr, ctx.fpcr));
200  for (int i = 0; i < 32; ++i) {
201  union {
202  __uint128_t u128;
203  uint32_t u32[4];
204  } c;
205  c.u128 = ctx.vregs[i];
206  MYWRITE (fd, buf, snprintf (buf, buf_size,
207  "\n v%d:%s [%08x %08x %08x %08x]",
208  i,
209  i < 10 ? " " : "",
210  c.u32[0], c.u32[1], c.u32[2], c.u32[3]));
211  }
212 }
213 
214 
215 void aarch64_dump_esr (IOFD fd,
216  char* buf, unsigned int buf_size,
217  const esr_context& ctx)
218 {
219  MYWRITE (fd, buf, snprintf (buf, buf_size,
220  "\n\n Mem abort info --- ESR: %016llx",
221  ctx.esr));
222  MYWRITE (fd, buf, snprintf (buf, buf_size,
223  "\n Exception class = %s, IL = %u bits",
224  esr_get_class_string (ctx.esr),
225  (ctx.esr & ESR_ELx_IL) ? 32 : 16));
226  MYWRITE (fd, buf, snprintf (buf, buf_size,
227  "\n SET = %llu, FnV = %llu",
228  (ctx.esr & ESR_ELx_SET_MASK) >> ESR_ELx_SET_SHIFT,
229  (ctx.esr & ESR_ELx_FnV) >> ESR_ELx_FnV_SHIFT));
230  MYWRITE (fd, buf, snprintf (buf, buf_size,
231  "\n EA = %llu, S1PTW = %llu",
232  (ctx.esr & ESR_ELx_EA) >> ESR_ELx_EA_SHIFT,
233  (ctx.esr & ESR_ELx_S1PTW) >> ESR_ELx_S1PTW_SHIFT));
234 
235  if (esr_is_data_abort (ctx.esr)) {
236  esr_data_abort_decode (fd, buf, buf_size, ctx.esr);
237  }
238 }
239 
240 
248 void aarch64_dump_registers (IOFD fd,
249  char* buf, unsigned int buf_size,
250  const mcontext_t& mc)
251 {
252  MYWRITE (fd, buf, snprintf (buf, buf_size,
253  "\n pc: %016llx pstate: %016llx",
254  mc.pc, mc.pstate));
255  for (int i = 0; i < 30; i += 2) {
256  MYWRITE (fd, buf, snprintf (buf, buf_size,
257  "\n x%d:%s %016llx x%d:%s %016llx",
258  i, i < 10 ? " " : "", mc.regs[i],
259  i+1, i+1 < 10 ? " " : "", mc.regs[i+1]));
260  }
261  MYWRITE (fd, buf, snprintf (buf, buf_size,
262  "\n x30: %016llx sp: %016llx",
263  mc.regs[30], mc.sp));
264 
265  int ipos = 0;
266  while (ipos + sizeof(_aarch64_ctx) <= sizeof (mc.__reserved)) {
267  const _aarch64_ctx* ctx = reinterpret_cast<const _aarch64_ctx*> (&mc.__reserved[ipos]);
268  if (ctx->magic == 0 || ipos + ctx->size > sizeof (mc.__reserved)) {
269  break;
270  }
271  if (ctx->magic == FPSIMD_MAGIC) {
272  aarch64_dump_fpsimd (fd, buf, buf_size, *reinterpret_cast<const fpsimd_context*>(ctx));
273  }
274  else if (ctx->magic == ESR_MAGIC) {
275  aarch64_dump_esr (fd, buf, buf_size, *reinterpret_cast<const esr_context*>(ctx));
276  }
277  else if (ctx->magic == EXTRA_MAGIC) {
278  MYWRITE (fd, buf, snprintf (buf, buf_size, "\n\n[extra dump not implemented]\n"));
279  }
280  else if (ctx->magic == SVE_MAGIC) {
281  MYWRITE (fd, buf, snprintf (buf, buf_size, "\n\n[SVE dump not implemented]\n"));
282  }
283  ipos += ctx->size;
284  }
285 }
286 
287 
288 } // namespace CxxUtils
289 
290 
291 #endif // __aarch64__ && __linux
arm_helpers.h
xAOD::uint32_t
setEventNumber uint32_t
Definition: EventInfo_v1.cxx:127
SealDebug.h
This are the SEAL debug aids, adapted to build in Atlas, after the drop of that project.
Trk::u
@ u
Enums for curvilinear frames.
Definition: ParamDefs.h:77
python.setupRTTAlg.size
int size
Definition: setupRTTAlg.py:39
histSizes.code
code
Definition: histSizes.py:129
mc
Definition: mc.PG_single_nu_valid.py:1
lumiFormat.i
int i
Definition: lumiFormat.py:85
IOFD
int IOFD
Type the system uses for channel descriptors.
Definition: SealCommon.h:27
CxxUtils
Definition: aligned_vector.h:29
detail::ul
unsigned long ul
Definition: PrimitiveHelpers.h:45
ReadFromCoolCompare.fd
fd
Definition: ReadFromCoolCompare.py:196
python.compressB64.c
def c
Definition: compressB64.py:93
MYWRITE
#define MYWRITE(fd, data, n)
Definition: SealDebug.h:44