diff --git a/sys/arch/sh5/include/trap.h b/sys/arch/sh5/include/trap.h index 7b41843c1449..0b36fc85b997 100644 --- a/sys/arch/sh5/include/trap.h +++ b/sys/arch/sh5/include/trap.h @@ -1,4 +1,4 @@ -/* $NetBSD: trap.h,v 1.5 2002/09/10 11:51:01 scw Exp $ */ +/* $NetBSD: trap.h,v 1.6 2002/09/22 20:31:18 scw Exp $ */ /* * Copyright 2002 Wasabi Systems, Inc. @@ -117,6 +117,10 @@ extern void trapa(struct proc *, struct trapframe *); extern void panic_trap(struct trapframe *, register_t, register_t, register_t, int); extern const char *trap_type(int); +#if defined(DIAGNOSTIC) || defined(DDB) +extern void dump_trapframe(void (*)(const char *, ...), const char *, + struct trapframe *); +#endif extern label_t *onfault; #endif diff --git a/sys/arch/sh5/sh5/db_trace.c b/sys/arch/sh5/sh5/db_trace.c index 200e61c6adb9..e999517c0ada 100644 --- a/sys/arch/sh5/sh5/db_trace.c +++ b/sys/arch/sh5/sh5/db_trace.c @@ -1,4 +1,4 @@ -/* $NetBSD: db_trace.c,v 1.5 2002/09/19 15:47:33 scw Exp $ */ +/* $NetBSD: db_trace.c,v 1.6 2002/09/22 20:31:19 scw Exp $ */ /* * Copyright 2002 Wasabi Systems, Inc. @@ -125,12 +125,13 @@ db_stack_trace_print(db_expr_t addr, int have_addr, db_expr_t count, db_addr_t pc, fp; db_addr_t nextpc, nextfp; db_sym_t sym; - db_expr_t diff; + db_expr_t diff, pc_adj; char *symp; - int trace_thread; + int trace_thread, dump_eframe; /* trace_thread is non-zero if tracing a specific process */ trace_thread = (strchr(modif, 't') != NULL); + dump_eframe = (strchr(modif, 'e') != NULL); if (have_addr == 0) { /* @@ -180,6 +181,8 @@ db_stack_trace_print(db_expr_t addr, int have_addr, db_expr_t count, } } + pc_adj = 0; + /* * Walk the call stack until the PC or FP are not valid */ @@ -189,7 +192,8 @@ db_stack_trace_print(db_expr_t addr, int have_addr, db_expr_t count, * Lookup the name of the current function */ symp = NULL; - if ((sym = db_search_symbol(pc, DB_STGY_PROC, &diff)) == NULL) { + sym = db_search_symbol(pc - pc_adj, DB_STGY_PROC, &diff); + if (sym == NULL) { (*pr)("0x%lx: Symbol not found\n"); break; } @@ -200,27 +204,6 @@ db_stack_trace_print(db_expr_t addr, int have_addr, db_expr_t count, break; } - /* - * Compensate for the symbol in ltsleep(), which matches - * before the real function name. - */ - if (strcmp(symp, "bpendtsleep") == 0) { - symp = NULL; - sym = db_search_symbol(pc - 4, DB_STGY_PROC, &diff); - if (sym == NULL) { - (*pr)("0x%lx: Symbol not found\n"); - break; - } - symp = NULL; - db_symbol_values(sym, &symp, NULL); - if (symp == NULL) { - (*pr)("0x%lx: No symbol string found\n"); - break; - } - diff += 4; - } - /* * There's no point even trying to grovel for function * parameters. It's just Too Much Trouble. @@ -229,7 +212,7 @@ db_stack_trace_print(db_expr_t addr, int have_addr, db_expr_t count, * figure out what's what anyway. */ (*pr)("0x%lx: %s() at ", fp, symp); - db_printsym(pc, DB_STGY_PROC, pr); + db_printsym(pc - pc_adj, DB_STGY_PROC, pr); (*pr)("\n"); /* @@ -252,12 +235,17 @@ db_stack_trace_print(db_expr_t addr, int have_addr, db_expr_t count, pc = (db_addr_t) tf->tf_state.sf_spc & ~1; fp = (db_addr_t) tf->tf_caller.r14; cur_intrframe = &tf->tf_ifr; + pc_adj = 0; (*pr)("\tTrap Type: %s\n", trap_type((int)tf->tf_state.sf_expevt)); - (*pr)("\tSSR=0x%lx, TEA=0x%lx, TRA=0x%lx\n", + (*pr)("\tSSR=0x%lx, TEA=0x%lx, TRA=0x%lx", (long)tf->tf_state.sf_ssr, (long)tf->tf_state.sf_tea, (long)tf->tf_state.sf_tra); + if (dump_eframe) + dump_trapframe(pr, "\n\t", tf); + else + (*pr)("\n"); } else if (strcmp(symp, "Lsh5_event_interrupt") == 0 || strcmp(symp, "Lintrexit") == 0) { @@ -271,26 +259,34 @@ db_stack_trace_print(db_expr_t addr, int have_addr, db_expr_t count, pc = (db_addr_t) tf->if_state.sf_spc & ~1; fp = (db_addr_t) tf->if_caller.r14; cur_intrframe = tf; - (*pr)("\tSSR=0x%lx, INTEVT=0x%lx\n", + pc_adj = 0; + (*pr)("\tSSR=0x%lx, INTEVT=0x%lx", (long)tf->if_state.sf_ssr, (long)tf->if_state.sf_intevt); + if (dump_eframe) { + struct trapframe tfr; + memset(&tfr, 0, sizeof(tfr)); + tfr.tf_ifr = *tf; + dump_trapframe(pr, "\n\t", &tfr); + } else + (*pr)("\n"); } else /* * Looks like we have to grovel the current function's * prologue to find out the next PC and FP. Start the - * search from "PC - 4" to ensure we catch the actual - * "blink" instruction which made the call. Without this, - * we can fall foul of tail-calls and functions with - * the "__noreturn__" attribute (depending on alignment, - * we could pick up the symbol for the *next* function - * and, hence, get the wrong prologue). + * search from "PC - pc_adj" to ensure we catch the actual + * call-site. Without this, we can fall foul of tail-calls + * and functions with the "__noreturn__" attribute + * (depending on alignment, we could pick up the symbol for + * the *next* function and, hence, get the wrong prologue). */ - if (prev_frame(fp, pc - 4, &nextfp, &nextpc) == 0) { - (*pr)("Can't find caller's stack frame.\n"); - break; - } else { + if (prev_frame(fp, pc - pc_adj, &nextfp, &nextpc)) { fp = nextfp; pc = nextpc & ~1; + pc_adj = 4; + } else { + (*pr)("Can't find caller's stack frame.\n"); + break; } } diff --git a/sys/arch/sh5/sh5/trap.c b/sys/arch/sh5/sh5/trap.c index 7910c9d5c31a..16d1dc2b634e 100644 --- a/sys/arch/sh5/sh5/trap.c +++ b/sys/arch/sh5/sh5/trap.c @@ -1,4 +1,4 @@ -/* $NetBSD: trap.c,v 1.12 2002/09/10 12:15:39 scw Exp $ */ +/* $NetBSD: trap.c,v 1.13 2002/09/22 20:31:20 scw Exp $ */ /* * Copyright 2002 Wasabi Systems, Inc. @@ -94,11 +94,6 @@ #include #endif -#ifdef DIAGNOSTIC -static void dump_trapframe(struct trapframe *); -static void print_a_reg(const char *, register_t, int); -#endif - /* Used to trap faults while probing */ label_t *onfault; @@ -205,7 +200,7 @@ trap(struct proc *p, struct trapframe *tf) kdb_trap(traptype, tf); #else #ifdef DIAGNOSTIC - dump_trapframe(tf); + dump_trapframe(printf, "\n", tf); #endif #endif panic("trap"); @@ -363,6 +358,11 @@ trap(struct proc *p, struct trapframe *tf) case T_FPUEXC|T_USER: sig = SIGFPE; ucode = vaddr; /* XXX: "code" should probably be FPSCR */ +#ifdef DEBUG + sh5_fpsave((u_int)tf->tf_state.sf_usr, &p->p_addr->u_pcb); + printf("trap: FPUEXC - fpscr = 0x%x\n", + (u_int)p->p_addr->u_pcb.pcb_ctx.sf_fpregs.fpscr); +#endif break; case T_AST|T_USER: @@ -373,14 +373,16 @@ trap(struct proc *p, struct trapframe *tf) userret(p); return; -#ifdef DDB case T_NMI: case T_NMI|T_USER: printf("trap: NMI detected\n"); - if (kdb_trap(traptype, tf)) + sh5_nmi_clear(); +#ifdef DDB + if (kdb_trap(traptype, tf)) { return; - goto dopanic; + } #endif + goto dopanic; } trapsignal(p, sig, ucode); @@ -435,10 +437,10 @@ trapa_panic: p->p_pid, p->p_comm, (uintptr_t)tf->tf_caller.r15); else printf("curproc == NULL "); - printf("trapa: SPC=0x%lx, SSR=0x%x, TRA=0x%x\n\n", + printf("trapa: SPC=0x%lx, SSR=0x%x, TRA=0x%x\n", (uintptr_t)tf->tf_state.sf_spc, (u_int)tf->tf_state.sf_ssr, (u_int)tf->tf_state.sf_tra); - dump_trapframe(tf); + dump_trapframe(printf, "\n", tf); panic(pstr); /*NOTREACHED*/ } @@ -557,10 +559,10 @@ panic_trap(struct trapframe *tf, register_t ssr, register_t spc, printf(" SPC: 0x%08x%08x\n", (u_int)(excf.es_spc >> 32), (u_int)excf.es_spc); printf(" SSR: 0x%08x\n", (u_int)excf.es_ssr); - printf(" USR: 0x%04x\n\n", (u_int)excf.es_usr); + printf(" USR: 0x%04x\n", (u_int)excf.es_usr); #ifdef DIAGNOSTIC - dump_trapframe(tf); + dump_trapframe(printf, "\n", tf); #endif #ifdef DDB kdb_trap(0, tf); @@ -618,10 +620,10 @@ panic_critical_fault(struct trapframe *tf, struct exc_scratch_frame *es, printf(" SSR: 0x%08x\n", (u_int)excf.es_ssr); printf(" USR: 0x%04x\n\n", (u_int)excf.es_usr); } else - printf("exit.\nNot much to show.\n\n"); + printf("exit.\nNot much to show.\n"); #ifdef DIAGNOSTIC - dump_trapframe(tf); + dump_trapframe(printf, "\n", tf); #endif #ifdef DDB kdb_trap(0, tf); @@ -710,10 +712,19 @@ trap_type(int traptype) return (t); } -#ifdef DIAGNOSTIC -static void -dump_trapframe(struct trapframe *tf) +#if defined(DIAGNOSTIC) || defined(DDB) +void +dump_trapframe(void (*pr)(const char *, ...), const char *prefix, + struct trapframe *tf) { + const char fmt[] = "%s=0x%08x%08x%s"; + const char comma[] = ", "; + + (*pr)(prefix); + +#define print_a_reg(reg, v, nl) (*pr)(fmt, (reg), \ + (u_int)((v) >> 32), (u_int)(v), (nl) ? prefix : comma) + print_a_reg(" r0", tf->tf_caller.r0, 0); print_a_reg(" r1", tf->tf_caller.r1, 0); print_a_reg(" r2", tf->tf_caller.r2, 1); @@ -746,21 +757,24 @@ dump_trapframe(struct trapframe *tf) print_a_reg("r22", tf->tf_caller.r22, 0); print_a_reg("r23", tf->tf_caller.r23, 1); - print_a_reg("r24", 0, 0); + print_a_reg("r24", (register_t)0, 0); print_a_reg("r25", tf->tf_caller.r25, 0); print_a_reg("r26", tf->tf_caller.r26, 1); print_a_reg("r27", tf->tf_caller.r27, 0); - print_a_reg("r28", tf->tf_callee.r28, 0); - print_a_reg("r29", tf->tf_callee.r29, 1); + if (tf->tf_state.sf_flags & SF_FLAGS_CALLEE_SAVED) { + print_a_reg("r28", tf->tf_callee.r28, 0); + print_a_reg("r29", tf->tf_callee.r29, 1); - print_a_reg("r30", tf->tf_callee.r30, 0); - print_a_reg("r31", tf->tf_callee.r31, 0); - print_a_reg("r32", tf->tf_callee.r32, 1); + print_a_reg("r30", tf->tf_callee.r30, 0); + print_a_reg("r31", tf->tf_callee.r31, 0); + print_a_reg("r32", tf->tf_callee.r32, 1); - print_a_reg("r33", tf->tf_callee.r33, 0); - print_a_reg("r34", tf->tf_callee.r34, 0); - print_a_reg("r35", tf->tf_callee.r35, 1); + print_a_reg("r33", tf->tf_callee.r33, 0); + print_a_reg("r34", tf->tf_callee.r34, 0); + print_a_reg("r35", tf->tf_callee.r35, 1); + } else + (*pr)(prefix); print_a_reg("r36", tf->tf_caller.r36, 0); print_a_reg("r37", tf->tf_caller.r37, 0); @@ -772,51 +786,57 @@ dump_trapframe(struct trapframe *tf) print_a_reg("r42", tf->tf_caller.r42, 0); print_a_reg("r43", tf->tf_caller.r43, 0); - print_a_reg("r44", tf->tf_callee.r44, 1); + if (tf->tf_state.sf_flags & SF_FLAGS_CALLEE_SAVED) { + print_a_reg("r44", tf->tf_callee.r44, 1); - print_a_reg("r45", tf->tf_callee.r45, 0); - print_a_reg("r46", tf->tf_callee.r46, 0); - print_a_reg("r47", tf->tf_callee.r47, 1); + print_a_reg("r45", tf->tf_callee.r45, 0); + print_a_reg("r46", tf->tf_callee.r46, 0); + print_a_reg("r47", tf->tf_callee.r47, 1); - print_a_reg("r48", tf->tf_callee.r48, 0); - print_a_reg("r49", tf->tf_callee.r49, 0); - print_a_reg("r50", tf->tf_callee.r50, 1); + print_a_reg("r48", tf->tf_callee.r48, 0); + print_a_reg("r49", tf->tf_callee.r49, 0); + print_a_reg("r50", tf->tf_callee.r50, 1); - print_a_reg("r51", tf->tf_callee.r51, 0); - print_a_reg("r52", tf->tf_callee.r52, 0); - print_a_reg("r53", tf->tf_callee.r53, 1); + print_a_reg("r51", tf->tf_callee.r51, 0); + print_a_reg("r52", tf->tf_callee.r52, 0); + print_a_reg("r53", tf->tf_callee.r53, 1); - print_a_reg("r54", tf->tf_callee.r54, 0); - print_a_reg("r55", tf->tf_callee.r55, 0); - print_a_reg("r56", tf->tf_callee.r56, 1); + print_a_reg("r54", tf->tf_callee.r54, 0); + print_a_reg("r55", tf->tf_callee.r55, 0); + print_a_reg("r56", tf->tf_callee.r56, 1); - print_a_reg("r57", tf->tf_callee.r57, 0); - print_a_reg("r58", tf->tf_callee.r58, 0); - print_a_reg("r59", tf->tf_callee.r59, 1); + print_a_reg("r57", tf->tf_callee.r57, 0); + print_a_reg("r58", tf->tf_callee.r58, 0); + print_a_reg("r59", tf->tf_callee.r59, 1); + } else + (*pr)(prefix); print_a_reg("r60", tf->tf_caller.r60, 0); print_a_reg("r61", tf->tf_caller.r61, 0); print_a_reg("r62", tf->tf_caller.r62, 1); - print_a_reg("\ntr0", tf->tf_caller.tr0, 0); + (*pr)(prefix); + + print_a_reg("tr0", tf->tf_caller.tr0, 0); print_a_reg("tr1", tf->tf_caller.tr1, 0); print_a_reg("tr2", tf->tf_caller.tr2, 1); print_a_reg("tr3", tf->tf_caller.tr3, 0); print_a_reg("tr4", tf->tf_caller.tr4, 0); - print_a_reg("tr5", tf->tf_callee.tr5, 1); + if (tf->tf_state.sf_flags & SF_FLAGS_CALLEE_SAVED) { + print_a_reg("tr5", tf->tf_callee.tr5, 1); - print_a_reg("tr6", tf->tf_callee.tr6, 0); - print_a_reg("tr7", tf->tf_callee.tr7, 1); + print_a_reg("tr6", tf->tf_callee.tr6, 0); + print_a_reg("tr7", tf->tf_callee.tr7, 0); + } + + (*pr)("\n"); +#undef print_a_reg } +#endif -static void -print_a_reg(const char *reg, register_t v, int nl) -{ - printf("%s=0x%08x%08x%s", reg, - (u_int)(v >> 32), (u_int)v, nl ? "\n" : ", "); -} +#ifdef DIAGNOSTIC /* * Called from Ltrapexit in exception.S just before we restore the * trapframe in order to verify that the trapframe is valid enough @@ -884,7 +904,7 @@ validate_trapframe(struct trapframe *tf) boom: printf("oops: current trapframe address: %p\n", tf); - dump_trapframe(tf); + dump_trapframe(printf, "\n", tf); #ifdef DDB kdb_trap(0, tf); #endif