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