The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/powerpc/powerpc/db_interface.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: b3e6256d0391036fc34636303a4052f0


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.