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