]> git.saurik.com Git - apple/xnu.git/blame - osfmk/ppc/db_low_trace.c
xnu-1228.15.4.tar.gz
[apple/xnu.git] / osfmk / ppc / db_low_trace.c
CommitLineData
1c79356b 1/*
2d21ac55 2 * Copyright (c) 2000-2007 Apple Inc. All rights reserved.
1c79356b 3 *
2d21ac55 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
1c79356b 5 *
2d21ac55
A
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.
8f6c56a5 14 *
2d21ac55
A
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
8f6c56a5
A
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
2d21ac55
A
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.
8f6c56a5 25 *
2d21ac55 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
1c79356b
A
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>
1c79356b 67#include <ppc/savearea.h>
9bccf70c 68#include <ppc/vmachmon.h>
1c79356b 69
55e303ae 70void db_dumppca(unsigned int ptegindex);
1c79356b 71void db_dumpmapping(struct mapping *mp); /* Dump out a mapping */
1c79356b
A
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 */
2d21ac55
A
86void
87db_low_trace(db_expr_t addr, boolean_t have_addr, db_expr_t count, char *modif)
88{
1c79356b
A
89 int c, i;
90 unsigned int tempx, cnt;
55e303ae 91 unsigned int xTraceCurr, xTraceStart, xTraceEnd, cxltr;
1c79356b
A
92 db_addr_t next_addr;
93 LowTraceRecord xltr;
94 unsigned char cmark;
55e303ae 95 addr64_t xxltr;
1c79356b
A
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
55e303ae
A
115 if((unsigned int)addr&0x0000007F) { /* Proper alignment? */
116 db_printf("address not aligned on trace entry boundary (0x80)\n"); /* Tell 'em */
1c79356b
A
117 return; /* Leave... */
118 }
119
55e303ae
A
120 xxltr = addr; /* Set the start */
121 cxltr = ((xTraceCurr == xTraceStart ? xTraceEnd : xTraceCurr) - sizeof(LowTraceRecord)); /* Get address of newest entry */
1c79356b
A
122
123 db_low_trace_prev = addr; /* Starting point */
124
125 for(i=0; i < cnt; i++) { /* Dump the 16 (or all) entries */
126
55e303ae
A
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 */
1c79356b 131
a3d08fcd 132 db_printf("\n%s%08llX %1X %08X %08X - %04X", (xxltr != cxltr ? " " : "*"),
1c79356b 133 xxltr,
a3d08fcd 134 (xltr.LTR_cpu & 0xFF), xltr.LTR_timeHi, xltr.LTR_timeLo,
55e303ae 135 (xltr.LTR_excpt & 0x8000 ? 0xFFFF : xltr.LTR_excpt * 64)); /* Print the first line */
a3d08fcd
A
136
137 if(xltr.LTR_cpu & 0xFF00) db_printf(", sflgs = %02X\n", ((xltr.LTR_cpu >> 8) & 0xFF));
138 else db_printf("\n");
55e303ae
A
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);
1c79356b
A
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);
1c79356b
A
157}
158
159
160/*
161 * Print out 256 bytes
162 *
163 *
164 * dl [entaddr]
165 */
2d21ac55
A
166void
167db_display_long(db_expr_t addr, __unused boolean_t have_addr,
168 db_expr_t count, char * modif)
169{
1c79356b
A
170 int i;
171
172 for(i=0; i<8; i++) { /* Print 256 bytes */
55e303ae 173 db_printf("%016llX %08X %08X %08X %08X %08X %08X %08X %08X\n", addr, /* Print a line */
1c79356b
A
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]);
55e303ae 176 addr=(db_expr_t)(addr+0x00000020); /* Point to next address */
1c79356b
A
177 }
178 db_next = addr;
179
180
55e303ae
A
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 */
2d21ac55
A
209void
210db_display_char(db_expr_t addr, boolean_t have_addr, db_expr_t count,
211 char * modif)
212{
55e303ae
A
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
1c79356b
A
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 */
2d21ac55
A
248void
249db_display_real(db_expr_t addr, boolean_t have_addr, db_expr_t count,
250 char *modif)
251{
1c79356b
A
252 int i;
253 unsigned int xbuf[8];
254
255 for(i=0; i<8; i++) { /* Print 256 bytes */
55e303ae
A
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 */
1c79356b
A
258 xbuf[0], xbuf[1], xbuf[2], xbuf[3],
259 xbuf[4], xbuf[5], xbuf[6], xbuf[7]);
55e303ae 260 addr = addr + 0x00000020; /* Point to next address */
1c79356b
A
261 }
262 db_next = addr;
1c79356b
A
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 */
2d21ac55
A
273void
274db_display_mappings(db_expr_t addr, boolean_t have_addr, db_expr_t count,
275 char *modif)
276{
55e303ae
A
277 db_expr_t xspace;
278 pmap_t pmap;
279 addr64_t lnextva;
1c79356b 280
91447636 281 mapping_t *mp;
55e303ae
A
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 }
1c79356b 290
55e303ae
A
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 }
1c79356b 304
1c79356b
A
305 if(!mp) { /* Did we find one? */
306 db_printf("Not mapped\n");
307 return; /* Didn't find any, return FALSE... */
308 }
55e303ae
A
309
310 mapping_drop_busy(mp); /* The mapping shouldn't be changing */
311
312 db_dumpmapping(mp); /* Dump it all out */
313
2d21ac55 314 /* Tell them we did it */
55e303ae
A
315}
316
317/*
318 * Print out hash table data
319 *
320 *
321 * dh vaddr [space] (defaults to last entered)
322 */
2d21ac55
A
323void
324db_display_hash(db_expr_t addr, boolean_t have_addr, db_expr_t count,
325 char *modif)
326{
55e303ae
A
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
91447636 336 s4bit = !((PerProcTable[0].ppe_vaddr->pf.Available & pf64Bit) == 0); /* Are we a big guy? */
55e303ae
A
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 */
1c79356b 343 }
55e303ae
A
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;
1c79356b 349 }
55e303ae
A
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
2d21ac55 363 /* Tell them we did it */
1c79356b
A
364}
365
366/*
367 * Displays all of the in-use pmaps in the system.
368 *
369 * dp
370 */
2d21ac55
A
371void
372db_display_pmap(db_expr_t addr, boolean_t have_addr, db_expr_t count,
373 char *modif)
374{
1c79356b 375 pmap_t pmap;
55e303ae
A
376 int i;
377 unsigned int v0, v1, st0, st1;
1c79356b 378
55e303ae
A
379 pmap = (pmap_t)addr;
380 if(!have_addr) pmap = kernel_pmap; /* Start at the beginning */
1c79356b 381
55e303ae
A
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
1c79356b 384 while(1) { /* Do them all */
55e303ae
A
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,
1c79356b
A
389 pmap->stats.resident_count,
390 pmap->stats.wired_count);
391
55e303ae
A
392 db_printf("lists = %d, rand = %08X, visits = %016llX, searches = %08X\n",
393 pmap->pmapCurLists, pmap->pmapRandNum,
394 pmap->pmapSearchVisits, pmap->pmapSearchCnt);
1c79356b 395
55e303ae
A
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 }
1c79356b 409
de355530 410 db_printf("\n");
55e303ae
A
411 if(have_addr) break; /* Do only one if address supplied */
412 pmap = (pmap_t)pmap->pmap_link.next; /* Skip to the next */
1c79356b
A
413 if(pmap == kernel_pmap) break; /* We've wrapped, we're done */
414 }
1c79356b
A
415}
416
1c79356b 417
55e303ae
A
418/*
419 * Checks the pmap skip lists
420 *
421 *
422 * cp pmap
423 */
2d21ac55
A
424void
425db_check_pmaps(db_expr_t addr, boolean_t have_addr, db_expr_t count,
426 char *modif)
427{
55e303ae
A
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 }
1c79356b
A
450}
451
55e303ae 452
1c79356b 453/*
55e303ae 454 * Displays iokit junk
1c79356b 455 *
3a60a9f5 456 * di
1c79356b 457 */
1c79356b 458
55e303ae
A
459void db_piokjunk(void);
460
2d21ac55
A
461void
462db_display_iokit(__unused db_expr_t addr, __unused boolean_t have_addr,
463 __unused db_expr_t count, __unused char *modif)
464{
55e303ae 465 db_piokjunk();
1c79356b
A
466}
467
468/*
55e303ae 469 * Prints out a mapping control block
1c79356b
A
470 *
471 */
472
55e303ae
A
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);
91447636 482 db_printf(" mpBSize: %04X\n", mp->u.mpBSize);
55e303ae
A
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 }
1c79356b
A
492}
493
494/*
55e303ae
A
495 * Prints out a PTEG and PCA
496 *
1c79356b
A
497 */
498
55e303ae
A
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
91447636 506 s4bit = !((PerProcTable[0].ppe_vaddr->pf.Available & pf64Bit) == 0); /* Are we a big guy? */
55e303ae
A
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);
de355530 512
55e303ae
A
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 */
a3d08fcd 550 llhash = llhash & 0x0000001FFFFFFFFFULL; /* Make sure we stay within supported ranges */
55e303ae
A
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 }
1c79356b
A
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 */
2d21ac55
A
568void
569db_display_virtual(db_expr_t addr, boolean_t have_addr, db_expr_t count,
570 char *modif)
571{
1c79356b 572
55e303ae 573 int i, size, lines, rlines;
1c79356b 574 unsigned int xbuf[8];
55e303ae
A
575 db_expr_t xspace;
576 pmap_t pmap;
1c79356b 577
91447636 578 mapping_t *mp, *mpv;
55e303ae
A
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 }
1c79356b 589
55e303ae
A
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 }
1c79356b 595
55e303ae 596 addr &= -32;
1c79356b
A
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
55e303ae
A
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? */
1c79356b
A
608 db_printf("Not mapped\n");
609 return; /* Didn't find any, return FALSE... */
610 }
55e303ae
A
611
612 pa = (addr64_t)(pnum << 12) | (addr64_t)(addr & 0xFFF); /* Get the physical address */
613 db_printf("phys = %016llX\n", pa);
614
1c79356b 615 for(i=0; i<lines; i++) { /* Print n bytes */
55e303ae
A
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 */
1c79356b
A
618 xbuf[0], xbuf[1], xbuf[2], xbuf[3],
619 xbuf[4], xbuf[5], xbuf[6], xbuf[7]);
91447636 620 addr = (db_expr_t)(addr + 0x00000020); /* Point to next address */
55e303ae 621 pa = pa + 0x00000020; /* Point to next address */
1c79356b
A
622 }
623 db_next = addr;
624
625 if(!rlines) return;
626
55e303ae
A
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? */
1c79356b
A
631 db_printf("Not mapped\n");
632 return; /* Didn't find any, return FALSE... */
633 }
55e303ae
A
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
1c79356b 638 for(i=0; i<rlines; i++) { /* Print n bytes */
55e303ae
A
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 */
1c79356b
A
641 xbuf[0], xbuf[1], xbuf[2], xbuf[3],
642 xbuf[4], xbuf[5], xbuf[6], xbuf[7]);
55e303ae
A
643 addr = (db_expr_t)(addr + 0x00000020); /* Point to next address */
644 pa = pa + 0x00000020; /* Point to next address */
1c79356b
A
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
2d21ac55
A
661void
662db_display_save(db_expr_t addr, boolean_t have_addr, db_expr_t count,
663 char *modif)
664{
9bccf70c 665 int i, j, totsaves, tottasks, taskact, chainsize, vmid, didvmhead;
1c79356b
A
666 task_t task;
667 thread_act_t act;
2d21ac55 668 struct savearea *save;
9bccf70c 669 vmmCntrlTable *CTable;
1c79356b
A
670
671 tottasks = 0;
672 totsaves = 0;
673
2d21ac55 674 for(task = (task_t)tasks.next; task != (task_t)&tasks.next; task = (task_t)task->tasks.next) { /* Go through the tasks */
1c79356b
A
675 taskact = 0; /* Reset activation count */
676 db_printf("\nTask %4d @%08X:\n", tottasks, task); /* Show where we're at */
55e303ae 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 */
9bccf70c 678 db_printf(" Act %4d @%08X - p: %08X current context: %08X\n",
91447636 679 taskact, act, act->machine.pcb, act->machine.curctx);
1c79356b 680
2d21ac55 681 save = (struct savearea *)act->machine.pcb; /* Set the start of the normal chain */
1c79356b 682 chainsize = 0;
9bccf70c
A
683
684 db_printf(" General context - fp: %08X fl: %08X fc: %d vp: %08X vl: %08X vp: %d\n",
91447636
A
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);
9bccf70c 687
1c79356b
A
688 while(save) { /* Do them all */
689 totsaves++; /* Count savearea */
55e303ae 690 db_printf(" Norm %08X: %016llX %016llX - tot = %d\n", save, save->save_srr0, save->save_srr1, totsaves);
2d21ac55 691 save = (struct savearea *)save->save_hdr.save_prev; /* Next one */
1c79356b 692 if(chainsize++ > chainmax) { /* See if we might be in a loop */
9bccf70c 693 db_printf(" Chain terminated by count (%d) before %08X\n", chainmax, save);
1c79356b
A
694 break;
695 }
696 }
697
2d21ac55 698 save = (struct savearea *)act->machine.facctx.FPUsave; /* Set the start of the floating point chain */
1c79356b
A
699 chainsize = 0;
700 while(save) { /* Do them all */
9bccf70c
A
701 totsaves++; /* Count savearea */
702 db_printf(" FPU %08X: %08X - tot = %d\n", save, save->save_hdr.save_level, totsaves);
2d21ac55 703 save = (struct savearea *)save->save_hdr.save_prev; /* Next one */
1c79356b 704 if(chainsize++ > chainmax) { /* See if we might be in a loop */
9bccf70c 705 db_printf(" Chain terminated by count (%d) before %08X\n", chainmax, save);
1c79356b
A
706 break;
707 }
708 }
709
2d21ac55 710 save = (struct savearea *)act->machine.facctx.VMXsave; /* Set the start of the floating point chain */
1c79356b
A
711 chainsize = 0;
712 while(save) { /* Do them all */
9bccf70c
A
713 totsaves++; /* Count savearea */
714 db_printf(" Vec %08X: %08X - tot = %d\n", save, save->save_hdr.save_level, totsaves);
2d21ac55 715 save = (struct savearea *)save->save_hdr.save_prev; /* Next one */
1c79356b 716 if(chainsize++ > chainmax) { /* See if we might be in a loop */
9bccf70c 717 db_printf(" Chain terminated by count (%d) before %08X\n", chainmax, save);
1c79356b
A
718 break;
719 }
720 }
9bccf70c 721
91447636 722 if(CTable = act->machine.vmmControl) { /* Are there virtual machines? */
9bccf70c 723
55e303ae 724 for(vmid = 0; vmid < kVmmMaxContexts; vmid++) {
9bccf70c
A
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
2d21ac55 735 save = (struct savearea *)CTable->vmmc[vmid].vmmFacCtx.FPUsave; /* Set the start of the floating point chain */
9bccf70c
A
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);
2d21ac55 740 save = (struct savearea *)save->save_hdr.save_prev; /* Next one */
9bccf70c
A
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
2d21ac55 747 save = (struct savearea *)CTable->vmmc[vmid].vmmFacCtx.VMXsave; /* Set the start of the floating point chain */
9bccf70c
A
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);
2d21ac55 752 save = (struct savearea *)save->save_hdr.save_prev; /* Next one */
9bccf70c
A
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 }
1c79356b
A
760 taskact++;
761 }
762 tottasks++;
763 }
764
765 db_printf("Total saveareas accounted for: %d\n", totsaves);
1c79356b
A
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];
91447636 777extern unsigned int dbspecrs[336];
1c79356b 778
2d21ac55
A
779void
780db_display_xregs(db_expr_t addr, boolean_t have_addr, db_expr_t count,
781 char *modif)
782{
1c79356b
A
783 int i, j, pents;
784
785 stSpecrs(dbspecrs); /* Save special registers */
91447636 786 if(PerProcTable[0].ppe_vaddr->pf.Available & pf64Bit) {
a3d08fcd
A
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 }
1c79356b
A
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
2d21ac55 851 /* Tell them we did it */
1c79356b
A
852}
853
55e303ae
A
854/*
855 * Check check mappings and hash table for consistency
856 *
857 * cm
858 */
2d21ac55
A
859void
860db_check_mappings(db_expr_t addr, boolean_t have_addr, db_expr_t count,
861 char *modif)
862{
55e303ae
A
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;
91447636 867 mapping_t *mp;
55e303ae
A
868 ppnum_t ppn, pa, aoff;
869 unsigned long long llslot, llseg, llhash;
870
871 s4bit = 0; /* Assume dinky? */
91447636 872 if(PerProcTable[0].ppe_vaddr->pf.Available & pf64Bit) s4bit = 1; /* Are we a big guy? */
55e303ae
A
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 */
a3d08fcd 954 llhash = llhash & 0x0000001FFFFFFFFFULL; /* Make sure we stay within supported ranges */
55e303ae
A
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 }
91447636
A
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;
55e303ae 981 }
91447636
A
982
983 if(!mp) { /* Did we find one? */
984 db_printf("Not mapped, slot = %d, va = %08X\n", j, (unsigned int)llva);
55e303ae 985 fnderr = 1;
91447636 986 goto dcmout;
55e303ae 987 }
91447636
A
988
989 if((mp->mpFlags & 0xFF000000) > 0x01000000) { /* Is busy count too high? */
990 db_printf("Busy count too high, slot = %d\n", j);
55e303ae
A
991 fnderr = 1;
992 }
91447636
A
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 }
55e303ae 1010
91447636
A
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 */
55e303ae 1026 }
55e303ae
A
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 }
55e303ae
A
1044}
1045
1c79356b
A
1046/*
1047 * Displays all of the kmods in the system.
1048 *
1049 * dp
1050 */
2d21ac55
A
1051void
1052db_display_kmod(db_expr_t addr, boolean_t have_addr, db_expr_t count,
1053 char *modif)
1054{
1c79356b
A
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 }
1c79356b
A
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
2d21ac55
A
1078void
1079db_gsnoop(db_expr_t addr, boolean_t have_addr, db_expr_t count, char *modif)
1080{
1c79356b
A
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 */
1c79356b
A
1101}
1102
1103
1104void Dumbo(void);
1105void Dumbo(void){
1106}