From 25d4fd9342a48e45eedeb0858f7996661bafca8d Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Tue, 23 Jul 1991 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1991-07-23 --- gnot/lock.c | 46 ++++++++++++----------------- pc/fault386.c | 3 -- pc/fns.h | 1 + pc/main.c | 36 +++++++++++++++++++++++ pc/mmu.c | 11 +++---- pc/trap.c | 8 ------ pc/vga.c | 29 +++++++++++++++++++ port/chan.c | 12 ++------ port/devcons.c | 3 +- port/devdk.c | 2 +- port/devip.c | 31 -------------------- port/sysproc.c | 36 ++++++++++++++++------- port/tcpoutput.c | 32 +++++++++++++++++++++ power/devhotrod.c | 1 + ss/bbmalloc.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++ ss/clock.c | 2 +- 16 files changed, 228 insertions(+), 98 deletions(-) create mode 100644 pc/vga.c create mode 100644 ss/bbmalloc.c diff --git a/gnot/lock.c b/gnot/lock.c index 43015f402012af5efd300b993eaea055e02b8897..66a3a3874844734e74937026412329122e74c8d4 100644 --- a/gnot/lock.c +++ b/gnot/lock.c @@ -7,55 +7,45 @@ #define PCOFF -1 -/* - * N.B. Ken's compiler generates a TAS instruction for the sequence: - * - * if(l->key >= 0){ - * l->key |= 0x80; - * ... - * - * DO NOT TAKE THE ADDRESS OF l->key or the TAS will disappear. - */ void lock(Lock *l) { - Lock *ll = l; /* do NOT take the address of ll */ int i; /* * Try the fast grab first */ - if(ll->key >= 0){ - ll->key |= 0x80; - ll->pc = ((ulong*)&l)[PCOFF]; + if(tas(&l->key) == 0){ if(u && u->p) u->p->hasspin = 1; + l->pc = ((ulong*)&l)[PCOFF]; return; } - for(i=0; i<10000000; i++) - if(ll->key >= 0){ - ll->key |= 0x80; - ll->pc = ((ulong*)&l)[PCOFF]; + for(i = 0; i < 1000; i++){ + sched(); + if (tas(&l->key) == 0){ if(u && u->p) u->p->hasspin = 1; + l->pc = ((ulong*)&l)[PCOFF]; return; } - ll->key = 0; - print("lock loop %lux pc %lux held by pc %lux\n", l, ((ulong*)&l)[PCOFF], l->pc); + } + i = l->key; + l->key = 0; + + panic("lock loop 0x%lux key 0x%lux pc 0x%lux held by pc 0x%lux\n", l, i, + ((ulong*)&l)[PCOFF], l->pc); } int canlock(Lock *l) { - Lock *ll = l; /* do NOT take the address of ll */ - if(ll->key >= 0){ - ll->key |= 0x80; - ll->pc = ((ulong*)&l)[PCOFF]; - if(u && u->p) - u->p->hasspin = 1; - return 1; - } - return 0; + if(tas(&l->key)) + return 0; + l->pc = ((ulong*)&l)[PCOFF]; + if(u && u->p) + u->p->hasspin = 1; + return 1; } void diff --git a/pc/fault386.c b/pc/fault386.c index 12876bf867ec8b95d3db568ac7f0e9e0039c398e..a2f9fbdbf976aaa8b898f53a473c01b4f2fa04ae 100644 --- a/pc/fault386.c +++ b/pc/fault386.c @@ -16,7 +16,6 @@ fault386(Ureg *ur) int user; int n; int insyscall; - static int times; insyscall = u->p->insyscall; u->p->insyscall = 1; @@ -29,8 +28,6 @@ dumpregs(ur); read = !(ur->ecode & 2); user = (ur->ecode & 4); n = fault(addr, read); -if(++times==3) - panic("3rd time in fault"); if(n < 0){ if(user){ pprint("user %s error addr=0x%lux\n", read?"read":"write", addr); diff --git a/pc/fns.h b/pc/fns.h index 2bcc0b7caef1227555502707c4b515dc0f51a0b8..2d406e5ab87c886906d09de3cc9d8fe0fe6451d9 100644 --- a/pc/fns.h +++ b/pc/fns.h @@ -64,4 +64,5 @@ void systrap(void); void touser(void); void trapinit(void); int tas(Lock*); +void vgainit(void); #define waserror() (u->nerrlab++, setlabel(&u->errlab[u->nerrlab-1])) diff --git a/pc/main.c b/pc/main.c index 707678e3bdedcb1fb0ea5ad5e986753b1d7b7c5a..3c2d6870123aa1b1c6040933cdbd773a54610aae 100644 --- a/pc/main.c +++ b/pc/main.c @@ -19,6 +19,7 @@ main(void) screeninit(); printinit(); mmuinit(); + vgainit(); trapinit(); kbdinit(); clockinit(); @@ -273,3 +274,38 @@ mouseputc(IOQ *q, int c) { return c; } + +/* + * headland hip set for the safari. + * + * serious magic!!! + */ + +enum +{ + Head= 0x92, /* control port */ + Reset= (1<<0), /* reset the 386 */ + A20ena= (1<<1), /* enable address line 20 */ +}; + +/* + * enable address bit 20 + */ +void +a20enable(void) +{ + outb(Head, A20ena); +} + +/* + * reset the chip + */ +void +exit(void) +{ + int i; + + u = 0; + print("exiting\n"); + outb(Head, Reset); +} diff --git a/pc/mmu.c b/pc/mmu.c index 9cc03d3c91c29ea9ce4f27eec48c84e49e111459..4be1a687959cfe92a6cec617dbae7ddd25ba5078 100644 --- a/pc/mmu.c +++ b/pc/mmu.c @@ -178,8 +178,8 @@ mapstack(Proc *p) /* * point top level page table to bottom level ones */ - memmove(toppt, p->mmu, MAXMMU*sizeof(ulong)); - memmove(&toppt[TOPOFF(USTKBTM)], &p->mmu[MAXMMU], MAXSMMU*sizeof(ulong)); + memmove(toppt, p->mmue, MAXMMU*sizeof(ulong)); + memmove(&toppt[TOPOFF(USTKBTM)], &p->mmue[MAXMMU], MAXSMMU*sizeof(ulong)); /* map in u area */ upt[0] = PPN(p->upage->pa) | PTEVALID | PTEKERNEL | PTEWRITE; @@ -216,7 +216,7 @@ putmmu(ulong va, ulong pa, Page *pg) int topoff; ulong *pt; Proc *p; - int i; + int i = 0; print("putmmu %lux %lux\n", va, pa); /**/ if(u==0) @@ -238,18 +238,19 @@ print("putmmu %lux %lux\n", va, pa); /**/ * if bottom level page table missing, allocate one */ pg = p->mmu[i]; +print("toppt[%d] was %lux\n", topoff, toppt[topoff]); if(pg == 0){ pg = p->mmu[i] = newpage(1, 0, 0); p->mmue[i] = PPN(pg->pa) | PTEVALID | PTEUSER | PTEWRITE; toppt[topoff] = p->mmue[i]; -print("toppt[%d] = %lux\n", topoff, toppt[topoff]); +print("toppt[%d] now %lux\n", topoff, toppt[topoff]); } /* * fill in the bottom level page table */ -print("%lux[%d] was %lux\n", pt, BTMOFF(va), pt[BTMOFF(va)]); pt = (ulong*)(p->mmu[i]->pa|KZERO); +print("%lux[%d] was %lux\n", pt, BTMOFF(va), pt[BTMOFF(va)]); pt[BTMOFF(va)] = pa | PTEUSER; print("%lux[%d] now %lux\n", pt, BTMOFF(va), pt[BTMOFF(va)]); diff --git a/pc/trap.c b/pc/trap.c index 0a6300ae762b2eb9f827b1af52ab797778eb9f86..1b0fe2bd42dae6c019366f7bc8d478a348429295 100644 --- a/pc/trap.c +++ b/pc/trap.c @@ -223,8 +223,6 @@ syscall(Ureg *ur) ulong sp; long ret; int i; - static int times; -ulong *z; u->p->insyscall = 1; u->p->pc = ur->pc; @@ -240,11 +238,6 @@ ulong *z; sp = ur->usp; u->nerrlab = 0; ret = -1; -z = (ulong *)sp; -print("syscall %lux %lux %lux %lux\n", *z, *(z+1), *(z+2), *(z+3)); -dumpregs(ur); -if(++times==3) - panic("3rd time in syscall"); if(!waserror()){ if(ax >= sizeof systab/BY2WD){ pprint("bad sys call number %d pc %lux\n", ax, ur->pc); @@ -256,7 +249,6 @@ if(++times==3) ret = (*systab[ax])((ulong*)(sp+BY2WD)); poperror(); } -print("return from syscall\n"); if(u->nerrlab){ print("bad errstack [%d]: %d extra\n", ax, u->nerrlab); for(i = 0; i < NERR; i++) diff --git a/pc/vga.c b/pc/vga.c new file mode 100644 index 0000000000000000000000000000000000000000..38fb39d44810f2cee6f8540ea7ef6c916e99496f --- /dev/null +++ b/pc/vga.c @@ -0,0 +1,29 @@ +#include "u.h" +#include "lib.h" +#include "mem.h" +#include "dat.h" +#include "fns.h" +#include "io.h" + +enum +{ + GRX= 0x3CE, /* index to graphics registers */ + GR= 0x3CF, /* graphics registers 0-8 */ +}; + +/* + * look at VGA registers + */ +void +vgainit(void) +{ + int i; + uchar x; + + for(i = 0; i < 9; i++){ + outb(GRX, i); + x = inb(GR); + print("GR%d == %ux\n", i, x); + } + panic("for the hell of it"); +} diff --git a/port/chan.c b/port/chan.c index 94432d96a639732de299402d5f0c84cc64d29d78..49bf132de0d3fb57cbd5bfb23217dde58bbc3117 100644 --- a/port/chan.c +++ b/port/chan.c @@ -34,17 +34,9 @@ decref(Ref *r) lock(r); x = --r->ref; unlock(r); - if(x < 0) { - if(u) { - print("%d: %s %lux %lux\n", u->p->pid, u->p->text, *(ulong*)((Ureg*)UREGADDR)->pc, r); - for(i = 0; i < NSEG; i++) { - s = u->p->seg[i]; - if(s) - print("%d: %lux %lux %lux", i, s, s->base, s->top); - } - } + if(x < 0) panic("decref"); - } + return x; } diff --git a/port/devcons.c b/port/devcons.c index 580f1dd8246b957ad7db71f811dc3dc96558906a..9943a8de10b51e1eede1db99a06feeae193e0edd 100644 --- a/port/devcons.c +++ b/port/devcons.c @@ -11,7 +11,7 @@ struct { IOQ; /* lock to klogputs */ QLock; /* qlock to getc */ -} klogq; +}klogq; IOQ lineq; /* lock to getc; interrupt putc's */ IOQ printq; @@ -141,6 +141,7 @@ panic(char *fmt, ...) char buf[PRINTSIZE]; int n; + print("panic: %lux m=%lux\n", &fmt, m); strcpy(buf, "panic: "); n = doprint(buf+7, buf+sizeof(buf), fmt, (&fmt+1)) - buf; buf[n] = '\n'; diff --git a/port/devdk.c b/port/devdk.c index 9094504b8a82507e39caa72b409a5904dcdc748f..e2f5872e9b6e1901eb9f896fe999be762c8167b3 100644 --- a/port/devdk.c +++ b/port/devdk.c @@ -1464,7 +1464,7 @@ dkcsckproc(void *a) break; case T_SRV: /* ignore it, it's useless */ - print("dksrvmesg(%d)\n", line); +/* print("dksrvmesg(%d)\n", line); /**/ break; case T_RESTART: /* datakit reboot */ diff --git a/port/devip.c b/port/devip.c index 8faa1c89b796fee4c039118030b6a5188b9d38bb..b212e233d8c7b18bbc5020654fd5c3188bc49d50 100644 --- a/port/devip.c +++ b/port/devip.c @@ -708,37 +708,6 @@ tcpstclose(Queue *q) } } -/* - * Network byte order functions - */ - -void -hnputs(uchar *ptr, ushort val) -{ - ptr[0] = val>>8; - ptr[1] = val; -} - -void -hnputl(uchar *ptr, ulong val) -{ - ptr[0] = val>>24; - ptr[1] = val>>16; - ptr[2] = val>>8; - ptr[3] = val; -} - -ulong -nhgetl(uchar *ptr) -{ - return ((ptr[0]<<24) | (ptr[1]<<16) | (ptr[2]<<8) | ptr[3]); -} - -ushort -nhgets(uchar *ptr) -{ - return ((ptr[0]<<8) | ptr[1]); -} /* * ptcl_csum - protcol cecksum routine diff --git a/port/sysproc.c b/port/sysproc.c index 9241ecebdcad4a537b20ad75ef562ceac8b53cbe..55edf1fb7051d7c47f181c35d4f8e67d8e27d3cf 100644 --- a/port/sysproc.c +++ b/port/sysproc.c @@ -96,6 +96,15 @@ sysfork(ulong *arg) return pid; } +static ulong +l2be(long l) +{ + uchar *cp; + + cp = (uchar*)&l; + return (cp[0]<<24) | (cp[1]<<16) | (cp[2]<<8) | cp[3]; +} + long sysexec(ulong *arg) { @@ -114,6 +123,7 @@ sysexec(ulong *arg) char line[sizeof(Exec)]; Fgrp *f; Image *img; + ulong magic, text, entry, data, bss; p = u->p; validaddr(arg[0], 1, 0); @@ -132,10 +142,13 @@ sysexec(ulong *arg) if(n < 2) Err: error(Ebadexec); - if(n==sizeof(Exec) && exec.magic==AOUT_MAGIC){ - if((exec.text&KZERO) - || (ulong)exec.entry < UTZERO+sizeof(Exec) - || (ulong)exec.entry >= UTZERO+sizeof(Exec)+exec.text) + magic = l2be(exec.magic); + text = l2be(exec.text); + entry = l2be(exec.entry); + if(n==sizeof(Exec) && magic==AOUT_MAGIC){ + if((text&KZERO) + || entry < UTZERO+sizeof(Exec) + || entry >= UTZERO+sizeof(Exec)+text) goto Err; goto Binary; } @@ -165,9 +178,11 @@ sysexec(ulong *arg) Binary: poperror(); - t = (UTZERO+sizeof(Exec)+exec.text+(BY2PG-1)) & ~(BY2PG-1); - d = (t + exec.data + (BY2PG-1)) & ~(BY2PG-1); - bssend = t + exec.data + exec.bss; + data = l2be(exec.data); + bss = l2be(exec.bss); + t = (UTZERO+sizeof(Exec)+text+(BY2PG-1)) & ~(BY2PG-1); + d = (t + data + (BY2PG-1)) & ~(BY2PG-1); + bssend = t + data + bss; b = (bssend + (BY2PG-1)) & ~(BY2PG-1); if((t|d|b) & KZERO) error(Ebadexec); @@ -254,7 +269,7 @@ sysexec(ulong *arg) p->seg[TSEG] = ts; ts->flushme = 1; ts->fstart = 0; - ts->flen = sizeof(Exec)+exec.text; + ts->flen = sizeof(Exec)+text; /* Data. Shared. */ s = newseg(SG_DATA, t, (d-t)>>PGSHIFT); @@ -264,7 +279,7 @@ sysexec(ulong *arg) incref(img); s->image = img; s->fstart = ts->fstart+ts->flen; - s->flen = exec.data; + s->flen = data; /* BSS. Zero fill on demand */ p->seg[BSEG] = newseg(SG_BSS, d, (b-d)>>PGSHIFT); @@ -288,7 +303,7 @@ sysexec(ulong *arg) */ flushmmu(); clearmmucache(); - execpc(exec.entry); + execpc(entry); sp = (ulong*)(USTKTOP - ssize); *--sp = nargs; ((Ureg*)UREGADDR)->usp = (ulong)sp; @@ -488,6 +503,7 @@ syssegdetach(ulong *arg) int i; Segment *s; + s = 0; for(i = 0; i < NSEG; i++) if(s = u->p->seg[i]) { qlock(&s->lk); diff --git a/port/tcpoutput.c b/port/tcpoutput.c index 57fe97eb3c25e527cc6cb600be1467d116c3aba8..f433d69f435ed9c4419b9e1e424a7d8907c7cb87 100644 --- a/port/tcpoutput.c +++ b/port/tcpoutput.c @@ -282,3 +282,35 @@ tcprcvwin(Ipconv *s) else tcb->rcv.wnd = Streamhi; } + +/* + * Network byte order functions + */ + +void +hnputs(uchar *ptr, ushort val) +{ + ptr[0] = val>>8; + ptr[1] = val; +} + +void +hnputl(uchar *ptr, ulong val) +{ + ptr[0] = val>>24; + ptr[1] = val>>16; + ptr[2] = val>>8; + ptr[3] = val; +} + +ulong +nhgetl(uchar *ptr) +{ + return ((ptr[0]<<24) | (ptr[1]<<16) | (ptr[2]<<8) | ptr[3]); +} + +ushort +nhgets(uchar *ptr) +{ + return ((ptr[0]<<8) | ptr[1]); +} diff --git a/power/devhotrod.c b/power/devhotrod.c index 51af70930fcfb4c5f6fc355fa7b8a2a742889df9..e2debd461c5fe49ba9befa5537b8652a784e3da3 100644 --- a/power/devhotrod.c +++ b/power/devhotrod.c @@ -13,6 +13,7 @@ /* * If defined, ENABMEMTEST causes memory test to be run at device open */ +#define ENABMEMTEST #ifdef ENABMEMTEST void mem(Hot*, ulong*, ulong); #define NTESTBUF 256 diff --git a/ss/bbmalloc.c b/ss/bbmalloc.c new file mode 100644 index 0000000000000000000000000000000000000000..c9eed4fe01c8a16304020c82e9e7112e57d5f632 --- /dev/null +++ b/ss/bbmalloc.c @@ -0,0 +1,73 @@ +#include "u.h" +#include "lib.h" +#include "mem.h" +#include "dat.h" +#include "fns.h" +#include "io.h" + +/* + * Allocate memory for use in kernel bitblts. + * The allocated memory must have a flushed instruction + * cache, and the data cache must be flushed by bbdflush(). + * To avoid the need for frequent cache flushes, the memory + * is allocated out of an arena, and the i-cache is only + * flushed when it has to be reused. By returning an + * address in non-cached space, the need for flushing the + * d-cache is avoided. + * + * Currently, the only kernel users of bitblt are devbit, + * print, and the cursor stuff in devbit. The cursor + * can get drawn at clock interrupt time, so it might need + * to bbmalloc while another bitblt is going on. + * + * This code will have to be interlocked if we ever get + * a multiprocessor with a bitmapped display. + */ + +/* a 0->3 bitblt can take 900 words */ +enum { + nbbarena=8192 /* number of words in an arena */ +}; + +static ulong bbarena[nbbarena]; +static ulong *bbcur = bbarena; +static ulong *bblast = 0; + +void * +bbmalloc(int nbytes) +{ + int nw; + int s; + ulong *ans; + + nw = nbytes/sizeof(long); + s = splhi(); + if(bbcur + nw > &bbarena[nbbarena]) + ans = bbarena; + else + ans = bbcur; + bbcur = ans + nw; + splx(s); +/* + if(ans == bbarena) + icflush(ans, sizeof(bbarena)); +*/ + bblast = ans; + ans = (void *)ans; + return ans; +} + +void +bbfree(void *p, int n) +{ + ulong *up; + + if(p == bblast) + bbcur = (ulong *)(((char *)bblast) + n); +} + +void * +bbdflush(void *p, int n) +{ + return p; +} diff --git a/ss/clock.c b/ss/clock.c index fb44f8735a3e421d35990877dcffaffac7c5bb85..ba59e2baf976a303c250259210e8719d7a1a7f6b 100644 --- a/ss/clock.c +++ b/ss/clock.c @@ -60,7 +60,7 @@ clock(Ureg *ur) if(anyready()) sched(); if((ur->psr&PSRPSUPER) == 0){ - *(ulong*)(USTKTOP-BY2WD) += TK2MS(1); +/* *(ulong*)(USTKTOP-BY2WD) += TK2MS(1); /**/ if(u->nnote) notify(ur); }