~kris/9p

9hist

f086cfa66a7c6087428d360e12f5e3150cab963b — David du Colombier 35 years ago 6e6d311
Plan 9 from Bell Labs 1990-11-22
M gnot/boot.c => gnot/boot.c +27 -18
@@ 1,7 1,6 @@
#include <u.h>
#include <libc.h>

#include "fcall.h"
#include <fcall.h>

Fcall	hdr;
char	buf[100];


@@ 14,7 13,7 @@ void	sendmsg(int, char*);

main(int argc, char *argv[])
{
	int cfd, fd, n, fu, f;
	int cfd, fd, n, fu, f, i;
	char buf[256];
	int p[2];



@@ 100,14 99,23 @@ main(int argc, char *argv[])
	 *  open a datakit channel and call ken, leave the
	 *  incon ctl channel open
	 */
	fd = open("#k/2/data", 2);
	if(fd < 0)
		error("opening #k/2/data");
	cfd = open("#k/2/ctl", 2);
	if(cfd < 0)
		error("opening #k/2/ctl");
	sprint(buf, "connect %s", bootserver);
	sendmsg(cfd, buf);
	for(i = 0; ; i++){
		fd = open("#k/2/data", 2);
		if(fd < 0)
			error("opening #k/2/data");
		cfd = open("#k/2/ctl", 2);
		if(cfd < 0)
			error("opening #k/2/ctl");
		sprint(buf, "connect %s", bootserver);
		n = strlen(buf);
		if(write(cfd, buf, n) == n)
			break;
		if(i == 5)
			error("dialing");
		print("error dialing, retrying ...\n");
		close(fd);
		close(cfd);
	}
	print("connected to %s\n", bootserver);
	close(cfd);



@@ 116,6 124,7 @@ main(int argc, char *argv[])
	 */
	print("nop...");
	hdr.type = Tnop;
	hdr.tag = ~0;
	n = convS2M(&hdr, buf);
	if(write(fd, buf, n) != n)
		error("write nop");


@@ 134,7 143,7 @@ main(int argc, char *argv[])

	print("session...");
	hdr.type = Tsession;
	hdr.lang = 'v';
	hdr.tag = ~0;
	n = convS2M(&hdr, buf);
	if(write(fd, buf, n) != n)
		error("write session");


@@ 143,12 152,12 @@ main(int argc, char *argv[])
		error("read session");
	if(convM2S(buf, &hdr, n) == 0)
		error("format session");
	if(hdr.type == Rerror){
		print("error %s;", hdr.ename);
		error(hdr.ename);
	}
	if(hdr.type != Rsession)
		error("not Rsession");
	if(hdr.err){
		print("error %d;", hdr.err);
		error("remote error");
	}

	print("post...");
	sprint(buf, "#s/%s", "bootes");


@@ 171,7 180,7 @@ main(int argc, char *argv[])
	print("mount...");
	if(bind("/", "/", MREPL) < 0)
		error("bind");
	if(mount(fd, "/", MAFTER|MCREATE, "") < 0)
	if(mount(fd, "/", MAFTER|MCREATE, "", "") < 0)
		error("mount");
	print("success\n");
	if(strchr(bootline, ' '))


@@ 196,7 205,7 @@ error(char *s)
{
	char buf[64];

	errstr(0, buf);
	errstr(buf);
	fprint(2, "boot: %s: %s\n", s, buf);
	exits(0);
}

M gnot/boot.h => gnot/boot.h +1138 -1110
@@ 1,8 1,8 @@
ulong bootcode[]={
	0x000000107,
	0x000002482,
	0x000000474,
	0x0000001b0,
	0x000002504,
	0x000000464,
	0x0000001e4,
	0x000000000,
	0x000002020,
	0x000000000,


@@ 13,387 13,409 @@ ulong bootcode[]={
	0x000142f2f,
	0x00014610c,
	0x02f006100,
	0x006304fef,
	0x006884fef,
	0x0001c4e75,
	0x04feffee4,
	0x04feffee0,
	0x042a7486e,
	0x081166100,
	0x0243e4878,
	0x0151e4878,
	0x00001486e,
	0x0811e6100,
	0x024324878,
	0x015124878,
	0x00001486e,
	0x081266100,
	0x0242642a7,
	0x0150642a7,
	0x0486e812e,
	0x06100241c,
	0x0610014fc,
	0x04a806d1e,
	0x048780040,
	0x0486e85e6,
	0x0486e860a,
	0x02f002f40,
	0x001406100,
	0x0240c2f2f,
	0x001406100,
	0x023da4fef,
	0x001446100,
	0x014ec2f2f,
	0x001446100,
	0x014c04fef,
	0x0001042a7,
	0x0486e813a,
	0x0610023f0,
	0x0610014d0,
	0x04a806d1e,
	0x048780001,
	0x0486e8002,
	0x02f002f40,
	0x001486100,
	0x023e02f2f,
	0x001486100,
	0x023ae4fef,
	0x0014c6100,
	0x014c02f2f,
	0x0014c6100,
	0x014944fef,
	0x0001042a7,
	0x0486e8148,
	0x0610023c4,
	0x0610014a4,
	0x04a806d00,
	0x004d84878,
	0x005324878,
	0x00040486e,
	0x084fa2f00,
	0x02f400150,
	0x0610023b2,
	0x02f2f0150,
	0x061002380,
	0x084ea2f00,
	0x02f400154,
	0x061001492,
	0x02f2f0154,
	0x061001466,
	0x0102e8002,
	0x049c04fef,
	0x000407241,
	0x0b2006700,
	0x004727261,
	0x004cc7261,
	0x0b2006700,
	0x0042e4878,
	0x004884878,
	0x00002486e,
	0x081bd6100,
	0x0237e2f40,
	0x001204aaf,
	0x00120508f,
	0x0145e2f40,
	0x001244aaf,
	0x00124508f,
	0x06c0a486e,
	0x081c46100,
	0x004c6588f,
	0x00520588f,
	0x0486e81d3,
	0x02f2f011c,
	0x061000488,
	0x02f2f0120,
	0x0610004e2,
	0x0486e81de,
	0x02f2f0124,
	0x06100047c,
	0x061002340,
	0x02f2f0128,
	0x0610004d6,
	0x061001420,
	0x04fef0010,
	0x072ffb280,
	0x0670003e0,
	0x06700043a,
	0x04281b280,
	0x0670003ca,
	0x02f2f0118,
	0x06100230c,
	0x0588f4878,
	0x067000424,
	0x02f2f011c,
	0x0610013f2,
	0x0588f42af,
	0x001084878,
	0x00002486e,
	0x081f46100,
	0x023224a80,
	0x013fe4a80,
	0x042e72f40,
	0x0011e44df,
	0x0012244df,
	0x06c0a486e,
	0x081fe6100,
	0x0046a588f,
	0x004c0588f,
	0x048780002,
	0x0486e8210,
	0x061002300,
	0x0610013dc,
	0x04a8042e7,
	0x02f40012a,
	0x02f40012e,
	0x044df6c0a,
	0x0486e8219,
	0x061000448,
	0x06100049e,
	0x0588f486e,
	0x084fa486e,
	0x084ea486e,
	0x0822a486f,
	0x000206100,
	0x005d6486f,
	0x000242f2f,
	0x001386100,
	0x003fa486e,
	0x084fa486e,
	0x082356100,
	0x004ee2f2f,
	0x001446100,
	0x02296486e,
	0x082466100,
	0x004de422e,
	0x0859e486f,
	0x0003c486e,
	0x0859e6100,
	0x013062f00,
	0x02f400150,
	0x0486f0048,
	0x02f2f0158,
	0x0610022a2,
	0x0b0af0158,
	0x0670a486e,
	0x0824d6100,
	0x003de588f,
	0x048780100,
	0x0486f0054,
	0x02f2f0164,
	0x061002276,
	0x024007002,
	0x0b082660a,
	0x00c2f004f,
	0x0005c6700,
	0x002cc4a82,
	0x042e72f42,
	0x0016644df,
	0x06e0e486e,
	0x082576100,
	0x003a6242f,
	0x00168588f,
	0x02f02486e,
	0x0859e486f,
	0x000646100,
	0x01a404a80,
	0x06638102f,
	0x0006b49c0,
	0x02f00102f,
	0x0006e49c0,
	0x02f00102f,
	0x0007149c0,
	0x02f00102f,
	0x0007449c0,
	0x02f002f2f,
	0x00180486e,
	0x082606100,
	0x00432486e,
	0x082836100,
	0x0035a4fef,
	0x0001c0c2e,
	0x00001859e,
	0x0670a486e,
	0x0828e6100,
	0x00346588f,
	0x0486e8297,
	0x06100040c,
	0x01d7c0002,
	0x0859e1d7c,
	0x0007685a8,
	0x0486f006c,
	0x0486e859e,
	0x06100122c,
	0x0062a486f,
	0x000246100,
	0x0136c2f00,
	0x02f400138,
	0x0486f002c,
	0x02f2f0144,
	0x0610013ae,
	0x0b0af0140,
	0x06600036a,
	0x0486e84ea,
	0x0486e825a,
	0x06100052c,
	0x02f2f0150,
	0x061001362,
	0x0486e826b,
	0x06100051c,
	0x01d7c0032,
	0x0858e3d7c,
	0x0ffff8592,
	0x0486f0044,
	0x0486e858e,
	0x06100137e,
	0x02f002f40,
	0x00180486f,
	0x000782f2f,
	0x001886100,
	0x021c8b0af,
	0x00188670a,
	0x0486e82a2,
	0x061000304,
	0x0015c486f,
	0x000502f2f,
	0x001646100,
	0x01360b0af,
	0x00164670a,
	0x0486e8272,
	0x061000416,
	0x0588f4878,
	0x00100486f,
	0x000842f2f,
	0x001946100,
	0x0219c2f40,
	0x001944aaf,
	0x001946e0a,
	0x0486e82b0,
	0x0610002e0,
	0x0588f2f2f,
	0x00194486e,
	0x0859e486f,
	0x000946100,
	0x0197c4a80,
	0x0660a486e,
	0x082bd6100,
	0x002c2588f,
	0x00c2e0003,
	0x0859e670a,
	0x0486e82cc,
	0x0610002b0,
	0x0588f4a6e,
	0x085a2671c,
	0x0302e85a2,
	0x048c02f00,
	0x0486e82d9,
	0x061000368,
	0x0486e82e3,
	0x061000290,
	0x04fef000c,
	0x0486e82f0,
	0x061000354,
	0x0486e82fe,
	0x0486e82f8,
	0x0486f00a4,
	0x061000414,
	0x0005c2f2f,
	0x001706100,
	0x013342400,
	0x07002b082,
	0x0660a0c2f,
	0x0004f0064,
	0x0670002ce,
	0x04a8242e7,
	0x02f420172,
	0x044df6e0e,
	0x0486e827c,
	0x0610003de,
	0x0242f0174,
	0x0588f2f02,
	0x0486e858e,
	0x0486f006c,
	0x061001ace,
	0x04a806638,
	0x0102f0073,
	0x049c02f00,
	0x0102f0076,
	0x049c02f00,
	0x0102f0079,
	0x049c02f00,
	0x0102f007c,
	0x049c02f00,
	0x02f2f018c,
	0x0486e8285,
	0x061000468,
	0x0486e82a8,
	0x061000392,
	0x04fef001c,
	0x00c2e0033,
	0x0858e670a,
	0x0486e82b3,
	0x06100037e,
	0x0588f486e,
	0x082bc6100,
	0x004421d7c,
	0x00034858e,
	0x03d7cffff,
	0x08592486f,
	0x00074486e,
	0x0858e6100,
	0x012a42f00,
	0x02f40018c,
	0x0486f0080,
	0x02f2f0194,
	0x061001286,
	0x0b0af0194,
	0x0670a486e,
	0x082c76100,
	0x0033c588f,
	0x048780100,
	0x0486f008c,
	0x02f2f01a0,
	0x06100125a,
	0x02f4001a0,
	0x04aaf01a0,
	0x06e0a486e,
	0x082d56100,
	0x00318588f,
	0x02f2f01a0,
	0x0486e858e,
	0x0486f009c,
	0x061001a0a,
	0x04a80660a,
	0x0486e82e2,
	0x0610002fa,
	0x0588f0c2e,
	0x00037858e,
	0x06618486e,
	0x08594486e,
	0x082f16100,
	0x003b2486e,
	0x085946100,
	0x002dc4fef,
	0x0000c0c2e,
	0x00035858e,
	0x0670a486e,
	0x082fb6100,
	0x002c8588f,
	0x0486e8308,
	0x06100038c,
	0x0486e8316,
	0x0486e8310,
	0x0486f00ac,
	0x06100044c,
	0x0487801b6,
	0x048780001,
	0x0486f00b0,
	0x0610020ea,
	0x0486f00b8,
	0x0610011b0,
	0x04a8042e7,
	0x02f4001b6,
	0x02f4001c2,
	0x044df6c0a,
	0x0486e8305,
	0x061000250,
	0x0486e831d,
	0x06100028a,
	0x0588f2f2f,
	0x001c0486e,
	0x0830c486f,
	0x000bc6100,
	0x003de486f,
	0x000c06100,
	0x01120588f,
	0x001cc486e,
	0x08324486f,
	0x000c46100,
	0x00416486f,
	0x000c86100,
	0x01158588f,
	0x02f00486f,
	0x000c42f2f,
	0x001c86100,
	0x020dc2f00,
	0x0486f00d0,
	0x061001106,
	0x000cc2f2f,
	0x001d46100,
	0x0119c2f00,
	0x0486f00d8,
	0x06100113e,
	0x0588f221f,
	0x0b280670a,
	0x0486e830f,
	0x06100020c,
	0x0486e8327,
	0x061000246,
	0x0588f2f2f,
	0x001cc6100,
	0x02082486e,
	0x0831b486e,
	0x08315486f,
	0x000d86100,
	0x003924878,
	0x001d86100,
	0x01148486e,
	0x08333486e,
	0x0832d486f,
	0x000e06100,
	0x003ca4878,
	0x001b64878,
	0x00001486e,
	0x083226100,
	0x020684a80,
	0x0833a6100,
	0x0112e4a80,
	0x042e72f40,
	0x001ea44df,
	0x001f644df,
	0x06c0a486e,
	0x0832a6100,
	0x001ce588f,
	0x02f2f01f4,
	0x0486e8331,
	0x0486f00f0,
	0x06100035c,
	0x0486f00f4,
	0x06100109e,
	0x0588f2f00,
	0x083426100,
	0x00208588f,
	0x02f2f0200,
	0x0486e8349,
	0x0486f00f8,
	0x02f2f01fc,
	0x06100205a,
	0x061000394,
	0x0486f00fc,
	0x0610010d6,
	0x0588f2f00,
	0x0486f0100,
	0x02f2f0208,
	0x06100111a,
	0x02f00486f,
	0x001046100,
	0x01084588f,
	0x0010c6100,
	0x010bc588f,
	0x0221fb280,
	0x0670a486e,
	0x083346100,
	0x0018a588f,
	0x02f2f0200,
	0x061002000,
	0x0486e833a,
	0x061000248,
	0x0834c6100,
	0x001c4588f,
	0x02f2f020c,
	0x0610010c6,
	0x0486e8352,
	0x061000280,
	0x042a7486e,
	0x08345486e,
	0x083436100,
	0x0106c4a80,
	0x0835d486e,
	0x0835b6100,
	0x010a44a80,
	0x06c0a486e,
	0x083476100,
	0x0015e588f,
	0x0486e834e,
	0x0835f6100,
	0x00198588f,
	0x0486e8367,
	0x0486e8366,
	0x048780006,
	0x0486e834c,
	0x02f2f022c,
	0x061001fe6,
	0x0486e8364,
	0x02f2f023c,
	0x0610010a2,
	0x04a806c0a,
	0x0486e834f,
	0x06100013c,
	0x0486e8368,
	0x061000172,
	0x0588f486e,
	0x083556100,
	0x002024878,
	0x0836e6100,
	0x002364878,
	0x00020486e,
	0x085e66100,
	0x00fd84a80,
	0x0860a6100,
	0x0100c4a80,
	0x0672042a7,
	0x0486e836f,
	0x0486e836a,
	0x0486e835e,
	0x061000f22,
	0x0486e8388,
	0x0486e8383,
	0x061000108,
	0x04fef0258,
	0x0486e8377,
	0x061000f56,
	0x0486e839c,
	0x06100013e,
	0x04fef0268,
	0x04e7542a7,
	0x0486e837e,
	0x0486e8372,
	0x061000f06,
	0x0486e8397,
	0x0486e838b,
	0x061000f3a,
	0x0598f60e0,
	0x00c2f004b,
	0x0005d6600,
	0x0fd2e4878,
	0x000656600,
	0x0fd2c4878,
	0x00100486f,
	0x000602f2f,
	0x001706100,
	0x01f802400,
	0x000682f2f,
	0x0017c6100,
	0x0103c2400,
	0x04fef000c,
	0x06000fd14,
	0x048790000,
	0x0ea606100,
	0x01f72588f,
	0x060f26000,
	0x0fc324878,
	0x00002486e,
	0x0818b6100,
	0x01f522f40,
	0x001204aaf,
	0x001206c0a,
	0x0486e8197,
	0x06100009c,
	0x06000fd12,
	0x07005b0af,
	0x00134660a,
	0x0486e8235,
	0x0610000f2,
	0x0588f486e,
	0x081ab2f2f,
	0x00124615e,
	0x0486e81b2,
	0x02f2f012c,
	0x061544fef,
	0x000186000,
	0x0fbbc4878,
	0x00002486e,
	0x0815a6100,
	0x01f162f40,
	0x001204aaf,
	0x001206c08,
	0x0486e8166,
	0x06160588f,
	0x0486e817a,
	0x02f2f0124,
	0x06124486e,
	0x081802f2f,
	0x0012c611a,
	0x0823d6100,
	0x001b62f2f,
	0x001486100,
	0x00fec2f2f,
	0x001506100,
	0x00fe452af,
	0x001404fef,
	0x000386000,
	0x0fbee4879,
	0x00000ea60,
	0x061000ff8,
	0x0588f60f2,
	0x06000fbd8,
	0x048780002,
	0x0486e818b,
	0x061000fd8,
	0x02f400124,
	0x04aaf0124,
	0x06c0a486e,
	0x081976100,
	0x0009c588f,
	0x0486e81ab,
	0x02f2f0128,
	0x0615e486e,
	0x081b22f2f,
	0x001306154,
	0x04fef0018,
	0x06000fb82,
	0x0486e8156,
	0x0486e84fa,
	0x061000f10,
	0x0518f6000,
	0x0fb34598f,
	0x02f2f000c,
	0x061000f12,
	0x02f002f40,
	0x000082f2f,
	0x000142f2f,
	0x000146100,
	0x01eccb0af,
	0x000106708,
	0x02f2f001c,
	0x06108588f,
	0x04fef0014,
	0x04e754fef,
	0x0ffc04857,
	0x042a76100,
	0x01e82486f,
	0x000082f2f,
	0x00050486e,
	0x0838f4878,
	0x06000fb62,
	0x048780002,
	0x0486e815a,
	0x061000f9c,
	0x02f400124,
	0x04aaf0124,
	0x06c08486e,
	0x081666160,
	0x0588f486e,
	0x0817a2f2f,
	0x001286124,
	0x0486e8180,
	0x02f2f0130,
	0x0611a4fef,
	0x000186000,
	0x0fb28486e,
	0x08156486e,
	0x084ea6100,
	0x00f0e518f,
	0x06000fada,
	0x0598f2f2f,
	0x0000c6100,
	0x00f102f00,
	0x02f400008,
	0x02f2f0014,
	0x02f2f0014,
	0x061000f52,
	0x0b0af0010,
	0x067082f2f,
	0x0001c6108,
	0x0588f4fef,
	0x000144e75,
	0x04fefffc0,
	0x048576100,
	0x00f3a486f,
	0x000042f2f,
	0x0004c486e,
	0x083a84878,
	0x000026100,
	0x0011a42a7,
	0x061744fef,
	0x0005c4e75,
	0x000584e75,
	0x0598f4281,
	0x07021b081,
	0x06f1e4ab6,
	0x01d208476,
	0x01d208466,
	0x0660e2daf,
	0x000081d20,
	0x084767001,
	0x084667001,
	0x0588f4e75,
	0x052817021,
	0x0b0816ee2,


@@ 403,30 425,30 @@ ulong bootcode[]={
	0x042827021,
	0x0b0826f18,
	0x020362d20,
	0x08476b088,
	0x08466b088,
	0x0660642b6,
	0x02d208476,
	0x02d208466,
	0x052827021,
	0x0b0826ee8,
	0x0588f4e75,
	0x04aaf0004,
	0x0660642a7,
	0x0610c588f,
	0x0486e83be,
	0x0486e844e,
	0x06104588f,
	0x04e75518f,
	0x072204a81,
	0x06d222eb6,
	0x01d208476,
	0x01d208466,
	0x04a976712,
	0x02f410004,
	0x042b61d20,
	0x084764eb7,
	0x084664eb7,
	0x00151222f,
	0x000045381,
	0x04a816cde,
	0x02f2f000c,
	0x061001db2,
	0x061000e40,
	0x04fef000c,
	0x04e754fef,
	0x0eff841ef,


@@ 442,7 464,7 @@ ulong bootcode[]={
	0x092882f01,
	0x0486f001c,
	0x048780001,
	0x061001dae,
	0x061000e36,
	0x0240042e7,
	0x02f40001e,
	0x044df6c1a,


@@ 468,7 490,7 @@ ulong bootcode[]={
	0x092882f01,
	0x0486f001c,
	0x02f2f1024,
	0x061001d46,
	0x061000dce,
	0x0240042e7,
	0x02f40001e,
	0x044df6c1a,


@@ 1280,7 1302,7 @@ ulong bootcode[]={
	0x041ef0004,
	0x058882f08,
	0x02f2f0008,
	0x061001072,
	0x0610000fa,
	0x0508f4e75,
	0x0518ff22f,
	0x0543a000c,


@@ 1338,35 1360,114 @@ ulong bootcode[]={
	0x020094e75,
	0x070004e75,
	0x070024e40,
	0x04e75598f,
	0x0226f0008,
	0x0206f000c,
	0x010d11011,
	0x049c04201,
	0x0b0016d00,
	0x005f07227,
	0x0b0016e00,
	0x005e83036,
	0x00b2083d6,
	0x04efb0000,
	0x0200890af,
	0x0000c588f,
	0x04e753029,
	0x04e757008,
	0x04e404e75,
	0x070044e40,
	0x04e757016,
	0x04e404e75,
	0x070074e40,
	0x04e757009,
	0x04e404e75,
	0x0700d4e40,
	0x04e75700e,
	0x04e404e75,
	0x0700f4e40,
	0x04e757011,
	0x04e404e75,
	0x070144e40,
	0x04e757001,
	0x04e404e75,
	0x0598f226f,
	0x00008206f,
	0x0000c10d1,
	0x030290004,
	0x010803029,
	0x0000448c0,
	0x0e0801140,
	0x000015488,
	0x0101149c0,
	0x07232b001,
	0x06d0005d4,
	0x0724fb001,
	0x06e0005cc,
	0x030360b20,
	0x083724efb,
	0x000002008,
	0x090af000c,
	0x0588f4e75,
	0x030290002,
	0x010803029,
	0x0000248c0,
	0x0e0801140,
	0x000015488,
	0x060e03029,
	0x000021080,
	0x030290002,
	0x048c0e080,
	0x011400001,
	0x054883029,
	0x000041080,
	0x030290004,
	0x054884878,
	0x000744869,
	0x000062f08,
	0x02f48000c,
	0x061000ecc,
	0x0206f000c,
	0x07074d1c0,
	0x04fef000c,
	0x060ac3029,
	0x000021080,
	0x030290002,
	0x048c0e080,
	0x011400001,
	0x054882029,
	0x0000a1080,
	0x02029000a,
	0x054884878,
	0x000744869,
	0x000062f08,
	0x02f48000c,
	0x061000e98,
	0x0206f000c,
	0x07074d1c0,
	0x04fef000c,
	0x06000ff78,
	0x030290002,
	0x010803029,
	0x0000248c0,
	0x0e0801140,
	0x000015488,
	0x06000ff60,
	0x030290002,
	0x010803029,
	0x0000248c0,
	0x0e0801140,
	0x000015488,
	0x06000ff48,
	0x030290002,
	0x010803029,
	0x0000248c0,
	0x0e0801140,
	0x000015488,
	0x06000ff30,
	0x030290002,
	0x010803029,
	0x0000248c0,
	0x0e0801140,
	0x000015488,
	0x06000ff18,
	0x030290002,
	0x010803029,
	0x0000248c0,
	0x0e0801140,
	0x000015488,
	0x06000ff00,
	0x030290002,
	0x010803029,
	0x0000248c0,
	0x0e0801140,
	0x000015488,
	0x060ba3029,
	0x02029000a,
	0x010802029,
	0x0000ae080,
	0x011400001,
	0x054886000,
	0x0fed63029,
	0x000021080,
	0x030290002,
	0x048c0e080,


@@ 1395,22 1496,17 @@ ulong bootcode[]={
	0x02f29000e,
	0x02f082f48,
	0x0000c6100,
	0x00df2206f,
	0x00d72206f,
	0x0000c2037,
	0x001620014,
	0x0000ad1c0,
	0x04fef000c,
	0x06000ff32,
	0x06000fe4c,
	0x030290002,
	0x010803029,
	0x0000248c0,
	0x0e0801140,
	0x000015488,
	0x030290004,
	0x010803029,
	0x0000448c0,
	0x0e0801140,
	0x000015488,
	0x02029000a,
	0x010802029,
	0x0000ae080,


@@ 1420,12 1516,12 @@ ulong bootcode[]={
	0x02f29000e,
	0x02f082f48,
	0x0000c6100,
	0x00d8e206f,
	0x00d22206f,
	0x0000c2037,
	0x001620014,
	0x0000ad1c0,
	0x04fef000c,
	0x06000fece,
	0x06000fdfc,
	0x030290002,
	0x010803029,
	0x0000248c0,


@@ 1450,116 1546,121 @@ ulong bootcode[]={
	0x02029000a,
	0x0e0801140,
	0x000015488,
	0x06000fe6a,
	0x06000fd98,
	0x030290002,
	0x010803029,
	0x0000248c0,
	0x0e0801140,
	0x000015488,
	0x030290004,
	0x02029000a,
	0x010802029,
	0x0000ae088,
	0x011400001,
	0x02029000a,
	0x07210e2a8,
	0x011400002,
	0x02029000a,
	0x07218e2a8,
	0x011400003,
	0x058882029,
	0x0000e1080,
	0x02029000e,
	0x0e0881140,
	0x000012029,
	0x0000e7210,
	0x0e2a81140,
	0x000022029,
	0x0000e7218,
	0x0e2a81140,
	0x000035888,
	0x06000fd2c,
	0x030290002,
	0x010803029,
	0x0000448c0,
	0x0000248c0,
	0x0e0801140,
	0x000015488,
	0x04878001c,
	0x048690006,
	0x04869000a,
	0x02f082f48,
	0x0000c6100,
	0x00cda206f,
	0x00c16226f,
	0x00014206f,
	0x0000c701c,
	0x0d1c04fef,
	0x0000c6000,
	0x0fe203029,
	0x000021080,
	0x030290002,
	0x048c0e080,
	0x011400001,
	0x054883029,
	0x0d1c02029,
	0x000061080,
	0x030290006,
	0x048c0e080,
	0x011400001,
	0x054886000,
	0x0fdf43029,
	0x000021080,
	0x030290002,
	0x048c0e080,
	0x011400001,
	0x054883029,
	0x000041080,
	0x030290004,
	0x048c0e080,
	0x011400001,
	0x054884878,
	0x000404869,
	0x000062f08,
	0x02f48000c,
	0x061000c64,
	0x0206f000c,
	0x07040d1c0,
	0x020290006,
	0x0e0801140,
	0x000012029,
	0x000067210,
	0x0e2a01140,
	0x000022029,
	0x000067218,
	0x0e2a01140,
	0x000035888,
	0x010e90026,
	0x04fef000c,
	0x06000fdaa,
	0x06000fcc4,
	0x030290002,
	0x010803029,
	0x0000248c0,
	0x0e0801140,
	0x000015488,
	0x030290004,
	0x010803029,
	0x0000448c0,
	0x0e0801140,
	0x000015488,
	0x06000fd7e,
	0x02029000a,
	0x010802029,
	0x0000ae088,
	0x011400001,
	0x02029000a,
	0x07210e2a8,
	0x011400002,
	0x02029000a,
	0x07218e2a8,
	0x011400003,
	0x058882029,
	0x0000e1080,
	0x02029000e,
	0x0e0881140,
	0x000012029,
	0x0000e7210,
	0x0e2a81140,
	0x000022029,
	0x0000e7218,
	0x0e2a81140,
	0x000035888,
	0x06000fc58,
	0x030290002,
	0x010803029,
	0x0000248c0,
	0x0e0801140,
	0x000015488,
	0x030290004,
	0x010803029,
	0x0000448c0,
	0x0e0801140,
	0x000015488,
	0x06000fd52,
	0x010e90026,
	0x06000fc3c,
	0x030290002,
	0x010803029,
	0x0000248c0,
	0x0e0801140,
	0x000015488,
	0x048780040,
	0x048690006,
	0x02f082f48,
	0x0000c6100,
	0x00bd6206f,
	0x0000c7040,
	0x0d1c04fef,
	0x0000c6000,
	0x0fd1c3029,
	0x000021080,
	0x030290002,
	0x048c0e080,
	0x011400001,
	0x054883029,
	0x000041080,
	0x030290004,
	0x048c0e080,
	0x02029000a,
	0x010802029,
	0x0000ae088,
	0x011400001,
	0x054884878,
	0x000404869,
	0x000062f08,
	0x02f48000c,
	0x061000b8c,
	0x0206f000c,
	0x07040d1c0,
	0x04fef000c,
	0x06000fcd2,
	0x030290002,
	0x010803029,
	0x0000248c0,
	0x0e0801140,
	0x000015488,
	0x06000fcba,
	0x06000ff3a,
	0x02029000a,
	0x07210e2a8,
	0x011400002,
	0x02029000a,
	0x07218e2a8,
	0x011400003,
	0x058882029,
	0x0000e1080,
	0x02029000e,
	0x0e0881140,
	0x000012029,
	0x0000e7210,
	0x0e2a81140,
	0x000022029,
	0x0000e7218,
	0x0e2a81140,
	0x000035888,
	0x06000fbd0,
	0x030290002,
	0x010803029,
	0x0000248c0,


@@ 1569,275 1670,223 @@ ulong bootcode[]={
	0x04869000a,
	0x02f082f48,
	0x0000c6100,
	0x00b3a206f,
	0x00aba206f,
	0x0000c701c,
	0x0d1c04fef,
	0x0000c6000,
	0x0fc8060c4,
	0x060aa6000,
	0x0fc823029,
	0x0fb9a3029,
	0x000021080,
	0x030290002,
	0x048c0e080,
	0x011400001,
	0x054882029,
	0x054886000,
	0x0fb823029,
	0x000021080,
	0x030290002,
	0x048c0e080,
	0x011400001,
	0x054883029,
	0x000061080,
	0x020290006,
	0x0e0801140,
	0x000012029,
	0x000067210,
	0x0e2a01140,
	0x000022029,
	0x000067218,
	0x0e2a01140,
	0x000034228,
	0x000044228,
	0x000054228,
	0x000064228,
	0x000075088,
	0x02029000a,
	0x010802029,
	0x0000ae080,
	0x030290006,
	0x048c0e080,
	0x011400001,
	0x054882f29,
	0x0000a2f29,
	0x0000e2f08,
	0x02f48000c,
	0x061000ab0,
	0x0206f000c,
	0x020370162,
	0x00014000a,
	0x0d1c04fef,
	0x0000c6000,
	0x0fbf03029,
	0x054886000,
	0x0fb563029,
	0x000021080,
	0x030290002,
	0x048c0e080,
	0x011400001,
	0x054883029,
	0x000041080,
	0x030290004,
	0x048c0e080,
	0x011400001,
	0x054882029,
	0x0000a1080,
	0x02029000a,
	0x0e0801140,
	0x000015488,
	0x02f29000a,
	0x02f29000e,
	0x02f082f48,
	0x0000c6100,
	0x00a4e206f,
	0x0000c2037,
	0x001620014,
	0x0000ad1c0,
	0x04fef000c,
	0x06000fb8e,
	0x06000fcbe,
	0x030290002,
	0x010803029,
	0x0000248c0,
	0x0e0801140,
	0x000015488,
	0x030290004,
	0x010803029,
	0x0000448c0,
	0x0e0801140,
	0x000015488,
	0x02029000c,
	0x0e0881140,
	0x000012029,
	0x0000a7210,
	0x0e2a81140,
	0x000022029,
	0x0000a7218,
	0x0e2a81140,
	0x000035888,
	0x02029000e,
	0x010802029,
	0x0000ce088,
	0x0000ee088,
	0x011400001,
	0x02029000c,
	0x02029000e,
	0x07210e2a8,
	0x011400002,
	0x02029000c,
	0x02029000e,
	0x07218e2a8,
	0x011400003,
	0x058886000,
	0x0fb343029,
	0x0faea3029,
	0x000021080,
	0x030290002,
	0x048c0e080,
	0x011400001,
	0x054884878,
	0x0001c4869,
	0x0000a2f08,
	0x000062f08,
	0x02f48000c,
	0x0610009b8,
	0x0226f0014,
	0x0206f000c,
	0x0610009d4,
	0x0701cd1af,
	0x0000c4878,
	0x0001c4877,
	0x001620018,
	0x000222f2f,
	0x000146100,
	0x009ba701c,
	0x0d1af0018,
	0x04878001c,
	0x048770162,
	0x00024003e,
	0x02f2f0020,
	0x0610009a0,
	0x0206f0024,
	0x0701cd1c0,
	0x020290006,
	0x010802029,
	0x00006e080,
	0x011400001,
	0x020290006,
	0x07210e2a0,
	0x011400002,
	0x020290006,
	0x07218e2a0,
	0x011400003,
	0x0588810e9,
	0x000264fef,
	0x0000c6000,
	0x0facc6000,
	0x0ff403029,
	0x000021080,
	0x030290002,
	0x048c0e080,
	0x011400001,
	0x0548810e9,
	0x000266000,
	0x0faac60de,
	0x06000fdf2,
	0x06000fe24,
	0x030290002,
	0x010803029,
	0x0000248c0,
	0x0e0801140,
	0x000015488,
	0x04fef0024,
	0x06000fa80,
	0x06000fa7c,
	0x030290008,
	0x010803029,
	0x0000848c0,
	0x0e0801140,
	0x000015488,
	0x06000fa76,
	0x030290002,
	0x010803029,
	0x0000248c0,
	0x0e0801140,
	0x000015488,
	0x04878001c,
	0x06000fa64,
	0x048780040,
	0x048690006,
	0x02f082f48,
	0x0000c6100,
	0x008fa701c,
	0x0d1af000c,
	0x04878001c,
	0x048770162,
	0x000180022,
	0x02f2f0014,
	0x0610008e0,
	0x0206f0018,
	0x0701cd1c0,
	0x04fef0018,
	0x06000fa26,
	0x0101149c0,
	0x02f00486e,
	0x0839e6100,
	0x0ebb64280,
	0x04fef000c,
	0x04e753029,
	0x000041080,
	0x030290004,
	0x048c0e080,
	0x011400001,
	0x054886000,
	0x0f9f810e9,
	0x0000a6000,
	0x0f9f06000,
	0x0f9ec60fa,
	0x00962206f,
	0x0000c7040,
	0x0d1c04fef,
	0x0000c6000,
	0x0fa421011,
	0x049c02f00,
	0x0486e83b6,
	0x06100eb7c,
	0x042804fef,
	0x0000c4e75,
	0x06000fa28,
	0x06000fa24,
	0x06000fa20,
	0x06000fa1c,
	0x0598f206f,
	0x0000c4878,
	0x0001c2f2f,
	0x0000c2f08,
	0x02f48000c,
	0x06100087c,
	0x0226f0014,
	0x0206f000c,
	0x061000914,
	0x0701cd1af,
	0x0000c4878,
	0x0001c4877,
	0x001620018,
	0x0001c2f2f,
	0x000146100,
	0x008fa701c,
	0x0d1af0018,
	0x04878001c,
	0x048770162,
	0x000240038,
	0x02f2f0020,
	0x0610008e0,
	0x0226f002c,
	0x0206f0024,
	0x0701cd1c0,
	0x02029001c,
	0x020290054,
	0x010802029,
	0x0001ce080,
	0x00054e088,
	0x011400001,
	0x02029001c,
	0x07210e2a0,
	0x020290054,
	0x07210e2a8,
	0x011400002,
	0x02029001c,
	0x07218e2a0,
	0x020290054,
	0x07218e2a8,
	0x011400003,
	0x058885888,
	0x020290024,
	0x058882029,
	0x000581080,
	0x020290058,
	0x0e0881140,
	0x000012029,
	0x000587210,
	0x0e2a81140,
	0x000022029,
	0x000587218,
	0x0e2a81140,
	0x000035888,
	0x02029005c,
	0x010802029,
	0x00024e080,
	0x0005ce088,
	0x011400001,
	0x020290024,
	0x07210e2a0,
	0x02029005c,
	0x07210e2a8,
	0x011400002,
	0x020290024,
	0x07218e2a0,
	0x02029005c,
	0x07218e2a8,
	0x011400003,
	0x058882029,
	0x000281080,
	0x020290028,
	0x000601080,
	0x020290060,
	0x0e0801140,
	0x000012029,
	0x000287210,
	0x000607210,
	0x0e2a01140,
	0x000022029,
	0x000287218,
	0x000607218,
	0x0e2a01140,
	0x000035888,
	0x02029002c,
	0x020290064,
	0x010802029,
	0x0002ce080,
	0x00064e080,
	0x011400001,
	0x02029002c,
	0x020290064,
	0x07210e2a0,
	0x011400002,
	0x02029002c,
	0x020290064,
	0x07218e2a0,
	0x011400003,
	0x058882029,
	0x000341080,
	0x020290034,
	0x0006c1080,
	0x02029006c,
	0x0e0801140,
	0x000012029,
	0x000347210,
	0x0006c7210,
	0x0e2a01140,
	0x000022029,
	0x000347218,
	0x0006c7218,
	0x0e2a01140,
	0x000034228,
	0x000044228,
	0x000054228,
	0x000064228,
	0x000075088,
	0x030290038,
	0x010803029,
	0x0003848c0,
	0x0e0801140,
	0x000015488,
	0x03029003a,
	0x030290070,
	0x010803029,
	0x0003a48c0,
	0x0007048c0,
	0x0e0801140,
	0x000015488,
	0x030290020,
	0x030290072,
	0x010803029,
	0x0002048c0,
	0x0e0801140,
	0x000015488,
	0x030290022,
	0x010803029,
	0x0002248c0,
	0x0007248c0,
	0x0e0801140,
	0x000015488,
	0x0200890af,
	0x000184fef,
	0x000104e75,
	0x000304fef,
	0x000284e75,
	0x0598f226f,
	0x0000c206f,
	0x000081298,
	0x042801010,
	0x042811228,
	0x00001e181,
	0x080813340,
	0x000045488,
	0x0101149c0,
	0x04201b001,
	0x06d00057e,
	0x07227b001,
	0x06e000576,
	0x07232b001,
	0x06d0005ae,
	0x0724fb001,
	0x06e0005a6,
	0x030360b20,
	0x084264efb,
	0x083ae4efb,
	0x00000202f,
	0x00008d0af,
	0x00010b088,


@@ 1850,207 1899,74 @@ ulong bootcode[]={
	0x00001e181,
	0x080813340,
	0x000025488,
	0x042801010,
	0x042811228,
	0x00001e181,
	0x080813340,
	0x000045488,
	0x042801010,
	0x042811228,
	0x00001e181,
	0x080812340,
	0x0000a5488,
	0x060a84280,
	0x010104281,
	0x012280001,
	0x0e1818081,
	0x033400002,
	0x054884280,
	0x010104281,
	0x012280001,
	0x0e1818081,
	0x042811228,
	0x000027410,
	0x0e5a18081,
	0x042811228,
	0x000037418,
	0x0e5a18081,
	0x023400006,
	0x050884280,
	0x010104281,
	0x012280001,
	0x0e1818081,
	0x02340000a,
	0x054885288,
	0x02348000e,
	0x02029000a,
	0x0d1c06000,
	0x0ff464280,
	0x010104281,
	0x012280001,
	0x0e1818081,
	0x033400002,
	0x054884280,
	0x010104281,
	0x012280001,
	0x0e1818081,
	0x033400004,
	0x054884280,
	0x010104281,
	0x012280001,
	0x0e1818081,
	0x02340000a,
	0x054885288,
	0x02348000e,
	0x02029000a,
	0x0d1c06000,
	0x0fefa4280,
	0x060d04280,
	0x010104281,
	0x012280001,
	0x0e1818081,
	0x033400002,
	0x054884280,
	0x010104281,
	0x012280001,
	0x0e1818081,
	0x042811228,
	0x000027410,
	0x0e5a18081,
	0x042811228,
	0x000037418,
	0x0e5a18081,
	0x023400006,
	0x050884280,
	0x010104281,
	0x012280001,
	0x0e1818081,
	0x02340000a,
	0x054886000,
	0x0fea24280,
	0x054884878,
	0x000742f08,
	0x02f480008,
	0x048690006,
	0x061000700,
	0x0206f000c,
	0x07074d1c0,
	0x04fef000c,
	0x0609c4280,
	0x010104281,
	0x012280001,
	0x0e1818081,
	0x033400002,
	0x054884280,
	0x010104281,
	0x012280001,
	0x0e1818081,
	0x033400004,
	0x054884878,
	0x0001c2f08,
	0x000742f08,
	0x02f480008,
	0x048690006,
	0x06100056c,
	0x0610006cc,
	0x0206f000c,
	0x0701cd1c0,
	0x07074d1c0,
	0x04fef000c,
	0x06000fe58,
	0x06000ff68,
	0x042801010,
	0x042811228,
	0x00001e181,
	0x080813340,
	0x000025488,
	0x06000ff50,
	0x042801010,
	0x042811228,
	0x00001e181,
	0x080813340,
	0x000065488,
	0x06000fe2c,
	0x000025488,
	0x06000ff38,
	0x042801010,
	0x042811228,
	0x00001e181,
	0x080813340,
	0x000025488,
	0x06000ff20,
	0x042801010,
	0x042811228,
	0x00001e181,
	0x080813340,
	0x000045488,
	0x048780040,
	0x02f082f48,
	0x000084869,
	0x000066100,
	0x004f6206f,
	0x0000c7040,
	0x0d1c04fef,
	0x0000c6000,
	0x0fde24280,
	0x010104281,
	0x012280001,
	0x0e1818081,
	0x033400002,
	0x054884280,
	0x010104281,
	0x012280001,
	0x0e1818081,
	0x033400004,
	0x054886000,
	0x0fdb64280,
	0x010104281,
	0x012280001,
	0x0e1818081,
	0x033400002,
	0x054884280,
	0x010104281,
	0x012280001,
	0x0e1818081,
	0x033400004,
	0x054886000,
	0x0fd8a4280,
	0x010104281,
	0x012280001,
	0x0e1818081,
	0x033400002,
	0x054884878,
	0x000402f08,
	0x02f480008,
	0x048690006,
	0x061000468,
	0x0206f000c,
	0x07040d1c0,
	0x04fef000c,
	0x06000fd54,
	0x000025488,
	0x06000ff08,
	0x042801010,
	0x042811228,
	0x00001e181,
	0x080813340,
	0x000025488,
	0x06000fef0,
	0x042801010,
	0x042811228,
	0x00001e181,
	0x080813340,
	0x000045488,
	0x048780040,
	0x02f082f48,
	0x000084869,
	0x000066100,
	0x0041e206f,
	0x0000c7040,
	0x0d1c04fef,
	0x0000c6000,
	0x0fd0a4280,
	0x010104281,
	0x012280001,
	0x0e1818081,
	0x033400002,
	0x054886000,
	0x0fcf26000,
	0x0ff3a4280,
	0x010104281,
	0x012280001,
	0x0e1818081,
	0x033400002,
	0x054884878,
	0x0001c2f08,
	0x02f480008,
	0x04869000a,
	0x0610003cc,
	0x0206f000c,
	0x0701cd1c0,
	0x04fef000c,
	0x06000fcb8,
	0x060c460aa,
	0x06000fcca,
	0x000025488,
	0x042801010,
	0x042811228,
	0x00001e181,
	0x080812340,
	0x0000a5488,
	0x06000fec4,
	0x042801010,
	0x042811228,
	0x00001e181,


@@ 2072,29 1988,46 @@ ulong bootcode[]={
	0x00001e181,
	0x080812340,
	0x0000a5488,
	0x02348000e,
	0x02029000a,
	0x0d1c06000,
	0x0fc4e4280,
	0x010104281,
	0x012280001,
	0x0e1818081,
	0x033400002,
	0x054884280,
	0x010104281,
	0x012280001,
	0x0e1818081,
	0x033400004,
	0x054884280,
	0x010104281,
	0x012280001,
	0x0e1818081,
	0x02340000a,
	0x054882348,
	0x052882348,
	0x0000e2029,
	0x0000ad1c0,
	0x06000fe60,
	0x042801010,
	0x042811228,
	0x00001e181,
	0x080813340,
	0x000025488,
	0x042801010,
	0x042811228,
	0x00001e181,
	0x080812340,
	0x0000a5488,
	0x052882348,
	0x0000e2029,
	0x0000ad1c0,
	0x06000fc04,
	0x06000fd08,
	0x06000fe28,
	0x042801010,
	0x042811228,
	0x00001e181,
	0x080813340,
	0x000025488,
	0x042801010,
	0x042811228,
	0x00001e181,
	0x080814281,
	0x012280002,
	0x07410e5a1,
	0x080814281,
	0x012280003,
	0x07418e5a1,
	0x080812340,
	0x000065088,
	0x042801010,
	0x042811228,
	0x00001e181,
	0x080812340,
	0x0000a5488,
	0x06000fdd0,
	0x042801010,
	0x042811228,
	0x00001e181,


@@ 2103,8 2036,14 @@ ulong bootcode[]={
	0x042801010,
	0x042811228,
	0x00001e181,
	0x080813340,
	0x000045488,
	0x080814281,
	0x012280002,
	0x07410e5a1,
	0x080814281,
	0x012280003,
	0x07418e5a1,
	0x080812340,
	0x0000a5888,
	0x042801010,
	0x042811228,
	0x00001e181,


@@ 2115,8 2054,8 @@ ulong bootcode[]={
	0x012280003,
	0x07418e5a1,
	0x080812340,
	0x0000c5888,
	0x06000fba8,
	0x0000e5888,
	0x06000fd60,
	0x042801010,
	0x042811228,
	0x00001e181,


@@ 2126,7 2065,7 @@ ulong bootcode[]={
	0x02f082f48,
	0x000084869,
	0x0000a6100,
	0x00286226f,
	0x0048e226f,
	0x00018206f,
	0x0000c701c,
	0x0d1c04280,


@@ 2143,17 2082,89 @@ ulong bootcode[]={
	0x058881358,
	0x000264fef,
	0x0000c6000,
	0x0fb3e6000,
	0x0ff3c4280,
	0x0fcf64280,
	0x010104281,
	0x012280001,
	0x0e1818081,
	0x033400002,
	0x054884280,
	0x010104281,
	0x012280001,
	0x0e1818081,
	0x042811228,
	0x000027410,
	0x0e5a18081,
	0x042811228,
	0x000037418,
	0x0e5a18081,
	0x02340000a,
	0x058884280,
	0x010104281,
	0x012280001,
	0x0e1818081,
	0x042811228,
	0x000027410,
	0x0e5a18081,
	0x042811228,
	0x000037418,
	0x0e5a18081,
	0x02340000e,
	0x058886000,
	0x0fc864280,
	0x010104281,
	0x012280001,
	0x0e1818081,
	0x033400002,
	0x054881358,
	0x000266000,
	0x0fb1e60de,
	0x06000fe2c,
	0x06000fe5e,
	0x0fc6a4280,
	0x010104281,
	0x012280001,
	0x0e1818081,
	0x033400002,
	0x054884280,
	0x010104281,
	0x012280001,
	0x0e1818081,
	0x042811228,
	0x000027410,
	0x0e5a18081,
	0x042811228,
	0x000037418,
	0x0e5a18081,
	0x02340000a,
	0x058884280,
	0x010104281,
	0x012280001,
	0x0e1818081,
	0x042811228,
	0x000027410,
	0x0e5a18081,
	0x042811228,
	0x000037418,
	0x0e5a18081,
	0x02340000e,
	0x058886000,
	0x0fbfa4280,
	0x010104281,
	0x012280001,
	0x0e1818081,
	0x033400002,
	0x054884878,
	0x0001c2f08,
	0x02f480008,
	0x04869000a,
	0x061000328,
	0x0206f000c,
	0x0701cd1c0,
	0x04fef000c,
	0x06000fbc4,
	0x042801010,
	0x042811228,
	0x00001e181,
	0x080813340,
	0x000025488,
	0x06000fbac,
	0x042801010,
	0x042811228,
	0x00001e181,


@@ 2163,8 2174,36 @@ ulong bootcode[]={
	0x042811228,
	0x00001e181,
	0x080813340,
	0x000085488,
	0x06000fae8,
	0x000065488,
	0x06000fb80,
	0x042801010,
	0x042811228,
	0x00001e181,
	0x080813340,
	0x000025488,
	0x042801010,
	0x042811228,
	0x00001e181,
	0x080814281,
	0x012280002,
	0x07410e5a1,
	0x080814281,
	0x012280003,
	0x07418e5a1,
	0x080812340,
	0x0000a5888,
	0x042801010,
	0x042811228,
	0x00001e181,
	0x080814281,
	0x012280002,
	0x07410e5a1,
	0x080814281,
	0x012280003,
	0x07418e5a1,
	0x080812340,
	0x0000e5888,
	0x06000fb10,
	0x042801010,
	0x042811228,
	0x00001e181,


@@ 2174,53 2213,71 @@ ulong bootcode[]={
	0x02f082f48,
	0x000084869,
	0x000066100,
	0x001c6701c,
	0x0023e701c,
	0x0d1af000c,
	0x04878001c,
	0x02f2f0010,
	0x048770162,
	0x000200022,
	0x0610001ac,
	0x0206f0018,
	0x0701cd1c0,
	0x04fef0018,
	0x06000fa98,
	0x0101149c0,
	0x02f00486e,
	0x083ac6100,
	0x0e4824280,
	0x04fef000c,
	0x04e754280,
	0x061000224,
	0x0701cd1af,
	0x000184878,
	0x0001c2f2f,
	0x0001c4877,
	0x00162002c,
	0x0003e6100,
	0x0020a206f,
	0x00024701c,
	0x0d1c04fef,
	0x000246000,
	0x0faa66000,
	0x0faa24280,
	0x010104281,
	0x012280001,
	0x0e1818081,
	0x033400004,
	0x033400008,
	0x054886000,
	0x0fa6a1358,
	0x0000a6000,
	0x0fa626000,
	0x0fa5e60fa,
	0x0598f206f,
	0x000084878,
	0x0001c2f08,
	0x0fa8a4878,
	0x000402f08,
	0x02f480008,
	0x02f2f0014,
	0x061000148,
	0x0226f0018,
	0x048690006,
	0x0610001cc,
	0x0206f000c,
	0x0701cd1c0,
	0x042801010,
	0x042811228,
	0x00001e181,
	0x080814281,
	0x012280002,
	0x07410e5a1,
	0x080814281,
	0x012280003,
	0x07418e5a1,
	0x080812340,
	0x0001c5888,
	0x058884280,
	0x07040d1c0,
	0x04fef000c,
	0x06000fa68,
	0x0101149c0,
	0x02f00486e,
	0x083c46100,
	0x0e3e64280,
	0x04fef000c,
	0x04e756000,
	0x0fa4e6000,
	0x0fa4a6000,
	0x0fa466000,
	0x0fa42598f,
	0x0206f0008,
	0x04878001c,
	0x02f082f48,
	0x000082f2f,
	0x000146100,
	0x0017e701c,
	0x0d1af000c,
	0x04878001c,
	0x02f2f0010,
	0x048770162,
	0x00020001c,
	0x061000164,
	0x0701cd1af,
	0x000184878,
	0x0001c2f2f,
	0x0001c4877,
	0x00162002c,
	0x000386100,
	0x0014a226f,
	0x00030206f,
	0x00024701c,
	0x0d1c04280,
	0x010104281,
	0x012280001,
	0x0e1818081,


@@ 2230,7 2287,7 @@ ulong bootcode[]={
	0x042811228,
	0x000037418,
	0x0e5a18081,
	0x023400024,
	0x023400054,
	0x058884280,
	0x010104281,
	0x012280001,


@@ 2241,7 2298,7 @@ ulong bootcode[]={
	0x042811228,
	0x000037418,
	0x0e5a18081,
	0x023400028,
	0x023400058,
	0x058884280,
	0x010104281,
	0x012280001,


@@ 2252,7 2309,7 @@ ulong bootcode[]={
	0x042811228,
	0x000037418,
	0x0e5a18081,
	0x02340002c,
	0x02340005c,
	0x058884280,
	0x010104281,
	0x012280001,


@@ 2263,102 2320,76 @@ ulong bootcode[]={
	0x042811228,
	0x000037418,
	0x0e5a18081,
	0x023400034,
	0x050884280,
	0x023400060,
	0x058884280,
	0x010104281,
	0x012280001,
	0x0e1818081,
	0x033400038,
	0x054884280,
	0x042811228,
	0x000027410,
	0x0e5a18081,
	0x042811228,
	0x000037418,
	0x0e5a18081,
	0x023400064,
	0x058884280,
	0x010104281,
	0x012280001,
	0x0e1818081,
	0x03340003a,
	0x054884280,
	0x042811228,
	0x000027410,
	0x0e5a18081,
	0x042811228,
	0x000037418,
	0x0e5a18081,
	0x02340006c,
	0x050884280,
	0x010104281,
	0x012280001,
	0x0e1818081,
	0x033400020,
	0x033400070,
	0x054884280,
	0x010104281,
	0x012280001,
	0x0e1818081,
	0x033400022,
	0x033400072,
	0x054882008,
	0x090af0014,
	0x04fef0010,
	0x04e75202f,
	0x0000c6f4c,
	0x0246f0004,
	0x0226f0008,
	0x0b5c96246,
	0x02209c2bc,
	0x000000003,
	0x067105380,
	0x06d3214d9,
	0x02209c2bc,
	0x000000003,
	0x066f090bc,
	0x000000010,
	0x06d1024d9,
	0x024d924d9,
	0x024d990bc,
	0x000000010,
	0x06cf0d0bc,
	0x00000000f,
	0x06d0614d9,
	0x053806cfa,
	0x0202f0004,
	0x04e75d3c0,
	0x0d5c02209,
	0x0c2bc0000,
	0x000036710,
	0x053806de8,
	0x015212209,
	0x0c2bc0000,
	0x0000366f0,
	0x090bc0000,
	0x000106d10,
	0x025212521,
	0x025212521,
	0x090bc0000,
	0x000106cf0,
	0x0d0bc0000,
	0x0000f6dbc,
	0x015215380,
	0x06db660f8,
	0x070084e40,
	0x04e757004,
	0x04e404e75,
	0x070164e40,
	0x04e757006,
	0x04e404e75,
	0x070074e40,
	0x04e757009,
	0x04e404e75,
	0x0700d4e40,
	0x04e75700e,
	0x04e404e75,
	0x0700f4e40,
	0x04e757011,
	0x04e404e75,
	0x070144e40,
	0x04e750000,
	0x000000000,
	0x090af002c,
	0x04fef0028,
	0x04e75518f,
	0x0242f0010,
	0x0222f000c,
	0x0206f0014,
	0x0b2826320,
	0x02441d5c8,
	0x02242d3c8,
	0x05388b0fc,
	0x000006d0a,
	0x015215388,
	0x0b0fc0000,
	0x06cf62001,
	0x0508f4e75,
	0x024412242,
	0x05388b0fc,
	0x000006d0a,
	0x014d95388,
	0x0b0fc0000,
	0x06cf62001,
	0x0508f4e75,
	0x000000000,
	0x000000000,
	0x000000000,
	0x000000000,
	0x000000000,
	0x000070000,
	0x02c9a0000,
	0x02d260000,
	0x029c20000,
	0x02d780000,
	0x02cc80000,
	0x02cee0000,
	0x02d0c0000,
	0x000000000,
	0x000000007,
	0x000002cf2,
	0x000002d7e,
	0x000002a1a,
	0x000002dd0,
	0x000002d20,
	0x000002d46,
	0x000002d64,
	0x000000000,
	0x000000000,
	0x000000000,


@@ 2389,246 2420,243 @@ ulong bootcode[]={
	0x000000000,
	0x000000000,
	0x000000000,
	0x000010006,
	0x000000000,
	0x000010001,
	0x000000001,
	0x000060000,
	0x000000001,
	0x000010000,
	0x000000000,
	0x000000000,
	0x000000000,
	0x000000000,
	0x000000000,
	0x000000003,
	0x000030000,
	0x000030003,
	0x000000000,
	0x000000000,
	0x000000000,
	0x000000200,
	0x000000000,
	0x002000000,
	0x000000000,
	0x000040203,
	0x003030100,
	0x000000100,
	0x000020000,
	0x000050001,
	0x000000200,
	0x000000004,
	0x002030303,
	0x001000000,
	0x001000002,
	0x000000005,
	0x000010000,
	0x002000000,
	0x000000000,
	0x000002363,
	0x02f636f6e,
	0x073002363,
	0x02f636f6e,
	0x073002363,
	0x02f636f6e,
	0x073002365,
	0x02f626f6f,
	0x0746c696e,
	0x023632f63,
	0x06f6e7300,
	0x023632f63,
	0x06f6e7300,
	0x023632f63,
	0x06f6e7300,
	0x023652f62,
	0x06f6f746c,
	0x0696e6500,
	0x023652f62,
	0x06f6f7464,
	0x065766963,
	0x065002365,
	0x02f626f6f,
	0x074646576,
	0x069636500,
	0x023652f62,
	0x06f6f7473,
	0x065727665,
	0x072006e66,
	0x073002363,
	0x02f727332,
	0x033326374,
	0x06c006f70,
	0x0656e696e,
	0x067202363,
	0x02f727332,
	0x033326374,
	0x06c004239,
	0x036303000,
	0x070757368,
	0x020617379,
	0x06e630023,
	0x0632f7273,
	0x032333263,
	0x0746c006f,
	0x070656e69,
	0x06e672023,
	0x0632f7273,
	0x032333263,
	0x0746c0042,
	0x031393230,
	0x030007075,
	0x073682061,
	0x073796e63,
	0x00023692f,
	0x074736572,
	0x076657200,
	0x06e667300,
	0x023632f72,
	0x073323332,
	0x063746c00,
	0x06f70656e,
	0x0696e6720,
	0x023692f63,
	0x0746c0070,
	0x075736820,
	0x0646b6d75,
	0x07800636f,
	0x06e666967,
	0x020312031,
	0x036206e6f,
	0x072657374,
	0x061727400,
	0x0236b2f32,
	0x02f646174,
	0x061006f70,
	0x023632f72,
	0x073323332,
	0x063746c00,
	0x042393630,
	0x030007075,
	0x073682061,
	0x073796e63,
	0x00023632f,
	0x072733233,
	0x03263746c,
	0x0006f7065,
	0x06e696e67,
	0x02023632f,
	0x072733233,
	0x03263746c,
	0x000423139,
	0x032303000,
	0x070757368,
	0x020617379,
	0x06e630023,
	0x0692f6374,
	0x06c006f70,
	0x0656e696e,
	0x06720236b,
	0x067202369,
	0x02f63746c,
	0x000707573,
	0x06820646b,
	0x06d757800,
	0x0636f6e66,
	0x069672031,
	0x020313620,
	0x06e6f7265,
	0x073746172,
	0x07400236b,
	0x02f322f64,
	0x061746100,
	0x06f70656e,
	0x0696e6720,
	0x0236b2f32,
	0x02f63746c,
	0x0006f7065,
	0x06e696e67,
	0x020236b2f,
	0x0322f6374,
	0x06c00636f,
	0x06e6e6563,
	0x074202573,
	0x000636f6e,
	0x06e656374,
	0x065642074,
	0x06f202573,
	0x00a006e6f,
	0x0702e2e2e,
	0x000777269,
	0x07465206e,
	0x06f700072,
	0x065616420,
	0x06e6f7000,
	0x06e203d20,
	0x025643b20,
	0x062756620,
	0x03d20252e,
	0x02f646174,
	0x06100236b,
	0x02f322f63,
	0x0746c006f,
	0x070656e69,
	0x06e672023,
	0x06b2f322f,
	0x063746c00,
	0x0636f6e6e,
	0x065637420,
	0x025730064,
	0x069616c69,
	0x06e670065,
	0x072726f72,
	0x020646961,
	0x06c696e67,
	0x02c207265,
	0x074727969,
	0x06e67202e,
	0x02e2e0a00,
	0x0636f6e6e,
	0x065637465,
	0x06420746f,
	0x02025730a,
	0x0006e6f70,
	0x02e2e2e00,
	0x077726974,
	0x065206e6f,
	0x070007265,
	0x06164206e,
	0x06f70006e,
	0x0203d2025,
	0x0643b2062,
	0x07566203d,
	0x020252e32,
	0x07820252e,
	0x032782025,
	0x02e327820,
	0x0252e3278,
	0x020252e32,
	0x0780a0066,
	0x06f726d61,
	0x074206e6f,
	0x070006e6f,
	0x07420526e,
	0x06f700073,
	0x00a00666f,
	0x0726d6174,
	0x0206e6f70,
	0x0006e6f74,
	0x020526e6f,
	0x070007365,
	0x07373696f,
	0x06e2e2e2e,
	0x000777269,
	0x074652073,
	0x065737369,
	0x06f6e2e2e,
	0x02e007772,
	0x069746520,
	0x073657373,
	0x0696f6e00,
	0x072656164,
	0x020736573,
	0x073696f6e,
	0x000666f72,
	0x06d617420,
	0x06f6e0072,
	0x065616420,
	0x073657373,
	0x0696f6e00,
	0x06e6f7420,
	0x052736573,
	0x073696f6e,
	0x000657272,
	0x06f722025,
	0x0643b0072,
	0x0656d6f74,
	0x065206572,
	0x0726f7200,
	0x0706f7374,
	0x02e2e2e00,
	0x023732f25,
	0x07300626f,
	0x06f746573,
	0x000637265,
	0x061746500,
	0x025640077,
	0x072697465,
	0x00023732f,
	0x025730062,
	0x06f6f7465,
	0x073002373,
	0x02f626f6f,
	0x074006372,
	0x065617465,
	0x000256400,
	0x077726974,
	0x065006d6f,
	0x0756e742e,
	0x02e2e002f,
	0x0002f0062,
	0x0696e6400,
	0x02f00006d,
	0x06f756e74,
	0x000737563,
	0x063657373,
	0x00a002f36,
	0x038303230,
	0x02f696e69,
	0x07400696e,
	0x06974002d,
	0x06d002f36,
	0x0666f726d,
	0x061742073,
	0x065737369,
	0x06f6e0065,
	0x072726f72,
	0x02025733b,
	0x0006e6f74,
	0x020527365,
	0x07373696f,
	0x06e00706f,
	0x073742e2e,
	0x02e002373,
	0x02f257300,
	0x0626f6f74,
	0x065730063,
	0x072656174,
	0x065002564,
	0x000777269,
	0x074650023,
	0x0732f2573,
	0x000626f6f,
	0x074657300,
	0x023732f62,
	0x06f6f7400,
	0x063726561,
	0x074650025,
	0x064007772,
	0x069746500,
	0x06d6f756e,
	0x0742e2e2e,
	0x0002f002f,
	0x00062696e,
	0x064002f00,
	0x000006d6f,
	0x0756e7400,
	0x073756363,
	0x06573730a,
	0x0002f3638,
	0x03032302f,
	0x0696e6974,
	0x000696e69,
	0x074002d6d,
	0x0002f3638,
	0x03032302f,
	0x0696e6974,
	0x000696e69,
	0x074002f36,
	0x038303230,
	0x02f696e69,
	0x07400696e,
	0x06974002f,
	0x036383032,
	0x0302f696e,
	0x069740062,
	0x06f6f743a,
	0x02025733a,
	0x02025730a,
	0x000006261,
	0x064207479,
	0x070653a20,
	0x025640a00,
	0x07400626f,
	0x06f743a20,
	0x025733a20,
	0x025730a00,
	0x062616420,
	0x074797065,
	0x03a202564,
	0x00a000000,
	0x000006e6f,
	0x06e2d7a65,
	0x0726f2065,
	0x078697420,
	0x073746174,
	0x075730000,
	0x000000618,
	0x00614060c,
	0x005f405de,
	0x005de05de,
	0x005de05de,
	0x005de058e,
	0x005580562,
	0x0055e055a,
	0x00558053c,
	0x0053804d0,
	0x0047a0476,
	0x00414038c,
	0x003880386,
	0x00384034e,
	0x0034a0332,
	0x002e802b2,
	0x00286025a,
	0x0021001e4,
	0x0019a0136,
	0x000d20048,
	0x0000c05a6,
	0x005a2059a,
	0x00582056c,
	0x0056c056c,
	0x0056c056c,
	0x0056c051c,
	0x004e604f0,
	0x004ec04e8,
	0x004e604ca,
	0x004c6045c,
	0x004040400,
	0x003b60354,
	0x00350034e,
	0x0034c0316,
	0x0031202fa,
	0x002b0027a,
	0x0024e0222,
	0x001d801ac,
	0x00162010a,
	0x000be005a,
	0x0001c0000,
	0x00002916,
	0x00a006261,
	0x064207479,
	0x070653a20,
	0x025640a00,
	0x000000000,
	0x005e405e0,
	0x005dc05d8,
	0x005c205a0,
	0x005880584,
	0x0051a04ae,
	0x00482046a,
	0x0043403c8,
	0x003ac0340,
	0x002d8026c,
	0x0020801b8,
	0x0012e0104,
	0x000ec00d4,
	0x000bc00a4,
	0x0008c0056,
	0x00022000c,
	0x005be05ba,
	0x005b605b2,
	0x0059c057a,
	0x00562055e,
	0x004f40484,
	0x004580440,
	0x0040a039a,
	0x0037e030e,
	0x002a40234,
	0x001dc01a4,
	0x001400114,
	0x000fc00e4,
	0x000cc00b4,
	0x0009c0066,
	0x00032001c,
	0x06e6f6e2d,
	0x07a65726f,
	0x020657869,
	0x074207374,
	0x061747573,
	0x000000000,
	0x00002988,
	0x0,
};

M gnot/chan.c => gnot/chan.c +39 -31
@@ 85,7 85,7 @@ loop:
		c->mnt = 0;
		c->stream = 0;
		c->mchan = 0;
		c->mqid = 0;
		c->mqid = (Qid){0, 0};
		return c;
	}
	unlock(&chanalloc);


@@ 117,9 117,17 @@ close(Chan *c)
}

int
eqchan(Chan *a, Chan *b, long qmask)
eqqid(Qid a, Qid b)
{
	if((a->qid^b->qid) & qmask)
	return a.path==b.path && a.vers==b.vers;
}

int
eqchan(Chan *a, Chan *b, int pathonly)
{
	if(a->qid.path != b->qid.path)
		return 0;
	if(!pathonly && a->qid.vers!=b->qid.vers)
		return 0;
	if(a->type != b->type)
		return 0;


@@ 159,10 167,10 @@ mount(Chan *new, Chan *old, int flag)
	Pgrp *pg;
	int islast;

	if(CHDIR & (old->qid^new->qid))
		error(0, Emount);
	if((old->qid&CHDIR)==0 && (flag&MORDER)!=MREPL)
		error(0, Emount);
	if(CHDIR & (old->qid.path^new->qid.path))
		error(Emount);
	if((old->qid.path&CHDIR)==0 && (flag&MORDER)!=MREPL)
		error(Emount);

	mz = 0;
	islast = 0;


@@ 184,14 192,14 @@ mount(Chan *new, Chan *old, int flag)
	for(i=0; i<pg->nmtab; i++,mt++){
		if(mt->c==0 && mz==0)
			mz = mt;
		else if(eqchan(mt->c, old, CHDIR|QPATH)){
		else if(eqchan(mt->c, old, 1)){
			mz = 0;
			goto Found;
		}
	}
	if(mz == 0){
		if(i == conf.nmtab)
			error(0, Enomount);
			error(Enomount);
		mz = &pg->mtab[i];
		islast++;
	}


@@ 211,7 219,7 @@ mount(Chan *new, Chan *old, int flag)
	 */
	case MBEFORE:
		if(mt->mnt == 0)
			error(0, Enotunion);
			error(Enotunion);
		/* fall through */

	case MREPL:


@@ 228,7 236,7 @@ mount(Chan *new, Chan *old, int flag)
	 */
	case MAFTER:
		if(mt->mnt == 0)
			error(0, Enotunion);
			error(Enotunion);
		omnt = mt->mnt;
		pmnt = 0;
		while(!omnt->term){


@@ 288,7 296,7 @@ domount(Chan *c)
	 */
	mt = pg->mtab;
	for(i=0; i<pg->nmtab; i++,mt++)
		if(mt->c && eqchan(mt->c, c, CHDIR|QPATH))
		if(mt->c && eqchan(mt->c, c, 1))
			goto Found;
	/*
	 * No; c is unaffected


@@ 300,7 308,7 @@ domount(Chan *c)
	 */
    Found:
	lock(pg);
	if(!eqchan(mt->c, c, CHDIR|QPATH)){	/* table changed underfoot */
	if(!eqchan(mt->c, c, 1)){	/* table changed underfoot */
		pprint("domount: changed underfoot?\n");
		unlock(pg);
		return c;


@@ 417,11 425,11 @@ createdir(Chan *c)
	mnt = c->mnt;
	if(c->mountid != mnt->mountid){
		pprint("createdir: changed underfoot?\n");
		error(0, Enocreate);
		error(Enocreate);
	}
	do{
		if(mnt->term)
			error(0, Enocreate);
			error(Enocreate);
		mnt = mnt->next;
	}while(!(mnt->c->flag&CCREATE));
	mc = mnt->c;


@@ 458,7 466,7 @@ namec(char *name, int amode, int omode, ulong perm)
	char *elem;

	if(name[0] == 0)
		error(0, Enonexist);
		error(Enonexist);

	/*
	 * Make sure all of name is o.k.  first byte is validated


@@ 485,10 493,10 @@ namec(char *name, int amode, int omode, ulong perm)
	}else if(name[0] == '#'){
		mntok = 0;
		if(name[1]=='M')
			error(0, Enonexist);
			error(Enonexist);
		t = devno(name[1], 1);
		if(t == -1)
			error(0, Ebadsharp);
			error(Ebadsharp);
		name += 2;
		if(*name == '/'){
			name = skipslash(name);


@@ 520,7 528,7 @@ namec(char *name, int amode, int omode, ulong perm)
	 */
	while(*name){
		if((nc=walk(c, elem, mntok)) == 0)
			error(0, Enonexist);
			error(Enonexist);
		c = nc;
		name = nextelem(name, elem);
	}


@@ 535,7 543,7 @@ namec(char *name, int amode, int omode, ulong perm)
			c = domount(c);
		else{
			if((nc=walk(c, elem, mntok)) == 0)
				error(0, Enonexist);
				error(Enonexist);
			c = nc;
		}
		break;


@@ 546,10 554,10 @@ namec(char *name, int amode, int omode, ulong perm)
		 * so one may mount on / or . and see the effect.
		 */
		if((nc=walk(c, elem, 0)) == 0)
			error(0, Enonexist);
			error(Enonexist);
		c = nc;
		if(!(c->qid & CHDIR))
			error(0, Enotdir);
		if(!(c->qid.path & CHDIR))
			error(Enotdir);
		break;

	case Aopen:


@@ 557,7 565,7 @@ namec(char *name, int amode, int omode, ulong perm)
			c = domount(c);
		else{
			if((nc=walk(c, elem, mntok)) == 0)
				error(0, Enonexist);
				error(Enonexist);
			c = nc;
		}
	Open:


@@ 574,13 582,13 @@ namec(char *name, int amode, int omode, ulong perm)
		 * the replacement.
		 */
		if((nc=walk(c, elem, 0)) == 0)
			error(0, Enonexist);
			error(Enonexist);
		c = nc;
		break;

	case Acreate:
		if(isdot)
			error(0, Eisdir);
			error(Eisdir);
		if((nc=walk(c, elem, 1)) != 0){
			c = nc;
			omode |= OTRUNC;


@@ 638,12 646,12 @@ nextelem(char *name, char *elem)
	char *end, *e;

	if(*name == '/')
		error(0, Efilename);
		error(Efilename);
	end = memchr(name, 0, NAMELEN);
	if(end == 0){
		end = memchr(name, '/', NAMELEN);
		if(end == 0)
			error(0, Efilename);
			error(Efilename);
	}else{
		e = memchr(name, '/', end-name);
		if(e)


@@ 652,7 660,7 @@ nextelem(char *name, char *elem)
	while(name < end){
		c = *name++;
		if((c&0x80) || isfrog[c])
			error(0, Ebadchar);
			error(Ebadchar);
		*elem++ = c;
	}
	*elem = 0;


@@ 662,7 670,7 @@ nextelem(char *name, char *elem)
void
isdir(Chan *c)
{
	if(c->qid & CHDIR)
	if(c->qid.path & CHDIR)
		return;
	error(0, Enotdir);
	error(Enotdir);
}

M gnot/dat.h => gnot/dat.h +9 -10
@@ 83,7 83,6 @@ struct Alarm
#define	CHDIR	0x80000000L
#define	CHAPPEND 0x40000000L
#define	CHEXCL	0x20000000L
#define	QPATH	0x0000FFFFL
struct Chan
{
	QLock;				/* general access */


@@ 96,17 95,17 @@ struct Chan
	ushort	dev;
	ushort	mode;			/* read/write */
	ushort	flag;
	ulong	qid;
	Qid	qid;
	Mount	*mnt;			/* mount point that derived Chan */
	ulong	mountid;
	int	fid;			/* for devmnt */
	union {
		Stream	*stream;	/* for stream channels */
		void	*aux;
		ulong	pgrpid;		/* for #p/notepg */
		Qid	pgrpid;		/* for #p/notepg */
	};
	Chan	*mchan;			/* channel to mounted server */
	ulong	mqid;			/* qid of root of mount point */
	Qid	mqid;			/* qid of root of mount point */
};

struct	FPsave


@@ 170,14 169,12 @@ struct Dev
	long	 (*write)(Chan*, void*, long);
	void	 (*remove)(Chan*);
	void	 (*wstat)(Chan*, char*);
	void	 (*errstr)(Error*, char*);
	void	 (*userstr)(Error*, char*);
};

struct Dirtab
{
	char	name[NAMELEN];
	ulong	qid;
	Qid	qid;
	long	length;
	long	perm;
};


@@ 259,9 256,9 @@ struct Orig
	PTE	*pte;
	Chan	*chan;			/* channel deriving segment (if open) */
	ushort	type;			/* of channel (which could be non-open) */
	ulong	qid;
	Qid	qid;
	Chan	*mchan;
	ulong	mqid;
	Qid	mqid;
	ulong	minca;			/* base of region in chan */
	ulong	maxca;			/* end of region in chan */
};


@@ 372,7 369,7 @@ struct User
	Proc	*p;
	int	nerrlab;
	Label	errlab[NERR];
	Error	error;
	char	error[ERRLEN];
	FPsave	fpsave;			/* address of this is known by vdb */
	char	elem[NAMELEN];		/* last name element from namec */
	Chan	*slash;


@@ 601,5 598,7 @@ extern	Dev	devtab[];
extern	char	devchar[];
extern	FPsave	initfp;
extern	Mach	mach0;
extern	char	user[NAMELEN];
extern	char	*errstrtab[];

extern  void	(*kprofp)(ulong);

M gnot/dev.c => gnot/dev.c +12 -15
@@ 4,7 4,6 @@
#include	"dat.h"
#include	"fns.h"
#include	"errno.h"

#define	DEVTAB
#include	"devtab.h"



@@ 25,13 24,13 @@ devno(int c, int user)
}

void
devdir(Chan *c, long qid, char *n, long length, long perm, Dir *db)
devdir(Chan *c, Qid qid, char *n, long length, long perm, Dir *db)
{
	strcpy(db->name, n);
	db->qid = qid;
	db->type = devchar[c->type];
	db->dev = c->dev;
	if(qid & CHDIR)
	if(qid.path & CHDIR)
		db->mode = CHDIR|perm;
	else
		db->mode = perm;


@@ 39,8 38,8 @@ devdir(Chan *c, long qid, char *n, long length, long perm, Dir *db)
	db->mtime = db->atime;
	db->hlength = 0;
	db->length = length;
	db->uid = 0;
	db->gid = 0;
	memcpy(db->uid, user, NAMELEN);
	memcpy(db->gid, user, NAMELEN);
}

int


@@ 59,7 58,7 @@ devattach(int tc, char *spec)
	Chan *c;

	c = newchan();
	c->qid = CHDIR;
	c->qid = (Qid){CHDIR, 0};
	c->type = devno(tc, 0);
	return c;
}


@@ 95,9 94,7 @@ devwalk(Chan *c, char *name, Dirtab *tab, int ntab, Devgen *gen)
	for(i=0;; i++)
		switch((*gen)(c, tab, ntab, i, &dir)){
		case -1:
			u->error.type = 0;
			u->error.dev = 0;
			u->error.code = Enonexist;
			strncpy(u->error, errstrtab[Enonexist], NAMELEN);
			return 0;
		case 0:
			continue;


@@ 123,7 120,7 @@ devstat(Chan *c, char *db, Dirtab *tab, int ntab, Devgen *gen)
			 * devices with interesting directories usually don't get
			 * here, which is good because we've lost the name by now.
			 */
			if(c->qid & CHDIR){
			if(c->qid.path & CHDIR){
				devdir(c, c->qid, ".", 0L, CHDIR|0700, &dir);
				convD2M(&dir, db);
				return;


@@ 132,7 129,7 @@ devstat(Chan *c, char *db, Dirtab *tab, int ntab, Devgen *gen)
		case 0:
			break;
		case 1:
			if(c->qid == dir.qid){
			if(eqqid(c->qid, dir.qid)){
				convD2M(&dir, db);
				return;
			}


@@ 180,17 177,17 @@ devopen(Chan *c, int omode, Dirtab *tab, int ntab, Devgen *gen)
		case 0:
			break;
		case 1:
			if(c->qid == dir.qid){
			if(eqqid(c->qid, dir.qid)){
				if((access[omode&3] & dir.mode) == access[omode&3])
					goto Return;
				error(0, Eperm);
				error(Eperm);
			}
			break;
		}
    Return:
	c->offset = 0;
	if((c->qid&CHDIR) && omode!=OREAD)
		error(0, Eperm);
	if((c->qid.path&CHDIR) && omode!=OREAD)
		error(Eperm);
	c->mode = openmode(omode);
	c->flag |= COPEN;
	return c;

M gnot/devcons.c => gnot/devcons.c +26 -38
@@ 392,20 392,20 @@ enum{
};

Dirtab consdir[]={
	"cons",		Qcons,		0,		0600,
	"cputime",	Qcputime,	6*NUMSIZE,	0600,
	"null",		Qnull,		0,		0600,
	"pgrpid",	Qpgrpid,	NUMSIZE,	0600,
	"pid",		Qpid,		NUMSIZE,	0600,
	"ppid",		Qppid,		NUMSIZE,	0600,
	"rcons",	Qrcons,		0,		0600,
	"rs232",	Qrs232,		0,		0600,
	"rs232ctl",	Qrs232ctl,	0,		0600,
	"time",		Qtime,		NUMSIZE,	0600,
	"user",		Quser,		0,		0600,
	"klog",		Qklog,		0,		0400,
	"msec",		Qmsec,		NUMSIZE,	0400,
	"clock",	Qclock,		2*NUMSIZE,	0400,
	"cons",		{Qcons},	0,		0600,
	"cputime",	{Qcputime},	6*NUMSIZE,	0600,
	"null",		{Qnull},	0,		0600,
	"pgrpid",	{Qpgrpid},	NUMSIZE,	0600,
	"pid",		{Qpid},		NUMSIZE,	0600,
	"ppid",		{Qppid},	NUMSIZE,	0600,
	"rcons",	{Qrcons},	0,		0600,
	"rs232",	{Qrs232},	0,		0600,
	"rs232ctl",	{Qrs232ctl},	0,		0600,
	"time",		{Qtime},	NUMSIZE,	0600,
	"user",		{Quser},	0,		0600,
	"klog",		{Qklog},	0,		0400,
	"msec",		{Qmsec},	NUMSIZE,	0400,
	"clock",	{Qclock},	2*NUMSIZE,	0400,
};

#define	NCONS	(sizeof consdir/sizeof(Dirtab))


@@ 489,7 489,7 @@ conswalk(Chan *c, char *name)
void
consstat(Chan *c, char *dp)
{
	switch(c->qid){
	switch(c->qid.path){
	case Qrs232:
		streamstat(c, dp, "rs232");
		break;


@@ 504,14 504,14 @@ consopen(Chan *c, int omode)
{
	int ch;

	switch(c->qid){
	switch(c->qid.path){
	case Quser:
		if(omode==(OWRITE|OTRUNC)){
			/* truncate? */
			if(strcmp(u->p->pgrp->user, "bootes") == 0)	/* BUG */
				u->p->pgrp->user[0] = 0;
			else
				error(0, Eperm);
				error(Eperm);
		}
		break;
	case Qrcons:


@@ 536,13 536,13 @@ consopen(Chan *c, int omode)
void
conscreate(Chan *c, char *name, int omode, ulong perm)
{
	error(0, Eperm);
	error(Eperm);
}

void
consclose(Chan *c)
{
	if(c->qid==Qrcons && (c->flag&COPEN))
	if(c->qid.path==Qrcons && (c->flag&COPEN))
		decref(&raw);
	if(c->stream)
		streamclose(c);


@@ 561,7 561,7 @@ consread(Chan *c, void *buf, long n)

	if(n <= 0)
		return n;
	switch(c->qid&~CHDIR){
	switch(c->qid.path&~CHDIR){
	case Qdir:
		return devdirread(c, buf, n, consdir, NCONS, consgen);



@@ 701,7 701,7 @@ conswrite(Chan *c, void *va, long n)
	long l, m;
	char *a = va;

	switch(c->qid){
	switch(c->qid.path){
	case Qcons:
	case Qrcons:
		/*


@@ 736,7 736,7 @@ conswrite(Chan *c, void *va, long n)

	case Quser:
		if(u->p->pgrp->user[0])		/* trying to overwrite /dev/user */
			error(0, Eperm);
			error(Eperm);
		if(c->offset >= NAMELEN-1)
			return 0;
		if(c->offset+n >= NAMELEN-1)


@@ 749,12 749,12 @@ conswrite(Chan *c, void *va, long n)
	case Qpgrpid:
	case Qpid:
	case Qppid:
		error(0, Eperm);
		error(Eperm);

	case Qnull:
		break;
	default:
		error(0, Egreg);
		error(Egreg);
	}
	return n;
}


@@ 762,25 762,13 @@ conswrite(Chan *c, void *va, long n)
void
consremove(Chan *c)
{
	error(0, Eperm);
	error(Eperm);
}

void
conswstat(Chan *c, char *dp)
{
	error(0, Eperm);
}

void
conserrstr(Error *e, char *buf)
{
	rooterrstr(e, buf);
}

void
consuserstr(Error *e, char *buf)
{
	strcpy(buf, u->p->pgrp->user);
	error(Eperm);
}

/*

M gnot/devdk.c => gnot/devdk.c +58 -69
@@ 6,7 6,7 @@
#include	"io.h"
#include	"errno.h"

#define	DPRINT	if(0)	/*kprint*/
#define	DPRINT	if(0) print

#define	NOW	(MACHP(0)->ticks)



@@ 232,7 232,7 @@ dkalloc(char *name)
	}
	if(freep == 0){
		unlock(&dklock);
		error(0, Enoifc);
		error(Enoifc);
	}
	dp = freep;
	dp->opened = 0;


@@ 388,7 388,7 @@ dkstopen(Queue *q, Stream *s)
	lock(dp);
	if(dp->opened==0 || streamenter(dp->s)<0){
		unlock(dp);
		error(0, Ehungup);
		error(Ehungup);
	}
	unlock(dp);
	lp->rq = q;


@@ 499,7 499,7 @@ dkoput(Queue *q, Block *bp)

	if(bp->type != M_DATA){
		freeb(bp);
		error(0, Ebadarg);
		error(Ebadarg);
	}

	lp = (Line *)q->ptr;


@@ 540,7 540,7 @@ dkmuxconfig(Queue *q, Block *bp)

	if(WR(q)->ptr){
		freeb(bp);
		error(0, Egreg);
		error(Egreg);
	}

	/*


@@ 571,11 571,11 @@ dkmuxconfig(Queue *q, Block *bp)
		break;
	default:
		freeb(bp);
		error(0, Ebadarg);
		error(Ebadarg);
	}
	freeb(bp);
	if(ncsc <= 0 || lines <= ncsc)
		error(0, Ebadarg);
		error(Ebadarg);

	/*
	 *  set up


@@ 584,7 584,7 @@ dkmuxconfig(Queue *q, Block *bp)
	lock(dp);
	if(dp->opened){
		unlock(dp);
		error(0, Ebadarg);
		error(Ebadarg);
	}
	dp->ncsc = ncsc;
	dp->lines = lines;


@@ 653,11 653,11 @@ Dirtab dkdir[Ndir];
 *  the per stream directory structure
 */
Dirtab dksubdir[]={
	"addr",		Daddrqid,	0,	0600,
	"listen",	Dlistenqid,	0,	0600,
	"other",	Dotherqid,	0,	0600,
	"raddr",	Draddrqid,	0, 	0600,
	"ruser",	Duserqid,	0, 	0600,
	"addr",		{Daddrqid},	0,	0600,
	"listen",	{Dlistenqid},	0,	0600,
	"other",	{Dotherqid},	0,	0600,
	"raddr",	{Draddrqid},	0, 	0600,
	"ruser",	{Duserqid},	0, 	0600,
};

/*


@@ 687,7 687,8 @@ dkinit(void)
	 */
	for(i = 1; i < Nline; i++) {
		sprint(dkdir[i].name, "%d", i);
		dkdir[i].qid = CHDIR|STREAMQID(i, Dlineqid);
		dkdir[i].qid.path = CHDIR|STREAMQID(i, Dlineqid);
		dkdir[i].qid.vers = 0;
		dkdir[i].length = 0;
		dkdir[i].perm = 0600;
	}


@@ 696,7 697,8 @@ dkinit(void)
	 *  the clone device
	 */
	strcpy(dkdir[0].name, "clone");
	dkdir[0].qid = Dcloneqid;
	dkdir[0].qid.path = Dcloneqid;
	dkdir[0].qid.vers = 0;
	dkdir[0].length = 0;
	dkdir[0].perm = 0600;
}


@@ 731,7 733,7 @@ dkclone(Chan *c, Chan *nc)
int	 
dkwalk(Chan *c, char *name)
{
	if(c->qid == CHDIR)
	if(c->qid.path == CHDIR)
		return devwalk(c, name, dkdir, dk[c->dev].lines, devgen);
	else
		return devwalk(c, name, dksubdir, Nsubdir, streamgen);


@@ 740,7 742,7 @@ dkwalk(Chan *c, char *name)
void	 
dkstat(Chan *c, char *dp)
{
	if(c->qid == CHDIR)
	if(c->qid.path == CHDIR)
		devstat(c, dp, dkdir, dk[c->dev].lines, devgen);
	else
		devstat(c, dp, dksubdir, Nsubdir, streamgen);


@@ 764,13 766,13 @@ dkopen(Chan *c, int omode)
	Dk *dp;
	int line;

	if(c->qid & CHDIR){
	if(c->qid.path & CHDIR){
		/*
		 *  directories are read only
		 */
		if(omode != OREAD)
			error(0, Ebadarg);
	} else switch(STREAMTYPE(c->qid)){
			error(Ebadarg);
	} else switch(STREAMTYPE(c->qid.path)){
	case Dcloneqid:
		dp = &dk[c->dev];
		/*


@@ 783,12 785,12 @@ dkopen(Chan *c, int omode)
					qunlock(lp);
					continue;
				}
				c->qid = STREAMQID(lp-dp->line, Sctlqid);
				c->qid.path = STREAMQID(lp-dp->line, Sctlqid);
				break;
			}
		}
		if(lp == end)
			error(0, Enodev);
			error(Enodev);
		lp->state = Lopened;
		qunlock(lp);
		streamopen(c, &dkinfo);


@@ 800,7 802,7 @@ dkopen(Chan *c, int omode)
		 *  channel on which the call arrived.
		 */
		line = dklisten(c);
		c->qid = STREAMQID(line, Sctlqid);
		c->qid.path = STREAMQID(line, Sctlqid);
		streamopen(c, &dkinfo);
		pushq(c->stream, &urpinfo);
		dkwindow(c);


@@ 813,7 815,7 @@ dkopen(Chan *c, int omode)
		 *  read only files
		 */
		if(omode != OREAD)
			error(0, Ebadarg);
			error(Ebadarg);
		break;
	default:
		/*


@@ 834,7 836,7 @@ dkopen(Chan *c, int omode)
void	 
dkcreate(Chan *c, char *name, int omode, ulong perm)
{
	error(0, Eperm);
	error(Eperm);
}

void	 


@@ 852,15 854,15 @@ dkread(Chan *c, void *a, long n)
	if(c->stream)
		return streamread(c, a, n);

	if(c->qid & CHDIR){
		if(c->qid == CHDIR)
	if(c->qid.path & CHDIR){
		if(c->qid.path == CHDIR)
			return devdirread(c, a, n, dkdir, dk[c->dev].lines, devgen);
		else
			return devdirread(c, a, n, dksubdir, Nsubdir, streamgen);
	}

	lp = &dk[c->dev].line[STREAMID(c->qid)];
	switch(STREAMTYPE(c->qid)){
	lp = &dk[c->dev].line[STREAMID(c->qid.path)];
	switch(STREAMTYPE(c->qid.path)){
	case Daddrqid:
		return stringread(c, a, n, lp->addr);
	case Draddrqid:


@@ 868,7 870,7 @@ dkread(Chan *c, void *a, long n)
	case Duserqid:
		return stringread(c, a, n, lp->ruser);
	}
	error(0, Eperm);
	error(Eperm);
}

long	 


@@ 879,7 881,7 @@ dkwrite(Chan *c, void *a, long n)
	char *field[5];
	int m;

	t = STREAMTYPE(c->qid);
	t = STREAMTYPE(c->qid.path);

	/*
	 *  get data dispatched as quickly as possible


@@ 895,56 897,42 @@ dkwrite(Chan *c, void *a, long n)
		m = getfields(buf, field, 5, ' ');
		if(strcmp(field[0], "connect")==0){
			if(m < 2)
				error(0, Ebadarg);
				error(Ebadarg);
			dkcall(Dial, c, field[1], 0, 0);
		} else if(strcmp(field[0], "announce")==0){
			if(m < 2)
				error(0, Ebadarg);
				error(Ebadarg);
			dkcall(Announce, c, field[1], 0, 0);
		} else if(strcmp(field[0], "redial")==0){
			if(m < 4)
				error(0, Ebadarg);
				error(Ebadarg);
			dkcall(Redial, c, field[1], field[2], field[3]);
		} else if(strcmp(field[0], "accept")==0){
			if(m < 2)
				error(0, Ebadarg);
				error(Ebadarg);
			dkanswer(c, strtoul(field[1], 0, 0), 0);
		} else if(strcmp(field[0], "reject")==0){
			if(m < 3)
				error(0, Ebadarg);
				error(Ebadarg);
			dkanswer(c, strtoul(field[1], 0, 0), strtoul(field[2], 0, 0));
		} else
			return streamwrite(c, a, n, 0);
		return n;
	}

	error(0, Eperm);
	error(Eperm);
}

void	 
dkremove(Chan *c)
{
	error(0, Eperm);
	error(Eperm);
}

void	 
dkwstat(Chan *c, char *dp)
{
	error(0, Eperm);
}

void	 
dkerrstr(Error *e, char *buf)
{
	rooterrstr(e, buf);
}

void	 
dkuserstr(Error *e, char *buf)
{
	extern consuserstr(Error *, char *);

	consuserstr(e, buf);
	error(Eperm);
}

/*


@@ 962,7 950,7 @@ dkopenline(Dk *dp, int line)
		nexterror();
	}
	c = dkattach(dp->name);
	c->qid = STREAMQID(line, Sdataqid);
	c->qid.path = STREAMQID(line, Sdataqid);
	dkopen(c, ORDWR);
	poperror();



@@ 1022,7 1010,7 @@ dkcall(int type, Chan *c, char *addr, char *nuser, char *machine)
	Chan *csc;
	char *bang, *dot;
	
	line = STREAMID(c->qid);
	line = STREAMID(c->qid.path);
	dp = &dk[c->dev];
	lp = &dp->line[line];



@@ 1030,7 1018,7 @@ dkcall(int type, Chan *c, char *addr, char *nuser, char *machine)
	 *  only dial on virgin lines
	 */
	if(lp->state != Lopened)
		error(0, Ebadarg);
		error(Ebadarg);

	DPRINT("dkcall(line=%d, type=%d, dest=%s)\n", line, type, addr);



@@ 1040,9 1028,9 @@ dkcall(int type, Chan *c, char *addr, char *nuser, char *machine)
	 *	- change ! into . to delimit service
	 */
	if(strchr(addr, '\n'))
		error(0, Ebadarg);
		error(Ebadarg);
	if(strlen(addr)+strlen(u->p->pgrp->user)+2 >= sizeof(dialstr))
		error(0, Ebadarg);
		error(Ebadarg);
	strcpy(dialstr, addr);
	bang = strchr(dialstr, '!');
	if(bang){


@@ 1109,7 1097,7 @@ dkcall(int type, Chan *c, char *addr, char *nuser, char *machine)
	if(type==Redial){
		if(streamread(dc, &dialtone, 1L) != 1L){
			lp->state = Lconnected;
			error(0, Ebadarg);
			error(Ebadarg);
		}
	}



@@ 1142,9 1130,9 @@ dkcall(int type, Chan *c, char *addr, char *nuser, char *machine)
	DPRINT("got reply %d\n", lp->state);
	if(lp->state != Lconnected) {
		if(lp->err >= DKERRS)
			error(0, dkerr[0]);
			error(dkerr[0]);
		else
			error(0, dkerr[lp->err]);
			error(dkerr[lp->err]);
	}

	/*


@@ 1202,7 1190,7 @@ dklisten(Chan *c)
	/*
	 *  open the data file
	 */
	dc = dkopenline(dp, STREAMID(c->qid));
	dc = dkopenline(dp, STREAMID(c->qid.path));
	if(waserror()){
		close(dc);
		nexterror();


@@ 1218,7 1206,7 @@ dklisten(Chan *c)
		n = streamread(dc, dialstr, sizeof(dialstr)-1);
		DPRINT("returns %d\n", n);
		if(n <= 0)
			error(0, Eio);
			error(Eio);
		dialstr[n] = 0;
		DPRINT("dialstr = %s\n", dialstr);



@@ 1228,7 1216,7 @@ dklisten(Chan *c)
		n = getfields(dialstr, line, 12, '\n');
		if (n < 2) {
			DPRINT("bad dialstr from dk (1 line)\n");
			error(0, Eio);
			error(Eio);
		}

		/*


@@ 1332,7 1320,7 @@ dklisten(Chan *c)
		default:
			print("bad message from dk(>4 line)\n");
			qunlock(lp);
			error(0, Ebadarg);
			error(Ebadarg);
		}

		sprint(lp->other, "w(%d)", W_TRAF(lp->window));


@@ 1372,7 1360,7 @@ dkanswer(Chan *c, int line, int code)
		close(dc);
		nexterror();
	}
	dc->qid = STREAMQID(STREAMID(c->qid), Sdataqid);
	dc->qid.path = STREAMQID(STREAMID(c->qid.path), Sdataqid);
	dkopen(dc, ORDWR);

	/*


@@ 1395,7 1383,7 @@ dkwindow(Chan *c)
	long wins;
	Line *lp;

	lp = &dk[c->dev].line[STREAMID(c->qid)];
	lp = &dk[c->dev].line[STREAMID(c->qid.path)];
	if(lp->window == 0)
		lp->window = 64;
	sprint(buf, "init %d %d", lp->window, Streamhi);


@@ 1444,7 1432,7 @@ dkcsckproc(void *a)
		n = streamread(dp->csc, (char *)&d, (long)sizeof(d));
		if(n != sizeof(d)){
			if(n == 0)
				error(0, Ehungup);
				error(Ehungup);
			print("strange csc message %d\n", n);
			continue;
		}


@@ 1663,11 1651,12 @@ dktimer(void *a)

	for(;;){
		if(dp->opened==0)
			error(0, Ehungup);
			error(Ehungup);

		/*
		 * send keep alive
		 */
		DPRINT("keep alive\n");
		dkmesg(c, T_ALIVE, D_CONTINUE, 0, 0);

		/*

M gnot/devdup.c => gnot/devdup.c +9 -21
@@ 20,7 20,7 @@ dupgen(Chan *c, Dirtab *tab, int ntab, int s, Dir *dp)
	if((f=u->fd[s]) == 0)
		return 0;
	sprint(buf, "%ld", s);
	devdir(c, s, buf, 0, perm[f->mode&3], dp);
	devdir(c, (Qid){s, 0}, buf, 0, perm[f->mode&3], dp);
	return 1;
}



@@ 63,16 63,16 @@ dupopen(Chan *c, int omode)
{
	Chan *f;

	if(c->qid == CHDIR){
	if(c->qid.path == CHDIR){
		if(omode != 0)
			error(0, Eisdir);
			error(Eisdir);
		c->mode = 0;
		c->flag |= COPEN;
		c->offset = 0;
		return c;
	}
	fdtochan(c->qid, openmode(omode));	/* error check only */
	f = u->fd[c->qid];
	fdtochan(c->qid.path, openmode(omode));	/* error check only */
	f = u->fd[c->qid.path];
	close(c);
	incref(f);
	return f;


@@ 81,19 81,19 @@ dupopen(Chan *c, int omode)
void
dupcreate(Chan *c, char *name, int omode, ulong perm)
{
	error(0, Eperm);
	error(Eperm);
}

void
dupremove(Chan *c)
{
	error(0, Eperm);
	error(Eperm);
}

void
dupwstat(Chan *c, char *dp)
{
	error(0, Egreg);
	error(Egreg);
}

void


@@ 106,7 106,7 @@ dupread(Chan *c, void *va, long n)
{
	char *a = va;

	if(c->qid != CHDIR)
	if(c->qid.path != CHDIR)
		panic("dupread");
	return devdirread(c, a, n, (Dirtab *)0, 0L, dupgen);
}


@@ 116,15 116,3 @@ dupwrite(Chan *c, void *va, long n)
{
	panic("dupwrite");
}

void
duperrstr(Error *e, char *buf)
{
	rooterrstr(e, buf);
}

void
dupuserstr(Error *e, char *buf)
{
	consuserstr(e, buf);
}

M gnot/devenv.c => gnot/devenv.c +29 -42
@@ 155,7 155,7 @@ compactenv(Env *e, ulong n)
	envalloc.vfree = p1;
	if(envalloc.end-envalloc.vfree < n){
		print("env compact failed\n");
		error(0, Enoenv);
		error(Enoenv);
	}
}



@@ 173,7 173,7 @@ copyenv(Env *e, int trunc)
	ne = envalloc.efree;
	if(!ne){
		print("out of envs\n");
		error(0, Enoenv);
		error(Enoenv);
	}
	envalloc.efree = ne->next;
	lock(ne);


@@ 224,7 224,7 @@ envgen(Chan *c, Dirtab *tab, int ntab, int s, Dir *dp)
			ans = 0;
		else{
			lock(e);
			devdir(c, s+1, e->name, e->val? e->val->len : 0, 0666, dp);
			devdir(c, (Qid){s+1,0}, e->name, e->val? e->val->len : 0, 0666, dp);
			unlock(e);
			ans = 1;
		}


@@ 244,10 244,10 @@ envclone(Chan *c, Chan *nc)
{
	Pgrp *pg;

	if(!(c->qid&CHDIR)){
	if(!(c->qid.path&CHDIR)){
		pg = u->p->pgrp;
		lock(pg);
		pg->etab[c->qid-1].chref++;
		pg->etab[c->qid.path-1].chref++;
		unlock(pg);
	}
	return devclone(c, nc);


@@ 259,10 259,10 @@ envwalk(Chan *c, char *name)
	Pgrp *pg;

	if(devwalk(c, name, 0, 0, envgen)){
		if(!(c->qid&CHDIR)){
		if(!(c->qid.path&CHDIR)){
			pg = u->p->pgrp;
			lock(pg);
			pg->etab[c->qid-1].chref++;
			pg->etab[c->qid.path-1].chref++;
			unlock(pg);
			return 1;
		}


@@ 284,15 284,15 @@ envopen(Chan *c, int omode)
	Pgrp *pg;

	if(omode & (OWRITE|OTRUNC)){
		if(c->qid & CHDIR)
			error(0, Eperm);
		if(c->qid.path & CHDIR)
			error(Eperm);
		pg = u->p->pgrp;
		lock(pg);
		ep = &pg->etab[c->qid-1];
		ep = &pg->etab[c->qid.path-1];
		e = ep->env;
		if(!e){
			unlock(pg);
			error(0, Egreg);
			error(Egreg);
		}
		lock(&envalloc);
		lock(e);


@@ 333,8 333,8 @@ envcreate(Chan *c, char *name, int omode, ulong perm)
	Pgrp *pg;
	int i;

	if(c->qid != CHDIR)
		error(0, Eperm);
	if(c->qid.path != CHDIR)
		error(Eperm);
	pg = u->p->pgrp;
	lock(pg);
	lock(&envalloc);


@@ 346,7 346,7 @@ envcreate(Chan *c, char *name, int omode, ulong perm)
	e = envalloc.efree;
	if(e == 0){
		print("out of envs\n");
		error(0,Enoenv);
		error(Enoenv);
	}
	envalloc.efree = e->next;
	e->next = 0;


@@ 358,11 358,11 @@ envcreate(Chan *c, char *name, int omode, ulong perm)
				break;
		if(i == pg->nenv){
			print("out of pgroup envs\n");
			error(0, Enoenv);
			error(Enoenv);
		}
	}else
		i = pg->nenv++;
	c->qid = i+1;
	c->qid.path = i+1;
	pg->etab[i].env = e;
	pg->etab[i].chref = 1;
	unlock(&envalloc);


@@ 380,15 380,15 @@ envremove(Chan *c)
	Envp *ep;
	Pgrp *pg;

	if(c->qid & CHDIR)
		error(0, Eperm);
	if(c->qid.path & CHDIR)
		error(Eperm);
	pg = u->p->pgrp;
	lock(pg);
	ep = &pg->etab[c->qid-1];
	ep = &pg->etab[c->qid.path-1];
	e = ep->env;
	if(!e){
		unlock(pg);
		error(0, Enonexist);
		error(Enonexist);
	}
	ep->env = 0;
	ep->chref--;


@@ 401,7 401,7 @@ envwstat(Chan *c, char *db)
{	int dumpenv(void);
	dumpenv();  /*DEBUG*/
	print("envwstat\n");
	error(0, Egreg);
	error(Egreg);
}

void


@@ 409,11 409,11 @@ envclose(Chan * c)
{
	Pgrp *pg;

	if(c->qid & CHDIR)
	if(c->qid.path & CHDIR)
		return;
	pg = u->p->pgrp;
	lock(pg);
	pg->etab[c->qid-1].chref--;
	pg->etab[c->qid.path-1].chref--;
	unlock(pg);
}



@@ 444,14 444,14 @@ envread(Chan *c, void *va, long n)
	Pgrp *pg;
	char *a = va;

	if(c->qid & CHDIR)
	if(c->qid.path & CHDIR)
		return devdirread(c, a, n, 0, 0, envgen);
	pg = u->p->pgrp;
	lock(pg);
	e = pg->etab[c->qid-1].env;
	e = pg->etab[c->qid.path-1].env;
	if(!e){
		unlock(pg);
		error(0, Eio);
		error(Eio);
	}
	lock(e);
	ev = e->val;


@@ 481,10 481,10 @@ envwrite(Chan *c, void *va, long n)
		return 0;
	pg = u->p->pgrp;
	lock(pg);
	e = pg->etab[c->qid-1].env; /* caller checks for CHDIR */
	e = pg->etab[c->qid.path-1].env; /* caller checks for CHDIR */
	if(!e){
		unlock(pg);
		error(0, Eio);
		error(Eio);
	}
	lock(&envalloc);
	lock(e);


@@ 500,7 500,7 @@ envwrite(Chan *c, void *va, long n)
	ev = e->val;
	vn = ev? ev->len : 0;
	if(c->offset > vn)
		error(0, Egreg); /* perhaps should zero fill */
		error(Egreg); /* perhaps should zero fill */
	memcpy(ev->dat+c->offset, a, n);
	e->val->len = c->offset+n;
	poperror();


@@ 543,16 543,3 @@ dumpenv(void)
			i += ev->n*sizeof(Envval);
	print(" %d free enval chars\n", i+((char *)envalloc.end-(char*)envalloc.vfree));
}

void
envuserstr(Error *e, char *buf)
{
	consuserstr(e, buf);
}

void
enverrstr(Error *e, char *buf)
{
	rooterrstr(e, buf);
}


M gnot/devincon.c => gnot/devincon.c +13 -24
@@ 151,7 151,7 @@ inconset(Incon *ip, int cnt, int del)
	Device *dev;

	if (cnt<1 || cnt>14 || del<1 || del>15)
		error(0, Ebadarg);
		error(Ebadarg);

	dev = ip->dev;
	dev->cmd = sel_rcv_cnt | INCON_RUN;


@@ 181,19 181,19 @@ inconsetctl(Incon *ip, Block *bp)
	switch(n){
	default:
		freeb(bp);
		error(0, Ebadarg);
		error(Ebadarg);
	case 2:
		del = strtol(field[1], 0, 0);
		if(del<0 || del>15){
			freeb(bp);
			error(0, Ebadarg);
			error(Ebadarg);
		}
		/* fall through */
	case 1:
		cnt = strtol(field[0], 0, 0);
		if(cnt<0 || cnt>15){
			freeb(bp);
			error(0, Ebadarg);
			error(Ebadarg);
		}
	}
	inconset(ip, cnt, del);


@@ 336,14 336,15 @@ inconattach(char *spec)

	i = strtoul(spec, 0, 0);
	if(i >= Nincon)
		error(0, Ebadarg);
		error(Ebadarg);
	ip = &incon[i];
	if(ip->state != Selected)
		inconrestart(ip);

	c = devattach('i', spec);
	c->dev = i;
	c->qid = CHDIR;
	c->qid.path = CHDIR;
	c->qid.vers = 0;
	return c;
}



@@ 368,9 369,9 @@ inconstat(Chan *c, char *dp)
Chan*
inconopen(Chan *c, int omode)
{
	if(c->qid == CHDIR){
	if(c->qid.path == CHDIR){
		if(omode != OREAD)
			error(0, Eperm);
			error(Eperm);
	}else
		streamopen(c, &inconinfo);
	c->mode = openmode(omode);


@@ 382,13 383,13 @@ inconopen(Chan *c, int omode)
void	 
inconcreate(Chan *c, char *name, int omode, ulong perm)
{
	error(0, Eperm);
	error(Eperm);
}

void	 
inconclose(Chan *c)
{
	if(c->qid != CHDIR)
	if(c->qid.path != CHDIR)
		streamclose(c);
}



@@ 407,25 408,13 @@ inconwrite(Chan *c, void *buf, long n)
void	 
inconremove(Chan *c)
{
	error(0, Eperm);
	error(Eperm);
}

void	 
inconwstat(Chan *c, char *dp)
{
	error(0, Eperm);
}

void
inconuserstr(Error *e, char *buf)
{
	consuserstr(e, buf);
}

void	 
inconerrstr(Error *e, char *buf)
{
	rooterrstr(e, buf);
	error(Eperm);
}

/*

M gnot/devmnt.c => gnot/devmnt.c +38 -88
@@ 9,7 9,6 @@

#include	"fcall.h"


typedef struct Mnt	Mnt;
typedef struct Mnthdr	Mnthdr;
typedef struct MntQ	MntQ;


@@ 194,7 193,7 @@ mntdev(int dev, int noerr)
		}
	if(noerr)
		return 0;
	error(0, Eshutdown);
	error(Eshutdown);
}

void


@@ 214,9 213,12 @@ mntreset(void)
	mntbufalloc.free = mb;

	mh = ialloc(conf.nmnthdr*sizeof(Mnthdr), 0);
	for(i=0; i<conf.nmnthdr-1; i++)
	for(i=0; i<conf.nmnthdr-1; i++){
		mh[i].next = &mh[i+1];
		mh[i].thdr.tag = i;
	}
	mh[i].next = 0;
	mh[i].thdr.tag = i;
	mnthdralloc.free = mh;

	mq = ialloc(conf.nmntdev*sizeof(MntQ), 0);


@@ 233,7 235,7 @@ mntinit(void)
}

Chan*
mntattach(char *spec)
mntattach(char *crud)
{
	int i;
	Mnt *m, *mm;


@@ 243,10 245,10 @@ mntattach(char *spec)
	struct bogus{
		Chan	*chan;
		char	*spec;
		char	*auth;
	}bogus;

	bogus = *((struct bogus *)spec);
	spec = bogus.spec;
	bogus = *((struct bogus *)crud);

	m = mnt;
	for(i=0; i<conf.nmntdev; i++,m++){


@@ 255,7 257,7 @@ mntattach(char *spec)
			goto Found;
		unlock(m);
	}
	error(0, Enomntdev);
	error(Enomntdev);

    Found:
	m->ref = 1;


@@ 263,7 265,7 @@ mntattach(char *spec)
	lock(&mntid);
	m->mntid = ++mntid.id;
	unlock(&mntid);
	c = devattach('M', spec);
	c = devattach('M', bogus.spec);
	c->dev = m->mntid;
	m->mntpt = c;
	cm = bogus.chan;


@@ 297,7 299,8 @@ mntattach(char *spec)
	mh->thdr.type = Tattach;
	mh->thdr.fid = c->fid;
	memcpy(mh->thdr.uname, u->p->pgrp->user, NAMELEN);
	strcpy(mh->thdr.aname, spec);
	strcpy(mh->thdr.aname, bogus.spec);
	strcpy(mh->thdr.auth, bogus.auth);
	mntxmit(m, mh);
	c->qid = mh->rhdr.qid;
	c->mchan = m->q->msg;


@@ 537,7 540,7 @@ mntread(Chan *c, void *buf, long n)
	uchar *b;

	n = mntreadwrite(c, buf, n, Tread);
	if(c->qid & CHDIR){
	if(c->qid.path & CHDIR){
		b = (uchar*)buf;
		for(i=n-DIRLEN; i>=0; i-=DIRLEN){
			b[DIRLEN-4] = devchar[c->type];


@@ 582,60 585,6 @@ mntwstat(Chan *c, char *dp)
	poperror();
}

void	 
mnterrstr(Error *e, char *buf)
{
	Mnt *m;
	Mnthdr *mh;
	char *def="mounted device shut down";

	m = mntdev(e->dev, 1);
	if(m == 0){
		strcpy(buf, def);
		return;
	}
	mh = mhalloc();
	if(waserror()){
		strcpy(buf, def);
		mhfree(mh);
		nexterror();
	}
	mh->thdr.type = Terrstr;
	mh->thdr.fid = 0;
	mh->thdr.err = e->code;
	mntxmit(m, mh);
	strcpy(buf, (char*)mh->rhdr.ename);
	mhfree(mh);
	poperror();
}

void	 
mntuserstr(Error *e, char *buf)
{
	Mnt *m;
	Mnthdr *mh;
	char *def="mounted device shut down";

	m = mntdev(e->dev, 1);
	if(m == 0){
		strcpy(buf, def);
		return;
	}
	mh = mhalloc();
	if(waserror()){
		strcpy(buf, def);
		mhfree(mh);
		nexterror();
	}
	mh->thdr.type = Tuserstr;
	mh->thdr.fid = 0;
	mh->thdr.uid = e->code;
	mntxmit(m, mh);
	strcpy(buf, (char*)mh->rhdr.uname);
	mhfree(mh);
	poperror();
}

void
mnterrdequeue(MntQ *q, Mnthdr *mh)		/* queue is unlocked */
{


@@ 670,18 619,19 @@ mnterrdequeue(MntQ *q, Mnthdr *mh)		/* queue is unlocked */
	qunlock(q);

}

int
mntreadreply(void *a)
{
	return ((Mnthdr *)a)->readreply;
}

void
mntxmit(Mnt *m, Mnthdr *mh)
{
	ulong n;
	Mntbuf *mbw;
	Mnthdr *w, *ow;
	Chan *mntpt;
	MntQ *q;
	int qlocked;



@@ 695,7 645,7 @@ mntxmit(Mnt *m, Mnthdr *mh)
	n = convS2M(&mh->thdr, mbw->buf);
	q = m->q;
	if(q == 0)
		error(0, Eshutdown);
		error(Eshutdown);
#ifdef	BIT3
	/*
	 * Bit3 does its own multiplexing.  (Well, the file server does.)


@@ 711,7 661,7 @@ mntxmit(Mnt *m, Mnthdr *mh)
	}
	if((*devtab[q->msg->type].write)(q->msg, mbw->buf, n) != n){
		print("short write in mntxmit\n");
		error(0, Eshortmsg);
		error(Eshortmsg);
	}

	/*


@@ 723,25 673,28 @@ mntxmit(Mnt *m, Mnthdr *mh)

	if(convM2S(mh->mbr->buf, &mh->rhdr, n) == 0){
		print("format error in mntxmit\n");
		error(0, Ebadmsg);
		error(Ebadmsg);
	}

	/*
	 * Various checks
	 */
	if(mh->rhdr.tag != mh->thdr.tag){
		print("tag mismatch %d %d\n", mh->rhdr.tag, mh->thdr.tag);
		error(Ebadmsg);
	}
	if(mh->rhdr.type == Rerror){
		if(m->mntpt)
			errors(mh->rhdr.ename);
		error(Eshutdown);
	}
	if(mh->rhdr.type != mh->thdr.type+1){
		print("type mismatch %d %d\n", mh->rhdr.type, mh->thdr.type+1);
		error(0, Ebadmsg);
		error(Ebadmsg);
	}
	if(mh->rhdr.fid != mh->thdr.fid){
		print("fid mismatch %d %d type %d\n", mh->rhdr.fid, mh->thdr.fid, mh->rhdr.type);
		error(0, Ebadmsg);
	}
	if(mh->rhdr.err){
		mntpt = m->mntpt;	/* unsafe, but Errors are unsafe anyway */
		if(mntpt)
			error(mntpt, mh->rhdr.err);
		error(0, Eshutdown);
		error(Ebadmsg);
	}

	/*


@@ 768,7 721,7 @@ mntxmit(Mnt *m, Mnthdr *mh)
	mh->readreply = 0;
	if((*devtab[q->msg->type].write)(q->msg, mbw->buf, n) != n){
		print("short write in mntxmit\n");
		error(0, Eshortmsg);
		error(Eshortmsg);
	}
	if(q->reader == 0){		/* i will read */
		q->reader = u->p;


@@ 783,15 736,14 @@ mntxmit(Mnt *m, Mnthdr *mh)
		poperror();
		if(convM2S(mh->mbr->buf, &mh->rhdr, n) == 0){
			mnterrdequeue(q, mh);
			error(0, Ebadmsg);
			error(Ebadmsg);
		}
		/*
		 * Response might not be mine
		 */
		qlock(q);
		qlocked = 1;
		if(mh->rhdr.fid == mh->thdr.fid
		&& mh->rhdr.type == mh->thdr.type+1){	/* it's mine */
		if(mh->rhdr.tag == mh->thdr.tag){	/* it's mine */
			q->reader = 0;
			if(w = q->writer){	/* advance a writer to reader */
				q->reader = w->p;


@@ 807,8 759,7 @@ mntxmit(Mnt *m, Mnthdr *mh)
		 * Hand response to correct recipient
		 */
		for(ow=0,w=q->writer; w; ow=w,w=w->next)
			if(mh->rhdr.fid == w->thdr.fid
			&& mh->rhdr.type == w->thdr.type+1){
			if(mh->rhdr.tag == w->thdr.tag){
				Mntbuf *t;
				t = mh->mbr;
				mh->mbr = w->mbr;


@@ 849,18 800,17 @@ mntxmit(Mnt *m, Mnthdr *mh)
    Respond:
	mqfree(q);
	poperror();
	if(mh->rhdr.err){
		mntpt = m->mntpt;	/* unsafe, but Errors are unsafe anyway */
		if(mntpt)
			error(mntpt, mh->rhdr.err);
		error(0, Eshutdown);
	if(mh->rhdr.type == Rerror){
		if(m->mntpt)
			errors(mh->rhdr.ename);
		error(Eshutdown);
	}
	/*
	 * Copy out on read
	 */
	if(mh->thdr.type == Tread){
		if(mh->rhdr.count > mh->thdr.count)
			error(0, Ebadcnt);
			error(Ebadcnt);
		memcpy(mh->thdr.data, mh->rhdr.data, mh->rhdr.count);
	}
	mbfree(mh->mbr);

M gnot/devpipe.c => gnot/devpipe.c +25 -39
@@ 37,10 37,10 @@ Qinfo pipeinfo =
};

Dirtab pipedir[]={
	"data",		Sdataqid,	0,			0600,
	"ctl",		Sctlqid,	0,			0600,
	"data1",	Sdataqid,	0,			0600,
	"ctl1",		Sctlqid,	0,			0600,
	"data",		{Sdataqid},	0,			0600,
	"ctl",		{Sctlqid},	0,			0600,
	"data1",	{Sdataqid},	0,			0600,
	"ctl1",		{Sctlqid},	0,			0600,
};
#define NPIPEDIR 4



@@ 78,7 78,7 @@ pipeattach(char *spec)
	lock(&pipealloc);
	if(pipealloc.free == 0){
		unlock(&pipealloc);
		error(0, Enopipe);
		error(Enopipe);
	}
	p = pipealloc.free;
	pipealloc.free = p->next;


@@ 86,7 86,7 @@ pipeattach(char *spec)
		panic("pipeattach");
	unlock(&pipealloc);

	c->qid = CHDIR|STREAMQID(2*(p - pipealloc.pipe), 0);
	c->qid = (Qid){CHDIR|STREAMQID(2*(p - pipealloc.pipe), 0), 0};
	return c;
}



@@ 95,7 95,7 @@ pipeclone(Chan *c, Chan *nc)
{
	Pipe *p;

	p = &pipealloc.pipe[STREAMID(c->qid)/2];
	p = &pipealloc.pipe[STREAMID(c->qid.path)/2];
	nc = devclone(c, nc);
	if(incref(p) <= 1)
		panic("pipeclone");


@@ 107,13 107,13 @@ pipegen(Chan *c, Dirtab *tab, int ntab, int i, Dir *dp)
{
	int id;

	id = STREAMID(c->qid);
	id = STREAMID(c->qid.path);
	if(i > 1)
		id++;
	if(tab==0 || i>=ntab)
		return -1;
	tab += i;
	devdir(c, STREAMQID(id, tab->qid), tab->name, tab->length, tab->perm, dp);
	devdir(c, (Qid){STREAMQID(id, tab->qid.path),0}, tab->name, tab->length, tab->perm, dp);
	return 1;
}



@@ 139,16 139,16 @@ pipeopen(Chan *c, int omode)
	Pipe *p;
	Stream *local, *remote;

	if(CHDIR & c->qid){
	if(c->qid.path & CHDIR){
		if(omode != OREAD)
			error(0, Ebadarg);
			error(Ebadarg);
		c->mode = omode;
		c->flag |= COPEN;
		c->offset = 0;
		return c;
	}

	p = &pipealloc.pipe[STREAMID(c->qid)/2];
	p = &pipealloc.pipe[STREAMID(c->qid.path)/2];
	remote = 0;
	if(waserror()){
		unlock(p);


@@ 163,7 163,7 @@ pipeopen(Chan *c, int omode)
		/*
		 *  First stream opened, create the other end also
		 */
		remote = streamnew(c->type, c->dev, STREAMID(c->qid)^1, &pipeinfo, 1);
		remote = streamnew(c->type, c->dev, STREAMID(c->qid.path)^1, &pipeinfo, 1);

		/*
		 *  connect the device ends of both streams


@@ 192,33 192,37 @@ pipeopen(Chan *c, int omode)
void
pipecreate(Chan *c, char *name, int omode, ulong perm)
{
	error(0, Egreg);
	error(Egreg);
}

void
piperemove(Chan *c)
{
	error(0, Egreg);
	error(Egreg);
}

void
pipewstat(Chan *c, char *db)
{
	error(0, Eperm);
	error(Eperm);
}

void
pipeclose(Chan *c)
{
	Pipe *p;
	Stream *remote;

	p = &pipealloc.pipe[STREAMID(c->qid)/2];
	p = &pipealloc.pipe[STREAMID(c->qid.path)/2];

	/*
	 *  take care of associated streams
	 */
	if(c->stream)
		streamclose(c);		/* close this stream */
	if(c->stream){
		remote = c->stream->devq->ptr;
		if(streamclose(c) <= 0)
			streamexit(remote, 0);
	}

	/*
	 *  free the structure


@@ 236,7 240,7 @@ pipeclose(Chan *c)
long
piperead(Chan *c, void *va, long n)
{
	if(CHDIR&c->qid)
	if(c->qid.path & CHDIR)
		return devdirread(c, va, n, pipedir, NPIPEDIR, pipegen);
	else
		return streamread(c, va, n);


@@ 251,25 255,13 @@ pipewrite(Chan *c, void *va, long n)
{
	if(waserror()){
		postnote(u->p, 1, "sys: write on closed pipe", NExit);
		error(0, Egreg);
		error(Egreg);
	}
	n = streamwrite(c, va, n, 0);
	poperror();
	return n;
}

void
pipeuserstr(Error *e, char *buf)
{
	consuserstr(e, buf);
}

void
pipeerrstr(Error *e, char *buf)
{
	rooterrstr(e, buf);
}

/*
 *  stream stuff
 */


@@ 317,10 309,4 @@ pipestclose(Queue *q)
	bp = allocb(0);
	bp->type = M_HANGUP;
	PUTNEXT(q, bp);

	/*
	 *  release stream for other half of pipe
	 */
	remote = RD(q)->ptr;
	streamexit(remote, 0);
}

M gnot/devproc.c => gnot/devproc.c +62 -69
@@ 5,6 5,9 @@
#include	"fns.h"
#include	"errno.h"

/* BUG mips only TAKE IT OUT */
#include	"io.h"

#include	"devtab.h"

enum{


@@ 19,28 22,28 @@ enum{
};

Dirtab procdir[]={
	"ctl",		Qctl,		0,			0600,
	"mem",		Qmem,		0,			0600,
	"note",		Qnote,		0,			0600,
	"notepg",	Qnotepg,	0,			0200,
	"proc",		Qproc,		sizeof(Proc),		0600,
	"status",	Qstatus,	NAMELEN+12+6*12,	0600,
	"text",		Qtext,		0,			0600,
	"ctl",		{Qctl},		0,			0600,
	"mem",		{Qmem},		0,			0600,
	"note",		{Qnote},	0,			0600,
	"notepg",	{Qnotepg},	0,			0200,
	"proc",		{Qproc},	sizeof(Proc),		0600,
	"status",	{Qstatus},	NAMELEN+12+6*12,	0600,
	"text",		{Qtext},	0,			0600,
};

/*
 * Qids are, from bottom to top:
 * Qids are, in path:
 *	 4 bits of file type (qids above)
 *	12 bits of process slot number + 1
 *	15 bits of pid, for consistency checking
 *	24 bits of process slot number + 1
 *	     in vers,
 *	32 bits of pid, for consistency checking
 * If notepg, c->pgrpid.path is pgrp slot, .vers is pgrpid.
 */
#define	NPROC	(sizeof procdir/sizeof(Dirtab))
#define	QSHIFT	4	/* location in qid of proc slot # */
#define	PIDSHIFT 16	/* location in qid of pid */
#define	PIDMASK	0x7FFF	/* low bits of pid used in qid */
#define	QID(q)	(((q)&0x0000000F)>>0)
#define	SLOT(q)	((((q)&0x0000FFF0)>>QSHIFT)-1)
#define	PID(q)	(((q)&0x7FFF0000)>>PIDSHIFT)
#define	QID(q)	(((q).path&0x0000000F)>>0)
#define	SLOT(q)	((((q).path&0x0FFFFFFF0)>>QSHIFT)-1)
#define	PID(q)	((q).vers)

int
procgen(Chan *c, Dirtab *tab, int ntab, int s, Dir *dp)


@@ 49,7 52,7 @@ procgen(Chan *c, Dirtab *tab, int ntab, int s, Dir *dp)
	char buf[NAMELEN];
	ulong pid;

	if(c->qid == CHDIR){
	if(c->qid.path == CHDIR){
		if(s >= conf.nproc)
			return -1;
		p = proctab(s);


@@ 57,7 60,7 @@ procgen(Chan *c, Dirtab *tab, int ntab, int s, Dir *dp)
		if(pid == 0)
			return 0;
		sprint(buf, "%d", pid);
		devdir(c, CHDIR|(pid<<PIDSHIFT)|((s+1)<<QSHIFT), buf, 0, CHDIR|0500, dp);
		devdir(c, (Qid){CHDIR|((s+1)<<QSHIFT), pid}, buf, 0, CHDIR|0500, dp);
		return 1;
	}
	if(s >= NPROC)


@@ 65,7 68,8 @@ procgen(Chan *c, Dirtab *tab, int ntab, int s, Dir *dp)
	if(tab)
		panic("procgen");
	tab = &procdir[s];
	devdir(c, (~CHDIR)&(c->qid|tab->qid), tab->name, tab->length, tab->perm, dp);
	devdir(c, (Qid){(~CHDIR)&(c->qid.path|tab->qid.path), c->qid.vers},
		tab->name, tab->length, tab->perm, dp);
	return 1;
}



@@ 114,16 118,16 @@ procopen(Chan *c, int omode)
	Orig *o;
	Chan *tc;

	if(c->qid == CHDIR){
	if(c->qid.path == CHDIR){
		if(omode != OREAD)
			error(0, Eperm);
			error(Eperm);
		goto done;
	}
	p = proctab(SLOT(c->qid));
	pg = p->pgrp;
	if((p->pid&PIDMASK) != PID(c->qid))
	if(p->pid != PID(c->qid))
    Died:
		error(0, Eprocdied);
		error(Eprocdied);
	omode = openmode(omode);

	switch(QID(c->qid)){


@@ 141,7 145,7 @@ procopen(Chan *c, int omode)
		}
		if(!(tc->flag&COPEN) || tc->mode!=OREAD)
			goto Close;
		if((p->pid&PIDMASK) != PID(c->qid))
		if(p->pid != PID(c->qid))
			goto Close;
		qlock(tc);
		tc->offset = 0;


@@ 153,8 157,9 @@ procopen(Chan *c, int omode)

	case Qnotepg:
		if(omode!=OWRITE || pg->pgrpid==1)	/* easy to do by mistake */
			error(0, Eperm);
		c->pgrpid = (pg->pgrpid<<PIDSHIFT)|((pg->index+1)<<QSHIFT);
			error(Eperm);
		c->pgrpid.path = pg->index+1;
		c->pgrpid.vers = pg->pgrpid;
		break;

	case Qdir:


@@ 162,17 167,17 @@ procopen(Chan *c, int omode)
	case Qproc:
	case Qstatus:
		if(omode != OREAD)
			error(0, Eperm);
			error(Eperm);
		break;
	default:
		pprint("unknown qid in devopen\n");
		error(0, Egreg);
		error(Egreg);
	}
	/*
	 * Affix pid to qid
	 */
	if(p->state != Dead)
		c->qid |= (p->pid&PIDMASK)<<PIDSHIFT;
		c->qid.vers = p->pid;
   done:
	c->mode = omode;
	c->flag |= COPEN;


@@ 183,19 188,19 @@ procopen(Chan *c, int omode)
void
proccreate(Chan *c, char *name, int omode, ulong perm)
{
	error(0, Eperm);
	error(Eperm);
}

void
procremove(Chan *c)
{
	error(0, Eperm);
	error(Eperm);
}

void
procwstat(Chan *c, char *db)
{
	error(0, Eperm);
	error(Eperm);
}

void


@@ 219,15 224,15 @@ procread(Chan *c, void *va, long n)
	long pid;
	User *up;

	if(c->qid & CHDIR)
	if(c->qid.path & CHDIR)
		return devdirread(c, a, n, 0, 0, procgen);

	/*
	 * BUG: should lock(&p->debug)?
	 */
	p = proctab(SLOT(c->qid));
	if((p->pid&PIDMASK) != PID(c->qid))
		error(0, Eprocdied);
	if(p->pid != PID(c->qid))
		error(Eprocdied);

	switch(QID(c->qid)){
	case Qmem:


@@ 240,15 245,15 @@ procread(Chan *c, void *va, long n)
		if(s){
			o = s->o;
			if(o == 0)
				error(0, Eprocdied);
				error(Eprocdied);
			lock(o);
			if(s->o!=o || (p->pid&PIDMASK)!=PID(c->qid)){
			if(s->o!=o || p->pid!=PID(c->qid)){
				unlock(o);
				error(0, Eprocdied);
				error(Eprocdied);
			}
			if(seg(p, c->offset) != s){
				unlock(o);
				error(0, Egreg);
				error(Egreg);
			}
			pte = &o->pte[(c->offset-o->va)>>PGSHIFT];
			if(s->mod){


@@ 278,8 283,8 @@ procread(Chan *c, void *va, long n)
			if(c->offset+n > USERADDR+BY2PG)
				n = USERADDR+BY2PG - c->offset;
			pg = p->upage;
			if(pg==0 || (p->pid&PIDMASK)!=PID(c->qid))
				error(0, Eprocdied);
			if(pg==0 || p->pid!=PID(c->qid))
				error(Eprocdied);
			k = kmap(pg);
			b = (char*)VA(k);
			memcpy(a, b+(c->offset-USERADDR), n);


@@ 303,17 308,17 @@ procread(Chan *c, void *va, long n)
			unlock(&p->debug);
			nexterror();
		}
		if((p->pid&PIDMASK) != PID(c->qid))
			error(0, Eprocdied);
		if(p->pid != PID(c->qid))
			error(Eprocdied);
		k = kmap(p->upage);
		up = (User*)VA(k);
		if(up->p != p){
			kunmap(k);
			pprint("note read u/p mismatch");
			error(0, Egreg);
			error(Egreg);
		}
		if(n < ERRLEN)
			error(0, Etoosmall);
			error(Etoosmall);
		if(up->nnote == 0)
			n = 0;
		else{


@@ 350,7 355,7 @@ procread(Chan *c, void *va, long n)
		memcpy(a, statbuf+c->offset, n);
		return n;
	}
	error(0, Egreg);
	error(Egreg);
}




@@ 363,20 368,20 @@ procwrite(Chan *c, void *va, long n)
	KMap *k;
	char buf[ERRLEN];

	if(c->qid & CHDIR)
		error(0, Eisdir);
	if(c->qid.path & CHDIR)
		error(Eisdir);

	/*
	 * Special case: don't worry about process, just use remembered group
	 */
	if(QID(c->qid) == Qnotepg){
		pg = pgrptab(SLOT(c->pgrpid));
		pg = pgrptab(c->pgrpid.path-1);
		lock(&pg->debug);
		if(waserror()){
			unlock(&pg->debug);
			nexterror();
		}
		if((pg->pgrpid&PIDMASK) != PID(c->pgrpid)){
		if(pg->pgrpid != c->pgrpid.vers){
			unlock(&pg->debug);
  	  		goto Died;
		}


@@ 391,16 396,16 @@ procwrite(Chan *c, void *va, long n)
		unlock(&p->debug);
		nexterror();
	}
	if((p->pid&PIDMASK) != PID(c->qid))
	if(p->pid != PID(c->qid))
    Died:
		error(0, Eprocdied);
		error(Eprocdied);

	switch(QID(c->qid)){
	case Qctl:
		if(p->state==Broken && n>=4 && strncmp(va, "exit", 4)==0)
			ready(p);
		else
			error(0, Ebadctl);
			error(Ebadctl);
		break;
	case Qnote:
		k = kmap(p->upage);


@@ 408,34 413,22 @@ procwrite(Chan *c, void *va, long n)
		if(up->p != p){
			kunmap(k);
			pprint("note write u/p mismatch");
			error(0, Egreg);
			error(Egreg);
		}
		kunmap(k);
		if(n >= ERRLEN-1)
			error(0, Etoobig);
			error(Etoobig);
		if(n>=4 && strncmp(va, "sys:", 4)==0)
			error(0, Ebadarg);
			error(Ebadarg);
		memcpy(buf, va, n);
		buf[n] = 0;
		if(!postnote(p, 0, buf, NUser))
			error(0, Enonote);
			error(Enonote);
		break;
	default:
		pprint("unknown qid in procwrite\n");
		error(0, Egreg);
		error(Egreg);
	}
	unlock(&p->debug);
	return n;
}

void
procuserstr(Error *e, char *buf)
{
	consuserstr(e, buf);
}

void
procerrstr(Error *e, char *buf)
{
	rooterrstr(e, buf);
}

M gnot/devroot.c => gnot/devroot.c +11 -28
@@ 16,11 16,11 @@ enum{
};

Dirtab rootdir[]={
	"bin",		Qbin|CHDIR,	0,			0700,
	"boot",		Qboot,		0,			0700,
	"dev",		Qdev|CHDIR,	0,			0700,
	"env",		Qenv|CHDIR,	0,			0700,
	"proc",		Qproc|CHDIR,	0,			0700,
	"bin",		{Qbin|CHDIR},	0,			0700,
	"boot",		{Qboot},	0,			0700,
	"dev",		{Qdev|CHDIR},	0,			0700,
	"env",		{Qenv|CHDIR},	0,			0700,
	"proc",		{Qproc|CHDIR},	0,			0700,
};

#define	NROOT	(sizeof rootdir/sizeof(Dirtab))


@@ 68,7 68,7 @@ rootopen(Chan *c, int omode)
void	 
rootcreate(Chan *c, char *name, int omode, ulong perm)
{
	error(0, Eperm);
	error(Eperm);
}

/*


@@ 85,7 85,7 @@ long
rootread(Chan *c, void *buf, long n)
{

	switch(c->qid & ~CHDIR){
	switch(c->qid.path & ~CHDIR){
	case Qdir:
		return devdirread(c, buf, n, rootdir, NROOT, devgen);



@@ 100,41 100,24 @@ rootread(Chan *c, void *buf, long n)
	case Qdev:
		return 0;
	}
	error(0, Egreg);
	error(Egreg);
	return 0;
}

long	 
rootwrite(Chan *c, void *buf, long n)
{
	error(0, Egreg);
	error(Egreg);
}

void	 
rootremove(Chan *c)
{
	error(0, Eperm);
	error(Eperm);
}

void	 
rootwstat(Chan *c, char *dp)
{
	error(0, Eperm);
}

void
rootuserstr(Error *e, char *buf)
{
	consuserstr(e, buf);
}

#include "errstr.h"

void	 
rooterrstr(Error *e, char *buf)
{
	if(e->code<0 || e->code>=sizeof errstrtab/sizeof(char*))
		strcpy(buf, "no such error");
	else
		strcpy(buf, errstrtab[e->code]);
	error(Eperm);
}

M gnot/devsrv.c => gnot/devsrv.c +17 -31
@@ 45,7 45,7 @@ srvalloc(int mode){
	e = calloc(1, sizeof(Entry));
	e->dir.atime = e->dir.mtime = seconds();
	lock(&qidlock);	/* for qid allocation */
	e->dir.qid = mode | nextqid++;
	e->dir.qid = (Qid){mode|nextqid++, 0};
	unlock(&qidlock);
	return e;
}


@@ 97,9 97,7 @@ srvwalk(Chan *c, char *name)
		unlock(dir);
	}
	if(e==0){
		u->error.code = Enonexist;
		u->error.type = 0;
		u->error.dev = 0;
		strncpy(u->error, errstrtab[Enonexist], NAMELEN);
		return 0;
	}
	c->qid = e->dir.qid;


@@ 122,22 120,22 @@ srvopen(Chan *c, int omode)
	Entry *e;
	Chan *f;

	if(c->qid & CHDIR){
	if(c->qid.path & CHDIR){
		if(omode != OREAD)
			error(0, Eisdir);
			error(Eisdir);
		c->mode = omode;
		c->flag |= COPEN;
		c->offset = 0;
		return c;
	}
	if((e=c->aux) == 0)
		error(0, Egreg);
		error(Egreg);
	if((f=e->chan) == 0)
		error(0, Eshutdown);
		error(Eshutdown);
	if(omode & OTRUNC)
		error(0, Eperm);
		error(Eperm);
	if(omode!=f->mode && f->mode!=ORDWR)
		error(0, Eperm);
		error(Eperm);
	close(c);
	incref(f);
	return f;


@@ 157,12 155,12 @@ srvcreate(Chan *c, char *name, int omode, ulong perm)
	}
	for(e=parent->entries; e; e=e->next)
		if(strcmp(name, e->dir.name) == 0)
			error(0, Einuse);
			error(Einuse);
	e = srvalloc(perm & CHDIR);
	e->parent = parent;
	strcpy(e->dir.name, name);
	e->dir.mode = perm & parent->dir.mode;
	e->dir.gid = parent->dir.gid;
	strcpy(e->dir.gid, parent->dir.gid);
	if(e->next = parent->entries)	/* assign = */
		e->next->back = &e->next;
	e->back = &parent->entries;


@@ 183,7 181,7 @@ srvremove(Chan *c)

	e = c->aux;
	if(e->parent == 0)
		error(0, Eperm);
		error(Eperm);
	lock(e->parent);
	if(waserror()){
		unlock(e->parent);


@@ 191,10 189,10 @@ srvremove(Chan *c)
	}
	if(e->dir.mode & CHDIR){
		if (e->entries != 0)
			error(0, Eperm);
			error(Eperm);
	}else{
		if(e->chan == 0)
			error(0, Eshutdown);
			error(Eshutdown);
		close(e->chan);
	}
	if(*e->back = e->next)	/* assign = */


@@ 207,7 205,7 @@ srvremove(Chan *c)
void
srvwstat(Chan *c, char *dp)
{
	error(0, Egreg);
	error(Egreg);
}

void


@@ 244,7 242,7 @@ srvread(Chan *c, void *va, long n)
	if(n <= 0)
		return 0;
	if(offset%DIRLEN || n%DIRLEN)
		error(0, Ebaddirread);
		error(Ebaddirread);
	lock(dir);
	for(e=dir->entries; e; e=e->next)
		if(offset <= 0){


@@ 274,9 272,9 @@ srvwrite(Chan *c, void *va, long n)
		nexterror();
	}
	if(e->chan)
		error(0, Egreg);
		error(Egreg);
	if(n >= sizeof buf)
		error(0, Egreg);
		error(Egreg);
	memcpy(buf, va, n);	/* so we can NUL-terminate */
	buf[n] = 0;
	fd = strtoul(buf, 0, 0);


@@ 287,15 285,3 @@ srvwrite(Chan *c, void *va, long n)
	poperror();
	return n;
}

void
srverrstr(Error *e, char *buf)
{
	rooterrstr(e, buf);
}

void
srvuserstr(Error *e, char *buf)
{
	consuserstr(e, buf);
}

M gnot/fault.c => gnot/fault.c +3 -3
@@ 161,7 161,7 @@ fault(Ureg *ur, FFrame *f)
			k = kmap(pg);
			qlock(o->chan);
			if(waserror()){
				print("demand load i/o error %d\n", u->error.code);
				print("demand load i/o error %s\n", u->error);
				kunmap(k);
				qunlock(o->chan);
				pg->o = 0;


@@ 171,7 171,7 @@ fault(Ureg *ur, FFrame *f)
			o->chan->offset = (addr-o->va) + o->minca;
			l = (char*)VA(k);
			if((*devtab[o->chan->type].read)(o->chan, l, n) != n)
				error(0, Eioload);
				error(Eioload);
			qunlock(o->chan);
			if(n<BY2PG)
				memset(l+n, 0, BY2PG-n);


@@ 291,7 291,7 @@ validaddr(ulong addr, ulong len, int write)
    Err:
		pprint("invalid address in sys call pc %lux sp %lux\n", ((Ureg*)UREGADDR)->pc, ((Ureg*)UREGADDR)->sp);
		postnote(u->p, 1, "sys: bad address", NDebug);
		error(0, Ebadarg);
		error(Ebadarg);
	}
    Again:
	s = seg(u->p, addr);

M gnot/fcall.c => gnot/fcall.c +107 -104
@@ 1,12 1,12 @@
#include	<u.h>
#include	"lib.h"
#include	"fcall.h"
#include	<libc.h>
#include	<fcall.h>

#define	CHAR(x)		*p++ = f->x
#define	SHORT(x)	p[0] = f->x; p[1] = f->x>>8; p += 2
#define	LONG(x)		p[0] = f->x; p[1] = f->x>>8; p[2] = f->x>>16; p[3] = f->x>>24; p += 4
#define	VLONG(x)	p[0] = f->x; p[1] = f->x>>8; p[2] = f->x>>16; p[3] = f->x>>24;\
			p[4] = 0; p[5] = 0; p[6] = 0; p[7] = 0; p += 8
				p[4] = 0; p[5] = 0; p[6] = 0; p[7] = 0; p += 8
#define	STRING(x,n)	memcpy(p, f->x, n); p += n

int


@@ 16,24 16,28 @@ convS2M(Fcall *f, char *ap)

	p = (uchar*)ap;
	CHAR(type);
	SHORT(tag);
	switch(f->type)
	{
	default:
		print("bad type: %d\n", f->type);
		print("fcall: bad type: %d\n", f->type);
		return 0;

	case Tnop:
	case Rnop:
		break;

	case Tsession:
		CHAR(lang);
		break;

	case Tflush:
		SHORT(oldtag);
		break;

	case Tattach:
		SHORT(fid);
		STRING(uname, sizeof(f->uname));
		STRING(aname, sizeof(f->aname));
		STRING(auth, sizeof(f->auth));
		break;

	case Tclone:


@@ 42,7 46,6 @@ convS2M(Fcall *f, char *ap)
		break;

	case Twalk:
	case Tremove:
		SHORT(fid);
		STRING(name, sizeof(f->name));
		break;


@@ 59,108 62,106 @@ convS2M(Fcall *f, char *ap)
		CHAR(mode);
		break;

	case Toread:
	case Tread:
		SHORT(fid);
		VLONG(offset);
		SHORT(count);
		break;

	case Towrite:
		SHORT(fid);
		VLONG(offset);
		SHORT(count);
		STRING(data, f->count);
		break;

	case Twrite:
		SHORT(fid);
		VLONG(offset);
		SHORT(count);
		p++;
		p++;	/* pad(1) */
		STRING(data, f->count);
		break;

	case Tclunk:
	case Tstat:
		SHORT(fid);
		break;

	case Twstat:
	case Tremove:
		SHORT(fid);
		STRING(stat, sizeof(f->stat));
		break;

	case Terrstr:
	case Tstat:
		SHORT(fid);
		SHORT(err);
		break;

	case Tuserstr:
	case Twstat:
		SHORT(fid);
		SHORT(uid);
		STRING(stat, sizeof(f->stat));
		break;
/*
 */
	case Rnop:
		break;

	case Rsession:
		SHORT(err);
		break;

	case Rerror:
		STRING(ename, sizeof(f->ename));
		break;

	case Rflush:
		break;

	case Rattach:
		SHORT(fid);
		LONG(qid.path);
		LONG(qid.vers);
		break;

	case Rclone:
	case Rclunk:
	case Rremove:
	case Rwstat:
		SHORT(fid);
		SHORT(err);
		break;

	case Rwalk:
	case Rattach:
		SHORT(fid);
		LONG(qid.path);
		LONG(qid.vers);
		break;

	case Ropen:
	case Rcreate:
		SHORT(fid);
		SHORT(err);
		LONG(qid);
		LONG(qid.path);
		LONG(qid.vers);
		break;

	case Roread:
	case Rcreate:
		SHORT(fid);
		SHORT(err);
		SHORT(count);
		STRING(data, f->count);
		LONG(qid.path);
		LONG(qid.vers);
		break;

	case Rread:
		SHORT(fid);
		SHORT(err);
		SHORT(count);
		p++;
		p++;	/* pad(1) */
		STRING(data, f->count);
		break;

	case Rowrite:
	case Rwrite:
		SHORT(fid);
		SHORT(err);
		SHORT(count);
		break;

	case Rstat:
	case Rclunk:
		SHORT(fid);
		SHORT(err);
		STRING(stat, sizeof(f->stat));
		break;

	case Rerrstr:
	case Rremove:
		SHORT(fid);
		SHORT(err);
		STRING(ename, sizeof(f->ename));
		break;

	case Ruserstr:
	case Rstat:
		SHORT(fid);
		STRING(stat, sizeof(f->stat));
		break;

	case Rwstat:
		SHORT(fid);
		SHORT(err);
		STRING(uname, sizeof(f->uname));
		break;
	}
	return p - (uchar*)ap;


@@ 173,14 174,14 @@ convD2M(Dir *f, char *ap)

	p = (uchar*)ap;
	STRING(name, sizeof(f->name));
	LONG(qid);
	p += 4;
	STRING(uid, sizeof(f->uid));
	STRING(gid, sizeof(f->gid));
	LONG(qid.path);
	LONG(qid.vers);
	LONG(mode);
	LONG(atime);
	LONG(mtime);
	VLONG(length);
	SHORT(uid);
	SHORT(gid);
	SHORT(type);
	SHORT(dev);
	return p - (uchar*)ap;


@@ 195,9 196,9 @@ convD2M(Dir *f, char *ap)
#define	CHAR(x)		f->x = *p++
#define	SHORT(x)	f->x = (p[0] | (p[1]<<8)); p += 2
#define	LONG(x)		f->x = (p[0] | (p[1]<<8) |\
			(p[2]<<16) | (p[3]<<24)); p += 4
				(p[2]<<16) | (p[3]<<24)); p += 4
#define	VLONG(x)	f->x = (p[0] | (p[1]<<8) |\
			(p[2]<<16) | (p[3]<<24)); p += 8
				(p[2]<<16) | (p[3]<<24)); p += 8
#define	STRING(x,n)	memcpy(f->x, p, n); p += n

int


@@ 207,24 208,28 @@ convM2S(char *ap, Fcall *f, int n)

	p = (uchar*)ap;
	CHAR(type);
	SHORT(tag);
	switch(f->type)
	{
	default:
		print("bad type: %d\n", f->type);
		print("fcall: bad type: %d\n", f->type);
		return 0;

	case Tnop:
	case Rnop:
		break;

	case Tsession:
		CHAR(lang);
		break;

	case Tflush:
		SHORT(oldtag);
		break;

	case Tattach:
		SHORT(fid);
		STRING(uname, sizeof(f->uname));
		STRING(aname, sizeof(f->aname));
		STRING(auth, sizeof(f->auth));
		break;

	case Tclone:


@@ 233,7 238,6 @@ convM2S(char *ap, Fcall *f, int n)
		break;

	case Twalk:
	case Tremove:
		SHORT(fid);
		STRING(name, sizeof(f->name));
		break;


@@ 250,29 254,28 @@ convM2S(char *ap, Fcall *f, int n)
		CHAR(mode);
		break;

	case Toread:
	case Tread:
		SHORT(fid);
		VLONG(offset);
		SHORT(count);
		break;

	case Towrite:
	case Twrite:
		SHORT(fid);
		VLONG(offset);
		SHORT(count);
		p++;	/* pad(1) */
		f->data = (char*)p; p += f->count;
		break;

	case Twrite:
	case Tclunk:
		SHORT(fid);
		break;

	case Tremove:
		SHORT(fid);
		VLONG(offset);
		SHORT(count);
		p++;
		f->data = (char*)p; p += f->count;
		break;

	case Tclunk:
	case Tstat:
		SHORT(fid);
		break;


@@ 281,76 284,76 @@ convM2S(char *ap, Fcall *f, int n)
		SHORT(fid);
		STRING(stat, sizeof(f->stat));
		break;
/*
 */
	case Rnop:
		break;

	case Terrstr:
		SHORT(fid);
		SHORT(err);
	case Rsession:
		break;

	case Tuserstr:
		SHORT(fid);
		SHORT(uid);
	case Rerror:
		STRING(ename, sizeof(f->ename));
		break;

	case Rsession:
		SHORT(err);
	case Rflush:
		break;

	case Rattach:
		SHORT(fid);
		LONG(qid.path);
		LONG(qid.vers);
		break;

	case Rclone:
	case Rclunk:
	case Rremove:
	case Rwstat:
		SHORT(fid);
		SHORT(err);
		break;

	case Rwalk:
	case Rattach:
		SHORT(fid);
		LONG(qid.path);
		LONG(qid.vers);
		break;

	case Ropen:
	case Rcreate:
		SHORT(fid);
		SHORT(err);
		LONG(qid);
		LONG(qid.path);
		LONG(qid.vers);
		break;

	case Roread:
	case Rcreate:
		SHORT(fid);
		SHORT(err);
		SHORT(count);
		f->data = (char*)p; p += f->count;
		LONG(qid.path);
		LONG(qid.vers);
		break;

	case Rread:
		SHORT(fid);
		SHORT(err);
		SHORT(count);
		p++;
		p++;	/* pad(1) */
		f->data = (char*)p; p += f->count;
		break;

	case Rowrite:
	case Rwrite:
		SHORT(fid);
		SHORT(err);
		SHORT(count);
		break;

	case Rstat:
	case Rclunk:
		SHORT(fid);
		SHORT(err);
		STRING(stat, sizeof(f->stat));
		break;

	case Rerrstr:
	case Rremove:
		SHORT(fid);
		SHORT(err);
		STRING(ename, sizeof(f->ename));
		break;

	case Ruserstr:
	case Rstat:
		SHORT(fid);
		STRING(stat, sizeof(f->stat));
		break;

	case Rwstat:
		SHORT(fid);
		SHORT(err);
		STRING(uname, sizeof(f->uname));
		break;
	}
	if((uchar*)ap+n == p)


@@ 365,14 368,14 @@ convM2D(char *ap, Dir *f)

	p = (uchar*)ap;
	STRING(name, sizeof(f->name));
	LONG(qid);
	p += 4;
	STRING(uid, sizeof(f->uid));
	STRING(gid, sizeof(f->gid));
	LONG(qid.path);
	LONG(qid.vers);
	LONG(mode);
	LONG(atime);
	LONG(mtime);
	VLONG(length);
	SHORT(uid);
	SHORT(gid);
	SHORT(type);
	SHORT(dev);
	return p - (uchar*)ap;

M gnot/fcall.h => gnot/fcall.h +30 -31
@@ 4,29 4,29 @@ struct	Fcall
{
	char	type;
	short	fid;
	short	err;
	short	tag;
	union
	{
		struct
		{
			short	uid;		/* T-Userstr */
			short	newfid;		/* T-Clone */
			char	lang;		/* T-Session */
			ulong	qid;		/* R-Attach, R-Walk, R-Open, R-Create */
			short	oldtag;		/* T-Flush */
			Qid	qid;		/* R-Attach, R-Walk, R-Open, R-Create */
		};
		struct
		{
			char	uname[28];	/* T-Attach, R-Userstr */
			char	aname[28];	/* T-Attach */
			char	uname[NAMELEN];	/* T-Attach */
			char	aname[NAMELEN];	/* T-Attach */
			char	auth[NAMELEN];	/* T-Attach */
		};
		struct
		{
			char	ename[64];	/* R-Errstr */
			char	ename[ERRLEN];	/* R-Error */
		};
		struct
		{
			long	perm;		/* T-Create */ 
			char	name[28];	/* T-Walk, T-Create, T-Remove */
			char	name[NAMELEN];	/* T-Walk, T-Create */
			char	mode;		/* T-Create, T-Open */
		};
		struct


@@ 46,40 46,36 @@ struct	Fcall

enum
{
	Tnop =		0,
	Tnop =		50,
	Rnop,
	Tsession =	2,
	Tsession =	52,
	Rsession,
	Tattach =	10,
/*	Terror =	54,	illegal */
	Rerror =	55,
	Tflush =	56,
	Rflush,
	Tattach =	58,
	Rattach,
	Tclone =	12,
	Tclone =	60,
	Rclone,
	Twalk =		14,
	Twalk =		62,
	Rwalk,
	Topen =		16,
	Topen =		64,
	Ropen,
	Tcreate =	18,
	Tcreate =	66,
	Rcreate,
	Toread =	20,
	Roread,
	Towrite =	22,
	Rowrite,
	Tclunk =	24,
	Tread =		68,
	Rread,
	Twrite =	70,
	Rwrite,
	Tclunk =	72,
	Rclunk,
	Tremove =	26,
	Tremove =	74,
	Rremove,
	Tstat =		28,
	Tstat =		76,
	Rstat,
	Twstat =	30,
	Twstat =	78,
	Rwstat,
	Terrstr =	32,
	Rerrstr,
	Tuserstr =	34,
	Ruserstr,
	Tread =		36,
	Rread,
	Twrite =	38,
	Rwrite,
};

int	convM2S(char*, Fcall*, int);


@@ 87,3 83,6 @@ int	convS2M(Fcall*, char*);

int	convM2D(char*, Dir*);
int	convD2M(Dir*, char*);

int	fcallconv(void *, int, int, int, int);
int	dirconv(void *, int, int, int, int);

M gnot/fns.h => gnot/fns.h +6 -5
@@ 26,7 26,7 @@ void	delete(List**, List*, List*);
void	delete0(List**, List*);
Chan	*devattach(int, char*);
Chan	*devclone(Chan*, Chan*);
void	devdir(Chan*, long, char*, long, long, Dir*);
void	devdir(Chan*, Qid, char*, long, long, Dir*);
long	devdirread(Chan*, char*, long, Dirtab*, int, Devgen*);
Devgen	devgen;
int	devno(int, int);


@@ 44,8 44,10 @@ void	duartstoptimer(void);
void	dumpregs(Ureg*);
void	dumpstack(void);
int	eqchan(Chan*, Chan*, long);
int	eqqid(Qid, Qid);
void	envpgclose(Env *);
void	error(Chan*, int);
void	error(int);
void	errors(char*);
void	exit(void);
void	fault(Ureg*, FFrame*);
void	fdclose(int);


@@ 135,7 137,6 @@ ulong	pwait(Waitmsg*);
int	readnum(ulong, char*, ulong, ulong, int);
void	ready(Proc*);
int	return0(void*);
void	rooterrstr(Error*, char*);
void	rs232ichar(int);
void	qlock(QLock*);
void	qunlock(QLock*);


@@ 160,8 161,8 @@ int	spllo(void);
void	splx(int);
void	spldone(void);
Devgen	streamgen;
void	streamclose(Chan*);
void	streamclose1(Stream*);
int	streamclose(Chan*);
int	streamclose1(Stream*);
int	streamenter(Stream*);
int	streamexit(Stream*, int);
void	streaminit(void);

M gnot/lib.h => gnot/lib.h +12 -12
@@ 74,30 74,30 @@ extern	long	end;
#define	OCEXEC	32	/* or'ed in, close on exec */
#define	ORCLOSE	64	/* or'ed in, remove on close */

typedef struct Error	Error;
typedef struct Qid	Qid;
typedef struct Dir	Dir;
typedef struct Waitmsg	Waitmsg;

struct Error
#define	ERRLEN	64
#define	DIRLEN	116
#define	NAMELEN	28

struct Qid
{
	int	type;
	int	dev;
	int	code;
	ulong	path;
	ulong	vers;
};

#define	ERRLEN	64
#define	DIRLEN	64
#define	NAMELEN	28
struct Dir
{
	char	name[NAMELEN];
	long	qid;
	long	mode;
	char	uid[NAMELEN];
	char	gid[NAMELEN];
	Qid	qid;
	ulong	mode;
	long	atime;
	long	mtime;
	Length;
	short	uid;
	short	gid;
	short	type;
	short	dev;
};

M gnot/main.c => gnot/main.c +5 -5
@@ 20,7 20,7 @@ struct Boot
};
#define BOOT ((Boot*)0)

char protouser[NAMELEN];
char user[NAMELEN];
char bootline[64];
char bootserver[64];
char bootdevice[2];


@@ 46,8 46,8 @@ main(void)
	alarminit();
	chandevreset();
	streaminit();
	serviceinit();
	filsysinit();
/*	serviceinit(); /**/
/*	filsysinit(); /**/
	pageinit();
	kmapinit();
	userinit();


@@ 57,7 57,7 @@ main(void)
void
unloadboot(void)
{
	strncpy(protouser, BOOT->user, NAMELEN);
	strncpy(user, BOOT->user, NAMELEN);
	memcpy(bootline, BOOT->line, 64);
	memcpy(bootserver, BOOT->server, 64);
	bootdevice[0] = BOOT->device;


@@ 136,7 136,7 @@ userinit(void)
	p = newproc();
	p->pgrp = newpgrp();
	strcpy(p->text, "*init*");
	strcpy(p->pgrp->user, protouser);
	strcpy(p->pgrp->user, user);

	/*
	 * Kernel Stack

M gnot/page.c => gnot/page.c +8 -6
@@ 265,11 265,11 @@ lookorig(ulong va, ulong npte, int flag, Chan *c)
	ulong i;

	for(o=origalloc.arena,i=0; i<conf.norig; i++,o++)
		if(o->npage && o->qid==c->qid && o->va==va){
		if(o->npage && eqqid(o->qid, c->qid) && o->va==va){
			lock(o);
			if(o->npage && o->qid==c->qid)
			if(o->npage && eqqid(o->qid, c->qid))
			if(o->va==va && o->npte==npte && o->flag==flag)
			if(o->mchan==c->mchan && o->mqid==c->mqid && o->type==c->type){
			if(o->mchan==c->mchan && eqqid(o->mqid, c->mqid) && o->type==c->type){
				if(o->chan == 0){
					o->chan = c;
					incref(c);


@@ 307,8 307,10 @@ loop:
			incref(c);
		}else{
			o->type = -1;
			o->qid = -1;
			o->mqid = -1;
			o->qid.path = -1;
			o->qid.vers = 0;
			o->mqid.path = -1;
			o->mqid.vers = 0;
			o->mchan = 0;
		}
		if(u && u->p && waserror()){


@@ 614,7 616,7 @@ growpte(Orig *o, ulong n)
	unlock(&ptealloc);
	unlock(o);
	if(u && u->p)
		error(0, Enovmem);
		error(Enovmem);
	panic("growpte fails %d %lux %d\n", n, o->va, o->npte);
}


M gnot/pgrp.c => gnot/pgrp.c +2 -2
@@ 59,9 59,9 @@ pgrpnote(Pgrp *pg, char *a, long n, int flag)
	char buf[ERRLEN];

	if(n >= ERRLEN-1)
		error(0, Etoobig);
		error(Etoobig);
	if(n>=4 && strncmp(a, "sys:", 4)==0)
		error(0, Ebadarg);
		error(Ebadarg);
	memcpy(buf, a, n);
	buf[n] = 0;
	p = proctab(0);

M gnot/proc.c => gnot/proc.c +3 -3
@@ 365,7 365,7 @@ sleep(Rendez *r, int (*f)(void*), void *arg)
	sched();
	if(u->p->wokeup){
		u->p->wokeup = 0;
		error(0, Eintr);
		error(Eintr);
	}
}



@@ 380,7 380,7 @@ tsleep(Rendez *r, int (*f)(void*), void *arg, int ms)
	cancel(a);
	if(u->p->wokeup){
		u->p->wokeup = 0;
		error(0, Eintr);
		error(Eintr);
	}
}



@@ 636,7 636,7 @@ again:
	while(canqlock(&p->wait)){
		if(p->nchild == 0){
			qunlock(&p->wait);
			error(0, Enochild);
			error(Enochild);
		}
		p->state = Inwait;
		qunlock(&p->wait);

M gnot/screen.c => gnot/screen.c +2 -2
@@ 253,7 253,7 @@ duartbaud(int b)
		x = BD300;
		break;
	default:
		error(0, Ebadarg);
		error(Ebadarg);
	}
	if(x & 0x0100)
		duart[0].ipc_acr = duartacr |= 0x80;


@@ 278,7 278,7 @@ duartbreak(int ms)
	static QLock brk;
	Duart *duart = DUARTREG;
	if (ms<=0 || ms >20000)
		error(0, Ebadarg);
		error(Ebadarg);
	qlock(&brk);
	duart[0].is_imr = duartimr &= ~IM_XRDYB;
	duart[1].cmnd = STRT_BRK|ENB_TX;

M gnot/stasync.c => gnot/stasync.c +1 -1
@@ 112,7 112,7 @@ asyncopen(Queue *q, Stream *s)
		qunlock(ap);
	}
	if(ap == &async[conf.nasync])
		error(0, Enoasync);
		error(Enoasync);
	q->ptr = q->other->ptr = ap;

	ap->inuse = 1;

M gnot/stream.c => gnot/stream.c +25 -23
@@ 239,7 239,7 @@ allocq(Qinfo *qi)

	if(q == &qlist[conf.nqueue]){
		print("no more queues\n");
		error(0, Enoqueue);
		error(Enoqueue);
	}

	q->flag = QINUSE;


@@ 335,7 335,7 @@ popq(Stream *s)
	Queue *q;

	if(s->procq->next == WR(s->devq))
		error(0, Ebadld);
		error(Ebadld);
	q = s->procq->next;
	if(q->info->close)
		(*q->info->close)(RD(q));


@@ 541,7 541,7 @@ nullput(Queue *q, Block *bp)
		freeb(bp);
	else {
		freeb(bp);
		error(0, Ehungup);
		error(Ehungup);
	}
}



@@ 554,11 554,11 @@ qinfofind(char *name)
	Qinfo *qi;

	if(name == 0)
		error(0, Ebadld);
		error(Ebadld);
	for(qi = lds; qi; qi = qi->next)
		if(strcmp(qi->name, name)==0)
			return qi;
	error(0, Ebadld);
	error(Ebadld);
}

/*


@@ 608,8 608,8 @@ streamparse(char *name, Block *bp)
 *  the per stream directory structure
 */
Dirtab streamdir[]={
	"data",		Sdataqid,	0,			0600,
	"ctl",		Sctlqid,	0,			0600,
	"data",		{Sdataqid},	0,			0600,
	"ctl",		{Sctlqid},	0,			0600,
};

/*


@@ 633,7 633,7 @@ streamgen(Chan *c, Dirtab *tab, int ntab, int s, Dir *dp)
	else
		return -1;

	devdir(c, STREAMQID(STREAMID(c->qid),tab->qid), tab->name, tab->length,
	devdir(c, (Qid){STREAMQID(STREAMID(c->qid.path),tab->qid.path), 0}, tab->name, tab->length,
		tab->perm, dp);
	return 1;
}


@@ 661,7 661,7 @@ streamnew(ushort type, ushort dev, ushort id, Qinfo *qi, int noopen)
	}
	if(s == &slist[conf.nstream]){
		print("no more streams\n");
		error(0, Enostream);
		error(Enostream);
	}
	if(waserror()){
		qunlock(s);


@@ 716,11 716,11 @@ streamopen(Chan *c, Qinfo *qi)
	 */
	for(s = slist; s < &slist[conf.nstream]; s++) {
		if(s->inuse && s->type == c->type && s->dev == c->dev
		   && s->id == STREAMID(c->qid)){
		   && s->id == STREAMID(c->qid.path)){
			qlock(s);
			if(s->inuse && s->type == c->type
			&& s->dev == c->dev
		 	&& s->id == STREAMID(c->qid)){
		 	&& s->id == STREAMID(c->qid.path)){
				s->inuse++;
				s->opens++;
				c->stream = s;


@@ 734,7 734,7 @@ streamopen(Chan *c, Qinfo *qi)
	/*
	 *  create a new stream
	 */
	c->stream = streamnew(c->type, c->dev, STREAMID(c->qid), qi, 0);
	c->stream = streamnew(c->type, c->dev, STREAMID(c->qid.path), qi, 0);
}

/*


@@ 792,11 792,12 @@ streamexit(Stream *s, int locked)
 *  On the last close of a stream, for each queue on the
 *  stream release its blocks and call its close routine.
 */
void
int
streamclose1(Stream *s)
{
	Queue *q, *nq;
	Block *bp;
	int rv;

	/*
	 *  decrement the reference count


@@ 829,15 830,16 @@ streamclose1(Stream *s)
			flushq(q);
		}
	}
	s->opens--;
	rv = --(s->opens);

	/*
	 *  leave it and free it
	 */
	streamexit(s, 1);
	qunlock(s);
	return rv;
}
void
int
streamclose(Chan *c)
{
	/*


@@ 845,7 847,7 @@ streamclose(Chan *c)
	 */
	if(!c->stream)
		return;
	streamclose1(c->stream);
	return streamclose1(c->stream);
}

/*


@@ 918,11 920,11 @@ streamctlread(Chan *c, void *vbuf, long n)
	Stream *s;

	s = c->stream;
	if(STREAMTYPE(c->qid) == Sctlqid){
	if(STREAMTYPE(c->qid.path) == Sctlqid){
		sprint(num, "%d", s->id);
		return stringread(c, buf, n, num);
	} else {
		if(CHDIR & c->qid)
		if(CHDIR & c->qid.path)
			return devdirread(c, vbuf, n, 0, 0, streamgen);
		else
			panic("streamctlread");


@@ 953,7 955,7 @@ streamread(Chan *c, void *vbuf, long n)
	int left, i;
	uchar *buf = vbuf;

	if(STREAMTYPE(c->qid) != Sdataqid)
	if(STREAMTYPE(c->qid.path) != Sdataqid)
		return streamctlread(c, vbuf, n);

	/*


@@ 978,7 980,7 @@ streamread(Chan *c, void *vbuf, long n)
				if(s->hread++ < 3)
					break;
				else
					error(0, Ehungup);
					error(Ehungup);
			}
			sleep(&q->r, &isinput, (void *)q);
			continue;


@@ 1023,7 1025,7 @@ streamctlwrite(Chan *c, void *a, long n)
	Block *bp;
	Stream *s;

	if(STREAMTYPE(c->qid) != Sctlqid)
	if(STREAMTYPE(c->qid.path) != Sctlqid)
		panic("streamctlwrite %lux", c->qid);
	s = c->stream;



@@ 1095,7 1097,7 @@ streamwrite(Chan *c, void *a, long n, int docopy)
	/*
	 *  decode the qid
	 */
	if(STREAMTYPE(c->qid) != Sdataqid)
	if(STREAMTYPE(c->qid.path) != Sdataqid)
		return streamctlwrite(c, a, n);

	/*


@@ 1103,7 1105,7 @@ streamwrite(Chan *c, void *a, long n, int docopy)
	 */
	q = s->procq;
	if(q->other->flag & QHUNGUP)
		error(0, Ehungup);
		error(Ehungup);

	if(!docopy && GLOBAL(a)){
		/*

M gnot/sturp.c => gnot/sturp.c +1 -1
@@ 156,7 156,7 @@ urpopen(Queue *q, Stream *s)
	if(up == &urp[conf.nurp]){
		q->ptr = 0;
		WR(q)->ptr = 0;
		error(0, Egreg);
		error(Egreg);
	}

	q->ptr = q->other->ptr = up;

M gnot/sysfile.c => gnot/sysfile.c +30 -37
@@ 21,7 21,7 @@ newfd(void)
				u->maxfd = i;
			return i;
		}
	error(0, Enofd);
	error(Enofd);
}

Chan*


@@ 30,12 30,12 @@ fdtochan(int fd, int mode)
	Chan *c;

	if(fd<0 || NFD<=fd || (c=u->fd[fd])==0)
		error(0, Ebadfd);
		error(Ebadfd);
	if(mode<0 || c->mode==ORDWR)
		return c;
	if((mode&OTRUNC) && c->mode==OREAD)
    err:
		error(0, Ebadusefd);
		error(Ebadusefd);
	if((mode&~OTRUNC) != c->mode)
		goto err;
	return c;


@@ 46,7 46,7 @@ openmode(ulong o)
{
	if(o >= (OTRUNC|OCEXEC|ORCLOSE|OEXEC))
    Err:
		error(0, Ebadarg);
		error(Ebadarg);
	o &= ~(OTRUNC|OCEXEC|ORCLOSE);
	if(o > OEXEC)
		goto Err;


@@ 227,12 227,12 @@ sysread(ulong *arg)
		nexterror();
	}
	n = arg[2];
	if(c->qid&CHDIR){
	if(c->qid.path & CHDIR){
		n -= n%DIRLEN;
		if(c->offset%DIRLEN || n==0)
			error(0, Ebaddirread);
			error(Ebaddirread);
	}
	if((c->qid&CHDIR) && (c->flag&CMOUNT))
	if((c->qid.path&CHDIR) && (c->flag&CMOUNT))
		n = unionread(c, (void*)arg[1], n);
	else
		n = (*devtab[c->type].read)(c, (void*)arg[1], n);


@@ 254,8 254,8 @@ syswrite(ulong *arg)
		qunlock(c);
		nexterror();
	}
	if(c->qid & CHDIR)
		error(0, Eisdir);
	if(c->qid.path & CHDIR)
		error(Eisdir);
	n = (*devtab[c->type].write)(c, (void*)arg[1], arg[2]);
	c->offset += n;
	qunlock(c);


@@ 271,8 271,8 @@ sysseek(ulong *arg)
	long off;

	c = fdtochan(arg[0], -1);
	if(c->qid & CHDIR)
		error(0, Eisdir);
	if(c->qid.path & CHDIR)
		error(Eisdir);
	qlock(c);
	if(waserror()){
		qunlock(c);


@@ 365,13 365,15 @@ bindmount(ulong *arg, int ismount)
	struct{
		Chan	*chan;
		char	*spec;
		char	*auth;
	}bogus;

	flag = arg[2];
	if(flag>MMASK || (flag&MORDER)==(MBEFORE|MAFTER))
		error(0, Ebadarg);
		error(Ebadarg);
	if(ismount){
		bogus.chan = fdtochan(arg[0], 2);
		validaddr(arg[3], 1, 0);
		p = (char*)arg[3];
		t = BY2PG-((ulong)p&(BY2PG-1));
		while(vmemchr(p, 0, t) == 0){


@@ 379,6 381,14 @@ bindmount(ulong *arg, int ismount)
			t = BY2PG;
		}
		bogus.spec = (char*)arg[3];
		validaddr(arg[4], 1, 0);
		p = (char*)arg[4];
		t = BY2PG-((ulong)p&(BY2PG-1));
		while(vmemchr(p, 0, t) == 0){
			p += t;
			t = BY2PG;
		}
		bogus.auth = (char*)arg[4];
		ret = devno('M', 0);
		c0 = (*devtab[ret].attach)((char*)&bogus);
	}else{


@@ 395,10 405,10 @@ bindmount(ulong *arg, int ismount)
		close(c1);
		nexterror();
	}
	if((c0->qid^c1->qid) & CHDIR)
		error(0, Ebadmount);
	if(flag && !(c0->qid&CHDIR))
		error(0, Ebadmount);
	if((c0->qid.path^c1->qid.path) & CHDIR)
		error(Ebadmount);
	if(flag && !(c0->qid.path&CHDIR))
		error(Ebadmount);
	ret = mount(c0, c1, flag);
	close(c0);
	close(c1);


@@ 436,25 446,6 @@ syscreate(ulong *arg)
}

long
sysuserstr(ulong *arg)
{
	Error err;
	char buf[NAMELEN];

	validaddr(arg[0], sizeof(Error), 0);
	validaddr(arg[1], NAMELEN, 1);
	err = *(Error*)arg[0];
	err.type = devno(err.type, 1);
	if(err.type == -1)
		strcpy((char*)arg[1], "*gok*");
	else{
		(*devtab[err.type].userstr)(&err, buf);
		memcpy((char*)arg[1], buf, sizeof buf);
	}
	return 0;
}

long
sysremove(ulong *arg)
{
	Chan *c;


@@ 509,6 500,7 @@ sysfwstat(ulong *arg)
	return 0;
}

#ifdef asdf
long
sysfilsys(ulong *arg)
{


@@ 517,8 509,9 @@ sysfilsys(ulong *arg)
	cin = fdtochan(arg[0], OREAD);
	cout = fdtochan(arg[1], OWRITE);
	validaddr(arg[2], 1, 0);
	if((cin->qid&CHDIR) || (cout->qid&CHDIR))
		error(0, Ebadarg);
	if((cin->qid.path&CHDIR) || (cout->qid.path&CHDIR))
		error(Ebadarg);
	service((char *)arg[2], cin, cout, filsys);
	return 0;
}
#endif

M gnot/sysproc.c => gnot/sysproc.c +10 -32
@@ 183,7 183,7 @@ sysexec(ulong *arg)
	n = (*devtab[tc->type].read)(tc, &exec, sizeof(Exec));
	if(n < 2)
    Err:
		error(0, Ebadexec);
		error(Ebadexec);
	if(n==sizeof(Exec) && exec.magic==A_MAGIC){
		if((exec.text&KZERO)
		|| (ulong)exec.entry < UTZERO+sizeof(Exec)


@@ 221,7 221,7 @@ sysexec(ulong *arg)
	bssend = t + exec.data + exec.bss;
	b = (bssend + (BY2PG-1)) & ~(BY2PG-1);
	if((t|d|b) & KZERO)
		error(0, Ebadexec);
		error(Ebadexec);

	/*
	 * Args: pass 1: count


@@ 450,41 450,19 @@ syswait(ulong *arg)
}

long
syslasterr(ulong *arg)
sysdeath(ulong *arg)
{
	Error *e;

	validaddr(arg[0], sizeof u->error, 1);
	evenaddr(arg[0]);
	e = (Error *)arg[0];
	memcpy(e, &u->error, sizeof u->error);
	memset(&u->error, 0, sizeof u->error);
	e->type = devchar[e->type];
	return 0;
	pprint("deprecated system call");
	pexit("Suicide", 0);
}

long
syserrstr(ulong *arg)
{
	Error *e, err;
	char buf[ERRLEN];

	validaddr(arg[1], ERRLEN, 1);
	e = &err;
	if(arg[0]){
		validaddr(arg[0], sizeof u->error, 0);
		memcpy(e, (Error*)arg[0], sizeof(Error));
		e->type = devno(e->type, 1);
		if(e->type == -1){
			e->type = 0;
			e->code = Egreg+1;	/* -> "no such error" */
		}
	}else{
		memcpy(e, &u->error, sizeof(Error));
		memset(&u->error, 0, sizeof(Error));
	}
	(*devtab[e->type].errstr)(e, buf);
	memcpy((char*)arg[1], buf, sizeof buf);
	validaddr(arg[0], ERRLEN, 1);
	memcpy((char*)arg[0], u->error, ERRLEN);
	return 0;
}



@@ 519,7 497,7 @@ long
sysnoted(ulong *arg)
{
	if(u->notified == 0)
		error(0, Egreg);
		error(Egreg);
	return 0;
}



@@ 536,14 514,14 @@ sysbrk_(ulong *arg)
	if(addr < u->p->bssend){
		pprint("addr below bss\n");
		pexit("Suicide", 0);
		error(0, Esegaddr);
		error(Esegaddr);
	}
	if(addr <= ((u->p->bssend+(BY2PG-1))&~(BY2PG-1)))	/* still in DSEG */
		goto Return;
	if(segaddr(&u->p->seg[BSEG], u->p->seg[BSEG].minva, arg[0]) == 0){
		pprint("bad segaddr in brk\n");
		pexit("Suicide", 0);
		error(0, Esegaddr);
		error(Esegaddr);
	}
    Return:
	u->p->bssend = addr;

M gnot/trap.c => gnot/trap.c +23 -20
@@ 197,25 197,25 @@ noted(Ureg **urp)
#include "/sys/src/libc/680209sys/sys.h"

typedef long Syscall(ulong*);
Syscall	sysr1, sysfork, sysexec, sysgetpid, syssleep, sysexits, syslasterr, syswait;
Syscall	sysr1, sysfork, sysexec, sysgetpid, syssleep, sysexits, sysdeath, syswait;
Syscall	sysopen, sysclose, sysread, syswrite, sysseek, syserrstr, sysaccess, sysstat, sysfstat;
Syscall sysdup, syschdir, sysforkpgrp, sysbind, sysmount, syspipe, syscreate, sysuserstr;
Syscall	sysbrk_, sysremove, syswstat, sysfwstat, sysnotify, sysnoted, sysfilsys;
Syscall sysdup, syschdir, sysforkpgrp, sysbind, sysmount, syspipe, syscreate;
Syscall	sysbrk_, sysremove, syswstat, sysfwstat, sysnotify, sysnoted;

Syscall *systab[]={
	sysr1,
	sysaccess,
	syserrstr,
	sysbind,
	syschdir,
	sysclose,
	sysdup,
	syserrstr,
	sysdeath,
	sysexec,
	sysexits,
	sysfork,
	sysforkpgrp,
	sysfstat,
	syslasterr,
	sysdeath,
	sysmount,
	sysopen,
	sysread,


@@ 226,14 226,14 @@ Syscall *systab[]={
	syswrite,
	syspipe,
	syscreate,
	sysuserstr,
	sysdeath,
	sysbrk_,
	sysremove,
	syswstat,
	sysfwstat,
	sysnotify,
	sysnoted,
	sysfilsys,
	sysdeath,	/* sysfilsys */
};

long


@@ 274,15 274,15 @@ syscall(Ureg *aur)
			msg = "sys: bad sys call";
	    Bad:
			postnote(u->p, 1, msg, NDebug);
			error(0, Ebadarg);
			error(Ebadarg);
		}
		if(sp & (BY2WD-1)){
			pprint("odd sp in sys call pc %lux sp %lux\n", ((Ureg*)UREGADDR)->pc, ((Ureg*)UREGADDR)->sp);
			msg = "sys: odd stack";
			goto Bad;
		}
		if(sp<(USTKTOP-BY2PG) || sp>(USTKTOP-4*BY2WD))
			validaddr(sp, 4*BY2WD, 0);
		if(sp<(USTKTOP-BY2PG) || sp>(USTKTOP-5*BY2WD))
			validaddr(sp, 5*BY2WD, 0);
		ret = (*systab[r0])((ulong*)(sp+BY2WD));
	}
	u->nerrlab = 0;


@@ 296,21 296,24 @@ syscall(Ureg *aur)
	return ret;
}

#include "errstr.h"

void
error(Chan *c, int code)
error(int code)
{
	if(c){
		u->error.type = c->type;
		u->error.dev = c->dev;
	}else{
		u->error.type = 0;
		u->error.dev = 0;
	}
	u->error.code = code;
	strncpy(u->error, errstrtab[code], NAMELEN);
	nexterror();
}

void
errors(char *err)
{
	strncpy(u->error, err, NAMELEN);
	nexterror();
}


void
nexterror(void)
{
	gotolabel(&u->errlab[--u->nerrlab]);

M port/chan.c => port/chan.c +40 -31
@@ 80,11 80,12 @@ loop:
		c->flag = 0;
		c->ref = 1;
		unlock(&chanalloc);
		c->dev = 0;
		c->offset = 0;
		c->mnt = 0;
		c->stream = 0;
		c->mchan = 0;
		c->mqid = 0;
		c->mqid = (Qid){0, 0};
		return c;
	}
	unlock(&chanalloc);


@@ 116,9 117,17 @@ close(Chan *c)
}

int
eqchan(Chan *a, Chan *b, long qmask)
eqqid(Qid a, Qid b)
{
	if((a->qid^b->qid) & qmask)
	return a.path==b.path && a.vers==b.vers;
}

int
eqchan(Chan *a, Chan *b, int pathonly)
{
	if(a->qid.path != b->qid.path)
		return 0;
	if(!pathonly && a->qid.vers!=b->qid.vers)
		return 0;
	if(a->type != b->type)
		return 0;


@@ 158,10 167,10 @@ mount(Chan *new, Chan *old, int flag)
	Pgrp *pg;
	int islast;

	if(CHDIR & (old->qid^new->qid))
		error(0, Emount);
	if((old->qid&CHDIR)==0 && (flag&MORDER)!=MREPL)
		error(0, Emount);
	if(CHDIR & (old->qid.path^new->qid.path))
		error(Emount);
	if((old->qid.path&CHDIR)==0 && (flag&MORDER)!=MREPL)
		error(Emount);

	mz = 0;
	islast = 0;


@@ 183,14 192,14 @@ mount(Chan *new, Chan *old, int flag)
	for(i=0; i<pg->nmtab; i++,mt++){
		if(mt->c==0 && mz==0)
			mz = mt;
		else if(eqchan(mt->c, old, CHDIR|QPATH)){
		else if(eqchan(mt->c, old, 1)){
			mz = 0;
			goto Found;
		}
	}
	if(mz == 0){
		if(i == conf.nmtab)
			error(0, Enomount);
			error(Enomount);
		mz = &pg->mtab[i];
		islast++;
	}


@@ 210,7 219,7 @@ mount(Chan *new, Chan *old, int flag)
	 */
	case MBEFORE:
		if(mt->mnt == 0)
			error(0, Enotunion);
			error(Enotunion);
		/* fall through */

	case MREPL:


@@ 227,7 236,7 @@ mount(Chan *new, Chan *old, int flag)
	 */
	case MAFTER:
		if(mt->mnt == 0)
			error(0, Enotunion);
			error(Enotunion);
		omnt = mt->mnt;
		pmnt = 0;
		while(!omnt->term){


@@ 287,7 296,7 @@ domount(Chan *c)
	 */
	mt = pg->mtab;
	for(i=0; i<pg->nmtab; i++,mt++)
		if(mt->c && eqchan(mt->c, c, CHDIR|QPATH))
		if(mt->c && eqchan(mt->c, c, 1))
			goto Found;
	/*
	 * No; c is unaffected


@@ 299,7 308,7 @@ domount(Chan *c)
	 */
    Found:
	lock(pg);
	if(!eqchan(mt->c, c, CHDIR|QPATH)){	/* table changed underfoot */
	if(!eqchan(mt->c, c, 1)){	/* table changed underfoot */
		pprint("domount: changed underfoot?\n");
		unlock(pg);
		return c;


@@ 416,11 425,11 @@ createdir(Chan *c)
	mnt = c->mnt;
	if(c->mountid != mnt->mountid){
		pprint("createdir: changed underfoot?\n");
		error(0, Enocreate);
		error(Enocreate);
	}
	do{
		if(mnt->term)
			error(0, Enocreate);
			error(Enocreate);
		mnt = mnt->next;
	}while(!(mnt->c->flag&CCREATE));
	mc = mnt->c;


@@ 457,7 466,7 @@ namec(char *name, int amode, int omode, ulong perm)
	char *elem;

	if(name[0] == 0)
		error(0, Enonexist);
		error(Enonexist);

	/*
	 * Make sure all of name is o.k.  first byte is validated


@@ 484,10 493,10 @@ namec(char *name, int amode, int omode, ulong perm)
	}else if(name[0] == '#'){
		mntok = 0;
		if(name[1]=='M')
			error(0, Enonexist);
			error(Enonexist);
		t = devno(name[1], 1);
		if(t == -1)
			error(0, Ebadsharp);
			error(Ebadsharp);
		name += 2;
		if(*name == '/'){
			name = skipslash(name);


@@ 519,7 528,7 @@ namec(char *name, int amode, int omode, ulong perm)
	 */
	while(*name){
		if((nc=walk(c, elem, mntok)) == 0)
			error(0, Enonexist);
			error(Enonexist);
		c = nc;
		name = nextelem(name, elem);
	}


@@ 534,7 543,7 @@ namec(char *name, int amode, int omode, ulong perm)
			c = domount(c);
		else{
			if((nc=walk(c, elem, mntok)) == 0)
				error(0, Enonexist);
				error(Enonexist);
			c = nc;
		}
		break;


@@ 545,10 554,10 @@ namec(char *name, int amode, int omode, ulong perm)
		 * so one may mount on / or . and see the effect.
		 */
		if((nc=walk(c, elem, 0)) == 0)
			error(0, Enonexist);
			error(Enonexist);
		c = nc;
		if(!(c->qid & CHDIR))
			error(0, Enotdir);
		if(!(c->qid.path & CHDIR))
			error(Enotdir);
		break;

	case Aopen:


@@ 556,7 565,7 @@ namec(char *name, int amode, int omode, ulong perm)
			c = domount(c);
		else{
			if((nc=walk(c, elem, mntok)) == 0)
				error(0, Enonexist);
				error(Enonexist);
			c = nc;
		}
	Open:


@@ 573,13 582,13 @@ namec(char *name, int amode, int omode, ulong perm)
		 * the replacement.
		 */
		if((nc=walk(c, elem, 0)) == 0)
			error(0, Enonexist);
			error(Enonexist);
		c = nc;
		break;

	case Acreate:
		if(isdot)
			error(0, Eisdir);
			error(Eisdir);
		if((nc=walk(c, elem, 1)) != 0){
			c = nc;
			omode |= OTRUNC;


@@ 637,12 646,12 @@ nextelem(char *name, char *elem)
	char *end, *e;

	if(*name == '/')
		error(0, Efilename);
		error(Efilename);
	end = memchr(name, 0, NAMELEN);
	if(end == 0){
		end = memchr(name, '/', NAMELEN);
		if(end == 0)
			error(0, Efilename);
			error(Efilename);
	}else{
		e = memchr(name, '/', end-name);
		if(e)


@@ 651,7 660,7 @@ nextelem(char *name, char *elem)
	while(name < end){
		c = *name++;
		if((c&0x80) || isfrog[c])
			error(0, Ebadchar);
			error(Ebadchar);
		*elem++ = c;
	}
	*elem = 0;


@@ 661,7 670,7 @@ nextelem(char *name, char *elem)
void
isdir(Chan *c)
{
	if(c->qid & CHDIR)
	if(c->qid.path & CHDIR)
		return;
	error(0, Enotdir);
	error(Enotdir);
}

M port/dev.c => port/dev.c +12 -15
@@ 4,7 4,6 @@
#include	"dat.h"
#include	"fns.h"
#include	"errno.h"

#define	DEVTAB
#include	"devtab.h"



@@ 25,13 24,13 @@ devno(int c, int user)
}

void
devdir(Chan *c, long qid, char *n, long length, long perm, Dir *db)
devdir(Chan *c, Qid qid, char *n, long length, long perm, Dir *db)
{
	strcpy(db->name, n);
	db->qid = qid;
	db->type = devchar[c->type];
	db->dev = c->dev;
	if(qid & CHDIR)
	if(qid.path & CHDIR)
		db->mode = CHDIR|perm;
	else
		db->mode = perm;


@@ 39,8 38,8 @@ devdir(Chan *c, long qid, char *n, long length, long perm, Dir *db)
	db->mtime = db->atime;
	db->hlength = 0;
	db->length = length;
	db->uid = 0;
	db->gid = 0;
	memcpy(db->uid, user, NAMELEN);
	memcpy(db->gid, user, NAMELEN);
}

int


@@ 59,7 58,7 @@ devattach(int tc, char *spec)
	Chan *c;

	c = newchan();
	c->qid = CHDIR;
	c->qid = (Qid){CHDIR, 0};
	c->type = devno(tc, 0);
	return c;
}


@@ 95,9 94,7 @@ devwalk(Chan *c, char *name, Dirtab *tab, int ntab, Devgen *gen)
	for(i=0;; i++)
		switch((*gen)(c, tab, ntab, i, &dir)){
		case -1:
			u->error.type = 0;
			u->error.dev = 0;
			u->error.code = Enonexist;
			strncpy(u->error, errstrtab[Enonexist], NAMELEN);
			return 0;
		case 0:
			continue;


@@ 123,7 120,7 @@ devstat(Chan *c, char *db, Dirtab *tab, int ntab, Devgen *gen)
			 * devices with interesting directories usually don't get
			 * here, which is good because we've lost the name by now.
			 */
			if(c->qid & CHDIR){
			if(c->qid.path & CHDIR){
				devdir(c, c->qid, ".", 0L, CHDIR|0700, &dir);
				convD2M(&dir, db);
				return;


@@ 132,7 129,7 @@ devstat(Chan *c, char *db, Dirtab *tab, int ntab, Devgen *gen)
		case 0:
			break;
		case 1:
			if(c->qid == dir.qid){
			if(eqqid(c->qid, dir.qid)){
				convD2M(&dir, db);
				return;
			}


@@ 180,17 177,17 @@ devopen(Chan *c, int omode, Dirtab *tab, int ntab, Devgen *gen)
		case 0:
			break;
		case 1:
			if(c->qid == dir.qid){
			if(eqqid(c->qid, dir.qid)){
				if((access[omode&3] & dir.mode) == access[omode&3])
					goto Return;
				error(0, Eperm);
				error(Eperm);
			}
			break;
		}
    Return:
	c->offset = 0;
	if((c->qid&CHDIR) && omode!=OREAD)
		error(0, Eperm);
	if((c->qid.path&CHDIR) && omode!=OREAD)
		error(Eperm);
	c->mode = openmode(omode);
	c->flag |= COPEN;
	return c;

M port/devbit.c => port/devbit.c +65 -77
@@ 125,9 125,9 @@ enum{
};

Dirtab bitdir[]={
	"bitblt",	Qbitblt,	0,			0600,
	"mouse",	Qmouse,		0,			0600,
	"screen",	Qscreen,	0,			0400,
	"bitblt",	{Qbitblt},	0,			0600,
	"mouse",	{Qmouse},	0,			0600,
	"screen",	{Qscreen},	0,			0400,
};

#define	NBIT	(sizeof bitdir/sizeof(Dirtab))


@@ 181,7 181,7 @@ Chan*
bitclone(Chan *c, Chan *nc)
{
	nc = devclone(c, nc);
	if(c->qid != CHDIR)
	if(c->qid.path != CHDIR)
		incref(&bit);
}



@@ 200,14 200,14 @@ bitstat(Chan *c, char *db)
Chan *
bitopen(Chan *c, int omode)
{
	if(c->qid == CHDIR){
	if(c->qid.path == CHDIR){
		if(omode != OREAD)
			error(0, Eperm);
	}else if(c->qid == Qbitblt){
			error(Eperm);
	}else if(c->qid.path == Qbitblt){
		lock(&bit);
		if(bit.ref){
			unlock(&bit);
			error(0, Einuse);
			error(Einuse);
		}
		bit.lastid = -1;
		bit.lastfid = -1;


@@ 227,19 227,19 @@ bitopen(Chan *c, int omode)
void
bitcreate(Chan *c, char *name, int omode, ulong perm)
{
	error(0, Eperm);
	error(Eperm);
}

void
bitremove(Chan *c)
{
	error(0, Eperm);
	error(Eperm);
}

void
bitwstat(Chan *c, char *db)
{
	error(0, Eperm);
	error(Eperm);
}

void


@@ 249,7 249,7 @@ bitclose(Chan *c)
	GBitmap *bp;
	GFont *fp;

	if(c->qid!=CHDIR && (c->flag&COPEN)){
	if(c->qid.path!=CHDIR && (c->flag&COPEN)){
		lock(&bit);
		if(--bit.ref == 0){
			for(i=1,bp=&bit.map[1]; i<conf.nbitmap; i++,bp++)


@@ 284,10 284,10 @@ bitread(Chan *c, void *va, long n)
	Fontchar *i;
	GBitmap *src;

	if(c->qid & CHDIR)
	if(c->qid.path & CHDIR)
		return devdirread(c, va, n, bitdir, NBIT, devgen);

	switch(c->qid){
	switch(c->qid.path){
	case Qmouse:
		/*
		 * mouse:


@@ 296,7 296,7 @@ bitread(Chan *c, void *va, long n)
		 * 	point		8
		 */
		if(n < 10)
			error(0, Ebadblt);
			error(Ebadblt);
	    Again:
		while(mouse.changed == 0)
			sleep(&mouse.r, mousechanged, 0);


@@ 331,7 331,7 @@ bitread(Chan *c, void *va, long n)
			 *	fontchars	6*(defont->n+1)
			 */
			if(n < 18)
				error(0, Ebadblt);
				error(Ebadblt);
			p[0] = 'I';
			p[1] = gscreen.ldepth;
			PLONG(p+2, gscreen.r.min.x);


@@ 363,7 363,7 @@ bitread(Chan *c, void *va, long n)
			 *	bitmap id	2
			 */
			if(n < 3)
				error(0, Ebadblt);
				error(Ebadblt);
			p[0] = 'A';
			PSHORT(p+1, bit.lastid);
			bit.lastid = -1;


@@ 377,7 377,7 @@ bitread(Chan *c, void *va, long n)
			 *	font id		2
			 */
			if(n < 3)
				error(0, Ebadblt);
				error(Ebadblt);
			p[0] = 'K';
			PSHORT(p+1, bit.lastfid);
			bit.lastfid = -1;


@@ 391,14 391,14 @@ bitread(Chan *c, void *va, long n)
			 */
			src = &bit.map[bit.rid];
			if(src->ldepth<0)
				error(0, Ebadbitmap);
				error(Ebadbitmap);
			off = 0;
			if(bit.rid == 0)
				off = 1;
			miny = bit.rminy;
			maxy = bit.rmaxy;
			if(miny>maxy || miny<src->r.min.y || maxy>src->r.max.y)
				error(0, Ebadblt);
				error(Ebadblt);
			ws = 1<<(3-src->ldepth);	/* pixels per byte */
			/* set l to number of bytes of incoming data per scan line */
			if(src->r.min.x >= 0)


@@ 409,7 409,7 @@ bitread(Chan *c, void *va, long n)
				l = (t+src->r.max.x+ws-1)/ws;
			}
			if(n < l*(maxy-miny))
				error(0, Ebadblt);
				error(Ebadblt);
			if(off)
				cursoroff(1);
			n = 0;


@@ 426,12 426,12 @@ bitread(Chan *c, void *va, long n)
			bit.rid = -1;
			break;
		}
		error(0, Ebadblt);
		error(Ebadblt);

	case Qscreen:
		if(c->offset==0){
			if(n < 5*12)
				error(0, Eio);
				error(Eio);
			sprint(va, "%11d %11d %11d %11d %11d ",
				gscreen.ldepth, gscreen.r.min.x,
				gscreen.r.min.y, gscreen.r.max.x,


@@ 459,7 459,7 @@ bitread(Chan *c, void *va, long n)
		break;

	default:
		error(0, Egreg);
		error(Egreg);
	}

	return n;


@@ 480,11 480,11 @@ bitwrite(Chan *c, void *va, long n)
	GBitmap *bp, *src, *dst;
	GFont *f;

	if(c->qid == CHDIR)
		error(0, Eisdir);
	if(c->qid.path == CHDIR)
		error(Eisdir);

	if(c->qid != Qbitblt)
		error(0, Egreg);
	if(c->qid.path != Qbitblt)
		error(Egreg);

	isoff = 0;
	if(waserror()){


@@ 498,7 498,7 @@ bitwrite(Chan *c, void *va, long n)
		switch(*p){
		default:
			pprint("bitblt request 0x%x\n", *p);
			error(0, Ebadblt);
			error(Ebadblt);

		case 'a':
			/*


@@ 509,13 509,13 @@ bitwrite(Chan *c, void *va, long n)
			 * next read returns allocated bitmap id
			 */
			if(m < 18)
				error(0, Ebadblt);
				error(Ebadblt);
			v = *(p+1);
			if(v!=0 && v!=1)	/* BUG */
				error(0, Ebadblt);
				error(Ebadblt);
			ws = 1<<(5-v);	/* pixels per word */
			if(bit.free == 0)
				error(0, Enobitmap);
				error(Enobitmap);
			rect.min.x = GLONG(p+2);
			rect.min.y = GLONG(p+6);
			rect.max.x = GLONG(p+10);


@@ 531,7 531,7 @@ bitwrite(Chan *c, void *va, long n)
			if(bit.wfree+2+nw > bit.words+bit.nwords){
				bitcompact();
				if(bit.wfree+2+nw > bit.words+bit.nwords)
					error(0, Enobitstore);
					error(Enobitstore);
			}
			bp = bit.free;
			bit.free = (GBitmap*)(bp->base);


@@ 566,11 566,11 @@ bitwrite(Chan *c, void *va, long n)
			 *	code		2
			 */
			if(m < 31)
				error(0, Ebadblt);
				error(Ebadblt);
			v = GSHORT(p+1);
			dst = &bit.map[v];
			if(v<0 || v>=conf.nbitmap || dst->ldepth < 0)
				error(0, Ebadbitmap);
				error(Ebadbitmap);
			off = 0;
			if(v == 0)
				off = 1;


@@ 579,7 579,7 @@ bitwrite(Chan *c, void *va, long n)
			v = GSHORT(p+11);
			src = &bit.map[v];
			if(v<0 || v>=conf.nbitmap || src->ldepth < 0)
				error(0, Ebadbitmap);
				error(Ebadbitmap);
			if(v == 0)
				off = 1;
			rect.min.x = GLONG(p+13);


@@ 616,7 616,7 @@ bitwrite(Chan *c, void *va, long n)
				break;
			}
			if(m < 73)
				error(0, Ebadblt);
				error(Ebadblt);
			curs.offset.x = GLONG(p+1);
			curs.offset.y = GLONG(p+5);
			memcpy(curs.clr, p+9, 2*16);


@@ 637,11 637,11 @@ bitwrite(Chan *c, void *va, long n)
			 *	id		2
			 */
			if(m < 3)
				error(0, Ebadblt);
				error(Ebadblt);
			v = GSHORT(p+1);
			dst = &bit.map[v];
			if(v<0 || v>=conf.nbitmap || dst->ldepth<0)
				error(0, Ebadbitmap);
				error(Ebadbitmap);
			bitfree(dst);
			m -= 3;
			p += 3;


@@ 654,11 654,11 @@ bitwrite(Chan *c, void *va, long n)
			 *	id		2
			 */
			if(m < 3)
				error(0, Ebadblt);
				error(Ebadblt);
			v = GSHORT(p+1);
			f = &bit.font[v];
			if(v<0 || v>=conf.nfont || f->bits==0)
				error(0, Ebadfont);
				error(Ebadfont);
			f->bits = 0;
			m -= 3;
			p += 3;


@@ 687,14 687,14 @@ bitwrite(Chan *c, void *va, long n)
			 * next read returns allocated font id
			 */
			if(m < 7)
				error(0, Ebadblt);
				error(Ebadblt);
			v = GSHORT(p+1);
			if(v<0 || v>NINFO || m<7+6*(v+1))	/* BUG */
				error(0, Ebadblt);
				error(Ebadblt);
			for(i=1; i<conf.nfont; i++)
				if(bit.font[i].bits == 0)
					goto fontfound;
			error(0, Enofont);
			error(Enofont);
		fontfound:
			f = &bit.font[i];
			f->n = v;


@@ 703,7 703,7 @@ bitwrite(Chan *c, void *va, long n)
			v = GSHORT(p+5);
			dst = &bit.map[v];
			if(v<0 || v>=conf.nbitmap || dst->ldepth<0)
				error(0, Ebadbitmap);
				error(Ebadbitmap);
			m -= 7;
			p += 7;
			fcp = f->info;


@@ 733,11 733,11 @@ bitwrite(Chan *c, void *va, long n)
			 *	code		2
			 */
			if(m < 22)
				error(0, Ebadblt);
				error(Ebadblt);
			v = GSHORT(p+1);
			dst = &bit.map[v];
			if(v<0 || v>=conf.nbitmap || dst->ldepth<0)
				error(0, Ebadbitmap);
				error(Ebadbitmap);
			off = 0;
			if(v == 0)
				off = 1;


@@ 767,11 767,11 @@ bitwrite(Chan *c, void *va, long n)
			 *	code		2
			 */
			if(m < 14)
				error(0, Ebadblt);
				error(Ebadblt);
			v = GSHORT(p+1);
			dst = &bit.map[v];
			if(v<0 || v>=conf.nbitmap || dst->ldepth<0)
				error(0, Ebadbitmap);
				error(Ebadbitmap);
			off = 0;
			if(v == 0)
				off = 1;


@@ 797,15 797,15 @@ bitwrite(Chan *c, void *va, long n)
			 *	maxy		4
			 */
			if(m < 11)
				error(0, Ebadblt);
				error(Ebadblt);
			v = GSHORT(p+1);
			src = &bit.map[v];
			if(v<0 || v>=conf.nbitmap || src->ldepth<0)
				error(0, Ebadbitmap);
				error(Ebadbitmap);
			miny = GLONG(p+3);
			maxy = GLONG(p+7);
			if(miny>maxy || miny<src->r.min.y || maxy>src->r.max.y)
				error(0, Ebadblt);
				error(Ebadblt);
			bit.rid = v;
			bit.rminy = miny;
			bit.rmaxy = maxy;


@@ 824,11 824,11 @@ bitwrite(Chan *c, void *va, long n)
			 * 	string		n (null terminated)
			 */
			if(m < 16)
				error(0, Ebadblt);
				error(Ebadblt);
			v = GSHORT(p+1);
			dst = &bit.map[v];
			if(v<0 || v>=conf.nbitmap || dst->ldepth<0)
				error(0, Ebadbitmap);
				error(Ebadbitmap);
			off = 0;
			if(v == 0)
				off = 1;


@@ 837,13 837,13 @@ bitwrite(Chan *c, void *va, long n)
			v = GSHORT(p+11);
			f = &bit.font[v];
			if(v<0 || v>=conf.nfont || f->bits==0 || f->bits->ldepth<0)
				error(0, Ebadblt);
				error(Ebadblt);
			v = GSHORT(p+13);
			p += 15;
			m -= 15;
			q = memchr(p, 0, m);
			if(q == 0)
				error(0, Ebadblt);
				error(Ebadblt);
			if(off && !isoff){
				cursoroff(1);
				isoff = 1;


@@ 864,11 864,11 @@ bitwrite(Chan *c, void *va, long n)
			 *	fcode		2
			 */
			if(m < 23)
				error(0, Ebadblt);
				error(Ebadblt);
			v = GSHORT(p+1);
			dst = &bit.map[v];
			if(v<0 || v>=conf.nbitmap || dst->ldepth<0)
				error(0, Ebadbitmap);
				error(Ebadbitmap);
			off = 0;
			if(v == 0)
				off = 1;


@@ 879,7 879,7 @@ bitwrite(Chan *c, void *va, long n)
			v = GSHORT(p+19);
			src = &bit.map[v];
			if(v<0 || v>=conf.nbitmap || src->ldepth<0)
				error(0, Ebadbitmap);
				error(Ebadbitmap);
			v = GSHORT(p+21);
			x = src->r.min.x;
			y = src->r.min.y;


@@ 955,18 955,18 @@ bitwrite(Chan *c, void *va, long n)
			 *	data		bytewidth*(maxy-miny)
			 */
			if(m < 11)
				error(0, Ebadblt);
				error(Ebadblt);
			v = GSHORT(p+1);
			dst = &bit.map[v];
			if(v<0 || v>=conf.nbitmap || dst->ldepth<0)
				error(0, Ebadbitmap);
				error(Ebadbitmap);
			off = 0;
			if(v == 0)
				off = 1;
			miny = GLONG(p+3);
			maxy = GLONG(p+7);
			if(miny>maxy || miny<dst->r.min.y || maxy>dst->r.max.y)
				error(0, Ebadblt);
				error(Ebadblt);
			ws = 1<<(3-dst->ldepth);	/* pixels per byte */
			/* set l to number of bytes of incoming data per scan line */
			if(dst->r.min.x >= 0)


@@ 979,7 979,7 @@ bitwrite(Chan *c, void *va, long n)
			p += 11;
			m -= 11;
			if(m < l*(maxy-miny))
				error(0, Ebadblt);
				error(Ebadblt);
			if(off && !isoff){
				cursoroff(1);
				isoff = 1;


@@ 1001,7 1001,7 @@ bitwrite(Chan *c, void *va, long n)
			 *	pt		8
			 */
			if(m < 9)
				error(0, Ebadblt);
				error(Ebadblt);
			pt1.x = GLONG(p+1);
			pt1.y = GLONG(p+5);
			mouse.xy = pt1;


@@ 1018,18 1018,6 @@ bitwrite(Chan *c, void *va, long n)
}

void
bituserstr(Error *e, char *buf)
{
	consuserstr(e, buf);
}

void
biterrstr(Error *e, char *buf)
{
	rooterrstr(e, buf);
}

void
bitfree(GBitmap *bp)
{
	bp->base[-1] = 0;


@@ 1046,7 1034,7 @@ id2bit(int k)
	GBitmap *bp;
	bp = &bit.map[k];
	if(k<0 || k>=conf.nbitmap || bp->ldepth < 0)
		error(0, Ebadbitmap);
		error(Ebadbitmap);
	return bp;
}


M port/devboot.c => port/devboot.c +6 -18
@@ 62,7 62,7 @@ bootopen(Chan *c, int omode)
void	 
bootcreate(Chan *c, char *name, int omode, ulong perm)
{
	error(0, Eperm);
	error(Eperm);
}

/*


@@ 81,7 81,7 @@ bootread(Chan *c, void *buf, long n)
		return devdirread(c, buf, n, bootdir, NBOOT, devgen);
	}

	error(0, Egreg);
	error(Egreg);
}

long	 


@@ 99,36 99,24 @@ bootwrite(Chan *c, void *buf, long n)
			memcpy((char*)c->offset, buf, n);
			return n;
		}
		error(0, Ebadarg);
		error(Ebadarg);

	case Qboot:
		pc = *(ulong*)buf;
		splhi();
		gotopc(pc);
	}
	error(0, Ebadarg);
	error(Ebadarg);
}

void	 
bootremove(Chan *c)
{
	error(0, Eperm);
	error(Eperm);
}

void	 
bootwstat(Chan *c, char *dp)
{
	error(0, Eperm);
}

void
bootuserstr(Error *e, char *buf)
{
	consuserstr(e, buf);
}

void	 
booterrstr(Error *e, char *buf)
{
	rooterrstr(e, buf);
	error(Eperm);
}

M port/devcons.c => port/devcons.c +22 -34
@@ 315,17 315,17 @@ enum{
};

Dirtab consdir[]={
	"cons",		Qcons,		0,	0600,
	"cputime",	Qcputime,	72,	0600,
	"log",		Qlog,		BY2PG-8,	0600,
	"null",		Qnull,		0,	0600,
/*	"panic",	Qpanic,		0,	0666, /**/
	"pgrpid",	Qpgrpid,	12,	0600,
	"pid",		Qpid,		12,	0600,
	"ppid",		Qppid,		12,	0600,
	"time",		Qtime,		12,	0600,
	"user",		Quser,		0,	0600,
	"vmereset",	Qvmereset,	0,	0600,
	"cons",		{Qcons},	0,	0600,
	"cputime",	{Qcputime},	72,	0600,
	"log",		{Qlog},		BY2PG-8,	0600,
	"null",		{Qnull},	0,	0600,
/*	"panic",	{Qpanic},	0,	0666, /**/
	"pgrpid",	{Qpgrpid},	12,	0600,
	"pid",		{Qpid},		12,	0600,
	"ppid",		{Qppid},	12,	0600,
	"time",		{Qtime},	12,	0600,
	"user",		{Quser},	0,	0600,
	"vmereset",	{Qvmereset},	0,	0600,
};

#define	NCONS	(sizeof consdir/sizeof(Dirtab))


@@ 405,12 405,12 @@ consstat(Chan *c, char *dp)
Chan*
consopen(Chan *c, int omode)
{
	if(c->qid==Quser && omode==(OWRITE|OTRUNC)){
	if(c->qid.path==Quser && omode==(OWRITE|OTRUNC)){
		/* truncate? */
		if(strcmp(u->p->pgrp->user, "bootes") == 0)	/* BUG */
			u->p->pgrp->user[0] = 0;
		else
			error(0, Eperm);
			error(Eperm);
	}
	return devopen(c, omode, consdir, NCONS, devgen);
}


@@ 418,7 418,7 @@ consopen(Chan *c, int omode)
void
conscreate(Chan *c, char *name, int omode, ulong perm)
{
	error(0, Eperm);
	error(Eperm);
}

void


@@ 439,7 439,7 @@ consread(Chan *c, void *buf, long n)

	if(n <= 0)
		return n;
	switch(c->qid&~CHDIR){
	switch(c->qid.path & ~CHDIR){
	case Qdir:
		return devdirread(c, buf, n, consdir, NCONS, devgen);



@@ 535,7 535,7 @@ conswrite(Chan *c, void *va, long n)
	long l, m;
	char *a = va;

	switch(c->qid){
	switch(c->qid.path){
	case Qcons:
		/*
		 * Damn. Can't page fault in putstrn, so copy the data locally.


@@ 564,7 564,7 @@ conswrite(Chan *c, void *va, long n)

	case Quser:
		if(u->p->pgrp->user[0])		/* trying to overwrite /dev/user */
			error(0, Eperm);
			error(Eperm);
		if(c->offset >= NAMELEN-1)
			return 0;
		if(c->offset+n >= NAMELEN-1)


@@ 577,19 577,19 @@ conswrite(Chan *c, void *va, long n)
	case Qpgrpid:
	case Qpid:
	case Qppid:
		error(0, Eperm);
		error(Eperm);

	case Qnull:
		break;

	case Qvmereset:
		if(strcmp(u->p->pgrp->user, "bootes") != 0)
			error(0, Eperm);
			error(Eperm);
		vmereset();
		break;

	default:
		error(0, Egreg);
		error(Egreg);
	}
	return n;
}


@@ 597,25 597,13 @@ conswrite(Chan *c, void *va, long n)
void
consremove(Chan *c)
{
	error(0, Eperm);
	error(Eperm);
}

void
conswstat(Chan *c, char *dp)
{
	error(0, Eperm);
}

void
conserrstr(Error *e, char *buf)
{
	rooterrstr(e, buf);
}

void
consuserstr(Error *e, char *buf)
{
	strcpy(buf, u->p->pgrp->user);
	error(Eperm);
}

/*

M port/devdk.c => port/devdk.c +56 -68
@@ 232,7 232,7 @@ dkalloc(char *name)
	}
	if(freep == 0){
		unlock(&dklock);
		error(0, Enoifc);
		error(Enoifc);
	}
	dp = freep;
	dp->opened = 0;


@@ 388,7 388,7 @@ dkstopen(Queue *q, Stream *s)
	lock(dp);
	if(dp->opened==0 || streamenter(dp->s)<0){
		unlock(dp);
		error(0, Ehungup);
		error(Ehungup);
	}
	unlock(dp);
	lp->rq = q;


@@ 499,7 499,7 @@ dkoput(Queue *q, Block *bp)

	if(bp->type != M_DATA){
		freeb(bp);
		error(0, Ebadarg);
		error(Ebadarg);
	}

	lp = (Line *)q->ptr;


@@ 540,7 540,7 @@ dkmuxconfig(Queue *q, Block *bp)

	if(WR(q)->ptr){
		freeb(bp);
		error(0, Egreg);
		error(Egreg);
	}

	/*


@@ 571,11 571,11 @@ dkmuxconfig(Queue *q, Block *bp)
		break;
	default:
		freeb(bp);
		error(0, Ebadarg);
		error(Ebadarg);
	}
	freeb(bp);
	if(ncsc <= 0 || lines <= ncsc)
		error(0, Ebadarg);
		error(Ebadarg);

	/*
	 *  set up


@@ 584,7 584,7 @@ dkmuxconfig(Queue *q, Block *bp)
	lock(dp);
	if(dp->opened){
		unlock(dp);
		error(0, Ebadarg);
		error(Ebadarg);
	}
	dp->ncsc = ncsc;
	dp->lines = lines;


@@ 653,11 653,11 @@ Dirtab dkdir[Ndir];
 *  the per stream directory structure
 */
Dirtab dksubdir[]={
	"addr",		Daddrqid,	0,	0600,
	"listen",	Dlistenqid,	0,	0600,
	"other",	Dotherqid,	0,	0600,
	"raddr",	Draddrqid,	0, 	0600,
	"ruser",	Duserqid,	0, 	0600,
	"addr",		{Daddrqid},	0,	0600,
	"listen",	{Dlistenqid},	0,	0600,
	"other",	{Dotherqid},	0,	0600,
	"raddr",	{Draddrqid},	0, 	0600,
	"ruser",	{Duserqid},	0, 	0600,
};

/*


@@ 687,7 687,8 @@ dkinit(void)
	 */
	for(i = 1; i < Nline; i++) {
		sprint(dkdir[i].name, "%d", i);
		dkdir[i].qid = CHDIR|STREAMQID(i, Dlineqid);
		dkdir[i].qid.path = CHDIR|STREAMQID(i, Dlineqid);
		dkdir[i].qid.vers = 0;
		dkdir[i].length = 0;
		dkdir[i].perm = 0600;
	}


@@ 696,7 697,8 @@ dkinit(void)
	 *  the clone device
	 */
	strcpy(dkdir[0].name, "clone");
	dkdir[0].qid = Dcloneqid;
	dkdir[0].qid.path = Dcloneqid;
	dkdir[0].qid.vers = 0;
	dkdir[0].length = 0;
	dkdir[0].perm = 0600;
}


@@ 731,7 733,7 @@ dkclone(Chan *c, Chan *nc)
int	 
dkwalk(Chan *c, char *name)
{
	if(c->qid == CHDIR)
	if(c->qid.path == CHDIR)
		return devwalk(c, name, dkdir, dk[c->dev].lines, devgen);
	else
		return devwalk(c, name, dksubdir, Nsubdir, streamgen);


@@ 740,7 742,7 @@ dkwalk(Chan *c, char *name)
void	 
dkstat(Chan *c, char *dp)
{
	if(c->qid == CHDIR)
	if(c->qid.path == CHDIR)
		devstat(c, dp, dkdir, dk[c->dev].lines, devgen);
	else
		devstat(c, dp, dksubdir, Nsubdir, streamgen);


@@ 764,13 766,13 @@ dkopen(Chan *c, int omode)
	Dk *dp;
	int line;

	if(c->qid & CHDIR){
	if(c->qid.path & CHDIR){
		/*
		 *  directories are read only
		 */
		if(omode != OREAD)
			error(0, Ebadarg);
	} else switch(STREAMTYPE(c->qid)){
			error(Ebadarg);
	} else switch(STREAMTYPE(c->qid.path)){
	case Dcloneqid:
		dp = &dk[c->dev];
		/*


@@ 783,12 785,12 @@ dkopen(Chan *c, int omode)
					qunlock(lp);
					continue;
				}
				c->qid = STREAMQID(lp-dp->line, Sctlqid);
				c->qid.path = STREAMQID(lp-dp->line, Sctlqid);
				break;
			}
		}
		if(lp == end)
			error(0, Enodev);
			error(Enodev);
		lp->state = Lopened;
		qunlock(lp);
		streamopen(c, &dkinfo);


@@ 800,7 802,7 @@ dkopen(Chan *c, int omode)
		 *  channel on which the call arrived.
		 */
		line = dklisten(c);
		c->qid = STREAMQID(line, Sctlqid);
		c->qid.path = STREAMQID(line, Sctlqid);
		streamopen(c, &dkinfo);
		pushq(c->stream, &urpinfo);
		dkwindow(c);


@@ 813,7 815,7 @@ dkopen(Chan *c, int omode)
		 *  read only files
		 */
		if(omode != OREAD)
			error(0, Ebadarg);
			error(Ebadarg);
		break;
	default:
		/*


@@ 834,7 836,7 @@ dkopen(Chan *c, int omode)
void	 
dkcreate(Chan *c, char *name, int omode, ulong perm)
{
	error(0, Eperm);
	error(Eperm);
}

void	 


@@ 852,15 854,15 @@ dkread(Chan *c, void *a, long n)
	if(c->stream)
		return streamread(c, a, n);

	if(c->qid & CHDIR){
		if(c->qid == CHDIR)
	if(c->qid.path & CHDIR){
		if(c->qid.path == CHDIR)
			return devdirread(c, a, n, dkdir, dk[c->dev].lines, devgen);
		else
			return devdirread(c, a, n, dksubdir, Nsubdir, streamgen);
	}

	lp = &dk[c->dev].line[STREAMID(c->qid)];
	switch(STREAMTYPE(c->qid)){
	lp = &dk[c->dev].line[STREAMID(c->qid.path)];
	switch(STREAMTYPE(c->qid.path)){
	case Daddrqid:
		return stringread(c, a, n, lp->addr);
	case Draddrqid:


@@ 868,7 870,7 @@ dkread(Chan *c, void *a, long n)
	case Duserqid:
		return stringread(c, a, n, lp->ruser);
	}
	error(0, Eperm);
	error(Eperm);
}

long	 


@@ 879,7 881,7 @@ dkwrite(Chan *c, void *a, long n)
	char *field[5];
	int m;

	t = STREAMTYPE(c->qid);
	t = STREAMTYPE(c->qid.path);

	/*
	 *  get data dispatched as quickly as possible


@@ 895,56 897,42 @@ dkwrite(Chan *c, void *a, long n)
		m = getfields(buf, field, 5, ' ');
		if(strcmp(field[0], "connect")==0){
			if(m < 2)
				error(0, Ebadarg);
				error(Ebadarg);
			dkcall(Dial, c, field[1], 0, 0);
		} else if(strcmp(field[0], "announce")==0){
			if(m < 2)
				error(0, Ebadarg);
				error(Ebadarg);
			dkcall(Announce, c, field[1], 0, 0);
		} else if(strcmp(field[0], "redial")==0){
			if(m < 4)
				error(0, Ebadarg);
				error(Ebadarg);
			dkcall(Redial, c, field[1], field[2], field[3]);
		} else if(strcmp(field[0], "accept")==0){
			if(m < 2)
				error(0, Ebadarg);
				error(Ebadarg);
			dkanswer(c, strtoul(field[1], 0, 0), 0);
		} else if(strcmp(field[0], "reject")==0){
			if(m < 3)
				error(0, Ebadarg);
				error(Ebadarg);
			dkanswer(c, strtoul(field[1], 0, 0), strtoul(field[2], 0, 0));
		} else
			return streamwrite(c, a, n, 0);
		return n;
	}

	error(0, Eperm);
	error(Eperm);
}

void	 
dkremove(Chan *c)
{
	error(0, Eperm);
	error(Eperm);
}

void	 
dkwstat(Chan *c, char *dp)
{
	error(0, Eperm);
}

void	 
dkerrstr(Error *e, char *buf)
{
	rooterrstr(e, buf);
}

void	 
dkuserstr(Error *e, char *buf)
{
	extern consuserstr(Error *, char *);

	consuserstr(e, buf);
	error(Eperm);
}

/*


@@ 962,7 950,7 @@ dkopenline(Dk *dp, int line)
		nexterror();
	}
	c = dkattach(dp->name);
	c->qid = STREAMQID(line, Sdataqid);
	c->qid.path = STREAMQID(line, Sdataqid);
	dkopen(c, ORDWR);
	poperror();



@@ 1022,7 1010,7 @@ dkcall(int type, Chan *c, char *addr, char *nuser, char *machine)
	Chan *csc;
	char *bang, *dot;
	
	line = STREAMID(c->qid);
	line = STREAMID(c->qid.path);
	dp = &dk[c->dev];
	lp = &dp->line[line];



@@ 1030,7 1018,7 @@ dkcall(int type, Chan *c, char *addr, char *nuser, char *machine)
	 *  only dial on virgin lines
	 */
	if(lp->state != Lopened)
		error(0, Ebadarg);
		error(Ebadarg);

	DPRINT("dkcall(line=%d, type=%d, dest=%s)\n", line, type, addr);



@@ 1040,9 1028,9 @@ dkcall(int type, Chan *c, char *addr, char *nuser, char *machine)
	 *	- change ! into . to delimit service
	 */
	if(strchr(addr, '\n'))
		error(0, Ebadarg);
		error(Ebadarg);
	if(strlen(addr)+strlen(u->p->pgrp->user)+2 >= sizeof(dialstr))
		error(0, Ebadarg);
		error(Ebadarg);
	strcpy(dialstr, addr);
	bang = strchr(dialstr, '!');
	if(bang){


@@ 1109,7 1097,7 @@ dkcall(int type, Chan *c, char *addr, char *nuser, char *machine)
	if(type==Redial){
		if(streamread(dc, &dialtone, 1L) != 1L){
			lp->state = Lconnected;
			error(0, Ebadarg);
			error(Ebadarg);
		}
	}



@@ 1142,9 1130,9 @@ dkcall(int type, Chan *c, char *addr, char *nuser, char *machine)
	DPRINT("got reply %d\n", lp->state);
	if(lp->state != Lconnected) {
		if(lp->err >= DKERRS)
			error(0, dkerr[0]);
			error(dkerr[0]);
		else
			error(0, dkerr[lp->err]);
			error(dkerr[lp->err]);
	}

	/*


@@ 1202,7 1190,7 @@ dklisten(Chan *c)
	/*
	 *  open the data file
	 */
	dc = dkopenline(dp, STREAMID(c->qid));
	dc = dkopenline(dp, STREAMID(c->qid.path));
	if(waserror()){
		close(dc);
		nexterror();


@@ 1218,7 1206,7 @@ dklisten(Chan *c)
		n = streamread(dc, dialstr, sizeof(dialstr)-1);
		DPRINT("returns %d\n", n);
		if(n <= 0)
			error(0, Eio);
			error(Eio);
		dialstr[n] = 0;
		DPRINT("dialstr = %s\n", dialstr);



@@ 1228,7 1216,7 @@ dklisten(Chan *c)
		n = getfields(dialstr, line, 12, '\n');
		if (n < 2) {
			DPRINT("bad dialstr from dk (1 line)\n");
			error(0, Eio);
			error(Eio);
		}

		/*


@@ 1332,7 1320,7 @@ dklisten(Chan *c)
		default:
			print("bad message from dk(>4 line)\n");
			qunlock(lp);
			error(0, Ebadarg);
			error(Ebadarg);
		}

		sprint(lp->other, "w(%d)", W_TRAF(lp->window));


@@ 1372,7 1360,7 @@ dkanswer(Chan *c, int line, int code)
		close(dc);
		nexterror();
	}
	dc->qid = STREAMQID(STREAMID(c->qid), Sdataqid);
	dc->qid.path = STREAMQID(STREAMID(c->qid.path), Sdataqid);
	dkopen(dc, ORDWR);

	/*


@@ 1395,7 1383,7 @@ dkwindow(Chan *c)
	long wins;
	Line *lp;

	lp = &dk[c->dev].line[STREAMID(c->qid)];
	lp = &dk[c->dev].line[STREAMID(c->qid.path)];
	if(lp->window == 0)
		lp->window = 64;
	sprint(buf, "init %d %d", lp->window, Streamhi);


@@ 1444,7 1432,7 @@ dkcsckproc(void *a)
		n = streamread(dp->csc, (char *)&d, (long)sizeof(d));
		if(n != sizeof(d)){
			if(n == 0)
				error(0, Ehungup);
				error(Ehungup);
			print("strange csc message %d\n", n);
			continue;
		}


@@ 1663,7 1651,7 @@ dktimer(void *a)

	for(;;){
		if(dp->opened==0)
			error(0, Ehungup);
			error(Ehungup);

		/*
		 * send keep alive

M port/devdup.c => port/devdup.c +9 -21
@@ 20,7 20,7 @@ dupgen(Chan *c, Dirtab *tab, int ntab, int s, Dir *dp)
	if((f=u->fd[s]) == 0)
		return 0;
	sprint(buf, "%ld", s);
	devdir(c, s, buf, 0, perm[f->mode&3], dp);
	devdir(c, (Qid){s, 0}, buf, 0, perm[f->mode&3], dp);
	return 1;
}



@@ 63,16 63,16 @@ dupopen(Chan *c, int omode)
{
	Chan *f;

	if(c->qid == CHDIR){
	if(c->qid.path == CHDIR){
		if(omode != 0)
			error(0, Eisdir);
			error(Eisdir);
		c->mode = 0;
		c->flag |= COPEN;
		c->offset = 0;
		return c;
	}
	fdtochan(c->qid, openmode(omode));	/* error check only */
	f = u->fd[c->qid];
	fdtochan(c->qid.path, openmode(omode));	/* error check only */
	f = u->fd[c->qid.path];
	close(c);
	incref(f);
	return f;


@@ 81,19 81,19 @@ dupopen(Chan *c, int omode)
void
dupcreate(Chan *c, char *name, int omode, ulong perm)
{
	error(0, Eperm);
	error(Eperm);
}

void
dupremove(Chan *c)
{
	error(0, Eperm);
	error(Eperm);
}

void
dupwstat(Chan *c, char *dp)
{
	error(0, Egreg);
	error(Egreg);
}

void


@@ 106,7 106,7 @@ dupread(Chan *c, void *va, long n)
{
	char *a = va;

	if(c->qid != CHDIR)
	if(c->qid.path != CHDIR)
		panic("dupread");
	return devdirread(c, a, n, (Dirtab *)0, 0L, dupgen);
}


@@ 116,15 116,3 @@ dupwrite(Chan *c, void *va, long n)
{
	panic("dupwrite");
}

void
duperrstr(Error *e, char *buf)
{
	rooterrstr(e, buf);
}

void
dupuserstr(Error *e, char *buf)
{
	consuserstr(e, buf);
}

M port/devenv.c => port/devenv.c +29 -42
@@ 155,7 155,7 @@ compactenv(Env *e, ulong n)
	envalloc.vfree = p1;
	if(envalloc.end-envalloc.vfree < n){
		print("env compact failed\n");
		error(0, Enoenv);
		error(Enoenv);
	}
}



@@ 173,7 173,7 @@ copyenv(Env *e, int trunc)
	ne = envalloc.efree;
	if(!ne){
		print("out of envs\n");
		error(0, Enoenv);
		error(Enoenv);
	}
	envalloc.efree = ne->next;
	lock(ne);


@@ 224,7 224,7 @@ envgen(Chan *c, Dirtab *tab, int ntab, int s, Dir *dp)
			ans = 0;
		else{
			lock(e);
			devdir(c, s+1, e->name, e->val? e->val->len : 0, 0666, dp);
			devdir(c, (Qid){s+1,0}, e->name, e->val? e->val->len : 0, 0666, dp);
			unlock(e);
			ans = 1;
		}


@@ 244,10 244,10 @@ envclone(Chan *c, Chan *nc)
{
	Pgrp *pg;

	if(!(c->qid&CHDIR)){
	if(!(c->qid.path&CHDIR)){
		pg = u->p->pgrp;
		lock(pg);
		pg->etab[c->qid-1].chref++;
		pg->etab[c->qid.path-1].chref++;
		unlock(pg);
	}
	return devclone(c, nc);


@@ 259,10 259,10 @@ envwalk(Chan *c, char *name)
	Pgrp *pg;

	if(devwalk(c, name, 0, 0, envgen)){
		if(!(c->qid&CHDIR)){
		if(!(c->qid.path&CHDIR)){
			pg = u->p->pgrp;
			lock(pg);
			pg->etab[c->qid-1].chref++;
			pg->etab[c->qid.path-1].chref++;
			unlock(pg);
			return 1;
		}


@@ 284,15 284,15 @@ envopen(Chan *c, int omode)
	Pgrp *pg;

	if(omode & (OWRITE|OTRUNC)){
		if(c->qid & CHDIR)
			error(0, Eperm);
		if(c->qid.path & CHDIR)
			error(Eperm);
		pg = u->p->pgrp;
		lock(pg);
		ep = &pg->etab[c->qid-1];
		ep = &pg->etab[c->qid.path-1];
		e = ep->env;
		if(!e){
			unlock(pg);
			error(0, Egreg);
			error(Egreg);
		}
		lock(&envalloc);
		lock(e);


@@ 333,8 333,8 @@ envcreate(Chan *c, char *name, int omode, ulong perm)
	Pgrp *pg;
	int i;

	if(c->qid != CHDIR)
		error(0, Eperm);
	if(c->qid.path != CHDIR)
		error(Eperm);
	pg = u->p->pgrp;
	lock(pg);
	lock(&envalloc);


@@ 346,7 346,7 @@ envcreate(Chan *c, char *name, int omode, ulong perm)
	e = envalloc.efree;
	if(e == 0){
		print("out of envs\n");
		error(0,Enoenv);
		error(Enoenv);
	}
	envalloc.efree = e->next;
	e->next = 0;


@@ 358,11 358,11 @@ envcreate(Chan *c, char *name, int omode, ulong perm)
				break;
		if(i == pg->nenv){
			print("out of pgroup envs\n");
			error(0, Enoenv);
			error(Enoenv);
		}
	}else
		i = pg->nenv++;
	c->qid = i+1;
	c->qid.path = i+1;
	pg->etab[i].env = e;
	pg->etab[i].chref = 1;
	unlock(&envalloc);


@@ 380,15 380,15 @@ envremove(Chan *c)
	Envp *ep;
	Pgrp *pg;

	if(c->qid & CHDIR)
		error(0, Eperm);
	if(c->qid.path & CHDIR)
		error(Eperm);
	pg = u->p->pgrp;
	lock(pg);
	ep = &pg->etab[c->qid-1];
	ep = &pg->etab[c->qid.path-1];
	e = ep->env;
	if(!e){
		unlock(pg);
		error(0, Enonexist);
		error(Enonexist);
	}
	ep->env = 0;
	ep->chref--;


@@ 401,7 401,7 @@ envwstat(Chan *c, char *db)
{	int dumpenv(void);
	dumpenv();  /*DEBUG*/
	print("envwstat\n");
	error(0, Egreg);
	error(Egreg);
}

void


@@ 409,11 409,11 @@ envclose(Chan * c)
{
	Pgrp *pg;

	if(c->qid & CHDIR)
	if(c->qid.path & CHDIR)
		return;
	pg = u->p->pgrp;
	lock(pg);
	pg->etab[c->qid-1].chref--;
	pg->etab[c->qid.path-1].chref--;
	unlock(pg);
}



@@ 444,14 444,14 @@ envread(Chan *c, void *va, long n)
	Pgrp *pg;
	char *a = va;

	if(c->qid & CHDIR)
	if(c->qid.path & CHDIR)
		return devdirread(c, a, n, 0, 0, envgen);
	pg = u->p->pgrp;
	lock(pg);
	e = pg->etab[c->qid-1].env;
	e = pg->etab[c->qid.path-1].env;
	if(!e){
		unlock(pg);
		error(0, Eio);
		error(Eio);
	}
	lock(e);
	ev = e->val;


@@ 481,10 481,10 @@ envwrite(Chan *c, void *va, long n)
		return 0;
	pg = u->p->pgrp;
	lock(pg);
	e = pg->etab[c->qid-1].env; /* caller checks for CHDIR */
	e = pg->etab[c->qid.path-1].env; /* caller checks for CHDIR */
	if(!e){
		unlock(pg);
		error(0, Eio);
		error(Eio);
	}
	lock(&envalloc);
	lock(e);


@@ 500,7 500,7 @@ envwrite(Chan *c, void *va, long n)
	ev = e->val;
	vn = ev? ev->len : 0;
	if(c->offset > vn)
		error(0, Egreg); /* perhaps should zero fill */
		error(Egreg); /* perhaps should zero fill */
	memcpy(ev->dat+c->offset, a, n);
	e->val->len = c->offset+n;
	poperror();


@@ 543,16 543,3 @@ dumpenv(void)
			i += ev->n*sizeof(Envval);
	print(" %d free enval chars\n", i+((char *)envalloc.end-(char*)envalloc.vfree));
}

void
envuserstr(Error *e, char *buf)
{
	consuserstr(e, buf);
}

void
enverrstr(Error *e, char *buf)
{
	rooterrstr(e, buf);
}


M port/devlance.c => port/devlance.c +13 -24
@@ 626,16 626,17 @@ lanceinit(void)
	 */
	for(i=0; i<Ntypes; i++) {
		sprint(lancedir[i].name, "%d", i);
		lancedir[i].qid = CHDIR|STREAMQID(i, Lchanqid);
		lancedir[i].qid.path = CHDIR|STREAMQID(i, Lchanqid);
		lancedir[i].qid.vers = 0;
		lancedir[i].length = 0;
		lancedir[i].perm = 0600;
	}
	strcpy(lancedir[Ntypes].name, "trace");
	lancedir[Ntypes].qid = Ltraceqid;
	lancedir[Ntypes].qid.path = Ltraceqid;
	lancedir[Ntypes].length = 0;
	lancedir[Ntypes].perm = 0600;
	strcpy(lancedir[Ntypes+1].name, "stats");
	lancedir[Ntypes+1].qid = Lstatsqid;
	lancedir[Ntypes+1].qid.path = Lstatsqid;
	lancedir[Ntypes+1].length = 0;
	lancedir[Ntypes+1].perm = 0600;
}


@@ 668,7 669,7 @@ lanceclone(Chan *c, Chan *nc)
int	 
lancewalk(Chan *c, char *name)
{
	if(c->qid == CHDIR)
	if(c->qid.path == CHDIR)
		return devwalk(c, name, lancedir, Ndir, devgen);
	else
		return devwalk(c, name, 0, 0, streamgen);


@@ 677,7 678,7 @@ lancewalk(Chan *c, char *name)
void	 
lancestat(Chan *c, char *dp)
{
	if(c->qid==CHDIR || c->qid==Ltraceqid || c->qid==Lstatsqid)
	if(c->qid.path==CHDIR || c->qid.path==Ltraceqid || c->qid.path==Lstatsqid)
		devstat(c, dp, lancedir, Ndir, devgen);
	else
		devstat(c, dp, 0, 0, streamgen);


@@ 691,12 692,12 @@ lanceopen(Chan *c, int omode)
{
	extern Qinfo nonetinfo;

	switch(c->qid){
	switch(c->qid.path){
	case CHDIR:
	case Ltraceqid:
	case Lstatsqid:
		if(omode != OREAD)
			error(0, Eperm);
			error(Eperm);
		break;
	default:
		streamopen(c, &lanceinfo);


@@ 711,14 712,14 @@ lanceopen(Chan *c, int omode)
void	 
lancecreate(Chan *c, char *name, int omode, ulong perm)
{
	error(0, Eperm);
	error(Eperm);
}

void	 
lanceclose(Chan *c)
{
	/* real closing happens in lancestclose */
	switch(c->qid){
	switch(c->qid.path){
	case CHDIR:
	case Ltraceqid:
	case Lstatsqid:


@@ 767,7 768,7 @@ lanceread(Chan *c, void *a, long n)
{
	char buf[256];

	switch(c->qid){
	switch(c->qid.path){
	case CHDIR:
		return devdirread(c, a, n, lancedir, Ndir, devgen);
	case Lstatsqid:


@@ 791,25 792,13 @@ lancewrite(Chan *c, void *a, long n)
void	 
lanceremove(Chan *c)
{
	error(0, Eperm);
	error(Eperm);
}

void	 
lancewstat(Chan *c, char *dp)
{
	error(0, Eperm);
}

void	 
lanceerrstr(Error *e, char *buf)
{
	rooterrstr(e, buf);
}

void	 
lanceuserstr(Error *e, char *buf)
{
	consuserstr(e, buf);
	error(Eperm);
}

/*

M port/devmnt.c => port/devmnt.c +38 -88
@@ 9,7 9,6 @@

#include	"fcall.h"


typedef struct Mnt	Mnt;
typedef struct Mnthdr	Mnthdr;
typedef struct MntQ	MntQ;


@@ 194,7 193,7 @@ mntdev(int dev, int noerr)
		}
	if(noerr)
		return 0;
	error(0, Eshutdown);
	error(Eshutdown);
}

void


@@ 214,9 213,12 @@ mntreset(void)
	mntbufalloc.free = mb;

	mh = ialloc(conf.nmnthdr*sizeof(Mnthdr), 0);
	for(i=0; i<conf.nmnthdr-1; i++)
	for(i=0; i<conf.nmnthdr-1; i++){
		mh[i].next = &mh[i+1];
		mh[i].thdr.tag = i;
	}
	mh[i].next = 0;
	mh[i].thdr.tag = i;
	mnthdralloc.free = mh;

	mq = ialloc(conf.nmntdev*sizeof(MntQ), 0);


@@ 233,7 235,7 @@ mntinit(void)
}

Chan*
mntattach(char *spec)
mntattach(char *crud)
{
	int i;
	Mnt *m, *mm;


@@ 243,10 245,10 @@ mntattach(char *spec)
	struct bogus{
		Chan	*chan;
		char	*spec;
		char	*auth;
	}bogus;

	bogus = *((struct bogus *)spec);
	spec = bogus.spec;
	bogus = *((struct bogus *)crud);

	m = mnt;
	for(i=0; i<conf.nmntdev; i++,m++){


@@ 255,7 257,7 @@ mntattach(char *spec)
			goto Found;
		unlock(m);
	}
	error(0, Enomntdev);
	error(Enomntdev);

    Found:
	m->ref = 1;


@@ 263,7 265,7 @@ mntattach(char *spec)
	lock(&mntid);
	m->mntid = ++mntid.id;
	unlock(&mntid);
	c = devattach('M', spec);
	c = devattach('M', bogus.spec);
	c->dev = m->mntid;
	m->mntpt = c;
	cm = bogus.chan;


@@ 297,7 299,8 @@ mntattach(char *spec)
	mh->thdr.type = Tattach;
	mh->thdr.fid = c->fid;
	memcpy(mh->thdr.uname, u->p->pgrp->user, NAMELEN);
	strcpy(mh->thdr.aname, spec);
	strcpy(mh->thdr.aname, bogus.spec);
	strcpy(mh->thdr.auth, bogus.auth);
	mntxmit(m, mh);
	c->qid = mh->rhdr.qid;
	c->mchan = m->q->msg;


@@ 537,7 540,7 @@ mntread(Chan *c, void *buf, long n)
	uchar *b;

	n = mntreadwrite(c, buf, n, Tread);
	if(c->qid & CHDIR){
	if(c->qid.path & CHDIR){
		b = (uchar*)buf;
		for(i=n-DIRLEN; i>=0; i-=DIRLEN){
			b[DIRLEN-4] = devchar[c->type];


@@ 582,60 585,6 @@ mntwstat(Chan *c, char *dp)
	poperror();
}

void	 
mnterrstr(Error *e, char *buf)
{
	Mnt *m;
	Mnthdr *mh;
	char *def="mounted device shut down";

	m = mntdev(e->dev, 1);
	if(m == 0){
		strcpy(buf, def);
		return;
	}
	mh = mhalloc();
	if(waserror()){
		strcpy(buf, def);
		mhfree(mh);
		nexterror();
	}
	mh->thdr.type = Terrstr;
	mh->thdr.fid = 0;
	mh->thdr.err = e->code;
	mntxmit(m, mh);
	strcpy(buf, (char*)mh->rhdr.ename);
	mhfree(mh);
	poperror();
}

void	 
mntuserstr(Error *e, char *buf)
{
	Mnt *m;
	Mnthdr *mh;
	char *def="mounted device shut down";

	m = mntdev(e->dev, 1);
	if(m == 0){
		strcpy(buf, def);
		return;
	}
	mh = mhalloc();
	if(waserror()){
		strcpy(buf, def);
		mhfree(mh);
		nexterror();
	}
	mh->thdr.type = Tuserstr;
	mh->thdr.fid = 0;
	mh->thdr.uid = e->code;
	mntxmit(m, mh);
	strcpy(buf, (char*)mh->rhdr.uname);
	mhfree(mh);
	poperror();
}

void
mnterrdequeue(MntQ *q, Mnthdr *mh)		/* queue is unlocked */
{


@@ 670,18 619,19 @@ mnterrdequeue(MntQ *q, Mnthdr *mh)		/* queue is unlocked */
	qunlock(q);

}

int
mntreadreply(void *a)
{
	return ((Mnthdr *)a)->readreply;
}

void
mntxmit(Mnt *m, Mnthdr *mh)
{
	ulong n;
	Mntbuf *mbw;
	Mnthdr *w, *ow;
	Chan *mntpt;
	MntQ *q;
	int qlocked;



@@ 695,7 645,7 @@ mntxmit(Mnt *m, Mnthdr *mh)
	n = convS2M(&mh->thdr, mbw->buf);
	q = m->q;
	if(q == 0)
		error(0, Eshutdown);
		error(Eshutdown);
#ifdef	BIT3
	/*
	 * Bit3 does its own multiplexing.  (Well, the file server does.)


@@ 711,7 661,7 @@ mntxmit(Mnt *m, Mnthdr *mh)
	}
	if((*devtab[q->msg->type].write)(q->msg, mbw->buf, n) != n){
		print("short write in mntxmit\n");
		error(0, Eshortmsg);
		error(Eshortmsg);
	}

	/*


@@ 723,25 673,28 @@ mntxmit(Mnt *m, Mnthdr *mh)

	if(convM2S(mh->mbr->buf, &mh->rhdr, n) == 0){
		print("format error in mntxmit\n");
		error(0, Ebadmsg);
		error(Ebadmsg);
	}

	/*
	 * Various checks
	 */
	if(mh->rhdr.tag != mh->thdr.tag){
		print("tag mismatch %d %d\n", mh->rhdr.tag, mh->thdr.tag);
		error(Ebadmsg);
	}
	if(mh->rhdr.type == Rerror){
		if(m->mntpt)
			errors(mh->rhdr.ename);
		error(Eshutdown);
	}
	if(mh->rhdr.type != mh->thdr.type+1){
		print("type mismatch %d %d\n", mh->rhdr.type, mh->thdr.type+1);
		error(0, Ebadmsg);
		error(Ebadmsg);
	}
	if(mh->rhdr.fid != mh->thdr.fid){
		print("fid mismatch %d %d type %d\n", mh->rhdr.fid, mh->thdr.fid, mh->rhdr.type);
		error(0, Ebadmsg);
	}
	if(mh->rhdr.err){
		mntpt = m->mntpt;	/* unsafe, but Errors are unsafe anyway */
		if(mntpt)
			error(mntpt, mh->rhdr.err);
		error(0, Eshutdown);
		error(Ebadmsg);
	}

	/*


@@ 768,7 721,7 @@ mntxmit(Mnt *m, Mnthdr *mh)
	mh->readreply = 0;
	if((*devtab[q->msg->type].write)(q->msg, mbw->buf, n) != n){
		print("short write in mntxmit\n");
		error(0, Eshortmsg);
		error(Eshortmsg);
	}
	if(q->reader == 0){		/* i will read */
		q->reader = u->p;


@@ 783,15 736,14 @@ mntxmit(Mnt *m, Mnthdr *mh)
		poperror();
		if(convM2S(mh->mbr->buf, &mh->rhdr, n) == 0){
			mnterrdequeue(q, mh);
			error(0, Ebadmsg);
			error(Ebadmsg);
		}
		/*
		 * Response might not be mine
		 */
		qlock(q);
		qlocked = 1;
		if(mh->rhdr.fid == mh->thdr.fid
		&& mh->rhdr.type == mh->thdr.type+1){	/* it's mine */
		if(mh->rhdr.tag == mh->thdr.tag){	/* it's mine */
			q->reader = 0;
			if(w = q->writer){	/* advance a writer to reader */
				q->reader = w->p;


@@ 807,8 759,7 @@ mntxmit(Mnt *m, Mnthdr *mh)
		 * Hand response to correct recipient
		 */
		for(ow=0,w=q->writer; w; ow=w,w=w->next)
			if(mh->rhdr.fid == w->thdr.fid
			&& mh->rhdr.type == w->thdr.type+1){
			if(mh->rhdr.tag == w->thdr.tag){
				Mntbuf *t;
				t = mh->mbr;
				mh->mbr = w->mbr;


@@ 849,18 800,17 @@ mntxmit(Mnt *m, Mnthdr *mh)
    Respond:
	mqfree(q);
	poperror();
	if(mh->rhdr.err){
		mntpt = m->mntpt;	/* unsafe, but Errors are unsafe anyway */
		if(mntpt)
			error(mntpt, mh->rhdr.err);
		error(0, Eshutdown);
	if(mh->rhdr.type == Rerror){
		if(m->mntpt)
			errors(mh->rhdr.ename);
		error(Eshutdown);
	}
	/*
	 * Copy out on read
	 */
	if(mh->thdr.type == Tread){
		if(mh->rhdr.count > mh->thdr.count)
			error(0, Ebadcnt);
			error(Ebadcnt);
		memcpy(mh->thdr.data, mh->rhdr.data, mh->rhdr.count);
	}
	mbfree(mh->mbr);

M port/devpipe.c => port/devpipe.c +25 -39
@@ 37,10 37,10 @@ Qinfo pipeinfo =
};

Dirtab pipedir[]={
	"data",		Sdataqid,	0,			0600,
	"ctl",		Sctlqid,	0,			0600,
	"data1",	Sdataqid,	0,			0600,
	"ctl1",		Sctlqid,	0,			0600,
	"data",		{Sdataqid},	0,			0600,
	"ctl",		{Sctlqid},	0,			0600,
	"data1",	{Sdataqid},	0,			0600,
	"ctl1",		{Sctlqid},	0,			0600,
};
#define NPIPEDIR 4



@@ 78,7 78,7 @@ pipeattach(char *spec)
	lock(&pipealloc);
	if(pipealloc.free == 0){
		unlock(&pipealloc);
		error(0, Enopipe);
		error(Enopipe);
	}
	p = pipealloc.free;
	pipealloc.free = p->next;


@@ 86,7 86,7 @@ pipeattach(char *spec)
		panic("pipeattach");
	unlock(&pipealloc);

	c->qid = CHDIR|STREAMQID(2*(p - pipealloc.pipe), 0);
	c->qid = (Qid){CHDIR|STREAMQID(2*(p - pipealloc.pipe), 0), 0};
	return c;
}



@@ 95,7 95,7 @@ pipeclone(Chan *c, Chan *nc)
{
	Pipe *p;

	p = &pipealloc.pipe[STREAMID(c->qid)/2];
	p = &pipealloc.pipe[STREAMID(c->qid.path)/2];
	nc = devclone(c, nc);
	if(incref(p) <= 1)
		panic("pipeclone");


@@ 107,13 107,13 @@ pipegen(Chan *c, Dirtab *tab, int ntab, int i, Dir *dp)
{
	int id;

	id = STREAMID(c->qid);
	id = STREAMID(c->qid.path);
	if(i > 1)
		id++;
	if(tab==0 || i>=ntab)
		return -1;
	tab += i;
	devdir(c, STREAMQID(id, tab->qid), tab->name, tab->length, tab->perm, dp);
	devdir(c, (Qid){STREAMQID(id, tab->qid.path),0}, tab->name, tab->length, tab->perm, dp);
	return 1;
}



@@ 139,16 139,16 @@ pipeopen(Chan *c, int omode)
	Pipe *p;
	Stream *local, *remote;

	if(CHDIR & c->qid){
	if(c->qid.path & CHDIR){
		if(omode != OREAD)
			error(0, Ebadarg);
			error(Ebadarg);
		c->mode = omode;
		c->flag |= COPEN;
		c->offset = 0;
		return c;
	}

	p = &pipealloc.pipe[STREAMID(c->qid)/2];
	p = &pipealloc.pipe[STREAMID(c->qid.path)/2];
	remote = 0;
	if(waserror()){
		unlock(p);


@@ 163,7 163,7 @@ pipeopen(Chan *c, int omode)
		/*
		 *  First stream opened, create the other end also
		 */
		remote = streamnew(c->type, c->dev, STREAMID(c->qid)^1, &pipeinfo, 1);
		remote = streamnew(c->type, c->dev, STREAMID(c->qid.path)^1, &pipeinfo, 1);

		/*
		 *  connect the device ends of both streams


@@ 192,33 192,37 @@ pipeopen(Chan *c, int omode)
void
pipecreate(Chan *c, char *name, int omode, ulong perm)
{
	error(0, Egreg);
	error(Egreg);
}

void
piperemove(Chan *c)
{
	error(0, Egreg);
	error(Egreg);
}

void
pipewstat(Chan *c, char *db)
{
	error(0, Eperm);
	error(Eperm);
}

void
pipeclose(Chan *c)
{
	Pipe *p;
	Stream *remote;

	p = &pipealloc.pipe[STREAMID(c->qid)/2];
	p = &pipealloc.pipe[STREAMID(c->qid.path)/2];

	/*
	 *  take care of associated streams
	 */
	if(c->stream)
		streamclose(c);		/* close this stream */
	if(c->stream){
		remote = c->stream->devq->ptr;
		if(streamclose(c) <= 0)
			streamexit(remote, 0);
	}

	/*
	 *  free the structure


@@ 236,7 240,7 @@ pipeclose(Chan *c)
long
piperead(Chan *c, void *va, long n)
{
	if(CHDIR&c->qid)
	if(c->qid.path & CHDIR)
		return devdirread(c, va, n, pipedir, NPIPEDIR, pipegen);
	else
		return streamread(c, va, n);


@@ 251,25 255,13 @@ pipewrite(Chan *c, void *va, long n)
{
	if(waserror()){
		postnote(u->p, 1, "sys: write on closed pipe", NExit);
		error(0, Egreg);
		error(Egreg);
	}
	n = streamwrite(c, va, n, 0);
	poperror();
	return n;
}

void
pipeuserstr(Error *e, char *buf)
{
	consuserstr(e, buf);
}

void
pipeerrstr(Error *e, char *buf)
{
	rooterrstr(e, buf);
}

/*
 *  stream stuff
 */


@@ 317,10 309,4 @@ pipestclose(Queue *q)
	bp = allocb(0);
	bp->type = M_HANGUP;
	PUTNEXT(q, bp);

	/*
	 *  release stream for other half of pipe
	 */
	remote = RD(q)->ptr;
	streamexit(remote, 0);
}

M port/devproc.c => port/devproc.c +59 -75
@@ 22,28 22,28 @@ enum{
};

Dirtab procdir[]={
	"ctl",		Qctl,		0,			0600,
	"mem",		Qmem,		0,			0600,
	"note",		Qnote,		0,			0600,
	"notepg",	Qnotepg,	0,			0200,
	"proc",		Qproc,		sizeof(Proc),		0600,
	"status",	Qstatus,	NAMELEN+12+6*12,	0600,
	"text",		Qtext,		0,			0600,
	"ctl",		{Qctl},		0,			0600,
	"mem",		{Qmem},		0,			0600,
	"note",		{Qnote},	0,			0600,
	"notepg",	{Qnotepg},	0,			0200,
	"proc",		{Qproc},	sizeof(Proc),		0600,
	"status",	{Qstatus},	NAMELEN+12+6*12,	0600,
	"text",		{Qtext},	0,			0600,
};

/*
 * Qids are, from bottom to top:
 * Qids are, in path:
 *	 4 bits of file type (qids above)
 *	12 bits of process slot number + 1
 *	15 bits of pid, for consistency checking
 *	24 bits of process slot number + 1
 *	     in vers,
 *	32 bits of pid, for consistency checking
 * If notepg, c->pgrpid.path is pgrp slot, .vers is pgrpid.
 */
#define	NPROC	(sizeof procdir/sizeof(Dirtab))
#define	QSHIFT	4	/* location in qid of proc slot # */
#define	PIDSHIFT 16	/* location in qid of pid */
#define	PIDMASK	0x7FFF	/* low bits of pid used in qid */
#define	QID(q)	(((q)&0x0000000F)>>0)
#define	SLOT(q)	((((q)&0x0000FFF0)>>QSHIFT)-1)
#define	PID(q)	(((q)&0x7FFF0000)>>PIDSHIFT)
#define	QID(q)	(((q).path&0x0000000F)>>0)
#define	SLOT(q)	((((q).path&0x0FFFFFFF0)>>QSHIFT)-1)
#define	PID(q)	((q).vers)

int
procgen(Chan *c, Dirtab *tab, int ntab, int s, Dir *dp)


@@ 52,7 52,7 @@ procgen(Chan *c, Dirtab *tab, int ntab, int s, Dir *dp)
	char buf[NAMELEN];
	ulong pid;

	if(c->qid == CHDIR){
	if(c->qid.path == CHDIR){
		if(s >= conf.nproc)
			return -1;
		p = proctab(s);


@@ 60,7 60,7 @@ procgen(Chan *c, Dirtab *tab, int ntab, int s, Dir *dp)
		if(pid == 0)
			return 0;
		sprint(buf, "%d", pid);
		devdir(c, CHDIR|(pid<<PIDSHIFT)|((s+1)<<QSHIFT), buf, 0, CHDIR|0500, dp);
		devdir(c, (Qid){CHDIR|((s+1)<<QSHIFT), pid}, buf, 0, CHDIR|0500, dp);
		return 1;
	}
	if(s >= NPROC)


@@ 68,7 68,8 @@ procgen(Chan *c, Dirtab *tab, int ntab, int s, Dir *dp)
	if(tab)
		panic("procgen");
	tab = &procdir[s];
	devdir(c, (~CHDIR)&(c->qid|tab->qid), tab->name, tab->length, tab->perm, dp);
	devdir(c, (Qid){(~CHDIR)&(c->qid.path|tab->qid.path), c->qid.vers},
		tab->name, tab->length, tab->perm, dp);
	return 1;
}



@@ 117,16 118,16 @@ procopen(Chan *c, int omode)
	Orig *o;
	Chan *tc;

	if(c->qid == CHDIR){
	if(c->qid.path == CHDIR){
		if(omode != OREAD)
			error(0, Eperm);
			error(Eperm);
		goto done;
	}
	p = proctab(SLOT(c->qid));
	pg = p->pgrp;
	if((p->pid&PIDMASK) != PID(c->qid))
	if(p->pid != PID(c->qid))
    Died:
		error(0, Eprocdied);
		error(Eprocdied);
	omode = openmode(omode);

	switch(QID(c->qid)){


@@ 144,7 145,7 @@ procopen(Chan *c, int omode)
		}
		if(!(tc->flag&COPEN) || tc->mode!=OREAD)
			goto Close;
		if((p->pid&PIDMASK) != PID(c->qid))
		if(p->pid != PID(c->qid))
			goto Close;
		qlock(tc);
		tc->offset = 0;


@@ 156,8 157,9 @@ procopen(Chan *c, int omode)

	case Qnotepg:
		if(omode!=OWRITE || pg->pgrpid==1)	/* easy to do by mistake */
			error(0, Eperm);
		c->pgrpid = (pg->pgrpid<<PIDSHIFT)|((pg->index+1)<<QSHIFT);
			error(Eperm);
		c->pgrpid.path = pg->index+1;
		c->pgrpid.vers = pg->pgrpid;
		break;

	case Qdir:


@@ 165,17 167,17 @@ procopen(Chan *c, int omode)
	case Qproc:
	case Qstatus:
		if(omode != OREAD)
			error(0, Eperm);
			error(Eperm);
		break;
	default:
		pprint("unknown qid in devopen\n");
		error(0, Egreg);
		error(Egreg);
	}
	/*
	 * Affix pid to qid
	 */
	if(p->state != Dead)
		c->qid |= (p->pid&PIDMASK)<<PIDSHIFT;
		c->qid.vers = p->pid;
   done:
	c->mode = omode;
	c->flag |= COPEN;


@@ 186,19 188,19 @@ procopen(Chan *c, int omode)
void
proccreate(Chan *c, char *name, int omode, ulong perm)
{
	error(0, Eperm);
	error(Eperm);
}

void
procremove(Chan *c)
{
	error(0, Eperm);
	error(Eperm);
}

void
procwstat(Chan *c, char *db)
{
	error(0, Eperm);
	error(Eperm);
}

void


@@ 222,15 224,15 @@ procread(Chan *c, void *va, long n)
	long pid;
	User *up;

	if(c->qid & CHDIR)
	if(c->qid.path & CHDIR)
		return devdirread(c, a, n, 0, 0, procgen);

	/*
	 * BUG: should lock(&p->debug)?
	 */
	p = proctab(SLOT(c->qid));
	if((p->pid&PIDMASK) != PID(c->qid))
		error(0, Eprocdied);
	if(p->pid != PID(c->qid))
		error(Eprocdied);

	switch(QID(c->qid)){
	case Qmem:


@@ 243,15 245,15 @@ procread(Chan *c, void *va, long n)
		if(s){
			o = s->o;
			if(o == 0)
				error(0, Eprocdied);
				error(Eprocdied);
			lock(o);
			if(s->o!=o || (p->pid&PIDMASK)!=PID(c->qid)){
			if(s->o!=o || p->pid!=PID(c->qid)){
				unlock(o);
				error(0, Eprocdied);
				error(Eprocdied);
			}
			if(seg(p, c->offset) != s){
				unlock(o);
				error(0, Egreg);
				error(Egreg);
			}
			pte = &o->pte[(c->offset-o->va)>>PGSHIFT];
			if(s->mod){


@@ 281,8 283,8 @@ procread(Chan *c, void *va, long n)
			if(c->offset+n > USERADDR+BY2PG)
				n = USERADDR+BY2PG - c->offset;
			pg = p->upage;
			if(pg==0 || (p->pid&PIDMASK)!=PID(c->qid))
				error(0, Eprocdied);
			if(pg==0 || p->pid!=PID(c->qid))
				error(Eprocdied);
			k = kmap(pg);
			b = (char*)VA(k);
			memcpy(a, b+(c->offset-USERADDR), n);


@@ 296,12 298,6 @@ procread(Chan *c, void *va, long n)
				n = KZERO+conf.npage0*BY2PG - c->offset;
			memcpy(a, (char*)c->offset, n);
			return n;
		}else if(c->offset>=UNCACHED && c->offset<UNCACHED+conf.npage0*BY2PG){
			/* BUT mips only TAKE IT OUT */
			if(c->offset+n > UNCACHED+conf.npage0*BY2PG)
				n = UNCACHED+conf.npage0*BY2PG - c->offset;
			memcpy(a, (char*)c->offset, n);
			return n;
		}
		return 0;
		break;


@@ 312,17 308,17 @@ procread(Chan *c, void *va, long n)
			unlock(&p->debug);
			nexterror();
		}
		if((p->pid&PIDMASK) != PID(c->qid))
			error(0, Eprocdied);
		if(p->pid != PID(c->qid))
			error(Eprocdied);
		k = kmap(p->upage);
		up = (User*)VA(k);
		if(up->p != p){
			kunmap(k);
			pprint("note read u/p mismatch");
			error(0, Egreg);
			error(Egreg);
		}
		if(n < ERRLEN)
			error(0, Etoosmall);
			error(Etoosmall);
		if(up->nnote == 0)
			n = 0;
		else{


@@ 359,7 355,7 @@ procread(Chan *c, void *va, long n)
		memcpy(a, statbuf+c->offset, n);
		return n;
	}
	error(0, Egreg);
	error(Egreg);
}




@@ 372,20 368,20 @@ procwrite(Chan *c, void *va, long n)
	KMap *k;
	char buf[ERRLEN];

	if(c->qid & CHDIR)
		error(0, Eisdir);
	if(c->qid.path & CHDIR)
		error(Eisdir);

	/*
	 * Special case: don't worry about process, just use remembered group
	 */
	if(QID(c->qid) == Qnotepg){
		pg = pgrptab(SLOT(c->pgrpid));
		pg = pgrptab(c->pgrpid.path-1);
		lock(&pg->debug);
		if(waserror()){
			unlock(&pg->debug);
			nexterror();
		}
		if((pg->pgrpid&PIDMASK) != PID(c->pgrpid)){
		if(pg->pgrpid != c->pgrpid.vers){
			unlock(&pg->debug);
  	  		goto Died;
		}


@@ 400,16 396,16 @@ procwrite(Chan *c, void *va, long n)
		unlock(&p->debug);
		nexterror();
	}
	if((p->pid&PIDMASK) != PID(c->qid))
	if(p->pid != PID(c->qid))
    Died:
		error(0, Eprocdied);
		error(Eprocdied);

	switch(QID(c->qid)){
	case Qctl:
		if(p->state==Broken && n>=4 && strncmp(va, "exit", 4)==0)
			ready(p);
		else
			error(0, Ebadctl);
			error(Ebadctl);
		break;
	case Qnote:
		k = kmap(p->upage);


@@ 417,34 413,22 @@ procwrite(Chan *c, void *va, long n)
		if(up->p != p){
			kunmap(k);
			pprint("note write u/p mismatch");
			error(0, Egreg);
			error(Egreg);
		}
		kunmap(k);
		if(n >= ERRLEN-1)
			error(0, Etoobig);
			error(Etoobig);
		if(n>=4 && strncmp(va, "sys:", 4)==0)
			error(0, Ebadarg);
			error(Ebadarg);
		memcpy(buf, va, n);
		buf[n] = 0;
		if(!postnote(p, 0, buf, NUser))
			error(0, Enonote);
			error(Enonote);
		break;
	default:
		pprint("unknown qid in procwrite\n");
		error(0, Egreg);
		error(Egreg);
	}
	unlock(&p->debug);
	return n;
}

void
procuserstr(Error *e, char *buf)
{
	consuserstr(e, buf);
}

void
procerrstr(Error *e, char *buf)
{
	rooterrstr(e, buf);
}

M port/devroot.c => port/devroot.c +11 -28
@@ 16,11 16,11 @@ enum{
};

Dirtab rootdir[]={
	"bin",		Qbin|CHDIR,	0,			0700,
	"boot",		Qboot,		0,			0700,
	"dev",		Qdev|CHDIR,	0,			0700,
	"env",		Qenv|CHDIR,	0,			0700,
	"proc",		Qproc|CHDIR,	0,			0700,
	"bin",		{Qbin|CHDIR},	0,			0700,
	"boot",		{Qboot},	0,			0700,
	"dev",		{Qdev|CHDIR},	0,			0700,
	"env",		{Qenv|CHDIR},	0,			0700,
	"proc",		{Qproc|CHDIR},	0,			0700,
};

#define	NROOT	(sizeof rootdir/sizeof(Dirtab))


@@ 68,7 68,7 @@ rootopen(Chan *c, int omode)
void	 
rootcreate(Chan *c, char *name, int omode, ulong perm)
{
	error(0, Eperm);
	error(Eperm);
}

/*


@@ 85,7 85,7 @@ long
rootread(Chan *c, void *buf, long n)
{

	switch(c->qid & ~CHDIR){
	switch(c->qid.path & ~CHDIR){
	case Qdir:
		return devdirread(c, buf, n, rootdir, NROOT, devgen);



@@ 100,41 100,24 @@ rootread(Chan *c, void *buf, long n)
	case Qdev:
		return 0;
	}
	error(0, Egreg);
	error(Egreg);
	return 0;
}

long	 
rootwrite(Chan *c, void *buf, long n)
{
	error(0, Egreg);
	error(Egreg);
}

void	 
rootremove(Chan *c)
{
	error(0, Eperm);
	error(Eperm);
}

void	 
rootwstat(Chan *c, char *dp)
{
	error(0, Eperm);
}

void
rootuserstr(Error *e, char *buf)
{
	consuserstr(e, buf);
}

#include "errstr.h"

void	 
rooterrstr(Error *e, char *buf)
{
	if(e->code<0 || e->code>=sizeof errstrtab/sizeof(char*))
		strcpy(buf, "no such error");
	else
		strcpy(buf, errstrtab[e->code]);
	error(Eperm);
}

M port/devsrv.c => port/devsrv.c +17 -31
@@ 45,7 45,7 @@ srvalloc(int mode){
	e = calloc(1, sizeof(Entry));
	e->dir.atime = e->dir.mtime = seconds();
	lock(&qidlock);	/* for qid allocation */
	e->dir.qid = mode | nextqid++;
	e->dir.qid = (Qid){mode|nextqid++, 0};
	unlock(&qidlock);
	return e;
}


@@ 97,9 97,7 @@ srvwalk(Chan *c, char *name)
		unlock(dir);
	}
	if(e==0){
		u->error.code = Enonexist;
		u->error.type = 0;
		u->error.dev = 0;
		strncpy(u->error, errstrtab[Enonexist], NAMELEN);
		return 0;
	}
	c->qid = e->dir.qid;


@@ 122,22 120,22 @@ srvopen(Chan *c, int omode)
	Entry *e;
	Chan *f;

	if(c->qid & CHDIR){
	if(c->qid.path & CHDIR){
		if(omode != OREAD)
			error(0, Eisdir);
			error(Eisdir);
		c->mode = omode;
		c->flag |= COPEN;
		c->offset = 0;
		return c;
	}
	if((e=c->aux) == 0)
		error(0, Egreg);
		error(Egreg);
	if((f=e->chan) == 0)
		error(0, Eshutdown);
		error(Eshutdown);
	if(omode & OTRUNC)
		error(0, Eperm);
		error(Eperm);
	if(omode!=f->mode && f->mode!=ORDWR)
		error(0, Eperm);
		error(Eperm);
	close(c);
	incref(f);
	return f;


@@ 157,12 155,12 @@ srvcreate(Chan *c, char *name, int omode, ulong perm)
	}
	for(e=parent->entries; e; e=e->next)
		if(strcmp(name, e->dir.name) == 0)
			error(0, Einuse);
			error(Einuse);
	e = srvalloc(perm & CHDIR);
	e->parent = parent;
	strcpy(e->dir.name, name);
	e->dir.mode = perm & parent->dir.mode;
	e->dir.gid = parent->dir.gid;
	strcpy(e->dir.gid, parent->dir.gid);
	if(e->next = parent->entries)	/* assign = */
		e->next->back = &e->next;
	e->back = &parent->entries;


@@ 183,7 181,7 @@ srvremove(Chan *c)

	e = c->aux;
	if(e->parent == 0)
		error(0, Eperm);
		error(Eperm);
	lock(e->parent);
	if(waserror()){
		unlock(e->parent);


@@ 191,10 189,10 @@ srvremove(Chan *c)
	}
	if(e->dir.mode & CHDIR){
		if (e->entries != 0)
			error(0, Eperm);
			error(Eperm);
	}else{
		if(e->chan == 0)
			error(0, Eshutdown);
			error(Eshutdown);
		close(e->chan);
	}
	if(*e->back = e->next)	/* assign = */


@@ 207,7 205,7 @@ srvremove(Chan *c)
void
srvwstat(Chan *c, char *dp)
{
	error(0, Egreg);
	error(Egreg);
}

void


@@ 244,7 242,7 @@ srvread(Chan *c, void *va, long n)
	if(n <= 0)
		return 0;
	if(offset%DIRLEN || n%DIRLEN)
		error(0, Ebaddirread);
		error(Ebaddirread);
	lock(dir);
	for(e=dir->entries; e; e=e->next)
		if(offset <= 0){


@@ 274,9 272,9 @@ srvwrite(Chan *c, void *va, long n)
		nexterror();
	}
	if(e->chan)
		error(0, Egreg);
		error(Egreg);
	if(n >= sizeof buf)
		error(0, Egreg);
		error(Egreg);
	memcpy(buf, va, n);	/* so we can NUL-terminate */
	buf[n] = 0;
	fd = strtoul(buf, 0, 0);


@@ 287,15 285,3 @@ srvwrite(Chan *c, void *va, long n)
	poperror();
	return n;
}

void
srverrstr(Error *e, char *buf)
{
	rooterrstr(e, buf);
}

void
srvuserstr(Error *e, char *buf)
{
	consuserstr(e, buf);
}

M port/fault.c => port/fault.c +4 -5
@@ 94,7 94,7 @@ fault(Ureg *ur, int user, int code)
			pg = newpage(1, o, addr);
			qlock(o->chan);
			if(waserror()){
				print("demand load i/o error %d\n", u->error.code);
				print("demand load i/o error %s\n", u->error);
				qunlock(o->chan);
				pg->o = 0;
				pg->ref--;


@@ 103,7 103,7 @@ fault(Ureg *ur, int user, int code)
			o->chan->offset = (addr-o->va) + o->minca;
			l = (char*)(pg->pa|KZERO);
			if((*devtab[o->chan->type].read)(o->chan, l, n) != n)
				error(0, Eioload);
				error(Eioload);
			qunlock(o->chan);
			poperror();
			/* BUG: if was first page of bss, move to data */


@@ 143,7 143,6 @@ fault(Ureg *ur, int user, int code)
			 * Add to mod list
			 */
			pte = newmod(o);
o->nmod++;
			pte->proc = u->p;
			pte->page = opte->page;
			pte->page->ref++;


@@ 219,7 218,7 @@ validaddr(ulong addr, ulong len, int write)
    Err:
		pprint("invalid address in sys call pc %lux sp %lux\n", ((Ureg*)UREGADDR)->pc, ((Ureg*)UREGADDR)->sp);
		postnote(u->p, 1, "sys: bad address", NDebug);
		error(0, Ebadarg);
		error(Ebadarg);
	}
    Again:
	s = seg(u->p, addr);


@@ 242,7 241,7 @@ evenaddr(ulong addr)
{
	if(addr & 3){
		postnote(u->p, 1, "sys: odd address", NDebug);
		error(0, Ebadarg);
		error(Ebadarg);
	}
}


M port/fcall.c => port/fcall.c +107 -104
@@ 1,12 1,12 @@
#include	<u.h>
#include	"lib.h"
#include	"fcall.h"
#include	<libc.h>
#include	<fcall.h>

#define	CHAR(x)		*p++ = f->x
#define	SHORT(x)	p[0] = f->x; p[1] = f->x>>8; p += 2
#define	LONG(x)		p[0] = f->x; p[1] = f->x>>8; p[2] = f->x>>16; p[3] = f->x>>24; p += 4
#define	VLONG(x)	p[0] = f->x; p[1] = f->x>>8; p[2] = f->x>>16; p[3] = f->x>>24;\
			p[4] = 0; p[5] = 0; p[6] = 0; p[7] = 0; p += 8
				p[4] = 0; p[5] = 0; p[6] = 0; p[7] = 0; p += 8
#define	STRING(x,n)	memcpy(p, f->x, n); p += n

int


@@ 16,24 16,28 @@ convS2M(Fcall *f, char *ap)

	p = (uchar*)ap;
	CHAR(type);
	SHORT(tag);
	switch(f->type)
	{
	default:
		print("bad type: %d\n", f->type);
		print("fcall: bad type: %d\n", f->type);
		return 0;

	case Tnop:
	case Rnop:
		break;

	case Tsession:
		CHAR(lang);
		break;

	case Tflush:
		SHORT(oldtag);
		break;

	case Tattach:
		SHORT(fid);
		STRING(uname, sizeof(f->uname));
		STRING(aname, sizeof(f->aname));
		STRING(auth, sizeof(f->auth));
		break;

	case Tclone:


@@ 42,7 46,6 @@ convS2M(Fcall *f, char *ap)
		break;

	case Twalk:
	case Tremove:
		SHORT(fid);
		STRING(name, sizeof(f->name));
		break;


@@ 59,108 62,106 @@ convS2M(Fcall *f, char *ap)
		CHAR(mode);
		break;

	case Toread:
	case Tread:
		SHORT(fid);
		VLONG(offset);
		SHORT(count);
		break;

	case Towrite:
		SHORT(fid);
		VLONG(offset);
		SHORT(count);
		STRING(data, f->count);
		break;

	case Twrite:
		SHORT(fid);
		VLONG(offset);
		SHORT(count);
		p++;
		p++;	/* pad(1) */
		STRING(data, f->count);
		break;

	case Tclunk:
	case Tstat:
		SHORT(fid);
		break;

	case Twstat:
	case Tremove:
		SHORT(fid);
		STRING(stat, sizeof(f->stat));
		break;

	case Terrstr:
	case Tstat:
		SHORT(fid);
		SHORT(err);
		break;

	case Tuserstr:
	case Twstat:
		SHORT(fid);
		SHORT(uid);
		STRING(stat, sizeof(f->stat));
		break;
/*
 */
	case Rnop:
		break;

	case Rsession:
		SHORT(err);
		break;

	case Rerror:
		STRING(ename, sizeof(f->ename));
		break;

	case Rflush:
		break;

	case Rattach:
		SHORT(fid);
		LONG(qid.path);
		LONG(qid.vers);
		break;

	case Rclone:
	case Rclunk:
	case Rremove:
	case Rwstat:
		SHORT(fid);
		SHORT(err);
		break;

	case Rwalk:
	case Rattach:
		SHORT(fid);
		LONG(qid.path);
		LONG(qid.vers);
		break;

	case Ropen:
	case Rcreate:
		SHORT(fid);
		SHORT(err);
		LONG(qid);
		LONG(qid.path);
		LONG(qid.vers);
		break;

	case Roread:
	case Rcreate:
		SHORT(fid);
		SHORT(err);
		SHORT(count);
		STRING(data, f->count);
		LONG(qid.path);
		LONG(qid.vers);
		break;

	case Rread:
		SHORT(fid);
		SHORT(err);
		SHORT(count);
		p++;
		p++;	/* pad(1) */
		STRING(data, f->count);
		break;

	case Rowrite:
	case Rwrite:
		SHORT(fid);
		SHORT(err);
		SHORT(count);
		break;

	case Rstat:
	case Rclunk:
		SHORT(fid);
		SHORT(err);
		STRING(stat, sizeof(f->stat));
		break;

	case Rerrstr:
	case Rremove:
		SHORT(fid);
		SHORT(err);
		STRING(ename, sizeof(f->ename));
		break;

	case Ruserstr:
	case Rstat:
		SHORT(fid);
		STRING(stat, sizeof(f->stat));
		break;

	case Rwstat:
		SHORT(fid);
		SHORT(err);
		STRING(uname, sizeof(f->uname));
		break;
	}
	return p - (uchar*)ap;


@@ 173,14 174,14 @@ convD2M(Dir *f, char *ap)

	p = (uchar*)ap;
	STRING(name, sizeof(f->name));
	LONG(qid);
	p += 4;
	STRING(uid, sizeof(f->uid));
	STRING(gid, sizeof(f->gid));
	LONG(qid.path);
	LONG(qid.vers);
	LONG(mode);
	LONG(atime);
	LONG(mtime);
	VLONG(length);
	SHORT(uid);
	SHORT(gid);
	SHORT(type);
	SHORT(dev);
	return p - (uchar*)ap;


@@ 195,9 196,9 @@ convD2M(Dir *f, char *ap)
#define	CHAR(x)		f->x = *p++
#define	SHORT(x)	f->x = (p[0] | (p[1]<<8)); p += 2
#define	LONG(x)		f->x = (p[0] | (p[1]<<8) |\
			(p[2]<<16) | (p[3]<<24)); p += 4
				(p[2]<<16) | (p[3]<<24)); p += 4
#define	VLONG(x)	f->x = (p[0] | (p[1]<<8) |\
			(p[2]<<16) | (p[3]<<24)); p += 8
				(p[2]<<16) | (p[3]<<24)); p += 8
#define	STRING(x,n)	memcpy(f->x, p, n); p += n

int


@@ 207,24 208,28 @@ convM2S(char *ap, Fcall *f, int n)

	p = (uchar*)ap;
	CHAR(type);
	SHORT(tag);
	switch(f->type)
	{
	default:
		print("bad type: %d\n", f->type);
		print("fcall: bad type: %d\n", f->type);
		return 0;

	case Tnop:
	case Rnop:
		break;

	case Tsession:
		CHAR(lang);
		break;

	case Tflush:
		SHORT(oldtag);
		break;

	case Tattach:
		SHORT(fid);
		STRING(uname, sizeof(f->uname));
		STRING(aname, sizeof(f->aname));
		STRING(auth, sizeof(f->auth));
		break;

	case Tclone:


@@ 233,7 238,6 @@ convM2S(char *ap, Fcall *f, int n)
		break;

	case Twalk:
	case Tremove:
		SHORT(fid);
		STRING(name, sizeof(f->name));
		break;


@@ 250,29 254,28 @@ convM2S(char *ap, Fcall *f, int n)
		CHAR(mode);
		break;

	case Toread:
	case Tread:
		SHORT(fid);
		VLONG(offset);
		SHORT(count);
		break;

	case Towrite:
	case Twrite:
		SHORT(fid);
		VLONG(offset);
		SHORT(count);
		p++;	/* pad(1) */
		f->data = (char*)p; p += f->count;
		break;

	case Twrite:
	case Tclunk:
		SHORT(fid);
		break;

	case Tremove:
		SHORT(fid);
		VLONG(offset);
		SHORT(count);
		p++;
		f->data = (char*)p; p += f->count;
		break;

	case Tclunk:
	case Tstat:
		SHORT(fid);
		break;


@@ 281,76 284,76 @@ convM2S(char *ap, Fcall *f, int n)
		SHORT(fid);
		STRING(stat, sizeof(f->stat));
		break;
/*
 */
	case Rnop:
		break;

	case Terrstr:
		SHORT(fid);
		SHORT(err);
	case Rsession:
		break;

	case Tuserstr:
		SHORT(fid);
		SHORT(uid);
	case Rerror:
		STRING(ename, sizeof(f->ename));
		break;

	case Rsession:
		SHORT(err);
	case Rflush:
		break;

	case Rattach:
		SHORT(fid);
		LONG(qid.path);
		LONG(qid.vers);
		break;

	case Rclone:
	case Rclunk:
	case Rremove:
	case Rwstat:
		SHORT(fid);
		SHORT(err);
		break;

	case Rwalk:
	case Rattach:
		SHORT(fid);
		LONG(qid.path);
		LONG(qid.vers);
		break;

	case Ropen:
	case Rcreate:
		SHORT(fid);
		SHORT(err);
		LONG(qid);
		LONG(qid.path);
		LONG(qid.vers);
		break;

	case Roread:
	case Rcreate:
		SHORT(fid);
		SHORT(err);
		SHORT(count);
		f->data = (char*)p; p += f->count;
		LONG(qid.path);
		LONG(qid.vers);
		break;

	case Rread:
		SHORT(fid);
		SHORT(err);
		SHORT(count);
		p++;
		p++;	/* pad(1) */
		f->data = (char*)p; p += f->count;
		break;

	case Rowrite:
	case Rwrite:
		SHORT(fid);
		SHORT(err);
		SHORT(count);
		break;

	case Rstat:
	case Rclunk:
		SHORT(fid);
		SHORT(err);
		STRING(stat, sizeof(f->stat));
		break;

	case Rerrstr:
	case Rremove:
		SHORT(fid);
		SHORT(err);
		STRING(ename, sizeof(f->ename));
		break;

	case Ruserstr:
	case Rstat:
		SHORT(fid);
		STRING(stat, sizeof(f->stat));
		break;

	case Rwstat:
		SHORT(fid);
		SHORT(err);
		STRING(uname, sizeof(f->uname));
		break;
	}
	if((uchar*)ap+n == p)


@@ 365,14 368,14 @@ convM2D(char *ap, Dir *f)

	p = (uchar*)ap;
	STRING(name, sizeof(f->name));
	LONG(qid);
	p += 4;
	STRING(uid, sizeof(f->uid));
	STRING(gid, sizeof(f->gid));
	LONG(qid.path);
	LONG(qid.vers);
	LONG(mode);
	LONG(atime);
	LONG(mtime);
	VLONG(length);
	SHORT(uid);
	SHORT(gid);
	SHORT(type);
	SHORT(dev);
	return p - (uchar*)ap;

M port/lib.h => port/lib.h +12 -12
@@ 74,30 74,30 @@ extern	long	end;
#define	OCEXEC	32	/* or'ed in, close on exec */
#define	ORCLOSE	64	/* or'ed in, remove on close */

typedef struct Error	Error;
typedef struct Qid	Qid;
typedef struct Dir	Dir;
typedef struct Waitmsg	Waitmsg;

struct Error
#define	ERRLEN	64
#define	DIRLEN	116
#define	NAMELEN	28

struct Qid
{
	int	type;
	int	dev;
	int	code;
	ulong	path;
	ulong	vers;
};

#define	ERRLEN	64
#define	DIRLEN	64
#define	NAMELEN	28
struct Dir
{
	char	name[NAMELEN];
	long	qid;
	long	mode;
	char	uid[NAMELEN];
	char	gid[NAMELEN];
	Qid	qid;
	ulong	mode;
	long	atime;
	long	mtime;
	Length;
	short	uid;
	short	gid;
	short	type;
	short	dev;
};

M port/page.c => port/page.c +6 -11
@@ 294,11 294,11 @@ lookorig(ulong va, ulong npte, int flag, Chan *c)
	ulong i;

	for(o=origalloc.arena,i=0; i<conf.norig; i++,o++)
		if(o->npage && o->qid==c->qid && o->va==va){
		if(o->npage && o->qid.path==c->qid.path && o->va==va){
			lock(o);
			if(o->npage && o->qid==c->qid)
			if(o->npage && eqqid(o->qid, c->qid))
			if(o->va==va && o->npte==npte && o->flag==flag)
			if(o->mchan==c->mchan && o->mqid==c->mqid && o->type==c->type){
			if(o->mchan==c->mchan && o->type==c->type && eqqid(o->mqid, c->mqid)){
				if(o->chan == 0){
					o->chan = c;
					incref(c);


@@ 329,7 329,6 @@ loop:
		o->nproc = 1;
		o->npage = 0;
		o->chan = c;
o->nmod = 0;
		if(c){
			o->type = c->type;
			o->qid = c->qid;


@@ 338,8 337,8 @@ o->nmod = 0;
			incref(c);
		}else{
			o->type = -1;
			o->qid = -1;
			o->mqid = -1;
			o->qid = (Qid){~0, ~0};
			o->mqid = (Qid){~0, ~0};
			o->mchan = 0;
		}
		if(u && u->p && waserror()){


@@ 401,8 400,6 @@ loop:
	}
	unlock(&modalloc);
	print("no mods\n");
DEBUG();
panic("mods %lux %d %d", o->va, o->npte, o->nmod);
	if(u == 0)
		panic("newmod");
	u->p->state = Wakeme;


@@ 429,7 426,6 @@ forkmod(Seg *old, Seg *new, Proc *p)
if(pte->page==0) panic("forkmod zero page");
if(pte->proc != u->p) panic("forkmod wrong page");
		npte = newmod(o);
o->nmod++;
		npte->proc = p;
		npte->page = pte->page;
		pte->page->ref++;


@@ 490,7 486,6 @@ freesegs(int save)
				}
				pg->ref--;
				o->npage--;
o->nmod--;
				old = (PTEA*)pte;
				pte = pte->nextva;
				lock(&modalloc);


@@ 653,7 648,7 @@ growpte(Orig *o, ulong n)
	unlock(&ptealloc);
	unlock(o);
	if(u && u->p)
		error(0, Enovmem);
		error(Enovmem);
	panic("growpte fails %d %lux %d\n", n, o->va, o->npte);
}


M port/pgrp.c => port/pgrp.c +2 -2
@@ 59,9 59,9 @@ pgrpnote(Pgrp *pg, char *a, long n, int flag)
	char buf[ERRLEN];

	if(n >= ERRLEN-1)
		error(0, Etoobig);
		error(Etoobig);
	if(n>=4 && strncmp(a, "sys:", 4)==0)
		error(0, Ebadarg);
		error(Ebadarg);
	memcpy(buf, a, n);
	buf[n] = 0;
	p = proctab(0);

M port/proc.c => port/proc.c +3 -3
@@ 250,7 250,7 @@ sleep(Rendez *r, int (*f)(void*), void *arg)
	sched();
	if(u->p->wokeup){
		u->p->wokeup = 0;
		error(0, Eintr);
		error(Eintr);
	}
}



@@ 265,7 265,7 @@ tsleep(Rendez *r, int (*f)(void*), void *arg, int ms)
	cancel(a);
	if(u->p->wokeup){
		u->p->wokeup = 0;
		error(0, Eintr);
		error(Eintr);
	}
}



@@ 540,7 540,7 @@ again:
	while(canlock(&p->wait.use)){
		if(p->nchild == 0){
			qunlock(&p->wait);
			error(0, Enochild);
			error(Enochild);
		}
		p->state = Inwait;
		qunlock(&p->wait);

M port/stasync.c => port/stasync.c +1 -1
@@ 112,7 112,7 @@ asyncopen(Queue *q, Stream *s)
		qunlock(ap);
	}
	if(ap == &async[conf.nasync])
		error(0, Enoasync);
		error(Enoasync);
	q->ptr = q->other->ptr = ap;

	ap->inuse = 1;

M port/stream.c => port/stream.c +26 -24
@@ 239,7 239,7 @@ allocq(Qinfo *qi)

	if(q == &qlist[conf.nqueue]){
		print("no more queues\n");
		error(0, Enoqueue);
		error(Enoqueue);
	}

	q->flag = QINUSE;


@@ 335,7 335,7 @@ popq(Stream *s)
	Queue *q;

	if(s->procq->next == WR(s->devq))
		error(0, Ebadld);
		error(Ebadld);
	q = s->procq->next;
	if(q->info->close)
		(*q->info->close)(RD(q));


@@ 541,7 541,7 @@ nullput(Queue *q, Block *bp)
		freeb(bp);
	else {
		freeb(bp);
		error(0, Ehungup);
		error(Ehungup);
	}
}



@@ 554,11 554,11 @@ qinfofind(char *name)
	Qinfo *qi;

	if(name == 0)
		error(0, Ebadld);
		error(Ebadld);
	for(qi = lds; qi; qi = qi->next)
		if(strcmp(qi->name, name)==0)
			return qi;
	error(0, Ebadld);
	error(Ebadld);
}

/*


@@ 608,8 608,8 @@ streamparse(char *name, Block *bp)
 *  the per stream directory structure
 */
Dirtab streamdir[]={
	"data",		Sdataqid,	0,			0600,
	"ctl",		Sctlqid,	0,			0600,
	"data",		{Sdataqid},	0,			0600,
	"ctl",		{Sctlqid},	0,			0600,
};

/*


@@ 633,7 633,7 @@ streamgen(Chan *c, Dirtab *tab, int ntab, int s, Dir *dp)
	else
		return -1;

	devdir(c, STREAMQID(STREAMID(c->qid),tab->qid), tab->name, tab->length,
	devdir(c, (Qid){STREAMQID(STREAMID(c->qid.path),tab->qid.path), 0}, tab->name, tab->length,
		tab->perm, dp);
	return 1;
}


@@ 661,7 661,7 @@ streamnew(ushort type, ushort dev, ushort id, Qinfo *qi, int noopen)
	}
	if(s == &slist[conf.nstream]){
		print("no more streams\n");
		error(0, Enostream);
		error(Enostream);
	}
	if(waserror()){
		qunlock(s);


@@ 716,11 716,11 @@ streamopen(Chan *c, Qinfo *qi)
	 */
	for(s = slist; s < &slist[conf.nstream]; s++) {
		if(s->inuse && s->type == c->type && s->dev == c->dev
		   && s->id == STREAMID(c->qid)){
		   && s->id == STREAMID(c->qid.path)){
			qlock(s);
			if(s->inuse && s->type == c->type
			&& s->dev == c->dev
		 	&& s->id == STREAMID(c->qid)){
		 	&& s->id == STREAMID(c->qid.path)){
				s->inuse++;
				s->opens++;
				c->stream = s;


@@ 734,7 734,7 @@ streamopen(Chan *c, Qinfo *qi)
	/*
	 *  create a new stream
	 */
	c->stream = streamnew(c->type, c->dev, STREAMID(c->qid), qi, 0);
	c->stream = streamnew(c->type, c->dev, STREAMID(c->qid.path), qi, 0);
}

/*


@@ 792,11 792,12 @@ streamexit(Stream *s, int locked)
 *  On the last close of a stream, for each queue on the
 *  stream release its blocks and call its close routine.
 */
void
int
streamclose1(Stream *s)
{
	Queue *q, *nq;
	Block *bp;
	int rv;

	/*
	 *  decrement the reference count


@@ 829,23 830,24 @@ streamclose1(Stream *s)
			flushq(q);
		}
	}
	s->opens--;
	rv = --(s->opens);

	/*
	 *  leave it and free it
	 */
	streamexit(s, 1);
	qunlock(s);
	return rv;
}
void
int
streamclose(Chan *c)
{
	/*
	 *  if no stream, ignore it
	 */
	if(!c->stream)
		return;
	streamclose1(c->stream);
		return 1;
	return streamclose1(c->stream);
}

/*


@@ 918,11 920,11 @@ streamctlread(Chan *c, void *vbuf, long n)
	Stream *s;

	s = c->stream;
	if(STREAMTYPE(c->qid) == Sctlqid){
	if(STREAMTYPE(c->qid.path) == Sctlqid){
		sprint(num, "%d", s->id);
		return stringread(c, buf, n, num);
	} else {
		if(CHDIR & c->qid)
		if(CHDIR & c->qid.path)
			return devdirread(c, vbuf, n, 0, 0, streamgen);
		else
			panic("streamctlread");


@@ 953,7 955,7 @@ streamread(Chan *c, void *vbuf, long n)
	int left, i;
	uchar *buf = vbuf;

	if(STREAMTYPE(c->qid) != Sdataqid)
	if(STREAMTYPE(c->qid.path) != Sdataqid)
		return streamctlread(c, vbuf, n);

	/*


@@ 978,7 980,7 @@ streamread(Chan *c, void *vbuf, long n)
				if(s->hread++ < 3)
					break;
				else
					error(0, Ehungup);
					error(Ehungup);
			}
			sleep(&q->r, &isinput, (void *)q);
			continue;


@@ 1023,7 1025,7 @@ streamctlwrite(Chan *c, void *a, long n)
	Block *bp;
	Stream *s;

	if(STREAMTYPE(c->qid) != Sctlqid)
	if(STREAMTYPE(c->qid.path) != Sctlqid)
		panic("streamctlwrite %lux", c->qid);
	s = c->stream;



@@ 1095,7 1097,7 @@ streamwrite(Chan *c, void *a, long n, int docopy)
	/*
	 *  decode the qid
	 */
	if(STREAMTYPE(c->qid) != Sdataqid)
	if(STREAMTYPE(c->qid.path) != Sdataqid)
		return streamctlwrite(c, a, n);

	/*


@@ 1103,7 1105,7 @@ streamwrite(Chan *c, void *a, long n, int docopy)
	 */
	q = s->procq;
	if(q->other->flag & QHUNGUP)
		error(0, Ehungup);
		error(Ehungup);

	if(!docopy && GLOBAL(a)){
		/*

M port/sturp.c => port/sturp.c +1 -1
@@ 156,7 156,7 @@ urpopen(Queue *q, Stream *s)
	if(up == &urp[conf.nurp]){
		q->ptr = 0;
		WR(q)->ptr = 0;
		error(0, Egreg);
		error(Egreg);
	}

	q->ptr = q->other->ptr = up;

M port/sysfile.c => port/sysfile.c +26 -35
@@ 21,7 21,7 @@ newfd(void)
				u->maxfd = i;
			return i;
		}
	error(0, Enofd);
	error(Enofd);
}

Chan*


@@ 30,12 30,12 @@ fdtochan(int fd, int mode)
	Chan *c;

	if(fd<0 || NFD<=fd || (c=u->fd[fd])==0)
		error(0, Ebadfd);
		error(Ebadfd);
	if(mode<0 || c->mode==ORDWR)
		return c;
	if((mode&OTRUNC) && c->mode==OREAD)
    err:
		error(0, Ebadusefd);
		error(Ebadusefd);
	if((mode&~OTRUNC) != c->mode)
		goto err;
	return c;


@@ 46,7 46,7 @@ openmode(ulong o)
{
	if(o >= (OTRUNC|OCEXEC|ORCLOSE|OEXEC))
    Err:
		error(0, Ebadarg);
		error(Ebadarg);
	o &= ~(OTRUNC|OCEXEC|ORCLOSE);
	if(o > OEXEC)
		goto Err;


@@ 227,12 227,12 @@ sysread(ulong *arg)
		nexterror();
	}
	n = arg[2];
	if(c->qid&CHDIR){
	if(c->qid.path & CHDIR){
		n -= n%DIRLEN;
		if(c->offset%DIRLEN || n==0)
			error(0, Ebaddirread);
			error(Ebaddirread);
	}
	if((c->qid&CHDIR) && (c->flag&CMOUNT))
	if((c->qid.path&CHDIR) && (c->flag&CMOUNT))
		n = unionread(c, (void*)arg[1], n);
	else
		n = (*devtab[c->type].read)(c, (void*)arg[1], n);


@@ 254,8 254,8 @@ syswrite(ulong *arg)
		qunlock(c);
		nexterror();
	}
	if(c->qid & CHDIR)
		error(0, Eisdir);
	if(c->qid.path & CHDIR)
		error(Eisdir);
	n = (*devtab[c->type].write)(c, (void*)arg[1], arg[2]);
	c->offset += n;
	qunlock(c);


@@ 271,8 271,8 @@ sysseek(ulong *arg)
	long off;

	c = fdtochan(arg[0], -1);
	if(c->qid & CHDIR)
		error(0, Eisdir);
	if(c->qid.path & CHDIR)
		error(Eisdir);
	qlock(c);
	if(waserror()){
		qunlock(c);


@@ 365,13 365,15 @@ bindmount(ulong *arg, int ismount)
	struct{
		Chan	*chan;
		char	*spec;
		char	*auth;
	}bogus;

	flag = arg[2];
	if(flag>MMASK || (flag&MORDER)==(MBEFORE|MAFTER))
		error(0, Ebadarg);
		error(Ebadarg);
	if(ismount){
		bogus.chan = fdtochan(arg[0], 2);
		validaddr(arg[3], 1, 0);
		p = (char*)arg[3];
		t = BY2PG-((ulong)p&(BY2PG-1));
		while(vmemchr(p, 0, t) == 0){


@@ 379,6 381,14 @@ bindmount(ulong *arg, int ismount)
			t = BY2PG;
		}
		bogus.spec = (char*)arg[3];
		validaddr(arg[4], 1, 0);
		p = (char*)arg[4];
		t = BY2PG-((ulong)p&(BY2PG-1));
		while(vmemchr(p, 0, t) == 0){
			p += t;
			t = BY2PG;
		}
		bogus.auth = (char*)arg[4];
		ret = devno('M', 0);
		c0 = (*devtab[ret].attach)((char*)&bogus);
	}else{


@@ 395,10 405,10 @@ bindmount(ulong *arg, int ismount)
		close(c1);
		nexterror();
	}
	if((c0->qid^c1->qid) & CHDIR)
		error(0, Ebadmount);
	if(flag && !(c0->qid&CHDIR))
		error(0, Ebadmount);
	if((c0->qid.path^c1->qid.path) & CHDIR)
		error(Ebadmount);
	if(flag && !(c0->qid.path&CHDIR))
		error(Ebadmount);
	ret = mount(c0, c1, flag);
	close(c0);
	close(c1);


@@ 436,25 446,6 @@ syscreate(ulong *arg)
}

long
sysuserstr(ulong *arg)
{
	Error err;
	char buf[NAMELEN];

	validaddr(arg[0], sizeof(Error), 0);
	validaddr(arg[1], NAMELEN, 1);
	err = *(Error*)arg[0];
	err.type = devno(err.type, 1);
	if(err.type == -1)
		strcpy((char*)arg[1], "*gok*");
	else{
		(*devtab[err.type].userstr)(&err, buf);
		memcpy((char*)arg[1], buf, sizeof buf);
	}
	return 0;
}

long
sysremove(ulong *arg)
{
	Chan *c;

M port/sysproc.c => port/sysproc.c +9 -31
@@ 183,7 183,7 @@ sysexec(ulong *arg)
	n = (*devtab[tc->type].read)(tc, &exec, sizeof(Exec));
	if(n < 2)
    Err:
		error(0, Ebadexec);
		error(Ebadexec);
	if(n==sizeof(Exec) && exec.magic==V_MAGIC){
		if((exec.text&KZERO)
		|| (ulong)exec.entry < UTZERO+sizeof(Exec)


@@ 223,7 223,7 @@ sysexec(ulong *arg)
	d = (t + exec.data) & ~(BY2PG-1);
	b = (t + exec.data + exec.bss + (BY2PG-1)) & ~(BY2PG-1);
	if((t|d|b) & KZERO)
		error(0, Ebadexec);
		error(Ebadexec);

	/*
	 * Args: pass 1: count


@@ 446,41 446,19 @@ syswait(ulong *arg)
}

long
syslasterr(ulong *arg)
sysdeath(ulong *arg)
{
	Error *e;

	validaddr(arg[0], sizeof u->error, 1);
	evenaddr(arg[0]);
	e = (Error *)arg[0];
	memcpy(e, &u->error, sizeof u->error);
	memset(&u->error, 0, sizeof u->error);
	e->type = devchar[e->type];
	return 0;
	pprint("deprecated system call");
	pexit("Suicide", 0);
}

long
syserrstr(ulong *arg)
{
	Error *e, err;
	char buf[ERRLEN];

	validaddr(arg[1], ERRLEN, 1);
	e = &err;
	if(arg[0]){
		validaddr(arg[0], sizeof u->error, 0);
		memcpy(e, (Error*)arg[0], sizeof(Error));
		e->type = devno(e->type, 1);
		if(e->type == -1){
			e->type = 0;
			e->code = Egreg+1;	/* -> "no such error" */
		}
	}else{
		memcpy(e, &u->error, sizeof(Error));
		memset(&u->error, 0, sizeof(Error));
	}
	(*devtab[e->type].errstr)(e, buf);
	memcpy((char*)arg[1], buf, sizeof buf);
	validaddr(arg[0], ERRLEN, 1);
	memcpy((char*)arg[0], u->error, ERRLEN);
	return 0;
}



@@ 515,7 493,7 @@ long
sysnoted(ulong *arg)
{
	if(u->notified == 0)
		error(0, Egreg);
		error(Egreg);
	return 0;
}



@@ 526,6 504,6 @@ long
sysbrk_(ulong *arg)
{
	if(segaddr(&u->p->seg[BSEG], u->p->seg[BSEG].minva, arg[0]) == 0)
		error(0, Esegaddr);
		error(Esegaddr);
	return 0;
}

M power/boot.c => power/boot.c +17 -10
@@ 1,6 1,5 @@
#include <u.h>
#include <libc.h>

#include <fcall.h>

#define DEFSYS "bitbootes"


@@ 175,6 174,7 @@ boot(int ask)
    Mesg:
	print("nop...");
	hdr.type = Tnop;
	hdr.tag = ~0;
	n = convS2M(&hdr, buf);
	if(write(fd, buf, n) != n){
		print("n = %d\n", n);


@@ 196,10 196,14 @@ boot(int ask)
		prerror("not Rnop");
		return;
	}
	if(hdr.tag != ~0){
		prerror("tag not ~0");
		return;
	}

	print("session...");
	hdr.type = Tsession;
	hdr.lang = 'v';
	hdr.tag = ~0;
	n = convS2M(&hdr, buf);
	if(write(fd, buf, n) != n){
		prerror("write session");


@@ 214,13 218,16 @@ boot(int ask)
		prerror("format session");
		return;
	}
	if(hdr.type != Rsession){
		prerror("not Rsession");
	if(hdr.tag != ~0){
		prerror("tag not ~0");
		return;
	}
	if(hdr.err){
		print("error %d;", hdr.err);
		prerror("remote error");
	if(hdr.type == Rerror){
		fprint(2, "boot: error %s\n", hdr.ename);
		return;
	}
	if(hdr.type != Rsession){
		prerror("not Rsession");
		return;
	}



@@ 244,7 251,7 @@ boot(int ask)
	print("mount...");
	if(bind("/", "/", MREPL) < 0)
		error("bind");
	if(mount(fd, "/", MAFTER|MCREATE, "") < 0)
	if(mount(fd, "/", MAFTER|MCREATE, "", "") < 0)
		error("mount");
	print("success\n");
	close(fd);


@@ 264,7 271,7 @@ prerror(char *s)
{
	char buf[64];

	errstr(0, buf);
	errstr(buf);
	fprint(2, "boot: %s: %s\n", s, buf);
}



@@ 276,7 283,7 @@ error(char *s)
{
	char buf[64];

	errstr(0, buf);
	errstr(buf);
	fprint(2, "boot: %s: %s\n", s, buf);
	exits(0);
}

M power/boot.h => power/boot.h +2042 -2082
@@ 1,8 1,8 @@
ulong bootcode[]={
	0x000000407,
	0x000004498,
	0x0000005d8,
	0x0000010d0,
	0x0000043e8,
	0x0000005e8,
	0x000001100,
	0x000000000,
	0x000001020,
	0x000000000,


@@ 16,7 16,7 @@ ulong bootcode[]={
	0x0afa10004,
	0x00c000415,
	0x0afa20008,
	0x00c000760,
	0x00c00077b,
	0x0afa10004,
	0x008000411,
	0x000000027,


@@ 25,34 25,34 @@ ulong bootcode[]={
	0x0afa00014,
	0x023c2823d,
	0x0afa20004,
	0x00c000ed5,
	0x00c000885,
	0x0afa00008,
	0x023c38245,
	0x0afa30004,
	0x020020001,
	0x00c000ed5,
	0x00c000885,
	0x0afa20008,
	0x023c3824d,
	0x0afa30004,
	0x020020001,
	0x00c000ed5,
	0x00c000885,
	0x0afa20008,
	0x023c28255,
	0x0afa20004,
	0x020040001,
	0x0afa40008,
	0x0200201b6,
	0x00c000ec1,
	0x00c000871,
	0x0afa2000c,
	0x004210004,
	0x0afa10018,
	0x023c38260,
	0x00c0006ab,
	0x00c0006c5,
	0x0afa30004,
	0x08fa40024,
	0x000000027,
	0x08c840000,
	0x00c000857,
	0x00c00084a,
	0x0afa40004,
	0x0afa10010,
	0x08fa40018,


@@ 64,15 64,15 @@ ulong bootcode[]={
	0x000000027,
	0x0afa30008,
	0x08fa40010,
	0x00c000edf,
	0x00c00088f,
	0x0afa4000c,
	0x01c200004,
	0x000000027,
	0x023c28268,
	0x00c0006ab,
	0x00c0006c5,
	0x0afa20004,
	0x08fa30018,
	0x00c000ebc,
	0x00c00086c,
	0x0afa30004,
	0x08fa70014,
	0x02009002d,


@@ 110,50 110,50 @@ ulong bootcode[]={
	0x023c3827a,
	0x038c20001,
	0x010400029,
	0x0afc38032,
	0x0afc3805a,
	0x038c20002,
	0x010400020,
	0x000000027,
	0x00c00049b,
	0x0afa70004,
	0x08fc58076,
	0x08fc58096,
	0x000000027,
	0x018a00003,
	0x000000027,
	0x00c000ebc,
	0x00c00086c,
	0x0afa50004,
	0x08fc28042,
	0x08fc28072,
	0x000000027,
	0x018400004,
	0x000000027,
	0x08fc38042,
	0x00c000ebc,
	0x08fc38072,
	0x00c00086c,
	0x0afa30004,
	0x08fc28046,
	0x08fc28076,
	0x000000027,
	0x018400004,
	0x000000027,
	0x08fc38046,
	0x00c000ebc,
	0x08fc38076,
	0x00c00086c,
	0x0afa30004,
	0x0afc08046,
	0x0afc08042,
	0x0afc08076,
	0x0afc08072,
	0x0afc08096,
	0x020030001,
	0x00c00049b,
	0x0afa30004,
	0x08fc58076,
	0x08fc58096,
	0x008000477,
	0x000000027,
	0x08ca30000,
	0x000000027,
	0x0afc38032,
	0x0afc3805a,
	0x08ca20004,
	0x008000473,
	0x0afc28002,
	0x08ca20000,
	0x008000473,
	0x0afc28032,
	0x0afc2805a,
	0x023bdffd8,
	0x0afbf0000,
	0x08fc58002,


@@ 164,14 164,14 @@ ulong bootcode[]={
	0x023c38282,
	0x0afa30004,
	0x0afa50008,
	0x023c3807a,
	0x023c3809a,
	0x0afa3000c,
	0x020020038,
	0x00c000702,
	0x00c00071b,
	0x0afa20010,
	0x023c5807a,
	0x023c5809a,
	0x0afc58002,
	0x00c0006c0,
	0x00c0006d9,
	0x0afa50004,
	0x01420000c,
	0x000000027,


@@ 180,7 180,7 @@ ulong bootcode[]={
	0x023c38289,
	0x0afa30008,
	0x08fc28002,
	0x00c0007b0,
	0x00c0007cb,
	0x0afa2000c,
	0x08fa20000,
	0x000000027,


@@ 189,40 189,43 @@ ulong bootcode[]={
	0x0afa1001c,
	0x08c250004,
	0x023c4829b,
	0x0afc58052,
	0x0afc5807a,
	0x0afa50004,
	0x00c0007ee,
	0x00c000808,
	0x0afa40008,
	0x014200167,
	0x014200182,
	0x020050002,
	0x023c382a6,
	0x0afa30004,
	0x00c000ed5,
	0x00c000885,
	0x0afa50008,
	0x004210008,
	0x0afc18076,
	0x0afc18096,
	0x023c282ae,
	0x00c000698,
	0x00c0006b3,
	0x0afa20004,
	0x08fa20000,
	0x000000027,
	0x000400008,
	0x023bd0028,
	0x023c38372,
	0x00c00078b,
	0x00c0007a6,
	0x0afa30004,
	0x0a3c0965e,
	0x023c3965e,
	0x020020032,
	0x0a3c2966e,
	0x02003ffff,
	0x0a7c39672,
	0x023c3966e,
	0x0afa30004,
	0x023c4865e,
	0x00c00086f,
	0x023c4866e,
	0x00c000894,
	0x0afa40008,
	0x08fc28076,
	0x023c4865e,
	0x08fc28096,
	0x023c4866e,
	0x0afa20004,
	0x0afa40008,
	0x0afa10024,
	0x00c000edf,
	0x00c00088f,
	0x0afa1000c,
	0x08fa50024,
	0x000000027,


@@ 230,37 233,37 @@ ulong bootcode[]={
	0x000000027,
	0x023c28379,
	0x0afa20004,
	0x00c00078b,
	0x00c0007a6,
	0x0afa50008,
	0x023c28381,
	0x00c000698,
	0x00c0006b3,
	0x0afa20004,
	0x08fa20000,
	0x000000027,
	0x000400008,
	0x023bd0028,
	0x08fc28076,
	0x023c4865e,
	0x08fc28096,
	0x023c4866e,
	0x0afa20004,
	0x0afa40008,
	0x020021000,
	0x00c000eda,
	0x00c00088a,
	0x0afa2000c,
	0x01c200008,
	0x000000027,
	0x023c3838b,
	0x00c000698,
	0x00c0006b3,
	0x0afa30004,
	0x08fa20000,
	0x000000027,
	0x000400008,
	0x023bd0028,
	0x023c3865e,
	0x023c3866e,
	0x0afa30004,
	0x023c4965e,
	0x023c4966e,
	0x0afa40008,
	0x0afa10024,
	0x00c000c0c,
	0x00c000c47,
	0x0afa1000c,
	0x014200019,
	0x000000027,


@@ 269,298 272,322 @@ ulong bootcode[]={
	0x08fa30024,
	0x000000027,
	0x0afa30008,
	0x083c2865e,
	0x083c2866e,
	0x000000027,
	0x0afa2000c,
	0x083c3865f,
	0x083c3866f,
	0x000000027,
	0x0afa30010,
	0x083c28660,
	0x083c28670,
	0x000000027,
	0x0afa20014,
	0x083c38661,
	0x00c00078b,
	0x083c38671,
	0x00c0007a6,
	0x0afa30018,
	0x023c283b7,
	0x00c000698,
	0x00c0006b3,
	0x0afa20004,
	0x08fa20000,
	0x000000027,
	0x000400008,
	0x023bd0028,
	0x083c3965e,
	0x020020001,
	0x083c3966e,
	0x020020033,
	0x010620008,
	0x000000027,
	0x023c383c2,
	0x00c000698,
	0x00c0006b3,
	0x0afa30004,
	0x08fa20000,
	0x000000027,
	0x000400008,
	0x023bd0028,
	0x087c29672,
	0x02003ffff,
	0x010430008,
	0x000000027,
	0x023c283cb,
	0x00c00078b,
	0x0afa20004,
	0x020030002,
	0x0a3c3965e,
	0x020020076,
	0x0a3c2966a,
	0x023c2965e,
	0x00c0006b3,
	0x0afa20004,
	0x023c4865e,
	0x00c00086f,
	0x0afa40008,
	0x08fc38076,
	0x023c4865e,
	0x08fa20000,
	0x000000027,
	0x000400008,
	0x023bd0028,
	0x023c383d6,
	0x00c0007a6,
	0x0afa30004,
	0x020020034,
	0x0a3c2966e,
	0x02003ffff,
	0x0a7c39672,
	0x023c3966e,
	0x0afa30004,
	0x023c4866e,
	0x00c000894,
	0x0afa40008,
	0x08fc28096,
	0x023c4866e,
	0x0afa20004,
	0x0afa40008,
	0x0afa10024,
	0x00c000edf,
	0x00c00088f,
	0x0afa1000c,
	0x08fa40024,
	0x000000027,
	0x010240008,
	0x000000027,
	0x023c283d6,
	0x00c000698,
	0x023c283e1,
	0x00c0006b3,
	0x0afa20004,
	0x08fa20000,
	0x000000027,
	0x000400008,
	0x023bd0028,
	0x08fc28076,
	0x023c4865e,
	0x08fc28096,
	0x023c4866e,
	0x0afa20004,
	0x0afa40008,
	0x020021000,
	0x00c000eda,
	0x00c00088a,
	0x0afa2000c,
	0x01c200008,
	0x000000027,
	0x023c383e4,
	0x00c000698,
	0x023c383ef,
	0x00c0006b3,
	0x0afa30004,
	0x08fa20000,
	0x000000027,
	0x000400008,
	0x023bd0028,
	0x023c3865e,
	0x023c3866e,
	0x0afa30004,
	0x023c4965e,
	0x023c4966e,
	0x0afa40008,
	0x00c000c0c,
	0x00c000c47,
	0x0afa1000c,
	0x014200008,
	0x000000027,
	0x023c283f1,
	0x00c000698,
	0x023c283fc,
	0x00c0006b3,
	0x0afa20004,
	0x08fa20000,
	0x000000027,
	0x000400008,
	0x023bd0028,
	0x083c3965e,
	0x020020003,
	0x087c39672,
	0x02002ffff,
	0x010620008,
	0x000000027,
	0x023c38400,
	0x00c000698,
	0x023c3840b,
	0x00c0006b3,
	0x0afa30004,
	0x08fa20000,
	0x000000027,
	0x000400008,
	0x023bd0028,
	0x087c29662,
	0x083c2966e,
	0x020030037,
	0x01443000d,
	0x000000027,
	0x01040000d,
	0x020020002,
	0x0afa20004,
	0x023c38416,
	0x0afa30008,
	0x023c2966e,
	0x024420008,
	0x00c0007cb,
	0x0afa2000c,
	0x08fa20000,
	0x000000027,
	0x023c3840d,
	0x0afa30004,
	0x087c29662,
	0x00c00078b,
	0x0afa20008,
	0x023c38417,
	0x00c000698,
	0x000400008,
	0x023bd0028,
	0x083c3966e,
	0x020020035,
	0x010620008,
	0x000000027,
	0x023c38426,
	0x00c0006b3,
	0x0afa30004,
	0x08fa20000,
	0x000000027,
	0x000400008,
	0x023bd0028,
	0x023c28424,
	0x00c00078b,
	0x023c28433,
	0x00c0007a6,
	0x0afa20004,
	0x023c3865e,
	0x023c3866e,
	0x0afa30004,
	0x023c2842c,
	0x023c2843b,
	0x0afa20008,
	0x08fa3001c,
	0x000000027,
	0x08c630008,
	0x00c0007d5,
	0x00c0007f0,
	0x0afa3000c,
	0x023c3865e,
	0x023c3866e,
	0x0afa30004,
	0x020040001,
	0x0afa40008,
	0x0200301b6,
	0x00c000ec1,
	0x00c000871,
	0x0afa3000c,
	0x004210004,
	0x0afa10020,
	0x023c28432,
	0x00c0006ab,
	0x023c28441,
	0x00c0006c5,
	0x0afa20004,
	0x023c3865e,
	0x023c3866e,
	0x0afa30004,
	0x023c28439,
	0x023c28448,
	0x0afa20008,
	0x08fc38076,
	0x00c0007d5,
	0x08fc38096,
	0x00c0007f0,
	0x0afa3000c,
	0x023c2865e,
	0x00c000857,
	0x023c2866e,
	0x00c00084a,
	0x0afa20004,
	0x0afa10018,
	0x023c4865e,
	0x00c000857,
	0x023c4866e,
	0x00c00084a,
	0x0afa40004,
	0x0afa10014,
	0x08fa40020,
	0x023c3865e,
	0x023c3866e,
	0x0afa40004,
	0x0afa30008,
	0x08fa40014,
	0x00c000edf,
	0x00c00088f,
	0x0afa4000c,
	0x08fa30018,
	0x000000027,
	0x010230004,
	0x000000027,
	0x023c2843c,
	0x00c0006ab,
	0x023c2844b,
	0x00c0006c5,
	0x0afa20004,
	0x08fa30020,
	0x00c000ebc,
	0x00c00086c,
	0x0afa30004,
	0x023c38442,
	0x023c38451,
	0x0afa30004,
	0x020040001,
	0x0afa40008,
	0x0200301b6,
	0x00c000ec1,
	0x00c000871,
	0x0afa3000c,
	0x004210004,
	0x0afa10020,
	0x023c2844a,
	0x00c0006ab,
	0x023c28459,
	0x00c0006c5,
	0x0afa20004,
	0x023c3865e,
	0x023c3866e,
	0x0afa30004,
	0x023c28451,
	0x023c28460,
	0x0afa20008,
	0x08fc38076,
	0x00c0007d5,
	0x08fc38096,
	0x00c0007f0,
	0x0afa3000c,
	0x023c2865e,
	0x00c000857,
	0x023c2866e,
	0x00c00084a,
	0x0afa20004,
	0x0afa10018,
	0x023c4865e,
	0x00c000857,
	0x023c4866e,
	0x00c00084a,
	0x0afa40004,
	0x0afa10014,
	0x08fa40020,
	0x023c3865e,
	0x023c3866e,
	0x0afa40004,
	0x0afa30008,
	0x08fa40014,
	0x00c000edf,
	0x00c00088f,
	0x0afa4000c,
	0x08fa30018,
	0x000000027,
	0x010230004,
	0x000000027,
	0x023c28454,
	0x00c0006ab,
	0x023c28463,
	0x00c0006c5,
	0x0afa20004,
	0x08fa30020,
	0x00c000ebc,
	0x00c00086c,
	0x0afa30004,
	0x023c2845a,
	0x00c00078b,
	0x023c28469,
	0x00c0007a6,
	0x0afa20004,
	0x023c28463,
	0x023c28472,
	0x0afa20004,
	0x023c48465,
	0x023c48474,
	0x0afa40008,
	0x00c000eb7,
	0x00c000867,
	0x0afa0000c,
	0x004210004,
	0x000000027,
	0x023c28467,
	0x00c0006ab,
	0x023c28476,
	0x00c0006c5,
	0x0afa20004,
	0x08fc28076,
	0x023c4846c,
	0x08fc28096,
	0x023c4847b,
	0x0afa20004,
	0x0afa40008,
	0x020020006,
	0x0afa2000c,
	0x023c4846e,
	0x00c000ed0,
	0x023c4847d,
	0x0afa40010,
	0x023c2847e,
	0x00c000880,
	0x0afa20014,
	0x004210004,
	0x000000027,
	0x023c2846f,
	0x00c0006ab,
	0x0afa20004,
	0x023c38475,
	0x00c00078b,
	0x023c3847f,
	0x00c0006c5,
	0x0afa30004,
	0x08fc28076,
	0x00c000ebc,
	0x023c28485,
	0x00c0007a6,
	0x0afa20004,
	0x08fa3002c,
	0x08fc38096,
	0x00c00086c,
	0x0afa30004,
	0x08fa2002c,
	0x000000027,
	0x010600010,
	0x010400010,
	0x000000027,
	0x023c2847e,
	0x0afa20004,
	0x023c38489,
	0x0afa30008,
	0x023c2848e,
	0x0afa2000c,
	0x00c000863,
	0x0afa00010,
	0x023c384a1,
	0x00c0006ab,
	0x023c3848e,
	0x0afa30004,
	0x023c28499,
	0x0afa20008,
	0x023c3849e,
	0x0afa3000c,
	0x00c000856,
	0x0afa00010,
	0x023c284b1,
	0x00c0006c5,
	0x0afa20004,
	0x08fa20000,
	0x000000027,
	0x000400008,
	0x023bd0028,
	0x023c38491,
	0x0afa30004,
	0x023c2849c,
	0x0afa20008,
	0x00c000863,
	0x023c284a1,
	0x0afa20004,
	0x023c384ac,
	0x0afa30008,
	0x00c000856,
	0x0afa0000c,
	0x023c384a1,
	0x00c0006ab,
	0x0afa30004,
	0x023c284b1,
	0x00c0006c5,
	0x0afa20004,
	0x08fa20000,
	0x000000027,
	0x000400008,
	0x023bd0028,
	0x023c282be,
	0x0afa20004,
	0x00c000ed5,
	0x00c000885,
	0x0afa50008,
	0x004210008,
	0x0afc18046,
	0x0afc18076,
	0x023c382c7,
	0x00c000698,
	0x00c0006b3,
	0x0afa30004,
	0x08fa20000,
	0x000000027,


@@ 570,44 597,44 @@ ulong bootcode[]={
	0x023c482d8,
	0x0afa40008,
	0x02003000d,
	0x00c000edf,
	0x00c00088f,
	0x0afa3000c,
	0x004210008,
	0x000000027,
	0x023c282e6,
	0x00c000698,
	0x00c0006b3,
	0x0afa20004,
	0x08fa20000,
	0x000000027,
	0x000400008,
	0x023bd0028,
	0x08fc28046,
	0x08fc28076,
	0x023c482f4,
	0x0afa20004,
	0x0afa40008,
	0x02002000c,
	0x00c000edf,
	0x00c00088f,
	0x0afa2000c,
	0x004210008,
	0x000000027,
	0x023c38301,
	0x00c000698,
	0x00c0006b3,
	0x0afa30004,
	0x08fa20000,
	0x000000027,
	0x000400008,
	0x023bd0028,
	0x08fc38046,
	0x08fc38076,
	0x023c4830e,
	0x0afa30004,
	0x0afa40008,
	0x02003000c,
	0x00c000edf,
	0x00c00088f,
	0x0afa3000c,
	0x004210008,
	0x000000027,
	0x023c2831b,
	0x00c000698,
	0x00c0006b3,
	0x0afa20004,
	0x08fa20000,
	0x000000027,


@@ 616,12 643,12 @@ ulong bootcode[]={
	0x023c28328,
	0x0afa20004,
	0x020040002,
	0x00c000ed5,
	0x00c000885,
	0x0afa40008,
	0x004210008,
	0x0afc18076,
	0x0afc18096,
	0x023c38337,
	0x00c000698,
	0x00c0006b3,
	0x0afa30004,
	0x08fa20000,
	0x000000027,


@@ 630,34 657,34 @@ ulong bootcode[]={
	0x023c3834e,
	0x0afa30004,
	0x020040002,
	0x00c000ed5,
	0x00c000885,
	0x0afa40008,
	0x004210008,
	0x0afc18042,
	0x0afc18072,
	0x023c2835c,
	0x00c000698,
	0x00c0006b3,
	0x0afa20004,
	0x08fa20000,
	0x000000027,
	0x000400008,
	0x023bd0028,
	0x08fc48052,
	0x00c000857,
	0x08fc4807a,
	0x00c00084a,
	0x0afa40004,
	0x0afa10018,
	0x08fc48042,
	0x08fc48072,
	0x000000027,
	0x0afa40004,
	0x08fc28052,
	0x08fc2807a,
	0x000000027,
	0x0afa20008,
	0x08fa40018,
	0x00c000edf,
	0x00c00088f,
	0x0afa4000c,
	0x00421fe41,
	0x00421fe26,
	0x000000027,
	0x08fc28052,
	0x00c000698,
	0x08fc2807a,
	0x00c0006b3,
	0x0afa20004,
	0x08fa20000,
	0x000000027,


@@ 665,39 692,37 @@ ulong bootcode[]={
	0x023bd0028,
	0x023bdffac,
	0x0afbf0000,
	0x0afa00004,
	0x023a20014,
	0x00c000ec6,
	0x0afa20008,
	0x020030002,
	0x0afa30004,
	0x023c284ac,
	0x0afa20008,
	0x08fa30058,
	0x023a20014,
	0x0afa3000c,
	0x00c0007b0,
	0x0afa20010,
	0x08fa20000,
	0x000000027,
	0x000400008,
	0x023bd0054,
	0x023bdffac,
	0x0afbf0000,
	0x0afa00004,
	0x023a30014,
	0x00c000ec6,
	0x0afa30008,
	0x00c000876,
	0x0afa30004,
	0x020020002,
	0x0afa20004,
	0x023c384ba,
	0x023c384bc,
	0x0afa30008,
	0x08fa20058,
	0x023a30014,
	0x0afa2000c,
	0x00c0007b0,
	0x00c0007cb,
	0x0afa30010,
	0x00c00076f,
	0x08fa20000,
	0x000000027,
	0x000400008,
	0x023bd0054,
	0x023bdffac,
	0x0afbf0000,
	0x023a20014,
	0x00c000876,
	0x0afa20004,
	0x020030002,
	0x0afa30004,
	0x023c284ca,
	0x0afa20008,
	0x08fa30058,
	0x023a20014,
	0x0afa3000c,
	0x00c0007cb,
	0x0afa20010,
	0x00c00078a,
	0x0afa00004,
	0x08fa20000,
	0x000000027,


@@ 705,21 730,21 @@ ulong bootcode[]={
	0x023bd0054,
	0x023bdfff0,
	0x0afbf0000,
	0x08fa30014,
	0x023c484c8,
	0x0afa30004,
	0x00c0007ee,
	0x08fa20014,
	0x023c484d8,
	0x0afa20004,
	0x00c000808,
	0x0afa40008,
	0x010200024,
	0x000000027,
	0x08fa30014,
	0x023c484ca,
	0x023c484da,
	0x0afa30004,
	0x00c0007ee,
	0x00c000808,
	0x0afa40008,
	0x01020001d,
	0x000000027,
	0x023c58582,
	0x023c58592,
	0x08ca30000,
	0x000000027,
	0x010600014,


@@ 729,7 754,7 @@ ulong bootcode[]={
	0x000000027,
	0x0afa30004,
	0x08fa40014,
	0x00c0007ee,
	0x00c000808,
	0x0afa40008,
	0x08fa5000c,
	0x014200005,


@@ 747,16 772,16 @@ ulong bootcode[]={
	0x023bd0010,
	0x000400008,
	0x000000825,
	0x023c58582,
	0x023c58592,
	0x08ca20000,
	0x000000027,
	0x01040000e,
	0x000000027,
	0x023c384cf,
	0x023c384df,
	0x0afa30004,
	0x0afa5000c,
	0x08ca20000,
	0x00c00078b,
	0x00c0007a6,
	0x0afa20008,
	0x08fa3000c,
	0x000000027,


@@ 771,29 796,29 @@ ulong bootcode[]={
	0x000000825,
	0x023bdffec,
	0x0afbf0000,
	0x023c384d3,
	0x023c384e3,
	0x0afa30004,
	0x08fa20018,
	0x000000027,
	0x0afa20008,
	0x08fa3001c,
	0x00c00078b,
	0x00c0007a6,
	0x0afa3000c,
	0x0afa00004,
	0x08fa30020,
	0x000000027,
	0x0afa30008,
	0x08fa40024,
	0x00c000eda,
	0x00c00088a,
	0x0afa4000c,
	0x014200003,
	0x000012825,
	0x008000704,
	0x00800071d,
	0x000000027,
	0x004210006,
	0x0afa10010,
	0x023c284dc,
	0x00c0006ab,
	0x023c284ec,
	0x00c0006c5,
	0x0afa20004,
	0x08fa50010,
	0x000000027,


@@ 804,7 829,7 @@ ulong bootcode[]={
	0x000000027,
	0x0afa30004,
	0x08fa2001c,
	0x00c000817,
	0x00c00082f,
	0x0afa20008,
	0x08fa50010,
	0x08fa20000,


@@ 820,88 845,90 @@ ulong bootcode[]={
	0x000400008,
	0x000050825,
	0x023bdfff8,
	0x000002025,
	0x028810021,
	0x010200011,
	0x023c585da,
	0x000040880,
	0x000250821,
	0x08c210000,
	0x023c685ea,
	0x000002825,
	0x028a20021,
	0x010400011,
	0x000003825,
	0x000051080,
	0x000461021,
	0x08c420000,
	0x000000027,
	0x014200008,
	0x014400008,
	0x000000027,
	0x000041080,
	0x08fa3000c,
	0x000451021,
	0x000051880,
	0x08fa4000c,
	0x000661821,
	0x020010001,
	0x023bd0008,
	0x003e00008,
	0x0ac430000,
	0x028810020,
	0x01420fff1,
	0x024840001,
	0x0ac640000,
	0x028a20020,
	0x01440fff1,
	0x024a50001,
	0x023bd0008,
	0x003e00008,
	0x000000825,
	0x000070825,
	0x023bdfff8,
	0x08fa5000c,
	0x000001825,
	0x028610021,
	0x01020000d,
	0x023c485da,
	0x000030880,
	0x000240821,
	0x08c210000,
	0x000000027,
	0x014250004,
	0x000000027,
	0x000030880,
	0x000240821,
	0x0ac200000,
	0x028610020,
	0x01420fff5,
	0x024630001,
	0x08fa7000c,
	0x023c585ea,
	0x000002025,
	0x028820021,
	0x01040000d,
	0x000003025,
	0x000041080,
	0x000451021,
	0x08c420000,
	0x000000027,
	0x014470004,
	0x000000027,
	0x000041080,
	0x000451021,
	0x0ac460000,
	0x028820020,
	0x01440fff5,
	0x024840001,
	0x003e00008,
	0x023bd0008,
	0x023bdfff8,
	0x0afbf0000,
	0x08fa1000c,
	0x08fa2000c,
	0x000000027,
	0x014200003,
	0x014400003,
	0x000000027,
	0x00c00076f,
	0x00c00078a,
	0x0afa00004,
	0x023c2805e,
	0x00c00076f,
	0x0afa20004,
	0x023c3807e,
	0x00c00078a,
	0x0afa30004,
	0x08fa20000,
	0x000000027,
	0x000400008,
	0x023bd0008,
	0x023bdfff0,
	0x0afbf0000,
	0x023c585da,
	0x020030020,
	0x004600010,
	0x023c685ea,
	0x020040020,
	0x004800010,
	0x000000027,
	0x000031080,
	0x000451021,
	0x08c440000,
	0x000041880,
	0x000661821,
	0x08c650000,
	0x000000027,
	0x010800008,
	0x010a00008,
	0x000000027,
	0x0afa3000c,
	0x000030880,
	0x000250821,
	0x00080f809,
	0x0ac200000,
	0x08fa3000c,
	0x023c585da,
	0x008000773,
	0x02463ffff,
	0x08fa20014,
	0x00c000eb2,
	0x0afa20004,
	0x0afa4000c,
	0x000041080,
	0x000461021,
	0x000a0f809,
	0x0ac400000,
	0x08fa4000c,
	0x023c685ea,
	0x00800078e,
	0x02484ffff,
	0x08fa30014,
	0x00c000862,
	0x0afa30004,
	0x08fa20000,
	0x000000027,
	0x000400008,


@@ 910,33 937,33 @@ ulong bootcode[]={
	0x0afbf0000,
	0x023a5001c,
	0x0afa50004,
	0x024a21000,
	0x0afa20008,
	0x024a41000,
	0x0afa40008,
	0x08fa31020,
	0x023a21020,
	0x023a41020,
	0x0afa3000c,
	0x024420004,
	0x00c000f02,
	0x0afa20010,
	0x024840004,
	0x00c000f1c,
	0x0afa40010,
	0x023a6001c,
	0x020020001,
	0x0afa20004,
	0x0afa60008,
	0x000261023,
	0x00c000edf,
	0x00c00088f,
	0x0afa2000c,
	0x0afa10014,
	0x00421000c,
	0x000012825,
	0x08fc28036,
	0x08fc38066,
	0x000000027,
	0x024410001,
	0x02822000a,
	0x024630001,
	0x02862000a,
	0x014400006,
	0x0afc18036,
	0x020010001,
	0x00c000760,
	0x0afa10004,
	0x0afc38066,
	0x020020001,
	0x00c00077b,
	0x0afa20004,
	0x08fa50014,
	0x000000027,
	0x08fa20000,


@@ 947,33 974,33 @@ ulong bootcode[]={
	0x0afbf0000,
	0x023a5001c,
	0x0afa50004,
	0x024a21000,
	0x0afa20008,
	0x024a41000,
	0x0afa40008,
	0x08fa31024,
	0x023a21024,
	0x023a41024,
	0x0afa3000c,
	0x024420004,
	0x00c000f02,
	0x0afa20010,
	0x08fa31020,
	0x024840004,
	0x00c000f1c,
	0x0afa40010,
	0x08fa21020,
	0x023a6001c,
	0x0afa30004,
	0x0afa20004,
	0x0afa60008,
	0x000261023,
	0x00c000edf,
	0x00c00088f,
	0x0afa2000c,
	0x0afa10014,
	0x00421000c,
	0x000012825,
	0x08fc28036,
	0x08fc38066,
	0x000000027,
	0x024410001,
	0x02822000a,
	0x024630001,
	0x02862000a,
	0x014400006,
	0x0afc18036,
	0x020010001,
	0x00c000760,
	0x0afa10004,
	0x0afc38066,
	0x020020001,
	0x00c00077b,
	0x0afa20004,
	0x08fa50014,
	0x000000027,
	0x08fa20000,


@@ 983,55 1010,52 @@ ulong bootcode[]={
	0x023bdffe4,
	0x0afbf0000,
	0x08fa50020,
	0x08fc1803a,
	0x024a21000,
	0x0afa10014,
	0x08fc2806a,
	0x024a41000,
	0x0afa20014,
	0x0afa50004,
	0x0afa20008,
	0x08fa30024,
	0x023a20024,
	0x0afa3000c,
	0x024420004,
	0x00c000f02,
	0x0afa20010,
	0x000012825,
	0x08fa10014,
	0x0afa40008,
	0x08fa20024,
	0x023a40024,
	0x0afa2000c,
	0x024840004,
	0x00c000f1c,
	0x0afa40010,
	0x08fa20014,
	0x000000027,
	0x0afc1803a,
	0x0afc2806a,
	0x08fa20020,
	0x000000027,
	0x000a20823,
	0x000220823,
	0x08fa20000,
	0x000000027,
	0x000400008,
	0x023bd001c,
	0x023bdfff4,
	0x08fa70010,
	0x08fa60014,
	0x08fa80010,
	0x08fa70014,
	0x000000027,
	0x000070825,
	0x080230000,
	0x000060825,
	0x000032600,
	0x000042603,
	0x080230000,
	0x024c60001,
	0x000032e00,
	0x000081025,
	0x080420000,
	0x000071825,
	0x000022e00,
	0x000052e03,
	0x000041600,
	0x000021603,
	0x000020825,
	0x000051600,
	0x000021603,
	0x01022000f,
	0x080630000,
	0x024e70001,
	0x000041600,
	0x000033600,
	0x000063603,
	0x000051600,
	0x000021603,
	0x000020825,
	0x000061e00,
	0x000031e03,
	0x01043000e,
	0x025080001,
	0x000051600,
	0x000021603,
	0x00041102a,
	0x010400004,
	0x000061e00,
	0x000031e03,
	0x00062202a,
	0x010800004,
	0x000000027,
	0x023bd000c,
	0x003e00008,


@@ 1039,83 1063,46 @@ ulong bootcode[]={
	0x023bd000c,
	0x003e00008,
	0x02001ffff,
	0x000041600,
	0x000051600,
	0x000021603,
	0x01440ffdf,
	0x01440ffe1,
	0x000000027,
	0x023bd000c,
	0x003e00008,
	0x000000825,
	0x023bdfffc,
	0x08fa30008,
	0x08fa4000c,
	0x000000027,
	0x000830826,
	0x030210003,
	0x014200030,
	0x023bdffe8,
	0x0afbf0000,
	0x08fa60020,
	0x08fa5001c,
	0x000000027,
	0x03c06ff00,
	0x03c0700ff,
	0x030810003,
	0x01020000a,
	0x0afa50014,
	0x0afa5001c,
	0x0afa50004,
	0x0afa60020,
	0x0afa60008,
	0x0afa0000c,
	0x020022710,
	0x00c0014c9,
	0x0afa20010,
	0x014200007,
	0x000000027,
	0x080850000,
	0x08fa3001c,
	0x08fa20020,
	0x000000027,
	0x0a0650000,
	0x024630001,
	0x014a0fff8,
	0x024840001,
	0x08fa10008,
	0x003e00008,
	0x023bd0004,
	0x08c850000,
	0x024840004,
	0x000a60824,
	0x000a71024,
	0x010200018,
	0x024630004,
	0x010400010,
	0x030a1ff00,
	0x010200006,
	0x030a200ff,
	0x01440fff5,
	0x0ac65fffc,
	0x08fa10008,
	0x003e00008,
	0x023bd0004,
	0x000050e02,
	0x0a061fffc,
	0x000052c02,
	0x0a065fffd,
	0x0a060fffe,
	0x08fa10008,
	0x003e00008,
	0x023bd0004,
	0x000052e02,
	0x0a065fffc,
	0x0a060fffd,
	0x08fa10008,
	0x003e00008,
	0x023bd0004,
	0x0a060fffc,
	0x08fa10008,
	0x003e00008,
	0x023bd0004,
	0x080850000,
	0x024462710,
	0x008000835,
	0x024652710,
	0x08fa10014,
	0x08fa20000,
	0x000000027,
	0x0a0650000,
	0x024630001,
	0x014a0fffb,
	0x024840001,
	0x08fa10008,
	0x003e00008,
	0x023bd0004,
	0x000400008,
	0x023bd0018,
	0x023bdfff4,
	0x0afbf0000,
	0x08fa30010,
	0x08fa20010,
	0x000000027,
	0x0afa30004,
	0x00c001405,
	0x0afa20004,
	0x00c00141e,
	0x0afa00008,
	0x08fa30010,
	0x08fa20000,


@@ 1128,996 1115,1065 @@ ulong bootcode[]={
	0x023a30010,
	0x0afa20004,
	0x024630004,
	0x00c000ecb,
	0x00c00087b,
	0x0afa30008,
	0x08fa20000,
	0x000000027,
	0x000400008,
	0x023bd000c,
	0x023bdffec,
	0x0afbf0000,
	0x08fa40018,
	0x02006001c,
	0x08fa2001c,
	0x090830000,
	0x024450001,
	0x0a0430000,
	0x080810000,
	0x000000027,
	0x02422ffe9,
	0x01c4001c9,
	0x020070040,
	0x0104001ab,
	0x000000027,
	0x02422fff2,
	0x01c4000c7,
	0x000000027,
	0x0104000ae,
	0x000000027,
	0x02422fff6,
	0x01c400052,
	0x023bdfffc,
	0x020010008,
	0x00000000c,
	0x003e00008,
	0x023bd0004,
	0x023bdfffc,
	0x020010002,
	0x00000000c,
	0x003e00008,
	0x023bd0004,
	0x023bdfffc,
	0x020010004,
	0x00000000c,
	0x003e00008,
	0x023bd0004,
	0x023bdfffc,
	0x020010016,
	0x00000000c,
	0x003e00008,
	0x023bd0004,
	0x023bdfffc,
	0x020010001,
	0x00000000c,
	0x003e00008,
	0x023bd0004,
	0x023bdfffc,
	0x020010007,
	0x00000000c,
	0x003e00008,
	0x023bd0004,
	0x023bdfffc,
	0x02001000d,
	0x00000000c,
	0x003e00008,
	0x023bd0004,
	0x023bdfffc,
	0x02001000e,
	0x00000000c,
	0x003e00008,
	0x023bd0004,
	0x023bdfffc,
	0x02001000f,
	0x00000000c,
	0x003e00008,
	0x023bd0004,
	0x023bdfffc,
	0x020010014,
	0x00000000c,
	0x003e00008,
	0x023bd0004,
	0x023bdffec,
	0x0afbf0000,
	0x08fa50018,
	0x02007001c,
	0x08fa3001c,
	0x090a40000,
	0x024660001,
	0x0a0640000,
	0x084a30004,
	0x000000027,
	0x010400030,
	0x0a0c30000,
	0x084a30004,
	0x000000027,
	0x000201026,
	0x01040001b,
	0x000031a03,
	0x0a0c30001,
	0x080a30000,
	0x024c60002,
	0x02462ffbf,
	0x01c400163,
	0x020080074,
	0x010400135,
	0x000000027,
	0x038220001,
	0x010400018,
	0x02462ffc6,
	0x01c400078,
	0x000000027,
	0x038220002,
	0x01040001c,
	0x010400049,
	0x000000027,
	0x038220003,
	0x02462ffcb,
	0x01c40001c,
	0x000000027,
	0x010400013,
	0x000000027,
	0x038620032,
	0x010400010,
	0x000000027,
	0x038620033,
	0x01040000d,
	0x000000027,
	0x038620034,
	0x01040000a,
	0x000000027,
	0x023c180b6,
	0x0afa10004,
	0x080820000,
	0x00c00078b,
	0x023c3802e,
	0x0afa30004,
	0x080a20000,
	0x00c0007a6,
	0x0afa20008,
	0x08fa20000,
	0x023bd0014,
	0x000400008,
	0x000000825,
	0x084820004,
	0x08fa2001c,
	0x000000027,
	0x0a0a20000,
	0x084820004,
	0x000c20823,
	0x08fa20000,
	0x000000027,
	0x000400008,
	0x023bd0014,
	0x038620037,
	0x010400017,
	0x000000027,
	0x038620038,
	0x010400006,
	0x000000027,
	0x038620039,
	0x01040fff1,
	0x000000027,
	0x0080008bd,
	0x000000027,
	0x084a2000a,
	0x000000027,
	0x0a0c20000,
	0x084a2000a,
	0x000000027,
	0x000021203,
	0x0a0a20001,
	0x024a50002,
	0x0a0c20001,
	0x08fa2001c,
	0x000000027,
	0x000a20823,
	0x024c60002,
	0x000c20823,
	0x08fa20000,
	0x000000027,
	0x000400008,
	0x023bd0014,
	0x000050825,
	0x09083000c,
	0x024a50001,
	0x0a0230000,
	0x0afa60010,
	0x0afa60004,
	0x024a20008,
	0x0afa20008,
	0x020030040,
	0x00c0014df,
	0x0afa3000c,
	0x08fa20010,
	0x000000027,
	0x024460040,
	0x08fa2001c,
	0x000000027,
	0x000a20823,
	0x000c20823,
	0x08fa20000,
	0x000000027,
	0x000400008,
	0x023bd0014,
	0x084820002,
	0x024a10002,
	0x0a0a20000,
	0x084820002,
	0x084a30002,
	0x024c20002,
	0x0a0c30000,
	0x084a30002,
	0x000000027,
	0x000021203,
	0x0a0a20001,
	0x0afa10010,
	0x0afa10004,
	0x024810008,
	0x0afa10008,
	0x00c0014be,
	0x0afa6000c,
	0x08fa10010,
	0x02002001c,
	0x02421001c,
	0x0afa10010,
	0x0afa10004,
	0x08fa10018,
	0x000031a03,
	0x0a0c30001,
	0x0afa20010,
	0x0afa20004,
	0x024a20008,
	0x0afa20008,
	0x00c0014df,
	0x0afa7000c,
	0x08fa20010,
	0x02003001c,
	0x02442001c,
	0x0afa20010,
	0x0afa20004,
	0x08fa20018,
	0x000000027,
	0x024210024,
	0x0afa10008,
	0x00c0014be,
	0x0afa2000c,
	0x08fa10010,
	0x024420024,
	0x0afa20008,
	0x00c0014df,
	0x0afa3000c,
	0x08fa20010,
	0x02003001c,
	0x02442001c,
	0x0afa20010,
	0x0afa20004,
	0x08fa20018,
	0x000000027,
	0x024420040,
	0x0afa20008,
	0x00c0014df,
	0x0afa3000c,
	0x08fa20010,
	0x000000027,
	0x02446001c,
	0x08fa2001c,
	0x02425001c,
	0x000a20823,
	0x000000027,
	0x000c20823,
	0x08fa20000,
	0x000000027,
	0x000400008,
	0x023bd0014,
	0x03822000b,
	0x010400033,
	0x02462ffc2,
	0x01c400072,
	0x000000027,
	0x03822000c,
	0x01040001b,
	0x01040005b,
	0x000000027,
	0x03822000d,
	0x03862003b,
	0x01040002c,
	0x000000027,
	0x03862003c,
	0x010400014,
	0x000000027,
	0x03862003d,
	0x010400003,
	0x000000027,
	0x008000894,
	0x0080008bd,
	0x000000027,
	0x084810002,
	0x084a30002,
	0x000000027,
	0x0a0a10000,
	0x084810002,
	0x0a0c30000,
	0x084a30002,
	0x000000027,
	0x000010a03,
	0x0a0a10001,
	0x084820004,
	0x024a50002,
	0x0a0a20000,
	0x084820004,
	0x000031a03,
	0x0a0c30001,
	0x08fa2001c,
	0x024c60002,
	0x000c20823,
	0x08fa20000,
	0x000000027,
	0x000400008,
	0x023bd0014,
	0x084a20002,
	0x000000027,
	0x0a0c20000,
	0x084a20002,
	0x000000027,
	0x000021203,
	0x0a0a20001,
	0x0a0c20001,
	0x084a30008,
	0x024c60002,
	0x0a0c30000,
	0x084a30008,
	0x000000027,
	0x000031a03,
	0x0a0c30001,
	0x08fa2001c,
	0x024a50002,
	0x000a20823,
	0x024c60002,
	0x000c20823,
	0x08fa20000,
	0x000000027,
	0x000400008,
	0x023bd0014,
	0x084810002,
	0x084a20002,
	0x000000027,
	0x0a0a10000,
	0x084810002,
	0x000000027,
	0x000010a03,
	0x0a0a10001,
	0x08482000a,
	0x024a50002,
	0x0a0a20000,
	0x08482000a,
	0x0a0c20000,
	0x084a20002,
	0x000000027,
	0x000021203,
	0x0a0a20001,
	0x0a0c20001,
	0x08ca3000c,
	0x024c60002,
	0x0a0c30000,
	0x08ca3000c,
	0x000000027,
	0x000031a02,
	0x0a0c30001,
	0x08ca3000c,
	0x000000027,
	0x000031c02,
	0x0a0c30002,
	0x08ca3000c,
	0x000000027,
	0x000031e02,
	0x0a0c30003,
	0x08ca20010,
	0x024c60004,
	0x0a0c20000,
	0x08ca20010,
	0x000000027,
	0x000021202,
	0x0a0c20001,
	0x08ca20010,
	0x000000027,
	0x000021402,
	0x0a0c20002,
	0x08ca20010,
	0x000000027,
	0x000021602,
	0x0a0c20003,
	0x08fa2001c,
	0x024a50002,
	0x000a20823,
	0x024c60004,
	0x000c20823,
	0x08fa20000,
	0x000000027,
	0x000400008,
	0x023bd0014,
	0x084810002,
	0x084a20002,
	0x024c30002,
	0x0a0c20000,
	0x084a20002,
	0x000000027,
	0x000021203,
	0x0a0c20001,
	0x0afa30010,
	0x0afa30004,
	0x024a3000c,
	0x0afa30008,
	0x00c0014df,
	0x0afa7000c,
	0x08fa30010,
	0x08fa2001c,
	0x02466001c,
	0x000c20823,
	0x08fa20000,
	0x000000027,
	0x0a0a10000,
	0x084810002,
	0x000400008,
	0x023bd0014,
	0x03862003f,
	0x010400018,
	0x000000027,
	0x000010a03,
	0x0a0a10001,
	0x084820004,
	0x024a50002,
	0x0a0a20000,
	0x084820004,
	0x038620040,
	0x010400003,
	0x000000027,
	0x000021203,
	0x0a0a20001,
	0x08c810010,
	0x024a50002,
	0x0a0a10000,
	0x08c810010,
	0x0080008bd,
	0x000000027,
	0x000010a02,
	0x0a0a10001,
	0x08c810010,
	0x084a30002,
	0x000000027,
	0x000010c02,
	0x0a0a10002,
	0x08c810010,
	0x0a0c30000,
	0x084a30002,
	0x000000027,
	0x000010e02,
	0x0a0a10003,
	0x000031a03,
	0x0a0c30001,
	0x024c30002,
	0x090a40028,
	0x024660001,
	0x0a0640000,
	0x08fa2001c,
	0x024a50004,
	0x000a20823,
	0x000000027,
	0x000c20823,
	0x08fa20000,
	0x000000027,
	0x000400008,
	0x023bd0014,
	0x084810002,
	0x024a20002,
	0x0a0a10000,
	0x084810002,
	0x084a20002,
	0x000000027,
	0x000010a03,
	0x0a0a10001,
	0x0afa20010,
	0x0afa20004,
	0x02482000c,
	0x0afa20008,
	0x00c0014be,
	0x0afa6000c,
	0x08fa20010,
	0x0a0c20000,
	0x084a20002,
	0x000000027,
	0x02445001c,
	0x000021203,
	0x0a0c20001,
	0x08ca3000c,
	0x024c60002,
	0x0a0c30000,
	0x08ca3000c,
	0x000000027,
	0x000031a02,
	0x0a0c30001,
	0x08ca3000c,
	0x000000027,
	0x000031c02,
	0x0a0c30002,
	0x08ca3000c,
	0x000000027,
	0x000031e02,
	0x0a0c30003,
	0x08ca20010,
	0x024c60004,
	0x0a0c20000,
	0x08ca20010,
	0x000000027,
	0x000021202,
	0x0a0c20001,
	0x08ca20010,
	0x000000027,
	0x000021402,
	0x0a0c20002,
	0x08ca20010,
	0x000000027,
	0x000021602,
	0x0a0c20003,
	0x08fa2001c,
	0x000000027,
	0x000a20823,
	0x024c60004,
	0x000c20823,
	0x08fa20000,
	0x000000027,
	0x000400008,
	0x023bd0014,
	0x02422ffed,
	0x01c40004e,
	0x084a30002,
	0x000000027,
	0x01040ffc1,
	0x0a0c30000,
	0x084a30002,
	0x000000027,
	0x03822000f,
	0x01040ffbe,
	0x000031a03,
	0x0a0c30001,
	0x08ca2000c,
	0x024c60002,
	0x0a0c20000,
	0x08ca2000c,
	0x000000027,
	0x038220010,
	0x010400034,
	0x000021202,
	0x0a0c20001,
	0x08ca2000c,
	0x000000027,
	0x038220011,
	0x01040ffb8,
	0x000021402,
	0x0a0c20002,
	0x08ca2000c,
	0x000000027,
	0x038220012,
	0x010400003,
	0x000021602,
	0x0a0c20003,
	0x08ca30010,
	0x024c60004,
	0x0a0c30000,
	0x08ca30010,
	0x000000027,
	0x008000894,
	0x000031a02,
	0x0a0c30001,
	0x08ca30010,
	0x000000027,
	0x084820002,
	0x024a10002,
	0x0a0a20000,
	0x084820002,
	0x000031c02,
	0x0a0c30002,
	0x08ca30010,
	0x000000027,
	0x000021203,
	0x0a0a20001,
	0x0afa10010,
	0x0afa10004,
	0x02481000c,
	0x0afa10008,
	0x00c0014be,
	0x0afa6000c,
	0x08fa60018,
	0x08fa10010,
	0x000000027,
	0x02424001c,
	0x08cc10008,
	0x000000027,
	0x0a0810000,
	0x08cc10008,
	0x000000027,
	0x000010a03,
	0x0a0810001,
	0x08cc10008,
	0x000000027,
	0x000010c03,
	0x0a0810002,
	0x08cc10008,
	0x000000027,
	0x000010e03,
	0x0a0810003,
	0x024810004,
	0x090c30028,
	0x024250001,
	0x0a0230000,
	0x000031e02,
	0x0a0c30003,
	0x08fa2001c,
	0x000000027,
	0x000a20823,
	0x024c60004,
	0x000c20823,
	0x08fa20000,
	0x000000027,
	0x000400008,
	0x023bd0014,
	0x084820002,
	0x02462ffb7,
	0x01c400127,
	0x000000027,
	0x0a0a20000,
	0x084820002,
	0x010400117,
	0x000000027,
	0x02462ffbb,
	0x01c4000b0,
	0x000000027,
	0x01040008b,
	0x000000027,
	0x038620042,
	0x01040005d,
	0x000000027,
	0x038620043,
	0x01040002e,
	0x000000027,
	0x038620044,
	0x010400003,
	0x000000027,
	0x0080008bd,
	0x000000027,
	0x084a30002,
	0x000000027,
	0x0a0c30000,
	0x084a30002,
	0x000000027,
	0x000031a03,
	0x0a0c30001,
	0x08ca20008,
	0x024c60002,
	0x0a0c20000,
	0x08ca20008,
	0x000000027,
	0x000021203,
	0x0a0a20001,
	0x024a20002,
	0x090830028,
	0x024450001,
	0x0a0430000,
	0x08fa2001c,
	0x0a0c20001,
	0x08ca20008,
	0x000000027,
	0x000021403,
	0x0a0c20002,
	0x08ca20008,
	0x000000027,
	0x000a20823,
	0x000021603,
	0x0a0c20003,
	0x0a0c00004,
	0x0a0c00005,
	0x0a0c00006,
	0x0a0c00007,
	0x08ca3000c,
	0x024c60008,
	0x0a0c30000,
	0x08ca3000c,
	0x000000027,
	0x000031a03,
	0x0a0c30001,
	0x08fa2001c,
	0x024c60002,
	0x000c20823,
	0x08fa20000,
	0x000000027,
	0x000400008,
	0x023bd0014,
	0x038220014,
	0x010400067,
	0x084a20002,
	0x000000027,
	0x038220015,
	0x01040003b,
	0x0a0c20000,
	0x084a20002,
	0x000000027,
	0x038220016,
	0x010400003,
	0x000021203,
	0x0a0c20001,
	0x08ca3000c,
	0x024c60002,
	0x0a0c30000,
	0x08ca3000c,
	0x000000027,
	0x000031a02,
	0x0a0c30001,
	0x08ca3000c,
	0x000000027,
	0x000031c02,
	0x0a0c30002,
	0x08ca3000c,
	0x000000027,
	0x000031e02,
	0x0a0c30003,
	0x08ca20010,
	0x024c60004,
	0x0a0c20000,
	0x08ca20010,
	0x000000027,
	0x000021202,
	0x0a0c20001,
	0x08ca20010,
	0x000000027,
	0x000021402,
	0x0a0c20002,
	0x08ca20010,
	0x000000027,
	0x000021602,
	0x0a0c20003,
	0x08fa2001c,
	0x024c60004,
	0x000c20823,
	0x08fa20000,
	0x000000027,
	0x008000894,
	0x000400008,
	0x023bd0014,
	0x084a30002,
	0x024c20002,
	0x0a0c30000,
	0x084a30002,
	0x000000027,
	0x084810002,
	0x000031a03,
	0x0a0c30001,
	0x0afa20010,
	0x0afa20004,
	0x024a2000c,
	0x0afa20008,
	0x00c0014df,
	0x0afa7000c,
	0x08fa70018,
	0x08fa20010,
	0x000000027,
	0x0a0a10000,
	0x084810002,
	0x02445001c,
	0x08ce20008,
	0x000000027,
	0x000010a03,
	0x0a0a10001,
	0x08c820008,
	0x024a50002,
	0x0a0a20000,
	0x08c820008,
	0x08ce20008,
	0x000000027,
	0x000021203,
	0x0a0a20001,
	0x08c820008,
	0x08ce20008,
	0x000000027,
	0x000021403,
	0x0a0a20002,
	0x08c820008,
	0x08ce20008,
	0x000000027,
	0x000021603,
	0x0a0a20003,
	0x0a0a00004,
	0x0a0a00005,
	0x0a0a00006,
	0x0a0a00007,
	0x08c81000c,
	0x024a50008,
	0x0a0a10000,
	0x08c81000c,
	0x024a20002,
	0x000010a03,
	0x0a0a10001,
	0x024a20004,
	0x090e40028,
	0x024460001,
	0x0a0440000,
	0x08fa2001c,
	0x000000027,
	0x000c20823,
	0x08fa20000,
	0x000000027,
	0x000400008,
	0x023bd0014,
	0x084a30002,
	0x000000027,
	0x0a0c30000,
	0x084a30002,
	0x000000027,
	0x000031a03,
	0x0a0c30001,
	0x08ca2000c,
	0x024c60002,
	0x0a0c20000,
	0x08ca2000c,
	0x024c30002,
	0x000021203,
	0x0a0c20001,
	0x024620001,
	0x0afa20010,
	0x0afa20004,
	0x08c820010,
	0x08ca20010,
	0x000000027,
	0x0afa20008,
	0x08c81000c,
	0x00c0014be,
	0x0afa1000c,
	0x08ca3000c,
	0x00c0014df,
	0x0afa3000c,
	0x08fa20018,
	0x08fa10010,
	0x08fa30010,
	0x08c42000c,
	0x000000027,
	0x000222821,
	0x000623021,
	0x08fa2001c,
	0x000000027,
	0x000a20823,
	0x000c20823,
	0x08fa20000,
	0x000000027,
	0x000400008,
	0x023bd0014,
	0x084820002,
	0x038620046,
	0x01040002c,
	0x000000027,
	0x0a0a20000,
	0x084820002,
	0x038620047,
	0x010400014,
	0x000000027,
	0x000021203,
	0x0a0a20001,
	0x084810004,
	0x024a50002,
	0x0a0a10000,
	0x084810004,
	0x038620048,
	0x010400003,
	0x000000027,
	0x000010a03,
	0x0a0a10001,
	0x08c82000c,
	0x024a50002,
	0x0a0a20000,
	0x08c82000c,
	0x024a10002,
	0x000021203,
	0x0a0a20001,
	0x0afa10010,
	0x0afa10004,
	0x08c810010,
	0x0080008bd,
	0x000000027,
	0x0afa10008,
	0x08c82000c,
	0x00c0014be,
	0x0afa2000c,
	0x08fa10018,
	0x08fa20010,
	0x08c21000c,
	0x084a20002,
	0x000000027,
	0x000412821,
	0x08fa2001c,
	0x0a0c20000,
	0x084a20002,
	0x000000027,
	0x000a20823,
	0x000021203,
	0x0a0c20001,
	0x08fa2001c,
	0x024c60002,
	0x000c20823,
	0x08fa20000,
	0x000000027,
	0x000400008,
	0x023bd0014,
	0x084820002,
	0x084a20002,
	0x000000027,
	0x0a0a20000,
	0x084820002,
	0x0a0c20000,
	0x084a20002,
	0x000000027,
	0x000021203,
	0x0a0a20001,
	0x08c810008,
	0x024a50002,
	0x0a0a10000,
	0x08c810008,
	0x0a0c20001,
	0x08ca3000c,
	0x024c60002,
	0x0a0c30000,
	0x08ca3000c,
	0x000000027,
	0x000031a03,
	0x0a0c30001,
	0x08fa2001c,
	0x024c60002,
	0x000c20823,
	0x08fa20000,
	0x000000027,
	0x000010a03,
	0x0a0a10001,
	0x08c810008,
	0x000400008,
	0x023bd0014,
	0x084a20002,
	0x000000027,
	0x000010c03,
	0x0a0a10002,
	0x08c810008,
	0x0a0c20000,
	0x084a20002,
	0x000000027,
	0x000010e03,
	0x0a0a10003,
	0x0a0a00004,
	0x0a0a00005,
	0x0a0a00006,
	0x0a0a00007,
	0x08c82000c,
	0x024a50008,
	0x0a0a20000,
	0x08c82000c,
	0x000021203,
	0x0a0c20001,
	0x08ca30008,
	0x024c60002,
	0x0a0c30000,
	0x08ca30008,
	0x000000027,
	0x000031a03,
	0x0a0c30001,
	0x08ca30008,
	0x000000027,
	0x000031c03,
	0x0a0c30002,
	0x08ca30008,
	0x000000027,
	0x000031e03,
	0x0a0c30003,
	0x0a0c00004,
	0x0a0c00005,
	0x0a0c00006,
	0x0a0c00007,
	0x08ca2000c,
	0x024c60008,
	0x0a0c20000,
	0x08ca2000c,
	0x024c30002,
	0x000021203,
	0x0a0a20001,
	0x0a0c20001,
	0x024620001,
	0x0afa20010,
	0x0afa20004,
	0x08ca20010,
	0x000000027,
	0x0afa20008,
	0x08ca3000c,
	0x00c0014df,
	0x0afa3000c,
	0x08fa20018,
	0x08fa30010,
	0x08c42000c,
	0x000000027,
	0x000623021,
	0x08fa2001c,
	0x024a50002,
	0x000a20823,
	0x000000027,
	0x000c20823,
	0x08fa20000,
	0x000000027,
	0x000400008,
	0x023bd0014,
	0x084810002,
	0x000000027,
	0x0a0a10000,
	0x084810002,
	0x084a20002,
	0x000000027,
	0x000010a03,
	0x0a0a10001,
	0x084820004,
	0x024a50002,
	0x0a0a20000,
	0x084820004,
	0x0a0c20000,
	0x084a20002,
	0x000000027,
	0x000021203,
	0x0a0a20001,
	0x08c81000c,
	0x024a50002,
	0x0a0a10000,
	0x08c81000c,
	0x000000027,
	0x000010a03,
	0x0a0a10001,
	0x0a0c20001,
	0x08fa2001c,
	0x024a50002,
	0x000a20823,
	0x024c60002,
	0x000c20823,
	0x08fa20000,
	0x000000027,
	0x000400008,
	0x023bd0014,
	0x02422ffe0,
	0x01c400079,
	0x000000027,
	0x010400062,
	0x000000027,
	0x02422ffe4,
	0x01c40001f,
	0x02462ffb3,
	0x01c40004d,
	0x000000027,
	0x01040000f,
	0x010400036,
	0x000000027,
	0x038220018,
	0x01040000c,
	0x03862004a,
	0x010400025,
	0x000000027,
	0x038220019,
	0x01040fe8f,
	0x03862004b,
	0x010400014,
	0x000000027,
	0x03822001a,
	0x01040feda,
	0x000000027,
	0x03822001b,
	0x01040fe89,
	0x03862004c,
	0x010400003,
	0x000000027,
	0x008000894,
	0x0080008bd,
	0x000000027,
	0x084820002,
	0x084a20002,
	0x000000027,
	0x0a0a20000,
	0x084820002,
	0x0a0c20000,
	0x084a20002,
	0x000000027,
	0x000021203,
	0x0a0a20001,
	0x0a0c20001,
	0x08fa2001c,
	0x024a50002,
	0x000a20823,
	0x024c60002,
	0x000c20823,
	0x08fa20000,
	0x000000027,
	0x000400008,
	0x023bd0014,
	0x03822001d,
	0x010400020,
	0x084a30002,
	0x000000027,
	0x03822001e,
	0x010400006,
	0x000000027,
	0x03822001f,
	0x01040fe70,
	0x000000027,
	0x008000894,
	0x000000027,
	0x084810002,
	0x024a20002,
	0x0a0a10000,
	0x084810002,
	0x0a0c30000,
	0x084a30002,
	0x000000027,
	0x000010a03,
	0x0a0a10001,
	0x0afa20010,
	0x0afa20004,
	0x024820008,
	0x0afa20008,
	0x00c0014be,
	0x0afa7000c,
	0x08fa20010,
	0x000000027,
	0x024450040,
	0x000031a03,
	0x0a0c30001,
	0x08fa2001c,
	0x000000027,
	0x000a20823,
	0x024c60002,
	0x000c20823,
	0x08fa20000,
	0x000000027,
	0x000400008,
	0x023bd0014,
	0x084820002,
	0x084a30002,
	0x000000027,
	0x0a0a20000,
	0x084820002,
	0x0a0c30000,
	0x084a30002,
	0x000000027,
	0x000021203,
	0x0a0a20001,
	0x084810004,
	0x024a50002,
	0x0a0a10000,
	0x084810004,
	0x024a20002,
	0x000010a03,
	0x0a0a10001,
	0x0afa20010,
	0x0afa20004,
	0x024820008,
	0x0afa20008,
	0x00c0014be,
	0x0afa7000c,
	0x08fa20010,
	0x000000027,
	0x024450040,
	0x000031a03,
	0x0a0c30001,
	0x08fa2001c,
	0x000000027,
	0x000a20823,
	0x024c60002,
	0x000c20823,
	0x08fa20000,
	0x000000027,
	0x000400008,
	0x023bd0014,
	0x084820002,
	0x000000027,
	0x0a0a20000,
	0x084820002,
	0x084a20002,
	0x024c30002,
	0x0a0c20000,
	0x084a20002,
	0x000000027,
	0x000021203,
	0x0a0a20001,
	0x084810004,
	0x024a50002,
	0x0a0a10000,
	0x084810004,
	0x000000027,
	0x000010a03,
	0x0a0a10001,
	0x0a0c20001,
	0x0afa30010,
	0x0afa30004,
	0x024a30008,
	0x0afa30008,
	0x00c0014df,
	0x0afa8000c,
	0x08fa30010,
	0x08fa2001c,
	0x024a50002,
	0x000a20823,
	0x024660074,
	0x000c20823,
	0x08fa20000,
	0x000000027,
	0x000400008,
	0x023bd0014,
	0x02422ffdc,
	0x01c40005f,
	0x000000027,
	0x01040ff3d,
	0x03862004e,
	0x010400014,
	0x000000027,
	0x038220021,
	0x01040003c,
	0x000000027,
	0x038220022,
	0x010400024,
	0x000000027,
	0x038220023,
	0x03862004f,
	0x010400003,
	0x000000027,
	0x008000894,
	0x0080008bd,
	0x000000027,
	0x084820002,
	0x084a30002,
	0x000000027,
	0x0a0a20000,
	0x084820002,
	0x0a0c30000,
	0x084a30002,
	0x000000027,
	0x000021203,
	0x0a0a20001,
	0x084810004,
	0x024a50002,
	0x0a0a10000,
	0x084810004,
	0x024a20002,
	0x000010a03,
	0x0a0a10001,
	0x0afa20010,
	0x0afa20004,
	0x024820008,
	0x0afa20008,
	0x00c0014be,
	0x0afa6000c,
	0x08fa20010,
	0x000000027,
	0x02445001c,
	0x000031a03,
	0x0a0c30001,
	0x08fa2001c,
	0x000000027,
	0x000a20823,
	0x024c60002,
	0x000c20823,
	0x08fa20000,
	0x000000027,
	0x000400008,
	0x023bd0014,
	0x084820002,
	0x000000027,
	0x0a0a20000,
	0x084820002,
	0x000000027,
	0x000021203,
	0x0a0a20001,
	0x084810008,
	0x024a50002,
	0x0a0a10000,
	0x084810008,
	0x084a30002,
	0x024c20002,
	0x0a0c30000,
	0x084a30002,
	0x000000027,
	0x000010a03,
	0x0a0a10001,
	0x08fa2001c,
	0x024a50002,
	0x000a20823,
	0x08fa20000,
	0x000000027,
	0x000400008,
	0x023bd0014,
	0x084820002,
	0x000000027,
	0x0a0a20000,
	0x084820002,
	0x000000027,
	0x000021203,
	0x0a0a20001,
	0x084810004,
	0x024a50002,
	0x0a0a10000,
	0x084810004,
	0x024a20002,
	0x000010a03,
	0x0a0a10001,
	0x000031a03,
	0x0a0c30001,
	0x0afa20010,
	0x0afa20004,
	0x024820008,
	0x024a20008,
	0x0afa20008,
	0x00c0014be,
	0x0afa7000c,
	0x00c0014df,
	0x0afa8000c,
	0x08fa20010,
	0x000000027,
	0x024450040,
	0x024460074,
	0x08fa2001c,
	0x000000027,
	0x000a20823,
	0x000c20823,
	0x08fa20000,
	0x000000027,
	0x000400008,
	0x023bd0014,
	0x038220025,
	0x01040003f,
	0x000000027,
	0x038220026,
	0x010400006,
	0x023bdffec,
	0x0afbf0000,
	0x08fa3001c,
	0x02002001c,
	0x0afa30010,
	0x0afa30004,
	0x08fa30018,
	0x000000027,
	0x038220027,
	0x01040ff00,
	0x0afa30008,
	0x00c0014df,
	0x0afa2000c,
	0x08fa30010,
	0x02002001c,
	0x02463001c,
	0x0afa30010,
	0x0afa30004,
	0x08fa30018,
	0x000000027,
	0x008000894,
	0x02463001c,
	0x0afa30008,
	0x00c0014df,
	0x0afa2000c,
	0x08fa30010,
	0x02002001c,
	0x02463001c,
	0x0afa30010,
	0x0afa30004,
	0x08fa30018,
	0x000000027,
	0x084820002,
	0x024630038,
	0x0afa30008,
	0x00c0014df,
	0x0afa2000c,
	0x08fa40018,
	0x08fa30010,
	0x000000027,
	0x0a0a20000,
	0x084820002,
	0x02465001c,
	0x08c830054,
	0x000000027,
	0x000021203,
	0x0a0a20001,
	0x08c810008,
	0x024a50002,
	0x0a0a10000,
	0x08c810008,
	0x0a0a30000,
	0x08c830054,
	0x000000027,
	0x000010a03,
	0x0a0a10001,
	0x08c810008,
	0x000031a02,
	0x0a0a30001,
	0x08c830054,
	0x000000027,
	0x000010c03,
	0x0a0a10002,
	0x08c810008,
	0x000031c02,
	0x0a0a30002,
	0x08c830054,
	0x000000027,
	0x000010e03,
	0x0a0a10003,
	0x0a0a00004,
	0x0a0a00005,
	0x0a0a00006,
	0x0a0a00007,
	0x08c82000c,
	0x024a50008,
	0x000031e02,
	0x0a0a30003,
	0x08c820058,
	0x024a50004,
	0x0a0a20000,
	0x08c82000c,
	0x024a10002,
	0x000021203,
	0x0a0a20001,
	0x024220001,
	0x0afa20010,
	0x0afa20004,
	0x08c820010,
	0x08c820058,
	0x000000027,
	0x0afa20008,
	0x08c81000c,
	0x00c0014be,
	0x0afa1000c,
	0x08fa20018,
	0x08fa10010,
	0x08c42000c,
	0x000021202,
	0x0a0a20001,
	0x08c820058,
	0x000000027,
	0x000222821,
	0x08fa2001c,
	0x000021402,
	0x0a0a20002,
	0x08c820058,
	0x000000027,
	0x000a20823,
	0x08fa20000,
	0x000021602,
	0x0a0a20003,
	0x08c83005c,
	0x024a50004,
	0x0a0a30000,
	0x08c83005c,
	0x000000027,
	0x000400008,
	0x023bd0014,
	0x084810002,
	0x000031a02,
	0x0a0a30001,
	0x08c83005c,
	0x000000027,
	0x0a0a10000,
	0x084810002,
	0x000031c02,
	0x0a0a30002,
	0x08c83005c,
	0x000000027,
	0x000010a03,
	0x0a0a10001,
	0x084820004,
	0x024a50002,
	0x000031e02,
	0x0a0a30003,
	0x08c820060,
	0x024a50004,
	0x0a0a20000,
	0x084820004,
	0x08c820060,
	0x000000027,
	0x000021203,
	0x0a0a20001,
	0x08c81000c,
	0x024a50002,
	0x0a0a10000,
	0x08c81000c,
	0x024a20002,
	0x000010a03,
	0x0a0a10001,
	0x024410001,
	0x0afa10010,
	0x0afa10004,
	0x08c810010,
	0x000000027,
	0x0afa10008,
	0x08c82000c,
	0x00c0014be,
	0x0afa2000c,
	0x08fa10018,
	0x08fa20010,
	0x08c21000c,
	0x000000027,
	0x000412821,
	0x08fa2001c,
	0x000000027,
	0x000a20823,
	0x08fa20000,
	0x000000027,
	0x000400008,
	0x023bd0014,
	0x023bdffec,
	0x0afbf0000,
	0x08fa1001c,
	0x02002001c,
	0x0afa10010,
	0x0afa10004,
	0x08fa10018,
	0x000000027,
	0x0afa10008,
	0x00c0014be,
	0x0afa2000c,
	0x08fa30018,
	0x08fa10010,
	0x000000027,
	0x02424001c,
	0x08c61001c,
	0x024820004,
	0x0a0810000,
	0x08c61001c,
	0x000000027,
	0x000010a03,
	0x0a0810001,
	0x08c61001c,
	0x000000027,
	0x000010c03,
	0x0a0810002,
	0x08c61001c,
	0x000000027,
	0x000010e03,
	0x0a0810003,
	0x08c610024,
	0x024440004,
	0x0a0810000,
	0x08c610024,
	0x000000027,
	0x000010a03,
	0x0a0810001,
	0x08c610024,
	0x000000027,
	0x000010c03,
	0x0a0810002,
	0x08c610024,
	0x000000027,
	0x000010e03,
	0x0a0810003,
	0x08c620028,
	0x024840004,
	0x0a0820000,
	0x08c620028,
	0x000000027,
	0x000021203,
	0x0a0820001,
	0x08c620028,
	0x08c820060,
	0x000000027,
	0x000021403,
	0x0a0820002,
	0x08c620028,
	0x0a0a20002,
	0x08c820060,
	0x000000027,
	0x000021603,
	0x0a0820003,
	0x08c61002c,
	0x024840004,
	0x0a0810000,
	0x08c61002c,
	0x0a0a20003,
	0x08c830064,
	0x024a50004,
	0x0a0a30000,
	0x08c830064,
	0x000000027,
	0x000010a03,
	0x0a0810001,
	0x08c61002c,
	0x000031a03,
	0x0a0a30001,
	0x08c830064,
	0x000000027,
	0x000010c03,
	0x0a0810002,
	0x08c61002c,
	0x000031c03,
	0x0a0a30002,
	0x08c830064,
	0x000000027,
	0x000010e03,
	0x0a0810003,
	0x08c620034,
	0x024840004,
	0x0a0820000,
	0x08c620034,
	0x000031e03,
	0x0a0a30003,
	0x08c82006c,
	0x024a50004,
	0x0a0a20000,
	0x08c82006c,
	0x000000027,
	0x000021203,
	0x0a0820001,
	0x08c620034,
	0x0a0a20001,
	0x08c82006c,
	0x000000027,
	0x000021403,
	0x0a0820002,
	0x08c620034,
	0x0a0a20002,
	0x08c82006c,
	0x000000027,
	0x000021603,
	0x0a0820003,
	0x0a0800004,
	0x0a0800005,
	0x0a0800006,
	0x0a0800007,
	0x084610038,
	0x024840008,
	0x0a0810000,
	0x084610038,
	0x000000027,
	0x000010a03,
	0x0a0810001,
	0x08462003a,
	0x024840002,
	0x0a0820000,
	0x08462003a,
	0x0a0a20003,
	0x0a0a00004,
	0x0a0a00005,
	0x0a0a00006,
	0x0a0a00007,
	0x084830070,
	0x024a50008,
	0x0a0a30000,
	0x084830070,
	0x000000027,
	0x000031a03,
	0x0a0a30001,
	0x084820072,
	0x024a50002,
	0x0a0a20000,
	0x084820072,
	0x024a30002,
	0x000021203,
	0x0a0820001,
	0x084610020,
	0x024840002,
	0x0a0810000,
	0x084610020,
	0x000000027,
	0x000010a03,
	0x0a0810001,
	0x084620022,
	0x024840002,
	0x0a0820000,
	0x084620022,
	0x024810002,
	0x000021203,
	0x0a0820001,
	0x0a0a20001,
	0x08fa2001c,
	0x000000027,
	0x000220823,
	0x000620823,
	0x08fa20000,
	0x000000027,
	0x000400008,
	0x023bd0014,
	0x023bdffec,
	0x0afbf0000,
	0x08fa5001c,
	0x02006001c,
	0x08fa10018,
	0x000000027,
	0x024240001,
	0x080210000,
	0x08fa6001c,
	0x02007001c,
	0x08fa30018,
	0x000000027,
	0x0a0a10000,
	0x080a20000,
	0x024650001,
	0x080630000,
	0x000000027,
	0x02441ffe9,
	0x01c20014a,
	0x020070040,
	0x010200135,
	0x0a0c30000,
	0x090a20000,
	0x090a30001,
	0x024a50002,
	0x000031a00,
	0x000431025,
	0x0a4c20004,
	0x080c20000,
	0x000000027,
	0x02441fff2,
	0x01c20009e,
	0x02443ffbf,
	0x01c600110,
	0x020080074,
	0x0106000ef,
	0x000000027,
	0x01020008d,
	0x02443ffc6,
	0x01c600068,
	0x000000027,
	0x02441fff6,
	0x01c20004c,
	0x010600043,
	0x000000027,
	0x010200031,
	0x02443ffcb,
	0x01c600024,
	0x000000027,
	0x000400826,
	0x010200019,
	0x010600013,
	0x000000027,
	0x038410001,
	0x010200016,
	0x038430032,
	0x010600010,
	0x000000027,
	0x038410002,
	0x010200022,
	0x038430033,
	0x01060000d,
	0x000000027,
	0x038410003,
	0x01020000a,
	0x038430034,
	0x01060000a,
	0x000000027,
	0x023c280c4,
	0x023c2803c,
	0x0afa20004,
	0x080a10000,
	0x00c00078b,
	0x0afa10008,
	0x080c30000,
	0x00c0007a6,
	0x0afa30008,
	0x08fa20000,
	0x023bd0014,
	0x000400008,
	0x000000825,
	0x090810000,
	0x090820001,
	0x024840002,
	0x000021200,
	0x000220825,
	0x0a4a10004,
	0x08fa20018,
	0x08fa10020,
	0x08fa30020,
	0x000000027,
	0x000411021,
	0x014440006,
	0x000431021,
	0x014450006,
	0x000000027,
	0x08fa10020,
	0x08fa20000,


@@ 2128,674 2184,644 @@ ulong bootcode[]={
	0x023bd0014,
	0x000400008,
	0x000000825,
	0x000040825,
	0x080210000,
	0x038430037,
	0x010600010,
	0x000000027,
	0x0a0a1000c,
	0x008000c42,
	0x024840001,
	0x090820000,
	0x090810001,
	0x024840002,
	0x000010a00,
	0x000411025,
	0x0a4a20002,
	0x024a20008,
	0x038430038,
	0x010600006,
	0x000000027,
	0x038430039,
	0x01060ffe9,
	0x000000027,
	0x008000c71,
	0x000000027,
	0x090a20000,
	0x090a30001,
	0x024a50002,
	0x000031a00,
	0x000431025,
	0x008000c7a,
	0x0a4c2000a,
	0x024c20008,
	0x0afa20004,
	0x0afa40010,
	0x0afa40008,
	0x00c0014be,
	0x0afa6000c,
	0x08fa10010,
	0x0afa50010,
	0x0afa50008,
	0x020020040,
	0x00c0014df,
	0x0afa2000c,
	0x08fa30010,
	0x008000c7a,
	0x024650040,
	0x090a20000,
	0x090a30001,
	0x024a50002,
	0x000031a00,
	0x000431025,
	0x0a4c20002,
	0x024c20008,
	0x0afa20004,
	0x0afa50010,
	0x0afa50008,
	0x00c0014df,
	0x0afa7000c,
	0x08fa30010,
	0x08fa2001c,
	0x02424001c,
	0x02465001c,
	0x024420024,
	0x0afa20004,
	0x0afa40010,
	0x0afa40008,
	0x0afa50010,
	0x0afa50008,
	0x02002001c,
	0x00c0014be,
	0x00c0014df,
	0x0afa2000c,
	0x08fa10010,
	0x008000c42,
	0x02424001c,
	0x03841000b,
	0x010200023,
	0x08fa30010,
	0x08fa2001c,
	0x02465001c,
	0x024420040,
	0x0afa20004,
	0x0afa50010,
	0x0afa50008,
	0x02002001c,
	0x00c0014df,
	0x0afa2000c,
	0x08fa30010,
	0x008000c7a,
	0x02465001c,
	0x02443ffc2,
	0x01c600050,
	0x000000027,
	0x03841000c,
	0x010200013,
	0x01060003f,
	0x000000027,
	0x03841000d,
	0x010200003,
	0x03843003b,
	0x01060001d,
	0x000000027,
	0x008000c33,
	0x03843003c,
	0x01060000d,
	0x000000027,
	0x090810000,
	0x090820001,
	0x024840002,
	0x000021200,
	0x000220825,
	0x0a4a10002,
	0x090810000,
	0x090820001,
	0x024840002,
	0x000021200,
	0x000220825,
	0x008000c42,
	0x0a4a10004,
	0x090820000,
	0x090810001,
	0x024840002,
	0x000010a00,
	0x000411025,
	0x0a4a20002,
	0x090820000,
	0x090810001,
	0x024840002,
	0x000010a00,
	0x000411025,
	0x008000c42,
	0x0a4a2000a,
	0x090810000,
	0x090820001,
	0x024840002,
	0x000021200,
	0x000220825,
	0x0a4a10002,
	0x090810000,
	0x090820001,
	0x024840002,
	0x000021200,
	0x000220825,
	0x0a4a10004,
	0x090810000,
	0x090820001,
	0x090830002,
	0x000021200,
	0x000220825,
	0x000031c00,
	0x090820003,
	0x000230825,
	0x000021600,
	0x000220825,
	0x024840004,
	0x008000c42,
	0x0aca10010,
	0x090820000,
	0x090810001,
	0x024840002,
	0x000010a00,
	0x000411025,
	0x0a4a20002,
	0x024a2000c,
	0x03843003d,
	0x010600003,
	0x000000027,
	0x008000c71,
	0x000000027,
	0x090a20000,
	0x090a30001,
	0x024a50002,
	0x000031a00,
	0x000431025,
	0x008000c7a,
	0x0a4c20002,
	0x090a20000,
	0x090a30001,
	0x024a50002,
	0x000031a00,
	0x000431025,
	0x0a4c20002,
	0x090a20000,
	0x090a30001,
	0x024a50002,
	0x000031a00,
	0x000431025,
	0x008000c7a,
	0x0a4c20008,
	0x090a20000,
	0x090a30001,
	0x024a50002,
	0x000031a00,
	0x000431025,
	0x0a4c20002,
	0x090a20000,
	0x090a30001,
	0x090a40002,
	0x000031a00,
	0x000431025,
	0x000042400,
	0x090a30003,
	0x000441025,
	0x000031e00,
	0x000431025,
	0x0acc2000c,
	0x024a50004,
	0x090a20000,
	0x090a30001,
	0x090a40002,
	0x000031a00,
	0x000431025,
	0x000042400,
	0x090a30003,
	0x000441025,
	0x000031e00,
	0x000431025,
	0x024a50004,
	0x008000c7a,
	0x0acc20010,
	0x090a20000,
	0x090a30001,
	0x024a50002,
	0x000031a00,
	0x000431025,
	0x0a4c20002,
	0x024c2000c,
	0x0afa20004,
	0x0afa40010,
	0x0afa40008,
	0x00c0014be,
	0x0afa6000c,
	0x08fa10010,
	0x008000c42,
	0x02424001c,
	0x02441ffed,
	0x01c20003c,
	0x0afa50010,
	0x0afa50008,
	0x00c0014df,
	0x0afa7000c,
	0x08fa30010,
	0x008000c7a,
	0x02465001c,
	0x03843003f,
	0x010600011,
	0x000000027,
	0x038430040,
	0x010600003,
	0x000000027,
	0x008000c71,
	0x000000027,
	0x090a20000,
	0x090a30001,
	0x000000027,
	0x000031a00,
	0x000431025,
	0x0a4c20002,
	0x024a30002,
	0x024650001,
	0x080630000,
	0x008000c7a,
	0x0a0c30028,
	0x090a20000,
	0x090a30001,
	0x024a50002,
	0x000031a00,
	0x000431025,
	0x0a4c20002,
	0x090a20000,
	0x090a30001,
	0x090a40002,
	0x000031a00,
	0x000431025,
	0x000042400,
	0x090a30003,
	0x000441025,
	0x000031e00,
	0x000431025,
	0x0acc2000c,
	0x024a50004,
	0x090a20000,
	0x090a30001,
	0x090a40002,
	0x000031a00,
	0x000431025,
	0x000042400,
	0x090a30003,
	0x000441025,
	0x000031e00,
	0x000431025,
	0x024a50004,
	0x008000c7a,
	0x0acc20010,
	0x090a20000,
	0x090a30001,
	0x024a50002,
	0x000031a00,
	0x000431025,
	0x0a4c20002,
	0x090a20000,
	0x090a30001,
	0x090a40002,
	0x000031a00,
	0x000431025,
	0x000042400,
	0x090a30003,
	0x000441025,
	0x000031e00,
	0x000431025,
	0x0acc2000c,
	0x024a50004,
	0x090a20000,
	0x090a30001,
	0x090a40002,
	0x000031a00,
	0x000431025,
	0x000042400,
	0x090a30003,
	0x000441025,
	0x000031e00,
	0x000431025,
	0x024a50004,
	0x008000c7a,
	0x0acc20010,
	0x02443ffb7,
	0x01c6000c1,
	0x000000027,
	0x01020ffd4,
	0x0106000b8,
	0x000000027,
	0x03841000f,
	0x01020ffd1,
	0x02443ffbb,
	0x01c600078,
	0x000000027,
	0x038410010,
	0x010200029,
	0x010600064,
	0x000000027,
	0x038410011,
	0x01020ffcb,
	0x038430042,
	0x010600041,
	0x000000027,
	0x038410012,
	0x010200003,
	0x038430043,
	0x01060001f,
	0x000000027,
	0x008000c33,
	0x038430044,
	0x010600003,
	0x000000027,
	0x090820000,
	0x090810001,
	0x024840002,
	0x000010a00,
	0x000411025,
	0x0a4a20002,
	0x024a2000c,
	0x008000c71,
	0x000000027,
	0x090a20000,
	0x090a30001,
	0x024a50002,
	0x000031a00,
	0x000431025,
	0x0a4c20002,
	0x090a20000,
	0x090a30001,
	0x090a40002,
	0x000031a00,
	0x000431025,
	0x000042400,
	0x090a30003,
	0x000441025,
	0x000031e00,
	0x000431025,
	0x0acc20008,
	0x024a50008,
	0x090a20000,
	0x090a30001,
	0x024a50002,
	0x000031a00,
	0x000431025,
	0x008000c7a,
	0x0acc2000c,
	0x090a20000,
	0x090a30001,
	0x024a50002,
	0x000031a00,
	0x000431025,
	0x0a4c20002,
	0x090a20000,
	0x090a30001,
	0x090a40002,
	0x000031a00,
	0x000431025,
	0x000042400,
	0x090a30003,
	0x000441025,
	0x000031e00,
	0x000431025,
	0x0acc2000c,
	0x024a50004,
	0x090a20000,
	0x090a30001,
	0x090a40002,
	0x000031a00,
	0x000431025,
	0x000042400,
	0x090a30003,
	0x000441025,
	0x000031e00,
	0x000431025,
	0x024a50004,
	0x008000c7a,
	0x0acc20010,
	0x090a20000,
	0x090a30001,
	0x024a50002,
	0x000031a00,
	0x000431025,
	0x0a4c20002,
	0x024c2000c,
	0x0afa20004,
	0x0afa40010,
	0x0afa40008,
	0x00c0014be,
	0x0afa6000c,
	0x08fa5001c,
	0x08fa10010,
	0x000000027,
	0x02424001c,
	0x090820000,
	0x090810001,
	0x090830002,
	0x000010a00,
	0x000411025,
	0x000031c00,
	0x090810003,
	0x0afa50010,
	0x0afa50008,
	0x00c0014df,
	0x0afa7000c,
	0x08fa6001c,
	0x08fa30010,
	0x000000027,
	0x02465001c,
	0x090a20000,
	0x090a30001,
	0x090a40002,
	0x000031a00,
	0x000431025,
	0x000010e00,
	0x000411025,
	0x0aca20008,
	0x024810004,
	0x024240001,
	0x080210000,
	0x008000c42,
	0x0a0a10028,
	0x090820000,
	0x090810001,
	0x000000027,
	0x000010a00,
	0x000411025,
	0x0a4a20002,
	0x024810002,
	0x024240001,
	0x080210000,
	0x008000c42,
	0x0a0a10028,
	0x038410014,
	0x01020003b,
	0x000000027,
	0x038410015,
	0x010200022,
	0x000000027,
	0x038410016,
	0x010200003,
	0x000000027,
	0x008000c33,
	0x000000027,
	0x090820000,
	0x090810001,
	0x024840002,
	0x000010a00,
	0x000411025,
	0x0a4a20002,
	0x090820000,
	0x090810001,
	0x090830002,
	0x000010a00,
	0x000411025,
	0x000031c00,
	0x090810003,
	0x000042400,
	0x090a30003,
	0x000441025,
	0x000031e00,
	0x000431025,
	0x000010e00,
	0x000411025,
	0x0aca20008,
	0x024840008,
	0x090820000,
	0x090810001,
	0x024840002,
	0x000010a00,
	0x000411025,
	0x0aca2000c,
	0x0aca40010,
	0x08ca2000c,
	0x008000c42,
	0x000822021,
	0x090810000,
	0x090820001,
	0x024840002,
	0x000021200,
	0x000220825,
	0x0a4a10002,
	0x090810000,
	0x090820001,
	0x024840002,
	0x000021200,
	0x000220825,
	0x0a4a10004,
	0x090810000,
	0x090820001,
	0x024840002,
	0x000021200,
	0x000220825,
	0x0aca1000c,
	0x0aca40010,
	0x08ca1000c,
	0x008000c42,
	0x000812021,
	0x090820000,
	0x090810001,
	0x024840002,
	0x000010a00,
	0x000411025,
	0x0a4a20002,
	0x090820000,
	0x090810001,
	0x090830002,
	0x000010a00,
	0x000411025,
	0x000031c00,
	0x090810003,
	0x0acc20008,
	0x024a30004,
	0x024650001,
	0x080630000,
	0x008000c7a,
	0x0a0c30028,
	0x090a20000,
	0x090a30001,
	0x024a50002,
	0x000031a00,
	0x000431025,
	0x000010e00,
	0x000411025,
	0x0aca20008,
	0x024840008,
	0x090820000,
	0x090810001,
	0x024840002,
	0x000010a00,
	0x000411025,
	0x008000c42,
	0x0aca2000c,
	0x090820000,
	0x090810001,
	0x024840002,
	0x000010a00,
	0x000411025,
	0x0a4a20002,
	0x090820000,
	0x090810001,
	0x024840002,
	0x000010a00,
	0x000411025,
	0x0a4a20004,
	0x090820000,
	0x090810001,
	0x024840002,
	0x000010a00,
	0x000411025,
	0x008000c42,
	0x0aca2000c,
	0x02441ffe0,
	0x01c200059,
	0x000000027,
	0x01020004a,
	0x000000027,
	0x02441ffe4,
	0x01c200018,
	0x000000027,
	0x01020000f,
	0x000000027,
	0x038410018,
	0x01020000c,
	0x000000027,
	0x038410019,
	0x01020ff08,
	0x000000027,
	0x03841001a,
	0x01020ff38,
	0x000000027,
	0x03841001b,
	0x01020ff02,
	0x000000027,
	0x008000c33,
	0x000000027,
	0x090810000,
	0x090820001,
	0x024840002,
	0x000021200,
	0x000220825,
	0x008000c42,
	0x0a4a10002,
	0x03841001d,
	0x010200018,
	0x0a4c20002,
	0x090a20000,
	0x090a30001,
	0x000000027,
	0x03841001e,
	0x010200006,
	0x000031a00,
	0x000431025,
	0x0acc2000c,
	0x024a30002,
	0x024650001,
	0x0acc50010,
	0x08cc3000c,
	0x008000c7a,
	0x000a32821,
	0x038430046,
	0x01060001d,
	0x000000027,
	0x03841001f,
	0x01020fef0,
	0x038430047,
	0x01060000d,
	0x000000027,
	0x008000c33,
	0x038430048,
	0x010600003,
	0x000000027,
	0x090810000,
	0x090820001,
	0x024840002,
	0x000021200,
	0x000220825,
	0x0a4a10002,
	0x024a10008,
	0x0afa10004,
	0x0afa40010,
	0x0afa40008,
	0x00c0014be,
	0x0afa7000c,
	0x08fa20010,
	0x008000c42,
	0x024440040,
	0x090820000,
	0x090810001,
	0x024840002,
	0x000010a00,
	0x000411025,
	0x0a4a20002,
	0x090820000,
	0x090810001,
	0x024840002,
	0x000010a00,
	0x000411025,
	0x0a4a20004,
	0x024a20008,
	0x0afa20004,
	0x0afa40010,
	0x0afa40008,
	0x00c0014be,
	0x0afa7000c,
	0x08fa10010,
	0x008000c42,
	0x024240040,
	0x090810000,
	0x090820001,
	0x024840002,
	0x000021200,
	0x000220825,
	0x0a4a10002,
	0x090810000,
	0x090820001,
	0x024840002,
	0x000021200,
	0x000220825,
	0x008000c42,
	0x0a4a10004,
	0x02441ffdc,
	0x01c200045,
	0x000000027,
	0x01020ff75,
	0x000000027,
	0x038410021,
	0x01020002b,
	0x000000027,
	0x038410022,
	0x01020001b,
	0x000000027,
	0x038410023,
	0x010200003,
	0x000000027,
	0x008000c33,
	0x000000027,
	0x090820000,
	0x090810001,
	0x024840002,
	0x000010a00,
	0x000411025,
	0x0a4a20002,
	0x090820000,
	0x090810001,
	0x024840002,
	0x000010a00,
	0x000411025,
	0x0a4a20004,
	0x024a20008,
	0x0afa20004,
	0x0afa40010,
	0x0afa40008,
	0x00c0014be,
	0x0afa6000c,
	0x08fa10010,
	0x008000c42,
	0x02424001c,
	0x090810000,
	0x090820001,
	0x024840002,
	0x000021200,
	0x000220825,
	0x0a4a10002,
	0x090810000,
	0x090820001,
	0x024840002,
	0x000021200,
	0x000220825,
	0x008000c42,
	0x0a4a10008,
	0x090820000,
	0x090810001,
	0x024840002,
	0x000010a00,
	0x000411025,
	0x0a4a20002,
	0x090820000,
	0x090810001,
	0x024840002,
	0x000010a00,
	0x000411025,
	0x0a4a20004,
	0x024a20008,
	0x0afa20004,
	0x0afa40010,
	0x0afa40008,
	0x00c0014be,
	0x0afa7000c,
	0x08fa10010,
	0x008000c42,
	0x024240040,
	0x038410025,
	0x010200027,
	0x008000c71,
	0x000000027,
	0x038410026,
	0x010200006,
	0x090a20000,
	0x090a30001,
	0x024a50002,
	0x000031a00,
	0x000431025,
	0x008000c7a,
	0x0a4c20002,
	0x090a20000,
	0x090a30001,
	0x024a50002,
	0x000031a00,
	0x000431025,
	0x0a4c20002,
	0x090a20000,
	0x090a30001,
	0x024a50002,
	0x000031a00,
	0x000431025,
	0x008000c7a,
	0x0acc2000c,
	0x090a20000,
	0x090a30001,
	0x024a50002,
	0x000031a00,
	0x000431025,
	0x0a4c20002,
	0x090a20000,
	0x090a30001,
	0x090a40002,
	0x000031a00,
	0x000431025,
	0x000042400,
	0x090a30003,
	0x000441025,
	0x000031e00,
	0x000431025,
	0x0acc20008,
	0x024a50008,
	0x090a20000,
	0x090a30001,
	0x000000027,
	0x000031a00,
	0x000431025,
	0x0acc2000c,
	0x024a30002,
	0x024650001,
	0x0acc50010,
	0x08cc3000c,
	0x008000c7a,
	0x000a32821,
	0x090a20000,
	0x090a30001,
	0x024a50002,
	0x000031a00,
	0x000431025,
	0x008000c7a,
	0x0a4c20002,
	0x02443ffb3,
	0x01c600032,
	0x000000027,
	0x038410027,
	0x01020ff43,
	0x010600021,
	0x000000027,
	0x008000c33,
	0x03843004a,
	0x010600017,
	0x000000027,
	0x090810000,
	0x090820001,
	0x024840002,
	0x000021200,
	0x000220825,
	0x0a4a10002,
	0x090810000,
	0x090820001,
	0x090830002,
	0x000021200,
	0x000220825,
	0x000031c00,
	0x090820003,
	0x000230825,
	0x000021600,
	0x000220825,
	0x0aca10008,
	0x024840008,
	0x090810000,
	0x090820001,
	0x03843004b,
	0x01060000d,
	0x000000027,
	0x000021200,
	0x000220825,
	0x0aca1000c,
	0x024820002,
	0x024440001,
	0x0aca40010,
	0x08ca2000c,
	0x008000c42,
	0x000822021,
	0x090820000,
	0x090810001,
	0x024840002,
	0x000010a00,
	0x000411025,
	0x0a4a20002,
	0x090820000,
	0x090810001,
	0x024840002,
	0x000010a00,
	0x000411025,
	0x0a4a20004,
	0x090820000,
	0x090810001,
	0x000000027,
	0x000010a00,
	0x000411025,
	0x0aca2000c,
	0x024810002,
	0x024240001,
	0x0aca40010,
	0x08ca1000c,
	0x008000c42,
	0x000812021,
	0x023bdffec,
	0x0afbf0000,
	0x08fa40018,
	0x08fa1001c,
	0x03843004c,
	0x010600003,
	0x000000027,
	0x0afa10004,
	0x0afa40010,
	0x0afa40008,
	0x02001001c,
	0x00c0014be,
	0x0afa1000c,
	0x08fa4001c,
	0x08fa20010,
	0x008000c71,
	0x000000027,
	0x02445001c,
	0x090a10000,
	0x090a20001,
	0x090a30002,
	0x000021200,
	0x000220825,
	0x000031c00,
	0x090a20003,
	0x000230825,
	0x000021600,
	0x000220825,
	0x0ac81001c,
	0x024a20004,
	0x024450004,
	0x090a20000,
	0x090a10001,
	0x090a30002,
	0x000010a00,
	0x000411025,
	0x000031c00,
	0x090a10003,
	0x000431025,
	0x000010e00,
	0x000411025,
	0x0ac820024,
	0x024a50004,
	0x090a20000,
	0x090a10001,
	0x090a30002,
	0x000010a00,
	0x000411025,
	0x000031c00,
	0x090a10003,
	0x090a30001,
	0x024a50002,
	0x000031a00,
	0x000431025,
	0x000010e00,
	0x000411025,
	0x0ac820028,
	0x024a50004,
	0x008000c7a,
	0x0a4c20002,
	0x090a20000,
	0x090a10001,
	0x090a30002,
	0x000010a00,
	0x000411025,
	0x000031c00,
	0x090a10003,
	0x090a30001,
	0x024a50002,
	0x000031a00,
	0x000431025,
	0x000010e00,
	0x000411025,
	0x0ac82002c,
	0x024a50004,
	0x008000c7a,
	0x0a4c20002,
	0x090a20000,
	0x090a10001,
	0x090a30002,
	0x000010a00,
	0x000411025,
	0x000031c00,
	0x090a10003,
	0x090a30001,
	0x024a50002,
	0x000031a00,
	0x000431025,
	0x000010e00,
	0x000411025,
	0x0ac820034,
	0x024a50008,
	0x008000c7a,
	0x0a4c20002,
	0x090a20000,
	0x090a10001,
	0x090a30001,
	0x024a50002,
	0x000010a00,
	0x000411025,
	0x0a4820038,
	0x000031a00,
	0x000431025,
	0x0a4c20002,
	0x024c20008,
	0x0afa20004,
	0x0afa50010,
	0x0afa50008,
	0x00c0014df,
	0x0afa8000c,
	0x08fa30010,
	0x008000c7a,
	0x024650074,
	0x03843004e,
	0x01060000d,
	0x000000027,
	0x03843004f,
	0x010600003,
	0x000000027,
	0x008000c71,
	0x000000027,
	0x090a20000,
	0x090a10001,
	0x090a30001,
	0x024a50002,
	0x000010a00,
	0x000411025,
	0x0a482003a,
	0x000031a00,
	0x000431025,
	0x008000c7a,
	0x0a4c20002,
	0x090a20000,
	0x090a10001,
	0x090a30001,
	0x024a50002,
	0x000010a00,
	0x000411025,
	0x0a4820020,
	0x090a20000,
	0x090a10001,
	0x000031a00,
	0x000431025,
	0x0a4c20002,
	0x024c20008,
	0x0afa20004,
	0x0afa50010,
	0x0afa50008,
	0x00c0014df,
	0x0afa8000c,
	0x08fa30010,
	0x008000c7a,
	0x024650074,
	0x023bdffec,
	0x0afbf0000,
	0x08fa50018,
	0x08fa3001c,
	0x000000027,
	0x0afa30004,
	0x0afa50010,
	0x0afa50008,
	0x02003001c,
	0x00c0014df,
	0x0afa3000c,
	0x08fa20010,
	0x08fa3001c,
	0x02445001c,
	0x02463001c,
	0x0afa30004,
	0x0afa50010,
	0x0afa50008,
	0x02003001c,
	0x00c0014df,
	0x0afa3000c,
	0x08fa20010,
	0x08fa3001c,
	0x02445001c,
	0x024630038,
	0x0afa30004,
	0x0afa50010,
	0x0afa50008,
	0x02003001c,
	0x00c0014df,
	0x0afa3000c,
	0x08fa5001c,
	0x08fa20010,
	0x000000027,
	0x000010a00,
	0x000411025,
	0x0a4820022,
	0x02446001c,
	0x090c30000,
	0x090c20001,
	0x090c40002,
	0x000021200,
	0x000621825,
	0x000042400,
	0x090c20003,
	0x000641825,
	0x000021600,
	0x000621825,
	0x0aca30054,
	0x024c60004,
	0x090c30000,
	0x090c20001,
	0x090c40002,
	0x000021200,
	0x000621825,
	0x000042400,
	0x090c20003,
	0x000641825,
	0x000021600,
	0x000621825,
	0x0aca30058,
	0x024c60004,
	0x090c30000,
	0x090c20001,
	0x090c40002,
	0x000021200,
	0x000621825,
	0x000042400,
	0x090c20003,
	0x000641825,
	0x000021600,
	0x000621825,
	0x0aca3005c,
	0x024c60004,
	0x090c30000,
	0x090c20001,
	0x090c40002,
	0x000021200,
	0x000621825,
	0x000042400,
	0x090c20003,
	0x000641825,
	0x000021600,
	0x000621825,
	0x0aca30060,
	0x024c60004,
	0x090c30000,
	0x090c20001,
	0x090c40002,
	0x000021200,
	0x000621825,
	0x000042400,
	0x090c20003,
	0x000641825,
	0x000021600,
	0x000621825,
	0x0aca30064,
	0x024c60004,
	0x090c30000,
	0x090c20001,
	0x090c40002,
	0x000021200,
	0x000621825,
	0x000042400,
	0x090c20003,
	0x000641825,
	0x000021600,
	0x000621825,
	0x0aca3006c,
	0x024c60008,
	0x090c30000,
	0x090c20001,
	0x024c60002,
	0x000021200,
	0x000621825,
	0x0a4a30070,
	0x090c30000,
	0x090c20001,
	0x024c10002,
	0x000021200,
	0x000621825,
	0x0a4a30072,
	0x08fa20018,
	0x024a10002,
	0x000000027,
	0x000220823,
	0x08fa20000,
	0x000000027,
	0x000400008,
	0x023bd0014,
	0x023bdfffc,
	0x020010008,
	0x00000000c,
	0x003e00008,
	0x023bd0004,
	0x023bdfffc,
	0x020010002,
	0x00000000c,
	0x003e00008,
	0x023bd0004,
	0x023bdfffc,
	0x020010004,
	0x00000000c,
	0x003e00008,
	0x023bd0004,
	0x023bdfffc,
	0x020010016,
	0x00000000c,
	0x003e00008,
	0x023bd0004,
	0x023bdfffc,
	0x020010006,
	0x00000000c,
	0x003e00008,
	0x023bd0004,
	0x023bdfffc,
	0x020010007,
	0x00000000c,
	0x003e00008,
	0x023bd0004,
	0x023bdfffc,
	0x02001000d,
	0x00000000c,
	0x003e00008,
	0x023bd0004,
	0x023bdfffc,
	0x02001000e,
	0x00000000c,
	0x003e00008,
	0x023bd0004,
	0x023bdfffc,
	0x02001000f,
	0x00000000c,
	0x003e00008,
	0x023bd0004,
	0x023bdfffc,
	0x020010014,
	0x00000000c,
	0x003e00008,
	0x023bd0004,
	0x023bdfffc,
	0x08fc780b2,
	0x08fc780d2,
	0x083a2000b,
	0x028e3001e,
	0x03042007f,
	0x000022e00,
	0x000052e03,
	0x014600004,
	0x023c68502,
	0x023c68512,
	0x023bd0004,
	0x003e00008,
	0x020010001,


@@ 2803,7 2829,7 @@ ulong bootcode[]={
	0x000031e03,
	0x000661821,
	0x024e20001,
	0x0afc280b2,
	0x0afc280d2,
	0x0a0670000,
	0x000051600,
	0x000021603,


@@ 2827,7 2853,7 @@ ulong bootcode[]={
	0x08fc280d6,
	0x02011002a,
	0x0afa2001c,
	0x08fc3803e,
	0x08fc3806e,
	0x0200e002e,
	0x0afa30018,
	0x08fb00038,


@@ 2836,7 2862,7 @@ ulong bootcode[]={
	0x08fa3003c,
	0x000004825,
	0x02463ffff,
	0x0afc3803e,
	0x0afc3806e,
	0x000062825,
	0x080a50000,
	0x000000027,


@@ 2844,7 2870,7 @@ ulong bootcode[]={
	0x024c60001,
	0x014a00012,
	0x000000027,
	0x08fc3803e,
	0x08fc3806e,
	0x000000027,
	0x00203202b,
	0x014800002,


@@ 2856,12 2882,12 @@ ulong bootcode[]={
	0x0afc380d6,
	0x08fa20018,
	0x000000027,
	0x0afc2803e,
	0x0afc2806e,
	0x08fa20000,
	0x023bd0034,
	0x000400008,
	0x000100825,
	0x08fc3803e,
	0x08fc3806e,
	0x000000027,
	0x00203202b,
	0x010800005,


@@ 2870,14 2896,14 @@ ulong bootcode[]={
	0x026100001,
	0x0afd080d6,
	0x0a0450000,
	0x08fc2803a,
	0x08fc2806a,
	0x000000027,
	0x024420001,
	0x0afc2803a,
	0x0afc2806a,
	0x02002000a,
	0x014a20071,
	0x000000027,
	0x0afc9803a,
	0x0afc9806a,
	0x000062825,
	0x080a50000,
	0x000000027,


@@ 2893,14 2919,14 @@ ulong bootcode[]={
	0x000000027,
	0x014a00003,
	0x000000027,
	0x008000f16,
	0x008000f30,
	0x024c6ffff,
	0x014ae0006,
	0x000000027,
	0x014e80002,
	0x000000027,
	0x000093825,
	0x008000f47,
	0x008000f61,
	0x000097825,
	0x028a20031,
	0x01440001f,


@@ 2919,11 2945,11 @@ ulong bootcode[]={
	0x000000027,
	0x014a0ffe9,
	0x0000a3825,
	0x008000f16,
	0x008000f30,
	0x024c6ffff,
	0x014a0ffe5,
	0x0000a7825,
	0x008000f16,
	0x008000f30,
	0x024c6ffff,
	0x02002000a,
	0x001420018,


@@ 2933,22 2959,22 @@ ulong bootcode[]={
	0x024c60001,
	0x0afa60040,
	0x080a50000,
	0x008000f5e,
	0x008000f78,
	0x0246affd0,
	0x014b20005,
	0x000000027,
	0x010e80003,
	0x000000027,
	0x008000f5d,
	0x008000f77,
	0x000000027,
	0x014b10008,
	0x000000027,
	0x08d650000,
	0x014e80003,
	0x0256b0004,
	0x008000f47,
	0x008000f61,
	0x000053825,
	0x008000f47,
	0x008000f61,
	0x000057825,
	0x030a5007f,
	0x0afab0044,


@@ 2960,7 2986,7 @@ ulong bootcode[]={
	0x0afad0028,
	0x0afad0010,
	0x0afa50014,
	0x023c28502,
	0x023c28512,
	0x000451021,
	0x080420000,
	0x023c380e2,


@@ 2985,20 3011,20 @@ ulong bootcode[]={
	0x020130025,
	0x08fa40028,
	0x001211023,
	0x008000f47,
	0x008000f61,
	0x000826825,
	0x008000f16,
	0x008000f30,
	0x001615821,
	0x020020009,
	0x014a2ff66,
	0x000000027,
	0x08fc3803a,
	0x08fc3806a,
	0x000000027,
	0x024630007,
	0x0201cfff8,
	0x0007c1824,
	0x008000f16,
	0x0afc3803a,
	0x008000f30,
	0x0afc3806a,
	0x023bdfff0,
	0x0afbf0000,
	0x08fa40018,


@@ 3015,13 3041,13 @@ ulong bootcode[]={
	0x0afa20004,
	0x0afa40008,
	0x08fa2001c,
	0x00c0010a1,
	0x00c0010bb,
	0x0afa2000c,
	0x08fa20000,
	0x000000027,
	0x000400008,
	0x023bd0010,
	0x008000fc3,
	0x008000fdd,
	0x000042023,
	0x023bdffa8,
	0x0afbf0000,


@@ 3116,7 3142,7 @@ ulong bootcode[]={
	0x000000027,
	0x0afa30008,
	0x0afad000c,
	0x00c000fb8,
	0x00c000fd2,
	0x0afa70010,
	0x08fa10028,
	0x08fa20000,


@@ 3133,7 3159,7 @@ ulong bootcode[]={
	0x0a0640000,
	0x024a5ffff,
	0x001651021,
	0x008001021,
	0x00800103b,
	0x0a0520000,
	0x024a5ffff,
	0x001651021,


@@ 3141,7 3167,7 @@ ulong bootcode[]={
	0x0a0440000,
	0x024a5ffff,
	0x001651021,
	0x008001021,
	0x00800103b,
	0x0a0520000,
	0x030e30040,
	0x01060001c,


@@ 3161,26 3187,26 @@ ulong bootcode[]={
	0x000000027,
	0x01d000003,
	0x000000027,
	0x008001014,
	0x00800102e,
	0x000000027,
	0x01d400003,
	0x000000027,
	0x008001014,
	0x00800102e,
	0x000000027,
	0x030e30040,
	0x01460ffa5,
	0x024a5ffff,
	0x00149001b,
	0x00800100b,
	0x008001025,
	0x000003010,
	0x00149001b,
	0x00800104f,
	0x008001069,
	0x000005012,
	0x000158025,
	0x008001003,
	0x00800101d,
	0x0026a5023,
	0x08cca0000,
	0x008000ffe,
	0x008001018,
	0x0afa50028,
	0x08cc30000,
	0x0afa50028,


@@ 3188,13 3214,13 @@ ulong bootcode[]={
	0x000063403,
	0x000061400,
	0x000021403,
	0x008000ffe,
	0x008001018,
	0x000025025,
	0x08cca0000,
	0x008000ffe,
	0x008001018,
	0x0afa50028,
	0x08cca0000,
	0x008000ffe,
	0x008001018,
	0x0afa50028,
	0x038620030,
	0x010400009,


@@ 3202,24 3228,24 @@ ulong bootcode[]={
	0x038620048,
	0x010400003,
	0x000000027,
	0x008000ffc,
	0x008001016,
	0x000000027,
	0x08cc80000,
	0x008000ffe,
	0x008001018,
	0x0afa50028,
	0x08cc20000,
	0x0afa50028,
	0x000023400,
	0x000063403,
	0x030c3ffff,
	0x008000ffe,
	0x008001018,
	0x000035025,
	0x008000fed,
	0x008001007,
	0x02009000a,
	0x000158825,
	0x008000fed,
	0x008001007,
	0x000144825,
	0x008000fed,
	0x008001007,
	0x000164825,
	0x039220075,
	0x010400006,


@@ 3227,22 3253,22 @@ ulong bootcode[]={
	0x039220078,
	0x01040fff7,
	0x000000027,
	0x008000fed,
	0x008001007,
	0x000000027,
	0x02009000a,
	0x008000fed,
	0x008001007,
	0x034e70020,
	0x023bdfff0,
	0x0afbf0000,
	0x08fa30014,
	0x00c000857,
	0x00c00084a,
	0x0afa30004,
	0x08fad0014,
	0x0200efc18,
	0x08faa0018,
	0x0200c0020,
	0x08fc9803e,
	0x08fc8803a,
	0x08fc9806e,
	0x08fc8806a,
	0x08fa7001c,
	0x08fc680d6,
	0x000012825,


@@ 3285,8 3311,8 @@ ulong bootcode[]={
	0x0a06c0000,
	0x025080001,
	0x024a50001,
	0x0080010ca,
	0x0afc8803a,
	0x0080010e4,
	0x0afc8806a,
	0x000c9202b,
	0x010800005,
	0x000000027,


@@ 3297,12 3323,12 @@ ulong bootcode[]={
	0x025080001,
	0x02002000a,
	0x015620007,
	0x0afc8803a,
	0x0afc8806a,
	0x0000f4025,
	0x0afcf803a,
	0x0afcf806a,
	0x010eeffcd,
	0x000000027,
	0x0080010b3,
	0x0080010cd,
	0x024e7ffff,
	0x020020009,
	0x01562fffa,


@@ 3311,8 3337,8 @@ ulong bootcode[]={
	0x0201cfff8,
	0x0007c4024,
	0x010eeffc3,
	0x0afc8803a,
	0x0080010b3,
	0x0afc8806a,
	0x0080010cd,
	0x024e7ffff,
	0x000aa202a,
	0x01080ffbe,


@@ 3326,8 3352,8 @@ ulong bootcode[]={
	0x0a04c0000,
	0x025080001,
	0x024a50001,
	0x0080010f3,
	0x0afc8803a,
	0x00800110d,
	0x0afc8806a,
	0x023bdffec,
	0x0afbf0000,
	0x02004002a,


@@ 3340,7 3366,7 @@ ulong bootcode[]={
	0x023a30010,
	0x0afa30004,
	0x0afa00008,
	0x00c0010a1,
	0x00c0010bb,
	0x0afa2000c,
	0x08fa20000,
	0x023bd0014,


@@ 3358,7 3384,7 @@ ulong bootcode[]={
	0x08fa3001c,
	0x02002fc18,
	0x0afa30008,
	0x00c0010a1,
	0x00c0010bb,
	0x0afa2000c,
	0x08fa20000,
	0x023bd0014,


@@ 3378,7 3404,7 @@ ulong bootcode[]={
	0x000000027,
	0x0afa3000c,
	0x08fa20024,
	0x00c000fb8,
	0x00c000fd2,
	0x0afa20010,
	0x08fa20000,
	0x023bd0014,


@@ 3386,7 3412,7 @@ ulong bootcode[]={
	0x020010004,
	0x023bdfffc,
	0x08fc580d6,
	0x08fc2803e,
	0x08fc2806e,
	0x000000027,
	0x000a2202b,
	0x010800005,


@@ 3503,10 3529,10 @@ ulong bootcode[]={
	0x023a20034,
	0x0e7a10004,
	0x0e7a00008,
	0x00c001437,
	0x00c001442,
	0x0afa2000c,
	0x0c7c18056,
	0x0c7c0805a,
	0x0c7c18052,
	0x0c7c08056,
	0x0c7a20034,
	0x000000027,
	0x0468010a1,


@@ 3518,7 3544,7 @@ ulong bootcode[]={
	0x000023043,
	0x0afa60030,
	0x000061023,
	0x00c0013db,
	0x00c0013f5,
	0x0afa20004,
	0x0c7a30048,
	0x0c7a2004c,


@@ 3530,7 3556,7 @@ ulong bootcode[]={
	0x08fa30034,
	0x000000027,
	0x000431023,
	0x00c0013db,
	0x00c0013f5,
	0x0afa20004,
	0x08fad00b4,
	0x023ae0078,


@@ 3553,7 3579,7 @@ ulong bootcode[]={
	0x08fa30034,
	0x000000027,
	0x000431023,
	0x00c0013db,
	0x00c0013f5,
	0x0afa20004,
	0x08fad00b4,
	0x08fac00ac,


@@ 3562,10 3588,10 @@ ulong bootcode[]={
	0x0c7a2003c,
	0x000000027,
	0x046201182,
	0x0080011d6,
	0x0080011f0,
	0x023ae0078,
	0x0c7c1804a,
	0x0c7c0804e,
	0x0c7c1805e,
	0x0c7c08062,
	0x000000027,
	0x04626003e,
	0x000000027,


@@ 3579,7 3605,7 @@ ulong bootcode[]={
	0x08fa30034,
	0x000000027,
	0x000431023,
	0x00c0013db,
	0x00c0013f5,
	0x0afa20004,
	0x08fad00b4,
	0x08fac00ac,


@@ 3588,7 3614,7 @@ ulong bootcode[]={
	0x0c7a2003c,
	0x000000027,
	0x046201182,
	0x0080011ed,
	0x008001207,
	0x023ae0078,
	0x02003fc18,
	0x015830002,


@@ 3623,7 3649,7 @@ ulong bootcode[]={
	0x0200cffff,
	0x0afac00ac,
	0x0200d0065,
	0x0080011a3,
	0x0080011bd,
	0x0afad00b4,
	0x0c7a70048,
	0x0c7a6004c,


@@ 3637,7 3663,7 @@ ulong bootcode[]={
	0x08fa30034,
	0x02002ffff,
	0x000431023,
	0x00c0013db,
	0x00c0013f5,
	0x0afa20004,
	0x08fad00b4,
	0x023ae0078,


@@ 3659,7 3685,7 @@ ulong bootcode[]={
	0x000671823,
	0x00460012b,
	0x0afa7002c,
	0x00c0013db,
	0x00c0013f5,
	0x0afa30004,
	0x0c7a30040,
	0x0c7a20044,


@@ 3668,7 3694,7 @@ ulong bootcode[]={
	0x046201083,
	0x0e7a30004,
	0x0e7a20008,
	0x00c001399,
	0x00c0013b3,
	0x000000027,
	0x08fad00b4,
	0x023ae0078,


@@ 3717,7 3743,7 @@ ulong bootcode[]={
	0x024e70001,
	0x02484fff6,
	0x0a0440001,
	0x008001274,
	0x00800128e,
	0x024c6ffff,
	0x010e00007,
	0x0200b0001,


@@ 3785,7 3811,7 @@ ulong bootcode[]={
	0x020030030,
	0x0a0430000,
	0x024e7ffff,
	0x0080012bb,
	0x0080012d5,
	0x024c60001,
	0x019000013,
	0x000000027,


@@ 3805,7 3831,7 @@ ulong bootcode[]={
	0x0256b0001,
	0x0a0430000,
	0x02508ffff,
	0x0080012cc,
	0x0080012e6,
	0x024c60001,
	0x08fa300b0,
	0x000000027,


@@ 3834,7 3860,7 @@ ulong bootcode[]={
	0x0afa30008,
	0x0afa2000c,
	0x08fa300b0,
	0x00c000fb8,
	0x00c000fd2,
	0x0afa30010,
	0x08fa20000,
	0x023bd00a0,


@@ 3890,19 3916,19 @@ ulong bootcode[]={
	0x000001810,
	0x024630030,
	0x0a0430000,
	0x0080012f3,
	0x00800130d,
	0x024c60001,
	0x000061825,
	0x001231021,
	0x02003002b,
	0x0a0430000,
	0x008001314,
	0x00800132e,
	0x024c60001,
	0x000061025,
	0x001221821,
	0x020020065,
	0x0a0620000,
	0x00800130a,
	0x008001324,
	0x024c60001,
	0x020030067,
	0x011a30006,


@@ 3910,7 3936,7 @@ ulong bootcode[]={
	0x020030068,
	0x011a30003,
	0x000000027,
	0x0080012ed,
	0x008001307,
	0x000000027,
	0x024c7ffff,
	0x004e00006,


@@ 3930,11 3956,11 @@ ulong bootcode[]={
	0x000000027,
	0x01107ff93,
	0x000073025,
	0x0080012ed,
	0x008001307,
	0x024c60001,
	0x008001352,
	0x00800136c,
	0x02508ffff,
	0x00800134a,
	0x008001364,
	0x024e7ffff,
	0x08fa30034,
	0x02002ffff,


@@ 3944,7 3970,7 @@ ulong bootcode[]={
	0x000003825,
	0x08fa30034,
	0x0200d0068,
	0x0080012a8,
	0x0080012c2,
	0x001835023,
	0x08fa200b0,
	0x000000027,


@@ 3955,17 3981,17 @@ ulong bootcode[]={
	0x001221821,
	0x02002002b,
	0x0a0620000,
	0x008001299,
	0x0080012b3,
	0x024c60001,
	0x0c7c3804a,
	0x0c7c2804e,
	0x0c7c3805e,
	0x0c7c28062,
	0x000000027,
	0x046223182,
	0x0e7a70040,
	0x0e7a60044,
	0x0e7a70004,
	0x0e7a60008,
	0x00c001399,
	0x00c0013b3,
	0x000000027,
	0x08fad00b4,
	0x08fa8002c,


@@ 3983,14 4009,14 @@ ulong bootcode[]={
	0x046201181,
	0x0e7a70040,
	0x0e7a60044,
	0x00800126b,
	0x008001285,
	0x023ae0078,
	0x008001210,
	0x00800122a,
	0x0258cffff,
	0x020020001,
	0x0afa20014,
	0x025ad0020,
	0x0080011a3,
	0x0080011bd,
	0x0afad00b4,
	0x023bdffe8,
	0x0afbf0000,


@@ 4003,12 4029,12 @@ ulong bootcode[]={
	0x000000027,
	0x0c7a5001c,
	0x0c7a40020,
	0x023a1001c,
	0x023a2001c,
	0x04624c081,
	0x0e7a30004,
	0x0e7a20008,
	0x00c001486,
	0x0afa1000c,
	0x00c001491,
	0x0afa2000c,
	0x04620c032,
	0x000000027,
	0x045010007,


@@ 4033,11 4059,11 @@ ulong bootcode[]={
	0x023bd0018,
	0x0c7a3001c,
	0x0c7a20020,
	0x023a1001c,
	0x023a2001c,
	0x0e7a30004,
	0x0e7a20008,
	0x00c001486,
	0x0afa1000c,
	0x00c001491,
	0x0afa2000c,
	0x0c7a1001c,
	0x0c7a00020,
	0x08fa20000,


@@ 4052,7 4078,7 @@ ulong bootcode[]={
	0x04624c081,
	0x0e7a30004,
	0x0e7a20008,
	0x00c001399,
	0x00c0013b3,
	0x000000027,
	0x08fa20000,
	0x023bd000c,


@@ 4060,96 4086,81 @@ ulong bootcode[]={
	0x04620c001,
	0x023bdffec,
	0x0afbf0000,
	0x08fa30018,
	0x08fa40018,
	0x000000027,
	0x004610008,
	0x004810008,
	0x000000027,
	0x000030823,
	0x00c0013db,
	0x0afa10004,
	0x000041023,
	0x00c0013f5,
	0x0afa20004,
	0x08fa20000,
	0x023bd0014,
	0x000400008,
	0x04620e003,
	0x02862000a,
	0x01040000b,
	0x02883000a,
	0x01060000a,
	0x000000027,
	0x000031080,
	0x023c18006,
	0x000411021,
	0x08c420000,
	0x000000027,
	0x044820000,
	0x000041880,
	0x023c28006,
	0x000621821,
	0x08c630000,
	0x08fa20000,
	0x044830000,
	0x023bd0014,
	0x000400008,
	0x046800021,
	0x000032043,
	0x0afa40010,
	0x000641023,
	0x00c0013db,
	0x0afa20004,
	0x000042843,
	0x0afa50010,
	0x000851823,
	0x00c0013f5,
	0x0afa30004,
	0x0e7a10008,
	0x0e7a0000c,
	0x08fa10010,
	0x00c0013db,
	0x0afa10004,
	0x08fa20010,
	0x00c0013f5,
	0x0afa20004,
	0x0c7a30008,
	0x0c7a2000c,
	0x08fa20000,
	0x023bd0014,
	0x000400008,
	0x046220002,
	0x023bdfffc,
	0x083a4000f,
	0x08fa30008,
	0x01080000a,
	0x000000027,
	0x080610000,
	0x000000027,
	0x010200004,
	0x024630001,
	0x01424fffb,
	0x023bdfff8,
	0x083a60013,
	0x08fa4000c,
	0x000061600,
	0x000021603,
	0x01440000b,
	0x000000027,
	0x02461ffff,
	0x003e00008,
	0x023bd0004,
	0x030610003,
	0x010200008,
	0x000041825,
	0x080630000,
	0x000000027,
	0x080610000,
	0x010600003,
	0x024840001,
	0x008001425,
	0x000000027,
	0x01420fffa,
	0x024630001,
	0x023bd0004,
	0x023bd0008,
	0x003e00008,
	0x02461ffff,
	0x03c06ff00,
	0x03c0700ff,
	0x08c650000,
	0x02481ffff,
	0x000041025,
	0x080420000,
	0x000000027,
	0x000a60824,
	0x000a71024,
	0x010200010,
	0x024630004,
	0x01040000b,
	0x030a1ff00,
	0x010200006,
	0x030a200ff,
	0x01440fff5,
	0x000022e00,
	0x000052e03,
	0x01040000a,
	0x024840001,
	0x000051e00,
	0x000031e03,
	0x000061600,
	0x000021603,
	0x01462fff4,
	0x000000027,
	0x023bd0004,
	0x003e00008,
	0x02461ffff,
	0x023bd0004,
	0x003e00008,
	0x02461fffe,
	0x023bd0004,
	0x023bd0008,
	0x003e00008,
	0x02461fffd,
	0x023bd0004,
	0x02481ffff,
	0x023bd0008,
	0x003e00008,
	0x02461fffc,
	0x000000825,
	0x023bdfff4,
	0x0c7a70010,
	0x0c7a60014,


@@ 4283,119 4294,64 @@ ulong bootcode[]={
	0x08fa3000c,
	0x000000027,
	0x000610824,
	0x0080014a6,
	0x0080014b1,
	0x0afa1000c,
	0x023bdfffc,
	0x08fa30010,
	0x08fa40008,
	0x08fa5000c,
	0x000833021,
	0x028620004,
	0x000a4082b,
	0x014200036,
	0x000a33821,
	0x01440002a,
	0x000000027,
	0x000a40826,
	0x030210003,
	0x014200026,
	0x000000027,
	0x030810003,
	0x010200008,
	0x000000027,
	0x080a80000,
	0x023bdfff4,
	0x08fa80018,
	0x08fa7001c,
	0x08fa50010,
	0x08fa60014,
	0x000000027,
	0x0a0880000,
	0x024840001,
	0x030810003,
	0x01420fffa,
	0x024a50001,
	0x024c3fff1,
	0x00083082b,
	0x01020000d,
	0x000000027,
	0x08ca80000,
	0x08ca90004,
	0x0ac880000,
	0x08ca80008,
	0x0ac890004,
	0x08ca9000c,
	0x0ac880008,
	0x0ac89000c,
	0x024840010,
	0x00083082b,
	0x01420fff5,
	0x024a50010,
	0x024c3fffd,
	0x00083082b,
	0x010200008,
	0x000000027,
	0x08ca80000,
	0x000000027,
	0x0ac880000,
	0x024840004,
	0x00083082b,
	0x01420fffa,
	0x024a50004,
	0x010e50006,
	0x024e7ffff,
	0x004e0000b,
	0x000000027,
	0x080a80000,
	0x000061825,
	0x024c60001,
	0x080630000,
	0x000051025,
	0x0a0430000,
	0x01468fff7,
	0x024a50001,
	0x0a0880000,
	0x014e5fffc,
	0x024840001,
	0x08fa10008,
	0x023bd000c,
	0x003e00008,
	0x023bd0004,
	0x014400028,
	0x000000027,
	0x000e60826,
	0x030210003,
	0x014200024,
	0x000050825,
	0x023bd000c,
	0x003e00008,
	0x000000825,
	0x023bdfff4,
	0x08fa60014,
	0x08fa80010,
	0x08fa50018,
	0x000c8202b,
	0x01080000e,
	0x000000027,
	0x030e10003,
	0x010200007,
	0x001053821,
	0x000c53021,
	0x024a5ffff,
	0x004a00006,
	0x000000027,
	0x080e8ffff,
	0x024e7ffff,
	0x0a0c8ffff,
	0x030e10003,
	0x01420fffb,
	0x024c6ffff,
	0x024a3000f,
	0x00067082b,
	0x01020000d,
	0x000000027,
	0x08ce8fffc,
	0x08ce9fff8,
	0x0acc8fffc,
	0x08ce8fff4,
	0x0acc9fff8,
	0x08ce9fff0,
	0x024e7fff0,
	0x0acc8fff4,
	0x0acc9fff0,
	0x00067082b,
	0x01420fff5,
	0x024c6fff0,
	0x024a30003,
	0x00067082b,
	0x010200007,
	0x000000027,
	0x08ce8fffc,
	0x024e7fffc,
	0x0acc8fffc,
	0x00067082b,
	0x01420fffb,
	0x024c6fffc,
	0x010e5ffd3,
	0x000000027,
	0x080e8ffff,
	0x000000027,
	0x0a0c8ffff,
	0x024c6ffff,
	0x008001525,
	0x080c20000,
	0x024e7ffff,
	0x0080014e8,
	0x0a0e20000,
	0x023bd000c,
	0x003e00008,
	0x000080825,
	0x000083825,
	0x024a5ffff,
	0x004a00008,
	0x000000027,
	0x000062025,
	0x024c60001,
	0x080840000,
	0x000071825,
	0x0a0640000,
	0x0080014f4,
	0x024e70001,
	0x023bd000c,
	0x003e00008,
	0x000080825,
	0x000000000,
	0x000000000,
	0x000000001,


@@ 4408,18 4364,26 @@ ulong bootcode[]={
	0x000989680,
	0x005f5e100,
	0x03b9aca00,
	0x062616420,
	0x074797065,
	0x03a202564,
	0x00a006261,
	0x064207479,
	0x070653a20,
	0x025640a00,
	0x000000000,
	0x000000000,
	0x03fd34413,
	0x055475a32,
	0x000000000,
	0x040240000,
	0x000000000,
	0x000000000,
	0x000000000,
	0x000000000,
	0x000000000,
	0x040240000,
	0x000000000,
	0x000000000,
	0x03fd34413,
	0x055475a32,
	0x06e6f6e2d,
	0x07a65726f,
	0x020657869,


@@ 4442,24 4406,16 @@ ulong bootcode[]={
	0x000000000,
	0x000000000,
	0x000000007,
	0x062616420,
	0x074797065,
	0x03a202564,
	0x00a006261,
	0x064207479,
	0x070653a20,
	0x025640a00,
	0x000000000,
	0x000000000,
	0x0001fffff,
	0x07fffffff,
	0x000004404,
	0x00000451c,
	0x000003f40,
	0x0000045f8,
	0x00000444c,
	0x000004494,
	0x0000044e4,
	0x00000446c,
	0x000004584,
	0x000003fa8,
	0x000004660,
	0x0000044b4,
	0x0000044fc,
	0x00000454c,
	0x000000000,
	0x000000000,
	0x000000000,


@@ 4639,47 4595,51 @@ ulong bootcode[]={
	0x06e6f7000,
	0x06e6f7420,
	0x0526e6f70,
	0x000736573,
	0x000746167,
	0x0206e6f74,
	0x0207e3000,
	0x073657373,
	0x0696f6e2e,
	0x02e2e0077,
	0x072697465,
	0x020736573,
	0x073696f6e,
	0x02e2e2e00,
	0x077726974,
	0x065207365,
	0x07373696f,
	0x06e007265,
	0x061642073,
	0x065737369,
	0x06f6e0066,
	0x06f726d61,
	0x074207365,
	0x000726561,
	0x064207365,
	0x07373696f,
	0x06e006e6f,
	0x074205273,
	0x065737369,
	0x06f6e0065,
	0x072726f72,
	0x02025643b,
	0x00072656d,
	0x06f746520,
	0x06572726f,
	0x07200706f,
	0x073742e2e,
	0x02e002373,
	0x02f257300,
	0x063726561,
	0x074650025,
	0x064007772,
	0x069746500,
	0x023732f62,
	0x06f6f7400,
	0x063726561,
	0x074650025,
	0x064007772,
	0x069746500,
	0x06d6f756e,
	0x06e00666f,
	0x0726d6174,
	0x020736573,
	0x073696f6e,
	0x000746167,
	0x0206e6f74,
	0x0207e3000,
	0x0626f6f74,
	0x03a206572,
	0x0726f7220,
	0x025730a00,
	0x06e6f7420,
	0x052736573,
	0x073696f6e,
	0x000706f73,
	0x0742e2e2e,
	0x0002f002f,
	0x00062696e,
	0x064002f00,
	0x00023732f,
	0x025730063,
	0x072656174,
	0x065002564,
	0x000777269,
	0x074650023,
	0x0732f626f,
	0x06f740063,
	0x072656174,
	0x065002564,
	0x000777269,
	0x07465006d,
	0x06f756e74,
	0x02e2e2e00,
	0x02f002f00,
	0x062696e64,
	0x0002f0000,
	0x0006d6f75,
	0x06e740073,
	0x075636365,


@@ 4771,8 4731,8 @@ ulong bootcode[]={
	0x000000000,
	0x000000000,
	0x000000000,
	0x00004a90,
	0x000049f0,
	0x0,
	0x00004a90,
	0x000049f0,
	0x0,
};

M power/dat.h => power/dat.h +10 -11
@@ 89,7 89,6 @@ struct Bit3msg
};

#define	CHDIR	0x80000000L
#define	QPATH	0x0000FFFFL
struct Chan
{
	QLock;				/* general access */


@@ 102,17 101,17 @@ struct Chan
	ushort	dev;
	ushort	mode;			/* read/write */
	ushort	flag;
	ulong	qid;
	Qid	qid;
	Mount	*mnt;			/* mount point that derived Chan */
	ulong	mountid;
	int	fid;			/* for devmnt */
	union{
		Stream	*stream;	/* for stream channels */
		void	*aux;
		ulong	pgrpid;		/* for #p/notepg */
		Qid	pgrpid;		/* for #p/notepg */
	};
	Chan	*mchan;			/* channel to mounted server */
	ulong	mqid;			/* qid of root of mount point */
	Qid	mqid;			/* qid of root of mount point */
};

struct	FPsave


@@ 167,14 166,12 @@ struct Dev
	long	 (*write)(Chan*, void*, long);
	void	 (*remove)(Chan*);
	void	 (*wstat)(Chan*, char*);
	void	 (*errstr)(Error*, char*);
	void	 (*userstr)(Error*, char*);
};

struct Dirtab
{
	char	name[NAMELEN];
	ulong	qid;
	Qid	qid;
	long	length;
	long	perm;
};


@@ 252,12 249,11 @@ struct Orig
	PTE	*pte;
	Chan	*chan;			/* channel deriving segment (if open) */
	ushort	type;			/* of channel (which could be non-open) */
	ulong	qid;
	Qid	qid;
	Chan	*mchan;
	ulong	mqid;
	Qid	mqid;
	ulong	minca;			/* base of region in chan */
	ulong	maxca;			/* end of region in chan */
int nmod;
};

struct Page


@@ 351,7 347,7 @@ struct User
	Proc	*p;
	Label	errlab[NERR];
	int	nerrlab;
	Error	error;
	char	error[ERRLEN];
	FPsave	fpsave;			/* address of this is known by vdb */
	char	elem[NAMELEN];		/* last name element from namec */
	Chan	*slash;


@@ 636,6 632,9 @@ enum
};
extern	char	*statename[];

extern	char	user[NAMELEN];
extern	char	*errstrtab[];

/*
 * Chan flags
 */

M power/devbit3.c => power/devbit3.c +17 -29
@@ 69,10 69,10 @@ bit3clone(Chan *c, Chan *nc)
int	 
bit3walk(Chan *c, char *name)
{
	if(c->qid != CHDIR)
	if(c->qid.path != CHDIR)
		return 0;
	if(strcmp(name, "bit3") == 0){
		c->qid = 1;
		c->qid.path = 1;
		return 1;
	}
	return 0;


@@ 82,7 82,7 @@ void
bit3stat(Chan *c, char *dp)
{
	print("bit3stat\n");
	error(0, Egreg);
	error(Egreg);
}

Chan*


@@ 91,12 91,12 @@ bit3open(Chan *c, int omode)
	Bit3msg *bp;

	bp = &((User*)(u->p->upage->pa|KZERO))->kbit3;
	if(c->qid!=1 || omode!=ORDWR)
		error(0, Eperm);
	if(c->qid.path!=1 || omode!=ORDWR)
		error(Eperm);
	qlock(&bit3);
	if(bit3.open){
		qunlock(&bit3);
		error(0, Einuse);
		error(Einuse);
	}
	bit3send(bp, RESET, 0, 0);
	bit3.open = 1;


@@ 110,7 110,7 @@ bit3open(Chan *c, int omode)
void	 
bit3create(Chan *c, char *name, int omode, ulong perm)
{
	error(0, Eperm);
	error(Eperm);
}

void	 


@@ 135,22 135,24 @@ bit3read(Chan *c, void *buf, long n)
	Bit3msg *bp;
	int docpy;

	switch(c->qid){
	switch(c->qid.path){
	case 1:
		if(n > sizeof bit3.buf)
			error(0, Egreg);
			error(Egreg);
		if((((ulong)buf)&(KSEGM|3)) == KSEG0){
			/*
			 *  use supplied buffer, no need to lock for reply
			 */
			bp = &((User*)(u->p->upage->pa|KZERO))->kbit3;
			bp->rcount = 0;
qlock(&bit3.buflock); /* BUG */
			qlock(&bit3);
			bit3send(bp, READ, buf, n);
			qunlock(&bit3);
			do
				n = bp->rcount;
			while(n == 0);
qunlock(&bit3.buflock); /* BUG */
		}else{
			/*
			 *  use bit3 buffer.  lock the buffer till the reply


@@ 158,7 160,6 @@ bit3read(Chan *c, void *buf, long n)
			bp = &((User*)(u->p->upage->pa|KZERO))->ubit3;
			bp->rcount = 0;
			qlock(&bit3.buflock);

			qlock(&bit3);
			bit3send(bp, READ, bit3.buf, n);
			qunlock(&bit3);


@@ 166,12 167,11 @@ bit3read(Chan *c, void *buf, long n)
				n = bp->rcount;
			while(n == 0);
			memcpy(buf, bit3.buf, n);

			qunlock(&bit3.buflock);
		}
		return n;
	}
	error(0, Egreg);
	error(Egreg);
	return 0;
}



@@ 180,10 180,10 @@ bit3write(Chan *c, void *buf, long n)
{
	Bit3msg *bp;

	switch(c->qid){
	switch(c->qid.path){
	case 1:
		if(n > sizeof bit3.buf)
			error(0, Egreg);
			error(Egreg);
		if((((ulong)buf)&(KSEGM|3)) == KSEG0){
			bp = &((User*)(u->p->upage->pa|KZERO))->kbit3;
			qlock(&bit3);


@@ 203,30 203,18 @@ bit3write(Chan *c, void *buf, long n)
		}
		return n;
	}
	error(0, Egreg);
	error(Egreg);
	return 0;
}

void	 
bit3remove(Chan *c)
{
	error(0, Eperm);
	error(Eperm);
}

void	 
bit3wstat(Chan *c, char *dp)
{
	error(0, Eperm);
}

void
bit3userstr(Error *e, char *buf)
{
	consuserstr(e, buf);
}

void	 
bit3errstr(Error *e, char *buf)
{
	rooterrstr(e, buf);
	error(Eperm);
}

M power/devhotrod.c => power/devhotrod.c +12 -23
@@ 60,7 60,7 @@ hotrodgen(Chan *c, Dirtab *tab, int ntab, int i, Dir *dp)
{
	if(i || c->dev>=Nhotrod)
		return -1;
	devdir(c, 0, hotrod[c->dev].name, sizeof(Device), 0666, dp);
	devdir(c, (Qid){0,0}, hotrod[c->dev].name, sizeof(Device), 0666, dp);
	return 1;
}



@@ 100,7 100,7 @@ hotrodattach(char *spec)

	i = strtoul(spec, 0, 0);
	if(i >= Nhotrod)
		error(0, Ebadarg);
		error(Ebadarg);

	hp = &hotrod[i];
	if(hp->kprocstarted == 0)


@@ 108,7 108,8 @@ hotrodattach(char *spec)

	c = devattach('H', spec);
	c->dev = i;
	c->qid = CHDIR;
	c->qid.path = CHDIR;
	c->qid.vers = 0;
	return c;
}



@@ 146,9 147,9 @@ hotrodopen(Chan *c, int omode)
	dp->mem[256*1024/sizeof(ulong)] = (((ulong)&hp->pbuf) - KZERO) | (SLAVE<<28);
#endif

	if(c->qid == CHDIR){
	if(c->qid.path == CHDIR){
		if(omode != OREAD)
			error(0, Eperm);
			error(Eperm);
	}
	c->mode = openmode(omode);
	c->flag |= COPEN;


@@ 159,7 160,7 @@ hotrodopen(Chan *c, int omode)
void	 
hotrodcreate(Chan *c, char *name, int omode, ulong perm)
{
	error(0, Eperm);
	error(Eperm);
}

void	 


@@ 179,14 180,14 @@ hotrodread(Chan *c, void *buf, long n)
	ulong *to;
	ulong *end;

	if(c->qid&CHDIR)
	if(c->qid.path & CHDIR)
		return devdirread(c, buf, n, 0, 0, hotrodgen);

	/*
	 *  allow full word access only
	 */
	if((c->offset&(sizeof(ulong)-1)) || (n&(sizeof(ulong)-1)))
		error(0, Ebadarg);
		error(Ebadarg);

	hp = &hotrod[c->dev];
	dp = hp->addr;


@@ 225,7 226,7 @@ hotrodwrite(Chan *c, void *buf, long n)
	 *  allow full word access only
	 */
	if((c->offset&(sizeof(ulong)-1)) || (n&(sizeof(ulong)-1)))
		error(0, Ebadarg);
		error(Ebadarg);

	hp = &hotrod[c->dev];
	dp = hp->addr;


@@ 250,25 251,13 @@ hotrodwrite(Chan *c, void *buf, long n)
void	 
hotrodremove(Chan *c)
{
	error(0, Eperm);
	error(Eperm);
}

void	 
hotrodwstat(Chan *c, char *dp)
{
	error(0, Eperm);
}

void
hotroduserstr(Error *e, char *buf)
{
	consuserstr(e, buf);
}

void	 
hotroderrstr(Error *e, char *buf)
{
	rooterrstr(e, buf);
	error(Eperm);
}

void

M power/devhs.c => power/devhs.c +8 -20
@@ 162,13 162,13 @@ hsvmeattach(char *spec)

	i = strtoul(spec, 0, 0);
	if(i >= Nhsvme)
		error(0, Ebadarg);
		error(Ebadarg);
	hp = &hsvme[i];
	hsvmerestart(hp);

	c = devattach('h', spec);
	c->dev = i;
	c->qid = CHDIR;
	c->qid.path = CHDIR;
	return c;
}



@@ 193,9 193,9 @@ hsvmestat(Chan *c, char *dp)
Chan*
hsvmeopen(Chan *c, int omode)
{
	if(c->qid == CHDIR){
	if(c->qid.path == CHDIR){
		if(omode != OREAD)
			error(0, Eperm);
			error(Eperm);
	}else
		streamopen(c, &hsvmeinfo);
	c->mode = openmode(omode);


@@ 207,13 207,13 @@ hsvmeopen(Chan *c, int omode)
void	 
hsvmecreate(Chan *c, char *name, int omode, ulong perm)
{
	error(0, Eperm);
	error(Eperm);
}

void	 
hsvmeclose(Chan *c)
{
	if(c->qid != CHDIR)
	if(c->qid.path != CHDIR)
		streamclose(c);
}



@@ 232,25 232,13 @@ hsvmewrite(Chan *c, void *buf, long n)
void	 
hsvmeremove(Chan *c)
{
	error(0, Eperm);
	error(Eperm);
}

void	 
hsvmewstat(Chan *c, char *dp)
{
	error(0, Eperm);
}

void
hsvmeuserstr(Error *e, char *buf)
{
	consuserstr(e, buf);
}

void	 
hsvmeerrstr(Error *e, char *buf)
{
	rooterrstr(e, buf);
	error(Eperm);
}

/*

M power/fcall.h => power/fcall.h +30 -31
@@ 4,29 4,29 @@ struct	Fcall
{
	char	type;
	short	fid;
	short	err;
	short	tag;
	union
	{
		struct
		{
			short	uid;		/* T-Userstr */
			short	newfid;		/* T-Clone */
			char	lang;		/* T-Session */
			ulong	qid;		/* R-Attach, R-Walk, R-Open, R-Create */
			short	oldtag;		/* T-Flush */
			Qid	qid;		/* R-Attach, R-Walk, R-Open, R-Create */
		};
		struct
		{
			char	uname[28];	/* T-Attach, R-Userstr */
			char	aname[28];	/* T-Attach */
			char	uname[NAMELEN];	/* T-Attach */
			char	aname[NAMELEN];	/* T-Attach */
			char	auth[NAMELEN];	/* T-Attach */
		};
		struct
		{
			char	ename[64];	/* R-Errstr */
			char	ename[ERRLEN];	/* R-Error */
		};
		struct
		{
			long	perm;		/* T-Create */ 
			char	name[28];	/* T-Walk, T-Create, T-Remove */
			char	name[NAMELEN];	/* T-Walk, T-Create */
			char	mode;		/* T-Create, T-Open */
		};
		struct


@@ 46,40 46,36 @@ struct	Fcall

enum
{
	Tnop =		0,
	Tnop =		50,
	Rnop,
	Tsession =	2,
	Tsession =	52,
	Rsession,
	Tattach =	10,
/*	Terror =	54,	illegal */
	Rerror =	55,
	Tflush =	56,
	Rflush,
	Tattach =	58,
	Rattach,
	Tclone =	12,
	Tclone =	60,
	Rclone,
	Twalk =		14,
	Twalk =		62,
	Rwalk,
	Topen =		16,
	Topen =		64,
	Ropen,
	Tcreate =	18,
	Tcreate =	66,
	Rcreate,
	Toread =	20,
	Roread,
	Towrite =	22,
	Rowrite,
	Tclunk =	24,
	Tread =		68,
	Rread,
	Twrite =	70,
	Rwrite,
	Tclunk =	72,
	Rclunk,
	Tremove =	26,
	Tremove =	74,
	Rremove,
	Tstat =		28,
	Tstat =		76,
	Rstat,
	Twstat =	30,
	Twstat =	78,
	Rwstat,
	Terrstr =	32,
	Rerrstr,
	Tuserstr =	34,
	Ruserstr,
	Tread =		36,
	Rread,
	Twrite =	38,
	Rwrite,
};

int	convM2S(char*, Fcall*, int);


@@ 87,3 83,6 @@ int	convS2M(Fcall*, char*);

int	convM2D(char*, Dir*);
int	convD2M(Dir*, char*);

int	fcallconv(void *, int, int, int, int);
int	dirconv(void *, int, int, int, int);

M power/fns.h => power/fns.h +6 -5
@@ 33,7 33,7 @@ void	delete(List**, List*, List*);
void	delete0(List**, List*);
Chan	*devattach(int, char*);
Chan	*devclone(Chan*, Chan*);
void	devdir(Chan*, long, char*, long, long, Dir*);
void	devdir(Chan*, Qid, char*, long, long, Dir*);
long	devdirread(Chan*, char*, long, Dirtab*, int, Devgen*);
Devgen	devgen;
int	devno(int, int);


@@ 49,8 49,10 @@ void	duartxmit(int);
void	dumpregs(Ureg*);
void	dumpstack(void);
int	eqchan(Chan*, Chan*, long);
int	eqqid(Qid, Qid);
void	envpgclose(Env*);
void	error(Chan*, int);
void	error(int);
void	errors(char*);
void	evenaddr(ulong);
void	exit(void);
void	fault(Ureg*, int, int);


@@ 148,7 150,6 @@ ulong	pwait(Waitmsg*);
int	readlog(ulong, char*, ulong);
int	readnum(ulong, char*, ulong, ulong, int);
void	ready(Proc*);
void	rooterrstr(Error*, char*);
void	qlock(QLock*);
void	qunlock(QLock*);
void	restfpregs(FPsave*);


@@ 171,8 172,8 @@ int	spllo(void);
void	splx(int);
void	sunmap(int, uchar*);
Devgen	streamgen;
void	streamclose(Chan*);
void	streamclose1(Stream*);
int	streamclose(Chan*);
int	streamclose1(Stream*);
int	streamenter(Stream*);
int	streamexit(Stream*, int);
void	streaminit(void);

M power/main.c => power/main.c +2 -0
@@ 39,6 39,8 @@ char sysname[64];
 */
int ioid;

char	user[NAMELEN] = "bootes";

void
main(void)
{

M power/trap.c => power/trap.c +21 -20
@@ 327,7 327,6 @@ dumpregs(Ureg *ur)
	l = &ur->status;
	for(i=0; i<sizeof regname/sizeof(char*); i+=2, l+=2)
		print("%s\t%.8lux\t%s\t%.8lux\n", regname[i], l[0], regname[i+1], l[1]);
	dumpstack();
}

/*


@@ 396,26 395,26 @@ noted(Ureg **urp)
#include "/sys/src/libc/mips9sys/sys.h"

typedef long Syscall(ulong*);
Syscall sysaccess, sysbind, sysbrk_, syschdir, sysclose, syscreate;
Syscall sysbind, sysbrk_, syschdir, sysclose, syscreate, sysdeath;
Syscall	sysdup, syserrstr, sysexec, sysexits, sysfork, sysforkpgrp;
Syscall	sysfstat, sysfwstat, sysgetpid, syslasterr, sysmount, sysnoted;
Syscall	sysfstat, sysfwstat, sysgetpid, sysmount, sysnoted;
Syscall	sysnotify, sysopen, syspipe, sysr1, sysread, sysremove, sysseek;
Syscall syssleep, sysstat, sysuserstr, syswait, syswrite, syswstat;
Syscall syssleep, sysstat, syswait, syswrite, syswstat;

Syscall *systab[]={
	[SYSR1]		sysr1,
	[___ACCESS___]	sysaccess,
	[ERRSTR]	syserrstr,
	[BIND]		sysbind,
	[CHDIR]		syschdir,
	[CLOSE]		sysclose,
	[DUP]		sysdup,
	[ERRSTR]	syserrstr,
	[___ERRSTR___]	sysdeath,
	[EXEC]		sysexec,
	[EXITS]		sysexits,
	[FORK]		sysfork,
	[FORKPGRP]	sysforkpgrp,
	[FSTAT]		sysfstat,
	[LASTERR]	syslasterr,
	[___LASTERR___]	sysdeath,
	[MOUNT]		sysmount,
	[OPEN]		sysopen,
	[READ]		sysread,


@@ 426,7 425,7 @@ Syscall *systab[]={
	[WRITE]		syswrite,
	[PIPE]		syspipe,
	[CREATE]	syscreate,
	[USERSTR]	sysuserstr,
	[___USERSTR___]	sysdeath,
	[BRK_]		sysbrk_,
	[REMOVE]	sysremove,
	[WSTAT]		syswstat,


@@ 467,15 466,15 @@ syscall(Ureg *aur)
			msg = "sys: bad sys call";
	    Bad:
			postnote(u->p, 1, msg, NDebug);
			error(0, Ebadarg);
			error(Ebadarg);
		}
		if(sp & (BY2WD-1)){
			pprint("odd sp in sys call pc %lux sp %lux\n", ((Ureg*)UREGADDR)->pc, ((Ureg*)UREGADDR)->sp);
			msg = "sys: odd stack";
			goto Bad;
		}
		if(sp<(USTKTOP-BY2PG) || sp>(USTKTOP-4*BY2WD))
			validaddr(sp, 4*BY2WD, 0);
		if(sp<(USTKTOP-BY2PG) || sp>(USTKTOP-5*BY2WD))
			validaddr(sp, 5*BY2WD, 0);
		ret = (*systab[r1])((ulong*)(sp+2*BY2WD));
	}
	ur->pc += 4;


@@ 491,17 490,19 @@ syscall(Ureg *aur)
	return ret;
}

#include "errstr.h"

void
error(Chan *c, int code)
error(int code)
{
	if(c){
		u->error.type = c->type;
		u->error.dev = c->dev;
	}else{
		u->error.type = 0;
		u->error.dev = 0;
	}
	u->error.code = code;
	strncpy(u->error, errstrtab[code], NAMELEN);
	nexterror();
}

void
errors(char *err)
{
	strncpy(u->error, err, NAMELEN);
	nexterror();
}