Home | History | Annotate | Line # | Download | only in powerpc
db_interface.c revision 1.12.6.7
      1  1.12.6.7  thorpej /*	$NetBSD: db_interface.c,v 1.12.6.7 2002/12/29 19:35:06 thorpej Exp $ */
      2  1.12.6.2  nathanw /*	$OpenBSD: db_interface.c,v 1.2 1996/12/28 06:21:50 rahnds Exp $	*/
      3  1.12.6.2  nathanw 
      4  1.12.6.2  nathanw #define USERACC
      5  1.12.6.2  nathanw 
      6  1.12.6.2  nathanw #include "opt_ddb.h"
      7  1.12.6.3  nathanw #include "opt_kgdb.h"
      8  1.12.6.2  nathanw #include "opt_ppcarch.h"
      9  1.12.6.2  nathanw 
     10  1.12.6.2  nathanw #include <sys/param.h>
     11  1.12.6.2  nathanw #include <sys/proc.h>
     12  1.12.6.2  nathanw #include <sys/systm.h>
     13  1.12.6.2  nathanw 
     14  1.12.6.2  nathanw #include <dev/cons.h>
     15  1.12.6.2  nathanw 
     16  1.12.6.2  nathanw #include <machine/db_machdep.h>
     17  1.12.6.2  nathanw #include <machine/frame.h>
     18  1.12.6.2  nathanw #ifdef PPC_IBM4XX
     19  1.12.6.2  nathanw #include <machine/tlb.h>
     20  1.12.6.2  nathanw #include <powerpc/spr.h>
     21  1.12.6.2  nathanw #include <uvm/uvm_extern.h>
     22  1.12.6.2  nathanw #endif
     23  1.12.6.2  nathanw 
     24  1.12.6.3  nathanw #ifdef DDB
     25  1.12.6.2  nathanw #include <ddb/db_sym.h>
     26  1.12.6.2  nathanw #include <ddb/db_command.h>
     27  1.12.6.2  nathanw #include <ddb/db_extern.h>
     28  1.12.6.2  nathanw #include <ddb/db_access.h>
     29  1.12.6.7  thorpej #include <ddb/db_lex.h>
     30  1.12.6.2  nathanw #include <ddb/db_output.h>
     31  1.12.6.2  nathanw #include <ddb/ddbvar.h>
     32  1.12.6.3  nathanw #endif
     33  1.12.6.3  nathanw 
     34  1.12.6.3  nathanw #ifdef KGDB
     35  1.12.6.3  nathanw #include <sys/kgdb.h>
     36  1.12.6.3  nathanw #endif
     37  1.12.6.3  nathanw 
     38  1.12.6.3  nathanw #include <dev/ofw/openfirm.h>
     39  1.12.6.2  nathanw 
     40  1.12.6.2  nathanw int	db_active = 0;
     41  1.12.6.2  nathanw 
     42  1.12.6.5  nathanw db_regs_t ddb_regs;
     43  1.12.6.2  nathanw 
     44  1.12.6.2  nathanw void ddb_trap(void);				/* Call into trap_subr.S */
     45  1.12.6.2  nathanw int ddb_trap_glue(struct trapframe *);		/* Called from trap_subr.S */
     46  1.12.6.2  nathanw #ifdef PPC_IBM4XX
     47  1.12.6.2  nathanw static void db_ppc4xx_ctx(db_expr_t, int, db_expr_t, char *);
     48  1.12.6.2  nathanw static void db_ppc4xx_pv(db_expr_t, int, db_expr_t, char *);
     49  1.12.6.2  nathanw static void db_ppc4xx_reset(db_expr_t, int, db_expr_t, char *);
     50  1.12.6.2  nathanw static void db_ppc4xx_tf(db_expr_t, int, db_expr_t, char *);
     51  1.12.6.2  nathanw static void db_ppc4xx_dumptlb(db_expr_t, int, db_expr_t, char *);
     52  1.12.6.7  thorpej static void db_ppc4xx_dcr(db_expr_t, int, db_expr_t, char *);
     53  1.12.6.7  thorpej static db_expr_t db_ppc4xx_mfdcr(db_expr_t);
     54  1.12.6.7  thorpej static void db_ppc4xx_mtdcr(db_expr_t, db_expr_t);
     55  1.12.6.2  nathanw #ifdef USERACC
     56  1.12.6.2  nathanw static void db_ppc4xx_useracc(db_expr_t, int, db_expr_t, char *);
     57  1.12.6.2  nathanw #endif
     58  1.12.6.2  nathanw #endif /* PPC_IBM4XX */
     59  1.12.6.2  nathanw 
     60  1.12.6.3  nathanw #ifdef DDB
     61  1.12.6.2  nathanw void
     62  1.12.6.2  nathanw cpu_Debugger()
     63  1.12.6.2  nathanw {
     64  1.12.6.2  nathanw 	ddb_trap();
     65  1.12.6.2  nathanw }
     66  1.12.6.3  nathanw #endif
     67  1.12.6.2  nathanw 
     68  1.12.6.2  nathanw int
     69  1.12.6.2  nathanw ddb_trap_glue(frame)
     70  1.12.6.2  nathanw 	struct trapframe *frame;
     71  1.12.6.2  nathanw {
     72  1.12.6.7  thorpej #ifndef PPC_IBM4XX
     73  1.12.6.2  nathanw 	if (!(frame->srr1 & PSL_PR)
     74  1.12.6.4  nathanw 	    && (frame->exc == EXC_TRC || frame->exc == EXC_RUNMODETRC
     75  1.12.6.2  nathanw 		|| (frame->exc == EXC_PGM
     76  1.12.6.2  nathanw 		    && (frame->srr1 & 0x20000))
     77  1.12.6.2  nathanw 		|| frame->exc == EXC_BPT)) {
     78  1.12.6.3  nathanw 		int type = frame->exc;
     79  1.12.6.3  nathanw 		if (type == EXC_PGM && (frame->srr1 & 0x20000)) {
     80  1.12.6.3  nathanw 			type = T_BREAKPOINT;
     81  1.12.6.3  nathanw 		}
     82  1.12.6.3  nathanw 		return kdb_trap(type, frame);
     83  1.12.6.2  nathanw 	}
     84  1.12.6.2  nathanw 	return 0;
     85  1.12.6.7  thorpej #else
     86  1.12.6.7  thorpej 	return kdb_trap(frame->exc, frame);
     87  1.12.6.7  thorpej #endif
     88  1.12.6.2  nathanw }
     89  1.12.6.2  nathanw 
     90  1.12.6.2  nathanw int
     91  1.12.6.2  nathanw kdb_trap(type, v)
     92  1.12.6.2  nathanw 	int type;
     93  1.12.6.2  nathanw 	void *v;
     94  1.12.6.2  nathanw {
     95  1.12.6.2  nathanw 	struct trapframe *frame = v;
     96  1.12.6.2  nathanw 
     97  1.12.6.3  nathanw #ifdef DDB
     98  1.12.6.2  nathanw 	switch (type) {
     99  1.12.6.2  nathanw 	case T_BREAKPOINT:
    100  1.12.6.2  nathanw 	case -1:
    101  1.12.6.2  nathanw 		break;
    102  1.12.6.2  nathanw 	default:
    103  1.12.6.2  nathanw 		if (!db_onpanic && db_recover == 0)
    104  1.12.6.2  nathanw 			return 0;
    105  1.12.6.2  nathanw 		if (db_recover != 0) {
    106  1.12.6.2  nathanw 			db_error("Faulted in DDB; continuing...\n");
    107  1.12.6.2  nathanw 			/*NOTREACHED*/
    108  1.12.6.2  nathanw 		}
    109  1.12.6.2  nathanw 	}
    110  1.12.6.3  nathanw #endif
    111  1.12.6.2  nathanw 
    112  1.12.6.2  nathanw 	/* XXX Should switch to kdb's own stack here. */
    113  1.12.6.2  nathanw 
    114  1.12.6.2  nathanw 	memcpy(DDB_REGS->r, frame->fixreg, 32 * sizeof(u_int32_t));
    115  1.12.6.2  nathanw 	DDB_REGS->iar = frame->srr0;
    116  1.12.6.2  nathanw 	DDB_REGS->msr = frame->srr1;
    117  1.12.6.2  nathanw 	DDB_REGS->lr = frame->lr;
    118  1.12.6.2  nathanw 	DDB_REGS->ctr = frame->ctr;
    119  1.12.6.2  nathanw 	DDB_REGS->cr = frame->cr;
    120  1.12.6.2  nathanw 	DDB_REGS->xer = frame->xer;
    121  1.12.6.2  nathanw #ifdef PPC_IBM4XX
    122  1.12.6.2  nathanw 	DDB_REGS->dear = frame->dear;
    123  1.12.6.2  nathanw 	DDB_REGS->esr = frame->esr;
    124  1.12.6.2  nathanw 	DDB_REGS->pid = frame->pid;
    125  1.12.6.2  nathanw #endif
    126  1.12.6.2  nathanw 
    127  1.12.6.3  nathanw #ifdef DDB
    128  1.12.6.2  nathanw 	db_active++;
    129  1.12.6.2  nathanw 	cnpollc(1);
    130  1.12.6.2  nathanw 	db_trap(type, 0);
    131  1.12.6.2  nathanw 	cnpollc(0);
    132  1.12.6.2  nathanw 	db_active--;
    133  1.12.6.3  nathanw #elif defined(KGDB)
    134  1.12.6.3  nathanw 	if (!kgdb_trap(type, DDB_REGS))
    135  1.12.6.3  nathanw 		return 0;
    136  1.12.6.3  nathanw #endif
    137  1.12.6.3  nathanw 
    138  1.12.6.3  nathanw 	/* KGDB isn't smart about advancing PC if we
    139  1.12.6.3  nathanw 	 * take a breakpoint trap after kgdb_active is set.
    140  1.12.6.3  nathanw 	 * Therefore, we help out here.
    141  1.12.6.3  nathanw 	 */
    142  1.12.6.3  nathanw 	if (IS_BREAKPOINT_TRAP(type, 0)) {
    143  1.12.6.3  nathanw 		int bkpt;
    144  1.12.6.3  nathanw 		db_read_bytes(PC_REGS(DDB_REGS),BKPT_SIZE,(void *)&bkpt);
    145  1.12.6.3  nathanw 		if (bkpt== BKPT_INST) {
    146  1.12.6.3  nathanw 			PC_REGS(DDB_REGS) += BKPT_SIZE;
    147  1.12.6.3  nathanw 		}
    148  1.12.6.3  nathanw 	}
    149  1.12.6.2  nathanw 
    150  1.12.6.2  nathanw 	memcpy(frame->fixreg, DDB_REGS->r, 32 * sizeof(u_int32_t));
    151  1.12.6.2  nathanw 	frame->srr0 = DDB_REGS->iar;
    152  1.12.6.2  nathanw 	frame->srr1 = DDB_REGS->msr;
    153  1.12.6.2  nathanw 	frame->lr = DDB_REGS->lr;
    154  1.12.6.2  nathanw 	frame->ctr = DDB_REGS->ctr;
    155  1.12.6.2  nathanw 	frame->cr = DDB_REGS->cr;
    156  1.12.6.2  nathanw 	frame->xer = DDB_REGS->xer;
    157  1.12.6.2  nathanw #ifdef PPC_IBM4XX
    158  1.12.6.2  nathanw 	frame->dear = DDB_REGS->dear;
    159  1.12.6.2  nathanw 	frame->esr = DDB_REGS->esr;
    160  1.12.6.2  nathanw 	frame->pid = DDB_REGS->pid;
    161  1.12.6.2  nathanw #endif
    162  1.12.6.2  nathanw 
    163  1.12.6.2  nathanw 	return 1;
    164  1.12.6.2  nathanw }
    165  1.12.6.2  nathanw 
    166  1.12.6.2  nathanw #ifdef PPC_IBM4XX
    167  1.12.6.7  thorpej db_addr_t
    168  1.12.6.7  thorpej branch_taken(int inst, db_addr_t pc, db_regs_t *regs)
    169  1.12.6.7  thorpej {
    170  1.12.6.7  thorpej 
    171  1.12.6.7  thorpej 	if ((inst & M_B ) == I_B || (inst & M_B ) == I_BL) {
    172  1.12.6.7  thorpej 		db_expr_t off;
    173  1.12.6.7  thorpej 		off = ((db_expr_t)((inst & 0x03fffffc) << 6)) >> 6;
    174  1.12.6.7  thorpej 		return (((inst & 0x2) ? 0 : pc) + off);
    175  1.12.6.7  thorpej 	}
    176  1.12.6.7  thorpej 
    177  1.12.6.7  thorpej 	if ((inst & M_BC) == I_BC || (inst & M_BC) == I_BCL) {
    178  1.12.6.7  thorpej 		db_expr_t off;
    179  1.12.6.7  thorpej 		off = ((db_expr_t)((inst & 0x0000fffc) << 16)) >> 16;
    180  1.12.6.7  thorpej 		return (((inst & 0x2) ? 0 : pc) + off);
    181  1.12.6.7  thorpej 	}
    182  1.12.6.7  thorpej 
    183  1.12.6.7  thorpej 	if ((inst & M_RTS) == I_RTS || (inst & M_RTS) == I_BLRL)
    184  1.12.6.7  thorpej 		return (regs->lr);
    185  1.12.6.7  thorpej 
    186  1.12.6.7  thorpej 	if ((inst & M_BCTR) == I_BCTR || (inst & M_BCTR) == I_BCTRL)
    187  1.12.6.7  thorpej 		return (regs->ctr);
    188  1.12.6.7  thorpej 
    189  1.12.6.7  thorpej 	db_printf("branch_taken: can't figure out branch target for 0x%x!\n",
    190  1.12.6.7  thorpej 	    inst);
    191  1.12.6.7  thorpej 	return (0);
    192  1.12.6.7  thorpej }
    193  1.12.6.7  thorpej 
    194  1.12.6.2  nathanw const struct db_command db_machine_command_table[] = {
    195  1.12.6.2  nathanw 	{ "ctx",	db_ppc4xx_ctx,		0,	0 },
    196  1.12.6.2  nathanw 	{ "pv",		db_ppc4xx_pv,		0,	0 },
    197  1.12.6.2  nathanw 	{ "reset",	db_ppc4xx_reset,	0,	0 },
    198  1.12.6.7  thorpej 	{ "tf",		db_ppc4xx_tf,		0,	0 },
    199  1.12.6.2  nathanw 	{ "tlb",	db_ppc4xx_dumptlb,	0,	0 },
    200  1.12.6.7  thorpej 	{ "dcr",	db_ppc4xx_dcr,		CS_MORE|CS_SET_DOT,	0 },
    201  1.12.6.2  nathanw #ifdef USERACC
    202  1.12.6.2  nathanw 	{ "user",	db_ppc4xx_useracc,	0,	0 },
    203  1.12.6.2  nathanw #endif
    204  1.12.6.2  nathanw 	{ NULL, }
    205  1.12.6.2  nathanw };
    206  1.12.6.2  nathanw 
    207  1.12.6.2  nathanw static void
    208  1.12.6.2  nathanw db_ppc4xx_ctx(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
    209  1.12.6.2  nathanw {
    210  1.12.6.2  nathanw 	struct proc *p;
    211  1.12.6.2  nathanw 
    212  1.12.6.2  nathanw 	/* XXX LOCKING XXX */
    213  1.12.6.2  nathanw 	for (p = allproc.lh_first; p != 0; p = p->p_list.le_next) {
    214  1.12.6.2  nathanw 		if (p->p_stat) {
    215  1.12.6.2  nathanw 			db_printf("process %p:", p);
    216  1.12.6.2  nathanw 			db_printf("pid:%d pmap:%p ctx:%d %s\n",
    217  1.12.6.2  nathanw 				p->p_pid, p->p_vmspace->vm_map.pmap,
    218  1.12.6.2  nathanw 				p->p_vmspace->vm_map.pmap->pm_ctx,
    219  1.12.6.2  nathanw 				p->p_comm);
    220  1.12.6.2  nathanw 		}
    221  1.12.6.2  nathanw 	}
    222  1.12.6.2  nathanw 	return;
    223  1.12.6.2  nathanw }
    224  1.12.6.2  nathanw 
    225  1.12.6.2  nathanw static void
    226  1.12.6.2  nathanw db_ppc4xx_pv(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
    227  1.12.6.2  nathanw {
    228  1.12.6.2  nathanw 	struct pv_entry {
    229  1.12.6.2  nathanw 		struct pv_entry *pv_next;	/* Linked list of mappings */
    230  1.12.6.2  nathanw 		vaddr_t pv_va;			/* virtual address of mapping */
    231  1.12.6.2  nathanw 		struct pmap *pv_pm;
    232  1.12.6.2  nathanw 	};
    233  1.12.6.2  nathanw 	struct pv_entry *pa_to_pv(paddr_t);
    234  1.12.6.2  nathanw 	struct pv_entry *pv;
    235  1.12.6.2  nathanw 
    236  1.12.6.2  nathanw 	if (!have_addr) {
    237  1.12.6.2  nathanw 		db_printf("pv: <pa>\n");
    238  1.12.6.2  nathanw 		return;
    239  1.12.6.2  nathanw 	}
    240  1.12.6.2  nathanw 	pv = pa_to_pv(addr);
    241  1.12.6.2  nathanw 	db_printf("pv at %p\n", pv);
    242  1.12.6.2  nathanw 	while (pv && pv->pv_pm) {
    243  1.12.6.2  nathanw 		db_printf("next %p va %p pmap %p\n", pv->pv_next,
    244  1.12.6.2  nathanw 			(void *)pv->pv_va, pv->pv_pm);
    245  1.12.6.2  nathanw 		pv = pv->pv_next;
    246  1.12.6.2  nathanw 	}
    247  1.12.6.2  nathanw }
    248  1.12.6.2  nathanw 
    249  1.12.6.2  nathanw static void
    250  1.12.6.2  nathanw db_ppc4xx_reset(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
    251  1.12.6.2  nathanw {
    252  1.12.6.2  nathanw 	printf("Reseting...\n");
    253  1.12.6.2  nathanw 	ppc4xx_reset();
    254  1.12.6.2  nathanw }
    255  1.12.6.2  nathanw 
    256  1.12.6.2  nathanw static void
    257  1.12.6.2  nathanw db_ppc4xx_tf(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
    258  1.12.6.2  nathanw {
    259  1.12.6.2  nathanw 	struct trapframe *f;
    260  1.12.6.2  nathanw 
    261  1.12.6.2  nathanw 
    262  1.12.6.2  nathanw 	if (have_addr) {
    263  1.12.6.2  nathanw 		f = (struct trapframe *)addr;
    264  1.12.6.2  nathanw 
    265  1.12.6.2  nathanw 		db_printf("r0-r3:  \t%8.8x %8.8x %8.8x %8.8x\n",
    266  1.12.6.2  nathanw 			f->fixreg[0], f->fixreg[1],
    267  1.12.6.2  nathanw 			f->fixreg[2], f->fixreg[3]);
    268  1.12.6.2  nathanw 		db_printf("r4-r7:  \t%8.8x %8.8x %8.8x %8.8x\n",
    269  1.12.6.2  nathanw 			f->fixreg[4], f->fixreg[5],
    270  1.12.6.2  nathanw 			f->fixreg[6], f->fixreg[7]);
    271  1.12.6.2  nathanw 		db_printf("r8-r11: \t%8.8x %8.8x %8.8x %8.8x\n",
    272  1.12.6.2  nathanw 			f->fixreg[8], f->fixreg[9],
    273  1.12.6.2  nathanw 			f->fixreg[10], f->fixreg[11]);
    274  1.12.6.2  nathanw 		db_printf("r12-r15:\t%8.8x %8.8x %8.8x %8.8x\n",
    275  1.12.6.2  nathanw 			f->fixreg[12], f->fixreg[13],
    276  1.12.6.2  nathanw 			f->fixreg[14], f->fixreg[15]);
    277  1.12.6.2  nathanw 		db_printf("r16-r19:\t%8.8x %8.8x %8.8x %8.8x\n",
    278  1.12.6.2  nathanw 			f->fixreg[16], f->fixreg[17],
    279  1.12.6.2  nathanw 			f->fixreg[18], f->fixreg[19]);
    280  1.12.6.2  nathanw 		db_printf("r20-r23:\t%8.8x %8.8x %8.8x %8.8x\n",
    281  1.12.6.2  nathanw 			f->fixreg[20], f->fixreg[21],
    282  1.12.6.2  nathanw 			f->fixreg[22], f->fixreg[23]);
    283  1.12.6.2  nathanw 		db_printf("r24-r27:\t%8.8x %8.8x %8.8x %8.8x\n",
    284  1.12.6.2  nathanw 			f->fixreg[24], f->fixreg[25],
    285  1.12.6.2  nathanw 			f->fixreg[26], f->fixreg[27]);
    286  1.12.6.2  nathanw 		db_printf("r28-r31:\t%8.8x %8.8x %8.8x %8.8x\n",
    287  1.12.6.2  nathanw 			f->fixreg[28], f->fixreg[29],
    288  1.12.6.2  nathanw 			f->fixreg[30], f->fixreg[31]);
    289  1.12.6.2  nathanw 
    290  1.12.6.2  nathanw 		db_printf("lr: %8.8x cr: %8.8x xer: %8.8x ctr: %8.8x\n",
    291  1.12.6.2  nathanw 			f->lr, f->cr, f->xer, f->ctr);
    292  1.12.6.2  nathanw 		db_printf("srr0(pc): %8.8x srr1(msr): %8.8x "
    293  1.12.6.2  nathanw 			"dear: %8.8x esr: %8.8x\n",
    294  1.12.6.2  nathanw 			f->srr0, f->srr1, f->dear, f->esr);
    295  1.12.6.2  nathanw 		db_printf("exc: %8.8x pid: %8.8x\n",
    296  1.12.6.2  nathanw 			f->exc, f->pid);
    297  1.12.6.2  nathanw 	}
    298  1.12.6.2  nathanw 	return;
    299  1.12.6.2  nathanw }
    300  1.12.6.2  nathanw 
    301  1.12.6.2  nathanw static const char *const tlbsizes[] = {
    302  1.12.6.2  nathanw 	  "1kB",
    303  1.12.6.2  nathanw 	  "4kB",
    304  1.12.6.2  nathanw 	 "16kB",
    305  1.12.6.2  nathanw 	 "64kB",
    306  1.12.6.2  nathanw 	"256kB",
    307  1.12.6.2  nathanw 	  "1MB",
    308  1.12.6.2  nathanw 	  "4MB",
    309  1.12.6.2  nathanw 	 "16MB"
    310  1.12.6.2  nathanw };
    311  1.12.6.2  nathanw 
    312  1.12.6.2  nathanw static void
    313  1.12.6.2  nathanw db_ppc4xx_dumptlb(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
    314  1.12.6.2  nathanw {
    315  1.12.6.2  nathanw 	int i, zone, tlbsize;
    316  1.12.6.2  nathanw 	u_int zpr, pid, opid, msr;
    317  1.12.6.2  nathanw 	u_long tlblo, tlbhi, tlbmask;
    318  1.12.6.2  nathanw 
    319  1.12.6.2  nathanw 	zpr = mfspr(SPR_ZPR);
    320  1.12.6.2  nathanw 	for (i = 0; i < NTLB; i++) {
    321  1.12.6.2  nathanw 		asm volatile("mfmsr %3;"
    322  1.12.6.2  nathanw 			"mfpid %4;"
    323  1.12.6.2  nathanw 			"li %0,0;"
    324  1.12.6.2  nathanw 			"mtmsr %0;"
    325  1.12.6.2  nathanw 			"sync; isync;"
    326  1.12.6.6  thorpej 			"tlbrelo %0,%5;"
    327  1.12.6.6  thorpej 			"tlbrehi %1,%5;"
    328  1.12.6.2  nathanw 			"mfpid %2;"
    329  1.12.6.2  nathanw 			"mtpid %4;"
    330  1.12.6.2  nathanw 			"mtmsr %3;"
    331  1.12.6.2  nathanw 			"sync; isync"
    332  1.12.6.2  nathanw 			: "=&r" (tlblo), "=&r" (tlbhi), "=r" (pid),
    333  1.12.6.2  nathanw 			"=&r" (msr), "=&r" (opid) : "r" (i));
    334  1.12.6.2  nathanw 
    335  1.12.6.2  nathanw 		if (strchr(modif, 'v') && !(tlbhi & TLB_VALID))
    336  1.12.6.2  nathanw 			continue;
    337  1.12.6.2  nathanw 
    338  1.12.6.2  nathanw 		tlbsize = (tlbhi & TLB_SIZE_MASK) >> TLB_SIZE_SHFT;
    339  1.12.6.2  nathanw 		/* map tlbsize 0 .. 7 to masks for 1kB .. 16MB */
    340  1.12.6.2  nathanw 		tlbmask = ~(1 << (tlbsize * 2 + 10)) + 1;
    341  1.12.6.2  nathanw 
    342  1.12.6.2  nathanw 		if (have_addr && ((tlbhi & tlbmask) != (addr & tlbmask)))
    343  1.12.6.2  nathanw 			continue;
    344  1.12.6.2  nathanw 
    345  1.12.6.2  nathanw 		zone = (tlblo & TLB_ZSEL_MASK) >> TLB_ZSEL_SHFT;
    346  1.12.6.2  nathanw 		db_printf("tlb%c%2d", tlbhi & TLB_VALID ? ' ' : '*', i);
    347  1.12.6.2  nathanw 		db_printf("  PID %3d EPN 0x%08lx %-5s",
    348  1.12.6.2  nathanw 		    pid,
    349  1.12.6.2  nathanw 		    tlbhi & tlbmask,
    350  1.12.6.2  nathanw 		    tlbsizes[tlbsize]);
    351  1.12.6.2  nathanw 		db_printf("  RPN 0x%08lx  ZONE %2d%c  %s %s %c%c%c%c%c %s",
    352  1.12.6.2  nathanw 		    tlblo & tlbmask,
    353  1.12.6.2  nathanw 		    zone,
    354  1.12.6.2  nathanw 		    "NTTA"[(zpr >> ((15 - zone) * 2)) & 3],
    355  1.12.6.2  nathanw 		    tlblo & TLB_EX ? "EX" : "  ",
    356  1.12.6.2  nathanw 		    tlblo & TLB_WR ? "WR" : "  ",
    357  1.12.6.2  nathanw 		    tlblo & TLB_W ? 'W' : ' ',
    358  1.12.6.2  nathanw 		    tlblo & TLB_I ? 'I' : ' ',
    359  1.12.6.2  nathanw 		    tlblo & TLB_M ? 'M' : ' ',
    360  1.12.6.2  nathanw 		    tlblo & TLB_G ? 'G' : ' ',
    361  1.12.6.2  nathanw 		    tlbhi & TLB_ENDIAN ? 'E' : ' ',
    362  1.12.6.2  nathanw 		    tlbhi & TLB_U0 ? "U0" : "  ");
    363  1.12.6.2  nathanw 		db_printf("\n");
    364  1.12.6.2  nathanw 	}
    365  1.12.6.2  nathanw }
    366  1.12.6.2  nathanw 
    367  1.12.6.7  thorpej static void
    368  1.12.6.7  thorpej db_ppc4xx_dcr(db_expr_t address, int have_addr, db_expr_t count, char *modif)
    369  1.12.6.7  thorpej {
    370  1.12.6.7  thorpej 	db_expr_t new_value;
    371  1.12.6.7  thorpej 	db_expr_t addr;
    372  1.12.6.7  thorpej 
    373  1.12.6.7  thorpej 	if (address < 0 || address > 0x3ff)
    374  1.12.6.7  thorpej 		db_error("Invalid DCR address (Valid range is 0x0 - 0x3ff)\n");
    375  1.12.6.7  thorpej 
    376  1.12.6.7  thorpej 	addr = address;
    377  1.12.6.7  thorpej 
    378  1.12.6.7  thorpej 	while (db_expression(&new_value)) {
    379  1.12.6.7  thorpej 		db_printf("dcr 0x%lx\t\t%s = ", addr,
    380  1.12.6.7  thorpej 		    db_num_to_str(db_ppc4xx_mfdcr(addr)));
    381  1.12.6.7  thorpej 		db_ppc4xx_mtdcr(addr, new_value);
    382  1.12.6.7  thorpej 		db_printf("%s\n", db_num_to_str(db_ppc4xx_mfdcr(addr)));
    383  1.12.6.7  thorpej 		addr += 1;
    384  1.12.6.7  thorpej 	}
    385  1.12.6.7  thorpej 
    386  1.12.6.7  thorpej 	if (addr == address) {
    387  1.12.6.7  thorpej 		db_next = (db_addr_t)addr + 1;
    388  1.12.6.7  thorpej 		db_prev = (db_addr_t)addr;
    389  1.12.6.7  thorpej 		db_printf("dcr 0x%lx\t\t%s\n", addr,
    390  1.12.6.7  thorpej 		    db_num_to_str(db_ppc4xx_mfdcr(addr)));
    391  1.12.6.7  thorpej 	} else {
    392  1.12.6.7  thorpej 		db_next = (db_addr_t)addr;
    393  1.12.6.7  thorpej 		db_prev = (db_addr_t)addr - 1;
    394  1.12.6.7  thorpej 	}
    395  1.12.6.7  thorpej 
    396  1.12.6.7  thorpej 	db_skip_to_eol();
    397  1.12.6.7  thorpej }
    398  1.12.6.7  thorpej 
    399  1.12.6.7  thorpej /*
    400  1.12.6.7  thorpej  * XXX Grossness Alert! XXX
    401  1.12.6.7  thorpej  *
    402  1.12.6.7  thorpej  * Please look away now if you don't like self-modifying code
    403  1.12.6.7  thorpej  */
    404  1.12.6.7  thorpej static u_int32_t db_ppc4xx_dcrfunc[4];
    405  1.12.6.7  thorpej 
    406  1.12.6.7  thorpej static db_expr_t
    407  1.12.6.7  thorpej db_ppc4xx_mfdcr(db_expr_t reg)
    408  1.12.6.7  thorpej {
    409  1.12.6.7  thorpej 	db_expr_t (*func)(void);
    410  1.12.6.7  thorpej 
    411  1.12.6.7  thorpej 	reg = (((reg & 0x1f) << 5) | ((reg >> 5) & 0x1f)) << 11;
    412  1.12.6.7  thorpej 	db_ppc4xx_dcrfunc[0] = 0x7c0004ac;		/* sync */
    413  1.12.6.7  thorpej 	db_ppc4xx_dcrfunc[1] = 0x4c00012c;		/* isync */
    414  1.12.6.7  thorpej 	db_ppc4xx_dcrfunc[2] = 0x7c600286 | reg;	/* mfdcr reg, r3 */
    415  1.12.6.7  thorpej 	db_ppc4xx_dcrfunc[3] = 0x4e800020;		/* blr */
    416  1.12.6.7  thorpej 
    417  1.12.6.7  thorpej 	__syncicache((void *)db_ppc4xx_dcrfunc, sizeof(db_ppc4xx_dcrfunc));
    418  1.12.6.7  thorpej 	func = (db_expr_t (*)(void))(void *)db_ppc4xx_dcrfunc;
    419  1.12.6.7  thorpej 
    420  1.12.6.7  thorpej 	return ((*func)());
    421  1.12.6.7  thorpej }
    422  1.12.6.7  thorpej 
    423  1.12.6.7  thorpej static void
    424  1.12.6.7  thorpej db_ppc4xx_mtdcr(db_expr_t reg, db_expr_t val)
    425  1.12.6.7  thorpej {
    426  1.12.6.7  thorpej 	db_expr_t (*func)(db_expr_t);
    427  1.12.6.7  thorpej 
    428  1.12.6.7  thorpej 	reg = (((reg & 0x1f) << 5) | ((reg >> 5) & 0x1f)) << 11;
    429  1.12.6.7  thorpej 	db_ppc4xx_dcrfunc[0] = 0x7c0004ac;		/* sync */
    430  1.12.6.7  thorpej 	db_ppc4xx_dcrfunc[1] = 0x4c00012c;		/* isync */
    431  1.12.6.7  thorpej 	db_ppc4xx_dcrfunc[2] = 0x7c600386 | reg;	/* mtdcr r3, reg */
    432  1.12.6.7  thorpej 	db_ppc4xx_dcrfunc[3] = 0x4e800020;		/* blr */
    433  1.12.6.7  thorpej 
    434  1.12.6.7  thorpej 	__syncicache((void *)db_ppc4xx_dcrfunc, sizeof(db_ppc4xx_dcrfunc));
    435  1.12.6.7  thorpej 	func = (db_expr_t (*)(db_expr_t))(void *)db_ppc4xx_dcrfunc;
    436  1.12.6.7  thorpej 
    437  1.12.6.7  thorpej 	(*func)(val);
    438  1.12.6.7  thorpej }
    439  1.12.6.7  thorpej 
    440  1.12.6.2  nathanw #ifdef USERACC
    441  1.12.6.2  nathanw static void
    442  1.12.6.2  nathanw db_ppc4xx_useracc(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
    443  1.12.6.2  nathanw {
    444  1.12.6.2  nathanw 	static paddr_t oldaddr = -1;
    445  1.12.6.2  nathanw 	int instr = 0;
    446  1.12.6.2  nathanw 	int data;
    447  1.12.6.2  nathanw 	extern vaddr_t opc_disasm(vaddr_t loc, int);
    448  1.12.6.2  nathanw 
    449  1.12.6.2  nathanw 
    450  1.12.6.2  nathanw 	if (!have_addr) {
    451  1.12.6.2  nathanw 		addr = oldaddr;
    452  1.12.6.2  nathanw 	}
    453  1.12.6.2  nathanw 	if (addr == -1) {
    454  1.12.6.2  nathanw 		db_printf("no address\n");
    455  1.12.6.2  nathanw 		return;
    456  1.12.6.2  nathanw 	}
    457  1.12.6.2  nathanw 	addr &= ~0x3; /* align */
    458  1.12.6.2  nathanw 	{
    459  1.12.6.2  nathanw 		register char c, *cp = modif;
    460  1.12.6.2  nathanw 		while ((c = *cp++) != 0)
    461  1.12.6.2  nathanw 			if (c == 'i')
    462  1.12.6.2  nathanw 				instr = 1;
    463  1.12.6.2  nathanw 	}
    464  1.12.6.2  nathanw 	while (count--) {
    465  1.12.6.2  nathanw 		if (db_print_position() == 0) {
    466  1.12.6.2  nathanw 			/* Always print the address. */
    467  1.12.6.2  nathanw 			db_printf("%8.4lx:\t", addr);
    468  1.12.6.2  nathanw 		}
    469  1.12.6.2  nathanw 		oldaddr=addr;
    470  1.12.6.2  nathanw 		copyin((void *)addr, &data, sizeof(data));
    471  1.12.6.2  nathanw 		if (instr) {
    472  1.12.6.2  nathanw 			opc_disasm(addr, data);
    473  1.12.6.2  nathanw 		} else {
    474  1.12.6.2  nathanw 			db_printf("%4.4x\n", data);
    475  1.12.6.2  nathanw 		}
    476  1.12.6.2  nathanw 		addr += 4;
    477  1.12.6.2  nathanw 		db_end_line();
    478  1.12.6.2  nathanw 	}
    479  1.12.6.2  nathanw 
    480  1.12.6.2  nathanw }
    481  1.12.6.2  nathanw #endif
    482  1.12.6.2  nathanw 
    483  1.12.6.2  nathanw #endif /* PPC_IBM4XX */
    484