From 920fe64e4f04de28f4e8eead34b2188974505c87 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Fri, 11 Mar 1994 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1994-03-11 --- boot/boot.c | 77 +++++++++++++++++++++++++++++++++++--------------- boot/boot.h | 2 ++ carrera/dat.h | 7 +++++ carrera/fns.h | 10 ++++++- carrera/l.s | 21 +++++++++++++- carrera/trap.c | 5 +++- pc/dat.h | 7 +++++ pc/devvga.c | 33 +++++++++++++++++++++- pc/mem.h | 1 + port/portfns.h | 3 ++ port/proc.c | 26 +++++++++++++++++ port/qio.c | 67 +++++++++++++++++++++++++++++++++++++++++++ 12 files changed, 233 insertions(+), 26 deletions(-) diff --git a/boot/boot.c b/boot/boot.c index 1c1952c8b43a26c6b84742cf07309b537b0b00fe..a3d832da028b99b801da7d0ac839d7e56ea40686 100644 --- a/boot/boot.c +++ b/boot/boot.c @@ -13,6 +13,7 @@ char sys[2*NAMELEN]; char username[NAMELEN]; char bootfile[3*NAMELEN]; char conffile[NAMELEN]; +char reply[64]; int printcol; int mflag; int fflag; @@ -23,6 +24,8 @@ int afd = -1; static void swapproc(void); static void recover(Method*); static Method *rootserver(char*); +char *bargv[6]; +int bargc; void boot(int argc, char *argv[]) @@ -38,6 +41,7 @@ boot(int argc, char *argv[]) open("#c/cons", OREAD); open("#c/cons", OWRITE); open("#c/cons", OWRITE); + bind("#c", "/dev", MAFTER); #ifdef DEBUG print("argc=%d\n", argc); for(fd = 0; fd < argc; fd++) @@ -149,6 +153,29 @@ boot(int argc, char *argv[]) fatal(cmd); } +Method* +findmethod(char *a) +{ + Method *mp; + int i, j; + char *cp; + + i = strlen(a); + cp = strchr(a, '!'); + if(cp) + i = cp - a; + for(mp = method; mp->name; mp++){ + j = strlen(mp->name); + if(j > i) + j = i; + if(strncmp(a, mp->name, j) == 0) + break; + } + if(mp->name) + return mp; + return 0; +} + /* * ask user from whence cometh the root file system */ @@ -156,45 +183,51 @@ Method* rootserver(char *arg) { char prompt[256]; - char reply[64]; Method *mp; char *cp; - int n, j; + int n; int notfirst; + /* make list of methods */ mp = method; n = sprint(prompt, "root is from (%s", mp->name); for(mp++; mp->name; mp++) n += sprint(prompt+n, ", %s", mp->name); sprint(prompt+n, ")"); - strcpy(reply, method->name); - if(arg){ - j = strlen(arg); - for(mp = method; mp->name; mp++) - if(strncmp(arg, mp->name, j) == 0) - break; - if(mp->name) - strcpy(reply, arg); + /* create default reply */ + readfile("#e/bootargs", reply, sizeof(reply)); + if(reply[0] == 0 && arg != 0) + strcpy(reply, arg); + if(reply[0]){ + mp = findmethod(reply); + if(mp == 0) + reply[0] = 0; } + if(reply[0] == 0) + strcpy(reply, method->name); + /* parse replies */ for(notfirst = 0;; notfirst = 1){ if(pflag || notfirst) outin(prompt, reply, sizeof(reply)); - cp = strchr(reply, '!'); - if(cp) - j = cp - reply; - else - j = strlen(reply); - for(mp = method; mp->name; mp++) - if(strncmp(reply, mp->name, j) == 0){ - if(cp) - strcpy(sys, cp+1); - return mp; + mp = findmethod(reply); + if(mp){ + for(cp = reply; *cp; cp++){ + while(*cp && *cp != ' ') + cp++; + while(*cp == ' ') + *cp++ = 0; + if(*cp) + bargv[bargc++] = cp; } - if(mp->name == 0) - continue; + cp = strchr(reply, '!'); + if(cp) + strcpy(sys, cp+1); + return mp; + } } + return 0; /* not reached */ } diff --git a/boot/boot.h b/boot/boot.h index 303ef5337868070113368858c1f2088862b98e72..2ed10df4f0c1c973a217a3b98389f852951d199d 100644 --- a/boot/boot.h +++ b/boot/boot.h @@ -22,6 +22,8 @@ extern char terminal[]; extern char username[NAMELEN]; extern char bootfile[]; extern char conffile[]; +extern int bargc; +extern char *bargv[]; extern int afd; /* libc equivalent */ diff --git a/carrera/dat.h b/carrera/dat.h index cdcefaf6af2264c64f2bbeb24fbb286225d1160a..aa77a899468d896893785c8776c3438397b792fe 100644 --- a/carrera/dat.h +++ b/carrera/dat.h @@ -85,6 +85,8 @@ struct Notsave #include "../port/portdat.h" +#define NCALLBACK 32 + /* First FOUR members offsets known by l.s */ struct Mach { @@ -112,6 +114,11 @@ struct Mach Schedq hiq; Schedq loq; + void (**cbin)(void); + void (**cbout)(void); + void (**cbend)(void); + void (*calls[NCALLBACK])(void); + int pfault; int cs; int syscall; diff --git a/carrera/fns.h b/carrera/fns.h index d7ba3fe4f1e6a03ceb68fa0240ceb44bbe01e032..f4e324b4e6836165ec84f6ae020744388b4652eb 100644 --- a/carrera/fns.h +++ b/carrera/fns.h @@ -125,8 +125,16 @@ ushort nhgets(void*); void ifwrite(void*, Block*); void* ifinit(int); void ifjab(void); -void fiberint(int); ulong ifaddr(void*); +void filiput(Block*); +void fiberint(int); void audiosbintr(void); void audiodmaintr(void); ulong fwblock(void*, void*, ulong); +ulong frblock(void*, void*, ulong); +void ifree(void*); +Block* iallocb(int); +void* ifroute(ulong); +ulong ifunroute(ulong); +void parseip(char*, char*); + diff --git a/carrera/l.s b/carrera/l.s index f10fc59d4423702b3b25657fb7dccb19662aad9a..e3879c2bc48e4f5a86eb50aa00e1b4b6bac255ba 100644 --- a/carrera/l.s +++ b/carrera/l.s @@ -815,7 +815,7 @@ TEXT uvst(SB), $-4 /* uvst(address, src) */ MOVV R5, 0(R1) RET -TEXT fwblock(SB), $-4 /* wblock(void*port, void *block, csum) */ +TEXT fwblock(SB), $-4 /* fwblock(void*port, void *block, csum) */ MOVW 4(FP), R2 MOVW 8(FP), R3 @@ -833,3 +833,22 @@ fwloop: MOVW R3, R1 RET + +TEXT frblock(SB), $-4 /* frblock(void*port, void *block, csum) */ + MOVW 4(FP), R2 + MOVW 8(FP), R3 + + MOVW $64, R4 +frloop: + MOVV 0(R1), R5 + MOVV R5, 0(R2) + ADDU R5, R3 + SRLV $32, R5 + ADDU R5, R3 + + ADD $8, R2 + SUB $1, R4 + BNE R4, frloop + + MOVW R3, R1 + RET diff --git a/carrera/trap.c b/carrera/trap.c index 89ecc5bb26f5a75774a4f2574a8cde7badcf29ba..f0709a46a0e2b2106b5963f0bf191f02330afa93 100644 --- a/carrera/trap.c +++ b/carrera/trap.c @@ -402,7 +402,10 @@ kernfault(Ureg *ur, int code) print("kfault %s badvaddr=0x%lux\n", excname[code], ur->badvaddr); print("UP=0x%lux SR=0x%lux PC=0x%lux R31=%lux SP=0x%lux\n", up, ur->status, ur->pc, ur->r31, ur->sp); - kpteprint(ur); + + dumpregs(ur); + splhi(); + for(;;); panic("kfault"); } diff --git a/pc/dat.h b/pc/dat.h index 79f021e5ce582d77c340f15738d7a9d9c1510d1d..c33980e58220b7d4083c90ba3e3bdc979b8d5c49 100644 --- a/pc/dat.h +++ b/pc/dat.h @@ -113,6 +113,8 @@ struct Notsave * machine dependent definitions not used by ../port/dat.h */ +#define NCALLBACK 32 + struct Mach { int machno; /* physical id of processor */ @@ -126,6 +128,11 @@ struct Mach Schedq hiq; Schedq loq; + void (**cbin)(void); + void (**cbout)(void); + void (**cbend)(void); + void (*calls[NCALLBACK])(void); + int tlbfault; int tlbpurge; int pfault; diff --git a/pc/devvga.c b/pc/devvga.c index 411fe3d32945ddc8d403457ef695c8d550b7f271..2a3bbb3b78f74db04e16e3c21e175ba6984563ec 100644 --- a/pc/devvga.c +++ b/pc/devvga.c @@ -146,11 +146,12 @@ enum Trident, /* Trident 8900 */ Tseng, /* tseng labs te4000 */ Cirrus, /* Cirrus CLGD542X */ + S3, Generic, }; static void nopage(int), tsengpage(int), tridentpage(int), parapage(int); -static void atipage(int), cirruspage(int); +static void atipage(int), cirruspage(int), s3page(int); Vgacard vgachips[] = { @@ -159,6 +160,7 @@ Vgacard vgachips[] = [Trident] { "trident", tridentpage, }, [Tseng] { "tseng", tsengpage, }, [Cirrus] { "cirrus", cirruspage, }, +[S3] { "s3", s3page, }, [Generic] { "generic", nopage, }, { 0, 0, }, }; @@ -963,6 +965,35 @@ parapage(int page) { grout(0x9, page<<4); } +static void +s3page(int page) +{ +#ifdef notdef + uchar crt51; + + /* + * The S3 registers need to be unlocked for this. + * Let's hope they are already: + * crout(0x38, 0x48); + * crout(0x39, 0xA0); + * + * The page is 6 bits, the lower 4 bits in Crt35<3:0>, + * the upper 2 in Crt51<3:2>. + */ + crout(0x35, page & 0x0F); + outb(CRX, 0x51); + crt51 = (0xF3 & inb(CR))|((page & 0x30)>>2); + outb(CR, crt51); +{ +uchar crt35; +outb(CRX, 0x35); +crt35 = inb(CR); +print("page #%ux, crt51=#%ux, crt35=#%ux\n", page, crt51, crt35); +} +#else + crout(0x35, (page<<2) & 0x0f); +#endif /* notdef +} void mousescreenupdate(void) diff --git a/pc/mem.h b/pc/mem.h index db5ab4f333556d5b285a411377d9a40a295c8ba3..0348acd8dcdc0f2267c89e5b202657c4cfdafdb2 100644 --- a/pc/mem.h +++ b/pc/mem.h @@ -8,6 +8,7 @@ #define BI2BY 8 /* bits per byte */ #define BI2WD 32 /* bits per word */ #define BY2WD 4 /* bytes per word */ +#define BY2V 8 /* bytes per double word */ #define BY2PG 4096 /* bytes per page */ #define WD2PG (BY2PG/BY2WD) /* words per page */ #define PGSHIFT 12 /* log(BY2PG) */ diff --git a/port/portfns.h b/port/portfns.h index 34e914da5301040b18018b86994ee6bd4e56e609..c64d810dbaa4c4d433863e9343b7db25e91f4cc5 100644 --- a/port/portfns.h +++ b/port/portfns.h @@ -15,6 +15,8 @@ Page* auxpage(void); void buzz(int, int); void cachedel(Image*, ulong); void cachepage(Page*, Image*); +void callbacks(void); +void newcallback(void (*)(void)); int cangetc(void*); int canlock(Lock*); int canpage(Proc*); @@ -193,6 +195,7 @@ void qinit(void); int qlen(Queue*); void qlock(QLock*); Queue* qopen(int, int, void (*)(void*), void*); +int qpass(Queue*, Block*); int qproduce(Queue*, void*, int); long qread(Queue*, void*, int); void qreopen(Queue*); diff --git a/port/proc.c b/port/proc.c index 4fea4daf981528e63764187080c464f430514c6d..dce1a462f1669d2e4e8c8b2c8cdce15f60bd90f2 100644 --- a/port/proc.c +++ b/port/proc.c @@ -44,6 +44,10 @@ char *statename[] = void schedinit(void) /* never returns */ { + m->cbin = m->calls; + m->cbout = m->calls; + m->cbend = &m->calls[NCALLBACK]; + setlabel(&m->sched); if(up) { m->proc = 0; @@ -87,6 +91,7 @@ sched(void) procsave(up); if(setlabel(&up->sched)) { procrestore(up); + callbacks(); spllo(); return; } @@ -100,6 +105,27 @@ sched(void) gotolabel(&up->sched); } +void +newcallback(void (*func)(void)) +{ + *m->cbin = func; + if(++m->cbin >= m->cbend) + m->cbin = m->calls; +} + +void +callbacks(void) +{ + void (*func)(void); + + while(m->cbin != m->cbout) { + func = *m->cbout; + if(++m->cbout >= m->cbend) + m->cbout = m->calls; + func(); + } +} + int anyready(void) { diff --git a/port/qio.c b/port/qio.c index 3244289500b174b6176a01563da1cc567880d55d..e5dc746f5358121d16af2e716d392736359fd294 100644 --- a/port/qio.c +++ b/port/qio.c @@ -368,6 +368,73 @@ checkb(b, "qconsume 2"); return len; } +int +qpass(Queue *q, Block *b) +{ + int s, i, len; + int dowakeup; + + s = splhi(); + + len = BLEN(b); + + /* sync with qread */ + dowakeup = 0; + lock(q); + + if(q->syncbuf){ + /* synchronous communications, just copy into buffer */ + if(len < q->synclen) + q->synclen = len; + i = q->synclen; + memmove(q->syncbuf, b->rp, i); + q->syncbuf = 0; /* tell reader buffer is full */ + len -= i; + if(len <= 0 || (q->state & Qmsg)){ + unlock(q); + wakeup(&q->rr); + ifree(b); + splx(s); + return i; + } + + /* queue anything that's left */ + dowakeup = 1; + b->rp += i; + } + + /* no waiting receivers, room in buffer? */ + if(q->len >= q->limit){ + unlock(q); + splx(s); + return -1; + } + + /* save in buffer */ + if(q->bfirst) + q->blast->next = b; + else + q->bfirst = b; + q->blast = b; + q->len += len; +checkb(b, "qproduce"); + + if(q->state & Qstarve){ + q->state &= ~Qstarve; + dowakeup = 1; + } + unlock(q); + + if(dowakeup){ + if(q->kick) + (*q->kick)(q->arg); + wakeup(&q->rr); + } + splx(s); + + return len; +} + int qproduce(Queue *q, void *vp, int len) {