2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
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
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.
23 * @APPLE_LICENSE_HEADER_END@
26 * @OSF_FREE_COPYRIGHT@
29 * @APPLE_FREE_COPYRIGHT@
33 * Author: Bill Angell, Apple
36 * exceptions and certain C functions write into a trace table which
37 * can be examined via the machine 'lt' command under kdb
41 #include <string.h> /* For strcpy() */
42 #include <mach/boolean.h>
43 #include <machine/db_machdep.h>
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>
64 #include <ppc/pmap_internals.h>
65 #include <ppc/savearea.h>
66 #include <ppc/vmachmon.h>
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 */
74 db_addr_t db_low_trace_prev
= 0;
77 * Print out the low level trace table:
79 * Displays the entry and 15 before it in newest to oldest order
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
86 void db_low_trace(db_expr_t addr
, int have_addr
, db_expr_t count
, char * modif
) {
89 unsigned int tempx
, cnt
;
91 unsigned int xTraceCurr
, xTraceStart
, xTraceEnd
, cxltr
, xxltr
;
96 cnt
= 16; /* Default to 16 entries */
98 xTraceCurr
= trcWork
.traceCurr
; /* Transfer current pointer */
99 xTraceStart
= trcWork
.traceStart
; /* Transfer start of table */
100 xTraceEnd
= trcWork
.traceEnd
; /* Transfer end of table */
102 if(addr
== -1) cnt
= 0x7FFFFFFF; /* Max the count */
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 */
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... */
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... */
119 xxltr
=(unsigned int)addr
; /* Set the start */
120 cxltr
=((xTraceCurr
==xTraceStart
? xTraceEnd
: xTraceCurr
)-sizeof(LowTraceRecord
)); /* Get address of newest entry */
122 db_low_trace_prev
= addr
; /* Starting point */
124 for(i
=0; i
< cnt
; i
++) { /* Dump the 16 (or all) entries */
126 ReadReal(xxltr
, (unsigned int *)&xltr
); /* Get the first half */
127 ReadReal(xxltr
+32, &(((unsigned int *)&xltr
)[8])); /* Get the second half */
129 db_printf("\n%s%08X %1X %08X %08X - %04X\n", (xxltr
!=cxltr
? " " : "*"),
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
);
138 if((cnt
!= 16) && (xxltr
== xTraceCurr
)) break; /* If whole table dump, exit when we hit start again... */
140 xxltr
-=sizeof(LowTraceRecord
); /* Back it on up */
141 if(xxltr
<xTraceStart
)
142 xxltr
=(xTraceEnd
-sizeof(LowTraceRecord
)); /* Wrap low back to high */
145 db_next
= (db_expr_t
)(xxltr
);
151 * Print out 256 bytes
156 void db_display_long(db_expr_t addr
, int have_addr
, db_expr_t count
, char * modif
) {
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 */
172 * Print out 256 bytes of real storage
174 * Displays the entry and 15 before it in newest to oldest order
178 void db_display_real(db_expr_t addr
, int have_addr
, db_expr_t count
, char * modif
) {
181 unsigned int xbuf
[8];
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 */
195 unsigned int dvspace
= 0;
198 * Print out virtual to real translation information
201 * dm vaddr [space] (defaults to last entered)
203 void db_display_mappings(db_expr_t addr
, int have_addr
, db_expr_t count
, char * modif
) {
211 if (db_expression(&xspace
)) dvspace
= xspace
; /* Get the space or set default */
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... */
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... */
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 */
227 hw_unlock_bit((unsigned int *)&mpv
->physent
->phys_link
, PHYS_LOCK
); /* Unlock physical entry associated with mapping */
229 return; /* Tell them we did it */
235 * Displays all of the in-use pmaps in the system.
239 void db_display_pmap(db_expr_t addr
, int have_addr
, db_expr_t count
, char * modif
) {
243 pmap
= kernel_pmap
; /* Start at the beginning */
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
);
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]);
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]);
267 pmap
= (pmap_t
)pmap
->pmap_link
.next
; /* Skip to the next */
269 if(pmap
== kernel_pmap
) break; /* We've wrapped, we're done */
275 * print information about the passed in pmap block
278 void db_dumppmap(pmap_t pmap
) {
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
);
296 * Prints out a mapping control block
300 void db_dumpmapping(struct mapping
*mp
) { /* Dump out a mapping */
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
);
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
);
316 db_printf("Associated physical entry: none\n");
319 db_dumppca(mp
); /* Dump out the PCA information */
325 * Prints out a PTEG control area
329 void db_dumppca(struct mapping
*mp
) { /* PCA */
332 unsigned int *pteg
, sdr
;
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]);
352 * Dumps starting with a physical entry
355 void db_dumpphys(struct phys_entry
*pp
) { /* Dump from physent */
361 db_printf("Dump from physical entry %08X: %08X %08X\n", pp
, pp
->phys_link
, pp
->pte1
);
362 mp
= hw_cpv(pp
->phys_link
);
366 mp
= hw_cpv(mp
->next
);
374 * Print out 256 bytes of virtual storage
377 * dv [entaddr] [space]
378 * address must be on 32-byte boundary. It will be rounded down if not
380 void db_display_virtual(db_expr_t addr
, int have_addr
, db_expr_t count
, char * modif
) {
382 int i
, size
, lines
, rlines
;
383 unsigned int xbuf
[8];
389 if (db_expression(&xspace
)) dvspace
= xspace
; /* Get the space or set default */
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;
397 if(rlines
< 0) lines
= 0;
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... */
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... */
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 */
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 */
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 */
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... */
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... */
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 */
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 */
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 */
464 * Print out savearea stuff
472 void db_display_save(db_expr_t addr
, int have_addr
, db_expr_t count
, char * modif
) {
474 int i
, j
, totsaves
, tottasks
, taskact
, chainsize
, vmid
, didvmhead
;
475 processor_set_t pset
= &default_pset
;
479 vmmCntrlTable
*CTable
;
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
);
491 save
= (savearea
*)act
->mact
.pcb
; /* Set the start of the normal chain */
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
);
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
);
508 save
= (savearea
*)act
->mact
.facctx
.FPUsave
; /* Set the start of the floating point chain */
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
);
520 save
= (savearea
*)act
->mact
.facctx
.VMXsave
; /* Set the start of the floating point chain */
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
);
532 if(CTable
= act
->mact
.vmmControl
) { /* Are there virtual machines? */
534 for(vmid
= 0; vmid
< kVmmMaxContextsPerThread
; vmid
++) {
536 if(!(CTable
->vmmc
[vmid
].vmmFlags
& vmmInUse
)) continue; /* Skip if vm is not in use */
538 if(!CTable
->vmmc
[vmid
].vmmFacCtx
.FPUsave
&& !CTable
->vmmc
[vmid
].vmmFacCtx
.VMXsave
) continue; /* If neither types, skip this vm */
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
545 save
= (savearea
*)CTable
->vmmc
[vmid
].vmmFacCtx
.FPUsave
; /* Set the start of the floating point chain */
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
);
557 save
= (savearea
*)CTable
->vmmc
[vmid
].vmmFacCtx
.VMXsave
; /* Set the start of the floating point chain */
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
);
575 db_printf("Total saveareas accounted for: %d\n", totsaves
);
580 * Print out extra registers
586 extern unsigned int dbfloats
[33][2];
587 extern unsigned int dbvecs
[33][4];
588 extern unsigned int dbspecrs
[80];
590 void db_display_xregs(db_expr_t addr
, int have_addr
, db_expr_t count
, char * modif
) {
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]);
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]);
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
]);
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]);
629 db_printf("FCR: %08X %08X\n", dbfloats
[32][0], dbfloats
[32][1]); /* Print FSCR */
631 if(!stVectors(dbvecs
)) return; /* Return if not Altivec capable */
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]);
640 db_printf("VCR: %08X %08X %08X %08X\n", dbvecs
[32][0], dbvecs
[32][1], dbvecs
[32][2], dbvecs
[32][3]); /* Print VSCR */
642 return; /* Tell them we did it */
648 * Displays all of the kmods in the system.
652 void db_display_kmod(db_expr_t addr
, int have_addr
, db_expr_t count
, char * modif
) {
655 unsigned int strt
, end
;
657 kmd
= kmod
; /* Start at the start */
659 db_printf("info addr start - end name ver\n");
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 */
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};
679 void db_gsnoop(db_expr_t addr
, int have_addr
, db_expr_t count
, char * modif
) {
682 unsigned char *gp
, gpn
[36];
685 gp
= (unsigned char *)0x8000005C;
687 for(i
= 0; i
< ngpr
; i
++) gpn
[i
] = gp
[i
]; /* Copy 'em */
689 for(i
= 0; i
< ngpr
; i
++) {
690 db_printf("%02X ", gpn
[i
]);
694 for(i
= 0; i
< ngpr
; i
++) {
695 if(gpn
[i
] != xxgpo
[i
]) db_printf("^^ ");
700 for(i
= 0; i
< ngpr
; i
++) xxgpo
[i
] = gpn
[i
]; /* Save 'em */