|
From: falcovorbis <fal...@us...> - 2024-06-03 02:32:24
|
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "A pseudo Operating System for the Dreamcast.".
The branch, master has been updated
via cfcd40fd57bab6de70c181e48b0eea1db4b263a6 (commit)
via e6a50173d1a7c94a633bceffe1d30b37038fb676 (commit)
from 34f7e943d311cd0105eb012571e7fcda41d3370d (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit cfcd40fd57bab6de70c181e48b0eea1db4b263a6
Author: Donald Haase <qu...@ya...>
Date: Sun Jun 2 22:31:52 2024 -0400
Correct bitmasks in fpu_exc stringify (#601)
Co-authored-by: QuzarDC <qu...@co...>
commit e6a50173d1a7c94a633bceffe1d30b37038fb676
Author: Andy Barajas <and...@gm...>
Date: Sun Jun 2 19:23:12 2024 -0700
Diagnose help on reg dumps (#600)
* Print out command to help diagnose kernal panic reg dump
-----------------------------------------------------------------------
Summary of changes:
environ_base.sh | 1 +
examples/dreamcast/basic/fpu/exc/fpu_exc.c | 4 +-
kernel/arch/dreamcast/include/arch/stack.h | 2 +-
kernel/arch/dreamcast/kernel/irq.c | 73 +++++++++++++++++++++++++++---
kernel/arch/dreamcast/kernel/panic.c | 2 +-
kernel/arch/dreamcast/kernel/stack.c | 15 ++++--
6 files changed, 84 insertions(+), 13 deletions(-)
diff --git a/environ_base.sh b/environ_base.sh
index ada69c13..446e3b3a 100644
--- a/environ_base.sh
+++ b/environ_base.sh
@@ -33,6 +33,7 @@ export KOS_AS="${KOS_CC_BASE}/bin/${KOS_CC_PREFIX}-as"
export KOS_AR="${KOS_CC_BASE}/bin/${KOS_CC_PREFIX}-gcc-ar"
export KOS_OBJCOPY="${KOS_CC_BASE}/bin/${KOS_CC_PREFIX}-objcopy"
export KOS_OBJDUMP="${KOS_CC_BASE}/bin/${KOS_CC_PREFIX}-objdump"
+export KOS_ADDR2LINE="${KOS_CC_BASE}/bin/${KOS_CC_PREFIX}-addr2line"
export KOS_LD="${KOS_CC_BASE}/bin/${KOS_CC_PREFIX}-ld"
export KOS_RANLIB="${KOS_CC_BASE}/bin/${KOS_CC_PREFIX}-gcc-ranlib"
export KOS_STRIP="${KOS_CC_BASE}/bin/${KOS_CC_PREFIX}-strip"
diff --git a/examples/dreamcast/basic/fpu/exc/fpu_exc.c b/examples/dreamcast/basic/fpu/exc/fpu_exc.c
index 718d5e0d..3f42cfaf 100644
--- a/examples/dreamcast/basic/fpu/exc/fpu_exc.c
+++ b/examples/dreamcast/basic/fpu/exc/fpu_exc.c
@@ -42,8 +42,8 @@ fpscr_stringify(unsigned int value, char* buffer, size_t bytes) {
!!(value & (1 << 19)),
!!(value & (1 << 18)),
(value >> 12) & 0x3f,
- (value >> 7) & 0x3f,
- (value >> 2) & 0x3f,
+ (value >> 7) & 0x1f,
+ (value >> 2) & 0x1f,
value & 0x3);
return buffer;
diff --git a/kernel/arch/dreamcast/include/arch/stack.h b/kernel/arch/dreamcast/include/arch/stack.h
index 38f1b0be..d3f5062b 100644
--- a/kernel/arch/dreamcast/include/arch/stack.h
+++ b/kernel/arch/dreamcast/include/arch/stack.h
@@ -53,7 +53,7 @@ void arch_stk_trace(int n);
\param fp The frame pointer to start from.
\param n The number of frames to leave off.
*/
-void arch_stk_trace_at(uint32 fp, int n);
+void arch_stk_trace_at(uint32_t fp, size_t n);
/** @} */
diff --git a/kernel/arch/dreamcast/kernel/irq.c b/kernel/arch/dreamcast/kernel/irq.c
index e4840ac1..dbb75e01 100644
--- a/kernel/arch/dreamcast/kernel/irq.c
+++ b/kernel/arch/dreamcast/kernel/irq.c
@@ -83,10 +83,48 @@ int trapa_set_handler(irq_t code, irq_handler hnd, void *data) {
return 0;
}
+/* Get a string description of the exception */
+static char *irq_exception_string(int evt) {
+ switch(evt) {
+ case EXC_ILLEGAL_INSTR:
+ return "Illegal instruction";
+ case EXC_SLOT_ILLEGAL_INSTR:
+ return "Slot illegal instruction";
+ case EXC_GENERAL_FPU:
+ return "General FPU exception";
+ case EXC_SLOT_FPU:
+ return "Slot FPU exception";
+ case EXC_DATA_ADDRESS_READ:
+ return "Data address error (read)";
+ case EXC_DATA_ADDRESS_WRITE:
+ return "Data address error (write)";
+ case EXC_DTLB_MISS_READ: /* or EXC_ITLB_MISS */
+ return "Instruction or Data(read) TLB miss";
+ case EXC_DTLB_MISS_WRITE:
+ return "Data(write) TLB miss";
+ case EXC_DTLB_PV_READ: /* or EXC_ITLB_PV */
+ return "Instruction or Data(read) TLB protection violation";
+ case EXC_DTLB_PV_WRITE:
+ return "Data TLB protection violation (write)";
+ case EXC_FPU:
+ return "FPU exception";
+ case EXC_INITIAL_PAGE_WRITE:
+ return "Initial page write exception";
+ case EXC_TRAPA:
+ return "Unconditional trap (trapa)";
+ case EXC_USER_BREAK_POST: /* or EXC_USER_BREAK_PRE */
+ return "User break";
+ default:
+ return "Unknown exception";
+ }
+}
+
/* Print a kernel panic reg dump */
extern irq_context_t *irq_srt_addr;
-void irq_dump_regs(int code, int evt) {
+static void irq_dump_regs(int code, int evt) {
+ uint32_t fp;
uint32_t *regs = irq_srt_addr->r;
+
dbglog(DBG_DEAD, "Unhandled exception: PC %08lx, code %d, evt %04x\n",
irq_srt_addr->pc, code, (uint16)evt);
dbglog(DBG_DEAD, " R0-R7: %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
@@ -94,11 +132,34 @@ void irq_dump_regs(int code, int evt) {
dbglog(DBG_DEAD, " R8-R15: %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
regs[8], regs[9], regs[10], regs[11], regs[12], regs[13], regs[14], regs[15]);
dbglog(DBG_DEAD, " SR %08lx PR %08lx\n", irq_srt_addr->sr, irq_srt_addr->pr);
- arch_stk_trace_at(regs[14], 0);
- /* dbgio_printf(" Vicinity code ");
- dbgio_printf(" @%08lx: %04x %04x %04x %04x %04x\n",
- srt_addr->pc-4, *((uint16*)(srt_addr->pc-4)), *((uint16*)(srt_addr->pc-2)),
- *((uint16*)(srt_addr->pc)), *((uint16*)(srt_addr->pc+2)), *((uint16*)(srt_addr->pc+4))); */
+ fp = regs[14];
+ arch_stk_trace_at(fp, 0);
+
+ if(code == 1) {
+ dbglog(DBG_DEAD, "Encountered %s. Use this terminal command to help"
+ " diagnose:\n\n\t$KOS_ADDR2LINE -e your_program.elf %08lx %08lx",
+ irq_exception_string(evt), irq_srt_addr->pc, irq_srt_addr->pr);
+
+#ifdef FRAME_POINTERS
+ while(fp != 0xffffffff) {
+ /* Validate the function pointer (fp) */
+ if((fp & 3) || (fp < 0x8c000000) || (fp > _arch_mem_top))
+ break;
+
+ /* Get the return address from the function pointer */
+ fp = arch_fptr_ret_addr(fp);
+
+ /* Validate the return address */
+ if(!arch_valid_address(fp))
+ break;
+
+ dbglog(DBG_DEAD, " %08lx", fp);
+ fp = arch_fptr_next(fp);
+ }
+#endif
+
+ dbglog(DBG_DEAD, "\n");
+ }
}
/* The C-level routine that processes context switching and other
diff --git a/kernel/arch/dreamcast/kernel/panic.c b/kernel/arch/dreamcast/kernel/panic.c
index 09c18d06..97c255ec 100644
--- a/kernel/arch/dreamcast/kernel/panic.c
+++ b/kernel/arch/dreamcast/kernel/panic.c
@@ -12,6 +12,6 @@
can recover, call this. This is a pretty standard tactic from *nixy
kernels which ought to be avoided if at all possible. */
void arch_panic(const char *msg) {
- printf("kernel panic: %s\r\n", msg);
+ printf("\nkernel panic: %s\r\n", msg);
arch_abort();
}
diff --git a/kernel/arch/dreamcast/kernel/stack.c b/kernel/arch/dreamcast/kernel/stack.c
index 2a2fe7c1..a57140d6 100644
--- a/kernel/arch/dreamcast/kernel/stack.c
+++ b/kernel/arch/dreamcast/kernel/stack.c
@@ -31,18 +31,27 @@ void arch_stk_trace(int n) {
/* Do a stack trace from the given frame pointer (useful for things like
tracing from an ISR); leave off the first n frames. */
-void arch_stk_trace_at(uint32 fp, int n) {
+void arch_stk_trace_at(uint32_t fp, size_t n) {
#ifdef FRAME_POINTERS
dbgio_printf("-------- Stack Trace (innermost first) ---------\n");
while(fp != 0xffffffff) {
+ /* Validate the function pointer (fp) */
if((fp & 3) || (fp < 0x8c000000) || (fp > _arch_mem_top)) {
dbgio_printf(" (invalid frame pointer)\n");
break;
}
+
+ if(n == 0) {
+ /* Get the return address from the function pointer */
+ fp = arch_fptr_ret_addr(fp);
- if(n <= 0) {
- dbgio_printf(" %08lx\n", arch_fptr_ret_addr(fp));
+ /* Validate the return address */
+ if(!arch_valid_address(fp)) {
+ dbgio_printf(" %08lx (invalid return address)\n", fp);
+ break;
+ } else
+ dbgio_printf(" %08lx\n", fp);
}
else n--;
hooks/post-receive
--
A pseudo Operating System for the Dreamcast.
|