diff options
Diffstat (limited to 'appl/cmd/auxi')
| -rw-r--r-- | appl/cmd/auxi/cpuslave.b | 79 | ||||
| -rw-r--r-- | appl/cmd/auxi/digest.b | 91 | ||||
| -rw-r--r-- | appl/cmd/auxi/fpgaload.b | 67 | ||||
| -rw-r--r-- | appl/cmd/auxi/mangaload.b | 362 | ||||
| -rw-r--r-- | appl/cmd/auxi/mkfile | 24 | ||||
| -rw-r--r-- | appl/cmd/auxi/pcmcia.b | 491 | ||||
| -rw-r--r-- | appl/cmd/auxi/rdbgsrv.b | 222 | ||||
| -rw-r--r-- | appl/cmd/auxi/rstyxd.b | 114 |
8 files changed, 1450 insertions, 0 deletions
diff --git a/appl/cmd/auxi/cpuslave.b b/appl/cmd/auxi/cpuslave.b new file mode 100644 index 00000000..66b409ac --- /dev/null +++ b/appl/cmd/auxi/cpuslave.b @@ -0,0 +1,79 @@ +implement CPUslave; + +include "sys.m"; + sys: Sys; +include "draw.m"; + draw: Draw; + Context, Display, Screen: import draw; +include "arg.m"; + +include "sh.m"; + +stderr: ref Sys->FD; + +CPUslave: module +{ + init: fn(ctxt: ref Context, args: list of string); +}; + +usage() +{ + sys->fprint(stderr, "usage: cpuslave [-s screenid] command args\n"); + raise "fail:usage"; +} + +init(nil: ref Context, args: list of string) +{ + sys = load Sys Sys->PATH; + stderr = sys->fildes(2); + draw = load Draw Draw->PATH; + + arg := load Arg Arg->PATH; + if (arg == nil) { + sys->fprint(stderr, "cpuslave: cannot load %s: %r\n", Arg->PATH); + raise "fail:bad module"; + } + screenid := -1; + arg->init(args); + while ((opt := arg->opt()) != 0) { + if (opt != 's' || (a := arg->arg()) == nil) + usage(); + screenid = int a; + } + args = arg->argv(); + if(args == nil) + usage(); + + file := hd args + ".dis"; + cmd := load Command file; + if(cmd == nil) + cmd = load Command "/dis/"+file; + if(cmd == nil){ + sys->fprint(stderr, "cpuslave: can't load %s: %r\n", hd args); + raise "fail:bad command"; + } + + ctxt: ref Context; + if (screenid >= 0) { + display := Display.allocate(nil); + if(display == nil){ + sys->fprint(stderr, "cpuslave: can't initialize display: %r\n"); + raise "fail:no display"; + } + + screen: ref Screen; + if(screenid >= 0){ + screen = display.publicscreen(screenid); + if(screen == nil){ + sys->fprint(stderr, "cpuslave: cannot access screen %d: %r\n", screenid); + raise "fail:bad screen"; + } + } + + ctxt = ref Context; + ctxt.screen = screen; + ctxt.display = display; + } + + spawn cmd->init(ctxt, args); +} diff --git a/appl/cmd/auxi/digest.b b/appl/cmd/auxi/digest.b new file mode 100644 index 00000000..108de205 --- /dev/null +++ b/appl/cmd/auxi/digest.b @@ -0,0 +1,91 @@ +implement Digest; + +# +# read a classifier example file and write its digest +# + +include "sys.m"; + sys: Sys; + +include "draw.m"; + +include "bufio.m"; + bufio: Bufio; + Iobuf: import bufio; + +include "strokes.m"; + strokes: Strokes; + Classifier, Penpoint, Stroke: import strokes; + readstrokes: Readstrokes; + writestrokes: Writestrokes; + +include "arg.m"; + +Digest: module +{ + init: fn(nil: ref Draw->Context, nil: list of string); +}; + +usage() +{ + sys->fprint(sys->fildes(2), "Usage: digest [file.cl ...]\n"); + raise "fail:usage"; +} + +init(nil: ref Draw->Context, args: list of string) +{ + sys = load Sys Sys->PATH; + bufio = load Bufio Bufio->PATH; + strokes = load Strokes Strokes->PATH; + if(strokes == nil) + nomod(Strokes->PATH); + strokes->init(); + readstrokes = load Readstrokes Readstrokes->PATH; + if(readstrokes == nil) + nomod(Readstrokes->PATH); + readstrokes->init(strokes); + writestrokes = load Writestrokes Writestrokes->PATH; + if(writestrokes == nil) + nomod(Writestrokes->PATH); + writestrokes->init(strokes); + + arg := load Arg Arg->PATH; + if(arg == nil) + nomod(Arg->PATH); + arg->init(args); + while((opt := arg->opt()) != 0) + case opt { + * => + usage(); + } + args = arg->argv(); + arg = nil; + + for(; args != nil; args = tl args){ + ofile := file := hd args; + n := len file; + if(n >= 3 && ofile[n-3:] == ".cl") + ofile = ofile[0:n-3]; + ofile += ".clx"; + (err, rec) := readstrokes->read_classifier(hd args, 1, 0); + if(err != nil) + error(sys->sprint("error reading classifier from %s: %s", file, err)); + fd := sys->create(ofile, Sys->OWRITE, 8r666); + if(fd == nil) + error(sys->sprint("can't create %s: %r", file)); + err = writestrokes->write_digest(fd, rec.cnames, rec.dompts); + if(err != nil) + error(sys->sprint("error writing digest to %s: %s", file, err)); + } +} + +nomod(s: string) +{ + error(sys->sprint("can't load %s: %r", s)); +} + +error(s: string) +{ + sys->fprint(sys->fildes(2), "digest: %s\n", s); + raise "fail:error"; +} diff --git a/appl/cmd/auxi/fpgaload.b b/appl/cmd/auxi/fpgaload.b new file mode 100644 index 00000000..5c37b80b --- /dev/null +++ b/appl/cmd/auxi/fpgaload.b @@ -0,0 +1,67 @@ +implement Fpgaload; + +include"sys.m"; + sys: Sys; + +include "draw.m"; + +include "arg.m"; + +Fpgaload: module +{ + init: fn(nil: ref Draw->Context, nil: list of string); +}; + +init(nil: ref Draw->Context, args: list of string) +{ + sys = load Sys Sys->PATH; + arg := load Arg Arg->PATH; + if(arg == nil) + error(sys->sprint("can't load %s: %r", Arg->PATH)); + arg->init(args); + arg->setusage("fpgaload [-c clock] file.rbf"); + clock := -1; + while((c := arg->opt()) != 0) + case c { + 'c' => + clock = int arg->earg(); + if(clock <= 0) + error("invalid clock value"); + * => + arg->usage(); + } + args = arg->argv(); + if(args == nil) + arg->usage(); + arg = nil; + + fd := sys->open(hd args, Sys->OREAD); + if(fd == nil) + error(sys->sprint("can't open %s: %r", hd args)); + ofd := sys->open("#G/fpgaprog", Sys->OWRITE); + if(ofd == nil) + error(sys->sprint("can't open %s: %r", "#G/fpgaprog")); + a := array[128*1024] of byte; + while((n := sys->read(fd, a, len a)) > 0) + if(sys->write(ofd, a, n) != n) + error(sys->sprint("write error: %r")); + if(n < 0) + error(sys->sprint("read error: %r")); + if(clock >= 0) + setclock(clock); +} + +setclock(n: int) +{ + fd := sys->open("#G/fpgactl", Sys->OWRITE); + if(fd == nil) + error(sys->sprint("can't open %s: %r", "#G/fpgactl")); + if(sys->fprint(fd, "bclk %d", n) < 0) + error(sys->sprint("can't set clock to %d: %r", n)); +} + +error(s: string) +{ + sys->fprint(sys->fildes(2), "fpgaload: %s\n", s); + raise "fail:error"; +} diff --git a/appl/cmd/auxi/mangaload.b b/appl/cmd/auxi/mangaload.b new file mode 100644 index 00000000..380dd22e --- /dev/null +++ b/appl/cmd/auxi/mangaload.b @@ -0,0 +1,362 @@ +implement Mangaload; + +# to do: +# - set arp entry based on /lib/ndb if necessary + +include "sys.m"; + sys: Sys; + +include "draw.m"; + +include "ip.m"; + ip: IP; + IPaddr: import ip; + +include "timers.m"; + timers: Timers; + Timer: import timers; + +include "arg.m"; + +Mangaload: module +{ + init: fn(nil: ref Draw->Context, nil: list of string); +}; + +# manga parameters +FlashBlocksize: con 16r10000; +FlashSize: con 16r400000; # 4meg for now +FlashUserArea: con 16r3C0000; + +# magic values +FooterOffset: con 16rFFEC; +FooterSig: con 16rA0FFFF9F; # ARM flash library +FileInfosize: con 64; +FileNamesize: con FileInfosize - 3*4; # x, y, z +Packetdatasize: con 1500-28; # ether data less IP + ICMP header +RequestTimeout: con 500; +Probecount: con 10; # query unit every so many packets + +# manga uses extended TFTP ops in ICMP InfoRequest packets +Tftp_Req: con 0; +Tftp_Read: con 1; +Tftp_Write: con 2; +Tftp_Data: con 3; +Tftp_Ack: con 4; +Tftp_Error: con 5; +Tftp_Last: con 6; + +Icmp: adt +{ + ttl: int; # time to live + src: IPaddr; + dst: IPaddr; + ptype: int; + code: int; + id: int; + seq: int; + data: array of byte; + munged: int; # packet received but corrupt + + unpack: fn(b: array of byte): ref Icmp; +}; + +# ICMP packet types +EchoReply: con 0; +Unreachable: con 3; +SrcQuench: con 4; +EchoRequest: con 8; +TimeExceed: con 11; +Timestamp: con 13; +TimestampReply: con 14; +InfoRequest: con 15; +InfoReply: con 16; + +Nmsg: con 32; +Interval: con 1000; # ms + +debug := 0; +flashblock := 1; # never 0, that's the boot firmware +maxfilesize := 8*FlashBlocksize; +flashlim := FlashSize/FlashBlocksize; +loadinitrd := 0; +maxlen := 512*1024; +mypid := 0; +Datablocksize: con 4096; + +init(nil: ref Draw->Context, args: list of string) +{ + sys = load Sys Sys->PATH; + timers = load Timers Timers->PATH; + ip = load IP IP->PATH; + ip->init(); + + + arg := load Arg Arg->PATH; + arg->init(args); + arg->setusage("mangaload [-48dr] destination file"); + while((o := arg->opt()) != 0) + case o { + '4' => + flashlim = 4*1024*1024/FlashBlocksize; + '8' => + flashlim = 8*1024*1024/FlashBlocksize; + 'r' => + loadinitrd = 1; + flashblock = 9; + if(flashlim > 4*1024*1024/FlashBlocksize) + maxfilesize = 113*FlashBlocksize; + else + maxfilesize = 50*FlashBlocksize; + 'd' => + debug++; + } + args = arg->argv(); + if(len args != 2) + arg->usage(); + arg = nil; + + sys->pctl(Sys->NEWPGRP|Sys->FORKFD, nil); + + filename := hd tl args; + fd := sys->open(filename, Sys->OREAD); + if(fd == nil){ + sys->fprint(sys->fildes(2), "mangaload: can't open %s: %r\n", filename); + raise "fail:open"; + } + (ok, d) := sys->fstat(fd); + if(ok < 0){ + sys->fprint(sys->fildes(2), "mangaload: can't stat %s: %r\n", filename); + raise "fail:stat"; + } + if(d.length > big maxfilesize){ + sys->fprint(sys->fildes(2), "mangaload: file %s too long (must not exceed %d bytes)\n", + filename, maxfilesize); + raise "fail:size"; + } + filesize := int d.length; + + port := sys->sprint("%d", 16r8695); + addr := netmkaddr(hd args, "icmp", port); + (rok, c) := sys->dial(addr, port); + if(rok < 0){ + sys->fprint(sys->fildes(2), "mangaload: can't dial %s: %r\n", addr); + raise "fail:dial"; + } + + tpid := timers->init(20); + + pids := chan of int; + replies := chan [2] of ref Icmp; + spawn reader(c.dfd, replies, pids); + rpid := <-pids; + + flashoffset := flashblock * FlashBlocksize; + + # file name first + bname := array of byte filename; + l := len bname; + buf := array[Packetdatasize] of byte; + ip->put4(buf, 0, filesize); + ip->put4(buf, 4, l); + buf[8:] = bname; + l += 2*4; + buf[l++] = byte 0; + ip->put4(buf, l, flashoffset); + l += 4; + { + if(send(c.dfd, buf[0:l], Tftp_Write, 0) < 0) + senderr(); + (op, iseq, data) := recv(replies, 400); + sys->print("initial reply: %d %d\n", op, iseq); + if(op != Tftp_Ack){ + why := "no response"; + if(op == Tftp_Error) + why = "manga cannot receive file"; + sys->fprint(sys->fildes(2), "mangaload: %s\n", why); + raise "fail:error"; + } + sys->print("sending %s size %d at address %d (0x%x)\n", filename, filesize, flashoffset, flashoffset); + seq := 1; + nsent := 0; + last := 0; + while((n := sys->read(fd, buf, len buf)) >= 0 && !last){ + last = n != len buf; + nretry := 0; + Retry: + for(;;){ + if(++nsent%10 == 0){ # probe + o = Tftp_Req; + send(c.dfd, array[0] of byte, Tftp_Req, seq); + (op, iseq, data) = recv(replies, 500); + if(debug || op != Tftp_Ack) + sys->print("ack reply: %d %d\n", op, iseq); + if(op == Tftp_Last || op == Tftp_Error){ + if(op == Tftp_Last) + sys->print("timed out\n"); + else + sys->print("error reply\n"); + raise "disaster"; + } + if(debug) + sys->print("ok\n"); + continue Retry; + } + send(c.dfd, buf[0:n], Tftp_Data, seq); + (op, iseq, data) = recv(replies, 40); + case op { + Tftp_Error => + sys->fprint(sys->fildes(2), "mangaload: manga refused data\n"); + raise "disaster"; + Tftp_Ack => + if(seq == iseq){ + seq++; + break Retry; + } + sys->print("sequence error: rcvd %d expected %d\n", iseq, seq); + if(iseq > seq){ + sys->print("unrecoverable sequence error\n"); + send(c.dfd, array[0] of byte, Tftp_Data, ++seq); # stop manga + raise "disaster"; + } + # resend + sys->seek(fd, -big ((seq-iseq)*len buf), 1); + seq = iseq; + Tftp_Last => + seq++; + break Retry; # timeout ok: manga doesn't usually reply unless packet lost + } + } + } + }exception{ + * => + ; + } + kill(rpid); + kill(tpid); + sys->print("ok?\n"); +} + +kill(pid: int) +{ + if(pid) + sys->fprint(sys->open("#p/"+string pid+"/ctl", Sys->OWRITE), "kill"); +} + +senderr() +{ + sys->fprint(sys->fildes(2), "mangaload: icmp write failed: %r\n"); + raise "disaster"; +} + +send(fd: ref Sys->FD, data: array of byte, op: int, seq: int): int +{ + buf := array[64*1024+512] of {* => byte 0}; + buf[Odata:] = data; + ip->put2(buf, Oseq, seq); + buf[Otype] = byte InfoRequest; + buf[Ocode] = byte op; + if(sys->write(fd, buf, Odata+len data) < Odata+len data) + return -1; + if(debug) + sys->print("sent op=%d seq=%d ld=%d\n", op, seq, len data); + return 0; +} + +flush(input: chan of ref Icmp) +{ + for(;;)alt{ + <-input => + ; + * => + return; + } +} + +recv(input: chan of ref Icmp, msec: int): (int, int, array of byte) +{ + t := Timer.start(msec); + alt{ + <-t.timeout => + return (Tftp_Last, 0, nil); + ic := <-input => + t.stop(); + if(ic.ptype == InfoReply) + return (ic.code, ic.seq, ic.data); + return (Tftp_Last, 0, nil); + } +} + +reader(fd: ref Sys->FD, out: chan of ref Icmp, pid: chan of int) +{ + pid <-= sys->pctl(0, nil); + for(;;){ + buf := array[64*1024+512] of byte; + n := sys->read(fd, buf, len buf); + if(n <= 0){ + if(n == 0) + sys->werrstr("unexpected eof"); + break; + } + ic := Icmp.unpack(buf[0:n]); + if(ic != nil){ + if(debug) + sys->print("recv type=%d op=%d seq=%d id=%d\n", ic.ptype, ic.code, ic.seq, ic.id); + out <-= ic; + }else + sys->fprint(sys->fildes(2), "mangaload: corrupt icmp packet rcvd\n"); + } + sys->print("read: %r\n"); + out <-= nil; +} + +# IP and ICMP packet header +Ovihl: con 0; +Otos: con 1; +Olength: con 2; +Oid: con Olength+2; +Ofrag: con Oid+2; +Ottl: con Ofrag+2; +Oproto: con Ottl+1; +Oipcksum: con Oproto+1; +Osrc: con Oipcksum+2; +Odst: con Osrc+4; +Otype: con Odst+4; +Ocode: con Otype+1; +Ocksum: con Ocode+1; +Oicmpid: con Ocksum+2; +Oseq: con Oicmpid+2; +Odata: con Oseq+2; + +Icmp.unpack(b: array of byte): ref Icmp +{ + if(len b < Odata) + return nil; + ic := ref Icmp; + ic.ttl = int b[Ottl]; + ic.src = IPaddr.newv4(b[Osrc:]); + ic.dst = IPaddr.newv4(b[Odst:]); + ic.ptype = int b[Otype]; + ic.code = int b[Ocode]; + ic.seq = ip->get2(b, Oseq); + ic.id = ip->get2(b, Oicmpid); + ic.munged = 0; + if(len b > Odata) + ic.data = b[Odata:]; + return ic; +} + +netmkaddr(addr, net, svc: string): string +{ + if(net == nil) + net = "net"; + (n, nil) := sys->tokenize(addr, "!"); + if(n <= 1){ + if(svc== nil) + return sys->sprint("%s!%s", net, addr); + return sys->sprint("%s!%s!%s", net, addr, svc); + } + if(svc == nil || n > 2) + return addr; + return sys->sprint("%s!%s", addr, svc); +} diff --git a/appl/cmd/auxi/mkfile b/appl/cmd/auxi/mkfile new file mode 100644 index 00000000..6d8dfc88 --- /dev/null +++ b/appl/cmd/auxi/mkfile @@ -0,0 +1,24 @@ +<../../../mkconfig + +TARG=\ + cpuslave.dis\ + digest.dis\ + fpgaload.dis\ + mangaload.dis\ + pcmcia.dis\ + rdbgsrv.dis\ + rstyxd.dis\ + +SYSMODULES=\ + arg.m\ + bufio.m\ + draw.m\ + sh.m\ + string.m\ + strokes.m\ + styx.m\ + sys.m\ + +DISBIN=$ROOT/dis/auxi + +<$ROOT/mkfiles/mkdis diff --git a/appl/cmd/auxi/pcmcia.b b/appl/cmd/auxi/pcmcia.b new file mode 100644 index 00000000..d5d998b0 --- /dev/null +++ b/appl/cmd/auxi/pcmcia.b @@ -0,0 +1,491 @@ +implement Pcmcia; + +# +# Copyright © 1995-2001 Lucent Technologies Inc. All rights reserved. +# Revisions Copyright © 2001-2003 Vita Nuova Holdings Limited. All rights reserved. +# + +include "sys.m"; + sys: Sys; + print, fprint: import sys; + +include "draw.m"; + +Pcmcia: module +{ + init: fn(nil: ref Draw->Context, nil: list of string); +}; + +End: con 16rFF; + +fd: ref Sys->FD; +stderr: ref Sys->FD; +pos := 0; + +hex := 0; + +init(nil: ref Draw->Context, args: list of string) +{ + sys = load Sys Sys->PATH; + stderr = sys->fildes(2); + if(args != nil) + args = tl args; + if(args != nil && hd args == "-x"){ + hex = 1; + args = tl args; + } + + file := "#y/pcm0attr"; + if(args != nil) + file = hd args; + + fd = sys->open(file, Sys->OREAD); + if(fd == nil) + fatal(sys->sprint("can't open %s: %r", file)); + + for(next := 0; next >= 0;) + next = dtuple(next); +} + +fatal(s: string) +{ + fprint(stderr, "pcmcia: %s\n", s); + raise "fail:error"; +} + +readc(): int +{ + x := array[1] of byte; + sys->seek(fd, big(2*pos), 0); + pos++; + rv := sys->read(fd, x, 1); + if(rv != 1){ + if(rv < 0) + sys->print("readc err: %r\n"); + return -1; + } + v := int x[0]; + if(hex) + print("%2.2ux ", v); + return v; +} + +dtuple(next: int): int +{ + pos = next; + if((ttype := readc()) < 0) + return -1; + if(ttype == End) + return -1; + if((link := readc()) < 0) + return -1; + case ttype { + * => print("unknown tuple type #%2.2ux\n", ttype); + 16r01 => tdevice(ttype, link); + 16r15 => tvers1(ttype, link); + 16r17 => tdevice(ttype, link); + 16r1A => tcfig(ttype, link); + 16r1B => tentry(ttype, link); + } + if(link == End) + next = -1; + else + next = next+2+link; + return next; +} + +speedtab := array[16] of { +0 => 0, +1 => 250, +2 => 200, +3 => 150, +4 => 100, +}; + +mantissa := array[16] of { +1 => 10, +2 => 12, +3 => 13, +4 => 15, +5 => 20, +6 => 25, +7 => 30, +8 => 35, +9 => 40, +10=> 45, +11=> 50, +12=> 55, +13=> 60, +14=> 70, +15=> 80, +}; + +exponent := array[] of { + 1, + 10, + 100, + 1000, + 10000, + 100000, + 1000000, + 10000000, +}; + +typetab := array [256] of { +1=> "Masked ROM", +2=> "PROM", +3=> "EPROM", +4=> "EEPROM", +5=> "FLASH", +6=> "SRAM", +7=> "DRAM", +16rD=> "IO+MEM", +* => "Unknown", +}; + +getlong(size: int): int +{ + x := 0; + for(i := 0; i < size; i++){ + if((c := readc()) < 0) + break; + x |= c<<(i*8); + } + return x; +} + +tdevice(dtype: int, tlen: int) +{ + while(tlen > 0){ + if((id := readc()) < 0) + return; + tlen--; + if(id == End) + return; + + speed := id & 16r7; + ns := 0; + if(speed == 16r7){ + if((speed = readc()) < 0) + return; + tlen--; + if(speed & 16r80){ + if((aespeed := readc()) < 0) + return; + ns = 0; + } else + ns = (mantissa[(speed>>3)&16rF]*exponent[speed&7])/10; + } else + ns = speedtab[speed]; + + ttype := id>>4; + if(ttype == 16rE){ + if((ttype = readc()) < 0) + return; + tlen--; + } + tname := typetab[ttype]; + if(tname == nil) + tname = "unknown"; + + if((size := readc()) < 0) + return; + tlen--; + bytes := ((size>>3)+1) * 512 * (1<<(2*(size&16r7))); + + ttname := "attr device"; + if(dtype == 1) + ttname = "device"; + print("%s %d bytes of %dns %s\n", ttname, bytes, ns, tname); + } +} + +tvers1(nil: int, tlen: int) +{ + if((major := readc()) < 0) + return; + tlen--; + if((minor := readc()) < 0) + return; + tlen--; + print("version %d.%d\n", major, minor); + while(tlen > 0){ + s := ""; + while(tlen > 0){ + if((c := readc()) < 0) + return; + tlen--; + if(c == 0) + break; + if(c == End){ + if(s != "") + print("\t%s<missing null>\n", s); + return; + } + s[len s] = c; + } + print("\t%s\n", s); + } +} + +tcfig(nil: int, nil: int) +{ + if((size := readc()) < 0) + return; + rasize := (size&16r3) + 1; + rmsize := ((size>>2)&16rf) + 1; + if((last := readc()) < 0) + return; + caddr := getlong(rasize); + cregs := getlong(rmsize); + + print("configuration registers at"); + for(i := 0; i < 16; i++) + if((1<<i) & cregs) + print(" (%d) #%ux", i, caddr + i*2); + print("\n"); +} + +intrname := array[16] of { +0 => "memory", +1 => "I/O", +4 => "Custom 0", +5 => "Custom 1", +6 => "Custom 2", +7 => "Custom 3", +* => "unknown" +}; + +vexp := array[8] of { + 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000 +}; +vmant := array[16] of { + 10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80, 90, +}; + +volt(name: string) +{ + if((c := readc()) < 0) + return; + exp := vexp[c&16r7]; + microv := vmant[(c>>3)&16rf]*exp; + while(c & 16r80){ + if((c = readc()) < 0) + return; + case c { + 16r7d => + break; # high impedence when sleeping + 16r7e or 16r7f => + microv = 0; # no connection + * => + exp /= 10; + microv += exp*(c&16r7f); + } + } + print(" V%s %duV", name, microv); +} + +amps(name: string) +{ + if((c := readc()) < 0) + return; + amps := vexp[c&16r7]*vmant[(c>>3)&16rf]; + while(c & 16r80){ + if((c = readc()) < 0) + return; + if(c == 16r7d || c == 16r7e || c == 16r7f) + amps = 0; + } + if(amps >= 1000000) + print(" I%s %dmA", name, amps/100000); + else if(amps >= 1000) + print(" I%s %duA", name, amps/100); + else + print(" I%s %dnA", name, amps*10); +} + +power(name: string) +{ + print("\t%s: ", name); + if((feature := readc()) < 0) + return; + if(feature & 1) + volt("nominal"); + if(feature & 2) + volt("min"); + if(feature & 4) + volt("max"); + if(feature & 8) + amps("static"); + if(feature & 16r10) + amps("avg"); + if(feature & 16r20) + amps("peak"); + if(feature & 16r40) + amps("powerdown"); + print("\n"); +} + +ttiming(name: string, scale: int) +{ + if((unscaled := readc()) < 0) + return; + scaled := (mantissa[(unscaled>>3)&16rf]*exponent[unscaled&7])/10; + scaled = scaled * vexp[scale]; + print("\t%s %dns\n", name, scaled); +} + +timing() +{ + if((c := readc()) < 0) + return; + i := c&16r3; + if(i != 3) + ttiming("max wait", i); + i = (c>>2)&16r7; + if(i != 7) + ttiming("max ready/busy wait", i); + i = (c>>5)&16r7; + if(i != 7) + ttiming("reserved wait", i); +} + +range(asize: int, lsize: int) +{ + address := getlong(asize); + alen := getlong(lsize); + print("\t\t%ux - %ux\n", address, address+alen); +} + +ioaccess := array[] of { + 0 => " no access", + 1 => " 8bit access only", + 2 => " 8bit or 16bit access", + 3 => " selectable 8bit or 8&16bit access", +}; + +iospace(c: int): int +{ + print("\tIO space %d address lines%s\n", c&16r1f, ioaccess[(c>>5)&3]); + if((c & 16r80) == 0) + return -1; + + if((c = readc()) < 0) + return -1; + + for(i := (c&16rf)+1; i; i--) + range((c>>4)&16r3, (c>>6)&16r3); + return 0; +} + +iospaces() +{ + if((c := readc()) < 0) + return; + iospace(c); +} + +irq() +{ + if((c := readc()) < 0) + return; + irqs: int; + if(c & 16r10){ + if((irq1 := readc()) < 0) + return; + if((irq2 := readc()) < 0) + return; + irqs = irq1|(irq2<<8); + } else + irqs = 1<<(c&16rf); + level := ""; + if(c & 16r20) + level = " level"; + pulse := ""; + if(c & 16r40) + pulse = " pulse"; + shared := ""; + if(c & 16r80) + shared = " shared"; + print("\tinterrupts%s%s%s", level, pulse, shared); + for(i := 0; i < 16; i++) + if(irqs & (1<<i)) + print(", %d", i); + print("\n"); +} + +memspace(asize: int, lsize: int, host: int) +{ + alen := getlong(lsize)*256; + address := getlong(asize)*256; + if(host){ + haddress := getlong(asize)*256; + print("\tmemory address range #%ux - #%ux hostaddr #%ux\n", + address, address+alen, haddress); + } else + print("\tmemory address range #%ux - #%ux\n", address, address+alen); +} + +misc() +{ +} + +tentry(nil: int, nil: int) +{ + if((c := readc()) < 0) + return; + def := ""; + if(c & 16r40) + def = " (default)"; + print("configuration %d%s\n", c&16r3f, def); + if(c & 16r80){ + if((i := readc()) < 0) + return; + tname := intrname[i & 16rf]; + if(tname == "") + tname = sys->sprint("type %d", i & 16rf); + attrib := ""; + if(i & 16r10) + attrib += " Battery status active"; + if(i & 16r20) + attrib += " Write Protect active"; + if(i & 16r40) + attrib += " Ready/Busy active"; + if(i & 16r80) + attrib += " Memory Wait required"; + print("\t%s device, %s\n", tname, attrib); + } + if((feature := readc()) < 0) + return; + case feature&16r3 { + 1 => + power("Vcc"); + 2 => + power("Vcc"); + power("Vpp"); + 3 => + power("Vcc"); + power("Vpp1"); + power("Vpp2"); + } + if(feature&16r4) + timing(); + if(feature&16r8) + iospaces(); + if(feature&16r10) + irq(); + case (feature>>5)&16r3 { + 1 => + memspace(0, 2, 0); + 2 => + memspace(2, 2, 0); + 3 => + if((c = readc()) < 0) + return; + for(i := 0; i <= (c&16r7); i++) + memspace((c>>5)&16r3, (c>>3)&16r3, c&16r80); + break; + } + if(feature&16r80) + misc(); +} diff --git a/appl/cmd/auxi/rdbgsrv.b b/appl/cmd/auxi/rdbgsrv.b new file mode 100644 index 00000000..2a958eee --- /dev/null +++ b/appl/cmd/auxi/rdbgsrv.b @@ -0,0 +1,222 @@ +implement RDbgSrv; + +include "sys.m"; + sys: Sys; +include "draw.m"; + +include "styx.m"; + styx: Styx; + Rmsg, Tmsg: import styx; + +include "arg.m"; + arg: Arg; + +RDbgSrv: module +{ + init: fn(nil: ref Draw->Context, argv: list of string); +}; + +debug:= 0; +dev:= "/dev/eia0"; +speed:= 38400; +progname: string; +rpid := 0; +wpid := 0; + +usage() +{ + sys->fprint(stderr(), "Usage: rdbgsrv [-d n] [-s speed] [-f dev] mountpoint\n"); + raise "fail: usage"; +} + +init(nil: ref Draw->Context, av: list of string) +{ + sys = load Sys Sys->PATH; + if(sys == nil) + return; + styx = load Styx Styx->PATH; + if(styx == nil){ + sys->fprint(stderr(), "rdbgsrv: can't load %s; %r\n", Styx->PATH); + raise "fail:load"; + } + arg = load Arg Arg->PATH; + if(arg == nil){ + sys->fprint(stderr(), "rdbgsrv: can't load %s: %r\n", Arg->PATH); + raise "fail:load"; + } + + arg->init(av); + progname = arg->progname(); + while(o := arg->opt()) + case o { + 'd' => + d := arg->arg(); + if(d == nil) + usage(); + debug = int d; + 's' => + s := arg->arg(); + if(s == nil) + usage(); + speed = int s; + 'f' => + s := arg->arg(); + if(s == nil) + usage(); + dev = s; + 'h' => + usage(); + } + + mtpt := arg->arg(); + if(mtpt == nil) + usage(); + + ctl := dev + "ctl"; + cfd := sys->open(ctl, Sys->OWRITE); + if(cfd == nil){ + sys->fprint(stderr(), "%s: can't open %s: %r\n", progname, ctl); + raise "fail: open eia\n"; + } + + sys->fprint(cfd, "b%d", speed); + sys->fprint(cfd, "l8"); + sys->fprint(cfd, "pn"); + sys->fprint(cfd, "s1"); + + (rfd, wfd) := start(dev); + if(rfd == nil){ + sys->fprint(stderr(), "%s: failed to start protocol\n", progname); + raise "fail:proto start"; + } + + fds := array[2] of ref Sys->FD; + + if(sys->pipe(fds) == -1){ + sys->fprint(stderr(), "%s: pipe: %r\n", progname); + raise "fail:no pipe"; + } + + if(debug) + sys->fprint(stderr(), "%s: starting server\n", progname); + + rc := chan of int; + spawn copymsg(fds[1], wfd, "->", rc); + rpid = <-rc; + spawn copymsg(rfd, fds[1], "<-", rc); + wpid = <-rc; + + if(sys->mount(fds[0], nil, mtpt, Sys->MREPL, nil) == -1) { + fds[1] = nil; + sys->fprint(stderr(), "%s: can't mount on %s: %r\n", progname, mtpt); + quit("mount"); + } +} + +stderr(): ref Sys->FD +{ + return sys->fildes(2); +} + +killpid(pid: int) +{ + fd := sys->open("#p/"+string pid+"/ctl", sys->OWRITE); + if(fd != nil) + sys->fprint(fd, "kill"); +} + +quit(err: string) +{ + killpid(rpid); + killpid(wpid); + if(err != nil) + raise "fail:"+err; + exit; +} + +start(name:string): (ref Sys->FD, ref Sys->FD) +{ + rfd := sys->open(name, Sys->OREAD); + wfd := sys->open(name, Sys->OWRITE); + if(rfd == nil || wfd == nil) + return (nil, nil); + if(sys->fprint(wfd, "go") < 0) + return (nil, nil); + c := array[1] of byte; + state := 0; + for(;;) { + if(sys->read(rfd, c, 1) != 1) + return (nil, nil); + if(state == 0 && c[0] == byte 'o') + state = 1; + else if(state == 1 && c[0] == byte 'k') + break; + else + state = 0; + } + return (rfd, wfd); +} + +copymsg(f: ref Sys->FD, t: ref Sys->FD, dir: string, pidc: chan of int) +{ + pidc <-= sys->pctl(0, nil); + + { + for(;;) { + (msg, err) := styx->readmsg(f, 0); + if(msg == nil){ + sys->fprint(stderr(), "%s: %s: read error: %s\n", progname, dir, err); + quit("error"); + } + if(debug &1) + trace(dir, msg); + if(debug & 2) + dump(dir, msg, len msg); + if(sys->write(t, msg, len msg) != len msg){ + sys->fprint(stderr(), "%s: %s: write error: %r\n", progname, dir); + quit("error"); + } + } + }exception e{ + "*" => + sys->print("%s: %s: %s: exiting\n", progname, dir, e); + quit("exception"); + } +} + +trace(sourcept: string, op: array of byte ) +{ + if(styx->istmsg(op)){ + (nil, m) := Tmsg.unpack(op); + if(m != nil) + sys->print("%s: %s\n", sourcept, m.text()); + else + sys->print("%s: unknown\n", sourcept); + }else{ + (nil, m) := Rmsg.unpack(op); + if(m != nil) + sys->print("%s: %s\n", sourcept, m.text()); + else + sys->print("%s: unknown\n", sourcept); + } +} + +dump(msg: string, buf: array of byte, n: int) +{ + sys->print("%s: [%d bytes]: ", msg, n); + s := ""; + for(i:=0;i<n;i++) { + if((i % 20) == 0) { + sys->print(" %s\n", s); + s = ""; + } + sys->print("%2.2x ", int buf[i]); + if(int buf[i] >= 32 && int buf[i] < 127) + s[len s] = int buf[i]; + else + s += "."; + } + for(i %= 20; i < 20; i++) + sys->print(" "); + sys->print(" %s\n\n", s); +} diff --git a/appl/cmd/auxi/rstyxd.b b/appl/cmd/auxi/rstyxd.b new file mode 100644 index 00000000..2f853ad5 --- /dev/null +++ b/appl/cmd/auxi/rstyxd.b @@ -0,0 +1,114 @@ +implement Rstyxd; + +include "sys.m"; +include "draw.m"; +include "sh.m"; +include "string.m"; + +sys: Sys; +str: String; +stderr: ref Sys->FD; + +Rstyxd: module +{ + init: fn(ctxt: ref Draw->Context, argv: list of string); +}; + +# +# argv is a list of Inferno supported algorithms from Security->Auth +# +init(nil: ref Draw->Context, nil: list of string) +{ + sys = load Sys Sys->PATH; + str = load String String->PATH; + if (str == nil) + badmod(String->PATH); + + fd := sys->fildes(0); + stderr = sys->fildes(2); + sys->pctl(sys->FORKFD, fd.fd :: nil); + + args := readargs(fd); + if(args == nil) + err(sys->sprint("error reading arguments: %r")); + + cmd := hd args; + s := ""; + for (a := args; a != nil; a = tl a) + s += hd a + " "; + sys->fprint(stderr, "rstyxd: cmd: %s\n", s); + s = nil; + file: string; + if(cmd == "sh") + file = "/dis/sh.dis"; + else + file = cmd + ".dis"; + mod := load Command file; + if(mod == nil){ + mod = load Command "/dis/"+file; + if(mod == nil) + badmod("/dis/"+file); + } + + sys->pctl(Sys->FORKNS|Sys->FORKENV, nil); + + if(sys->mount(fd, nil, "/n/client", Sys->MREPL, "") < 0) + err(sys->sprint("cannot mount connection on /n/client: %r")); + + if(sys->bind("/n/client/dev", "/dev", Sys->MBEFORE) < 0) + err(sys->sprint("cannot bind /n/client/dev to /dev: %r")); + + fd = sys->open("/dev/cons", sys->OREAD); + sys->dup(fd.fd, 0); + fd = sys->open("/dev/cons", sys->OWRITE); + sys->dup(fd.fd, 1); + sys->dup(fd.fd, 2); + fd = nil; + + mod->init(nil, args); +} + +readargs(fd: ref Sys->FD): list of string +{ + buf := array[1024] of byte; + c := array[1] of byte; + for(i:=0; ; i++){ + if(i>=len buf || sys->read(fd, c, 1)!=1) + return nil; + buf[i] = c[0]; + if(c[0] == byte '\n') + break; + } + nb := int string buf[0:i]; + if(nb <= 0) + return nil; + args := readn(fd, nb); + if (args == nil) + return nil; + return str->unquoted(string args[0:nb]); +} + +readn(fd: ref Sys->FD, nb: int): array of byte +{ + buf:= array[nb] of byte; + for(n:=0; n<nb;){ + m := sys->read(fd, buf[n:], nb-n); + if(m <= 0) + return nil; + n += m; + } + return buf; +} + + +err(s: string) +{ + sys->fprint(stderr, "rstyxd: %s\n", s); + raise "fail:error"; +} + +badmod(s: string) +{ + sys->fprint(stderr, "rstyxd: can't load %s: %r\n", s); + raise "fail:load"; +} |
