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/osfmk/ppc/db_low_trace.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 /*
    2  * Copyright (c) 2000-2005 Apple Computer, Inc. All rights reserved.
    3  *
    4  * @APPLE_LICENSE_HEADER_START@
    5  * 
    6  * The contents of this file constitute Original Code as defined in and
    7  * are subject to the Apple Public Source License Version 1.1 (the
    8  * "License").  You may not use this file except in compliance with the
    9  * License.  Please obtain a copy of the License at
   10  * http://www.apple.com/publicsource and read it before using this file.
   11  * 
   12  * This Original Code and all software distributed under the License are
   13  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
   14  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
   15  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
   16  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
   17  * License for the specific language governing rights and limitations
   18  * under the License.
   19  * 
   20  * @APPLE_LICENSE_HEADER_END@
   21  */
   22 /*
   23  * @OSF_FREE_COPYRIGHT@
   24  */
   25 /*
   26  * @APPLE_FREE_COPYRIGHT@
   27  */
   28 
   29 /*
   30  *      Author: Bill Angell, Apple
   31  *      Date:   6/97
   32  *
   33  * exceptions and certain C functions write into a trace table which
   34  * can be examined via the machine 'lt' command under kdb
   35  */
   36 
   37 
   38 #include <string.h>                     /* For strcpy() */
   39 #include <mach/boolean.h>
   40 #include <machine/db_machdep.h>
   41 
   42 #include <ddb/db_access.h>
   43 #include <ddb/db_lex.h>
   44 #include <ddb/db_output.h>
   45 #include <ddb/db_command.h>
   46 #include <ddb/db_sym.h>
   47 #include <ddb/db_task_thread.h>
   48 #include <ddb/db_command.h>             /* For db_option() */
   49 #include <ddb/db_examine.h>
   50 #include <ddb/db_expr.h>
   51 #include <kern/thread.h>
   52 #include <kern/task.h>
   53 #include <mach/vm_param.h>
   54 #include <mach/kmod.h>
   55 #include <ppc/Firmware.h>
   56 #include <ppc/low_trace.h>
   57 #include <ppc/db_low_trace.h>
   58 #include <ppc/mappings.h>
   59 #include <ppc/pmap.h>
   60 #include <ppc/mem.h>
   61 #include <ppc/savearea.h>
   62 #include <ppc/vmachmon.h>
   63 
   64 void db_dumppca(unsigned int ptegindex);        
   65 void db_dumpmapping(struct mapping *mp);                                        /* Dump out a mapping */
   66 extern kmod_info_t *kmod;                                                                       /* Find the kmods */
   67 
   68 db_addr_t       db_low_trace_prev = 0;
   69 
   70 /*
   71  *              Print out the low level trace table:
   72  *
   73  *              Displays the entry and 15 before it in newest to oldest order
   74  *              
   75  *              lt [entaddr]
   76  
   77  *              If entaddr is omitted, it starts with the most current
   78  *              If entaddr = 0, it starts with the most current and does the whole table
   79  */
   80 void db_low_trace(db_expr_t addr, int have_addr, db_expr_t count, char * modif) {
   81 
   82         int             c, i;
   83         unsigned int tempx, cnt;
   84         unsigned int xTraceCurr, xTraceStart, xTraceEnd, cxltr;
   85         db_addr_t       next_addr;
   86         LowTraceRecord xltr;
   87         unsigned char cmark;
   88         addr64_t xxltr;
   89         
   90         cnt = 16;                                                                                                       /* Default to 16 entries */
   91         
   92         xTraceCurr = trcWork.traceCurr;                                                         /* Transfer current pointer */
   93         xTraceStart = trcWork.traceStart;                                                       /* Transfer start of table */
   94         xTraceEnd = trcWork.traceEnd;                                                           /* Transfer end of table */
   95         
   96         if(addr == -1) cnt = 0x7FFFFFFF;                                                        /* Max the count */
   97 
   98         if(!addr || (addr == -1)) {
   99                 addr=xTraceCurr-sizeof(LowTraceRecord);                                 /* Start at the newest */
  100                 if((unsigned int)addr<xTraceStart) addr=xTraceEnd-sizeof(LowTraceRecord);       /* Wrap low back to high */
  101         }
  102         
  103         if((unsigned int)addr<xTraceStart||(unsigned int)addr>=xTraceEnd) {     /* In the table? */
  104                 db_printf("address not in low memory trace table\n");   /* Tell the fool */
  105                 return;                                                                                                 /* Leave... */
  106         }
  107 
  108         if((unsigned int)addr&0x0000007F) {                                                     /* Proper alignment? */
  109                 db_printf("address not aligned on trace entry boundary (0x80)\n");      /* Tell 'em */
  110                 return;                                                                                                 /* Leave... */
  111         }
  112         
  113         xxltr = addr;                                                                                           /* Set the start */
  114         cxltr = ((xTraceCurr == xTraceStart ? xTraceEnd : xTraceCurr) - sizeof(LowTraceRecord));        /* Get address of newest entry */
  115 
  116         db_low_trace_prev = addr;                                                                       /* Starting point */
  117 
  118         for(i=0; i < cnt; i++) {                                                                        /* Dump the 16 (or all) entries */
  119         
  120                 ReadReal((addr64_t)xxltr, (unsigned int *)&xltr);                                       /* Get the first half */
  121                 ReadReal((addr64_t)xxltr + 32, &(((unsigned int *)&xltr)[8]));          /* Get the second half */
  122                 ReadReal((addr64_t)xxltr + 64, &(((unsigned int *)&xltr)[16]));         /* Get the second half */
  123                 ReadReal((addr64_t)xxltr + 96, &(((unsigned int *)&xltr)[24]));         /* Get the second half */
  124                 
  125                 db_printf("\n%s%08llX  %1X  %08X %08X - %04X", (xxltr != cxltr ? " " : "*"), 
  126                         xxltr,
  127                         (xltr.LTR_cpu & 0xFF), xltr.LTR_timeHi, xltr.LTR_timeLo, 
  128                         (xltr.LTR_excpt & 0x8000 ? 0xFFFF : xltr.LTR_excpt * 64));      /* Print the first line */
  129 
  130                 if(xltr.LTR_cpu & 0xFF00) db_printf(", sflgs = %02X\n", ((xltr.LTR_cpu >> 8) & 0xFF));
  131                 else db_printf("\n");
  132                         
  133                 db_printf("              DAR/DSR/CR: %016llX %08X %08X\n", xltr.LTR_dar, xltr.LTR_dsisr, xltr.LTR_cr);
  134                 
  135                 db_printf("                SRR0/SRR1 %016llX %016llX\n",  xltr.LTR_srr0, xltr.LTR_srr1);
  136                 db_printf("                LR/CTR    %016llX %016llX\n",  xltr.LTR_lr, xltr.LTR_ctr);
  137 
  138                 db_printf("                R0/R1/R2  %016llX %016llX %016llX\n", xltr.LTR_r0, xltr.LTR_r1, xltr.LTR_r2);
  139                 db_printf("                R3/R4/R5  %016llX %016llX %016llX\n", xltr.LTR_r3, xltr.LTR_r4, xltr.LTR_r5);
  140                 db_printf("              R6/sv/rsv   %016llX %016llX %08X\n", xltr.LTR_r6, xltr.LTR_save, xltr.LTR_rsvd0);
  141         
  142                 if((cnt != 16) && (xxltr == xTraceCurr)) break;                 /* If whole table dump, exit when we hit start again... */
  143 
  144                 xxltr-=sizeof(LowTraceRecord);                                                  /* Back it on up */
  145                 if(xxltr<xTraceStart)
  146                         xxltr=(xTraceEnd-sizeof(LowTraceRecord));                       /* Wrap low back to high */
  147         
  148         }
  149         db_next = (db_expr_t)(xxltr);
  150         return;
  151 }
  152 
  153 
  154 /*
  155  *              Print out 256 bytes
  156  *
  157  *              
  158  *              dl [entaddr]
  159  */
  160 void db_display_long(db_expr_t addr, int have_addr, db_expr_t count, char * modif) {
  161 
  162         int                             i;
  163 
  164         for(i=0; i<8; i++) {                                                                    /* Print 256 bytes */
  165                 db_printf("%016llX   %08X %08X %08X %08X  %08X %08X %08X %08X\n", addr, /* Print a line */
  166                         ((unsigned long *)addr)[0], ((unsigned long *)addr)[1], ((unsigned long *)addr)[2], ((unsigned long *)addr)[3], 
  167                         ((unsigned long *)addr)[4], ((unsigned long *)addr)[5], ((unsigned long *)addr)[6], ((unsigned long *)addr)[7]);
  168                 addr=(db_expr_t)(addr+0x00000020);                                      /* Point to next address */
  169         }
  170         db_next = addr;
  171 
  172 
  173 }
  174 
  175 unsigned char xtran[256] = {
  176 /*  x0   x1   x2   x3   x4   x5   x6   x7   x8   x9   xA   xB   xC   xD   xE   xF          */
  177         '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.',  /* 0x */
  178         '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.',  /* 1x */
  179         ' ', '!', '"', '#', '$', '%', '&',0x27, '(', ')', '*', '+', ',', '-', '.', '/',  /* 2x */
  180         '', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?',  /* 3x */
  181         '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',  /* 4x */
  182         'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[',0x5C, ']', '^', '_',  /* 5x */
  183         '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',  /* 6x */
  184         'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~', '.',  /* 7x */
  185         '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.',  /* 8x */
  186         '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.',  /* 9x */
  187         '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.',  /* Ax */
  188         '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.',  /* Bx */
  189         '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.',  /* Cx */
  190         '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.',  /* Dx */
  191         '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.',  /* Ex */
  192         '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.',  /* Fx */
  193 };
  194 
  195 /*
  196  *              Print out 256 bytes in characters
  197  *
  198  *              
  199  *              dc [entaddr]
  200  */
  201 void db_display_char(db_expr_t addr, int have_addr, db_expr_t count, char * modif) {
  202 
  203         int                             i, j, k;
  204         unsigned char xlt[256], *xaddr;
  205         
  206         xaddr = (unsigned char *)addr;
  207         
  208 
  209         for(i = 0; i < 8; i++) {                                                                /* Print 256 bytes */
  210                 j = 0;
  211                 for(k = 0; k < 32; k++) {
  212                         xlt[j] = xtran[*xaddr];
  213                         xaddr++;
  214                         j++;
  215                         if((k & 3) == 3) {
  216                                 xlt[j] = ' ';
  217                                 j++;
  218                         }
  219                 }
  220                 xlt[j] = 0;
  221                 
  222                 db_printf("%016llX   %s\n", (addr64_t)(xaddr - 32), xlt);       /* Print a line */
  223         }
  224 
  225         db_next = (db_expr_t)xaddr;
  226 
  227 
  228 }
  229 
  230 /*
  231  *              Print out 256 bytes of real storage
  232  *
  233  *              Displays the entry and 15 before it in newest to oldest order
  234  *              
  235  *              dr [entaddr]
  236  */
  237 void db_display_real(db_expr_t addr, int have_addr, db_expr_t count, char * modif) {
  238 
  239         int                             i;
  240         unsigned int xbuf[8];
  241 
  242         for(i=0; i<8; i++) {                                                                    /* Print 256 bytes */
  243                 ReadReal(addr, &xbuf[0]);                                                       /* Get the real storage data */
  244                 db_printf("%016llX   %08X %08X %08X %08X  %08X %08X %08X %08X\n", addr, /* Print a line */
  245                         xbuf[0], xbuf[1], xbuf[2], xbuf[3], 
  246                         xbuf[4], xbuf[5], xbuf[6], xbuf[7]);
  247                 addr = addr + 0x00000020;                                                       /* Point to next address */
  248         }
  249         db_next = addr;
  250 }
  251 
  252 unsigned int    dvspace = 0;
  253 
  254 /*
  255  *              Print out virtual to real translation information
  256  *
  257  *              
  258  *              dm vaddr [space] (defaults to last entered) 
  259  */
  260 void db_display_mappings(db_expr_t addr, int have_addr, db_expr_t count, char * modif) {
  261 
  262         db_expr_t       xspace;
  263         pmap_t                  pmap;
  264         addr64_t                lnextva;
  265 
  266         mapping_t       *mp;
  267         
  268         if (db_expression(&xspace)) {                                                   /* Get the address space requested */
  269                 if(xspace >= maxAdrSp) {
  270                         db_printf("requested address space (%llX) larger than max (%X)\n", xspace, maxAdrSp - 1);
  271                         return;
  272                 }
  273                 dvspace = xspace;                                                                       /* Get the space or set default */
  274         }
  275         
  276         db_printf("mapping information for %016llX in space %8X:\n", addr, dvspace);
  277 
  278         pmap = pmapTrans[dvspace].pmapVAddr;                                    /* Find the pmap address */
  279         if(!pmap) {                                                                                             /* The pmap is not in use */
  280                 db_printf("The space %X is not assigned to a pmap\n", dvspace); /* Say we are wrong */
  281                 return;
  282         }
  283 
  284         mp = hw_find_map(pmap, (addr64_t)addr, &lnextva);               /* Try to find the mapping for this address */
  285         if((unsigned int)mp == mapRtBadLk) {                                    /* Did we lock up ok? */
  286                 db_printf("Timeout locking physical entry for virtual address %016ll8X\n", addr);       
  287                 return;
  288         }
  289         
  290         if(!mp) {                                                                                               /* Did we find one? */
  291                 db_printf("Not mapped\n");      
  292                 return;                                                                                         /* Didn't find any, return FALSE... */
  293         }
  294         
  295         mapping_drop_busy(mp);                                                                  /* The mapping shouldn't be changing */
  296 
  297         db_dumpmapping(mp);                                                                             /* Dump it all out */
  298 
  299         return;                                                                                                 /* Tell them we did it */
  300 
  301 
  302 }
  303 
  304 /*
  305  *              Print out hash table data
  306  *
  307  *              
  308  *              dh vaddr [space] (defaults to last entered) 
  309  */
  310 void db_display_hash(db_expr_t addr, int have_addr, db_expr_t count, char * modif) {
  311 
  312         db_expr_t               xspace;
  313         unsigned int    seg, vsid, ptegindex, htsize;
  314         pmap_t                  pmap;
  315         addr64_t                lnextva, llva, vpn, esid;
  316         uint64_t                hash;
  317         int                     s4bit;
  318 
  319         llva = (addr64_t)((unsigned int)addr);                                  /* Make sure we are 64-bit now */
  320         
  321         s4bit = !((PerProcTable[0].ppe_vaddr->pf.Available & pf64Bit) == 0);    /* Are we a big guy? */
  322         if (db_expression(&xspace)) {                                                   /* Get the address space requested */
  323                 if(xspace >= maxAdrSp) {
  324                         db_printf("requested address space (%llX) larger than max (%X)\n", xspace, maxAdrSp - 1);
  325                         return;
  326                 }
  327                 dvspace = xspace;                                                                       /* Get the space or set default */
  328         }
  329         
  330         pmap = pmapTrans[dvspace].pmapVAddr;                                    /* Find the pmap address */
  331         if(!pmap) {                                                                                             /* The pmap is not in use */
  332                 db_printf("The space %X is not assigned to a pmap\n", dvspace); /* Say we are wrong */
  333                 return;
  334         }
  335 
  336         hash = (uint64_t)pmap->space | ((uint64_t)pmap->space << maxAdrSpb) | ((uint64_t)pmap->space << (2 * maxAdrSpb));       /* Get hash value */
  337         hash = hash & 0x0000001FFFFFFFFF;                                               /* Make sure we stay within supported ranges */
  338         
  339         esid = ((llva >> 14) & -maxAdrSp) ^ hash;                               /* Get ESID */
  340         llva = ((llva >> 12) & 0xFFFF) ^ esid;                                  /* Get index into hash table */
  341 
  342         if(s4bit) htsize = hash_table_size >> 7;                                /* Get number of entries in hash table for 64-bit */
  343         else htsize = hash_table_size >> 6;                                             /* get number of entries in hash table for 32-bit */
  344         
  345         ptegindex = llva & (htsize - 1);                                                /* Get the index to the pteg and pca */
  346         db_dumppca(ptegindex);                                                                  /* dump the info */
  347         
  348         return;                                                                                                 /* Tell them we did it */
  349 
  350 
  351 }
  352 
  353 /*
  354  *              Displays all of the in-use pmaps in the system.
  355  *
  356   *             dp
  357  */
  358 void db_display_pmap(db_expr_t addr, int have_addr, db_expr_t count, char * modif) {
  359 
  360         pmap_t                  pmap;
  361         int i;
  362         unsigned int v0, v1, st0, st1;
  363         
  364         pmap = (pmap_t)addr;
  365         if(!have_addr) pmap = kernel_pmap;                                              /* Start at the beginning */
  366         
  367         db_printf("PMAP     (real)            Next     Prev     Space    Flags    Ref      spaceNum Resident Wired\n"); 
  368 //                 xxxxxxxx rrrrrrrrrrrrrrrr  xxxxxxxx pppppppp ssssssss cccccccc vvvvvvvv nnnnnnnn rrrrrrrr wwwwwwwww
  369         while(1) {                                                                                              /* Do them all */
  370                 db_printf("%08X %016llX  %08X %08X %08X %08X %08X %08X %08X %08X\n",
  371                         pmap, (addr64_t)pmap ^ pmap->pmapvr,
  372                         pmap->pmap_link.next,  pmap->pmap_link.prev,
  373                         pmap->space, pmap->pmapFlags, pmap->ref_count, pmap->spaceNum,
  374                         pmap->stats.resident_count,
  375                         pmap->stats.wired_count);
  376 
  377                 db_printf("lists = %d, rand = %08X, visits = %016llX, searches = %08X\n",
  378                         pmap->pmapCurLists, pmap->pmapRandNum,
  379                         pmap->pmapSearchVisits, pmap->pmapSearchCnt); 
  380 
  381                 db_printf("cctl = %08X, SCSubTag = %016llX\n",
  382                         pmap->pmapCCtl, pmap->pmapSCSubTag); 
  383                 
  384                 for(i = 0; i < 16; i +=2) {
  385                         v0 = (pmap->pmapCCtl >> (31 - i) & 1);                  /* Get high order bit */
  386                         v1 = (pmap->pmapCCtl >> (30 - i) & 1);                  /* Get high order bit */
  387                         st0 = (pmap->pmapSCSubTag >> (60 - (4 * i))) & 0xF;     /* Get the sub-tag */
  388                         st1 = (pmap->pmapSCSubTag >> (56 - (4 * i))) & 0xF;     /* Get the sub-tag */
  389                         
  390                         db_printf("         %01X %01X %016llX/%016llX  %01X %01X %016llX/%016llX\n", 
  391                                 v0, st0, pmap->pmapSegCache[i].sgcESID, pmap->pmapSegCache[i].sgcVSID,
  392                                 v1, st1, pmap->pmapSegCache[i+1].sgcESID, pmap->pmapSegCache[i+1].sgcVSID);
  393                 }
  394 
  395                 db_printf("\n");
  396                 if(have_addr) break;                                                            /* Do only one if address supplied */
  397                 pmap = (pmap_t)pmap->pmap_link.next;                            /* Skip to the next */
  398                 if(pmap == kernel_pmap) break;                                          /* We've wrapped, we're done */
  399         }
  400         return;
  401 }
  402 
  403 
  404 /*
  405  *              Checks the pmap skip lists
  406  *
  407  *              
  408  *              cp pmap
  409  */
  410 void db_check_pmaps(db_expr_t addr, int have_addr, db_expr_t count, char * modif) {
  411 
  412         int                             i;
  413         unsigned int ret;
  414         uint64_t dumpa[32];
  415         pmap_t pmap;
  416         
  417         pmap = (pmap_t)addr;
  418         if(!have_addr) pmap = kernel_pmap;                                              /* If no map supplied, start with kernel */
  419         
  420         while(1) {                                                                                              /* Do them all */
  421                 ret = mapSkipListVerifyC(pmap, &dumpa);                                                 /* Check out the map */
  422                 if(!ret) db_printf("Skiplists verified ok, pmap = %08X\n", pmap);
  423                 else { 
  424                         db_printf("Verification failure at %08X, pmap = %08X\n", ret, pmap);
  425                         for(i = 0; i < 32; i += 4) {
  426                                 db_printf("R%02d  %016llX  %016llX  %016llX  %016llX\n", i,
  427                                         dumpa[i], dumpa[i + 1], dumpa[i + 2], dumpa[i + 3]);
  428                         }
  429                 }
  430                 if(have_addr) break;                                                            /* Do only one if address supplied */
  431                 pmap = (pmap_t)pmap->pmap_link.next;                            /* Skip to the next */
  432                 if(pmap == kernel_pmap) break;                                          /* We've wrapped, we're done */
  433         }
  434         
  435         return;
  436 
  437 }
  438 
  439 
  440 /*
  441  *              Displays iokit junk
  442  *
  443   *             di
  444  */
  445 
  446 void db_piokjunk(void);
  447 
  448 void db_display_iokit(db_expr_t addr, int have_addr, db_expr_t count, char * modif) {
  449 
  450         db_piokjunk();
  451 
  452         return;
  453 }
  454 
  455 /*
  456  *              Prints out a mapping control block
  457  *
  458  */
  459  
  460 void db_dumpmapping(struct mapping *mp) {                                       /* Dump out a mapping */
  461 
  462         pmap_t pmap;
  463         int i;
  464 
  465         db_printf("Dump of mapping block: %08X,  pmap: %08X (%016llX)\n", mp, pmapTrans[mp->mpSpace].pmapVAddr, 
  466                 pmapTrans[mp->mpSpace].pmapPAddr);                      /* Header */
  467         db_printf("              mpFlags: %08X\n", mp->mpFlags);                 
  468         db_printf("              mpSpace: %04X\n", mp->mpSpace);                 
  469         db_printf("              mpBSize: %04X\n", mp->u.mpBSize);                 
  470         db_printf("                mpPte: %08X\n", mp->mpPte);                 
  471         db_printf("              mpPAddr: %08X\n", mp->mpPAddr);                 
  472         db_printf("              mpVAddr: %016llX\n", mp->mpVAddr);                 
  473         db_printf("              mpAlias: %016llX\n", mp->mpAlias);                 
  474         db_printf("             mpList00: %016llX\n", mp->mpList0);                 
  475         
  476         for(i = 1; i < (mp->mpFlags & mpLists); i++) {                  /* Dump out secondary physical skip lists */
  477                 db_printf("             mpList%02d: %016llX\n", i, mp->mpList[i - 1]);     
  478         }
  479                     
  480         return;
  481 }
  482 
  483 /*
  484  *              Prints out a PTEG and PCA
  485  *
  486  */
  487  
  488 void db_dumppca(unsigned int ptegindex) {       
  489 
  490         addr64_t pteg, pca, llva;       
  491         unsigned int xpteg[32], xpca[8], space, hash, pva, seg, api, va;
  492         int i, s4bit;
  493         unsigned long long llslot, llseg, llhash;
  494 
  495         s4bit = !((PerProcTable[0].ppe_vaddr->pf.Available & pf64Bit) == 0);    /* Are we a big guy? */
  496 
  497         pteg = hash_table_base + (ptegindex << 6);                              /* Point to the PTEG */
  498         if(s4bit) pteg = hash_table_base + (ptegindex << 7);    /* Point to the PTEG */
  499         pca  = hash_table_base - ((ptegindex + 1) * 4);                 /* Point to the PCA */
  500         db_printf("PTEG = %016llX, PCA = %016llX (index = %08X)\n", pteg, pca, ptegindex);
  501         
  502         ReadReal(pteg, &xpteg[0]);                                                              /* Get first half of the pteg */
  503         ReadReal(pteg + 0x20, &xpteg[8]);                                               /* Get second half of the pteg */
  504         ReadReal(pca, &xpca[0]);                                                                /* Get pca */
  505 
  506         db_printf("PCA: free = %02X, steal = %02X, auto = %02X, misc = %02X\n", 
  507                 ((xpca[0] >> 24) & 255), ((xpca[0] >> 16) & 255), ((xpca[0] >> 8) & 255), xpca[0] & 255);
  508                 
  509         if(!s4bit) {                                                                                    /* Little guy? */
  510 
  511                 for(i = 0; i < 16; i += 2) {                                            /* Step through pteg */
  512                         db_printf("%08X %08X - ", xpteg[i], xpteg[i + 1]);      /* Dump the pteg slot */
  513                         
  514                         if(xpteg[i] & 0x80000000) db_printf("  valid - ");      /* Is it valid? */
  515                         else db_printf("invalid - ");                                   /* Nope, invalid */
  516                 
  517                         space = (xpteg[i] >> 7) & (maxAdrSp - 1);               /* Extract the space */
  518                         hash = space | (space << maxAdrSpb) | (space << (2 * maxAdrSpb));       /* Get the hash */
  519                         pva =  ptegindex ^ hash;                                                /* Get part of the vaddr */
  520                         seg = (xpteg[i] >> 7) ^ hash;                                   /* Get the segment number */
  521                         api = (xpteg[i] & 0x3F);                                                /* Get the API */
  522                         va = ((seg << (28 - maxAdrSpb)) & 0xF0000000) | (api << 22) | ((pva << 12) & 0x003FF000);       /* Get the vaddr */
  523                         db_printf("va = %08X\n", va);
  524                 }
  525         }
  526         else {
  527                 ReadReal(pteg + 0x40, &xpteg[16]);                                      /* Get third half of the pteg */
  528                 ReadReal(pteg + 0x60, &xpteg[24]);                                      /* Get fourth half of the pteg */
  529 
  530                 for(i = 0; i < 32; i += 4) {                                            /* Step through pteg */
  531                         db_printf("%08X%08X %08X%08X - ", xpteg[i], xpteg[i + 1], xpteg[i + 2], xpteg[i + 3]);  /* Dump the pteg slot */
  532                         
  533                         if(xpteg[i + 1] & 1) db_printf("  valid - ");   /* Is it valid? */
  534                         else db_printf("invalid - ");                                   /* Nope, invalid */
  535 
  536                         llslot = ((long long)xpteg[i] << 32) | (long long)xpteg[i + 1]; /* Make a long long version of this */ 
  537                         space = (llslot >> 12) & (maxAdrSp - 1);                /* Extract the space */
  538                         llhash = (unsigned long long)space | ((unsigned long long)space << maxAdrSpb) | ((unsigned long long)space << (2 * maxAdrSpb)); /* Get the hash */
  539                         llhash = llhash & 0x0000001FFFFFFFFFULL;                /* Make sure we stay within supported ranges */
  540                         pva =  (unsigned long long)ptegindex ^ llhash;  /* Get part of the vaddr */
  541                         llseg = (llslot >> 12) ^ llhash;                                /* Get the segment number */
  542                         api = (llslot >> 7) & 0x1F;                                             /* Get the API */
  543                         llva = ((llseg << (28 - maxAdrSpb)) & 0xFFFFFFFFF0000000ULL) | (api << 23) | ((pva << 12) & 0x007FF000);        /* Get the vaddr */
  544                         db_printf("va = %016llX\n", llva);
  545                 }
  546         }
  547 
  548         return;
  549 }
  550 
  551 
  552 /*
  553  *              Print out 256 bytes of virtual storage
  554  *
  555  *              
  556  *              dv [entaddr] [space]
  557  *              address must be on 32-byte boundary.  It will be rounded down if not
  558  */
  559 void db_display_virtual(db_expr_t addr, int have_addr, db_expr_t count, char * modif) {
  560 
  561         int                     i, size, lines, rlines;
  562         unsigned int    xbuf[8];
  563         db_expr_t       xspace;
  564         pmap_t          pmap;
  565 
  566         mapping_t       *mp, *mpv;
  567         addr64_t        pa;
  568         ppnum_t         pnum;
  569 
  570         if (db_expression(&xspace)) {                                                   /* Parse the space ID */
  571                 if(xspace >= (1 << maxAdrSpb)) {                                        /* Check if they gave us a sane space number */
  572                         db_printf("Invalid space ID: %llX - max is %X\n", xspace, (1 << maxAdrSpb) - 1);
  573                         return;
  574                 }
  575                 dvspace = xspace;                                                                       /* Get the space or set default */
  576         }
  577         
  578         pmap = (pmap_t)pmapTrans[dvspace].pmapVAddr;                    /* Find the pmap address */
  579         if((unsigned int)pmap == 0) {                                                   /* Is there actually a pmap here? */
  580                 db_printf("Address space not found: %X\n", dvspace);    /* Complain */
  581                 return;
  582         }
  583         
  584         addr &= -32;
  585         
  586         size = 4096 - (addr & 0x00000FFF);                                              /* Bytes left on page */
  587         lines = size / 32;                                                                              /* Number of lines in first or only part */
  588         if(lines > 8) lines = 8;
  589         rlines = 8 - lines;
  590         if(rlines < 0) lines = 0;
  591         
  592         db_printf("Dumping %016llX (pmap = %08X, space = %X); ", addr, pmap, dvspace);
  593 
  594         pnum = pmap_find_phys(pmap, (addr64_t)addr);                    /* Phynd the Physical */
  595         if(!pnum) {                                                                                             /* Did we find one? */
  596                 db_printf("Not mapped\n");      
  597                 return;                                                                                         /* Didn't find any, return FALSE... */
  598         }
  599 
  600         pa = (addr64_t)(pnum << 12) | (addr64_t)(addr & 0xFFF); /* Get the physical address */
  601         db_printf("phys = %016llX\n", pa);
  602 
  603         for(i=0; i<lines; i++) {                                                                /* Print n bytes */
  604                 ReadReal(pa, &xbuf[0]);                                                         /* Get the real storage data */
  605                 db_printf("%016llX   %08X %08X %08X %08X  %08X %08X %08X %08X\n", addr, /* Print a line */
  606                         xbuf[0], xbuf[1], xbuf[2], xbuf[3], 
  607                         xbuf[4], xbuf[5], xbuf[6], xbuf[7]);
  608                 addr = (db_expr_t)(addr + 0x00000020);                          /* Point to next address */
  609                 pa = pa + 0x00000020;                                                           /* Point to next address */
  610         }
  611         db_next = addr;
  612         
  613         if(!rlines) return;
  614         
  615         db_printf("Dumping %016llX (pmap = %08X, space = %X); ", addr, pmap, dvspace);
  616 
  617         pnum = pmap_find_phys(pmap, (addr64_t)((unsigned int)addr));    /* Phynd the Physical */
  618         if(!pnum) {                                                                                             /* Did we find one? */
  619                 db_printf("Not mapped\n");      
  620                 return;                                                                                         /* Didn't find any, return FALSE... */
  621         }
  622 
  623         pa = (addr64_t)(pnum << 12) | (addr64_t)((unsigned int)addr & 0xFFF);   /* Get the physical address */
  624         db_printf("phys = %016llX\n", pa);
  625 
  626         for(i=0; i<rlines; i++) {                                                               /* Print n bytes */
  627                 ReadReal(pa, &xbuf[0]);                                                         /* Get the real storage data */
  628                 db_printf("%016llX   %08X %08X %08X %08X  %08X %08X %08X %08X\n", addr, /* Print a line */
  629                         xbuf[0], xbuf[1], xbuf[2], xbuf[3], 
  630                         xbuf[4], xbuf[5], xbuf[6], xbuf[7]);
  631                 addr = (db_expr_t)(addr + 0x00000020);                          /* Point to next address */
  632                 pa = pa + 0x00000020;                                                           /* Point to next address */
  633         }
  634         db_next = addr;
  635 
  636 
  637 }
  638 
  639 
  640 /*
  641  *              Print out savearea stuff
  642  *
  643  *              
  644  *              ds 
  645  */
  646 
  647 #define chainmax 32
  648 
  649 void db_display_save(db_expr_t addr, int have_addr, db_expr_t count, char * modif) {
  650 
  651         int                             i, j, totsaves, tottasks, taskact, chainsize, vmid, didvmhead;
  652         processor_set_t pset = &default_pset;
  653         task_t                  task;
  654         thread_act_t    act;
  655         savearea                *save;
  656         vmmCntrlTable   *CTable;
  657         
  658         tottasks = 0;
  659         totsaves = 0;
  660         
  661         for(task = (task_t)pset->tasks.next; task != (task_t)&pset->tasks.next; task = (task_t)task->pset_tasks.next) { /* Go through the tasks */
  662                 taskact = 0;                                                            /* Reset activation count */
  663                 db_printf("\nTask %4d @%08X:\n", tottasks, task);       /* Show where we're at */
  664                 for(act = (thread_act_t)task->threads.next; act != (thread_act_t)&task->threads; act = (thread_act_t)act->task_threads.next) {  /* Go through activations */
  665                         db_printf("   Act %4d @%08X - p: %08X  current context: %08X\n",
  666                                           taskact, act, act->machine.pcb, act->machine.curctx);                                 
  667                                         
  668                         save = (savearea *)act->machine.pcb;            /* Set the start of the normal chain */
  669                         chainsize = 0;
  670                         
  671                         db_printf("      General context - fp: %08X  fl: %08X  fc: %d  vp: %08X  vl: %08X  vp: %d\n",
  672                                 act->machine.facctx.FPUsave, act->machine.facctx.FPUlevel, act->machine.facctx.FPUcpu,          
  673                                 act->machine.facctx.VMXsave, act->machine.facctx.VMXlevel, act->machine.facctx.VMXcpu);
  674                         
  675                         while(save) {                                                   /* Do them all */
  676                                 totsaves++;                                                     /* Count savearea */
  677                                 db_printf("         Norm %08X: %016llX %016llX - tot = %d\n", save, save->save_srr0, save->save_srr1, totsaves);
  678                                 save = (savearea *)save->save_hdr.save_prev;    /* Next one */
  679                                 if(chainsize++ > chainmax) {            /* See if we might be in a loop */
  680                                         db_printf("         Chain terminated by count (%d) before %08X\n", chainmax, save);
  681                                         break;
  682                                 }
  683                         }
  684                         
  685                         save = (savearea *)act->machine.facctx.FPUsave;         /* Set the start of the floating point chain */
  686                         chainsize = 0;
  687                         while(save) {                                                   /* Do them all */
  688                                 totsaves++;                                                     /* Count savearea */
  689                                 db_printf("         FPU  %08X: %08X - tot = %d\n", save, save->save_hdr.save_level, totsaves);
  690                                 save = (savearea *)save->save_hdr.save_prev;    /* Next one */
  691                                 if(chainsize++ > chainmax) {            /* See if we might be in a loop */
  692                                         db_printf("         Chain terminated by count (%d) before %08X\n", chainmax, save);
  693                                         break;
  694                                 }
  695                         }
  696                         
  697                         save = (savearea *)act->machine.facctx.VMXsave;         /* Set the start of the floating point chain */
  698                         chainsize = 0;
  699                         while(save) {                                                   /* Do them all */
  700                                 totsaves++;                                                     /* Count savearea */
  701                                 db_printf("         Vec  %08X: %08X - tot = %d\n", save, save->save_hdr.save_level, totsaves);
  702                                 save = (savearea *)save->save_hdr.save_prev;    /* Next one */
  703                                 if(chainsize++ > chainmax) {            /* See if we might be in a loop */
  704                                         db_printf("         Chain terminated by count (%d) before %08X\n", chainmax, save);
  705                                         break;
  706                                 }
  707                         }
  708                         
  709                         if(CTable = act->machine.vmmControl) {          /* Are there virtual machines? */
  710                                 
  711                                 for(vmid = 0; vmid < kVmmMaxContexts; vmid++) {
  712                                         
  713                                         if(!(CTable->vmmc[vmid].vmmFlags & vmmInUse)) continue; /* Skip if vm is not in use */
  714                                         
  715                                         if(!CTable->vmmc[vmid].vmmFacCtx.FPUsave && !CTable->vmmc[vmid].vmmFacCtx.VMXsave) continue;    /* If neither types, skip this vm */
  716                                         
  717                                         db_printf("      VMachine ID %3d - fp: %08X  fl: %08X  fc: %d  vp: %08X  vl: %08X  vp: %d\n", vmid,     /* Title it */
  718                                                 CTable->vmmc[vmid].vmmFacCtx.FPUsave, CTable->vmmc[vmid].vmmFacCtx.FPUlevel, CTable->vmmc[vmid].vmmFacCtx.FPUcpu,               
  719                                                 CTable->vmmc[vmid].vmmFacCtx.VMXsave, CTable->vmmc[vmid].vmmFacCtx.VMXlevel, CTable->vmmc[vmid].vmmFacCtx.VMXcpu
  720                                         );
  721                                         
  722                                         save = (savearea *)CTable->vmmc[vmid].vmmFacCtx.FPUsave;        /* Set the start of the floating point chain */
  723                                         chainsize = 0;
  724                                         while(save) {                                           /* Do them all */
  725                                                 totsaves++;                                             /* Count savearea */
  726                                                 db_printf("         FPU  %08X: %08X - tot = %d\n", save, save->save_hdr.save_level, totsaves);
  727                                                 save = (savearea *)save->save_hdr.save_prev;    /* Next one */
  728                                                 if(chainsize++ > chainmax) {    /* See if we might be in a loop */
  729                                                         db_printf("         Chain terminated by count (%d) before %08X\n", chainmax, save);
  730                                                         break;
  731                                                 }
  732                                         }
  733                                         
  734                                         save = (savearea *)CTable->vmmc[vmid].vmmFacCtx.VMXsave;        /* Set the start of the floating point chain */
  735                                         chainsize = 0;
  736                                         while(save) {                                           /* Do them all */
  737                                                 totsaves++;                                             /* Count savearea */
  738                                                 db_printf("         Vec  %08X: %08X - tot = %d\n", save, save->save_hdr.save_level, totsaves);
  739                                                 save = (savearea *)save->save_hdr.save_prev;    /* Next one */
  740                                                 if(chainsize++ > chainmax) {    /* See if we might be in a loop */
  741                                                         db_printf("         Chain terminated by count (%d) before %08X\n", chainmax, save);
  742                                                         break;
  743                                                 }
  744                                         }
  745                                 }
  746                         }
  747                         taskact++;
  748                 }
  749                 tottasks++;
  750         }
  751         
  752         db_printf("Total saveareas accounted for: %d\n", totsaves);
  753         return;
  754 }
  755 
  756 /*
  757  *              Print out extra registers
  758  *
  759  *              
  760  *              dx 
  761  */
  762 
  763 extern unsigned int dbfloats[33][2];
  764 extern unsigned int dbvecs[33][4];
  765 extern unsigned int dbspecrs[336];
  766 
  767 void db_display_xregs(db_expr_t addr, int have_addr, db_expr_t count, char * modif) {
  768 
  769         int                             i, j, pents;
  770 
  771         stSpecrs(dbspecrs);                                                                             /* Save special registers */
  772         if(PerProcTable[0].ppe_vaddr->pf.Available & pf64Bit) {
  773                 db_printf("PIR:    %08X\n", dbspecrs[0]);
  774                 db_printf("PVR:    %08X\n", dbspecrs[1]);
  775                 db_printf("SDR1:   %08X.%08X\n", dbspecrs[26], dbspecrs[27]);
  776                 db_printf("HID0:   %08X.%08X\n", dbspecrs[28], dbspecrs[29]);
  777                 db_printf("HID1:   %08X.%08X\n", dbspecrs[30], dbspecrs[31]);
  778                 db_printf("HID4:   %08X.%08X\n", dbspecrs[32], dbspecrs[33]);
  779                 db_printf("HID5:   %08X.%08X\n", dbspecrs[34], dbspecrs[35]);
  780                 db_printf("SPRG0:  %08X.%08X %08X.%08X\n", dbspecrs[18], dbspecrs[19], dbspecrs[20], dbspecrs[21]);
  781                 db_printf("SPRG2:  %08X.%08X %08X.%08X\n", dbspecrs[22], dbspecrs[23], dbspecrs[24], dbspecrs[25]);
  782                 db_printf("\n");
  783                 for(i = 0; i < (64 * 4); i += 4) {
  784                         db_printf("SLB %02d: %08X.%08X %08X.%08X\n", i / 4, dbspecrs[80 + i], dbspecrs[81 + i], dbspecrs[82 + i], dbspecrs[83 + i]);
  785                 }
  786         }
  787         else {  
  788                 db_printf("PIR:    %08X\n", dbspecrs[0]);
  789                 db_printf("PVR:    %08X\n", dbspecrs[1]);
  790                 db_printf("SDR1:   %08X\n", dbspecrs[22]);
  791                 db_printf("HID0:   %08X\n", dbspecrs[39]);
  792                 db_printf("HID1:   %08X\n", dbspecrs[40]);
  793                 db_printf("L2CR:   %08X\n", dbspecrs[41]);
  794                 db_printf("MSSCR0: %08X\n", dbspecrs[42]);
  795                 db_printf("MSSCR1: %08X\n", dbspecrs[43]);
  796                 db_printf("THRM1:  %08X\n", dbspecrs[44]);
  797                 db_printf("THRM2:  %08X\n", dbspecrs[45]);
  798                 db_printf("THRM3:  %08X\n", dbspecrs[46]);
  799                 db_printf("ICTC:   %08X\n", dbspecrs[47]);
  800                 db_printf("L2CR2:  %08X\n", dbspecrs[48]);
  801                 db_printf("DABR:   %08X\n", dbspecrs[49]);
  802         
  803                 db_printf("DBAT: %08X %08X %08X %08X\n", dbspecrs[2], dbspecrs[3], dbspecrs[4], dbspecrs[5]);
  804                 db_printf("      %08X %08X %08X %08X\n", dbspecrs[6], dbspecrs[7], dbspecrs[8], dbspecrs[9]);
  805                 db_printf("IBAT: %08X %08X %08X %08X\n", dbspecrs[10], dbspecrs[11], dbspecrs[12], dbspecrs[13]);
  806                 db_printf("      %08X %08X %08X %08X\n", dbspecrs[14], dbspecrs[15], dbspecrs[16], dbspecrs[17]);
  807                 db_printf("SPRG: %08X %08X %08X %08X\n", dbspecrs[18], dbspecrs[19], dbspecrs[20], dbspecrs[21]);
  808                 db_printf("\n");
  809                 for(i = 0; i < 16; i += 8) {                                            /* Print 8 at a time */
  810                         db_printf("SR%02d: %08X %08X %08X %08X %08X %08X %08X %08X\n", i,
  811                                 dbspecrs[23+i], dbspecrs[24+i], dbspecrs[25+i], dbspecrs[26+i], 
  812                                 dbspecrs[27+i], dbspecrs[28+i], dbspecrs[29+i], dbspecrs[30+i]); 
  813                 }
  814         }
  815         
  816         db_printf("\n");
  817 
  818         stFloat(dbfloats);                                                                              /* Save floating point registers */
  819         for(i = 0; i < 32; i += 4) {                                                    /* Print 4 at a time */
  820                 db_printf("F%02d: %08X %08X  %08X %08X  %08X %08X  %08X %08X\n", i,
  821                         dbfloats[i][0], dbfloats[i][1], dbfloats[i+1][0], dbfloats[i+1][1], 
  822                         dbfloats[i+2][0], dbfloats[i+2][1], dbfloats[i+3][0], dbfloats[i+3][1]); 
  823         }
  824         db_printf("FCR: %08X %08X\n", dbfloats[32][0], dbfloats[32][1]);        /* Print FSCR */
  825         
  826         if(!stVectors(dbvecs)) return;                                                  /* Return if not Altivec capable */
  827         
  828         db_printf("\n");
  829         
  830         for(i = 0; i < 32; i += 2) {                                                    /* Print 2 at a time */
  831                 db_printf("V%02d: %08X %08X %08X %08X  %08X %08X %08X %08X\n", i,
  832                         dbvecs[i][0], dbvecs[i][1], dbvecs[i][2], dbvecs[i][3], 
  833                         dbvecs[i+1][0], dbvecs[i+1][1], dbvecs[i+1][2], dbvecs[i+1][3]); 
  834         }
  835         db_printf("VCR: %08X %08X %08X %08X\n", dbvecs[32][0], dbvecs[32][1], dbvecs[32][2], dbvecs[32][3]);    /* Print VSCR */
  836 
  837         return;                                                                                                 /* Tell them we did it */
  838 
  839 
  840 }
  841 
  842 /*
  843  *              Check check mappings and hash table for consistency
  844  *
  845   *             cm
  846  */
  847 void db_check_mappings(db_expr_t addr, int have_addr, db_expr_t count, char * modif) {
  848 
  849         addr64_t  pteg, pca, llva, lnextva;     
  850         unsigned int xpteg[32], xpca[8], space, hash, pva, seg, api, va, free, free2, xauto, PTEGcnt, wimgkk, wimgxx, slotoff;
  851         int i, j, fnderr, slot, slot2, k, s4bit;
  852         pmap_t pmap;
  853         mapping_t *mp;
  854         ppnum_t ppn, pa, aoff;
  855         unsigned long long llslot, llseg, llhash;
  856         
  857         s4bit = 0;                                                                                              /* Assume dinky? */
  858         if(PerProcTable[0].ppe_vaddr->pf.Available & pf64Bit) s4bit = 1;        /* Are we a big guy? */
  859         
  860         PTEGcnt = hash_table_size / 64;                                                 /* Get the number of PTEGS */
  861         if(s4bit) PTEGcnt = PTEGcnt / 2;                                                /* PTEGs are twice as big */    
  862 
  863         pteg = hash_table_base;                                                                 /* Start of hash table */
  864         pca = hash_table_base - 4;                                                              /* Start of PCA */
  865         
  866         for(i = 0; i < PTEGcnt; i++) {                                                  /* Step through them all */
  867 
  868                 fnderr = 0;
  869         
  870                 ReadReal(pteg, &xpteg[0]);                                                      /* Get first half of the pteg */
  871                 ReadReal(pteg + 0x20, &xpteg[8]);                                       /* Get second half of the pteg */
  872                 if(s4bit) {                                                                                     /* See if we need the other half */
  873                         ReadReal(pteg + 0x40, &xpteg[16]);                              /* Get third half of the pteg */
  874                         ReadReal(pteg + 0x60, &xpteg[24]);                              /* Get fourth half of the pteg */
  875                 }
  876                 ReadReal(pca, &xpca[0]);                                                        /* Get pca */
  877         
  878                 if(xpca[0] & 0x00000001) {                                                      /* Is PCA locked? */
  879                         db_printf("Unexpected locked PCA\n");                   /* Yeah, this may be bad */
  880                         fnderr = 1;                                                                             /* Remember to print the pca/pteg pair later */
  881                 }
  882 
  883                 free = 0x80000000;
  884                 
  885                 for(j = 0; j < 7; j++) {                                                        /* Search for duplicates */
  886                         slot = j * 2;                                                                   /* Point to the slot */
  887                         if(s4bit) slot = slot * 2;                                              /* Adjust for bigger slots */
  888                         if(!(xpca[0] & free)) {                                                 /* Check more if slot is allocated */
  889                                 for(k = j + 1; k < 8; k++) {                            /* Search remaining slots */
  890                                         slot2 = k * 2;                                                  /* Point to the slot */
  891                                         if(s4bit) slot2 = slot2 * 2;                    /* Adjust for bigger slots */
  892                                         if((xpteg[slot] == xpteg[slot2]) 
  893                                            && (!s4bit || (xpteg[slot + 1] == xpteg[slot2 + 1]))) {              /* Do we have duplicates? */
  894                                                 db_printf("Duplicate tags in pteg, slot %d and slot %d\n", j, k);
  895                                                 fnderr = 1;
  896                                         }
  897                                 }
  898                         }
  899                         free = free >> 1;                                                               /* Move slot over */
  900                 }
  901                 
  902                 free = 0x80000000;
  903                 xauto = 0x00008000;
  904 
  905                 for(j = 0; j < 8; j++) {                                                        /* Step through the slots */
  906                 
  907                         slot = j * 2;                                                                   /* Point to the slot */
  908                         if(s4bit) slot = slot * 2;                                              /* Hagfish? */
  909                         if(xpca[0] & free) {                                                    /* Check if marked free */
  910                                 if((!s4bit && (xpteg[slot] & 0x80000000))       /* Is a supposedly free slot valid? */
  911                                    || (s4bit && (xpteg[slot + 1] & 1))) {       
  912                                         db_printf("Free slot still valid - %d\n", j);   
  913                                         fnderr = 1;
  914                                 }       
  915                         }
  916                         else {                                                                                  /* We have an in use slot here */
  917                                                                 
  918                                 if(!(!s4bit && (xpteg[slot] & 0x80000000))      /* Is a supposedly in use slot valid? */
  919                                    && !(s4bit && (xpteg[slot + 1] & 1))) {      
  920                                         db_printf("Inuse slot not valid - %d\n", j);    
  921                                         fnderr = 1;
  922                                 }       
  923                                 else {                                                                          /* Slot is valid, check mapping */
  924                                         if(!s4bit) {                                                    /* Not Hagfish? */
  925                                                 space = (xpteg[slot] >> 7) & (maxAdrSp - 1);    /* Extract the space */
  926                                                 hash = space | (space << maxAdrSpb) | (space << (2 * maxAdrSpb));       /* Get the hash */
  927                                                 pva =  i ^ hash;                                        /* Get part of the vaddr */
  928                                                 seg = (xpteg[slot] >> 7) ^ hash;        /* Get the segment number */
  929                                                 api = (xpteg[slot] & 0x3F);                     /* Get the API */
  930                                                 va = ((seg << (28 - maxAdrSpb)) & 0xF0000000) | (api << 22) | ((pva << 12) & 0x003FF000);       /* Get the vaddr */
  931                                                 llva = (addr64_t)va;                            /* Make this a long long */
  932                                                 wimgxx = xpteg[slot + 1] & 0x7F;        /* Get the wimg and pp */
  933                                                 ppn = xpteg[slot + 1] >> 12;            /* Get physical page number */
  934                                                 slotoff = (i * 64) + (j * 8) | 1;       /* Get offset to slot and valid bit */
  935                                         }
  936                                         else {                                                                  /* Yes, Hagfish */
  937                                                 llslot = ((long long)xpteg[slot] << 32) | (long long)xpteg[slot + 1];   /* Make a long long version of this */ 
  938                                                 space = (llslot >> 12) & (maxAdrSp - 1);        /* Extract the space */
  939                                                 llhash = (unsigned long long)space | ((unsigned long long)space << maxAdrSpb) | ((unsigned long long)space << (2 * maxAdrSpb)); /* Get the hash */
  940                                                 llhash = llhash & 0x0000001FFFFFFFFFULL;        /* Make sure we stay within supported ranges */
  941                                                 pva =  i ^ llhash;                                      /* Get part of the vaddr */
  942                                                 llseg = ((llslot >> 12) ^ llhash);      /* Get the segment number */
  943                                                 api = (llslot >> 7) & 0x1F;                     /* Get the API */
  944                                                 llva = ((llseg << (28 - maxAdrSpb)) & 0xFFFFFFFFF0000000ULL) | (api << 23) | ((pva << 12) & 0x007FF000);        /* Get the vaddr */
  945                                                 wimgxx = xpteg[slot + 3] & 0x7F;        /* Get the wimg and pp */
  946                                                 ppn =  (xpteg[slot + 2] << 20) | (xpteg[slot + 3] >> 12);       /* Get physical page number */
  947                                                 slotoff = (i * 128) + (j * 16) | 1;             /* Get offset to slot and valid bit */
  948                                         }
  949                                         
  950                                         pmap = pmapTrans[space].pmapVAddr;      /* Find the pmap address */
  951                                         if(!pmap) {                                                             /* The pmap is not in use */
  952                                                 db_printf("The space %08X is not assigned to a pmap, slot = %d\n", space, slot);        /* Say we are wrong */
  953                                                 fnderr = 1;
  954                                                 goto dcmout;
  955                                         }
  956 
  957                                         if (pmap->pmapFlags & pmapVMgsaa) {
  958                                                 unsigned int ret;
  959                                                 mapping_t mpcopy;
  960                                                 ret = hw_find_map_gv(pmap, llva, &mpcopy);
  961                                         } else {
  962                                                 mp = hw_find_map(pmap, llva, &lnextva);         /* Try to find the mapping for this address */
  963         //                                      db_printf("%08X - %017llX\n", mp, llva);
  964                                                 if((unsigned int)mp == mapRtBadLk) {    /* Did we lock up ok? */
  965                                                         db_printf("Timeout locking mapping for for virtual address %016ll8X, slot = %d\n", llva, j);    
  966                                                         return;
  967                                                 }
  968                                                 
  969                                                 if(!mp) {                                                               /* Did we find one? */
  970                                                         db_printf("Not mapped, slot = %d, va = %08X\n", j, (unsigned int)llva); 
  971                                                         fnderr = 1;
  972                                                         goto dcmout;
  973                                                 }
  974                                                 
  975                                                 if((mp->mpFlags & 0xFF000000) > 0x01000000) {   /* Is busy count too high? */
  976                                                         db_printf("Busy count too high, slot = %d\n", j);
  977                                                         fnderr = 1;
  978                                                 }
  979                                                 
  980                                                 if((mp->mpFlags & mpType) == mpBlock) {         /* Is this a block map? */
  981                                                         if(!(xpca[0] & xauto)) {                                /* Is it marked as such? */
  982                                                                 db_printf("mapping marked as block, PCA is not, slot = %d\n", j);
  983                                                                 fnderr = 1;
  984                                                         }
  985                                                 }
  986                                                 else {                                                                  /* Is a block */
  987                                                         if(xpca[0] & xauto) {                           /* Is it marked as such? */
  988                                                                 db_printf("mapping not marked as block, PCA is, slot = %d\n", j);
  989                                                                 fnderr = 1;
  990                                                         }
  991                                                         if(mp->mpPte != slotoff) {                      /* See if mapping PTEG offset is us */
  992                                                                 db_printf("mapping does not point to PTE, slot = %d\n", j);
  993                                                                 fnderr = 1;
  994                                                         }
  995                                                 }
  996                                         
  997                                                 wimgkk = (unsigned int)mp->mpVAddr;             /* Get last half of vaddr where keys, etc are */
  998                                                 wimgkk = (wimgkk ^ wimgxx) & 0x7F;              /* XOR to find differences from PTE */
  999                                                 if(wimgkk) {                                                    /* See if key in PTE is what we want */
 1000                                                         db_printf("key or WIMG does not match, slot = %d\n", j);
 1001                                                         fnderr = 1;
 1002                                                 }
 1003                                                 
 1004                                                 aoff = (ppnum_t)((llva >> 12) - (mp->mpVAddr >> 12));   /* Get the offset from vaddr */
 1005                                                 pa = aoff + mp->mpPAddr;                                /* Get the physical page number we expect */
 1006                                                 if(pa != ppn) {                                                 /* Is physical address expected? */
 1007                                                         db_printf("Physical address does not match, slot = %d\n", j);
 1008                                                         fnderr = 1;
 1009                                                 }
 1010                 
 1011                                                 mapping_drop_busy(mp);                                  /* We're done with the mapping */
 1012                                         }
 1013                                 }
 1014                                 
 1015                         }
 1016 dcmout:
 1017                         free = free >> 1;
 1018                         xauto = xauto >> 1;
 1019                 }
 1020 
 1021 
 1022                 if(fnderr)db_dumppca(i);                                                        /* Print if error */
 1023 
 1024                 pteg = pteg + 64;                                                                       /* Go to the next one */
 1025                 if(s4bit) pteg = pteg + 64;                                                     /* Hagfish? */
 1026                 pca = pca - 4;                                                                          /* Go to the next one */
 1027 
 1028 
 1029         }
 1030 
 1031         return;
 1032 }
 1033 
 1034 /*
 1035  *              Displays all of the kmods in the system.
 1036  *
 1037   *             dp
 1038  */
 1039 void db_display_kmod(db_expr_t addr, int have_addr, db_expr_t count, char * modif) {
 1040 
 1041         kmod_info_t     *kmd;
 1042         unsigned int strt, end;
 1043         
 1044         kmd = kmod;                                                     /* Start at the start */
 1045         
 1046         db_printf("info      addr      start    - end       name ver\n");
 1047 
 1048         while(kmd) {                                            /* Dump 'em all */
 1049                 strt = (unsigned int)kmd->address + kmd->hdr_size;      /* Get start of kmod text */
 1050                 end = (unsigned int)kmd->address + kmd->size;                   /* Get end of kmod */
 1051                 db_printf("%08X  %08X  %08X - %08X: %s, %s\n", kmd, kmd->address, strt, end, 
 1052                         kmd->name, kmd->version);
 1053                 kmd = kmd->next;                                /* Step to it */
 1054         }
 1055 
 1056         return;
 1057 }
 1058 
 1059 /*
 1060  *              Displays stuff
 1061  *
 1062   *             gs
 1063  */
 1064 unsigned char xxgpo[36] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
 1065 
 1066 void db_gsnoop(db_expr_t addr, int have_addr, db_expr_t count, char * modif) {
 1067 
 1068         int i, j;
 1069         unsigned char *gp, gpn[36];
 1070 #define ngpr 34
 1071         
 1072         gp = (unsigned char *)0x8000005C;
 1073         
 1074         for(i = 0; i < ngpr; i++) gpn[i] = gp[i];       /* Copy 'em */
 1075         
 1076         for(i = 0; i < ngpr; i++) {
 1077                 db_printf("%02X ", gpn[i]);
 1078         }
 1079         db_printf("\n");
 1080         
 1081         for(i = 0; i < ngpr; i++) {
 1082                 if(gpn[i] != xxgpo[i]) db_printf("^^ ");
 1083                 else  db_printf("   ");
 1084         }
 1085         db_printf("\n");
 1086         
 1087         for(i = 0; i < ngpr; i++) xxgpo[i] = gpn[i];    /* Save 'em */
 1088 
 1089         return;
 1090 }
 1091 
 1092 
 1093 void Dumbo(void);
 1094 void Dumbo(void){
 1095 }

Cache object: 3c2b30f7de18910d81066209d1d9f601


[ 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.