1 /* Debugging dump procedures for the kernel. */
2
3 #include "inc.h"
4 #include <timers.h>
5 #include <ibm/interrupt.h>
6 #include "../../kernel/const.h"
7 #include "../../kernel/config.h"
8 #include "../../kernel/debug.h"
9 #include "../../kernel/type.h"
10 #include "../../kernel/proc.h"
11 #include "../../kernel/ipc.h"
12
13 #define click_to_round_k(n) \
14 ((unsigned) ((((unsigned long) (n) << CLICK_SHIFT) + 512) / 1024))
15
16 /* Declare some local dump procedures. */
17 FORWARD _PROTOTYPE( char *proc_name, (int proc_nr) );
18 FORWARD _PROTOTYPE( char *s_traps_str, (int flags) );
19 FORWARD _PROTOTYPE( char *s_flags_str, (int flags) );
20 FORWARD _PROTOTYPE( char *p_rts_flags_str, (int flags) );
21
22 /* Some global data that is shared among several dumping procedures.
23 * Note that the process table copy has the same name as in the kernel
24 * so that most macros and definitions from proc.h also apply here.
25 */
26 PUBLIC struct proc proc[NR_TASKS + NR_PROCS];
27 PUBLIC struct priv priv[NR_SYS_PROCS];
28 PUBLIC struct boot_image image[NR_BOOT_PROCS];
29
30 /*===========================================================================*
31 * timing_dmp *
32 *===========================================================================*/
33 PUBLIC void timing_dmp()
34 {
35 #if ! DEBUG_TIME_LOCKS
36 printf("Enable the DEBUG_TIME_LOCKS definition in src/kernel/config.h\n");
37 #else
38 static struct lock_timingdata timingdata[TIMING_CATEGORIES];
39 int r, c, f, skipped = 0, printed = 0, maxlines = 23, x = 0;
40 static int offsetlines = 0;
41
42 if ((r = sys_getlocktimings(&timingdata[0])) != OK) {
43 report("IS","warning: couldn't get copy of lock timings", r);
44 return;
45 }
46
47 for(c = 0; c < TIMING_CATEGORIES; c++) {
48 int b;
49 if (!timingdata[c].lock_timings_range[0] || !timingdata[c].binsize)
50 continue;
51 x = printf("%-*s: misses %lu, resets %lu, measurements %lu: ",
52 TIMING_NAME, timingdata[c].names,
53 timingdata[c].misses,
54 timingdata[c].resets,
55 timingdata[c].measurements);
56 for(b = 0; b < TIMING_POINTS; b++) {
57 int w;
58 if (!timingdata[c].lock_timings[b])
59 continue;
60 x += (w = printf(" %5d: %5d", timingdata[c].lock_timings_range[0] +
61 b*timingdata[c].binsize,
62 timingdata[c].lock_timings[b]));
63 if (x + w >= 80) { printf("\n"); x = 0; }
64 }
65 if (x > 0) printf("\n");
66 }
67 #endif
68 }
69
70 /*===========================================================================*
71 * kmessages_dmp *
72 *===========================================================================*/
73 PUBLIC void kmessages_dmp()
74 {
75 struct kmessages kmess; /* get copy of kernel messages */
76 char print_buf[KMESS_BUF_SIZE+1]; /* this one is used to print */
77 int start; /* calculate start of messages */
78 int r;
79
80 /* Try to get a copy of the kernel messages. */
81 if ((r = sys_getkmessages(&kmess)) != OK) {
82 report("IS","warning: couldn't get copy of kmessages", r);
83 return;
84 }
85
86 /* Try to print the kernel messages. First determine start and copy the
87 * buffer into a print-buffer. This is done because the messages in the
88 * copy may wrap (the kernel buffer is circular).
89 */
90 start = ((kmess.km_next + KMESS_BUF_SIZE) - kmess.km_size) % KMESS_BUF_SIZE;
91 r = 0;
92 while (kmess.km_size > 0) {
93 print_buf[r] = kmess.km_buf[(start+r) % KMESS_BUF_SIZE];
94 r ++;
95 kmess.km_size --;
96 }
97 print_buf[r] = 0; /* make sure it terminates */
98 printf("Dump of all messages generated by the kernel.\n\n");
99 printf("%s", print_buf); /* print the messages */
100 }
101
102 /*===========================================================================*
103 * monparams_dmp *
104 *===========================================================================*/
105 PUBLIC void monparams_dmp()
106 {
107 char val[1024];
108 char *e;
109 int r;
110
111 /* Try to get a copy of the boot monitor parameters. */
112 if ((r = sys_getmonparams(val, sizeof(val))) != OK) {
113 report("IS","warning: couldn't get copy of monitor params", r);
114 return;
115 }
116
117 /* Append new lines to the result. */
118 e = val;
119 do {
120 e += strlen(e);
121 *e++ = '\n';
122 } while (*e != 0);
123
124 /* Finally, print the result. */
125 printf("Dump of kernel environment strings set by boot monitor.\n");
126 printf("\n%s\n", val);
127 }
128
129 /*===========================================================================*
130 * irqtab_dmp *
131 *===========================================================================*/
132 PUBLIC void irqtab_dmp()
133 {
134 int i,r;
135 struct irq_hook irq_hooks[NR_IRQ_HOOKS];
136 struct irq_hook *e; /* irq tab entry */
137 char *irq[] = {
138 "clock", /* 00 */
139 "keyboard", /* 01 */
140 "cascade", /* 02 */
141 "rs232", /* 03 */
142 "rs232", /* 04 */
143 "NIC(eth)", /* 05 */
144 "floppy", /* 06 */
145 "printer", /* 07 */
146 "", /* 08 */
147 "", /* 09 */
148 "", /* 10 */
149 "", /* 11 */
150 "", /* 12 */
151 "", /* 13 */
152 "at_wini_0", /* 14 */
153 "at_wini_1", /* 15 */
154 };
155
156 if ((r = sys_getirqhooks(irq_hooks)) != OK) {
157 report("IS","warning: couldn't get copy of irq hooks", r);
158 return;
159 }
160
161 printf("IRQ policies dump shows use of kernel's IRQ hooks.\n");
162 printf("-h.id- -proc.nr- -IRQ vector (nr.)- -policy- -notify id-\n");
163 for (i=0; i<NR_IRQ_HOOKS; i++) {
164 e = &irq_hooks[i];
165 printf("%3d", i);
166 if (e->proc_nr==NONE) {
167 printf(" <unused>\n");
168 continue;
169 }
170 printf("%10d ", e->proc_nr);
171 printf(" %9.9s (%02d) ", irq[e->irq], e->irq);
172 printf(" %s", (e->policy & IRQ_REENABLE) ? "reenable" : " - ");
173 printf(" %d\n", e->notify_id);
174 }
175 printf("\n");
176 }
177
178 /*===========================================================================*
179 * image_dmp *
180 *===========================================================================*/
181 PUBLIC void image_dmp()
182 {
183 int m, i,j,r;
184 struct boot_image *ip;
185 static char ipc_to[BITCHUNK_BITS*2];
186
187 if ((r = sys_getimage(image)) != OK) {
188 report("IS","warning: couldn't get copy of image table", r);
189 return;
190 }
191 printf("Image table dump showing all processes included in system image.\n");
192 printf("---name-- -nr- -flags- -traps- -sq- ----pc- -stack- -ipc_to[0]--------\n");
193 for (m=0; m<NR_BOOT_PROCS; m++) {
194 ip = &image[m];
195 for (i=j=0; i < BITCHUNK_BITS; i++, j++) {
196 ipc_to[j] = (ip->ipc_to & (1<<i)) ? '1' : '';
197 if (i % 8 == 7) ipc_to[++j] = ' ';
198 }
199 ipc_to[j] = '\0';
200 printf("%8s %4d %s %s %3d %7lu %7lu %s\n",
201 ip->proc_name, ip->proc_nr,
202 s_flags_str(ip->flags), s_traps_str(ip->trap_mask),
203 ip->priority, (long)ip->initial_pc, ip->stksize, ipc_to);
204 }
205 printf("\n");
206 }
207
208 /*===========================================================================*
209 * sched_dmp *
210 *===========================================================================*/
211 PUBLIC void sched_dmp()
212 {
213 struct proc *rdy_head[NR_SCHED_QUEUES];
214 struct kinfo kinfo;
215 register struct proc *rp;
216 vir_bytes ptr_diff;
217 int r;
218
219 /* First obtain a scheduling information. */
220 if ((r = sys_getschedinfo(proc, rdy_head)) != OK) {
221 report("IS","warning: couldn't get copy of process table", r);
222 return;
223 }
224 /* Then obtain kernel addresses to correct pointer information. */
225 if ((r = sys_getkinfo(&kinfo)) != OK) {
226 report("IS","warning: couldn't get kernel addresses", r);
227 return;
228 }
229
230 /* Update all pointers. Nasty pointer algorithmic ... */
231 ptr_diff = (vir_bytes) proc - (vir_bytes) kinfo.proc_addr;
232 for (r=0;r<NR_SCHED_QUEUES; r++)
233 if (rdy_head[r] != NIL_PROC)
234 rdy_head[r] =
235 (struct proc *)((vir_bytes) rdy_head[r] + ptr_diff);
236 for (rp=BEG_PROC_ADDR; rp < END_PROC_ADDR; rp++)
237 if (rp->p_nextready != NIL_PROC)
238 rp->p_nextready =
239 (struct proc *)((vir_bytes) rp->p_nextready + ptr_diff);
240
241 /* Now show scheduling queues. */
242 printf("Dumping scheduling queues.\n");
243
244 for (r=0;r<NR_SCHED_QUEUES; r++) {
245 rp = rdy_head[r];
246 if (!rp) continue;
247 printf("%2d: ", r);
248 while (rp != NIL_PROC) {
249 printf("%3d ", rp->p_nr);
250 rp = rp->p_nextready;
251 }
252 printf("\n");
253 }
254 printf("\n");
255 }
256
257 /*===========================================================================*
258 * kenv_dmp *
259 *===========================================================================*/
260 PUBLIC void kenv_dmp()
261 {
262 struct kinfo kinfo;
263 struct machine machine;
264 int r;
265 if ((r = sys_getkinfo(&kinfo)) != OK) {
266 report("IS","warning: couldn't get copy of kernel info struct", r);
267 return;
268 }
269 if ((r = sys_getmachine(&machine)) != OK) {
270 report("IS","warning: couldn't get copy of kernel machine struct", r);
271 return;
272 }
273
274 printf("Dump of kinfo and machine structures.\n\n");
275 printf("Machine structure:\n");
276 printf("- pc_at: %3d\n", machine.pc_at);
277 printf("- ps_mca: %3d\n", machine.ps_mca);
278 printf("- processor: %3d\n", machine.processor);
279 printf("- protected: %3d\n", machine.protected);
280 printf("- vdu_ega: %3d\n", machine.vdu_ega);
281 printf("- vdu_vga: %3d\n\n", machine.vdu_vga);
282 printf("Kernel info structure:\n");
283 printf("- code_base: %5u\n", kinfo.code_base);
284 printf("- code_size: %5u\n", kinfo.code_size);
285 printf("- data_base: %5u\n", kinfo.data_base);
286 printf("- data_size: %5u\n", kinfo.data_size);
287 printf("- proc_addr: %5u\n", kinfo.proc_addr);
288 printf("- kmem_base: %5u\n", kinfo.kmem_base);
289 printf("- kmem_size: %5u\n", kinfo.kmem_size);
290 printf("- bootdev_base: %5u\n", kinfo.bootdev_base);
291 printf("- bootdev_size: %5u\n", kinfo.bootdev_size);
292 printf("- ramdev_base: %5u\n", kinfo.ramdev_base);
293 printf("- ramdev_size: %5u\n", kinfo.ramdev_size);
294 printf("- params_base: %5u\n", kinfo.params_base);
295 printf("- params_size: %5u\n", kinfo.params_size);
296 printf("- nr_procs: %3u\n", kinfo.nr_procs);
297 printf("- nr_tasks: %3u\n", kinfo.nr_tasks);
298 printf("- release: %.6s\n", kinfo.release);
299 printf("- version: %.6s\n", kinfo.version);
300 #if DEBUG_LOCK_CHECK
301 printf("- relocking: %d\n", kinfo.relocking);
302 #endif
303 printf("\n");
304 }
305
306 PRIVATE char *s_flags_str(int flags)
307 {
308 static char str[10];
309 str[0] = (flags & PREEMPTIBLE) ? 'P' : '-';
310 str[1] = '-';
311 str[2] = (flags & BILLABLE) ? 'B' : '-';
312 str[3] = (flags & SYS_PROC) ? 'S' : '-';
313 str[4] = '-';
314 str[5] = '\0';
315
316 return str;
317 }
318
319 PRIVATE char *s_traps_str(int flags)
320 {
321 static char str[10];
322 str[0] = (flags & (1 << ECHO)) ? 'E' : '-';
323 str[1] = (flags & (1 << SEND)) ? 'S' : '-';
324 str[2] = (flags & (1 << RECEIVE)) ? 'R' : '-';
325 str[3] = (flags & (1 << SENDREC)) ? 'B' : '-';
326 str[4] = (flags & (1 << NOTIFY)) ? 'N' : '-';
327 str[5] = '\0';
328
329 return str;
330 }
331
332 /*===========================================================================*
333 * privileges_dmp *
334 *===========================================================================*/
335 PUBLIC void privileges_dmp()
336 {
337 register struct proc *rp;
338 static struct proc *oldrp = BEG_PROC_ADDR;
339 register struct priv *sp;
340 static char ipc_to[NR_SYS_PROCS + 1 + NR_SYS_PROCS/8];
341 int r, i,j, n = 0;
342
343 /* First obtain a fresh copy of the current process and system table. */
344 if ((r = sys_getprivtab(priv)) != OK) {
345 report("IS","warning: couldn't get copy of system privileges table", r);
346 return;
347 }
348 if ((r = sys_getproctab(proc)) != OK) {
349 report("IS","warning: couldn't get copy of process table", r);
350 return;
351 }
352
353 printf("\n--nr-id-name---- -flags- -traps- -ipc_to mask------------------------ \n");
354
355 for (rp = oldrp; rp < END_PROC_ADDR; rp++) {
356 if (isemptyp(rp)) continue;
357 if (++n > 23) break;
358 if (proc_nr(rp) == IDLE) printf("(%2d) ", proc_nr(rp));
359 else if (proc_nr(rp) < 0) printf("[%2d] ", proc_nr(rp));
360 else printf(" %2d ", proc_nr(rp));
361 r = -1;
362 for (sp = &priv[0]; sp < &priv[NR_SYS_PROCS]; sp++)
363 if (sp->s_proc_nr == rp->p_nr) { r ++; break; }
364 if (r == -1 && ! (rp->p_rts_flags & SLOT_FREE)) {
365 sp = &priv[USER_PRIV_ID];
366 }
367 printf("(%02u) %-7.7s %s %s ",
368 sp->s_id, rp->p_name,
369 s_flags_str(sp->s_flags), s_traps_str(sp->s_trap_mask)
370 );
371 for (i=j=0; i < NR_SYS_PROCS; i++, j++) {
372 ipc_to[j] = get_sys_bit(sp->s_ipc_to, i) ? '1' : '';
373 if (i % 8 == 7) ipc_to[++j] = ' ';
374 }
375 ipc_to[j] = '\0';
376
377 printf(" %s \n", ipc_to);
378 }
379 if (rp == END_PROC_ADDR) rp = BEG_PROC_ADDR; else printf("--more--\r");
380 oldrp = rp;
381
382 }
383
384 /*===========================================================================*
385 * sendmask_dmp *
386 *===========================================================================*/
387 PUBLIC void sendmask_dmp()
388 {
389 register struct proc *rp;
390 static struct proc *oldrp = BEG_PROC_ADDR;
391 int r, i,j, n = 0;
392
393 /* First obtain a fresh copy of the current process table. */
394 if ((r = sys_getproctab(proc)) != OK) {
395 report("IS","warning: couldn't get copy of process table", r);
396 return;
397 }
398
399 printf("\n\n");
400 printf("Sendmask dump for process table. User processes (*) don't have [].");
401 printf("\n");
402 printf("The rows of bits indicate to which processes each process may send.");
403 printf("\n\n");
404
405 #if DEAD_CODE
406 printf(" ");
407 for (j=proc_nr(BEG_PROC_ADDR); j< INIT_PROC_NR+1; j++) {
408 printf("%3d", j);
409 }
410 printf(" *\n");
411
412 for (rp = oldrp; rp < END_PROC_ADDR; rp++) {
413 if (isemptyp(rp)) continue;
414 if (++n > 20) break;
415
416 printf("%8s ", rp->p_name);
417 if (proc_nr(rp) == IDLE) printf("(%2d) ", proc_nr(rp));
418 else if (proc_nr(rp) < 0) printf("[%2d] ", proc_nr(rp));
419 else printf(" %2d ", proc_nr(rp));
420
421 for (j=proc_nr(BEG_PROC_ADDR); j<INIT_PROC_NR+2; j++) {
422 if (isallowed(rp->p_sendmask, j)) printf(" 1 ");
423 else printf(" 0 ");
424 }
425 printf("\n");
426 }
427 if (rp == END_PROC_ADDR) { printf("\n"); rp = BEG_PROC_ADDR; }
428 else printf("--more--\r");
429 oldrp = rp;
430 #endif
431 }
432
433 PRIVATE char *p_rts_flags_str(int flags)
434 {
435 static char str[10];
436 str[0] = (flags & NO_MAP) ? 'M' : '-';
437 str[1] = (flags & SENDING) ? 'S' : '-';
438 str[2] = (flags & RECEIVING) ? 'R' : '-';
439 str[3] = (flags & SIGNALED) ? 'I' : '-';
440 str[4] = (flags & SIG_PENDING) ? 'P' : '-';
441 str[5] = (flags & P_STOP) ? 'T' : '-';
442 str[6] = '\0';
443
444 return str;
445 }
446
447 /*===========================================================================*
448 * proctab_dmp *
449 *===========================================================================*/
450 #if (CHIP == INTEL)
451 PUBLIC void proctab_dmp()
452 {
453 /* Proc table dump */
454
455 register struct proc *rp;
456 static struct proc *oldrp = BEG_PROC_ADDR;
457 int r, n = 0;
458 phys_clicks text, data, size;
459
460 /* First obtain a fresh copy of the current process table. */
461 if ((r = sys_getproctab(proc)) != OK) {
462 report("IS","warning: couldn't get copy of process table", r);
463 return;
464 }
465
466 printf("\n--nr-name---- -prior-quant- -user---sys- -text---data---size- -rts flags-\n");
467
468 for (rp = oldrp; rp < END_PROC_ADDR; rp++) {
469 if (isemptyp(rp)) continue;
470 if (++n > 23) break;
471 text = rp->p_memmap[T].mem_phys;
472 data = rp->p_memmap[D].mem_phys;
473 size = rp->p_memmap[T].mem_len
474 + ((rp->p_memmap[S].mem_phys + rp->p_memmap[S].mem_len) - data);
475 if (proc_nr(rp) == IDLE) printf("(%2d) ", proc_nr(rp));
476 else if (proc_nr(rp) < 0) printf("[%2d] ", proc_nr(rp));
477 else printf(" %2d ", proc_nr(rp));
478 printf(" %-8.8s %02u/%02u %02d/%02u %6lu%6lu %6uK%6uK%6uK %s",
479 rp->p_name,
480 rp->p_priority, rp->p_max_priority,
481 rp->p_ticks_left, rp->p_quantum_size,
482 rp->p_user_time, rp->p_sys_time,
483 click_to_round_k(text), click_to_round_k(data),
484 click_to_round_k(size),
485 p_rts_flags_str(rp->p_rts_flags));
486 if (rp->p_rts_flags & (SENDING|RECEIVING)) {
487 printf(" %-7.7s", proc_name(rp->p_getfrom));
488 }
489 printf("\n");
490 }
491 if (rp == END_PROC_ADDR) rp = BEG_PROC_ADDR; else printf("--more--\r");
492 oldrp = rp;
493 }
494 #endif /* (CHIP == INTEL) */
495
496 /*===========================================================================*
497 * memmap_dmp *
498 *===========================================================================*/
499 PUBLIC void memmap_dmp()
500 {
501 register struct proc *rp;
502 static struct proc *oldrp = proc;
503 int r, n = 0;
504 phys_clicks size;
505
506 /* First obtain a fresh copy of the current process table. */
507 if ((r = sys_getproctab(proc)) != OK) {
508 report("IS","warning: couldn't get copy of process table", r);
509 return;
510 }
511
512 printf("\n-nr/name--- --pc-- --sp-- -----text----- -----data----- ----stack----- --size-\n");
513 for (rp = oldrp; rp < END_PROC_ADDR; rp++) {
514 if (isemptyp(rp)) continue;
515 if (++n > 23) break;
516 size = rp->p_memmap[T].mem_len
517 + ((rp->p_memmap[S].mem_phys + rp->p_memmap[S].mem_len)
518 - rp->p_memmap[D].mem_phys);
519 printf("%3d %-7.7s%7lx%7lx %4x %4x %4x %4x %4x %4x %4x %4x %4x %5uK\n",
520 proc_nr(rp),
521 rp->p_name,
522 (unsigned long) rp->p_reg.pc,
523 (unsigned long) rp->p_reg.sp,
524 rp->p_memmap[T].mem_vir, rp->p_memmap[T].mem_phys, rp->p_memmap[T].mem_len,
525 rp->p_memmap[D].mem_vir, rp->p_memmap[D].mem_phys, rp->p_memmap[D].mem_len,
526 rp->p_memmap[S].mem_vir, rp->p_memmap[S].mem_phys, rp->p_memmap[S].mem_len,
527 click_to_round_k(size));
528 }
529 if (rp == END_PROC_ADDR) rp = proc;
530 else printf("--more--\r");
531 oldrp = rp;
532 }
533
534 /*===========================================================================*
535 * proc_name *
536 *===========================================================================*/
537 PRIVATE char *proc_name(proc_nr)
538 int proc_nr;
539 {
540 if (proc_nr == ANY) return "ANY";
541 return cproc_addr(proc_nr)->p_name;
542 }
543
Cache object: d05722498c6edbeb1d63c1da2d98882d
|