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