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