From a249b1e4b8cb1930f1566e0041145f1f83f29907 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Wed, 9 Sep 1992 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1992-09-09 --- boot/boot.c | 7 ++-- boot/boot.h | 3 ++ boot/settime.c | 4 ++- pc/devether.c | 96 ++++++++++++++++++++++++++++++++++++++------------ port/proc.c | 21 ++++++----- 5 files changed, 96 insertions(+), 35 deletions(-) diff --git a/boot/boot.c b/boot/boot.c index 37ebf49ab7eea240efbc6953aeab78fa0ab5db12..19193268bdc1e2a3a5de1238dca89f666cb94105 100644 --- a/boot/boot.c +++ b/boot/boot.c @@ -32,7 +32,7 @@ boot(int argc, char *argv[]) Method *mp; char cmd[64]; char flags[6]; - int islocal; + int islocal, ishybrid; sleep(1000); @@ -76,6 +76,7 @@ boot(int argc, char *argv[]) mp = rootserver(argc ? *argv : 0); (*mp->config)(mp); islocal = strcmp(mp->name, "local") == 0; + ishybrid = strcmp(mp->name, "hybrid") == 0; /* * get/set key or password @@ -88,7 +89,7 @@ boot(int argc, char *argv[]) fd = (*mp->connect)(); if(fd < 0) fatal("can't connect to file server"); - if(!islocal){ + if(!islocal && !ishybrid){ nop(fd); session(fd); if(cfs) @@ -115,7 +116,7 @@ boot(int argc, char *argv[]) * if a local file server exists and it's not * running, start it and mount it onto /n/kfs */ - if(!islocal){ + if(!islocal && !ishybrid){ for(mp = method; mp->name; mp++){ if(strcmp(mp->name, "local") != 0) continue; diff --git a/boot/boot.h b/boot/boot.h index 4943597e68581bee15210404de698c33173acb30..95d569d5f1169ad14d7e232576c5cfa31346a1fb 100644 --- a/boot/boot.h +++ b/boot/boot.h @@ -78,3 +78,6 @@ extern int connectlocal(void); extern void configbri(Method*); extern int authbri(void); extern int connectbri(void); +extern void confighybrid(Method*); +extern int authhybrid(void); +extern int connecthybrid(void); diff --git a/boot/settime.c b/boot/settime.c index 3792e0d05e35b6d1fb9a19f7f5ea237090d24405..f44f216a28f85fb10a34b3c20aa0c39ede2298d7 100644 --- a/boot/settime.c +++ b/boot/settime.c @@ -5,6 +5,8 @@ static long lusertime(char*); +char *timeserver = "#s/boot"; + void settime(int islocal) { @@ -35,7 +37,7 @@ settime(int islocal) /* * set the time from the access time of the root */ - f = open("#s/boot", ORDWR); + f = open(timeserver, ORDWR); if(f < 0) return; if(mount(f, "/n/boot", MREPL, "", sauth) < 0){ diff --git a/pc/devether.c b/pc/devether.c index 69fff4424297e33cb43e260dc55f33b23dc2750a..a727b770ebaac8b480c8109efcf8315dbdf863a3 100644 --- a/pc/devether.c +++ b/pc/devether.c @@ -13,6 +13,14 @@ typedef struct Type Type; typedef struct Ctlr Ctlr; struct Hw { + void (*reset)(Ctlr*); + void (*init)(Ctlr*); + void (*mode)(Ctlr*, int); + void (*online)(Ctlr*, int); + void (*receive)(Ctlr*); + void (*transmit)(Ctlr*); + void (*intr)(Ureg*); + void (*tweek)(Ctlr*); int addr; /* interface address */ uchar *ram; /* interface shared memory address */ int bt16; /* true if a 16 bit interface */ @@ -21,13 +29,6 @@ struct Hw { uchar tstart; uchar pstart; uchar pstop; - void (*reset)(Ctlr*); - void (*init)(Ctlr*); - void (*mode)(Ctlr*, int); - void (*online)(Ctlr*, int); - void (*receive)(Ctlr*); - void (*transmit)(Ctlr*); - void (*intr)(Ureg*); }; static Hw wd8013; @@ -464,7 +465,8 @@ etherkproc(void *arg) } cp->kproc = 1; for(;;){ - sleep(&cp->rr, isinput, cp); + tsleep(&cp->rr, isinput, cp, 1000); + (*cp->hw->tweek)(cp); /* * process any internal loopback packets @@ -620,7 +622,6 @@ typedef struct { uchar data[256-4]; } Ring; - static void wd8013dumpregs(Hw *hw) { @@ -696,6 +697,7 @@ wd8013reset(Ctlr *cp) hw->size = 8*1024; if(hw->bt16) hw->size <<= 1; + hw->pstart = HOWMANY(sizeof(Etherpkt), 256); hw->pstop = HOWMANY(hw->size, 256); print("ether width %d addr %lux size %d lvl %d\n", hw->bt16?16:8, @@ -704,12 +706,46 @@ print("ether width %d addr %lux size %d lvl %d\n", hw->bt16?16:8, /* enable interface RAM, set interface width */ OUT(hw, msr, MENB|msr); if(hw->bt16) - OUT(hw, laar, laar|L16EN|M16EN); + OUT(hw, laar, laar|L16EN); (*hw->init)(cp); setvec(Int0vec + hw->lvl, hw->intr); } +static void +wd8013tweek(Ctlr *cp) +{ + uchar laar, msr; + Hw *hw = cp->hw; + Buffer *tb; + int s; + + s = splhi(); + msr = IN(hw, msr); + if(msr & MENB){ + splx(s); + return; + } + print("TWEEK\n"); + delay(500); + + /* reset the hardware */ + OUT(hw, msr, MENB|msr); + laar = IN(hw, laar); + if(hw->bt16) + OUT(hw, laar, laar|L16EN); + (*hw->init)(cp); + (*cp->hw->online)(cp, 1); + + /* retransmit the current packet */ + tb = &cp->tb[cp->ti]; + if(tb->owner == Interface){ + tb->busy = 0; + (*cp->hw->transmit)(cp); + } + splx(s); +} + static void dp8390rinit(Ctlr *cp) { @@ -727,7 +763,7 @@ dp8390rinit(Ctlr *cp) * and pointing to Page0. */ static void -wd8013init(Ctlr *cp) +dp8390init(Ctlr *cp) { Hw *hw = cp->hw; int i; @@ -805,7 +841,7 @@ wd8013receive(Ctlr *cp) len = ((p->len1<<8)|p->len0)-4; if(p->next < hw->pstart || p->next >= hw->pstop || len < 60){ print("%d/%d : #%2.2ux #%2.2ux #%2.2ux #%2.2ux\n", next, len, - p->status, p->next, p->len0, p->len1); + p->status, p->next, p->len0, p->len1);/**/ dp8390rinit(cp); break; } @@ -839,16 +875,26 @@ wd8013transmit(Ctlr *cp) Hw *hw; Buffer *tb; int s; + uchar laar; s = splhi(); hw = cp->hw; tb = &cp->tb[cp->ti]; if(tb->busy == 0 && tb->owner == Interface){ + if(hw->bt16){ + OUT(hw, w.imr, 0x0); + laar = IN(hw, laar); + OUT(hw, laar, laar|M16EN); + } memmove(hw->ram, tb->pkt, tb->len); OUT(hw, w.tbcr0, tb->len & 0xFF); OUT(hw, w.tbcr1, (tb->len>>8) & 0xFF); OUT(hw, w.cr, 0x26); /* Page0|RD2|TXP|STA */ tb->busy = 1; + if(hw->bt16 && (laar&M16EN)==0){ + OUT(hw, laar, laar); + OUT(hw, w.imr, 0x1F); + } } splx(s); } @@ -859,8 +905,13 @@ wd8013intr(Ureg *ur) Ctlr *cp = &ctlr[0]; Hw *hw = cp->hw; Buffer *tb; - uchar isr; + uchar isr, laar; + if(hw->bt16){ + laar = IN(hw, laar); + OUT(hw, w.imr, 0x0); + OUT(hw, laar, laar|M16EN); + } USED(ur); while(isr = IN(hw, r.isr)){ OUT(hw, w.isr, isr); @@ -896,22 +947,21 @@ wd8013intr(Ureg *ur) wakeup(&cp->rr); } } + if(hw->bt16){ + OUT(hw, laar, laar); + OUT(hw, w.imr, 0x1F); + } } -static Hw wd8013 = { - 0x360, /* I/O base address */ - 0, - 0, - 0, - 0, - 0, - HOWMANY(sizeof(Etherpkt), 256), - 0, +static Hw wd8013 = +{ wd8013reset, - wd8013init, + dp8390init, wd8013mode, wd8013online, wd8013receive, wd8013transmit, wd8013intr, + wd8013tweek, + 0x360, /* I/O base address */ }; diff --git a/port/proc.c b/port/proc.c index 0e9492b94e1be9319ca42e55fc828e0c6a5a51b0..5efebeed9ef0c844c9c652f514647514c40cb120 100644 --- a/port/proc.c +++ b/port/proc.c @@ -359,6 +359,9 @@ tsleep(Rendez *r, int (*fn)(void*), void *arg, int ms) p->twhen = 0; } +/* + * Expects that only one process can call wakeup for any given Rendez + */ void wakeup(Rendez *r) { @@ -422,14 +425,16 @@ postnote(Proc *p, int dolock, char *n, int flag) if(r = p->r){ /* assign = */ /* wake up; can't call wakeup itself because we're racing with it */ - s = splhi(); - lock(r); - if(p->r==r && r->p==p){ /* check we won the race */ - if(p->state == Wakeme){ - r->p = 0; - p->r = 0; - ready(p); - } + for(;;) { + s = splhi(); + if(canlock(r)) + break; + splx(s); + } + if(p->r==r && r->p==p && p->state==Wakeme){ /* check we won the race */ + r->p = 0; + p->r = 0; + ready(p); } unlock(r); splx(s);