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