From aed4b11f664ff86f536220d5861470a654ad0a8e Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Sun, 27 May 2001 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 2001-05-27 --- alphapc/ns16552.h | 51 -- boot/aux.c | 20 +- boot/boot.c | 221 +---- boot/boot.h | 11 +- boot/bootcache.c | 12 +- boot/bootip.c | 46 +- boot/doauthenticate.c | 10 +- boot/fcall.c | 171 ---- boot/glendakey.c | 26 - boot/key.c | 3 + boot/local.c | 32 +- boot/nopsession.c | 3 + boot/sac.c | 16 +- boot/settime.c | 25 +- boot/userpasswd.c | 30 +- carrera/audio.h | 37 - carrera/clock.c | 143 ---- carrera/dat.h | 186 ---- carrera/devether.c | 431 ---------- carrera/devrtc.c | 431 ---------- carrera/dma.c | 125 --- carrera/etherif.h | 48 -- carrera/ethersonic.c | 727 ---------------- carrera/faultmips.c | 153 ---- carrera/fns.h | 91 -- carrera/fptrap.c | 286 ------- carrera/io.h | 133 --- carrera/kbd.c | 421 ---------- carrera/l.s | 802 ------------------ carrera/main.c | 616 -------------- carrera/mem.h | 243 ------ carrera/memmove.s | 241 ------ carrera/memset.s | 90 -- carrera/mmu.c | 391 --------- carrera/ns16552.h | 19 - carrera/random.c | 138 --- carrera/screen.c | 620 -------------- carrera/screen.h | 20 - carrera/trap.c | 888 -------------------- carrera/ureg.h | 1 - ip/chandial.c | 6 +- ip/devip.c | 128 ++- ip/ethermedium.c | 4 +- ip/il.c | 2 +- ip/ip.h | 8 +- ip/tcp.c | 2 +- mpc/_inb.s | 110 --- mpc/clock.c | 212 ----- mpc/cmmu.c | 391 --------- mpc/conf.c | 74 -- mpc/cpm.c | 566 ------------- mpc/cpm2.c | 819 ------------------ mpc/dat.h | 233 ------ mpc/devether.c | 451 ---------- mpc/devpcmcia.c | 1109 ------------------------ mpc/devrtc.c | 325 ------- mpc/devsac.c | 528 ------------ mpc/devuart.c | 1463 -------------------------------- mpc/devusb.c | 628 -------------- mpc/ether589.c | 156 ---- mpc/etherelnk3.c | 1863 ----------------------------------------- mpc/etherif.h | 28 - mpc/etherscc.c | 630 -------------- mpc/etherwavelan.c | 946 --------------------- mpc/etherwavelan.h | 494 ----------- mpc/fns.h | 120 --- mpc/inb.s | 119 --- mpc/inbc.c | 134 --- mpc/io.h | 592 ------------- mpc/l.s | 952 --------------------- mpc/main.c | 402 --------- mpc/mem.h | 216 ----- mpc/memspeed.c | 53 -- mpc/mmu.c | 172 ---- mpc/ms.c | 82 -- mpc/nocache.c | 38 - mpc/random.c | 138 --- mpc/rmap.c | 106 --- mpc/sh.c | 481 ----------- mpc/spi.c | 547 ------------ mpc/tar.c | 86 -- mpc/trap.c | 828 ------------------ mpc/unsac.c | 627 -------------- pc/cga.c | 21 +- pc/dat.h | 6 +- pc/devarch.c | 22 +- pc/devastar.c | 5 + pc/devether.c | 46 +- pc/devfloppy.c | 16 +- pc/devi82365.c | 41 +- pc/devlml.c | 2 +- pc/devlpt.c | 39 +- pc/devrtc.c | 25 +- pc/devusb.c | 91 +- pc/devvga.c | 75 +- pc/ether2114x.c | 4 +- pc/ether79c970.c | 15 +- pc/ether82557.c | 4 +- pc/etherec2t.c | 5 +- pc/etherwavelan.c | 45 +- pc/fns.h | 10 +- pc/i8259.c | 2 +- pc/io.h | 2 +- pc/kpmemmove.c | 21 - pc/l.s | 8 + pc/main.c | 152 +--- pc/memory.c | 13 +- pc/mmu.c | 22 - pc/mouse.c | 11 +- pc/mp.c | 15 +- pc/ns16552.h | 217 ----- pc/screen.c | 148 +--- pc/screen.h | 7 +- pc/sd53c8xx.c | 13 +- pc/sdata.c | 12 +- pc/sdmylex.c | 4 +- pc/sdscsi.c | 4 +- pc/trap.c | 33 +- pc/uarti8250.c | 648 ++++++++++++++ pc/vga.c | 16 - pc/vga3dfx.c | 6 +- pc/vgaclgd546x.c | 6 +- pc/vgacyber938x.c | 19 +- pc/vgahiqvideo.c | 3 +- pc/vgamach64xx.c | 597 ++----------- pc/vgamga2164w.c | 6 +- pc/vganeomagic.c | 6 +- pc/vgas3.c | 19 +- pc/vgat2r4.c | 6 +- port/allocb.c | 1 - port/auth.c | 662 ++++----------- port/cache.c | 34 +- port/chan.c | 1058 ++++++++++++++++------- port/dev.c | 229 +++-- port/devaudio.c | 33 +- port/devcap.c | 266 ++++++ port/devcons.c | 199 +++-- port/devdraw.c | 67 +- port/devdup.c | 87 +- port/devenv.c | 49 +- port/devintrts.c | 134 --- port/devkprof.c | 25 +- port/devmnt.c | 498 +++++------ port/devmntstats.c | 5 +- port/devmouse.c | 57 +- port/devns16552.c | 1228 --------------------------- port/devpipe.c | 87 +- port/devproc.c | 168 ++-- port/devroot.c | 62 +- port/devsd.c | 169 ++-- port/devsrv.c | 60 +- port/devssl.c | 137 +-- port/devuart.c | 632 ++++++++++++++ port/error.h | 4 +- port/lib.h | 60 +- port/netif.c | 83 +- port/netif.h | 16 +- port/parse.c | 12 +- port/pgrp.c | 19 +- port/portclock.c | 2 + port/portdat.h | 192 +++-- port/portfns.h | 57 +- port/proc.c | 46 +- port/qio.c | 4 +- port/rdb.c | 5 +- port/sd.h | 6 +- port/segment.c | 50 +- port/swap.c | 11 +- port/sysfile.c | 452 +++++----- port/sysproc.c | 78 +- port/systab.h | 67 +- port/taslock.c | 4 +- port/thwack.h | 3 +- port/unthwack.c | 95 +-- port/watchdog.c | 136 --- 175 files changed, 4786 insertions(+), 29878 deletions(-) delete mode 100644 alphapc/ns16552.h delete mode 100644 boot/fcall.c delete mode 100644 boot/glendakey.c delete mode 100644 carrera/audio.h delete mode 100644 carrera/clock.c delete mode 100644 carrera/dat.h delete mode 100644 carrera/devether.c delete mode 100644 carrera/devrtc.c delete mode 100644 carrera/dma.c delete mode 100644 carrera/etherif.h delete mode 100644 carrera/ethersonic.c delete mode 100644 carrera/faultmips.c delete mode 100644 carrera/fns.h delete mode 100644 carrera/fptrap.c delete mode 100644 carrera/io.h delete mode 100644 carrera/kbd.c delete mode 100644 carrera/l.s delete mode 100644 carrera/main.c delete mode 100644 carrera/mem.h delete mode 100644 carrera/memmove.s delete mode 100644 carrera/memset.s delete mode 100644 carrera/mmu.c delete mode 100644 carrera/ns16552.h delete mode 100644 carrera/random.c delete mode 100644 carrera/screen.c delete mode 100644 carrera/screen.h delete mode 100644 carrera/trap.c delete mode 100644 carrera/ureg.h delete mode 100644 mpc/_inb.s delete mode 100644 mpc/clock.c delete mode 100644 mpc/cmmu.c delete mode 100644 mpc/conf.c delete mode 100644 mpc/cpm.c delete mode 100644 mpc/cpm2.c delete mode 100644 mpc/dat.h delete mode 100644 mpc/devether.c delete mode 100644 mpc/devpcmcia.c delete mode 100644 mpc/devrtc.c delete mode 100644 mpc/devsac.c delete mode 100644 mpc/devuart.c delete mode 100644 mpc/devusb.c delete mode 100644 mpc/ether589.c delete mode 100644 mpc/etherelnk3.c delete mode 100644 mpc/etherif.h delete mode 100644 mpc/etherscc.c delete mode 100644 mpc/etherwavelan.c delete mode 100644 mpc/etherwavelan.h delete mode 100644 mpc/fns.h delete mode 100644 mpc/inb.s delete mode 100644 mpc/inbc.c delete mode 100644 mpc/io.h delete mode 100644 mpc/l.s delete mode 100644 mpc/main.c delete mode 100644 mpc/mem.h delete mode 100644 mpc/memspeed.c delete mode 100644 mpc/mmu.c delete mode 100644 mpc/ms.c delete mode 100644 mpc/nocache.c delete mode 100644 mpc/random.c delete mode 100644 mpc/rmap.c delete mode 100644 mpc/sh.c delete mode 100644 mpc/spi.c delete mode 100644 mpc/tar.c delete mode 100644 mpc/trap.c delete mode 100644 mpc/unsac.c delete mode 100644 pc/kpmemmove.c delete mode 100644 pc/ns16552.h create mode 100644 pc/uarti8250.c create mode 100644 port/devcap.c delete mode 100644 port/devintrts.c delete mode 100644 port/devns16552.c create mode 100644 port/devuart.c delete mode 100644 port/watchdog.c diff --git a/alphapc/ns16552.h b/alphapc/ns16552.h deleted file mode 100644 index b95b61fcb73d411307e61bb3742f589278e01433..0000000000000000000000000000000000000000 --- a/alphapc/ns16552.h +++ /dev/null @@ -1,51 +0,0 @@ -#define uartwrreg(u,r,v) outb((u)->port + (r), (u)->sticky[r] | (v)) -#define uartrdreg(u,r) inb((u)->port + (r)) - -#define uartpower(x, y) - -void ns16552setup(ulong, ulong, char*, int); -void ns16552intr(int); -void uartclock(void); - -/* - * handle an interrupt to a single uart - */ -static void -ns16552intrx(Ureg*, void* arg) -{ - ns16552intr((ulong)arg); -} - -void -ns16552install(void) -{ - static int already; - - if(already) - return; - already = 1; - - if(ioalloc(Uart0, 8, 0, "eia0") < 0) - print("eia0: port %d in use\n", Uart0); - ns16552setup(Uart0, UartFREQ, "eia0", Ns550); - intrenable(IrqUART0, ns16552intrx, (void*)0, BUSUNKNOWN, "eia0"); - if(ioalloc(Uart1, 8, 0, "eia1") < 0) - print("eia1: port %d in use\n", Uart1); - ns16552setup(Uart1, UartFREQ, "eia1", Ns550); - intrenable(IrqUART1, ns16552intrx, (void*)0, BUSUNKNOWN, "eia1"); - addclock0link(uartclock); -} - -#define RD(r) inb(Uart0+(r)) -static void -ns16552iputc(char c) -{ - mb(); - while((RD(5) & (1<<5)) == 0) - mb(); - outb(Uart0, c); - mb(); - while((RD(5) & (1<<5)) == 0) - mb(); -} - diff --git a/boot/aux.c b/boot/aux.c index 7a2a7ed59a2f675f67ec4c77cd0f4e15b698cb41..8241228efc1d2984199f49f66777af3e18d95696 100644 --- a/boot/aux.c +++ b/boot/aux.c @@ -54,13 +54,21 @@ sendmsg(int fd, char *msg) void warning(char *s) { - fprint(2, "boot: %s: %r\n", s); + char buf[ERRMAX]; + + buf[0] = '\0'; + errstr(buf, sizeof buf); + fprint(2, "boot: %s: %s\n", s, buf); } void fatal(char *s) { - fprint(2, "boot fatal: %s: %r\n", s); + char buf[ERRMAX]; + + buf[0] = '\0'; + errstr(buf, sizeof buf); + fprint(2, "boot: %s: %s\n", s, buf); exits(0); } @@ -97,9 +105,9 @@ void setenv(char *name, char *val) { int f; - char ename[2*NAMELEN]; + char ename[64]; - sprint(ename, "#e/%s", name); + snprint(ename, sizeof ename, "#e/%s", name); f = create(ename, 1, 0666); if(f < 0) return; @@ -112,7 +120,7 @@ srvcreate(char *name, int fd) { char *srvname; int f; - char buf[2*NAMELEN]; + char buf[64]; srvname = strrchr(name, '/'); if(srvname) @@ -120,7 +128,7 @@ srvcreate(char *name, int fd) else srvname = name; - sprint(buf, "#s/%s", srvname); + snprint(buf, sizeof buf, "#s/%s", srvname); f = create(buf, 1, 0666); if(f < 0) fatal(buf); diff --git a/boot/boot.c b/boot/boot.c index bf84fb3086525dfeba4857f0461abb00afcd7522..69b69843f7542c5f1e34a2a3be03a1efad782fa4 100644 --- a/boot/boot.c +++ b/boot/boot.c @@ -4,9 +4,8 @@ #include #include "../boot/boot.h" -char cputype[NAMELEN]; -char sys[2*NAMELEN]; -char username[NAMELEN]; +char cputype[64]; +char sys[2*64]; char reply[256]; int printcol; int mflag; @@ -17,18 +16,17 @@ char *bargv[Nbarg]; int bargc; static void swapproc(void); -static void recover(Method*); static Method *rootserver(char*); static int rconv(va_list *arg, Fconv *fp) { - char s[ERRLEN]; + char s[ERRMAX]; USED(arg); - s[0] = 0; - errstr(s); + s[0] = '\0'; + errstr(s, sizeof s); strconv(s, fp); return 0; } @@ -38,10 +36,13 @@ boot(int argc, char *argv[]) { int fd; Method *mp; - char *cmd, cmdbuf[64], *iargv[16]; + char cmd[64]; char rootbuf[64]; - int islocal, ishybrid, iargc; + char flags[6]; + int islocal, ishybrid; char *rp; + int n; + char buf[32]; sleep(1000); @@ -90,22 +91,20 @@ 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(getenv("srvold9p")) + fd = old9p(fd); + print("version..."); + buf[0] = '\0'; + n = fversion(fd, 0, buf, sizeof buf); + if(n < 0) + fatal("can't init 9P"); + print("(%.*s)", n, buf); if(!islocal && !ishybrid){ if(cfs) fd = (*cfs)(fd); @@ -151,11 +150,10 @@ boot(int argc, char *argv[]) * if a local file server exists and it's not * running, start it and mount it onto /n/kfs */ - if(access("#s/kfs", 0) < 0){ + if(0 && access("#s/kfs", 0) < 0){ /* BUG: DISABLED UNTIL KFS SUPPORTS 9P2000 */ for(mp = method; mp->name; mp++){ if(strcmp(mp->name, "local") != 0) continue; - bargc = 1; (*mp->config)(mp); fd = (*mp->connect)(); if(fd < 0) @@ -169,24 +167,9 @@ boot(int argc, char *argv[]) settime(islocal); swapproc(); - cmd = getenv("init"); - if(cmd == nil){ - sprint(cmdbuf, "/%s/init -%s%s", cputype, - cpuflag ? "c" : "t", mflag ? "m" : ""); - cmd = cmdbuf; - } - iargc = tokenize(cmd, iargv, nelem(iargv)-1); - cmd = iargv[0]; - - /* make iargv[0] basename(iargv[0]) */ - if(iargv[0] = strrchr(iargv[0], '/')) - iargv[0]++; - else - iargv[0] = cmd; - - iargv[iargc] = nil; - - exec(cmd, iargv); + sprint(cmd, "/%s/ninit", cputype); + sprint(flags, "-%s%s", cpuflag ? "c" : "t", mflag ? "m" : ""); + execl(cmd, "init", flags, 0); fatal(cmd); } @@ -213,34 +196,6 @@ findmethod(char *a) return 0; } -int -parsecmd(char *s, char **av, int n) -{ - int ac; - - n--; - for(ac = 0; ac < n; ac++){ - while(*s == ' ' || *s == '\t') - s++; - if(*s == 0 || *s == '\n' || *s == '\r') - break; - if(*s == '\''){ - s++; - av[ac] = s; - while(*s && *s != '\'') - s++; - } else { - av[ac] = s; - while(*s && *s != ' ' && *s != '\t') - s++; - } - if(*s != 0) - *s++ = 0; - } - av[ac] = 0; - return ac; -} - /* * ask user from whence cometh the root file system */ @@ -276,7 +231,7 @@ rootserver(char *arg) outin(prompt, reply, sizeof(reply)); mp = findmethod(reply); if(mp){ - bargc = parsecmd(reply, bargv, Nbarg); + bargc = getfields(reply, bargv, Nbarg-1, 1, " "); cp = strchr(reply, '!'); if(cp) strcpy(sys, cp+1); @@ -287,44 +242,6 @@ 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) { @@ -340,79 +257,29 @@ swapproc(void) 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!%s down, wait...\n", buf, 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("\nboot: 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); -} - -static void -recover(Method *mp) +int +old9p(int fd) { - int fd, n; - char buf[256]; + int p[2]; - fd = open("#/./recover", ORDWR); - if(fd < 0) - exits(0); + if(pipe(p) < 0) + fatal("pipe"); - for(;;) { - n = read(fd, buf, sizeof(buf)); - if(n < 0) - exits(0); - buf[n] = '\0'; - - if(fork() == 0) - reattach(fd, mp, buf); + print("srvold9p..."); + switch(fork()) { + case -1: + fatal("rfork srvold9p"); + case 0: + dup(fd, 1); + close(fd); + dup(p[0], 0); + close(p[0]); + close(p[1]); + execl("/srvold9p", "srvold9p", "-s", 0); + fatal("exec srvold9p"); + default: + close(fd); + close(p[0]); } + return p[1]; } diff --git a/boot/boot.h b/boot/boot.h index 4cf8451980ecb1ebe825460572a53cd3f02e53d3..7d5f2b27e65179f39c9731a2dc96d1d4a73ef707 100644 --- a/boot/boot.h +++ b/boot/boot.h @@ -15,15 +15,15 @@ extern int cpuflag; extern char cputype[]; extern int fflag; extern int kflag; -extern int pushfcall(int); extern Method method[]; extern void (*pword)(int, Method*); extern char sys[]; extern uchar hostkey[]; -extern char username[NAMELEN]; +extern char username[]; +extern uchar statbuf[STATMAX]; enum { - Nbarg= 32, + Nbarg= 16, }; extern int bargc; extern char *bargv[Nbarg]; @@ -34,8 +34,6 @@ extern char* checkkey(Method*, char*, char*); extern void fatal(char*); extern void getpasswd(char*, int); extern void key(int, Method*); -extern void glendakey(int, Method*); -extern int nop(int); extern int outin(char*, char*, int); extern int plumb(char*, char*, int*, char*); extern int readfile(char*, char*, int); @@ -44,11 +42,12 @@ extern int sendmsg(int, char*); extern void setenv(char*, char*); extern void settime(int); extern void srvcreate(char*, int); -extern void userpasswd(int, Method*); +extern void setusername(int, Method*); extern void warning(char*); extern int writefile(char*, char*, int); extern void boot(int, char **); extern void doauthenticate(int, Method*); +extern int old9p(int); extern int parsefields(char*, char**, int, char*); /* methods */ diff --git a/boot/bootcache.c b/boot/bootcache.c index 4293cfdfa6b4d5a923dbf7d2f27a9a9752a6f9d2..f3cb16c2e0e9933cfea63825e4fcf80a7b45f40a 100644 --- a/boot/bootcache.c +++ b/boot/bootcache.c @@ -2,13 +2,15 @@ #include #include <../boot/boot.h> +uchar statbuf[STATMAX]; + int cache(int fd) { int argc, i, p[2]; - char *argv[5], bd[NAMELEN], buf[256], d[DIRLEN], partition[2*NAMELEN], *pp; + char *argv[5], bd[32], buf[256], partition[64], *pp; - if(stat("/cfs", d) < 0) + if(stat("/cfs", statbuf, sizeof statbuf) < 0) return fd; *partition = 0; @@ -19,7 +21,7 @@ cache(int fd) for(i = 0; i < argc; i++){ if(strcmp(argv[i], "off") == 0) return fd; - else if(stat(argv[i], d) >= 0){ + else if(stat(argv[i], statbuf, sizeof statbuf) >= 0){ strncpy(partition, argv[i], sizeof(partition)-1); partition[sizeof(partition)-1] = 0; } @@ -38,12 +40,12 @@ cache(int fd) else if(strcmp("fs", &bd[i-2]) == 0) bd[i-2] = 0; sprint(partition, "%scache", bd); - if(stat(partition, d) < 0) + if(stat(partition, statbuf, sizeof statbuf) < 0) *bd = 0; } if(*bd == 0){ sprint(partition, "%scache", bootdisk); - if(stat(partition, d) < 0) + if(stat(partition, statbuf, sizeof statbuf) < 0) return fd; } } diff --git a/boot/bootip.c b/boot/bootip.c index f9e7dbc98bccd65a0dab103ce2aad80abc24d0e8..b745b226acea88cc8cce32d4a0f74f610497d544 100644 --- a/boot/bootip.c +++ b/boot/bootip.c @@ -27,7 +27,7 @@ configip(void) arg = malloc((bargc+1) * sizeof(char*)); if(arg == nil) - fatal("malloc"); + fatal("%r"); memmove(arg, bargv, (bargc+1) * sizeof(char*)); argc = bargc; @@ -43,7 +43,6 @@ configip(void) case 'b': case 'h': case 'm': - case 'c': p = ARGF(); USED(p); break; @@ -57,7 +56,7 @@ configip(void) /* let ipconfig configure the ip interface */ switch(pid = fork()){ case -1: - fatal("configuring ip"); + fatal("configuring ip: %r"); case 0: exec("/ipconfig", arg); fatal("execing /ipconfig"); @@ -97,55 +96,54 @@ configip(void) } void -configil(Method*) +configtcp(Method*) { + sleep(100); + print("t"); + sleep(100); configip(); + sleep(100); + print("."); + sleep(100); } int -authil(void) +authtcp(void) { - char buf[2*NAMELEN]; - - sprint(buf, "il!%I!566", auip); - return dial(buf, 0, 0, 0); + return -1; } int -connectil(void) +connecttcp(void) { - char buf[2*NAMELEN]; + char buf[64]; - sprint(buf, "il!%I!17008", fsip); + snprint(buf, sizeof buf, "tcp!%I!564", fsip); return dial(buf, 0, 0, 0); } void -configtcp(Method*) +configil(Method*) { configip(); } int -authtcp(void) +authil(void) { - char buf[2*NAMELEN]; + char buf[64]; - sprint(buf, "tcp!%I!567", auip); + snprint(buf, sizeof buf, "il!%I!566", auip); return dial(buf, 0, 0, 0); } int -connecttcp(void) +connectil(void) { - char buf[2*NAMELEN]; - int fd; + char buf[64]; - sprint(buf, "tcp!%I!564", fsip); - fd = dial(buf, 0, 0, 0); - if(fd < 0) - return -1; - return pushfcall(fd); + snprint(buf, sizeof buf, "il!%I!17008", fsip); + return dial(buf, 0, 0, 0); } static int diff --git a/boot/doauthenticate.c b/boot/doauthenticate.c index 00984172c97404ae9511a80072ab622e27808f5c..f632ab08e29d36d69e07a63e25db4072f3acee12 100644 --- a/boot/doauthenticate.c +++ b/boot/doauthenticate.c @@ -27,7 +27,7 @@ fromauth(Method *mp, char *trbuf, char *tbuf) int afd; char t; char *msg; - static char error[2*ERRLEN]; + static char error[2*ERRMAX]; if(mp->auth == 0) fatal("no method for accessing auth server"); @@ -51,12 +51,12 @@ fromauth(Method *mp, char *trbuf, char *tbuf) } break; case AuthErr: - if(readn(afd, error, ERRLEN) < 0) { + if(readn(afd, error, ERRMAX) < 0) { sprint(error, "%s: %r", pbmsg); msg = error; } else { - error[ERRLEN-1] = 0; + error[ERRMAX-1] = 0; msg = error; } break; @@ -77,7 +77,7 @@ doauthenticate(int fd, Method *mp) char tbuf[2*TICKETLEN]; print("session..."); - if(fsession(fd, trbuf) < 0) + if(fsession(fd, trbuf, sizeof trbuf) < 0) fatal("session command failed"); /* no authentication required? */ @@ -86,7 +86,9 @@ doauthenticate(int fd, Method *mp) return; /* try getting to an auth server */ + print("getting ticket..."); msg = fromauth(mp, trbuf, tbuf); + print("authenticating..."); if(msg == 0) if(fauth(fd, tbuf) >= 0) return; diff --git a/boot/fcall.c b/boot/fcall.c deleted file mode 100644 index 296ec670d69862c7cf80e141830bd4afd2d2af2c..0000000000000000000000000000000000000000 --- a/boot/fcall.c +++ /dev/null @@ -1,171 +0,0 @@ -#include -#include -#include -#include -#include - -#include "boot.h" - -/* - * reassemble 9P messages for stream based protocols - * interposed between devmnt and the network by srv for tcp connections - * fcall expects devmnt on fd0, network fd1 - */ -static uchar msglen[256] = -{ - [Tnop] 3, - [Rnop] 3, - [Tsession] 3+CHALLEN, - [Rsession] 3+NAMELEN+DOMLEN+CHALLEN, - [Terror] 0, - [Rerror] 67, - [Tflush] 5, - [Rflush] 3, - [Tattach] 5+2*NAMELEN+TICKETLEN+AUTHENTLEN, - [Rattach] 13+AUTHENTLEN, - [Tclone] 7, - [Rclone] 5, - [Twalk] 33, - [Rwalk] 13, - [Topen] 6, - [Ropen] 13, - [Tcreate] 38, - [Rcreate] 13, - [Tread] 15, - [Rread] 8, - [Twrite] 16, - [Rwrite] 7, - [Tclunk] 5, - [Rclunk] 5, - [Tremove] 5, - [Rremove] 5, - [Tstat] 5, - [Rstat] 121, - [Twstat] 121, - [Rwstat] 5, - [Tclwalk] 35, - [Rclwalk] 13, -}; - -enum -{ - Twritehdr = 16, /* Min bytes for Twrite */ - Rreadhdr = 8, /* Min bytes for Rread */ - Twritecnt = 13, /* Offset in byte stream of write count */ - Rreadcnt = 5, /* Offset for Readcnt */ -}; - -void -echo(int f, int t) -{ - int n; - char buf[MAXRPC]; - - for(;;) { - n = read9p(f, buf, MAXRPC); - if(n <= 0) - break; - if(write(t, buf, n) < n) - break; - } -} - -int -mntrpclen(uchar *d, int n) -{ - uchar t; - int len, off; - - if(n < 1) - return 0; - - t = d[0]; - switch(t) { /* This is the type */ - default: - len = msglen[t]; - if(len == 0) /* Illegal type so consume */ - return n; - if(n < len) - return 0; - return len; - case Twrite: /* Fmt: TGGFFOOOOOOOOCC */ - len = Twritehdr; /* T = type, G = tag, F = fid */ - off = Twritecnt; /* O = offset, C = count */ - break; - case Rread: /* Fmt: TGGFFCC */ - len = Rreadhdr; - off = Rreadcnt; - break; - } - if(n < off+2) - return 0; - - len += d[off]|(d[off+1]<<8); - if(n < len) - return 0; - - return len; -} - -int -pushfcall(int fd) -{ - int r, n, l, pfd[2]; - uchar *p, buf[MAXRPC]; - - if(pipe(pfd) < 0){ - fprint(2, "pipe: %r\n"); - exits("pipe"); - } - - /* Downstream is just a copy process */ - switch(rfork(RFPROC|RFFDG|RFMEM)){ - case 0: - close(pfd[1]); - echo(pfd[0], fd); - fprint(2, "echo finished\n"); - exits("echo done"); - case -1: - fprint(2, "fcall fork failed: %r\n"); - exits("fork"); - } - - switch(rfork(RFPROC|RFFDG|RFMEM)){ - default: - close(pfd[0]); - return pfd[1]; - case 0: - close(pfd[1]); - break; - case -1: - fprint(2, "fcall fork failed: %r\n"); - exits("fork"); - } - - /* Dispatch only full RPC's to the mount driver */ - l = MAXRPC; - p = buf; - for(;;) { - n = read(fd, p, l); - if(n < 0) - break; - p += n; - l -= n; - - for(;;) { - r = mntrpclen(buf, p - buf); - if(r == 0) - break; - - if(write(pfd[0], buf, r) < 0) - break; - - n = (p - buf) - r; - memmove(buf, buf+r, n); - p = buf+n; - l = MAXRPC - n; - } - } - abort(); - return 0; -} diff --git a/boot/glendakey.c b/boot/glendakey.c deleted file mode 100644 index 0974847941006ad2cc824f73074c7710e08d8427..0000000000000000000000000000000000000000 --- a/boot/glendakey.c +++ /dev/null @@ -1,26 +0,0 @@ -#include -#include -#include -#include <../boot/boot.h> - -/* - * pretend to get info out of nvram. - */ -void -glendakey(int, Method*) -{ - char key[DESKEYLEN]; - - passtokey(key, "boyd"); - - /* set host's key */ - if(writefile("#c/key", key, DESKEYLEN) < 0) - warning("#c/key"); - - /* set host's owner (and uid of current process) */ - if(writefile("#c/hostowner", "glenda", 6) < 0) - warning("#c/hostowner"); - - if(writefile("#c/hostdomain", "plan9", 5) < 0) - warning("#c/hostdomain"); -} diff --git a/boot/key.c b/boot/key.c index cb96ceda14918812d2c5057f9208efef36f79115..1593ac919dddca690ae3ff42ff21b9c1ba1e8f1f 100644 --- a/boot/key.c +++ b/boot/key.c @@ -77,7 +77,10 @@ key(int islocal, Method *mp) warning("can't read nvram"); } check(safe->machkey, DESKEYLEN, safe->machsum, "bad nvram key"); +#define NAMELEN 28 +/*BUG: THIS IS TOTALLY BOGUS */ check(safe->authid, NAMELEN, safe->authidsum, "bad authentication id"); +#undef NAMELEN check(safe->authdom, DOMLEN, safe->authdomsum, "bad authentication domain"); if(kflag){ do diff --git a/boot/local.c b/boot/local.c index 4aa391306c06991db1402c47aba035d096ce426d..61f918587ab05e121dbd6df0a3bd632018025e56 100644 --- a/boot/local.c +++ b/boot/local.c @@ -2,7 +2,7 @@ #include #include <../boot/boot.h> -static char diskname[2*NAMELEN]; +static char diskname[64]; static char *disk; static char **args; @@ -58,28 +58,27 @@ int connectlocal(void) { int i, p[2]; - Dir dir; - char d[DIRLEN]; - char partition[2*NAMELEN]; + Dir *dir; + char partition[64]; char *dev; char **arg, **argp; + ulong mode; - if(stat("/kfs", d) < 0){ - print("stat /kfs fails: %r\n"); + if(stat("/kfs", statbuf, sizeof statbuf) < 0) return -1; - } dev = disk ? disk : bootdisk; - sprint(partition, "%sfs", dev); - if(dirstat(partition, &dir) < 0){ + snprint(partition, sizeof partition, "%sfs", dev); + dir = dirstat(partition); + if(dir == nil){ strcpy(partition, dev); - if(dirstat(partition, &dir) < 0){ - print("stat %s fails: %r\n", partition); - print("(stat %sfs also failed)\n", dev); + dir = dirstat(partition); + if(dir == nil) return -1; - } } - if(dir.mode & CHDIR) + mode = dir->mode; + free(dir); + if(mode & DMDIR) return -1; print("kfs..."); @@ -103,6 +102,11 @@ connectlocal(void) *argp++ = bargv[i]; *argp = 0; + print("kfs"); + for(argp=arg; *argp; argp++) + print(" %s", *argp); + print("\n"); + dup(p[0], 0); dup(p[1], 1); close(p[0]); diff --git a/boot/nopsession.c b/boot/nopsession.c index 8893ac35dba41d69b6c06ba09a876f324ebea066..4d3f3494e533a8d981688e7797ad9fe71925e678 100644 --- a/boot/nopsession.c +++ b/boot/nopsession.c @@ -4,6 +4,9 @@ #include #include "../boot/boot.h" +/*BUG transition*/ +int client9p=2; +int kernel9p=2; static Fcall hdr; static void diff --git a/boot/sac.c b/boot/sac.c index 21507155b4bf1028e8f8cb7415bb1517cf0f3bb3..b281b9d94c258116826be63d68aa280cb360233b 100644 --- a/boot/sac.c +++ b/boot/sac.c @@ -4,7 +4,7 @@ void configip(char* dev); -// HACK - take over from boot since files system is not +// HACK - take over from boot since file system is not // available on a pipe void @@ -12,32 +12,28 @@ configsac(Method *mp) { int fd; char cmd[64]; - char *t; USED(mp); - // create the name space, mount the root fs + /* + * create the name space, mount the root fs + */ if(bind("/", "/", MREPL) < 0) fatal("bind /"); if(bind("#C", "/", MAFTER) < 0) fatal("bind /"); - // yet another hack - figure out what to call ourselves - t = getenv("terminal"); - if(t == nil) - t = "brick"; - // fixed sysname - enables correct namespace file fd = open("#c/sysname", OWRITE); if(fd < 0) fatal("open sysname"); - write(fd, t, strlen(t)); + write(fd, "brick", 5); close(fd); fd = open("#c/hostowner", OWRITE); if(fd < 0) fatal("open sysname"); - write(fd, t, strlen(t)); + write(fd, "brick", 5); close(fd); sprint(cmd, "/%s/init", cputype); diff --git a/boot/settime.c b/boot/settime.c index fc083566c1df98b52f0fed4d93306771c564d185..9b0243d2bc6d02e706c58d061d40e9ec20f25070 100644 --- a/boot/settime.c +++ b/boot/settime.c @@ -3,6 +3,9 @@ #include #include #include "../boot/boot.h" +/*BUG transition*/ +int client9p=2; +int kernel9p=2; static long lusertime(char*); @@ -13,8 +16,8 @@ settime(int islocal) { int n, f; int timeset; - Dir dir; - char dirbuf[DIRLEN]; + Dir dir[2]; + char timebuf[64]; print("time..."); timeset = 0; @@ -24,15 +27,15 @@ settime(int islocal) */ f = open("#r/rtc", ORDWR); if(f >= 0){ - if((n = read(f, dirbuf, sizeof(dirbuf)-1)) > 0){ - dirbuf[n] = 0; + if((n = read(f, timebuf, sizeof(timebuf)-1)) > 0){ + timebuf[n] = '\0'; timeset = 1; } close(f); }else do{ - strcpy(dirbuf, "yymmddhhmm[ss]"); - outin("\ndate/time ", dirbuf, sizeof(dirbuf)); - }while((timeset=lusertime(dirbuf)) <= 0); + strcpy(timebuf, "yymmddhhmm[ss]"); + outin("\ndate/time ", timebuf, sizeof(timebuf)); + }while((timeset=lusertime(timebuf)) <= 0); } if(timeset == 0){ /* @@ -47,15 +50,15 @@ settime(int islocal) return; } close(f); - if(stat("/mnt", dirbuf) < 0) + if(stat("/mnt", statbuf, sizeof statbuf) < 0) fatal("stat"); - convM2D(dirbuf, &dir); - sprint(dirbuf, "%ld", dir.atime); + convM2D(statbuf, sizeof statbuf, &dir[0], (char*)&dir[1]); + sprint(timebuf, "%ld", dir[0].atime); unmount(0, "/mnt"); } f = open("#c/time", OWRITE); - if(write(f, dirbuf, strlen(dirbuf)) < 0) + if(write(f, timebuf, strlen(timebuf)) < 0) warning("can't set #c/time"); close(f); print("\n"); diff --git a/boot/userpasswd.c b/boot/userpasswd.c index 98caf80ed148ba362c920d854636757e4d28e307..4282220698466c79806cb2881a5ee36c79df0df1 100644 --- a/boot/userpasswd.c +++ b/boot/userpasswd.c @@ -3,7 +3,8 @@ #include #include <../boot/boot.h> -char password[NAMELEN]; +char username[64]; +char password[64]; #ifdef asdf extern char *sauth; #endif asdf @@ -11,38 +12,15 @@ extern char *sauth; char *homsg = "can't set user name or key; please reboot"; /* - * get/set user name and password. verify password with auth server. + * get/set user name. */ void -userpasswd(int islocal, Method *mp) +setusername(int, Method*) { - int fd; - char *msg; - char hostkey[DESKEYLEN]; - if(*username == 0 || strcmp(username, "none") == 0){ strcpy(username, "none"); outin("user", username, sizeof(username)); } - fd = -1; - while(strcmp(username, "none") != 0){ - getpasswd(password, sizeof password); - passtokey(hostkey, password); - fd = -1; - if(islocal) - break; - msg = checkkey(mp, username, hostkey); - if(msg == 0) - break; - fprint(2, "?%s\n", msg); - outin("user", username, sizeof(username)); - } - if(fd > 0) - close(fd); - - /* set host's key */ - if(writefile("#c/key", hostkey, DESKEYLEN) < 0) - fatal(homsg); /* set host's owner (and uid of current process) */ if(writefile("#c/hostowner", username, strlen(username)) < 0) diff --git a/carrera/audio.h b/carrera/audio.h deleted file mode 100644 index 9fe66bca19d7cbc627882f2900e135a566609323..0000000000000000000000000000000000000000 --- a/carrera/audio.h +++ /dev/null @@ -1,37 +0,0 @@ -enum -{ - Bufsize = 16*1024, /* 92 ms each */ - Nbuf = 16, /* 1.5 seconds total */ - Dma = 6, - IrqAUDIO = 7, - - SBswab = 1, - - DMA2_WRMASK = 0xd4, - DMA2_WRMODE = 0xd6, - DMA2_CLRBP = 0xd8, - - DMA6_ADDRESS = 0xc8, - DMA6_COUNT = 0xca, - DMA6_LPAGE = 0x89, - DMA6_HPAGE = 0x489, - - Dspport = 0x220, - - PORT_RESET = Dspport + 0x6, - PORT_READ = Dspport + 0xA, - PORT_WRITE = Dspport + 0xC, - PORT_WSTATUS = Dspport + 0xC, - PORT_RSTATUS = Dspport + 0xE, - - PORT_MIXER_ADDR = Dspport + 0x4, - PORT_MIXER_DATA = Dspport + 0x5, - - PORT_CLRI8 = Dspport + 0xE, - PORT_CLRI16 = Dspport + 0xF, - PORT_CLRI401 = Dspport + 0x100, -}; - -#define setvec(a,b,c) -#define outb(a,b) EISAOUTB(a,b) -#define inb(a) EISAINB(a) diff --git a/carrera/clock.c b/carrera/clock.c deleted file mode 100644 index 1d725554e6e465dcf72da22d1946a572f74ac43a..0000000000000000000000000000000000000000 --- a/carrera/clock.c +++ /dev/null @@ -1,143 +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 (*kproftimer)(ulong); - -typedef struct Clock0link Clock0link; -typedef struct Clock0link { - void (*clock)(void); - Clock0link* link; -} Clock0link; - -static Clock0link *clock0link; -static Lock clock0lock; -static ulong incr; /* compare register increment */ -static ulong lastcmp; - - -void -addclock0link(void (*clock)(void)) -{ - Clock0link *lp; - - if((lp = malloc(sizeof(Clock0link))) == 0){ - print("addclock0link: too many links\n"); - return; - } - ilock(&clock0lock); - lp->clock = clock; - lp->link = clock0link; - clock0link = lp; - iunlock(&clock0lock); -} - -/* - * delay for l milliseconds more or less. delayloop is set by - * clockinit() to match the actual CPU speed. - */ -void -delay(int l) -{ - ulong i, j; - - j = m->delayloop; - while(l-- > 0) - for(i=0; i < j; i++) - ; -} - -void -clockinit(void) -{ - long x; - - m->delayloop = m->speed*100; - do { - x = rdcount(); - delay(10); - x = rdcount() - x; - } while(x < 0); - - /* - * fix count - */ - m->delayloop = (m->delayloop*m->speed*1000*10)/x; - if(m->delayloop == 0) - m->delayloop = 1; - - incr = (m->speed*1000000)/HZ; - wrcompare(lastcmp = rdcount()+incr); -} - -void -clock(Ureg *ur) -{ - Clock0link *lp; - ulong count; - - count = rdcount(); - if(lastcmp+incr < count+100) - lastcmp = count+incr; - else - lastcmp += incr; - wrcompare(lastcmp); - - m->ticks++; - if(m->proc) - m->proc->pc = ur->pc; - - accounttime(); - - if(kproftimer != nil) - kproftimer(ur->pc); - - kmapinval(); - - if((active.machs&(1<machno)) == 0) - return; - - if(active.exiting && (active.machs & (1<machno))) { - print("someone's exiting\n"); - exit(0); - } - - checkalarms(); - if(m->machno == 0){ - lock(&clock0lock); - for(lp = clock0link; lp; lp = lp->link) - lp->clock(); - unlock(&clock0lock); - } - - if(m->flushmmu){ - if(up) - flushmmu(); - m->flushmmu = 0; - } - - if(up == 0 || up->state != Running) - return; - - /* user profiling clock */ - if(ur->status & KUSER) { - (*(ulong*)(USTKTOP-BY2WD)) += TK2MS(1); - segclock(ur->pc); - } - - if(anyready()) - sched(); -} - -vlong -fastticks(uvlong *hz) -{ - if(hz != nil) - *hz = HZ*100; - return m->ticks*100; -} diff --git a/carrera/dat.h b/carrera/dat.h deleted file mode 100644 index d14b4ee3f10777abba5e9c23a80e738ceb197249..0000000000000000000000000000000000000000 --- a/carrera/dat.h +++ /dev/null @@ -1,186 +0,0 @@ -typedef struct Conf Conf; -typedef struct FPsave FPsave; -typedef struct ISAConf ISAConf; -typedef struct KMap KMap; -typedef struct Lance Lance; -typedef struct Lancemem Lancemem; -typedef struct Label Label; -typedef struct Lock Lock; -typedef struct Mach Mach; -typedef struct MMU MMU; -typedef struct Notsave Notsave; -typedef struct PMMU PMMU; -typedef struct Softtlb Softtlb; -typedef struct Ureg Ureg; -typedef struct Proc Proc; - -/* - * parameters for sysproc.c - */ -#define AOUT_MAGIC V_MAGIC || magic==M_MAGIC -/* - * machine dependent definitions used by ../port/dat.h - */ - -struct Lock -{ - ulong key; /* semaphore (non-zero = locked) */ - ulong sr; - ulong pc; - Proc *p; - ushort isilock; -}; - -struct Label -{ - ulong sp; - ulong pc; -}; - -struct Conf -{ - ulong nmach; /* processors */ - ulong nproc; /* processes */ - ulong npage0; /* total physical pages of memory */ - ulong npage1; /* total physical pages of memory */ - ulong npage; /* total physical pages of memory */ - ulong upages; /* user page pool */ - ulong nimage; /* number of page cache image headers */ - ulong nswap; /* number of swap pages */ - int nswppo; /* max # of pageouts per segment pass */ - ulong base0; /* base of bank 0 */ - ulong base1; /* base of bank 1 */ - ulong copymode; /* 0 is copy on write, 1 is copy on reference */ - int monitor; - ulong ialloc; /* bytes available for interrupt time allocation */ - ulong pipeqsize; /* size in bytes of pipe queues */ -}; - -/* - * floating point registers - */ -enum -{ - FPinit, - FPactive, - FPinactive, -}; - -struct FPsave -{ - long fpreg[32]; - long fpstatus; -}; - -/* - * mmu goo in the Proc structure - */ -struct PMMU -{ - int pidonmach[MAXMACH]; -}; - -/* - * things saved in the Proc structure during a notify - */ -struct Notsave -{ - ulong UNUSED; -}; - -#include "../port/portdat.h" - -/* First FOUR members offsets known by l.s */ -struct Mach -{ - /* the following are all known by l.s and cannot be moved */ - int machno; /* physical id of processor FIRST */ - Softtlb*stb; /* Software tlb simulation SECOND */ - Proc* proc; /* process on this processor THIRD */ - ulong splpc; /* pc that called splhi() FOURTH */ - int tlbfault; /* # of tlb faults FIFTH */ - int tlbpurge; /* MUST BE SIXTH */ - - /* the following are safe to move */ - ulong ticks; /* of the clock since boot time */ - Label sched; /* scheduler wakeup */ - int lastpid; /* last pid allocated on this machine */ - Proc* pidproc[NTLBPID]; /* proc that owns tlbpid on this mach */ - ulong vaddrtst; /* address probe by tstbadvaddr */ - Ureg* ur; - KMap* kactive; /* active on this machine */ - int knext; - uchar ktlbnext; - int speed; /* cpu speed */ - ulong delayloop; /* for the delay() routine */ - int nrdy; - ulong fairness; /* for runproc */ - ulong lastcyclecount; - uvlong fastclock; - vlong intrts; /* time stamp of last interrupt */ - int flushmmu; /* make current proc flush it's mmu state */ - - int pfault; - int cs; - int syscall; - int load; - int intr; - int ledval; /* value last written to LED */ - - int stack[1]; -}; - -struct KMap -{ - Ref; - ulong virt; - ulong phys0; - ulong phys1; - KMap* next; - KMap* konmach[MAXMACH]; - int tlbi[MAXMACH]; - Page* pg; -}; - -#define VA(k) ((k)->virt) -#define PPN(x) ((ulong)(x)>>6) - -struct Softtlb -{ - ulong virt; - ulong phys0; - ulong phys1; -}; - - - -struct -{ - Lock; - short machs; - short exiting; - short ispanic; -}active; - -/* - * a parsed plan9.ini line - */ -#define ISAOPTLEN 16 -#define NISAOPT 8 - -struct ISAConf { - char type[NAMELEN]; - ulong port; - ulong irq; - ulong dma; - ulong mem; - ulong size; - ulong freq; - - int nopt; - char opt[NISAOPT][ISAOPTLEN]; -}; - -extern KMap kpte[]; -extern register Mach *m; -extern register Proc *up; diff --git a/carrera/devether.c b/carrera/devether.c deleted file mode 100644 index 20053c00a119c911405a2faceaab3da81b8d0046..0000000000000000000000000000000000000000 --- a/carrera/devether.c +++ /dev/null @@ -1,431 +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 "../port/netif.h" - -#include "etherif.h" - -static Ether *etherxx[MaxEther]; - -Chan* -etherattach(char* spec) -{ - ulong ctlrno; - char *p; - Chan *chan; - - ctlrno = 0; - if(spec && *spec){ - ctlrno = strtoul(spec, &p, 0); - if((ctlrno == 0 && p == spec) || *p || (ctlrno >= MaxEther)) - error(Ebadarg); - } - if(etherxx[ctlrno] == 0) - error(Enodev); - - chan = devattach('l', spec); - chan->dev = ctlrno; - if(etherxx[ctlrno]->dev && etherxx[ctlrno]->dev->attach) - etherxx[ctlrno]->dev->attach(etherxx[ctlrno]); - return chan; -} - -static int -etherwalk(Chan* chan, char* name) -{ - return netifwalk(etherxx[chan->dev], chan, name); -} - -static void -etherstat(Chan* chan, char* dp) -{ - netifstat(etherxx[chan->dev], chan, dp); -} - -static Chan* -etheropen(Chan* chan, int omode) -{ - return netifopen(etherxx[chan->dev], chan, omode); -} - -static void -ethercreate(Chan*, char*, int, ulong) -{ -} - -static void -etherclose(Chan* chan) -{ - netifclose(etherxx[chan->dev], chan); -} - -static long -etherread(Chan* chan, void* buf, long n, vlong off) -{ - Ether *ether; - ulong offset = off; - - ether = etherxx[chan->dev]; - if((chan->qid.path & CHDIR) == 0 && ether->dev && ether->dev->ifstat){ - /* - * With some controllers it is necessary to reach - * into the chip to extract statistics. - */ - if(NETTYPE(chan->qid.path) == Nifstatqid) - return ether->dev->ifstat(ether, buf, n, offset); - else if(NETTYPE(chan->qid.path) == Nstatqid) - ether->dev->ifstat(ether, buf, 0, offset); - } - - return netifread(ether, chan, buf, n, offset); -} - -static Block* -etherbread(Chan* chan, long n, ulong offset) -{ - return netifbread(etherxx[chan->dev], chan, n, offset); -} - -static void -etherremove(Chan*) -{ -} - -static void -etherwstat(Chan* chan, char* dp) -{ - netifwstat(etherxx[chan->dev], chan, dp); -} - -static void -etherrtrace(Netfile* f, Etherpkt* pkt, int len) -{ - int i, n; - Block *bp; - - if(qwindow(f->in) <= 0) - return; - if(len > 58) - n = 58; - else - n = len; - bp = iallocb(64); - if(bp == nil) - return; - memmove(bp->wp, pkt->d, n); - i = TK2MS(MACHP(0)->ticks); - bp->wp[58] = len>>8; - bp->wp[59] = len; - bp->wp[60] = i>>24; - bp->wp[61] = i>>16; - bp->wp[62] = i>>8; - bp->wp[63] = i; - bp->wp += 64; - qpass(f->in, bp); -} - -Block* -etheriq(Ether* ether, Block* bp, int freebp) -{ - Etherpkt *pkt; - ushort type; - int len; - Netfile **ep, *f, **fp, *fx; - Block *xbp; - - ether->inpackets++; - - pkt = (Etherpkt*)bp->rp; - len = BLEN(bp); - type = (pkt->type[0]<<8)|pkt->type[1]; - fx = 0; - ep = ðer->f[Ntypes]; - - /* check for valid multcast addresses */ - if((pkt->d[0] & 1) && memcmp(pkt->d, ether->bcast, sizeof(pkt->d)) && ether->prom == 0){ - if(!activemulti(ether, pkt->d, sizeof(pkt->d))){ - if(freebp){ - freeb(bp); - bp = 0; - } - return bp; - } - } - - /* - * Multiplex the packet to all the connections which want it. - * If the packet is not to be used subsequently (freebp != 0), - * attempt to simply pass it into one of the connections, thereby - * saving a copy of the data (usual case hopefully). - */ - for(fp = ether->f; fp < ep; fp++){ - if((f = *fp) && (f->type == type || f->type < 0)){ - if(f->type > -2){ - if(freebp && fx == 0) - fx = f; - else if(xbp = iallocb(len)){ - memmove(xbp->wp, pkt, len); - xbp->wp += len; - qpass(f->in, xbp); - } - else - ether->soverflows++; - } - else - etherrtrace(f, pkt, len); - } - } - - if(fx){ - qpass(fx->in, bp); - return 0; - } - if(freebp){ - freeb(bp); - return 0; - } - - return bp; -} - -static int -etheroq(Ether* ether, Block* bp) -{ - int len, loopback, s; - Etherpkt *pkt; - - ether->outpackets++; - - /* - * Check if the packet has to be placed back onto the input queue, - * i.e. if it's a loopback or broadcast packet or the interface is - * in promiscuous mode. - * If it's a loopback packet indicate to etheriq that the data isn't - * needed and return, etheriq will pass-on or free the block. - */ - pkt = (Etherpkt*)bp->rp; - len = BLEN(bp); - loopback = (memcmp(pkt->d, ether->addr, sizeof(pkt->d)) == 0); - if(loopback || memcmp(pkt->d, ether->bcast, sizeof(pkt->d)) == 0 || ether->prom){ - s = splhi(); - etheriq(ether, bp, loopback); - splx(s); - } - - if(!loopback){ - if(ether->dev && ether->dev->transmit){ - qbwrite(ether->oq, bp); - ether->dev->transmit(ether); - } - else{ - freeb(bp); - return 0; - } - } - - return len; -} - -static long -etherwrite(Chan* chan, void* buf, long n, vlong) -{ - Ether *ether; - Block *bp; - - ether = etherxx[chan->dev]; - if(NETTYPE(chan->qid.path) != Ndataqid) - return netifwrite(ether, chan, buf, n); - - if(n > ETHERMAXTU) - error(Etoobig); - if(n < ETHERMINTU) - error(Etoosmall); - - bp = allocb(n); - if(waserror()){ - freeb(bp); - nexterror(); - } - memmove(bp->rp, buf, n); - memmove(bp->rp+Eaddrlen, ether->addr, Eaddrlen); - poperror(); - bp->wp += n; - - return etheroq(ether, bp); -} - -static long -etherbwrite(Chan* chan, Block* bp, ulong) -{ - Ether *ether; - long n; - - n = BLEN(bp); - ether = etherxx[chan->dev]; - if(NETTYPE(chan->qid.path) != Ndataqid){ - n = netifwrite(ether, chan, bp->rp, n); - freeb(bp); - return n; - } - - if(n > ETHERMAXTU){ - freeb(bp); - error(Ebadarg); - } - if(n < ETHERMINTU){ - freeb(bp); - error(Etoosmall); - } - - return etheroq(ether, bp); -} - -void -etherreset(void) -{ - Ether *ether; - int i, n, ctlrno; - char name[NAMELEN], buf[128]; - - for(ether = 0, ctlrno = 0; ctlrno < MaxEther; ctlrno++){ - if(ether == 0) - ether = malloc(sizeof(Ether)); - memset(ether, 0, sizeof(Ether)); - ether->ctlrno = ctlrno; - ether->tbdf = BUSUNKNOWN; - ether->mbps = 10; - if(isaconfig("ether", ctlrno, ether) == 0) - continue; - for(n = 0; endev[n]; n++){ - if(cistrcmp(endev[n]->name, ether->type)) - continue; - ether->dev = endev[n]; - for(i = 0; i < ether->nopt; i++){ - if(strncmp(ether->opt[i], "ea=", 3)) - continue; - if(parseether(ether->addr, ðer->opt[i][3]) == -1) - memset(ether->addr, 0, Eaddrlen); - } - if(endev[n]->reset(ether)) - break; - - /* - * IRQ2 doesn't really exist, it's used to gang the interrupt - * controllers together. A device set to IRQ2 will appear on - * the second interrupt controller as IRQ9. - */ - if(ether->irq == 2) - ether->irq = 9; - intrenable(VectorPIC+ether->irq, ether->interrupt, ether, ether->tbdf); - - i = sprint(buf, "#l%d: %s: %dMbps port 0x%luX", - ctlrno, ether->type, ether->mbps, ether->port); - if(ether->irq) - i += sprint(buf+i, " irq %ld", ether->irq); - if(ether->mem) - i += sprint(buf+i, " addr 0x%luX", PADDR(ether->mem)); - if(ether->size) - i += sprint(buf+i, " size 0x%luX", ether->size); - i += sprint(buf+i, ": %2.2uX%2.2uX%2.2uX%2.2uX%2.2uX%2.2uX", - ether->addr[0], ether->addr[1], ether->addr[2], - ether->addr[3], ether->addr[4], ether->addr[5]); - sprint(buf+i, "\n"); - print(buf); - - snprint(name, sizeof(name), "ether%d", ctlrno); - if(ether->mbps == 100){ - netifinit(ether, name, Ntypes, 256*1024); - if(ether->oq == 0) - ether->oq = qopen(256*1024, 1, 0, 0); - } - else{ - netifinit(ether, name, Ntypes, 32*1024); - if(ether->oq == 0) - ether->oq = qopen(64*1024, 1, 0, 0); - } - if(ether->oq == 0) - panic("etherreset %s", name); - - ether->alen = Eaddrlen; - memset(ether->bcast, 0xFF, Eaddrlen); - ether->arg = ether; - ether->promiscuous = ether->dev->promiscuous; - ether->multicast = ether->dev->multicast; - - etherxx[ctlrno] = ether; - ether = 0; - break; - } - } - if(ether) - free(ether); -} - -int -parseether(uchar* to, char* from) -{ - char nip[4]; - char *p; - int i; - - p = from; - for(i = 0; i < 6; i++){ - if(*p == 0) - return -1; - nip[0] = *p++; - if(*p == 0) - return -1; - nip[1] = *p++; - nip[2] = 0; - to[i] = strtoul(nip, 0, 16); - if(*p == ':') - p++; - } - return 0; -} - -#define POLY 0xedb88320 - -/* really slow 32 bit crc for ethers */ -ulong -ethercrc(uchar* p, int len) -{ - int i, j; - ulong crc, b; - - crc = 0xffffffff; - for(i = 0; i < len; i++){ - b = *p++; - for(j = 0; j < 8; j++){ - crc = (crc>>1) ^ (((crc^b) & 1) ? POLY : 0); - b >>= 1; - } - } - return crc; -} - -Dev etherdevtab = { - 'l', - "ether", - - etherreset, - devinit, - etherattach, - devclone, - etherwalk, - etherstat, - etheropen, - ethercreate, - etherclose, - etherread, - etherbread, - etherwrite, - etherbwrite, - etherremove, - etherwstat, -}; diff --git a/carrera/devrtc.c b/carrera/devrtc.c deleted file mode 100644 index c54acb6aea5b3c8e48bad722f0bbf2277472145f..0000000000000000000000000000000000000000 --- a/carrera/devrtc.c +++ /dev/null @@ -1,431 +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" - -/* - * real time clock and non-volatile ram - */ - -extern ulong boottime; - -typedef struct Rtc Rtc; -struct Rtc -{ - int sec; - int min; - int hour; - int mday; - int mon; - int year; -}; - -enum -{ - Qrtc = 1, - Qnvram, - - Seconds= 0x00, - Minutes= 0x02, - Hours= 0x04, - Mday= 0x07, - Month= 0x08, - Year= 0x09, - Status= 0x0A, - StatusB= 0x0B, - StatusC= 0x0C, - StatusD= 0x0D, - - Update= 0x80, - - Nvsize = 4096, - - Nclock= 6, -}; - -#define GETBCD(v) (((v) & 0x0F) + 10*((v)>>4)) -#define PUTBCD(v) ((v) % 10)|((((v)/10) % 10)<<4) - -Dirtab rtcdir[]={ - "nvram", {Qnvram, 0}, Nvsize, 0664, - "rtc", {Qrtc, 0}, 0, 0664, -}; - -static ulong rtc2sec(Rtc*); -static void sec2rtc(ulong, Rtc*); - -static int isbinary; -static Lock rtclock; - -static void -rtcreset(void) -{ - int i, x; - uchar r; - - for(i = 0; i < 10000; i++){ - x = (*(uchar*)Rtcindex)&~0x7f; - *(uchar*)Rtcindex = x|Status; - r = *(uchar*)Rtcdata; - if(r & 0x80) - continue; - - *(uchar*)Rtcindex = x|StatusB; - isbinary = *(uchar*)Rtcdata & 0x04; - break; - } -} - -static Chan* -rtcattach(char *spec) -{ - return devattach('r', spec); -} - -static int -rtcwalk(Chan *c, char *name) -{ - return devwalk(c, name, rtcdir, nelem(rtcdir), devgen); -} - -static void -rtcstat(Chan *c, char *dp) -{ - devstat(c, dp, rtcdir, nelem(rtcdir), devgen); -} - -static Chan* -rtcopen(Chan *c, int omode) -{ - omode = openmode(omode); - switch(c->qid.path){ - case Qrtc: - if(strcmp(up->user, eve)!=0 && omode!=OREAD) - error(Eperm); - break; - case Qnvram: - if(strcmp(up->user, eve)!=0) - error(Eperm); - } - return devopen(c, omode, rtcdir, nelem(rtcdir), devgen); -} - -static void -rtcclose(Chan*) -{ -} - -static long -_rtctime(void) -{ - Rtc rtc; - int i, x; - uchar r; - - /* don't do the read until the clock is no longer busy */ - for(i = 0; i < 10000; i++){ - x = (*(uchar*)Rtcindex)&~0x7f; - *(uchar*)Rtcindex = x|Status; - r = *(uchar*)Rtcdata; - if(r & Update) - continue; - - /* read clock values */ - *(uchar*)Rtcindex = x|Seconds; - rtc.sec = *(uchar*)Rtcdata; - *(uchar*)Rtcindex = x|Minutes; - rtc.min = *(uchar*)Rtcdata; - *(uchar*)Rtcindex = x|Hours; - rtc.hour = *(uchar*)Rtcdata; - *(uchar*)Rtcindex = x|Mday; - rtc.mday = *(uchar*)Rtcdata; - *(uchar*)Rtcindex = x|Month; - rtc.mon = *(uchar*)Rtcdata; - *(uchar*)Rtcindex = x|Year; - rtc.year = *(uchar*)Rtcdata; - - *(uchar*)Rtcindex = x|Status; - r = *(uchar*)Rtcdata; - if((r & Update) == 0) - break; - } - - if(!isbinary){ - /* - * convert from BCD - */ - rtc.sec = GETBCD(rtc.sec); - rtc.min = GETBCD(rtc.min); - rtc.hour = GETBCD(rtc.hour); - rtc.mday = GETBCD(rtc.mday); - rtc.mon = GETBCD(rtc.mon); - rtc.year = GETBCD(rtc.year); - } - - /* - * the world starts jan 1 1970 - */ - rtc.year += 1970; - - return rtc2sec(&rtc); -} - -long -rtctime(void) -{ - int i; - long t, ot; - - ilock(&rtclock); - - /* loop till we get two reads in a row the same */ - t = _rtctime(); - for(i = 0; i < 100; i++){ - ot = t; - t = _rtctime(); - if(ot == t) - break; - } - iunlock(&rtclock); - - return t; -} - -static long -rtcread(Chan *c, void *buf, long n, vlong off) -{ - uchar *f, *to, *e; - ulong offset = off; - - if(c->qid.path & CHDIR) - return devdirread(c, buf, n, rtcdir, nelem(rtcdir), devgen); - - switch(c->qid.path){ - case Qrtc: - return readnum(offset, buf, n, rtctime(), 12); - case Qnvram: - if(offset > Nvsize) - return -1; - if(offset + n > Nvsize) - n = Nvsize - offset; - f = (uchar*)Nvram+offset; - to = buf; - e = f + n; - while(f < e) - *to++ = *f++; - return n; - } - error(Ebadarg); - return 0; -} - -static long -rtcwrite(Chan *c, void *buf, long n, vlong off) -{ - Rtc rtc; - ulong secs; - char *cp, *ep; - uchar *f, *t, *e; - uchar x; - ulong offset = off; - - switch(c->qid.path){ - case Qrtc: - /* - * read the time - */ - cp = ep = buf; - ep += n; - while(cp < ep){ - if(*cp>='0' && *cp<='9') - break; - cp++; - } - secs = strtoul(cp, 0, 0); - sec2rtc(secs, &rtc); - rtc.year -= 1970; - - if(!isbinary){ - /* - * convert to bcd - */ - rtc.sec = PUTBCD(rtc.sec); - rtc.min = PUTBCD(rtc.min); - rtc.hour = PUTBCD(rtc.hour); - rtc.mday = PUTBCD(rtc.mday); - rtc.mon = PUTBCD(rtc.mon); - rtc.year = PUTBCD(rtc.year); - } - - ilock(&rtclock); - /* set clock values */ - x = (*(uchar*)Rtcindex)&~0x7f; - *(uchar*)Rtcindex = x|Seconds; - *(uchar*)Rtcdata = rtc.sec; - *(uchar*)Rtcindex = x|Minutes; - *(uchar*)Rtcdata = rtc.min; - *(uchar*)Rtcindex = x|Hours; - *(uchar*)Rtcdata = rtc.hour; - *(uchar*)Rtcindex = x|Mday; - *(uchar*)Rtcdata = rtc.mday; - *(uchar*)Rtcindex = x|Month; - *(uchar*)Rtcdata = rtc.mon; - *(uchar*)Rtcindex = x|Year; - *(uchar*)Rtcdata = rtc.year; - iunlock(&rtclock); - - return n; - case Qnvram: - if(offset > Nvsize) - return -1; - if(offset + n > Nvsize) - n = Nvsize - offset; - t = (uchar*)Nvram+offset; - f = buf; - e = f + n; - while(f < e) - *t++ = *f++; - return n; - } - error(Ebadarg); - return 0; -} - -Dev rtcdevtab = { - 'r', - "rtc", - - rtcreset, - devinit, - rtcattach, - devclone, - rtcwalk, - rtcstat, - rtcopen, - devcreate, - rtcclose, - rtcread, - devbread, - rtcwrite, - devbwrite, - devremove, - devwstat, -}; - -#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 - */ -static int* -yrsize(int yr) -{ - if((yr % 4) == 0) - return ldmsize; - else - return dmsize; -} - -/* - * compute seconds since Jan 1 1970 - */ -static 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 - */ -static 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/carrera/dma.c b/carrera/dma.c deleted file mode 100644 index 8099cb0b53d622daf2f812a601d7f30bb324a2c6..0000000000000000000000000000000000000000 --- a/carrera/dma.c +++ /dev/null @@ -1,125 +0,0 @@ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "io.h" - -/* - * headland chip set for the safari. - */ -typedef struct DMAport DMAport; -typedef struct DMA DMA; - -enum -{ - /* - * the byte registers for DMA0 are all one byte apart - */ - Dma0= 0x00, - Dma0status= Dma0+0x8, /* status port */ - Dma0reset= Dma0+0xD, /* reset port */ - - /* - * the byte registers for DMA1 are all two bytes apart (why?) - */ - Dma1= 0xC0, - Dma1status= Dma1+2*0x8, /* status port */ - Dma1reset= Dma1+2*0xD, /* reset port */ -}; - -/* - * the dma controllers. the first half of this structure specifies - * the I/O ports used by the DMA controllers. - */ -struct DMAport -{ - uchar addr[4]; /* current address (4 channels) */ - uchar count[4]; /* current count (4 channels) */ - uchar page[4]; /* page registers (4 channels) */ - uchar cmd; /* command status register */ - uchar req; /* request registers */ - uchar sbm; /* single bit mask register */ - uchar mode; /* mode register */ - uchar cbp; /* clear byte pointer */ - uchar mc; /* master clear */ - uchar cmask; /* clear mask register */ - uchar wam; /* write all mask register bit */ -}; - -struct DMA -{ - DMAport; - int shift; - Lock; -}; - -DMA dma[2] = { - { 0x00, 0x02, 0x04, 0x06, - 0x01, 0x03, 0x05, 0x07, - 0x87, 0x83, 0x81, 0x82, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0 }, - - { 0xc0, 0xc4, 0xc8, 0xcc, - 0xc2, 0xc6, 0xca, 0xce, - 0x8f, 0x8b, 0x89, 0x8a, - 0xd0, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde, - 1 }, -}; - -/* - * setup a dma transfer. - * needs to change if the address is over 16meg - * - * we assume BIOS has set up the command register before we - * are booted. - */ -long -dmasetup(int chan, void *va, long len, int isread) -{ - DMA *dp; - ulong pa; - uchar mode; - - dp = &dma[(chan>>2)&1]; - chan = chan & 3; - - pa = PADDR(va); - - /* - * this setup must be atomic - */ - ilock(dp); - mode = (isread ? 0x44 : 0x48) | chan; - EISAOUTB(dp->mode, mode); /* single mode dma (give CPU a chance at mem) */ - EISAOUTB(dp->page[chan], pa>>16); - EISAOUTB(dp->cbp, 0); /* set count & address to their first byte */ - EISAOUTB(dp->addr[chan], pa>>dp->shift); /* set address */ - EISAOUTB(dp->addr[chan], pa>>(8+dp->shift)); - EISAOUTB(dp->count[chan], (len>>dp->shift)-1); /* set count */ - EISAOUTB(dp->count[chan], ((len>>dp->shift)-1)>>8); - EISAOUTB(dp->sbm, chan); /* enable the channel */ - iunlock(dp); - - return len; -} - -/* - * this must be called after a dma has been completed. - */ -void -dmaend(int chan) -{ - DMA *dp; - - dp = &dma[(chan>>2)&1]; - chan = chan & 3; - - /* - * disable the channel - */ - ilock(dp); - EISAOUTB(dp->sbm, 4|chan); - iunlock(dp); -} diff --git a/carrera/etherif.h b/carrera/etherif.h deleted file mode 100644 index 447e587a2869dc4fd7e09a4b73fe7c9e2499d1ea..0000000000000000000000000000000000000000 --- a/carrera/etherif.h +++ /dev/null @@ -1,48 +0,0 @@ -enum { - MaxEther = 1, - Ntypes = 8, -}; - -typedef struct Ether Ether; -typedef struct Endev Endev; - -struct Ether { - ISAConf; /* hardware info */ - int ctlrno; - int tbdf; /* type+busno+devno+funcno */ - int mbps; /* Mbps */ - - Netif; - - Endev* dev; - void *ctlr; - Queue* oq; -}; - -struct Endev { - char* name; - - int (*reset)(Ether*); - void (*attach)(Ether*); - void (*transmit)(Ether*); - void (*interrupt)(Ureg*, void*); - long (*ifstat)(Ether*, void*, long, ulong); - void (*promiscuous)(void*, int); - void (*multicast)(void*, uchar*, int); - - int vid; - int did; -}; - -/* - * devether.c - */ -extern Block* etheriq(Ether*, Block*, int); -extern ulong ethercrc(uchar*, int); - -extern Endev* endev[]; - -#define NEXT(x, l) (((x)+1)%(l)) -#define PREV(x, l) (((x) == 0) ? (l)-1: (x)-1) -#define HOWMANY(x, y) (((x)+((y)-1))/(y)) -#define ROUNDUP(x, y) (HOWMANY((x), (y))*(y)) diff --git a/carrera/ethersonic.c b/carrera/ethersonic.c deleted file mode 100644 index 7988d798d8f41ebd9e40ba8562bbc9d832f20a6b..0000000000000000000000000000000000000000 --- a/carrera/ethersonic.c +++ /dev/null @@ -1,727 +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 "../port/netif.h" - -#include "etherif.h" - -/* - * National Semiconductor DP83932 - * Systems-Oriented Network Interface Controller - * (SONIC) - */ - -#define SONICADDR ((Sonic*)Sonicbase) - -#define RD(rn) (delay(0), *(ulong*)((ulong)&SONICADDR->rn^4)) -#define WR(rn, v) (delay(0), *(ulong*)((ulong)&SONICADDR->rn^4) = (v)) -#define ISquad(s) if((ulong)s & 0x7) panic("sonic: Quad alignment"); - -typedef struct Pbuf Pbuf; -struct Pbuf -{ - uchar d[6]; - uchar s[6]; - uchar type[2]; - uchar data[1500]; - uchar crc[4]; -}; - -typedef struct -{ - ulong cr; /* command */ - ulong dcr; /* data configuration */ - ulong rcr; /* receive control */ - ulong tcr; /* transmit control */ - ulong imr; /* interrupt mask */ - ulong isr; /* interrupt status */ - ulong utda; /* upper transmit descriptor address */ - ulong ctda; /* current transmit descriptor address */ - ulong pad0x08[5]; /* */ - ulong urda; /* upper receive descriptor address */ - ulong crda; /* current receive descriptor address */ - ulong crba0; /* DO NOT WRITE THESE */ - ulong crba1; - ulong rbwc0; - ulong rbwc1; - ulong eobc; /* end of buffer word count */ - ulong urra; /* upper receive resource address */ - ulong rsa; /* resource start address */ - ulong rea; /* resource end address */ - ulong rrp; /* resource read pointer */ - ulong rwp; /* resource write pointer */ - ulong pad0x19[8]; /* */ - ulong cep; /* CAM entry pointer */ - ulong cap2; /* CAM address port 2 */ - ulong cap1; /* CAM address port 1 */ - ulong cap0; /* CAM address port 0 */ - ulong ce; /* CAM enable */ - ulong cdp; /* CAM descriptor pointer */ - ulong cdc; /* CAM descriptor count */ - ulong sr; /* silicon revision */ - ulong wt0; /* watchdog timer 0 */ - ulong wt1; /* watchdog timer 1 */ - ulong rsc; /* receive sequence counter */ - ulong crct; /* CRC error tally */ - ulong faet; /* FAE tally */ - ulong mpt; /* missed packet tally */ - ulong mdt; /* maximum deferral timer */ - ulong pad0x30[15]; /* */ - ulong dcr2; /* data configuration 2 */ -} Sonic; - -enum -{ - Nrb = 16, /* receive buffers */ - Ntb = 8, /* transmit buffers */ -}; - -enum -{ - Htx = 0x0001, /* halt transmission */ - Txp = 0x0002, /* transmit packet(s) */ - Rxdis = 0x0004, /* receiver disable */ - Rxen = 0x0008, /* receiver enable */ - Stp = 0x0010, /* stop timer */ - St = 0x0020, /* start timer */ - Rst = 0x0080, /* software reset */ - Rrra = 0x0100, /* read RRA */ - Lcam = 0x0200, /* load CAM */ - - Dw32 = 0x0020, /* data width select */ - Sterm = 0x0400, /* synchronous termination */ - Lbr = 0x4000, /* latched bus retry */ - Efm = 0x0010, /* Empty fill mode */ - W14tf = 0x0003, /* 14 Word transmit fifo */ - - Prx = 0x0001, /* packet received ok */ - Fae = 0x0004, /* frame alignment error */ - Crc = 0x0008, /* CRC error */ - Lpkt = 0x0040, /* last packet in rba */ - Bc = 0x0080, /* broadcast packet received */ - Pro = 0x1000, /* physical promiscuous mode */ - Brd = 0x2000, /* accept broadcast packets */ - Rnt = 0x4000, /* accept runt packets */ - Err = 0x8000, /* accept packets with errors */ - - Ptx = 0x0001, /* packet transmitted ok */ - Pintr = 0x8000, /* programmable interrupt */ - - Rfo = 0x0001, /* receive fifo overrun */ - MpTally = 0x0002, /* missed packet tally counter rollover */ - FaeTally= 0x0004, /* frame alignment error tally counter rollover */ - CrcTally= 0x0008, /* Crc tally counter rollover */ - Rbae = 0x0010, /* receive buffer area exceeded */ - Rbe = 0x0020, /* receive buffer exhausted */ - Rde = 0x0040, /* receive descriptors exhausted */ - Txer = 0x0100, /* transmit error */ - Txdn = 0x0200, /* transmission done */ - Pktrx = 0x0400, /* packet received */ - Pint = 0x0800, /* programmed interrupt */ - Lcd = 0x1000, /* load CAM done */ - Hbl = 0x2000, /* CD heartbeat lost */ - Br = 0x4000, /* bus retry occurred */ - AllIntr = 0x7771, /* all of the above */ - - Rxbuf = sizeof(Pbuf)+4, - Txbuf = sizeof(Pbuf), -}; - -/* - * Receive Resource Descriptor. - */ -typedef struct -{ - ushort pad1; - ushort ptr1; /* buffer pointer in the RRA */ - ushort pad2; - ushort ptr0; - ushort pad3; - ushort wc1; /* buffer word count in the RRA */ - ushort pad4; - ushort wc0; -} RXrsc; - -/* - * Receive Packet Descriptor. - */ -typedef struct -{ - ushort pad0; - ushort count; /* packet byte count */ - ushort pad1; - ushort status; /* receive status */ - ushort pad2; - ushort ptr1; /* buffer pointer */ - ushort pad3; - ushort ptr0; - ushort pad4; - ushort link; /* descriptor link and EOL */ - ushort pad5; - ushort seqno; /* */ - ulong pad6; - ushort pad7; - ushort owner; /* in use */ -} RXpkt; - -/* - * Transmit Packet Descriptor. - */ -typedef struct -{ - ushort pad1; - ushort config; /* */ - ushort pad0; - ushort status; /* transmit status */ - ushort pad3; - ushort count; /* fragment count */ - ushort pad2; - ushort size; /* byte count of entire packet */ - ushort pad5; - ushort ptr1; - ushort pad4; - ushort ptr0; /* packet pointer */ - ushort pad7; - ushort link; /* descriptor link */ - ushort pad6; - ushort fsize; /* fragment size */ -} TXpkt; - -enum{ - Eol = 1, /* end of list bit in descriptor link */ - Host = 0, /* descriptor belongs to host */ - Interface = -1, /* descriptor belongs to interface */ -}; - -/* - * CAM Descriptor - */ -typedef struct -{ - ushort pad0; - ushort cap0; /* CAM address port 0 */ - ushort pad1; - ushort cep; /* CAM entry pointer */ - ushort pad2; - ushort cap2; /* CAM address port 2 */ - ushort pad3; - ushort cap1; /* CAM address port 1 */ - ulong pad4; - ushort pad5; - ushort ce; /* CAM enable */ -} Cam; - -typedef struct Ctlr { - Lock lock; - - Lock tlock; - int th; /* first transmit buffer owned by host */ - int ti; /* first transmit buffer owned by interface */ - int ntq; - - int rh; /* first receive buffer owned by host */ - int ri; /* first receive buffer owned by interface */ - - RXrsc* rra; /* receive resource area */ - RXpkt* rda; /* receive descriptor area */ - TXpkt* tda; /* transmit descriptor area */ - Cam* cda; /* CAM descriptor area */ - - ulong* rb[Nrb]; /* receive buffer area */ - ulong* tb[Ntb]; /* transmit buffer area */ -} Ctlr; - -static Ether* etherxx; - -#define LS16(addr) (PADDR(addr) & 0xFFFF) -#define MS16(addr) ((PADDR(addr)>>16) & 0xFFFF) - -static void -attach(Ether* ether) -{ - Ctlr *ctlr; - - ctlr = ether->ctlr; - - ilock(&ctlr->lock); - if(!(RD(cr) & Rxen)) - WR(cr, Rxen); - iunlock(&ctlr->lock); -} - -static void -promiscuous(void* arg, int on) -{ - Ctlr *ctlr; - ushort rcr; - - ctlr = ((Ether*)arg)->ctlr; - - ilock(&ctlr->lock); - rcr = RD(rcr); - if(on) - rcr |= Pro; - else - rcr &= ~Pro; - WR(rcr, rcr); - iunlock(&ctlr->lock); -} - -static void -wus(ushort* a, ushort v) -{ - a[0] = v; - a[-1] = v; -} - -static void -swizzle(uchar* to, ulong *from, int nbytes) -{ - ulong *l, l0, l1; - uchar *p; - - p = to; - l = from; - for(nbytes = ROUNDUP(nbytes, 8); nbytes; nbytes -= 8){ - l1 = *l++; - l0 = *l++; - p[0] = l0; - p[1] = l0>>8; - p[2] = l0>>16; - p[3] = l0>>24; - p[4] = l1; - p[5] = l1>>8; - p[6] = l1>>16; - p[7] = l1>>24; - p += 8; - } -} - -static void -swozzle(ulong* to, uchar *from, int nbytes) -{ - ulong *l; - uchar *p; - - l = to; - p = from; - for(nbytes = ROUNDUP(nbytes, 8); nbytes; nbytes -= 8){ - *l++ = (p[7]<<24)|(p[6]<<16)|(p[5]<<8)|p[4]; - *l++ = (p[3]<<24)|(p[2]<<16)|(p[1]<<8)|p[0]; - p += 8; - } -} - -static void -txstart(Ether* ether) -{ - Ctlr *ctlr; - Block *bp; - ushort *s; - TXpkt *txpkt; - int len; - - ctlr = ether->ctlr; - txpkt = &ctlr->tda[ctlr->th]; - while(txpkt->status == Host){ - bp = qget(ether->oq); - if(bp == nil) - break; - - len = BLEN(bp); - swozzle(ctlr->tb[ctlr->th], bp->rp, len); - - txpkt->size = len; - txpkt->fsize = len; - wus(&txpkt->link, txpkt->link|Eol); - txpkt->status = Interface; - s = &ctlr->tda[PREV(ctlr->th, Ntb)].link; - wus(s, *s & ~Eol); - - ctlr->th = NEXT(ctlr->th, Ntb); - txpkt = &ctlr->tda[ctlr->th]; - WR(cr, Txp); - - freeb(bp); - } -} - -void -etherintr(void) -{ - Ether *ether; - Ctlr *ctlr; - ushort *s; - ulong status; - TXpkt *txpkt; - RXpkt *rxpkt; - int len; - Block *bp; - - ether = etherxx; - ctlr = ether->ctlr; - - for(status = (RD(isr) & AllIntr); status; status = (RD(isr) & AllIntr)){ - /* - * Warnings that something is atoe. - */ - if(status & Hbl){ - WR(isr, Hbl); - status &= ~Hbl; - print("sonic: cd heartbeat lost\n"); - } - if(status & Br){ - WR(cr, Rst); - print("sonic: bus retry occurred\n"); - (*(void(*)(void))0xA001C020)(); - status &= ~Br; - } - - /* - * Transmission complete, for good or bad. - */ - if(status & (Txdn|Txer)){ - txpkt = &ctlr->tda[ctlr->ti]; - while(txpkt->status != Host){ - if(txpkt->status == Interface){ - WR(ctda, LS16(txpkt)); - WR(cr, Txp); - break; - } - - if((txpkt->status & Ptx) == 0) - ether->oerrs++; - - txpkt->status = Host; - ctlr->ti = NEXT(ctlr->ti, Ntb); - txpkt = &ctlr->tda[ctlr->ti]; - } - WR(isr, status & (Txdn|Txer)); - status &= ~(Txdn|Txer); - - lock(&ctlr->tlock); - txstart(ether); - unlock(&ctlr->tlock); - } - - if((status & (Pktrx|Rde)) == 0) - goto noinput; - - /* - * A packet arrived or we ran out of descriptors. - */ - rxpkt = &ctlr->rda[ctlr->rh]; - while(rxpkt->owner == Host){ - ether->inpackets++; - - /* - * If the packet was received OK, pass it up, - * otherwise log the error. - */ - if(rxpkt->status & Prx){ - /* - * Sonic delivers CRC as part of the packet count. - */ - len = (rxpkt->count & 0xFFFF)-4; - if(bp = iallocb(ROUNDUP(len, 8))){ - swizzle(bp->rp, ctlr->rb[ctlr->rh], len); - bp->wp += len; - etheriq(ether, bp, 1); - } - } - else if(rxpkt->status & Fae) - ether->frames++; - else if(rxpkt->status & Crc) - ether->crcs++; - else - ether->buffs++; - rxpkt->status = 0; - - /* - * Finished with this packet, it becomes the - * last free packet in the ring, so give it Eol, - * and take the Eol bit off the previous packet. - * Move the ring index on. - */ - wus(&rxpkt->link, rxpkt->link|Eol); - rxpkt->owner = Interface; - s = &ctlr->rda[PREV(ctlr->rh, Nrb)].link; - wus(s, *s & ~Eol); - ctlr->rh = NEXT(ctlr->rh, Nrb); - - rxpkt = &ctlr->rda[ctlr->rh]; - } - WR(isr, status & (Pktrx|Rde)); - status &= ~(Pktrx|Rde); - - noinput: - /* - * We get a 'load CAM done' interrupt - * after initialisation. Ignore it. - */ - if(status & Lcd) { - WR(isr, Lcd); - status &= ~Lcd; - } - - if(status & AllIntr) { - WR(isr, status); - print("sonic #%lux\n", status); - } - } -} - -static void -transmit(Ether* ether) -{ - Ctlr *ctlr; - - ctlr = ether->ctlr; - ilock(&ctlr->tlock); - txstart(ether); - iunlock(&ctlr->tlock); -} - -static void -reset(Ether* ether) -{ - Ctlr *ctlr; - int i; - ushort lolen, hilen, loadr, hiadr; - - ctlr = ether->ctlr; - - /* - * Reset the SONIC, toggle the Rst bit. - * Set the data config register for synchronous termination - * and 32-bit data-path width. - * Setup the descriptor and buffer area. - */ - WR(cr, Rst); - WR(dcr, 0x2423); /* 5-19 Carrera manual */ - WR(cr, 0); - - /* - * Initialise the receive resource area (RRA) and - * the receive descriptor area (RDA). - * - * We use a simple scheme of one packet per descriptor. - * We achieve this by setting the EOBC register to be - * 2 (16-bit words) less than the buffer size; - * thus the size of the receive buffers must be sizeof(Pbuf)+4. - * Set up the receive descriptors as a ring. - */ - - lolen = (Rxbuf/2) & 0xFFFF; - hilen = ((Rxbuf/2)>>16) & 0xFFFF; - - for(i = 0; i < Nrb; i++) { - wus(&ctlr->rra[i].wc0, lolen); - wus(&ctlr->rra[i].wc1, hilen); - - ctlr->rda[i].link = LS16(&ctlr->rda[NEXT(i, Nrb)]); - ctlr->rda[i].owner = Interface; - - loadr = LS16(ctlr->rb[i]); - wus(&ctlr->rra[i].ptr0, loadr); - wus(&ctlr->rda[i].ptr0, loadr); - - hiadr = MS16(ctlr->rb[i]); - wus(&ctlr->rra[i].ptr1, hiadr); - wus(&ctlr->rda[i].ptr1, hiadr); - } - - /* - * Check the important resources are QUAD aligned - */ - ISquad(ctlr->rra); - ISquad(ctlr->rda); - - /* - * Terminate the receive descriptor ring - * and load the SONIC registers to describe the RDA. - */ - ctlr->rda[Nrb-1].link |= Eol; - - WR(crda, LS16(ctlr->rda)); - WR(urda, MS16(ctlr->rda)); - WR(eobc, Rxbuf/2 - 2); - - /* - * Load the SONIC registers to describe the RRA. - * We set the rwp to beyond the area delimited by rsa and - * rea. This means that since we've already allocated all - * the buffers, we'll never get a 'receive buffer area - * exhausted' interrupt and the rrp will just wrap round. - */ - WR(urra, MS16(&ctlr->rra[0])); - WR(rsa, LS16(&ctlr->rra[0])); - WR(rrp, LS16(&ctlr->rra[0])); - WR(rea, LS16(&ctlr->rra[Nrb])); - WR(rwp, LS16(&ctlr->rra[Nrb+1])); - - /* - * Initialise the transmit descriptor area (TDA). - * Each descriptor describes one packet, we make no use - * of having the packet in multiple fragments. - * The descriptors are linked in a ring; overlapping transmission - * with buffer queueing will cause some packets to - * go out back-to-back. - * - * Load the SONIC registers to describe the TDA. - */ - for(i = 0; i < Ntb; i++){ - ctlr->tda[i].status = Host; - ctlr->tda[i].config = 0; - ctlr->tda[i].count = 1; - ctlr->tda[i].ptr0 = LS16(ctlr->tb[i]); - ctlr->tda[i].ptr1 = MS16(ctlr->tb[i]); - ctlr->tda[i].link = LS16(&ctlr->tda[NEXT(i, Ntb)]); - } - - WR(ctda, LS16(&ctlr->tda[0])); - WR(utda, MS16(&ctlr->tda[0])); - - /* - * Initialise the software receive and transmit - * ring indexes. - */ - ctlr->rh = 0; - ctlr->ri = 0; - ctlr->th = 0; - ctlr->ti = 0; - - /* - * Initialise the CAM descriptor area (CDA). - * We only have one ethernet address to load, - * broadcast is defined by the SONIC as all 1s. - * - * Load the SONIC registers to describe the CDA. - */ - ctlr->cda->cep = 0; - ctlr->cda->cap0 = (ether->addr[1]<<8)|ether->addr[0]; - ctlr->cda->cap1 = (ether->addr[3]<<8)|ether->addr[2]; - ctlr->cda->cap2 = (ether->addr[5]<<8)|ether->addr[4]; - ctlr->cda->ce = 1; - - WR(cdp, LS16(ctlr->cda)); - WR(cdc, 1); - - /* - * Load the Resource Descriptors and Cam contents - */ - WR(cr, Rrra); - while(RD(cr) & Rrra) - ; - - WR(cr, Lcam); - while(RD(cr) & Lcam) - ; - - /* - * Configure the receive control, transmit control - * and interrupt-mask registers. - * The SONIC is now initialised, but not enabled. - */ - WR(rcr, Brd); - WR(tcr, 0); - WR(imr, AllIntr); -} - -static void -initbufs(Ctlr* ctlr) -{ - int i; - uchar *mem, *base; - - /* Put the ethernet buffers in the same place - * as the bootrom - */ - mem = (void*)(KZERO|0x2000); - base = mem; - mem = CACHELINE(uchar, mem); - - /* - * Descriptors must be built in uncached space - */ - ctlr->rra = UNCACHED(RXrsc, mem); - mem = QUAD(uchar, mem+Nrb*sizeof(RXrsc)); - - ctlr->rda = UNCACHED(RXpkt, mem); - mem = QUAD(uchar, mem+Nrb*sizeof(RXpkt)); - - ctlr->tda = UNCACHED(TXpkt, mem); - mem = QUAD(uchar, mem+Ntb*sizeof(TXpkt)); - - ctlr->cda = UNCACHED(Cam, mem); - - mem = CACHELINE(uchar, mem+sizeof(Cam)); - for(i = 0; i < Nrb; i++) { - ctlr->rb[i] = UNCACHED(ulong, mem); - mem += sizeof(Pbuf)+4; - mem = QUAD(uchar, mem); - } - for(i = 0; i < Ntb; i++) { - ctlr->tb[i] = UNCACHED(ulong, mem); - mem += sizeof(Pbuf); - mem = QUAD(uchar, mem); - } - if(mem >= base+64*1024) - panic("sonic init"); -} - -static int -sonicreset(Ether* ether) -{ - Ctlr *ctlr; - - if(ether->ctlrno != 0) - return 1; - - /* - * Map the device registers and allocate - * memory for the receive/transmit rings. - * Set the physical ethernet address and - * prime the interrupt handler. - */ - ether->ctlr = malloc(sizeof(Ctlr)); - ctlr = ether->ctlr; - ether->port = Sonicbase; - - initbufs(ctlr); - enetaddr(ether->addr); - - reset(ether); - - /* - * Hack: etherintr is called directly from trap with no arguments. - * There can only be one sonic, so keep a note of the generic ether - * struct. - */ - etherxx = ether; - - return 0; -} - -static Endev sonicdev = { - "sonic", - - sonicreset, - attach, - transmit, - nil, /* interrupt - etherintr called directly from trap */ - nil, /* ifstat */ - promiscuous, - nil, /* multicast */ - - 0, 0, /* vid, did */ -}; - -Endev* endev[] = { - &sonicdev, - nil, -}; diff --git a/carrera/faultmips.c b/carrera/faultmips.c deleted file mode 100644 index cbf3dae219eb137a7499287caf5f81e10371dafd..0000000000000000000000000000000000000000 --- a/carrera/faultmips.c +++ /dev/null @@ -1,153 +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" -#include "io.h" - -static int iwf; - -/* - * Ask if the instruction at EPC could have cause this badvaddr - */ -int -tstbadvaddr(Ureg *ur, int read) -{ - int rn; - ulong iw, off, ea; - - if(ur->cause & (1<<31)) - iw = ur->pc+4; - else - iw = ur->pc; - - if(seg(up, iw, 0) == 0) - return 0; - - m->vaddrtst = iw; - iw = *(ulong*)iw; - m->vaddrtst = 0; - -/* print("iw: %lux\n", iw); /**/ - - switch((iw>>26) & 0x3f) { - default: - return 1; - case 0x20: /* LB */ - case 0x24: /* LBU */ - /* LD */ - case 0x35: - case 0x36: - case 0x37: /* LDCz */ - case 0x1A: /* LDL */ - case 0x1B: /* LDR */ - case 0x21: /* LH */ - case 0x25: /* LHU */ - case 0x30: /* LL */ - case 0x34: /* LLD */ - case 0x23: /* LW */ - case 0x31: - case 0x32: /* LWCz possible 0x33 */ - case 0x27: /* LWU */ - case 0x22: /* LWL */ - case 0x26: /* LWR */ - if(!read) - print("bogus: load causes store fault\n"); - break; - - case 0x28: /* SB */ - case 0x38: /* SC */ - case 0x3C: /* SCD */ - case 0x3D: - case 0x3E: - case 0x3F: /* SDCz */ - case 0x2C: /* SDL */ - case 0x2D: /* SDR */ - case 0x29: /* SH */ - case 0x2B: /* SW */ - case 0x39: - case 0x3A: /* SWCz */ - case 0x2A: /* SWL */ - case 0x2E: /* SWR */ - if(read) - print("bogus: store causes load fault\n"); - break; - } - - off = iw & 0xffff; - if(off & 0x8000) - off |= ~0xffff; - - rn = (iw>>21) & 0x1f; - ea = *reg(ur, rn); - if(rn == 0) - ea = 0; - ea += off; - - /* print("ea %lux 0x%lux(R%d) bv 0x%lux pc 0x%lux\n", - ea, off, rn, ur->badvaddr, ur->pc); /**/ - - if(ur->badvaddr == ea) - return 0; - - return 1; -} - -/* - * find out fault address and type of access. - * Call common fault handler. - */ -void -faultmips(Ureg *ur, int user, int code) -{ - int read; - ulong addr; - extern char *excname[]; - char *p, buf[ERRLEN]; - - addr = ur->badvaddr; - - addr &= ~(BY2PG-1); - read = !(code==CTLBM || code==CTLBS); - - /* print("fault: %s code %d va %lux pc %lux r31 %lux %lux\n", - up->text, code, ur->badvaddr, ur->pc, ur->r31, tlbvirt());/**/ - - if(fault(addr, read) == 0) - return; - - if(tstbadvaddr(ur, read)) { - /* print("spurious badvaddr 0x%lux in %s at pc 0x%lux\n", - ur->badvaddr, up->text, ur->pc);/**/ - return; - } - - if(user) { - p = "store"; - if(read) - p = "load"; - sprint(buf, "sys: trap: fault %s addr=0x%lux r31=0x%lux", - p, ur->badvaddr, ur->r31); - postnote(up, 1, buf, NDebug); - return; - } - - print("kernel %s vaddr=0x%lux\n", excname[code], ur->badvaddr); - print("st=0x%lux pc=0x%lux sp=0x%lux\n", ur->status, ur->pc, ur->sp); - dumpregs(ur); - panic("fault"); -} - -/* - * called in sysfile.c - */ -void -evenaddr(ulong addr) -{ - if(addr & 3){ - postnote(up, 1, "sys: odd address", NDebug); - error(Ebadarg); - } -} diff --git a/carrera/fns.h b/carrera/fns.h deleted file mode 100644 index 34e32416f719365dc5557581d252cde573df2e45..0000000000000000000000000000000000000000 --- a/carrera/fns.h +++ /dev/null @@ -1,91 +0,0 @@ -#include "../port/portfns.h" - -void addclock0link(void (*)(void)); -void arginit(void); -int busprobe(ulong); -int cistrcmp(char*, char*); -void cleancache(void); -void clearmmucache(void); -void clock(Ureg*); -void clockinit(void); -#define coherence() -void dcflush(void*, ulong); -void dcinvalidate(void*, ulong); -void dmaend(int); -long dmasetup(int, void*, long, int); -void evenaddr(ulong); -void faultmips(Ureg*, int, int); -ulong fcr31(void); -void firmware(int); -#define flushpage(s) icflush((void*)(s), BY2PG) -void fptrap(Ureg*); -ulong getstatus(void); -void gettlb(int, ulong*); -int gettlbp(ulong, ulong*); -ulong gettlbvirt(int); -void icflush(void *, ulong); -#define idlehands() -void intr(Ureg*); -void ioinit(int); -int iprint(char*, ...); -int isaconfig(char*, int, ISAConf*); -int kbdinit(void); -void kbdintr(void); -void kfault(Ureg*); -KMap* kmap(Page*); -void kmapinit(void); -void kmapinval(void); -void kunmap(KMap*); -void links(void); -void mmunewpage(Page*); -void mouseintr(void); -int newtlbpid(Proc*); -void ns16552install(void); -#define procrestore(p) -#define procsave(p) -#define procsetup(p) ((p)->fpstate = FPinit) -void purgetlb(int); -Softtlb* putstlb(ulong, ulong); -int puttlb(ulong, ulong, ulong); -void puttlbx(int, ulong, ulong, ulong, int); -void rdbginit(void); -ulong rdcompare(void); -ulong rdcount(void); -ulong* reg(Ureg*, int); -void restfpregs(FPsave*, ulong); -void screeninit(void); -void screenputs(char*, int); -void seteisadma(int, void(*)(void)); -long syscall(Ureg*); -int tas(ulong*); -void tlbinit(void); -ulong tlbvirt(void); -void touser(void*); -#define userureg(ur) ((ur)->status & KUSER) -void vecinit(void); -void vector0(void); -void vector100(void); -void vector180(void); -void vmereset(void); -void uartclock(void); -void wbflush(void); -void wrcompare(ulong); - -void serialinit(void); -void ns16552special(int, int, Queue**, Queue**, int (*)(Queue*, int)); -void ns16552setup(ulong, ulong, char*, int); -void ns16552intr(int); -void etherintr(void); -void iomapinit(void); -void enetaddr(uchar*); - -#define waserror() setlabel(&up->errlab[up->nerrlab++]) -#define kmapperm(x) kmap(x) - -#define KADDR(a) ((void*)((ulong)(a)|KSEG0)) -#define KADDR1(a) ((void*)((ulong)(a)|KSEG1)) -#define PADDR(a) ((ulong)(a)&~KSEGM) - -void audiosbintr(void); -void audiodmaintr(void); -void mpegintr(void); diff --git a/carrera/fptrap.c b/carrera/fptrap.c deleted file mode 100644 index 78e748adc682f591d458f37947cebd79a7e7a9e6..0000000000000000000000000000000000000000 --- a/carrera/fptrap.c +++ /dev/null @@ -1,286 +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" - -enum /* op */ -{ - ABS = 5, - ADD = 0, - CVTD = 33, - CVTS = 32, - CVTW = 36, - DIV = 3, - MOV = 6, - MUL = 2, - NEG = 7, - SUB = 1, -}; - -static int fpunimp(ulong); -static ulong branch(Ureg*, ulong); - -void -fptrap(Ureg *ur) -{ - ulong iw, npc; - - if((up->fpsave.fpstatus&(1<<17)) == 0) - return; - -/*print("fpt: %d %s %lux\n", up->pid, up->text, up->fpsave.fpstatus);/**/ - - iw = ur->pc; - if(ur->cause & (1<<31)) - iw += 4; - iw = *(ulong*)iw; - - if(fpunimp(iw) == 0) - return; - - if(ur->cause & (1<<31)){ - npc = branch(ur, up->fpsave.fpstatus); - if(npc == 0) - return; - ur->pc = npc; - } - else - ur->pc += 4; - - up->fpsave.fpstatus = up->fpsave.fpstatus & ~(1<<17); -} - -static void -unpack(FPsave *f, int fmt, int reg, int *sign, int *exp) -{ - *sign = 1; - if(f->fpreg[reg] & 0x80000000) - *sign = -1; - - switch(fmt){ - case 0: - *exp = ((f->fpreg[reg]>>23)&0xFF) - ((1<<7)-2); - break; - case 1: - if(reg & 1) /* shouldn't happen */ - reg &= ~1; - *exp = ((f->fpreg[reg]>>20)&0x7FF) - ((1<<10)-2); - break; - } -} - -static void -zeroreg(FPsave *f, int fmt, int reg, int sign) -{ - int size; - - size = 0; - switch(fmt){ - case 0: - size = 4; - break; - case 1: - if(reg & 1) - reg &= ~1; - size = 8; - break; - } - memset(&f->fpreg[reg], 0, size); - if(sign < 0) - f->fpreg[reg] |= 0x80000000; -} - -static int -fpunimp(ulong iw) -{ - int ss, st, sd; - int es, et, ed; - int maxe, maxm; - ulong op, fmt, ft, fs, fd; - - if((iw>>25) != 0x23) - return 0; - op = iw & ((1<<6)-1); - fmt = (iw>>21) & ((1<<4)-1); - ft = (iw>>16) & ((1<<5)-1); - fs = (iw>>11) & ((1<<5)-1); - fd = (iw>>6) & ((1<<5)-1); - unpack(&up->fpsave, fmt, fs, &ss, &es); - unpack(&up->fpsave, fmt, ft, &st, &et); - ed = 0; - maxe = 0; - maxm = 0; - switch(fmt){ - case 0: - maxe = 1<<7; - maxm = 24; - break; - case 1: - maxe = 1<<10; - maxm = 53; - break; - } - switch(op){ - case ABS: - up->fpsave.fpreg[fd] &= ~0x80000000; - return 1; - - case NEG: - up->fpsave.fpreg[fd] ^= 0x80000000; - return 1; - - case SUB: - st = -st; - case ADD: - if(es<-(maxe-maxm) && et<-(maxe-maxm)) - ed = -maxe; - if(es > et) - sd = es; - else - sd = et; - break; - - case DIV: - et = -et; - case MUL: - sd = 1; - if(ss != st) - sd = -1; - ed = es + et; - break; - - case CVTS: - if(fmt != 1) - return 0; - fmt = 0; /* convert FROM double TO single */ - maxe = 1<<7; - ed = es; - sd = ss; - break; - - default: /* probably a compare */ - return 0; - } - if(ed <= -(maxe-4)){ /* guess: underflow */ - zeroreg(&up->fpsave, fmt, fd, sd); - /* Set underflow exception and sticky */ - up->fpsave.fpstatus |= (1<<3)|(1<<13); - return 1; - } - return 0; -} - -ulong* -reg(Ureg *ur, int regno) -{ - /* regs go from R31 down in ureg, R29 is missing */ - switch(regno) { - case 31: - return (ulong*)&ur->r31; - case 30: - return (ulong*)&ur->r30; - case 29: - return (ulong*)&ur->sp; - } - return (ulong*)((&ur->r28) + (28-regno)*(&ur->r27-&ur->r28)); -} - -static ulong -branch(Ureg *ur, ulong fcr31) -{ - ulong iw, npc, rs, rt, rd, offset; - - iw = ur->pc; - iw = *(ulong*)iw; - rs = (iw>>21) & 0x1F; - if(rs) - rs = *reg(ur, rs); - rt = (iw>>16) & 0x1F; - if(rt) - rt = *reg(ur, rt); - offset = iw & ((1<<16)-1); - if(offset & (1<<15)) /* sign extend */ - offset |= ~((1<<16)-1); - offset <<= 2; - /* - * Integer unit jumps first - */ - switch(iw>>26){ - case 0: /* SPECIAL: JR or JALR */ - switch(iw&0x3F){ - case 0x09: /* JALR */ - rd = (iw>>11) & 0x1F; - if(rd) - *reg(ur, rd) = ur->pc+8; - /* fall through */ - case 0x08: /* JR */ - return rs; - default: - return 0; - } - case 1: /* BCOND */ - switch((iw>>16) & 0x1F){ - case 0x10: /* BLTZAL */ - ur->r31 = ur->pc + 8; - /* fall through */ - case 0x00: /* BLTZ */ - if((long)rs < 0) - return ur->pc+4 + offset; - return ur->pc + 8; - case 0x11: /* BGEZAL */ - ur->r31 = ur->pc + 8; - /* fall through */ - case 0x01: /* BGEZ */ - if((long)rs >= 0) - return ur->pc+4 + offset; - return ur->pc + 8; - default: - return 0; - } - case 3: /* JAL */ - ur->r31 = ur->pc+8; - /* fall through */ - case 2: /* JMP */ - npc = iw & ((1<<26)-1); - npc <<= 2; - return npc | (ur->pc&0xF0000000); - case 4: /* BEQ */ - if(rs == rt) - return ur->pc+4 + offset; - return ur->pc + 8; - case 5: /* BNE */ - if(rs != rt) - return ur->pc+4 + offset; - return ur->pc + 8; - case 6: /* BLEZ */ - if((long)rs <= 0) - return ur->pc+4 + offset; - return ur->pc + 8; - case 7: /* BGTZ */ - if((long)rs > 0) - return ur->pc+4 + offset; - return ur->pc + 8; - } - /* - * Floating point unit jumps - */ - if((iw>>26) == 0x11) /* COP1 */ - switch((iw>>16) & 0x3C1){ - case 0x101: /* BCT */ - case 0x181: /* BCT */ - if(fcr31 & (1<<23)) - return ur->pc+4 + offset; - return ur->pc + 8; - case 0x100: /* BCF */ - case 0x180: /* BCF */ - if(!(fcr31 & (1<<23))) - return ur->pc+4 + offset; - return ur->pc + 8; - } - /* shouldn't get here */ - return 0; -} diff --git a/carrera/io.h b/carrera/io.h deleted file mode 100644 index 93d1036880dbce510ea15c470b6634f6f5169fc8..0000000000000000000000000000000000000000 --- a/carrera/io.h +++ /dev/null @@ -1,133 +0,0 @@ -/* - * These register addresses have already been adjusted for BE operation - * - * The EISA memory address is completely fictional. Look at mmu.c for - * a translation of Eisamphys into a 33 bit address. - */ -enum -{ - Devicephys = 0x80000000, - Eisaphys = 0x90000000, /* IO port physical */ - Devicevirt = 0xE0000000, - MCTgcr = 0xE0000004, - Dmabase = 0xE0000100, - R4030ier = 0xE00000EC, /* Interrupt enable register */ - R4030ipr = 0xE00000EC, /* Interrupt pending register */ - R4030Isr = 0xE0000204, /* Interrupt status register */ - R4030Et = 0xE000020C, /* Eisa error type */ - R4030Rfa = 0xE000003C, /* Remote failed address */ - R4030Mfa = 0xE0000044, /* Memory failed address */ - Sonicbase = 0xE0001000, - Scsibase = 0xE0002000, - Floppybase = 0xE0003000, - Clockbase = 0xE0004000, - Uart0 = 0xE0006000, - Uart1 = 0xE0007000, - UartFREQ = 8000000, - Centronics = 0xE0008000, - Nvram = 0xE0009000, - NvramRW = 0xE000A000, - NvramRO = 0xE000B000, - Enetoffset = 0, - KeyboardIO = 0xE0005000, - Keyctl = 6, - Keydat = 7, - MouseIO = 0xE0005000, - SoundIO = 0xE000C000, - EisaLatch = 0xE000E007, - Diag = 0xE000F000, - VideoCTL = 0x60000000, - VideoMEM = 0x40000000, - Screenvirt = 0xE2000000, - BTDac = 0xE2400000, - I386ack = 0xE000023f, - EisaControl = 0xE0010000, /* Second 64K Page from Devicevirt */ - Eisanmi = EisaControl+0x77, - Rtcindex = Eisanmi, - Rtcdata = 0xE0004007, - Eisamphys = 0x91000000, - Eisavgaphys = Eisamphys+0xA0000, - Eisamvirt = 0xE0300000, /* Second 1M page entry from Intctl */ - Eisadmaintr = 0x40a, - Intctlphys = 0xF0000000, - Intctlvirt = 0xE0200000, - Uart1int = (1<<9), - Uart0int = (1<<8), - Mouseint = (1<<7), - Keybint = (1<<6), - Scsiint = (1<<5), - Etherint = (1<<4), - Fiberint = (1<<3), - Soundint = (1<<2), - Floppyint = (1<<1), - Parallelint = (1<<0), - Intenareg = 0xE0200004, /* Device interrupt enable */ - Intcause = 0xE0200007, /* Device interrupt cause register */ - - Promvirt = 0xE1000000, /* From ARCS chipset */ - Promphys = 0x1FC00000, /* MIPs processors */ - - Ttbr = 0xE000001C, /* Translation table base address */ - Tlrb = 0xE0000024, /* Translation table limit address */ - Tir = 0xE000002C, /* Translation invalidate register */ - Ntranslation = 4096, /* Number of translation registers */ -}; - -enum -{ - SB16pcm = 100, -}; - -typedef struct Tte Tte; -struct Tte -{ - ulong hi; - ulong lo; -}; - -#define IO(type, reg) (*(type*)(reg)) -#define QUAD(type, v) (type*)(((ulong)(v)+7)&~7) -#define CACHELINE(type, v) (type*)(((ulong)(v)+127)&~127) -#define UNCACHED(type, v) (type*)((ulong)(v)|0xA0000000) - -#define EISA(v) (Eisamvirt+(v)) -#define EISAINB(port) (*(uchar*)((EisaControl+(port))^7)) -#define EISAINW(port) (*(ushort*)((EisaControl+(port))^6)) -#define EISAOUTB(port, v) EISAINB(port) = v -#define EISAOUTW(port, v) EISAINW(port) = v - -/* - * 8259 interrupt controllers - */ -enum -{ - Int0vec= 0, /* first 8259 */ - Clockvec= Int0vec+0, /* clock interrupts */ - Kbdvec= Int0vec+1, /* keyboard interrupts */ - Uart1vec= Int0vec+3, /* modem line */ - Uart0vec= Int0vec+4, /* serial line */ - PCMCIAvec= Int0vec+5, /* PCMCIA card change */ - Floppyvec= Int0vec+6, /* floppy interrupts */ - Parallelvec= Int0vec+7, /* parallel port interrupts */ - Int1vec= Int0vec+8, /* second 8259 */ - Ethervec= Int0vec+10, /* ethernet interrupt */ - Mousevec= Int0vec+12, /* mouse interrupt */ - Matherr2vec= Int0vec+13, /* math coprocessor */ - Hardvec= Int0vec+14, /* hard disk */ - - Int0ctl= 0x20, /* control port (ICW1, OCW2, OCW3) */ - Int0aux= 0x21, /* everything else (ICW2, ICW3, ICW4, OCW1) */ - Int1ctl= 0xA0, /* control port */ - Int1aux= 0xA1, /* everything else (ICW2, ICW3, ICW4, OCW1) */ - - EOI= 0x20, /* non-specific end of interrupt */ -}; - -extern int int0mask; /* interrupts enabled for first 8259 */ -extern int int1mask; /* interrupts enabled for second 8259 */ - -/* - * All motherboard and ISA interrupts are enabled by default. - */ -#define intrenable(a, b, c, d) -#define BUSUNKNOWN (-1) diff --git a/carrera/kbd.c b/carrera/kbd.c deleted file mode 100644 index ef28a5e2ea6bf255901aa216c3b8b86d65cfc39c..0000000000000000000000000000000000000000 --- a/carrera/kbd.c +++ /dev/null @@ -1,421 +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 Image IMAGE -#include -#include -#include "screen.h" - -enum -{ - /* controller command byte */ - Cscs1= (1<<6), /* scan code set 1 */ - Cmousedis= (1<<5), /* mouse disable */ - Ckbddis= (1<<4), /* kbd disable */ - Csf= (1<<2), /* system flag */ - Cmouseint= (1<<1), /* mouse interrupt enable */ - Ckbdint= (1<<0), /* kbd interrupt enable */ - - /* - * responses from keyboard - */ - Rok= 0xAA, /* self test OK */ - Recho= 0xEE, /* ??? */ - Rack= 0xFA, /* command acknowledged */ - Rfail= 0xFC, /* self test failed */ - Rresend= 0xFE, /* ??? */ - Rovfl= 0xFF, /* input overflow */ - - /* - * status bits - */ - Sobf= 1<<0, /* output buffer full */ - Sibf= 1<<1, /* input buffer full */ - Ssys= 1<<2, /* set by self-test */ - Slast= 1<<3, /* last access was to data */ - Senabled= 1<<4, /* keyboard is enabled */ - Stxtimeout= 1<<5, /* transmit to kybd has timed out */ - Srxtimeout= 1<<6, /* receive from kybd has timed out */ - Sparity= 1<<7, /* parity on byte was even */ - - Spec= 0x80, - - PF= Spec|0x20, /* num pad function key */ - View= Spec|0x00, /* view (shift window up) */ - KF= 0xF000, /* function key (begin Unicode private space) */ - Shift= Spec|0x60, - Break= Spec|0x61, - Ctrl= Spec|0x62, - Latin= Spec|0x63, - Caps= Spec|0x64, - Num= Spec|0x65, - Middle= Spec|0x66, - No= 0x00, /* peter */ - - Home= KF|13, - Up= KF|14, - Pgup= KF|15, - Print= KF|16, - Left= KF|17, - Right= KF|18, - End= '\r', - Down= View, - Pgdown= KF|19, - Ins= KF|20, - Del= 0x7F, -}; - -#define KBDCTL (*(uchar*)(KeyboardIO+Keyctl)) -#define KBDDAT (*(uchar*)(KeyboardIO+Keydat)) -#define OUTWAIT while(KBDCTL & Sibf); kdbdly(1) -#define INWAIT while(!(KBDCTL & Sobf)); kdbdly(1) -#define ACKWAIT INWAIT ; if(KBDDAT != Rack) print("bad response\n"); kdbdly(1) - -Rune kbtab[] = -{ -[0x00] No, 0x1b, '1', '2', '3', '4', '5', '6', -[0x08] '7', '8', '9', '0', '-', '=', '\b', '\t', -[0x10] 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', -[0x18] 'o', 'p', '[', ']', '\n', Ctrl, 'a', 's', -[0x20] 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', -[0x28] '\'', '`', Shift, '\\', 'z', 'x', 'c', 'v', -[0x30] 'b', 'n', 'm', ',', '.', '/', Shift, '*', -[0x38] Latin, ' ', Ctrl, KF|1, KF|2, KF|3, KF|4, KF|5, -[0x40] KF|6, KF|7, KF|8, KF|9, KF|10, Num, KF|12, '7', -[0x48] '8', '9', '-', '4', '5', '6', '+', '1', -[0x50] '2', '3', '0', '.', No, No, No, KF|11, -[0x58] KF|12, No, No, No, No, No, No, No, -}; - -Rune kbtabshift[] = -{ -[0x00] No, 0x1b, '!', '@', '#', '$', '%', '^', -[0x08] '&', '*', '(', ')', '_', '+', '\b', '\t', -[0x10] 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', -[0x18] 'O', 'P', '{', '}', '\n', Ctrl, 'A', 'S', -[0x20] 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', -[0x28] '"', '~', Shift, '|', 'Z', 'X', 'C', 'V', -[0x30] 'B', 'N', 'M', '<', '>', '?', Shift, '*', -[0x38] Latin, ' ', Ctrl, KF|1, KF|2, KF|3, KF|4, KF|5, -[0x40] KF|6, KF|7, KF|8, KF|9, KF|10, Num, KF|12, '7', -[0x48] '8', '9', '-', '4', '5', '6', '+', '1', -[0x50] '2', '3', '0', '.', No, No, No, KF|11, -[0x58] KF|12, No, No, No, No, No, No, No, -}; - -Rune kbtabesc1[] = -{ -[0x00] No, No, No, No, No, No, No, No, -[0x08] No, No, No, No, No, No, No, No, -[0x10] No, No, No, No, No, No, No, No, -[0x18] No, No, No, No, '\n', Ctrl, No, No, -[0x20] No, No, No, No, No, No, No, No, -[0x28] No, No, Shift, No, No, No, No, No, -[0x30] No, No, No, No, No, '/', No, Print, -[0x38] Latin, No, No, No, No, No, No, No, -[0x40] No, No, No, No, No, No, Break, Home, -[0x48] Up, Pgup, No, Left, No, Right, No, End, -[0x50] Down, Pgdown, Ins, Del, No, No, No, No, -[0x58] No, No, No, No, No, No, No, No, -}; - -struct Kbd -{ - Lock; - int l; -} kbd; -static uchar ccc; - -void -kdbdly(int l) -{ - int i; - - l *= 21; /* experimentally determined */ - for(i=0; i sizeof kbtab){ - print("unknown key %ux\n", c|keyup); - return; - } - - if(esc1){ - c = kbtabesc1[c]; - esc1 = 0; - } - else if(esc2){ - esc2--; - return; - } - else if(shift) - c = kbtabshift[c]; - else - c = kbtab[c]; - - if(caps && c<='z' && c>='a') - c += 'A' - 'a'; - - /* - * keyup only important for shifts - */ - if(keyup){ - switch(c){ - case Shift: - shift = 0; - break; - case Ctrl: - ctl = 0; - break; - } - return; - } - /* - * normal character - */ - if(!(c & Spec)){ - if(ctl) - c &= 0x1f; - if(!collecting){ - kbdputc(kbdq, c); - return; - } - kc[nk++] = c; - c = latin1(kc, nk); - if(c < -1) /* need more keystrokes */ - return; - if(c != -1) /* valid sequence */ - kbdputc(kbdq, c); - else /* dump characters */ - for(i=0; i 2) - break; - OUTWAIT; - KBDCTL = 0xD4; - OUTWAIT; - KBDDAT = cmd; - OUTWAIT; - kbdwait(); - c = KBDDAT; - } while(c == 0xFE || c == 0); - if(c != 0xFA){ - /*print("mouse returns %2.2ux to the %2.2ux command\n", c, cmd);/**/ - return -1; - } - return 0; -} - -int -kbdinit(void) -{ - int i; - - kbdq = qopen(4*1024, 0, 0, 0); - if(kbdq == nil) - panic("kbdinit"); - qnoblock(kbdq, 1); - - /* - * empty the buffer - */ - while(KBDCTL & Sobf){ - i = KBDDAT; - USED(i); - } - - - /* wait for a quiescent controller */ - OUTWAIT; - KBDCTL = 0x20; - if(kbdwait() == 0) { - print("kbdinit: can't read ccc\n"); - ccc = 0; - } else - ccc = KBDDAT; - - /* enable kbd xfers and interrupts */ - ccc &= ~Ckbddis; - ccc |= Csf | Ckbdint | Cscs1 | Cmouseint; - - OUTWAIT; - KBDCTL = 0x60; - OUTWAIT; - KBDDAT = ccc; - OUTWAIT; - - mousecmd(0xEA); /* streaming */ - mousecmd(0xE8); /* set resolution */ - mousecmd(3); - mousecmd(0xF4); /* enabled */ - - return 1; -} - -void -mousectl(char* field[], int) -{ - int s; - - if(strncmp(field[0], "reset", 5) == 0){ - s = splhi(); - mousecmd(0xF6); - mousecmd(0xEA); /* streaming */ - mousecmd(0xE8); /* set resolution */ - mousecmd(3); - mousecmd(0xF4); /* enabled */ - splx(s); - } - else if(strcmp(field[0], "accelerated") == 0){ - s = splhi(); - mousecmd(0xE7); - splx(s); - } - else - error(Ebadctl); -} diff --git a/carrera/l.s b/carrera/l.s deleted file mode 100644 index 8ee69c0ee951dd0dfa1b530372865f9216dd283d..0000000000000000000000000000000000000000 --- a/carrera/l.s +++ /dev/null @@ -1,802 +0,0 @@ -#include "mem.h" - -#define SP R29 - -#define NOOP WORD $0x27 -#define FCRNOOP NOOP; NOOP; NOOP -#define WAIT NOOP; NOOP -#define NOOP4 NOOP; NOOP; NOOP; NOOP -#define ERET NOOP4;NOOP4;NOOP4;WORD $0x42000018;NOOP4;NOOP4;NOOP4 -#define CONST(x,r) MOVW $((x)&0xffff0000), r; OR $((x)&0xffff), r - -/* - * R4000 instructions - */ -#define LL(base, rt) WORD $((060<<26)|((base)<<21)|((rt)<<16)) -#define SC(base, rt) WORD $((070<<26)|((base)<<21)|((rt)<<16)) - -/* - * Boot first processor - */ -TEXT start(SB), $-4 - - MOVW $setR30(SB), R30 - MOVW $(CU1|INTR7|INTR6|INTR5|INTR4|INTR3|INTR2|INTR1|INTR0), R1 - MOVW R1, M(STATUS) - WAIT - - MOVW $TLBROFF, R1 - MOVW R1, M(WIRED) - - /* setfcr(FPPDBL|FPRNR|FPINVAL|FPZDIV|FPOVFL) */ - /* bit 24 is R4000-specific; underflow goes to zero */ - MOVW $((0x1C<<7)|(1<<24)), R1 - MOVW R1, FCR31 /* permit only inexact and underflow */ - NOOP - MOVD $0.5, F26 - SUBD F26, F26, F24 - ADDD F26, F26, F28 - ADDD F28, F28, F30 - - MOVD F24, F0 - MOVD F24, F2 - MOVD F24, F4 - MOVD F24, F6 - MOVD F24, F8 - MOVD F24, F10 - MOVD F24, F12 - MOVD F24, F14 - MOVD F24, F16 - MOVD F24, F18 - MOVD F24, F20 - MOVD F24, F22 - - MOVW $MACHADDR, R(MACH) - ADDU $(BY2PG-4), R(MACH), SP - MOVW $0, R(USER) - MOVW R0, 0(R(MACH)) - - MOVW $edata(SB), R1 - MOVW $end(SB), R2 - -clrbss: - MOVB $0, (R1) - ADDU $1, R1 - BNE R1, R2, clrbss - - MOVW R4, _argc(SB) - MOVW R5, _argv(SB) - MOVW R6, _env(SB) - JAL main(SB) - JMP (R0) - -/* - * Take first processor into user mode - * - argument is stack pointer to user - */ -TEXT touser(SB), $-4 - - MOVW $(UTZERO+32), R2 /* header appears in text */ - MOVW (R2), R3 /* fault now */ - MOVW M(STATUS), R4 - WAIT - AND $(~KMODEMASK), R4 - OR $(KUSER|EXL|IE|UX), R4 - MOVW R4, M(STATUS) - WAIT - MOVW R1, SP - MOVW R2, M(EPC) - ERET - -TEXT firmware(SB), $0 - MOVW $0xE000D004, R1 - MOVW R0, 0(R1) -firm: - JMP firm - -TEXT splhi(SB), $0 - MOVW R31, 12(R(MACH)) /* save PC in m->splpc */ - MOVW M(STATUS), R1 - WAIT - AND $~IE, R1, R2 - MOVW R2, M(STATUS) - WAIT - RET - -TEXT splx(SB), $0 - MOVW R31, 12(R(MACH)) /* save PC in m->splpc */ - /* fall though */ - -TEXT splxpc(SB), $0 /* for iunlock */ - MOVW M(STATUS), R2 - WAIT - AND $IE, R1 - AND $~IE, R2 - OR R2, R1 - MOVW R1, M(STATUS) - WAIT - RET - -TEXT spllo(SB), $0 - MOVW M(STATUS), R1 - WAIT - OR $IE, R1, R2 - MOVW R2, M(STATUS) - WAIT - RET - -TEXT spldone(SB), $0 - RET - -TEXT islo(SB), $0 - MOVW M(STATUS), R1 - AND $IE, R1 - WAIT - RET - -TEXT wbflush(SB), $-4 - RET - -TEXT setlabel(SB), $-4 - MOVW R29, 0(R1) - MOVW R31, 4(R1) - MOVW $0, R1 - RET - -TEXT gotolabel(SB), $-4 - MOVW 0(R1), R29 - MOVW 4(R1), R31 - MOVW $1, R1 - RET - -TEXT puttlb(SB), $0 - MOVW R1, M(TLBVIRT) - MOVW 4(FP), R2 /* phys0 */ - MOVW 8(FP), R3 /* phys1 */ - MOVW R2, M(TLBPHYS0) - WAIT - MOVW $PGSZ4K, R1 - MOVW R3, M(TLBPHYS1) - WAIT - MOVW R1, M(PAGEMASK) - OR R2, R3, R4 /* MTC0 delay slot */ - AND $PTEVALID, R4 /* MTC0 delay slot */ - NOOP - TLBP - NOOP4 - MOVW M(INDEX), R1 - NOOP4 - BGEZ R1, index - BEQ R4, dont /* cf. kunmap */ - TLBWR - NOOP -dont: - RET -index: - TLBWI - NOOP - RET - -TEXT getwired(SB),$0 - MOVW M(WIRED), R1 - WAIT - RET - -TEXT getrandom(SB),$0 - MOVW M(RANDOM), R1 - WAIT - RET - -TEXT puttlbx(SB), $0 - MOVW 4(FP), R2 - MOVW 8(FP), R3 - MOVW 12(FP), R4 - MOVW 16(FP), R5 - MOVW R2, M(TLBVIRT) - NOOP4 - MOVW R3, M(TLBPHYS0) - NOOP4 - MOVW R4, M(TLBPHYS1) - NOOP4 - MOVW R5, M(PAGEMASK) - NOOP4 - MOVW R1, M(INDEX) - NOOP4 - TLBWI - WAIT - RET - -TEXT tlbvirt(SB), $0 - NOOP - MOVW M(TLBVIRT), R1 - NOOP - RET - -TEXT gettlbx(SB), $0 - MOVW 4(FP), R5 - MOVW M(TLBVIRT), R10 - NOOP4 - MOVW R1, M(INDEX) - NOOP4 - TLBR - NOOP4 - MOVW M(TLBVIRT), R2 - MOVW M(TLBPHYS0), R3 - MOVW M(TLBPHYS1), R4 - NOOP4 - MOVW R2, 0(R5) - MOVW R3, 4(R5) - MOVW R4, 8(R5) - MOVW R10, M(TLBVIRT) - NOOP4 - RET - -TEXT gettlbp(SB), $0 - MOVW 4(FP), R5 - MOVW R1, M(TLBVIRT) - NOOP - NOOP - NOOP - TLBP - NOOP - NOOP - MOVW M(INDEX), R1 - NOOP - BLTZ R1, gettlbp1 - TLBR - NOOP - NOOP - NOOP - MOVW M(TLBVIRT), R2 - MOVW M(TLBPHYS0), R3 - MOVW M(TLBPHYS1), R4 - MOVW M(PAGEMASK), R6 - NOOP - MOVW R2, 0(R5) - MOVW R3, 4(R5) - MOVW R4, 8(R5) - MOVW R6, 12(R5) -gettlbp1: - RET - -TEXT gettlbvirt(SB), $0 - MOVW R1, M(INDEX) - NOOP - NOOP - TLBR - NOOP - NOOP - NOOP - MOVW M(TLBVIRT), R1 - NOOP - RET - -TEXT vector0(SB), $-4 - NOOP4 - NOOP4 - MOVW $utlbmiss(SB), R26 - JMP (R26) - -TEXT utlbmiss(SB), $-4 - CONST (MACHADDR, R26) /* R26 = m-> */ - MOVW 16(R26), R27 - ADDU $1, R27 - MOVW R27, 16(R26) /* m->tlbfault++ */ - - MOVW M(TLBVIRT), R27 - WAIT - MOVW R27, R26 - SRL $13, R27 - XOR R26, R27 - AND $(STLBSIZE-1), R27 - SLL $2, R27 - MOVW R27, R26 - SLL $1, R27 - ADDU R26, R27 - /* R27 = ((tlbvirt^(tlbvirt>>13)) & (STLBSIZE-1)) x 12 */ - - CONST (MACHADDR, R26) /* R26 = m-> */ - MOVW 4(R26), R26 /* R26 = m->stb */ - ADDU R26, R27 /* R27 = &m->stb[hash] */ - - MOVW M(BADVADDR), R26 - WAIT - AND $BY2PG, R26 - BNE R26, utlbodd - - MOVW 4(R27), R26 - BEQ R26, stlbm - MOVW R26, M(TLBPHYS0) - WAIT - MOVW 8(R27), R26 - MOVW R26, M(TLBPHYS1) - JMP utlbcom - -utlbodd: - MOVW 8(R27), R26 - BEQ R26, stlbm - MOVW R26, M(TLBPHYS1) - WAIT - MOVW 4(R27), R26 - MOVW R26, M(TLBPHYS0) - -utlbcom: - WAIT /* MTC0/MFC0 hazard */ - MOVW M(TLBVIRT), R26 - WAIT - MOVW (R27), R27 - BEQ R27, stlbm - BNE R26, R27, stlbm - - MOVW $PGSZ4K, R27 - MOVW R27, M(PAGEMASK) - NOOP4 - TLBP - NOOP4 - MOVW M(INDEX), R26 - NOOP4 - BGEZ R26, utlindex - TLBWR - ERET -utlindex: - TLBWI - ERET - -stlbm: - MOVW $exception(SB), R26 - JMP (R26) - -TEXT vector100(SB), $-4 - NOOP4 - NOOP4 - MOVW $exception(SB), R26 - JMP (R26) - -TEXT vector180(SB), $-4 - NOOP4 - NOOP4 - MOVW $exception(SB), R26 - JMP (R26) - NOP - -TEXT exception(SB), $-4 - MOVW M(STATUS), R26 - WAIT - AND $KUSER, R26, R27 - BEQ R27, waskernel - -wasuser: - MOVW SP, R27 - CONST (MACHADDR, SP) /* m-> */ - MOVW 8(SP), SP /* m->proc */ - MOVW 8(SP), SP /* m->proc->kstack */ - MOVW M(STATUS), R26 /* redundant test */ - ADDU $(KSTACK-UREGSIZE), SP - MOVV R31, (Ureg_r31-4)(SP) - - JAL savereg1(SB) - - MOVV R30, (Ureg_r30-4)(SP) - MOVV R(MACH), (Ureg_r25-4)(SP) - MOVV R(USER), (Ureg_r24-4)(SP) - - MOVW $setR30(SB), R30 - CONST (MACHADDR, R(MACH)) /* R(MACH) = m-> */ - MOVW 8(R(MACH)), R(USER) /* up = m->proc */ - - AND $(EXCMASK<<2), R26, R1 - SUBU $(CSYS<<2), R1 - BNE R1, notsys - - ADDU $Uoffset, SP, R1 /* first arg for syscall */ - JAL syscall(SB) - -sysrestore: - JAL restreg1(SB) - - MOVV (Ureg_r31-4)(SP), R31 - MOVW Ureg_status(SP), R26 - MOVV (Ureg_r30-4)(SP), R30 - MOVW R26, M(STATUS) - WAIT - MOVW Ureg_pc(SP), R26 /* old pc */ - MOVW Ureg_sp(SP), SP - MOVW R26, M(EPC) - ERET - -notsys: - JAL savereg2(SB) - - ADDU $Uoffset, SP, R1 /* first arg for trap */ - JAL trap(SB) - -restore: - JAL restreg1(SB) - JAL restreg2(SB) - - MOVV (Ureg_r30-4)(SP), R30 - MOVV (Ureg_r31-4)(SP), R31 - MOVV (Ureg_r25-4)(SP), R(MACH) - MOVV (Ureg_r24-4)(SP), R(USER) - MOVW Ureg_sp(SP), SP - MOVW R26, M(EPC) - ERET - -waskernel: - MOVW SP, R27 - SUBU $UREGSIZE, SP - OR $7, SP - XOR $7, SP - MOVV R31, (Ureg_r31-4)(SP) - - JAL savereg1(SB) - JAL savereg2(SB) - - ADDU $Uoffset, SP, R1 /* first arg for trap */ - JAL trap(SB) - - JAL restreg1(SB) - JAL restreg2(SB) - - MOVV (Ureg_r31-4)(SP), R31 - MOVW Ureg_sp(SP), SP - MOVW R26, M(EPC) - ERET - -TEXT forkret(SB), $0 - MOVW R0, R1 /* Fake out system call return */ - JMP sysrestore - -/* - * save manditory registers. - * called with old M(STATUS) in R26. - * called with old SP in R27 - * returns with M(CAUSE) in R26 - */ -TEXT savereg1(SB), $-4 - MOVV R1, (Ureg_r1-4)(SP) - - MOVW $(~KMODEMASK),R1 /* don't use R28 */ - AND R26, R1 - MOVW R1, M(STATUS) - - MOVW R26, Ureg_status(SP) /* status */ - MOVW R27, Ureg_sp(SP) /* user SP */ - - MOVW M(EPC), R1 - MOVW M(CAUSE), R26 - - MOVV R23, (Ureg_r23-4)(SP) - MOVV R22, (Ureg_r22-4)(SP) - MOVV R21, (Ureg_r21-4)(SP) - MOVV R20, (Ureg_r20-4)(SP) - MOVV R19, (Ureg_r19-4)(SP) - MOVW R1, Ureg_pc(SP) - RET - -/* - * all other registers. - * called with M(CAUSE) in R26 - */ -TEXT savereg2(SB), $-4 - MOVV R2, (Ureg_r2-4)(SP) - - MOVW M(BADVADDR), R2 - NOOP - MOVW R26, Ureg_cause(SP) - MOVW M(TLBVIRT), R1 - NOOP - MOVW R2, Ureg_badvaddr(SP) - MOVW R1, Ureg_tlbvirt(SP) - MOVV HI, R1 - MOVV LO, R2 - MOVV R1, (Ureg_hi-4)(SP) - MOVV R2, (Ureg_lo-4)(SP) - /* LINK,SB,SP missing */ - MOVV R28, (Ureg_r28-4)(SP) - /* R27, R26 not saved */ - /* R25, R24 missing */ - /* R23- R19 saved in save1 */ - MOVV R18, (Ureg_r18-4)(SP) - MOVV R17, (Ureg_r17-4)(SP) - MOVV R16, (Ureg_r16-4)(SP) - MOVV R15, (Ureg_r15-4)(SP) - MOVV R14, (Ureg_r14-4)(SP) - MOVV R13, (Ureg_r13-4)(SP) - MOVV R12, (Ureg_r12-4)(SP) - MOVV R11, (Ureg_r11-4)(SP) - MOVV R10, (Ureg_r10-4)(SP) - MOVV R9, (Ureg_r9-4)(SP) - MOVV R8, (Ureg_r8-4)(SP) - MOVV R7, (Ureg_r7-4)(SP) - MOVV R6, (Ureg_r6-4)(SP) - MOVV R5, (Ureg_r5-4)(SP) - MOVV R4, (Ureg_r4-4)(SP) - MOVV R3, (Ureg_r3-4)(SP) - RET - -TEXT restreg1(SB), $-4 - MOVV (Ureg_r23-4)(SP), R23 - MOVV (Ureg_r22-4)(SP), R22 - MOVV (Ureg_r21-4)(SP), R21 - MOVV (Ureg_r20-4)(SP), R20 - MOVV (Ureg_r19-4)(SP), R19 - RET - -TEXT restreg2(SB), $-4 - /* LINK,SB,SP missing */ - MOVV (Ureg_r28-4)(SP), R28 - /* R27, R26 not saved */ - /* R25, R24 missing */ - /* R19- R23 restored in rest1 */ - MOVV (Ureg_r18-4)(SP), R18 - MOVV (Ureg_r17-4)(SP), R17 - MOVV (Ureg_r16-4)(SP), R16 - MOVV (Ureg_r15-4)(SP), R15 - MOVV (Ureg_r14-4)(SP), R14 - MOVV (Ureg_r13-4)(SP), R13 - MOVV (Ureg_r12-4)(SP), R12 - MOVV (Ureg_r11-4)(SP), R11 - MOVV (Ureg_r10-4)(SP), R10 - MOVV (Ureg_r9-4)(SP), R9 - MOVV (Ureg_r8-4)(SP), R8 - MOVV (Ureg_r7-4)(SP), R7 - MOVV (Ureg_r6-4)(SP), R6 - MOVV (Ureg_r5-4)(SP), R5 - MOVV (Ureg_r4-4)(SP), R4 - MOVV (Ureg_r3-4)(SP), R3 - MOVV (Ureg_lo-4)(SP), R2 - MOVV (Ureg_hi-4)(SP), R1 - MOVV R2, LO - MOVV R1, HI - - MOVW Ureg_status(SP), R1 - MOVV (Ureg_r2-4)(SP), R2 - MOVW R1, M(STATUS) - WAIT - MOVV (Ureg_r1-4)(SP), R1 /* BOTCH */ - MOVW Ureg_pc(SP), R26 - RET - -TEXT rfnote(SB), $0 - MOVW R1, R26 /* 1st arg is &uregpointer */ - SUBU $(BY2WD), R26, SP /* pc hole */ - JMP restore - -TEXT clrfpintr(SB), $0 - MOVW M(STATUS), R3 - WAIT - OR $CU1, R3 - MOVW R3, M(STATUS) - NOOP - NOOP - NOOP - - MOVW FCR31, R1 - FCRNOOP - MOVW R1, R2 - AND $~(0x3F<<12), R2 - MOVW R2, FCR31 - - AND $~CU1, R3 - MOVW R3, M(STATUS) - WAIT - RET - -TEXT getstatus(SB), $0 - MOVW M(STATUS), R1 - WAIT - RET - -TEXT savefpregs(SB), $0 - MOVW FCR31, R2 /* 3 delays before R2 ok */ - MOVW M(STATUS), R3 - WAIT - AND $~(0x3F<<12), R2, R4 - MOVW R4, FCR31 - - MOVD F0, 0x00(R1) - MOVD F2, 0x08(R1) - MOVD F4, 0x10(R1) - MOVD F6, 0x18(R1) - MOVD F8, 0x20(R1) - MOVD F10, 0x28(R1) - MOVD F12, 0x30(R1) - MOVD F14, 0x38(R1) - MOVD F16, 0x40(R1) - MOVD F18, 0x48(R1) - MOVD F20, 0x50(R1) - MOVD F22, 0x58(R1) - MOVD F24, 0x60(R1) - MOVD F26, 0x68(R1) - MOVD F28, 0x70(R1) - MOVD F30, 0x78(R1) - - MOVW R2, 0x80(R1) - AND $~CU1, R3 - MOVW R3, M(STATUS) - WAIT - RET - -TEXT restfpregs(SB), $0 - MOVW M(STATUS), R3 - WAIT - OR $CU1, R3 - MOVW R3, M(STATUS) - WAIT - MOVW fpstat+4(FP), R2 - NOOP - - MOVD 0x00(R1), F0 - MOVD 0x08(R1), F2 - MOVD 0x10(R1), F4 - MOVD 0x18(R1), F6 - MOVD 0x20(R1), F8 - MOVD 0x28(R1), F10 - MOVD 0x30(R1), F12 - MOVD 0x38(R1), F14 - MOVD 0x40(R1), F16 - MOVD 0x48(R1), F18 - MOVD 0x50(R1), F20 - MOVD 0x58(R1), F22 - MOVD 0x60(R1), F24 - MOVD 0x68(R1), F26 - MOVD 0x70(R1), F28 - MOVD 0x78(R1), F30 - - MOVW R2, FCR31 - AND $~CU1, R3 - MOVW R3, M(STATUS) - WAIT - RET - -TEXT fcr31(SB), $0 - MOVW FCR31, R1 /* 3 delays before using R1 */ - MOVW M(STATUS), R3 - WAIT - AND $~CU1, R3 - MOVW R3, M(STATUS) - WAIT - RET - -/* - * Emulate 68020 test and set: load linked / store conditional - */ - -TEXT tas(SB), $0 - MOVW R1, R2 /* address of key */ -tas1: - MOVW $1, R3 - LL(2, 1) - NOOP - SC(2, 3) - NOOP - BEQ R3, tas1 - RET - -/* - * cache manipulation - */ - -#define CACHE BREAK /* overloaded op-code */ - -#define PI R((0 /* primary I cache */ -#define PD R((1 /* primary D cache */ -#define SD R((3 /* secondary combined I/D cache */ - -#define IWBI (0<<2))) /* index write-back invalidate */ -#define ILT (1<<2))) /* index load tag */ -#define IST (2<<2))) /* index store tag */ -#define CDE (3<<2))) /* create dirty exclusive */ -#define HI (4<<2))) /* hit invalidate */ -#define HWBI (5<<2))) /* hit write back invalidate */ -#define HWB (6<<2))) /* hit write back */ -#define HSV (7<<2))) /* hit set virtual */ - -/* - * we avoid using R4, R5, R6, and R7 so gotopc can call us without saving them - */ -TEXT icflush(SB), $-4 /* icflush(virtaddr, count) */ - MOVW M(STATUS), R10 - WAIT - MOVW 4(FP), R9 - MOVW $0, M(STATUS) - WAIT - WAIT - WAIT - ADDU R1, R9 /* R9 = last address */ - MOVW $(~0x3f), R8 - AND R1, R8 /* R8 = first address, rounded down */ - ADDU $0x3f, R9 - AND $(~0x3f), R9 /* round last address up */ - SUBU R8, R9 /* R9 = revised count */ -icflush1: /* primary cache line size is 16 bytes */ - CACHE PD+HWB, 0x00(R8) - CACHE PI+HI, 0x00(R8) - CACHE PD+HWB, 0x10(R8) - CACHE PI+HI, 0x10(R8) - CACHE PD+HWB, 0x20(R8) - CACHE PI+HI, 0x20(R8) - CACHE PD+HWB, 0x30(R8) - CACHE PI+HI, 0x30(R8) - SUBU $0x40, R9 - ADDU $0x40, R8 - BGTZ R9, icflush1 - MOVW R10, M(STATUS) - WAIT - WAIT - WAIT - RET - -TEXT dcflush(SB), $-4 /* dcflush(virtaddr, count) */ - MOVW M(STATUS), R10 - WAIT - MOVW 4(FP), R9 - MOVW $0, M(STATUS) - WAIT - ADDU R1, R9 /* R9 = last address */ - MOVW $(~0x3f), R8 - AND R1, R8 /* R8 = first address, rounded down */ - ADDU $0x3f, R9 - AND $(~0x3f), R9 /* round last address up */ - SUBU R8, R9 /* R9 = revised count */ -dcflush1: /* primary cache line is 16 bytes */ - CACHE PI+HI, 0x00(R8) - CACHE PI+HI, 0x10(R8) - CACHE PI+HI, 0x20(R8) - CACHE PI+HI, 0x30(R8) - CACHE PD+HWBI, 0x00(R8) - CACHE PD+HWBI, 0x10(R8) - CACHE PD+HWBI, 0x20(R8) - CACHE PD+HWBI, 0x30(R8) - SUBU $0x40, R9 - ADDU $0x40, R8 - BGTZ R9, dcflush1 - MOVW R10, M(STATUS) - WAIT - RET - -TEXT cleancache(SB), $-4 - MOVW $KZERO, R1 - MOVW M(STATUS), R10 - WAIT - MOVW $0, M(STATUS) - WAIT - MOVW $(32*1024), R9 -ccache: - CACHE PD+IWBI, 0x00(R1) - WAIT - CACHE PI+IWBI, 0x00(R1) - WAIT - SUBU $16, R9 - ADDU $16, R1 - BGTZ R9, ccache - MOVW R10, M(STATUS) - WAIT - - /* - * set up 32 byte primary cache line sizes, - * kseg0 cache mode, - * and store conditional using tlb cache mode - */ - MOVW M(CONFIG), R1 - WAIT - AND $~0x3f, R1 - OR $((1<<4)|(1<<5)|(PTECOHERXCLW>>3)), R1 - MOVW R1, M(CONFIG) - WAIT - RET - -TEXT rdcount(SB), $0 - MOVW M(COUNT), R1 - NOOP - RET - -TEXT wrcompare(SB), $0 - MOVW R1, M(COMPARE) - RET - -TEXT rdcompare(SB), $0 - MOVW M(COMPARE), R1 - NOP - RET diff --git a/carrera/main.c b/carrera/main.c deleted file mode 100644 index ae94def9ad99885f06dfa5d2056ac9ed64269b2f..0000000000000000000000000000000000000000 --- a/carrera/main.c +++ /dev/null @@ -1,616 +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 "pool.h" - -/* - * args passed by boot process - */ -int _argc; char **_argv; char **_env; - -/* - * arguments passed to initcode and /boot - */ -char argbuf[128]; - -/* - * environment passed to boot -- sysname, consname, diskid - */ -char consname[NAMELEN]; -char bootdisk[NAMELEN]; -char screenldepth[NAMELEN]; - -/* - * software tlb simulation - */ -Softtlb stlb[MAXMACH][STLBSIZE]; - -Conf conf; -FPsave initfp; -int configreg; - -int int0mask = 0xff; /* interrupts enabled for first 8259 */ -int int1mask = 0xff; /* interrupts enabled for second 8259 */ - -extern uchar rdbgcode[]; -extern ulong rdbglen; -extern int noprint; - -static void addps(void); - -void -main(void) -{ - noprint = 1; - tlbinit(); - ioinit(1); /* Very early to establish IO mappings */ - rdbginit(); - arginit(); - confinit(); - savefpregs(&initfp); - machinit(); - kmapinit(); - xinit(); - iomapinit(); - printinit(); - serialinit(); - iprint("Plan 9\n"); /**/ - vecinit(); - screeninit(); - pageinit(); - procinit0(); - initseg(); - links(); - addps(); - chandevreset(); - swapinit(); - userinit(); - noprint = 0; - schedinit(); -} - - -/* - * copy arguments passed by the boot kernel (or ROM) into a temporary buffer. - * we do this because the arguments are in memory that may be allocated - * to processes or kernel buffers. - * - * also grab any environment variables that might be useful - */ -struct -{ - char *name; - char *val; -}bootenv[] = -{ - {"netaddr=", sysname}, - {"console=", consname}, - {"bootdisk=", bootdisk}, - {"ldepth=", screenldepth}, -}; -char *sp; - -char * -pusharg(char *p) -{ - int n; - - n = strlen(p)+1; - sp -= n; - memmove(sp, p, n); - return sp; -} - -void -arginit(void) -{ - int i, n; - char **av; - - /* - * get boot env variables - */ - if(*sysname == 0) - for(av = _env; *av; av++) - for(i=0; i < nelem(bootenv); i++){ - n = strlen(bootenv[i].name); - if(strncmp(*av, bootenv[i].name, n) == 0){ - strncpy(bootenv[i].val, (*av)+n, NAMELEN); - bootenv[i].val[NAMELEN-1] = '\0'; - break; - } - } - - /* - * pack args into buffer - */ - av = (char**)argbuf; - sp = argbuf + sizeof(argbuf); - for(i = 0; i < _argc; i++){ - if(strchr(_argv[i], '=')) - break; - av[i] = pusharg(_argv[i]); - } - av[i] = 0; -} - -/* - * initialize a processor's mach structure. each processor does this - * for itself. - */ -void -machinit(void) -{ - int n; - - /* Ensure CU1 is off */ - clrfpintr(); - - /* scrub cache */ - configreg = ((int(*)(void))((ulong)cleancache|0xA0000000))(); - - memset(m, 0, sizeof(Mach)); - - n = m->machno; - m->stb = &stlb[n][0]; - - m->speed = 50; - clockinit(); - - active.exiting = 0; - active.machs = 1; -} - -/* - * Set up a console on serial port 2 - */ -void -serialinit(void) -{ - ns16552install(); - kbdinit(); -} - -/* - * Map IO address space in wired down TLB entry 1 - */ -void -ioinit(int mapeisa) -{ - ulong devphys, isaphys, intphys, isamphys, promphys, ptec, ptes, v; - - /* - * If you want to segattach the eisa space these - * mappings must be turned off to prevent duplication - * of the tlb entries - */ - if(mapeisa) { - isaphys = IOPTE|PPN(Eisaphys)|PTEGLOBL; - isamphys = 0x04000000|IOPTE|PTEGLOBL; - } - else { - isaphys = PTEGLOBL; - isamphys = PTEGLOBL; - } - - /* - * Map devices and the Eisa control space - */ - devphys = IOPTE|PPN(Devicephys); - puttlbx(1, Devicevirt, devphys, isaphys, PGSZ64K); - - /* - * Map Interrupt control & Eisa memory - */ - intphys = IOPTE|PPN(Intctlphys); - puttlbx(2, Intctlvirt, intphys, isamphys, PGSZ1M); - - /* Enable all device interrupts */ - IO(ushort, Intenareg) = 0xffff; - - /* Map the rom back into Promvirt to allow NMI handling */ - promphys = IOPTE|PPN(Promphys); - puttlbx(3, Promvirt, promphys, PTEGLOBL, PGSZ1M); - - /* 8 MB video ram config */ - v = IO(ulong, 0xE0000004); - v &= ~(3<<8); - v |= (2<<8); - IO(ulong, 0xE0000004) = v; - - /* Map the display hardware */ - ptec = PPN(VideoCTL)|PTEGLOBL|PTEVALID|PTEWRITE|PTEUNCACHED; - ptes = PPN(VideoMEM)|PTEGLOBL|PTEVALID|PTEWRITE|PTEUNCACHED; - puttlbx(4, Screenvirt, ptes, ptec, PGSZ4M); - - /* for PC weenies */ - /* - * Set up the first 8259 interrupt processor. - * Make 8259 interrupts start at CPU vector Int0vec. - * Set the 8259 as master with edge triggered - * input with fully nested interrupts. - */ - EISAOUTB(Int0ctl, 0x11); /* ICW1 - edge triggered, master, - ICW4 will be sent */ - EISAOUTB(Int0aux, Int0vec); /* ICW2 - interrupt vector offset */ - EISAOUTB(Int0aux, 0x04); /* ICW3 - have slave on level 2 */ - EISAOUTB(Int0aux, 0x01); /* ICW4 - 8086 mode, not buffered */ - - /* - * Set up the second 8259 interrupt processor. - * Make 8259 interrupts start at CPU vector Int0vec. - * Set the 8259 as master with edge triggered - * input with fully nested interrupts. - */ - EISAOUTB(Int1ctl, 0x11); /* ICW1 - edge triggered, master, - ICW4 will be sent */ - EISAOUTB(Int1aux, Int1vec); /* ICW2 - interrupt vector offset */ - EISAOUTB(Int1aux, 0x02); /* ICW3 - I am a slave on level 2 */ - EISAOUTB(Int1aux, 0x01); /* ICW4 - 8086 mode, not buffered */ - - /* - * pass #2 8259 interrupts to #1 - */ - - /* enable all PC interrupts except the clock */ - int0mask = 0; - int0mask |= 1<<(Clockvec&7); - EISAOUTB(Int0aux, int0mask); - - int1mask = 0; - EISAOUTB(Int1aux, int1mask); - - IO(ulong, R4030ier) = 0xf; /* enable eisa interrupts */ -} - -/* - * Pull the ethernet address out of NVRAM - */ -void -enetaddr(uchar *ea) -{ - int i; - uchar tbuf[8]; - - for(i = 0; i < 8; i++) - tbuf[i] = ((uchar*)(NvramRO+Enetoffset))[i]; - - print("ether:"); - for(i = 0; i < 6; i++) { - ea[i] = tbuf[7-i]; - print("%2.2ux", ea[i]); - } - print("\n"); -} - -/* - * All DMA and ether IO buffers must reside in the first 16M bytes of - * memory to be covered by the translation registers - */ -void -iomapinit(void) -{ - int i; - Tte *t; - - t = xspanalloc(Ntranslation*sizeof(Tte), BY2PG, 0); - - for(i = 0; i < Ntranslation; i++) - t[i].lo = i<slash = namec("#/", Atodir, 0, 0); - cnameclose(up->slash->name); - up->slash->name = newcname("/"); - up->dot = cclone(up->slash, 0); - - chandevinit(); - - if(!waserror()){ - ksetenv("cputype", "mips"); - sprint(buf, "carrera %s R4400PC", conffile); - ksetenv("terminal", buf); - ksetenv("sysname", sysname); - poperror(); - } - - kproc("alarm", alarmkproc, 0); - touser((uchar*)(USTKTOP-sizeof(argbuf))); -} - -void -userinit(void) -{ - Proc *p; - KMap *k; - Page *pg; - char **av; - Segment *s; - - p = newproc(); - p->pgrp = newpgrp(); - p->egrp = smalloc(sizeof(Egrp)); - p->egrp->ref = 1; - p->fgrp = dupfgrp(nil); - p->rgrp = newrgrp(); - p->procmode = 0640; - - strcpy(p->text, "*init*"); - strcpy(p->user, eve); - - p->fpstate = FPinit; - p->fpsave.fpstatus = initfp.fpstatus; - - /* - * Kernel Stack - */ - p->sched.pc = (ulong)init0; - p->sched.sp = (ulong)p->kstack+KSTACK-(1+MAXSYSARG)*BY2WD; - /* - * User Stack, pass input arguments to boot process - */ - s = newseg(SG_STACK, USTKTOP-USTKSIZE, USTKSIZE/BY2PG); - p->seg[SSEG] = s; - pg = newpage(1, 0, USTKTOP-BY2PG); - segpage(s, pg); - 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 */ - s = newseg(SG_TEXT, UTZERO, 1); - s->flushme++; - p->seg[TSEG] = s; - pg = newpage(1, 0, UTZERO); - memset(pg->cachectl, PG_TXTFLUSH, sizeof(pg->cachectl)); - segpage(s, pg); - k = kmap(s->map[0]->pages[0]); - memmove((ulong*)VA(k), initcode, sizeof initcode); - kunmap(k); - - ready(p); -} - -void -exit(int type) -{ - uchar *vec; - - USED(type); - - lock(&active); - active.machs &= ~(1<machno); - active.exiting = 1; - unlock(&active); - - spllo(); - print("cpu%d exiting\n", m->machno); - while(consactive()) - delay(10); - - splhi(); - if(type == 1) - rdb(); - - /* Turn off the NMI hander for the debugger */ - vec = (uchar*)0xA0000420; - vec[0] = 0; - - firmware(type); -} - -ulong -memsize(void) -{ - ulong gcr; - - gcr = IO(ulong, MCTgcr); - /* Check for bank one enable - - * assumes both have 4Meg SIMMS - */ - if(gcr & 0x20){ - memset(UNCACHED(void, 16*MB), 0, 16*MB); - return 32*MB; - } - return 16*MB; -} - -void -confinit(void) -{ - ulong ktop, top; - - ktop = PGROUND((ulong)end); - ktop = PADDR(ktop); - top = memsize()/BY2PG; - - conf.base0 = 0; - conf.npage0 = top; - conf.npage = conf.npage0; - conf.npage0 -= ktop/BY2PG; - conf.base0 += ktop; - conf.npage1 = 0; - conf.base1 = 0; - - if(top > 16*MB/BY2PG){ - conf.upages = (conf.npage*60)/100; - imagmem->minarena = 4*1024*1024; - }else - conf.upages = (conf.npage*40)/100; - conf.ialloc = ((conf.npage-conf.upages)/2)*BY2PG; - - conf.nmach = 1; - - /* set up other configuration parameters */ - conf.nproc = 100; - conf.nswap = conf.npage*3; - conf.nswppo = 4096; - conf.nimage = 200; - - conf.monitor = 1; - - conf.copymode = 0; /* copy on write */ -} - -void -buzz(int f, int d) -{ - USED(f); - USED(d); -} - -int -cistrcmp(char *a, char *b) -{ - int ac, bc; - - for(;;){ - ac = *a++; - bc = *b++; - - if(ac >= 'A' && ac <= 'Z') - ac = 'a' + (ac - 'A'); - if(bc >= 'A' && bc <= 'Z') - bc = 'a' + (bc - 'A'); - ac -= bc; - if(ac) - return ac; - if(bc == 0) - break; - } - return 0; -} - -/* - * dummy routine for interoperability with pc's - */ -int -isaconfig(char *class, int ctlrno, ISAConf *isa) -{ - if(cistrcmp(class, "audio") == 0 && ctlrno == 0){ - strcpy(isa->type, "sb16"); - return 1; - } - if(cistrcmp(class, "ether") == 0 && ctlrno == 0){ - strcpy(isa->type, "sonic"); - return 1; - } - return 0; -} - -/* - register offsets of ARCS prom jmpbuf - JB_PC 0 - JB_SP 1 - JB_FP 2 - JB_S0 3 - JB_S1 4 - JB_S2 5 - JB_S3 6 - JB_S4 7 - JB_S5 8 - JB_S6 9 - JB_S7 10 -*/ - -struct -{ - ulong pc; - ulong sp; - ulong fp; - ulong s[7]; -} Mipsjmpbuf; - -void -rdbginit(void) -{ - uchar *vec; - ulong jba; -return;/**/ - /* Only interested in the PC */ - Mipsjmpbuf.pc = 0xA001C020; - - /* Link an NMI handler to the debugger - * - addresses from the ARCS rom source - */ - vec = (uchar*)0xA0000420; - jba = (ulong)UNCACHED(void, &Mipsjmpbuf); - - vec[0] = 'N'; - vec[1] = 'm'; - vec[2] = 'i'; - vec[3] = 's'; - vec[4] = jba>>24; - vec[5] = jba>>16; - vec[6] = jba>>8; - vec[7] = jba; - - /* Install the debugger code in a known place */ - memmove((void*)0xA001C000, rdbgcode, rdbglen); -} - -/* - * physical segs unique to the carrera - */ -static Physseg myphyssegs[] = -{ - { SG_PHYSICAL, "eisaio", Eisaphys, 64*1024, 0, 0 }, - { SG_PHYSICAL, "eisavga", Eisavgaphys, 128*1024, 0, 0 }, - { SG_PHYSICAL, "bootrom", 0x1fc00000, 256*1024, 0, 0 }, - { SG_PHYSICAL, "nvram", 0xe0009000, 12*1024, 0, 0 }, - { SG_PHYSICAL, "fb", 0x40000000, 4*1024*1024, 0, 0 }, -}; - -static void -addps(void) -{ - int i; - - for(i = 0; i < nelem(myphyssegs); i++) - addphysseg(&myphyssegs[i]); -} diff --git a/carrera/mem.h b/carrera/mem.h deleted file mode 100644 index 0c354d8aa9972955669c89cc29ddd02e217e355d..0000000000000000000000000000000000000000 --- a/carrera/mem.h +++ /dev/null @@ -1,243 +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 BY2V 8 /* bytes per vlong */ -#define BY2PG 4096 /* bytes per page */ -#define WD2PG (BY2PG/BY2WD) /* words per page */ -#define PGSHIFT 12 /* log(BY2PG) */ -#define ROUND(s, sz) (((s)+((sz)-1))&~((sz)-1)) -#define PGROUND(s) ROUND(s, BY2PG) - -#define MAXMACH 1 /* max # cpus system can run */ -#define KSTACK 4096 /* Size of kernel stack */ -#define BLOCKALIGN 8 - -/* - * Time - */ -#define HZ 100 /* clock frequency */ -#define MS2HZ (1000/HZ) /* millisec per clock tick */ -#define TK2SEC(t) ((t)/HZ) /* ticks to seconds */ -#define TK2MS(t) ((t)*MS2HZ) /* ticks to milliseconds */ -#define MS2TK(t) (((t)*HZ+500)/1000) /* milliseconds to closest tick */ - -/* - * CP0 registers - */ - -#define INDEX 0 -#define RANDOM 1 -#define TLBPHYS0 2 -#define TLBPHYS1 3 -#define CONTEXT 4 -#define PAGEMASK 5 -#define WIRED 6 -#define BADVADDR 8 -#define COUNT 9 -#define TLBVIRT 10 -#define COMPARE 11 -#define STATUS 12 -#define CAUSE 13 -#define EPC 14 -#define PRID 15 -#define CONFIG 16 -#define LLADDR 17 -#define WATCHLO 18 -#define WATCHHI 19 -#define CACHEECC 26 -#define CACHEERR 27 -#define TAGLO 28 -#define TAGHI 29 -#define ERROREPC 30 - -/* - * M(STATUS) bits - */ -#define KMODEMASK 0x0000001f -#define IE 0x00000001 -#define EXL 0x00000002 -#define ERL 0x00000004 -#define KSUPER 0x00000008 -#define KUSER 0x00000010 -#define KSU 0x00000018 -#define UX 0x00000020 -#define SX 0x00000040 -#define KX 0x00000080 -#define INTMASK 0x0000ff00 -#define INTR0 0x00000100 -#define INTR1 0x00000200 -#define INTR2 0x00000400 -#define INTR3 0x00000800 -#define INTR4 0x00001000 -#define INTR5 0x00002000 -#define INTR6 0x00004000 -#define INTR7 0x00008000 -#define DE 0x00010000 -#define BEV 0x00400000 -#define CU0 0x10000000 -#define CU1 0x20000000 - -/* - * Trap vectors - */ -#define UTLBMISS (KSEG0+0x000) -#define XEXCEPTION (KSEG0+0x080) -#define CACHETRAP (KSEG0+0x100) -#define EXCEPTION (KSEG0+0x180) - -/* - * Magic registers - */ -#define USER 24 /* R24 is up-> */ -#define MACH 25 /* R25 is m-> */ - -/* - * Fundamental addresses - */ -#define MACHADDR (KTZERO-MAXMACH*BY2PG) /* warning: rdbg is near here */ -#define MACHP(n) ((Mach *)(MACHADDR+(n)*BY2PG)) - -/* - * offsets in ureg.h for l.s - */ -#define Ureg_status (Uoffset+0) -#define Ureg_pc (Uoffset+4) -#define Ureg_sp (Uoffset+8) -#define Ureg_cause (Uoffset+12) -#define Ureg_badvaddr (Uoffset+16) -#define Ureg_tlbvirt (Uoffset+20) - -#define Ureg_hi (Uoffset+28) -#define Ureg_lo (Uoffset+36) -#define Ureg_r31 (Uoffset+44) -#define Ureg_r30 (Uoffset+52) -#define Ureg_r28 (Uoffset+60) -#define Ureg_r27 (Uoffset+68) -#define Ureg_r26 (Uoffset+76) -#define Ureg_r25 (Uoffset+84) -#define Ureg_r24 (Uoffset+92) -#define Ureg_r23 (Uoffset+100) -#define Ureg_r22 (Uoffset+108) -#define Ureg_r21 (Uoffset+116) -#define Ureg_r20 (Uoffset+124) -#define Ureg_r19 (Uoffset+132) -#define Ureg_r18 (Uoffset+140) -#define Ureg_r17 (Uoffset+148) -#define Ureg_r16 (Uoffset+156) -#define Ureg_r15 (Uoffset+164) -#define Ureg_r14 (Uoffset+172) -#define Ureg_r13 (Uoffset+180) -#define Ureg_r12 (Uoffset+188) -#define Ureg_r11 (Uoffset+196) -#define Ureg_r10 (Uoffset+204) -#define Ureg_r9 (Uoffset+212) -#define Ureg_r8 (Uoffset+220) -#define Ureg_r7 (Uoffset+228) -#define Ureg_r6 (Uoffset+236) -#define Ureg_r5 (Uoffset+244) -#define Ureg_r4 (Uoffset+252) -#define Ureg_r3 (Uoffset+260) -#define Ureg_r2 (Uoffset+268) -#define Ureg_r1 (Uoffset+276) - -/* Sizeof(Ureg) + (R5,R6) + 16 bytes slop + retpc + ur */ -#define UREGSIZE ((Ureg_r1+4-Uoffset) + 16 + 16 + 4 + 4) -#define Uoffset 8 - -/* - * MMU - */ -#define PGSZ4K (0x00<<13) -#define PGSZ64K (0x0F<<13) -#define PGSZ256K (0x3F<<13) -#define PGSZ1M (0xFF<<13) -#define PGSZ4M (0x3FF<<13) - -#define KUSEG 0x00000000 -#define KSEG0 0x80000000 -#define KSEG1 0xA0000000 -#define KSEG2 0xC0000000 -#define KSEG3 0xE0000000 -#define KSEGM 0xE0000000 /* mask to check which seg */ -#define CACHELINESZ 128 - -#define PIDXSHFT 12 -#define PIDX (0x7<>PIDXSHFT)&7) - -#define PTEGLOBL (1<<0) -#define PTEVALID (1<<1) -#define PTEWRITE (1<<2) -#define PTERONLY 0 -#define PTEALGMASK (7<<3) -#define PTEUNCACHED (2<<3) -#define PTENONCOHER (3<<3) -#define PTECOHERXCL (4<<3) -#define PTECOHERXCLW (5<<3) -#define PTECOHERUPDW (6<<3) -#define IOPTE (PTEGLOBL|PTEVALID|PTEWRITE|PTEUNCACHED) - -#define PTEPID(n) (n) -#define TLBPID(n) ((n)&0xFF) -#define PTEMAPMEM (1024*1024) -#define PTEPERTAB (PTEMAPMEM/BY2PG) -#define STLBLOG 13 -#define STLBSIZE (1<next = k+1; - k->next = 0; - - m->ktlbnext = TLBROFF; -} - -/* - * Arrange that the KMap'd virtual address will hit the same - * primary cache line as pg->va by making bits 14...12 of the - * tag the same as virtual address. These bits are the index - * into the primary cache and are checked whenever accessing - * the secondary cache through the primary. Violation causes - * a VCE trap. - */ -KMap * -kmap(Page *pg) -{ - int s; - KMap *k; - ulong pte; - ulong x, virt; - - s = splhi(); - lock(&kmaplock); - - if(kmapfree == 0) { - unlock(&kmaplock); - kmapinval(); /* try and free some */ - lock(&kmaplock); - if(kmapfree == 0) - panic("out of kmap"); - } - - k = kmapfree; - kmapfree = k->next; - - k->pg = pg; - /* One for the allocation, - * One for kactive - */ - k->ref = 2; - k->konmach[m->machno] = m->kactive; - m->kactive = k; - - virt = pg->va; - /* bits 14..12 form the secondary-cache virtual index */ - virt &= PIDX; - virt |= KMAPADDR | ((k-kpte)<virt = virt; - pte = PPN(pg->pa)|PTECOHERXCLW|PTEGLOBL|PTEWRITE|PTEVALID; - if(virt & BY2PG) { - k->phys0 = PTEGLOBL|PTECOHERXCLW; - k->phys1 = pte; - } - else { - k->phys0 = pte; - k->phys1 = PTEGLOBL|PTECOHERXCLW; - } - - x = m->ktlbnext; - k->tlbi[m->machno] = x; - puttlbx(x, (virt&~BY2PG)|TLBPID(tlbvirt()), k->phys0, k->phys1, PGSZ4K); - if(++x >= NTLB) - m->ktlbnext = TLBROFF; - else - m->ktlbnext = x; - - unlock(&kmaplock); - - splx(s); - return k; -} - -void -kunmap(KMap *k) -{ - int s; - - s = splhi(); - if(decref(k) == 0) { - k->virt = 0; - k->phys0 = 0; - k->phys1 = 0; - k->pg = 0; - - lock(&kmaplock); - k->next = kmapfree; - kmapfree = k; - unlock(&kmaplock); - } - splx(s); -} - -void -kfault(Ureg *ur) -{ - int mno; - KMap *k, *f; - ulong x, index, virt, addr; - - mno = m->machno; - addr = ur->badvaddr; - index = (addr & ~KMAPADDR) >> KMAPSHIFT; - - if(index >= KPTESIZE) - panic("kmapfault: %lux", addr); - - k = &kpte[index]; - if(k->virt == 0 || k->ref < 1) - panic("kmapfault: unmapped %lux", addr); - - for(f = m->kactive; f; f = f->konmach[mno]) - if(f == k) - break; - - if(f == 0) { - incref(k); - k->konmach[mno] = m->kactive; - m->kactive = k; - } - - x = m->ktlbnext; - virt = (k->virt&~BY2PG)|TLBPID(tlbvirt()); - puttlbx(x, virt, k->phys0, k->phys1, PGSZ4K); - k->tlbi[mno] = x; - - if(++x >= NTLB) - m->ktlbnext = TLBROFF; - else - m->ktlbnext = x; -} - -void -kmapinval() -{ - int mno, curpid; - KMap *k, *next; - - if(m->kactive == 0) - return; - - curpid = PTEPID(TLBPID(tlbvirt())); - mno = m->machno; - for(k = m->kactive; k; k = next) { - next = k->konmach[mno]; - TLBINVAL(k->tlbi[mno], curpid); - kunmap(k); - } - m->kactive = 0; -} - -void -mmuswitch(Proc *p) -{ - int tp; - - if(p->newtlb) { - memset(p->pidonmach, 0, sizeof p->pidonmach); - p->newtlb = 0; - } - tp = p->pidonmach[m->machno]; - if(tp == 0) - tp = newtlbpid(p); - - puttlbx(0, KZERO|PTEPID(tp), 0, 0, PGSZ4K); -} - -void -mmurelease(Proc *p) -{ - memset(p->pidonmach, 0, sizeof p->pidonmach); -} - -/* - * Process must be splhi - */ -int -newtlbpid(Proc *p) -{ - int i, s; - Proc **h; - - i = m->lastpid; - h = m->pidproc; - for(s = 0; s < NTLBPID; s++) { - i++; - if(i >= NTLBPID) - i = 1; - if(h[i] == 0) - break; - } - - if(h[i]) - purgetlb(i); - if(h[i] != 0) - panic("newtlb"); - - m->pidproc[i] = p; - p->pidonmach[m->machno] = i; - m->lastpid = i; - - return i; -} - -void -putmmu(ulong tlbvirt, ulong tlbphys, Page *pg) -{ - int s; - short tp; - char *ctl; - Softtlb *entry; - - s = splhi(); - tp = up->pidonmach[m->machno]; - if(tp == 0) - tp = newtlbpid(up); - - /* - * Fix up EISA memory address which are greater - * than 32 bits physical: 0x100000000 - */ - if((tlbphys&0xffff0000) == PPN(Eisamphys)) { - tlbphys &= ~PPN(Eisamphys); - tlbphys |= 0x04000000; - } - tlbvirt |= PTEPID(tp); - if((tlbphys & PTEALGMASK) != PTEUNCACHED) { - tlbphys &= ~PTEALGMASK; - tlbphys |= PTECOHERXCLW; - } - - entry = putstlb(tlbvirt, tlbphys); - puttlb(entry->virt, entry->phys0, entry->phys1); - - ctl = &pg->cachectl[m->machno]; - switch(*ctl) { - case PG_TXTFLUSH: - icflush((void*)pg->va, BY2PG); - *ctl = PG_NOFLUSH; - break; - case PG_DATFLUSH: - dcflush((void*)pg->va, BY2PG); - *ctl = PG_NOFLUSH; - break; - case PG_NEWCOL: - cleancache(); /* Too expensive */ - *ctl = PG_NOFLUSH; - break; - } - splx(s); -} - -void -purgetlb(int pid) -{ - int i, mno; - Proc *sp, **pidproc; - Softtlb *entry, *etab; - - m->tlbpurge++; - - /* - * find all pid entries that are no longer used by processes - */ - mno = m->machno; - pidproc = m->pidproc; - for(i=1; ipidonmach[mno] != i) - pidproc[i] = 0; - } - - /* - * shoot down the one we want - */ - sp = pidproc[pid]; - if(sp != 0) - sp->pidonmach[mno] = 0; - pidproc[pid] = 0; - - /* - * clean out all dead pids from the stlb; - */ - entry = m->stb; - for(etab = &entry[STLBSIZE]; entry < etab; entry++) - if(pidproc[TLBPID(entry->virt)] == 0) - entry->virt = 0; - - /* - * clean up the hardware - */ - for(i=TLBROFF; inewtlb = 1; - mmuswitch(up); - splx(s); -} - -void -clearmmucache(void) -{ -} - -Softtlb* -putstlb(ulong tlbvirt, ulong tlbphys) -{ - int k; - Softtlb *entry; - - k = tlbvirt & BY2PG; - tlbvirt &= ~BY2PG; - - entry = &m->stb[(tlbvirt ^ (tlbvirt>>13)) & (STLBSIZE-1)]; - if(entry->virt != tlbvirt) { - entry->virt = tlbvirt; - entry->phys0 = 0; - entry->phys1 = 0; - } - - if(k) - entry->phys1 = tlbphys; - else - entry->phys0 = tlbphys; - - if(entry->phys0 == 0 && entry->phys1 == 0) - entry->virt = 0; - - return entry; -} diff --git a/carrera/ns16552.h b/carrera/ns16552.h deleted file mode 100644 index bd05fba544b1cfcda8c4cd0cd9522e4c2f2b24e1..0000000000000000000000000000000000000000 --- a/carrera/ns16552.h +++ /dev/null @@ -1,19 +0,0 @@ -#define outb(p, ch) *(uchar*)((p)^7) = ch -#define inb(p) *(uchar*)((p)^7) -#define uartwrreg(u,r,v) outb((u)->port + (r), (u)->sticky[r] | (v)) -#define uartrdreg(u,r) *(uchar*)(((u)->port + (r))^7) - -#define uartpower(x, y) - -void -ns16552install(void) -{ - static int already; - - if(already) - return; - already = 1; - - ns16552setup(Uart1, UartFREQ, "eia0", Ns550); -} - diff --git a/carrera/random.c b/carrera/random.c deleted file mode 100644 index 4954367f8ad4a996b0d9ee49e775103f92beb9b8..0000000000000000000000000000000000000000 --- a/carrera/random.c +++ /dev/null @@ -1,138 +0,0 @@ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "../port/error.h" - - -struct Rb -{ - QLock; - Rendez producer; - Rendez consumer; - ulong randomcount; - uchar buf[1024]; - uchar *ep; - uchar *rp; - uchar *wp; - uchar next; - uchar wakeme; - ushort bits; - ulong randn; -} rb; - -static int -rbnotfull(void*) -{ - int i; - - i = rb.rp - rb.wp; - return i != 1 && i != (1 - sizeof(rb.buf)); -} - -static int -rbnotempty(void*) -{ - return rb.wp != rb.rp; -} - -void -genrandom(void*) -{ - up->basepri = PriNormal; - up->priority = up->basepri; - - for(;;){ - for(;;) - if(++rb.randomcount > 100000) - break; - if(anyhigher()) - sched(); - if(!rbnotfull(0)) - sleep(&rb.producer, rbnotfull, 0); - } -} - -/* - * produce random bits in a circular buffer - */ -static void -randomclock(void) -{ - if(rb.randomcount == 0 || !rbnotfull(0)) - return; - - rb.bits = (rb.bits<<2) ^ rb.randomcount; - rb.randomcount = 0; - - rb.next++; - if(rb.next != 8/2) - return; - rb.next = 0; - - *rb.wp ^= rb.bits; - if(rb.wp+1 == rb.ep) - rb.wp = rb.buf; - else - rb.wp = rb.wp+1; - - if(rb.wakeme) - wakeup(&rb.consumer); -} - -void -randominit(void) -{ - addclock0link(randomclock); - rb.ep = rb.buf + sizeof(rb.buf); - rb.rp = rb.wp = rb.buf; - kproc("genrandom", genrandom, 0); -} - -/* - * consume random bytes from a circular buffer - */ -ulong -randomread(void *xp, ulong n) -{ - uchar *e, *p; - ulong x; - - p = xp; - - if(waserror()){ - qunlock(&rb); - nexterror(); - } - - qlock(&rb); - for(e = p + n; p < e; ){ - if(rb.wp == rb.rp){ - rb.wakeme = 1; - wakeup(&rb.producer); - sleep(&rb.consumer, rbnotempty, 0); - rb.wakeme = 0; - continue; - } - - /* - * beating clocks will be precictable if - * they are synchronized. Use a cheap pseudo - * random number generator to obscure any cycles. - */ - x = rb.randn*1103515245 ^ *rb.rp; - *p++ = rb.randn = x; - - if(rb.rp+1 == rb.ep) - rb.rp = rb.buf; - else - rb.rp = rb.rp+1; - } - qunlock(&rb); - poperror(); - - wakeup(&rb.producer); - - return n; -} diff --git a/carrera/screen.c b/carrera/screen.c deleted file mode 100644 index b0e06833b22939d388f7e9f124a3d0076c0ee86c..0000000000000000000000000000000000000000 --- a/carrera/screen.c +++ /dev/null @@ -1,620 +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" - -#define Image IMAGE -#include -#include -#include -#include "screen.h" - -#define MINX 8 - -#define DAC ((Dac*)BTDac) -typedef struct Dac Dac; -struct Dac -{ - uchar pad0[7]; - uchar cr0; - uchar pad1[7]; - uchar cr1; - uchar pad2[7]; - uchar cr2; - uchar pad3[7]; - uchar cr3; -}; - -char s1[] = { 0x00, 0x00, 0xC0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; -#define Backgnd 0xFF /* white */ - - Memsubfont *memdefont; -static ulong rep(ulong, int); - -struct{ - Point pos; - int bwid; -}out; - -Lock screenlock; - -Point ZP = {0, 0}; - -static Memdata gscreendata = -{ - nil, - (ulong*)(Screenvirt+0x000178D0), - 1, -}; - -static Memimage xgscreen = -{ - { 0, 0, 1597, 1234 }, /* r */ - { 0, 0, 1597, 1234 }, /* clipr */ - 8, /* depth */ - 1, /* nchan */ - CMAP8, /* chan */ - nil, /* cmap */ - &gscreendata, /* data */ - 0, /* zero */ - 512, /* width */ - 0, /* layer */ - 0, /* flags */ -}; - -Memimage *gscreen; -Memimage *conscol; -Memimage *back; -Memimage *hwcursor; - -Cursor arrow = { - { -1, -1 }, - { 0xFF, 0xFF, 0x80, 0x01, 0x80, 0x02, 0x80, 0x0C, - 0x80, 0x10, 0x80, 0x10, 0x80, 0x08, 0x80, 0x04, - 0x80, 0x02, 0x80, 0x01, 0x80, 0x02, 0x8C, 0x04, - 0x92, 0x08, 0x91, 0x10, 0xA0, 0xA0, 0xC0, 0x40, - }, - { 0x00, 0x00, 0x7F, 0xFE, 0x7F, 0xFC, 0x7F, 0xF0, - 0x7F, 0xE0, 0x7F, 0xE0, 0x7F, 0xF0, 0x7F, 0xF8, - 0x7F, 0xFC, 0x7F, 0xFE, 0x7F, 0xFC, 0x73, 0xF8, - 0x61, 0xF0, 0x60, 0xE0, 0x40, 0x40, 0x00, 0x00, - }, -}; - -static Rectangle window; -static Point curpos; -static int h, w; -int drawdebug; - -void -screenwin(void) -{ - Dac *d; - Point p, q; - Cursor zero; - char *greet; - Memimage *grey; - - gscreen = &xgscreen; - memsetchan(gscreen, CMAP8); - hwcursor = allocmemimage(Rect(0,0,64,64), GREY2); - memsetchan(hwcursor, GREY2); - - back = memwhite; - conscol = memblack; - - memset((void*)Screenvirt, 0, 3*1024*1024); - memfillcolor(gscreen, 0x444488FF); - - w = memdefont->info[' '].width; - h = memdefont->height; - - window.min = Pt(100, 100); - window.max = addpt(window.min, Pt(10+w*120, 10+h*60)); - - memimagedraw(gscreen, window, memblack, ZP, memopaque, ZP); - window = insetrect(window, 4); - memimagedraw(gscreen, window, memwhite, ZP, memopaque, ZP); - - /* a lot of work to get a grey color */ - grey = allocmemimage(Rect(0,0,1,1), CMAP8); - grey->flags |= Frepl; - grey->clipr = gscreen->r; - grey->data->bdata[0] = 0xAA; - memimagedraw(gscreen, Rect(window.min.x, window.min.y, - window.max.x, window.min.y+h+5+6), grey, ZP, nil, ZP); - freememimage(grey); - window = insetrect(window, 5); - - greet = " Plan 9 Console "; - p = addpt(window.min, Pt(10, 0)); - q = memsubfontwidth(memdefont, greet); - memimagestring(gscreen, p, conscol, ZP, memdefont, greet); - window.min.y += h+6; - curpos = window.min; - window.max.y = window.min.y+((window.max.y-window.min.y)/h)*h; - - d = DAC; - /* cursor color 1: white */ - d->cr1 = 0x01; - d->cr0 = 0x81; - d->cr2 = 0xFF; - d->cr2 = 0xFF; - d->cr2 = 0xFF; - /* cursor color 2: noir */ - d->cr1 = 0x01; - d->cr0 = 0x82; - d->cr2 = 0; - d->cr2 = 0; - d->cr2 = 0; - /* cursor color 3: schwarz */ - d->cr1 = 0x01; - d->cr0 = 0x83; - d->cr2 = 0; - d->cr2 = 0; - d->cr2 = 0; - /* initialize with all-transparent cursor */ - memset(&zero, 0, sizeof zero); - setcursor(&zero); - /* enable both planes of cursor */ - d->cr1 = 0x03; - d->cr0 = 0x00; - d->cr2 = 0xc0; -} - -void -dacinit(void) -{ - Dac *d; - int i; - - d = DAC; - - /* Control registers */ - d->cr0 = 0x01; - d->cr1 = 0x02; - for(i = 0; i < sizeof s1; i++) - d->cr2 = s1[i]; - - /* Cursor programming */ - d->cr0 = 0x00; - d->cr1 = 0x03; - d->cr2 = 0xC0; - for(i = 0; i < 12; i++) - d->cr2 = 0; - - /* Load Cursor Ram */ - d->cr0 = 0x00; - d->cr1 = 0x04; - for(i = 0; i < 0x400; i++) - d->cr2 = 0xff; - - drawcmap(); - - /* Overlay Palette Ram */ - d->cr0 = 0x00; - d->cr1 = 0x01; - for(i = 0; i < 0x10; i++) { - d->cr2 = 0xff; - d->cr2 = 0xff; - d->cr2 = 0xff; - } - - /* Overlay Palette Ram */ - d->cr0 = 0x81; - d->cr1 = 0x01; - for(i = 0; i < 3; i++) { - d->cr2 = 0xff; - d->cr2 = 0xff; - d->cr2 = 0xff; - } -} - -void -screeninit(void) -{ - dacinit(); - - memimageinit(); - memdefont = getmemdefont(); - - out.pos.x = MINX; - out.pos.y = 0; - out.bwid = memdefont->info[' '].width; - - screenwin(); -} - -static void -scroll(void) -{ - int o; - Point p; - Rectangle r; - - o = 8*h; - r = Rpt(window.min, Pt(window.max.x, window.max.y-o)); - p = Pt(window.min.x, window.min.y+o); - memimagedraw(gscreen, r, gscreen, p, nil, p); - r = Rpt(Pt(window.min.x, window.max.y-o), window.max); - memimagedraw(gscreen, r, back, ZP, nil, ZP); - - curpos.y -= o; -} - -/* - * export screen to devdraw - */ -uchar* -attachscreen(Rectangle *r, ulong *chan, int* d, int *width, int *softscreen) -{ - *r = gscreen->r; - *d = gscreen->depth; - *chan = gscreen->chan; - *width = gscreen->width; - *softscreen = 0; - - return gscreendata.bdata; -} - -/* - * update screen (no-op: frame buffer is direct-mapped) - */ -void -flushmemscreen(Rectangle r) -{ - USED(r); -/* - DEBUG version flashes the screen to indicate what's being painted - Memimage *x; - int i; - - if(Dx(r)<=0 || Dy(r)<=0) - return; - x = allocmemimage(r, 3); - memimagedraw(x, r, &gscreen, r.min, memopaque, r.min); - memimagedraw(&gscreen, r, memblack, r.min, memopaque, r.min); - for(i=1000000; --i>0; ); - memimagedraw(&gscreen, r, x, r.min, memopaque, r.min); - freememimage(x); -*/ -} - -static void -screenputc(char *buf) -{ - Point p; - int w, pos; - Rectangle r; - static int *xp; - static int xbuf[256]; - - if(xp < xbuf || xp >= &xbuf[sizeof(xbuf)]) - xp = xbuf; - - switch(buf[0]) { - case '\n': - if(curpos.y+h >= window.max.y) - scroll(); - curpos.y += h; - screenputc("\r"); - break; - case '\r': - xp = xbuf; - curpos.x = window.min.x; - break; - case '\t': - p = memsubfontwidth(memdefont, " "); - w = p.x; - if(curpos.x >= window.max.x-8*w) - screenputc("\n"); - - pos = (curpos.x-window.min.x)/w; - pos = 8-(pos%8); - *xp++ = curpos.x; - r = Rect(curpos.x, curpos.y, curpos.x+pos*w, curpos.y + h); - memimagedraw(gscreen, r, back, back->r.min, nil, back->r.min); - curpos.x += pos*w; - break; - case '\b': - if(xp <= xbuf) - break; - xp--; - r = Rect(*xp, curpos.y, curpos.x, curpos.y + h); - memimagedraw(gscreen, r, back, back->r.min, nil, back->r.min); - curpos.x = *xp; - break; - case '\0': - break; - default: - p = memsubfontwidth(memdefont, buf); - w = p.x; - - if(curpos.x >= window.max.x-w) - screenputc("\n"); - - *xp++ = curpos.x; - r = Rect(curpos.x, curpos.y, curpos.x+w, curpos.y + h); - memimagedraw(gscreen, r, back, back->r.min, nil, back->r.min); - memimagestring(gscreen, curpos, conscol, ZP, memdefont, buf); - curpos.x += w; - } -} - -void -screenputs(char *s, int n) -{ - int i; - Rune r; - char buf[4]; - - if(!islo()) { - /* don't deadlock trying to print in interrupt */ - if(!canlock(&screenlock)) - return; - } - 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; - screenputc(buf); - } - unlock(&screenlock); -} - -uchar revtab0[] = { - 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, - 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, - 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, - 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, - 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, - 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, - 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, - 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, - 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, - 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, - 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, - 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, - 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, - 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, - 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, - 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, - 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, - 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, - 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, - 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, - 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, - 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, - 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, - 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, - 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, - 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, - 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, - 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, - 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, - 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, - 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, - 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff, -}; - -void -getcolor(ulong p, ulong *pr, ulong *pg, ulong *pb) -{ - Dac *d; - uchar r, g, b; - extern uchar revtab0[]; - - d = DAC; - - /* to protect DAC from mouse movement */ - lock(&cursor); - - d->cr0 = revtab0[p & 0xFF]; - d->cr1 = 0; - r = d->cr3; - g = d->cr3; - b = d->cr3; - *pr = (r<<24) | (r<<16) | (r<<8) | r; - *pg = (g<<24) | (g<<16) | (g<<8) | g; - *pb = (b<<24) | (b<<16) | (b<<8) | b; - - unlock(&cursor); -} - -int -setcolor(ulong p, ulong r, ulong g, ulong b) -{ - Dac *d; - extern uchar revtab0[]; - - d = DAC; - - /* to protect DAC from mouse movement */ - lock(&cursor); - - d->cr0 = revtab0[p & 0xFF]; - d->cr1 = 0; - d->cr3 = r >> 24; - d->cr3 = g >> 24; - d->cr3 = b >> 24; - - unlock(&cursor); - - return 1; -} - -/* 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; -} - -void -setcursor(Cursor *curs) -{ - Dac *d; - int x, y, i; - Point org; - uchar ylow, yhigh, *p; - ulong spix, cpix, dpix; - ushort s[16], c[16]; - - for(i=0; i<16; i++){ - p = (uchar*)&s[i]; - *p = curs->set[2*i]; - *(p+1) = curs->set[2*i+1]; - p = (uchar*)&c[i]; - *p = curs->clr[2*i]; - *(p+1) = curs->clr[2*i+1]; - } - memset(hwcursor->data->bdata, 0, sizeof(long)*hwcursor->width*Dy(hwcursor->r)); - /* hw cursor is 64x64 with hot point at (32,32) */ - org = addpt(Pt(32,32), curs->offset); - for(y = 0; y < 16; y++) - for(x = 0; x < 16; x++) { - spix = (s[y]>>(15-x))&1; - cpix = (c[y]>>(15-x))&1; - dpix = (spix<<1) | cpix; - /* point(&hwcursor, addpt(Pt(x,y), org), dpix, S), by hand */ - *byteaddr(hwcursor, Pt(x+org.x, y+org.y)) |= (dpix<<(6-(2*((x+org.x)&3)))); - } - - d = DAC; - - /* have to set y offscreen before writing cursor bits */ - d->cr1 = 0x03; - d->cr0 = 0x03; - ylow = d->cr2; - yhigh = d->cr2; - d->cr1 = 0x03; - d->cr0 = 0x03; - d->cr2 = 0xFF; - d->cr2 = 0xFF; - /* now set the bits */ - d->cr1 = 0x04; - d->cr0 = 0x00; - for(x = 0; x < 1024; x++) - d->cr2 = hwcursor->data->bdata[x]; - /* set y back */ - d->cr1 = 0x03; - d->cr0 = 0x03; - d->cr2 = ylow; - d->cr2 = yhigh; -} - -int -cursoron(int dolock) -{ - Dac *d; - Point p; - - p = mousexy(); - - d = DAC; - - if(dolock) - lock(&cursor); - - p.x += 296; /* adjusted by experiment */ - p.y += 9; /* adjusted by experiment */ - d->cr1 = 03; - d->cr0 = 01; - d->cr2 = p.x&0xFF; - d->cr2 = (p.x>>8)&0xF; - d->cr2 = p.y&0xFF; - d->cr2 = (p.y>>8)&0xF; - - if(dolock) - unlock(&cursor); - return 0; -} - -int -screenbits(void) -{ - return gscreen->depth; -} - -extern cursorlock(Rectangle); -extern cursorunlock(void); - -/* - * paste tile into screen. - * tile is at location r, first pixel in *data. - * tl is length of scan line to insert, - * l is amount to advance data after each scan line. - * gscreen.ldepth is known to be >= 3 - */ -void -screenload(Rectangle r, uchar *data, int tl, int l, int dolock) -{ - uchar *q; - int y; - - USED(dolock); - - if(!rectclip(&r, gscreen->r) || tl<=0) - return; - - lock(&screenlock); - q = byteaddr(gscreen, r.min); - for(y=r.min.y; ywidth*sizeof(ulong); - data += l; - } - unlock(&screenlock); -} - -/* - * get a tile from screen memory. - * tile is at location r, first pixel in *data. - * tl is length of scan line to insert, - * l is amount to advance data after each scan line. - * gscreen.ldepth is known to be >= 3. - * screenunload() doesn't clip, so must be - * called correctly. - */ -void -screenunload(Rectangle r, uchar *data, int tl, int l, int dolock) -{ - uchar *q; - int y; - - USED(dolock); - - lock(&screenlock); - q = byteaddr(gscreen, r.min); - for(y=r.min.y; ywidth*sizeof(ulong); - data += l; - } - unlock(&screenlock); -} - -void -blankscreen(int) -{ -} diff --git a/carrera/screen.h b/carrera/screen.h deleted file mode 100644 index 2e600cc2f910c2d04a24124c0df55eabc9a6a4e8..0000000000000000000000000000000000000000 --- a/carrera/screen.h +++ /dev/null @@ -1,20 +0,0 @@ -typedef struct Cursor Cursor; -typedef struct Cursorinfo Cursorinfo; - -struct Cursorinfo -{ - Cursor; - Lock; -}; - -extern Cursorinfo cursor; -extern Cursor arrow; - -extern int cursoron(int); -#define cursoroff(x) -extern Point mousexy(void); -void setcursor(Cursor*); - -void mousectl(char*[], int); -void mousetrack(int, int, int); -void blankscreen(int); diff --git a/carrera/trap.c b/carrera/trap.c deleted file mode 100644 index 4cd1354cbbb9526169ce944aa82fc76419c40f72..0000000000000000000000000000000000000000 --- a/carrera/trap.c +++ /dev/null @@ -1,888 +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*, Ureg**, ulong); -void rfnote(Ureg**); -void kernfault(Ureg*, int); - -char *excname[] = -{ - "trap: external interrupt", - "trap: TLB modification", - "trap: TLB miss (load or fetch)", - "trap: TLB miss (store)", - "trap: address error (load or fetch)", - "trap: address error (store)", - "trap: bus error (fetch)", - "trap: bus error (data load or store)", - "trap: system call", - "breakpoint", - "trap: reserved instruction", - "trap: coprocessor unusable", - "trap: arithmetic overflow", - "trap: TRAP exception", - "trap: VCE (instruction)", - "trap: floating-point exception", - "trap: undefined 16", /* used as sys call for debugger */ - "trap: undefined 17", - "trap: undefined 18", - "trap: undefined 19", - "trap: undefined 20", - "trap: undefined 21", - "trap: undefined 22", - "trap: WATCH exception", - "trap: undefined 24", - "trap: undefined 25", - "trap: undefined 26", - "trap: undefined 27", - "trap: undefined 28", - "trap: undefined 29", - "trap: undefined 30", - "trap: VCE (data)", -}; - -char *fpcause[] = -{ - "inexact operation", - "underflow", - "overflow", - "division by zero", - "invalid operation", -}; -char *fpexcname(Ureg*, ulong, char*); -#define FPEXPMASK (0x3f<<12) /* Floating exception bits in fcr31 */ -void (*eisadma[8])(void); /* Eisa dma chain vectors */ - - -struct -{ - char *name; - int off; -} regname[]={ - "STATUS", Ureg_status, - "PC", Ureg_pc, - "SP", Ureg_sp, - "CAUSE", Ureg_cause, - "BADADDR", Ureg_badvaddr, - "TLBVIRT", Ureg_tlbvirt, - "HI", Ureg_hi, - "LO", Ureg_lo, - "R31", Ureg_r31, - "R30", Ureg_r30, - "R28", Ureg_r28, - "R27", Ureg_r27, - "R26", Ureg_r26, - "R25", Ureg_r25, - "R24", Ureg_r24, - "R23", Ureg_r23, - "R22", Ureg_r22, - "R21", Ureg_r21, - "R20", Ureg_r20, - "R19", Ureg_r19, - "R18", Ureg_r18, - "R17", Ureg_r17, - "R16", Ureg_r16, - "R15", Ureg_r15, - "R14", Ureg_r14, - "R13", Ureg_r13, - "R12", Ureg_r12, - "R11", Ureg_r11, - "R10", Ureg_r10, - "R9", Ureg_r9, - "R8", Ureg_r8, - "R7", Ureg_r7, - "R6", Ureg_r6, - "R5", Ureg_r5, - "R4", Ureg_r4, - "R3", Ureg_r3, - "R2", Ureg_r2, - "R1", Ureg_r1, -}; - -static char * -ptlb(ulong phys) -{ - static char buf[4][32]; - static int k; - char *p; - - k = (k+1)&3; - p = buf[k]; - p += sprint(p, "(0x%lux %ld ", (phys<<6) & ~(BY2PG-1), (phys>>3)&7); - if(phys & 4) - *p++ = 'd'; - if(phys & 2) - *p++ = 'v'; - if(phys & 1) - *p++ = 'g'; - *p++ = ')'; - *p = 0; - return buf[k]; -} - -static void -kpteprint(Ureg *ur) -{ - ulong i, tlbstuff[3]; - KMap *k; - - i = (ur->badvaddr & ~(2*BY2PG-1)) | TLBPID(tlbvirt()); - print("tlbvirt=0x%lux\n", i); - i = gettlbp(i, tlbstuff); - print("i=%ld v=0x%lux p0=%s p1=%s\n", - i, tlbstuff[0], ptlb(tlbstuff[1]), ptlb(tlbstuff[2])); - - i = (ur->badvaddr & ~KMAPADDR)>>15; - if(i > KPTESIZE){ - print("kpte index = 0x%lux ?\n", i); - return; - } - k = &kpte[i]; - print("i=%ld, &k=0x%lux, k={v=0x%lux, p0=%s, p1=%s, pg=0x%lux}\n", - i, k, k->virt, ptlb(k->phys0), ptlb(k->phys1), k->pg); - print("pg={pa=0x%lux, va=0x%lux}\n", k->pg->pa, k->pg->va); -} - -void -kvce(Ureg *ur, int ecode) -{ - char c; - Pte **p; - Page **pg; - Segment *s; - ulong addr, soff; - - c = 'D'; - if(ecode == CVCEI) - c = 'I'; - print("Trap: VCE%c: addr=0x%lux\n", c, ur->badvaddr); - if((ur->badvaddr & KSEGM) == KSEG3) { - kpteprint(ur); - return; - } - if(up && !(ur->badvaddr & KSEGM)) { - addr = ur->badvaddr; - s = seg(up, addr, 0); - if(s == 0){ - print("no s\n"); - for(;;); - } - addr &= ~(BY2PG-1); - soff = addr-s->base; - p = &s->map[soff/PTEMAPMEM]; - if(*p){ - pg = &(*p)->pages[(soff&(PTEMAPMEM-1))/BY2PG]; - if(*pg) { - print("pa=0x%lux, va=0x%lux\n", - (*pg)->pa, (*pg)->va); - } else - print("no *pg\n"); - }else - print("no *p\n"); - } -} - -void -trap(Ureg *ur) -{ - int ecode; - ulong fpfcr31; - int user, cop, x, fpchk; - char buf[2*ERRLEN], buf1[ERRLEN], *fpexcep; - - m->intrts = fastticks(nil); - - /* - * Retry failed probes of legal addresses from tstbadvaddr - * workaround for the R4400 >2.3 - */ - if(m->vaddrtst) { - m->vaddrtst = 0; - return; - } - - ecode = (ur->cause>>2)&EXCMASK; - user = ur->status&KUSER; - - fpchk = 0; - if(user){ - up->dbgreg = ur; - if(up && up->fpstate == FPactive) { - if((ur->status&CU1) == 0) /* Paranoid */ - panic("FPactive but no CU1"); - ur->status &= ~CU1; - up->fpstate = FPinactive; - savefpregs(&up->fpsave); - } - } - - switch(ecode){ - case CINT: - intr(ur); - break; - - case CFPE: - fptrap(ur); - clrfpintr(); - fpchk = 1; - break; - - case CTLBM: - case CTLBL: - case CTLBS: - if(up == 0) - kernfault(ur, ecode); - - if(!user && (ur->badvaddr & KMAPMASK) == KMAPADDR) { - kfault(ur); - break; - } - - x = up->insyscall; - up->insyscall = 1; - spllo(); - faultmips(ur, user, ecode); - up->insyscall = x; - break; - - case CVCEI: - case CVCED: - kvce(ur, ecode); - goto Default; - - case CCPU: - cop = (ur->cause>>28)&3; - if(user && up && cop == 1) { - if(up->fpstate == FPinit) { - up->fpstate = FPinactive; - fpfcr31 = up->fpsave.fpstatus; - up->fpsave = initfp; - up->fpsave.fpstatus = fpfcr31; - break; - } - if(up->fpstate == FPinactive) - break; - } - /* Fallthrough */ - - Default: - default: - if(user) { - spllo(); - sprint(buf, "sys: %s", excname[ecode]); - postnote(up, 1, buf, NDebug); - break; - } - print("kernel %s pc=%lux\n", excname[ecode], ur->pc); - dumpregs(ur); - dumpstack(); - if(m->machno == 0) - spllo(); - exit(1); - } - - if(fpchk) { - fpfcr31 = up->fpsave.fpstatus; - if((fpfcr31>>12) & ((fpfcr31>>7)|0x20) & 0x3f) { - spllo(); - fpexcep = fpexcname(ur, fpfcr31, buf1); - sprint(buf, "sys: fp: %s", fpexcep); - postnote(up, 1, buf, NDebug); - } - } - - splhi(); - if(!user) - return; - - notify(ur); - if(up->fpstate == FPinactive) { - restfpregs(&up->fpsave, up->fpsave.fpstatus&~FPEXPMASK); - up->fpstate = FPactive; - ur->status |= CU1; - } -} - -void -seteisadma(int ch, void (*func)(void)) -{ - if(ch < 0 || ch > 7) - panic("seteisadma"); - if(eisadma[ch] != 0) - print("EISA dma%d: intr used twice", ch); - - eisadma[ch] = func; -} - -void -eisadmaintr(void) -{ - int i; - uchar isr; - void (*f)(void); - - isr = EISAINB(Eisadmaintr) & ~(1<<4); - for(i = 0; i < 8; i++) { - if(isr & 1) { - f = eisadma[i]; - if(f == 0) - print("EISAdma%d: stray intr %.2ux\n", i, isr); - else - f(); - } - isr >>= 1; - } -} - -void -intr(Ureg *ur) -{ - static uchar devint; - ulong cause = ur->cause; - ulong isr; - - m->intr++; - cause &= INTR7|INTR6|INTR5|INTR4|INTR3|INTR2|INTR1|INTR0; - if(cause & INTR3) { - devint = IO(uchar, Intcause); - switch(devint) { - default: - panic("unknown devint=#%lux", devint); - case 0x28: /* Serial 1 */ - ns16552intr(0); - break; - case 0x24: /* Serial 2 */ - ns16552intr(1); - break; -/* - case 0x10: - fiberint(0); - break; - */ - case 0x14: - etherintr(); - break; - case 0x1C: - kbdintr(); - break; - case 0x20: - mouseintr(); - break; - } - cause &= ~INTR3; - } - - if(cause & INTR2) { - isr = IO(ulong, R4030Isr); - if(isr) { - print("R4030 Interrupt PC %lux R31 %lux\n", ur->pc, ur->r31); - print(" ISR #%lux\n", IO(ulong, R4030Isr)); - print(" ET #%lux\n", IO(ulong, R4030Et)); - print(" RFA #%lux\n", IO(ulong, R4030Rfa)); - print(" MFA #%lux\n", IO(ulong, R4030Mfa)); - } - cause &= ~INTR2; - } - - if(cause & INTR5) - panic("EISA NMI\n"); - - - if(cause & INTR4) { - devint = IO(uchar, I386ack); - switch(devint) { - default: - print("i386ACK #%ux\n", devint); - break; - case 7: - audiosbintr(); - break; - case 13: - eisadmaintr(); - break; - } - EISAOUTB(Int0ctl, EOI); - if(devint > 7) - EISAOUTB(Int1ctl, EOI); - cause &= ~INTR4; - } - - if(cause & INTR7) { - clock(ur); - return; - } - - if(cause) { - print("cause %lux\n", cause); - exit(1); - } - - /* preemptive scheduling */ - if(up && up->state == Running && anyhigher()) - sched(); -} - -char* -fpexcname(Ureg *ur, ulong fcr31, char *buf) -{ - int i; - char *s; - ulong fppc; - - fppc = ur->pc; - if(ur->cause & (1<<31)) /* branch delay */ - fppc += 4; - s = 0; - if(fcr31 & (1<<17)) - s = "unimplemented operation"; - else{ - fcr31 >>= 7; /* trap enable bits */ - fcr31 &= (fcr31>>5); /* anded with exceptions */ - for(i=0; i<5; i++) - if(fcr31 & (1<badvaddr); - print("UP=0x%lux SR=0x%lux PC=0x%lux R31=%lux SP=0x%lux\n", - up, ur->status, ur->pc, ur->r31, ur->sp); - - dumpregs(ur); - panic("kfault"); -} - -static void -getpcsp(ulong *pc, ulong *sp) -{ - *pc = getcallerpc(&pc); - *sp = (ulong)&pc-4; -} - -void -callwithureg(void (*fn)(Ureg*)) -{ - Ureg ureg; - - getpcsp((ulong*)&ureg.pc, (ulong*)&ureg.sp); - ureg.r31 = getcallerpc(&fn); - fn(&ureg); -} - -static void -_dumpstack(Ureg *ureg) -{ - ulong l, v, top, i; - extern ulong etext; - - if(up == 0) - return; - - print("ktrace /kernel/path %.8lux %.8lux %.8lux\n", ureg->pc, ureg->sp, ureg->r31); - top = (ulong)up->kstack + KSTACK; - i = 0; - for(l=ureg->sp; l < top; l += BY2WD) { - v = *(ulong*)l; - if(KTZERO < v && v < (ulong)&etext) { - print("%.8lux=%.8lux ", l, v); - if((++i%4) == 0){ - print("\n"); - delay(200); - } - } - } - print("\n"); -} - -void -dumpstack(void) -{ - callwithureg(_dumpstack); -} - -ulong -R(Ureg *ur, int i) -{ - uchar *s; - - s = (uchar*)ur; - return *(ulong*)(s+regname[i].off-Uoffset); -} - -void -dumpregs(Ureg *ur) -{ - int i; - - if(up) - print("registers for %s %ld\n", up->text, up->pid); - else - print("registers for kernel\n"); - - for(i=0; iprocctl) - procctl(up); - if(up->nnote == 0) - return 0; - - spllo(); - 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" */ - l = ERRLEN-15; - - sprint(n->msg+l, " pc=0x%lux", ur->pc); - } - - if(n->flag != NUser && (up->notified || up->notify==0)) { - if(n->flag == NDebug) - pprint("suicide: %s\n", n->msg); - qunlock(&up->debug); - pexit(n->msg, n->flag!=NDebug); - } - - if(up->notified) { - qunlock(&up->debug); - splhi(); - return 0; - } - - if(!up->notify) { - qunlock(&up->debug); - pexit(n->msg, n->flag!=NDebug); - } - sp = ur->usp & ~(BY2V-1); - sp -= sizeof(Ureg); - - if(!okaddr((ulong)up->notify, BY2WD, 0) || - !okaddr(sp-ERRLEN-4*BY2WD, sizeof(Ureg)+ERRLEN+4*BY2WD, 1)) { - pprint("suicide: bad address or sp in notify\n"); - qunlock(&up->debug); - pexit("Suicide", 0); - } - - memmove((Ureg*)sp, ur, sizeof(Ureg)); - *(Ureg**)(sp-BY2WD) = up->ureg; /* word under Ureg is old up->ureg */ - up->ureg = (void*)sp; - sp -= BY2WD+ERRLEN; - memmove((char*)sp, up->note[0].msg, ERRLEN); - sp -= 3*BY2WD; - *(ulong*)(sp+2*BY2WD) = sp+3*BY2WD; /* arg 2 is string */ - ur->r1 = (long)up->ureg; /* arg 1 is ureg* */ - ur->hr1 = 0; - if(ur->r1 < 0) - ur->hr1 = ~0; - ((ulong*)sp)[1] = (ulong)up->ureg; /* arg 1 0(FP) is ureg* */ - ((ulong*)sp)[0] = 0; /* arg 0 is pc */ - ur->usp = sp; - 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(&up->debug); - splhi(); - return 1; -} - -/* - * Check that status is OK to return from note. - */ -int -validstatus(ulong kstatus, ulong ustatus) -{ - if((kstatus & (INTMASK|KX|SX|UX)) != (ustatus & (INTMASK|KX|SX|UX))) - return 0; - if((ustatus&(KSU|ERL|EXL|IE)) != (KUSER|EXL|IE)) - return 0; - if(ustatus & (0xFFFF0000&~CU1)) /* no CU3, CU2, CU0, RP, FR, RE, DS */ - return 0; - return 1; -} - -/* - * Return user to state before notify() - */ -void -noted(Ureg *kur, Ureg **urp, ulong arg0) -{ - Ureg *nur; - ulong oureg, sp; - - qlock(&up->debug); - if(arg0!=NRSTR && !up->notified) { - qunlock(&up->debug); - pprint("call to noted() when not notified\n"); - pexit("Suicide", 0); - } - up->notified = 0; - - nur = up->ureg; - - oureg = (ulong)nur; - if((oureg & (BY2V-1)) - || !okaddr((ulong)oureg-BY2WD, BY2WD+sizeof(Ureg), 0)){ - pprint("bad ureg in noted or call to noted() when not notified\n"); - qunlock(&up->debug); - pexit("Suicide", 0); - } - - if(!validstatus(kur->status, nur->status)) { - qunlock(&up->debug); - pprint("bad noted ureg status %lux\n", nur->status); - pexit("Suicide", 0); - } - - memmove(*urp, up->ureg, sizeof(Ureg)); - switch(arg0) { - case NCONT: - case NRSTR: - if(!okaddr(nur->pc, BY2WD, 0) || !okaddr(nur->usp, BY2WD, 0)){ - pprint("suicide: trap in noted\n"); - qunlock(&up->debug); - pexit("Suicide", 0); - } - up->ureg = (Ureg*)(*(ulong*)(oureg-BY2WD)); - qunlock(&up->debug); - splhi(); - rfnote(urp); - break; - - case NSAVE: - if(!okaddr(nur->pc, BY2WD, 0) || !okaddr(nur->usp, BY2WD, 0)){ - pprint("suicide: trap in noted\n"); - qunlock(&up->debug); - pexit("Suicide", 0); - } - qunlock(&up->debug); - sp = oureg-4*BY2WD-ERRLEN; - splhi(); - (*urp)->sp = sp; - ((ulong*)sp)[1] = oureg; /* arg 1 0(FP) is ureg* */ - ((ulong*)sp)[0] = 0; /* arg 0 is pc */ - (*urp)->r1 = oureg; /* arg 1 is ureg* */ - (*urp)->hr1 = 0; - if(oureg < 0) - (*urp)->hr1 = ~0; - rfnote(urp); - break; - - default: - pprint("unknown noted arg 0x%lux\n", arg0); - up->lastnote.flag = NDebug; - /* fall through */ - - case NDFLT: - if(up->lastnote.flag == NDebug) - pprint("suicide: %s\n", up->lastnote.msg); - qunlock(&up->debug); - pexit(up->lastnote.msg, up->lastnote.flag!=NDebug); - } -} - -#include "../port/systab.h" - -long -syscall(Ureg *aur) -{ - long ret; - ulong sp; - Ureg *ur; - - m->syscall++; - up->insyscall = 1; - ur = aur; - up->pc = ur->pc; - up->dbgreg = aur; - ur->cause = 16<<2; /* for debugging: system call is undef 16 */ - - if(up->fpstate == FPactive) { - if((ur->status&CU1) == 0) - panic("syscall: FPactive but no CU1"); - up->fpsave.fpstatus = fcr31(); - up->fpstate = FPinit; - ur->status &= ~CU1; - } - spllo(); - - if(up->procctl) - procctl(up); - - up->scallnr = ur->r1; - up->nerrlab = 0; - sp = ur->sp; - ret = -1; - if(waserror()) - goto error; - - if(up->scallnr >= nsyscall){ - pprint("bad sys call %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(up, 1, "sys: odd stack", NDebug); - error(Ebadarg); - } - - if(sp<(USTKTOP-BY2PG) || sp>(USTKTOP-sizeof(Sargs))) - validaddr(sp, sizeof(Sargs), 0); - - up->s = *((Sargs*)(sp+BY2WD)); - up->psstate = sysctab[up->scallnr]; - - ret = systab[up->scallnr](up->s.args); - poperror(); - -error: - ur->pc += 4; - up->nerrlab = 0; - up->psstate = 0; - up->insyscall = 0; - if(up->scallnr == NOTED) /* ugly hack */ - noted(ur, &aur, *(ulong*)(sp+BY2WD)); /* doesn't return */ - - splhi(); - if(up->scallnr!=RFORK && (up->procctl || up->nnote)){ - ur->r1 = ret; /* load up for noted() */ - ur->hr1 = 0; - if(ur->r1 < 0) - ur->hr1 = ~0; - if(notify(ur)) - return ur->r1; - } - return ret; -} - -void -forkchild(Proc *p, Ureg *ur) -{ - Ureg *cur; - - p->sched.sp = (ulong)p->kstack+KSTACK-UREGSIZE; - 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; - - 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) -{ - Ureg *ur; - - ur = (Ureg*)up->dbgreg; - return ur->pc; -} - -/* 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) -{ - ulong status; - - status = xp->status; - memmove(pureg, uva, n); - xp->status = status; -} - -/* Give enough context in the ureg to produce a kernel stack for - * a sleeping process - */ -void -setkernur(Ureg *xp, Proc *p) -{ - xp->pc = p->sched.pc; - xp->sp = p->sched.sp; - xp->r31 = (ulong)sched; -} - -ulong -dbgpc(Proc *p) -{ - Ureg *ur; - - ur = p->dbgreg; - if(ur == 0) - return 0; - - return ur->pc; -} diff --git a/carrera/ureg.h b/carrera/ureg.h deleted file mode 100644 index d5eb04c0d3a6cb748d498d427846cd8c23aa79c8..0000000000000000000000000000000000000000 --- a/carrera/ureg.h +++ /dev/null @@ -1 +0,0 @@ -#include "/mips/include/mips2ureg.h" diff --git a/ip/chandial.c b/ip/chandial.c index f14c1c7e4ab1245c2a5f76edb3b48ce53ce50508..cb115025b9a193bada6548fa1ea36c7ba575f79c 100644 --- a/ip/chandial.c +++ b/ip/chandial.c @@ -4,6 +4,7 @@ #include "dat.h" #include "fns.h" #include "../port/error.h" +#include "../ip/ip.h" typedef struct DS DS; static Chan* call(char*, char*, DS*); @@ -12,7 +13,6 @@ static void _dial_string_parse(char*, DS*); enum { Maxstring= 128, - Maxpath= 256, }; struct DS @@ -53,7 +53,7 @@ call(char *clone, char *dest, DS *ds) { int n; Chan *dchan, *cchan; - char name[3*NAMELEN+5], data[3*NAMELEN+10], *p; + char name[Maxpath], data[Maxpath], *p; cchan = namec(clone, Aopen, ORDWR, 0); @@ -70,7 +70,7 @@ call(char *clone, char *dest, DS *ds) p = strrchr(clone, '/'); *p = 0; if(ds->dir) - snprint(ds->dir, 2*NAMELEN, "%s/%s", clone, name); + snprint(ds->dir, Maxpath, "%s/%s", clone, name); snprint(data, sizeof(data), "%s/%s/data", clone, name); /* connect */ diff --git a/ip/devip.c b/ip/devip.c index 48d4843a238844011136b8188c12a32ddda7dba6..8c57776b4669eb9d21865132cdcff5abab8897cc 100644 --- a/ip/devip.c +++ b/ip/devip.c @@ -43,9 +43,9 @@ enum Nfs= 16, }; -#define TYPE(x) ( (x).path & Masktype ) -#define CONV(x) ( ((x).path >> Shiftconv) & Maskconv ) -#define PROTO(x) ( ((x).path >> Shiftproto) & Maskproto ) +#define TYPE(x) ( ((ulong)(x).path) & Masktype ) +#define CONV(x) ( (((ulong)(x).path) >> Shiftconv) & Maskconv ) +#define PROTO(x) ( (((ulong)(x).path) >> Shiftproto) & Maskproto ) #define QID(p, c, y) ( ((p)<<(Shiftproto)) | ((c)<dev]->p[PROTO(c->qid)]->conv[CONV(c->qid)]; - if(cv->owner[0] == 0) - memmove(cv->owner, eve, NAMELEN); + if(cv->owner == nil) + kstrdup(&cv->owner, eve); + mkqid(&q, QID(PROTO(c->qid), CONV(c->qid), i), 0, QTFILE); + switch(i) { default: return -1; case Qctl: - q = (Qid){QID(PROTO(c->qid), CONV(c->qid), Qctl), 0}; devdir(c, q, "ctl", 0, cv->owner, cv->perm, dp); return 1; case Qdata: - q = (Qid){QID(PROTO(c->qid), CONV(c->qid), Qdata), 0}; devdir(c, q, "data", qlen(cv->rq), cv->owner, cv->perm, dp); return 1; case Qerr: - q = (Qid){QID(PROTO(c->qid), CONV(c->qid), Qerr), 0}; devdir(c, q, "err", qlen(cv->eq), cv->owner, cv->perm, dp); return 1; case Qlisten: - q = (Qid){QID(PROTO(c->qid), CONV(c->qid), Qlisten), 0}; devdir(c, q, "listen", qlen(cv->eq), cv->owner, cv->perm, dp); return 1; case Qlocal: p = "local"; - q = (Qid){QID(PROTO(c->qid), CONV(c->qid), Qlocal), 0}; break; case Qremote: p = "remote"; - q = (Qid){QID(PROTO(c->qid), CONV(c->qid), Qremote), 0}; break; case Qstatus: p = "status"; - q = (Qid){QID(PROTO(c->qid), CONV(c->qid), Qstatus), 0}; break; } devdir(c, q, p, 0, cv->owner, 0444, dp); @@ -111,11 +106,11 @@ ip2gen(Chan *c, int i, Dir *dp) switch(i) { case Qclone: - q = (Qid){QID(PROTO(c->qid), 0, Qclone), 0}; + mkqid(&q, QID(PROTO(c->qid), 0, Qclone), 0, QTFILE); devdir(c, q, "clone", 0, network, 0666, dp); return 1; case Qstats: - q = (Qid){QID(PROTO(c->qid), 0, Qstats), 0}; + mkqid(&q, QID(PROTO(c->qid), 0, Qstats), 0, QTFILE); devdir(c, q, "stats", 0, network, 0444, dp); return 1; } @@ -134,34 +129,29 @@ ip1gen(Chan *c, int i, Dir *dp) f = ipfs[c->dev]; prot = 0666; + mkqid(&q, QID(0, 0, i), 0, QTFILE); switch(i) { default: return -1; case Qarp: p = "arp"; - q = (Qid){QID(0, 0, Qarp), 0}; break; case Qbootp: p = "bootp"; - q = (Qid){QID(0, 0, Qbootp), 0}; break; case Qndb: p = "ndb"; - q = (Qid){QID(0, 0, Qndb), 0}; len = strlen(f->ndb); break; case Qiproute: p = "iproute"; - q = (Qid){QID(0, 0, Qiproute), 0}; break; case Qipselftab: p = "ipselftab"; prot = 0444; - q = (Qid){QID(0, 0, Qipselftab), 0}; break; case Qlog: p = "log"; - q = (Qid){QID(0, 0, Qlog), 0}; break; } devdir(c, q, p, len, network, prot, dp); @@ -169,11 +159,10 @@ ip1gen(Chan *c, int i, Dir *dp) } static int -ipgen(Chan *c, Dirtab*, int, int s, Dir *dp) +ipgen(Chan *c, char*, Dirtab*, int, int s, Dir *dp) { Qid q; Conv *cv; - char name[16]; Fs *f; f = ipfs[c->dev]; @@ -181,15 +170,15 @@ ipgen(Chan *c, Dirtab*, int, int s, Dir *dp) switch(TYPE(c->qid)) { case Qtopdir: if(s == DEVDOTDOT){ - q = (Qid){QID(0, 0, Qtopdir)|CHDIR, 0}; - sprint(name, "#I%lud", c->dev); - devdir(c, q, name, 0, network, 0555, dp); + mkqid(&q, QID(0, 0, Qtopdir), 0, QTDIR); + sprint(up->genbuf, "#I%lud", c->dev); + devdir(c, q, up->genbuf, 0, network, 0555, dp); return 1; } if(s < f->np) { if(f->p[s]->connect == nil) return 0; /* protocol with no user interface */ - q = (Qid){QID(s, 0, Qprotodir)|CHDIR, 0}; + mkqid(&q, QID(s, 0, Qprotodir), 0, QTDIR); devdir(c, q, f->p[s]->name, 0, network, 0555, dp); return 1; } @@ -204,16 +193,16 @@ ipgen(Chan *c, Dirtab*, int, int s, Dir *dp) return ip1gen(c, TYPE(c->qid), dp); case Qprotodir: if(s == DEVDOTDOT){ - q = (Qid){QID(0, 0, Qtopdir)|CHDIR, 0}; - sprint(name, "#I%lud", c->dev); - devdir(c, q, name, 0, network, 0555, dp); + mkqid(&q, QID(0, 0, Qtopdir), 0, QTDIR); + sprint(up->genbuf, "#I%lud", c->dev); + devdir(c, q, up->genbuf, 0, network, 0555, dp); return 1; } if(s < f->p[PROTO(c->qid)]->ac) { cv = f->p[PROTO(c->qid)]->conv[s]; - sprint(name, "%d", s); - q = (Qid){QID(PROTO(c->qid), s, Qconvdir)|CHDIR, 0}; - devdir(c, q, name, 0, cv->owner, 0555, dp); + sprint(up->genbuf, "%d", s); + mkqid(&q, QID(PROTO(c->qid), s, Qconvdir), 0, QTDIR); + devdir(c, q, up->genbuf, 0, cv->owner, 0555, dp); return 1; } s -= f->p[PROTO(c->qid)]->ac; @@ -224,7 +213,7 @@ ipgen(Chan *c, Dirtab*, int, int s, Dir *dp) case Qconvdir: if(s == DEVDOTDOT){ s = PROTO(c->qid); - q = (Qid){QID(s, 0, Qprotodir)|CHDIR, 0}; + mkqid(&q, QID(s, 0, Qprotodir), 0, QTDIR); devdir(c, q, f->p[s]->name, 0, network, 0555, dp); return 1; } @@ -291,7 +280,7 @@ newipaux(char *owner, char *tag) int n; a = smalloc(sizeof(*a)); - memmove(a->owner, owner, NAMELEN); + kstrdup(&a->owner, owner); memset(a->tag, ' ', sizeof(a->tag)); n = strlen(tag); if(n > sizeof(a->tag)) @@ -314,7 +303,7 @@ ipattach(char* spec) ipgetfs(dev); c = devattach('I', spec); - c->qid = (Qid){QID(0, 0, Qtopdir)|CHDIR, 0}; + mkqid(&c->qid, QID(0, 0, Qtopdir), 0, QTDIR); c->dev = dev; c->aux = newipaux(commonuser(), "none"); @@ -322,26 +311,22 @@ ipattach(char* spec) return c; } -static Chan* -ipclone(Chan* c, Chan* nc) +static Walkqid* +ipwalk(Chan* c, Chan *nc, char **name, int nname) { IPaux *a = c->aux; + Walkqid* w; - nc = devclone(c, nc); - nc->aux = newipaux(a->owner, a->tag); - return nc; + w = devwalk(c, nc, name, nname, nil, 0, ipgen); + if(w != nil && w->clone != nil) + w->clone->aux = newipaux(a->owner, a->tag); + return w; } static int -ipwalk(Chan* c, char* name) -{ - return devwalk(c, name, nil, 0, ipgen); -} - -static void -ipstat(Chan* c, char* db) +ipstat(Chan* c, uchar* db, int n) { - devstat(c, db, nil, 0, ipgen); + return devstat(c, db, n, nil, 0, ipgen); } static int @@ -367,7 +352,8 @@ ipopen(Chan* c, int omode) int perm; Fs *f; - perm = m2p[omode&3]; + omode &= 3; + perm = m2p[omode]; f = ipfs[c->dev]; @@ -411,7 +397,7 @@ ipopen(Chan* c, int omode) error(Enodev); break; } - c->qid = (Qid){QID(p->x, cv->x, Qctl), 0}; + mkqid(&c->qid, QID(p->x, cv->x, Qctl), 0, QTFILE); break; case Qdata: case Qctl: @@ -434,7 +420,7 @@ ipopen(Chan* c, int omode) } cv->inuse++; if(cv->inuse == 1){ - memmove(cv->owner, ATTACHER(c), NAMELEN); + kstrdup(&cv->owner, ATTACHER(c)); cv->perm = 0660; } qunlock(cv); @@ -473,8 +459,8 @@ ipopen(Chan* c, int omode) nc = cv->incall; if(nc != nil){ cv->incall = nc->next; - c->qid = (Qid){QID(PROTO(c->qid), nc->x, Qctl), 0}; - memmove(nc->owner, ATTACHER(c), NAMELEN); + mkqid(&c->qid, QID(PROTO(c->qid), nc->x, Qctl), 0, QTFILE); + kstrdup(&cv->owner, ATTACHER(c)); } qunlock(cv); @@ -501,8 +487,8 @@ ipremove(Chan*) error(Eperm); } -static void -ipwstat(Chan *c, char *dp) +static int +ipwstat(Chan *c, uchar *dp, int n) { Dir d; Conv *cv; @@ -519,17 +505,17 @@ ipwstat(Chan *c, char *dp) break; } - convM2D(dp, &d); - - p = f->p[PROTO(c->qid)]; - cv = p->conv[CONV(c->qid)]; - if(!iseve() && strcmp(ATTACHER(c), cv->owner) != 0) - error(Eperm); - if(d.uid[0]){ - strncpy(cv->owner, d.uid, sizeof(cv->owner)); - cv->owner[sizeof(cv->owner)-1] = 0; + n = convM2D(dp, n, &d, nil); + if(n > 0){ + p = f->p[PROTO(c->qid)]; + cv = p->conv[CONV(c->qid)]; + if(!iseve() && strcmp(ATTACHER(c), cv->owner) != 0) + error(Eperm); + if(d.uid[0]) + kstrdup(&cv->owner, d.uid); + cv->perm = d.mode & 0777; } - cv->perm = d.mode & 0777; + return n; } void @@ -552,7 +538,7 @@ closeconv(Conv *cv) } cv->incall = nil; - strcpy(cv->owner, network); + kstrdup(&cv->owner, network); cv->perm = 0660; while((mp = cv->multi) != nil) @@ -582,6 +568,7 @@ ipclose(Chan* c) if(c->flag & COPEN) closeconv(f->p[PROTO(c->qid)]->conv[CONV(c->qid)]); } + free(((IPaux*)c->aux)->owner); free(c->aux); } @@ -738,7 +725,6 @@ setluniqueport(Conv* c, int lport) return nil; } - /* * pick a local port and set it */ @@ -1153,7 +1139,6 @@ Dev ipdevtab = { ipreset, ipinit, ipattach, - ipclone, ipwalk, ipstat, ipopen, @@ -1181,7 +1166,8 @@ Fsproto(Fs *f, Proto *p) f->t2p[p->ipproto] = p; } - p->qid.path = CHDIR|QID(f->np, 0, Qprotodir); + p->qid.type = QTDIR; + p->qid.path = QID(f->np, 0, Qprotodir); p->conv = malloc(sizeof(Conv*)*(p->nc+1)); if(p->conv == nil) panic("Fsproto"); @@ -1255,7 +1241,7 @@ retry: } c->inuse = 1; - strcpy(c->owner, user); + kstrdup(&c->owner, user); c->perm = 0660; c->state = Idle; ipmove(c->laddr, IPnoaddr); @@ -1276,7 +1262,7 @@ int Fsconnected(Conv* c, char* msg) { if(msg != nil && *msg != '\0') - strncpy(c->cerr, msg, ERRLEN-1); + strncpy(c->cerr, msg, ERRMAX-1); switch(c->state){ diff --git a/ip/ethermedium.c b/ip/ethermedium.c index 96ba2fe367f12c04461c35bd71619e2b343066d4..3ca1c164f0287f2c87e8289aeef02269649dbd9b 100644 --- a/ip/ethermedium.c +++ b/ip/ethermedium.c @@ -106,8 +106,8 @@ static void etherbind(Ipifc *ifc, int argc, char **argv) { Chan *mchan, *cchan, *achan; - char addr[2*NAMELEN]; - char dir[2*NAMELEN]; + char addr[Maxpath]; + char dir[Maxpath]; char *buf; int n; char *ptr; diff --git a/ip/il.c b/ip/il.c index 027cddc07d730db11776da74db621c9096e84ac2..a5283336b3e1e27bb0f3fbc65243a4e061d578d2 100644 --- a/ip/il.c +++ b/ip/il.c @@ -1218,7 +1218,7 @@ ilstart(Conv *c, int type, int fasttimeout) { Ilcb *ic; Ilpriv *ipriv; - char kpname[NAMELEN]; + char kpname[KNAMELEN]; ipriv = c->p->priv; diff --git a/ip/ip.h b/ip/ip.h index 32373503a75a8b26a8609a7122d91fe052ceaa8c..d4d13bbc575fb724d042906bf5fa7fe31f46cc14 100644 --- a/ip/ip.h +++ b/ip/ip.h @@ -47,6 +47,8 @@ enum /* 2^Lroot trees in the root table */ Lroot = 10, + + Maxpath = 64, }; enum @@ -76,7 +78,7 @@ struct Conv uint ttl; /* max time to live */ uint tos; /* type of service */ - char owner[NAMELEN]; /* protections */ + char *owner ; /* protections */ int perm; int inuse; /* opens of listen/data/ctl */ int length; @@ -95,7 +97,7 @@ struct Conv QLock car; Rendez cr; - char cerr[ERRLEN]; + char cerr[ERRMAX]; QLock listenq; Rendez listenr; @@ -428,7 +430,7 @@ extern void convroute(Route*, uchar*, uchar*, uchar*, char*, int*); */ struct IPaux { - char owner[NAMELEN]; /* the user that did the attach */ + char *owner; /* the user that did the attach */ char tag[4]; }; diff --git a/ip/tcp.c b/ip/tcp.c index 50f78530f8d3e7d3aecb4e36d9f3f9b85f60e8c2..70f51eecbc8c78ad671a3921338dd935d431ae2a 100644 --- a/ip/tcp.c +++ b/ip/tcp.c @@ -700,7 +700,7 @@ tcpstart(Conv *s, int mode, ushort window) { Tcpctl *tcb; Tcppriv *tpriv; - char kpname[NAMELEN]; + char kpname[KNAMELEN]; tpriv = s->p->priv; diff --git a/mpc/_inb.s b/mpc/_inb.s deleted file mode 100644 index 3a13b76dd8977ee13be54c00dc1baea3e6a816e3..0000000000000000000000000000000000000000 --- a/mpc/_inb.s +++ /dev/null @@ -1,110 +0,0 @@ -#include "mem.h" - -#define BDNZ BC 16,0, -#define BDNE BC 0,2, - -TEXT inb(SB), $0 - OR $ISAMEM, R3 - MOVBZ (R3), R3 - RETURN - -TEXT insb(SB), $0 - MOVW v+4(FP), R4 - MOVW n+8(FP), R5 - MOVW R5, CTR - OR $ISAMEM, R3 - SUB $1, R4 -insb1: - MOVBZ (R3), R7 - MOVBU R7, 1(R4) - BDNZ insb1 - RETURN - -TEXT outb(SB), $0 - MOVW v+4(FP), R4 - OR $ISAMEM, R3 - MOVB R4, (R3) - RETURN - -TEXT outsb(SB), $0 - MOVW v+4(FP), R4 - MOVW n+8(FP), R5 - MOVW R5, CTR - OR $ISAMEM, R3 - SUB $1, R4 -outsb1: - MOVBZU 1(R4), R7 - MOVB R7, (R3) - BDNZ outsb1 - RETURN - -TEXT ins(SB), $0 - OR $ISAMEM, R3 - EIEIO - MOVHBR (R3), R3 - RETURN - -TEXT inss(SB), $0 - MOVW v+4(FP), R4 - MOVW n+8(FP), R5 - MOVW R5, CTR - OR $ISAMEM, R3 - SUB $2, R4 -inss1: - MOVHZ (R3), R7 - MOVHU R7, 2(R4) - BDNZ inss1 - RETURN - -TEXT outs(SB), $0 - MOVW v+4(FP), R4 - OR $ISAMEM, R3 - MOVHBR R4, (R3) - RETURN - -TEXT outss(SB), $0 - MOVW v+4(FP), R4 - MOVW n+8(FP), R5 - MOVW R5, CTR - OR $ISAMEM, R3 - SUB $2, R4 -outss1: - MOVHZU 2(R4), R7 - MOVH R7, (R3) - BDNZ outss1 - RETURN - -TEXT inl(SB), $0 - OR $ISAMEM, R3 - MOVWBR (R3), R3 - RETURN - -TEXT insl(SB), $0 - MOVW v+4(FP), R4 - MOVW n+8(FP), R5 - MOVW R5, CTR - OR $ISAMEM, R3 - SUB $4, R4 -insl1: - MOVW (R3), R7 - MOVWU R7, 4(R4) - BDNZ insl1 - RETURN - -TEXT outl(SB), $0 - MOVW v+4(FP), R4 - OR $ISAMEM, R3 - MOVWBR R4, (R3) - RETURN - -TEXT outsl(SB), $0 - MOVW v+4(FP), R4 - MOVW n+8(FP), R5 - MOVW R5, CTR - OR $ISAMEM, R3 - SUB $4, R4 -outsl1: - MOVWU 4(R4), R7 - MOVW R7, (R3) - BDNZ outsl1 - RETURN diff --git a/mpc/clock.c b/mpc/clock.c deleted file mode 100644 index 32c8aedc57ed48f9831c4db603a847848963304f..0000000000000000000000000000000000000000 --- a/mpc/clock.c +++ /dev/null @@ -1,212 +0,0 @@ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "io.h" -#include "ureg.h" - -typedef struct Clock0link Clock0link; -typedef struct Clock0link { - void (*clock)(void); - Clock0link* link; -} Clock0link; - -static Clock0link *clock0link; -static Lock clock0lock; -ulong clkrelinq; -void (*kproftick)(ulong); /* set by devkprof.c when active */ -long clkvv; -ulong clkhigh; - -void -addclock0link(void (*clock)(void)) -{ - Clock0link *lp; - - if((lp = malloc(sizeof(Clock0link))) == 0){ - print("addclock0link: too many links\n"); - return; - } - ilock(&clock0lock); - lp->clock = clock; - lp->link = clock0link; - clock0link = lp; - iunlock(&clock0lock); -} - -void -delay(int l) -{ - ulong i, j; - - j = m->delayloop; - while(l-- > 0) - for(i=0; i < j; i++) - ; -} - -void -microdelay(int l) -{ - ulong i; - - l *= m->delayloop; - l += 500; - l /= 1000; - if(l <= 0) - l = 1; - for(i = 0; i < l; i++) - ; -} - -// the following can be 4 or 16 depending on the clock multiplier -// see 15.3.3 in 860 manual -enum { - Timebase = 16, /* system clock cycles per time base cycle */ -}; - -static ulong clkreload; - -#ifdef XXX -ulong -millisec(void) -{ - ulong tbu, tbl, x; - vlong t; - - do { - tbu = gettbu(); - tbl = gettbl(); - } while (gettbu() != tbu); - t = (((vlong)tbu)<<32) + tbl; - - t <<= 4; - t /= m->oscclk * 1000; - - x = t; - if((long)(ledtime-x) < 0) - powerdownled(); - - return (ulong)t; -} - -#endif -ulong -millisec(void) -{ - ulong tbl, x; - - tbl = gettbl(); - x = tbl/((m->oscclk * 1000)/16); - - return x; -} - -void -delayloopinit(void) -{ - long x, est; - - est = m->cpuhz/1000; /* initial estimate */ - m->delayloop = est; - do { - x = gettbl(); - delay(1); - x = gettbl() - x; - } while(x < 0); - - /* - * fix count - */ - m->delayloop = (m->delayloop*est/Timebase)/(x); - if(m->delayloop == 0) - m->delayloop = 1; -} - -void -clockinit(void) -{ - delayloopinit(); - - clkreload = (m->clockgen/Timebase)/HZ-1; - putdec(clkreload); -} - -void -clockintr(Ureg *ur) -{ - Clock0link *lp; - long v; - - v = (clkvv = -getdec()); - if(v > clkreload) - clkhigh++; - if(v > clkreload/2){ - if(v > clkreload) - m->ticks += v/clkreload; - v = 0; - } - putdec(clkreload-v); - - // keep alive for watchdog - m->iomem->swsr = 0x556c; - m->iomem->swsr = 0xaa39; - - m->ticks++; - - if((m->iomem->pddat & SIBIT(15)) == 0) { - print("button pressed\n"); - delay(200); - reset(); - } - - if(m->proc) - m->proc->pc = ur->pc; - - accounttime(); - if(kproftimer != nil) - kproftimer(ur->pc); - - - checkalarms(); - if(m->machno == 0) { - lock(&clock0lock); - for(lp = clock0link; lp; lp = lp->link) - lp->clock(); - unlock(&clock0lock); - } - - if(m->flushmmu){ - if(up) - flushmmu(); - m->flushmmu = 0; - } - - if(up == 0 || up->state != Running) - return; - -// user profiling clock -// if(ur->status & KUSER) { -// (*(ulong*)(USTKTOP-BY2WD)) += TK2MS(1); -// segclock(ur->pc); -// } - - if(anyready()) - sched(); -} - -void -clkprint(void) -{ - print("clkr=%ld clkvv=%ld clkhigh=%lud\n", clkreload, clkvv, clkhigh); - print("\n"); -} - -vlong -fastticks(uvlong *hz) -{ - if(hz) - *hz = HZ; - return m->ticks; -} diff --git a/mpc/cmmu.c b/mpc/cmmu.c deleted file mode 100644 index 38171bfe0d64268df48bf22c439a4e57f02cb22c..0000000000000000000000000000000000000000 --- a/mpc/cmmu.c +++ /dev/null @@ -1,391 +0,0 @@ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "io.h" -#include "ureg.h" - -/* - * tlb entry 0 is used only by mmuswitch() to set the current tlb pid. - */ - -/* - * Kmap entries start at tlb index 1 and work their way up until - * kmapinval() removes them. They then restart at 1. As long as there - * are few kmap entries they will not pass TLBROFF (the WIRED tlb entry - * limit) and interfere with user tlb entries. - */ - -/* - * All invalidations of the tlb are via indexed entries. The virtual - * address used is always 'KZERO | (x<<(PGSHIFT+1) | currentpid' where - * 'x' is the index into the tlb. This ensures that the current pid doesn't - * change and that no two invalidated entries have matching virtual - * addresses just in case SGI/MIPS ever makes a chip that cares (as - * they keep threatening). These entries should never be used in - * lookups since accesses to KZERO addresses don't go through the tlb. - */ - -#define TLBINVAL(x, pid) puttlbx(x, KZERO|((x)<<(PGSHIFT+1))|(pid), 0, 0, PGSZ4K) - -void -tlbinit(void) -{ - int i; - - for(i=0; inext = k+1; - k->next = 0; - - m->ktlbnext = TLBROFF; -} - -/* - * Arrange that the KMap'd virtual address will hit the same - * primary cache line as pg->va by making bits 14...12 of the - * tag the same as virtual address. These bits are the index - * into the primary cache and are checked whenever accessing - * the secondary cache through the primary. Violation causes - * a VCE trap. - */ -KMap * -kmap(Page *pg) -{ - int s; - KMap *k; - ulong pte; - ulong x, virt; - - s = splhi(); - lock(&kmaplock); - - if(kmapfree == 0) { - unlock(&kmaplock); - kmapinval(); /* try and free some */ - lock(&kmaplock); - if(kmapfree == 0) - panic("out of kmap"); - } - - k = kmapfree; - kmapfree = k->next; - - k->pg = pg; - /* One for the allocation, - * One for kactive - */ - k->ref = 2; - k->konmach[m->machno] = m->kactive; - m->kactive = k; - - virt = pg->va; - /* bits 14..12 form the secondary-cache virtual index */ - virt &= PIDX; - virt |= KMAPADDR | ((k-kpte)<virt = virt; - pte = PPN(pg->pa)|PTECOHERXCLW|PTEGLOBL|PTEWRITE|PTEVALID; - if(virt & BY2PG) { - k->phys0 = PTEGLOBL|PTECOHERXCLW; - k->phys1 = pte; - } - else { - k->phys0 = pte; - k->phys1 = PTEGLOBL|PTECOHERXCLW; - } - - x = m->ktlbnext; - k->tlbi[m->machno] = x; - puttlbx(x, (virt&~BY2PG)|TLBPID(tlbvirt()), k->phys0, k->phys1, PGSZ4K); - if(++x >= NTLB) - m->ktlbnext = TLBROFF; - else - m->ktlbnext = x; - - unlock(&kmaplock); - - splx(s); - return k; -} - -void -kunmap(KMap *k) -{ - int s; - - s = splhi(); - if(decref(k) == 0) { - k->virt = 0; - k->phys0 = 0; - k->phys1 = 0; - k->pg = 0; - - lock(&kmaplock); - k->next = kmapfree; - kmapfree = k; - unlock(&kmaplock); - } - splx(s); -} - -void -kfault(Ureg *ur) -{ - int mno; - KMap *k, *f; - ulong x, index, virt, addr; - - mno = m->machno; - addr = ur->badvaddr; - index = (addr & ~KMAPADDR) >> KMAPSHIFT; - - if(index >= KPTESIZE) - panic("kmapfault: %lux", addr); - - k = &kpte[index]; - if(k->virt == 0 || k->ref < 1) - panic("kmapfault: unmapped %lux", addr); - - for(f = m->kactive; f; f = f->konmach[mno]) - if(f == k) - break; - - if(f == 0) { - incref(k); - k->konmach[mno] = m->kactive; - m->kactive = k; - } - - x = m->ktlbnext; - virt = (k->virt&~BY2PG)|TLBPID(tlbvirt()); - puttlbx(x, virt, k->phys0, k->phys1, PGSZ4K); - k->tlbi[mno] = x; - - if(++x >= NTLB) - m->ktlbnext = TLBROFF; - else - m->ktlbnext = x; -} - -void -kmapinval() -{ - int mno, curpid; - KMap *k, *next; - - if(m->kactive == 0) - return; - - curpid = PTEPID(TLBPID(tlbvirt())); - mno = m->machno; - for(k = m->kactive; k; k = next) { - next = k->konmach[mno]; - TLBINVAL(k->tlbi[mno], curpid); - kunmap(k); - } - m->kactive = 0; -} - -void -mmuswitch(Proc *p) -{ - int tp; - - if(p->newtlb) { - memset(p->pidonmach, 0, sizeof p->pidonmach); - p->newtlb = 0; - } - tp = p->pidonmach[m->machno]; - if(tp == 0) - tp = newtlbpid(p); - - puttlbx(0, KZERO|PTEPID(tp), 0, 0, PGSZ4K); -} - -void -mmurelease(Proc *p) -{ - memset(p->pidonmach, 0, sizeof p->pidonmach); -} - -/* - * Process must be splhi - */ -int -newtlbpid(Proc *p) -{ - int i, s; - Proc **h; - - i = m->lastpid; - h = m->pidproc; - for(s = 0; s < NTLBPID; s++) { - i++; - if(i >= NTLBPID) - i = 1; - if(h[i] == 0) - break; - } - - if(h[i]) - purgetlb(i); - if(h[i] != 0) - panic("newtlb"); - - m->pidproc[i] = p; - p->pidonmach[m->machno] = i; - m->lastpid = i; - - return i; -} - -void -putmmu(ulong tlbvirt, ulong tlbphys, Page *pg) -{ - int s; - short tp; - char *ctl; - Softtlb *entry; - - s = splhi(); - tp = up->pidonmach[m->machno]; - if(tp == 0) - tp = newtlbpid(up); - - /* - * Fix up EISA memory address which are greater - * than 32 bits physical: 0x100000000 - */ - if((tlbphys&0xffff0000) == PPN(Eisamphys)) { - tlbphys &= ~PPN(Eisamphys); - tlbphys |= 0x04000000; - } - tlbvirt |= PTEPID(tp); - if((tlbphys & PTEALGMASK) != PTEUNCACHED) { - tlbphys &= ~PTEALGMASK; - tlbphys |= PTECOHERXCLW; - } - - entry = putstlb(tlbvirt, tlbphys); - puttlb(entry->virt, entry->phys0, entry->phys1); - - ctl = &pg->cachectl[m->machno]; - switch(*ctl) { - case PG_TXTFLUSH: - icflush((void*)pg->va, BY2PG); - *ctl = PG_NOFLUSH; - break; - case PG_DATFLUSH: - dcflush((void*)pg->va, BY2PG); - *ctl = PG_NOFLUSH; - break; - case PG_NEWCOL: - cleancache(); /* Too expensive */ - *ctl = PG_NOFLUSH; - break; - } - splx(s); -} - -void -purgetlb(int pid) -{ - int i, mno; - Proc *sp, **pidproc; - Softtlb *entry, *etab; - - m->tlbpurge++; - - /* - * find all pid entries that are no longer used by processes - */ - mno = m->machno; - pidproc = m->pidproc; - for(i=1; ipidonmach[mno] != i) - pidproc[i] = 0; - } - - /* - * shoot down the one we want - */ - sp = pidproc[pid]; - if(sp != 0) - sp->pidonmach[mno] = 0; - pidproc[pid] = 0; - - /* - * clean out all dead pids from the stlb; - */ - entry = m->stb; - for(etab = &entry[STLBSIZE]; entry < etab; entry++) - if(pidproc[TLBPID(entry->virt)] == 0) - entry->virt = 0; - - /* - * clean up the hardware - */ - for(i=TLBROFF; inewtlb = 1; - mmuswitch(up); - splx(s); -} - -void -clearmmucache(void) -{ -} - -Softtlb* -putstlb(ulong tlbvirt, ulong tlbphys) -{ - int k; - Softtlb *entry; - - k = tlbvirt & BY2PG; - tlbvirt &= ~BY2PG; - - entry = &m->stb[(tlbvirt ^ (tlbvirt>>13)) & (STLBSIZE-1)]; - if(entry->virt != tlbvirt) { - entry->virt = tlbvirt; - entry->phys0 = 0; - entry->phys1 = 0; - } - - if(k) - entry->phys1 = tlbphys; - else - entry->phys0 = tlbphys; - - if(entry->phys0 == 0 && entry->phys1 == 0) - entry->virt = 0; - - return entry; -} diff --git a/mpc/conf.c b/mpc/conf.c deleted file mode 100644 index 318913d83777bcb6b6417e5bc92cf52f99b5f57a..0000000000000000000000000000000000000000 --- a/mpc/conf.c +++ /dev/null @@ -1,74 +0,0 @@ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "io.h" -#include "init.h" - -char* -getconf(char *name) -{ - char **p; - int n; - - n = strlen(name); - - for(p = conf; *p; p++) { - if(strncmp(*p, name, n) == 0 && (*p)[n] == '=') - return *p+n+1; - } - return 0; -} - -int -isaconfig(char *class, int ctlrno, ISAConf *isa) -{ - char cc[NAMELEN], *p, *q, *r; - - strcpy(cc, class); - p = cc + strlen(cc); - *p++ = ctlrno + '0'; - *p = 0; - - p = getconf(cc); - if(p == 0) - return 0; - - while(*p){ - while(*p == ' ' || *p == '\t') - p++; - if(*p == '\0') - break; - if(strncmp(p, "type=", 5) == 0){ - p += 5; - for(q = isa->type; q < &isa->type[NAMELEN-1]; q++){ - if(*p == '\0' || *p == ' ' || *p == '\t') - break; - *q = *p++; - } - *q = '\0'; - } - else if(strncmp(p, "port=", 5) == 0) - isa->port = strtoul(p+5, &p, 0); - else if(strncmp(p, "irq=", 4) == 0) - isa->irq = strtoul(p+4, &p, 0); - else if(strncmp(p, "mem=", 4) == 0) - isa->mem = strtoul(p+4, &p, 0); - else if(strncmp(p, "size=", 5) == 0) - isa->size = strtoul(p+5, &p, 0); - else if(isa->nopt < NISAOPT){ - r = isa->opt[isa->nopt]; - while(*p && *p != ' ' && *p != '\t'){ - *r++ = *p++; - if(r-isa->opt[isa->nopt] >= ISAOPTLEN-1) - break; - } - *r = '\0'; - isa->nopt++; - } - while(*p && *p != ' ' && *p != '\t') - p++; - } - return 1; -} diff --git a/mpc/cpm.c b/mpc/cpm.c deleted file mode 100644 index b9a476225b500b6693f7bbfc9293e8d54cfb35fb..0000000000000000000000000000000000000000 --- a/mpc/cpm.c +++ /dev/null @@ -1,566 +0,0 @@ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "io.h" - -enum { - BDSIZE= 1024, /* IO memory reserved for buffer descriptors */ - CPMSIZE= 1024, /* IO memory reserved for other uses */ -}; - -static Map bdmapv[BDSIZE/sizeof(BD)]; -static RMap bdmap = {"buffer descriptors"}; - -static Map cpmmapv[CPMSIZE/sizeof(ulong)]; -static RMap cpmmap = {"CPM memory"}; - -static Lock cpmlock; - -static struct { - Lock; - ulong avail; -} brgens; - -static struct { - Lock; - ulong clash; /* disable bits for mutually-exclusive options */ - ulong active; /* disable bit for current owner, or 0 */ - void (*stop)(void*); - void* arg; -} scc2owner; - -static void i2cspireloc(void); - -/* - * initialise the communications processor module - * and associated device registers - */ -void -cpminit(void) -{ - IMM *io; - - io = m->iomem; - io->rccr = 0; - io->rmds = 0; -// io->lccr &= ~1; /* disable LCD */ - io->sdcr = 1; - io->pcint = 0; /* disable all port C interrupts */ - io->pcso = 0; - io->pcdir =0; - io->pcpar = 0; - io->papar = 0; - io->padir = 0; - io->pbpar = 0; - io->pbdir = 0; - io->tgcr = 0x2222; /* reset timers, low-power stop */ - eieio(); - - for(io->cpcr = 0x8001; io->cpcr & 1;) /* reset all CPM channels */ - eieio(); - - mapinit(&bdmap, bdmapv, sizeof(bdmapv)); - mapfree(&bdmap, DPBASE, BDSIZE); - mapinit(&cpmmap, cpmmapv, sizeof(cpmmapv)); - mapfree(&cpmmap, DPBASE+BDSIZE, CPMSIZE); - - if(m->cputype == 0x50 && (getimmr() & 0xFFFF) <= 0x2001) - brgens.avail = 0x3; - else - brgens.avail = 0xF; - - scc2owner.clash = DisableEther|DisableIR|DisableRS232b; - - i2cspireloc(); -} - -/* - * issue a request to a CPM device - */ -void -cpmop(int op, int cno, int param) -{ - IMM *io; - - ilock(&cpmlock); - io = m->iomem; - while(io->cpcr & 1) - eieio(); - io->cpcr = (op<<8)|(cno<<4)|(param<<1)|1; - eieio(); - while(io->cpcr & 1) - eieio(); - iunlock(&cpmlock); -} - -/* - * lock the shared IO memory and return a reference to it - */ -IMM* -ioplock(void) -{ - ilock(&cpmlock); - return m->iomem; -} - -/* - * release the lock on the shared IO memory - */ -void -iopunlock(void) -{ - eieio(); - iunlock(&cpmlock); -} - -/* - * connect SCCx clocks in NSMI mode (x=1 for USB) - */ -void -sccnmsi(int x, int rcs, int tcs) -{ - IMM *io; - ulong v; - int sh; - - sh = (x-1)*8; /* each SCCx field in sicr is 8 bits */ - v = (((rcs&7)<<3) | (tcs&7)) << sh; - io = ioplock(); - io->sicr = (io->sicr & ~(0xFF<bcsr[1] & clash */ 0){ - if(!force){ - iunlock(&scc2owner); - return 0; - } - /* notify current owner */ - if(scc2owner.stop) - scc2owner.stop(scc2owner.arg); -// m->bcsr[1] |= clash; - } - scc2owner.stop = stop; - scc2owner.arg = arg; - scc2owner.active = enable; -// m->bcsr[1] &= ~enable; /* the bits are active low */ - iunlock(&scc2owner); - /* beware: someone else can claim it during the `successful' return */ - return 1; -} - -/* - * if SCC2 is currently enabled, shut it down - */ -void -scc2stop(void *a) -{ - SCC *scc; - - scc = a; - if(scc->gsmrl & (3<<4)){ - cpmop(GracefulStopTx, SCC2ID, 0); - cpmop(CloseRxBD, SCC2ID, 0); - delay(1); - scc->gsmrl &= ~(3<<4); /* disable current use */ -// m->bcsr[1] |= scc2owner.clash; - } -} - -/* - * yield up control of SCC2 - */ -void -scc2free(void) -{ - ilock(&scc2owner); -// m->bcsr[1] |= scc2owner.active; - scc2owner.active = 0; - iunlock(&scc2owner); -} - -/* - * allocate a buffer descriptor - */ -BD * -bdalloc(int n) -{ - ulong a; - - a = rmapalloc(&bdmap, 0, n*sizeof(BD), sizeof(BD)); - if(a == 0) - panic("bdalloc"); - return KADDR(a); -} - -/* - * free a buffer descriptor - */ -void -bdfree(BD *b, int n) -{ - if(b){ - eieio(); - mapfree(&bdmap, PADDR(b), n*sizeof(BD)); - } -} - -/* - * allocate memory from the shared IO memory space - */ -void * -cpmalloc(int n, int align) -{ - ulong a; - - a = rmapalloc(&cpmmap, 0, n, align); - if(a == 0) - panic("cpmalloc"); - return KADDR(a); -} - -/* - * free previously allocated shared memory - */ -void -cpmfree(void *p, int n) -{ - if(p != nil && n > 0){ - eieio(); - mapfree(&cpmmap, PADDR(p), n); - } -} - -/* - * allocate a baud rate generator, returning its index - * (or -1 if none is available) - */ -int -brgalloc(void) -{ - int n; - - lock(&brgens); - for(n=0; brgens.avail!=0; n++) - if(brgens.avail & (1<= 0){ - if(n > 3 || brgens.avail & (1<cpuhz+rate)/(2*rate) - 1; - if(d < 0) - d = 0; - if(d >= (1<<12)) - return ((d+15)>>(4-1))|1; /* divider too big: enable prescale by 16 */ - return d<<1; -} - -/* - * initialise receive and transmit buffer rings. - */ -int -ioringinit(Ring* r, int nrdre, int ntdre, int bufsize) -{ - int i, x; - - /* the ring entries must be aligned on sizeof(BD) boundaries */ - r->nrdre = nrdre; - if(r->rdr == nil) - r->rdr = bdalloc(nrdre); - if(r->rrb == nil) - r->rrb = malloc(nrdre*bufsize); - dcflush(r->rrb, nrdre*bufsize); - if(r->rdr == nil || r->rrb == nil) - return -1; - x = PADDR(r->rrb); - for(i = 0; i < nrdre; i++){ - r->rdr[i].length = 0; - r->rdr[i].addr = x; - r->rdr[i].status = BDEmpty|BDInt; - x += bufsize; - } - r->rdr[i-1].status |= BDWrap; - r->rdrx = 0; - - r->ntdre = ntdre; - if(r->tdr == nil) - r->tdr = bdalloc(ntdre); - if(r->txb == nil) - r->txb = malloc(ntdre*sizeof(Block*)); - if(r->tdr == nil || r->txb == nil) - return -1; - for(i = 0; i < ntdre; i++){ - r->txb[i] = nil; - r->tdr[i].addr = 0; - r->tdr[i].length = 0; - r->tdr[i].status = 0; - } - r->tdr[i-1].status |= BDWrap; - r->tdrh = 0; - r->tdri = 0; - r->ntq = 0; - return 0; -} - -/* - * Allocate a new parameter block for I2C or SPI, - * and plant a pointer to it for the microcode, - * returning the kernel address. - * See motorola errata and microcode package: - * the design botch is that the parameters for the SCC2 ethernet overlap the - * SPI/I2C parameter space; this compensates by relocating the latter. - * This routine may be used iff i2cspireloc is used (and it is, above). - */ -void* -cpmparam(ulong olda, int nb) -{ - void *p; - - if(olda < INTMEM) - olda += INTMEM; - if(olda != SPIP && olda != I2CP) - return (void*)(olda); - p = cpmalloc(nb, 32); /* ``RPBASE must be multiple of 32'' */ - if(p == nil) - return p; - *(ushort*)(olda+0x2C) = PADDR(p); /* set RPBASE */ - eieio(); - return p; -} - -/* - * I2C/SPI microcode package from Motorola - * (to relocate I2C/SPI parameters), which was distributed - * on their web site in S-record format. - * - * May 1998 - */ - -static ulong ubase1 = 0x2000; - -static ulong ucode1[] = { -/*S30902202000*/ 0x7FFFEFD9, -/*S30902202004*/ 0x3FFD0000, -/*S30902202008*/ 0x7FFB49F7, -/*S3090220200C*/ 0x7FF90000, -/*S30902202010*/ 0x5FEFADF7, -/*S30902202014*/ 0x5F88ADF7, -/*S30902202018*/ 0x5FEFAFF7, -/*S3090220201C*/ 0x5F88AFF7, -/*S30902202020*/ 0x3A9CFBC8, -/*S30902202024*/ 0x77CAE1BB, -/*S30902202028*/ 0xF4DE7FAD, -/*S3090220202C*/ 0xABAE9330, -/*S30902202030*/ 0x4E08FDCF, -/*S30902202034*/ 0x6E0FAFF8, -/*S30902202038*/ 0x7CCF76CF, -/*S3090220203C*/ 0xFDAFF9CF, -/*S30902202040*/ 0xABF88DC8, -/*S30902202044*/ 0xAB5879F7, -/*S30902202048*/ 0xB0926A27, -/*S3090220204C*/ 0xDFD079F7, -/*S30902202050*/ 0xB090E6BB, -/*S30902202054*/ 0xE5BBE74F, -/*S30902202058*/ 0xAA616F0F, -/*S3090220205C*/ 0x6FFB76CE, -/*S30902202060*/ 0xEE0CF9CF, -/*S30902202064*/ 0x2BFBEFEF, -/*S30902202068*/ 0xCFEEF9CF, -/*S3090220206C*/ 0x76CEAD23, -/*S30902202070*/ 0x90B3DF99, -/*S30902202074*/ 0x7FDDD0C1, -/*S30902202078*/ 0x4BF847FD, -/*S3090220207C*/ 0x7CCF76CE, -/*S30902202080*/ 0xCFEF77CA, -/*S30902202084*/ 0x7EAF7FAD, -/*S30902202088*/ 0x7DFDF0B7, -/*S3090220208C*/ 0xEF7A7FCA, -/*S30902202090*/ 0x77CAFBC8, -/*S30902202094*/ 0x6079E722, -/*S30902202098*/ 0xFBC85FFF, -/*S3090220209C*/ 0xDFFF5FB3, -/*S309022020A0*/ 0xFFFBFBC8, -/*S309022020A4*/ 0xF3C894A5, -/*S309022020A8*/ 0xE7C9EDF9, -/*S309022020AC*/ 0x7F9A7FAD, -/*S309022020B0*/ 0x5F36AFE8, -/*S309022020B4*/ 0x5F5BFFDF, -/*S309022020B8*/ 0xDF95CB9E, -/*S309022020BC*/ 0xAF7D5FC3, -/*S309022020C0*/ 0xAFED8C1B, -/*S309022020C4*/ 0x5FC3AFDD, -/*S309022020C8*/ 0x5FC5DF99, -/*S309022020CC*/ 0x7EFDB0B3, -/*S309022020D0*/ 0x5FB3FFFE, -/*S309022020D4*/ 0xABAE5FB3, -/*S309022020D8*/ 0xFFFE5FD0, -/*S309022020DC*/ 0x600BE6BB, -/*S309022020E0*/ 0x600B5FD0, -/*S309022020E4*/ 0xDFC827FB, -/*S309022020E8*/ 0xEFDF5FCA, -/*S309022020EC*/ 0xCFDE3A9C, -/*S309022020F0*/ 0xE7C9EDF9, -/*S309022020F4*/ 0xF3C87F9E, -/*S309022020F8*/ 0x54CA7FED, -/*S309022020FC*/ 0x2D3A3637, -/*S30902202100*/ 0x756F7E9A, -/*S30902202104*/ 0xF1CE37EF, -/*S30902202108*/ 0x2E677FEE, -/*S3090220210C*/ 0x10EBADF8, -/*S30902202110*/ 0xEFDECFEA, -/*S30902202114*/ 0xE52F7D9F, -/*S30902202118*/ 0xE12BF1CE, -/*S3090220211C*/ 0x5F647E9A, -/*S30902202120*/ 0x4DF8CFEA, -/*S30902202124*/ 0x5F717D9B, -/*S30902202128*/ 0xEFEECFEA, -/*S3090220212C*/ 0x5F73E522, -/*S30902202130*/ 0xEFDE5F73, -/*S30902202134*/ 0xCFDA0B61, -/*S30902202138*/ 0x6A29DF61, -/*S3090220213C*/ 0xE7C9EDF9, -/*S30902202140*/ 0x7E9A30D5, -/*S30902202144*/ 0x1458BFFF, -/*S30902202148*/ 0xF3C85FFF, -/*S3090220214C*/ 0xDFFFA7F8, -/*S30902202150*/ 0x5F5BBFFE, -/*S30902202154*/ 0x7F7D10D0, -/*S30902202158*/ 0x144D5F33, -/*S3090220215C*/ 0xBFFFAF78, -/*S30902202160*/ 0x5F5BBFFD, -/*S30902202164*/ 0xA7F85F33, -/*S30902202168*/ 0xBFFE77FD, -/*S3090220216C*/ 0x30BD4E08, -/*S30902202170*/ 0xFDCFE5FF, -/*S30902202174*/ 0x6E0FAFF8, -/*S30902202178*/ 0x7EEF7E9F, -/*S3090220217C*/ 0xFDEFF1CF, -/*S30902202180*/ 0x5F17ABF8, -/*S30902202184*/ 0x0D5B5F5B, -/*S30902202188*/ 0xFFEF79F7, -/*S3090220218C*/ 0x309EAFDD, -/*S30902202190*/ 0x5F3147F8, -/*S30902202194*/ 0x5F31AFED, -/*S30902202198*/ 0x7FDD50AF, -/*S3090220219C*/ 0x497847FD, -/*S309022021A0*/ 0x7F9E7FED, -/*S309022021A4*/ 0x7DFD70A9, -/*S309022021A8*/ 0xEF7E7ECE, -/*S309022021AC*/ 0x6BA07F9E, -/*S309022021B0*/ 0x2D227EFD, -/*S309022021B4*/ 0x30DB5F5B, -/*S309022021B8*/ 0xFFFD5F5B, -/*S309022021BC*/ 0xFFEF5F5B, -/*S309022021C0*/ 0xFFDF0C9C, -/*S309022021C4*/ 0xAFED0A9A, -/*S309022021C8*/ 0xAFDD0C37, -/*S309022021CC*/ 0x5F37AFBD, -/*S309022021D0*/ 0x7FBDB081, -/*S309022021D4*/ 0x5F8147F8, -}; - -static ulong ubase2 = 0x2F00; -static ulong ucode2[] = { -/*S30902202F00*/ 0x3E303430, -/*S30902202F04*/ 0x34343737, -/*S30902202F08*/ 0xABBF9B99, -/*S30902202F0C*/ 0x4B4FBDBD, -/*S30902202F10*/ 0x59949334, -/*S30902202F14*/ 0x9FFF37FB, -/*S30902202F18*/ 0x9B177DD9, -/*S30902202F1C*/ 0x936956BB, -/*S30902202F20*/ 0xFBDD697B, -/*S30902202F24*/ 0xDD2FD113, -/*S30902202F28*/ 0x1DB9F7BB, -/*S30902202F2C*/ 0x36313963, -/*S30902202F30*/ 0x79373369, -/*S30902202F34*/ 0x3193137F, -/*S30902202F38*/ 0x7331737A, -/*S30902202F3C*/ 0xF7BB9B99, -/*S30902202F40*/ 0x9BB19795, -/*S30902202F44*/ 0x77FDFD3D, -/*S30902202F48*/ 0x573B773F, -/*S30902202F4C*/ 0x737933F7, -/*S30902202F50*/ 0xB991D115, -/*S30902202F54*/ 0x31699315, -/*S30902202F58*/ 0x31531694, -/*S30902202F5C*/ 0xBF4FBDBD, -/*S30902202F60*/ 0x35931497, -/*S30902202F64*/ 0x35376956, -/*S30902202F68*/ 0xBD697B9D, -/*S30902202F6C*/ 0x96931313, -/*S30902202F70*/ 0x19797937, -/*S30902202F74*/ 0x69350000, -}; - -/* - * compensate for chip design botch by installing - * microcode to relocate I2C and SPI parameters away - * from the ethernet parameters - */ -static void -i2cspireloc(void) -{ - IMM *io; - static int done; - - if(done) - return; - io = m->iomem; - io->rccr &= ~3; - memmove((uchar*)m->iomem+ubase1, ucode1, sizeof(ucode1)); - memmove((uchar*)m->iomem+ubase2, ucode2, sizeof(ucode2)); - - io->rctr1 = 0x802a; /* relocate SPI */ - io->rctr2 = 0x8028; /* relocate SPI */ - io->rctr3 = 0x802e; /* relocate I2C */ - io->rctr4 = 0x802c; /* relocate I2C */ - io->rccr |= 1; - done = 1; -} diff --git a/mpc/cpm2.c b/mpc/cpm2.c deleted file mode 100644 index e56e57a5bca171170bfc6ad5c5900195fcb537df..0000000000000000000000000000000000000000 --- a/mpc/cpm2.c +++ /dev/null @@ -1,819 +0,0 @@ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "io.h" - -enum { - BDSIZE= 1024, /* IO memory reserved for buffer descriptors */ - CPMSIZE= 1024, /* IO memory reserved for other uses */ -}; - -static Map bdmapv[BDSIZE/sizeof(BD)]; -static RMap bdmap = {"buffer descriptors"}; - -static Map cpmmapv[CPMSIZE/sizeof(ulong)]; -static RMap cpmmap = {"CPM memory"}; - -static Lock cpmlock; - -static struct { - Lock; - ulong avail; -} brgens; - -static struct { - Lock; - ulong clash; /* disable bits for mutually-exclusive options */ - ulong active; /* disable bit for current owner, or 0 */ - void (*stop)(void*); - void* arg; -} scc2owner; - -static void i2cspireloc(void); - -/* - * initialise the communications processor module - * and associated device registers - */ -void -cpminit(void) -{ - IMM *io; - - io = m->iomem; - io->rccr = 0; - io->rmds = 0; -// io->lccr &= ~1; /* disable LCD */ - io->sdcr = 1; - io->pcint = 0; /* disable all port C interrupts */ - io->pcso = 0; - io->pcdir =0; - io->pcpar = 0; - io->papar = 0; - io->padir = 0; - io->pbpar = 0; - io->pbdir = 0; - io->tgcr = 0x2222; /* reset timers, low-power stop */ - eieio(); - - for(io->cpcr = 0x8001; io->cpcr & 1;) /* reset all CPM channels */ - eieio(); - - mapinit(&bdmap, bdmapv, sizeof(bdmapv)); - mapfree(&bdmap, DPBASE, BDSIZE); - mapinit(&cpmmap, cpmmapv, sizeof(cpmmapv)); - mapfree(&cpmmap, DPBASE+BDSIZE, CPMSIZE); - - if(m->cputype == 0x50 && (getimmr() & 0xFFFF) <= 0x2001) - brgens.avail = 0x3; - else - brgens.avail = 0xF; - - scc2owner.clash = DisableEther|DisableIR|DisableRS232b; - - i2cspireloc(); -} - -/* - * issue a request to a CPM device - */ -void -cpmop(int op, int cno, int param) -{ - IMM *io; - - ilock(&cpmlock); - io = m->iomem; - while(io->cpcr & 1) - eieio(); - io->cpcr = (op<<8)|(cno<<4)|(param<<1)|1; - eieio(); - while(io->cpcr & 1) - eieio(); - iunlock(&cpmlock); -} - -/* - * lock the shared IO memory and return a reference to it - */ -IMM* -ioplock(void) -{ - ilock(&cpmlock); - return m->iomem; -} - -/* - * release the lock on the shared IO memory - */ -void -iopunlock(void) -{ - eieio(); - iunlock(&cpmlock); -} - -/* - * connect SCCx clocks in NSMI mode (x=1 for USB) - */ -void -sccnmsi(int x, int rcs, int tcs) -{ - IMM *io; - ulong v; - int sh; - - sh = (x-1)*8; /* each SCCx field in sicr is 8 bits */ - v = (((rcs&7)<<3) | (tcs&7)) << sh; - io = ioplock(); - io->sicr = (io->sicr & ~(0xFF<bcsr[1] & clash */ 0){ - if(!force){ - iunlock(&scc2owner); - return 0; - } - /* notify current owner */ - if(scc2owner.stop) - scc2owner.stop(scc2owner.arg); -// m->bcsr[1] |= clash; - } - scc2owner.stop = stop; - scc2owner.arg = arg; - scc2owner.active = enable; -// m->bcsr[1] &= ~enable; /* the bits are active low */ - iunlock(&scc2owner); - /* beware: someone else can claim it during the `successful' return */ - return 1; -} - -/* - * if SCC2 is currently enabled, shut it down - */ -void -scc2stop(void *a) -{ - SCC *scc; - - scc = a; - if(scc->gsmrl & (3<<4)){ - cpmop(GracefulStopTx, SCC2ID, 0); - cpmop(CloseRxBD, SCC2ID, 0); - delay(1); - scc->gsmrl &= ~(3<<4); /* disable current use */ -// m->bcsr[1] |= scc2owner.clash; - } -} - -/* - * yield up control of SCC2 - */ -void -scc2free(void) -{ - ilock(&scc2owner); -// m->bcsr[1] |= scc2owner.active; - scc2owner.active = 0; - iunlock(&scc2owner); -} - -/* - * allocate a buffer descriptor - */ -BD * -bdalloc(int n) -{ - ulong a; - - a = rmapalloc(&bdmap, 0, n*sizeof(BD), sizeof(BD)); - if(a == 0) - panic("bdalloc"); - return KADDR(a); -} - -/* - * free a buffer descriptor - */ -void -bdfree(BD *b, int n) -{ - if(b){ - eieio(); - mapfree(&bdmap, PADDR(b), n*sizeof(BD)); - } -} - -/* - * allocate memory from the shared IO memory space - */ -void * -cpmalloc(int n, int align) -{ - ulong a; - - a = rmapalloc(&cpmmap, 0, n, align); - if(a == 0) - panic("cpmalloc"); - return KADDR(a); -} - -/* - * free previously allocated shared memory - */ -void -cpmfree(void *p, int n) -{ - if(p != nil && n > 0){ - eieio(); - mapfree(&cpmmap, PADDR(p), n); - } -} - -/* - * allocate a baud rate generator, returning its index - * (or -1 if none is available) - */ -int -brgalloc(void) -{ - int n; - - lock(&brgens); - for(n=0; brgens.avail!=0; n++) - if(brgens.avail & (1<= 0){ - if(n > 3 || brgens.avail & (1<cpuhz+rate)/(2*rate) - 1; - if(d < 0) - d = 0; - if(d >= (1<<12)) - return ((d+15)>>(4-1))|1; /* divider too big: enable prescale by 16 */ - return d<<1; -} - -/* - * initialise receive and transmit buffer rings. - */ -int -ioringinit(Ring* r, int nrdre, int ntdre, int bufsize) -{ - int i, x; - - /* the ring entries must be aligned on sizeof(BD) boundaries */ - r->nrdre = nrdre; - if(r->rdr == nil) - r->rdr = bdalloc(nrdre); - if(r->rrb == nil) - r->rrb = malloc(nrdre*bufsize); - dcflush(r->rrb, nrdre*bufsize); - if(r->rdr == nil || r->rrb == nil) - return -1; - x = PADDR(r->rrb); - for(i = 0; i < nrdre; i++){ - r->rdr[i].length = 0; - r->rdr[i].addr = x; - r->rdr[i].status = BDEmpty|BDInt; - x += bufsize; - } - r->rdr[i-1].status |= BDWrap; - r->rdrx = 0; - - r->ntdre = ntdre; - if(r->tdr == nil) - r->tdr = bdalloc(ntdre); - if(r->txb == nil) - r->txb = malloc(ntdre*sizeof(Block*)); - if(r->tdr == nil || r->txb == nil) - return -1; - for(i = 0; i < ntdre; i++){ - r->txb[i] = nil; - r->tdr[i].addr = 0; - r->tdr[i].length = 0; - r->tdr[i].status = 0; - } - r->tdr[i-1].status |= BDWrap; - r->tdrh = 0; - r->tdri = 0; - r->ntq = 0; - return 0; -} - -/* - * Allocate a new parameter block for I2C or SPI, - * and plant a pointer to it for the microcode, - * returning the kernel address. - * See motorola errata and microcode package: - * the design botch is that the parameters for the SCC2 ethernet overlap the - * SPI/I2C parameter space; this compensates by relocating the latter. - * This routine may be used iff i2cspireloc is used (and it is, above). - */ -void* -cpmparam(ulong olda, int nb) -{ - void *p; - - if(olda < INTMEM) - olda += INTMEM; - if(olda != SPIP && olda != I2CP) - return (void*)(olda); - p = cpmalloc(nb, 32); /* ``RPBASE must be multiple of 32'' */ - if(p == nil) - return p; - *(ushort*)(olda+0x2C) = PADDR(p); /* set RPBASE */ - eieio(); - return p; -} - -/* - * I2C/SPI microcode package from Motorola - * (to relocate I2C/SPI parameters), which was distributed - * on their web site in S-record format. - * - * May 1998 - */ - -static ulong ubase1 = 0x2000; - -/*S00600004844521B*/ -static ulong ucode1[] = { -/*S30902202000*/ 0x3FFF0000, -/*S30902202004*/ 0x3FFD0000, -/*S30902202008*/ 0x3FFB0000, -/*S3090220200C*/ 0x3FF90000, -/*S30902202010*/ 0x5F13EFF8, -/*S30902202014*/ 0x5EB5EFF8, -/*S30902202018*/ 0x5F88ADF7, -/*S3090220201C*/ 0x5FEFADF7, -/*S30902202020*/ 0x3A9CFBC8, -/*S30902202024*/ 0x77CAE1BB, -/*S30902202028*/ 0xF4DE7FAD, -/*S3090220202C*/ 0xABAE9330, -/*S30902202030*/ 0x4E08FDCF, -/*S30902202034*/ 0x6E0FAFF8, -/*S30902202038*/ 0x7CCF76CF, -/*S3090220203C*/ 0xFDAFF9CF, -/*S30902202040*/ 0xABF88DC8, -/*S30902202044*/ 0xAB5879F7, -/*S30902202048*/ 0xB0925D8D, -/*S3090220204C*/ 0xDFD079F7, -/*S30902202050*/ 0xB090E6BB, -/*S30902202054*/ 0xE5BBE74F, -/*S30902202058*/ 0x9E046F0F, -/*S3090220205C*/ 0x6FFB76CE, -/*S30902202060*/ 0xEE0CF9CF, -/*S30902202064*/ 0x2BFBEFEF, -/*S30902202068*/ 0xCFEEF9CF, -/*S3090220206C*/ 0x76CEAD23, -/*S30902202070*/ 0x90B3DF99, -/*S30902202074*/ 0x7FDDD0C1, -/*S30902202078*/ 0x4BF847FD, -/*S3090220207C*/ 0x7CCF76CE, -/*S30902202080*/ 0xCFEF77CA, -/*S30902202084*/ 0x7EAF7FAD, -/*S30902202088*/ 0x7DFDF0B7, -/*S3090220208C*/ 0xEF7A7FCA, -/*S30902202090*/ 0x77CAFBC8, -/*S30902202094*/ 0x6079E722, -/*S30902202098*/ 0xFBC85FFF, -/*S3090220209C*/ 0xDFFF5FB3, -/*S309022020A0*/ 0xFFFBFBC8, -/*S309022020A4*/ 0xF3C894A5, -/*S309022020A8*/ 0xE7C9EDF9, -/*S309022020AC*/ 0x7F9A7FAD, -/*S309022020B0*/ 0x5F36AFE8, -/*S309022020B4*/ 0x5F5BFFDF, -/*S309022020B8*/ 0xDF95CB9E, -/*S309022020BC*/ 0xAF7D5FC3, -/*S309022020C0*/ 0xAFED8C1B, -/*S309022020C4*/ 0x5FC3AFDD, -/*S309022020C8*/ 0x5FC5DF99, -/*S309022020CC*/ 0x7EFDB0B3, -/*S309022020D0*/ 0x5FB3FFFE, -/*S309022020D4*/ 0xABAE5FB3, -/*S309022020D8*/ 0xFFFE5FD0, -/*S309022020DC*/ 0x600BE6BB, -/*S309022020E0*/ 0x600B5FD0, -/*S309022020E4*/ 0xDFC827FB, -/*S309022020E8*/ 0xEFDF5FCA, -/*S309022020EC*/ 0xCFDE3A9C, -/*S309022020F0*/ 0xE7C9EDF9, -/*S309022020F4*/ 0xF3C87F9E, -/*S309022020F8*/ 0x54CA7FED, -/*S309022020FC*/ 0x2D3A3637, -/*S30902202100*/ 0x756F7E9A, -/*S30902202104*/ 0xF1CE37EF, -/*S30902202108*/ 0x2E677FEE, -/*S3090220210C*/ 0x10EBADF8, -/*S30902202110*/ 0xEFDECFEA, -/*S30902202114*/ 0xE52F7D9F, -/*S30902202118*/ 0xE12BF1CE, -/*S3090220211C*/ 0x5F647E9A, -/*S30902202120*/ 0x4DF8CFEA, -/*S30902202124*/ 0x5F717D9B, -/*S30902202128*/ 0xEFEECFEA, -/*S3090220212C*/ 0x5F73E522, -/*S30902202130*/ 0xEFDE5F73, -/*S30902202134*/ 0xCFDA0B61, -/*S30902202138*/ 0x5D8FDF61, -/*S3090220213C*/ 0xE7C9EDF9, -/*S30902202140*/ 0x7E9A30D5, -/*S30902202144*/ 0x1458BFFF, -/*S30902202148*/ 0xF3C85FFF, -/*S3090220214C*/ 0xDFFFA7F8, -/*S30902202150*/ 0x5F5BBFFE, -/*S30902202154*/ 0x7F7D10D0, -/*S30902202158*/ 0x144D5F33, -/*S3090220215C*/ 0xBFFFAF78, -/*S30902202160*/ 0x5F5BBFFD, -/*S30902202164*/ 0xA7F85F33, -/*S30902202168*/ 0xBFFE77FD, -/*S3090220216C*/ 0x30BD4E08, -/*S30902202170*/ 0xFDCFE5FF, -/*S30902202174*/ 0x6E0FAFF8, -/*S30902202178*/ 0x7EEF7E9F, -/*S3090220217C*/ 0xFDEFF1CF, -/*S30902202180*/ 0x5F17ABF8, -/*S30902202184*/ 0x0D5B5F5B, -/*S30902202188*/ 0xFFEF79F7, -/*S3090220218C*/ 0x309EAFDD, -/*S30902202190*/ 0x5F3147F8, -/*S30902202194*/ 0x5F31AFED, -/*S30902202198*/ 0x7FDD50AF, -/*S3090220219C*/ 0x497847FD, -/*S309022021A0*/ 0x7F9E7FED, -/*S309022021A4*/ 0x7DFD70A9, -/*S309022021A8*/ 0xEF7E7ECE, -/*S309022021AC*/ 0x6BA07F9E, -/*S309022021B0*/ 0x2D227EFD, -/*S309022021B4*/ 0x30DB5F5B, -/*S309022021B8*/ 0xFFFD5F5B, -/*S309022021BC*/ 0xFFEF5F5B, -/*S309022021C0*/ 0xFFDF0C9C, -/*S309022021C4*/ 0xAFED0A9A, -/*S309022021C8*/ 0xAFDD0C37, -/*S309022021CC*/ 0x5F37AFBD, -/*S309022021D0*/ 0x7FBDB081, -/*S309022021D4*/ 0x5F8147F8, -/*S309022021D8*/ 0x3A11E710, -/*S309022021DC*/ 0xEDF0CCDD, -/*S309022021E0*/ 0xF3186D0A, -/*S309022021E4*/ 0x7F0E5F06, -/*S309022021E8*/ 0x7FEDBB38, -/*S309022021EC*/ 0x3AFE7468, -/*S309022021F0*/ 0x7FEDF4FC, -/*S309022021F4*/ 0x8FFBB951, -/*S309022021F8*/ 0xB85F77FD, -/*S309022021FC*/ 0xB0DF5DDD, -/*S30902202200*/ 0xDEFE7FED, -/*S30902202204*/ 0x90E1E74D, -/*S30902202208*/ 0x6F0DCBF7, -/*S3090220220C*/ 0xE7DECFED, -/*S30902202210*/ 0xCB74CFED, -/*S30902202214*/ 0xCFEDDF6D, -/*S30902202218*/ 0x91714F74, -/*S3090220221C*/ 0x5DD2DEEF, -/*S30902202220*/ 0x9E04E7DF, -/*S30902202224*/ 0xEFBB6FFB, -/*S30902202228*/ 0xE7EF7F0E, -/*S3090220222C*/ 0x9E097FED, -/*S30902202230*/ 0xEBDBEFFA, -/*S30902202234*/ 0xEB54AFFB, -/*S30902202238*/ 0x7FEA90D7, -/*S3090220223C*/ 0x7E0CF0C3, -/*S30902202240*/ 0xBFFFF318, -/*S30902202244*/ 0x5FFFDFFF, -/*S30902202248*/ 0xAC59EFEA, -/*S3090220224C*/ 0x7FCE1EE5, -/*S30902202250*/ 0xE2FF5EE1, -/*S30902202254*/ 0xAFFBE2FF, -/*S30902202258*/ 0x5EE3AFFB, -/*S3090220225C*/ 0xF9CC7D0F, -/*S30902202260*/ 0xAEF8770F, -/*S30902202264*/ 0x7D0FB0C6, -/*S30902202268*/ 0xEFFBBFFF, -/*S3090220226C*/ 0xCFEF5EDE, -/*S30902202270*/ 0x7D0FBFFF, -/*S30902202274*/ 0x5EDE4CF8, -/*S30902202278*/ 0x7FDDD0BF, -/*S3090220227C*/ 0x49F847FD, -/*S30902202280*/ 0x7EFDF0BB, -/*S30902202284*/ 0x7FEDFFFD, -/*S30902202288*/ 0x7DFDF0B7, -/*S3090220228C*/ 0xEF7E7E1E, -/*S30902202290*/ 0x5EDE7F0E, -/*S30902202294*/ 0x3A11E710, -/*S30902202298*/ 0xEDF0CCAB, -/*S3090220229C*/ 0xFB18AD2E, -/*S309022022A0*/ 0x1EA9BBB8, -/*S309022022A4*/ 0x74283B7E, -/*S309022022A8*/ 0x73C2E4BB, -/*S309022022AC*/ 0x2ADA4FB8, -/*S309022022B0*/ 0xDC21E4BB, -/*S309022022B4*/ 0xB2A1FFBF, -/*S309022022B8*/ 0x5E2C43F8, -/*S309022022BC*/ 0xFC87E1BB, -/*S309022022C0*/ 0xE74FFD91, -/*S309022022C4*/ 0x6F0F4FE8, -/*S309022022C8*/ 0xC7BA32E2, -/*S309022022CC*/ 0xF396EFEB, -/*S309022022D0*/ 0x600B4F78, -/*S309022022D4*/ 0xE5BB760B, -/*S309022022D8*/ 0x53ACAEF8, -/*S309022022DC*/ 0x4EF88B0E, -/*S309022022E0*/ 0xCFEF9E09, -/*S309022022E4*/ 0xABF8751F, -/*S309022022E8*/ 0xEFEF5BAC, -/*S309022022EC*/ 0x741F4FE8, -/*S309022022F0*/ 0x751E760D, -/*S309022022F4*/ 0x7FDBF081, -/*S309022022F8*/ 0x741CAFCE, -/*S309022022FC*/ 0xEFCC7FCE, -/*S30902202300*/ 0x751E70AC, -/*S30902202304*/ 0x741CE7BB, -/*S30902202308*/ 0x3372CFED, -/*S3090220230C*/ 0xAFDBEFEB, -/*S30902202310*/ 0xE5BB760B, -/*S30902202314*/ 0x53F2AEF8, -/*S30902202318*/ 0xAFE8E7EB, -/*S3090220231C*/ 0x4BF8771E, -/*S30902202320*/ 0x7E247FED, -/*S30902202324*/ 0x4FCBE2CC, -/*S30902202328*/ 0x7FBC30A9, -/*S3090220232C*/ 0x7B0F7A0F, -/*S30902202330*/ 0x34D577FD, -/*S30902202334*/ 0x308B5DB7, -/*S30902202338*/ 0xDE553E5F, -/*S3090220233C*/ 0xAF78741F, -/*S30902202340*/ 0x741F30F0, -/*S30902202344*/ 0xCFEF5E2C, -/*S30902202348*/ 0x741F3EAC, -/*S3090220234C*/ 0xAFB8771E, -/*S30902202350*/ 0x5E677FED, -/*S30902202354*/ 0x0BD3E2CC, -/*S30902202358*/ 0x741CCFEC, -/*S3090220235C*/ 0xE5CA53CD, -/*S30902202360*/ 0x6FCB4F74, -/*S30902202364*/ 0x5DADDE4B, -/*S30902202368*/ 0x2AB63D38, -/*S3090220236C*/ 0x4BB3DE30, -/*S30902202370*/ 0x751F741C, -/*S30902202374*/ 0x6C42EFFA, -/*S30902202378*/ 0xEFEA7FCE, -/*S3090220237C*/ 0x6FFC30BE, -/*S30902202380*/ 0xEFEC3FCA, -/*S30902202384*/ 0x30B3DE2E, -/*S30902202388*/ 0xADF85D9E, -/*S3090220238C*/ 0xAF7DAEFD, -/*S30902202390*/ 0x5D9EDE2E, -/*S30902202394*/ 0x5D9EAFDD, -/*S30902202398*/ 0x761F10AC, -/*S3090220239C*/ 0x1DA07EFD, -/*S309022023A0*/ 0x30ADFFFE, -/*S309022023A4*/ 0x4908FB18, -/*S309022023A8*/ 0x5FFFDFFF, -/*S309022023AC*/ 0xAFBB709B, -/*S309022023B0*/ 0x4EF85E67, -/*S309022023B4*/ 0xADF814AD, -/*S309022023B8*/ 0x7A0F70AD, -/*S309022023BC*/ 0xCFEF50AD, -/*S309022023C0*/ 0x7A0FDE30, -/*S309022023C4*/ 0x5DA0AFED, -/*S309022023C8*/ 0x3C12780F, -/*S309022023CC*/ 0xEFEF780F, -/*S309022023D0*/ 0xEFEF790F, -/*S309022023D4*/ 0xA7F85E0F, -/*S309022023D8*/ 0xFFEF790F, -/*S309022023DC*/ 0xEFEF790F, -/*S309022023E0*/ 0x14ADDE2E, -/*S309022023E4*/ 0x5D9EADFD, -/*S309022023E8*/ 0x5E2DFFFB, -/*S309022023EC*/ 0xE79ADDFD, -/*S309022023F0*/ 0xEFF96079, -/*S309022023F4*/ 0x607AE79A, -/*S309022023F8*/ 0xDDFCEFF9, -/*S309022023FC*/ 0x60795DFF, -/*S30902202400*/ 0x607ACFEF, -/*S30902202404*/ 0xEFEFEFDF, -/*S30902202408*/ 0xEFBFEF7F, -/*S3090220240C*/ 0xEEFFEDFF, -/*S30902202410*/ 0xEBFFE7FF, -/*S30902202414*/ 0xAFEFAFDF, -/*S30902202418*/ 0xAFBFAF7F, -/*S3090220241C*/ 0xAEFFADFF, -/*S30902202420*/ 0xABFFA7FF, -/*S30902202424*/ 0x6FEF6FDF, -/*S30902202428*/ 0x6FBF6F7F, -/*S3090220242C*/ 0x6EFF6DFF, -/*S30902202430*/ 0x6BFF67FF, -/*S30902202434*/ 0x2FEF2FDF, -/*S30902202438*/ 0x2FBF2F7F, -/*S3090220243C*/ 0x2EFF2DFF, -/*S30902202440*/ 0x2BFF27FF, -/*S30902202444*/ 0x4E08FD1F, -/*S30902202448*/ 0xE5FF6E0F, -/*S3090220244C*/ 0xAFF87EEF, -/*S30902202450*/ 0x7E0FFDEF, -/*S30902202454*/ 0xF11F6079, -/*S30902202458*/ 0xABF8F542, -/*S3090220245C*/ 0x7E0AF11C, -/*S30902202460*/ 0x37CFAE3A, -/*S30902202464*/ 0x7FEC90BE, -/*S30902202468*/ 0xADF8EFDC, -/*S3090220246C*/ 0xCFEAE52F, -/*S30902202470*/ 0x7D0FE12B, -/*S30902202474*/ 0xF11C6079, -/*S30902202478*/ 0x7E0A4DF8, -/*S3090220247C*/ 0xCFEA5DC4, -/*S30902202480*/ 0x7D0BEFEC, -/*S30902202484*/ 0xCFEA5DC6, -/*S30902202488*/ 0xE522EFDC, -/*S3090220248C*/ 0x5DC6CFDA, -/*S30902202490*/ 0x4E08FD1F, -/*S30902202494*/ 0x6E0FAFF8, -/*S30902202498*/ 0x7C1F761F, -/*S3090220249C*/ 0xFDEFF91F, -/*S309022024A0*/ 0x6079ABF8, -/*S309022024A4*/ 0x761CEE24, -/*S309022024A8*/ 0xF91F2BFB, -/*S309022024AC*/ 0xEFEFCFEC, -/*S309022024B0*/ 0xF91F6079, -/*S309022024B4*/ 0x761C27FB, -/*S309022024B8*/ 0xEFDF5DA7, -/*S309022024BC*/ 0xCFDC7FDD, -/*S309022024C0*/ 0xD09C4BF8, -/*S309022024C4*/ 0x47FD7C1F, -/*S309022024C8*/ 0x761CCFCF, -/*S309022024CC*/ 0x7EEF7FED, -/*S309022024D0*/ 0x7DFDF093, -/*S309022024D4*/ 0xEF7E7F1E, -/*S309022024D8*/ 0x771EFB18, -/*S309022024DC*/ 0x6079E722, -/*S309022024E0*/ 0xE6BBE5BB, -/*S309022024E4*/ 0xAE0AE5BB, -/*S309022024E8*/ 0x600BAE85, -/*S309022024EC*/ 0xE2BBE2BB, -/*S309022024F0*/ 0xE2BBE2BB, -/*S309022024F4*/ 0xAF02E2BB, -/*S309022024F8*/ 0xE2BB2FF9, -/*S309022024FC*/ 0x6079E2BB, -}; - -static ulong ubase2 = 0x2F00; -static ulong ucode2[] = { -/*S30902202F00*/ 0x30303030, -/*S30902202F04*/ 0x3E3E3434, -/*S30902202F08*/ 0xABBF9B99, -/*S30902202F0C*/ 0x4B4FBDBD, -/*S30902202F10*/ 0x59949334, -/*S30902202F14*/ 0x9FFF37FB, -/*S30902202F18*/ 0x9B177DD9, -/*S30902202F1C*/ 0x936956BB, -/*S30902202F20*/ 0xFBDD697B, -/*S30902202F24*/ 0xDD2FD113, -/*S30902202F28*/ 0x1DB9F7BB, -/*S30902202F2C*/ 0x36313963, -/*S30902202F30*/ 0x79373369, -/*S30902202F34*/ 0x3193137F, -/*S30902202F38*/ 0x7331737A, -/*S30902202F3C*/ 0xF7BB9B99, -/*S30902202F40*/ 0x9BB19795, -/*S30902202F44*/ 0x77FDFD3D, -/*S30902202F48*/ 0x573B773F, -/*S30902202F4C*/ 0x737933F7, -/*S30902202F50*/ 0xB991D115, -/*S30902202F54*/ 0x31699315, -/*S30902202F58*/ 0x31531694, -/*S30902202F5C*/ 0xBF4FBDBD, -/*S30902202F60*/ 0x35931497, -/*S30902202F64*/ 0x35376956, -/*S30902202F68*/ 0xBD697B9D, -/*S30902202F6C*/ 0x96931313, -/*S30902202F70*/ 0x19797937, -/*S30902202F74*/ 0x6935AF78, -/*S30902202F78*/ 0xB9B3BAA3, -/*S30902202F7C*/ 0xB8788683, -/*S30902202F80*/ 0x368F78F7, -/*S30902202F84*/ 0x87778733, -/*S30902202F88*/ 0x3FFFFB3B, -/*S30902202F8C*/ 0x8E8F78B8, -/*S30902202F90*/ 0x1D118E13, -/*S30902202F94*/ 0xF3FF3F8B, -/*S30902202F98*/ 0x6BD8E173, -/*S30902202F9C*/ 0xD1366856, -/*S30902202FA0*/ 0x68D1687B, -/*S30902202FA4*/ 0x3DAF78B8, -/*S30902202FA8*/ 0x3A3A3F87, -/*S30902202FAC*/ 0x8F81378F, -/*S30902202FB0*/ 0xF876F887, -/*S30902202FB4*/ 0x77FD8778, -/*S30902202FB8*/ 0x737DE8D6, -/*S30902202FBC*/ 0xBBF8BFFF, -/*S30902202FC0*/ 0xD8DF87F7, -/*S30902202FC4*/ 0xFD876F7B, -/*S30902202FC8*/ 0x8BFFF8BD, -/*S30902202FCC*/ 0x8683387D, -/*S30902202FD0*/ 0xB873D87B, -/*S30902202FD4*/ 0x3B8FD7F8, -/*S30902202FD8*/ 0xF7338883, -/*S30902202FDC*/ 0xBB8EE1F8, -/*S30902202FE0*/ 0xEF837377, -/*S30902202FE4*/ 0x3337B836, -/*S30902202FE8*/ 0x817D11F8, -/*S30902202FEC*/ 0x7378B878, -/*S30902202FF0*/ 0xD3368B7D, -/*S30902202FF4*/ 0xED731B7D, -/*S30902202FF8*/ 0x833731F3, -/*S30902202FFC*/ 0xF22F3F23, -/*S30902202E00*/ 0x27EEEEEE, -/*S30902202E04*/ 0xEEEEEEEE, -/*S30902202E08*/ 0xEEEEEEEE, -/*S30902202E0C*/ 0xEEEEEEEE, -/*S30902202E10*/ 0xEE4BF4FB, -/*S30902202E14*/ 0xDBD259BB, -/*S30902202E18*/ 0x1979577F, -/*S30902202E1C*/ 0xDFD2D573, -/*S30902202E20*/ 0xB773F737, -/*S30902202E24*/ 0x4B4FBDBD, -/*S30902202E28*/ 0x25B9B177, -/*S30902202E2C*/ 0xD2D17376, -/*S30902202E30*/ 0x956BBFDD, -/*S30902202E34*/ 0x697BDD2F, -/*S30902202E38*/ 0xFF9F79FF, -/*S30902202E3C*/ 0xFF9FF22F, -}; - -/* - * compensate for chip design botch by installing - * microcode to relocate I2C and SPI parameters away - * from the ethernet parameters - */ -static void -i2cspireloc(void) -{ - IMM *io; - static int done; - - if(done) - return; - io = m->iomem; - io->rccr &= ~3; - memmove((uchar*)m->iomem+ubase1, ucode1, sizeof(ucode1)); - memmove((uchar*)m->iomem+ubase2, ucode2, sizeof(ucode2)); - - io->rctr1 = 0x8080; /* relocate SPI */ - io->rctr2 = 0x808a; /* relocate SPI */ - io->rctr3 = 0x8028; /* relocate I2C */ - io->rctr4 = 0x802a; /* relocate I2C */ - io->rccr |= 3; - done = 1; -} diff --git a/mpc/dat.h b/mpc/dat.h deleted file mode 100644 index a6e1a22aa104d3c7f165ceb9a798a3e7414066d1..0000000000000000000000000000000000000000 --- a/mpc/dat.h +++ /dev/null @@ -1,233 +0,0 @@ -typedef struct Conf Conf; -typedef struct FPsave FPsave; -typedef struct IMM IMM; -typedef struct Irqctl Irqctl; -typedef struct ISAConf ISAConf; -typedef struct Label Label; -typedef struct Lock Lock; -typedef struct Mach Mach; -typedef struct Notsave Notsave; -typedef struct PCMmap PCMmap; -typedef struct PMMU PMMU; -typedef struct Map Map; -typedef struct PCArch PCArch; -typedef struct Proc Proc; -typedef struct RMap RMap; -typedef struct Softtlb Softtlb; -typedef struct Ureg Ureg; - -/* - * parameters for sysproc.c - */ -#define AOUT_MAGIC (Q_MAGIC) - - -struct Lock -{ - ulong key; - ulong pc; - ulong sr; - Proc *p; - ushort isilock; -}; - -struct Label -{ - ulong sp; - ulong pc; -}; - -/* - * things saved in the Proc structure during a notify - */ -struct Notsave -{ - ulong UNUSED; -}; - -/* - * MMU stuff in proc - */ -#define NCOLOR 1 -struct PMMU -{ - int pidonmach[MAXMACH]; -}; - -/* - * FPsave.status - */ -enum -{ - FPinit, - FPactive, - FPinactive, -}; - -/* - * This structure must agree with fpsave and fprestore asm routines - */ -struct FPsave -{ - double fpreg[32]; - union { - double fpscrd; - struct { - ulong pad; - ulong fpscr; - }; - }; - int fpistate; /* emulated fp */ - ulong emreg[32][3]; /* emulated fp */ -}; - -struct Conf -{ - ulong nmach; /* processors */ - ulong nproc; /* processes */ - ulong npage0; /* total physical pages of memory */ - ulong npage1; /* total physical pages of memory */ - ulong npage; /* total physical pages of memory */ - ulong upages; /* user page pool */ - ulong nimage; /* number of page cache image headers */ - ulong nswap; /* number of swap pages */ - int nswppo; /* max # of pageouts per segment pass */ - 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 ialloc; /* max interrupt time allocation in bytes */ - ulong interps; /* number of interpreter processes */ - ulong pipeqsize; /* size in bytes of pipe queues */ -}; - -#include "../port/portdat.h" - -/* - * machine dependent definitions not used by ../port/dat.h - */ - -struct Mach -{ - /* OFFSETS OF THE FOLLOWING KNOWN BY l.s */ - int machno; /* physical id of processor (unused) */ - ulong splpc; /* pc of last caller to splhi */ - int mmask; /* 1<machno (unused) */ - Proc *proc; /* current process on this processor */ - Softtlb *stb; /* software tlb cache */ - ulong tlbfault; /* # of tlb faults */ - ulong dar; /* # of tlb faults */ - ulong dsisr; /* # of tlb faults */ - ulong epn; - ulong cmp1; - - /* ordering from here on irrelevant */ - ulong ticks; /* of the clock since boot time */ - Label sched; /* scheduler wakeup */ - QLock stlblk; /* lock for allocating stlb entries on this mach */ - int lastpid; /* last pid allocated on this machine */ - int purgepid; /* last pid purged on this machine */ - Proc* pidproc[NTLBPID]; /* proc that owns tlbpid on this mach */ - Lock alarmlock; /* access to alarm list */ - void *alarm; /* alarms bound to this clock */ - int nrdy; - int speed; /* general system clock in MHz */ - long oscclk; /* oscillator frequency (MHz) */ - long cpuhz; /* general system clock (cycles) */ - long clockgen; /* clock generator frequency (cycles) */ - int cputype; - ulong delayloop; -// ulong* bcsr; - IMM* iomem; /* MPC8xx internal i/o control memory */ - - ulong fairness; /* for runproc */ - - int tlbpurge; - int pfault; - int cs; - int syscall; - int load; - int intr; - vlong fastclock; /* last sampled value */ - vlong intrts; /* time stamp of last interrupt */ - int flushmmu; /* make current proc flush it's mmu state */ - - /* MUST BE LAST */ - int stack[1]; -}; - -struct Softtlb -{ - ulong virt; - ulong phys; -}; - -/* - * Fake kmap - */ -typedef void KMap; -#define VA(k) ((ulong)(k)) -#define kmap(p) (KMap*)(((p)->pa)|KZERO) -#define kunmap(k) - -/* - * routines for things outside the PowerPC model - */ -struct PCArch -{ - char* id; - int (*ident)(void); /* this should be in the model */ - void (*reset)(void); /* this should be in the model */ - int (*serialpower)(int); /* 1 == on, 0 == off */ - int (*modempower)(int); /* 1 == on, 0 == off */ - - void (*intrinit)(void); - int (*intrenable)(int, int, Irqctl*); - - void (*clockenable)(void); -}; - -/* - * a parsed .ini line - */ -#define ISAOPTLEN 16 -#define NISAOPT 8 - -struct ISAConf { - char type[NAMELEN]; - ulong port; - ulong irq; - ulong mem; - int dma; - ulong size; - ulong freq; - uchar bus; - - int nopt; - char opt[NISAOPT][ISAOPTLEN]; -}; - -struct Map { - int size; - ulong addr; -}; - -struct RMap { - char* name; - Map* map; - Map* mapend; - - Lock; -}; - -struct -{ - Lock; - short machs; - short exiting; - short ispanic; -}active; - -extern register Mach *m; -extern register Proc *up; - -extern int predawn; diff --git a/mpc/devether.c b/mpc/devether.c deleted file mode 100644 index e4ff561f47fe44e18d75879f19fbe3840ca9306d..0000000000000000000000000000000000000000 --- a/mpc/devether.c +++ /dev/null @@ -1,451 +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 "../port/netif.h" - -#include "etherif.h" - -static Ether *etherxx[MaxEther]; - -Chan* -etherattach(char* spec) -{ - ulong ctlrno; - char *p; - Chan *chan; - - ctlrno = 0; - if(spec && *spec){ - ctlrno = strtoul(spec, &p, 0); - if((ctlrno == 0 && p == spec) || *p || (ctlrno >= MaxEther)) - error(Ebadarg); - } - if(etherxx[ctlrno] == 0) - error(Enodev); - - chan = devattach('l', spec); - chan->dev = ctlrno; - if(etherxx[ctlrno]->attach) - etherxx[ctlrno]->attach(etherxx[ctlrno]); - return chan; -} - -static int -etherwalk(Chan* chan, char* name) -{ - return netifwalk(etherxx[chan->dev], chan, name); -} - -static void -etherstat(Chan* chan, char* dp) -{ - netifstat(etherxx[chan->dev], chan, dp); -} - -static Chan* -etheropen(Chan* chan, int omode) -{ - return netifopen(etherxx[chan->dev], chan, omode); -} - -static void -ethercreate(Chan*, char*, int, ulong) -{ -} - -static void -etherclose(Chan* chan) -{ - netifclose(etherxx[chan->dev], chan); -} - -static long -etherread(Chan* chan, void* buf, long n, vlong off) -{ - Ether *ether; - ulong offset = off; - - ether = etherxx[chan->dev]; - if((chan->qid.path & CHDIR) == 0 && ether->ifstat){ - /* - * With some controllers it is necessary to reach - * into the chip to extract statistics. - */ - if(NETTYPE(chan->qid.path) == Nifstatqid) - return ether->ifstat(ether, buf, n, offset); - else if(NETTYPE(chan->qid.path) == Nstatqid) - ether->ifstat(ether, buf, 0, offset); - } - - return netifread(ether, chan, buf, n, offset); -} - -static Block* -etherbread(Chan* chan, long n, ulong offset) -{ - return netifbread(etherxx[chan->dev], chan, n, offset); -} - -static void -etherremove(Chan*) -{ -} - -static void -etherwstat(Chan* chan, char* dp) -{ - netifwstat(etherxx[chan->dev], chan, dp); -} - -static void -etherrtrace(Netfile* f, Etherpkt* pkt, int len) -{ - int i, n; - Block *bp; - - if(qwindow(f->in) <= 0) - return; - if(len > 58) - n = 58; - else - n = len; - bp = iallocb(64); - if(bp == nil) - return; - memmove(bp->wp, pkt->d, n); - i = TK2MS(MACHP(0)->ticks); - bp->wp[58] = len>>8; - bp->wp[59] = len; - bp->wp[60] = i>>24; - bp->wp[61] = i>>16; - bp->wp[62] = i>>8; - bp->wp[63] = i; - bp->wp += 64; - qpass(f->in, bp); -} - -Block* -etheriq(Ether* ether, Block* bp, int fromwire) -{ - Etherpkt *pkt; - ushort type; - int len, multi, tome, fromme; - Netfile **ep, *f, **fp, *fx; - Block *xbp; - - ether->inpackets++; - - pkt = (Etherpkt*)bp->rp; - len = BLEN(bp); - type = (pkt->type[0]<<8)|pkt->type[1]; - fx = 0; - ep = ðer->f[Ntypes]; - - multi = pkt->d[0] & 1; - /* check for valid multcast addresses */ - if(multi && memcmp(pkt->d, ether->bcast, sizeof(pkt->d)) && ether->prom == 0){ - if(!activemulti(ether, pkt->d, sizeof(pkt->d))){ - if(fromwire){ - freeb(bp); - bp = 0; - } - return bp; - } - } - - /* is it for me? */ - tome = memcmp(pkt->d, ether->ea, sizeof(pkt->d)) == 0; - fromme = memcmp(pkt->s, ether->ea, sizeof(pkt->s)) == 0; - - /* - * Multiplex the packet to all the connections which want it. - * If the packet is not to be used subsequently (fromwire != 0), - * attempt to simply pass it into one of the connections, thereby - * saving a copy of the data (usual case hopefully). - */ - for(fp = ether->f; fp < ep; fp++){ - if(f = *fp) - if(f->type == type || f->type < 0) - if(tome || multi || f->prom){ - /* Don't want to hear bridged packets */ - if(f->bridge && !fromwire && !fromme) - continue; - if(!f->headersonly){ - if(fromwire && fx == 0) - fx = f; - else if(xbp = iallocb(len)){ - memmove(xbp->wp, pkt, len); - xbp->wp += len; - qpass(f->in, xbp); - } - else - ether->soverflows++; - } - else - etherrtrace(f, pkt, len); - } - } - - if(fx){ - if(qpass(fx->in, bp) < 0) - ether->soverflows++; - return 0; - } - if(fromwire){ - freeb(bp); - return 0; - } - - return bp; -} - -static int -etheroq(Ether* ether, Block* bp) -{ - int len, loopback, s; - Etherpkt *pkt; - - ether->outpackets++; - - /* - * Check if the packet has to be placed back onto the input queue, - * i.e. if it's a loopback or broadcast packet or the interface is - * in promiscuous mode. - * If it's a loopback packet indicate to etheriq that the data isn't - * needed and return, etheriq will pass-on or free the block. - * To enable bridging to work, only packets that were originated - * by this interface are fed back. - */ - pkt = (Etherpkt*)bp->rp; - len = BLEN(bp); - loopback = memcmp(pkt->d, ether->ea, sizeof(pkt->d)) == 0; - if(loopback || memcmp(pkt->d, ether->bcast, sizeof(pkt->d)) == 0 || ether->prom){ - s = splhi(); - etheriq(ether, bp, 0); - splx(s); - } - - if(!loopback){ - qbwrite(ether->oq, bp); - ether->transmit(ether); - } else - freeb(bp); - - return len; -} - -static long -etherwrite(Chan* chan, void* buf, long n, vlong) -{ - Ether *ether; - Block *volatile bp; - - ether = etherxx[chan->dev]; - if(NETTYPE(chan->qid.path) != Ndataqid) - return netifwrite(ether, chan, buf, n); - - if(n > ETHERMAXTU) - error(Etoobig); - if(n < ETHERMINTU) - error(Etoosmall); - - bp = allocb(n); - if(waserror()){ - freeb(bp); - nexterror(); - } - memmove(bp->rp, buf, n); - memmove(bp->rp+Eaddrlen, ether->ea, Eaddrlen); - poperror(); - bp->wp += n; - - return etheroq(ether, bp); -} - -static long -etherbwrite(Chan* chan, Block* bp, ulong) -{ - Ether *ether; - long n; - - n = BLEN(bp); - ether = etherxx[chan->dev]; - if(NETTYPE(chan->qid.path) != Ndataqid){ - n = netifwrite(ether, chan, bp->rp, n); - freeb(bp); - return n; - } - - if(n > ETHERMAXTU){ - freeb(bp); - error(Ebadarg); - } - if(n < ETHERMINTU){ - freeb(bp); - error(Etoosmall); - } - - return etheroq(ether, bp); -} - -static struct { - char* type; - int (*reset)(Ether*); -} cards[MaxEther+1]; - -void -addethercard(char* t, int (*r)(Ether*)) -{ - static int ncard; - - if(ncard == MaxEther) - panic("too many ether cards"); - cards[ncard].type = t; - cards[ncard].reset = r; - ncard++; -} - -int -parseether(uchar *to, char *from) -{ - char nip[4]; - char *p; - int i; - - p = from; - for(i = 0; i < 6; i++){ - if(*p == 0) - return -1; - nip[0] = *p++; - if(*p == 0) - return -1; - nip[1] = *p++; - nip[2] = 0; - to[i] = strtoul(nip, 0, 16); - if(*p == ':') - p++; - } - return 0; -} - -static void -etherreset(void) -{ - Ether *ether; - int i, n, ctlrno; - char name[NAMELEN], buf[128]; - - for(ether = 0, ctlrno = 0; ctlrno < MaxEther; ctlrno++){ - if(ether == 0) - ether = malloc(sizeof(Ether)); - memset(ether, 0, sizeof(Ether)); - ether->ctlrno = ctlrno; - ether->tbdf = BUSUNKNOWN; - ether->mbps = 10; - if(isaconfig("ether", ctlrno, ether) == 0) - continue; -print("etherreset ether%d\n", ctlrno); - for(n = 0; cards[n].type; n++){ - if(cistrcmp(cards[n].type, ether->type)) - continue; - for(i = 0; i < ether->nopt; i++){ - if(strncmp(ether->opt[i], "ea=", 3)) - continue; - if(parseether(ether->ea, ðer->opt[i][3]) == -1) - memset(ether->ea, 0, Eaddrlen); - } - if(cards[n].reset(ether)) - break; - - /* - * IRQ2 doesn't really exist, it's used to gang the interrupt - * controllers together. A device set to IRQ2 will appear on - * the second interrupt controller as IRQ9. - */ - if(ether->irq == 2) - ether->irq = 9; - intrenable(ether->irq, ether->interrupt, ether, ether->tbdf); - - i = sprint(buf, "#l%d: %s: %dMbps port 0x%luX irq %lud", - ctlrno, ether->type, ether->mbps, ether->port, ether->irq); - if(ether->mem) - i += sprint(buf+i, " addr 0x%luX", PADDR(ether->mem)); - if(ether->size) - i += sprint(buf+i, " size 0x%luX", ether->size); - i += sprint(buf+i, ": %2.2uX%2.2uX%2.2uX%2.2uX%2.2uX%2.2uX", - ether->ea[0], ether->ea[1], ether->ea[2], - ether->ea[3], ether->ea[4], ether->ea[5]); - sprint(buf+i, "\n"); - print(buf); - - snprint(name, sizeof(name), "ether%d", ctlrno); - if(ether->mbps == 100){ - netifinit(ether, name, Ntypes, 256*1024); - if(ether->oq == 0) - ether->oq = qopen(256*1024, 1, 0, 0); - } - else{ - netifinit(ether, name, Ntypes, 65*1024); - if(ether->oq == 0) - ether->oq = qopen(65*1024, 1, 0, 0); - } - if(ether->oq == 0) - panic("etherreset %s", name); - ether->alen = Eaddrlen; - memmove(ether->addr, ether->ea, Eaddrlen); - memset(ether->bcast, 0xFF, Eaddrlen); - - etherxx[ctlrno] = ether; - ether = 0; - break; - } - } - if(ether) - free(ether); -} - -#define POLY 0xedb88320 - -/* really slow 32 bit crc for ethers */ -ulong -ethercrc(uchar *p, int len) -{ - int i, j; - ulong crc, b; - - crc = 0xffffffff; - for(i = 0; i < len; i++){ - b = *p++; - for(j = 0; j < 8; j++){ - crc = (crc>>1) ^ (((crc^b) & 1) ? POLY : 0); - b >>= 1; - } - } - return crc; -} - -Dev etherdevtab = { - 'l', - "ether", - - etherreset, - devinit, - etherattach, - devclone, - etherwalk, - etherstat, - etheropen, - ethercreate, - etherclose, - etherread, - etherbread, - etherwrite, - etherbwrite, - etherremove, - etherwstat, -}; diff --git a/mpc/devpcmcia.c b/mpc/devpcmcia.c deleted file mode 100644 index a456db4d15602021c2f1c4b7a6c625f0c24160ff..0000000000000000000000000000000000000000 --- a/mpc/devpcmcia.c +++ /dev/null @@ -1,1109 +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" - -/* - * MPC8xx PCMCIA driver - * - */ - -typedef struct Slot Slot; -typedef struct Conftab Conftab; - -enum -{ - Maxctlr= 1, - - /* pipr */ - Cvs1= 1<<15, // voltage sense 1 - Cvs2= 1<<14, // voltage sense 2 - Cwp= 1<<13, // write protect - Ccd2= 1<<12, // card detect 2 - Ccd1= 1<<11, // card detect 1 - Cbvd2= 1<<10, // battery voltage 2 - Cbvd1= 1<<9, // battery voltage 1 - Crdy= 1<<8, // ready - - /* pscr */ - Cvs1_c= 1<<15, // voltage sense 1 changed - Cvs2_c= 1<<14, // voltage sense 2 changed - Cwp_c= 1<<13, // write protect changed - Ccd2_c= 1<<12, // card detect 2 changed - Ccd1_c= 1<<11, // card detect 1 changed - Cbvd2_c= 1<<10, // battery voltage 2 changed - Cbvd1_c= 1<<9, // battery voltage 1 changed - Crdy_l= 1<<7, // ready is low - Crdy_h= 1<<6, // ready is hi - Crdy_r= 1<<5, // ready raising edge - Crdy_f= 1<<4, // ready falling edge - - /* pgcrx */ - Creset = IBIT(25), // card reset - Coe = IBIT(24), // output enable - - /* porN */ - Rport8= 0<<6, - Rport16= 1<<6, - Rmem= 0<<3, /* common memory space */ - Rattrib= 2<<3, /* attribute space */ - Rio= 3<<3, - Rdma= 4<<3, /* normal DMA */ - Rdmalx= 5<<3, /* DMA, last transaction */ - RA22_23= 6<<3, /* ``drive A22 and A23 signals on CE2 and CE1'' */ - RslotB= 1<<2, /* select slot B (always, on MPC823) */ - Rwp= 1<<1, /* write protect */ - Rvalid= 1<<0, /* region valid */ - - /* - * configuration registers - they start at an offset in attribute - * memory found in the CIS. - */ - Rconfig= 0, - Clevel= (1<<6), /* level sensitive interrupt line */ - - Maxctab= 8, /* maximum configuration table entries */ - Nmap= 4, // map entries per slot - Mshift= 12, - Mgran= (1<qid.path>>8)&0xff) -#define TYPE(c) (c->qid.path&0xff) -#define QID(s,t) (((s)<<8)|(t)) - -static void pcmciaintr(Ureg *, void *); -static void increfp(Slot *pp); -static void decrefp(Slot *pp); - -static Slot *slot; -static nslot; - -static int -pcmgen(Chan *c, Dirtab *tab, int ntab, int i, Dir *dp) -{ - int slotno; - Qid qid; - long len; - Slot *pp; - char name[NAMELEN]; - - USED(tab, ntab); - - if(i == DEVDOTDOT){ - devdir(c, c->qid, "#y", 0, eve, 0550, dp); - return 1; - } - if(i>=3*nslot) - return -1; - slotno = i/3; - pp = slot + slotno; - len = 0; - switch(i%3){ - case 0: - qid.path = QID(slotno, Qmem); - sprint(name, "pcm%dmem", slotno); - len = pp->memlen; - break; - case 1: - qid.path = QID(slotno, Qattr); - sprint(name, "pcm%dattr", slotno); - len = pp->memlen; - break; - case 2: - qid.path = QID(slotno, Qctl); - sprint(name, "pcm%dctl", slotno); - break; - } - qid.vers = 0; - devdir(c, qid, name, len, eve, 0660, dp); - return 1; -} - -/* - * set up for slot cards - */ -static void -pcmciareset(void) -{ - static int already; - int i; - IMM *io; - Slot *pp; - - if(already) - return; - already = 1; - - nslot = 2; - slot = xalloc(nslot * sizeof(Slot)); - - io = m->iomem; - - for(i=0; i<8; i++){ - io->pcmr[i].option = 0; - io->pcmr[i].base = 0; - } - - for(i=0; i<2; i++) - io->pgcr[i] = (1<<(31-PCMCIAlevel)) | (1<<(23-PCMCIAlevel)); - - for(i = 0; i < nslot; i++){ - pp = slot + i; - pp->slotno = i; - pp->memlen = 512*1024; - } - - /* 512K - slow - attr */ - io->pcmr[0].base = ISAMEM + 512*1024; - io->pcmr[0].option = (0x1a<<27) | (8<<16) | (6<<12) | (24<<7) - | Rport16 | Rattrib | Rvalid; - -// intrenable(VectorPIC+PCMCIAlevel, pcmciaintr, 0, BUSUNKNOWN); - io->pscr = 0xFEF0FEF0; /* reset status */ - io->per = 0x00800000; /* enable interrupts */ - - print("pcmcia reset\n"); -} - -static Chan* -pcmciaattach(char *spec) -{ - return devattach('y', spec); -} - -static int -pcmciawalk(Chan *c, char *name) -{ - return devwalk(c, name, 0, 0, pcmgen); -} - -static void -pcmciastat(Chan *c, char *db) -{ - devstat(c, db, 0, 0, pcmgen); -} - -static Chan* -pcmciaopen(Chan *c, int omode) -{ - if(c->qid.path == CHDIR){ - if(omode != OREAD) - error(Eperm); - } else - increfp(slot + SLOTNO(c)); - c->mode = openmode(omode); - c->flag |= COPEN; - c->offset = 0; - return c; -} - -static void -pcmciaclose(Chan *c) -{ - if(c->flag & COPEN) - if(c->qid.path != CHDIR) - decrefp(slot+SLOTNO(c)); -} - -/* a memmove using only bytes */ -static void -memmoveb(uchar *to, uchar *from, int n) -{ - while(n-- > 0) - *to++ = *from++; -} - -static long -pcmread(int slotno, int attr, void *a, long n, vlong offset) -{ - int i, len; - PCMmap *m; - ulong ka; - uchar *ac; - Slot *pp; - - pp = slot + slotno; - if(pp->memlen < offset) - return 0; - if(pp->memlen < offset + n) - n = pp->memlen - offset; - - m = 0; - if(waserror()){ - if(m) - pcmunmap(pp->slotno, m); - nexterror(); - } - - ac = a; - for(len = n; len > 0; len -= i){ - m = pcmmap(pp->slotno, offset, 0, attr); - if(m == 0) - error("can't map PCMCIA card"); - if(offset + len > m->cea) - i = m->cea - offset; - else - i = len; - ka = KZERO|(m->isa + offset - m->ca); - memmoveb(ac, (void*)ka, i); - pcmunmap(pp->slotno, m); - offset += i; - ac += i; - } - poperror(); - return n; -} - -static long -pcmciaread(Chan *c, void *a, long n, vlong offset) -{ - char *cp, *buf; - ulong p; - Slot *pp; - - p = TYPE(c); - switch(p){ - case Qdir: - return devdirread(c, a, n, 0, 0, pcmgen); - case Qmem: - case Qattr: - return pcmread(SLOTNO(c), p==Qattr, a, n, offset); - case Qctl: - buf = malloc(2048); - if(buf == nil) - error(Enomem); - if(waserror()){ - free(buf); - nexterror(); - } - cp = buf; - pp = slot + SLOTNO(c); - if(pp->occupied) - cp += sprint(cp, "occupied\n"); - if(pp->enabled) - cp += sprint(cp, "enabled\n"); - if(pp->powered) - cp += sprint(cp, "powered\n"); - if(pp->configed) - cp += sprint(cp, "configed\n"); - if(pp->wrprot) - cp += sprint(cp, "write protected\n"); - if(pp->busy) - cp += sprint(cp, "busy\n"); - cp += sprint(cp, "battery lvl %d\n", pp->battery); - cp += sprint(cp, "voltage select %d\n", pp->voltage); - cp += sprint(cp, "pipr %ulx\n", m->iomem->pipr); - cp += sprint(cp, "pcsr %ulx\n", m->iomem->pscr); - *cp = 0; - n = readstr(offset, a, n, buf); - poperror(); - free(buf); - break; - default: - n=0; - break; - } - return n; -} - -static long -pcmwrite(int dev, int attr, void *a, long n, vlong offset) -{ - int i, len; - PCMmap *m; - Slot *pp; - uchar *ac; - ulong ka; - - pp = slot + dev; - if(pp->memlen < offset) - return 0; - if(pp->memlen < offset + n) - n = pp->memlen - offset; - - m = 0; - if(waserror()){ - if(m) - pcmunmap(pp->slotno, m); - nexterror(); - } - - ac = a; - for(len = n; len > 0; len -= i){ - m = pcmmap(pp->slotno, offset, 0, attr); - if(m == 0) - error("can't map PCMCIA card"); - if(offset + len > m->cea) - i = m->cea - offset; - else - i = len; - ka = KZERO|(m->isa + offset - m->ca); - memmoveb((void*)ka, ac, i); - pcmunmap(pp->slotno, m); - offset += i; - ac += i; - } - - poperror(); - - return n; -} - -static long -pcmciawrite(Chan *c, void *a, long n, vlong offset) -{ - ulong p; - Slot *pp; - char buf[32]; - - p = TYPE(c); - switch(p){ - case Qctl: - if(n >= sizeof(buf)) - n = sizeof(buf) - 1; - strncpy(buf, a, n); - buf[n] = 0; - pp = slot + SLOTNO(c); - if(!pp->occupied) - error(Eio); - - break; - case Qmem: - case Qattr: - pp = slot + SLOTNO(c); - if(pp->occupied == 0 || pp->enabled == 0) - error(Eio); - n = pcmwrite(pp->slotno, p == Qattr, a, n, offset); - if(n < 0) - error(Eio); - break; - default: - error(Ebadusefd); - } - return n; -} - -Dev pcmciadevtab = { - 'y', - "pcmcia", - - pcmciareset, - devinit, - pcmciaattach, - devclone, - pcmciawalk, - pcmciastat, - pcmciaopen, - devcreate, - pcmciaclose, - pcmciaread, - devbread, - pcmciawrite, - devbwrite, - devremove, - devwstat, -}; - -static void -pcmciaintr(Ureg *, void *) -{ - print("pcmciaintr\n"); -} - -/* - * get a map for pc card region, return corrected len - */ -PCMmap* -pcmmap(int slotno, ulong offset, int len, int attr) -{ - PCMmap *m; - ulong e; - Slot *pp; - - pp = slot + slotno; - if(attr == 0) - panic("pcmmap"); - - /* convert offset to granularity */ - if(len <= 0) - len = 1; - e = ROUND(offset+len, Mgran); - offset &= Mmask; - len = e - offset; - USED(len); - - m = pp->mmap; - - m->ca = 0; - m->cea = 512*1024; - m->isa = ISAMEM + 512*1024; - m->len = 512*1024; - m->attr = attr; - m->ref = 1; - - return m; -} - -void -pcmunmap(int slotno, PCMmap *m) -{ - USED(slotno, m); -} - -static int -pcmio(int slotno, ISAConf *isa) -{ - uchar *p; - Slot *pp; - Conftab *ct, *et, *t; - PCMmap *mm; - int i, index, irq; - char *cp; - IMM *io; - ulong x; - - io = m->iomem; - - isa->irq = VectorPIC+PCMCIAlevel; - irq = isa->irq; - - if(slotno > nslot) - return -1; - pp = slot + slotno; - - if(!pp->occupied) - return -1; - - et = &pp->ctab[pp->nctab]; - - ct = 0; - for(i = 0; i < isa->nopt; i++){ - if(strncmp(isa->opt[i], "index=", 6)) - continue; - index = strtol(&isa->opt[i][6], &cp, 0); - if(cp == &isa->opt[i][6] || index >= pp->nctab) - return -1; - ct = &pp->ctab[index]; - } - - if(ct == 0){ - - /* assume default is right */ - if(pp->def) - ct = pp->def; - else - ct = pp->ctab; - - /* try for best match */ - if(ct->nio == 0 - || ct->io[0].start != isa->port || ((1<irqs) == 0){ - for(t = pp->ctab; t < et; t++) - if(t->nio - && t->io[0].start == isa->port - && ((1<irqs)){ - ct = t; - break; - } - } - if(ct->nio == 0 || ((1<irqs) == 0){ - for(t = pp->ctab; t < et; t++) - if(t->nio && ((1<irqs)){ - ct = t; - break; - } - } - if(ct->nio == 0){ - for(t = pp->ctab; t < et; t++) - if(t->nio){ - ct = t; - break; - } - } - } - - if(ct == et || ct->nio == 0) - return -1; - - /* enable io port map 0 */ - if(isa->port == 0) - isa->port = ct->io[0].start; - if(isa->port == 0 && ct->io[0].start == 0) - return -1; - - // setup io space - this could be better - io->pcmr[1].base = ISAMEM+isa->port; - x = (0x6<<27) | (2<<16) | (4<<12) | (8<<7) | Rio | Rvalid; -// x = (0x6<<27) | (8<<16) | (6<<12) | (24<<7) | Rio | Rvalid; - /* 16-bit data path */ - if(ct->bit16) - x |= Rport16; - else - x |= Rport8; - io->pcmr[1].option = x; - - if(pp->cpresent & (1<slotno, pp->caddr + Rconfig, 1, 1); - p = KADDR(mm->isa + pp->caddr + Rconfig - mm->ca); - - /* set configuration and interrupt type */ - x = 1; - x |= ct->index<<1; - if((ct->irqtype & 0x20) && ((ct->irqtype & 0x40)==0 || isa->irq>7)) { - x |= Clevel; - } - *p = x; - delay(5); - pcmunmap(pp->slotno, mm); - } - return 0; -} - -/* - * look for a card whose version contains 'idstr' - */ -int -pcmspecial(char *idstr, ISAConf *isa) -{ - Slot *pp; - extern char *strstr(char*, char*); - - for(pp = slot; pp < slot+nslot; pp++){ - if(pp->special) - continue; /* already taken */ - increfp(pp); - - if(pp->occupied) - if(strstr(pp->verstr, idstr)) - if(isa == 0 || pcmio(pp->slotno, isa) == 0){ - pp->special = 1; - return pp->slotno; - } - - decrefp(pp); - } - return -1; -} - -void -pcmspecialclose(int slotno) -{ - Slot *pp; - - if(slotno >= nslot) - panic("pcmspecialclose"); - pp = slot + slotno; - pp->special = 0; - decrefp(pp); -} - -static void -slotinfo(Slot *pp) -{ - ulong pipr; - - pipr = m->iomem->pipr; - if(pp->slotno == 0) - pipr >>= 16; - pp->occupied = (pipr&(Ccd1|Ccd2))==0; - pp->battery = (pipr & (Cbvd1|Cbvd2)) != 0; - pp->voltage = ((pipr & Cvs1) != 0) | (((pipr & Cvs2) != 0)<<1); - pp->wrprot = (pipr&Cwp)==0; - pp->busy = (pipr&Crdy)==0; - pp->powered = 1; // assume power is always on for the momment -} - -/* - * read and crack the card information structure enough to set - * important parameters like power - */ -static void tcfig(Slot*, int); -static void tentry(Slot*, int); -static void tvers1(Slot*, int); - -static void (*parse[256])(Slot*, int) = -{ -[0x15] tvers1, -[0x1A] tcfig, -[0x1B] tentry, -}; - -static int -readc(Slot *pp, uchar *x) -{ - if(pp->cispos >= Mgran) - return 0; - *x = pp->cisbase[2*pp->cispos]; - pp->cispos++; - return 1; -} - -static void -cisread(Slot *pp) -{ - uchar link; - uchar type; - int this, i; - PCMmap *m; - - memset(pp->ctab, 0, sizeof(pp->ctab)); - pp->caddr = 0; - pp->cpresent = 0; - pp->configed = 0; - pp->nctab = 0; - - m = pcmmap(pp->slotno, 0, 0, 1); - if(m == 0) - return; - pp->cisbase = KADDR(m->isa); - pp->cispos = 0; - - /* loop through all the tuples */ - for(i = 0; i < 1000; i++){ - this = pp->cispos; - if(readc(pp, &type) != 1) - break; - if(type == 0xFF) - break; - if(readc(pp, &link) != 1) - break; - if(parse[type]) - (*parse[type])(pp, type); - if(link == 0xff) - break; - pp->cispos = this + (2+link); - } - pcmunmap(pp->slotno, m); -} - -static ulong -getlong(Slot *pp, int size) -{ - uchar c; - int i; - ulong x; - - x = 0; - for(i = 0; i < size; i++){ - if(readc(pp, &c) != 1) - break; - x |= c<<(i*8); - } - return x; -} - -static void -tcfig(Slot *pp, int ) -{ - uchar size, rasize, rmsize; - uchar last; - - if(readc(pp, &size) != 1) - return; - rasize = (size&0x3) + 1; - rmsize = ((size>>2)&0xf) + 1; - if(readc(pp, &last) != 1) - return; - pp->caddr = getlong(pp, rasize); - pp->cpresent = getlong(pp, rmsize); -} - -/* - * enable the slot card - */ -static void -slotena(Slot *pp) -{ - IMM *io; - - if(pp->enabled) - return; - - io = m->iomem; -// io->pgcr[pp->slotno] |= Coe; - io->pgcr[pp->slotno] &= ~Coe; // active low - delay(300); - io->pgcr[pp->slotno] |= Creset; - delay(100); - io->pgcr[pp->slotno] &= ~Creset; - delay(500); - /* get configuration */ - slotinfo(pp); - if(pp->occupied){ - cisread(pp); - pp->enabled = 1; - } -} - -/* - * disable the slot card - */ -static void -slotdis(Slot *pp) -{ - pp->enabled = 0; -} - -static void -increfp(Slot *pp) -{ - lock(pp); - if(pp->ref++ == 0) - slotena(pp); - unlock(pp); -} - -static void -decrefp(Slot *pp) -{ - lock(pp); - if(pp->ref-- == 1) - slotdis(pp); - unlock(pp); -} - -static ulong vexp[8] = -{ - 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000 -}; -static ulong vmant[16] = -{ - 10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80, 90, -}; - -static ulong -microvolt(Slot *pp) -{ - uchar c; - ulong microvolts; - ulong exp; - - if(readc(pp, &c) != 1) - return 0; - exp = vexp[c&0x7]; - microvolts = vmant[(c>>3)&0xf]*exp; - while(c & 0x80){ - if(readc(pp, &c) != 1) - return 0; - switch(c){ - case 0x7d: - break; /* high impedence when sleeping */ - case 0x7e: - case 0x7f: - microvolts = 0; /* no connection */ - break; - default: - exp /= 10; - microvolts += exp*(c&0x7f); - } - } - return microvolts; -} - -static ulong -nanoamps(Slot *pp) -{ - uchar c; - ulong nanoamps; - - if(readc(pp, &c) != 1) - return 0; - nanoamps = vexp[c&0x7]*vmant[(c>>3)&0xf]; - while(c & 0x80){ - if(readc(pp, &c) != 1) - return 0; - if(c == 0x7d || c == 0x7e || c == 0x7f) - nanoamps = 0; - } - return nanoamps; -} - -/* - * only nominal voltage is important for config - */ -static ulong -power(Slot *pp) -{ - uchar feature; - ulong mv; - - mv = 0; - if(readc(pp, &feature) != 1) - return 0; - if(feature & 1) - mv = microvolt(pp); - if(feature & 2) - microvolt(pp); - if(feature & 4) - microvolt(pp); - if(feature & 8) - nanoamps(pp); - if(feature & 0x10) - nanoamps(pp); - if(feature & 0x20) - nanoamps(pp); - if(feature & 0x40) - nanoamps(pp); - return mv/1000000; -} - -static ulong mantissa[16] = -{ 0, 10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80, }; - -static ulong exponent[8] = -{ 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, }; - -static ulong -ttiming(Slot *pp, int scale) -{ - uchar unscaled; - ulong nanosecs; - - if(readc(pp, &unscaled) != 1) - return 0; - nanosecs = (mantissa[(unscaled>>3)&0xf]*exponent[unscaled&7])/10; - nanosecs = nanosecs * vexp[scale]; - return nanosecs; -} - -static void -timing(Slot *pp, Conftab *ct) -{ - uchar c, i; - - if(readc(pp, &c) != 1) - return; - i = c&0x3; - if(i != 3) - ct->maxwait = ttiming(pp, i); /* max wait */ - i = (c>>2)&0x7; - if(i != 7) - ct->readywait = ttiming(pp, i); /* max ready/busy wait */ - i = (c>>5)&0x7; - if(i != 7) - ct->otherwait = ttiming(pp, i); /* reserved wait */ -} - -static void -iospaces(Slot *pp, Conftab *ct) -{ - uchar c; - int i, nio; - - ct->nio = 0; - if(readc(pp, &c) != 1) - return; - - ct->bit16 = ((c>>5)&3) >= 2; - if(!(c & 0x80)){ - ct->io[0].start = 0; - ct->io[0].len = 1<<(c&0x1f); - ct->nio = 1; - return; - } - - if(readc(pp, &c) != 1) - return; - - nio = (c&0xf)+1; - for(i = 0; i < nio; i++){ - ct->io[i].start = getlong(pp, (c>>4)&0x3); - ct->io[0].len = getlong(pp, (c>>6)&0x3); - } - ct->nio = nio; -} - -static void -irq(Slot *pp, Conftab *ct) -{ - uchar c; - - if(readc(pp, &c) != 1) - return; - ct->irqtype = c & 0xe0; - if(c & 0x10) - ct->irqs = getlong(pp, 2); - else - ct->irqs = 1<<(c&0xf); - ct->irqs &= 0xDEB8; /* levels available to card */ -} - -static void -memspace(Slot *pp, int asize, int lsize, int host) -{ - ulong haddress, address, len; - - len = getlong(pp, lsize)*256; - address = getlong(pp, asize)*256; - USED(len, address); - if(host){ - haddress = getlong(pp, asize)*256; - USED(haddress); - } -} - -static void -tentry(Slot *pp, int ) -{ - uchar c, i, feature; - Conftab *ct; - - if(pp->nctab >= Maxctab) - return; - if(readc(pp, &c) != 1) - return; - ct = &pp->ctab[pp->nctab++]; - - /* copy from last default config */ - if(pp->def) - *ct = *pp->def; - - ct->index = c & 0x3f; - - /* is this the new default? */ - if(c & 0x40) - pp->def = ct; - - /* memory wait specified? */ - if(c & 0x80){ - if(readc(pp, &i) != 1) - return; - if(i&0x80) - ct->memwait = 1; - } - - if(readc(pp, &feature) != 1) - return; - switch(feature&0x3){ - case 1: - ct->vpp1 = ct->vpp2 = power(pp); - break; - case 2: - power(pp); - ct->vpp1 = ct->vpp2 = power(pp); - break; - case 3: - power(pp); - ct->vpp1 = power(pp); - ct->vpp2 = power(pp); - break; - default: - break; - } - if(feature&0x4) - timing(pp, ct); - if(feature&0x8) - iospaces(pp, ct); - if(feature&0x10) - irq(pp, ct); - switch((feature>>5)&0x3){ - case 1: - memspace(pp, 0, 2, 0); - break; - case 2: - memspace(pp, 2, 2, 0); - break; - case 3: - if(readc(pp, &c) != 1) - return; - for(i = 0; i <= (c&0x7); i++) - memspace(pp, (c>>5)&0x3, (c>>3)&0x3, c&0x80); - break; - } - pp->configed++; -} - -static void -tvers1(Slot *pp, int ) -{ - uchar c, major, minor; - int i; - - if(readc(pp, &major) != 1) - return; - if(readc(pp, &minor) != 1) - return; - for(i = 0; i < sizeof(pp->verstr)-1; i++){ - if(readc(pp, &c) != 1) - return; - if(c == 0) - c = '\n'; - if(c == 0xff) - break; - pp->verstr[i] = c; - } - pp->verstr[i] = 0; -} diff --git a/mpc/devrtc.c b/mpc/devrtc.c deleted file mode 100644 index 4e28c2c7d2184c6181ac76b900c8e1fba9ec8244..0000000000000000000000000000000000000000 --- a/mpc/devrtc.c +++ /dev/null @@ -1,325 +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" - -enum{ - Qrtc = 1, - Qnvram, - Qeeprom, - Qnvram2, - Qled, - - /* sccr */ - RTDIV= 1<<24, - RTSEL= 1<<23, - - /* rtcsc */ - RTE= 1<<0, - R38K= 1<<4, - - Nvoff= 0, /* where usable EEPROM lives */ - Nvsize= 256,/*128x16=256x8*/ - Nvoff2= 8*1024, /* where second usable nvram lives */ - Nvsize2= 4*1024, -}; - -static QLock rtclock; /* mutex on clock operations */ -static Lock nvrtlock; -static Lock eepromlock; - -static Dirtab rtcdir[]={ - "rtc", {Qrtc, 0}, 12, 0666, - "eeprom", {Qeeprom, 0}, Nvsize, 0664, - "nvram2", {Qnvram2, 0}, Nvsize, 0664, - "led", {Qled, 0}, 0, 0664, -}; -#define NRTC (sizeof(rtcdir)/sizeof(rtcdir[0])) - -extern void spiread(ulong addr, uchar *buf); -extern void spiwrite(ulong addr, uchar *buf); -extern void spiresult(void); -extern void spienwrite(void); -extern void spidiswrite(void); -extern void spiwriteall(uchar *buf); - -static void -rtcreset(void) -{ - IMM *io; - int n; - - io = m->iomem; - io->rtcsck = KEEP_ALIVE_KEY; - n = (RTClevel<<8)|RTE; - if(m->oscclk == 5) - n |= R38K; - io->rtcsc = n; - io->rtcsck = ~KEEP_ALIVE_KEY; -print("sccr=#%8.8lux plprcr=#%8.8lux\n", io->sccr, io->plprcr); -} - -static Chan* -rtcattach(char *spec) -{ - return devattach('r', spec); -} - -static int -rtcwalk(Chan *c, char *name) -{ - return devwalk(c, name, rtcdir, NRTC, devgen); -} - -static void -rtcstat(Chan *c, char *dp) -{ - devstat(c, dp, rtcdir, NRTC, devgen); -} - -static Chan* -rtcopen(Chan *c, int omode) -{ - omode = openmode(omode); - switch(c->qid.path){ - case Qrtc: - case Qled: - if(strcmp(up->user, eve)!=0 && omode!=OREAD) - error(Eperm); - break; - case Qeeprom: - //case Qnvram: - case Qnvram2: - if(strcmp(up->user, eve)!=0) - error(Eperm); - break; - } - return devopen(c, omode, rtcdir, NRTC, devgen); -} - -static void -rtcclose(Chan*) -{ -} - -static long -rtcread(Chan *c, void *buf, long n, vlong offset) -{ - ulong t,readaddr; - uchar spibuf[2]; - int index; - - if(c->qid.path & CHDIR) - return devdirread(c, buf, n, rtcdir, NRTC, devgen); - - switch(c->qid.path){ - case Qrtc: - t = m->iomem->rtc; - n = readnum(offset, buf, n, t, 12); - return n; - case Qeeprom: - //case Qnvram: - if(offset >= Nvsize) - return 0; - t = offset; - if(t + n > Nvsize) - n = Nvsize - t; - ilock(&eepromlock); - - /* read from eeprom through spi, two bytes a time*/ - - index=0; - if(t%2!=0){ - print("not starting from an even address\n"); - readaddr=(t-1)/2; - spiread(readaddr,spibuf); - memmove((uchar*)buf+index,(uchar *)spibuf+1,1); - index++; - readaddr++; - } - else - readaddr=t/2; - - while(index= Nvsize2) - return 0; - t = offset; - if(t + n > Nvsize2) - n = Nvsize2 - t; - ilock(&nvrtlock); - memmove(buf, (uchar*)(NVRAMMEM + Nvoff2 + t), n); - iunlock(&nvrtlock); - return n; - case Qled: - if(offset >= 5) - return 0; - t = offset; - if(t + n > 5) - n = 5 - t; - memmove(buf, "kitty" + t, n); - return n; - } - error(Egreg); - return 0; /* not reached */ -} - -static long -rtcwrite(Chan *c, void *buf, long n, vlong offset) -{ - ulong secs; - char *cp, *ep; - IMM *io; - ulong t,readaddr,writeaddr; - int index; - uchar spibuf[2]; - - 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); - /* - * set it - */ - io = ioplock(); - io->rtck = KEEP_ALIVE_KEY; - io->rtc = secs; - io->rtck = ~KEEP_ALIVE_KEY; - iopunlock(); - return n; - case Qeeprom: - //case Qnvram: - print("write %d to eeprom\n",n); - if(offset >= Nvsize) - return 0; - t = offset; - if(t + n > Nvsize) - n = Nvsize - t; - - ilock(&eepromlock); - index=0; - spienwrite(); - /*if the writing addr starts at an odd address, we need to read in - the higher byte first, combined it with the lower byte, - and then write them out - */ - if(t%2!=0){ - print("not starting from an even address\n"); - readaddr=(t-1)/2; - spiread(readaddr,spibuf); - memmove((uchar*)spibuf+1,(uchar*)buf+index,1); - //spienwrite(); - spiwrite(readaddr,spibuf); - //spidiswrite(); - index++; - writeaddr=readaddr+1; - } - else - writeaddr=t/2; - - while(index= Nvsize2) - return 0; - t = offset; - if(t + n > Nvsize2) - n = Nvsize2 - t; - ilock(&nvrtlock); - memmove((uchar*)(NVRAMMEM + Nvoff2 + offset), buf, n); - iunlock(&nvrtlock); - return n; - case Qled: - if(strncmp(buf, "on", 2) == 0) - powerupled(); - else if(strncmp(buf, "off", 3) == 0) - powerdownled(); - else - error("unknown command"); - return n; - } - error(Egreg); - return 0; /* not reached */ -} - -long -rtctime(void) -{ - return m->iomem->rtc; -} - -Dev rtcdevtab = { - 'r', - "rtc", - - rtcreset, - devinit, - rtcattach, - devclone, - rtcwalk, - rtcstat, - rtcopen, - devcreate, - rtcclose, - rtcread, - devbread, - rtcwrite, - devbwrite, - devremove, - devwstat, -}; diff --git a/mpc/devsac.c b/mpc/devsac.c deleted file mode 100644 index 804e89931750a08086df04d4ad2f5b1aa823d93f..0000000000000000000000000000000000000000 --- a/mpc/devsac.c +++ /dev/null @@ -1,528 +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" - -enum -{ - OPERM = 0x3, /* mask of all permission types in open mode */ - Nram = 512, - CacheSize = 20, - OffsetSize = 4, /* size in bytes of an offset */ -}; - -typedef struct SacPath SacPath; -typedef struct Sac Sac; -typedef struct SacHeader SacHeader; -typedef struct SacDir SacDir; -typedef struct Cache Cache; - -enum { - Magic = 0x5acf5, -}; - -struct SacDir -{ - char name[NAMELEN]; - char uid[NAMELEN]; - char gid[NAMELEN]; - uchar qid[4]; - uchar mode[4]; - uchar atime[4]; - uchar mtime[4]; - uchar length[8]; - uchar blocks[8]; -}; - -struct SacHeader -{ - uchar magic[4]; - uchar length[8]; - uchar blocksize[4]; - uchar md5[16]; -}; - - -struct Sac -{ - SacDir; - SacPath *path; -}; - -struct SacPath -{ - Ref; - SacPath *up; - long blocks; - int entry; - int nentry; -}; - -struct Cache -{ - long block; - ulong age; - uchar *data; -}; - -enum -{ - Pexec = 1, - Pwrite = 2, - Pread = 4, - Pother = 1, - Pgroup = 8, - Powner = 64, -}; - -static char *sacfs = "fs.sac"; -static uchar *data; -static int blocksize; -static Sac root; -static Cache cache[CacheSize]; -static ulong cacheage; - -static void sacdir(Chan *, SacDir*, char*); -static ulong getl(void *p); -static Sac *saccpy(Sac *s); -static Sac *saclookup(Sac *s, char *name); -static int sacdirread(Chan *, char *p, long off, long cnt); -static void loadblock(void *buf, uchar *offset, int blocksize); -static void sacfree(Sac*); - -static void -sacinit(void) -{ - SacHeader *hdr; - uchar *p; - char *s; - int i; - -print("sacinit\n"); - s = getconf("flash"); - if(s == nil) { - print("devsac: no flash file system\n"); - return; - } - - p = (uchar*)strtoul(s, 0, 0); - if(p == 0) { - print("devsac: bad address for flash file system\n"); - return; - } - data = tarlookup(p, sacfs, &i); - if(data == 0) { - print("devsac: could not find file: %s\n", sacfs); - return; - } - hdr = (SacHeader*)data; - if(getl(hdr->magic) != Magic) { -print("devsac: bad magic\n"); - return; - } - blocksize = getl(hdr->blocksize); - root.SacDir = *(SacDir*)(data + sizeof(SacHeader)); - p = malloc(CacheSize*blocksize); - if(p == nil) - error("allocating cache"); - for(i=0; iqid = (Qid){getl(root.qid), 0}; - c->dev = dev; - c->aux = saccpy(&root); - return c; -} - -static Chan* -sacclone(Chan *c, Chan *nc) -{ - nc = devclone(c, nc); - nc->aux = saccpy(c->aux); - return nc; -} - -static int -sacwalk(Chan *c, char *name) -{ - Sac *sac; - -//print("walk %s\n", name); - - isdir(c); - if(name[0]=='.' && name[1]==0) - return 1; - sac = c->aux; - sac = saclookup(sac, name); - if(sac == nil) { - strncpy(up->error, Enonexist, NAMELEN); - return 0; - } - c->aux = sac; - c->qid = (Qid){getl(sac->qid), 0}; - return 1; -} - -static Chan* -sacopen(Chan *c, int omode) -{ - ulong t, mode; - Sac *sac; - static int access[] = { 0400, 0200, 0600, 0100 }; - - sac = c->aux; - mode = getl(sac->mode); - if(strcmp(up->user, sac->uid) == 0) - mode = mode; - else if(strcmp(up->user, sac->gid) == 0) - mode = mode<<3; - else - mode = mode<<6; - - t = access[omode&3]; - if((t & mode) != t) - error(Eperm); - c->offset = 0; - c->mode = openmode(omode); - c->flag |= COPEN; - return c; -} - - -static long -sacread(Chan *c, void *a, long n, vlong voff) -{ - Sac *sac; - char *buf, *buf2; - int nn, cnt, i, j; - uchar *blocks; - long length; - long off = voff; - - buf = a; - cnt = n; - if(c->qid.path & CHDIR){ - cnt = (cnt/DIRLEN)*DIRLEN; - if(off%DIRLEN) - error("i/o error"); - return sacdirread(c, buf, off, cnt); - } - sac = c->aux; - length = getl(sac->length); - if(off >= length) - return 0; - if(cnt > length-off) - cnt = length-off; - if(cnt == 0) - return 0; - n = cnt; - blocks = data + getl(sac->blocks); - buf2 = malloc(blocksize); - while(cnt > 0) { - i = off/blocksize; - nn = blocksize; - if(nn > length-i*blocksize) - nn = length-i*blocksize; - loadblock(buf2, blocks+i*OffsetSize, nn); - j = off-i*blocksize; - nn -= j; - if(nn > cnt) - nn = cnt; - memmove(buf, buf2+j, nn); - cnt -= nn; - off += nn; - buf += nn; - } - free(buf2); - return n; -} - -static long -sacwrite(Chan *, void *, long, vlong) -{ - error(Eperm); - return 0; -} - -static void -sacclose(Chan* c) -{ - Sac *sac = c->aux; - c->aux = nil; - sacfree(sac); -} - - -static void -sacstat(Chan *c, char *db) -{ - sacdir(c, c->aux, db); -} - -static Sac* -saccpy(Sac *s) -{ - Sac *ss; - - ss = malloc(sizeof(Sac)); - *ss = *s; - if(ss->path) - incref(ss->path); - return ss; -} - -static SacPath * -sacpathalloc(SacPath *p, long blocks, int entry, int nentry) -{ - SacPath *pp = malloc(sizeof(SacPath)); - pp->ref = 1; - pp->blocks = blocks; - pp->entry = entry; - pp->nentry = nentry; - pp->up = p; - return pp; -} - -static void -sacpathfree(SacPath *p) -{ - if(p == nil) - return; - if(decref(p) > 0) - return; - sacpathfree(p->up); - free(p); -} - - -static void -sacfree(Sac *s) -{ - sacpathfree(s->path); - free(s); -} - -static void -sacdir(Chan *c, SacDir *s, char *buf) -{ - Dir dir; - - memmove(dir.name, s->name, NAMELEN); - dir.qid = (Qid){getl(s->qid), 0}; - dir.mode = getl(s->mode); - dir.length = getl(s->length); - if(dir.mode &CHDIR) - dir.length *= DIRLEN; - memmove(dir.uid, s->uid, NAMELEN); - memmove(dir.gid, s->gid, NAMELEN); - dir.atime = getl(s->atime); - dir.mtime = getl(s->mtime); - dir.type = devtab[c->type]->dc; - dir.dev = c->dev; - convD2M(&dir, buf); -} - -static void -loadblock(void *buf, uchar *offset, int blocksize) -{ - long block, n; - ulong age; - int i, j; - - block = getl(offset); - if(block < 0) { - block = -block; - cacheage++; - // age has wraped - if(cacheage == 0) { - for(i=0; ipath; - if(p == nil || p->up == nil) { - sacpathfree(p); - *s = root; - return s; - } - p = p->up; - - blocks = data + p->blocks; - per = blocksize/sizeof(SacDir); - i = p->entry/per; - n = per; - if(n > p->nentry-i*per) - n = p->nentry-i*per; - buf = malloc(per*sizeof(SacDir)); - loadblock(buf, blocks + i*OffsetSize, n*sizeof(SacDir)); - s->SacDir = buf[p->entry-i*per]; - free(buf); - incref(p); - sacpathfree(s->path); - s->path = p; - return s; -} - -static int -sacdirread(Chan *c, char *p, long off, long cnt) -{ - uchar *blocks; - SacDir *buf; - int iblock, per, i, j, n, ndir; - Sac *s; - - s = c->aux; - blocks = data + getl(s->blocks); - per = blocksize/sizeof(SacDir); - ndir = getl(s->length); - off /= DIRLEN; - cnt /= DIRLEN; - if(off >= ndir) - return 0; - if(cnt > ndir-off) - cnt = ndir-off; - iblock = -1; - buf = malloc(per*sizeof(SacDir)); - for(i=off; i ndir-j*per) - n = ndir-j*per; - loadblock(buf, blocks + j*OffsetSize, n*sizeof(SacDir)); - iblock = j; - } - j *= per; - sacdir(c, buf+i-j, p); - p += DIRLEN; - } - free(buf); - return cnt*DIRLEN; -} - -static Sac* -saclookup(Sac *s, char *name) -{ - int ndir; - int i, j, k, n, per; - uchar *blocks; - SacDir *buf; - int iblock; - SacDir *sd; - - if(strcmp(name, "..") == 0) - return sacparent(s); - blocks = data + getl(s->blocks); - per = blocksize/sizeof(SacDir); - ndir = getl(s->length); - buf = malloc(per*sizeof(SacDir)); - iblock = -1; - - // linear search - for(i=0; i ndir-j*per) - n = ndir-j*per; - loadblock(buf, blocks + j*OffsetSize, n*sizeof(SacDir)); - iblock = j; - } - j *= per; - sd = buf+i-j; - k = strcmp(name, sd->name); - if(k == 0) { - s->path = sacpathalloc(s->path, getl(s->blocks), i, ndir); - s->SacDir = *sd; - free(buf); - return s; - } - } - free(buf); - return 0; -} - -static ulong -getl(void *p) -{ - uchar *a = p; - - return (a[0]<<24) | (a[1]<<16) | (a[2]<<8) | a[3]; -} - -Dev sacdevtab = { - 'C', - "sac", - - devreset, - sacinit, - sacattach, - sacclone, - sacwalk, - sacstat, - sacopen, - devcreate, - sacclose, - sacread, - devbread, - sacwrite, - devbwrite, - devremove, - devwstat, -}; diff --git a/mpc/devuart.c b/mpc/devuart.c deleted file mode 100644 index 2261f3a819166974dbc9140e4d46889eb8a3ec6f..0000000000000000000000000000000000000000 --- a/mpc/devuart.c +++ /dev/null @@ -1,1463 +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 "../port/netif.h" - -enum { - FADS823 = 1, - - Rbufsize= 32, // read buffer size - Nuart= 3, /* max per machine (SMC1, SMC2, SCC2) */ - CTLS= 's'&037, - CTLQ= 'q'&037, -}; - -enum { - /* status bits in SCC receive buffer descriptors */ - RxBRK= 1<<7, /* break ended frame (async hdlc) */ - RxDE= 1<<7, /* DPLL error (hdlc) */ - RxBOF= 1<<6, /* BOF ended frame (async hdlc) */ - RxLG= 1<<5, /* frame too large (hdlc) */ - RxNO= 1<<4, /* bad bit alignment (hdlc) */ - RxBR= 1<<5, /* break received during frame (uart) */ - RxFR= 1<<4, /* framing error (uart) */ - RxPR= 1<<3, /* parity error (uart) */ - RxAB= 1<<3, /* frame aborted (hdlc, async hdlc) */ - RxCR= 1<<2, /* bad CRC (hdlc, async hdlc) */ - RxOV= 1<<1, /* receiver overrun (all) */ - RxCD= 1<<0, /* CD lost (all) */ - - /* hdlc-specific Rx/Tx BDs */ - TxTC= 1<<10, -}; - -/* - * SMC in UART mode - */ -enum { - USESMC2 = 0 -}; - -typedef struct Uartsmc Uartsmc; -struct Uartsmc { - IOCparam; - ushort maxidl; - ushort idlc; - ushort brkln; - ushort brkec; - ushort brkcr; - ushort rmask; -}; - -/* - * SCC2 UART parameters - */ -enum { - USESCC2 = 0, - - /* special mode bits */ - SccAHDLC = 1<<0, - SccHDLC = 1<<1, - SccIR = 1<<2, - SccPPP = 1<<3, -}; - -typedef struct Uartscc Uartscc; -struct Uartscc { - SCCparam; - uchar rsvd[8]; - ushort max_idl; - ushort idlc; - ushort brkcr; - ushort parec; - ushort frmec; - ushort nosec; - ushort brkec; - ushort brkln; - ushort uaddr1; - ushort uaddr2; - ushort rtemp; - ushort toseq; - ushort character[8]; - ushort rccm; - ushort rccrp; - ushort rlbc; -}; - -typedef struct UartAHDLC UartAHDLC; -struct UartAHDLC { - SCCparam; - ulong rsvd1; - ulong c_mask; - ulong c_pres; - ushort bof; - ushort eof; - ushort esc; - ushort rsvd2[2]; - ushort zero; - ushort rsvd3; - ushort rfthr; - ushort resvd4[2]; - ulong txctl_tbl; - ulong rxctl_tbl; - ushort nof; - ushort rsvd5; -}; - -typedef struct UartHDLC UartHDLC; -struct UartHDLC { - SCCparam; - ulong rsvd1; - ulong c_mask; - ulong c_pres; - ushort disfc; - ushort crcec; - ushort abtsc; - ushort nmarc; - ushort retrc; - ushort mflr; - ushort max_cnt; - ushort rfthr; - ushort rfcnt; - ushort hmask; - ushort haddr[4]; - ushort tmp; - ushort tmp_mb; -}; - -enum { - /* SCC events of possible interest here eventually */ - AB= 1<<9, /* autobaud detected */ - GRA= 1<<7, /* graceful stop completed */ - CCR= 1<<3, /* control character detected */ - - /* SCC, SMC common interrupt events */ - BSY= 1<<2, /* receive buffer was busy (overrun) */ - TXB= 1<<1, /* block sent */ - RXB= 1<<0, /* block received */ - - /* SCC events */ - TXE = 1<<4, /* transmission error */ - RXF = 1<<3, /* final block received */ - - /* gsmr_l */ - ENR = 2<<4, /* enable receiver */ - ENT = 1<<4, /* enable transmitter */ -}; - -typedef struct Uart Uart; -struct Uart -{ - QLock; - - Uart *elist; /* next enabled interface */ - char name[NAMELEN]; - - int x; /* index: x in SMCx or SCCx */ - int cpmid; /* eg, SCC1ID, SMC1ID */ - int opens; - uchar bpc; /* bits/char */ - uchar parity; - uchar stopb; - uchar setup; - uchar enabled; - int dev; - - ulong frame; /* framing errors */ - ulong perror; - ulong overrun; /* rcvr overruns */ - ulong crcerr; - ulong interrupts; - int baud; /* baud rate */ - - /* flow control */ - int xonoff; /* software flow control on */ - int blocked; - int modem; /* hardware flow control on */ - int cts; /* ... cts state */ - int rts; /* ... rts state */ - Rendez r; - - /* buffers */ - int (*putc)(Queue*, int); - Queue *iq; - Queue *oq; - - int rdrx; /* last buffer read */ - - Lock plock; /* for output variables */ - Block* outb; /* currently transmitting Block */ - - BD* rxb; - BD* txb; - - SMC* smc; - SCC* scc; - IOCparam* param; - ushort* brkcr; /* brkcr location in appropriate block */ - int brgc; - int mode; - Block* partial; - int loopback; -}; - -static Uart *uart[Nuart]; -static int nuart; - -struct Uartalloc { - Lock; - Uart *elist; /* list of enabled interfaces */ -} uartalloc; - -static void uartintr(Uart*, int); -static void smcuintr(Ureg*, void*); -static void sccuintr(Ureg*, void*); - -static int sccirq[] = {-1, 0x1E, 0x1D, 0x1C, 0x1B}; -static int sccid[] = {-1, SCC1ID, SCC2ID, SCC3ID, SCC4ID}; -static int sccbase[] = {-1, 0xA00, 0xA20, 0xA40, 0xA60}; -static int sccparam[] = {-1, SCC1P, SCC2P, SCC3P, SCC4P}; - -static void -uartsetbuf(Uart *up) -{ - IOCparam *p; - BD *bd; - int n; - uchar *buf; - - p = up->param; - p->rfcr = 0x18; - p->tfcr = 0x18; - p->mrblr = Rbufsize; - - // allocate buffer for receive - // the buffers need to be CACHELINESZ aligned and - // a multiple of CACHELINESZ long in order for - // the manul cache coherence to work - n = 2*ROUND(Rbufsize, CACHELINESZ)+CACHELINESZ-1; - buf = malloc(n); - buf = (uchar*)ROUND((long)buf, CACHELINESZ); - - if((bd = up->rxb) == nil){ - bd = bdalloc(2); - up->rxb = bd; - } - p->rbase = (ushort)bd; - bd->status = BDEmpty|BDInt; - bd->length = 0; - bd->addr = PADDR(buf); - bd++; - bd->status = BDEmpty|BDInt|BDWrap; - bd->length = 0; - bd->addr = PADDR(buf + ROUND(Rbufsize, CACHELINESZ)); - dcflush(buf, 2*ROUND(Rbufsize, CACHELINESZ)); - up->rdrx = 0; - - if((bd = up->txb) == nil){ - bd = bdalloc(1); - up->txb = bd; - } - p->tbase = (ushort)bd; - bd->status = BDWrap|BDInt; - bd->length = 0; - bd->addr = 0; -} - -static void -smcsetup(Uart *up) -{ - IMM *io; - Uartsmc *p; - SMC *smc; - - up->brgc = brgalloc(); - if(up->brgc < 0) - error(Eio); - - io = ioplock(); - /* step 1 */ - io->papar |= SIBIT(8)|SIBIT(9); - io->padir &= ~(SIBIT(8)|SIBIT(9)); - io->paodr &= ~(SIBIT(8)|SIBIT(9)); - - io->brgc[up->brgc] = baudgen(up->baud, 16) | BaudEnable; - - /* step 3: route clock to SMC2 */ - io->simode = (io->simode & ~0xF0000000) | (up->brgc<<28); - - iopunlock(); - - up->param = KADDR(SMC2P); - uartsetbuf(up); - - cpmop(InitRxTx, SMC2ID, 0); - - /* SMC protocol parameters */ - p = (Uartsmc*)up->param; - up->brkcr = &p->brkcr; - p->maxidl = 10; - p->brkln = 0; - p->brkec = 0; - p->brkcr = 1; - smc = IOREGS(0xA90, SMC); - smc->smce = 0xff; /* clear events */ - smc->smcm = BSY|RXB|TXB; /* enable all possible interrupts */ - up->smc = smc; - smc->smcmr = ((1+8+1-1)<<11)|(2<<4); /* 8-bit, 1 stop, no parity; UART mode */ - intrenable(VectorCPIC+3, smcuintr, up, BUSUNKNOWN); - smc->smcmr |= 3; /* enable rx/tx */ -} - -static void -smcuintr(Ureg*, void *a) -{ - Uart *up; - int events; - - up = a; - events = up->smc->smce; - eieio(); - up->smc->smce = events; - uartintr(up, events&(BSY|RXB|TXB)); -} - -static void -sccustop(void *a) -{ - Uart *up; - - up = a; - if(up->setup){ - scc2stop(up->scc); - brgfree(up->brgc); - up->brgc = -1; - up->setup = 0; - } -} - -static void -sccsetup(Uart *up) -{ - IMM *io; - SCC *scc; - ulong bg; - int i; - - scc = IOREGS(sccbase[up->x], SCC); - if(up->x == 2){ /* BUG: 823FADS-specific */ - if(scc->gsmrl & (ENT|ENR)) - scc2stop(scc); - scc->gsmrl &= ~(ENT|ENR); - scc2claim(1, up->mode&SccIR? DisableIR: DisableRS232b, sccustop, scc); - } - up->scc = scc; - if(up->brgc < 0){ - up->brgc = brgalloc(); - if(up->brgc < 0) - error(Eio); - } - bg = baudgen(up->baud, 16) | BaudEnable; - - io = ioplock(); - io->papar |= SIBIT(12)|SIBIT(13); /* enable TXD2 and RXD2 pins */ - io->padir &= ~(SIBIT(12)|SIBIT(13)); - if((up->mode & SccIR) == 0) - io->paodr |= SIBIT(12); /* TO DO: is this right? */ - else - io->paodr &= ~(SIBIT(12)|SIBIT(13)); /* TO DO: is this right? */ - - io->pbpar &= ~IBIT(18); /* disable RTS2 */ - io->pbdir &= ~IBIT(18); - if((up->mode&SccIR) == 0) - io->pcpar |= SIBIT(14); /* RTS2~ */ - else - io->pcpar &= ~SIBIT(14); - io->pcpar &= ~(SIBIT(9)|SIBIT(8)); /* CTS2~ and CD2~ */ - io->pcdir &= ~(SIBIT(14)|SIBIT(9)|SIBIT(8)); - if(FADS823 || up->mode) - io->pcso &= ~(SIBIT(9)|SIBIT(8)); /* 82xFADS: force CTS and CD on */ - else - io->pcso |= SIBIT(9)|SIBIT(8); - eieio(); - - io->brgc[up->brgc] = bg; - iopunlock(); - - sccnmsi(2, up->brgc, up->brgc); - - up->param = KADDR(sccparam[up->x]); - uartsetbuf(up); - - cpmop(InitRxTx, up->cpmid, 0); - - /* SCC protocol parameters */ - if((up->mode & (SccAHDLC|SccHDLC)) == 0){ - Uartscc *sp; - sp = (Uartscc*)up->param; - sp->max_idl = 1; - sp->brkcr = 1; - sp->parec = 0; - sp->frmec = 0; - sp->nosec = 0; - sp->brkec = 0; - sp->brkln = 0; - sp->brkec = 0; - sp->uaddr1 = 0; - sp->uaddr2 = 0; - sp->toseq = 0; - for(i=0; i<8; i++) - sp->character[i] = 0x8000; - sp->rccm = 0xC0FF; - up->brkcr = &sp->brkcr; - scc->irmode = 0; - scc->dsr = ~0; - scc->gsmrh = 1<<5; /* 8-bit oriented receive fifo */ - scc->gsmrl = 0x28004; /* UART mode */ - }else{ - UartAHDLC *hp; - hp = (UartAHDLC*)up->param; - hp->c_mask = 0x0000F0B8; - hp->c_pres = 0x0000FFFF; - if(up->mode & SccIR){ - hp->bof = 0xC0; - hp->eof = 0xC1; - //scc->dsr = 0xC0C0; - scc->dsr = 0x7E7E; - }else{ - hp->bof = 0x7E; - hp->eof = 0x7E; - scc->dsr = 0x7E7E; - } - hp->esc = 0x7D; - hp->zero = 0; - if(up->mode & SccHDLC) - hp->rfthr = 1; - else - hp->rfthr = 0; /* receive threshold of 1 doesn't work properly for Async HDLC */ - hp->txctl_tbl = 0; - hp->rxctl_tbl = 0; - if(up->mode & SccIR){ - /* low-speed infrared */ - hp->nof = 12-1; /* 12 flags */ - scc->irsip = 0; - scc->irmode = (2<<8) | 1; -// m->bcsr[1] |= DisableIR; -// microdelay(2); -// m->bcsr[1] &= ~DisableIR; /* put TFDS6000 xcvr in low-speed mode (see 4.9.2.1 in FADS manual) */ - if(up->loopback) - scc->irmode = (3<<4)|1; /* loopback */ - }else{ - scc->irmode = 0; - hp->txctl_tbl = ~0; - hp->rxctl_tbl = ~0; - hp->nof = 1-1; /* one opening flag */ - } - up->brkcr = nil; - scc->gsmrh = 1<<5; /* 8-bit oriented receive fifo */ - if(up->mode & SccHDLC) - scc->gsmrl = 0x28000; /* HDLC */ - else - scc->gsmrl = 0x28006; /* async HDLC/IrDA */ - } - scc->scce = ~0; /* clear events */ - scc->sccm = TXE|BSY|RXF|TXB|RXB; /* enable all interesting interrupts */ - intrenable(VectorCPIC+sccirq[up->x], sccuintr, up, BUSUNKNOWN); - scc->psmr = 3<<12; /* 8-bit, 1 stop, no parity; UART mode */ - if(up->loopback && (up->mode & SccIR) == 0) - scc->gsmrl |= 1<<6; /* internal loop back */ - scc->gsmrl |= ENT|ENR; /* enable rx/tx */ - if(0){ - print("gsmrl=%8.8lux gsmrh=%8.8lux dsr=%4.4ux irmode=%4.4ux\n", scc->gsmrl, scc->gsmrh, scc->dsr, scc->irmode); - for(i=0; iparam+i)); - } -} - -static void -sccuintr(Ureg*, void *a) -{ - Uart *up; - int events; - - up = a; - if(/*(m->bcsr[1] & (DisableRS232b|DisableIR)) == (DisableRS232b|DisableIR) ||*/ up->scc == nil) - return; - events = up->scc->scce; - eieio(); - up->scc->scce = events; - if(up->enabled){ - if(0) - print("#%ux|", events); - uartintr(up, events); - } -} - -static void -uartsetbaud(Uart *p, int rate) -{ - if(rate <= 0 || p->brgc < 0) - return; - p->baud = rate; - m->iomem->brgc[p->brgc] = baudgen(rate, 16) | BaudEnable; -} - -static void -uartsetmode(Uart *p) -{ - int r, clen; - - ilock(&p->plock); - clen = p->bpc; - if(p->parity == 'e' || p->parity == 'o') - clen++; - clen++; /* stop bit */ - if(p->stopb == 2) - clen++; - if(p->smc){ - r = p->smc->smcmr & 0x3F; /* keep mode, enable bits */ - r |= (clen<<11); - if(p->parity == 'e') - r |= 3<<8; - else if(p->parity == 'o') - r |= 2<<8; - if(p->stopb == 2) - r |= 1<<10; - eieio(); - p->smc->smcmr = r; - }else if(p->scc && p->mode == 0){ - r = p->scc->psmr & 0x8FE0; /* keep mode bits */ - r |= ((p->bpc-5)&3)<<12; - if(p->parity == 'e') - r |= (6<<2)|2; - else if(p->parity == 'o') - r |= (4<<2)|0; - if(p->stopb == 2) - r |= 1<<14; - eieio(); - p->scc->psmr = r; - } - iunlock(&p->plock); -} - -static void -uartparity(Uart *p, char type) -{ - ilock(&p->plock); - p->parity = type; - iunlock(&p->plock); - uartsetmode(p); -} - -/* - * set bits/character - */ -static void -uartbits(Uart *p, int bits) -{ - if(bits < 5 || bits > 14 || bits > 8 && p->scc) - error(Ebadarg); - - ilock(&p->plock); - p->bpc = bits; - iunlock(&p->plock); - uartsetmode(p); -} - - -/* - * toggle DTR - */ -static void -uartdtr(Uart *p, int n) -{ - if(p->scc == nil) - return; /* not possible */ - USED(n); /* not possible on FADS */ -} - -/* - * toggle RTS - */ -static void -uartrts(Uart *p, int n) -{ - p->rts = n; - if(p->scc == nil) - return; /* not possible */ - USED(n); /* not possible on FADS */ -} - -/* - * send break - */ -static void -uartbreak(Uart *p, int ms) -{ - if(p->brkcr == nil) - return; - - if(ms <= 0) - ms = 200; - - if(waserror()){ - ilock(&p->plock); - *p->brkcr = 1; - cpmop(RestartTx, p->cpmid, 0); - iunlock(&p->plock); - nexterror(); - } - ilock(&p->plock); - *p->brkcr = ((p->baud/(p->bpc+2))*ms+500)/1000; - cpmop(StopTx, p->cpmid, 0); - iunlock(&p->plock); - - tsleep(&up->sleep, return0, 0, ms); - - poperror(); - ilock(&p->plock); - *p->brkcr = 1; - cpmop(RestartTx, p->cpmid, 0); - iunlock(&p->plock); -} - -/* - * modem flow control on/off (rts/cts) - */ -static void -uartmflow(Uart *p, int n) -{ - if(p->scc == nil) - return; /* not possible */ - if(n){ - p->modem = 1; - /* enable status interrupts ... */ - p->scc->psmr |= 1<<15; /* enable async flow control */ - p->cts = 1; - /* could change maxidl */ - }else{ - p->modem = 0; - /* stop status interrupts ... */ - p->scc->psmr &= ~(1<<15); - p->cts = 1; - } -} - -/* - * turn on a port's interrupts. set DTR and RTS - */ -void -uartenable(Uart *p) -{ - Uart **l; - - if(p->enabled) - return; - - if(p->setup == 0){ - if(p->cpmid == SMC1ID || p->cpmid == SMC2ID) - smcsetup(p); - else - sccsetup(p); - p->setup = 1; - } - - /* - * turn on interrupts - */ - if(p->smc){ - cpmop(RestartTx, p->cpmid, 0); - p->smc->smcmr |= 3; - p->smc->smcm = BSY|TXB|RXB; - eieio(); - }else if(p->scc){ - cpmop(RestartTx, p->cpmid, 0); - p->scc->gsmrl |= ENT|ENR; - p->scc->sccm = BSY|TXB|RXB; - eieio(); - } - - /* - * turn on DTR and RTS - */ - uartdtr(p, 1); - uartrts(p, 1); - - /* - * assume we can send - */ - p->cts = 1; - p->blocked = 0; - - /* - * set baud rate to the last used - */ - uartsetbaud(p, p->baud); - - lock(&uartalloc); - for(l = &uartalloc.elist; *l; l = &(*l)->elist){ - if(*l == p) - break; - } - if(*l == 0){ - p->elist = uartalloc.elist; - uartalloc.elist = p; - } - p->enabled = 1; - unlock(&uartalloc); - p->cts = 1; - p->blocked = 0; - p->xonoff = 0; - p->enabled = 1; -} - -/* - * turn off a port's interrupts. reset DTR and RTS - */ -void -uartdisable(Uart *p) -{ - Uart **l; - - /* - * turn off interrpts - */ - if(p->smc){ - cpmop(StopTx, p->cpmid, 0); - cpmop(CloseRxBD, p->cpmid, 0); - delay(1); - p->smc->smcmr &= ~3; - eieio(); - p->smc->smcm = 0; - }else if(p->scc){ - cpmop(GracefulStopTx, p->cpmid, 0); - delay(1); - cpmop(CloseRxBD, p->cpmid, 0); - p->scc->gsmrl &= ~(ENT|ENR); - eieio(); - p->scc->sccm = 0; - } - - /* - * revert to default settings - */ - p->bpc = 8; - p->parity = 0; - p->stopb = 0; - - /* - * turn off DTR, RTS, hardware flow control & fifo's - */ - uartdtr(p, 0); - uartrts(p, 0); - uartmflow(p, 0); - p->xonoff = p->blocked = 0; - - lock(&uartalloc); - for(l = &uartalloc.elist; *l; l = &(*l)->elist){ - if(*l == p){ - *l = p->elist; - break; - } - } - p->enabled = 0; - unlock(&uartalloc); -} - -/* - * set the next output buffer going - */ -static void -txstart(Uart *p) -{ - Block *b; - int n, flags; - - - if(!p->cts || p->blocked || p->txb->status & BDReady) - return; - - if((b = p->outb) == nil){ - if((b = qget(p->oq)) == nil) - return; - if(p->mode & SccPPP && - p->mode & SccAHDLC && - BLEN(b) >= 8){ /* strip framing data */ - UartAHDLC *hp; - hp = (UartAHDLC*)p->param; - if(hp != nil && (p->mode & SccIR) == 0){ - hp->txctl_tbl = nhgetl(b->rp); - hp->rxctl_tbl = nhgetl(b->rp+4); - } - b->rp += 8; - if(0) - print("tx #%lux rx #%lux\n", hp->txctl_tbl, hp->rxctl_tbl); - } - } - n = BLEN(b); -// if(n <= 0) -// print("txstart: 0\n"); - if(p->bpc > 8){ - /* half-word alignment and length if chars are long */ - if(PADDR(b->rp)&1){ /* must be even if chars are long */ - memmove(b->base, b->rp, n); - b->rp = b->base; - b->wp = b->rp+n; - } - if(n & 1) - n++; - } - dcflush(b->rp, n); - p->outb = b; - if(n > 0xFFFF) - n = 0xFFFE; - if(p->mode & SccHDLC) - flags = BDLast | TxTC; - else if(p->mode) - flags = BDLast; - else - flags = 0; - p->txb->addr = PADDR(b->rp); - p->txb->length = n; - eieio(); - p->txb->status = (p->txb->status & BDWrap) | flags | BDReady | BDInt; - eieio(); -} - -/* - * (re)start output - */ -static void -uartkick(void *arg) -{ - Uart *p = arg; - ilock(&p->plock); - if(p->outb == nil) - txstart(p); - iunlock(&p->plock); - - if(predawn) - uartwait(); -} - -/* - * restart input if its off - */ -static void -uartflow(void *arg) -{ - Uart *p = arg; - if(p->modem) - uartrts(p, 1); -} - -static void -uartsetup(int x, int cpmid, char *name) -{ - Uart *p; - - if(nuart >= Nuart) - return; - - p = xalloc(sizeof(Uart)); - uart[nuart] = p; - strcpy(p->name, name); - p->dev = nuart; - nuart++; - p->x = x; - p->cpmid = cpmid; - p->brgc = -1; - p->mode = 0; - - /* - * set rate to 9600 baud. - * 8 bits/character. - * 1 stop bit. - * interrupts enabled. - */ - p->bpc = 8; - p->parity = 0; - p->baud = 9600; - - p->iq = qopen(4*1024, 0, uartflow, p); - p->oq = qopen(4*1024, 0, uartkick, p); -} - -/* - * called by main() to configure a duart port as a console or a mouse - */ -void -uartspecial(int port, int baud, Queue **in, Queue **out, int (*putc)(Queue*, int)) -{ - Uart *p = uart[port]; - - uartenable(p); - if(baud) - uartsetbaud(p, baud); - p->putc = putc; - if(in) - *in = p->iq; - if(out) - *out = p->oq; - p->opens++; -} - -int lastc = 'x'; - -static int -uartinput(Uart *p, BD *bd) -{ - int ch, dokick, i, l; - uchar *bp; - - dokick = 0; - if(bd->status & RxFR) - p->frame++; - if(bd->status & RxOV) - p->overrun++; - l = bd->length; - if(bd->status & RxPR){ - p->perror++; - l--; /* it's the last character */ - } - bp = KADDR(bd->addr); - if(p->xonoff || p->putc){ - for(i=0; ixonoff){ - if(ch == CTLS){ - p->blocked = 1; - cpmop(StopTx, p->cpmid, 0); - }else if (ch == CTLQ){ - p->blocked = 0; - dokick = 1; - } - /* BUG? should discard on/off char? */ - } - if(p->putc) { - (*p->putc)(p->iq, ch); - lastc = ch; - } - } - } - if(p->putc == nil && l > 0) - qproduce(p->iq, bp, l); - return dokick; -} - -static void -framedinput(Uart *p, BD *bd) -{ - Block *pkt; - int l; - - pkt = p->partial; - p->partial = nil; - if(bd->status & RxOV){ - p->overrun++; - goto Discard; - } - if(bd->status & (RxAB|RxCR|RxCD|RxLG|RxNO|RxDE|RxBOF|RxBRK)){ - if(bd->status & RxCR) - p->crcerr++; - else - p->frame++; - goto Discard; - } - if(pkt == nil){ - pkt = iallocb(1500); /* TO DO: allocate less if possible */ - if(pkt == nil) - return; - } - l = bd->length; - if(bd->status & BDLast) - l -= BLEN(pkt); /* last one gives size of entire frame */ - if(l > 0){ - if(pkt->wp+l > pkt->lim) - goto Discard; - memmove(pkt->wp, KADDR(bd->addr), l); - pkt->wp += l; - } - if(0) - print("#%ux|", bd->status); - if(bd->status & BDLast){ - if(p->mode & (SccHDLC|SccAHDLC)){ - if(BLEN(pkt) <= 2){ - p->frame++; - goto Discard; - } - pkt->wp -= 2; /* strip CRC */ - } - qpass(p->iq, pkt); - }else - p->partial = pkt; - return; - -Discard: - if(pkt != nil) - freeb(pkt); -} - -/* - * handle an interrupt to a single uart - */ -static void -uartintr(Uart *p, int events) -{ - int dokick; - BD *bd; - Block *b; - if(events & BSY) - p->overrun++; - p->interrupts++; - dokick = 0; - while(p->rxb != nil && ((bd = &p->rxb[p->rdrx])->status & BDEmpty) == 0){ - if(p->mode) - framedinput(p, bd); - else if(uartinput(p, bd)) - dokick = 1; - dcflush(KADDR(bd->addr), bd->length); - eieio(); - bd->status = (bd->status & BDWrap) | BDEmpty|BDInt; - p->rdrx ^= 1; - } - if((bd = p->txb) != nil){ - if((bd->status & BDReady) == 0){ - ilock(&p->plock); - if((b = p->outb) != nil){ - b->rp += bd->length; - if(b->rp >= b->wp){ - p->outb = nil; - freeb(b); - } - } - txstart(p); - iunlock(&p->plock); - } - } - USED(dokick); -#ifdef XXX - eieio(); - /* TO DO: modem status isn't available on 82xFADS */ - if(dokick && p->cts && !p->blocked){ - if(p->outb == nil){ - ilock(&p->plock); - txstart(p); - iunlock(&p->plock); - } - cpmop(RestartTx, p->cpmid, 0); - } else -#endif - - if (events & TXE) - cpmop(RestartTx, p->cpmid, 0); -} - -/* - * used to ensure uart console output when debugging - */ -void -uartwait(void) -{ - Uart *p = uart[0]; - int s; - - while(p && p->outb){ - s = splhi(); - if((p->txb->status & BDReady) == 0){ - p->blocked = 0; - p->cts = 1; - if(p->cpmid == SMC1ID || p->cpmid == SMC2ID) - smcuintr(nil, p); - else - sccuintr(nil, p); - } - splx(s); - } -} - -static Dirtab *uartdir; -static int ndir; - -static void -setlength(int i) -{ - Uart *p; - - if(i > 0){ - p = uart[i]; - if(p && p->opens && p->iq) - uartdir[3*i].length = qlen(p->iq); - } else for(i = 0; i < nuart; i++){ - p = uart[i]; - if(p && p->opens && p->iq) - uartdir[3*i].length = qlen(p->iq); - } - -} - -void -uartinstall(void) -{ - static int already; - - if(already) - return; - already = 1; - uartsetup(1, SMC1ID, "eia0"); -/* - int port; - char *p, *q; - if((p = getconf("console")) || (p = "0")){ - if(USESMC2) - port = strtol(p, &q, 0); - else - port = 0; - if(p != q && (port == 0 || port == 1)) - uartspecial(port, 9600, &kbdq, &printq, kbdcr2nl); - } -*/ - uartspecial(0, 9600, &kbdq, &printq, kbdcr2nl); - -// if(USESMC2) -// uartsetup(2, SMC2ID, "eia1"); -// if(USESCC2) -// uartsetup(2, SCC2ID, "eia2"); -} - -/* - * all uarts must be uartsetup() by this point or inside of uartinstall() - */ -static void -uartreset(void) -{ - int i; - Dirtab *dp; - - uartinstall(); /* architecture specific */ - - ndir = 4*nuart; - uartdir = xalloc(ndir * sizeof(Dirtab)); - dp = uartdir; - for(i = 0; i < nuart; i++){ - /* 3 directory entries per port */ - strcpy(dp->name, uart[i]->name); - dp->qid.path = NETQID(i, Ndataqid); - dp->perm = 0660; - dp++; - sprint(dp->name, "%sctl", uart[i]->name); - dp->qid.path = NETQID(i, Nctlqid); - dp->perm = 0660; - dp++; - sprint(dp->name, "%sstat", uart[i]->name); - dp->qid.path = NETQID(i, Nstatqid); - dp->perm = 0444; - dp++; - sprint(dp->name, "%smode", uart[i]->name); - dp->qid.path = NETQID(i, Ntypeqid); - dp->perm = 0660; - dp++; - } -} - -static Chan* -uartattach(char *spec) -{ - return devattach('t', spec); -} - -static int -uartwalk(Chan *c, char *name) -{ - return devwalk(c, name, uartdir, ndir, devgen); -} - -static void -uartstat(Chan *c, char *dp) -{ - if(NETTYPE(c->qid.path) == Ndataqid) - setlength(NETID(c->qid.path)); - devstat(c, dp, uartdir, ndir, devgen); -} - -static Chan* -uartopen(Chan *c, int omode) -{ - Uart *p; - - c = devopen(c, omode, uartdir, ndir, devgen); - - switch(NETTYPE(c->qid.path)){ - case Nctlqid: - case Ndataqid: - p = uart[NETID(c->qid.path)]; - qlock(p); - if(p->opens++ == 0){ - uartenable(p); - qreopen(p->iq); - qreopen(p->oq); - } - qunlock(p); - break; - } - - return c; -} - -static void -uartclose(Chan *c) -{ - Uart *p; - - if(c->qid.path & CHDIR) - return; - if((c->flag & COPEN) == 0) - return; - switch(NETTYPE(c->qid.path)){ - case Ndataqid: - case Nctlqid: - p = uart[NETID(c->qid.path)]; - qlock(p); - if(--(p->opens) == 0){ - uartdisable(p); - qclose(p->iq); - qclose(p->oq); - } - qunlock(p); - break; - } -} - -static long -uartstatus(Chan*, Uart *p, void *buf, long n, long offset) -{ - IMM *io; - char str[256]; - - sprint(str, "opens %d ferr %lud oerr %lud crcerr %lud baud %ud perr %lud intr %lud lastc = %c", p->opens, - p->frame, p->overrun, p->crcerr, p->baud, p->perror, p->interrupts, lastc); - /* TO DO: cts, dsr, ring, dcd, dtr, rts aren't all available on 82xFADS */ - io = m->iomem; - if(p->scc){ - if((io->pcdat & SIBIT(9)) == 0) - strcat(str, " cts"); - if((io->pcdat & SIBIT(8)) == 0) - strcat(str, " dcd"); - if((io->pbdat & IBIT(22)) == 0) - strcat(str, " dtr"); - }else if(p->smc){ - if((io->pbdat & IBIT(23)) == 0) - strcat(str, " dtr"); - } - strcat(str, "\n"); - return readstr(offset, buf, n, str); -} - -static long -uartread(Chan *c, void *buf, long n, vlong offset) -{ - Uart *p; - - if(c->qid.path & CHDIR){ - setlength(-1); - return devdirread(c, buf, n, uartdir, ndir, devgen); - } - - p = uart[NETID(c->qid.path)]; - switch(NETTYPE(c->qid.path)){ - case Ndataqid: - return qread(p->iq, buf, n); - case Nctlqid: - return readnum(offset, buf, n, NETID(c->qid.path), NUMSIZE); - case Nstatqid: - return uartstatus(c, p, buf, n, offset); - case Ntypeqid: - return readnum(offset, buf, n, p->mode, NUMSIZE); - } - - return 0; -} - -static Block* -uartbread(Chan *c, long n, ulong offset) -{ - if(c->qid.path & CHDIR || NETTYPE(c->qid.path) != Ndataqid) - return devbread(c, n, offset); - return qbread(uart[NETID(c->qid.path)]->iq, n); -} - -static void -uartctl(Uart *p, char *cmd) -{ - int i, n; - - /* let output drain for a while */ - for(i = 0; i < 16 && qlen(p->oq); i++) - tsleep(&p->r, (int (*)(void*))qlen, p->oq, 125); - - if(strncmp(cmd, "break", 5) == 0){ - uartbreak(p, 0); - return; - } - - n = atoi(cmd+1); - switch(*cmd){ - case 'B': - case 'b': - uartsetbaud(p, n); - break; - case 'D': - case 'd': - uartdtr(p, n); - break; - case 'f': - case 'F': - qflush(p->oq); - break; - case 'H': - case 'h': - qhangup(p->iq, 0); - qhangup(p->oq, 0); - break; - case 'L': - case 'l': - uartbits(p, n); - break; - case 'm': - case 'M': - uartmflow(p, n); - break; - case 'n': - case 'N': - qnoblock(p->oq, n); - break; - case 'P': - case 'p': - uartparity(p, *(cmd+1)); - break; - case 'K': - case 'k': - uartbreak(p, n); - break; - case 'R': - case 'r': - uartrts(p, n); - break; - case 'Q': - case 'q': - qsetlimit(p->iq, n); - qsetlimit(p->oq, n); - break; - case 'W': - case 'w': - /* obsolete */ - break; - case 'X': - case 'x': - p->xonoff = n; - break; - case 'Z': - case 'z': - p->loopback = n; - break; - } -} - -static long -uartwrite(Chan *c, void *buf, long n, vlong offset) -{ - Uart *p; - char cmd[32]; - int m, inuse; - - USED(offset); - - if(c->qid.path & CHDIR) - error(Eperm); - - p = uart[NETID(c->qid.path)]; - - switch(NETTYPE(c->qid.path)){ - case Ndataqid: - return qwrite(p->oq, buf, n); - case Nctlqid: - if(n >= sizeof(cmd)) - n = sizeof(cmd)-1; - memmove(cmd, buf, n); - cmd[n] = 0; - uartctl(p, cmd); - return n; - case Ntypeqid: - if(p->smc || p->putc) - error(Ebadarg); - if(n >= sizeof(cmd)) - n = sizeof(cmd)-1; - memmove(cmd, buf, n); - cmd[n] = 0; - m = strtoul(cmd, nil, 0); - inuse = 0; - qlock(p); - if(p->opens == 0){ - p->mode = m & 0x7F; - p->loopback = (m&0x80)!=0; - p->setup = 0; - }else - inuse = 1; - qunlock(p); - if(inuse) - error(Einuse); - return n; - } -} - -static long -uartbwrite(Chan *c, Block *bp, ulong offset) -{ - /* TO DO: better */ - return devbwrite(c, bp, offset); -} - -static void -uartwstat(Chan *c, char *dp) -{ - Dir d; - Dirtab *dt; - - if(!iseve()) - error(Eperm); - if(CHDIR & c->qid.path) - error(Eperm); - if(NETTYPE(c->qid.path) == Nstatqid) - error(Eperm); - - dt = &uartdir[3 * NETID(c->qid.path)]; - convM2D(dp, &d); - d.mode &= 0666; - dt[0].perm = dt[1].perm = d.mode; -} - -Dev uartdevtab = { - 't', - "uart", - - uartreset, - devinit, - uartattach, - devclone, - uartwalk, - uartstat, - uartopen, - devcreate, - uartclose, - uartread, - uartbread, - uartwrite, - uartbwrite, - devremove, - uartwstat, -}; diff --git a/mpc/devusb.c b/mpc/devusb.c deleted file mode 100644 index ab9a982a3f2f2ee960bedbc450e247db13838e74..0000000000000000000000000000000000000000 --- a/mpc/devusb.c +++ /dev/null @@ -1,628 +0,0 @@ -#include "u.h" -#include "lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "io.h" - -typedef struct USBparam USBparam; -struct USBparam { - ushort epptr[4]; /**/ - ulong rstate; - ulong rptr; - ushort frame_n; /**/ - ushort rbcnt; - ulong rtemp; -}; - -typedef struct EPparam EPparam; -struct EPparam { - ushort rbase; - ushort tbase; - uchar rfcr; - uchar tfcr; - ushort mrblr; - ushort rbptr; - ushort tbptr; - - ulong tstate; - ulong tptr; - ushort tcrc; - ushort tbcnt; - ulong res[2]; -}; - -enum { - Nrdre = 8, /* receive descriptor ring entries */ - Ntdre = 8, /* transmit descriptor ring entries */ - - Rbsize = 8+3, /* ring buffer size (+3 for PID+CRC16) */ - Bufsize = (Rbsize+7)&~7, /* aligned */ - - Nendpt = 4, -}; - -#define MkPID(x) (((~x&0xF)<<4)|(x&0xF)) -enum { - TokIN = MkPID(9), - TokOUT = MkPID(1), - TokSOF = MkPID(5), - TokSETUP = MkPID(0xD), - TokDATA0 = MkPID(3), - TokDATA1 = MkPID(0xB), - TokACK = MkPID(2), - TokNAK = MkPID(0xA), - TokPRE = MkPID(0xC), -}; - -enum { - BDData0= 1<<7, - BDData1= 1<<6, /* DATA1 if set, DATA0 otherwise */ - BDrxerr= 0x3F, /* various error flags */ - - BDtxcrc= 1<<10, - BDcnf= 1<<9, /* transmit confirmation */ - /* BDData0, BDData1 */ - BDNak= 1<<4, /* nak received */ - BDStall= 1<<3, /* stall received */ - BDTmo= 1<<2, /* timeout */ - BDUrun= 1<<1, /* underrun */ - - /* usmod */ - EN= 1<<0, /* enable USB */ - HOST= 1<<1, /* host mode */ - TEST= 1<<2, /* test mode */ - RESUME= 1<<6, /* generate resume condition */ - LSS= 1<<7, /* low-speed signalling */ - - /* usber */ - Freset= 1<<9, - Fidle= 1<<8, - Ftxe3= 1<<7, - Ftxe2= 1<<6, - Ftxe1= 1<<5, - Ftxe0= 1<<4, - Ftxe= Ftxe0|Ftxe1|Ftxe2|Ftxe3, - Fsof= 1<<3, - Fbsy= 1<<2, - Ftxb= 1<<1, - Frxb= 1<<0, - - /* uscom */ - FifoFill= 1<<7, - FifoFlush= 1<<6, - - /* USB commands (or'd with USBCmd) */ - StopTxEndPt = 1<<4, - RestartTxEndPt = 2<<4, - - SOFmask= (1<<11)-1, -}; - -#define USBABITS (SIBIT(14)|SIBIT(15)) -#define USBRXCBIT (SIBIT(10)|SIBIT(11)) -#define USBTXCBIT (SIBIT(6)|SIBIT(7)) - -/* - * software structures - */ -typedef struct Ctlr Ctlr; -typedef struct Endpt Endpt; - -struct Endpt { - int x; /* index in Ctlr.pts */ - int dev; /* remote device (host endpt only) */ - int endpt; /* remote endpt (host endpt only) */ - uchar addr[2]; /* crc5<<11 | endpt<<7 | dev */ - int rtog; /* DATA0 or DATA1 */ - int xtog; /* DATA0 or DATA1 */ - int rxintr; - Rendez ir; - EPparam* ep; - Ring; - - Queue* oq; - Queue* iq; - Ctlr* ctlr; -}; - -struct Ctlr { - Lock; - int init; - USB* usb; - USBparam *usbp; - Endpt pts[4]; -}; - -static Ctlr usbctlr[1]; - -static void dumpusb(Block*, char*); -static void interrupt(Ureg*, void*); -static void setupep(int, EPparam*); -static void usbtest(void); - -/* - * test driver for USB, host mode - */ -void -usbreset(void) -{ - IMM *io; - USB *usb; - USBparam *usbp; - EPparam *ep; - int brg, i; - - brg = brgalloc(); - if(brg < 0){ - print("usb: no baud rate generator is free\n"); - return; - } - - io = m->iomem; - usb = (USB*)((ulong)m->iomem+0xA00); - usbp = (USBparam*)KADDR(SCC1P); - - /* select port pins */ - io->padir &= ~USBABITS; - io->papar |= USBABITS; - io->pcpar = (io->pcpar & ~USBRXCBIT) | USBTXCBIT; - io->pcdir = (io->pcdir & ~USBRXCBIT) | USBTXCBIT; - io->pcso |= USBRXCBIT; - eieio(); - - ep = cpmalloc(Nendpt*sizeof(*ep), 32); - if(ep == nil){ - print("can't allocate USB\n"); - return; - } -print("ep=#%.8ux\n", PADDR(ep)); - - usbp->frame_n = 0; - usbp->rstate = 0; - for(i=0; iuscom = FifoFlush|i; - usb->usep[i] = 0; - usbp->epptr[i] = PADDR(ep+i) & 0xffff; - ep[i].rbase = 0; - ep[i].tbase = 0; - ep[i].rfcr = 0x10; - ep[i].tfcr = 0x10; - ep[i].mrblr = Bufsize; - ep[i].rbptr = 0; - ep[i].tbptr = 0; - ep[i].tstate = 0; - ep[i].tptr = 0; - } - - usbctlr->usb = usb; - usbctlr->usbp = usbp; - - usb->usmod = 0; - if(1) - usb->usmod = HOST; - if(0) - usb->usmod |= LSS; - if(1) - usb->usmod |= TEST|HOST; - - /* set up baud rate generator for appropriate speed */ - if(usb->usmod & LSS){ - print("USB: low speed\n"); - io->brgc[brg] = baudgen(1000000, 1) | BaudEnable; - }else - io->brgc[brg] = BaudEnable; - eieio(); - io->sicr = (io->sicr & ~(7<<3)) | (brg<<3); /* set R1CS */ - eieio(); - - usb->usep[0] = (0<<12) | (2<<8) | (1<<5); /* EPN=0, TM=bulk, multi frame */ - setupep(0, ep); - if(usb->usmod & TEST){ - print("USB: loop back mode\n"); - usb->usep[1] = (1<<12) | (0<<8); /* EPN=1, TM=control*/ - setupep(1, ep+1); - } - - m->bcsr[4] &= ~(DisableUSB|DisableUSBVcc); - if(usb->usmod & LSS) - m->bcsr[4] &= ~USBFullSpeed; - else - m->bcsr[4] |= USBFullSpeed; - if(usb->usmod & HOST && !(usb->usmod & TEST)) - usb->usadr = 0x7f; /* unused in host mode, but just in case */ - else - usb->usadr = 0; - usb->usber = ~0; /* clear events */ - intrenable(CPICvec+0x1E, interrupt, usbctlr, BUSUNKNOWN); - usb->usbmr = ~0 & ~Fidle; /* enable all events except idle */ - eieio(); - delay(12); - usb->usmod |= EN; -} - -static void -setupep(int n, EPparam *ep) -{ - Endpt *e; - - e = &usbctlr->pts[n]; - e->x = n; - e->ctlr = usbctlr; - e->xtog = TokDATA0; - if(e->oq == nil) - e->oq = qopen(8*1024, 1, 0, 0); - if(e->iq == nil) - e->iq = qopen(8*1024, 1, 0, 0); - e->ep = ep; - if(ioringinit(e, Nrdre, Ntdre, Bufsize) < 0) - panic("usbreset"); - ep->rbase = PADDR(e->rdr); - ep->rbptr = ep->rbase; - ep->tbase = PADDR(e->tdr); - ep->tbptr = ep->tbase; - eieio(); -} - -static void -epprod(Ctlr *ctlr, int epn) -{ - ctlr->usb->uscom = FifoFill | (epn&3); - eieio(); -} - -static void -txstart(Endpt *r) -{ - int len, flags; - Block *b; - BD *dre, *rdy; - - if(r->ctlr->init) - return; - rdy = nil; - while(r->ntq < Ntdre-1){ - b = qget(r->oq); - if(b == 0) - break; - - dre = &r->tdr[r->tdrh]; - if(dre->status & BDReady) - panic("txstart"); -print("Tx%d: ", r->x); dumpusb(b, "TX"); - - /* - * Give ownership of the descriptor to the chip, increment the - * software ring descriptor pointer and tell the chip to poll. - */ - flags = 0; - switch(b->rp[0]){ - case TokDATA1: - flags = BDData1|BDData0; - case TokDATA0: - flags |= BDtxcrc|BDcnf|BDReady; - flags |= BDData0; - /*b->rp++; /* skip DATAn */ - } - len = BLEN(b); - dcflush(b->rp, len); - if(r->txb[r->tdrh] != nil) - panic("usb: txstart"); - r->txb[r->tdrh] = b; - dre->addr = PADDR(b->rp); - dre->length = len; - eieio(); - dre->status = (dre->status & BDWrap) | BDInt|BDLast | flags; - if(rdy){ - rdy->status |= BDReady; - rdy = nil; - } - if((flags & BDReady) == 0) - rdy = dre; - eieio(); - r->ntq++; - r->tdrh = NEXT(r->tdrh, Ntdre); - } - if(rdy) - rdy->status |= BDReady; - eieio(); -} - -static void -transmit(Endpt *r) -{ - ilock(r->ctlr); - txstart(r); - iunlock(r->ctlr); -} - -static void -endptintr(Endpt *r, int events) -{ - int len, status; - BD *dre; - Block *b; - - if(events & Frxb || 1){ - dre = &r->rdr[r->rdrx]; - while(((status = dre->status) & BDEmpty) == 0){ - if(status & BDrxerr || (status & (BDFirst|BDLast)) != (BDFirst|BDLast)){ - print("usb rx%d: %4.4ux %d ", r->x, status, dre->length); - {uchar *p;int i; p=KADDR(dre->addr); for(i=0;i<14&&ilength; i++)print(" %.2ux", p[i]);print("\n");} - } - else{ - /* - * We have a packet. Read it into the next - * free ring buffer, if any. - */ - len = dre->length-2; /* discard CRC */ - if(len >= 0 && (b = iallocb(len)) != 0){ - memmove(b->wp, KADDR(dre->addr), len); - dcflush(KADDR(dre->addr), len); - b->wp += len; - // usbiq(ctlr, b); - print("rx%d: ", r->x); dumpusb(b, "RX"); - freeb(b); - } - } - - /* - * Finished with this descriptor, reinitialise it, - * give it back to the chip, then on to the next... - */ - dre->length = 0; - dre->status = (dre->status & BDWrap) | BDEmpty | BDInt; - eieio(); - - r->rdrx = NEXT(r->rdrx, Nrdre); - dre = &r->rdr[r->rdrx]; - r->rxintr = 1; - wakeup(&r->ir); - } - } - - /* - * Transmitter interrupt: handle anything queued for a free descriptor. - */ - if(events & (Ftxb|Ftxe0|Ftxe1)){ - lock(r->ctlr); - while(r->ntq){ - dre = &r->tdr[r->tdri]; - if(dre->status & BDReady) - break; - print("usbtx%d=#%.4x %8.8lux\n", r->x, dre->status, dre->addr); - /* TO DO: error counting */ - b = r->txb[r->tdri]; - if(b == nil) - panic("usb/interrupt: bufp"); - r->txb[r->tdri] = nil; - freeb(b); - r->ntq--; - r->tdri = NEXT(r->tdri, Ntdre); - } - txstart(r); - unlock(r->ctlr); - if(r->ntq) - epprod(r->ctlr, r->x); - } -} - -static void -interrupt(Ureg*, void *arg) -{ - int events; - Ctlr *ctlr; - USB *usb; - - ctlr = arg; - usb = ctlr->usb; - events = usb->usber; - eieio(); - usb->usber = events; - print("USB#%x\n", events); - - if(events & Fsof) - print("SOF #%ux\n", ctlr->usbp->frame_n&SOFmask); - endptintr(&ctlr->pts[0], events); - if(usb->usmod & TEST) - endptintr(&ctlr->pts[1], events); - if(events & Ftxe0) - cpmop(USBCmd|RestartTxEndPt, USBID, 0<<1); - if(events & Ftxe1) - cpmop(USBCmd|RestartTxEndPt, USBID, 1<<1); -} - -void -usbinit(void) -{ - usbreset(); -usbtest(); -} - -static void -dumpusb(Block *b, char *msg) -{ - int i; - - print("%s: %8.8lux [%d]: ", msg, (ulong)b->rp, BLEN(b)); - for(i=0; irp[i]); - print("\n"); -} - -/* - * could generate a table, but since the result can be precomputed - * per connection, it doesn't seem worthwhile. - */ -static ulong -crc5(ushort v) -{ - int i; - ulong x, poly; - - x = 0x1F; - poly = 0x14; - for(i=0; i<11; i++, v>>= 1){ - if((x^v) & 1) - x = ((x>>1)&0x0F)^poly; - else - x = ((x>>1)&0x0F); - } - return ~x&0x1F; -} - -static void -setaddr(Endpt *e, int dev, int endpt) -{ - ushort v; - - e->dev = dev; - e->endpt = endpt; - v = (e->endpt<<7) | e->dev; - v |= crc5(v) << 11; - e->addr[0] = v; - e->addr[1] = v>>8; -} - -/* - * Token packets (watch bit/byte order; it's LSB on the wire): - * - * 4 bit PID, 4 bit check - * TokIN, etc. - * 7 bit device, 4 bit end point - * 5 bit CRC5 - */ -static void -sendtoken(Endpt *e, int pid) -{ - Block *b; - - b = allocb(3); - b->wp[0] = pid; - b->wp[1] = e->addr[0]; - b->wp[2] = e->addr[1]; - b->wp += 3; - if(pid == TokDATA0 || pid == TokDATA1) - e->xtog ^= TokDATA1^TokDATA0; - else - e->xtog = TokDATA0; - qbwrite(e->oq, b); - /* wait for reply? */ -// transmit(e); -} - -static void -sendSOF(Endpt *e, int frame) -{ - Block *b; - - b = allocb(3); - b->wp[0] = TokSOF; - frame &= SOFmask; - frame |= crc5(frame) << 11; - b->wp[1] = frame; - b->wp[2] = frame>>8; - b->wp += 3; - qbwrite(e->oq, b); - transmit(e); -} - -static void -sendack(Endpt *e, int pid) -{ - Block *b; - - b = allocb(1); - b->wp[0] = pid; - b->wp += 1; - qbwrite(e->oq, b); - /* wait for reply? */ - transmit(e); -} - -static void -senddata(Endpt *e, void *buf, long n) -{ - Block *b; - - b = allocb(n+4); - b->wp += 3; /* skip 3 bytes for word alignment of data */ - b->rp = b->wp; - b->wp[0] = e->xtog; - memmove(b->wp+1, buf, n); - b->wp += n+1; - e->xtog ^= TokDATA1^TokDATA0; - qbwrite(e->oq, b); - /* wait for reply? */ - transmit(e); - epprod(e->ctlr, e->x); -} - -static int -usbinput(void *a) -{ - return ((Endpt*)a)->rxintr; -} - -static void -usbtest(void) -{ - Ctlr *ctlr; - Endpt *e, *e1; - uchar msg[8]; - int epn, testing, i; - - ctlr = usbctlr; - epn = 0; - testing = ctlr->usb->usmod & TEST; - if(testing) - epn = 1; - e = &ctlr->pts[0]; - e1 = &ctlr->pts[1]; - if((ctlr->usb->usmod & LSS) == 0) - sendSOF(e, 0); - memset(msg, 0, 8); - msg[0] = 0; - msg[1] = 8; /* set configuration */ - msg[2] = 1; - setaddr(e, 0, epn); - sendtoken(e, TokSETUP); - senddata(e, msg, 8); - if(testing){ - for(i=0; i<8; i++) - msg[i] = 0x40+i; - senddata(e1, msg, 8); - tsleep(&up->sleep, return0, 0, 3); - } - if(1){ - e->rxintr = 0; - sendtoken(e, TokIN); - transmit(e); - epprod(ctlr, 0); - tsleep(&e->ir, usbinput, e, 1000); - if(!usbinput(e)) - print("RX: none\n"); - } - sendtoken(e, TokSETUP); - msg[0] = 0x23; - msg[1] = 3; /* set feature */ - msg[2] = 8; /* port power */ - msg[3] = 0; - msg[4] = 1; /* port 1 */ - senddata(e, msg, 8); - if(testing){ - for(i=0; i<8; i++) - msg[i] = 0x60+i; - senddata(e1, msg, 8); - tsleep(&up->sleep, return0, 0, 3); - } - if(1){ - e->rxintr = 0; - sendtoken(e, TokIN); - transmit(e); - epprod(ctlr, 0); - tsleep(&e->ir, usbinput, e, 1000); - if(!usbinput(e)) - print("RX: none\n"); - } -} diff --git a/mpc/ether589.c b/mpc/ether589.c deleted file mode 100644 index d8931e2ddcc712827f6f61b23e1604100f822889..0000000000000000000000000000000000000000 --- a/mpc/ether589.c +++ /dev/null @@ -1,156 +0,0 @@ -/* - * 3C589 and 3C562. - * To do: - * check xcvr10Base2 still works (is GlobalReset necessary?). - * pull the station address out of the card space for the 3C562, - * it has no EEPROM. - */ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "io.h" -#include "../port/error.h" -#include "../port/netif.h" - -#include "etherif.h" - -enum { /* all windows */ - CommandR = 0x000E, - IntStatusR = 0x000E, -}; - -enum { /* Commands */ - GlobalReset = 0x0000, - SelectRegisterWindow = 0x0001, - RxReset = 0x0005, - TxReset = 0x000B, - AcknowledgeInterrupt = 0x000D, -}; - -enum { /* IntStatus bits */ - commandInProgress = 0x1000, -}; - -#define COMMAND(port, cmd, a) outs((port)+CommandR, ((cmd)<<11)|(a)) -#define STATUS(port) ins((port)+IntStatusR) - -enum { /* Window 0 - setup */ - Wsetup = 0x0000, - /* registers */ - ManufacturerID = 0x0000, /* 3C5[08]*, 3C59[27] */ - ProductID = 0x0002, /* 3C5[08]*, 3C59[27] */ - ConfigControl = 0x0004, /* 3C5[08]*, 3C59[27] */ - AddressConfig = 0x0006, /* 3C5[08]*, 3C59[27] */ - ResourceConfig = 0x0008, /* 3C5[08]*, 3C59[27] */ - EepromCommand = 0x000A, - EepromData = 0x000C, - /* AddressConfig Bits */ - autoSelect9 = 0x0080, - xcvrMask9 = 0xC000, - /* ConfigControl bits */ - Ena = 0x0001, - base10TAvailable9 = 0x0200, - coaxAvailable9 = 0x1000, - auiAvailable9 = 0x2000, - /* EepromCommand bits */ - EepromReadRegister = 0x0080, - EepromBusy = 0x8000, -}; - -enum { /* Window 1 - operating set */ - Wop = 0x0001, -}; - -enum { /* Window 3 - FIFO management */ - Wfifo = 0x0003, - /* registers */ - InternalConfig = 0x0000, /* 3C509B, 3C589, 3C59[0257] */ - /* InternalConfig bits */ - xcvr10BaseT = 0x00000000, - xcvr10Base2 = 0x00300000, -}; - -enum { /* Window 4 - diagnostic */ - Wdiagnostic = 0x0004, - /* registers */ - MediaStatus = 0x000A, - /* MediaStatus bits */ - linkBeatDetect = 0x0800, -}; - -extern int etherelnk3reset(Ether*); - -static int -configASIC(Ether* ether, int port, int xcvr) -{ - int x; - - /* set Window 0 configuration registers */ - COMMAND(port, SelectRegisterWindow, Wsetup); - outs(port+ConfigControl, Ena); - - /* IRQ must be 3 on 3C589/3C562 */ - outs(port + ResourceConfig, 0x3F00); - - x = ins(port+AddressConfig) & ~xcvrMask9; - x |= (xcvr>>20)<<14; - outs(port+AddressConfig, x); - - COMMAND(port, TxReset, 0); - while(STATUS(port) & commandInProgress) - ; - COMMAND(port, RxReset, 0); - while(STATUS(port) & commandInProgress) - ; - - return etherelnk3reset(ether); -} - -static int -reset(Ether* ether) -{ - int slot; - int port; - - if(ether->irq == 0) - ether->irq = 10; - if(ether->port == 0) - ether->port = 0x240; - port = ether->port; - - if((slot = pcmspecial(ether->type, ether)) < 0) - return -1; - - /* try configuring as a 10BaseT */ - if(configASIC(ether, port, xcvr10BaseT) < 0){ - pcmspecialclose(slot); - return -1; - } - delay(100); - COMMAND(port, SelectRegisterWindow, Wdiagnostic); - if(ins(port+MediaStatus) & linkBeatDetect){ - COMMAND(port, SelectRegisterWindow, Wop); - print("#l%d: xcvr10BaseT %s\n", ether->ctlrno, ether->type); - return 0; - } - - /* try configuring as a 10base2 */ - COMMAND(port, GlobalReset, 0); - if(configASIC(ether, port, xcvr10Base2) < 0){ - pcmspecialclose(slot); - return -1; - } - print("#l%d: xcvr10Base2 %s\n", ether->ctlrno, ether->type); - - return 0; -} - -void -ether589link(void) -{ - addethercard("3C589", reset); - addethercard("3C562", reset); - addethercard("589E", reset); -} diff --git a/mpc/etherelnk3.c b/mpc/etherelnk3.c deleted file mode 100644 index 81b3af667e0ff0da745c2b4ccda35f29aec5ad3b..0000000000000000000000000000000000000000 --- a/mpc/etherelnk3.c +++ /dev/null @@ -1,1863 +0,0 @@ -/* - * Etherlink III, Fast EtherLink and Fast EtherLink XL adapters. - * To do: - * check robustness in the face of errors (e.g. busmaster & rxUnderrun); - * RxEarly and busmaster; - * autoSelect; - * PCI latency timer and master enable; - * errata list; - * rewrite all initialisation; - * handle the cyclone adapter. - * - * Product ID: - * 9150 ISA 3C509[B] - * 9050 ISA 3C509[B]-TP - * 9450 ISA 3C509[B]-COMBO - * 9550 ISA 3C509[B]-TPO - * - * 9350 EISA 3C579 - * 9250 EISA 3C579-TP - * - * 5920 EISA 3C592-[TP|COMBO|TPO] - * 5970 EISA 3C597-TX Fast Etherlink 10BASE-T/100BASE-TX - * 5971 EISA 3C597-T4 Fast Etherlink 10BASE-T/100BASE-T4 - * 5972 EISA 3C597-MII Fast Etherlink 10BASE-T/MII - * - * 5900 PCI 3C590-[TP|COMBO|TPO] - * 5950 PCI 3C595-TX Fast Etherlink Shared 10BASE-T/100BASE-TX - * 5951 PCI 3C595-T4 Fast Etherlink Shared 10BASE-T/100BASE-T4 - * 5952 PCI 3C595-MII Fast Etherlink 10BASE-T/MII - * - * 9000 PCI 3C900-TPO Etherlink III XL PCI 10BASE-T - * 9001 PCI 3C900-COMBO Etherlink III XL PCI 10BASE-T/10BASE-2/AUI - * 9005 PCI 3C900B-COMBO Etherlink III XL PCI 10BASE-T/10BASE-2/AUI - * 9050 PCI 3C905-TX Fast Etherlink XL Shared 10BASE-T/100BASE-TX - * 9051 PCI 3C905-T4 Fast Etherlink Shared 10BASE-T/100BASE-T4 - * 9055 PCI 3C905B-TX Fast Etherlink Shared 10BASE-T/100BASE-TX - * - * 9058 PCMCIA 3C589[B]-[TP|COMBO] - * - * 627C MCA 3C529 - * 627D MCA 3C529-TP - */ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "io.h" -#include "../port/error.h" -#include "../port/netif.h" - -#include "etherif.h" - -#define XCVRDEBUG if(0)print - -enum { - IDport = 0x0110, /* anywhere between 0x0100 and 0x01F0 */ -}; - -enum { /* all windows */ - CommandR = 0x000E, - IntStatusR = 0x000E, -}; - -enum { /* Commands */ - GlobalReset = 0x0000, - SelectRegisterWindow = 0x0001, - EnableDcConverter = 0x0002, - RxDisable = 0x0003, - RxEnable = 0x0004, - RxReset = 0x0005, - Stall = 0x0006, /* 3C90x */ - TxDone = 0x0007, - RxDiscard = 0x0008, - TxEnable = 0x0009, - TxDisable = 0x000A, - TxReset = 0x000B, - RequestInterrupt = 0x000C, - AcknowledgeInterrupt = 0x000D, - SetInterruptEnable = 0x000E, - SetIndicationEnable = 0x000F, /* SetReadZeroMask */ - SetRxFilter = 0x0010, - SetRxEarlyThresh = 0x0011, - SetTxAvailableThresh = 0x0012, - SetTxStartThresh = 0x0013, - StartDma = 0x0014, /* initiate busmaster operation */ - StatisticsEnable = 0x0015, - StatisticsDisable = 0x0016, - DisableDcConverter = 0x0017, - SetTxReclaimThresh = 0x0018, /* PIO-only adapters */ - PowerUp = 0x001B, /* not all adapters */ - PowerDownFull = 0x001C, /* not all adapters */ - PowerAuto = 0x001D, /* not all adapters */ -}; - -enum { /* (Global|Rx|Tx)Reset command bits */ - tpAuiReset = 0x0001, /* 10BaseT and AUI transceivers */ - endecReset = 0x0002, /* internal Ethernet encoder/decoder */ - networkReset = 0x0004, /* network interface logic */ - fifoReset = 0x0008, /* FIFO control logic */ - aismReset = 0x0010, /* autoinitialise state-machine logic */ - hostReset = 0x0020, /* bus interface logic */ - dmaReset = 0x0040, /* bus master logic */ - vcoReset = 0x0080, /* on-board 10Mbps VCO */ - updnReset = 0x0100, /* upload/download (Rx/TX) logic */ - - resetMask = 0x01FF, -}; - -enum { /* Stall command bits */ - upStall = 0x0000, - upUnStall = 0x0001, - dnStall = 0x0002, - dnUnStall = 0x0003, -}; - -enum { /* SetRxFilter command bits */ - receiveIndividual = 0x0001, /* match station address */ - receiveMulticast = 0x0002, - receiveBroadcast = 0x0004, - receiveAllFrames = 0x0008, /* promiscuous */ -}; - -enum { /* StartDma command bits */ - Upload = 0x0000, /* transfer data from adapter to memory */ - Download = 0x0001, /* transfer data from memory to adapter */ -}; - -enum { /* IntStatus bits */ - interruptLatch = 0x0001, - hostError = 0x0002, /* Adapter Failure */ - txComplete = 0x0004, - txAvailable = 0x0008, - rxComplete = 0x0010, - rxEarly = 0x0020, - intRequested = 0x0040, - updateStats = 0x0080, - transferInt = 0x0100, /* Bus Master Transfer Complete */ - dnComplete = 0x0200, - upComplete = 0x0400, - busMasterInProgress = 0x0800, - commandInProgress = 0x1000, - - interruptMask = 0x07FE, -}; - -#define COMMAND(port, cmd, a) outs((port)+CommandR, ((cmd)<<11)|(a)) -#define STATUS(port) ins((port)+IntStatusR) - -enum { /* Window 0 - setup */ - Wsetup = 0x0000, - /* registers */ - ManufacturerID = 0x0000, /* 3C5[08]*, 3C59[27] */ - ProductID = 0x0002, /* 3C5[08]*, 3C59[27] */ - ConfigControl = 0x0004, /* 3C5[08]*, 3C59[27] */ - AddressConfig = 0x0006, /* 3C5[08]*, 3C59[27] */ - ResourceConfig = 0x0008, /* 3C5[08]*, 3C59[27] */ - EepromCommand = 0x000A, - EepromData = 0x000C, - /* AddressConfig Bits */ - autoSelect9 = 0x0080, - xcvrMask9 = 0xC000, - /* ConfigControl bits */ - Ena = 0x0001, - base10TAvailable9 = 0x0200, - coaxAvailable9 = 0x1000, - auiAvailable9 = 0x2000, - /* EepromCommand bits */ - EepromReadRegister = 0x0080, - EepromBusy = 0x8000, -}; - -#define EEPROMCMD(port, cmd, a) outs((port)+EepromCommand, (cmd)|(a)) -#define EEPROMBUSY(port) (ins((port)+EepromCommand) & EepromBusy) -#define EEPROMDATA(port) ins((port)+EepromData) - -enum { /* Window 1 - operating set */ - Wop = 0x0001, - /* registers */ - Fifo = 0x0000, - RxError = 0x0004, /* 3C59[0257] only */ - RxStatus = 0x0008, - Timer = 0x000A, - TxStatus = 0x000B, - TxFree = 0x000C, - /* RxError bits */ - rxOverrun = 0x0001, - runtFrame = 0x0002, - alignmentError = 0x0004, /* Framing */ - crcError = 0x0008, - oversizedFrame = 0x0010, - dribbleBits = 0x0080, - /* RxStatus bits */ - rxBytes = 0x1FFF, /* 3C59[0257] mask */ - rxBytes9 = 0x07FF, /* 3C5[078]9 mask */ - rxError9 = 0x3800, /* 3C5[078]9 error mask */ - rxOverrun9 = 0x0000, - oversizedFrame9 = 0x0800, - dribbleBits9 = 0x1000, - runtFrame9 = 0x1800, - alignmentError9 = 0x2000, /* Framing */ - crcError9 = 0x2800, - rxError = 0x4000, - rxIncomplete = 0x8000, - /* TxStatus Bits */ - txStatusOverflow = 0x0004, - maxCollisions = 0x0008, - txUnderrun = 0x0010, - txJabber = 0x0020, - interruptRequested = 0x0040, - txStatusComplete = 0x0080, -}; - -enum { /* Window 2 - station address */ - Wstation = 0x0002, - - ResetOp905B = 0x000C, -}; - -enum { /* Window 3 - FIFO management */ - Wfifo = 0x0003, - /* registers */ - InternalConfig = 0x0000, /* 3C509B, 3C589, 3C59[0257] */ - OtherInt = 0x0004, /* 3C59[0257] */ - RomControl = 0x0006, /* 3C509B, 3C59[27] */ - MacControl = 0x0006, /* 3C59[0257] */ - ResetOptions = 0x0008, /* 3C59[0257] */ - MediaOptions = 0x0008, /* 3C905B */ - RxFree = 0x000A, - /* InternalConfig bits */ - disableBadSsdDetect = 0x00000100, - ramLocation = 0x00000200, /* 0 external, 1 internal */ - ramPartition5to3 = 0x00000000, - ramPartition3to1 = 0x00010000, - ramPartition1to1 = 0x00020000, - ramPartition3to5 = 0x00030000, - ramPartitionMask = 0x00030000, - xcvr10BaseT = 0x00000000, - xcvrAui = 0x00100000, /* 10BASE5 */ - xcvr10Base2 = 0x00300000, - xcvr100BaseTX = 0x00400000, - xcvr100BaseFX = 0x00500000, - xcvrMii = 0x00600000, - xcvrMask = 0x00700000, - autoSelect = 0x01000000, - /* MacControl bits */ - deferExtendEnable = 0x0001, - deferTimerSelect = 0x001E, /* mask */ - fullDuplexEnable = 0x0020, - allowLargePackets = 0x0040, - extendAfterCollision = 0x0080, /* 3C90xB */ - flowControlEnable = 0x0100, /* 3C90xB */ - vltEnable = 0x0200, /* 3C90xB */ - /* ResetOptions bits */ - baseT4Available = 0x0001, - baseTXAvailable = 0x0002, - baseFXAvailable = 0x0004, - base10TAvailable = 0x0008, - coaxAvailable = 0x0010, - auiAvailable = 0x0020, - miiConnector = 0x0040, -}; - -enum { /* Window 4 - diagnostic */ - Wdiagnostic = 0x0004, - /* registers */ - VcoDiagnostic = 0x0002, - FifoDiagnostic = 0x0004, - NetworkDiagnostic = 0x0006, - PhysicalMgmt = 0x0008, - MediaStatus = 0x000A, - BadSSD = 0x000C, - UpperBytesOk = 0x000D, - /* FifoDiagnostic bits */ - txOverrun = 0x0400, - rxUnderrun = 0x2000, - receiving = 0x8000, - /* PhysicalMgmt bits */ - mgmtClk = 0x0001, - mgmtData = 0x0002, - mgmtDir = 0x0004, - cat5LinkTestDefeat = 0x8000, - /* MediaStatus bits */ - dataRate100 = 0x0002, - crcStripDisable = 0x0004, - enableSqeStats = 0x0008, - collisionDetect = 0x0010, - carrierSense = 0x0020, - jabberGuardEnable = 0x0040, - linkBeatEnable = 0x0080, - jabberDetect = 0x0200, - polarityReversed = 0x0400, - linkBeatDetect = 0x0800, - txInProg = 0x1000, - dcConverterEnabled = 0x4000, - auiDisable = 0x8000, /* 10BaseT transceiver selected */ -}; - -enum { /* Window 5 - internal state */ - Wstate = 0x0005, - /* registers */ - TxStartThresh = 0x0000, - TxAvailableThresh = 0x0002, - RxEarlyThresh = 0x0006, - RxFilter = 0x0008, - InterruptEnable = 0x000A, - IndicationEnable = 0x000C, -}; - -enum { /* Window 6 - statistics */ - Wstatistics = 0x0006, - /* registers */ - CarrierLost = 0x0000, - SqeErrors = 0x0001, - MultipleColls = 0x0002, - SingleCollFrames = 0x0003, - LateCollisions = 0x0004, - RxOverruns = 0x0005, - FramesXmittedOk = 0x0006, - FramesRcvdOk = 0x0007, - FramesDeferred = 0x0008, - UpperFramesOk = 0x0009, - BytesRcvdOk = 0x000A, - BytesXmittedOk = 0x000C, -}; - -enum { /* Window 7 - bus master operations */ - Wmaster = 0x0007, - /* registers */ - MasterAddress = 0x0000, - MasterLen = 0x0006, - MasterStatus = 0x000C, - /* MasterStatus bits */ - masterAbort = 0x0001, - targetAbort = 0x0002, - targetRetry = 0x0004, - targetDisc = 0x0008, - masterDownload = 0x1000, - masterUpload = 0x4000, - masterInProgress = 0x8000, - - masterMask = 0xD00F, -}; - -enum { /* 3C90x extended register set */ - PktStatus = 0x0020, /* 32-bits */ - DnListPtr = 0x0024, /* 32-bits, 8-byte aligned */ - FragAddr = 0x0028, /* 32-bits */ - FragLen = 0x002C, /* 16-bits */ - ListOffset = 0x002E, /* 8-bits */ - TxFreeThresh = 0x002F, /* 8-bits */ - UpPktStatus = 0x0030, /* 32-bits */ - FreeTimer = 0x0034, /* 16-bits */ - UpListPtr = 0x0038, /* 32-bits, 8-byte aligned */ - - /* PktStatus bits */ - fragLast = 0x00000001, - dnCmplReq = 0x00000002, - dnStalled = 0x00000004, - upCompleteX = 0x00000008, - dnCompleteX = 0x00000010, - upRxEarlyEnable = 0x00000020, - armCountdown = 0x00000040, - dnInProg = 0x00000080, - counterSpeed = 0x00000010, /* 0 3.2uS, 1 320nS */ - countdownMode = 0x00000020, - /* UpPktStatus bits (dpd->control) */ - upPktLenMask = 0x00001FFF, - upStalled = 0x00002000, - upError = 0x00004000, - upPktComplete = 0x00008000, - upOverrun = 0x00010000, /* RxError<<16 */ - upRuntFrame = 0x00020000, - upAlignmentError = 0x00040000, - upCRCError = 0x00080000, - upOversizedFrame = 0x00100000, - upDribbleBits = 0x00800000, - upOverflow = 0x01000000, - - dnIndicate = 0x80000000, /* FrameStartHeader (dpd->control) */ - - updnLastFrag = 0x80000000, /* (dpd->len) */ - - Nup = 32, - Ndn = 64, -}; - -/* - * Up/Dn Packet Descriptors. - * The hardware info (np, control, addr, len) must be 8-byte aligned - * and this structure size must be a multiple of 8. - */ -typedef struct Pd Pd; -typedef struct Pd { - ulong np; /* next pointer */ - ulong control; /* FSH or UpPktStatus */ - ulong addr; - ulong len; - - Pd* next; - Block* bp; -} Pd; - -typedef struct { - Lock wlock; /* window access */ - - int attached; - int busmaster; - Block* rbp; /* receive buffer */ - - Block* txbp; /* FIFO -based transmission */ - int txthreshold; - int txbusy; - - int nup; /* full-busmaster -based reception */ - void* upbase; - Pd* upr; - Pd* uphead; - - int ndn; /* full-busmaster -based transmission */ - void* dnbase; - Pd* dnr; - Pd* dnhead; - Pd* dntail; - int dnq; - - long interrupts; /* statistics */ - long timer; - long stats[BytesRcvdOk+3]; - - int upqmax; - int upqmaxhw; - ulong upinterrupts; - ulong upqueued; - ulong upstalls; - int dnqmax; - int dnqmaxhw; - ulong dninterrupts; - ulong dnqueued; - - int xcvr; /* transceiver type */ - int rxstatus9; /* old-style RxStatus register */ - int rxearly; /* RxEarlyThreshold */ - int ts; /* threshold shift */ - int upenabled; - int dnenabled; -} Ctlr; - -static void -init905(Ctlr* ctlr) -{ - Block *bp; - Pd *pd, *prev; - - /* - * Create rings for the receive and transmit sides. - * Take care with alignment: - * make sure ring base is 8-byte aligned; - * make sure each entry is 8-byte aligned. - */ - ctlr->upbase = malloc((ctlr->nup+1)*sizeof(Pd)); - ctlr->upr = (Pd*)ROUNDUP((ulong)ctlr->upbase, 8); - - prev = ctlr->upr; - for(pd = &ctlr->upr[ctlr->nup-1]; pd >= ctlr->upr; pd--){ - pd->np = PADDR(&prev->np); - pd->control = 0; - bp = iallocb(sizeof(Etherpkt)); - if(bp == nil) - panic("can't allocate ethernet receive ring"); - pd->addr = PADDR(bp->rp); - pd->len = updnLastFrag|sizeof(Etherpkt); - - pd->next = prev; - prev = pd; - pd->bp = bp; - } - ctlr->uphead = ctlr->upr; - - ctlr->dnbase = malloc((ctlr->ndn+1)*sizeof(Pd)); - ctlr->dnr = (Pd*)ROUNDUP((ulong)ctlr->dnbase, 8); - - prev = ctlr->dnr; - for(pd = &ctlr->dnr[ctlr->ndn-1]; pd >= ctlr->dnr; pd--){ - pd->next = prev; - prev = pd; - } - ctlr->dnhead = ctlr->dnr; - ctlr->dntail = ctlr->dnr; - ctlr->dnq = 0; -} - -static Block* -rbpalloc(Block* (*f)(int)) -{ - Block *bp; - ulong addr; - - /* - * The receive buffers must be on a 32-byte - * boundary for EISA busmastering. - */ - if(bp = f(ROUNDUP(sizeof(Etherpkt), 4) + 31)){ - addr = (ulong)bp->base; - addr = ROUNDUP(addr, 32); - bp->rp = (uchar*)addr; - } - - return bp; -} - -static uchar* -startdma(Ether* ether, ulong address) -{ - int port, status, w; - uchar *wp; - - port = ether->port; - - w = (STATUS(port)>>13) & 0x07; - COMMAND(port, SelectRegisterWindow, Wmaster); - - wp = KADDR(inl(port+MasterAddress)); - status = ins(port+MasterStatus); - if(status & (masterInProgress|targetAbort|masterAbort)) - print("#l%d: BM status 0x%uX\n", ether->ctlrno, status); - outs(port+MasterStatus, masterMask); - outl(port+MasterAddress, address); - outs(port+MasterLen, sizeof(Etherpkt)); - COMMAND(port, StartDma, Upload); - - COMMAND(port, SelectRegisterWindow, w); - return wp; -} - -static void -promiscuous(void* arg, int on) -{ - int filter, port; - Ether *ether; - - ether = (Ether*)arg; - port = ether->port; - - filter = receiveBroadcast|receiveIndividual; - if(ether->nmaddr) - filter |= receiveMulticast; - if(on) - filter |= receiveAllFrames; - COMMAND(port, SetRxFilter, filter); -} - -static void -multicast(void* arg, uchar *addr, int on) -{ - int filter, port; - Ether *ether; - - USED(addr, on); - - ether = (Ether*)arg; - port = ether->port; - - filter = receiveBroadcast|receiveIndividual; - if(ether->nmaddr) - filter |= receiveMulticast; - if(ether->prom) - filter |= receiveAllFrames; - COMMAND(port, SetRxFilter, filter); -} - -static void -attach(Ether* ether) -{ - int port, x; - Ctlr *ctlr; - - ctlr = ether->ctlr; - ilock(&ctlr->wlock); - if(ctlr->attached){ - iunlock(&ctlr->wlock); - return; - } - - port = ether->port; - - /* - * Set the receiver packet filter for this and broadcast addresses, - * set the interrupt masks for all interrupts, enable the receiver - * and transmitter. - */ - promiscuous(ether, ether->prom); - - x = interruptMask; - if(ctlr->busmaster == 1) - x &= ~(rxEarly|rxComplete); - else{ - if(ctlr->dnenabled) - x &= ~transferInt; - if(ctlr->upenabled) - x &= ~(rxEarly|rxComplete); - } - COMMAND(port, SetIndicationEnable, x); - COMMAND(port, SetInterruptEnable, x); - - COMMAND(port, RxEnable, 0); - COMMAND(port, TxEnable, 0); - - /* - * Prime the busmaster channel for receiving directly into a - * receive packet buffer if necessary. - */ - if(ctlr->busmaster == 1) - startdma(ether, PADDR(ctlr->rbp->rp)); - else{ - if(ctlr->upenabled) - outl(port+UpListPtr, PADDR(&ctlr->uphead->np)); - } - - ctlr->attached = 1; - iunlock(&ctlr->wlock); -} - -static void -statistics(Ether* ether) -{ - int port, i, u, w; - Ctlr *ctlr; - - port = ether->port; - ctlr = ether->ctlr; - - /* - * 3C59[27] require a read between a PIO write and - * reading a statistics register. - */ - w = (STATUS(port)>>13) & 0x07; - COMMAND(port, SelectRegisterWindow, Wstatistics); - STATUS(port); - - for(i = 0; i < UpperFramesOk; i++) - ctlr->stats[i] += inb(port+i) & 0xFF; - u = inb(port+UpperFramesOk) & 0xFF; - ctlr->stats[FramesXmittedOk] += (u & 0x30)<<4; - ctlr->stats[FramesRcvdOk] += (u & 0x03)<<8; - ctlr->stats[BytesRcvdOk] += ins(port+BytesRcvdOk) & 0xFFFF; - ctlr->stats[BytesRcvdOk+1] += ins(port+BytesXmittedOk) & 0xFFFF; - - switch(ctlr->xcvr){ - - case xcvrMii: - case xcvr100BaseTX: - case xcvr100BaseFX: - COMMAND(port, SelectRegisterWindow, Wdiagnostic); - STATUS(port); - ctlr->stats[BytesRcvdOk+2] += inb(port+BadSSD); - break; - } - - COMMAND(port, SelectRegisterWindow, w); -} - -static void -txstart(Ether* ether) -{ - int port, len; - Ctlr *ctlr; - Block *bp; - - port = ether->port; - ctlr = ether->ctlr; - - /* - * Attempt to top-up the transmit FIFO. If there's room simply - * stuff in the packet length (unpadded to a dword boundary), the - * packet data (padded) and remove the packet from the queue. - * If there's no room post an interrupt for when there is. - * This routine is called both from the top level and from interrupt - * level and expects to be called with ctlr->wlock already locked - * and the correct register window (Wop) in place. - */ - for(;;){ - if(ctlr->txbp){ - bp = ctlr->txbp; - ctlr->txbp = 0; - } - else{ - bp = qget(ether->oq); - if(bp == nil) - break; - } - - len = ROUNDUP(BLEN(bp), 4); - if(len+4 <= ins(port+TxFree)){ - outl(port+Fifo, BLEN(bp)); - outsl(port+Fifo, bp->rp, len/4); - - freeb(bp); - - ether->outpackets++; - } - else{ - ctlr->txbp = bp; - if(ctlr->txbusy == 0){ - ctlr->txbusy = 1; - COMMAND(port, SetTxAvailableThresh, len>>ctlr->ts); - } - break; - } - } -} - -static void -txstart905(Ether* ether) -{ - Ctlr *ctlr; - int port, stalled, timeo; - Block *bp; - Pd *pd; - - ctlr = ether->ctlr; - port = ether->port; - /* - * Free any completed packets. - */ - pd = ctlr->dntail; - while(ctlr->dnq){ - if(PADDR(&pd->np) == inl(port+DnListPtr)) - break; - if(pd->bp){ - freeb(pd->bp); - pd->bp = nil; - } - ctlr->dnq--; - pd = pd->next; - } - ctlr->dntail = pd; - - stalled = 0; - while(ctlr->dnq < (ctlr->ndn-1)){ - bp = qget(ether->oq); - if(bp == nil) - break; - - pd = ctlr->dnhead->next; - pd->np = 0; - pd->control = dnIndicate|BLEN(bp); - pd->addr = PADDR(bp->rp); - pd->len = updnLastFrag|BLEN(bp); - pd->bp = bp; - - if(stalled == 0 && ctlr->dnq && inl(port+DnListPtr)){ - COMMAND(port, Stall, dnStall); - for(timeo = 100; (STATUS(port) & commandInProgress) && timeo; timeo--) - ; - if(timeo == 0) - print("#l%d: dnstall %d\n", ether->ctlrno, timeo); - stalled = 1; - } - - coherence(); - ctlr->dnhead->np = PADDR(&pd->np); - ctlr->dnhead->control &= ~dnIndicate; - ctlr->dnhead = pd; - if(ctlr->dnq == 0) - ctlr->dntail = pd; - ctlr->dnq++; - - ctlr->dnqueued++; - } - - if(ctlr->dnq > ctlr->dnqmax) - ctlr->dnqmax = ctlr->dnq; - - /* - * If the adapter is not currently processing anything - * and there is something on the queue, start it processing. - */ - if(inl(port+DnListPtr) == 0 && ctlr->dnq) - outl(port+DnListPtr, PADDR(&ctlr->dnhead->np)); - if(stalled) - COMMAND(port, Stall, dnUnStall); -} - -static void -transmit(Ether* ether) -{ - Ctlr *ctlr; - int port, w; - - port = ether->port; - ctlr = ether->ctlr; - - ilock(&ctlr->wlock); - if(ctlr->dnenabled) - txstart905(ether); - else{ - w = (STATUS(port)>>13) & 0x07; - COMMAND(port, SelectRegisterWindow, Wop); - txstart(ether); - COMMAND(port, SelectRegisterWindow, w); - } - iunlock(&ctlr->wlock); -} - -static void -receive905(Ether* ether) -{ - Ctlr *ctlr; - int len, port, q; - Pd *pd; - Block *bp; - - ctlr = ether->ctlr; - port = ether->port; - - if(inl(port+UpPktStatus) & upStalled) - ctlr->upstalls++; - q = 0; - for(pd = ctlr->uphead; pd->control & upPktComplete; pd = pd->next){ - if(pd->control & upError){ - if(pd->control & upOverrun) - ether->overflows++; - if(pd->control & (upOversizedFrame|upRuntFrame)) - ether->buffs++; - if(pd->control & upAlignmentError) - ether->frames++; - if(pd->control & upCRCError) - ether->crcs++; - } - else if(bp = iallocb(sizeof(Etherpkt)+4)){ - len = pd->control & rxBytes; - pd->bp->wp = pd->bp->rp+len; - etheriq(ether, pd->bp, 1); - pd->bp = bp; - pd->addr = PADDR(bp->rp); - coherence(); - } - - pd->control = 0; - COMMAND(port, Stall, upUnStall); - - q++; - } - ctlr->uphead = pd; - - ctlr->upqueued += q; - if(q > ctlr->upqmax) - ctlr->upqmax = q; -} - -static void -receive(Ether* ether) -{ - int len, port, rxerror, rxstatus; - Ctlr *ctlr; - Block *bp; - - port = ether->port; - ctlr = ether->ctlr; - - while(((rxstatus = ins(port+RxStatus)) & rxIncomplete) == 0){ - if(ctlr->busmaster == 1 && (STATUS(port) & busMasterInProgress)) - break; - - /* - * If there was an error, log it and continue. - * Unfortunately the 3C5[078]9 has the error info in the status register - * and the 3C59[0257] implement a separate RxError register. - */ - if(rxstatus & rxError){ - if(ctlr->rxstatus9){ - switch(rxstatus & rxError9){ - - case rxOverrun9: - ether->overflows++; - break; - - case oversizedFrame9: - case runtFrame9: - ether->buffs++; - break; - - case alignmentError9: - ether->frames++; - break; - - case crcError9: - ether->crcs++; - break; - - } - } - else{ - rxerror = inb(port+RxError); - if(rxerror & rxOverrun) - ether->overflows++; - if(rxerror & (oversizedFrame|runtFrame)) - ether->buffs++; - if(rxerror & alignmentError) - ether->frames++; - if(rxerror & crcError) - ether->crcs++; - } - } - - /* - * If there was an error or a new receive buffer can't be - * allocated, discard the packet and go on to the next. - */ - if((rxstatus & rxError) || (bp = rbpalloc(iallocb)) == 0){ - COMMAND(port, RxDiscard, 0); - while(STATUS(port) & commandInProgress) - ; - - if(ctlr->busmaster == 1) - startdma(ether, PADDR(ctlr->rbp->rp)); - - continue; - } - - /* - * A valid receive packet awaits: - * if using PIO, read it into the buffer; - * discard the packet from the FIFO; - * if using busmastering, start a new transfer for - * the next packet and as a side-effect get the - * end-pointer of the one just received; - * pass the packet on to whoever wants it. - */ - if(ctlr->busmaster == 0 || ctlr->busmaster == 2){ - len = (rxstatus & rxBytes9); - ctlr->rbp->wp = ctlr->rbp->rp + len; - insl(port+Fifo, ctlr->rbp->rp, HOWMANY(len, 4)); - } - - COMMAND(port, RxDiscard, 0); - while(STATUS(port) & commandInProgress) - ; - - if(ctlr->busmaster == 1) - ctlr->rbp->wp = startdma(ether, PADDR(bp->rp)); - - etheriq(ether, ctlr->rbp, 1); - ctlr->rbp = bp; - } -} - -static void -interrupt(Ureg*, void* arg) -{ - Ether *ether; - int port, status, s, w, x; - Ctlr *ctlr; - - ether = arg; - port = ether->port; - ctlr = ether->ctlr; - - ilock(&ctlr->wlock); - w = (STATUS(port)>>13) & 0x07; - COMMAND(port, SelectRegisterWindow, Wop); - - ctlr->interrupts++; - ctlr->timer += inb(port+Timer) & 0xFF; - while((status = STATUS(port)) & (interruptMask|interruptLatch)){ - if(status & hostError){ - /* - * Adapter failure, try to find out why, reset if - * necessary. What happens if Tx is active and a reset - * occurs, need to retransmit? This probably isn't right. - */ - COMMAND(port, SelectRegisterWindow, Wdiagnostic); - x = ins(port+FifoDiagnostic); - COMMAND(port, SelectRegisterWindow, Wop); - print("#l%d: status 0x%uX, diag 0x%uX\n", - ether->ctlrno, status, x); - - if(x & txOverrun){ - if(ctlr->busmaster == 0) - COMMAND(port, TxReset, 0); - else - COMMAND(port, TxReset, (updnReset|dmaReset)); - COMMAND(port, TxEnable, 0); - } - - if(x & rxUnderrun){ - /* - * This shouldn't happen... - * Reset the receiver and restore the filter and RxEarly - * threshold before re-enabling. - * Need to restart any busmastering? - */ - COMMAND(port, SelectRegisterWindow, Wstate); - s = (port+RxFilter) & 0x000F; - COMMAND(port, SelectRegisterWindow, Wop); - COMMAND(port, RxReset, 0); - while(STATUS(port) & commandInProgress) - ; - COMMAND(port, SetRxFilter, s); - COMMAND(port, SetRxEarlyThresh, ctlr->rxearly>>ctlr->ts); - COMMAND(port, RxEnable, 0); - } - - status &= ~hostError; - } - - if(status & (transferInt|rxComplete)){ - receive(ether); - status &= ~(transferInt|rxComplete); - } - - if(status & (upComplete)){ - COMMAND(port, AcknowledgeInterrupt, upComplete); - receive905(ether); - status &= ~upComplete; - ctlr->upinterrupts++; - } - - if(status & txComplete){ - /* - * Pop the TxStatus stack, accumulating errors. - * Adjust the TX start threshold if there was an underrun. - * If there was a Jabber or Underrun error, reset - * the transmitter, taking care not to reset the dma logic - * as a busmaster receive may be in progress. - * For all conditions enable the transmitter. - */ - s = 0; - do{ - if(x = inb(port+TxStatus)) - outb(port+TxStatus, 0); - s |= x; - }while(STATUS(port) & txComplete); - - if(s & txUnderrun){ - if(ctlr->dnenabled){ - while(inl(port+PktStatus) & dnInProg) - ; - } - COMMAND(port, SelectRegisterWindow, Wdiagnostic); - while(ins(port+MediaStatus) & txInProg) - ; - COMMAND(port, SelectRegisterWindow, Wop); - if(ctlr->txthreshold < ETHERMAXTU) - ctlr->txthreshold += ETHERMINTU; - } - - /* - * According to the manual, maxCollisions does not require - * a TxReset, merely a TxEnable. However, evidence points to - * it being necessary on the 3C905. The jury is still out. - * On busy or badly configured networks maxCollisions can - * happen frequently enough for messages to be annoying so - * keep quiet about them by popular request. - */ - if(s & (txJabber|txUnderrun|maxCollisions)){ - if(ctlr->busmaster == 0) - COMMAND(port, TxReset, 0); - else - COMMAND(port, TxReset, (updnReset|dmaReset)); - while(STATUS(port) & commandInProgress) - ; - COMMAND(port, SetTxStartThresh, ctlr->txthreshold>>ctlr->ts); - if(ctlr->busmaster == 2) - outl(port+TxFreeThresh, HOWMANY(ETHERMAXTU, 256)); - if(ctlr->dnenabled) - status |= dnComplete; - } - - if(s & ~(txStatusComplete|maxCollisions)) - print("#l%d: txstatus 0x%uX, threshold %d\n", - ether->ctlrno, s, ctlr->txthreshold); - COMMAND(port, TxEnable, 0); - ether->oerrs++; - status &= ~txComplete; - status |= txAvailable; - } - - if(status & txAvailable){ - COMMAND(port, AcknowledgeInterrupt, txAvailable); - ctlr->txbusy = 0; - txstart(ether); - status &= ~txAvailable; - } - - if(status & dnComplete){ - COMMAND(port, AcknowledgeInterrupt, dnComplete); - txstart905(ether); - status &= ~dnComplete; - ctlr->dninterrupts++; - } - - if(status & updateStats){ - statistics(ether); - status &= ~updateStats; - } - - /* - * Currently, this shouldn't happen. - */ - if(status & rxEarly){ - COMMAND(port, AcknowledgeInterrupt, rxEarly); - status &= ~rxEarly; - } - - /* - * Panic if there are any interrupts not dealt with. - */ - if(status & interruptMask) - panic("#l%d: interrupt mask 0x%uX\n", ether->ctlrno, status); - - COMMAND(port, AcknowledgeInterrupt, interruptLatch); - } - - COMMAND(port, SelectRegisterWindow, w); - iunlock(&ctlr->wlock); -} - -static long -ifstat(Ether* ether, void* a, long n, ulong offset) -{ - char *p; - int len; - Ctlr *ctlr; - - if(n == 0) - return 0; - - ctlr = ether->ctlr; - - ilock(&ctlr->wlock); - statistics(ether); - iunlock(&ctlr->wlock); - - p = malloc(READSTR); - len = snprint(p, READSTR, "interrupts: %lud\n", ctlr->interrupts); - len += snprint(p+len, READSTR-len, "timer: %lud\n", ctlr->timer); - len += snprint(p+len, READSTR-len, "carrierlost: %lud\n", ctlr->stats[CarrierLost]); - len += snprint(p+len, READSTR-len, "sqeerrors: %lud\n", ctlr->stats[SqeErrors]); - len += snprint(p+len, READSTR-len, "multiplecolls: %lud\n", ctlr->stats[MultipleColls]); - len += snprint(p+len, READSTR-len, "singlecollframes: %lud\n", ctlr->stats[SingleCollFrames]); - len += snprint(p+len, READSTR-len, "latecollisions: %lud\n", ctlr->stats[LateCollisions]); - len += snprint(p+len, READSTR-len, "rxoverruns: %lud\n", ctlr->stats[RxOverruns]); - len += snprint(p+len, READSTR-len, "framesxmittedok: %lud\n", ctlr->stats[FramesXmittedOk]); - len += snprint(p+len, READSTR-len, "framesrcvdok: %lud\n", ctlr->stats[FramesRcvdOk]); - len += snprint(p+len, READSTR-len, "framesdeferred: %lud\n", ctlr->stats[FramesDeferred]); - len += snprint(p+len, READSTR-len, "bytesrcvdok: %lud\n", ctlr->stats[BytesRcvdOk]); - len += snprint(p+len, READSTR-len, "bytesxmittedok: %lud\n", ctlr->stats[BytesRcvdOk+1]); - - if(ctlr->upenabled){ - if(ctlr->upqmax > ctlr->upqmaxhw) - ctlr->upqmaxhw = ctlr->upqmax; - len += snprint(p+len, READSTR-len, "up: q %lud i %lud m %d h %d s %lud\n", - ctlr->upqueued, ctlr->upinterrupts, - ctlr->upqmax, ctlr->upqmaxhw, ctlr->upstalls); - ctlr->upqmax = 0; - } - if(ctlr->dnenabled){ - if(ctlr->dnqmax > ctlr->dnqmaxhw) - ctlr->dnqmaxhw = ctlr->dnqmax; - len += snprint(p+len, READSTR-len, "dn: q %lud i %lud m %d h %d\n", - ctlr->dnqueued, ctlr->dninterrupts, ctlr->dnqmax, ctlr->dnqmaxhw); - ctlr->dnqmax = 0; - } - - snprint(p+len, READSTR-len, "badssd: %lud\n", ctlr->stats[BytesRcvdOk+2]); - - n = readstr(offset, a, n, p); - free(p); - - return n; -} - -static void -txrxreset(int port) -{ - COMMAND(port, TxReset, 0); - while(STATUS(port) & commandInProgress) - ; - COMMAND(port, RxReset, 0); - while(STATUS(port) & commandInProgress) - ; -} - -typedef struct Adapter { - int port; - int irq; - int tbdf; -} Adapter; -static Block* adapter; - -static void -tcmadapter(int port, int irq, int tbdf) -{ - Block *bp; - Adapter *ap; - - bp = iallocb(sizeof(Adapter)); - if(bp == nil) - return; - ap = (Adapter*)bp->rp; - ap->port = port; - ap->irq = irq; - ap->tbdf = tbdf; - - bp->next = adapter; - adapter = bp; -} - -/* - * Write two 0 bytes to identify the IDport and then reset the - * ID sequence. Then send the ID sequence to the card to get - * the card into command state. - */ -static void -idseq(void) -{ - int i; - uchar al; - static int reset, untag; - - /* - * One time only: - * reset any adapters listening - */ - if(reset == 0){ - outb(IDport, 0); - outb(IDport, 0); - outb(IDport, 0xC0); - delay(20); - reset = 1; - } - - outb(IDport, 0); - outb(IDport, 0); - for(al = 0xFF, i = 0; i < 255; i++){ - outb(IDport, al); - if(al & 0x80){ - al <<= 1; - al ^= 0xCF; - } - else - al <<= 1; - } - - /* - * One time only: - * write ID sequence to get the attention of all adapters; - * untag all adapters. - * If a global reset is done here on all adapters it will confuse - * any ISA cards configured for EISA mode. - */ - if(untag == 0){ - outb(IDport, 0xD0); - untag = 1; - } -} - -static ulong -activate(void) -{ - int i; - ushort x, acr; - - /* - * Do the little configuration dance: - * - * 2. write the ID sequence to get to command state. - */ - idseq(); - - /* - * 3. Read the Manufacturer ID from the EEPROM. - * This is done by writing the IDPort with 0x87 (0x80 - * is the 'read EEPROM' command, 0x07 is the offset of - * the Manufacturer ID field in the EEPROM). - * The data comes back 1 bit at a time. - * A delay seems necessary between reading the bits. - * - * If the ID doesn't match, there are no more adapters. - */ - outb(IDport, 0x87); - delay(20); - for(x = 0, i = 0; i < 16; i++){ - delay(20); - x <<= 1; - x |= inb(IDport) & 0x01; - } - if(x != 0x6D50) - return 0; - - /* - * 3. Read the Address Configuration from the EEPROM. - * The Address Configuration field is at offset 0x08 in the EEPROM). - */ - outb(IDport, 0x88); - for(acr = 0, i = 0; i < 16; i++){ - delay(20); - acr <<= 1; - acr |= inb(IDport) & 0x01; - } - - return (acr & 0x1F)*0x10 + 0x200; -} - -static char* tcmpcmcia[] = { - "3C589", /* 3COM 589[ABCD] */ - "3C562", /* 3COM 562 */ - "589E", /* 3COM Megahertz 589E */ - nil, -}; - -static int -tcm5XXpcmcia(Ether* ether) -{ - int i; - - for(i = 0; tcmpcmcia[i] != nil; i++){ - if(!cistrcmp(ether->type, tcmpcmcia[i])) - return ether->port; - } - - return 0; -} - -static void -setxcvr(int port, int xcvr, int is9) -{ - int x; - - if(is9){ - COMMAND(port, SelectRegisterWindow, Wsetup); - x = ins(port+AddressConfig) & ~xcvrMask9; - x |= (xcvr>>20)<<14; - outs(port+AddressConfig, x); - } - else{ - COMMAND(port, SelectRegisterWindow, Wfifo); - x = inl(port+InternalConfig) & ~xcvrMask; - x |= xcvr; - outl(port+InternalConfig, x); - } - - txrxreset(port); -} - -static void -setfullduplex(int port) -{ - int x; - - COMMAND(port, SelectRegisterWindow, Wfifo); - x = ins(port+MacControl); - outs(port+MacControl, fullDuplexEnable|x); - - txrxreset(port); -} - -static int -miimdi(int port, int n) -{ - int data, i; - - /* - * Read n bits from the MII Management Register. - */ - data = 0; - for(i = n-1; i >= 0; i--){ - if(ins(port) & mgmtData) - data |= (1<= 0; i--){ - if(bits & (1<>13) & 0x07; - COMMAND(port, SelectRegisterWindow, Wdiagnostic); - port += PhysicalMgmt; - - /* - * Preamble; - * ST+OP+PHYAD+REGAD; - * TA + 16 data bits. - */ - miimdo(port, 0xFFFFFFFF, 32); - miimdo(port, 0x1800|(phyad<<5)|regad, 14); - data = miimdi(port, 18); - - port -= PhysicalMgmt; - COMMAND(port, SelectRegisterWindow, w); - - if(data & 0x10000) - return -1; - - return data & 0xFFFF; -} - -static void -scanphy(int port) -{ - int i, x; - - for(i = 0; i < 32; i++){ - if((x = miir(port, i, 2)) == -1 || x == 0) - continue; - x <<= 6; - x |= miir(port, i, 3)>>10; - XCVRDEBUG("phy%d: oui %uX reg1 %uX\n", i, x, miir(port, i, 1)); - USED(x); - } -} - -#ifdef notdef -static struct xxx { - int available; - int next; -} xxx[8] = { - { base10TAvailable, 1, }, /* xcvr10BaseT -> xcvrAui */ - { auiAvailable, 3, }, /* xcvrAui -> xcvr10Base2 */ - { 0, -1, }, - { coaxAvailable, -1, }, /* xcvr10Base2 -> nowhere */ - { baseTXAvailable, 5, }, /* xcvr100BaseTX-> xcvr100BaseFX */ - { baseFXAvailable, -1, }, /* xcvr100BaseFX-> nowhere */ - { miiConnector, -1, }, /* xcvrMii -> nowhere */ - { 0, -1, }, -}; -#endif /* notdef */ - -static int -autoselect(int port, int xcvr, int is9) -{ - int media, x; - - USED(xcvr); - - /* - * Pathetic attempt at automatic media selection. - * Really just to get the Fast Etherlink 10BASE-T/100BASE-TX - * cards operational. - * It's a bonus if it works for anything else. - */ - if(is9){ - COMMAND(port, SelectRegisterWindow, Wsetup); - x = ins(port+ConfigControl); - media = 0; - if(x & base10TAvailable9) - media |= base10TAvailable; - if(x & coaxAvailable9) - media |= coaxAvailable; - if(x & auiAvailable9) - media |= auiAvailable; - } - else{ - COMMAND(port, SelectRegisterWindow, Wfifo); - media = ins(port+ResetOptions); - } - XCVRDEBUG("autoselect: media %uX\n", media); - - if(media & miiConnector) - return xcvrMii; - - COMMAND(port, SelectRegisterWindow, Wdiagnostic); - XCVRDEBUG("autoselect: media status %uX\n", ins(port+MediaStatus)); - - if(media & baseTXAvailable){ - /* - * Must have InternalConfig register. - */ - setxcvr(port, xcvr100BaseTX, is9); - - COMMAND(port, SelectRegisterWindow, Wdiagnostic); - x = ins(port+MediaStatus) & ~(dcConverterEnabled|jabberGuardEnable); - outs(port+MediaStatus, linkBeatEnable|x); - delay(10); - - if(ins(port+MediaStatus) & linkBeatDetect) - return xcvr100BaseTX; - outs(port+MediaStatus, x); - } - - if(media & base10TAvailable){ - setxcvr(port, xcvr10BaseT, is9); - - COMMAND(port, SelectRegisterWindow, Wdiagnostic); - x = ins(port+MediaStatus) & ~dcConverterEnabled; - outs(port+MediaStatus, linkBeatEnable|jabberGuardEnable|x); - delay(100); - - XCVRDEBUG("autoselect: 10BaseT media status %uX\n", ins(port+MediaStatus)); - if(ins(port+MediaStatus) & linkBeatDetect) - return xcvr10BaseT; - outs(port+MediaStatus, x); - } - - /* - * Botch. - */ - return autoSelect; -} - -static int -eepromdata(int port, int offset) -{ - COMMAND(port, SelectRegisterWindow, Wsetup); - while(EEPROMBUSY(port)) - ; - EEPROMCMD(port, EepromReadRegister, offset); - while(EEPROMBUSY(port)) - ; - return EEPROMDATA(port); -} - -int -etherelnk3reset(Ether* ether) -{ - int anar, anlpar, busmaster, did, i, phyaddr, port, rxearly, rxstatus9, x, xcvr; - Block *bp, **bpp; - Adapter *ap; - uchar ea[Eaddrlen]; - Ctlr *ctlr; - - /* - * Any adapter matches if no ether->port is supplied, - * otherwise the ports must match. - */ - port = 0; - bpp = &adapter; - for(bp = *bpp; bp; bp = bp->next){ - ap = (Adapter*)bp->rp; - if(ether->port == 0 || ether->port == ap->port){ - port = ap->port; - ether->irq = ap->irq; - ether->tbdf = ap->tbdf; - *bpp = bp->next; - freeb(bp); - break; - } - bpp = &bp->next; - } - if(port == 0 && (port = tcm5XXpcmcia(ether)) == 0) - return -1; - - /* - * Read the DeviceID from the EEPROM, it's at offset 0x03, - * and do something depending on capabilities. - */ - switch(did = eepromdata(port, 0x03)){ - - case 0x9000: - case 0x9001: - case 0x9005: - case 0x9050: - case 0x9051: - case 0x9055: - if(BUSTYPE(ether->tbdf) != BusPCI) - goto buggery; - busmaster = 2; - goto vortex; - - case 0x5900: - case 0x5920: - case 0x5950: - case 0x5951: - case 0x5952: - case 0x5970: - case 0x5971: - case 0x5972: - busmaster = 1; - vortex: - COMMAND(port, SelectRegisterWindow, Wfifo); - xcvr = inl(port+InternalConfig) & (autoSelect|xcvrMask); - rxearly = 8188; - rxstatus9 = 0; - break; - - buggery: - default: - busmaster = 0; - COMMAND(port, SelectRegisterWindow, Wsetup); - x = ins(port+AddressConfig); - xcvr = ((x & xcvrMask9)>>14)<<20; - if(x & autoSelect9) - xcvr |= autoSelect; - rxearly = 2044; - rxstatus9 = 1; - break; - } - - /* - * Check if the adapter's station address is to be overridden. - * If not, read it from the EEPROM and set in ether->ea prior to loading the - * station address in Wstation. The EEPROM returns 16-bits at a time. - */ - memset(ea, 0, Eaddrlen); - if(memcmp(ea, ether->ea, Eaddrlen) == 0){ - for(i = 0; i < Eaddrlen/2; i++){ - x = eepromdata(port, i); - ether->ea[2*i] = x>>8; - ether->ea[2*i+1] = x; - } - } - - COMMAND(port, SelectRegisterWindow, Wstation); - for(i = 0; i < Eaddrlen; i++) - outb(port+i, ether->ea[i]); - - /* - * Enable the transceiver if necessary and determine whether - * busmastering can be used. Due to bugs in the first revision - * of the 3C59[05], don't use busmastering at 10Mbps. - */ - XCVRDEBUG("reset: xcvr %uX\n", xcvr); -/* - * forgive me, but i am weak - */ -if(did == 0x9055){ - xcvr = xcvrMii; - XCVRDEBUG("9055 reset ops 0x%uX\n", - ins(port+ResetOp905B)); -} -else - if(xcvr & autoSelect) - xcvr = autoselect(port, xcvr, rxstatus9); - XCVRDEBUG("autoselect returns: xcvr %uX, did 0x%uX\n", xcvr, did); - switch(xcvr){ - - case xcvrMii: - /* - * Quick hack. - scanphy(port); - */ - phyaddr = 24; -for(i = 0; i < 7; i++) - XCVRDEBUG(" %2.2uX", miir(port, phyaddr, i)); -XCVRDEBUG("\n"); - -{ int phystat, timeo; - for(timeo = 0; timeo < 30; timeo++){ - phystat = miir(port, phyaddr, 0x01); - if(phystat & 0x20) - break; - XCVRDEBUG(" %2.2uX", phystat); - delay(100); - } - XCVRDEBUG(" %2.2uX", miir(port, phyaddr, 0x01)); - XCVRDEBUG("\n"); -} - - anar = miir(port, phyaddr, 0x04); - anlpar = miir(port, phyaddr, 0x05) & 0x03E0; - anar &= anlpar; - miir(port, phyaddr, 0x00); - XCVRDEBUG("mii an: %uX anlp: %uX r0:%uX r1:%uX\n", - anar, anlpar, miir(port, phyaddr, 0x00), - miir(port, phyaddr, 0x01)); - for(i = 0; i < ether->nopt; i++){ - if(cistrcmp(ether->opt[i], "fullduplex") == 0) - anar |= 0x0100; - else if(cistrcmp(ether->opt[i], "100BASE-TXFD") == 0) - anar |= 0x0100; - else if(cistrcmp(ether->opt[i], "force100") == 0) - anar |= 0x0080; - } - XCVRDEBUG("mii anar: %uX\n", anar); - if(anar & 0x0100){ /* 100BASE-TXFD */ - ether->mbps = 100; - setfullduplex(port); - } - else if(anar & 0x0200) /* 100BASE-T4 */ - ; - else if(anar & 0x0080) /* 100BASE-TX */ - ether->mbps = 100; - else if(anar & 0x0040) /* 10BASE-TFD */ - setfullduplex(port); - else /* 10BASE-T */ - ; - break; - - case xcvr100BaseTX: - case xcvr100BaseFX: - COMMAND(port, SelectRegisterWindow, Wfifo); - x = inl(port+InternalConfig) & ~ramPartitionMask; - outl(port+InternalConfig, x|ramPartition1to1); - - COMMAND(port, SelectRegisterWindow, Wdiagnostic); - x = ins(port+MediaStatus) & ~(dcConverterEnabled|jabberGuardEnable); - x |= linkBeatEnable; - outs(port+MediaStatus, x); - - if(x & dataRate100) - ether->mbps = 100; - break; - - case xcvr10BaseT: - /* - * Enable Link Beat and Jabber to start the - * transceiver. - */ - COMMAND(port, SelectRegisterWindow, Wdiagnostic); - x = ins(port+MediaStatus) & ~dcConverterEnabled; - x |= linkBeatEnable|jabberGuardEnable; - outs(port+MediaStatus, x); - - if((did & 0xFF00) == 0x5900) - busmaster = 0; - break; - - case xcvr10Base2: - COMMAND(port, SelectRegisterWindow, Wdiagnostic); - x = ins(port+MediaStatus) & ~(linkBeatEnable|jabberGuardEnable); - outs(port+MediaStatus, x); - - /* - * Start the DC-DC converter. - * Wait > 800 microseconds. - */ - COMMAND(port, EnableDcConverter, 0); - delay(1); - break; - } - - /* - * Wop is the normal operating register set. - * The 3C59[0257] adapters allow access to more than one register window - * at a time, but there are situations where switching still needs to be - * done, so just do it. - * Clear out any lingering Tx status. - */ - COMMAND(port, SelectRegisterWindow, Wop); - while(inb(port+TxStatus)) - outb(port+TxStatus, 0); - - /* - * Allocate a controller structure, clear out the - * adapter statistics, clear the statistics logged into ctlr - * and enable statistics collection. Xcvr is needed in order - * to collect the BadSSD statistics. - */ - ether->ctlr = malloc(sizeof(Ctlr)); - ctlr = ether->ctlr; - - ilock(&ctlr->wlock); - ctlr->xcvr = xcvr; - statistics(ether); - memset(ctlr->stats, 0, sizeof(ctlr->stats)); - - ctlr->busmaster = busmaster; - ctlr->xcvr = xcvr; - ctlr->rxstatus9 = rxstatus9; - ctlr->rxearly = rxearly; - if(rxearly >= 2048) - ctlr->ts = 2; - - COMMAND(port, StatisticsEnable, 0); - - /* - * Allocate any receive buffers. - */ - switch(ctlr->busmaster){ - - case 2: - ctlr->dnenabled = 1; - - /* - * 10MUpldBug. - * Disabling is too severe, can use receive busmastering at - * 100Mbps OK, but how to tell which rate is actually being used - - * the 3c905 always seems to have dataRate100 set? - * Believe the bug doesn't apply if upRxEarlyEnable is set - * and the threshold is set such that uploads won't start - * until the whole packet has been received. - */ - ctlr->upenabled = 1; - x = eepromdata(port, 0x0F); - if(!(x & 0x01)) - outl(port+PktStatus, upRxEarlyEnable); - - if(ctlr->upenabled || ctlr->dnenabled){ - ctlr->nup = Nup; - ctlr->ndn = Ndn; - init905(ctlr); - } - else{ - ctlr->rbp = rbpalloc(iallocb); - if(ctlr->rbp == nil) - panic("can't reset ethernet: out of memory"); - } - outl(port+TxFreeThresh, HOWMANY(ETHERMAXTU, 256)); - break; - - default: - ctlr->rbp = rbpalloc(iallocb); - if(ctlr->rbp == nil) - panic("can't reset ethernet: out of memory"); - break; - } - - /* - * Set a base TxStartThresh which will be incremented - * if any txUnderrun errors occur and ensure no RxEarly - * interrupts happen. - */ - ctlr->txthreshold = ETHERMAXTU/2; - COMMAND(port, SetTxStartThresh, ctlr->txthreshold>>ctlr->ts); - COMMAND(port, SetRxEarlyThresh, rxearly>>ctlr->ts); - - iunlock(&ctlr->wlock); - - /* - * Linkage to the generic ethernet driver. - */ - ether->port = port; - ether->attach = attach; - ether->transmit = transmit; - ether->interrupt = interrupt; - ether->ifstat = ifstat; - - ether->promiscuous = promiscuous; - ether->multicast = multicast; - ether->arg = ether; - - return 0; -} - -void -etherelnk3link(void) -{ - addethercard("elnk3", etherelnk3reset); - addethercard("3C509", etherelnk3reset); -} diff --git a/mpc/etherif.h b/mpc/etherif.h deleted file mode 100644 index 6e43bf628ee3d246456443cf5e19a5d61fa47cb3..0000000000000000000000000000000000000000 --- a/mpc/etherif.h +++ /dev/null @@ -1,28 +0,0 @@ -enum { - MaxEther = 4, - Ntypes = 8, -}; - -typedef struct Ether Ether; -struct Ether { - ISAConf; /* hardware info */ - int ctlrno; - int tbdf; /* type+busno+devno+funcno */ - int mbps; /* Mbps */ - uchar ea[Eaddrlen]; - - void (*attach)(Ether*); /* filled in by reset routine */ - void (*closed)(Ether*); - void (*detach)(Ether*); - void (*transmit)(Ether*); - void (*interrupt)(Ureg*, void*); - long (*ifstat)(Ether*, void*, long, ulong); - void *ctlr; - - Queue* oq; - - Netif; -}; - -extern Block* etheriq(Ether*, Block*, int); -extern void addethercard(char*, int(*)(Ether*)); diff --git a/mpc/etherscc.c b/mpc/etherscc.c deleted file mode 100644 index 6cf157c9ff130740452433df4155edf257e31d34..0000000000000000000000000000000000000000 --- a/mpc/etherscc.c +++ /dev/null @@ -1,630 +0,0 @@ -/* - * SCCn ethernet - */ - -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "io.h" -#include "../port/error.h" -#include "../port/netif.h" - -#include "etherif.h" - -enum { - Nrdre = 16, /* receive descriptor ring entries */ - Ntdre = 16, /* transmit descriptor ring entries */ - - Rbsize = ETHERMAXTU+4, /* ring buffer size (+4 for CRC) */ - Bufsize = (Rbsize+7)&~7, /* aligned */ -}; - -enum { - /* ether-specific Rx BD bits */ - RxMiss= 1<<8, - RxeLG= 1<<5, - RxeNO= 1<<4, - RxeSH= 1<<3, - RxeCR= 1<<2, - RxeOV= 1<<1, - RxeCL= 1<<0, - RxError= (RxeLG|RxeNO|RxeSH|RxeCR|RxeOV|RxeCL), /* various error flags */ - - /* ether-specific Tx BD bits */ - TxPad= 1<<14, /* pad short frames */ - TxTC= 1<<10, /* transmit CRC */ - TxeDEF= 1<<9, - TxeHB= 1<<8, - TxeLC= 1<<7, - TxeRL= 1<<6, - TxeUN= 1<<1, - TxeCSL= 1<<0, - - /* scce */ - RXB= 1<<0, - TXB= 1<<1, - BSY= 1<<2, - RXF= 1<<3, - TXE= 1<<4, - - /* psmr */ - PRO= 1<<9, /* promiscuous mode */ - - /* gsmrl */ - ENR= 1<<5, - ENT= 1<<4, -}; - -typedef struct Etherparam Etherparam; -struct Etherparam { - SCCparam; - ulong c_pres; /* preset CRC */ - ulong c_mask; /* constant mask for CRC */ - ulong crcec; /* CRC error counter */ - ulong alec; /* alighnment error counter */ - ulong disfc; /* discard frame counter */ - ushort pads; /* short frame PAD characters */ - ushort ret_lim; /* retry limit threshold */ - ushort ret_cnt; /* retry limit counter */ - ushort mflr; /* maximum frame length reg */ - ushort minflr; /* minimum frame length reg */ - ushort maxd1; /* maximum DMA1 length reg */ - ushort maxd2; /* maximum DMA2 length reg */ - ushort maxd; /* rx max DMA */ - ushort dma_cnt; /* rx dma counter */ - ushort max_b; /* max bd byte count */ - ushort gaddr[4]; /* group address filter */ - ulong tbuf0_data0; /* save area 0 - current frm */ - ulong tbuf0_data1; /* save area 1 - current frm */ - ulong tbuf0_rba0; - ulong tbuf0_crc; - ushort tbuf0_bcnt; - ushort paddr[3]; /* physical address LSB to MSB increasing */ - ushort p_per; /* persistence */ - ushort rfbd_ptr; /* rx first bd pointer */ - ushort tfbd_ptr; /* tx first bd pointer */ - ushort tlbd_ptr; /* tx last bd pointer */ - ulong tbuf1_data0; /* save area 0 - next frame */ - ulong tbuf1_data1; /* save area 1 - next frame */ - ulong tbuf1_rba0; - ulong tbuf1_crc; - ushort tbuf1_bcnt; - ushort tx_len; /* tx frame length counter */ - ushort iaddr[4]; /* individual address filter*/ - ushort boff_cnt; /* back-off counter */ - ushort taddr[3]; /* temp address */ -}; - -typedef struct { - Lock; - int sccid; - int port; - int init; - int active; - SCC* scc; - - Ring; - - ulong interrupts; /* statistics */ - ulong deferred; - ulong heartbeat; - ulong latecoll; - ulong retrylim; - ulong underrun; - ulong overrun; - ulong carrierlost; - ulong retrycount; -} Ctlr; - -static int sccirq[] = {-1, 0x1E, 0x1D, 0x1C, 0x1B}; -static int sccid[] = {-1, SCC1ID, SCC2ID, SCC3ID, SCC4ID}; -static int sccbase[] = {-1, 0xA00, 0xA20, 0xA40, 0xA60}; -static int sccparam[] = {-1, SCC1P, SCC2P, SCC3P, SCC4P}; - -static void -attach(Ether *ether) -{ - Ctlr *ctlr; - - ctlr = ether->ctlr; - ctlr->active = 1; - ctlr->scc->gsmrl |= ENR|ENT; - eieio(); -} - -static void -closed(Ether *ether) -{ - if(0){ - Ctlr *ctlr; - - ctlr = ether->ctlr; - if(ether->port == 2) - scc2stop(ctlr->scc); - ilock(ctlr); - ctlr->active = 0; - iunlock(ctlr); - print("Ether closed\n"); - } -} - -static void -promiscuous(void* arg, int on) -{ - Ether *ether; - Ctlr *ctlr; - - ether = (Ether*)arg; - ctlr = ether->ctlr; - - ilock(ctlr); - if(on || ether->nmaddr) - ctlr->scc->psmr |= PRO; - else - ctlr->scc->psmr &= ~PRO; - iunlock(ctlr); -} - -static void -multicast(void* arg, uchar *addr, int on) -{ - Ether *ether; - Ctlr *ctlr; - - USED(addr, on); /* if on, could SetGroupAddress; if !on, it's hard */ - - ether = (Ether*)arg; - ctlr = ether->ctlr; - - ilock(ctlr); - if(ether->prom || ether->nmaddr) - ctlr->scc->psmr |= PRO; - else - ctlr->scc->psmr &= ~PRO; - iunlock(ctlr); -} - -static void -txstart(Ether *ether) -{ - int len; - Ctlr *ctlr; - Block *b; - BD *dre; - - ctlr = ether->ctlr; - if(ctlr->init) - return; - while(ctlr->ntq < Ntdre-1){ - b = qget(ether->oq); - if(b == 0) - break; - - dre = &ctlr->tdr[ctlr->tdrh]; - if(dre->status & BDReady) - panic("ether: txstart"); - - /* - * Give ownership of the descriptor to the chip, increment the - * software ring descriptor pointer and tell the chip to poll. - */ - len = BLEN(b); - dcflush(b->rp, len); - if(ctlr->txb[ctlr->tdrh] != nil) - panic("scc/ether: txstart"); - ctlr->txb[ctlr->tdrh] = b; - if((ulong)b->rp&1) - panic("scc/ether: txstart align"); /* TO DO: ensure alignment */ - dre->addr = PADDR(b->rp); - dre->length = len; - eieio(); - dre->status = (dre->status & BDWrap) | BDReady|TxPad|BDInt|BDLast|TxTC; - eieio(); - ctlr->scc->todr = 1<<15; /* transmit now */ - eieio(); - ctlr->ntq++; - ctlr->tdrh = NEXT(ctlr->tdrh, Ntdre); - } -} - -static void -transmit(Ether* ether) -{ - Ctlr *ctlr; - - ctlr = ether->ctlr; - ilock(ctlr); - txstart(ether); - iunlock(ctlr); -} - -static void -interrupt(Ureg*, void *arg) -{ - int len, events, status; - Ctlr *ctlr; - BD *dre; - Block *b; - Ether *ether = arg; - - ctlr = ether->ctlr; - if(!ctlr->active) - return; /* not ours */ - - /* - * Acknowledge all interrupts and whine about those that shouldn't - * happen. - */ - events = ctlr->scc->scce; - eieio(); - ctlr->scc->scce = events; - eieio(); - ctlr->interrupts++; - - if(events & (TXE|BSY|RXB)){ - if(events & RXB) - ctlr->overrun++; - if(events & TXE) - ether->oerrs++; - } - - /* - * Receiver interrupt: run round the descriptor ring logging - * errors and passing valid receive data up to the higher levels - * until we encounter a descriptor still owned by the chip. - */ - if(events & (RXF|RXB)){ - dre = &ctlr->rdr[ctlr->rdrx]; - while(((status = dre->status) & BDEmpty) == 0){ - if(status & RxError || (status & (BDFirst|BDLast)) != (BDFirst|BDLast)){ - if(status & (RxeLG|RxeSH)) - ether->buffs++; - if(status & RxeNO) - ether->frames++; - if(status & RxeCR) - ether->crcs++; - if(status & RxeOV) - ether->overflows++; - print("eth rx: %ux\n", status); - } - else{ - /* - * We have a packet. Read it in. - */ - len = dre->length-4; - if((b = iallocb(len)) != 0){ - memmove(b->wp, KADDR(dre->addr), len); - b->wp += len; - etheriq(ether, b, 1); - dcflush(KADDR(dre->addr), len); - }else - ether->soverflows++; - } - - /* - * Finished with this descriptor, reinitialise it, - * give it back to the chip, then on to the next... - */ - dre->length = 0; - dre->status = (status & BDWrap) | BDEmpty | BDInt; - eieio(); - - ctlr->rdrx = NEXT(ctlr->rdrx, Nrdre); - dre = &ctlr->rdr[ctlr->rdrx]; - } - } - - /* - * Transmitter interrupt: handle anything queued for a free descriptor. - */ - if(events & (TXB|TXE)){ - lock(ctlr); - while(ctlr->ntq){ - dre = &ctlr->tdr[ctlr->tdri]; - status = dre->status; - if(status & BDReady) - break; - if(status & TxeDEF) - ctlr->deferred++; - if(status & TxeHB) - ctlr->heartbeat++; - if(status & TxeLC) - ctlr->latecoll++; - if(status & TxeRL) - ctlr->retrylim++; - if(status & TxeUN) - ctlr->underrun++; - if(status & TxeCSL) - ctlr->carrierlost++; - ctlr->retrycount += (status>>2)&0xF; - b = ctlr->txb[ctlr->tdri]; - if(b == nil) - panic("scce/interrupt: bufp"); - ctlr->txb[ctlr->tdri] = nil; - freeb(b); - ctlr->ntq--; - ctlr->tdri = NEXT(ctlr->tdri, Ntdre); - } - - if(events & TXE) - cpmop(RestartTx, ctlr->sccid, 0); - - txstart(ether); - unlock(ctlr); - } -} - -static long -ifstat(Ether* ether, void* a, long n, ulong offset) -{ - char *p; - int len; - Ctlr *ctlr; - - if(n == 0) - return 0; - - ctlr = ether->ctlr; - - p = malloc(READSTR); - len = snprint(p, READSTR, "interrupts: %lud\n", ctlr->interrupts); - len += snprint(p+len, READSTR-len, "carrierlost: %lud\n", ctlr->carrierlost); - len += snprint(p+len, READSTR-len, "heartbeat: %lud\n", ctlr->heartbeat); - len += snprint(p+len, READSTR-len, "retrylimit: %lud\n", ctlr->retrylim); - len += snprint(p+len, READSTR-len, "retrycount: %lud\n", ctlr->retrycount); - len += snprint(p+len, READSTR-len, "latecollisions: %lud\n", ctlr->latecoll); - len += snprint(p+len, READSTR-len, "rxoverruns: %lud\n", ctlr->overrun); - len += snprint(p+len, READSTR-len, "txunderruns: %lud\n", ctlr->underrun); - snprint(p+len, READSTR-len, "framesdeferred: %lud\n", ctlr->deferred); - n = readstr(offset, a, n, p); - free(p); - - return n; -} - -/* - * This follows the MPC823 user guide: section16.9.23.7's initialisation sequence, - * except that it sets the right bits for the MPC823ADS board when SCC2 is used, - * and those for the 860/821 development board for SCC1. - */ -static void -sccsetup(Ctlr *ctlr, SCC *scc, uchar *ea) -{ - int i; - Etherparam *p; - IMM *io; - - io = ioplock(); - - switch(ctlr->port) { - default: - iopunlock(); - return; - case 2: - p = (Etherparam*)(SCC2P); - - // step 1: enable TXD RXD ports - io->papar |= SIBIT(12)|SIBIT(13); - io->padir &= ~(SIBIT(12)|SIBIT(13)); - io->paodr &= ~(SIBIT(12)|SIBIT(13)); - - // step 2: enable CLSN and RENA ports - io->pcpar &= ~(SIBIT(8)|SIBIT(9)); - io->pcdir &= ~(SIBIT(8)|SIBIT(9)); - io->pcso |= SIBIT(8)|SIBIT(9); - - // setp 3: disble TENA pin */ - io->pcpar &= ~SIBIT(14); - io->pcdir &= ~SIBIT(14); - - // step 4: enable clocks CLK3 and CLK4 - io->papar |= SIBIT(6)|SIBIT(7); - io->padir &= ~(SIBIT(6)|SIBIT(7)); - - // step 5/6: route clocks - iopunlock(); - sccnmsi(2, CLK1, CLK2); /* connect the clocks */ - io = ioplock(); - break; - - case 3: - p = (Etherparam*)KADDR(SCC3P); - - // step 1: enable TXD RXD ports - io->pbpar |= IBIT(24)|IBIT(25); - io->pbdir |= IBIT(24)|IBIT(25); - io->pbodr &= ~(IBIT(24)|IBIT(25)); - - // step 2: enable CLSN and RENA ports - io->pcpar &= ~(SIBIT(4)|SIBIT(5)); - io->pcdir &= ~(SIBIT(4)|SIBIT(5)); - io->pcso |= SIBIT(4)|SIBIT(5); - eieio(); - - // setp 3 - io->pcpar &= ~SIBIT(13); - io->pcdir &= ~SIBIT(13); - - // step 4: enable clocks - io->papar |= SIBIT(4)|SIBIT(5); - io->padir &= ~(SIBIT(4)|SIBIT(5)); - eieio(); - - // step 5/6: route clocks - iopunlock(); - sccnmsi(3, CLK3, CLK4); - io = ioplock(); - break; - } - - // step 7: set dma priority - io->sdcr = 1; - - iopunlock(); - - // step 8: - p->rbase = PADDR(ctlr->rdr); - p->tbase = PADDR(ctlr->tdr); - - // step 9: - cpmop(InitRxTx, sccid[ctlr->port], 0); - - // step 10 - p->rfcr = 0x18; // manuals say 0x10 - p->tfcr = 0x18; - - // step 11 - p->mrblr = Bufsize; - - // step 12: - p->c_pres = ~0; - - // step 13: - p->c_mask = 0xDEBB20E3; - - // step 14: - p->crcec = 0; - p->alec = 0; - p->disfc = 0; - - // step 15: - p->pads = 0x8888; - - // step 16: - p->ret_lim = 0xF; - - // step 17: - p->mflr = Rbsize; - - // step 18: - p->minflr = ETHERMINTU+4; - - // step 19: - p->maxd1 = Bufsize; /* was 0x5F0 */ - p->maxd2 = Bufsize; /* was 0x5F0 */ - - // step 20: - memset(p->gaddr, 0, sizeof(p->gaddr)); - - // step 21: - for(i=0; ipaddr[2-i/2] = (ea[i+1]<<8)|ea[i]; - - // step 22 - p->p_per = 0; /* only moderate aggression */ - - // step 23: - memset(p->iaddr, 0, sizeof(p->iaddr)); - - // step 24: - memset(p->taddr, 0, sizeof(p->taddr)); - - // step 25: - - // step 26: - - // step 27: - scc->scce = ~0; /* clear all events */ - - // step 28: - scc->sccm = TXE | RXF | TXB; /* enable interrupts */ - p->p_per = 0; /* only moderate aggression */ - - // step 29: - // set by setvec - - // step 30: - scc->gsmrh = 0; /* normal operation */ - - // step 31: - scc->gsmrl = 0x1088000c; - - // step 32: - scc->dsr = 0xd555; - - // step 33: - scc->psmr = 0x080A; /* 32-bit CRC, non-promiscuous */ - - // step 34: enable TENA - switch(ctlr->port) { - case 2: - io->pcpar |= SIBIT(14); - io->pcdir &= ~SIBIT(14); - break; - case 3: - io->pcpar |= SIBIT(13); - io->pcdir &= ~SIBIT(13); - break; - } - - // step 35: done at attach time -} - -static int -reset(Ether* ether) -{ - uchar ea[Eaddrlen]; - Ctlr *ctlr; - SCC *scc; - -print("etherscc: reset\n"); - - if(m->speed < 24){ - print("%s ether: system speed must be >= 24MHz for ether use\n", ether->type); - return -1; - } - - if(!(ether->port >= 1 && ether->port <= 4)){ - print("%s ether: no SCC port %ld\n", ether->type, ether->port); - return -1; - } - - ether->irq = VectorCPIC + sccirq[ether->port]; - scc = IOREGS(sccbase[ether->port], SCC); - if(ether->port == 2) - scc2claim(1, DisableEther, scc2stop, scc); - - ctlr = malloc(sizeof(*ctlr)); - ether->ctlr = ctlr; - memset(ctlr, 0, sizeof(*ctlr)); - ctlr->scc = scc; - ctlr->port = ether->port; - ctlr->sccid = sccid[ether->port]; - - if(ioringinit(ctlr, Nrdre, Ntdre, Bufsize) < 0) - panic("etherscc init"); - - sccsetup(ctlr, scc, ether->ea); - - ether->mbps = 10; /* TO DO: could be 100mbps on 860T */ - ether->attach = attach; - ether->closed = closed; - ether->transmit = transmit; - ether->interrupt = interrupt; - ether->ifstat = ifstat; - - ether->arg = ether; - ether->promiscuous = promiscuous; - ether->multicast = multicast; - - /* - * Until we know where to find it, insist that the plan9.ini - * entry holds the Ethernet address. - */ - memset(ea, 0, Eaddrlen); - if(memcmp(ea, ether->ea, Eaddrlen) == 0){ - print("no ether address"); - return -1; - } - - return 0; -} - -void -etherscclink(void) -{ - addethercard("SCC", reset); -// addethercard("SCC3", reset); -} diff --git a/mpc/etherwavelan.c b/mpc/etherwavelan.c deleted file mode 100644 index 040777d339683f1632a25126d549a99a07f26416..0000000000000000000000000000000000000000 --- a/mpc/etherwavelan.c +++ /dev/null @@ -1,946 +0,0 @@ -/* - * Port for WaveLAN I PCMCIA cards running on 2.4 GHz - * important: only works for WaveLAN I and PCMCIA 2.4 GHz cards - * Based on Linux driver by Anthony D. Joseph MIT a.o. - * We have not added the frequency, encryption and NWID selection stuff, this - * can be done with the WaveLAN provided DOS programs: instconf.exe, setconf.exe, wfreqsel.exe, etc. - * Gerard Smit 07/22/98 - */ - -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "io.h" -#include "../port/error.h" -#include "../port/netif.h" -#include "etherif.h" -#include "etherwavelan.h" - - -static int wavelan_receive(Ether *ether); -static int txstart(Ether *ether); - -static void -hacr_write_slow(int base, uchar hacr) -{ - outb(HACR(base), hacr); - /* delay might only be needed sometimes */ - delay(1); -} /* hacr_write_slow */ - -static long -ifstat(Ether* ether, void* a, long n, ulong offset) -{ - Ctlr *ctlr; - int len; - char *p; - - ctlr = ether->ctlr; - p = malloc(READSTR); - len = snprint(p, READSTR, "interrupts: %lud\n", ctlr->interrupts); - len += snprint(p+len, READSTR-len, "upinterrupts: %lud\n", ctlr->upinterrupts); - len += snprint(p+len, READSTR-len, "dninterrupts: %lud\n", ctlr->dninterrupts); - len += snprint(p+len, READSTR-len, "int_errors: %lud\n", ctlr->int_errors); - len += snprint(p+len, READSTR-len, "read_errors: %lud\n", ctlr->read_errors); - len += snprint(p+len, READSTR-len, "out_packets: %lud\n", ctlr->out_packets); - len += snprint(p+len, READSTR-len, "tx_too_long: %lud\n", ctlr->tx_too_long); - len += snprint(p+len, READSTR-len, "tx_DMA_underrun: %lud\n", ctlr->tx_DMA_underrun); - len += snprint(p+len, READSTR-len, "tx_carrier_error: %lud\n", ctlr->tx_carrier_error); - len += snprint(p+len, READSTR-len, "tx_congestion: %lud\n", ctlr->tx_congestion); - len += snprint(p+len, READSTR-len, "tx_heart_beat: %lud\n", ctlr->tx_heart_beat); - len += snprint(p+len, READSTR-len, "rx_overflow: %lud\n", ctlr->rx_overflow); - len += snprint(p+len, READSTR-len, "rx_overrun: %lud\n", ctlr->rx_overrun); - len += snprint(p+len, READSTR-len, "rx_crc_error: %lud\n", ctlr->rx_crc); - len += snprint(p+len, READSTR-len, "rx_no_sfd: %lud\n", ctlr->rx_no_sfd); - len += snprint(p+len, READSTR-len, "rx_dropped: %lud\n", ctlr->rx_dropped); - len += snprint(p+len, READSTR-len, "tx_packets: %lud\n", ctlr->tx_packets); - len += snprint(p+len, READSTR-len, "rx_packets: %lud\n", ctlr->rx_packets); - snprint(p+len, READSTR-len, "in_packets: %lud\n", ctlr->in_packets); - - n = readstr(offset, a, n, p); - free(p); - return n; -} - -static void -attach(Ether* ether) -{ - Ctlr *ctlr; - - ctlr = ether->ctlr; - ilock(&ctlr->wlock); - if(ctlr->attached){ - iunlock(&ctlr->wlock); - return; - } - ctlr->attached = 1; - iunlock(&ctlr->wlock); -} - -static void -interrupt_handler(Ether *ether, uchar status) -{ - Ctlr *ctlr; - int status0; - int tx_status; - int base; - ctlr = ether->ctlr; - base = ctlr->port; - - status0 = status; - - /* Return if no actual interrupt from i82593 */ - if(!(status0 & SR0_INTERRUPT)) { - print("Wavelan: Interrupt from dead card\n"); - return; - } - ctlr->status = status0; /* Save current status (for commands) */ - if (status0 & SR0_RECEPTION) { - if((status0 & SR0_EVENT_MASK) == SR0_STOP_REG_HIT) { - print("wavelan: receive buffer overflow\n"); - ctlr->rx_overflow++; - outb(LCCR(base), CR0_INT_ACK | OP0_NOP); /* Acknowledge the interrupt */ - return; - } - while(wavelan_receive(ether)) - ; - if (status0 & SR0_EXECUTION) - print("wavelan_cs: interrupt is both rx and tx, status0 = %x\n", - status0); - outb(LCCR(base), CR0_INT_ACK | OP0_NOP); /* Acknowledge the interrupt */ - return; - } - if (!(status0 & SR0_EXECUTION)) { - print("wavelan_cs: interrupt is neither rx or tx, status0 = %x\n", - status0); - outb(LCCR(base), CR0_INT_ACK | OP0_NOP); /* Acknowledge the interrupt */ - return; - } - /* interrupt due to configure_done or IA_setup_done */ - if ((status0 & SR0_EVENT_MASK) == SR0_CONFIGURE_DONE || - (status0 & SR0_EVENT_MASK) == SR0_IA_SETUP_DONE) { - outb(LCCR(base), CR0_INT_ACK | OP0_NOP); /* Acknowledge the interrupt */ - return; - } - /* so a transmit interrupt is remaining */ - if((status0 & SR0_EVENT_MASK) == SR0_TRANSMIT_DONE || - (status0 & SR0_EVENT_MASK) == SR0_RETRANSMIT_DONE) { - tx_status = inb(LCSR(base)); - tx_status |= (inb(LCSR(base)) << 8); - if (!(tx_status & TX_OK)) { - if (tx_status & TX_FRTL) { - print("wavelan_cs: frame too long\n"); - ctlr->tx_too_long++; - } - if (tx_status & TX_UND_RUN) { - /* print("wavelan_csd: DMA underrun\n"); */ - ctlr->tx_DMA_underrun++; - } - if (tx_status & TX_LOST_CTS) { - /* print("wavelan: no CTS\n"); */ - ctlr->tx_carrier_error++; - } - if (tx_status & TX_LOST_CRS) { - /* print("wavelan: lost CRS\n"); */ - ctlr->tx_carrier_error++; - } - if (tx_status & TX_DEFER) { - /* print("wavelan: channel jammed\n"); */ - ctlr->tx_congestion++; - } - if (tx_status & TX_COLL) { - if (tx_status & TX_MAX_COL) { - /* print("wavelan_cs: channel congestion\n"); */ - ctlr->tx_congestion++; - } - } - if (tx_status & TX_HRT_BEAT) { - /* print("wavelan_cs: heart beat\n"); */ - ctlr->tx_heart_beat++; - } - } - - ctlr->tx_packets++; - ctlr->txbusy = 0; - outb(LCCR(base), CR0_INT_ACK | OP0_NOP); /* Acknowledge the interrupt */ - txstart(ether); /* start new transfer if any */ - return; - } - print("wavelan: unknown interrupt\n"); - outb(LCCR(base), CR0_INT_ACK | OP0_NOP); /* Acknowledge the interrupt */ - -} - - -static Block* -rbpalloc(Block* (*f)(int)) -{ - Block *bp; - ulong addr; - - /* - * The receive buffers must be on a 32-byte - * boundary for EISA busmastering. - */ - if(bp = f(ROUNDUP(sizeof(Etherpkt), 4) + 31)){ - addr = (ulong)bp->base; - addr = ROUNDUP(addr, 32); - bp->rp = (uchar*)addr; - } - - return bp; -} - -static int -wavelan_cmd(Ether *ether, int base, char *str, int cmd, int result) -{ - int status; - unsigned long spin; - - /* Spin until the chip finishes executing its current command (if any) */ - do { - outb(LCCR(base), OP0_NOP | CR0_STATUS_3); - status = inb(LCSR(base)); - } while ((status & SR3_EXEC_STATE_MASK) != SR3_EXEC_IDLE); - - outb(LCCR(base), cmd); /* Send the command */ - if(result == SR0_NO_RESULT) { /* Return immediately, if the command - doesn't return a result */ - return(TRUE); - } - - /* Busy wait while the LAN controller executes the command. - * Interrupts had better be enabled (or it will be a long wait). - * (We could enable just the WaveLAN's IRQ..., we do not bother this is only for setup commands) - */ - for(spin = 0; (spin < 10000000); spin++) - ; - outb(LCCR(base), CR0_STATUS_0 | OP0_NOP); - status = inb(LCSR(base)); - if(status & SR0_INTERRUPT){ - if (((status & SR0_EVENT_MASK) == SR0_CONFIGURE_DONE) || - ((status & SR0_EVENT_MASK) == SR0_IA_SETUP_DONE) || - ((status & SR0_EVENT_MASK) == SR0_EXECUTION_ABORTED) || - ((status & SR0_EVENT_MASK) == SR0_DIAGNOSE_PASSED)) - outb(LCCR(base), CR0_INT_ACK | OP0_NOP); /* acknowledge interrupt */ - else - interrupt_handler(ether, status); - } else { - print("wavelan_cmd: %s timeout, status0 = 0x%uX\n", str, status); - outb(OP0_ABORT, LCCR(base)); - spin = 0; - while(spin++ < 250) /* wait for the command to execute */ - delay(1); - return 0; - } - if((status & SR0_EVENT_MASK) != result){ - print("wavelan_cmd: %s failed, status0 = 0x%uX\n", str, status); - return 0; - } - return 1; -} /* wavelan_cmd */ - -static uchar -mmc_in(int base, uchar o) -{ - while (inb(HASR(base)) & HASR_MMI_BUSY) ; /* Wait for MMC to go idle */ - outb(MMR(base), o << 1); /* Set the read address */ - outb(MMD(base), 0); /* Required dummy write */ - while (inb(HASR(base)) & HASR_MMI_BUSY) ; /* Wait for MMC to go idle */ - return((uchar) (inb(MMD(base)))); -} - -/* - * a standard insb causes the wavelan card to not be able - * to simultanisouly receive a packet out of the ether. - * It appears that the card runs out of bandwidth to it's - * internal memory - */ -void -slowinsb(int port, void *buf, int len) -{ - int i, j, n; - uchar *p, *q; - - p = (uchar*)(port + ISAMEM); - q = buf; - n = m->delayloop/2000; - if(n == 0) - n = 1; - for(i = 0; i < len; i++){ - *q++ = *p; - // a small delay of about .5micro seconds - for(j=0; jctlr; - base = ctlr->port; - - /* If buf is NULL, just increment the ring buffer pointer */ - if (buf == 0) - return((ring_ptr - RX_BASE + len) % RX_SIZE + RX_BASE); - while (len > 0) { - /* Position the Program I/O Register at the ring buffer pointer */ - outb(PIORL(base), ring_ptr & 0xff); - outb(PIORH(base), ((ring_ptr >> 8) & PIORH_MASK)); - /* First, determine how much we can read without wrapping around the - ring buffer */ - if ((ring_ptr + len) < (RX_BASE + RX_SIZE)) - chunk_len = len; - else - chunk_len = RX_BASE + RX_SIZE - ring_ptr; - slowinsb(PIOP(base), buf_ptr, chunk_len); - buf_ptr += chunk_len; - len -= chunk_len; - ring_ptr = (ring_ptr - RX_BASE + chunk_len) % RX_SIZE + RX_BASE; - } - return(ring_ptr); -} /* read_ringbuf */ - -static void -wavelan_hardware_send_packet(Ether *ether, void *buf, short length) -{ - Ctlr *ctlr; - int base; - register ushort xmtdata_base = TX_BASE; - ctlr = ether->ctlr; - base = ctlr->port; - - outb(PIORL(base), xmtdata_base & 0xff); - outb(PIORH(base), ((xmtdata_base >> 8) & PIORH_MASK) | PIORH_SEL_TX); - outb(PIOP(base), length & 0xff); /* lsb */ - outb(PIOP(base), length >> 8); /* msb */ - outsb(PIOP(base), buf, length); /* Send the data */ - outb(PIOP(base), OP0_NOP); /* Indicate end of transmit chain */ - - /* Reset the transmit DMA pointer */ - hacr_write_slow(base, HACR_PWR_STAT | HACR_TX_DMA_RESET); - outb(HACR(base), HACR_DEFAULT); - /* Send the transmit command */ - wavelan_cmd(ether, base, "wavelan_hardware_send_packet(): transmit", OP0_TRANSMIT, - SR0_NO_RESULT); -} /* wavelan_hardware_send_packet */ - - - -static int -txstart(Ether *ether) -{ - Ctlr *ctlr; - Block *bp; - int base, length; - int status; - ctlr = ether->ctlr; - base = ctlr->port; - - for(;;) { - if(ctlr->txbp){ - bp = ctlr->txbp; - ctlr->txbp = 0; - } - else{ - bp = qget(ether->oq); - if(bp == nil) - break; - } - - length = BLEN(bp); - length = (ETH_ZLEN < length) ? length : ETH_ZLEN; - outb(LCCR(base), OP0_NOP | CR0_STATUS_3); - status = inb(LCSR(base)); - if ((status & SR3_EXEC_STATE_MASK) == SR3_EXEC_IDLE) { - wavelan_hardware_send_packet(ether, bp->rp, length); - freeb(bp); - ctlr->out_packets++; - } - else{ - ctlr->txbp = bp; - if(ctlr->txbusy == 0){ - ctlr->txbusy = 1; - } - break; - } - - } - return 0; -} /* wavelan txstart */ - - -static int -wavelan_start_of_frame(Ether *ether, int rfp, int wrap) -{ - Ctlr *ctlr; - int base; - int rp, len; - - ctlr = ether->ctlr; - base = ctlr->port; - - rp = (rfp - 5 + RX_SIZE) % RX_SIZE; - outb(PIORL(base), rp & 0xff); - outb(PIORH(base), ((rp >> 8) & PIORH_MASK)); - len = inb(PIOP(base)); - len |= inb(PIOP(base)) << 8; - - if (len > 1600) { /* Sanity check on size */ - print("wavelan_cs: Received frame too large, rfp %d rp %d len 0x%x\n", - rfp, rp, len); - return -1; - } - - if(len < 7){ - print("wavelan_start_of_frame: Received null frame, rfp %d len 0x%x\n", rfp, len); - return(-1); - } - /* Wrap around buffer */ - if(len > ((wrap - (rfp - len) + RX_SIZE) % RX_SIZE)) { /* magic formula ! */ - print("wavelan_start_of_frame: wrap around buffer, wrap %d rfp %d len 0x%x\n",wrap, rfp, len); - return(-1); - } - - return((rp - len + RX_SIZE) % RX_SIZE); -} /* wv_start_of_frame */ - -static void wavelan_read(Ether *ether, int fd_p, int sksize) -{ - Ctlr *ctlr; - Block *bp; - uchar stats[3]; - - ctlr = ether->ctlr; - - ctlr->rx_packets++; - - if ((bp = rbpalloc(iallocb)) == 0){ - print("wavelan: could not rbpalloc(%d).\n", sksize); - ctlr->rx_dropped++; - return; - } else { - fd_p = read_ringbuf(ether, fd_p, ctlr->rbp->rp, sksize); - ctlr->rbp->wp = ctlr->rbp->rp + sksize; - /* read signal level, silence level and signal quality bytes */ - read_ringbuf(ether, (fd_p+4) % RX_SIZE+RX_BASE, stats, 3); - /* - * Hand the packet to the Network Module - */ - etheriq(ether, ctlr->rbp, 1); - ctlr->in_packets++; - ctlr->rbp = bp; - return; - } -} /* wavelan_read */ - -static int -wavelan_receive(Ether *ether) -{ - Ctlr *ctlr; - int base; - int newrfp, rp, len, f_start, status; - int i593_rfp, stat_ptr; - uchar c[4]; - - ctlr = ether->ctlr; - base = ctlr->port; - - /* Get the new receive frame pointer from the i82593 chip */ - outb(LCCR(base), CR0_STATUS_2 | OP0_NOP); - i593_rfp = inb(LCSR(base)); - i593_rfp |= inb(LCSR(base)) << 8; - i593_rfp %= RX_SIZE; - - /* Get the new receive frame pointer from the WaveLAN card. - * It is 3 bytes more than the increment of the i82593 receive - * frame pointer, for each packet. This is because it includes the - * 3 roaming bytes added by the mmc. - */ - newrfp = inb(RPLL(base)); - newrfp |= inb(RPLH(base)) << 8; - newrfp %= RX_SIZE; - -if(0) print("before wavelan_cs: i593_rfp %d stop %d newrfp %d ctlr->rfp %d\n", i593_rfp, ctlr->stop, newrfp, ctlr->rfp); - - if (newrfp == ctlr->rfp) { - if(0) print("wavelan_cs: odd RFPs: i593_rfp %d stop %d newrfp %d ctlr->rfp %d\n", - i593_rfp, ctlr->stop, newrfp, ctlr->rfp); - return 0; - } - - while(newrfp != ctlr->rfp) { - rp = newrfp; - /* Find the first frame by skipping backwards over the frames */ - while (((f_start = wavelan_start_of_frame(ether,rp, newrfp)) != ctlr->rfp) && (f_start != -1)) - rp = f_start; - if(f_start == -1){ - print("wavelan_cs: cannot find start of frame "); - print(" i593_rfp %d stop %d newrfp %d ctlr->rfp %d\n", - i593_rfp, ctlr->stop, newrfp, ctlr->rfp); - ctlr->rfp = rp; - continue; - } - stat_ptr = (rp - 7 + RX_SIZE) % RX_SIZE; - read_ringbuf(ether, stat_ptr, c, 4); - status = c[0] | (c[1] << 8); - len = c[2] | (c[3] << 8); - -if(0) print("%ld: len = %d status = %ux %ux %ux\n", m->ticks, len, status, newrfp, rp); - - if(!(status & RX_RCV_OK)) { - if(status & RX_NO_SFD) ctlr->rx_no_sfd++; - if(status & RX_CRC_ERR) ctlr->rx_crc++; - if(status & RX_OVRRUN) ctlr->rx_overrun++; - - print("wavelan_cs: packet not received ok, status = 0x%x\n", status); - } else wavelan_read(ether, f_start, len - 2); - - ctlr->rfp = rp; /* one packet processed, skip it */ - } - - /* - * Update the frame stop register, but set it to less than - * the full 8K to allow space for 3 bytes of signal strength - * per packet. - */ - ctlr->stop = (i593_rfp + RX_SIZE - ((RX_SIZE / 64) * 3)) % RX_SIZE; - outb(LCCR(base), OP0_SWIT_TO_PORT_1 | CR0_CHNL); - outb(LCCR(base), CR1_STOP_REG_UPDATE | (ctlr->stop >> RX_SIZE_SHIFT)); - outb(LCCR(base), OP1_SWIT_TO_PORT_0); - -if(0){ - newrfp = inb(RPLL(base)); - newrfp |= inb(RPLH(base)) << 8; - newrfp %= RX_SIZE; - - if(newrfp != ctlr->rfp) - print("after wavelan_cs: left over = %d\n", (newrfp - ctlr->rfp + RX_SIZE) % RX_SIZE); -} - - return 1; -} /* wavelan_receive */ - -static void -interrupt(Ureg*, void* arg) -{ - Ether *ether; - Ctlr *ctlr; - int base; - - ether = arg; - ctlr = ether->ctlr; - base = ctlr->port; - - ilock(&ctlr->wlock); - - ctlr->interrupts++; - - outb(LCCR(base), CR0_STATUS_0 | OP0_NOP); - interrupt_handler(ether, inb(LCSR(base))); - iunlock(&ctlr->wlock); - -}; /* wavelan interrupt */ - - - -static void -promiscuous() -{ - ; -}; - -static void -multicast() -{ - ; -}; - -static void -mmc_read(int base, uchar o, uchar *b, int n) -{ - while (n-- > 0) { - while (inb(HASR(base)) & HASR_MMI_BUSY) ; /* Wait for MMC to go idle */ - outb(MMR(base), o << 1); /* Set the read address */ - o++; - - outb(MMD(base), 0); /* Required dummy write */ - while (inb(HASR(base)) & HASR_MMI_BUSY) ; /* Wait for MMC to go idle */ - *b++ = (uchar)(inb(MMD(base))); /* Now do the actual read */ - } -} /* mmc_read */ - - -static void -fee_wait(int base, int del, int numb) -{ int count = 0; - while ((count++ < numb) && (mmc_in(base, MMC_EECTRL) & MMR_FEE_STATUS_BUSY)) - delay(del); - if (count==numb) print("Wavelan: fee wait timed out\n"); -} - -static void -mmc_write_b(int base, uchar o, uchar b) -{ - while (inb(HASR(base)) & HASR_MMI_BUSY) ; /* Wait for MMC to go idle */ - outb(MMR(base), (uchar)((o << 1) | MMR_MMI_WR)); - outb(MMD(base), (uchar)(b)); -} /* mmc_write_b */ - -static void -mmc_write(int base, uchar o, uchar *b, int n) -{ - o += n; - b += n; - while (n-- > 0 ) - mmc_write_b(base, --o, *(--b)); -} /* mmc_write */ - - -static void wavelan_mmc_init(Ether *ether, int port) -{ - Ctlr *ctlr; - mmw_t m; - ctlr = ether->ctlr; - - memset(&m, 0x00, sizeof(m)); - - /* - * Set default modem control parameters. - * See NCR document 407-0024326 Rev. A. - */ - m.mmw_jabber_enable = 0x01; - m.mmw_anten_sel = MMW_ANTEN_SEL_ALG_EN; - m.mmw_ifs = 0x20; - m.mmw_mod_delay = 0x04; - m.mmw_jam_time = 0x38; - m.mmw_encr_enable = 0; - m.mmw_des_io_invert = 0; - m.mmw_freeze = 0; - m.mmw_decay_prm = 0; - m.mmw_decay_updat_prm = 0; - m.mmw_loopt_sel = MMW_LOOPT_SEL_UNDEFINED; - m.mmw_thr_pre_set = 0x04; /* PCMCIA */ - m.mmw_quality_thr = 0x03; - m.mmw_netw_id_l = ctlr->nwid[1]; /* use nwid of PSA memory */ - m.mmw_netw_id_h = ctlr->nwid[0]; - - mmc_write(port, 0, (uchar *)&m, 37); /* size of mmw_t == 37 */ - - /* Start the modem's receive unit on version 2.00 */ - /* 2.4 Gz: half-card ver */ - /* 2.4 Gz */ - /* 2.4 Gz: position ch # */ - mmc_write_b(port, MMC_EEADDR, 0x0f); /* 2.4 Gz: named ch, wc=16 */ - mmc_write_b(port, MMC_EECTRL,MMC_EECTRL_DWLD | /* 2.4 Gz: Download Synths */ - MMC_EECTRL_EEOP_READ); /* 2.4 Gz: Read EEPROM */ - fee_wait(port, 10, 100); /* 2.4 Gz: wait for download */ - /* 2.4 Gz */ - mmc_write_b(port, MMC_EEADDR,0x61); /* 2.4 Gz: default pwr, wc=2 */ - mmc_write_b(port, MMC_EECTRL,MMC_EECTRL_DWLD | /* 2.4 Gz: Download Xmit Pwr */ - MMC_EECTRL_EEOP_READ); /* 2.4 Gz: Read EEPROM */ - fee_wait(port, 10, 100); /* 2.4 Gz: wait for download */ - -} /* wavelan_mmc_init */ - - -int wavelan_diag(Ether *ether, int port) -{ - if (wavelan_cmd(ether, port, "wavelan_diag(): diagnose", OP0_DIAGNOSE, - SR0_DIAGNOSE_PASSED)){ - return 0; - } - print("wavelan_cs: i82593 Self Test failed!\n"); - return 1; -} /* wavelan_diag */ - - - -int wavelan_hw_config(int base, Ether *ether) -{ - - /* the i82593_conf_block uses bit fields which are not - * machine independent. In particular this code does not work - * on the powerPC (bigendian) - */ - if(0) { - struct i82593_conf_block cfblk; - - memset(&cfblk, 0x00, sizeof(struct i82593_conf_block)); - cfblk.d6mod = FALSE; /* Run in i82593 advanced mode */ - cfblk.fifo_limit = 6; /* = 48 bytes rx and tx fifo thresholds */ - cfblk.forgnesi = FALSE; /* 0=82C501, 1=AMD7992B compatibility */ - cfblk.fifo_32 = 0; - cfblk.throttle_enb = TRUE; - cfblk.contin = TRUE; /* enable continuous mode */ - cfblk.cntrxint = FALSE; /* enable continuous mode receive interrupts */ - cfblk.addr_len = WAVELAN_ADDR_SIZE; - cfblk.acloc = TRUE; /* Disable source addr insertion by i82593 */ - cfblk.preamb_len = 2; /* 7 byte preamble */ - cfblk.loopback = FALSE; - cfblk.lin_prio = 0; /* conform to 802.3 backoff algoritm */ - cfblk.exp_prio = 0; /* conform to 802.3 backoff algoritm */ - cfblk.bof_met = 0; /* conform to 802.3 backoff algoritm */ - cfblk.ifrm_spc = 6; /* 96 bit times interframe spacing */ - cfblk.slottim_low = 0x10 & 0x7; /* 512 bit times slot time */ - cfblk.slottim_hi = 0x10 >> 3; - cfblk.max_retr = 15; - cfblk.prmisc = FALSE; /* Promiscuous mode ?? */ - cfblk.bc_dis = FALSE; /* Enable broadcast reception */ - cfblk.crs_1 = TRUE; /* Transmit without carrier sense */ - cfblk.nocrc_ins = FALSE; /* i82593 generates CRC */ - cfblk.crc_1632 = FALSE; /* 32-bit Autodin-II CRC */ - cfblk.crs_cdt = FALSE; /* CD not to be interpreted as CS */ - cfblk.cs_filter = 0; /* CS is recognized immediately */ - cfblk.crs_src = FALSE; /* External carrier sense */ - cfblk.cd_filter = 0; /* CD is recognized immediately */ - cfblk.min_fr_len = 64 >> 2; /* Minimum frame length 64 bytes */ - cfblk.lng_typ = FALSE; /* Length field > 1500 = type field */ - cfblk.lng_fld = TRUE; /* Disable 802.3 length field check */ - cfblk.rxcrc_xf = TRUE; /* Don't transfer CRC to memory */ - cfblk.artx = TRUE; /* Disable automatic retransmission */ - cfblk.sarec = TRUE; /* Disable source addr trig of CD */ - cfblk.tx_jabber = TRUE; /* Disable jabber jam sequence */ - cfblk.hash_1 = FALSE; /* Use bits 0-5 in mc address hash */ - cfblk.lbpkpol = TRUE; /* Loopback pin active high */ - cfblk.fdx = FALSE; /* Disable full duplex operation */ - cfblk.dummy_6 = 0x3f; /* all ones */ - cfblk.mult_ia = FALSE; /* No multiple individual addresses */ - cfblk.dis_bof = FALSE; /* Disable the backoff algorithm ?! */ - cfblk.dummy_1 = TRUE; /* set to 1 */ - cfblk.tx_ifs_retrig = 3; /* Hmm... Disabled */ - cfblk.mc_all = FALSE; /* No multicast all mode */ - cfblk.rcv_mon = 0; /* Monitor mode disabled */ - cfblk.frag_acpt = TRUE;/* Do not accept fragments */ - cfblk.tstrttrs = FALSE; /* No start transmission threshold */ - cfblk.fretx = TRUE; /* FIFO automatic retransmission */ - cfblk.syncrqs = TRUE; /* Synchronous DRQ deassertion... */ - cfblk.sttlen = TRUE; /* 6 byte status registers */ - cfblk.rx_eop = TRUE; /* Signal EOP on packet reception */ - cfblk.tx_eop = TRUE; /* Signal EOP on packet transmission */ - cfblk.rbuf_size = RX_SIZE>>11; /* Set receive buffer size */ - cfblk.rcvstop = TRUE; /* Enable Receive Stop Register */ - outb(PIORL(base), (TX_BASE & 0xff)); - outb(PIORH(base), (((TX_BASE >> 8) & PIORH_MASK) | PIORH_SEL_TX)); - outb(PIOP(base), (sizeof(struct i82593_conf_block) & 0xff)); /* lsb */ - outb(PIOP(base), (sizeof(struct i82593_conf_block) >> 8)); /* msb */ - outsb(PIOP(base), ((char *) &cfblk), sizeof(struct i82593_conf_block)); - } else { - /* - * The following are the values that result in the above on - * the 386. Sleazy, but these values don't change and I - * don't have any docs anyway - */ - uchar buf[16] = { 0x86, 0x80, 0x2e, 0x00, 0x60, 0x00, 0xf2, 0x08, - 0x00, 0x40, 0xbe, 0x00, 0x3f, 0x47, 0xf1, 0x24}; - - outb(PIORL(base), (TX_BASE & 0xff)); - outb(PIORH(base), (((TX_BASE >> 8) & PIORH_MASK) | PIORH_SEL_TX)); - outb(PIOP(base), (sizeof(buf) & 0xff)); /* lsb */ - outb(PIOP(base), (sizeof(buf) >> 8)); /* msb */ - outsb(PIOP(base), buf, sizeof(buf)); - } - - /* reset transmit DMA pointer */ - hacr_write_slow(base, HACR_PWR_STAT | HACR_TX_DMA_RESET); - outb(HACR(base), HACR_DEFAULT); - if(!wavelan_cmd(ether, base, "wavelan_hw_config(): configure", OP0_CONFIGURE, - SR0_CONFIGURE_DONE)) - return(FALSE); - - /* Initialize adapter's ethernet MAC address */ - outb(PIORL(base), (TX_BASE & 0xff)); - outb(PIORH(base), (((TX_BASE >> 8) & PIORH_MASK) | PIORH_SEL_TX)); - outb(PIOP(base), WAVELAN_ADDR_SIZE); /* byte count lsb */ - outb(PIOP(base), 0); /* byte count msb */ - outsb(PIOP(base), ðer->ea[0], WAVELAN_ADDR_SIZE); - /* reset transmit DMA pointer */ - hacr_write_slow(base, HACR_PWR_STAT | HACR_TX_DMA_RESET); - outb(HACR(base), HACR_DEFAULT); - if(!wavelan_cmd(ether, base, "wavelan_hw_config(): ia-setup", OP0_IA_SETUP, SR0_IA_SETUP_DONE)) - return(FALSE); - return(TRUE); -} /* wavelan_hw_config */ - -static void -wavelan_graceful_shutdown(Ether *ether, int base) -{ - int status; - - /* First, send the LAN controller a stop receive command */ - wavelan_cmd(ether, base, "wavelan_graceful_shutdown(): stop-rcv", OP0_STOP_RCV, - SR0_NO_RESULT); - /* Then, spin until the receive unit goes idle */ - do { - outb(LCCR(base), (OP0_NOP | CR0_STATUS_3)); - status = inb(LCSR(base)); - } while((status & SR3_RCV_STATE_MASK) != SR3_RCV_IDLE); - - /* Now, spin until the chip finishes executing its current command */ - do { - outb(LCCR(base), (OP0_NOP | CR0_STATUS_3)); - status = inb(LCSR(base)); - } while ((status & SR3_EXEC_STATE_MASK) != SR3_EXEC_IDLE); -} /* wavelan_graceful_shutdown */ - - -static void -wavelan_ru_start(Ether *ether, int base) -{ - Ctlr *ctlr; - ctlr = ether->ctlr; - - /* - * We need to start from a quiescent state. To do so, we could check - * if the card is already running, but instead we just try to shut - * it down. First, we disable reception (in case it was already enabled). - */ - - wavelan_graceful_shutdown(ether, base); - - /* Now we know that no command is being executed. */ - - /* Set the receive frame pointer and stop pointer */ - ctlr->rfp = 0; - outb(LCCR(base), OP0_SWIT_TO_PORT_1 | CR0_CHNL); - - /* Reset ring management. This sets the receive frame pointer to 1 */ - outb(LCCR(base), OP1_RESET_RING_MNGMT); - ctlr->stop = (0 + RX_SIZE - ((RX_SIZE / 64) * 3)) % RX_SIZE; - outb(LCCR(base), CR1_STOP_REG_UPDATE | (ctlr->stop >> RX_SIZE_SHIFT)); - outb(LCCR(base), OP1_INT_ENABLE); - outb(LCCR(base), OP1_SWIT_TO_PORT_0); - - /* Reset receive DMA pointer */ - outb(HACR(base), HACR_PWR_STAT | HACR_RX_DMA_RESET); - delay(100); - outb(HACR(base), HACR_PWR_STAT); - delay(100); - - /* Receive DMA on channel 1 */ - wavelan_cmd(ether, base, "wavelan_ru_start(): rcv-enable", - (CR0_CHNL | OP0_RCV_ENABLE), SR0_NO_RESULT); - -} /* wavelan_ru_start */ - -static void -transmit(Ether* ether) -{ - Ctlr *ctlr; - ctlr = ether->ctlr; - - ilock(&ctlr->wlock); - txstart(ether); - iunlock(&ctlr->wlock); -} - - -static int -reset(Ether* ether) -{ - int slot, p; - int port; - char *pp; - Ctlr *ctlr; - PCMmap *m; - - ctlr = ether->ctlr = malloc(sizeof(Ctlr)); - ilock(&ctlr->wlock); - - if(ether->port == 0) - ether->port = 0x280; - port = ether->port; - - if((slot = pcmspecial(ether->type, ether)) < 0) { - print("could not find the PCMCIA WaveLAN card.\n"); - return -1; - } - - - print("#l%dWaveLAN: slot %d, port 0x%ulX irq %ld type %s\n", ether->ctlrno, slot, ether->port, ether->irq, ether->type); - - /* create a receive buffer */ - ctlr->rbp = rbpalloc(iallocb); - if(ctlr->rbp == nil) - panic("can't reset ethernet: out of memory"); - -/* map a piece of memory (Attribute memory) first */ - m = pcmmap(slot, 0, 0x5000, 1); - if (m==0) { - return 1; - } -/* read ethernet address from the card and put in ether->ea */ - pp = (char*)(KZERO|m->isa) + 0x0E00 + 2*0x10; - for(p = 0; pea); p++) - ether->ea[p] = (uchar) (*(pp+2*p))&0xFF; - -// print("wavelan: dump of PSA memory\n"); -// pp = (char *) (KZERO|m->isa) + 0x0E00; -// for(p=0; p<64; p++) { -// print("%2uX ", (*(pp+2*p)&0xFF)); -// if (p%16==15) print("\n"); -// } - -/* read nwid from PSA into ctlr->nwid */ - pp = (char*)(KZERO|m->isa) + 0x0E00; - ctlr->nwid[0] = *(pp+2*0x23); - ctlr->nwid[1] = *(pp+2*0x24); - -/* access the configuration option register */ - pp = (char *)(KZERO|m->isa) + 0x4000; - *pp = *pp | COR_SW_RESET; - delay(5); - *pp = (COR_LEVEL_IRQ | COR_CONFIG); - delay(5); - - hacr_write_slow(port, HACR_RESET); - outb(HACR(port), HACR_DEFAULT); - - if(inb(HASR(port)) & HASR_NO_CLK) { - print("wavelan: modem not connected\n"); - return 1; - } - - wavelan_mmc_init(ether, port); /* initialize modem */ - - outb(LCCR(port), OP0_RESET); /* reset the LAN controller */ - delay(10); - - if (wavelan_hw_config(port, ether) == FALSE) - return 1; - - if (wavelan_diag(ether, port) == 1) - return 1; - wavelan_ru_start(ether, port); - - print("wavelan: init done; receiver started\n"); - - iunlock(&ctlr->wlock); - - ctlr->port = port; - ether->port = port; - ether->mbps = 2; /* 2 Mpbs */ - ether->attach = attach; - ether->transmit = transmit; - ether->interrupt = interrupt; - ether->ifstat = ifstat; - - ether->promiscuous = promiscuous; - ether->multicast = multicast; - ether->arg = ether; - - return 0; /* reset succeeded */ -} - -void -etherwavelanlink(void) -{ - addethercard("WaveLAN", reset); -} diff --git a/mpc/etherwavelan.h b/mpc/etherwavelan.h deleted file mode 100644 index 3fa7f2b7a007120a1a0253b86b3fa2d5f0b86deb..0000000000000000000000000000000000000000 --- a/mpc/etherwavelan.h +++ /dev/null @@ -1,494 +0,0 @@ - -/* Intel 82593 CSMA/CD Core LAN Controller */ - -/* Port 0 Command Register definitions */ - -/* Execution operations */ -enum { - OP0_NOP = 0, /* CHNL = 0 */ - OP0_SWIT_TO_PORT_1 = 0, /* CHNL = 1 */ - OP0_IA_SETUP = 1, - OP0_CONFIGURE = 2, - OP0_MC_SETUP = 3, - OP0_TRANSMIT = 4, - OP0_TDR = 5, - OP0_DUMP = 6, - OP0_DIAGNOSE = 7, - OP0_TRANSMIT_NO_CRC = 9, - OP0_RETRANSMIT = 12, - OP0_ABORT = 13, -/* Reception operations */ - OP0_RCV_ENABLE = 8, - OP0_RCV_DISABLE = 10, - OP0_STOP_RCV = 11, -/* Status pointer control operations */ - OP0_FIX_PTR = 15, /* CHNL = 1 */ - OP0_RLS_PTR = 15, /* CHNL = 0 */ - OP0_RESET = 14, -}; -enum { - CR0_CHNL = (1 << 4), /* 0=Channel 0, 1=Channel 1 */ - CR0_STATUS_0 = 0x00, - CR0_STATUS_1 = 0x20, - CR0_STATUS_2 = 0x40, - CR0_STATUS_3 = 0x60, - CR0_INT_ACK = (1 << 7), /* 0=No ack, 1=acknowledge */ -}; -/* Port 0 Status Register definitions */ -enum { - SR0_NO_RESULT = 0, /* dummy */ - SR0_EVENT_MASK = 0x0f, - SR0_IA_SETUP_DONE = 1, - SR0_CONFIGURE_DONE = 2, - SR0_MC_SETUP_DONE = 3, - SR0_TRANSMIT_DONE = 4, - SR0_TDR_DONE = 5, - SR0_DUMP_DONE = 6, - SR0_DIAGNOSE_PASSED = 7, - SR0_END_OF_FRAME = 8, - SR0_TRANSMIT_NO_CRC_DONE = 9, - SR0_RETRANSMIT_DONE = 12, - SR0_EXECUTION_ABORTED = 13, - SR0_RECEPTION_ABORTED = 10, - SR0_DIAGNOSE_FAILED = 15, - SR0_STOP_REG_HIT = 11, - - SR0_CHNL = (1 << 4), - SR0_EXECUTION = (1 << 5), - SR0_RECEPTION = (1 << 6), - SR0_INTERRUPT = (1 << 7), -}; -enum { - SR3_EXEC_STATE_MASK = 0x03, - SR3_EXEC_IDLE = 0, - SR3_TX_ABORT_IN_PROGRESS = 1, - SR3_EXEC_ACTIVE = 2, - SR3_ABORT_IN_PROGRESS = 3, - SR3_EXEC_CHNL = (1 << 2), - SR3_STP_ON_NO_RSRC = (1 << 3), - SR3_RCVING_NO_RSRC = (1 << 4), - SR3_RCV_STATE_MASK = 0x60, - SR3_RCV_IDLE = 0x00, - SR3_RCV_READY = 0x20, - SR3_RCV_ACTIVE = 0x40, - SR3_RCV_STOP_IN_PROG = 0x60, - SR3_RCV_CHNL = (1 << 7), -}; -/* Port 1 Command Register definitions */ -enum { - OP1_NOP = 0, - OP1_SWIT_TO_PORT_0 = 1, - OP1_INT_DISABLE = 2, - OP1_INT_ENABLE = 3, - OP1_SET_TS = 5, - OP1_RST_TS = 7, - OP1_POWER_DOWN = 8, - OP1_RESET_RING_MNGMT = 11, - OP1_RESET = 14, - OP1_SEL_RST = 15, -}; -enum { - CR1_STATUS_4 = 0x00, - CR1_STATUS_5 = 0x20, - CR1_STATUS_6 = 0x40, - CR1_STOP_REG_UPDATE = (1 << 7), -}; -/* Receive frame status bits */ -enum { - RX_RCLD = (1 << 0), - RX_IA_MATCH = (1 << 1), - RX_NO_AD_MATCH = (1 << 2), - RX_NO_SFD = (1 << 3), - RX_SRT_FRM = (1 << 7), - RX_OVRRUN = (1 << 8), - RX_ALG_ERR = (1 << 10), - RX_CRC_ERR = (1 << 11), - RX_LEN_ERR = (1 << 12), - RX_RCV_OK = (1 << 13), - RX_TYP_LEN = (1 << 15), -}; -/* Transmit status bits */ -enum { - TX_NCOL_MASK = 0x0f, - TX_FRTL = (1 << 4), - TX_MAX_COL = (1 << 5), - TX_HRT_BEAT = (1 << 6), - TX_DEFER = (1 << 7), - TX_UND_RUN = (1 << 8), - TX_LOST_CTS = (1 << 9), - TX_LOST_CRS = (1 << 10), - TX_LTCOL = (1 << 11), - TX_OK = (1 << 13), - TX_COLL = (1 << 15), -}; - -typedef struct { - Lock wlock; - int port; /* port number */ - int status; /* interrupt status */ - int stop; - int rfp; - int attached; - Block* rbp; /* receive buffer */ - Block* txbp; /* FIFO -based transmission */ - int txbusy; - uchar nwid[2]; /* Network ID */ - long interrupts; /* statistics */ - long upinterrupts; - long dninterrupts; - long out_packets; - long in_packets; - long tx_too_long; - long tx_DMA_underrun; - long tx_carrier_error; - long tx_congestion; - long tx_heart_beat; - long rx_overflow; - long rx_overrun; - long rx_crc; - long rx_no_sfd; - long rx_dropped; - long tx_packets; - long rx_packets; - long int_errors; - long read_errors; - int upenabled; - int dnenabled; - int waiting; -} Ctlr; - - -struct i82593_conf_block { - uchar fifo_limit : 4, - forgnesi : 1, - fifo_32 : 1, - d6mod : 1, - throttle_enb : 1; - uchar throttle : 6, - cntrxint : 1, - contin : 1; - uchar addr_len : 3, - acloc : 1, - preamb_len : 2, - loopback : 2; - uchar lin_prio : 3, - tbofstop : 1, - exp_prio : 3, - bof_met : 1; - uchar : 4, - ifrm_spc : 4; - uchar : 5, - slottim_low : 3; - uchar slottim_hi : 3, - : 1, - max_retr : 4; - uchar prmisc : 1, - bc_dis : 1, - : 1, - crs_1 : 1, - nocrc_ins : 1, - crc_1632 : 1, - : 1, - crs_cdt : 1; - uchar cs_filter : 3, - crs_src : 1, - cd_filter : 3, - : 1; - uchar : 2, - min_fr_len : 6; - uchar lng_typ : 1, - lng_fld : 1, - rxcrc_xf : 1, - artx : 1, - sarec : 1, - tx_jabber : 1, /* why is this called max_len in the manual? */ - hash_1 : 1, - lbpkpol : 1; - uchar : 6, - fdx : 1, - : 1; - uchar dummy_6 : 6, /* supposed to be ones */ - mult_ia : 1, - dis_bof : 1; - uchar dummy_1 : 1, /* supposed to be one */ - tx_ifs_retrig : 2, - mc_all : 1, - rcv_mon : 2, - frag_acpt : 1, - tstrttrs : 1; - uchar fretx : 1, - runt_eop : 1, - hw_sw_pin : 1, - big_endn : 1, - syncrqs : 1, - sttlen : 1, - tx_eop : 1, - rx_eop : 1; - uchar rbuf_size : 5, - rcvstop : 1, - : 2; -}; - -/* WaveLAN host interface definitions */ - -#define LCCR(base) (base) /* LAN Controller Command Register */ -#define LCSR(base) (base) /* LAN Controller Status Register */ -#define HACR(base) (base+0x1) /* Host Adapter Command Register */ -#define HASR(base) (base+0x1) /* Host Adapter Status Register */ -#define PIORL(base) (base+0x2) /* Program I/O Register Low */ -#define RPLL(base) (base+0x2) /* Receive Pointer Latched Low */ -#define PIORH(base) (base+0x3) /* Program I/O Register High */ -#define RPLH(base) (base+0x3) /* Receive Pointer Latched High */ -#define PIOP(base) (base+0x4) /* Program I/O Port */ -#define MMR(base) (base+0x6) /* MMI Address Register */ -#define MMD(base) (base+0x7) /* MMI Data Register */ - -/* Host Adaptor Command Register bit definitions */ -enum { - HACR_LOF = (1 << 3), /* Lock Out Flag, toggle every 250ms */ - HACR_PWR_STAT = (1 << 4), /* Power State, 1=active, 0=sleep */ - HACR_TX_DMA_RESET = (1 << 5), /* Reset transmit DMA ptr on high */ - HACR_RX_DMA_RESET = (1 << 6), /* Reset receive DMA ptr on high */ - HACR_ROM_WEN = (1 << 7), /* EEPROM write enabled when true */ - - HACR_RESET = (HACR_TX_DMA_RESET | HACR_RX_DMA_RESET), - HACR_DEFAULT = (HACR_PWR_STAT), -}; -/* Host Adapter Status Register bit definitions */ -enum { - HASR_MMI_BUSY = (1 << 2), /* MMI is busy when true */ - HASR_LOF = (1 << 3), /* Lock out flag status */ - HASR_NO_CLK = (1 << 4), /* active when modem not connected */ -}; -/* Miscellaneous bit definitions */ -enum { - PIORH_SEL_TX = (1 << 5), /* PIOR points to 0=rx/1=tx buffer */ - MMR_MMI_WR = (1 << 0), /* Next MMI cycle is 0=read, 1=write */ - PIORH_MASK = 0x1f, /* only low 5 bits are significant */ - RPLH_MASK = 0x1f, /* only low 5 bits are significant */ - MMI_ADDR_MASK = 0x7e, /* Bits 1-6 of MMR are significant */ -}; -/* Attribute Memory map */ -enum { - CIS_ADDR = 0x0000, /* Card Information Status Register */ - PSA_ADDR = 0x0e00, /* Parameter Storage Area address */ - EEPROM_ADDR = 0x1000, /* EEPROM address */ - COR_ADDR = 0x4000, /* Configuration Option Register */ -}; -/* Configuration Option Register bit definitions */ -enum { - COR_CONFIG = (1 << 0), /* Config Index, 0 when unconfigured */ - COR_SW_RESET = (1 << 7), /* Software Reset on true */ - COR_LEVEL_IRQ = (1 << 6), /* Level IRQ */ -}; -/* Local Memory map */ -enum { - RX_BASE = 0x0000, /* Receive memory, 8 kB */ - TX_BASE = 0x2000, /* Transmit memory, 2 kB */ - UNUSED_BASE = 0x2800, /* Unused, 22 kB */ - RX_SIZE = (TX_BASE-RX_BASE), /* Size of receive area */ - RX_SIZE_SHIFT = 6, /* Bits to shift in stop register */ -}; -#define MMI_WRITE(base,cmd,val) \ - while(inb(HASR(base)) & HASR_MMI_BUSY) ; \ - outb(MMR(base), ((cmd) << 1) | MMR_MMI_WR); \ - outb(MMD(base), va); - - -#define TRUE 1 -#define FALSE 0 -#define ETH_ZLEN 64 /* minimum length 64 bytes */ - -#define WAVELAN_ADDR_SIZE 6 /* Size of a MAC address */ - -#define SA_ADDR0 0x08 /* First octet of AT&T WaveLAN MAC addr */ -#define SA_ADDR1 0x00 /* Second octet of AT&T WaveLAN MAC addr */ -#define SA_ADDR2 0x0E /* Third octet of AT&T WaveLAN MAC addr */ - -#define WAVELAN_MTU 1500 /* Maximum size of Wavelan packet */ - -/* - * Parameter Storage Area (PSA). - */ -typedef struct psa_t psa_t; -struct psa_t -{ - /* For the PCMCIA Adapter, locations 0x00-0x0F are fixed at 00 */ - uchar psa_io_base_addr_1; /* [0x00] Base address 1 ??? */ - uchar psa_io_base_addr_2; /* [0x01] Base address 2 */ - uchar psa_io_base_addr_3; /* [0x02] Base address 3 */ - uchar psa_io_base_addr_4; /* [0x03] Base address 4 */ - uchar psa_rem_boot_addr_1; /* [0x04] Remote Boot Address 1 */ - uchar psa_rem_boot_addr_2; /* [0x05] Remote Boot Address 2 */ - uchar psa_rem_boot_addr_3; /* [0x06] Remote Boot Address 3 */ - uchar psa_holi_params; /* [0x07] HOst Lan Interface (HOLI) Parameters */ - uchar psa_int_req_no; /* [0x08] Interrupt Request Line */ - uchar psa_unused0[7]; /* [0x09-0x0F] unused */ - uchar psa_univ_mac_addr[WAVELAN_ADDR_SIZE]; - /* [0x10-0x15] Universal (factory) MAC Address */ - uchar psa_local_mac_addr[WAVELAN_ADDR_SIZE]; /* [0x16-1B] Local MAC Address */ - uchar psa_univ_local_sel; /* [0x1C] Universal Local Selection */ - uchar psa_comp_number; /* [0x1D] Compatability Number: */ - uchar psa_thr_pre_set; /* [0x1E] Modem Threshold Preset */ - uchar psa_feature_select; /* [0x1F] Call code required (1=on) */ - uchar psa_subband; /* [0x20] Subband */ - uchar psa_quality_thr; /* [0x21] Modem Quality Threshold */ - uchar psa_mod_delay; /* [0x22] Modem Delay ??? (reserved) */ - uchar psa_nwid[2]; /* [0x23-0x24] Network ID */ - uchar psa_nwid_select; /* [0x25] Network ID Select */ - uchar psa_encryption_select; /* [0x26] Encryption On Off */ - uchar psa_encryption_key[8]; /* [0x27-0x2E] Encryption Key */ - uchar psa_databus_width; /* [0x2F] AT Dbus width select 8/16 */ - uchar psa_call_code[8]; /* [0x30-0x37] (Japan) Call Code */ - uchar psa_reserved[4]; /* [0x38-0x3B] Reserved - fixed (00) */ - uchar psa_conf_status; /* [0x3C] Conf Status, bit 0=1:config*/ - uchar psa_crc[2]; /* [0x3D] CRC-16 over PSA */ - uchar psa_crc_status; /* [0x3F] CRC Valid Flag */ -}; -enum { - PSA_UNIVERSAL = 0, /* Universal (factory) */ - PSA_LOCAL = 1, /* Local */ -}; -enum { - PSA_COMP_PC_AT_915 = 0, /* PC-AT 915 MHz */ - PSA_COMP_PC_MC_915 = 1, /* PC-MC 915 MHz */ - PSA_COMP_PC_AT_2400 = 2, /* PC-AT 2.4 GHz */ - PSA_COMP_PC_MC_2400 = 3, /* PC-MC 2.4 GHz */ - PSA_COMP_PCMCIA_915 = 4, /* PCMCIA 915 MHz */ -}; -enum { - PSA_SUBBAND_915 = 0, /* 915 MHz */ - PSA_SUBBAND_2425 = 1, /* 2425 MHz */ - PSA_SUBBAND_2460 = 2, /* 2460 MHz */ - PSA_SUBBAND_2484 = 3, /* 2484 MHz */ - PSA_SUBBAND_2430_5 = 4, /* 2430.5 MHz */ -}; -/* - * Modem Management Controller (MMC) write structure. - */ -typedef struct mmw_t mmw_t; -struct mmw_t -{ - uchar mmw_encr_key[8]; /* 0x00--07 encryption key */ - uchar mmw_encr_enable; /* 0x08 enable/disable encryption */ - uchar mmw_unused0; /* 0x09 unused */ - uchar mmw_des_io_invert; /* 0x0A ??? */ - uchar mmw_unused1[5]; /* 0x0B - 0F unused */ - uchar mmw_loopt_sel; /* 0x10 looptest selection */ - uchar mmw_jabber_enable; /* 0x11 jabber timer enable */ - uchar mmw_freeze; /* 0x12 freeze / unfreeeze signal level */ - uchar mmw_anten_sel; /* 0x13 antenna selection */ - uchar mmw_ifs; /* 0x14 inter frame spacing */ - uchar mmw_mod_delay; /* 0x15 modem delay */ - uchar mmw_jam_time; /* 0x16 jamming time */ - uchar mmw_unused2; /* 0x17 unused */ - uchar mmw_thr_pre_set; /* 0x18 level threshold preset */ - uchar mmw_decay_prm; /* 0x19 decay parameters */ - uchar mmw_decay_updat_prm; /* 0x1A decay update parameterz */ - uchar mmw_quality_thr; /* 0x1B quality (z-quotient) threshold */ - uchar mmw_netw_id_l; /* 0x1C NWID low order byte */ - uchar mmw_netw_id_h; /* 0x1D NWID high order byte */ - uchar mmw_mode_sel; /* 0x1E */ - uchar mmw_dummy; /* 0x1F */ - uchar mmw_eectrl; /* 0x20 2.4 Gz */ - uchar mmw_eeaddr; /* 0x21 2.4 Gz */ - uchar mmw_eedatal; /* 0x22 2.4 Gz */ - uchar mmw_eedatah; /* 0x23 2.4 Gz */ - uchar mmw_analctrl; /* 0x24 2.4 Gz */ - -}; - -enum { MMC_EECTRL = 0x20, - MMC_EEADDR = 0x21, - MMC_ANALCTRL = 0x24, -}; -enum { - MMW_LOOPT_SEL_UNDEFINED = 0x40, /* undefined */ - MMW_LOOPT_SEL_INT = 0x20, /* activate Attention Request */ - MMW_LOOPT_SEL_LS = 0x10, /* looptest w/o collision avoidance */ - MMW_LOOPT_SEL_LT3A = 0x08, /* looptest 3a */ - MMW_LOOPT_SEL_LT3B = 0x04, /* looptest 3b */ - MMW_LOOPT_SEL_LT3C = 0x02, /* looptest 3c */ - MMW_LOOPT_SEL_LT3D = 0x01, /* looptest 3d */ -}; -enum { - MMW_ANTEN_SEL_SEL = 0x01, /* direct antenna selection */ - MMW_ANTEN_SEL_ALG_EN = 0x02, /* antenna selection algo. enable */ -}; - -#define mmwoff(p,f) (unsigned short)((void *)(&((mmw_t *)((void *)0 + (p)))->f) - (void *)0) - -/* - * Modem Management Controller (MMC) read structure. - */ -typedef struct mmr_t mmr_t; -struct mmr_t -{ - uchar mmr_unused0[8]; /* 0x00..07 unused */ - uchar mmr_des_status; /* 0x08 encryption status */ - uchar mmr_des_avail; /* 0x09 encryption available (0x55 read) */ - uchar mmr_des_io_invert; /* 0x0A des I/O invert register */ - uchar mmr_unused1[5]; /* 0x0B..0F unused */ - uchar mmr_dce_status; /* 0x10 DCE status */ - uchar mmr_mmr_dsp_id; /* 0x11 DSP id (AA = Deadalus rev A) - uchar mmr_unused2[2]; /* 0x12..13 unused */ - uchar mmr_correct_nwid_l; /* 0x14 no. of correct NWID's rxd (low) */ - uchar mmr_correct_nwid_h; /* 0x15 no. of correct NWID's rxd (high) */ - uchar mmr_wrong_nwid_l; /* 0x16 count of wrong NWID's received (low) */ - uchar mmr_wrong_nwid_h; /* 0x17 count of wrong NWID's received (high) */ - uchar mmr_thr_pre_set; /* 0x18 level threshold preset */ - uchar mmr_signal_lvl; /* 0x19 signal level */ - uchar mmr_silence_lvl; /* 0x1A silence level */ - uchar mmr_sgnl_qual; /* 0x1B signal quality */ - uchar mmr_netw_id_l; /* 0x1C NWID low order byte ??? */ - uchar mmr_unused3[3]; /* 0x1D..1F unused */ - uchar mmr_fee_status; /* 0x20 status of frequency eeprom */ - uchar mmr_unused4[1]; /* 0x21 */ - uchar mmr_fee_data_l; /* 0x22 read data from eeprom (low) */ - uchar mmr_fee_data_h; /* 0x23 read data from eeprom (high) */ -}; -enum { - MMR_DCE_STATUS_ENERG_DET = 0x01, /* energy detected */ - MMR_DCE_STATUS_LOOPT_IND = 0x02, /* loop test indicated */ - MMR_DCE_STATUS_XMTITR_IND = 0x04, /* transmitter on */ - MMR_DCE_STATUS_JBR_EXPIRED = 0x08, /* jabber timer expired */ -}; -enum { - MMR_FEE_STATUS_ID = 0xF0, /* modem revision id */ - MMR_FEE_STATUS_DWLD = 0x08, /* download in progress */ - MMR_FEE_STATUS_BUSY = 0x04, /* EEprom busy */ -}; -enum { - MMR_SGNL_QUAL_0 = 0x01, /* signal quality 0 */ - MMR_SGNL_QUAL_1 = 0x02, /* signal quality 1 */ - MMR_SGNL_QUAL_2 = 0x04, /* signal quality 2 */ - MMR_SGNL_QUAL_3 = 0x08, /* signal quality 3 */ - MMR_SGNL_QUAL_S_A = 0x80, /* currently selected antenna */ -}; -#define MMR_LEVEL_MASK 0x3F - -/* fields in MMC registers that relate to EEPROM in WaveMODEM daughtercard */ -enum{ - MMC_EECTRL_EEPRE = 0x10, /* 2.4 Gz EEPROM Protect Reg Enable */ - MMC_EECTRL_DWLD = 0x08, /* 2.4 Gz EEPROM Download Synths */ - MMC_EECTRL_EEOP = 0x07, /* 2.4 Gz EEPROM Opcode mask */ - MMC_EECTRL_EEOP_READ = 0x06, /* 2.4 Gz EEPROM Read Opcode */ - MMC_EEADDR_CHAN = 0xf0, /* 2.4 Gz EEPROM Channel # mask */ - MMC_EEADDR_WDCNT = 0x0f, /* 2.4 Gz EEPROM DNLD WordCount-1 */ - MMC_ANALCTRL_ANTPOL = 0x02, /* 2.4 Gz Antenna Polarity mask */ - MMC_ANALCTRL_EXTANT = 0x01, /* 2.4 Gz External Antenna mask */ -}; -#define mmroff(p,f) (unsigned short)((void *)(&((mmr_t *)((void *)0 + (p)))->f) - (void *)0) - -#define MAXDATAZ (6 + 6 + 2 + WAVELAN_MTU) - -struct wl_cntrs { - int pkt_arp; - int pkt_ein[32]; - int pkt_lin[128/8]; - int pkt_eout[32]; - int pkt_lout[128/8]; -}; -typedef struct wl_cntrs *wl_cntrs_t; - -#endif /* WAVELAN_H */ diff --git a/mpc/fns.h b/mpc/fns.h deleted file mode 100644 index fcfa7ad6071ef71b56f6977b609df0b6e7c93169..0000000000000000000000000000000000000000 --- a/mpc/fns.h +++ /dev/null @@ -1,120 +0,0 @@ -#include "../port/portfns.h" - -void archinit(void); -int brgalloc(void); -void brgfree(int); -ulong baudgen(int, int); -int cistrcmp(char*, char*); -int cistrncmp(char*, char*, int); -void clockcheck(void); -void clockinit(void); -void clockintr(Ureg*); -void clrfptrap(void); -#define coherence() -void cpminit(void); -int cpuidentify(void); -void cpuidprint(void); -void dcflush(void*, ulong); -void delay(int); -ulong draminit(ulong*); -void dtlbmiss(void); -void dtlberror(void); -void dumpregs(Ureg*); -void delayloopinit(void); -void eieio(void); -//#define eieio() -void evenaddr(ulong); -void faultpower(Ureg*, ulong addr, int read); -void firmware(int); -void fpinit(void); -int fpipower(Ureg*); -void fpoff(void); -ulong fpstatus(void); -char* getconf(char*); -ulong getdar(void); -ulong getdec(void); -ulong getdepn(void); -ulong getdsisr(void); -ulong getimmr(void); -ulong getmsr(void); -ulong getpvr(void); -ulong gettbl(void); -ulong gettbu(void); -void gotopc(ulong); -void icflush(void*, ulong); -void idle(void); -#define idlehands() /* nothing to do in the runproc */ -int inb(int); -void insb(int, void*, int); -ushort ins(int); -void inss(int, void*, int); -ulong inl(int); -void insl(int, void*, int); -void intr(Ureg*); -void intrenable(int, void (*)(Ureg*, void*), void*, int); -int intrstats(char*, int); -void intrvec(void); -int iprint(char*, ...); -void itlbmiss(void); -int isaconfig(char*, int, ISAConf*); -void kbdinit(void); -void kbdreset(void); -void kernelmmu(void); -void links(void); -void mapfree(RMap*, ulong, int); -void mapinit(RMap*, Map*, int); -void mathinit(void); -void mmuinit(void); -ulong* mmuwalk(ulong*, ulong, int); -void outb(int, int); -void outsb(int, void*, int); -void outs(int, ushort); -void outss(int, void*, int); -void outl(int, ulong); -void outsl(int, void*, int); -PCMmap* pcmmap(int, ulong, int, int); -void pcmunmap(int, PCMmap*); -int pcmspecial(char*, ISAConf*); -void pcmspecialclose(int); -#define procrestore(p) -void powerdownled(void); -void powerupled(void); -void procsave(Proc*); -void procsetup(Proc*); -void putdec(ulong); -void putmsr(ulong); -void putcasid(ulong); -ulong rmapalloc(RMap*, ulong, int, int); -void screeninit(void); -void setpanic(void); -int screenprint(char*, ...); /* debugging */ -#define screenputs(x, y) -ulong sdraminit(ulong*); -int segflush(void*, ulong); -void spireset(void); -long spioutin(void*, long, void*); -int tas(void*); -uchar* tarlookup(uchar *addr, char *file, int *dlen); -void touser(void*); -void trapinit(void); -void trapvec(void); -void tlbflush(ulong); -void tlbflushall(void); -void uartinstall(void); -void uartwait(void); /* debugging */ -int unsac(uchar *dst, uchar *src, int n, int nsrc); -#define userureg(ur) ((ur)->status & KUSER) -void wbflush(void); - -#define waserror() (up->nerrlab++, setlabel(&up->errlab[up->nerrlab-1])) -#define KADDR(a) ((void*)((ulong)(a)|KZERO)) -#define PADDR(a) ((ulong)(a)&~KZERO) - -/* IBM bit field order */ -#define IBIT(b) ((ulong)1<<(31-(b))) -#define SIBIT(n) ((ushort)1<<(15-(n))) - -/* compatibility with inf2.1 */ -#define bpenumenv(n) ((char*)0) - -#define IOREGS(x, T) ((T*)((char*)m->iomem+(x))) diff --git a/mpc/inb.s b/mpc/inb.s deleted file mode 100644 index 82a57f0d5bd8256f04b729cddcdc7a37b39a756a..0000000000000000000000000000000000000000 --- a/mpc/inb.s +++ /dev/null @@ -1,119 +0,0 @@ -#include "mem.h" - -#define BDNZ BC 16,0, -#define BDNE BC 0,2, - -TEXT inb(SB), $0 - OR $ISAMEM, R3 - MOVBZ (R3), R3 - RETURN - -TEXT insb(SB), $0 - MOVW v+4(FP), R4 - MOVW n+8(FP), R5 - MOVW R5, CTR - OR $ISAMEM, R3 - SUB $1, R4 -insb1: - MOVBZ (R3), R7 - MOVBU R7, 1(R4) - BDNZ insb1 - RETURN - -TEXT outb(SB), $0 - MOVW v+4(FP), R4 - OR $ISAMEM, R3 - EIEIO - MOVB R4, (R3) - RETURN - -TEXT outsb(SB), $0 - MOVW v+4(FP), R4 - MOVW n+8(FP), R5 - MOVW R5, CTR - OR $ISAMEM, R3 - SUB $1, R4 -outsb1: - EIEIO - MOVBZU 1(R4), R7 - MOVB R7, (R3) - BDNZ outsb1 - RETURN - -TEXT ins(SB), $0 - OR $ISAMEM, R3 - EIEIO - MOVHBR (R3), R3 - RETURN - -TEXT inss(SB), $0 - MOVW v+4(FP), R4 - MOVW n+8(FP), R5 - MOVW R5, CTR - OR $ISAMEM, R3 - SUB $2, R4 -inss1: - EIEIO - MOVHZ (R3), R7 - MOVHU R7, 2(R4) - BDNZ inss1 - RETURN - -TEXT outs(SB), $0 - MOVW v+4(FP), R4 - OR $ISAMEM, R3 - EIEIO - MOVHBR R4, (R3) - RETURN - -TEXT outss(SB), $0 - MOVW v+4(FP), R4 - MOVW n+8(FP), R5 - MOVW R5, CTR - OR $ISAMEM, R3 - SUB $2, R4 -outss1: - EIEIO - MOVHZU 2(R4), R7 - MOVH R7, (R3) - BDNZ outss1 - RETURN - -TEXT inl(SB), $0 - OR $ISAMEM, R3 - EIEIO - MOVWBR (R3), R3 - RETURN - -TEXT insl(SB), $0 - MOVW v+4(FP), R4 - MOVW n+8(FP), R5 - MOVW R5, CTR - OR $ISAMEM, R3 - SUB $4, R4 -insl1: - EIEIO - MOVW (R3), R7 - MOVWU R7, 4(R4) - BDNZ insl1 - RETURN - -TEXT outl(SB), $0 - MOVW v+4(FP), R4 - OR $ISAMEM, R3 - EIEIO - MOVWBR R4, (R3) - RETURN - -TEXT outsl(SB), $0 - MOVW v+4(FP), R4 - MOVW n+8(FP), R5 - MOVW R5, CTR - OR $ISAMEM, R3 - SUB $4, R4 -outsl1: - EIEIO - MOVWU 4(R4), R7 - MOVW R7, (R3) - BDNZ outsl1 - RETURN diff --git a/mpc/inbc.c b/mpc/inbc.c deleted file mode 100644 index e842a51114f8b08c315277da0e8a2557f83f29f2..0000000000000000000000000000000000000000 --- a/mpc/inbc.c +++ /dev/null @@ -1,134 +0,0 @@ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "io.h" - -int -inb(int port) -{ - return *(uchar*)(port + ISAMEM); -} - -ushort -ins(int port) -{ - int x = *(ushort*)(port + ISAMEM); - return ((x&0xff) << 8) | (x>>8); -} - -ulong -inl(int port) -{ - ulong x = *(ulong*)(port + ISAMEM); -//print("inl %d\n", port); - return (x << 24) | ((x&0xff00)<<8) | ((x>>8)&0xff00) | (x>>24); -} - -void -outb(int port, int val) -{ -//print("outb %d %ux\n", port, val); - *(uchar*)(port + ISAMEM) = val; -} - -void -outs(int port, ushort val) -{ -//print("outs %d %ux\n", port, val); - int x = (val<<8) | (val>>8); - *(ushort*)(port + ISAMEM) = x; -} - -void -outl(int port, ulong val) -{ -//print("outl %d %ulx\n", port, val); - ulong x = (val << 24) | ((val&0xff00)<<8) | ((val>>8)&0xff00) | (val>>24); - *(ulong*)(port + ISAMEM) = x; -} - -void -insb(int port, void *buf, int len) -{ - int i; - uchar *p, *q; - -//print("insb %d %d\n", port, len); - p = (uchar*)(port + ISAMEM); - q = buf; - for(i = 0; i < len; i++){ - *q++ = *p; - } -} - -void -inss(int port, void *buf, int len) -{ - int i; - ushort *p, *q; - -//print("inss %d %d\n", port, len); - p = (ushort*)(port + ISAMEM); - q = buf; - for(i = 0; i < len; i++){ - *q++ = *p; - } -} - -void -insl(int port, void *buf, int len) -{ - int i; - ulong *p, *q; - -//print("insl %d %d\n", port, len); - p = (ulong*)(port + ISAMEM); - q = buf; - for(i = 0; i < len; i++){ - *q++ = *p; - } -} - -void -outsb(int port, void *buf, int len) -{ - int i; - uchar *p, *q; - -//print("outsb %d %d\n", port, len); - p = (uchar*)(port + ISAMEM); - q = buf; - for(i = 0; i < len; i++){ - *p = *q++; - } -} - -void -outss(int port, void *buf, int len) -{ - int i; - ushort *p, *q; - -//print("outss %d %d\n", port, len); - p = (ushort*)(port + ISAMEM); - q = buf; - for(i = 0; i < len; i++){ - *p = *q++; - } -} - -void -outsl(int port, void *buf, int len) -{ - int i; - ulong *p, *q; - -//print("outsl %d %d\n", port, len); - p = (ulong*)(port + ISAMEM); - q = buf; - for(i = 0; i < len; i++){ - *p = *q++; - } -} diff --git a/mpc/io.h b/mpc/io.h deleted file mode 100644 index 3e76a8003fcfd5fe2777c0ac101a16c7ba496e40..0000000000000000000000000000000000000000 --- a/mpc/io.h +++ /dev/null @@ -1,592 +0,0 @@ -typedef struct BD BD; -typedef struct Ring Ring; -typedef struct GTimer GTimer; - -enum -{ - /* interrupt vectors (SIU and CPM) */ - VectorPIC= 0, /* level 0 to level 7, assigned by software */ - /* vector assignments are determined by the assignments here */ - PITlevel= 2, - CPIClevel= 4, - PCMCIAlevel= 6, - RTClevel= 7, - VectorIRQ= VectorPIC+8, /* IRQ0 to IRQ7 */ - VectorCPIC= VectorIRQ+8, /* 32 CPM interrupts: 0 (error) to 0x1F (PC15) */ -}; - -/* - * these are defined to keep the interface compatible with other - * architectures, but only BUSUNKNOWN is currently used - */ -#define MKBUS(t,b,d,f) (((t)<<24)|(((b)&0xFF)<<16)|(((d)&0x1F)<<11)|(((f)&0x07)<<8)) -#define BUSFNO(tbdf) (((tbdf)>>8)&0x07) -#define BUSDNO(tbdf) (((tbdf)>>11)&0x1F) -#define BUSBNO(tbdf) (((tbdf)>>16)&0xFF) -#define BUSTYPE(tbdf) ((tbdf)>>24) -#define BUSBDF(tbdf) ((tbdf)&0x00FFFF00) -#define BUSUNKNOWN (-1) - -/* - * Buffer Descriptors and IO Rings - */ - -struct BD { - ushort status; - ushort length; - ulong addr; -}; - -BD* bdalloc(int); -void bdfree(BD*, int); - -enum { - /* Rx BDs, bits common to all protocols */ - BDEmpty= 1<<15, - BDWrap= 1<<13, - BDInt= 1<<12, - BDLast= 1<<11, - BDFirst= 1<<10, - - /* Tx BDs */ - BDReady= 1<<15, - /* BDWrap, BDInt, BDLast */ -}; - - -struct Ring { - BD* rdr; /* receive descriptor ring */ - void* rrb; /* receive ring buffers */ - int rdrx; /* index into rdr */ - int nrdre; /* length of rdr */ - - BD* tdr; /* transmit descriptor ring */ - Block** txb; /* corresponding transmit ring buffers */ - int tdrh; /* host index into tdr */ - int tdri; /* interface index into tdr */ - int ntdre; /* length of tdr */ - int ntq; /* pending transmit requests */ -}; - -#define NEXT(x, l) (((x)+1)%(l)) -#define PREV(x, l) (((x) == 0) ? (l)-1: (x)-1) -#define HOWMANY(x, y) (((x)+((y)-1))/(y)) -#define ROUNDUP(x, y) (HOWMANY((x), (y))*(y)) - -int ioringinit(Ring*, int, int, int); - -/* - * CPM - */ -enum { - /* commands */ - InitRxTx = 0, - InitRx = 1, - InitTx = 2, - EnterHunt= 3, - StopTx= 4, - GracefulStopTx = 5, - InitIDMA = 5, - RestartTx = 6, - CloseRxBD = 7, - SetGroupAddr = 8, - SetTimer = 8, - GCITimeout = 9, - GCIAbort = 10, - StopIDMA = 11, - StartDSP = 12, - ArmIDMA = 13, - InitDSP = 13, - USBCmd = 15, - - /* channel IDs */ - SCC1ID= 0, - USBID= 0, - I2CID= 1, - IDMA1ID= 1, - SCC2ID= 4, - SPIID= 5, - IDMA2ID= 5, - TIMERID= 5, - SCC3ID= 8, - SMC1ID= 9, - DSP1ID=9, - SCC4ID= 12, - SMC2ID= 13, - DSP2ID= 13, - - /* bgcr */ - BaudEnable = 1<<16, - - /* sicr */ - CLK1 = 4, /* SCC1,2 */ - CLK2 = 5, - CLK3 = 6, - CLK4 = 7, - CLK5 = CLK1, /* SCC3,4 */ - CLK6 = CLK2, - CLK7 = CLK3, - CLK8 = CLK4, -}; - -void cpmop(int, int, int); -void* cpmalloc(int, int); -void cpmfree(void*, int); -void* cpmparam(ulong, int); -IMM* ioplock(void); -void iopunlock(void); -void sccnmsi(int, int, int); -int scc2claim(int, ulong, void(*)(void*), void*); -void scc2stop(void*); - -/* - * CPM timers - */ -enum { - /* timer modes */ - CaptureRise= 1<<6, - CaptureFall= 2<<6, - CaptureEdge= 3<<6, - TimerToggle= 1<<5, /* toggle TOUTx* pin */ - TimerORI= 1<<4, /* Output Reference Interrupt */ - TimerRestart= 1<<3, - TimerSclk= 1<<1, - TimerSclk16= 2<<1, - TimerTIN= 3<<1, /* clock by falling edge of TINx */ - TimerGate= 1<<0, /* TGATE1* controls timer */ - - /* timer events */ - TimerREF= 1<<1, - TimerCAP= 1<<0 -}; - -struct GTimer{ - int x; - int inuse; - int event; - ushort* tmr; - ushort* trr; - ushort* tcr; - ushort* tcn; - ushort* ter; - void* arg; - void (*interrupt)(Ureg*, void*, GTimer*); -}; -GTimer* gtimer(ushort, ushort, void (*)(Ureg*,void*,GTimer*), void*); -void gtimerset(GTimer*, ushort, int); -void gtimerstart(GTimer*); -void gtimerstop(GTimer*); -void gtimerfree(GTimer*); - -enum { - /* BCSR1 bits */ - DisableFlash= IBIT(0), - DisableDRAM= IBIT(1), - DisableEther= IBIT(2), - DisableIR= IBIT(3), - DisableRS232a= IBIT(7), - DisablePCMCIA= IBIT(8), - PCCVCCMask= IBIT(9)|IBIT(15), - PCCVPPMask= IBIT(10)|IBIT(11), - DisableRS232b= IBIT(13), - EnableSDRAM= IBIT(14), - - PCCVCC0V= IBIT(15)|IBIT(9), - PCCVCC5V= IBIT(9), /* active low */ - PCCVCC3V= IBIT(15), /* active low */ - PCCVPP0V= IBIT(10)|IBIT(11), /* active low */ - PCCVPP5V= IBIT(10), /* active low */ - PCCVPP12V= IBIT(11), /* active low */ - PCCVPPHiZ= IBIT(10)|IBIT(11), - - /* BCSR4 bits */ - DisableTPDuplex= IBIT(1), - DisableLamp= IBIT(3), - DisableUSB= IBIT(4), - USBFullSpeed= IBIT(5), - DisableUSBVcc= IBIT(6), - DisableVideoLamp= IBIT(8), - EnableVideoClock= IBIT(9), - EnableVideoPort= IBIT(10), - DisableModem= IBIT(11), -}; - -/* - * everything in this file follows a hardware/firmware layout in the 8xx manuals: - * mind the data types, offsets and alignment - */ - -/* - * basic IO controller parameters (SMC and SCC) - */ -typedef struct IOCparam IOCparam; -struct IOCparam { - ushort rbase; - ushort tbase; - uchar rfcr; - uchar tfcr; - ushort mrblr; - ulong rstate; - ulong rxidp; - ushort rbptr; - ushort rxibc; - ulong rxtemp; - ulong tstate; - ulong txidp; - ushort tbptr; - ushort txibc; - ulong txtemp; -}; - -typedef struct SCCparam SCCparam; -struct SCCparam { - IOCparam; - ulong rcrc; - ulong tcrc; -}; - -typedef struct SCC SCC; -struct SCC { - ulong gsmrl; - ulong gsmrh; - ushort psmr; - uchar rsvscc0[2]; - ushort todr; - ushort dsr; - ushort scce; - uchar rsvscc1[2]; - ushort sccm; - uchar rsvscc3; - uchar sccs; - ushort irmode; - ushort irsip; -}; - -typedef struct SMC SMC; -struct SMC { - uchar pad1[2]; - ushort smcmr; - uchar pad2[2]; - uchar smce; - uchar pad3[3]; - uchar smcm; - uchar pad4[5]; -}; - -typedef struct SPI SPI; -struct SPI { - ushort spmode; - uchar res1[4]; - uchar spie; - uchar res2[3]; - uchar spim; - uchar res3[2]; - uchar spcom; - uchar res4[10]; -}; - -typedef struct USB USB; -struct USB { - uchar usmod; - uchar usadr; - uchar uscom; - uchar rsvu1; - ushort usep[4]; - uchar rsvu2[4]; - ushort usber; - uchar rsvu3[2]; - ushort usbmr; - uchar rsvu4; - uchar usbs; - uchar rsvu5[8]; -}; - -typedef struct IMM IMM; -struct IMM { - struct { /* general SIU */ - ulong siumcr; - ulong sypcr; - uchar rsv0[0xE-0x8]; - ushort swsr; - ulong sipend; - ulong simask; - ulong siel; - uchar sivec; - uchar padv[3]; - ulong tesr; - uchar rsv1[0x30-0x24]; - ulong sdcr; - uchar rsv2[0x80-0x34]; - }; - struct { /* PCMCIA */ - struct { - ulong base; - ulong option; - } pcmr[8]; - uchar rsv3[0xe0-0xc0]; - ulong pgcr[2]; - ulong pscr; - uchar rsv4[0xf0-0xec]; - ulong pipr; - uchar rsv5[4]; - ulong per; - uchar rsv6[4]; - }; - struct { /* MEMC */ - struct { - ulong base; - ulong option; - } memc[8]; - uchar rsv7a[0x24]; - ulong mar; - ulong mcr; - uchar rsv7b[4]; - ulong mamr; - ulong mbmr; - ushort mstat; - ushort mptpr; - ulong mdr; - uchar rsv7c[0x80]; - }; - struct { /* system integration timers */ - ushort tbscr; - uchar rsv8a[2]; - ulong tbrefu; - ulong tbrefl; - uchar rsv8b[0x14]; - ushort rtcsc; - uchar rsv8c[2]; - ulong rtc; - ulong rtsec; - ulong rtcal; - uchar rsv8d[0x10]; - ushort piscr; - ushort rsv8e; - ulong pitc; - ulong pitr; - uchar rsv8f[0x34]; - }; - struct { /* 280: clocks and resets */ - ulong sccr; - ulong plprcr; - ulong rsr; - uchar rsv9[0x300-0x28c]; - }; - struct { /* 300: system integration timers keys */ - ulong tbscrk; - ulong tbrefuk; - ulong tbreflk; - ulong tbk; - uchar rsv10a[0x10]; - ulong rtcsck; - ulong rtck; - ulong rtseck; - ulong rtcalk; - uchar rsv10b[0x10]; - ulong piscrk; - ulong pitck; - uchar rsv10c[0x38]; - }; - struct { /* 380: clocks and resets keys */ - ulong sccrk; - ulong plprcrk; - ulong rsrk; - uchar rsv11[0x800-0x38C]; - }; - struct { /* 800: video controller */ - ushort vccr; - ushort pad11a; - uchar vsr; - uchar pad11b; - uchar vcmr; - uchar pad11c; - ulong vbcb; - ulong pad11d; - ulong vfcr0; - ulong vfaa0; - ulong vfba0; - ulong vfcr1; - ulong vfaa1; - ulong vfba1; - uchar rsv11a[0x840-0x828]; - }; - struct { /* 840: LCD */ - ulong lccr; - ulong lchcr; - ulong lcvcr; - ulong rsv11b; - ulong lcfaa; - ulong lcfba; - uchar lcsr; - uchar rsv11c[0x860-0x859]; - }; - struct { /* 860: I2C */ - uchar i2mod; - uchar rsv12a[3]; - uchar i2add; - uchar rsv12b[3]; - uchar i2brg; - uchar rsv12c[3]; - uchar i2com; - uchar rsv12d[3]; - uchar i2cer; - uchar rsv12e[3]; - uchar i2cmr; - uchar rsv12[0x900-0x875]; - }; - struct { /* 900: DMA */ - uchar rsv13[4]; - ulong sdar; - uchar sdsr; - uchar pad1[3]; - uchar sdmr; - uchar pad2[3]; - uchar idsr1; - uchar pad3[3]; - uchar idmr1; - uchar pad4[3]; - uchar idsr2; - uchar pad5[3]; - uchar idmr2; - uchar pad6[0x930-0x91D]; - }; - struct { /* CPM interrupt control */ - ushort civr; - uchar pad7[0x940-0x932]; - ulong cicr; - ulong cipr; - ulong cimr; - ulong cisr; - }; - struct { /* input/output port */ - ushort padir; - ushort papar; - ushort paodr; - ushort padat; - uchar pad8[8]; - ushort pcdir; - ushort pcpar; - ushort pcso; - ushort pcdat; - ushort pcint; - uchar pad9[6]; - ushort pddir; - ushort pdpar; - ushort rsv14a; - ushort pddat; - uchar rsv14[0x980-0x978]; - }; - struct { /* CPM timers */ - ushort tgcr; - uchar rsv15a[0x990-0x982]; - ushort tmr1; - ushort tmr2; - ushort trr1; - ushort trr2; - ushort tcr1; - ushort tcr2; - ushort tcn1; - ushort tcn2; - ushort tmr3; - ushort tmr4; - ushort trr3; - ushort trr4; - ushort tcr3; - ushort tcr4; - ushort tcn3; - ushort tcn4; - ushort ter1; - ushort ter2; - ushort ter3; - ushort ter4; - uchar rsv15[0x9C0-0x9B8]; - }; - struct { /* CPM */ - ushort cpcr; - uchar res0[2]; - ushort rccr; - uchar res1; - uchar rmds; - uchar res2a[4]; - ushort rctr1; - ushort rctr2; - ushort rctr3; - ushort rctr4; - uchar res2[2]; - ushort rter; - uchar res3[2]; - ushort rtmr; - uchar rsv16[0x9F0-0x9DC]; - }; - union { /* BRG */ - struct { - ulong brgc1; - ulong brgc2; - ulong brgc3; - ulong brgc4; - }; - ulong brgc[4]; - }; - uchar skip0[0xAB2-0xA00]; /* USB, SCC, SMC, SPI: address using IOREGS in fns.h */ - struct { /* PIP */ - ushort pipc; /* not 823 */ - ushort ptpr; /* not 823 */ - ulong pbdir; - ulong pbpar; - uchar pad10[2]; - ushort pbodr; - ulong pbdat; - uchar pad11[0xAE0-0xAC8]; - }; - struct { /* SI */ - ulong simode; - uchar sigmr; - uchar pad12; - uchar sistr; - uchar sicmr; - uchar pad13[4]; - ulong sicr; - ulong sirp; - uchar pad14[0xB00-0xAF4]; - }; - uchar vcram[256]; - uchar siram[512]; - ushort lcdmap[256]; -}; - - -enum { - BusCBUS = 0, /* Corollary CBUS */ - BusCBUSII, /* Corollary CBUS II */ - BusEISA, /* Extended ISA */ - BusFUTURE, /* IEEE Futurebus */ - BusINTERN, /* Internal bus */ - BusISA, /* Industry Standard Architecture */ - BusMBI, /* Multibus I */ - BusMBII, /* Multibus II */ - BusMCA, /* Micro Channel Architecture */ - BusMPI, /* MPI */ - BusMPSA, /* MPSA */ - BusNUBUS, /* Apple Macintosh NuBus */ - BusPCI, /* Peripheral Component Interconnect */ - BusPCMCIA, /* PC Memory Card International Association */ - BusTC, /* DEC TurboChannel */ - BusVL, /* VESA Local bus */ - BusVME, /* VMEbus */ - BusXPRESS, /* Express System Bus */ -}; - -/* - * PCMCIA support code. - */ -/* - * Map between ISA memory space and PCMCIA card memory space. - */ -struct PCMmap { - ulong ca; /* card address */ - ulong cea; /* card end address */ - ulong isa; /* ISA address */ - int len; /* length of the ISA area */ - int attr; /* attribute memory */ - int ref; -}; diff --git a/mpc/l.s b/mpc/l.s deleted file mode 100644 index af9b57c46956bdc89f44f58a26848e4bb29fe438..0000000000000000000000000000000000000000 --- a/mpc/l.s +++ /dev/null @@ -1,952 +0,0 @@ -#include "mem.h" - -/* - * common ppc special purpose registers - */ -#define DSISR 18 -#define DAR 19 /* Data Address Register */ -#define DEC 22 /* Decrementer */ -#define SRR0 26 /* Saved Registers (exception) */ -#define SRR1 27 -#define SPRG0 272 /* Supervisor Private Registers */ -#define SPRG1 273 -#define SPRG2 274 -#define SPRG3 275 -#define TBRU 269 /* Time base Upper/Lower (Reading) */ -#define TBRL 268 -#define TBWU 285 /* Time base Upper/Lower (Writing) */ -#define TBWL 284 -#define PVR 287 /* Processor Version */ - -/* - * mpc8xx-specific special purpose registers of interest here - */ -#define EIE 80 -#define EID 81 -#define NRI 82 -#define IMMR 638 -#define IC_CST 560 -#define IC_ADR 561 -#define IC_DAT 562 -#define DC_CST 568 -#define DC_ADR 569 -#define DC_DAT 570 -#define MI_CTR 784 -#define MI_AP 786 -#define MI_EPN 787 -#define MI_TWC 789 -#define MI_RPN 790 -#define MI_DBCAM 816 -#define MI_DBRAM0 817 -#define MI_DBRAM1 818 -#define MD_CTR 792 -#define M_CASID 793 -#define MD_AP 794 -#define MD_EPN 795 -#define M_TWB 796 -#define MD_TWC 797 -#define MD_RPN 798 -#define M_TW 799 -#define MD_DBCAM 824 -#define MD_DBRAM0 825 -#define MD_DBRAM1 826 - -/* - * mpc8xx specific debug-level SPRs - */ -#define CMPA 144 -#define CMPB 145 -#define CMPC 146 -#define CMPD 147 -#define ICR 148 -#define DER 149 -#define COUNTA 150 -#define COUNTB 151 -#define CMPE 152 -#define CMPF 153 -#define CMPG 154 -#define CMPH 155 -#define LCTRL1 156 -#define LCTRL2 157 -#define ICTRL 158 -#define BAR 159 -#define DPDR 630 - -/* use of SPRG registers in save/restore */ -#define SAVER0 SPRG0 -#define SAVER1 SPRG1 -#define SAVELR SPRG2 -#define SAVEXX SPRG3 - -/* special instruction definitions */ -#define BDNZ BC 16,0, -#define BDNE BC 0,2, -#define TLBIA WORD $((31<<26)|(370<<1)) -#define MFTB(tbr,d) WORD $((31<<26)|((d)<<21)|((tbr&0x1f)<<16)|(((tbr>>5)&0x1f)<<11)|(371<<1)) - -/* on some models mtmsr doesn't synchronise enough (eg, 603e) */ -#define MSRSYNC SYNC; ISYNC - -/* - * The following code assume that the MPC8xx processor has been - * configured to a certain extent. In particular, we assume the following - * following registers have been set up. - * - * SIU - * SIUMCR - * SYPCR - * - */ - -#define UREGSPACE (UREGSIZE+8) - - TEXT start(SB), $-4 - - /* - * setup MSR - * turn off interrupts - * use 0x000 as exception prefix - * enable machine check - */ - MOVW MSR, R3 - MOVW $(MSR_EE|MSR_IP), R4 - ANDN R4, R3 - OR $(MSR_ME), R3 - ISYNC - MOVW R3, MSR - MSRSYNC - - /* set internal memory base */ - MOVW $INTMEM, R4 - MOVW R4, SPR(IMMR) - - /* except during trap handling, R0 is zero from now on */ - MOVW $0, R0 - - /* setup SB for pre mmu */ - MOVW $setSB(SB), R2 - MOVW $KZERO, R3 - ANDN R3, R2 - -/* - * reset the caches and disable them for now - */ - MOVW SPR(IC_CST), R4 /* read and clear */ - MOVW $(5<<25), R4 - MOVW R4, SPR(IC_CST) /* unlock all */ - ISYNC - MOVW $(6<<25), R4 - MOVW R4, SPR(IC_CST) /* invalidate all */ - ISYNC - MOVW $(2<<25), R4 - MOVW R4, SPR(IC_CST) /* disable i-cache */ - ISYNC - - SYNC - MOVW SPR(DC_CST), R4 /* read and clear */ - MOVW $(10<<24), R4 - SYNC - MOVW R4, SPR(DC_CST) /* unlock all */ - ISYNC - MOVW $(12<<24), R4 - SYNC - MOVW R4, SPR(DC_CST) /* invalidate all */ - ISYNC - MOVW $(4<<24), R4 - SYNC - MOVW R4, SPR(DC_CST) /* disable d-cache */ - ISYNC - - MOVW $7, R4 - MOVW R4, SPR(ICTRL) /* cancel `show cycle' for normal instruction execution */ - ISYNC - MOVW R4, SPR(DER) - ISYNC - BL mmuinit0(SB) - - /* running with MMU on!! */ - - /* set R2 to it correct value */ - MOVW $setSB(SB), R2 - - /* enable i-cache */ - MOVW $(1<<25), R4 - MOVW R4, SPR(IC_CST) - ISYNC - - /* enable d-cache */ - MOVW $(2<<24), R4 - MOVW R4, SPR(DC_CST) - ISYNC - - -/* - * set other system configuration values - */ - - -/* - * setup mach - */ - MOVW $MACHADDR, R(MACH) - ADD $(MACHSIZE-8), R(MACH), R1 /* set stack */ - SUB $4, R(MACH), R3 - ADD $4, R1, R4 -clrmach: - MOVWU R0, 4(R3) - CMP R3, R4 - - MOVW R0, R(USER) - MOVW R0, 0(R(MACH)) - - /* zero bss */ - MOVW $edata(SB), R3 - MOVW $end(SB), R4 - SUBCC R3, R4 - BLE skipz - SRAW $2, R4 - MOVW R4, CTR - SUB $4, R3 -zero: - MOVWU R0, 4(R3) - BDNZ zero -skipz: - - /* off to main */ - BL main(SB) - BR 0(PC) - -/* - * on return from this function we will be running in virtual mode. - * We setup two TLB entries: - * 1) map the first 8Mb of RAM to KZERO - * 2) map the region that contains the IMMR - */ -TEXT mmuinit0(SB), $0 - /* reset all the tlbs */ - TLBIA - - /* dont use CASID yet - set to zero for now */ - MOVW $0, R4 - MOVW R4, SPR(M_CASID) - - /* set Ks = 0 Kp = 1 for all access groups */ - MOVW $0x55555555, R4 - MOVW R4, SPR(MI_AP) - MOVW R4, SPR(MD_AP) - - /* - * set: - * GPM = 0: PowerPC mode - * PPM = 0: Page protection mode - no 1K pages - * CIDEF = 0: cache enable when MMU disabled - * WTDEF = 0: write back when MMU is disbaled - * RSV2 = 0: no reserved entries - * TWAM = 0: don't use table walk assit - * PPCS = 0: not used in PowerPC mode - * INDX = 0: start at first entry - */ - MOVW $0, R4 - MOVW R4, SPR(MI_CTR) /* i-mmu control */ - MOVW $0, R4 - MOVW R4, SPR(MD_CTR) /* d-mmu control */ - - /* - * map 8Mb of ram at 0 -> KZERO, cached, writeback, shared - */ - MOVW $(KZERO|MMUEV), R4 - MOVW R4, SPR(MD_EPN) - MOVW R4, SPR(MI_EPN) - MOVW $(MMUPS8M|MMUV), R4 /* |MMUWT */ - MOVW R4, SPR(MD_TWC) - MOVW R4, SPR(MI_TWC) - MOVW $(0|MMUPP|MMUSPS|MMUSH|MMUV), R4 - MOVW R4, SPR(MD_RPN) - MOVW R4, SPR(MI_RPN) - - /* - * map 8mb IO at INTMEM->INTMEM, cache inhibit, shared - */ - MOVW $(INTMEM|MMUEV), R4 - MOVW R4, SPR(MD_EPN) - MOVW $(MMUPS8M|MMUWT|MMUV), R4 - MOVW R4, SPR(MD_TWC) - MOVW $(INTMEM|MMUPP|MMUSPS|MMUSH|MMUCI|MMUV), R4 - MOVW R4, SPR(MD_RPN) - - /* enable MMU */ - MOVW LR, R3 - OR $KZERO, R3 - MOVW R3, SPR(SRR0) - MOVW MSR, R4 - OR $(MSR_IR|MSR_DR), R4 - MOVW R4, SPR(SRR1) - RFI /* resume in kernel mode in caller */ - - RETURN - -TEXT splhi(SB), $0 - MOVW MSR, R3 - RLWNM $0, R3, $~MSR_EE, R4 - SYNC - MOVW R4, MSR - MSRSYNC - MOVW LR, R31 - MOVW R31, 4(R(MACH)) /* save PC in m->splpc */ - RETURN - -TEXT splx(SB), $0 - /* fall though */ - -TEXT splxpc(SB), $0 - MOVW MSR, R4 - RLWMI $0, R3, $MSR_EE, R4 - RLWNMCC $0, R3, $MSR_EE, R5 - BNE splx0 - MOVW LR, R31 - MOVW R31, 4(R(MACH)) /* save PC in m->splpc */ -splx0: - SYNC - MOVW R4, MSR - MSRSYNC - RETURN - -TEXT spllo(SB), $0 - MFTB(TBRL, 3) - MOVW R3, spltbl(SB) - MOVW MSR, R3 - OR $MSR_EE, R3, R4 - SYNC - MOVW R4, MSR - MSRSYNC - RETURN - -TEXT spldone(SB), $0 - RETURN - -TEXT islo(SB), $0 - MOVW MSR, R3 - RLWNM $0, R3, $MSR_EE, R3 - RETURN - -TEXT setlabel(SB), $-4 - MOVW LR, R31 - MOVW R1, 0(R3) - MOVW R31, 4(R3) - MOVW $0, R3 - RETURN - -TEXT gotolabel(SB), $-4 - MOVW 4(R3), R31 - MOVW R31, LR - MOVW 0(R3), R1 - MOVW $1, R3 - RETURN - -TEXT touser(SB), $-4 - MOVW $(UTZERO+32), R5 /* header appears in text */ - MOVW $(MSR_EE|MSR_PR|MSR_ME|MSR_IR|MSR_DR|MSR_RI), R4 - MOVW R4, SPR(SRR1) - MOVW R3, R1 - MOVW R5, SPR(SRR0) - RFI - - -TEXT icflush(SB), $-4 /* icflush(virtaddr, count) */ - MOVW n+4(FP), R4 - RLWNM $0, R3, $~(CACHELINESZ-1), R5 - SUB R5, R3 - ADD R3, R4 - ADD $(CACHELINESZ-1), R4 - SRAW $CACHELINELOG, R4 - MOVW R4, CTR -icf0: ICBI (R5) - ADD $CACHELINESZ, R5 - BDNZ icf0 - ISYNC - RETURN - -TEXT dcflush(SB), $-4 /* dcflush(virtaddr, count) */ - MOVW n+4(FP), R4 - RLWNM $0, R3, $~(CACHELINESZ-1), R5 - CMP R4, $0 - BLE dcf1 - SUB R5, R3 - ADD R3, R4 - ADD $(CACHELINESZ-1), R4 - SRAW $CACHELINELOG, R4 - MOVW R4, CTR -dcf0: DCBF (R5) - ADD $CACHELINESZ, R5 - BDNZ dcf0 -dcf1: - RETURN - -TEXT tas(SB), $0 - SYNC - MOVW R3, R4 - MOVW $0xdead,R5 -tas1: - DCBF (R4) /* fix for 603x bug */ - LWAR (R4), R3 - CMP R3, $0 - BNE tas0 - STWCCC R5, (R4) - BNE tas1 -tas0: - SYNC - ISYNC - RETURN - -TEXT gettbl(SB), $0 - MFTB(TBRL, 3) - RETURN - -TEXT gettbu(SB), $0 - MOVW SPR(TBRU), R3 - RETURN - -TEXT getpvr(SB), $0 - MOVW SPR(PVR), R3 - RETURN - -TEXT getimmr(SB), $0 - MOVW SPR(IMMR), R3 - RETURN - -TEXT getdec(SB), $0 - MOVW SPR(DEC), R3 - RETURN - -TEXT putdec(SB), $0 - MOVW R3, SPR(DEC) - RETURN - -TEXT getdar(SB), $0 - MOVW SPR(DAR), R3 - RETURN - -TEXT getdsisr(SB), $0 - MOVW SPR(DSISR), R3 - RETURN - -TEXT getdepn(SB), $0 - MOVW SPR(MD_EPN), R3 - RETURN - -TEXT getmsr(SB), $0 - MOVW MSR, R3 - RETURN - -TEXT putder(SB), $0 - MOVW R3, SPR(DER) - RETURN - -TEXT getder(SB), $0 - MOVW SPR(DER), R3 - RETURN - -TEXT putmsr(SB), $0 - SYNC - MOVW R3, MSR - MSRSYNC - RETURN - -TEXT eieio(SB), $0 - EIEIO - RETURN - -TEXT tlbflushall(SB), $0 - TLBIA - RETURN - -TEXT tlbflush(SB), $0 - TLBIE R3 - RETURN - -TEXT putcasid(SB), $-4 - MOVW LR, R4 - MOVW MSR, R5 - BL nommu(SB) - MOVW R3, SPR(M_CASID) - MOVW R4, SPR(SRR0) - MOVW R5, SPR(SRR1) - RFI - -TEXT nommu(SB), $-4 - MOVW LR, R6 - RLWNM $0, R6, $~KZERO, R6 - MOVW $(MSR_DR|MSR_IR), R8 - MOVW R5, R7 - ANDN R8, R7 - MOVW R6, SPR(SRR0) - MOVW R7, SPR(SRR1) - RFI - -TEXT gotopc(SB), $0 - MOVW R3, CTR - MOVW LR, R31 /* for trace back */ - BR (CTR) - -/* - * byte swapping of arrays of long and short; - * could possibly be avoided with more changes to drivers - */ -TEXT swabl(SB), $0 - MOVW v+4(FP), R4 - MOVW n+8(FP), R5 - SRAW $2, R5, R5 - MOVW R5, CTR - SUB $4, R4 - SUB $4, R3 -swabl1: - ADD $4, R3 - MOVWU 4(R4), R7 - MOVWBR R7, (R3) - BDNZ swabl1 - RETURN - -TEXT swabs(SB), $0 - MOVW v+4(FP), R4 - MOVW n+8(FP), R5 - SRAW $1, R5, R5 - MOVW R5, CTR - SUB $2, R4 - SUB $2, R3 -swabs1: - ADD $2, R3 - MOVHZU 2(R4), R7 - MOVHBR R7, (R3) - BDNZ swabs1 - RETURN - -TEXT legetl(SB), $0 - MOVWBR (R3), R3 - RETURN - -TEXT lesetl(SB), $0 - MOVW v+4(FP), R4 - MOVWBR R4, (R3) - RETURN - -TEXT legets(SB), $0 - MOVHBR (R3), R3 - RETURN - -TEXT lesets(SB), $0 - MOVW v+4(FP), R4 - MOVHBR R4, (R3) - RETURN - - -TEXT itlbmiss(SB), $-4 - MOVW R1, SPR(SAVER1) - MOVW R2, SPR(M_TW) - -/* - to enable hardware break points - MOVW MSR, R1 - OR $(MSR_RI), R1 - MOVW R1, MSR - ISYNC -*/ - - /* m->tlbfault++ */ - MOVW $(MACHADDR&~KZERO), R1 /* m-> */ - MOVW 20(R1), R2 - ADD $1, R2 - MOVW R2, 20(R1) - - MOVW CR, R2 - MOVW SPR(MI_EPN), R1 - MOVW R1, CR - BC 4,0,itlblookup - /* - * map ram - */ - MOVW R2, CR - MOVW $(MMUPS8M|MMUV), R2 - MOVW R2, SPR(MI_TWC) - RLWNM $0, R1, $0x7f800000, R1 - OR $(MMUPP|MMUSPS|MMUSH|MMUV), R1 - MOVW R1, SPR(MI_RPN) - MOVW SPR(M_TW), R2 - MOVW SPR(SAVER1), R1 - RFI - -itlblookup: - MOVW R0, SPR(SAVER0) - MOVW R3, SPR(SAVEXX) - - /* - * R1 = 20 bits of addr | 8 bits of junk | 4 bits of asid - * calulate ((x>>9)^(x>>21)^(x<<11)) & (0xfff<<3) - * note (x>>21)^(x<<11) = rotate left 11 - */ - RLWNM $(32-9), R1, $(0xfff<<3), R3 - RLWNM $11, R1, $(0xfff<<3), R1 - XOR R1, R3, R1 - MOVW $(MACHADDR&~KZERO), R3 /* m-> */ - MOVW 16(R3), R3 /* m->stb */ - RLWNM $0, R3, $~KZERO, R3 /* PADDR(m->stb) */ - ADD R1, R3 - MOVW 4(R3), R0 - MOVW 0(R3), R3 - MOVW SPR(MI_EPN), R1 - RLWNM $20, R1, $0xffffff, R1 - RLWNM $12, R1, $~0, R1 - CMP R3, R1 - BNE itlbtrap - MOVW R2, CR - MOVW $(MMUV), R1 - MOVW R1, SPR(MI_TWC) - MOVW R0, SPR(MI_RPN) - MOVW SPR(SAVEXX), R3 - MOVW SPR(M_TW), R2 - MOVW SPR(SAVER1), R1 - MOVW SPR(SAVER0), R0 - RFI -itlbtrap: - MOVW R2, CR - - MOVW $(MACHADDR&~KZERO), R2 /* m-> */ - MOVW R1, 32(R2) - MOVW R3, 36(R2) - - MOVW SPR(SAVEXX), R3 - MOVW SPR(M_TW), R2 - MOVW LR, R0 - MOVW R0, SPR(SAVELR) - MOVW $0x1100, R0 - BR traps - - -TEXT dtlbmiss(SB), $-4 - - MOVW R1, SPR(SAVER1) - MOVW R2, SPR(M_TW) -/* - to enable hardware break points - MOVW MSR, R1 - OR $(MSR_RI), R1 - MOVW R1, MSR - ISYNC -*/ - - /* m->tlbfault++ */ - MOVW $(MACHADDR&~KZERO), R1 /* m-> */ - MOVW 20(R1), R2 - ADD $1, R2 - MOVW R2, 20(R1) - - MOVW CR, R2 - MOVW SPR(MD_EPN), R1 - MOVW R1, CR - BC 4,0,dtlblookup - BC 12,1,dtlbio - /* - * map ram - */ - MOVW R2, CR - MOVW $(MMUPS8M|MMUV), R2 - MOVW R2, SPR(MD_TWC) - RLWNM $0, R1, $0x7f800000, R1 - OR $(MMUPP|MMUSPS|MMUSH|MMUV), R1 - MOVW R1, SPR(MD_RPN) - MOVW SPR(M_TW), R2 - MOVW SPR(SAVER1), R1 - RFI -dtlbio: - /* - * map io - */ - MOVW R2, CR - MOVW $(MMUPS8M|MMUWT|MMUV), R2 - MOVW R2, SPR(MD_TWC) - RLWNM $0, R1, $0xff800000, R1 - OR $(MMUPP|MMUSPS|MMUSH|MMUCI|MMUV), R1 - MOVW R1, SPR(MD_RPN) - MOVW SPR(M_TW), R2 - MOVW SPR(SAVER1), R1 - RFI -dtlblookup: - MOVW R0, SPR(SAVER0) - MOVW R3, SPR(SAVEXX) - - /* - * R1 = 20 bits of addr | 8 bits of junk | 4 bits of asid - * calulate ((x>>9)^(x>>21)^(x<<11)) & (0xfff<<3) - * note (x>>21)^(x<<11) = rotate left 11 - */ - RLWNM $(32-9), R1, $(0xfff<<3), R3 - RLWNM $11, R1, $(0xfff<<3), R1 - XOR R1, R3, R1 - MOVW $(MACHADDR&~KZERO), R3 /* m-> */ - MOVW 16(R3), R3 /* m->stb */ - RLWNM $0, R3, $~KZERO, R3 /* PADDR(m->stb) */ - ADD R1,R3,R3 - MOVW 4(R3), R0 - MOVW 0(R3), R3 - MOVW SPR(MD_EPN), R1 - RLWNM $20, R1, $0xffffff, R1 - RLWNM $12, R1, $~0, R1 - CMP R3, R1 - BNE dtlbtrap - MOVW $(MMUV), R1 - MOVW R1, SPR(MD_TWC) - MOVW R0, SPR(MD_RPN) - MOVW R2, CR - MOVW SPR(SAVEXX), R3 - MOVW SPR(M_TW), R2 - MOVW SPR(SAVER1), R1 - MOVW SPR(SAVER0), R0 - RFI -dtlbtrap: - MOVW R2, CR - - MOVW $(MACHADDR&~KZERO), R2 /* m-> */ - MOVW R1, 32(R2) - MOVW R3, 36(R2) - - MOVW SPR(MD_EPN), R1 - MOVW $(MACHADDR&~KZERO), R3 /* m-> */ - MOVW R1, 24(R3) /* save dar */ - MOVW SPR(SAVEXX), R3 - MOVW SPR(M_TW), R2 - MOVW LR, R0 - MOVW R0, SPR(SAVELR) - MOVW $0x1200, R0 - BR traps - -TEXT dtlberror(SB), $-4 - MOVW R0, SPR(SAVER0) - MOVW R1, SPR(SAVER1) - MOVW LR, R0 - MOVW R0, SPR(SAVELR) - MOVW $(MACHADDR&~KZERO), R1 /* m-> */ - MOVW SPR(DAR), R0 - MOVW R0, 24(R1) /* save dar */ - MOVW SPR(DSISR), R0 - MOVW R0, 28(R1) /* save dsisr */ - MOVW $0x1400, R0 - BR traps - -/* - * traps force memory mapping off. - * the following code has been executed at the exception - * vector location - * MOVW R0, SPR(SAVER0) - * MOVW LR, R0 - * MOVW R0, SPR(SAVELR) - * bl trapvec(SB) - */ -TEXT trapvec(SB), $-4 - MOVW LR, R0 - MOVW R1, SPR(SAVER1) -traps: - MOVW R0, SPR(SAVEXX) /* vector */ - -/* - to enable hardware break points - MOVW MSR, R1 - OR $(MSR_RI), R1 - MOVW R1, MSR - ISYNC -*/ - - /* did we come from user space */ - MOVW SPR(SRR1), R0 - MOVW CR, R1 - MOVW R0, CR - BC 4,17,ktrap - - /* switch to kernel stack */ - MOVW R1, CR - MOVW $(MACHADDR&~KZERO), R1 /* PADDR(m->) */ - MOVW 12(R1), R1 /* m->proc */ - RLWNM $0, R1, $~KZERO, R1 /* PADDR(m->proc) */ - MOVW 8(R1), R1 /* m->proc->kstack */ - RLWNM $0, R1, $~KZERO, R1 /* PADDR(m->proc->kstack) */ - ADD $(KSTACK-UREGSIZE), R1 - BL saveureg(SB) - BL trap(SB) - BR restoreureg -ktrap: - MOVW R1, CR - MOVW SPR(SAVER1), R1 - RLWNM $0, R1, $~KZERO, R1 /* PADDR(m->proc->kstack) */ - SUB $UREGSPACE, R1 - BL saveureg(SB) - BL trap(SB) - BR restoreureg - -TEXT intrvec(SB), $-4 - MOVW LR, R0 - - BR 0(PC) - -/* - * map data virtually and make space to save - */ - MOVW R0, SPR(SAVEXX) /* vector */ - MOVW R1, SPR(SAVER1) - SYNC - ISYNC - MOVW MSR, R0 - OR $MSR_DR, R0 /* make data space usable */ - SYNC - MOVW R0, MSR - MSRSYNC - SUB $UREGSPACE, R1 - - MFTB(TBRL, 0) - MOVW R0, intrtbl(SB) - - MOVW SPR(SRR0), R0 - MOVW R0, LR - MOVW SPR(SRR1), R0 - MOVW R0, 12(R1) - MOVW LR, R0 - MOVW R0, 16(R1) - BL saveureg(SB) - - MFTB(TBRL, 5) - MOVW R5, isavetbl(SB) - - BL intr(SB) -/* - * enter with stack set and mapped. - * on return, SB (R2) has been set, and R3 has the Ureg*, - * the MMU has been re-enabled, kernel text and PC are in KSEG, - * R(MACH) has been set, and R0 contains 0. - * - */ -TEXT saveureg(SB), $-4 -/* - * save state - */ - MOVMW R2, 48(R1) /* r2:r31 */ - MOVW $setSB(SB), R2 - MOVW $(MACHADDR&~KZERO), R(MACH) - MOVW 12(R(MACH)), R(USER) - MOVW $MACHADDR, R(MACH) - MOVW SPR(SAVER1), R4 - MOVW R4, 44(R1) - MOVW SPR(SAVER0), R5 - MOVW R5, 40(R1) - MOVW CTR, R6 - MOVW R6, 36(R1) - MOVW XER, R4 - MOVW R4, 32(R1) - MOVW CR, R5 - MOVW R5, 28(R1) - MOVW SPR(SAVELR), R6 /* LR */ - MOVW R6, 24(R1) - /* pad at 20(R1) */ - MOVW SPR(SRR0), R0 - MOVW R0, 16(R1) /* old PC */ - MOVW SPR(SRR1), R0 - MOVW R0, 12(R1) /* old status */ - MOVW SPR(SAVEXX), R0 - MOVW R0, 8(R1) /* cause/vector */ - ADD $8, R1, R3 /* Ureg* */ - OR $KZERO, R3 /* fix ureg */ - STWCCC R3, (R1) /* break any pending reservations */ - MOVW $0, R0 /* compiler/linker expect R0 to be zero */ - - MOVW MSR, R5 - OR $(MSR_IR|MSR_DR|MSR_RI), R5 /* enable MMU */ - MOVW R5, SPR(SRR1) - MOVW LR, R31 - OR $KZERO, R31 /* return PC in KSEG0 */ - MOVW R31, SPR(SRR0) - OR $KZERO, R1 /* fix stack pointer */ - RFI /* returns to trap handler */ - -/* - * restore state from Ureg and return from trap/interrupt - */ -TEXT forkret(SB), $0 - BR restoreureg - -restoreureg: - MOVMW 48(R1), R2 /* r2:r31 */ - /* defer R1 */ - MOVW 40(R1), R0 - MOVW R0, SPR(SAVER0) - MOVW 36(R1), R0 - MOVW R0, CTR - MOVW 32(R1), R0 - MOVW R0, XER - MOVW 28(R1), R0 - MOVW R0, CR /* CR */ - MOVW 24(R1), R0 - MOVW R0, LR - /* pad, skip */ - MOVW 16(R1), R0 - MOVW R0, SPR(SRR0) /* old PC */ - MOVW 12(R1), R0 - MOVW R0, SPR(SRR1) /* old MSR */ - /* cause, skip */ - MOVW 44(R1), R1 /* old SP */ - MOVW SPR(SAVER0), R0 - RFI - -TEXT flash(SB), $-4 -flash0: - BL powerupled(SB); - MOVW $0x100000, R5 - MOVW R5, CTR -delay0: - BDNZ delay0 - BL powerdownled(SB); - MOVW $0x100000, R5 - MOVW R5, CTR -delay1: - BDNZ delay1 - BR flash0 - -TEXT powerupled(SB), $0 - - MOVW $INTMEM,R11 - MOVH 0x970(R11), R7 - MOVW $0x100,R8 - OR R8,R7 - MOVH R7,0x970(R11) - MOVH 0x976(R11), R7 - ANDN R8,R7 - MOVH R7,0x976(R11) - RETURN - -TEXT powerdownled(SB), $0 - - MOVW $INTMEM,R11 - MOVH 0x970(R11), R7 - MOVW $0x100,R8 - OR R8,R7 - MOVH R7,0x970(R11) - MOVH 0x976(R11), R7 - OR R8,R7 - MOVH R7,0x976(R11) - RETURN - -GLOBL spltbl+0(SB), $4 -GLOBL intrtbl+0(SB), $4 -GLOBL isavetbl+0(SB), $4 - - RETURN - -/* - * TLB prototype entries, loaded once-for-all at startup, - * remaining unchanged thereafter. - * Limit the table to at most 4 entries - */ -#define TLBE(epn,twc,rpn) WORD $(epn); WORD $(twc); WORD $(rpn) - -TEXT tlbtab(SB), $-4 - /* epn, rpn, twc */ - TLBE(FLASHMEM|MMUEV, MMUPS8M|MMUWT|MMUV, FLASHMEM|MMUPP|MMUSPS|MMUSH|MMUCI|MMUV) /* FLASH, 8M */ - TLBE(DRAMMEM|MMUEV, MMUPS8M|MMUWT|MMUV, DRAMMEM|MMUPP|MMUSPS|MMUSH|MMUV) /* DRAM, second 8M */ - TLBE(INTMEM|MMUEV, MMUPS8M|MMUWT|MMUV, INTMEM|MMUPP|MMUSPS|MMUSH|MMUCI|MMUV) /* IO space 8M */ -TEXT tlbtabe(SB), $-4 - RETURN diff --git a/mpc/main.c b/mpc/main.c deleted file mode 100644 index 590f954197ceb8b2800b17a1b2ad947f018fc09f..0000000000000000000000000000000000000000 --- a/mpc/main.c +++ /dev/null @@ -1,402 +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 "pool.h" - -static char **confenv = (char**)(CONFPARSED); - -int predawn = 1; - -typedef struct Bootargs Bootargs; - -struct Bootargs -{ - char args[1000]; - uchar chksum; -}; - -/* - * software tlb simulation - */ -Softtlb stlb[MAXMACH][STLBSIZE]; - -Conf conf; - -void -main(void) -{ - powerdownled(); - machinit(); - clockinit(); - confinit(); - xinit(); - trapinit(); - printinit(); - cpminit(); - uartinstall(); -print("hello world from kernel %ux %ux %ux\n", m->iomem->pddat, m->iomem->pddir, m->iomem->pdpar); - spiinit(); - mmuinit(); - pageinit(); - procinit0(); - initseg(); - links(); - chandevreset(); - swapinit(); - userinit(); -predawn = 0; - schedinit(); -} - -void -machinit(void) -{ - IMM *io; - int mf, osc; - - memset(m, 0, sizeof(*m)); - m->delayloop = 20000; - m->cputype = getpvr()>>16; - m->iomem = KADDR(INTMEM); - m->stb = &stlb[0][0]; - - io = m->iomem; - osc = 50; - mf = io->plprcr >> 20; - m->oscclk = osc; - m->speed = osc*(mf+1); - m->cpuhz = m->speed*MHz; /* general system clock (cycles) */ - m->clockgen = osc*MHz; /* clock generator frequency (cycles) */ - - active.machs = 1; - active.exiting = 0; - - /* enable check stop reset */ - io->plprcrk = KEEP_ALIVE_KEY; // unlock - io->plprcr |= IBIT(24); // enable checkstop reset - putmsr(getmsr() | MSR_RI | MSR_ME); -// putmsr(getmsr() & ~MSR_ME); -} - -char* -getconf(char *name) -{ - char **p, *q; - int n; - - n = strlen(name); - - for(p = confenv; *p; p++) { - q = *p; - if(strncmp(q, name, n) == 0 && q[n] == '=') - return q+n+1; - } - return 0; -} - -void -init0(void) -{ - char **p, *q, name[NAMELEN]; - int n; - -print("init0\n"); - - up->nerrlab = 0; - - /* - * These are o.k. because rootinit is null. - * Then early kproc's will have a root and dot. - */ - up->slash = namec("#/", Atodir, 0, 0); - cnameclose(up->slash->name); - up->slash->name = newcname("/"); - up->dot = cclone(up->slash, 0); - - chandevinit(); - - if(!waserror()){ - ksetenv("cputype", "power"); - if(cpuserver) - ksetenv("service", "cpu"); - else - ksetenv("service", "terminal"); - - for(p = confenv; *p; p++) { - q = strchr(p[0], '='); - if(q == 0) - continue; - n = q-p[0]; - if(n >= NAMELEN) - n = NAMELEN-1; - memmove(name, p[0], n); - name[n] = 0; - ksetenv(name, q+1); - } - poperror(); - } - kproc("alarm", alarmkproc, 0); - print("to user!!\n"); - touser((void*)(USTKTOP-8)); -} - -void -userinit(void) -{ - Proc *p; - Segment *s; - KMap *k; - Page *pg; - - p = newproc(); - p->pgrp = newpgrp(); - p->egrp = smalloc(sizeof(Egrp)); - p->egrp->ref = 1; - p->fgrp = dupfgrp(nil); - p->rgrp = newrgrp(); - p->procmode = 0640; - - strcpy(p->text, "*init*"); - strcpy(p->user, eve); - p->fpstate = FPinit; - - /* - * Kernel Stack - * - * N.B. The -12 for the stack pointer is important. - * 4 bytes for gotolabel's return PC - */ - p->sched.pc = (ulong)init0; - p->sched.sp = (ulong)p->kstack+KSTACK-(1+MAXSYSARG)*BY2WD; - - /* - * User Stack - */ - s = newseg(SG_STACK, USTKTOP-USTKSIZE, USTKSIZE/BY2PG); - p->seg[SSEG] = s; - pg = newpage(1, 0, USTKTOP-BY2PG); - segpage(s, pg); - - /* - * Text - */ - s = newseg(SG_TEXT, UTZERO, 1); - s->flushme++; - p->seg[TSEG] = s; - pg = newpage(1, 0, UTZERO); - memset(pg->cachectl, PG_TXTFLUSH, sizeof(pg->cachectl)); - segpage(s, pg); - k = kmap(s->map[0]->pages[0]); - memmove((ulong*)VA(k), initcode, sizeof initcode); - kunmap(k); - - ready(p); -} - -void -exit(int ispanic) -{ - int ms, once; - - lock(&active); - if(ispanic) - active.ispanic = ispanic; - else if(m->machno == 0 && (active.machs & (1<machno)) == 0) - active.ispanic = 0; - once = active.machs & (1<machno); - active.machs &= ~(1<machno); - active.exiting = 1; - unlock(&active); - - if(once) - print("cpu%d: exiting\n", m->machno); - spllo(); - for(ms = 5*1000; ms > 0; ms -= TK2MS(2)){ - delay(TK2MS(2)); - if(active.machs == 0 && consactive() == 0) - break; - } - - if(active.ispanic && m->machno == 0){ - if(cpuserver) - delay(10000); - else - for(;;); - } - else - delay(1000); - - for(;;) - ; -// arch->reset(); -} - -/* - * set up floating point for a new process - */ -void -procsetup(Proc *p) -{ - USED(p); -} - -/* - * Save the mach dependent part of the process state. - */ -void -procsave(Proc *p) -{ - USED(p); -} - -// print without using interrupts -void -serialputs(char *s, int n) -{ - putstrn(s, n); -} - -void -rdb(void) -{ - panic("rdb"); -} - -void -confinit(void) -{ - int nbytes; - ulong pa; - char **p; - - /* fix up confenv */ - for(p = confenv; *p; p++) - *p = KADDR(*p); - - conf.nmach = 1; /* processors */ - conf.nproc = 60; /* processes */ - - // hard wire for now - pa = 0x200000; // leave 2 Meg for kernel - nbytes = 8*1024*1024; // leave room at the top as well - - conf.npage0 = nbytes/BY2PG; - conf.base0 = pa; - - conf.npage1 = 0; - conf.base1 = pa; - - conf.npage = conf.npage0 + conf.npage1; - - conf.upages = (conf.npage*60)/100; - conf.ialloc = ((conf.npage-conf.upages)/2)*BY2PG; - - /* set up other configuration parameters */ - conf.nswap = 0; - conf.nswppo = 0; - conf.nimage = 20; - - conf.copymode = 0; /* copy on write */ -} - -static int -getcfields(char* lp, char** fields, int n, char* sep) -{ - int i; - - for(i = 0; lp && *lp && i < n; i++){ - while(*lp && strchr(sep, *lp) != 0) - *lp++ = 0; - if(*lp == 0) - break; - fields[i] = lp; - while(*lp && strchr(sep, *lp) == 0){ - if(*lp == '\\' && *(lp+1) == '\n') - *lp++ = ' '; - lp++; - } - } - - return i; -} - -int -isaconfig(char *class, int ctlrno, ISAConf *isa) -{ - char cc[NAMELEN], *p, *q, *r; - - sprint(cc, "%s%d", class, ctlrno); - - p = getconf(cc); - if(p == 0) - return 0; -print("%s=%s\n", cc, p); - isa->nopt = 0; - while(*p){ - while(*p == ' ' || *p == '\t') - p++; - if(*p == '\0') - break; - if(strncmp(p, "type=", 5) == 0){ - p += 5; - for(q = isa->type; q < &isa->type[NAMELEN-1]; q++){ - if(*p == '\0' || *p == ' ' || *p == '\t') - break; - *q = *p++; - } - *q = '\0'; - } - else if(strncmp(p, "port=", 5) == 0) - isa->port = strtoul(p+5, &p, 0); - else if(strncmp(p, "irq=", 4) == 0) - isa->irq = strtoul(p+4, &p, 0); - else if(strncmp(p, "mem=", 4) == 0) - isa->mem = strtoul(p+4, &p, 0); - else if(strncmp(p, "size=", 5) == 0) - isa->size = strtoul(p+5, &p, 0); - else if(strncmp(p, "freq=", 5) == 0) - isa->freq = strtoul(p+5, &p, 0); - else if(strncmp(p, "dma=", 4) == 0) - isa->dma = strtoul(p+4, &p, 0); - else if(isa->nopt < NISAOPT){ - r = isa->opt[isa->nopt]; - while(*p && *p != ' ' && *p != '\t'){ - *r++ = *p++; - if(r-isa->opt[isa->nopt] >= ISAOPTLEN-1) - break; - } - *r = '\0'; - isa->nopt++; - } - while(*p && *p != ' ' && *p != '\t') - p++; - } - return 1; -} - -int -cistrcmp(char *a, char *b) -{ - int ac, bc; - - for(;;){ - ac = *a++; - bc = *b++; - - if(ac >= 'A' && ac <= 'Z') - ac = 'a' + (ac - 'A'); - if(bc >= 'A' && bc <= 'Z') - bc = 'a' + (bc - 'A'); - ac -= bc; - if(ac) - return ac; - if(bc == 0) - break; - } - return 0; -} - diff --git a/mpc/mem.h b/mpc/mem.h deleted file mode 100644 index 18998bed42de77d99202d2318f0dff895614917d..0000000000000000000000000000000000000000 --- a/mpc/mem.h +++ /dev/null @@ -1,216 +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 BY2V 8 /* bytes per double word */ -#define BY2PG 4096 /* bytes per page */ -#define WD2PG (BY2PG/BY2WD) /* words per page */ -#define PGSHIFT 12 /* log(BY2PG) */ -#define ROUND(s, sz) (((s)+((sz)-1))&~((sz)-1)) -#define PGROUND(s) ROUND(s, BY2PG) -#define CACHELINELOG 4 -#define CACHELINESZ (1< */ -#define USER 29 /* R29 is up-> */ - - -/* - * virtual MMU - */ -#define PTEMAPMEM (1024*1024) -#define PTEPERTAB (PTEMAPMEM/BY2PG) -#define SEGMAPSIZE 1984 -#define SSEGMAPSIZE 16 -#define PPN(x) ((x)&~(BY2PG-1)) - -/* - * Fundamental addresses - */ -#define MACHADDR (KTZERO-MAXMACH*MACHSIZE) -#define MACHP(n) ((Mach *)(MACHADDR+(n)*MACHSIZE)) - -#define UREGSIZE ((8+32)*4) - -/* - * MMU - */ - -/* L1 table entry and Mx_TWC flags */ -#define PTEWT (1<<1) /* write through */ -#define PTE4K (0<<2) -#define PTE512K (1<<2) -#define PTE8MB (3<<2) -#define PTEG (1<<4) /* guarded */ - -/* L2 table entry and Mx_RPN flags (also PTEVALID) */ -#define PTECI (1<<1) /* cache inhibit */ -#define PTESH (1<<2) /* page is shared; ASID ignored */ -#define PTELPS (1<<3) /* large page size */ - -#define PTEKERNEL (0<<2) -#define PTEUSER (1<<2) -#define PTESIZE (1<<7) - -#define NTLBPID 16 -#define TLBPID(n) ((n)&(NTLBPID-1)) - -/* soft tlb */ -#define STLBLOG 12 -#define STLBSIZE (1<ticks); - n = 10000000/size; - while(n) { - memmove(d0+align, d1, size); - n--; - } - t += TK2MS(m->ticks); - print("size = %d align = %d KB/s %d %d\n", size, align, 10000000/t, t); -} - diff --git a/mpc/mmu.c b/mpc/mmu.c deleted file mode 100644 index b80b1d013f30bfc203f7e2dbf21acc45460585e9..0000000000000000000000000000000000000000 --- a/mpc/mmu.c +++ /dev/null @@ -1,172 +0,0 @@ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "io.h" - -#define TLBINVLAID KZERO - -void -mmuinit(void) -{ - int i; - - print("mmuinit\n"); - for(i=0; istb[i].virt = TLBINVLAID; -} - -void -flushmmu(void) -{ - int x; - -if(0)print("flushmmu(%ld)\n", up->pid); - x = splhi(); - up->newtlb = 1; - mmuswitch(up); - splx(x); -} - -/* - * called with splhi - */ -void -mmuswitch(Proc *p) -{ - int tp; - -if(0)print("mmuswitch()\n"); - if(p->newtlb) { - memset(p->pidonmach, 0, sizeof p->pidonmach); - p->newtlb = 0; - } - tp = p->pidonmach[m->machno]; - putcasid(tp); -} - -void -mmurelease(Proc* p) -{ -if(0)print("mmurelease(%ld)\n", p->pid); - memset(p->pidonmach, 0, sizeof p->pidonmach); -} - -void -purgetlb(int pid) -{ - int i, mno; - Proc *sp, **pidproc; - Softtlb *entry, *etab; - -if(0)print("purgetlb: pid = %d\n", pid); - m->tlbpurge++; - /* - * find all pid entries that are no longer used by processes - */ - mno = m->machno; - pidproc = m->pidproc; - for(i=1; ipidonmach[mno] != i) - pidproc[i] = 0; - } - - /* - * shoot down the one we want - */ - sp = pidproc[pid]; - if(sp != 0) - sp->pidonmach[mno] = 0; - pidproc[pid] = 0; - - /* - * clean out all dead pids from the stlb; - */ - entry = m->stb; - for(etab = &entry[STLBSIZE]; entry < etab; entry++) - if(pidproc[TLBPID(entry->virt)] == 0) - entry->virt = TLBINVLAID; - - /* - * clean up the hardware - */ - tlbflushall(); -} - -int -newtlbpid(Proc *p) -{ - int i, s; - Proc **h; - - i = m->lastpid; - h = m->pidproc; - for(s = 0; s < NTLBPID; s++) { - i++; - if(i >= NTLBPID) - i = 1; - if(h[i] == 0) - break; - } - - if(h[i]) { - i = m->purgepid+1; - if(i >= NTLBPID) - i = 1; - m->purgepid = i; - purgetlb(i); - } - - if(h[i] != 0) - panic("newtlb"); - - m->pidproc[i] = p; - p->pidonmach[m->machno] = i; - m->lastpid = i; -if(0)print("newtlbpid: pid=%ld = tlbpid = %d\n", p->pid, i); - return i; -} - -void -putmmu(ulong va, ulong pa, Page *pg) -{ - char *ctl; - int tp; - ulong h; - - qlock(&m->stlblk); - - tp = up->pidonmach[m->machno]; - if(tp == 0) { - tp = newtlbpid(up); - putcasid(tp); - } - - h = ((va>>12)^(va>>24)^(tp<<8)) & 0xfff; - m->stb[h].virt = va|tp; - m->stb[h].phys = pa; - tlbflush(va); - - qunlock(&m->stlblk); - - ctl = &pg->cachectl[m->machno]; -if(0)print("putmmu tp=%d h=%ld va=%lux pa=%lux ctl=%x\n", tp, h,va, pa, *ctl); - switch(*ctl) { - default: - panic("putmmu: %d\n", *ctl); - break; - case PG_NOFLUSH: - break; - case PG_TXTFLUSH: - dcflush((void*)pg->va, BY2PG); - icflush((void*)pg->va, BY2PG); - *ctl = PG_NOFLUSH; - break; - case PG_NEWCOL: -print("PG_NEWCOL!!\n"); - *ctl = PG_NOFLUSH; - break; - } -} diff --git a/mpc/ms.c b/mpc/ms.c deleted file mode 100644 index 2b369925be81b731db3d9bcc522a8f3872629b9d..0000000000000000000000000000000000000000 --- a/mpc/ms.c +++ /dev/null @@ -1,82 +0,0 @@ -#include -#include - -char d0[1000008], d1[1000008]; - -void test(int size, int align); - -memtest(char *pp, int n) -{ - static int seed = 0; - ulong *p, *ep; - ulong x; - -if(seed % 100 == 0) -print("memtest seed = %d\n", seed); - - p = (ulong*)pp; - ep = (ulong*)(pp+n); - - x = seed; - while(p < ep) { - *p++ = x; - x *= 1103515245; - } - - x = seed; - p = (ulong*)pp; - ep = (ulong*)(pp+n); - while(p < ep) { - if(*p++ != x) { - print("error %ux!!\n", ((char*)p) - pp); - return; - } - x *= 1103515245; - } - seed++; -} - -void -main() -{ - int j; - - memmove(d0, d1, sizeof(d0)); - - for(j=0; j<10; j++) { - memtest(d0, sizeof(d0)); - } - - for(j = 0; j<8; j++) - test(12, j); - for(j = 0; j<8; j++) - test(100, j); - for(j = 0; j<8; j++) - test(400, j); - for(j = 0; j<8; j++) - test(1000, j); - for(j = 0; j<8; j++) - test(10000, j); - for(j = 0; j<8; j++) - test(100000, j); - for(j = 0; j<8; j++) - test(1000000, j); - - exits(0); -} - -void -test(int size, int align) -{ - int n; - int t; - - t = -times(0); - n = 10000000/size; - while(n) { - memmove(d0+align, d1, size); - n--; - } - t += times(0); - print("size = %d align = %d KB/s %d %d\n", size, align, 10000000/t, t); -} diff --git a/mpc/nocache.c b/mpc/nocache.c deleted file mode 100644 index ce11c8cc79f3b885525faecb690185c1951c0494..0000000000000000000000000000000000000000 --- a/mpc/nocache.c +++ /dev/null @@ -1,38 +0,0 @@ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "../port/error.h" - -// No file caching - -void -cinit(void) -{ -} - -void -copen(Chan *c) -{ - USED(c); -} - -int -cread(Chan *c, uchar *buf, int len, vlong off) -{ - USED(c, buf, len, off); - return 0; -} - -void -cupdate(Chan *c, uchar *buf, int len, vlong off) -{ - USED(c, buf, len, off); -} - -void -cwrite(Chan* c, uchar *buf, int len, vlong off) -{ - USED(c, buf, len, off); -} diff --git a/mpc/random.c b/mpc/random.c deleted file mode 100644 index 4954367f8ad4a996b0d9ee49e775103f92beb9b8..0000000000000000000000000000000000000000 --- a/mpc/random.c +++ /dev/null @@ -1,138 +0,0 @@ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "../port/error.h" - - -struct Rb -{ - QLock; - Rendez producer; - Rendez consumer; - ulong randomcount; - uchar buf[1024]; - uchar *ep; - uchar *rp; - uchar *wp; - uchar next; - uchar wakeme; - ushort bits; - ulong randn; -} rb; - -static int -rbnotfull(void*) -{ - int i; - - i = rb.rp - rb.wp; - return i != 1 && i != (1 - sizeof(rb.buf)); -} - -static int -rbnotempty(void*) -{ - return rb.wp != rb.rp; -} - -void -genrandom(void*) -{ - up->basepri = PriNormal; - up->priority = up->basepri; - - for(;;){ - for(;;) - if(++rb.randomcount > 100000) - break; - if(anyhigher()) - sched(); - if(!rbnotfull(0)) - sleep(&rb.producer, rbnotfull, 0); - } -} - -/* - * produce random bits in a circular buffer - */ -static void -randomclock(void) -{ - if(rb.randomcount == 0 || !rbnotfull(0)) - return; - - rb.bits = (rb.bits<<2) ^ rb.randomcount; - rb.randomcount = 0; - - rb.next++; - if(rb.next != 8/2) - return; - rb.next = 0; - - *rb.wp ^= rb.bits; - if(rb.wp+1 == rb.ep) - rb.wp = rb.buf; - else - rb.wp = rb.wp+1; - - if(rb.wakeme) - wakeup(&rb.consumer); -} - -void -randominit(void) -{ - addclock0link(randomclock); - rb.ep = rb.buf + sizeof(rb.buf); - rb.rp = rb.wp = rb.buf; - kproc("genrandom", genrandom, 0); -} - -/* - * consume random bytes from a circular buffer - */ -ulong -randomread(void *xp, ulong n) -{ - uchar *e, *p; - ulong x; - - p = xp; - - if(waserror()){ - qunlock(&rb); - nexterror(); - } - - qlock(&rb); - for(e = p + n; p < e; ){ - if(rb.wp == rb.rp){ - rb.wakeme = 1; - wakeup(&rb.producer); - sleep(&rb.consumer, rbnotempty, 0); - rb.wakeme = 0; - continue; - } - - /* - * beating clocks will be precictable if - * they are synchronized. Use a cheap pseudo - * random number generator to obscure any cycles. - */ - x = rb.randn*1103515245 ^ *rb.rp; - *p++ = rb.randn = x; - - if(rb.rp+1 == rb.ep) - rb.rp = rb.buf; - else - rb.rp = rb.rp+1; - } - qunlock(&rb); - poperror(); - - wakeup(&rb.producer); - - return n; -} diff --git a/mpc/rmap.c b/mpc/rmap.c deleted file mode 100644 index 964ba029d11e9cc25595ce426440222259f09068..0000000000000000000000000000000000000000 --- a/mpc/rmap.c +++ /dev/null @@ -1,106 +0,0 @@ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" - -void -mapinit(RMap *rmap, Map *map, int size) -{ - lock(rmap); - rmap->map = map; - rmap->mapend = map+(size/sizeof(Map)); - unlock(rmap); -} - -void -mapfree(RMap* rmap, ulong addr, int size) -{ - Map *mp; - ulong t; - - if(size <= 0) - return; - - lock(rmap); - for(mp = rmap->map; mp->addr <= addr && mp->size; mp++) - ; - - if(mp > rmap->map && (mp-1)->addr+(mp-1)->size == addr){ - (mp-1)->size += size; - if(addr+size == mp->addr){ - (mp-1)->size += mp->size; - while(mp->size){ - mp++; - (mp-1)->addr = mp->addr; - (mp-1)->size = mp->size; - } - } - } - else{ - if(addr+size == mp->addr && mp->size){ - mp->addr -= size; - mp->size += size; - } - else do{ - if(mp >= rmap->mapend){ - print("mapfree: %s: losing 0x%luX, %d\n", - rmap->name, addr, size); - break; - } - t = mp->addr; - mp->addr = addr; - addr = t; - t = mp->size; - mp->size = size; - mp++; - }while(size = t); - } - unlock(rmap); -} - -ulong -rmapalloc(RMap* rmap, ulong addr, int size, int align) -{ - Map *mp; - ulong maddr, oaddr; - - lock(rmap); - for(mp = rmap->map; mp->size; mp++){ - maddr = mp->addr; - - if(addr){ - if(maddr > addr) - break; - if(maddr+mp->size < addr) - continue; - if(addr+size > maddr+mp->size) - break; - maddr = addr; - } - - if(align > 0) - maddr = ((maddr+align-1)/align)*align; - if(mp->addr+mp->size-maddr < size) - continue; - - oaddr = mp->addr; - mp->addr = maddr+size; - mp->size -= maddr-oaddr+size; - if(mp->size == 0){ - do{ - mp++; - (mp-1)->addr = mp->addr; - }while((mp-1)->size = mp->size); - } - - unlock(rmap); - if(oaddr != maddr) - mapfree(rmap, oaddr, maddr-oaddr); - - return maddr; - } - unlock(rmap); - - return 0; -} diff --git a/mpc/sh.c b/mpc/sh.c deleted file mode 100644 index 8f18d06900ae7d0125c6d23076c8e5da8249e682..0000000000000000000000000000000000000000 --- a/mpc/sh.c +++ /dev/null @@ -1,481 +0,0 @@ -/* sh - simple shell - great for early stages of porting */ -#include -#include - -#define MAXLINE 200 /* maximum line length */ -#define WORD 256 /* token code for words */ -#define EOF -1 /* token code for end of file */ -#define ispunct(c) (c=='|' || c=='&' || c==';' || c=='<' || \ - c=='>' || c=='(' || c==')' || c=='\n') -#define isspace(c) (c==' ' || c=='\t') -#define execute(np) (np? (*(np)->op)(np) : 0) - -typedef struct Node Node; -struct Node{ /* parse tree node */ - int (*op)(Node *); /* operator function */ - Node *args[2]; /* argument nodes */ - char *argv[100]; /* argument pointers */ - char *io[3]; /* i/o redirection */ -}; - -Node nodes[25]; /* node pool */ -Node *nfree; /* next available node */ -char strspace[10*MAXLINE]; /* string storage */ -char *sfree; /* next free character in strspace */ -int t; /* current token code */ -char *token; /* current token text (in strspace) */ -int putback = 0; /* lookahead */ -Waitmsg status; /* exit status of most recent command */ -int cflag = 0; /* command is argument to sh */ -int tflag = 0; /* read only one line */ -int interactive = 0; /* prompt */ -char *cflagp; /* command line for cflag */ -char *path[] ={"/bin", 0}; - -Node *alloc(int (*op)(Node *)); -int builtin(Node *np); -Node *command(void); -int getch(void); -int gettoken(void); -Node *list(void); -void error(char *s, char *t); -Node *pipeline(void); -void redirect(Node *np); -int setio(Node *np); -Node *simple(void); -int xpipeline(Node *np); -int xsimple(Node *np); -int xsubshell(Node *np); -int xnowait(Node *np); -int xwait(Node *np); - -main(int argc, char *argv[]) -{ - Node *np; - - open("#c/cons", OREAD); - open("#c/cons", OWRITE); - open("#c/cons", OWRITE); - - print("hello world from sh\n"); - - if(argc>1 && strcmp(argv[1], "-t")==0) - tflag++; - else if(argc>2 && strcmp(argv[1], "-c")==0){ - cflag++; - cflagp = argv[2]; - }else if(argc>1){ - close(0); - if(open(argv[1], 0) != 0){ - error(": can't open", argv[1]); - exits("argument"); - } - }else - interactive = 1; - for(;;){ - if(interactive) - fprint(2, "%d$ ", getpid()); - nfree = nodes; - sfree = strspace; - if((t=gettoken()) == EOF) - break; - if(t != '\n') - if(np = list()) - execute(np); - else - error("syntax error", ""); - while(t!=EOF && t!='\n') /* flush syntax errors */ - t = gettoken(); - } - exits(status.msg); -} - -/* alloc - allocate for op and return a node */ -Node* -alloc(int (*op)(Node *)) -{ - if(nfree < nodes+sizeof(nodes)){ - nfree->op = op; - nfree->args[0] = nfree->args[1] = 0; - nfree->argv[0] = nfree->argv[1] = 0; - nfree->io[0] = nfree->io[1] = nfree->io[2] = 0; - return nfree++; - } - error("node storage overflow", ""); - exits("node storage overflow"); -} - -/* builtin - check np for builtin command and, if found, execute it */ -int -builtin(Node *np) -{ - int n = 0; - char *s, name[MAXLINE]; - - if(np->argv[1]) - n = strtoul(np->argv[1], 0, 0); - if(strcmp(np->argv[0], "cd") == 0){ - if(chdir(np->argv[1]? np->argv[1] : "/") == -1) - error(": bad directory", np->argv[0]); - return 1; - }else if(strcmp(np->argv[0], "exit") == 0) - exits(np->argv[1]? np->argv[1] : status.msg); - else if(strcmp(np->argv[0], "bind") == 0){ - if(np->argv[1]==0 || np->argv[2]==0) - error("usage: bind new old", ""); - else if(bind(np->argv[1], np->argv[2], 0)==-1) - error("bind failed", ""); - return 1; -#ifdef asdf - }else if(strcmp(np->argv[0], "unmount") == 0){ - if(np->argv[1] == 0) - error("usage: unmount [new] old", ""); - else if(np->argv[2] == 0){ - if(unmount((char *)0, np->argv[1]) == -1) - error("unmount:", ""); - }else if(unmount(np->argv[1], np->argv[2]) == -1) - error("unmount", ""); - return 1; -#endif - }else if(strcmp(np->argv[0], "wait") == 0){ - while(wait(&status) != -1) - if(n && atoi(status.pid)==n){ - n = 0; - break; - } - if(n) - error("wait error", ""); - return 1; - }else if(strcmp(np->argv[0], "newpgrp") == 0){ - int i; - i = rfork(RFNAMEG|RFENVG); - if(i < 0) - error("rfork error", ""); - else - fprint(2, "%d\n", i); - return 1; - }else if(strcmp(np->argv[0], "exec") == 0){ - redirect(np); - if(np->argv[1] == (char *) 0) - return 1; - exec(np->argv[1], &np->argv[1]); - n = np->argv[1][0]; - if(n!='/' && n!='#' && (n!='.' || np->argv[1][1]!='/')) - for(n = 0; path[n]; n++){ - sprint(name, "%s/%s", path[n], np->argv[1]); - exec(name, &np->argv[1]); - } - error(": not found", np->argv[1]); - return 1; - } - return 0; -} - -/* command - ( list ) [ ( < | > | >> ) word ]* | simple */ -Node* -command(void) -{ - Node *np; - - if(t != '(') - return simple(); - np = alloc(xsubshell); - t = gettoken(); - if((np->args[0]=list())==0 || t!=')') - return 0; - while((t=gettoken())=='<' || t=='>') - if(!setio(np)) - return 0; - return np; -} - -/* getch - get next, possibly pushed back, input character */ -int -getch(void) -{ - unsigned char c; - static done=0; - - if(putback){ - c = putback; - putback = 0; - }else if(tflag){ - if(done || read(0, &c, 1)!=1){ - done = 1; - return EOF; - } - if(c == '\n') - done = 1; - }else if(cflag){ - if(done) - return EOF; - if((c=*cflagp++) == 0){ - done = 1; - c = '\n'; - } - }else if(read(0, &c, 1) != 1) - return EOF; - return c; -} - -/* gettoken - get next token into string space, return token code */ -int -gettoken(void) -{ - int c; - - while((c = getch()) != EOF) - if(!isspace(c)) - break; - if(c==EOF || ispunct(c)) - return c; - token = sfree; - do{ - if(sfree >= strspace+sizeof(strspace) - 1){ - error("string storage overflow", ""); - exits("string storage overflow"); - } - *sfree++ = c; - }while((c=getch()) != EOF && !ispunct(c) && !isspace(c)); - *sfree++ = 0; - putback = c; - return WORD; -} - -/* list - pipeline ( ( ; | & ) pipeline )* [ ; | & ] (not LL(1), but ok) */ -Node* -list(void) -{ - Node *np, *np1; - - np = alloc(0); - if((np->args[1]=pipeline()) == 0) - return 0; - while(t==';' || t=='&'){ - np->op = (t==';')? xwait : xnowait; - t = gettoken(); - if(t==')' || t=='\n') /* tests ~first(pipeline) */ - break; - np1 = alloc(0); - np1->args[0] = np; - if((np1->args[1]=pipeline()) == 0) - return 0; - np = np1; - } - if(np->op == 0) - np->op = xwait; - return np; -} - -/* error - print error message s, prefixed by t */ -void -error(char *s, char *t) -{ - char buf[ERRLEN]; - - fprint(2, "%s%s", t, s); - errstr(buf); - fprint(2, ": %s\n", buf); -} - -/* pipeline - command ( | command )* */ -Node* -pipeline(void) -{ - Node *np, *np1; - - if((np=command()) == 0) - return 0; - while(t == '|'){ - np1 = alloc(xpipeline); - np1->args[0] = np; - t = gettoken(); - if((np1->args[1]=command()) == 0) - return 0; - np = np1; - } - return np; -} - -/* redirect - redirect i/o according to np->io[] values */ -void -redirect(Node *np) -{ - int fd; - - if(np->io[0]){ - if((fd = open(np->io[0], 0)) < 0){ - error(": can't open", np->io[0]); - exits("open"); - } - dup(fd, 0); - close(fd); - } - if(np->io[1]){ - if((fd = create(np->io[1], 1, 0666L)) < 0){ - error(": can't create", np->io[1]); - exits("create"); - } - dup(fd, 1); - close(fd); - } - if(np->io[2]){ - if((fd = open(np->io[2], 1)) < 0 && (fd = create(np->io[2], 1, 0666L)) < 0){ - error(": can't write", np->io[2]); - exits("write"); - } - dup(fd, 1); - close(fd); - seek(1, 0, 2); - } -} - -/* setio - ( < | > | >> ) word; fill in np->io[] */ -int -setio(Node *np) -{ - if(t == '<'){ - t = gettoken(); - np->io[0] = token; - }else if(t == '>'){ - t = gettoken(); - if(t == '>'){ - t = gettoken(); - np->io[2] = token; - }else - np->io[1] = token; - }else - return 0; - if(t != WORD) - return 0; - return 1; -} - -/* simple - word ( [ < | > | >> ] word )* */ -Node* -simple(void) -{ - Node *np; - int n = 1; - - if(t != WORD) - return 0; - np = alloc(xsimple); - np->argv[0] = token; - while((t = gettoken())==WORD || t=='<' || t=='>') - if(t == WORD) - np->argv[n++] = token; - else if(!setio(np)) - return 0; - np->argv[n] = 0; - return np; -} - -/* xpipeline - execute cmd | cmd */ -int -xpipeline(Node *np) -{ - int pid, fd[2]; - - if(pipe(fd) < 0){ - error("can't create pipe", ""); - return 0; - } - if((pid=fork()) == 0){ /* left side; redirect stdout */ - dup(fd[1], 1); - close(fd[0]); - close(fd[1]); - execute(np->args[0]); - exits(status.msg); - }else if(pid == -1){ - error("can't create process", ""); - return 0; - } - if((pid=fork()) == 0){ /* right side; redirect stdin */ - dup(fd[0], 0); - close(fd[0]); - close(fd[1]); - pid = execute(np->args[1]); /*BUG: this is wrong sometimes*/ - if(pid > 0) - while(wait(&status)!=-1 && atoi(status.pid)!=pid) - ; - exits(0); - }else if(pid == -1){ - error("can't create process", ""); - return 0; - } - close(fd[0]); /* avoid using up fd's */ - close(fd[1]); - return pid; -} - -/* xsimple - execute a simple command */ -int -xsimple(Node *np) -{ - char name[MAXLINE]; - int pid, i; - - if(builtin(np)) - return 0; - if(pid = fork()){ - if(pid == -1) - error(": can't create process", np->argv[0]); - return pid; - } - redirect(np); /* child process */ - exec(np->argv[0], &np->argv[0]); - i = np->argv[0][0]; - if(i!='/' && i!='#' && (i!='.' || np->argv[0][1]!='/')) - for(i = 0; path[i]; i++){ - sprint(name, "%s/%s", path[i], np->argv[0]); - exec(name, &np->argv[0]); - } - error(": not found", np->argv[0]); - exits("not found"); -} - -/* xsubshell - execute (cmd) */ -int -xsubshell(Node *np) -{ - int pid; - - if(pid = fork()){ - if(pid == -1) - error("can't create process", ""); - return pid; - } - redirect(np); /* child process */ - execute(np->args[0]); - exits(status.msg); -} - -/* xnowait - execute cmd & */ -int -xnowait(Node *np) -{ - int pid; - - execute(np->args[0]); - pid = execute(np->args[1]); - if(interactive) - fprint(2, "%d\n", pid); - return 0; -} - -/* xwait - execute cmd ; */ -int xwait(Node *np) -{ - int pid; - - execute(np->args[0]); - pid = execute(np->args[1]); - if(pid > 0){ - while(wait(&status) != -1 && atoi(status.pid) != pid) - ; - if(atoi(status.pid) != pid) - error("wait error", ""); - } - return 0; -} diff --git a/mpc/spi.c b/mpc/spi.c deleted file mode 100644 index c1f43a18047a03fffb0bc8e0d8c60884174e998e..0000000000000000000000000000000000000000 --- a/mpc/spi.c +++ /dev/null @@ -1,547 +0,0 @@ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "io.h" - -typedef struct SPIparam SPIparam; -struct SPIparam { - ushort rbase; - ushort tbase; - uchar rfcr; - uchar tfcr; - ushort mrblr; - ulong rstate; - ulong rptr; - ushort rbptr; - ushort rcnt; - ulong rtmp; - ulong tstate; - ulong tptr; - ushort tbptr; - ushort tcnt; - ulong ttmp; -}; - -enum { - Nrdre = 2, /* receive descriptor ring entries */ - Ntdre = 2, /* transmit descriptor ring entries */ - - Rbsize = 8, /* ring buffer size (+3 for PID+CRC16) */ - Bufsize = (Rbsize+7)&~7, /* aligned */ -}; - -enum { - /* spi-specific BD flags */ - BDContin= 1<<9, /* continuous mode */ - BDrxov= 1<<1, /* overrun */ - BDtxun= 1<<1, /* underflow */ - BDme= 1<<0, /* multimaster error */ - BDrxerr= BDrxov|BDme, - BDtxerr= BDtxun|BDme, - - /* spmod */ - MLoop= 1<<14, /* loopback mode */ - MClockInv= 1<<13, /* inactive state of SPICLK is high */ - MClockPhs= 1<<12, /* SPCLK starts toggling at beginning of transfer */ - MDiv16= 1<<11, /* use BRGCLK/16 as input to SPI baud rate */ - MRev= 1<<10, /* normal operation */ - MMaster= 1<<9, - MSlave= 0<<9, - MEnable= 1<<8, - /* LEN, PS fields */ - - /* spie */ - MME = 1<<5, - TXE = 1<<4, - RES = 1<<3, - BSY = 1<<2, - TXB = 1<<1, - RXB = 1<<0, -}; - -/* - * software structures - */ -typedef struct Ctlr Ctlr; - -struct Ctlr { - QLock; - int init; - SPI* spi; - SPIparam* sp; - - int rxintr; - Rendez ir; - Ring; -}; - -static Ctlr spictlr[1]; - -static void interrupt(Ureg*, void*); - -/* - * test driver for SPI, host mode - */ -void -spireset(void) -{ - IMM *io; - SPI *spi; - SPIparam *sp; - Ctlr *ctlr; - - io = m->iomem; - sp = (SPIparam*)cpmparam(SPIP, sizeof(*sp)); - memset(sp, 0, sizeof(*sp)); - if(sp == nil){ - print("SPI: can't allocate new parameter memory\n"); - return; - } - - spi = (SPI*)((ulong)m->iomem+0xAA0); - ctlr = spictlr; - - /* step 1: select port pins */ - io->pbdir |= IBIT(30)|IBIT(29)|IBIT(28); - io->pbpar |= IBIT(30)|IBIT(29)|IBIT(28); /* SPICLK, SPIMOSI, SPIMISO */ - - /* step 2: set CS pin - also disables SPISEL */ - io->pbpar &= ~(IBIT(31)); - io->pbdir |= IBIT(31); - io->pbodr &= ~(IBIT(31)); - io->pbdat &= ~(IBIT(31)); - - ctlr->spi = spi; - ctlr->sp = sp; - - if(ioringinit(ctlr, Nrdre, Ntdre, Bufsize)<0) - panic("spireset: ioringinit"); - - /* step 3: configure rbase and tbase */ - sp->rbase = PADDR(ctlr->rdr); - sp->tbase = PADDR(ctlr->tdr); - - /* step 4: do not issue InitRxTx command - due to microcode bug */ - - /* step 5: */ - io->sdcr = 1; - - /* step 6: */ - sp->rfcr = 0x10; - sp->tfcr = 0x10; - - /* step 7: */ - sp->mrblr = Bufsize; - - /* step 7.5: init other params because of bug in microcode */ - sp->rstate = 0; - sp->rbptr = sp->rbase; - sp->rcnt = 0; - sp->tstate = 0; - sp->tbptr = sp->tbase; - sp->tcnt = 0; - - /* step 8-9: done by ioringinit */ - - /* step 10: clear events */ - spi->spie = ~0; - - /* step 11-12: enable interrupts */ - intrenable(VectorCPIC+0x05, interrupt, spictlr, BUSUNKNOWN); - spi->spim = ~0; - - /* step 13: enable in master mode, 8 bit chacters, slow clock */ - spi->spmode = MMaster|MRev|MDiv16|MEnable|(0x7<<4)|0xf; - -} - -static void -interrupt(Ureg*, void *arg) -{ - int events; - Ctlr *ctlr; - SPI *spi; - - ctlr = arg; - spi = ctlr->spi; - events = spi->spie; - spi->spie = events; -// print("SPI#%x\n", events); -} - -void -spdump(SPIparam *sp) -{ - print("rbase = %ux\n", sp->rbase); - print("tbase = %ux\n", sp->tbase); - print("rfcr = %ux\n", sp->rfcr); - print("tfcr = %ux\n", sp->tfcr); - print("mrblr = %ux\n", sp->mrblr); - print("rstate = %lux\n", sp->rstate); - print("rptr = %lux\n", sp->rptr); - print("rbptr = %ux\n", sp->rbptr); - print("rcnt = %ux\n", sp->rcnt); - print("rtmp = %lux\n", sp->rtmp); - print("tstate = %lux\n", sp->tstate); - print("tptr = %lux\n", sp->tptr); - print("tbptr = %ux\n", sp->tbptr); - print("tcnt = %ux\n", sp->tcnt); - print("ttmp = %lux\n", sp->ttmp); -} - -void -spitest(void) -{ - BD *dre; - Block *b; - int len; - Ctlr *ctlr; - ulong status; - uchar buf[2]; - - ctlr = spictlr; - - dre = &ctlr->tdr[ctlr->tdrh]; - if(dre->status & BDReady) - panic("spitest: txstart"); - -print("dre->status %ux %ux\n", dre[0].status, dre[1].status); - b = allocb(4); - b->wp[0] = 0xc0; - b->wp[1] = 0x00; - b->wp[2] = 0x00; - b->wp[3] = 0x00; - b->wp += 4; - len = BLEN(b); -print("len = %d\n", len); - dcflush(b->rp, len); - if(ctlr->txb[ctlr->tdrh] != nil) - panic("scc/ether: txstart"); - ctlr->txb[ctlr->tdrh] = b; - dre->addr = PADDR(b->rp); -print("addr = %lux\n", PADDR(b->rp)); - dre->length = len; - dre->status = (dre->status & BDWrap) | BDReady|BDInt|BDLast; -spdump(ctlr->sp); -m->iomem->pbdat |= IBIT(31); -microdelay(1); - ctlr->spi->spcom = 1<<7; /* transmit now */ -print("cpcom = %p\n", &ctlr->spi->spcom); -spdump(ctlr->sp); - eieio(); - ctlr->ntq++; - ctlr->tdrh = NEXT(ctlr->tdrh, Ntdre); -print("going into loop %ux %ux\n", dre->status, ctlr->spi->spcom); - while(dre->status&BDReady) { -print("ctrl->spi->spim = %ux %ux\n", ctlr->spi->spie, dre->status); -spdump(ctlr->sp); - delay(10000); - } -delay(100); - dre = &ctlr->rdr[ctlr->rdrx]; - status = dre->status; - len = dre->length; -print("%d status = %lux len=%d\n", ctlr->rdrx, status, len); - b = iallocb(len); - memmove(b->wp, KADDR(dre->addr), len); - b->wp += len; -print("%ux %ux %ux %ux\n", b->rp[0], b->rp[1], b->rp[2], b->rp[3]); - -/* get the data out of the receiving block - the data begins at the 13th bit, and ends at the (13+16)th bit -*/ - buf[0]=b->rp[1]<<4 | b->rp[2]>>4; - buf[1]=b->rp[2]<<4 | b->rp[3]>>4; - -print("the value of address 0 in EEPROM is %ux %ux\n",buf[0],buf[1]); - dcflush(KADDR(dre->addr), len); - dre->status = (status & BDWrap) | BDEmpty | BDInt; - ctlr->rdrx = NEXT(ctlr->rdrx, Nrdre); -m->iomem->pbdat &= ~(IBIT(31)); -microdelay(1); -} - - -void -spiinit(void) -{ - spireset(); -// spitest(); -} - -void -spicmdsend(Block *b, BD *dre, Ctlr *ctlr, int CSdown) -{ - int len; - - if(dre->status & BDReady) - panic("spicmdsend: txstart"); - - len = BLEN(b); - dcflush(b->rp, len); - - ctlr->txb[ctlr->tdrh] = b; - dre->addr = PADDR(b->rp); - dre->length = len; - dre->status = (dre->status & BDWrap) | BDReady|BDInt|BDLast; - m->iomem->pbdat |= IBIT(31); - - ctlr->spi->spcom = 1<<7; /* transmit now */ - - //eieio(); - ctlr->ntq++; - ctlr->tdrh = NEXT(ctlr->tdrh, Ntdre); - - delay(1); - - while(dre->status&BDReady) microdelay(10); - - if(CSdown) m->iomem->pbdat &= ~(IBIT(31)); - -} - - -void -spiread(ulong addr,uchar * buf) -{ - - BD *dre; - Block *b; - int len; - Ctlr *ctlr; - ushort status; - - ctlr = spictlr; - - dre = &ctlr->tdr[ctlr->tdrh]; - - b = allocb(4); - b->wp[0] = 0xc0 | addr>>3; - b->wp[1] = addr<<5; - b->wp[2] = 0x00; - b->wp[3] = 0x00; - b->wp += 4; - - spicmdsend(b, dre, ctlr, 0); - - //delay(10); - - dre = &ctlr->rdr[ctlr->rdrx]; - status = dre->status; - len = dre->length; - - while(dre->status&BDEmpty) microdelay(10); - - b = iallocb(len); - memmove(b->wp, KADDR(dre->addr), len); - b->wp += len; - - -/* get the data out of the receiving block - the data begins at the 13th bit, and ends at the (13+16)th bit -*/ - buf[0]=b->rp[1]<<4 | b->rp[2]>>4; - buf[1]=b->rp[2]<<4 | b->rp[3]>>4; - -// print("read out %ux %ux\n", buf[0],buf[1]); - dcflush(KADDR(dre->addr), len); - dre->status = (status & BDWrap) | BDEmpty | BDInt; - ctlr->rdrx = NEXT(ctlr->rdrx, Nrdre); - freeb(b); - m->iomem->pbdat &= ~(IBIT(31)); - microdelay(5); - - return; -} - -void -spienwrite(void) -{ - BD *dre; - Block *b; - Ctlr *ctlr; - int len; - - ctlr = spictlr; - - b = allocb(4); - b->wp[0] = 0x98; - b->wp[1] = 0x00; - b->wp[2] = 0x00; - b->wp[3] = 0x00; - b->wp += 4; - - dre = &ctlr->tdr[ctlr->tdrh]; - spicmdsend(b,dre,ctlr,1); - - dre=&ctlr->rdr[ctlr->rdrx]; - len=dre->length; - dcflush(KADDR(dre->addr),len); - dre->status=(dre->status&BDWrap)|BDEmpty|BDInt; - ctlr->rdrx=NEXT(ctlr->rdrx,Nrdre); - - freeb(b); - microdelay(5); - return; -} - -void -spidiswrite(void) -{ - BD *dre; - Block *b; - Ctlr *ctlr; - int len; - - ctlr = spictlr; - - dre = &ctlr->tdr[ctlr->tdrh]; - - b = allocb(4); - b->wp[0] = 0x80; - b->wp[1] = 0x00; - b->wp[2] = 0x00; - b->wp[3] = 0x00; - b->wp += 4; - - spicmdsend(b,dre,ctlr,1); - - dre=&ctlr->rdr[ctlr->rdrx]; - len=dre->length; - dcflush(KADDR(dre->addr),len); - dre->status=(dre->status&BDWrap)|BDEmpty|BDInt; - ctlr->rdrx=NEXT(ctlr->rdrx,Nrdre); - - freeb(b); - microdelay(5); - return; -} - -void -spiwrite(ulong addr, uchar *buf) -{ - BD *dre; - Block *b; - Ctlr *ctlr; - int len; - - ctlr = spictlr; - - dre = &ctlr->tdr[ctlr->tdrh]; - - b = allocb(4); - b->wp[0] = 0x05 ; - b->wp[1] = 0x7f & addr; - b->wp+=2; - memmove((uchar*)b->wp,buf,2); - b->wp += 2; - - spicmdsend(b,dre,ctlr,1); - - dre=&ctlr->rdr[ctlr->rdrx]; - len=dre->length; - dcflush(KADDR(dre->addr),len); - dre->status=(dre->status&BDWrap)|BDEmpty|BDInt; - ctlr->rdrx=NEXT(ctlr->rdrx,Nrdre); - - freeb(b); - delay(15); - //sleep(15); //sleep for 15ms - return; -} - -void -spiwriteall(uchar *buf) -{ - BD *dre; - Block *b; - Ctlr *ctlr; - int len; - - ctlr = spictlr; - - dre = &ctlr->tdr[ctlr->tdrh]; - - b = allocb(4); - b->wp[0] = 0x04; - b->wp[1] = 0x40; - b->wp+=2; - memmove((uchar*)b->wp,buf,2); - //b->wp[2]=0xf0; - //b->wp[3]=0xf0; - b->wp += 2; - - spicmdsend(b,dre,ctlr,1); - - dre=&ctlr->rdr[ctlr->rdrx]; - len=dre->length; - dcflush(KADDR(dre->addr),len); - dre->status=(dre->status&BDWrap)|BDEmpty|BDInt; - ctlr->rdrx=NEXT(ctlr->rdrx,Nrdre); - - freeb(b); - delay(15); - //sleep(15000); //sleep for 15ms - print("leave spiwriteall\n"); - return; -} - -void -spierase(ulong addr) -{ - BD *dre; - Block *b; - Ctlr *ctlr; - int len; - - ctlr = spictlr; - - b = allocb(2); - b->wp[0] = 0x07; - b->wp[1] = addr&0x7f; - b->wp+=2; - - dre = &ctlr->tdr[ctlr->tdrh]; - spicmdsend(b,dre,ctlr,1); - - dre=&ctlr->rdr[ctlr->rdrx]; - len=dre->length; - dcflush(KADDR(dre->addr),len); - dre->status=(dre->status&BDWrap)|BDEmpty|BDInt; - ctlr->rdrx=NEXT(ctlr->rdrx,Nrdre); - - freeb(b); - delay(15); - return; -} - -void -spieraseall(void) -{ - BD *dre; - Block *b; - Ctlr *ctlr; - int len; - - ctlr = spictlr; - - b = allocb(2); - b->wp[0] = 0x07; - b->wp[1] = 0x80; - b->wp+=2; - - dre = &ctlr->tdr[ctlr->tdrh]; - spicmdsend(b,dre,ctlr,1); - - dre=&ctlr->rdr[ctlr->rdrx]; - len=dre->length; - dcflush(KADDR(dre->addr),len); - dre->status=(dre->status&BDWrap)|BDEmpty|BDInt; - ctlr->rdrx=NEXT(ctlr->rdrx,Nrdre); - - freeb(b); - delay(15); - return; -} diff --git a/mpc/tar.c b/mpc/tar.c deleted file mode 100644 index 108dd8eb0675b2d666c07afc3e2cbeea3215b2c9..0000000000000000000000000000000000000000 --- a/mpc/tar.c +++ /dev/null @@ -1,86 +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" - -typedef union Hblock Hblock; - -#define TBLOCK 512 -#define NAMSIZ 100 -union Hblock -{ - char dummy[TBLOCK]; - struct header - { - char name[NAMSIZ]; - char mode[8]; - char uid[8]; - char gid[8]; - char size[12]; - char mtime[12]; - char chksum[8]; - char linkflag; - char linkname[NAMSIZ]; - } dbuf; -}; - -static int getdir(Hblock *hb, Dir *sp); -static int checksum(Hblock *hb); - -uchar* -tarlookup(uchar *addr, char *file, int *dlen) -{ - Hblock *hp; - Dir dir; - -print("tarlookup: %p\n", addr); - hp = (Hblock*)addr; - while(getdir(hp, &dir) != 0) { -print("name = %s\n", hp->dbuf.name); - if(strcmp(file, hp->dbuf.name) == 0) { - *dlen = dir.length; - return (uchar*)(hp+1); - } - hp += (dir.length+TBLOCK-1)/TBLOCK + 1; - } - return 0; -} - -static int -getdir(Hblock *hp, Dir *sp) -{ - int chksum; - - if (hp->dbuf.name[0] == '\0') - return 0; - sp->mode = strtol(hp->dbuf.mode, 0, 8); - strncpy(sp->uid, "adm", sizeof(sp->uid)); - strncpy(sp->gid, "adm", sizeof(sp->gid)); - sp->length = strtol(hp->dbuf.size, 0, 8); - sp->mtime = strtol(hp->dbuf.mtime, 0, 8); - chksum = strtol(hp->dbuf.chksum, 0, 8); - if (chksum != checksum(hp)) { - print("directory checksum error\n"); - return 0; - } - return 1; -} - -static int -checksum(Hblock *hp) -{ - int i; - char *cp; - - i = 0; - for (cp = hp->dummy; cp < &hp->dummy[TBLOCK]; cp++) { - if(cp < hp->dbuf.chksum || cp >= &hp->dbuf.chksum[sizeof(hp->dbuf.chksum)]) - i += *cp & 0xff; - else - i += ' ' & 0xff; - } - return(i); -} diff --git a/mpc/trap.c b/mpc/trap.c deleted file mode 100644 index 4ba11ef77b5e43e00cc04ee3f48641cba77995ec..0000000000000000000000000000000000000000 --- a/mpc/trap.c +++ /dev/null @@ -1,828 +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" - -enum -{ - Maxhandler= 32+16, /* max number of interrupt handlers */ -}; - -typedef struct Handler Handler; -struct Handler -{ - void (*r)(Ureg*, void*); - void *arg; - Handler *next; - int edge; - int nintr; - ulong ticks; - int maxtick; -}; - -struct -{ - Handler *ivec[128]; - Handler h[Maxhandler]; - int free; -} halloc; - -void faultpower(Ureg *ur, ulong addr, int read); -void kernfault(Ureg*, int); -void syscall(Ureg* ureg); -void noted(Ureg*, ulong); -void reset(void); - -char *excname[] = -{ - "reserved 0", - "system reset", - "machine check", - "data access", - "instruction access", - "external interrupt", - "alignment", - "program exception", - "floating-point unavailable", - "decrementer", - "i/o controller interface error", - "reserved B", - "system call", - "trace trap", - "floating point assist", - "reserved F", - "software emulation", - "ITLB miss", - "DTLB miss", - "ITLB error", - "DTLB error", - "reserved 15", - "reserved 16", - "reserved 17", - "reserved 18", - "reserved 19", - "reserved 1A", - "reserved 1B", - "data breakpoint", - "instruction breakpoint", - "peripheral breakpoint", - "development port", - /* the following are made up on a program exception */ - "floating point exception", /* 20: FPEXC */ - "illegal instruction", /* 21 */ - "privileged instruction", /* 22 */ - "trap", /* 23 */ - "illegal operation", /* 24 */ - "breakpoint", /* 25 */ -}; - -char *fpcause[] = -{ - "inexact operation", - "division by zero", - "underflow", - "overflow", - "invalid operation", -}; -char *fpexcname(Ureg*, ulong, char*); -#define FPEXPMASK 0xfff80300 /* Floating exception bits in fpscr */ - - -char *regname[]={ - "CAUSE", "SRR1", - "PC", "GOK", - "LR", "CR", - "XER", "CTR", - "R0", "R1", - "R2", "R3", - "R4", "R5", - "R6", "R7", - "R8", "R9", - "R10", "R11", - "R12", "R13", - "R14", "R15", - "R16", "R17", - "R18", "R19", - "R20", "R21", - "R22", "R23", - "R24", "R25", - "R26", "R27", - "R28", "R29", - "R30", "R31", -}; - -void -sethvec(int v, void (*r)(void)) -{ - ulong *vp, pa, o; - - vp = KADDR(v); - vp[0] = 0x7c1043a6; /* MOVW R0, SPR(SPRG0) */ - vp[1] = 0x7c0802a6; /* MOVW LR, R0 */ - vp[2] = 0x7c1243a6; /* MOVW R0, SPR(SPRG2) */ - pa = PADDR(r); - o = pa >> 25; - if(o != 0 && o != 0x7F){ - /* a branch too far */ - vp[3] = (15<<26)|(pa>>16); /* MOVW $r&~0xFFFF, R0 */ - vp[4] = (24<<26)|(pa&0xFFFF); /* OR $r&0xFFFF, R0 */ - vp[5] = 0x7c0803a6; /* MOVW R0, LR */ - vp[6] = 0x4e800021; /* BL (LR) */ - }else - vp[3] = (18<<26)|(pa&0x3FFFFFC)|3; /* bla */ - dcflush(vp, 8*sizeof(ulong)); -} - -void -sethvec2(int v, void (*r)(void)) -{ - ulong *vp; - - vp = (ulong*)KADDR(v); - vp[0] = (18<<26)|(PADDR(r))|2; /* ba */ - dcflush(vp, sizeof(*vp)); -} - -void -trap(Ureg *ur) -{ - int ecode; - static struct {int callsched;} c = {1}; - int user = (ur->srr1 & MSR_PR) != 0; - char buf[ERRLEN]; - - m->intrts = fastticks(nil); - ecode = (ur->cause >> 8) & 0xff; - -if(ur->status & MSR_RI == 0) -print("double fault?: ecode = %d\n", ecode); - switch(ecode){ - case CEI: - intr(ur); - break; - - case CDEC: - clockintr(ur); - break; - case CIMISS: - faultpower(ur, ur->pc, 1); - break; - case CITLBE: - faultpower(ur, ur->pc, 1); - break; - case CDMISS: -if(0) print("CDMISS: %lux %lux\n", m->epn, m->cmp1); - faultpower(ur, m->dar, 1); - break; - case CDTLBE: - faultpower(ur, m->dar, !(m->dsisr & (1<<25))); - break; - - case CEMU: - print("CEMU: pc=#%lux op=#%8.8lux\n", ur->pc, *(ulong*)ur->pc); - sprint(buf, "sys: trap: illegal op addr=0x%lux", ur->pc); - postnote(up, 1, buf, NDebug); - break; - - case CSYSCALL: - syscall(ur); - break; - - case CPROG: - if(ur->status & (1<<19)) - ecode = 0x20; - if(ur->status & (1<<18)) - ecode = 0x21; - if(ur->status & (1<<17)) - ecode = 0x22; - goto Default; - - Default: - default: - spllo(); - print("ecode = %d\n", ecode); - if(ecode < 0 || ecode >= 0x1F) - ecode = 0x1F; - print("kernel %s pc=0x%lux\n", excname[ecode], ur->pc); - dumpregs(ur); - dumpstack(); - delay(100); - reset(); - } - - splhi(); - if(user) - notify(ur); -} - -void -faultpower(Ureg *ureg, ulong addr, int read) -{ - int user, insyscall, n; - char buf[ERRLEN]; - user = (ureg->srr1 & MSR_PR) != 0; -if(0)print("fault: pid=%ld pc = %lux, addr = %lux read = %d user = %d stack=%ulx\n", up->pid, ureg->pc, addr, read, user, &ureg); - insyscall = up->insyscall; - up->insyscall = 1; - spllo(); - n = fault(addr, read); - if(n < 0){ - if(!user){ - dumpregs(ureg); - panic("fault: 0x%lux\n", addr); - } -print("fault: pid=%ld pc = %lux, addr = %lux read = %d user = %d stack=%ulx\n", up->pid, ureg->pc, addr, read, user, &ureg); -dumpregs(ureg); - sprint(buf, "sys: trap: fault %s addr=0x%lux", - read? "read" : "write", addr); - postnote(up, 1, buf, NDebug); - } - up->insyscall = insyscall; -} - -void -spurious(Ureg *ur, void *a) -{ - USED(a); - print("SPURIOUS interrupt pc=0x%lux cause=0x%lux\n", - ur->pc, ur->cause); - panic("bad interrupt"); -} - -#define LEV(n) (((n)<<1)|1) -#define IRQ(n) (((n)<<1)|0) - -Lock veclock; - -void -trapinit(void) -{ - int i; - IMM *io; - - - io = m->iomem; - io->sypcr &= ~(1<<3); /* disable watchdog (821/823) */ - io->simask = 0; /* mask all */ - io->siel = ~0; /* edge sensitive, wake on all */ - io->cicr = 0; /* disable CPM interrupts */ - io->cipr = ~0; /* clear all interrupts */ - io->cimr = 0; /* mask all events */ - io->cicr = (0xE1<<16)|(CPIClevel<<13)|(0x1F<<8); - io->cicr |= 1 << 7; /* enable */ - io->tbscr = 1; /* TBE */ - io->simask |= 1<<(31-LEV(CPIClevel)); /* CPM's level */ - eieio(); - putdec(~0); - - /* - * set all exceptions to trap - */ - for(i = 0x0; i < 0x2000; i += 0x100) - sethvec(i, trapvec); - - //sethvec(CEI<<8, intrvec); - sethvec2(CIMISS<<8, itlbmiss); - sethvec2(CDMISS<<8, dtlbmiss); - sethvec2(CDTLBE<<8, dtlberror); -} - -void -intrenable(int v, void (*r)(Ureg*, void*), void *arg, int) -{ - Handler *h; - IMM *io; - - if(halloc.free >= Maxhandler) - panic("out of interrupt handlers"); - v -= VectorPIC; - if(v < 0 || v >= nelem(halloc.ivec)) - panic("intrenable(%d)", v+VectorPIC); - ilock(&veclock); - if(v < VectorCPIC || (h = halloc.ivec[v]) == nil){ - h = &halloc.h[halloc.free++]; - h->next = halloc.ivec[v]; - halloc.ivec[v] = h; - } - h->r = r; - h->arg = arg; - - /* - * enable corresponding interrupt in SIU/CPM - */ - - eieio(); - io = m->iomem; - if(v >= VectorCPIC){ - v -= VectorCPIC; - io->cimr |= 1<<(v&0x1F); - } - else if(v >= VectorIRQ) - io->simask |= 1<<(31-IRQ(v&7)); - else - io->simask |= 1<<(31-LEV(v)); - eieio(); - iunlock(&veclock); -} - -void -intr(Ureg *ur) -{ - int b, v; - IMM *io; - Handler *h; - long t0; - - ur->cause &= ~0xff; - io = m->iomem; - b = io->sivec>>2; - v = b>>1; - if(b & 1) { - if(v == CPIClevel){ - io->civr = 1; - eieio(); - v = VectorCPIC+(io->civr>>11); - } - }else - v += VectorIRQ; - ur->cause |= v; - h = halloc.ivec[v]; - if(h == nil){ - print("unknown interrupt %d pc=0x%lux\n", v, ur->pc); - uartwait(); - return; - } - if(h->edge){ - io->sipend |= 1<<(31-b); - eieio(); - } - /* - * call the interrupt handlers - */ - do { - h->nintr++; - t0 = getdec(); - (*h->r)(ur, h->arg); - t0 -= getdec(); - h->ticks += t0; - if(h->maxtick < t0) - h->maxtick = t0; - h = h->next; - } while(h != nil); - if(v >= VectorCPIC) - io->cisr |= 1<<(v-VectorCPIC); - eieio(); -} - -int -intrstats(char *buf, int bsize) -{ - Handler *h; - int i, n; - - n = 0; - for(i=0; inintr) - n += snprint(buf+n, bsize-n, "%3d %ud %uld %ud\n", i, h->nintr, h->ticks, h->maxtick); - return n; -} - -char* -fpexcname(Ureg *ur, ulong fpscr, char *buf) -{ - int i; - char *s; - ulong fppc; - - fppc = ur->pc; - s = 0; - fpscr >>= 3; /* trap enable bits */ - fpscr &= (fpscr>>22); /* anded with exceptions */ - for(i=0; i<5; i++) - if(fpscr & (1<status, ur->pc, ur->sp); - dumpregs(ur); - l.sp = ur->sp; - l.pc = ur->pc; - dumpstack(); - for(;;) - sched(); -} - -void -dumpstack(void) -{ - ulong l, v; - int i; - - if(up == 0) - return; - i = 0; - for(l=(ulong)&l; l<(ulong)(up->kstack+KSTACK); l+=4){ - v = *(ulong*)l; - if(KTZERO < v && v < (ulong)etext){ - print("%lux=%lux, ", l, v); - if(i++ == 4){ - print("\n"); - i = 0; - } - } - } -} - -void -dumpregs(Ureg *ur) -{ - int i; - ulong *l; - if(up) { - print("registers for %s %ld\n", up->text, up->pid); - if(ur->srr1 & MSR_PR == 0) - if(ur->usp < (ulong)up->kstack || ur->usp > (ulong)up->kstack+KSTACK) - print("invalid stack ptr\n"); - } - else - print("registers for kernel\n"); - - print("dsisr\t%.8lux\tdar\t%.8lux\n", getdsisr(), getdar()); - l = &ur->cause; - for(i=0; ikpfun)(up->kparg); - pexit("", 0); -} - -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; -} - -int -isvalid_pc(ulong pc) -{ - return KERNPC(pc) && (pc&3) == 0; -} - -void -dumplongs(char*, ulong*, int) -{ -} - -void -reset(void) -{ - IMM *io; - - io = m->iomem; - io->plprcrk = KEEP_ALIVE_KEY; // unlock - io->plprcr |= IBIT(24); // enable checkstop reset - putmsr(getmsr() & ~(MSR_ME|MSR_RI)); -predawn = 1; -print("reset = %ulx\n", getmsr()); - delay(1000); - // cause checkstop -> causes reset - *(uchar*)(0xdeadbeef) = 0; - *(ulong*)(0) = 0; -} - -/* - * called in sysfile.c - */ -void -evenaddr(ulong addr) -{ - if(addr & 3){ - postnote(up, 1, "sys: odd address", NDebug); - error(Ebadarg); - } -} - -long -execregs(ulong entry, ulong ssize, ulong nargs) -{ - ulong *sp; - Ureg *ureg; - - sp = (ulong*)(USTKTOP - ssize); - *--sp = nargs; - - ureg = up->dbgreg; - ureg->usp = (ulong)sp; - ureg->pc = entry; - return USTKTOP-BY2WD; /* address of user-level clock */ -} - -void -forkchild(Proc *p, Ureg *ur) -{ - Ureg *cur; - - p->sched.sp = (ulong)p->kstack+KSTACK-UREGSIZE; - p->sched.pc = (ulong)forkret; - - cur = (Ureg*)(p->sched.sp+2*BY2WD); - memmove(cur, ur, sizeof(Ureg)); - cur->r3 = 0; - - /* Things from bottom of syscall we never got to execute */ - p->psstate = 0; - p->insyscall = 0; -} - -ulong -userpc(void) -{ - Ureg *ureg; - - ureg = (Ureg*)up->dbgreg; - return ureg->pc; -} - - -/* 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) -{ - ulong status; - - status = xp->status; - memmove(pureg, uva, n); - xp->status = status; -} - -/* Give enough context in the ureg to produce a kernel stack for - * a sleeping process - */ -void -setkernur(Ureg* ureg, Proc* p) -{ - ureg->pc = p->sched.pc; - ureg->sp = p->sched.sp+4; -} - -ulong -dbgpc(Proc *p) -{ - Ureg *ureg; - - ureg = p->dbgreg; - if(ureg == 0) - return 0; - - return ureg->pc; -} - -/* - * system calls - */ -#include "../port/systab.h" - -/* - * Syscall should be called directly from assembler without going through trap(). - */ -void -syscall(Ureg* ureg) -{ - ulong sp; - long ret; - int i, scallnr; - - if((ureg->srr1 & MSR_PR) == 0) - panic("syscall: srr1 0x%4.4uX\n", ureg->srr1); - - m->syscall++; - up->insyscall = 1; - up->pc = ureg->pc; - up->dbgreg = ureg; - - scallnr = ureg->r3; -//print("scall %s lr =%lux\n", sysctab[scallnr], ureg->lr); - up->scallnr = scallnr; - spllo(); - - sp = ureg->usp; - up->nerrlab = 0; - ret = -1; - if(!waserror()){ - if(scallnr >= nsyscall){ - pprint("bad sys call number %d pc %lux\n", scallnr, ureg->pc); - postnote(up, 1, "sys: bad sys call", NDebug); - error(Ebadarg); - } - - if(sp<(USTKTOP-BY2PG) || sp>(USTKTOP-sizeof(Sargs)-BY2WD)) - validaddr(sp, sizeof(Sargs)+BY2WD, 0); - - up->s = *((Sargs*)(sp+BY2WD)); - up->psstate = sysctab[scallnr]; - - ret = systab[scallnr](up->s.args); - poperror(); - } - if(up->nerrlab){ - print("bad errstack [%d]: %d extra\n", scallnr, up->nerrlab); - print("scall %s lr =%lux\n", sysctab[scallnr], ureg->lr); - for(i = 0; i < NERR; i++) - print("sp=%lux pc=%lux\n", up->errlab[i].sp, up->errlab[i].pc); - panic("error stack"); - } - - up->insyscall = 0; - up->psstate = 0; - - /* - * Put return value in frame. On the x86 the syscall is - * just another trap and the return value from syscall is - * ignored. On other machines the return value is put into - * the results register by caller of syscall. - */ - ureg->r3 = ret; - - if(scallnr == NOTED) - noted(ureg, *(ulong*)(sp+BY2WD)); - - if(scallnr!=RFORK && (up->procctl || up->nnote)){ - splhi(); - notify(ureg); - } -} -/* - * Call user, if necessary, with note. - * Pass user the Ureg struct and the note on his stack. - */ -int -notify(Ureg* ur) -{ - int l; - ulong s, sp; - Note *n; - - if(up->procctl) - procctl(up); - if(up->nnote == 0) - return 0; - - s = spllo(); - 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" */ - l = ERRLEN-15; - sprint(n->msg+l, " pc=0x%.8lux", ur->pc); - } - - if(n->flag!=NUser && (up->notified || up->notify==0)){ - if(n->flag == NDebug) - pprint("suicide: %s\n", n->msg); - qunlock(&up->debug); - pexit(n->msg, n->flag!=NDebug); - } - - if(up->notified) { - qunlock(&up->debug); - splhi(); - return 0; - } - - if(!up->notify) { - qunlock(&up->debug); - pexit(n->msg, n->flag!=NDebug); - } - sp = ur->usp & ~(BY2V-1); - sp -= sizeof(Ureg); - - if(!okaddr((ulong)up->notify, BY2WD, 0) || - !okaddr(sp-ERRLEN-4*BY2WD, sizeof(Ureg)+ERRLEN+4*BY2WD, 1)) { - pprint("suicide: bad address or sp in notify\n"); - qunlock(&up->debug); - pexit("Suicide", 0); - } - - memmove((Ureg*)sp, ur, sizeof(Ureg)); - *(Ureg**)(sp-BY2WD) = up->ureg; /* word under Ureg is old up->ureg */ - up->ureg = (void*)sp; - sp -= BY2WD+ERRLEN; - memmove((char*)sp, up->note[0].msg, ERRLEN); - sp -= 3*BY2WD; - *(ulong*)(sp+2*BY2WD) = sp+3*BY2WD; /* arg 2 is string */ - ur->r1 = (long)up->ureg; /* arg 1 is ureg* */ - ((ulong*)sp)[1] = (ulong)up->ureg; /* arg 1 0(FP) is ureg* */ - ((ulong*)sp)[0] = 0; /* arg 0 is pc */ - ur->usp = sp; - 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(&up->debug); - splx(s); - return 1; -} - - -/* - * Return user to state before notify() - */ -void -noted(Ureg* ureg, ulong arg0) -{ - Ureg *nureg; - ulong oureg, sp; - - qlock(&up->debug); - if(arg0!=NRSTR && !up->notified) { - qunlock(&up->debug); - pprint("call to noted() when not notified\n"); - pexit("Suicide", 0); - } - up->notified = 0; - - nureg = up->ureg; /* pointer to user returned Ureg struct */ - - /* sanity clause */ - oureg = (ulong)nureg; - if(!okaddr((ulong)oureg-BY2WD, BY2WD+sizeof(Ureg), 0)){ - pprint("bad ureg in noted or call to noted when not notified\n"); - qunlock(&up->debug); - pexit("Suicide", 0); - } - - memmove(ureg, nureg, sizeof(Ureg)); - - switch(arg0){ - case NCONT: - case NRSTR: - if(!okaddr(nureg->pc, 1, 0) || !okaddr(nureg->usp, BY2WD, 0)){ - pprint("suicide: trap in noted\n"); - qunlock(&up->debug); - pexit("Suicide", 0); - } - up->ureg = (Ureg*)(*(ulong*)(oureg-BY2WD)); - qunlock(&up->debug); - break; - - case NSAVE: - if(!okaddr(nureg->pc, BY2WD, 0) - || !okaddr(nureg->usp, BY2WD, 0)){ - pprint("suicide: trap in noted\n"); - qunlock(&up->debug); - pexit("Suicide", 0); - } - qunlock(&up->debug); - sp = oureg-4*BY2WD-ERRLEN; - splhi(); - ureg->sp = sp; - ((ulong*)sp)[1] = oureg; /* arg 1 0(FP) is ureg* */ - ((ulong*)sp)[0] = 0; /* arg 0 is pc */ - break; - - default: - pprint("unknown noted arg 0x%lux\n", arg0); - up->lastnote.flag = NDebug; - /* fall through */ - - case NDFLT: - if(up->lastnote.flag == NDebug) - pprint("suicide: %s\n", up->lastnote.msg); - qunlock(&up->debug); - pexit(up->lastnote.msg, up->lastnote.flag!=NDebug); - } -} diff --git a/mpc/unsac.c b/mpc/unsac.c deleted file mode 100644 index f918792eef7b6c1333d51bc59299900b45b14916..0000000000000000000000000000000000000000 --- a/mpc/unsac.c +++ /dev/null @@ -1,627 +0,0 @@ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "io.h" - -typedef struct Huff Huff; -typedef struct Mtf Mtf; -typedef struct Decode Decode; - -enum -{ - ZBase = 2, /* base of code to encode 0 runs */ - LitBase = ZBase-1, /* base of literal values */ - MaxLit = 256, - - MaxLeaf = MaxLit+LitBase, - MaxHuffBits = 16, /* max bits in a huffman code */ - MaxFlatbits = 5, /* max bits decoded in flat table */ - - CombLog = 4, - CombSpace = 1 << CombLog, /* mtf speedup indices spacing */ - CombMask = CombSpace - 1, -}; - -struct Mtf -{ - int maxcomb; /* index of last valid comb */ - uchar prev[MaxLit]; - uchar next[MaxLit]; - uchar comb[MaxLit / CombSpace + 1]; -}; - -struct Huff -{ - int maxbits; - int flatbits; - ulong flat[1<prev[i] = last; - m->next[i] = i + 1; - last = i; - } - m->next[last] = 0; - f = 0; - - /* - * pull valid entries off free list and enter into mtf list - */ - comb = 0; - last = front[0]; - for(i = 0; i < n; i++){ - me = front[i]; - - f = m->next[me]; - m->prev[f] = m->prev[me]; - m->next[m->prev[f]] = f; - - m->next[last] = me; - m->prev[me] = last; - last = me; - if((i & CombMask) == 0) - m->comb[comb++] = me; - } - - /* - * pad out the list with dummies to the next comb, - * using free entries - */ - for(; i & CombMask; i++){ - me = f; - - f = m->next[me]; - m->prev[f] = m->prev[me]; - m->next[m->prev[f]] = f; - - m->next[last] = me; - m->prev[me] = last; - last = me; - } - me = front[0]; - m->next[last] = me; - m->prev[me] = last; - m->comb[comb] = me; - m->maxcomb = comb; -} - -static int -mtflist(Mtf *m, int pos) -{ - uchar *next, *prev, *mycomb; - int c, c0, pc, nc, off; - - if(pos == 0) - return m->comb[0]; - - next = m->next; - prev = m->prev; - mycomb = &m->comb[pos >> CombLog]; - off = pos & CombMask; - if(off >= CombSpace / 2){ - c = mycomb[1]; - for(; off < CombSpace; off++) - c = prev[c]; - }else{ - c = *mycomb; - for(; off; off--) - c = next[c]; - } - - nc = next[c]; - pc = prev[c]; - prev[nc] = pc; - next[pc] = nc; - - for(; mycomb > m->comb; mycomb--) - *mycomb = prev[*mycomb]; - c0 = *mycomb; - *mycomb = c; - mycomb[m->maxcomb] = c; - - next[c] = c0; - pc = prev[c0]; - prev[c] = pc; - prev[c0] = c; - next[pc] = c; - return c; -} - -static void -hdecblock(Decode *dec, ulong n, ulong I, uchar *buf, ulong *sums, ulong *prev) -{ - ulong i, nn, sum; - int m, z, zz, c; - - nn = I; - n--; - i = 0; -again: - for(; i < nn; i++){ - while((m = hdec(dec)) == 0 && i + dec->nzero < n) - ; - if(z = dec->nzero){ - dec->nzero = 0; - c = dec->mtf.comb[0]; - sum = sums[c]; - sums[c] = sum + z; - - z += i; - zz = z; - if(i < I && z > I){ - zz = I; - z++; - } - - zagain: - for(; i < zz; i++){ - buf[i] = c; - prev[i] = sum++; - } - if(i != z){ - zz = z; - nn = ++n; - i++; - goto zagain; - } - if(i == nn){ - if(i == n) - return; - nn = ++n; - i++; - } - } - - c = mtflist(&dec->mtf, m); - - buf[i] = c; - sum = sums[c]; - prev[i] = sum++; - sums[c] = sum; - - } - if(i == n) - return; - nn = ++n; - i++; - goto again; -} - -int -unsac(uchar *dst, uchar *src, int n, int nsrc) -{ - Decode *dec; - uchar *buf, *front; - ulong *prev, *sums; - ulong sum, i, I; - int m, j, c; - - dec = malloc(sizeof *dec); - buf = malloc(n+2); - prev = malloc((n+2) * sizeof *prev); - front = malloc(MaxLit * sizeof *front); - sums = malloc(MaxLit * sizeof *sums); - - if(waserror()){ - free(dec); - free(buf); - free(prev); - free(front); - free(sums); - nexterror(); - } - - dec->src = src; - dec->smax = src + nsrc; - - dec->nbits = 0; - dec->bits = 0; - dec->nzero = 0; - for(i = 0; i < MaxLit; i++) - front[i] = i; - - n++; - I = bitget(dec, 16); - if(I >= n) - fatal(dec, "corrupted input"); - - /* - * decode the character usage map - */ - for(i = 0; i < MaxLit; i++) - sums[i] = 0; - c = bitget(dec, 1); - for(i = 0; i < MaxLit; ){ - m = bitget(dec, 8) + 1; - while(m--){ - if(i >= MaxLit) - fatal(dec, "corrupted char map"); - front[i++] = c; - } - c = c ^ 1; - } - - /* - * initialize mtf state - */ - c = 0; - for(i = 0; i < MaxLit; i++) - if(front[i]) - front[c++] = i; - mtflistinit(&dec->mtf, front, c); - dec->maxblocksym = c + LitBase; - - /* - * huffman decoding, move to front decoding, - * along with character counting - */ - dec->base = 1; - recvtab(dec, &dec->tab, MaxLeaf, nil); - hdecblock(dec, n, I, buf, sums, prev); - - sum = 1; - for(i = 0; i < MaxLit; i++){ - c = sums[i]; - sums[i] = sum; - sum += c; - } - - i = 0; - for(j = n - 2; j >= 0; j--){ - if(i > n || i < 0 || i == I) - fatal(dec, "corrupted data"); - c = buf[i]; - dst[j] = c; - i = prev[i] + sums[c]; - } - - poperror(); - - free(dec); - free(buf); - free(prev); - free(front); - free(sums); - return n; -} - -static ulong -bitget(Decode *dec, int nb) -{ - int c; - - while(dec->nbits < nb){ - if(dec->src >= dec->smax) - fatal(dec, "premature eof 1"); - c = *dec->src++; - dec->bits <<= 8; - dec->bits |= c; - dec->nbits += 8; - } - dec->nbits -= nb; - return (dec->bits >> dec->nbits) & ((1 << nb) - 1); -} - -static void -fillbits(Decode *dec) -{ - int c; - - while(dec->nbits < 24){ - if(dec->src >= dec->smax) - fatal(dec, "premature eof 2"); - c = *dec->src++; - dec->bits <<= 8; - dec->bits |= c; - dec->nbits += 8; - } -} - -/* - * decode one symbol - */ -static int -hdecsym(Decode *dec, Huff *h, int b) -{ - long c; - ulong bits; - int nbits; - - bits = dec->bits; - nbits = dec->nbits; - for(; (c = bits >> (nbits - b)) > h->maxcode[b]; b++) - ; - if(b > h->maxbits) - fatal(dec, "too many bits consumed"); - dec->nbits = nbits - b; - return h->decode[h->last[b] - c]; -} - -static int -hdec(Decode *dec) -{ - ulong c; - int nbits, nb; - - if(dec->nbits < dec->tab.maxbits) - fillbits(dec); - nbits = dec->nbits; - dec->bits &= (1 << nbits) - 1; - c = dec->tab.flat[dec->bits >> (nbits - dec->tab.flatbits)]; - nb = c & 0xff; - c >>= 8; - if(nb == 0xff) - c = hdecsym(dec, &dec->tab, c); - else - dec->nbits = nbits - nb; - - /* - * reverse funny run-length coding - */ - if(c < ZBase){ - dec->nzero += dec->base << c; - dec->base <<= 1; - return 0; - } - - dec->base = 1; - c -= LitBase; - return c; -} - -static void -hufftab(Decode *dec, Huff *h, char *hb, ulong *bitcount, int maxleaf, int maxbits, int flatbits) -{ - ulong c, mincode, code, nc[MaxHuffBits]; - int i, b, ec; - - h->maxbits = maxbits; - if(maxbits < 0) - return; - - code = 0; - c = 0; - for(b = 0; b <= maxbits; b++){ - h->last[b] = c; - c += bitcount[b]; - mincode = code << 1; - nc[b] = mincode; - code = mincode + bitcount[b]; - if(code > (1 << b)) - fatal(dec, "corrupted huffman table"); - h->maxcode[b] = code - 1; - h->last[b] += code - 1; - } - if(code != (1 << maxbits)) - fatal(dec, "huffman table not full"); - if(flatbits > maxbits) - flatbits = maxbits; - h->flatbits = flatbits; - - b = 1 << flatbits; - for(i = 0; i < b; i++) - h->flat[i] = ~0; - - /* - * initialize the flat table to include the minimum possible - * bit length for each code prefix - */ - for(b = maxbits; b > flatbits; b--){ - code = h->maxcode[b]; - if(code == -1) - break; - mincode = code + 1 - bitcount[b]; - mincode >>= b - flatbits; - code >>= b - flatbits; - for(; mincode <= code; mincode++) - h->flat[mincode] = (b << 8) | 0xff; - } - - for(i = 0; i < maxleaf; i++){ - b = hb[i]; - if(b == -1) - continue; - c = nc[b]++; - if(b <= flatbits){ - code = (i << 8) | b; - ec = (c + 1) << (flatbits - b); - if(ec > (1<flat[c] = code; - }else{ - c = h->last[b] - c; - if(c >= maxleaf) - fatal(dec, "corrupted huffman table"); - h->decode[c] = i; - } - } -} - -static void -elimBit(int b, char *tmtf, int maxbits) -{ - int bb; - - for(bb = 0; bb < maxbits; bb++) - if(tmtf[bb] == b) - break; - while(++bb <= maxbits) - tmtf[bb - 1] = tmtf[bb]; -} - -static int -elimBits(int b, ulong *bused, char *tmtf, int maxbits) -{ - int bb, elim; - - if(b < 0) - return 0; - - elim = 0; - - /* - * increase bits counts for all descendants - */ - for(bb = b + 1; bb < maxbits; bb++){ - bused[bb] += 1 << (bb - b); - if(bused[bb] == (1 << bb)){ - elim++; - elimBit(bb, tmtf, maxbits); - } - } - - /* - * steal bits from parent & check for fullness - */ - for(; b >= 0; b--){ - bused[b]++; - if(bused[b] == (1 << b)){ - elim++; - elimBit(b, tmtf, maxbits); - } - if((bused[b] & 1) == 0) - break; - } - return elim; -} - -static void -recvtab(Decode *dec, Huff *tab, int maxleaf, ushort *map) -{ - ulong bitcount[MaxHuffBits+1], bused[MaxHuffBits+1]; - char tmtf[MaxHuffBits+1], *hb; - int i, b, ttb, m, maxbits, max, elim; - - hb = malloc(MaxLeaf * sizeof *hb); - if(waserror()) { - free(hb); - nexterror(); - } - - /* - * read the tables for the tables - */ - max = 8; - for(i = 0; i <= MaxHuffBits; i++){ - bitcount[i] = 0; - tmtf[i] = i; - bused[i] = 0; - } - tmtf[0] = -1; - tmtf[max] = 0; - elim = 0; - maxbits = -1; - for(i = 0; i <= MaxHuffBits && elim != max; i++){ - ttb = 4; - while(max - elim < (1 << (ttb-1))) - ttb--; - b = bitget(dec, ttb); - if(b > max - elim) - fatal(dec, "corrupted huffman table table"); - b = tmtf[b]; - hb[i] = b; - bitcount[b]++; - if(b > maxbits) - maxbits = b; - - elim += elimBits(b, bused, tmtf, max); - } - if(elim != max) - fatal(dec, "incomplete huffman table table"); - hufftab(dec, tab, hb, bitcount, i, maxbits, MaxFlatbits); - for(i = 0; i <= MaxHuffBits; i++){ - tmtf[i] = i; - bitcount[i] = 0; - bused[i] = 0; - } - tmtf[0] = -1; - tmtf[MaxHuffBits] = 0; - elim = 0; - maxbits = -1; - for(i = 0; i < maxleaf && elim != MaxHuffBits; i++){ - if(dec->nbits <= tab->maxbits) - fillbits(dec); - dec->bits &= (1 << dec->nbits) - 1; - m = tab->flat[dec->bits >> (dec->nbits - tab->flatbits)]; - b = m & 0xff; - m >>= 8; - if(b == 0xff) - m = hdecsym(dec, tab, m); - else - dec->nbits -= b; - b = tmtf[m]; - for(; m > 0; m--) - tmtf[m] = tmtf[m-1]; - tmtf[0] = b; - - if(b > MaxHuffBits) - fatal(dec, "bit length too big"); - m = i; - if(map != nil) - m = map[m]; - hb[m] = b; - bitcount[b]++; - if(b > maxbits) - maxbits = b; - elim += elimBits(b, bused, tmtf, MaxHuffBits); - } - if(elim != MaxHuffBits && elim != 0) - fatal(dec, "incomplete huffman table"); - if(map != nil) - for(; i < maxleaf; i++) - hb[map[i]] = -1; - - hufftab(dec, tab, hb, bitcount, i, maxbits, MaxFlatbits); - - poperror(); - free(hb); -} - -static void -fatal(Decode *dec, char *msg) -{ - USED(dec); -print("unsac: %s\n", msg); - error(msg); -} diff --git a/pc/cga.c b/pc/cga.c index c1ffa0275e85daa8ab3eac9bd27ea82d79fcdbac..6365d44cca767fe5dad4046b19424ce0825c8b42 100644 --- a/pc/cga.c +++ b/pc/cga.c @@ -34,7 +34,6 @@ enum { #define CGASCREENBASE ((uchar*)KADDR(0xB8000)) static int cgapos; -static int screeninitdone; static Lock cgascreenlock; static uchar @@ -96,15 +95,6 @@ cgascreenputc(int c) movecursor(); } -void -screeninit(void) -{ - cgapos = cgaregr(0x0E)<<8; - cgapos |= cgaregr(0x0F); - cgapos *= 2; - screeninitdone = 1; -} - static void cgascreenputs(char* s, int n) { @@ -125,4 +115,13 @@ cgascreenputs(char* s, int n) unlock(&cgascreenlock); } -void (*screenputs)(char*, int) = cgascreenputs; +void +screeninit(void) +{ + + cgapos = cgaregr(0x0E)<<8; + cgapos |= cgaregr(0x0F); + cgapos *= 2; + + screenputs = cgascreenputs; +} diff --git a/pc/dat.h b/pc/dat.h index 01220b8380214651b9675f5e1cc80dc3b8f5da41..e4aff19140870d065b93c49b8ea4924273edd062 100644 --- a/pc/dat.h +++ b/pc/dat.h @@ -82,6 +82,7 @@ struct Conf ulong copymode; /* 0 is copy on write, 1 is copy on reference */ ulong ialloc; /* max interrupt time allocation in bytes */ ulong pipeqsize; /* size in bytes of pipe queues */ + int nuart; /* number of uart devices */ }; /* @@ -246,11 +247,10 @@ struct PCArch /* * a parsed plan9.ini line */ -#define ISAOPTLEN 28 #define NISAOPT 8 struct ISAConf { - char type[NAMELEN]; + char *type; ulong port; ulong irq; ulong dma; @@ -259,7 +259,7 @@ struct ISAConf { ulong freq; int nopt; - char opt[NISAOPT][ISAOPTLEN]; + char *opt[NISAOPT]; }; extern PCArch *arch; /* PC architecture */ diff --git a/pc/devarch.c b/pc/devarch.c index 04c0bd13a1f6ae1195939c82b54ffab9b62eb4d8..2f1e99f1d8bd231808db463c4ec50b0993ab0e33 100644 --- a/pc/devarch.c +++ b/pc/devarch.c @@ -27,8 +27,8 @@ static struct } iomap; enum { - Qdir = CHDIR, - Qioalloc = 0, + Qdir = 0, + Qioalloc = 1, Qiob, Qiow, Qiol, @@ -43,6 +43,7 @@ static Rdwrfn *readfn[Qmax]; static Rdwrfn *writefn[Qmax]; static Dirtab archdir[Qmax] = { + ".", { Qdir, 0, QTDIR }, 0, 0555, "ioalloc", { Qioalloc, 0 }, 0, 0444, "iob", { Qiob, 0 }, 0, 0660, "iow", { Qiow, 0 }, 0, 0660, @@ -223,16 +224,16 @@ archattach(char* spec) return devattach('P', spec); } -int -archwalk(Chan* c, char* name) +Walkqid* +archwalk(Chan* c, Chan *nc, char** name, int nname) { - return devwalk(c, name, archdir, narchdir, devgen); + return devwalk(c, nc, name, nname, archdir, narchdir, devgen); } -static void -archstat(Chan* c, char* dp) +static int +archstat(Chan* c, uchar* dp, int n) { - devstat(c, dp, archdir, narchdir, devgen); + return devstat(c, dp, n, archdir, narchdir, devgen); } static Chan* @@ -261,7 +262,7 @@ archread(Chan *c, void *a, long n, vlong offset) IOMap *m; Rdwrfn *fn; - switch(c->qid.path){ + switch((ulong)c->qid.path){ case Qdir: return devdirread(c, a, n, archdir, narchdir, devgen); @@ -331,7 +332,7 @@ archwrite(Chan *c, void *a, long n, vlong offset) ulong *lp; Rdwrfn *fn; - switch(c->qid.path & ~CHDIR){ + switch((ulong)c->qid.path){ case Qiob: p = a; @@ -376,7 +377,6 @@ Dev archdevtab = { devreset, devinit, archattach, - devclone, archwalk, archstat, archopen, diff --git a/pc/devastar.c b/pc/devastar.c index f7129638cacd1cf91222a77dafcc4b8c912310fd..9a18277c0f2647ababaeb4fb4f9679cf639473f4 100644 --- a/pc/devastar.c +++ b/pc/devastar.c @@ -679,12 +679,17 @@ astarclose(Chan *c) case Qctl: ac = a->c + CHAN(c->qid.path); qlock(ac); + if(waserror()){ + qunlock(ac); + nexterror(); + } if(--(ac->opens) == 0){ disable(ac); qclose(ac->iq); qclose(ac->oq); } qunlock(ac); + poperror(); break; } } diff --git a/pc/devether.c b/pc/devether.c index 7a04a23c37be61c0af9c3fc4cd5c500c24c9b3a4..a522dc8d14ac2503a2f7a38c28bc5c937c2c2f86 100644 --- a/pc/devether.c +++ b/pc/devether.c @@ -35,16 +35,16 @@ etherattach(char* spec) return chan; } -static int -etherwalk(Chan* chan, char* name) +static Walkqid* +etherwalk(Chan* chan, Chan* nchan, char** name, int nname) { - return netifwalk(etherxx[chan->dev], chan, name); + return netifwalk(etherxx[chan->dev], chan, nchan, name, nname); } -static void -etherstat(Chan* chan, char* dp) +static int +etherstat(Chan* chan, uchar* dp, int n) { - netifstat(etherxx[chan->dev], chan, dp); + return netifstat(etherxx[chan->dev], chan, dp, n); } static Chan* @@ -71,7 +71,7 @@ etherread(Chan* chan, void* buf, long n, vlong off) ulong offset = off; ether = etherxx[chan->dev]; - if((chan->qid.path & CHDIR) == 0 && ether->ifstat){ + if((chan->qid.type & QTDIR) == 0 && ether->ifstat){ /* * With some controllers it is necessary to reach * into the chip to extract statistics. @@ -96,18 +96,17 @@ etherremove(Chan*) { } -static void -etherwstat(Chan* chan, char* dp) +static int +etherwstat(Chan* chan, uchar* dp, int n) { - netifwstat(etherxx[chan->dev], chan, dp); + return netifwstat(etherxx[chan->dev], chan, dp, n); } static void etherrtrace(Netfile* f, Etherpkt* pkt, int len) { - int n; + int i, n; Block *bp; - uvlong ts; if(qwindow(f->in) <= 0) return; @@ -115,22 +114,18 @@ etherrtrace(Netfile* f, Etherpkt* pkt, int len) n = 58; else n = len; - bp = iallocb(68); + bp = iallocb(64); if(bp == nil) return; memmove(bp->wp, pkt->d, n); - ts = fastticks(nil); + i = TK2MS(MACHP(0)->ticks); bp->wp[58] = len>>8; bp->wp[59] = len; - bp->wp[60] = ts>>56; - bp->wp[61] = ts>>48; - bp->wp[62] = ts>>40; - bp->wp[63] = ts>>32; - bp->wp[64] = ts>>24; - bp->wp[65] = ts>>16; - bp->wp[66] = ts>>8; - bp->wp[67] = ts; - bp->wp += 68; + bp->wp[60] = i>>24; + bp->wp[61] = i>>16; + bp->wp[62] = i>>8; + bp->wp[63] = i; + bp->wp += 64; qpass(f->in, bp); } @@ -248,7 +243,7 @@ static long etherwrite(Chan* chan, void* buf, long n, vlong) { Ether *ether; - Block *volatile bp; + Block *bp; int nn; ether = etherxx[chan->dev]; @@ -357,7 +352,7 @@ etherreset(void) { Ether *ether; int i, n, ctlrno; - char name[NAMELEN], buf[128]; + char name[32], buf[128]; for(ether = 0, ctlrno = 0; ctlrno < MaxEther; ctlrno++){ if(ether == 0) @@ -461,7 +456,6 @@ Dev etherdevtab = { etherreset, devinit, etherattach, - devclone, etherwalk, etherstat, etheropen, diff --git a/pc/devfloppy.c b/pc/devfloppy.c index 132deaa5f53eebbd5d9bc64f543a47c2b4cb955e..905e840c5e8213aa8e062377e57405aa2011e955 100644 --- a/pc/devfloppy.c +++ b/pc/devfloppy.c @@ -104,6 +104,7 @@ static void floppywait(int); static long floppyxfer(FDrive*, int, void*, long, long); Dirtab floppydir[]={ + ".", {Qdir, 0, QTDIR}, 0, 0550, "fd0disk", {Qdata + 0}, 0, 0660, "fd0ctl", {Qctl + 0}, 0, 0660, "fd1disk", {Qdata + 1}, 0, 0660, @@ -216,16 +217,16 @@ floppyattach(char *spec) return devattach('f', spec); } -static int -floppywalk(Chan *c, char *name) +static Walkqid* +floppywalk(Chan *c, Chan *nc, char **name, int nname) { - return devwalk(c, name, floppydir, fl.ndrive*NFDIR, devgen); + return devwalk(c, nc, name, nname, floppydir, fl.ndrive*NFDIR, devgen); } -static void -floppystat(Chan *c, char *dp) +static int +floppystat(Chan *c, uchar *dp, int n) { - devstat(c, dp, floppydir, fl.ndrive*NFDIR, devgen); + return devstat(c, dp, n, floppydir, fl.ndrive*NFDIR, devgen); } static Chan* @@ -351,7 +352,7 @@ floppyread(Chan *c, void *a, long n, vlong off) uchar *aa; ulong offset = off; - if(c->qid.path == CHDIR) + if(c->qid.type & QTDIR) return devdirread(c, a, n, floppydir, fl.ndrive*NFDIR, devgen); rv = 0; @@ -1035,7 +1036,6 @@ Dev floppydevtab = { floppyreset, devinit, floppyattach, - devclone, floppywalk, floppystat, floppyopen, diff --git a/pc/devi82365.c b/pc/devi82365.c index 2d08091849fac8c57df880c4a947d18516ec2aab..bf0a32334148c45b76274d88d85b706c65ee1b41 100644 --- a/pc/devi82365.c +++ b/pc/devi82365.c @@ -294,7 +294,7 @@ pcmmap(int slotno, ulong offset, int len, int attr) } m->isa = PADDR(umbmalloc(0, len, Mgran)); if(m->isa == 0){ - print("pcmmap: %d out of isa space\n", len); + print("pcmmap: out of isa space\n"); unlock(&pp->mlock); return 0; } @@ -419,21 +419,21 @@ enum Nents = 3, }; -#define SLOTNO(c) ((c->qid.path>>8)&0xff) -#define TYPE(c) (c->qid.path&0xff) +#define SLOTNO(c) ((ulong)((c->qid.path>>8)&0xff)) +#define TYPE(c) ((ulong)(c->qid.path&0xff)) #define QID(s,t) (((s)<<8)|(t)) static int -pcmgen(Chan *c, Dirtab *, int , int i, Dir *dp) +pcmgen(Chan *c, char*, Dirtab *, int , int i, Dir *dp) { int slotno; Qid qid; long len; PCMslot *pp; - char name[NAMELEN]; if(i == DEVDOTDOT){ - devdir(c, (Qid){CHDIR, 0}, "#y", 0, eve, 0555, dp); + mkqid(&qid, Qdir, 0, QTDIR); + devdir(c, qid, "#y", 0, eve, 0555, dp); return 1; } @@ -445,21 +445,21 @@ pcmgen(Chan *c, Dirtab *, int , int i, Dir *dp) switch(i%Nents){ case 0: qid.path = QID(slotno, Qmem); - sprint(name, "pcm%dmem", slotno); + snprint(up->genbuf, sizeof up->genbuf, "pcm%dmem", slotno); len = pp->memlen; break; case 1: qid.path = QID(slotno, Qattr); - sprint(name, "pcm%dattr", slotno); + snprint(up->genbuf, sizeof up->genbuf, "pcm%dattr", slotno); len = pp->memlen; break; case 2: qid.path = QID(slotno, Qctl); - sprint(name, "pcm%dctl", slotno); + snprint(up->genbuf, sizeof up->genbuf, "pcm%dctl", slotno); break; } qid.vers = 0; - devdir(c, qid, name, len, eve, 0660, dp); + devdir(c, qid, up->genbuf, len, eve, 0660, dp); return 1; } @@ -584,7 +584,7 @@ i82365reset(void) int i, j; I82365 *cp; PCMslot *pp; - char buf[NAMELEN]; + char buf[32]; if(already) return; @@ -630,7 +630,7 @@ i82365reset(void) } /* for card management interrupts */ - sprint(buf, "i82365.%d", i); + snprint(buf, sizeof buf, "i82365.%d", i); intrenable(cp->irq, i82365intr, 0, BUSUNKNOWN, buf); } } @@ -641,22 +641,22 @@ i82365attach(char *spec) return devattach('y', spec); } -static int -i82365walk(Chan *c, char *name) +static Walkqid* +i82365walk(Chan *c, Chan *nc, char **name, int nname) { - return devwalk(c, name, 0, 0, pcmgen); + return devwalk(c, nc, name, nname, 0, 0, pcmgen); } -static void -i82365stat(Chan *c, char *db) +static int +i82365stat(Chan *c, uchar *db, int n) { - devstat(c, db, 0, 0, pcmgen); + return devstat(c, db, n, 0, 0, pcmgen); } static Chan* i82365open(Chan *c, int omode) { - if(c->qid.path == CHDIR){ + if(c->qid.type & QTDIR){ if(omode != OREAD) error(Eperm); } else @@ -671,7 +671,7 @@ static void i82365close(Chan *c) { if(c->flag & COPEN) - if(c->qid.path != CHDIR) + if((c->qid.type & QTDIR) == 0) decrefp(slot+SLOTNO(c)); } @@ -869,7 +869,6 @@ Dev i82365devtab = { i82365reset, devinit, i82365attach, - devclone, i82365walk, i82365stat, i82365open, diff --git a/pc/devlml.c b/pc/devlml.c index 647bade18160d237593532ed9b9d4d04ae589f3c..0d604c0c77a1ab08fed826441d32020a442f16e0 100644 --- a/pc/devlml.c +++ b/pc/devlml.c @@ -17,7 +17,7 @@ static Pcidev * pcidev; #define DBGINTR 0x04 #define DBGINTS 0x08 -int debug = 0; +int debug = -1; // Lml 22 driver diff --git a/pc/devlpt.c b/pc/devlpt.c index 817dd1f4229cde99ee6f101e9df72b068903b663..febb8eb366fbce8c44e6d82dd65008f080f9afe5 100644 --- a/pc/devlpt.c +++ b/pc/devlpt.c @@ -20,6 +20,7 @@ static int lptallocd[NDEV]; /* offsets, and bits in the registers */ enum { + Qdir= 0x8000, /* data latch register */ Qdlr= 0x0, /* printer status register */ @@ -47,32 +48,34 @@ static void lptintr(Ureg*, void*); static Rendez lptrendez; Dirtab lptdir[]={ - "dlr", {Qdlr}, 1, 0666, - "psr", {Qpsr}, 5, 0444, - "pcr", {Qpcr}, 0, 0222, - "data", {Qdata}, 0, 0222, + ".", {Qdir, 0, QTDIR}, 0, DMDIR|0555, + "dlr", {Qdlr}, 1, 0666, + "psr", {Qpsr}, 5, 0444, + "pcr", {Qpcr}, 0, 0222, + "data", {Qdata}, 0, 0222, }; static int -lptgen(Chan *c, Dirtab *tab, int ntab, int i, Dir *dp) +lptgen(Chan *c, char*, Dirtab *tab, int ntab, int i, Dir *dp) { Qid qid; - char name[NAMELEN]; if(i == DEVDOTDOT){ - sprint(name, "#L%lud", c->dev+1); - devdir(c, (Qid){CHDIR, 0}, name, 0, eve, 0555, dp); + mkqid(&qid, Qdir, 0, QTDIR); + devdir(c, qid, ".", 0, eve, 0555, dp); return 1; } + i++; /* skip first element for . itself */ if(tab==0 || i>=ntab) return -1; tab += i; qid = tab->qid; + qid.path &= ~Qdir; if(qid.path < Qdata) qid.path += lptbase[c->dev]; qid.vers = c->dev; - sprint(name, "lpt%lud%s", c->dev+1, tab->name); - devdir(c, qid, name, tab->length, eve, tab->perm, dp); + sprint(up->genbuf, "lpt%lud%s", c->dev+1, tab->name); + devdir(c, qid, up->genbuf, tab->length, eve, tab->perm, dp); return 1; } @@ -109,20 +112,21 @@ lptattach(char *spec) } } c = devattach('L', spec); + c->qid.path = Qdir; c->dev = i-1; return c; } -static int -lptwalk(Chan *c, char *name) +static Walkqid* +lptwalk(Chan *c, Chan *nc, char **name, int nname) { - return devwalk(c, name, lptdir, nelem(lptdir), lptgen); + return devwalk(c, nc, name, nname, lptdir, nelem(lptdir), lptgen); } -static void -lptstat(Chan *c, char *dp) +static int +lptstat(Chan *c, uchar *dp, int n) { - devstat(c, dp, lptdir, nelem(lptdir), lptgen); + return devstat(c, dp, n, lptdir, nelem(lptdir), lptgen); } static Chan* @@ -143,7 +147,7 @@ lptread(Chan *c, void *a, long n, vlong) int size; ulong o; - if(c->qid.path == CHDIR) + if(c->qid.path == Qdir) return devdirread(c, a, n, lptdir, nelem(lptdir), lptgen); size = sprint(str, "0x%2.2ux\n", inb(c->qid.path)); o = c->offset; @@ -226,7 +230,6 @@ Dev lptdevtab = { devreset, devinit, lptattach, - devclone, lptwalk, lptstat, lptopen, diff --git a/pc/devrtc.c b/pc/devrtc.c index 14fc598c18d60d1e5547cb4a2de3d998de6c310d..205932a33cb4232f8aa76fbcb1bcf7c4e113d728 100644 --- a/pc/devrtc.c +++ b/pc/devrtc.c @@ -40,11 +40,13 @@ struct Rtc enum{ - Qrtc = 1, + Qdir = 0, + Qrtc, Qnvram, }; Dirtab rtcdir[]={ + ".", {Qdir, 0, QTDIR}, 0, 0555, "nvram", {Qnvram, 0}, Nvsize, 0664, "rtc", {Qrtc, 0}, 0, 0664, }; @@ -65,23 +67,23 @@ rtcattach(char* spec) return devattach('r', spec); } -static int -rtcwalk(Chan* c, char* name) +static Walkqid* +rtcwalk(Chan* c, Chan *nc, char** name, int nname) { - return devwalk(c, name, rtcdir, nelem(rtcdir), devgen); + return devwalk(c, nc, name, nname, rtcdir, nelem(rtcdir), devgen); } -static void -rtcstat(Chan* c, char* dp) +static int +rtcstat(Chan* c, uchar* dp, int n) { - devstat(c, dp, rtcdir, nelem(rtcdir), devgen); + return devstat(c, dp, n, rtcdir, nelem(rtcdir), devgen); } static Chan* rtcopen(Chan* c, int omode) { omode = openmode(omode); - switch(c->qid.path){ + switch((ulong)c->qid.path){ case Qrtc: if(strcmp(up->user, eve)!=0 && omode!=OREAD) error(Eperm); @@ -178,10 +180,10 @@ rtcread(Chan* c, void* buf, long n, vlong off) char *a, *start; ulong offset = off; - if(c->qid.path & CHDIR) + if(c->qid.type & QTDIR) return devdirread(c, buf, n, rtcdir, nelem(rtcdir), devgen); - switch(c->qid.path){ + switch((ulong)c->qid.path){ case Qrtc: t = rtctime(); n = readnum(offset, buf, n, t, 12); @@ -233,7 +235,7 @@ rtcwrite(Chan* c, void* buf, long n, vlong off) error(Ebadarg); - switch(c->qid.path){ + switch((ulong)c->qid.path){ case Qrtc: /* * read the time @@ -307,7 +309,6 @@ Dev rtcdevtab = { devreset, rtcinit, rtcattach, - devclone, rtcwalk, rtcstat, rtcopen, diff --git a/pc/devusb.c b/pc/devusb.c index 07319191bbada0e702a74438171e13d029b50819..20cb14c6faa5a69bfb1f7cf5b53e8eb70d607d1f 100644 --- a/pc/devusb.c +++ b/pc/devusb.c @@ -718,8 +718,8 @@ qrcv(Endpt *e) QH *qh; int vf; - b = allocb(e->maxpkt); t = alloctde(e, TokIN, e->maxpkt); + b = allocb(e->maxpkt); t->bp = b; t->buffer = PADDR(b->wp); ub = &ubus; @@ -734,6 +734,21 @@ qrcv(Endpt *e) return qh; } +static Block * +usbreq(int type, int req, int value, int offset, int count) +{ + Block *b; + + b = allocb(8); + b->wp[0] = type; + b->wp[1] = req; + PUT2(b->wp+2, value); + PUT2(b->wp+4, offset); + PUT2(b->wp+6, count); + b->wp += 8; + return b; +} + /* * return smallest power of 2 >= n */ @@ -816,14 +831,14 @@ dumpframe(int f, int t) if(t < 0) t = 32; for(i=f; ihead); + XPRINT("F%.2d %8.8lux %8.8lux\n", i, frame[i], QFOL(frame[i])->head); for(p=frame[i]; (p & IsQH) && (p &Terminate) == 0; p = q->head){ q = QFOL(p); if(!(q >= tree && q < &tree[n])){ - pprint("Q: p=%8.8lux out of range\n", p); + XPRINT("Q: p=%8.8lux out of range\n", p); break; } - pprint(" -> %8.8lux h=%8.8lux e=%8.8lux\n", p, q->head, q->entries); + XPRINT(" -> %8.8lux h=%8.8lux e=%8.8lux\n", p, q->head, q->entries); } } } @@ -1182,7 +1197,7 @@ usbdevice(Chan *c) d = usbdeviceofpath(c->qid.path); if(d == nil || d->id != c->qid.vers || d->state == Disabled) - return nil; + error(Ehungup); return d; } @@ -1223,36 +1238,29 @@ static void usbreset(void) { Pcidev *cfg; - int i, port; + int i; + ulong port; QTree *qt; TD *t; Ctlr *ub; ub = &ubus; - for(cfg = pcimatch(nil, 0, 0); cfg != nil; cfg = pcimatch(cfg, 0, 0)){ - /* - * Look for devices with the correct class and - * sub-class code and known device and vendor ID. - */ - if(cfg->ccrb != 0x0C || cfg->ccru != 0x03) - continue; - switch((cfg->did<<16)|cfg->vid){ - default: - continue; - case (0x7112<<16)|0x8086: /* 82371[AE]B (PIIX4[E]) */ - case (0x719A<<16)|0x8086: /* 82443MX */ - case (0x1106<<16)|0x0586: /* VIA 82C586 */ - break; + memset(&cfg, 0, sizeof(cfg)); + cfg = pcimatch(0, 0x8086, 0x7112); /* Intel chipset PIIX 4*/ + if(cfg == nil) { + cfg = pcimatch(0, 0x1106, 0x0586); /* Via chipset */ + if(cfg == nil) { + DPRINT("No USB device found\n"); + return; } - if((cfg->mem[4].bar & ~0x0F) != 0) - break; } - if(cfg == nil) - return; - port = cfg->mem[4].bar & ~0x0F; + if (port == 0) { + print("usb: failed to map registers\n"); + return; + } - DPRINT("USB: %x/%x port 0x%ux size 0x%x irq %d\n", + DPRINT("USB: %x/%x port 0x%lux size 0x%x irq %d\n", cfg->vid, cfg->did, port, cfg->mem[4].size, cfg->intl); i = inb(port+SOFMod); @@ -1295,7 +1303,6 @@ usbreset(void) ub->bwsop = allocqh(ub); ub->bulkq = allocqh(ub); ub->recvq = allocqh(ub); -if(0){ t = alloctd(ub); /* inactive TD, looped */ t->link = PADDR(t); ub->bwsop->entries = PADDR(t); @@ -1303,7 +1310,6 @@ if(0){ ub->bwsop->head = PADDR(ub->bulkq) | IsQH; ub->bulkq->head = PADDR(ub->recvq) | IsQH; ub->recvq->head = PADDR(ub->bwsop) | IsQH; /* loop back */ -} XPRINT("usbcmd\t0x%.4x\nusbsts\t0x%.4x\nusbintr\t0x%.4x\nfrnum\t0x%.2x\n", IN(Cmd), IN(Status), IN(Usbintr), inb(port+Frnum)); XPRINT("frbaseadd\t0x%.4x\nsofmod\t0x%x\nportsc1\t0x%.4x\nportsc2\t0x%.4x\n", @@ -1500,8 +1506,6 @@ usbopen(Chan *c, int omode) switch(QID(c->qid)){ case Qctl: d = usbdevice(c); - if (d == nil) - error(Ehungup); if(0&&d->busy) error(Einuse); d->busy = 1; @@ -1511,8 +1515,6 @@ usbopen(Chan *c, int omode) default: d = usbdevice(c); - if (d == nil) - error(Ehungup); s = QID(c->qid) - Qep0; if(s >= 0 && s < nelem(d->ep)){ Endpt *e; @@ -1561,13 +1563,16 @@ usbclose(Chan *c) if(c->qid.path & CHDIR || c->qid.path < Q3rd) return; qlock(&usbstate); - d = usbdeviceofpath(c->qid.path); - if (d && d->id == c->qid.vers) { - if(QID(c->qid) == Qctl) - d->busy = 0; - if(c->flag & COPEN) - freedev(d); + if(waserror()){ + qunlock(&usbstate); + nexterror(); } + d = usbdevice(c); + if(QID(c->qid) == Qctl) + d->busy = 0; + if(c->flag & COPEN) + freedev(d); + poperror(); qunlock(&usbstate); } @@ -1658,15 +1663,11 @@ usbread(Chan *c, void *a, long n, vlong offset) case Qctl: d = usbdevice(c); - if (d == nil) - error(Ehungup); sprint(buf, "%11d %11d ", d->x, d->id); return readstr(offset, a, n, buf); case Qsetup: /* endpoint 0 */ d = usbdevice(c); - if (d == nil) - error(Ehungup); if((e = d->ep[0]) == nil) error(Eio); /* can't happen */ e->data01 = 1; @@ -1684,8 +1685,6 @@ usbread(Chan *c, void *a, long n, vlong offset) case Qstatus: d = usbdevice(c); - if (d == nil) - error(Ehungup); s = smalloc(READSTR); if(waserror()){ free(s); @@ -1702,8 +1701,6 @@ usbread(Chan *c, void *a, long n, vlong offset) default: d = usbdevice(c); - if (d == nil) - error(Ehungup); if((t -= Qep0) < 0 || t >= nelem(d->ep)) error(Eio); if((e = d->ep[t]) == nil || e->mode == OWRITE) @@ -1807,8 +1804,6 @@ usbwrite(Chan *c, void *a, long n, vlong) return n; } d = usbdevice(c); - if (d == nil) - error(Ehungup); t = QID(c->qid); switch(t){ case Qctl: diff --git a/pc/devvga.c b/pc/devvga.c index 381099c997bee73e45ca5e91b30366b6a796a5c2..1d2a760b7b852151be96c29fcd6d4857ca76f499 100644 --- a/pc/devvga.c +++ b/pc/devvga.c @@ -17,14 +17,11 @@ enum { Qdir, Qvgactl, - Qvgaovl, - Qvgaovlctl, }; static Dirtab vgadir[] = { - "vgactl", { Qvgactl, 0 }, 0, 0660, - "vgaovl", { Qvgaovl, 0 }, 0, 0660, - "vgaovlctl", { Qvgaovlctl, 0 }, 0, 0660, + ".", { Qdir, 0, QTDIR }, 0, 0550, + "vgactl", { Qvgactl, 0 }, 0, 0660, }; static void @@ -46,49 +43,27 @@ vgaattach(char* spec) return devattach('v', spec); } -int -vgawalk(Chan* c, char* name) +Walkqid* +vgawalk(Chan* c, Chan *nc, char** name, int nname) { - return devwalk(c, name, vgadir, nelem(vgadir), devgen); + return devwalk(c, nc, name, nname, vgadir, nelem(vgadir), devgen); } -static void -vgastat(Chan* c, char* dp) +static int +vgastat(Chan* c, uchar* dp, int n) { - devstat(c, dp, vgadir, nelem(vgadir), devgen); + return devstat(c, dp, n, vgadir, nelem(vgadir), devgen); } static Chan* vgaopen(Chan* c, int omode) { - VGAscr *scr; - static char *openctl = "openctl\n"; - - scr = &vgascreen[0]; - if ((c->qid.path & ~CHDIR) == Qvgaovlctl) { - if (scr->dev->ovlctl) - scr->dev->ovlctl(scr, c, openctl, strlen(openctl)); - else - error(Enonexist); - } return devopen(c, omode, vgadir, nelem(vgadir), devgen); } static void -vgaclose(Chan* c) -{ - VGAscr *scr; - static char *closectl = "closectl\n"; - - scr = &vgascreen[0]; - if ((c->qid.path & ~CHDIR) == Qvgaovlctl) { - if (scr->dev->ovlctl){ - if(waserror()) - return; - scr->dev->ovlctl(scr, c, closectl, strlen(closectl)); - poperror(); - } - } +vgaclose(Chan*) +{ } static void @@ -114,7 +89,7 @@ vgaread(Chan* c, void* a, long n, vlong off) ulong offset = off; char chbuf[30]; - switch(c->qid.path & ~CHDIR){ + switch((ulong)c->qid.path){ case Qdir: return devdirread(c, a, n, vgadir, nelem(vgadir), devgen); @@ -157,11 +132,6 @@ vgaread(Chan* c, void* a, long n, vlong off) return n; - case Qvgaovl: - case Qvgaovlctl: - error(Ebadusefd); - break; - default: error(Egreg); break; @@ -368,16 +338,13 @@ vgactl(char* a) error(Ebadarg); } -char Enooverlay[] = "No overlay support"; - static long vgawrite(Chan* c, void* a, long n, vlong off) { char *p; ulong offset = off; - VGAscr *scr; - switch(c->qid.path & ~CHDIR){ + switch((ulong)c->qid.path){ case Qdir: error(Eperm); @@ -397,23 +364,6 @@ vgawrite(Chan* c, void* a, long n, vlong off) free(p); return n; - case Qvgaovl: - scr = &vgascreen[0]; - if (scr->dev->ovlwrite == nil) { - error(Enooverlay); - break; - } - return scr->dev->ovlwrite(scr, a, n, off); - - case Qvgaovlctl: - scr = &vgascreen[0]; - if (scr->dev->ovlctl == nil) { - error(Enooverlay); - break; - } - scr->dev->ovlctl(scr, c, a, n); - return n; - default: error(Egreg); break; @@ -429,7 +379,6 @@ Dev vgadevtab = { vgareset, devinit, vgaattach, - devclone, vgawalk, vgastat, vgaopen, diff --git a/pc/ether2114x.c b/pc/ether2114x.c index d6a3a4674c6946f7d246ae8271ee5b1fdfd858d1..4b798166a634084f305de25a365e79f20658ca31 100644 --- a/pc/ether2114x.c +++ b/pc/ether2114x.c @@ -578,7 +578,7 @@ ctlrinit(Ether* ether) for(des = ctlr->rdr; des < &ctlr->rdr[ctlr->nrdr]; des++){ des->bp = iallocb(Rbsz); if(des->bp == nil) - panic("can't allocate ethernet receive ring"); + panic("can't allocate ethernet receive ring\n"); des->status = Own; des->control = Rbsz; des->addr = PADDR(des->bp->rp); @@ -611,7 +611,7 @@ ctlrinit(Ether* ether) } bp = iallocb(Eaddrlen*2*16); if(bp == nil) - panic("can't allocate ethernet setup buffer"); + panic("can't allocate ethernet setup buffer\n"); memset(bp->rp, 0xFF, sizeof(bi)); for(i = sizeof(bi); i < sizeof(bi)*16; i += sizeof(bi)) memmove(bp->rp+i, bi, sizeof(bi)); diff --git a/pc/ether79c970.c b/pc/ether79c970.c index d309f14af95eebec6f9a9643af459245e3cb9e43..083b35b51ef7a395e14c58b96b11382b56389e1e 100644 --- a/pc/ether79c970.c +++ b/pc/ether79c970.c @@ -209,6 +209,8 @@ ringinit(Ctlr* ctlr) ctlr->rdr = xspanalloc(Nrdre*sizeof(Dre), 0x10, 0); for(dre = ctlr->rdr; dre < &ctlr->rdr[Nrdre]; dre++){ dre->bp = iallocb(Rbsize); + if(dre->bp == nil) + panic("can't allocate ethernet receive ring\n"); dre->addr = PADDR(dre->bp->rp); dre->md2 = 0; dre->md1 = Own|(-Rbsize & 0xFFFF); @@ -424,15 +426,15 @@ typedef struct Adapter { } Adapter; static Block* adapter; -static void +static int amd79c970adapter(Block** bpp, int port, int irq, int tbdf) { Block *bp; Adapter *ap; - bp = iallocb(sizeof(Adapter)); + bp = allocb(sizeof(Adapter)); if(bp == nil) - return; + return -1; ap = (Adapter*)bp->rp; ap->port = port; ap->irq = irq; @@ -440,6 +442,8 @@ amd79c970adapter(Block** bpp, int port, int irq, int tbdf) bp->next = *bpp; *bpp = bp; + + return 0; } static void @@ -455,7 +459,10 @@ amd79c970pci(void) print("amd79c970: port 0x%uX in use\n", port); continue; } - amd79c970adapter(&adapter, port, p->intl, p->tbdf); + if(amd79c970adapter(&adapter, port, p->intl, p->tbdf)){ + iofree(port); + continue; + } pcisetbme(p); } } diff --git a/pc/ether82557.c b/pc/ether82557.c index edd0276e8ea5e678b31d5bed4410034872183c99..fae45bc3ba2ea7f1600861b94f3bcfe262c81fbf 100644 --- a/pc/ether82557.c +++ b/pc/ether82557.c @@ -363,7 +363,7 @@ static void attach(Ether* ether) { Ctlr *ctlr; - char name[NAMELEN]; + char name[KNAMELEN]; ctlr = ether->ctlr; lock(&ctlr->slock); @@ -380,7 +380,7 @@ attach(Ether* ether) * omitted. */ if((ctlr->eeprom[0x03] & 0x0003) != 0x0003){ - snprint(name, NAMELEN, "#l%dwatchdog", ether->ctlrno); + snprint(name, KNAMELEN, "#l%dwatchdog", ether->ctlrno); kproc(name, watchdog, ether); } } diff --git a/pc/etherec2t.c b/pc/etherec2t.c index 33b21fe89b4c1546861c542626b2b17b318168fd..994b2f6181cf9d5c4b5d55c154e72148784d0209 100644 --- a/pc/etherec2t.c +++ b/pc/etherec2t.c @@ -21,7 +21,6 @@ enum { static char* ec2tpcmcia[] = { "EC2T", /* Linksys Combo PCMCIA EthernetCard */ "PCMPC100", /* EtherFast 10/100 PC Card */ - "PCM100", /* EtherFast 10/100 Integrated PC Card */ "EN2216", /* Accton EtherPair-PCMCIA */ "FA410TX", /* Netgear FA410TX */ nil, @@ -117,9 +116,9 @@ reset(Ether* ether) */ dp8390reset(ether); sum = 0; - if(cistrcmp(type, "PCMPC100") == 0 || cistrcmp(type, "PCM100") == 0 || cistrcmp(type, "FA410TX") == 0){ + if(cistrcmp(type, "PCMPC100") == 0 || cistrcmp(type, "FA410TX") == 0){ /* - * These NICs have the ethernet address in I/O space. + * The PCMPC100 has the ethernet address in I/O space. * There's a checksum over 8 bytes which sums to 0xFF. */ for(i = 0; i < 8; i++){ diff --git a/pc/etherwavelan.c b/pc/etherwavelan.c index f4a199fca305fa10ad552cc64a55f8b89c8c0e52..11156b1d0d888982e6326620fcabe20797b9f85f 100644 --- a/pc/etherwavelan.c +++ b/pc/etherwavelan.c @@ -29,7 +29,7 @@ #define DEBUG if(1)print -#define SEEKEYS 0 +#define SEEKEYS 1 typedef struct Ctlr Ctlr; typedef struct Wltv Wltv; @@ -114,9 +114,7 @@ enum WTyp_Prom = 0xfc85, WTyp_Keys = 0xfcb0, WTyp_TxKey = 0xfcb1, - WTyp_StationID = 0xfd20, WTyp_CurName = 0xfd41, - WTyp_BaseID = 0xfd42, // ID of the currently connected-to base station WTyp_CurTxRate = 0xfd44, // Current TX rate WTyp_HasCrypt = 0xfd4f, }; @@ -434,10 +432,7 @@ ltv_outstr(Ctlr* ctlr, int type, char* val) memset(<v, 0, sizeof(ltv)); ltv.len = (sizeof(ltv.type)+sizeof(ltv.slen)+sizeof(ltv.s))/2; ltv.type = type; - -// This should be ltv.slen = len; according to Axel Belinfante ltv.slen = (len+1) & ~1; - strncpy(ltv.s, val, len); w_outltv(ctlr, <v); } @@ -917,7 +912,7 @@ ifstat(Ether* ether, void* a, long n, ulong offset) k = ((ctlr->txbusy)? ", txbusy" : ""); PRINTSTAT("%s\n", k); - if (ctlr->hascrypt){ + if (ctlr->txkey){ PRINTSTR("Keys: "); for (i = 0; i < WNKeys; i++){ if (ctlr->keys.keys[i].len == 0) @@ -945,16 +940,8 @@ ifstat(Ether* ether, void* a, long n, ulong offset) PRINTSTAT("Promiscuous mode: %d\n", ltv_ins(ctlr, WTyp_Prom)); if(i == 3) PRINTSTAT("SSID name: %s\n", ltv_inname(ctlr, WTyp_NetName)); - else { - Wltv ltv; + else PRINTSTAT("Current name: %s\n", ltv_inname(ctlr, WTyp_CurName)); - ltv.type = WTyp_BaseID; - ltv.len = 4; - if (w_inltv(ctlr, <v)) - print("#l%d: unable to read base station mac addr\n", ether->ctlrno); - l += snprint(p+l, READSTR-l, "Base station: %2.2x%2.2x%2.2x%2.2x%2.2x%2.2x\n", - ltv.addr[0], ltv.addr[1], ltv.addr[2], ltv.addr[3], ltv.addr[4], ltv.addr[5]); - } PRINTSTAT("Net name: %s\n", ltv_inname(ctlr, WTyp_WantName)); PRINTSTAT("Node name: %s\n", ltv_inname(ctlr, WTyp_NodeName)); if (ltv_ins(ctlr, WTyp_HasCrypt) == 0) @@ -1179,7 +1166,12 @@ reset(Ether* ether) int i; Wltv ltv; Ctlr* ctlr; - char buf[ISAOPTLEN], *p; + char *p; + + if (ether->ctlr){ + print("#l%d: only one card supported\n", ether->ctlrno); + return -1; + } if((ctlr = malloc(sizeof(Ctlr))) == nil) return -1; @@ -1199,13 +1191,11 @@ reset(Ether* ether) } if ((ctlr->slot = pcmspecial("WaveLAN/IEEE", ether))<0){ - if ((ctlr->slot = pcmspecial("TrueMobile 1150", ether))<0){ - DEBUG("no wavelan found\n"); - goto abort; - } + DEBUG("no wavelan found\n"); + goto abort; } - // DEBUG("#l%d: port=0x%lx irq=%ld\n", - // ether->ctlrno, ether->port, ether->irq); +// DEBUG("#l%d: port=0x%lx irq=%ld\n", +// ether->ctlrno, ether->port, ether->irq); w_intdis(ctlr); if (w_cmd(ctlr,WCmdIni,0)){ @@ -1226,14 +1216,9 @@ reset(Ether* ether) strcpy(ctlr->nodename, "Plan 9 STA"); for(i = 0; i < ether->nopt; i++){ - // - // The max. length of an 'opt' is ISAOPTLEN in dat.h. - // It should be > 16 to give reasonable name lengths. - // - strcpy(buf, ether->opt[i]); - if(p = strchr(buf, '=')) + if(p = strchr(ether->opt[i], '=')) *p = ' '; - option(ctlr, buf, strlen(buf)); + option(ctlr, ether->opt[i], strlen(ether->opt[i])); } ctlr->netname[WNameLen-1] = 0; diff --git a/pc/fns.h b/pc/fns.h index cbea642561671c3f1faa7928ae27d6cb48217523..d07040b6270391bf280221ca376cf6d6b9609c8b 100644 --- a/pc/fns.h +++ b/pc/fns.h @@ -38,7 +38,6 @@ ulong getcr3(void); ulong getcr4(void); char* getconf(char*); int havecycintr(void); -void halt(void); /* x86 HLT */ int i8042auxcmd(int); void i8042auxenable(void (*)(int, int)); void i8042reset(void); @@ -63,6 +62,7 @@ int ioalloc(int, int, int, char*); int iprint(char*, ...); int isaconfig(char*, int, ISAConf*); void kbdinit(void); +#define kmapinval() void lgdt(ushort[3]); void lidt(ushort[3]); void links(void); @@ -75,8 +75,6 @@ ulong mmukmap(ulong, ulong, int); int mmukmapsync(ulong); #define mmunewpage(x) ulong* mmuwalk(ulong*, ulong, int, int); -void ns16552install(void); -void ns16552special(int, int, Queue**, Queue**, int (*)(Queue*, int)); uchar nvramread(int); void nvramwrite(int, uchar); void outb(int, int); @@ -134,9 +132,3 @@ ulong TK2MS(ulong); /* ticks to milliseconds */ #define PADDR(a) ((ulong)(a)&~KZERO) #define dcflush(a, b) - -/* - * wrapper around memmove that causes kprof to credit caller for time - */ -// extern void *kpmemmove(void*, void*, long); -// #define memmove kpmemmove diff --git a/pc/i8259.c b/pc/i8259.c index ca87f1d9fe976a56a5ab5673fa712ac7620b6411..4c3d905ae7044e19bddc20d6f0a705a5ac34df5f 100644 --- a/pc/i8259.c +++ b/pc/i8259.c @@ -95,7 +95,7 @@ i8259init(void) if(inb(Elcr1) == 0x20) i8259elcr = x; outb(Elcr1, x & 0xFF); - //print("ELCR: %4.4uX\n", i8259elcr); + print("ELCR: %4.4uX\n", i8259elcr); } } iunlock(&i8259lock); diff --git a/pc/io.h b/pc/io.h index 0d2276f96b4635443cd598cf39ce56cf7dec2bba..a0149acd9b15817e2c9fa0ade36dd926bbef1317 100644 --- a/pc/io.h +++ b/pc/io.h @@ -44,7 +44,7 @@ enum { typedef struct Vctl { Vctl* next; /* handlers on this vector */ - char name[NAMELEN]; /* of driver */ + char name[KNAMELEN]; /* of driver */ int isintr; /* interrupt or fault/trap */ int irq; int tbdf; diff --git a/pc/kpmemmove.c b/pc/kpmemmove.c deleted file mode 100644 index 60540b7c1e317f3f72366b8ec9ba439ca126c07c..0000000000000000000000000000000000000000 --- a/pc/kpmemmove.c +++ /dev/null @@ -1,21 +0,0 @@ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "../port/error.h" - -#undef memmove - -void * -kpmemmove(void *s, void *d, long n) -{ - void *p; - if(up == nil) - return memmove(s, d, n); - - up->kppc = getcallerpc(&s); - p = memmove(s, d, n); - up->kppc = 0; - return p; -} diff --git a/pc/l.s b/pc/l.s index 42478b685e855fa70e5baed09f13533856652009..e80e7dcaf9a2b474d374951e0735494992e89489 100644 --- a/pc/l.s +++ b/pc/l.s @@ -509,6 +509,14 @@ TEXT setlabel(SB), $0 * Attempt at power saving. -rsc */ TEXT halt(SB), $0 + CLI + CMPL nrdy(SB), $0 + JEQ _nothingready + STI + RET + +_nothingready: + STI HLT RET diff --git a/pc/main.c b/pc/main.c index 00da260dfc2318db08e2f9723fe68ca83b41ab05..1a4060b153191ac4e9238d6c34d3c465d3c9c976 100644 --- a/pc/main.c +++ b/pc/main.c @@ -24,54 +24,17 @@ static uchar *sp; /* stack pointer for /boot */ #define BOOTARGSLEN (4096-0x200-BOOTLINELEN) #define MAXCONF 32 -char bootdisk[NAMELEN]; +char bootdisk[KNAMELEN]; char *confname[MAXCONF]; char *confval[MAXCONF]; int nconf; -extern void ns16552install(void); /* botch: config */ - -static int isoldbcom; - -static int -getcfields(char* lp, char** fields, int n, char* sep) -{ - int i; - - for(i = 0; lp && *lp && i < n; i++){ - while(*lp && strchr(sep, *lp) != 0) - *lp++ = 0; - if(*lp == 0) - break; - fields[i] = lp; - while(*lp && strchr(sep, *lp) == 0){ - if(*lp == '\\' && *(lp+1) == '\n') - *lp++ = ' '; - lp++; - } - } - - return i; -} - static void options(void) { - uchar *bda; long i, n; char *cp, *line[MAXCONF], *p, *q; - if(strncmp(BOOTARGS, "ZORT 0\r\n", 8)){ - isoldbcom = 1; - - memmove(BOOTARGS, KADDR(1024), BOOTARGSLEN); - memmove(BOOTLINE, KADDR(0x100), BOOTLINELEN); - - bda = KADDR(0x400); - bda[0x13] = 639; - bda[0x14] = 639>>8; - } - /* * parse configuration args from dos file plan9.ini */ @@ -91,16 +54,14 @@ options(void) } *p = 0; - n = getcfields(cp, line, MAXCONF, "\n"); + n = getfields(cp, line, MAXCONF, 1, "\n"); for(i = 0; i < n; i++){ if(*line[i] == '#') continue; cp = strchr(line[i], '='); - if(cp == 0) + if(cp == nil) continue; - *cp++ = 0; - if(cp - line[i] >= NAMELEN+1) - *(line[i]+NAMELEN-1) = 0; + *cp++ = '\0'; confname[nconf] = line[i]; confval[nconf] = cp; nconf++; @@ -110,45 +71,27 @@ options(void) void main(void) { - outb(0x3F2, 0x00); /* botch: turn off the floppy motor */ - - /* - * There is a little leeway here in the ordering but care must be - * taken with dependencies: - * function dependencies - * ======== ============ - * machinit depends on: m->machno, m->pdb - * cpuidentify depends on: m - * confinit calls: meminit - * meminit depends on: cpuidentify (needs to know processor - * type for caching, etc.) - * archinit depends on: meminit (MP config table may be at the - * top of system physical memory); - * conf.nmach (not critical, mpinit will check); - * arch->intrinit depends on: trapinit - */ conf.nmach = 1; MACHP(0) = (Mach*)CPU0MACH; m->pdb = (ulong*)CPU0PDB; machinit(); - ioinit(); active.machs = 1; active.exiting = 0; options(); - screeninit(); + ioinit(); + i8250console(); + print("\nPlan 9\n"); cpuidentify(); + screeninit(); confinit(); archinit(); xinit(); trapinit(); printinit(); cpuidprint(); - if(isoldbcom) - print(" ****OLD B.COM - UPGRADE****\n"); mmuinit(); if(arch->intrinit) arch->intrinit(); - ns16552install(); /* botch: config */ mathinit(); kbdinit(); if(arch->clockenable) @@ -175,12 +118,20 @@ machinit(void) memset(m, 0, sizeof(Mach)); m->machno = machno; m->pdb = pdb; + + /* + * For polled uart output at boot, need + * a default delay constant. 100000 should + * be enough for a while. Cpuidentify will + * calculate the real value later. + */ + m->loopconst = 100000; } void ksetterm(char *f) { - char buf[2*NAMELEN]; + char buf[2*KNAMELEN]; sprint(buf, f, conffile); ksetenv("terminal", buf); @@ -203,7 +154,7 @@ init0(void) up->slash = namec("#/", Atodir, 0, 0); cnameclose(up->slash->name); up->slash->name = newcname("/"); - up->dot = cclone(up->slash, 0); + up->dot = cclone(up->slash); chandevinit(); @@ -241,8 +192,10 @@ userinit(void) p->rgrp = newrgrp(); p->procmode = 0640; - strcpy(p->text, "*init*"); - strcpy(p->user, eve); + kstrdup(&eve, ""); + kstrdup(&p->text, "*init*"); + kstrdup(&p->user, eve); + p->fpstate = FPinit; fpoff(); @@ -465,7 +418,7 @@ mathnote(void) { int i; ulong status; - char *msg, note[ERRLEN]; + char *msg, note[ERRMAX]; status = up->fpsave.status; @@ -642,29 +595,18 @@ exit(int ispanic) int isaconfig(char *class, int ctlrno, ISAConf *isa) { - char cc[NAMELEN], *p, *q, *r; - int n; + char cc[32], *p; + int i, n; - sprint(cc, "%s%d", class, ctlrno); + snprint(cc, sizeof cc, "%s%d", class, ctlrno); for(n = 0; n < nconf; n++){ - if(cistrncmp(confname[n], cc, NAMELEN)) + if(cistrcmp(confname[n], cc) != 0) continue; - isa->nopt = 0; - p = confval[n]; - while(*p){ - while(*p == ' ' || *p == '\t') - p++; - if(*p == '\0') - break; - if(cistrncmp(p, "type=", 5) == 0){ - p += 5; - for(q = isa->type; q < &isa->type[NAMELEN-1]; q++){ - if(*p == '\0' || *p == ' ' || *p == '\t') - break; - *q = *p++; - } - *q = '\0'; - } + isa->nopt = tokenize(confval[n], isa->opt, NISAOPT); + for(i = 0; i < isa->nopt; i++){ + p = isa->opt[i]; + if(cistrncmp(p, "type=", 5) == 0) + isa->type = p + 5; else if(cistrncmp(p, "port=", 5) == 0) isa->port = strtoul(p+5, &p, 0); else if(cistrncmp(p, "irq=", 4) == 0) @@ -677,42 +619,12 @@ isaconfig(char *class, int ctlrno, ISAConf *isa) isa->size = strtoul(p+5, &p, 0); else if(cistrncmp(p, "freq=", 5) == 0) isa->freq = strtoul(p+5, &p, 0); - else if(isa->nopt < NISAOPT){ - r = isa->opt[isa->nopt]; - while(*p && *p != ' ' && *p != '\t'){ - *r++ = *p++; - if(r-isa->opt[isa->nopt] >= ISAOPTLEN-1) - break; - } - *r = '\0'; - isa->nopt++; - } - while(*p && *p != ' ' && *p != '\t') - p++; } return 1; } return 0; } -/* -int -iprint(char *fmt, ...) -{ - char buf[PRINTSIZE]; - int n; - va_list arg; - - va_start(arg, fmt); - n = doprint(buf, buf+sizeof(buf), fmt, arg) - buf; - va_end(arg); - - screenputs(buf, n); - - return n; -} -*/ - int cistrcmp(char *a, char *b) { diff --git a/pc/memory.c b/pc/memory.c index e48539460bdb09121eaa7994018724ce1c0b7ea7..fa881c66e9870e65bc1371fc9b63db6cb4c83e3f 100644 --- a/pc/memory.c +++ b/pc/memory.c @@ -225,11 +225,14 @@ umbscan(void) */ p = KADDR(0xC0000); while(p < (uchar*)KADDR(0xE0000)){ - if (p[0] == 0x55 && p[1] == 0xAA) { - /* Skip p[2] chunks of 512 bytes. Test for 0x55 AA before - poking obtrusively, or else the Thinkpad X20 dies when - setting up the cardbus (PB) */ - p += p[2] * 512; + /* + * Test for 0x55 AA before poking obtrusively, + * some machines (e.g. Thinkpad X20) seem to map + * something dynamic here (cardbus?) causing weird + * problems if it is changed. + */ + if(p[0] == 0x55 && p[1] == 0xAA){ + p += p[2]*512; continue; } diff --git a/pc/mmu.c b/pc/mmu.c index f4bf80ab278ef54de9a9a5398f3dbed1ad22147f..198ca9cb77ff956972a91e56e3b4c911d62d37c3 100644 --- a/pc/mmu.c +++ b/pc/mmu.c @@ -5,26 +5,6 @@ #include "fns.h" #include "io.h" -/* - * There are 2 coherence calls in this file, before each putcr3() (mmuflushtlb - * is really a putcr3() call). They are there because of my IBM 570 and ehg's - * IBM 600E. We found that when the coherence() instructions were removed from - * unlock and iunlock, the processors would hang and/or get spurious interrupts. - * I posited that we were getting hit by some interaction between the tlb, - * cache flushing, and tlb flushing, so I moved the calls here and it seems - * to work. - * - * I don't really understand why they'ld change anything since the putcr3 is - * supposed to be a serializing instruction. Also, reads and writes are supposed - * to be ordered in the view of the processing core. This is just desperation. - * I can only believe that the coherence() is fixing something else. - * - * The 570 is a Celeron and the 600E is a PentiumII/Xeon. Both screw up when - * pounding on PCMCIA devices. - * - * -- presotto - */ - #define DATASEGM(p) { 0xFFFF, SEGG|SEGB|(0xF<<16)|SEGP|SEGPL(p)|SEGDATA|SEGW } #define EXECSEGM(p) { 0xFFFF, SEGG|SEGD|(0xF<<16)|SEGP|SEGPL(p)|SEGEXEC|SEGR } #define TSSSEGM(b,p) { ((b)<<16)|sizeof(Tss),\ @@ -56,7 +36,6 @@ taskswitch(ulong pdb, ulong stack) tss->ss2 = KDSEL; tss->esp2 = stack; tss->cr3 = pdb; - coherence(); // *** See note at beginning of file *** putcr3(pdb); } @@ -247,7 +226,6 @@ putmmu(ulong va, ulong pa, Page*) s = splhi(); pdb[PDX(MACHADDR)] = m->pdb[PDX(MACHADDR)]; - coherence(); // *** See note at beginning of file *** mmuflushtlb(up->mmupdb->pa); splx(s); } diff --git a/pc/mouse.c b/pc/mouse.c index 256b42a9a640dbefb33af2802515638294c2ce05..e5d455654f6a2ddb466c81ffb88443d6d74f9fb8 100644 --- a/pc/mouse.c +++ b/pc/mouse.c @@ -33,6 +33,7 @@ static int accelerated; static void serialmouse(int port, char *type, int setspeed) { +#ifdef notdef if(mousetype == Mouseserial) error(Emouseset); @@ -43,11 +44,15 @@ serialmouse(int port, char *type, int setspeed) if(setspeed) setspeed = 1200; if(type && *type == 'M') - ns16552special(port, setspeed, 0, 0, m3mouseputc); + uartspecial(port, setspeed, 0, 0, m3mouseputc); else - ns16552special(port, setspeed, 0, 0, mouseputc); + uartspecial(port, setspeed, 0, 0, mouseputc); mousetype = Mouseserial; packetsize = 3; +#else + error("serial mouse not supported yet"); + USED(port, type, setspeed); +#endif /* notdef */ } /* @@ -131,7 +136,7 @@ ps2mouseputc(int c, int shift) } dx = msg[1]; dy = -msg[2]; - mousetrack(buttons, dx, dy); + mousetrack(dx, dy, buttons, TK2MS(MACHP(0)->ticks)); } return; } diff --git a/pc/mp.c b/pc/mp.c index f52189623918d382702421582fcc7a0f9928d0c1..ed345ac39f10a670ab7fde521a92bb094be62ac6 100644 --- a/pc/mp.c +++ b/pc/mp.c @@ -462,8 +462,6 @@ mpstartap(Apic* apic) void mpinit(void) { - int ncpu; - char *cp; PCMP *pcmp; uchar *e, *p; Apic *apic, *bpapic; @@ -564,22 +562,11 @@ mpinit(void) /* * Initialise the application processors. */ - if(cp = getconf("*ncpu")){ - ncpu = strtol(cp, 0, 0); - if(ncpu < 1) - ncpu = 1; - } - else - ncpu = MaxAPICNO; memmove((void*)APBOOTSTRAP, apbootstrap, sizeof(apbootstrap)); for(apic = mpapic; apic <= &mpapic[MaxAPICNO]; apic++){ - if(ncpu <= 1) - break; if((apic->flags & (PcmpBP|PcmpEN)) == PcmpEN - && apic->type == PcmpPROCESSOR){ + && apic->type == PcmpPROCESSOR) mpstartap(apic); - ncpu--; - } } /* diff --git a/pc/ns16552.h b/pc/ns16552.h deleted file mode 100644 index 6a14f387db141221c771e2cdb1cd8161a8ec390b..0000000000000000000000000000000000000000 --- a/pc/ns16552.h +++ /dev/null @@ -1,217 +0,0 @@ -/* - * PC specific code for the ns16552. It includes support for the 2 built - * in uarts plus up to 5 MP-008 8 uart ISA cards. - */ -enum -{ - Maxcard= 5, /* max serial cards */ - UartFREQ= 1843200, - - Serial= 0, - Modem= 1, -}; - -#define uartwrreg(u,r,v) outb((u)->port + r, (u)->sticky[r] | (v)) -#define uartrdreg(u,r) inb((u)->port + r) - -void ns16552setup(ulong, ulong, char*, int); -void ns16552special(int, int, Queue**, Queue**, int (*)(Queue*, int)); -void uartclock(void); -/* - * definition of an optional serial card - */ -typedef struct Scard -{ - ISAConf; /* card configuration */ - int first; /* number of first port */ -} Scard; -static Scard *scard[Maxcard]; /* configs for the serial card */ - -/* power management currently only makes sense on the AT&T safari */ -static void -uartpower(int dev, int onoff) -{ - switch(dev){ - case Modem: - if((*arch->modempower)(onoff) < 0) - print("can't turn %s modem speaker\n", onoff?"on":"off"); - break; - case Serial: - if((*arch->serialpower)(onoff) < 0) - print("can't turn %s serial port power\n", onoff?"on":"off"); - break; - } -} - -/* - * handle an interrupt to a single uart - */ -static void -ns16552intrx(Ureg*, void* arg) -{ - ns16552intr((ulong)arg); -} - -/* - * interrupts from the multiport card, MP-008. A polling port - * tells which of 8 devices interrupted. - */ -static void -mp008intr(Ureg* ureg, void* arg) -{ - int i, loops; - uchar n; - Scard *mp; - - mp = arg; - for(loops = 0; loops < 1024; loops++){ - n = ~inb(mp->mem); - if(n == 0) - return; - for(i = 0; n; i++){ - if(n & 1) - ns16552intrx(ureg, (void*)(mp->first+i)); - n >>= 1; - } - } -} - -/* - * install a default serial port on a PC unless - * name=disabled is set in plan9.ini - */ -void -ns16552default(char *name, int port, int irq) -{ - char *p; - - if((p = getconf(name)) && strncmp(p, "disabled", 8) == 0) - return; - - if(ioalloc(port, 8, 0, name) < 0) { - print("%s: port %x in use\n", name, port); - return; - } - - ns16552setup(port, UartFREQ, name, Ns550); - intrenable(irq, ns16552intrx, (void*)(nuart-1), BUSUNKNOWN, name); -} - - -/* - * install the uarts (called by reset) - */ -void -ns16552install(void) -{ - int i, j, port, nscard, baud; - char *p, *q; - Scard *sc; - char name[NAMELEN]; - static int already; - - if(already) - return; - already = 1; - - /* first two ports are usually there and always the normal frequency */ - ns16552default("eia0", 0x3F8, IrqUART0); - ns16552default("eia1", 0x2F8, IrqUART1); - - addclock0link(uartclock); - - /* set up a serial console */ - if(p = getconf("console")){ - port = strtol(p, &q, 0); - if(p != q && (port == 0 || port == 1)) { - baud = 0; - if(p = getconf("baud")) - baud = strtoul(p, 0, 0); - if(baud == 0) - baud = 9600; - ns16552special(port, baud, &kbdq, &printq, kbdcr2nl); - } - } - - /* the rest come out of plan9.ini */ - nscard = 0; - for(i = 0; i < Maxcard; i++){ - sc = scard[nscard] = xalloc(sizeof(Scard)); - if(isaconfig("serial", i, sc) == 0){ - xfree(sc); - scard[nscard] = 0; - continue; - } - - snprint(name, sizeof name, "eia%d00", nscard); - if(cistrcmp(sc->type, "MP008") == 0){ - /* - * port gives base port address for uarts - * irq is interrupt - * mem is the polling port - * size is the number of serial ports on the same polling port - * freq is the baud rate generator frequency - */ - if(sc->size == 0) - sc->size = 8; - if(sc->freq == 0) - sc->freq = UartFREQ; - sc->first = nuart; - if(ioalloc(sc->port, 8*sc->size, 0, name) < 0){ - print("mp008: port %lud in use\n", sc->port); - xfree(sc); - scard[nscard] = 0; - continue; - } - intrenable(sc->irq, mp008intr, sc, BUSUNKNOWN, name); - port = sc->port; - for(j=0; j < sc->size; j++){ - sprint(name, "eia%d%2.2d", nscard, j); - ns16552setup(port, sc->freq, name, Ns550); - port += 8; - } - } else if(cistrcmp(sc->type, "turbo650") == 0){ - /* - * port gives base port address for the uart - * irq is interrupt - * freq is the baud rate generator frequency - */ - if(sc->freq == 0) - sc->freq = UartFREQ*4; - if(ioalloc(sc->port, 8, 0, name) < 0){ - print("%s: port %lud in use\n", name, sc->port); - xfree(sc); - scard[nscard] = 0; - continue; - } - ns16552setup(sc->port, sc->freq, name, Ns650); - - /* - * multiply clock speed by 4 - */ - if(sc->mem == 0) - outb(0x2c8, 0); - else - outb(sc->mem, 0); - - intrenable(sc->irq, ns16552intrx, (void*)(nuart-1), BUSUNKNOWN, name); - } else if(cistrcmp(sc->type, "com") == 0 && sc->port != 0x3F8 && sc->port != 0x2F8){ - /* - * port gives base port address for the uart - * irq is interrupt - * freq is the baud rate generator frequency - */ - if(sc->freq == 0) - sc->freq = UartFREQ; - if(ioalloc(sc->port, 8, 0, name) < 0){ - print("%s: port %lud in use\n", name, sc->port); - xfree(sc); - scard[nscard] = 0; - continue; - } - ns16552setup(sc->port, sc->freq, name, Ns550); - intrenable(sc->irq, ns16552intrx, (void*)(nuart-1), BUSUNKNOWN, name); - } - nscard++; - } -} diff --git a/pc/screen.c b/pc/screen.c index e6aa86fe70f53678ef47740166e1dbde2b8a2d23..f428c85945c4492c08e3f43d2b58fe42be395e9c 100644 --- a/pc/screen.c +++ b/pc/screen.c @@ -73,7 +73,7 @@ screensize(int x, int y, int z, ulong chan) return -1; /* memset(gscreen->data->bdata, 0x15, (x*y*z+7)/8); /* RSC BUG */ -// memfillcolor(gscreen, DRed); + memfillcolor(gscreen, DRed); scr->palettedepth = 6; /* default */ scr->gscreendata = &gscreendata; @@ -327,141 +327,6 @@ setcursor(Cursor* curs) scr->cur->load(scr, curs); } -static ulong -pixelbits(Memimage *i, Point pt) -{ - uchar *p; - ulong val; - int off, bpp, npack; - - val = 0; - p = byteaddr(i, pt); - switch(bpp=i->depth){ - case 1: - case 2: - case 4: - npack = 8/bpp; - off = pt.x%npack; - val = p[0] >> bpp*(npack-1-off); - val &= (1<chan; chan; chan>>=8){ - nb = NBITS(chan); - ov = v = val&((1<>= nb; - - while(nb < 8){ - v |= v<>= (nb-8); - - switch(TYPE(chan)){ - case CRed: - r = v; - break; - case CGreen: - g = v; - break; - case CBlue: - b = v; - break; - case CAlpha: - a = v; - break; - case CGrey: - r = g = b = v; - break; - case CMap: - p = img->cmap->cmap2rgb+3*ov; - r = *p++; - g = *p++; - b = *p; - break; - } - } - return (r<<24)|(g<<16)|(b<<8)|a; -} - -static ulong -rgbatoimg(Memimage *img, ulong rgba) -{ - ulong chan; - int d, nb; - ulong v; - uchar *p, r, g, b, a, m; - - v = 0; - r = rgba>>24; - g = rgba>>16; - b = rgba>>8; - a = rgba; - d = 0; - for(chan=img->chan; chan; chan>>=8){ - nb = NBITS(chan); - switch(TYPE(chan)){ - case CRed: - v |= (r>>(8-nb))<>(8-nb))<>(8-nb))<>(8-nb))<cmap->rgb2cmap; - m = p[(r>>4)*256+(g>>4)*16+(b>>4)]; - v |= m<data->bdata != gscreendata.bdata) return 0; -// if(dst->data != &gscreendata){ -// lastbad = dst->data; -// lastbadi = dst; -// return 0; -// } - if(scr->fill==nil && scr->scroll==nil) return 0; @@ -509,11 +368,6 @@ hwdraw(Memdrawparam *par) src = par->src; if(scr->scroll && src->data->bdata==dst->data->bdata && !(src->flags&Falpha) && (par->state&(Simplemask|Fullmask))==(Simplemask|Fullmask)){ -// if(src->zero != dst->zero){ -// lastbadsrc = src; -// lastbaddst = dst; -// iprint("#"); -// } return scr->scroll(scr, par->r, par->sr); } diff --git a/pc/screen.h b/pc/screen.h index 52f2942c4a27f2e42f5b19c89754ee0f893298d0..809fae2fcc4712ae6d1d9ee5fcbb4cd5acef5fbf 100644 --- a/pc/screen.h +++ b/pc/screen.h @@ -6,7 +6,7 @@ struct Cursorinfo { }; /* devmouse.c */ -extern void mousetrack(int, int, int); +extern void mousetrack(int, int, int, int); extern Point mousexy(void); extern void mouseaccelerate(int); @@ -68,8 +68,6 @@ struct VGAdev { ulong (*linear)(VGAscr*, int*, int*); void (*drawinit)(VGAscr*); int (*fill)(VGAscr*, Rectangle, ulong); - void (*ovlctl)(VGAscr*, Chan*, void*, int); - int (*ovlwrite)(VGAscr*, void*, int, vlong); }; struct VGAcur { @@ -127,6 +125,7 @@ extern void mousectl(char*[], int); /* screen.c */ extern int hwaccel; /* use hw acceleration; default on */ extern int hwblank; /* use hw blanking; default on */ +extern uchar* attachscreen(Rectangle*, ulong*, int*, int*, int*); extern void flushmemscreen(Rectangle); extern int cursoron(int); extern void cursoroff(int); @@ -140,7 +139,6 @@ extern void blankscreen(int); extern void deletescreenimage(void); extern int drawhasclients(void); extern ulong blanktime; -extern uchar* attachscreen(Rectangle*, ulong*, int*, int*, int*); /* vga.c */ extern void vgascreenwin(VGAscr*); @@ -149,4 +147,3 @@ extern ulong vgapcilinear(VGAscr*, int*, int*, int, int); extern void drawblankscreen(int); extern void vgablank(VGAscr*, int); -extern void addvgaseg(char*, ulong, ulong); diff --git a/pc/sd53c8xx.c b/pc/sd53c8xx.c index 883188b9853e2059a2176ab455d3c98a1d4ee879..99ce51ddac7ef3c11f2b7df51aef684e399a634a 100644 --- a/pc/sd53c8xx.c +++ b/pc/sd53c8xx.c @@ -2,8 +2,6 @@ * NCR/Symbios/LSI Logic 53c8xx driver for Plan 9 * Nigel Roles (nigel@9fs.org) * - * 13/3/01 Fixed microcode to support targets > 7 - * * 01/12/00 Removed previous comments. Fixed a small problem in * mismatch recovery for targets with synchronous offsets of >=16 * connected to >=875s. Thanks, Jean. @@ -315,7 +313,6 @@ typedef struct Controller { } Controller; #define SYNCOFFMASK(c) (((c)->v->maxsyncoff * 2) - 1) -#define SSIDMASK(c) (((c)->v->feature & Wide) ? 15 : 7) /* ISTAT */ enum { Abrt = 0x80, Srst = 0x40, Sigp = 0x20, Sem = 0x10, Con = 0x08, Intf = 0x04, Sip = 0x02, Dip = 0x01 }; @@ -1341,8 +1338,8 @@ interrupt(Ureg *ur, void *a) break; case A_SIR_ERROR_NOT_MSG_IN_AFTER_RESELECT: IPRINT(PRINTPREFIX "%d: not msg_in after reselect (%s)", - n->ssid & SSIDMASK(c), phase[n->sstat1 & 7]); - dsa = dsafind(c, n->ssid & SSIDMASK(c), -1, A_STATE_DISCONNECTED); + n->ssid & 7, phase[n->sstat1 & 7]); + dsa = dsafind(c, n->ssid & 7, -1, A_STATE_DISCONNECTED); dumpncrregs(c, 1); wakeme = 1; break; @@ -1838,8 +1835,6 @@ xfunc(Controller *c, enum na_external x, unsigned long *v) *v = offsetof(Dsa, status_buf); return 1; case X_dsa_head: *v = DMASEG(&c->dsalist.head[0]); return 1; - case X_ssid_mask: - *v = SSIDMASK(c); return 1; default: print("xfunc: can't find external %d\n", x); return 0; @@ -2030,13 +2025,13 @@ symenable(SDev* sdev) { Pcidev *pcidev; Controller *ctlr; - char name[NAMELEN]; + char name[32]; ctlr = sdev->ctlr; pcidev = ctlr->pcidev; pcisetbme(pcidev); - snprint(name, NAMELEN, "%s (%s)", sdev->name, sdev->ifc->name); + snprint(name, sizeof(name), "%s (%s)", sdev->name, sdev->ifc->name); intrenable(pcidev->intl, interrupt, ctlr, pcidev->tbdf, name); ilock(ctlr); diff --git a/pc/sdata.c b/pc/sdata.c index aae76241bd67582434a6b5fa6304f28a6fa4ab3e..bc57d805c76011c364753bf2ef8e7062bde14833 100644 --- a/pc/sdata.c +++ b/pc/sdata.c @@ -402,7 +402,7 @@ atacsf(Drive* drive, vlong csf, int supported) info = &drive->info[Icsfs]; else info = &drive->info[Icsfe]; - + for(i = 0; i < 3; i++){ x = (csf>>(16*i)) & 0xFFFF; if(x == 0) @@ -1500,7 +1500,7 @@ atainterrupt(Ureg*, void* arg) if((drive = ctlr->curdrive) == nil){ iunlock(ctlr); if((DEBUG & DbgDEBUG) && ctlr->command != Cedd) - print("Inil%2.2uX/%2.2uX+", ctlr->command, status); + print("Inil%2.2uX+", ctlr->command); return; } @@ -1702,6 +1702,7 @@ ataid(SDev* sdev) { int i; Ctlr *ctlr; + char name[32]; /* * Legacy controllers are always 'C' and 'D' and if @@ -1727,7 +1728,8 @@ ataid(SDev* sdev) sdev->idno = 'C'+i; i++; } - snprint(sdev->name, NAMELEN, "sd%c", sdev->idno); + snprint(name, sizeof(name), "sd%c", sdev->idno); + kstrdup(&sdev->name, name); } sdev = sdev->next; } @@ -1739,7 +1741,7 @@ static int ataenable(SDev* sdev) { Ctlr *ctlr; - char name[NAMELEN]; + char name[32]; ctlr = sdev->ctlr; @@ -1748,7 +1750,7 @@ ataenable(SDev* sdev) pcisetbme(ctlr->pcidev); ctlr->prdt = xspanalloc(Nprd*sizeof(Prd), 4, 4*1024); } - snprint(name, NAMELEN, "%s (%s)", sdev->name, sdev->ifc->name); + snprint(name, sizeof(name), "%s (%s)", sdev->name, sdev->ifc->name); intrenable(ctlr->irq, atainterrupt, ctlr, ctlr->tbdf, name); outb(ctlr->ctlport+Dc, 0); if(ctlr->ienable) diff --git a/pc/sdmylex.c b/pc/sdmylex.c index 25b0c5d5ab36c59ca961a8cb7e3e0771b3c20010..12a160cb69faaa765ae9503cef745ccfc2c6bd42 100644 --- a/pc/sdmylex.c +++ b/pc/sdmylex.c @@ -1193,7 +1193,7 @@ mylexenable(SDev* sdev) int tbdf; Ctlr *ctlr; void (*interrupt)(Ureg*, void*); - char name[NAMELEN]; + char name[32]; ctlr = sdev->ctlr; if(ctlr->cache == nil){ @@ -1216,7 +1216,7 @@ mylexenable(SDev* sdev) else return 0; - snprint(name, NAMELEN, "sd%c (%s)", sdev->idno, sdev->ifc->name); + snprint(name, sizeof(name), "sd%c (%s)", sdev->idno, sdev->ifc->name); intrenable(ctlr->irq, interrupt, ctlr, tbdf, name); return 1; diff --git a/pc/sdscsi.c b/pc/sdscsi.c index 68f220b2fb4ec159199d77a9d7d351792e78be7a..6c7bc094fd38aec099c37dd9fca73505e6595e5b 100644 --- a/pc/sdscsi.c +++ b/pc/sdscsi.c @@ -369,13 +369,15 @@ again: SDev* scsiid(SDev* sdev, SDifc* ifc) { + char name[32]; static char idno[16] = "0123456789abcdef"; static char *p = idno; while(sdev){ if(sdev->ifc == ifc){ sdev->idno = *p++; - snprint(sdev->name, NAMELEN, "sd%c", sdev->idno); + snprint(name, sizeof(name), "sd%c", sdev->idno); + kstrdup(&sdev->name, name); if(p >= &idno[sizeof(idno)]) break; } diff --git a/pc/trap.c b/pc/trap.c index db0a29236ae7cd891c9a2873389cbe0786897b5d..793375de51be856fb141f1c571738c187f4111f3 100644 --- a/pc/trap.c +++ b/pc/trap.c @@ -27,8 +27,8 @@ intrenable(int irq, void (*f)(Ureg*, void*), void* a, int tbdf, char *name) v->tbdf = tbdf; v->f = f; v->a = a; - strncpy(v->name, name, NAMELEN-1); - v->name[NAMELEN-1] = 0; + strncpy(v->name, name, KNAMELEN-1); + v->name[KNAMELEN-1] = 0; ilock(&vctllock); vno = arch->intrenable(v); @@ -53,7 +53,7 @@ intrenable(int irq, void (*f)(Ureg*, void*), void* a, int tbdf, char *name) static long irqallocread(Chan*, void *vbuf, long n, vlong offset) { - char *buf, *p, str[11+1+NAMELEN+1]; + char *buf, *p, str[11+1+KNAMELEN+1]; int m, vno; long oldn; Vctl *v; @@ -65,7 +65,7 @@ irqallocread(Chan*, void *vbuf, long n, vlong offset) buf = vbuf; for(vno=0; vnonext){ - m = snprint(str, sizeof str, "%11d %11d %.*s\n", vno, v->irq, NAMELEN, v->name); + m = snprint(str, sizeof str, "%11d %11d %.*s\n", vno, v->irq, KNAMELEN, v->name); if(m <= offset) /* if do not want this, skip entry */ offset -= m; else{ @@ -100,8 +100,8 @@ trapenable(int vno, void (*f)(Ureg*, void*), void* a, char *name) v->tbdf = BUSUNKNOWN; v->f = f; v->a = a; - strncpy(v->name, name, NAMELEN); - v->name[NAMELEN-1] = 0; + strncpy(v->name, name, KNAMELEN); + v->name[KNAMELEN-1] = 0; lock(&vctllock); if(vctl[vno]) @@ -214,7 +214,7 @@ void trap(Ureg* ureg) { int i, vno, user; - char buf[ERRLEN]; + char buf[ERRMAX]; Vctl *ctl, *v; Mach *mach; @@ -276,7 +276,7 @@ trap(Ureg* ureg) */ print("cpu%d: spurious interrupt %d, last %d", m->machno, vno, m->lastintr); - for(i = 0; i < conf.nmach; i++){ + for(i = 0; i < 32; i++){ if(!(active.machs & (1<cs & 0xFFFF) == UESEL; if(!user && mmukmapsync(addr)) return; read = !(ureg->ecode & 2); +if(up == nil) {print("what? up is zero pc %8lux\n", ureg->pc); for(;;);} insyscall = up->insyscall; up->insyscall = 1; n = fault(addr, read); @@ -552,8 +553,8 @@ notify(Ureg* ureg) n = &up->note[0]; if(strncmp(n->msg, "sys:", 4) == 0){ l = strlen(n->msg); - if(l > ERRLEN-15) /* " pc=0x12345678\0" */ - l = ERRLEN-15; + if(l > ERRMAX-15) /* " pc=0x12345678\0" */ + l = ERRMAX-15; sprint(n->msg+l, " pc=0x%.8lux", ureg->pc); } @@ -578,7 +579,7 @@ notify(Ureg* ureg) sp -= sizeof(Ureg); if(!okaddr((ulong)up->notify, 1, 0) - || !okaddr(sp-ERRLEN-4*BY2WD, sizeof(Ureg)+ERRLEN+4*BY2WD, 1)){ + || !okaddr(sp-ERRMAX-4*BY2WD, sizeof(Ureg)+ERRMAX+4*BY2WD, 1)){ pprint("suicide: bad address in notify\n"); qunlock(&up->debug); pexit("Suicide", 0); @@ -588,8 +589,8 @@ notify(Ureg* ureg) memmove((Ureg*)sp, ureg, sizeof(Ureg)); *(Ureg**)(sp-BY2WD) = up->ureg; /* word under Ureg is old up->ureg */ up->ureg = (void*)sp; - sp -= BY2WD+ERRLEN; - memmove((char*)sp, up->note[0].msg, ERRLEN); + sp -= BY2WD+ERRMAX; + memmove((char*)sp, up->note[0].msg, ERRMAX); sp -= 3*BY2WD; *(ulong*)(sp+2*BY2WD) = sp+3*BY2WD; /* arg 2 is string */ *(ulong*)(sp+1*BY2WD) = (ulong)up->ureg; /* arg 1 is ureg* */ @@ -673,7 +674,7 @@ noted(Ureg* ureg, ulong arg0) pexit("Suicide", 0); } qunlock(&up->debug); - sp = oureg-4*BY2WD-ERRLEN; + sp = oureg-4*BY2WD-ERRMAX; splhi(); ureg->sp = sp; ((ulong*)sp)[1] = oureg; /* arg 1 0(FP) is ureg* */ diff --git a/pc/uarti8250.c b/pc/uarti8250.c new file mode 100644 index 0000000000000000000000000000000000000000..fd252a7171a468862aac8e3d8e11dcf3e1f78934 --- /dev/null +++ b/pc/uarti8250.c @@ -0,0 +1,648 @@ +#include "u.h" +#include "../port/lib.h" +#include "mem.h" +#include "dat.h" +#include "fns.h" +#include "io.h" +#include "../port/error.h" + +/* + * 8250 UART and compatibles. + */ +enum { + Uart0 = 0x3F8, /* COM1 */ + Uart0IRQ = 4, + Uart1 = 0x2F8, /* COM2 */ + Uart1IRQ = 3, + + UartFREQ = 1843200, +}; + +enum { /* I/O ports */ + Rbr = 0, /* Receiver Buffer (RO) */ + Thr = 0, /* Transmitter Holding (WO) */ + Ier = 1, /* Interrupt Enable */ + Iir = 2, /* Interrupt Identification (RO) */ + Fcr = 2, /* FIFO Control (WO) */ + Lcr = 3, /* Line Control */ + Mcr = 4, /* Modem Control */ + Lsr = 5, /* Line Status */ + Msr = 6, /* Modem Status */ + Scr = 7, /* Scratch Pad */ + Dll = 0, /* Divisor Latch LSB */ + Dlm = 1, /* Divisor Latch MSB */ +}; + +enum { /* Ier */ + Erda = 0x01, /* Enable Received Data Available */ + Ethre = 0x02, /* Enable Thr Empty */ + Erls = 0x04, /* Enable Receiver Line Status */ + Ems = 0x08, /* Enable Modem Status */ +}; + +enum { /* Iir */ + Ims = 0x00, /* Ms interrupt */ + Ip = 0x01, /* Interrupt Pending (not) */ + Ithre = 0x02, /* Thr Empty */ + Irda = 0x04, /* Received Data Available */ + Irls = 0x06, /* Receiver Line Status */ + Ictoi = 0x0C, /* Character Time-out Indication */ + IirMASK = 0x3F, + Ife = 0xC0, /* FIFOs enabled */ +}; + +enum { /* Fcr */ + FIFOena = 0x01, /* FIFO enable */ + FIFOrclr = 0x02, /* clear Rx FIFO */ + FIFOtclr = 0x04, /* clear Tx FIFO */ + FIFO1 = 0x00, /* Rx FIFO trigger level 1 byte */ + FIFO4 = 0x40, /* 4 bytes */ + FIFO8 = 0x80, /* 8 bytes */ + FIFO14 = 0xC0, /* 14 bytes */ +}; + +enum { /* Lcr */ + Wls5 = 0x00, /* Word Length Select 5 bits/byte */ + Wls6 = 0x01, /* 6 bits/byte */ + Wls7 = 0x02, /* 7 bits/byte */ + Wls8 = 0x03, /* 8 bits/byte */ + WlsMASK = 0x03, + Stb = 0x04, /* 2 stop bits */ + Pen = 0x08, /* Parity Enable */ + Eps = 0x10, /* Even Parity Select */ + Stp = 0x20, /* Stick Parity */ + Brk = 0x40, /* Break */ + Dlab = 0x80, /* Divisor Latch Access Bit */ +}; + +enum { /* Mcr */ + Dtr = 0x01, /* Data Terminal Ready */ + Rts = 0x02, /* Ready To Send */ + Out1 = 0x04, /* no longer in use */ + Ie = 0x08, /* IRQ Enable */ + Dm = 0x10, /* Diagnostic Mode loopback */ +}; + +enum { /* Lsr */ + Dr = 0x01, /* Data Ready */ + Oe = 0x02, /* Overrun Error */ + Pe = 0x04, /* Parity Error */ + Fe = 0x08, /* Framing Error */ + Bi = 0x10, /* Break Interrupt */ + Thre = 0x20, /* Thr Empty */ + Temt = 0x40, /* Tramsmitter Empty */ + FIFOerr = 0x80, /* error in receiver FIFO */ +}; + +enum { /* Msr */ + Dcts = 0x01, /* Delta Cts */ + Ddsr = 0x02, /* Delta Dsr */ + Teri = 0x04, /* Trailing Edge of Ri */ + Ddcd = 0x08, /* Delta Dcd */ + Cts = 0x10, /* Clear To Send */ + Dsr = 0x20, /* Data Set Ready */ + Ri = 0x40, /* Ring Indicator */ + Dcd = 0x80, /* Data Set Ready */ +}; + +typedef struct Ctlr { + int io; + int irq; + int tbdf; + int iena; + + uchar sticky[8]; + + Lock; + int fifo; + int fena; +} Ctlr; + +extern PhysUart i8250physuart; + +static Ctlr i8250ctlr[2] = { +{ .io = Uart0, + .irq = Uart0IRQ, + .tbdf = BUSUNKNOWN, }, + +{ .io = Uart1, + .irq = Uart1IRQ, + .tbdf = BUSUNKNOWN, }, +}; + +static Uart i8250uart[2] = { +{ .regs = &i8250ctlr[0], + .name = "COM1", + .freq = UartFREQ, + .bits = 8, + .stop = 1, + .parity = 'n', + .baud = 9600, + .phys = &i8250physuart, + .special=0, + .next = &i8250uart[1], }, + +{ .regs = &i8250ctlr[1], + .name = "COM2", + .freq = UartFREQ, + .bits = 8, + .stop = 1, + .parity = 'n', + .baud = 9600, + .phys = &i8250physuart, + .special=0, + .next = nil, }, +}; + +static Uart* consuart; + +#define csr8r(c, r) inb((c)->io+(r)) +#define csr8w(c, r, v) outb((c)->io+(r), (c)->sticky[(r)]|(v)) + +static long +i8250status(Uart* uart, void* buf, long n, long offset) +{ + char *p; + Ctlr *ctlr; + uchar ier, lcr, mcr, msr; + + ctlr = uart->regs; + p = malloc(READSTR); + mcr = ctlr->sticky[Mcr]; + msr = csr8r(ctlr, Msr); + ier = ctlr->sticky[Ier]; + lcr = ctlr->sticky[Lcr]; + snprint(p, READSTR, + "b%d c%d d%d e%d l%d m%d p%c r%d s%d i%d\n" + "dev(%d) type(%d) framing(%d) overruns(%d)%s%s%s%s\n", + + uart->baud, + uart->hup_dcd, + (msr & Dsr) != 0, + uart->hup_dsr, + (lcr & WlsMASK) + 5, + (ier & Ems) != 0, + (lcr & Pen) ? ((lcr & Eps) ? 'e': 'o'): 'n', + (mcr & Rts) != 0, + (lcr & Stb) ? 2: 1, + ctlr->fena, + + uart->dev, + uart->type, + uart->ferr, + uart->oerr, + (msr & Cts) ? " cts": "", + (msr & Dsr) ? " dsr": "", + (msr & Dcd) ? " dcd": "", + (msr & Ri) ? " ring": "" + ); + n = readstr(offset, buf, n, p); + free(p); + + return n; +} + +static void +i8250fifo(Uart* uart, int on) +{ + int i; + Ctlr *ctlr; + + /* + * Toggle FIFOs: + * if none, do nothing; + * reset the Rx and Tx FIFOs; + * empty the Rx buffer and clear any interrupt conditions; + * if enabling, try to turn them on. + */ + ctlr = uart->regs; + + ilock(ctlr); + if(!ctlr->fifo){ + csr8w(ctlr, Fcr, FIFOtclr|FIFOrclr); + for(i = 0; i < 16; i++){ + csr8r(ctlr, Iir); + csr8r(ctlr, Rbr); + } + + ctlr->fena = 0; + if(on){ + csr8w(ctlr, Fcr, FIFO4|FIFOena); + if(!(csr8r(ctlr, Iir) & Ife)) + ctlr->fifo = 1; + ctlr->fena = 1; + } + } + iunlock(ctlr); +} + +static void +i8250dtr(Uart* uart, int on) +{ + Ctlr *ctlr; + + /* + * Toggle DTR. + */ + ctlr = uart->regs; + if(on) + ctlr->sticky[Mcr] |= Dtr; + else + ctlr->sticky[Mcr] &= ~Dtr; + csr8w(ctlr, Mcr, 0); +} + +static void +i8250rts(Uart* uart, int on) +{ + Ctlr *ctlr; + + /* + * Toggle RTS. + */ + ctlr = uart->regs; + if(on) + ctlr->sticky[Mcr] |= Rts; + else + ctlr->sticky[Mcr] &= ~Rts; + csr8w(ctlr, Mcr, 0); +} + +static void +i8250modemctl(Uart* uart, int on) +{ + Ctlr *ctlr; + + ctlr = uart->regs; + ilock(&uart->tlock); + if(on){ + ctlr->sticky[Ier] |= Ems; + csr8w(ctlr, Ier, 0); + uart->modem = 1; + uart->cts = csr8r(ctlr, Msr) & Cts; + } + else{ + ctlr->sticky[Ier] &= ~Ems; + csr8w(ctlr, Ier, 0); + uart->modem = 0; + uart->cts = 1; + } + iunlock(&uart->tlock); + + /* modem needs fifo */ + (*uart->phys->fifo)(uart, on); +} + +static int +i8250parity(Uart* uart, int parity) +{ + int lcr; + Ctlr *ctlr; + + ctlr = uart->regs; + lcr = ctlr->sticky[Lcr] & ~(Eps|Pen); + + switch(parity){ + case 'e': + lcr |= Eps|Pen; + break; + case 'o': + lcr |= Pen; + break; + case 'n': + default: + break; + } + ctlr->sticky[Lcr] = lcr; + csr8w(ctlr, Lcr, 0); + + uart->parity = parity; + + return 0; +} + +static int +i8250stop(Uart* uart, int stop) +{ + int lcr; + Ctlr *ctlr; + + ctlr = uart->regs; + lcr = ctlr->sticky[Lcr] & ~Stb; + + switch(stop){ + case 1: + break; + case 2: + lcr |= Stb; + break; + default: + return -1; + } + ctlr->sticky[Lcr] = lcr; + csr8w(ctlr, Lcr, 0); + + uart->stop = stop; + + return 0; +} + +static int +i8250bits(Uart* uart, int bits) +{ + int lcr; + Ctlr *ctlr; + + ctlr = uart->regs; + lcr = ctlr->sticky[Lcr] & ~WlsMASK; + + switch(bits){ + case 5: + lcr |= Wls5; + break; + case 6: + lcr |= Wls6; + break; + case 7: + lcr |= Wls7; + break; + case 8: + lcr |= Wls8; + break; + default: + return -1; + } + ctlr->sticky[Lcr] = lcr; + csr8w(ctlr, Lcr, 0); + + uart->bits = bits; + + return 0; +} + +static int +i8250baud(Uart* uart, int baud) +{ + ulong bgc; + Ctlr *ctlr; + + /* + * Set the baudrate by calculating and setting the baudrate + * generator constant. This will work with fairly non-standard + * baudrates. + */ + if(uart->freq == 0 || baud <= 0) + return -1; + bgc = (uart->freq+8*baud-1)/(16*baud); + + ctlr = uart->regs; + csr8w(ctlr, Lcr, Dlab); + outb(ctlr->io+Dlm, bgc>>8); + outb(ctlr->io+Dll, bgc); + csr8w(ctlr, Lcr, 0); + + uart->baud = baud; + + return 0; +} + +static void +i8250break(Uart* uart, int ms) +{ + Ctlr *ctlr; + + /* + * Send a break. + */ + if(ms == 0) + ms = 200; + + ctlr = uart->regs; + csr8w(ctlr, Lcr, Brk); + tsleep(&up->sleep, return0, 0, ms); + csr8w(ctlr, Lcr, 0); +} + +static void +i8250kick(Uart* uart) +{ + int i; + Ctlr *ctlr; + + if(uart->cts == 0 || uart->blocked) + return; + + /* + * 128 here is an arbitrary limit to make sure + * we don't stay in this loop too long. If the + * chip's output queue is longer than 128, too + * bad -- presotto + */ + ctlr = uart->regs; + for(i = 0; i < 128; i++){ + if(!(csr8r(ctlr, Lsr) & Thre)) + break; + if(uart->op >= uart->oe && uartstageoutput(uart) == 0) + break; + outb(ctlr->io+Thr, *(uart->op++)); + } +} + +static void +i8250interrupt(Ureg*, void* arg) +{ + Ctlr *ctlr; + Uart *uart; + int iir, old, r; + + uart = arg; + + ctlr = uart->regs; + for(iir = csr8r(ctlr, Iir); !(iir & Ip); iir = csr8r(ctlr, Iir)){ + switch(iir & IirMASK){ + case Ims: /* Ms interrupt */ + r = csr8r(ctlr, Msr); + if(r & Dcts){ + ilock(&uart->tlock); + old = uart->cts; + uart->cts = r & Cts; + if(old == 0 && uart->cts) + uart->ctsbackoff = 2; + iunlock(&uart->tlock); + } + if(r & Ddsr){ + old = r & Dsr; + if(uart->hup_dsr && uart->dsr && !old) + uart->dohup = 1; + uart->dsr = old; + } + if(r & Ddcd){ + old = r & Dcd; + if(uart->hup_dcd && uart->dcd && !old) + uart->dohup = 1; + uart->dcd = old; + } + break; + case Ithre: /* Thr Empty */ + uartkick(uart); + break; + case Irda: /* Received Data Available */ + case Ictoi: /* Character Time-out Indication */ + uartrecv(uart, csr8r(ctlr, Rbr)); + break; + case Irls: /* Receiver Line Status */ + r = csr8r(ctlr, Lsr); + if(r & Oe) + uart->oerr++; + if(r & Pe) + uart->perr++; + if(r & Fe) + uart->ferr++; + break; + default: + iprint("weird uart interrupt 0x%2.2uX\n", iir); + break; + } + } +} + +static void +i8250disable(Uart* uart) +{ + Ctlr *ctlr; + + /* + * Turn off DTR and RTS, disable interrupts and fifos. + */ + (*uart->phys->dtr)(uart, 0); + (*uart->phys->rts)(uart, 0); + (*uart->phys->fifo)(uart, 0); + + ctlr = uart->regs; + ctlr->sticky[Ier] = 0; + csr8w(ctlr, Ier, 0); +} + +static void +i8250enable(Uart* uart, int ie) +{ + Ctlr *ctlr; + + /* + * Enable interrupts and turn on DTR and RTS. + * Be careful if this is called to set up a polled serial line + * early on not to try to enable interrupts as interrupt- + * -enabling mechanisms might not be set up yet. + */ + ctlr = uart->regs; + if(ie){ + if(ctlr->iena == 0){ + intrenable(ctlr->irq, i8250interrupt, uart, ctlr->tbdf, uart->name); + ctlr->iena = 1; + } + ctlr->sticky[Ier] = Erls|Ethre|Erda; + ctlr->sticky[Mcr] |= Ie; + } + else{ + ctlr->sticky[Ier] = 0; + ctlr->sticky[Mcr] = 0; + } + csr8w(ctlr, Ier, ctlr->sticky[Ier]); + csr8w(ctlr, Mcr, ctlr->sticky[Mcr]); + + (*uart->phys->dtr)(uart, 1); + (*uart->phys->rts)(uart, 1); +} + +static Uart* +i8250pnp(void) +{ + return i8250uart; +} + +PhysUart i8250physuart = { + .name = "i8250", + .pnp = i8250pnp, + .enable = i8250enable, + .disable = i8250disable, + .kick = i8250kick, + .dobreak = i8250break, + .baud = i8250baud, + .bits = i8250bits, + .stop = i8250stop, + .parity = i8250parity, + .modemctl = i8250modemctl, + .rts = i8250rts, + .dtr = i8250dtr, + .status = i8250status, + .fifo = i8250fifo, +}; + +int +serialgetc(void) +{ + return -1; +} + +static void +i8250putc(Ctlr* ctlr, int c) +{ + int i; + + for(i = 0; i < 128; i++){ + if(csr8r(ctlr, Lsr) & Thre) + break; + delay(1); + } + outb(ctlr->io+Thr, c); +} + +static void +i8250puts(char* s, int n) +{ + Ctlr *ctlr; + Uart *uart; + + if((uart = consuart) == nil) + return; + + ctlr = uart->regs; + while(n--){ + if(*s == '\n') + i8250putc(ctlr, '\r'); + i8250putc(ctlr, *s++); + } +} + +void +i8250console(void) +{ + Uart *uart; + int n; + char *cmd, *p; + + if((p = getconf("console")) == nil) + return; + n = strtoul(p, &cmd, 0); + if(p == cmd) + return; + switch(n){ + default: + return; + case 0: + uart = &i8250uart[0]; + break; + case 1: + uart = &i8250uart[1]; + break; + } + + if(*cmd == 0) + cmd = "b9600 l8 pn s1"; + uartctl(uart, cmd); + (*uart->phys->enable)(uart, 0); + + consuart = uart; + serialputs = i8250puts; + uart->console = 1; +} diff --git a/pc/vga.c b/pc/vga.c index 682b6ee3cce3343055ab751a8410ee9eae255c34..daf77be4b082a82cc6593ac1a74055d3b32ac54c 100644 --- a/pc/vga.c +++ b/pc/vga.c @@ -218,19 +218,3 @@ vgablank(VGAscr*, int blank) vgaxo(Crtx, 0x17, crtc17); outs(Crtx, 0x0300); /* end synchronous reset */ } - -void -addvgaseg(char *name, ulong pa, ulong size) -{ - Physseg seg; - - memset(&seg, 0, sizeof seg); - seg.attr = SG_PHYSICAL; - /* can we just seg.name = name; ? */ - seg.name = smalloc(NAMELEN); - snprint(seg.name, NAMELEN, name); - seg.pa = pa; - seg.size = size; - addphysseg(&seg); -} - diff --git a/pc/vga3dfx.c b/pc/vga3dfx.c index 21e4dfd4d9cdfb3cd91b80ce38e09599d268ad49..7508e9ddb3545617211e6022116b06d90fff58ec 100644 --- a/pc/vga3dfx.c +++ b/pc/vga3dfx.c @@ -105,8 +105,7 @@ tdfxenable(VGAscr* scr) memset(&seg, 0, sizeof(seg)); seg.attr = SG_PHYSICAL; - seg.name = smalloc(NAMELEN); - snprint(seg.name, NAMELEN, "3dfxmmio"); + kstrdup(&seg.name, "3dfxmmio"); seg.pa = scr->io; seg.size = p->mem[0].size; addphysseg(&seg); @@ -119,8 +118,7 @@ tdfxenable(VGAscr* scr) scr->apsize = size; memset(&seg, 0, sizeof(seg)); seg.attr = SG_PHYSICAL; - seg.name = smalloc(NAMELEN); - snprint(seg.name, NAMELEN, "3dfxscreen"); + kstrdup(&seg.name, "3dfxscreen"); seg.pa = aperture; seg.size = size; addphysseg(&seg); diff --git a/pc/vgaclgd546x.c b/pc/vgaclgd546x.c index cca156235a7972b5614b08cca907d10dfb60dab9..6f5eafb0a273698690baa15e92519bd95941dd20 100644 --- a/pc/vgaclgd546x.c +++ b/pc/vgaclgd546x.c @@ -104,8 +104,7 @@ clgd546xenable(VGAscr* scr) memset(&seg, 0, sizeof(seg)); seg.attr = SG_PHYSICAL; - seg.name = smalloc(NAMELEN); - snprint(seg.name, NAMELEN, "clgd546xmmio"); + kstrdup(&seg.name, "clgd546xmmio"); seg.pa = scr->io; seg.size = p->mem[1].size; addphysseg(&seg); @@ -120,8 +119,7 @@ clgd546xenable(VGAscr* scr) scr->apsize = size; memset(&seg, 0, sizeof(seg)); seg.attr = SG_PHYSICAL; - seg.name = smalloc(NAMELEN); - snprint(seg.name, NAMELEN, "clgd546xscreen"); + kstrdup(&seg.name, "clgd546xscreen"); seg.pa = aperture; seg.size = size; addphysseg(&seg); diff --git a/pc/vgacyber938x.c b/pc/vgacyber938x.c index 7c86679c5acbc20c25e9afbe2608efbdfb6b08cf..00cd74faf7e06de9386a8cfb97124a3ea1fd01f8 100644 --- a/pc/vgacyber938x.c +++ b/pc/vgacyber938x.c @@ -43,27 +43,18 @@ cyber938xlinear(VGAscr* scr, int* size, int* align) { ulong aperture, oaperture; int oapsize, wasupamem; - int osize; Pcidev *p; - osize = *size; oaperture = scr->aperture; oapsize = scr->apsize; wasupamem = scr->isupamem; if(wasupamem) upafree(oaperture, oapsize); scr->isupamem = 0; - scr->mmio = 0; if(p = pcimatch(nil, 0x1023, 0)){ aperture = p->mem[0].bar & ~0x0F; *size = p->mem[0].size; - /* - * Heuristic to detect the MMIO space. We're flying blind - * here, with only the XFree86 source to guide us. - */ - if(p->mem[1].size == 0x20000) - scr->mmio = (ulong*)(p->mem[1].bar & ~0x0F); } else aperture = 0; @@ -76,11 +67,6 @@ cyber938xlinear(VGAscr* scr, int* size, int* align) else scr->isupamem = 1; - if(aperture) - addvgaseg("cyber938xscreen", aperture, osize); - if(scr->mmio) - addvgaseg("cyber938xmmio", (ulong)scr->mmio, 0x20000); - return aperture; } @@ -208,11 +194,10 @@ cyber938xcurenable(VGAscr* scr) VGAdev vgacyber938xdev = { "cyber938x", - nil, /* enable */ - nil, /* disable */ + 0, /* enable */ + 0, /* disable */ cyber938xpage, /* page */ cyber938xlinear, /* linear */ - nil, /* drawinit */ }; VGAcur vgacyber938xcur = { diff --git a/pc/vgahiqvideo.c b/pc/vgahiqvideo.c index 7f206fd64dcdaa3be5a039241cb1d10ecf353e21..d0d905cddaadcfeffbf0905334c519b0eb5eba26 100644 --- a/pc/vgahiqvideo.c +++ b/pc/vgahiqvideo.c @@ -126,8 +126,7 @@ hiqvideoenable(VGAscr* scr) scr->apsize = size; memset(&seg, 0, sizeof(seg)); seg.attr = SG_PHYSICAL; - seg.name = smalloc(NAMELEN); - snprint(seg.name, NAMELEN, "hiqvideoscreen"); + kstrdup(&seg.name, "hiqvideoscreen"); seg.pa = aperture; seg.size = size; addphysseg(&seg); diff --git a/pc/vgamach64xx.c b/pc/vgamach64xx.c index 7a7b7da523ca54caf7a69a7a37087244b8e2277b..bebdf33a46c82a8a34d1986341c206af0530f463 100644 --- a/pc/vgamach64xx.c +++ b/pc/vgamach64xx.c @@ -12,131 +12,30 @@ #include #include "screen.h" -char Eunsupportedformat[] = "unsupported video format"; -char Enotconfigured[] = "device not configured"; - -#define SCALE_ZERO_EXTEND 0x0 -#define SCALE_DYNAMIC 0x1 -#define SCALE_RED_TEMP_6500K 0x0 -#define SCALE_RED_TEMP_9800K 0x2 -#define SCALE_HORZ_BLEND 0x0 -#define SCALE_HORZ_REP 0x4 -#define SCALE_VERT_BLEND 0x0 -#define SCALE_VERT_REP 0x8 -#define SCALE_BANDWIDTH_NORMAL 0x0 -#define SCALE_BANDWIDTH_EXCEEDED 0x4000000 -#define SCALE_BANDWIDTH_RESET 0x4000000 -#define SCALE_CLK_ACTIVITY 0x0 -#define SCALE_CLK_CONTINUOUS 0x20000000 -#define OVERLAY_DISABLE 0x0 -#define OVERLAY_ENABLE 0x40000000 -#define SCALE_DISABLE 0x0 -#define SCALE_ENABLE 0x80000000 - -#define SCALER_FRAME_READ_MODE_FULL 0x0 -#define SCALER_BUF_MODE_SINGLE 0x0 -#define SCALER_BUF_MODE_DOUBLE 0x40000 -#define SCALER_BUF_NEXT_0 0x0 -#define SCALER_BUF_NEXT_1 0x80000 -#define SCALER_BUF_STATUS_0 0x0 -#define SCALER_BUF_STATUS_1 0x100000 - -#define OVERLAY_MIX_G_CMP 0x0 -#define OVERLAY_MIX_ALWAYS_G 0x100 -#define OVERLAY_MIX_ALWAYS_V 0x200 -#define OVERLAY_MIX_NOT_G 0x300 -#define OVERLAY_MIX_NOT_V 0x400 -#define OVERLAY_MIX_G_XOR_V 0x500 -#define OVERLAY_MIX_NOT_G_XOR_V 0x600 -#define OVERLAY_MIX_V_CMP 0x700 -#define OVERLAY_MIX_NOT_G_OR_NOT_V 0x800 -#define OVERLAY_MIX_G_OR_NOT_V 0x900 -#define OVERLAY_MIX_NOT_G_OR_V 0xA00 -#define OVERLAY_MIX_G_OR_V 0xB00 -#define OVERLAY_MIX_G_AND_V 0xC00 -#define OVERLAY_MIX_NOT_G_AND_V 0xD00 -#define OVERLAY_MIX_G_AND_NOT_V 0xE00 -#define OVERLAY_MIX_NOT_G_AND_NOT_V 0xF00 -#define OVERLAY_EXCLUSIVE_NORMAL 0x0 -#define OVERLAY_EXCLUSIVE_V_ONLY 0x80000000 - -#define VIDEO_IN_8BPP 0x2 -#define VIDEO_IN_16BPP 0x4 -#define VIDEO_IN_32BPP 0x6 -#define VIDEO_IN_VYUY422 0xB /*16 bpp */ -#define VIDEO_IN_YVYU422 0xC /* 16 bpp */ -#define SCALE_IN_15BPP 0x30000 /* aRGB 1555 */ -#define SCALE_IN_16BPP 0x40000 /* RGB 565 */ -#define SCALE_IN_32BPP 0x60000 /* aRGB 8888 */ -#define SCALE_IN_YUV9 0x90000 /* planar */ -#define SCALE_IN_YUV12 0xA0000 /* planar */ -#define SCALE_IN_VYUY422 0xB0000 /* 16 bpp */ -#define SCALE_IN_YVYU422 0xC0000 /* 16 bpp */ -#define HOST_YUV_APERTURE_UPPER 0x0 -#define HOST_YUV_APERTURE_LOWER 0x20000000 -#define HOST_MEM_MODE_Y 0x40000000 -#define HOST_MEM_MODE_U 0x80000000 -#define HOST_MEM_MODE_V 0xC0000000 -#define HOST_MEM_MODE_NORMAL HOST_YUV_APERTURE_UPPER - -static Chan *ovl_chan; /* Channel of controlling process */ -static int ovl_width; /* Width of input overlay buffer */ -static int ovl_height; /* Height of input overlay buffer */ -static int ovl_format; /* Overlay format */ -static ulong ovl_fib; /* Frame in bytes */ - -enum { - VTGTB1S1 = 0x01, // Asic description for VTB1S1 and GTB1S1. - VT4GTIIC = 0x3A, // asic descr for VT4 and RAGE IIC - GTB1U1 = 0x19, // Asic description for GTB1U1. - GTB1S2 = 0x41, // Asic description for GTB1S2. - GTB2U1 = 0x1A, - GTB2U2 = 0x5A, - GTB2U3 = 0x9A, - GTIIIC1U1 = 0x1B, // 3D RAGE PRO asic descrp. - GTIIIC1U2 = 0x5B, // 3D RAGE PRO asic descrp. - GTIIIC2U1 = 0x1C, // 3D RAGE PRO asic descrp. - GTIIIC2U2 = 0x5C, // 3D RAGE PRO asic descrp. - GTIIIC2U3 = 0x7C, // 3D RAGE PRO asic descrp. - GTBC = 0x3A, // 3D RAGE IIC asic descrp. - LTPRO = 0x9C, // 3D RAGE LT PRO -}; - /* * ATI Mach64(CT|ET|G*|V*|L*). */ -typedef struct { - ushort m64_id; /* Chip ID */ - int m64_vtgt; /* Is this a VT or GT chipset? */ - double m64_ovlclock; /* Max. overlay clock frequency */ - int m64_pro; /* Is this a PRO? */ -} mach64types; - -static double mach64refclock; -static mach64types *mach64type; -static int mach64revb; /* Revision B or greater? */ -static ulong mach64overlay; /* Overlay buffer */ - -static mach64types mach64s[] = { - ('C'<<8)|'T', 0, 0., 0, /* 4354: CT */ - ('E'<<8)|'T', 0, 0., 0, /* 4554: ET */ - ('G'<<8)|'B', 1, 125., 1, /* 4742: 264GT PRO */ - ('G'<<8)|'D', 1, 125., 1, /* 4744: 264GT PRO */ - ('G'<<8)|'I', 1, 125., 1, /* 4749: 264GT PRO */ - ('G'<<8)|'M', 0, 135., 0, /* 474D: Rage XL */ - ('G'<<8)|'P', 1, 125., 1, /* 4750: 264GT PRO */ - ('G'<<8)|'Q', 1, 125., 1, /* 4751: 264GT PRO */ - ('G'<<8)|'T', 1, 80., 0, /* 4754: 264GT[B] */ - ('G'<<8)|'U', 1, 100., 0, /* 4755: 264GT DVD */ - ('G'<<8)|'V', 1, 100., 0, /* 4756: Rage2C */ - ('G'<<8)|'Z', 1, 100., 0, /* 475A: Rage2C */ - ('V'<<8)|'T', 1, 80., 0, /* 5654: 264VT/GT/VTB */ - ('V'<<8)|'U', 1, 80., 0, /* 5655: 264VT3 */ - ('V'<<8)|'V', 1, 100., 0, /* 5656: 264VT4 */ - ('L'<<8)|'B', 0, 135., 1, /* 4C42: Rage LTPro AGP */ - ('L'<<8)|'I', 0, 135., 0, /* 4C49: Rage LTPro AGP */ - ('L'<<8)|'M', 0, 135., 0, /* 4C4D: Rage Mobility */ - ('L'<<8)|'P', 0, 135., 1, /* 4C50: 264LT PRO */ +static ushort mach64xxdid[] = { + ('C'<<8)|'T', + ('E'<<8)|'T', + ('G'<<8)|'B', + ('G'<<8)|'D', + ('G'<<8)|'I', + ('G'<<8)|'M', + ('G'<<8)|'P', + ('G'<<8)|'Q', + ('G'<<8)|'T', + ('G'<<8)|'U', + ('G'<<8)|'V', + ('G'<<8)|'Z', + ('V'<<8)|'T', + ('V'<<8)|'U', + ('V'<<8)|'V', + ('L'<<8)|'B', + ('L'<<8)|'I', + ('L'<<8)|'M', + ('L'<<8)|'P', + 0, }; static int hwfill(VGAscr*, Rectangle, ulong); @@ -147,16 +46,15 @@ static Pcidev* mach64xxpci(void) { Pcidev *p; - int i; + ushort *did; if((p = pcimatch(nil, 0x1002, 0)) == nil) return nil; - - for (i = 0; i != nelem(mach64s); i++) - if (mach64s[i].m64_id == p->did) { - mach64type = &mach64s[i]; + for(did = mach64xxdid; *did; did++){ + if(*did == p->did) return p; - } + } + return nil; } @@ -172,7 +70,6 @@ mach64xxenable(VGAscr* scr) return; if(p = mach64xxpci()){ scr->id = p->did; - // iprint("mach64xxenable: found x%.4X\n", p->did); /* * The CT doesn't always have the I/O base address @@ -233,14 +130,12 @@ mach64xxlinear(VGAscr* scr, int* size, int* align) print("warning (BUG): redefinition of aperture does not change mach64mmio segment\n"); memset(&seg, 0, sizeof(seg)); seg.attr = SG_PHYSICAL; - seg.name = smalloc(NAMELEN); - snprint(seg.name, NAMELEN, "mach64mmio"); + kstrdup(&seg.name, "mach64mmio"); seg.pa = aperture+osize - BY2PG; seg.size = BY2PG; addphysseg(&seg); - seg.name = smalloc(NAMELEN); - snprint(seg.name, NAMELEN, "mach64screen"); + kstrdup(&seg.name, "mach64screen"); seg.pa = aperture; seg.size = osize; addphysseg(&seg); @@ -303,29 +198,6 @@ enum { SrcOffPitch, LcdIndex, LcdData, - ClockCntl, - OverlayScaleCntl, - ConfigChipId, - Buf0Pitch, - ScalerBuf0Pitch, - CaptureConfig, - OverlayKeyCntl, - ScalerColourCntl, - ScalerHCoef0, - ScalerHCoef1, - ScalerHCoef2, - ScalerHCoef3, - ScalerHCoef4, - VideoFormat, - Buf0Offset, - ScalerBuf0Offset, - CrtcGenCntl, - OverlayScaleInc, - OverlayYX, - OverlayYXEnd, - ScalerHeightWidth, - HTotalDisp, - VTotalDisp, }; enum { @@ -342,83 +214,56 @@ enum { Nlcd, }; -#define Bank1 (-0x100) /* 1KB */ - -static int mmoffset[] = { - [HTotalDisp] 0x00, - [VTotalDisp] 0x02, - [CrtcOffPitch] 0x05, - [CrtcGenCntl] 0x07, - [CurClr0] 0x18, - [CurClr1] 0x19, - [CurOffset] 0x1A, - [CurHVposn] 0x1B, - [CurHVoff] 0x1C, - [ClockCntl] 0x24, - [BusCntl] 0x28, - [LcdIndex] 0x29, - [LcdData] 0x2A, - [GenTestCntl] 0x34, - [ConfigChipId] 0x38, - [DstOffPitch] 0x40, - [DstYX] 0x43, - [DstHeight] 0x45, +static uchar mmoffset[] = { + [CrtcOffPitch] 0x05, + [CurClr0] 0x18, + [CurClr1] 0x19, + [CurOffset] 0x1A, + [CurHVposn] 0x1B, + [CurHVoff] 0x1C, + [BusCntl] 0x28, + [LcdIndex] 0x29, + [LcdData] 0x2A, + [GenTestCntl] 0x34, + [DstOffPitch] 0x40, + [DstYX] 0x43, + [DstHeight] 0x45, [DstHeightWidth] 0x46, - [DstBresErr] 0x49, - [DstBresInc] 0x4A, - [DstBresDec] 0x4B, - [DstCntl] 0x4C, - [SrcOffPitch] 0x60, - [SrcYX] 0x63, - [SrcWidth1] 0x64, - [SrcYXstart] 0x69, + [DstBresErr] 0x49, + [DstBresInc] 0x4A, + [DstBresDec] 0x4B, + [DstCntl] 0x4C, + [SrcOffPitch] 0x60, + [SrcYX] 0x63, + [SrcWidth1] 0x64, + [SrcYXstart] 0x69, [SrcHeight1Width1] 0x66, [SrcHeight2Width2] 0x6C, - [SrcCntl] 0x6D, - [HostCntl] 0x90, - [PatReg0] 0xA0, - [PatReg1] 0xA1, - [PatCntl] 0xA2, - [ScLeft] 0xA8, - [ScRight] 0xA9, - [ScLeftRight] 0xAA, - [ScTop] 0xAB, - [ScBottom] 0xAC, - [ScTopBottom] 0xAD, - [DpBkgdClr] 0xB0, - [DpFrgdClr] 0xB1, - [DpWriteMask] 0xB2, - [DpChainMask] 0xB3, - [DpPixWidth] 0xB4, - [DpMix] 0xB5, - [DpSrc] 0xB6, - [ClrCmpClr] 0xC0, - [ClrCmpMask] 0xC1, - [ClrCmpCntl] 0xC2, - [FifoStat] 0xC4, - [ContextMask] 0xC8, - [GuiTrajCntl] 0xCC, - [GuiStat] 0xCE, - - /* Bank1 */ - [OverlayYX] Bank1 + 0x00, - [OverlayYXEnd] Bank1 + 0x01, - [OverlayKeyCntl] Bank1 + 0x06, - [OverlayScaleInc] Bank1 + 0x08, - [OverlayScaleCntl] Bank1 + 0x09, - [ScalerHeightWidth] Bank1 + 0x0A, - [ScalerBuf0Offset] Bank1 + 0x0D, - [ScalerBuf0Pitch] Bank1 + 0x0F, - [VideoFormat] Bank1 + 0x12, - [CaptureConfig] Bank1 + 0x14, - [Buf0Offset] Bank1 + 0x20, - [Buf0Pitch] Bank1 + 0x23, - [ScalerColourCntl] Bank1 + 0x54, - [ScalerHCoef0] Bank1 + 0x55, - [ScalerHCoef1] Bank1 + 0x56, - [ScalerHCoef2] Bank1 + 0x57, - [ScalerHCoef3] Bank1 + 0x58, - [ScalerHCoef4] Bank1 + 0x59, + [SrcCntl] 0x6D, + [HostCntl] 0x90, + [PatReg0] 0xA0, + [PatReg1] 0xA1, + [PatCntl] 0xA2, + [ScLeft] 0xA8, + [ScRight] 0xA9, + [ScLeftRight] 0xAA, + [ScTop] 0xAB, + [ScBottom] 0xAC, + [ScTopBottom] 0xAD, + [DpBkgdClr] 0xB0, + [DpFrgdClr] 0xB1, + [DpWriteMask] 0xB2, + [DpChainMask] 0xB3, + [DpPixWidth] 0xB4, + [DpMix] 0xB5, + [DpSrc] 0xB6, + [ClrCmpClr] 0xC0, + [ClrCmpMask] 0xC1, + [ClrCmpCntl] 0xC2, + [FifoStat] 0xC4, + [ContextMask] 0xC8, + [GuiTrajCntl] 0xCC, + [GuiStat] 0xCE, }; static ulong @@ -511,7 +356,7 @@ mach64xxcurload(VGAscr* scr, Cursor* curs) if(s & (1<<(15-i))) m |= 0x01<<(2*i); else if(c & (1<<(15-i))){ - /* noting to do */ + /* nothing to do */ } else m |= 0x02<<(2*i); @@ -698,47 +543,10 @@ resetengine(VGAscr *scr) iow32(scr, BusCntl, ior32(scr, BusCntl)|0x00A00000); } -static void -init_overlayclock(VGAscr *scr) -{ - uchar *cc, save, pll_ref_div, pll_vclk_cntl, vclk_post_div, - vclk_fb_div, ecp_div; - int i; - double dotclock; - - /* Taken from GLX */ - /* Get monitor dotclock, check for Overlay Scaler clock limit */ - cc = (uchar *)&scr->mmio[mmoffset[ClockCntl]]; - save = cc[1]; i = cc[0] & 3; - cc[1] = 2<<2; pll_ref_div = cc[2]; - cc[1] = 5<<2; pll_vclk_cntl = cc[2]; - cc[1] = 6<<2; vclk_post_div = (cc[2]>>(i+i)) & 3; - cc[1] = (7+i)<<2; vclk_fb_div = cc[2]; - - dotclock = 2.0 * mach64refclock * vclk_fb_div / - (pll_ref_div * (1 << vclk_post_div)); - /* ecp_div: 0=dotclock, 1=dotclock/2, 2=dotclock/4 */ - ecp_div = dotclock / mach64type->m64_ovlclock; - if (ecp_div>2) ecp_div = 2; - - /* Force a scaler clock factor of 1 if refclock * - * is unknown (VCLK_SRC not PLLVCLK) */ - if ((pll_vclk_cntl & 0x03) != 0x03) dotclock = ecp_div = 0; - if ((pll_vclk_cntl & 0x30) != ecp_div<<4) { - cc[1] = (5<<2)|2; - cc[2] = (pll_vclk_cntl&0xCF) | (ecp_div<<4); - } - - /* Restore PLL Register Index */ - cc[1] = save; -} - static void initengine(VGAscr *scr) { ulong pitch; - uchar *bios; - ushort table; pitch = Dx(scr->gscreen->r)/8; if(scr->gscreen->depth == 24) @@ -798,52 +606,7 @@ initengine(VGAscr *scr) break; } - /* Get the base freq from the BIOS */ - bios = KADDR(0xC000); - table = *(ushort *)(bios + 0x48); - table = *(ushort *)(bios + table + 0x10); - switch (*(ushort *)(bios + table + 0x08)) { - case 2700: - mach64refclock = 27.0; - break; - case 2863: - case 2864: - mach64refclock = 28.63636; - break; - case 2950: - mach64refclock = 29.498928713; - break; - case 1432: - default: - mach64refclock = 14.31818; - break ; - } - - /* Figure out which revision this chip is */ - switch ((scr->mmio[mmoffset[ConfigChipId]] >> 24) & 0xFF) { - case VTGTB1S1: - case GTB1U1: - case GTB1S2: - case GTB2U1: - case GTB2U2: - case GTB2U3: - case GTBC: - case GTIIIC1U1: - case GTIIIC1U2: - case GTIIIC2U1: - case GTIIIC2U2: - case GTIIIC2U3: - case LTPRO: - mach64revb = 1; - break; - default: - mach64revb = 0; - break; - } - - init_overlayclock(scr); waitforidle(scr); - } static int @@ -997,7 +760,7 @@ mach64lcdblank(VGAscr *scr, int blank) static void mach64xxdrawinit(VGAscr *scr) -{ +{ if(scr->io > 0x2FF){ initengine(scr); scr->fill = mach64hwfill; @@ -1016,216 +779,14 @@ mach64xxdrawinit(VGAscr *scr) } } -static void -ovl_configure(VGAscr *scr, Chan *c, int nfields, char **field) -{ - int w, h; - char *format; - - if (nfields != 4) error(Ebadarg); - - w = (int)strtol(field[1], nil, 0); - h = (int)strtol(field[2], nil, 0); - format = field[3]; - - if (c != ovl_chan) error(Einuse); - if (strcmp(format, "YUYV")) - error(Eunsupportedformat); - - ovl_width = w; - ovl_height = h; - ovl_fib = w * h * sizeof(ushort); - - waitforidle(scr); - scr->mmio[mmoffset[BusCntl]] |= 0x08000000; /* Enable regblock 1 */ - scr->mmio[mmoffset[OverlayScaleCntl]] = - SCALE_ZERO_EXTEND|SCALE_RED_TEMP_6500K| - SCALE_HORZ_BLEND|SCALE_VERT_BLEND; - scr->mmio[mmoffset[!mach64revb? Buf0Pitch: ScalerBuf0Pitch]] = w; - scr->mmio[mmoffset[CaptureConfig]] = - SCALER_FRAME_READ_MODE_FULL| - SCALER_BUF_MODE_SINGLE| - SCALER_BUF_NEXT_0; - scr->mmio[mmoffset[OverlayKeyCntl]] = !mach64revb? - OVERLAY_MIX_ALWAYS_V|(OVERLAY_EXCLUSIVE_NORMAL << 28): - 0x011; - - if (mach64type->m64_pro) { - waitforfifo(scr, 6); - - /* set the scaler co-efficient registers */ - scr->mmio[mmoffset[ScalerColourCntl]] = - (0x00) | (0x10 << 8) | (0x10 << 16); - scr->mmio[mmoffset[ScalerHCoef0]] = - (0x00) | (0x20 << 8); - scr->mmio[mmoffset[ScalerHCoef1]] = - (0x0D) | (0x20 << 8) | (0x06 << 16) | (0x0D << 24); - scr->mmio[mmoffset[ScalerHCoef2]] = - (0x0D) | (0x1C << 8) | (0x0A << 16) | (0x0D << 24); - scr->mmio[mmoffset[ScalerHCoef3]] = - (0x0C) | (0x1A << 8) | (0x0E << 16) | (0x0C << 24); - scr->mmio[mmoffset[ScalerHCoef4]] = - (0x0C) | (0x14 << 8) | (0x14 << 16) | (0x0C << 24); - } - - waitforfifo(scr, 3); - scr->mmio[mmoffset[VideoFormat]] = SCALE_IN_YVYU422 | - (!mach64revb? 0xC: 0); - - if (mach64overlay == 0) - mach64overlay = scr->storage + 64 * 64 * sizeof(uchar); - scr->mmio[mmoffset[!mach64revb? Buf0Offset: ScalerBuf0Offset]] = - mach64overlay; -} - -static void -ovl_enable(VGAscr *scr, Chan *c, int nfields, char **field) -{ - int x, y, w, h; - long h_inc, v_inc; - - if (nfields != 5) error(Ebadarg); - - x = (int)strtol(field[1], nil, 0); - y = (int)strtol(field[2], nil, 0); - w = (int)strtol(field[3], nil, 0); - h = (int)strtol(field[4], nil, 0); - - if (x < 0 || x + w > physgscreenr.max.x || - y < 0 || y + h > physgscreenr.max.y) - error(Ebadarg); - - if (c != ovl_chan) error(Einuse); - if (scr->mmio[mmoffset[CrtcGenCntl]] & 1) { /* double scan enable */ - y *= 2; - h *= 2; - } - - waitforfifo(scr, 2); - scr->mmio[mmoffset[OverlayYX]] = - ((x & 0xFFFF) << 16) | (y & 0xFFFF); - scr->mmio[mmoffset[OverlayYXEnd]] = - (((x + w) & 0xFFFF) << 16) | ((y + h) & 0xFFFF); - - h_inc = (ovl_width << 12) / (w >> 1); /* ??? */ - v_inc = (ovl_height << 12) / h; - waitforfifo(scr, 2); - scr->mmio[mmoffset[OverlayScaleInc]] = - ((h_inc & 0xFFFF) << 16) | (v_inc & 0xFFFF); - scr->mmio[mmoffset[ScalerHeightWidth]] = - ((ovl_width & 0xFFFF) << 16) | (ovl_height & 0xFFFF); - waitforidle(scr); - scr->mmio[mmoffset[OverlayScaleCntl]] |= - (SCALE_ENABLE|OVERLAY_ENABLE); -} - -static void -ovl_status(VGAscr *scr, Chan *, int nfields, char **field) -{ - if (nfields != 1) error(Ebadarg); - - pprint("%s: %s %.4uX, VT/GT %s, PRO %s, ovlclock %d, rev B %s, refclock %d\n", - scr->dev->name, field[0], mach64type->m64_id, - mach64type->m64_vtgt? "yes": "no", - mach64type->m64_pro? "yes": "no", - (int)(mach64type->m64_ovlclock * 10000.), - mach64revb? "yes": "no", - (int)(mach64refclock * 10000.)); - pprint("%s: storage @%.8luX, aperture @%8.ulX, ovl buf @%.8ulX\n", - scr->dev->name, scr->storage, scr->aperture, - mach64overlay); -} - -static void -ovl_openctl(VGAscr *, Chan *c, int nfields, char **) -{ - if (nfields != 1) error(Ebadarg); - if (ovl_chan) error(Einuse); - ovl_chan = c; -} - -static void -ovl_closectl(VGAscr *scr, Chan *c, int nfields, char **) -{ - if (c != ovl_chan || nfields != 1) return; - - waitforidle(scr); - scr->mmio[mmoffset[OverlayScaleCntl]] &= - ~(SCALE_ENABLE|OVERLAY_ENABLE); - ovl_chan = nil; - ovl_width = ovl_height = ovl_fib = 0; -} - -static struct { - char *ovl_command; - void (*ovl_f)(VGAscr *, Chan *, int, char **); -} ovl_cmds[] = { - { "openctl", ovl_openctl }, - { "configure", ovl_configure, }, - { "enable", ovl_enable, }, - { "closectl", ovl_closectl }, - { "status", ovl_status }, -}; - -static void -mach64xxovlctl(VGAscr *scr, Chan *c, void *a, int) -{ -#define MAXARGS 10 - char *field[MAXARGS]; - int nfields, i; - - if (!mach64type->m64_vtgt) error(Enodev); - - nfields = getfields(a, field, nelem(field), 1, "\t\n\r "); - if (nfields < 1) error(Ebadarg); - - for (i = 0; i != nelem(ovl_cmds); i++) - if (!strcmp(field[0], ovl_cmds[i].ovl_command)) - break; - - if (i == nelem(ovl_cmds)) - error(Ebadarg); - - ovl_cmds[i].ovl_f(scr, c, nfields, field); -} - -static int -mach64xxovlwrite(VGAscr *scr, void *a, int len, vlong offs) -{ - uchar *src; - int _len; - - if (ovl_chan == nil) return len; /* Acts as a /dev/null */ - - /* Calculate the destination address */ - _len = len; - src = (uchar *)a; - while (len > 0) { - ulong _offs; - int nb; - - _offs = (ulong)(offs % ovl_fib); - nb = (_offs + len > ovl_fib)? ovl_fib - _offs: len; - memmove((uchar *)KADDR(scr->aperture + mach64overlay + _offs), - src, nb); - offs += nb; - src += nb; - len -= nb; - } - return _len; -} - VGAdev vgamach64xxdev = { "mach64xx", - mach64xxenable, /* enable */ + mach64xxenable, /* enable */ 0, /* disable */ 0, /* page */ - mach64xxlinear, /* linear */ + mach64xxlinear, /* linear */ mach64xxdrawinit, /* drawinit */ - 0, - mach64xxovlctl, /* overlay control */ - mach64xxovlwrite, /* write the overlay */ }; VGAcur vgamach64xxcur = { diff --git a/pc/vgamga2164w.c b/pc/vgamga2164w.c index b9ebe0353ba3bf4754e2b9b2cafd29be8057896d..3123801c454522657c05752be23b968ab90754c8 100644 --- a/pc/vgamga2164w.c +++ b/pc/vgamga2164w.c @@ -109,8 +109,7 @@ mga2164wenable(VGAscr* scr) memset(&seg, 0, sizeof(seg)); seg.attr = SG_PHYSICAL; - seg.name = smalloc(NAMELEN); - snprint(seg.name, NAMELEN, "mga2164wmmio"); + kstrdup(&seg.name, "mga2164wmmio"); seg.pa = scr->io; seg.size = p->mem[immio].size; addphysseg(&seg); @@ -126,8 +125,7 @@ mga2164wenable(VGAscr* scr) scr->apsize = size; memset(&seg, 0, sizeof(seg)); seg.attr = SG_PHYSICAL; - seg.name = smalloc(NAMELEN); - snprint(seg.name, NAMELEN, "mga2164wscreen"); + kstrdup(&seg.name, "mga2164wscreen"); seg.pa = aperture; seg.size = size; addphysseg(&seg); diff --git a/pc/vganeomagic.c b/pc/vganeomagic.c index 230a5c22ce793515dfd1f7747fc706bfb2ec6f7d..c9b98010147ba917b82d14ebe5d46e9ee8549b4b 100644 --- a/pc/vganeomagic.c +++ b/pc/vganeomagic.c @@ -110,8 +110,7 @@ neomagicenable(VGAscr* scr) memset(&seg, 0, sizeof(seg)); seg.attr = SG_PHYSICAL; - seg.name = smalloc(NAMELEN); - snprint(seg.name, NAMELEN, "neomagicmmio"); + kstrdup(&seg.name, "neomagicmmio"); seg.pa = scr->io; seg.size = p->mem[1].size; addphysseg(&seg); @@ -132,8 +131,7 @@ neomagicenable(VGAscr* scr) scr->apsize = size; memset(&seg, 0, sizeof(seg)); seg.attr = SG_PHYSICAL; - seg.name = smalloc(NAMELEN); - snprint(seg.name, NAMELEN, "neomagicscreen"); + kstrdup(&seg.name, "neomagicscreen"); seg.pa = aperture; seg.size = size; addphysseg(&seg); diff --git a/pc/vgas3.c b/pc/vgas3.c index 505e1231f1ddbacfc0ace61f9e1c1a1834e4a9a6..b2b29c11c2e0f15b0855c81adda685c2dafeb3c7 100644 --- a/pc/vgas3.c +++ b/pc/vgas3.c @@ -100,18 +100,7 @@ s3linear(VGAscr* scr, int* size, int* align) mmiosize = 0; mmiobase = 0; mmioname = nil; - - /* - * S3 makes cards other than display controllers, so - * look for the first S3 display controller (device class 3) - * and not one of their sound cards. - */ - p = nil; - while(p = pcimatch(p, PCIS3, 0)){ - if(p->ccrb == 0x03) - break; - } - if(p != nil){ + if(p = pcimatch(nil, PCIS3, 0)){ for(i=0; imem); i++){ if(p->mem[i].size >= *size && ((p->mem[i].bar & ~0x0F) & (*align-1)) == 0) @@ -170,8 +159,7 @@ s3linear(VGAscr* scr, int* size, int* align) print("warning (BUG): redefinition of aperture does not change s3screen segment\n"); memset(&seg, 0, sizeof(seg)); seg.attr = SG_PHYSICAL; - seg.name = smalloc(NAMELEN); - snprint(seg.name, NAMELEN, "s3screen"); + kstrdup(&seg.name, "s3screen"); seg.pa = aperture; seg.size = osize; addphysseg(&seg); @@ -179,8 +167,7 @@ s3linear(VGAscr* scr, int* size, int* align) if(mmiosize){ memset(&seg, 0, sizeof(seg)); seg.attr = SG_PHYSICAL; - seg.name = smalloc(NAMELEN); - snprint(seg.name, NAMELEN, mmioname); + kstrdup(&seg.name, mmioname); seg.pa = mmiobase; seg.size = mmiosize; addphysseg(&seg); diff --git a/pc/vgat2r4.c b/pc/vgat2r4.c index 629e28f25decd409c793e45105e24ba8d8baa5e6..9f2153bf5090866417bb8ab26d860cd29e0b9aa9 100644 --- a/pc/vgat2r4.c +++ b/pc/vgat2r4.c @@ -132,8 +132,7 @@ t2r4enable(VGAscr* scr) memset(&seg, 0, sizeof(seg)); seg.attr = SG_PHYSICAL; - seg.name = smalloc(NAMELEN); - snprint(seg.name, NAMELEN, "t2r4mmio"); + kstrdup(&seg.name, "t2r4mmio"); seg.pa = mmio; seg.size = p->mem[4].size; addphysseg(&seg); @@ -148,8 +147,7 @@ t2r4enable(VGAscr* scr) scr->apsize = size; memset(&seg, 0, sizeof(seg)); seg.attr = SG_PHYSICAL; - seg.name = smalloc(NAMELEN); - snprint(seg.name, NAMELEN, "t2r4screen"); + kstrdup(&seg.name, "t2r4screen"); seg.pa = aperture; seg.size = size; addphysseg(&seg); diff --git a/port/allocb.c b/port/allocb.c index 6d74b7472803ae8bd9137093eb61bc04b08f994d..615e7d93e06b6a5c748215e1032bd00bac6d07fe 100644 --- a/port/allocb.c +++ b/port/allocb.c @@ -4,7 +4,6 @@ #include "dat.h" #include "fns.h" #include "error.h" -#include "pool.h" enum { diff --git a/port/auth.c b/port/auth.c index b4a8450d7f890ac69cf3587eb1a3ad09236e79f4..bc034d7bf8519fd3b95f1f586ad9e912287da4d5 100644 --- a/port/auth.c +++ b/port/auth.c @@ -5,36 +5,9 @@ #include "fns.h" #include "../port/error.h" -typedef struct Crypt Crypt; -struct Crypt -{ - Crypt *next; - Ticket t; - Authenticator a; - 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 -{ - Lock; - Crypt *free; -} cryptalloc; +#include -char eve[NAMELEN]; +char *eve; char evekey[DESKEYLEN]; char hostdomain[DOMLEN]; @@ -47,524 +20,182 @@ iseve(void) return strcmp(eve, up->user) == 0; } -/* - * crypt entries are allocated from a pool rather than allocated using malloc so - * the memory can be protected from reading by devproc. The base and top of the - * crypt arena is stored in palloc for devproc. - */ -Crypt* -newcrypt(void) -{ - Crypt *c; - - lock(&cryptalloc); - if(cryptalloc.free) { - c = cryptalloc.free; - cryptalloc.free = c->next; - unlock(&cryptalloc); - memset(c, 0, sizeof(Crypt)); - return c; - } - - cryptalloc.free = xalloc(sizeof(Crypt)*conf.nproc); - if(cryptalloc.free == 0) - panic("newcrypt"); - - for(c = cryptalloc.free; c < cryptalloc.free+conf.nproc-1; c++) - c->next = c+1; - - palloc.cmembase = (ulong)cryptalloc.free; - palloc.cmemtop = palloc.cmembase+(sizeof(Crypt)*conf.nproc); - unlock(&cryptalloc); - return newcrypt(); -} - -void -freecrypt(Crypt *c) -{ - lock(&cryptalloc); - c->next = cryptalloc.free; - cryptalloc.free = c; - unlock(&cryptalloc); -} - -/* - * return the info received in the session message on this channel. - * if no session message has been exchanged, do it. - */ long -sysfsession(ulong *arg) +sysfversion(ulong *arg) { - int i, n; + Fcall f; /* two Fcalls should be big enough for reply */ + uchar *msg; + char *vers; + uint arglen, n, m, msize; Chan *c; - Crypt *cp; - Session *s; - Ticketreq tr; - Fcall f; - char buf[MAXMSG]; - - validaddr(arg[1], TICKREQLEN, 1); - c = fdtochan(arg[0], OWRITE, 0, 1); + uvlong oo; + + msize = arg[1]; + vers = (char*)arg[2]; + arglen = arg[3]; + validaddr(arg[2], arglen, 1); + /* check there's a NUL in the version string */ + if(memchr(vers, 0, arglen) == 0) + error(Ebadarg); + c = fdtochan(arg[0], ORDWR, 0, 1); if(waserror()){ cclose(c); nexterror(); } - /* add a session structure to the channel if it has none */ - lock(c); - s = c->session; - if(s == 0){ - s = malloc(sizeof(Session)); - if(s == 0){ - unlock(c); - error(Enomem); - } - c->session = s; + if((c->flag&CMSG) && c->version!=nil) /* BUG: insufficient; should check compatibility */ + goto Return; + + f.type = Tversion; + f.tag = NOTAG; + if(msize == 0) + msize = IOHDRSZ+8192; /* reasonable default */ + f.msize = msize; + if(vers[0] == '\0') + vers = VERSION9P; + f.version = vers; + msg = smalloc(MAXMSG); + if(waserror()){ + free(msg); + nexterror(); } + n = convS2M(&f, msg, MAXMSG); + if(n == 0) + error("bad fversion conversion on send"); + + lock(c); + oo = c->offset; + c->offset += n; unlock(c); - /* back off if someone else is doing an fsession */ - while(!canlock(&s->send)) - sched(); - - if(s->valid == 0 && (c->flag & CMSG) == 0){ - - /* - * Exchange a session message with the server. - * If an error occurs reading or writing, - * assume this is a mount of a mount and turn off - * authentication. - */ - if(!waserror()){ - for(i = 0; i < CHALLEN; i++) - s->cchal[i] = nrand(256); - f.tag = NOTAG; - f.type = Tsession; - memmove(f.chal, s->cchal, CHALLEN); - n = convS2M(&f, buf); - if(devtab[c->type]->write(c, buf, n, 0) != n) - error(Emountrpc); - 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); - poperror(); - if(convM2S(buf, &f, n) == 0){ - unlock(&s->send); - error(Emountrpc); - } - switch(f.type){ - case Rsession: - memmove(s->schal, f.chal, CHALLEN); - memmove(s->authid, f.authid, NAMELEN); - memmove(s->authdom, f.authdom, DOMLEN); - break; - case Rerror: - unlock(&s->send); - error(f.ename); - default: - unlock(&s->send); - error(Emountrpc); - } - } - s->valid = 1; - } - 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(up->user, "none") == 0 || s->authid[0] == 0) - tr.type = 0; - else{ - lock(s); - for(cp = s->cache; cp; cp = cp->next) - if(strcmp(cp->t.cuid, up->user) == 0){ - tr.type = 0; - break; - } - unlock(s); + m = devtab[c->type]->write(c, msg, n, oo); + + if(m < n){ + lock(c); + c->offset -= n - m; + unlock(c); + error("short write in fversion"); } - /* create ticket request */ - memmove(tr.chal, s->schal, CHALLEN); - memmove(tr.authid, s->authid, NAMELEN); - memmove(tr.authdom, s->authdom, DOMLEN); - memmove(tr.uid, up->user, NAMELEN); - memmove(tr.hostid, eve, NAMELEN); - convTR2M(&tr, (char*)arg[1]); + /* message sent; receive and decode reply */ + m = devtab[c->type]->read(c, msg, MAXMSG, c->offset); + if(m <= 0) + error("EOF receiving fversion reply"); + + lock(c); + c->offset += m; + unlock(c); + + n = convM2S(msg, m, &f); + if(n != m) + error("bad fversion conversion on reply"); + if(f.type != Rversion) + error("unexpected reply type in fversion"); + if(f.msize > msize) + error("server tries to increase msize in fversion"); + if(f.msize<256 || f.msize>1024*1024) + error("nonsense value of msize in fversion"); + kstrdup(&c->version, f.version); + c->iounit = f.msize; + free(msg); + poperror(); + +Return: + m = strlen(c->version); + if(m > arglen) + m = arglen; + memmove((char*)arg[2], c->version, m); cclose(c); poperror(); - return 0; + return m; } -/* - * attach tickets to a session - */ long -sysfauth(ulong *arg) +sysfsession(ulong *arg) { + Fcall f; + uchar *msg; + uint authlen, n, m; Chan *c; - char *ta; - Session *s; - Crypt *cp, *ncp, **l; - char tbuf[2*TICKETLEN]; - - validaddr(arg[1], 2*TICKETLEN, 0); - c = fdtochan(arg[0], OWRITE, 0, 1); - s = c->session; - if(s == 0){ - cclose(c); - error("fauth must follow fsession"); - } - cp = newcrypt(); + uvlong oo; + +//BUG print("warning: stub fsession being used\n"); + authlen = arg[2]; + validaddr(arg[1], authlen, 1); + c = fdtochan(arg[0], ORDWR, 0, 1); if(waserror()){ cclose(c); - freecrypt(cp); nexterror(); } - /* ticket supplied, use it */ - ta = (char*)arg[1]; - memmove(tbuf, ta, 2*TICKETLEN); - convM2T(tbuf, &cp->t, evekey); - if(cp->t.num != AuthTc) - error("bad AuthTc in ticket"); - 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"); - memmove(cp->tbuf, tbuf+TICKETLEN, TICKETLEN); - - /* string onto local list, replace old version */ - lock(s); - l = &s->cache; - for(ncp = s->cache; ncp; ncp = *l){ - if(strcmp(ncp->t.cuid, up->user) == 0){ - *l = ncp->next; - freecrypt(ncp); - break; - } - l = &ncp->next; - } - cp->next = s->cache; - s->cache = cp; - unlock(s); - cclose(c); - poperror(); - return 0; -} - -/* - * free a session created by fsession - */ -void -freesession(Session *s) -{ - Crypt *cp, *next; - - for(cp = s->cache; cp; cp = next) { - next = cp->next; - freecrypt(cp); - } - free(s); -} - -/* - * called by mattach() to fill in the Tattach message - */ -ulong -authrequest(Session *s, Fcall *f) -{ - Authenticator a; - Crypt *cp; - ulong id, dofree; - - /* no authentication if user is "none" or if no ticket required by remote */ - if(s == 0 || s->authid[0] == 0 || strcmp(up->user, "none") == 0){ - memset(f->ticket, 0, TICKETLEN); - memset(f->auth, 0, AUTHENTLEN); + if(c->flag & CMSG){ +//BUG what to do? + ((uchar*)arg[1])[0] = 0; + poperror(); + cclose(c); return 0; } - /* look for ticket in cache */ - dofree = 0; - lock(s); - for(cp = s->cache; cp; cp = cp->next) - if(strcmp(cp->t.cuid, up->user) == 0) - break; - - id = s->cid++; - unlock(s); - - if(cp == 0){ - /* - * create a ticket using hostkey, this solves the - * chicken and egg problem - */ - cp = newcrypt(); - cp->t.num = AuthTs; - memmove(cp->t.chal, s->schal, CHALLEN); - 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; - } else - memmove(f->ticket, cp->tbuf, TICKETLEN); - - /* create an authenticator */ - memmove(a.chal, s->schal, CHALLEN); - a.num = AuthAc; - a.id = id; - convA2M(&a, f->auth, cp->t.key); - if(dofree) - freecrypt(cp); - return id; -} - -/* - * called by mattach() to check the Rattach message - */ -void -authreply(Session *s, ulong id, Fcall *f) -{ - Authenticator a; - Crypt *cp; - - if(s == 0) - return; - - lock(s); - for(cp = s->cache; cp; cp = cp->next) - 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(up->user, "none") == 0) - return; - - convM2A(f->rauth, &a, cp->t.key); - if(a.num != AuthAs){ - print("bad encryption type\n"); - error("server lies"); - } - if(memcmp(a.chal, s->cchal, sizeof(a.chal))){ - print("bad returned challenge\n"); - error("server lies"); - } - if(a.id != id){ - print("bad returned id\n"); - error("server lies"); - } -} - -/* - * called by devcons() for #c/authenticate - * - * 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 - * 3) read authenticator (to confirm this is the server advertised) - */ -long -authread(Chan *c, char *a, int n) -{ - Crypt *cp; - int i; - Ticketreq tr; - - if(c->aux == 0){ - /* - * first read returns a ticket request - */ - if(n != TICKREQLEN) - 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, up->user); - for(i = 0; i < CHALLEN; i++) - tr.chal[i] = nrand(256); - memmove(cp->a.chal, tr.chal, CHALLEN); - convTR2M(&tr, a); - } else { - /* - * subsequent read returns an authenticator - */ - 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); - - if(n >= AUTHENTLEN + TICKETLEN) - convT2M(&cp->t, a+AUTHENTLEN, nil); - - freecrypt(cp); - c->aux = 0; + f.type = Tsession; + f.tag = NOTAG; + f.nchal = 0; + f.chal = (uchar*)""; + msg = smalloc(MAXMSG); + if(waserror()){ + free(msg); + nexterror(); } - return n; -} - -long -authwrite(Chan *c, char *a, int n) -{ - Crypt *cp; + n = convS2M(&f, msg, MAXMSG); + if(n == 0) + error("bad fsession conversion on send"); - if(n != TICKETLEN+AUTHENTLEN) - error(Ebadarg); - if(c->aux == 0) - error(Ebadarg); - cp = c->aux; - - memmove(cp->tbuf, a, TICKETLEN); - convM2T(cp->tbuf, &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(up->user, cp->t.suid, NAMELEN); - return n; -} + lock(c); + oo = c->offset; + c->offset += n; + unlock(c); -/* - * called by devcons() for #c/authcheck - * - * a write of a ticket+authenticator [+challenge+id] succeeds if they match - */ -long -authcheck(Chan *c, char *a, int n) -{ - Crypt *cp; - char *chal; - ulong id; + m = devtab[c->type]->write(c, msg, n, oo); - if(n != TICKETLEN+AUTHENTLEN && n != TICKETLEN+AUTHENTLEN+CHALLEN+4) - 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) - error(Ebadarg); - 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); - if(n == TICKETLEN+AUTHENTLEN+CHALLEN+4){ - uchar *p = (uchar *)&a[TICKETLEN+AUTHENTLEN+CHALLEN]; - id = p[0] | (p[1]<<8) | (p[2]<<16) | (p[3]<<24); - chal = &a[TICKETLEN+AUTHENTLEN]; - }else{ - id = 0; - chal = cp->t.chal; + if(m < n){ + lock(c); + c->offset -= n - m; + unlock(c); + error("short write in fsession"); } - if(cp->a.num != AuthAs || memcmp(chal, cp->a.chal, CHALLEN) || cp->a.id != id) - error(Eperm); - return n; -} + /* message sent; receive and decode reply */ + m = devtab[c->type]->read(c, msg, MAXMSG, c->offset); + if(m <= 0) + error("EOF receiving fsession reply"); -/* - * reading authcheck after writing into it yields the - * unencrypted ticket - */ -long -authcheckread(Chan *c, char *a, int n) -{ - Crypt *cp; - - cp = c->aux; - if(cp == nil) - error(Ebadarg); - if(n < TICKETLEN) - error(Ebadarg); - convT2M(&cp->t, a, nil); - return sizeof(cp->t); -} - -/* - * called by devcons() for #c/authenticator - * - * a read after a write of a ticket (or ticket+id) returns an authenticator - * for that ticket. - */ -long -authentwrite(Chan *c, char *a, int n) -{ - Crypt *cp; - - if(n != TICKETLEN && n != TICKETLEN+4) - 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, up->user)){ - freecrypt(cp); - c->aux = 0; - error(Ebadarg); - } - if(n == TICKETLEN+4){ - uchar *p = (uchar *)&a[TICKETLEN]; - cp->a.id = p[0] | (p[1]<<8) | (p[2]<<16) | (p[3]<<24); - }else - cp->a.id = 0; + lock(c); + c->offset += m; + unlock(c); - return n; + n = convM2S(msg, m, &f); + if(n != m) + error("bad fsession conversion on reply"); + if(f.type != Rsession) + error("unexpected reply type in fsession"); + m = f.nchal; + if(m > authlen) + error(Eshort); +//BUG print("auth stuff ignored; noauth by default\n"); + ((uchar*)arg[1])[0] = 0; + + free(msg); + poperror(); + poperror(); + cclose(c); + return m; } -/* - * create an authenticator and return it and optionally the - * unencrypted ticket - */ long -authentread(Chan *c, char *a, int n) +sysfauth(ulong *) { - 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); - convA2M(&cp->a, cp->tbuf, cp->t.key); - - if(n >= AUTHENTLEN) - memmove(a, cp->tbuf, AUTHENTLEN); - return n; -} - -void -authclose(Chan *c) -{ - if(c->aux) - freecrypt(c->aux); - c->aux = 0; + error("sysfauth unimplemented"); + return -1; } /* @@ -600,12 +231,9 @@ keywrite(char *a, int n) long userwrite(char *a, int n) { - if(n >= NAMELEN) - error(Ebadarg); if(!iseve() || strcmp(a, "none") != 0) error(Eperm); - memset(up->user, 0, NAMELEN); - strcpy(up->user, "none"); + kstrdup(&up->user, "none"); up->basepri = PriNormal; return n; } @@ -618,19 +246,19 @@ userwrite(char *a, int n) long hostownerwrite(char *a, int n) { - char buf[NAMELEN]; + char buf[128]; if(!iseve()) error(Eperm); - if(n >= NAMELEN) + if(n >= sizeof buf) error(Ebadarg); - memset(buf, 0, NAMELEN); - strncpy(buf, a, n); - if(buf[0] == 0) + strncpy(buf, a, n+1); + if(buf[0] == '\0') error(Ebadarg); + renameuser(eve, buf); - memmove(eve, buf, NAMELEN); - memmove(up->user, buf, NAMELEN); + kstrdup(&eve, buf); + kstrdup(&up->user, buf); up->basepri = PriNormal; return n; } diff --git a/port/cache.c b/port/cache.c index 0bc9d49115fc957554adcb1af145df7861ae9d68..41c6056d6b555685e88abe1f03016a6866d9999e 100644 --- a/port/cache.c +++ b/port/cache.c @@ -26,7 +26,7 @@ struct Extent typedef struct Mntcache Mntcache; struct Mntcache { - Qid; + Qid qid; int dev; int type; QLock; @@ -111,10 +111,10 @@ cinit(void) m = cache.head; /* a better algorithm would be nice */ -// if(conf.npage*BY2PG > 200*MB) -// maxcache = 10*MAXCACHE; -// if(conf.npage*BY2PG > 400*MB) -// maxcache = 50*MAXCACHE; + if(conf.npage*BY2PG > 200*MB) + maxcache = 10*MAXCACHE; + if(conf.npage*BY2PG > 400*MB) + maxcache = 50*MAXCACHE; for(i = 0; i < NFILE-1; i++) { m->next = m+1; @@ -148,7 +148,7 @@ cprint(Chan *c, Mntcache *m, char *s) o = e->start+e->len; } pprint("%s: 0x%lux.0x%lux %d %d %s (%d %c)\n", - s, m->path, m->vers, m->type, m->dev, c->name, nb, ct ? 'C' : 'N'); + s, m->qid.path, m->qid.vers, m->type, m->dev, c->name, nb, ct ? 'C' : 'N'); for(e = m->list; e; e = e->next) { pprint("\t%4d %5d %4d %lux\n", @@ -216,21 +216,23 @@ copen(Chan *c) Extent *e, *next; Mntcache *m, *f, **l; - if(c->qid.path&CHDIR) + /* directories aren't cacheable and append-only files confuse us */ + if(c->qid.type&(QTDIR|QTAPPEND)) return; h = c->qid.path%NHASH; lock(&cache); for(m = cache.hash[h]; m; m = m->hash) { - if(m->path == c->qid.path) + if(m->qid.path == c->qid.path) + if(m->qid.type == c->qid.type) if(m->dev == c->dev && m->type == c->type) { c->mcp = m; ctail(m); unlock(&cache); /* File was updated, invalidate cache */ - if(m->vers != c->qid.vers) { - m->vers = c->qid.vers; + if(m->qid.vers != c->qid.vers) { + m->qid.vers = c->qid.vers; qlock(m); cnodata(m); qunlock(m); @@ -241,7 +243,7 @@ copen(Chan *c) /* LRU the cache headers */ m = cache.head; - l = &cache.hash[m->path%NHASH]; + l = &cache.hash[m->qid.path%NHASH]; for(f = *l; f; f = f->hash) { if(f == m) { *l = m->hash; @@ -250,7 +252,7 @@ copen(Chan *c) l = &f->hash; } - m->Qid = c->qid; + m->qid = c->qid; m->dev = c->dev; m->type = c->type; @@ -276,13 +278,15 @@ copen(Chan *c) static int cdev(Mntcache *m, Chan *c) { - if(m->path != c->qid.path) + if(m->qid.path != c->qid.path) + return 0; + if(m->qid.type != c->qid.type) return 0; if(m->dev != c->dev) return 0; if(m->type != c->type) return 0; - if(m->vers != c->qid.vers) + if(m->qid.vers != c->qid.vers) return 0; return 1; } @@ -573,7 +577,7 @@ cwrite(Chan* c, uchar *buf, int len, vlong off) } offset = off; - m->vers++; + m->qid.vers++; c->qid.vers++; p = 0; diff --git a/port/chan.c b/port/chan.c index 503035fb4a7a77f3ef585198be1075d7f2119468..4df227000f2e92684d17eb4aee5c3cf59cac3d8e 100644 --- a/port/chan.c +++ b/port/chan.c @@ -5,6 +5,53 @@ #include "fns.h" #include "../port/error.h" +int chandebug=0; /* toggled by sysr1 */ + +/* transition BUG */ +int client9p = 2; +int kernel9p = 2; + + +int domount(Chan**, Mhead**); +Ref mheadcounter; + +void +dumpmount(void) /* DEBUGGING */ +{ + Pgrp *pg; + Mount *t; + Mhead **h, **he, *f; + + if(up == nil){ + print("no process for dumpmount\n"); + return; + } + pg = up->pgrp; + if(pg == nil){ + print("no pgrp for dumpmount\n"); + return; + } + 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) { + print("head: %p: %s 0x%llux.%lud %C %lud -> \n", f, + f->from->name->s, f->from->qid.path, + f->from->qid.vers, devtab[f->from->type]->dc, + f->from->dev); + for(t = f->mount; t; t = t->next) + print("\t%p: %s (umh %p)\n", t, t->to->name->s, t->to->umh); + } + } + poperror(); + runlock(&pg->ns); +} + enum { CNAMESLOP = 20 @@ -18,9 +65,24 @@ struct Chan *list; }chanalloc; +typedef struct Elemlist Elemlist; + +struct Elemlist +{ + char *name; /* copy of name, so '/' can be overwritten */ + int nelems; + char **elems; +}; + #define SEP(c) ((c) == 0 || (c) == '/') void cleancname(Cname*); +int +isdotdot(char *p) +{ + return p[0]=='.' && p[1]=='.' && p[2]=='\0'; +} + int incref(Ref *r) { @@ -46,6 +108,87 @@ decref(Ref *r) return x; } +/* + * Rather than strncpy, which zeros the rest of the buffer, kstrcpy + * truncates if necessary, always zero terminates, does not zero fill, + * and puts ... at the end of the string if it's too long. Usually used to + * save a string in up->genbuf; + */ +void +kstrcpy(char *s, char *t, int ns) +{ + int nt; + + nt = strlen(t); + if(nt+1 <= ns){ + memmove(s, t, nt+1); + return; + } + /* too long */ + if(ns < 4){ + /* but very short! */ + strncpy(s, t, ns); + return; + } + /* truncate with ... at character boundary (very rare case) */ + memmove(s, t, ns-4); + ns -= 4; + s[ns] = '\0'; + /* look for first byte of UTF-8 sequence by skipping continuation bytes */ + while(ns>0 && (s[--ns]&0xC0)==0x80) + ; + strcpy(s+ns, "..."); +} + +int +emptystr(char *s) +{ + if(s == nil) + return 1; + if(s[0] == '\0') + return 1; + return 0; +} + +/* + * Atomically replace *p with copy of s + */ +void +kstrdup(char **p, char *s) +{ + int n; + char *t, *prev; + static Lock l; + + n = strlen(s)+1; +// if(n == 1){ +// ulong pc; +// int i; +// static ulong pcs[128]; +// pc = getcallerpc(&p); +// for(i=0; inext; unlock(&chanalloc); - if(c == 0) { + if(c == nil) { c = smalloc(sizeof(Chan)); lock(&chanalloc); c->fid = ++chanalloc.fid; c->link = chanalloc.list; chanalloc.list = c; unlock(&chanalloc); +if(chandebug) print("newchan %d\n", c->fid); } /* if you get an error before associating with a dev, @@ -91,14 +235,15 @@ newchan(void) c->ref = 1; c->dev = 0; c->offset = 0; - c->mh = 0; - c->xmh = 0; + c->iounit = 0; + c->umh = 0; c->uri = 0; c->aux = 0; c->mchan = 0; c->mcp = 0; - c->mqid = (Qid){0, 0}; + memset(&c->mqid, 0, sizeof(c->mqid)); c->name = 0; + c->version = 0; return c; } @@ -124,7 +269,7 @@ newcname(char *s) void cnameclose(Cname *n) { - if(n == 0) + if(n == nil) return; if(decref(n)) return; @@ -140,6 +285,9 @@ addelem(Cname *n, char *s) char *t; Cname *new; + if(s[0]=='.' && s[1]=='\0') + return n; + if(n->ref > 1){ /* copy on write */ new = newcname(n->s); @@ -160,6 +308,8 @@ addelem(Cname *n, char *s) n->s[n->len++] = '/'; memmove(n->s+n->len, s, i+1); n->len += i; + if(isdotdot(s)) + cleancname(n); return n; } @@ -168,14 +318,17 @@ chanfree(Chan *c) { c->flag = CFREE; - if(c->session){ - freesession(c->session); - c->session = 0; + if(c->version){ + free(c->version); + c->version = 0; } - - if(c->mh != nil){ - putmhead(c->mh); - c->mh = nil; + if(c->umh != nil){ + putmhead(c->umh); + c->umh = nil; + } + if(c->umc != nil){ + cclose(c->umc); + c->umc = nil; } cnameclose(c->name); @@ -205,6 +358,23 @@ cclose(Chan *c) chanfree(c); } +/* + * Make sure we have the only copy of c. (Copy on write.) + */ +Chan* +cunique(Chan *c) +{ + Chan *nc; + + if(c->ref != 1) { + nc = cclone(c); + cclose(c); + c = nc; + } + + return c; +} + int eqqid(Qid a, Qid b) { @@ -226,37 +396,82 @@ eqchan(Chan *a, Chan *b, int pathonly) } int -cmount(Chan *new, Chan *old, int flag, char *spec) +eqchantdqid(Chan *a, int type, int dev, Qid qid, int pathonly) +{ + if(a->qid.path != qid.path) + return 0; + if(!pathonly && a->qid.vers!=qid.vers) + return 0; + if(a->type != type) + return 0; + if(a->dev != dev) + return 0; + return 1; +} + +int +cmount(Chan **newp, Chan *old, int flag, char *spec) { Pgrp *pg; int order, flg; - Mhead *m, **l; + Mhead *m, **l, *mh; Mount *nm, *f, *um, **h; + Chan *new; - if(CHDIR & (old->qid.path^new->qid.path)) + if(QTDIR & (old->qid.type^(*newp)->qid.type)) error(Emount); +if((*newp)->umh) /* should not happen */ + print("cmount newp extra umh\n"); +if(old->umh) + print("cmount old extra umh\n"); + order = flag&MORDER; - if((old->qid.path&CHDIR)==0 && order != MREPL) + if((old->qid.type&QTDIR)==0 && order != MREPL) + error(Emount); + + mh = nil; + domount(newp, &mh); + new = *newp; + + /* + * Not allowed to bind when the old directory + * is itself a union. (Maybe it should be allowed, but I don't see + * what the semantics would be.) + * + * We need to check mh->mount->next to tell unions apart from + * simple mount points, so that things like + * mount -c fd /root + * bind -c /root / + * work. The check of mount->mflag catches things like + * mount fd /root + * bind -c /root / + * + * This is far more complicated than it should be, but I don't + * see an easier way at the moment. -rsc + */ + if((flag&MCREATE) && mh && mh->mount + && (mh->mount->next || !(mh->mount->mflag&MCREATE))) error(Emount); pg = up->pgrp; wlock(&pg->ns); - l = &MOUNTH(pg, old); + l = &MOUNTH(pg, old->qid); for(m = *l; m; m = m->hash) { if(eqchan(m->from, old, 1)) break; l = &m->hash; } - if(m == 0) { + if(m == nil) { /* * nothing mounted here yet. create a mount * head and add to the hash table. */ m = smalloc(sizeof(Mhead)); +incref(&mheadcounter); m->ref = 1; m->from = old; incref(old); @@ -278,7 +493,7 @@ cmount(Chan *new, Chan *old, int flag, char *spec) wunlock(&pg->ns); nm = newmount(m, new, flag, spec); - if(new->mh != nil && new->mh->mount != nil) { + if(mh != nil && mh->mount != nil) { /* * copy a union when binding it onto a directory */ @@ -286,7 +501,7 @@ cmount(Chan *new, Chan *old, int flag, char *spec) if(order == MREPL) flg = MAFTER; h = &nm->next; - um = new->mh->mount; + um = mh->mount; for(um = um->next; um; um = um->next) { f = newmount(m, um->to, flg, um->spec); *h = f; @@ -300,7 +515,7 @@ cmount(Chan *new, Chan *old, int flag, char *spec) } if(flag & MCREATE) - new->flag |= CCREATE; + nm->mflag |= MCREATE; if(m->mount && order == MAFTER) { for(f = m->mount; f->next; f = f->next) @@ -326,10 +541,15 @@ cunmount(Chan *mnt, Chan *mounted) Mhead *m, **l; Mount *f, **p; +if(mnt->umh) /* should not happen */ + print("cmount newp extra umh\n"); +if(mounted && mounted->umh) + print("cmount old extra umh\n"); + pg = up->pgrp; wlock(&pg->ns); - l = &MOUNTH(pg, mnt); + l = &MOUNTH(pg, mnt->qid); for(m = *l; m; m = m->hash) { if(eqchan(m->from, mnt, 1)) break; @@ -379,63 +599,67 @@ cunmount(Chan *mnt, Chan *mounted) } Chan* -cclone(Chan *c, Chan *nc) +cclone(Chan *c) { - nc = devtab[c->type]->clone(c, nc); - if(nc != nil){ - nc->name = c->name; - if(c->name) - incref(c->name); - } + Chan *nc; + Walkqid *wq; + + wq = devtab[c->type]->walk(c, nil, nil, 0); + if(wq == nil) + error("clone failed"); + nc = wq->clone; + free(wq); + nc->name = c->name; + if(c->name) + incref(c->name); return nc; } -Chan* -domount(Chan *c) +int +findmount(Chan **cp, Mhead **mp, int type, int dev, Qid qid) { Pgrp *pg; - Chan *nc; Mhead *m; pg = up->pgrp; rlock(&pg->ns); - if(c->mh){ - putmhead(c->mh); - c->mh = 0; - } - - for(m = MOUNTH(pg, c); m; m = m->hash){ + for(m = MOUNTH(pg, qid); m; m = m->hash){ rlock(&m->lock); - if(eqchan(m->from, c, 1)) { - if(waserror()) { - runlock(&m->lock); - nexterror(); - } +if(m->from == nil){ + print("m %p m->from 0\n", m); + runlock(&m->lock); + continue; +} + if(eqchantdqid(m->from, type, dev, qid, 1)) { runlock(&pg->ns); - nc = cclone(m->mount->to, 0); - if(nc->mh != nil) - putmhead(nc->mh); - nc->mh = m; - nc->xmh = m; - incref(m); - cnameclose(nc->name); - nc->name = c->name; - incref(c->name); - cclose(c); - c = nc; - poperror(); + if(mp != nil){ + incref(m); + if(*mp != nil) + putmhead(*mp); + *mp = m; + } + if(*cp != nil) + cclose(*cp); + incref(m->mount->to); + *cp = m->mount->to; runlock(&m->lock); - return c; + return 1; } runlock(&m->lock); } runlock(&pg->ns); - return c; + return 0; +} + +int +domount(Chan **cp, Mhead **mp) +{ + return findmount(cp, mp, (*cp)->type, (*cp)->dev, (*cp)->qid); } Chan* -undomount(Chan *c) +undomount(Chan *c, Cname *name) { Chan *nc; Pgrp *pg; @@ -460,10 +684,10 @@ undomount(Chan *c) * To do this, find the element that has a from name of * c->name->s. */ - if(strcmp(t->head->from->name->s, c->name->s) != 0) + if(strcmp(t->head->from->name->s, name->s) != 0) continue; - nc = cclone(t->head->from, 0); - /* don't need to update nc->name because c->name is same! */ + nc = t->head->from; + incref(nc); cclose(c); c = nc; break; @@ -476,90 +700,166 @@ undomount(Chan *c) return c; } -Chan * -updatecname(Chan *c, char *name, int dotdot) -{ - if(c->name == nil) - c->name = newcname(name); - else - c->name = addelem(c->name, name); - - if(dotdot){ - cleancname(c->name); /* could be cheaper */ - c = undomount(c); - } - return c; -} - +/* + * Either walks all the way or not at all. No partial results. + */ int -walk(Chan **cp, char *name, int domnt) +walk(Chan **cp, char **names, int nnames, int nomount) { - Chan *c, *ac; + int i, dotdot, n, ntry, type, dev; + Chan *c, *nc; + Cname *cname; Mount *f; - int dotdot; + Mhead *mh, *nmh; + Walkqid *wq; + +//BUG: waserror? + + c = *cp; + incref(c); + cname = c->name; + incref(cname); + mh = nil; + +if(chandebug){ +print("walk"); +for(i=0; i 0){ + ntry = nnames; + if(ntry > MAXWELEM) + ntry = MAXWELEM; + dotdot = 0; + for(i=0; i\n", c->qid.path, devtab[c->type]->dc, c->dev); +for(i=0; itype; + dev = c->dev; + + if((wq = devtab[type]->walk(c, nil, names, ntry)) == nil){ +if(chandebug) print("walk failed."); + /* try a union mount, if any */ + if(mh == nil || nomount){ + Giveup: +if(chandebug) print("give up\n"); +//delay(2000); + cclose(c); + cnameclose(cname); + return -1; + } - dotdot = 0; - if(name[0] == '.' && name[1] == '.' && name[2] == '\0') { - *cp = ac = undomount(ac); - dotdot = 1; - } + rlock(&mh->lock); + if(waserror()){ + runlock(&mh->lock); + nexterror(); + } + for(f = mh->mount; f; f = f->next) +{ +if(chandebug) print("\ttry chan: qid %.8llux devchar %C dev %lud ->\n", c->qid.path, devtab[c->type]->dc, c->dev); + if((wq = devtab[f->to->type]->walk(f->to, nil, names, ntry)) != nil) + break; +} + poperror(); + runlock(&mh->lock); - ac->flag &= ~CCREATE; /* not inherited through a walk */ - if(devtab[ac->type]->walk(ac, name) != 0) { - /* walk succeeded: update name associated with *cp (ac) */ - *cp = updatecname(*cp, name, dotdot); - if(domnt) - *cp = domount(*cp); - return 0; - } + if(wq == nil) + goto Giveup; - if(ac->mh == nil) - return -1; + type = f->to->type; + dev = f->to->dev; + } - c = nil; + nmh = nil; + if(dotdot) { + assert(wq->nqid == 1); + assert(wq->clone != nil); +if(chandebug) print("undo."); + nc = undomount(wq->clone, cname); + n = 1; + } else { + nc = nil; +if(chandebug) print("find."); + if(!nomount) + for(i=0; inqid && iqid[i])) + break; + if(nc == nil){ /* no mount points along path */ + if(wq->clone == nil){ + cclose(c); + cnameclose(cname); + free(wq); +if(chandebug) print("fail\n"); + return -1; + } + n = wq->nqid; + nc = wq->clone; + }else{ /* stopped early, at a mount point */ + if(wq->clone != nil){ + cclose(wq->clone); + wq->clone = nil; + } + n = i+1; + } + } - rlock(&ac->mh->lock); - if(waserror()) { - runlock(&ac->mh->lock); - if(c) - cclose(c); - nexterror(); - } - for(f = ac->mh->mount; f; f = f->next) { - c = cclone(f->to, 0); - c->flag &= ~CCREATE; /* not inherited through a walk */ - if(devtab[c->type]->walk(c, name) != 0) - break; cclose(c); - c = nil; - } - poperror(); - runlock(&ac->mh->lock); + c = nc; + putmhead(mh); + mh = nmh; - if(c == nil) - return -1; + for(i=0; imh){ - putmhead(c->mh); - c->mh = nil; + names += n; + nnames -= n; +//print("nc %s nnames %d devchar %C qid %.8llux\n", cname->s, nnames, devtab[c->type]->dc, c->qid.path); + free(wq); } - /* replace c->name by ac->name */ + putmhead(mh); + + c = cunique(c); +if(c->umh != nil){ + print("walk umh\n"); + putmhead(c->umh); + c->umh = nil; +} + cnameclose(c->name); - c->name = ac->name; - if(ac->name) - incref(ac->name); - c = updatecname(c, name, dotdot); - cclose(ac); - *cp = c; + c->name = cname; - if(domnt) - *cp = domount(c); + cclose(*cp); + *cp = c; +if(chandebug) print("success\n"); return 0; } @@ -567,24 +867,20 @@ walk(Chan **cp, char *name, int domnt) * c is a mounted non-creatable directory. find a creatable one. */ Chan* -createdir(Chan *c) +createdir(Chan *c, Mhead *m) { Chan *nc; Mount *f; - rlock(&c->mh->lock); + rlock(&m->lock); if(waserror()) { - runlock(&c->mh->lock); + runlock(&m->lock); nexterror(); } - for(f = c->mh->mount; f; f = f->next) { - if(f->to->flag&CCREATE) { - nc = cclone(f->to, 0); - if(nc->mh != nil) - putmhead(nc->mh); - nc->mh = c->mh; - incref(c->mh); - runlock(&c->mh->lock); + for(f = m->mount; f; f = f->next) { + if(f->mflag&MCREATE) { + nc = cclone(f->to); + runlock(&m->lock); poperror(); cclose(c); return nc; @@ -624,63 +920,103 @@ cleancname(Cname *n) n->len = strlen(n->s); } +static void +growparse(Elemlist *e) +{ + char **new; + enum { Delta = 8 }; + + if(e->nelems % Delta == 0){ + new = smalloc((e->nelems+Delta) * sizeof(char*)); + memmove(new, e->elems, e->nelems*sizeof(char*)); + free(e->elems); + e->elems = new; + } +} + +/* + * The name is known to be valid. + * Copy the name so slashes can be overwritten. + * An empty string will set nelem=0. + */ +static void +parsename(char *name, Elemlist *e) +{ + char *slash; + + kstrdup(&e->name, name); + name = e->name; + e->nelems = 0; + e->elems = nil; + for(;;){ + name = skipslash(name); + if(*name=='\0') + break; + growparse(e); + e->elems[e->nelems++] = name; + slash = utfrune(name, '/'); + if(slash == nil) + break; + *slash++ = '\0'; + name = slash; + } +} + /* * Turn a name into a channel. * &name[0] is known to be a valid address. It may be a kernel address. + * + * Opening with amode Aopen, Acreate, or Aremove guarantees + * that the result will be the only reference to that particular fid. + * This is necessary since we might pass the result to + * devtab[]->remove(). + * + * Opening Atodir, Amount, or Aaccess does not guarantee this. + * + * Opening Aaccess can, under certain conditions, return a + * correct Chan* but with an incorrect Cname attached. + * Since the functions that open Aaccess (sysstat, syswstat, sys_stat) + * do not use the Cname*, this avoids an unnecessary clone. */ Chan* -namec(char *name, int amode, int omode, ulong perm) +namec(char *aname, int amode, int omode, ulong perm) { - Rune r; - char *p; - char *elem; + int n, t, nomount; + Chan *c, *cnew; Cname *cname; - int t, n, newname; - int mntok, isdot; - Chan *c, *cc; - char createerr[ERRLEN]; - - if(name[0] == 0) - error(Enonexist); - - if(((ulong)name & KZERO) != KZERO) { - p = name; - t = BY2PG-((ulong)p&(BY2PG-1)); - while(vmemchr(p, 0, t) == 0) { - p += t; - t = BY2PG; - } - } + Elemlist e; + Rune r; + Mhead *m; + char *name; - newname = 1; - cname = nil; - if(waserror()){ - cnameclose(cname); - nexterror(); - } + name = aname; + if(name[0] == '\0') + error("empty file name"); + validname(name, 1); - elem = up->elem; - mntok = 1; - isdot = 0; - switch(name[0]) { + /* + * Find the starting off point (the current slash, the root of + * a device tree, or the current dot) as well as the name to + * evaluate starting there. + */ + nomount = 0; + switch(name[0]){ case '/': - cname = newcname(name); /* save this before advancing */ + c = up->slash; + incref(c); name = skipslash(name); - c = cclone(up->slash, 0); - if(*name == 0) - isdot = 1; break; + case '#': - cname = newcname(name); /* save this before advancing */ - mntok = 0; - elem[0] = 0; + nomount = 1; + up->genbuf[0] = '\0'; n = 0; - while(*name && (*name != '/' || n < 2)){ - if(n >= NAMELEN-1) + while(*name!='\0' && (*name != '/' || n < 2)){ + if(n >= sizeof(up->genbuf)-1) error(Efilename); - elem[n++] = *name++; + up->genbuf[n++] = *name++; } - elem[n] = '\0'; + up->genbuf[n] = '\0'; /* * noattach is sandboxing. * @@ -693,7 +1029,7 @@ namec(char *name, int amode, int omode, ulong perm) * p control of your own processes (and unfortunately * any others left unprotected) */ - n = chartorune(&r, elem+1)+1; + n = chartorune(&r, up->genbuf+1)+1; /* actually / is caught by parsing earlier */ if(utfrune("M", r)) error(Enoattach); @@ -702,78 +1038,90 @@ namec(char *name, int amode, int omode, ulong perm) t = devno(r, 1); if(t == -1) error(Ebadsharp); - - c = devtab[t]->attach(elem+n); - name = skipslash(name); + c = devtab[t]->attach(up->genbuf+n); break; + default: - cname = newcname(up->dot->name->s); - cname = addelem(cname, name); - c = cclone(up->dot, 0); + c = up->dot; + incref(c); name = skipslash(name); - if(*name == 0) - isdot = 1; + break; } + e.name = nil; + e.elems = nil; if(waserror()){ + if(strcmp(up->error, Enonexist) == 0){ + if(strlen(aname) < ERRMAX/3 || (name=strrchr(aname, '/'))==nil || name==aname) + snprint(up->error, sizeof up->error, "\"%s\" does not exist", aname); + else + snprint(up->error, sizeof up->error, "file \"...%s\" does not exist", name); + } cclose(c); + free(e.name); + free(e.elems); +//dumpmount(); nexterror(); } - name = nextelem(name, elem); - /* - * If mounting, don't follow the mount entry for root or the - * current directory. + * Build a list of elements in the path. */ - if(mntok && !isdot && !(amode==Amount && elem[0]==0)) - c = domount(c); /* see case Atodir below */ + parsename(name, &e); - while(*name) { - if(walk(&c, elem, mntok) < 0) - error(Enonexist); - name = nextelem(name, elem); + /* + * On create, don't try to walk the last path element just yet. + */ + if(amode == Acreate){ + if(e.nelems == 0) + error(Eisdir); + e.nelems--; } - switch(amode) { - case Aaccess: - if(isdot) { - c = domount(c); - break; - } - if(walk(&c, elem, mntok) < 0) - error(Enonexist); - break; + if(walk(&c, e.elems, e.nelems, nomount) < 0) + error(Enonexist); - case Atodir: - /* - * Directories (e.g. for cd) are left before the mount point, - * so one may mount on / or . and see the effect. - */ - if(walk(&c, elem, 0) < 0) - error(Enonexist); - if(!(c->qid.path & CHDIR)) - error(Enotdir); + switch(amode){ + case Aaccess: + if(!nomount) + domount(&c, nil); break; + case Aremove: case Aopen: - if(isdot) - c = domount(c); - else { - if(walk(&c, elem, mntok) < 0) - error(Enonexist); - } Open: - /* else error() in open has wrong value of c saved */ + /* save the name; domount might change c */ + cname = c->name; + incref(cname); + m = nil; + if(!nomount) + domount(&c, &m); + + /* our own copy to open or remove */ + c = cunique(c); + + /* now it's our copy anyway, we can put the name back */ + cnameclose(c->name); + c->name = cname; + + if(amode == Aremove){ + putmhead(m); + break; + } + +if(c->umh != nil){ + print("cunique umh\n"); + putmhead(c->umh); +} + c->umh = m; + + /* save registers else error() in open has wrong value of c saved */ saveregisters(); if(omode == OEXEC) c->flag &= ~CCACHE; - cc = c; c = devtab[c->type]->open(c, omode&~OCEXEC); - if(cc != c) - newname = 0; if(omode & OCEXEC) c->flag |= CCEXEC; @@ -781,66 +1129,123 @@ namec(char *name, int amode, int omode, ulong perm) c->flag |= CRCLOSE; break; + case Atodir: + /* + * Directories (e.g. for cd) are left before the mount point, + * so one may mount on / or . and see the effect. + */ + if(!(c->qid.type & QTDIR)) + error(Enotdir); + break; + case Amount: /* * When mounting on an already mounted upon directory, * one wants subsequent mounts to be attached to the - * original directory, not the replacement. + * original directory, not the replacement. Don't domount. */ - if(walk(&c, elem, 0) < 0) - error(Enonexist); break; case Acreate: - if(isdot) - error(Eisdir); - /* - * Walk the element before trying to create it - * to see if it exists. We clone the channel - * first, just in case someone is trying to - * use clwalk outside the kernel. + * We've already walked all but the last element. + * If the last exists, try to open it OTRUNC. + * If omode&OEXCL is set, just give up. */ - cc = cclone(c, 0); - if(waserror()){ - cclose(cc); - nexterror(); - } - nameok(elem, 0); - if(walk(&cc, elem, 1) == 0){ - poperror(); - cclose(c); - c = cc; + e.nelems++; + if(walk(&c, e.elems+e.nelems-1, 1, nomount) == 0){ + if(omode&OEXCL){ + cclose(c); + error(Eexist); + } omode |= OTRUNC; goto Open; } - cclose(cc); - poperror(); /* - * the file didn't exist, try the create + * The semantics of the create(2) system call are that if the + * file exists and can be written, it is to be opened with truncation. + * On the other hand, the create(5) message fails if the file exists. + * If we get two create(2) calls happening simultaneously, + * they might both get here and send create(5) messages, but only + * one of the messages will succeed. To provide the expected create(2) + * semantics, the call with the failed message needs to try the above + * walk again, opening for truncation. This correctly solves the + * create/create race, in the sense that any observable outcome can + * be explained as one happening before the other. + * The create/create race is quite common. For example, it happens + * when two rc subshells simultaneously update the same + * environment variable. + * + * The implementation still admits a create/create/remove race: + * (A) walk to file, fails + * (B) walk to file, fails + * (A) create file, succeeds, returns + * (B) create file, fails + * (A) remove file, succeeds, returns + * (B) walk to file, return failure. + * + * This is hardly as common as the create/create race, and is really + * not too much worse than what might happen if (B) got a hold of a + * file descriptor and then the file was removed -- either way (B) can't do + * anything with the result of the create call. So we don't care about this race. + * + * Applications that care about more fine-grained decision of the races + * can use the OEXCL flag to get at the underlying create(5) semantics; + * by default we provide the common case. + * + * We need to stay behind the mount point in case we + * need to do the first walk again (should the create fail). + * + * We also need to cross the mount point and find the directory + * in the union in which we should be creating. + * + * The channel staying behind is c, the one moving forward is cnew. */ - if(c->mh != nil && !(c->flag&CCREATE)) - c = createdir(c); + m = nil; + cnew = nil; /* is this assignment necessary? */ + if(!waserror()){ /* try create */ + if(!nomount && findmount(&cnew, &m, c->type, c->dev, c->qid)) + cnew = createdir(cnew, m); + else{ + cnew = c; + incref(cnew); + } - /* - * protect against the open/create race. - * This is not a complete fix. It just reduces the window. - */ - if(waserror()) { - strcpy(createerr, up->error); - if(walk(&c, elem, 1) < 0) - error(createerr); + /* + * We need our own copy of the Chan because we're + * about to send a create, which will move it. Once we have + * our own copy, we can fix the name, which might be wrong + * if findmount gave us a new Chan. + */ + cnew = cunique(cnew); + cnameclose(cnew->name); + cnew->name = c->name; + incref(cnew->name); + + devtab[cnew->type]->create(cnew, e.elems[e.nelems-1], omode&~(OEXCL|OCEXEC), perm); + poperror(); + if(omode & OCEXEC) + cnew->flag |= CCEXEC; + if(omode & ORCLOSE) + cnew->flag |= CRCLOSE; + if(m) + putmhead(m); + cclose(c); + c = cnew; + break; + }else{ /* create failed */ + cclose(cnew); + if(m) + putmhead(m); + if(omode & OEXCL) + nexterror(); + if(walk(&c, e.elems+e.nelems-1, 1, nomount) < 0) + nexterror(); omode |= OTRUNC; goto Open; } - devtab[c->type]->create(c, elem, omode&~OCEXEC, perm); - if(omode & OCEXEC) - c->flag |= CCEXEC; - if(omode & ORCLOSE) - c->flag |= CRCLOSE; - poperror(); - break; + panic("namec: not reached"); default: panic("unknown namec access %d\n", amode); @@ -848,19 +1253,18 @@ namec(char *name, int amode, int omode, ulong perm) poperror(); - if(newname){ - cleancname(cname); - cnameclose(c->name); - c->name = cname; - }else - cnameclose(cname); - - poperror(); + /* place final element in genbuf for e.g. exec */ + if(e.nelems > 0) + kstrcpy(up->genbuf, e.elems[e.nelems-1], sizeof up->genbuf); + else + kstrcpy(up->genbuf, ".", sizeof up->genbuf); + free(e.name); + free(e.elems); return c; } /* - * name[0] is addressable. + * name is valid. skip leading / and ./ and trailing . */ char* skipslash(char *name) @@ -868,7 +1272,7 @@ skipslash(char *name) Again: while(*name == '/') name++; - if(*name=='.' && (name[1]==0 || name[1]=='/')){ + if(*name=='.' && (name[1]=='\0' || name[1]=='/')){ name++; goto Again; } @@ -880,66 +1284,88 @@ char isfrog[256]={ /*BKS*/ 1, 1, 1, 1, 1, 1, 1, 1, /*DLE*/ 1, 1, 1, 1, 1, 1, 1, 1, /*CAN*/ 1, 1, 1, 1, 1, 1, 1, 1, -/* [' '] 1, rob - let's try this out */ ['/'] 1, [0x7f] 1, }; -void -nameok(char *elem, int slashok) -{ - char *eelem; - - eelem = elem+NAMELEN; - while(*elem) { - if(isfrog[*(uchar*)elem]) - if(!slashok || *elem!='/') - error(Ebadchar); - elem++; - if(elem >= eelem) - error(Efilename); - } -} - /* - * name[0] should not be a slash. + * Check that the name + * a) is in valid memory. + * b) is shorter than 2^16 bytes, so it can fit in a 9P string field. + * c) contains no frogs. + * The first byte is known to be addressible by the requester, so the + * routine works for kernel and user memory both. + * The parameter slashok flags whether a slash character is an error + * or a valid character. */ -char* -nextelem(char *name, char *elem) +void +validname(char *name, int slashok) { - int w; - char *end; + char *p, *ename; + uint t; + int c; Rune r; - if(*name == '/') - error(Efilename); - 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 < end){ - name += chartorune(&r, name); - if(r=(1<<16)) + error("name too long"); + + while(*name){ + /* all characters above '~' are ok */ + c = *(uchar*)name; + if(c >= Runeself) + name += chartorune(&r, name); + else{ + if(isfrog[c]) + if(!slashok || c!='/') + error(Ebadchar); + name++; + } } - return skipslash(name); } void isdir(Chan *c) { - if(c->qid.path & CHDIR) + if(c->qid.type & QTDIR) return; error(Enotdir); } +/* + * This is necessary because there are many + * pointers to the top of a given mount list: + * + * - the mhead in the namespace hash table + * - the mhead in chans returned from findmount: + * used in namec and then by unionread. + * - the mhead in chans returned from createdir: + * used in the open/create race protect, which is gone. + * + * The RWlock in the Mhead protects the mount list it contains. + * The mount list is deleted when we cunmount. + * The RWlock ensures that nothing is using the mount list at that time. + * + * It is okay to replace c->mh with whatever you want as + * long as you are sure you have a unique reference to it. + * + * This comment might belong somewhere else. + */ void putmhead(Mhead *m) { - if(decref(m) == 0) + if(m && decref(m) == 0){ +decref(&mheadcounter); + m->mount = (Mount*)0xCafeBeef; free(m); + } } diff --git a/port/dev.c b/port/dev.c index a8984e1f218f6a0ee666f8bccc8cf2a3d6287a7d..420d68b192f5ee28b470abe9926ab9f129ffff98 100644 --- a/port/dev.c +++ b/port/dev.c @@ -7,6 +7,14 @@ extern ulong kerndate; +void +mkqid(Qid *q, vlong path, ulong vers, int type) +{ + q->type = type; + q->vers = vers; + q->path = path; +} + int devno(int c, int user) { @@ -25,33 +33,34 @@ devno(int c, int user) void devdir(Chan *c, Qid qid, char *n, vlong length, char *user, long perm, Dir *db) { - strcpy(db->name, n); + db->name = n; + if(c->flag&CMSG) + qid.type |= QTMOUNT; db->qid = qid; db->type = devtab[c->type]->dc; db->dev = c->dev; - if(qid.path & CHDIR) - db->mode = CHDIR|perm; - else - db->mode = perm; - if(c->flag&CMSG) - db->mode |= CHMOUNT; + db->mode = perm; + db->mode |= qid.type << 24; db->atime = seconds(); db->mtime = kerndate; db->length = length; - memmove(db->uid, user, NAMELEN); - memmove(db->gid, eve, NAMELEN); + db->uid = user; + db->gid = eve; + db->muid = user; } -// -// the zeroth element of the table MUST be the directory itself for .. -// +/* + * the zeroth element of the table MUST be the directory itself for .. +*/ int -devgen(Chan *c, Dirtab *tab, int ntab, int i, Dir *dp) +devgen(Chan *c, char*, Dirtab *tab, int ntab, int i, Dir *dp) { - if(tab==0) + if(tab == 0) return -1; - if(i!=DEVDOTDOT){ - if(i>=ntab) + if(i != DEVDOTDOT){ + /* skip over the first element, that for . itself */ + i++; + if(i >= ntab) return -1; tab += i; } @@ -73,34 +82,37 @@ Chan* devattach(int tc, char *spec) { Chan *c; - char buf[NAMELEN+4]; + char *buf; c = newchan(); - c->qid = (Qid){CHDIR, 0}; + mkqid(&c->qid, 0, 0, QTDIR); c->type = devno(tc, 0); - sprint(buf, "#%C%s", tc, spec==nil? "" : spec); + if(spec == nil) + spec = ""; + buf = smalloc(4+strlen(spec)+1); + sprint(buf, "#%C%s", tc, spec); c->name = newcname(buf); + free(buf); return c; } + Chan* -devclone(Chan *c, Chan *nc) +devclone(Chan *c) { + Chan *nc; + if(c->flag & COPEN) panic("clone of open file type %C\n", devtab[c->type]->dc); - if(nc == 0) - nc = newchan(); + nc = newchan(); nc->type = c->type; nc->dev = c->dev; nc->mode = c->mode; nc->qid = c->qid; nc->offset = c->offset; - nc->flag = c->flag; - nc->mh = c->mh; - if(c->mh != nil) - incref(c->mh); + nc->umh = nil; nc->mountid = c->mountid; nc->aux = c->aux; nc->mchan = c->mchan; @@ -109,49 +121,109 @@ devclone(Chan *c, Chan *nc) return nc; } -int -devwalk(Chan *c, char *name, Dirtab *tab, int ntab, Devgen *gen) +Walkqid* +devwalk(Chan *c, Chan *nc, char **name, int nname, Dirtab *tab, int ntab, Devgen *gen) { - long i; + int i, j, alloc; + Walkqid *wq; + char *n; Dir dir; - isdir(c); - if(name[0]=='.' && name[1]==0) - return 1; - if(name[0]=='.' && name[1]=='.' && name[2]==0){ - (*gen)(c, tab, ntab, DEVDOTDOT, &dir); - c->qid = dir.qid; - return 1; + if(nname > 0) + isdir(c); + +// print("devwalk (%d:%c:%p) ", nname, devtab[c->type]->dc, nc); +// for(i=0; iclone!=nil) + cclose(wq->clone); + free(wq); + return nil; } - for(i=0;; i++) { - switch((*gen)(c, tab, ntab, i, &dir)){ - case -1: - strncpy(up->error, Enonexist, NAMELEN); - return 0; - case 0: + if(nc == nil){ + nc = devclone(c); + nc->type = 0; /* device doesn't know about this channel yet */ + alloc = 1; + } + wq->clone = nc; + + for(j=0; jqid[wq->nqid++] = nc->qid; continue; - case 1: - if(strcmp(name, dir.name) == 0){ - c->qid = dir.qid; - return 1; + } + if(strcmp(n, "..") == 0){ + (*gen)(nc, nil, tab, ntab, DEVDOTDOT, &dir); + nc->qid = dir.qid; + goto Accept; + } + /* + * Ugly problem: If we're using devgen, make sure we're + * walking the directory itself, represented by the first + * entry in the table, and not trying to step into a sub- + * directory of the table, e.g. /net/net. Devgen itself + * should take care of the problem, but it doesn't have + * the necessary information (that we're doing a walk). + */ + if(gen==devgen && nc->qid.path!=tab[0].qid.path) + goto Notfound; + for(i=0;; i++) { + switch((*gen)(nc, n, tab, ntab, i, &dir)){ + case -1: + Notfound: + if(j == 0) + error(Enonexist); + strncpy(up->error, Enonexist, ERRMAX); + goto Done; + case 0: + continue; + case 1: + if(strcmp(n, dir.name) == 0){ + nc->qid = dir.qid; + goto Accept; + } + continue; } - continue; } } - return 0; + /* + * We processed at least one name, so will return some data. + * If we didn't process all nname entries succesfully, we drop + * the cloned channel and return just the Qids of the walks. + */ +Done: + poperror(); + if(wq->nqid < nname){ + if(alloc) + cclose(wq->clone); + wq->clone = nil; + }else if(wq->clone){ + /* attach cloned channel to same device */ + wq->clone->type = c->type; + } + return wq; } -void -devstat(Chan *c, char *db, Dirtab *tab, int ntab, Devgen *gen) +int +devstat(Chan *c, uchar *db, int n, Dirtab *tab, int ntab, Devgen *gen) { int i; Dir dir; char *p, *elem; for(i=0;; i++) - switch((*gen)(c, tab, ntab, i, &dir)){ + switch((*gen)(c, nil, tab, ntab, i, &dir)){ case -1: - if(c->qid.path & CHDIR){ + if(c->qid.type & QTDIR){ if(c->name == nil) elem = "???"; else if(strcmp(c->name->s, "/") == 0) @@ -160,11 +232,13 @@ devstat(Chan *c, char *db, Dirtab *tab, int ntab, Devgen *gen) for(elem=p=c->name->s; *p; p++) if(*p == '/') elem = p+1; - devdir(c, c->qid, elem, 0, eve, CHDIR|0555, &dir); - convD2M(&dir, db); - return; + devdir(c, c->qid, elem, 0, eve, DMDIR|0555, &dir); + n = convD2M(&dir, db, n); + if(n == 0) + error(Ebadarg); + return n; } - print("%s %s: devstat %C %lux\n", + print("%s %s: devstat %C %llux\n", up->text, up->user, devtab[c->type]->dc, c->qid.path); @@ -174,34 +248,46 @@ devstat(Chan *c, char *db, Dirtab *tab, int ntab, Devgen *gen) case 1: if(c->qid.path == dir.qid.path) { if(c->flag&CMSG) - dir.mode |= CHMOUNT; - convD2M(&dir, db); - return; + dir.mode |= DMMOUNT; + n = convD2M(&dir, db, n); + if(n == 0) + error(Ebadarg); + return n; } break; } + error(Egreg); /* not reached? */ + return -1; } long devdirread(Chan *c, char *d, long n, Dirtab *tab, int ntab, Devgen *gen) { - long k, m; - Dir dir; + long k, m, dsz; + struct{ + Dir; + char slop[100]; + }dir; - k = c->offset/DIRLEN; + k = c->offset; for(m=0; moffset += DIRLEN; + c->offset++; /* BUG??? (was DIRLEN: skip entry) */ break; case 1: - convD2M(&dir, d); - m += DIRLEN; - d += DIRLEN; + dsz = convD2M(&dir, (uchar*)d, n-m); + if(dsz <= BIT16SZ){ /* <= not < because this isn't stat; read is stuck */ + if(m == 0) + return -1; + return m; + } + m += dsz; + d += dsz; break; } } @@ -238,7 +324,7 @@ devopen(Chan *c, int omode, Dirtab *tab, int ntab, Devgen *gen) Dir dir; for(i=0;; i++) { - switch((*gen)(c, tab, ntab, i, &dir)){ + switch((*gen)(c, nil, tab, ntab, i, &dir)){ case -1: goto Return; case 0: @@ -253,7 +339,7 @@ devopen(Chan *c, int omode, Dirtab *tab, int ntab, Devgen *gen) } Return: c->offset = 0; - if((c->qid.path&CHDIR) && omode!=OREAD) + if((c->qid.type&QTDIR) && omode!=OREAD) error(Eperm); c->mode = openmode(omode); c->flag |= COPEN; @@ -305,8 +391,9 @@ devremove(Chan*) error(Eperm); } -void -devwstat(Chan*, char*) +int +devwstat(Chan*, uchar*, int) { error(Eperm); + return 0; } diff --git a/port/devaudio.c b/port/devaudio.c index 687a8018b7d3a2aece30307bd2e04fc444ed7ce8..027d129bb52f4d17d94b4d62cf839bfd2b4a9cb8 100644 --- a/port/devaudio.c +++ b/port/devaudio.c @@ -46,6 +46,7 @@ enum Dirtab audiodir[] = { + ".", {Qdir, 0, QTDIR}, 0, DMDIR|0555, "audio", {Qaudio}, 0, 0666, "volume", {Qvolume}, 0, 0666, "audiostat",{Qstatus}, 0, 0444, @@ -144,7 +145,6 @@ sbcmd(int val) s = inb(blaster.wstatus); if((s & 0x80) == 0) { outb(blaster.write, val); - delay(1); return 0; } } @@ -190,9 +190,7 @@ mxcmd(int addr, int val) { outb(blaster.mixaddr, addr); - delay(1); outb(blaster.mixdata, val); - delay(1); return 1; } @@ -844,16 +842,16 @@ audioattach(char *param) return devattach('A', param); } -static int -audiowalk(Chan *c, char *name) +static Walkqid* +audiowalk(Chan *c, Chan *nc, char **name, int nname) { - return devwalk(c, name, audiodir, nelem(audiodir), devgen); + return devwalk(c, nc, name, nname, audiodir, nelem(audiodir), devgen); } -static void -audiostat(Chan *c, char *db) +static int +audiostat(Chan *c, uchar *db, int n) { - devstat(c, db, audiodir, nelem(audiodir), devgen); + return devstat(c, db, n, audiodir, nelem(audiodir), devgen); } static Chan* @@ -864,7 +862,7 @@ audioopen(Chan *c, int omode) if(audio.major != 4) error(Emajor); - switch(c->qid.path & ~CHDIR) { + switch((ulong)c->qid.path) { default: error(Eperm); break; @@ -909,9 +907,9 @@ audioclose(Chan *c) { Buf *b; - switch(c->qid.path & ~CHDIR) { + switch((ulong)c->qid.path) { default: - error(Eperm); /* can't happen */ + error(Eperm); break; case Qdir: @@ -935,8 +933,10 @@ audioclose(Chan *c) pokeaudio(); } audio.amode = Aclosed; - while(waserror()) - ; + if(waserror()){ + qunlock(&audio); + nexterror(); + } while(audio.active) waitaudio(); setempty(); @@ -960,7 +960,7 @@ audioread(Chan *c, void *v, long n, vlong off) n0 = n; a = v; - switch(c->qid.path & ~CHDIR) { + switch((ulong)c->qid.path) { default: error(Eperm); break; @@ -1066,7 +1066,7 @@ audiowrite(Chan *c, void *vp, long n, vlong) a = vp; n0 = n; - switch(c->qid.path & ~CHDIR) { + switch((ulong)c->qid.path) { default: error(Eperm); break; @@ -1211,7 +1211,6 @@ Dev audiodevtab = { devreset, audioinit, audioattach, - devclone, audiowalk, audiostat, audioopen, diff --git a/port/devcap.c b/port/devcap.c new file mode 100644 index 0000000000000000000000000000000000000000..a4e6f59b0f4686fa75a440c64f4a46c4f1e9c930 --- /dev/null +++ b/port/devcap.c @@ -0,0 +1,266 @@ +#include "u.h" +#include "../port/lib.h" +#include "mem.h" +#include "dat.h" +#include "fns.h" +#include "../port/error.h" + +#include "netif.h" +#include + +enum +{ + Hashlen= SHA1dlen, + Maxhash= 256, +}; + +/* + * if a process knows cap->cap, it can change user + * to capabilty->user. + */ +typedef struct Caphash Caphash; +struct Caphash +{ + Caphash *next; + char hash[Hashlen]; + ulong ticks; +}; + +struct +{ + QLock; + int opens; + Caphash *first; + int nhash; +} capalloc; + +enum +{ + Qdir, + Qhash, + Quse, +}; + +Dirtab capdir[] = +{ + ".", {Qdir,0,QTDIR}, 0, DMDIR|0500, + "caphash", {Qhash}, 0, 0200, + "capuse", {Quse}, 0, 0222, +}; +#define NCAPDIR 3 + +static Chan* +capattach(char *spec) +{ + return devattach(L'¤', spec); +} + +static Walkqid* +capwalk(Chan *c, Chan *nc, char **name, int nname) +{ + return devwalk(c, nc, name, nname, capdir, NCAPDIR, devgen); +} + +static int +capstat(Chan *c, uchar *db, int n) +{ + return devstat(c, db, n, capdir, NCAPDIR, devgen); +} + +/* + * if the stream doesn't exist, create it + */ +static Chan* +capopen(Chan *c, int omode) +{ + if(c->qid.type & QTDIR){ + if(omode != OREAD) + error(Ebadarg); + c->mode = omode; + c->flag |= COPEN; + c->offset = 0; + return c; + } + + if(waserror()){ + qunlock(&capalloc); + nexterror(); + } + qlock(&capalloc); + switch((ulong)c->qid.path){ + case Qhash: + if(capalloc.opens > 0){ + qunlock(&capalloc); + error("exclusive use"); + } + capalloc.opens++; + break; + } + poperror(); + qunlock(&capalloc); + + c->mode = openmode(omode); + c->flag |= COPEN; + c->offset = 0; + return c; +} + +static Caphash* +remcap(uchar *hash) +{ + Caphash *t, **l; + + qlock(&capalloc); + + /* find the matching capability */ + for(l = &capalloc.first; *l != nil;){ + t = *l; + if(memcmp(hash, t->hash, Hashlen) == 0) + break; + l = &t->next; + } + t = *l; + if(t != nil){ + capalloc.nhash--; + *l = t->next; + } + qunlock(&capalloc); + + return t; +} + +/* add a capability, throwing out any old ones */ +static void +addcap(uchar *hash) +{ + Caphash *p, *t, **l; + + p = smalloc(sizeof *p); + memmove(p->hash, hash, Hashlen); + p->next = nil; + p->ticks = m->ticks; + + qlock(&capalloc); + + /* trim extras */ + while(capalloc.nhash >= Maxhash){ + t = capalloc.first; + if(t == nil) + panic("addcap"); + capalloc.first = t->next; + free(t); + capalloc.nhash--; + } + + /* add new one */ + for(l = &capalloc.first; *l != nil; l = &(*l)->next) + ; + *l = p; + capalloc.nhash++; + + qunlock(&capalloc); +} + +static void +capclose(Chan *c) +{ + if(c->flag & COPEN) + if(c->qid.path == Qhash){ + qlock(&capalloc); + capalloc.opens--; + qunlock(&capalloc); + } +} + +static long +capread(Chan *c, void *va, long n, vlong) +{ + switch((ulong)c->qid.path){ + case Qdir: + return devdirread(c, va, n, capdir, nelem(capdir), devgen); + + default: + error(Eperm); + break; + } + return n; +} + +static long +capwrite(Chan *c, void *va, long n, vlong) +{ + Caphash *p; + char *cp; + uchar hash[Hashlen]; + char *key, *user; + char err[256]; + + switch((ulong)c->qid.path){ + case Qhash: + if(n < Hashlen) + error(Eshort); + memmove(hash, va, Hashlen); + addcap(hash); + break; + + case Quse: + /* copy key to avoid a fault in hmac_xx */ + cp = nil; + if(waserror()){ + free(cp); + nexterror(); + } + cp = smalloc(n+1); + memmove(cp, va, n); + cp[n] = 0; + + user = cp; + key = strchr(cp, '@'); + if(key == nil) + error(Eshort); + *key++ = 0; + + hmac_sha1((uchar*)user, strlen(user), (uchar*)key, strlen(key), hash, nil); + + p = remcap(hash); + if(p == nil){ + snprint(err, sizeof err, "invalid capability %s@%s", user, key); + error(err); + } + + /* set user id */ + kstrdup(&up->user, user); + up->basepri = PriNormal; + + free(p); + free(cp); + poperror(); + break; + + default: + error(Eperm); + break; + } + + return n; +} + +Dev capdevtab = { + L'¤', + "cap", + + devreset, + devinit, + capattach, + capwalk, + capstat, + capopen, + devcreate, + capclose, + capread, + devbread, + capwrite, + devbwrite, + devremove, + devwstat, +}; diff --git a/port/devcons.c b/port/devcons.c index 60c9c59b8a38c12c67fbe16c7fc856506c836122..949ce4808050f012b250c3b5283db3438cc22ab2 100644 --- a/port/devcons.c +++ b/port/devcons.c @@ -5,11 +5,17 @@ #include "fns.h" #include "../port/error.h" +#include + void (*consdebug)(void) = nil; +void (*screenputs)(char*, int) = nil; +void (*serialputs)(char*, int) = nil; Queue* kbdq; /* unprocessed console input */ Queue* lineq; /* processed console input */ -Queue* printq; /* console output */ +Queue* serialoq; /* serial console output */ +Queue* kprintoq; /* console output, for /dev/kprint */ +Lock kprintinuse; /* test and set whether /dev/kprint is open */ static struct { @@ -31,7 +37,7 @@ static struct char *ie; } kbd; -char sysname[NAMELEN]; +char *sysname; vlong fasthz; static void seedrand(void); @@ -52,8 +58,8 @@ printinit(void) int consactive(void) { - if(printq) - return qlen(printq) > 0; + if(serialoq) + return qlen(serialoq) > 0; return 0; } @@ -81,38 +87,47 @@ putstrn0(char *str, int n, int usewrite) char *t; /* - * if there's an attached bit mapped display, - * put the message there. screenputs is defined - * as a null macro for systems that have no such - * display. - */ - screenputs(str, n); - - /* + * if someone is reading /dev/kprint and the message + * is from the kernel (as opposed to from conswrite), + * put the message there. + * if not and there's an attached bit mapped display, + * put the message there. + * * if there's a serial line being used as a console, * put the message there. */ - if(printq == 0) + if(kprintoq != nil && !qisclosed(kprintoq)){ + if(usewrite) + qwrite(kprintoq, str, n); + else + qiwrite(kprintoq, str, n); + }else if(screenputs != nil) + screenputs(str, n); + + if(serialoq == nil){ + if(serialputs != nil) + serialputs(str, n); return; + } while(n > 0) { t = memchr(str, '\n', n); if(t && !kbd.raw) { m = t-str; if(usewrite){ - qwrite(printq, str, m); - qwrite(printq, "\r\n", 2); + qwrite(serialoq, str, m); + qwrite(serialoq, "\r\n", 2); } else { - qiwrite(printq, str, m); - qiwrite(printq, "\r\n", 2); + qiwrite(serialoq, str, m); + qiwrite(serialoq, "\r\n", 2); } n -= m+1; str = t+1; } else { if(usewrite) - qwrite(printq, str, n); + qwrite(serialoq, str, n); else - qiwrite(printq, str, n); + qiwrite(serialoq, str, n); break; } } @@ -190,8 +205,10 @@ iprint(char *fmt, ...) va_start(arg, fmt); n = doprint(buf, buf+sizeof(buf), fmt, arg) - buf; va_end(arg); - serialputs(buf, n); -// screenputs(buf, n); + if(screenputs != nil) + screenputs(buf, n); + if(serialputs != nil) + serialputs(buf, n); splx(s); return n; @@ -203,6 +220,13 @@ panic(char *fmt, ...) int n; va_list arg; char buf[PRINTSIZE]; + static int panicking; + + kprintoq = nil; /* don't try to write to /dev/kprint */ + + if(panicking) + for(;;); + panicking = 1; splhi(); strcpy(buf, "panic: "); @@ -210,7 +234,8 @@ panic(char *fmt, ...) n = doprint(buf+strlen(buf), buf+sizeof(buf), fmt, arg) - buf; va_end(arg); buf[n] = '\n'; - serialputs(buf, n+1); + if(serialputs != nil) + serialputs(buf, n+1); if(consdebug) consdebug(); spllo(); @@ -285,7 +310,7 @@ echoscreen(char *buf, int n) } static void -echoprintq(char *buf, int n) +echoserialoq(char *buf, int n) { char *e, *p; char ebuf[128]; @@ -295,7 +320,7 @@ echoprintq(char *buf, int n) e = ebuf + sizeof(ebuf) - 4; while(n-- > 0){ if(p >= e){ - qiwrite(printq, ebuf, p - ebuf); + qiwrite(serialoq, ebuf, p - ebuf); p = ebuf; } x = *buf++; @@ -310,7 +335,7 @@ echoprintq(char *buf, int n) *p++ = x; } if(p != ebuf) - qiwrite(printq, ebuf, p - ebuf); + qiwrite(serialoq, ebuf, p - ebuf); } void @@ -385,9 +410,10 @@ echo(char *buf, int n) qproduce(kbdq, buf, n); if(kbd.raw) return; - echoscreen(buf, n); - if(printq) - echoprintq(buf, n); + if(screenputs != nil) + echoscreen(buf, n); + if(serialoq) + echoserialoq(buf, n); } /* @@ -476,18 +502,17 @@ kbdputcinit(void) enum{ Qdir, - Qauth, - Qauthcheck, - Qauthent, Qbintime, Qcons, Qconsctl, Qcputime, Qdrivers, Qkey, + Qkprint, Qhostdomain, Qhostowner, Qnull, + Qosversion, Qpgrpid, Qpid, Qppid, @@ -507,18 +532,18 @@ enum }; static Dirtab consdir[]={ - "authenticate", {Qauth}, 0, 0666, - "authcheck", {Qauthcheck}, 0, 0666, - "authenticator", {Qauthent}, 0, 0666, + ".", {Qdir, 0, QTDIR}, 0, DMDIR|0555, "bintime", {Qbintime}, 24, 0664, "cons", {Qcons}, 0, 0660, "consctl", {Qconsctl}, 0, 0220, "cputime", {Qcputime}, 6*NUMSIZE, 0444, "drivers", {Qdrivers}, 0, 0644, "hostdomain", {Qhostdomain}, DOMLEN, 0664, - "hostowner", {Qhostowner}, NAMELEN, 0664, + "hostowner", {Qhostowner}, 0, 0664, "key", {Qkey}, DESKEYLEN, 0622, + "kprint", {Qkprint, 0, QTEXCL}, 0, DMEXCL|0440, "null", {Qnull}, 0, 0666, + "osversion", {Qosversion}, 0, 0444, "pgrpid", {Qpgrpid}, NUMSIZE, 0444, "pid", {Qpid}, NUMSIZE, 0444, "ppid", {Qppid}, NUMSIZE, 0444, @@ -528,7 +553,7 @@ static Dirtab consdir[]={ "sysname", {Qsysname}, 0, 0664, "sysstat", {Qsysstat}, 0, 0666, "time", {Qtime}, NUMSIZE+3*VLNUMSIZE, 0664, - "user", {Quser}, NAMELEN, 0666, + "user", {Quser}, 0, 0666, "zero", {Qzero}, 0, 0444, }; @@ -575,39 +600,54 @@ consattach(char *spec) return devattach('c', spec); } -static int -conswalk(Chan *c, char *name) +static Walkqid* +conswalk(Chan *c, Chan *nc, char **name, int nname) { - return devwalk(c, name, consdir, nelem(consdir), devgen); + return devwalk(c, nc, name,nname, consdir, nelem(consdir), devgen); } -static void -consstat(Chan *c, char *dp) +static int +consstat(Chan *c, uchar *dp, int n) { - devstat(c, dp, consdir, nelem(consdir), devgen); + return devstat(c, dp, n, consdir, nelem(consdir), devgen); } static Chan* consopen(Chan *c, int omode) { - c->aux = 0; - switch(c->qid.path){ + c->aux = nil; + c = devopen(c, omode, consdir, nelem(consdir), devgen); + switch((ulong)c->qid.path){ case Qconsctl: - if(!iseve()) - error(Eperm); qlock(&kbd); kbd.ctl++; qunlock(&kbd); break; + + case Qkprint: + if(!canlock(&kprintinuse)){ + c->flag &= ~COPEN; + error(Einuse); + } + if(kprintoq == nil){ + kprintoq = qopen(8*1024, -1, 0, 0); + if(kprintoq == nil){ + c->flag &= ~COPEN; + error(Enomem); + } + qnoblock(kprintoq, 1); + }else + qreopen(kprintoq); + break; } - return devopen(c, omode, consdir, nelem(consdir), devgen); + return c; } static void consclose(Chan *c) { + switch((ulong)c->qid.path){ /* last close of control file turns off raw */ - switch(c->qid.path){ case Qconsctl: if(c->flag&COPEN){ qlock(&kbd); @@ -616,10 +656,14 @@ consclose(Chan *c) qunlock(&kbd); } break; - case Qauth: - case Qauthcheck: - case Qauthent: - authclose(c); + + /* close of kprint allows other opens */ + case Qkprint: + if(c->flag & COPEN){ + unlock(&kprintinuse); + qhangup(kprintoq, nil); + } + break; } } @@ -636,7 +680,7 @@ consread(Chan *c, void *buf, long n, vlong off) if(n <= 0) return n; - switch(c->qid.path & ~CHDIR){ + switch((ulong)c->qid.path){ case Qdir: return devdirread(c, buf, n, consdir, nelem(consdir), devgen); @@ -708,6 +752,9 @@ consread(Chan *c, void *buf, long n, vlong off) memmove(buf, tmp+k, n); return n; + case Qkprint: + return qread(kprintoq, buf, n); + case Qpgrpid: return readnum((ulong)offset, buf, n, up->pgrp->pgrpid, NUMSIZE); @@ -726,15 +773,6 @@ consread(Chan *c, void *buf, long n, vlong off) case Qkey: return keyread(buf, n, offset); - case Qauth: - return authread(c, cbuf, n); - - case Qauthcheck: - return authcheckread(c, cbuf, n); - - case Qauthent: - return authentread(c, cbuf, n); - case Qhostowner: return readstr((ulong)offset, buf, n, eve); @@ -784,6 +822,8 @@ consread(Chan *c, void *buf, long n, vlong off) return readstr((ulong)offset, buf, n, tmp); case Qsysname: + if(sysname == nil) + return 0; return readstr((ulong)offset, buf, n, sysname); case Qrandom: @@ -804,8 +844,12 @@ consread(Chan *c, void *buf, long n, vlong off) memset(buf, 0, n); return n; + case Qosversion: + n = readstr((ulong)offset, buf, n, "2000"); + return n; + default: - print("consread %lux\n", c->qid.path); + print("consread 0x%llux\n", c->qid.path); error(Egreg); } return -1; /* never reached */ @@ -822,7 +866,7 @@ conswrite(Chan *c, void *va, long n, vlong off) Chan *swc; ulong offset = off; - switch(c->qid.path){ + switch((ulong)c->qid.path){ case Qcons: /* * Can't page fault in putstrn, so copy the data locally. @@ -890,15 +934,6 @@ conswrite(Chan *c, void *va, long n, vlong off) case Quser: return userwrite(a, n); - case Qauth: - return authwrite(c, a, n); - - case Qauthcheck: - return authcheck(c, a, n); - - case Qauthent: - return authentwrite(c, a, n); - case Qnull: break; @@ -958,16 +993,17 @@ conswrite(Chan *c, void *va, long n, vlong off) case Qsysname: if(offset != 0) error(Ebadarg); - if(n <= 0 || n >= NAMELEN) + if(n <= 0 || n >= sizeof buf) error(Ebadarg); - strncpy(sysname, a, n); - sysname[n] = 0; - if(sysname[n-1] == '\n') - sysname[n-1] = 0; + strncpy(buf, a, n); + buf[n] = 0; + if(buf[n-1] == '\n') + buf[n-1] = 0; + kstrdup(&sysname, buf); break; default: - print("conswrite: %lud\n", c->qid.path); + print("conswrite: 0x%llux\n", c->qid.path); error(Egreg); } return n; @@ -976,9 +1012,9 @@ conswrite(Chan *c, void *va, long n, vlong off) void setterm(char *f) { - char buf[2*NAMELEN]; + char buf[64]; - sprint(buf, f, conffile); + snprint(buf, sizeof buf, f, conffile); ksetenv("terminal", buf); } @@ -989,7 +1025,6 @@ Dev consdevtab = { devreset, consinit, consattach, - devclone, conswalk, consstat, consopen, diff --git a/port/devdraw.c b/port/devdraw.c index 35cb094207d63d00cbd1990854c090ba8c16b678..c40f29217d91f6fef5f48af98be003356ab97a58 100644 --- a/port/devdraw.c +++ b/port/devdraw.c @@ -4,7 +4,6 @@ #include "dat.h" #include "fns.h" #include "../port/error.h" -#include #define Image IMAGE #include @@ -32,8 +31,8 @@ enum */ #define QSHIFT 4 /* location in qid of client # */ -#define QID(q) (((q).path&0x0000000F)>>0) -#define CLIENTPATH(q) ((q&0x07FFFFFF0)>>QSHIFT) +#define QID(q) ((((ulong)(q).path)&0x0000000F)>>0) +#define CLIENTPATH(q) ((((ulong)q)&0x7FFFFFF0)>>QSHIFT) #define CLIENT(q) CLIENTPATH((q).path) #define NHASH (1<<5) @@ -184,30 +183,30 @@ static char Enamed[] = "image already has name"; static char Ewrongname[] = "wrong name for image"; static int -drawgen(Chan *c, Dirtab *tab, int x, int s, Dir *dp) +drawgen(Chan *c, char*, Dirtab*, int, int s, Dir *dp) { int t; Qid q; ulong path; Client *cl; - char buf[NAMELEN]; - USED(tab, x); q.vers = 0; if(s == DEVDOTDOT){ switch(QID(c->qid)){ case Qtopdir: case Q2nd: - devdir(c, (Qid){CHDIR|Qtopdir, 0}, "#i", 0, eve, 0500, dp); + mkqid(&q, Qtopdir, 0, QTDIR); + devdir(c, q, "#i", 0, eve, 0500, dp); break; case Q3rd: cl = drawclientofpath(c->qid.path); if(cl == nil) - strcpy(buf, "??"); + strcpy(up->genbuf, "??"); else - sprint(buf, "%d", cl->clientid); - devdir(c, (Qid){CHDIR|Q2nd, 0}, buf, 0, eve, 0500, dp); + sprint(up->genbuf, "%d", cl->clientid); + mkqid(&q, Q2nd, 0, QTDIR); + devdir(c, q, up->genbuf, 0, eve, 0500, dp); break; default: panic("drawwalk %lux", c->qid.path); @@ -218,10 +217,11 @@ drawgen(Chan *c, Dirtab *tab, int x, int s, Dir *dp) /* * Top level directory contains the name of the device. */ - if(c->qid.path == CHDIR){ + t = QID(c->qid); + if(t == Qtopdir){ switch(s){ case 0: - q = (Qid){CHDIR|Q2nd, 0}; + mkqid(&q, Q2nd, 0, QTDIR); devdir(c, q, "draw", 0, eve, 0555, dp); break; default: @@ -233,19 +233,18 @@ drawgen(Chan *c, Dirtab *tab, int x, int s, Dir *dp) /* * Second level contains "new" plus all the clients. */ - t = QID(c->qid); if(t == Q2nd || t == Qnew){ if(s == 0){ - q = (Qid){Qnew, 0}; - devdir(c, q, "new", 0, eve, 0600, dp); + mkqid(&q, Qnew, 0, QTFILE); + devdir(c, q, "new", 0, eve, 0666, dp); } else if(s <= sdraw.nclient){ cl = sdraw.client[s-1]; if(cl == 0) return 0; - sprint(buf, "%d", cl->clientid); - q = (Qid){CHDIR|(s<genbuf, "%d", cl->clientid); + mkqid(&q, (s<genbuf, 0, eve, 0555, dp); return 1; } else @@ -256,23 +255,24 @@ drawgen(Chan *c, Dirtab *tab, int x, int s, Dir *dp) /* * Third level. */ - path = c->qid.path&~(CHDIR|((1<qid.path&~(((1<qid.vers; + q.type = QTFILE; switch(s){ case 0: - q = (Qid){path|Qcolormap, c->qid.vers}; + q.path = path|Qcolormap; devdir(c, q, "colormap", 0, eve, 0600, dp); break; case 1: - q = (Qid){path|Qctl, c->qid.vers}; + q.path = path|Qctl; devdir(c, q, "ctl", 0, eve, 0600, dp); break; case 2: - q = (Qid){path|Qdata, c->qid.vers}; + q.path = path|Qdata; devdir(c, q, "data", 0, eve, 0600, dp); break; case 3: - q = (Qid){path|Qrefresh, c->qid.vers}; + q.path = path|Qrefresh; devdir(c, q, "refresh", 0, eve, 0400, dp); break; default: @@ -888,18 +888,18 @@ drawattach(char *spec) return devattach('i', spec); } -int -drawwalk(Chan *c, char *name) +Walkqid* +drawwalk(Chan *c, Chan *nc, char **name, int nname) { if(screendata.bdata == nil) error("no frame buffer"); - return devwalk(c, name, 0, 0, drawgen); + return devwalk(c, nc, name, nname, 0, 0, drawgen); } -static void -drawstat(Chan *c, char *db) +static int +drawstat(Chan *c, uchar *db, int n) { - devstat(c, db, 0, 0, drawgen); + return devstat(c, db, n, 0, 0, drawgen); } static Chan* @@ -907,7 +907,7 @@ drawopen(Chan *c, int omode) { Client *cl; - if(c->qid.path & CHDIR) + if(c->qid.type & QTDIR) return devopen(c, omode, 0, 0, drawgen); qlock(&sdraw); @@ -1014,7 +1014,7 @@ drawread(Chan *c, void *a, long n, vlong off) char buf[16]; USED(offset); - if(c->qid.path & CHDIR) + if(c->qid.type & QTDIR) return devdirread(c, a, n, 0, 0, drawgen); cl = drawclient(c); qlock(&sdraw); @@ -1128,7 +1128,7 @@ drawwrite(Chan *c, void *a, long n, vlong off) ulong offset = off; USED(offset); - if(c->qid.path & CHDIR) + if(c->qid.type & QTDIR) error(Eisdir); cl = drawclient(c); qlock(&sdraw); @@ -1225,7 +1225,7 @@ printmesg(char *fmt, uchar *a, int plsprnt) char *p, *q; int s; - if(1 || plsprnt==0){ + if(1|| plsprnt==0){ SET(s,q,p); USED(fmt, a, buf, p, q, s); return; @@ -1924,7 +1924,6 @@ Dev drawdevtab = { devreset, devinit, drawattach, - devclone, drawwalk, drawstat, drawopen, diff --git a/port/devdup.c b/port/devdup.c index 229e5cc523cbfc38f5dfd02b6e3ed128506960a1..eca7ec6368278897f728512c140e5c78f4f0d74a 100644 --- a/port/devdup.c +++ b/port/devdup.c @@ -5,24 +5,37 @@ #include "fns.h" #include "../port/error.h" +/* Qid is (2*fd + (file is ctl))+1 */ + static int -dupgen(Chan *c, Dirtab*, int, int s, Dir *dp) +dupgen(Chan *c, char *, Dirtab*, int, int s, Dir *dp) { - char buf[8]; Fgrp *fgrp = up->fgrp; Chan *f; static int perm[] = { 0400, 0200, 0600, 0 }; + int p; + Qid q; if(s == DEVDOTDOT){ - devdir(c, c->qid, "#d", 0, eve, 0555, dp); + devdir(c, c->qid, ".", 0, eve, DMDIR|0555, dp); return 1; } - if(s > fgrp->maxfd) + if(s == 0) + return 0; + s--; + if(s > 2*fgrp->maxfd) return -1; - if((f=fgrp->fd[s]) == 0) + if((f=fgrp->fd[s/2]) == nil) return 0; - sprint(buf, "%d", s); - devdir(c, (Qid){s, 0}, buf, 0, eve, perm[f->mode&3], dp); + if(s & 1){ + p = 0600; + sprint(up->genbuf, "%dctl", s/2); + }else{ + p = perm[f->mode&3]; + sprint(up->genbuf, "%d", s/2); + } + mkqid(&q, s+1, 0, QTFILE); + devdir(c, q, up->genbuf, 0, eve, p, dp); return 1; } @@ -32,24 +45,25 @@ dupattach(char *spec) return devattach('d', spec); } -static int -dupwalk(Chan *c, char *name) +static Walkqid* +dupwalk(Chan *c, Chan *nc, char **name, int nname) { - return devwalk(c, name, (Dirtab *)0, 0, dupgen); + return devwalk(c, nc, name, nname, (Dirtab *)0, 0, dupgen); } -static void -dupstat(Chan *c, char *db) +static int +dupstat(Chan *c, uchar *db, int n) { - devstat(c, db, (Dirtab *)0, 0L, dupgen); + return devstat(c, db, n, (Dirtab *)0, 0L, dupgen); } static Chan* dupopen(Chan *c, int omode) { Chan *f; + int fd, twicefd; - if(c->qid.path == CHDIR){ + if(c->qid.type == QTDIR){ if(omode != 0) error(Eisdir); c->mode = 0; @@ -57,10 +71,18 @@ dupopen(Chan *c, int omode) c->offset = 0; return c; } - fdtochan(c->qid.path, openmode(omode), 0, 0); /* error check only */ - f = up->fgrp->fd[c->qid.path]; - cclose(c); - incref(f); + twicefd = c->qid.path - 1; + fd = twicefd/2; + if((twicefd & 1)){ + /* ctl file */ + f = c; + }else{ + /* fd file */ + fdtochan(fd, openmode(omode), 0, 0); /* error check only */ + f = up->fgrp->fd[fd]; + cclose(c); + incref(f); + } if(omode & OCEXEC) f->flag |= CCEXEC; return f; @@ -72,18 +94,36 @@ dupclose(Chan*) } static long -dupread(Chan *c, void *va, long n, vlong) +dupread(Chan *c, void *va, long n, vlong offset) { char *a = va; + char buf[256]; + int fd, twicefd; + Fgrp *f; - if(c->qid.path != CHDIR) - panic("dupread"); - return devdirread(c, a, n, (Dirtab *)0, 0L, dupgen); + if(c->qid.type == QTDIR) + return devdirread(c, a, n, (Dirtab *)0, 0L, dupgen); + twicefd = c->qid.path - 1; + fd = twicefd/2; + f = up->fgrp; + if(twicefd & 1){ + if(fd<0 || f->nfd<=fd) + error(Ebadfd); + c = fdtochan(fd, -1, 0, 0); + snprint(buf, sizeof buf, "%d %ld", fd, c->iounit); + return readstr((ulong)offset, va, n, buf); + } + panic("dupread"); + return 0; } static long -dupwrite(Chan*, void*, long, vlong) +dupwrite(Chan *c, void *va, long n, vlong) { + if(c->qid.path & 1){ + print("do ctl write\n"); + return -1; + } panic("dupwrite"); return 0; /* not reached */ } @@ -95,7 +135,6 @@ Dev dupdevtab = { devreset, devinit, dupattach, - devclone, dupwalk, dupstat, dupopen, diff --git a/port/devenv.c b/port/devenv.c index 1e71f8d751bd0b207ba77363717c68b796e79103..44452ee785b5debffef1703ab4088a552164383e 100644 --- a/port/devenv.c +++ b/port/devenv.c @@ -12,13 +12,13 @@ enum }; static int -envgen(Chan *c, Dirtab*, int, int s, Dir *dp) +envgen(Chan *c, char*, Dirtab*, int, int s, Dir *dp) { Egrp *eg; Evalue *e; if(s == DEVDOTDOT){ - devdir(c, c->qid, "#e", 0, eve, 0775, dp); + devdir(c, c->qid, "#e", 0, eve, DMDIR|0775, dp); return 1; } @@ -33,7 +33,9 @@ envgen(Chan *c, Dirtab*, int, int s, Dir *dp) return -1; } - devdir(c, e->qid, e->name, e->len, eve, 0666, dp); + /* make sure name string continues to exist after we release lock */ + kstrcpy(up->genbuf, e->name, sizeof up->genbuf); + devdir(c, e->qid, up->genbuf, e->len, eve, 0666, dp); qunlock(eg); return 1; } @@ -54,34 +56,18 @@ envattach(char *spec) return devattach('e', spec); } -static int -envwalk(Chan *c, char *name) +static Walkqid* +envwalk(Chan *c, Chan *nc, char **name, int nname) { - Evalue *e; - Egrp *eg; - int rv; - - if(c->qid.path == CHDIR && name[0] != '.'){ - rv = 0; - eg = up->egrp; - qlock(eg); - for(e = eg->entries; e; e = e->link) - if(strcmp(e->name, name) == 0){ - rv = 1; - c->qid = e->qid; - } - qunlock(eg); - return rv; - } else - return devwalk(c, name, 0, 0, envgen); + return devwalk(c, nc, name, nname, 0, 0, envgen); } -static void -envstat(Chan *c, char *db) +static int +envstat(Chan *c, uchar *db, int n) { - if(c->qid.path & CHDIR) + if(c->qid.type & QTDIR) c->qid.vers = up->egrp->vers; - devstat(c, db, 0, 0, envgen); + return devstat(c, db, n, 0, 0, envgen); } static Chan* @@ -91,7 +77,7 @@ envopen(Chan *c, int omode) Evalue *e; eg = up->egrp; - if(c->qid.path & CHDIR) { + if(c->qid.type & QTDIR) { if(omode != OREAD) error(Eperm); } @@ -122,7 +108,7 @@ envcreate(Chan *c, char *name, int omode, ulong) Egrp *eg; Evalue *e; - if(c->qid.path != CHDIR) + if(c->qid.type != QTDIR) error(Eperm); omode = openmode(omode); @@ -162,7 +148,7 @@ envremove(Chan *c) Egrp *eg; Evalue *e, **l; - if(c->qid.path & CHDIR) + if(c->qid.type & QTDIR) error(Eperm); eg = up->egrp; @@ -207,7 +193,7 @@ envread(Chan *c, void *a, long n, vlong off) Evalue *e; ulong offset = off; - if(c->qid.path & CHDIR) + if(c->qid.type & QTDIR) return devdirread(c, a, n, 0, 0, envgen); eg = up->egrp; @@ -275,7 +261,6 @@ Dev envdevtab = { devreset, devinit, envattach, - devclone, envwalk, envstat, envopen, @@ -336,7 +321,7 @@ void ksetenv(char *ename, char *eval) { Chan *c; - char buf[2*NAMELEN]; + char buf[2*KNAMELEN]; sprint(buf, "#e/%s", ename); c = namec(buf, Acreate, OWRITE, 0600); diff --git a/port/devintrts.c b/port/devintrts.c deleted file mode 100644 index 4c64d08202fedbe761aa566d5cabd93fb024ee49..0000000000000000000000000000000000000000 --- a/port/devintrts.c +++ /dev/null @@ -1,134 +0,0 @@ -/* - */ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "../port/error.h" - -enum { - Qdir, - Qintrts, -}; - -static Dirtab intrtsdir[] = { - "intrts", { Qintrts, 0 }, 0, 0666, -}; - -void (*saveintrts)(void) = nil; - -/* interrupt timestamps, trap() fills intrts each interrupt */ -uvlong intrts; -static struct { - Lock; - int vno; /* vector to save timestamps for */ - int n; /* number of valid timestamps in ts[] */ - uvlong ts[128]; /* time stamps */ -} tsalloc; - -/* called with interrupts off by interrupt routine */ -void -_saveintrts(void) -{ - ilock(&tsalloc); - if(tsalloc.n < nelem(tsalloc.ts)) - tsalloc.ts[tsalloc.n++] = m->intrts; - iunlock(&tsalloc); -} - -/* read interrupt timestamps */ -static long -readintrts(void *buf, int n) -{ - n /= sizeof(uvlong); - if(n <= 0) - return 0; - ilock(&tsalloc); - if(n > tsalloc.n) - n = tsalloc.n; - memmove(buf, tsalloc.ts, n*sizeof(uvlong)); - tsalloc.n = 0; - iunlock(&tsalloc); - return n*sizeof(uvlong); -} - - -static void -intrtsreset(void) -{ - saveintrts = _saveintrts; -} - -static Chan* -intrtsattach(char* spec) -{ - return devattach('Z', spec); /* everything good was taken */ -} - -int -intrtswalk(Chan* c, char* name) -{ - return devwalk(c, name, intrtsdir, nelem(intrtsdir), devgen); -} - -static void -intrtsstat(Chan* c, char* dp) -{ - devstat(c, dp, intrtsdir, nelem(intrtsdir), devgen); -} - -static Chan* -intrtsopen(Chan* c, int omode) -{ - return devopen(c, omode, intrtsdir, nelem(intrtsdir), devgen); -} - -static void -intrtsclose(Chan*) -{ -} - -static long -intrtsread(Chan* c, void* a, long n, vlong) -{ - switch(c->qid.path & ~CHDIR){ - - case Qdir: - return devdirread(c, a, n, intrtsdir, nelem(intrtsdir), devgen); - - case Qintrts: - return readintrts(a, n); - } - - error(Eperm); - return 0; -} - -static long -intrtswrite(Chan*, void*, long, vlong) -{ - error(Eperm); - return 0; -} - -Dev intrtsdevtab = { - 'Z', - "intrts", - - intrtsreset, - devinit, - intrtsattach, - devclone, - intrtswalk, - intrtsstat, - intrtsopen, - devcreate, - intrtsclose, - intrtsread, - devbread, - intrtswrite, - devbwrite, - devremove, - devwstat, -}; diff --git a/port/devkprof.c b/port/devkprof.c index 5da7c64a389115e7c6ba398de35bf8964fdb1d2e..7d562bb46c0338b867b629d3d8386bff86b865a8 100644 --- a/port/devkprof.c +++ b/port/devkprof.c @@ -24,6 +24,7 @@ enum{ Kprofctlqid, }; Dirtab kproftab[]={ + ".", {Kprofdirqid, 0, QTDIR}, 0, DMDIR|0600, "kpdata", {Kprofdataqid}, 0, 0600, "kpctl", {Kprofctlqid}, 0, 0600, }; @@ -41,8 +42,7 @@ _kproftimer(ulong pc) */ if(pc>=(ulong)spllo && pc<=(ulong)spldone) pc = m->splpc; - if(up && up->kppc) - pc = up->kppc; + kprof.buf[0] += TK2MS(1); if(kprof.minpc<=pc && pcqid.path == CHDIR){ + if(c->qid.type == QTDIR){ if(omode != OREAD) error(Eperm); } @@ -117,7 +117,7 @@ kprofread(Chan *c, void *va, long n, vlong off) uchar *a, *ea; ulong offset = off; - switch(c->qid.path & ~CHDIR){ + switch((int)c->qid.path){ case Kprofdirqid: return devdirread(c, va, n, kproftab, nelem(kproftab), devgen); @@ -154,7 +154,7 @@ kprofread(Chan *c, void *va, long n, vlong off) static long kprofwrite(Chan *c, void *a, long n, vlong) { - switch((int)(c->qid.path&~CHDIR)){ + switch((int)(c->qid.path)){ case Kprofctlqid: if(strncmp(a, "startclr", 8) == 0){ memset((char *)kprof.buf, 0, kprof.nbuf*SZ); @@ -177,7 +177,6 @@ Dev kprofdevtab = { devreset, kprofinit, kprofattach, - devclone, kprofwalk, kprofstat, kprofopen, diff --git a/port/devmnt.c b/port/devmnt.c index 7f04f66fd598eb2a32ed8e9936c54cfc217ab6a4..cdeec2218e985c8b17b8117326b1f4feab75c245 100644 --- a/port/devmnt.c +++ b/port/devmnt.c @@ -5,15 +5,17 @@ #include "fns.h" #include "../port/error.h" +#define MAXRPC (IOHDRSZ+8192) + 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 */ + Fcall reply; /* Incoming reply */ Mnt* m; /* Mount device during rpc */ Rendez r; /* Place to hang out */ - char* rpc; /* I/O Data buffer */ + uchar* rpc; /* I/O Data buffer */ char done; /* Rpc completed */ uvlong stime; /* start time for mnt statistics */ ulong reqlen; /* request length for mnt statistics */ @@ -33,26 +35,27 @@ struct Mntalloc int rpctag; }mntalloc; -static void mattach(Mnt*, Chan*, char*); -static void mntauth(Mnt*, Mntrpc*, char*, ushort); -static Mnt* mntchk(Chan*); -static void mntdirfix(uchar*, Chan*); -static Mntrpc* mntflushalloc(Mntrpc*); -static void mntflushfree(Mnt*, Mntrpc*); -static void mntfree(Mntrpc*); -static void mntgate(Mnt*); -static void mntpntfree(Mnt*); -static void mntqrm(Mnt*, Mntrpc*); -static Mntrpc* mntralloc(Chan*); -static long mntrdwr(int, Chan*, void*, long, vlong); -static long mnt9prdwr(int, Chan*, void*, long, vlong); -static void mntrpcread(Mnt*, Mntrpc*); -static void mountio(Mnt*, Mntrpc*); -static void mountmux(Mnt*, Mntrpc*); -static void mountrpc(Mnt*, Mntrpc*); -static int rpcattn(void*); -static void mclose(Mnt*, Chan*); -static Chan* mntchan(void); +void mattach(Mnt*, Chan*, char*); +void mntauth(Mnt*, Mntrpc*, char*, ushort); +Mnt* mntchk(Chan*); +void mntdirfix(uchar*, Chan*); +Mntrpc* mntflushalloc(Mntrpc*, ulong); +void mntflushfree(Mnt*, Mntrpc*); +void mntfree(Mntrpc*); +void mntgate(Mnt*); +void mntpntfree(Mnt*); +void mntqrm(Mnt*, Mntrpc*); +Mntrpc* mntralloc(Chan*, ulong); +long mntrdwr(int, Chan*, void*, long, vlong); +int mntrpcread(Mnt*, Mntrpc*); +void mountio(Mnt*, Mntrpc*); +void mountmux(Mnt*, Mntrpc*); +void mountrpc(Mnt*, Mntrpc*); +int rpcattn(void*); +void mclose(Mnt*, Chan*); +Chan* mntchan(void); + +char Esbadstat[] = "invalid directory entry received from server"; void (*mntstats)(int, Chan*, uvlong, ulong); @@ -66,6 +69,9 @@ mntreset(void) { mntalloc.id = 1; mntalloc.rpctag = Tagspace; + fmtinstall('F', fcallconv); + fmtinstall('D', dirconv); + fmtinstall('M', dirmodeconv); cinit(); } @@ -75,7 +81,6 @@ mntattach(char *muxattach) { Mnt *m; Chan *c, *mc; - char buf[NAMELEN]; struct bogus{ Chan *chan; char *spec; @@ -95,7 +100,7 @@ mntattach(char *muxattach) unlock(&mntalloc); c = mntchan(); if(waserror()) { - cclose(c); + chanfree(c); nexterror(); } mattach(m, c, bogus.spec); @@ -129,27 +134,21 @@ mntattach(char *muxattach) m->rip = 0; m->c = c; m->c->flag |= CMSG; - if(strncmp(bogus.spec, "mntblk=", 7) == 0) { - m->blocksize = strtoul(bogus.spec+7, 0, 0); - if(m->blocksize > MAXFDATA) - m->blocksize = MAXFDATA; - print("mount blk %d\n", m->blocksize); - bogus.spec = ""; - } - else - m->blocksize = MAXFDATA; + if(m->c->iounit == 0) + m->c->iounit = MAXRPC; m->flags = bogus.flags & ~MCACHE; incref(m->c); - sprint(buf, "#M%lud", m->id); - unlock(m); c = mntchan(); if(waserror()) { mclose(m, c); - cclose(c); + /* Close must not be called since it will + * call mnt recursively + */ + chanfree(c); nexterror(); } @@ -158,15 +157,15 @@ mntattach(char *muxattach) /* * Detect a recursive mount for a mount point served by exportfs. - * If CHDIR is clear in the returned qid, the foreign server is + * If QTDIR is clear in the returned qid, the foreign server is * requesting the mount point be folded into the connection * to the exportfs. In this case the remote mount driver does * the multiplexing. */ mc = m->c; - if(mc->type == devno('M', 0) && (c->qid.path&CHDIR) == 0) { + if(mc->type == devno('M', 0) && (c->qid.type&QTDIR) == 0) { mclose(m, c); - c->qid.path |= CHDIR; + c->qid.type |= QTDIR; c->mntptr = mc->mntptr; c->mchan = c->mntptr->c; c->mqid = c->qid; @@ -179,17 +178,12 @@ mntattach(char *muxattach) return c; } -/* - * start off the channel as a root device - * until we've really gotten it started so - * an early close won't run through devmnt again - */ -static Chan* +Chan* mntchan(void) { Chan *c; - c = devattach('/', 0); + c = devattach('M', 0); lock(&mntalloc); c->dev = mntalloc.id++; unlock(&mntalloc); @@ -197,13 +191,12 @@ mntchan(void) return c; } -static void +void mattach(Mnt *m, Chan *c, char *spec) { - ulong id; Mntrpc *r; - r = mntralloc(0); + r = mntralloc(0, m->c->iounit); c->mntptr = m; if(waserror()) { @@ -213,89 +206,116 @@ mattach(Mnt *m, Chan *c, char *spec) r->request.type = Tattach; r->request.fid = c->fid; - memmove(r->request.uname, up->user, NAMELEN); - strncpy(r->request.aname, spec, NAMELEN); - id = authrequest(m->c->session, &r->request); + r->request.uname = up->user; + r->request.aname = spec; + r->request.nauth = 0; + r->request.auth = (uchar*)""; mountrpc(m, r); - c->type = devno('M', 0); c->qid = r->reply.qid; c->mchan = m->c; c->mqid = c->qid; - authreply(m->c->session, id, &r->reply); - poperror(); mntfree(r); } -static Chan* -mntclone(Chan *c, Chan *nc) +static Walkqid* +mntwalk(Chan *c, Chan *nc, char **name, int nname) { + int i, alloc; Mnt *m; Mntrpc *r; - int alloc = 0; + Walkqid *wq; +extern int chandebug; +if(chandebug){ + print("mntwalk "); + for(i=0; i MAXWELEM) + error("devmnt: too many name elements"); + alloc = 0; + wq = smalloc(sizeof(Walkqid)+(nname-1)*sizeof(Qid)); + if(waserror()){ + if(alloc && wq->clone!=nil) + cclose(wq->clone); + free(wq); + return nil; + } + alloc = 0; m = mntchk(c); - r = mntralloc(c); - if(nc == 0) { - nc = newchan(); + r = mntralloc(c, m->c->iounit); + if(nc == nil){ + nc = devclone(c); + /* + * Until the other side accepts this fid, we can't mntclose it. + * Therefore set type to 0 for now; rootclose is known to be safe. + */ + nc->type = 0; alloc = 1; } + wq->clone = nc; + if(waserror()) { mntfree(r); - if(alloc) - cclose(nc); nexterror(); + return nil; } - - r->request.type = Tclone; + r->request.type = Twalk; r->request.fid = c->fid; r->request.newfid = nc->fid; - mountrpc(m, r); - - devclone(c, nc); - nc->mqid = c->qid; - incref(m); + r->request.nwname = nname; + memmove(r->request.wname, name, nname*sizeof(char*)); - USED(alloc); - poperror(); - mntfree(r); - return nc; -} - -static int -mntwalk(Chan *c, char *name) -{ - Mnt *m; - Mntrpc *r; + mountrpc(m, r); - m = mntchk(c); - r = mntralloc(c); - if(waserror()) { - mntfree(r); - return 0; + if(r->reply.nwqid > nname) + error("too many QIDs returned by walk"); + if(r->reply.nwqid < nname){ + if(alloc) + cclose(nc); + wq->clone = nil; + if(r->reply.nwqid == 0){ + free(wq); + wq = nil; + goto Return; + } } - r->request.type = Twalk; - r->request.fid = c->fid; - strncpy(r->request.name, name, NAMELEN); - mountrpc(m, r); - c->qid = r->reply.qid; + /* move new fid onto mnt device and update its qid */ + if(wq->clone != nil){ + if(wq->clone != c){ + wq->clone->type = c->type; + incref(m); + } + if(r->reply.nwqid > 0) + wq->clone->qid = r->reply.wqid[r->reply.nwqid-1]; + } + wq->nqid = r->reply.nwqid; + for(i=0; inqid; i++) + wq->qid[i] = r->reply.wqid[i]; + Return: poperror(); mntfree(r); - return 1; + poperror(); + return wq; } -static void -mntstat(Chan *c, char *dp) +static int +mntstat(Chan *c, uchar *dp, int n) { Mnt *m; Mntrpc *r; + if(n < BIT16SZ) + error(Eshortstat); m = mntchk(c); - r = mntralloc(c); + r = mntralloc(c, m->c->iounit); if(waserror()) { mntfree(r); nexterror(); @@ -304,32 +324,49 @@ mntstat(Chan *c, char *dp) r->request.fid = c->fid; mountrpc(m, r); - memmove(dp, r->reply.stat, DIRLEN); - mntdirfix((uchar*)dp, c); + if(r->reply.nstat >= 1<<(8*BIT16SZ)) + error("returned stat buffer count too large"); + + if(r->reply.nstat > n){ + /* doesn't fit; just patch the count and return */ + PBIT16((uchar*)dp, r->reply.nstat); + n = BIT16SZ; + }else{ + n = r->reply.nstat; + memmove(dp, r->reply.stat, n); + validstat(dp, n); + mntdirfix(dp, c); + } poperror(); mntfree(r); + return n; } static Chan* -mntopen(Chan *c, int omode) +mntopencreate(int type, Chan *c, char *name, int omode, ulong perm) { Mnt *m; Mntrpc *r; m = mntchk(c); - r = mntralloc(c); + r = mntralloc(c, m->c->iounit); if(waserror()) { mntfree(r); nexterror(); } - r->request.type = Topen; + r->request.type = type; r->request.fid = c->fid; r->request.mode = omode; + if(type == Tcreate){ + r->request.perm = perm; + r->request.name = name; + } mountrpc(m, r); c->qid = r->reply.qid; c->offset = 0; c->mode = openmode(omode); + c->iounit = r->reply.iounit; c->flag |= COPEN; poperror(); mntfree(r); @@ -340,33 +377,16 @@ mntopen(Chan *c, int omode) return c; } +static Chan* +mntopen(Chan *c, int omode) +{ + return mntopencreate(Topen, c, nil, omode, 0); +} + static void mntcreate(Chan *c, char *name, int omode, ulong perm) { - Mnt *m; - Mntrpc *r; - - m = mntchk(c); - r = mntralloc(c); - if(waserror()) { - mntfree(r); - nexterror(); - } - r->request.type = Tcreate; - r->request.fid = c->fid; - r->request.mode = omode; - r->request.perm = perm; - strncpy(r->request.name, name, NAMELEN); - mountrpc(m, r); - - c->qid = r->reply.qid; - c->flag |= COPEN; - c->mode = openmode(omode); - poperror(); - mntfree(r); - - if(c->flag & CCACHE) - copen(c); + mntopencreate(Tcreate, c, name, omode, perm); } static void @@ -376,7 +396,7 @@ mntclunk(Chan *c, int t) Mntrpc *r; m = mntchk(c); - r = mntralloc(c); + r = mntralloc(c, m->c->iounit); if(waserror()){ mntfree(r); mclose(m, c); @@ -391,7 +411,7 @@ mntclunk(Chan *c, int t) poperror(); } -static void +void mclose(Mnt *m, Chan*) { Mntrpc *q, *r; @@ -408,7 +428,7 @@ mclose(Mnt *m, Chan*) mntpntfree(m); } -static void +void mntpntfree(Mnt *m) { Mnt *f, **l; @@ -440,41 +460,37 @@ mntremove(Chan *c) mntclunk(c, Tremove); } -static void -mntwstat(Chan *c, char *dp) +static int +mntwstat(Chan *c, uchar *dp, int n) { Mnt *m; Mntrpc *r; m = mntchk(c); - r = mntralloc(c); + r = mntralloc(c, m->c->iounit); if(waserror()) { mntfree(r); nexterror(); } r->request.type = Twstat; r->request.fid = c->fid; - memmove(r->request.stat, dp, DIRLEN); + r->request.nstat = n; + r->request.stat = dp; mountrpc(m, r); poperror(); mntfree(r); -} - -long -mntread9p(Chan *c, void *buf, long n, vlong off) -{ - return mnt9prdwr(Tread, c, buf, n, off); + return n; } static long mntread(Chan *c, void *buf, long n, vlong off) { uchar *p, *e; - int nc, cache, isdir; + int nc, cache, isdir, dirlen; isdir = 0; cache = c->flag & CCACHE; - if(c->qid.path & CHDIR) { + if(c->qid.type & QTDIR) { cache = 0; isdir = 1; } @@ -496,63 +512,27 @@ mntread(Chan *c, void *buf, long n, vlong off) n = mntrdwr(Tread, c, buf, n, off); if(isdir) { - for(e = &p[n]; p < e; p += DIRLEN) + for(e = &p[n]; p+BIT16SZ < e; p += dirlen){ + dirlen = BIT16SZ+GBIT16(p); + if(p+dirlen > e) + break; + validstat(p, dirlen); mntdirfix(p, c); + } + if(p != e) + error(Esbadstat); } return n; } -long -mntwrite9p(Chan *c, void *buf, long n, vlong off) -{ - return mnt9prdwr(Twrite, c, buf, n, off); -} - static long mntwrite(Chan *c, void *buf, long n, vlong off) { return mntrdwr(Twrite, c, buf, n, off); } -static long -mnt9prdwr(int type, Chan *c, void *buf, long n, vlong off) -{ - Mnt *m; - ulong nr; - Mntrpc *r; - - if(n > MAXRPC-32) { - if(type == Twrite) - error("write9p too long"); - n = MAXRPC-32; - } - - m = mntchk(c); - r = mntralloc(c); - if(waserror()) { - mntfree(r); - nexterror(); - } - r->request.type = type; - r->request.fid = c->fid; - r->request.offset = off; - r->request.data = buf; - r->request.count = n; - mountrpc(m, r); - nr = r->reply.count; - if(nr > r->request.count) - nr = r->request.count; - - if(type == Tread) - memmove(buf, r->reply.data, nr); - - poperror(); - mntfree(r); - return nr; -} - -static long +long mntrdwr(int type, Chan *c, void *buf, long n, vlong off) { Mnt *m; @@ -565,10 +545,10 @@ mntrdwr(int type, Chan *c, void *buf, long n, vlong off) uba = buf; cnt = 0; cache = c->flag & CCACHE; - if(c->qid.path & CHDIR) + if(c->qid.type & QTDIR) cache = 0; for(;;) { - r = mntralloc(c); + r = mntralloc(c, m->c->iounit); if(waserror()) { mntfree(r); nexterror(); @@ -577,13 +557,12 @@ mntrdwr(int type, Chan *c, void *buf, long n, vlong off) r->request.fid = c->fid; r->request.offset = off; r->request.data = uba; - if(n > m->blocksize){ - if(c->qid.path & CHDIR) - r->request.count = (m->blocksize/DIRLEN)*DIRLEN; - else - r->request.count = m->blocksize; - } else - r->request.count = n; + nr = n; + if(nr > m->c->iounit-IOHDRSZ) + nr = m->c->iounit-IOHDRSZ; + if(c->iounit != 0 && nr > c->iounit) + nr = c->iounit; + r->request.count = nr; mountrpc(m, r); nreq = r->request.count; nr = r->reply.count; @@ -607,7 +586,7 @@ mntrdwr(int type, Chan *c, void *buf, long n, vlong off) return cnt; } -static void +void mountrpc(Mnt *m, Mntrpc *r) { char *sn, *cn; @@ -641,7 +620,7 @@ mountrpc(Mnt *m, Mntrpc *r) } } -static void +void mountio(Mnt *m, Mntrpc *r) { int n; @@ -653,7 +632,7 @@ mountio(Mnt *m, Mntrpc *r) mntflushfree(m, r); nexterror(); } - r = mntflushalloc(r); + r = mntflushalloc(r, m->c->iounit); } lock(m); @@ -663,16 +642,13 @@ mountio(Mnt *m, Mntrpc *r) unlock(m); /* Transmit a file system rpc */ - n = convS2M(&r->request, r->rpc); + if(m->c->iounit == 0) + panic("iounit"); + n = convS2M(&r->request, r->rpc, m->c->iounit); if(n < 0) panic("bad message type in mountio"); - if(devtab[m->c->type]->dc == L'M'){ - if(mnt9prdwr(Twrite, m->c, r->rpc, n, 0) != n) - error(Emountrpc); - }else{ - if(devtab[m->c->type]->write(m->c, r->rpc, n, 0) != n) - error(Emountrpc); - } + if(devtab[m->c->type]->write(m->c, r->rpc, n, 0) != n) + error(Emountrpc); r->stime = fastticks(nil); r->reqlen = n; @@ -692,7 +668,8 @@ mountio(Mnt *m, Mntrpc *r) m->rip = up; unlock(m); while(r->done == 0) { - mntrpcread(m, r); + if(mntrpcread(m, r) < 0) + error(Emountrpc); mountmux(m, r); } mntgate(m); @@ -700,28 +677,62 @@ mountio(Mnt *m, Mntrpc *r) mntflushfree(m, r); } -static void +int +mntreadn(Chan *c, uchar *buf, int n) +{ + int m, dm; + + for(m=0; mtype]->read(c, buf, n-m, 0); + if(dm <= 0) + return 0; + buf += dm; + } + return n; +} + +int mntrpcread(Mnt *m, Mntrpc *r) { - int n; + int n, len; + ulong chunk; - for(;;) { - r->reply.type = 0; - r->reply.tag = 0; - if(devtab[m->c->type]->dc == L'M') - n = mnt9prdwr(Tread, m->c, r->rpc, MAXRPC, 0); - else - n = devtab[m->c->type]->read(m->c, r->rpc, MAXRPC, 0); - if(n == 0) - continue; - - r->replen = n; - if(convM2S(r->rpc, &r->reply, n) != 0) - return; + chunk = m->c->iounit; + if(chunk == 0 || chunk > m->c->iounit) + chunk = m->c->iounit; + r->reply.type = 0; + r->reply.tag = 0; + /* read size, then read exactly the right number of bytes */ + n = mntreadn(m->c, r->rpc, BIT32SZ); + if(n != BIT32SZ){ + if(n > 0) + print("devmnt expected BIT32SZ got %d\n", n); + return -1; + } + len = GBIT32((uchar*)r->rpc); + if(len <= BIT32SZ || len > chunk){ + print("devmnt: len %d max messagesize %ld\n", len, m->c->iounit); + return -1; + } + n += mntreadn(m->c, r->rpc+BIT32SZ, len-BIT32SZ); + if(n != len){ + print("devmnt: length %d expected %d\n", n, len); + return -1; + } + + r->replen = n; + if(convM2S(r->rpc, n, &r->reply) == 0){ + int i; + print("bad conversion of received message; %d bytes iounit %ld\n", n, m->c->iounit); + for(i=0; irpc[i]); + print("\n"); + return -1; } + return 0; } -static void +void mntgate(Mnt *m) { Mntrpc *q; @@ -736,10 +747,10 @@ mntgate(Mnt *m) unlock(m); } -static void +void mountmux(Mnt *m, Mntrpc *r) { - char *dp; + uchar *dp; Mntrpc **l, *q; lock(m); @@ -771,18 +782,19 @@ mountmux(Mnt *m, Mntrpc *r) l = &q->list; } unlock(m); + print("unexpected reply tag %ud; type %d\n", r->reply.tag, r->reply.type); } /* * Create a new flush request and chain the previous * requests from it */ -static Mntrpc* -mntflushalloc(Mntrpc *r) +Mntrpc* +mntflushalloc(Mntrpc *r, ulong iounit) { Mntrpc *fr; - fr = mntralloc(0); + fr = mntralloc(0, iounit); fr->request.type = Tflush; if(r->request.type == Tflush) @@ -801,7 +813,7 @@ mntflushalloc(Mntrpc *r) * and if it hasn't been answered set the reply to to * Rflush. */ -static void +void mntflushfree(Mnt *m, Mntrpc *r) { Mntrpc *fr; @@ -818,8 +830,8 @@ mntflushfree(Mnt *m, Mntrpc *r) } } -static Mntrpc* -mntralloc(Chan *c) +Mntrpc* +mntralloc(Chan *c, ulong iounit) { Mntrpc *new; @@ -835,7 +847,7 @@ mntralloc(Chan *c) * The header is split from the data buffer as * mountmux may swap the buffer with another header. */ - new->rpc = mallocz(MAXRPC, 0); + new->rpc = mallocz(iounit, 0); if(new->rpc == nil){ free(new); unlock(&mntalloc); @@ -855,7 +867,7 @@ mntralloc(Chan *c) return new; } -static void +void mntfree(Mntrpc *r) { lock(&mntalloc); @@ -872,7 +884,7 @@ mntfree(Mntrpc *r) unlock(&mntalloc); } -static void +void mntqrm(Mnt *m, Mntrpc *r) { Mntrpc **l, *f; @@ -891,7 +903,7 @@ mntqrm(Mnt *m, Mntrpc *r) unlock(m); } -static Mnt* +Mnt* mntchk(Chan *c) { Mnt *m; @@ -907,19 +919,24 @@ mntchk(Chan *c) return m; } -static void +/* + * Rewrite channel type and dev for in-flight data to + * reflect local values. These entries are known to be + * the first two in the Dir encoding after the count. + */ +void mntdirfix(uchar *dirbuf, Chan *c) { - int r; + uint r; r = devtab[c->type]->dc; - dirbuf[DIRLEN-4] = r>>0; - dirbuf[DIRLEN-3] = r>>8; - dirbuf[DIRLEN-2] = c->dev; - dirbuf[DIRLEN-1] = c->dev>>8; + dirbuf += BIT16SZ; /* skip count */ + PBIT16(dirbuf, r); + dirbuf += BIT16SZ; + PBIT32(dirbuf, c->dev); } -static int +int rpcattn(void *v) { Mntrpc *r; @@ -935,7 +952,6 @@ Dev mntdevtab = { mntreset, devinit, mntattach, - mntclone, mntwalk, mntstat, mntopen, diff --git a/port/devmntstats.c b/port/devmntstats.c index 120ea4c8157f7ee49d7dc90070bbc0d11818e9ed..26441817099ff2dab05040147d5ef99f4b7885dd 100644 --- a/port/devmntstats.c +++ b/port/devmntstats.c @@ -94,7 +94,6 @@ static int mntstatsgen(Chan *c, Dirtab*, int, int i, Dir *dp) { Qid q; - char name[NAMELEN]; Mntstats *m; if(i == DEVDOTDOT){ @@ -107,8 +106,8 @@ mntstatsgen(Chan *c, Dirtab*, int, int i, Dir *dp) return -1; q = (Qid){Qmntstat+i, 0}; - snprint(name, NAMELEN, "%C%lud.%lux", devtab[m->c.type]->dc, m->c.dev, m->c.qid.path); - devdir(c, q, name, 0, eve, 0666, dp); + snprint(up->genbuf, sizeof up->genbuf, "%C%lud.%lux", devtab[m->c.type]->dc, m->c.dev, m->c.qid.path); + devdir(c, q, up->genbuf, 0, eve, 0666, dp); return 1; } diff --git a/port/devmouse.c b/port/devmouse.c index 63bff0a5b40c58b232b34e0e88a443e2474d6205..128cf5c1be3e79d1398893c4eab0373d62a67930 100644 --- a/port/devmouse.c +++ b/port/devmouse.c @@ -61,6 +61,7 @@ enum{ }; static Dirtab mousedir[]={ + ".", {Qdir, 0, QTDIR}, 0, DMDIR|0555, "cursor", {Qcursor}, 0, 0666, "mouse", {Qmouse}, 0, 0666, "mousein", {Qmousein}, 0, 0220, @@ -102,32 +103,28 @@ mouseattach(char *spec) return devattach('m', spec); } -static Chan* -mouseclone(Chan *c, Chan *nc) +static Walkqid* +mousewalk(Chan *c, Chan *nc, char **name, int nname) { - nc = devclone(c, nc); - if(c->qid.path != CHDIR) + Walkqid *wq; + + wq = devwalk(c, nc, name, nname, mousedir, nelem(mousedir), devgen); + if(wq != nil && wq->clone != c && (wq->clone->qid.type&QTDIR)==0) incref(&mouse); - return nc; + return wq; } static int -mousewalk(Chan *c, char *name) -{ - return devwalk(c, name, mousedir, nelem(mousedir), devgen); -} - -static void -mousestat(Chan *c, char *db) +mousestat(Chan *c, uchar *db, int n) { - devstat(c, db, mousedir, nelem(mousedir), devgen); + return devstat(c, db, n, mousedir, nelem(mousedir), devgen); } static Chan* mouseopen(Chan *c, int omode) { - switch(c->qid.path){ - case CHDIR: + switch((ulong)c->qid.path){ + case Qdir: if(omode != OREAD) error(Eperm); break; @@ -171,7 +168,7 @@ mousecreate(Chan*, char*, int, ulong) static void mouseclose(Chan *c) { - if(c->qid.path!=CHDIR && (c->flag&COPEN)){ + if((c->qid.type&QTDIR)==0 && (c->flag&COPEN)){ lock(&mouse); if(c->qid.path == Qmouse) mouse.open = 0; @@ -202,8 +199,8 @@ mouseread(Chan *c, void *va, long n, vlong off) int b; p = va; - switch(c->qid.path){ - case CHDIR: + switch((ulong)c->qid.path){ + case Qdir: return devdirread(c, va, n, mousedir, nelem(mousedir), devgen); case Qcursor: @@ -311,11 +308,11 @@ mousewrite(Chan *c, void *va, long n, vlong) char *p; Point pt; char buf[64], *field[3]; - int nf, b; + int nf, b, msec; p = va; - switch(c->qid.path){ - case CHDIR: + switch((ulong)c->qid.path){ + case Qdir: error(Eisdir); case Qcursor: @@ -377,7 +374,10 @@ mousewrite(Chan *c, void *va, long n, vlong) if(p == 0) error(Eshort); b = strtol(p, &p, 0); - mousetrack(b, pt.x, pt.y); + msec = strtol(p, &p, 0); + if(msec == 0) + msec = TK2MS(MACHP(0)->ticks); + mousetrack(pt.x, pt.y, b, msec); return n; case Qmouse: @@ -412,7 +412,6 @@ Dev mousedevtab = { mousereset, mouseinit, mouseattach, - mouseclone, mousewalk, mousestat, mouseopen, @@ -443,7 +442,7 @@ static void mouseclock(void) { if(mouse.track){ - mousetrack(mouse.buttons, mouse.dx, mouse.dy); + mousetrack(mouse.dx, mouse.dy, mouse.buttons, TK2MS(MACHP(0)->ticks)); mouse.track = 0; mouse.dx = 0; mouse.dy = 0; @@ -490,7 +489,7 @@ scale(int x) * awaken any waiting procs. */ void -mousetrack(int b, int dx, int dy) +mousetrack(int dx, int dy, int b, int msec) { int x, y, lastb; @@ -517,7 +516,7 @@ mousetrack(int b, int dx, int dy) mouse.buttons = b; mouse.redraw = 1; mouse.counter++; - mouse.msec = TK2MS(MACHP(0)->ticks); + mouse.msec = msec; /* * if the queue fills, we discard the entire queue and don't @@ -563,7 +562,7 @@ m3mouseputc(Queue*, int c) /* an extra byte gets sent for the middle button */ middle = (c&0x20) ? 2 : 0; newbuttons = (mouse.buttons & ~2) | middle; - mousetrack(newbuttons, 0, 0); + mousetrack(0, 0, newbuttons, TK2MS(MACHP(0)->ticks)); return 0; } } @@ -575,7 +574,7 @@ m3mouseputc(Queue*, int c) dx = (x>>8) | msg[1]; x = (msg[0]&0xc)<<12; dy = (x>>8) | msg[2]; - mousetrack(newbuttons, dx, dy); + mousetrack(dx, dy, newbuttons, TK2MS(MACHP(0)->ticks)); } return 0; } @@ -602,7 +601,7 @@ mouseputc(Queue*, int c) newbuttons = b[((msg[0]&7)^7) | (mouseshifted ? 8 : 0)]; dx = msg[1]+msg[3]; dy = -(msg[2]+msg[4]); - mousetrack(newbuttons, dx, dy); + mousetrack(dx, dy, newbuttons, TK2MS(MACHP(0)->ticks)); nb = 0; } return 0; diff --git a/port/devns16552.c b/port/devns16552.c deleted file mode 100644 index 89f484ca80e3826089e0ebb1570afef9b4c55d0a..0000000000000000000000000000000000000000 --- a/port/devns16552.c +++ /dev/null @@ -1,1228 +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 "../port/netif.h" - -/* - * Driver for the ns16552. - */ -enum -{ - /* - * register numbers - */ - Data= 0, /* xmit/rcv buffer */ - Iena= 1, /* interrupt enable */ - Ircv= (1<<0), /* for char rcv'd */ - Ixmt= (1<<1), /* for xmit buffer empty */ - Irstat=(1<<2), /* for change in rcv'er status */ - Imstat=(1<<3), /* for change in modem status */ - Isleep=(1<<4), /* put in sleep mode; 16C650 */ - Ixoff= (1<<5), /* for xoff received; 16C650 */ - Irts= (1<<6), /* for !rts asserted in auto mode; 16C650 */ - Icts= (1<<7), /* for !cts asserted in auto mode; 16C650 */ - Istat= 2, /* interrupt flag (read) */ - Fenabd=(3<<6), /* on if fifo's enabled */ - Irctsd=(1<<4), /* auto rts or cts changed state */ - Fifoctl=2, /* fifo control (write) */ - Fena= (1<<0), /* enable xmit/rcv fifos */ - Ftrig4= (1<<6), /* trigger after 4 input characters */ - Ftrig24= (2<<6), /* trigger after 24 input characters */ - Fclear=(3<<1), /* clear xmit & rcv fifos */ - Format= 3, /* byte format */ - Bits8= (3<<0), /* 8 bits/byte */ - Stop2= (1<<2), /* 2 stop bits */ - Pena= (1<<3), /* generate parity */ - Peven= (1<<4), /* even parity */ - Pforce=(1<<5), /* force parity */ - Break= (1<<6), /* generate a break */ - Dra= (1<<7), /* address the divisor */ - Ers= 0xbf, /* enable enhaced register set on 16C650 */ - Mctl= 4, /* modem control */ - Dtr= (1<<0), /* data terminal ready */ - Rts= (1<<1), /* request to send */ - Ri= (1<<2), /* ring */ - Inton= (1<<3), /* turn on interrupts */ - Loop= (1<<4), /* loop back */ - Intsel=(1<<5), /* NO! open source interrupts; 16C650 */ - Irda= (1<<6), /* infrared interface; 16C650 */ - Cdiv= (1<<7), /* divide clock by four; 16C650 */ - Lstat= 5, /* line status */ - Inready=(1<<0), /* receive buffer full */ - Oerror=(1<<1), /* receiver overrun */ - Perror=(1<<2), /* receiver parity error */ - Ferror=(1<<3), /* rcv framing error */ - Outready=(1<<5), /* output buffer full */ - Mstat= 6, /* modem status */ - Ctsc= (1<<0), /* clear to send changed */ - Dsrc= (1<<1), /* data set ready changed */ - Rire= (1<<2), /* rising edge of ring indicator */ - Dcdc= (1<<3), /* data carrier detect changed */ - Cts= (1<<4), /* complement of clear to send line */ - Dsr= (1<<5), /* complement of data set ready line */ - Ring= (1<<6), /* complement of ring indicator line */ - Dcd= (1<<7), /* complement of data carrier detect line */ - Scratch=7, /* scratchpad */ - Dlsb= 0, /* divisor lsb */ - Dmsb= 1, /* divisor msb */ - Efr= 2, /* enhanced features for 16C650 */ - Eena= (1<<4), /* enable enhanced bits in normal registers */ - Arts= (1<<6), /* auto rts */ - Acts= (1<<7), /* auto cts */ - - CTLS= 023, - CTLQ= 021, - - Stagesize= 1024, - Nuart= 32, /* max per machine */ - - Ns450= 0, - Ns550, - Ns650, -}; - -typedef struct Uart Uart; -struct Uart -{ - QLock; - int opens; - - int enabled; - Uart *elist; /* next enabled interface */ - char name[NAMELEN]; - - uchar sticky[8]; /* sticky write register values */ - uchar osticky[8]; /* kernel saved sticky write register values */ - ulong port; /* io ports */ - ulong freq; /* clock frequency */ - uchar mask; /* bits/char */ - int dev; - int baud; /* baud rate */ - - uchar istat; /* last istat read */ - int frame; /* framing errors */ - int overrun; /* rcvr overruns */ - - /* buffers */ - int (*putc)(Queue*, int); - Queue *iq; - Queue *oq; - - Lock flock; /* fifo */ - uchar fifoon; /* fifo's enabled */ - uchar type; /* chip version */ - - Lock rlock; /* receive */ - uchar istage[Stagesize]; - uchar *ip; - uchar *ie; - - int haveinput; - - Lock tlock; /* transmit */ - uchar ostage[Stagesize]; - uchar *op; - uchar *oe; - - int modem; /* hardware flow control on */ - int xonoff; /* software flow control on */ - int blocked; - int cts, dsr, dcd, dcdts; /* keep track of modem status */ - int ctsbackoff; - int hup_dsr, hup_dcd; /* send hangup upstream? */ - int dohup; - - int kinuse; /* device in use by kernel */ - - Rendez r; -}; - -static Uart *uart[Nuart]; -static int nuart; - -struct Uartalloc { - Lock; - Uart *elist; /* list of enabled interfaces */ -} uartalloc; - -void ns16552intr(int); - -/* - * means the kernel is using this for debugging output - */ -static char Ekinuse[] = "device in use by kernel"; - -/* - * pick up architecture specific routines and definitions - */ -#include "ns16552.h" - -/* - * set the baud rate by calculating and setting the baudrate - * generator constant. This will work with fairly non-standard - * baud rates. - */ -static void -ns16552setbaud(Uart *p, int rate) -{ - ulong brconst; - - if(rate <= 0) - return; - - brconst = (p->freq+8*rate-1)/(16*rate); - - uartwrreg(p, Format, Dra); - outb(p->port + Dmsb, (brconst>>8) & 0xff); - outb(p->port + Dlsb, brconst & 0xff); - uartwrreg(p, Format, 0); - - p->baud = rate; -} - -/* - * decide if we should hangup when dsr or dcd drops. - */ -static void -ns16552dsrhup(Uart *p, int n) -{ - p->hup_dsr = n; -} - -static void -ns16552dcdhup(Uart *p, int n) -{ - p->hup_dcd = n; -} - -static void -ns16552parity(Uart *p, char type) -{ - switch(type){ - case 'e': - p->sticky[Format] |= Pena|Peven; - break; - case 'o': - p->sticky[Format] &= ~Peven; - p->sticky[Format] |= Pena; - break; - default: - p->sticky[Format] &= ~(Pena|Peven); - break; - } - uartwrreg(p, Format, 0); -} - -/* - * set bits/character, default 8 - */ -void -ns16552bits(Uart *p, int bits) -{ - if(bits < 5 || bits > 8) - error(Ebadarg); - - p->sticky[Format] &= ~3; - p->sticky[Format] |= bits-5; - - uartwrreg(p, Format, 0); -} - -/* - * toggle DTR - */ -void -ns16552dtr(Uart *p, int n) -{ - if(n) - p->sticky[Mctl] |= Dtr; - else - p->sticky[Mctl] &= ~Dtr; - - uartwrreg(p, Mctl, 0); -} - -/* - * toggle RTS - */ -void -ns16552rts(Uart *p, int n) -{ - if(n) - p->sticky[Mctl] |= Rts; - else - p->sticky[Mctl] &= ~Rts; - - uartwrreg(p, Mctl, 0); -} - -/* - * save dcd timestamps for gps clock - */ -static void -ns16552dcdts(Uart *p, int n) -{ - p->dcdts = n; -} - -/* - * send break - */ -static void -ns16552break(Uart *p, int ms) -{ - if(ms == 0) - ms = 200; - - uartwrreg(p, Format, Break); - tsleep(&up->sleep, return0, 0, ms); - uartwrreg(p, Format, 0); -} - -/* - * always called under lock(&p->flock) - */ -static void -ns16552fifo(Uart *p, int n) -{ - ulong i; - int x; - - if(p->type < Ns550) - return; - - x = splhi(); - - if(n == 0){ - /* turn off fifo's */ - p->fifoon = 0; - uartwrreg(p, Fifoctl, 0); - splx(x); - return; - } - - /* reset fifos */ - uartwrreg(p, Fifoctl, Fclear); - - /* empty buffer and interrupt conditions */ - for(i = 0; i < 16; i++){ - uartrdreg(p, Istat); - uartrdreg(p, Data); - } - - /* turn on fifo */ - p->fifoon = 1; - if(p->type == Ns650) - uartwrreg(p, Fifoctl, Fena|Ftrig24); - else - uartwrreg(p, Fifoctl, Fena|Ftrig4); - - /* fix from Scott Schwartz */ - p->istat = uartrdreg(p, Istat); - if((p->istat & Fenabd) == 0){ - /* didn't work, must be an earlier chip type */ - p->type = Ns450; - } - splx(x); -} - -/* - * modem flow control on/off (rts/cts) - */ -static void -ns16552mflow(Uart *p, int n) -{ - - ilock(&p->tlock); - if(n){ - if(p->type == Ns650){ - outb(p->port + Format, 0xbf); - outb(p->port + Efr, Eena|Arts|Acts); - uartwrreg(p, Format, 0); - p->cts = 1; - } else { - p->sticky[Iena] |= Imstat; - uartwrreg(p, Iena, 0); - p->modem = 1; - p->cts = uartrdreg(p, Mstat) & Cts; - } - } else { - if(p->type == Ns650){ - outb(p->port + Format, 0xbf); - outb(p->port + Efr, Eena|Arts|Acts); - uartwrreg(p, Format, 0); - } else { - p->sticky[Iena] &= ~Imstat; - uartwrreg(p, Iena, 0); - p->modem = 0; - } - p->cts = 1; - } - iunlock(&p->tlock); - - /* modem needs fifo */ - lock(&p->flock); - ns16552fifo(p, n); - unlock(&p->flock); -} - -/* - * turn on a port's interrupts. set DTR and RTS - */ -static void -ns16552enable(Uart *p) -{ - Uart **l; - - if(p->enabled) - return; - - uartpower(p->dev, 1); - - p->hup_dsr = p->hup_dcd = 0; - p->cts = p->dsr = p->dcd = 0; - - /* - * turn on interrupts - */ - p->sticky[Iena] = Ircv | Ixmt | Irstat; - uartwrreg(p, Iena, 0); - - /* - * turn on DTR and RTS - */ - ns16552dtr(p, 1); - ns16552rts(p, 1); - - /* - * assume we can send - */ - ilock(&p->tlock); - p->cts = 1; - p->blocked = 0; - iunlock(&p->tlock); - - /* - * set baud rate to the last used - */ - ns16552setbaud(p, p->baud); - - lock(&uartalloc); - for(l = &uartalloc.elist; *l; l = &(*l)->elist){ - if(*l == p) - break; - } - if(*l == 0){ - p->elist = uartalloc.elist; - uartalloc.elist = p; - } - p->enabled = 1; - unlock(&uartalloc); -} - -/* - * turn off a port's interrupts. reset DTR and RTS - */ -static void -ns16552disable(Uart *p) -{ - Uart **l; - - /* - * turn off interrupts - */ - p->sticky[Iena] = 0; - uartwrreg(p, Iena, 0); - - /* - * revert to default settings - */ - p->sticky[Format] = Bits8; - uartwrreg(p, Format, 0); - - /* - * turn off DTR, RTS, hardware flow control & fifo's - */ - ns16552dtr(p, 0); - ns16552rts(p, 0); - ns16552mflow(p, 0); - ilock(&p->tlock); - p->xonoff = p->blocked = 0; - iunlock(&p->tlock); - - uartpower(p->dev, 0); - - lock(&uartalloc); - for(l = &uartalloc.elist; *l; l = &(*l)->elist){ - if(*l == p){ - *l = p->elist; - break; - } - } - p->enabled = 0; - unlock(&uartalloc); -} - -/* - * put some bytes into the local queue to avoid calling - * qconsume for every character - */ -static int -stageoutput(Uart *p) -{ - int n; - - n = qconsume(p->oq, p->ostage, Stagesize); - if(n <= 0) - return 0; - p->op = p->ostage; - p->oe = p->ostage + n; - return n; -} - -/* - * (re)start output - */ -static void -ns16552kick0(void *v) -{ - int i; - Uart *p; - - p = v; - if(p->cts == 0 || p->blocked) - return; - - /* - * 128 here is an arbitrary limit to make sure - * we don't stay in this loop too long. If the - * chips output queue is longer than 128, too - * bad -- presotto - */ - for(i = 0; i < 128; i++){ - if(!(uartrdreg(p, Lstat) & Outready)) - break; - if(p->op >= p->oe && stageoutput(p) == 0) - break; - outb(p->port + Data, *(p->op++)); - } -} - -static void -ns16552kick(void *v) -{ - Uart *p; - - p = v; - ilock(&p->tlock); - ns16552kick0(p); - iunlock(&p->tlock); -} - -/* - * restart input if it's off - */ -static void -ns16552flow(void *v) -{ - Uart *p; - - p = v; - if(p->modem){ - ns16552rts(p, 1); - ilock(&p->rlock); - p->haveinput = 1; - iunlock(&p->rlock); - } -} - -/* - * default is 9600 baud, 1 stop bit, 8 bit chars, no interrupts, - * transmit and receive enabled, interrupts disabled. - */ -static void -ns16552setup0(Uart *p) -{ - memset(p->sticky, 0, sizeof(p->sticky)); - /* - * set rate to 9600 baud. - * 8 bits/character. - * 1 stop bit. - * interrupts enabled. - */ - p->sticky[Format] = Bits8; - uartwrreg(p, Format, 0); - p->sticky[Mctl] |= Inton; - uartwrreg(p, Mctl, 0x0); - - ns16552setbaud(p, 9600); - - p->iq = qopen(4*1024, 0, ns16552flow, p); - p->oq = qopen(4*1024, 0, ns16552kick, p); - if(p->iq == nil || p->oq == nil) - panic("ns16552setup0"); - - p->ip = p->istage; - p->ie = &p->istage[Stagesize]; - p->op = p->ostage; - p->oe = p->ostage; -} - -/* - * called by main() to create a new duart - */ -void -ns16552setup(ulong port, ulong freq, char *name, int type) -{ - Uart *p; - - if(nuart >= Nuart) - return; - - p = xalloc(sizeof(Uart)); - uart[nuart] = p; - strcpy(p->name, name); - p->dev = nuart; - nuart++; - p->port = port; - p->freq = freq; - p->type = type; - ns16552setup0(p); -} - -/* - * called by main() to configure a duart port as a console or a mouse - */ -void -ns16552special(int port, int baud, Queue **in, Queue **out, int (*putc)(Queue*, int)) -{ - Uart *p = uart[port]; - - ns16552enable(p); - if(baud) - ns16552setbaud(p, baud); - p->putc = putc; - if(in) - *in = p->iq; - if(out) - *out = p->oq; - p->opens++; -} - -/* - * handle an interrupt to a single uart - */ -void -ns16552intr(int dev) -{ - uchar ch; - int s, l, loops; - Uart *p = uart[dev]; - - for(loops = 0;; loops++){ - p->istat = s = uartrdreg(p, Istat); - if(loops > 10000000){ - print("lstat %ux mstat %ux istat %ux iena %ux ferr %d oerr %d", - uartrdreg(p, Lstat), uartrdreg(p, Mstat), - s, uartrdreg(p, Iena), p->frame, p->overrun); - panic("ns16552intr"); - } - switch(s&0x3f){ - case 6: /* receiver line status */ - l = uartrdreg(p, Lstat); - if(l & Ferror) - p->frame++; - if(l & Oerror) - p->overrun++; - break; - - case 4: /* received data available */ - case 12: - ch = uartrdreg(p, Data) & 0xff; - if(p->xonoff){ - if(ch == CTLS){ - p->blocked = 1; - }else if (ch == CTLQ){ - p->blocked = 0; - p->ctsbackoff = 2; /* clock gets output going again */ - } - } - if(p->putc) - p->putc(p->iq, ch); - else { - ilock(&p->rlock); - if(p->ip < p->ie) - *p->ip++ = ch; - p->haveinput = 1; - iunlock(&p->rlock); - } - break; - - case 2: /* transmitter not full */ - ns16552kick(p); - break; - - case 0: /* modem status */ - ch = uartrdreg(p, Mstat); - if(ch & Ctsc){ - l = p->cts; - p->cts = ch & Cts; - if(l == 0 && p->cts) - p->ctsbackoff = 2; /* clock gets output going again */ - } - if (ch & Dsrc) { - l = ch & Dsr; - if(p->hup_dsr && p->dsr && !l) - p->dohup = 1; /* clock peforms hangup */ - p->dsr = l; - } - if (ch & Dcdc) { - l = ch & Dcd; - if(l == 0 && p->dcd != 0 && p->dcdts && saveintrts != nil) - (*saveintrts)(); - if(p->hup_dcd && p->dcd && !l) - p->dohup = 1; /* clock peforms hangup */ - p->dcd = l; - } - break; - - default: - if(s&1) - return; - print("weird modem interrupt #%2.2ux\n", s); - break; - } - } -} - -/* - * we save up input characters till clock time - * - * There's also a bit of code to get a stalled print going. - * It shouldn't happen, but it does. Obviously I don't - * understand something. Since it was there, I bundled a - * restart after flow control with it to give some hysteresis - * to the hardware flow control. This makes compressing - * modems happier but will probably bother something else. - * -- presotto - */ -void -uartclock(void) -{ - int n; - Uart *p; - - for(p = uartalloc.elist; p; p = p->elist){ - - /* this amortizes cost of qproduce to many chars */ - if(p->haveinput){ - ilock(&p->rlock); - if(p->haveinput){ - n = p->ip - p->istage; - if(n > 0 && p->iq){ - if(n > Stagesize) - panic("uartclock"); - if(qproduce(p->iq, p->istage, n) < 0) - ns16552rts(p, 0); - else - p->ip = p->istage; - } - p->haveinput = 0; - } - iunlock(&p->rlock); - } - if(p->dohup){ - ilock(&p->rlock); - if(p->dohup){ - qhangup(p->iq, 0); - qhangup(p->oq, 0); - } - p->dohup = 0; - iunlock(&p->rlock); - } - - /* this adds hysteresis to hardware/software flow control */ - if(p->ctsbackoff){ - ilock(&p->tlock); - if(p->ctsbackoff){ - if(--(p->ctsbackoff) == 0) - ns16552kick0(p); - } - iunlock(&p->tlock); - } - } -} - -Dirtab *ns16552dir; -int ndir; - -static void -setlength(int i) -{ - Uart *p; - - if(i > 0){ - p = uart[i]; - if(p && p->opens && p->iq) - ns16552dir[3*i].length = qlen(p->iq); - } else for(i = 0; i < nuart; i++){ - p = uart[i]; - if(p && p->opens && p->iq) - ns16552dir[3*i].length = qlen(p->iq); - } -} - -/* - * all uarts must be ns16552setup() by this point or inside of ns16552install() - */ -static void -ns16552reset(void) -{ - int i; - Dirtab *dp; - - ns16552install(); /* architecture specific */ - - ndir = 3*nuart; - ns16552dir = xalloc(ndir * sizeof(Dirtab)); - dp = ns16552dir; - for(i = 0; i < nuart; i++){ - /* 3 directory entries per port */ - strcpy(dp->name, uart[i]->name); - dp->qid.path = NETQID(i, Ndataqid); - dp->perm = 0660; - dp++; - sprint(dp->name, "%sctl", uart[i]->name); - dp->qid.path = NETQID(i, Nctlqid); - dp->perm = 0660; - dp++; - sprint(dp->name, "%sstat", uart[i]->name); - dp->qid.path = NETQID(i, Nstatqid); - dp->perm = 0444; - dp++; - } -} - -static Chan* -ns16552attach(char *spec) -{ - return devattach('t', spec); -} - -static int -ns16552walk(Chan *c, char *name) -{ - return devwalk(c, name, ns16552dir, ndir, devgen); -} - -static void -ns16552stat(Chan *c, char *dp) -{ - if(NETTYPE(c->qid.path) == Ndataqid) - setlength(NETID(c->qid.path)); - devstat(c, dp, ns16552dir, ndir, devgen); -} - -static Chan* -ns16552open(Chan *c, int omode) -{ - Uart *p; - - c = devopen(c, omode, ns16552dir, ndir, devgen); - - switch(NETTYPE(c->qid.path)){ - case Nctlqid: - case Ndataqid: - p = uart[NETID(c->qid.path)]; - if(p->kinuse) - error(Ekinuse); - qlock(p); - if(p->opens++ == 0){ - ns16552enable(p); - qreopen(p->iq); - qreopen(p->oq); - } - qunlock(p); - break; - } - - return c; -} - -static void -ns16552close(Chan *c) -{ - Uart *p; - - if(c->qid.path & CHDIR) - return; - if((c->flag & COPEN) == 0) - return; - switch(NETTYPE(c->qid.path)){ - case Ndataqid: - case Nctlqid: - p = uart[NETID(c->qid.path)]; - if(p->kinuse) - error(Ekinuse); - qlock(p); - if(--(p->opens) == 0){ - ns16552disable(p); - qclose(p->iq); - qclose(p->oq); - p->ip = p->istage; - p->dcd = p->dsr = p->dohup = 0; - } - qunlock(p); - break; - } -} - -static long -uartstatus(Chan*, Uart *p, void *buf, long n, long offset) -{ - uchar mstat, fstat, istat, tstat; - char str[256]; - - str[0] = 0; - tstat = p->sticky[Mctl]; - mstat = uartrdreg(p, Mstat); - istat = p->sticky[Iena]; - fstat = p->sticky[Format]; - snprint(str, sizeof str, - "b%d c%d d%d e%d l%d m%d p%c r%d s%d i%d\n" - "dev(%d) type(%d) framing(%d) overruns(%d)%s%s%s%s\n", - - p->baud, - p->hup_dcd, - (tstat & Dtr) != 0, - p->hup_dsr, - (fstat & Bits8) + 5, - (istat & Imstat) != 0, - (fstat & Pena) ? ((fstat & Peven) ? 'e' : 'o') : 'n', - (tstat & Rts) != 0, - (fstat & Stop2) ? 2 : 1, - p->fifoon, - - p->dev, - p->type, - p->frame, - p->overrun, - (mstat & Cts) ? " cts" : "", - (mstat & Dsr) ? " dsr" : "", - (mstat & Dcd) ? " dcd" : "", - (mstat & Ring) ? " ring" : "" - ); - return readstr(offset, buf, n, str); -} - -static long -ns16552read(Chan *c, void *buf, long n, vlong off) -{ - Uart *p; - ulong offset = off; - - if(c->qid.path & CHDIR){ - setlength(-1); - return devdirread(c, buf, n, ns16552dir, ndir, devgen); - } - - p = uart[NETID(c->qid.path)]; - if(p->kinuse) - error(Ekinuse); - switch(NETTYPE(c->qid.path)){ - case Ndataqid: - return qread(p->iq, buf, n); - case Nctlqid: - return readnum(offset, buf, n, NETID(c->qid.path), NUMSIZE); - case Nstatqid: - return uartstatus(c, p, buf, n, offset); - } - - return 0; -} - -static void -ns16552ctl(Uart *p, char *cmd) -{ - int i, n; - char *f[32]; - int nf; - - /* let output drain for a while */ - for(i = 0; i < 16 && qlen(p->oq); i++) - tsleep(&p->r, (int(*)(void*))qlen, p->oq, 125); - - nf = getfields(cmd, f, nelem(f), 1, " \t\n"); - - for(i = 0; i < nf; i++){ - - if(strncmp(f[i], "break", 5) == 0){ - ns16552break(p, 0); - continue; - } - - n = atoi(f[i]+1); - switch(*f[i]){ - case 'B': - case 'b': - ns16552setbaud(p, n); - break; - case 'C': - case 'c': - ns16552dcdhup(p, n); - break; - case 'D': - case 'd': - ns16552dtr(p, n); - break; - case 'E': - case 'e': - ns16552dsrhup(p, n); - break; - case 'f': - case 'F': - qflush(p->oq); - break; - case 'H': - case 'h': - qhangup(p->iq, 0); - qhangup(p->oq, 0); - break; - case 'i': - case 'I': - lock(&p->flock); - ns16552fifo(p, n); - unlock(&p->flock); - break; - case 'L': - case 'l': - ns16552bits(p, n); - break; - case 'm': - case 'M': - ns16552mflow(p, n); - break; - case 'n': - case 'N': - qnoblock(p->oq, n); - break; - case 'P': - case 'p': - ns16552parity(p, *(cmd+1)); - break; - case 'K': - case 'k': - ns16552break(p, n); - break; - case 'R': - case 'r': - ns16552rts(p, n); - break; - case 'Q': - case 'q': - qsetlimit(p->iq, n); - qsetlimit(p->oq, n); - break; - case 'T': - case 't': - ns16552dcdts(p, n); - break; - case 'W': - case 'w': - /* obsolete */ - break; - case 'X': - case 'x': - ilock(&p->tlock); - p->xonoff = n; - iunlock(&p->tlock); - break; - } - } -} - -static long -ns16552write(Chan *c, void *buf, long n, vlong) -{ - Uart *p; - char cmd[32]; - - if(c->qid.path & CHDIR) - error(Eperm); - - p = uart[NETID(c->qid.path)]; - if(p->kinuse) - error(Ekinuse); - - /* - * The fifo's turn themselves off sometimes. - * It must be something I don't understand. -- presotto - */ - if((p->istat & Fenabd) == 0 && p->fifoon && p->type < Ns550){ - lock(&p->flock); - if((p->istat & Fenabd) == 0 && p->fifoon && p->type < Ns550) - ns16552fifo(p, 1); - unlock(&p->flock); - } - - switch(NETTYPE(c->qid.path)){ - case Ndataqid: - return qwrite(p->oq, buf, n); - case Nctlqid: - if(n >= sizeof(cmd)) - n = sizeof(cmd)-1; - memmove(cmd, buf, n); - cmd[n] = 0; - ns16552ctl(p, cmd); - return n; - } -} - -static void -ns16552wstat(Chan *c, char *dp) -{ - Dir d; - Dirtab *dt; - - if(!iseve()) - error(Eperm); - if(CHDIR & c->qid.path) - error(Eperm); - if(NETTYPE(c->qid.path) == Nstatqid) - error(Eperm); - - dt = &ns16552dir[3 * NETID(c->qid.path)]; - convM2D(dp, &d); - d.mode &= 0666; - dt[0].perm = dt[1].perm = d.mode; -} - -Dev ns16552devtab = { - 't', - "ns16552", - - ns16552reset, - devinit, - ns16552attach, - devclone, - ns16552walk, - ns16552stat, - ns16552open, - devcreate, - ns16552close, - ns16552read, - devbread, - ns16552write, - devbwrite, - devremove, - ns16552wstat, -}; - -/* - * Polling I/O routines for kernel debugging helps. - */ -static void -ns16552setuppoll(Uart *p, int rate) -{ - ulong brconst; - - /* - * 8 bits/character, 1 stop bit; - * set rate to rate baud; - * turn on Rts and Dtr. - */ - memmove(p->osticky, p->sticky, sizeof p->osticky); - - p->sticky[Format] = Bits8; - uartwrreg(p, Format, 0); - - brconst = (UartFREQ+8*rate-1)/(16*rate); - uartwrreg(p, Format, Dra); - outb(p->port+Dmsb, (brconst>>8) & 0xff); - outb(p->port+Dlsb, brconst & 0xff); - uartwrreg(p, Format, 0); - - p->sticky[Mctl] = Rts|Dtr; - uartwrreg(p, Mctl, 0); - - p->kinuse = 1; -} - -/* - * Restore serial state from before kernel took over. - */ -static void -ns16552restore(Uart *p) -{ - ulong brconst; - - memmove(p->sticky, p->osticky, sizeof p->sticky); - uartwrreg(p, Format, 0); - - brconst = (UartFREQ+8*p->baud-1)/(16*p->baud); - uartwrreg(p, Format, Dra); - outb(p->port+Dmsb, (brconst>>8) & 0xff); - outb(p->port+Dlsb, brconst & 0xff); - uartwrreg(p, Format, 0); - - uartwrreg(p, Mctl, 0); - p->kinuse = 0; -} - -/* BUG should be configurable */ -enum { - WHICH = 0, - RATE = 9600, -}; - -int -serialgetc(void) -{ - Uart *p; - int c; - - if((p=uart[WHICH]) == nil) - return -1; - if(!p->kinuse) - ns16552setuppoll(p, RATE); - - while((uartrdreg(p, Lstat)&Inready) == 0) - ; - c = inb(p->port+Data) & 0xFF; - return c; - // there should be a restore here but i think it will slow things down too much. -} - -static void -serialputc(Uart *p, int c) -{ - while((uartrdreg(p, Lstat)&Outready) == 0) - ; - outb(p->port+Data, c); - while((uartrdreg(p, Lstat)&Outready) == 0) - ; -} - -void -serialputs(char *s, int n) -{ - Uart *p; - - if((p=uart[WHICH]) == nil) - return; - if(!p->kinuse) - ns16552setuppoll(p, RATE); - - while(n-- > 0){ - serialputc(p, *s); - if(*s == '\n') - serialputc(p, '\r'); - s++; - } - ns16552restore(p); -} diff --git a/port/devpipe.c b/port/devpipe.c index 991479e2e24e6135db3bee94c64dd5190e22d81b..d5cd43d6169b8fd8101393403bb302622d81eb14 100644 --- a/port/devpipe.c +++ b/port/devpipe.c @@ -33,10 +33,11 @@ enum Dirtab pipedir[] = { - "data", {Qdata0}, 0, 0600, - "data1", {Qdata1}, 0, 0600, + ".", {Qdir,0,QTDIR}, 0, DMDIR|0500, + "data", {Qdata0}, 0, 0600, + "data1", {Qdata1}, 0, 0600, }; -#define NPIPEDIR 2 +#define NPIPEDIR 3 static void pipeinit(void) @@ -80,53 +81,29 @@ pipeattach(char *spec) p->path = ++pipealloc.path; unlock(&pipealloc); - c->qid = (Qid){CHDIR|NETQID(2*p->path, Qdir), 0}; + mkqid(&c->qid, NETQID(2*p->path, Qdir), 0, QTDIR); c->aux = p; c->dev = 0; return c; } -static Chan* -pipeclone(Chan *c, Chan *nc) -{ - Pipe *p; - - p = c->aux; - nc = devclone(c, nc); - qlock(p); - p->ref++; - if(c->flag & COPEN){ - switch(NETTYPE(c->qid.path)){ - case Qdata0: - p->qref[0]++; - break; - case Qdata1: - p->qref[1]++; - break; - } - } - qunlock(p); - return nc; -} - static int -pipegen(Chan *c, Dirtab *tab, int ntab, int i, Dir *dp) +pipegen(Chan *c, char*, Dirtab *tab, int ntab, int i, Dir *dp) { - int id; int len; Pipe *p; + Qid q; if(i == DEVDOTDOT){ - devdir(c, c->qid, "#|", 0, eve, CHDIR|0555, dp); + devdir(c, c->qid, "#|", 0, eve, DMDIR|0555, dp); return 1; } - - id = NETID(c->qid.path); if(tab==0 || i>=ntab) return -1; + tab += i; p = c->aux; - switch(tab->qid.path){ + switch((ulong)tab->qid.path){ case Qdata0: len = qlen(p->q[0]); break; @@ -137,19 +114,41 @@ pipegen(Chan *c, Dirtab *tab, int ntab, int i, Dir *dp) len = tab->length; break; } - devdir(c, (Qid){NETQID(id, tab->qid.path),0}, tab->name, len, eve, tab->perm, dp); + mkqid(&q, NETQID(NETID(c->qid.path), tab->qid.path), 0, QTFILE); + devdir(c, q, tab->name, len, eve, tab->perm, dp); return 1; } -static int -pipewalk(Chan *c, char *name) +static Walkqid* +pipewalk(Chan *c, Chan *nc, char **name, int nname) { - return devwalk(c, name, pipedir, NPIPEDIR, pipegen); + Walkqid *wq; + Pipe *p; + + wq = devwalk(c, nc, name, nname, pipedir, NPIPEDIR, pipegen); + if(wq != nil && wq->clone != nil && wq->clone != c){ + p = c->aux; + qlock(p); + p->ref++; + if(c->flag & COPEN){ + print("channel open in pipewalk\n"); + switch(NETTYPE(c->qid.path)){ + case Qdata0: + p->qref[0]++; + break; + case Qdata1: + p->qref[1]++; + break; + } + } + qunlock(p); + } + return wq; } -static void -pipestat(Chan *c, char *db) +static int +pipestat(Chan *c, uchar *db, int n) { Pipe *p; Dir dir; @@ -158,7 +157,7 @@ pipestat(Chan *c, char *db) switch(NETTYPE(c->qid.path)){ case Qdir: - devdir(c, c->qid, ".", 2*DIRLEN, eve, CHDIR|0555, &dir); + devdir(c, c->qid, ".", 0, eve, DMDIR|0555, &dir); break; case Qdata0: devdir(c, c->qid, "data", qlen(p->q[0]), eve, 0660, &dir); @@ -169,7 +168,10 @@ pipestat(Chan *c, char *db) default: panic("pipestat"); } - convD2M(&dir, db); + n = convD2M(&dir, db, n); + if(n < BIT16SZ) + error(Eshortstat); + return n; } /* @@ -180,7 +182,7 @@ pipeopen(Chan *c, int omode) { Pipe *p; - if(c->qid.path & CHDIR){ + if(c->qid.type & QTDIR){ if(omode != OREAD) error(Ebadarg); c->mode = omode; @@ -372,7 +374,6 @@ Dev pipedevtab = { devreset, pipeinit, pipeattach, - pipeclone, pipewalk, pipestat, pipeopen, diff --git a/port/devproc.c b/port/devproc.c index 57f95dd1a62814150e27154777898b2e44dbd4d1..56ecfd26ca8e051cc8cef00ac686d2e6818a773d 100644 --- a/port/devproc.c +++ b/port/devproc.c @@ -8,9 +8,9 @@ enum { - Qctl, Qdir, Qargs, + Qctl, Qfd, Qfpregs, Qkregs, @@ -28,14 +28,19 @@ enum Qprofile, }; -#define STATSIZE (2*NAMELEN+12+9*12) +#define STATSIZE (2*KNAMELEN+12+9*12) +/* + * Status, fd, and ns are left fully readable (0444) because of their use in debugging, + * particularly on shared servers. + * Arguably, ns and fd shouldn't be readable; if you'd prefer, change them to 0000 + */ Dirtab procdir[] = { "args", {Qargs}, 0, 0440, "ctl", {Qctl}, 0, 0000, - "fd", {Qfd}, 0, 0000, + "fd", {Qfd}, 0, 0444, "fpregs", {Qfpregs}, sizeof(FPsave), 0000, - "kregs", {Qkregs}, sizeof(Ureg), 0440, + "kregs", {Qkregs}, sizeof(Ureg), 0400, "mem", {Qmem}, 0, 0000, "note", {Qnote}, 0, 0000, "noteid", {Qnoteid}, 0, 0664, @@ -51,7 +56,7 @@ Dirtab procdir[] = }; /* Segment type from portdat.h */ -static char *sname[]={ "Text", "Data", "Bss", "Stack", "Shared", "Phys" }; +static char *sname[]={ "Text", "Data", "Bss", "Stack", "Shared", "Phys", }; /* * Qids are, in path: @@ -63,8 +68,8 @@ static char *sname[]={ "Text", "Data", "Bss", "Stack", "Shared", "Phys" }; */ #define QSHIFT 5 /* location in qid of proc slot # */ -#define QID(q) (((q).path&0x0000001F)>>0) -#define SLOT(q) ((((q).path&0x07FFFFFE0)>>QSHIFT)-1) +#define QID(q) ((((ulong)(q).path)&0x0000001F)>>0) +#define SLOT(q) (((((ulong)(q).path)&0x07FFFFFE0)>>QSHIFT)-1) #define PID(q) ((q).vers) #define NOTEID(q) ((q).vers) @@ -76,30 +81,38 @@ int procstopped(void*); void mntscan(Mntwalk*, Proc*); static int -procgen(Chan *c, Dirtab *tab, int, int s, Dir *dp) +procgen(Chan *c, char *name, Dirtab *tab, int, int s, Dir *dp) { Qid qid; Proc *p; Segment *q; - char buf[NAMELEN]; ulong pid, path, perm, len; if(s == DEVDOTDOT){ - c->qid.path = CHDIR; - devdir(c, c->qid, "#p", 0, eve, 0555, dp); + mkqid(&qid, Qdir, 0, QTDIR); + devdir(c, qid, "#p", 0, eve, 0555, dp); return 1; } - if(c->qid.path == CHDIR){ - if(s >= conf.nproc) - return -1; + if(c->qid.path == Qdir){ + if(name != nil){ + /* ignore s and use name to find pid */ + pid = strtol(name, &name, 0); + if(pid==0 || name[0]!='\0') + return -1; + s = procindex(pid); + if(s < 0) + return -1; + }else + if(s >= conf.nproc) + return -1; p = proctab(s); pid = p->pid; if(pid == 0) return 0; - sprint(buf, "%lud", pid); - qid = (Qid){CHDIR|((s+1)<user, CHDIR|0555, dp); + sprint(up->genbuf, "%lud", pid); + mkqid(&qid, (s+1)<genbuf, 0, p->user, DMDIR|0555, dp); return 1; } if(s >= nelem(procdir)) @@ -108,7 +121,7 @@ procgen(Chan *c, Dirtab *tab, int, int s, Dir *dp) panic("procgen"); tab = &procdir[s]; - path = c->qid.path&~(CHDIR|((1<qid.path&~(((1<qid)); perm = tab->perm; @@ -131,7 +144,7 @@ procgen(Chan *c, Dirtab *tab, int, int s, Dir *dp) break; } - qid = (Qid){path|tab->qid.path, c->qid.vers}; + mkqid(&qid, path|tab->qid.path, c->qid.vers, QTFILE); devdir(c, qid, tab->name, len, p->user, perm, dp); return 1; } @@ -149,30 +162,16 @@ procattach(char *spec) return devattach('p', spec); } -static int -procwalk(Chan *c, char *name) +static Walkqid* +procwalk(Chan *c, Chan *nc, char **name, int nname) { - int s; - int pid; - - if(c->qid.path == CHDIR && name[0] != '.'){ - /* this is a hack to speed walks through a large directory */ - pid = strtol(name, &name, 0); - if(pid <= 0 || *name != 0) - return 0; - s = procindex(pid); - if(s < 0) - return 0; - c->qid = (Qid){CHDIR|((s+1)<qid.path & CHDIR) + if(c->qid.type & QTDIR) return devopen(c, omode, 0, 0, procgen); p = proctab(SLOT(c->qid)); @@ -285,13 +284,13 @@ procopen(Chan *c, int omode) return tc; } -static void -procwstat(Chan *c, char *db) +static int +procwstat(Chan *c, uchar *db, int n) { Proc *p; - Dir d; + Dir *d; - if(c->qid.path&CHDIR) + if(c->qid.type&QTDIR) error(Eperm); p = proctab(SLOT(c->qid)); @@ -308,21 +307,24 @@ procwstat(Chan *c, char *db) if(strcmp(up->user, p->user) != 0 && strcmp(up->user, eve) != 0) error(Eperm); - convM2D(db, &d); - if(strcmp(d.uid, p->user) != 0){ - if(strcmp(up->user, eve) != 0) - error(Eperm); - else { - strncpy(p->user, d.uid, sizeof(p->user)); - p->user[sizeof(p->user)-1] = 0; + d = smalloc(sizeof(Dir)+n); + n = convM2D(db, n, &d[0], (char*)&d[1]); + if(n > 0){ + if(strcmp(d->uid, "") != 0 && strcmp(d->uid, p->user) != 0){ + if(strcmp(up->user, eve) != 0) + error(Eperm); + else + kstrdup(&p->user, d->uid); } + p->procmode = d->mode&0777; } - p->procmode = d.mode&0777; poperror(); qunlock(&p->debug); + return n; } + static long procoffset(long offset, char *va, int *np) { @@ -343,7 +345,8 @@ procfds(Proc *p, char *va, int count, long offset) { Fgrp *f; Chan *c; - int n, i; + int n, i, w, ww; + char buf[32]; qlock(&p->debug); f = p->fgrp; @@ -361,15 +364,25 @@ procfds(Proc *p, char *va, int count, long offset) n = readstr(0, va, count, p->dot->name->s); n += snprint(va+n, count-n, "\n"); offset = procoffset(offset, va, &n); + /* compute width of qid.path */ + w = 0; for(i = 0; i <= f->maxfd; i++) { c = f->fd[i]; if(c == nil) continue; - n += snprint(va+n, count-n, "%3d %.2s %C %4ld %.8lux.%.8lud %8lld ", + ww = sprint(buf, "%lud", c->qid.vers); + if(ww > w) + w = ww; + } + for(i = 0; i <= f->maxfd; i++) { + c = f->fd[i]; + if(c == nil) + continue; + n += snprint(va+n, count-n, "%3d %.2s %C %4ld (%.16llux %*lud %.2ux) %8lld ", i, &"r w rw"[(c->mode&3)<<1], devtab[c->type]->dc, c->dev, - c->qid.path, c->qid.vers, + c->qid.path, w, c->qid.vers, c->qid.type, c->offset); n += readstr(0, va+n, count-n, c->name->s); n += snprint(va+n, count-n, "\n"); @@ -433,6 +446,7 @@ procargs(Proc *p, char *buf, int nbuf) static long procread(Chan *c, void *va, long n, vlong off) { + int m; long l; Proc *p; Waitq *wq; @@ -445,7 +459,7 @@ procread(Chan *c, void *va, long n, vlong off) char statbuf[NSEG*32], *srv, flag[10]; ulong offset = off; - if(c->qid.path & CHDIR) + if(c->qid.type & QTDIR) return devdirread(c, a, n, 0, 0, procgen); p = proctab(SLOT(c->qid)); @@ -454,12 +468,12 @@ procread(Chan *c, void *va, long n, vlong off) switch(QID(c->qid)){ case Qargs: - j = procargs(p, statbuf, sizeof statbuf); + j = procargs(p, p->genbuf, sizeof p->genbuf); if(offset >= j) return 0; if(offset+n > j) n = j-offset; - memmove(a, &statbuf[offset], n); + memmove(a, &p->genbuf[offset], n); return n; case Qmem: @@ -491,6 +505,7 @@ procread(Chan *c, void *va, long n, vlong off) return n; } error(Ebadarg); + case Qprofile: s = p->seg[TSEG]; if(s == 0 || s->profile == 0) @@ -512,15 +527,19 @@ procread(Chan *c, void *va, long n, vlong off) } if(p->pid != PID(c->qid)) error(Eprocdied); - if(n < ERRLEN) + if(n < 1) /* must accept at least the '\0' */ error(Etoosmall); if(p->nnote == 0) n = 0; else { - memmove(va, p->note[0].msg, ERRLEN); + m = strlen(p->note[0].msg) + 1; + if(m > n) + m = n; + memmove(va, p->note[0].msg, m); + ((char*)va)[m-1] = '\0'; p->nnote--; memmove(p->note, p->note+1, p->nnote*sizeof(Note)); - n = ERRLEN; + n = m; } if(p->nnote == 0) p->notepending = 0; @@ -571,10 +590,10 @@ procread(Chan *c, void *va, long n, vlong off) if(sps == 0) sps = statename[p->state]; memset(statbuf, ' ', sizeof statbuf); - memmove(statbuf+0*NAMELEN, p->text, strlen(p->text)); - memmove(statbuf+1*NAMELEN, p->user, strlen(p->user)); - memmove(statbuf+2*NAMELEN, sps, strlen(sps)); - j = 2*NAMELEN + 12; + memmove(statbuf+0*KNAMELEN, p->text, strlen(p->text)); + memmove(statbuf+1*KNAMELEN, p->user, strlen(p->user)); + memmove(statbuf+2*KNAMELEN, sps, strlen(sps)); + j = 2*KNAMELEN + 12; for(i = 0; i < 6; i++) { l = p->time[i]; @@ -675,12 +694,12 @@ procread(Chan *c, void *va, long n, vlong off) poperror(); return i; } - int2flag(mw->cm->flag, flag); + int2flag(mw->cm->mflag, flag); if(strcmp(mw->cm->to->name->s, "#M") == 0){ srv = srvname(mw->cm->to->mchan); - i = snprint(a, n, "mount %s %s %s %.*s\n", flag, + i = snprint(a, n, "mount %s %s %s %s\n", flag, srv==nil? mw->cm->to->mchan->name->s : srv, - mw->mh->from->name->s, NAMELEN, mw->cm->spec); + mw->mh->from->name->s, mw->cm->spec? mw->cm->spec : ""); free(srv); }else i = snprint(a, n, "bind %s %s %s\n", flag, @@ -741,11 +760,11 @@ procwrite(Chan *c, void *va, long n, vlong off) { int id; Proc *p, *t, *et; - char *a, buf[ERRLEN]; + char *a, buf[ERRMAX]; ulong offset = off; a = va; - if(c->qid.path & CHDIR) + if(c->qid.type & QTDIR) error(Eisdir); p = proctab(SLOT(c->qid)); @@ -799,7 +818,7 @@ procwrite(Chan *c, void *va, long n, vlong off) case Qnote: if(p->kp) error(Eperm); - if(n >= ERRLEN-1) + if(n >= ERRMAX-1) error(Etoobig); memmove(buf, va, n); buf[n] = 0; @@ -840,7 +859,6 @@ Dev procdevtab = { devreset, procinit, procattach, - devclone, procwalk, procstat, procopen, @@ -960,11 +978,9 @@ procctlreq(Proc *p, char *va, int n) { Segment *s; int i, npc; - char buf[NAMELEN]; + char buf[64]; - if(n > NAMELEN) - n = NAMELEN; - strncpy(buf, va, n); + kstrcpy(buf, va, sizeof buf); if(strncmp(buf, "stop", 4) == 0) procstopwait(p, Proc_stopme); diff --git a/port/devroot.c b/port/devroot.c index 352575f6606c9d502c8cf76263dc7d671d216572..d8ee66dae0166df242c5e85b0f6d2f922112ff4d 100644 --- a/port/devroot.c +++ b/port/devroot.c @@ -14,26 +14,12 @@ enum{ extern ulong bootlen; extern uchar bootcode[]; -Dirtab rootdir[Nfiles]; - -static uchar *rootdata[Nfiles]; -static int nroot = 0; - -typedef struct Recover Recover; -struct Recover -{ - int len; - char *req; - Recover *next; +Dirtab rootdir[Nfiles] = { + ".", {Qdir, 0, QTDIR}, 0, DMDIR|0555, }; -struct -{ - Lock; - QLock; - Rendez; - Recover *q; -}reclist; +static uchar *rootdata[Nfiles]; +static int nroot = 1; /* * add a root file @@ -50,9 +36,11 @@ addroot(char *name, uchar *contents, ulong len, int perm) strcpy(d->name, name); d->length = len; d->perm = perm; + d->qid.type = 0; + d->qid.vers = 0; d->qid.path = nroot+1; - if(perm & CHDIR) - d->qid.path |= CHDIR; + if(perm & DMDIR) + d->qid.type |= QTDIR; nroot++; } @@ -71,7 +59,7 @@ addrootfile(char *name, uchar *contents, ulong len) static void addrootdir(char *name) { - addroot(name, nil, 0, CHDIR|0555); + addroot(name, nil, 0, DMDIR|0555); } static void @@ -80,6 +68,7 @@ rootreset(void) addrootdir("bin"); addrootdir("dev"); addrootdir("env"); + addrootdir("fd"); addrootdir("net"); addrootdir("net.alt"); addrootdir("proc"); @@ -95,28 +84,22 @@ rootattach(char *spec) return devattach('/', spec); } -static int -rootwalk(Chan *c, char *name) +static Walkqid* +rootwalk(Chan *c, Chan *nc, char **name, int nname) { - if(strcmp(name, "..") == 0) { - c->qid.path = Qdir|CHDIR; - return 1; - } - if((c->qid.path & ~CHDIR) != Qdir) - return 0; - return devwalk(c, name, rootdir, nroot, devgen); + return devwalk(c, nc, name, nname, rootdir, nroot, devgen); } -static void -rootstat(Chan *c, char *dp) +static int +rootstat(Chan *c, uchar *dp, int n) { - devstat(c, dp, rootdir, nroot, devgen); + return devstat(c, dp, n, rootdir, nroot, devgen); } static Chan* rootopen(Chan *c, int omode) { - switch(c->qid.path & ~CHDIR) { + switch((ulong)c->qid.path) { default: break; } @@ -132,12 +115,6 @@ rootclose(Chan*) { } -static int -rdrdy(void*) -{ - return reclist.q != 0; -} - static long rootread(Chan *c, void *buf, long n, vlong off) { @@ -146,7 +123,7 @@ rootread(Chan *c, void *buf, long n, vlong off) uchar *data; ulong offset = off; - t = c->qid.path & ~CHDIR; + t = c->qid.path; switch(t){ case Qdir: return devdirread(c, buf, n, rootdir, nroot, devgen); @@ -165,7 +142,7 @@ rootread(Chan *c, void *buf, long n, vlong off) static long rootwrite(Chan *c, void*, long, vlong) { - switch(c->qid.path & ~CHDIR){ + switch((ulong)c->qid.path){ default: error(Egreg); } @@ -179,7 +156,6 @@ Dev rootdevtab = { rootreset, devinit, rootattach, - devclone, rootwalk, rootstat, rootopen, diff --git a/port/devsd.c b/port/devsd.c index e9f631b0303e470b84671cfc7a321aa4718547f6..2b1bd0b5114a59dc52e20e30d8f84d02d390bf2a 100644 --- a/port/devsd.c +++ b/port/devsd.c @@ -34,14 +34,13 @@ enum { Qunitdir, /* directory per unit */ Qunitbase, Qctl = Qunitbase, - Qlog, Qraw, Qpart, }; -#define TYPE(q) ((q).path & 0x0F) -#define PART(q) (((q).path>>4) & 0x0F) -#define UNIT(q) (((q).path>>8) & 0xFF) +#define TYPE(q) (((ulong)(q).path) & 0x0F) +#define PART(q) ((((ulong)(q).path)>>4) & 0x0F) +#define UNIT(q) ((((ulong)(q).path)>>8) & 0xFF) #define QID(u, p, t) (((u)<<8)|((p)<<4)|(t)) static void @@ -63,7 +62,7 @@ sdaddpart(SDunit* unit, char* name, ulong start, ulong end) partno = i; break; } - if(strncmp(name, pp->name, NAMELEN) == 0){ + if(strcmp(name, pp->name) == 0){ if(pp->start == start && pp->end == end) return; error(Ebadctl); @@ -99,8 +98,8 @@ sdaddpart(SDunit* unit, char* name, ulong start, ulong end) pp = &unit->part[partno]; pp->start = start; pp->end = end; - strncpy(pp->name, name, NAMELEN); - strncpy(pp->user, eve, NAMELEN); + kstrdup(&pp->name, name); + kstrdup(&pp->user, eve); pp->perm = 0640; pp->valid = 1; } @@ -117,12 +116,14 @@ sddelpart(SDunit* unit, char* name) */ pp = unit->part; for(i = 0; i < unit->npart; i++){ - if(strncmp(name, pp->name, NAMELEN) == 0) + if(strcmp(name, pp->name) == 0) break; pp++; } if(i >= unit->npart) error(Ebadctl); + if(strcmp(up->user, pp->user) && !iseve()) + error(Eperm); pp->valid = 0; pp->vers++; } @@ -193,6 +194,7 @@ sdgetunit(SDev* sdev, int subno) { int index; SDunit *unit; + char buf[32]; /* * Associate a unit with a given device and sub-unit @@ -222,16 +224,13 @@ sdgetunit(SDev* sdev, int subno) sdev->ifc->enable(sdev); sdev->enabled = 1; - snprint(unit->name, NAMELEN, "%s%d", sdev->name, subno); - strncpy(unit->user, eve, NAMELEN); + snprint(buf, sizeof(buf), "%s%d", sdev->name, subno); + kstrdup(&unit->name, buf); + kstrdup(&unit->user, eve); unit->perm = 0555; unit->subno = subno; unit->dev = sdev; - unit->log.logmask = ~0; - unit->log.nlog = 16*1024; - unit->log.minread = 4*1024; - /* * No need to lock anything here as this is only * called before the unit is made available in the @@ -337,39 +336,30 @@ sd2gen(Chan* c, int i, Dir* dp) unit = sdunit[UNIT(c->qid)]; switch(i){ - case Qlog: - q = (Qid){QID(UNIT(c->qid), PART(c->qid), Qlog), unit->vers}; - perm = &unit->rawperm; - if(perm->user[0] == '\0'){ - strncpy(perm->user, eve, NAMELEN); - perm->perm = 0666; - } - devdir(c, q, "log", 0, perm->user, perm->perm, dp); - return 1; case Qctl: - q = (Qid){QID(UNIT(c->qid), PART(c->qid), Qctl), unit->vers}; + mkqid(&q, QID(UNIT(c->qid), PART(c->qid), Qctl), unit->vers, QTFILE); perm = &unit->ctlperm; - if(perm->user[0] == '\0'){ - strncpy(perm->user, eve, NAMELEN); + if(emptystr(perm->user)){ + kstrdup(&perm->user, eve); perm->perm = 0640; } devdir(c, q, "ctl", 0, perm->user, perm->perm, dp); return 1; case Qraw: - q = (Qid){QID(UNIT(c->qid), PART(c->qid), Qraw), unit->vers}; + mkqid(&q, QID(UNIT(c->qid), PART(c->qid), Qraw), unit->vers, QTFILE); perm = &unit->rawperm; - if(perm->user[0] == '\0'){ - strncpy(perm->user, eve, NAMELEN); - perm->perm = CHEXCL|0600; + if(emptystr(perm->user)){ + kstrdup(&perm->user, eve); + perm->perm = DMEXCL|0600; } devdir(c, q, "raw", 0, perm->user, perm->perm, dp); return 1; case Qpart: pp = &unit->part[PART(c->qid)]; l = (pp->end - pp->start) * (vlong)unit->secsize; - q = (Qid){QID(UNIT(c->qid), PART(c->qid), Qpart), unit->vers+pp->vers}; - if(pp->user[0] == '\0') - strncpy(pp->user, eve, NAMELEN); + mkqid(&q, QID(UNIT(c->qid), PART(c->qid), Qpart), unit->vers+pp->vers, QTFILE); + if(emptystr(pp->user)) + kstrdup(&pp->user, eve); devdir(c, q, pp->name, l, pp->user, pp->perm, dp); return 1; } @@ -387,21 +377,20 @@ sd1gen(Chan*, int i, Dir*) } static int -sdgen(Chan* c, Dirtab*, int, int s, Dir* dp) +sdgen(Chan* c, char*, Dirtab*, int, int s, Dir* dp) { Qid q; vlong l; int i, r; SDpart *pp; SDunit *unit; - char name[NAMELEN]; switch(TYPE(c->qid)){ case Qtopdir: if(s == DEVDOTDOT){ - q = (Qid){QID(0, 0, Qtopdir)|CHDIR, 0}; - snprint(name, NAMELEN, "#%C", sddevtab.dc); - devdir(c, q, name, 0, eve, 0555, dp); + mkqid(&q, QID(s, 0, Qtopdir), 0, QTDIR); + sprint(up->genbuf, "#%C", sddevtab.dc); + devdir(c, q, up->genbuf, 0, eve, 0555, dp); return 1; } if(s < sdnunit){ @@ -409,9 +398,9 @@ sdgen(Chan* c, Dirtab*, int, int s, Dir* dp) if((unit = sdindex2unit(s)) == nil) return 0; } - q = (Qid){QID(s, 0, Qunitdir)|CHDIR, 0}; - if(unit->user[0] == '\0') - strncpy(unit->user, eve, NAMELEN); + mkqid(&q, QID(s, 0, Qunitdir), 0, QTDIR); + if(emptystr(unit->user)) + kstrdup(&unit->user, eve); devdir(c, q, unit->name, 0, unit->user, unit->perm, dp); return 1; } @@ -419,9 +408,9 @@ sdgen(Chan* c, Dirtab*, int, int s, Dir* dp) return sd1gen(c, s+Qtopbase, dp); case Qunitdir: if(s == DEVDOTDOT){ - q = (Qid){QID(0, 0, Qtopdir)|CHDIR, 0}; - snprint(name, NAMELEN, "#%C", sddevtab.dc); - devdir(c, q, name, 0, eve, 0555, dp); + mkqid(&q, QID(s, 0, Qtopdir), 0, QTDIR); + sprint(up->genbuf, "#%C", sddevtab.dc); + devdir(c, q, up->genbuf, 0, eve, 0555, dp); return 1; } unit = sdunit[UNIT(c->qid)]; @@ -455,16 +444,15 @@ sdgen(Chan* c, Dirtab*, int, int s, Dir* dp) return 0; } l = (pp->end - pp->start) * (vlong)unit->secsize; - q = (Qid){QID(UNIT(c->qid), i, Qpart), unit->vers+pp->vers}; - if(pp->user[0] == '\0') - strncpy(pp->user, eve, NAMELEN); + mkqid(&q, QID(UNIT(c->qid), i, Qpart), unit->vers+pp->vers, QTFILE); + if(emptystr(pp->user)) + kstrdup(&pp->user, eve); devdir(c, q, pp->name, l, pp->user, pp->perm, dp); qunlock(&unit->ctl); return 1; case Qraw: case Qctl: case Qpart: - case Qlog: unit = sdunit[UNIT(c->qid)]; qlock(&unit->ctl); r = sd2gen(c, TYPE(c->qid), dp); @@ -487,7 +475,7 @@ sdattach(char* spec) if(sdnunit == 0 || *spec == '\0'){ c = devattach(sddevtab.dc, spec); - c->qid = (Qid){QID(0, 0, Qtopdir)|CHDIR, 0}; + mkqid(&c->qid, QID(0, 0, Qtopdir), 0, QTDIR); return c; } @@ -505,27 +493,21 @@ sdattach(char* spec) error(Enonexist); c = devattach(sddevtab.dc, spec); - c->qid = (Qid){QID(sdev->index+subno, 0, Qunitdir)|CHDIR, 0}; + mkqid(&c->qid, QID(sdev->index+subno, 0, Qunitdir), 0, QTDIR); c->dev = sdev->index+subno; return c; } -static Chan* -sdclone(Chan* c, Chan* nc) +static Walkqid* +sdwalk(Chan* c, Chan* nc, char** name, int nname) { - return devclone(c, nc); + return devwalk(c, nc, name, nname, nil, 0, sdgen); } static int -sdwalk(Chan* c, char* name) -{ - return devwalk(c, name, nil, 0, sdgen); -} - -static void -sdstat(Chan* c, char* db) +sdstat(Chan* c, uchar* db, int n) { - devstat(c, db, nil, 0, sdgen); + return devstat(c, db, n, nil, 0, sdgen); } static Chan* @@ -538,10 +520,6 @@ sdopen(Chan* c, int omode) switch(TYPE(c->qid)){ default: break; - case Qlog: - unit = sdunit[UNIT(c->qid)]; - logopen(&unit->log); - break; case Qctl: unit = sdunit[UNIT(c->qid)]; c->qid.vers = unit->vers; @@ -577,7 +555,7 @@ sdclose(Chan* c) { SDunit *unit; - if(c->qid.path & CHDIR) + if(c->qid.type & QTDIR) return; if(!(c->flag & COPEN)) return; @@ -585,10 +563,6 @@ sdclose(Chan* c) switch(TYPE(c->qid)){ default: break; - case Qlog: - unit = sdunit[UNIT(c->qid)]; - logclose(&unit->log); - break; case Qraw: unit = sdunit[UNIT(c->qid)]; unlock(&unit->rawinuse); @@ -655,26 +629,6 @@ sdbio(Chan* c, int write, char* a, long len, vlong off) poperror(); } - if(unit->log.opens) { - int i; - uchar lbuf[1+4+8], *p; - ulong x[3]; - - p = lbuf; - *p++ = write ? 'w' : 'r'; - x[0] = off>>32; - x[1] = off; - x[2] = len; - for(i=0; i<3; i++) { - *p++ = x[i]>>24; - *p++ = x[i]>>16; - *p++ = x[i]>>8; - *p++ = x[i]; - } - - logn(&unit->log, 1, lbuf, 1+4+8); - } - b = sdmalloc(nb*unit->secsize); if(b == nil) error(Enomem); @@ -782,9 +736,6 @@ sdread(Chan *c, void *a, long n, vlong off) case Qtopdir: case Qunitdir: return devdirread(c, a, n, 0, 0, sdgen); - case Qlog: - unit = sdunit[UNIT(c->qid)]; - return logread(&unit->log, a, 0, n); case Qctl: unit = sdunit[UNIT(c->qid)]; p = malloc(READSTR); @@ -809,9 +760,8 @@ sdread(Chan *c, void *a, long n, vlong off) for(i = 0; i < unit->npart; i++){ if(pp->valid) l += snprint(p+l, READSTR-l, - "part %.*s %lud %lud\n", - NAMELEN, pp->name, - pp->start, pp->end); + "part %s %lud %lud\n", + pp->name, pp->start, pp->end); pp++; } } @@ -859,10 +809,6 @@ sdwrite(Chan *c, void *a, long n, vlong off) switch(TYPE(c->qid)){ default: error(Eperm); - - case Qlog: - error(Ebadctl); - case Qctl: cb = parsecmd(a, n); unit = sdunit[UNIT(c->qid)]; @@ -940,8 +886,7 @@ sdwrite(Chan *c, void *a, long n, vlong off) } qunlock(&unit->raw); poperror(); - return n; - + break; case Qpart: return sdbio(c, 1, a, n, off); } @@ -949,15 +894,15 @@ sdwrite(Chan *c, void *a, long n, vlong off) return n; } -static void -sdwstat(Chan* c, char* dp) +static int +sdwstat(Chan* c, uchar* dp, int n) { - Dir d; + Dir d[2]; SDpart *pp; SDperm *perm; SDunit *unit; - if(c->qid.path & CHDIR) + if(c->qid.type & QTDIR) error(Eperm); unit = sdunit[UNIT(c->qid)]; @@ -984,14 +929,17 @@ sdwstat(Chan* c, char* dp) break; } - if(strncmp(up->user, perm->user, NAMELEN) && !iseve()) + if(strcmp(up->user, perm->user) && !iseve()) error(Eperm); - convM2D(dp, &d); - strncpy(perm->user, d.uid, NAMELEN); - perm->perm = (perm->perm & ~0777) | (d.mode & 0777); + n = convM2D(dp, n, &d[0], (char*)&d[1]); + if(n == 0) + error(Eshortstat); + kstrdup(&perm->user, d[0].uid); + perm->perm = (perm->perm & ~0777) | (d[0].mode & 0777); qunlock(&unit->ctl); poperror(); + return n; } Dev sddevtab = { @@ -1001,7 +949,6 @@ Dev sddevtab = { sdreset, devinit, sdattach, - sdclone, sdwalk, sdstat, sdopen, diff --git a/port/devsrv.c b/port/devsrv.c index 5daf4190e2df00d9ac4b062025f30ec0471128ad..8a25a738556e36218d731958dd9358622987fa47 100644 --- a/port/devsrv.c +++ b/port/devsrv.c @@ -9,8 +9,8 @@ typedef struct Srv Srv; struct Srv { - char name[NAMELEN]; - char owner[NAMELEN]; + char *name; + char *owner; ulong perm; Chan *chan; Srv *link; @@ -22,9 +22,10 @@ static Srv *srv; static int qidpath; static int -srvgen(Chan *c, Dirtab*, int, int s, Dir *dp) +srvgen(Chan *c, char*, Dirtab*, int, int s, Dir *dp) { Srv *sp; + Qid q; if(s == DEVDOTDOT){ devdir(c, c->qid, "#s", 0, eve, 0555, dp); @@ -39,7 +40,11 @@ srvgen(Chan *c, Dirtab*, int, int s, Dir *dp) qunlock(&srvlk); return -1; } - devdir(c, (Qid){sp->path, 0}, sp->name, 0, sp->owner, sp->perm, dp); + + mkqid(&q, sp->path, 0, QTFILE); + /* make sure name string continues to exist after we release lock */ + kstrcpy(up->genbuf, sp->name, sizeof up->genbuf); + devdir(c, q, up->genbuf, 0, sp->owner, sp->perm, dp); qunlock(&srvlk); return 1; } @@ -56,16 +61,10 @@ srvattach(char *spec) return devattach('s', spec); } -static int -srvwalk(Chan *c, char *name) +static Walkqid* +srvwalk(Chan *c, Chan *nc, char **name, int nname) { - return devwalk(c, name, 0, 0, srvgen); -} - -static void -srvstat(Chan *c, char *db) -{ - devstat(c, db, 0, 0, srvgen); + return devwalk(c, nc, name, nname, 0, 0, srvgen); } static Srv* @@ -78,6 +77,12 @@ srvlookup(char *name, ulong qidpath) return nil; } +static int +srvstat(Chan *c, uchar *db, int n) +{ + return devstat(c, db, n, 0, 0, srvgen); +} + char* srvname(Chan *c) { @@ -98,7 +103,7 @@ srvopen(Chan *c, int omode) { Srv *sp; - if(c->qid.path == CHDIR){ + if(c->qid.type == QTDIR){ if(omode & ORCLOSE) error(Eperm); if(omode != OREAD) @@ -148,6 +153,7 @@ srvcreate(Chan *c, char *name, int omode, ulong perm) qlock(&srvlk); if(waserror()){ + free(sp); qunlock(&srvlk); nexterror(); } @@ -156,13 +162,15 @@ srvcreate(Chan *c, char *name, int omode, ulong perm) sp->path = qidpath++; sp->link = srv; + c->qid.type = QTFILE; c->qid.path = sp->path; srv = sp; qunlock(&srvlk); poperror(); - strncpy(sp->name, name, NAMELEN); - strncpy(sp->owner, up->user, NAMELEN); + sp->name = smalloc(strlen(name)+1); + strcpy(sp->name, name); + kstrdup(&sp->owner, up->user); sp->perm = perm&0777; c->flag |= COPEN; @@ -174,7 +182,7 @@ srvremove(Chan *c) { Srv *sp, **l; - if(c->qid.path == CHDIR) + if(c->qid.type == QTDIR) error(Eperm); qlock(&srvlk); @@ -201,16 +209,20 @@ srvremove(Chan *c) if(sp->chan) cclose(sp->chan); + if(sp->name){ + free(sp->name); + sp->name = nil; + } free(sp); } -static void -srvwstat(Chan *c, char *dp) +static int +srvwstat(Chan *c, uchar *dp, int n) { Dir d; Srv *sp; - if(c->qid.path & CHDIR) + if(c->qid.type & QTDIR) error(Eperm); qlock(&srvlk); @@ -226,12 +238,13 @@ srvwstat(Chan *c, char *dp) if(strcmp(sp->owner, up->user) && !iseve()) error(Eperm); - convM2D(dp, &d); - d.mode &= 0777; - sp->perm = d.mode; + n = convM2D(dp, n, &d, nil); + if(n > 0) + sp->perm = d.mode & 0777; qunlock(&srvlk); poperror(); + return n; } static void @@ -301,7 +314,6 @@ Dev srvdevtab = { devreset, srvinit, srvattach, - devclone, srvwalk, srvstat, srvopen, diff --git a/port/devssl.c b/port/devssl.c index 75184abaabcdd250e1185d10e5f4ddd2db3feba5..b4b03692a9d9831dc9f73b2f2c25febf3a0dcbcb 100644 --- a/port/devssl.c +++ b/port/devssl.c @@ -66,14 +66,15 @@ struct Dstate OneWay out; /* protections */ - char user[NAMELEN]; + char *user; int perm; }; Lock dslock; int dshiwat; int maxdstate = 128; -Dstate** dstate; +char **dsname; +Dstate **dstate; char *encalgs; char *hashalgs; @@ -123,42 +124,54 @@ char *sslnames[] = { }; static int -sslgen(Chan *c, Dirtab *d, int nd, int s, Dir *dp) +sslgen(Chan *c, char*, Dirtab *d, int nd, int s, Dir *dp) { Qid q; Dstate *ds; char name[16], *p, *nm; + int ft; USED(nd); USED(d); + + q.type = QTFILE; q.vers = 0; - switch(TYPE(c->qid)) { + + ft = TYPE(c->qid); + switch(ft) { case Qtopdir: if(s == DEVDOTDOT){ - q.path = QID(0, Qtopdir)|CHDIR; - devdir(c, q, "#D", 0, eve, CHDIR|0555, dp); + q.path = QID(0, Qtopdir); + q.type = QTDIR; + devdir(c, q, "#D", 0, eve, 0555, dp); return 1; } if(s > 0) return -1; - q.path = QID(0, Qprotodir)|CHDIR; - devdir(c, q, "ssl", 0, eve, CHDIR|0555, dp); + q.path = QID(0, Qprotodir); + q.type = QTDIR; + devdir(c, q, "ssl", 0, eve, 0555, dp); return 1; case Qprotodir: if(s == DEVDOTDOT){ - q.path = QID(0, Qtopdir)|CHDIR; - devdir(c, q, ".", 0, eve, CHDIR|0555, dp); + q.path = QID(0, Qtopdir); + q.type = QTDIR; + devdir(c, q, ".", 0, eve, 0555, dp); return 1; } if(s < dshiwat) { - sprint(name, "%d", s); - q.path = QID(s, Qconvdir)|CHDIR; + q.path = QID(s, Qconvdir); + q.type = QTDIR; ds = dstate[s]; if(ds != 0) nm = ds->user; else nm = eve; - devdir(c, q, name, 0, nm, CHDIR|0555, dp); + if(dsname[s] == nil){ + sprint(name, "%d", s); + kstrdup(&dsname[s], name); + } + devdir(c, q, dsname[s], 0, nm, 0555, dp); return 1; } if(s > dshiwat) @@ -168,8 +181,9 @@ sslgen(Chan *c, Dirtab *d, int nd, int s, Dir *dp) return 1; case Qconvdir: if(s == DEVDOTDOT){ - q.path = QID(0, Qprotodir)|CHDIR; - devdir(c, q, "ssl", 0, eve, CHDIR|0555, dp); + q.path = QID(0, Qprotodir); + q.type = QTDIR; + devdir(c, q, "ssl", 0, eve, 0555, dp); return 1; } ds = dstate[CONV(c->qid)]; @@ -212,11 +226,7 @@ sslgen(Chan *c, Dirtab *d, int nd, int s, Dir *dp) return 1; default: ds = dstate[CONV(c->qid)]; - if(ds != nil) - nm = ds->user; - else - nm = eve; - devdir(c, c->qid, sslnames[TYPE(c->qid)], 0, nm, 0660, dp); + devdir(c, c->qid, sslnames[TYPE(c->qid)], 0, ds->user, 0660, dp); return 1; } return -1; @@ -228,21 +238,22 @@ sslattach(char *spec) Chan *c; c = devattach('D', spec); - c->qid.path = QID(0, Qtopdir)|CHDIR; + c->qid.path = QID(0, Qtopdir); c->qid.vers = 0; + c->qid.type = QTDIR; return c; } -static int -sslwalk(Chan *c, char *name) +static Walkqid* +sslwalk(Chan *c, Chan *nc, char **name, int nname) { - return devwalk(c, name, 0, 0, sslgen); + return devwalk(c, nc, name, nname, nil, 0, sslgen); } -static void -sslstat(Chan *c, char *db) +static int +sslstat(Chan *c, uchar *db, int n) { - devstat(c, db, 0, 0, sslgen); + return devstat(c, db, n, nil, 0, sslgen); } static Chan* @@ -250,6 +261,7 @@ sslopen(Chan *c, int omode) { Dstate *s, **pp; int perm; + int ft; perm = 0; omode &= 3; @@ -265,7 +277,8 @@ sslopen(Chan *c, int omode) break; } - switch(TYPE(c->qid)) { + ft = TYPE(c->qid); + switch(ft) { default: panic("sslopen"); case Qtopdir: @@ -315,13 +328,12 @@ sslopen(Chan *c, int omode) return c; } -static void -sslwstat(Chan *c, char *dp) +static int +sslwstat(Chan *c, uchar *db, int n) { - Dir d; + Dir *dir; Dstate *s; - - convM2D(dp, &d); + int m; s = dstate[CONV(c->qid)]; if(s == 0) @@ -329,16 +341,24 @@ sslwstat(Chan *c, char *dp) if(strcmp(s->user, up->user) != 0) error(Eperm); - memmove(s->user, d.uid, NAMELEN); - s->perm = d.mode; + dir = smalloc(sizeof(Dir)+n); + m = convM2D(db, n, &dir[0], (char*)&dir[1]); + if(m > 0){ + kstrdup(&s->user, dir->uid); + s->perm = dir->mode; + } + free(dir); + return m; } static void sslclose(Chan *c) { Dstate *s; + int ft; - switch(TYPE(c->qid)) { + ft = TYPE(c->qid); + switch(ft) { case Qctl: case Qdata: case Qsecretin: @@ -358,6 +378,8 @@ sslclose(Chan *c) dstate[CONV(c->qid)] = 0; unlock(&dslock); + if(s->user != nil) + free(s->user); sslhangup(s); if(s->c) cclose(s->c); @@ -506,11 +528,11 @@ qremove(Block **l, int n, int discard) } /* - * We can't let Eintrs lose data, since doing so will get - * us out of sync with the sender and break the reliablity - * of the channel. Eintr only happens during the reads in - * consume. Therefore we put back any bytes consumed before - * the last call to ensure. + * We can't let Eintr's lose data since the program + * doing the read may be able to handle it. The only + * places Eintr is possible is during the read's in consume. + * Therefore, we make sure we can always put back the bytes + * consumed before the last ensure. */ static Block* sslbread(Chan *c, long n, ulong) @@ -529,10 +551,8 @@ sslbread(Chan *c, long n, ulong) nconsumed = 0; if(waserror()){ - if(strcmp(up->error, Eintr) == 0 && !waserror()){ + if(strcmp(up->error, Eintr) != 0) regurgitate(s.s, consumed, nconsumed); - poperror(); - } qunlock(&s.s->in.q); nexterror(); } @@ -627,23 +647,28 @@ sslread(Chan *c, void *a, long n, vlong off) int i; char buf[128]; ulong offset = off; + int ft; - if(c->qid.path & CHDIR) + if(c->qid.type & QTDIR) return devdirread(c, a, n, 0, 0, sslgen); - switch(TYPE(c->qid)) { + ft = TYPE(c->qid); + switch(ft) { default: error(Ebadusefd); case Qctl: - sprint(buf, "%lud", CONV(c->qid)); + ft = CONV(c->qid); + sprint(buf, "%d", ft); return readstr(offset, a, n, buf); case Qdata: b.b = sslbread(c, n, offset); break; case Qencalgs: return readstr(offset, a, n, encalgs); + break; case Qhashalgs: return readstr(offset, a, n, hashalgs); + break; } if(waserror()){ @@ -777,7 +802,9 @@ sslbwrite(Chan *c, Block *b, ulong offset) s.s->out.mid++; + m = BLEN(nb); devtab[s.s->c->type]->bwrite(s.s->c, nb, s.s->c->offset); + s.s->c->offset += m; } qunlock(&s.s->out.q); poperror(); @@ -1149,6 +1176,9 @@ sslinit(void) if((dstate = smalloc(sizeof(Dstate*) * maxdstate)) == 0) panic("sslinit"); + if((dsname = smalloc(sizeof(char*) * maxdstate)) == 0) + panic("sslinit"); + n = 1; for(e = encrypttab; e->name != nil; e++) n += strlen(e->name) + 1; @@ -1185,7 +1215,6 @@ Dev ssldevtab = { devreset, sslinit, sslattach, - devclone, sslwalk, sslstat, sslopen, @@ -1394,6 +1423,7 @@ static Dstate* dsclone(Chan *ch) { Dstate **pp, **ep, **np; + char **names; int newmax; if(waserror()) { @@ -1417,13 +1447,20 @@ dsclone(Chan *ch) newmax = 2 * maxdstate; if(newmax > Maxdstate) newmax = Maxdstate; + np = smalloc(sizeof(Dstate*) * newmax); if(np == 0) error(Enomem); memmove(np, dstate, sizeof(Dstate*) * maxdstate); dstate = np; pp = &dstate[maxdstate]; - memset(pp, 0, sizeof(Dstate*)*(newmax - maxdstate)); + + names = smalloc(sizeof(char*) * newmax); + if(names == 0) + error(Enomem); + memmove(names, dsname, sizeof(char*) * maxdstate); + dsname = names; + maxdstate = newmax; dsnew(ch, pp); } @@ -1446,7 +1483,7 @@ dsnew(Chan *ch, Dstate **pp) memset(s, 0, sizeof(*s)); s->state = Sincomplete; s->ref = 1; - strncpy(s->user, up->user, sizeof(s->user)); + kstrdup(&s->user, up->user); s->perm = 0660; t = TYPE(ch->qid); if(t == Qclonus) diff --git a/port/devuart.c b/port/devuart.c new file mode 100644 index 0000000000000000000000000000000000000000..ead2231fd118ff07e85d698096098a176e52b516 --- /dev/null +++ b/port/devuart.c @@ -0,0 +1,632 @@ +#include "u.h" +#include "../port/lib.h" +#include "mem.h" +#include "dat.h" +#include "fns.h" +#include "io.h" +#include "../port/error.h" + +#include "../port/netif.h" + +enum +{ + /* soft flow control chars */ + CTLS= 023, + CTLQ= 021, +}; + +extern Dev uartdevtab; +extern PhysUart* physuart[]; + +static Uart* uartlist; +static Uart** uart; +static int uartnuart; +static Dirtab *uartdir; +static int uartndir; + +struct Uartalloc { + Lock; + Uart *elist; /* list of enabled interfaces */ +} uartalloc; + +static void uartclock(void); +static void uartflow(void*); + +/* + * enable/disable uart and add/remove to list of enabled uarts + */ +static Uart* +uartenable(Uart *p) +{ + Uart **l; + + if(p->iq == nil){ + if((p->iq = qopen(4*1024, 0, uartflow, p)) == nil) + return nil; + } + else + qreopen(p->iq); + if(p->oq == nil){ + if((p->oq = qopen(4*1024, 0, uartkick, p)) == nil){ + qfree(p->iq); + p->iq = nil; + return nil; + } + } + else + qreopen(p->oq); + + p->ir = p->istage; + p->iw = p->istage; + p->ie = &p->istage[Stagesize]; + p->op = p->ostage; + p->oe = p->ostage; + + p->hup_dsr = p->hup_dcd = 0; + p->dsr = p->dcd = 0; + + /* assume we can send */ + p->cts = 1; + p->ctsbackoff = 0; + + if(p->bits == 0) + uartctl(p, "l8"); + if(p->stop == 0) + uartctl(p, "s1"); + if(p->parity == 0) + uartctl(p, "pn"); + if(p->baud == 0) + uartctl(p, "b9600"); + (*p->phys->enable)(p, 1); + + lock(&uartalloc); + for(l = &uartalloc.elist; *l; l = &(*l)->elist){ + if(*l == p) + break; + } + if(*l == 0){ + p->elist = uartalloc.elist; + uartalloc.elist = p; + } + p->enabled = 1; + unlock(&uartalloc); + + return p; +} + +static void +uartdisable(Uart *p) +{ + Uart **l; + + (*p->phys->disable)(p); + + lock(&uartalloc); + for(l = &uartalloc.elist; *l; l = &(*l)->elist){ + if(*l == p){ + *l = p->elist; + break; + } + } + p->enabled = 0; + unlock(&uartalloc); +} + +static void +setlength(int i) +{ + Uart *p; + + if(i > 0){ + p = uart[i]; + if(p && p->opens && p->iq) + uartdir[1+3*i].length = qlen(p->iq); + } else for(i = 0; i < uartnuart; i++){ + p = uart[i]; + if(p && p->opens && p->iq) + uartdir[1+3*i].length = qlen(p->iq); + } +} + +/* + * set up the '#t' directory + */ +static void +uartreset(void) +{ + int i; + Dirtab *dp; + Uart *p, *tail; + + tail = nil; + for(i = 0; physuart[i] != nil; i++){ + if(physuart[i]->pnp == nil) + continue; + if((p = physuart[i]->pnp()) == nil) + continue; + if(uartlist != nil) + tail->next = p; + else + uartlist = p; + for(tail = p; tail->next != nil; tail = tail->next) + uartnuart++; + uartnuart++; + } + + if(uartnuart) + uart = xalloc(uartnuart*sizeof(Uart)); + + uartndir = 1 + 3*uartnuart; + uartdir = xalloc(uartndir * sizeof(Dirtab)); + dp = uartdir; + strcpy(dp->name, "."); + mkqid(&dp->qid, 0, 0, QTDIR); + dp->length = 0; + dp->perm = DMDIR|0555; + dp++; + + p = uartlist; + for(i = 0; i < uartnuart; i++){ + /* 3 directory entries per port */ + sprint(dp->name, "eia%d", i); + dp->qid.path = NETQID(i, Ndataqid); + dp->perm = 0660; + dp++; + sprint(dp->name, "eia%dctl", i); + dp->qid.path = NETQID(i, Nctlqid); + dp->perm = 0660; + dp++; + sprint(dp->name, "eia%dstatus", i); + dp->qid.path = NETQID(i, Nstatqid); + dp->perm = 0444; + dp++; + + uart[i] = p; + p->dev = i; + if(p->console && uartenable(p) != nil){ + kbdq = p->iq; + serialoq = p->oq; + p->putc = kbdcr2nl; + p->opens++; + } + p = p->next; + } + + if(uartnuart) + addclock0link(uartclock); +} + + +static Chan* +uartattach(char *spec) +{ + return devattach('t', spec); +} + +static Walkqid* +uartwalk(Chan *c, Chan *nc, char **name, int nname) +{ + return devwalk(c, nc, name, nname, uartdir, uartndir, devgen); +} + +static int +uartstat(Chan *c, uchar *dp, int n) +{ + if(NETTYPE(c->qid.path) == Ndataqid) + setlength(NETID(c->qid.path)); + return devstat(c, dp, n, uartdir, uartndir, devgen); +} + +static Chan* +uartopen(Chan *c, int omode) +{ + Uart *p; + + c = devopen(c, omode, uartdir, uartndir, devgen); + + switch(NETTYPE(c->qid.path)){ + case Nctlqid: + case Ndataqid: + p = uart[NETID(c->qid.path)]; + qlock(p); + if(p->opens++ == 0 && uartenable(p) == nil){ + qunlock(p); + c->flag &= ~COPEN; + error(Enodev); + } + qunlock(p); + break; + } + + return c; +} + +static int +uartdrained(void* arg) +{ + Uart *p; + + p = arg; + return qlen(p->oq) == 0 && p->op == p->oe; +} + +static void +uartclose(Chan *c) +{ + Uart *p; + + if(c->qid.type & QTDIR) + return; + if((c->flag & COPEN) == 0) + return; + switch(NETTYPE(c->qid.path)){ + case Ndataqid: + case Nctlqid: + p = uart[NETID(c->qid.path)]; + qlock(p); + if(--(p->opens) == 0){ + qclose(p->iq); + p->ir = p->iw = p->istage; + + /* + */ + qhangup(p->oq, nil); + if(!waserror()){ + sleep(&p->r, uartdrained, p); + poperror(); + } + qclose(p->oq); + uartdisable(p); + p->dcd = p->dsr = p->dohup = 0; + } + qunlock(p); + break; + } +} + +static long +uartread(Chan *c, void *buf, long n, vlong off) +{ + Uart *p; + ulong offset = off; + + if(c->qid.type & QTDIR){ + setlength(-1); + return devdirread(c, buf, n, uartdir, uartndir, devgen); + } + + p = uart[NETID(c->qid.path)]; + switch(NETTYPE(c->qid.path)){ + case Ndataqid: + return qread(p->iq, buf, n); + case Nctlqid: + return readnum(offset, buf, n, NETID(c->qid.path), NUMSIZE); + case Nstatqid: + return (*p->phys->status)(p, buf, n, offset); + } + + return 0; +} + +int +uartctl(Uart *p, char *cmd) +{ + char *f[16]; + int i, n, nf; + + nf = getfields(cmd, f, nelem(f), 1, " \t\n"); + for(i = 0; i < nf; i++){ + if(strncmp(f[i], "break", 5) == 0){ + (*p->phys->dobreak)(p, 0); + continue; + } + + n = atoi(f[i]+1); + switch(*f[i]){ + case 'B': + case 'b': + if((*p->phys->baud)(p, n) < 0) + return -1; + break; + case 'C': + case 'c': + p->hup_dcd = n; + break; + case 'D': + case 'd': + (*p->phys->dtr)(p, n); + break; + case 'E': + case 'e': + p->hup_dsr = n; + break; + case 'f': + case 'F': + if(p->oq != nil) + qflush(p->oq); + break; + case 'H': + case 'h': + if(p->iq != nil) + qhangup(p->iq, 0); + if(p->oq != nil) + qhangup(p->oq, 0); + break; + case 'i': + case 'I': + (*p->phys->fifo)(p, n); + break; + case 'K': + case 'k': + (*p->phys->dobreak)(p, n); + break; + case 'L': + case 'l': + if((*p->phys->bits)(p, n) < 0) + return -1; + break; + case 'm': + case 'M': + (*p->phys->modemctl)(p, n); + break; + case 'n': + case 'N': + if(p->oq != nil) + qnoblock(p->oq, n); + break; + case 'P': + case 'p': + if((*p->phys->parity)(p, *(f[i]+1)) < 0) + return -1; + break; + case 'Q': + case 'q': + if(p->iq != nil) + qsetlimit(p->iq, n); + if(p->oq != nil) + qsetlimit(p->oq, n); + break; + case 'R': + case 'r': + (*p->phys->rts)(p, n); + break; + case 'S': + case 's': + if((*p->phys->stop)(p, n) < 0) + return -1; + break; + case 'T': + case 't': + p->dcdts = n; + break; + case 'W': + case 'w': + /* obsolete */ + break; + case 'X': + case 'x': + if(p->enabled){ + ilock(&p->tlock); + p->xonoff = n; + iunlock(&p->tlock); + } + break; + } + } + return 0; +} + +static long +uartwrite(Chan *c, void *buf, long n, vlong) +{ + Uart *p; + char *cmd; + + if(c->qid.type & QTDIR) + error(Eperm); + + p = uart[NETID(c->qid.path)]; + + switch(NETTYPE(c->qid.path)){ + case Ndataqid: + qlock(p); + if(waserror()){ + qunlock(p); + nexterror(); + } + + n = qwrite(p->oq, buf, n); + + qunlock(p); + poperror(); + break; + case Nctlqid: + cmd = malloc(n+1); + memmove(cmd, buf, n); + cmd[n] = 0; + qlock(p); + if(waserror()){ + qunlock(p); + free(cmd); + nexterror(); + } + + /* let output drain */ + sleep(&p->r, uartdrained, p); + if(uartctl(p, cmd) < 0) + error(Ebadarg); + + qunlock(p); + poperror(); + free(cmd); + break; + } + + return n; +} + +static int +uartwstat(Chan *c, uchar *dp, int n) +{ + Dir d; + Dirtab *dt; + + if(!iseve()) + error(Eperm); + if(QTDIR & c->qid.type) + error(Eperm); + if(NETTYPE(c->qid.path) == Nstatqid) + error(Eperm); + + dt = &uartdir[1 + 3 * NETID(c->qid.path)]; + n = convM2D(dp, n, &d, nil); + if(n == 0) + error(Eshortstat); + dt[0].perm = dt[1].perm = d.mode; + return n; +} + +Dev uartdevtab = { + 't', + "uart", + + uartreset, + devinit, + uartattach, + uartwalk, + uartstat, + uartopen, + devcreate, + uartclose, + uartread, + devbread, + uartwrite, + devbwrite, + devremove, + uartwstat, +}; + +/* + * restart input if it's off + */ +static void +uartflow(void *v) +{ + Uart *p; + + p = v; + if(p->modem) + (*p->phys->rts)(p, 1); +} + +/* + * put some bytes into the local queue to avoid calling + * qconsume for every character + */ +int +uartstageoutput(Uart *p) +{ + int n; + + n = qconsume(p->oq, p->ostage, Stagesize); + if(n <= 0) + return 0; + p->op = p->ostage; + p->oe = p->ostage + n; + return n; +} + +/* + * restart output + */ +void +uartkick(void *v) +{ + Uart *p = v; + + if(p->blocked) + return; + + ilock(&p->tlock); + (*p->phys->kick)(p); + iunlock(&p->tlock); + + if(qisclosed(p->oq) && uartdrained(p)) + wakeup(&p->r); +} + +/* + * receive a character at interrupt time + */ +void +uartrecv(Uart *p, char ch) +{ + uchar *next; + + /* software flow control */ + if(p->xonoff){ + if(ch == CTLS){ + p->blocked = 1; + }else if (ch == CTLQ){ + p->blocked = 0; + p->ctsbackoff = 2; /* clock gets output going again */ + } + } + + /* receive the character */ + if(p->putc) + p->putc(p->iq, ch); + else { + next = p->iw + 1; + if(next == p->ie) + next = p->istage; + if(next != p->ir){ + *p->iw = ch; + p->iw = next; + } + } +} + +/* + * we save up input characters till clock time to reduce + * per character interrupt overhead. + */ +static void +uartclock(void) +{ + Uart *p; + uchar *iw; + + for(p = uartalloc.elist; p; p = p->elist){ + + /* this amortizes cost of qproduce to many chars */ + if(p->iw != p->ir){ + iw = p->iw; + if(iw < p->ir){ + if(qproduce(p->iq, p->ir, p->ie-p->ir) < 0) + (*p->phys->rts)(p, 0); + p->ir = p->istage; + } + if(qproduce(p->iq, p->ir, iw-p->ir) < 0) + (*p->phys->rts)(p, 0); + p->ir = iw; + } + + /* hang up if requested */ + if(p->dohup){ + qhangup(p->iq, 0); + qhangup(p->oq, 0); + p->dohup = 0; + } + + /* this adds hysteresis to hardware/software flow control */ + if(p->ctsbackoff){ + ilock(&p->tlock); + if(p->ctsbackoff){ + if(--(p->ctsbackoff) == 0) + (*p->phys->kick)(p); + } + iunlock(&p->tlock); + } + } +} diff --git a/port/error.h b/port/error.h index 62b513f3571dc08c04ce206aa3c502aa519ae3d1..877fdfc39e1fe63311d46ea04c38838a57647a7c 100644 --- a/port/error.h +++ b/port/error.h @@ -40,7 +40,9 @@ extern char Enoswap[]; /* swap space full */ extern char Esoverlap[]; /* segments overlap */ extern char Emouseset[]; /* mouse type already set */ extern char Eshort[]; /* i/o count too small */ -extern char Egreg[]; /* xterm: Error 50, errno 1: Too big */ +extern char Egreg[]; /* ken has left the building */ extern char Ebadspec[]; /* bad attach specifier */ extern char Enoreg[]; /* process has no saved registers */ extern char Enoattach[]; /* mount/attach disallowed */ +extern char Eshortstat[]; /* stat buffer too small */ +extern char Ebadstat[]; /* malformed stat buffer */ diff --git a/port/lib.h b/port/lib.h index e35280bc13d9b7f65bcd7d07952aefe445c0c73a..2ca7a0c649795f8af18990498c80271f98e9afa8 100644 --- a/port/lib.h +++ b/port/lib.h @@ -19,13 +19,14 @@ extern char *strchr(char*, char); extern char *strrchr(char*, char); extern int strcmp(char*, char*); extern char *strcpy(char*, char*); +extern char *strecpy(char*, char*, char*); extern char *strncat(char*, char*, long); extern char *strncpy(char*, char*, long); extern int strncmp(char*, char*, long); extern long strlen(char*); extern char* strstr(char*, char*); extern int atoi(char*); -extern int tokenize(char*, char**, int); +extern int fullrune(char*, int); enum { @@ -81,6 +82,7 @@ extern char etext[]; extern char edata[]; extern char end[]; extern int getfields(char*, char**, int, int, char*); +extern int tokenize(char*, char**, int); /* * Syscall data structures @@ -100,6 +102,7 @@ extern int getfields(char*, char**, int, int, char*); #define OTRUNC 16 /* or'ed in (except for exec), truncate file first */ #define OCEXEC 32 /* or'ed in, close on exec */ #define ORCLOSE 64 /* or'ed in, remove on close */ +#define OEXCL 0x1000 /* or'ed in, exclusive create */ #define NCONT 0 /* continue after note */ #define NDFLT 1 /* terminate after note */ @@ -110,33 +113,52 @@ typedef struct Qid Qid; typedef struct Dir Dir; typedef struct Waitmsg Waitmsg; -#define ERRLEN 64 -#define DIRLEN 116 -#define NAMELEN 28 +#define ERRMAX 128 /* max length of error string */ +#define KNAMELEN 28 /* max length of name held in kernel */ + +/* bits in Qid.type */ +#define QTDIR 0x80 /* type bit for directories */ +#define QTAPPEND 0x40 /* type bit for append only files */ +#define QTEXCL 0x20 /* type bit for exclusive use files */ +#define QTMOUNT 0x10 /* type bit for mounted channel */ +#define QTFILE 0x00 /* plain file */ + +/* bits in Dir.mode */ +#define DMDIR 0x80000000 /* mode bit for directories */ +#define DMAPPEND 0x40000000 /* mode bit for append only files */ +#define DMEXCL 0x20000000 /* mode bit for exclusive use files */ +#define DMMOUNT 0x10000000 /* mode bit for mounted channel */ +#define DMREAD 0x4 /* mode bit for read permission */ +#define DMWRITE 0x2 /* mode bit for write permission */ +#define DMEXEC 0x1 /* mode bit for execute permission */ struct Qid { - ulong path; + vlong path; ulong vers; + uchar type; }; -struct Dir -{ - char name[NAMELEN]; - char uid[NAMELEN]; - char gid[NAMELEN]; - Qid qid; - ulong mode; - long atime; - long mtime; - vlong length; - short type; - short dev; -}; +typedef +struct Dir { + /* system-modified data */ + ushort type; /* server type */ + uint dev; /* server subtype */ + /* file data */ + Qid qid; /* unique id from server */ + ulong mode; /* permissions */ + ulong atime; /* last read time */ + ulong mtime; /* last write time */ + vlong length; /* file length: see */ + char *name; /* last element of path */ + char *uid; /* owner name */ + char *gid; /* group name */ + char *muid; /* last modifier name */ +} Dir; struct Waitmsg { char pid[12]; /* of loved one */ char time[3*12]; /* of loved one and descendants */ - char msg[ERRLEN]; + char msg[64]; /* compatibility BUG */ }; diff --git a/port/netif.c b/port/netif.c index c2f8ff01d87e67ab2cc22f48a8e58298375d5232..a7f9c22dafb4c8d249d13d33fdd05f3586fe1790 100644 --- a/port/netif.c +++ b/port/netif.c @@ -18,8 +18,8 @@ static int parseaddr(uchar*, char*, int); void netifinit(Netif *nif, char *name, int nfile, ulong limit) { - strncpy(nif->name, name, NAMELEN-1); - nif->name[NAMELEN-1] = 0; + strncpy(nif->name, name, KNAMELEN-1); + nif->name[KNAMELEN-1] = 0; nif->nfile = nfile; nif->f = xalloc(nfile*sizeof(Netfile*)); memset(nif->f, 0, nfile*sizeof(Netfile*)); @@ -30,29 +30,31 @@ netifinit(Netif *nif, char *name, int nfile, ulong limit) * generate a 3 level directory */ static int -netifgen(Chan *c, Dirtab *vp, int, int i, Dir *dp) +netifgen(Chan *c, char*, Dirtab *vp, int, int i, Dir *dp) { Qid q; - char buf[32]; Netif *nif = (Netif*)vp; Netfile *f; int t; int perm; char *o; + q.type = QTFILE; q.vers = 0; /* top level directory contains the name of the network */ - if(c->qid.path == CHDIR){ + if(c->qid.path == 0){ switch(i){ case DEVDOTDOT: - q.path = CHDIR; - devdir(c, q, ".", 0, eve, CHDIR|0555, dp); + q.path = 0; + q.type = QTDIR; + devdir(c, q, ".", 0, eve, 0555, dp); break; case 0: - q.path = CHDIR | N2ndqid; - strcpy(buf, nif->name); - devdir(c, q, buf, 0, eve, CHDIR|0555, dp); + q.path = N2ndqid; + q.type = QTDIR; + strcpy(up->genbuf, nif->name); + devdir(c, q, up->genbuf, 0, eve, 0555, dp); break; default: return -1; @@ -65,8 +67,9 @@ netifgen(Chan *c, Dirtab *vp, int, int i, Dir *dp) if(t == N2ndqid || t == Ncloneqid || t == Naddrqid){ switch(i) { case DEVDOTDOT: - q.path = CHDIR; - devdir(c, q, ".", 0, eve, CHDIR|0555, dp); + q.type = QTDIR; + q.path = 0; + devdir(c, q, ".", 0, eve, DMDIR|0555, dp); break; case 0: q.path = Ncloneqid; @@ -82,9 +85,10 @@ netifgen(Chan *c, Dirtab *vp, int, int i, Dir *dp) return -1; if(nif->f[i] == 0) return 0; - q.path = CHDIR|NETQID(i, N3rdqid); - sprint(buf, "%d", i); - devdir(c, q, buf, 0, eve, CHDIR|0555, dp); + q.type = QTDIR; + q.path = NETQID(i, N3rdqid); + sprint(up->genbuf, "%d", i); + devdir(c, q, up->genbuf, 0, eve, DMDIR|0555, dp); break; } return 1; @@ -103,9 +107,10 @@ netifgen(Chan *c, Dirtab *vp, int, int i, Dir *dp) } switch(i){ case DEVDOTDOT: - q.path = CHDIR | N2ndqid; - strcpy(buf, nif->name); - devdir(c, q, buf, 0, eve, CHDIR|0555, dp); + q.type = QTDIR; + q.path = N2ndqid; + strcpy(up->genbuf, nif->name); + devdir(c, q, up->genbuf, 0, eve, DMDIR|0555, dp); break; case 0: q.path = NETQID(NETID(c->qid.path), Ndataqid); @@ -133,10 +138,10 @@ netifgen(Chan *c, Dirtab *vp, int, int i, Dir *dp) return 1; } -int -netifwalk(Netif *nif, Chan *c, char *name) +Walkqid* +netifwalk(Netif *nif, Chan *c, Chan *nc, char **name, int nname) { - return devwalk(c, name, (Dirtab *)nif, 0, netifgen); + return devwalk(c, nc, name, nname, (Dirtab *)nif, 0, netifgen); } Chan* @@ -146,7 +151,7 @@ netifopen(Netif *nif, Chan *c, int omode) Netfile *f; id = 0; - if(c->qid.path & CHDIR){ + if(c->qid.type & QTDIR){ if(omode != OREAD) error(Eperm); } else { @@ -186,7 +191,7 @@ netifread(Netif *nif, Chan *c, void *a, long n, ulong offset) Netfile *f; char *p; - if(c->qid.path&CHDIR) + if(c->qid.type&QTDIR) return devdirread(c, a, n, (Dirtab*)nif, 0, netifgen); switch(NETTYPE(c->qid.path)){ @@ -234,7 +239,7 @@ netifread(Netif *nif, Chan *c, void *a, long n, ulong offset) Block* netifbread(Netif *nif, Chan *c, long n, ulong offset) { - if((c->qid.path & CHDIR) || NETTYPE(c->qid.path) != Ndataqid) + if((c->qid.type & QTDIR) || NETTYPE(c->qid.path) != Ndataqid) return devbread(c, n, offset); return qbread(nif->f[NETID(c->qid.path)]->in, n); @@ -325,11 +330,12 @@ netifwrite(Netif *nif, Chan *c, void *a, long n) return n; } -void -netifwstat(Netif *nif, Chan *c, char *db) +int +netifwstat(Netif *nif, Chan *c, uchar *db, int n) { - Dir dir; + Dir *dir; Netfile *f; + int m; f = nif->f[NETID(c->qid.path)]; if(f == 0) @@ -338,15 +344,20 @@ netifwstat(Netif *nif, Chan *c, char *db) if(netown(f, up->user, OWRITE) < 0) error(Eperm); - convM2D(db, &dir); - strncpy(f->owner, dir.uid, NAMELEN); - f->mode = dir.mode; + dir = smalloc(sizeof(Dir)+n); + m = convM2D(db, n, &dir[0], (char*)&dir[1]); + if(m > 0){ + strncpy(f->owner, dir[0].uid, KNAMELEN); + f->mode = dir[0].mode; + } + free(dir); + return m; } -void -netifstat(Netif *nif, Chan *c, char *db) +int +netifstat(Netif *nif, Chan *c, uchar *db, int n) { - devstat(c, db, (Dirtab *)nif, 0, netifgen); + return devstat(c, db, n, (Dirtab *)nif, 0, netifgen); } void @@ -406,9 +417,9 @@ netown(Netfile *p, char *o, int omode) lock(&netlock); if(*p->owner){ - if(strncmp(o, p->owner, NAMELEN) == 0) /* User */ + if(strncmp(o, p->owner, KNAMELEN) == 0) /* User */ mode = p->mode; - else if(strncmp(o, eve, NAMELEN) == 0) /* Bootes is group */ + else if(strncmp(o, eve, KNAMELEN) == 0) /* Bootes is group */ mode = p->mode<<3; else mode = p->mode<<6; /* Other */ @@ -422,7 +433,7 @@ netown(Netfile *p, char *o, int omode) return -1; } } - strncpy(p->owner, o, NAMELEN); + strncpy(p->owner, o, KNAMELEN); p->mode = 0660; unlock(&netlock); return 0; diff --git a/port/netif.h b/port/netif.h index b728071a3a512c0871b7a55f71020ae1c12a0a02..2312a4ebae0fd00fcb9ddc22d1ac283119db1977 100644 --- a/port/netif.h +++ b/port/netif.h @@ -22,9 +22,9 @@ enum /* * Macros to manage Qid's used for multiplexed devices */ -#define NETTYPE(x) ((x)&0x1f) -#define NETID(x) (((x)&~CHDIR)>>5) -#define NETQID(i,t) (((i)<<5)|(t)) +#define NETTYPE(x) (((ulong)x)&0x1f) +#define NETID(x) ((((ulong)x))>>5) +#define NETQID(i,t) ((((ulong)i)<<5)|(t)) /* * one per multiplexed connection @@ -35,7 +35,7 @@ struct Netfile int inuse; ulong mode; - char owner[NAMELEN]; + char owner[KNAMELEN]; int type; /* multiplexor type */ int prom; /* promiscuous mode */ @@ -66,7 +66,7 @@ struct Netif QLock; /* multiplexing */ - char name[NAMELEN]; /* for top level directory */ + char name[KNAMELEN]; /* for top level directory */ int nfile; /* max number of Netfiles */ Netfile **f; @@ -99,14 +99,14 @@ struct Netif }; void netifinit(Netif*, char*, int, ulong); -int netifwalk(Netif*, Chan*, char*); +Walkqid* netifwalk(Netif*, Chan*, Chan*, char **, int); Chan* netifopen(Netif*, Chan*, int); void netifclose(Netif*, Chan*); long netifread(Netif*, Chan*, void*, long, ulong); Block* netifbread(Netif*, Chan*, long, ulong); long netifwrite(Netif*, Chan*, void*, long); -void netifwstat(Netif*, Chan*, char*); -void netifstat(Netif*, Chan*, char*); +int netifwstat(Netif*, Chan*, uchar*, int); +int netifstat(Netif*, Chan*, uchar*, int); int activemulti(Netif*, uchar*, int); /* diff --git a/port/parse.c b/port/parse.c index 47518c0bd4a68d6d4a334b6f82a5a8d866177693..ef8b8af95f65de42a3de49df2502a50351c2ad91 100644 --- a/port/parse.c +++ b/port/parse.c @@ -13,18 +13,12 @@ parsecmd(char *p, int n) { Cmdbuf *volatile cb; - if(up != nil) - cb = smalloc(sizeof(*cb)); - else{ - cb = malloc(sizeof(*cb)); - if(cb == nil) - return nil; - } + cb = smalloc(sizeof(*cb)); if(n > sizeof(cb->buf)-1) n = sizeof(cb->buf)-1; - if(up != nil && waserror()){ + if(up!=nil && waserror()){ free(cb); nexterror(); } @@ -35,7 +29,7 @@ parsecmd(char *p, int n) if(n > 0 && cb->buf[n-1] == '\n') n--; cb->buf[n] = '\0'; - cb->nf = tokenize(cb->buf, cb->f, nelem(cb->f)); + cb->nf = getfields(cb->buf, cb->f, nelem(cb->f), 1, " "); return cb; } diff --git a/port/pgrp.c b/port/pgrp.c index 53abfefe8cc50864a3d731bf0910cbde1c7d4a77..b258e206745571fdf2ce2490b6a0fcaa2bda5d24 100644 --- a/port/pgrp.c +++ b/port/pgrp.c @@ -12,9 +12,9 @@ void pgrpnote(ulong noteid, char *a, long n, int flag) { Proc *p, *ep; - char buf[ERRLEN]; + char buf[ERRMAX]; - if(n >= ERRLEN-1) + if(n >= ERRMAX-1) error(Etoobig); memmove(buf, a, n); @@ -133,8 +133,10 @@ pgrpcpy(Pgrp *to, Pgrp *from) for(i = 0; i < MNTHASH; i++) { l = tom++; for(f = from->mnthash[i]; f; f = f->hash) { +extern Ref mheadcounter; rlock(&f->lock); mh = smalloc(sizeof(Mhead)); +incref(&mheadcounter); mh->from = f->from; mh->ref = 1; incref(mh->from); @@ -142,13 +144,7 @@ pgrpcpy(Pgrp *to, Pgrp *from) l = &mh->hash; link = &mh->mount; for(m = f->mount; m; m = m->next) { - n = smalloc(sizeof(Mount)); - n->to = m->to; - incref(n->to); - n->head = mh; - n->flag = m->flag; - if(m->spec[0] != 0) - strncpy(n->spec, m->spec, NAMELEN); + n = newmount(mh, m->to, m->mflag, m->spec); m->copy = n; pgrpinsert(&order, m); *link = n; @@ -237,9 +233,9 @@ newmount(Mhead *mh, Chan *to, int flag, char *spec) m->head = mh; incref(to); m->mountid = incref(&mountid); - m->flag = flag; + m->mflag = flag; if(spec != 0) - strncpy(m->spec, spec, NAMELEN); + kstrdup(&m->spec, spec); return m; } @@ -253,6 +249,7 @@ mountfree(Mount *m) f = m->next; cclose(m->to); m->mountid = 0; + free(m->spec); free(m); m = f; } diff --git a/port/portclock.c b/port/portclock.c index 7d261aa7793cee61c2fe06cfe8595ff160f3025e..edc1917470ba0fa0aba72db21aae37dea74f34bb 100644 --- a/port/portclock.c +++ b/port/portclock.c @@ -47,6 +47,7 @@ portclock(Ureg *ur) m->inclockintr = 1; accounttime(); + kmapinval(); if(kproftimer != nil) kproftimer(ur->pc); @@ -70,6 +71,7 @@ portclock(Ureg *ur) } m->inclockintr = 0; + if(up == 0 || up->state != Running) return; diff --git a/port/portdat.h b/port/portdat.h index a6aac9ea967028128f372d96191778c9ad571f15..b1be6a3f3620e44210bc23fb02cb5e35faedd456 100644 --- a/port/portdat.h +++ b/port/portdat.h @@ -9,7 +9,6 @@ typedef struct Dirtab Dirtab; typedef struct Egrp Egrp; typedef struct Evalue Evalue; typedef struct Fgrp Fgrp; -typedef struct DevConf DevConf; typedef struct Image Image; typedef struct List List; typedef struct Log Log; @@ -24,6 +23,7 @@ typedef struct Note Note; typedef struct Page Page; typedef struct Palloc Palloc; typedef struct Pgrps Pgrps; +typedef struct PhysUart PhysUart; typedef struct Pgrp Pgrp; typedef struct Physseg Physseg; typedef struct Proc Proc; @@ -40,12 +40,12 @@ typedef struct Segment Segment; typedef struct Session Session; typedef struct Talarm Talarm; typedef struct Target Target; +typedef struct Uart Uart; typedef struct Waitq Waitq; -typedef struct Watchdog Watchdog; -typedef int Devgen(Chan*, Dirtab*, int, int, Dir*); +typedef struct Walkqid Walkqid; +typedef int Devgen(Chan*, char*, Dirtab*, int, int, Dir*); -#include #include struct Ref @@ -102,15 +102,16 @@ struct Sargs */ enum { - Aaccess, /* as in access, stat */ + Aaccess, /* as in stat, wstat */ Atodir, /* as in chdir */ Aopen, /* for i/o */ - Amount, /* to be mounted upon */ - Acreate, /* file is to be created */ + Amount, /* to be mounted or mounted upon */ + Acreate, /* is to be created */ + Aremove, /* will be removed by caller */ COPEN = 0x0001, /* for i/o */ CMSG = 0x0002, /* the message channel for a mount */ - CCREATE = 0x0004, /* permits creation if c->mnt */ +/*rsc CCREATE = 0x0004, /* permits creation if c->mnt */ CCEXEC = 0x0008, /* close on exec */ CFREE = 0x0010, /* not in use */ CRCLOSE = 0x0020, /* remove on close */ @@ -149,8 +150,10 @@ struct Chan ushort flag; Qid qid; int fid; /* for devmnt */ - Mhead* mh; /* mount point that derived Chan */ - Mhead* xmh; /* Last mount point crossed */ + ulong iounit; /* chunk size for i/o; 0==default */ + Mhead* umh; /* mount point that derived Chan; used in unionread */ + Chan* umc; /* channel in union; held for union read */ + QLock umqlock; /* serialize unionreads */ int uri; /* union read index */ ulong mountid; Mntcache *mcp; /* Mount cache pointer */ @@ -163,6 +166,7 @@ struct Chan Chan* mchan; /* channel to mounted server */ Qid mqid; /* qid of root of mount point */ Session*session; + char *version; /* 9P version */ Cname *name; }; @@ -182,9 +186,8 @@ struct Dev void (*reset)(void); void (*init)(void); Chan* (*attach)(char*); - Chan* (*clone)(Chan*, Chan*); - int (*walk)(Chan*, char*); - void (*stat)(Chan*, char*); + Walkqid* (*walk)(Chan*, Chan*, char**, int); + int (*stat)(Chan*, uchar*, int); Chan* (*open)(Chan*, int); void (*create)(Chan*, char*, int, ulong); void (*close)(Chan*); @@ -193,19 +196,24 @@ struct Dev long (*write)(Chan*, void*, long, vlong); long (*bwrite)(Chan*, Block*, ulong); void (*remove)(Chan*); - void (*wstat)(Chan*, char*); - void (*power)(int); /* power mgt: power(1) → on, power (0) → off */ - int (*config)(int, char*, DevConf*); + int (*wstat)(Chan*, uchar*, int); }; struct Dirtab { - char name[NAMELEN]; + char name[KNAMELEN]; Qid qid; - vlong length; + vlong length; long perm; }; +struct Walkqid +{ + Chan *clone; + int nqid; + Qid qid[1]; +}; + enum { NSMAX = 1000, @@ -229,8 +237,8 @@ struct Mount Mount* copy; Mount* order; Chan* to; /* channel replacing channel */ - int flag; - char spec[NAMELEN]; + int mflag; + char *spec; }; struct Mhead @@ -251,9 +259,6 @@ struct Mnt ulong id; /* Multiplexer id for channel check */ Mnt *list; /* Free list */ int flags; /* cache */ - int blocksize; /* read/write block size */ - char *partial; /* Outstanding read data */ - int npart; /* Sizeof remains */ }; enum @@ -265,7 +270,7 @@ enum struct Note { - char msg[ERRLEN]; + char msg[ERRMAX]; int flag; /* whether system posted it */ }; @@ -386,14 +391,16 @@ struct Segment enum { - RENDHASH = 32, /* Hash to lookup rendezvous tags */ - MNTHASH = 32, /* Hash to walk mount table */ + RENDLOG = 5, + RENDHASH = 1<rendhash[(s)%RENDHASH]) -#define MOUNTH(p,s) ((p)->mnthash[(s)->qid.path%MNTHASH]) +#define REND(p,s) ((p)->rendhash[(s)&((1<mnthash[(qid).path&((1<wired = 0; p->ureg = 0; p->error[0] = '\0'; + kstrdup(&p->user, "*nouser"); + kstrdup(&p->text, "*notext"); + kstrdup(&p->args, ""); + p->nargs = 0; memset(p->seg, 0, sizeof p->seg); p->pid = incref(&pidalloc); pidhash(p); @@ -784,8 +782,8 @@ pexit(char *exitstr, int freemem) TK2MS(MACHP(0)->ticks - up->time[TReal]), NUMSIZE); if(exitstr && exitstr[0]){ n = sprint(wq->w.msg, "%s %lud:", up->text, up->pid); - strncpy(wq->w.msg+n, exitstr, ERRLEN-n); - wq->w.msg[ERRLEN-1] = 0; + strncpy(wq->w.msg+n, exitstr, sizeof wq->w.msg-n); + wq->w.msg[sizeof wq->w.msg-1] = 0; } else wq->w.msg[0] = '\0'; @@ -948,7 +946,6 @@ procdump(void) continue; dumpaproc(p); - prflush(); } } @@ -1023,8 +1020,8 @@ kproc(char *name, void (*func)(void *), void *arg) static Pgrp *kpgrp; p = newproc(); - p->psstate = "kproc"; - p->procmode = 0644; + p->psstate = 0; + p->procmode = 0640; p->kp = 1; p->fpsave = up->fpsave; @@ -1048,14 +1045,13 @@ kproc(char *name, void (*func)(void *), void *arg) kprocchild(p, func, arg); - strcpy(p->user, eve); + kstrdup(&p->user, eve); + kstrdup(&p->text, name); if(kpgrp == 0) kpgrp = newpgrp(); p->pgrp = kpgrp; incref(kpgrp); - strcpy(p->text, name); - p->nchild = 0; p->parent = 0; memset(p->time, 0, sizeof(p->time)); @@ -1121,7 +1117,7 @@ void error(char *err) { spllo(); - strncpy(up->error, err, ERRLEN); + strncpy(up->error, err, ERRMAX); nexterror(); } @@ -1134,7 +1130,7 @@ nexterror(void) void exhausted(char *resource) { - char buf[ERRLEN]; + char buf[ERRMAX]; sprint(buf, "no free %s", resource); iprint("%s\n", buf); @@ -1188,8 +1184,8 @@ renameuser(char *old, char *new) ep = procalloc.arena+conf.nproc; for(p = procalloc.arena; p < ep; p++) - if(strcmp(old, p->user) == 0) - memmove(p->user, new, NAMELEN); + if(p->user!=nil && strcmp(old, p->user)==0) + kstrdup(&p->user, new); } /* @@ -1249,7 +1245,7 @@ pidunhash(Proc *p) } int -procindex(int pid) +procindex(ulong pid) { Proc *p; int h; diff --git a/port/qio.c b/port/qio.c index 72e65c658d8c498957a23a73c7e8c0f27ef97b0f..3ac46de4e53a04ba226f3072234ce5933254e0a3 100644 --- a/port/qio.c +++ b/port/qio.c @@ -45,7 +45,7 @@ struct Queue QLock wlock; /* mutex for writing processes */ Rendez wr; /* process waiting to write */ - char err[ERRLEN]; + char err[ERRMAX]; }; enum @@ -1277,7 +1277,7 @@ qhangup(Queue *q, char *msg) if(msg == 0 || *msg == 0) strcpy(q->err, Ehungup); else - strncpy(q->err, msg, ERRLEN-1); + strncpy(q->err, msg, ERRMAX-1); iunlock(q); /* wake up readers/writers */ diff --git a/port/rdb.c b/port/rdb.c index ca5559173701793ad9f9f8fc183321399537ba73..976fc5d6f13a38071b18ceac23d640e9e5313374 100644 --- a/port/rdb.c +++ b/port/rdb.c @@ -6,8 +6,6 @@ #include "io.h" #include "ureg.h" -extern Queue *printq; - #define DBG if(0)scrprint #pragma varargck argpos scrprint 1 static Ureg ureg; @@ -62,7 +60,8 @@ talkrdb(Ureg *ureg) char *p; char *req; - printq = nil; // turn off serial console + serialoq = nil; // turn off serial console + kprintoq = nil; // turn off /dev/kprint if active // scrprint("Plan 9 debugger\n"); iprint("Edebugger reset\n"); for(;;){ diff --git a/port/sd.h b/port/sd.h index bd1075e174c87c3fec96598c7a9621caa2b5f984..55dcf8a43bb9cf22ae7e6d5b21ceed878a8461fc 100644 --- a/port/sd.h +++ b/port/sd.h @@ -9,8 +9,8 @@ typedef struct SDreq SDreq; typedef struct SDunit SDunit; typedef struct SDperm { - char name[NAMELEN]; - char user[NAMELEN]; + char *name; + char *user; ulong perm; } SDperm; @@ -50,7 +50,7 @@ typedef struct SDev { SDifc* ifc; /* pnp/legacy */ void *ctlr; int idno; - char name[NAMELEN]; + char *name; int index; /* into unit space */ int nunit; SDev* next; diff --git a/port/segment.c b/port/segment.c index 848012b02f19beb8f2cb3650b31934aeb9022d7b..69c4c72c8021b5213b5986c0df73897402aa3d1c 100644 --- a/port/segment.c +++ b/port/segment.c @@ -387,7 +387,7 @@ putimage(Image *i) lock(i); if(--i->ref == 0) { l = &ihash(i->qid.path); - i->qid = (Qid){~0, ~0}; + mkqid(&i->qid, ~0, ~0, QTFILE); unlock(i); c = i->c; @@ -541,11 +541,13 @@ out: } Segment* -isoverlap(Proc *p, ulong va, int newtop) +isoverlap(Proc *p, ulong va, int len) { int i; Segment *ns; + ulong newtop; + newtop = va+len; for(i = 0; i < NSEG; i++) { ns = p->seg[i]; if(ns == 0) @@ -584,30 +586,10 @@ addphysseg(Physseg* new) return 0; } -int -isphysseg(char *name) -{ - Physseg *ps; - int rv = 0; - - lock(&physseglock); - for(ps = physseg; ps->name; ps++){ - if(strcmp(ps->name, name) == 0){ - rv = 1; - break; - } - } - unlock(&physseglock); - return rv; -} - -Segment* (*_globalsegattach)(Proc*, char*); - ulong segattach(Proc *p, ulong attr, char *name, ulong va, ulong len) { int sno; - ulong top; Segment *s, *os; Physseg *ps; @@ -624,18 +606,7 @@ segattach(Proc *p, ulong attr, char *name, ulong va, ulong len) if(sno == NSEG) error(Enovmem); - /* - * first look for a global segment with the - * same name - */ - if(_globalsegattach != nil){ - s = (*_globalsegattach)(p, name); - if(s != nil){ - p->seg[sno] = s; - return s->base; - } - } - + len = PGROUND(len); if(len == 0) error(Ebadarg); @@ -647,10 +618,9 @@ segattach(Proc *p, ulong attr, char *name, ulong va, ulong len) * or the address space is exhausted. */ if(va == 0) { - len = PGROUND(len); va = p->seg[SSEG]->base - len; for(;;) { - os = isoverlap(p, va, va+len); + os = isoverlap(p, va, len); if(os == nil) break; va = os->base; @@ -660,10 +630,8 @@ segattach(Proc *p, ulong attr, char *name, ulong va, ulong len) } } - top = PGROUND(va + len); va = va&~(BY2PG-1); - len = top - va; - if(isoverlap(p, va, top) != nil) + if(isoverlap(p, va, len) != nil) error(Esoverlap); for(ps = physseg; ps->name; ps++) @@ -702,9 +670,9 @@ long syssegflush(ulong *arg) { Segment *s; - ulong addr, l, ps, pe; + ulong addr, l; Pte *pte; - int chunk, len; + int chunk, ps, pe, len; addr = arg[0]; len = arg[1]; diff --git a/port/swap.c b/port/swap.c index cecf52af8dcab8adc057ec243b7de3b537b9c20c..70c180ef7e6fc926ca0d9646044529834e2796a7 100644 --- a/port/swap.c +++ b/port/swap.c @@ -370,8 +370,9 @@ needpages(void*) void setswapchan(Chan *c) { - char dirbuf[DIRLEN]; + uchar dirbuf[sizeof(Dir)+100]; Dir d; + int n; if(swapimage.c) { if(swapalloc.free != conf.nswap){ @@ -386,8 +387,12 @@ setswapchan(Chan *c) * to be at most the size of the partition */ if(devtab[c->type]->dc != L'M'){ - devtab[c->type]->stat(c, dirbuf); - convM2D(dirbuf, &d); + n = devtab[c->type]->stat(c, dirbuf, sizeof dirbuf); + if(n <= 0){ + cclose(c); + error("stat failed in setswapchan"); + } + convM2D(dirbuf, n, &d, nil); if(d.length < conf.nswap*BY2PG){ conf.nswap = d.length/BY2PG; swapalloc.top = &swapalloc.swmap[conf.nswap]; diff --git a/port/sysfile.c b/port/sysfile.c index c54c5694337677e876ff60c930a7540c2f86cb71..3a62c9d24864d274f27740ede39b49e12d4768e2 100644 --- a/port/sysfile.c +++ b/port/sysfile.c @@ -180,6 +180,7 @@ syspipe(ulong *arg) int fd[2]; Chan *c[2]; Dev *d; + static char *datastr[] = {"data", "data1"}; validaddr(arg[0], 2*BY2WD, 1); evenaddr(arg[0]); @@ -195,10 +196,10 @@ syspipe(ulong *arg) cclose(c[1]); nexterror(); } - c[1] = cclone(c[0], 0); - if(walk(&c[0], "data", 1) < 0) + c[1] = cclone(c[0]); + if(walk(&c[0], datastr+0, 1, 1) < 0) error(Egreg); - if(walk(&c[1], "data1", 1) < 0) + if(walk(&c[1], datastr+1, 1, 1) < 0) error(Egreg); c[0] = d->open(c[0], ORDWR); c[1] = d->open(c[1], ORDWR); @@ -316,89 +317,84 @@ unionread(Chan *c, void *va, long n) { int i; long nr; - Chan *nc; Mhead *m; Mount *mount; - m = c->mh; + qlock(&c->umqlock); + m = c->umh; rlock(&m->lock); mount = m->mount; + /* bring mount in sync with c->uri and c->umc */ for(i = 0; mount != nil && i < c->uri; i++) mount = mount->next; + nr = 0; while(mount != nil) { - if(waserror()) { - runlock(&m->lock); - nexterror(); - } - if(mount->to == nil) - goto next; - nc = cclone(mount->to, 0); - poperror(); - /* Error causes component of union to be skipped */ - if(waserror()) { - cclose(nc); - goto next; + if(mount->to && !waserror()) { + if(c->umc == nil){ + c->umc = cclone(mount->to); + c->umc = devtab[c->umc->type]->open(c->umc, OREAD); + } + + nr = devtab[c->umc->type]->read(c->umc, va, n, c->umc->offset); + c->umc->offset += nr; + poperror(); } + if(nr > 0) + break; - nc = devtab[nc->type]->open(nc, OREAD); - nc->offset = c->offset; - nr = devtab[nc->type]->read(nc, va, n, nc->offset); - /* devdirread e.g. changes it */ - c->offset = nc->offset; - poperror(); - - cclose(nc); - if(nr > 0) { - runlock(&m->lock); - return nr; - } /* Advance to next element */ - next: c->uri++; + if(c->umc) { + cclose(c->umc); + c->umc = nil; + } mount = mount->next; - if(mount == nil) - break; - c->offset = 0; } runlock(&m->lock); - return 0; + qunlock(&c->umqlock); + return nr; } -long -sysread9p(ulong *arg) +static long +read(ulong *arg, uvlong *offp) { int dir; long n; Chan *c; + uvlong off; - validaddr(arg[1], arg[2], 1); + n = arg[2]; + validaddr(arg[1], n, 1); c = fdtochan(arg[0], OREAD, 1, 1); + if(waserror()) { cclose(c); nexterror(); } - n = arg[2]; - dir = c->qid.path&CHDIR; + dir = c->qid.type&QTDIR; + /* + * The offset is passed through on directories, normally. sysseek complains but + * pread is used by servers and e.g. exportfs that shouldn't need to worry about this issue. + */ - if(dir) { - n -= n%DIRLEN; - if(c->offset%DIRLEN || n==0) - error(Etoosmall); - } + if(offp == nil) /* use and maintain channel's offset */ + off = c->offset; + else + off = *offp; - if(dir && c->mh) + if(dir && c->umh) n = unionread(c, (void*)arg[1], n); - else if(devtab[c->type]->dc != L'M') - n = devtab[c->type]->read(c, (void*)arg[1], n, c->offset); else - n = mntread9p(c, (void*)arg[1], n, c->offset); + n = devtab[c->type]->read(c, (void*)arg[1], n, off); - lock(c); - c->offset += n; - unlock(c); + if(offp == nil){ + lock(c); + c->offset += n; + unlock(c); + } poperror(); cclose(c); @@ -407,138 +403,64 @@ sysread9p(ulong *arg) } long -sysread(ulong *arg) +sys_read(ulong *arg) { - int dir; - long n; - Chan *c; - - n = arg[2]; - validaddr(arg[1], n, 1); - c = fdtochan(arg[0], OREAD, 1, 1); - - if(waserror()) { - cclose(c); - nexterror(); - } - - dir = c->qid.path&CHDIR; - - if(dir) { - n -= n%DIRLEN; - if(c->offset%DIRLEN || n==0) - error(Etoosmall); - } - - if(dir && c->mh) - n = unionread(c, (void*)arg[1], n); - else - n = devtab[c->type]->read(c, (void*)arg[1], n, c->offset); - - lock(c); - c->offset += n; - unlock(c); - - poperror(); - cclose(c); - - return n; + return read(arg, nil); } long syspread(ulong *arg) { - long n; - Chan *c; union { uvlong v; ulong u[2]; } o; - if(arg[3] == ~0UL && arg[4] == ~0UL) - return sysread(arg); + if(arg[3]==~0UL && arg[4]==~0UL) + return read(arg, nil); - n = arg[2]; - validaddr(arg[1], n, 1); - c = fdtochan(arg[0], OREAD, 1, 1); o.u[0] = arg[3]; o.u[1] = arg[4]; - if(waserror()) { - cclose(c); - nexterror(); - } - - if(c->qid.path&CHDIR) - error(Eisdir); - - n = devtab[c->type]->read(c, (void*)arg[1], n, o.v); - - poperror(); - cclose(c); - - return n; + return read(arg, &o.v); } -long -syswrite9p(ulong *arg) +static long +write(ulong *arg, uvlong *offp) { Chan *c; - long n; + long m, n; + uvlong off; validaddr(arg[1], arg[2], 0); + n = 0; c = fdtochan(arg[0], OWRITE, 1, 1); if(waserror()) { + if(offp == nil){ + lock(c); + c->offset -= n; + unlock(c); + } cclose(c); nexterror(); } - if(c->qid.path & CHDIR) + if(c->qid.type & QTDIR) error(Eisdir); - if(devtab[c->type]->dc != L'M') - n = devtab[c->type]->write(c, (void*)arg[1], arg[2], c->offset); - else - n = mntwrite9p(c, (void*)arg[1], arg[2], c->offset); - lock(c); - c->offset += n; - unlock(c); - - poperror(); - cclose(c); - - return n; -} - -long -syswrite(ulong *arg) -{ - Chan *c; - long m, n; - uvlong oo; - - validaddr(arg[1], arg[2], 0); n = arg[2]; - c = fdtochan(arg[0], OWRITE, 1, 1); - if(waserror()) { - cclose(c); + + if(offp == nil){ /* use and maintain channel's offset */ lock(c); - c->offset -= n; + off = c->offset; + c->offset += n; unlock(c); - nexterror(); - } + }else + off = *offp; - if(c->qid.path & CHDIR) - error(Eisdir); - - lock(c); - oo = c->offset; - c->offset += n; - unlock(c); - - m = devtab[c->type]->write(c, (void*)arg[1], n, oo); + m = devtab[c->type]->write(c, (void*)arg[1], n, off); - if(m < n){ + if(offp == nil && m < n){ lock(c); c->offset -= n - m; unlock(c); @@ -550,46 +472,36 @@ syswrite(ulong *arg) return m; } +long +sys_write(ulong *arg) +{ + return write(arg, nil); +} + long syspwrite(ulong *arg) { - Chan *c; - long m, n; union { uvlong v; ulong u[2]; } o; - if(arg[3] == ~0UL && arg[4] == ~0UL) - return syswrite(arg); + if(arg[3]==~0UL && arg[4]==~0UL) + return write(arg, nil); - validaddr(arg[1], arg[2], 0); - n = arg[2]; - c = fdtochan(arg[0], OWRITE, 1, 1); o.u[0] = arg[3]; o.u[1] = arg[4]; - if(waserror()) { - cclose(c); - nexterror(); - } - - if(c->qid.path & CHDIR) - error(Eisdir); - m = devtab[c->type]->write(c, (void*)arg[1], n, o.v); - - poperror(); - cclose(c); - - return m; + return write(arg, &o.v); } static void sseek(ulong *arg) { Chan *c; - char buf[DIRLEN]; + uchar buf[sizeof(Dir)+100]; Dir dir; + int n; vlong off; union { vlong v; @@ -601,9 +513,6 @@ sseek(ulong *arg) cclose(c); nexterror(); } - if(c->qid.path & CHDIR) - error(Eisdir); - if(devtab[c->type]->dc == '|') error(Eisstream); @@ -613,10 +522,14 @@ sseek(ulong *arg) switch(arg[4]){ case 0: off = o.v; + if((c->qid.type & QTDIR) && off != 0) + error(Eisdir); c->offset = off; break; case 1: + if(c->qid.type & QTDIR) + error(Eisdir); lock(c); /* lock for read/write update */ off = o.v + c->offset; c->offset = off; @@ -624,11 +537,17 @@ sseek(ulong *arg) break; case 2: - devtab[c->type]->stat(c, buf); - convM2D(buf, &dir); + if(c->qid.type & QTDIR) + error(Eisdir); + n = devtab[c->type]->stat(c, buf, sizeof buf); + if(convM2D(buf, n, &dir, nil) == 0) + error("internal error: stat error in seek"); off = dir.length + o.v; c->offset = off; break; + + default: + error(Ebadarg); } *(vlong*)arg[0] = off; c->uri = 0; @@ -663,41 +582,70 @@ sysoseek(ulong *arg) return o.v; } +void +validstat(uchar *s, int n) +{ + int m; + char buf[64]; + + if(statcheck(s, n) < 0) + error(Ebadstat); + /* verify that name entry is acceptable */ + s += STATFIXLEN - 4*BIT16SZ; /* location of first string */ + /* + * s now points at count for first string. + * if it's too long, let the server decide; this is + * only for his protection anyway. otherwise + * we'd have to allocate and waserror. + */ + m = GBIT16(s); + s += BIT16SZ; + if(m+1 > sizeof buf) + return; + memmove(buf, s, m); + buf[m] = '\0'; + /* name could be '/' */ + if(strcmp(buf, "/") != 0) + validname(buf, 0); +} + long sysfstat(ulong *arg) { Chan *c; + uint l; - validaddr(arg[1], DIRLEN, 1); - evenaddr(arg[1]); + l = arg[2]; + validaddr(arg[1], l, 1); c = fdtochan(arg[0], -1, 0, 1); if(waserror()) { cclose(c); nexterror(); } - devtab[c->type]->stat(c, (char*)arg[1]); + l = devtab[c->type]->stat(c, (uchar*)arg[1], l); poperror(); cclose(c); - return 0; + return l; } long sysstat(ulong *arg) { Chan *c; + uint l; - validaddr(arg[1], DIRLEN, 1); - evenaddr(arg[1]); + l = arg[2]; + validaddr(arg[1], l, 1); validaddr(arg[0], 1, 0); c = namec((char*)arg[0], Aaccess, 0, 0); if(waserror()){ cclose(c); nexterror(); } - devtab[c->type]->stat(c, (char*)arg[1]); + l = devtab[c->type]->stat(c, (uchar*)arg[1], l); poperror(); cclose(c); - return 0; + return l; } long @@ -744,13 +692,12 @@ bindmount(ulong *arg, int ismount) bogus.chan = bc; validaddr(arg[3], 1, 0); - if(vmemchr((char*)arg[3], '\0', NAMELEN) == 0) - error(Ebadarg); + validname((char*)arg[3], 1); bogus.spec = (char*)arg[3]; if(waserror()) error(Ebadspec); - nameok(bogus.spec, 1); + validname(bogus.spec, 1); poperror(); ret = devno('M', 0); @@ -762,7 +709,7 @@ bindmount(ulong *arg, int ismount) else { bogus.spec = 0; validaddr(arg[0], 1, 0); - c0 = namec((char*)arg[0], Aaccess, 0, 0); + c0 = namec((char*)arg[0], Amount, 0, 0); } if(waserror()){ @@ -777,7 +724,7 @@ bindmount(ulong *arg, int ismount) nexterror(); } - ret = cmount(c0, c1, flag, bogus.spec); + ret = cmount(&c0, c1, flag, bogus.spec); poperror(); cclose(c1); @@ -862,7 +809,7 @@ sysremove(ulong *arg) Chan *c; validaddr(arg[0], 1, 0); - c = namec((char*)arg[0], Aaccess, 0, 0); + c = namec((char*)arg[0], Aremove, 0, 0); if(waserror()){ c->type = 0; /* see below */ cclose(c); @@ -883,35 +830,148 @@ long syswstat(ulong *arg) { Chan *c; + uint l; - validaddr(arg[1], DIRLEN, 0); - nameok((char*)arg[1], 0); + l = arg[2]; + validaddr(arg[1], l, 0); + validstat((uchar*)arg[1], l); validaddr(arg[0], 1, 0); c = namec((char*)arg[0], Aaccess, 0, 0); if(waserror()){ cclose(c); nexterror(); } - devtab[c->type]->wstat(c, (char*)arg[1]); + l = devtab[c->type]->wstat(c, (uchar*)arg[1], l); poperror(); cclose(c); - return 0; + return l; } long sysfwstat(ulong *arg) { Chan *c; + uint l; - validaddr(arg[1], DIRLEN, 0); - nameok((char*)arg[1], 0); + l = arg[2]; + validaddr(arg[1], l, 0); + validstat((uchar*)arg[1], l); c = fdtochan(arg[0], -1, 1, 1); if(waserror()) { cclose(c); nexterror(); } - devtab[c->type]->wstat(c, (char*)arg[1]); + l = devtab[c->type]->wstat(c, (uchar*)arg[1], l); + poperror(); + cclose(c); + return l; +} + +static void +packoldstat(uchar *buf, Dir *d) +{ + uchar *p; + ulong q; + + /* lay down old stat buffer - grotty code but it's temporary */ + p = buf; + strncpy((char*)p, d->name, 28); + p += 28; + strncpy((char*)p, d->uid, 28); + p += 28; + strncpy((char*)p, d->gid, 28); + p += 28; + q = d->qid.path & ~DMDIR; /* make sure doesn't accidentally look like directory */ + if(d->qid.type & QTDIR) /* this is the real test of a new directory */ + q |= DMDIR; + PBIT32(p, q); + p += BIT32SZ; + PBIT32(p, d->qid.vers); + p += BIT32SZ; + PBIT32(p, d->mode); + p += BIT32SZ; + PBIT32(p, d->atime); + p += BIT32SZ; + PBIT32(p, d->mtime); + p += BIT32SZ; + PBIT64(p, d->length); + p += BIT64SZ; + PBIT16(p, d->type); + p += BIT16SZ; + PBIT16(p, d->dev); +} + +long +sys_stat(ulong *arg) +{ + Chan *c; + uint l; + uchar buf[128]; /* old DIRLEN plus a little should be plenty */ + char strs[128]; + Dir d; + char old[] = "old stat system call - recompile"; + + validaddr(arg[1], 116, 1); + validaddr(arg[0], 1, 0); + c = namec((char*)arg[0], Aaccess, 0, 0); + if(waserror()){ + cclose(c); + nexterror(); + } + l = devtab[c->type]->stat(c, buf, sizeof buf); + /* buf contains a new stat buf; convert to old. yuck. */ + if(l <= BIT16SZ) /* buffer too small; time to face reality */ + error(old); + l = convM2D(buf, l, &d, strs); + if(l == 0) + error(old); + packoldstat((uchar*)arg[1], &d); + + poperror(); + cclose(c); + return 0; +} + +long +sys_fstat(ulong *arg) +{ + Chan *c; + uint l; + uchar buf[128]; /* old DIRLEN plus a little should be plenty */ + char strs[128]; + Dir d; + char old[] = "old fstat system call - recompile"; + + validaddr(arg[1], 116, 1); + c = fdtochan(arg[0], -1, 0, 1); + if(waserror()){ + cclose(c); + nexterror(); + } + l = devtab[c->type]->stat(c, buf, sizeof buf); + /* buf contains a new stat buf; convert to old. yuck. */ + if(l <= BIT16SZ) /* buffer too small; time to face reality */ + error(old); + l = convM2D(buf, l, &d, strs); + if(l == 0) + error(old); + packoldstat((uchar*)arg[1], &d); + poperror(); cclose(c); return 0; } + +long +sys_wstat(ulong *) +{ + error("old wstat system call - recompile"); + return -1; +} + +long +sys_fwstat(ulong *) +{ + error("old fwstat system call - recompile"); + return -1; +} diff --git a/port/sysproc.c b/port/sysproc.c index 639c6b9a1fa11d185b54374292b441e0c37886e4..9ba3751ceb8de87b1e2f20ef7d4f987c22c42788 100644 --- a/port/sysproc.c +++ b/port/sysproc.c @@ -12,7 +12,14 @@ int shargs(char*, int, char**); long sysr1(ulong *arg) { +extern int chandebug; +extern void dumpmount(void); + print("[%s %s %lud] r1 = %lud\n", up->user, up->text, up->pid, arg[0]); +chandebug=!chandebug; +if(chandebug) + dumpmount(); + return 0; } @@ -164,7 +171,7 @@ sysrfork(ulong *arg) p->parent = up; p->parentpid = up->pid; if(flag&RFNOWAIT) - p->parentpid = 1; + p->parentpid = 0; else { lock(&up->exl); up->nchild++; @@ -177,8 +184,9 @@ sysrfork(ulong *arg) pid = p->pid; memset(p->time, 0, sizeof(p->time)); p->time[TReal] = MACHP(0)->ticks; - memmove(p->text, up->text, NAMELEN); - memmove(p->user, up->user, NAMELEN); + + kstrdup(&p->text, up->text); + kstrdup(&p->user, up->user); /* * since the bss/data segments are now shareable, * any mmu info about this process is now stale @@ -215,7 +223,7 @@ sysexec(ulong *arg) Chan *tc; char **argv, **argp; char *a, *charp, *args, *file; - char *progarg[sizeof(Exec)/2+1], elem[NAMELEN]; + char *progarg[sizeof(Exec)/2+1], *elem, progelem[64]; ulong ssize, spage, nargs, nbytes, n, bssend; int indir; Exec exec; @@ -227,6 +235,11 @@ sysexec(ulong *arg) validaddr(arg[0], 1, 0); file = (char*)arg[0]; indir = 0; + elem = nil; + if(waserror()){ + free(elem); + nexterror(); + } for(;;){ tc = namec(file, Aopen, OEXEC, 0); if(waserror()){ @@ -234,7 +247,7 @@ sysexec(ulong *arg) nexterror(); } if(!indir) - strcpy(elem, up->elem); + kstrdup(&elem, up->genbuf); n = devtab[tc->type]->read(tc, &exec, sizeof(Exec), 0); if(n < 2) @@ -268,7 +281,10 @@ sysexec(ulong *arg) validaddr(arg[1], BY2WD, 1); arg[1] += BY2WD; file = progarg[0]; - progarg[0] = elem; + if(strlen(elem) >= sizeof progelem) + error(Ebadexec); + strcpy(progelem, elem); + progarg[0] = progelem; poperror(); cclose(tc); } @@ -351,7 +367,10 @@ sysexec(ulong *arg) charp += n; } - memmove(up->text, elem, NAMELEN); + free(up->text); + up->text = elem; + elem = nil; /* so waserror() won't free elem */ + USED(elem); /* copy args; easiest from new process's stack */ n = charp - args; @@ -428,7 +447,8 @@ sysexec(ulong *arg) up->seg[ESEG] = 0; up->seg[SSEG] = s; qunlock(&up->seglock); - poperror(); + poperror(); /* seglock */ + poperror(); /* elem */ s->base = USTKTOP-USTKSIZE; s->top = USTKTOP; relocateseg(s, USTKTOP-TSTKTOP); @@ -525,7 +545,7 @@ sysexits(ulong *arg) { char *status; char *inval = "invalid exit string"; - char buf[ERRLEN]; + char buf[ERRMAX]; status = (char*)arg[0]; if(status){ @@ -533,9 +553,9 @@ sysexits(ulong *arg) status = inval; else{ validaddr((ulong)status, 1, 0); - if(vmemchr(status, 0, ERRLEN) == 0){ - memmove(buf, status, ERRLEN); - buf[ERRLEN-1] = 0; + if(vmemchr(status, 0, ERRMAX) == 0){ + memmove(buf, status, ERRMAX); + buf[ERRMAX-1] = 0; status = buf; } } @@ -573,23 +593,45 @@ werrstr(char *fmt, ...) return; va_start(va, fmt); - doprint(up->error, up->error+ERRLEN, fmt, va); + doprint(up->error, up->error+ERRMAX, fmt, va); va_end(va); } long syserrstr(ulong *arg) { - char *e, tmp[ERRLEN]; + char *e, tmp[sizeof up->error]; + uint n; - validaddr(arg[0], ERRLEN, 1); + n = arg[1]; + if(n > sizeof tmp) + n = sizeof tmp; + validaddr(arg[0], n, 1); e = (char*)arg[0]; - memmove(tmp, e, ERRLEN); - memmove(e, up->error, ERRLEN); - memmove(up->error, tmp, ERRLEN); + memmove(tmp, e, n); + /* make sure it's NUL-terminated */ + tmp[n-1] = '\0'; + memmove(e, up->error, n); + e[n-1] = '\0'; + memmove(up->error, tmp, n); return 0; } +/* compatibility for old binaries */ +long +sys_errstr(ulong *arg) +{ + char *e, tmp[64]; + + validaddr(arg[0], 64, 1); + e = (char*)arg[0]; + memmove(tmp, e, 64); + memmove(e, up->error, 64); + memmove(up->error, tmp, 64); + return 0; +} + + long sysnotify(ulong *arg) { diff --git a/port/systab.h b/port/systab.h index 574a5e492c8edb18b4f47cf9efb1c2cf4d4724d8..d201490783632ba2d13369a9fe3572c5acfbb06f 100644 --- a/port/systab.h +++ b/port/systab.h @@ -1,10 +1,9 @@ -#undef CHDIR /* BUG */ #include "/sys/src/libc/9syscall/sys.h" typedef long Syscall(ulong*); Syscall sysr1; -Syscall syserrstr; +Syscall sys_errstr; Syscall sysbind; Syscall syschdir; Syscall sysclose; @@ -14,23 +13,23 @@ Syscall sysexec; Syscall sysexits; Syscall sysfsession; Syscall sysfauth; -Syscall sysfstat; +Syscall sys_fstat; Syscall syssegbrk; Syscall sysmount; Syscall sysopen; -Syscall sysread; +Syscall sys_read; Syscall sysoseek; Syscall syssleep; -Syscall sysstat; +Syscall sys_stat; Syscall sysrfork; -Syscall syswrite; +Syscall sys_write; Syscall syspipe; Syscall syscreate; Syscall sysfd2path; Syscall sysbrk_; Syscall sysremove; -Syscall syswstat; -Syscall sysfwstat; +Syscall sys_wstat; +Syscall sys_fwstat; Syscall sysnotify; Syscall sysnoted; Syscall syssegattach; @@ -40,16 +39,20 @@ Syscall syssegflush; Syscall sysrendezvous; Syscall sysunmount; Syscall syswait; -Syscall syswrite9p; -Syscall sysread9p; Syscall sysseek; +Syscall sysfversion; +Syscall syserrstr; +Syscall sysstat; +Syscall sysfstat; +Syscall syswstat; +Syscall sysfwstat; Syscall syspread; Syscall syspwrite; Syscall sysdeath; Syscall *systab[]={ [SYSR1] sysr1, - [ERRSTR] syserrstr, + [_ERRSTR] sys_errstr, [BIND] sysbind, [CHDIR] syschdir, [CLOSE] sysclose, @@ -59,23 +62,23 @@ Syscall *systab[]={ [EXITS] sysexits, [FSESSION] sysfsession, [FAUTH] sysfauth, - [FSTAT] sysfstat, + [_FSTAT] sys_fstat, [SEGBRK] syssegbrk, [MOUNT] sysmount, [OPEN] sysopen, - [READ] sysread, + [_READ] sys_read, [OSEEK] sysoseek, [SLEEP] syssleep, - [STAT] sysstat, + [_STAT] sys_stat, [RFORK] sysrfork, - [WRITE] syswrite, + [_WRITE] sys_write, [PIPE] syspipe, [CREATE] syscreate, [FD2PATH] sysfd2path, [BRK_] sysbrk_, [REMOVE] sysremove, - [WSTAT] syswstat, - [FWSTAT] sysfwstat, + [_WSTAT] sys_wstat, + [_FWSTAT] sys_fwstat, [NOTIFY] sysnotify, [NOTED] sysnoted, [SEGATTACH] syssegattach, @@ -85,16 +88,20 @@ Syscall *systab[]={ [RENDEZVOUS] sysrendezvous, [UNMOUNT] sysunmount, [WAIT] syswait, - [WRITE9P] syswrite9p, - [READ9P] sysread9p, [SEEK] sysseek, + [FVERSION] sysfversion, + [ERRSTR] syserrstr, + [STAT] sysstat, + [FSTAT] sysfstat, + [WSTAT] syswstat, + [FWSTAT] sysfwstat, [PREAD] syspread, [PWRITE] syspwrite, }; char *sysctab[]={ [SYSR1] "Running", - [ERRSTR] "Errstr", + [_ERRSTR] "_errstr", [BIND] "Bind", [CHDIR] "Chdir", [CLOSE] "Close", @@ -104,23 +111,23 @@ char *sysctab[]={ [EXITS] "Exits", [FSESSION] "Fsession", [FAUTH] "Fauth", - [FSTAT] "Fstat", + [_FSTAT] "_fstat", [SEGBRK] "Segbrk", [MOUNT] "Mount", [OPEN] "Open", - [READ] "Read", + [_READ] "_read", [OSEEK] "Oseek", [SLEEP] "Sleep", - [STAT] "Stat", + [_STAT] "_stat", [RFORK] "Rfork", - [WRITE] "Write", + [_WRITE] "_write", [PIPE] "Pipe", [CREATE] "Create", [FD2PATH] "Fd2path", [BRK_] "Brk", [REMOVE] "Remove", - [WSTAT] "Wstat", - [FWSTAT] "Fwstat", + [_WSTAT] "_wstat", + [_FWSTAT] "_fwstat", [NOTIFY] "Notify", [NOTED] "Noted", [SEGATTACH] "Segattach", @@ -130,9 +137,13 @@ char *sysctab[]={ [RENDEZVOUS] "Rendez", [UNMOUNT] "Unmount", [WAIT] "Wait", - [WRITE9P] "Write9p", - [READ9P] "Read9p", [SEEK] "Seek", + [FVERSION] "Fversion", + [ERRSTR] "Errstr", + [STAT] "Stat", + [FSTAT] "Fstat", + [WSTAT] "Wstat", + [FWSTAT] "Fwstat", [PREAD] "Pread", [PWRITE] "Pwrite", }; diff --git a/port/taslock.c b/port/taslock.c index 19a763f72a15b9a8baf4a91d124b7de24bb7d093..99a492357f2f4a1626283589f4b54e61b147c6fa 100644 --- a/port/taslock.c +++ b/port/taslock.c @@ -30,8 +30,8 @@ lockloop(Lock *l, ulong pc) Proc *p; p = l->p; - print("lock loop key 0x%lux pc 0x%lux held by pc 0x%lux proc %lud\n", - l->key, pc, l->pc, p ? p->pid : 0); + print("lock 0x%lux loop key 0x%lux pc 0x%lux held by pc 0x%lux proc %lud\n", + l, l->key, pc, l->pc, p ? p->pid : 0); dumpaproc(up); if(p != nil) dumpaproc(p); diff --git a/port/thwack.h b/port/thwack.h index d50c47c23c26a365a1522111dd7ddd377780fb4e..abb6cd3beccecdf1cfaec6b1e8e277168f009de4 100644 --- a/port/thwack.h +++ b/port/thwack.h @@ -19,7 +19,7 @@ enum MinDecode = 8, /* minimum bits to decode a match or lit; >= 8 */ - EWinBlocks = 22, /* blocks held in encoder window */ + EWinBlocks = 32, /* blocks held in encoder window */ DWinBlocks = 32, /* blocks held in decoder window */ CompBlocks = 10, /* max blocks used to encode data */ @@ -65,4 +65,3 @@ void unthwackinit(Unthwack*); int thwack(Thwack*, uchar *dst, uchar *src, int nsrc, ulong seq, ulong stats[ThwStats]); void thwackack(Thwack*, ulong seq, ulong mask); int unthwack(Unthwack*, uchar *dst, int ndst, uchar *src, int nsrc, ulong seq); -ulong unthwackstate(Unthwack *ut, uchar *mask); diff --git a/port/unthwack.c b/port/unthwack.c index 3c8f40f5c1a3415309590a171e3c7d26703ea69e..4ea74af18be783ac1bb1aad47cdfc2f8cf7e37fd 100644 --- a/port/unthwack.c +++ b/port/unthwack.c @@ -59,86 +59,39 @@ unthwackinit(Unthwack *ut) ut->blocks[i].data = ut->data[i]; } -ulong -unthwackstate(Unthwack *ut, uchar *mask) +int +unthwack(Unthwack *ut, uchar *dst, int ndst, uchar *src, int nsrc, ulong seq) { - ulong bseq, seq; - int slot, m; - - seq = ~0UL; - m = 0; - slot = ut->slot; - for(;;){ - slot--; - if(slot < 0) - slot += DWinBlocks; - if(slot == ut->slot) - break; - if(ut->blocks[slot].maxoff == 0) - continue; - bseq = ut->blocks[slot].seq; - if(seq == ~0UL) - seq = bseq; - else if(seq - bseq > MaxSeqMask) - break; - else - m |= 1 << (seq - bseq - 1); - } - *mask = m; - return seq; -} + UnthwBlock blocks[CompBlocks], *b, *eblocks; + uchar *s, *d, *dmax, *smax, lit; + ulong cmask, cseq, bseq, utbits, lithist; + int i, off, len, bits, slot, tslot, use, code, utnbits, overbits; -/* - * insert this block in it's correct sequence number order. - * replace the oldest block, which is always pointed to by ut->slot. - * the encoder doesn't use a history at wraparound, - * so don't worry about that case. - */ -static int -unthwackinsert(Unthwack *ut, int len, ulong seq) -{ - uchar *d; - int slot, tslot; + if(nsrc < 4 || nsrc > ThwMaxBlock) + return -1; + /* + * insert this block in it's correct sequence number order. + * replace the oldest block, which is always pointed to by ut->slot. + * the encoder doesn't use a history at wraparound, + * so don't worry about that case. + */ tslot = ut->slot; for(;;){ slot = tslot - 1; if(slot < 0) slot += DWinBlocks; - if(ut->blocks[slot].seq <= seq || ut->blocks[slot].maxoff == 0) + if(ut->blocks[slot].seq <= seq) break; d = ut->blocks[tslot].data; ut->blocks[tslot] = ut->blocks[slot]; ut->blocks[slot].data = d; tslot = slot; } - ut->blocks[tslot].seq = seq; - ut->blocks[tslot].maxoff = len; - - ut->slot++; - if(ut->slot >= DWinBlocks) - ut->slot = 0; - - ut->blocks[ut->slot].seq = ~0UL; - ut->blocks[ut->slot].maxoff = 0; - - return tslot; -} - -int -unthwack(Unthwack *ut, uchar *dst, int ndst, uchar *src, int nsrc, ulong seq) -{ - UnthwBlock blocks[CompBlocks], *b, *eblocks; - uchar *s, *d, *dmax, *smax, lit; - ulong cmask, cseq, bseq, utbits; - int i, off, len, bits, slot, use, code, utnbits, overbits, lithist; - - if(nsrc < 4 || nsrc > ThwMaxBlock) - return -1; - - slot = ut->slot; b = blocks; - *b = ut->blocks[slot]; + ut->blocks[tslot].seq = seq; + ut->blocks[tslot].maxoff = 0; + *b = ut->blocks[tslot]; d = b->data; dmax = d + ndst; @@ -148,6 +101,7 @@ unthwack(Unthwack *ut, uchar *dst, int ndst, uchar *src, int nsrc, ulong seq) cseq = seq - src[0]; cmask = src[1]; b++; + slot = tslot; while(cseq != seq && b < blocks + CompBlocks){ slot--; if(slot < 0) @@ -171,8 +125,8 @@ unthwack(Unthwack *ut, uchar *dst, int ndst, uchar *src, int nsrc, ulong seq) } eblocks = b; if(cseq != seq){ - print("blocks dropped: seq=%ld cseq=%ld %d cmask=%#lx %#x\n", seq, cseq, src[0], cmask, src[1]); - return -2; + print("blocks not in decompression window: cseq=%ld seq=%ld cmask=%lx nb=%ld\n", cseq, seq, cmask, eblocks - blocks); + return -1; } smax = src + nsrc; @@ -214,8 +168,6 @@ unthwack(Unthwack *ut, uchar *dst, int ndst, uchar *src, int nsrc, ulong seq) lit = (lit - 64) & 0xff; } } - if(d >= dmax) - return -1; *d++ = lit; lithist = (lithist << 1) | (lit < 32) | (lit > 127); blocks->maxoff++; @@ -290,8 +242,11 @@ unthwack(Unthwack *ut, uchar *dst, int ndst, uchar *src, int nsrc, ulong seq) len = d - blocks->data; memmove(dst, blocks->data, len); + ut->blocks[tslot].maxoff = len; - unthwackinsert(ut, len, seq); + ut->slot++; + if(ut->slot >= DWinBlocks) + ut->slot = 0; return len; } diff --git a/port/watchdog.c b/port/watchdog.c deleted file mode 100644 index 27327d64a6c528e7fefe4d5b5a4e3ad282f190c8..0000000000000000000000000000000000000000 --- a/port/watchdog.c +++ /dev/null @@ -1,136 +0,0 @@ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "../port/error.h" - -#define WDMAGIC 0xfaceface - -struct Watchdog -{ - Watchdog *next; - ulong magic; - ulong ticks; - void (*f)(int); - ulong arg; - uchar armed; -}; - -struct { - Lock; - Watchdog *wd; -} wdalloc; - -Watchdog* -wdCreate(void) -{ - Watchdog *wd; - - wd = mallocz(sizeof(Watchdog), 1); - if(wd == nil) - return nil; - wd->magic = WDMAGIC; - return wd; -} - -static char* -wdunlink(Watchdog *wd, ulong magic) -{ - char *rv; - Watchdog **l; - - rv = "not started"; - ilock(&wdalloc); - wd->magic = magic; - for(l = &wdalloc.wd; *l != nil; l = &(*l)->next) - if(*l == wd){ - *l = wd->next; - rv = nil; - break; - } - wd->armed = 0; - iunlock(&wdalloc); - return rv; -} - -char* -wdDelete(Watchdog *wd) -{ - if(wd->magic != WDMAGIC) - return "not a watchdog"; - - wdunlink(wd, ~WDMAGIC); - free(wd); - - return nil; -} - -char* -wdStart(Watchdog *wd, ulong ms, void (*f)(int), int arg) -{ - Watchdog **l; - - if(wd->magic != WDMAGIC) - return "not a watchdog"; - - /* unchain it in case it already is chained */ - if(wd->armed) - wdunlink(wd, WDMAGIC); - - /* chain the watchdogs in time order */ - ilock(&wdalloc); - wd->ticks = MS2TK(ms) + MACHP(0)->ticks; - wd->f = f; - wd->arg = arg; - wd->armed = 1; - for(l = &wdalloc.wd; *l != nil; l = &(*l)->next) - if(wd->ticks < (*l)->ticks) - break; - wd->next = *l; - *l = wd; - iunlock(&wdalloc); - - return nil; -} - -char* -wdCancel(Watchdog *wd) -{ - if(wd->magic != WDMAGIC) - return "not a watchdog"; - return wdunlink(wd, WDMAGIC); -} - -static void -wdclock(void) -{ - Watchdog *wd, **l; - - /* find the barking dogs, remoe from the chain */ - ilock(&wdalloc); - wd = wdalloc.wd; - for(l = &wdalloc.wd; *l != nil; l = &(*l)->next) - if(MACHP(0)->ticks - (*l)->ticks >= 0x10000000) - break; - if(l == &wdalloc.wd) - wd = nil; - else { - wdalloc.wd = *l; - *l = nil; - } - iunlock(&wdalloc); - - /* let them run */ - for(; wd != nil; wd = wd->next){ - wd->ticks = 0; - wd->armed = 0; - (*wd->f)(wd->arg); - } -} - -void -watchdoglink(void) -{ - addclock0link(wdclock); -}