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