Home | History | Annotate | Line # | Download | only in powerpc
db_interface.c revision 1.53
      1 /*	$NetBSD: db_interface.c,v 1.53 2015/01/23 07:27:05 nonaka Exp $ */
      2 /*	$OpenBSD: db_interface.c,v 1.2 1996/12/28 06:21:50 rahnds Exp $	*/
      3 
      4 #include <sys/cdefs.h>
      5 __KERNEL_RCSID(0, "$NetBSD: db_interface.c,v 1.53 2015/01/23 07:27:05 nonaka Exp $");
      6 
      7 #define USERACC
      8 
      9 #include "opt_ddb.h"
     10 #include "opt_kgdb.h"
     11 #include "opt_multiprocessor.h"
     12 #include "opt_ppcarch.h"
     13 
     14 #include <sys/param.h>
     15 #include <sys/proc.h>
     16 #include <sys/systm.h>
     17 #include <sys/cpu.h>
     18 #include <sys/atomic.h>
     19 
     20 #include <dev/cons.h>
     21 
     22 #include <powerpc/db_machdep.h>
     23 #include <powerpc/frame.h>
     24 #include <powerpc/spr.h>
     25 #include <powerpc/pte.h>
     26 #include <powerpc/psl.h>
     27 
     28 #if defined (PPC_OEA) || defined(PPC_OEA64) || defined (PPC_OEA64_BRIDGE)
     29 #include <powerpc/oea/spr.h>
     30 #include <powerpc/oea/bat.h>
     31 #include <powerpc/oea/cpufeat.h>
     32 #endif
     33 
     34 #ifdef PPC_IBM4XX
     35 #include <powerpc/ibm4xx/cpu.h>
     36 #include <powerpc/ibm4xx/spr.h>
     37 #include <machine/tlb.h>
     38 #include <uvm/uvm_extern.h>
     39 #endif
     40 
     41 #ifdef PPC_BOOKE
     42 #include <powerpc/booke/cpuvar.h>
     43 #include <powerpc/booke/spr.h>
     44 #endif
     45 
     46 #ifdef DDB
     47 #include <ddb/db_sym.h>
     48 #include <ddb/db_command.h>
     49 #include <ddb/db_extern.h>
     50 #include <ddb/db_access.h>
     51 #include <ddb/db_lex.h>
     52 #include <ddb/db_output.h>
     53 #include <ddb/db_run.h>	/* for db_continue_cmd() proto */
     54 #include <ddb/ddbvar.h>
     55 #endif
     56 
     57 #ifdef KGDB
     58 #include <sys/kgdb.h>
     59 #define db_printf printf
     60 #endif
     61 
     62 #include <dev/ofw/openfirm.h>
     63 
     64 #define NOCPU   ~0
     65 volatile u_int ddb_cpu = NOCPU;
     66 
     67 int	db_active = 0;
     68 
     69 db_regs_t ddb_regs;
     70 
     71 void ddb_trap(void);				/* Call into trap_subr.S */
     72 int ddb_trap_glue(struct trapframe *);		/* Called from trap_subr.S */
     73 #if defined (PPC_OEA) || defined(PPC_OEA64) || defined (PPC_OEA64_BRIDGE)
     74 static void db_show_bat(db_expr_t, bool, db_expr_t, const char *);
     75 static void db_show_mmu(db_expr_t, bool, db_expr_t, const char *);
     76 #endif /* PPC_OEA || PPC_OEA64 || PPC_OEA64_BRIDGE */
     77 #ifdef PPC_IBM4XX
     78 static void db_ppc4xx_ctx(db_expr_t, bool, db_expr_t, const char *);
     79 static void db_ppc4xx_pv(db_expr_t, bool, db_expr_t, const char *);
     80 static void db_ppc4xx_reset(db_expr_t, bool, db_expr_t, const char *);
     81 static void db_ppc4xx_tf(db_expr_t, bool, db_expr_t, const char *);
     82 static void db_ppc4xx_dumptlb(db_expr_t, bool, db_expr_t, const char *);
     83 static void db_ppc4xx_dcr(db_expr_t, bool, db_expr_t, const char *);
     84 static db_expr_t db_ppc4xx_mfdcr(db_expr_t);
     85 static void db_ppc4xx_mtdcr(db_expr_t, db_expr_t);
     86 #ifdef USERACC
     87 static void db_ppc4xx_useracc(db_expr_t, bool, db_expr_t, const char *);
     88 #endif
     89 #endif /* PPC_IBM4XX */
     90 
     91 #ifdef PPC_BOOKE
     92 static void db_ppcbooke_reset(db_expr_t, bool, db_expr_t, const char *);
     93 static void db_ppcbooke_splhist(db_expr_t, bool, db_expr_t, const char *);
     94 static void db_ppcbooke_tf(db_expr_t, bool, db_expr_t, const char *);
     95 static void db_ppcbooke_dumptlb(db_expr_t, bool, db_expr_t, const char *);
     96 #endif
     97 
     98 #ifdef MULTIPROCESSOR
     99 static void db_mach_cpu(db_expr_t, bool, db_expr_t, const char *);
    100 #endif	/* MULTIPROCESSOR */
    101 
    102 #ifdef DDB
    103 const struct db_command db_machine_command_table[] = {
    104 #if defined (PPC_OEA) || defined(PPC_OEA64) || defined (PPC_OEA64_BRIDGE)
    105 	{ DDB_ADD_CMD("bat",	db_show_bat,		0,
    106 	  "Print BAT register translations", NULL,NULL) },
    107 	{ DDB_ADD_CMD("mmu",	db_show_mmu,		0,
    108 	  "Print MMU registers", NULL,NULL) },
    109 #endif /* PPC_OEA || PPC_OEA64 || PPC_OEA64_BRIDGE */
    110 #ifdef PPC_IBM4XX
    111 	{ DDB_ADD_CMD("ctx",	db_ppc4xx_ctx,		0,
    112 	  "Print process MMU context information", NULL,NULL) },
    113 	{ DDB_ADD_CMD("pv",	db_ppc4xx_pv,		0,
    114 	  "Print PA->VA mapping information",
    115 	  "address",
    116 	  "   address:\tphysical address to look up") },
    117 	{ DDB_ADD_CMD("reset",	db_ppc4xx_reset,	0,
    118 	  "Reset the system ", NULL,NULL) },
    119 	{ DDB_ADD_CMD("tf",	db_ppc4xx_tf,		0,
    120 	  "Display the contents of the trapframe",
    121 	  "address",
    122 	  "   address:\tthe struct trapframe to print") },
    123 	{ DDB_ADD_CMD("tlb",	db_ppc4xx_dumptlb,	0,
    124 	  "Display instruction translation storage buffer information.",
    125 	  NULL,NULL) },
    126 	{ DDB_ADD_CMD("dcr",	db_ppc4xx_dcr,		CS_MORE|CS_SET_DOT,
    127 	  "Set the DCR register",
    128 	  "dcr",
    129 	  "   dcr:\tNew DCR value (between 0x0 and 0x3ff)") },
    130 #ifdef USERACC
    131 	{ DDB_ADD_CMD("user",	db_ppc4xx_useracc,	0,
    132 	   "Display user memory.", "[address][,count]",
    133 	   "   address:\tuserspace address to start\n"
    134 	   "   count:\tnumber of bytes to display") },
    135 #endif
    136 #endif /* PPC_IBM4XX */
    137 #ifdef PPC_BOOKE
    138 	{ DDB_ADD_CMD("reset",	db_ppcbooke_reset,	0,
    139 	  "Reset the system ", NULL,NULL) },
    140 	{ DDB_ADD_CMD("tf",	db_ppcbooke_tf,		0,
    141 	  "Display the contents of the trapframe",
    142 	  "address",
    143 	  "   address:\tthe struct trapframe to print") },
    144 	{ DDB_ADD_CMD("splhist", db_ppcbooke_splhist,	0,
    145 	  "Display the splraise/splx splx",
    146 	  NULL, NULL) },
    147 	{ DDB_ADD_CMD("tlb",	db_ppcbooke_dumptlb,	0,
    148 	  "Display instruction translation storage buffer information.",
    149 	  NULL,NULL) },
    150 #endif /* PPC_BOOKE */
    151 
    152 #ifdef MULTIPROCESSOR
    153 	{ DDB_ADD_CMD("cpu",	db_mach_cpu,	0,
    154 	  "switch to another cpu", "cpu-no", NULL) },
    155 #endif	/* MULTIPROCESSOR */
    156 
    157 	{ DDB_ADD_CMD(NULL,	NULL,			0,
    158 	  NULL,NULL,NULL) }
    159 };
    160 
    161 void
    162 cpu_Debugger(void)
    163 {
    164 #ifdef PPC_BOOKE
    165 	const register_t msr = mfmsr();
    166 	__asm volatile("wrteei 0\n\ttweq\t1,1");
    167 	mtmsr(msr);
    168 	__asm volatile("isync");
    169 #else
    170 	ddb_trap();
    171 #endif
    172 }
    173 #endif /* DDB */
    174 
    175 int
    176 ddb_trap_glue(struct trapframe *tf)
    177 {
    178 #if defined(PPC_IBM4XX) || defined(PPC_BOOKE)
    179 	if ((tf->tf_srr1 & PSL_PR) == 0)
    180 		return kdb_trap(tf->tf_exc, tf);
    181 #else /* PPC_OEA */
    182 	if ((tf->tf_srr1 & PSL_PR) == 0 &&
    183 	    (tf->tf_exc == EXC_TRC ||
    184 	     tf->tf_exc == EXC_RUNMODETRC ||
    185 	     (tf->tf_exc == EXC_PGM && (tf->tf_srr1 & 0x20000)) ||
    186 	     tf->tf_exc == EXC_BPT ||
    187 	     tf->tf_exc == EXC_DSI)) {
    188 		int type = tf->tf_exc;
    189 		if (type == EXC_PGM && (tf->tf_srr1 & 0x20000)) {
    190 			type = T_BREAKPOINT;
    191 		}
    192 		return kdb_trap(type, tf);
    193 	}
    194 #endif
    195 	return 0;
    196 }
    197 
    198 int
    199 kdb_trap(int type, void *v)
    200 {
    201 	struct trapframe *tf = v;
    202 	int rv = 1;
    203 	int s;
    204 
    205 #ifdef DDB
    206 	if (db_recover != 0 && (type != -1 && type != T_BREAKPOINT)) {
    207 		db_error("Faulted in DDB; continuing...\n");
    208 		/* NOTREACHED */
    209 	}
    210 #endif
    211 
    212 	/* XXX Should switch to kdb's own stack here. */
    213 
    214 #ifdef MULTIPROCESSOR
    215 	bool first_in_ddb = false;
    216 	const u_int cpu_me = cpu_number();
    217 	const u_int old_ddb_cpu = atomic_cas_uint(&ddb_cpu, NOCPU, cpu_me);
    218 	if (old_ddb_cpu == NOCPU) {
    219 		first_in_ddb = true;
    220 		cpu_pause_others();
    221 	} else {
    222 		if (old_ddb_cpu != cpu_me) {
    223 			KASSERT(cpu_is_paused(cpu_me));
    224 			cpu_pause(tf);
    225 			return 1;
    226 		}
    227 	}
    228 	KASSERT(!cpu_is_paused(cpu_me));
    229 #endif	/* MULTIPROCESSOR */
    230 
    231 	s = splhigh();
    232 	memcpy(DDB_REGS->r, tf->tf_fixreg, 32 * sizeof(u_int32_t));
    233 	DDB_REGS->iar = tf->tf_srr0;
    234 	DDB_REGS->msr = tf->tf_srr1;
    235 	DDB_REGS->lr = tf->tf_lr;
    236 	DDB_REGS->ctr = tf->tf_ctr;
    237 	DDB_REGS->cr = tf->tf_cr;
    238 	DDB_REGS->xer = tf->tf_xer;
    239 #ifdef PPC_OEA
    240 	DDB_REGS->mq = tf->tf_mq;
    241 #elif defined(PPC_IBM4XX) || defined(PPC_BOOKE)
    242 	DDB_REGS->dear = tf->tf_dear;
    243 	DDB_REGS->esr = tf->tf_esr;
    244 	DDB_REGS->pid = tf->tf_pid;
    245 #endif
    246 
    247 #ifdef DDB
    248 	db_active++;
    249 	cnpollc(1);
    250 	db_trap(type, 0);
    251 	cnpollc(0);
    252 	db_active--;
    253 #elif defined(KGDB)
    254 	if (!kgdb_trap(type, DDB_REGS)) {
    255 		rv = 0;
    256 		goto out;
    257 	}
    258 #endif
    259 
    260 	/* KGDB isn't smart about advancing PC if we
    261 	 * take a breakpoint trap after kgdb_active is set.
    262 	 * Therefore, we help out here.
    263 	 */
    264 	if (IS_BREAKPOINT_TRAP(type, 0)) {
    265 		int bkpt;
    266 		db_read_bytes(PC_REGS(DDB_REGS),BKPT_SIZE,(void *)&bkpt);
    267 		if (bkpt== BKPT_INST) {
    268 			PC_REGS(DDB_REGS) += BKPT_SIZE;
    269 		}
    270 	}
    271 
    272 	memcpy(tf->tf_fixreg, DDB_REGS->r, 32 * sizeof(u_int32_t));
    273 	tf->tf_srr0 = DDB_REGS->iar;
    274 	tf->tf_srr1 = DDB_REGS->msr;
    275 	tf->tf_lr = DDB_REGS->lr;
    276 	tf->tf_ctr = DDB_REGS->ctr;
    277 	tf->tf_cr = DDB_REGS->cr;
    278 	tf->tf_xer = DDB_REGS->xer;
    279 #ifdef PPC_OEA
    280 	tf->tf_mq = DDB_REGS->mq;
    281 #endif
    282 #if defined(PPC_IBM4XX) || defined(PPC_BOOKE)
    283 	tf->tf_dear = DDB_REGS->dear;
    284 	tf->tf_esr = DDB_REGS->esr;
    285 	tf->tf_pid = DDB_REGS->pid;
    286 #endif
    287 #ifdef KGDB
    288  out:
    289 #endif	/* KGDB */
    290 	splx(s);
    291 
    292 #ifdef MULTIPROCESSOR
    293 	if (atomic_cas_uint(&ddb_cpu, cpu_me, NOCPU) == cpu_me) {
    294 		cpu_resume_others();
    295 	} else {
    296 		cpu_resume(ddb_cpu);
    297 		if (first_in_ddb)
    298 			cpu_pause(tf);
    299 	}
    300 #endif	/* MULTIPROCESSOR */
    301 
    302 	return rv;
    303 }
    304 
    305 #if defined (PPC_OEA) || defined(PPC_OEA64) || defined (PPC_OEA64_BRIDGE)
    306 static void
    307 print_battranslation(struct bat *bat, unsigned int blidx)
    308 {
    309 	static const char batsizes[][6] = {
    310 		"128KB",
    311 		"256KB",
    312 		"512KB",
    313 		"1MB",
    314 		"2MB",
    315 		"4MB",
    316 		"8MB",
    317 		"16MB",
    318 		"32MB",
    319 		"64MB",
    320 		"128MB",
    321 		"256MB",
    322 		"512MB",
    323 		"1GB",
    324 		"2GB",
    325 		"4GB",
    326 	};
    327 	vsize_t len;
    328 
    329 	len = (0x20000L << blidx) - 1;
    330 	db_printf("\t%08lx %08lx %5s: 0x%08lx..0x%08lx -> 0x%08lx physical\n",
    331 	    bat->batu, bat->batl, batsizes[blidx], bat->batu & ~len,
    332 	    (bat->batu & ~len) + len, bat->batl & ~len);
    333 }
    334 
    335 static void
    336 print_batmodes(register_t super, register_t user, register_t pp)
    337 {
    338 	static const char *const accessmodes[] = {
    339 		"none",
    340 		"ro soft",
    341 		"read/write",
    342 		"read only"
    343 	};
    344 
    345 	db_printf("\tvalid: %c%c  access: %-10s  memory:",
    346 	    super ? 'S' : '-', user ? 'U' : '-', accessmodes[pp]);
    347 }
    348 
    349 static void
    350 print_wimg(register_t wimg)
    351 {
    352 	if (wimg & BAT_W)
    353 		db_printf(" wrthrough");
    354 	if (wimg & BAT_I)
    355 		db_printf(" nocache");
    356 	if (wimg & BAT_M)
    357 		db_printf(" coherent");
    358 	if (wimg & BAT_G)
    359 		db_printf(" guard");
    360 }
    361 
    362 static void
    363 print_bat(struct bat *bat)
    364 {
    365 	if ((bat->batu & BAT_V) == 0) {
    366 		db_printf("\tdisabled\n\n");
    367 		return;
    368 	}
    369 	print_battranslation(bat,
    370 	    30 - __builtin_clz((bat->batu & (BAT_XBL|BAT_BL))|2));
    371 	print_batmodes(bat->batu & BAT_Vs, bat->batu & BAT_Vu,
    372 	    bat->batl & BAT_PP);
    373 	print_wimg(bat->batl & BAT_WIMG);
    374 	db_printf("\n");
    375 }
    376 
    377 #ifdef PPC_OEA601
    378 static void
    379 print_bat601(struct bat *bat)
    380 {
    381 	if ((bat->batl & BAT601_V) == 0) {
    382 		db_printf("\tdisabled\n\n");
    383 		return;
    384 	}
    385 	print_battranslation(bat, 32 - __builtin_clz(bat->batl & BAT601_BSM));
    386 	print_batmodes(bat->batu & BAT601_Ks, bat->batu & BAT601_Ku,
    387 	    bat->batu & BAT601_PP);
    388 	print_wimg(bat->batu & (BAT601_W | BAT601_I | BAT601_M));
    389 	db_printf("\n");
    390 }
    391 #endif
    392 
    393 static void
    394 db_show_bat(db_expr_t addr, bool have_addr, db_expr_t count, const char *modif)
    395 {
    396 	struct bat ibat[8];
    397 	struct bat dbat[8];
    398 	unsigned int cpuvers;
    399 	u_int i;
    400 	u_int maxbat = (oeacpufeat & OEACPU_HIGHBAT) ? 8 : 4;
    401 
    402 	if (oeacpufeat & OEACPU_NOBAT)
    403 		return;
    404 
    405 	cpuvers = mfpvr() >> 16;
    406 
    407 	ibat[0].batu = mfspr(SPR_IBAT0U);
    408 	ibat[0].batl = mfspr(SPR_IBAT0L);
    409 	ibat[1].batu = mfspr(SPR_IBAT1U);
    410 	ibat[1].batl = mfspr(SPR_IBAT1L);
    411 	ibat[2].batu = mfspr(SPR_IBAT2U);
    412 	ibat[2].batl = mfspr(SPR_IBAT2L);
    413 	ibat[3].batu = mfspr(SPR_IBAT3U);
    414 	ibat[3].batl = mfspr(SPR_IBAT3L);
    415 	if (maxbat == 8) {
    416 		ibat[4].batu = mfspr(SPR_IBAT4U);
    417 		ibat[4].batl = mfspr(SPR_IBAT4L);
    418 		ibat[5].batu = mfspr(SPR_IBAT5U);
    419 		ibat[5].batl = mfspr(SPR_IBAT5L);
    420 		ibat[6].batu = mfspr(SPR_IBAT6U);
    421 		ibat[6].batl = mfspr(SPR_IBAT6L);
    422 		ibat[7].batu = mfspr(SPR_IBAT7U);
    423 		ibat[7].batl = mfspr(SPR_IBAT7L);
    424 	}
    425 
    426 	if (cpuvers != MPC601) {
    427 		/* The 601 has only four unified BATs */
    428 		dbat[0].batu = mfspr(SPR_DBAT0U);
    429 		dbat[0].batl = mfspr(SPR_DBAT0L);
    430 		dbat[1].batu = mfspr(SPR_DBAT1U);
    431 		dbat[1].batl = mfspr(SPR_DBAT1L);
    432 		dbat[2].batu = mfspr(SPR_DBAT2U);
    433 		dbat[2].batl = mfspr(SPR_DBAT2L);
    434 		dbat[3].batu = mfspr(SPR_DBAT3U);
    435 		dbat[3].batl = mfspr(SPR_DBAT3L);
    436 		if (maxbat == 8) {
    437 			dbat[4].batu = mfspr(SPR_DBAT4U);
    438 			dbat[4].batl = mfspr(SPR_DBAT4L);
    439 			dbat[5].batu = mfspr(SPR_DBAT5U);
    440 			dbat[5].batl = mfspr(SPR_DBAT5L);
    441 			dbat[6].batu = mfspr(SPR_DBAT6U);
    442 			dbat[6].batl = mfspr(SPR_DBAT6L);
    443 			dbat[7].batu = mfspr(SPR_DBAT7U);
    444 			dbat[7].batl = mfspr(SPR_DBAT7L);
    445 		}
    446 	}
    447 
    448 	for (i = 0; i < maxbat; i++) {
    449 #ifdef PPC_OEA601
    450 		if (cpuvers == MPC601) {
    451 			db_printf("bat[%u]:\n", i);
    452 			print_bat601(&ibat[i]);
    453 		} else
    454 #endif
    455 		{
    456 			db_printf("ibat[%u]:\n", i);
    457 			print_bat(&ibat[i]);
    458 			db_printf("dbat[%u]:\n", i);
    459 			print_bat(&dbat[i]);
    460 		}
    461 	}
    462 }
    463 
    464 static void
    465 db_show_mmu(db_expr_t addr, bool have_addr, db_expr_t count, const char *modif)
    466 {
    467 	paddr_t sdr1;
    468 
    469 	__asm volatile ("mfsdr1 %0" : "=r"(sdr1));
    470 	db_printf("sdr1\t\t0x%08lx\n", sdr1);
    471 
    472 #if defined(PPC_OEA64) || defined(PPC_OEA64_BRIDGE)
    473 	if (oeacpufeat & (OEACPU_64|OEACPU_64_BRIDGE)) {
    474 		__asm volatile ("mfasr %0" : "=r"(sdr1));
    475 		db_printf("asr\t\t0x%08lx\n", sdr1);
    476 	}
    477 #endif
    478 #if defined(PPC_OEA) || defined(PPC_OEA64_BRIDGE)
    479 	if ((oeacpufeat & OEACPU_64) == 0) {
    480 		vaddr_t saddr = 0;
    481 		for (u_int i = 0; i <= 0xf; i++) {
    482 			register_t sr;
    483 			if ((i & 3) == 0)
    484 				db_printf("sr%d-%d\t\t", i, i+3);
    485 			__asm volatile ("mfsrin %0,%1" : "=r"(sr) : "r"(saddr));
    486 			db_printf("0x%08lx   %c", sr, (i&3) == 3 ? '\n' : ' ');
    487 			saddr += 1 << ADDR_SR_SHFT;
    488 		}
    489 	}
    490 #endif
    491 }
    492 #endif /* PPC_OEA || PPC_OEA64 || PPC_OEA64_BRIDGE */
    493 
    494 #if defined(PPC_IBM4XX) || defined(PPC_BOOKE)
    495 db_addr_t
    496 branch_taken(int inst, db_addr_t pc, db_regs_t *regs)
    497 {
    498 
    499 	if ((inst & M_B ) == I_B || (inst & M_B ) == I_BL) {
    500 		db_expr_t off;
    501 		off = ((db_expr_t)((inst & 0x03fffffc) << 6)) >> 6;
    502 		return (((inst & 0x2) ? 0 : pc) + off);
    503 	}
    504 
    505 	if ((inst & M_BC) == I_BC || (inst & M_BC) == I_BCL) {
    506 		db_expr_t off;
    507 		off = ((db_expr_t)((inst & 0x0000fffc) << 16)) >> 16;
    508 		return (((inst & 0x2) ? 0 : pc) + off);
    509 	}
    510 
    511 	if ((inst & M_RTS) == I_RTS || (inst & M_RTS) == I_BLRL)
    512 		return (regs->lr);
    513 
    514 	if ((inst & M_BCTR) == I_BCTR || (inst & M_BCTR) == I_BCTRL)
    515 		return (regs->ctr);
    516 
    517 	db_printf("branch_taken: can't figure out branch target for 0x%x!\n",
    518 	    inst);
    519 	return (0);
    520 }
    521 #endif /* PPC_IBM4XX || PPC_BOOKE */
    522 
    523 
    524 #ifdef PPC_IBM4XX
    525 #ifdef DDB
    526 static void
    527 db_ppc4xx_ctx(db_expr_t addr, bool have_addr, db_expr_t count, const char *modif)
    528 {
    529 	struct proc *p;
    530 
    531 	/* XXX LOCKING XXX */
    532 	for (p = allproc.lh_first; p != 0; p = p->p_list.le_next) {
    533 		if (p->p_stat) {
    534 			db_printf("process %p:", p);
    535 			db_printf("pid:%d pmap:%p ctx:%d %s\n",
    536 				p->p_pid, p->p_vmspace->vm_map.pmap,
    537 				p->p_vmspace->vm_map.pmap->pm_ctx,
    538 				p->p_comm);
    539 		}
    540 	}
    541 	return;
    542 }
    543 
    544 static void
    545 db_ppc4xx_pv(db_expr_t addr, bool have_addr, db_expr_t count, const char *modif)
    546 {
    547 	struct pv_entry {
    548 		struct pv_entry *pv_next;	/* Linked list of mappings */
    549 		vaddr_t pv_va;			/* virtual address of mapping */
    550 		struct pmap *pv_pm;
    551 	};
    552 	struct pv_entry *pa_to_pv(paddr_t);
    553 	struct pv_entry *pv;
    554 
    555 	if (!have_addr) {
    556 		db_printf("pv: <pa>\n");
    557 		return;
    558 	}
    559 	pv = pa_to_pv(addr);
    560 	db_printf("pv at %p\n", pv);
    561 	while (pv && pv->pv_pm) {
    562 		db_printf("next %p va %p pmap %p\n", pv->pv_next,
    563 			(void *)pv->pv_va, pv->pv_pm);
    564 		pv = pv->pv_next;
    565 	}
    566 }
    567 
    568 static void
    569 db_ppc4xx_reset(db_expr_t addr, bool have_addr, db_expr_t count,
    570     const char *modif)
    571 {
    572 	printf("Reseting...\n");
    573 	ppc4xx_reset();
    574 }
    575 
    576 static void
    577 db_ppc4xx_tf(db_expr_t addr, bool have_addr, db_expr_t count, const char *modif)
    578 {
    579 	struct trapframe *tf;
    580 
    581 
    582 	if (have_addr) {
    583 		tf = (struct trapframe *)addr;
    584 
    585 		db_printf("r0-r3:  \t%8.8lx %8.8lx %8.8lx %8.8lx\n",
    586 			tf->tf_fixreg[0], tf->tf_fixreg[1],
    587 			tf->tf_fixreg[2], tf->tf_fixreg[3]);
    588 		db_printf("r4-r7:  \t%8.8lx %8.8lx %8.8lx %8.8lx\n",
    589 			tf->tf_fixreg[4], tf->tf_fixreg[5],
    590 			tf->tf_fixreg[6], tf->tf_fixreg[7]);
    591 		db_printf("r8-r11: \t%8.8lx %8.8lx %8.8lx %8.8lx\n",
    592 			tf->tf_fixreg[8], tf->tf_fixreg[9],
    593 			tf->tf_fixreg[10], tf->tf_fixreg[11]);
    594 		db_printf("r12-r15:\t%8.8lx %8.8lx %8.8lx %8.8lx\n",
    595 			tf->tf_fixreg[12], tf->tf_fixreg[13],
    596 			tf->tf_fixreg[14], tf->tf_fixreg[15]);
    597 		db_printf("r16-r19:\t%8.8lx %8.8lx %8.8lx %8.8lx\n",
    598 			tf->tf_fixreg[16], tf->tf_fixreg[17],
    599 			tf->tf_fixreg[18], tf->tf_fixreg[19]);
    600 		db_printf("r20-r23:\t%8.8lx %8.8lx %8.8lx %8.8lx\n",
    601 			tf->tf_fixreg[20], tf->tf_fixreg[21],
    602 			tf->tf_fixreg[22], tf->tf_fixreg[23]);
    603 		db_printf("r24-r27:\t%8.8lx %8.8lx %8.8lx %8.8lx\n",
    604 			tf->tf_fixreg[24], tf->tf_fixreg[25],
    605 			tf->tf_fixreg[26], tf->tf_fixreg[27]);
    606 		db_printf("r28-r31:\t%8.8lx %8.8lx %8.8lx %8.8lx\n",
    607 			tf->tf_fixreg[28], tf->tf_fixreg[29],
    608 			tf->tf_fixreg[30], tf->tf_fixreg[31]);
    609 
    610 		db_printf("lr: %8.8lx cr: %8.8x xer: %8.8x ctr: %8.8lx\n",
    611 			tf->tf_lr, tf->tf_cr, tf->tf_xer, tf->tf_ctr);
    612 		db_printf("srr0(pc): %8.8lx srr1(msr): %8.8lx "
    613 			"dear: %8.8lx esr: %8.8x\n",
    614 			tf->tf_srr0, tf->tf_srr1, tf->tf_dear, tf->tf_esr);
    615 		db_printf("exc: %8.8x pid: %8.8x\n",
    616 			tf->tf_exc, tf->tf_pid);
    617 	}
    618 	return;
    619 }
    620 
    621 static const char *const tlbsizes[] = {
    622 	  "1kB",
    623 	  "4kB",
    624 	 "16kB",
    625 	 "64kB",
    626 	"256kB",
    627 	  "1MB",
    628 	  "4MB",
    629 	 "16MB"
    630 };
    631 
    632 static void
    633 db_ppc4xx_dumptlb(db_expr_t addr, bool have_addr, db_expr_t count,
    634     const char *modif)
    635 {
    636 	int i, zone, tlbsize;
    637 	u_int zpr, pid, opid, msr;
    638 	u_long tlblo, tlbhi, tlbmask;
    639 
    640 	zpr = mfspr(SPR_ZPR);
    641 	for (i = 0; i < NTLB; i++) {
    642 		__asm volatile("mfmsr %3;"
    643 			"mfpid %4;"
    644 			"li %0,0;"
    645 			"mtmsr %0;"
    646 			"sync; isync;"
    647 			"tlbrelo %0,%5;"
    648 			"tlbrehi %1,%5;"
    649 			"mfpid %2;"
    650 			"mtpid %4;"
    651 			"mtmsr %3;"
    652 			"sync; isync"
    653 			: "=&r" (tlblo), "=&r" (tlbhi), "=r" (pid),
    654 			"=&r" (msr), "=&r" (opid) : "r" (i));
    655 
    656 		if (strchr(modif, 'v') && !(tlbhi & TLB_VALID))
    657 			continue;
    658 
    659 		tlbsize = (tlbhi & TLB_SIZE_MASK) >> TLB_SIZE_SHFT;
    660 		/* map tlbsize 0 .. 7 to masks for 1kB .. 16MB */
    661 		tlbmask = ~(1 << (tlbsize * 2 + 10)) + 1;
    662 
    663 		if (have_addr && ((tlbhi & tlbmask) != (addr & tlbmask)))
    664 			continue;
    665 
    666 		zone = (tlblo & TLB_ZSEL_MASK) >> TLB_ZSEL_SHFT;
    667 		db_printf("tlb%c%2d", tlbhi & TLB_VALID ? ' ' : '*', i);
    668 		db_printf("  PID %3d EPN 0x%08lx %-5s",
    669 		    pid,
    670 		    tlbhi & tlbmask,
    671 		    tlbsizes[tlbsize]);
    672 		db_printf("  RPN 0x%08lx  ZONE %2d%c  %s %s %c%c%c%c%c %s",
    673 		    tlblo & tlbmask,
    674 		    zone,
    675 		    "NTTA"[(zpr >> ((15 - zone) * 2)) & 3],
    676 		    tlblo & TLB_EX ? "EX" : "  ",
    677 		    tlblo & TLB_WR ? "WR" : "  ",
    678 		    tlblo & TLB_W ? 'W' : ' ',
    679 		    tlblo & TLB_I ? 'I' : ' ',
    680 		    tlblo & TLB_M ? 'M' : ' ',
    681 		    tlblo & TLB_G ? 'G' : ' ',
    682 		    tlbhi & TLB_ENDIAN ? 'E' : ' ',
    683 		    tlbhi & TLB_U0 ? "U0" : "  ");
    684 		db_printf("\n");
    685 	}
    686 }
    687 
    688 static void
    689 db_ppc4xx_dcr(db_expr_t address, bool have_addr, db_expr_t count,
    690     const char *modif)
    691 {
    692 	db_expr_t new_value;
    693 	db_expr_t addr;
    694 
    695 	if (address < 0 || address > 0x3ff)
    696 		db_error("Invalid DCR address (Valid range is 0x0 - 0x3ff)\n");
    697 
    698 	addr = address;
    699 
    700 	while (db_expression(&new_value)) {
    701 		db_printf("dcr 0x%lx\t\t%s = ", addr,
    702 		    db_num_to_str(db_ppc4xx_mfdcr(addr)));
    703 		db_ppc4xx_mtdcr(addr, new_value);
    704 		db_printf("%s\n", db_num_to_str(db_ppc4xx_mfdcr(addr)));
    705 		addr += 1;
    706 	}
    707 
    708 	if (addr == address) {
    709 		db_next = (db_addr_t)addr + 1;
    710 		db_prev = (db_addr_t)addr;
    711 		db_printf("dcr 0x%lx\t\t%s\n", addr,
    712 		    db_num_to_str(db_ppc4xx_mfdcr(addr)));
    713 	} else {
    714 		db_next = (db_addr_t)addr;
    715 		db_prev = (db_addr_t)addr - 1;
    716 	}
    717 
    718 	db_skip_to_eol();
    719 }
    720 
    721 /*
    722  * XXX Grossness Alert! XXX
    723  *
    724  * Please look away now if you don't like self-modifying code
    725  */
    726 static u_int32_t db_ppc4xx_dcrfunc[4];
    727 
    728 static db_expr_t
    729 db_ppc4xx_mfdcr(db_expr_t reg)
    730 {
    731 	db_expr_t (*func)(void);
    732 
    733 	reg = (((reg & 0x1f) << 5) | ((reg >> 5) & 0x1f)) << 11;
    734 	db_ppc4xx_dcrfunc[0] = 0x7c0004ac;		/* sync */
    735 	db_ppc4xx_dcrfunc[1] = 0x4c00012c;		/* isync */
    736 	db_ppc4xx_dcrfunc[2] = 0x7c600286 | reg;	/* mfdcr reg, r3 */
    737 	db_ppc4xx_dcrfunc[3] = 0x4e800020;		/* blr */
    738 
    739 	__syncicache((void *)db_ppc4xx_dcrfunc, sizeof(db_ppc4xx_dcrfunc));
    740 	func = (db_expr_t (*)(void))(void *)db_ppc4xx_dcrfunc;
    741 
    742 	return ((*func)());
    743 }
    744 
    745 static void
    746 db_ppc4xx_mtdcr(db_expr_t reg, db_expr_t val)
    747 {
    748 	db_expr_t (*func)(db_expr_t);
    749 
    750 	reg = (((reg & 0x1f) << 5) | ((reg >> 5) & 0x1f)) << 11;
    751 	db_ppc4xx_dcrfunc[0] = 0x7c0004ac;		/* sync */
    752 	db_ppc4xx_dcrfunc[1] = 0x4c00012c;		/* isync */
    753 	db_ppc4xx_dcrfunc[2] = 0x7c600386 | reg;	/* mtdcr r3, reg */
    754 	db_ppc4xx_dcrfunc[3] = 0x4e800020;		/* blr */
    755 
    756 	__syncicache((void *)db_ppc4xx_dcrfunc, sizeof(db_ppc4xx_dcrfunc));
    757 	func = (db_expr_t (*)(db_expr_t))(void *)db_ppc4xx_dcrfunc;
    758 
    759 	(*func)(val);
    760 }
    761 
    762 #ifdef USERACC
    763 static void
    764 db_ppc4xx_useracc(db_expr_t addr, bool have_addr, db_expr_t count,
    765     const char *modif)
    766 {
    767 	static paddr_t oldaddr = -1;
    768 	int instr = 0;
    769 	int data;
    770 	extern vaddr_t opc_disasm(vaddr_t loc, int);
    771 
    772 
    773 	if (!have_addr) {
    774 		addr = oldaddr;
    775 	}
    776 	if (addr == -1) {
    777 		db_printf("no address\n");
    778 		return;
    779 	}
    780 	addr &= ~0x3; /* align */
    781 	{
    782 		const char *cp = modif;
    783 		char c;
    784 		while ((c = *cp++) != 0)
    785 			if (c == 'i')
    786 				instr = 1;
    787 	}
    788 	while (count--) {
    789 		if (db_print_position() == 0) {
    790 			/* Always print the address. */
    791 			db_printf("%8.4lx:\t", addr);
    792 		}
    793 		oldaddr=addr;
    794 		copyin((void *)addr, &data, sizeof(data));
    795 		if (instr) {
    796 			opc_disasm(addr, data);
    797 		} else {
    798 			db_printf("%4.4x\n", data);
    799 		}
    800 		addr += 4;
    801 		db_end_line();
    802 	}
    803 
    804 }
    805 #endif
    806 
    807 #endif /* DDB */
    808 
    809 #endif /* PPC_IBM4XX */
    810 
    811 #ifdef PPC_BOOKE
    812 static void
    813 db_ppcbooke_reset(db_expr_t addr, bool have_addr, db_expr_t count,
    814     const char *modif)
    815 {
    816 	printf("Reseting...\n");
    817 	(*cpu_md_ops.md_cpu_reset)();
    818 }
    819 
    820 static void
    821 db_ppcbooke_splhist(db_expr_t addr, bool have_addr, db_expr_t count,
    822     const char *modif)
    823 {
    824 	dump_splhist(curcpu(), db_printf);
    825 }
    826 
    827 static void
    828 db_ppcbooke_tf(db_expr_t addr, bool have_addr, db_expr_t count,
    829     const char *modif)
    830 {
    831 	if (!have_addr)
    832 		return;
    833 
    834 	dump_trapframe((const struct trapframe *)addr, db_printf);
    835 }
    836 
    837 static void
    838 db_ppcbooke_dumptlb(db_expr_t addr, bool have_addr, db_expr_t count,
    839     const char *modif)
    840 {
    841 	tlb_dump(db_printf);
    842 }
    843 #endif /* PPC_BOOKE */
    844 
    845 #ifdef MULTIPROCESSOR
    846 bool
    847 ddb_running_on_this_cpu_p(void)
    848 {
    849 
    850 	return ddb_cpu == cpu_number();
    851 }
    852 
    853 bool
    854 ddb_running_on_any_cpu_p(void)
    855 {
    856 
    857 	return ddb_cpu != NOCPU;
    858 }
    859 
    860 void
    861 db_resume_others(void)
    862 {
    863 	u_int cpu_me = cpu_number();
    864 
    865 	if (atomic_cas_uint(&ddb_cpu, cpu_me, NOCPU) == cpu_me)
    866 		cpu_resume_others();
    867 }
    868 
    869 static void
    870 db_mach_cpu(db_expr_t addr, bool have_addr, db_expr_t count, const char *modif)
    871 {
    872 	CPU_INFO_ITERATOR cii;
    873 	struct cpu_info *ci;
    874 	bool found = false;
    875 
    876 	if (!have_addr) {
    877 		cpu_debug_dump();
    878 		return;
    879 	}
    880 
    881 	if (addr < 0) {
    882 		db_printf("%ld: CPU out of range\n", addr);
    883 		return;
    884 	}
    885 	for (CPU_INFO_FOREACH(cii, ci)) {
    886 		if (cpu_index(ci) == addr) {
    887 			found = true;
    888 			break;
    889 		}
    890 	}
    891 	if (!found) {
    892 		db_printf("CPU %ld not configured\n", addr);
    893 		return;
    894 	}
    895 	if (ci != curcpu()) {
    896 		if (!cpu_is_paused(cpu_index(ci))) {
    897 			db_printf("CPU %ld not paused\n", (long)addr);
    898 			return;
    899 		}
    900 		(void)atomic_cas_uint(&ddb_cpu, cpu_number(), cpu_index(ci));
    901 		db_continue_cmd(0, false, 0, "");
    902 	}
    903 }
    904 #endif	/* MULTIPROCESSOR */
    905