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