]> git.saurik.com Git - apple/xnu.git/blob - osfmk/ppc/db_low_trace.c
xnu-344.49.tar.gz
[apple/xnu.git] / osfmk / ppc / db_low_trace.c
1 /*
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
7 *
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * file.
14 *
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
22 *
23 * @APPLE_LICENSE_HEADER_END@
24 */
25 /*
26 * @OSF_FREE_COPYRIGHT@
27 */
28 /*
29 * @APPLE_FREE_COPYRIGHT@
30 */
31
32 /*
33 * Author: Bill Angell, Apple
34 * Date: 6/97
35 *
36 * exceptions and certain C functions write into a trace table which
37 * can be examined via the machine 'lt' command under kdb
38 */
39
40
41 #include <string.h> /* For strcpy() */
42 #include <mach/boolean.h>
43 #include <machine/db_machdep.h>
44
45 #include <ddb/db_access.h>
46 #include <ddb/db_lex.h>
47 #include <ddb/db_output.h>
48 #include <ddb/db_command.h>
49 #include <ddb/db_sym.h>
50 #include <ddb/db_task_thread.h>
51 #include <ddb/db_command.h> /* For db_option() */
52 #include <ddb/db_examine.h>
53 #include <ddb/db_expr.h>
54 #include <kern/thread.h>
55 #include <kern/task.h>
56 #include <mach/vm_param.h>
57 #include <mach/kmod.h>
58 #include <ppc/Firmware.h>
59 #include <ppc/low_trace.h>
60 #include <ppc/db_low_trace.h>
61 #include <ppc/mappings.h>
62 #include <ppc/pmap.h>
63 #include <ppc/mem.h>
64 #include <ppc/pmap_internals.h>
65 #include <ppc/savearea.h>
66 #include <ppc/vmachmon.h>
67
68 void db_dumpphys(struct phys_entry *pp); /* Dump from physent */
69 void db_dumppca(struct mapping *mp); /* PCA */
70 void db_dumpmapping(struct mapping *mp); /* Dump out a mapping */
71 void db_dumppmap(pmap_t pmap); /* Dump out a pmap */
72 extern kmod_info_t *kmod; /* Find the kmods */
73
74 db_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 */
86 void db_low_trace(db_expr_t addr, int have_addr, db_expr_t count, char * modif) {
87
88 int c, i;
89 unsigned int tempx, cnt;
90 unsigned int xbuf[8];
91 unsigned int xTraceCurr, xTraceStart, xTraceEnd, cxltr, xxltr;
92 db_addr_t next_addr;
93 LowTraceRecord xltr;
94 unsigned char cmark;
95
96 cnt = 16; /* Default to 16 entries */
97
98 xTraceCurr = trcWork.traceCurr; /* Transfer current pointer */
99 xTraceStart = trcWork.traceStart; /* Transfer start of table */
100 xTraceEnd = trcWork.traceEnd; /* Transfer end of table */
101
102 if(addr == -1) cnt = 0x7FFFFFFF; /* Max the count */
103
104 if(!addr || (addr == -1)) {
105 addr=xTraceCurr-sizeof(LowTraceRecord); /* Start at the newest */
106 if((unsigned int)addr<xTraceStart) addr=xTraceEnd-sizeof(LowTraceRecord); /* Wrap low back to high */
107 }
108
109 if((unsigned int)addr<xTraceStart||(unsigned int)addr>=xTraceEnd) { /* In the table? */
110 db_printf("address not in low memory trace table\n"); /* Tell the fool */
111 return; /* Leave... */
112 }
113
114 if((unsigned int)addr&0x0000003F) { /* Proper alignment? */
115 db_printf("address not aligned on trace entry boundary (0x40)\n"); /* Tell 'em */
116 return; /* Leave... */
117 }
118
119 xxltr=(unsigned int)addr; /* Set the start */
120 cxltr=((xTraceCurr==xTraceStart ? xTraceEnd : xTraceCurr)-sizeof(LowTraceRecord)); /* Get address of newest entry */
121
122 db_low_trace_prev = addr; /* Starting point */
123
124 for(i=0; i < cnt; i++) { /* Dump the 16 (or all) entries */
125
126 ReadReal(xxltr, (unsigned int *)&xltr); /* Get the first half */
127 ReadReal(xxltr+32, &(((unsigned int *)&xltr)[8])); /* Get the second half */
128
129 db_printf("\n%s%08X %1X %08X %08X - %04X\n", (xxltr!=cxltr ? " " : "*"),
130 xxltr,
131 xltr.LTR_cpu, xltr.LTR_timeHi, xltr.LTR_timeLo,
132 (xltr.LTR_excpt&0x8000 ? 0xFFFF : xltr.LTR_excpt*64)); /* Print the first line */
133 db_printf(" %08X %08X %08X %08X %08X %08X %08X\n",
134 xltr.LTR_cr, xltr.LTR_srr0, xltr.LTR_srr1, xltr.LTR_dar, xltr.LTR_save, xltr.LTR_lr, xltr.LTR_ctr);
135 db_printf(" %08X %08X %08X %08X %08X %08X\n",
136 xltr.LTR_r0, xltr.LTR_r1, xltr.LTR_r2, xltr.LTR_r3, xltr.LTR_r4, xltr.LTR_r5);
137
138 if((cnt != 16) && (xxltr == xTraceCurr)) break; /* If whole table dump, exit when we hit start again... */
139
140 xxltr-=sizeof(LowTraceRecord); /* Back it on up */
141 if(xxltr<xTraceStart)
142 xxltr=(xTraceEnd-sizeof(LowTraceRecord)); /* Wrap low back to high */
143
144 }
145 db_next = (db_expr_t)(xxltr);
146 return;
147 }
148
149
150 /*
151 * Print out 256 bytes
152 *
153 *
154 * dl [entaddr]
155 */
156 void db_display_long(db_expr_t addr, int have_addr, db_expr_t count, char * modif) {
157
158 int i;
159
160 for(i=0; i<8; i++) { /* Print 256 bytes */
161 db_printf("%08X %08X %08X %08X %08X %08X %08X %08X %08X\n", addr, /* Print a line */
162 ((unsigned long *)addr)[0], ((unsigned long *)addr)[1], ((unsigned long *)addr)[2], ((unsigned long *)addr)[3],
163 ((unsigned long *)addr)[4], ((unsigned long *)addr)[5], ((unsigned long *)addr)[6], ((unsigned long *)addr)[7]);
164 addr=(db_expr_t)((unsigned int)addr+0x00000020); /* Point to next address */
165 }
166 db_next = addr;
167
168
169 }
170
171 /*
172 * Print out 256 bytes of real storage
173 *
174 * Displays the entry and 15 before it in newest to oldest order
175 *
176 * dr [entaddr]
177 */
178 void db_display_real(db_expr_t addr, int have_addr, db_expr_t count, char * modif) {
179
180 int i;
181 unsigned int xbuf[8];
182
183 for(i=0; i<8; i++) { /* Print 256 bytes */
184 ReadReal((unsigned int)addr, &xbuf[0]); /* Get the real storage data */
185 db_printf("%08X %08X %08X %08X %08X %08X %08X %08X %08X\n", addr, /* Print a line */
186 xbuf[0], xbuf[1], xbuf[2], xbuf[3],
187 xbuf[4], xbuf[5], xbuf[6], xbuf[7]);
188 addr=(db_expr_t)((unsigned int)addr+0x00000020); /* Point to next address */
189 }
190 db_next = addr;
191
192
193 }
194
195 unsigned int dvspace = 0;
196
197 /*
198 * Print out virtual to real translation information
199 *
200 *
201 * dm vaddr [space] (defaults to last entered)
202 */
203 void db_display_mappings(db_expr_t addr, int have_addr, db_expr_t count, char * modif) {
204
205 int i;
206 unsigned int xspace;
207
208 mapping *mp, *mpv;
209 vm_offset_t pa;
210
211 if (db_expression(&xspace)) dvspace = xspace; /* Get the space or set default */
212
213 db_printf("mapping information for %08X in space %08X:\n", addr, dvspace);
214 mp = hw_lock_phys_vir(dvspace, addr); /* Lock the physical entry for this mapping */
215 if(!mp) { /* Did we find one? */
216 db_printf("Not mapped\n");
217 return; /* Didn't find any, return FALSE... */
218 }
219 if((unsigned int)mp&1) { /* Did we timeout? */
220 db_printf("Timeout locking physical entry for virtual address (%08X)\n", addr); /* Yeah, scream about it! */
221 return; /* Bad hair day, return FALSE... */
222 }
223 printf("dumpaddr: space=%08X; vaddr=%08X\n", dvspace, addr); /* Say what address were dumping */
224 mpv = hw_cpv(mp); /* Get virtual address of mapping */
225 dumpmapping(mpv);
226 if(mpv->physent) {
227 hw_unlock_bit((unsigned int *)&mpv->physent->phys_link, PHYS_LOCK); /* Unlock physical entry associated with mapping */
228 }
229 return; /* Tell them we did it */
230
231
232 }
233
234 /*
235 * Displays all of the in-use pmaps in the system.
236 *
237 * dp
238 */
239 void db_display_pmap(db_expr_t addr, int have_addr, db_expr_t count, char * modif) {
240
241 pmap_t pmap;
242
243 pmap = kernel_pmap; /* Start at the beginning */
244
245 db_printf("PMAP (real) Next Prev VRMask Space Bmaps Flags Ref spaceNum Resident Wired\n");
246 // xxxxxxxx rrrrrrrr xxxxxxxx pppppppp vvvvvvvv ssssssss bbbbbbbb cccccccc vvvvvvvv nnnnnnnn rrrrrrrr wwwwwwwww
247 while(1) { /* Do them all */
248 db_printf("%08X %08X %08X %08X %08X %08X %08X %08X %08X %08X %08X %08X\n",
249 pmap, (unsigned int)pmap ^ pmap->pmapvr,
250 pmap->pmap_link.next, pmap->pmap_link.prev, pmap->pmapvr,
251 pmap->space, pmap->bmaps, pmap->vflags, pmap->ref_count, pmap->spaceNum,
252 pmap->stats.resident_count,
253 pmap->stats.wired_count);
254
255
256 // xxxxxxxx rrrrrrrr xxxxxxxx pppppppp vvvvvvvv ssssssss bbbbbbbb cccccccc vvvvvvvv nnnnnnnn rrrrrrrr wwwwwwwww
257 db_printf(" SRs: %08X %08X %08X %08X %08X %08X %08X %08X\n", pmap->pmapSegs[0], pmap->pmapSegs[1], pmap->pmapSegs[2], pmap->pmapSegs[3],
258 pmap->pmapSegs[4], pmap->pmapSegs[5], pmap->pmapSegs[6], pmap->pmapSegs[7]);
259 db_printf(" %08X %08X %08X %08X %08X %08X %08X %08X\n", pmap->pmapSegs[8], pmap->pmapSegs[9], pmap->pmapSegs[10], pmap->pmapSegs[11],
260 pmap->pmapSegs[12], pmap->pmapSegs[13], pmap->pmapSegs[14], pmap->pmapSegs[15]);
261
262 db_printf(" spmaps: %08X %08X %08X %08X %08X %08X %08X %08X\n", pmap->pmapPmaps[0], pmap->pmapPmaps[1], pmap->pmapPmaps[2], pmap->pmapPmaps[3],
263 pmap->pmapPmaps[4], pmap->pmapPmaps[5], pmap->pmapPmaps[6], pmap->pmapPmaps[7]);
264 db_printf(" %08X %08X %08X %08X %08X %08X %08X %08X\n", pmap->pmapPmaps[8], pmap->pmapPmaps[9], pmap->pmapPmaps[10], pmap->pmapPmaps[11],
265 pmap->pmapPmaps[12], pmap->pmapPmaps[13], pmap->pmapPmaps[14], pmap->pmapPmaps[15]);
266
267 pmap = (pmap_t)pmap->pmap_link.next; /* Skip to the next */
268 db_printf("\n");
269 if(pmap == kernel_pmap) break; /* We've wrapped, we're done */
270 }
271 return;
272 }
273
274 /*
275 * print information about the passed in pmap block
276 */
277
278 void db_dumppmap(pmap_t pmap) {
279
280 db_printf("Dump of pmap block: %08X\n", pmap);
281 db_printf(" pmap_link: %08X %08X\n", pmap->pmap_link.next, pmap->pmap_link.prev);
282 db_printf(" pmapvr: %08X\n", pmap->pmapvr);
283 db_printf(" space: %08X\n", pmap->space);
284 db_printf(" bmaps: %08X\n", pmap->bmaps);
285 db_printf(" ref_count: %08X\n", pmap->ref_count);
286 db_printf(" spaceNum: %08X\n", pmap->spaceNum);
287 db_printf(" resident_count: %08X\n", pmap->stats.resident_count);
288 db_printf(" wired_count: %08X\n", pmap->stats.wired_count);
289 db_printf("\n");
290
291 return;
292
293 }
294
295 /*
296 * Prints out a mapping control block
297 *
298 */
299
300 void db_dumpmapping(struct mapping *mp) { /* Dump out a mapping */
301
302 db_printf("Dump of mapping block: %08X\n", mp); /* Header */
303 db_printf(" next: %08X\n", mp->next);
304 db_printf(" hashnext: %08X\n", mp->hashnext);
305 db_printf(" PTEhash: %08X\n", mp->PTEhash);
306 db_printf(" PTEent: %08X\n", mp->PTEent);
307 db_printf(" physent: %08X\n", mp->physent);
308 db_printf(" PTEv: %08X\n", mp->PTEv);
309 db_printf(" PTEr: %08X\n", mp->PTEr);
310 db_printf(" pmap: %08X\n", mp->pmap);
311
312 if(mp->physent) { /* Print physent if it exists */
313 db_printf("Associated physical entry: %08X %08X\n", mp->physent->phys_link, mp->physent->pte1);
314 }
315 else {
316 db_printf("Associated physical entry: none\n");
317 }
318
319 db_dumppca(mp); /* Dump out the PCA information */
320
321 return;
322 }
323
324 /*
325 * Prints out a PTEG control area
326 *
327 */
328
329 void db_dumppca(struct mapping *mp) { /* PCA */
330
331 PCA *pca;
332 unsigned int *pteg, sdr;
333
334 pca = (PCA *)((unsigned int)mp->PTEhash&-64); /* Back up to the start of the PCA */
335 __asm__ volatile("mfsdr1 %0" : "=r" (sdr));
336 db_printf(" SDR1: %08X\n", sdr);
337 pteg=(unsigned int *)((unsigned int)pca-(((sdr&0x0000FFFF)+1)<<16));
338 db_printf(" Dump of PCA: %08X\n", pca); /* Header */
339 db_printf(" PCAlock: %08X\n", pca->PCAlock);
340 db_printf(" PCAallo: %08X\n", pca->flgs.PCAallo);
341 db_printf(" PCAhash: %08X %08X %08X %08X\n", pca->PCAhash[0], pca->PCAhash[1], pca->PCAhash[2], pca->PCAhash[3]);
342 db_printf(" %08X %08X %08X %08X\n", pca->PCAhash[4], pca->PCAhash[5], pca->PCAhash[6], pca->PCAhash[7]);
343 db_printf("Dump of PTEG: %08X\n", pteg); /* Header */
344 db_printf(" %08X %08X %08X %08X\n", pteg[0], pteg[1], pteg[2], pteg[3]);
345 db_printf(" %08X %08X %08X %08X\n", pteg[4], pteg[5], pteg[6], pteg[7]);
346 db_printf(" %08X %08X %08X %08X\n", pteg[8], pteg[9], pteg[10], pteg[11]);
347 db_printf(" %08X %08X %08X %08X\n", pteg[12], pteg[13], pteg[14], pteg[15]);
348 return;
349 }
350
351 /*
352 * Dumps starting with a physical entry
353 */
354
355 void db_dumpphys(struct phys_entry *pp) { /* Dump from physent */
356
357 mapping *mp;
358 PCA *pca;
359 unsigned int *pteg;
360
361 db_printf("Dump from physical entry %08X: %08X %08X\n", pp, pp->phys_link, pp->pte1);
362 mp = hw_cpv(pp->phys_link);
363 while(mp) {
364 db_dumpmapping(mp);
365 db_dumppca(mp);
366 mp = hw_cpv(mp->next);
367 }
368
369 return;
370 }
371
372
373 /*
374 * Print out 256 bytes of virtual storage
375 *
376 *
377 * dv [entaddr] [space]
378 * address must be on 32-byte boundary. It will be rounded down if not
379 */
380 void db_display_virtual(db_expr_t addr, int have_addr, db_expr_t count, char * modif) {
381
382 int i, size, lines, rlines;
383 unsigned int xbuf[8];
384 unsigned int xspace;
385
386 mapping *mp, *mpv;
387 vm_offset_t pa;
388
389 if (db_expression(&xspace)) dvspace = xspace; /* Get the space or set default */
390
391 addr&=-32;
392
393 size = 4096 - (addr & 0x00000FFF); /* Bytes left on page */
394 lines = size / 32; /* Number of lines in first or only part */
395 if(lines > 8) lines = 8;
396 rlines = 8 - lines;
397 if(rlines < 0) lines = 0;
398
399 db_printf("Dumping %08X (space=%08X); ", addr, dvspace);
400 mp = hw_lock_phys_vir(dvspace, addr); /* Lock the physical entry for this mapping */
401 if(!mp) { /* Did we find one? */
402 db_printf("Not mapped\n");
403 return; /* Didn't find any, return FALSE... */
404 }
405 if((unsigned int)mp&1) { /* Did we timeout? */
406 db_printf("Timeout locking physical entry for virtual address (%08X)\n", addr); /* Yeah, scream about it! */
407 return; /* Bad hair day, return FALSE... */
408 }
409 mpv = hw_cpv(mp); /* Get virtual address of mapping */
410 if(!mpv->physent) { /* Was there a physical entry? */
411 pa = (vm_offset_t)((mpv->PTEr & -PAGE_SIZE) | ((unsigned int)addr & (PAGE_SIZE-1))); /* Get physical address from physent */
412 }
413 else {
414 pa = (vm_offset_t)((mpv->physent->pte1 & -PAGE_SIZE) | ((unsigned int)addr & (PAGE_SIZE-1))); /* Get physical address from physent */
415 hw_unlock_bit((unsigned int *)&mpv->physent->phys_link, PHYS_LOCK); /* Unlock the physical entry */
416 }
417 db_printf("phys=%08X\n", pa);
418 for(i=0; i<lines; i++) { /* Print n bytes */
419 ReadReal((unsigned int)pa, &xbuf[0]); /* Get the real storage data */
420 db_printf("%08X %08X %08X %08X %08X %08X %08X %08X %08X\n", addr, /* Print a line */
421 xbuf[0], xbuf[1], xbuf[2], xbuf[3],
422 xbuf[4], xbuf[5], xbuf[6], xbuf[7]);
423 addr=(db_expr_t)((unsigned int)addr+0x00000020); /* Point to next address */
424 pa=(unsigned int)pa+0x00000020; /* Point to next address */
425 }
426 db_next = addr;
427
428 if(!rlines) return;
429
430 db_printf("Dumping %08X (space=%08X); ", addr, dvspace);
431 mp = hw_lock_phys_vir(dvspace, addr); /* Lock the physical entry for this mapping */
432 if(!mp) { /* Did we find one? */
433 db_printf("Not mapped\n");
434 return; /* Didn't find any, return FALSE... */
435 }
436 if((unsigned int)mp&1) { /* Did we timeout? */
437 db_printf("Timeout locking physical entry for virtual address (%08X)\n", addr); /* Yeah, scream about it! */
438 return; /* Bad hair day, return FALSE... */
439 }
440 mpv = hw_cpv(mp); /* Get virtual address of mapping */
441 if(!mpv->physent) { /* Was there a physical entry? */
442 pa = (vm_offset_t)((mpv->PTEr & -PAGE_SIZE) | ((unsigned int)addr & (PAGE_SIZE-1))); /* Get physical address from physent */
443 }
444 else {
445 pa = (vm_offset_t)((mpv->physent->pte1 & -PAGE_SIZE) | ((unsigned int)addr & (PAGE_SIZE-1))); /* Get physical address from physent */
446 hw_unlock_bit((unsigned int *)&mp->physent->phys_link, PHYS_LOCK); /* Unlock the physical entry */
447 }
448 db_printf("phys=%08X\n", pa);
449 for(i=0; i<rlines; i++) { /* Print n bytes */
450 ReadReal((unsigned int)pa, &xbuf[0]); /* Get the real storage data */
451 db_printf("%08X %08X %08X %08X %08X %08X %08X %08X %08X\n", addr, /* Print a line */
452 xbuf[0], xbuf[1], xbuf[2], xbuf[3],
453 xbuf[4], xbuf[5], xbuf[6], xbuf[7]);
454 addr=(db_expr_t)((unsigned int)addr+0x00000020); /* Point to next address */
455 pa=(unsigned int)pa+0x00000020; /* Point to next address */
456 }
457 db_next = addr;
458
459
460 }
461
462
463 /*
464 * Print out savearea stuff
465 *
466 *
467 * ds
468 */
469
470 #define chainmax 32
471
472 void db_display_save(db_expr_t addr, int have_addr, db_expr_t count, char * modif) {
473
474 int i, j, totsaves, tottasks, taskact, chainsize, vmid, didvmhead;
475 processor_set_t pset = &default_pset;
476 task_t task;
477 thread_act_t act;
478 savearea *save;
479 vmmCntrlTable *CTable;
480
481 tottasks = 0;
482 totsaves = 0;
483
484 for(task = (task_t)pset->tasks.next; task != (task_t)&pset->tasks.next; task = (task_t)task->pset_tasks.next) { /* Go through the tasks */
485 taskact = 0; /* Reset activation count */
486 db_printf("\nTask %4d @%08X:\n", tottasks, task); /* Show where we're at */
487 for(act = (thread_act_t)task->thr_acts.next; act != (thread_act_t)&task->thr_acts; act = (thread_act_t)act->thr_acts.next) { /* Go through activations */
488 db_printf(" Act %4d @%08X - p: %08X current context: %08X\n",
489 taskact, act, act->mact.pcb, act->mact.curctx);
490
491 save = (savearea *)act->mact.pcb; /* Set the start of the normal chain */
492 chainsize = 0;
493
494 db_printf(" General context - fp: %08X fl: %08X fc: %d vp: %08X vl: %08X vp: %d\n",
495 act->mact.facctx.FPUsave, act->mact.facctx.FPUlevel, act->mact.facctx.FPUcpu,
496 act->mact.facctx.VMXsave, act->mact.facctx.VMXlevel, act->mact.facctx.VMXcpu);
497
498 while(save) { /* Do them all */
499 totsaves++; /* Count savearea */
500 db_printf(" Norm %08X: %08X %08X - tot = %d\n", save, save->save_srr0, save->save_srr1, totsaves);
501 save = save->save_hdr.save_prev; /* Next one */
502 if(chainsize++ > chainmax) { /* See if we might be in a loop */
503 db_printf(" Chain terminated by count (%d) before %08X\n", chainmax, save);
504 break;
505 }
506 }
507
508 save = (savearea *)act->mact.facctx.FPUsave; /* Set the start of the floating point chain */
509 chainsize = 0;
510 while(save) { /* Do them all */
511 totsaves++; /* Count savearea */
512 db_printf(" FPU %08X: %08X - tot = %d\n", save, save->save_hdr.save_level, totsaves);
513 save = save->save_hdr.save_prev; /* Next one */
514 if(chainsize++ > chainmax) { /* See if we might be in a loop */
515 db_printf(" Chain terminated by count (%d) before %08X\n", chainmax, save);
516 break;
517 }
518 }
519
520 save = (savearea *)act->mact.facctx.VMXsave; /* Set the start of the floating point chain */
521 chainsize = 0;
522 while(save) { /* Do them all */
523 totsaves++; /* Count savearea */
524 db_printf(" Vec %08X: %08X - tot = %d\n", save, save->save_hdr.save_level, totsaves);
525 save = save->save_hdr.save_prev; /* Next one */
526 if(chainsize++ > chainmax) { /* See if we might be in a loop */
527 db_printf(" Chain terminated by count (%d) before %08X\n", chainmax, save);
528 break;
529 }
530 }
531
532 if(CTable = act->mact.vmmControl) { /* Are there virtual machines? */
533
534 for(vmid = 0; vmid < kVmmMaxContextsPerThread; vmid++) {
535
536 if(!(CTable->vmmc[vmid].vmmFlags & vmmInUse)) continue; /* Skip if vm is not in use */
537
538 if(!CTable->vmmc[vmid].vmmFacCtx.FPUsave && !CTable->vmmc[vmid].vmmFacCtx.VMXsave) continue; /* If neither types, skip this vm */
539
540 db_printf(" VMachine ID %3d - fp: %08X fl: %08X fc: %d vp: %08X vl: %08X vp: %d\n", vmid, /* Title it */
541 CTable->vmmc[vmid].vmmFacCtx.FPUsave, CTable->vmmc[vmid].vmmFacCtx.FPUlevel, CTable->vmmc[vmid].vmmFacCtx.FPUcpu,
542 CTable->vmmc[vmid].vmmFacCtx.VMXsave, CTable->vmmc[vmid].vmmFacCtx.VMXlevel, CTable->vmmc[vmid].vmmFacCtx.VMXcpu
543 );
544
545 save = (savearea *)CTable->vmmc[vmid].vmmFacCtx.FPUsave; /* Set the start of the floating point chain */
546 chainsize = 0;
547 while(save) { /* Do them all */
548 totsaves++; /* Count savearea */
549 db_printf(" FPU %08X: %08X - tot = %d\n", save, save->save_hdr.save_level, totsaves);
550 save = save->save_hdr.save_prev; /* Next one */
551 if(chainsize++ > chainmax) { /* See if we might be in a loop */
552 db_printf(" Chain terminated by count (%d) before %08X\n", chainmax, save);
553 break;
554 }
555 }
556
557 save = (savearea *)CTable->vmmc[vmid].vmmFacCtx.VMXsave; /* Set the start of the floating point chain */
558 chainsize = 0;
559 while(save) { /* Do them all */
560 totsaves++; /* Count savearea */
561 db_printf(" Vec %08X: %08X - tot = %d\n", save, save->save_hdr.save_level, totsaves);
562 save = save->save_hdr.save_prev; /* Next one */
563 if(chainsize++ > chainmax) { /* See if we might be in a loop */
564 db_printf(" Chain terminated by count (%d) before %08X\n", chainmax, save);
565 break;
566 }
567 }
568 }
569 }
570 taskact++;
571 }
572 tottasks++;
573 }
574
575 db_printf("Total saveareas accounted for: %d\n", totsaves);
576 return;
577 }
578
579 /*
580 * Print out extra registers
581 *
582 *
583 * dx
584 */
585
586 extern unsigned int dbfloats[33][2];
587 extern unsigned int dbvecs[33][4];
588 extern unsigned int dbspecrs[80];
589
590 void db_display_xregs(db_expr_t addr, int have_addr, db_expr_t count, char * modif) {
591
592 int i, j, pents;
593
594 stSpecrs(dbspecrs); /* Save special registers */
595 db_printf("PIR: %08X\n", dbspecrs[0]);
596 db_printf("PVR: %08X\n", dbspecrs[1]);
597 db_printf("SDR1: %08X\n", dbspecrs[22]);
598 db_printf("HID0: %08X\n", dbspecrs[39]);
599 db_printf("HID1: %08X\n", dbspecrs[40]);
600 db_printf("L2CR: %08X\n", dbspecrs[41]);
601 db_printf("MSSCR0: %08X\n", dbspecrs[42]);
602 db_printf("MSSCR1: %08X\n", dbspecrs[43]);
603 db_printf("THRM1: %08X\n", dbspecrs[44]);
604 db_printf("THRM2: %08X\n", dbspecrs[45]);
605 db_printf("THRM3: %08X\n", dbspecrs[46]);
606 db_printf("ICTC: %08X\n", dbspecrs[47]);
607 db_printf("\n");
608
609 db_printf("DBAT: %08X %08X %08X %08X\n", dbspecrs[2], dbspecrs[3], dbspecrs[4], dbspecrs[5]);
610 db_printf(" %08X %08X %08X %08X\n", dbspecrs[6], dbspecrs[7], dbspecrs[8], dbspecrs[9]);
611 db_printf("IBAT: %08X %08X %08X %08X\n", dbspecrs[10], dbspecrs[11], dbspecrs[12], dbspecrs[13]);
612 db_printf(" %08X %08X %08X %08X\n", dbspecrs[14], dbspecrs[15], dbspecrs[16], dbspecrs[17]);
613 db_printf("SPRG: %08X %08X %08X %08X\n", dbspecrs[18], dbspecrs[19], dbspecrs[20], dbspecrs[21]);
614 db_printf("\n");
615 for(i = 0; i < 16; i += 8) { /* Print 8 at a time */
616 db_printf("SR%02d: %08X %08X %08X %08X %08X %08X %08X %08X\n", i,
617 dbspecrs[23+i], dbspecrs[24+i], dbspecrs[25+i], dbspecrs[26+i],
618 dbspecrs[27+i], dbspecrs[28+i], dbspecrs[29+i], dbspecrs[30+i]);
619 }
620
621 db_printf("\n");
622
623 stFloat(dbfloats); /* Save floating point registers */
624 for(i = 0; i < 32; i += 4) { /* Print 4 at a time */
625 db_printf("F%02d: %08X %08X %08X %08X %08X %08X %08X %08X\n", i,
626 dbfloats[i][0], dbfloats[i][1], dbfloats[i+1][0], dbfloats[i+1][1],
627 dbfloats[i+2][0], dbfloats[i+2][1], dbfloats[i+3][0], dbfloats[i+3][1]);
628 }
629 db_printf("FCR: %08X %08X\n", dbfloats[32][0], dbfloats[32][1]); /* Print FSCR */
630
631 if(!stVectors(dbvecs)) return; /* Return if not Altivec capable */
632
633 db_printf("\n");
634
635 for(i = 0; i < 32; i += 2) { /* Print 2 at a time */
636 db_printf("V%02d: %08X %08X %08X %08X %08X %08X %08X %08X\n", i,
637 dbvecs[i][0], dbvecs[i][1], dbvecs[i][2], dbvecs[i][3],
638 dbvecs[i+1][0], dbvecs[i+1][1], dbvecs[i+1][2], dbvecs[i+1][3]);
639 }
640 db_printf("VCR: %08X %08X %08X %08X\n", dbvecs[32][0], dbvecs[32][1], dbvecs[32][2], dbvecs[32][3]); /* Print VSCR */
641
642 return; /* Tell them we did it */
643
644
645 }
646
647 /*
648 * Displays all of the kmods in the system.
649 *
650 * dp
651 */
652 void db_display_kmod(db_expr_t addr, int have_addr, db_expr_t count, char * modif) {
653
654 kmod_info_t *kmd;
655 unsigned int strt, end;
656
657 kmd = kmod; /* Start at the start */
658
659 db_printf("info addr start - end name ver\n");
660
661 while(kmd) { /* Dump 'em all */
662 strt = (unsigned int)kmd->address + kmd->hdr_size; /* Get start of kmod text */
663 end = (unsigned int)kmd->address + kmd->size; /* Get end of kmod */
664 db_printf("%08X %08X %08X - %08X: %s, %s\n", kmd, kmd->address, strt, end,
665 kmd->name, kmd->version);
666 kmd = kmd->next; /* Step to it */
667 }
668
669 return;
670 }
671
672 /*
673 * Displays stuff
674 *
675 * gs
676 */
677 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};
678
679 void db_gsnoop(db_expr_t addr, int have_addr, db_expr_t count, char * modif) {
680
681 int i, j;
682 unsigned char *gp, gpn[36];
683 #define ngpr 34
684
685 gp = (unsigned char *)0x8000005C;
686
687 for(i = 0; i < ngpr; i++) gpn[i] = gp[i]; /* Copy 'em */
688
689 for(i = 0; i < ngpr; i++) {
690 db_printf("%02X ", gpn[i]);
691 }
692 db_printf("\n");
693
694 for(i = 0; i < ngpr; i++) {
695 if(gpn[i] != xxgpo[i]) db_printf("^^ ");
696 else db_printf(" ");
697 }
698 db_printf("\n");
699
700 for(i = 0; i < ngpr; i++) xxgpo[i] = gpn[i]; /* Save 'em */
701
702 return;
703 }
704
705
706 void Dumbo(void);
707 void Dumbo(void){
708 }