openblt

a hobby OS from the late 90s
git clone http://frotz.net/git/openblt.git
Log | Files | Refs | LICENSE

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