Home | History | Annotate | Line # | Download | only in powerpc
db_interface.c revision 1.39.20.1
      1  1.39.20.1      yamt /*	$NetBSD: db_interface.c,v 1.39.20.1 2010/03/11 15:02:51 yamt 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.39.20.1      yamt __KERNEL_RCSID(0, "$NetBSD: db_interface.c,v 1.39.20.1 2010/03/11 15:02:51 yamt Exp $");
      6        1.3  jonathan 
      7       1.10    simonb #define USERACC
      8       1.10    simonb 
      9        1.3  jonathan #include "opt_ddb.h"
     10       1.17       dbj #include "opt_kgdb.h"
     11       1.10    simonb #include "opt_ppcarch.h"
     12        1.1  sakamoto 
     13        1.1  sakamoto #include <sys/param.h>
     14        1.1  sakamoto #include <sys/proc.h>
     15        1.4    tsubai #include <sys/systm.h>
     16        1.6    kleink 
     17       1.11    simonb #include <dev/cons.h>
     18       1.11    simonb 
     19        1.7    tsubai #include <machine/db_machdep.h>
     20        1.7    tsubai #include <machine/frame.h>
     21  1.39.20.1      yamt #include <powerpc/spr.h>
     22  1.39.20.1      yamt #include <powerpc/cpu.h>
     23  1.39.20.1      yamt #include <powerpc/bat.h>
     24  1.39.20.1      yamt #include <powerpc/pte.h>
     25  1.39.20.1      yamt 
     26  1.39.20.1      yamt #if defined (PPC_OEA) || defined(PPC_OEA64) || defined (PPC_OEA64_BRIDGE)
     27  1.39.20.1      yamt #include <powerpc/oea/spr.h>
     28  1.39.20.1      yamt #endif
     29  1.39.20.1      yamt 
     30       1.10    simonb #ifdef PPC_IBM4XX
     31  1.39.20.1      yamt #include <powerpc/ibm4xx/spr.h>
     32       1.10    simonb #include <machine/tlb.h>
     33       1.10    simonb #include <uvm/uvm_extern.h>
     34       1.10    simonb #endif
     35        1.7    tsubai 
     36  1.39.20.1      yamt #ifdef PPC_BOOKE
     37  1.39.20.1      yamt #include <powerpc/booke/spr.h>
     38  1.39.20.1      yamt #endif
     39  1.39.20.1      yamt 
     40       1.17       dbj #ifdef DDB
     41        1.6    kleink #include <ddb/db_sym.h>
     42        1.6    kleink #include <ddb/db_command.h>
     43        1.6    kleink #include <ddb/db_extern.h>
     44        1.6    kleink #include <ddb/db_access.h>
     45       1.22       scw #include <ddb/db_lex.h>
     46        1.6    kleink #include <ddb/db_output.h>
     47        1.6    kleink #include <ddb/ddbvar.h>
     48       1.17       dbj #endif
     49       1.17       dbj 
     50       1.17       dbj #ifdef KGDB
     51       1.17       dbj #include <sys/kgdb.h>
     52       1.39   garbled #define db_printf printf
     53       1.17       dbj #endif
     54       1.17       dbj 
     55       1.17       dbj #include <dev/ofw/openfirm.h>
     56        1.1  sakamoto 
     57       1.11    simonb int	db_active = 0;
     58       1.11    simonb 
     59       1.19      matt db_regs_t ddb_regs;
     60        1.8    tsubai 
     61       1.10    simonb void ddb_trap(void);				/* Call into trap_subr.S */
     62       1.10    simonb int ddb_trap_glue(struct trapframe *);		/* Called from trap_subr.S */
     63  1.39.20.1      yamt #if defined (PPC_OEA) || defined(PPC_OEA64) || defined (PPC_OEA64_BRIDGE)
     64  1.39.20.1      yamt static void db_show_bat(db_expr_t, bool, db_expr_t, const char *);
     65  1.39.20.1      yamt static void db_show_mmu(db_expr_t, bool, db_expr_t, const char *);
     66  1.39.20.1      yamt #endif /* PPC_OEA || PPC_OEA64 || PPC_OEA64_BRIDGE */
     67       1.10    simonb #ifdef PPC_IBM4XX
     68       1.37      matt static void db_ppc4xx_ctx(db_expr_t, bool, db_expr_t, const char *);
     69       1.37      matt static void db_ppc4xx_pv(db_expr_t, bool, db_expr_t, const char *);
     70       1.37      matt static void db_ppc4xx_reset(db_expr_t, bool, db_expr_t, const char *);
     71       1.37      matt static void db_ppc4xx_tf(db_expr_t, bool, db_expr_t, const char *);
     72       1.37      matt static void db_ppc4xx_dumptlb(db_expr_t, bool, db_expr_t, const char *);
     73       1.37      matt static void db_ppc4xx_dcr(db_expr_t, bool, db_expr_t, const char *);
     74       1.22       scw static db_expr_t db_ppc4xx_mfdcr(db_expr_t);
     75       1.22       scw static void db_ppc4xx_mtdcr(db_expr_t, db_expr_t);
     76       1.10    simonb #ifdef USERACC
     77       1.37      matt static void db_ppc4xx_useracc(db_expr_t, bool, db_expr_t, const char *);
     78       1.10    simonb #endif
     79       1.10    simonb #endif /* PPC_IBM4XX */
     80        1.9    briggs 
     81       1.17       dbj #ifdef DDB
     82  1.39.20.1      yamt const struct db_command db_machine_command_table[] = {
     83  1.39.20.1      yamt #if defined (PPC_OEA) || defined(PPC_OEA64) || defined (PPC_OEA64_BRIDGE)
     84  1.39.20.1      yamt 	{ DDB_ADD_CMD("bat",	db_show_bat,		0,
     85  1.39.20.1      yamt 	  "Print BAT register translations", NULL,NULL) },
     86  1.39.20.1      yamt 	{ DDB_ADD_CMD("mmu",	db_show_mmu,		0,
     87  1.39.20.1      yamt 	  "Print MMU registers", NULL,NULL) },
     88  1.39.20.1      yamt #endif /* PPC_OEA || PPC_OEA64 || PPC_OEA64_BRIDGE */
     89  1.39.20.1      yamt #ifdef PPC_IBM4XX
     90  1.39.20.1      yamt 	{ DDB_ADD_CMD("ctx",	db_ppc4xx_ctx,		0,
     91  1.39.20.1      yamt 	  "Print process MMU context information", NULL,NULL) },
     92  1.39.20.1      yamt 	{ DDB_ADD_CMD("pv",	db_ppc4xx_pv,		0,
     93  1.39.20.1      yamt 	  "Print PA->VA mapping information",
     94  1.39.20.1      yamt 	  "address",
     95  1.39.20.1      yamt 	  "   address:\tphysical address to look up") },
     96  1.39.20.1      yamt 	{ DDB_ADD_CMD("reset",	db_ppc4xx_reset,	0,
     97  1.39.20.1      yamt 	  "Reset the system ", NULL,NULL) },
     98  1.39.20.1      yamt 	{ DDB_ADD_CMD("tf",	db_ppc4xx_tf,		0,
     99  1.39.20.1      yamt 	  "Display the contents of the trapframe",
    100  1.39.20.1      yamt 	  "address",
    101  1.39.20.1      yamt 	  "   address:\tthe struct trapframe to print") },
    102  1.39.20.1      yamt 	{ DDB_ADD_CMD("tlb",	db_ppc4xx_dumptlb,	0,
    103  1.39.20.1      yamt 	  "Display instruction translation storage buffer information.",
    104  1.39.20.1      yamt 	  NULL,NULL) },
    105  1.39.20.1      yamt 	{ DDB_ADD_CMD("dcr",	db_ppc4xx_dcr,		CS_MORE|CS_SET_DOT,
    106  1.39.20.1      yamt 	  "Set the DCR register",
    107  1.39.20.1      yamt 	  "dcr",
    108  1.39.20.1      yamt 	  "   dcr:\tNew DCR value (between 0x0 and 0x3ff)") },
    109  1.39.20.1      yamt #ifdef USERACC
    110  1.39.20.1      yamt 	{ DDB_ADD_CMD("user",	db_ppc4xx_useracc,	0,
    111  1.39.20.1      yamt 	   "Display user memory.", "[address][,count]",
    112  1.39.20.1      yamt 	   "   address:\tuserspace address to start\n"
    113  1.39.20.1      yamt 	   "   count:\tnumber of bytes to display") },
    114  1.39.20.1      yamt #endif
    115  1.39.20.1      yamt #endif /* PPC_IBM4XX */
    116  1.39.20.1      yamt 	{ DDB_ADD_CMD(NULL,	NULL,			0,
    117  1.39.20.1      yamt 	  NULL,NULL,NULL) }
    118  1.39.20.1      yamt };
    119  1.39.20.1      yamt 
    120        1.1  sakamoto void
    121       1.31      matt cpu_Debugger(void)
    122        1.1  sakamoto {
    123        1.1  sakamoto 	ddb_trap();
    124        1.1  sakamoto }
    125       1.17       dbj #endif
    126        1.1  sakamoto 
    127        1.1  sakamoto int
    128       1.31      matt ddb_trap_glue(struct trapframe *frame)
    129        1.1  sakamoto {
    130       1.25   thorpej #ifdef PPC_IBM4XX
    131       1.25   thorpej 	if ((frame->srr1 & PSL_PR) == 0)
    132       1.25   thorpej 		return kdb_trap(frame->exc, frame);
    133       1.28      matt #else /* PPC_OEA */
    134       1.25   thorpej 	if ((frame->srr1 & PSL_PR) == 0 &&
    135       1.32      matt 	    (frame->exc == EXC_TRC ||
    136       1.32      matt 	     frame->exc == EXC_RUNMODETRC ||
    137       1.25   thorpej 	     (frame->exc == EXC_PGM && (frame->srr1 & 0x20000)) ||
    138       1.32      matt 	     frame->exc == EXC_BPT ||
    139       1.32      matt 	     frame->exc == EXC_DSI)) {
    140       1.17       dbj 		int type = frame->exc;
    141       1.17       dbj 		if (type == EXC_PGM && (frame->srr1 & 0x20000)) {
    142       1.17       dbj 			type = T_BREAKPOINT;
    143       1.17       dbj 		}
    144       1.17       dbj 		return kdb_trap(type, frame);
    145        1.1  sakamoto 	}
    146       1.25   thorpej #endif
    147        1.1  sakamoto 	return 0;
    148        1.8    tsubai }
    149        1.8    tsubai 
    150        1.8    tsubai int
    151       1.31      matt kdb_trap(int type, void *v)
    152        1.8    tsubai {
    153        1.8    tsubai 	struct trapframe *frame = v;
    154        1.8    tsubai 
    155       1.17       dbj #ifdef DDB
    156       1.30      matt 	if (db_recover != 0 && (type != -1 && type != T_BREAKPOINT)) {
    157       1.30      matt 		db_error("Faulted in DDB; continuing...\n");
    158       1.30      matt 		/* NOTREACHED */
    159        1.8    tsubai 	}
    160       1.17       dbj #endif
    161        1.8    tsubai 
    162        1.8    tsubai 	/* XXX Should switch to kdb's own stack here. */
    163        1.8    tsubai 
    164       1.12       wiz 	memcpy(DDB_REGS->r, frame->fixreg, 32 * sizeof(u_int32_t));
    165        1.8    tsubai 	DDB_REGS->iar = frame->srr0;
    166        1.8    tsubai 	DDB_REGS->msr = frame->srr1;
    167       1.10    simonb 	DDB_REGS->lr = frame->lr;
    168       1.10    simonb 	DDB_REGS->ctr = frame->ctr;
    169       1.10    simonb 	DDB_REGS->cr = frame->cr;
    170       1.10    simonb 	DDB_REGS->xer = frame->xer;
    171       1.28      matt #ifdef PPC_OEA
    172       1.27      matt 	DDB_REGS->mq = frame->tf_xtra[TF_MQ];
    173       1.27      matt #endif
    174       1.16       dbj #ifdef PPC_IBM4XX
    175       1.27      matt 	DDB_REGS->dear = frame->dar;
    176       1.27      matt 	DDB_REGS->esr = frame->tf_xtra[TF_ESR];
    177       1.27      matt 	DDB_REGS->pid = frame->tf_xtra[TF_PID];
    178       1.10    simonb #endif
    179        1.8    tsubai 
    180       1.17       dbj #ifdef DDB
    181       1.11    simonb 	db_active++;
    182       1.11    simonb 	cnpollc(1);
    183       1.15       dbj 	db_trap(type, 0);
    184       1.11    simonb 	cnpollc(0);
    185       1.11    simonb 	db_active--;
    186       1.17       dbj #elif defined(KGDB)
    187       1.17       dbj 	if (!kgdb_trap(type, DDB_REGS))
    188       1.17       dbj 		return 0;
    189       1.17       dbj #endif
    190       1.17       dbj 
    191       1.17       dbj 	/* KGDB isn't smart about advancing PC if we
    192       1.17       dbj 	 * take a breakpoint trap after kgdb_active is set.
    193       1.17       dbj 	 * Therefore, we help out here.
    194       1.17       dbj 	 */
    195       1.17       dbj 	if (IS_BREAKPOINT_TRAP(type, 0)) {
    196       1.17       dbj 		int bkpt;
    197       1.17       dbj 		db_read_bytes(PC_REGS(DDB_REGS),BKPT_SIZE,(void *)&bkpt);
    198       1.17       dbj 		if (bkpt== BKPT_INST) {
    199       1.17       dbj 			PC_REGS(DDB_REGS) += BKPT_SIZE;
    200       1.17       dbj 		}
    201       1.17       dbj 	}
    202        1.8    tsubai 
    203       1.12       wiz 	memcpy(frame->fixreg, DDB_REGS->r, 32 * sizeof(u_int32_t));
    204        1.8    tsubai 	frame->srr0 = DDB_REGS->iar;
    205        1.8    tsubai 	frame->srr1 = DDB_REGS->msr;
    206       1.10    simonb 	frame->lr = DDB_REGS->lr;
    207       1.10    simonb 	frame->ctr = DDB_REGS->ctr;
    208       1.10    simonb 	frame->cr = DDB_REGS->cr;
    209       1.10    simonb 	frame->xer = DDB_REGS->xer;
    210       1.28      matt #ifdef PPC_OEA
    211       1.27      matt 	frame->tf_xtra[TF_MQ] = DDB_REGS->mq;
    212       1.27      matt #endif
    213       1.16       dbj #ifdef PPC_IBM4XX
    214       1.27      matt 	frame->dar = DDB_REGS->dear;
    215       1.27      matt 	frame->tf_xtra[TF_ESR] = DDB_REGS->esr;
    216       1.27      matt 	frame->tf_xtra[TF_PID] = DDB_REGS->pid;
    217       1.10    simonb #endif
    218        1.8    tsubai 
    219        1.8    tsubai 	return 1;
    220        1.1  sakamoto }
    221       1.10    simonb 
    222  1.39.20.1      yamt #if defined (PPC_OEA) || defined(PPC_OEA64) || defined (PPC_OEA64_BRIDGE)
    223  1.39.20.1      yamt static void
    224  1.39.20.1      yamt print_battranslation(struct bat *bat, unsigned int blidx)
    225  1.39.20.1      yamt {
    226  1.39.20.1      yamt 	static const char *const batsizes[] = {
    227  1.39.20.1      yamt 		"128kB",
    228  1.39.20.1      yamt 		"256kB",
    229  1.39.20.1      yamt 		"512kB",
    230  1.39.20.1      yamt 		"1MB",
    231  1.39.20.1      yamt 		"2MB",
    232  1.39.20.1      yamt 		"4MB",
    233  1.39.20.1      yamt 		"8MB",
    234  1.39.20.1      yamt 		"16MB",
    235  1.39.20.1      yamt 		"32MB",
    236  1.39.20.1      yamt 		"64MB",
    237  1.39.20.1      yamt 		"128MB",
    238  1.39.20.1      yamt 		"256MB"
    239  1.39.20.1      yamt 	};
    240  1.39.20.1      yamt 	vsize_t len;
    241  1.39.20.1      yamt 
    242  1.39.20.1      yamt 	len = (0x20000L << blidx) - 1;
    243  1.39.20.1      yamt 	db_printf("\t%08lx %08lx %5s: 0x%08lx..0x%08lx -> 0x%08lx physical\n",
    244  1.39.20.1      yamt 	    bat->batu, bat->batl, batsizes[blidx], bat->batu & ~len,
    245  1.39.20.1      yamt 	    (bat->batu & ~len) + len, bat->batl & ~len);
    246  1.39.20.1      yamt }
    247  1.39.20.1      yamt 
    248  1.39.20.1      yamt static void
    249  1.39.20.1      yamt print_batmodes(register_t super, register_t user, register_t pp)
    250  1.39.20.1      yamt {
    251  1.39.20.1      yamt 	static const char *const accessmodes[] = {
    252  1.39.20.1      yamt 		"none",
    253  1.39.20.1      yamt 		"ro soft",
    254  1.39.20.1      yamt 		"read/write",
    255  1.39.20.1      yamt 		"read only"
    256  1.39.20.1      yamt 	};
    257  1.39.20.1      yamt 
    258  1.39.20.1      yamt 	db_printf("\tvalid: %c%c  access: %-10s  memory:",
    259  1.39.20.1      yamt 	    super ? 'S' : '-', user ? 'U' : '-', accessmodes[pp]);
    260  1.39.20.1      yamt }
    261  1.39.20.1      yamt 
    262  1.39.20.1      yamt static void
    263  1.39.20.1      yamt print_wimg(register_t wimg)
    264  1.39.20.1      yamt {
    265  1.39.20.1      yamt 	if (wimg & BAT_W)
    266  1.39.20.1      yamt 		db_printf(" wrthrough");
    267  1.39.20.1      yamt 	if (wimg & BAT_I)
    268  1.39.20.1      yamt 		db_printf(" nocache");
    269  1.39.20.1      yamt 	if (wimg & BAT_M)
    270  1.39.20.1      yamt 		db_printf(" coherent");
    271  1.39.20.1      yamt 	if (wimg & BAT_G)
    272  1.39.20.1      yamt 		db_printf(" guard");
    273  1.39.20.1      yamt }
    274  1.39.20.1      yamt 
    275  1.39.20.1      yamt static void
    276  1.39.20.1      yamt print_bat(struct bat *bat)
    277  1.39.20.1      yamt {
    278  1.39.20.1      yamt 	if ((bat->batu & BAT_V) == 0) {
    279  1.39.20.1      yamt 		db_printf("\tdisabled\n\n");
    280  1.39.20.1      yamt 		return;
    281  1.39.20.1      yamt 	}
    282  1.39.20.1      yamt 	print_battranslation(bat, 30 - __builtin_clz((bat->batu & BAT_BL)|2));
    283  1.39.20.1      yamt 	print_batmodes(bat->batu & BAT_Vs, bat->batu & BAT_Vu,
    284  1.39.20.1      yamt 	    bat->batl & BAT_PP);
    285  1.39.20.1      yamt 	print_wimg(bat->batl & BAT_WIMG);
    286  1.39.20.1      yamt 	db_printf("\n");
    287  1.39.20.1      yamt }
    288  1.39.20.1      yamt 
    289  1.39.20.1      yamt #ifdef PPC_OEA601
    290  1.39.20.1      yamt static void
    291  1.39.20.1      yamt print_bat601(struct bat *bat)
    292  1.39.20.1      yamt {
    293  1.39.20.1      yamt 	if ((bat->batl & BAT601_V) == 0) {
    294  1.39.20.1      yamt 		db_printf("\tdisabled\n\n");
    295  1.39.20.1      yamt 		return;
    296  1.39.20.1      yamt 	}
    297  1.39.20.1      yamt 	print_battranslation(bat, 32 - __builtin_clz(bat->batl & BAT601_BSM));
    298  1.39.20.1      yamt 	print_batmodes(bat->batu & BAT601_Ks, bat->batu & BAT601_Ku,
    299  1.39.20.1      yamt 	    bat->batu & BAT601_PP);
    300  1.39.20.1      yamt 	print_wimg(bat->batu & (BAT601_W | BAT601_I | BAT601_M));
    301  1.39.20.1      yamt 	db_printf("\n");
    302  1.39.20.1      yamt }
    303  1.39.20.1      yamt #endif
    304  1.39.20.1      yamt 
    305  1.39.20.1      yamt static void
    306  1.39.20.1      yamt db_show_bat(db_expr_t addr, bool have_addr, db_expr_t count, const char *modif)
    307  1.39.20.1      yamt {
    308  1.39.20.1      yamt 	struct bat ibat[4];
    309  1.39.20.1      yamt 	struct bat dbat[4];
    310  1.39.20.1      yamt 	unsigned int cpuvers;
    311  1.39.20.1      yamt 	int i;
    312  1.39.20.1      yamt 
    313  1.39.20.1      yamt 	cpuvers = mfpvr() >> 16;
    314  1.39.20.1      yamt 
    315  1.39.20.1      yamt 	__asm volatile ("mfibatu %0,0" : "=r"(ibat[0].batu));
    316  1.39.20.1      yamt 	__asm volatile ("mfibatl %0,0" : "=r"(ibat[0].batl));
    317  1.39.20.1      yamt 	__asm volatile ("mfibatu %0,1" : "=r"(ibat[1].batu));
    318  1.39.20.1      yamt 	__asm volatile ("mfibatl %0,1" : "=r"(ibat[1].batl));
    319  1.39.20.1      yamt 	__asm volatile ("mfibatu %0,2" : "=r"(ibat[2].batu));
    320  1.39.20.1      yamt 	__asm volatile ("mfibatl %0,2" : "=r"(ibat[2].batl));
    321  1.39.20.1      yamt 	__asm volatile ("mfibatu %0,3" : "=r"(ibat[3].batu));
    322  1.39.20.1      yamt 	__asm volatile ("mfibatl %0,3" : "=r"(ibat[3].batl));
    323  1.39.20.1      yamt 
    324  1.39.20.1      yamt 	if (cpuvers != MPC601) {
    325  1.39.20.1      yamt 		/* The 601 has only four unified BATs */
    326  1.39.20.1      yamt 		__asm volatile ("mfdbatu %0,0" : "=r"(dbat[0].batu));
    327  1.39.20.1      yamt 		__asm volatile ("mfdbatl %0,0" : "=r"(dbat[0].batl));
    328  1.39.20.1      yamt 		__asm volatile ("mfdbatu %0,1" : "=r"(dbat[1].batu));
    329  1.39.20.1      yamt 		__asm volatile ("mfdbatl %0,1" : "=r"(dbat[1].batl));
    330  1.39.20.1      yamt 		__asm volatile ("mfdbatu %0,2" : "=r"(dbat[2].batu));
    331  1.39.20.1      yamt 		__asm volatile ("mfdbatl %0,2" : "=r"(dbat[2].batl));
    332  1.39.20.1      yamt 		__asm volatile ("mfdbatu %0,3" : "=r"(dbat[3].batu));
    333  1.39.20.1      yamt 		__asm volatile ("mfdbatl %0,3" : "=r"(dbat[3].batl));
    334  1.39.20.1      yamt 	}
    335  1.39.20.1      yamt 
    336  1.39.20.1      yamt 	for (i = 0; i < 4; i++) {
    337  1.39.20.1      yamt #ifdef PPC_OEA601
    338  1.39.20.1      yamt 		if (cpuvers == MPC601) {
    339  1.39.20.1      yamt 			db_printf("bat%d:", i);
    340  1.39.20.1      yamt 			print_bat601(&ibat[i]);
    341  1.39.20.1      yamt 		} else
    342  1.39.20.1      yamt #endif
    343  1.39.20.1      yamt 		{
    344  1.39.20.1      yamt 			db_printf("ibat%d:", i);
    345  1.39.20.1      yamt 			print_bat(&ibat[i]);
    346  1.39.20.1      yamt 		}
    347  1.39.20.1      yamt 	}
    348  1.39.20.1      yamt 	if (cpuvers != MPC601) {
    349  1.39.20.1      yamt 		for (i = 0; i < 4; i++) {
    350  1.39.20.1      yamt 			db_printf("dbat%d:", i);
    351  1.39.20.1      yamt 			print_bat(&dbat[i]);
    352  1.39.20.1      yamt 		}
    353  1.39.20.1      yamt 	}
    354  1.39.20.1      yamt }
    355  1.39.20.1      yamt 
    356  1.39.20.1      yamt static void
    357  1.39.20.1      yamt db_show_mmu(db_expr_t addr, bool have_addr, db_expr_t count, const char *modif)
    358  1.39.20.1      yamt {
    359  1.39.20.1      yamt 	paddr_t sdr1;
    360  1.39.20.1      yamt #if !defined(PPC_OEA64) && !defined(PPC_OEA64_BRIDGE)
    361  1.39.20.1      yamt 	register_t sr;
    362  1.39.20.1      yamt 	vaddr_t saddr;
    363  1.39.20.1      yamt 	int i;
    364  1.39.20.1      yamt #endif
    365  1.39.20.1      yamt 
    366  1.39.20.1      yamt 	__asm volatile ("mfsdr1 %0" : "=r"(sdr1));
    367  1.39.20.1      yamt 	db_printf("sdr1\t\t0x%08lx\n", sdr1);
    368  1.39.20.1      yamt 
    369  1.39.20.1      yamt #if defined(PPC_OEA64) || defined(PPC_OEA64_BRIDGE)
    370  1.39.20.1      yamt 	__asm volatile ("mfasr %0" : "=r"(sdr1));
    371  1.39.20.1      yamt 	db_printf("asr\t\t0x%08lx\n", sdr1);
    372  1.39.20.1      yamt #else
    373  1.39.20.1      yamt 	saddr = 0;
    374  1.39.20.1      yamt 	for (i = 0; i<= 0xf; i++) {
    375  1.39.20.1      yamt 		if ((i & 3) == 0)
    376  1.39.20.1      yamt 			db_printf("sr%d-%d\t\t", i, i+3);
    377  1.39.20.1      yamt 		__asm volatile ("mfsrin %0,%1" : "=r"(sr) : "r"(saddr));
    378  1.39.20.1      yamt 		db_printf("0x%08lx   %c", sr, (i&3) == 3 ? '\n' : ' ');
    379  1.39.20.1      yamt 		saddr += 1 << ADDR_SR_SHFT;
    380  1.39.20.1      yamt 	}
    381  1.39.20.1      yamt #endif
    382  1.39.20.1      yamt }
    383  1.39.20.1      yamt #endif /* PPC_OEA || PPC_OEA64 || PPC_OEA64_BRIDGE */
    384  1.39.20.1      yamt 
    385       1.10    simonb #ifdef PPC_IBM4XX
    386       1.24       scw db_addr_t
    387       1.24       scw branch_taken(int inst, db_addr_t pc, db_regs_t *regs)
    388       1.24       scw {
    389       1.24       scw 
    390       1.24       scw 	if ((inst & M_B ) == I_B || (inst & M_B ) == I_BL) {
    391       1.24       scw 		db_expr_t off;
    392       1.24       scw 		off = ((db_expr_t)((inst & 0x03fffffc) << 6)) >> 6;
    393       1.24       scw 		return (((inst & 0x2) ? 0 : pc) + off);
    394       1.24       scw 	}
    395       1.24       scw 
    396       1.24       scw 	if ((inst & M_BC) == I_BC || (inst & M_BC) == I_BCL) {
    397       1.24       scw 		db_expr_t off;
    398       1.24       scw 		off = ((db_expr_t)((inst & 0x0000fffc) << 16)) >> 16;
    399       1.24       scw 		return (((inst & 0x2) ? 0 : pc) + off);
    400       1.24       scw 	}
    401       1.24       scw 
    402       1.24       scw 	if ((inst & M_RTS) == I_RTS || (inst & M_RTS) == I_BLRL)
    403       1.24       scw 		return (regs->lr);
    404       1.24       scw 
    405       1.24       scw 	if ((inst & M_BCTR) == I_BCTR || (inst & M_BCTR) == I_BCTRL)
    406       1.24       scw 		return (regs->ctr);
    407       1.24       scw 
    408       1.24       scw 	db_printf("branch_taken: can't figure out branch target for 0x%x!\n",
    409       1.24       scw 	    inst);
    410       1.24       scw 	return (0);
    411       1.24       scw }
    412       1.24       scw 
    413       1.10    simonb 
    414  1.39.20.1      yamt #ifdef DDB
    415       1.10    simonb static void
    416       1.37      matt db_ppc4xx_ctx(db_expr_t addr, bool have_addr, db_expr_t count, const char *modif)
    417       1.10    simonb {
    418       1.10    simonb 	struct proc *p;
    419       1.10    simonb 
    420       1.10    simonb 	/* XXX LOCKING XXX */
    421       1.10    simonb 	for (p = allproc.lh_first; p != 0; p = p->p_list.le_next) {
    422       1.10    simonb 		if (p->p_stat) {
    423       1.10    simonb 			db_printf("process %p:", p);
    424       1.10    simonb 			db_printf("pid:%d pmap:%p ctx:%d %s\n",
    425       1.10    simonb 				p->p_pid, p->p_vmspace->vm_map.pmap,
    426       1.10    simonb 				p->p_vmspace->vm_map.pmap->pm_ctx,
    427       1.10    simonb 				p->p_comm);
    428       1.10    simonb 		}
    429       1.10    simonb 	}
    430       1.10    simonb 	return;
    431       1.10    simonb }
    432       1.10    simonb 
    433       1.10    simonb static void
    434       1.37      matt db_ppc4xx_pv(db_expr_t addr, bool have_addr, db_expr_t count, const char *modif)
    435       1.10    simonb {
    436       1.10    simonb 	struct pv_entry {
    437       1.10    simonb 		struct pv_entry *pv_next;	/* Linked list of mappings */
    438       1.10    simonb 		vaddr_t pv_va;			/* virtual address of mapping */
    439       1.10    simonb 		struct pmap *pv_pm;
    440       1.10    simonb 	};
    441       1.10    simonb 	struct pv_entry *pa_to_pv(paddr_t);
    442       1.10    simonb 	struct pv_entry *pv;
    443       1.10    simonb 
    444       1.10    simonb 	if (!have_addr) {
    445       1.10    simonb 		db_printf("pv: <pa>\n");
    446       1.10    simonb 		return;
    447       1.10    simonb 	}
    448       1.10    simonb 	pv = pa_to_pv(addr);
    449       1.10    simonb 	db_printf("pv at %p\n", pv);
    450       1.10    simonb 	while (pv && pv->pv_pm) {
    451       1.10    simonb 		db_printf("next %p va %p pmap %p\n", pv->pv_next,
    452       1.10    simonb 			(void *)pv->pv_va, pv->pv_pm);
    453       1.10    simonb 		pv = pv->pv_next;
    454       1.10    simonb 	}
    455       1.10    simonb }
    456       1.10    simonb 
    457       1.10    simonb static void
    458       1.37      matt db_ppc4xx_reset(db_expr_t addr, bool have_addr, db_expr_t count,
    459       1.34       scw     const char *modif)
    460       1.10    simonb {
    461       1.10    simonb 	printf("Reseting...\n");
    462       1.10    simonb 	ppc4xx_reset();
    463       1.10    simonb }
    464       1.10    simonb 
    465       1.10    simonb static void
    466       1.37      matt db_ppc4xx_tf(db_expr_t addr, bool have_addr, db_expr_t count, const char *modif)
    467       1.10    simonb {
    468       1.10    simonb 	struct trapframe *f;
    469       1.10    simonb 
    470       1.10    simonb 
    471       1.10    simonb 	if (have_addr) {
    472       1.10    simonb 		f = (struct trapframe *)addr;
    473       1.10    simonb 
    474       1.27      matt 		db_printf("r0-r3:  \t%8.8lx %8.8lx %8.8lx %8.8lx\n",
    475       1.10    simonb 			f->fixreg[0], f->fixreg[1],
    476       1.10    simonb 			f->fixreg[2], f->fixreg[3]);
    477       1.27      matt 		db_printf("r4-r7:  \t%8.8lx %8.8lx %8.8lx %8.8lx\n",
    478       1.10    simonb 			f->fixreg[4], f->fixreg[5],
    479       1.10    simonb 			f->fixreg[6], f->fixreg[7]);
    480       1.27      matt 		db_printf("r8-r11: \t%8.8lx %8.8lx %8.8lx %8.8lx\n",
    481       1.10    simonb 			f->fixreg[8], f->fixreg[9],
    482       1.10    simonb 			f->fixreg[10], f->fixreg[11]);
    483       1.27      matt 		db_printf("r12-r15:\t%8.8lx %8.8lx %8.8lx %8.8lx\n",
    484       1.10    simonb 			f->fixreg[12], f->fixreg[13],
    485       1.10    simonb 			f->fixreg[14], f->fixreg[15]);
    486       1.27      matt 		db_printf("r16-r19:\t%8.8lx %8.8lx %8.8lx %8.8lx\n",
    487       1.10    simonb 			f->fixreg[16], f->fixreg[17],
    488       1.10    simonb 			f->fixreg[18], f->fixreg[19]);
    489       1.27      matt 		db_printf("r20-r23:\t%8.8lx %8.8lx %8.8lx %8.8lx\n",
    490       1.10    simonb 			f->fixreg[20], f->fixreg[21],
    491       1.10    simonb 			f->fixreg[22], f->fixreg[23]);
    492       1.27      matt 		db_printf("r24-r27:\t%8.8lx %8.8lx %8.8lx %8.8lx\n",
    493       1.10    simonb 			f->fixreg[24], f->fixreg[25],
    494       1.10    simonb 			f->fixreg[26], f->fixreg[27]);
    495       1.27      matt 		db_printf("r28-r31:\t%8.8lx %8.8lx %8.8lx %8.8lx\n",
    496       1.10    simonb 			f->fixreg[28], f->fixreg[29],
    497       1.10    simonb 			f->fixreg[30], f->fixreg[31]);
    498       1.10    simonb 
    499       1.27      matt 		db_printf("lr: %8.8lx cr: %8.8x xer: %8.8x ctr: %8.8lx\n",
    500       1.10    simonb 			f->lr, f->cr, f->xer, f->ctr);
    501       1.27      matt 		db_printf("srr0(pc): %8.8lx srr1(msr): %8.8lx "
    502       1.27      matt 			"dear: %8.8lx esr: %8.8x\n",
    503       1.27      matt 			f->srr0, f->srr1, f->dar, f->tf_xtra[TF_ESR]);
    504       1.10    simonb 		db_printf("exc: %8.8x pid: %8.8x\n",
    505       1.27      matt 			f->exc, f->tf_xtra[TF_PID]);
    506       1.10    simonb 	}
    507       1.10    simonb 	return;
    508       1.10    simonb }
    509       1.10    simonb 
    510       1.10    simonb static const char *const tlbsizes[] = {
    511       1.10    simonb 	  "1kB",
    512       1.10    simonb 	  "4kB",
    513       1.10    simonb 	 "16kB",
    514       1.10    simonb 	 "64kB",
    515       1.10    simonb 	"256kB",
    516       1.10    simonb 	  "1MB",
    517       1.10    simonb 	  "4MB",
    518       1.10    simonb 	 "16MB"
    519       1.10    simonb };
    520       1.10    simonb 
    521       1.10    simonb static void
    522       1.37      matt db_ppc4xx_dumptlb(db_expr_t addr, bool have_addr, db_expr_t count,
    523       1.34       scw     const char *modif)
    524       1.10    simonb {
    525       1.10    simonb 	int i, zone, tlbsize;
    526       1.10    simonb 	u_int zpr, pid, opid, msr;
    527       1.10    simonb 	u_long tlblo, tlbhi, tlbmask;
    528       1.10    simonb 
    529       1.10    simonb 	zpr = mfspr(SPR_ZPR);
    530       1.10    simonb 	for (i = 0; i < NTLB; i++) {
    531       1.36     perry 		__asm volatile("mfmsr %3;"
    532       1.10    simonb 			"mfpid %4;"
    533       1.10    simonb 			"li %0,0;"
    534       1.10    simonb 			"mtmsr %0;"
    535       1.10    simonb 			"sync; isync;"
    536       1.21   thorpej 			"tlbrelo %0,%5;"
    537       1.21   thorpej 			"tlbrehi %1,%5;"
    538       1.10    simonb 			"mfpid %2;"
    539       1.10    simonb 			"mtpid %4;"
    540       1.10    simonb 			"mtmsr %3;"
    541       1.10    simonb 			"sync; isync"
    542       1.10    simonb 			: "=&r" (tlblo), "=&r" (tlbhi), "=r" (pid),
    543       1.10    simonb 			"=&r" (msr), "=&r" (opid) : "r" (i));
    544       1.10    simonb 
    545       1.10    simonb 		if (strchr(modif, 'v') && !(tlbhi & TLB_VALID))
    546       1.10    simonb 			continue;
    547       1.10    simonb 
    548       1.10    simonb 		tlbsize = (tlbhi & TLB_SIZE_MASK) >> TLB_SIZE_SHFT;
    549       1.10    simonb 		/* map tlbsize 0 .. 7 to masks for 1kB .. 16MB */
    550       1.10    simonb 		tlbmask = ~(1 << (tlbsize * 2 + 10)) + 1;
    551       1.10    simonb 
    552       1.10    simonb 		if (have_addr && ((tlbhi & tlbmask) != (addr & tlbmask)))
    553       1.10    simonb 			continue;
    554       1.10    simonb 
    555       1.10    simonb 		zone = (tlblo & TLB_ZSEL_MASK) >> TLB_ZSEL_SHFT;
    556       1.10    simonb 		db_printf("tlb%c%2d", tlbhi & TLB_VALID ? ' ' : '*', i);
    557       1.10    simonb 		db_printf("  PID %3d EPN 0x%08lx %-5s",
    558       1.10    simonb 		    pid,
    559       1.10    simonb 		    tlbhi & tlbmask,
    560       1.10    simonb 		    tlbsizes[tlbsize]);
    561       1.10    simonb 		db_printf("  RPN 0x%08lx  ZONE %2d%c  %s %s %c%c%c%c%c %s",
    562       1.10    simonb 		    tlblo & tlbmask,
    563       1.10    simonb 		    zone,
    564       1.10    simonb 		    "NTTA"[(zpr >> ((15 - zone) * 2)) & 3],
    565       1.10    simonb 		    tlblo & TLB_EX ? "EX" : "  ",
    566       1.10    simonb 		    tlblo & TLB_WR ? "WR" : "  ",
    567       1.10    simonb 		    tlblo & TLB_W ? 'W' : ' ',
    568       1.10    simonb 		    tlblo & TLB_I ? 'I' : ' ',
    569       1.10    simonb 		    tlblo & TLB_M ? 'M' : ' ',
    570       1.10    simonb 		    tlblo & TLB_G ? 'G' : ' ',
    571       1.10    simonb 		    tlbhi & TLB_ENDIAN ? 'E' : ' ',
    572       1.10    simonb 		    tlbhi & TLB_U0 ? "U0" : "  ");
    573       1.10    simonb 		db_printf("\n");
    574       1.10    simonb 	}
    575       1.22       scw }
    576       1.22       scw 
    577       1.22       scw static void
    578       1.37      matt db_ppc4xx_dcr(db_expr_t address, bool have_addr, db_expr_t count,
    579       1.34       scw     const char *modif)
    580       1.22       scw {
    581       1.22       scw 	db_expr_t new_value;
    582       1.22       scw 	db_expr_t addr;
    583       1.23       scw 
    584       1.23       scw 	if (address < 0 || address > 0x3ff)
    585       1.23       scw 		db_error("Invalid DCR address (Valid range is 0x0 - 0x3ff)\n");
    586       1.22       scw 
    587       1.22       scw 	addr = address;
    588       1.22       scw 
    589       1.22       scw 	while (db_expression(&new_value)) {
    590       1.22       scw 		db_printf("dcr 0x%lx\t\t%s = ", addr,
    591       1.22       scw 		    db_num_to_str(db_ppc4xx_mfdcr(addr)));
    592       1.22       scw 		db_ppc4xx_mtdcr(addr, new_value);
    593       1.22       scw 		db_printf("%s\n", db_num_to_str(db_ppc4xx_mfdcr(addr)));
    594       1.22       scw 		addr += 1;
    595       1.22       scw 	}
    596       1.22       scw 
    597       1.22       scw 	if (addr == address) {
    598       1.22       scw 		db_next = (db_addr_t)addr + 1;
    599       1.22       scw 		db_prev = (db_addr_t)addr;
    600       1.22       scw 		db_printf("dcr 0x%lx\t\t%s\n", addr,
    601       1.22       scw 		    db_num_to_str(db_ppc4xx_mfdcr(addr)));
    602       1.22       scw 	} else {
    603       1.22       scw 		db_next = (db_addr_t)addr;
    604       1.22       scw 		db_prev = (db_addr_t)addr - 1;
    605       1.22       scw 	}
    606       1.22       scw 
    607       1.22       scw 	db_skip_to_eol();
    608       1.22       scw }
    609       1.22       scw 
    610       1.22       scw /*
    611       1.22       scw  * XXX Grossness Alert! XXX
    612       1.22       scw  *
    613       1.22       scw  * Please look away now if you don't like self-modifying code
    614       1.22       scw  */
    615       1.22       scw static u_int32_t db_ppc4xx_dcrfunc[4];
    616       1.22       scw 
    617       1.22       scw static db_expr_t
    618       1.22       scw db_ppc4xx_mfdcr(db_expr_t reg)
    619       1.22       scw {
    620       1.22       scw 	db_expr_t (*func)(void);
    621       1.22       scw 
    622       1.22       scw 	reg = (((reg & 0x1f) << 5) | ((reg >> 5) & 0x1f)) << 11;
    623       1.22       scw 	db_ppc4xx_dcrfunc[0] = 0x7c0004ac;		/* sync */
    624       1.22       scw 	db_ppc4xx_dcrfunc[1] = 0x4c00012c;		/* isync */
    625       1.22       scw 	db_ppc4xx_dcrfunc[2] = 0x7c600286 | reg;	/* mfdcr reg, r3 */
    626       1.22       scw 	db_ppc4xx_dcrfunc[3] = 0x4e800020;		/* blr */
    627       1.22       scw 
    628       1.22       scw 	__syncicache((void *)db_ppc4xx_dcrfunc, sizeof(db_ppc4xx_dcrfunc));
    629       1.22       scw 	func = (db_expr_t (*)(void))(void *)db_ppc4xx_dcrfunc;
    630       1.22       scw 
    631       1.22       scw 	return ((*func)());
    632       1.22       scw }
    633       1.22       scw 
    634       1.22       scw static void
    635       1.22       scw db_ppc4xx_mtdcr(db_expr_t reg, db_expr_t val)
    636       1.22       scw {
    637       1.22       scw 	db_expr_t (*func)(db_expr_t);
    638       1.22       scw 
    639       1.22       scw 	reg = (((reg & 0x1f) << 5) | ((reg >> 5) & 0x1f)) << 11;
    640       1.22       scw 	db_ppc4xx_dcrfunc[0] = 0x7c0004ac;		/* sync */
    641       1.22       scw 	db_ppc4xx_dcrfunc[1] = 0x4c00012c;		/* isync */
    642       1.22       scw 	db_ppc4xx_dcrfunc[2] = 0x7c600386 | reg;	/* mtdcr r3, reg */
    643       1.22       scw 	db_ppc4xx_dcrfunc[3] = 0x4e800020;		/* blr */
    644       1.22       scw 
    645       1.22       scw 	__syncicache((void *)db_ppc4xx_dcrfunc, sizeof(db_ppc4xx_dcrfunc));
    646       1.22       scw 	func = (db_expr_t (*)(db_expr_t))(void *)db_ppc4xx_dcrfunc;
    647       1.22       scw 
    648       1.22       scw 	(*func)(val);
    649       1.10    simonb }
    650       1.10    simonb 
    651       1.10    simonb #ifdef USERACC
    652       1.10    simonb static void
    653       1.37      matt db_ppc4xx_useracc(db_expr_t addr, bool have_addr, db_expr_t count,
    654       1.34       scw     const char *modif)
    655       1.10    simonb {
    656       1.10    simonb 	static paddr_t oldaddr = -1;
    657       1.10    simonb 	int instr = 0;
    658       1.10    simonb 	int data;
    659       1.10    simonb 	extern vaddr_t opc_disasm(vaddr_t loc, int);
    660       1.10    simonb 
    661       1.10    simonb 
    662       1.10    simonb 	if (!have_addr) {
    663       1.10    simonb 		addr = oldaddr;
    664       1.10    simonb 	}
    665       1.10    simonb 	if (addr == -1) {
    666       1.10    simonb 		db_printf("no address\n");
    667       1.10    simonb 		return;
    668       1.10    simonb 	}
    669       1.10    simonb 	addr &= ~0x3; /* align */
    670       1.10    simonb 	{
    671       1.34       scw 		const char *cp = modif;
    672       1.34       scw 		char c;
    673       1.10    simonb 		while ((c = *cp++) != 0)
    674       1.10    simonb 			if (c == 'i')
    675       1.10    simonb 				instr = 1;
    676       1.10    simonb 	}
    677       1.10    simonb 	while (count--) {
    678       1.10    simonb 		if (db_print_position() == 0) {
    679       1.10    simonb 			/* Always print the address. */
    680       1.10    simonb 			db_printf("%8.4lx:\t", addr);
    681       1.10    simonb 		}
    682       1.10    simonb 		oldaddr=addr;
    683       1.10    simonb 		copyin((void *)addr, &data, sizeof(data));
    684       1.10    simonb 		if (instr) {
    685       1.10    simonb 			opc_disasm(addr, data);
    686       1.10    simonb 		} else {
    687       1.10    simonb 			db_printf("%4.4x\n", data);
    688       1.10    simonb 		}
    689       1.10    simonb 		addr += 4;
    690       1.10    simonb 		db_end_line();
    691       1.10    simonb 	}
    692       1.10    simonb 
    693       1.10    simonb }
    694       1.10    simonb #endif
    695       1.10    simonb 
    696       1.39   garbled #endif /* DDB */
    697       1.39   garbled 
    698       1.10    simonb #endif /* PPC_IBM4XX */
    699