Skip to content

Commit 6780ddd

Browse files
Nicolas Pitrekartben
authored andcommitted
arch: arm64: Enhance FPU debug traces with PC addresses
Improve FPU trap debugging by showing the program counter (PC) of instructions that trigger FPU access traps instead of potentially stale saved FPU context data. Signed-off-by: Nicolas Pitre <[email protected]>
1 parent be5c800 commit 6780ddd

File tree

1 file changed

+42
-8
lines changed

1 file changed

+42
-8
lines changed

arch/arm64/core/fpu.c

Lines changed: 42 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,23 +28,32 @@ extern void z_arm64_fpu_restore(struct z_arm64_fp_context *saved_fp_context);
2828

2929
#include <string.h>
3030

31-
static void DBG(char *msg, struct k_thread *th)
31+
static char *dbg_prefix(char *buf, char *msg, struct k_thread *th)
3232
{
33-
char buf[80], *p;
34-
unsigned int v;
35-
3633
strcpy(buf, "CPU# exc# ");
3734
buf[3] = '0' + _current_cpu->id;
3835
buf[8] = '0' + arch_exception_depth();
3936
strcat(buf, _current->name);
4037
strcat(buf, ": ");
4138
strcat(buf, msg);
42-
strcat(buf, " ");
43-
strcat(buf, th->name);
39+
if (th != NULL) {
40+
strcat(buf, " ");
41+
strcat(buf, th->name);
42+
}
43+
return buf + strlen(buf);
44+
}
4445

46+
static void DBG(char *msg, struct k_thread *th)
47+
{
48+
char buf[80], *p;
49+
unsigned int v;
4550

51+
p = dbg_prefix(buf, msg, th);
52+
53+
if (th == NULL) {
54+
th = _current;
55+
}
4656
v = *(unsigned char *)&th->arch.saved_fp_context;
47-
p = buf + strlen(buf);
4857
*p++ = ' ';
4958
*p++ = ((v >> 4) < 10) ? ((v >> 4) + '0') : ((v >> 4) - 10 + 'a');
5059
*p++ = ((v & 15) < 10) ? ((v & 15) + '0') : ((v & 15) - 10 + 'a');
@@ -54,9 +63,31 @@ static void DBG(char *msg, struct k_thread *th)
5463
k_str_out(buf, p - buf);
5564
}
5665

66+
static void DBG_PC(char *msg, uintptr_t pc)
67+
{
68+
char buf[80], *p;
69+
uintptr_t addr = pc;
70+
int i;
71+
72+
p = dbg_prefix(buf, msg, NULL);
73+
strcpy(p, " PC=0x");
74+
p += 6;
75+
76+
/* Format PC address as hex */
77+
for (i = (sizeof(uintptr_t) * 2) - 1; i >= 0; i--) {
78+
unsigned int nibble = (addr >> (i * 4)) & 0xf;
79+
*p++ = (nibble < 10) ? (nibble + '0') : (nibble - 10 + 'a');
80+
}
81+
*p++ = '\n';
82+
*p = 0;
83+
84+
k_str_out(buf, p - buf);
85+
}
86+
5787
#else
5888

5989
static inline void DBG(char *msg, struct k_thread *t) { }
90+
static inline void DBG_PC(char *msg, uintptr_t pc) { }
6091

6192
#endif /* FPU_DEBUG */
6293

@@ -199,6 +230,7 @@ static bool simulate_str_q_insn(struct arch_esf *esf)
199230

200231
/* did we do something? */
201232
if (pc != (uint32_t *)esf->elr) {
233+
DBG_PC("simulated", esf->elr);
202234
/* resume execution past the simulated instructions */
203235
esf->elr = (uintptr_t)pc;
204236
return true;
@@ -230,6 +262,8 @@ void z_arm64_fpu_trap(struct arch_esf *esf)
230262
return;
231263
}
232264

265+
DBG_PC("trap entry", esf->elr);
266+
233267
/* turn on FPU access */
234268
write_cpacr_el1(read_cpacr_el1() | CPACR_EL1_FPEN_NOTRAP);
235269
barrier_isync_fence_full();
@@ -268,7 +302,7 @@ void z_arm64_fpu_trap(struct arch_esf *esf)
268302

269303
/* restore our content */
270304
z_arm64_fpu_restore(&_current->arch.saved_fp_context);
271-
DBG("restore", _current);
305+
DBG("restore", NULL);
272306
}
273307

274308
/*

0 commit comments

Comments
 (0)