add kernel stack and trapframe debug command.
This commit is contained in:
parent
9e6153d985
commit
3900e66164
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: db_interface.c,v 1.12 2002/03/03 14:31:27 uch Exp $ */
|
||||
/* $NetBSD: db_interface.c,v 1.13 2002/03/17 14:03:55 uch Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (C) 2002 UCHIYAMA Yasushi. All rights reserved.
|
||||
|
@ -29,9 +29,11 @@
|
|||
|
||||
#include "opt_ddb.h"
|
||||
#include "opt_kgdb.h"
|
||||
#include "opt_kstack_debug.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/user.h>
|
||||
|
||||
#include <uvm/uvm_extern.h>
|
||||
|
||||
|
@ -39,6 +41,7 @@
|
|||
|
||||
#include <machine/db_machdep.h>
|
||||
#include <ddb/db_run.h>
|
||||
#include <ddb/db_sym.h>
|
||||
|
||||
#include <sh3/ubcreg.h>
|
||||
|
||||
|
@ -67,10 +70,17 @@ void __db_tlbdump_pfn(u_int32_t);
|
|||
void db_cachedump_cmd(db_expr_t, int, db_expr_t, char *);
|
||||
void __db_cachedump_sh3(vaddr_t);
|
||||
void __db_cachedump_sh4(vaddr_t);
|
||||
void db_stackcheck_cmd(db_expr_t, int, db_expr_t, char *);
|
||||
void db_frame_cmd(db_expr_t, int, db_expr_t, char *);
|
||||
void __db_print_symbol(db_expr_t);
|
||||
|
||||
const struct db_command db_machine_command_table[] = {
|
||||
{ "tlb", db_tlbdump_cmd, 0, 0 },
|
||||
{ "cache", db_cachedump_cmd, 0, 0 },
|
||||
{ "frame", db_frame_cmd, 0, 0 },
|
||||
#ifdef KSTACK_DEBUG
|
||||
{ "stack", db_stackcheck_cmd, 0, 0 },
|
||||
#endif
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
|
@ -79,13 +89,16 @@ int db_active;
|
|||
void
|
||||
kdb_printtrap(u_int type, int code)
|
||||
{
|
||||
int i;
|
||||
i = type >> 5;
|
||||
|
||||
db_printf("kernel mode trap: ");
|
||||
if (type >= trap_types)
|
||||
db_printf("type %d", type);
|
||||
db_printf("%s mode trap: ", type & 1 ? "user" : "kernel");
|
||||
if (i >= trap_types)
|
||||
db_printf("type 0x%03x", type & ~1);
|
||||
else
|
||||
db_printf("%s", trap_type[type]);
|
||||
db_printf(" (code = 0x%x)\n", code);
|
||||
db_printf("%s", trap_type[i]);
|
||||
|
||||
db_printf(" code = 0x%x\n", code);
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -212,26 +225,26 @@ db_tlbdump_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
|
|||
if (CPU_IS_SH3) {
|
||||
/* MMU configuration. */
|
||||
r = _reg_read_4(SH3_MMUCR);
|
||||
printf("%s-mode, %s virtual storage mode\n",
|
||||
db_printf("%s-mode, %s virtual storage mode\n",
|
||||
r & SH3_MMUCR_IX
|
||||
? "ASID + VPN" : "VPN only",
|
||||
r & SH3_MMUCR_SV ? "single" : "multiple");
|
||||
printf("---TLB DUMP---\n%s\n%s\n", title, title2);
|
||||
db_printf("---TLB DUMP---\n%s\n%s\n", title, title2);
|
||||
for (i = 0; i < SH3_MMU_WAY; i++) {
|
||||
printf(" [way %d]\n", i);
|
||||
db_printf(" [way %d]\n", i);
|
||||
for (e = 0; e < SH3_MMU_ENTRY; e++) {
|
||||
/* address/data array common offset. */
|
||||
a = (e << SH3_MMU_VPN_SHIFT) |
|
||||
(i << SH3_MMU_WAY_SHIFT);
|
||||
|
||||
r = _reg_read_4(SH3_MMUAA | a);
|
||||
printf("0x%08x %3d",
|
||||
db_printf("0x%08x %3d",
|
||||
r & SH3_MMUAA_D_VPN_MASK_1K,
|
||||
r & SH3_MMUAA_D_ASID_MASK);
|
||||
r = _reg_read_4(SH3_MMUDA | a);
|
||||
|
||||
__db_tlbdump_pfn(r);
|
||||
printf(" %c%c%c%cx %s %2dK\n",
|
||||
db_printf(" %c%c%c%cx %s %2dK\n",
|
||||
ON(r, SH3_MMUDA_D_V),
|
||||
ON(r, SH3_MMUDA_D_D),
|
||||
ON(r, SH3_MMUDA_D_C),
|
||||
|
@ -244,23 +257,23 @@ db_tlbdump_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
|
|||
} else {
|
||||
/* MMU configuration */
|
||||
r = _reg_read_4(SH4_MMUCR);
|
||||
printf("%s virtual storage mode, SQ access: (kernel%s)\n",
|
||||
db_printf("%s virtual storage mode, SQ access: (kernel%s)\n",
|
||||
r & SH3_MMUCR_SV ? "single" : "multiple",
|
||||
r & SH4_MMUCR_SQMD ? "" : "/user");
|
||||
printf("random counter limit=%d\n", (r & SH4_MMUCR_URB_MASK) >>
|
||||
db_printf("random counter limit=%d\n", (r & SH4_MMUCR_URB_MASK) >>
|
||||
SH4_MMUCR_URB_SHIFT);
|
||||
|
||||
/* Dump ITLB */
|
||||
printf("---ITLB DUMP ---\n%s TC SA\n%s\n", title, title2);
|
||||
db_printf("---ITLB DUMP ---\n%s TC SA\n%s\n", title, title2);
|
||||
for (i = 0; i < 4; i++) {
|
||||
e = i << SH4_ITLB_E_SHIFT;
|
||||
r = _reg_read_4(SH4_ITLB_AA | e);
|
||||
printf("0x%08x %3d",
|
||||
db_printf("0x%08x %3d",
|
||||
r & SH4_ITLB_AA_VPN_MASK,
|
||||
r & SH4_ITLB_AA_ASID_MASK);
|
||||
r = _reg_read_4(SH4_ITLB_DA1 | e);
|
||||
__db_tlbdump_pfn(r);
|
||||
printf(" %c_%c%c_ %s ",
|
||||
db_printf(" %c_%c%c_ %s ",
|
||||
ON(r, SH4_ITLB_DA1_V),
|
||||
ON(r, SH4_ITLB_DA1_C),
|
||||
ON(r, SH4_ITLB_DA1_SH),
|
||||
|
@ -268,21 +281,21 @@ db_tlbdump_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
|
|||
SH4_UTLB_DA1_PR_SHIFT]);
|
||||
__db_tlbdump_page_size_sh4(r);
|
||||
r = _reg_read_4(SH4_ITLB_DA2 | e);
|
||||
printf(" %c %d\n",
|
||||
db_printf(" %c %d\n",
|
||||
ON(r, SH4_ITLB_DA2_TC),
|
||||
r & SH4_ITLB_DA2_SA_MASK);
|
||||
}
|
||||
/* Dump UTLB */
|
||||
printf("---UTLB DUMP---\n%s TC SA\n%s\n", title, title2);
|
||||
db_printf("---UTLB DUMP---\n%s TC SA\n%s\n", title, title2);
|
||||
for (i = 0; i < 64; i++) {
|
||||
e = i << SH4_UTLB_E_SHIFT;
|
||||
r = _reg_read_4(SH4_UTLB_AA | e);
|
||||
printf("0x%08x %3d",
|
||||
db_printf("0x%08x %3d",
|
||||
r & SH4_UTLB_AA_VPN_MASK,
|
||||
r & SH4_UTLB_AA_ASID_MASK);
|
||||
r = _reg_read_4(SH4_UTLB_DA1 | e);
|
||||
__db_tlbdump_pfn(r);
|
||||
printf(" %c%c%c%c%c %s ",
|
||||
db_printf(" %c%c%c%c%c %s ",
|
||||
ON(r, SH4_UTLB_DA1_V),
|
||||
ON(r, SH4_UTLB_DA1_D),
|
||||
ON(r, SH4_UTLB_DA1_C),
|
||||
|
@ -293,7 +306,7 @@ db_tlbdump_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
|
|||
);
|
||||
__db_tlbdump_page_size_sh4(r);
|
||||
r = _reg_read_4(SH4_UTLB_DA2 | e);
|
||||
printf(" %c %d\n",
|
||||
db_printf(" %c %d\n",
|
||||
ON(r, SH4_UTLB_DA2_TC),
|
||||
r & SH4_UTLB_DA2_SA_MASK);
|
||||
}
|
||||
|
@ -305,7 +318,7 @@ __db_tlbdump_pfn(u_int32_t r)
|
|||
{
|
||||
u_int32_t pa = (r & SH3_MMUDA_D_PPN_MASK);
|
||||
|
||||
printf(" 0x%08x %d", pa, (pa >> 26) & 7);
|
||||
db_printf(" 0x%08x %d", pa, (pa >> 26) & 7);
|
||||
}
|
||||
|
||||
#ifdef SH4
|
||||
|
@ -314,16 +327,16 @@ __db_tlbdump_page_size_sh4(u_int32_t r)
|
|||
{
|
||||
switch (r & SH4_PTEL_SZ_MASK) {
|
||||
case SH4_PTEL_SZ_1K:
|
||||
printf(" 1K");
|
||||
db_printf(" 1K");
|
||||
break;
|
||||
case SH4_PTEL_SZ_4K:
|
||||
printf(" 4K");
|
||||
db_printf(" 4K");
|
||||
break;
|
||||
case SH4_PTEL_SZ_64K:
|
||||
printf("64K");
|
||||
db_printf("64K");
|
||||
break;
|
||||
case SH4_PTEL_SZ_1M:
|
||||
printf(" 1M");
|
||||
db_printf(" 1M");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -363,20 +376,20 @@ __db_cachedump_sh3(vaddr_t va_start)
|
|||
va_end = sh_cache_way_size;
|
||||
}
|
||||
|
||||
printf("%d-way, way-size=%dB, way-shift=%d, entry-mask=%08x, "
|
||||
db_printf("%d-way, way-size=%dB, way-shift=%d, entry-mask=%08x, "
|
||||
"line-size=%dB \n", sh_cache_ways, sh_cache_way_size,
|
||||
sh_cache_way_shift, sh_cache_entry_mask, sh_cache_line_size);
|
||||
printf("Entry Way 0 UV Way 1 UV Way 2 UV Way 3 UV\n");
|
||||
db_printf("Entry Way 0 UV Way 1 UV Way 2 UV Way 3 UV\n");
|
||||
for (; va < va_end; va += sh_cache_line_size) {
|
||||
entry = va & sh_cache_entry_mask;
|
||||
cca = SH3_CCA | entry;
|
||||
printf(" %3d ", entry >> CCA_ENTRY_SHIFT);
|
||||
db_printf(" %3d ", entry >> CCA_ENTRY_SHIFT);
|
||||
for (way = 0; way < sh_cache_ways; way++) {
|
||||
r = _reg_read_4(cca | (way << sh_cache_way_shift));
|
||||
printf("%08x %c%c ", r & CCA_TAGADDR_MASK,
|
||||
db_printf("%08x %c%c ", r & CCA_TAGADDR_MASK,
|
||||
ON(r, CCA_U), ON(r, CCA_V));
|
||||
}
|
||||
printf("\n");
|
||||
db_printf("\n");
|
||||
}
|
||||
|
||||
/* enable cache */
|
||||
|
@ -408,27 +421,27 @@ __db_cachedump_sh4(vaddr_t va)
|
|||
iend = SH4_ICACHE_SIZE / SH4_CACHE_LINESZ;
|
||||
}
|
||||
|
||||
printf("[I-cache]\n");
|
||||
printf(" Entry V V V V\n");
|
||||
db_printf("[I-cache]\n");
|
||||
db_printf(" Entry V V V V\n");
|
||||
for (i = istart; i < iend; i++) {
|
||||
if ((i & 3) == 0)
|
||||
printf("\n[%3d-%3d] ", i, i + 3);
|
||||
db_printf("\n[%3d-%3d] ", i, i + 3);
|
||||
r = _reg_read_4(SH4_CCIA | (i << CCIA_ENTRY_SHIFT));
|
||||
printf("%08x _%c ", r & CCIA_TAGADDR_MASK, ON(r, CCIA_V));
|
||||
db_printf("%08x _%c ", r & CCIA_TAGADDR_MASK, ON(r, CCIA_V));
|
||||
}
|
||||
|
||||
printf("\n[D-cache]\n");
|
||||
printf(" Entry UV UV UV UV\n");
|
||||
db_printf("\n[D-cache]\n");
|
||||
db_printf(" Entry UV UV UV UV\n");
|
||||
for (i = istart; i < iend; i++) {
|
||||
if ((i & 3) == 0)
|
||||
printf("\n[%3d-%3d] ", i, i + 3);
|
||||
db_printf("\n[%3d-%3d] ", i, i + 3);
|
||||
e = (i << CCDA_ENTRY_SHIFT);
|
||||
r = _reg_read_4(SH4_CCDA | e);
|
||||
printf("%08x %c%c ", r & CCDA_TAGADDR_MASK, ON(r, CCDA_U),
|
||||
db_printf("%08x %c%c ", r & CCDA_TAGADDR_MASK, ON(r, CCDA_U),
|
||||
ON(r, CCDA_V));
|
||||
|
||||
}
|
||||
printf("\n");
|
||||
db_printf("\n");
|
||||
|
||||
_reg_write_4(SH4_CCR,
|
||||
_reg_read_4(SH4_CCR) | SH4_CCR_ICE | SH4_CCR_OCE);
|
||||
|
@ -438,4 +451,133 @@ __db_cachedump_sh4(vaddr_t va)
|
|||
}
|
||||
#endif /* SH4 */
|
||||
#undef ON
|
||||
|
||||
void
|
||||
db_frame_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
|
||||
{
|
||||
struct switchframe *sf = &curpcb->pcb_sf;
|
||||
struct trapframe *tf, *tftop;
|
||||
|
||||
/* Print switch frame */
|
||||
db_printf("[switch frame]\n");
|
||||
#define SF(x) db_printf("sf_" #x "\t\t0x%08x\t", sf->sf_ ## x); \
|
||||
__db_print_symbol(sf->sf_ ## x)
|
||||
SF(ppl);
|
||||
SF(r15);
|
||||
SF(r14);
|
||||
SF(r13);
|
||||
SF(r12);
|
||||
SF(r11);
|
||||
SF(r10);
|
||||
SF(r9);
|
||||
SF(r8);
|
||||
SF(pr);
|
||||
#undef SF
|
||||
db_printf("sf_r6_bank\t0x%08x\n", sf->sf_r6_bank);
|
||||
db_printf("pcb_fp 0x%08lx\n", curpcb->pcb_fp);
|
||||
db_printf("pcb_sp 0x%08lx\n", curpcb->pcb_sp);
|
||||
db_printf("pageDirReg 0x%08x\n", curpcb->pageDirReg);
|
||||
db_printf("pcb_pmap %p\n", curpcb->pcb_pmap);
|
||||
|
||||
tftop = (struct trapframe *)curpcb->pcb_fp;
|
||||
|
||||
/* Print trap frame stack */
|
||||
db_printf("[trap frame]\n");
|
||||
__asm__ __volatile__("stc r6_bank, %0" :: "r"(tf));
|
||||
for (; tf != tftop; tf++) {
|
||||
db_printf("-- %p-%p --\n", tf, tf + 1);
|
||||
db_printf("tf_trapno\t0x%08x\n", tf->tf_trapno);
|
||||
#define TF(x) db_printf("tf_" #x "\t\t0x%08x\t", tf->tf_ ## x); \
|
||||
__db_print_symbol(tf->tf_ ## x)
|
||||
TF(ubc);
|
||||
TF(spc);
|
||||
TF(ssr);
|
||||
TF(macl);
|
||||
TF(mach);
|
||||
TF(pr);
|
||||
TF(r13);
|
||||
TF(r12);
|
||||
TF(r11);
|
||||
TF(r10);
|
||||
TF(r9);
|
||||
TF(r8);
|
||||
TF(r7);
|
||||
TF(r6);
|
||||
TF(r5);
|
||||
TF(r4);
|
||||
TF(r3);
|
||||
TF(r2);
|
||||
TF(r1);
|
||||
TF(r0);
|
||||
TF(r15);
|
||||
TF(r14);
|
||||
#undef TF
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
__db_print_symbol(db_expr_t value)
|
||||
{
|
||||
char *name;
|
||||
db_expr_t offset;
|
||||
|
||||
db_find_xtrn_sym_and_offset((db_addr_t)value, &name, &offset);
|
||||
if (name != 0 && offset <= db_maxoff && offset != value) {
|
||||
db_printf("%s", name);
|
||||
if (offset != 0) {
|
||||
char tbuf[24];
|
||||
|
||||
db_format_radix(tbuf, 24, offset, TRUE);
|
||||
db_printf("+%s", tbuf);
|
||||
}
|
||||
}
|
||||
db_printf("\n");
|
||||
}
|
||||
|
||||
#ifdef KSTACK_DEBUG
|
||||
/*
|
||||
* Stack overflow check
|
||||
*/
|
||||
void
|
||||
db_stackcheck_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
|
||||
{
|
||||
struct proc *p;
|
||||
struct user *u;
|
||||
struct pcb *pcb;
|
||||
u_int32_t *t32;
|
||||
u_int8_t *t8;
|
||||
int i, j;
|
||||
#define MAX_STACK (USPACE - NBPG)
|
||||
#define MAX_FRAME (NBPG - sizeof(struct user))
|
||||
db_printf("stack max: %d byte, frame max %d byte,"
|
||||
" sizeof(struct trapframe) %d byte\n", MAX_STACK, MAX_FRAME,
|
||||
sizeof(struct trapframe));
|
||||
db_printf("PID stack top max used frame top max used"
|
||||
" nest\n");
|
||||
LIST_FOREACH(p, &allproc, p_list) {
|
||||
u = p->p_addr;
|
||||
pcb = &u->u_pcb;
|
||||
/* stack */
|
||||
t32 = (u_int32_t *)(pcb->pcb_sp - MAX_STACK);
|
||||
for (i = 0; *t32++ == 0xa5a5a5a5; i++)
|
||||
;
|
||||
i = MAX_STACK - i * sizeof(int);
|
||||
|
||||
/* frame */
|
||||
t8 = (u_int8_t *)(pcb->pcb_fp - MAX_FRAME);
|
||||
for (j = 0; *t8++ == 0x5a; j++)
|
||||
;
|
||||
j = MAX_FRAME - j;
|
||||
|
||||
db_printf("%-6d 0x%08lx %6d (%3d%%) 0x%08lx %6d (%3d%%) %d %s\n",
|
||||
p->p_pid,
|
||||
pcb->pcb_sp, i, i * 100 / MAX_STACK,
|
||||
pcb->pcb_fp, j, j * 100 / MAX_FRAME,
|
||||
j / sizeof(struct trapframe),
|
||||
p->p_comm);
|
||||
}
|
||||
#undef MAX_STACK
|
||||
#undef MAX_FRAME
|
||||
}
|
||||
#endif /* KSTACK_DEBUG */
|
||||
#endif /* !KGDB */
|
||||
|
|
Loading…
Reference in New Issue