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