Home | History | Annotate | Line # | Download | only in powerpc
db_interface.c revision 1.9.2.1
      1  1.9.2.1   nathanw /*	$NetBSD: db_interface.c,v 1.9.2.1 2001/06/21 19:32:28 nathanw Exp $ */
      2      1.1  sakamoto /*	$OpenBSD: db_interface.c,v 1.2 1996/12/28 06:21:50 rahnds Exp $	*/
      3      1.3  jonathan 
      4  1.9.2.1   nathanw #define USERACC
      5  1.9.2.1   nathanw 
      6      1.3  jonathan #include "opt_ddb.h"
      7  1.9.2.1   nathanw #include "opt_ppcarch.h"
      8      1.1  sakamoto 
      9      1.1  sakamoto #include <sys/param.h>
     10      1.1  sakamoto #include <sys/proc.h>
     11      1.4    tsubai #include <sys/systm.h>
     12      1.6    kleink 
     13      1.7    tsubai #include <machine/db_machdep.h>
     14      1.7    tsubai #include <machine/frame.h>
     15  1.9.2.1   nathanw #ifdef PPC_IBM4XX
     16  1.9.2.1   nathanw #include <machine/tlb.h>
     17  1.9.2.1   nathanw #include <powerpc/spr.h>
     18  1.9.2.1   nathanw #include <uvm/uvm_extern.h>
     19  1.9.2.1   nathanw #endif
     20      1.7    tsubai 
     21      1.6    kleink #include <ddb/db_sym.h>
     22      1.6    kleink #include <ddb/db_command.h>
     23      1.6    kleink #include <ddb/db_extern.h>
     24      1.6    kleink #include <ddb/db_access.h>
     25      1.6    kleink #include <ddb/db_output.h>
     26      1.6    kleink #include <ddb/ddbvar.h>
     27      1.1  sakamoto 
     28      1.8    tsubai extern label_t *db_recover;
     29      1.8    tsubai 
     30  1.9.2.1   nathanw void ddb_trap(void);				/* Call into trap_subr.S */
     31  1.9.2.1   nathanw int ddb_trap_glue(struct trapframe *);		/* Called from trap_subr.S */
     32  1.9.2.1   nathanw #ifdef PPC_IBM4XX
     33  1.9.2.1   nathanw static void db_ppc4xx_ctx(db_expr_t, int, db_expr_t, char *);
     34  1.9.2.1   nathanw static void db_ppc4xx_pv(db_expr_t, int, db_expr_t, char *);
     35  1.9.2.1   nathanw static void db_ppc4xx_reset(db_expr_t, int, db_expr_t, char *);
     36  1.9.2.1   nathanw static void db_ppc4xx_tf(db_expr_t, int, db_expr_t, char *);
     37  1.9.2.1   nathanw static void db_ppc4xx_dumptlb(db_expr_t, int, db_expr_t, char *);
     38  1.9.2.1   nathanw #ifdef USERACC
     39  1.9.2.1   nathanw static void db_ppc4xx_useracc(db_expr_t, int, db_expr_t, char *);
     40  1.9.2.1   nathanw #endif
     41  1.9.2.1   nathanw #endif /* PPC_IBM4XX */
     42      1.9    briggs 
     43      1.1  sakamoto void
     44      1.5  jdolecek cpu_Debugger()
     45      1.1  sakamoto {
     46      1.1  sakamoto 	ddb_trap();
     47      1.1  sakamoto }
     48      1.1  sakamoto 
     49      1.1  sakamoto int
     50      1.1  sakamoto ddb_trap_glue(frame)
     51      1.1  sakamoto 	struct trapframe *frame;
     52      1.1  sakamoto {
     53      1.1  sakamoto 	if (!(frame->srr1 & PSL_PR)
     54      1.1  sakamoto 	    && (frame->exc == EXC_TRC
     55      1.1  sakamoto 		|| (frame->exc == EXC_PGM
     56      1.1  sakamoto 		    && (frame->srr1 & 0x20000))
     57      1.1  sakamoto 		|| frame->exc == EXC_BPT)) {
     58      1.1  sakamoto 
     59      1.2   mycroft 		bcopy(frame->fixreg, DDB_REGS->r, 32 * sizeof(u_int32_t));
     60      1.2   mycroft 		DDB_REGS->iar = frame->srr0;
     61      1.2   mycroft 		DDB_REGS->msr = frame->srr1;
     62      1.1  sakamoto 
     63      1.1  sakamoto 		db_trap(T_BREAKPOINT, 0);
     64      1.2   mycroft 
     65      1.2   mycroft 		bcopy(DDB_REGS->r, frame->fixreg, 32 * sizeof(u_int32_t));
     66      1.1  sakamoto 
     67      1.1  sakamoto 		return 1;
     68      1.1  sakamoto 	}
     69      1.1  sakamoto 	return 0;
     70      1.8    tsubai }
     71      1.8    tsubai 
     72      1.8    tsubai int
     73      1.8    tsubai kdb_trap(type, v)
     74      1.8    tsubai 	int type;
     75      1.8    tsubai 	void *v;
     76      1.8    tsubai {
     77      1.8    tsubai 	struct trapframe *frame = v;
     78      1.8    tsubai 
     79      1.8    tsubai 	switch (type) {
     80      1.8    tsubai 	case T_BREAKPOINT:
     81      1.8    tsubai 	case -1:
     82      1.8    tsubai 		break;
     83      1.8    tsubai 	default:
     84      1.8    tsubai 		if (!db_onpanic && db_recover == 0)
     85      1.8    tsubai 			return 0;
     86      1.8    tsubai 		if (db_recover != 0) {
     87      1.8    tsubai 			db_error("Faulted in DDB; continuing...\n");
     88      1.8    tsubai 			/*NOTREACHED*/
     89      1.8    tsubai 		}
     90      1.8    tsubai 	}
     91      1.8    tsubai 
     92      1.8    tsubai 	/* XXX Should switch to kdb's own stack here. */
     93      1.8    tsubai 
     94      1.8    tsubai 	bcopy(frame->fixreg, DDB_REGS->r, 32 * sizeof(u_int32_t));
     95      1.8    tsubai 	DDB_REGS->iar = frame->srr0;
     96      1.8    tsubai 	DDB_REGS->msr = frame->srr1;
     97  1.9.2.1   nathanw #ifdef PPC_IBM4XX
     98  1.9.2.1   nathanw 	DDB_REGS->lr = frame->lr;
     99  1.9.2.1   nathanw 	DDB_REGS->ctr = frame->ctr;
    100  1.9.2.1   nathanw 	DDB_REGS->cr = frame->cr;
    101  1.9.2.1   nathanw 	DDB_REGS->xer = frame->xer;
    102  1.9.2.1   nathanw 	DDB_REGS->dear = frame->dear;
    103  1.9.2.1   nathanw 	DDB_REGS->esr = frame->esr;
    104  1.9.2.1   nathanw 	DDB_REGS->pid = frame->pid;
    105  1.9.2.1   nathanw #endif
    106      1.8    tsubai 
    107      1.8    tsubai 	db_trap(T_BREAKPOINT, 0);
    108      1.8    tsubai 
    109      1.8    tsubai 	bcopy(DDB_REGS->r, frame->fixreg, 32 * sizeof(u_int32_t));
    110      1.8    tsubai 	frame->srr0 = DDB_REGS->iar;
    111      1.8    tsubai 	frame->srr1 = DDB_REGS->msr;
    112  1.9.2.1   nathanw #ifdef PPC_IBM4XX
    113  1.9.2.1   nathanw 	frame->lr = DDB_REGS->lr;
    114  1.9.2.1   nathanw 	frame->ctr = DDB_REGS->ctr;
    115  1.9.2.1   nathanw 	frame->cr = DDB_REGS->cr;
    116  1.9.2.1   nathanw 	frame->xer = DDB_REGS->xer;
    117  1.9.2.1   nathanw 	frame->dear = DDB_REGS->dear;
    118  1.9.2.1   nathanw 	frame->esr = DDB_REGS->esr;
    119  1.9.2.1   nathanw 	frame->pid = DDB_REGS->pid;
    120  1.9.2.1   nathanw #endif
    121      1.8    tsubai 
    122      1.8    tsubai 	return 1;
    123      1.1  sakamoto }
    124  1.9.2.1   nathanw 
    125  1.9.2.1   nathanw #ifdef PPC_IBM4XX
    126  1.9.2.1   nathanw const struct db_command db_machine_command_table[] = {
    127  1.9.2.1   nathanw 	{ "ctx",	db_ppc4xx_ctx,		0,	0 },
    128  1.9.2.1   nathanw 	{ "pv",		db_ppc4xx_pv,		0,	0 },
    129  1.9.2.1   nathanw 	{ "reset",	db_ppc4xx_reset,	0,	0 },
    130  1.9.2.1   nathanw 	{ "tf",		db_ppc4xx_tf,	0,	0 },
    131  1.9.2.1   nathanw 	{ "tlb",	db_ppc4xx_dumptlb,	0,	0 },
    132  1.9.2.1   nathanw #ifdef USERACC
    133  1.9.2.1   nathanw 	{ "user",	db_ppc4xx_useracc,	0,	0 },
    134  1.9.2.1   nathanw #endif
    135  1.9.2.1   nathanw 	{ NULL, }
    136  1.9.2.1   nathanw };
    137  1.9.2.1   nathanw 
    138  1.9.2.1   nathanw static void
    139  1.9.2.1   nathanw db_ppc4xx_ctx(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
    140  1.9.2.1   nathanw {
    141  1.9.2.1   nathanw 	struct proc *p;
    142  1.9.2.1   nathanw 
    143  1.9.2.1   nathanw 	/* XXX LOCKING XXX */
    144  1.9.2.1   nathanw 	for (p = allproc.lh_first; p != 0; p = p->p_list.le_next) {
    145  1.9.2.1   nathanw 		if (p->p_stat) {
    146  1.9.2.1   nathanw 			db_printf("process %p:", p);
    147  1.9.2.1   nathanw 			db_printf("pid:%d pmap:%p ctx:%d %s\n",
    148  1.9.2.1   nathanw 				p->p_pid, p->p_vmspace->vm_map.pmap,
    149  1.9.2.1   nathanw 				p->p_vmspace->vm_map.pmap->pm_ctx,
    150  1.9.2.1   nathanw 				p->p_comm);
    151  1.9.2.1   nathanw 		}
    152  1.9.2.1   nathanw 	}
    153  1.9.2.1   nathanw 	return;
    154  1.9.2.1   nathanw }
    155  1.9.2.1   nathanw 
    156  1.9.2.1   nathanw static void
    157  1.9.2.1   nathanw db_ppc4xx_pv(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
    158  1.9.2.1   nathanw {
    159  1.9.2.1   nathanw 	struct pv_entry {
    160  1.9.2.1   nathanw 		struct pv_entry *pv_next;	/* Linked list of mappings */
    161  1.9.2.1   nathanw 		vaddr_t pv_va;			/* virtual address of mapping */
    162  1.9.2.1   nathanw 		struct pmap *pv_pm;
    163  1.9.2.1   nathanw 	};
    164  1.9.2.1   nathanw 	struct pv_entry *pa_to_pv(paddr_t);
    165  1.9.2.1   nathanw 	struct pv_entry *pv;
    166  1.9.2.1   nathanw 
    167  1.9.2.1   nathanw 	if (!have_addr) {
    168  1.9.2.1   nathanw 		db_printf("pv: <pa>\n");
    169  1.9.2.1   nathanw 		return;
    170  1.9.2.1   nathanw 	}
    171  1.9.2.1   nathanw 	pv = pa_to_pv(addr);
    172  1.9.2.1   nathanw 	db_printf("pv at %p\n", pv);
    173  1.9.2.1   nathanw 	while (pv && pv->pv_pm) {
    174  1.9.2.1   nathanw 		db_printf("next %p va %p pmap %p\n", pv->pv_next,
    175  1.9.2.1   nathanw 			(void *)pv->pv_va, pv->pv_pm);
    176  1.9.2.1   nathanw 		pv = pv->pv_next;
    177  1.9.2.1   nathanw 	}
    178  1.9.2.1   nathanw }
    179  1.9.2.1   nathanw 
    180  1.9.2.1   nathanw static void
    181  1.9.2.1   nathanw db_ppc4xx_reset(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
    182  1.9.2.1   nathanw {
    183  1.9.2.1   nathanw 	printf("Reseting...\n");
    184  1.9.2.1   nathanw 	ppc4xx_reset();
    185  1.9.2.1   nathanw }
    186  1.9.2.1   nathanw 
    187  1.9.2.1   nathanw static void
    188  1.9.2.1   nathanw db_ppc4xx_tf(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
    189  1.9.2.1   nathanw {
    190  1.9.2.1   nathanw 	struct trapframe *f;
    191  1.9.2.1   nathanw 
    192  1.9.2.1   nathanw 
    193  1.9.2.1   nathanw 	if (have_addr) {
    194  1.9.2.1   nathanw 		f = (struct trapframe *)addr;
    195  1.9.2.1   nathanw 
    196  1.9.2.1   nathanw 		db_printf("r0-r3:  \t%8.8x %8.8x %8.8x %8.8x\n",
    197  1.9.2.1   nathanw 			f->fixreg[0], f->fixreg[1],
    198  1.9.2.1   nathanw 			f->fixreg[2], f->fixreg[3]);
    199  1.9.2.1   nathanw 		db_printf("r4-r7:  \t%8.8x %8.8x %8.8x %8.8x\n",
    200  1.9.2.1   nathanw 			f->fixreg[4], f->fixreg[5],
    201  1.9.2.1   nathanw 			f->fixreg[6], f->fixreg[7]);
    202  1.9.2.1   nathanw 		db_printf("r8-r11: \t%8.8x %8.8x %8.8x %8.8x\n",
    203  1.9.2.1   nathanw 			f->fixreg[8], f->fixreg[9],
    204  1.9.2.1   nathanw 			f->fixreg[10], f->fixreg[11]);
    205  1.9.2.1   nathanw 		db_printf("r12-r15:\t%8.8x %8.8x %8.8x %8.8x\n",
    206  1.9.2.1   nathanw 			f->fixreg[12], f->fixreg[13],
    207  1.9.2.1   nathanw 			f->fixreg[14], f->fixreg[15]);
    208  1.9.2.1   nathanw 		db_printf("r16-r19:\t%8.8x %8.8x %8.8x %8.8x\n",
    209  1.9.2.1   nathanw 			f->fixreg[16], f->fixreg[17],
    210  1.9.2.1   nathanw 			f->fixreg[18], f->fixreg[19]);
    211  1.9.2.1   nathanw 		db_printf("r20-r23:\t%8.8x %8.8x %8.8x %8.8x\n",
    212  1.9.2.1   nathanw 			f->fixreg[20], f->fixreg[21],
    213  1.9.2.1   nathanw 			f->fixreg[22], f->fixreg[23]);
    214  1.9.2.1   nathanw 		db_printf("r24-r27:\t%8.8x %8.8x %8.8x %8.8x\n",
    215  1.9.2.1   nathanw 			f->fixreg[24], f->fixreg[25],
    216  1.9.2.1   nathanw 			f->fixreg[26], f->fixreg[27]);
    217  1.9.2.1   nathanw 		db_printf("r28-r31:\t%8.8x %8.8x %8.8x %8.8x\n",
    218  1.9.2.1   nathanw 			f->fixreg[28], f->fixreg[29],
    219  1.9.2.1   nathanw 			f->fixreg[30], f->fixreg[31]);
    220  1.9.2.1   nathanw 
    221  1.9.2.1   nathanw 		db_printf("lr: %8.8x cr: %8.8x xer: %8.8x ctr: %8.8x\n",
    222  1.9.2.1   nathanw 			f->lr, f->cr, f->xer, f->ctr);
    223  1.9.2.1   nathanw 		db_printf("srr0(pc): %8.8x srr1(msr): %8.8x "
    224  1.9.2.1   nathanw 			"dear: %8.8x esr: %8.8x\n",
    225  1.9.2.1   nathanw 			f->srr0, f->srr1, f->dear, f->esr);
    226  1.9.2.1   nathanw 		db_printf("exc: %8.8x pid: %8.8x\n",
    227  1.9.2.1   nathanw 			f->exc, f->pid);
    228  1.9.2.1   nathanw 	}
    229  1.9.2.1   nathanw 	return;
    230  1.9.2.1   nathanw }
    231  1.9.2.1   nathanw 
    232  1.9.2.1   nathanw static const char *const tlbsizes[] = {
    233  1.9.2.1   nathanw 	  "1kB",
    234  1.9.2.1   nathanw 	  "4kB",
    235  1.9.2.1   nathanw 	 "16kB",
    236  1.9.2.1   nathanw 	 "64kB",
    237  1.9.2.1   nathanw 	"256kB",
    238  1.9.2.1   nathanw 	  "1MB",
    239  1.9.2.1   nathanw 	  "4MB",
    240  1.9.2.1   nathanw 	 "16MB"
    241  1.9.2.1   nathanw };
    242  1.9.2.1   nathanw 
    243  1.9.2.1   nathanw static void
    244  1.9.2.1   nathanw db_ppc4xx_dumptlb(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
    245  1.9.2.1   nathanw {
    246  1.9.2.1   nathanw 	int i, zone, tlbsize;
    247  1.9.2.1   nathanw 	u_int zpr, pid, opid, msr;
    248  1.9.2.1   nathanw 	u_long tlblo, tlbhi, tlbmask;
    249  1.9.2.1   nathanw 
    250  1.9.2.1   nathanw 	zpr = mfspr(SPR_ZPR);
    251  1.9.2.1   nathanw 	for (i = 0; i < NTLB; i++) {
    252  1.9.2.1   nathanw 		asm volatile("mfmsr %3;"
    253  1.9.2.1   nathanw 			"mfpid %4;"
    254  1.9.2.1   nathanw 			"li %0,0;"
    255  1.9.2.1   nathanw 			"mtmsr %0;"
    256  1.9.2.1   nathanw 			"sync; isync;"
    257  1.9.2.1   nathanw 			"tlbre %0,%5,1;"
    258  1.9.2.1   nathanw 			"tlbre %1,%5,0;"
    259  1.9.2.1   nathanw 			"mfpid %2;"
    260  1.9.2.1   nathanw 			"mtpid %4;"
    261  1.9.2.1   nathanw 			"mtmsr %3;"
    262  1.9.2.1   nathanw 			"sync; isync"
    263  1.9.2.1   nathanw 			: "=&r" (tlblo), "=&r" (tlbhi), "=r" (pid),
    264  1.9.2.1   nathanw 			"=&r" (msr), "=&r" (opid) : "r" (i));
    265  1.9.2.1   nathanw 
    266  1.9.2.1   nathanw 		if (strchr(modif, 'v') && !(tlbhi & TLB_VALID))
    267  1.9.2.1   nathanw 			continue;
    268  1.9.2.1   nathanw 
    269  1.9.2.1   nathanw 		tlbsize = (tlbhi & TLB_SIZE_MASK) >> TLB_SIZE_SHFT;
    270  1.9.2.1   nathanw 		/* map tlbsize 0 .. 7 to masks for 1kB .. 16MB */
    271  1.9.2.1   nathanw 		tlbmask = ~(1 << (tlbsize * 2 + 10)) + 1;
    272  1.9.2.1   nathanw 
    273  1.9.2.1   nathanw 		if (have_addr && ((tlbhi & tlbmask) != (addr & tlbmask)))
    274  1.9.2.1   nathanw 			continue;
    275  1.9.2.1   nathanw 
    276  1.9.2.1   nathanw 		zone = (tlblo & TLB_ZSEL_MASK) >> TLB_ZSEL_SHFT;
    277  1.9.2.1   nathanw 		db_printf("tlb%c%2d", tlbhi & TLB_VALID ? ' ' : '*', i);
    278  1.9.2.1   nathanw 		db_printf("  PID %3d EPN 0x%08lx %-5s",
    279  1.9.2.1   nathanw 		    pid,
    280  1.9.2.1   nathanw 		    tlbhi & tlbmask,
    281  1.9.2.1   nathanw 		    tlbsizes[tlbsize]);
    282  1.9.2.1   nathanw 		db_printf("  RPN 0x%08lx  ZONE %2d%c  %s %s %c%c%c%c%c %s",
    283  1.9.2.1   nathanw 		    tlblo & tlbmask,
    284  1.9.2.1   nathanw 		    zone,
    285  1.9.2.1   nathanw 		    "NTTA"[(zpr >> ((15 - zone) * 2)) & 3],
    286  1.9.2.1   nathanw 		    tlblo & TLB_EX ? "EX" : "  ",
    287  1.9.2.1   nathanw 		    tlblo & TLB_WR ? "WR" : "  ",
    288  1.9.2.1   nathanw 		    tlblo & TLB_W ? 'W' : ' ',
    289  1.9.2.1   nathanw 		    tlblo & TLB_I ? 'I' : ' ',
    290  1.9.2.1   nathanw 		    tlblo & TLB_M ? 'M' : ' ',
    291  1.9.2.1   nathanw 		    tlblo & TLB_G ? 'G' : ' ',
    292  1.9.2.1   nathanw 		    tlbhi & TLB_ENDIAN ? 'E' : ' ',
    293  1.9.2.1   nathanw 		    tlbhi & TLB_U0 ? "U0" : "  ");
    294  1.9.2.1   nathanw 		db_printf("\n");
    295  1.9.2.1   nathanw 	}
    296  1.9.2.1   nathanw }
    297  1.9.2.1   nathanw 
    298  1.9.2.1   nathanw #ifdef USERACC
    299  1.9.2.1   nathanw static void
    300  1.9.2.1   nathanw db_ppc4xx_useracc(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
    301  1.9.2.1   nathanw {
    302  1.9.2.1   nathanw 	static paddr_t oldaddr = -1;
    303  1.9.2.1   nathanw 	int instr = 0;
    304  1.9.2.1   nathanw 	int data;
    305  1.9.2.1   nathanw 	extern vaddr_t opc_disasm(vaddr_t loc, int);
    306  1.9.2.1   nathanw 
    307  1.9.2.1   nathanw 
    308  1.9.2.1   nathanw 	if (!have_addr) {
    309  1.9.2.1   nathanw 		addr = oldaddr;
    310  1.9.2.1   nathanw 	}
    311  1.9.2.1   nathanw 	if (addr == -1) {
    312  1.9.2.1   nathanw 		db_printf("no address\n");
    313  1.9.2.1   nathanw 		return;
    314  1.9.2.1   nathanw 	}
    315  1.9.2.1   nathanw 	addr &= ~0x3; /* align */
    316  1.9.2.1   nathanw 	{
    317  1.9.2.1   nathanw 		register char c, *cp = modif;
    318  1.9.2.1   nathanw 		while ((c = *cp++) != 0)
    319  1.9.2.1   nathanw 			if (c == 'i')
    320  1.9.2.1   nathanw 				instr = 1;
    321  1.9.2.1   nathanw 	}
    322  1.9.2.1   nathanw 	while (count--) {
    323  1.9.2.1   nathanw 		if (db_print_position() == 0) {
    324  1.9.2.1   nathanw 			/* Always print the address. */
    325  1.9.2.1   nathanw 			db_printf("%8.4lx:\t", addr);
    326  1.9.2.1   nathanw 		}
    327  1.9.2.1   nathanw 		oldaddr=addr;
    328  1.9.2.1   nathanw 		copyin((void *)addr, &data, sizeof(data));
    329  1.9.2.1   nathanw 		if (instr) {
    330  1.9.2.1   nathanw 			opc_disasm(addr, data);
    331  1.9.2.1   nathanw 		} else {
    332  1.9.2.1   nathanw 			db_printf("%4.4x\n", data);
    333  1.9.2.1   nathanw 		}
    334  1.9.2.1   nathanw 		addr += 4;
    335  1.9.2.1   nathanw 		db_end_line();
    336  1.9.2.1   nathanw 	}
    337  1.9.2.1   nathanw 
    338  1.9.2.1   nathanw }
    339  1.9.2.1   nathanw #endif
    340  1.9.2.1   nathanw 
    341  1.9.2.1   nathanw #endif /* PPC_IBM4XX */
    342