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