debug.c (10141B)
1 /* Copyright 1998-1999, Brian J. Swetland. All rights reserved. 2 ** Distributed under the terms of the OpenBLT License 3 */ 4 5 #ifndef KDEBUG 6 7 #include <i386/io.h> 8 #include <blt/conio.h> 9 10 #include <string.h> 11 #include "kernel.h" 12 #include "port.h" 13 #include "rights.h" 14 #include "resource.h" 15 #include "list.h" 16 #include "i386.h" 17 18 extern list_t resource_list; 19 20 #define RMAX 1024 21 22 static char *tstate[] = 23 { "KERNL", "RUNNG", "READY", "DEAD ", "WAIT ", "S/IRQ", "S/TMR", "S/PAG" }; 24 25 uint32 readnum(const char *s); 26 27 char *taskstate(task_t *task) 28 { 29 static char ts[60]; 30 if(task->waiting_on){ 31 snprintf(ts,60,"Waiting on %s #%d \"%s\"", 32 rsrc_typename(task->waiting_on), task->waiting_on->id, 33 task->waiting_on->name); 34 return ts; 35 } else { 36 return "Running"; 37 } 38 } 39 40 void printres(resource_t *r) 41 { 42 switch(r->type){ 43 case RSRC_PORT: 44 kprintf(" PORT %U: (slave=%d) (size=%d) \"%s\"",r->id, 45 ((port_t*)r)->slaved, ((port_t*)r)->msgcount,r->name); 46 break; 47 case RSRC_TASK: 48 kprintf(" TASK %U: \"%s\"",r->id,r->name); 49 kprintf(" : %s",taskstate((task_t*)r)); 50 break; 51 case RSRC_ASPACE: 52 kprintf(" ASPACE %U: @ %x",r->id,((aspace_t*)r)->pdir[0]&0xFFFFF000); 53 break; 54 case RSRC_RIGHT: 55 kprintf(" RIGHT %U: %x",r->id,((right_t*)r)->flags); 56 break; 57 case RSRC_SEM: 58 kprintf(" SEM %U: (count=%d) \"%s\"", 59 r->id,((sem_t*)r)->count,r->name); 60 break; 61 case RSRC_AREA: 62 kprintf(" AREA %U: virt %x size %x pgroup %x (refcnt=%d)",r->id, 63 ((area_t*)r)->virt_addr * 0x1000, ((area_t*)r)->length * 0x1000, 64 ((area_t*)r)->pgroup, ((area_t*)r)->pgroup->refcount); 65 break; 66 case RSRC_QUEUE: 67 kprintf(" QUEUE %U: (count=%d) \"%s\"",r->id,r->queue.count,r->name); 68 break; 69 case RSRC_TEAM: 70 kprintf(" TEAM %U: \"%s\"",r->id,r->name); 71 break; 72 } 73 } 74 75 void dumprsrc(list_t *rl) 76 { 77 node_t *rn = rl->next; 78 while(rn != (node_t*) rl) { 79 printres((resource_t*)rn->data); 80 rn = rn->next; 81 } 82 } 83 84 void dumponersrc(const char *num) 85 { 86 int n; 87 node_t *rn; 88 89 n = readnum (num); 90 rn = resource_list.next; 91 while(rn != (node_t*) &resource_list) { 92 if (((resource_t*)rn->data)->id == n) { 93 printres((resource_t*) rn->data); 94 break; 95 } else { 96 rn = rn->next; 97 } 98 } 99 } 100 101 void dumptasks(void) 102 { 103 int i,j,n; 104 task_t *t; 105 aspace_t *a; 106 team_t *team; 107 108 kprintf("Task Team Aspc State Wait esp scount Name"); 109 kprintf("---- ---- ---- ----- ---- -------- -------- --------------------------------"); 110 111 for(i=1;i<RMAX;i++){ 112 if((t = rsrc_find_task(i))){ 113 team = t->rsrc.owner; 114 a = team->aspace; 115 { 116 area_t *area = rsrc_find_area(t->rsrc.owner->heap_id); 117 if(area) j = area->virt_addr + area->length; 118 else j =0; 119 } 120 121 kprintf("%U %U %U %s %U %x %x %s", 122 i,team->rsrc.id,a->rsrc.id,tstate[t->flags], 123 (t->waiting_on ? t->waiting_on->id : 0),t->esp /*j*4096*/,t->scount, 124 t->rsrc.name); 125 126 } 127 } 128 } 129 130 131 void dumpports() 132 { 133 int i; 134 port_t *p; 135 136 kprintf("Port Task Rstr Slav Size Owner Name"); 137 kprintf("---- ---- ---- ---- ---- --------------------------------"); 138 139 for(i=1;i<RMAX;i++){ 140 if((p = rsrc_find_port(i))){ 141 kprintf("%U %U %U %U %U %s", 142 i, p->rsrc.owner->rsrc.id, p->restrict, p->slaved, 143 p->msgcount, p->rsrc.owner->rsrc.name); 144 } 145 } 146 147 } 148 149 150 static void trace(uint32 ebp,uint32 eip) 151 { 152 int f = 1; 153 154 kprintf("f# EBP EIP"); 155 kprintf("00 xxxxxxxx %x",eip); 156 do { 157 /* kprintf("%X %x %x",f,ebp, *((uint32*)ebp));*/ 158 kprintf("%X %x %x",f,ebp+4, *((uint32*)(ebp+4))); 159 ebp = *((uint32*)ebp); 160 f++; 161 } while(ebp < 0x00400000 && ebp > 0x00200000); 162 } 163 164 165 static void dump(uint32 addr, int sections) 166 { 167 int i; 168 unsigned char *x; 169 170 for(i=0;i<sections;i++){ 171 x = (unsigned char *) (addr + 16*i); 172 kprintf("%x: %X %X %X %X %X %X %X %X %X %X %X %X %X %X %X %X", 173 addr+16*i,x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7], 174 x[8],x[9],x[10],x[11],x[12],x[13],x[14],x[15]); 175 } 176 } 177 178 static char *hex = "0123456789abcdef"; 179 180 #define atoi readhex 181 uint32 readhex(const char *s) 182 { 183 uint32 n=0; 184 char *x; 185 while(*s) { 186 x = hex; 187 while(*x) { 188 if(*x == *s){ 189 n = n*16 + (x - hex); 190 break; 191 } 192 x++; 193 } 194 s++; 195 } 196 return n; 197 } 198 199 uint32 readnum(const char *s) 200 { 201 uint32 n=0; 202 if((*s == '0') && (*(s+1) == 'x')) return readhex(s+2); 203 //while(isdigit(*s)) { 204 while(*s) { 205 n = n*10 + (*s - '0'); 206 s++; 207 } 208 return n; 209 } 210 211 void reboot(void) 212 { 213 i386lidt(0,0); 214 asm("int $0"); 215 } 216 217 extern aspace_t *flat; 218 219 void dumpaddr(int id) 220 { 221 node_t *an; 222 area_t *area; 223 aspace_t *a = rsrc_find_aspace(id); 224 225 if(id == 0){ 226 aspace_kprint(flat); 227 return; 228 } 229 230 if(!a) { 231 kprintf("no such aspace %d",id); 232 return; 233 } 234 235 aspace_print(a); 236 for(an = a->areas.next; an != (node_t *) &a->areas; an = an->next){ 237 area = (area_t*) an->data; 238 239 kprintf("area %U virtaddr %x size %x pgroup %x (refcnt=%d)", 240 area->rsrc.id, 241 area->virt_addr * 0x1000, 242 area->length * 0x1000, 243 area->pgroup, area->pgroup->refcount); 244 } 245 246 } 247 248 void memory_status(void); 249 void print_regs(regs *r, uint32 eip, uint32 cs, uint32 eflags); 250 251 void dumpteams(void) 252 { 253 node_t *rn = resource_list.next; 254 resource_t *rsrc; 255 256 while(rn != (node_t*) &resource_list) { 257 rsrc = (resource_t*)rn->data; 258 if(rsrc->type == RSRC_TEAM){ 259 kprintf("Team %d (%s)",rsrc->id,rsrc->name); 260 } 261 rn = rn->next; 262 } 263 } 264 265 void dumpteam(int id) 266 { 267 node_t *rn; 268 269 team_t *team = rsrc_find_team(id); 270 if(team){ 271 kprintf("team %d (%s)...",team->rsrc.id,team->rsrc.name); 272 rn = team->resources.next; 273 while(rn != (node_t*) &team->resources) { 274 printres((resource_t*) rn->data); 275 rn = rn->next; 276 } 277 } else { 278 kprintf("no such team %d",id); 279 } 280 281 } 282 283 void dumpqueue(int num) 284 { 285 resource_t *rsrc; 286 node_t *n; 287 288 int i; 289 290 for(i=1;i<RSRC_MAX;i++){ 291 if(rsrc = rsrc_find(i,num)){ 292 task_t *task; 293 kprintf("resource: %d \"%s\"",rsrc->id,rsrc->name); 294 kprintf("type : %s",rsrc_typename(rsrc)); 295 if(rsrc->owner){ 296 kprintf("owner : %d \"%s\"", 297 rsrc->owner->rsrc.id,rsrc->owner->rsrc.name); 298 } 299 kprintf("count : %d",rsrc->queue.count); 300 301 for(n = rsrc->queue.next; n != (node_t*) &rsrc->queue; n = n->next){ 302 kprintf("queue : task %d \"%s\"",((task_t*)n->data)->rsrc.id, 303 ((task_t*)n->data)->rsrc.name); 304 } 305 return; 306 } 307 } 308 kprintf("no such resource %d",n); 309 } 310 311 static int ipchksum(unsigned short *ip, int len) 312 { 313 unsigned long sum = 0; 314 315 len >>= 1; 316 while (len--) { 317 sum += *(ip++); 318 if (sum > 0xFFFF) 319 sum -= 0xFFFF; 320 } 321 return((~sum) & 0x0000FFFF); 322 } 323 324 void checksum (char *range) 325 { 326 char *s; 327 unsigned int i, good, begin, end; 328 329 if (!*range) 330 return; 331 for (i = good = 0; (i < strlen (range)) && !good; i++) 332 { 333 if (range[i] == ' ') 334 { 335 *(s = range + i) = 0; 336 s++; 337 good = 1; 338 } 339 } 340 if ((!good) || !*s) 341 return; 342 begin = atoi (range); 343 end = atoi (s); 344 kprintf ("%x", ipchksum ((unsigned short *) begin, end - begin)); 345 } 346 347 static void dumppgroup(uint32 addr) 348 { 349 pagegroup_t *pg = (pagegroup_t*) addr; 350 phys_page_t *pp = pg->pages; 351 node_t *an = pg->areas.next; 352 int size = pg->size; 353 354 kprintf("pgroup @ 0x%x rc=%d sz=%d",addr,pg->refcount,pg->size); 355 while(an != (node_t*) &pg->areas){ 356 kprintf(" area @ 0x%x (id %d) (owner #%d \"%s\")", 357 an->data,((area_t*)an->data)->rsrc.id, 358 ((area_t*)an->data)->rsrc.owner->rsrc.id, 359 ((area_t*)an->data)->rsrc.owner->rsrc.name); 360 an = an->next; 361 } 362 while(size > 0){ 363 kprintf(" pages %U %U %U %U %U %U", 364 pp->addr[0],pp->addr[1],pp->addr[2], 365 pp->addr[3],pp->addr[4],pp->addr[5]); 366 size -= 6; 367 pp = pp->next; 368 } 369 } 370 371 int findpage(uint32 n) 372 { 373 node_t *rn = resource_list.next; 374 resource_t *rsrc; 375 int count = 0; 376 int size,i; 377 378 while(rn != (node_t*) &resource_list) { 379 rsrc = (resource_t*)rn->data; 380 if(rsrc->type == RSRC_AREA){ 381 area_t *area = (area_t*) rsrc; 382 phys_page_t *pp = area->pgroup->pages; 383 size = area->pgroup->size; 384 while(size > 0){ 385 for(i=0;i<6;i++,size--){ 386 if(pp->addr[i] == n){ 387 kprintf("area %U pgroup %x slot %d",rsrc->id,area->pgroup,i); 388 count ++; 389 } 390 } 391 pp = pp->next; 392 } 393 } 394 rn = rn->next; 395 } 396 return count; 397 } 398 399 static char linebuf[80]; 400 void k_debugger(regs *r,uint32 eip, uint32 cs, uint32 eflags) 401 { 402 char *line; 403 uint32 n; 404 405 kprintf("OpenBLT Kernel Debugger"); 406 407 for(;;){ 408 krefresh(); 409 line = kgetline(linebuf,80); 410 411 if(!strncmp(line,"pgroup ",7)) { dumppgroup(readnum(line+7)); continue; } 412 if(!strncmp(line,"resource ", 9)) { dumponersrc(line+9); continue; } 413 if(!strcmp(line,"resources")) { dumprsrc(&resource_list); continue; } 414 if(!strncmp(line,"queue ",6)) { dumpqueue(readnum(line+6)); continue; } 415 if(!strcmp(line,"tasks")) { dumptasks(); continue; } 416 if(!strcmp(line,"ports")) { dumpports(); continue; } 417 if(!strcmp(line,"memory")) { memory_status(); continue; } 418 if(!strcmp(line,"trace")) { trace(r->ebp,eip); continue; } 419 if(!strcmp(line,"regs")) { print_regs(r,eip,cs,eflags); continue; } 420 if(!strncmp(line,"dump ",5)) { dump(readnum(line+5),16); continue; } 421 if(!strncmp(line,"aspace ",7)) { dumpaddr(readnum(line+7)); continue; } 422 if(!strcmp(line,"reboot")) { reboot(); } 423 if(!strncmp(line,"checksum ",9)) { checksum(line+9); continue; } 424 if(!strncmp(line,"team ",5)) { dumpteam(readnum(line+5)); continue; } 425 if(!strncmp(line,"find ",5)) { findpage(readnum(line+5)); continue; } 426 if(!strcmp(line,"teams")) { dumpteams(); continue; } 427 428 if(!strcmp(line,"exit")) break; 429 if(!strcmp(line,"x")) break; 430 if(!strcmp(line,"c")) break; 431 } 432 } 433 434 void DEBUGGER(void) 435 { 436 regs r; 437 k_debugger(&r, 0, 0, 0); 438 } 439 440 #endif