M pc/dat.h => pc/dat.h +1 -0
@@ 195,3 195,4 @@ extern int cpuflag; /* true if this is a CPU */
extern Mach *m;
extern Proc *up;
extern char filaddr[];
+extern ulong crasharea;
M pc/main.c => pc/main.c +8 -9
@@ 31,6 31,7 @@ char filaddr[NAMELEN];
char *confname[MAXCONF];
char *confval[MAXCONF];
int nconf;
+ulong crasharea;
/* memory map */
#define MAXMEG 64
@@ 63,6 64,7 @@ main(void)
chandevreset();
swapinit();
userinit();
+conf.npage0 += CRASHSIZE;
schedinit();
}
@@ 353,7 355,6 @@ confinit(void)
/*
* zero memory to set ECC but skip over the kernel
* do a quick memory test also
- */
if(i != 1){
for(j = 0; j < MB/BY2PG; j += BY2PG){
lp = mapaddr(KZERO|(i*MB+j));
@@ 376,6 377,7 @@ confinit(void)
memset(lp, 0, BY2PG);
}
}
+ */
}
x += 0x3141526;
}
@@ 387,16 389,17 @@ confinit(void)
conf.base0 = ktop;
for(i = 1; mmap[i] == 'x'; i++)
;
- conf.npage0 = (i*MB - ktop)/BY2PG;
+ conf.npage0 = (i*MB - ktop - CRASHSIZE)/BY2PG;
+ crasharea = KZERO|(conf.base0 + conf.npage0*BY2PG);
conf.topofmem = i*MB;
/*
- * bank1 usually goes from the end of BOOTARGS to 640k
+ * bank1 usually goes from the end of BOOTARGS to 640k - crash space
*/
- conf.base1 = (ulong)(BOOTARGS+BOOTARGSLEN);
+ conf.base1 = (ulong)(BOOTARGS + BOOTARGSLEN);
conf.base1 = PGROUND(conf.base1);
conf.base1 = PADDR(conf.base1);
- conf.npage1 = (640*1024-conf.base1)/BY2PG;
+ conf.npage1 = (640*1024 - conf.base1)/BY2PG;
/*
* if there is a hole in memory (due to a shadow BIOS) make the
@@ 568,15 571,11 @@ procrestore(Proc *p)
USED(p);
}
-
/*
* the following functions all are slightly different from
* PC to PC.
*/
-/*
- * reset the i387 chip
- */
void
exit(int ispanic)
{
M pc/mem.h => pc/mem.h +4 -0
@@ 55,6 55,10 @@
#define MACHSIZE 4096
+/*
+ * an area for storing crash info to be picked up later
+ */
+#define CRASHSIZE (KSTACK+BY2PG)
/*
* known 80386 segments (in GDT) and their selectors
M pc/trap.c => pc/trap.c +31 -1
@@ 61,6 61,19 @@ struct
int free;
} halloc;
+/*
+ * somewhere to drop crash info
+ */
+typedef struct
+{
+ ulong magic;
+ void *kbot;
+ void *ksp;
+ char text[NAMELEN];
+ Ureg ureg;
+ uchar kstack[KSTACK];
+} Crashstate;
+
void
sethvec(int v, void (*r)(void), int type, int pri)
{
@@ 340,12 353,20 @@ dumpregs2(Ureg *ur)
void
dumpregs(Ureg *ur)
{
+ Crashstate *cs;
+ extern ulong etext;
ulong *x;
+
x = (ulong*)(ur+1);
dumpregs2(ur);
print(" magic %lux %lux %lux\n", x[0], x[1], x[2]);
print(" ur %lux up %lux\n", ur, up);
+
+ /* save crash info */
+ print("crasharea 0x%lux\n", crasharea);
+ cs = (Crashstate*)crasharea;
+ memmove(&cs->ureg, ur, sizeof(Ureg));
}
void
@@ 354,13 375,14 @@ dumpstack(void)
ulong l, v, i;
extern ulong etext;
int lim;
+ Crashstate *cs;
if(up == 0)
return;
i = 0;
lim = 6;
- for(l=(ulong)&l; l<(ulong)(up->kstack+BY2PG) && lim; l+=4){
+ for(l=(ulong)&l; l<(ulong)(up->kstack+KSTACK) && lim; l+=4){
v = *(ulong*)l;
if(KTZERO < v && v < (ulong)&etext){
print("%lux ", v);
@@ 373,6 395,14 @@ dumpstack(void)
}
}
+ /* save crash info */
+ print("crasharea 0x%lux\n", crasharea);
+ cs = (Crashstate*)crasharea;
+ memmove(cs->kstack, up->kstack, KSTACK);
+ cs->kbot = up->kstack;
+ memmove(cs->text, up->text, NAMELEN);
+ cs->magic = 0xdeaddead;
+ cs->ksp = &l;
}
/*
M port/chan.c => port/chan.c +1 -1
@@ 130,7 130,7 @@ chanfree(Chan *c)
void
close(Chan *c)
{
- if(c == 0 || (c->flag&CFREE))
+ if(c->flag&CFREE)
panic("close");
if(decref(c))
M port/devcons.c => port/devcons.c +3 -0
@@ 214,6 214,9 @@ echo(Rune r, char *buf, int n)
switch(r){
case 0x14:
break; /* pass it on */
+ case 's':
+ dumpstack();
+ break;
case 'x':
xsummary();
ixsummary();