From 93e67d8b42f178491667ba7165427bc5ac2705f3 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Wed, 18 Mar 1992 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1992-03-18 --- boot/aux.c | 1 + boot/boot.c | 202 ++++------------------------------ boot/boot.h | 78 +++++++------ boot/getpasswd.c | 25 +++++ boot/key.c | 10 +- boot/local.c | 2 +- boot/nopsession.c | 56 ++++++++++ boot/settime.c | 61 +++++++++++ boot/userpasswd.c | 29 +---- gnot/fns.h | 3 +- gnot/l.s | 7 +- gnot/main.c | 90 ++++++++++++--- port/devcons.c | 6 +- port/devip.c | 12 +- port/devmnt.c | 88 ++++++++++----- port/page.c | 1 - port/portdat.h | 24 +++- port/portfns.h | 2 + port/stfcall.c | 273 ++++++++++++++++++---------------------------- port/stream.c | 48 +++++++- port/tcpinput.c | 40 ------- power/boot.c | 2 +- power/l.s | 2 +- 23 files changed, 540 insertions(+), 522 deletions(-) create mode 100644 boot/nopsession.c create mode 100644 boot/settime.c diff --git a/boot/aux.c b/boot/aux.c index 72aa782bac7649e312938c71d3980196abfe292d..fba62146ddf1285234cdfd17627a9da7b16b09ba 100644 --- a/boot/aux.c +++ b/boot/aux.c @@ -107,6 +107,7 @@ srvcreate(char *name, int fd) { char *srvname; int f; + char buf[2*NAMELEN]; srvname = strrchr(name, '/'); if(srvname) diff --git a/boot/boot.c b/boot/boot.c index 7f62079a78940effbe96512ebeed16dbbcf8a8c7..dcfa7639d874ba493a0864ef703bd615104f74e1 100644 --- a/boot/boot.c +++ b/boot/boot.c @@ -1,22 +1,11 @@ #include #include -#include -#include "../port/bootp.h" -#include "../port/arp.h" +#include "../boot/boot.h" #define DEFSYS "bootes" typedef struct Net Net; typedef struct Flavor Flavor; -enum -{ - Nterm = 4, - CtrlD = 4, - Cr = 13, - View = 0x80, -}; - -Fcall hdr; int printcol; char cputype[NAMELEN]; @@ -28,20 +17,17 @@ int mflag; int fflag; int kflag; -void nop(int); -void session(int); int cache(int); void swapproc(void); -void settime(int); Method *rootserver(char*); void -main(int argc, char *argv) +main(int argc, char *argv[]) { int fd; Method *mp; char cmd[64]; - char flags[5]; + char flags[6]; int islocal; sleep(1000); @@ -71,14 +57,14 @@ main(int argc, char *argv) /* * pick a method and initialize it */ - mp = rootserver(*argv); - islocal = strcmp(mp->name, "local") == 0; + mp = rootserver(argc ? *argv : 0); (*mp->config)(mp); + islocal = strcmp(mp->name, "local") == 0; /* * get/set key or password */ - (*pword)(mp); + (*pword)(islocal, mp); /* * connect to the root file system @@ -89,7 +75,8 @@ main(int argc, char *argv) if(!islocal){ nop(fd); session(fd); - fd = cache(fd); + if(cfs) + fd = (*cfs)(fd); srvcreate(sys, fd); } srvcreate("boot", fd); @@ -104,17 +91,19 @@ main(int argc, char *argv) close(fd); /* - * start local fs if its not the root file server + * if a local file server exists and it's not the + * root file server, start it and mount it onto /n/kfs */ if(!islocal){ for(mp = method; mp->name; mp++) if(strcmp(mp->name, "local")==0){ - local = (*mp->connect)(mp); - if(local < 0) + (*mp->config)(mp); + fd = (*mp->connect)(); + if(fd < 0) break; - if(mount(local, "/n/kfs", MAFTER|MCREATE, "", "") < 0) + if(mount(fd, "/n/kfs", MAFTER|MCREATE, "", "") < 0) fatal("mount"); - close(local); + close(fd); break; } } @@ -124,13 +113,13 @@ main(int argc, char *argv) sleep(1000); sprint(cmd, "/%s/init", cputype); - sprint(flags, "-%s%s", cpuflag ? "c" : "t", mflag ? "m", ""); + sprint(flags, "-%s%s", cpuflag ? "c" : "t", mflag ? "m" : ""); execl(cmd, "init", flags, 0); fatal(cmd); } /* - * ask user from whence comes the root file system + * ask user from whence cometh the root file system */ Method* rootserver(char *arg) @@ -142,18 +131,18 @@ rootserver(char *arg) int n; mp = method; - n = 0; - sprint(prompt, "root is from (", mp->name); + n = sprint(prompt, "root is from (%s", mp->name); for(mp++; mp->name; mp++) n += sprint(prompt+n, ", %s", mp->name); sprint(prompt+n, ")"); - for(;;){ + if(arg) + strcpy(reply, arg); + else strcpy(reply, method->name); - if(arg == 0) + for(;;){ + if(arg == 0 || mflag) outin(prompt, reply, sizeof(reply)); - else - strcpy(reply, arg); arg = 0; for(mp = method; mp->name; mp++) if(*reply == *mp->name){ @@ -167,94 +156,6 @@ rootserver(char *arg) } } -void -nop(int fd) -{ - long n; - - print("nop..."); - hdr.type = Tnop; - hdr.tag = NOTAG; - n = convS2M(&hdr, buf); - if(write(fd, buf, n) != n) - fatal("write nop"); - n = read(fd, buf, sizeof buf); - if(n==2 && buf[0]=='O' && buf[1]=='K') - n = read(fd, buf, sizeof buf); - if(n <= 0) - fatal("read nop"); - if(convM2S(buf, &hdr, n) == 0) { - print("n = %d; buf = %#.2x %#.2x %#.2x %#.2x\n", - n, buf[0], buf[1], buf[2], buf[3]); - fatal("format nop"); - } - if(hdr.type != Rnop) - fatal("not Rnop"); -} - -void -session(int fd) -{ - long n; - - print("session..."); - hdr.type = Tsession; - hdr.tag = NOTAG; - n = convS2M(&hdr, buf); - if(write(fd, buf, n) != n) - fatal("write session"); - n = read(fd, buf, sizeof buf); - if(n <= 0) - fatal("read session"); - if(convM2S(buf, &hdr, n) == 0) - fatal("format session"); - if(hdr.type == Rerror){ - print("error %s;", hdr.ename); - fatal(hdr.ename); - } - if(hdr.type != Rsession) - fatal("not Rsession"); -} - -int -cache(int fd) -{ - ulong i; - int p[2]; - char d[DIRLEN]; - char partition[2*NAMELEN]; - - if(stat("/cfs", d) < 0) - return fd; - sprint(partition, "%scache", bootdisk); - if(stat(partition, d) < 0) - return fd; - print("cfs..."); - if(pipe(p)<0) - fatal("pipe"); - switch(fork()){ - case -1: - fatal("fork"); - case 0: - close(p[1]); - dup(fd, 0); - close(fd); - dup(p[0], 1); - close(p[0]); - if(format) - execl("/cfs", "bootcfs", "-fs", "-p", partition, 0); - else - execl("/cfs", "bootcfs", "-s", "-p", partition, 0); - break; - default: - close(p[0]); - close(fd); - fd = p[1]; - break; - } - return fd; -} - void swapproc(void) { @@ -268,60 +169,3 @@ swapproc(void) if(write(fd, "start", 5) <= 0) warning("starting swap kproc"); } - -void -settime(int islocal) -{ - int n, f; - int timeset; - Dir dir; - char dirbuf[DIRLEN]; - char *srvname; - - print("time..."); - timeset = 0; - if(islocal){ - /* - * set the time from the real time clock - */ - f = open("#r/rtc", ORDWR); - if(f >= 0){ - if((n = read(f, dirbuf, sizeof(dirbuf)-1)) > 0){ - dirbuf[n] = 0; - timeset = 1; - } - close(f); - } - } - if(timeset == 0){ - /* - * set the time from the access time of the root - */ - f = open("#s/boot", ORDWR); - if(f < 0) - return; - if(mount(f, "/n/boot", MREPL, "", "") < 0){ - close(f); - return; - } - close(f); - if(stat("/n/boot", dirbuf) < 0) - fatal("stat"); - convM2D(dirbuf, &dir); - sprint(dirbuf, "%ld", dir.atime); - unmount(0, "/n/boot"); - /* - * set real time clock if there is one - */ - f = open("#r/rtc", ORDWR); - if(f > 0){ - write(f, dirbuf, strlen(dirbuf)); - close(f); - } - close(f); - } - - f = open("#c/time", OWRITE); - write(f, dirbuf, strlen(dirbuf)); - close(f); -} diff --git a/boot/boot.h b/boot/boot.h index a55681bc639295a5bb5a6673a55266dceecd88f8..14d8468b03c12e87ec7415187c04110ed9c34dda 100644 --- a/boot/boot.h +++ b/boot/boot.h @@ -3,57 +3,67 @@ struct Method { char *name; void (*config)(Method*); - void (*auth)(Method*); - void (*connect)(Method*); + int (*auth)(void); + int (*connect)(void); char *arg; }; -extern char terminal[NAMELEN]; -extern char sys[2*NAMELEN]; -extern char password[NAMELEN]; -extern char username[NAMELEN]; +extern char* bootdisk; +extern int (*cfs)(int); +extern int cpuflag; extern char cputype[NAMELEN]; -extern char *bootdisk; -extern char *initflag; -extern void (*pword)(Method*); +extern int fflag; extern int kflag; +extern Method method[]; +extern char password[NAMELEN]; +extern void (*pword)(int, Method*); +extern char sys[2*NAMELEN]; +extern char terminal[NAMELEN]; +extern char username[NAMELEN]; /* libc equivalent */ -extern int plumb(char*, char*, int*, char*); -extern int outin(char*, char*, int); -extern int sendmsg(int, char*); -extern void warning(char*); +extern int cache(int); +extern int dkauth(void); +extern int dkconnect(void); extern void fatal(char*); +extern void getpasswd(char*, int); +extern void key(int, Method*); +extern void newkernel(void); +extern void nop(int); +extern int outin(char*, char*, int); +extern int passtokey(char*, char*, int); +extern int plumb(char*, char*, int*, char*); extern int readenv(char*, char*, int); +extern int sendmsg(int, char*); +extern void session(int); extern void setenv(char*, char*); +extern void settime(int); extern void srvcreate(char*, int); -extern int dkauth(void); -extern int dkconnect(void); -extern void userpasswd(int); -extern void getpasswd(char*, int); +extern void userpasswd(int, Method*); +extern void warning(char*); /* methods */ extern void config9600(Method*); -extern int auth9600(Method*); -extern int connect9600(Method*); -extern void config192000(Method*); -extern int auth192000(Method*); -extern int connect192000(Method*); +extern int auth9600(void); +extern int connect9600(void); +extern void config19200(Method*); +extern int auth19200(void); +extern int connect19200(void); extern void confighs(Method*); -extern int authhs(Method*); -extern int connecths(Method*); +extern int authhs(void); +extern int connecths(void); extern void configincon(Method*); -extern int authincon(Method*); -extern int connectincon(Method*); +extern int authincon(void); +extern int connectincon(void); extern void configil(Method*); -extern int authil(Method*); -extern int connectil(Method*); +extern int authil(void); +extern int connectil(void); extern void configtcp(Method*); -extern int authtcp(Method*); -extern int connecttcp(Method*); +extern int authtcp(void); +extern int connecttcp(void); extern void configcyc(Method*); -extern int authcyc(Method*); -extern int connectcyc(Method*); +extern int authcyc(void); +extern int connectcyc(void); extern void configlocal(Method*); -extern int authlocal(Method*); -extern int connectlocal(Method*); +extern int authlocal(void); +extern int connectlocal(void); diff --git a/boot/getpasswd.c b/boot/getpasswd.c index b766e254389e869274319e2ba065cddc8f5783e1..d6f1f5f8666a54f409694a98b701ebe6d8de6813 100644 --- a/boot/getpasswd.c +++ b/boot/getpasswd.c @@ -2,6 +2,31 @@ #include #include <../boot/boot.h> +int +passtokey(char *key, char *p, int n) +{ + uchar t[10]; + int c; + + memset(t, ' ', sizeof t); + if(n < 5) + return 0; + if(n > 10) + n = 10; + strncpy((char*)t, p, n); + if(n >= 9){ + c = p[8] & 0xf; + if(n == 10) + c += p[9] << 4; + for(n = 0; n < 8; n++) + if(c & (1 << n)) + t[n] -= ' '; + } + for(n = 0; n < 7; n++) + key[n] = (t[n] >> n) + (t[n+1] << (8 - (n+1))); + return 1; +} + void getpasswd(char *p, int len) { diff --git a/boot/key.c b/boot/key.c index 3822853c780f9aa1e08088d1b7b3f02577c0dbb9..4fefa6f4d3f36be7bc8ac752caccbe8078bff4cd 100644 --- a/boot/key.c +++ b/boot/key.c @@ -3,11 +3,12 @@ #include <../boot/boot.h> void -key(Method *mp) +key(int islocal, Method *mp) { char password[20], key[7]; int prompt, fd; + USED(islocal); USED(mp); prompt = kflag; @@ -18,16 +19,13 @@ key(Method *mp) } if(prompt){ do - if(getpasswd(password, sizeof password) < 0){ - warning("can't read cons"); - return; - } + getpasswd(password, sizeof password); while(!passtokey(key, password, strlen(password))); }else if(seek(fd, 1024+900, 0) < 0 || read(fd, key, 7) != 7){ close(fd); warning("can't read key from nvram"); } - if(kflag && seek(fd, 1024+900, 0) < 0 || write(fd, key, 7) != 7){ + if(kflag && (seek(fd, 1024+900, 0) < 0 || write(fd, key, 7) != 7)){ close(fd); warning("can't write key to nvram"); } diff --git a/boot/local.c b/boot/local.c index ffdb08955f893356d8b153485420ece2efdce8d6..8f7f4f1760e54219de24829504494ca2a32616d5 100644 --- a/boot/local.c +++ b/boot/local.c @@ -30,7 +30,7 @@ connectlocal(void) if(stat("/kfs", d) < 0) return -1; - sprint(partition, "%sfs", mp->arg ? mp->arg : bootdisk); + sprint(partition, "%sfs", disk ? disk : bootdisk); if(stat(partition, d) < 0) return -1; diff --git a/boot/nopsession.c b/boot/nopsession.c new file mode 100644 index 0000000000000000000000000000000000000000..8178cda0f022089319c6f9f3215db4b9b3cec429 --- /dev/null +++ b/boot/nopsession.c @@ -0,0 +1,56 @@ +#include +#include +#include +#include "../boot/boot.h" + +static Fcall hdr; +static char buf[4*1024]; + +void +nop(int fd) +{ + long n; + + print("nop..."); + hdr.type = Tnop; + hdr.tag = NOTAG; + n = convS2M(&hdr, buf); + if(write(fd, buf, n) != n) + fatal("write nop"); + n = read(fd, buf, sizeof buf); + if(n==2 && buf[0]=='O' && buf[1]=='K') + n = read(fd, buf, sizeof buf); + if(n <= 0) + fatal("read nop"); + if(convM2S(buf, &hdr, n) == 0) { + print("n = %d; buf = %#.2x %#.2x %#.2x %#.2x\n", + n, buf[0], buf[1], buf[2], buf[3]); + fatal("format nop"); + } + if(hdr.type != Rnop) + fatal("not Rnop"); +} + +void +session(int fd) +{ + long n; + + print("session..."); + hdr.type = Tsession; + hdr.tag = NOTAG; + n = convS2M(&hdr, buf); + if(write(fd, buf, n) != n) + fatal("write session"); + n = read(fd, buf, sizeof buf); + if(n <= 0) + fatal("read session"); + if(convM2S(buf, &hdr, n) == 0) + fatal("format session"); + if(hdr.type == Rerror){ + print("error %s;", hdr.ename); + fatal(hdr.ename); + } + if(hdr.type != Rsession) + fatal("not Rsession"); +} diff --git a/boot/settime.c b/boot/settime.c new file mode 100644 index 0000000000000000000000000000000000000000..8fa9bc9caac7ac9b4143353829e633c5424cb623 --- /dev/null +++ b/boot/settime.c @@ -0,0 +1,61 @@ +#include +#include +#include +#include "../boot/boot.h" + +void +settime(int islocal) +{ + int n, f; + int timeset; + Dir dir; + char dirbuf[DIRLEN]; + char *srvname; + + print("time..."); + timeset = 0; + if(islocal){ + /* + * set the time from the real time clock + */ + f = open("#r/rtc", ORDWR); + if(f >= 0){ + if((n = read(f, dirbuf, sizeof(dirbuf)-1)) > 0){ + dirbuf[n] = 0; + timeset = 1; + } + close(f); + } + } + if(timeset == 0){ + /* + * set the time from the access time of the root + */ + f = open("#s/boot", ORDWR); + if(f < 0) + return; + if(mount(f, "/n/boot", MREPL, "", "") < 0){ + close(f); + return; + } + close(f); + if(stat("/n/boot", dirbuf) < 0) + fatal("stat"); + convM2D(dirbuf, &dir); + sprint(dirbuf, "%ld", dir.atime); + unmount(0, "/n/boot"); + /* + * set real time clock if there is one + */ + f = open("#r/rtc", ORDWR); + if(f > 0){ + write(f, dirbuf, strlen(dirbuf)); + close(f); + } + close(f); + } + + f = open("#c/time", OWRITE); + write(f, dirbuf, strlen(dirbuf)); + close(f); +} diff --git a/boot/userpasswd.c b/boot/userpasswd.c index ba331d919c70b13d404e0e035814f52a09619ff5..ad82cea1227168054458bef92ad6d2c370feeb2b 100644 --- a/boot/userpasswd.c +++ b/boot/userpasswd.c @@ -4,36 +4,11 @@ char password[NAMELEN]; -static int -passtokey(char *key, char *p, int n) -{ - uchar t[10]; - int c; - - memset(t, ' ', sizeof t); - if(n < 5) - return 0; - if(n > 10) - n = 10; - strncpy((char*)t, p, n); - if(n >= 9){ - c = p[8] & 0xf; - if(n == 10) - c += p[9] << 4; - for(n = 0; n < 8; n++) - if(c & (1 << n)) - t[n] -= ' '; - } - for(n = 0; n < 7; n++) - key[n] = (t[n] >> n) + (t[n+1] << (8 - (n+1))); - return 1; -} - /* * get/set user name and password. verify password with auth server. */ void -userpasswd(Method *mp) +userpasswd(int islocal, Method *mp) { char key[7]; char buf[8 + NAMELEN]; @@ -44,7 +19,7 @@ userpasswd(Method *mp) outin("user", username, sizeof(username)); } crfd = fd = -1; - while(strcmp(username, "none") != 0 && strcmp(mp->name, "local") != 0){ + while(strcmp(username, "none") != 0 && !islocal){ getpasswd(password, sizeof password); if(!passtokey(key, password, strlen(password))){ print("bad password; try again\n"); diff --git a/gnot/fns.h b/gnot/fns.h index 35b7a4116f8b2df1a30cc2c5efb186ec311318d2..18731ec317746749c073c4f18670a59242a56ef0 100644 --- a/gnot/fns.h +++ b/gnot/fns.h @@ -7,6 +7,7 @@ #define P_write(sel, addr, val, type) P_oper(sel, *(type *)(PORT+addr) = val) void addportintr(int (*)(void)); +void bootargs(ulong); void clearmmucache(void); void duartclock(void); void duartinit(void); @@ -58,7 +59,7 @@ int spl1(void); void spldone(void); int splduart(void); int tas(char*); -void touser(void); +void touser(void*); #define waserror() (u->nerrlab++, setlabel(&u->errlab[u->nerrlab-1])) #define kmapperm(x) kmap(x) #define getcallerpc(x) (*(ulong*)(x)) diff --git a/gnot/l.s b/gnot/l.s index 1fc9b2105350fbd33a20113734c82ce18e7b1cf2..590e0608e07e950095144ff75c27426e20618986 100644 --- a/gnot/l.s +++ b/gnot/l.s @@ -29,17 +29,18 @@ dead: BRA dead /* - * Take first processor into user mode. Leave enough room on the stack + * Take first processor into user mode. Leave enough room on the kernel stack * for a full-sized Ureg (including long bus error format) to fit + * - argument is stack pointer to user */ -TEXT touser(SB), $-4 +TEXT touser(SB), $0 + MOVL usp+0(FP), A0 MOVL $(USERADDR+BY2PG-UREGVARSZ), A7 MOVW $0, -(A7) MOVL $(UTZERO+32), -(A7) /* header is in text */ MOVW $0, -(A7) - MOVL $(USTKTOP-6*BY2WD), A0 /* MAXSYSARG=6 */ MOVL A0, USP MOVW $(SUPER|SPL(0)), SR MOVL $8, R0 diff --git a/gnot/main.c b/gnot/main.c index 62355bd1add09f00a4fd54367ea9a0c0749bb38c..4658ddaa7abba732d8f5c4863f25d18da9e4b09a 100644 --- a/gnot/main.c +++ b/gnot/main.c @@ -11,7 +11,6 @@ #include typedef struct Boot Boot; - struct Boot { long station; @@ -23,11 +22,11 @@ struct Boot }; #define BOOT ((Boot*)0) -char bootuser[NAMELEN]; -char bootline[64]; -char bootserver[64]; -char bootdevice[2]; -int bank[2]; +char bootuser[NAMELEN]; +char bootline[64]; +char bootserver[72]; +int bank[2]; +uchar *sp; void unloadboot(void); @@ -66,10 +65,25 @@ main(void) void unloadboot(void) { + char s[64]; + strncpy(bootuser, BOOT->user, NAMELEN); memmove(bootline, BOOT->line, 64); - memmove(bootserver, BOOT->server, 64); - bootdevice[0] = BOOT->device; + memmove(s, BOOT->server, 64); + switch(BOOT->device){ + case 'a': + sprint(bootserver, "19200!%s", s); + break; + case 'A': + sprint(bootserver, "9600!%s", s); + break; + case 'i': + sprint(bootserver, "incon!%s", s); + break; + default: + sprint(bootserver, "scsi!%s", s); + break; + } } void @@ -124,14 +138,10 @@ init0(void) if(!waserror()){ ksetterm("at&t %s"); ksetenv("cputype", "68020"); - ksetenv("bootuser", bootuser); - ksetenv("bootline", bootline); - ksetenv("bootserver", bootserver); - ksetenv("bootdevice", bootdevice); poperror(); } - touser(); + touser(sp); } FPsave initfp; @@ -143,6 +153,7 @@ userinit(void) Segment *s; User *up; KMap *k; + Page *pg; p = newproc(); p->pgrp = newpgrp(); @@ -171,10 +182,15 @@ userinit(void) kunmap(k); /* - * User Stack + * User Stack, copy in boot arguments */ s = newseg(SG_STACK, USTKTOP-BY2PG, 1); p->seg[SSEG] = s; + pg = newpage(1, 0, USTKTOP-BY2PG); + segpage(s, pg); + k = kmap(pg); + bootargs(VA(k)); + kunmap(k); /* * Text @@ -189,6 +205,52 @@ userinit(void) ready(p); } +uchar * +pusharg(char *p) +{ + int n; + + n = strlen(p)+1; + sp -= n; + memmove(sp, p, n); + return sp; +} + +void +bootargs(ulong base) +{ + int i, ac; + uchar *av[32]; + char *p, *pp; + uchar **lsp; + + sp = (uchar*)base + BY2PG - MAXSYSARG*BY2WD; + + ac = 0; + for(p = bootline; p && *p; p = pp){ + pp = strchr(p, ' '); + if(pp) + *pp++ = 0; + av[ac++] = pusharg(p); + } + if(bootuser[0]){ + av[ac++] = pusharg("-u"); + av[ac++] = pusharg(bootuser); + } + av[ac++] = pusharg(bootserver); + + /* 4 byte word align stack */ + sp = (uchar*)((ulong)sp & ~3); + + /* build argc, argv on stack */ + sp -= (ac+1)*sizeof(sp); + lsp = (uchar**)sp; + for(i = 0; i < ac; i++) + *lsp++ = av[i] + ((USTKTOP - BY2PG) - base); + *lsp = 0; + sp += (USTKTOP - BY2PG) - base - sizeof(sp); +} + void exit(void) { diff --git a/port/devcons.c b/port/devcons.c index 640b74134d19bc1df57099bc1e757e693ebe3b39..405e5c65aa2509809b9541ec4899900de42f8aec 100644 --- a/port/devcons.c +++ b/port/devcons.c @@ -379,7 +379,7 @@ int readnum(ulong off, char *buf, ulong n, ulong val, int size) { char tmp[64]; - Op op = { tmp, tmp+sizeof(tmp), &val, size-1, 0, FUNSIGN|FLONG }; + Op op = (Op){ tmp, tmp+sizeof(tmp), &val, size-1, 0, FUNSIGN|FLONG }; numbconv(&op, 10); tmp[size-1] = ' '; @@ -597,12 +597,12 @@ consread(Chan *c, void *buf, long n, ulong offset) if(offset != 0 || n != 8) error(Ebadarg); chal = u->p->pgrp->crypt->chal; - chal[0] = 0; + chal[0] = RXschal; for(i=1; i<8; i++) chal[i] = nrand(256); memmove(buf, chal, 8); encrypt(evekey, buf, 8); - chal[0] = 1; + chal[0] = RXstick; return n; case Quser: diff --git a/port/devip.c b/port/devip.c index ef454344e7cc231123c4bea7cce46134212775f0..8ab322898a20266876c4eada1eeaa3341565f931 100644 --- a/port/devip.c +++ b/port/devip.c @@ -11,8 +11,8 @@ enum { - Nrprotocol = 3, /* Number of protocols supported by this driver */ - Nipsubdir = 4, /* Number of subdirectory entries per connection */ + Nrprotocol = 3, /* Number of protocols supported by this driver */ + Nipsubdir = 4, /* Number of subdirectory entries per connection */ }; int udpsum = 1; @@ -38,7 +38,7 @@ void iloput(Queue *, Block *); void ilopen(Queue *, Stream *); void ilclose(Queue *); -Qinfo tcpinfo = { tcpstiput, tcpstoput, tcpstopen, tcpstclose, "tcp" }; +Qinfo tcpinfo = { tcpstiput, tcpstoput, tcpstopen, tcpstclose, "tcp", 0, 1 }; Qinfo udpinfo = { udpstiput, udpstoput, udpstopen, udpstclose, "udp" }; Qinfo ilinfo = { iliput, iloput, ilopen, ilclose, "il" }; @@ -164,12 +164,10 @@ ipincoming(Ipconv *base, Ipconv *from) qunlock(new); continue; } - if(from) - /* copy ownership from listening channel */ + if(from) /* copy ownership from listening channel */ netown(new->net, new->index, new->net->prot[from->index].owner, 0); - else - /* current user becomes owner */ + else /* current user becomes owner */ netown(new->net, new->index, u->p->user, 0); new->ref = 1; diff --git a/port/devmnt.c b/port/devmnt.c index e0f329d4bc944f0bbccb165ffcfa224f649f42e4..cd2bf764a3b4400c2a40fc31a8b202f312f84ac0 100644 --- a/port/devmnt.c +++ b/port/devmnt.c @@ -67,6 +67,7 @@ void mntdirfix(uchar*, Chan*); void mntgate(Mnt*); void mntrpcread(Mnt*, Mntrpc*); void mntdoclunk(Mnt *, Mntrpc *); +void mntauth(Mnt *, Mntrpc *, char *, ushort); enum { @@ -123,6 +124,8 @@ Chan* mntattach(char *muxattach) { Mnt *m, *e; + Stream *s; + Qinfo *qi; struct bogus{ Chan *chan; char *spec; @@ -159,9 +162,23 @@ mntattach(char *muxattach) m->c->flag |= CMSG; m->blocksize = MAXFDATA; + /* If we have a stream based protocol (TCP/IP) we push fcall to block + * up P9 protocol messages into single deliminted blocks + */ + s = m->c->stream; + qi = qinfofind("fcall"); + if(s) + if(s->procq->next) + if(s->procq->next->info->nodelim) { + if(qi == 0) + error(Ebadctl); + pushq(s, qi); + } + switch(devchar[m->c->type]) { default: m->mux = 0; + break; case 'H': /* Cyclone */ m->mux = 1; break; @@ -177,8 +194,6 @@ mattach(Mnt *m, char *spec, char *serv) { Chan *c; Mntrpc *r; - char chal[8]; - int i; r = mntralloc(); c = devattach('M', spec); @@ -193,31 +208,10 @@ mattach(Mnt *m, char *spec, char *serv) nexterror(); } - if(*serv){ - r->request.type = Tauth; - r->request.fid = c->fid; - memmove(r->request.uname, u->p->user, NAMELEN); - chal[0] = 1; - for(i = 1; i < sizeof chal; i++) - chal[i++] = nrand(256); - memmove(r->request.chal, chal, 8); - strncpy(r->request.chal+8, serv, NAMELEN); - encrypt(u->p->pgrp->crypt->key, r->request.chal, 8+NAMELEN); - if(waserror()) - memset(r->request.auth, 0, sizeof r->request.auth); - else{ - mountrpc(m, r); - poperror(); - decrypt(u->p->pgrp->crypt->key, r->reply.chal, 2*8+2*DESKEYLEN); - chal[0] = 4; - if(memcmp(chal, r->reply.chal, 8) != 0) - error(Eperm); - memmove(r->request.auth, r->reply.chal+8+DESKEYLEN, 8+DESKEYLEN); - } - r->done = 0; - r->flushed = 0; - }else - memset(r->request.auth, 0, sizeof r->request.auth); + memset(r->request.auth, 0, sizeof r->request.auth); + if(*serv) + mntauth(m, r, serv, c->fid); + r->request.type = Tattach; r->request.fid = c->fid; @@ -233,6 +227,42 @@ mattach(Mnt *m, char *spec, char *serv) return c; } +void +mntauth(Mnt *m, Mntrpc *f, char *serv, ushort fid) +{ + Mntrpc *r; + uchar chal[CHLEN]; + int i; + + r = mntralloc(); + if(waserror()) { + mntfree(r); + return; + } + + r->request.type = Tauth; + r->request.fid = fid; + memmove(r->request.uname, u->p->user, NAMELEN); + chal[0] = FScchal; + for(i = 1; i < CHLEN; i++) + chal[i++] = nrand(256); + + memmove(r->request.chal, chal, CHLEN); + strncpy(r->request.chal+CHLEN, serv, NAMELEN); + encrypt(u->p->pgrp->crypt->key, r->request.chal, CHLEN+NAMELEN); + + mountrpc(m, r); + decrypt(u->p->pgrp->crypt->key, r->reply.chal, 2*CHLEN+2*DESKEYLEN); + chal[0] = FSctick; + poperror(); + if(memcmp(chal, r->reply.chal, CHLEN) != 0) { + mntfree(r); + error(Eperm); + } + memmove(f->request.auth, r->reply.chal+CHLEN+DESKEYLEN, CHLEN+DESKEYLEN); + mntfree(r); +} + Chan* mntclone(Chan *c, Chan *nc) { @@ -790,8 +820,8 @@ mntdump(void) for(m = mntalloc.mntarena; m < me; m++) { if(m->ref == 0) continue; - print("mount %d: mux %d queue %lux rip 0x%lux %d %s\n", m->id, m->mux, m->queue, - m->rip, + print("mount %d: mux %d queue %lux rip 0x%lux %d %s\n", + m->id, m->mux, m->queue, m->rip, m->rip ? m->rip->pid : 0, m->rip ? m->rip->text : "no"); } print("rpcfree 0x%lux\n", mntalloc.rpcfree); diff --git a/port/page.c b/port/page.c index c9a3caacaa96658ef0c31bbb7ec4f18a7e07694a..7648f7fd7df5cb6efaef5922a7d54202edb4c5e6 100644 --- a/port/page.c +++ b/port/page.c @@ -195,7 +195,6 @@ pageinit(void) ulong i, vmem, pmem, hw, hr; Page *p; -print("addr0 %lux addr1 %lux\n", palloc.addr0, palloc.addr1); /* * calculate an upper bound to the number of pages structures * we'll need (np). diff --git a/port/portdat.h b/port/portdat.h index 75bdc95190854af82039adbb48cbdf1ce59ec3be..301150c6001327ea3df155cffbfb17ada9480b61 100644 --- a/port/portdat.h +++ b/port/portdat.h @@ -156,8 +156,8 @@ struct Chan Mount *mnt; /* mount point that derived Chan */ ulong mountid; int fid; /* for devmnt */ + Stream *stream; /* for stream channels */ union { - Stream *stream; /* for stream channels */ void *aux; Qid pgrpid; /* for #p/notepg */ int mntindex; /* for devmnt */ @@ -579,6 +579,7 @@ struct Qinfo void (*close)(Queue*); char *name; void (*reset)(void); /* initialization */ + char nodelim; /* True if stream does not preserve delimiters */ Qinfo *next; }; @@ -590,7 +591,8 @@ struct Qinfo #define QHIWAT 0x4 /* queue has gone past the high water mark */ #define QDEBUG 0x8 -struct Queue { +struct Queue +{ Blist; int flag; Qinfo *info; /* line discipline definition */ @@ -603,7 +605,8 @@ struct Queue { void *ptr; /* private info for the queue */ }; -struct Stream { +struct Stream +{ QLock; /* structure lock */ short inuse; /* number of processes in stream */ short opens; /* number of processes with stream open */ @@ -623,7 +626,6 @@ struct Stream { */ #define RD(q) ((q)->other < (q) ? (q->other) : q) #define WR(q) ((q)->other > (q) ? (q->other) : q) -#define GLOBAL(a) (((ulong)(a)) & 0x80000000) #define STREAMTYPE(x) ((x)&0x1f) #define STREAMID(x) (((x)&~CHDIR)>>5) #define STREAMQID(i,t) (((i)<<5)|(t)) @@ -684,7 +686,7 @@ extern FPsave initfp; extern Conf conf; extern ulong initcode[]; extern Dev devtab[]; -extern char devchar[]; +extern char *devchar; extern char *conffile; extern char *statename[]; extern Palloc palloc; @@ -696,3 +698,15 @@ extern int nrdy; #define CHDIR 0x80000000L #define CHAPPEND 0x40000000L #define CHEXCL 0x20000000L + +/* + * auth messages + */ +#define CHLEN 8 +enum{ + FScchal = 1, + FSctick, + + RXschal = 0, + RXstick = 1, +}; diff --git a/port/portfns.h b/port/portfns.h index 46c18206f3053739c85aeb615bded0670589c37c..a5bd7ba800cc2b9082c58f44e41801a0a854e27e 100644 --- a/port/portfns.h +++ b/port/portfns.h @@ -143,6 +143,7 @@ Segment* newseg(int, ulong, ulong); Waitq* newwaitq(void); char* nextelem(char*, char*); void nexterror(void); +int nodelims(Stream*); int notify(Ureg*); int nrand(int); void nullput(Queue*, Block*); @@ -182,6 +183,7 @@ void putstr(char*); void putstrn(char*, long); void putswap(Page*); ulong pwait(Waitmsg*); +Qinfo* qinfofind(char*); void qlock(QLock*); void qunlock(QLock*); int readnum(ulong, char*, ulong, ulong, int); diff --git a/port/stfcall.c b/port/stfcall.c index 36ef5c1c70892b616b33cdac14950bffecdfbcd1..e5f915394b6cd1b77013557adb4919abdd3bbc4f 100644 --- a/port/stfcall.c +++ b/port/stfcall.c @@ -7,91 +7,74 @@ #include "fcall.h" -#define DPRINT if(fcalldebug)kprint - -int fcalldebug = 0; - -typedef struct Fcalld Fcalld; - -struct Fcalld{ - int dev; /* ref. for debug output */ - int state; - int type; /* of current message */ - int need; /* bytes remaining in current message */ - int nhdr; /* bytes of header treasured up in hdr */ - uchar hdr[16]; -}; - -enum { - Startup, Startup1, Begin, Header, Data +enum +{ + Twritehdr = 15, /* Min bytes for Twrite */ + Rreadhdr = 8, /* Min bytes for Rread */ + Twritecnt = 13, /* Offset in byte stream of write count */ + Rreadcnt = 5, /* Offset for Readcnt */ }; -/* - * fcall stream module definition - */ static void fcalliput(Queue*, Block*); static void fcalloput(Queue*, Block*); static void fcallopen(Queue*, Stream*); static void fcallclose(Queue*); static void fcallreset(void); -Qinfo fcallinfo = +Qinfo fcallinfo = { fcalliput, fcalloput, fcallopen, fcallclose, "fcall", fcallreset }; + +static uchar msglen[256] = { - fcalliput, - fcalloput, - fcallopen, - fcallclose, - "fcall", - fcallreset + [Tnop] 3, + [Rnop] 3, + [Tsession] 3, + [Rsession] 3, + [Terror] 0, + [Rerror] 67, + [Tflush] 5, + [Rflush] 3, + [Tattach] 89, + [Rattach] 13, + [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, + [Tauth] 69, + [Rauth] 35, }; -static Block * putmsg(Queue*, Block*, int); - -static uchar msglen[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 3, 3, 3, 3, 0, 67, 5, 3, 89, 13, 7, 5, 33, 13, - 6, 13, 38, 13, 15, 8, 16, 7, 5, 5, 5, 5, 5,121,121, 5, - 35, 13, 69, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; static void fcallreset(void) -{} +{ +} static void fcallopen(Queue *q, Stream *s) { - Fcalld *f; - - DPRINT("fcallopen %d\n", s->dev); - - q->ptr = allocb(sizeof(Fcalld)); - f = (Fcalld *)((Block *)q->ptr)->base; - f->dev = s->dev; - f->state = Startup; - f->type = 0; - f->need = 0; - f->nhdr = 0; + USED(q, s); } static void fcallclose(Queue * q) { - Fcalld *f = (Fcalld *)((Block *)q->ptr)->base; - - DPRINT("fcallstclose %d\n", f->dev); - freeb(q->ptr); - q->ptr = 0; + USED(q); } void @@ -100,125 +83,81 @@ fcalloput(Queue *q, Block *bp) PUTNEXT(q, bp); } +void +upstream(Queue *q, ulong len) +{ + Block *bl, **tail, *bp; + ulong l; + + tail = &bl; + while(len) { + l = BLEN(q->first); + if(l > len) + break; + bp = getq(q); /* Consume all of block */ + *tail = bp; + tail = &bp->next; + len -= l; + } + if(len) { /* Consume partial block */ + lock(q); + *tail = copyb(q->first, len); + q->first->rptr += len; + q->len -= len; + unlock(q); + } + for(bp = bl; bp->next; bp = bp->next) + ; + bp->flags |= S_DELIM; + PUTNEXT(q, bl); +} static void fcalliput(Queue *q, Block *bp) { - Fcalld *f = (Fcalld *)((Block *)q->ptr)->base; - int len, n; + ulong len, need, off; - len = BLEN(bp); - DPRINT("fcalliput %d: blen=%d\n", f->dev, len); - if(bp->type != M_DATA){ - DPRINT("fcalliput %d: type=%d\n", f->dev, bp->type); + if(bp->type != M_DATA) { PUTNEXT(q, bp); return; } - bp->flags &= ~S_DELIM; - if(len == 0){ + if(BLEN(bp) == 0) { freeb(bp); return; } - while(len > 0)switch(f->state){ - case Startup: - if (len == 1 && bp->rptr[0] == 'O'){ - DPRINT("fcalliput %d: O\n", f->dev); - PUTNEXT(q, bp); - f->state = Startup1; - return; - } - if(bp->rptr[0] == 'O' && bp->rptr[1] == 'K'){ - DPRINT("fcalliput %d: OK\n", f->dev); - bp = putmsg(q, bp, 2); - len -= 2; - } - f->state = Begin; - break; - case Startup1: - if(bp->rptr[0] == 'K'){ - DPRINT("fcalliput %d: K\n", f->dev); - bp = putmsg(q, bp, 1); - len -= 1; - f->state = Begin; - break; - } - f->type = 'O'; - f->need = msglen['O']-1; - f->state = Data; - DPRINT("fcalliput %d: type=%d, need=%d\n", - f->dev, f->type, f->need); - break; + /* Stash the data */ + bp->flags &= ~S_DELIM; + putq(q, bp); - case Begin: - f->type = bp->rptr[0]; - f->need = msglen[f->type]; - f->nhdr = 0; - if(f->type == Twrite || f->type == Rread) - f->state = Header; - else - f->state = Data; - DPRINT("fcalliput %d: type=%d, need=%d\n", - f->dev, f->type, f->need); - break; + bp = q->first; + switch(bp->rptr[0]) { /* This is the type */ + default: + len = msglen[bp->rptr[0]]; + if(len == 0) + error(Emountrpc); + if(q->len >= len) + upstream(q, len); - case Header: - n = f->need; - if(n > len) - n = len; - memmove(&f->hdr[f->nhdr], bp->rptr, n); - f->nhdr += n; - DPRINT("fcalliput %d: nhdr=%d\n", - f->dev, f->nhdr); - if(n == f->need){ - f->need += f->hdr[f->nhdr-3]; - f->need += f->hdr[f->nhdr-2] << 8; - f->state = Data; - DPRINT("fcalliput %d: need=%d\n", - f->dev, f->need); - } - /* fall through */ - - case Data: - if(f->need > len){ - f->need -= len; - PUTNEXT(q, bp); - return; - } - bp = putmsg(q, bp, f->need); - len -= f->need; - f->state = Begin; + return; + 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; } -} -static Block * -putmsg(Queue *q, Block *bp, int n) -{ - Block *xbp; - int k; + if(q->len < len) + return; - DPRINT("putmsg: n=%d\n\n", n); - k = BLEN(bp) - n; - if(k == 0){ - bp->flags |= S_DELIM; - PUTNEXT(q, bp); - return 0; - } - if(n <= k){ - xbp = allocb(n); - memmove(xbp->wptr, bp->rptr, n); - xbp->wptr += n; - bp->rptr += n; - xbp->flags |= S_DELIM; - PUTNEXT(q, xbp); - return bp; - } - xbp = allocb(k); - memmove(xbp->wptr, bp->rptr+n, k); - xbp->wptr += k; - bp->wptr -= k; - bp->flags |= S_DELIM; - PUTNEXT(q, bp); - return xbp; + pullup(q->first, len); + bp = q->first; + need = len+bp->rptr[off]+(bp->rptr[off+1]<<8); + if(q->len < need) + return; + + upstream(q, need); } diff --git a/port/stream.c b/port/stream.c index 269c1a9b1d5c95c52a9a953ea1ddc228763a56ac..7fd17c82fa7cd0ea2ff3022de0081ebf8260c0ce 100644 --- a/port/stream.c +++ b/port/stream.c @@ -708,17 +708,17 @@ nullput(Queue *q, Block *bp) /* * find the info structure for line discipline 'name' */ -static Qinfo * +Qinfo * qinfofind(char *name) { Qinfo *qi; if(name == 0) - error(Ebadld); + return 0; for(qi = lds; qi; qi = qi->next) if(strcmp(qi->name, name)==0) return qi; - error(Ebadld); + return 0; } /* @@ -1260,6 +1260,8 @@ streamctlwrite(Chan *c, void *a, long n) freeb(bp); } else if(streamparse("push", bp)){ qi = qinfofind((char *)bp->rptr); + if(qi == 0) + error(Ebadld); pushq(s, qi); freeb(bp); } else if(streamparse("pop", bp)){ @@ -1415,6 +1417,46 @@ streamstat(Chan *c, char *db, char *name) convD2M(&dir, db); } +Block * +copyb(Block *bp, int count) +{ + Block *nb, *head, **p; + int l; + + p = &head; + while(count) { + l = BLEN(bp); + if(count < l) + l = count; + nb = allocb(l); + if(nb == 0) + panic("copyb.1"); + memmove(nb->wptr, bp->rptr, l); + nb->wptr += l; + count -= l; + if(bp->flags & S_DELIM) + nb->flags |= S_DELIM; + *p = nb; + p = &nb->next; + bp = bp->next; + if(bp == 0) + break; + } + if(count) { + nb = allocb(count); + if(nb == 0) + panic("copyb.2"); + memset(nb->wptr, 0, count); + nb->wptr += count; + nb->flags |= S_DELIM; + *p = nb; + } + if(blen(head) == 0) + print("copyb: zero length\n"); + + return head; +} + /* * Dump all block information of how many blocks are in which queues */ diff --git a/port/tcpinput.c b/port/tcpinput.c index 60af142bfcba658c51040dee18e8ac180d1a9176..4b5969ff4804e17b5b1caae2aaf4e93ae878b39e 100644 --- a/port/tcpinput.c +++ b/port/tcpinput.c @@ -748,46 +748,6 @@ dupb(Block **hp, Block *bp, int offset, int count) return bytes; } -Block * -copyb(Block *bp, int count) -{ - Block *nb, *head, **p; - int l; - - p = &head; - while(count) { - l = BLEN(bp); - if(count < l) - l = count; - nb = allocb(l); - if(nb == 0) - panic("copyb.1"); - memmove(nb->wptr, bp->rptr, l); - nb->wptr += l; - count -= l; - if(bp->flags & S_DELIM) - nb->flags |= S_DELIM; - *p = nb; - p = &nb->next; - bp = bp->next; - if(bp == 0) - break; - } - if(count) { - nb = allocb(count); - if(nb == 0) - panic("copyb.2"); - memset(nb->wptr, 0, count); - nb->wptr += count; - nb->flags |= S_DELIM; - *p = nb; - } - if(blen(head) == 0) - print("copyb: zero length\n"); - - return head; -} - ushort tcp_mss = DEF_MSS; /* Maximum segment size to be sent with SYN */ int tcp_irtt = DEF_RTT; /* Initial guess at round trip time */ diff --git a/power/boot.c b/power/boot.c index 8e94f350485ea52a965652c478541a2a4cc6ef82..1647da788def8600d288987cc3e8cb66a55356b2 100644 --- a/power/boot.c +++ b/power/boot.c @@ -396,7 +396,7 @@ key(void) close(fd); prerror("can't read key from nvram"); } - if(setkey && seek(fd, 1024+900, 0) < 0 || write(fd, key, 7) != 7){ + if(setkey && (seek(fd, 1024+900, 0) < 0 || write(fd, key, 7) != 7)){ close(fd); prerror("can't write key to nvram"); } diff --git a/power/l.s b/power/l.s index 5f5bcb95548322c4cd32f37479042511cb3a3862..4df247cbc45efdc21ab40a30b378d5cc62909121 100644 --- a/power/l.s +++ b/power/l.s @@ -63,7 +63,7 @@ clrbss: TEXT touser(SB), $-4 - MOVW R1, SP + MOVW R1, SP /* user stack pointer */ MOVW M(STATUS), R1 OR $(KUP|IEP), R1 MOVW R1, M(STATUS)