darwin-xnu/osfmk/ppc/db_low_trace.c
<<
>>
Prefs
   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
  64void db_dumppca(unsigned int ptegindex);        
  65void db_dumpmapping(struct mapping *mp);                                        /* Dump out a mapping */
  66extern kmod_info_t *kmod;                                                                       /* Find the kmods */
  67
  68db_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 */
  80void 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 */
 160void 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
 175unsigned 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        '0', '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 */
 201void 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 */
 237void 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
 252unsigned int    dvspace = 0;
 253
 254/*
 255 *              Print out virtual to real translation information
 256 *
 257 *              
 258 *              dm vaddr [space] (defaults to last entered) 
 259 */
 260void 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 */
 310void 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 */
 358void 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 */
 410void 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
 446void db_piokjunk(void);
 447
 448void 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 
 460void 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 
 488void 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 */
 559void 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
 649void 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
 763extern unsigned int dbfloats[33][2];
 764extern unsigned int dbvecs[33][4];
 765extern unsigned int dbspecrs[336];
 766
 767void 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 */
 847void 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                        }
1016dcmout:
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 */
1039void 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 */
1064unsigned 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
1066void 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
1093void Dumbo(void);
1094void Dumbo(void){
1095}
1096
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.