xref: /minix/minix/servers/is/dmp_kernel.c (revision 117b6ea0)
1 /* Debugging dump procedures for the kernel. */
2 
3 #include "inc.h"
4 #include <lib.h>
5 #include <minix/timers.h>
6 #include <assert.h>
7 #include <machine/interrupt.h>
8 #include <minix/endpoint.h>
9 #include <minix/sysutil.h>
10 #include <minix/sys_config.h>
11 #include "kernel/const.h"
12 #include "kernel/config.h"
13 #include "kernel/debug.h"
14 #include "kernel/type.h"
15 #include "kernel/proc.h"
16 #include "kernel/ipc.h"
17 
18 #define LINES 22
19 
20 #define PRINTRTS(rp) { \
21 	char *procname = "";	\
22 	printf(" %s", p_rts_flags_str(rp->p_rts_flags));	\
23 	if (rp->p_rts_flags & RTS_SENDING)				\
24 		procname = proc_name(_ENDPOINT_P(rp->p_sendto_e)); \
25 	else if (rp->p_rts_flags & RTS_RECEIVING)			\
26 		procname = proc_name(_ENDPOINT_P(rp->p_getfrom_e)); \
27 	printf(" %-7.7s", procname);	\
28 }
29 
30 static int pagelines;
31 
32 #define PROCLOOP(rp, oldrp) \
33 	pagelines = 0; \
34 	for (rp = oldrp; rp < END_PROC_ADDR; rp++) { \
35 	  oldrp = BEG_PROC_ADDR; \
36 	  if (isemptyp(rp)) continue; \
37 	  if (++pagelines >= LINES) { oldrp = rp; printf("--more--\n"); break; }\
38 	  if (proc_nr(rp) == IDLE) 	printf("(%2d) ", proc_nr(rp));  \
39 	  else if (proc_nr(rp) < 0) 	printf("[%2d] ", proc_nr(rp)); 	\
40 	  else 				printf(" %2d  ", proc_nr(rp));
41 
42 #define click_to_round_k(n) \
43 	((unsigned) ((((unsigned long) (n) << CLICK_SHIFT) + 512) / 1024))
44 
45 /* Declare some local dump procedures. */
46 static char *proc_name(int proc_nr);
47 static char *s_traps_str(int flags);
48 static char *s_flags_str(int flags);
49 static char *p_rts_flags_str(int flags);
50 
51 /* Some global data that is shared among several dumping procedures.
52  * Note that the process table copy has the same name as in the kernel
53  * so that most macros and definitions from proc.h also apply here.
54  */
55 struct proc proc[NR_TASKS + NR_PROCS];
56 struct priv priv[NR_SYS_PROCS];
57 struct boot_image image[NR_BOOT_PROCS];
58 
59 /*===========================================================================*
60  *				kmessages_dmp				     *
61  *===========================================================================*/
62 void
63 kmessages_dmp(void)
64 {
65   struct kmessages *kmess;		/* get copy of kernel messages */
66   static char print_buf[_KMESS_BUF_SIZE+1]; /* this one is used to print */
67   int start;				/* calculate start of messages */
68   int r;
69   int size;
70 
71   kmess = get_minix_kerninfo()->kmessages;
72 
73   /* Try to print the kernel messages. First determine start and copy the
74    * buffer into a print-buffer. This is done because the messages in the
75    * copy may wrap (the kernel buffer is circular).
76    */
77   start = ((kmess->km_next + _KMESS_BUF_SIZE) - kmess->km_size) % _KMESS_BUF_SIZE;
78   r = 0;
79   size = kmess->km_size;
80   while (size > 0) {
81   	print_buf[r] = kmess->km_buf[(start+r) % _KMESS_BUF_SIZE];
82   	r ++;
83   	size--;
84   }
85   print_buf[r] = 0;		/* make sure it terminates */
86   printf("Dump of all messages generated by the kernel.\n\n");
87   printf("%s", print_buf);		/* print the messages */
88 }
89 
90 /*===========================================================================*
91  *				monparams_dmp				     *
92  *===========================================================================*/
93 void
94 monparams_dmp(void)
95 {
96   char val[MULTIBOOT_PARAM_BUF_SIZE];
97   char *e;
98   int r;
99 
100   /* Try to get a copy of the boot monitor parameters. */
101   if ((r = sys_getmonparams(val, sizeof(val))) != OK) {
102       printf("IS: warning: couldn't get copy of monitor params: %d\n", r);
103       return;
104   }
105 
106   /* Append new lines to the result. */
107   e = val;
108   do {
109 	e += strlen(e);
110 	*e++ = '\n';
111   } while (*e != 0);
112 
113   /* Finally, print the result. */
114   printf("Dump of kernel environment strings set by boot monitor.\n");
115   printf("\n%s\n", val);
116 }
117 
118 /*===========================================================================*
119  *				irqtab_dmp				     *
120  *===========================================================================*/
121 void
122 irqtab_dmp(void)
123 {
124   int i,r;
125   struct irq_hook irq_hooks[NR_IRQ_HOOKS];
126   int irq_actids[NR_IRQ_VECTORS];
127   struct irq_hook *e;	/* irq tab entry */
128 
129   if ((r = sys_getirqhooks(irq_hooks)) != OK) {
130       printf("IS: warning: couldn't get copy of irq hooks: %d\n", r);
131       return;
132   }
133   if ((r = sys_getirqactids(irq_actids)) != OK) {
134       printf("IS: warning: couldn't get copy of irq mask: %d\n", r);
135       return;
136   }
137 
138 #if 0
139   printf("irq_actids:");
140   for (i= 0; i<NR_IRQ_VECTORS; i++)
141 	printf(" [%d] = 0x%08x", i, irq_actids[i]);
142   printf("\n");
143 #endif
144 
145   printf("IRQ policies dump shows use of kernel's IRQ hooks.\n");
146   printf("-h.id- -proc.nr- -irq nr- -policy- -notify id- -masked-\n");
147   for (i=0; i<NR_IRQ_HOOKS; i++) {
148   	e = &irq_hooks[i];
149   	printf("%3d", i);
150   	if (e->proc_nr_e==NONE) {
151   	    printf("    <unused>\n");
152   	    continue;
153   	}
154   	printf("%10d  ", e->proc_nr_e);
155   	printf("    (%02d) ", e->irq);
156   	printf("  %s", (e->policy & IRQ_REENABLE) ? "reenable" : "    -   ");
157   	printf("   %4lu", e->notify_id);
158 	if (irq_actids[e->irq] & e->id)
159 		printf("       masked");
160 	printf("\n");
161   }
162   printf("\n");
163 }
164 
165 /*===========================================================================*
166  *				image_dmp				     *
167  *===========================================================================*/
168 void
169 image_dmp(void)
170 {
171   int m, r;
172   struct boot_image *ip;
173 
174   if ((r = sys_getimage(image)) != OK) {
175       printf("IS: warning: couldn't get copy of image table: %d\n", r);
176       return;
177   }
178   printf("Image table dump showing all processes included in system image.\n");
179   printf("---name- -nr- flags -stack-\n");
180   for (m=0; m<NR_BOOT_PROCS; m++) {
181       ip = &image[m];
182       printf("%8s %4d\n", ip->proc_name, ip->proc_nr);
183   }
184   printf("\n");
185 }
186 
187 
188 /*===========================================================================*
189  *				kenv_dmp				     *
190  *===========================================================================*/
191 void
192 kenv_dmp(void)
193 {
194     struct kinfo kinfo;
195     struct machine machine;
196     int r;
197     if ((r = sys_getkinfo(&kinfo)) != OK) {
198     	printf("IS: warning: couldn't get copy of kernel info struct: %d\n", r);
199     	return;
200     }
201     if ((r = sys_getmachine(&machine)) != OK) {
202     	printf("IS: warning: couldn't get copy of kernel machine struct: %d\n", r);
203     	return;
204     }
205 
206     printf("Dump of kinfo structure.\n\n");
207     printf("Kernel info structure:\n");
208     printf("- nr_procs:     %3u\n", kinfo.nr_procs);
209     printf("- nr_tasks:     %3u\n", kinfo.nr_tasks);
210     printf("- release:      %.6s\n", kinfo.release);
211     printf("- version:      %.6s\n", kinfo.version);
212     printf("\n");
213 }
214 
215 /*===========================================================================*
216  *			      s_flags_str				     *
217  *===========================================================================*/
218 static char *s_flags_str(int flags)
219 {
220 	static char str[10];
221 	str[0] = (flags & PREEMPTIBLE)        ? 'P' : '-';
222 	str[1] = (flags & BILLABLE)           ? 'B' : '-';
223 	str[2] = (flags & DYN_PRIV_ID)        ? 'D' : '-';
224 	str[3] = (flags & SYS_PROC)           ? 'S' : '-';
225 	str[4] = (flags & CHECK_IO_PORT)      ? 'I' : '-';
226 	str[5] = (flags & CHECK_IRQ)          ? 'Q' : '-';
227 	str[6] = (flags & CHECK_MEM)          ? 'M' : '-';
228 	str[7] = '\0';
229 
230 	return str;
231 }
232 
233 /*===========================================================================*
234  *			      s_traps_str				     *
235  *===========================================================================*/
236 static char *s_traps_str(int flags)
237 {
238 	static char str[10];
239 	str[0] = (flags & (1 << SEND))  ? 'S' : '-';
240 	str[1] = (flags & (1 << SENDA)) ? 'A' : '-';
241 	str[2] = (flags & (1 << RECEIVE))  ? 'R' : '-';
242 	str[3] = (flags & (1 << SENDREC))  ? 'B' : '-';
243 	str[4] = (flags & (1 << NOTIFY)) ? 'N' : '-';
244 	str[5] = '\0';
245 
246 	return str;
247 }
248 
249 /*===========================================================================*
250  *				privileges_dmp 				     *
251  *===========================================================================*/
252 void
253 privileges_dmp(void)
254 {
255   register struct proc *rp;
256   static struct proc *oldrp = BEG_PROC_ADDR;
257   register struct priv *sp;
258   int r, i;
259 
260   /* First obtain a fresh copy of the current process and system table. */
261   if ((r = sys_getprivtab(priv)) != OK) {
262       printf("IS: warning: couldn't get copy of system privileges table: %d\n", r);
263       return;
264   }
265   if ((r = sys_getproctab(proc)) != OK) {
266       printf("IS: warning: couldn't get copy of process table: %d\n", r);
267       return;
268   }
269 
270   printf("-nr- -id- -name-- -flags- traps grants -ipc_to--"
271     "          -kernel calls-\n");
272 
273   PROCLOOP(rp, oldrp)
274         r = -1;
275         for (sp = &priv[0]; sp < &priv[NR_SYS_PROCS]; sp++)
276             if (sp->s_proc_nr == rp->p_nr) { r ++; break; }
277         if (r == -1 && !isemptyp(rp)) {
278 	    sp = &priv[USER_PRIV_ID];
279         }
280 	printf("(%02u) %-7.7s %s %s %6d",
281 	       sp->s_id, rp->p_name,
282 	       s_flags_str(sp->s_flags), s_traps_str(sp->s_trap_mask),
283 		sp->s_grant_entries);
284         for (i=0; i < NR_SYS_PROCS; i += BITCHUNK_BITS) {
285 	    printf(" %08x", get_sys_bits(sp->s_ipc_to, i));
286        	}
287 
288 	printf(" ");
289         for (i=0; i < NR_SYS_CALLS; i += BITCHUNK_BITS) {
290 	    printf(" %08x", sp->s_k_call_mask[i/BITCHUNK_BITS]);
291        	}
292 	printf("\n");
293 
294   }
295 }
296 
297 /*===========================================================================*
298  *			       p_rts_flags_str 				     *
299  *===========================================================================*/
300 static char *p_rts_flags_str(int flags)
301 {
302 	static char str[10];
303 	str[0] = (flags & RTS_PROC_STOP) ? 's' : '-';
304 	str[1] = (flags & RTS_SENDING)  ? 'S' : '-';
305 	str[2] = (flags & RTS_RECEIVING)    ? 'R' : '-';
306 	str[3] = (flags & RTS_SIGNALED)    ? 'I' : '-';
307 	str[4] = (flags & RTS_SIG_PENDING)    ? 'P' : '-';
308 	str[5] = (flags & RTS_P_STOP)    ? 'T' : '-';
309 	str[6] = (flags & RTS_NO_PRIV) ? 'p' : '-';
310 	str[7] = '\0';
311 
312 	return str;
313 }
314 
315 /*===========================================================================*
316  *				proctab_dmp    				     *
317  *===========================================================================*/
318 #if defined(__i386__)
319 void proctab_dmp(void)
320 {
321 /* Proc table dump */
322 
323   register struct proc *rp;
324   static struct proc *oldrp = BEG_PROC_ADDR;
325   int r;
326 
327   /* First obtain a fresh copy of the current process table. */
328   if ((r = sys_getproctab(proc)) != OK) {
329       printf("IS: warning: couldn't get copy of process table: %d\n", r);
330       return;
331   }
332 
333   printf("\n-nr-----gen---endpoint-name--- -prior-quant- -user----sys-rtsflags-from/to-\n");
334 
335   PROCLOOP(rp, oldrp)
336 	printf(" %5d %10d ", _ENDPOINT_G(rp->p_endpoint), rp->p_endpoint);
337 	printf("%-8.8s %5u %5u %6u %6u ",
338 	       rp->p_name,
339 	       rp->p_priority,
340 	       rp->p_quantum_size_ms,
341 	       rp->p_user_time, rp->p_sys_time);
342 	PRINTRTS(rp);
343 	printf("\n");
344   }
345 }
346 #endif				/* defined(__i386__) */
347 
348 #if defined(__arm__)
349 void proctab_dmp(void)
350 {
351     /* LSC FIXME: Not implemented for arm */
352 }
353 #endif				/* defined(__arm__) */
354 
355 /*===========================================================================*
356  *				procstack_dmp  				     *
357  *===========================================================================*/
358 void
359 procstack_dmp(void)
360 {
361 /* Proc table dump, with stack */
362 
363   register struct proc *rp;
364   static struct proc *oldrp = BEG_PROC_ADDR;
365   int r;
366 
367   /* First obtain a fresh copy of the current process table. */
368   if ((r = sys_getproctab(proc)) != OK) {
369       printf("IS: warning: couldn't get copy of process table: %d\n", r);
370       return;
371   }
372 
373   printf("\n-nr-rts flags--      --stack--\n");
374 
375   PROCLOOP(rp, oldrp)
376 	PRINTRTS(rp);
377 	printf("\n"); pagelines++;
378 	sys_diagctl_stacktrace(rp->p_endpoint);
379   }
380 }
381 
382 /*===========================================================================*
383  *				proc_name    				     *
384  *===========================================================================*/
385 static char *
386 proc_name(int proc_nr)
387 {
388   struct proc *p;
389   if (proc_nr == ANY) return "ANY";
390   if (proc_nr == NONE) return "NONE";	/* bogus */
391   if (proc_nr < -NR_TASKS || proc_nr >= NR_PROCS) return "BOGUS";
392   p = proc_addr(proc_nr);
393   if (isemptyp(p)) return "EMPTY";	/* bogus */
394   return p->p_name;
395 }
396 
397