From 841f1110dd6180f69bfb19a1a22d12d52660dc04 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Sun, 14 Aug 1994 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1994-08-14 --- pc/dat.h | 1 - pc/main.c | 105 ++++++++++++++++++++++++++++++++----------------- pc/trap.c | 4 ++ port/devproc.c | 10 +++++ port/portdat.h | 3 ++ 5 files changed, 86 insertions(+), 37 deletions(-) diff --git a/pc/dat.h b/pc/dat.h index 7c18da9cd489f8f750343770fa3c1e57b229bd02..0ccf03e826f138c9a438fd3f7165e14386f03ef3 100644 --- a/pc/dat.h +++ b/pc/dat.h @@ -195,4 +195,3 @@ extern int cpuflag; /* true if this is a CPU */ extern Mach *m; extern Proc *up; extern char filaddr[]; -extern ulong crasharea; diff --git a/pc/main.c b/pc/main.c index adf43b795de4321f879d011bb605e9e2177c6579..e99b2f1e9c2a62c2a7c11c5611d3200e2928718d 100644 --- a/pc/main.c +++ b/pc/main.c @@ -31,7 +31,6 @@ char filaddr[NAMELEN]; char *confname[MAXCONF]; char *confval[MAXCONF]; int nconf; -ulong crasharea; /* memory map */ #define MAXMEG 64 @@ -64,7 +63,6 @@ main(void) chandevreset(); swapinit(); userinit(); -conf.npage0 += CRASHSIZE; schedinit(); } @@ -282,13 +280,48 @@ getconf(char *name) return 0; } +/* + * zero memory to set ECC. + * do a quick memory test also. + * + * if any part of a meg is missing/broken, drop the whole meg. + */ +int +memclrtest(int meg, int len, long seed) +{ + int j, n; + long y; + long *lp; + + for(j = 0; j < len; j += BY2PG){ + lp = mapaddr(KZERO|(meg*MB+j)); + for(n = 0; n < BY2PG/BY2WD; n++) + lp[n] = seed + n; + } + for(j = 0; j < len; j += BY2PG){ + lp = mapaddr(KZERO|(meg*MB+j)); + for(n = 0; n < BY2PG/(2*BY2WD); n++){ + y = lp[n]; + lp[n] = ~lp[n^((BY2PG/BY2WD)-1)]; + lp[n^((BY2PG/BY2WD)-1)] = ~y; + } + } + for(j = 0; j < len; j += BY2PG){ + lp = mapaddr(KZERO|(meg*MB+j)); + for(n = 0; n < BY2PG/BY2WD; n++) + if(lp[n] != ~(seed + (n^((BY2PG/BY2WD)-1)))) + return -1; + memset(lp, 0, BY2PG); + } + return 0; +} + void confinit(void) { - long x, y, i, j, n; + long x, i, j, n; int pcnt; ulong ktop; - long *lp; char *cp; char *line[MAXCONF]; extern int defmaxmsg; @@ -320,11 +353,11 @@ confinit(void) if(i < defmaxmsg && i >=128) defmaxmsg = i; } - /* HACK: where should this come from? */ if(strcmp(confname[nconf], "filaddr") == 0) strcpy(filaddr, confval[nconf]); nconf++; } + /* * size memory above 1 meg. Kernel sits at 1 meg. We * only recognize MB size chunks. @@ -350,37 +383,30 @@ confinit(void) /* * check for correct value */ - if(*mapaddr(KZERO|(i*MB)) == x && *mapaddr(KZERO|((i+1)*MB-BY2WD)) == x){ + if(*mapaddr(KZERO|(i*MB)) == x && *mapaddr(KZERO|((i+1)*MB-BY2WD)) == x) mmap[i] = 'x'; - /* - * 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)); - for(n = 0; n < BY2PG/BY2WD; n++) - lp[n] = x + n; - } - for(j = 0; j < MB/BY2PG; j += BY2PG){ - lp = mapaddr(KZERO|(i*MB+j)); - for(n = 0; n < BY2PG/(2*BY2WD); n++){ - y = lp[n]; - lp[n] = ~lp[n^((BY2PG/BY2WD)-1)]; - lp[n^((BY2PG/BY2WD)-1)] = ~y; - } - } - for(j = 0; j < MB/BY2PG; j += BY2PG){ - lp = mapaddr(KZERO|(i*MB+j)); - for(n = 0; n < BY2PG/BY2WD; n++) - if(lp[n] != ~(x + (n^((BY2PG/BY2WD)-1)))) - mmap[i] = ' '; - memset(lp, 0, BY2PG); - } - } - */ + x += 0x3141526; + } + + /* + * zero and clear all except first 2 meg and crash area. + * put crash area at high end of memory. + */ + x = 0x12345678; + for(i = MAXMEG; i > 1; i--){ + if(mmap[i] != 'x') + continue; + j = MB; + if(crasharea == 0){ + crasharea = i*MB - CRASHSIZE; + crashend = crasharea + CRASHSIZE; + j = MB - CRASHSIZE; } + if(memclrtest(i, j, x) < 0) + mmap[i] = ' '; x += 0x3141526; } + /* * bank0 usually goes from the end of kernel bss to the end of memory */ @@ -389,12 +415,13 @@ confinit(void) conf.base0 = ktop; for(i = 1; mmap[i] == 'x'; i++) ; - conf.npage0 = (i*MB - ktop - CRASHSIZE)/BY2PG; - crasharea = KZERO|(conf.base0 + conf.npage0*BY2PG); + conf.npage0 = (i*MB - ktop)/BY2PG; conf.topofmem = i*MB; + if(crasharea < conf.base0 + BY2PG*conf.npage0) + conf.npage0 -= PGROUND(CRASHSIZE)/BY2PG; /* - * bank1 usually goes from the end of BOOTARGS to 640k - crash space + * bank1 usually goes from the end of BOOTARGS to 640k */ conf.base1 = (ulong)(BOOTARGS + BOOTARGSLEN); conf.base1 = PGROUND(conf.base1); @@ -402,7 +429,7 @@ confinit(void) conf.npage1 = (640*1024 - conf.base1)/BY2PG; /* - * if there is a hole in memory (due to a shadow BIOS) make the + * if there is a hole in memory (e.g. due to a shadow BIOS) make the * memory after the hole be bank 1. The memory from 0 to 640k * is lost. */ @@ -413,9 +440,15 @@ confinit(void) ; conf.npage1 = (j - i)*MB/BY2PG; conf.topofmem = j*MB; + if(crasharea < conf.base1 + BY2PG*conf.npage1) + conf.npage1 -= PGROUND(CRASHSIZE)/BY2PG; break; } + /* make crasharea a virtual address */ + crasharea |= KZERO; + crashend |= KZERO; + conf.npage = conf.npage0 + conf.npage1; conf.ldepth = 0; if(pcnt < 10) diff --git a/pc/trap.c b/pc/trap.c index 14bd520c4df44e25d0e28fb6c45350e6df685a95..4c1d05ecc89365eae53bd78d6e9caeec4e1f2cef 100644 --- a/pc/trap.c +++ b/pc/trap.c @@ -364,6 +364,8 @@ dumpregs(Ureg *ur) print(" ur %lux up %lux\n", ur, up); /* save crash info */ + if(crasharea == 0) + return; print("crasharea 0x%lux\n", crasharea); cs = (Crashstate*)crasharea; memmove(&cs->ureg, ur, sizeof(Ureg)); @@ -396,6 +398,8 @@ dumpstack(void) } /* save crash info */ + if(crasharea == 0) + return; print("crasharea 0x%lux\n", crasharea); cs = (Crashstate*)crasharea; memmove(cs->kstack, up->kstack, KSTACK); diff --git a/port/devproc.c b/port/devproc.c index ab5855016514f4d493b856bbcf5023ae59ad8839..d17d8a94b7f2a40f2df3136d11dbc5f0b5e1d9ff 100644 --- a/port/devproc.c +++ b/port/devproc.c @@ -49,6 +49,10 @@ Dirtab procdir[] = /* Segment type from portdat.h */ char *sname[]={ "Text", "Data", "Bss", "Stack", "Shared", "Phys", "Shdata" }; +/* where to put crash information when memory isn't wiped */ +ulong crasharea; +ulong crashend; + /* * Qids are, in path: * 4 bits of file type (qids above) @@ -314,6 +318,12 @@ procread(Chan *c, void *va, long n, ulong offset) memmove(a, (char*)offset, n); return n; } + if(offset >= crasharea && offset < crashend){ + if(offset+n > crashend) + n = crashend - offset; + memmove(a, (char*)offset, n); + return n; + } error(Ebadarg); case Qnote: diff --git a/port/portdat.h b/port/portdat.h index 91fa531a43ac1185bfea149c6ef9041edef282e5..99697c75369f806534ee98b4667c8b26572dcc85 100644 --- a/port/portdat.h +++ b/port/portdat.h @@ -697,5 +697,8 @@ enum extern int mouseshifted; extern int mousetype; extern int mouseswap; + extern int nsyscall; extern Physseg physseg[]; +extern ulong crasharea; +extern ulong crashend;