From 069ed6746a216e075e0b8b620ced93b4c4b07066 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Sat, 1 May 1993 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1993-05-01 --- boot/boot.c | 144 ++++++- boot/boot.h | 3 +- boot/doauthenticate.c | 23 +- boot/key.c | 11 +- boot/local.c | 20 +- boot/settime.c | 3 +- gnot/bbmalloc.c | 85 ---- gnot/clock.c | 60 --- gnot/dat.h | 177 -------- gnot/devduart.c | 762 ---------------------------------- gnot/devhifi.c | 765 ---------------------------------- gnot/devincon.c | 925 ------------------------------------------ gnot/devisdn.c | 763 ---------------------------------- gnot/devlbp.c | 805 ------------------------------------ gnot/devport.c | 262 ------------ gnot/disk.c | 55 --- gnot/fault68020.c | 104 ----- gnot/fns.h | 55 --- gnot/hifi.h | 106 ----- gnot/io.h | 58 --- gnot/isdn.h | 139 ------- gnot/l.s | 373 ----------------- gnot/main.c | 416 ------------------- gnot/malloc.h | 15 - gnot/mem.h | 115 ------ gnot/mmu.c | 157 ------- gnot/screen.c | 166 -------- gnot/screen.h | 8 - gnot/scsi.c | 309 -------------- gnot/scsibuf.c | 63 --- gnot/scsisubs.s | 60 --- gnot/segment.h | 10 - gnot/trap.c | 394 ------------------ gnot/u.h | 17 - gnot/unite.h | 120 ------ gnot/vec.s | 268 ------------ pc/inconsubs.s | 52 --- port/alarm.c | 21 +- port/alloc.c | 39 +- port/auth.c | 168 +++----- port/chan.c | 276 ++++++++----- port/dev.c | 54 ++- port/devarp.c | 15 +- port/devbit.c | 128 +++--- port/devconc.c | 491 ---------------------- port/devcons.c | 35 +- port/devdk.c | 6 +- port/devdup.c | 4 +- port/devenv.c | 22 +- port/devip.c | 19 +- port/devkprof.c | 10 +- port/devlance.c | 4 +- port/devmnt.c | 359 ++++++++++++---- port/devmux.c | 668 ------------------------------ port/devpipe.c | 4 +- port/devproc.c | 197 ++++----- port/devroot.c | 99 ++++- port/devscc.c | 35 +- port/devscsi.c | 68 +--- port/devsrv.c | 28 +- port/error.h | 1 + port/fault.c | 55 ++- port/ipdat.h | 44 +- port/lib.h | 13 +- port/net.c | 35 +- port/page.c | 22 +- port/pgrp.c | 22 +- port/portdat.h | 233 +++++++---- port/portfns.h | 55 ++- port/proc.c | 412 ++++++++----------- port/qlock.c | 8 +- port/segment.c | 28 +- port/stasync.c | 1 - port/stfcall.c | 23 +- port/stil.c | 11 +- port/stip.c | 8 +- port/stlapd.c | 813 ------------------------------------- port/streboot.c | 2 +- port/sturp.c | 481 +++++++++++----------- port/swap.c | 6 +- port/sysfile.c | 47 ++- port/sysproc.c | 252 ++++++------ port/taslock.c | 6 - port/tcpinput.c | 49 +-- port/tcpoutput.c | 11 +- power/clock.c | 110 +++-- power/conf.h | 4 + power/dat.h | 66 +-- power/devcyc.c | 25 +- power/devduart.c | 7 +- power/devrtc.c | 4 +- power/faultmips.c | 36 +- power/fns.h | 6 +- power/fptrap.c | 43 +- power/io.h | 8 +- power/l.s | 104 ++--- power/lock.c | 4 +- power/main.c | 77 ++-- power/mem.h | 19 +- power/mmu.c | 36 +- power/trap.c | 309 +++++++------- ss/arp.h | 40 -- ss/bbmalloc.c | 54 --- ss/clock.c | 79 ---- ss/compile.c | 185 --------- ss/dat.h | 217 ---------- ss/devrtc.c | 378 ----------------- ss/faultsparc.c | 88 ---- ss/fns.h | 91 ----- ss/fptrap.c | 252 ------------ ss/io.h | 150 ------- ss/l.s | 520 ------------------------ ss/main.c | 536 ------------------------ ss/mem.h | 126 ------ ss/mmu.c | 676 ------------------------------ ss/rom.h | 57 --- ss/screen.c | 549 ------------------------- ss/screen.h | 8 - ss/scsi.c | 326 --------------- ss/scsibuf.c | 63 --- ss/segment.h | 10 - ss/stream.h | 5 - ss/trap.c | 626 ---------------------------- ss/u.h | 18 - 124 files changed, 2408 insertions(+), 16760 deletions(-) delete mode 100644 gnot/bbmalloc.c delete mode 100644 gnot/clock.c delete mode 100644 gnot/dat.h delete mode 100644 gnot/devduart.c delete mode 100644 gnot/devhifi.c delete mode 100644 gnot/devincon.c delete mode 100644 gnot/devisdn.c delete mode 100644 gnot/devlbp.c delete mode 100644 gnot/devport.c delete mode 100644 gnot/disk.c delete mode 100644 gnot/fault68020.c delete mode 100644 gnot/fns.h delete mode 100644 gnot/hifi.h delete mode 100644 gnot/io.h delete mode 100644 gnot/isdn.h delete mode 100644 gnot/l.s delete mode 100644 gnot/main.c delete mode 100644 gnot/malloc.h delete mode 100644 gnot/mem.h delete mode 100644 gnot/mmu.c delete mode 100644 gnot/screen.c delete mode 100644 gnot/screen.h delete mode 100644 gnot/scsi.c delete mode 100644 gnot/scsibuf.c delete mode 100644 gnot/scsisubs.s delete mode 100644 gnot/segment.h delete mode 100644 gnot/trap.c delete mode 100644 gnot/u.h delete mode 100644 gnot/unite.h delete mode 100644 gnot/vec.s delete mode 100644 pc/inconsubs.s delete mode 100644 port/devconc.c delete mode 100644 port/devmux.c delete mode 100644 port/stlapd.c delete mode 100644 ss/arp.h delete mode 100644 ss/bbmalloc.c delete mode 100644 ss/clock.c delete mode 100644 ss/compile.c delete mode 100644 ss/dat.h delete mode 100644 ss/devrtc.c delete mode 100644 ss/faultsparc.c delete mode 100644 ss/fns.h delete mode 100644 ss/fptrap.c delete mode 100644 ss/io.h delete mode 100644 ss/l.s delete mode 100644 ss/main.c delete mode 100644 ss/mem.h delete mode 100644 ss/mmu.c delete mode 100644 ss/rom.h delete mode 100644 ss/screen.c delete mode 100644 ss/screen.h delete mode 100644 ss/scsi.c delete mode 100644 ss/scsibuf.c delete mode 100644 ss/segment.h delete mode 100644 ss/stream.h delete mode 100644 ss/trap.c delete mode 100644 ss/u.h diff --git a/boot/boot.c b/boot/boot.c index 9be8af01b07829fccb84151a23e59779ff3385a7..59c5ad7a11976e07f875c3f50a03cf2fb9c4d1a8 100644 --- a/boot/boot.c +++ b/boot/boot.c @@ -1,29 +1,27 @@ #include #include #include +#include #include "../boot/boot.h" -#define DEFSYS "bootes" typedef struct Net Net; typedef struct Flavor Flavor; -int printcol; - char cputype[NAMELEN]; char terminal[NAMELEN]; char sys[2*NAMELEN]; char username[NAMELEN]; char bootfile[3*NAMELEN]; char conffile[NAMELEN]; - -int mflag; -int fflag; -int kflag; -int aflag; -int pflag; -int afd = -1; - +int printcol; +int mflag; +int fflag; +int kflag; +int aflag; +int pflag; +int afd = -1; static void swapproc(void); +static void recover(Method*); static Method *rootserver(char*); void @@ -87,12 +85,22 @@ boot(int argc, char *argv[]) */ (*pword)(islocal, mp); + switch(rfork(RFPROC|RFNAMEG|RFFDG)) { + case -1: + print("failed to start recover: %r\n"); + break; + case 0: + recover(mp); + break; + } + /* * connect to the root file system */ fd = (*mp->connect)(); if(fd < 0) fatal("can't connect to file server"); + nop(fd); if(!islocal && !ishybrid){ if(cfs) fd = (*cfs)(fd); @@ -132,7 +140,6 @@ boot(int argc, char *argv[]) settime(islocal); close(afd); swapproc(); - remove("#e/password"); sprint(cmd, "/%s/init", cputype); sprint(flags, "-%s%s%s", cpuflag ? "c" : "t", mflag ? "m" : "", aflag ? "a" : ""); @@ -183,6 +190,44 @@ rootserver(char *arg) return 0; /* not reached */ } +int +nop(int fd) +{ + int n; + Fcall hdr; + char buf[128]; + + print("boot: nop..."); + hdr.type = Tnop; + hdr.tag = NOTAG; + n = convS2M(&hdr, buf); + if(write(fd, buf, n) != n){ + fatal("write nop"); + return 0; + } +reread: + n = read(fd, buf, sizeof buf); + if(n <= 0){ + fatal("read nop"); + return 0; + } + if(n == 2) + goto reread; + if(convM2S(buf, &hdr, n) == 0) { + fatal("format nop"); + return 0; + } + if(hdr.type != Rnop){ + fatal("not Rnop"); + return 0; + } + if(hdr.tag != NOTAG){ + fatal("tag not NOTAG"); + return 0; + } + return 1; +} + static void swapproc(void) { @@ -195,4 +240,79 @@ swapproc(void) } if(write(fd, "start", 5) <= 0) warning("starting swap kproc"); + close(fd); +} + +void +reattach(int rec, Method *amp, char *buf) +{ + char *mp; + int fd, n, sv[2]; + char tmp[64], *p; + + mp = strchr(buf, ' '); + if(mp == 0) + goto fail; + *mp++ = '\0'; + + p = strrchr(buf, '/'); + if(p == 0) + goto fail; + *p = '\0'; + + sprint(tmp, "%s/remote", buf); + fd = open(tmp, OREAD); + if(fd < 0) + goto fail; + n = read(fd, tmp, sizeof(tmp)); + if(n < 0) + goto fail; + close(fd); + tmp[n-1] = '\0'; + + print("boot: Service %s down, wait...\n", tmp); + + p = strrchr(buf, '/'); + if(p == 0) + goto fail; + *p = '\0'; + + while(plumb(buf, tmp, sv, 0) < 0) + sleep(30); + + nop(sv[1]); + doauthenticate(sv[1], amp); + + print("boot: Service %s Ok\n", tmp); + + n = sprint(tmp, "%d %s", sv[1], mp); + if(write(rec, tmp, n) < 0) { + errstr(tmp); + print("write recover: %s\n", tmp); + } + exits(0); +fail: + print("recover fail: %s\n", buf); + exits(0); +} + +void +recover(Method *mp) +{ + int fd, n; + char buf[256]; + + fd = open("#/./recover", ORDWR); + if(fd < 0) + exits(0); + + for(;;) { + n = read(fd, buf, sizeof(buf)); + if(n < 0) + exits(0); + buf[n] = '\0'; + + if(fork() == 0) + reattach(fd, mp, buf); + } } diff --git a/boot/boot.h b/boot/boot.h index 443be55b72de3d4c5606c84186f49c387839d4db..303ef5337868070113368858c1f2088862b98e72 100644 --- a/boot/boot.h +++ b/boot/boot.h @@ -34,13 +34,12 @@ extern void getconffile(char*, char*); extern void getpasswd(char*, int); extern void key(int, Method*); extern void newkernel(void); -extern void nop(int); +extern int nop(int); extern int outin(char*, char*, int); extern int plumb(char*, char*, int*, char*); extern int readfile(char*, char*, int); extern int readn(int, char*, int); extern int sendmsg(int, char*); -extern void session(int); extern void setenv(char*, char*); extern void settime(int); extern void srvcreate(char*, int); diff --git a/boot/doauthenticate.c b/boot/doauthenticate.c index f2a2bde9d9e0ed1e197eab453dad89dd9db91ffd..ba549ddf200f73dbc890ac2a7f76bfaf8b727a92 100644 --- a/boot/doauthenticate.c +++ b/boot/doauthenticate.c @@ -24,29 +24,36 @@ fromauth(Method *mp, char *trbuf, char *tbuf) { char t; char *msg; - static char error[ERRLEN]; + static char error[2*ERRLEN]; if(afd < 0){ if(mp->auth == 0) fatal("no method for accessing auth server"); afd = (*mp->auth)(); - if(afd < 0) - return ccmsg; + if(afd < 0) { + sprint(error, "%s: %r", ccmsg); + return error; + } } if(write(afd, trbuf, TICKREQLEN) < 0 || read(afd, &t, 1) != 1){ close(afd); afd = -1; - return pbmsg; + sprint(error, "%s: %r", pbmsg); + return error; } switch(t){ case AuthOK: msg = 0; - if(readn(afd, tbuf, 2*TICKETLEN) < 0) - msg = pbmsg; + if(readn(afd, tbuf, 2*TICKETLEN) < 0) { + sprint(error, "%s: %r", pbmsg); + msg = error; + } break; case AuthErr: - if(readn(afd, error, ERRLEN) < 0) - msg = pbmsg; + if(readn(afd, error, ERRLEN) < 0) { + sprint(error, "%s: %r", pbmsg); + msg = error; + } else { error[ERRLEN-1] = 0; msg = error; diff --git a/boot/key.c b/boot/key.c index 318866bc1623c994e6bfd1450f3127434b21f849..8220bf7da3b4cff4acff0807198ac7bb0290a5ce 100644 --- a/boot/key.c +++ b/boot/key.c @@ -26,21 +26,16 @@ getsafe(char *field, int len, uchar *sum, char *file, int pass) void key(int islocal, Method *mp) { - int fd, safeoff; + int fd; Nvrsafe safe; char password[20]; USED(islocal); USED(mp); - if(strcmp(cputype, "sparc") == 0) - safeoff = 1024+850; - else - safeoff = 1024+900; - fd = open("#r/nvram", ORDWR); if(fd < 0 - || seek(fd, safeoff, 0) < 0 + || seek(fd, 1024+900, 0) < 0 || read(fd, &safe, sizeof safe) != sizeof safe){ memset(&safe, 0, sizeof(safe)); warning("can't read nvram"); @@ -60,7 +55,7 @@ key(int islocal, Method *mp) safe.machsum = nvcsum(safe.machkey, DESKEYLEN); safe.authidsum = nvcsum(safe.authid, sizeof(safe.authid)); safe.authdomsum = nvcsum(safe.authdom, sizeof(safe.authdom)); - if(seek(fd, safeoff, 0) < 0 + if(seek(fd, 1024+900, 0) < 0 || write(fd, &safe, sizeof safe) != sizeof safe) warning("can't write key to nvram"); } diff --git a/boot/local.c b/boot/local.c index 54ede9d73ae21a15a8e6dab863a8cb43520000e5..58220587cedde0c255b0c979620221eaad38d3dd 100644 --- a/boot/local.c +++ b/boot/local.c @@ -2,30 +2,18 @@ #include #include <../boot/boot.h> -static char diskname[2*NAMELEN]; static char *disk; static char *niob; void configlocal(Method *mp) { - char *p; - int n; - - disk = mp->arg; /* 1st try from config file */ - if(disk && (niob = strchr(disk, ' '))) /* assign = */ - *niob++ = 0; - if(strncmp(argv0, "dksc(0,", 7) == 0){ - p = strchr(argv0, ','); - n = strtoul(p+1, 0, 10); - sprint(diskname, "#w%d/sd%dfs", n, n); - disk = diskname; - /*print("argv0=\"%s\" --> disk = \"%s\"\n", argv0, disk);/**/ - } if(*sys == '/' || *sys == '#') disk = sys; - if(disk) - setenv("bootdisk", disk); + else + disk = mp->arg; + if(niob = strchr(disk, ' ')) /* assign = */ + *niob++ = 0; USED(mp); } diff --git a/boot/settime.c b/boot/settime.c index e602abe7cbc7e43f8b9452c6a87c97c81f1bf1e4..81f82c3da7721700a740fc26c0f1b88d382629a0 100644 --- a/boot/settime.c +++ b/boot/settime.c @@ -42,7 +42,7 @@ settime(int islocal) if(f < 0) return; if(mount(f, "/n/boot", MREPL, "") < 0){ -warning("settime mount"); + warning("settime mount"); close(f); return; } @@ -66,6 +66,7 @@ warning("settime mount"); if(write(f, dirbuf, strlen(dirbuf)) < 0) warning("can't set #c/time"); close(f); + print("\n"); } #define SEC2MIN 60L diff --git a/gnot/bbmalloc.c b/gnot/bbmalloc.c deleted file mode 100644 index c1c06ac1bdf99e746aa9195aade72009d050d73a..0000000000000000000000000000000000000000 --- a/gnot/bbmalloc.c +++ /dev/null @@ -1,85 +0,0 @@ -#include "u.h" -#include "../port/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. - * - * This code will have to be interlocked if we ever get - * a multiprocessor with a bitmapped display. - */ - -/* a 0->3 bitblt can take 800 longs */ -enum { - narena=2, /* put interrupt time stuff in separate arena */ - nbbarena=4096 /* number of words in an arena */ -}; - -static ulong bbarena[narena][nbbarena]; -static ulong *bbcur[narena] = {&bbarena[0][0], &bbarena[1][0]}; -static ulong *bblast[narena] = {0, 0}; - -#define INTLEVEL(v) ((v)&0x700) -void * -bbmalloc(int nbytes) -{ - int nw, a; - int s; - ulong *ans; - - nw = nbytes/sizeof(long); - s = splhi(); - a = INTLEVEL(s)? 1 : 0; - if(bbcur[a] + nw > &bbarena[a][nbbarena]) - ans = bbarena[a]; - else - ans = bbcur[a]; - bbcur[a] = ans + nw; - splx(s); - bblast[a] = ans; - return ans; -} - -void -bbfree(void *p, int n) -{ - int a, s; - - s = splhi(); - a = INTLEVEL(s)? 1 : 0; - if(p == bblast[a]) - bbcur[a] = (ulong *)(((char *)bblast[a]) + n); - splx(s); -} - -void -flushvirtpage(void *p) -{ - USED(p); - flushcpucache(); -} - -void -bbdflush(void *p, int n) -{ - USED(p, n); - flushcpucache(); -} - -int -bbonstack(void) -{ - if(u) - return 1; - return 0; -} diff --git a/gnot/clock.c b/gnot/clock.c deleted file mode 100644 index 3e24fad8d5ade847fdcfb87b0a9067de8f7b83a2..0000000000000000000000000000000000000000 --- a/gnot/clock.c +++ /dev/null @@ -1,60 +0,0 @@ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "io.h" - -#include "ureg.h" - -void -delay(int ms) -{ - int i; - - ms *= 1000; /* experimentally determined */ - for(i=0; isr&SUPER) == 0; - if(user){ - u->dbgreg = ur; - u->p->pc = ur->pc; - } - - SYNCREG[1] = 0x5F; /* clear interrupt */ - m->ticks++; - p = m->proc; - if(p){ - nrun = 1; - p->pc = ur->pc; - if (p->state==Running) - p->time[p->insyscall]++; - } - nrun = (nrdy+nrun)*1000; - MACHP(0)->load = (MACHP(0)->load*19+nrun)/20; - checkalarms(); - kbdclock(); - duartclock(); - mouseclock(); - kproftimer(ur->pc); - if((ur->sr&SPL(7)) == 0 && p && p->state==Running){ - if(anyready()){ - if(p->hasspin) - p->hasspin = 0; - else - sched(); - } - if(user){ - (*(ulong*)(USTKTOP-BY2WD)) += TK2MS(1); /* profiling clock */ - notify(ur); - } - } -} diff --git a/gnot/dat.h b/gnot/dat.h deleted file mode 100644 index 49602b9068df792db6bcb0026e2d8dff5b6c307a..0000000000000000000000000000000000000000 --- a/gnot/dat.h +++ /dev/null @@ -1,177 +0,0 @@ -typedef struct Conf Conf; -typedef struct FFrame FFrame; -typedef struct FPsave FPsave; -typedef struct KMap KMap; -typedef struct Label Label; -typedef struct Lock Lock; -typedef struct MMU MMU; -typedef struct Mach Mach; -typedef struct PMMU PMMU; -typedef struct Portpage Portpage; -typedef struct Ureg Ureg; -typedef struct User User; - -#define MACHP(n) (n==0? &mach0 : *(Mach**)0) - -extern Mach mach0; -extern void (*kprofp)(ulong); - -/* - * parameters for sysproc.c - */ -#define AOUT_MAGIC A_MAGIC - -/* - * machine dependent definitions used by ../port/dat.h - */ - -struct Lock -{ - char key; - ulong pc; -}; - -enum -{ - FPinit, - FPactive, - FPdirty, -}; - -struct FPsave -{ - uchar type; - uchar size; - short reserved; - char junk[212]; /* 68881: sizes 24, 180; 68882: 56, 212 */ - /* this offset known in db */ - char reg[3*4+8*12]; -}; - -struct Label -{ - ulong sp; - ulong pc; - ushort sr; -}; - -/* - * MMU info included in the Proc structure - */ -struct PMMU -{ - int pmmu_dummy; -}; - -struct Conf -{ - int nmach; /* processors */ - int nproc; /* processes */ - int monitor; /* has display */ - ulong npage0; /* total physical pages of memory, bank 0 */ - ulong npage1; /* total physical pages of memory, bank 1 */ - ulong npage; - ulong base0; /* base of bank 0 */ - ulong base1; /* base of bank 1 */ - ulong upages; /* user page pool */ - ulong nimage; /* number of page cache image headers */ - ulong nswap; /* number of swap blocks */ - int nfsyschan; /* number of filsys open channels */ - int nisdn; /* number of isdn interfaces */ - int nlapd; /* number of dragnet protocol modules */ - int copymode; /* 0 is copy on write, 1 is copy on reference */ - int portispaged; /* 1 if extended I/O port addresses */ - int nconc; /* number of datakit concentrators */ -}; - -#include "../port/portdat.h" - -/* - * machine dependent definitions not used by ../port/dat.h - */ -struct KMap -{ - KMap *next; - ulong pa; - ulong va; -}; -#define VA(k) ((k)->va) - -struct Mach -{ - int machno; /* physical id of processor */ - ulong splpc; /* pc of last caller to splhi */ - ulong ticks; /* of the clock since boot time */ - Proc *proc; /* current process on this processor */ - Proc *lproc; /* last process on this processor */ - Label sched; /* scheduler wakeup */ - Lock alarmlock; /* access to alarm list */ - void *alarm; /* alarms bound to this clock */ - int fpstate; /* state of fp registers on machine */ - - int tlbpurge; - int tlbfault; - int pfault; - int cs; - int syscall; - int load; - int intr; - - int stack[1]; -}; - -/* - * gnot bus ports - */ -#define PORTSIZE 64 -#define PORTSHIFT 6 -#define PORTSELECT PORT[32] - -struct Portpage -{ - union{ - Lock; - QLock; - }; - int select; -}; - -#define NERR 25 -#define NNOTE 5 -struct User -{ - Proc *p; - FPsave fpsave; /* address of this is known by vdb */ - int scallnr; /* sys call number - known by db */ - Sargs s; /* address of this is known by db */ - uchar balusave[64]; /* #include botch */ - int nerrlab; - Label errlab[NERR]; - char error[ERRLEN]; - char elem[NAMELEN]; /* last name element from namec */ - Chan *slash; - Chan *dot; - /* - * Rest of structure controlled by devproc.c and friends. - * lock(&p->debug) to modify. - */ - Note note[NNOTE]; - short nnote; - short notified; /* sysnoted is due */ - Note lastnote; - int (*notify)(void*, char*); - void *ureg; - void *dbgreg; - ushort svsr; - ushort svvo; -}; - -struct -{ - Lock; - short machs; - short exiting; -}active; - -extern Mach *m; -extern User *u; diff --git a/gnot/devduart.c b/gnot/devduart.c deleted file mode 100644 index f3dda464c979b541ed2083dc31ca90d887eed940..0000000000000000000000000000000000000000 --- a/gnot/devduart.c +++ /dev/null @@ -1,762 +0,0 @@ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "io.h" -#include "ureg.h" -#include "../port/error.h" - -#include "devtab.h" - -int duartacr; -int duartimr; -void (*kprofp)(ulong); - -/* - * Register set for half the duart. There are really two sets. - */ -struct Duart{ - uchar mr1_2; /* Mode Register Channels 1 & 2 */ - uchar sr_csr; /* Status Register/Clock Select Register */ - uchar cmnd; /* Command Register */ - uchar data; /* RX Holding / TX Holding Register */ - uchar ipc_acr; /* Input Port Change/Aux. Control Register */ -#define ivr ivr /* Interrupt Vector Register */ - uchar is_imr; /* Interrupt Status/Interrupt Mask Register */ -#define ip_opcr is_imr /* Input Port/Output Port Configuration Register */ - uchar ctur; /* Counter/Timer Upper Register */ -#define scc_sopbc ctur /* Start Counter Command/Set Output Port Bits Command */ - uchar ctlr; /* Counter/Timer Lower Register */ -#define scc_ropbc ctlr /* Stop Counter Command/Reset Output Port Bits Command */ -}; - -enum{ - CHAR_ERR =0x00, /* MR1x - Mode Register 1 */ - PAR_ENB =0x00, - EVEN_PAR =0x00, - ODD_PAR =0x04, - NO_PAR =0x10, - CBITS8 =0x03, - CBITS7 =0x02, - CBITS6 =0x01, - CBITS5 =0x00, - NORM_OP =0x00, /* MR2x - Mode Register 2 */ - TWOSTOPB =0x0F, - ONESTOPB =0x07, - ENB_RX =0x01, /* CRx - Command Register */ - DIS_RX =0x02, - ENB_TX =0x04, - DIS_TX =0x08, - RESET_MR =0x10, - RESET_RCV =0x20, - RESET_TRANS =0x30, - RESET_ERR =0x40, - RESET_BCH =0x50, - STRT_BRK =0x60, - STOP_BRK =0x70, - RCV_RDY =0x01, /* SRx - Channel Status Register */ - FIFOFULL =0x02, - XMT_RDY =0x04, - XMT_EMT =0x08, - OVR_ERR =0x10, - PAR_ERR =0x20, - FRM_ERR =0x40, - RCVD_BRK =0x80, - BD38400 =0xCC|0x0000, - BD19200 =0xCC|0x0100, - BD9600 =0xBB|0x0000, - BD4800 =0x99|0x0000, - BD2400 =0x88|0x0000, - BD1200 =0x66|0x0000, - BD300 =0x44|0x0000, - IM_IPC =0x80, /* IMRx/ISRx - Interrupt Mask/Interrupt Status */ - IM_DBB =0x40, - IM_RRDYB =0x20, - IM_XRDYB =0x10, - IM_CRDY =0x08, - IM_DBA =0x04, - IM_RRDYA =0x02, - IM_XRDYA =0x01, -}; - -/* - * software info for a serial duart interface - */ -typedef struct Duartport Duartport; -struct Duartport -{ - QLock; - int printing; /* true if printing */ - - /* console interface */ - int nostream; /* can't use the stream interface */ - IOQ *iq; /* input character queue */ - IOQ *oq; /* output character queue */ - - /* stream interface */ - Queue *wq; /* write queue */ - Rendez r; /* kproc waiting for input */ - int kstarted; /* kproc started */ -}; -Duartport duartport[1]; - -uchar keymap[]={ -/*80*/ 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, - 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x8e, 0x58, -/*90*/ 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, - 0x98, 0x99, 0x9a, 0x9b, 0x58, 0x58, 0x58, 0x58, -/*A0*/ 0x58, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, - 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0xae, 0xaf, -/*B0*/ 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, - 0xb8, 0xb9, 0x00, 0xbb, 0x1e, 0xbd, 0x60, 0x1f, -/*C0*/ 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0x58, 0xc6, 0x0a, - 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, -/*D0*/ 0x09, 0x08, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, - 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x7f, 0x58, -/*E0*/ 0x58, 0x58, 0xe2, 0x1b, 0x0d, 0xe5, 0x58, 0x0a, - 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, -/*F0*/ 0x09, 0x08, 0xb2, 0x1b, 0x0d, 0xf5, 0x81, 0x58, - 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x7f, 0x80, -}; - -void -duartinit(void) -{ - Duart *duart; - static int already; - - if(already) - return; - already = 1; - - duart = DUARTREG; - - /* - * Keyboard - */ - duart[0].cmnd = RESET_RCV|DIS_TX|DIS_RX; - duart[0].cmnd = RESET_TRANS; - duart[0].cmnd = RESET_ERR; - duart[0].cmnd = RESET_MR; - duart[0].mr1_2 = CHAR_ERR|PAR_ENB|EVEN_PAR|CBITS8; - duart[0].mr1_2 = NORM_OP|ONESTOPB; - duart[0].sr_csr = BD4800; - - /* - * RS232 - */ - duart[1].cmnd = RESET_RCV|DIS_TX|DIS_RX; - duart[1].cmnd = RESET_TRANS; - duart[1].cmnd = RESET_ERR; - duart[1].cmnd = RESET_MR; - duart[1].mr1_2 = CHAR_ERR|NO_PAR|CBITS8; - duart[1].mr1_2 = NORM_OP|ONESTOPB; - duart[1].sr_csr = BD9600; - - /* - * Output port - */ - duart[0].ipc_acr = duartacr = 0xB7; /* allow change of state interrupt */ - duart[1].ip_opcr = 0x00; - duart[1].scc_ropbc = 0xFF; /* make sure the port is reset first */ - duart[1].scc_sopbc = 0x04; /* dtr = 1, pp = 01 */ - duart[0].is_imr = duartimr = IM_IPC|IM_RRDYB|IM_XRDYB|IM_RRDYA|IM_XRDYA; - duart[0].cmnd = ENB_TX|ENB_RX; /* enable TX and RX last */ - duart[1].cmnd = ENB_TX|ENB_RX; - - /* - * Initialize keyboard - */ - while (!(duart[0].sr_csr & (XMT_EMT|XMT_RDY))) - ; - duart[0].data = 0x02; -} - - -void -duartbaud(int b) -{ - int x = 0; - Duart *duart = DUARTREG; - - switch(b){ - case 38400: - x = BD38400; - break; - case 19200: - x = BD19200; - break; - case 9600: - x = BD9600; - break; - case 4800: - x = BD4800; - break; - case 2400: - x = BD2400; - break; - case 1200: - x = BD1200; - break; - case 300: - x = BD300; - break; - default: - error(Ebadarg); - } - if(x & 0x0100) - duart[0].ipc_acr = duartacr |= 0x80; - else - duart[0].ipc_acr = duartacr &= ~0x80; - duart[1].sr_csr = x; -} - -void -duartdtr(int val) -{ - Duart *duart = DUARTREG; - if (val) - duart[1].scc_ropbc=0x01; - else - duart[1].scc_sopbc=0x01; -} - -void -duartbreak(int ms) -{ - static QLock brk; - Duart *duart = DUARTREG; - if (ms<=0 || ms >20000) - error(Ebadarg); - qlock(&brk); - duart[0].is_imr = duartimr &= ~IM_XRDYB; - duart[1].cmnd = STRT_BRK|ENB_TX; - tsleep(&u->p->sleep, return0, 0, ms); - duart[1].cmnd = STOP_BRK|ENB_TX; - duart[0].is_imr = duartimr |= IM_XRDYB; - qunlock(&brk); -} - -enum{ - Kptime=200 -}; -void -duartstarttimer(void) -{ - Duart *duart; - char x; - - duart = DUARTREG; - duart[0].ctur = (Kptime)>>8; - duart[0].ctlr = (Kptime)&255; - duart[0].is_imr = duartimr |= IM_CRDY; - x = duart[1].scc_sopbc; - USED(x); -} - -void -duartstoptimer(void) -{ - Duart *duart; - char x; - - duart = DUARTREG; - x = duart[1].scc_ropbc; - USED(x); - duart[0].is_imr = duartimr &= ~IM_CRDY; -} - - -/* - * a serial line input interrupt - */ -void -duartrintr(char ch) -{ - IOQ *cq; - Duartport *dp = duartport; - - cq = dp->iq; - if(cq->putc) - (*cq->putc)(cq, ch); - else { - putc(cq, ch); - } -} -void -duartclock(void) -{ - Duartport *dp = duartport; - IOQ *cq; - - cq = dp->iq; - if(cangetc(cq)) - wakeup(&cq->r); -} - -/* - * a serial line output interrupt - */ -void -duartxintr(void) -{ - int ch; - IOQ *cq; - Duartport *dp = duartport; - Duart *duart; - - cq = dp->oq; - lock(cq); - ch = getc(cq); - duart = DUARTREG; - if(ch < 0){ - dp->printing = 0; - wakeup(&cq->r); - duart[1].cmnd = DIS_TX; - } else - duart[1].data = ch; - unlock(cq); -} - - -void -duartintr(Ureg *ur) -{ - int cause, status, ch, i, nk; - Duart *duart; - static int lstate; - static uchar kc[5]; - - duart = DUARTREG; - cause = duart->is_imr; - /* - * I can guess your interrupt. - */ - /* - * Is it 0? - */ - if(cause & IM_CRDY){ - if(kprofp) - (*kprofp)(ur->pc); - ch = duart[1].scc_ropbc; - USED(ch); - duart[0].ctur = (Kptime)>>8; - duart[0].ctlr = (Kptime)&255; - ch = duart[1].scc_sopbc; - USED(ch); - return; - } - /* - * Is it 1? - */ - if(cause & IM_RRDYA){ /* keyboard input */ - status = duart->sr_csr; - ch = duart->data; - if(status & (FRM_ERR|OVR_ERR|PAR_ERR)) - duart->cmnd = RESET_ERR; - if(status & PAR_ERR) /* control word: caps lock (0x4) or repeat (0x10) */ - kbdrepeat((ch&0x10) == 0); - else{ - if(ch == 0x7F) /* VIEW key (bizarre) */ - ch = 0xFF; - if(ch == 0xB6) /* NUM PAD */ - lstate = 1; - else{ - if(ch & 0x80) - ch = keymap[ch&0x7F]; - switch(lstate){ - case 1: - kc[0] = ch; - lstate = 2; - if(ch == 'X') - lstate = 3; - break; - case 2: - kc[1] = ch; - ch = latin1(kc); - nk = 2; - putit: - lstate = 0; - if(ch != -1) - kbdputc(&kbdq, ch); - else for(i=0; iis_imr; - } - /* - * Is it 3? - */ - if(cause & IM_XRDYB) /* duart output */ - duartxintr(); - /* - * Is it 4? - */ - if(cause & IM_XRDYA) - duart[0].cmnd = DIS_TX; - /* - * Is it 5? - */ - if(cause & IM_IPC) - mousetrack((~duart[0].ipc_acr) & 7, 0, 0); -} - - -/* - * Queue n characters for output; if queue is full, we lose characters. - * Get the output going if it isn't already. - */ -void -duartputs(IOQ *cq, char *s, int n) -{ - int ch, x; - Duartport *dp = duartport; - Duart *duart; - - x = splduart(); - lock(cq); - puts(cq, s, n); - if(dp->printing == 0){ - ch = getc(cq); - if(ch >= 0){ - dp->printing = 1; - duart = DUARTREG; - duart[1].cmnd = ENB_TX; - while(!(duart[1].sr_csr & (XMT_RDY|XMT_EMT))) - ; - duart[1].data = ch; - } - } - unlock(cq); - splx(x); -} - -void -duartenable(Duartport *dp) -{ - /* - * set up i/o routines - */ - if(dp->oq){ - dp->oq->puts = duartputs; - dp->oq->ptr = dp; - } - if(dp->iq) - dp->iq->ptr = dp; -} - -/* - * set up an duart port as something other than a stream - */ -void -duartspecial(int port, IOQ *oq, IOQ *iq, int baud) -{ - Duartport *dp = &duartport[port]; - - dp->nostream = 1; - dp->oq = oq; - dp->iq = iq; - duartenable(dp); - duartbaud(baud); -} - -static int duartputc(IOQ *, int); -static void duartstopen(Queue*, Stream*); -static void duartstclose(Queue*); -static void duartoput(Queue*, Block*); -static void duartkproc(void *); -Qinfo duartinfo = -{ - nullput, - duartoput, - duartstopen, - duartstclose, - "duart" -}; - -static void -duartstopen(Queue *q, Stream *s) -{ - Duartport *dp; - char name[NAMELEN]; - - if(s->id > 0) - panic("duartstopen"); - dp = &duartport[s->id]; - - qlock(dp); - dp->wq = WR(q); - WR(q)->ptr = dp; - RD(q)->ptr = dp; - qunlock(dp); - - if(dp->kstarted == 0){ - dp->kstarted = 1; - sprint(name, "duart%d", s->id); - kproc(name, duartkproc, dp); - } -} - -static void -duartstclose(Queue *q) -{ - Duartport *dp = q->ptr; - - qlock(dp); - dp->wq = 0; - dp->iq->putc = 0; - WR(q)->ptr = 0; - RD(q)->ptr = 0; - qunlock(dp); -} - -static void -duartoput(Queue *q, Block *bp) -{ - Duartport *dp = q->ptr; - IOQ *cq; - int n, m; - - if(dp == 0){ - freeb(bp); - return; - } - cq = dp->oq; - if(waserror()){ - freeb(bp); - nexterror(); - } - if(bp->type == M_CTL){ - while (cangetc(cq)) /* let output drain */ - sleep(&cq->r, cangetc, cq); - n = strtoul((char *)(bp->rptr+1), 0, 0); - switch(*bp->rptr){ - case 'B': - case 'b': - duartbaud(n); - break; - case 'D': - case 'd': - duartdtr(n); - break; - case 'K': - case 'k': - duartbreak(n); - break; - case 'R': - case 'r': - /* can't control? */ - break; - case 'W': - case 'w': - /* obsolete */ - break; - } - }else while((m = BLEN(bp)) > 0){ - while ((n = canputc(cq)) == 0){ - kprint(" duartoput: sleeping\n"); - sleep(&cq->r, canputc, cq); - } - if(n > m) - n = m; - (*cq->puts)(cq, bp->rptr, n); - bp->rptr += n; - } - poperror(); - freeb(bp); -} - -/* - * process to send bytes upstream for a port - */ -static void -duartkproc(void *a) -{ - Duartport *dp = a; - IOQ *cq = dp->iq; - Block *bp; - int n; - -loop: - while ((n = cangetc(cq)) == 0) - sleep(&cq->r, cangetc, cq); - qlock(dp); - if(dp->wq == 0){ - cq->out = cq->in; - }else{ - bp = allocb(n); - bp->flags |= S_DELIM; - bp->wptr += gets(cq, bp->wptr, n); - PUTNEXT(RD(dp->wq), bp); - } - qunlock(dp); - goto loop; -} - -enum{ - Qdir= 0, - Qeia0= STREAMQID(0, Sdataqid), - Qeia0ctl= STREAMQID(0, Sctlqid), -}; - -Dirtab duartdir[]={ - "eia0", {Qeia0}, 0, 0666, - "eia0ctl", {Qeia0ctl}, 0, 0666, -}; - -#define NDuartport (sizeof duartdir/sizeof(Dirtab)) - -/* - * allocate the queues if no one else has - */ -void -duartreset(void) -{ - Duartport *dp = duartport; - - if(dp->nostream) - return; - dp->iq = xalloc(sizeof(IOQ)); - initq(dp->iq); - dp->oq = xalloc(sizeof(IOQ)); - initq(dp->oq); - duartenable(dp); -} - -Chan* -duartattach(char *spec) -{ - return devattach('t', spec); -} - -Chan* -duartclone(Chan *c, Chan *nc) -{ - return devclone(c, nc); -} - -int -duartwalk(Chan *c, char *name) -{ - return devwalk(c, name, duartdir, NDuartport, devgen); -} - -void -duartstat(Chan *c, char *dp) -{ - switch(c->qid.path){ - case Qeia0: - streamstat(c, dp, duartdir[0].name, duartdir[0].perm); - break; - default: - devstat(c, dp, duartdir, NDuartport, devgen); - break; - } -} - -Chan* -duartopen(Chan *c, int omode) -{ - Duartport *dp; - - switch(c->qid.path){ - case Qeia0: - case Qeia0ctl: - dp = &duartport[0]; - break; - default: - dp = 0; - break; - } - - if(dp && dp->nostream) - error(Einuse); - - if((c->qid.path & CHDIR) == 0) - streamopen(c, &duartinfo); - return devopen(c, omode, duartdir, NDuartport, devgen); -} - -void -duartcreate(Chan *c, char *name, int omode, ulong perm) -{ - USED(c, name, omode, perm); - error(Eperm); -} - -void -duartclose(Chan *c) -{ - if(c->stream) - streamclose(c); -} - -long -duartread(Chan *c, void *buf, long n, ulong offset) -{ - int s; - Duart *duart = DUARTREG; - - switch(c->qid.path&~CHDIR){ - case Qdir: - return devdirread(c, buf, n, duartdir, NDuartport, devgen); - case Qeia0ctl: - if(offset) - return 0; - s = splhi(); - *(uchar *)buf = duart[1].ip_opcr; - splx(s); - return 1; - } - return streamread(c, buf, n); -} - -long -duartwrite(Chan *c, void *va, long n, ulong offset) -{ - USED(offset); - return streamwrite(c, va, n, 0); -} - -void -duartremove(Chan *c) -{ - USED(c); - error(Eperm); -} - -void -duartwstat(Chan *c, char *dp) -{ - USED(c, dp); - error(Eperm); -} diff --git a/gnot/devhifi.c b/gnot/devhifi.c deleted file mode 100644 index 7fc19d8242961756facd90b4c4ecf3cc4b3df4af..0000000000000000000000000000000000000000 --- a/gnot/devhifi.c +++ /dev/null @@ -1,765 +0,0 @@ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "../port/error.h" -#include "devtab.h" - -#include "io.h" -#ifdef SET -#undef SET -#endif -#include "isdn.h" -#include "hifi.h" - -#define DPRINT if(hifidebug)kprint - -#define BSIZE 4000 - -typedef struct Hifichan -{ - Isdn * udev; /* unite interface */ - Hifi * hdev; /* pointer to device */ - uchar imask; /* interrupt bit */ - uchar opreg; /* sticky bits */ - uchar tctl; /* more sticky bits */ - uchar devaddr; /* debug access */ - - Lock kctl; /* kproc start */ - Rendez kr; /* kernel process sleep/wakeup */ - QLock; /* access to struct */ - int hdlc; /* hdlc mode enabled */ - int hangup; /* hangup pending */ - int nohup; /* hangups ignored */ - - int renable; /* reading enabled */ - Block * inb[NB]; /* input buffer */ - int ri; /* input read pointer */ - int wi; /* input write pointer */ - Queue * rq; /* read queue */ - - int wenable; /* writing enabled */ - int wactive; /* writing in progress */ - QLock wlock; /* write's are atomic */ - Block * outb[NB]; /* output buffer */ - int so; /* output scavenge pointer */ - int ro; /* output read pointer */ - int wo; /* output write pointer */ - Block * out; /* current output block */ - Rendez tr; /* if transmitter must wait */ - Rendez cr; /* waiting to close */ - - /* statistics */ - - ulong inchars; - ulong badcrc; - ulong abort; - ulong overrun; - ulong badcount; - ulong overflow; - ulong toolong; - ulong underrun; - ulong outchars; -} Hifichan; - -Hifichan * hifichan; -Hifichan * hifichanN; - -static void devinit(int); -static int hifiintr(void); -static void hifikproc(void*); -static void hifiloopctl(Hifichan*, int); -static int hifirecv(Hifichan*); -static void hifirecven(Hifichan*, int); -static int hifixmit(Hifichan*); -static void hifixmitdis(Hifichan*, int); -static void hifixmiten(Hifichan*, int); - -enum { - Qdir, Qdev, Qstats, Qdebug -}; - -Dirtab hifidir[]={ - "dev", {Qdev}, 0, 0666, - "stats", {Qstats}, 0, 0444, - "debug", {Qdebug}, 0, 0666, -}; -#define NHIFI (sizeof hifidir/sizeof(Dirtab)) - -/* - * stream module definition - */ -static void hifiiput(Queue*, Block*); -static void hifioput(Queue*, Block*); -static void hifistopen(Queue*, Stream*); -static void hifistclose(Queue*); -Qinfo hifiinfo = { hifiiput, hifioput, hifistopen, hifistclose, "hifi" }; - -int hifidebug; - -void -hifireset(void) -{ - hifichan = xalloc(2*conf.nisdn*sizeof(Hifichan)); - hifichanN = &hifichan[2*conf.nisdn]; -} - -void -hifiinit(void) -{} - -Chan* -hifiattach(char *spec) -{ - int dev; - Chan *c; - Hifichan *hp; - static int intrinited; - - dev = strtoul(spec, 0, 0); - if(dev >= 2*conf.nisdn) - error(Enonexist); - - c = devattach('H', spec); - c->dev = dev; - hp = &hifichan[dev]; - if(!hp->udev){ - DPRINT("hifiattach: init dev=%d\n", c->dev); - if(!intrinited){ - intrinited = 1; - DPRINT("addportintr(hifiintr)\n"); - addportintr(hifiintr); - } - devinit(c->dev); - } - return c; -} - -Chan* -hificlone(Chan *c, Chan *nc) -{ - return devclone(c, nc); -} - -int -hifiwalk(Chan *c, char *name) -{ - return devwalk(c, name, hifidir, NHIFI, streamgen); -} - -void -hifistat(Chan *c, char *dp) -{ - devstat(c, dp, hifidir, NHIFI, streamgen); -} - -Chan* -hifiopen(Chan *c, int omode) -{ - if(c->qid.path == CHDIR){ - if(omode != OREAD) - error(Eperm); - }else switch(STREAMTYPE(c->qid.path)){ - case Qdev: - case Qstats: - case Qdebug: - break; - default: - DPRINT("hifiopen dev=%d\n", c->dev); - streamopen(c, &hifiinfo); - } - c->mode = openmode(omode); - c->flag |= COPEN; - c->offset = 0; - return c; -} - -void -hificreate(Chan *c, char *name, int omode, ulong perm) -{ - USED(c, name, omode, perm); - error(Eperm); -} - -void -hificlose(Chan *c) -{ - if(c->qid.path != CHDIR) - streamclose(c); -} - -long -hifiread(Chan *c, void *buf, long n, ulong offset) -{ - Hifichan *hp = &hifichan[c->dev]; - char nbuf[512], *p; - - if(n <= 0) - return 0; - if(c->qid.path == CHDIR){ - return devdirread(c, buf, n, hifidir, NHIFI, streamgen); - }else switch(STREAMTYPE(c->qid.path)){ - case Qdev: - sprint(nbuf, "0x%2.2ux = 0x%2.2ux\n", - hp->devaddr, isdnpeek(hp->udev, (void *)hp->devaddr)); - return readstr(offset, buf, n, nbuf); - - case Qstats: - p = nbuf; - p += sprint(p, "inchars %10lud\n", hp->inchars); - p += sprint(p, "badcrc %10lud\n", hp->badcrc); - p += sprint(p, "abort %10lud\n", hp->abort); - p += sprint(p, "overrun %10lud\n", hp->overrun); - p += sprint(p, "badcount %10lud\n", hp->badcount); - p += sprint(p, "overflow %10lud\n", hp->overflow); - p += sprint(p, "toolong %10lud\n", hp->toolong); - p += sprint(p, "underrun %10lud\n", hp->underrun); - p += sprint(p, "outchars %10lud\n", hp->outchars); - USED(p); - return readstr(offset, buf, n, nbuf); - - case Qdebug: - sprint(nbuf, "%d\n", hifidebug); - return readstr(offset, buf, n, nbuf); - } - if(!hp->renable) - hifirecven(hp, 1); - return streamread(c, buf, n); -} - -long -hifiwrite(Chan *c, void *buf, long n, ulong offset) -{ - Hifichan *hp = &hifichan[c->dev]; - char nbuf[32], *p; - - USED(offset); - if(n < 0) - return 0; - switch(STREAMTYPE(c->qid.path)){ - case Qdev: - if(n>sizeof nbuf-1) - n = sizeof nbuf-1; - memmove(nbuf, buf, n); - nbuf[n-1] = 0; - hp->devaddr = (int)hp->hdev + strtoul(nbuf,0,0); - if(p = strchr(nbuf, '=')) /* assign = */ - isdnpoke(hp->udev, (void *)hp->devaddr, strtoul(++p,0,0)); - return n; - case Qdebug: - if (n>sizeof nbuf) - n = sizeof nbuf; - memmove(nbuf, buf, n); - nbuf[n-1] = 0; - hifidebug = strtoul(nbuf,0,0); - return n; - } - return streamwrite(c, buf, n, 0); -} - -void -hifiremove(Chan *c) -{ - USED(c); - error(Eperm); -} - -void -hifiwstat(Chan *c, char *dp) -{ - USED(c, dp); - error(Eperm); -} - -/* - * the stream routines - */ - -#define Predicate(name, expr) static int name(void *arg) { return expr; } -#define hp ((Hifichan *)arg) - -Predicate(kRun, hp->ri != hp->wi || hp->so != hp->ro) - -Predicate(tActive, hp->wenable) -Predicate(tDead, hp->wenable == 0) -Predicate(tEmpty, hp->ro == hp->wo) -Predicate(tFull, NEXT(hp->wo) == hp->so) -Predicate(tNotFull, NEXT(hp->wo) != hp->so) - -#undef hp - -static void -hifistopen(Queue *q, Stream *s) -{ - Hifichan *hp = &hifichan[s->dev]; - char name[32]; - - DPRINT("hifistopen %d\n", s->dev); - qlock(hp); - q->ptr = q->other->ptr = hp; - hp->rq = q; - if(canlock(&hp->kctl)){ - sprint(name, "hifi%d", s->dev); - kproc(name, hifikproc, hp); - } - qunlock(hp); -} - -static void -hifistclose(Queue * q) -{ - Hifichan *hp = (Hifichan *)q->ptr; - - DPRINT("hifistclose %d...\n", hp-hifichan); - hifirecven(hp, -1); - qlock(hp); - hp->rq = 0; - hp->hangup = 0; - hp->nohup = 0; - if(tActive(hp)){ - if(!hp->wactive || waserror()){ - hifixmitdis(hp, 1); - wakeup(&hp->kr); - }else{ - sleep(&hp->cr, tDead, hp); - poperror(); - } - } - qunlock(hp); - DPRINT("hifistclose %d OK\n", hp-hifichan); -} - -/* - * this is only called by hangup - */ -static void -hifiiput(Queue *q, Block *bp) -{ - Hifichan *hp = (Hifichan *)q->ptr; - - if(bp->type == M_HANGUP){ - DPRINT("hifiiput %d M_HANGUP (%d)\n", hp-hifichan, hp->nohup); - if(!hp->nohup) - hifirecven(hp, 0); - } - freeb(bp); -} - -void -hifioput(Queue *q, Block *bp) -{ - Hifichan *hp = (Hifichan *)q->ptr; - - if(bp->type != M_DATA){ - if(hifidebug){ - char fmt[32]; - sprint(fmt, "hifioput %%d: %%.%ds\n", bp->wptr-bp->rptr); - kprint(fmt, hp-hifichan, bp->rptr); - } - if(streamparse("hdlc", bp)){ - if(streamparse("on", bp)){ - hp->hdlc = 1; - hifixmiten(hp, 1); - }else{ - hp->hdlc = 0; - if(hp->wenable) - hifixmiten(hp, 1); - } - }else if(streamparse("loop", bp)){ - if(streamparse("on", bp)) - hifiloopctl(hp, 1); - else - hifiloopctl(hp, 0); - }else if(streamparse("click!", bp)){ - hifirecven(hp, 0); - }else if(streamparse("recven", bp)){ - hifirecven(hp, 1); - }else if(streamparse("nohup", bp)){ - hp->nohup = 1; - } - freeb(bp); - return; - } - qlock(&hp->wlock); - if(!putq(q, bp)){ /* send only whole messages */ - qunlock(&hp->wlock); - return; - } - DPRINT("hifioput %d: [%d] len=%d\n", - hp-hifichan, TK2MS(MACHP(0)->ticks), q->len); - if(tFull(hp)) - sleep(&hp->tr, tNotFull, hp); - hp->outb[hp->wo] = grabq(q); - hp->wo = NEXT(hp->wo); - qunlock(&hp->wlock); - - isdnlock(hp->udev); - if(hifixmit(hp)) - wakeup(&hp->kr); - isdnunlock(hp->udev); -} - -static void -hifirecven(Hifichan *hp, int r) -{ - Hifi *hifi = hp->hdev; - int i; - - qlock(hp); - if(!hp->renable && r > 0){ - hp->ri = hp->wi; - for (i=0; iinb[i]) - hp->inb[i] = allocb(BSIZE); - hp->renable = 1; - isdnpoke(hp->udev, &hifi->opreg, hp->opreg |= Enr); - DPRINT("hifirecven %d: enabled\n", hp-hifichan); - }else if(hp->renable && r <= 0){ - isdnpoke(hp->udev, &hifi->opreg, hp->opreg &= ~Enr); - hp->renable = 0; - hp->hangup = 1; - wakeup(&hp->kr); - DPRINT("hifirecven %d: disabled\n", hp-hifichan); - } - if(r < 0){ - hp->ri = hp->wi; - for (i=0; iinb[i]){ - freeb(hp->inb[i]); - hp->inb[i] = 0; - } - DPRINT("hifirecven %d: flushed\n", hp-hifichan); - } - qunlock(hp); -} - -static void -hifikproc(void *arg) -{ - Hifichan *hp = arg; - Block *bp; - int i; -Top: - if(waserror()){ - print("hifikproc: error\n"); - goto Top; - } - for(;;){ - qlock(hp); - while(hp->ri != hp->wi){ - if(hp->rq){ - FLOWCTL(hp->rq, hp->inb[hp->ri]); - }else - freeb(hp->inb[hp->ri]); - if(hp->renable) - hp->inb[hp->ri] = allocb(BSIZE); - else - hp->inb[hp->ri] = 0; - hp->ri = NEXT(hp->ri); - } - if(hp->hangup){ - hp->hangup = 0; - if(hp->rq){ - bp = allocb(0); - bp->type = M_HANGUP; - PUTNEXT(hp->rq, bp); - } - } - i = 0; - while(hp->so != hp->ro){ - freeb(hp->outb[hp->so]); - hp->so = NEXT(hp->so); - i++; - } - qunlock(hp); - if(i) - wakeup(&hp->tr); - sleep(&hp->kr, kRun, hp); - } -} - -static void -devinit(int h) -{ - Hifichan *hp = &hifichan[h]; - Hifi *hifi = (h&1) ? hifi1 : hifi0; - Isdn *ip = &isdndev[h>>1]; - - isdnlock(ip); - - hp->udev = ip; - hp->hdev = hifi; - hp->imask = (h&1) ? Hint1 : Hint0; - - hp->opreg = 0; - SET(hifi->opreg, Rres|Tres); /* master reset */ - SET(hifi->config, Fsen); /* frame sync enable */ - hp->tctl = 30; - SET(hifi->tctl, hp->tctl); /* transmitter interrupt level */ - SET(hifi->rctl, 20); /* receiver interrupt level */ - SET(hifi->bofctl, Clkxi); /* transmit in rising edge of CLKX */ - /* SET(hifi->tofctl, Dxi); /* transmit inverted data */ - SET(hifi->tofctl, 0); /* transmit normal data */ - SET(hifi->rof_tm, Dri); /* receive inverted data */ - SET(hifi->config, Fsen|Alt); /* alternate reg's... */ - SET(hifi->rof_tm, Trans); /* transparent mode */ - SET(hifi->config, Fsen); /* normal reg's... */ - SET(hifi->tmask, 0xff); /* transmit all bits */ - SET(hifi->imask, Undie|Tdie|Teie|Rfie|Reofie); /* interrupt enables */ - - isdnunlock(ip); -} - -static void -hifiloopctl(Hifichan *hp, int loop) -{ - Isdn *ip = hp->udev; - Hifi *hifi = hp->hdev; - - DPRINT("hifiloopctl %d: %d\n", hp-hifichan, loop); - isdnlock(ip); - if(loop) - SET(hifi->opreg, hp->opreg |= Lloop); - else - SET(hifi->opreg, hp->opreg &= ~Lloop); - isdnunlock(ip); -} - -static int -hifiintr(void) -{ - Isdn *ip; - Hifichan *hp; - Hifi *hifi; - int intr = 0, status, wake = 0, w = 0; - - for(hp=hifichan; hpudev)) /* assign = */ - continue; - if (!(*(ip->asr)&hp->imask)) - continue; - ++intr; - hifi = hp->hdev; - status = GET(hifi->istat); - if(status&(Rf|Reof)){ - status &= ~(Rf|Reof); - wake += hifirecv(hp); - } - if(status&Te){ - status &= ~Te; - wake += w = hifixmit(hp); - } - if(status&Undabt){ - status &= ~Undabt; - DPRINT("hifiintr: hdlc %d under run\n", hp-hifichan); - ++hp->underrun; - } - if(status&Tdone){ - status &= ~Tdone; - hp->wactive = 0; - if(!hp->hdlc && (w || hp->out || hp->ro != hp->wo)){ - DPRINT("hifiintr: trans %d under run\n", - hp-hifichan); - ++hp->underrun; - }else if(!hp->hdlc || !hp->rq){ - DPRINT("hifiintr: xmtr %d done\n", hp-hifichan); - hifixmitdis(hp, 0); - ++wake; - wakeup(&hp->cr); - } - } - if(wake) - wakeup(&hp->kr); - if(status) - DPRINT("hifiintr: status %d 0x%2.2x\n", - status, hp-hifichan); - } - return intr; -} - -static int -hifirecv(Hifichan *hp) -{ - Isdn *ip = hp->udev; - Hifi *hifi = hp->hdev; - Block *bp = hp->inb[hp->wi]; - uchar *p; - int status, i, n, m, wake = 0; -Loop: - status = GET(hifi->rstat); - if(status == 0) - return wake; - n = status&0x7f; - p = bp->wptr; - m = bp->lim - p; - if(hp->hdlc){ - if(n > m){ - hp->toolong++; - bp->wptr = bp->base; - bp->rptr = bp->base; - SET(hifi->opreg, hp->opreg | Rres); - return wake; - } - hp->inchars += n; - SETADDR(&hifi->data); - while(--n >= 0) - *p++ = *(ip->data); - if(status&Eof){ - if(*--p == 0){ - i = NEXT(hp->wi); - if(i == hp->ri) - hp->overflow++; - else{ - bp->wptr = p; - bp->flags |= S_DELIM; - hp->wi = i; - bp = hp->inb[i]; - ++wake; - } - }else{ - if(*p & 0x80) - hp->badcrc++; - if(*p & 0x40) - hp->abort++; - if(*p & 0x20) - hp->overrun++; - if(*p & 0x10) - hp->badcount++; - } - bp->wptr = bp->base; - bp->rptr = bp->base; - }else - bp->wptr = p; - }else{ - if(n > m) - n = m; - hp->inchars += n; - SETADDR(&hifi->data); - while(--n >= 0) - *p++ = *(ip->data); - bp->wptr = p; - if(p >= bp->lim){ - i = NEXT(hp->wi); - if(i == hp->ri){ - bp->wptr = bp->base; - bp->rptr = bp->base; - return wake; - }else{ - bp->flags |= S_DELIM; - hp->wi = i; - bp = hp->inb[i]; - ++wake; - } - } - } - goto Loop; -} - -static int -hifixmit(Hifichan *hp) -{ - Isdn *ip = hp->udev; - Hifi *hifi = hp->hdev; - Block *bp; - uchar *p; - int n, k, wake = 0; - -Loop: - n = GET(hifi->tstat)&0x7f; - if(n == 0) - return wake; - if(!(bp = hp->out)){ /* assign = */ - if(hp->ro == hp->wo){ - DPRINT("hifixmit %d: [%d] empty\n", - hp-hifichan, TK2MS(MACHP(0)->ticks)); - return wake; - } - hp->out = bp = hp->outb[hp->ro]; - } - p = bp->rptr; - k = bp->wptr - p; - if (n > k) - n = k; - hp->outchars += n; - SETADDR(&hifi->data); - if(hp->hdlc){ - while(--n >= 0) - *(ip->data) = *p++; - }else{ - while(--n >= 0) - *(ip->data) = ~*p++; - } - bp->rptr = p; - hp->wactive = 1; - if(!hp->wenable) - hifixmiten(hp, 0); - if(bp->rptr == bp->wptr){ - if(hp->hdlc && (bp->flags & S_DELIM)) - SET(hifi->tctl, hp->tctl|Tfc); - if(!(hp->out = bp = bp->next)){ /* assign = */ - hp->ro = NEXT(hp->ro); - ++wake; - } - } - goto Loop; -} - -static void -hifixmiten(Hifichan *hp, int dolock) -{ - Isdn *ip = hp->udev; - Hifi *hifi = hp->hdev; - - DPRINT("hifixmiten %d: %s\n", hp-hifichan, hp->hdlc?"hdlc":"trans"); - if(dolock) - isdnlock(ip); - if(hp->hdlc){ - SET(hifi->tofctl, Dxi|Tlbit); /* xmit ~data, lsb first */ - SET(hifi->rof_tm, Dri|Rlbit); /* rcv ~data, lsb first */ - SET(hifi->config, Fsen|Alt); /* alternate reg's... */ - SET(hifi->rof_tm, 0); /* hdlc mode */ - SET(hifi->config, Fsen|Flags); /* normal reg's, send flags */ - }else{ - SET(hifi->tofctl, 0); /* xmit data, msb first */ - SET(hifi->rof_tm, Dri); /* rcv ~data, msb first */ - SET(hifi->config, Fsen|Alt); /* alternate reg's... */ - SET(hifi->rof_tm, Trans); /* transparent mode */ - SET(hifi->config, Fsen); /* normal reg's, send ones */ - } - hp->wenable = 1; - if(hp->hdev == hifi0){ - ip->venval &= ~DXCODEC; - if(hp->hdlc) - ip->venval &= ~DRCODEC; - }else if(hp->hdlc) - SET(hifi->config, Flags); /* no fs on chan. 2 */ - SET(hifi->ttsctl, Dxac); - SET(hifi->opreg, hp->opreg |= Ent); - if(dolock) - isdnunlock(ip); -} - -static void -hifixmitdis(Hifichan *hp, int dolock) -{ - Isdn *ip = hp->udev; - Hifi *hifi = hp->hdev; - - DPRINT("hifixmitdis %d\n", hp-hifichan); - if(dolock) - isdnlock(ip); - SET(hifi->ttsctl, 0); - if(hp->hdev == hifi0){ - ip->venval |= DXCODEC; - if(hp->hdlc) - ip->venval |= DRCODEC; - } - SET(hifi->opreg, hp->opreg &= ~Ent); - hp->out = 0; - hp->ro = hp->wo; - hp->wenable = 0; - /*SET(hifi->opreg, hp->opreg | Tres);*/ - if(dolock) - isdnunlock(ip); -} diff --git a/gnot/devincon.c b/gnot/devincon.c deleted file mode 100644 index 456ff0fd6ba9042c3507bf91e8349a8545447a51..0000000000000000000000000000000000000000 --- a/gnot/devincon.c +++ /dev/null @@ -1,925 +0,0 @@ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "../port/error.h" -#include "devtab.h" - -#include "io.h" -#include "ureg.h" - -typedef struct Incon Incon; -typedef struct Device Device; - -#define NOW (MACHP(0)->ticks*MS2HZ) - -#define MICROSECOND USED(NOW) - -#define DPRINT if(0) - -enum { - Minstation= 2, /* lowest station # to poll */ - Maxstation= 15, /* highest station # to poll */ - Nincon= 1, /* number of incons */ - Nin= 32, /* Blocks in the input ring */ - Bsize= 128, /* size of an input ring block */ - Mfifo= 0xff, /* a mask, must be 2^n-1, must be > Nin */ - - Qstats= 1, /* qid of the statistics file */ -}; - -/* - * incon datakit board - */ -struct Device { - uchar cdata; -#define cpolln cdata - uchar u0; - uchar cstatus; - uchar u1; - uchar creset; - uchar u2; - uchar csend; - uchar u3; - ushort data_cntl; /* data is high byte, cntl is low byte */ - uchar status; -#define cmd status - uchar u5; - uchar reset; - uchar u6; - uchar send; - uchar u7; -}; -#define INCON ((Device *)0x40700000) - -struct Incon { - QLock; - - QLock xmit; /* transmit lock */ - QLock reslock; /* reset lock */ - Device *dev; - int station; /* station number */ - int state; /* chip state */ - Rendez r; /* output process */ - Rendez kr; /* input kernel process */ - ushort chan; /* current input channel */ - Queue *rq; /* read queue */ - int kstarted; /* true if kernel process started */ - - /* input blocks */ - - Block *inb[Nin]; - ushort wi; - ushort ri; - - /* statistics */ - - ulong overflow; /* overflow errors */ - ulong pack0; /* channel 0 */ - ulong crc; /* crc errors */ - ulong in; /* bytes in */ - ulong out; /* bytes out */ - ulong wait; /* wait time in milliseconds */ -}; - -Incon incon[Nincon]; - -/* - * chip state - */ -enum { - Selecting, - Selected, - Notliving, -}; - -/* - * internal chip registers - */ -#define sel_polln 0 -#define sel_station 1 -#define sel_poll0 2 -#define sel_rcv_cnt 3 -#define sel_rcv_tim 4 -#define sel_tx_cnt 5 - -/* - * CSR bits - */ -#define INCON_RUN 0x80 -#define INCON_STOP 0x00 -#define ENABLE_IRQ 0x40 -#define ENABLE_TX_IRQ 0x20 -#define INCON_ALIVE 0x80 -#define TX_FULL 0x10 -#define TX_EMPTY 0x08 -#define RCV_EMPTY 0x04 -#define OVERFLOW 0x02 -#define CRC_ERROR 0x01 - -/* - * polling constants - */ -#define HT_GNOT 0x30 -#define ST_UNIX 0x04 -#define NCHAN 16 - -static void inconkproc(void*); - -/* - * incon stream module definition - */ -static void inconoput(Queue*, Block*); -static void inconstopen(Queue*, Stream*); -static void inconstclose(Queue*); -Qinfo inconinfo = -{ - nullput, - inconoput, - inconstopen, - inconstclose, - "incon" -}; - -int incondebug; - -Dirtab incondir[]={ - "stats", {Qstats}, 0, 0444, -}; - -/* - * set the incon parameters - */ -void -inconset(Incon *ip, int cnt, int del) -{ - Device *dev; - - if (cnt<1 || cnt>14 || del<1 || del>15) - error(Ebadarg); - - dev = ip->dev; - dev->cmd = sel_rcv_cnt | INCON_RUN; - MICROSECOND; - *(uchar *)&dev->data_cntl = cnt; - MICROSECOND; - dev->cmd = sel_rcv_tim | INCON_RUN; - MICROSECOND; - *(uchar *)&dev->data_cntl = del; - MICROSECOND; - dev->cmd = INCON_RUN | ENABLE_IRQ; -} - -/* - * parse a set request - */ -void -inconsetctl(Incon *ip, Block *bp) -{ - char *field[3]; - int n; - int del; - int cnt; - - del = 15; - n = getfields((char *)bp->rptr, field, 3, ' '); - switch(n){ - default: - freeb(bp); - error(Ebadarg); - case 2: - del = strtol(field[1], 0, 0); - if(del<0 || del>15){ - freeb(bp); - error(Ebadarg); - } - /* fall through */ - case 1: - cnt = strtol(field[0], 0, 0); - if(cnt<0 || cnt>15){ - freeb(bp); - error(Ebadarg); - } - } - inconset(ip, cnt, del); - freeb(bp); -} - -static void -nop(void) -{ -} - -/* - * poll for a station number - */ -void -inconpoll(Incon *ip, int station) -{ - ulong timer; - Device *dev; - - dev = ip->dev; - - /* - * get us to a known state - */ - ip->state = Notliving; - dev->cmd = INCON_STOP; - - /* - * try a station number - */ - dev->cmd = sel_station; - *(uchar *)&dev->data_cntl = station; - dev->cmd = sel_poll0; - *(uchar *)&dev->data_cntl = HT_GNOT; - dev->cmd = sel_rcv_cnt; - *(uchar *)&dev->data_cntl = 3; - dev->cmd = sel_rcv_tim; - *(uchar *)&dev->data_cntl = 15; - dev->cmd = sel_tx_cnt; - *(uchar *)&dev->data_cntl = 1; - dev->cmd = sel_polln; - *(uchar *)&dev->data_cntl = 0x00; - *(uchar *)&dev->data_cntl = ST_UNIX; - *(uchar *)&dev->data_cntl = NCHAN; - *(uchar *)&dev->data_cntl = 'g'; - *(uchar *)&dev->data_cntl = 'n'; - *(uchar *)&dev->data_cntl = 'o'; - *(uchar *)&dev->data_cntl = 't'; - dev->cpolln = 0; - - /* - * poll and wait for ready (or 1/4 second) - */ - ip->state = Selecting; - dev->cmd = INCON_RUN | ENABLE_IRQ; - timer = NOW + 250; - while (NOW < timer) { - nop(); - if(dev->status & INCON_ALIVE){ - ip->station = station; - ip->state = Selected; - break; - } - } -} - -/* - * reset the chip and find a new staion number - */ -void -inconrestart(Incon *ip) -{ - int i; - - if(!canqlock(&ip->reslock)) - return; - - /* - * poll for incon station numbers - */ - for(i = Minstation; i <= Maxstation; i++){ - inconpoll(ip, i); - if(ip->state == Selected) - break; - } - switch(ip->state) { - case Selecting: - print("incon[%d] not polled\n", ip-incon); - break; - case Selected: - print("incon[%d] station %d\n", ip-incon, ip->station); - inconset(ip, 3, 15); - break; - default: - print("incon[%d] bollixed\n", ip-incon); - break; - } - qunlock(&ip->reslock); -} - -/* - * reset all incon chips. - */ -void -inconreset(void) -{ - int i; - - incon[0].dev = INCON; - incon[0].state = Selected; - incon[0].ri = incon[0].wi = 0; -/* inconset(&incon[0], 3, 15); /**/ - for(i=1; icmd = INCON_STOP; - incon[i].ri = incon[i].wi = 0; - } -} - -void -inconinit(void) -{ -} - -/* - * enable the device for interrupts, spec is the device number - */ -Chan* -inconattach(char *spec) -{ - Incon *ip; - int i; - Chan *c; - - i = strtoul(spec, 0, 0); - if(i >= Nincon) - error(Ebadarg); - ip = &incon[i]; - if(ip->state != Selected) - inconrestart(ip); - - c = devattach('i', spec); - c->dev = i; - c->qid.path = CHDIR; - c->qid.vers = 0; - return c; -} - -Chan* -inconclone(Chan *c, Chan *nc) -{ - return devclone(c, nc); -} - -int -inconwalk(Chan *c, char *name) -{ - return devwalk(c, name, incondir, 1, streamgen); -} - -void -inconstat(Chan *c, char *dp) -{ - devstat(c, dp, incondir, 1, streamgen); -} - -Chan* -inconopen(Chan *c, int omode) -{ - if(c->qid.path == CHDIR || c->qid.path == Qstats){ - if(omode != OREAD) - error(Eperm); - }else - streamopen(c, &inconinfo); - c->mode = openmode(omode); - c->flag |= COPEN; - c->offset = 0; - return c; -} - -void -inconcreate(Chan *c, char *name, int omode, ulong perm) -{ - USED(c, name, omode, perm); - error(Eperm); -} - -void -inconclose(Chan *c) -{ - if(c->qid.path != CHDIR) - streamclose(c); -} - -long -inconread(Chan *c, void *buf, long n, ulong offset) -{ - char b[256]; - Incon *i; - - if(c->qid.path == CHDIR) - return devdirread(c, buf, n, incondir, 1, streamgen); - else if(c->qid.path == Qstats){ - i = &incon[c->dev]; - sprint(b, "in: %d\nout: %d\noverflow: %d\ncrc: %d\nwait: %d\n", i->in, - i->out, i->overflow, i->crc, i->wait); - return readstr(offset, buf, n, b); - } else - return streamread(c, buf, n); -} - -long -inconwrite(Chan *c, void *buf, long n, ulong offset) -{ - USED(offset); - return streamwrite(c, buf, n, 0); -} - -void -inconremove(Chan *c) -{ - USED(c); - error(Eperm); -} - -void -inconwstat(Chan *c, char *dp) -{ - USED(c, dp); - error(Eperm); -} - -/* - * the stream routines - */ - -/* - * for sleeping while kproc dies - */ -static int -kNotliving(void *arg) -{ - Incon *ip; - - ip = (Incon *)arg; - return ip->kstarted == 0; -} - -/* - * create the kernel process for input - * first wait for any old ones to die - */ -static void -inconstopen(Queue *q, Stream *s) -{ - Incon *ip; - char name[32]; - - ip = &incon[s->dev]; - sprint(name, "incon%d", s->dev); - q->ptr = q->other->ptr = ip; - wakeup(&ip->kr); - sleep(&ip->r, kNotliving, ip); - ip->rq = q; - kproc(name, inconkproc, ip); -} - -/* - * kill off the kernel process - */ -static void -inconstclose(Queue * q) -{ - Incon *ip; - - ip = (Incon *)q->ptr; - qlock(ip); - ip->rq = 0; - qunlock(ip); - wakeup(&ip->kr); - sleep(&ip->r, kNotliving, ip); -} - -/* - * free all blocks of a message in `q', `bp' is the first block - * of the message - */ -static void -freemsg(Queue *q, Block *bp) -{ - for(; bp; bp = getq(q)){ - if(bp->flags & S_DELIM){ - freeb(bp); - return; - } - freeb(bp); - } -} - -/* - * output a block - * - * the first 2 bytes of every message are the channel number, - * low order byte first. the third is a possible trailing control - * character. - */ -void -inconoput(Queue *q, Block *bp) -{ - Device *dev; - Incon *ip; - ulong start, end; - int chan; - int ctl; - int n, size; - - ip = (Incon *)q->ptr; - - if(bp->type != M_DATA){ - if(streamparse("inconset", bp)) - inconsetctl(ip, bp); - else - freeb(bp); - return; - } - if(BLEN(bp) < 3){ - bp = pullup(bp, 3); - if(bp == 0){ - print("inconoput pullup failed\n"); - return; - } - } - - /* - * get a whole message before handing bytes to the device - */ - if(!putq(q, bp)) - return; - - /* - * one transmitter at a time - */ - qlock(&ip->xmit); - dev = ip->dev; - - /* - * parse message - */ - bp = getq(q); - chan = bp->rptr[0] | (bp->rptr[1]<<8); - ctl = bp->rptr[2]; - bp->rptr += 3; - if(chan<=0) - print("bad channel %d\n", chan); - - if(incondebug) - print("->(%d)%uo %d\n", chan, ctl, bp->wptr - bp->rptr); - - /* - * make sure there's an incon out there - */ - if(!(dev->status&INCON_ALIVE) || ip->state==Notliving){ - inconrestart(ip); - freemsg(q, bp); - qunlock(&ip->xmit); - return; - } - - /* - * send the 8 bit data - */ - for(;;){ - /* - * spin till there is room - */ - start = NOW; - for(n = 0, end = start+1000; dev->status & TX_FULL; n++){ - nop(); /* make sure we don't optimize too much */ - if(NOW > end){ - print("incon output stuck\n"); - freemsg(q, bp); - qunlock(&ip->xmit); - return; - } - } - ip->wait = (n + ip->wait)>>1; - - /* - * put in next packet - */ - n = bp->wptr - bp->rptr; - if(n > 16) - n = 16; - size = n; - dev->cdata = chan; - ip->out += n; - while(n--){ - *(uchar *)&dev->data_cntl = *bp->rptr++; - } - - /* - * get next block - */ - if(bp->rptr >= bp->wptr){ - if(bp->flags & S_DELIM){ - freeb(bp); - break; - } - freeb(bp); - bp = getq(q); - if(bp==0) - break; - } - - /* - * end packet - */ - dev->cdata = 0; - } - - /* - * send the control byte if there is one - */ - if(ctl){ - if(size >= 16){ - dev->cdata = 0; - MICROSECOND; - for(end = NOW+1000; dev->status & TX_FULL;){ - nop(); /* make sure we don't optimize too much */ - if(NOW > end){ - print("incon output stuck\n"); - freemsg(q, bp); - qunlock(&ip->xmit); - return; - } - } - dev->cdata = chan; - MICROSECOND; - } - if(dev->status & TX_FULL) - print("inconfull\n"); - dev->cdata = ctl; - } - MICROSECOND; - dev->cdata = 0; - - qunlock(&ip->xmit); - return; -} - -/* - * return true if the raw fifo is non-empty - */ -static int -notempty(void *arg) -{ - Incon *ip; - - ip = (Incon *)arg; - return ip->ri!=ip->wi; -} - -/* - * Read bytes from the raw input circular buffer. - */ -static void -inconkproc(void *arg) -{ - Incon *ip; - Block *bp; - int i; - int locked; - - ip = (Incon *)arg; - ip->kstarted = 1; - - /* - * create a number of blocks for input - */ - for(i = 0; i < Nin; i++){ - bp = ip->inb[i] = allocb(Bsize); - bp->wptr += 3; - } - - locked = 0; - if(waserror()){ - if(locked) - qunlock(ip); - ip->kstarted = 0; - wakeup(&ip->r); - return; - } - - for(;;){ - /* - * sleep if input fifo empty - */ - sleep(&ip->kr, notempty, ip); - - /* - * die if the device is closed - */ - USED(locked); - qlock(ip); - locked = 1; - if(ip->rq == 0){ - qunlock(ip); - ip->kstarted = 0; - wakeup(&ip->r); - poperror(); - return; - } - - /* - * send blocks upstream and stage new blocks. if the block is small - * (< 64 bytes) copy into a smaller buffer. - */ - while(ip->ri != ip->wi){ - bp = ip->inb[ip->ri]; - ip->in += BLEN(bp); - PUTNEXT(ip->rq, bp); - bp = ip->inb[ip->ri] = allocb(Bsize); - bp->wptr += 3; - ip->ri = (ip->ri+1)%Nin; - } - USED(locked); - qunlock(ip); - locked = 0; - } -} - -/* - * drop a single packet - */ -static void -droppacket(Device *dev) -{ - int i; - int c; - - for(i = 0; i < 17; i++){ - c = dev->data_cntl; - if(c==0) - break; - } -} - -/* - * flush the input fifo - */ -static void -flushfifo(Device *dev) -{ - while(!(dev->status & RCV_EMPTY)) - droppacket(dev); -} - -/* - * advance the queue. if we've run out of staged input blocks, - * drop the packet and return 0. otherwise return the next input - * block to fill. - */ -static Block * -nextin(Incon *ip, unsigned int c) -{ - Block *bp; - int next; - - bp = ip->inb[ip->wi]; - bp->rptr[0] = ip->chan; - bp->rptr[1] = ip->chan>>8; - bp->rptr[2] = c; - if(incondebug) - print("<-(%d)%uo %d\n", ip->chan, c, bp->wptr-bp->rptr); - - next = (ip->wi+1)%Nin; - if(next == ip->ri){ - bp->wptr = bp->rptr+3; - return bp; - } - ip->wi = next; - - return ip->inb[ip->wi]; -} - -/* - * read the packets from the device into the staged input blocks. - * we have to do this at interrupt tevel to turn off the interrupts. - */ -static void -rdpackets(Incon *ip) -{ - Block *bp; - unsigned int c; - Device *dev; - uchar *p; - int first = ip->wi; - - dev = ip->dev; - bp = ip->inb[ip->wi]; - if(bp==0){ - flushfifo(ip->dev); - return; - } - p = bp->wptr; - while(!(dev->status & RCV_EMPTY)){ - /* - * get channel number - */ - c = (dev->data_cntl)>>8; - if(c == 0){ - droppacket(dev); - continue; - } - if(ip->chan != c){ - if(p - bp->rptr > 3){ - bp->wptr = p; - bp = nextin(ip, 0); - if(bp==0){ - flushfifo(ip->dev); - return; - } - p = bp->wptr; - } - ip->chan = c; - } - - /* - * null byte marks end of packet - */ - for(;;){ - if((c=dev->data_cntl)&1) { - /* - * data byte, put in local buffer - */ - *p++ = c>>8; - } else if (c>>=8) { - /* - * control byte ends block - */ - bp->wptr = p; - bp = nextin(ip, c); - if(bp==0){ - flushfifo(ip->dev); - return; - } - p = bp->wptr; - } else { - /* end of packet */ - break; - } - } - - /* - * pass a block on if it doesn't have room for one more - * packet. this way we don't have to check per byte. - */ - if(p + 16 > bp->lim){ - bp->wptr = p; - bp = nextin(ip, 0); - p = bp->wptr; - } - } - bp->wptr = p; - if(bp->wptr != bp->rptr+3) - nextin(ip, 0); - - if(first != ip->wi)/**/ - wakeup(&ip->kr); -} - -/* - * Receive an incon interrupt. One entry point - * for all types of interrupt. Until we figure out - * how to use more than one incon, this routine only - * is for incon[0]. - */ -void -inconintr(Ureg *ur) -{ - uchar status; - Incon *ip; - - USED(ur); - ip = &incon[0]; - - status = ip->dev->status; - if(!(status & RCV_EMPTY)) - rdpackets(ip); - - /* check for exceptional conditions */ - if(status&(OVERFLOW|CRC_ERROR)){ - if(status&OVERFLOW) - ip->overflow++; - if(status&CRC_ERROR) - ip->crc++; - } - - /* see if it died underneath us */ - if(!(status&INCON_ALIVE)){ - switch(ip->state){ - case Selected: - ip->dev->cmd = INCON_STOP; - print("Incon died\n"); - break; - case Selecting: - print("rejected\n"); - break; - default: - ip->dev->cmd = INCON_STOP; - break; - } - ip->state = Notliving; - } -} - -void -incontoggle(void) -{ - incondebug ^= 1; -} diff --git a/gnot/devisdn.c b/gnot/devisdn.c deleted file mode 100644 index ef260bf8aea0a22b707af38b799d93989dcca324..0000000000000000000000000000000000000000 --- a/gnot/devisdn.c +++ /dev/null @@ -1,763 +0,0 @@ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "../port/error.h" -#include "devtab.h" - -#include "io.h" -#ifdef SET -#undef SET -#endif -#include "isdn.h" -#include "unite.h" - -#define DPRINT if(isdndebug)kprint - -#define BSIZE 200 /* should be 260, but for xalloc */ - -Isdn * isdndev; -Isdn * isdndevN; - -static void devinit(int); -static void devctl(Isdn*, int, int); -static void devlctl(Isdn*, int); -static void devb1xb2(Isdn*, int); -static void isdnkproc(void*); -static int isdnintr(void); -static int isdnInfo(Isdn*); -static int isdnrecv(Isdn*); -static int isdnxmit(Isdn*); - -enum { - Qdir, Qloop, QInfo, Qb1xb2, Qstats, Qdev, Qdebug -}; - -Dirtab isdndir[]={ - "loop", {Qloop}, 5, 0666, - "info", {QInfo}, 1, 0666, - "b1xb2", {Qb1xb2}, 1, 0666, - "stats", {Qstats}, 0, 0444, - "dev", {Qdev}, 0, 0666, - "debug", {Qdebug}, 0, 0666, -}; -#define NISDN (sizeof isdndir/sizeof(Dirtab)) - -/* - * I.430 stream module definition - */ -static void isdniput(Queue*, Block*); -static void isdnoput(Queue*, Block*); -static void isdnstopen(Queue*, Stream*); -static void isdnstclose(Queue*); -Qinfo isdninfo = { isdniput, isdnoput, isdnstopen, isdnstclose, "isdn" }; - -int venval; -int isdndebug; - -void -isdnreset(void) -{ - isdndev = xalloc(conf.nisdn*sizeof(Isdn)); - isdndevN = &isdndev[conf.nisdn]; -} - -void -isdninit(void) -{} - -Chan* -isdnattach(char *spec) -{ - Chan *c; - int dev; - - if(spec && *spec){ - if(*spec < '0' || *spec > '9') - error(Enonexist); - dev = strtoul(spec, 0, 0); - }else - dev = 0; - if(dev >= conf.nisdn) - error(Enonexist); - if(!isdndev[dev].asr){ - addportintr(isdnintr); - devinit(dev); - } - c = devattach('J', spec); - c->dev = dev; - return c; -} - -Chan* -isdnclone(Chan *c, Chan *nc) -{ - return devclone(c, nc); -} - -int -isdnwalk(Chan *c, char *name) -{ - return devwalk(c, name, isdndir, NISDN, streamgen); -} - -void -isdnstat(Chan *c, char *dp) -{ - devstat(c, dp, isdndir, NISDN, streamgen); -} - -Chan* -isdnopen(Chan *c, int omode) -{ - if(c->qid.path == CHDIR){ - if(omode != OREAD) - error(Eperm); - }else switch(STREAMTYPE(c->qid.path)){ - case Qloop: - case QInfo: - case Qb1xb2: - case Qstats: - case Qdev: - case Qdebug: - break; - default: - DPRINT("isdnopen dev=%d\n", c->dev); - streamopen(c, &isdninfo); - } - c->mode = openmode(omode); - c->flag |= COPEN; - c->offset = 0; - return c; -} - -void -isdncreate(Chan *c, char *name, int omode, ulong perm) -{ - USED(c, name, omode, perm); - error(Eperm); -} - -void -isdnclose(Chan *c) -{ - if(c->qid.path != CHDIR) - streamclose(c); -} - -long -isdnread(Chan *c, void *buf, long n, ulong offset) -{ - Isdn *ip = &isdndev[c->dev]; - char nbuf[512], *p; - int k; - - if(n <= 0) - return 0; - if(c->qid.path == CHDIR){ - return devdirread(c, buf, n, isdndir, NISDN, streamgen); - }else switch(STREAMTYPE(c->qid.path)){ - case Qloop: - sprint(nbuf, "0x%2.2ux ", ip->lctl); - return readstr(offset, buf, n, nbuf); - case QInfo: - if(offset>0) - return 0; - k = isdnpeek(ip, &unite->listat)&Rss; - *(char *)buf = "024L"[k>>2]; - return 1; - case Qb1xb2: - if(offset>0) - return 0; - k = isdnpeek(ip, &unite->stictl)&B1xb2; - *(char *)buf = "01"[k != 0]; - return 1; - case Qstats: - p = nbuf; - p += sprint(p, "inchars %10lud\n", ip->inchars); - p += sprint(p, "badcrc %10lud\n", ip->badcrc); - p += sprint(p, "abort %10lud\n", ip->abort); - p += sprint(p, "overrun %10lud\n", ip->overrun); - p += sprint(p, "badcount %10lud\n", ip->badcount); - p += sprint(p, "overflow %10lud\n", ip->overflow); - p += sprint(p, "toolong %10lud\n", ip->toolong); - p += sprint(p, "underrun %10lud\n", ip->underrun); - p += sprint(p, "outchars %10lud\n", ip->outchars); - USED(p); - return readstr(offset, buf, n, nbuf); - case Qdev: - k = isdnpeek(ip, (void *)ip->devaddr); - sprint(nbuf, "0x%2.2ux = 0x%2.2ux\n", ip->devaddr, k); - return readstr(offset, buf, n, nbuf); - case Qdebug: - sprint(nbuf, "%d\n", isdndebug); - return readstr(offset, buf, n, nbuf); - } - return streamread(c, buf, n); -} - -long -isdnwrite(Chan *c, void *buf, long n, ulong offset) -{ - Isdn *ip = &isdndev[c->dev]; - char nbuf[32], *p; - - if(n <= 0) - return 0; - switch(STREAMTYPE(c->qid.path)){ - case Qloop: - if(offset>0) - return 0; - if (n>sizeof nbuf) - n = sizeof nbuf; - memmove(nbuf, buf, n); - nbuf[n-1] = 0; - devlctl(ip, strtoul(nbuf,0,0)); - return n; - case QInfo: - if(offset>0) - return 0; - switch(*(char *)buf){ - case '0': - case '1': - case '3': - devctl(ip, Tss, *(char *)buf - '0'); - break; - default: - error(Ebadarg); - } - return n; - case Qb1xb2: - if(offset>0) - return 0; - switch(*(char *)buf){ - case '0': - case '1': - devb1xb2(ip, *(char *)buf - '0'); - break; - default: - error(Ebadarg); - } - return n; - case Qdev: - if (n>sizeof nbuf) - n = sizeof nbuf; - memmove(nbuf, buf, n); - nbuf[n-1] = 0; - ip->devaddr = strtoul(nbuf,0,0); - if (p = strchr(nbuf, '=')) /* assign = */ - isdnpoke(ip, (void *)ip->devaddr, strtoul(++p,0,0)); - return n; - case Qdebug: - if (n>sizeof nbuf) - n = sizeof nbuf; - memmove(nbuf, buf, n); - nbuf[n-1] = 0; - isdndebug = strtoul(nbuf,0,0); - return n; - } - return streamwrite(c, buf, n, 0); -} - -void -isdnremove(Chan *c) -{ - USED(c); - error(Eperm); -} - -void -isdnwstat(Chan *c, char *dp) -{ - USED(c, dp); - error(Eperm); -} - -/* - * to sleep, perchance to dream... - */ - -#define Predicate(name, expr) static int name(void *arg) { return expr; } -#define ip ((Isdn *)arg) - -Predicate(kLive, ip->kstart != 0) -Predicate(kDead, ip->kstart == 0) - -Predicate(kRun, !ip->rq || ip->ri != ip->wi || ip->so != ip->ro) - -Predicate(lActive, (ip->listat&Rss)>>1 == 4) - -Predicate(tEmpty, ip->ro == ip->wo) -Predicate(tFull, NEXT(ip->wo) == ip->so) -Predicate(tNotFull, NEXT(ip->wo) != ip->so) - -#undef ip - -/* - * the stream routines - */ - -static void -isdnstopen(Queue *q, Stream *s) -{ - Isdn *ip = &isdndev[s->dev]; - char name[32]; - int rss; - - DPRINT("isdnstopen %d...", s->dev); - qlock(&ip->kctl); - if (ip->kstart) { - qunlock(&ip->kctl); - DPRINT("active\n", s->dev); - return; - } - q->ptr = q->other->ptr = ip; - ip->rq = q; - ip->hangup = 0; - rss = (isdnpeek(ip, &unite->listat)&Rss)>>1; - if (ip->lctl & Lld) /* if loopback D, */ - devctl(ip, Tss, 0); /* transmit INFO 0 */ - else if (rss == 2 || rss ==4) /* else if line active */ - devctl(ip, Tss, 3); /* transmit INFO 3 */ - else - devctl(ip, Tss, 1); /* transmit INFO 1 */ - sprint(name, "isdn%d", s->dev); - kproc(name, isdnkproc, ip); - if (waserror()) { - qunlock(&ip->kctl); - DPRINT("aborted\n"); - nexterror(); - } - sleep(&ip->kctlr, kLive, ip); - qunlock(&ip->kctl); - poperror(); - DPRINT("started\n"); - if (!(ip->lctl & Lld)) { - DPRINT("waiting for INFO 4\n"); - sleep(&ip->ar, lActive, ip); - DPRINT("got INFO 4\n"); - } -} - -static void -isdnstclose(Queue * q) -{ - Isdn *ip = (Isdn *)q->ptr; - DPRINT("isdnstclose %d...", ip-isdndev); - qlock(&ip->kctl); - qlock(ip); - ip->rq = 0; - qunlock(ip); - wakeup(&ip->kr); - if (waserror()) { - qunlock(&ip->kctl); - DPRINT("aborted\n"); - nexterror(); - } - sleep(&ip->kctlr, kDead, ip); - qunlock(&ip->kctl); - poperror(); - DPRINT("stopped\n"); -} - -static void -showframe(char *t, uchar *buf, int n) -{ - kprint("I %s [", t); - while (--n >= 0) - kprint(" %2.2ux", *buf++); - kprint(" ]\n"); -} - -/* - * this is only called by hangup - */ -static void -isdniput(Queue *q, Block *bp) -{ - PUTNEXT(q, bp); -} - -/* - * output a block - */ -static void -isdnoput(Queue *q, Block *bp) -{ - Isdn *ip = (Isdn *)q->ptr; - uchar set, clr; - - if(bp->type != M_DATA){ - set = clr = 0; - if(streamparse("ear", bp)){ - if(streamparse("on", bp)) - set = DRCODEC; - else if(streamparse("off", bp)) - clr = DRCODEC; - }else if(streamparse("mic", bp)){ - if(streamparse("on", bp)) - set = DXCODEC; - else if(streamparse("off", bp)) - clr = DXCODEC; - } - freeb(bp); - isdnlock(ip); - ip->venval &= ~clr; - ip->venval |= set; - *(ip->asr) = ip->venval; - isdnunlock(ip); - return; - } - qlock(&ip->wlock); - if(!putq(q, bp)){ /* send only whole messages */ - qunlock(&ip->wlock); - return; - } - DPRINT("isdnoput: len=%d\n", q->len); - if (tFull(ip)) - sleep(&ip->tr, tNotFull, ip); - ip->outb[ip->wo] = grabq(q); - ip->wo = NEXT(ip->wo); - qunlock(&ip->wlock); - - isdnlock(ip); - if (isdnxmit(ip)) - wakeup(&ip->kr); - isdnunlock(ip); -} - -static void -isdnkproc(void *arg) -{ - Isdn *ip = (Isdn *)arg; - Block *bp; - int i; - - if(waserror()){ - devctl(ip, Enr, 0); - ip->kstart = 0; - wakeup(&ip->kctlr); - return; - } - /* - * create a number of blocks for input - */ - for(i=0; iinb[i]) - ip->inb[i] = allocb(BSIZE); - ip->ri = 0; - ip->wi = 0; - devctl(ip, 0, Enr); - ip->kstart = 1; - wakeup(&ip->kctlr); - for(;;){ - qlock(ip); - if(!ip->rq){ - qunlock(ip); - break; - } - while(ip->ri != ip->wi){ - FLOWCTL(ip->rq, ip->inb[ip->ri]); - ip->inb[ip->ri] = allocb(BSIZE); - ip->ri = NEXT(ip->ri); - } - if(ip->hangup){ - ip->hangup = 0; - bp = allocb(0); - bp->type = M_HANGUP; - PUTNEXT(ip->rq, bp); - } - i = 0; - while(ip->so != ip->ro){ - freeb(ip->outb[ip->so]); - ip->so = NEXT(ip->so); - i++; - } - qunlock(ip); - if (i) - wakeup(&ip->tr); - sleep(&ip->kr, kRun, ip); - } - devctl(ip, Enr, 0); - sleep(&ip->kr, tEmpty, ip); - while(ip->so != ip->ro){ - freeb(ip->outb[ip->so]); - ip->so = NEXT(ip->so); - } - poperror(); - ip->kstart = 0; - wakeup(&ip->kctlr); -} - -void -isdnlock(Isdn *ip) -{ - int s; - - s = spl2(); - lock(&ip->dev); - ip->pri = s; -} - -void -isdnunlock(Isdn *ip) -{ - int s; - - s = ip->pri; - unlock(&ip->dev); - splx(s); -} - -static void -devinit(int h) -{ - Isdn *ip = &isdndev[h]; - - isdnlock(ip); - ip->asr = ISDNDEV0+2*h; - ip->data = ip->asr+1; - ip->venval = DRCODEC | DXCODEC; - SET(unite->reset, Mres); - ip->lctl = 0; /* no loopback or 1's transmission */ - SET(unite->lctl, ip->lctl); - ip->stictl = Prye; /* S/T interface normal */ - SET(unite->stictl, ip->stictl); - SET(unite->itl, 0x88); /* interrupt on 8 rcv/xmit char's */ - SET(unite->hcr, Tpol|Ipol|Clkmux|B2f|B1f); - ip->tctl = Ent; /* enable transmitter, send INFO 0 */ - ip->imask = Richgie|Teie; - SET(unite->tctl, ip->tctl); - SET(unite->imask, ip->imask); - ip->listat = GET(unite->listat); - isdnunlock(ip); -} - -static void -devctl(Isdn *ip, int clear, int set) -{ - isdnlock(ip); - ip->tctl &= ~clear; - ip->tctl |= set; - if (clear & Ent) - ip->imask &= ~Teie; - if (set & Ent) - ip->imask |= Teie; - if (clear & Enr) - ip->imask &= ~(Rfie|Reofie); - if (set & Enr) - ip->imask |= (Rfie|Reofie); - ip->imask |= Richgie; - SET(unite->tctl, ip->tctl); - SET(unite->imask, ip->imask); - isdnunlock(ip); -} - -int -isdnpeek(Isdn *ip, void *arg) -{ - int r; - - isdnlock(ip); - SETADDR(arg); - r = *(ip->data); - isdnunlock(ip); - return r; -} - -void -isdnpoke(Isdn *ip, void *arg, int data) -{ - isdnlock(ip); - SETADDR(arg); - *(ip->data) = data; - isdnunlock(ip); -} - -static void -devlctl(Isdn *ip, int val) -{ - isdnlock(ip); - ip->lctl = val; - SET(unite->lctl, val); - ip->stictl &= ~(Clrmm|Prye); - if (val & Lld) - ip->stictl |= Clrmm; - else - ip->stictl |= Prye; - SET(unite->stictl, ip->stictl); - isdnunlock(ip); -} - -static void -devb1xb2(Isdn *ip, int val) -{ - isdnlock(ip); - if(val) - ip->stictl |= B1xb2; - else - ip->stictl &= ~B1xb2; - SET(unite->stictl, ip->stictl); - isdnunlock(ip); -} - -static int -isdnintr(void) -{ - int status, wake = 0, intr = 0; - Isdn *ip; - - for(ip=isdndev; ipasr) - continue; - if (!(*(ip->asr)&Uint)) - continue; - ++intr; - status = GET(unite->istat); - if (status & Richg) - wake += isdnInfo(ip); - if (status & (Rfull|Reof)) - wake += isdnrecv(ip); - if (status & Tempty) - wake += isdnxmit(ip); - if (wake) - wakeup(&ip->kr); - } - return intr; -} - -static int -isdnInfo(Isdn *ip) -{ - int oldstat, newstat; - - newstat = GET(unite->listat); - DPRINT("isdnInfo: old=0x%2.2ux, new=0x%2.2ux\n", - ip->listat, newstat); - oldstat = (ip->listat&Rss)>>1; - ip->listat = newstat; - if (!ip->rq) { - ip->imask &= ~Richgie; - SET(unite->imask, ip->imask); - return 0; - } - newstat = (newstat&Rss)>>1; - ip->tctl &= ~Tss; - if (newstat == 2 || newstat == 4) - ip->tctl |= 3; /* transmit INFO 3 */ - else - ip->tctl |= 1; /* transmit INFO 1 */ - SET(unite->tctl, ip->tctl); - DPRINT("isdnInfo: tctl=0x%2.2ux\n", ip->tctl); - if(newstat == 4){ - wakeup(&ip->ar); - return 0; - } - if(oldstat == 4){ - ip->hangup = 1; - return 1; - } - return 0; -} - -static int -isdnrecv(Isdn *ip) -{ - Block *bp = ip->inb[ip->wi]; - uchar status, *p; - int i, n, wake = 0; -Loop: - status = GET(unite->rstat); - if (status&Overrun) { - ip->overrun++; - goto Reset; - } - if (!(n = status&Rqs)) - return wake; - p = bp->wptr; - if (p+n > bp->lim) { - ip->toolong++; - goto Reset; - } - ip->inchars += n; - SETADDR(&unite->data); - while (--n >= 0) - *p++ = *(ip->data); - if (status&Eof) { - if (*--p == 0) { - i = NEXT(ip->wi); - if (i == ip->ri) - ip->overflow++; - else { - bp->wptr = p; - bp->flags |= S_DELIM; - ip->wi = i; - bp = ip->inb[i]; - ++wake; - } - } else { - if (*p & 0x80) - ip->badcrc++; - if (*p & 0x40) - ip->abort++; - if (*p & 0x20) - ip->overrun++; - if (*p & 0x10) - ip->badcount++; - } - bp->wptr = bp->base; - bp->rptr = bp->base; - } else - bp->wptr = p; - goto Loop; -Reset: - bp->wptr = bp->base; - bp->rptr = bp->base; - SET(unite->reset, Rres); - return wake; -} - -static int -isdnxmit(Isdn *ip) -{ - Block *bp; - uchar status, *p; - int n, k, wake = 0; -Loop: - status = GET(unite->tstat); - if (status&Undabt) { - ip->underrun++; - SET(unite->reset, Tres); - if (ip->out) { - ip->ro = NEXT(ip->ro); - ip->out = 0; - ++wake; - } - } - if (!(n = status&Tqs)) - return wake; - if (!(bp = ip->out)) { - if (ip->ro == ip->wo) - return wake; - ip->out = bp = ip->outb[ip->ro]; - } - p = bp->rptr; - k = bp->wptr - p; - if (n > k) - n = k; - ip->outchars += n; - SETADDR(&unite->data); - while (--n >= 0) - *(ip->data) = *p++; - bp->rptr = p; - if (bp->rptr == bp->wptr) { - if (bp->flags & S_DELIM) - SET(unite->tctl, ip->tctl|Tfc); - if (!(ip->out = bp = bp->next)) { - ip->ro = NEXT(ip->ro); - ++wake; - } - } - goto Loop; -} diff --git a/gnot/devlbp.c b/gnot/devlbp.c deleted file mode 100644 index 922affbbb0b77db4570f1098b0543bd696d10ce2..0000000000000000000000000000000000000000 --- a/gnot/devlbp.c +++ /dev/null @@ -1,805 +0,0 @@ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "io.h" -#include "../port/error.h" - -#include -#include - -#include "devtab.h" - -#define GSHORT(p) (((p)[0]<<0) | ((p)[1]<<8)) -#define GLONG(p) ((GSHORT(p)<<0) | (GSHORT(p+2)<<16)) -#define PSHORT(p, v) ((p)[0]=(v), (p)[1]=((v)>>8)) -#define PLONG(p, v) (PSHORT(p, (v)), PSHORT(p+2, (v)>>16)) - -#define ISKVA(va) ((ulong)(va)&KZERO) - -typedef struct Lbpfifo { - unsigned long fifo; - unsigned short csr; - unsigned short hblank; -} Lbpfifo; - -enum Csrin { - BINT = 0x0001, VEND = 0x0002, EFL = 0x0004, HFL = 0x0008, - FFL = 0x0010, VSTARTL = 0x0020, - PPRDYL = 0x0100, RDY = 0x0200, SBSY = 0x0400, SCIN = 0x0800, - SCLKIN = 0x1000, VSREQ = 0x2000, -}; - -enum Csrout { - GO = 0x0001, EOL = 0x0002, EFINTEN = 0x0004, HFINTEN = 0x0008, - VCLRL = 0x0010, FOURHDPI = 0x0020, - CPRDYL = 0x0100, PRNT = 0x0200, CBSY = 0x0400, SC = 0x0800, - SCLK = 0x1000, VSYNC = 0x2000, -}; - -#define DPRINT kprint - -#define LBPDEV ((Lbpfifo *)&PORT[56]) - -static ushort csrwval; - -#define CSRW(val) (dev->csr = csrwval = (val)) -#define CSRSET(val) (dev->csr = csrwval |= (val)) -#define CSRCLR(val) (dev->csr = csrwval &= ~(val)) - -#define CMDW(val) (csrwval &= ~(CBSY|SC|SCLK), CSRSET(val)) - -enum { - Inited = 1, - Cmdlocked=2, - Bitlocked=4, - Bitmapped=8 -}; - -typedef struct Lbp { - int fifosize; - ulong flags; - Lock mlock; /* monitor proc active */ - Rendez ready; /* to wake monitor proc */ - QLock cmdlock; /* to send commands */ - int cmdreply; - QLock pagelock; /* to print */ - Rendez printing; /* to wake printing proc */ - Rectangle rect; /* page size */ - ulong *left, lmask, rmask; - int nhblank, width, nvblank, nlines; - Segment *s; /* bitmap may not span segments (BUG) */ - Page *xmap[256]; - Page **x, **xend; - KMap *kmap; - int ihl, maxhl, lcount; - long startclicks, stopclicks; -} Lbp; - -enum Lbpsize { - NHBLANK = 255, NVBLANK = 84, - LBPXMAX = 2424, LBPYMAX = 3262, LBPDOTS = 300, -}; - -typedef struct Lbpconf { - int nhblank, nvblank, xmax, ymax, res; -} Lbpconf; - -static Lbpconf lbpiconf = { - NHBLANK, NVBLANK, LBPXMAX, LBPYMAX, LBPDOTS, -}; -static Lbpconf lbpconf; -static Lbp lbp; -static int cprint0, cprint1; -static ulong pingval; - -enum { - Qdir, Qconf, Qdcmd, Qrcmd, Qmon, Qping, Qbit, Qpage -}; - -Dirtab lbpdir[]={ - "conf", {Qconf}, sizeof(Lbpconf), 0666, - "dcmd", {Qdcmd}, 1, 0666, - "rcmd", {Qrcmd}, 1, 0666, - "mon", {Qmon}, 0, 0666, - "ping", {Qping}, 0, 0666, - "bit", {Qbit}, 0, 0666, - "page", {Qpage}, 0, 0666 -}; -#define NLBP (sizeof lbpdir/sizeof(Dirtab)) - -static int lbpcmd(int); -static long lbppage(Point, GBitmap *, Rectangle); -static void lbpmap(Point, GBitmap *, Rectangle); -static Page * addr2page(ulong); -static void validbitmap(GBitmap *); -static int fillfifo(int); -static int lbpintr(void); - -static void -lbpsetconf(Lbpconf *cp) -{ - lbpconf = *cp; - lbp.rect.max.x = lbpconf.xmax; - lbp.rect.max.y = lbpconf.ymax; - return; -} - -void -lbpreset(void) -{ - lbpsetconf(&lbpiconf); -} - -void -lbpinit(void) -{} - -Chan * -lbpattach(char *param) -{ - Lbpfifo *dev = LBPDEV; - int i, hsize=0, fsize=0; - - addportintr(lbpintr); - if(lbp.fifosize<=0){ - CSRCLR(VCLRL); - CSRSET(VCLRL); - for(i=0; i<20000; i+=4){ - dev->fifo = 0; - if(!hsize && (dev->csr&HFL) == 0) - hsize = i+4; - if((dev->csr&FFL) == 0){ - fsize = i+4; - break; - } - } - /*pprint("lbpattach: hsize=%d, fsize=%d\n", hsize, fsize);*/ - lbp.fifosize = fsize; - } - return devattach('l', param); -} - -Chan * -lbpclone(Chan *c, Chan *nc) -{ - return devclone(c, nc); -} - -int -lbpwalk(Chan *c, char *name) -{ - return devwalk(c, name, lbpdir, NLBP, devgen); -} - -void -lbpstat(Chan *c, char *db) -{ - devstat(c, db, lbpdir, NLBP, devgen); -} - -Chan * -lbpopen(Chan *c, int omode) -{ - switch ((int)(c->qid.path & ~CHDIR)) { - /*case Qcmd:*/ - case Qbit: - case Qpage: - if (!(lbp.flags & Inited)) { - lbp.cmdreply = lbpcmd(0x40); - lbp.flags |= Inited; - } - break; - } - return devopen(c, omode, lbpdir, NLBP, devgen); -} - -void -lbpcreate(Chan *c, char *name, int omode, ulong perm) -{ - USED(c, name, omode, perm); - error(Eperm); -} - -void -lbpclose(Chan *c) -{ - USED(c); -} - -long -lbpread(Chan *c, void *va, long n, ulong offset) -{ - uchar *a = (uchar *)va; - if (n == 0) - return 0; - switch ((int)(c->qid.path & ~CHDIR)) { - case Qdir: - return devdirread(c, va, n, lbpdir, NLBP, devgen); - case Qconf: - if (offset >= 20) - return 0; - if (n < 20) - error(Etoosmall); - PLONG(&a[ 0], lbpconf.nhblank); - PLONG(&a[ 4], lbpconf.nvblank); - PLONG(&a[ 8], lbpconf.xmax); - PLONG(&a[12], lbpconf.ymax); - PLONG(&a[16], lbpconf.res); - n = 20; - break; - case Qdcmd: - *a = cprint1; - n = 1; - break; - case Qrcmd: - if (lbp.cmdreply > 0) - *a = lbp.cmdreply, n = 1; - else - n = 0; - break; - case Qmon: - if (canlock(&lbp.mlock)) { - sleep(&lbp.ready, return0, 0); - unlock(&lbp.mlock); - } else - error(Einuse); - n = 0; - break; - case Qping: - if (n != sizeof(ulong)) - n = 0; - else - *(ulong *)a = pingval; - break; - case Qbit: - case Qpage: - n = 0; - break; - } - return n; -} - -#define OKRECT(r) ((r).min.x<(r).max.x && (r).min.y<(r).max.y) -#define PTINRECT(p, r) ((r).min.x<=(p).x && (r).min.y<=(p).y && \ - (p).x<=(r).max.x && (p).y<=(r).max.y) -#define RINRECT(r, s) (PTINRECT((r).min, s) && PTINRECT((r).max, s)) - -long -lbpwrite(Chan *c, void *va, long n, ulong offset) -{ - uchar *a = (uchar *)va; - extern GBitmap *id2bit(int); - Point p; GBitmap *bp; Rectangle r; - Lbpconf tc; - int k, m = 0; - if (n == 0) - return 0; - switch ((int)c->qid.path) { - case Qconf: - if (offset >= 20) - return 0; - if (n < 20) - error(Etoosmall); - tc.nhblank = GLONG(&a[ 0]); - tc.nvblank = GLONG(&a[ 4]); - tc.xmax = GLONG(&a[ 8]); - tc.ymax = GLONG(&a[12]); - tc.res = GLONG(&a[16]); - lbpsetconf(&tc); - m = 20; - break; - case Qdcmd: - cprint1 = *a ? PRNT : 0; - m = 1; - break; - case Qrcmd: - lbp.cmdreply = lbpcmd(*a); - m = 1; - break; - case Qmon: - wakeup(&lbp.ready); - m = 0; - break; - case Qping: - if (n != sizeof(ulong)) - m = 0; - else { - Lbpfifo *dev = LBPDEV; - dev->fifo = *(ulong *)a; - pingval = dev->fifo; - m = sizeof(ulong); - } - break; - case Qbit: - case Qpage: - if (n != 28) - error(Ebadarg); - p.x = GLONG(&a[0]); - p.y = GLONG(&a[4]); - if (c->qid.path == Qbit) - bp = id2bit(GLONG(&a[8])); - else { - bp = (GBitmap *)GLONG(&a[8]); - validbitmap(bp); - } - r.min.x = GLONG(&a[12]); - r.min.y = GLONG(&a[16]); - r.max.x = GLONG(&a[20]); - r.max.y = GLONG(&a[24]); - DPRINT("lbpwrite: ckpage..."); - if ((k = lbp.rect.min.x - p.x) > 0) - r.min.x += k, p.x += k; - if ((k = lbp.rect.min.y - p.y) > 0) - r.min.y += k, p.y += k; - if ((k = Dx(r) + p.x - lbp.rect.max.x) > 0) - r.max.x -= k; - if ((k = Dy(r) + p.y - lbp.rect.max.y) > 0) - r.max.y -= k; - if (!OKRECT(r) || !RINRECT(r, bp->r)) - error(Ebadblt); - DPRINT("OK\n"); - m = lbppage(p, bp, r); - /*pprint("lbpwrite: %d clicks\n", m);*/ - break; - default: - panic("lbpwrite"); - } - return m; -} - -void -lbpremove(Chan *c) -{ - USED(c); - error(Eperm); -} - -void -lbpwstat(Chan *c, char *dp) -{ - USED(c, dp); - error(Eperm); -} - -static short poot, hoot; -#define MICROSECOND (poot=0, hoot=0); USED(poot, hoot) -#define TLIMIT 0x3fffff - -static void -lbpwait(int set, int clear, long timeout) -{ - Lbpfifo *dev = LBPDEV; - int status; long i=0; - - if(timeout <= 0) - timeout = TLIMIT; - timeout += m->ticks; - do{ - status = dev->csr; - if((status & set) == set && (status & clear) == 0){ - DPRINT("OK lbpwait(pid=%d,i=%d)...", u->p->pid, i); - return; - } - if((i++ % 32768) == 0) - DPRINT("lbpwait(pid=%d,i=%d)...", u->p->pid, i-1); - sched(); - if(u->p->notepending){ - u->p->notepending = 0; - DPRINT("intr lbpwait(pid=%d,i=%d)\n", u->p->pid, i); - error(Eintr); - } - }while(m->ticks < timeout); - DPRINT("timeout lbpwait(pid=%d,i=%d)\n", u->p->pid, i); - error(Eio); -} - -static int -lbpcmd(int cmd) -{ - Lbpfifo *dev = LBPDEV; - int mask = 0x80, status; - - qlock(&lbp.cmdlock); - if (waserror()) { - qunlock(&lbp.cmdlock); - nexterror(); - } - lbpwait(0, (PPRDYL|SBSY|SC|SCLK), 600); - - CMDW(CBSY); /* cbsy asserted */ - do { - if (cmd & mask) { - CMDW(CBSY|SCLK|SC); /* clock up, data 1 */ - MICROSECOND; - CMDW(CBSY|SC); /* clock down, data 1 */ - MICROSECOND; - } else { - CMDW(CBSY|SCLK); /* clock up, data 0 */ - MICROSECOND; - CMDW(CBSY); /* clock down, data 0 */ - MICROSECOND; - } - } while (mask >>= 1); - CMDW(0); /* release cbsy, clock, data */ - - lbpwait(SBSY, 0, 120); /* wait for sbsy */ - sched(); /* wait >1 msec */ - - status = 0; - mask = 0x80; do { - int temp; - CMDW(SCLK); /* clock up */ - MICROSECOND; - CMDW(0); /* clock down */ - MICROSECOND; - temp = dev->csr; - if (temp & SC) - status |= mask; - } while (mask >>= 1); - - DPRINT("lbp: cmd = 0x%x, status = 0x%x\n", cmd, status); - poperror(); - qunlock(&lbp.cmdlock); - return status; -} - -#define WORDSIZE 32 - -/*extern ulong _topbits[];*/ - -static ulong _topbits[]={ - 0x00000000, 0x80000000, 0xc0000000, 0xe0000000, - 0xf0000000, 0xf8000000, 0xfc000000, 0xfe000000, - 0xff000000, 0xff800000, 0xffc00000, 0xffe00000, - 0xfff00000, 0xfff80000, 0xfffc0000, 0xfffe0000, - 0xffff0000, 0xffff8000, 0xffffc000, 0xffffe000, - 0xfffff000, 0xfffff800, 0xfffffc00, 0xfffffe00, - 0xffffff00, 0xffffff80, 0xffffffc0, 0xffffffe0, - 0xfffffff0, 0xfffffff8, 0xfffffffc, 0xfffffffe, - 0xffffffff, -}; - -#define PBASE(va) (((ulong)(va)) & ~(BY2PG-1)) -#define POFFSET(va) (((ulong)(va)) & (BY2PG-1)) - -static void -lbpmap(Point p, GBitmap *bp, Rectangle r) -{ - ulong *left, *right; ulong j; - int i, lbits, rbits; - - if ((lbits = r.min.x%WORDSIZE) < 0) - lbits += WORDSIZE; - if ((rbits = r.max.x%WORDSIZE) < 0) - rbits += WORDSIZE; - lbp.lmask = lbits ? ~_topbits[lbits] : 0; - lbp.rmask = rbits ? _topbits[rbits] : 0; - lbp.nhblank = 0xff00-(lbpconf.nhblank - lbits + p.x); - if (lbp.nhblank < 0) - lbp.nhblank = 0; - else if (lbp.nhblank > 0xfeff) - lbp.nhblank = 0xfeff; - left = gaddr(bp, r.min); - right = gaddr(bp, Pt(r.max.x-1, r.min.y)); - lbp.left = left; - lbp.maxhl = right - left; - lbp.width = bp->width; - lbp.nvblank = lbpconf.nvblank + p.y; - lbp.nlines = lbp.nvblank + Dy(r); - DPRINT("lbpmap: nvblank=%d, nlines=%d\n", lbp.nvblank, lbp.nlines); - lbp.ihl = 0; - lbp.lcount = 0; - - lbp.x = lbp.xend = lbp.xmap; - lbp.s = 0; - if (ISKVA(left)) - return; - lbp.s = seg(u->p, (ulong)left, 1); - if (!lbp.s) - error(Ebadarg); - lbp.s->steal++; - qunlock(&lbp.s->lk); - if (waserror()){ - qlock(&lbp.s->lk); - lbp.s->steal--; - qunlock(&lbp.s->lk); - error(Ebadarg); - } - - for (i=r.min.y; iwidth, right+=bp->width) { - for (j=PBASE(left); j<=PBASE(right); j+=BY2PG) { - if (lbp.xend > lbp.xmap && j <= lbp.xend[-1]->va) - continue; - /*DPRINT("probing 0x%lux\n", j);*/ - *lbp.xend++ = addr2page(j); - } - } - poperror(); -} - -Page * -addr2page(ulong addr) -{ - Segment *s; long soff; Pte *pte; Page *pg = 0; - - poot = *(ulong *)addr; /* fault it if necessary */ - s = seg(u->p, addr, 1); - if(s != lbp.s) - error(Ebadarg); - soff = addr-s->base; - pte = s->map[soff/PTEMAPMEM]; - if(pte) - pg = pte->pages[(soff&(PTEMAPMEM-1))/BY2PG]; - - if(pg == 0){ - qunlock(&s->lk); - pprint("nonresident page addr %lux (complain to rob)\n", addr); - error(Eio); - } - qunlock(&s->lk); - return pg; -} - -static void -validbitmap(GBitmap *bp) -{ - ulong tl, br; - validaddr((ulong)bp, sizeof(GBitmap), 0); - if (((ulong)bp->base&3) || bp->width<=0 || bp->ldepth!=0 || !OKRECT(bp->r)) - error(Ebadbitmap); - tl = (ulong)gaddr(bp, bp->r.min); - br = (ulong)gaddr(bp, bp->r.max); - validaddr(tl, br-tl, 0); -} - -static long -lbppage(Point p, GBitmap *bp, Rectangle r) -{ - extern QLock bitlock; - Lbpfifo *dev = LBPDEV; - long dt; - - if (csrwval & (PRNT|GO)) { - cprint0 = PRNT; - if (!(csrwval & PRNT)) - CSRSET(PRNT); - } - DPRINT("lbppage: qlock %d...\n", u->p->pid); - qlock(&lbp.pagelock); - DPRINT("...%d OK\n", u->p->pid); - if(waserror()){ - if(lbp.flags & Bitmapped){ - lbp.flags &= ~Bitmapped; - kunmap(lbp.kmap); - qlock(&lbp.s->lk); - lbp.s->steal--; - qunlock(&lbp.s->lk); - } - if(lbp.flags & Bitlocked){ - lbp.flags &= ~Bitlocked; - qunlock(&bitlock); - } - if(lbp.flags & Cmdlocked){ - lbp.flags &= ~Cmdlocked; - qunlock(&lbp.cmdlock); - } - qunlock(&lbp.pagelock); - nexterror(); - } - cprint0 = lbp.pagelock.head ? PRNT : 0; - - if (dev->csr & PPRDYL) { - CSRW(0); - pprint("printer power not ready\n"); - error(Eio); - } - if (!(dev->csr & RDY)) { - DPRINT("lbpprt: not ready, waiting..."); - wakeup(&lbp.ready); - lbpwait(RDY, 0, 0x7fffffffL); /* wait for rdy */ - DPRINT("OK\n"); - } - - qlock(&lbp.cmdlock); - lbp.flags |= Cmdlocked; - if(ISKVA(bp->base)){ - qlock(&bitlock); - lbp.flags |= Bitlocked; - } - lbpmap(p, bp, r); - if(!ISKVA(bp->base)){ - lbp.kmap = kmap(lbp.xmap[0]); - lbp.flags |= Bitmapped; - } - DPRINT("lbpprt: filling fifo..."); - CSRCLR(VCLRL); /* clear fifo */ - CSRSET(VCLRL); - dev->hblank = lbp.nhblank; /* left margin */ - if (fillfifo(lbp.fifosize)) /* did all the data fit ? */ - CSRSET(EFINTEN); /* yes, interrupt when fifo empty */ - else - CSRSET(HFINTEN|EFINTEN);/* no, interrupt when half-empty */ - DPRINT("OK\n"); - CSRSET(PRNT); /* assert prnt */ - DPRINT("(PRNT 0x%4.4x)...", csrwval); - lbpwait(VSREQ, 0, 0L); /* wait for vsreq */ - DPRINT("VSREQ+..."); - - DPRINT("(VSYNC)..."); - CSRSET(VSYNC); /* now give him vsync */ - - lbpwait(0, VSREQ, 0L); /* wait for ack (vsreq goes away) */ - DPRINT("VSREQ-..."); - csrwval &= ~(FOURHDPI|PRNT|VSYNC); - if (lbpconf.res == 400) - CSRSET(FOURHDPI|cprint0|cprint1|GO); - else - CSRSET(cprint0|cprint1|GO); - DPRINT("lbpprt: ready, ticks=%d\n", m->ticks); - qunlock(&lbp.cmdlock); - lbp.flags &= ~Cmdlocked; - lbp.startclicks = 0; - lbp.stopclicks = 0; - sleep(&lbp.printing, return0, 0); - if(ISKVA(bp->base)){ - qunlock(&bitlock); - lbp.flags &= ~Bitlocked; - }else{ - kunmap(lbp.kmap); - qlock(&lbp.s->lk); - lbp.s->steal--; - qunlock(&lbp.s->lk); - lbp.flags &= ~Bitmapped; - } - dt = lbp.stopclicks - lbp.startclicks; - DPRINT("lbpprt: lcount=%d, nlines=%d\n", lbp.lcount, lbp.nlines); - DPRINT("lbpprt: start=%d, stop=%d, dt=%d\n", - lbp.startclicks, lbp.stopclicks, dt); - qunlock(&lbp.pagelock); - poperror(); - return dt; -} - -static int -fillfifo(int nfifo) -{ - Lbpfifo *dev = LBPDEV; - ulong *up, *kp; - int nout, npg; - if (lbp.lcount < lbp.nvblank) { - nout = lbp.nvblank - lbp.lcount; - if (nout > nfifo) - nout = nfifo; - nfifo -= nout; - lbp.lcount += nout; - CSRSET(EOL); - while (--nout >= 0) - *(char *)&dev->fifo = 0; - CSRCLR(EOL); - } - while (nfifo > sizeof(ulong)) { - up = lbp.left + lbp.ihl; - if (ISKVA(up)) - kp = up; - else { - while (PBASE(up) > (*lbp.x)->va) - ++lbp.x; - lbp.kmap->pa = (*lbp.x)->pa; - putkmmu(lbp.kmap->va, PPN(lbp.kmap->pa) | PTEVALID | PTEKERNEL); - kp = (ulong *)(lbp.kmap->va + POFFSET(up)); - } - if (lbp.ihl == 0 && lbp.lmask) { - dev->fifo = *kp & lbp.lmask; - ++lbp.ihl, nfifo -= sizeof(ulong); - } else if (lbp.ihl == lbp.maxhl && lbp.rmask) { - dev->fifo = *kp & lbp.rmask; - ++lbp.ihl, nfifo -= sizeof(ulong); - } else { - nout = lbp.maxhl - lbp.ihl + (lbp.rmask == 0); - npg = (BY2PG - POFFSET(up))/BY2WD; - if (nout > npg) - nout = npg; - if (nout > nfifo/sizeof(ulong)) - nout = nfifo/sizeof(ulong); - lbp.ihl += nout; - nfifo -= nout*sizeof(ulong); - while(--nout >= 0) - dev->fifo = *kp++; - } - if (lbp.ihl > lbp.maxhl) { - CSRSET(EOL); - *(char *)&dev->fifo = 0; - CSRCLR(EOL); - --nfifo; - lbp.ihl = 0; - lbp.left += lbp.width; - if (++lbp.lcount >= lbp.nlines) - return 1; - } - } - return 0; -} - -/*static int -fillfifo(int nfifo) -{ - Lbpfifo *dev = LBPDEV; - ulong *up; - int nout, npg; - if (lbp.lcount < lbp.nvblank) { - nout = lbp.nvblank - lbp.lcount; - if (nout > nfifo) - nout = nfifo; - nfifo -= nout; - lbp.lcount += nout; - CSRSET(EOL); - while (--nout >= 0) - *(char *)&dev->fifo = 0; - CSRCLR(EOL); - } - while (nfifo > sizeof(ulong)) { - up = lbp.left + lbp.ihl; - if (lbp.ihl == 0 && lbp.lmask) { - dev->fifo = *up & lbp.lmask; - ++lbp.ihl, nfifo -= sizeof(ulong); - } else if (lbp.ihl == lbp.maxhl && lbp.rmask) { - dev->fifo = *up & lbp.rmask; - ++lbp.ihl, nfifo -= sizeof(ulong); - } else { - nout = lbp.maxhl - lbp.ihl + (lbp.rmask == 0); - if (nout > nfifo/sizeof(ulong)) - nout = nfifo/sizeof(ulong); - lbp.ihl += nout; - nfifo -= nout*sizeof(ulong); - while (--nout >= 0) - dev->fifo = *up++; - } - if (lbp.ihl > lbp.maxhl) { - CSRSET(EOL); - *(char *)&dev->fifo = 0; - CSRCLR(EOL); - --nfifo; - lbp.ihl = 0; - lbp.left += lbp.width; - if (++lbp.lcount >= lbp.nlines) - return 1; - } - } - return 0; -} -*/ - -static int -lbpintr(void) -{ - Lbpfifo *dev = LBPDEV; - ushort csr = dev->csr; - if (!(csr & BINT)) { - /*print("lbpintr: no BINT 0x%x\n", csr);*/ - return 1/*0*/; - } - if (!lbp.printing.p) { - csr = dev->csr; - CSRCLR(HFINTEN|EFINTEN|GO); - if(csr & BINT) - print("spurious lbpintr: 0x%4.4ux\n", csr); - return 1; - } - if (!(csr & EFL)) { - lbp.stopclicks = m->ticks; - CSRCLR(HFINTEN|EFINTEN|GO); - wakeup(&lbp.printing); - } else if (csr & HFL) { - if (!lbp.startclicks) - lbp.startclicks = m->ticks; - if (fillfifo(lbp.fifosize/2)) { /* did all the data fit ? */ - csrwval &= ~HFINTEN; - CSRSET(EFINTEN); /* yes, interrupt when fifo empty */ - } - } else { - print("null lbpintr: 0x%4.4ux\n", csr); - } - return 1; -} diff --git a/gnot/devport.c b/gnot/devport.c deleted file mode 100644 index 1aeda20e7acedbe912adee7c38cc83149614bce5..0000000000000000000000000000000000000000 --- a/gnot/devport.c +++ /dev/null @@ -1,262 +0,0 @@ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "io.h" -#include "../port/error.h" - -#include "devtab.h" - -#define ROMADDR 0x40000000 -#define ROMSIZE ((256*1024)/8) - -#define P_qlock(sel) if(sel >= 0){\ - qlock(&portpage);\ - PORTSELECT = portpage.select = sel;\ - }else - -#define P_qunlock(sel) if(sel >= 0){\ - qunlock(&portpage);\ - }else - -#define P_oper(sel, inst) P_qlock(sel); inst; P_qunlock(sel) -#define P_read(sel, addr, val, type) P_oper(sel, val = *(type *)(PORT+addr)) -#define P_write(sel, addr, val, type) P_oper(sel, *(type *)(PORT+addr) = val) - -enum -{ - Qdir, - Qdata, - Qrom -}; - -Dirtab portdir[]={ - "data", {Qdata}, 0, 0666, - "rom", {Qrom}, ROMSIZE, 0444, -}; - -#define NPORT (sizeof portdir/sizeof(Dirtab)) - -#define Nportservice 8 -static int (*portservice[Nportservice])(void); - Portpage portpage; -static Lock intrlock; - -int -portprobe(char *what, int select, int addr, int rw, long val) -{ - int time; - if (!conf.portispaged) - return 0; - P_qlock(select); - switch (rw) { - case -1: - val = *(uchar *)(PORT+addr); - break; - case -2: - val = *(ushort *)(PORT+addr); - break; - case -4: - val = *(long *)(PORT+addr); - break; - case 1: - *(uchar *)(PORT+addr) = val; - break; - case 2: - *(ushort *)(PORT+addr) = val; - break; - case 4: - *(long *)(PORT+addr) = val; - break; - default: - panic("portprobe"); - } - time = PORTSELECT & 0x1f; - P_qunlock(select); - if (what) { - print("%s at %d, %d", what, select, addr); - print("%s", time & 0x10 ? " -- NOT FOUND\n" : "\n"); - } - if (time & 0x10) - return -1; - return val; -} - -void -portreset(void) -{ - portpage.select = -1; - lock(&portpage); - unlock(&portpage); -} - -void -portinit(void) -{ -} - -Chan * -portattach(char *param) -{ - return devattach('x', param); -} - -Chan * -portclone(Chan *c, Chan *nc) -{ - return devclone(c, nc); -} - -int -portwalk(Chan *c, char *name) -{ - return devwalk(c, name, portdir, NPORT, devgen); -} - -void -portstat(Chan *c, char *db) -{ - devstat(c, db, portdir, NPORT, devgen); -} - -Chan * -portopen(Chan *c, int omode) -{ - return devopen(c, omode, portdir, NPORT, devgen); -} - -void -portcreate(Chan *c, char *name, int omode, ulong perm) -{ - USED(c, name, omode, perm); - error(Eperm); -} - -void -portclose(Chan *c) -{ - USED(c); -} - -long -portread(Chan *c, char *a, long n, ulong offset) -{ - long s, k; - if (n == 0) - return 0; - switch ((int)(c->qid.path & ~CHDIR)) { - case Qdir: - return devdirread(c, a, n, portdir, NPORT, devgen); - case Qdata: - if (!conf.portispaged || (s = offset >> PORTSHIFT) > 0xff) - s = -1; - k = offset % PORTSIZE; - P_qlock(s); - switch ((int)n) { - case 1: - *a = PORT[k]; break; - case 2: - *(short *)a = *(short *)(PORT+k); break; - case 4: - *(long *)a = *(long *)(PORT+k); break; - default: - P_qunlock(s); - error(Ebadarg); - } - P_qunlock(s); - break; - case Qrom: - if(offset >= ROMSIZE) - return 0; - if(offset+n > ROMSIZE) - n = ROMSIZE - offset; - memmove(a, ((char*)ROMADDR)+offset, n); - return n; - break; - default: - panic("portread"); - } - return n; -} - -long -portwrite(Chan *c, char *a, long n, ulong offset) -{ - long s, k; - if (n == 0) - return 0; - switch ((int)c->qid.path) { - case Qdata: - if (!conf.portispaged || (s = offset >> PORTSHIFT) > 0xff) - s = -1; - k = offset % PORTSIZE; - P_qlock(s); - switch ((int)n) { - case 1: - PORT[k] = *a; break; - case 2: - *(short *)(PORT+k) = *(short *)a; - break; - case 4: - *(long *)(PORT+k) = *(long *)a; - break; - default: - P_qunlock(s); - error(Ebadarg); - } - P_qunlock(s); - break; - default: - panic("portwrite"); - } - return n; -} - -void -portremove(Chan *c) -{ - USED(c); - error(Eperm); -} - -void -portwstat(Chan *c, char *dp) -{ - USED(c, dp); - error(Eperm); -} - -void -addportintr(int (*f)(void)) -{ - int s = splhi(); - int (**p)(void); - - lock(&intrlock); - for (p=portservice; *p; p++) - if (*p == f) - goto out; - if (p >= &portservice[Nportservice-1]) - panic("addportintr"); - *p = f; -out: - unlock(&intrlock); - splx(s); -} - -void -devportintr(void) -{ - int (**p)(void); - int i = 0; - - for (p=portservice; *p; p++) - i |= (**p)(); - - if (!i) - /*putstring("spurious portintr\n");*/ - panic("portintr"); - if (portpage.select >= 0) - PORTSELECT = portpage.select; -} diff --git a/gnot/disk.c b/gnot/disk.c deleted file mode 100644 index 4892094ebe6ac5c301e821a293dd0f444047d1b0..0000000000000000000000000000000000000000 --- a/gnot/disk.c +++ /dev/null @@ -1,55 +0,0 @@ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "../port/error.h" - -#include "devtab.h" - -#include "fcall.h" - -Dev devtab[]={ - { rootreset, rootinit, rootattach, rootclone, rootwalk, rootstat, rootopen, rootcreate, - rootclose, rootread, rootwrite, rootremove, rootwstat, }, - { consreset, consinit, consattach, consclone, conswalk, consstat, consopen, conscreate, - consclose, consread, conswrite, consremove, conswstat, }, - { envreset, envinit, envattach, envclone, envwalk, envstat, envopen, envcreate, - envclose, envread, envwrite, envremove, envwstat, }, - { pipereset, pipeinit, pipeattach, pipeclone, pipewalk, pipestat, pipeopen, pipecreate, - pipeclose, piperead, pipewrite, piperemove, pipewstat, }, - { procreset, procinit, procattach, procclone, procwalk, procstat, procopen, proccreate, - procclose, procread, procwrite, procremove, procwstat, }, - { srvreset, srvinit, srvattach, srvclone, srvwalk, srvstat, srvopen, srvcreate, - srvclose, srvread, srvwrite, srvremove, srvwstat, }, - { mntreset, mntinit, mntattach, mntclone, mntwalk, mntstat, mntopen, mntcreate, - mntclose, mntread, mntwrite, mntremove, mntwstat, }, - { inconreset, inconinit, inconattach, inconclone, inconwalk, inconstat, inconopen, inconcreate, - inconclose, inconread, inconwrite, inconremove, inconwstat, }, - { dkreset, dkinit, dkattach, dkclone, dkwalk, dkstat, dkopen, dkcreate, - dkclose, dkread, dkwrite, dkremove, dkwstat, }, - { dupreset, dupinit, dupattach, dupclone, dupwalk, dupstat, dupopen, dupcreate, - dupclose, dupread, dupwrite, dupremove, dupwstat, }, - { bitreset, bitinit, bitattach, bitclone, bitwalk, bitstat, bitopen, bitcreate, - bitclose, bitread, bitwrite, bitremove, bitwstat, }, - { portreset, portinit, portattach, portclone, portwalk, portstat, portopen, portcreate, - portclose, portread, portwrite, portremove, portwstat, }, - { scsireset, scsiinit, scsiattach, scsiclone, scsiwalk, scsistat, scsiopen, scsicreate, - scsiclose, scsiread, scsiwrite, scsiremove, scsiwstat, }, - { wrenreset, wreninit, wrenattach, wrenclone, wrenwalk, wrenstat, wrenopen, wrencreate, - wrenclose, wrenread, wrenwrite, wrenremove, wrenwstat, }, - { duartreset, duartinit, duartattach, duartclone, duartwalk, duartstat, duartopen, duartcreate, - duartclose, duartread, duartwrite, duartremove, duartwstat, }, -}; -char devchar[]="/ce|psMikdbxSwt"; -extern Qinfo urpinfo; -extern Qinfo asyncinfo; -extern Qinfo fcallinfo; -void streaminit0(void){ - newqinfo(&urpinfo); - newqinfo(&asyncinfo); - newqinfo(&fcallinfo); -} - #include "cfs.h" - #include "kfs.h" - void kproftimer(ulong pc){} diff --git a/gnot/fault68020.c b/gnot/fault68020.c deleted file mode 100644 index 8f2b1fd7025840b06ee72058106c1b7121f1268e..0000000000000000000000000000000000000000 --- a/gnot/fault68020.c +++ /dev/null @@ -1,104 +0,0 @@ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "ureg.h" -#include "../port/error.h" - -#define FORMAT(ur) ((((ur)->vo)>>12)&0xF) -#define OFFSET(ur) (((ur)->vo)&0xFFF) - - -struct FFrame -{ - ushort ireg0; /* internal register */ - ushort ssw; /* special status word */ - ushort ipsc; /* instr. pipe stage c */ - ushort ipsb; /* instr. pipe stage b */ - ulong addr; /* data cycle fault address */ - ushort ireg1; /* internal register */ - ushort ireg2; /* internal register */ - ulong dob; /* data output buffer */ - ushort ireg3[4]; /* more stuff */ - ulong baddr; /* stage b address */ - ushort ireg4[26]; /* more more stuff */ -}; - -/* - * SSW bits - */ -#define RW 0x0040 /* read/write for data cycle */ -#define FC 0x8000 /* fault on stage C of instruction pipe */ -#define FB 0x4000 /* fault on stage B of instruction pipe */ -#define RC 0x2000 /* rerun flag for stage C of instruction pipe */ -#define RB 0x1000 /* rerun flag for stage B of instruction pipe */ -#define DF 0x0100 /* fault/rerun flag for data cycle */ -#define RM 0x0080 /* read-modify-write on data cycle */ -#define READ 0x0040 -#define WRITE 0x0000 -#define SIZ 0x0030 /* size code for data cycle */ -#define FC2 0x0004 /* address space for data cycle */ -#define FC1 0x0002 -#define FC0 0x0001 - -void -fault68020(Ureg *ur, FFrame *f) -{ - ulong addr, badvaddr; - int user, read, insyscall; - char buf[ERRLEN]; - - if(u == 0){ - dumpregs(ur); - panic("fault u==0 pc=%lux", ur->pc); - } - insyscall = u->p->insyscall; - u->p->insyscall = 1; - addr = 0; /* set */ - if(f->ssw & DF) - addr = f->addr; - else if(FORMAT(ur) == 0xA){ - if(f->ssw & FC) - addr = ur->pc+2; - else if(f->ssw & FB) - addr = ur->pc+4; - else - panic("prefetch pagefault"); - }else if(FORMAT(ur) == 0xB){ - if(f->ssw & FC) - addr = f->baddr-2; - else if(f->ssw & FB) - addr = f->baddr; - else - panic("prefetch pagefault"); - }else - panic("prefetch format"); - - addr &= VAMASK; - badvaddr = addr; - addr &= ~(BY2PG-1); - user = !(ur->sr&SUPER); - if(user) - u->dbgreg = ur; - - if(f->ssw & DF) - read = (f->ssw&READ) && !(f->ssw&RM); - else - read = f->ssw&(FB|FC); - -/* print("fault pc=%lux addr=%lux read %d\n", ur->pc, badvaddr, read); /**/ - - if(fault(addr, read) < 0){ - if(user){ - sprint(buf, "sys: trap: fault %s addr=0x%lux", - read? "read" : "write", badvaddr); - postnote(u->p, 1, buf, NDebug); - notify(ur); - return; - } - dumpregs(ur); - panic("fault: 0x%lux", badvaddr); - } - u->p->insyscall = insyscall; -} diff --git a/gnot/fns.h b/gnot/fns.h deleted file mode 100644 index 658f25d04bc812bc37d9497bc2887d8a56b7e6b6..0000000000000000000000000000000000000000 --- a/gnot/fns.h +++ /dev/null @@ -1,55 +0,0 @@ -#include "../port/portfns.h" - -void addportintr(int (*)(void)); -void bootargs(ulong); -void clearmmucache(void); -void duartclock(void); -void duartinit(void); -void duartstarttimer(void); -void duartstoptimer(void); -#define evenaddr(x) /* 68020 doesn't care */ -void fault68020(Ureg*, FFrame*); -void firmware(void); -#define flushapage(x) -void flushcpucache(void); -#define flushpage(x) if(x) -int fpcr(int); -ulong fpiar(void); -void fpregrestore(char*); -void fpregsave(char*); -void fprestore(FPsave*); -void fpsave(FPsave*); -ulong getsr(void); -#define icflush(a, b) -void incontoggle(void); -KMap* kmap(Page*); -void kmapinit(void); -void kunmap(KMap*); -void mmuinit(void); -#define mmunewpage(x) -void mousebuttons(int); -void mouseclock(void); -int portprobe(char*, int, int, int, long); -void procrestore(Proc*); -void procsave(Proc*); -void procsetup(Proc*); -void putkmmu(ulong, ulong); -void restfpregs(FPsave*); -void screeninit(void); -void screenputc(int); -void screenputs(char*, int); -void scsictrlintr(void); -void scsidmaintr(void); -uchar* scsirecv(uchar *); -void scsirun(void); -uchar* scsixmit(uchar *); -int spl1(void); -void spldone(void); -int splduart(void); -int tas(char*); -void touser(void*); -#define waserror() (u->nerrlab++, setlabel(&u->errlab[u->nerrlab-1])) -#define kmapperm(x) kmap(x) -#define getcallerpc(x) (*(ulong*)(x)) -#define KADDR(a) ((void*)((ulong)(a)|KZERO)) -#define PADDR(a) ((ulong)(a)&~KZERO) diff --git a/gnot/hifi.h b/gnot/hifi.h deleted file mode 100644 index 5114fc545e6cc23de77fdc7f7ec87f6bffdf8822..0000000000000000000000000000000000000000 --- a/gnot/hifi.h +++ /dev/null @@ -1,106 +0,0 @@ -/* AT&T T7121 HDLC Interface for ISDN (HIFI-64) */ - -enum Hifi_r0 { /* Chip Configuration Register */ - Dint = Bit(0), - Ipol = Bit(1), - Flags = Bit(2), - Bm = Bit(3), - Alt = Bit(4), - Fe = Bit(5), - Fspol = Bit(6), - Fsen = Bit(7) -}; - -enum Hifi_r1 { /* Transmitter Control Register */ - Til = Bits(0,5), - Tabt = Bit(6), - Tfc = Bit(7) -}; - -enum Hifi_r2 { /* Transmitter Status Register */ - Tqs = Bits(0,6), - Ted = Bit(7) -}; - -enum Hifi_r4 { /* Receiver Status Register */ - Rqs = Bits(0,6), - Eof = Bit(7) -}; - -enum Hifi_r5 { /* Receiver Control Register */ - Ril = Bits(0,5), - P21ctl = Bit(6), - P17ctl = Bit(7) -}; - -enum Hifi_r6 { /* Operation Control Register */ - Rloop = Bit(0), - Lloop = Bit(1), - Enr = Bit(2), - Ent = Bit(3), - Rres = Bit(4), - Tres = Bit(5), - Tristate= Bit(6), - Pdwn = Bit(7) -}; - -enum Hifi_r7 { /* Transmit Time Slot Control Register */ - Tslt = Bits(0,5), - Dxbc = Bit(6), - Dxac = Bit(7) -}; - -enum Hifi_r8 { /* Receiver Time Slot Control Register */ - Rslt = Bits(0,5), - Iom2 = Bit(6), - Drab = Bit(7) -}; - -enum Hifi_r9 { /* Bit Offset Control Register */ - Clkri = Bit(0), - Rbof = Bits(1,3), - Clkxi = Bit(4), - Tbof = Bits(5,7), -}; - -enum Hifi_r10 { /* Transmitter Time Slot Offset Control Register */ - Ttsof = Bits(0,5), - Tlbit = Bit(6), - Dxi = Bit(7) -}; - -enum Hifi_r11 { /* Receiver Time Slot Offset Control Register */ - Rtsof = Bits(0,5), - Rlbit = Bit(6), - Dri = Bit(7) -}; - -enum Hifi_ar11 { /* Transparent Mode Control Register */ - Octof = Bits(0,2), - Mstat = Bit(3), - Aloct = Bit(4), - Match = Bit(5), - Trans = Bit(6), - Test = Bit(7) -}; - -enum Hifi_r14 { /* Interrupt Mask Register */ - Tdie = Bit(0), - Teie = Bit(1), - Undie = Bit(2), - Rfie = Bit(3), - Reofie = Bit(4), - Rovie = Bit(5), - Riie = Bit(6), - Tbcrc = Bit(7) -}; - -enum Hifi_r15 { /* Interrupt Status Register */ - Tdone = Bit(0), - Te = Bit(1), - Undabt = Bit(2), - Rf = Bit(3), - Reof = Bit(4), - Overun = Bit(5), - Ridl = Bit(6) -}; diff --git a/gnot/io.h b/gnot/io.h deleted file mode 100644 index 32b70726035463cfa301528d789f937d9b65f3bc..0000000000000000000000000000000000000000 --- a/gnot/io.h +++ /dev/null @@ -1,58 +0,0 @@ -typedef struct Duart Duart; - -#define SYNCREG ((char*)0x40400000) -#define DISPLAYRAM 0x02000000 -#define DUARTREG ((Duart*)0x40100000) -#define PORT ((uchar *)0x40300000) - -/* - * Balu - */ -typedef struct Balu Balu; - -struct Balu{ - ulong src[4]; - ulong dst[4]; - ulong res[4]; - ulong cr0; - ulong cr1; -}; - -#define BALU ((Balu *) 0xc0000000) -#define OR(x,n) (ulong *) (((ulong) (x)) | n) -#define SOR(x) (OR(x,0x30000000)) -#define DOR(x) (OR(x,0x20000000)) - -/* goo for cr0 manipulations */ -#define OPLENMA 0x0000ffff /* 15 bits only needed */ -#define OPLENSH 0 -#define OPCNTMA 0xffff0000 /* 16 bit signed */ -#define OPCNTSH 16 - -/* goo for cr1 manipulations */ -#define ALUOPMA 0x0000001f /* 5bits */ -#define ALUOPSH 0 -#define PIXELMA 0x00000060 /* 2bits */ -#define PIXELSH 5 -#define SHMAGMA 0x00000f80 /* 5bits */ -#define SHMAGSH 7 -#define ALIGNMA 0x00003000 /* 2bits */ -#define ALIGNSH 12 -#define RLSCANMA 0x00004000 /* 1bit */ -#define RLSCANSH 14 -#define QOPMA 0x00008000 /* 1bit */ -#define QOPSH 15 -#define RMASKMA 0x001f0000 /* 5bits */ -#define RMASKSH 16 -#define LMASKMA 0x03e00000 /* 5bits */ -#define LMASKSH 21 - -enum -{ - SUB = 0x10, /* balu arithmetic codes */ - SSUB = 0x11, - ADD = 0x12, - SADD = 0x13, - MIN = 0x14, - MAX = 0x15 -}; diff --git a/gnot/isdn.h b/gnot/isdn.h deleted file mode 100644 index 1a8873d9cd7608404c0ed55311acbc924a8ee8c4..0000000000000000000000000000000000000000 --- a/gnot/isdn.h +++ /dev/null @@ -1,139 +0,0 @@ -typedef struct Isdn Isdn; -typedef struct Unite Unite; -typedef struct Hifi Hifi; - -/* -struct Isdndev { - uchar asr; - uchar data; -}; -*/ - -#define ISDNDEV0 ((uchar *)&PORT[52]) /* the first one */ - -#define Bit(n) (1<<(n)) - -#define Bits(m,n) (((1<<((n)-(m)+1))-1)<<(m)) - -enum Isdn_asr { /* Board status */ - Uint = Bit(0), - Hint0 = Bit(1), - Hint1 = Bit(2), - DRCODEC = Bit(6), /* enable codec receiver */ - DXCODEC = Bit(7) /* enable codec transmitter */ -}; - -/* - * Board addresses - */ - -#define unite ((Unite *)(0*Bit(4))) -#define hifi0 ((Hifi *) (2*Bit(4))) -#define hifi1 ((Hifi *) (3*Bit(4))) - -struct Unite { - uchar config; /* Chip/Hardware Configuration Register */ - uchar listat; /* Line Interface Status */ - uchar tctl; /* Transmitter Control Register */ - uchar data; /* D-channel data register */ - uchar hcr; /* Hardware Configuration Register */ - uchar rstat; /* HDLC Receiver Status */ - uchar itl; /* Interrupt Trigger Levels for D-Channel Queues */ - uchar mfstat; /* Multiframe Status and S-Channel Queues */ - uchar stictl; /* S/T Interface control */ - uchar imask; /* Interrupt masks */ - uchar istat; /* Interrupt Status */ - uchar qstat; /* Q-Channel Data and Status */ - uchar lctl; /* Loopback and Transmit 1's Control */ - uchar timctl; /* Timer Configuration Control */ - uchar tstat; /* Transmitter Queue Status */ - uchar reset; /* Software Resets */ -}; - -struct Hifi { - uchar config; /* Chip Configuration Register */ - uchar tctl; /* Transmitter Control Register */ - uchar tstat; /* Transmitter Status Register */ - uchar data; /* r3 is the Data Byte Register. */ - uchar rstat; /* Receiver Status Register */ - uchar rctl; /* Receiver Control Register */ - uchar opreg; /* Operation Register */ - uchar ttsctl; /* Transmitter Time Slot Control Register */ - uchar rtsctl; /* Receiver Time Slot Control Register */ - uchar bofctl; /* Bit Offset Control Register */ - uchar tofctl; /* Transmitter Time Slot Offset Control Register */ - uchar rof_tm; /* Rcvr Time Slot Offset/Trans. Mode Control Register */ - uchar rmask; /* Receiver Mask/Character Register. */ - uchar tmask; /* Transmitter Mask/Idle Char. Register. */ - uchar imask; /* Interrupt Mask Register */ - uchar istat; /* Interrupt Status Register */ -}; - -/* - * usage: SET(unite->chcr, C2pol); - */ - -#define SETADDR(addr) (*(ip->asr) = ip->venval | ((int)(addr))) - -#define GET(lval) (SETADDR(&(lval)), *(ip->data)) - -#define SET(lval, rval) (SETADDR(&(lval)), *(ip->data)=(rval)) - -#define NBMASK 0x0f -#define NB (NBMASK+1) -#define NEXT(a) (((a)+1)&NBMASK) - -struct Isdn -{ - QLock; /* access to struct */ - QLock kctl; /* kproc start/stop */ - Rendez kctlr; - int kstart; /* set if kernel process started */ - Rendez kr; /* kernel process sleep/wakeup */ - Rendez ar; /* wait for active link (INFO 4) */ - - int pri; /* priority at time of lock(&dev) */ - Lock dev; /* access to device */ - uchar venval; - uchar * asr; - uchar * data; - int hangup; /* hangup pending */ - uchar listat; /* previous line interface status */ - uchar tctl; /* transmitter control */ - uchar imask; /* interrupt mask */ - uchar stictl; /* S/T interface control and b1xb2 bit */ - uchar lctl; /* loopback control */ - uchar devaddr; /* debug access */ - - Block * inb[NB]; /* input buffer */ - int ri; /* input read pointer */ - int wi; /* input write pointer */ - Queue * rq; /* read queue */ - - QLock wlock; /* write's are atomic */ - Block * outb[NB]; /* output buffer */ - int so; /* output scavenge pointer */ - int ro; /* output read pointer */ - int wo; /* output write pointer */ - Block * out; /* current output block */ - Rendez tr; /* if transmitter must wait */ - - /* statistics */ - - ulong inchars; - ulong badcrc; - ulong abort; - ulong overrun; - ulong badcount; - ulong overflow; - ulong toolong; - ulong underrun; - ulong outchars; -}; - -extern Isdn * isdndev; -extern void isdnlock(Isdn*); -extern int isdnpeek(Isdn*, void*); -extern void isdnpoke(Isdn*, void*, int); -extern void isdnunlock(Isdn*); -extern int spl2(void); diff --git a/gnot/l.s b/gnot/l.s deleted file mode 100644 index 28a01c583b328a029484a714b8d2ec3f29cd26c1..0000000000000000000000000000000000000000 --- a/gnot/l.s +++ /dev/null @@ -1,373 +0,0 @@ -#include "mem.h" - -#define DBMAGIC 0xBADC0C0A - -/* - * Boot first processor - */ -TEXT start(SB), $-4 - - MOVW $(SUPER|SPL(7)), SR - MOVL $a6base(SB), A6 - MOVL $0, R0 - MOVL R0, CACR - MOVL R0, TACADDR /* zero tac counter (cause an intr?) */ - - MOVL $mach0(SB), A0 - MOVL A0, m(SB) - MOVL $0, 0(A0) - MOVL A0, A7 - ADDL $(MACHSIZE-4), A7 /* start stack under machine struct */ - MOVL $0, u(SB) - - MOVL $vectors(SB), A0 - MOVL A0, VBR - - BSR main(SB) - /* never returns */ -dead: - BRA dead - -/* - * Take first processor into user mode. Leave enough room on the kernel stack - * for a full-sized Ureg (including long bus error format) to fit - * - argument is stack pointer to user - */ - -TEXT touser(SB), $0 - - MOVL usp+0(FP), A0 - MOVL $(USERADDR+BY2PG-UREGVARSZ), A7 - MOVW $0, -(A7) - MOVL $(UTZERO+32), -(A7) /* header is in text */ - MOVW $0, -(A7) - MOVL A0, USP - MOVW $(SUPER|SPL(0)), SR - MOVL $8, R0 - MOVL R0, CACR - RTE - -TEXT firmware(SB), $0 - - MOVL $0x40000090, A0 - JMP (A0) - -TEXT splhi(SB), $0 - - MOVL m(SB), A0 - MOVL (A7), 4(A0) - MOVL $0, R0 - MOVW SR, R0 - MOVW $(SUPER|SPL(7)), SR - RTS - -TEXT splduart(SB), $0 - - MOVL $0, R0 - MOVW SR, R0 - MOVW $(SUPER|SPL(5)), SR - RTS - -TEXT spllo(SB), $0 - - MOVL $0, R0 - MOVW SR, R0 - MOVW $(SUPER|SPL(0)), SR - RTS - -TEXT splx(SB), $0 - - MOVL sr+0(FP), R0 - MOVW R0, SR - RTS - -TEXT spldone(SB), $0 - - RTS - -TEXT spl1(SB), $0 - - MOVL $0, R0 - MOVW SR, R0 - MOVW $(SUPER|SPL(1)), SR - RTS - -TEXT flushcpucache(SB), $0 - - MOVL $(CCLEAR|CENABLE), R0 - MOVL R0, CACR - RTS - -TEXT cacrtrap(SB), $0 /* user entry point to control cache, e.g. flush */ - - MOVL R0, CACR - RTE - -TEXT setlabel(SB), $0 - - MOVL sr+0(FP), A0 - MOVL A7, (A0)+ /* stack pointer */ - MOVL (A7), (A0)+ /* pc of caller */ - MOVW SR, (A0)+ /* status register */ - CLRL R0 /* ret 0 => not returning */ - RTS - -TEXT gotolabel(SB), $0 - - MOVL p+0(FP), A0 - MOVW $(SUPER|SPL(7)), SR - MOVL (A0)+, A7 /* stack pointer */ - MOVL (A0)+, (A7) /* pc; stuff into stack frame */ - MOVW (A0)+, R0 /* status register */ - MOVW R0, SR - MOVL $1, R0 /* ret 1 => returning */ - RTS - -/* - * Test and set, as a subroutine - */ - -TEXT tas(SB), $0 - - MOVL $0, R0 - MOVL a+0(FP), A0 - TAS (A0) - BEQ tas_1 - MOVL $1, R0 -tas_1: - RTS - -/* - * Floating point - */ - -TEXT fpsave(SB), $0 - - FSAVE (fp+0(FP)) - RTS - -TEXT fprestore(SB), $0 - - FRESTORE (fp+0(FP)) - RTS - -TEXT fpregsave(SB), $0 - - FMOVEM $0xFF, (3*4)(fr+0(FP)) - FMOVEMC $0x7, (fr+0(FP)) - RTS - -TEXT fpregrestore(SB), $0 - - FMOVEMC (fr+0(FP)), $0x7 - FMOVEM (3*4)(fr+0(FP)), $0xFF - RTS - -TEXT fpcr(SB), $0 - - MOVL new+0(FP), R1 - MOVL FPCR, R0 - MOVL R1, FPCR - RTS - -TEXT rfnote(SB), $0 - - MOVL uregp+0(FP), A7 - MOVL ((8+8)*BY2WD)(A7), A0 - MOVL A0, USP - MOVEM (A7), $0x7FFF - ADDL $((8+8+1+1)*BY2WD), A7 - RTE - -TEXT illegal(SB), $0 - - MOVL $DBMAGIC, -(A7) - SUBL $((8+8+1)*BY2WD), A7 - MOVEM $0x7FFF, (A7) - MOVL $a6base(SB), A6 - MOVL USP, A0 - MOVL A0, ((8+8)*BY2WD)(A7) - MOVL A7, -(A7) - BSR trap(SB) - ADDL $4, A7 - MOVL ((8+8)*BY2WD)(A7), A0 - MOVL A0, USP - MOVEM (A7), $0x7FFF - ADDL $((8+8+1)*BY2WD), A7 - MOVL $0, (A7)+ - RTE - -TEXT systrap(SB), $0 - - MOVL $DBMAGIC, -(A7) - SUBL $((8+8+1)*BY2WD), A7 - MOVL A6, ((8+6)*BY2WD)(A7) - MOVL R0, (A7) - MOVL $a6base(SB), A6 - MOVL USP, A0 - MOVL A0, ((8+8)*BY2WD)(A7) - MOVL A7, -(A7) - BSR syscall(SB) - MOVL ((1+8+8)*BY2WD)(A7), A0 - MOVL A0, USP - MOVL ((1+8+6)*BY2WD)(A7), A6 - ADDL $((1+8+8+1)*BY2WD), A7 - MOVL $0, (A7)+ - RTE - -TEXT buserror(SB), $0 - - MOVL $DBMAGIC, -(A7) - SUBL $((8+8+1)*BY2WD), A7 - MOVEM $0x7FFF, (A7) - MOVL $a6base(SB), A6 - MOVL USP, A0 - MOVL A0, ((8+8)*BY2WD)(A7) - PEA ((8+8+1+3)*BY2WD)(A7) - PEA 4(A7) - BSR fault68020(SB) - ADDL $8, A7 - MOVL ((8+8)*BY2WD)(A7), A0 - MOVL A0, USP - MOVEM (A7), $0x7FFF - ADDL $((8+8+1)*BY2WD), A7 - MOVL $0, (A7)+ - RTE - -TEXT tacintr(SB), $0 /* level 1 */ - - MOVL R0, -(A7) - MOVL TACADDR, R0 - MOVL (A7)+, R0 - RTE - -TEXT portintr(SB), $0 /* level 2 */ - - MOVL $DBMAGIC, -(A7) - SUBL $((8+8+1)*BY2WD), A7 - MOVEM $0x7FFF, (A7) - MOVL $a6base(SB), A6 - MOVL USP, A0 - MOVL A0, ((8+8)*BY2WD)(A7) - MOVL A7, -(A7) - BSR devportintr(SB) - BRA retintr - -TEXT dkintr(SB), $0 /* level 3 */ - - MOVL $DBMAGIC, -(A7) - SUBL $((8+8+1)*BY2WD), A7 - MOVEM $0x7FFF, (A7) - MOVL $a6base(SB), A6 - MOVL USP, A0 - MOVL A0, ((8+8)*BY2WD)(A7) - MOVL A7, -(A7) - BSR inconintr(SB) - BRA retintr - -TEXT mouseintr(SB), $0 /* level 4 */ - - MOVEM $0x80C2, -(A7) /* D0, A0, A1, A6 */ - MOVL $a6base(SB), A6 - MOVL $15, R0 /* mask off hex switch */ - ANDB MOUSE,R0 /* clears quadrature interrupt */ - LEA mousetab(SB)(R0.W*8), A0 - LEA mouse(SB), A1 - MOVL (A0)+, R0 - ADDL R0, (A1)+ /* dx */ - MOVL (A0), R0 - ADDL R0, (A1)+ /* dy */ - ADDL $1, (A1) /* track */ - MOVEM (A7)+, $0x4301 - RTE - -TEXT uartintr(SB), $0 /* level 5 */ - - MOVL $DBMAGIC, -(A7) - SUBL $((8+8+1)*BY2WD), A7 - MOVEM $0x7FFF, (A7) - MOVL $a6base(SB), A6 - MOVL USP, A0 - MOVL A0, ((8+8)*BY2WD)(A7) - MOVL A7, -(A7) - BSR duartintr(SB) - BRA retintr - -TEXT syncintr(SB), $0 /* level 6 */ - - MOVL $DBMAGIC, -(A7) - SUBL $((8+8+1)*BY2WD), A7 - MOVEM $0x7FFF, (A7) - MOVL $a6base(SB), A6 - MOVL USP, A0 - MOVL A0, ((8+8)*BY2WD)(A7) - MOVL A7, -(A7) - BSR clock(SB) - /* fall through */ -retintr: - ADDL $4, A7 - MOVL ((8+8)*BY2WD)(A7), A0 - MOVL A0, USP - MOVEM (A7), $0x7FFF - ADDL $((8+8+1)*BY2WD), A7 - MOVL $0, (A7)+ - RTE - -GLOBL duarttimer+0(SB),$4 - -TEXT duartreadtimer+0(SB), $0 - MOVW SR, R1 /* spl7() */ - MOVW $0x2700, SR - MOVL $0x40100000, A0 - CLRL R0 - TSTB 15(A0) /* stop timer */ - MOVW 6(A0), R0 /* read hi,lo */ - TSTB 14(A0) /* restart timer */ - NOTW R0 /* timer counts down from 0xffff */ - ADDL duarttimer(SB), R0 - MOVL R0, duarttimer(SB) - MOVW R1, SR - RTS - -TEXT getsr+0(SB), $0 - MOVL $0, R0 - MOVW SR, R0 - RTS - -GLOBL mousetab(SB), $128 -DATA mousetab+ 0(SB)/4, -1 /* x down, */ -DATA mousetab+ 4(SB)/4, 1 /* y up */ -DATA mousetab+ 8(SB)/4, 0 /* x - */ -DATA mousetab+ 12(SB)/4, 1 /* y up */ -DATA mousetab+ 16(SB)/4, 1 /* x up */ -DATA mousetab+ 20(SB)/4, 1 /* y up */ -DATA mousetab+ 24(SB)/4, 0 /* x - */ -DATA mousetab+ 28(SB)/4, 1 /* y up */ -DATA mousetab+ 32(SB)/4, -1 /* x down */ -DATA mousetab+ 36(SB)/4, 0 /* y - */ -DATA mousetab+ 40(SB)/4, 0 /* x - */ -DATA mousetab+ 44(SB)/4, 0 /* y - */ -DATA mousetab+ 48(SB)/4, 1 /* x up, */ -DATA mousetab+ 52(SB)/4, 0 /* y - */ -DATA mousetab+ 56(SB)/4, 0 /* x - */ -DATA mousetab+ 60(SB)/4, 0 /* y - */ -DATA mousetab+ 64(SB)/4, -1 /* x down */ -DATA mousetab+ 68(SB)/4, -1 /* y down */ -DATA mousetab+ 72(SB)/4, 0 /* x - */ -DATA mousetab+ 76(SB)/4, -1 /* y down */ -DATA mousetab+ 80(SB)/4, 1 /* x up */ -DATA mousetab+ 84(SB)/4, -1 /* y down */ -DATA mousetab+ 88(SB)/4, 0 /* x - */ -DATA mousetab+ 92(SB)/4, -1 /* y down */ -DATA mousetab+ 96(SB)/4, -1 /* x down */ -DATA mousetab+100(SB)/4, 0 /* y - */ -DATA mousetab+104(SB)/4, 0 /* x - */ -DATA mousetab+108(SB)/4, 0 /* y - */ -DATA mousetab+112(SB)/4, 1 /* x up */ -DATA mousetab+116(SB)/4, 0 /* y - */ -DATA mousetab+120(SB)/4, 0 /* x - */ -DATA mousetab+124(SB)/4, 0 /* y - */ - -GLOBL mach0+0(SB), $MACHSIZE -GLOBL u(SB), $4 -GLOBL m(SB), $4 diff --git a/gnot/main.c b/gnot/main.c deleted file mode 100644 index 6a5b8542447c74d947c7f5106b4ccaaaa525d10b..0000000000000000000000000000000000000000 --- a/gnot/main.c +++ /dev/null @@ -1,416 +0,0 @@ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "io.h" -#include "ureg.h" -#include "init.h" - -#include -#include - -typedef struct Boot Boot; -struct Boot -{ - long station; - long traffic; - char user[NAMELEN]; - char server[64]; - char line[64]; - char device; -}; -#define BOOT ((Boot*)0) - -char bootuser[NAMELEN]; -char bootline[64]; -char bootserver[72]; -int bank[2]; -uchar *sp; - -extern GBitmap gscreen; - -void unloadboot(void); - -void -main(void) -{ - u = 0; - unloadboot(); - machinit(); - active.exiting = 0; - active.machs = 1; - mmuinit(); - confinit(); - xinit(); - kmapinit(); - duartinit(); - screeninit(); - printinit(); - print("bank 0: %dM bank 1: %dM\n", bank[0], bank[1]); - flushmmu(); - pageinit(); - procinit0(); - initseg(); - chandevreset(); - streaminit(); - swapinit(); - kmapinit(); - userinit(); - schedinit(); -} - -void -unloadboot(void) -{ - char s[64]; - - memmove(bootuser, BOOT->user, sizeof(bootuser)-1); - bootuser[sizeof(bootuser)-1] = 0; - memmove(bootline, BOOT->line, sizeof(bootline)-1); - bootline[sizeof(bootline)-1] = 0; - memmove(s, BOOT->server, sizeof(s) - 1); - s[sizeof(s)-1] = 0; - switch(BOOT->device){ - case 'a': - sprint(bootserver, "19200!%s", s); - break; - case 'A': - sprint(bootserver, "9600!%s", s); - break; - case 'i': - sprint(bootserver, "incon!%s", s); - break; - default: - /* older boot ROM's don't zero out BOOT->user if it isn't set. */ - memset(bootuser, 0, sizeof(bootuser)); - sprint(bootserver, "scsi!%s", s); - break; - } -} - -void -machinit(void) -{ - int n; - - n = m->machno; - memset(m, 0, sizeof(Mach)); - m->machno = n; - m->fpstate = FPinit; - fprestore(&initfp); -} - -void -mmuinit(void) -{ - ulong l, d, i; - - /* - * Invalidate user addresses - */ - for(l=0; l<4*1024*1024; l+=BY2PG) - putmmu(l, INVALIDPTE, 0); - /* - * Four meg of usable memory, with top 256K for screen - */ - for(i=1,l=KTZERO; inerrlab = 0; - m->proc = u->p; - u->p->state = Running; - u->p->mach = m; - spllo(); - - u->slash = (*devtab[0].attach)(0); - u->dot = clone(u->slash, 0); - - kproc("alarm", alarmkproc, 0); - chandevinit(); - - if(!waserror()){ - ksetterm("at&t %s"); - ksetenv("cputype", "68020"); - poperror(); - } - - touser(sp); -} - -FPsave initfp; - -void -userinit(void) -{ - Proc *p; - Segment *s; - User *up; - KMap *k; - Page *pg; - - p = newproc(); - p->pgrp = newpgrp(); - p->egrp = smalloc(sizeof(Egrp)); - p->egrp->ref = 1; - p->fgrp = smalloc(sizeof(Fgrp)); - p->fgrp->ref = 1; - p->procmode = 0640; - - strcpy(p->text, "*init*"); - strcpy(p->user, eve); - p->fpstate = FPinit; - - /* - * Kernel Stack - */ - p->sched.pc = (ulong)init0; - p->sched.sp = USERADDR+BY2PG-5*BY2WD; - p->sched.sr = SUPER|SPL(0); - p->upage = newpage(1, 0, USERADDR|(p->pid&0xFFFF)); - - /* - * User - */ - k = kmap(p->upage); - up = (User*)VA(k); - up->p = p; - kunmap(k); - - /* - * User Stack, copy in boot arguments - */ - s = newseg(SG_STACK, USTKTOP-BY2PG, 1); - p->seg[SSEG] = s; - pg = newpage(1, 0, USTKTOP-BY2PG); - segpage(s, pg); - k = kmap(pg); - bootargs(VA(k)); - kunmap(k); - - /* - * Text - */ - s = newseg(SG_TEXT, UTZERO, 1); - p->seg[TSEG] = s; - segpage(s, newpage(1, 0, UTZERO)); - k = kmap(s->map[0]->pages[0]); - memmove((ulong*)VA(k), initcode, sizeof initcode); - kunmap(k); - - ready(p); -} - -uchar * -pusharg(char *p) -{ - int n; - - n = strlen(p)+1; - sp -= n; - memmove(sp, p, n); - return sp; -} - -void -bootargs(ulong base) -{ - int i, ac; - uchar *av[32]; - char *p, *pp; - uchar **lsp; - - sp = (uchar*)base + BY2PG - MAXSYSARG*BY2WD; - - ac = 0; - for(p = bootline; p && *p; p = pp){ - pp = strchr(p, ' '); - if(pp) - *pp++ = 0; - av[ac++] = pusharg(p); - } - if(bootuser[0]){ - av[ac++] = pusharg("-u"); - av[ac++] = pusharg(bootuser); - } - av[ac++] = pusharg(bootserver); - - /* 4 byte word align stack */ - sp = (uchar*)((ulong)sp & ~3); - - /* build argc, argv on stack */ - sp -= (ac+1)*sizeof(sp); - lsp = (uchar**)sp; - for(i = 0; i < ac; i++) - *lsp++ = av[i] + ((USTKTOP - BY2PG) - base); - *lsp = 0; - sp += (USTKTOP - BY2PG) - base - sizeof(sp); -} - -void -exit(int ispanic) -{ - int i; - - u = 0; - spllo(); - while(consactive()) - for(i=0; i<1000; i++) - ; - splhi(); - if(ispanic) - for(;;); - firmware(); -} - -banksize(int base) -{ - ulong va; - - if(end > (char *)((KZERO|1024L*1024L)-BY2PG)) - return 0; - va = UZERO; /* user page 1 is free to play with */ - putmmu(va, PTEVALID|(base+0)*MB/BY2PG, 0); - *(ulong*)va = 0; /* 0 at 0M */ - putmmu(va, PTEVALID|(base+1)*MB/BY2PG, 0); - *(ulong*)va = 1; /* 1 at 1M */ - putmmu(va, PTEVALID|(base+4)*MB/BY2PG, 0); - *(ulong*)va = 4; /* 4 at 4M */ - putmmu(va, PTEVALID|(base+0)*MB/BY2PG, 0); - if(*(ulong*)va == 0) - return 16; - putmmu(va, PTEVALID|(base+1)*MB/BY2PG, 0); - if(*(ulong*)va == 1) - return 4; - putmmu(va, PTEVALID|(base+0)*MB/BY2PG, 0); - if(*(ulong*)va == 4) - return 1; - return 0; -} - -Conf conf; - -void -confinit(void) -{ - int mul, pcnt; - ulong ktop; - - conf.nmach = 1; - if(conf.nmach > MAXMACH) - panic("confinit"); - conf.monitor = 1; - bank[0] = banksize(0); - bank[1] = banksize(16); - conf.npage0 = (bank[0]*MB)/BY2PG; - conf.base0 = 0; - conf.npage1 = (bank[1]*MB)/BY2PG; - conf.base1 = 16*MB; - conf.npage = conf.npage0+conf.npage1; - - pcnt = screenbits()-1; /* Calculate % of memory for page pool */ - pcnt = 70 - (pcnt*10); - conf.upages = (conf.npage*pcnt)/100; - - ktop = PGROUND((ulong)end); - ktop = PADDR(ktop); - conf.npage0 -= ktop/BY2PG; - conf.base0 += ktop; - - mul = 1 + (conf.npage1>0); - conf.nproc = 50*mul; - conf.nswap = 4096; - conf.nimage = 50; - conf.copymode = 0; /* copy on write */ - conf.portispaged = 0; - confinit1(mul); -} - -/* - * set up floating point for a new process - */ -void -procsetup(Proc *p) -{ - long fpnull; - - fpnull = 0; - splhi(); - m->fpstate = FPinit; - p->fpstate = FPinit; - fprestore((FPsave*)&fpnull); - spllo(); -} - -/* - * Save the part of the process state. - */ -void -procsave(Proc *p) -{ - Balu *balu = (Balu *)u->balusave; - - USED(p); - fpsave(&u->fpsave); - if(u->fpsave.type){ - if(u->fpsave.size > sizeof u->fpsave.junk) - panic("fpsize %d max %d\n", u->fpsave.size, sizeof u->fpsave.junk); - fpregsave(u->fpsave.reg); - u->p->fpstate = FPactive; - m->fpstate = FPdirty; - } - if(BALU->cr0 != 0xFFFFFFFF) /* balu busy */ - memmove(balu, BALU, sizeof(Balu)); - else{ - balu->cr0 = 0xFFFFFFFF; - BALU->cr0 = 0xFFFFFFFF; - } -} - -/* - * Restore what procsave() saves - * - * Procsave() makes sure that what state points to is long enough - */ -void -procrestore(Proc *p) -{ - Balu *balu = (Balu *)u->balusave; - - if(p->fpstate != m->fpstate){ - if(p->fpstate == FPinit){ - u->p->fpstate = FPinit; - fprestore(&initfp); - m->fpstate = FPinit; - }else{ - fpregrestore(u->fpsave.reg); - fprestore(&u->fpsave); - m->fpstate = FPdirty; - } - } - if(balu->cr0 != 0xFFFFFFFF) /* balu busy */ - memmove(BALU, balu, sizeof BALU); -} - -void -buzz(int f, int d) -{ - USED(f, d); -} - -void -lights(int val) -{ - USED(val); -} diff --git a/gnot/malloc.h b/gnot/malloc.h deleted file mode 100644 index 82d145d1af301580f5d152abcfb423b117978fea..0000000000000000000000000000000000000000 --- a/gnot/malloc.h +++ /dev/null @@ -1,15 +0,0 @@ -struct tbl_entry { - struct tbl_entry *next; /* free list */ - int *data; /* data */ -}; - -struct table { - int size; /* # entries */ - struct tbl_entry *entries; /* the entries */ - struct tbl_entry *free; /* the free list */ -}; - -void *tbl_alloc(struct table *, int); -void tbl_free(struct table *, void *); -int tbl_index(struct table *, void *); -void *tbl_data(struct table *, int); diff --git a/gnot/mem.h b/gnot/mem.h deleted file mode 100644 index fef61b8028c16b44d7f2ee90f2c02b379a3a0f3b..0000000000000000000000000000000000000000 --- a/gnot/mem.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Memory and machine-specific definitions. Used in C and assembler. - */ - -/* - * Sizes - */ - -#define BI2BY 8 /* bits per byte */ -#define BI2WD 32 /* bits per word */ -#define BY2WD 4 /* bytes per word */ -#define BY2PG 8192 /* bytes per page */ -#define WD2PG (BY2PG/BY2WD) /* words per page */ -#define PGSHIFT 13 /* log(BY2PG) */ -#define PGROUND(s) (((s)+(BY2PG-1))&~(BY2PG-1)) -#define ICACHESIZE 0 -#define MB4 (4*1024*1024) /* Lots of things are 4Mb in size */ - -#define MAXMACH 1 /* max # cpus system can run */ - -/* - * Time - */ -#define HZ (60) /* clock frequency */ -#define MS2HZ (1000/HZ) /* millisec per clock tick */ -#define TK2SEC(t) ((t)/HZ) /* ticks to seconds */ -#define TK2MS(t) ((((ulong)(t))*1000)/HZ) /* ticks to milliseconds */ -#define MS2TK(t) ((((ulong)(t))*HZ)/1000) /* milliseconds to ticks */ - -/* - * SR bits - */ -#define SUPER 0x2000 -#define SPL(n) (n<<8) - -/* - * CACR - */ -#define CCLEAR 0x08 -#define CENABLE 0x01 - -/* - * Magic registers (unused in current system) - */ - -#define MACH A5 /* A5 is m-> */ -#define USER A4 /* A4 is u-> */ - -/* - * Fundamental addresses - */ - -#define USERADDR 0x80000000 -/* assuming we're in a syscall, this is the address of the Ureg structure */ -#define UREGVARSZ (23*BY2WD) /* size of variable part of Ureg */ -#define UREGADDR (USERADDR+BY2PG-(UREGVARSZ+2+4+2+(8+8+1+1)*BY2WD)) - -/* - * Devices poked during bootstrap - */ -#define TACADDR 0x40600000 -#define MOUSE 0x40200000 - -/* - * MMU - */ - -#define VAMASK 0xCFFFFFFF /* clear balu bits in address */ -#define KUSEG 0x00000000 -#define KSEG 0x80000000 - -/* - * MMU entries - */ -#define PTEVALID (1<<13) -#define PTEWRITE 0 -#define PTERONLY (1<<14) -#define PTEKERNEL (1<<15) -#define PTEUNCACHED 0 -#define INVALIDPTE 0 -#define PTEMAPMEM (1024*1024) -#define PTEPERTAB (PTEMAPMEM/BY2PG) -#define SEGMAPSIZE 16 - -#define PPN(pa) ((pa>>13)&0x1FFF) - -#define KMAP ((unsigned long *)0xD0000000) -#define UMAP ((unsigned long *)0x50000000) - -/* - * Virtual addresses - */ -#define VTAG(va) ((va>>22)&0x03F) -#define VPN(va) ((va>>13)&0x1FF) - -#define PARAM ((char*)0x40500000) -#define TLBFLUSH_ 0x01 - -/* - * Address spaces - */ - -#define UZERO KUSEG /* base of user address space */ -#define UTZERO (UZERO+BY2PG) /* first address in user text */ -#define TSTKTOP 0x10000000 /* end of new stack in sysexec */ -#define TSTKSIZ 100 -#define USTKTOP (TSTKTOP-TSTKSIZ*BY2PG) /* byte just beyond user stack */ -#define KZERO KSEG /* base of kernel address space */ -#define KTZERO (KZERO+BY2PG) /* first address in kernel text */ -#define USTKSIZE (4*1024*1024) /* size of user stack */ - -#define MACHSIZE 4096 - - -#define isphys(p) ((((ulong)(p))&0xF0000000) == KSEG) diff --git a/gnot/mmu.c b/gnot/mmu.c deleted file mode 100644 index 1ae58e45455d5f572e5036476a5b4fd646717d1c..0000000000000000000000000000000000000000 --- a/gnot/mmu.c +++ /dev/null @@ -1,157 +0,0 @@ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" - -struct -{ - Lock; - int init; - KMap *free; - KMap arena[MB4/BY2PG]; /* kernel mmu maps up to 4MB */ -}kmapalloc; - -/* - * Called splhi, not in Running state - */ -void -mapstack(Proc *p) -{ - ulong tlbvirt, tlbphys; - - - if(p->upage->va != (USERADDR|(p->pid&0xFFFF)) && p->pid != 0) - panic("mapstack %d 0x%lux 0x%lux", p->pid, p->upage->pa, p->upage->va); - tlbvirt = USERADDR; - tlbphys = PPN(p->upage->pa) | PTEVALID | PTEKERNEL; - putkmmu(tlbvirt, tlbphys); - u = (User*)USERADDR; - - if(p->newtlb) { - flushmmu(); - p->newtlb = 0; - } - - /* - * if not a kernel process and this process was not the - * last process on this machine, flush & preload mmu - */ - if(!p->kp && p!=m->lproc){ - flushmmu(); - m->lproc = p; - } -} - -void -mmurelease(Proc *p) -{ - USED(p); -} - -void -putkmmu(ulong tlbvirt, ulong tlbphys) -{ - if(!(tlbvirt&KZERO)) - panic("putkmmu"); - tlbvirt &= ~KZERO; - KMAP[(tlbvirt&0x003FE000L)>>2] = tlbphys; -} - -void -putmmu(ulong tlbvirt, ulong tlbphys, Page *pg) -{ - USED(pg); - if(tlbvirt&KZERO) - panic("putmmu"); - tlbphys |= VTAG(tlbvirt)<<24; - tlbvirt = (tlbvirt&0x003FE000L)>>2; - UMAP[tlbvirt] = tlbphys; -} - -void -flushmmu(void) -{ - flushcpucache(); - *PARAM &= ~TLBFLUSH_; - *PARAM |= TLBFLUSH_; -} - -void -kmapinit(void) -{ - int i; - ulong endscreen; - Page *p; - KMap *k; - - if(kmapalloc.init == 0){ - k = &kmapalloc.arena[0]; - k->va = KZERO|(MB4-BY2PG); - k->next = 0; - kmapalloc.free = k; - kmapalloc.init = 1; - return; - } - - i = 0; - /* - * Reclaim map register for pages in bank0; - * screen is in virtual space overlaying physical pages; be careful - */ - endscreen = (PGROUND((ulong)end)&~KZERO) + 256*1024; - for(p = palloc.head; p; p = p->next) { - if(p->pa >= endscreen && p->pa < MB4) { - k = &kmapalloc.arena[p->pa/BY2PG]; - k->va = p->pa|KZERO; - kunmap(k); - i++; - } - } - print("%lud free map registers\n", i); -} - -KMap* -kmap(Page *pg) -{ - KMap *k; - int s; - - s = splhi(); - lock(&kmapalloc); - k = kmapalloc.free; - if(k == 0){ - dumpstack(); - panic("kmap"); - } - kmapalloc.free = k->next; - unlock(&kmapalloc); - splx(s); - - k->pa = pg->pa; - putkmmu(k->va, PPN(k->pa) | PTEVALID | PTEKERNEL); - - return k; -} - -void -kunmap(KMap *k) -{ - int s; - - k->pa = 0; - putkmmu(k->va, INVALIDPTE); - - s = splhi(); - lock(&kmapalloc); - k->next = kmapalloc.free; - kmapalloc.free = k; - unlock(&kmapalloc); - splx(s); -} - -void -invalidateu(void) -{ - putkmmu(USERADDR, INVALIDPTE); -} diff --git a/gnot/screen.c b/gnot/screen.c deleted file mode 100644 index e93471c86c0b80e04ea3b064a1c5475897482860..0000000000000000000000000000000000000000 --- a/gnot/screen.c +++ /dev/null @@ -1,166 +0,0 @@ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "io.h" -#include "ureg.h" -#include "../port/error.h" - -#include -#include -#include "screen.h" - -#define MINX 8 - -extern GSubfont defont0; -GSubfont *defont; - - -struct{ - Point pos; - int bwid; -}out; - -Lock screenlock; - -GBitmap gscreen = -{ - (ulong*)((1*1024*1024)|KZERO), /* bootrom puts it here; changed by mmuinit */ - 0, - 64, - 0, - { 0, 0, 1024, 1024, }, - { 0, 0, 1024, 1024, }, - 0 -}; - -void -screeninit(void) -{ - /* - * Read HEX switch to set ldepth - */ - if(*(uchar*)MOUSE & (1<<4)) - gscreen.ldepth = 1; - defont = &defont0; /* save space; let bitblt do the conversion work */ - gbitblt(&gscreen, Pt(0, 0), &gscreen, gscreen.r, 0); - out.pos.x = MINX; - out.pos.y = 0; - out.bwid = defont0.info[' '].width; -} - -void -screenputnl(void) -{ - out.pos.x = MINX; - out.pos.y += defont0.height; - if(out.pos.y > gscreen.r.max.y-defont0.height) - out.pos.y = gscreen.r.min.y; - gbitblt(&gscreen, Pt(0, out.pos.y), &gscreen, - Rect(0, out.pos.y, gscreen.r.max.x, out.pos.y+2*defont0.height), 0); -} - -void -screenputs(char *s, int n) -{ - Rune r; - int i; - char buf[4]; - - if(getsr() & 0x0700){ - if(!canlock(&screenlock)) - return; /* don't deadlock trying to print in interrupt */ - }else - lock(&screenlock); - while(n > 0){ - i = chartorune(&r, s); - if(i == 0){ - s++; - --n; - continue; - } - memmove(buf, s, i); - buf[i] = 0; - n -= i; - s += i; - if(r == '\n') - screenputnl(); - else if(r == '\t'){ - out.pos.x += (8-((out.pos.x-MINX)/out.bwid&7))*out.bwid; - if(out.pos.x >= gscreen.r.max.x) - screenputnl(); - }else if(r == '\b'){ - if(out.pos.x >= out.bwid+MINX){ - out.pos.x -= out.bwid; - gsubfstring(&gscreen, out.pos, defont, " ", S); - } - }else{ - if(out.pos.x >= gscreen.r.max.x-out.bwid) - screenputnl(); - out.pos = gsubfstring(&gscreen, out.pos, defont, buf, S); - } - } - unlock(&screenlock); -} - -int -screenbits(void) -{ - if(*(uchar*)MOUSE & (1<<4)) - return 2; - else - return 1; -} - -void -getcolor(ulong p, ulong *pr, ulong *pg, ulong *pb) -{ - ulong ans; - - /* - * The gnot says 0 is white (max intensity) - */ - if(gscreen.ldepth == 0){ - if(p == 0) - ans = ~0; - else - ans = 0; - }else{ - switch(p){ - case 0: ans = ~0; break; - case 1: ans = 0xAAAAAAAA; break; - case 2: ans = 0x55555555; break; - default: ans = 0; break; - } - } - *pr = *pg = *pb = ans; -} - -int -setcolor(ulong p, ulong r, ulong g, ulong b) -{ - USED(p, r, g, b); - return 0; /* can't change mono screen colormap */ -} - -int -hwcursset(uchar *s, uchar *c, int ox, int oy) -{ - USED(s, c, ox, oy); - return 0; -} - -int -hwcursmove(int x, int y) -{ - USED(x, y); - return 0; -} - -/* only 1 flavor mouse */ -void -mousectl(char *x) -{ - USED(x); -} diff --git a/gnot/screen.h b/gnot/screen.h deleted file mode 100644 index 21b9dad215e806a783d93d3c028f96c82ebeeb19..0000000000000000000000000000000000000000 --- a/gnot/screen.h +++ /dev/null @@ -1,8 +0,0 @@ -extern void mouseupdate(int); - -#define hwscreenwrite(a, b) - -#define mbbpt(x) -#define mbbrect(x) -#define screenupdate() -#define mousescreenupdate() diff --git a/gnot/scsi.c b/gnot/scsi.c deleted file mode 100644 index dc250e416a763656fe45fb5bacd2d1a0f3bd3e85..0000000000000000000000000000000000000000 --- a/gnot/scsi.c +++ /dev/null @@ -1,309 +0,0 @@ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "../port/error.h" -#include "devtab.h" -#include "io.h" - -int scsiintr(void); - -#define DPRINT if(debug)kprint - -int scsidebugs[8]; -int scsiownid = 0x08|7; /* enable advanced features */ - -Scsibuf * -scsialloc(ulong n) -{ - Scsibuf *b; - - b = xalloc(sizeof(Scsibuf)); - b->virt = b->phys = xalloc(n); - return b; -} - -typedef struct Scsictl { - uchar asr; - uchar data; - uchar stat; - uchar dma; -} Scsictl; - -#define Scsiaddr 48 -#define DEV ((Scsictl *)&PORT[Scsiaddr]) - -static long poot; -#define WAIT (poot=0, poot==0?0:poot) - -#define PUT(a,d) (DEV->asr=(a), WAIT, DEV->data=(d)) -#define GET(a) (DEV->asr=(a), WAIT, DEV->data) - -enum Int_status { - Inten = 0x01, Scsirst = 0x02, - INTRQ = 0x01, DMA = 0x02, -}; - -enum SBIC_regs { - Own_id=0x00, Control=0x01, CDB=0x03, Target_LUN=0x0f, - Cmd_phase=0x10, Tc_hi=0x12, - Dest_id=0x15, Src_id=0x16, SCSI_Status=0x17, - Cmd=0x18, Data=0x19, -}; - -enum Commands { - Reset = 0x00, - Assert_ATN = 0x02, - Negate_ACK = 0x03, - Select_with_ATN = 0x06, - Select_with_ATN_and_Xfr = 0x08, - Select_and_Xfr = 0x09, - Transfer_Info = 0x20, - SBT = 0x80, /* modifier for single-byte transfer */ -}; - -enum Aux_status { - INT=0x80, LCI=0x40, BSY=0x20, CIP=0x10, - PE=0x02, DBR=0x01, -}; - -static int isscsi; -static QLock scsilock; -static Rendez scsirendez; -static uchar * datap; -static uchar * datalim; -static long debug, scsirflag, scsibusy, scsiinservice; - -static void -nop(void) -{} - -void -resetscsi(void) -{ - static int inited; - - if(!inited) - addportintr(scsiintr); - inited = 1; -} - -void -initscsi(void) -{ - isscsi = portprobe("scsi", -1, Scsiaddr, -1, 0L); - if (isscsi >= 0) { - DEV->stat = Scsirst; - delay(100); - DEV->stat = Inten; - while (DEV->stat & (INTRQ|DMA)) - nop(); - scsiownid &= 0x0f; /* possibly advanced features */ - scsiownid |= 0x80; /* 16MHz */ - PUT(Own_id, scsiownid); - PUT(Cmd, Reset); - } -} - -static int -scsidone(void *arg) -{ - USED(arg); - return (scsibusy == 0); -} - -int -scsiexec(Scsi *p, int rflag) -{ - long n; - - debug = scsidebugs[p->target&7]; - DPRINT("scsi %d.%d %2.2ux ", p->target, p->lun, *(p->cmd.ptr)); - qlock(&scsilock); - if(waserror()){ - qunlock(&scsilock); - DPRINT(" error return\n"); - nexterror(); - } - scsirflag = rflag; - p->rflag = rflag; - datap = p->data.base; - datalim = p->data.lim; - if ((scsiownid & 0x08) && rflag) - PUT(Dest_id, 0x40|p->target); - else - PUT(Dest_id, p->target); - PUT(Target_LUN, p->lun); - n = p->data.lim - p->data.base; - PUT(Tc_hi, n>>16); - DEV->data = n>>8; - DEV->data = n; - if (scsiownid & 0x08) { - n = p->cmd.lim - p->cmd.ptr; - DPRINT("len=%d ", n); - PUT(Own_id, n); - } - PUT(CDB, *(p->cmd.ptr)++); - while (p->cmd.ptr < p->cmd.lim) - DEV->data = *(p->cmd.ptr)++; - scsibusy = 1; - PUT(Cmd, Select_and_Xfr); - /*PUT(Cmd, Select_with_ATN_and_Xfr);*/ - DPRINT("S<"); - sleep(&scsirendez, scsidone, 0); - DPRINT(">\n"); - p->data.ptr = datap; - p->status = GET(Target_LUN); - p->status |= DEV->data<<8; - poperror(); - qunlock(&scsilock); - debug = 0; - return p->status; -} - -void -scsirun(void) -{ - wakeup(&scsirendez); - scsibusy = 0; -} - -void -scsireset0(void) -{ -/* PUT(Control, 0x29); /* burst DMA, halt on parity error */ - PUT(Control, 0x28); /* burst DMA, allow parity errors */ - PUT(Control+1, 0xff); /* timeout */ - PUT(Src_id, 0x80); /* enable reselection */ - scsirun(); - /*qunlock(&scsilock);*/ -} - -int -scsiintr(void) -{ - int status, s; - - if(isscsi < 0 || scsiinservice - || !((status = DEV->stat) & (DMA|INTRQ))) - return 0; - DEV->stat = 0; - scsiinservice = 1; - s = spl1(); - DPRINT("i%x ", status); - do{ - if (status & DMA) - scsidmaintr(); - if (status & INTRQ) - scsictrlintr(); - }while ((status = DEV->stat) & (DMA|INTRQ)); - splx(s); - scsiinservice = 0; - DEV->stat = Inten; - return 1; -} - -void -scsidmaintr(void) -{ - uchar *p = 0; -/* - * if (scsirflag) { - * unsigned char *p; - * DPRINT("R", p=datap); - * do - * *datap++ = DEV->dma; - * while (DEV->stat & DMA); - * DPRINT("%d ", datap-p); - * } else { - * unsigned char *p; - * DPRINT("W", p=datap); - * do - * DEV->dma = *datap++; - * while (DEV->stat & DMA); - * DPRINT("%d ", datap-p); - * } - */ - if(scsirflag){ - DPRINT("R", p=datap); - datap = scsirecv(datap); - DPRINT("%d ", datap-p); - }else{ - DPRINT("X", p=datap); - datap = scsixmit(datap); - DPRINT("%d ", datap-p); - } -} - -void -scsictrlintr(void) -{ - int status, phase; - long n; - - status = GET(SCSI_Status); - DPRINT("I%2.2x ", status); - switch(status){ - case 0x00: /* reset by command or power-up */ - case 0x01: /* reset by command or power-up */ - scsireset0(); - break; - case 0x21: /* Save Data Pointers message received */ - n = GET(Tc_hi); - n = (n<<8)|DEV->data; - n = (n<<8)|DEV->data; - datap = datalim - n; - PUT(Cmd_phase, 0x41); - PUT(Cmd, Select_and_Xfr); - break; - case 0x16: /* select-and-transfer completed */ - case 0x42: /* timeout during select */ - scsirun(); - break; - case 0x4b: /* unexpected status phase */ - DEV->asr = Target_LUN; - kprint("lun/status 0x%ux\n", DEV->data); - phase = DEV->data; - kprint("phase 0x%ux\n", phase); - PUT(Tc_hi, 0); - DEV->data = 0; - DEV->data = 0; - switch(phase){ - case 0x50: - case 0x60: - break; - default: - phase = 0x46; - break; - } - PUT(Cmd_phase, phase); - PUT(Cmd, Select_and_Xfr); - break; - default: - kprint("scsintr 0x%ux\n", status); - DEV->asr = Target_LUN; - kprint("lun/status 0x%ux\n", DEV->data); - kprint("phase 0x%ux\n", DEV->data); - switch (status&0xf0) { - case 0x00: - case 0x10: - case 0x20: - case 0x40: - case 0x80: - if(status & 0x08){ - kprint("count 0x%ux", GET(Tc_hi)); - kprint(" 0x%ux", DEV->data); - kprint(" 0x%ux\n", DEV->data); - } - scsirun(); - break; - default: - panic("scsi status 0x%2.2ux", status); - } - kprint("resetting..."); - PUT(Own_id, scsiownid); - PUT(Cmd, Reset); - break; - } -} diff --git a/gnot/scsibuf.c b/gnot/scsibuf.c deleted file mode 100644 index cc6edda894648d72ddf5c16fd676c195fb8e3991..0000000000000000000000000000000000000000 --- a/gnot/scsibuf.c +++ /dev/null @@ -1,63 +0,0 @@ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "../port/error.h" -#include "io.h" - -/* - * The following routines - * scsibufreset, scsibuf, scsifree and scsialloc - * provide a pool of buffers used for scsi i/o. - * This is simplistic at best, and opportunities for - * deadlock abound. - */ -#define Nbuf 2 - -struct { - Lock; - Scsibuf *free; -} scsibufalloc; - -void -scsibufreset(ulong datasize) -{ - int i; - - for(i = 0; i < Nbuf; i++) - scsifree(scsialloc(datasize)); - lock(&scsibufalloc); - unlock(&scsibufalloc); -} - -/* - * get a scsi io buffer of DATASIZE size - */ -Scsibuf * -scsibuf(void) -{ - Scsibuf *b; - - for(;;) { - lock(&scsibufalloc); - b = scsibufalloc.free; - if(b != 0) { - scsibufalloc.free = b->next; - unlock(&scsibufalloc); - return b; - } - unlock(&scsibufalloc); - resrcwait(0); - } - return 0; /* not reached */ -} - -void -scsifree(Scsibuf *b) -{ - lock(&scsibufalloc); - b->next = scsibufalloc.free; - scsibufalloc.free = b; - unlock(&scsibufalloc); -} diff --git a/gnot/scsisubs.s b/gnot/scsisubs.s deleted file mode 100644 index cbdcfdf4e08d030ec81f7071e451fde878580dce..0000000000000000000000000000000000000000 --- a/gnot/scsisubs.s +++ /dev/null @@ -1,60 +0,0 @@ -#include "mem.h" - -TEXT spl2(SB), $0 - - MOVL $0, R0 - MOVW SR, R0 - MOVW $(SUPER|SPL(2)), SR - RTS - -TEXT scsirecv(SB), $0 - MOVL $0x40300033, A0 /* data */ - MOVL $0x40300032, A1 /* status */ - MOVL p+0(FP), A2 - BTST $1, (A1) - BEQ rout -rloop: - MOVB (A0), (A2)+ - BTST $1, (A1) - BEQ rout - - MOVB (A0), (A2)+ - BTST $1, (A1) - BEQ rout - - MOVB (A0), (A2)+ - BTST $1, (A1) - BEQ rout - - MOVB (A0), (A2)+ - BTST $1, (A1) - BNE rloop -rout: - MOVL A2, R0 - RTS - -TEXT scsixmit(SB), $0 - MOVL $0x40300033, A0 /* data */ - MOVL $0x40300032, A1 /* status */ - MOVL p+0(FP), A2 - BTST $1, (A1) - BEQ xout -xloop: - MOVB (A2)+, (A0) - BTST $1, (A1) - BEQ xout - - MOVB (A2)+, (A0) - BTST $1, (A1) - BEQ xout - - MOVB (A2)+, (A0) - BTST $1, (A1) - BEQ xout - - MOVB (A2)+, (A0) - BTST $1, (A1) - BNE xloop -xout: - MOVL A2, R0 - RTS diff --git a/gnot/segment.h b/gnot/segment.h deleted file mode 100644 index 4e0486de02f37f1d5236c4d74a6a9d5e62d13107..0000000000000000000000000000000000000000 --- a/gnot/segment.h +++ /dev/null @@ -1,10 +0,0 @@ -/* - * Attach segment types - */ - -Physseg physseg[] = { - { SG_SHARED, "lock", 0, SEGMAXSIZE, 0, 0 }, - { SG_SHARED, "shared", 0, SEGMAXSIZE, 0, 0 }, - { SG_BSS, "memory", 0, SEGMAXSIZE, 0, 0 }, - { 0, 0, 0, 0, 0, 0 }, -}; diff --git a/gnot/trap.c b/gnot/trap.c deleted file mode 100644 index e3a20fcbc86fe6c3932fd3ba516bc2daefd77aa3..0000000000000000000000000000000000000000 --- a/gnot/trap.c +++ /dev/null @@ -1,394 +0,0 @@ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "ureg.h" -#include "io.h" -#include "../port/error.h" - -void noted(Ureg*, ulong); -void rfnote(Ureg*); - -char *regname[]={ - "R0", - "R1", - "R2", - "R3", - "R4", - "R5", - "R6", - "R7", - "A0", - "A1", - "A2", - "A3", - "A4", - "A5", - "A6", - "A7", -}; - -long ticks; - -char *trapname[]={ - "reset isp", - "reset ipc", - "bus error", - "address error", - "illegal instruction", - "zero divide", - "chk, chk2 instruction", - "trapcc instruction", - "privilege violation", - "trace", - "line 1010 emulator", - "line 1111 emulator", - "reserved", - "coprocessor protocol violation", - "format error", - "uninitialized interrupt", - "unassigned 0x40", - "unassigned 0x44", - "unassigned 0x48", - "unassigned 0x4C", - "unassigned 0x50", - "unassigned 0x54", - "unassigned 0x58", - "unassigned 0x5C", - "spurious interrupt", - "level 1 autovector (tac)", - "level 2 autovector (port)", - "level 3 autovector (incon)", - "level 4 autovector (mouse)", - "level 5 autovector (uart)", - "level 6 autovector (sync)", - "level 7 autovector", -}; - -char *fptrapname[]={ -[49-49] "inexact result", -[50-49] "divide by zero", -[51-49] "underflow", -[52-49] "operand error", -[53-49] "overflow", -[54-49] "signaling NaN", -}; - -char* -excname(unsigned vo, ulong pc) -{ - static char buf[32]; /* BUG: not reentrant! */ - ulong fppc; - - vo &= 0x0FFF; - vo >>= 2; - if(vo < sizeof trapname/sizeof(char*)){ - /* special case, and pc will be o.k. */ - if(vo==4 && *(ushort*)pc==0x4848) - return "breakpoint"; - sprint(buf, "trap: %s", trapname[vo]); - return buf; - } - if(49<=vo && vo<=54){ - fppc = 0; - if(u) - fppc = *(ulong*)(u->fpsave.reg+8); - sprint(buf, "fp: %s fppc=0x%lux", fptrapname[vo-49], fppc); - return buf; - } - sprint(buf, "offset 0x%ux", vo<<2); - return buf; -} - -void -trap(Ureg *ur) -{ - int user; - char buf[64]; - - user = !(ur->sr&SUPER); - - if(u) - u->dbgreg = ur; - - if(user){ - splhi(); - procsave(u->p); - spllo(); - sprint(buf, "sys: %s", excname(ur->vo, ur->pc)); - postnote(u->p, 1, buf, NDebug); - }else{ - print("kernel trap %s pc=0x%lux\n", excname(ur->vo, ur->pc), ur->pc); - dumpregs(ur); - exit(1); - } - - if(user) - notify(ur); -} - -void -dumpstack(void) -{ - ulong l, v, i; - extern ulong etext; - - if(u==0) - return; - - i = 0; - for(l=(ulong)&l; lp->text, u->p->pid); - else - print("registers for kernel\n"); - print("SR=%ux PC=%lux VO=%lux, USP=%lux\n", ur->sr, ur->pc, ur->vo, ur->usp); - l = &ur->r0; - for(i=0; ip->procctl) - procctl(u->p); - if(u->nnote == 0) - return 0; - - s = spllo(); - qlock(&u->p->debug); - u->p->notepending = 0; - n = &u->note[0]; - if(strncmp(n->msg, "sys:", 4) == 0){ - l = strlen(n->msg); - if(l > ERRLEN-15) /* " pc=0x12345678\0" */ - l = ERRLEN-15; - sprint(n->msg+l, " pc=0x%lux", ur->pc); - } - if(n->flag!=NUser && (u->notified || u->notify==0)){ - if(n->flag == NDebug) - pprint("suicide: %s\n", n->msg); - Die: - qunlock(&u->p->debug); - pexit(n->msg, n->flag!=NDebug); - } - sent = 0; - if(!u->notified){ - if(!u->notify) - goto Die; - sent = 1; - u->svvo = ur->vo; - u->svsr = ur->sr; - sp = ur->usp; - sp -= sizeof(Ureg); - if(!okaddr((ulong)u->notify, 1, 0) - || !okaddr(sp-ERRLEN-3*BY2WD, sizeof(Ureg)+ERRLEN-3*BY2WD, 0)){ - pprint("suicide: bad address in notify\n"); - qunlock(&u->p->debug); - pexit("Suicide", 0); - } - u->ureg = (void*)sp; - memmove((Ureg*)sp, ur, sizeof(Ureg)); - sp -= ERRLEN; - memmove((char*)sp, u->note[0].msg, ERRLEN); - sp -= 3*BY2WD; - *(ulong*)(sp+2*BY2WD) = sp+3*BY2WD; /* arg 2 is string */ - *(ulong*)(sp+1*BY2WD) = (ulong)u->ureg; /* arg 1 is ureg* */ - *(ulong*)(sp+0*BY2WD) = 0; /* arg 0 is pc */ - ur->usp = sp; - ur->pc = (ulong)u->notify; - ur->vo = 0x0080; /* pretend we're returning from syscall */ - u->notified = 1; - u->nnote--; - memmove(&u->lastnote, &u->note[0], sizeof(Note)); - memmove(&u->note[0], &u->note[1], u->nnote*sizeof(Note)); - } - qunlock(&u->p->debug); - splx(s); - return sent; -} - -/* - * Return user to state before notify() - */ -void -noted(Ureg *ur, ulong arg0) -{ - Ureg *nur; - - nur = u->ureg; - if(nur->sr!=u->svsr || nur->vo!=u->svvo){ - pprint("bad noted ureg sr %ux vo %ux\n", nur->sr, nur->vo); - Die: - pexit("Suicide", 0); - } - qlock(&u->p->debug); - if(!u->notified){ - qunlock(&u->p->debug); - pprint("call to noted() when not notified\n"); - goto Die; - } - u->notified = 0; - memmove(ur, u->ureg, sizeof(Ureg)); - switch(arg0){ - case NCONT: - if(!okaddr(nur->pc, 1, 0) || !okaddr(nur->usp, BY2WD, 0)){ - pprint("suicide: trap in noted\n"); - qunlock(&u->p->debug); - goto Die; - } - splhi(); - qunlock(&u->p->debug); - rfnote(ur); - break; - /* never returns */ - - default: - pprint("unknown noted arg 0x%lux\n", arg0); - u->lastnote.flag = NDebug; - /* fall through */ - - case NDFLT: - if(u->lastnote.flag == NDebug) - pprint("suicide: %s\n", u->lastnote.msg); - qunlock(&u->p->debug); - pexit(u->lastnote.msg, u->lastnote.flag!=NDebug); - } -} - -#include "../port/systab.h" - -long -syscall(Ureg *aur) -{ - long ret; - ulong sp; - Ureg *ur; - - u->p->insyscall = 1; - ur = aur; - u->dbgreg = aur; - u->p->pc = ur->pc; - if(ur->sr & SUPER) - panic("recursive system call"); - - /* must save FP registers before fork */ - if(u->p->fpstate==FPactive && ur->r0==RFORK){ - splhi(); - procsave(u->p); - spllo(); - } - - if(u->p->procctl) - procctl(u->p); - - u->scallnr = ur->r0; - sp = ur->usp; - - u->nerrlab = 0; - ret = -1; - if(!waserror()){ - if(u->scallnr >= sizeof systab/sizeof systab[0]){ - pprint("bad sys call number %d pc %lux\n", u->scallnr, ur->pc); - postnote(u->p, 1, "sys: bad sys call", NDebug); - error(Ebadarg); - } - - if(sp & (BY2WD-1)){ - pprint("odd sp in sys call pc %lux sp %lux\n", ur->pc, ur->sp); - postnote(u->p, 1, "sys: odd stack", NDebug); - error(Ebadarg); - } - - if(sp<(USTKTOP-BY2PG) || sp>(USTKTOP-sizeof(Sargs))) - validaddr(sp, sizeof(Sargs), 0); - - u->s = *((Sargs*)(sp+1*BY2WD)); - u->p->psstate = sysctab[u->scallnr]; - - ret = (*systab[u->scallnr])(u->s.args); - poperror(); - } - - u->nerrlab = 0; - u->p->insyscall = 0; - u->p->psstate = 0; - - if(u->scallnr == NOTED) /* ugly hack */ - noted(aur, *(ulong*)(sp+BY2WD)); /* doesn't return */ - splhi(); - if(u->scallnr!=RFORK && (u->p->procctl || u->nnote)){ - ur->r0 = ret; - notify(ur); - } - return ret; -} - -long -execregs(ulong entry, ulong ssize, ulong nargs) -{ - ulong *sp; - - sp = (ulong*)(USTKTOP - ssize); - *--sp = nargs; - ((Ureg*)UREGADDR)->usp = (ulong)sp; - ((Ureg*)UREGADDR)->pc = entry; - return USTKTOP-BY2WD; /* address of user-level clock */ -} - -ulong -userpc(void) -{ - return ((Ureg*)UREGADDR)->pc; -} - -/* This routine must save the values of registers the user is not permitted to write - * from devproc and the restore the saved values before returning - */ -void -setregisters(Ureg *xp, char *pureg, char *uva, int n) -{ - ushort sr; - ulong magic; - ushort vo; - char microstate[UREGVARSZ]; - - sr = xp->sr; - vo = xp->vo; - magic = xp->magic; - memmove(microstate, xp->microstate, UREGVARSZ); - - memmove(pureg, uva, n); - - xp->sr = (sr&0xff00) |(xp->sr&0xff); - xp->vo = vo; - xp->magic = magic; - memmove(xp->microstate, microstate, UREGVARSZ); -} diff --git a/gnot/u.h b/gnot/u.h deleted file mode 100644 index 59f98d28fdd3c7f1e3aafecb214ffc8d631a78d0..0000000000000000000000000000000000000000 --- a/gnot/u.h +++ /dev/null @@ -1,17 +0,0 @@ -typedef unsigned short ushort; -typedef unsigned char uchar; -typedef signed char schar; -typedef unsigned long ulong; -typedef long vlong; -typedef union Length Length; -typedef ushort Rune; - -union Length -{ - char clength[8]; - vlong vlength; - struct{ - long hlength; - long length; - }; -}; diff --git a/gnot/unite.h b/gnot/unite.h deleted file mode 100644 index a68cdadd0a6c0f3d2593e3e630f9376057ee3aa7..0000000000000000000000000000000000000000 --- a/gnot/unite.h +++ /dev/null @@ -1,120 +0,0 @@ -/* AT&T T7250A User Network Interface for Terminal Equipment (UNITE) */ - -enum Unite_r0 { /* Chip/Hardware Configuration Register */ - Ckdm = Bit(1), - C2pol = Bit(2), - C1pol = Bit(3), - Dynrd = Bit(4), -}; - -enum Unite_r1 { /* Line Interface Status */ - Prss = Bits(0,1), - Rss = Bits(2,3), -}; - -enum Unite_r2 { /* Transmitter Control Register */ - Tss = Bits(0,1), - Tabt = Bit(2), - Tfc = Bit(3), - Tinv = Bit(4), - Rinv = Bit(5), - Ent = Bit(6), - Enr = Bit(7) -}; - -enum Unite_r4 { /* Hardware Configuration Register */ - Tpol = Bit(0), - Ipol = Bit(1), - Clkmux = Bit(2), - B2f = Bit(3), - B1f = Bit(4), - Syscko = Bit(5), - Codec2 = Bit(6), - Codec1 = Bit(7) -}; - -enum Unite_r5 { /* HDLC Receiver Status */ - Rqs = Bits(0,4), - Overrun = Bit(5), - Ridl = Bit(6), - Eof = Bit(7) -}; - -enum Unite_r6 { /* Interrupt Trigger Levels for D-Channel Queues */ - Tel = Bits(0,3), - Rfl = Bits(4,7) -}; - -enum Unite_r7 { /* Multiframe Status and S-Channel Queues */ - Sdata = Bits(0,4), - Mstate = Bits(5,6), - Mse = Bit(7) -}; - -enum Unite_r8 { /* S/T Interface control */ - Clrmm = Bit(0), - B1xb2 = Bit(1), - Pry = Bit(2), - Prye = Bit(3), - Lpry = Bit(4), - Ssm = Bit(5), - B2i = Bit(6), - B1i = Bit(7) -}; - -enum Unite_r9 { /* Interrupt masks */ - Mmie = Bit(0), - Richgie = Bit(1), - Qdie = Bit(2), - Ssie = Bit(3), - Tdie = Bit(4), - Teie = Bit(5), - Rfie = Bit(6), - Reofie = Bit(7) -}; - -enum Unite_r10 { /* Interrupt Status */ - Mm = Bit(0), - Richg = Bit(1), - Qdone = Bit(2), - Ss = Bit(3), - Tdone = Bit(4), - Tempty = Bit(5), - Rfull = Bit(6), - Reof = Bit(7) -}; - -enum Unite_r11 { /* Q-Channel Data and Status */ - Qdata = Bits(0,3), - Enflg = Bit(4), - Doneq = Bit(5), - Qse = Bit(7) -}; - -enum Unite_r12 { /* Loopback and Transmit 1's Control */ - Rlb2 = Bit(0), - Rlb1 = Bit(1), - Rld = Bit(2), - Llb2 = Bit(3), - Llb1 = Bit(4), - Lld = Bit(5), - T1b2 = Bit(6), - T1b1 = Bit(7) -}; - -enum Unite_r13 { /* Timer Configuration Control */ - Tim = Bits(0,3), - Tm = Bits(4,7) -}; - -enum Unite_r14 { /* Transmitter Queue Status */ - Tqs = Bits(0,4), - Undabt = Bit(5), -}; - -enum Unite_r15 { /* Software Resets */ - Mres = Bit(0), - Rres = Bit(1), - Tres = Bit(2), - Tcrcb = Bit(4), -}; diff --git a/gnot/vec.s b/gnot/vec.s deleted file mode 100644 index b64ee941b941175651d425878262f59cce62747a..0000000000000000000000000000000000000000 --- a/gnot/vec.s +++ /dev/null @@ -1,268 +0,0 @@ -TEXT vectors(SB), $0 - WORD $0x4eb9 /* JSR start (never to return) */ - WORD $0x8000 - WORD $0x2420 - WORD $0x0000 -TEXT vectors0<>(SB), $0 -/* origin 0008, vector 2 */ - LONG buserror(SB) /* bus error */ - LONG illegal(SB) /* address error */ - LONG illegal(SB) /* illegal(SB) instruction */ - LONG illegal(SB) /* zero divide */ - LONG illegal(SB) /* chk, chk2 instruction */ - LONG illegal(SB) /* cptrapcc, trapcc, trapv instruction */ - LONG illegal(SB) /* privilege violation */ - LONG illegal(SB) /* trace */ - LONG illegal(SB) /* line 1010 emulator */ - LONG illegal(SB) /* line 1111 emulator */ - LONG illegal(SB) /* unassigned */ - LONG illegal(SB) /* coprocessor protocol violation */ - LONG illegal(SB) /* format error */ - LONG illegal(SB) /* uninitialized interrupt */ -/* origin 0040, vector 16 */ - LONG illegal(SB) /* 16 */ - LONG illegal(SB) /* 17 */ - LONG illegal(SB) /* 18 */ - LONG illegal(SB) /* 19 */ - LONG illegal(SB) /* 20 */ - LONG illegal(SB) /* 21 */ - LONG illegal(SB) /* 22 */ - LONG illegal(SB) /* 23 */ - LONG illegal(SB) /* 24 */ -/* origin 0064, vector 25 */ - LONG tacintr(SB) /* level 1 autovector */ - LONG portintr(SB) /* level 2 autovector */ - LONG dkintr(SB) /* level 3 autovector */ - LONG mouseintr(SB) /* level 4 autovector */ - LONG uartintr(SB) /* level 5 autovector */ - LONG syncintr(SB) /* level 6 autovector */ - LONG illegal(SB) /* level 7 autovector */ -/* origin 0080, vector 32 */ - LONG systrap(SB) /* trap #0 */ - LONG cacrtrap(SB) /* trap #1 */ - LONG illegal(SB) /* trap #2 */ - LONG illegal(SB) /* trap #3 */ - LONG illegal(SB) /* trap #4 */ - LONG illegal(SB) /* trap #5 */ - LONG illegal(SB) /* trap #6 */ - LONG illegal(SB) /* trap #7 */ - LONG illegal(SB) /* trap #8 */ - LONG illegal(SB) /* trap #9 */ - LONG illegal(SB) /* trap #10 */ - LONG illegal(SB) /* trap #11 */ - LONG illegal(SB) /* trap #12 */ - LONG illegal(SB) /* trap #13 */ - LONG illegal(SB) /* trap #14 */ - LONG illegal(SB) /* trap #15 */ -/* origin 00C0, vector 48 */ - LONG illegal(SB) /* fpcp branch or set on unordered cond. */ - LONG illegal(SB) /* fpcp inexact result */ - LONG illegal(SB) /* fpcp divide by zero */ - LONG illegal(SB) /* fpcp underflow */ - LONG illegal(SB) /* fpcp operand error */ - LONG illegal(SB) /* fpcp overflow */ - LONG illegal(SB) /* fpcp signaling nan */ - LONG illegal(SB) /* unassigned, reserved */ - LONG illegal(SB) /* pmmu configuration */ - LONG illegal(SB) /* pmmu illegal(SB) operation */ - LONG illegal(SB) /* pmmu access level violation */ -/* origin 00EC, vector 59 */ - LONG illegal(SB) /* vector #59 */ - LONG illegal(SB) /* vector #60 */ - LONG illegal(SB) /* vector #61 */ - LONG illegal(SB) /* vector #62 */ - LONG illegal(SB) /* vector #63 */ - LONG illegal(SB) /* vector #64 */ - LONG illegal(SB) /* vector #65 */ - LONG illegal(SB) /* vector #66 */ - LONG illegal(SB) /* vector #67 */ - LONG illegal(SB) /* vector #68 */ - LONG illegal(SB) /* vector #69 */ - LONG illegal(SB) /* vector #70 */ - LONG illegal(SB) /* vector #71 */ - LONG illegal(SB) /* vector #72 */ - LONG illegal(SB) /* vector #73 */ - LONG illegal(SB) /* vector #74 */ - LONG illegal(SB) /* vector #75 */ - LONG illegal(SB) /* vector #76 */ - LONG illegal(SB) /* vector #77 */ - LONG illegal(SB) /* vector #78 */ - LONG illegal(SB) /* vector #79 */ - LONG illegal(SB) /* vector #80 */ - LONG illegal(SB) /* vector #81 */ - LONG illegal(SB) /* vector #82 */ - LONG illegal(SB) /* vector #83 */ - LONG illegal(SB) /* vector #84 */ - LONG illegal(SB) /* vector #85 */ - LONG illegal(SB) /* vector #86 */ - LONG illegal(SB) /* vector #87 */ - LONG illegal(SB) /* vector #88 */ - LONG illegal(SB) /* vector #89 */ - LONG illegal(SB) /* vector #90 */ - LONG illegal(SB) /* vector #91 */ - LONG illegal(SB) /* vector #92 */ - LONG illegal(SB) /* vector #93 */ - LONG illegal(SB) /* vector #94 */ - LONG illegal(SB) /* vector #95 */ - LONG illegal(SB) /* vector #96 */ - LONG illegal(SB) /* vector #97 */ - LONG illegal(SB) /* vector #98 */ - LONG illegal(SB) /* vector #99 */ - LONG illegal(SB) /* vector #100 */ - LONG illegal(SB) /* vector #101 */ - LONG illegal(SB) /* vector #102 */ - LONG illegal(SB) /* vector #103 */ - LONG illegal(SB) /* vector #104 */ - LONG illegal(SB) /* vector #105 */ - LONG illegal(SB) /* vector #106 */ - LONG illegal(SB) /* vector #107 */ - LONG illegal(SB) /* vector #108 */ - LONG illegal(SB) /* vector #109 */ - LONG illegal(SB) /* vector #110 */ - LONG illegal(SB) /* vector #111 */ - LONG illegal(SB) /* vector #112 */ - LONG illegal(SB) /* vector #113 */ - LONG illegal(SB) /* vector #114 */ - LONG illegal(SB) /* vector #115 */ - LONG illegal(SB) /* vector #116 */ - LONG illegal(SB) /* vector #117 */ - LONG illegal(SB) /* vector #118 */ - LONG illegal(SB) /* vector #119 */ - LONG illegal(SB) /* vector #120 */ - LONG illegal(SB) /* vector #121 */ - LONG illegal(SB) /* vector #122 */ - LONG illegal(SB) /* vector #123 */ - LONG illegal(SB) /* vector #124 */ - LONG illegal(SB) /* vector #125 */ - LONG illegal(SB) /* vector #126 */ - LONG illegal(SB) /* vector #127 */ - LONG illegal(SB) /* vector #128 */ - LONG illegal(SB) /* vector #129 */ - LONG illegal(SB) /* vector #130 */ - LONG illegal(SB) /* vector #131 */ - LONG illegal(SB) /* vector #132 */ - LONG illegal(SB) /* vector #133 */ - LONG illegal(SB) /* vector #134 */ - LONG illegal(SB) /* vector #135 */ - LONG illegal(SB) /* vector #136 */ - LONG illegal(SB) /* vector #137 */ - LONG illegal(SB) /* vector #138 */ - LONG illegal(SB) /* vector #139 */ - LONG illegal(SB) /* vector #140 */ - LONG illegal(SB) /* vector #141 */ - LONG illegal(SB) /* vector #142 */ - LONG illegal(SB) /* vector #143 */ - LONG illegal(SB) /* vector #144 */ - LONG illegal(SB) /* vector #145 */ - LONG illegal(SB) /* vector #146 */ - LONG illegal(SB) /* vector #147 */ - LONG illegal(SB) /* vector #148 */ - LONG illegal(SB) /* vector #149 */ - LONG illegal(SB) /* vector #150 */ - LONG illegal(SB) /* vector #151 */ - LONG illegal(SB) /* vector #152 */ - LONG illegal(SB) /* vector #153 */ - LONG illegal(SB) /* vector #154 */ - LONG illegal(SB) /* vector #155 */ - LONG illegal(SB) /* vector #156 */ - LONG illegal(SB) /* vector #157 */ - LONG illegal(SB) /* vector #158 */ - LONG illegal(SB) /* vector #159 */ - LONG illegal(SB) /* vector #160 */ - LONG illegal(SB) /* vector #161 */ - LONG illegal(SB) /* vector #162 */ - LONG illegal(SB) /* vector #163 */ - LONG illegal(SB) /* vector #164 */ - LONG illegal(SB) /* vector #165 */ - LONG illegal(SB) /* vector #166 */ - LONG illegal(SB) /* vector #167 */ - LONG illegal(SB) /* vector #168 */ - LONG illegal(SB) /* vector #169 */ - LONG illegal(SB) /* vector #170 */ - LONG illegal(SB) /* vector #171 */ - LONG illegal(SB) /* vector #172 */ - LONG illegal(SB) /* vector #173 */ - LONG illegal(SB) /* vector #174 */ - LONG illegal(SB) /* vector #175 */ - LONG illegal(SB) /* vector #176 */ - LONG illegal(SB) /* vector #177 */ - LONG illegal(SB) /* vector #178 */ - LONG illegal(SB) /* vector #179 */ - LONG illegal(SB) /* vector #180 */ - LONG illegal(SB) /* vector #181 */ - LONG illegal(SB) /* vector #182 */ - LONG illegal(SB) /* vector #183 */ - LONG illegal(SB) /* vector #184 */ - LONG illegal(SB) /* vector #185 */ - LONG illegal(SB) /* vector #186 */ - LONG illegal(SB) /* vector #187 */ - LONG illegal(SB) /* vector #188 */ - LONG illegal(SB) /* vector #189 */ - LONG illegal(SB) /* vector #190 */ - LONG illegal(SB) /* vector #191 */ - LONG illegal(SB) /* vector #192 */ - LONG illegal(SB) /* vector #193 */ - LONG illegal(SB) /* vector #194 */ - LONG illegal(SB) /* vector #195 */ - LONG illegal(SB) /* vector #196 */ - LONG illegal(SB) /* vector #197 */ - LONG illegal(SB) /* vector #198 */ - LONG illegal(SB) /* vector #199 */ - LONG illegal(SB) /* vector #200 */ - LONG illegal(SB) /* vector #201 */ - LONG illegal(SB) /* vector #202 */ - LONG illegal(SB) /* vector #203 */ - LONG illegal(SB) /* vector #204 */ - LONG illegal(SB) /* vector #205 */ - LONG illegal(SB) /* vector #206 */ - LONG illegal(SB) /* vector #207 */ - LONG illegal(SB) /* vector #208 */ - LONG illegal(SB) /* vector #209 */ - LONG illegal(SB) /* vector #210 */ - LONG illegal(SB) /* vector #211 */ - LONG illegal(SB) /* vector #212 */ - LONG illegal(SB) /* vector #213 */ - LONG illegal(SB) /* vector #214 */ - LONG illegal(SB) /* vector #215 */ - LONG illegal(SB) /* vector #216 */ - LONG illegal(SB) /* vector #217 */ - LONG illegal(SB) /* vector #218 */ - LONG illegal(SB) /* vector #219 */ - LONG illegal(SB) /* vector #220 */ - LONG illegal(SB) /* vector #221 */ - LONG illegal(SB) /* vector #222 */ - LONG illegal(SB) /* vector #223 */ - LONG illegal(SB) /* vector #224 */ - LONG illegal(SB) /* vector #225 */ - LONG illegal(SB) /* vector #226 */ - LONG illegal(SB) /* vector #227 */ - LONG illegal(SB) /* vector #228 */ - LONG illegal(SB) /* vector #229 */ - LONG illegal(SB) /* vector #230 */ - LONG illegal(SB) /* vector #231 */ - LONG illegal(SB) /* vector #232 */ - LONG illegal(SB) /* vector #233 */ - LONG illegal(SB) /* vector #234 */ - LONG illegal(SB) /* vector #235 */ - LONG illegal(SB) /* vector #236 */ - LONG illegal(SB) /* vector #237 */ - LONG illegal(SB) /* vector #238 */ - LONG illegal(SB) /* vector #239 */ - LONG illegal(SB) /* vector #240 */ - LONG illegal(SB) /* vector #241 */ - LONG illegal(SB) /* vector #242 */ - LONG illegal(SB) /* vector #243 */ - LONG illegal(SB) /* vector #244 */ - LONG illegal(SB) /* vector #245 */ - LONG illegal(SB) /* vector #246 */ - LONG illegal(SB) /* vector #247 */ - LONG illegal(SB) /* vector #248 */ - LONG illegal(SB) /* vector #249 */ - LONG illegal(SB) /* vector #250 */ - LONG illegal(SB) /* vector #251 */ - LONG illegal(SB) /* vector #252 */ - LONG illegal(SB) /* vector #253 */ - LONG illegal(SB) /* vector #254 */ - LONG illegal(SB) /* vector #255 */ -/* origin 400 */ -/* start(SB) follows immediately */ diff --git a/pc/inconsubs.s b/pc/inconsubs.s deleted file mode 100644 index 90c0f157a3cbca26e24a3e07de0b2dcbde670d35..0000000000000000000000000000000000000000 --- a/pc/inconsubs.s +++ /dev/null @@ -1,52 +0,0 @@ -/* Centronix parallel (printer) port */ - -/* base addresses */ - -#define Lpt1 0x3bc -#define Lpt2 0x378 -#define Lpt3 0x278 - -/* offsets, and bits in the registers */ - -#define Qdlr 0x0 /* data latch register */ - -#define Qpsr 0x1 /* printer status register */ -#define Fbusy 0x80 -#define Fintbar 0x40 - -#define Qpcr 0x2 /* printer control register */ -#define Fie 0x10 -#define Fsi 0x08 -#define Finitbar 0x04 -#define Faf 0x02 -#define Fstrobe 0x01 - -/* - * read next data byte - * - * outb(dev+Qpcr, Finitbar|Faf|Fsi|Fstrobe); - * data = (inb(dev+Qpsr)&0xf8)<<2; - * outb(dev+Qpcr, Finitbar|Faf|Fsi); - * data |= inb(dev+Qpsr)>>3; - */ -TEXT Irdnext(SB),$0 - - MOVL dev+0(FP),DX /* points to base address */ - MOVL $(Finitbar|Faf|Fsi|Fstrobe),AX - ADDL $Qpcr,DX /* points to control register */ - OUTB - OUTB /* have to wait, sorry */ - SUBL $1,DX /* points to status register */ - INB - MOVL AX,CX - MOVL $(Finitbar|Faf|Fsi),AX - ADDL $1,DX /* points to control register */ - OUTB - OUTB - ANDL $0xf8,CX - SHLL $2,CX - SUBL $1,DX /* points to status register */ - INB - SARL $3,AX - ORL CX,AX - RET diff --git a/port/alarm.c b/port/alarm.c index e2f9ec34ce40ba5bed7fc1e08d81a8a1482858b7..338c5ca94f503c0525b0cba7d98846d7cb4f15c3 100644 --- a/port/alarm.c +++ b/port/alarm.c @@ -81,13 +81,12 @@ checkalarms(void) ulong procalarm(ulong time) { - Proc **l, *f, *p; + Proc **l, *f; ulong when, old; - p = u->p; - old = TK2MS(p->alarm - MACHP(0)->ticks); + old = TK2MS(up->alarm - MACHP(0)->ticks); if(time == 0) { - p->alarm = 0; + up->alarm = 0; return old; } when = MS2TK(time)+MACHP(0)->ticks; @@ -95,30 +94,30 @@ procalarm(ulong time) qlock(&alarms); l = &alarms.head; for(f = *l; f; f = f->palarm) { - if(p == f){ + if(up == f){ *l = f->palarm; break; } l = &f->palarm; } - p->palarm = 0; + up->palarm = 0; if(alarms.head) { l = &alarms.head; for(f = *l; f; f = f->palarm) { if(f->alarm > when) { - p->palarm = f; - *l = p; + up->palarm = f; + *l = up; goto done; } l = &f->palarm; } - *l = p; + *l = up; } else - alarms.head = p; + alarms.head = up; done: - p->alarm = when; + up->alarm = when; qunlock(&alarms); return old; diff --git a/port/alloc.c b/port/alloc.c index d03cad60c7f9148057896425bee5c9af46fd2a1f..24196593bf3db9aefe45d57fb930de04cf023391 100644 --- a/port/alloc.c +++ b/port/alloc.c @@ -263,7 +263,7 @@ malloc(ulong size) int pow, n; Bucket *bp, *nbp; - for(pow = 3; pow < Maxpow; pow++) + for(pow = 3; pow <= Maxpow; pow++) if(size <= (1<next; - if(bp->magic != 0 || bp->size != pow){ - unlock(&arena); - panic("malloc bp %lux magic %lux size %d next %lux pow %d", bp, - bp->magic, bp->size, bp->next, pow); - } - bp->magic = Magic2n; unlock(&arena); - memset(bp->data, 0, size); + if(bp->magic != 0) + panic("malloc"); + + bp->magic = Magic2n; + + memset(bp->data, 0, size); return bp->data; } unlock(&arena); @@ -297,16 +296,18 @@ good: if(bp == nil) return nil; - nbp = bp; + next = (ulong)bp+size; + nbp = (Bucket*)next; lock(&arena); + arena.btab[pow] = nbp; arena.nbuck[pow] += n; - while(--n) { + for(n -= 2; n; n--) { next = (ulong)nbp+size; - nbp = (Bucket*)next; + nbp->next = (Bucket*)next; nbp->size = pow; - nbp->next = arena.btab[pow]; - arena.btab[pow] = nbp; + nbp = nbp->next; } + nbp->size = pow; unlock(&arena); } else { @@ -333,15 +334,15 @@ smalloc(ulong size) p = malloc(size); if(p != nil) return p; - s = u->p->psstate; - u->p->psstate = "Malloc"; + s = up->psstate; + up->psstate = "Malloc"; qlock(&arena.rq); while(waserror()) ; sleep(&arena.r, return0, nil); poperror(); qunlock(&arena.rq); - u->p->psstate = s; + up->psstate = s; } pexit(Enomem, 1); return 0; @@ -364,12 +365,12 @@ free(void *ptr) Bucket *bp, **l; bp = (Bucket*)((ulong)ptr - bdatoff); - l = &arena.btab[bp->size]; - - lock(&arena); if(bp->magic != Magic2n) panic("free"); + bp->magic = 0; + lock(&arena); + l = &arena.btab[bp->size]; bp->next = *l; *l = bp; unlock(&arena); diff --git a/port/auth.c b/port/auth.c index 2eecfb4a7e1cbee83937be24c83bc5d36f039a3e..bcd1fa474984799b6a93128e9f318a78d159a13e 100644 --- a/port/auth.c +++ b/port/auth.c @@ -15,18 +15,15 @@ struct Crypt char tbuf[TICKETLEN]; /* remote ticket */ }; -typedef struct Session Session; struct Session { Lock; - Lock send; Crypt *cache; /* cache of tickets */ char cchal[CHALLEN]; /* client challenge */ char schal[CHALLEN]; /* server challenge */ char authid[NAMELEN]; /* server encryption uid */ char authdom[DOMLEN]; /* server encryption domain */ ulong cid; /* challenge id */ - int valid; }; struct @@ -45,7 +42,7 @@ char hostdomain[DOMLEN]; int iseve(void) { - return strcmp(eve, u->p->user) == 0; + return strcmp(eve, up->user) == 0; } /* @@ -111,24 +108,21 @@ sysfsession(ulong *arg) nexterror(); } - /* add a session structure to the channel if it has none */ - lock(c); + /* + * if two processes get here at the same + * time with no session exchanged, we have + * a race. + */ s = c->session; if(s == 0){ + /* + * no session exchanged yet + */ s = malloc(sizeof(Session)); - if(s == 0){ - unlock(c); + if(s == 0) error(Enomem); - } - c->session = s; - } - unlock(c); - - /* back off if someone else is doing an fsession */ - while(!canlock(&s->send)) - sched(); + memset(s, 0, sizeof(Session)); - if(s->valid == 0){ /* * Exchange a session message with the server. * If an error occurs reading or writing, @@ -144,12 +138,13 @@ sysfsession(ulong *arg) n = convS2M(&f, buf); if((*devtab[c->type].write)(c, buf, n, 0) != n) error(Emountrpc); + dkhack: n = (*devtab[c->type].read)(c, buf, sizeof buf, 0); if(n == 2 && buf[0] == 'O' && buf[1] == 'K') - n = (*devtab[c->type].read)(c, buf, sizeof buf, 0); + goto dkhack; poperror(); if(convM2S(buf, &f, n) == 0){ - unlock(&s->send); + free(s); error(Emountrpc); } switch(f.type){ @@ -159,39 +154,34 @@ sysfsession(ulong *arg) memmove(s->authdom, f.authdom, DOMLEN); break; case Rerror: - unlock(&s->send); + free(s); error(f.ename); default: - unlock(&s->send); + free(s); error(Emountrpc); } } - s->valid = 1; + c->session = s; } - unlock(&s->send); /* * If server requires no ticket, or user is "none", or a ticket * is already cached, zero the request type */ tr.type = AuthTreq; - if(strcmp(u->p->user, "none") == 0 || s->authid[0] == 0) + if(strcmp(up->user, "none") == 0 || c->session->authid[0] == 0) tr.type = 0; - else{ - lock(s); - for(cp = s->cache; cp; cp = cp->next) - if(strcmp(cp->t.cuid, u->p->user) == 0){ - tr.type = 0; - break; - } - unlock(s); - } + else for(cp = s->cache; cp; cp = cp->next) + if(strcmp(cp->t.cuid, up->user) == 0){ + tr.type = 0; + break; + } /* create ticket request */ - memmove(tr.chal, s->schal, CHALLEN); - memmove(tr.authid, s->authid, NAMELEN); - memmove(tr.authdom, s->authdom, DOMLEN); - memmove(tr.uid, u->p->user, NAMELEN); + memmove(tr.chal, c->session->schal, CHALLEN); + memmove(tr.authid, c->session->authid, NAMELEN); + memmove(tr.authdom, c->session->authdom, DOMLEN); + memmove(tr.uid, up->user, NAMELEN); memmove(tr.hostid, eve, NAMELEN); convTR2M(&tr, (char*)arg[1]); @@ -229,7 +219,7 @@ sysfauth(ulong *arg) convM2T(tbuf, &cp->t, evekey); if(cp->t.num != AuthTc) error("bad AuthTc in ticket"); - if(strncmp(u->p->user, cp->t.cuid, NAMELEN) != 0) + if(strncmp(up->user, cp->t.cuid, NAMELEN) != 0) error("bad uid in ticket"); if(memcmp(cp->t.chal, s->schal, CHALLEN) != 0) error("bad chal in ticket"); @@ -239,7 +229,7 @@ sysfauth(ulong *arg) lock(s); l = &s->cache; for(ncp = s->cache; ncp; ncp = *l){ - if(strcmp(ncp->t.cuid, u->p->user) == 0){ + if(strcmp(ncp->t.cuid, up->user) == 0){ *l = ncp->next; freecrypt(ncp); break; @@ -278,7 +268,7 @@ authrequest(Session *s, Fcall *f) ulong id, dofree; /* no authentication if user is "none" or if no ticket required by remote */ - if(s == 0 || s->authid[0] == 0 || strcmp(u->p->user, "none") == 0){ + if(s == 0 || s->authid[0] == 0 || strcmp(up->user, "none") == 0){ memset(f->ticket, 0, TICKETLEN); memset(f->auth, 0, AUTHENTLEN); return 0; @@ -288,7 +278,7 @@ authrequest(Session *s, Fcall *f) dofree = 0; lock(s); for(cp = s->cache; cp; cp = cp->next) - if(strcmp(cp->t.cuid, u->p->user) == 0) + if(strcmp(cp->t.cuid, up->user) == 0) break; id = s->cid++; @@ -302,8 +292,8 @@ authrequest(Session *s, Fcall *f) cp = newcrypt(); cp->t.num = AuthTs; memmove(cp->t.chal, s->schal, CHALLEN); - memmove(cp->t.cuid, u->p->user, NAMELEN); - memmove(cp->t.suid, u->p->user, NAMELEN); + memmove(cp->t.cuid, up->user, NAMELEN); + memmove(cp->t.suid, up->user, NAMELEN); memmove(cp->t.key, evekey, DESKEYLEN); convT2M(&cp->t, f->ticket, evekey); dofree = 1; @@ -333,12 +323,12 @@ authreply(Session *s, ulong id, Fcall *f) lock(s); for(cp = s->cache; cp; cp = cp->next) - if(strcmp(cp->t.cuid, u->p->user) == 0) + if(strcmp(cp->t.cuid, up->user) == 0) break; unlock(s); /* we're getting around authentication */ - if(s == 0 || cp == 0 || s->authid[0] == 0 || strcmp(u->p->user, "none") == 0) + if(s == 0 || cp == 0 || s->authid[0] == 0 || strcmp(up->user, "none") == 0) return; convM2A(f->rauth, &cp->a, cp->t.key); @@ -361,8 +351,8 @@ authreply(Session *s, ulong id, Fcall *f) * * The protocol is * 1) read ticket request from #c/authenticate - * 2) write ticket+authenticator to #c/authenticate. if it matches - * the challenge the user is changed to the suid field of the ticket + * 2) write ticket to #c/authenticate. if it matchs the challenge the + * user is changed to the suid field of the ticket * 3) read authenticator (to confirm this is the server advertised) */ long @@ -380,13 +370,12 @@ authread(Chan *c, char *a, int n) error(Ebadarg); c->aux = newcrypt(); cp = c->aux; - memset(&tr, 0, sizeof(tr)); tr.type = AuthTreq; strcpy(tr.hostid, eve); strcpy(tr.authid, eve); strcpy(tr.authdom, hostdomain); - strcpy(tr.uid, u->p->user); + strcpy(tr.uid, up->user); for(i = 0; i < CHALLEN; i++) tr.chal[i] = nrand(256); memmove(cp->a.chal, tr.chal, CHALLEN); @@ -398,13 +387,10 @@ authread(Chan *c, char *a, int n) if(n != AUTHENTLEN) error(Ebadarg); cp = c->aux; - cp->a.num = AuthAs; memmove(cp->a.chal, cp->t.chal, CHALLEN); cp->a.id = 0; - convA2M(&cp->a, cp->tbuf, cp->t.key); - memmove(a, cp->tbuf, AUTHENTLEN); - + convA2M(&cp->a, a, cp->t.key); freecrypt(cp); c->aux = 0; } @@ -416,23 +402,15 @@ authwrite(Chan *c, char *a, int n) { Crypt *cp; - if(n != TICKETLEN+AUTHENTLEN) + if(n != TICKETLEN) error(Ebadarg); if(c->aux == 0) error(Ebadarg); cp = c->aux; - - memmove(cp->tbuf, a, TICKETLEN); - convM2T(cp->tbuf, &cp->t, evekey); + convM2T(a, &cp->t, evekey); if(cp->t.num != AuthTs || memcmp(cp->a.chal, cp->t.chal, CHALLEN)) error(Eperm); - - memmove(cp->tbuf, a+TICKETLEN, AUTHENTLEN); - convM2A(cp->tbuf, &cp->a, cp->t.key); - if(cp->a.num != AuthAc || memcmp(cp->a.chal, cp->t.chal, CHALLEN)) - error(Eperm); - - memmove(u->p->user, cp->t.suid, NAMELEN); + memmove(up->user, cp->t.suid, NAMELEN); return n; } @@ -451,64 +429,14 @@ authcheck(Chan *c, char *a, int n) if(c->aux == 0) c->aux = newcrypt(); cp = c->aux; - - memmove(cp->tbuf, a, TICKETLEN); - convM2T(cp->tbuf, &cp->t, evekey); + convM2T(a, &cp->t, evekey); if(cp->t.num != AuthTc) error(Ebadarg); - if(strcmp(u->p->user, cp->t.cuid)) + if(strcmp(up->user, cp->t.cuid)) error(cp->t.cuid); - - memmove(cp->tbuf, a+TICKETLEN, AUTHENTLEN); - convM2A(cp->tbuf, &cp->a, cp->t.key); + convM2A(a+TICKETLEN, &cp->a, cp->t.key); if(cp->a.num != AuthAs || memcmp(cp->t.chal, cp->a.chal, CHALLEN)) error(Eperm); - - return n; -} - -/* - * called by devcons() for #c/authenticator - * - * a read after a write of a ticket returns an authenticator - * for that ticket. - */ -long -authentwrite(Chan *c, char *a, int n) -{ - Crypt *cp; - - if(n != TICKETLEN) - error(Ebadarg); - if(c->aux == 0) - c->aux = newcrypt(); - cp = c->aux; - - memmove(cp->tbuf, a, TICKETLEN); - convM2T(cp->tbuf, &cp->t, evekey); - if(cp->t.num != AuthTc || strcmp(cp->t.cuid, u->p->user)){ - freecrypt(cp); - c->aux = 0; - error(Ebadarg); - } - - return n; -} -long -authentread(Chan *c, char *a, int n) -{ - Crypt *cp; - - cp = c->aux; - if(cp == 0) - error("authenticator read must follow a write"); - - cp->a.num = AuthAc; - memmove(cp->a.chal, cp->t.chal, CHALLEN); - cp->a.id = 0; - convA2M(&cp->a, cp->tbuf, cp->t.key); - memmove(a, cp->tbuf, AUTHENTLEN); - return n; } @@ -557,8 +485,8 @@ userwrite(char *a, int n) error(Ebadarg); if(strcmp(a, "none") != 0) error(Eperm); - memset(u->p->user, 0, NAMELEN); - strcpy(u->p->user, "none"); + memset(up->user, 0, NAMELEN); + strcpy(up->user, "none"); return n; } @@ -581,7 +509,7 @@ hostownerwrite(char *a, int n) if(buf[0] == 0) error(Ebadarg); memmove(eve, buf, NAMELEN); - memmove(u->p->user, buf, NAMELEN); + memmove(up->user, buf, NAMELEN); return n; } diff --git a/port/chan.c b/port/chan.c index 0c849de978476195f78a2612197cfcb0835f19da..1411080c0b72f9152fd49e0bfe30b5d251af76f3 100644 --- a/port/chan.c +++ b/port/chan.c @@ -8,8 +8,9 @@ struct { Lock; - Chan *free; int fid; + Chan *free; + Chan *list; }chanalloc; int @@ -37,6 +38,18 @@ decref(Ref *r) return x; } +void +chanrec(Mnt *m) +{ + Chan *c; + + lock(&chanalloc); + for(c = chanalloc.list; c; c = c->link) + if(c->mntptr == m) + c->flag |= CRECOV; + unlock(&chanalloc); +} + void chandevreset(void) { @@ -59,21 +72,20 @@ Chan* newchan(void) { Chan *c; - int nfid; - - SET(nfid); lock(&chanalloc); c = chanalloc.free; - if(c) + if(c != 0) chanalloc.free = c->next; - else - nfid = ++chanalloc.fid; unlock(&chanalloc); if(c == 0) { c = smalloc(sizeof(Chan)); - c->fid = nfid; + lock(&chanalloc); + c->fid = ++chanalloc.fid; + c->link = chanalloc.list; + chanalloc.list = c; + unlock(&chanalloc); } /* if you get an error before associating with a dev, @@ -87,6 +99,7 @@ newchan(void) c->stream = 0; c->aux = 0; c->mchan = 0; + c->path = 0; c->mqid = (Qid){0, 0}; return c; } @@ -95,10 +108,19 @@ void chanfree(Chan *c) { c->flag = CFREE; + if(c->session){ freesession(c->session); c->session = 0; } + + /* + * Channel can be closed before a path is created or the last + * channel in a mount which has already cleared its pt names + */ + if(c->path) + decref(c->path); + lock(&chanalloc); c->next = chanalloc.free; chanalloc.free = c; @@ -108,16 +130,25 @@ chanfree(Chan *c) void close(Chan *c) { - if(c->flag & CFREE) + if(c->flag&CFREE) panic("close"); - if(decref(c) == 0){ - if(!waserror()) { - (*devtab[c->type].close)(c); - poperror(); - } - chanfree(c); + if(decref(c)) + return; + + if(!waserror()) { + (*devtab[c->type].close)(c); + poperror(); } + +/* ASSERT */ +if(c->path && c->path->ref == 0) { + char buf[64]; + ptpath(c->path, buf, sizeof(buf)); + print(">>%s %c %d %lux.%lux\n", + buf, devchar[c->type], c->dev, c->qid.path, c->qid.vers); +} + chanfree(c); } int @@ -141,12 +172,12 @@ eqchan(Chan *a, Chan *b, int pathonly) } int -mount(Chan *new, Chan *old, int flag) +mount(Chan *new, Chan *old, int flag, char *spec) { Pgrp *pg; + int order; Mount *nm, *f; Mhead *m, **l; - int order; if(CHDIR & (old->qid.path^new->qid.path)) error(Emount); @@ -156,7 +187,7 @@ mount(Chan *new, Chan *old, int flag) if((old->qid.path&CHDIR)==0 && order != MREPL) error(Emount); - pg = u->p->pgrp; + pg = up->pgrp; wlock(&pg->ns); if(waserror()) { wunlock(&pg->ns); @@ -177,7 +208,7 @@ mount(Chan *new, Chan *old, int flag) m->hash = *l; *l = m; if(order != MREPL) - m->mount = newmount(m, old); + m->mount = newmount(m, old, 0, 0); } if(m->mount && order == MREPL) { @@ -185,7 +216,9 @@ mount(Chan *new, Chan *old, int flag) m->mount = 0; } - nm = newmount(m, new); + nm = newmount(m, new, flag, spec); + + if(flag & MCREATE) new->flag |= CCREATE; @@ -211,7 +244,7 @@ unmount(Chan *mnt, Chan *mounted) Mhead *m, **l; Mount *f, **p; - pg = u->p->pgrp; + pg = up->pgrp; wlock(&pg->ns); l = &MOUNTH(pg, mnt); @@ -270,7 +303,7 @@ domount(Chan *c) Chan *nc; Mhead *m; - pg = u->p->pgrp; + pg = up->pgrp; rlock(&pg->ns); if(waserror()) { runlock(&pg->ns); @@ -282,6 +315,7 @@ domount(Chan *c) if(eqchan(m->from, c, 1)) { nc = clone(m->mount->to, 0); nc->mnt = m->mount; + nc->xmnt = nc->mnt; nc->mountid = m->mount->mountid; close(c); c = nc; @@ -300,7 +334,7 @@ undomount(Chan *c) Mhead **h, **he, *f; Mount *t; - pg = u->p->pgrp; + pg = up->pgrp; rlock(&pg->ns); if(waserror()) { runlock(&pg->ns); @@ -328,17 +362,15 @@ Chan* walk(Chan *ac, char *name, int domnt) { Pgrp *pg; - Chan *c = 0; + Chan *c; Mount *f; int dotdot; - if(*name == '\0') + if(name[0] == '\0') return ac; dotdot = 0; - if(name[0] == '.') - if(name[1] == '.') - if(name[2] == '\0') { + if(name[0] == '.' && name[1] == '.' && name[2] == '\0') { ac = undomount(ac); dotdot = 1; } @@ -354,7 +386,9 @@ walk(Chan *ac, char *name, int domnt) if(ac->mnt == 0) return 0; - pg = u->p->pgrp; + c = 0; + pg = up->pgrp; + rlock(&pg->ns); if(waserror()) { runlock(&pg->ns); @@ -372,20 +406,22 @@ walk(Chan *ac, char *name, int domnt) poperror(); runlock(&pg->ns); - if(c) { - if(dotdot) - c = undomount(c); - c->mnt = 0; - if(domnt) { - if(waserror()) { - close(c); - nexterror(); - } - c = domount(c); - poperror(); + if(c == 0) + return 0; + + if(dotdot) + c = undomount(c); + + c->mnt = 0; + if(domnt) { + if(waserror()) { + close(c); + nexterror(); } - close(ac); + c = domount(c); + poperror(); } + close(ac); return c; } @@ -399,7 +435,7 @@ createdir(Chan *c) Chan *nc; Mount *f; - pg = u->p->pgrp; + pg = up->pgrp; rlock(&pg->ns); if(waserror()) { runlock(&pg->ns); @@ -419,6 +455,45 @@ createdir(Chan *c) return 0; /* not reached */ } +Chan* +mchan(char *id) +{ + Chan *c; + Pgrp *pg; + Mount *t; + int mdev; + ulong mountid; + Mhead **h, **he, *f; + + mountid = strtoul(id, 0, 0); + mdev = devno('M', 0); + + pg = up->pgrp; + rlock(&pg->ns); + if(waserror()) { + runlock(&pg->ns); + nexterror(); + } + + he = &pg->mnthash[MNTHASH]; + for(h = pg->mnthash; h < he; h++) { + for(f = *h; f; f = f->hash) { + for(t = f->mount; t; t = t->next) { + c = t->to; + if(c->type == mdev && c->mntptr->id == mountid) { + c = c->mntptr->c; + incref(c); + runlock(&pg->ns); + poperror(); + return c; + } + } + } + } + error(Enonexist); + return 0; +} + void saveregisters(void) { @@ -431,60 +506,58 @@ saveregisters(void) Chan* namec(char *name, int amode, int omode, ulong perm) { - Chan *c, *nc, *cc; - int t; Rune r; - int mntok, isdot; char *p; char *elem; + int t, n; + int mntok, isdot; + Chan *c, *nc, *cc; char createerr[ERRLEN]; if(name[0] == 0) error(Enonexist); - /* - * Make sure all of name is o.k. first byte is validated - * externally so if it's a kernel address we know it's o.k. - */ - if(!((ulong)name & KZERO)){ + if(!((ulong)name & KZERO)) { p = name; t = BY2PG-((ulong)p&(BY2PG-1)); - while(vmemchr(p, 0, t) == 0){ + while(vmemchr(p, 0, t) == 0) { p += t; t = BY2PG; } } - elem = u->elem; + elem = up->elem; mntok = 1; isdot = 0; - if(name[0] == '/') { - c = clone(u->slash, 0); - /* - * Skip leading slashes. - */ + switch(name[0]) { + case '/': + c = clone(up->slash, 0); name = skipslash(name); - } - else - if(name[0] == '#') { + break; + case '#': mntok = 0; - name++; - name += chartorune(&r, name); - if(r == 'M') - error(Enonexist); + elem[0] = 0; + n = 0; + while(*name && (*name != '/' || n < 2)) + elem[n++] = *name++; + elem[n] = '\0'; + n = chartorune(&r, elem+1)+1; + if(r == 'M') { + name = skipslash(name); + if(*name) + error(Eperm); + return mchan(elem+n); + } t = devno(r, 1); if(t == -1) error(Ebadsharp); - if(*name == '/'){ - name = skipslash(name); - elem[0]=0; - }else - name = nextelem(name, elem); - c = (*devtab[t].attach)(elem); - } - else { - c = clone(u->dot, 0); - name = skipslash(name); /* eat leading ./ */ + + c = (*devtab[t].attach)(elem+n); + name = skipslash(name); + break; + default: + c = clone(up->dot, 0); + name = skipslash(name); if(*name == 0) isdot = 1; } @@ -503,26 +576,21 @@ namec(char *name, int amode, int omode, ulong perm) if(mntok && !isdot && !(amode==Amount && elem[0]==0)) c = domount(c); /* see case Atodir below */ - /* - * How to treat the last element of the name depends on the operation. - * Therefore do all but the last element by the easy algorithm. - */ - while(*name){ - if((nc=walk(c, elem, mntok)) == 0) + while(*name) { + nc = walk(c, elem, mntok); + if(nc == 0) error(Enonexist); c = nc; name = nextelem(name, elem); } - /* - * Last element; act according to type of access. - */ switch(amode){ case Aaccess: if(isdot) c = domount(c); - else{ - if((nc=walk(c, elem, mntok)) == 0) + else { + nc = walk(c, elem, mntok); + if(nc == 0) error(Enonexist); c = nc; } @@ -533,7 +601,8 @@ namec(char *name, int amode, int omode, ulong perm) * Directories (e.g. for cd) are left before the mount point, * so one may mount on / or . and see the effect. */ - if((nc=walk(c, elem, 0)) == 0) + nc = walk(c, elem, 0); + if(nc == 0) error(Enonexist); c = nc; if(!(c->qid.path & CHDIR)) @@ -543,8 +612,9 @@ namec(char *name, int amode, int omode, ulong perm) case Aopen: if(isdot) c = domount(c); - else{ - if((nc=walk(c, elem, mntok)) == 0) + else { + nc = walk(c, elem, mntok); + if(nc == 0) error(Enonexist); c = nc; } @@ -560,11 +630,12 @@ namec(char *name, int amode, int omode, ulong perm) case Amount: /* - * When mounting on an already mounted upon directory, one wants - * subsequent mounts to be attached to the original directory, not - * the replacement. + * When mounting on an already mounted upon directory, + * one wants subsequent mounts to be attached to the + * original directory, not the replacement. */ - if((nc=walk(c, elem, 0)) == 0) + nc = walk(c, elem, 0); + if(nc == 0) error(Enonexist); c = nc; break; @@ -585,7 +656,8 @@ namec(char *name, int amode, int omode, ulong perm) nexterror(); } nameok(elem); - if((nc=walk(cc, elem, 1)) != 0){ + nc = walk(cc, elem, 1); + if(nc != 0) { poperror(); close(c); c = nc; @@ -602,11 +674,11 @@ namec(char *name, int amode, int omode, ulong perm) c = createdir(c); /* - * protect against the open/create race. This is not a complete - * fix. It just reduces the window. + * protect against the open/create race. + * This is not a complete fix. It just reduces the window. */ if(waserror()) { - strcpy(createerr, u->error); + strcpy(createerr, up->error); nc = walk(c, elem, 1); if(nc == 0) error(createerr); @@ -675,20 +747,20 @@ char* nextelem(char *name, char *elem) { int w; - char *nend; + char *end; Rune r; if(*name == '/') error(Efilename); - nend = utfrune(name, '/'); - if(nend == 0) - nend = strchr(name, 0); - w = nend-name; + end = utfrune(name, '/'); + if(end == 0) + end = strchr(name, 0); + w = end-name; if(w >= NAMELEN) error(Efilename); memmove(elem, name, w); elem[w] = 0; - while(name < nend){ + while(name < end){ name += chartorune(&r, name); if(rqid = (Qid){CHDIR, 0}; c->type = devno(tc, 0); + if(tc != 'M') { + sprint(buf, "#%C%s", tc, spec); + c->path = ptenter(&syspt, 0, buf); + } return c; } @@ -78,8 +83,10 @@ devclone(Chan *c, Chan *nc) { if(c->flag & COPEN) panic("clone of open file type %C\n", devchar[c->type]); + if(nc == 0) nc = newchan(); + nc->type = c->type; nc->dev = c->dev; nc->mode = c->mode; @@ -91,6 +98,8 @@ devclone(Chan *c, Chan *nc) nc->aux = c->aux; nc->mchan = c->mchan; nc->mqid = c->mqid; + nc->path = c->path; + incref(nc->path); return nc; } @@ -99,25 +108,30 @@ devwalk(Chan *c, char *name, Dirtab *tab, int ntab, Devgen *gen) { long i; Dir dir; + Path *op; isdir(c); if(name[0]=='.' && name[1]==0) return 1; - for(i=0;; i++) + for(i=0;; i++) { switch((*gen)(c, tab, ntab, i, &dir)){ case -1: - strncpy(u->error, Enonexist, NAMELEN); + strncpy(up->error, Enonexist, NAMELEN); return 0; case 0: continue; case 1: if(strcmp(name, dir.name) == 0){ c->qid = dir.qid; + op = c->path; + c->path = ptenter(&syspt, op, name); + decref(op); return 1; } continue; } - return 1; /* not reached */ + } + return 0; /* not reached */ } void @@ -129,23 +143,23 @@ devstat(Chan *c, char *db, Dirtab *tab, int ntab, Devgen *gen) for(i=0;; i++) switch((*gen)(c, tab, ntab, i, &dir)){ case -1: - /* - * given a channel, we cannot derive the directory name - * that the channel was generated from since it was lost - * by namec. - */ + /* + * given a channel, we cannot derive the directory name + * that the channel was generated from since it was lost + * by namec. + */ if(c->qid.path & CHDIR){ - devdir(c, c->qid, ".", 0L, eve, CHDIR|0775, &dir); + devdir(c, c->qid, c->path->elem, i*DIRLEN, eve, CHDIR|0700, &dir); convD2M(&dir, db); return; } - print("%s %s: devstat %C %lux\n", u->p->text, u->p->user, - devchar[c->type], c->qid.path); + print("%s %s: devstat %C %lux\n", up->text, up->user, + devchar[c->type], c->qid.path); error(Enonexist); case 0: break; case 1: - if(eqqid(c->qid, dir.qid)){ + if(eqqid(c->qid, dir.qid)) { if(c->flag&CMSG) dir.mode |= CHMOUNT; convD2M(&dir, db); @@ -162,7 +176,7 @@ devdirread(Chan *c, char *d, long n, Dirtab *tab, int ntab, Devgen *gen) Dir dir; k = c->offset/DIRLEN; - for(m=0; mqid, dir.qid)) { - if(strcmp(u->p->user, dir.uid) == 0) /* User */ + if(strcmp(up->user, dir.uid) == 0) mode = dir.mode; - else if(strcmp(u->p->user, eve) == 0) /* eve is group */ + else + if(strcmp(up->user, eve) == 0) mode = dir.mode<<3; else - mode = dir.mode<<6; /* Other */ + mode = dir.mode<<6; t = access[omode&3]; if((t & mode) == t) @@ -210,7 +227,8 @@ devopen(Chan *c, int omode, Dirtab *tab, int ntab, Devgen *gen) } break; } - Return: + } +Return: c->offset = 0; if((c->qid.path&CHDIR) && omode!=OREAD) error(Eperm); diff --git a/port/devarp.c b/port/devarp.c index c4cd97c9c5b7e9de7a2aeb9e36ad40b367cc5e06..fd9595c117b0b3a6bd90634373093fb5dc17f3e1 100644 --- a/port/devarp.c +++ b/port/devarp.c @@ -66,11 +66,6 @@ Dirtab arptab[]={ }; #define Narptab (sizeof(arptab)/sizeof(Dirtab)) -enum -{ - Narp= 64, /* size of arp cache */ -}; - /* * create a 2-level directory */ @@ -102,10 +97,10 @@ arpreset(void) { Arpcache *ap, *ep; - arp = xalloc(sizeof(Arpcache) * Narp); + arp = xalloc(sizeof(Arpcache) * conf.arp); arphash = (Arpcache **)xalloc(sizeof(Arpcache *) * Arphashsize); - ep = &arp[Narp]; + ep = &arp[conf.arp]; for(ap = arp; ap < ep; ap++) { ap->frwd = ap+1; ap->prev = ap-1; @@ -115,7 +110,7 @@ arpreset(void) arp[0].prev = 0; arplruhead = arp; - ap = &arp[Narp-1]; + ap = &arp[conf.arp-1]; ap->frwd = 0; arplrutail = ap; newqinfo(&arpinfo); @@ -216,7 +211,7 @@ arpread(Chan *c, void *a, long n, ulong offset) switch((int)(c->qid.path&~CHDIR)){ case arpdataqid: bytes = c->offset; - while(bytes < Narp*ARP_ENTRYLEN && n) { + while(bytes < conf.arp*ARP_ENTRYLEN && n) { ap = &arp[bytes/ARP_ENTRYLEN]; part = bytes%ARP_ENTRYLEN; @@ -393,7 +388,7 @@ arpflush(void) { Arpcache *ap, *ep; - ep = &arp[Narp]; + ep = &arp[conf.arp]; for(ap = arp; ap < ep; ap++) ap->status = ARP_FREE; } diff --git a/port/devbit.c b/port/devbit.c index 56c68eff005aebe2c97b4db78ced04850a5d2f9d..600494713ff1295d331f0d5de52154c9a2355c1f 100644 --- a/port/devbit.c +++ b/port/devbit.c @@ -104,31 +104,6 @@ void bitstring(GBitmap*, Point, GFont*, uchar*, long, Fcode); void bitloadchar(GFont*, int, GSubfont*, int); extern GBitmap gscreen; -typedef struct Mouseinfo Mouseinfo; -typedef struct Cursorinfo Cursorinfo; - -struct Mouseinfo{ - /* - * First three fields are known in some l.s's - */ - int dx; - int dy; - int track; /* l.s has updated dx & dy */ - Mouse; - int redraw; /* update cursor on screen */ - ulong counter; /* increments every update */ - ulong lastcounter; /* value when /dev/mouse read */ - Rendez r; -}; - -struct Cursorinfo{ - Cursor; - Lock; - int visible; /* on screen */ - int disable; /* from being used */ - Rectangle r; /* location */ -}; - Mouseinfo mouse; Cursorinfo cursor; int mouseshifted; @@ -549,16 +524,21 @@ bitread(Chan *c, void *va, long n, ulong offset) */ if(n < 14) error(Ebadblt); - while(mousechanged(0) == 0) + Again: + while(mouse.changed == 0) sleep(&mouse.r, mousechanged, 0); lock(&cursor); + if(mouse.changed == 0){ + unlock(&cursor); + goto Again; + } p = va; p[0] = 'm'; p[1] = mouse.buttons; BPLONG(p+2, mouse.xy.x); BPLONG(p+6, mouse.xy.y); BPLONG(p+10, TK2MS(MACHP(0)->ticks)); - mouse.lastcounter = mouse.counter; + mouse.changed = 0; unlock(&cursor); return 14; } @@ -732,7 +712,7 @@ bitread(Chan *c, void *va, long n, ulong offset) error(Ebadblt); for(j = 0; j < nw; j++){ if(bit.mid == 0){ - getcolor(flipping? nw-j-1 : j, &rv, &gv, &bv); + getcolor(flipping? ~j : j, &rv, &gv, &bv); }else{ rv = j; for(off = 32-l; off > 0; off -= l) @@ -1603,7 +1583,6 @@ bitwrite(Chan *c, void *va, long n, ulong offset) pt1.y = BGLONG(p+5); if(ptinrect(pt1, gscreen.r)){ mouse.xy = pt1; - mouse.redraw = 1; mouse.track = 1; mouseclock(); } @@ -2053,51 +2032,61 @@ cursoroff(int dolock) unlock(&cursor); } -/* - * called by the clock routine to redraw the cursor - */ void -mouseclock(void) +mousedelta(int b, int dx, int dy) /* called at higher priority */ { - if(mouse.track){ - mousetrack(mouse.buttons, mouse.dx, mouse.dy); - mouse.track = 0; - mouse.dx = 0; - mouse.dy = 0; - } - if(mouse.redraw && canlock(&cursor)){ - mouse.redraw = 0; - cursoroff(0); - cursoron(0); - mousescreenupdate(); - unlock(&cursor); - } + mouse.dx += dx; + mouse.dy += dy; + mouse.newbuttons = b; + mouse.track = 1; } -/* - * called at interrupt level to update the structure and - * awaken any waiting procs. - */ void -mousetrack(int b, int dx, int dy) +mousebuttons(int b) /* called at higher priority */ +{ + /* + * It is possible if you click very fast and get bad luck + * you could miss a button click (down up). Doesn't seem + * likely or important enough to worry about. + */ + mouse.newbuttons = b; + mouse.track = 1; /* aggressive but o.k. */ + mouseclock(); +} + +void +mouseupdate(int dolock) { int x, y; - x = mouse.xy.x + dx; + if(!mouse.track || (dolock && !canlock(&cursor))) + return; + + x = mouse.xy.x + mouse.dx; if(x < gscreen.r.min.x) x = gscreen.r.min.x; if(x >= gscreen.r.max.x) x = gscreen.r.max.x; - y = mouse.xy.y + dy; + y = mouse.xy.y + mouse.dy; if(y < gscreen.r.min.y) y = gscreen.r.min.y; if(y >= gscreen.r.max.y) y = gscreen.r.max.y; - mouse.counter++; + cursoroff(0); mouse.xy = Pt(x, y); - mouse.buttons = b; - mouse.redraw = 1; - wakeup(&mouse.r); + cursoron(0); + mousescreenupdate(); + mouse.dx = 0; + mouse.dy = 0; + mouse.clock = 0; + mouse.track = 0; + mouse.buttons = mouse.newbuttons; + mouse.changed = 1; + + if(dolock){ + unlock(&cursor); + wakeup(&mouse.r); + } } /* @@ -2118,7 +2107,6 @@ m3mouseputc(IOQ *q, int c) static int middle; static uchar b[] = { 0, 4, 1, 5, 0, 2, 1, 5 }; short x; - int dx, dy, newbuttons; USED(q); /* @@ -2128,20 +2116,20 @@ m3mouseputc(IOQ *q, int c) if((c&0x40) == 0){ /* an extra byte gets sent for the middle button */ middle = (c&0x20) ? 2 : 0; - newbuttons = (mouse.buttons & ~2) | middle; - mousetrack(newbuttons, 0, 0); + mousebuttons((mouse.buttons & ~2) | middle); return 0; } } msg[nb] = c; if(++nb == 3){ nb = 0; - newbuttons = middle | b[(msg[0]>>4)&3 | (mouseshifted ? 4 : 0)]; + mouse.newbuttons = middle | b[(msg[0]>>4)&3 | (mouseshifted ? 4 : 0)]; x = (msg[0]&0x3)<<14; - dx = (x>>8) | msg[1]; + mouse.dx = (x>>8) | msg[1]; x = (msg[0]&0xc)<<12; - dy = (x>>8) | msg[2]; - mousetrack(newbuttons, dx, dy); + mouse.dy = (x>>8) | msg[2]; + mouse.track = 1; + mouseclock(); } return 0; } @@ -2157,7 +2145,6 @@ mouseputc(IOQ *q, int c) static short msg[5]; static int nb; static uchar b[] = {0, 4, 2, 6, 1, 5, 3, 7, 0, 2, 2, 6, 1, 5, 3, 7}; - int dx, dy, newbuttons; USED(q); if((c&0xF0) == 0x80) @@ -2166,10 +2153,11 @@ mouseputc(IOQ *q, int c) if(c & 0x80) msg[nb] |= ~0xFF; /* sign extend */ if(++nb == 5){ - newbuttons = b[((msg[0]&7)^7) | (mouseshifted ? 8 : 0)]; - dx = msg[1]+msg[3]; - dy = -(msg[2]+msg[4]); - mousetrack(newbuttons, dx, dy); + mouse.newbuttons = b[((msg[0]&7)^7) | (mouseshifted ? 8 : 0)]; + mouse.dx = msg[1]+msg[3]; + mouse.dy = -(msg[2]+msg[4]); + mouse.track = 1; + mouseclock(); nb = 0; } return 0; @@ -2179,7 +2167,7 @@ int mousechanged(void *m) { USED(m); - return mouse.lastcounter != mouse.counter; + return mouse.changed; } /* diff --git a/port/devconc.c b/port/devconc.c deleted file mode 100644 index 12e12b59ff138fc7ab9bbdd320262f7c1c5d9b9d..0000000000000000000000000000000000000000 --- a/port/devconc.c +++ /dev/null @@ -1,491 +0,0 @@ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "io.h" -#include "../port/error.h" - -#define concdebug 1 - -#define DPRINT if(concdebug)kprint - -typedef struct Conc Conc; -typedef struct Subdev Subdev; - -/* - * A concentrator. One exists for every stream that a - * conc line discipline is pushed onto. - */ -struct Conc -{ - QLock; - Stream *s; - Queue * wq; - char name[64]; - int ndev; - Subdev *dev; - Block * bp; -}; - -struct Subdev -{ - Conc * cp; - int chan0; - Queue * rq; -}; - -static Lock conclock; -static Conc *concs; - -/* - * Concentrator line discipline (push here). - */ - -static void concstopen(Queue*, Stream*); -static void concstclose(Queue*); -static void concstoput(Queue*, Block*); -static void concstiput(Queue*, Block*); -Qinfo concinfo = -{ - concstiput, - concstoput, - concstopen, - concstclose, - "conc" -}; - -/* - * Stream interface to concentrator device (open here). - */ - -static void concdevstopen(Queue*, Stream*); -static void concdevstclose(Queue*); -static void concdevstoput(Queue*, Block*); -static void concdevstiput(Queue*, Block*); -Qinfo concdevinfo = -{ - concdevstiput, - concdevstoput, - concdevstopen, - concdevstclose, - "concdev" -}; - -static void -concstopen(Queue *q, Stream *s) -{ - DPRINT("concstopen q=0x%ux s=0x%ux\n", q, s); - - RD(q)->ptr = 0; /* (Conc *) for concstiput */ - WR(q)->ptr = s; - - s->opens++; /* Hold this queue in place */ - s->inuse++; -} - -static void -concstclose(Queue *q) -{ - Conc *cp = q->ptr; - Subdev *dp; - Block *bp; - int ndev; - - if(RD(q)->ptr == 0) - return; - DPRINT("concstclose \"%s\"\n", cp->name); - - qlock(cp); - ndev = cp->ndev; - cp->ndev = 0; - for(dp=cp->dev; dp<&cp->dev[ndev]; dp++){ - continue; - bp = allocb(0); - bp->type = M_HANGUP; - PUTNEXT(dp->rq, bp); - } - qunlock(cp); - cp->name[0] = 0; -} - -static Conc * -concalloc(char *name, int aflag) -{ - Conc *free, *cp; - - DPRINT("concalloc \"%s\" %d...", name, aflag); - lock(&conclock); - free = 0; - for(cp = concs; cp < &concs[conf.nconc]; cp++){ - if(strcmp(name, cp->name) == 0){ - unlock(&conclock); - DPRINT("found\n"); - return cp; - } - if(cp->name[0] == 0) - free = cp; - } - if(!aflag || free == 0){ - unlock(&conclock); - DPRINT("not found/none free\n"); - return 0; - } - strncpy(free->name, name, sizeof free->name-1); - unlock(&conclock); - DPRINT("alloc'd\n"); - return free; -} - -static void -concstoput(Queue *q, Block *bp) -{ - Conc *cp = 0; - Subdev *dp; - char *p, *err = 0; - int n, ndev, k; - - if(bp->type != M_CTL || streamparse("config", bp) == 0){ - PUTNEXT(q, bp); - return; - } - if(concdebug){ - char fmt[32]; - sprint(fmt, "concstoput config: %%.%ds\n", bp->wptr-bp->rptr); - kprint(fmt, bp->rptr); - } - if(RD(q)->ptr){ - err = "stream already configured"; - goto out; - } - n = BLEN(bp); - if(bp->wptr >= bp->lim){ - memmove(bp->base, bp->rptr, n); - bp->rptr = bp->base; - bp->wptr = bp->rptr+n; - } - *bp->wptr++ = 0; - p = strchr((char *)bp->rptr, ' '); - if(p == 0){ - err = "bad config command"; - goto out; - } - *p++ = 0; - cp = concalloc((char *)bp->rptr, 1); - bp->rptr = (uchar *)p; - if(cp == 0){ - err = "no free conc's"; - goto out; - } - qlock(cp); - if(cp->ndev){ - err = "conc name in use"; - goto out; - } - p = (char *)bp->rptr; - for(ndev=0; strtoul(p, &p, 0); ndev++) ; - DPRINT("concstoput: ndev=%d\n", ndev); - cp->bp = allocb(ndev*sizeof(Subdev)); - if(cp->bp == 0){ - err = "can't allocb for subdevices"; - cp->name[0] = 0; - goto out; - } - cp->dev = (Subdev *)cp->bp->base; - p = (char *)bp->rptr; - k = 0; - DPRINT("concstoput: chan0="); - for(dp=cp->dev; dp<&cp->dev[ndev]; dp++){ - dp->cp = cp; - dp->chan0 = k; - DPRINT(" %d", dp->chan0); - k += strtoul(p, &p, 0); - dp->rq = 0; - } - DPRINT("\n"); - cp->s = q->ptr; - cp->wq = q; - cp->ndev = ndev; - q->ptr = cp; - q->other->ptr = cp; -out: - freeb(bp); - if(cp) - qunlock(cp); - if(err){ - DPRINT("concstoput: err=\"%s\"\n", err); - error(err); - } -} - -/* - * Simplifying assumption: one put == one message && the channel number - * is in the first block (cf. dkmuxiput). - */ -static void -concstiput(Queue *q, Block *bp) -{ - Conc *cp = q->ptr; - Subdev *dp; - int chan; - - if(bp->type != M_DATA){ - PUTNEXT(q, bp); - return; - } - if(BLEN(bp) < 2 || cp == 0) - goto Drop; - chan = bp->rptr[0] | (bp->rptr[1]<<8); - for(dp=&cp->dev[cp->ndev-1]; dp>=cp->dev; dp--) - if(chan >= dp->chan0) - break; - if(dp < cp->dev || dp->rq == 0) - goto Drop; - chan -= dp->chan0; - bp->rptr[0] = chan; - bp->rptr[1] = chan>>8; - bp->flags |= S_DELIM; /* a process is probably waiting for this */ - PUTNEXT(dp->rq, bp); - return; - -Drop: - freeb(bp); - return; -} - -static void -concdevstopen(Queue *q, Stream *s) -{ - Conc *cp; - Subdev *dp; - - cp = &concs[s->dev]; - qlock(cp); - if(s->id > cp->ndev){ - qunlock(cp); - error("no such subdevice"); - } - dp = &cp->dev[s->id]; - q->ptr = dp; - q->other->ptr = dp; - dp->rq = RD(q); - streamenter(cp->s); - qunlock(cp); -} - -static void -concdevstclose(Queue *q) -{ - Subdev *dp = q->ptr; - Conc *cp = dp->cp; - - qlock(cp); - q->ptr = 0; - q->other->ptr = 0; - dp->rq = 0; - streamexit(cp->s); - qunlock(cp); -} - -/* - * this is only called by concstclose (hangup) - */ -static void -concdevstiput(Queue *q, Block *bp) -{ - PUTNEXT(q, bp); -} - -static void -concdevstoput(Queue *q, Block *bp) -{ - Subdev *dp = q->ptr; - Conc *cp; - int chan; - - if(dp == 0){ - DPRINT("concdevstoput: not config'd, dropped %d\n", BLEN(bp)); - freeb(bp); - return; - } - cp = dp->cp; - qlock(cp); - if(!putq(q, bp)){ /* send only whole messages */ - qunlock(cp); - return; - } - bp = grabq(q); - qunlock(cp); - if(BLEN(bp) < 2 || bp->type != M_DATA){ - DPRINT("concdevstoput: dropped %d\n", BLEN(bp)); - freeb(bp); - return; - } - chan = bp->rptr[0] | (bp->rptr[1]<<8); - chan += dp->chan0; - bp->rptr[0] = chan; - bp->rptr[1] = chan>>8; - PUTNEXT(cp->wq, bp); -} - -void -concreset(void) -{ - concs = xalloc(conf.nconc*sizeof(Conc)); - newqinfo(&concinfo); -} - -void -concinit(void) -{ -} - -Chan * -concattach(char *spec) -{ - Chan *c; - Conc *cp; - - /* - * find a concentrator with the same name (default conc) - */ - if(*spec == 0) - spec = "conc"; - cp = concalloc(spec, 0); - if(cp == 0 || cp->ndev == 0) - error("device not configured"); - - c = devattach('K', spec); - c->dev = cp-concs; - c->qid = (Qid){CHDIR, 0}; - return c; -} - -Chan * -concclone(Chan *c, Chan *nc) -{ - return devclone(c, nc); -} - -#define TOPDIR (CHDIR+1) -#define CHANDIR (CHDIR+2) - -static int -concgen(Chan *c, Dirtab *tab, int ntab, int i, Dir *dp) -{ - Conc *cp; - char buf[16]; - - USED(tab, ntab); - cp = &concs[c->dev]; - switch(c->qid.path){ - case CHDIR: - devdir(c, (Qid){TOPDIR,0}, concs[c->dev].name, 0, eve, 0555, dp); - return i==0 ? 1 : -1; - case TOPDIR: - if(i<0 || i >= cp->ndev) - return -1; - sprint(buf, "%d", i); - devdir(c, (Qid){STREAMQID(i,CHANDIR),0}, buf, 0, eve, 0555, dp); - return 1; - } - return streamgen(c, 0, 0, i, dp); -} - -int -concwalk(Chan *c, char *name) -{ - return devwalk(c, name, 0, 0, concgen); -} - -void -concstat(Chan *c, char *dp) -{ - char buf[16], *name; - Dir dir; - - if(c->qid.path&CHDIR)switch(c->qid.path){ - case CHDIR: - name = "."; - break; - case TOPDIR: - name = concs[c->dev].name; - break; - default: - sprint(name = buf, "%d", STREAMID(c->qid.path)); - break; - }else switch(STREAMTYPE(c->qid.path)){ - case Sdataqid: - name = "data"; - break; - case Sctlqid: - name = "ctl"; - break; - default: - name = "panic"; - break; - } - devdir(c, c->qid, name, 0, eve, (c->qid.path&CHDIR)?0555:0600, &dir); - convD2M(&dir, dp); -} - -Chan * -concopen(Chan *c, int omode) -{ - if(c->qid.path & CHDIR){ - if(omode != OREAD) - error(Eperm); - }else - streamopen(c, &concdevinfo); - c->mode = openmode(omode); - c->flag |= COPEN; - c->offset = 0; - return c; -} - -void -conccreate(Chan *c, char *name, int omode, ulong perm) -{ - USED(c, name, omode, perm); - error(Eperm); -} - -void -concclose(Chan *c) -{ - if(c->stream) - streamclose(c); -} - -long -concread(Chan *c, void *a, long n, ulong offset) -{ - USED(offset); - if(c->stream) - return streamread(c, a, n); - if(c->qid.path & CHDIR) - return devdirread(c, a, n, 0, 0, concgen); - error(Eio); - return -1; /* does not return */ -} - -long -concwrite(Chan *c, void *a, long n, ulong offset) -{ - USED(offset); - return streamwrite(c, a, n, 0); -} - -void -concremove(Chan *c) -{ - USED(c); - error(Eperm); -} - -void -concwstat(Chan *c, char *dp) -{ - USED(c, dp); - error(Eperm); -} diff --git a/port/devcons.c b/port/devcons.c index 561cc940987ac8711cf8aaa51c913b51f1423463..ea1c3dd14eaf00463a4fd9b6cc680e89f07641ec 100644 --- a/port/devcons.c +++ b/port/devcons.c @@ -18,8 +18,8 @@ IOQ lineq; /* lock to getc; interrupt putc's */ IOQ printq; KIOQ kbdq; -static Ref ctl; /* number of opens to the control file */ -static int raw; /* true if raw has been requested on a ctl file */ +static Ref ctl; /* number of opens to the control file */ +static int raw; /* true if ctl file is raw */ char sysname[NAMELEN]; @@ -178,13 +178,13 @@ pprint(char *fmt, ...) Chan *c; int n; - if(u->p->fgrp == 0) + if(up->fgrp == 0) return 0; - c = u->p->fgrp->fd[2]; + c = up->fgrp->fd[2]; if(c==0 || (c->mode!=OWRITE && c->mode!=ORDWR)) return 0; - n = sprint(buf, "%s %d: ", u->p->text, u->p->pid); + n = sprint(buf, "%s %d: ", up->text, up->pid); n = doprint(buf+n, buf+sizeof(buf), fmt, (&fmt+1)) - buf; if(waserror()) @@ -323,7 +323,6 @@ enum{ Qdir, Qauth, Qauthcheck, - Qauthent, Qclock, Qcons, Qconsctl, @@ -351,7 +350,6 @@ enum{ Dirtab consdir[]={ "authenticate", {Qauth}, 0, 0666, "authcheck", {Qauthcheck}, 0, 0666, - "authenticator", {Qauthent}, 0, 0666, "clock", {Qclock}, 2*NUMSIZE, 0444, "cons", {Qcons}, 0, 0660, "consctl", {Qconsctl}, 0, 0220, @@ -483,12 +481,9 @@ consclose(Chan *c) raw = 0; unlock(&ctl); } - break; case Qauth: case Qauthcheck: - case Qauthent: authclose(c); - break; } } @@ -564,7 +559,7 @@ consread(Chan *c, void *buf, long n, ulong offset) n = 6*NUMSIZE - k; /* easiest to format in a separate buffer and copy out */ for(i=0; i<6 && NUMSIZE*ip->time[i]; + l = up->time[i]; if(i == TReal) l = MACHP(0)->ticks - l; l = TK2MS(l); @@ -574,16 +569,16 @@ consread(Chan *c, void *buf, long n, ulong offset) return n; case Qpgrpid: - return readnum(offset, buf, n, u->p->pgrp->pgrpid, NUMSIZE); + return readnum(offset, buf, n, up->pgrp->pgrpid, NUMSIZE); case Qnoteid: - return readnum(offset, buf, n, u->p->noteid, NUMSIZE); + return readnum(offset, buf, n, up->noteid, NUMSIZE); case Qpid: - return readnum(offset, buf, n, u->p->pid, NUMSIZE); + return readnum(offset, buf, n, up->pid, NUMSIZE); case Qppid: - return readnum(offset, buf, n, u->p->parentpid, NUMSIZE); + return readnum(offset, buf, n, up->parentpid, NUMSIZE); case Qtime: return readnum(offset, buf, n, boottime+TK2SEC(MACHP(0)->ticks), 12); @@ -605,9 +600,6 @@ consread(Chan *c, void *buf, long n, ulong offset) case Qauth: return authread(c, cbuf, n); - case Qauthent: - return authentread(c, cbuf, n); - case Qhostowner: return readstr(offset, buf, n, eve); @@ -615,7 +607,7 @@ consread(Chan *c, void *buf, long n, ulong offset) return readstr(offset, buf, n, hostdomain); case Quser: - return readstr(offset, buf, n, u->p->user); + return readstr(offset, buf, n, up->user); case Qnull: return 0; @@ -813,9 +805,6 @@ conswrite(Chan *c, void *va, long n, ulong offset) case Qauthcheck: return authcheck(c, a, n); - case Qauthent: - return authentwrite(c, a, n); - case Qnull: break; @@ -851,7 +840,7 @@ conswrite(Chan *c, void *va, long n, ulong offset) kickpager(); break; } - if(cpuserver && strcmp(u->p->user, eve) != 0) + if(cpuserver && !iseve()) error(Eperm); if(buf[0]<'0' || '9'state = Lopened; /* current user becomes owner */ - netown(lp, u->p->user, 0); + netown(lp, up->user, 0); qunlock(&dp->netlock); return lp->lineno; @@ -976,7 +976,7 @@ dkcall(int type, Chan *c, char *addr, char *nuser, char *machine) */ if(strchr(addr, '\n')) error(Ebadarg); - if(strlen(addr)+strlen(u->p->user)+2 >= sizeof(dialstr)) + if(strlen(addr)+strlen(up->user)+2 >= sizeof(dialstr)) error(Ebadarg); strcpy(dialstr, addr); bang = strchr(dialstr, '!'); @@ -990,7 +990,7 @@ dkcall(int type, Chan *c, char *addr, char *nuser, char *machine) t_val = T_SRV; d_val = D_DIAL; strcat(dialstr, "\n"); - strcat(dialstr, u->p->user); + strcat(dialstr, up->user); strcat(dialstr, "\n"); break; case Announce: diff --git a/port/devdup.c b/port/devdup.c index c10aca9977eae305acf5f6655910af7bab28196f..9e6a28d5619bf576f880a5f79452dc2c4d709cfb 100644 --- a/port/devdup.c +++ b/port/devdup.c @@ -12,7 +12,7 @@ int dupgen(Chan *c, Dirtab *tab, int ntab, int s, Dir *dp) { char buf[8]; - Fgrp *fgrp = u->p->fgrp; + Fgrp *fgrp = up->fgrp; Chan *f; static int perm[] = { 0400, 0200, 0600, 0 }; @@ -75,7 +75,7 @@ dupopen(Chan *c, int omode) return c; } fdtochan(c->qid.path, openmode(omode), 0, 0); /* error check only */ - f = u->p->fgrp->fd[c->qid.path]; + f = up->fgrp->fd[c->qid.path]; close(c); incref(f); if(omode & OCEXEC) diff --git a/port/devenv.c b/port/devenv.c index dffe3b039b052d0a9e2d66f29014e8ed18e3c9c6..e9ce28fa588c3c54e842ed8ae87e33351c2066ee 100644 --- a/port/devenv.c +++ b/port/devenv.c @@ -31,7 +31,7 @@ envgen(Chan *c, Dirtab *tab, int ntab, int s, Dir *dp) USED(tab); USED(ntab); - eg = u->p->egrp; + eg = up->egrp; qlock(eg); for(e = eg->entries; e && s; e = e->link) @@ -62,7 +62,6 @@ envclone(Chan *c, Chan *nc) int envwalk(Chan *c, char *name) { - return devwalk(c, name, 0, 0, envgen); } @@ -78,7 +77,7 @@ envopen(Chan *c, int omode) Egrp *eg; Evalue *e; - eg = u->p->egrp; + eg = up->egrp; if(c->qid.path & CHDIR) { if(omode != OREAD) error(Eperm); @@ -117,7 +116,7 @@ envcreate(Chan *c, char *name, int omode, ulong perm) error(Eperm); omode = openmode(omode); - eg = u->p->egrp; + eg = up->egrp; qlock(eg); if(waserror()) { @@ -155,7 +154,7 @@ envremove(Chan *c) if(c->qid.path & CHDIR) error(Eperm); - eg = u->p->egrp; + eg = up->egrp; qlock(eg); l = &eg->entries; @@ -200,7 +199,7 @@ envread(Chan *c, void *a, long n, ulong offset) if(c->qid.path & CHDIR) return devdirread(c, a, n, 0, 0, envgen); - eg = u->p->egrp; + eg = up->egrp; qlock(eg); for(e = eg->entries; e; e = e->link) if(e->path == c->qid.path) @@ -236,7 +235,7 @@ envwrite(Chan *c, void *a, long n, ulong offset) if(vend > Maxenvsize) error(Etoobig); - eg = u->p->egrp; + eg = up->egrp; qlock(eg); for(e = eg->entries; e; e = e->link) if(e->path == c->qid.path) @@ -314,12 +313,3 @@ ksetenv(char *ename, char *eval) (*devtab[c->type].write)(c, eval, strlen(eval), 0); close(c); } - -void -ksetterm(char *f) -{ - char buf[2*NAMELEN]; - - sprint(buf, f, conffile); - ksetenv("terminal", buf); -} diff --git a/port/devip.c b/port/devip.c index 007b399fa7d6321098e685ceb89e845a0002b206..29c3fd8910db629cf938aab5dd98ee4f6636ae77 100644 --- a/port/devip.c +++ b/port/devip.c @@ -187,7 +187,7 @@ ipincoming(Ipifc *ifc, Ipconv *from) if(from) /* copy ownership from listening channel */ netown(new, from->owner, 0); else /* current user becomes owner */ - netown(new, u->p->user, 0); + netown(new, up->user, 0); new->ref = 1; qunlock(new); @@ -220,7 +220,7 @@ ipincoming(Ipifc *ifc, Ipconv *from) if(from) /* copy ownership from listening channel */ netown(new, from->owner, 0); else /* current user becomes owner */ - netown(new, u->p->user, 0); + netown(new, up->user, 0); new->ref = 1; qunlock(new); return new; @@ -736,8 +736,8 @@ ipremotefill(Chan *c, char *buf, int len) { Ipconv *cp; - if(len < 24) - error(Ebadarg); + if(len < 32) + error(Etoosmall); cp = ipcreateconv(ipifc[c->dev], STREAMID(c->qid.path)); sprint(buf, "%d.%d.%d.%d!%d\n", fmtaddr(cp->dst), cp->pdst); } @@ -747,8 +747,8 @@ iplocalfill(Chan *c, char *buf, int len) { Ipconv *cp; - if(len < 24) - error(Ebadarg); + if(len < 32) + error(Etoosmall); cp = ipcreateconv(ipifc[c->dev], STREAMID(c->qid.path)); sprint(buf, "%d.%d.%d.%d!%d\n", fmtaddr(Myip[Myself]), cp->psrc); } @@ -764,10 +764,9 @@ ipstatusfill(Chan *c, char *buf, int len) connection = STREAMID(c->qid.path); cp = ipcreateconv(ipifc[c->dev], connection); if(cp->ifc->protop == &tcpinfo) - sprint(buf, "tcp/%d %d %s %s %d+%d\n", connection, cp->ref, + sprint(buf, "tcp/%d %d %s %s\n", connection, cp->ref, tcpstate[cp->tcpctl.state], - cp->tcpctl.flags & CLONE ? "listen" : "connect", - cp->tcpctl.srtt, cp->tcpctl.mdev); + cp->tcpctl.flags & CLONE ? "listen" : "connect"); else if(cp->ifc->protop == &ilinfo) sprint(buf, "il/%d %d %s rtt %d ms %d csum\n", connection, cp->ref, ilstate[cp->ilctl.state], cp->ilctl.rtt, @@ -1195,7 +1194,7 @@ bsdoput(Queue *q, Block *bp) } /* if luser is a lie, hangup */ - if(memcmp(luser, u->p->user, strlen(u->p->user)+1) != 0) + if(memcmp(luser, up->user, strlen(up->user)+1) != 0) bsdclose(q); /* mark queue as authenticated and pass data to remote side */ diff --git a/port/devkprof.c b/port/devkprof.c index a9ab57b5fd0cefd79bc23c864d2c4f519453831d..fe6a7741a8a5952131ad84c817a0638f28af5638 100644 --- a/port/devkprof.c +++ b/port/devkprof.c @@ -124,7 +124,7 @@ kprofclose(Chan *c) long kprofread(Chan *c, void *va, long n, ulong offset) { - ulong tabend; + ulong end; ulong w, *bp; uchar *a, *ea; @@ -133,15 +133,15 @@ kprofread(Chan *c, void *va, long n, ulong offset) return devdirread(c, va, n, kproftab, Nkproftab, devgen); case Kprofdataqid: - tabend = kprof.nbuf*SZ; + end = kprof.nbuf*SZ; if(offset & (SZ-1)) error(Ebadarg); - if(offset >= tabend){ + if(offset >= end){ n = 0; break; } - if(offset+n > tabend) - n = tabend-offset; + if(offset+n > end) + n = end-offset; n &= ~(SZ-1); a = va; ea = a + n; diff --git a/port/devlance.c b/port/devlance.c index 366a463b1e1e7f459dde1d2725ad422a58ae74dd..3fde7d086c49cc73a8c2c34d139a90a467f690b2 100644 --- a/port/devlance.c +++ b/port/devlance.c @@ -685,7 +685,7 @@ lanceclonecon(Chan *c) continue; } e->inuse = 1; - netown(e, u->p->user, 0); + netown(e, up->user, 0); qunlock(e); return e - l.e; } @@ -817,7 +817,7 @@ lancekproc(void *arg) USED(arg); while(waserror()) - print("lancekproc err %s\n", u->error); + print("lancekproc err %s\n", up->error); for(;;){ qlock(&l.rlock); diff --git a/port/devmnt.c b/port/devmnt.c index f8da03c52132356da8da2bfc3b34a9c80cd4219f..dc3c9c084286bd2711c2450f44ccf583d953698f 100644 --- a/port/devmnt.c +++ b/port/devmnt.c @@ -6,9 +6,9 @@ #include "../port/error.h" #include "devtab.h" -typedef struct Mntrpc Mntrpc; struct Mntrpc { + Chan *c; /* Channel for whom we are working */ Mntrpc *list; /* Free/pending list */ Fcall request; /* Outgoing file system protocol message */ Fcall reply; /* Incoming reply */ @@ -21,24 +21,10 @@ struct Mntrpc char flush[MAXMSG]; /* Somewhere to build flush */ }; -struct Mnt -{ - Ref; /* Count of attached channels */ - Chan *c; /* Channel to file service */ - Proc *rip; /* Reader in progress */ - Mntrpc *queue; /* Queue of pending requests on this channel */ - int id; /* Multiplexor id for channel check */ - Mnt *list; /* Free list */ - char mux; /* Set if the device does the multiplexing */ - int blocksize; /* read/write block size */ - ushort flushtag; /* Tag to send flush on */ - ushort flushbase; /* Base tag of flush window for this buffer */ -}; - struct Mntalloc { Lock; - Mnt *list; /* Mount devices in used */ + Mnt *list; /* Mount devices in use */ Mnt *mntfree; /* Free list */ Mntrpc *rpcfree; int id; @@ -48,23 +34,25 @@ struct Mntalloc #define MAXRPC (MAXFDATA+MAXMSG) #define limit(n, max) (n > max ? max : n) -Chan* mattach(Mnt*, char*); +void mattach(Mnt*, Chan*, char*); +void mntauth(Mnt *, Mntrpc *, char *, ushort); Mnt* mntchk(Chan*); void mntdirfix(uchar*, Chan*); -void mntdoclunk(Mnt *, Mntrpc *); int mntflush(Mnt*, Mntrpc*); void mntfree(Mntrpc*); void mntgate(Mnt*); void mntpntfree(Mnt*); void mntqrm(Mnt*, Mntrpc*); -Mntrpc* mntralloc(void); +Mntrpc* mntralloc(Chan*); long mntrdwr(int , Chan*, void*,long , ulong); void mntrpcread(Mnt*, Mntrpc*); void mountio(Mnt*, Mntrpc*); void mountmux(Mnt*, Mntrpc*); void mountrpc(Mnt*, Mntrpc*); int rpcattn(Mntrpc*); -void mclose(Mnt*); +void mclose(Mnt*, Chan*); +void mntrecover(Mnt*, Mntrpc*); +Chan* mntchan(void); enum { @@ -92,9 +80,11 @@ mntattach(char *muxattach) { Mnt *m; Chan *c, *mc; + char buf[NAMELEN]; struct bogus{ Chan *chan; char *spec; + char recov; }bogus; bogus = *((struct bogus *)muxattach); @@ -108,12 +98,18 @@ mntattach(char *muxattach) unlock(&mntalloc); m->ref++; unlock(m); - return mattach(m, bogus.spec); + c = mntchan(); + if(waserror()) { + chanfree(c); + nexterror(); + } + mattach(m, c, bogus.spec); + poperror(); + return c; } unlock(m); } } - m = mntalloc.mntfree; if(m != 0) mntalloc.mntfree = m->list; @@ -137,7 +133,8 @@ mntattach(char *muxattach) m->rip = 0; m->c = c; m->c->flag |= CMSG; - m->blocksize = MAXFDATA;/**/ + m->blocksize = MAXFDATA; /**/ + m->recov = bogus.recov; switch(devchar[m->c->type]) { default: @@ -148,61 +145,70 @@ mntattach(char *muxattach) break; } incref(m->c); + + sprint(buf, "#M%d", m->id); + m->tree.root = ptenter(&m->tree, 0, buf); + unlock(m); + c = mntchan(); if(waserror()) { - mclose(m); + mclose(m, c); + /* Close must not be called since it will + * call mnt recursively + */ + chanfree(c); nexterror(); } - c = mattach(m, bogus.spec); + mattach(m, c, bogus.spec); + poperror(); - /* - * If exportfs mounts on behalf of a local devmnt, the mount - * point is folded onto the original channel to preserve a single - * fid/tag space. CHDIR is cleared by exportfs to indicate it - * is supplying the mount. - */ mc = m->c; if(mc->type == devno('M', 0) && (c->qid.path&CHDIR) == 0) { + mclose(m, c); c->qid.path |= CHDIR; c->mntptr = mc->mntptr; - c->mchan = mc->mntptr->c; + c->mchan = c->mntptr->c; c->mqid = c->qid; + c->path = c->mntptr->tree.root; + incref(c->path); incref(c->mntptr); - mclose(m); } - poperror(); return c; } -Chan * -mattach(Mnt *m, char *spec) +Chan* +mntchan(void) { Chan *c; - Mntrpc *r; - ulong id; - r = mntralloc(); - c = devattach('M', spec); + c = devattach('M', 0); lock(&mntalloc); c->dev = mntalloc.id++; unlock(&mntalloc); + + return c; +} + +void +mattach(Mnt *m, Chan *c, char *spec) +{ + ulong id; + Mntrpc *r; + + r = mntralloc(0); c->mntptr = m; if(waserror()){ mntfree(r); - /* Close must not be called since - * it will call mnt recursively - */ - chanfree(c); nexterror(); } r->request.type = Tattach; r->request.fid = c->fid; - memmove(r->request.uname, u->p->user, NAMELEN); + memmove(r->request.uname, up->user, NAMELEN); strncpy(r->request.aname, spec, NAMELEN); id = authrequest(m->c->session, &r->request); mountrpc(m, r); @@ -211,9 +217,11 @@ mattach(Mnt *m, char *spec) c->qid = r->reply.qid; c->mchan = m->c; c->mqid = c->qid; + c->path = m->tree.root; + incref(c->path); + poperror(); mntfree(r); - return c; } Chan* @@ -224,7 +232,7 @@ mntclone(Chan *c, Chan *nc) int alloc = 0; m = mntchk(c); - r = mntralloc(); + r = mntralloc(c); if(nc == 0) { nc = newchan(); alloc = 1; @@ -255,10 +263,11 @@ int mntwalk(Chan *c, char *name) { Mnt *m; + Path *op; Mntrpc *r; m = mntchk(c); - r = mntralloc(); + r = mntralloc(c); if(waserror()) { mntfree(r); return 0; @@ -269,6 +278,15 @@ mntwalk(Chan *c, char *name) mountrpc(m, r); c->qid = r->reply.qid; + op = c->path; + c->path = ptenter(&m->tree, op, name); +/* ASSERT */ +if(op->ref == 0) { + char buf[128]; + ptpath(op, buf, sizeof(buf)); + print("PATH: '%s' walking %s\n", op, name); +} + decref(op); poperror(); mntfree(r); @@ -282,7 +300,7 @@ mntstat(Chan *c, char *dp) Mntrpc *r; m = mntchk(c); - r = mntralloc(); + r = mntralloc(c); if(waserror()) { mntfree(r); nexterror(); @@ -304,7 +322,7 @@ mntopen(Chan *c, int omode) Mntrpc *r; m = mntchk(c); - r = mntralloc(); + r = mntralloc(c); if(waserror()) { mntfree(r); nexterror(); @@ -330,7 +348,7 @@ mntcreate(Chan *c, char *name, int omode, ulong perm) Mntrpc *r; m = mntchk(c); - r = mntralloc(); + r = mntralloc(c); if(waserror()) { mntfree(r); nexterror(); @@ -356,27 +374,32 @@ mntclunk(Chan *c, int t) Mntrpc *r; m = mntchk(c); - r = mntralloc(); + r = mntralloc(c); if(waserror()){ - mntdoclunk(m, r); + mntfree(r); + mclose(m, c); nexterror(); } r->request.type = t; r->request.fid = c->fid; mountrpc(m, r); - mntdoclunk(m, r); + mntfree(r); + mclose(m, c); poperror(); } void -mclose(Mnt *m) +mclose(Mnt *m, Chan *c) { Mntrpc *q, *r; if(decref(m) != 0) return; + c->path = 0; + ptclose(&m->tree); + for(q = m->queue; q; q = r) { r = q->list; q->flushed = 0; @@ -387,13 +410,6 @@ mclose(Mnt *m) mntpntfree(m); } -void -mntdoclunk(Mnt *m, Mntrpc *r) -{ - mntfree(r); - mclose(m); -} - void mntpntfree(Mnt *m) { @@ -433,7 +449,7 @@ mntwstat(Chan *c, char *dp) Mntrpc *r; m = mntchk(c); - r = mntralloc(); + r = mntralloc(c); if(waserror()) { mntfree(r); nexterror(); @@ -475,9 +491,8 @@ mntrdwr(int type, Chan *c, void *buf, long n, ulong offset) m = mntchk(c); uba = buf; - cnt = 0; - for(;;) { - r = mntralloc(); + for(cnt = 0; n; n -= nr) { + r = mntralloc(c); if(waserror()) { mntfree(r); nexterror(); @@ -496,8 +511,7 @@ mntrdwr(int type, Chan *c, void *buf, long n, ulong offset) offset += nr; uba += nr; cnt += nr; - n -= nr; - if(nr != r->request.count || n == 0) + if(nr != r->request.count) break; } return cnt; @@ -506,21 +520,31 @@ mntrdwr(int type, Chan *c, void *buf, long n, ulong offset) void mountrpc(Mnt *m, Mntrpc *r) { - r->reply.tag = 0; /* poison the old values */ + int t; + + r->reply.tag = 0; r->reply.type = 4; + while(waserror()) { + if(m->recov == 0) + nexterror(); + mntrecover(m, r); + } mountio(m, r); - if(r->reply.type == Rerror) - error(r->reply.ename); + poperror(); - if(r->reply.type == Rflush) + t = r->reply.type; + switch(t) { + case Rerror: + error(r->reply.ename); + case Rflush: error(Eintr); - - if(r->reply.type != r->request.type+1) { - print("mnt: mismatched reply 0x%lux T%d R%d tags req %d fls %d rep %d\n", - r, r->request.type, r->reply.type, r->request.tag, - r->flushtag, r->reply.tag); - + default: + if(t == r->request.type+1) + break; + print("mnt: mismatch rep 0x%lux T%d R%d rq %d fls %d rp %d\n", + r, t, r->reply.type, r->request.tag, + r->flushtag, r->reply.tag); error(Emountrpc); } } @@ -570,7 +594,7 @@ mountio(Mnt *m, Mntrpc *r) if(r->done) return; } - m->rip = u->p; + m->rip = up; unlock(m); while(r->done == 0) { mntrpcread(m, r); @@ -612,7 +636,7 @@ mntgate(Mnt *m) lock(m); m->rip = 0; - for(q = m->queue; q; q = q->list) + for(q = m->queue; q; q = q->list) { if(q->done == 0) { lock(&q->r); if(q->r.p) { @@ -623,6 +647,7 @@ mntgate(Mnt *m) } unlock(&q->r); } + } unlock(m); } @@ -643,7 +668,7 @@ mountmux(Mnt *m, Mntrpc *r) dp = q->rpc; q->rpc = r->rpc; r->rpc = dp; - memmove(&q->reply, &r->reply, sizeof(Fcall)); + q->reply = r->reply; q->done = 1; wakeup(&q->r); }else @@ -674,7 +699,7 @@ mntflush(Mnt *m, Mntrpc *r) n = convS2M(&flush, r->flush); if(waserror()) { - if(strcmp(u->error, Eintr) == 0) + if(strcmp(up->error, Eintr) == 0) return 1; mntqrm(m, r); return 0; @@ -685,7 +710,7 @@ mntflush(Mnt *m, Mntrpc *r) } Mntrpc * -mntralloc(void) +mntralloc(Chan *c) { Mntrpc *new; @@ -703,6 +728,7 @@ mntralloc(void) new->request.tag = mntalloc.rpctag++; } unlock(&mntalloc); + new->c = c; new->done = 0; new->flushed = 0; return new; @@ -737,15 +763,77 @@ mntqrm(Mnt *m, Mntrpc *r) unlock(m); } +void +recoverchan(Mnt *m, Chan *c) +{ + int i, n, flg; + Path *safe, *p, **pav; + + if(m->c == 0) + error(Eshutdown); + + flg = c->flag; + /* Don't recursively recover */ + c->flag &= ~(COPEN|CRECOV); + + n = 0; + for(p = c->path; p; p = p->parent) + n++; + pav = smalloc(sizeof(Path*)*n); + i = n; + for(p = c->path; p; p = p->parent) + pav[--i] = p; + + safe = c->path; + + if(waserror()) { + c->flag = flg; + free(pav); + nexterror(); + } + + /* Attach the fid onto the file server (sets c->path to #Mxxx) */ + mattach(m, c, c->xmnt->spec); + poperror(); + + /* + * c is now at the root so we free where + * the chan was before the server connection was lost + */ + decref(safe); + + for(i = 1; i < n; i++) { + if(mntwalk(c, pav[i]->elem) == 0) { + free(pav); + /* Shut down the channel */ + c->dev = m->id-1; + error(Erecover); + } + } + free(pav); + if(flg&COPEN) + mntopen(c, c->mode); +} + Mnt * mntchk(Chan *c) { Mnt *m; m = c->mntptr; - /* Was it closed and reused ? */ - if(m->id == 0 || m->id >= c->dev) /* Sanity check */ + + /* + * Was it closed and reused + */ + if(m->id == 0 || m->id >= c->dev) error(Eshutdown); + + /* + * Try and get the channel back + */ + if((c->flag&CRECOV) && m->recprog == 0) + recoverchan(m, c); + return m; } @@ -763,3 +851,104 @@ rpcattn(Mntrpc *r) { return r->done || r->m->rip == 0; } + +int +recdone(Mnt *m) +{ + return m->recprog == 0; +} + +void +mntrecdel(Mnt *m, Mntrpc *r) +{ + Mntrpc *f, **l; + + lock(m); + l = &m->recwait; + for(f = *l; f; f = f->list) { + if(f == r) { + *l = r->list; + break; + } + } + unlock(m); +} + +void +mntrecover(Mnt *m, Mntrpc *r) +{ + char *ps; + + lock(m); + if(m->recprog == 0) { + m->recprog = 1; + unlock(m); + chanrec(m); + /* + * Send a message to boot via #/recover + */ + rootrecover(m->c->path, m->tree.root->elem); + lock(m); + } + r->list = m->recwait; + m->recwait = r; + unlock(m); + + pprint("lost server connection, wait...\n"); + + ps = up->psstate; + up->psstate = "Recover"; + + if(waserror()) { + up->psstate = ps; + mntrecdel(m, r); + nexterror(); + } + sleep(&r->r, recdone, m); + poperror(); + + r->done = 0; + mntrecdel(m, r); + recoverchan(m, r->c); + + up->psstate = ps; +} + +void +mntrepl(char *buf) +{ + int fd; + Mnt *m; + char *p; + Chan *c1; + Mntrpc *r; + + /* reply from boot is 'fd #M23' */ + fd = strtoul(buf, &p, 0); + + p++; + lock(&mntalloc); + for(m = mntalloc.list; m; m = m->list) { + if(strcmp(p, m->tree.root->elem) == 0) + break; + } + unlock(&mntalloc); + if(m == 0) + error(Eunmount); + + c1 = fdtochan(fd, ORDWR, 0, 1); /* error check and inc ref */ + + /* If the channel was posted fix it up */ + srvrecover(m->c, c1); + + lock(m); + close(m->c); + m->c = c1; + m->recprog = 0; + + /* Wakeup partially complete rpc */ + for(r = m->recwait; r; r = r->list) + wakeup(&r->r); + + unlock(m); +} diff --git a/port/devmux.c b/port/devmux.c deleted file mode 100644 index 1eb22ead454c8428ca2a64c3131086a2693dfb4d..0000000000000000000000000000000000000000 --- a/port/devmux.c +++ /dev/null @@ -1,668 +0,0 @@ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "../port/error.h" - -#include "devtab.h" - -typedef struct Mux Mux; -typedef struct Con Con; -typedef struct Dtq Dtq; - -enum -{ - Qdir = 0, - Qhead = 0, - Qclone, - Qoffset, - - Nmuxchan= 64, - Nmux = 32, - Maxmsg = (32*1024), - Flowctl = Maxmsg/2, -}; - -struct Dtq -{ - QLock rd; - Rendez r; - Lock listlk; - Block *list; - int ndelim; - int nb; - QLock flow; - Rendez flowr; -}; - -struct Con -{ - int ref; - char user[NAMELEN]; - ulong perm; - Dtq conq; -}; - -struct Mux -{ - Ref; - int srv; - char name[NAMELEN]; - char user[NAMELEN]; - ulong perm; - int headopen; - Dtq headq; - Con connects[Nmux]; - Chan *c; -}; - -Mux *muxes; -ulong muxreadq(Mux *m, Dtq*, char*, ulong); -void muxwriteq(Dtq*, char*, long, int, int); -void muxflow(Dtq*); -Block *muxclq(Dtq *q); - -#define NMUX(c) (((c->qid.path>>8)&0xffff)-1) -#define NQID(m, c) (Qid){(m+1)<<8|(c)&0xff, 0} -#define DQID(m) (Qid){(m+1)<<8|CHDIR, 0} -#define NCON(c) (c->qid.path&0xff) - -int -muxgen(Chan *c, Dirtab *tab, int ntab, int s, Dir *dp) -{ - Mux *m; - int mux; - Con *cm; - char buf[10]; - int nq; - - USED(tab, ntab); - if(c->qid.path == CHDIR) { - if(s >= Nmuxchan) - return -1; - - m = &muxes[s]; - if(m->name[0] == '\0') - return 0; - if(m->srv) - devdir(c, NQID(s, 0), m->name, 0, m->user, m->perm, dp); - else - devdir(c, DQID(s), m->name, 0, m->user, m->perm, dp); - return 1; - } - - if(s >= Nmux+2) - return -1; - - mux = NMUX(c); - m = &muxes[mux]; - - switch(s) { - case Qhead: - devdir(c, NQID(mux, Qhead), "head", m->headq.nb, m->user, m->perm, dp); - break; - case Qclone: - devdir(c, NQID(mux, Qclone), "clone", 0, m->user, m->perm, dp); - break; - default: - nq = s-Qoffset; - cm = &m->connects[nq]; - if(cm->ref == 0) - return 0; - sprint(buf, "%d", nq); - devdir(c, NQID(mux, Qoffset+s), buf, cm->conq.nb, cm->user, cm->perm, dp); - break; - } - return 1; -} - -void -muxinit(void) -{ -} - -void -muxreset(void) -{ - muxes = xalloc(Nmuxchan*sizeof(Mux)); -} - -Chan * -muxattach(char *spec) -{ - Chan *c; - - c = devattach('s', spec); - c->qid.path = CHDIR|Qdir; - return c; -} - -Chan * -muxclone(Chan *c, Chan *nc) -{ - int ncon; - Mux *m; - - if(c->qid.path == CHDIR) - return devclone(c, nc);; - - m = &muxes[NMUX(c)]; - ncon = NCON(c); - c = devclone(c, nc); - - if((c->flag&COPEN) == 0) - return c; - - switch(ncon) { - case Qhead: - incref(m); - break; - case Qclone: - break; - default: - lock(m); - m->connects[ncon-Qoffset].ref++; - m->ref++; - unlock(m); - } - return c; -} - -int -muxwalk(Chan *c, char *name) -{ - if(strcmp(name, "..") == 0) { - c->qid.path = CHDIR|Qdir; - return 1; - } - - return devwalk(c, name, 0, 0, muxgen); -} - -void -muxstat(Chan *c, char *db) -{ - devstat(c, db, 0, 0, muxgen); -} - -Chan * -muxopen(Chan *c, int omode) -{ - Mux *m; - Con *cm, *e; - int mux; - Chan *new; - - c = devopen(c, omode, 0, 0, muxgen); - if(c->qid.path & CHDIR) - return c; - - mux = NMUX(c); - m = &muxes[mux]; - lock(m); - if(waserror()) { - c->flag &= ~COPEN; - unlock(m); - nexterror(); - } - if(m->srv) { - if(m->c == 0) - error(Eshutdown); - new = m->c; - incref(new); - unlock(m); - poperror(); - close(c); - return new; - } - switch(NCON(c)) { - case Qhead: - if(m->headopen) - error(Einuse); - m->headopen = 1; - m->ref++; - break; - case Qclone: - if(m->headopen == 0) - error(Emuxshutdown); - - cm = m->connects; - for(e = &cm[Nmux]; cm < e; cm++) - if(cm->ref == 0) - break; - if(cm == e) - error(Emuxbusy); - cm->ref = 1; - m->ref++; - strncpy(cm->user, u->p->user, NAMELEN); - cm->perm = 0600; - c->qid = NQID(mux, (cm-m->connects)+Qoffset); - break; - default: - cm = &m->connects[NCON(c)-Qoffset]; - cm->ref++; - m->ref++; - break; - } - unlock(m); - poperror(); - return c; -} - -void -muxcreate(Chan *c, char *name, int omode, ulong perm) -{ - int n; - Mux *m, *e; - - if(c->qid.path != CHDIR) - error(Eperm); - - omode = openmode(omode); - - m = muxes; - for(e = &m[Nmuxchan]; m < e; m++) { - if(m->name[0] == '\0' && m->ref == 0 && canlock(m)) { - if(m->ref != 0) { - unlock(m); - continue; - } - break; - } - } - - if(m == e) - exhausted("multiplexers"); - - strncpy(m->name, name, NAMELEN); - strncpy(m->user, u->p->user, NAMELEN); - m->perm = perm&~CHDIR; - m->srv = 1; - if(perm&CHDIR) - m->srv = 0; - unlock(m); - - n = m - muxes; - c->qid = (Qid){(CHDIR&perm)|(n+1)<<8, 0}; - c->flag |= COPEN; - c->mode = omode; -} - -void -muxclose(Chan *c) -{ - Block *f1, *f2; - Con *cm, *e; - Mux *m; - int nc; - - if(c->qid.path&CHDIR) - return; - - m = &muxes[NMUX(c)]; - if(!(c->flag&COPEN) || m->srv) - return; - - nc = NCON(c); - f1 = 0; - f2 = 0; - switch(nc) { - case Qhead: - m->headopen = 0; - cm = m->connects; - for(e = &cm[Nmux]; cm < e; cm++) - if(cm->ref) - wakeup(&cm->conq.r); - lock(m); - if(--m->ref == 0) - f1 = muxclq(&m->headq); - unlock(m); - break; - case Qclone: - break; - default: - lock(m); - cm = &m->connects[nc-Qoffset]; - if(--cm->ref == 0) - f1 = muxclq(&cm->conq); - if(--m->ref == 0) - f1 = muxclq(&m->headq); - unlock(m); - } - if(f1) - freeb(f1); - if(f2) - freeb(f2); -} - -void -muxremove(Chan *c) -{ - Mux *m; - Chan *srv; - - if(c->qid.path == CHDIR) - error(Eperm); - - m = &muxes[NMUX(c)]; - if((c->qid.path&CHDIR) == 0 && m->srv == 0) - error(Eperm); - - if(strncmp(u->p->user, m->user, NAMELEN)) - error(Eperm); - - srv = 0; - lock(m); - if(m->srv) { - srv = m->c; - m->c = 0; - } - m->name[0] = '\0'; - unlock(m); - if(srv) - close(srv); - - muxclose(c); -} - -void -muxwstat(Chan *c, char *db) -{ - Mux *m; - Dir d; - int nc; - - if(c->qid.path == CHDIR) - error(Eperm); - - m = &muxes[NMUX(c)]; - if(strncmp(u->p->user, m->user, NAMELEN)) - error(Eperm); - - convM2D(db, &d); - d.mode &= 0777; - if(c->qid.path&CHDIR || m->srv) { - strcpy(m->name, d.name); - m->perm = d.mode; - return; - } - nc = NCON(c); - switch(nc) { - case Qclone: - error(Eperm); - case Qhead: - m->perm = d.mode; - break; - default: - m->connects[nc-Qoffset].perm = d.mode; - break; - } -} - -long -muxread(Chan *c, void *va, long n, ulong offset) -{ - Mux *m; - Con *cm; - int bread; - - USED(offset); - if(c->qid.path & CHDIR) - return devdirread(c, va, n, 0, 0, muxgen); - - m = &muxes[NMUX(c)]; - switch(NCON(c)) { - case Qhead: - bread = muxreadq(m, &m->headq, va, n); - break; - case Qclone: - error(Eperm); - default: - cm = &m->connects[NCON(c)-Qoffset]; - bread = muxreadq(m, &cm->conq, va, n); - break; - } - - return bread; -} - -Con * -muxhdr(Mux *m, char *h) -{ - Con *c; - - if(h[0] != Tmux || h[2] != 0) - error(Emuxmsg); - - c = &m->connects[h[1]]; - if(c < m->connects || c > &m->connects[Nmux]) - error(Emuxmsg); - - if(c->ref == 0) - return 0; - - return c; -} - -long -muxwrite(Chan *c, void *va, long n, ulong offset) -{ - Mux *m; - Con *cm; - int muxid, fd; - char *a, hdr[3], buf[10]; - - USED(offset); - if(c->qid.path&CHDIR) - error(Eisdir); - - m = &muxes[NMUX(c)]; - if(n > Maxmsg || (m->srv && n >= sizeof(buf))) - error(Etoobig); - - if(m->srv) { - memmove(buf, va, n); /* so we can NUL-terminate */ - buf[n] = 0; - fd = strtoul(buf, 0, 0); - fdtochan(fd, -1, 0, 0); /* error check */ - m->c = u->p->fgrp->fd[fd]; - incref(m->c); - return n; - } - switch(NCON(c)) { - case Qclone: - error(Eperm); - case Qhead: - if(n < 2) - error(Emuxmsg); - - a = (char*)va; - memmove(hdr, a, sizeof(hdr)); - cm = muxhdr(m, hdr); - if(cm == 0) - error(Ehungup); - - muxwriteq(&cm->conq, a+sizeof(hdr), n-sizeof(hdr), 0, 0); - break; - default: - if(m->headopen == 0) - error(Ehungup); - - muxid = NCON(c)-Qoffset; - muxwriteq(&m->headq, va, n, 1, muxid); - break; - } - - return n; -} - -void -muxwriteq(Dtq *q, char *va, long n, int addid, int muxid) -{ - Block *head, *tail, *bp; - ulong l, bwrite; - - head = 0; - tail = 0; - if(waserror()) { - if(head) - freeb(head); - nexterror(); - } - - bwrite = 0; - while(n) { - if(addid) { - bp = allocb(n+3); - bp->wptr[0] = Tmux; - bp->wptr[1] = muxid; - bp->wptr[2] = 0; - bp->wptr += 3; - bwrite += 3; - addid = 0; - } - else - bp = allocb(n); - l = bp->lim - bp->wptr; - if(l > n) - l = n; - memmove(bp->wptr, va, l); /* Interruptable thru fault */ - va += l; - bp->wptr += l; - bwrite += l; - n -= l; - if(head == 0) - head = bp; - else - tail->next = bp; - tail = bp; - } - poperror(); - tail->flags |= S_DELIM; - - if(q->nb > Flowctl) - muxflow(q); - - lock(&q->listlk); - if(q->list == 0) - q->list = head; - else { - for(tail = q->list; tail->next; tail = tail->next) - ; - tail->next = head; - } - q->ndelim++; - q->nb += bwrite; - unlock(&q->listlk); - wakeup(&q->r); -} - -int -muxflw(Dtq *q) -{ - return q->nb < Flowctl; -} - -void -muxflow(Dtq *q) -{ - qlock(&q->flow); - if(waserror()) { - qunlock(&q->flow); - nexterror(); - } - sleep(&q->flowr, muxflw, q); - poperror(); - qunlock(&q->flow); -} - -int -havedata(Dtq *q) -{ - int n; - - lock(&q->listlk); - n = q->ndelim; - unlock(&q->listlk); - return n; -} - -ulong -muxreadq(Mux *m, Dtq *q, char *va, ulong n) -{ - int l, nread; - Block *bp, *f1; - - qlock(&q->rd); - bp = 0; - if(waserror()) { - lock(&q->listlk); - if(bp) { - bp->next = q->list; - q->list = bp; - } - unlock(&q->listlk); - qunlock(&q->rd); - nexterror(); - } - while(!havedata(q)) { - sleep(&q->r, havedata, q); - if(m->headopen == 0) - error(Emuxshutdown); - } - - nread = 0; - f1 = 0; - lock(&q->listlk); - while(n) { - bp = q->list; - q->list = bp->next; - bp->next = 0; - unlock(&q->listlk); - if(f1) { - freeb(f1); - f1 = 0; - } - l = BLEN(bp); - if(l > n) - l = n; - memmove(va, bp->rptr, l); /* Interruptable thru fault */ - va += l; - bp->rptr += l; - n -= l; - nread += l; - lock(&q->listlk); - if(bp->rptr == bp->wptr) - f1 = bp; - else { - bp->next = q->list; - q->list = bp; - } - if(bp->flags&S_DELIM) { - q->ndelim--; - break; - } - } - q->nb -= nread; - unlock(&q->listlk); - if(f1) - freeb(f1); - qunlock(&q->rd); - poperror(); - if(q->nb < Flowctl) - wakeup(&q->flowr); - return nread; -} - -Block * -muxclq(Dtq *q) -{ - Block *f; - - f = q->list; - q->list = 0; - q->nb = 0; - q->ndelim = 0; - return f; -} diff --git a/port/devpipe.c b/port/devpipe.c index a836c111ec183286a497837ae88f0fa0ed03e0bf..94a9ad98f68725c2a9836a7e59457c0f89d46c3b 100644 --- a/port/devpipe.c +++ b/port/devpipe.c @@ -170,7 +170,7 @@ pipeopen(Chan *c, int omode) qunlock(p); poperror(); - c->mode = openmode(omode); + c->mode = omode&~OTRUNC; c->flag |= COPEN; c->offset = 0; return c; @@ -260,7 +260,7 @@ pipewrite(Chan *c, void *va, long n, ulong offset) return streamwrite(c, va, n, 0); if(waserror()) { - postnote(u->p, 1, "sys: write on closed pipe", NUser); + postnote(up, 1, "sys: write on closed pipe", NUser); error(Egreg); } n = streamwrite(c, va, n, 0); diff --git a/port/devproc.c b/port/devproc.c index da66bdb2eccc1f6ca9d32bb0e09d93b3299426ab..628f645fc69751455acd21ffb641791948b4d0f3 100644 --- a/port/devproc.c +++ b/port/devproc.c @@ -8,7 +8,8 @@ #include "devtab.h" -enum{ +enum +{ Qdir, Qctl, Qmem, @@ -19,6 +20,7 @@ enum{ Qstatus, Qtext, Qwait, + Qns, }; #define STATSIZE (2*NAMELEN+12+7*12) @@ -33,6 +35,7 @@ Dirtab procdir[] = "status", {Qstatus}, STATSIZE, 0444, "text", {Qtext}, 0, 0000, "wait", {Qwait}, 0, 0400, + "ns", {Qns}, 0, 0400, }; /* Segment type from portdat.h */ @@ -59,6 +62,7 @@ int procctlmemio(Proc*, ulong, int, void*, int); Chan* proctext(Chan*, Proc*); Segment* txt2data(Proc*, Segment*); int procstopped(void*); +void mntscan(Mntwalk*); int procgen(Chan *c, Dirtab *tab, int ntab, int s, Dir *dp) @@ -163,6 +167,8 @@ procopen(Chan *c, int omode) switch(QID(c->qid)){ case Qtext: + if(omode != OREAD) + error(Eperm); tc = proctext(c, p); tc->offset = 0; return tc; @@ -176,6 +182,10 @@ procopen(Chan *c, int omode) case Qwait: break; + case Qns: + c->aux = malloc(sizeof(Mntwalk)); + break; + case Qnotepg: if(omode!=OWRITE || pg->pgrpid == 1) error(Eperm); @@ -223,7 +233,7 @@ procwstat(Chan *c, char *db) if(p->pid != PID(c->qid)) error(Eprocdied); - if(strcmp(u->p->user, p->user) != 0 && strcmp(u->p->user, eve) != 0) + if(strcmp(up->user, p->user) != 0 && strcmp(up->user, eve) != 0) error(Eperm); p->procmode = d.mode&0777; @@ -232,23 +242,21 @@ procwstat(Chan *c, char *db) void procclose(Chan * c) { - USED(c); + if(QID(c->qid) == Qns) + free(c->aux); } long procread(Chan *c, void *va, long n, ulong offset) { - char *a = va, *b, *sps; - char statbuf[NSEG*32]; + long l; Proc *p; - Page *pg; - KMap *k; - Segment *s; int i, j; - long l; - User *up; - Segment *sg; Waitq *wq; + Mntwalk *mw; + Segment *sg, *s; + char *a = va, *sps; + char statbuf[NSEG*32]; if(c->qid.path & CHDIR) return devdirread(c, a, n, 0, 0, procgen); @@ -259,23 +267,9 @@ procread(Chan *c, void *va, long n, ulong offset) switch(QID(c->qid)){ case Qmem: - /* ugly math: USERADDR+BY2PG may be == 0 */ - if(offset >= USERADDR && offset <= USERADDR+BY2PG-1) { - if(offset+n >= USERADDR+BY2PG-1) - n = USERADDR+BY2PG - offset; - pg = p->upage; - if(pg==0 || p->pid!=PID(c->qid)) - error(Eprocdied); - k = kmap(pg); - b = (char*)VA(k); - memmove(a, b+(offset-USERADDR), n); - kunmap(k); - return n; - } - if(offset >= KZERO) { /* Protect crypt key memory */ - if(offset < palloc.cmemtop && offset+n > palloc.cmembase) + if(offset >= palloc.cmembase&&offset < palloc.cmemtop) error(Eperm); /* validate physical kernel addresses */ @@ -309,26 +303,18 @@ procread(Chan *c, void *va, long n, ulong offset) } if(p->pid != PID(c->qid)) error(Eprocdied); - k = kmap(p->upage); - up = (User*)VA(k); - if(up->p != p){ - kunmap(k); - pprint("note read u/p mismatch"); - error(Egreg); - } if(n < ERRLEN) error(Etoosmall); - if(up->nnote == 0) + if(p->nnote == 0) n = 0; - else{ - memmove(va, up->note[0].msg, ERRLEN); - up->nnote--; - memmove(&up->note[0], &up->note[1], up->nnote*sizeof(Note)); + else { + memmove(va, p->note[0].msg, ERRLEN); + p->nnote--; + memmove(p->note, p->note+1, p->nnote*sizeof(Note)); n = ERRLEN; } - if(up->nnote == 0) + if(p->nnote == 0) p->notepending = 0; - kunmap(k); poperror(); qunlock(&p->debug); return n; @@ -403,7 +389,7 @@ procread(Chan *c, void *va, long n, ulong offset) } lock(&p->exl); - if(u->p == p && p->nchild == 0 && p->waitq == 0) { + if(up == p && p->nchild == 0 && p->waitq == 0) { unlock(&p->exl); error(Enochild); } @@ -422,31 +408,83 @@ procread(Chan *c, void *va, long n, ulong offset) memmove(a, &wq->w, sizeof(Waitmsg)); free(wq); return sizeof(Waitmsg); + + case Qns: + mw = c->aux; + mntscan(mw); + if(mw->mh == 0) + return 0; + if(n < NAMELEN+11) + error(Etoosmall); + i = sprint(a, "%s %d ", mw->cm->spec, mw->cm->flag); + n -= i; + a += i; + i = ptpath(mw->mh->from->path, a, n); + n -= i; + a += i; + if(n > 0) { + *a++ = ' '; + n--; + } + a += ptpath(mw->cm->to->path, a, n); + return a - (char*)va; } error(Egreg); return 0; /* not reached */ } +void +mntscan(Mntwalk *mw) +{ + Pgrp *pg; + Mount *t; + int nxt; + ulong last, bestmid; + Mhead **h, **he, *f; + + pg = up->pgrp; + rlock(&pg->ns); + + nxt = 0; + last = 0; + bestmid = ~0; + if(mw->mh) + last = mw->cm->mountid; + + he = &pg->mnthash[MNTHASH]; + for(h = pg->mnthash; h < he; h++) { + for(f = *h; f; f = f->hash) { + for(t = f->mount; t; t = t->next) { + if(mw->mh == 0 || + (t->mountid > last && t->mountid < bestmid)) { + mw->cm = t; + mw->mh = f; + bestmid = mw->cm->mountid; + nxt = 1; + } + } + } + } + if(nxt == 0) + mw->mh = 0; + + runlock(&pg->ns); +} long procwrite(Chan *c, void *va, long n, ulong offset) { Proc *p; - User *up; - KMap *k; char buf[ERRLEN]; - Ureg *ur; - User *pxu; - Page *pg; - char *a = va, *b; - ulong hi; if(c->qid.path & CHDIR) error(Eisdir); p = proctab(SLOT(c->qid)); - /* Use the remembered noteid in the channel rather than the process pgrpid */ + /* Use the remembered noteid in the channel rather + * than the process pgrpid + */ if(QID(c->qid) == Qnotepg) { pgrpnote(NOTEID(c->pgrpid), va, n, NUser); return n; @@ -465,32 +503,7 @@ procwrite(Chan *c, void *va, long n, ulong offset) if(p->state != Stopped) error(Ebadctl); - if(offset >= USERADDR && offset <= USERADDR+BY2PG-1) { - pg = p->upage; - if(pg==0 || p->pid!=PID(c->qid)) - error(Eprocdied); - k = kmap(pg); - b = (char*)VA(k); - pxu = (User*)b; - hi = offset+n; - /* Check for floating point registers */ - if(offset >= (ulong)&u->fpsave && - hi <= (ulong)&u->fpsave+sizeof(FPsave)){ - memmove(b+(offset-USERADDR), a, n); - break; - } - /* Check user register set for process at kernel entry */ - ur = pxu->dbgreg; - if(offset < (ulong)ur || hi > (ulong)ur+sizeof(Ureg)) { - kunmap(k); - error(Ebadarg); - } - ur = (Ureg*)(b+((ulong)ur-USERADDR)); - setregisters(ur, b+(offset-USERADDR), a, n); - kunmap(k); - } - else /* Try user memory segments */ - n = procctlmemio(p, offset, n, va, 0); + n = procctlmemio(p, offset, n, va, 0); break; case Qctl: @@ -500,14 +513,6 @@ procwrite(Chan *c, void *va, long n, ulong offset) case Qnote: if(p->kp) error(Eperm); - k = kmap(p->upage); - up = (User*)VA(k); - if(up->p != p){ - kunmap(k); - pprint("note write u/p mismatch"); - error(Egreg); - } - kunmap(k); if(n >= ERRLEN-1) error(Etoobig); memmove(buf, va, n); @@ -582,16 +587,16 @@ procstopwait(Proc *p, int ctl) if(ctl != 0) p->procctl = ctl; - p->pdbg = u->p; + p->pdbg = up; pid = p->pid; qunlock(&p->debug); - u->p->psstate = "Stopwait"; + up->psstate = "Stopwait"; if(waserror()) { p->pdbg = 0; qlock(&p->debug); nexterror(); } - sleep(&u->p->sleep, procstopped, p); + sleep(&up->sleep, procstopped, p); poperror(); qlock(&p->debug); if(p->pid != pid) @@ -609,7 +614,8 @@ procctlreq(Proc *p, char *va, int n) if(strncmp(buf, "stop", 4) == 0) procstopwait(p, Proc_stopme); - else if(strncmp(buf, "kill", 4) == 0) { + else + if(strncmp(buf, "kill", 4) == 0) { switch(p->state) { case Broken: unbreak(p); @@ -624,20 +630,25 @@ procctlreq(Proc *p, char *va, int n) p->procctl = Proc_exitme; } } - else if(strncmp(buf, "hang", 4) == 0) + else + if(strncmp(buf, "hang", 4) == 0) p->hang = 1; - else if(strncmp(buf, "nohang", 6) == 0) + else + if(strncmp(buf, "nohang", 6) == 0) p->hang = 0; - else if(strncmp(buf, "waitstop", 8) == 0) + else + if(strncmp(buf, "waitstop", 8) == 0) procstopwait(p, 0); - else if(strncmp(buf, "startstop", 9) == 0) { + else + if(strncmp(buf, "startstop", 9) == 0) { if(p->state != Stopped) error(Ebadctl); p->procctl = Proc_traceme; ready(p); procstopwait(p, Proc_traceme); } - else if(strncmp(buf, "start", 5) == 0) { + else + if(strncmp(buf, "start", 5) == 0) { if(p->state != Stopped) error(Ebadctl); ready(p); @@ -671,7 +682,7 @@ procctlmemio(Proc *p, ulong offset, int n, void *va, int read) if(offset+n >= s->top) n = s->top-offset; - if(read == 0 && (s->type&SG_TYPE) == SG_TEXT) + if((s->type&SG_TYPE) == SG_TEXT) s = txt2data(p, s); s->steal++; diff --git a/port/devroot.c b/port/devroot.c index bf332c831d869724a03ba6cf49feeb33767934c9..b4be24298936ca936464581bf5801bc9b401cf45 100644 --- a/port/devroot.c +++ b/port/devroot.c @@ -6,13 +6,15 @@ #include "../port/error.h" #include "devtab.h" -enum{ +enum +{ Qdir, Qbin, Qdev, Qenv, Qproc, Qnet, + Qrecover, Qboot, Qcfs, @@ -33,6 +35,7 @@ Dirtab rootdir[]={ "env", {Qenv|CHDIR}, 0, 0777, "proc", {Qproc|CHDIR}, 0, 0777, "net", {Qnet|CHDIR}, 0, 0777, + "recover", {Qrecover}, 0, 0777, }; #define NROOT (sizeof rootdir/sizeof(Dirtab)) Dirtab rootpdir[]={ @@ -42,6 +45,22 @@ Dirtab rootpdir[]={ Dirtab *rootmap[sizeof rootpdir/sizeof(Dirtab)]; int nroot; +typedef struct Recover Recover; +struct Recover +{ + int len; + char *req; + Recover *next; +}; + +struct +{ + Lock; + QLock; + Rendez; + Recover *q; +}reclist; + int rootgen(Chan *c, Dirtab *tab, int ntab, int i, Dir *dp) { @@ -110,6 +129,15 @@ rootstat(Chan *c, char *dp) Chan* rootopen(Chan *c, int omode) { + switch(c->qid.path & ~CHDIR) { + default: + break; + case Qrecover: + if(strcmp(up->user, eve) != 0) + error(Eperm); + break; + } + return devopen(c, omode, rootdir, nroot, rootgen); } @@ -129,9 +157,17 @@ rootclose(Chan *c) USED(c); } +int +rdrdy(void *a) +{ + USED(a); + return reclist.q != 0; +} + long rootread(Chan *c, void *buf, long n, ulong offset) { + Recover *r; switch(c->qid.path & ~CHDIR){ case Qdir: @@ -161,6 +197,30 @@ rootread(Chan *c, void *buf, long n, ulong offset) memmove(buf, ((char*)fscode)+offset, n); return n; + case Qrecover: + qlock(&reclist); + if(waserror()) { + qunlock(&reclist); + nexterror(); + } + + sleep(&reclist, rdrdy, 0); + + lock(&reclist); + r = reclist.q; + reclist.q = r->next; + unlock(&reclist); + + qunlock(&reclist); + + poperror(); + if(n < r->len) + n = r->len; + memmove(buf, r->req, n); + free(r->req); + free(r); + return n; + case Qdev: return 0; } @@ -170,9 +230,22 @@ rootread(Chan *c, void *buf, long n, ulong offset) long rootwrite(Chan *c, void *buf, long n, ulong offset) { - USED(c, buf, n, offset); - error(Egreg); - return 0; /* not reached */ + char tmp[256]; + + USED(offset); + switch(c->qid.path & ~CHDIR){ + default: + error(Egreg); + case Qrecover: + if(n > sizeof(tmp)-1) + error(Etoosmall); + /* Nul terminate */ + memmove(tmp, buf, n); + tmp[n] = '\0'; + mntrepl(tmp); + return n; + } + return 0; } void @@ -188,3 +261,21 @@ rootwstat(Chan *c, char *dp) USED(c, dp); error(Eperm); } + +void +rootrecover(Path *p, char *mntname) +{ + int i; + Recover *r; + char buf[256]; + + r = malloc(sizeof(Recover)); + i = ptpath(p, buf, sizeof(buf)); + r->req = smalloc(i+strlen(mntname)+2); + sprint(r->req, "%s %s", buf, mntname); + lock(&reclist); + r->next = reclist.q; + reclist.q = r; + unlock(&reclist); + wakeup(&reclist); +} diff --git a/port/devscc.c b/port/devscc.c index f08286f44ee063d5e1aa7ed3f5a442a3a4de5beb..6b4cf19ec387a2cbb6605538b75714a6fb69415d 100644 --- a/port/devscc.c +++ b/port/devscc.c @@ -63,9 +63,7 @@ enum /* wr 11 */ TRxCOutBR= 2, - TxClockTRxC= 1<<3, TxClockBR= 2<<3, - RxClockTRxC= 1<<5, RxClockBR= 2<<5, TRxCOI= 1<<2, @@ -234,24 +232,6 @@ sccbits(SCC *sp, int n) sccwrreg(sp, 5, 0); } -/* - * set/clear external clock mode; the indigo uses the CTS pin, - * so we disable external interrupts. - */ -void -sccextclk(SCC *sp, int n) -{ - if(n){ - sp->sticky[1] &= ~ExtIntEna; - sp->sticky[11] = TxClockTRxC | RxClockTRxC; - }else{ - sp->sticky[1] |= ExtIntEna; - sp->sticky[11] = TxClockBR | RxClockBR | TRxCOutBR; - } - sccwrreg(sp, 1, 0); - sccwrreg(sp, 11, 0); -} - /* * toggle DTR */ @@ -506,13 +486,6 @@ sccspecial(int port, IOQ *oq, IOQ *iq, int baud) { SCC *sp = scc[port]; - /* let output drain */ - if(sp->oq){ - while(cangetc(sp->oq)) - sleep(&sp->oq->r, cangetc, sp->oq); - tsleep(&sp->oq->r, cangetc, sp->oq, 50); - } - sp->special = 1; sp->oq = oq; sp->iq = iq; @@ -612,9 +585,7 @@ sccoput(Queue *q, Block *bp) nexterror(); } if(bp->type == M_CTL){ - if(*bp->rptr == '!') /* do it now! */ - ++bp->rptr; - else while(cangetc(cq)) /* else let output drain */ + while (cangetc(cq)) /* let output drain */ sleep(&cq->r, cangetc, cq); n = strtoul((char *)(bp->rptr+1), 0, 0); switch(*bp->rptr){ @@ -625,10 +596,6 @@ sccoput(Queue *q, Block *bp) else sccsetbaud(sp, n); break; - case 'C': - case 'c': - sccextclk(sp, n); - break; case 'D': case 'd': sccdtr(sp, n); diff --git a/port/devscsi.c b/port/devscsi.c index d25b2274b8fdf1a79e2c87705269d8be85e294db..8bc3f6b3f15c31ff91f3c367e04a43213e5b63f1 100644 --- a/port/devscsi.c +++ b/port/devscsi.c @@ -130,7 +130,7 @@ scsiclose(Chan *c) if((c->qid.path & CHDIR) || c->qid.path==1) return; if((c->qid.path & 0xf) == Qcmd){ - if(canqlock(cmd) || cmd->pid == u->p->pid){ + if(canqlock(cmd) || cmd->pid == up->pid){ cmd->pid = 0; qunlock(cmd); } @@ -161,7 +161,7 @@ scsiread(Chan *c, char *a, long n, ulong offset) qunlock(cmd); error(Egreg); } - if(cmd->pid != u->p->pid) + if(cmd->pid != up->pid) error(Egreg); n = 4; *a++ = 0; @@ -176,7 +176,7 @@ scsiread(Chan *c, char *a, long n, ulong offset) qunlock(cmd); error(Egreg); } - if(cmd->pid != u->p->pid) + if(cmd->pid != up->pid) error(Egreg); if (n > DATASIZE) error(Ebadarg); @@ -225,7 +225,7 @@ scsiwrite(Chan *c, char *a, long n, ulong offset) if(n < 6 || n > sizeof cmd->cmdblk) error(Ebadarg); qlock(cmd); - cmd->pid = u->p->pid; + cmd->pid = up->pid; cmd->cmd.base = cmd->cmdblk; memmove(cmd->cmd.base, a, n); cmd->cmd.lim = cmd->cmd.base + n; @@ -239,7 +239,7 @@ scsiwrite(Chan *c, char *a, long n, ulong offset) qunlock(cmd); error(Egreg); } - if(cmd->pid != u->p->pid) + if(cmd->pid != up->pid) error(Egreg); if (n > DATASIZE) error(Ebadarg); @@ -297,7 +297,6 @@ scsicmd(int dev, int cmdbyte, Scsibuf *b, long size) cmd->cmd.ptr = cmd->cmd.base; memset(cmd->cmdblk, 0, sizeof cmd->cmdblk); cmd->cmdblk[0] = cmdbyte; - cmd->cmdblk[1] = cmd->lun << 5; switch(cmdbyte >> 5){ case 0: cmd->cmd.lim = &cmd->cmdblk[6]; @@ -498,34 +497,16 @@ int scsibread(int dev, Scsibuf *b, long n, long blocksize, long blockno) { Scsi *cmd; - int cmdbyte; - if(blockno <= 0x1fffff && n <= 256) - cmdbyte = ScsiRead; - else - cmdbyte = ScsiExtread; - - cmd = scsicmd(dev, cmdbyte, b, n*blocksize); + cmd = scsicmd(dev, ScsiRead, b, n*blocksize); if(waserror()){ qunlock(cmd); nexterror(); } - switch(cmdbyte){ - case ScsiRead: - cmd->cmdblk[1] |= blockno >> 16; - cmd->cmdblk[2] = blockno >> 8; - cmd->cmdblk[3] = blockno; - cmd->cmdblk[4] = n; - break; - default: - cmd->cmdblk[2] = blockno >> 24; - cmd->cmdblk[3] = blockno >> 16; - cmd->cmdblk[4] = blockno >> 8; - cmd->cmdblk[5] = blockno; - cmd->cmdblk[7] = n>>8; - cmd->cmdblk[8] = n; - break; - } + cmd->cmdblk[1] = blockno >> 16; + cmd->cmdblk[2] = blockno >> 8; + cmd->cmdblk[3] = blockno; + cmd->cmdblk[4] = n; scsiexec(cmd, ScsiIn); n = cmd->data.ptr - cmd->data.base; poperror(); @@ -538,34 +519,15 @@ scsibwrite(int dev, Scsibuf *b, long n, long blocksize, long blockno) { Scsi *cmd; - int cmdbyte; - - if(blockno <= 0x1fffff && n <= 256) - cmdbyte = ScsiWrite; - else - cmdbyte = ScsiExtwrite; - - cmd = scsicmd(dev, cmdbyte, b, n*blocksize); + cmd = scsicmd(dev, ScsiWrite, b, n*blocksize); if(waserror()){ qunlock(cmd); nexterror(); } - switch(cmdbyte){ - case ScsiWrite: - cmd->cmdblk[1] |= blockno >> 16; - cmd->cmdblk[2] = blockno >> 8; - cmd->cmdblk[3] = blockno; - cmd->cmdblk[4] = n; - break; - default: - cmd->cmdblk[2] = blockno >> 24; - cmd->cmdblk[3] = blockno >> 16; - cmd->cmdblk[4] = blockno >> 8; - cmd->cmdblk[5] = blockno; - cmd->cmdblk[7] = n>>8; - cmd->cmdblk[8] = n; - break; - } + cmd->cmdblk[1] = blockno >> 16; + cmd->cmdblk[2] = blockno >> 8; + cmd->cmdblk[3] = blockno; + cmd->cmdblk[4] = n; scsiexec(cmd, ScsiOut); n = cmd->data.ptr - cmd->data.base; poperror(); diff --git a/port/devsrv.c b/port/devsrv.c index ae0a919808cd633d55f3e067c33a73bb259f3ffc..3bbcec7e9069ecb63b36c6c5c8f3790f3f03b7c0 100644 --- a/port/devsrv.c +++ b/port/devsrv.c @@ -20,7 +20,7 @@ struct Srv static QLock srvlk; static Srv *srv; -static int path; +static int qidpath; int srvgen(Chan *c, Dirtab *tab, int ntab, int s, Dir *dp) @@ -45,7 +45,7 @@ srvgen(Chan *c, Dirtab *tab, int ntab, int s, Dir *dp) void srvinit(void) { - path = 1; + qidpath = 1; } void @@ -132,7 +132,7 @@ srvcreate(Chan *c, char *name, int omode, ulong perm) qunlock(&srvlk); nexterror(); } - sp->path = path++; + sp->path = qidpath++; sp->link = srv; c->qid.path = sp->path; srv = sp; @@ -140,7 +140,7 @@ srvcreate(Chan *c, char *name, int omode, ulong perm) poperror(); strncpy(sp->name, name, NAMELEN); - strncpy(sp->owner, u->p->user, NAMELEN); + strncpy(sp->owner, up->user, NAMELEN); sp->perm = perm&0777; c->flag |= COPEN; @@ -218,7 +218,7 @@ srvwrite(Chan *c, void *va, long n, ulong offset) buf[n] = 0; fd = strtoul(buf, 0, 0); - c1 = fdtochan(fd, -1, 0, 1); /* error check only */ + c1 = fdtochan(fd, -1, 0, 1); /* error check and inc ref */ qlock(&srvlk); if(waserror()) { @@ -241,3 +241,21 @@ srvwrite(Chan *c, void *va, long n, ulong offset) poperror(); return n; } + +void +srvrecover(Chan *old, Chan *new) +{ + Srv *sp; + + qlock(&srvlk); + for(sp = srv; sp; sp = sp->link) { + if(sp->chan == old) { + sp->chan = new; + incref(new); + qunlock(&srvlk); + close(old); + return; + } + } + qunlock(&srvlk); +} diff --git a/port/error.h b/port/error.h index 01ae5bed47e4d1d044dc4deb95d9d2b3e844ddc7..c18abfecdaabdc3a9ac0c6b0d37be01eb8ccf77b 100644 --- a/port/error.h +++ b/port/error.h @@ -55,3 +55,4 @@ extern char Esfnotcached[]; /* subfont not cached */ extern char Egreg[]; /* it's a thermal problem */ extern char Esoverlap[]; /* segments overlap */ extern char Emouseset[]; /* mouse type already set */ +extern char Erecover[]; /* failed to recover fd */ diff --git a/port/fault.c b/port/fault.c index b378d759e52eab1659798ef541ab8e6181d21bec..747604620ec8f50ab47dfbe27eb74787d63ff93a 100644 --- a/port/fault.c +++ b/port/fault.c @@ -13,21 +13,21 @@ fault(ulong addr, int read) Segment *s; char *sps; - sps = u->p->psstate; - u->p->psstate = "Fault"; + sps = up->psstate; + up->psstate = "Fault"; spllo(); m->pfault++; for(;;) { - s = seg(u->p, addr, 1); + s = seg(up, addr, 1); if(s == 0) { - u->p->psstate = sps; + up->psstate = sps; return -1; } if(!read && (s->type&SG_RONLY)) { qunlock(&s->lk); - u->p->psstate = sps; + up->psstate = sps; return -1; } @@ -35,14 +35,14 @@ fault(ulong addr, int read) break; } - u->p->psstate = sps; + up->psstate = sps; return 0; } int fixfault(Segment *s, ulong addr, int read, int doputmmu) { - int type; + int i, type; Pte **p, *etp; ulong mmuphys=0, soff; Page **pg, *lkp, *new; @@ -80,11 +80,6 @@ fixfault(Segment *s, ulong addr, int read, int doputmmu) if(pagedout(*pg)) pio(s, addr, soff, pg); - lkp = *pg; - lock(lkp); - if(lkp->image) - duppage(lkp); - unlock(lkp); goto done; case SG_BSS: @@ -155,8 +150,10 @@ fixfault(Segment *s, ulong addr, int read, int doputmmu) break; } - if(s->flushme) - memset((*pg)->cachectl, PG_TXTFLUSH, sizeof(new->cachectl)); + if(s->flushme){ + for(i = 0; i < MAXMACH; i++) + (*pg)->cachectl[i] |= PG_TXTFLUSH; + } qunlock(&s->lk); @@ -203,7 +200,7 @@ pio(Segment *s, ulong addr, ulong soff, Page **p) if(loadrec == 0) { /* This is demand load */ c = s->image->c; while(waserror()) { - if(strcmp(u->error, Eintr) == 0) + if(strcmp(up->error, Eintr) == 0) continue; kunmap(k); putpage(new); @@ -264,8 +261,8 @@ pio(Segment *s, ulong addr, ulong soff, Page **p) void faulterror(char *s) { - if(u->nerrlab) { - postnote(u->p, 1, s, NDebug); + if(up->nerrlab) { + postnote(up, 1, s, NDebug); error(s); } pexit(s, 0); @@ -281,7 +278,7 @@ okaddr(ulong addr, ulong len, int write) if((long)len >= 0) { for(;;) { - s = seg(u->p, addr, 0); + s = seg(up, addr, 0); if(s == 0 || (write && (s->type&SG_RONLY))) break; @@ -336,18 +333,20 @@ seg(Proc *p, ulong addr, int dolock) Segment **s, **et, *n; et = &p->seg[NSEG]; - for(s = p->seg; s < et; s++) - if(n = *s){ - if(addr >= n->base && addr < n->top) { - if(dolock == 0) - return n; + for(s = p->seg; s < et; s++) { + n = *s; + if(n == 0) + continue; + if(addr >= n->base && addr < n->top) { + if(dolock == 0) + return n; - qlock(&n->lk); - if(addr >= n->base && addr < n->top) - return n; - qunlock(&n->lk); - } + qlock(&n->lk); + if(addr >= n->base && addr < n->top) + return n; + qunlock(&n->lk); } + } return 0; } diff --git a/port/ipdat.h b/port/ipdat.h index 75eecccc90246ef6fedbff1b2fc2e60de3790a34..7ec2de425198ef4de2c7cedec6bfb581dc43d37b 100644 --- a/port/ipdat.h +++ b/port/ipdat.h @@ -208,20 +208,20 @@ struct Tctl uchar type; /* Listening or active connection */ uchar code; /* Icmp code */ struct { - ulong una; /* Unacked data pointer */ - ulong nxt; /* Next sequence expected */ - ulong ptr; /* Data pointer */ + int una; /* Unacked data pointer */ + int nxt; /* Next sequence expected */ + int ptr; /* Data pointer */ ushort wnd; /* Tcp send window */ - ulong up; /* Urgent data pointer */ - ulong wl1; - ulong wl2; + int up; /* Urgent data pointer */ + int wl1; + int wl2; } snd; struct { - ulong nxt; /* Receive pointer to next byte slot */ + int nxt; /* Receive pointer to next byte slot */ ushort wnd; /* Receive window incoming */ - ulong up; /* Urgent pointer */ + int up; /* Urgent pointer */ } rcv; - ulong iss; /* Initial sequence number */ + int iss; /* Initial sequence number */ ushort cwind; /* Congestion window */ ushort ssthresh; /* Slow start threshold */ int resent; /* Bytes just resent */ @@ -230,7 +230,7 @@ struct Tctl int rerecv; /* Overlap of data rerecevived */ ushort window; /* Recevive window */ int max_snd; /* Max send */ - ulong last_ack; /* Last acknowledege received */ + int last_ack; /* Last acknowledege received */ char backoff; /* Exponential backoff counter */ char flags; /* State flags */ char tos; /* Type of service */ @@ -248,7 +248,7 @@ struct Tctl Timer timer; /* Activity timer */ Timer acktimer; /* Acknoledge timer */ Timer rtt_timer; /* Round trip timer */ - ulong rttseq; /* Round trip sequence */ + int rttseq; /* Round trip sequence */ int srtt; /* Shortened round trip */ int mdev; /* Mean deviation of round trip */ }; @@ -264,8 +264,8 @@ struct Tcp { Port source; Port dest; - ulong seq; - ulong ack; + int seq; + int ack; char flags; ushort wnd; ushort up; @@ -311,7 +311,7 @@ struct Ipconv enum { MAX_TIME = (1<<20), /* Forever */ - TCP_ACK = 50, /* Timed ack sequence in ms */ + TCP_ACK = 200, /* Timed ack sequence every 200ms */ URG = 0x20, /* Data marked urgent */ ACK = 0x10, /* Aknowledge is valid */ @@ -326,7 +326,7 @@ enum MSS_LENGTH = 4, /* Mean segment size */ MSL2 = 10, - MSPTICK = 50, /* Milliseconds per timer tick */ + MSPTICK = 100, /* Milliseconds per timer tick */ DEF_MSS = 1024, /* Default mean segment */ DEF_RTT = 1000, /* Default round trip */ @@ -477,13 +477,13 @@ ushort ptcl_csum(Block*bp, int, int); int pullb(Block **, int); void reset(Ipaddr, Ipaddr, char, ushort, Tcp*); void tcpsndsyn(Tcpctl*); -int seq_ge(ulong, ulong); -int seq_gt(ulong, ulong); -int seq_gt(ulong, ulong); -int seq_le(ulong, ulong); -int seq_lt(ulong, ulong); -int seq_within(ulong, ulong, ulong); -int seq_within(ulong, ulong, ulong); +int seq_ge(int, int); +int seq_gt(int, int); +int seq_gt(int, int); +int seq_le(int, int); +int seq_lt(int, int); +int seq_within(int, int, int); +int seq_within(int, int, int); void tcpsetstate(Ipconv *, char); void tcpgo(Timer *); void tcphalt(Timer *); diff --git a/port/lib.h b/port/lib.h index cd609ec01d1aba4c7fd45060af2554b6f40bfbe8..27b92d76ce88a4e2bba3511925a2ede5cbfb739d 100644 --- a/port/lib.h +++ b/port/lib.h @@ -26,10 +26,10 @@ extern int atoi(char*); enum { - UTFmax = 3, /* maximum bytes per rune */ - Runesync = 0x80, /* cannot represent part of a UTF sequence (<) */ - Runeself = 0x80, /* rune and UTF sequences are the same (<) */ - Runeerror = 0x80, /* decoding error in UTF */ + UTFmax = 3, /* maximum bytes per rune */ + Runesync = 0x80, /* cannot represent part of a UTF sequence */ + Runeself = 0x80, /* rune and UTF sequences are the same (<) */ + Runeerror = 0x80, /* decoding error in UTF */ }; /* @@ -70,16 +70,17 @@ extern ulong strtoul(char*, char**, int); extern char etext[]; extern char edata[]; extern char end[]; + /* * Syscall data structures */ - #define MORDER 0x0003 /* mask for bits defining order of mounting */ #define MREPL 0x0000 /* mount replaces object */ #define MBEFORE 0x0001 /* mount goes before others in union directory */ #define MAFTER 0x0002 /* mount goes after others in union directory */ #define MCREATE 0x0004 /* permit creation in mounted directory */ -#define MMASK 0x0007 /* all bits on */ +#define MRECOV 0x0008 /* perform recovery if mount channel is lost */ +#define MMASK 0x000F /* all bits on */ #define OREAD 0 /* open for read */ #define OWRITE 1 /* write */ diff --git a/port/net.c b/port/net.c index 8fa71304d8735383518771937413685f63c8d001..fe4aed27985978d97580ca0c4cc301aae48b8a93 100644 --- a/port/net.c +++ b/port/net.c @@ -136,7 +136,34 @@ netwalk(Chan *c, char *name, Network *np) void netstat(Chan *c, char *db, Network *np) { - devstat(c, db, (Dirtab*)np, 1, netgen); + int i; + Dir dir; + + for(i=0;; i++) + switch(netgen(c, (Dirtab*)np, 0, i, &dir)){ + case -1: + /* + * devices with interesting directories usually don't get + * here, which is good because we've lost the name by now. + */ + if(c->qid.path & CHDIR){ + devdir(c, c->qid, c->path->elem, 0L, eve, CHDIR|0555, &dir); + convD2M(&dir, db); + return; + } + print("netstat %C %lux\n", devchar[c->type], c->qid.path); + error(Enonexist); + case 0: + break; + case 1: + if(eqqid(c->qid, dir.qid)){ + if(c->flag&CMSG) + dir.mode |= CHMOUNT; + convD2M(&dir, db); + return; + } + break; + } } Chan * @@ -159,10 +186,12 @@ netopen(Chan *c, int omode, Network *np) id = (*np->listen)(c); streamclose(c); c->qid.path = STREAMQID(id, Sctlqid); + ptclone(c, 1, id); break; case Qclone: id = (*np->clone)(c); c->qid.path = STREAMQID(id, Sctlqid); + ptclone(c, 0, id); break; default: if(omode != OREAD) @@ -175,7 +204,7 @@ netopen(Chan *c, int omode, Network *np) if(np->protop && c->stream->devq->next->info != np->protop) pushq(c->stream, np->protop); p = findprot(np, id); - if(netown(p, u->p->user, omode&7) < 0) + if(netown(p, up->user, omode&7) < 0) error(Eperm); break; } @@ -283,7 +312,7 @@ netwstat(Chan *c, char *db, Network *np) * ownership of the connection. The open file descriptor is used as * a capability for the connection. */ - if(strncmp(p->owner, u->p->user, NAMELEN) != 0 && u->scallnr != FWSTAT){ + if(strncmp(p->owner, up->user, NAMELEN) != 0 && up->scallnr != FWSTAT){ unlock(np); error(Eperm); } diff --git a/port/page.c b/port/page.c index 32e4980445fef78bcb2badabdf271b2190202b96..e08e2dee40c78efa7d232567b68c3c99a776e085 100644 --- a/port/page.c +++ b/port/page.c @@ -14,7 +14,7 @@ void pageinit(void) { Page *p; - ulong np, hw, hr, vmem, pmem; + ulong np, vmem, pmem; np = palloc.np0+palloc.np1; palloc.head = xalloc(np*sizeof(Page)); @@ -51,11 +51,7 @@ pageinit(void) swapalloc.highwater = (palloc.freecount*5)/100; swapalloc.headroom = swapalloc.highwater + (swapalloc.highwater/4); - hw = swapalloc.highwater*BY2PG; - hr = swapalloc.headroom*BY2PG; - - print("%lud free pages, %dK bytes, swap %dK, highwater %dK, headroom %dK\n", - palloc.user, pmem, vmem, hw/1024, hr/1024);/**/ + print("%lud free pages\n%dK bytes\n%dK swap\n", palloc.user, pmem, vmem); } Page* @@ -63,13 +59,13 @@ newpage(int clear, Segment **s, ulong va) { Page *p; KMap *k; - int hw, i, dontalloc; + int hw, dontalloc; retry: lock(&palloc); hw = swapalloc.highwater; - while((palloc.freecount < hw && u->p->kp == 0) || palloc.freecount == 0) { + while((palloc.freecount < hw && up->kp == 0) || palloc.freecount == 0) { palloc.wanted++; unlock(&palloc); dontalloc = 0; @@ -120,9 +116,7 @@ retry: p->ref++; p->va = va; p->modref = 0; - for(i = 0; i < MAXMACH; i++) - p->cachectl[i] = PG_NOFLUSH; - mmunewpage(p); + memset(p->cachectl, PG_DATINVALID, sizeof(p->cachectl)); unlock(p); if(clear){ @@ -205,6 +199,7 @@ void duppage(Page *p) /* Always call with p locked */ { Page *np; + int i; /* No dup for swap pages */ if(p->image == &swapimage) { @@ -249,7 +244,8 @@ duppage(Page *p) /* Always call with p locked */ uncachepage(np); np->va = p->va; np->daddr = p->daddr; - mmunewpage(np); + for(i = 0; i < MAXMACH; i++) + np->cachectl[i] |= PG_DATINVALID; copypage(p, np); cachepage(np, p->image); unlock(np); @@ -408,8 +404,8 @@ void freepte(Segment *s, Pte *p) { int ref; - Page *pt, **pg, **ptop; void (*fn)(Page*); + Page *pt, **pg, **ptop; switch(s->type&SG_TYPE) { case SG_PHYSICAL: diff --git a/port/pgrp.c b/port/pgrp.c index eb2a4fb59b3a4684756fa9522a8f533b7823ecdc..6cef5618fa0f5f85de77c37b7a2f79b5c40e1bbc 100644 --- a/port/pgrp.c +++ b/port/pgrp.c @@ -93,7 +93,7 @@ pgrpcpy(Pgrp *to, Pgrp *from) l = &mh->hash; link = &mh->mount; for(m = f->mount; m; m = m->next) { - n = newmount(mh, m->to); + n = newmount(mh, m->to, m->flag, m->spec); *link = n; link = &n->next; } @@ -142,7 +142,7 @@ closefgrp(Fgrp *f) Mount* -newmount(Mhead *mh, Chan *to) +newmount(Mhead *mh, Chan *to, int flag, char *spec) { Mount *m; @@ -151,6 +151,10 @@ newmount(Mhead *mh, Chan *to) m->head = mh; incref(to); m->mountid = incref(&mountid); + m->flag = flag; + if(spec != 0) + strcpy(m->spec, spec); + return m; } @@ -162,6 +166,7 @@ mountfree(Mount *m) while(m) { f = m->next; close(m->to); + m->mountid = 0; free(m); m = f; } @@ -172,14 +177,15 @@ resrcwait(char *reason) { char *p; - p = u->p->psstate; + if(up == 0) + panic("resrcwait"); + + p = up->psstate; if(reason) { - u->p->psstate = reason; + up->psstate = reason; print("%s\n", reason); } - if(u == 0) - panic("resrcwait"); - tsleep(&u->p->sleep, return0, 0, 300); - u->p->psstate = p; + tsleep(&up->sleep, return0, 0, 300); + up->psstate = p; } diff --git a/port/portdat.h b/port/portdat.h index 222cf3d0c97b53f5ecd0fdf9bbfebcaf3b3427b3..7b04c7256ff766191c5e55b94c9d2b116f83b8a7 100644 --- a/port/portdat.h +++ b/port/portdat.h @@ -2,6 +2,7 @@ typedef struct Alarms Alarms; typedef struct Block Block; typedef struct Blist Blist; typedef struct Chan Chan; +typedef struct Crypt Crypt; typedef struct Dev Dev; typedef struct Dirtab Dirtab; typedef struct Egrp Egrp; @@ -13,6 +14,8 @@ typedef struct IOQ IOQ; typedef struct KIOQ KIOQ; typedef struct List List; typedef struct Mount Mount; +typedef struct Mntrpc Mntrpc; +typedef struct Mntwalk Mntwalk; typedef struct Mnt Mnt; typedef struct Mhead Mhead; typedef struct Netinf Netinf; @@ -20,12 +23,14 @@ typedef struct Netprot Netprot; typedef struct Network Network; typedef struct Note Note; typedef struct Page Page; +typedef struct Path Path; typedef struct Palloc Palloc; typedef struct Pgrps Pgrps; typedef struct Pgrp Pgrp; typedef struct Physseg Physseg; typedef struct Proc Proc; typedef struct Pte Pte; +typedef struct Pthash Pthash; typedef struct Qinfo Qinfo; typedef struct QLock QLock; typedef struct Queue Queue; @@ -33,11 +38,11 @@ typedef struct Ref Ref; typedef struct Rendez Rendez; typedef struct RWlock RWlock; typedef struct Sargs Sargs; -typedef struct Session Session; typedef struct Scsi Scsi; typedef struct Scsibuf Scsibuf; typedef struct Scsidata Scsidata; typedef struct Segment Segment; +typedef struct Session Session; typedef struct Stream Stream; typedef struct Talarm Talarm; typedef struct Waitq Waitq; @@ -128,7 +133,7 @@ struct Blist }; /* - * Access types in namec + * Access types in namec & channel flags */ enum { @@ -137,42 +142,51 @@ enum Aopen, /* for i/o */ Amount, /* to be mounted upon */ Acreate, /* file is to be created */ + + COPEN = 0x0001, /* for i/o */ + CMSG = 0x0002, /* the message channel for a mount */ + CCREATE = 0x0004, /* permits creation if c->mnt */ + CCEXEC = 0x0008, /* close on exec */ + CFREE = 0x0010, /* not in use */ + CRCLOSE = 0x0020, /* remove on close */ + CRECOV = 0x0040, /* requires recovery */ }; -/* - * Chan.flags - */ -#define COPEN 1 /* for i/o */ -#define CMSG 2 /* is the message channel for a mount */ -#define CCREATE 4 /* permits creation if c->mnt */ -#define CCEXEC 8 /* close on exec */ -#define CFREE 16 /* not in use */ -#define CRCLOSE 32 /* remove on close */ +struct Path +{ + Ref; + Path *hash; + Path *parent; + Pthash *pthash; + char elem[NAMELEN]; +}; struct Chan { Ref; - union{ - Chan *next; /* allocation */ - ulong offset; /* in file */ - }; + Chan *next; /* allocation */ + Chan *link; + ulong offset; /* in file */ ushort type; ushort dev; ushort mode; /* read/write */ ushort flag; Qid qid; - Mount *mnt; /* mount point that derived Chan */ - ulong mountid; int fid; /* for devmnt */ Stream *stream; /* for stream channels */ + Path *path; + Mount *mnt; /* mount point that derived Chan */ + Mount *xmnt; /* Last mount point crossed */ + ulong mountid; union { void *aux; Qid pgrpid; /* for #p/notepg */ Mnt *mntptr; /* for devmnt */ + ulong mid; /* for ns in devproc */ }; Chan *mchan; /* channel to mounted server */ Qid mqid; /* qid of root of mount point */ - Session *session; + Session *session; }; struct Dev @@ -231,8 +245,6 @@ enum ScsiGetcap = 0x25, ScsiRead = 0x08, ScsiWrite = 0x0a, - ScsiExtread = 0x28, - ScsiExtwrite = 0x2a, /* data direction */ ScsiIn = 1, @@ -298,12 +310,36 @@ struct KIOQ int count; }; +enum +{ + NSMAX = 1000, + NSLOG = 7, + NSCACHE = (1<nerrlab-- +#define poperror() up->nerrlab-- int postnote(Proc*, int, char*, int); int pprint(char*, ...); void printinit(void); @@ -214,6 +203,7 @@ void resetscsi(void); void resrcwait(char*); int return0(void*); void rlock(RWlock*); +void rootreq(Chan*, Mnt*); void runlock(RWlock*); Proc* runproc(void); void savefpregs(FPsave*); @@ -280,7 +270,6 @@ void unmount(Chan*, Chan*); void urpfillstats(Chan*, char*, int); void userinit(void); ulong userpc(void); -long userwrite(char*, int); void validaddr(ulong, ulong, int); void* vmemchr(void*, int, int); void wakeup(Rendez*); @@ -294,3 +283,25 @@ void* xspanalloc(ulong, int, ulong); void xsummary(void); Segment* dupseg(Segment**, int, int); Segment* seg(Proc*, ulong, int); +Path* ptenter(Pthash*, Path*, char*); +void ptclose(Pthash*); +int ptpath(Path*, char*, int); +void ptclone(Chan*, int, int); +Chan* walk(Chan*, char*, int); +Chan* domount(Chan*); +void rootrecover(Path*, char*); +void mntrepl(char*); +void srvrecover(Chan*, Chan*); +int iseve(void); +void authclose(Chan*); +long keyread(char*, int, long); +long keywrite(char*, int); +long userwrite(char*, int); +long hostownerwrite(char*, int); +long hostdomainwrite(char*, int); +long authread(Chan*, char*, int); +long authwrite(Chan*, char*, int); +long authcheck(Chan*, char*, int); +ulong authrequest(Session*, Fcall*); +void authreply(Session*, ulong, Fcall*); +void freesession(Session*); diff --git a/port/proc.c b/port/proc.c index eb08a3e88b87d09d1a8fb8ad85f40576b20f00f1..36896cc1607365549c916c53a7547aa4abee8bdd 100644 --- a/port/proc.c +++ b/port/proc.c @@ -51,36 +51,32 @@ char *statename[] = void schedinit(void) /* never returns */ { - Proc *p; - setlabel(&m->sched); - if(u){ + if(up) { m->proc = 0; - p = u->p; - invalidateu(); /* safety first */ - u = 0; - if(p->state == Running) - ready(p); - else - if(p->state == Moribund) { - p->pid = 0; - p->state = Dead; + switch(up->state) { + case Running: + ready(up); + break; + case Moribund: + up->pid = 0; + up->state = Dead; /* * Holding locks from pexit: * procalloc, debug, palloc */ - mmurelease(p); - simpleputpage(p->upage); - p->upage = 0; + mmurelease(up); - p->qnext = procalloc.free; - procalloc.free = p; + up->qnext = procalloc.free; + procalloc.free = up; unlock(&palloc); - qunlock(&p->debug); + qunlock(&up->debug); unlock(&procalloc); + break; } - p->mach = 0; + up->mach = 0; + up = 0; } sched(); } @@ -88,26 +84,23 @@ schedinit(void) /* never returns */ void sched(void) { - Proc *p; - - if(u){ + if(up) { splhi(); m->cs++; - procsave(u->p); - if(setlabel(&u->p->sched)){ /* woke up */ - p = u->p; - p->state = Running; - p->mach = m; - m->proc = p; - procrestore(p); + procsave(up); + if(setlabel(&up->sched)) { + procrestore(up); spllo(); return; } gotolabel(&m->sched); } - p = runproc(); - mapstack(p); - gotolabel(&p->sched); + up = runproc(); + up->state = Running; + up->mach = m; + m->proc = up; + mmuswitch(up); + gotolabel(&up->sched); } int @@ -119,15 +112,14 @@ anyready(void) void ready(Proc *p) { - Schedq *rq; int s; + Schedq *rq; s = splhi(); + rq = &runhiq; if(p->state == Running) rq = &runloq; - else - rq = &runhiq; lock(&runhiq); p->rnext = 0; @@ -154,7 +146,7 @@ runproc(void) loop: spllo(); - while(runhiq.head==0 && runloq.head==0) + while(runhiq.head == 0 && runloq.head == 0) ; splhi(); @@ -165,7 +157,8 @@ loop: rq = &runloq; p = rq->head; - if(p==0 || p->mach){ /* p->mach==0 only when process state is saved */ + /* p->mach==0 only when process state is saved */ + if(p == 0 || p->mach){ unlock(&runhiq); goto loop; } @@ -203,37 +196,43 @@ newproc(void) { Proc *p; + lock(&procalloc); for(;;) { - lock(&procalloc); - if(p = procalloc.free){ /* assign = */ - procalloc.free = p->qnext; - p->state = Scheding; - p->psstate = "New"; - unlock(&procalloc); - p->mach = 0; - p->qnext = 0; - p->nchild = 0; - p->nwait = 0; - p->waitq = 0; - p->pgrp = 0; - p->egrp = 0; - p->fgrp = 0; - p->pdbg = 0; - p->fpstate = FPinit; - p->kp = 0; - p->procctl = 0; - p->notepending = 0; - memset(p->seg, 0, sizeof p->seg); - p->pid = incref(&pidalloc); - p->noteid = incref(¬eidalloc); - if(p->pid==0 || p->noteid==0) - panic("pidalloc"); - return p; - } + if(p = procalloc.free) + break; + unlock(&procalloc); resrcwait("no procs"); + lock(&procalloc); } - return 0; /* not reached */ + procalloc.free = p->qnext; + unlock(&procalloc); + + procalloc.free = p->qnext; + p->state = Scheding; + p->psstate = "New"; + p->mach = 0; + p->qnext = 0; + p->nchild = 0; + p->nwait = 0; + p->waitq = 0; + p->pgrp = 0; + p->egrp = 0; + p->fgrp = 0; + p->pdbg = 0; + p->fpstate = FPinit; + p->kp = 0; + p->procctl = 0; + p->notepending = 0; + memset(p->seg, 0, sizeof p->seg); + p->pid = incref(&pidalloc); + p->noteid = incref(¬eidalloc); + if(p->pid==0 || p->noteid==0) + panic("pidalloc"); + if(p->kstack == 0) + p->kstack = smalloc(KSTACK); + + return p; } void @@ -254,7 +253,6 @@ procinit0(void) /* bad planning - clashes with devproc.c */ void sleep1(Rendez *r, int (*f)(void*), void *arg) { - Proc *p; int s; /* @@ -262,15 +260,14 @@ sleep1(Rendez *r, int (*f)(void*), void *arg) * at interrupt time. lock is mutual exclusion */ s = splhi(); - p = u->p; - p->r = r; /* early so postnote knows */ + up->r = r; /* early so postnote knows */ lock(r); /* * if condition happened, never mind */ if((*f)(arg)){ - p->r = 0; + up->r = 0; unlock(r); splx(s); return; @@ -281,29 +278,28 @@ sleep1(Rendez *r, int (*f)(void*), void *arg) * change state and call scheduler */ if(r->p){ - print("double sleep %d %d\n", r->p->pid, p->pid); + print("double sleep %d %d\n", r->p->pid, up->pid); dumpstack(); } - p->state = Wakeme; - r->p = p; + up->state = Wakeme; + r->p = up; unlock(r); } void sleep(Rendez *r, int (*f)(void*), void *arg) { - Proc *p; int s; - p = u->p; sleep1(r, f, arg); - if(p->notepending == 0) + if(up->notepending == 0) sched(); /* notepending may go true while asleep */ - if(p->notepending){ - p->notepending = 0; + + if(up->notepending) { + up->notepending = 0; s = splhi(); lock(r); - if(r->p == p) + if(r->p == up) r->p = 0; unlock(r); splx(s); @@ -314,28 +310,24 @@ sleep(Rendez *r, int (*f)(void*), void *arg) int tfn(void *arg) { - Proc *p; - - p = u->p; - return MACHP(0)->ticks >= p->twhen || (*p->tfn)(arg); + return MACHP(0)->ticks >= up->twhen || (*up->tfn)(arg); } void tsleep(Rendez *r, int (*fn)(void*), void *arg, int ms) { ulong when; - Proc *p, *f, **l; + Proc *f, **l; - p = u->p; when = MS2TK(ms)+MACHP(0)->ticks; lock(&talarm); /* take out of list if checkalarm didn't */ - if(p->trend) { + if(up->trend) { l = &talarm.list; for(f = *l; f; f = f->tlink) { - if(f == p) { - *l = p->tlink; + if(f == up) { + *l = up->tlink; break; } l = &f->tlink; @@ -348,15 +340,15 @@ tsleep(Rendez *r, int (*fn)(void*), void *arg, int ms) break; l = &f->tlink; } - p->trend = r; - p->twhen = when; - p->tfn = fn; - p->tlink = *l; - *l = p; + up->trend = r; + up->twhen = when; + up->tfn = fn; + up->tlink = *l; + *l = up; unlock(&talarm); sleep(r, tfn, arg); - p->twhen = 0; + up->twhen = 0; } /* @@ -385,8 +377,6 @@ wakeup(Rendez *r) int postnote(Proc *p, int dolock, char *n, int flag) { - User *up; - KMap *k; int s, ret; Rendez *r; Proc *d, **l; @@ -397,44 +387,28 @@ postnote(Proc *p, int dolock, char *n, int flag) if(p->kp) print("sending %s to kproc %d %s\n", n, p->pid, p->text); - if(p->upage == 0){ - if(dolock) - qunlock(&p->debug); - return 0; - } - - SET(k); - if(u == 0 || p != u->p){ - k = kmap(p->upage); - up = (User*)VA(k); - }else - up = u; - USED(k); - - if(flag!=NUser && (up->notify==0 || up->notified)) - up->nnote = 0; /* force user's hand */ + if(flag != NUser && (p->notify == 0 || p->notified)) + p->nnote = 0; ret = 0; - if(up->nnote < NNOTE){ - strcpy(up->note[up->nnote].msg, n); - up->note[up->nnote++].flag = flag; + if(p->nnote < NNOTE) { + strcpy(p->note[up->nnote].msg, n); + p->note[p->nnote++].flag = flag; ret = 1; } p->notepending = 1; - if(up != u) - kunmap(k); if(dolock) qunlock(&p->debug); - if(r = p->r){ /* assign = */ - /* wake up; can't call wakeup itself because we're racing with it */ + if(r = p->r) { for(;;) { s = splhi(); if(canlock(r)) break; splx(s); } - if(p->r==r && r->p==p && p->state==Wakeme){ /* check we won the race */ + /* check we won the race */ + if(p->r == r && r->p == p && p->state==Wakeme) { r->p = 0; p->r = 0; ready(p); @@ -454,11 +428,11 @@ postnote(Proc *p, int dolock, char *n, int flag) for(d = *l; d; d = d->rendhash) { if(d == p) { *l = p->rendhash; - ready(p); break; } l = &d->rendhash; } + ready(p); } unlock(p->pgrp); return ret; @@ -529,27 +503,27 @@ void pexit(char *exitstr, int freemem) { int n; - long utime, stime; - Proc *p, *c; + Proc *p; Segment **s, **es; + long utime, stime; Waitq *wq, *f, *next; - c = u->p; - c->alarm = 0; + up->alarm = 0; + + if(up->fgrp) + closefgrp(up->fgrp); + if(up->egrp) + closeegrp(up->egrp); - if(c->fgrp) - closefgrp(c->fgrp); - closepgrp(c->pgrp); - close(u->dot); - if(c->egrp) - closeegrp(c->egrp); + close(up->dot); + closepgrp(up->pgrp); /* * if not a kernel process and have a parent, * do some housekeeping. */ - if(c->kp == 0) { - p = c->parent; + if(up->kp == 0) { + p = up->parent; if(p == 0) { if(exitstr == 0) exitstr = "unknown"; @@ -557,31 +531,33 @@ pexit(char *exitstr, int freemem) } while(waserror()) - ; + ; + wq = smalloc(sizeof(Waitq)); poperror(); - readnum(0, wq->w.pid, NUMSIZE, c->pid, NUMSIZE); - utime = c->time[TUser] + c->time[TCUser]; - stime = c->time[TSys] + c->time[TCSys]; + readnum(0, wq->w.pid, NUMSIZE, up->pid, NUMSIZE); + utime = up->time[TUser] + up->time[TCUser]; + stime = up->time[TSys] + up->time[TCSys]; readnum(0, &wq->w.time[TUser*12], NUMSIZE, TK2MS(utime), NUMSIZE); readnum(0, &wq->w.time[TSys*12], NUMSIZE, TK2MS(stime), NUMSIZE); readnum(0, &wq->w.time[TReal*12], NUMSIZE, - TK2MS(MACHP(0)->ticks - c->time[TReal]), NUMSIZE); + TK2MS(MACHP(0)->ticks - up->time[TReal]), NUMSIZE); if(exitstr && exitstr[0]){ - n = sprint(wq->w.msg, "%s %d:", c->text, c->pid); + n = sprint(wq->w.msg, "%s %d:", up->text, up->pid); strncpy(wq->w.msg+n, exitstr, ERRLEN-n); } else wq->w.msg[0] = '\0'; lock(&p->exl); - /* My parent still alive, processes are limited to 128 Zombies to - * prevent a badly written daemon lots of wait records + /* My parent still alive, processes are limited to 128 + * Zombies to prevent a badly written daemon lots of wait + * records */ - if(p->pid == c->parentpid && p->state != Broken && p->nwait < 128) { + if(p->pid == up->parentpid && p->state != Broken && p->nwait < 128) { p->nchild--; p->time[TCUser] += utime; p->time[TCSys] += stime; @@ -590,7 +566,7 @@ pexit(char *exitstr, int freemem) p->waitq = wq; p->nwait++; unlock(&p->exl); - + wakeup(&p->waitr); } else { @@ -600,18 +576,18 @@ pexit(char *exitstr, int freemem) } if(!freemem) - addbroken(c); + addbroken(up); - es = &c->seg[NSEG]; - for(s = c->seg; s < es; s++) + es = &up->seg[NSEG]; + for(s = up->seg; s < es; s++) if(*s) putseg(*s); - lock(&c->exl); /* Prevent my children from leaving waits */ - c->pid = 0; - unlock(&c->exl); + lock(&up->exl); /* Prevent my children from leaving waits */ + up->pid = 0; + unlock(&up->exl); - for(f = c->waitq; f; f = next) { + for(f = up->waitq; f; f = next) { next = f->next; free(f); } @@ -619,17 +595,17 @@ pexit(char *exitstr, int freemem) /* * sched() cannot wait on these locks */ - qlock(&c->debug); + qlock(&up->debug); /* release debuggers */ - if(c->pdbg) { - wakeup(&c->pdbg->sleep); - c->pdbg = 0; + if(up->pdbg) { + wakeup(&up->pdbg->sleep); + up->pdbg = 0; } lock(&procalloc); lock(&palloc); - c->state = Moribund; + up->state = Moribund; sched(); panic("pexit"); } @@ -646,36 +622,33 @@ haswaitq(void *x) ulong pwait(Waitmsg *w) { - Proc *p; ulong cpid; Waitq *wq; - p = u->p; - - if(!canqlock(&p->qwaitr)) + if(!canqlock(&up->qwaitr)) error(Einuse); if(waserror()) { - qunlock(&p->qwaitr); + qunlock(&up->qwaitr); nexterror(); } - lock(&p->exl); - if(p->nchild == 0 && p->waitq == 0) { - unlock(&p->exl); + lock(&up->exl); + if(up->nchild == 0 && up->waitq == 0) { + unlock(&up->exl); error(Enochild); } - unlock(&p->exl); + unlock(&up->exl); - sleep(&p->waitr, haswaitq, u->p); + sleep(&up->waitr, haswaitq, up); - lock(&p->exl); - wq = p->waitq; - p->waitq = wq->next; - p->nwait--; - unlock(&p->exl); + lock(&up->exl); + wq = up->waitq; + up->waitq = wq->next; + up->nwait--; + unlock(&up->exl); - qunlock(&p->qwaitr); + qunlock(&up->qwaitr); poperror(); if(w) @@ -699,21 +672,20 @@ procdump(void) Proc *p; ulong bss; - for(i=0; istate != Dead){ - bss = 0; - if(p->seg[BSEG]) - bss = p->seg[BSEG]->top; - - s = p->psstate; - if(s == 0) - s = "kproc"; - print("%3d:%10s %10s pc %8lux %8s (%s) ut %ld st %ld r %lux qpc %lux bss %lux\n", - p->pid, p->text, p->user, p->pc, - s, statename[p->state], p->time[0], - p->time[1], p->r, p->qlockpc, bss); - } + for(i=0; istate == Dead) + continue; + bss = 0; + if(p->seg[BSEG]) + bss = p->seg[BSEG]->top; + + s = p->psstate; + if(s == 0) + s = "kproc"; + print("%3d:%10s pc %8lux %8s (%s) ut %ld st %ld bss %lux\n", + p->pid, p->text, p->pc, s, statename[p->state], + p->time[0], p->time[1], bss); } } @@ -721,58 +693,34 @@ void kproc(char *name, void (*func)(void *), void *arg) { Proc *p; - int n; - ulong upa; - User *up; - KMap *k; static Pgrp *kpgrp; - char *user; - int lastvar; /* used to compute stack address */ - /* - * Kernel stack - */ p = newproc(); p->psstate = 0; p->procmode = 0644; p->kp = 1; - p->upage = newpage(1, 0, USERADDR|(p->pid&0xFFFF)); - k = kmap(p->upage); - upa = VA(k); - up = (User*)upa; - /* - * Save time: only copy u-> data and useful stack - */ - memmove(up, u, sizeof(User)); - n = USERADDR+BY2PG - (ulong)&lastvar; - n = (n+32) & ~(BY2WD-1); /* be safe & word align */ - memmove((void*)(upa+BY2PG-n), (void*)(USERADDR+BY2PG-n), n); - up->p = p; - - /* - * Refs - */ - incref(up->dot); - kunmap(k); - - /* - * Sched - */ - if(setlabel(&p->sched)){ - p->state = Running; - p->mach = m; - m->proc = p; - spllo(); - (*func)(arg); - pexit(0, 1); - } - - user = eve; - strcpy(p->user, user); - if(kpgrp == 0){ + p->fpsave = up->fpsave; + p->scallnr = up->scallnr; + p->s = up->s; + p->nerrlab = 0; + p->slash = up->slash; + p->dot = up->dot; + incref(p->dot); + + memmove(p->note, up->note, sizeof(p->note)); + p->nnote = up->nnote; + p->notified = 0; + p->lastnote = up->lastnote; + p->notify = up->notify; + p->ureg = 0; + p->dbgreg = 0; + + kprocchild(p, func, arg); + + strcpy(p->user, eve); + if(kpgrp == 0) kpgrp = newpgrp(); - } p->pgrp = kpgrp; incref(kpgrp); @@ -802,11 +750,11 @@ procctl(Proc *p) switch(p->procctl) { case Proc_exitme: - spllo(); /* pexit has locks in it */ + spllo(); /* pexit has locks in it */ pexit("Killed", 1); case Proc_traceme: - if(u->nnote == 0) + if(p->nnote == 0) return; /* No break */ @@ -834,14 +782,14 @@ procctl(Proc *p) void error(char *err) { - strncpy(u->error, err, ERRLEN); + strncpy(up->error, err, ERRLEN); nexterror(); } void nexterror(void) { - gotolabel(&u->errlab[--u->nerrlab]); + gotolabel(&up->errlab[--up->nerrlab]); } void diff --git a/port/qlock.c b/port/qlock.c index 8a84ef7423e3fe61bb8bd21f48bee78890eb5e70..b8ed05973672e0a3f348410532e4d1f45515fa25 100644 --- a/port/qlock.c +++ b/port/qlock.c @@ -10,8 +10,6 @@ qlock(QLock *q) { Proc *p, *mp; - if(u) - u->p->qlockpc = getcallerpc(((uchar*)&q) - sizeof(q)); lock(&q->use); if(!q->locked) { q->locked = 1; @@ -19,7 +17,7 @@ qlock(QLock *q) return; } p = q->tail; - mp = u->p; + mp = up; if(p == 0) q->head = mp; else @@ -39,8 +37,6 @@ canqlock(QLock *q) unlock(&q->use); return 0; } - if(u) - u->p->qlockpc = getcallerpc(((uchar*)&q) - sizeof(q)); q->locked = 1; unlock(&q->use); return 1; @@ -51,8 +47,6 @@ qunlock(QLock *q) { Proc *p; - if(u) - u->p->qlockpc = 0; lock(&q->use); p = q->head; if(p) { diff --git a/port/segment.c b/port/segment.c index 8bb47f6e71f45654267794db618e10bb7fb80e62..bc16614a6177333c9b2b489254ce77a6902d138f 100644 --- a/port/segment.c +++ b/port/segment.c @@ -5,8 +5,7 @@ #include "fns.h" #include "../port/error.h" -Page *lkpage(Segment*, ulong); -void lkpgfree(Page*); +Page *snewpage(ulong addr); void imagereclaim(void); /* System specific segattach devices */ @@ -312,7 +311,7 @@ ibrk(ulong addr, int seg) ulong newtop, newsize; int i; - s = u->p->seg[seg]; + s = up->seg[seg]; if(s == 0) error(Ebadarg); @@ -323,7 +322,7 @@ ibrk(ulong addr, int seg) /* We may start with the bss overlapping the data */ if(addr < s->base) { - if(seg != BSEG || u->p->seg[DSEG] == 0 || addr < u->p->seg[DSEG]->base) { + if(seg != BSEG || up->seg[DSEG] == 0 || addr < up->seg[DSEG]->base) { qunlock(&s->lk); error(Enovmem); } @@ -340,7 +339,7 @@ ibrk(ulong addr, int seg) } for(i = 0; i < NSEG; i++) { - ns = u->p->seg[i]; + ns = up->seg[i]; if(ns == 0 || ns == s) continue; if(newtop >= ns->base && newtop < ns->top) { @@ -408,7 +407,7 @@ segattach(Proc *p, ulong attr, char *name, ulong va, ulong len) vmemchr(name, 0, ~0); for(sno = 0; sno < NSEG; sno++) - if(u->p->seg[sno] == 0 && sno != ESEG) + if(up->seg[sno] == 0 && sno != ESEG) break; if(sno == NSEG) @@ -418,7 +417,7 @@ segattach(Proc *p, ulong attr, char *name, ulong va, ulong len) len = PGROUND(len); newtop = va+len; for(i = 0; i < NSEG; i++) { - ns = u->p->seg[i]; + ns = up->seg[i]; if(ns == 0) continue; if((newtop > ns->base && newtop <= ns->top) || @@ -440,7 +439,9 @@ found: s = newseg(attr, va, len/BY2PG); s->pseg = ps; - u->p->seg[sno] = s; + up->seg[sno] = s; + + /* Need some code build mapped devices here */ return 0; } @@ -453,7 +454,7 @@ syssegflush(ulong *arg) ulong soff; Page *pg; - s = seg(u->p, arg[0], 1); + s = seg(up, arg[0], 1); if(s == 0) error(Ebadarg); @@ -469,7 +470,8 @@ syssegflush(ulong *arg) if(s->map[i]) { while(j < PTEPERTAB) { if(pg = s->map[i]->pages[j]) - memset(pg->cachectl, PG_TXTFLUSH, sizeof pg->cachectl); + for(i = 0; i < MAXMACH; i++) + pg->cachectl[i] |= PG_TXTFLUSH; if(--pages == 0) goto done; j++; @@ -484,3 +486,9 @@ done: flushmmu(); return 0; } + +Page* +snewpage(ulong addr) +{ + return newpage(1, 0, addr); +} diff --git a/port/stasync.c b/port/stasync.c index 86ae3173c786a0687b2e5fe7931731eae591969a..8baa27f9b43867b1051876af55cbad7246cf8d49 100644 --- a/port/stasync.c +++ b/port/stasync.c @@ -196,7 +196,6 @@ aswrite(Async *ap) return; FLOWCTL(ap->wq, ap->bp); ap->bp = 0; - ap->count = 0; } void diff --git a/port/stfcall.c b/port/stfcall.c index 20bdc439502e8ef6b3df40cc9ebc4424032a9d3f..54d3a24263b6995e16306c557f3cd78ef2a5784a 100644 --- a/port/stfcall.c +++ b/port/stfcall.c @@ -24,14 +24,14 @@ static uchar msglen[256] = { [Tnop] 3, [Rnop] 3, - [Tsession] 3+CHALLEN, - [Rsession] 3+NAMELEN+DOMLEN+CHALLEN, + [Tsession] 3, + [Rsession] 3, [Terror] 0, [Rerror] 67, [Tflush] 5, [Rflush] 3, - [Tattach] 5+2*NAMELEN+TICKETLEN+AUTHENTLEN, - [Rattach] 13+AUTHENTLEN, + [Tattach] 89, + [Rattach] 13, [Tclone] 7, [Rclone] 5, [Twalk] 33, @@ -54,6 +54,8 @@ static uchar msglen[256] = [Rwstat] 5, [Tclwalk] 35, [Rclwalk] 13, + [Tauth] 69, + [Rauth] 35, }; static void @@ -158,16 +160,9 @@ fcalliput(Queue *q, Block *bp) if(q->len < len) return; - - /* - * the lock here is wrong. it should be a qlock since - * the pullup may block. not worth fixing. - */ - lock(q); - bp = q->first = pullup(q->first, len); - if(bp == 0) - q->len = 0; - unlock(q); + + pullup(q->first, len); + bp = q->first; need = len+bp->rptr[off]+(bp->rptr[off+1]<<8); if(q->len < need) return; diff --git a/port/stil.c b/port/stil.c index c35bbeedcb3a9f10e3d6d627055b68172e65a8d6..0fd95f962420ffc30ed6e79041707c11ba72fe47 100644 --- a/port/stil.c +++ b/port/stil.c @@ -13,7 +13,7 @@ #define DBG if(0)print int ilcksum = 1; -static int initseq = 25001; +static int initseq = 26000; static Rendez ilackr; char *ilstate[] = @@ -596,9 +596,8 @@ ilhangup(Ipconv *s, char *msg) qunlock(s); if(callout) wakeup(&ic->syncer); + s->psrc = 0; - s->pdst = 0; - s->dst = 0; } void @@ -736,16 +735,16 @@ void ilackproc(void *a) { Ipifc *ifc; - Ipconv **base, **p, **last, *s; + Ipconv **base, **p, **end, *s; Ilcb *ic; ifc = (Ipifc*)a; base = ifc->conv; - last = &base[Nipconv]; + end = &base[Nipconv]; for(;;) { tsleep(&ilackr, return0, 0, Iltickms); - for(p = base; p < last && *p; p++) { + for(p = base; p < end && *p; p++) { s = *p; ic = &s->ilctl; ic->timeout += Iltickms; diff --git a/port/stip.c b/port/stip.c index 6a91a8b4512c4c9175f341960e7d39c9324d75f0..2c0c2bd696984b04362134078616ac7e0779e4c3 100644 --- a/port/stip.c +++ b/port/stip.c @@ -139,7 +139,7 @@ ipetheroput(Queue *q, Block *bp) if(bp->type != M_DATA){ /* Allow one setting of the ip address */ if(streamparse("setip", bp)) { - if(strncmp(eve, u->p->user, sizeof(eve)) != 0) + if(strncmp(eve, up->user, sizeof(eve)) != 0) error(Eperm); ptr = bp->rptr; Myip[Myself] = ipparse((char *)ptr); @@ -370,7 +370,7 @@ ip_reassemble(int offset, Block *bp, Etherhdr *ip) ushort id; Block *bl, **l, *last, *prev; int ovlap, len, fragsize, pktposn; - int fend; + int end; /* Check ethrnet has handed us a contiguous buffer */ if(bp->next) @@ -453,10 +453,10 @@ ip_reassemble(int offset, Block *bp, Etherhdr *ip) /* Check to see if succeeding segments overlap */ if(bp->next) { l = &bp->next; - fend = BLKFRAG(bp)->foff + BLKFRAG(bp)->flen; + end = BLKFRAG(bp)->foff + BLKFRAG(bp)->flen; /* Take completely covered segements out */ while(*l){ - ovlap = fend - BLKFRAG(*l)->foff; + ovlap = end - BLKFRAG(*l)->foff; if(ovlap <= 0) break; fragstat.succ++; diff --git a/port/stlapd.c b/port/stlapd.c deleted file mode 100644 index 9b783b9fc51a9ec39888394512d6f6429aa3cd94..0000000000000000000000000000000000000000 --- a/port/stlapd.c +++ /dev/null @@ -1,813 +0,0 @@ -#include "u.h" -#include "lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "io.h" -#include "../port/error.h" - -#define DPRINT if(q->flag&QDEBUG)kprint - -typedef struct Lapd Lapd; - -#define NOW TK2MS(MACHP(0)->ticks) -#define T200 (NOW+2500) -#define SAPI(s, cr) (((s)<<2)|cr) -#define TEI(t) (((t)<<1)|1) - -/* - * Commands and responses - */ -enum -{ - RR = 0x01, /* Receiver Ready */ - RNR = 0x05, /* Receiver Not Ready */ - REJ = 0x09, /* Reject */ - SABME = 0x6f, /* Set Asynchronous Balanced Mode Extended */ - DM = 0x0f, /* Disconnect Mode */ - UI = 0x03, /* Unnumbered Information */ - DISC = 0x43, /* Disconnect */ - UA = 0x63, /* Unnumbered Acknowledgement */ - FRMR = 0x87, /* Frame Reject */ - XID = 0xaf, /* Exchange Identification */ - - /* C/R bits */ - UCmd = 0, /* command, user to network */ - UResp = 2, /* response, user to network */ - NCmd = 2, /* command, network to user */ - NResp = 0 /* response, network to user */ -}; - -enum States -{ - Unused = 0, - NoTEI, - WaitTEI, - TEIassigned, - WaitEst, - Multiframe, - WaitRel, -}; - -enum Flags -{ - Ownbusy = 0x01, - Peerbusy = 0x02, - Rejecting = 0x04, - Timeout = 0x08, - Hungup = 0x80 -}; - -#define SMASK 127 -#define NSEQ (SMASK+1) -#define THISS(i) ((i)&SMASK) -#define NEXTS(i) (((i)+1)&SMASK) - -#define OMASK 7 -#define NOBUF (OMASK+1) -#define THISO(i) ((i)&OMASK) -#define NEXTO(i) (((i)+1)&OMASK) - -#define RSTATE(lp) ((lp->flags&Ownbusy) ? RNR : \ - (lp->flags&Rejecting) ? REJ : RR) - -struct Lapd -{ - QLock; /* access, state change */ - Rendez; /* waiting for state change */ - int klocked;/* locked by kernel proc */ - int state; - int flags; - Queue * rq; - Queue * wq; - ushort refnum; - int tei; - int kout; /* maximum allowed number of outstanding I frames */ - int vs; /* send state variable (next seq. no. to send) */ - int va; /* acknowledge state variable (next expected ack) */ - int vr; /* receive state variable (next expected input) */ - Rendez tr; /* so transmit writer can wait */ - Block * outb[NOBUF]; /* transmitter circular buffer */ - int vt; /* input pointer for outb */ - int t200; - Rendez timer; - int kstarted; - int error; -}; - -enum { - LAPD_OK, - Address, - BadUA, - Badassign, - Badmanage, - Tooshort, - Unimpmanage, - Unkdlci, - Egates, -}; - -char *lapderrors[] = { - "LAPD OK", - "Address", - "BadUA", - "Badassign", - "Badmanage", - "Tooshort", - "Unimpmanage", - "Unkdlci", - "Egates", -}; - -Lapd *lapd; -Lapd *lapdN; - -/* - * predeclared - */ -static void assigntei(Lapd*); -static void dl_establish(Lapd*); -static void dl_release(Lapd*); -static void lapdreset(void); -static void lapdclose(Queue*); -static void lapdhangup(Lapd*); -static void lapdiput(Queue*, Block*); -static void lapdkproc(void*); -static void lapdopen(Queue*, Stream*); -static void lapdoput(Queue*, Block*); -static int lapdxmit(Lapd*); -static void mdl_assign(Lapd*); -static void mdl_iput(Queue*, Block*); -static int recvack(Lapd*, int); -static void sendctl(Lapd*, int, int, int); - -Qinfo lapdinfo = { lapdiput, lapdoput, lapdopen, lapdclose, "lapd", lapdreset }; - -#define Predicate(name, expr) static int name(void *arg) { return expr; } -#define lp ((Lapd *)arg) - -Predicate(pTEIassigned, lp->state == TEIassigned); -Predicate(pMultiframe, lp->state == Multiframe); - -Predicate(tEmpty, lp->vs == lp->va) -Predicate(tFull, NEXTO(lp->vt) == THISO(lp->va)) -Predicate(tNotFull, NEXTO(lp->vt) != THISO(lp->va)) - -#undef lp - -static void -lapderror(Lapd *lp, int code) -{ - lp->error = code; - nexterror(); -} - -static void -lapdreset(void) -{ - int nlapd = 3; /* formerly conf.nlapd */ - - lapd = xalloc(nlapd*sizeof(Lapd)); - lapdN = lapd + nlapd; -} - -static void -lapdopen(Queue *q, Stream *s) -{ - Lapd *lp; - char name[32]; - - USED(s); - for(lp=lapd; lpstate == 0) - break; - qunlock(lp); - } - if(lp>=lapdN) - error(Enoifc); - - /*q->flag |= QDEBUG; - q->other->flag |= QDEBUG;*/ - DPRINT("lapdopen: lapd %d\n", lp - lapd); - q->ptr = q->other->ptr = lp; - lp->rq = q; - lp->wq = q->other; - lp->state = NoTEI; - lp->flags = 0; - lp->kout = 1; - qunlock(lp); - sprint(name, "lapd%d", lp - lapd); - kproc(name, lapdkproc, lp); - DPRINT("lapdopen: mdl_assign\n"); - mdl_assign(lp); - DPRINT("lapdopen: dl_establish\n"); - dl_establish(lp); -} - -static void -mdl_assign(Lapd *lp) -{ - char buf[ERRLEN]; - - qlock(lp); - if(lp->state != NoTEI){ - qunlock(lp); - sprint(buf, "mdl_assign: state=%d", lp->state); - kprint("%s\n", buf); - error(buf); - } - lp->state = WaitTEI; - assigntei(lp); - lp->t200 = T200; - qunlock(lp); - sleep(lp, pTEIassigned, lp); - if(lp->state != TEIassigned){ - /*lapdclose(lp->rq);*/ - sprint(buf, "mdl_assign failed: state=%d", lp->state); - kprint("%s\n", buf); - error(buf); - } -} - -static void -assigntei(Lapd *lp) -{ - Queue *q = lp->rq; - Block *b = allocb(16); - uchar *p = b->wptr; - static ulong then; - ulong now; - - now = NOW; - if(now <= then) - now = then+1; - lp->refnum = now; - then = now; - *p++ = SAPI(63, UCmd); - *p++ = TEI(127); - *p++ = UI; - *p++ = 0x0f; - *p++ = lp->refnum>>8; - *p++ = lp->refnum; - *p++ = 0x01; - *p++ = 0xff; - b->wptr = p; - b->flags |= S_DELIM; - DPRINT("assigntei: refnum=0x%4.4ux\n", lp->refnum); - PUTNEXT(lp->wq, b); -} - -static void -dl_establish(Lapd *lp) -{ - char buf[ERRLEN]; - - qlock(lp); - if(lp->state != TEIassigned){ - qunlock(lp); - sprint(buf, "dl_establish: state=%d", lp->state); - kprint("%s\n", buf); - error(buf); - } - lp->state = WaitEst; - sendctl(lp, UCmd, SABME, 0); - lp->t200 = T200; - qunlock(lp); - sleep(lp, pMultiframe, lp); - if(lp->state != Multiframe){ - /*lapdclose(lp->rq);*/ - sprint(buf, "dl_establish failed: state=%d", lp->state); - kprint("%s\n", buf); - error(buf); - } -} - -static void -dl_release(Lapd *lp) -{ - char buf[ERRLEN]; - - qlock(lp); - if(lp->state != Multiframe){ - qunlock(lp); - sprint(buf, "dl_release: state=%d", lp->state); - kprint("%s\n", buf); - error(buf); - } - lp->state = WaitRel; - sendctl(lp, UCmd, DISC, 0); - lp->t200 = T200; - qunlock(lp); - tsleep(lp, pTEIassigned, lp, 30*1000); - qlock(lp); - if(lp->state > TEIassigned) - lp->state = TEIassigned; - qunlock(lp); -} - -static void -lapdclose(Queue *q) -{ - Lapd *lp = (Lapd *)q->ptr; - int i; - - if(lp == 0) - return; - - if(lp->state == Multiframe){ - for(i=0; itr, tEmpty, lp, 2500); /* drain */ - dl_release(lp); /* DISC to NT */ - } - for(i=0; ioutb[i]){ - freeb(lp->outb[i]); - lp->outb[i] = 0; - } - lp->flags |= Hungup; /* tell kernel proc */ - lp->t200 = NOW; - wakeup(&lp->timer); - for(i=0; i<10 && lp->kstarted; i++) - tsleep(lp, return0, 0, 500); - - lp->state = 0; -} - -/* - * upstream control messages - */ -static void -lapdctliput(Lapd *lp, Queue *q, Block *bp) -{ - switch(bp->type){ - case M_HANGUP: - lp->flags |= Hungup; - wakeup(lp); - break; - } - PUTNEXT(q, bp); -} - -void -lapdiput(Queue *q, Block *bp) -{ - Lapd *lp = (Lapd *)q->ptr; - int sapi, cr, tei, ctl, ns, nr = 0, pf; - uchar *start, *p; - - DPRINT("lapdiput: %d byte(s)\n", bp->wptr-bp->rptr); - qlock(lp); - lp->error = 0; - p = start = bp->rptr; - if (waserror()) { - qunlock(lp); - kprint("lapdiput: %s:", lapderrors[lp->error]); - for(p=start; pwptr; p++) - kprint(" %2.2ux", *p); - kprint("\n"); - freeb(bp); - return; - } - - if(bp->type != M_DATA){ - lapdctliput(lp, q, bp); - bp = 0; - goto out; - } - if (bp->wptr-p < 3) - lapderror(lp, Tooshort); - if ((p[0] & 0x01) || !(p[1] & 0x01)) - lapderror(lp, Address); - sapi = p[0] >> 2; - cr = p[0] & 0x02; - tei = p[1] >> 1; - ctl = p[2]; - if ((ctl&0x03) != 0x03) { - if (bp->wptr-p < 4) - lapderror(lp, Tooshort); - pf = p[3]&0x01; - nr = p[3]>>1; - p += 4; - } else { - pf = ctl&0x10; - ctl &= ~0x10; - p += 3; - } - bp->rptr = p; - DPRINT("lapdiput: cr=%d sapi=%d tei=%d ctl=0x%2.2x pf=%d\n", - cr, sapi, tei, ctl, pf); - if (cr==NCmd && tei==127 && ctl==UI) { - switch (sapi) { - case 0: - PUTNEXT(q, bp); - bp = 0; - break; - case 63: - mdl_iput(q, bp); - bp = 0; - break; - default: - lapderror(lp, Unkdlci); - break; - } - goto out; - } - if (sapi != 0 || lp->state < TEIassigned || tei != lp->tei) - lapderror(lp, Unkdlci); - if (!(ctl&0x01)) { /* Information */ - if (recvack(lp, nr)>0 && !(lp->flags&(Peerbusy|Timeout))) - lp->t200 = 0; - if (lp->flags&Ownbusy) { - if (pf) - sendctl(lp, cr, RNR, pf); - lapdxmit(lp); - goto out; - } - ns = ctl>>1; - if (ns != lp->vr) { - lp->flags |= Rejecting; - sendctl(lp, cr, REJ, pf); - lapdxmit(lp); - goto out; - } - PUTNEXT(q, bp); - bp = 0; - lp->flags &= ~Rejecting; - lp->vr = NEXTS(lp->vr); - if (QFULL(q->next)) - lp->flags |= Ownbusy; - if (pf || (lp->flags&Ownbusy)) { - sendctl(lp, cr, RSTATE(lp), pf); - lapdxmit(lp); - } else if (!lapdxmit(lp)) - sendctl(lp, cr, RR, pf); - goto out; - } - switch (ctl) { - case RR: - if (recvack(lp, nr)<0) - goto out; - lp->flags &= ~Peerbusy; - if (cr==NCmd && pf) - sendctl(lp, cr, RSTATE(lp), pf); - if (!(lp->flags&Timeout)) { - lp->t200 = 0; - if (cr==NResp && pf) - DPRINT("lapdiput: RR response with F==1\n"); - lapdxmit(lp); - } else if (cr==NResp && pf) { - lp->flags &= ~Timeout; - lp->vs = nr; - lp->t200 = 0; - lapdxmit(lp); - } - break; - case RNR: - if (recvack(lp, nr)<0) - goto out; - lp->flags |= Peerbusy; - if (cr==NCmd && pf) - sendctl(lp, cr, RSTATE(lp), pf); - if (!(lp->flags&Timeout)) { - lp->t200 = T200; - if (cr==NResp && pf) - DPRINT("lapdiput: RNR response with F==1\n"); - } else if (cr==NResp && pf) { - lp->flags &= ~Timeout; - lp->vs = nr; - lp->t200 = T200; - } - break; - case REJ: - if (recvack(lp, nr)<0) - goto out; - lp->flags &= ~Peerbusy; - if (cr==NCmd && pf) - sendctl(lp, cr, RSTATE(lp), pf); - if (!(lp->flags&Timeout)) { - lp->vs = nr; - lp->t200 = 0; - if (cr==NResp && pf) - DPRINT("lapdiput: REJ response with F==1\n"); - lapdxmit(lp); - } else if (cr==NResp && pf) { - lp->flags &= ~Timeout; - lp->vs = nr; - lp->t200 = 0; - lapdxmit(lp); - } - break; - case DM: - lp->state = TEIassigned; - lp->flags = 0; - lp->t200 = 0; - wakeup(lp); - break; - case UA: - if (lp->state == WaitEst) { - lp->state = Multiframe; - lp->flags = 0; - lp->vs = 0; - lp->va = 0; - lp->vr = 0; - lp->vt = 0; - lp->t200 = 0; - wakeup(lp); - } else if (lp->state == WaitRel) { - lp->state = TEIassigned; - lp->flags = 0; - lp->t200 = 0; - wakeup(lp); - } else - lapderror(lp, BadUA); - break; - case DISC: - lp->state = TEIassigned; - lp->flags = 0; - lp->t200 = 0; - sendctl(lp, UResp, UA, pf); - lapdhangup(lp); - break; - case SABME: - case UI: - case FRMR: - case XID: - lapderror(lp, Egates); - break; - } -out: - if (bp) - freeb(bp); - poperror(); - qunlock(lp); -} - -static void -mdl_iput(Queue *q, Block *bp) -{ - Lapd *lp = (Lapd *)q->ptr; - uchar *p = bp->rptr; - ushort refnum; - int ai; - - if (bp->wptr-p != 5 || p[0] != 0x0f || !(p[4]&0x01)) - lapderror(lp, Badmanage); - refnum = (p[1]<<8)|p[2]; - ai = p[4]>>1; - switch(p[3]){ - case 2: /* identity assigned */ - if(lp->state == WaitTEI && lp->refnum == refnum){ - lp->state = TEIassigned; - lp->tei = ai; - lp->t200 = 0; - DPRINT("assigned tei = %d\n", lp->tei); - wakeup(lp); - } - break; - case 3: /* identity denied */ - if(lp->state == WaitTEI && lp->refnum == refnum){ - lp->t200 = 0; - DPRINT("denied tei = %d\n", ai); - wakeup(lp); - } else - lapderror(lp, Badassign); - break; - case 4: /* identity check request */ - if(lp->state >= TEIassigned && (ai==127||ai==lp->tei)){ - Block *b = allocb(16); - uchar *p = b->wptr; - - *p++ = SAPI(63, UCmd); - *p++ = TEI(127); - *p++ = UI; - *p++ = 0x0f; - *p++ = NOW>>8; - *p++ = NOW; - *p++ = 0x05; - *p++ = (lp->tei<<1)|1; - b->wptr = p; - b->flags |= S_DELIM; - DPRINT("id check response: tei=%d\n", lp->tei); - PUTNEXT(lp->wq, b); - } - break; - case 6: /* identity removal */ - DPRINT("id removal: ai=%d\n", ai); - if(lp->state >= TEIassigned && (ai == lp->tei || ai == 127)){ - lp->state = NoTEI; - lapdhangup(lp); - } - break; - default: - lapdhangup(lp); - lapderror(lp, Unimpmanage); - break; - } - freeb(bp); -} - -static void -lapdhangup(Lapd *lp) -{ - Queue *q = lp->rq; - Block *bp; - - DPRINT("lapd hangup\n"); - bp = allocb(0); - bp->type = M_HANGUP; - PUTNEXT(q, bp); -} - -static int -recvack(Lapd *lp, int nr) -{ - Queue *q = lp->wq; - int i; - - for(i=lp->va; i!=lp->vs; i=NEXTS(i)){ - if(i==nr) - break; - } - if(i!=nr) { - DPRINT("lapd recvack: va,nr,vs = %d,%d,%d\n", - lp->va, nr, lp->vs); - return -1; - } - i = 0; - while (lp->va != nr) { - freeb(lp->outb[THISO(lp->va)]); - lp->outb[THISO(lp->va)] = 0; - lp->va = NEXTS(lp->va); - i++; - } - if (i > 0) - wakeup(&lp->tr); - return i; -} - -/* - * downstream control - */ -static void -lapdctloput(Lapd *lp, Queue *q, Block *bp) -{ - char *fields[2]; - - USED(lp); - switch(bp->type){ - case M_CTL: - if(streamparse("debug", bp)){ - switch(getfields((char *)bp->rptr, fields, 2, ' ')){ - case 1: - if (strcmp(fields[0], "on") == 0) { - q->flag |= QDEBUG; - q->other->flag |= QDEBUG; - } - if (strcmp(fields[0], "off") == 0) { - q->flag &= ~QDEBUG; - q->other->flag &= ~QDEBUG; - } - } - freeb(bp); - return; - } - } - PUTNEXT(q, bp); -} - -/* - * accept data from a writer - */ -static void -lapdoput(Queue *q, Block *bp) -{ - Lapd *lp = (Lapd *)q->ptr; - - if(bp->type != M_DATA){ - lapdctloput(lp, q, bp); - return; - } - if(!putq(q, bp)) /* send only whole messages */ - return; - DPRINT("lapdoput: len=%d\n", q->len); - if (tFull(lp)) - sleep(&lp->tr, tNotFull, lp); - qlock(lp); - if (waserror()) { - qunlock(lp); - nexterror(); - } - lp->outb[lp->vt] = grabq(q); - lp->vt = NEXTO(lp->vt); - - lapdxmit(lp); - poperror(); - qunlock(lp); -} - -static int -lapdxmit(Lapd *lp) -{ - Block *bp, *db; - int i; uchar *p; - - for (i=0;;i++) { - if (THISO(lp->vs) == lp->vt) /* buffer empty */ - break; - if (THISS(lp->va+lp->kout) == lp->vs) /* window full */ - break; - if (lp->flags & Peerbusy) /* flow-controlled */ - break; - bp = allocb(16); - p = bp->wptr; - *p++ = SAPI(0, UCmd); - *p++ = TEI(lp->tei); - *p++ = lp->vs<<1; - *p++ = lp->vr<<1; - bp->wptr = p; - PUTNEXT(lp->wq, bp); - for(bp=lp->outb[THISO(lp->vs)]; bp; bp=bp->next){ - db = allocb(0); - db->rptr = bp->rptr; - db->wptr = bp->wptr; - db->flags |= (bp->flags&S_DELIM); - PUTNEXT(lp->wq, db); - } - lp->vs = NEXTS(lp->vs); - lp->t200 = T200; - } - return i; -} - -/* - * send a control frame. - */ -static void -sendctl(Lapd *lp, int cmd, int ctl, int pf) -{ - Block *bp = allocb(16); - uchar *p = bp->wptr; - - *p++ = SAPI(0, cmd); - *p++ = TEI(lp->tei); - if (ctl & 0x02) { - *p++ = ctl|(pf?0x10:0); - } else { - *p++ = ctl; - *p++ = (lp->vr<<1)|(pf?0x01:0); - } - bp->wptr = p; - bp->flags |= S_DELIM; - PUTNEXT(lp->wq, bp); -} - -static void -lapdkproc(void *arg) -{ - Lapd *lp = (Lapd *)arg; - - lp->klocked = 0; - lp->kstarted = 1; - - if(waserror()){ - if(lp->klocked) - qunlock(lp); - lp->klocked = 0; - print("lapdkproc %d error\n", lp-lapd); - lp->kstarted = 0; - wakeup(lp); - return; - } - for(;;){ - tsleep(&lp->timer, return0, 0, 500); - if(!lp->t200 || NOW < lp->t200) - continue; - qlock(lp); - lp->klocked = 1; - if(lp->flags & Hungup){ - qunlock(lp); - lp->klocked = 0; - break; - } - switch(lp->state){ - case WaitTEI: - assigntei(lp); - lp->t200 = T200; - break; - case WaitEst: - sendctl(lp, UCmd, SABME, 0); - break; - case Multiframe: - sendctl(lp, UCmd, RSTATE(lp), 1); - lp->flags |= Timeout; - lp->t200 = T200; - break; - } - qunlock(lp); - lp->klocked = 0; - } - lp->kstarted = 0; - wakeup(lp); - poperror(); -} diff --git a/port/streboot.c b/port/streboot.c index a5cd6b9d5dc7675666100265ef4b9d866d89e153..536c60e822cb6bbd10e55d392635e1a722973336 100644 --- a/port/streboot.c +++ b/port/streboot.c @@ -27,7 +27,7 @@ rebootopen(Queue *q, Stream *s) { USED(q); USED(s); - if(strcmp(u->p->user, eve) != 0) + if(strcmp(up->user, eve) != 0) error(Eperm); } diff --git a/port/sturp.c b/port/sturp.c index 1630c6d0801981ab63a0945ab8b2b715a9542bb4..2ad25375e7d01f2224f264314601de01e14bdf76 100644 --- a/port/sturp.c +++ b/port/sturp.c @@ -147,7 +147,7 @@ urpreset(void) static void urpopen(Queue *q, Stream *s) { - Urp *up; + Urp *urp; USED(s); if(!urpkstarted){ @@ -162,33 +162,33 @@ urpopen(Queue *q, Stream *s) /* * find an unused urp structure */ - for(up = urpalloc.urp; up; up = up->list){ - if(up->state == 0){ - qlock(up); - if(up->state == 0) + for(urp = urpalloc.urp; urp; urp = urp->list){ + if(urp->state == 0){ + qlock(urp); + if(urp->state == 0) break; - qunlock(up); + qunlock(urp); } } - if(up == 0){ + if(urp == 0){ /* * none available, create a new one, they are never freed */ - up = smalloc(sizeof(Urp)); - qlock(up); + urp = smalloc(sizeof(Urp)); + qlock(urp); lock(&urpalloc); - up->list = urpalloc.urp; - urpalloc.urp = up; + urp->list = urpalloc.urp; + urpalloc.urp = urp; unlock(&urpalloc); } - q->ptr = q->other->ptr = up; + q->ptr = q->other->ptr = urp; q->rp = &urpkr; - up->rq = q; - up->wq = q->other; - up->state = OPEN; - qunlock(up); - initinput(up); - initoutput(up, 0); + urp->rq = q; + urp->wq = q->other; + urp->state = OPEN; + qunlock(urp); + initinput(urp); + initoutput(urp, 0); } /* @@ -197,19 +197,19 @@ urpopen(Queue *q, Stream *s) static int isflushed(void *a) { - Urp *up; + Urp *urp; - up = (Urp *)a; - return (up->state&HUNGUP) || (up->unechoed==up->nxb && up->wq->len==0); + urp = (Urp *)a; + return (urp->state&HUNGUP) || (urp->unechoed==urp->nxb && urp->wq->len==0); } static void urpclose(Queue *q) { - Urp *up; + Urp *urp; int i; - up = (Urp *)q->ptr; - if(up == 0) + urp = (Urp *)q->ptr; + if(urp == 0) return; /* @@ -218,50 +218,47 @@ urpclose(Queue *q) * * if 2 minutes elapse, give it up */ - up->state |= CLOSING; + urp->state |= CLOSING; if(!waserror()){ - tsleep(&up->r, isflushed, up, 2*60*1000); + tsleep(&urp->r, isflushed, urp, 2*60*1000); poperror(); } - up->state |= HUNGUP; + urp->state |= HUNGUP; - qlock(&up->xmit); + qlock(&urp->xmit); /* * ack all outstanding messages */ - i = up->next - 1; + i = urp->next - 1; if(i < 0) i = 7; - rcvack(up, ECHO+i); + rcvack(urp, ECHO+i); /* * free all staged but unsent messages */ - for(i = 0; i < 7; i++){ - qlock(&up->xl[i]); - if(up->xb[i]){ - freeb(up->xb[i]); - up->xb[i] = 0; + for(i = 0; i < 7; i++) + if(urp->xb[i]){ + freeb(urp->xb[i]); + urp->xb[i] = 0; } - qunlock(&up->xl[i]); - } - qunlock(&up->xmit); + qunlock(&urp->xmit); - qlock(up); - up->state = 0; - qunlock(up); + qlock(urp); + urp->state = 0; + qunlock(urp); } /* * upstream control messages */ static void -urpctliput(Urp *up, Queue *q, Block *bp) +urpctliput(Urp *urp, Queue *q, Block *bp) { switch(bp->type){ case M_HANGUP: - up->state |= HUNGUP; - wakeup(&up->r); + urp->state |= HUNGUP; + wakeup(&urp->r); break; } PUTNEXT(q, bp); @@ -275,15 +272,15 @@ urpctliput(Urp *up, Queue *q, Block *bp) void urpciput(Queue *q, Block *bp) { - Urp *up; + Urp *urp; int i; int ctl; - up = (Urp *)q->ptr; - if(up == 0) + urp = (Urp *)q->ptr; + if(urp == 0) return; if(bp->type != M_DATA){ - urpctliput(up, q, bp); + urpctliput(urp, q, bp); return; } @@ -313,34 +310,34 @@ urpciput(Queue *q, Block *bp) case ENQ: DPRINT("rENQ(c)\n"); urpstat.enqsr++; - sendctl(up, up->lastecho); - sendctl(up, ACK+up->iseq); + sendctl(urp, urp->lastecho); + sendctl(urp, ACK+urp->iseq); break; case CHECK: DPRINT("rCHECK(c)\n"); - sendctl(up, ACK+up->iseq); + sendctl(urp, ACK+urp->iseq); break; case AINIT: DPRINT("rAINIT(c)\n"); - up->state &= ~INITING; - flushinput(up); - tryoutput(up); + urp->state &= ~INITING; + flushinput(urp); + tryoutput(urp); break; case INIT0: case INIT1: DPRINT("rINIT%d(c)\n", ctl-INIT0); - sendctl(up, AINIT); + sendctl(urp, AINIT); if(ctl == INIT1) q->put = urpiput; - initinput(up); + initinput(urp); break; case INITREQ: DPRINT("rINITREQ(c)\n"); - initoutput(up, 0); + initoutput(urp, 0); break; case BREAK: @@ -349,7 +346,7 @@ urpciput(Queue *q, Block *bp) case REJ+0: case REJ+1: case REJ+2: case REJ+3: case REJ+4: case REJ+5: case REJ+6: case REJ+7: DPRINT("rREJ%d(c)\n", ctl-REJ); - rcvack(up, ctl); + rcvack(urp, ctl); break; case ACK+0: case ACK+1: case ACK+2: case ACK+3: @@ -357,18 +354,18 @@ urpciput(Queue *q, Block *bp) case ECHO+0: case ECHO+1: case ECHO+2: case ECHO+3: case ECHO+4: case ECHO+5: case ECHO+6: case ECHO+7: DPRINT("%s%d(c)\n", (ctl&ECHO)?"rECHO":"rACK", ctl&7); - rcvack(up, ctl); + rcvack(urp, ctl); break; case SEQ+0: case SEQ+1: case SEQ+2: case SEQ+3: case SEQ+4: case SEQ+5: case SEQ+6: case SEQ+7: DPRINT("rSEQ%d(c)\n", ctl-SEQ); - qlock(&up->ack); + qlock(&urp->ack); i = ctl & Nmask; if(!QFULL(q->next)) - sendctl(up, up->lastecho = ECHO+i); - up->iseq = i; - qunlock(&up->ack); + sendctl(urp, urp->lastecho = ECHO+i); + urp->iseq = i; + qunlock(&urp->ack); break; } } @@ -388,15 +385,15 @@ urpciput(Queue *q, Block *bp) void urpiput(Queue *q, Block *bp) { - Urp *up; + Urp *urp; int i, len; int ctl; - up = (Urp *)q->ptr; - if(up == 0) + urp = (Urp *)q->ptr; + if(urp == 0) return; if(bp->type != M_DATA){ - urpctliput(up, q, bp); + urpctliput(urp, q, bp); return; } @@ -408,16 +405,16 @@ urpiput(Queue *q, Block *bp) /* * take care of any block count(trx) */ - while(up->trx){ + while(urp->trx){ if(BLEN(bp)<=0) break; - switch (up->trx) { + switch (urp->trx) { case 1: case 2: - up->trbuf[up->trx++] = *bp->rptr++; + urp->trbuf[urp->trx++] = *bp->rptr++; continue; default: - up->trx = 0; + urp->trx = 0; break; } } @@ -429,7 +426,7 @@ urpiput(Queue *q, Block *bp) bp->flags &= ~S_DELIM; putq(q, bp); if(q->len > 4*1024){ - flushinput(up); + flushinput(urp); return; } } else @@ -442,38 +439,38 @@ urpiput(Queue *q, Block *bp) case 0: break; case ENQ: - DPRINT("rENQ %d %uo %uo\n", up->blocks, up->lastecho, ACK+up->iseq); - up->blocks = 0; + DPRINT("rENQ %d %uo %uo\n", urp->blocks, urp->lastecho, ACK+urp->iseq); + urp->blocks = 0; urpstat.enqsr++; - sendctl(up, up->lastecho); - sendctl(up, ACK+up->iseq); - flushinput(up); + sendctl(urp, urp->lastecho); + sendctl(urp, ACK+urp->iseq); + flushinput(urp); break; case CHECK: DPRINT("rCHECK\n"); - sendctl(up, ACK+up->iseq); + sendctl(urp, ACK+urp->iseq); break; case AINIT: DPRINT("rAINIT\n"); - up->state &= ~INITING; - flushinput(up); - tryoutput(up); + urp->state &= ~INITING; + flushinput(urp); + tryoutput(urp); break; case INIT0: case INIT1: DPRINT("rINIT%d\n", ctl-INIT0); - sendctl(up, AINIT); + sendctl(urp, AINIT); if(ctl == INIT0) q->put = urpciput; - initinput(up); + initinput(urp); break; case INITREQ: DPRINT("rINITREQ\n"); - initoutput(up, 0); + initoutput(urp, 0); break; case BREAK: @@ -483,14 +480,14 @@ urpiput(Queue *q, Block *bp) case BOTM: case BOTS: DPRINT("rBOT%c...", " MS"[ctl-BOT]); - up->trx = 1; - up->trbuf[0] = ctl; + urp->trx = 1; + urp->trbuf[0] = ctl; break; case REJ+0: case REJ+1: case REJ+2: case REJ+3: case REJ+4: case REJ+5: case REJ+6: case REJ+7: DPRINT("rREJ%d\n", ctl-REJ); - rcvack(up, ctl); + rcvack(urp, ctl); break; case ACK+0: case ACK+1: case ACK+2: case ACK+3: @@ -498,7 +495,7 @@ urpiput(Queue *q, Block *bp) case ECHO+0: case ECHO+1: case ECHO+2: case ECHO+3: case ECHO+4: case ECHO+5: case ECHO+6: case ECHO+7: DPRINT("%s%d\n", (ctl&ECHO)?"rECHO":"rACK", ctl&7); - rcvack(up, ctl); + rcvack(urp, ctl); break; /* @@ -509,26 +506,26 @@ urpiput(Queue *q, Block *bp) */ case SEQ+0: case SEQ+1: case SEQ+2: case SEQ+3: case SEQ+4: case SEQ+5: case SEQ+6: case SEQ+7: - len = up->trbuf[1] + (up->trbuf[2]<<8); - DPRINT("rSEQ%d(%d,%d,%d)...", ctl-SEQ, up->trx, len, q->len); + len = urp->trbuf[1] + (urp->trbuf[2]<<8); + DPRINT("rSEQ%d(%d,%d,%d)...", ctl-SEQ, urp->trx, len, q->len); i = ctl & Nmask; - if(up->trx != 3){ + if(urp->trx != 3){ urpstat.rjtrs++; - sendrej(up); + sendrej(urp); break; }else if(q->len != len){ urpstat.rjpks++; - sendrej(up); + sendrej(urp); break; - }else if(i != ((up->iseq+1)&Nmask)){ + }else if(i != ((urp->iseq+1)&Nmask)){ urpstat.rjseq++; - sendrej(up); + sendrej(urp); break; }else if(q->next->len > (3*Streamhi)/2 || q->next->nb > (3*Streambhi)/2){ DPRINT("next->len=%d, next->nb=%d\n", q->next->len, q->next->nb); - flushinput(up); + flushinput(urp); break; } DPRINT("accept %d\n", q->len); @@ -537,7 +534,7 @@ urpiput(Queue *q, Block *bp) * send data upstream */ if(q->first) { - if(up->trbuf[0] != BOTM) + if(urp->trbuf[0] != BOTM) q->last->flags |= S_DELIM; while(bp = getq(q)){ urpstat.input += BLEN(bp); @@ -545,20 +542,20 @@ urpiput(Queue *q, Block *bp) } } else { bp = allocb(0); - if(up->trbuf[0] != BOTM) + if(urp->trbuf[0] != BOTM) bp->flags |= S_DELIM; PUTNEXT(q, bp); } - up->trx = 0; + urp->trx = 0; /* * acknowledge receipt */ - qlock(&up->ack); - up->iseq = i; + qlock(&urp->ack); + urp->iseq = i; if(!QFULL(q->next)) - sendctl(up, up->lastecho = ECHO|i); - qunlock(&up->ack); + sendctl(urp, urp->lastecho = ECHO|i); + qunlock(&urp->ack); break; } } @@ -567,7 +564,7 @@ urpiput(Queue *q, Block *bp) * downstream control */ static void -urpctloput(Urp *up, Queue *q, Block *bp) +urpctloput(Urp *urp, Queue *q, Block *bp) { char *fields[2]; int outwin; @@ -583,12 +580,12 @@ urpctloput(Urp *up, Queue *q, Block *bp) bp->rptr = bp->wptr - 1; *bp->rptr = BREAK; putq(q, bp); - output(up); + output(urp); return; } if(streamparse("init", bp)){ outwin = strtoul((char*)bp->rptr, 0, 0); - initoutput(up, outwin); + initoutput(urp, outwin); freeb(bp); return; } @@ -617,37 +614,37 @@ urpctloput(Urp *up, Queue *q, Block *bp) static void urpoput(Queue *q, Block *bp) { - Urp *up; + Urp *urp; - up = (Urp *)q->ptr; + urp = (Urp *)q->ptr; if(bp->type != M_DATA){ - urpctloput(up, q, bp); + urpctloput(urp, q, bp); return; } urpstat.output += BLEN(bp); putq(q, bp); - output(up); + output(urp); } /* * start output */ static void -output(Urp *up) +output(Urp *urp) { Block *bp, *nbp; ulong now; Queue *q; int i; - if(!canqlock(&up->xmit)) + if(!canqlock(&urp->xmit)) return; if(waserror()){ print("urp output error\n"); - qunlock(&up->xmit); + qunlock(&urp->xmit); nexterror(); } @@ -655,12 +652,12 @@ output(Urp *up) * if still initing and it's time to rexmit, send an INIT1 */ now = NOW; - if(up->state & INITING){ - if(now > up->timer){ - q = up->wq; - DPRINT("INITING timer (%d, %d): ", now, up->timer); - sendctl(up, INIT1); - up->timer = now + MSrexmit; + if(urp->state & INITING){ + if(now > urp->timer){ + q = urp->wq; + DPRINT("INITING timer (%d, %d): ", now, urp->timer); + sendctl(urp, INIT1); + urp->timer = now + MSrexmit; } goto out; } @@ -668,21 +665,21 @@ output(Urp *up) /* * fill the transmit buffers, `nxb' can never overtake `unechoed' */ - q = up->wq; - i = NEXT(up->nxb); - if(i != up->unechoed) { - for(bp = getq(q); bp && i!=up->unechoed; i = NEXT(i)){ - if(up->xb[up->nxb] != 0) - urpvomit("output", up); - if(BLEN(bp) > up->maxblock){ - nbp = up->xb[up->nxb] = allocb(0); + q = urp->wq; + i = NEXT(urp->nxb); + if(i != urp->unechoed) { + for(bp = getq(q); bp && i!=urp->unechoed; i = NEXT(i)){ + if(urp->xb[urp->nxb] != 0) + urpvomit("output", urp); + if(BLEN(bp) > urp->maxblock){ + nbp = urp->xb[urp->nxb] = allocb(0); nbp->rptr = bp->rptr; - nbp->wptr = bp->rptr = bp->rptr + up->maxblock; + nbp->wptr = bp->rptr = bp->rptr + urp->maxblock; } else { - up->xb[up->nxb] = bp; + urp->xb[urp->nxb] = bp; bp = getq(q); } - up->nxb = i; + urp->nxb = i; } if(bp) putbq(q, bp); @@ -691,24 +688,24 @@ output(Urp *up) /* * retransmit cruft */ - if(up->rexmit){ + if(urp->rexmit){ /* * if a retransmit is requested, move next back to * the unacked blocks */ urpstat.rexmit++; - up->rexmit = 0; - up->next = up->unacked; - } else if(up->unechoed!=up->next && NOW>up->timer){ + urp->rexmit = 0; + urp->next = urp->unacked; + } else if(urp->unechoed!=urp->next && NOW>urp->timer){ /* * if a retransmit time has elapsed since a transmit, * send an ENQ */ - DPRINT("OUTPUT timer (%d, %d): ", NOW, up->timer); - up->timer = NOW + MSrexmit; - up->state &= ~REJECTING; + DPRINT("OUTPUT timer (%d, %d): ", NOW, urp->timer); + urp->timer = NOW + MSrexmit; + urp->state &= ~REJECTING; urpstat.enqsx++; - sendctl(up, ENQ); + sendctl(urp, ENQ); goto out; } @@ -718,20 +715,20 @@ output(Urp *up) * the lock is to synchronize with acknowledges that free * blocks. */ - while(WINDOW(up)>0 && up->next!=up->nxb){ - i = up->next; - qlock(&up->xl[i]); + while(WINDOW(urp)>0 && urp->next!=urp->nxb){ + i = urp->next; + qlock(&urp->xl[i]); if(waserror()){ - qunlock(&up->xl[i]); + qunlock(&urp->xl[i]); nexterror(); } - sendblock(up, i); - qunlock(&up->xl[i]); - up->next = NEXT(up->next); + sendblock(urp, i); + qunlock(&urp->xl[i]); + urp->next = NEXT(urp->next); poperror(); } out: - qunlock(&up->xmit); + qunlock(&urp->xmit); poperror(); } @@ -739,10 +736,10 @@ out: * try output, this is called by an input process */ void -tryoutput(Urp *up) +tryoutput(Urp *urp) { if(!waserror()){ - output(up); + output(urp); poperror(); } } @@ -752,12 +749,12 @@ tryoutput(Urp *up) * space in case a lower layer needs header room. */ static void -sendctl(Urp *up, int ctl) +sendctl(Urp *urp, int ctl) { Block *bp; Queue *q; - q = up->wq; + q = urp->wq; if(QFULL(q->next)) return; bp = allocb(1); @@ -773,68 +770,68 @@ sendctl(Urp *up, int ctl) * send a reject */ static void -sendrej(Urp *up) +sendrej(Urp *urp) { - Queue *q = up->wq; - flushinput(up); - qlock(&up->ack); - if((up->lastecho&~Nmask) == ECHO){ - DPRINT("REJ %d\n", up->iseq); - sendctl(up, up->lastecho = REJ|up->iseq); + Queue *q = urp->wq; + flushinput(urp); + qlock(&urp->ack); + if((urp->lastecho&~Nmask) == ECHO){ + DPRINT("REJ %d\n", urp->iseq); + sendctl(urp, urp->lastecho = REJ|urp->iseq); } - qunlock(&up->ack); + qunlock(&urp->ack); } /* * send an acknowledge */ static void -sendack(Urp *up) +sendack(Urp *urp) { /* * check the precondition for acking */ - if(QFULL(up->rq->next) || (up->lastecho&Nmask)==up->iseq) + if(QFULL(urp->rq->next) || (urp->lastecho&Nmask)==urp->iseq) return; - if(!canqlock(&up->ack)) + if(!canqlock(&urp->ack)) return; /* * check again now that we've locked */ - if(QFULL(up->rq->next) || (up->lastecho&Nmask)==up->iseq){ - qunlock(&up->ack); + if(QFULL(urp->rq->next) || (urp->lastecho&Nmask)==urp->iseq){ + qunlock(&urp->ack); return; } /* * send the ack */ - { Queue *q = up->wq; DPRINT("sendack: "); } - sendctl(up, up->lastecho = ECHO|up->iseq); - qunlock(&up->ack); + { Queue *q = urp->wq; DPRINT("sendack: "); } + sendctl(urp, urp->lastecho = ECHO|urp->iseq); + qunlock(&urp->ack); } /* * send a block. */ static void -sendblock(Urp *up, int bn) +sendblock(Urp *urp, int bn) { - Block *bp, *m, *nbp; int n; Queue *q; + Block *bp, *m, *nbp; - q = up->wq; - up->timer = NOW + MSrexmit; + q = urp->wq; + urp->timer = NOW + MSrexmit; if(QFULL(q->next)) return; /* * message 1, the BOT and the data */ - bp = up->xb[bn]; + bp = urp->xb[bn]; if(bp == 0) return; m = allocb(1); @@ -865,17 +862,17 @@ sendblock(Urp *up, int bn) n = BLEN(bp); m->rptr[0] = SEQ | bn; m->rptr[1] = n; - m->rptr[2] = n>>8; + m->rptr[2] = n<<8; m->flags |= S_DELIM; PUTNEXT(q, m); - DPRINT("sb %d (%d)\n", bn, up->timer); + DPRINT("sb %d (%d)\n", bn, urp->timer); } /* * receive an acknowledgement */ static void -rcvack(Urp *up, int msg) +rcvack(Urp *urp, int msg) { int seqno; int next; @@ -887,31 +884,33 @@ rcvack(Urp *up, int msg) /* * release any acknowledged blocks */ - if(IN(seqno, up->unacked, up->next)){ - for(; up->unacked != next; up->unacked = NEXT(up->unacked)){ - i = up->unacked; - qlock(&up->xl[i]); - if(up->xb[i]) - freeb(up->xb[i]); - up->xb[i] = 0; - qunlock(&up->xl[i]); + if(IN(seqno, urp->unacked, urp->next)){ + for(; urp->unacked != next; urp->unacked = NEXT(urp->unacked)){ + i = urp->unacked; + qlock(&urp->xl[i]); + if(urp->xb[i]) + freeb(urp->xb[i]); + else + urpvomit("rcvack", urp); + urp->xb[i] = 0; + qunlock(&urp->xl[i]); } } switch(msg & 0370){ case ECHO: - if(IN(seqno, up->unechoed, up->next)) { - up->unechoed = next; + if(IN(seqno, urp->unechoed, urp->next)) { + urp->unechoed = next; } /* * the next reject at the start of a window starts a * retransmission. */ - up->state &= ~REJECTING; + urp->state &= ~REJECTING; break; case REJ: - if(IN(seqno, up->unechoed, up->next)) - up->unechoed = next; + if(IN(seqno, urp->unechoed, urp->next)) + urp->unechoed = next; /* * ... FALL THROUGH ... */ @@ -920,97 +919,97 @@ rcvack(Urp *up, int msg) * start a retransmission if we aren't retransmitting * and this is the start of a window. */ - if(up->unechoed==next && !(up->state & REJECTING)){ - up->state |= REJECTING; - up->rexmit = 1; + if(urp->unechoed==next && !(urp->state & REJECTING)){ + urp->state |= REJECTING; + urp->rexmit = 1; } break; } - tryoutput(up); - if(up->state & CLOSING) - wakeup(&up->r); + tryoutput(urp); + if(urp->state & CLOSING) + wakeup(&urp->r); } /* * throw away any partially collected input */ static void -flushinput(Urp *up) +flushinput(Urp *urp) { Block *bp; - while (bp = getq(up->rq)) + while (bp = getq(urp->rq)) freeb(bp); - up->trx = 0; + urp->trx = 0; } /* * initialize output */ static void -initoutput(Urp *up, int window) +initoutput(Urp *urp, int window) { int i; /* * set output window */ - up->maxblock = window/4; - if(up->maxblock < 64) - up->maxblock = 64; - up->maxblock -= 4; - up->maxout = 4; + urp->maxblock = window/4; + if(urp->maxblock < 64) + urp->maxblock = 64; + urp->maxblock -= 4; + urp->maxout = 4; /* * set sequence varialbles */ - up->unechoed = 1; - up->unacked = 1; - up->next = 1; - up->nxb = 1; - up->rexmit = 0; + urp->unechoed = 1; + urp->unacked = 1; + urp->next = 1; + urp->nxb = 1; + urp->rexmit = 0; /* * free any outstanding blocks */ for(i = 0; i < 8; i++){ - qlock(&up->xl[i]); - if(up->xb[i]) - freeb(up->xb[i]); - up->xb[i] = 0; - qunlock(&up->xl[i]); + qlock(&urp->xl[i]); + if(urp->xb[i]) + freeb(urp->xb[i]); + urp->xb[i] = 0; + qunlock(&urp->xl[i]); } /* * tell the other side we've inited */ - up->state |= INITING; - up->timer = NOW + MSrexmit; - { Queue *q = up->wq; DPRINT("initoutput (%d): ", up->timer); } - sendctl(up, INIT1); + urp->state |= INITING; + urp->timer = NOW + MSrexmit; + { Queue *q = urp->wq; DPRINT("initoutput (%d): ", urp->timer); } + sendctl(urp, INIT1); } /* * initialize input */ static void -initinput(Urp *up) +initinput(Urp *urp) { /* * restart all sequence parameters */ - up->blocks = 0; - up->trx = 0; - up->iseq = 0; - up->lastecho = ECHO+0; - flushinput(up); + urp->blocks = 0; + urp->trx = 0; + urp->iseq = 0; + urp->lastecho = ECHO+0; + flushinput(urp); } static void urpkproc(void *arg) { - Urp *up; + Urp *urp; USED(arg); @@ -1018,24 +1017,24 @@ urpkproc(void *arg) ; for(;;){ - for(up = urpalloc.urp; up; up = up->list){ - if(up->state==0 || (up->state&HUNGUP)) + for(urp = urpalloc.urp; urp; urp = urp->list){ + if(urp->state==0 || (urp->state&HUNGUP)) continue; - if(!canqlock(up)) + if(!canqlock(urp)) continue; if(waserror()){ - qunlock(up); + qunlock(urp); continue; } - if(up->state==0 || (up->state&HUNGUP)){ - qunlock(up); + if(urp->state==0 || (urp->state&HUNGUP)){ + qunlock(urp); poperror(); continue; } - if(up->iseq!=(up->lastecho&7) && !QFULL(up->rq->next)) - sendack(up); - output(up); - qunlock(up); + if(urp->iseq!=(urp->lastecho&7) && !QFULL(urp->rq->next)) + sendack(urp); + output(urp); + qunlock(urp); poperror(); } tsleep(&urpkr, return0, 0, 500); @@ -1046,18 +1045,18 @@ urpkproc(void *arg) * urp got very confused, complain */ static void -urpvomit(char *msg, Urp* up) +urpvomit(char *msg, Urp* urp) { print("urpvomit: %s %ux next %d unechoed %d unacked %d nxb %d\n", - msg, up, up->next, up->unechoed, up->unacked, up->nxb); + msg, urp, urp->next, urp->unechoed, urp->unacked, urp->nxb); print("\txb: %ux %ux %ux %ux %ux %ux %ux %ux\n", - up->xb[0], up->xb[1], up->xb[2], up->xb[3], up->xb[4], - up->xb[5], up->xb[6], up->xb[7]); + urp->xb[0], urp->xb[1], urp->xb[2], urp->xb[3], urp->xb[4], + urp->xb[5], urp->xb[6], urp->xb[7]); print("\tiseq: %uo lastecho: %uo trx: %d trbuf: %uo %uo %uo\n", - up->iseq, up->lastecho, up->trx, up->trbuf[0], up->trbuf[1], - up->trbuf[2]); - print("\tupq: %ux %d %d\n", &up->rq->next->r, up->rq->next->nb, - up->rq->next->len); + urp->iseq, urp->lastecho, urp->trx, urp->trbuf[0], urp->trbuf[1], + urp->trbuf[2]); + print("\tupq: %ux %d %d\n", &urp->rq->next->r, urp->rq->next->nb, + urp->rq->next->len); } void diff --git a/port/swap.c b/port/swap.c index 269d8544b39c54aa0f133cc4030dc742ba638e58..0b84f2980f153b969486b1ed20484340b34a08f0 100644 --- a/port/swap.c +++ b/port/swap.c @@ -106,7 +106,7 @@ pager(void *junk) ep = &p[conf.nproc]; loop: - u->p->psstate = "Idle"; + up->psstate = "Idle"; sleep(&swapalloc.r, needpages, 0); for(;;) { @@ -133,10 +133,10 @@ loop: case SG_BSS: case SG_STACK: case SG_SHARED: - u->p->psstate = "Pageout"; + up->psstate = "Pageout"; pageout(p, s); if(ioptr != 0) { - u->p->psstate = "I/O"; + up->psstate = "I/O"; executeio(); } } diff --git a/port/sysfile.c b/port/sysfile.c index 86c5cfb6c2f4ea1b0376c5e8e0d053b6221293c6..4bd1db99fc4a79ed42dcf6c133ad313c4ff0723c 100644 --- a/port/sysfile.c +++ b/port/sysfile.c @@ -12,7 +12,7 @@ int newfd(Chan *c) { - Fgrp *f = u->p->fgrp; + Fgrp *f = up->fgrp; int i; lock(f); @@ -36,7 +36,7 @@ fdtochan(int fd, int mode, int chkmnt, int iref) Fgrp *f; c = 0; - f = u->p->fgrp; + f = up->fgrp; lock(f); if(fd<0 || NFD<=fd || (c = f->fd[fd])==0) { @@ -90,12 +90,12 @@ syspipe(ulong *arg) int fd[2]; Chan *c[2]; Dev *d; - Fgrp *f = u->p->fgrp; + Fgrp *f = up->fgrp; validaddr(arg[0], 2*BY2WD, 1); evenaddr(arg[0]); d = &devtab[devno('|', 0)]; - c[0] = (*d->attach)(0); + c[0] = namec("#|", Atodir, 0, 0); c[1] = 0; fd[0] = -1; fd[1] = -1; @@ -109,9 +109,9 @@ syspipe(ulong *arg) f->fd[fd[1]]=0; nexterror(); } - c[1] = (*d->clone)(c[0], 0); - (*d->walk)(c[0], "data"); - (*d->walk)(c[1], "data1"); + c[1] = clone(c[0], 0); + walk(c[0], "data", 1); + walk(c[1], "data1", 1); c[0] = (*d->open)(c[0], ORDWR); c[1] = (*d->open)(c[1], ORDWR); fd[0] = newfd(c[0]); @@ -127,7 +127,7 @@ sysdup(ulong *arg) { int fd; Chan *c, *oc; - Fgrp *f = u->p->fgrp; + Fgrp *f = up->fgrp; /* * Close after dup'ing, so date > #d/1 works @@ -184,7 +184,7 @@ fdclose(int fd, int flag) { int i; Chan *c; - Fgrp *f = u->p->fgrp; + Fgrp *f = up->fgrp; lock(f); c = f->fd[fd]; @@ -224,7 +224,7 @@ unionread(Chan *c, void *va, long n) Chan *nc; Pgrp *pg; - pg = u->p->pgrp; + pg = up->pgrp; rlock(&pg->ns); for(;;) { @@ -419,30 +419,34 @@ syschdir(ulong *arg) Chan *c; validaddr(arg[0], 1, 0); + c = namec((char*)arg[0], Atodir, 0, 0); - close(u->dot); - u->dot = c; + close(up->dot); + up->dot = c; return 0; } long bindmount(ulong *arg, int ismount) { - Chan *c0, *c1, *bc; ulong flag; - long ret; - int fd; + int fd, ret; + Chan *c0, *c1, *bc; struct{ Chan *chan; char *spec; + char recov; }bogus; flag = arg[2]; fd = arg[0]; if(flag>MMASK || (flag&MORDER)==(MBEFORE|MAFTER)) error(Ebadarg); + + bogus.recov = flag&MRECOV; + if(ismount){ - bc = fdtochan(fd, 2, 0, 1); + bc = fdtochan(fd, ORDWR, 0, 1); if(waserror()) { close(bc); nexterror(); @@ -462,24 +466,25 @@ bindmount(ulong *arg, int ismount) close(bc); } else { + bogus.spec = 0; validaddr(arg[0], 1, 0); c0 = namec((char*)arg[0], Aaccess, 0, 0); } + if(waserror()){ close(c0); nexterror(); } + validaddr(arg[1], 1, 0); c1 = namec((char*)arg[1], Amount, 0, 0); if(waserror()){ close(c1); nexterror(); } - if((c0->qid.path^c1->qid.path) & CHDIR) - error(Emount); - if(flag && !(c0->qid.path&CHDIR)) - error(Emount); - ret = mount(c0, c1, flag); + + ret = mount(c0, c1, flag, bogus.spec); + poperror(); close(c1); poperror(); diff --git a/port/sysproc.c b/port/sysproc.c index 9359e40cc674e06dab790f34186c1ae7dc69133c..05794fcbc156e21ddc99d2b21022256539afb921 100644 --- a/port/sysproc.c +++ b/port/sysproc.c @@ -12,62 +12,58 @@ int shargs(char*, int, char**); long sysr1(ulong *arg) { - xsummary(); - print("[%s %s %d] r1 = %d\n", u->p->user, u->p->text, u->p->pid, arg[0]); + Chan *c; + + c = fdtochan(arg[0], -1, 0, 0); + ptpath(c->path, (char*)arg[1], arg[2]); return 0; } long sysrfork(ulong *arg) { - KMap *k; + Proc *p; + int n, i; Pgrp *opg; Egrp *oeg; Fgrp *ofg; - int n, i; - Proc *p, *parent; - ulong upa, pid, flag; - /* - * used to compute last valid system stack address for copy - */ - int lastvar; + ulong pid, flag; flag = arg[0]; - p = u->p; if((flag&RFPROC) == 0) { if(flag & (RFNAMEG|RFCNAMEG)) { if((flag & (RFNAMEG|RFCNAMEG)) == (RFNAMEG|RFCNAMEG)) error(Ebadarg); - opg = p->pgrp; - p->pgrp = newpgrp(); + opg = up->pgrp; + up->pgrp = newpgrp(); if(flag & RFNAMEG) - pgrpcpy(p->pgrp, opg); + pgrpcpy(up->pgrp, opg); closepgrp(opg); } if(flag & (RFENVG|RFCENVG)) { if((flag & (RFENVG|RFCENVG)) == (RFENVG|RFCENVG)) error(Ebadarg); - oeg = p->egrp; - p->egrp = smalloc(sizeof(Egrp)); - p->egrp->ref = 1; + oeg = up->egrp; + up->egrp = smalloc(sizeof(Egrp)); + up->egrp->ref = 1; if(flag & RFENVG) - envcpy(p->egrp, oeg); + envcpy(up->egrp, oeg); closeegrp(oeg); } if(flag & RFFDG) { - ofg = p->fgrp; - p->fgrp = dupfgrp(ofg); + ofg = up->fgrp; + up->fgrp = dupfgrp(ofg); closefgrp(ofg); } else if(flag & RFCFDG) { - ofg = p->fgrp; - p->fgrp = smalloc(sizeof(Fgrp)); - p->fgrp->ref = 1; + ofg = up->fgrp; + up->fgrp = smalloc(sizeof(Fgrp)); + up->fgrp->ref = 1; closefgrp(ofg); } if(flag & RFNOTEG) - p->noteid = incref(¬eidalloc); + up->noteid = incref(¬eidalloc); if(flag & (RFMEM|RFNOWAIT)) error(Ebadarg); return 0; @@ -81,41 +77,40 @@ sysrfork(ulong *arg) error(Ebadarg); p = newproc(); - parent = u->p; - /* Page va of upage used as check in mapstack */ - p->upage = newpage(0, 0, USERADDR|(p->pid&0xFFFF)); - k = kmap(p->upage); - upa = VA(k); - - /* Save time: only copy u-> data and useful stack */ - memmove((void*)upa, u, sizeof(User)); - n = USERADDR+BY2PG - (ulong)&lastvar; - n = (n+32) & ~(BY2WD-1); - memmove((void*)(upa+BY2PG-n), (void*)(USERADDR+BY2PG-n), n); - ((User *)upa)->p = p; - kunmap(k); + p->fpsave = up->fpsave; + p->scallnr = up->scallnr; + p->s = up->s; + p->nerrlab = 0; + p->slash = up->slash; + p->dot = up->dot; + incref(p->dot); + + memmove(p->note, up->note, sizeof(p->note)); + p->nnote = up->nnote; + p->notified = 0; + p->lastnote = up->lastnote; + p->notify = up->notify; + p->ureg = 0; + p->dbgreg = 0; /* Make a new set of memory segments */ n = flag & RFMEM; for(i = 0; i < NSEG; i++) - if(parent->seg[i]) - p->seg[i] = dupseg(parent->seg, i, n); - - /* Refs */ - incref(u->dot); + if(up->seg[i]) + p->seg[i] = dupseg(up->seg, i, n); /* File descriptors */ if(flag & (RFFDG|RFCFDG)) { if(flag & RFFDG) - p->fgrp = dupfgrp(parent->fgrp); + p->fgrp = dupfgrp(up->fgrp); else { p->fgrp = smalloc(sizeof(Fgrp)); p->fgrp->ref = 1; } } else { - p->fgrp = parent->fgrp; + p->fgrp = up->fgrp; incref(p->fgrp); } @@ -123,10 +118,10 @@ sysrfork(ulong *arg) if(flag & (RFNAMEG|RFCNAMEG)) { p->pgrp = newpgrp(); if(flag & RFNAMEG) - pgrpcpy(p->pgrp, parent->pgrp); + pgrpcpy(p->pgrp, up->pgrp); } else { - p->pgrp = parent->pgrp; + p->pgrp = up->pgrp; incref(p->pgrp); } @@ -135,47 +130,39 @@ sysrfork(ulong *arg) p->egrp = smalloc(sizeof(Egrp)); p->egrp->ref = 1; if(flag & RFENVG) - envcpy(p->egrp, parent->egrp); + envcpy(p->egrp, up->egrp); } else { - p->egrp = parent->egrp; + p->egrp = up->egrp; incref(p->egrp); } - p->hang = parent->hang; - p->procmode = parent->procmode; - - if(setlabel(&p->sched)){ - /* - * use u->p instead of p, because we don't trust the compiler, after a - * gotolabel, to find the correct contents of a local variable. - */ - p = u->p; - p->state = Running; - p->mach = m; - m->proc = p; - spllo(); - return 0; - } + p->hang = up->hang; + p->procmode = up->procmode; - p->parent = parent; - p->parentpid = parent->pid; + /* Craft a return frame which will cause the child to pop out of + * the scheduler in user mode with the return register zero + */ + forkchild(p, up->dbgreg); + + p->parent = up; + p->parentpid = up->pid; if(flag&RFNOWAIT) p->parentpid = 1; else { - lock(&parent->exl); - parent->nchild++; - unlock(&parent->exl); + lock(&up->exl); + up->nchild++; + unlock(&up->exl); } if((flag&RFNOTEG) == 0) - p->noteid = parent->noteid; + p->noteid = up->noteid; - p->fpstate = parent->fpstate; + p->fpstate = up->fpstate; pid = p->pid; memset(p->time, 0, sizeof(p->time)); p->time[TReal] = MACHP(0)->ticks; - memmove(p->text, parent->text, NAMELEN); - memmove(p->user, parent->user, NAMELEN); + memmove(p->text, up->text, NAMELEN); + memmove(p->user, up->user, NAMELEN); /* * since the bss/data segments are now shareable, * any mmu info about this process is now stale @@ -198,7 +185,6 @@ l2be(long l) long sysexec(ulong *arg) { - Proc *p; Segment *s, *ts; ulong t, d, b; int i; @@ -214,7 +200,6 @@ sysexec(ulong *arg) Image *img; ulong magic, text, entry, data, bss; - p = u->p; validaddr(arg[0], 1, 0); file = (char*)arg[0]; indir = 0; @@ -225,7 +210,7 @@ sysexec(ulong *arg) nexterror(); } if(!indir) - strcpy(elem, u->elem); + strcpy(elem, up->elem); n = (*devtab[tc->type].read)(tc, &exec, sizeof(Exec), 0); if(n < 2) @@ -315,7 +300,7 @@ sysexec(ulong *arg) if(spage > TSTKSIZ) error(Enovmem); - p->seg[ESEG] = newseg(SG_STACK, TSTKTOP-USTKSIZE, USTKSIZE/BY2PG); + up->seg[ESEG] = newseg(SG_STACK, TSTKTOP-USTKSIZE, USTKSIZE/BY2PG); /* * Args: pass 2: assemble; the pages will be faulted in @@ -338,7 +323,7 @@ sysexec(ulong *arg) charp += n; } - memmove(p->text, elem, NAMELEN); + memmove(up->text, elem, NAMELEN); /* * Committed. @@ -346,14 +331,14 @@ sysexec(ulong *arg) * Special segments are maintained accross exec */ for(i = SSEG; i <= BSEG; i++) { - putseg(p->seg[i]); - p->seg[i] = 0; /* prevent a second free if we have an error */ + putseg(up->seg[i]); + up->seg[i] = 0; /* prevent a second free if we have an error */ } /* * Close on exec */ - f = u->p->fgrp; + f = up->fgrp; for(i=0; i<=f->maxfd; i++) fdclose(i, CCEXEC); @@ -361,7 +346,7 @@ sysexec(ulong *arg) /* attachimage returns a locked cache image */ img = attachimage(SG_TEXT|SG_RONLY, tc, UTZERO, (t-UTZERO)>>PGSHIFT); ts = img->s; - p->seg[TSEG] = ts; + up->seg[TSEG] = ts; ts->flushme = 1; ts->fstart = 0; ts->flen = sizeof(Exec)+text; @@ -369,7 +354,7 @@ sysexec(ulong *arg) /* Data. Shared. */ s = newseg(SG_DATA, t, (d-t)>>PGSHIFT); - p->seg[DSEG] = s; + up->seg[DSEG] = s; /* Attached by hand */ incref(img); @@ -378,14 +363,14 @@ sysexec(ulong *arg) s->flen = data; /* BSS. Zero fill on demand */ - p->seg[BSEG] = newseg(SG_BSS, d, (b-d)>>PGSHIFT); + up->seg[BSEG] = newseg(SG_BSS, d, (b-d)>>PGSHIFT); /* * Move the stack */ - s = p->seg[ESEG]; - p->seg[ESEG] = 0; - p->seg[SSEG] = s; + s = up->seg[ESEG]; + up->seg[ESEG] = 0; + up->seg[SSEG] = s; s->base = USTKTOP-USTKSIZE; s->top = USTKTOP; relocateseg(s, TSTKTOP-USTKTOP); @@ -397,14 +382,14 @@ sysexec(ulong *arg) * space and needs to be flushed */ flushmmu(); - qlock(&p->debug); - u->nnote = 0; - u->notify = 0; - u->notified = 0; - procsetup(p); - qunlock(&p->debug); - if(p->hang) - p->procctl = Proc_stopme; + qlock(&up->debug); + up->nnote = 0; + up->notify = 0; + up->notified = 0; + procsetup(up); + qunlock(&up->debug); + if(up->hang) + up->procctl = Proc_stopme; return execregs(entry, ssize, nargs); } @@ -422,7 +407,7 @@ shargs(char *s, int n, char **ap) s[i] = 0; *ap = 0; i = 0; - for(;;){ + for(;;) { while(*s==' ' || *s=='\t') s++; if(*s == 0) @@ -453,7 +438,7 @@ syssleep(ulong *arg) if(arg[0] == 0) sched(); else - tsleep(&u->p->sleep, return0, 0, arg[0]); + tsleep(&up->sleep, return0, 0, arg[0]); return 0; } @@ -508,12 +493,13 @@ sysdeath(ulong *arg) long syserrstr(ulong *arg) { - char tmp[ERRLEN]; + char *e, tmp[ERRLEN]; validaddr(arg[0], ERRLEN, 1); - memmove(tmp, (char*)arg[0], ERRLEN); - memmove((char*)arg[0], u->error, ERRLEN); - memmove(u->error, tmp, ERRLEN); + e = (char*)arg[0]; + memmove(tmp, e, ERRLEN); + memmove(e, up->error, ERRLEN); + memmove(up->error, tmp, ERRLEN); return 0; } @@ -523,7 +509,7 @@ sysnotify(ulong *arg) USED(arg); if(arg[0] != 0) validaddr(arg[0], sizeof(ulong), 0); - u->notify = (int(*)(void*, char*))(arg[0]); + up->notify = (int(*)(void*, char*))(arg[0]); return 0; } @@ -531,7 +517,7 @@ long sysnoted(ulong *arg) { USED(arg); - if(u->notified == 0) + if(up->notified == 0) error(Egreg); return 0; } @@ -539,21 +525,23 @@ sysnoted(ulong *arg) long syssegbrk(ulong *arg) { - Segment *s; int i; + ulong addr; + Segment *s; - for(i = 0; i < NSEG; i++) - if(s = u->p->seg[i]) { - if(arg[0] >= s->base && arg[0] < s->top) { - switch(s->type&SG_TYPE) { - case SG_TEXT: - case SG_DATA: - error(Ebadarg); - default: - return ibrk(arg[1], i); - } - } + addr = arg[0]; + for(i = 0; i < NSEG; i++) { + s = up->seg[i]; + if(s == 0 || addr < s->base || addr >= s->top) + continue; + switch(s->type&SG_TYPE) { + case SG_TEXT: + case SG_DATA: + error(Ebadarg); + default: + return ibrk(arg[1], i); } + } error(Ebadarg); return 0; /* not reached */ @@ -562,21 +550,23 @@ syssegbrk(ulong *arg) long syssegattach(ulong *arg) { - return segattach(u->p, arg[0], (char*)arg[1], arg[2], arg[3]); + return segattach(up, arg[0], (char*)arg[1], arg[2], arg[3]); } long syssegdetach(ulong *arg) { int i; + ulong addr; Segment *s; s = 0; + addr = arg[0]; for(i = 0; i < NSEG; i++) - if(s = u->p->seg[i]) { + if(s = up->seg[i]) { qlock(&s->lk); - if((arg[0] >= s->base && arg[0] < s->top) || - (s->top == s->base && arg[0] == s->base)) + if((addr >= s->base && addr < s->top) || + (s->top == s->base && addr == s->base)) goto found; qunlock(&s->lk); } @@ -584,11 +574,12 @@ syssegdetach(ulong *arg) error(Ebadarg); found: + /* Check we are not detaching the current stack segment */ if((ulong)arg >= s->base && (ulong)arg < s->top) { qunlock(&s->lk); error(Ebadarg); } - u->p->seg[i] = 0; + up->seg[i] = 0; qunlock(&s->lk); putseg(s); @@ -604,7 +595,7 @@ syssegfree(ulong *arg) ulong from, pages; from = PGROUND(arg[0]); - s = seg(u->p, from, 1); + s = seg(up, from, 1); if(s == 0) error(Ebadarg); @@ -637,9 +628,9 @@ sysrendezvous(ulong *arg) ulong val; tag = arg[0]; - l = &REND(u->p->pgrp, tag); + l = &REND(up->pgrp, tag); - lock(u->p->pgrp); + lock(up->pgrp); for(p = *l; p; p = p->rendhash) { if(p->rendtag == tag) { *l = p->rendhash; @@ -649,24 +640,23 @@ sysrendezvous(ulong *arg) while(p->state != Rendezvous) ; ready(p); - unlock(u->p->pgrp); + unlock(up->pgrp); return val; } l = &p->rendhash; } /* Going to sleep here */ - p = u->p; - p->rendtag = tag; - p->rendval = arg[1]; - p->rendhash = *l; - *l = p; + up->rendtag = tag; + up->rendval = arg[1]; + up->rendhash = *l; + *l = up; s = splhi(); - unlock(p->pgrp); - u->p->state = Rendezvous; + unlock(up->pgrp); + up->state = Rendezvous; sched(); splx(s); - return u->p->rendval; + return up->rendval; } diff --git a/port/taslock.c b/port/taslock.c index fae34ae1e4f329b30f3873fb6b7ae66d2c175b28..83e0f8d7bcb27b5e75a83a139a216d5bc1b6f567 100644 --- a/port/taslock.c +++ b/port/taslock.c @@ -15,8 +15,6 @@ lock(Lock *l) for(i = 0; i < 10000000; i++){ if (tas(&l->key) == 0){ - if(u) - u->p->hasspin = 1; l->pc = pc; return; } @@ -32,8 +30,6 @@ canlock(Lock *l) if(tas(&l->key)) return 0; l->pc = getcallerpc(((uchar*)&l) - sizeof(l)); - if(u && u->p) - u->p->hasspin = 1; return 1; } @@ -42,6 +38,4 @@ unlock(Lock *l) { l->pc = 0; l->key = 0; - if(u && u->p) - u->p->hasspin = 0; } diff --git a/port/tcpinput.c b/port/tcpinput.c index 898572ebf15199b3d19b7471371cb21e3ac5cf95..8ccfa69af86ca86b932659cfb93b697a6a9b3036 100644 --- a/port/tcpinput.c +++ b/port/tcpinput.c @@ -84,8 +84,7 @@ tcpflushincoming(Ipconv *s) seg.dest = s->psrc; seg.flags = ACK; seg.seq = tcb->snd.ptr; - tcb->last_ack = tcb->rcv.nxt; - seg.ack = tcb->rcv.nxt; + seg.ack = tcb->last_ack = tcb->rcv.nxt; sndrst(s->dst, Myip[Myself], 0, &seg); localclose(s, 0); @@ -308,10 +307,6 @@ tcpinput(Ipifc *ifc, Block *bp) goto output; } - /* - * keep looping till we've processed this packet plus any - * adjacent packets in the resequence queue - */ for(;;) { if(seg.flags & RST) { if(tcb->state == Syn_received @@ -414,12 +409,10 @@ tcpinput(Ipifc *ifc, Block *bp) tcprcvwin(s); - if(tcb->acktimer.state != TimerON) - tcpgo(&tcb->acktimer); + tcpgo(&tcb->acktimer); - if(tcb->rcv.nxt-tcb->last_ack > Streamhi/2) + if(tcb->max_snd <= tcb->rcv.nxt-tcb->last_ack) tcb->flags |= FORCE; - break; case Finwait2: /* no process to read the data, send a reset */ @@ -465,22 +458,16 @@ tcpinput(Ipifc *ifc, Block *bp) } } - /* - * get next adjacent segment from the requence queue. - * dump/trim any overlapping segments - */ - for(;;) { - if(tcb->reseq == 0) - goto output; - + while(tcb->reseq) { if(seq_ge(tcb->rcv.nxt, tcb->reseq->seg.seq) == 0) - goto output; + break; get_reseq(tcb, &tos, &seg, &bp, &length); if(trim(tcb, &seg, &bp, &length) == 0) break; } + break; } output: tcpoutput(s); @@ -582,7 +569,7 @@ update(Ipconv *s, Tcp *seg) int in_window(Tcpctl *tcb, int seq) { - return seq_within(seq, tcb->rcv.nxt, tcb->rcv.nxt+tcb->rcv.wnd-1); + return seq_within(seq, tcb->rcv.nxt, (int)(tcb->rcv.nxt+tcb->rcv.wnd-1)); } void @@ -707,8 +694,8 @@ trim(Tcpctl *tcb, Tcp *seg, Block **bp, ushort *length) accept++; else if(len != 0) { - if(in_window(tcb, seg->seq+len-1) || - seq_within(tcb->rcv.nxt, seg->seq,seg->seq+len-1)) + if(in_window(tcb, (int)(seg->seq+len-1)) || + seq_within(tcb->rcv.nxt, seg->seq,(int)(seg->seq+len-1))) accept++; } } @@ -874,7 +861,7 @@ localclose(Ipconv *s, char reason[]) } int -seq_within(ulong x, ulong low, ulong high) +seq_within(int x, int low, int high) { if(low <= high){ if(low <= x && x <= high) @@ -888,27 +875,27 @@ seq_within(ulong x, ulong low, ulong high) } int -seq_lt(ulong x, ulong y) +seq_lt(int x, int y) { - return x < y; + return (long)(x-y) < 0; } int -seq_le(ulong x, ulong y) +seq_le(int x, int y) { - return x <= y; + return (long)(x-y) <= 0; } int -seq_gt(ulong x, ulong y) +seq_gt(int x, int y) { - return x > y; + return (long)(x-y) > 0; } int -seq_ge(ulong x, ulong y) +seq_ge(int x, int y) { - return x >= y; + return (long)(x-y) >= 0; } void diff --git a/port/tcpoutput.c b/port/tcpoutput.c index 44a125c18e831062982e7f78660a48711796d065..bbb1f7ee60ef5fcb87b5451289f506914e517077 100644 --- a/port/tcpoutput.c +++ b/port/tcpoutput.c @@ -46,9 +46,10 @@ tcpoutput(Ipconv *s) */ if(tcb->snd.wnd == 0){ if(sent != 0) { - if ((tcb->flags&FORCE) == 0) + if (tcb->flags&FORCE) + tcb->snd.ptr = tcb->snd.una; + else break; - tcb->snd.ptr = tcb->snd.una; } usable = 1; } @@ -91,9 +92,8 @@ tcpoutput(Ipconv *s) } break; } - tcb->last_ack = tcb->rcv.nxt; seg.seq = tcb->snd.ptr; - seg.ack = tcb->rcv.nxt; + seg.ack = tcb->last_ack = tcb->rcv.nxt; seg.wnd = tcb->rcv.wnd; /* Pull out data to send */ @@ -112,7 +112,7 @@ tcpoutput(Ipconv *s) /* * keep track of balance of resent data */ if(tcb->snd.ptr < tcb->snd.nxt) - tcb->resent += MIN(tcb->snd.nxt - tcb->snd.ptr,(int)ssize); + tcb->resent += MIN((int)tcb->snd.nxt - (int)tcb->snd.ptr,(int)ssize); tcb->snd.ptr += ssize; @@ -184,7 +184,6 @@ tcptimeout(void *arg) default: tcb->backoff++; if (tcb->backoff >= MAXBACKOFF && tcb->snd.wnd > 0) { -print("tcp connection timed out\n"); localclose(s, Etimedout); break; } diff --git a/power/clock.c b/power/clock.c index 9801620ebebf7264ea2bd90d0f75b6b39a09d63f..53d06f4d2218be1fa3a484feb46aa717217a103c 100644 --- a/power/clock.c +++ b/power/clock.c @@ -12,7 +12,7 @@ delay(int ms) { int i; - ms *= 7000; /* experimentally determined */ + ms *= 7000; /* experimentally determined */ for(i=0; iticks = 0; } - - void clock(Ureg *ur) { - int i, nrun = 0; Proc *p; + int i, nrun; - if(ur->cause & INTR2){ - i = *CLRTIM0; - USED(i); - m->ticks++; - if(m->ticks&(1<<4)) - LEDON(LEDpulse); - else - LEDOFF(LEDpulse); - if(m->proc) - m->proc->pc = ur->pc; - - if(m->machno == 0){ - p = m->proc; - if(p) { - nrun++; - p->time[p->insyscall]++; - } - for(i=1; iproc; - if(p) { - p->time[p->insyscall]++; - nrun++; - } - } - } - nrun = (nrdy+nrun)*1000; - m->load = (m->load*19+nrun)/20; + if((ur->cause&INTR2) == 0) { + if(ur->cause & INTR4) { + i = *CLRTIM1; + USED(i); } - duartslave(); - if((active.machs&(1<machno)) == 0) - return; - if(active.exiting && active.machs&(1<machno)){ - print("someone's exiting\n"); - exit(0); + return; + } + nrun = 0; + i = *CLRTIM0; + USED(i); + + m->ticks++; + if(m->proc) + m->proc->pc = ur->pc; + + if(m->machno == 0) { + p = m->proc; + if(p) { + nrun++; + p->time[p->insyscall]++; } - checkalarms(); - kproftimer(ur->pc); - if(u && (ur->status&IEP) && u->p->state==Running){ - if(anyready()) { - if(u->p->hasspin) - u->p->hasspin = 0; /* just in case */ - else - sched(); + for(i=1; iproc; + if(p) { + p->time[p->insyscall]++; + nrun++; + } } - /* user profiling clock */ - if(ur->status & KUP) - (*(ulong*)(USTKTOP-BY2WD)) += TK2MS(1); } + nrun = (nrdy+nrun)*1000; + m->load = (m->load*19+nrun)/20; + } + duartslave(); + if((active.machs&(1<machno)) == 0) return; + + if(active.exiting && active.machs&(1<machno)) { + print("someone's exiting\n"); + exit(0); } - if(ur->cause & INTR4){ - extern ulong start; - i = *CLRTIM1; - USED(i); + checkalarms(); + kproftimer(ur->pc); + + if(up == 0 || (ur->status&IEP) == 0 || up->state != Running) return; - } + + if(anyready()) + sched(); + + /* user profiling clock */ + if(ur->status & KUP) + (*(ulong*)(USTKTOP-BY2WD)) += TK2MS(1); } diff --git a/power/conf.h b/power/conf.h index c367b599ea88bf6ed77eedd3af51719ad4a594c6..6153f757ada7064914fbbcde5bc951dcd55ed379 100644 --- a/power/conf.h +++ b/power/conf.h @@ -10,6 +10,10 @@ Conftab conftab[] = { {"base0", &conf.base0 }, {"base1", &conf.base1 }, {"copymode", &conf.copymode }, + {"ipif", &conf.ipif }, + {"ip", &conf.ip }, + {"arp", &conf.arp }, + {"frag", &conf.frag }, {"debugger", &conf.debugger }, { 0, 0 }, }; diff --git a/power/dat.h b/power/dat.h index 6614d21bee2f0ebcc8002376734ccab8a3bdbdbb..9158d571c141dbb53e7f1f33be6494e30e4c4a1b 100644 --- a/power/dat.h +++ b/power/dat.h @@ -10,8 +10,6 @@ typedef struct MMU MMU; typedef struct PMMU PMMU; typedef struct Softtlb Softtlb; typedef struct Ureg Ureg; -typedef struct User User; - /* * parameters for sysproc.c */ @@ -46,6 +44,10 @@ struct Conf ulong base0; /* base of bank 0 */ ulong base1; /* base of bank 1 */ ulong copymode; /* 0 is copy on write, 1 is copy on reference */ + ulong ipif; /* Ip protocol interfaces */ + ulong ip; /* Ip conversations per interface */ + ulong arp; /* Arp table size */ + ulong frag; /* Ip fragment assemble queue size */ ulong debugger; /* use processor 1 as a kernel debugger */ }; @@ -71,6 +73,14 @@ struct FPsave struct PMMU { int pidonmach[MAXMACH]; + /* + * I/O point for hotrod interfaces. + * This is the easiest way to allocate + * them, but not the prettiest or most general. + */ + Cycmsg *kcyc; + Cycmsg *ucyc; + Cycmsg *fcyc; }; #include "../port/portdat.h" @@ -83,19 +93,21 @@ struct Cycmsg uchar intr; /* flag: interrupt has occurred */ }; +/* First FOUR members offsets known by l.s */ struct Mach { - int machno; /* physical id of processor NB. MUST BE FIRST */ - Softtlb *stb; /* Software tlb simulation NB. MUST BE SECOND */ + int machno; /* physical id of processor */ + Softtlb *stb; /* Software tlb simulation */ + Proc *proc; /* current process on this processor */ ulong splpc; /* pc that called splhi() */ + /* Ok to change from here */ ulong ticks; /* of the clock since boot time */ - Proc *proc; /* current process on this processor */ Label sched; /* scheduler wakeup */ Lock alarmlock; /* access to alarm list */ void *alarm; /* alarms bound to this clock */ char pidhere[NTLBPID]; /* is this pid possibly in this mmu? */ int lastpid; /* last pid allocated on this machine */ - Proc *pidproc[NTLBPID]; /* process that owns this tlbpid on this mach */ + Proc *pidproc[NTLBPID]; /* tlb allocation table */ Page *ufreeme; /* address of upage of exited process */ Ureg *ur; @@ -169,45 +181,5 @@ struct #define MACHP(n) ((Mach *)(MACHADDR+n*BY2PG)) -#define NERR 15 -#define NNOTE 5 -struct User -{ - Proc *p; - FPsave fpsave; /* address of this is known by db */ - int scallnr; /* sys call number - known by db */ - Sargs s; /* address of this is known by db */ - int nerrlab; - Label errlab[NERR]; - char error[ERRLEN]; - char elem[NAMELEN]; /* last name element from namec */ - Chan *slash; - Chan *dot; - /* - * Rest of structure controlled by devproc.c and friends. - * qlock(&p->debug) to modify. - */ - Note note[NNOTE]; - short nnote; - short notified; /* sysnoted is due */ - Note lastnote; - int (*notify)(void*, char*); - void *ureg; /* User registers for notes */ - void *dbgreg; /* User registers for debugging in proc */ - ulong svstatus; - ulong svr1; - /* - * machine dependent User stuff - */ - /* - * I/O point for hotrod interfaces. - * This is the easiest way to allocate - * them, but not the prettiest or most general. - */ - Cycmsg kcyc; - Cycmsg ucyc; - Cycmsg fcyc; -}; - extern register Mach *m; -extern register User *u; +extern register Proc *up; diff --git a/power/devcyc.c b/power/devcyc.c index 1636b779b34e1ac042548a26f97c7cb237fd2b8f..46204b9ce2e68bb00f8c6dcd5f89486345aa234f 100644 --- a/power/devcyc.c +++ b/power/devcyc.c @@ -7,7 +7,7 @@ #include "devtab.h" #include "io.h" -#include "../../fs/cyc/comm.h" +#include "/sys/src/fs/cyc/comm.h" typedef struct Commcyc Commcyc; @@ -171,9 +171,9 @@ cycopen(Chan *c, int omode) */ cp->wi = 0; cp->ri = 0; - mp = &u->kcyc; + mp = up->kcyc; mp->cmd = Ureset; - cmp = cycsend(cp, &((User*)(u->p->upage->pa|KZERO))->kcyc); + cmp = cycsend(cp, up->kcyc); cycwait(cmp); delay(100); print("reset\n"); @@ -199,8 +199,8 @@ cycclose(Chan *c) cp = &cyclone[c->dev]; if(c->qid.path != CHDIR){ - u->kcyc.cmd = Ureboot; - cmp = cycsend(cp, &((User*)(u->p->upage->pa|KZERO))->kcyc); + up->kcyc->cmd = Ureboot; + cmp = cycsend(cp, up->kcyc); cycwait(cmp); unlock(&cp->busy); } @@ -221,10 +221,9 @@ cycmsgintr(Cycmsg *hm) long cycread(Chan *c, void *buf, long n, ulong offset) { - User *pu; + ulong l, m; Commcyc *cp; Cycmsg *mp, **cmp; - ulong l, m; USED(offset); cp = &cyclone[c->dev]; @@ -237,13 +236,12 @@ cycread(Chan *c, void *buf, long n, ulong offset) print("cyclone bufsize %d %d\n", n, sizeof cp->buf); error(Egreg); } - pu = (User*)(u->p->upage->pa|KZERO); if((((ulong)buf)&(KSEGM|3)) == KSEG0){ /* * use supplied buffer, no need to lock for reply */ - mp = &pu->kcyc; + mp = up->kcyc; mp->cmd = Uread; mp->param[0] = MP2VME(buf); mp->param[1] = n; @@ -267,7 +265,7 @@ cycread(Chan *c, void *buf, long n, ulong offset) /* * use cyclone buffer. lock the buffer until the reply */ - mp = &pu->ucyc; + mp = up->ucyc; qlock(&cp->buflock); mp->cmd = Uread; mp->param[0] = MP2VME(cp->buf); @@ -281,6 +279,7 @@ cycread(Chan *c, void *buf, long n, ulong offset) do m = mp->param[3]; while(m==0 && --l>0); + if(m==0 || m>n){ print("devcyc: count %ld %ld\n", m, n); qunlock(&cp->buflock); @@ -299,7 +298,6 @@ cycread(Chan *c, void *buf, long n, ulong offset) long cycwrite(Chan *c, void *buf, long n, ulong offset) { - User *pu; Commcyc *cp; Cycmsg *mp, **cmp; @@ -314,12 +312,11 @@ cycwrite(Chan *c, void *buf, long n, ulong offset) print("cyclone write bufsize\n"); error(Egreg); } - pu = (User*)(u->p->upage->pa|KZERO); if((((ulong)buf)&(KSEGM|3)) == KSEG0){ /* * use supplied buffer, no need to lock for reply */ - mp = &pu->kcyc; + mp = up->kcyc; mp->cmd = Uwrite; mp->param[0] = MP2VME(buf); @@ -332,7 +329,7 @@ cycwrite(Chan *c, void *buf, long n, ulong offset) /* * use cyclone buffer. lock the buffer until the reply */ - mp = &pu->ucyc; + mp = up->ucyc; qlock(&cp->buflock); memmove(cp->buf, buf, n); diff --git a/power/devduart.c b/power/devduart.c index 355694a4070ad817ebe81c3dee1f2963e26e2422..9885085fac0b3b0d13aa3df2231f88684eb14140 100644 --- a/power/devduart.c +++ b/power/devduart.c @@ -447,14 +447,13 @@ duartrawputs(char *s) for(i=0; i < 1000000; i++) ; } + void iprint(char *fmt, ...) { - char buf[1024]; - long *arg; + char buf[512]; - arg = (long*)(&fmt+1); - sprint(buf, fmt, *arg, *(arg+1), *(arg+2), *(arg+3)); + doprint(buf, buf+sizeof(buf), fmt, (&fmt+1)); duartrawputs(buf); } diff --git a/power/devrtc.c b/power/devrtc.c index bdda527dd3be2f50142369a8e331905a507839e2..4dabd680f1ddba46ed8e9bd71b01099804b83c8e 100644 --- a/power/devrtc.c +++ b/power/devrtc.c @@ -100,11 +100,11 @@ rtcopen(Chan *c, int omode) omode = openmode(omode); switch(c->qid.path){ case Qrtc: - if(strcmp(u->p->user, eve)!=0 && omode!=OREAD) + if(strcmp(up->user, eve)!=0 && omode!=OREAD) error(Eperm); break; case Qnvram: - if(strcmp(u->p->user, eve)!=0 || !cpuserver) + if(strcmp(up->user, eve)!=0 || !cpuserver) error(Eperm); } return devopen(c, omode, rtcdir, NRTC, devgen); diff --git a/power/faultmips.c b/power/faultmips.c index 6f73f71d84d07a3a60771434c72b94249f7f74e2..6b1d0f9225e431c7864807f426ed4afd682d09b1 100644 --- a/power/faultmips.c +++ b/power/faultmips.c @@ -14,32 +14,30 @@ void faultmips(Ureg *ur, int user, int code) { + int read; ulong addr; extern char *excname[]; - char buf[ERRLEN]; - int read; + char *p, buf[ERRLEN]; - LEDON(LEDfault); addr = ur->badvaddr; - if((addr & KZERO) && (0xffff0000 & addr) != USERADDR) - LEDON(LEDkfault); addr &= ~(BY2PG-1); read = !(code==CTLBM || code==CTLBS); - if(fault(addr, read) < 0){ - if(user){ - sprint(buf, "sys: trap: fault %s addr=0x%lux", - read? "read" : "write", ur->badvaddr); - postnote(u->p, 1, buf, NDebug); - LEDOFF(LEDfault); - return; - } - print("kernel %s badvaddr=0x%lux\n", excname[code], ur->badvaddr); - print("status=0x%lux pc=0x%lux sp=0x%lux\n", ur->status, ur->pc, ur->sp); - dumpregs(ur); - panic("fault"); + if(fault(addr, read) == 0) + return; + + if(user) { + p = "store"; + if(read) + p = "load"; + sprint(buf, "sys: trap: fault %s addr=0x%lux", p, ur->badvaddr); + postnote(up, 1, buf, NDebug); + return; } - LEDOFF(LEDfault|LEDkfault); + print("kernel %s vaddr=0x%lux\n", excname[code], ur->badvaddr); + print("status=0x%lux pc=0x%lux sp=0x%lux\n", ur->status, ur->pc, ur->sp); + dumpregs(ur); + panic("fault"); } /* @@ -49,7 +47,7 @@ void evenaddr(ulong addr) { if(addr & 3){ - postnote(u->p, 1, "sys: odd address", NDebug); + postnote(up, 1, "sys: odd address", NDebug); error(Ebadarg); } } diff --git a/power/fns.h b/power/fns.h index 89e7d7f3aac398e5a38fdfa52a99a28194ff04e9..56f9fd08f81c4da416b0c224f5224b920a507829 100644 --- a/power/fns.h +++ b/power/fns.h @@ -39,7 +39,6 @@ void lanceparity(void); void lancesetup(Lance*); void launchinit(void); void launch(int); -#define mmunewpage(x) int muxlock(int*, int*); void newstart(void); int newtlbpid(Proc*); @@ -52,6 +51,7 @@ void printslave(void); #define procsave(p) #define procrestore(p) void purgetlb(int); +void putcontext(int); void putstlb(ulong, ulong); void putstrn(char*, long); void puttlb(ulong, ulong); @@ -74,7 +74,9 @@ void vector0(void); void vector80(void); void vmereset(void); void wbflush(void); -#define waserror() setlabel(&u->errlab[u->nerrlab++]) +#define waserror() setlabel(&up->errlab[up->nerrlab++]) #define kmapperm(x) kmap(x) #define KADDR(a) ((void*)((ulong)(a)|KZERO)) #define PADDR(a) ((ulong)(a)&~KZERO) +Page* lkpage(Segment*, ulong); +void lkpgfree(Page*); diff --git a/power/fptrap.c b/power/fptrap.c index 6d37dbee0756f0188f75ffe956b863619926cde4..bdf9ea7daff2e5270b5f3a4ddaa9a50ce8a2db18 100644 --- a/power/fptrap.c +++ b/power/fptrap.c @@ -22,34 +22,28 @@ enum /* op */ }; static int fpunimp(ulong); -static ulong branch(Ureg*, ulong, ulong); +static ulong branch(Ureg*, ulong); void fptrap(Ureg *ur) { - ulong iw, iw_4, npc; - static int counter; + ulong iw, npc; - if((u->fpsave.fpstatus&(1<<17)) == 0) + if((up->fpsave.fpstatus&(1<<17)) == 0) return; -if((counter&0xff) == 0) +print("fpt: %d %s %lux\n", up->pid, up->text, up->fpsave.fpstatus); - if(tlbp(ur->pc) == 0) - panic("not in tlb %lux\n", ur->pc); - iw = *(ulong*)ur->pc; - iw_4 = iw; - if(ur->cause & (1<<31)){ - if(tlbp(ur->pc+4) == 0) - panic("not in tlb %lux\n", ur->pc+4); + if(ur->cause & (1<<31)) iw = *(ulong*)(ur->pc+4); - } + else + iw = *(ulong*)ur->pc; if(fpunimp(iw) == 0) return; if(ur->cause & (1<<31)){ - npc = branch(ur, iw_4, u->fpsave.fpstatus); + npc = branch(ur, up->fpsave.fpstatus); if(npc == 0) return; ur->pc = npc; @@ -57,7 +51,7 @@ if((counter&0xff) == 0) else ur->pc += 4; - u->fpsave.fpstatus &= ~(1<<17); + up->fpsave.fpstatus = up->fpsave.fpstatus & ~(1<<17); } static void @@ -115,8 +109,8 @@ fpunimp(ulong iw) ft = (iw>>16) & ((1<<5)-1); fs = (iw>>11) & ((1<<5)-1); fd = (iw>>6) & ((1<<5)-1); - unpack(&u->fpsave, fmt, fs, &ss, &es); - unpack(&u->fpsave, fmt, ft, &st, &et); + unpack(&up->fpsave, fmt, fs, &ss, &es); + unpack(&up->fpsave, fmt, ft, &st, &et); ed = 0; maxe = 0; maxm = 0; @@ -132,11 +126,11 @@ fpunimp(ulong iw) } switch(op){ case ABS: - u->fpsave.fpreg[fd] &= ~0x80000000; + up->fpsave.fpreg[fd] &= ~0x80000000; return 1; case NEG: - u->fpsave.fpreg[fd] ^= 0x80000000; + up->fpsave.fpreg[fd] ^= 0x80000000; return 1; case SUB: @@ -171,10 +165,10 @@ fpunimp(ulong iw) default: /* probably a compare */ return 0; } - if(ed <= -(maxe-5)){ /* guess: underflow */ - zeroreg(&u->fpsave, fmt, fd, sd); + if(ed <= -(maxe-4)){ /* guess: underflow */ + zeroreg(&up->fpsave, fmt, fd, sd); /* Set underflow exception and sticky */ - u->fpsave.fpstatus |= (1<<3)|(1<<13); + up->fpsave.fpstatus |= (1<<3)|(1<<13); return 1; } return 0; @@ -194,10 +188,11 @@ reg(Ureg *ur, int regno) } static ulong -branch(Ureg *ur, ulong iw, ulong fcr31) +branch(Ureg *ur, ulong fcr31) { - ulong npc, rs, rt, rd, offset; + ulong iw, npc, rs, rt, rd, offset; + iw = *(ulong*)ur->pc; rs = (iw>>21) & 0x1F; if(rs) rs = *reg(ur, rs); diff --git a/power/io.h b/power/io.h index 407ee88a811891dfcf7acf3af270f53a9aeb4186..c49c4b93d1b912915fce542a6993ddc310e98f40 100644 --- a/power/io.h +++ b/power/io.h @@ -10,15 +10,17 @@ enum { LEDtrapmask= 0xf<<0, - LED2= 1<<2, - LED3= 1<<3, LEDkfault= 1<<4, - LED5= 1<<5, + LEDclock= 1<<5, LEDfault= 1<<6, LEDpulse= 1<<7, }; +/* #define LEDON(x) (m->ledval &= ~(x), *LED = m->ledval) #define LEDOFF(x) (m->ledval |= (x), *LED = m->ledval) +*/ +#define LEDON(x) +#define LEDOFF(x) typedef struct SBCC SBCC; typedef struct Timer Timer; diff --git a/power/l.s b/power/l.s index a653eeaeeb7c92caf6418cb3fe4faad41bead426..749937c8cbb2228cf0d751a11b88375a65ccb164 100644 --- a/power/l.s +++ b/power/l.s @@ -99,7 +99,7 @@ TEXT firmware(SB), $0 TEXT splhi(SB), $0 - MOVW R31, 8(R(MACH)) /* save PC in m->splpc */ + MOVW R31, 0xC(R(MACH)) /* save PC in m->splpc */ MOVW M(STATUS), R1 AND $~IEC, R1, R2 MOVW R2, M(STATUS) @@ -108,7 +108,7 @@ TEXT splhi(SB), $0 TEXT splx(SB), $0 - MOVW R31, 8(R(MACH)) /* save PC in m->splpc */ + MOVW R31, 0xC(R(MACH)) /* save PC in m->splpc */ MOVW M(STATUS), R2 AND $IEC, R1 AND $~IEC, R2 @@ -128,12 +128,11 @@ TEXT spllo(SB), $0 TEXT muxlock(SB),$0 MOVW R1, R2 /* sbsem */ - MOVW 4(FP), R3 /* &lk->val */ + MOVW 4(FP), R3 /* lk->val */ MOVW M(STATUS), R5 /* splhi */ AND $~IEC, R5, R4 MOVW R4, M(STATUS) - NOOP MOVW 0(R2),R4 /* grab sbsem */ AND $1, R4 @@ -183,18 +182,22 @@ TEXT getcallerpc(SB), $0 TEXT gotopc(SB), $8 - MOVW R1, 0(FP) - MOVW $(64*1024), R1 - MOVW R1, 8(SP) - MOVW R0, R1 + MOVW R1, 0(FP) /* save arguments for later */ + MOVW $(64*1024), R7 + MOVW R7, 8(SP) JAL icflush(SB) - MOVW 0(FP), R1 - + MOVW 0(FP), R7 MOVW _argc(SB), R4 MOVW _argv(SB), R5 MOVW _env(SB), R6 MOVW R0, 4(SP) - JMP (R1) + JMP (R7) + +TEXT putcontext(SB), $4 + + SLL $6, R1 + MOVW R1, M(TLBVIRT) + RET TEXT puttlb(SB), $4 @@ -229,19 +232,9 @@ TEXT puttlbx(SB), $0 RET TEXT tlbp(SB), $0 - MOVW M(TLBVIRT), R2 - AND $(~(BY2PG-1)), R1, R4 /* get the VPN */ - AND $((NTLBPID-1)<<6), R2 /* get the pid */ - OR R4, R2 - MOVW R2, M(TLBVIRT) - NOOP TLBP NOOP - MOVW M(INDEX), R2 - MOVW R0, R1 - BLTZ R2, bad - MOVW $1, R1 -bad: + MOVW M(INDEX), R1 RET TEXT tlbvirt(SB), $0 @@ -252,7 +245,6 @@ TEXT tlbvirt(SB), $0 TEXT gettlb(SB), $0 - MOVW 4(FP), R4 SLL $8, R1 MOVW R1, M(INDEX) @@ -267,7 +259,6 @@ TEXT gettlb(SB), $0 RET TEXT gettlbvirt(SB), $0 - SLL $8, R1 MOVW R1, M(INDEX) NOOP @@ -277,19 +268,22 @@ TEXT gettlbvirt(SB), $0 NOOP RET -TEXT vector80(SB), $-4 +TEXT getcause(SB), $0 + MOVW M(CAUSE), R1 + RET +TEXT vector80(SB), $-4 MOVW $exception(SB), R26 JMP (R26) TEXT vector0(SB), $-4 - - MOVW $((MACHADDR+368) & 0xffff0000), R26 /* get m->tlbfault BUG */ +/* get m->tlbfault BUG + MOVW $((MACHADDR+368) & 0xffff0000), R26 OR $((MACHADDR+368) & 0xffff), R26 MOVW (R26), R27 ADD $1, R27 MOVW R27, (R26) - +*/ MOVW $utlbmiss(SB), R26 MOVW M(TLBVIRT), R27 JMP (R26) @@ -302,12 +296,15 @@ TEXT utlbmiss(SB), $-4 XOR R26, R27 AND $(STLBSIZE-1), R27 SLL $8, R27 - /* R27 = (((tlbvirt<<1)^(tlbvirt>>12)) & (STLBSIZE-1)) << 8 (8 to clear zero in TLBPHYS) */ - MOVW R27, M(TLBPHYS) /* scratch register, store */ - - MOVW $((MACHADDR+4) & 0xffff0000), R26 /* get &mach[0].stb BUG */ - OR $((MACHADDR+4) & 0xffff), R26 - MOVW $MPID, R27 /* add BY2PG*machno */ + /* + * R27 = (((tlbvirt<<1)^(tlbvirt>>12)) & (STLBSIZE-1)) << 8 + * (8 to clear zero in TLBPHYS) + */ + MOVW R27, M(TLBPHYS) + + MOVW $((MACHADDR+4)&0xffff0000), R26 /* get &mach[0].stb BUG */ + OR $((MACHADDR+4)&0xffff), R26 + MOVW $MPID, R27 /* add BY2PG*machno */ MOVB 3(R27), R27 AND $7, R27 SLL $PGSHIFT, R27 @@ -334,20 +331,23 @@ stlbm: TEXT exception(SB), $-4 - MOVW M(STATUS), R26 AND $KUP, R26 BEQ R26, waskernel wasuser: - MOVW SP, R26 - /* - * set kernel sp: ureg - ureg* - pc - * done in 2 steps because R30 is not set - * and the loader will make a literal - */ - MOVW $((UREGADDR-2*BY2WD) & 0xffff0000), SP - OR $((UREGADDR-2*BY2WD) & 0xffff), SP + MOVW $(MACHADDR&0xffff0000), R27 + OR $(MACHADDR&0xffff), R27 + MOVW $MPID, R26 + MOVB 3(R26), R26 + AND $7, R26 + SLL $PGSHIFT, R26 + ADDU R26,R27 /* R27->current mach */ + MOVW 8(R27), R26 /* R27 = mach->proc */ + MOVW 8(R26), R27 /* mach->proc->kstack */ + MOVW SP, R26 /* save user sp */ + ADDU $(KSTACK-UREGSIZE-2*BY2WD), R27, SP + MOVW R26, 0x10(SP) /* user SP */ MOVW R31, 0x28(SP) MOVW R30, 0x2C(SP) @@ -360,19 +360,19 @@ wasuser: JAL saveregs(SB) MOVW $setR30(SB), R30 - SUBU $(UREGADDR-2*BY2WD-USERADDR), SP, R(USER) MOVW $MPID, R1 MOVB 3(R1), R1 MOVW $MACHADDR, R(MACH) /* locn of &mach[0] */ AND $7, R1 SLL $PGSHIFT, R1 ADDU R1, R(MACH) /* add offset for mach # */ - MOVW 4(SP), R1 /* first arg for syscall, trap */ - + MOVW 8(R(MACH)), R(USER) /* set up to mach->p */ + MOVW 4(SP), R1 /* first arg for syscall/trap */ BNE R26, notsys JAL syscall(SB) +sysrestore: MOVW 0x28(SP), R31 MOVW 0x08(SP), R26 MOVW 0x2C(SP), R30 @@ -395,7 +395,7 @@ restore: RFE (R26) waskernel: - MOVW $1, R26 /* not sys call */ + MOVW $1, R26 /* not syscall */ MOVW SP, -0x90(SP) /* drop this if possible */ SUB $0xA0, SP MOVW R31, 0x28(SP) @@ -407,6 +407,10 @@ waskernel: ADD $0xA0, SP RFE (R26) +TEXT forkret(SB), $0 + MOVW R0, R1 /* Fake out system call return */ + JMP sysrestore + TEXT saveregs(SB), $-4 MOVW R1, 0x9C(SP) MOVW R2, 0x98(SP) @@ -417,7 +421,7 @@ TEXT saveregs(SB), $-4 MOVW R1, 0x08(SP) MOVW R2, 0x0C(SP) - BEQ R26, return /* sys call, don't save */ + BEQ R26, return /* syscall, don't save */ MOVW M(CAUSE), R1 MOVW M(BADVADDR), R2 @@ -506,7 +510,7 @@ TEXT clrfpintr(SB), $0 OR $CU1, R3 MOVW R3, M(STATUS) WAIT - MOVW FCR31, R1 /* Read it to stall the fpu */ + MOVW FCR31, R1 /* Read it to stall the fpu */ WAIT MOVW R0, FCR31 WAIT @@ -516,7 +520,7 @@ TEXT clrfpintr(SB), $0 TEXT savefpregs(SB), $0 MOVW M(STATUS), R3 - MOVW FCR31, R2 /* Read stalls the fpu until inst. complete. */ + MOVW FCR31, R2 /* Read stalls the fpu until inst. complete. */ WAIT MOVD F0, 0x00(R1) diff --git a/power/lock.c b/power/lock.c index 20884d7edce9122018dc1684b844131abdb2b300..691b5964cbae3de0e3d95eadaa16640795dce1e3 100644 --- a/power/lock.c +++ b/power/lock.c @@ -50,9 +50,9 @@ lockinit(void) Page* lkpage(Segment *s, ulong va) { - uchar *p, *top; - Page *pg; int i; + Page *pg; + uchar *p, *top; USED(s); lock(&semalloc.lock); diff --git a/power/main.c b/power/main.c index ac9f760ef32badcf15fbd9c5ca0034bfff99dc98..9e6c6550bf92c965ce47b63756fd730c0c84e875 100644 --- a/power/main.c +++ b/power/main.c @@ -6,16 +6,16 @@ #include "io.h" #include "init.h" -Softtlb stlb[MAXMACH][STLBSIZE]; /* software tlb simulation */ -int _argc; /* args passed by boot process */ +Softtlb stlb[MAXMACH][STLBSIZE]; /* software tlb simulation */ +int _argc; /* args passed by boot process */ char **_argv; char **_env; -char argbuf[128]; /* arguments passed to initcode */ +char argbuf[128]; /* arguments passed to initcode */ int argsize; -char consname[NAMELEN]; /* environment vars from NVRAM */ +char consname[NAMELEN]; /* environment vars from NVRAM */ char diskless[NAMELEN]; -char confbuf[4*1024]; /* config file read by boot program */ -int ioid; /* IO board type */ +char confbuf[4*1024]; /* config file read by boot program */ +int ioid; /* IO board type */ void main(void) @@ -29,6 +29,7 @@ main(void) xinit(); printinit(); duartspecial(0, &printq, &kbdq, 9600); + print("\n\nBRAZIL\n"); pageinit(); tlbinit(); vecinit(); @@ -168,40 +169,38 @@ launchinit(void) launch(i); for(i=0; i<1000000; i++) if(active.machs == (1<proc = u->p; - u->p->state = Running; - u->p->mach = m; + char buf[2*NAMELEN]; + spllo(); /* * These are o.k. because rootinit is null. * Then early kproc's will have a root and dot. */ - u->slash = (*devtab[0].attach)(0); - u->dot = clone(u->slash, 0); + up->slash = namec("#/", Atodir, 0, 0); + up->dot = clone(up->slash, 0); + chandevinit(); if(!waserror()){ ksetenv("cputype", "mips"); - ksetterm("sgi %s 4D"); + sprint(buf, "sgi %s 4D", conffile); + ksetenv("terminal", buf); ksetenv("sysname", sysname); poperror(); } - if(conf.debugger && conf.nmach > 2) - kproc("kdebug", debugger, 0); kproc("alarm", alarmkproc, 0); - touser((uchar*)(USTKTOP - sizeof(argbuf))); + touser((uchar*)(USTKTOP-sizeof(argbuf))); } FPsave initfp; @@ -210,11 +209,10 @@ void userinit(void) { Proc *p; - Segment *s; - User *up; KMap *k; - char **av; Page *pg; + char **av; + Segment *s; p = newproc(); p->pgrp = newpgrp(); @@ -226,25 +224,16 @@ userinit(void) strcpy(p->text, "*init*"); strcpy(p->user, eve); + savefpregs(&initfp); p->fpstate = FPinit; + p->fpsave.fpstatus = initfp.fpstatus; /* * Kernel Stack */ p->sched.pc = (ulong)init0; - p->sched.sp = USERADDR+BY2PG-(1+MAXSYSARG)*BY2WD; - p->upage = newpage(1, 0, USERADDR|(p->pid&0xFFFF)); - - /* - * User - */ - k = kmap(p->upage); - up = (User*)VA(k); - up->p = p; - up->fpsave.fpstatus = initfp.fpstatus; - kunmap(k); - + p->sched.sp = (ulong)p->kstack+KSTACK-(1+MAXSYSARG)*BY2WD; /* * User Stack, pass input arguments to boot process */ @@ -255,12 +244,11 @@ userinit(void) k = kmap(pg); for(av = (char**)argbuf; *av; av++) *av += (USTKTOP - sizeof(argbuf)) - (ulong)argbuf; + memmove((uchar*)VA(k) + BY2PG - sizeof(argbuf), argbuf, sizeof argbuf); kunmap(k); - /* - * Text - */ + /* Text */ s = newseg(SG_TEXT, UTZERO, 1); p->seg[TSEG] = s; segpage(s, newpage(1, 0, UTZERO)); @@ -335,7 +323,6 @@ exit(int ispanic) int i; USED(ispanic); - u = 0; lock(&active); active.machs &= ~(1<machno); active.exiting = 1; @@ -349,6 +336,7 @@ exit(int ispanic) for(i=0; i<2000000; i++) ; duartenable0(); + firmware(PROM_REINIT); firmware(cpuserver ? PROM_AUTOBOOT : PROM_REINIT); } @@ -464,16 +452,16 @@ void confread(void) { char *line; - char *lend; + char *end; /* * process configuration file */ line = confbuf; - while(lend = strchr(line, '\n')){ - *lend = 0; + while(end = strchr(line, '\n')){ + *end = 0; confset(line); - line = lend+1; + line = end+1; } } @@ -519,8 +507,6 @@ confinit(void) conf.npage1 = 0; conf.base1 = 0; - conf.nproc = 128 + 3*i; - ktop = PGROUND((ulong)end); ktop = PADDR(ktop); conf.npage0 -= ktop/BY2PG; @@ -539,9 +525,14 @@ confinit(void) /* * set minimal default values */ - conf.nmach = 1; + conf.nmach = 2; + conf.nproc = 100; conf.nswap = 262144; conf.nimage = 200; + conf.ipif = 8; + conf.ip = 64; + conf.arp = 32; + conf.frag = 32; confread(); diff --git a/power/mem.h b/power/mem.h index 5704bd6fa5c7be9d26e0e89064abd17047670989..7c65ba058f5a76c0e81ca0946f16e23e90596651 100644 --- a/power/mem.h +++ b/power/mem.h @@ -20,9 +20,9 @@ /* * Time */ -#define HZ 100 -#define MS2HZ (1000/HZ) /* millisec per clock tick */ -#define TK2SEC(t) ((t)/HZ) /* ticks to seconds */ +#define HZ 20 +#define MS2HZ 50 /* millisec per clock tick */ +#define TK2SEC(t) ((t)/20) /* ticks to seconds */ #define TK2MS(t) ((t)*MS2HZ) /* ticks to milliseconds */ #define MS2TK(t) ((t)/MS2HZ) /* milliseconds to ticks */ @@ -73,17 +73,16 @@ */ #define MACH 25 /* R25 is m-> */ -#define USER 24 /* R24 is u-> */ -#define MPID 0xBF000000 /* long; low 3 bits identify mp bus slot */ -#define WBFLUSH 0xBC000000 /* D-CACHE data; used for write buffer flush */ +#define USER 24 /* R24 is up-> */ +#define MPID 0xBF000000 /* long; low 3 bits mp bus slot */ +#define WBFLUSH 0xBC000000 /* D-CACHE data; write buffer flush */ +#define UREGSIZE 0xA0 /* Sizeof(Ureg)+space for retpc & ur */ /* * Fundamental addresses */ #define MACHADDR 0x80014000 -#define USERADDR 0xC0000000 -#define UREGADDR (USERADDR+BY2PG-4-0xA0) /* * MMU */ @@ -94,6 +93,8 @@ #define KSEG2 0xC0000000 #define KSEGM 0xE0000000 /* mask to check which seg */ +#define KSTACK 4096 /* Size of kernel stack */ + #define PTEGLOBL (1<<8) #define PTEVALID (1<<9) #define PTEWRITE (1<<10) @@ -119,7 +120,7 @@ #define UZERO KUSEG /* base of user address space */ #define UTZERO (UZERO+BY2PG) /* first address in user text */ #define USTKTOP KZERO /* byte just beyond user stack */ -#define TSTKTOP (USERADDR+USTKSIZE) /* top of temporary stack */ +#define TSTKTOP (0xC0000000+USTKSIZE) /* top of temporary stack */ #define TSTKSIZ 500 #define KZERO KSEG0 /* base of kernel address space */ #define KTZERO (KZERO+0x20000) /* first address in kernel text */ diff --git a/power/mmu.c b/power/mmu.c index 39635632545fdd4d852f7cb51ec6885982764d43..64eb500b3b910a4d8d79ccbcd6ed1ddda676eced 100644 --- a/power/mmu.c +++ b/power/mmu.c @@ -4,28 +4,17 @@ #include "dat.h" #include "fns.h" -/* - * Called splhi, not in Running state - */ void -mapstack(Proc *p) +mmuswitch(Proc *p) { - short tp; - ulong tlbvirt, tlbphys; - if(p->newtlb) { memset(p->pidonmach, 0, sizeof p->pidonmach); p->newtlb = 0; } + if(p->pidonmach[m->machno] == 0) + newtlbpid(p); - tp = p->pidonmach[m->machno]; - if(tp == 0) - tp = newtlbpid(p); - - tlbvirt = USERADDR | PTEPID(tp); - tlbphys = p->upage->pa | PTEWRITE|PTEVALID|PTEGLOBL; - puttlbx(0, tlbvirt, tlbphys); - u = (User*)USERADDR; + putcontext(p->pidonmach[m->machno]); } void @@ -76,7 +65,6 @@ void putmmu(ulong tlbvirt, ulong tlbphys, Page *pg) { short tp; - Proc *p; char *ctl; splhi(); @@ -88,10 +76,9 @@ putmmu(ulong tlbvirt, ulong tlbphys, Page *pg) *ctl = PG_NOFLUSH; } - p = u->p; - tp = p->pidonmach[m->machno]; + tp = up->pidonmach[m->machno]; if(tp == 0) - tp = newtlbpid(p); + tp = newtlbpid(up); tlbvirt |= PTEPID(tp); putstlb(tlbvirt, tlbphys); @@ -151,8 +138,8 @@ void flushmmu(void) { splhi(); - u->p->newtlb = 1; - mapstack(u->p); + up->newtlb = 1; + mmuswitch(up); spllo(); } @@ -161,13 +148,6 @@ clearmmucache(void) { } -void -invalidateu(void) -{ - puttlbx(0, KZERO | PTEPID(0), 0); - putstlb(KZERO | PTEPID(0), 0); -} - void putstlb(ulong tlbvirt, ulong tlbphys) { diff --git a/power/trap.c b/power/trap.c index 933e2d4e895cab52c4a547a07b3da197d2480ac7..670636e7b5ea5fa5c6f08da6860a8f7658610b40 100644 --- a/power/trap.c +++ b/power/trap.c @@ -28,7 +28,7 @@ char *excname[] = "trap: arithmetic overflow", "trap: undefined 13", "trap: undefined 14", - "trap: undefined 15", /* used as sys call for debugger */ + "trap: undefined 15", /* used as sys call for debugger */ }; char *fpcause[] = @@ -40,56 +40,46 @@ char *fpcause[] = "invalid operation", }; char *fpexcname(Ureg*, ulong, char*); -#define FPEXPMASK (0x3f<<12) /* Floating exception bits in fcr31 */ - -char *regname[]={ - "STATUS", "PC", - "SP", "CAUSE", - "BADADDR", "TLBVIRT", - "HI", "LO", - "R31", "R30", - "R28", "R27", - "R26", "R25", - "R24", "R23", - "R22", "R21", - "R20", "R19", - "R18", "R17", - "R16", "R15", - "R14", "R13", - "R12", "R11", - "R10", "R9", - "R8", "R7", - "R6", "R5", - "R4", "R3", - "R2", "R1", +#define FPEXPMASK (0x3f<<12) /* Floating exception bits in fcr31 */ + +char* +regname[]= +{ + "STATUS", "PC", "SP", "CAUSE", + "BADADDR", "TLBVIRT", "HI", "LO", + "R31", "R30", "R28", "R27", + "R26", "R25", "R24", "R23", + "R22", "R21", "R20", "R19", + "R18", "R17", "R16", "R15", + "R14", "R13", "R12", "R11", + "R10", "R9", "R8", "R7", + "R6", "R5", "R4", "R3", + "R2", "R1" }; void trap(Ureg *ur) { - int ecode; ulong fcr31; - int user, cop, x, fpchk; + int user, cop, x, fpchk, ecode; char buf[2*ERRLEN], buf1[ERRLEN], *fpexcep; -m->ur = ur; - - ecode = (ur->cause>>2)&0xf; user = ur->status&KUP; + ecode = (ur->cause>>2)&0xf; + fpchk = 0; if(user) { - u->dbgreg = ur; - if(u->p->fpstate == FPactive) { + up->dbgreg = ur; + if(up->fpstate == FPactive) { if((ur->status&CU1) == 0) /* Paranoid */ panic("FPactive but no CU1"); - u->p->fpstate = FPinactive; + up->fpstate = FPinactive; ur->status &= ~CU1; - savefpregs(&u->fpsave); + savefpregs(&up->fpsave); fptrap(ur); fpchk = 1; } } - switch(ecode){ case CINT: if(ur->cause&INTR3) { /* FP trap */ @@ -102,28 +92,28 @@ m->ur = ur; case CTLBM: case CTLBL: case CTLBS: - if(u == 0) - panic("fault u==0 pc %lux addr %lux", ur->pc, ur->badvaddr); + if(up == 0) + panic("kfault pc %lux addr %lux", ur->pc, ur->badvaddr); - x = u->p->insyscall; - u->p->insyscall = 1; + x = up->insyscall; + up->insyscall = 1; spllo(); faultmips(ur, user, ecode); - u->p->insyscall = x; + up->insyscall = x; break; case CCPU: cop = (ur->cause>>28)&3; if(user && cop == 1) { - if(u->p->fpstate == FPinit) { - u->p->fpstate = FPinactive; - fcr31 = u->fpsave.fpstatus; - u->fpsave = initfp; - u->fpsave.fpstatus = fcr31; + if(up->fpstate == FPinit) { + up->fpstate = FPinactive; + fcr31 = up->fpsave.fpstatus; + up->fpsave = initfp; + up->fpsave.fpstatus = fcr31; break; } - if(u->p->fpstate == FPinactive) + if(up->fpstate == FPinactive) break; } /* Fallthrough */ @@ -132,7 +122,7 @@ m->ur = ur; if(user) { spllo(); sprint(buf, "sys: %s", excname[ecode]); - postnote(u->p, 1, buf, NDebug); + postnote(up, 1, buf, NDebug); break; } print("kernel %s pc=%lux\n", excname[ecode], ur->pc); @@ -144,12 +134,12 @@ m->ur = ur; } if(fpchk) { - fcr31 = u->fpsave.fpstatus; + fcr31 = up->fpsave.fpstatus; if((fcr31>>12) & ((fcr31>>7)|0x20) & 0x3f) { spllo(); fpexcep = fpexcname(ur, fcr31, buf1); sprint(buf, "sys: fp: %s", fpexcep); - postnote(u->p, 1, buf, NDebug); + postnote(up, 1, buf, NDebug); } } @@ -158,9 +148,9 @@ m->ur = ur; return; notify(ur); - if(u->p->fpstate == FPinactive) { - restfpregs(&u->fpsave, u->fpsave.fpstatus); - u->p->fpstate = FPactive; + if(up->fpstate == FPinactive) { + restfpregs(&up->fpsave, up->fpsave.fpstatus); + up->fpstate = FPactive; ur->status |= CU1; } } @@ -169,7 +159,7 @@ void intr(Ureg *ur) { long v; - int i, any, limit; + int i, any; ulong cause; static int bogies; uchar pend, xxx; @@ -182,7 +172,7 @@ intr(Ureg *ur) cause &= ~INTR1; } - for(limit = 50; (cause&INTR5) && limit; limit--) { + while(cause & INTR5) { any = 0; if(!(*MPBERR1 & (1<<8))){ print("MP bus error %lux %lux\n", *MPBERR0, *MPBERR1); @@ -285,20 +275,16 @@ intr(Ureg *ur) if(any == 0) cause &= ~INTR5; } - if(limit == 0) { - LEDON(LED5); - print("intr: unable to identify and clear level5\n"); - cause &= ~INTR5; - LEDOFF(LED5); - } if(cause & (INTR2|INTR4)) { + LEDON(LEDclock); clock(ur); + LEDOFF(LEDclock); cause &= ~(INTR2|INTR4); } if(cause) - panic("cause %lux %lux\n", u, cause); + panic("cause %lux %lux\n", up, cause); } char* @@ -331,15 +317,16 @@ fpexcname(Ureg *ur, ulong fcr31, char *buf) void dumpstack(void) { - ulong l, v; + ulong l, v, top; extern ulong etext; - if(u == 0) + if(up == 0) return; - for(l=(ulong)&l; lkstack + KSTACK; + for(l=(ulong)&l; l < top; l += BY2WD) { v = *(ulong*)l; - if(KTZERO < v && v < (ulong)&etext){ + if(KTZERO < v && v < (ulong)&etext) { print("%lux=%lux\n", l, v); delay(100); } @@ -352,14 +339,16 @@ dumpregs(Ureg *ur) int i; ulong *l; - if(u) - print("registers for %s %d\n", u->p->text, u->p->pid); + if(up) + print("registers for %s %d\n", up->text, up->pid); else print("registers for kernel\n"); l = &ur->status; - for(i=0; ip->procctl) - procctl(u->p); - if(u->nnote == 0) + if(up->procctl) + procctl(up); + if(up->nnote == 0) return 0; spllo(); - qlock(&u->p->debug); - u->p->notepending = 0; - n = &u->note[0]; + qlock(&up->debug); + up->notepending = 0; + n = &up->note[0]; if(strncmp(n->msg, "sys:", 4) == 0) { l = strlen(n->msg); if(l > ERRLEN-15) /* " pc=0x12345678\0" */ @@ -388,52 +377,51 @@ notify(Ureg *ur) sprint(n->msg+l, " pc=0x%lux", ur->pc); } - if(n->flag != NUser && (u->notified || u->notify==0)) { + if(n->flag != NUser && (up->notified || up->notify==0)) { if(n->flag == NDebug) pprint("suicide: %s\n", n->msg); - qunlock(&u->p->debug); + qunlock(&up->debug); pexit(n->msg, n->flag!=NDebug); } - if(u->notified) { - qunlock(&u->p->debug); + if(up->notified) { + qunlock(&up->debug); splhi(); return 0; } - if(!u->notify) { - qunlock(&u->p->debug); + if(!up->notify) { + qunlock(&up->debug); pexit(n->msg, n->flag!=NDebug); } - u->svstatus = ur->status; + up->svstatus = ur->status; sp = ur->usp - sizeof(Ureg); - if(sp&0x3 || !okaddr((ulong)u->notify, BY2WD, 0) + if(sp&0x3 || !okaddr((ulong)up->notify, BY2WD, 0) || !okaddr(sp-ERRLEN-3*BY2WD, sizeof(Ureg)+ERRLEN+3*BY2WD, 1)) { pprint("suicide: bad address or sp in notify\n"); - qunlock(&u->p->debug); + qunlock(&up->debug); pexit("Suicide", 0); } - u->ureg = (void*)sp; + up->ureg = (void*)sp; memmove((Ureg*)sp, ur, sizeof(Ureg)); sp -= ERRLEN; - memmove((char*)sp, u->note[0].msg, ERRLEN); + memmove((char*)sp, up->note[0].msg, ERRLEN); sp -= 3*BY2WD; *(ulong*)(sp+2*BY2WD) = sp+3*BY2WD; /* arg 2 is string */ - u->svr1 = ur->r1; /* save away r1 */ - ur->r1 = (ulong)u->ureg; /* arg 1 (R1) is ureg* */ - *(ulong*)(sp+1*BY2WD) = (ulong)u->ureg; /* arg 1 0(FP) is ureg* */ + up->svr1 = ur->r1; /* save away r1 */ + ur->r1 = (ulong)up->ureg; /* arg 1 is ureg* */ *(ulong*)(sp+0*BY2WD) = 0; /* arg 0 is pc */ ur->usp = sp; - ur->pc = (ulong)u->notify; - u->notified = 1; - u->nnote--; - memmove(&u->lastnote, &u->note[0], sizeof(Note)); - memmove(&u->note[0], &u->note[1], u->nnote*sizeof(Note)); + ur->pc = (ulong)up->notify; + up->notified = 1; + up->nnote--; + memmove(&up->lastnote, &up->note[0], sizeof(Note)); + memmove(&up->note[0], &up->note[1], up->nnote*sizeof(Note)); - qunlock(&u->p->debug); + qunlock(&up->debug); splhi(); return 1; } @@ -446,42 +434,42 @@ noted(Ureg **urp, ulong arg0) { Ureg *nur; - nur = u->ureg; - if(nur->status != u->svstatus) { + nur = up->ureg; + if(nur->status != up->svstatus) { pprint("bad noted ureg status %lux\n", nur->status); pexit("Suicide", 0); } - qlock(&u->p->debug); - if(!u->notified) { - qunlock(&u->p->debug); + qlock(&up->debug); + if(!up->notified) { + qunlock(&up->debug); pprint("call to noted() when not notified\n"); pexit("Suicide", 0); } - u->notified = 0; - memmove(*urp, u->ureg, sizeof(Ureg)); - (*urp)->r1 = u->svr1; + up->notified = 0; + memmove(*urp, up->ureg, sizeof(Ureg)); + (*urp)->r1 = up->svr1; switch(arg0) { case NCONT: if(!okaddr(nur->pc, 1, 0) || !okaddr(nur->usp, BY2WD, 0)){ pprint("suicide: trap in noted\n"); - qunlock(&u->p->debug); + qunlock(&up->debug); pexit("Suicide", 0); } splhi(); - qunlock(&u->p->debug); + qunlock(&up->debug); rfnote(urp); break; default: pprint("unknown noted arg 0x%lux\n", arg0); - u->lastnote.flag = NDebug; + up->lastnote.flag = NDebug; /* fall through */ case NDFLT: - if(u->lastnote.flag == NDebug) - pprint("suicide: %s\n", u->lastnote.msg); - qunlock(&u->p->debug); - pexit(u->lastnote.msg, u->lastnote.flag!=NDebug); + if(up->lastnote.flag == NDebug) + pprint("suicide: %s\n", up->lastnote.msg); + qunlock(&up->debug); + pexit(up->lastnote.msg, up->lastnote.flag != NDebug); } } @@ -494,64 +482,63 @@ syscall(Ureg *aur) long ret; ulong sp; Ureg *ur; - Proc *p; m->syscall++; - p = u->p; - p->insyscall = 1; + up->insyscall = 1; ur = aur; - p->pc = ur->pc; - u->dbgreg = aur; - ur->cause = 15<<2; /* for debugging: system call is undef 15; */ + up->pc = ur->pc; + up->dbgreg = aur; + ur->cause = 15<<2; /* for debugging: system call is undef 15; */ - if(p->fpstate == FPactive) { + if(up->fpstate == FPactive) { if((ur->status&CU1) == 0) panic("syscall: FPactive but no CU1"); - u->fpsave.fpstatus = fcr31(); - p->fpstate = FPinit; + up->fpsave.fpstatus = fcr31(); + up->fpstate = FPinit; ur->status &= ~CU1; } spllo(); - if(p->procctl) - procctl(p); + if(up->procctl) + procctl(up); - u->scallnr = ur->r1; - u->nerrlab = 0; + up->scallnr = ur->r1; + up->nerrlab = 0; sp = ur->sp; ret = -1; if(!waserror()){ - if(u->scallnr >= sizeof systab/sizeof systab[0]) { - pprint("bad sys call number %d pc %lux\n", u->scallnr, ur->pc); - postnote(p, 1, "sys: bad sys call", NDebug); + if(up->scallnr >= sizeof systab/sizeof systab[0]) { + pprint("bad sys call number %d pc %lux\n", + up->scallnr, ur->pc); + postnote(up, 1, "sys: bad sys call", NDebug); error(Ebadarg); } if(sp & (BY2WD-1)){ pprint("odd sp in sys call pc %lux sp %lux\n", ur->pc, ur->sp); - postnote(p, 1, "sys: odd stack", NDebug); + postnote(up, 1, "sys: odd stack", NDebug); error(Ebadarg); } - if(sp<(USTKTOP-BY2PG) || sp>(USTKTOP-sizeof(Sargs))) + if(sp < (USTKTOP-BY2PG) || sp > (USTKTOP-sizeof(Sargs))) validaddr(sp, sizeof(Sargs), 0); - u->s = *((Sargs*)(sp+BY2WD)); - p->psstate = sysctab[u->scallnr]; + up->s = *((Sargs*)(sp+BY2WD)); + up->psstate = sysctab[up->scallnr]; - ret = (*systab[u->scallnr])(u->s.args); + ret = (*systab[up->scallnr])(up->s.args); poperror(); } ur->pc += 4; - u->nerrlab = 0; - p->psstate = 0; - p->insyscall = 0; - if(u->scallnr == NOTED) /* ugly hack */ + up->nerrlab = 0; + up->psstate = 0; + up->insyscall = 0; + if(up->scallnr == NOTED) /* ugly hack */ noted(&aur, *(ulong*)(sp+BY2WD)); /* doesn't return */ splhi(); - if(u->scallnr!=RFORK && (p->procctl || u->nnote)){ + if(up->scallnr!=RFORK && (up->procctl || up->nnote)){ ur->r1 = ret; /* load up for noted() */ if(notify(ur)) return ur->r1; @@ -560,23 +547,65 @@ syscall(Ureg *aur) return ret; } +void +forkchild(Proc *p, Ureg *ur) +{ + Ureg *cur; + + p->sched.sp = (ulong)p->kstack+KSTACK-(sizeof(Ureg)+2*BY2WD); + p->sched.pc = (ulong)forkret; + + cur = (Ureg*)(p->sched.sp+2*BY2WD); + memmove(cur, ur, sizeof(Ureg)); + + cur->pc += 4; + + /* Things from bottom of syscall we never got to execute */ + p->psstate = 0; + p->insyscall = 0; +} + +static +void +linkproc(void) +{ + spllo(); + (*up->kpfun)(up->kparg); +} + +void +kprocchild(Proc *p, void (*func)(void*), void *arg) +{ + p->sched.pc = (ulong)linkproc; + p->sched.sp = (ulong)p->kstack+KSTACK; + + p->kpfun = func; + p->kparg = arg; +} + long execregs(ulong entry, ulong ssize, ulong nargs) { + Ureg *ur; ulong *sp; sp = (ulong*)(USTKTOP - ssize); *--sp = nargs; - ((Ureg*)UREGADDR)->usp = (ulong)sp; - ((Ureg*)UREGADDR)->pc = entry - 4; /* syscall advances it */ - u->fpsave.fpstatus = initfp.fpstatus; + + ur = (Ureg*)up->dbgreg; + ur->usp = (ulong)sp; + ur->pc = entry - 4; /* syscall advances it */ + up->fpsave.fpstatus = initfp.fpstatus; return USTKTOP-BY2WD; /* address of user-level clock */ } ulong userpc(void) { - return ((Ureg*)UREGADDR)->pc; + Ureg *ur; + + ur = (Ureg*)up->dbgreg; + return ur->pc; } void @@ -602,8 +631,8 @@ setvmevec(int v, void (*f)(int)) vmevec[v] = f; } -/* This routine must save the values of registers the user is not permitted to write - * from devproc and then restore the saved values before returning +/* This routine must save the values of registers the user is not permitted to + * write from devproc and then restore the saved values before returning */ void setregisters(Ureg *xp, char *pureg, char *uva, int n) diff --git a/ss/arp.h b/ss/arp.h deleted file mode 100644 index 0874d6abbaec4c2d766681be4c6b7b841bd8a89d..0000000000000000000000000000000000000000 --- a/ss/arp.h +++ /dev/null @@ -1,40 +0,0 @@ -typedef struct Arppkt Arppkt; -typedef struct Arpentry Arpentry; -typedef struct Arpstats Arpstats; - -/* Format of ethernet arp request */ -struct Arppkt { - uchar d[6]; - uchar s[6]; - uchar type[2]; - uchar hrd[2]; - uchar pro[2]; - uchar hln; - uchar pln; - uchar op[2]; - uchar sha[6]; - uchar spa[4]; - uchar tha[6]; - uchar tpa[4]; - }; - -/* Format of request from starp to user level arpd */ -struct Arpentry { - uchar etaddr[6]; - uchar ipaddr[4]; - }; - -/* Arp cache statistics */ -struct Arpstats { - int hit; - int miss; - int failed; - }; - -#define ET_ARP 0x0806 -#define ET_RARP 0x8035 - -#define ARP_REQUEST 1 -#define ARP_REPLY 2 -#define RARP_REQUEST 3 -#define RARP_REPLY 4 diff --git a/ss/bbmalloc.c b/ss/bbmalloc.c deleted file mode 100644 index 9e9025c4a505ae8f9989ab78b802ee33d39559f6..0000000000000000000000000000000000000000 --- a/ss/bbmalloc.c +++ /dev/null @@ -1,54 +0,0 @@ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "io.h" - -/* - * Allocate memory for use in kernel bitblts. - */ - -/* 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); - bblast = ans; - ans = (void *)ans; - return ans; -} - -void -bbfree(void *p, int n) -{ - if(p == bblast) - bbcur = (ulong *)(((char *)bblast) + n); -} - -int -bbonstack(void) -{ - if(u) - return 1; - return 0; -} diff --git a/ss/clock.c b/ss/clock.c deleted file mode 100644 index 141eb8348e2018ee442d2af3d07c04912d4a930d..0000000000000000000000000000000000000000 --- a/ss/clock.c +++ /dev/null @@ -1,79 +0,0 @@ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "io.h" - -#include "ureg.h" - -void -delay(int ms) -{ - int i; - - ms *= 6666; /* experimentally determined */ - if(conf.ss2) - ms *= 2; - for(i=0; iva; - ctr->lim1 = (CLOCKFREQ/HZ)<<10; -} - -void -clock(Ureg *ur) -{ - Proc *p; - ulong i, nrun = 0; - - i = ctr->lim1; /* clear interrupt */ - USED(i); - m->ticks++; - p = m->proc; - if(p){ - nrun = 1; - p->pc = ur->pc; - if (p->state==Running) - p->time[p->insyscall]++; - } - nrun = (nrdy+nrun)*1000; - MACHP(0)->load = (MACHP(0)->load*19+nrun)/20; - - checkalarms(); - kbdclock(); - mouseclock(); - sccclock(); - kproftimer(ur->pc); - if(m->fpunsafe) - return; - - if((ur->psr&SPL(0xF))==0 && p && p->state==Running) { - if(anyready()){ - if(p->hasspin) - p->hasspin = 0; - else - sched(); - } - if((ur->psr&PSRPSUPER) == 0) - *(ulong*)(USTKTOP-BY2WD) += TK2MS(1); - } -} diff --git a/ss/compile.c b/ss/compile.c deleted file mode 100644 index 777990f6f3cde46247596619e7a3289a1621236d..0000000000000000000000000000000000000000 --- a/ss/compile.c +++ /dev/null @@ -1,185 +0,0 @@ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "io.h" - -#define NCODE 1024 -static ulong code[NCODE]; -static ulong *codep; - -ulong (*getcontext)(void); -void (*putcontext)(ulong); -void (*putenab)(ulong); -ulong (*getenab)(void); -ulong (*getsysspace)(ulong); -void (*putsysspace)(ulong, ulong); -uchar (*getsysspaceb)(ulong); -void (*putsysspaceb)(ulong, uchar); -ulong (*getsegspace)(ulong); -void (*putsegspace)(ulong, ulong); -ulong (*getpmegspace)(ulong); -void (*putpmegspace)(ulong, ulong); -ulong (*flushpg)(ulong); - -/* - * Compile MMU code for this machine, since the MMU can only - * be addressed from parameterless machine instructions. - * What's wrong with MMUs you can talk to from C? - */ - -/* op3 */ -#define LD 0 -#define ADD 0 -#define OR 2 -#define LDA 16 -#define LDUBA 17 -#define STA 20 -#define STBA 21 -#define JMPL 56 -/* op2 */ -#define SETHI 4 - -#define ret() {*codep++ = (2<<30)|(0<<25)|(JMPL<<19)|(15<<14)|(1<<13)|8;} -#define nop() {*codep++ = (0<<30)|(0<<25)|(SETHI<<22)|(0>>10);} - -static void -parameter(int param, int reg) -{ - param += 1; /* 0th parameter is 1st word on stack */ - param *= 4; - /* LD #param(R1), Rreg */ - *codep++ = (3<<30)|(reg<<25)|(LD<<19)|(1<<14)|(1<<13)|param; -} - -static void -constant(ulong c, int reg) -{ - *codep++ = (0<<30)|(reg<<25)|(SETHI<<22)|(c>>10); - if(c & 0x3FF) - *codep++ = (2<<30)|(reg<<25)|(OR<<19)|(reg<<14)|(1<<13)|(c&0x3FF); -} - -/* - * value to/from constant address - * void f(int c) { *(word*,asi)addr = c } for stores - * ulong f(void) { return *(word*,asi)addr } for loads - */ -static void* -compileconst(int op3, ulong addr, int asi) -{ - void *a; - - a = codep; - constant(addr, 8); /* MOVW $CONSTANT, R8 */ - ret(); /* JMPL 8(R15), R0 */ - /* in delay slot st or ld R7, (R8+R0, asi) */ - *codep++ = (3<<30)|(7<<25)|(op3<<19)|(8<<14)|(asi<<5); - return a; -} - -/* - * value to parameter address - * void f(ulong addr, int c) { *(word*,asi)addr = c } - */ -static void* -compilestaddr(int op3, int asi) -{ - void *a; - - a = codep; - parameter(1, 8); /* MOVW (4*1)(FP), R8 */ - ret(); /* JMPL 8(R15), R0 */ - /* in delay slot st R8, (R7+R0, asi) */ - *codep++ = (3<<30)|(8<<25)|(op3<<19)|(7<<14)|(asi<<5); - return a; -} - -/* - * value from parameter address - * ulong f(ulong addr) { return *(word*,asi)addr } - */ -static void* -compileldaddr(int op3, int asi) -{ - void *a; - - a = codep; - ret(); /* JMPL 8(R15), R0 */ - /* in delay slot ld (R7+R0, asi), R7 */ - *codep++ = (3<<30)|(7<<25)|(op3<<19)|(7<<14)|(asi<<5); - return a; -} - -/* - * 1 store of zero - * ulong f(ulong addr) { *addr=0; addr+=offset; return addr} - * offset can be anything - */ -static void* -compile1(ulong offset, int asi) -{ - void *a; - - a = codep; - /* ST R0, (R7+R0, asi) */ - *codep++ = (3<<30)|(0<<25)|(STA<<19)|(7<<14)|(asi<<5); - if(offset < (1<<12)){ - ret(); /* JMPL 8(R15), R0 */ - /* in delay slot ADD $offset, R7 */ - *codep++ = (2<<30)|(7<<25)|(ADD<<19)|(7<<14)|(1<<13)|offset; - }else{ - constant(offset, 8); - ret(); /* JMPL 8(R15), R0 */ - /* in delay slot ADD R8, R7 */ - *codep++ = (2<<30)|(7<<25)|(ADD<<19)|(7<<14)|(0<<13)|8; - } - return a; -} - -/* - * 16 stores of zero - * ulong f(ulong addr) { for(i=0;i<16;i++) {*addr=0; addr+=offset}; return addr} - * offset must be less than 1<<12 - */ -static void* -compile16(ulong offset, int asi) -{ - void *a; - int i; - - a = codep; - for(i=0; i<16; i++){ - /* ST R0, (R7+R0, asi) */ - *codep++ = (3<<30)|(0<<25)|(STA<<19)|(7<<14)|(asi<<5); - /* ADD $offset, R7 */ - *codep++ = (2<<30)|(7<<25)|(ADD<<19)|(7<<14)|(1<<13)|offset; - } - ret(); /* JMPL 8(R15), R0 */ - nop(); - return a; -} - -void -compile(void) -{ - codep = code; - - getcontext = compileconst(LDUBA, CONTEXT, 2); - putcontext = compileconst(STBA, CONTEXT, 2); - getenab = compileconst(LDUBA, ENAB, 2); - putenab = compileconst(STBA, ENAB, 2); - getsysspace = compileldaddr(LDA, 2); - putsysspace = compilestaddr(STA, 2); - getsysspaceb = compileldaddr(LDUBA, 2); - putsysspaceb = compilestaddr(STBA, 2); - getsegspace = compileldaddr(LDUBA, 3); - putsegspace = compilestaddr(STBA, 3); - getpmegspace = compileldaddr(LDA, 4); - putpmegspace = compilestaddr(STA, 4); - if(conf.ss2) - flushpg = compile1(BY2PG, 6); - else - flushpg = compile16(conf.vaclinesize, 0xD); -} diff --git a/ss/dat.h b/ss/dat.h deleted file mode 100644 index 4a4caf45f0848e2d9d82cfa6f14f3949cbafee3b..0000000000000000000000000000000000000000 --- a/ss/dat.h +++ /dev/null @@ -1,217 +0,0 @@ -typedef struct Conf Conf; -typedef struct Ctx Ctx; -typedef struct FFrame FFrame; -typedef struct FPsave FPsave; -typedef struct KMap KMap; -typedef struct Lance Lance; -typedef struct Lancemem Lancemem; -typedef struct Label Label; -typedef struct Lock Lock; -typedef struct Pmeg Pmeg; -typedef struct PMMU PMMU; -typedef struct Mach Mach; -typedef struct Ureg Ureg; -typedef struct List List; -typedef struct User User; - - - -#define MACHP(n) (n==0? &mach0 : *(Mach**)0) - -extern Mach mach0; -extern void (*kprofp)(ulong); - -/* - * parameters for sysproc.c - */ -#define AOUT_MAGIC K_MAGIC - -/* - * machine dependent definitions used by ../port/dat.h - */ - -struct Lock -{ - ulong key; - ulong pc; -}; - -struct Label -{ - ulong sp; - ulong pc; -}; - -/* - * floating point registers - */ -enum -{ - FPinit, - FPactive, - FPinactive, -}; - -#define NFPQ 4 /* just a guess */ - -struct FPsave -{ - long fsr; - long fpreg[32]; - struct{ - ulong a; /* address */ - ulong i; /* instruction */ - }q[NFPQ]; - long fppc; /* for recursive traps only */ -}; - -struct Conf -{ - int nmach; /* processors */ - int nproc; /* processes */ - ulong monitor; /* graphics monitor id; 0 for none */ - char ss2; /* is a sparcstation 2 */ - char ss2cachebug; /* has sparcstation2 cache bug */ - int ncontext; /* in mmu */ - int npmeg; - int vacsize; /* size of virtual address cache, in bytes */ - int vaclinesize; /* size of cache line */ - ulong npage0; /* total physical pages of memory, bank 0 */ - ulong npage1; /* total physical pages of memory, bank 1 */ - ulong base0; /* base of bank 0 */ - ulong base1; /* base of bank 1 */ - ulong npage; /* total physical pages of memory */ - ulong nimage; /* number of page cache image headers */ - ulong nswap; /* number of swap blocks */ - ulong upages; /* number of user pages */ - int copymode; /* 0 is copy on write, 1 is copy on reference */ -}; - - -/* - * mmu goo in the Proc structure - */ -struct PMMU -{ - Ctx *ctxonmach[MAXMACH]; -}; - -#include "../port/portdat.h" - -/* - * machine dependent definitions not used by ../port/dat.h - */ -struct KMap -{ - KMap *next; - ulong pa; - ulong va; -}; -#define VA(k) ((k)->va) - -struct Mach -{ - int machno; /* physical id of processor */ - ulong splpc; /* pc of last caller to splhi */ - int mmask; /* 1<machno */ - ulong ticks; /* of the clock since boot time */ - Proc *proc; /* current process on this processor */ - Proc *lproc; /* last process on this processor */ - Label sched; /* scheduler wakeup */ - Lock alarmlock; /* access to alarm list */ - void *alarm; /* alarms bound to this clock */ - int fpstate; /* state of fp registers on machine */ - - Ctx *cctx; /* current context */ - List *clist; /* lru list of all contexts */ - Pmeg *pmeg; /* array of allocatable pmegs */ - int pfirst; /* index of first allocatable pmeg */ - List *plist; /* lru list of non-kernel Pmeg's */ - int needpmeg; /* a process needs a pmeg */ - - int tlbfault; - int tlbpurge; - int pfault; - int cs; - int syscall; - int load; - int fpunsafe; /* FP unsaved */ - int fptrap; /* FP trap occurred while unsafe */ - int intr; - - int stack[1]; -}; - -#define NERR 15 -#define NNOTE 5 -struct User -{ - Proc *p; - /* &fpsave must be 4 mod 8 */ - FPsave fpsave; /* address of this is known by db */ - int scallnr; /* sys call number - known by db */ - Sargs s; /* address of this is known by db */ - int nerrlab; - Label errlab[NERR]; - char error[ERRLEN]; - char elem[NAMELEN]; /* last name element from namec */ - Chan *slash; - Chan *dot; - /* - * Rest of structure controlled by devproc.c and friends. - * lock(&p->debug) to modify. - */ - ulong svpsr; - Note note[NNOTE]; - short nnote; - short notified; /* sysnoted is due */ - Note lastnote; - int (*notify)(void*, char*); - void *ureg; - void *dbgreg; /* User registers for debugging in proc */ - ulong svr7; -}; - -/* - * LANCE CSR3 (bus control bits) - */ -#define BSWP 0x4 -#define ACON 0x2 -#define BCON 0x1 - -/* - * system dependent lance stuff - * filled by lancesetup() - */ -struct Lance -{ - ushort lognrrb; /* log2 number of receive ring buffers */ - ushort logntrb; /* log2 number of xmit ring buffers */ - ushort nrrb; /* number of receive ring buffers */ - ushort ntrb; /* number of xmit ring buffers */ - ushort *rap; /* lance address register */ - ushort *rdp; /* lance data register */ - ushort busctl; /* bus control bits */ - uchar ea[6]; /* our ether addr */ - int sep; /* separation between shorts in lance ram - as seen by host */ - ushort *lanceram; /* start of lance ram as seen by host */ - Lancemem *lm; /* start of lance ram as seen by lance */ - Etherpkt *rp; /* receive buffers (host address) */ - Etherpkt *tp; /* transmit buffers (host address) */ - Etherpkt *lrp; /* receive buffers (lance address) */ - Etherpkt *ltp; /* transmit buffers (lance address) */ -}; - -extern register Mach *m; /* R6 */ -extern register User *u; /* R5 */ - -extern uchar *intrreg; -extern FPsave *initfpp; - -struct -{ - Lock; - short machs; - short exiting; -}active; diff --git a/ss/devrtc.c b/ss/devrtc.c deleted file mode 100644 index d57f222d42ffb4c0fe1bcbe49384130b5a601eeb..0000000000000000000000000000000000000000 --- a/ss/devrtc.c +++ /dev/null @@ -1,378 +0,0 @@ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "../port/error.h" -#include "devtab.h" - -#include "io.h" - -/* - * Mostek MK48T12-15 Zeropower/Timekeeper - * This driver is actually portable. - */ -typedef struct Rtc Rtc; -struct Rtc -{ - int sec; - int min; - int hour; - int wday; - int mday; - int mon; - int year; -}; -ulong rtc2sec(Rtc *); -void sec2rtc(ulong, Rtc *); - -static struct -{ - uchar *ram; - RTCdev *rtc; -}nvr; - -enum{ - Qrtc = 1, - Qnvram, -}; - -QLock rtclock; /* mutex on clock operations */ - -static Dirtab rtcdir[]={ - "rtc", {Qrtc, 0}, 0, 0666, - "nvram", {Qnvram, 0}, 0, 0666, -}; -#define NRTC (sizeof(rtcdir)/sizeof(rtcdir[0])) -void setrtc(Rtc*); -long rtctime(void); - -void -rtcreset(void) -{ -} - -void -rtcinit(void) -{ - KMap *k; - - k = kmappa(NVRAM, PTENOCACHE|PTEIO); - nvr.ram = (uchar*)k->va; - nvr.rtc = (RTCdev*)(k->va+RTCOFF); -} - -Chan* -rtcattach(char *spec) -{ - return devattach('r', spec); -} - -Chan* -rtcclone(Chan *c, Chan *nc) -{ - return devclone(c, nc); -} - -int -rtcwalk(Chan *c, char *name) -{ - return devwalk(c, name, rtcdir, NRTC, devgen); -} - -void -rtcstat(Chan *c, char *dp) -{ - devstat(c, dp, rtcdir, NRTC, devgen); -} - -Chan* -rtcopen(Chan *c, int omode) -{ - omode = openmode(omode); - switch(c->qid.path){ - case Qrtc: - if(strcmp(u->p->user, eve)!=0 && omode!=OREAD) - error(Eperm); - break; - case Qnvram: - if(strcmp(u->p->user, eve)!=0 || !cpuserver) - error(Eperm); - } - return devopen(c, omode, rtcdir, NRTC, devgen); -} - -void -rtccreate(Chan *c, char *name, int omode, ulong perm) -{ - USED(c, name, omode, perm); - error(Eperm); -} - -void -rtcclose(Chan *c) -{ - USED(c); -} - -long -rtcread(Chan *c, void *buf, long n, ulong offset) -{ - ulong t, ot; - - if(c->qid.path & CHDIR) - return devdirread(c, buf, n, rtcdir, NRTC, devgen); - - switch(c->qid.path){ - case Qrtc: - qlock(&rtclock); - t = rtctime(); - do{ - ot = t; - t = rtctime(); /* make sure there's no skew */ - }while(t != ot); - qunlock(&rtclock); - n = readnum(offset, buf, n, t, 12); - return n; - case Qnvram: - if(offset > NVREAD) - return 0; - if(n > NVREAD - offset) - n = NVREAD - offset; - qlock(&rtclock); - memmove(buf, nvr.ram+offset, n); - qunlock(&rtclock); - return n; - } - error(Egreg); - return 0; /* not reached */ -} - -long -rtcwrite(Chan *c, void *buf, long n, ulong offset) -{ - Rtc rtc; - ulong secs; - char *cp, *ep; - - switch(c->qid.path){ - case Qrtc: - if(offset!=0) - error(Ebadarg); - /* - * read the time - */ - cp = ep = buf; - ep += n; - while(cp < ep){ - if(*cp>='0' && *cp<='9') - break; - cp++; - } - secs = strtoul(cp, 0, 0); - /* - * convert to bcd - */ - sec2rtc(secs, &rtc); - /* - * write it - */ - qlock(&rtclock); - setrtc(&rtc); - qunlock(&rtclock); - return n; - case Qnvram: - if(offset > NVWRITE) - return 0; - if(n > NVWRITE - offset) - n = NVWRITE - offset; - qlock(&rtclock); - memmove(nvr.ram+offset, buf, n); - qunlock(&rtclock); - return n; - } - error(Egreg); - return 0; /* not reached */ -} - -void -rtcremove(Chan *c) -{ - USED(c); - error(Eperm); -} - -void -rtcwstat(Chan *c, char *dp) -{ - USED(c, dp); - error(Eperm); -} - -#define bcd2dec(bcd) (((((bcd)>>4) & 0x0F) * 10) + ((bcd) & 0x0F)) -#define dec2bcd(dec) ((((dec)/10)<<4)|((dec)%10)) - -void -setrtc(Rtc *rtc) -{ - struct RTCdev *dev; - - dev = nvr.rtc; - dev->control |= RTCWRITE; - wbflush(); - dev->year = dec2bcd(rtc->year % 100); - dev->mon = dec2bcd(rtc->mon); - dev->mday = dec2bcd(rtc->mday); - dev->hour = dec2bcd(rtc->hour); - dev->min = dec2bcd(rtc->min); - dev->sec = dec2bcd(rtc->sec); - wbflush(); - dev->control &= ~RTCWRITE; - wbflush(); -} - -long -rtctime(void) -{ - struct RTCdev *dev; - Rtc rtc; - - dev = nvr.rtc; - dev->control |= RTCREAD; - wbflush(); - rtc.sec = bcd2dec(dev->sec) & 0x7F; - rtc.min = bcd2dec(dev->min & 0x7F); - rtc.hour = bcd2dec(dev->hour & 0x3F); - rtc.mday = bcd2dec(dev->mday & 0x3F); - rtc.mon = bcd2dec(dev->mon & 0x3F); - rtc.year = bcd2dec(dev->year); - dev->control &= ~RTCREAD; - wbflush(); - - if (rtc.mon < 1 || rtc.mon > 12) - return 0; - /* - * the world starts Jan 1 1970 - */ - if(rtc.year < 70) - rtc.year += 2000; - else - rtc.year += 1900; - - return rtc2sec(&rtc); -} - -#define SEC2MIN 60L -#define SEC2HOUR (60L*SEC2MIN) -#define SEC2DAY (24L*SEC2HOUR) - -/* - * days per month plus days/year - */ -static int dmsize[] = -{ - 365, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 -}; -static int ldmsize[] = -{ - 366, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 -}; - -/* - * return the days/month for the given year - */ -int * -yrsize(int yr) -{ - if((yr % 4) == 0) - return ldmsize; - else - return dmsize; -} - -/* - * compute seconds since Jan 1 1970 - */ -ulong -rtc2sec(Rtc *rtc) -{ - ulong secs; - int i; - int *d2m; - - secs = 0; - - /* - * seconds per year - */ - for(i = 1970; i < rtc->year; i++){ - d2m = yrsize(i); - secs += d2m[0] * SEC2DAY; - } - - /* - * seconds per month - */ - d2m = yrsize(rtc->year); - for(i = 1; i < rtc->mon; i++) - secs += d2m[i] * SEC2DAY; - - secs += (rtc->mday-1) * SEC2DAY; - secs += rtc->hour * SEC2HOUR; - secs += rtc->min * SEC2MIN; - secs += rtc->sec; - - return secs; -} - -/* - * compute rtc from seconds since Jan 1 1970 - */ -void -sec2rtc(ulong secs, Rtc *rtc) -{ - int d; - long hms, day; - int *d2m; - - /* - * break initial number into days - */ - hms = secs % SEC2DAY; - day = secs / SEC2DAY; - if(hms < 0) { - hms += SEC2DAY; - day -= 1; - } - - /* - * generate hours:minutes:seconds - */ - rtc->sec = hms % 60; - d = hms / 60; - rtc->min = d % 60; - d /= 60; - rtc->hour = d; - - /* - * year number - */ - if(day >= 0) - for(d = 1970; day >= *yrsize(d); d++) - day -= *yrsize(d); - else - for (d = 1970; day < 0; d--) - day += *yrsize(d-1); - rtc->year = d; - - /* - * generate month - */ - d2m = yrsize(rtc->year); - for(d = 1; day >= d2m[d]; d++) - day -= d2m[d]; - rtc->mday = day + 1; - rtc->mon = d; - - return; -} diff --git a/ss/faultsparc.c b/ss/faultsparc.c deleted file mode 100644 index 01c4deef19eba96f4e61d0d969ff2400d097f5b5..0000000000000000000000000000000000000000 --- a/ss/faultsparc.c +++ /dev/null @@ -1,88 +0,0 @@ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "ureg.h" -#include "../port/error.h" - -enum -{ - SE_WRITE = 0x8000, - SE_INV = 0x0080, - SE_PROT = 0x0040, -}; - -void -faultsparc(Ureg *ur) -{ - ulong addr, badvaddr; - char buf[ERRLEN]; - int user, read; - ulong tbr, ser; - - tbr = (ur->tbr&0xFFF)>>4; - addr = ur->pc; /* assume instr. exception */ - read = 1; - if(tbr == 9){ /* data access exception */ - /* - * According to the book, this isn't good enough. We'll see. - */ - addr = getsysspace(SEVAR); - ser = getsysspace(SER); - if(ser&(SE_WRITE|SE_PROT)) - read = 0; - } - - spllo(); - if(u == 0){ - dumpregs(ur); - panic("fault u==0 pc=%lux addr=%lux", ur->pc, addr); - } - - badvaddr = addr; - addr &= ~(BY2PG-1); - user = !(ur->psr&PSRPSUPER); - - if(fault(addr, read) < 0){ - if(user){ - sprint(buf, "sys: trap: fault %s addr=0x%lux", - read? "read" : "write", badvaddr); - postnote(u->p, 1, buf, NDebug); - return; - } - dumpregs(ur); - panic("fault: 0x%lux", badvaddr); - } - splhi(); -} - -void -faultasync(Ureg *ur) -{ - int user; - - print("interrupt 15 ASER %lux ASEVAR %lux SER %lux\n", getsysspace(ASER), getsysspace(ASEVAR), getsysspace(SER)); - dumpregs(ur); - /* - * Clear interrupt by toggling low bit of interrupt register - */ - *intrreg &= ~1; - *intrreg |= 1; - user = !(ur->psr&PSRPSUPER); - if(user) - pexit("Suicide", 0); - panic("interrupt 15"); -} - -/* - * called in sysfile.c - */ -void -evenaddr(ulong addr) -{ - if(addr & 3){ - postnote(u->p, 1, "sys: odd address", NDebug); - error(Ebadarg); - } -} diff --git a/ss/fns.h b/ss/fns.h deleted file mode 100644 index 8ff54845f2aac9dd183510e0dd9289a33acf5f5b..0000000000000000000000000000000000000000 --- a/ss/fns.h +++ /dev/null @@ -1,91 +0,0 @@ -#include "../port/portfns.h" - -void bootargs(ulong); -void cacheinit(void); -ulong call(void*, ...); -void clearftt(ulong); -#define clearmmucache() -void clockinit(void); -void compile(void); -void disabfp(void); -void enabfp(void); -void evenaddr(ulong); -char* excname(ulong); -void faultasync(Ureg*); -void faultsparc(Ureg*); -void flushcpucache(void); -int fpcr(int); -int fpquiet(void); -void fpregrestore(char*); -void fpregsave(char*); -void fprestore(FPsave*); -void fpsave(FPsave*); -int fptrap(void); -int getfpq(ulong*); -ulong getfsr(void); -ulong getpsr(void); -void intrinit(void); -void ioinit(void); -int kbdstate(IOQ*, int); -void kbdclock(void); -void kbdrepeat(int); -KMap* kmap(Page*); -#define KADDR(a) ((void*)((ulong)(a)|KZERO)) -#define PADDR(a) ((ulong)(a)&~KZERO) -void kmapinit(void); -KMap* kmappa(ulong, ulong); -KMap* kmapperm(Page*); -ulong kmapregion(ulong, ulong, ulong); -int kprint(char*, ...); -void kproftimer(ulong); -void kunmap(KMap*); -void lanceintr(void); -void lancesetup(Lance*); -void lancetoggle(void); -void mmuinit(void); -#define mmunewpage(x) -void mousebuttons(int); -void printinit(void); -#define procrestore(p) -#define procsave(p) -#define procsetup(x) ((p)->fpstate = FPinit) -void putcxsegm(int, ulong, int); -void putpmeg(ulong, ulong); -void putsegm(ulong, int); -void putstr(char*); -void putstrn(char*, long); -void puttbr(ulong); -void putw4(ulong, ulong); /* needed only at boot time */ -void systemreset(void); -void restfpregs(FPsave*, ulong); -void screeninit(char*, int); -void screenputc(int); -void screenputs(char*, int); -void scsiintr(void); -void setpsr(ulong); -void spldone(void); -ulong tas(ulong*); -void touser(ulong); -void trap(Ureg*); -void trapinit(void); -#define wbflush() /* mips compatibility */ -#define waserror() (u->nerrlab++, setlabel(&u->errlab[u->nerrlab-1])) -#define getcallerpc(x) _getcallerpc() -ulong _getcallerpc(void); - -/* - * compiled entry points - */ -extern ulong (*getcontext)(void); -extern void (*putcontext)(ulong); -extern void (*putenab)(ulong); -extern ulong (*getenab)(void); -extern ulong (*getsysspace)(ulong); -extern void (*putsysspace)(ulong, ulong); -extern uchar (*getsysspaceb)(ulong); -extern void (*putsysspaceb)(ulong, uchar); -extern ulong (*getsegspace)(ulong); -extern void (*putsegspace)(ulong, ulong); -extern ulong (*getpmegspace)(ulong); -extern void (*putpmegspace)(ulong, ulong); -extern ulong (*flushpg)(ulong); diff --git a/ss/fptrap.c b/ss/fptrap.c deleted file mode 100644 index 96803056935ebffa0eb844fbcca7f8e22fc5216d..0000000000000000000000000000000000000000 --- a/ss/fptrap.c +++ /dev/null @@ -1,252 +0,0 @@ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "ureg.h" -#include "io.h" -#include "../port/error.h" - -static int unfinished(FPsave*); -static void fixq(FPsave*, int); -extern void* bbmalloc(int); - -int -fptrap(void) -{ - int n, ret; - ulong fsr; - - n = getfpq(&u->fpsave.q[0].a); - if(n > NFPQ) - panic("FPQ %d\n", n); - /* - * If faulted during restart, recover PC for debugging - */ - if(u->fpsave.fppc) - u->fpsave.q[0].a = u->fpsave.fppc; - fsr = getfsr(); - savefpregs(&u->fpsave); - u->fpsave.fsr = fsr; - ret = 0; - switch((fsr>>14) & 7){ - case 2: - ret = unfinished(&u->fpsave); - break; - } - if(ret){ - enabfp(); /* savefpregs disables it */ - clearftt(fsr & ~0x1F); /* clear ftt and cexc */ - restfpregs(&u->fpsave, fsr); - enabfp(); /* restfpregs disables it */ - fixq(&u->fpsave, n); - } - return ret; -} - -static void -unpack(FPsave *f, int size, int reg, int *sign, int *exp) -{ - *sign = 1; - if(f->fpreg[reg] & 0x80000000) - *sign = -1; - switch(size){ - case 1: - *exp = ((f->fpreg[reg]>>23)&0xFF) - ((1<<7)-2); - break; - case 2: - if(reg & 1){ - pprint("unaligned double fp register\n"); - reg &= ~1; - } - *exp = ((f->fpreg[reg]>>20)&0x7FF) - ((1<<10)-2); - break; - case 3: - if(reg & 3){ - pprint("unaligned quad fp register\n"); - reg &= ~3; - } - *exp = ((f->fpreg[reg]>>16)&0x7FFF) - ((1<<14)-2); - break; - } -} - -static void -zeroreg(FPsave *f, int size, int reg, int sign) -{ - switch(size){ - case 1: - size = 4; - break; - case 2: - if(reg & 1) - reg &= ~1; - size = 8; - break; - case 3: - if(reg & 3) - reg &= ~3; - size = 16; - break; - } - memset(&f->fpreg[reg], 0, size); - if(sign < 0) - f->fpreg[reg] |= 0x80000000; -} - -static int -unfinished(FPsave *f) -{ - ulong instr; - int size, maxe, maxm, op, rd, rs1, rs2; - int sd, ss1, ss2; - int ed, es1, es2; - - instr = f->q[0].i; - if((instr&0xC1F80000) != 0x81A00000){ - bad: - pprint("unknown unfinished instruction %lux\n", instr); - return 0; - } - size = (instr>>5) & 0x3; - if(size == 0) - goto bad; - maxe = 0; - maxm = 0; - switch(size){ - case 1: - maxe = 1<<7; - maxm = 24; - break; - case 2: - maxe = 1<<10; - maxm = 53; - break; - case 3: - maxe = 1<<14; - maxm = 113; - break; - } - rd = (instr>>25) & 0x1F; - rs1 = (instr>>14) & 0x1F; - rs2 = (instr>>0) & 0x1F; - unpack(f, size, rs1, &ss1, &es1); - unpack(f, size, rs2, &ss2, &es2); - op = (instr>>7) & 0x7F; - ed = 0; - switch(op){ - case 0x11: /* FSUB */ - ss2 = -ss2; - case 0x10: /* FADD */ - if(es1<-(maxe-maxm) && es2<-(maxe-maxm)) - ed = -maxe; - if(es1 > es2) - sd = es1; - else - sd = es2; - break; - - case 0x13: /* FDIV */ - es2 = -es2; - case 0x12: /* FMUL */ - sd = 1; - if(ss1 != ss2) - sd = -1; - ed = es1 + es2; - break; - - case 0x31: /* F?TOS */ - case 0x32: /* F?TOD */ - case 0x33: /* F?TOQ */ - if(es2 == maxe) /* NaN or Inf */ - return 0; - sd = ss2; - ed = es2; /* if underflow, this will do the trick */ - break; - - default: - goto bad; - } - if(ed <= -(maxe-5)){ /* guess: underflow */ - zeroreg(f, size, rd, sd); - return 1; - } - return 0; -} - -static void -fixq(FPsave *f, int n) -{ - ulong instr; - ulong *ip; - - while(n > 1){ - --n; - memmove(&f->q[0], &f->q[1], n*sizeof f->q[0]); - memset(&f->q[n], 0, (NFPQ-n)*sizeof f->q[0]); - instr = f->q[0].i; - /* - * Sparc says you have to emulate. To hell with that. - * We can compile on the fly instead. - * Run one instruction and wait for it to complete or trap. - * If it traps, we'll recurse but we won't overwrite - * our own data structures because there will be only - * one instruction uncompleted in the FPU. - * If that instruction generates an unfixable trap, - * stop the processing, which means a buglet: if the user - * process is attempting to resolve FP errors, it must - * find and extract the uncompleted instructions behind - * the trap by examining the non-zero members of the FPQ. - * Tough. - */ - ip = bbmalloc(3*sizeof(ulong)); - ip[0] = instr; - ip[1] = 0x81c3e008; /* JMPL #8(R15), R0 [RETURN] */ - ip[2] = 0x01000000; /* SETHI #0, R0 [NOP] */ - f->fppc = f->q[0].a; - (*(void(*)(void))ip)(); /* You are expected to understand this cast */ - f->fppc = 0; - if(!fpquiet()) - break; - } -} - -/* - * Must only be called splhi() when it is safe to spllo(). Because the FP unit - * traps if you touch it when an exception is pending, and because if you - * trap with ET==0 you halt, this routine sets some global flags to enable - * the rest of the system to handle the trap that might occur here without - * upsetting the kernel. Shouldn't be necessary, but safety first. - */ -int -fpquiet(void) -{ - int i, notrap; - ulong fsr; - char buf[128]; - - i = 0; - notrap = 1; - m->fpunsafe = 1; - u->p->fpstate = FPinactive; - for(;;){ - m->fptrap = 0; - fsr = getfsr(); - if(m->fptrap){ - /* trap occurred and u->fpsave contains state */ - sprint(buf, "sys: %s", excname(8)); - postnote(u->p, 1, buf, NDebug); - notrap = 0; - break; - } - if((fsr&(1<<13)) == 0) - break; - if(++i > 1000){ - print("fp not quiescent\n"); - break; - } - } - m->fpunsafe = 0; - u->p->fpstate = FPactive; - return notrap; -} diff --git a/ss/io.h b/ss/io.h deleted file mode 100644 index 95b92b67e77bf171511dbe8950b891eea1e1f2af..0000000000000000000000000000000000000000 --- a/ss/io.h +++ /dev/null @@ -1,150 +0,0 @@ -#define SBUS(n) (0xF8000000+(n)*0x2000000) -#define FRAMEBUF(n) SBUS(n) -#define FRAMEBUFID(n) (SBUS(n)+0x000000) -#define DISPLAYRAM(n) (SBUS(n)+0x800000) -#define EPROM 0xF6000000 -#define CLOCK 0xF3000000 -#define CLOCKFREQ 1000000 /* one microsecond increments */ -#define KMDUART 0xF0000000 /* keyboard A, mouse B */ -#define EIADUART 0xF1000000 /* serial ports */ -#define NVRAM 0xF2000000 /* non-volatile RAM */ -#define DMA 0xF8400000 /* DMA registers */ -#define SCSI 0xF8800000 /* NCR53C90 registers */ -#define ETHER 0xF8C00000 /* RDP, RAP */ -#define EEPROM 0xF2000000 -#define INTRREG 0xF5000000 /* interrupt register, IO space */ - -typedef struct SCCdev SCCdev; -struct SCCdev -{ - uchar ptrb; - uchar dummy1; - uchar datab; - uchar dummy2; - uchar ptra; - uchar dummy3; - uchar dataa; - uchar dummy4; -}; - -#define KMFREQ 10000000 /* crystal frequency for kbd/mouse 8530 */ -#define EIAFREQ 5000000 /* crystal frequency for serial port 8530 */ - -/* - * non-volatile ram - */ -#define NVREAD (2048-8) /* minus RTC */ -#define NVWRITE (2048-8-32) /* minus RTC, minus ID prom */ - -/* - * real-time clock - */ -typedef struct RTCdev RTCdev; -struct RTCdev -{ - uchar control; /* read or write the device */ - uchar sec; - uchar min; - uchar hour; - uchar wday; - uchar mday; - uchar mon; - uchar year; -}; -#define RTCOFF 0x7F8 -#define RTCREAD (0x40) -#define RTCWRITE (0x80) - -/* - * dma - */ -typedef struct DMAdev DMAdev; -struct DMAdev { - ulong csr; /* Control/Status */ - ulong addr; /* address in 16Mb segment */ - ulong count; /* transfer byte count */ - ulong diag; -}; - -enum { - Int_pend = 0x00000001, /* interrupt pending */ - Err_pend = 0x00000002, /* error pending */ - Pack_cnt = 0x0000000C, /* pack count (mask) */ - Int_en = 0x00000010, /* interrupt enable */ - Dma_Flush = 0x00000020, /* flush pack end error */ - Drain = 0x00000040, /* drain pack to memory */ - Dma_Reset = 0x00000080, /* hardware reset (sticky) */ - Write = 0x00000100, /* set for device to memory (!) */ - En_dma = 0x00000200, /* enable DMA */ - Req_pend = 0x00000400, /* request pending */ - Byte_addr = 0x00001800, /* next byte addr (mask) */ - En_cnt = 0x00002000, /* enable count */ - Tc = 0x00004000, /* terminal count */ - Ilacc = 0x00008000, /* which ether chip */ - Dev_id = 0xF0000000, /* device ID */ -}; - -/* - * NCR53C90 SCSI controller (every 4th location) - */ -typedef struct SCSIdev SCSIdev; -struct SCSIdev { - uchar countlo; /* byte count, low bits */ - uchar pad1[3]; - uchar countmi; /* byte count, middle bits */ - uchar pad2[3]; - uchar fifo; /* data fifo */ - uchar pad3[3]; - uchar cmd; /* command byte */ - uchar pad4[3]; - union { - struct { /* read only... */ - uchar status; /* status */ - uchar pad05[3]; - uchar intr; /* interrupt status */ - uchar pad06[3]; - uchar step; /* sequence step */ - uchar pad07[3]; - uchar fflags; /* fifo flags */ - uchar pad08[3]; - uchar config; /* RW: configuration */ - uchar pad09[3]; - uchar Reserved1; - uchar pad0A[3]; - uchar Reserved2; - uchar pad0B[3]; - uchar conf2; /* RW: configuration */ - uchar pad0C[3]; - uchar conf3; /* RW: configuration */ - uchar pad0D[3]; - uchar partid; /* unique part id */ - uchar pad0E[3]; - uchar fbottom; /* RW: fifo bottom */ - uchar pad0F[3]; - }; - struct { /* write only... */ - uchar destid; /* destination id */ - uchar pad15[3]; - uchar timeout; /* during selection */ - uchar pad16[3]; - uchar syncperiod; /* synchronous xfr period */ - uchar pad17[3]; - uchar syncoffset; /* synchronous xfr offset */ - uchar pad18[3]; - uchar RW0; - uchar pad19[3]; - uchar clkconf; - uchar pad1A[3]; - uchar test; - uchar pad1B[3]; - uchar RW1; - uchar pad1C[3]; - uchar RW2; - uchar pad1D[3]; - uchar counthi; /* byte count, hi bits */ - uchar pad1E[3]; - uchar RW3; - uchar pad1F[3]; - }; - }; -}; diff --git a/ss/l.s b/ss/l.s deleted file mode 100644 index d534b847916ac60c6ebfd4cc7f428a866026efd0..0000000000000000000000000000000000000000 --- a/ss/l.s +++ /dev/null @@ -1,520 +0,0 @@ -#include "mem.h" - -#define SYSPSR (PSREF|PSRET|PSRSUPER|SPL(15)) -#define NOOP ORN R0, R0; ORN R0, R0; ORN R0, R0 - -TEXT start(SB), $-4 - - /* get virtual, fast */ - /* we are executing in segment 0, mapped to pmeg 0. stack is there too */ - /* get virtual by mapping segment(KZERO) to pmeg 0, and next to 1, etc. */ - MOVW $KZERO, R7 - MOVB R0, (R7, 3) - ADD $(BY2SEGM), R7 - MOVW $1, R9 - MOVB R9, (R7, 3) - ADD $(BY2SEGM), R7 - MOVW $2, R9 - MOVB R9, (R7, 3) - ADD $(BY2SEGM), R7 - MOVW $3, R9 - MOVB R9, (R7, 3) - /* now mapped correctly. jmpl to where we want to be */ - MOVW $setSB(SB), R2 - - MOVW $startvirt(SB), R7 - JMPL (R7) - MOVW $_mul(SB), R0 /* touch _mul etc.; doesn't need to execute */ - RETURN /* can't get here */ - -TEXT startvirt(SB), $-4 - - MOVW $rom(SB), R7 - MOVW R8, (R7) /* romvec passed in %i0==R8 */ - - /* turn off the cache */ - MOVW $ENAB, R7 - MOVB (R7, 2), R8 - ANDN $ENABCACHE, R8 - MOVB R8, (R7, 2) - - MOVW $BOOTSTACK, R1 - - MOVW $(SPL(0xF)|PSREF|PSRSUPER), R7 - MOVW R7, PSR - - MOVW $(0x35<<22), R7 /* NVM OFM DZM NS */ - MOVW R7, fsr+0(SB) - MOVW $fsr+0(SB), R8 - MOVW (R8), FSR - FMOVD $0.5, F26 /* 0.5 -> F26 */ - FSUBD F26, F26, F24 /* 0.0 -> F24 */ - FADDD F26, F26, F28 /* 1.0 -> F28 */ - FADDD F28, F28, F30 /* 2.0 -> F30 */ - - FMOVD F24, F0 - FMOVD F24, F2 - FMOVD F24, F4 - FMOVD F24, F6 - FMOVD F24, F8 - FMOVD F24, F10 - FMOVD F24, F12 - FMOVD F24, F14 - FMOVD F24, F16 - FMOVD F24, F18 - FMOVD F24, F20 - FMOVD F24, F22 - - MOVW $mach0(SB), R(MACH) -/* MOVW $0x8, R7 /**/ - MOVW R0, WIM - JMPL main(SB) - MOVW (R0), R0 - RETURN - -TEXT oldtas(SB), $0 - - TAS (R7), R7 /* LDSTUB, thank you ken */ - RETURN - -TEXT tas(SB), $0 /* it seems we must be splhi */ - - MOVW PSR, R8 - MOVW $SYSPSR, R9 - MOVW R9, PSR - NOOP - TAS (R7), R7 /* LDSTUB, thank you ken */ - MOVW R8, PSR - NOOP - RETURN - -TEXT softtas(SB), $0 /* all software; avoid LDSTUB */ - - MOVW PSR, R8 - MOVW $SYSPSR, R9 - MOVW R9, PSR - NOOP - MOVB (R7), R10 - CMP R10, R0 - BE gotit -#ifdef asdf - ANDN $31, R7 /* flush cache line */ - MOVW $0, (R7, 0xD) -#endif - MOVW $0xFF, R7 - MOVW R8, PSR - NOOP - RETURN - -gotit: - MOVW $0xFF, R10 - MOVB R10, (R7) -#ifdef asdf - ANDN $31, R7 /* flush cache line */ - MOVW $0, (R7, 0xD) -#endif - MOVW $0, R7 - MOVW R8, PSR - NOOP - RETURN - -TEXT spllo(SB), $0 - - MOVW PSR, R7 - MOVW R7, R10 - ANDN $SPL(15), R10 - MOVW R10, PSR - NOOP - RETURN - -TEXT splhi(SB), $0 - - MOVW R15, 4(R(MACH)) /* save PC in m->splpc */ - MOVW PSR, R7 - MOVW R7, R10 - OR $SPL(15), R10 - MOVW R10, PSR - NOOP - RETURN - -TEXT splx(SB), $0 - - MOVW R15, 4(R(MACH)) /* save PC in m->splpc */ - MOVW R7, PSR /* BUG: book says this is buggy */ - NOOP - RETURN - -TEXT spldone(SB), $0 - - RETURN - -TEXT touser(SB), $0 - MOVW $(SYSPSR&~(PSREF|PSRET|SPL(15))), R8 - MOVW R8, PSR - NOOP - - MOVW R7, R1 - SAVE R0, R0 /* RETT is implicit RESTORE */ - MOVW $(UTZERO+32), R7 /* PC; header appears in text */ - MOVW $(UTZERO+32+4), R8 /* nPC */ - RETT R7, R8 - -TEXT rfnote(SB), $0 - - MOVW R7, R1 /* 1st arg is &uregpointer */ - ADD $4, R1 /* point at ureg */ - JMP restore - -TEXT traplink(SB), $-4 - - /* R8 to R23 are free to play with */ - /* R17 contains PC, R18 contains nPC */ - /* R19 has PSR loaded from vector code */ - - ANDCC $PSRPSUPER, R19, R0 - BE usertrap - -kerneltrap: - /* - * Interrupt or fault from kernel - */ - ANDN $7, R1, R20 /* dbl aligned */ - MOVW R1, (0-(4*(32+6))+(4*1))(R20) /* save R1=SP */ - /* really clumsy: store these in Ureg so can be restored below */ - MOVW R2, (0-(4*(32+6))+(4*2))(R20) /* SB */ - MOVW R5, (0-(4*(32+6))+(4*5))(R20) /* USER */ - MOVW R6, (0-(4*(32+6))+(4*6))(R20) /* MACH */ - SUB $(4*(32+6)), R20, R1 - -trap1: - MOVW Y, R20 - MOVW R20, (4*(32+0))(R1) /* Y */ - MOVW TBR, R20 - MOVW R20, (4*(32+1))(R1) /* TBR */ - AND $~0x1F, R19 /* force CWP=0 */ - MOVW R19, (4*(32+2))(R1) /* PSR */ - MOVW R18, (4*(32+3))(R1) /* nPC */ - MOVW R17, (4*(32+4))(R1) /* PC */ - MOVW R0, (4*0)(R1) - MOVW R3, (4*3)(R1) - MOVW R4, (4*4)(R1) - MOVW R7, (4*7)(R1) - RESTORE R0, R0 - /* now our registers R8-R31 are same as before trap */ - /* save registers two at a time */ - MOVD R8, (4*8)(R1) - MOVD R10, (4*10)(R1) - MOVD R12, (4*12)(R1) - MOVD R14, (4*14)(R1) - MOVD R16, (4*16)(R1) - MOVD R18, (4*18)(R1) - MOVD R20, (4*20)(R1) - MOVD R22, (4*22)(R1) - MOVD R24, (4*24)(R1) - MOVD R26, (4*26)(R1) - MOVD R28, (4*28)(R1) - MOVD R30, (4*30)(R1) - /* SP and SB and u and m are already set; away we go */ - MOVW R1, R7 /* pointer to Ureg */ - SUB $8, R1 - MOVW $SYSPSR, R8 - MOVW R8, PSR - NOOP - JMPL trap(SB) - - ADD $8, R1 -restore: - MOVW (4*(32+2))(R1), R8 /* PSR */ - MOVW R8, PSR - NOOP - - MOVD (4*30)(R1), R30 - MOVD (4*28)(R1), R28 - MOVD (4*26)(R1), R26 - MOVD (4*24)(R1), R24 - MOVD (4*22)(R1), R22 - MOVD (4*20)(R1), R20 - MOVD (4*18)(R1), R18 - MOVD (4*16)(R1), R16 - MOVD (4*14)(R1), R14 - MOVD (4*12)(R1), R12 - MOVD (4*10)(R1), R10 - MOVD (4*8)(R1), R8 - SAVE R0, R0 - MOVD (4*6)(R1), R6 - MOVD (4*4)(R1), R4 - MOVD (4*2)(R1), R2 - MOVW (4*(32+0))(R1), R20 /* Y */ - MOVW R20, Y - MOVW (4*(32+4))(R1), R17 /* PC */ - MOVW (4*(32+3))(R1), R18 /* nPC */ - MOVW (4*1)(R1), R1 /* restore R1=SP */ - RETT R17, R18 - -usertrap: - /* - * Interrupt or fault from user - */ - MOVW R1, R8 - MOVW R2, R9 - MOVW $setSB(SB), R2 - MOVW $(USERADDR+BY2PG), R1 - MOVW R8, (0-(4*(32+6))+(4*1))(R1) /* save R1=SP */ - MOVW R9, (0-(4*(32+6))+(4*2))(R1) /* save R2=SB */ - MOVW R5, (0-(4*(32+6))+(4*5))(R1) /* save R5=USER */ - MOVW R6, (0-(4*(32+6))+(4*6))(R1) /* save R6=MACH */ - MOVW $USERADDR, R(USER) - MOVW $mach0(SB), R(MACH) - SUB $(4*(32+6)), R1 - JMP trap1 - -TEXT syslink(SB), $-4 - - /* R8 to R23 are free to play with */ - /* R17 contains PC, R18 contains nPC */ - /* R19 has PSR loaded from vector code */ - /* assume user did it; syscall checks */ - - MOVW R1, R8 - MOVW R2, R9 - MOVW $setSB(SB), R2 - MOVW $(USERADDR+BY2PG), R1 - MOVW R8, (0-(4*(32+6))+4)(R1) /* save R1=SP */ - SUB $(4*(32+6)), R1 - MOVW R9, (4*2)(R1) /* save R2=SB */ - MOVW R3, (4*3)(R1) /* global register */ - MOVD R4, (4*4)(R1) /* global register, R5=USER */ - MOVD R6, (4*6)(R1) /* save R6=MACH, R7=syscall# */ - MOVW $USERADDR, R(USER) - MOVW $mach0(SB), R(MACH) - MOVW TBR, R20 - MOVW R20, (4*(32+1))(R1) /* TBR */ - AND $~0x1F, R19 - MOVW R19, (4*(32+2))(R1) /* PSR */ - MOVW R18, (4*(32+3))(R1) /* nPC */ - MOVW R17, (4*(32+4))(R1) /* PC */ - RESTORE R0, R0 - /* now our registers R8-R31 are same as before trap */ - MOVW R15, (4*15)(R1) - /* SP and SB and u and m are already set; away we go */ - MOVW R1, R7 /* pointer to Ureg */ - SUB $8, R1 - MOVW $SYSPSR, R8 - MOVW R8, PSR - JMPL syscall(SB) - /* R7 contains return value from syscall */ - - ADD $8, R1 - MOVW (4*(32+2))(R1), R8 /* PSR */ - MOVW R8, PSR - NOOP - - MOVW (4*15)(R1), R15 - SAVE R0, R0 - MOVW (4*6)(R1), R6 - MOVD (4*4)(R1), R4 - MOVD (4*2)(R1), R2 - MOVW (4*(32+4))(R1), R17 /* PC */ - MOVW (4*(32+3))(R1), R18 /* nPC */ - MOVW (4*1)(R1), R1 /* restore R1=SP */ - RETT R17, R18 - -TEXT puttbr(SB), $0 - - MOVW R7, TBR - NOOP - RETURN - -TEXT gettbr(SB), $0 - - MOVW TBR, R7 - RETURN - -TEXT r1(SB), $0 - - MOVW R1, R7 - RETURN - -TEXT getwim(SB), $0 - - MOVW WIM, R7 - RETURN - -TEXT setlabel(SB), $0 - - MOVW R1, (R7) - MOVW R15, 4(R7) - MOVW $0, R7 - RETURN - -TEXT gotolabel(SB), $0 - - MOVW (R7), R1 - MOVW 4(R7), R15 - MOVW $1, R7 - RETURN - -TEXT putcxsegm(SB), $0 - - MOVW R7, R8 /* context */ - MOVW 4(FP), R9 /* segment addr */ - MOVW 8(FP), R10 /* segment value */ - MOVW $romputcxsegm(SB), R7 - MOVW (R7), R7 - JMPL (R7) - RETURN - -TEXT putw4(SB), $0 - MOVW 4(FP), R8 - MOVW R8, (R7, 4) - RETURN - -TEXT getpsr(SB), $0 - - MOVW PSR, R7 - RETURN - -TEXT setpsr(SB), $0 - - MOVW R7, PSR - NOOP - RETURN - -TEXT putsegm(SB), $0 - - MOVW 4(FP), R8 - MOVW R8, (R7, 3) - RETURN - -TEXT savefpregs(SB), $0 - - MOVW FSR, 0(R7) - ADD $4, R7 - - MOVD F0, (0*4)(R7) - MOVD F2, (2*4)(R7) - MOVD F4, (4*4)(R7) - MOVD F6, (6*4)(R7) - MOVD F8, (8*4)(R7) - MOVD F10, (10*4)(R7) - MOVD F12, (12*4)(R7) - MOVD F14, (14*4)(R7) - MOVD F16, (16*4)(R7) - MOVD F18, (18*4)(R7) - MOVD F20, (20*4)(R7) - MOVD F22, (22*4)(R7) - MOVD F24, (24*4)(R7) - MOVD F26, (26*4)(R7) - MOVD F28, (28*4)(R7) - MOVD F30, (30*4)(R7) - - MOVW PSR, R8 - ANDN $PSREF, R8 - MOVW R8, PSR - RETURN - -TEXT enabfp(SB), $0 - - MOVW PSR, R8 - OR $PSREF, R8 - MOVW R8, PSR - RETURN - -TEXT disabfp(SB), $0 - - MOVW PSR, R8 - ANDN $PSREF, R8 - MOVW R8, PSR - RETURN - -TEXT restfpregs(SB), $0 - - MOVW PSR, R8 - OR $PSREF, R8 - MOVW R8, PSR - - NOOP /* wait for PSR to quiesce */ - MOVW fsr+4(FP), FSR - ADD $4, R7 - - MOVD (0*4)(R7), F0 - MOVD (2*4)(R7), F2 - MOVD (4*4)(R7), F4 - MOVD (6*4)(R7), F6 - MOVD (8*4)(R7), F8 - MOVD (10*4)(R7), F10 - MOVD (12*4)(R7), F12 - MOVD (14*4)(R7), F14 - MOVD (16*4)(R7), F16 - MOVD (18*4)(R7), F18 - MOVD (20*4)(R7), F20 - MOVD (22*4)(R7), F22 - MOVD (24*4)(R7), F24 - MOVD (26*4)(R7), F26 - MOVD (28*4)(R7), F28 - MOVD (30*4)(R7), F30 - - ANDN $PSREF, R8 - MOVW R8, PSR - RETURN - -TEXT getfpq(SB), $0 - - MOVW R7, R8 /* must be D aligned */ - MOVW $fsr+0(SB), R9 - MOVW $0, R7 -getfpq1: - MOVW FSR, (R9) - MOVW (R9), R10 - ANDCC $(1<<13), R10 /* queue not empty? */ - BE getfpq2 - MOVW (R8), R0 /* SS2 bug fix */ - MOVD FQ, (R8) - ADD $1, R7 - ADD $8, R8 - BA getfpq1 -getfpq2: - RETURN - -TEXT getfsr(SB), $0 - MOVW $fsr+0(SB), R7 - MOVW FSR, (R7) - MOVW (R7), R7 - RETURN - -TEXT clearftt(SB), $0 - MOVW R7, fsr+0(SB) - MOVW $fsr+0(SB), R7 - MOVW (R7), FSR - FMOVF F0, F0 - RETURN - -TEXT _getcallerpc(SB), $0 - MOVW 0(R1), R7 - RETURN - -GLOBL mach0+0(SB), $MACHSIZE -GLOBL fsr+0(SB), $BY2WD - -/* - * Interface to OPEN BOOT ROM. Must save and restore state because - * of different calling conventions. We don't use it, but it's here - * for reference.. - */ - -TEXT call(SB), $16 - MOVW R1, R14 /* save my SP in their SP */ - MOVW R2, sb-4(SP) - MOVW R(MACH), mach-8(SP) - MOVW R(USER), user-12(SP) - MOVW param1+4(FP), R8 - MOVW param2+8(FP), R9 - MOVW param3+12(FP), R10 - MOVW param4+16(FP), R11 - JMPL (R7) - MOVW R14, R1 /* restore my SP */ - MOVW user-12(SP), R(USER) - MOVW mach-8(SP), R(MACH) - MOVW sb-4(SP), R2 - MOVW R8, R7 /* move their return value into mine */ - RETURN diff --git a/ss/main.c b/ss/main.c deleted file mode 100644 index d3e39736a8a21d0777d615a7d73aee4807a3a3f5..0000000000000000000000000000000000000000 --- a/ss/main.c +++ /dev/null @@ -1,536 +0,0 @@ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "io.h" -#include "init.h" - -#include -#include - -uchar *intrreg; -uchar idprom[32]; -ulong rom; /* open boot rom vector */ -int cpuserver; -ulong romputcxsegm; -ulong bank[2]; -char mempres[256]; -char fbstr[32]; -ulong fbslot; -Label catch; -uchar *sp; - -typedef struct Sysparam Sysparam; -struct Sysparam -{ - int id; /* Model type from id prom */ - char *name; /* System name */ - char ss2; /* Is Sparcstation 2? */ - int vacsize; /* Cache size */ - int vacline; /* Cache line size */ - int ncontext; /* Number of MMU contexts */ - int npmeg; /* Number of page map entry groups */ - char cachebug; /* Machine needs cache bug work around */ - int memscan; /* Number of Meg to scan looking for memory */ -} -sysparam[] = -{ - { 0x51, "1 4/60", 0, 65536, 16, 8, 128, 0, 64 }, - { 0x52, "IPC 4/40", 0, 65536, 16, 8, 128, 0, 64 }, - { 0x53, "1+ 4/65", 0, 65536, 16, 8, 128, 0, 64 }, - { 0x54, "SLC 4/20", 0, 65536, 16, 8, 128, 0, 64 }, - { 0x55, "2 4/75", 1, 65536, 32, 16, 256, 1, 64 }, - { 0x56, "ELC 4/25", 1, 65536, 32, 8, 128, 1, 64 }, - { 0x57, "IPX 4/50", 1, 65536, 32, 8, 256, 1, 64 }, - { 0 } -}; -Sysparam *sparam; - -void -main(void) -{ - u = 0; - memset(edata, 0, (char*)end-(char*)edata); - - machinit(); - active.exiting = 0; - active.machs = 1; - trapinit(); - confinit(); - xinit(); - mmuinit(); - kmapinit(); - if(conf.monitor) - screeninit(fbstr, fbslot); - printinit(); - ioinit(); - if(conf.monitor == 0) - sccspecial(2, &printq, &kbdq, 9600); - pageinit(); - cacheinit(); - intrinit(); - procinit0(); - initseg(); - chandevreset(); - streaminit(); - swapinit(); - userinit(); - clockinit(); - schedinit(); -} - -void -intrinit(void) -{ - KMap *k; - - k = kmappa(INTRREG, PTEIO|PTENOCACHE); - intrreg = (uchar*)k->va; -} - -void -systemreset(void) -{ - delay(200); - putenab(ENABRESET); -} - - -void -machinit(void) -{ - int n; - - n = m->machno; - memset(m, 0, sizeof(Mach)); - m->machno = n; - m->mmask = 1<machno; - m->fpstate = FPinit; -} - -void -ioinit(void) -{ - KMap *k; - - /* tell scc driver its addresses */ - k = kmappa(KMDUART, PTEIO|PTENOCACHE); - sccsetup((void*)(k->va), KMFREQ, 1); - k = kmappa(EIADUART, PTEIO|PTENOCACHE); - sccsetup((void*)(k->va), EIAFREQ, 1); - - /* scc port 0 is the keyboard */ - sccspecial(0, 0, &kbdq, 2400); - kbdq.putc = kbdstate; - - /* scc port 1 is the mouse */ - sccspecial(1, 0, &mouseq, 2400); -} - -void -init0(void) -{ - u->nerrlab = 0; - m->proc = u->p; - u->p->state = Running; - u->p->mach = m; - spllo(); - - print("Sun Sparcstation %s\n", sparam->name); - print("bank 0: %dM 1: %dM\n", bank[0], bank[1]); - print("frame buffer id %lux slot %ld %s\n", conf.monitor, fbslot, fbstr); - - u->slash = (*devtab[0].attach)(0); - u->dot = clone(u->slash, 0); - - kproc("alarm", alarmkproc, 0); - chandevinit(); - - if(!waserror()){ - ksetterm("sun %s"); - ksetenv("cputype", "sparc"); - poperror(); - } - - touser((long)sp); -} - -FPsave *initfpp; -uchar initfpa[sizeof(FPsave)+7]; - -void -userinit(void) -{ - Proc *p; - Segment *s; - User *up; - KMap *k; - ulong l; - Page *pg; - - p = newproc(); - p->pgrp = newpgrp(); - p->egrp = smalloc(sizeof(Egrp)); - p->egrp->ref = 1; - p->fgrp = smalloc(sizeof(Fgrp)); - p->fgrp->ref = 1; - p->procmode = 0640; - - strcpy(p->text, "*init*"); - strcpy(p->user, eve); - /* must align initfpp to an ODD word boundary */ - l = (ulong)initfpa; - l += 3; - l &= ~7; - l += 4; - initfpp = (FPsave*)l; - savefpregs(initfpp); - p->fpstate = FPinit; - - /* - * Kernel Stack - */ - p->sched.pc = (((ulong)init0) - 8); /* 8 because of RETURN in gotolabel */ - p->sched.sp = USERADDR+BY2PG-(1+MAXSYSARG)*BY2WD; - p->sched.sp &= ~7; /* SP must be 8-byte aligned */ - p->upage = newpage(1, 0, USERADDR|(p->pid&0xFFFF)); - - /* - * User - */ - k = kmap(p->upage); - up = (User*)VA(k); - up->p = p; - kunmap(k); - - /* - * User Stack - */ - s = newseg(SG_STACK, USTKTOP-BY2PG, 1); - p->seg[SSEG] = s; - pg = newpage(1, 0, USTKTOP-BY2PG); - segpage(s, pg); - k = kmap(pg); - bootargs(VA(k)); - kunmap(k); - - /* - * Text - */ - s = newseg(SG_TEXT, UTZERO, 1); - p->seg[TSEG] = s; - segpage(s, newpage(1, 0, UTZERO)); - k = kmap(s->map[0]->pages[0]); - memmove((ulong*)VA(k), initcode, sizeof initcode); - kunmap(k); - - ready(p); -} - -uchar * -pusharg(char *p) -{ - int n; - - n = strlen(p)+1; - sp -= n; - memmove(sp, p, n); - return sp; -} - -void -bootargs(ulong base) -{ - int i, ac; - uchar *av[32]; - uchar **lsp; - - sp = (uchar*)base + BY2PG - MAXSYSARG*BY2WD; - - ac = 0; - av[ac++] = pusharg("/sparc/9ss"); - av[ac++] = pusharg("-p"); - - /* 4 byte word align stack */ - sp = (uchar*)((ulong)sp & ~3); - - /* build argc, argv on stack */ - sp -= (ac+1)*sizeof(sp); - lsp = (uchar**)sp; - for(i = 0; i < ac; i++) - *lsp++ = av[i] + ((USTKTOP - BY2PG) - base); - *lsp = 0; - sp += (USTKTOP - BY2PG) - base - sizeof(sp); -} - -void -exit(int ispanic) -{ - int i; - - u = 0; - spllo(); - print("cpu %d exiting\n", m->machno); - while(consactive()) - for(i=0; i<1000; i++) - ; - splhi(); - if(ispanic) - for(;;); - systemreset(); -} - -void -scanmem(char *mempres, int n) -{ - int i; - ulong va, addr; - - va = 1*MB-2*BY2PG; - for(i=0; i MAXMACH) - panic("confinit"); - - /* map id prom */ - va = 1*MB-BY2PG; - putw4(va, PPN(EEPROM)|PTEPROBEIO); - memmove(idprom, (char*)(va+0x7d8), 32); - if(idprom[0]!=1 || (idprom[1]&0xF0)!=0x50) - *(ulong*)va = 0; /* not a sparcstation; die! */ - putw4(va, INVALIDPTE); - - /* - * Look for a frame buffer. Do it the way the - * ROM does it: scan the slots in a specified order and use - * the first one it finds. - * - * If we find a frame buffer, we always use it as a console - * rather than the attached terminal, if any. This means - * if you have a frame buffer you'd better have a builtin - * keyboard, too. - */ - switch(idprom[1]){ - case 0x52: /* IPC */ - case 0x54: /* SLC */ - conf.monitor = 1; - fbslot = 3; - strcpy(fbstr, "bwtwo"); - break; - case 0x57: /* IPX */ - conf.monitor = 1; - fbslot = 3; - strcpy(fbstr, "cgsix"); - break; - default: - /* map frame buffer id in SBUS slots 0..3 */ - for(f=0; f<=3 && fbstr[0]==0; f++){ - putw4(va, ((FRAMEBUFID(f)>>PGSHIFT)&0xFFFF)|PTEPROBEIO); - conf.monitor = 0; - /* if frame buffer not present, we will trap, so prepare to catch it */ - if(setlabel(&catch) == 0){ - conf.monitor = *(ulong*)va; - switch(conf.monitor & 0xF0FFFFFF){ - case 0xF0010101: - strcpy(fbstr, "cgthree"); - break; - case 0xF0010104: - strcpy(fbstr, "bwtwo"); - break; - } - if(fbstr[0] == 0){ - j = *(ulong*)(va+4); - if(j > BY2PG-8) - j = BY2PG - 8; /* -8 for safety */ - for(i=0; iid; sparam++) - if(sparam->id == idprom[1]) - break; - - /* First entry in the table is the default */ - if(sparam->id == 0) - sparam = sysparam; - - conf.ss2 = sparam->ss2; - conf.vacsize = sparam->vacsize; - conf.vaclinesize = sparam->vacline; - conf.ncontext = sparam->ncontext; - conf.npmeg = sparam->npmeg; - conf.ss2cachebug = sparam->cachebug; - - /* Chart memory */ - scanmem(mempres, sparam->memscan); - - /* Find mirrors and allocate banks */ - for(i=0; imemscan; i++) - if(mempres[i]){ - v = mempres[i]; - i = v-'0'; - for(j=i+1; jmemscan && mempres[j]>v; j++) - v = mempres[j]; - npg = (j-i)*MB/BY2PG; - if(conf.npage0 == 0){ - conf.base0 = i*MB; - conf.npage0 = npg; - }else if(conf.npage1 < npg){ - conf.base1 = i*MB; - conf.npage1 = npg; - } - i = v-'0'; - } - - bank[0] = conf.npage0*BY2PG/MB; - bank[1] = conf.npage1*BY2PG/MB; - - if(bank[1] == 0){ - /* - * This split of memory into 2 banks fools the allocator into - * allocating low memory pages from bank 0 for the ethernet since - * it has only a 24bit address counter. - * NB. Suns must have at LEAST 8Mbytes. - */ - conf.npage1 = conf.npage0 - (8*MB)/BY2PG; - conf.base1 = conf.base0 + 8*MB; - conf.npage0 = (8*MB)/BY2PG; - bank[1] = bank[0]-8; - bank[0] = 8; - } - conf.npage = conf.npage0+conf.npage1; - i = screenbits()-1; /* Calculate % of memory for page pool */ - i = 70 - (i*10); - conf.upages = (conf.npage*i)/100; - if(cpuserver){ - i = conf.npage-conf.upages; - if(i > (12*MB)/BY2PG) - conf.upages += i - ((12*MB)/BY2PG); - } - - romputcxsegm = *(ulong*)(rom+260); - - ktop = PGROUND((ulong)end); - ktop = PADDR(ktop); - conf.npage0 -= ktop/BY2PG; - conf.base0 += ktop; - - mbytes = (conf.npage*BY2PG)>>20; - mul = 1 + (mbytes+11)/12; - if(mul > 2) - mul = 2; - - conf.nproc = 50*mul; - if(cpuserver) - conf.nswap = conf.npage*2; - else - conf.nswap = 16*MB/BY2PG; - conf.nimage = 50; - conf.copymode = 0; /* copy on write */ - if(cpuserver) - conf.nproc = 500; -} - -/* - * set up the lance - */ -void -lancesetup(Lance *lp) -{ - KMap *k; - uchar *cp; - ulong pa, va; - int i; - - k = kmappa(ETHER, PTEIO|PTENOCACHE); - lp->rdp = (void*)(k->va+0); - lp->rap = (void*)(k->va+2); - k = kmappa(EEPROM, PTEIO|PTENOCACHE); - cp = (uchar*)(k->va+0x7da); - for(i=0; i<6; i++) - lp->ea[i] = *cp++; - kunmap(k); - - lp->lognrrb = 7; - lp->logntrb = 5; - lp->nrrb = 1<lognrrb; - lp->ntrb = 1<logntrb; - lp->sep = 1; - lp->busctl = BSWP | ACON | BCON; - - /* - * Allocate area for lance init block and descriptor rings - */ - pa = (ulong)xspanalloc(BY2PG, BY2PG, 0); - - /* map at LANCESEGM */ - k = kmappa(pa, PTEMAINMEM|PTENOCACHE); - lp->lanceram = (ushort*)k->va; - lp->lm = (Lancemem*)k->va; - - /* - * Allocate space in host memory for the io buffers. - * Allocate a block and kmap it page by page. kmap's are initially - * in reverse order so rearrange them. - */ - i = (lp->nrrb+lp->ntrb)*sizeof(Etherpkt); - i = (i+(BY2PG-1))/BY2PG; - pa = (ulong)xspanalloc(i*BY2PG, BY2PG, 0)&~KZERO; - va = kmapregion(pa, i*BY2PG, PTEMAINMEM|PTENOCACHE); - - lp->lrp = (Etherpkt*)va; - lp->rp = (Etherpkt*)va; - lp->ltp = lp->lrp+lp->nrrb; - lp->tp = lp->rp+lp->nrrb; -} diff --git a/ss/mem.h b/ss/mem.h deleted file mode 100644 index d9a3da9815c630023c87da9cbfa14419642b487e..0000000000000000000000000000000000000000 --- a/ss/mem.h +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Memory and machine-specific definitions. Used in C and assembler. - */ - -/* - * Sizes - */ - -#define BI2BY 8 /* bits per byte */ -#define BI2WD 32 /* bits per word */ -#define BY2WD 4 /* bytes per word */ -#define BY2PG 4096 /* bytes per page */ -#define WD2PG (BY2PG/BY2WD) /* words per page */ -#define PGSHIFT 12 /* log(BY2PG) */ -#define PGROUND(s) (((s)+(BY2PG-1))&~(BY2PG-1)) - -#define MAXMACH 1 /* max # cpus system can run */ - -/* - * Time - */ -#define HZ 50 /* clock frequency */ -#define MS2HZ (1000/HZ) /* millisec per clock tick */ -#define TK2SEC(t) ((t)/HZ) /* ticks to seconds */ -#define TK2MS(t) ((((ulong)(t))*1000)/HZ) /* ticks to milliseconds */ -#define MS2TK(t) ((((ulong)(t))*HZ)/1000) /* milliseconds to ticks */ - -/* - * PSR bits - */ -#define PSREC 0x00002000 -#define PSREF 0x00001000 -#define PSRSUPER 0x00000080 -#define PSRPSUPER 0x00000040 -#define PSRET 0x00000020 -#define SPL(n) (n<<8) - -/* - * Magic registers - */ - -#define MACH 6 /* R6 is m-> */ -#define USER 5 /* R5 is u-> */ - -/* - * Fundamental addresses - */ - -#define USERADDR 0xE0000000 -#define UREGADDR (USERADDR+BY2PG-((32+6)*BY2WD)) -#define BOOTSTACK (KTZERO-0*BY2PG) -#define TRAPS (KTZERO-2*BY2PG) - -/* - * MMU - */ - -#define VAMASK 0x3FFFFFFF -#define BY2SEGM (1<<18) -#define PG2SEGM (1<<6) -#define CONTEXT 0x30000000 /* in ASI 2 */ - -/* - * MMU regions - */ -#define INVALIDSEGM 0xFFFC0000 /* highest seg of VA reserved as invalid */ -#define INVALIDPMEG (conf.npmeg-1) -#define IOSEGSIZE (MB + 2*MB) /* 1 meg for screen plus overhead */ -#define IOSEGM (INVALIDSEGM - IOSEGSIZE) - -/* - * MMU entries - */ -#define PTEVALID (1<<31) -#define PTERONLY (0<<30) -#define PTEWRITE (1<<30) -#define PTEKERNEL (1<<29) -#define PTENOCACHE (1<<28) -#define PTEMAINMEM (0<<26) -#define PTEIO (1<<26) -#define PTEACCESS (1<<25) -#define PTEMODIFY (1<<24) -#define PTEPROBEMEM (PTEVALID|PTEKERNEL|PTENOCACHE|PTEWRITE|PTEMAINMEM) -#define PTEPROBEIO (PTEVALID|PTEKERNEL|PTENOCACHE|PTEWRITE|PTEIO) -#define PTEUNCACHED 0 - -#define PTEMAPMEM (1024*1024) -#define PTEPERTAB (PTEMAPMEM/BY2PG) -#define SEGMAPSIZE 128 - -#define INVALIDPTE 0 -#define PPN(pa) (((pa)>>12)&0xFFFF) - -/* - * Weird addresses etc. in System ASI (2) - */ -#define CACHETAGS 0x80000000 -#define CACHEDATA 0x90000000 -#define SER 0x60000000 -#define SEVAR 0x60000004 -#define ASER 0x60000008 -#define ASEVAR 0x6000000C -#define ENAB 0x40000000 -#define ENABRESET 0x04 -#define ENABCACHE 0x10 -#define ENABDMA 0x20 - -/* - * Virtual addresses - */ -#define VTAG(va) ((va>>22)&0x03F) -#define VPN(va) ((va>>13)&0x1FF) - -/* - * Address spaces - */ -#define UZERO 0x00000000 /* base of user address space */ -#define UTZERO (UZERO+BY2PG) /* first address in user text */ -#define TSTKTOP 0x10000000 /* end of new stack in sysexec */ -#define TSTKSIZ 32 -#define USTKTOP (TSTKTOP-TSTKSIZ*BY2PG) /* byte just beyond user stack */ -#define KZERO 0xE0000000 /* base of kernel address space */ -#define KTZERO (KZERO+4*BY2PG) /* first address in kernel text */ -#define USTKSIZE (4*1024*1024) /* size of user stack */ - -#define MACHSIZE 4096 diff --git a/ss/mmu.c b/ss/mmu.c deleted file mode 100644 index 673915b9b5c4979083318b54c63b8ea39c1fe031..0000000000000000000000000000000000000000 --- a/ss/mmu.c +++ /dev/null @@ -1,676 +0,0 @@ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "io.h" - -/* - * WARNING: Even though all MMU data is in the mach structure or - * pointed to by it, this code will not work on a multi-processor - * without modification. - */ - -/* - * doubly linked list for LRU algorithm - */ -struct List -{ - List *prev; /* less recently used */ - List *next; /* more recently used */ -}; - -/* - * a Sparc context description - */ -struct Ctx -{ - List; /* MUST BE FIRST IN STRUCTURE!! */ - - Proc *proc; /* process that owns this context */ - Pmeg *pmeg; /* list of pmeg's used by this context */ - ushort index; /* which context this is */ -}; - -/* - * a Sparc PMEG description - */ -struct Pmeg -{ - List; /* MUST BE FIRST IN STRUCTURE!! */ - - ulong lo; /* low water mark of used entries */ - ulong hi; /* high water mark of used entries */ - ushort index; /* which Pmeg this is */ - - ulong virt; /* virtual address this Pmeg represents */ - Ctx *ctx; /* context Pmeg belongs to */ - Pmeg *cnext; /* next pmeg used in same context */ -}; - -#define HOWMANY(x, y) (((x)+((y)-1))/(y)) -#define ROUNDUP(x, y) (HOWMANY((x), (y))*(y)) - -static Pmeg* allocpmeg(ulong); -static void freepmeg(Pmeg*, int); -static Ctx* allocctx(Proc*); -static void freectx(Ctx*, int); -static void putpme(ulong, ulong, int); -static void mklast(List**, List*); -static void mkfirst(List**, List*); -static void remove(List**, List*); -static void add(List**, List*); -static void flushpage(ulong); -static void putctx(Ctx*); - -/* - * move to end of use list - */ -static void -mklast(List **list, List *entry) -{ - List *first; - - first = *list; - if(entry == first){ - *list = first->next; - return; - } - - /* remove from list */ - entry->prev->next = entry->next; - entry->next->prev = entry->prev; - - /* chain back in */ - entry->prev = first->prev; - entry->next = first; - first->prev->next = entry; - first->prev = entry; -} - -/* - * move to front of use list - */ -static void -mkfirst(List **list, List *entry) -{ - List *first; - - first = *list; - if(entry == first) - return; /* already at front */ - - /* unchain */ - entry->prev->next = entry->next; - entry->next->prev = entry->prev; - - /* chain back in */ - entry->prev = first->prev; - entry->next = first; - first->prev->next = entry; - first->prev = entry; - - *list = entry; -} - -/* - * add to list - */ -static void -add(List **list, List *entry) -{ - List *first; - - first = *list; - if(first == 0){ - entry->prev = entry; - entry->next = entry; - } else { - entry->prev = first->prev; - entry->next = first; - first->prev->next = entry; - first->prev = entry; - } - *list = entry; -} - -/* - * add a pmeg to the current context for the given address - */ -static Pmeg* -allocpmeg(ulong virt) -{ - Pmeg *p; - - virt = virt & ~(BY2SEGM-1); - for(;;){ - p = (Pmeg*)m->plist; - if(p->ctx == 0) - break; - m->needpmeg = 1; - sched(); - splhi(); - } - - /* add to current context */ - p->ctx = m->cctx; - p->cnext = m->cctx->pmeg; - m->cctx->pmeg = p; - p->virt = virt; - p->lo = virt + BY2PG; - p->hi = virt; - putsegspace(p->virt, p->index); - mklast(&m->plist, p); - return p; -} - -static void -freepmeg(Pmeg *p, int flush) -{ - ulong x; - - /* invalidate any used PTE's */ - for(x = p->lo; x <= p->hi; x += BY2PG) - putpme(x, INVALIDPTE, flush); - - /* invalidate segment pointer */ - putsegspace(p->virt, INVALIDPMEG); - - p->hi = 0; - p->lo = 0; - p->cnext = 0; - p->ctx = 0; - p->virt = 0; - mkfirst(&m->plist, p); -} - -/* - * get a context for a process. - */ -static Ctx* -allocctx(Proc *proc) -{ - Ctx *c; - - c = (Ctx*)m->clist; - putctx(c); - if(c->proc) - freectx(c, 1); - if(c->pmeg) - panic("allocctx c->pmeg %lux\n", c->pmeg); - - c->proc = proc; - c->proc->ctxonmach[m->machno] = c; - mklast(&m->clist, c); - return c; -} - -static void -freectx(Ctx *c, int flush) -{ - Pmeg *p; - - putctx(c); - if(c->proc->ctxonmach[m->machno] != c) - panic("freectx %lux %lux\n", c->proc->ctxonmach[m->machno], c); - - /* give back mappings */ - while(p = c->pmeg){ - if(p->ctx != c) - panic("freectx: %lux/%lux\n", p->ctx, c); - c->pmeg = p->cnext; - freepmeg(p, flush); - } - - /* flush u-> */ - flushpage(USERADDR); - - /* detach from process */ - c->proc->ctxonmach[m->machno] = 0; - c->proc = 0; - mkfirst(&m->clist, c); -} - -static void -putctx(Ctx *c) -{ - putcontext(c->index); - m->cctx = c; -} - -static void -flushpage(ulong virt) -{ - ulong a, evirt; - - a = virt; - evirt = virt+BY2PG; - do - a = flushpg(a); - while(a < evirt); -} - - -/* - * stuff an entry into a pmeg - */ -static void -putpme(ulong virt, ulong phys, int flush) -{ - virt = virt & ~(BY2PG-1); - if(flush) - flushpage(virt); - putpmegspace(virt, phys); -} - -/* - * put a mapping into current context - */ -void -putmmu(ulong virt, ulong phys, Page *pg) -{ - ulong x, v; - Pmeg *p; - int s; - - USED(pg); - s = splhi(); - v = virt & ~(BY2SEGM-1); - x = getsegspace(v); - if(x == INVALIDPMEG) - p = allocpmeg(v); - else { - p = &m->pmeg[x - m->pfirst]; - if(x != p->index) - panic("putmmu %d/%d\n", x, p->index); - } - if(virt < p->lo) - p->lo = virt; - if(virt > p->hi) - p->hi = virt; - - putpme(virt, phys, 1); - splx(s); -} - -/* - * Initialize cache by clearing the valid bit - * (along with the others) in all cache entries - */ -void -cacheinit(void) -{ - int i; - - for(i=0; iKZERO+4*BY2SEGM to physical - * 0<->4*BY2SEGM - */ - compile(); - - /* - * map all of text image - */ - ktop = PGROUND((ulong)end); - i = 0; - for(c = 0; c < conf.ncontext; c++){ - i = 0; - for(va = KZERO; va < ktop; va += BY2SEGM) - putcxsegm(c, va, i++); - } - fp = i; - - /* - * Make sure cache is turned on for program and data - */ - pme = PTEVALID|PTEWRITE|PTEKERNEL|PTEMAINMEM; - i = 0; - for(va = KZERO; va < ktop; va += BY2PG, i++) - putpme(va, pme+i, 1); - - /* - * invalidate rest of kernel's region 0's PMEG's - */ - va = ROUNDUP(ktop, BY2SEGM); - for(; ktop < va; ktop += BY2PG) - putpme(ktop, INVALIDPTE, 1); - - /* - * Invalidate all entries in all other pmegs - */ - for(j = fp; j < conf.npmeg; j++){ - putsegspace(INVALIDSEGM, j); - for(va = 0; va < BY2SEGM; va += BY2PG) - putpmegspace(INVALIDSEGM+va, INVALIDPTE); - } - - if(conf.base0 < conf.npage0){ - /* - * map kernel region 0, this may overlap kernel text image - */ - ktop1 = PGROUND(conf.npage0); - kbot1 = conf.base0 & ~(BY2SEGM - 1); - if(kbot1 < ktop) - kbot1 = ktop; - for(c = 0; c < conf.ncontext; c++){ - i = fp; - putcontext(c); - for(va = kbot1; va < ktop1; va += BY2SEGM) - putsegspace(va, i++); - } - fp = i; - - /* - * Make sure cache is turned on for kernel region 0 - */ - kbot1 = conf.base0 & ~(BY2PG - 1); - pme = PTEVALID|PTEWRITE|PTEKERNEL|PTEMAINMEM; - i = PPN(kbot1 & ~KZERO); - for(va = kbot1; va < ktop1; va += BY2PG, i++) - putpme(va, pme+i, 1); - ktop = ktop1; - } - - if(conf.base1 < conf.npage1){ - /* - * map kernel region 1, this may overlap kernel region 0's - * PMEG's. - */ - ktop1 = PGROUND(conf.npage1); - kbot1 = conf.base1 & ~(BY2SEGM - 1); - if(kbot1 < ktop) - kbot1 = ktop; - for(c = 0; c < conf.ncontext; c++){ - i = fp; - putcontext(c); - for(va = kbot1; va < ktop1; va += BY2SEGM) - putsegspace(va, i++); - } - fp = i; - - /* - * Make sure cache is turned on for kernel region 1 - */ - kbot1 = conf.base1 & ~(BY2PG - 1); - pme = PTEVALID|PTEWRITE|PTEKERNEL|PTEMAINMEM; - i = PPN(kbot1 & ~KZERO); - for(va = kbot1; va < ktop1; va += BY2PG, i++) - putpme(va, pme+i, 1); - ktop = ktop1; - } - - /* - * allocate pmegs for kmap'ing - */ - for(c = 0; c < conf.ncontext; c++){ - putcontext(c); - i = fp; - for(va = IOSEGM; va < IOSEGM+IOSEGSIZE; va += BY2SEGM) - putsegspace(va, i++); - } - fp = i; - - /* - * invalidate everything outside the kernel in every context - */ - for(c = 0; c < conf.ncontext; c++){ - putcontext(c); - for(va = UZERO; va < (KZERO & VAMASK); va += BY2SEGM) - putsegspace(va, INVALIDPMEG); - for(va = ktop; va < IOSEGM; va += BY2SEGM) - putsegspace(va, INVALIDPMEG); - } - - /* - * allocate MMU management data for this CPU - */ - m->pmeg = p = xalloc((INVALIDPMEG - fp) * sizeof(Pmeg)); - m->pfirst = fp; - for(; fp < INVALIDPMEG; fp++, p++){ - p->index = fp; - add(&m->plist, p); - } - m->cctx = ctx = xalloc(conf.ncontext * sizeof(Ctx)); - for(i = 0; i < conf.ncontext; i++, ctx++){ - ctx->index = i; - add(&m->clist, ctx); - } - - putctx(m->cctx); -} - -/* - * give up our mmu context - */ -void -mmurelease(Proc *p) -{ - Ctx *c; - - c = p->ctxonmach[m->machno]; - if(c == 0) - return; - - freectx(c, 1); -} - -/* - * set up context for a process - */ -void -mapstack(Proc *p) -{ - Ctx *c; - ulong tlbphys; - Pmeg *pm, *f, **l; - - if(p->upage->va != (USERADDR|(p->pid&0xFFFF)) && p->pid != 0) - panic("mapstack %s %d %lux 0x%lux 0x%lux", - p->text, p->pid, p->upage, p->upage->pa, p->upage->va); - - /* free a pmeg if a process needs one */ - if(m->needpmeg){ - pm = (Pmeg*)m->plist; - if(c = pm->ctx){ - /* remove from context list */ - l = &c->pmeg; - for(f = *l; f; f = f->cnext){ - if(f == pm){ - *l = f->cnext; - break; - } - l = &f->cnext; - } - if(f != pm) - panic("mapstack f != pm\n"); - - /* flush cache & remove mappings */ - putctx(c); - freepmeg(pm, 1); - } - m->needpmeg = 0; - } - - /* give up our context if it is unclean */ - if(p->newtlb){ - c = p->ctxonmach[m->machno]; - if(c) - freectx(c, 1); - p->newtlb = 0; - } - - /* set to this proc's context */ - c = p->ctxonmach[m->machno]; - if(c == 0) - c = allocctx(p); - else - putctx(c); - - if(c->proc != p || p->ctxonmach[m->machno] != c) - panic("mapstack c->proc != p\n"); - - /* make sure there's a mapping for u-> */ - tlbphys = PPN(p->upage->pa)|PTEVALID|PTEWRITE|PTEKERNEL|PTEMAINMEM; - putpmegspace(USERADDR, tlbphys); - u = (User*)USERADDR; -} - -void -flushmmu(void) -{ - Ctx *c; - Pmeg *p; - - splhi(); - c = u->p->ctxonmach[m->machno]; - if(c == 0) - panic("flushmmu"); - while(p = c->pmeg){ - c->pmeg = p->cnext; - freepmeg(p, 1); - } - spllo(); -} - -void -invalidateu(void) -{ - putpme(USERADDR, INVALIDPTE, 1); -} - -struct -{ - Lock; - KMap *free; - KMap arena[IOSEGSIZE/BY2PG]; - int inited; -}kmapalloc; - -void -kmapinit(void) -{ - KMap *k; - ulong va; - - kmapalloc.free = 0; - k = kmapalloc.arena; - for(va = IOSEGM; va < IOSEGM + IOSEGSIZE; va += BY2PG, k++){ - k->va = va; - kunmap(k); - } - kmapalloc.inited = 1; -} - -KMap* -kmappa(ulong pa, ulong flag) -{ - KMap *k; - ulong s; - - lock(&kmapalloc); - k = kmapalloc.free; - if(k == 0){ - dumpstack(); - panic("kmap"); - } - kmapalloc.free = k->next; - unlock(&kmapalloc); - k->pa = pa; - s = splhi(); - putpme(k->va, PPN(pa)|PTEVALID|PTEKERNEL|PTEWRITE|flag, 1); - splx(s); - return k; -} - - -void -kunmap(KMap *k) -{ - ulong pa; - - pa = k->pa; - k->pa = 0; - lock(&kmapalloc); - k->next = kmapalloc.free; - kmapalloc.free = k; - if(pa != k->pa) - putpme(k->va, INVALIDPTE, 1); - unlock(&kmapalloc); -} - -ulong -kmapregion(ulong pa, ulong n, ulong flag) -{ - KMap *k; - ulong va; - int i, j; - - /* - * kmap's are initially in reverse order so rearrange them. - */ - i = (n+(BY2PG-1))/BY2PG; - va = 0; - for(j=i-1; j>=0; j--){ - k = kmappa(pa+j*BY2PG, flag); - if(va && va != k->va+BY2PG) - systemreset(); - va = k->va; - } - return va; -} - -KMap* -kmap(Page *pg) -{ - ulong va; - KMap *k; - - /* - * avoid an alias: if part of kernel memory, just return map - */ - va = pg->pa|KZERO; - if((KZERO<=va && va<(ulong)end) || - (conf.base0<=va && vanext; - unlock(&kmapalloc); - k->va = va; - k->pa = va; - return k; - } - - /* - * Cache is virtual and a pain to deal with. - * Must avoid having the same entry in the cache twice, so - * must use NOCACHE or else extreme cleverness elsewhere. - */ - return kmappa(pg->pa, PTEMAINMEM|PTENOCACHE); -} diff --git a/ss/rom.h b/ss/rom.h deleted file mode 100644 index ed4ee2cbe95ee8b4ceffafa04ff0e11e755893aa..0000000000000000000000000000000000000000 --- a/ss/rom.h +++ /dev/null @@ -1,57 +0,0 @@ -typedef struct ROM ROM; -typedef struct ROMconf ROMconf; - -struct ROM -{ - uint magic; - uint version; - uint plugversion; - uint monid; - uint pad1[3]; - ROMconf *conf; - uint pad2[17]; - void (*boot)(void*); - uint pad3[1]; - void (*enter)(void); - int *msec; - void (*exit)(void); - void (**callback)(void); - uint (*interpret)(void*); - uint pad4[2]; - char **bootpath; - char **bootargs; - uint *stdin; - uint *stdout; - uint (*phandle)(uint); - uint (*alloc)(void*, uint); - void (*free)(void*); - uint (*map)(void*, uint, uint, uint); - void (*unmap)(void*, uint); - uint (*open)(char*); - uint (*close)(uint); - uint (*read)(uint, void*, int); - uint (*write)(uint, void*, int); - uint (*seek)(uint, uint, uint); - void (*chain)(void*, uint, void*, void*, uint); - void (*release)(void*, uint); - uint pad4[15]; - void (*putcxsegm)(int, ulong, int); - int (*startcpu)(uint, uint, uint, uint); - int (*stopcpu)(uint); - int (*idlecpu)(uint); - int (*resumecpu)(uint); -}; - -struct ROMconf -{ - uint (*next)(uint); - uint (*child)(uint); - int (*getproplen)(uint, void*); - int (*getprop)(uint, void*, void*); - int (*setprop)(uint, void*, void*); - void* (*nextprop)(uint, void*); -}; - -#define ROMMAGIC 0x10010407 - -extern ROM *rom; diff --git a/ss/screen.c b/ss/screen.c deleted file mode 100644 index ab8c0e6bca2adc2c52d3a80a3ef5df144fe94e84..0000000000000000000000000000000000000000 --- a/ss/screen.c +++ /dev/null @@ -1,549 +0,0 @@ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "io.h" -#include "../port/error.h" - -#include -#include -#include "screen.h" - -#define MINX 8 - -extern GSubfont defont0; -GSubfont *defont; -int islcd; - -struct{ - Point pos; - int bwid; -}out; - -static ulong rep(ulong, int); -void (*kprofp)(ulong); - -typedef struct Video Video; -struct Video -{ - /* Brooktree 458/451 */ - uchar addr; /* address register */ - uchar pad0[3]; - uchar color; /* color palette */ - uchar pad1[3]; - uchar cntrl; /* control register */ - uchar pad2[3]; - uchar ovrl; /* overlay palette */ - uchar pad3[3]; -#ifdef notright - /* Sun-4 video chip */ - uchar mcr; /* master control register */ - uchar sr; /* status register */ - uchar csa; /* cursor start address */ - uchar cea; /* cursor end address */ - uchar hbs; /* horizontal blank set */ - uchar hbc; /* horizontal blank clear */ - uchar hss; /* horizontal sync set */ - uchar hsc; /* horizontal sync clear */ - uchar csc; /* composite sync clear */ - uchar vbsh; /* vertical blank set high byte */ - uchar vbsl; /* vertical blank set low byte */ - uchar vbc; /* vertical blank clear */ - uchar vss; /* vertical sync set */ - uchar vsc; /* vertical sync clear */ - uchar xcs; /* transfer cycle hold off set */ - uchar xcc; /* transfer cycle hold off clear */ -#endif -} *vid; - -GBitmap gscreen; - -struct screens -{ - char *type; - int x; - int y; - int ld; - ulong vidaddr; -}screens[] = { - { "bwtwo", 1152, 900, 0, 0x400000 }, - { "cgsix", 1152, 900, 3, 0x200000 }, - { "cgthree", 1152, 900, 3, 0x400000 }, /* data from rwolff */ - 0 -}; - -Lock screenlock; - -void -screeninit(char *str, int slot) -{ - struct screens *s; - ulong n, r, g, b; - int i; - int havecol; - - for(s=screens; s->type; s++) - if(strcmp(s->type, str) == 0) - goto found; - /* default is 0th element of table */ - if(conf.monitor){ - s = screens; - goto found; - } - conf.monitor = 0; - return; - - found: - gscreen.zero = 0; - gscreen.width = (s->x<ld)/(8*sizeof(ulong)); - n = sizeof(ulong) * gscreen.width * s->y; - gscreen.base = (ulong*)kmapregion(DISPLAYRAM(slot), n, PTENOCACHE|PTEIO); - gscreen.ldepth = s->ld; - gscreen.r = Rect(0, 0, s->x, s->y); - gscreen.clipr = gscreen.r; - gscreen.cache = 0; - defont = &defont0; - gbitblt(&gscreen, Pt(0, 0), &gscreen, gscreen.r, 0); - out.pos.x = MINX; - out.pos.y = 0; - out.bwid = defont0.info[' '].width; - vid = (Video*)(kmappa(FRAMEBUF(slot)+s->vidaddr, PTENOCACHE|PTEIO)->va); - if(gscreen.ldepth == 3){ - vid->addr = 4; - vid->cntrl = 0xFF; /* enable all planes */ - vid->addr = 5; - vid->cntrl = 0x00; /* no blinking */ - vid->addr = 6; - vid->cntrl = 0x43; /* enable palette ram and display */ - vid->addr = 7; - vid->cntrl = 0x00; /* no tests */ - havecol = 0; - if(havecol) { - /* - * For now, just use a fixed colormap, where pixel i is - * regarded as 3 bits of red, 3 bits of green, and 2 bits of blue. - * Intensities are inverted so that 0 means white, 255 means black. - * Exception: pixels 85 and 170 are set to intermediate grey values - * so that 2-bit grey scale images will look ok on this screen. - */ - for(i = 0; i<256; i++) { - r = ~rep((i>>5) & 7, 3); - g = ~rep((i>>2) & 7, 3); - b = ~rep(i & 3, 2); - setcolor(i, r, g, b); - } - setcolor(85, 0xAAAAAAAA, 0xAAAAAAAA, 0xAAAAAAAA); - setcolor(170, 0x55555555, 0x55555555, 0x55555555); - } else { - vid->addr = 0; - for(i=255; i>=0; i--){ - vid->color = i; - vid->color = i; - vid->color = i; - } - } - } -} - - -void -screenputnl(void) -{ - if(!conf.monitor) - return; - out.pos.x = MINX; - out.pos.y += defont0.height; - if(out.pos.y > gscreen.r.max.y-defont0.height) - out.pos.y = gscreen.r.min.y; - gbitblt(&gscreen, Pt(0, out.pos.y), &gscreen, - Rect(0, out.pos.y, gscreen.r.max.x, out.pos.y+2*defont0.height), 0); -} - -void -screenputs(char *s, int n) -{ - Rune r; - int i; - char buf[4]; - - if(!conf.monitor) - return; - - if((getpsr()&SPL(15))){ - if(!canlock(&screenlock)) - return; /* don't deadlock trying to print in interrupt */ - }else - lock(&screenlock); - while(n > 0){ - i = chartorune(&r, s); - if(i == 0){ - s++; - --n; - continue; - } - memmove(buf, s, i); - buf[i] = 0; - n -= i; - s += i; - if(r == '\n') - screenputnl(); - else if(r == '\t'){ - out.pos.x += (8-((out.pos.x-MINX)/out.bwid&7))*out.bwid; - if(out.pos.x >= gscreen.r.max.x) - screenputnl(); - }else if(r == '\b'){ - if(out.pos.x >= out.bwid+MINX){ - out.pos.x -= out.bwid; - gsubfstring(&gscreen, out.pos, defont, " ", S); - } - }else{ - if(out.pos.x >= gscreen.r.max.x-out.bwid) - screenputnl(); - out.pos = gsubfstring(&gscreen, out.pos, defont, buf, S); - } - } - unlock(&screenlock); -} - -/* - * Map is indexed by keyboard char, output is ASCII. - * Plan 9-isms: - * Return sends newline and Line Feed sends carriage return. - * Delete and Backspace both send backspace. - * Num Lock sends delete (rubout). - * Alt Graph is VIEW (scroll). - * Compose builds Unicode characters. - */ -uchar keymap[128] = { -/* 00 L1 02 L2 04 F1 F2 07 */ - 0xFF, 0x80, 0xFF, 0x81, 0xFF, 0x82, 0x83, 0xFF, -/* F3 09 F4 0b F5 altgr F6 0f */ - 0x84, 0xFF, 0x85, 0xFF, 0x86, 0x80, 0x87, 0xFF, -/* F7 F8 F9 Alt 14 R1 R2 R3 */ - 0x88, 0x89, 0x8a, 0x8b, 0xFF, 0x8c, 0x8d, 0x8e, -/* 18 L3 L4 1b 1c Esc 1 2 */ - 0xFF, 0x8f, 0x90, 0xFF, 0xFF, 0x1b, '1', '2', -/* 3 4 5 6 7 8 9 0 */ - '3', '4', '5', '6', '7', '8', '9', '0', -/* - = ` bs 2c R4 R5 R6 */ - '-', '=', '`', '\b', 0xFF, 0x91, 0x92, 0x93, -/* 30 L5 del L6 34 tab q w */ - 0xFF, 0x94, 0xFF, 0x95, 0xFF, '\t', 'q', 'w', -/* e r t y u i o p */ - 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', -/* [ ] dele comp R7 R8 R9 r - */ - '[', ']', '\b', 0xB6, 0x96, 0x97, 0x98, 0xFF, -/* L7 L8 4a 4b ctrl a s d */ - 0x99, 0x9a, 0xFF, 0xFF, 0xF0, 'a', 's', 'd', -/* f g h j k l ; ' */ - 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', -/* \ ret enter R10 R11 R12 ins L9 */ - '\\', '\n', 0xFF, 0x9b, 0x9c, 0x9d, 0xFF, 0x9e, -/* 60 L10 numlk shift z x c v */ - 0xFF, 0x9f, 0x7F, 0xF1, 'z', 'x', 'c', 'v', -/* b n m , . / shift lf */ - 'b', 'n', 'm', ',', '.', '/', 0xF1, '\r', -/* R13 R14 R15 73 74 75 help caps */ - 0xA0, 0xA1, 0xA2, 0xFF, 0xFF, 0xFF, 0xFF, 0xF2, -/* lloz 79 rloz 7b 7c r + 7e 7f */ - 0xA3, ' ', 0xA4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -}; - -uchar keymapshift[128] = { -/* 00 L1 02 L2 04 F1 F2 07 */ - 0xFF, 0x80, 0xFF, 0x81, 0xFF, 0x82, 0x83, 0xFF, -/* F3 09 F4 0b F5 altgr F6 0f */ - 0x84, 0xFF, 0x85, 0xFF, 0x86, 0x80, 0x87, 0xFF, -/* F7 F8 F9 Alt 14 R1 R2 R3 */ - 0x88, 0x89, 0x8a, 0x8b, 0xFF, 0x8c, 0x8d, 0x8e, -/* 18 L3 L4 1b 1c Esc 1 2 */ - 0xFF, 0x8f, 0x90, 0xFF, 0xFF, 0x1b, '!', '@', -/* 3 4 5 6 7 8 9 0 */ - '#', '$', '%', '^', '&', '*', '(', ')', -/* - = ` bs 2c R4 R5 R6 */ - '_', '+', '~', '\b', 0xFF, 0x91, 0x92, 0x93, -/* 30 L5 del L6 34 tab q w */ - 0xFF, 0x94, 0xFF, 0x95, 0xFF, '\t', 'Q', 'W', -/* e r t y u i o p */ - 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', -/* [ ] dele comp R7 R8 R9 r - */ - '{', '}', '\b', 0xB6, 0x96, 0x97, 0x98, 0xFF, -/* L7 L8 4a 4b ctrl a s d */ - 0x99, 0x9a, 0xFF, 0xFF, 0xF0, 'A', 'S', 'D', -/* f g h j k l ; ' */ - 'F', 'G', 'H', 'J', 'K', 'L', ':', '"', -/* \ ret enter R10 R11 R12 ins L9 */ - '|', '\n', 0xFF, 0x9b, 0x9c, 0x9d, 0xFF, 0x9e, -/* 60 L10 numlk shift z x c v */ - 0xFF, 0x9f, 0x7F, 0xF1, 'Z', 'X', 'C', 'V', -/* b n m , . / shift lf */ - 'B', 'N', 'M', '<', '>', '?', 0xF1, '\r', -/* R13 R14 R15 73 74 75 help caps */ - 0xA0, 0xA1, 0xA2, 0xFF, 0xFF, 0xFF, 0xFF, 0xF2, -/* lloz 79 rloz 7b 7c r + 7e 7f */ - 0xA3, ' ', 0xA4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -}; - -uchar keymapctrl[128] = { -/* 00 L1 02 L2 04 F1 F2 07 */ - 0xFF, 0x80, 0xFF, 0x81, 0xFF, 0x82, 0x83, 0xFF, -/* F3 09 F4 0b F5 altgr F6 0f */ - 0x84, 0xFF, 0x85, 0xFF, 0x86, 0x80, 0x87, 0xFF, -/* F7 F8 F9 Alt 14 R1 R2 R3 */ - 0x88, 0x89, 0x8a, 0x8b, 0xFF, 0x8c, 0x8d, 0x8e, -/* 18 L3 L4 1b 1c Esc 1 2 */ - 0xFF, 0x8f, 0x90, 0xFF, 0xFF, 0x1b, '!', '@', -/* 3 4 5 6 7 8 9 0 */ - '#', '$', '%', '^', '&', '*', '(', ')', -/* - = ` bs 2c R4 R5 R6 */ - '_', '+', '~', '\b', 0xFF, 0x91, 0x92, 0x93, -/* 30 L5 del L6 34 tab q w */ - 0xFF, 0x94, 0xFF, 0x95, 0xFF, '\t', 0x11, 0x17, -/* e r t y u i o p */ - 0x05, 0x12, 0x14, 0x19, 0x15, 0x09, 0x0F, 0x10, -/* [ ] dele comp R7 R8 R9 r - */ - 0x1B, 0x1D, '\b', 0xB6, 0x96, 0x97, 0x98, 0xFF, -/* L7 L8 4a 4b ctrl a s d */ - 0x99, 0x9a, 0xFF, 0xFF, 0xF0, 0x01, 0x13, 0x04, -/* f g h j k l ; ' */ - 0x06, 0x07, 0x08, 0x0A, 0x0B, 0x0C,':', '"', -/* \ ret enter R10 R11 R12 ins L9 */ - 0x1C, '\n', 0xFF, 0x9b, 0x9c, 0x9d, 0xFF, 0x9e, -/* 60 L10 numlk shift z x c v */ - 0xFF, 0x9f, 0x7F, 0xF1, 0x1A, 0x18, 0x03, 0x16, -/* b n m , . / shift lf */ - 0x02, 0x0E, 0x0D, '<', '>', '?', 0xF1, '\r', -/* R13 R14 R15 73 74 75 help caps */ - 0xA0, 0xA1, 0xA2, 0xFF, 0xFF, 0xFF, 0xFF, 0xF2, -/* lloz 79 rloz 7b 7c r + 7e 7f */ - 0xA3, ' ', 0xA4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -}; - -uchar keymapshiftctrl[128] = { -/* 00 L1 02 L2 04 F1 F2 07 */ - 0xFF, 0x80, 0xFF, 0x81, 0xFF, 0x82, 0x83, 0xFF, -/* F3 09 F4 0b F5 altgr F6 0f */ - 0x84, 0xFF, 0x85, 0xFF, 0x86, 0x80, 0x87, 0xFF, -/* F7 F8 F9 Alt 14 R1 R2 R3 */ - 0x88, 0x89, 0x8a, 0x8b, 0xFF, 0x8c, 0x8d, 0x8e, -/* 18 L3 L4 1b 1c Esc 1 2 */ - 0xFF, 0x8f, 0x90, 0xFF, 0xFF, 0x1b, '!', 0x00, -/* 3 4 5 6 7 8 9 0 */ - '#', '$', '%', 0x1E, '&', '*', '(', ')', -/* - = ` bs 2c R4 R5 R6 */ - 0x1F, '+', '~', '\b', 0xFF, 0x91, 0x92, 0x93, -/* 30 L5 del L6 34 tab q w */ - 0xFF, 0x94, 0xFF, 0x95, 0xFF, '\t', 0x11, 0x17, -/* e r t y u i o p */ - 0x05, 0x12, 0x14, 0x19, 0x15, 0x09, 0x0F, 0x10, -/* [ ] dele comp R7 R8 R9 r - */ - 0x1B, 0x1D, '\b', 0xB6, 0x96, 0x97, 0x98, 0xFF, -/* L7 L8 4a 4b ctrl a s d */ - 0x99, 0x9a, 0xFF, 0xFF, 0xF0, 0x01, 0x13, 0x04, -/* f g h j k l ; ' */ - 0x06, 0x07, 0x08, 0x0A, 0x0B, 0x0C,':', '"', -/* \ ret enter R10 R11 R12 ins L9 */ - 0x1C, '\n', 0xFF, 0x9b, 0x9c, 0x9d, 0xFF, 0x9e, -/* 60 L10 numlk shift z x c v */ - 0xFF, 0x9f, 0x7F, 0xF1, 0x1A, 0x18, 0x03, 0x16, -/* b n m , . / shift lf */ - 0x02, 0x0E, 0x0D, '<', '>', '?', 0xF1, '\r', -/* R13 R14 R15 73 74 75 help caps */ - 0xA0, 0xA1, 0xA2, 0xFF, 0xFF, 0xFF, 0xFF, 0xF2, -/* lloz 79 rloz 7b 7c r + 7e 7f */ - 0xA3, ' ', 0xA4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -}; - -static uchar *kbdmap[4] = { - keymap, - keymapshift, - keymapctrl, - keymapshiftctrl -}; - -int -kbdstate(IOQ *q, int c) -{ - static shift = 0x00; - static caps = 0; - static long startclick; - static int repeatc; - static int lstate; - static uchar kc[4]; - uchar ch; - int i, nk; - - USED(q); - ch = kbdmap[shift][c&0x7F]; - if(c==0x7F){ /* all keys up */ - norepeat: - kbdrepeat(0); - return 0; - } - if(ch == 0xFF) /* shouldn't happen; ignore */ - return 0; - if(c & 0x80){ /* key went up */ - if(ch == 0xF0){ /* control */ - shift &= ~2; - goto norepeat; - } - if(ch == 0xF1){ /* shift */ - shift &= ~1; - goto norepeat; - } - if(ch == 0xF2){ /* caps */ - goto norepeat; - } - goto norepeat; - } - if(ch == 0xF0){ /* control */ - shift |= 2; - goto norepeat; - } - if(ch==0xF1){ /* shift */ - shift |= 1; - goto norepeat; - } - if(ch==0xF2){ /* caps */ - caps ^= 1; - goto norepeat; - } - if(caps && 'a'<=ch && ch<='z') - ch |= ' '; - repeatc = ch; - kbdrepeat(1); - if(ch == 0xB6) /* Compose */ - lstate = 1; - else{ - switch(lstate){ - case 1: - kc[0] = ch; - lstate = 2; - if(ch == 'X') - lstate = 3; - break; - case 2: - kc[1] = ch; - c = latin1(kc); - nk = 2; - putit: - lstate = 0; - if(c != -1) - kbdputc(&kbdq, c); - else for(i=0; iaddr = p & 0xFF; - r = vid->color; - g = vid->color; - b = vid->color; - *pr = (r<<24) | (r<<16) | (r<<8) | r; - *pg = (g<<24) | (g<<16) | (g<<8) | g; - *pb = (b<<24) | (b<<16) | (b<<8) | b; - } -} - - -int -setcolor(ulong p, ulong r, ulong g, ulong b) -{ - if(gscreen.ldepth == 0) - return 0; /* can't change mono screen colormap */ - else{ - vid->addr = p & 0xFF; - vid->color = r >> 24; - vid->color = g >> 24; - vid->color = b >> 24; - return 1; - } -} - -int -hwcursset(uchar *s, uchar *c, int ox, int oy) -{ - USED(s, c, ox, oy); - return 0; -} - -int -hwcursmove(int x, int y) -{ - USED(x, y); - return 0; -} - -/* replicate (from top) value in v (n bits) until it fills a ulong */ -static ulong -rep(ulong v, int n) -{ - int o; - ulong rv; - - rv = 0; - for(o = 32 - n; o >= 0; o -= n) - rv |= (v << o); - return rv; -} - -/* - * set/change mouse configuration - */ -void -mousectl(char *arg) -{ - USED(arg); -} diff --git a/ss/screen.h b/ss/screen.h deleted file mode 100644 index 21b9dad215e806a783d93d3c028f96c82ebeeb19..0000000000000000000000000000000000000000 --- a/ss/screen.h +++ /dev/null @@ -1,8 +0,0 @@ -extern void mouseupdate(int); - -#define hwscreenwrite(a, b) - -#define mbbpt(x) -#define mbbrect(x) -#define screenupdate() -#define mousescreenupdate() diff --git a/ss/scsi.c b/ss/scsi.c deleted file mode 100644 index 3864de25a931790cb344ca8668f91d36704973b2..0000000000000000000000000000000000000000 --- a/ss/scsi.c +++ /dev/null @@ -1,326 +0,0 @@ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "../port/error.h" -#include "devtab.h" -#include "io.h" - -uchar scsiownid = 7; -int scsidebugs[8]; - -static int dmatype; - -Scsibuf * -scsialloc(ulong n) -{ - Scsibuf *b; - ulong pa, va; - int i; - - b = xalloc(sizeof(Scsibuf)); - - /* - * Allocate space in host memory for the io buffer. - * NOTE: dma mustn't cross a 16Mb boundary. - */ - i = (n+(BY2PG-1))/BY2PG; - pa = (ulong)xspanalloc(i*BY2PG, BY2PG, 16*1024*1024) & ~KZERO; - va = kmapregion(pa, i*BY2PG, PTEMAINMEM|PTENOCACHE); - - b->virt = (void*)va; - b->phys = (void*)pa; - - return b; -} - -enum { - ResetIntDis = 0x40, /* config register */ - Penable = 0x10, - - Dma = 0x80, /* NCR 53C90 commands */ - Nop = 0x00, - Flush = 0x01, - Reset = 0x02, - Busreset = 0x03, - Select = 0x41, - Transfer = 0x10, - Cmdcomplete = 0x11, - Msgaccept = 0x12 -}; - -static QLock scsilock; /* access to device */ -static Rendez scsirendez; /* sleep/wakeup for requesting process */ -static Scsi * curcmd; /* currently executing command */ - -struct { - DMAdev *dma; - SCSIdev *scsi; -} ioaddr; - -static void -scsibusreset(void) -{ - SCSIdev *dev = ioaddr.scsi; - int s; - uchar intr; - - s = splhi(); - dev->config |= ResetIntDis; - dev->cmd = Busreset; - dev->config &= ~ResetIntDis; - intr = dev->intr; - USED(intr); - splx(s); -} - -void -resetscsi(void) -{ - SCSIdev *dev; - DMAdev *dma; - KMap *k; - uchar intr; - - k = kmappa(DMA, PTENOCACHE|PTEIO); - ioaddr.dma = (DMAdev*)k->va; - k = kmappa(SCSI, PTENOCACHE|PTEIO); - ioaddr.scsi = (SCSIdev*)k->va; - - dev = ioaddr.scsi; - dma = ioaddr.dma; - - dma->csr = Dma_Reset; - delay(1); - dma->csr = Int_en; - dma->count = 0; - - dmatype = (dma->csr>>28) & 0xF; - - /* - * try to determine chip type - dev->conf2 = 0; - dev->conf2 = 0x0A; - delay(1); - if((dev->conf2 & 0x0F) == 0x0A){ - dev->conf3 = 0; - dev->conf3 = 0x05; - delay(1); - if(dev->conf3 == 0x05) - print("scsi type ESP236\n"); - else - print("scsi type ESP100A\n"); - } - else - print("scsi type NCR53C90\n"); - */ - - dev->cmd = Reset; - dev->cmd = Dma|Nop; /* 2 are necessary for some chips */ - dev->cmd = Dma|Nop; - - dev->clkconf = 4; /* BUG: 20MHz */ - dev->timeout = 160; /* BUG: magic */ - dev->syncperiod = 0; - dev->syncoffset = 0; - dev->config = Penable|(scsiownid&7); - - intr = dev->intr; - USED(intr); - - putenab(getenab()|ENABDMA); /**/ -} - -void -initscsi(void) -{ -} - -static int -scsidone(void *arg) -{ - USED(arg); - return (curcmd == 0); -} - -int -scsiexec(Scsi *p, int rflag) -{ - SCSIdev *dev = ioaddr.scsi; - DMAdev *dma = ioaddr.dma; - long n; - - qlock(&scsilock); - - if(waserror()){ - qunlock(&scsilock); - nexterror(); - } - p->rflag = rflag; - p->status = 0; - - dma->csr = Dma_Flush|Int_en; - dma->addr = (ulong)p->data.ptr; - - dev->countlo = 0; - dev->countmi = 0; - dev->cmd = Dma|Nop; - dev->cmd = Flush; /* clear scsi fifo */ - - while (p->cmd.ptr < p->cmd.lim) - dev->fifo = *(p->cmd.ptr)++; - - dev->destid = p->target&7; - n = p->data.lim - p->data.ptr; - dev->countlo = n; - dev->countmi = n>>8; - dev->cmd = Dma|Nop; - - dma->csr = Int_en; - - curcmd = p; - dev->cmd = Select; - - sleep(&scsirendez, scsidone, 0); - poperror(); - qunlock(&scsilock); - return p->status; -} - -static void -scsimoan(char *msg, int status, int intr, int dmastat) -{ - print("scsiintr: %s:", msg); - print(" status=%2.2ux step/intr=%3.3ux", status, intr); - print(" dma=%8.8ux cmd status=%4.4ux\n", - dmastat, curcmd ? curcmd->status : 0xffff); -} - -void -scsiintr(void) -{ - SCSIdev *dev = ioaddr.scsi; - DMAdev *dma = ioaddr.dma; - Scsi *p = curcmd; - int status, step, intr, n; - ulong m, csr; - - csr = dma->csr; - - status = dev->status; - step = dev->step; - intr = dev->intr; - - intr |= ((step&7)<<8); - - if(p == 0 || (intr & 0x80)) { /* SCSI bus reset */ - dev->cmd = Nop; - goto Done; - } - - switch(p->status>>8){ - case 0x00: /* Select was issued */ - switch(intr){ - default: - scsimoan("bad case", status, intr, csr); - print("cmd = #%2.2ux\n", dev->cmd); - resetscsi(); - scsibusreset(); - goto Done; - case 0x020: /* arbitration complete, selection timed out */ - goto Done; - case 0x218: /* selection complete, no command phase */ - p->status = 0x1000; - scsimoan("no cmd phase", status, intr, csr); - resetscsi(); - scsibusreset(); - goto Done; - case 0x318: /* command phase ended prematurely */ - n = (p->cmd.lim - p->cmd.base) - (dev->fflags & 0x1f); - p->status = (0x30+n)<<8; - scsimoan("short cmd phase", status, intr, csr); - resetscsi(); - scsibusreset(); - goto Done; - case 0x418: /* select sequence complete */ - p->status = 0x4100; - if((status & 0x07) == p->rflag){ - dma->csr = p->rflag ? En_dma|Write|Int_en : En_dma|Int_en; - dev->cmd = Dma|Transfer; - return; - }else if((status & 0x07) != 3){ - scsimoan("weird phase after cmd", - status, intr, csr); - goto Done; - } - /* else fall through */ - } - - case 0x41: /* data transfer, if any, is finished */ - p->status = 0x4600; - p->data.ptr = p->data.lim - ((dev->countmi<<8)|dev->countlo); - if((status & 0x07) != 3){ - scsimoan("weird phase after xfr", - status, intr, csr); - goto Done; - } - - if(p->rflag){ - switch(dmatype){ - - case 8: - dma->csr = Drain|Int_en; - /*FALLTHROUGH*/ - - case 9: - while(dma->csr & Pack_cnt) - ; - break; - - default: - break; - } - } - - dev->cmd = Cmdcomplete; - return; - - case 0x46: /* Cmdcomplete was issued */ - p->status = 0x6000|dev->fifo; - m = dev->fifo; - USED(m); - dev->cmd = Msgaccept; - return; - - case 0x60: /* Msgaccept was issued */ - goto Done; - } -Done: - curcmd = 0; - wakeup(&scsirendez); -} - -#ifdef notdef -void -scsidump(void) -{ - SCSIdev *dev = ioaddr.scsi; - DMAdev *dma = ioaddr.dma; - - print("\nscsi:\n"); - print(" countlo=0x%2.2ux\n", dev->countlo); - print(" countmi=0x%2.2ux\n", dev->countmi); - print(" cmd =0x%2.2ux\n", dev->cmd); - print(" status =0x%2.2ux\n", dev->status); - print(" intr =0x%2.2ux\n", dev->intr); - print(" step =0x%2.2ux\n", dev->step); - print(" fflags =0x%2.2ux\n", dev->fflags); - print(" config =0x%2.2ux\n", dev->config); - print("dma:\n"); - print(" csr =0x%8.8ux\n", dma->csr); - print(" addr =0x%8.8ux\n", dma->addr); - print(" count =0x%4.4ux\n", dma->count); - print(" diag =0x%8.8ux\n", dma->diag); -} -#endif diff --git a/ss/scsibuf.c b/ss/scsibuf.c deleted file mode 100644 index cc6edda894648d72ddf5c16fd676c195fb8e3991..0000000000000000000000000000000000000000 --- a/ss/scsibuf.c +++ /dev/null @@ -1,63 +0,0 @@ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "../port/error.h" -#include "io.h" - -/* - * The following routines - * scsibufreset, scsibuf, scsifree and scsialloc - * provide a pool of buffers used for scsi i/o. - * This is simplistic at best, and opportunities for - * deadlock abound. - */ -#define Nbuf 2 - -struct { - Lock; - Scsibuf *free; -} scsibufalloc; - -void -scsibufreset(ulong datasize) -{ - int i; - - for(i = 0; i < Nbuf; i++) - scsifree(scsialloc(datasize)); - lock(&scsibufalloc); - unlock(&scsibufalloc); -} - -/* - * get a scsi io buffer of DATASIZE size - */ -Scsibuf * -scsibuf(void) -{ - Scsibuf *b; - - for(;;) { - lock(&scsibufalloc); - b = scsibufalloc.free; - if(b != 0) { - scsibufalloc.free = b->next; - unlock(&scsibufalloc); - return b; - } - unlock(&scsibufalloc); - resrcwait(0); - } - return 0; /* not reached */ -} - -void -scsifree(Scsibuf *b) -{ - lock(&scsibufalloc); - b->next = scsibufalloc.free; - scsibufalloc.free = b; - unlock(&scsibufalloc); -} diff --git a/ss/segment.h b/ss/segment.h deleted file mode 100644 index 7526c3e4ac9dc037f81d2dce7573ae1682db084e..0000000000000000000000000000000000000000 --- a/ss/segment.h +++ /dev/null @@ -1,10 +0,0 @@ -/* - * Attach segment types - */ - -Physseg physseg[] = { - { SG_SHARED, "shared", 0, SEGMAXSIZE, 0, 0 }, - { SG_PHYSICAL, "kmem", KZERO, SEGMAXSIZE, 0, 0 }, - { SG_BSS, "memory", 0, SEGMAXSIZE, 0, 0 }, - { 0, 0, 0, 0, 0, 0 }, -}; diff --git a/ss/stream.h b/ss/stream.h deleted file mode 100644 index f11ccc806670a02c79d09779e4dd31c22d2e938d..0000000000000000000000000000000000000000 --- a/ss/stream.h +++ /dev/null @@ -1,5 +0,0 @@ -extern Qinfo noetherinfo; - -void streaminit0(void){ - newqinfo(&noetherinfo); -} diff --git a/ss/trap.c b/ss/trap.c deleted file mode 100644 index e26af4f64860b34e682c6e953842415cb10b3ccf..0000000000000000000000000000000000000000 --- a/ss/trap.c +++ /dev/null @@ -1,626 +0,0 @@ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "ureg.h" -#include "io.h" -#include "../port/error.h" - -void noted(Ureg**, ulong); -void rfnote(Ureg**); -int domuldiv(ulong, Ureg*); - -extern Label catch; -extern void traplink(void); -extern void syslink(void); - - long ticks; -static char excbuf[64]; /* BUG: not reentrant! */ - -char *trapname[]={ - "reset", - "instruction access exception", - "illegal instruction", - "privileged instruction", - "fp: disabled", - "window overflow", - "window underflow", - "unaligned address", - "fp: exception", - "data access exception", - "tag overflow", - "watchpoint detected", -}; - -char *fptrapname[]={ - "none", - "IEEE 754 exception", - "unfinished FP op", - "unimplemented FP op", - "sequence error", - "hardware error", - "invalid FP register", - "reserved", -}; - -char* -excname(ulong tbr) -{ - char xx[64]; - char *t; - ulong fsr; - - switch(tbr){ - case 8: - if(u == 0) - panic("fptrap in kernel\n"); - else{ - if(m->fpunsafe==0 && u->p->fpstate!=FPactive) - panic("fptrap not active\n"); - fsr = u->fpsave.fsr; - sprint(excbuf, "fp: %s fppc=0x%lux", - fptrapname[(fsr>>14)&7], - u->fpsave.q[0].a, fsr); - } - return excbuf; - case 36: - return "trap: cp disabled"; - case 37: - return "trap: unimplemented instruction"; - case 40: - return "trap: cp exception"; - case 42: - return "trap: divide by zero"; - case 128: - return "syscall"; - case 129: - return "breakpoint"; - } - t = 0; - if(tbr < sizeof trapname/sizeof(char*)) - t = trapname[tbr]; - if(t == 0){ - if(tbr >= 130) - sprint(xx, "trap instruction %d", tbr-128); - else if(17<=tbr && tbr<=31) - sprint(xx, "interrupt level %d", tbr-16); - else - sprint(xx, "unknown trap %d", tbr); - t = xx; - } - if(strncmp(t, "fp: ", 4) == 0) - strcpy(excbuf, t); - else - sprint(excbuf, "trap: %s", t); - return excbuf; -} - -void -trap(Ureg *ur) -{ - int user, x; - char buf[64]; - ulong tbr, iw; - - tbr = (ur->tbr&0xFFF)>>4; - /* - * Hack to catch bootstrap fault during probe - */ - if(catch.pc) - gotolabel(&catch); - - if(u) - u->dbgreg = ur; - - user = !(ur->psr&PSRPSUPER); - /* SS2 bug: flush cache line holding trap entry in table */ - if(conf.ss2cachebug) - putsysspace(CACHETAGS+((TRAPS+16*tbr)&(conf.vacsize-1)), 0); - if(tbr > 16){ /* interrupt */ - if(u && u->p->state==Running){ - /* if active, FPop at head of Q is probably an excep */ - if(u->p->fpstate == FPactive){ - fpquiet(); - savefpregs(&u->fpsave); - u->p->fpstate = FPinactive; - } - } - switch(tbr-16){ - case 15: /* asynch mem err */ - faultasync(ur); - break; - case 14: /* counter 1 */ - clock(ur); - break; - case 12: /* keyboard and mouse */ - sccintr(); - break; - case 5: /* lance */ - lanceintr(); - break; - case 3: /* lance */ - scsiintr(); - break; - default: - goto Error; - } - }else{ - switch(tbr){ - case 1: /* instr. access */ - case 9: /* data access */ - if(u && u->p->fpstate==FPactive) { - fpquiet(); - savefpregs(&u->fpsave); - u->p->fpstate = FPinactive; - } - if(u){ - x = u->p->insyscall; - u->p->insyscall = 1; - faultsparc(ur); - u->p->insyscall = x; - }else - faultsparc(ur); - goto Return; - case 2: /* illegal instr, maybe mul */ - iw = *(ulong*)ur->pc; - if((iw&0xC1500000) == 0x80500000){ - if(domuldiv(iw, ur)) - goto Return; - tbr = ur->tbr; - } - break; - case 4: /* floating point disabled */ - if(u && u->p){ - if(u->p->fpstate == FPinit) - restfpregs(initfpp, u->fpsave.fsr); - else if(u->p->fpstate == FPinactive) - restfpregs(&u->fpsave, u->fpsave.fsr); - else - break; - u->p->fpstate = FPactive; - ur->psr |= PSREF; - return; - } - break; - case 8: /* floating point exception */ - /* if unsafe, trap happened shutting down FPU; just return */ - if(m->fpunsafe){ - m->fptrap = (fptrap()==0); - return; - } - if(fptrap()) - goto Return; /* handled the problem */ - break; - default: - break; - } - Error: - if(user){ - spllo(); - sprint(buf, "sys: %s", excname(tbr)); - postnote(u->p, 1, buf, NDebug); - }else - panic("kernel trap: %s pc=0x%lux\n", excname(tbr), ur->pc); - } - Return: - if(user){ - notify(ur); - if(u->p->fpstate == FPinactive) { - restfpregs(&u->fpsave, u->fpsave.fsr); - u->p->fpstate = FPactive; - ur->psr |= PSREF; - } - } -} - -void -trapinit(void) -{ - int i; - long t, a; - - a = ((ulong)traplink-TRAPS)>>2; - a += 0x40000000; /* CALL traplink(SB) */ - t = TRAPS; - for(i=0; i<256; i++){ - /* ss2: must flush cache line for table */ - *(ulong*)(t+0) = a; /* CALL traplink(SB) */ - *(ulong*)(t+4) = 0xa7480000; /* MOVW PSR, R19 */ - a -= 16/4; - t += 16; - } - /* - * Vector 128 goes directly to syslink - */ - t = TRAPS+128*16; - a = ((ulong)syslink-t)>>2; - a += 0x40000000; - *(ulong*)t = a; /* CALL syscall(SB) */ - *(ulong*)(t+4) = 0xa7480000; /* MOVW PSR, R19 */ - puttbr(TRAPS); - setpsr(getpsr()|PSRET|SPL(15)); /* enable traps, not interrupts */ -} - -void -mulu(ulong u1, ulong u2, ulong *lop, ulong *hip) -{ - ulong lo1, lo2, hi1, hi2, lo, hi, t1, t2, t; - - lo1 = u1 & 0xffff; - lo2 = u2 & 0xffff; - hi1 = u1 >> 16; - hi2 = u2 >> 16; - - lo = lo1 * lo2; - t1 = lo1 * hi2; - t2 = lo2 * hi1; - hi = hi1 * hi2; - t = lo; - lo += t1 << 16; - if(lo < t) - hi++; - t = lo; - lo += t2 << 16; - if(lo < t) - hi++; - hi += (t1 >> 16) + (t2 >> 16); - *lop = lo; - *hip = hi; -} - -void -muls(long l1, long l2, long *lop, long *hip) -{ - ulong t, lo, hi; - ulong mlo, mhi; - int sign; - - sign = 0; - if(l1 < 0){ - sign ^= 1; - l1 = -l1; - } - if(l2 < 0){ - sign ^= 1; - l2 = -l2; - } - mulu(l1, l2, &mlo, &mhi); - lo = mlo; - hi = mhi; - if(sign){ - t = lo = ~lo; - hi = ~hi; - lo++; - if(lo < t) - hi++; - } - *lop = lo; - *hip = hi; -} - -int -domuldiv(ulong iw, Ureg *ur) -{ - long op1, op2; - long *regp; - long *regs; - - regs = (long*)ur; - if(iw & (1<<13)){ /* signed immediate */ - op2 = iw & 0x1FFF; - if(op2 & 0x1000) - op2 |= ~0x1FFF; - }else - op2 = regs[iw&0x1F]; - op1 = regs[(iw>>14)&0x1F]; - regp = ®s[(iw>>25)&0x1F]; - - if(iw & (4<<19)){ /* divide */ - if(ur->y!=0 && ur->y!=~0){ - unimp: - ur->tbr = 37; /* "unimplemented instruction" */ - return 0; /* complex Y is too hard */ - } - if(op2 == 0){ - ur->tbr = 42; /* "zero divide" */ - return 0; - } - if(iw & (1<<19)){ - if(ur->y && (op1&(1<<31))==0) - goto unimp; /* Y not sign extension */ - *regp = op1 / op2; - }else{ - if(ur->y) - goto unimp; - *regp = (ulong)op1 / (ulong)op2; - } - }else{ - if(iw & (1<<19)) - muls(op1, op2, regp, (long*)&ur->y); - else - mulu(op1, op2, (ulong*)regp, &ur->y); - } - if(iw & (16<<19)){ /* set CC */ - ur->psr &= ~(0xF << 20); - if(*regp & (1<<31)) - ur->psr |= 8 << 20; /* N */ - if(*regp == 0) - ur->psr |= 4 << 20; /* Z */ - /* BUG: don't get overflow right on divide */ - } - ur->pc += 4; - ur->npc = ur->pc+4; - return 1; -} - -void -dumpstack(void) -{ - ulong l, v; - int i; - extern ulong etext; - static int dumping; - - if(dumping == 1){ - print("no dumpstack\n"); - return; - } - - dumping = 1; - if(u){ - i = 0; - for(l=(ulong)&l; lp->text, u->p->pid); - else - print("registers for kernel\n"); - print("PSR=%ux PC=%lux TBR=%lux\n", ur->psr, ur->pc, ur->tbr); - l = &ur->r0; - for(i=0; i<32; i+=2, l+=2) - print("R%d\t%.8lux\tR%d\t%.8lux\n", i, l[0], i+1, l[1]); - dumpstack(); -} - -int -notify(Ureg *ur) -{ - int l, sent; - ulong s, sp; - Note *n; - - if(u->p->procctl) - procctl(u->p); - if(u->nnote == 0) - return 0; - - s = spllo(); - qlock(&u->p->debug); - u->p->notepending = 0; - n = &u->note[0]; - if(strncmp(n->msg, "sys:", 4) == 0){ - l = strlen(n->msg); - if(l > ERRLEN-15) /* " pc=0x12345678\0" */ - l = ERRLEN-15; - sprint(n->msg+l, " pc=0x%lux", ur->pc); - } - if(n->flag!=NUser && (u->notified || u->notify==0)){ - if(n->flag == NDebug) - pprint("suicide: %s\n", n->msg); - Die: - qunlock(&u->p->debug); - pexit(n->msg, n->flag!=NDebug); - } - sent = 0; - if(!u->notified){ - if(!u->notify) - goto Die; - sent = 1; - u->svpsr = ur->psr; - sp = ur->usp; - sp -= sizeof(Ureg)+ERRLEN+3*BY2WD; - sp &= ~7; /* SP must be 8-byte aligned */ - sp += ERRLEN+3*BY2WD; - if(!okaddr((ulong)u->notify, 1, 0) - || !okaddr(sp-ERRLEN-3*BY2WD, sizeof(Ureg)+ERRLEN-3*BY2WD, 0)){ - pprint("suicide: bad address in notify\n"); - qunlock(&u->p->debug); - pexit("Suicide", 0); - } - u->ureg = (void*)sp; - memmove((Ureg*)sp, ur, sizeof(Ureg)); - sp -= ERRLEN; - memmove((char*)sp, u->note[0].msg, ERRLEN); - sp -= 3*BY2WD; - *(ulong*)(sp+2*BY2WD) = sp+3*BY2WD; /* arg 2 is string */ - *(ulong*)(sp+1*BY2WD) = (ulong)u->ureg; /* arg 1 is ureg* (compat) */ - u->svr7 = ur->r7; /* save away r7 */ - ur->r7 = (ulong)u->ureg; /* arg 1 is ureg* */ - *(ulong*)(sp+1*BY2WD) = (ulong)u->ureg; /* arg 1 0(FP) is ureg* */ - *(ulong*)(sp+0*BY2WD) = 0; /* arg 0 is pc */ - ur->usp = sp; - ur->pc = (ulong)u->notify; - ur->npc = (ulong)u->notify+4; - u->notified = 1; - u->nnote--; - memmove(&u->lastnote, &u->note[0], sizeof(Note)); - memmove(&u->note[0], &u->note[1], u->nnote*sizeof(Note)); - } - qunlock(&u->p->debug); - splx(s); - return sent; -} - -/* - * Return user to state before notify() - */ -void -noted(Ureg **urp, ulong arg0) -{ - Ureg *nur; - - nur = u->ureg; - if(nur->psr!=u->svpsr){ - pprint("bad noted ureg psr %lux\n", nur->psr); - Die: - pexit("Suicide", 0); - } - qlock(&u->p->debug); - if(!u->notified){ - qunlock(&u->p->debug); - pprint("call to noted() when not notified\n"); - goto Die; - } - u->notified = 0; - memmove(*urp, u->ureg, sizeof(Ureg)); - (*urp)->r7 = u->svr7; - switch(arg0){ - case NCONT: - if(!okaddr(nur->pc, 1, 0) || !okaddr(nur->usp, BY2WD, 0)){ - pprint("suicide: trap in noted\n"); - qunlock(&u->p->debug); - goto Die; - } - splhi(); - qunlock(&u->p->debug); - rfnote(urp); - break; - /* never returns */ - - default: - pprint("unknown noted arg 0x%lux\n", arg0); - u->lastnote.flag = NDebug; - /* fall through */ - - case NDFLT: - if(u->lastnote.flag == NDebug) - pprint("suicide: %s\n", u->lastnote.msg); - qunlock(&u->p->debug); - pexit(u->lastnote.msg, u->lastnote.flag!=NDebug); - } -} - -#include "../port/systab.h" - -long -syscall(Ureg *aur) -{ - long ret; - ulong sp; - Ureg *ur; - - ur = aur; - if(ur->psr & PSRPSUPER) - panic("recursive system call"); - u->p->insyscall = 1; - u->p->pc = ur->pc; - - /* SS2 bug: flush cache line holding trap entry in table */ - if(conf.ss2) - putsysspace(CACHETAGS+((TRAPS+16*128)&(conf.vacsize-1)), 0); - - if(u->p->fpstate == FPactive) { - fpquiet(); - u->p->fpstate = FPinit; - u->fpsave.fsr = getfsr(); - ur->psr &= ~PSREF; - } - spllo(); - - u->scallnr = ur->r7; - sp = ur->usp; - - u->nerrlab = 0; - ret = -1; - if(!waserror()){ - if(u->scallnr >= sizeof systab/BY2WD){ - pprint("bad sys call number %d pc %lux\n", u->scallnr, ur->pc); - postnote(u->p, 1, "sys: bad sys call", NDebug); - error(Ebadarg); - } - - if(sp & (BY2WD-1)){ - pprint("odd sp in sys call pc %lux sp %lux\n", ur->pc, ur->sp); - postnote(u->p, 1, "sys: odd stack", NDebug); - error(Ebadarg); - } - - if(sp<(USTKTOP-BY2PG) || sp>(USTKTOP-sizeof(Sargs))) - validaddr(sp, sizeof(Sargs), 0); - - u->s = *((Sargs*)(sp+1*BY2WD)); - u->p->psstate = sysctab[u->scallnr]; - - ret = (*systab[u->scallnr])(u->s.args); - poperror(); - } - - ur->pc += 4; - ur->npc = ur->pc+4; - u->nerrlab = 0; - if(u->p->procctl) - procctl(u->p); - - u->p->insyscall = 0; - u->p->psstate = 0; - if(u->scallnr == NOTED) /* ugly hack */ - noted(&aur, *(ulong*)(sp+1*BY2WD)); /* doesn't return */ - - splhi(); - if(u->scallnr!=RFORK && (u->p->procctl || u->nnote)){ - ur->r7 = ret; /* load up for noted() */ - if(notify(ur)) - return ur->r7; - } - return ret; -} - -long -execregs(ulong entry, ulong ssize, ulong nargs) -{ - ulong *sp; - - sp = (ulong*)(USTKTOP - ssize); - *--sp = nargs; - ((Ureg*)UREGADDR)->usp = (ulong)sp; - ((Ureg*)UREGADDR)->pc = entry - 4; /* syscall advances it */ - u->fpsave.fsr = initfpp->fsr; - return USTKTOP-BY2WD; /* address of user-level clock */ -} - -ulong -userpc(void) -{ - return ((Ureg*)UREGADDR)->pc; -} - -/* This routine must save the values of registers the user is not permitted to write - * from devproc and the restore the saved values before returning - */ -void -setregisters(Ureg *xp, char *pureg, char *uva, int n) -{ - ulong psr; - - psr = xp->psr; - memmove(pureg, uva, n); - xp->psr = psr; -} diff --git a/ss/u.h b/ss/u.h deleted file mode 100644 index edb76330f603dab56562d4ce1ce564f1da94a305..0000000000000000000000000000000000000000 --- a/ss/u.h +++ /dev/null @@ -1,18 +0,0 @@ -typedef unsigned int uint; -typedef unsigned short ushort; -typedef unsigned char uchar; -typedef signed char schar; -typedef unsigned long ulong; -typedef long vlong; -typedef union Length Length; -typedef ushort Rune; - -union Length -{ - char clength[8]; - vlong vlength; - struct{ - long hlength; - long length; - }; -};