diff options
| author | Charles.Forsyth <devnull@localhost> | 2006-12-22 17:07:39 +0000 |
|---|---|---|
| committer | Charles.Forsyth <devnull@localhost> | 2006-12-22 17:07:39 +0000 |
| commit | 37da2899f40661e3e9631e497da8dc59b971cbd0 (patch) | |
| tree | cbc6d4680e347d906f5fa7fca73214418741df72 /appl/cmd/mpc/qconfig.b | |
| parent | 54bc8ff236ac10b3eaa928fd6bcfc0cdb2ba46ae (diff) | |
20060303a
Diffstat (limited to 'appl/cmd/mpc/qconfig.b')
| -rw-r--r-- | appl/cmd/mpc/qconfig.b | 193 |
1 files changed, 193 insertions, 0 deletions
diff --git a/appl/cmd/mpc/qconfig.b b/appl/cmd/mpc/qconfig.b new file mode 100644 index 00000000..dbff19b7 --- /dev/null +++ b/appl/cmd/mpc/qconfig.b @@ -0,0 +1,193 @@ +implement Configflash; + +# +# this isn't a proper config program: it's currently just +# enough to set important parameters such as ethernet address. +# an extension is in the works. +# --chf + +include "sys.m"; + sys: Sys; + +include "draw.m"; + +include "string.m"; + str: String; + +Configflash: module +{ + init: fn(nil: ref Draw->Context, args: list of string); +}; + +Region: adt { + base: int; + limit: int; +}; + +# +# structure of allocation descriptor +# +Fcheck: con 0; +Fbase: con 4; +Flen: con 8; +Ftag: con 11; +Fsig: con 12; +Fasize: con 3*4+3+1; + +Tdead: con byte 0; +Tboot: con byte 16r01; +Tconf: con byte 16r02; +Tnone: con byte 16rFF; + +flashsig := array[] of {byte 16rF1, byte 16rA5, byte 16r5A, byte 16r1F}; +noval := array[] of {0 to 3 =>byte 16rFF}; # + +Ctag, Cscreen, Cconsole, Cbaud, Cether, Cea, Cend: con iota; +config := array[] of { + Ctag => "#plan9.ini\n", # current flag for qboot, don't change + Cscreen => "vgasize=640x480x8\n", + Cconsole => "console=0 lcd\n", + Cbaud => "baud=9600\n", + Cether => "ether0=type=SCC port=2 ", # note missing \n + Cea => "ea=08003e400080\n", + Cend => "\0" # qboot currently requires it but shouldn't +}; + +Param: adt { + name: string; + index: int; +}; + +params := array[] of { + Param("vgasize", Cscreen), + Param("console", Cconsole), + Param("ea", Cea), + Param("baud", Cbaud) +}; + +# could come from file or #F/flash/flashctl +FLASHSEG: con 256*1024; +bootregion := Region(0, FLASHSEG); + +stderr: ref Sys->FD; +prog := "qconfig"; +damaged := 0; +debug := 0; + +usage() +{ + sys->fprint(stderr, "Usage: %s [-D] [-f flash] [-param value ...]\n", prog); + exit; +} + +err(s: string) +{ + sys->fprint(stderr, "%s: %s", prog, s); + if(!damaged) + sys->fprint(stderr, "; flash not modified\n"); + else + sys->fprint(stderr, "; flash might now be invalid\n"); + exit; +} + +init(nil: ref Draw->Context, args: list of string) +{ + sys = load Sys Sys->PATH; + sys->pctl(Sys->FORKFD|Sys->NEWPGRP, nil); + stderr = sys->fildes(2); + if(args != nil){ + prog = hd args; + args = tl args; + } + str = load String String->PATH; + if(str == nil) + err(sys->sprint("can't load %s: %r", String->PATH)); + flash := "#F/flash/flash"; + offset := 0; + region := bootregion; + + for(; args != nil && (hd args)[0] == '-'; args = tl args) + case a := hd args { + "-f" => + (flash, args) = argf(tl args); + "-D" => + debug = 1; + * => + p := lookparam(params, a[1:]); + if(p.index < 0) + err(sys->sprint("unknown config parameter: %s", a)); + v: string; + (v, args) = argf(tl args); + config[p.index] = a[1:]+"="+v+"\n"; # would be nice to check it + } + if(len args > 0) + usage(); + out := sys->open(flash, Sys->ORDWR); + if(out == nil) + err(sys->sprint("can't open %s for read/write: %r", flash)); + # TO DO: hunt for free space and add new entry + plonk(out, FLASHSEG-Fasize, mkdesc(0, 128*1024, Tboot)); + c := flatten(config); + if(debug) + sys->print("%s", c); + bconf := array of byte c; + plonk(out, FLASHSEG-Fasize*2, mkdesc(128*1024, len bconf, Tconf)); + plonk(out, 128*1024, bconf); +} + +argf(args: list of string): (string, list of string) +{ + if(args == nil) + usage(); + return (hd args, args); +} + +lookparam(options: array of Param, s: string): Param +{ + for(i := 0; i < len options; i++) + if(options[i].name == s) + return options[i]; + return Param(nil, -1); +} + +flatten(a: array of string): string +{ + s := ""; + for(i := 0; i < len a; i++) + s += a[i]; + return s; +} + +plonk(out: ref Sys->FD, where: int, val: array of byte) +{ + if(debug){ + sys->print("write #%ux [%d]:", where, len val); + for(i:=0; i<len val; i++) + sys->print(" %.2ux", int val[i]); + sys->print("\n"); + } + sys->seek(out, big where, 0); + if(sys->write(out, val, len val) != len val) + err(sys->sprint("bad flash write: %r")); +} + +cvt(v: int): array of byte +{ + a := array[4] of byte; + a[0] = byte (v>>24); + a[1] = byte (v>>16); + a[2] = byte (v>>8); + a[3] = byte (v & 16rff); + return a; +} + +mkdesc(base: int, length: int, tag: byte): array of byte +{ + a := array[Fasize] of byte; + a[Fcheck:] = noval; + a[Fbase:] = cvt(base); + a[Flen:] = cvt(length)[1:]; # it's three bytes + a[Ftag] = tag; + a[Fsig:] = flashsig; + return a; +} |
