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