Browse Source

Some previous cleaning for kernel (#744)

* Deleting old bootloader

Signed-off-by: Álvaro Jurado <elbingmiss@gmail.com>

* Reintroducing basic boot

Signed-off-by: Álvaro Jurado <elbingmiss@gmail.com>
Álvaro Jurado 6 years ago
parent
commit
c475af5a69
85 changed files with 5 additions and 27231 deletions
  1. 1 43
      sys/src/9/boot/aux.c
  2. 4 4
      sys/src/9/boot/bootconf.json
  3. 0 59
      sys/src/9/mk/mkenum
  4. 0 56
      sys/src/9/mk/mkenumb
  5. 0 15
      sys/src/9/mk/mkroot
  6. 0 31
      sys/src/9/mk/mkrootall
  7. 0 45
      sys/src/9/mk/mkrr
  8. 0 570
      sys/src/9/mk/parse
  9. 0 36
      sys/src/9/root/rcmain
  10. 0 129
      sys/src/9/w/pxeload/386l.h
  11. 0 132
      sys/src/9/w/pxeload/alarm.c
  12. 0 25
      sys/src/9/w/pxeload/apm.c
  13. 0 514
      sys/src/9/w/pxeload/boot.c
  14. 0 760
      sys/src/9/w/pxeload/bootp.c
  15. 0 147
      sys/src/9/w/pxeload/cga.c
  16. 0 314
      sys/src/9/w/pxeload/clock.c
  17. 0 596
      sys/src/9/w/pxeload/conf.c
  18. 0 235
      sys/src/9/w/pxeload/console.c
  19. 0 334
      sys/src/9/w/pxeload/dat.h
  20. 0 862
      sys/src/9/w/pxeload/devfloppy.c
  21. 0 205
      sys/src/9/w/pxeload/devfloppy.h
  22. 0 254
      sys/src/9/w/pxeload/dma.c
  23. 0 594
      sys/src/9/w/pxeload/dosboot.c
  24. 0 71
      sys/src/9/w/pxeload/dosfs.h
  25. 0 58
      sys/src/9/w/pxeload/error.h
  26. 0 280
      sys/src/9/w/pxeload/ether.c
  27. 0 1688
      sys/src/9/w/pxeload/ether2114x.c
  28. 0 548
      sys/src/9/w/pxeload/ether79c970.c
  29. 0 623
      sys/src/9/w/pxeload/ether8139.c
  30. 0 957
      sys/src/9/w/pxeload/ether8169.c
  31. 0 892
      sys/src/9/w/pxeload/ether82557.c
  32. 0 1175
      sys/src/9/w/pxeload/ether82563.c
  33. 0 1136
      sys/src/9/w/pxeload/etherbcm4401.c
  34. 0 57
      sys/src/9/w/pxeload/etherif.h
  35. 0 1728
      sys/src/9/w/pxeload/etherigbe.c
  36. 0 233
      sys/src/9/w/pxeload/ethermii.c
  37. 0 125
      sys/src/9/w/pxeload/ethermii.h
  38. 0 1050
      sys/src/9/w/pxeload/ethervgbe.c
  39. 0 192
      sys/src/9/w/pxeload/fns.h
  40. 0 103
      sys/src/9/w/pxeload/fs.c
  41. 0 45
      sys/src/9/w/pxeload/fs.h
  42. 0 355
      sys/src/9/w/pxeload/i8250.c
  43. 0 33
      sys/src/9/w/pxeload/ilock.c
  44. 0 208
      sys/src/9/w/pxeload/inflate.c
  45. 0 279
      sys/src/9/w/pxeload/io.h
  46. 0 109
      sys/src/9/w/pxeload/ip.h
  47. 0 516
      sys/src/9/w/pxeload/kbd.c
  48. 0 66
      sys/src/9/w/pxeload/kfs.h
  49. 0 265
      sys/src/9/w/pxeload/kfsboot.c
  50. 0 249
      sys/src/9/w/pxeload/l16r.s
  51. 0 172
      sys/src/9/w/pxeload/l32p.s
  52. 0 557
      sys/src/9/w/pxeload/l32v.s
  53. 0 85
      sys/src/9/w/pxeload/l64p.s
  54. 0 114
      sys/src/9/w/pxeload/lib.h
  55. 0 654
      sys/src/9/w/pxeload/load.c
  56. 0 185
      sys/src/9/w/pxeload/lxxx.s
  57. 0 259
      sys/src/9/w/pxeload/mbr.s
  58. 0 121
      sys/src/9/w/pxeload/mem.h
  59. 0 587
      sys/src/9/w/pxeload/memory.c
  60. 0 109
      sys/src/9/w/pxeload/mkfile
  61. 0 80
      sys/src/9/w/pxeload/mmu64.h
  62. 0 34
      sys/src/9/w/pxeload/multiboot.c
  63. 0 354
      sys/src/9/w/pxeload/part.c
  64. 0 372
      sys/src/9/w/pxeload/pbs.s
  65. 0 362
      sys/src/9/w/pxeload/pbslba.s
  66. 0 1020
      sys/src/9/w/pxeload/pci.c
  67. BIN
      sys/src/9/w/pxeload/ppxeload
  68. BIN
      sys/src/9/w/pxeload/ppxeloadacid
  69. 0 85
      sys/src/9/w/pxeload/print.c
  70. 0 53
      sys/src/9/w/pxeload/queue.c
  71. 0 362
      sys/src/9/w/pxeload/trap.c
  72. 0 36
      sys/src/9/w/pxeload/ureg.h
  73. 0 157
      sys/src/9/w/pxeload/warp64.c
  74. 0 168
      sys/src/9/w/pxeload/x16.h
  75. 0 1
      sys/src/9/w/words
  76. 0 20
      sys/src/boot/mkfile
  77. 0 71
      sys/src/boot/pc/dosfs.h
  78. 0 258
      sys/src/boot/pc/mbr.s
  79. 0 62
      sys/src/boot/pc/mkfile
  80. 0 371
      sys/src/boot/pc/pbs.s
  81. 0 344
      sys/src/boot/pc/pbsdebug.s
  82. 0 362
      sys/src/boot/pc/pbslba.s
  83. 0 327
      sys/src/boot/pc/pbslbadebug.s
  84. 0 320
      sys/src/boot/pc/pbsraw.s
  85. 0 168
      sys/src/boot/pc/x16.h

+ 1 - 43
sys/src/9/boot/aux.c

@@ -11,48 +11,6 @@
 #include <libc.h>
 #include <../boot/boot.h>
 
-int readline(char* bud, int len);
-
-/*
-int
-plumb(char *dir, char *dest, int *efd, char *here)
-{
-	char buf[128];
-	char name[128];
-	int n;
-
-	sprint(name, "%s/clone", dir);
-	efd[0] = open(name, ORDWR);
-	if(efd[0] < 0)
-		return -1;
-	n = read(efd[0], buf, sizeof(buf)-1);
-	if(n < 0){
-		close(efd[0]);
-		return -1;
-	}
-	buf[n] = 0;
-	sprint(name, "%s/%s/data", dir, buf);
-	if(here){
-		sprint(buf, "announce %s", here);
-		if(sendmsg(efd[0], buf) < 0){
-			close(efd[0]);
-			return -1;
-		}
-	}
-	sprint(buf, "connect %s", dest);
-	if(sendmsg(efd[0], buf) < 0){
-		close(efd[0]);
-		return -1;
-	}
-	efd[1] = open(name, ORDWR);
-	if(efd[1] < 0){
-		close(efd[0]);
-		return -1;
-	}
-	return efd[1];
-}
- */
-
 int
 sendmsg(int fd, char *msg)
 {
@@ -179,7 +137,7 @@ outin(char *prompt, char *def, int len)
 	}
 	print("%s[%s]: ", prompt, *def ? def : "no default");
 	memset(buf, 0, sizeof buf);
-	n = readline(buf, sizeof buf);
+	n = read(0, buf, len);
 
 	if(cpuflag){
 		alarm(0);

+ 4 - 4
sys/src/9/boot/bootconf.json

@@ -1,13 +1,13 @@
 {
 	"bootcpu": {
 		"Include": [
-			"/amd64/include/cflags.json"
+			"/$ARCH/include/cflags.json"
 		],
 		"Libs": [
 			"libboot.a",
-			"/amd64/lib/libip.a",
-			"/amd64/lib/libauth.a",
-			"/amd64/lib/libc.a"
+			"/$ARCH/lib/libip.a",
+			"/$ARCH/lib/libauth.a",
+			"/$ARCH/lib/libc.a"
 		],
 		"Oflags": [
 			"-e_main",

+ 0 - 59
sys/src/9/mk/mkenum

@@ -1,59 +0,0 @@
-#!$PLAN9/bin/rc
-
-awk '
-BEGIN{
-	oargc = 0;
-	for(argc = 1; argc < ARGC; argc++){
-		if(ARGV[argc] !~ /^-.+/ || ARGV[argc] ~ /--/)
-			break;
-		if(ARGV[argc] != "-D")
-			oargv[ARGV[argc]] = oargc++;
-		else
-			DEBUG = 1;
-		ARGV[argc] = "";
-	}
-}
-
-/^enum([ \t]*{|$)/{
-	inenum = 1;
-	if(DEBUG)
-		printf "inenum = 1\n";
-	next;
-}
-
-inenum && /^};$/{
-	if(DEBUG)
-		printf "inenum = 0\n";
-	inenum = 0;
-}
-
-inenum && $0 ~ /^[ \t]+[_A-Za-z][_0-9A-Za-z]+[ \t]+=[ \t]+[0-9A-Z_a-z()<> ]+,/{
-	tab = "\t";
-	if(length($1) < 8)
-		sep = tab tab;
-	else
-		sep = tab;
-	split($3, a, ",");
-	printf "#define %s%s%s", $1, sep, a[1];
-	if(match($0, /\/\*.*\*\/$/)){
-		len = length(a[1]);
-		sep = "";
-		while(len < 24){
-			sep = sep tab;
-			len += 8;
-		}
-		printf "%s%s", sep, substr($0, RSTART);
-	}
-	printf "\n"
-}
-
-!inenum && /^#(define|include) /{
-	printf "%s\n", $0;
-}
-
-/^$/{
-	printf "\n";
-}
-
-END{
-}' $*

+ 0 - 56
sys/src/9/mk/mkenumb

@@ -1,56 +0,0 @@
-BEGIN{
-	oargc = 0;
-	for(argc = 1; argc < ARGC; argc++){
-		if(ARGV[argc] !~ /^-.+/ || ARGV[argc] ~ /--/)
-			break;
-		if(ARGV[argc] != "-D")
-			oargv[ARGV[argc]] = oargc++;
-		else
-			DEBUG = 1;
-		ARGV[argc] = "";
-	}
-}
-
-/^enum([ \t]*{|$)/{
-	inenum = 1;
-	if(DEBUG)
-		printf "inenum = 1\n";
-	next;
-}
-
-inenum && /^};$/{
-	if(DEBUG)
-		printf "inenum = 0\n";
-	inenum = 0;
-}
-
-inenum && $0 ~ /^[ \t]+[_A-Za-z][_0-9A-Za-z]+[ \t]+=[ \t]+[0-9A-Z_a-z()<> ]+,/{
-	tab = "\t";
-	if(length($1) < 8)
-		sep = tab tab;
-	else
-		sep = tab;
-	split($3, a, ",");
-	gsub(/ull/, "", a[1])
-	printf "#define %s%s%s", $1, sep, a[1];
-	if(match($0, /\/\*.*\*\/$/)){
-		len = length(a[1]);
-		sep = "";
-		while(len < 24){
-			sep = sep tab;
-			len += 8;
-		}
-		printf "%s%s", sep, substr($0, RSTART);
-	}
-	printf "\n"
-}
-
-!inenum && /^#(define|include) /{
-	printf "%s\n", $0;
-}
-
-/^$/{
-	printf "\n";
-}
-
-END{}

+ 0 - 15
sys/src/9/mk/mkroot

@@ -1,15 +0,0 @@
-#!$PLAN9/bin/rc
-
-rfork e
-echo mkroot $*
-if(! ~ $#* 2){
-	echo usage: mkroot path name >[2=1]
-	exit 1
-}
-n=`{basename $1}
-cp $1 $2.out
-t=`{file $2.out}
-if(~ $"t *executable*)
-	strip $2.out
-	data2c $2 < $2.out > $2.root.c
-echo mkroot $* done

+ 0 - 31
sys/src/9/mk/mkrootall

@@ -1,31 +0,0 @@
-#!$PLAN9/bin/rc
-
-rfork e
-n=`{echo $#*^'%3' | hoc}
-if(! ~ $n 0){
-	echo 'usage: mkrootall [name cname file]...' >[1=2]
-	exit usage
-}
-
-tmp=mkroot.$pid.out
-fn sigexit {
-	rm -f $tmp
-}
-
-allcname=()
-while(! ~ $#* 0){
-	name=$1
-	cname=$2
-	file=$3
-	shift
-	shift 
-	shift
-	allcname=($allcname $cname)
-	cp $file $tmp
-	t=`{file $tmp}
-	# do not strip venti - it uses its own symbols
-	if(~ $"t *executable* && ! ~ $name venti)
-#		strip $tmp
-		data2c $cname < $tmp
-}
-exit 0

+ 0 - 45
sys/src/9/mk/mkrr

@@ -1,45 +0,0 @@
-#!$PLAN9/bin/rc
-
-rfork en
-
-switch($#*){
-case 1
-	PROTO=$1.proto
-case 2
-	PROTO=$2
-case *
-	echo $0: usage: $0 conf [proto]
-	exit "usage"
-}
-
-ramfs -S ramfs.$pid
-mount -c /srv/ramfs.$pid /tmp
-mkdir /tmp/mnt /tmp/empty
-
-# clean up files and procs on exit
-fn sigexit {
-	echo sync>>/srv/flcons.$pid
-	unmount /tmp/mnt
-	unmount /tmp
-	echo halt>>/srv/flcons.$pid
-	rm -f /srv/*.$pid
-	kill ramfs fossil|rc
-}
-
-{syscall seek 1 8388608 0; echo} >>/tmp/fldisk |[0=2] grep -v 'no error$'
-fossil/flfmt -b 4096 -y /tmp/fldisk
-
-fossil/conf -w /tmp/fldisk <<CONF-EOF
-fsys main config /tmp/fldisk
-fsys main open -AWPV
-fsys main 
-srv -p flcons.$pid
-srv fldisk.$pid
-uname bootes :bootes
-uname sys +bootes
-users -w
-CONF-EOF
-fossil/fossil -f /tmp/fldisk && mount -c /srv/fldisk.$pid /tmp/mnt
-
-disk/mkfs -d /tmp/mnt -U $PROTO
-mkpaqfs -l $1.rr -o ./$1.rr /tmp/mnt

+ 0 - 570
sys/src/9/mk/parse

@@ -1,570 +0,0 @@
-BEGIN{
-	oargc = 0;
-	for(argc = 1; argc < ARGC; argc++){
-		if(ARGV[argc] !~ /^-.+/ || ARGV[argc] ~ /--/)
-			break;
-		if(ARGV[argc] != "-D")
-			oargv[ARGV[argc]] = oargc++;
-		else
-			DEBUG = 1;
-		ARGV[argc] = "";
-	}
-#	objtype = ENVIRON["objtype"];
-	objtype = "amd64";
-
-	while(getline > 0){
-		if(/^[ \t]*$/ || /^#/)
-			continue;
-
-		if(/^[^ \t]/){
-			#section[$1] = 0;
-			tag = $1;
-		}
-		if(!tag)
-			continue;
-		sub(/^[ \t]*/, "");
-		line[tag, section[tag]++] = $0;
-	}
-
-	o = "";
-	if(!oargc || ("-mkdevlist" in oargv)){
-		s = mkdevlist();
-		if(!("-mkdevlist" in oargv) || (oargc > 1))
-			s = "DEVS=" s;
-		o = o s "\n";
-	}
-	if((!oargc || ("-mkmach" in oargv)) && (objtype in section)){
-		s = mkmach();
-		if(!("-mkmach" in oargv) || (oargc > 1))
-			s = "MACH=" s;
-		o = o s "\n";
-	}
-	if((!oargc || ("-mklib" in oargv)) && ("lib" in section)){
-		s = mklib();
-		if(!("-mklib" in oargv) || (oargc > 1))
-			s = "LIB=" s;
-		o = o s "\n";
-	}
-	if((!oargc || ("-mkport" in oargv) ) && ("port" in section)){
-		s = mkport();
-		if(!("-mkport" in oargv) || (oargc > 1))
-			s = "PORT=" s;
-		o = o s "\n";
-	}
-	if("dbgflg" in section){
-		for(i = 1; i < section["dbgflg"]; i++){
-			n = split(line["dbgflg", i], a);
-			if(n < 2 || n > 4 || a[2] !~ /'[a-zA-Z]'/)
-				continue;
-			if(n > 2 && a[3] !~ /'[a-zA-Z]'/)
-				continue;
-			if(n == 4 && (a[4] < 1 || a[4] >= 128))
-				continue;
-			dbgc[a[1]] = a[2];
-			if(n == 4)
-				dbgflg[a[3]] = a[4];
-			else if(n == 3)
-				dbgflg[a[3]] = 1;
-		}
-	}
-	if((!oargc || ("-mkrules" in oargv)) && ("dir" in section)){
-		o = o mkrules(".", exists, a, c, "-I.");
-		for(i = 1; i < section["dir"]; i++){
-			n = split(line["dir", i], a);
-			dir = "../" a[1];
-			if(n == 1)
-				a[2] = "-I.";
-			s = a[2];
-			o = o mkrules(dir, exists, a, c, s);
-			l = listolate(a, "|");
-			if(l != ""){
-				o = o "^(" l ")\\.$O:R:	" dir "/\\1.s\n";
-				o = o "\t$AS $AFLAGS -o /$stem1.o " s " -c " dir "/$stem1.s\n";
-			}
-			l = listolate(c, "|");
-			if(l != ""){
-				o = o "^(" l ")\\.$O:R:	" dir "/\\1.c\n";
-				o = o "\t$CC $CFLAGS " s " -c " dir "/$stem1.c\n";
-			}
-		}
-	}
-	if((!oargc || ("-mkrootrules" in oargv)) && ("rootdir" in section)){
-		mkrootrules(name, cname, src);
-		s = ARGV[argc] ".root.c:D:";
-		for(i = 1; i < section["rootdir"]; i++)
-			s = s " " src[i];
-		s = s "\n\t../mk/mkrootall\\\n";
-		for(i = 1; i < section["rootdir"]; i++)
-			s = s "\t\t" name[i] " " cname[i] " " src[i] "\\\n";
-		s = s "\t>$target\n";
-		if(section["rootdir"] > 1)
-			o = o s;
-	}
-	if((!oargc || ("-mkrrrules" in oargv)) && ("rr" in section)){
-		n = split(line["rr", 0], a);
-		if(n == 1)
-			a[2] = ARGV[argc] ".proto";
-		s = "$CONF.rr:\t../mk/mkrr $CONF " a[2] "\n";
-		s = s "\t../mk/mkrr $CONF " a[2] "\n";
-		for(i = 1; i < section["rr"]; i++)
-			s = s "$CONF.rr:\t" line["rr", i] "\n";
-		o = o s;
-	}
-	if("-mkdevc" in oargv)
-		o = o mkdevc();
-	if("-mkerrstr" in oargv)
-		o = o mkerrstr();
-	if("-mksystab" in oargv)
-		o = o mksystab();
-	if("-mkbootconf" in oargv)
-		o = o mkbootconf();
-
-	#
-	# to do:
-	#	bootmkfile
-	#	mkrootall (can it be done at all?)
-	#
-	printf o;
-
-	exit 0;
-}
-
-function mkbootconf(				a, n, s, t, u, c, d, p, r){
-	s = "#include <u.h>\n";
-	s = s "#include <libc.h>\n\n";
-	s = s "#include \"../boot/boot.h\"\n\n";
-	s = s "Method method[] = {\n";
-
-	c = "0";
-	d = "#S/sdC0/";
-	p = "boot";
-	r = "/root";
-
-	for(i = 0; i < section["boot"]; i++){		# NOTE: start at 0
-		n = split(line["boot", i], a);
-		if(a[1] == "boot"){
-			if(a[2] == "cpu"){
-				c = "1";
-				if(n == 4 && a[3] == "boot")
-					d = a[4];
-			}
-			else if(a[2] == "rootdir" && n == 3)
-				r = a[3];
-			else if(a[2] ~ /^(bboot|dosboot|romboot)$/){
-				c = "1";
-				p = a[2];
-			}
-			else if(a[2] == "boot" && n == 3)
-				d = a[3];
-			continue;
-		}
-		s = s "\t{ \"" a[1] "\", config" a[1] ", connect" a[1] ", ";
-		t = "nil";
-		if(n > 1){
-			u = line["boot", i];
-			if(sub(/^[_A-Za-z][_A-Za-z0-9]*[ \t]*/, "", u)){
-				if(match(u, /^".*"$/))
-					u = substr(u, RSTART+1, RLENGTH-2);
-				t = "\"" u "\"";
-			}
-		}
-		s = s t ", },\n";
-	}
-	s = s "\t{ nil },\n};\n\n";
-	s = s "int cpuflag = " c ";\n";
-	s = s "char* rootdir = \"" r "\";\n";
-	s = s "char* bootdisk = \"" d "\";\n";
-	s = s "extern void " p "(int, char**);\n\n";
-	s = s "void\nmain(int argc, char **argv)\n";
-	s = s "{\n\t" p "(argc, argv);\n}\n"
-
-	t = "int (*cfs)(int) = 0;\n";
-	for(i = 1; i < section["rootdir"]; i++){
-		if($1 !~ /\/bin\/cfs$/)
-			continue;
-		t = "int (*cfs)(int) = cache;\n";
-		break;
-	}
-	s = s t;
-
-	return s;
-}
-
-function mksystab(					a, i, f, n, s, t){
-	s = "#include \"u.h\"\n";
-	s = s "#include \"../port/lib.h\"\n";
-	s = s "#include \"mem.h\"\n";
-	s = s "#include \"dat.h\"\n";
-	s = s "#include \"fns.h\"\n\n";
-#	s = s "#include \"/sys/src/libc/9syscall/sys.h\"\n\n";
-
-	s = s "#include \"../../libc/9syscall/sys.h\"\n\n";
-
-	t = "";
-	while(getline < "../../libc/9syscall/sys.h"){
-		if($1 != "#define" || NF != 3)
-			continue;
-
-		f = "sys" tolower($2);
-		if($2 == "SYSR1")
-			f = "sysr1";
-		if($2 == "RENDEZVOUS")
-			n = "Rendez";
-		else if($2 == "BRK_")
-			n = "Brk";
-		else
-			n = substr($2, 1, 1) tolower(substr($2, 2));
-
-		s = s "extern void " f "(Ar0*, ...);\n";
-		t = t "\t[" $2 "]\t";
-		if(length($2) < 6)
-			t = t "\t";
-		t = t "{ \"" n "\", " f ", ";
-		#
-		# The following should really be defined properly in the
-		# manual and code, but changing Plan 9 now is too awkward.
-		# It will matter more when sizeof(long) != sizeof(int).
-		#
-		# if($2 ~ "(FVERSION|STAT|FSTAT|WSTAT|FWSTAT|AWAIT)")
-		#	t = t "{ .u = 0 } },\n";
-		#
-		# if($2 ~ "(BIND|_MOUNT|MOUNT)")
-		#	t = t "{ .l = -1 } },\n";
-		#
-		if($2 ~ "(EXEC|SEGBRK|SEGATTACH|RENDEZVOUS)")
-			t = t "{ .v = (void*)-1 } },\n";
-		else if($2 ~ "(ALARM|_READ|_WRITE|PREAD|PWRITE)")
-			t = t "{ .l = -1 } },\n";
-		else if($2 ~ "(NSEC)")
-			t = t "{ .vl = -1LL } },\n";
-		else
-			t = t "{ .i = -1 } },\n";
-	}
-	if("syscall" in section){
-		for(i = 1; i < section["syscall"]; i++){
-			if(split(line["syscall", i], a) != 8)
-				continue;
-			if(line["syscall", i] !~ /#define.*{ \.[ilpuv] = .* }$/)
-				continue;
-
-			f = "sys" tolower(a[2]);
-			n = substr(a[2], 1, 1) tolower(substr(a[2], 2));
-
-			s = s "\nSyscall " f ";\n";
-			t = t a[1] " " a[2] "\t" a[3] "\n\t[" a[2] "]\t";
-			if(length(a[2]) < 6)
-				t = t "\t";
-			split(line["syscall", i], a, "{");
-			t = t "{ \"" n "\", " f ", {" a[2] " },\n";
-		}
-	}
-	#s = s "struct {\n\tchar*\tn;\n\tvoid (*f)(Ar0*, ...);\n\tAr0\tr;\n}";
-	s = s " systab_t systab = {\n" t "};\n\nint nsyscall = nelem(systab);\n";
-
-	return s;
-}
-
-function mkerrstr(					a, s){
-	FS="[ \t;]+";
-	while(getline < "../port/error.h"){
-		split($0, a, /\/\* | \*\//);
-		s = s $2 " " $3 " = \"" a[2] "\";\n";
-	}
-	FS=" ";
-
-	return s;
-}
-
-function mkdevc(		a, d, i, m, n, s, t, u, name, cname){
-	s = "#include \"u.h\"\n";
-	s = s "#include \"../port/lib.h\"\n";
-	s = s "#include \"mem.h\"\n";
-	s = s "#include \"dat.h\"\n";
-	s = s "#include \"fns.h\"\n";
-	s = s "#include \"../port/error.h\"\n\n";
-	s = s "#include \"io.h\"\n\n";
-
-	t = "";
-	for(i = 1; i < section["dev"]; i++){
-		split(line["dev", i], a);
-		s = s "extern Dev " a[1] "devtab;\n";
-		t = t "\t&" a[1] "devtab,\n";
-		d[a[1]]++;
-	}
-	s = s "Dev* devtab[] = {\n" t "\tnil,\n};\n\n";
-
-	mkrootrules(name, cname, m);
-	t = "";
-	for(i = 1; i < section["rootdir"]; i++){
-		s = s "extern unsigned char " cname[i] "code[];\n";
-		s = s "extern usize " cname[i] "len;\n";
-		t = t "\taddbootfile(\"" name[i] "\", " cname[i] "code, " cname[i] "len);\n";
-	}
-	for(i = 1; i < section["link"]; i++){
-		split(line["link", i], a);
-		s = s "extern void " a[1] "link(void);\n";
-		t = t "\t" a[1] "link();\n";
-	}
-	s = s "void\nlinks(void)\n{\n" t "}\n\n";
-
-	if("ip" in d && "ip" in section){
-		t = "";
-		s = s "#include \"../ip/ip.h\"\n";
-		for(i = 1; i < section["ip"]; i++){
-			split(line["ip", i], a);
-			s = s "extern void " a[1] "init(Fs*);\n";
-			t = t "\t" a[1] "init,\n";
-		}
-		s = s "void (*ipprotoinit[])(Fs*) = {\n" t "\tnil,\n};\n\n";
-	}
-
-	if("sd" in d && "sd" in section){
-		t = "";
-		s = s "#include \"../port/sd.h\"\n";
-		for(i = 1; i < section["sd"]; i++){
-			split(line["sd", i], a);
-			s = s "extern SDifc " a[1] "ifc;\n";
-			t = t  "\t&" a[1] "ifc,\n";
-		}
-		s = s "SDifc* sdifc[] = {\n" t "\tnil,\n};\n\n";
-	}
-
-	if("uart" in d && "uart" in section){
-		t = "";
-		for(i = 1; i < section["uart"]; i++){
-			split(line["uart", i], a);
-			a[1] = substr(a[1], 5, length(a[1])-4) "physuart";
-			s = s "extern PhysUart " a[1] ";\n";
-			t = t  "\t&" a[1] ",\n";
-		}
-		s = s "PhysUart* physuart[] = {\n" t "\tnil,\n};\n\n";
-	}
-
-	t = "";
-	n = 0;
-	if("physseg" in section){
-		for(i = 1; i < section["physseg"]; i++){
-			u = line["physseg", i];
-			if(u ~ /^\.[_A-Za-z][_A-Za-z0-9]*/)
-				t = t "\t";
-			t = t "\t" u "\n";
-			if(sub(/.*\.pgalloc.*=[^_A-Za-z]*/, "", u)){
-				if(match(u, /^[_A-Za-z][_A-Za-z0-9]*/)){
-					u = substr(u, RSTART, RLENGTH);
-					s = s "extern Page *(*" u ")(Segment*, uintptr);\n";
-				}
-			}
-			else if(sub(/.*\.pgfree.*=[^_A-Za-z]*/, "", u)){
-				if(match(u, /^[_A-Za-z][_A-Za-z0-9]*/)){
-					u = substr(u, RSTART, RLENGTH);
-					s = s "extern void (*" u ")(Page*);\n";
-				}
-			}
-			if(match(u, /}/))
-				n++;
-		}
-	}
-	s = s "Physseg physseg[" n+8 "] = {\n";
-	s = s "\t{\t.attr\t= SG_SHARED,\n";
-	s = s "\t\t.name\t= \"shared\",\n";
-	s = s "\t\t.size\t= SEGMAXPG,\n\t},\n";
-	s = s "\t{\t.attr\t= SG_BSS,\n";
-	s = s "\t\t.name\t= \"memory\",\n";
-	s = s "\t\t.size\t= SEGMAXPG,\n\t},\n";
-	s = s t "};\nint nphysseg = " n+8 ";\n\n";
-
-	s = s "char dbgflg[256]";
-	t = "";
-	for(u in dbgflg)
-		t = t "\t[" u "]\t" dbgflg[u] ",\n";
-	if(t != "")
-		s = s " = {\n" t "}";
-	s = s ";\n\n";
-
-	for(i in m)
-		delete m[i];
-
-	for(i = 1; i < section["misc"]; i++){
-		split(line["misc", i], a);
-		m[a[1]] = line["misc", i];
-	}
-	if("cache" in m){
-		s = s "extern void cinit(void);\n";
-		s = s "extern void copen(Chan*);\n";
-		s = s "extern int cread(Chan*, unsigned char*, int, int64_t);\n";
-		s = s "extern void cupdate(Chan*, unsigned char*, int, int64_t);\n";
-		s = s "extern void cwrite(Chan*, unsigned char*, int, int64_t);\n\n";
-		s = s "void (*mfcinit)(void) = cinit;\n";
-		s = s "void (*mfcopen)(Chan*) = copen;\n";
-		s = s "int (*mfcread)(Chan*, unsigned char*, int, int64_t) = cread;\n";
-		s = s "void (*mfcupdate)(Chan*, unsigned char*, int, int64_t) = cupdate;\n";
-		s = s "void (*mfcwrite)(Chan*, unsigned char*, int, int64_t) = cwrite;\n\n";
-	}
-	else{
-		s = s "void (*mfcinit)(void) = nil;\n";
-		s = s "void (*mfcopen)(Chan*) = nil;\n";
-		s = s "int (*mfcread)(Chan*, unsigned char*, int, int64_t) = nil;\n";
-		s = s "void (*mfcupdate)(Chan*, unsigned char*, int, int64_t) = nil;\n";
-		s = s "void (*mfcwrite)(Chan*, unsigned char*, int, int64_t) = nil;\n\n";
-	}
-	if(!("rdb" in misc)){
-		s = s "void\n";
-		s = s "rdb(void)\n";
-		s = s "{\n";
-		s = s "\tsplhi();\n";
-		s = s "\tiprint(\"rdb...not installed\\n\");\n";
-		s = s "\tfor(;;);\n";
-		s = s "}\n\n";
-	}
-	if(objtype == "power"){
-		for(i = 1; i < section[objtype]; i++){
-			split(line[objtype, i], a);
-			m[a[1]] = line[objtype, i];
-		}
-		if(!("cnksyscall" in m)){
-			s = s "void\n";
-			s = s "cnksyscall(Ureg*)\n";
-			s = s "{\n";
-			s = s "\tpanic(\"cnkemu...not installed\\n\");\n";
-			s = s "\tfor(;;);\n";
-			s = s "}\n\n";
-			s = s "void*\n";
-			s = s "cnksysexecregs(uintptr, uint32_t, uint32_t)\n";
-			s = s "{\n";
-			s = s "\tpanic(\"cnkemu...not installed\\n\");\n";
-			s = s "\tfor(;;);\n";
-			s = s "}\n\n";
-		}
-	}
-	if("conf" in section){
-		for(i = 1; i < section["conf"]; i++)
-			s = s line["conf", i] "\n";
-		s = s "\n";
-	}
-	t = ".";
-	while("pwd" | getline > 0){
-		if($0 ~ /^\//)
-			t = $0;
-	}
-	s = s "char* conffile = \"" t "/" ARGV[argc] "\";\n";
-	s = s "uint32_t kerndate = KERNDATE;\n";
-
-	return s;
-}
-
-function mkrootrules(name, cname, src,			a, i, n){
-	for(i = 1; i < section["rootdir"]; i++){
-		n = split(line["rootdir", i], a);
-		if(n >= 2)
-			name[i] = a[2];
-		else
-			name[i] = a[1];
-		sub(/.*\//, "", name[i]);
-		cname[i] = a[1];
-		gsub(/[^a-zA-Z0-9_]/, "_", cname[i]);
-		src[i] = a[1];
-	}
-}
-
-function mkrules(dir, exists, ameta, cmeta, flags,		f, i, s, t){
-	for(i in ameta)
-		delete ameta[i];
-	for(i in cmeta)
-		delete cmeta[i];
-
-	s = "";
-	while("cd " dir "; ls *.[cs]" | getline > 0){
-		if($0 !~ /^[A-Za-z0-9]*\.[cs]$/)
-			continue;
-		f = $0;
-		if(!sub(/\.[cs]$/, ""))
-			continue;
-		if($0 in exists)
-			continue;
-		exists[$0] = dir;
-		if(f ~ /\.c$/){
-			if(!($0 in dbgc)){
-				cmeta[$0]++;
-				continue;
-			}
-			t = "$CC $CFLAGS " flags;
-		}
-		else{
-			if(!($0 in dbgc)){
-				ameta[$0]++;
-				continue;
-			}
-			t = "$AS $AFLAGS " flags;
-		}
-		s = s $0 ".$O:\t" dir "/" f "\n";
-#		s = s "\t" t " -D'_DBGC_='" dbgc[$0] "'' " dir "/" f "\n";
-		s = s "\t" t " -c " dir "/" f "\n";
-	}
-	return s;
-}
-
-function mkport(					array){
-	arrayify(array, "port", "", ".$O", 1);
-
-	return listolate(array, " ");
-}
-
-function mklib(						array){
-	arrayify(array, "lib", "/$objtype/lib/", ".a", 1);
-
-	return listolate(array," ");
-}
-
-function mkmach(					a, i, s){
-	s = "";
-	for(i = 1; i < section[objtype]; i++){
-		if(!split(line[objtype, i], a))
-			continue;
-		if(s == "")
-			s = a[1] ".$O";
-		else
-			s = s " " a[1] ".$O";
-	}
-
-	return s;
-}
-
-function mkdevlist(					a, array, i, j, n, s){
-	for(s in section){
-		if(line[s, 0] !~ /[ \t]\+dev[^_A-Za-z0-9]*/)
-			continue;
-		if(s == "dev")
-			arrayify(array, s, "dev", ".$O", 1);
-		else if(s == objtype)
-			arrayify(array, s, "", ".$O", 0);
-		else
-			arrayify(array, s, "", ".$O", 1);
-	}
-
-	return listolate(array, " ");
-}
-
-function listolate(array, sep,				a, s){
-	s = "";
-	for(a in array){
-		if(s == "")
-			s = a;
-		else
-			s = a sep s;
-	}
-
-	return s;
-}
-
-function arrayify(array, tag, prefix, suffix, one,	a, i, j, n){
-	for(i = 1; i < section[tag]; i++){
-		n = split(line[tag, i], a);
-		if(one)
-			array[prefix a[1] suffix]++;
-		for(j = 2; j <= n; j++){
-			if(a[$j] ~ /[+=-].*/)
-				continue;
-			array[a[j] suffix]++;
-		}
-	}
-}

+ 0 - 36
sys/src/9/root/rcmain

@@ -1,36 +0,0 @@
-#
-# rcmain
-# Plan 9 initial boot environment version
-#
-home=/
-ifs=' 	
-'
-prompt=('# ' '	')
-path=(. /bin /boot)
-
-finit
-fn sigexit
-fn ps {@{
-	cd /proc;
-	for(i in `{echo [1-9] [1-9][0-9] [1-9][0-9][0-9] [1-9][0-9][0-9][0-9] [1-9][0-9][0-9][0-9][0-9] [1-9][0-9][0-9][0-9][0-9]*|sed 's/\[.*\][ \*]//'}){
-		for(f in $i^/status $i^/args)
-			>[2]/dev/null sed '' $f
-	}|sed -e '$!N;s/([^ 	])$/\1/;ta' -e 'P;D;b' -e ':a;s/\n//' \
-	 |sed 's/ +/ /g;s/^([^ ]+) +([^ ]+) +([^ ]+) +([^ ]+ +[^ ]+ +[^ ]+ +[^ ]+ +[^ ]+ +[^ ]+) +([^ ]+)+ ([^ ]+ +[^ ]+)(.*)/\2	'^$i^'	\5K	\3	\1	\7/'
-}}
-fn netstat {@{
-	for(p in tcp udp){
-		cd /net/$p;
-		for(i in `{echo [0-9] [1-9][0-9] [1-9][0-9][0-9] [1-9][0-9][0-9]*|sed 's/\[.*\][ \*]//'}){
-			echo -n $p'	'$i'	*owner*	';
-			cat $i/status $i/local $i/remote \
-			| sed -n -e :a -e '$!N; s/ .*//; s/!/	/; s/\n/	/; ta;
-				s/([^	]+)	([^	]+)	([^	]+)	([^	]+)	([^	]+)/\1	\3	\5 \4/p'
-		}			
-	}
-}}
-
-status=''
-if(! ~ $#* 0) . $*
-. -i '#d/0'
-exit $status

+ 0 - 129
sys/src/9/w/pxeload/386l.h

@@ -1,129 +0,0 @@
-/* 
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
-
-#define Pe		0x00000001		/* Protected Mode Enable */
-#define Mp		0x00000002		/* Monitor Coprocessor */
-#define Em		0x00000004		/* Emulate Coprocessor */
-#define Ts		0x00000008		/* Task Switched */
-#define Et		0x00000010		/* Extension Type */
-#define Ne		0x00000020		/* Numeric Error  */
-#define Wp		0x00010000		/* Write Protect */
-#define Am		0x00040000		/* Alignment Mask */
-#define Nw		0x20000000		/* Not Writethrough */
-#define Cd		0x40000000		/* Cache Disable */
-#define Pg		0x80000000		/* Paging Enable */
-
-#define Pwt		0x00000008		/* Page-Level Writethrough */
-#define Pcd		0x00000010		/* Page-Level Cache Disable */
-
-#define Vme		0x00000001		/* Virtual-8086 Mode Extensions */
-#define Pvi		0x00000002		/* Protected Mode Virtual Interrupts */
-#define Tsd		0x00000004		/* Time-Stamp Disable */
-#define De		0x00000008		/* Debugging Extensions */
-#define Pse		0x00000010		/* Page-Size Extensions */
-#define Pae		0x00000020		/* Physical Address Extension */
-#define Mce		0x00000040		/* Machine Check Enable */
-#define Pge		0x00000080		/* Page-Global Enable */
-#define Pce		0x00000100		/* Performance Monitoring Counter Enable */
-#define Osfxsr		0x00000200		/* FXSAVE/FXRSTOR Support */
-#define Osxmmexcpt	0x00000400		/* Unmasked Exception Support */
-
-#define Cf		0x00000001		/* Carry Flag */
-#define Pf		0x00000004		/* Parity Flag */
-#define Af		0x00000010		/* Auxiliary Flag */
-#define Zf		0x00000040		/* Zero Flag */
-#define Sf		0x00000080		/* Sign Flag */
-#define Tf		0x00000100		/* Trap Flag */
-#define If		0x00000200		/* Interrupt Flag */
-#define Df		0x00000400		/* Direction Flag */
-#define Of		0x00000800		/* Overflow Flag */
-#define Iopl0		0x00000000		/* I/O Privilege Level */
-#define Iopl1		0x00001000
-#define Iopl2		0x00002000
-#define Iopl3		0x00003000
-#define Nt		0x00004000		/* Nested Task */
-#define Rf		0x00010000		/* Resume Flag */
-#define Vm		0x00020000		/* Virtual-8086 Mode */
-#define Ac		0x00040000		/* Alignment Check */
-#define Vif		0x00080000		/* Virtual Interrupt Flag */
-#define Vip		0x00100000		/* Virtual Interrupt Pending */
-#define Id		0x00200000		/* ID Flag */
-
-#define PteP		0x00000001ul		/* Present */
-#define PteRW		0x00000002ul		/* Read/Write */
-#define PteU		0x00000004ul		/* User/Supervisor */
-#define PtePWT		0x00000008ul		/* Page-Level Write Through */
-#define PtePCD		0x00000010ul		/* Page Level Cache Disable */
-#define PteA		0x00000020ul		/* Accessed */
-#define PteD		0x00000040ul		/* Dirty */
-#define PtePS		0x00000080ul		/* Page Size */
-#define PtePAT0		PtePS			/* Level 0 PAT */
-#define PteG		0x00000100ul		/* Global */
-#define PtePAT1		0x00000800ul		/* Level 1 PAT */
-
-#define IdtDE		0x00			/* Divide-by-Zero Error */
-#define IdtDB		0x01			/* Debug */
-#define IdtNMI		0x02			/* Non-Maskable-Interrupt */
-#define IdtBP		0x03			/* Breakpoint */
-#define IdtOF		0x04			/* Overflow */
-#define IdtBR		0x05			/* Bound-Range */
-#define IdtUD		0x06			/* Invalid-Opcode */
-#define IdtNM		0x07			/* Device-Not-Available */
-#define IdtDF		0x08			/* Double-Fault */
-#define Idt09		0x09			/* unsupported */
-#define IdtTS		0x0a			/* Invalid-TSS */
-#define IdtNP		0x0b			/* Segment-Not-Present */
-#define IdtSS		0x0c			/* Stack */
-#define IdtGP		0x0d			/* General-Protection */
-#define IdtPF		0x0e			/* Page-Fault */
-#define Idt0F		0x0f			/* reserved */
-#define IdtMF		0x10			/* x87 FPE-Pending */
-#define IdtAC		0x11			/* Alignment-Check */
-#define IdtMC		0x12			/* Machine-Check */
-#define IdtXF		0x13			/* SIMD Floating-Point */
-
-#define SdISTM		0x0000000700000000ull	/* Interrupt Stack Table Mask */
-#define SdA		0x0000010000000000ull	/* Accessed */
-#define SdR		0x0000020000000000ull	/* Readable (Code) */
-#define SdW		0x0000020000000000ull	/* Writeable (Data) */
-#define SdE		0x0000040000000000ull	/* Expand Down */
-#define SdaTSS		0x0000090000000000ull	/* Available TSS */
-#define SdbTSS		0x00000b0000000000ull	/* Busy TSS */
-#define SdCG		0x00000c0000000000ull	/* Call Gate */
-#define SdIG		0x00000e0000000000ull	/* Interrupt Gate */
-#define SdTG		0x00000f0000000000ull	/* Trap Gate */
-#define SdCODE		0x0000080000000000ull	/* Code/Data */
-#define SdS		0x0000100000000000ull	/* System/User */
-#define SdDPL0		0x0000000000000000ull	/* Descriptor Privilege Level */
-#define SdDPL1		0x0000200000000000ull
-#define SdDPL2		0x0000400000000000ull
-#define SdDPL3		0x0000600000000000ull
-#define SdP		0x0000800000000000ull	/* Present */
-#define Sd4G		0x000f00000000ffffull	/* 4G Limit */
-#define SdL		0x0020000000000000ull	/* Long Attribute */
-#define SdD		0x0040000000000000ull	/* Default Operand Size */
-#define SdG		0x0080000000000000ull	/* Granularity */
-
-#define SsRPL0		0x0000			/* Requestor Privilege Level */
-#define SsRPL1		0x0001
-#define SsRPL2		0x0002
-#define SsRPL3		0x0003
-#define SsTIGDT		0x0000			/* GDT Table Indicator  */
-#define SsTILDT		0x0004			/* LDT Table Indicator */
-#define SsSIM		0xfff8			/* Selector Index Mask */
-
-#define SSEL(si, tirpl)	(((si)<<3)|(tirpl))	/* Segment Selector */
-
-#define SiNULL		0			/* NULL selector index */
-#define SiCS		1			/* CS selector index */
-#define SiDS		2			/* DS selector index */
-#define SiLCS		3			/* Legacy CS selector index */
-#define SiUDS		4			/* User DS selector index */
-#define SiUCS		5			/* User CS selector index */
-#define SiTSS		6			/* TSS selector index */

+ 0 - 132
sys/src/9/w/pxeload/alarm.c

@@ -1,132 +0,0 @@
-/*
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
-
-#include	"u.h"
-#include	"lib.h"
-#include	"mem.h"
-#include	"dat.h"
-#include	"fns.h"
-#include	"io.h"
-#define	MAXALARM	10
-
-Alarm	alarmtab[MAXALARM];
-
-/*
- * Insert new into list after where
- */
-void
-insert(List **head, List *where, List *new)
-{
-	if(where == 0){
-		new->next = *head;
-		*head = new;
-	}else{
-		new->next = where->next;
-		where->next = new;
-	}
-
-}
-
-/*
- * Delete old from list.  where->next is known to be old.
- */
-void
-delete(List **head, List *where, List *old)
-{
-	if(where == 0){
-		*head = old->next;
-		return;
-	}
-	where->next = old->next;
-}
-
-Alarm*
-newalarm(void)
-{
-	int i;
-	Alarm *a;
-
-	for(i=0,a=alarmtab; i < nelem(alarmtab); i++,a++)
-		if(a->busy==0 && a->f==0){
-			a->f = 0;
-			a->arg = 0;
-			a->busy = 1;
-			return a;
-		}
-	panic("newalarm");
-	return 0;	/* not reached */
-}
-
-Alarm*
-alarm(int ms, void (*f)(Alarm*), void *arg)
-{
-	Alarm *a, *w, *pw;
-	uint32_t s;
-
-	if(ms < 0)
-		ms = 0;
-	s = splhi();
-	a = newalarm();
-	a->dt = MS2TK(ms);
-	a->f = f;
-	a->arg = arg;
-	pw = 0;
-	for(w=m->alarm; w; pw=w, w=w->next){
-		if(w->dt <= a->dt){
-			a->dt -= w->dt;
-			continue;
-		}
-		w->dt -= a->dt;
-		break;
-	}
-	insert(&m->alarm, pw, a);
-	splx(s);
-	return a;
-}
-
-void
-cancel(Alarm *a)
-{
-	a->f = 0;
-}
-
-void
-alarminit(void)
-{
-}
-
-#define NA 10		/* alarms per clock tick */
-void
-checkalarms(void)
-{
-	int i, n, s;
-	Alarm *a;
-	void (*f)(Alarm*);
-	Alarm *alist[NA];
-
-	s = splhi();
-	a = m->alarm;
-	if(a){
-		for(n=0; a && a->dt<=0 && n<NA; n++){
-			alist[n] = a;
-			delete(&m->alarm, 0, a);
-			a = m->alarm;
-		}
-		if(a)
-			a->dt--;
-
-		for(i = 0; i < n; i++){
-			f = alist[i]->f;	/* avoid race with cancel */
-			if(f)
-				(*f)(alist[i]);
-			alist[i]->busy = 0;
-		}
-	}
-	splx(s);
-}

+ 0 - 25
sys/src/9/w/pxeload/apm.c

@@ -1,25 +0,0 @@
-/*
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
-
-#include "u.h"
-#include "lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-
-Apminfo apm;
-
-void
-apminit(void)
-{
-	if(getconf("apm0") && apm.haveinfo)
-		changeconf("apm0=ax=%x ebx=%x cx=%x dx=%x di=%x esi=%x\n",
-			apm.ax, apm.ebx, apm.cx, apm.dx, apm.di, apm.esi);
-}

+ 0 - 514
sys/src/9/w/pxeload/boot.c

@@ -1,514 +0,0 @@
-/*
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
-
-#include "u.h"
-#include "lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-
-#include "/sys/src/libmach/elf.h"
-
-static uint8_t elfident[7] = {
-	'\177', 'E', 'L', 'F', '\1', '\1', '\1'
-};
-static Ehdr ehdr, rehdr;
-static Phdr *phdr;
-static int curphdr;
-static uint32_t curoff;
-static uint32_t elftotal;
-static int32_t (*swal)(int32_t);
-static uint16_t (*swab)(uint16_t);
-
-/*
- * big-endian short
- */
-uint16_t
-beswab(uint16_t s)
-{
-	uint8_t *p;
-
-	p = (uint8_t*)&s;
-	return (p[0]<<8) | p[1];
-}
-
-/*
- * big-endian long
- */
-int32_t
-beswal(int32_t l)
-{
-	uint8_t *p;
-
-	p = (uint8_t*)&l;
-	return (p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3];
-}
-
-/*
- * big-endian vlong
- */
-uint64_t
-beswav(uint64_t v)
-{
-	uint8_t *p;
-
-	p = (uint8_t*)&v;
-	return ((uint64_t)p[0]<<56) | ((uint64_t)p[1]<<48) | ((uint64_t)p[2]<<40)
-				  | ((uint64_t)p[3]<<32) | ((uint64_t)p[4]<<24)
-				  | ((uint64_t)p[5]<<16) | ((uint64_t)p[6]<<8)
-				  | (uint64_t)p[7];
-}
-
-/*
- * little-endian short
- */
-uint16_t
-leswab(uint16_t s)
-{
-	uint8_t *p;
-
-	p = (uint8_t*)&s;
-	return (p[1]<<8) | p[0];
-}
-
-/*
- * little-endian long
- */
-int32_t
-leswal(int32_t l)
-{
-	uint8_t *p;
-
-	p = (uint8_t*)&l;
-	return (p[3]<<24) | (p[2]<<16) | (p[1]<<8) | p[0];
-}
-
-/*
- * Convert header to canonical form
- */
-static void
-hswal(int32_t *lp, int n, int32_t (*swap) (int32_t))
-{
-	while (n--) {
-		*lp = (*swap) (*lp);
-		lp++;
-	}
-}
-
-static int
-readehdr(Boot *b)
-{
-	int i;
-
-	/* bitswap the header according to the DATA format */
-	if(ehdr.ident[CLASS] != ELFCLASS32) {
-		print("bad ELF class - not 32 bit\n");
-		return 0;
-	}
-	if(ehdr.ident[DATA] == ELFDATA2LSB) {
-		swab = leswab;
-		swal = leswal;
-	} else if(ehdr.ident[DATA] == ELFDATA2MSB) {
-		swab = beswab;
-		swal = beswal;
-	} else {
-		print("bad ELF encoding - not big or little endian\n");
-		return 0;
-	}
-	memmove(&rehdr, &ehdr, sizeof(Ehdr));
-
-	ehdr.type = swab(ehdr.type);
-	ehdr.machine = swab(ehdr.machine);
-	ehdr.version = swal(ehdr.version);
-	ehdr.elfentry = swal(ehdr.elfentry);
-	ehdr.phoff = swal(ehdr.phoff);
-	ehdr.shoff = swal(ehdr.shoff);
-	ehdr.flags = swal(ehdr.flags);
-	ehdr.ehsize = swab(ehdr.ehsize);
-	ehdr.phentsize = swab(ehdr.phentsize);
-	ehdr.phnum = swab(ehdr.phnum);
-	ehdr.shentsize = swab(ehdr.shentsize);
-	ehdr.shnum = swab(ehdr.shnum);
-	ehdr.shstrndx = swab(ehdr.shstrndx);
-	if(ehdr.type != EXEC || ehdr.version != CURRENT)
-		return 0;
-	if(ehdr.phentsize != sizeof(Phdr))
-		return 0;
-
-	if(debug)
-		print("readehdr OK entry 0x%lux\n", ehdr.elfentry);
-
-	curoff = sizeof(Ehdr);
-	i = ehdr.phoff+ehdr.phentsize*ehdr.phnum - curoff;
-	b->state = READPHDR;
-	b->bp = (char*)malloc(i);
-	b->wp = b->bp;
-	b->ep = b->wp + i;
-	phdr = (Phdr*)(b->bp + ehdr.phoff-sizeof(Ehdr));
-	if(debug)
-		print("phdr...");
-
-	return 1;
-}
-
-static int
-nextphdr(Boot *b)
-{
-	Phdr *php;
-	uint32_t entry, offset;
-	char *paddr;
-
-	if(debug)
-		print("readedata %d\n", curphdr);
-
-	for(; curphdr < ehdr.phnum; curphdr++){
-		php = phdr+curphdr;
-		if(php->type != LOAD)
-			continue;
-		offset = php->offset;
-		paddr = (char*)PADDR(php->paddr);
-		if(offset < curoff){
-			/*
-			 * Can't (be bothered to) rewind the
-			 * input, it might be from tftp. If we
-			 * did then we could boot FreeBSD kernels
-			 * too maybe.
-			 */
-			return 0;
-		}
-		if(php->offset > curoff){
-			b->state = READEPAD;
-			b->bp = (char*)malloc(offset - curoff);
-			b->wp = b->bp;
-			b->ep = b->wp + offset - curoff;
-			if(debug)
-				print("nextphdr %lud...\n", offset - curoff);
-			return 1;
-		}
-		b->state = READEDATA;
-		b->bp = paddr;
-		b->wp = b->bp;
-		b->ep = b->wp+php->filesz;
-		print("%ud+", php->filesz);
-		elftotal += php->filesz;
-		if(debug)
-			print("nextphdr %ud@0x%p\n", php->filesz, paddr);
-
-		return 1;
-	}
-
-	if(curphdr != 0){
-		print("=%lud\n", elftotal);
-		b->state = TRYEBOOT;
-		entry = ehdr.elfentry & ~0xF0000000;
-		PLLONG(b->hdr.entry, entry);
-		return 1;
-	}
-
-	return 0;
-}
-
-static int
-readepad(Boot *b)
-{
-	Phdr *php;
-
-	php = phdr+curphdr;
-	if(debug)
-		print("readepad %d\n", curphdr);
-	curoff = php->offset;
-
-	return nextphdr(b);
-}
-
-static int
-readedata(Boot *b)
-{
-	Phdr *php;
-
-	php = phdr+curphdr;
-	if(debug)
-		print("readedata %d\n", curphdr);
-	if(php->filesz < php->memsz){
-		print("%lud",  php->memsz-php->filesz);
-		elftotal += php->memsz-php->filesz;
-		memset((char*)(PADDR(php->paddr)+php->filesz), 0,
-		       php->memsz-php->filesz);
-	}
-	curoff = php->offset+php->filesz;
-	curphdr++;
-
-	return nextphdr(b);
-}
-
-static int
-readphdr(Boot *b)
-{
-	Phdr *php;
-
-	php = phdr;
-	hswal((int32_t*)php, ehdr.phentsize*ehdr.phnum/sizeof(int32_t), swal);
-	if(debug)
-		print("phdr curoff %lud vaddr 0x%lux paddr 0x%lux\n",
-			curoff, php->vaddr, php->paddr);
-
-	curoff = ehdr.phoff+ehdr.phentsize*ehdr.phnum;
-	curphdr = 0;
-
-	return nextphdr(b);
-}
-
-static int
-addbytes(char **dbuf, char *edbuf, char **sbuf, char *esbuf)
-{
-	int n;
-
-	n = edbuf - *dbuf;
-	if(n <= 0)
-		return 0;
-	if(n > esbuf - *sbuf)
-		n = esbuf - *sbuf;
-	if(n <= 0)
-		return -1;
-
-	memmove(*dbuf, *sbuf, n);
-	*sbuf += n;
-	*dbuf += n;
-	return edbuf - *dbuf;
-}
-
-int
-bootpass(Boot *b, void *vbuf, int nbuf)
-{
-	char *buf, *ebuf;
-	Hdr *hdr;
-	uint32_t magic, entry, data, text, bss;
-	uint64_t entry64;
-
-	if(b->state == FAILED)
-		return FAIL;
-
-	if(nbuf == 0)
-		goto Endofinput;
-
-	buf = vbuf;
-	ebuf = buf+nbuf;
-	while(addbytes(&b->wp, b->ep, &buf, ebuf) == 0) {
-		switch(b->state) {
-		case INITKERNEL:
-			b->state = READEXEC;
-			b->bp = (char*)&b->hdr;
-			b->wp = b->bp;
-			b->ep = b->bp+sizeof(Hdr);
-			break;
-		case READEXEC:
-			hdr = &b->hdr;
-			magic = GLLONG(hdr->magic);
-			if(magic == I_MAGIC || magic == S_MAGIC) {
-				b->state = READ9TEXT;
-				b->bp = (char*)PADDR(GLLONG(hdr->entry));
-				b->wp = b->bp;
-				b->ep = b->wp+GLLONG(hdr->text);
-
-				if(magic == I_MAGIC){
-					memmove(b->bp, b->hdr.uvl, sizeof(b->hdr.uvl));
-					b->wp += sizeof(b->hdr.uvl);
-				}
-
-				print("%lud", GLLONG(hdr->text));
-				break;
-			}
-
-			/* check for gzipped kernel */
-			if(b->bp[0] == 0x1F && (uint8_t)b->bp[1] == 0x8B && b->bp[2] == 0x08) {
-				b->state = READGZIP;
-				b->bp = (char*)malloc(1440*1024);
-				b->wp = b->bp;
-				b->ep = b->wp + 1440*1024;
-				memmove(b->bp, &b->hdr, sizeof(Hdr));
-				b->wp += sizeof(Hdr);
-				print("gz...");
-				break;
-			}
-
-			/*
-			 * Check for ELF.
-			 */
-			if(memcmp(b->bp, elfident, 4) == 0){
-				b->state = READEHDR;
-				b->bp = (char*)&ehdr;
-				b->wp = b->bp;
-				b->ep = b->wp + sizeof(Ehdr);
-				memmove(b->bp, &b->hdr, sizeof(Hdr));
-				b->wp += sizeof(Hdr);
-				print("elf...");
-				break;
-			}
-
-			print("bad kernel format (magic == %#lux)\n", magic);
-			b->state = FAILED;
-			return FAIL;
-
-		case READ9TEXT:
-			hdr = &b->hdr;
-			b->state = READ9DATA;
-			b->bp = (char*)PGROUND(PADDR(GLLONG(hdr->entry))+GLLONG(hdr->text));
-			b->wp = b->bp;
-			b->ep = b->wp + GLLONG(hdr->data);
-			print("+%ld", GLLONG(hdr->data));
-			break;
-
-		case READ9DATA:
-			hdr = &b->hdr;
-			bss = GLLONG(hdr->bss);
-			memset(b->ep, 0, bss);
-			print("+%ld=%ld\n",
-				bss, GLLONG(hdr->text)+GLLONG(hdr->data)+bss);
-			b->state = TRYBOOT;
-			return ENOUGH;
-
-		case READEHDR:
-			if(!readehdr(b)){
-				print("readehdr failed\n");
-				b->state = FAILED;
-				return FAIL;
-			}
-			break;
-
-		case READPHDR:
-			if(!readphdr(b)){
-				b->state = FAILED;
-				return FAIL;
-			}
-			break;
-
-		case READEPAD:
-			if(!readepad(b)){
-				b->state = FAILED;
-				return FAIL;
-			}
-			break;
-
-		case READEDATA:
-			if(!readedata(b)){
-				b->state = FAILED;
-				return FAIL;
-			}
-			if(b->state == TRYBOOT)
-				return ENOUGH;
-			break;
-
-		case TRYBOOT:
-		case TRYEBOOT:
-		case READGZIP:
-			return ENOUGH;
-
-		case READ9LOAD:
-		case INIT9LOAD:
-			panic("9load");
-
-		default:
-			panic("bootstate");
-		}
-	}
-	return MORE;
-
-
-Endofinput:
-	/* end of input */
-	switch(b->state) {
-	case INITKERNEL:
-	case READEXEC:
-	case READ9TEXT:
-	case READ9DATA:
-	case READEHDR:
-	case READPHDR:
-	case READEPAD:
-	case READEDATA:
-		print("premature EOF\n");
-		b->state = FAILED;
-		return FAIL;
-
-	case TRYBOOT:
-		entry = GLLONG(b->hdr.entry);
-		magic = GLLONG(b->hdr.magic);
-		if(magic == I_MAGIC){
-			print("entry: 0x%lux\n", entry);
-			warp9(PADDR(entry));
-		}
-		else if(magic == S_MAGIC){
-			entry64 = beswav(b->hdr.uvl[0]);
-			warp64(entry64);
-		}
-		b->state = FAILED;
-		return FAIL;
-
-	case TRYEBOOT:
-		entry = GLLONG(b->hdr.entry);
-		if(ehdr.machine == I386){
-			print("entry: 0x%lux\n", entry);
-			warp9(PADDR(entry));
-		}
-		else if(ehdr.machine == AMD64){
-			print("entry: 0x%lux\n", entry);
-			warp64(entry);
-		}
-		b->state = FAILED;
-		return FAIL;
-
-	case READGZIP:
-		hdr = &b->hdr;
-		if(b->bp[0] != 0x1F || (uint8_t)b->bp[1] != 0x8B || b->bp[2] != 0x08)
-			print("lost magic\n");
-
-		print("%ld => ", b->wp - b->bp);
-		if(gunzip((uint8_t*)hdr, sizeof(*hdr), (uint8_t*)b->bp, b->wp - b->bp) < sizeof(*hdr)) {
-			print("badly compressed kernel\n");
-			return FAIL;
-		}
-
-		entry = GLLONG(hdr->entry);
-		text = GLLONG(hdr->text);
-		data = GLLONG(hdr->data);
-		bss = GLLONG(hdr->bss);
-		print("%lud+%lud+%lud=%lud\n", text, data, bss, text+data+bss);
-
-		if(gunzip((uint8_t*)PADDR(entry)-sizeof(Exec), sizeof(Exec)+text+data,
-		     (uint8_t*)b->bp, b->wp-b->bp) < sizeof(Exec)+text+data) {
-			print("error uncompressing kernel\n");
-			return FAIL;
-		}
-
-		/* relocate data to start at page boundary */
-		memmove((void*)PGROUND(PADDR(entry+text)), (void*)(PADDR(entry+text)), data);
-
-		entry = GLLONG(b->hdr.entry);
-		magic = GLLONG(b->hdr.magic);
-		if(magic == I_MAGIC){
-			print("entry: 0x%lux\n", entry);
-			warp9(PADDR(entry));
-		}
-		else if(magic == S_MAGIC){
-			entry64 = beswav(b->hdr.uvl[0]);
-			warp64(entry64);
-		}
-		b->state = FAILED;
-		return FAIL;
-
-	case INIT9LOAD:
-	case READ9LOAD:
-		panic("end 9load");
-
-	default:
-		panic("bootdone");
-	}
-	b->state = FAILED;
-	return FAIL;
-}

+ 0 - 760
sys/src/9/w/pxeload/bootp.c

@@ -1,760 +0,0 @@
-/*
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
-
-#include "u.h"
-#include "lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-
-#include "ip.h"
-
-int debugload;
-extern char *persist;
-
-uint8_t broadcast[Eaddrlen] = {
-	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-};
-
-static uint16_t tftpport = 5000;
-static int Id = 1;
-static Netaddr myaddr;
-static Netaddr server;
-
-typedef struct {
-	uint8_t	header[4];
-	uint8_t	data[TFTP_SEGSIZE];
-} Tftp;
-static Tftp tftpb;
-
-static void
-hnputs(uint8_t *ptr, uint16_t val)
-{
-	ptr[0] = val>>8;
-	ptr[1] = val;
-}
-
-static void
-hnputl(uint8_t *ptr, uint32_t val)
-{
-	ptr[0] = val>>24;
-	ptr[1] = val>>16;
-	ptr[2] = val>>8;
-	ptr[3] = val;
-}
-
-static uint32_t
-nhgetl(uint8_t *ptr)
-{
-	return ((ptr[0]<<24) | (ptr[1]<<16) | (ptr[2]<<8) | ptr[3]);
-}
-
-static uint16_t
-nhgets(uint8_t *ptr)
-{
-	return ((ptr[0]<<8) | ptr[1]);
-}
-
-static	int16_t	endian	= 1;
-static	char*	aendian	= (char*)&endian;
-#define	LITTLE	*aendian
-
-static uint16_t
-ptcl_csum(void *a, int len)
-{
-	uint8_t *addr;
-	uint32_t t1, t2;
-	uint32_t losum, hisum, mdsum, x;
-
-	addr = a;
-	losum = 0;
-	hisum = 0;
-	mdsum = 0;
-
-	x = 0;
-	if((uint32_t)addr & 1) {
-		if(len) {
-			hisum += addr[0];
-			len--;
-			addr++;
-		}
-		x = 1;
-	}
-	while(len >= 16) {
-		t1 = *(uint16_t*)(addr+0);
-		t2 = *(uint16_t*)(addr+2);	mdsum += t1;
-		t1 = *(uint16_t*)(addr+4);	mdsum += t2;
-		t2 = *(uint16_t*)(addr+6);	mdsum += t1;
-		t1 = *(uint16_t*)(addr+8);	mdsum += t2;
-		t2 = *(uint16_t*)(addr+10);	mdsum += t1;
-		t1 = *(uint16_t*)(addr+12);	mdsum += t2;
-		t2 = *(uint16_t*)(addr+14);	mdsum += t1;
-		mdsum += t2;
-		len -= 16;
-		addr += 16;
-	}
-	while(len >= 2) {
-		mdsum += *(uint16_t*)addr;
-		len -= 2;
-		addr += 2;
-	}
-	if(x) {
-		if(len)
-			losum += addr[0];
-		if(LITTLE)
-			losum += mdsum;
-		else
-			hisum += mdsum;
-	} else {
-		if(len)
-			hisum += addr[0];
-		if(LITTLE)
-			hisum += mdsum;
-		else
-			losum += mdsum;
-	}
-
-	losum += hisum >> 8;
-	losum += (hisum & 0xff) << 8;
-	while(hisum = losum>>16)
-		losum = hisum + (losum & 0xffff);
-
-	return ~losum;
-}
-
-static uint16_t
-ip_csum(uint8_t *addr)
-{
-	int len;
-	uint32_t sum = 0;
-
-	len = (addr[0]&0xf)<<2;
-
-	while(len > 0) {
-		sum += addr[0]<<8 | addr[1] ;
-		len -= 2;
-		addr += 2;
-	}
-
-	sum = (sum & 0xffff) + (sum >> 16);
-	sum = (sum & 0xffff) + (sum >> 16);
-	return (sum^0xffff);
-}
-
-enum {
-	/* this is only true of IPv4, but we're not doing v6 yet */
-	Min_udp_payload = ETHERMINTU - ETHERHDRSIZE - UDP_HDRSIZE,
-};
-
-static void
-udpsend(int ctlrno, Netaddr *a, void *data, int dlen)
-{
-	Udphdr *uh;
-	Etherhdr *ip;
-	Etherpkt pkt;
-	int len, ptcllen;
-
-	uh = (Udphdr*)&pkt;
-
-	memset(uh, 0, sizeof(Etherpkt));
-	memmove(uh->udpcksum+sizeof(uh->udpcksum), data, dlen);
-
-	/*
-	 * UDP portion
-	 */
-	ptcllen = dlen + (UDP_HDRSIZE-UDP_PHDRSIZE);
-	uh->ttl = 0;
-	uh->udpproto = IP_UDPPROTO;
-	uh->frag[0] = 0;
-	uh->frag[1] = 0;
-	hnputs(uh->udpplen, ptcllen);
-	hnputl(uh->udpsrc, myaddr.ip);
-	hnputs(uh->udpsport, myaddr.port);
-	hnputl(uh->udpdst, a->ip);
-	hnputs(uh->udpdport, a->port);
-	hnputs(uh->udplen, ptcllen);
-	uh->udpcksum[0] = 0;
-	uh->udpcksum[1] = 0;
-	dlen = (dlen+1)&~1;
-	hnputs(uh->udpcksum, ptcl_csum(&uh->ttl, dlen+UDP_HDRSIZE));
-
-	/*
-	 * IP portion
-	 */
-	ip = (Etherhdr*)&pkt;
-	len = UDP_EHSIZE+UDP_HDRSIZE+dlen;		/* non-descriptive names */
-	ip->vihl = IP_VER|IP_HLEN;
-	ip->tos = 0;
-	ip->ttl = 255;
-	hnputs(ip->length, len-ETHER_HDR);
-	hnputs(ip->id, Id++);
-	ip->frag[0] = 0;
-	ip->frag[1] = 0;
-	ip->cksum[0] = 0;
-	ip->cksum[1] = 0;
-	hnputs(ip->cksum, ip_csum(&ip->vihl));
-
-	/*
-	 * Ethernet MAC portion
-	 */
-	hnputs(ip->type, ET_IP);
-	memmove(ip->d, a->ea, sizeof(ip->d));
-
-if(debug) {
-	print("udpsend ");
-}
-	/*
-	 * if packet is too short, make it longer rather than relying
-	 * on ethernet interface or lower layers to pad it.
-	 */
-	if (len < ETHERMINTU)
-		len = ETHERMINTU;
-	ethertxpkt(ctlrno, &pkt, len, Timeout);
-}
-
-static void
-nak(int ctlrno, Netaddr *a, int code, char *msg, int report)
-{
-	int n;
-	char buf[128];
-
-	buf[0] = 0;
-	buf[1] = Tftp_ERROR;
-	buf[2] = 0;
-	buf[3] = code;
-	strcpy(buf+4, msg);
-	n = strlen(msg) + 4 + 1;
-	udpsend(ctlrno, a, buf, n);
-	if(report)
-		print("\ntftp: error(%d): %s\n", code, msg);
-}
-
-static int
-udprecv(int ctlrno, Netaddr *a, void *data, int dlen)
-{
-	int n, len, olen;
-	uint8_t *dp;
-	uint16_t csm;
-	Udphdr *h;
-	uint32_t addr, timo;
-	Etherpkt pkt;
-	static int rxactive;
-
-	if(rxactive == 0)
-		timo = 1000;
-	else
-		timo = Timeout;
-	timo += TK2MS(machp()->ticks);
-	while(timo > TK2MS(machp()->ticks)){
-		n = etherrxpkt(ctlrno, &pkt, timo-TK2MS(machp()->ticks));
-		if(n <= 0)
-			continue;
-
-		h = (Udphdr*)&pkt;
-		if(debug)
-			print("udprecv %E to %E...\n", h->s, h->d);
-
-		if(nhgets(h->type) != ET_IP || (h->vihl & 0xf0) != IP_VER) {
-			if(debug)
-				print("not ipv4 (%#4.4ux) %#2.2ux...",
-					nhgets(h->type), h->vihl);
-			continue;
-		}
-
-		if(ip_csum(&h->vihl)) {
-			print("ip chksum error\n");
-			continue;
-		}
-		if((h->vihl & 0x0f) != IP_HLEN) {
-			len = (h->vihl & 0xf)<<2;
-			if(len < (IP_HLEN<<2)) {
-				print("ip bad hlen %d %E to %E\n", len, h->s, h->d);
-				continue;
-			}
-			/* strip off the options */
-			olen = nhgets(h->length);
-			dp = (uint8_t*)h + (len - (IP_HLEN<<2));
-
-			memmove(dp, h, IP_HLEN<<2);
-			h = (Udphdr*)dp;
-			h->vihl = (IP_VER|IP_HLEN);
-			hnputs(h->length, olen-len+(IP_HLEN<<2));
-			if(debug)
-				print("strip %d %E to %E\n", len, h->s, h->d);
-		}
-
-		if(h->udpproto != IP_UDPPROTO) {
-			if(debug)
-				print("not udp (%d)...", h->udpproto);
-			continue;
-		}
-
-		if(debug)
-			print("okay udp...");
-
-		h->ttl = 0;
-		len = nhgets(h->udplen);
-		hnputs(h->udpplen, len);
-
-		if(nhgets(h->udpcksum)) {
-			csm = ptcl_csum(&h->ttl, len+UDP_PHDRSIZE);
-			if(csm != 0) {
-				print("udp chksum error csum #%4ux len %d\n",
-					csm, n);
-				break;
-			}
-		}
-
-		if(a->port != 0 && nhgets(h->udpsport) != a->port) {
-			if(debug)
-				print("udpport %ux not %ux\n",
-					nhgets(h->udpsport), a->port);
-			continue;
-		}
-
-		addr = nhgetl(h->udpsrc);
-		if(a->ip != Bcastip && a->ip != addr) {
-			if(debug)
-				print("bad ip %lux not %lux\n", addr, a->ip);
-			continue;
-		}
-
-		len -= UDP_HDRSIZE-UDP_PHDRSIZE;
-		if(len > dlen) {
-			print("udp: packet too big: %d > %d; from addr %E\n",
-				len, dlen, h->udpsrc);
-			continue;
-		}
-
-		memmove(data, h->udpcksum+sizeof(h->udpcksum), len);
-		a->ip = addr;
-		a->port = nhgets(h->udpsport);
-		memmove(a->ea, pkt.s, sizeof(a->ea));
-
-		rxactive = 1;
-		return len;
-	}
-
-	return 0;
-}
-
-static int tftpblockno;
-
-/*
- * format of a request packet, from the RFC:
- *
-            2 bytes     string    1 byte     string   1 byte
-            ------------------------------------------------
-           | Opcode |  Filename  |   0  |    Mode    |   0  |
-            ------------------------------------------------
- */
-static int
-tftpopen(int ctlrno, Netaddr *a, char *name, Tftp *tftp)
-{
-	int i, len, rlen, oport;
-	char buf[TFTP_SEGSIZE+2];
-
-	buf[0] = 0;
-	buf[1] = Tftp_READ;
-	len = 2 + sprint(buf+2, "%s", name) + 1;
-	len += sprint(buf+len, "octet") + 1;
-
-	oport = a->port;
-	for(i = 0; i < 5; i++){
-		a->port = oport;
-		udpsend(ctlrno, a, buf, len);
-		a->port = 0;
-		if((rlen = udprecv(ctlrno, a, tftp, sizeof(Tftp))) < sizeof(tftp->header))
-			continue;
-
-		switch((tftp->header[0]<<8)|tftp->header[1]){
-
-		case Tftp_ERROR:
-			print("tftpopen: error (%d): %s\n",
-				(tftp->header[2]<<8)|tftp->header[3],
-			      (char*)tftp->data);
-			return -1;
-
-		case Tftp_DATA:
-			tftpblockno = 1;
-			len = (tftp->header[2]<<8)|tftp->header[3];
-			if(len != tftpblockno){
-				print("tftpopen: block error: %d\n", len);
-				nak(ctlrno, a, 1, "block error", 0);
-				return -1;
-			}
-			rlen -= sizeof(tftp->header);
-			if(rlen < TFTP_SEGSIZE){
-				/* ACK now, in case we don't later */
-				buf[0] = 0;
-				buf[1] = Tftp_ACK;
-				buf[2] = tftpblockno>>8;
-				buf[3] = tftpblockno;
-				udpsend(ctlrno, a, buf, sizeof(tftp->header));
-			}
-			return rlen;
-		}
-	}
-
-	print("tftpopen: failed to connect to server\n");
-	return -1;
-}
-
-static int
-tftpread(int ctlrno, Netaddr *a, Tftp *tftp, int dlen)
-{
-	uint8_t buf[4];
-	int try, blockno, len;
-
-	dlen += sizeof(tftp->header);
-
-	for(try = 0; try < 10; try++) {
-		buf[0] = 0;
-		buf[1] = Tftp_ACK;
-		buf[2] = tftpblockno>>8;
-		buf[3] = tftpblockno;
-
-		udpsend(ctlrno, a, buf, sizeof(buf));
-		len = udprecv(ctlrno, a, tftp, dlen);
-		if(len <= sizeof(tftp->header)){
-			if(debug)
-				print("tftpread: too short %d <= %d\n",
-					len, sizeof(tftp->header));
-			continue;
-		}
-		blockno = (tftp->header[2]<<8)|tftp->header[3];
-		if(blockno <= tftpblockno){
-			if(debug)
-				print("tftpread: blkno %d <= %d\n",
-					blockno, tftpblockno);
-			continue;
-		}
-
-		if(blockno == tftpblockno+1) {
-			tftpblockno++;
-			if(len < dlen) {	/* last packet; send final ack */
-				tftpblockno++;
-				buf[0] = 0;
-				buf[1] = Tftp_ACK;
-				buf[2] = tftpblockno>>8;
-				buf[3] = tftpblockno;
-				udpsend(ctlrno, a, buf, sizeof(buf));
-			}
-			return len-sizeof(tftp->header);
-		}
-		print("tftpread: block error: %d, expected %d\n",
-			blockno, tftpblockno+1);
-	}
-
-	return -1;
-}
-
-static int
-bootpopen(int ctlrno, char *file, Bootp *brep, int dotftpopen)
-{
-	Bootp req, *rep;
-	int i, n;
-	uint8_t *ea, rpkt[1024];
-	char name[128], *filename, *sysname;
-
-	if (debugload)
-		print("bootpopen: ether%d!%s...", ctlrno, file);
-	if((ea = etheraddr(ctlrno)) == 0){
-		print("invalid ctlrno %d\n", ctlrno);
-		return -1;
-	}
-
-	filename = 0;
-	sysname = 0;
-	if(file && *file){
-		strcpy(name, file);
-		if(filename = strchr(name, '!')){
-			sysname = name;
-			*filename++ = 0;
-		}
-		else
-			filename = name;
-	}
-
-	memset(&req, 0, sizeof(req));
-	req.op = Bootrequest;
-	req.htype = 1;			/* ethernet */
-	req.hlen = Eaddrlen;		/* ethernet */
-	memmove(req.chaddr, ea, Eaddrlen);
-	if(filename != nil)
-		strncpy(req.file, filename, sizeof(req.file));
-	if(sysname != nil)
-		strncpy(req.sname, sysname, sizeof(req.sname));
-
-	myaddr.ip = 0;
-	myaddr.port = BPportsrc;
-	memmove(myaddr.ea, ea, Eaddrlen);
-
-	rep = (Bootp*)rpkt;
-
-	etherrxflush(ctlrno);
-	for(i = 0; i < 20; i++) {
-		server.ip = Bcastip;
-		server.port = BPportdst;
-		memmove(server.ea, broadcast, sizeof(server.ea));
-		udpsend(ctlrno, &server, &req, sizeof(req));
-		if(udprecv(ctlrno, &server, rpkt, sizeof(rpkt)) <= 0)
-			continue;
-		if(memcmp(req.chaddr, rep->chaddr, Eaddrlen))
-			continue;
-		if(rep->htype != 1 || rep->hlen != Eaddrlen)
-			continue;
-		if(sysname == 0 || strcmp(sysname, rep->sname) == 0)
-			break;
-	}
-	if(i >= 20) {
-		print("bootp on ether%d for %s timed out\n", ctlrno, file);
-		return -1;
-	}
-	memmove(brep, rep, sizeof(Bootp));
-
-	if(!dotftpopen)
-		return 0;
-
-	if(filename == 0 || *filename == 0){
-		if(strcmp(rep->file, "/386/9pxeload") == 0)
-			return -1;
-		filename = rep->file;
-	}
-
-	if(rep->sname[0] != '\0')
-		 print("%s ", rep->sname);
-	print("(%d.%d.%d.%d!%d): %s\n",
-		rep->siaddr[0],
-		rep->siaddr[1],
-		rep->siaddr[2],
-		rep->siaddr[3],
-		server.port,
-		filename);
-
-	myaddr.ip = nhgetl(rep->yiaddr);
-	myaddr.port = tftpport++;
-	server.ip = nhgetl(rep->siaddr);
-	server.port = TFTPport;
-
-	if((n = tftpopen(ctlrno, &server, filename, &tftpb)) < 0)
-		return -1;
-
-	return n;
-}
-
-int
-bootpboot(int ctlrno, char *file, Boot *b)
-{
-	int n;
-	Bootp rep;
-
-	if((n = bootpopen(ctlrno, file, &rep, 1)) < 0)
-		return -1;
-
-	while(n == TFTP_SEGSIZE && bootpass(b, tftpb.data, n) == MORE){
-		n = tftpread(ctlrno, &server, &tftpb, sizeof(tftpb.data));
-		if(n < sizeof(tftpb.data))
-			break;
-	}
-
-	if(0 < n && n < sizeof(tftpb.data))	/* got to end of file */
-		bootpass(b, tftpb.data, n);
-	else
-		nak(ctlrno, &server, 3, "ok", 0);	/* tftpclose to abort transfer */
-	bootpass(b, nil, 0);	/* boot if possible */
-	return -1;
-}
-
-#include "fs.h"
-
-#define INIPATHLEN	64
-
-static struct {
-	Fs	fs;
-	char	ini[INIPATHLEN];
-} pxether[MaxEther];
-
-static int64_t
-pxediskseek(Fs*, int64_t)
-{
-	return -1LL;
-}
-
-static int32_t
-pxediskread(Fs*, void*, int32_t)
-{
-	return -1;
-}
-
-static int32_t
-pxeread(File* f, void* va, int32_t len)
-{
-	int n;
-	Bootp rep;
-	char *p, *v;
-
-	if((n = bootpopen(f->fs->dev, pxether[f->fs->dev].ini, &rep, 1)) < 0)
-		return -1;
-
-	p = v = va;
-	while(n > 0) {
-		if((p-v)+n > len)
-			n = len - (p-v);
-		memmove(p, tftpb.data, n);
-		p += n;
-		if(n != TFTP_SEGSIZE)
-			break;
-		if((n = tftpread(f->fs->dev, &server, &tftpb, sizeof(tftpb.data))) < 0)
-			return -1;
-	}
-	return p-v;
-}
-
-static int
-pxewalk(File* f, char* name)
-{
-	char *ini;
-	uint8_t *ea;
-
-	switch(f->walked){
-	default:
-		return -1;
-	case 0:
-		if(strcmp(name, "cfg") == 0){
-			f->walked = 1;
-			return 1;
-		}
-		break;
-	case 1:
-		if(strcmp(name, "pxe") == 0){
-			f->walked = 2;
-			return 1;
-		}
-		break;
-	case 2:
-		if(strcmp(name, "%E") != 0)
-			break;
-		f->walked = 3;
-
-		if((ea = etheraddr(f->fs->dev)) == 0){
-			print("invalid ctlrno %d\n", f->fs->dev);
-			return 0;
-		}
-
-		ini = pxether[f->fs->dev].ini;
-		/* use our mac address instead of relying on a bootp answer */
-		snprint(ini, INIPATHLEN, "/cfg/pxe/%E", ea);
-		f->path = ini;
-
-		return 1;
-	}
-	return 0;
-}
-
-void*
-pxegetfspart(int ctlrno, char* part, int)
-{
-	if(!pxe)
-		return nil;
-	if(strcmp(part, "*") != 0)
-		return nil;
-	if(ctlrno >= MaxEther)
-		return nil;
-	if(iniread && getconf("*pxeini") != nil)
-		return nil;
-
-	pxether[ctlrno].fs.dev = ctlrno;
-	pxether[ctlrno].fs.diskread = pxediskread;
-	pxether[ctlrno].fs.diskseek = pxediskseek;
-
-	pxether[ctlrno].fs.read = pxeread;
-	pxether[ctlrno].fs.walk = pxewalk;
-
-	pxether[ctlrno].fs.root.fs = &pxether[ctlrno].fs;
-	pxether[ctlrno].fs.root.walked = 0;
-
-	return &pxether[ctlrno].fs;
-}
-
-/*
- * hack to avoid queueing packets we don't care about.
- * needs to admit udp and aoe packets.
- */
-int
-interesting(void* data)
-{
-	int len;
-	uint32_t addr;
-	Netaddr *a = &server;
-	Udphdr *h;
-
-	h = data;
-	if(debug)
-		print("inpkt %E to %E...\n", h->s, h->d);
-
-	switch(nhgets(h->type)){
-	case 0x88a2:				/* AoE */
-		return 1;
-	case ET_IP:
-		break;
-	default:
-		if(debug)
-			print("not ipv4...");
-		return 0;
-	}
-
-	if((h->vihl & 0xf0) != IP_VER) {
-		if(debug)
-			print("not ipv4 (%#4.4ux) %#2.2ux...",
-				nhgets(h->type), h->vihl);
-		return 0;
-	}
-	if((h->vihl & 0x0f) != IP_HLEN) {
-		len = (h->vihl & 0xf)<<2;
-		if(len < (IP_HLEN<<2)) {
-			print("ip bad hlen %d %E to %E\n", len, h->s, h->d);
-			return 0;
-		}
-		/*
-		 * fudge the header start,
-		 * can't strip the options here,
-		 * but only looking at udp stuff
-		 * from here on.
-		 */
-		h = (Udphdr*)((uint8_t*)h + (len - (IP_HLEN<<2)));
-
-		if(debug)
-			print("fudge %d\n", len);
-	}
-	if(h->udpproto != IP_UDPPROTO) {
-		if(debug)
-			print("not udp (%d)...", h->udpproto);
-		return 0;
-	}
-
-	if(debug)
-		print("okay udp...");
-
-	if(a->port != 0 && nhgets(h->udpsport) != a->port) {
-		if(debug)
-			print("udpport %ux not %ux\n",
-				nhgets(h->udpsport), a->port);
-		return 0;
-	}
-
-	addr = nhgetl(h->udpsrc);
-	if(a->ip != Bcastip && a->ip != addr) {
-		if(debug)
-			print("bad ip %lux not %lux\n", addr, a->ip);
-		return 0;
-	}
-	return 1;
-}

+ 0 - 147
sys/src/9/w/pxeload/cga.c

@@ -1,147 +0,0 @@
-/*
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
-
-#include "u.h"
-#include "lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-
-enum {
-	Black		= 0x00,
-	Blue		= 0x01,
-	Green		= 0x02,
-	Cyan		= 0x03,
-	Red		= 0x04,
-	Magenta		= 0x05,
-	Brown		= 0x06,
-	Grey		= 0x07,
-
-	Bright 		= 0x08,
-	Blinking	= 0x80,
-
-	Attr		= (Black<<4)|Grey,	/* (background<<4)|foreground */
-};
-
-enum {
-	Index		= 0x3D4,
-	Data		= Index+1,
-
-	Width		= 80*2,
-	Height		= 25,
-
-	Poststrlen	= 0,
-	Postcodelen	= 2,
-	Postlen		= Poststrlen+Postcodelen,
-};
-
-#define CGA		((uint8_t*)KADDR(0xB8000))
-
-static Lock cgalock;
-static int cgapos;
-static int cgainitdone;
-
-static int
-cgaregr(int index)
-{
-	outb(Index, index);
-	return inb(Data) & 0xFF;
-}
-
-static void
-cgaregw(int index, int data)
-{
-	outb(Index, index);
-	outb(Data, data);
-}
-
-static void
-cgacursor(void)
-{
-	uint8_t *cga;
-
-	cgaregw(0x0E, (cgapos/2>>8) & 0xFF);
-	cgaregw(0x0F, cgapos/2 & 0xFF);
-
-	cga = CGA;
-	cga[cgapos+1] = Attr;
-}
-
-static void
-cgaputc(int c)
-{
-	int i;
-	uint8_t *cga, *p;
-
-	cga = CGA;
-
-	if(c == '\n'){
-		cgapos = cgapos/Width;
-		cgapos = (cgapos+1)*Width;
-	}
-	else if(c == '\t'){
-		i = 8 - ((cgapos/2)&7);
-		while(i-- > 0)
-			cgaputc(' ');
-	}
-	else if(c == '\b'){
-		if(cgapos >= 2)
-			cgapos -= 2;
-		cgaputc(' ');
-		cgapos -= 2;
-	}
-	else{
-		cga[cgapos++] = c;
-		cga[cgapos++] = Attr;
-	}
-	if(cgapos >= (Width*Height)-Postlen*2){
-		memmove(cga, &cga[Width], Width*(Height-1));
-		p = &cga[Width*(Height-1)-Postlen*2];
-		for(i = 0; i < Width/2; i++){
-			*p++ = ' ';
-			*p++ = Attr;
-		}
-		cgapos -= Width;
-	}
-	cgacursor();
-}
-
-void
-cgaconsputs(char* s, int n)
-{
-	ilock(&cgalock);
-	while(n-- > 0)
-		cgaputc(*s++);
-	iunlock(&cgalock);
-}
-
-void
-cgapost(int code)
-{
-	uint8_t *cga;
-
-	static char hex[] = "0123456789ABCDEF";
-
-	cga = CGA;
-	cga[Width*Height-Postcodelen*2] = hex[(code>>4) & 0x0F];
-	cga[Width*Height-Postcodelen*2+1] = Attr;
-	cga[Width*Height-Postcodelen*2+2] = hex[code & 0x0F];
-	cga[Width*Height-Postcodelen*2+3] = Attr;
-}
-
-void
-cgainit(void)
-{
-	ilock(&cgalock);
-	cgapos = cgaregr(0x0E)<<8;
-	cgapos |= cgaregr(0x0F);
-	cgapos *= 2;
-	cgainitdone = 1;
-	iunlock(&cgalock);
-}

+ 0 - 314
sys/src/9/w/pxeload/clock.c

@@ -1,314 +0,0 @@
-/*
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
-
-#include	"u.h"
-#include	"lib.h"
-#include	"mem.h"
-#include	"dat.h"
-#include	"fns.h"
-#include	"io.h"
-#include	"ureg.h"
-
-/*
- *  8253 timer
- */
-enum
-{
-	T0cntr=	0x40,		/* counter ports */
-	T1cntr=	0x41,		/* ... */
-	T2cntr=	0x42,		/* ... */
-	Tmode=	0x43,		/* mode port */
-
-	/* commands */
-	Latch0=	0x00,		/* latch counter 0's value */
-	Load0=	0x30,		/* load counter 0 with 2 bytes */
-
-	/* modes */
-	Square=	0x36,		/* perioic square wave */
-
-	Freq=	1193182,	/* Real clock frequency */
-};
-
-static uint64_t cpuhz = 66000000;
-static int cpumhz = 66;
-static int loopconst = 100;
-int cpuidax, cpuiddx;
-int havetsc;
-
-extern void _cycles(uint64_t*);		/* in l.s */
-extern void wrmsr(int, int64_t);
-
-static void
-clockintr(Ureg*, void*)
-{
-	machp()->ticks++;
-	checkalarms();
-}
-
-#define STEPPING(x)	((x)&0xf)
-#define X86MODEL(x)	(((x)>>4)&0xf)
-#define X86FAMILY(x)	(((x)>>8)&0xf)
-
-enum
-{
-	/* flags */
-	CpuidFPU	= 0x001,	/* on-chip floating point unit */
-	CpuidMCE	= 0x080,	/* machine check exception */
-	CpuidCX8	= 0x100,	/* CMPXCHG8B instruction */
-};
-
-typedef struct
-{
-	int family;
-	int model;
-	int aalcycles;
-	char *name;
-} X86type;
-
-X86type x86intel[] =
-{
-	{ 4,	0,	22,	"486DX", },	/* known chips */
-	{ 4,	1,	22,	"486DX50", },
-	{ 4,	2,	22,	"486SX", },
-	{ 4,	3,	22,	"486DX2", },
-	{ 4,	4,	22,	"486SL", },
-	{ 4,	5,	22,	"486SX2", },
-	{ 4,	7,	22,	"DX2WB", },	/* P24D */
-	{ 4,	8,	22,	"DX4", },	/* P24C */
-	{ 4,	9,	22,	"DX4WB", },	/* P24CT */
-	{ 5,	0,	23,	"P5", },
-	{ 5,	1,	23,	"P5", },
-	{ 5,	2,	23,	"P54C", },
-	{ 5,	3,	23,	"P24T", },
-	{ 5,	4,	23,	"P55C MMX", },
-	{ 5,	7,	23,	"P54C VRT", },
-	{ 6,	1,	16,	"PentiumPro", },/* trial and error */
-	{ 6,	3,	16,	"PentiumII", },
-	{ 6,	5,	16,	"PentiumII/Xeon", },
-	{ 6,	6,	16,	"Celeron", },
-	{ 6,	7,	16,	"PentiumIII/Xeon", },
-	{ 6,	8,	16,	"PentiumIII/Xeon", },
-	{ 6,	0xB,	16,	"PentiumIII/Xeon", },
-	{ 0xF,	1,	16,	"P4", },	/* P4 */
-	{ 0xF,	2,	16,	"PentiumIV/Xeon", },
-
-	{ 3,	-1,	32,	"386", },	/* family defaults */
-	{ 4,	-1,	22,	"486", },
-	{ 5,	-1,	23,	"P5", },
-	{ 6,	-1,	16,	"P6", },
-	{ 0xF,	-1,	16,	"P4", },	/* P4 */
-
-	{ -1,	-1,	16,	"unknown", },	/* total default */
-};
-
-
-/*
- * The AMD processors all implement the CPUID instruction.
- * The later ones also return the processor name via functions
- * 0x80000002, 0x80000003 and 0x80000004 in registers AX, BX, CX
- * and DX:
- *	K5	"AMD-K5(tm) Processor"
- *	K6	"AMD-K6tm w/ multimedia extensions"
- *	K6 3D	"AMD-K6(tm) 3D processor"
- *	K6 3D+	?
- */
-static X86type x86amd[] =
-{
-	{ 5,	0,	23,	"AMD-K5", },	/* guesswork */
-	{ 5,	1,	23,	"AMD-K5", },	/* guesswork */
-	{ 5,	2,	23,	"AMD-K5", },	/* guesswork */
-	{ 5,	3,	23,	"AMD-K5", },	/* guesswork */
-	{ 5,	6,	11,	"AMD-K6", },	/* trial and error */
-	{ 5,	7,	11,	"AMD-K6", },	/* trial and error */
-	{ 5,	8,	11,	"AMD-K6-2", },	/* trial and error */
-	{ 5,	9,	11,	"AMD-K6-III", },/* trial and error */
-
-	{ 6,	1,	11,	"AMD-Athlon", },/* trial and error */
-	{ 6,	2,	11,	"AMD-Athlon", },/* trial and error */
-
-	{ 4,	-1,	22,	"Am486", },	/* guesswork */
-	{ 5,	-1,	23,	"AMD-K5/K6", },	/* guesswork */
-	{ 6,	-1,	11,	"AMD-Athlon", },/* guesswork */
-	{ 0xF,	-1,	11,	"AMD64", },	/* guesswork */
-
-	{ -1,	-1,	11,	"unknown", },	/* total default */
-};
-
-static X86type	*cputype;
-
-
-void
-delay(int millisecs)
-{
-	millisecs *= loopconst;
-	if(millisecs <= 0)
-		millisecs = 1;
-	aamloop(millisecs);
-}
-
-void
-microdelay(int microsecs)
-{
-	microsecs *= loopconst;
-	microsecs /= 1000;
-	if(microsecs <= 0)
-		microsecs = 1;
-	aamloop(microsecs);
-}
-
-extern void cpuid(char*, int*, int*);
-
-X86type*
-cpuidentify(void)
-{
-	int family, model;
-	X86type *t;
-	char cpuidid[16];
-	int cpuidax, cpuiddx;
-
-	cpuid(cpuidid, &cpuidax, &cpuiddx);
-	if(strncmp(cpuidid, "AuthenticAMD", 12) == 0)
-		t = x86amd;
-	else
-		t = x86intel;
-	family = X86FAMILY(cpuidax);
-	model = X86MODEL(cpuidax);
-	if (1)
-		print("cpuidentify: cpuidax 0x%ux cpuiddx 0x%ux\n",
-			cpuidax, cpuiddx);
-	while(t->name){
-		if((t->family == family && t->model == model)
-		|| (t->family == family && t->model == -1)
-		|| (t->family == -1))
-			break;
-		t++;
-	}
-	if(t->name == nil)
-		panic("cpuidentify");
-
-	if(cpuiddx & 0x10){
-		havetsc = 1;
-		if(cpuiddx & 0x20)
-			wrmsr(0x10, 0);
-	}
-
-	return t;
-}
-
-void
-clockinit(void)
-{
-	uint64_t a, b, cpufreq;
-	int loops, incr, x, y;
-	X86type *t;
-
-	/*
-	 *  set vector for clock interrupts
-	 */
-	setvec(VectorCLOCK, clockintr, 0);
-
-	t = cpuidentify();
-
-	/*
-	 *  set clock for 1/HZ seconds
-	 */
-	outb(Tmode, Load0|Square);
-	outb(T0cntr, (Freq/HZ));	/* low byte */
-	outb(T0cntr, (Freq/HZ)>>8);	/* high byte */
-
-	/*
-	 * Introduce a little delay to make sure the count is
-	 * latched and the timer is counting down; with a fast
-	 * enough processor this may not be the case.
-	 * The i8254 (which this probably is) has a read-back
-	 * command which can be used to make sure the counting
-	 * register has been written into the counting element.
-	 */
-	x = (Freq/HZ);
-	for(loops = 0; loops < 100000 && x >= (Freq/HZ); loops++){
-		outb(Tmode, Latch0);
-		x = inb(T0cntr);
-		x |= inb(T0cntr)<<8;
-	}
-
-	/* find biggest loop that doesn't wrap */
-	incr = 16000000/(t->aalcycles*HZ*2);
-	x = 2000;
-	for(loops = incr; loops < 64*1024; loops += incr) {
-
-		/*
-		 *  measure time for the loop
-		 *
-		 *			MOVL	loops,CX
-		 *	aaml1:	 	AAM
-		 *			LOOP	aaml1
-		 *
-		 *  the time for the loop should be independent of external
-		 *  cache and memory system since it fits in the execution
-		 *  prefetch buffer.
-		 *
-		 */
-		outb(Tmode, Latch0);
-		if(havetsc)
-			_cycles(&a);
-		x = inb(T0cntr);
-		x |= inb(T0cntr)<<8;
-		aamloop(loops);
-		outb(Tmode, Latch0);
-		if(havetsc)
-			_cycles(&b);
-		y = inb(T0cntr);
-		y |= inb(T0cntr)<<8;
-		x -= y;
-
-		if(x < 0)
-			x += Freq/HZ;
-
-		if(x > Freq/(3*HZ))
-			break;
-	}
-
-	/*
- 	 *  figure out clock frequency and a loop multiplier for delay().
-	 *  counter  goes at twice the frequency, once per transition,
-	 *  i.e., twice per square wave
-	 */
-	cpufreq = (int64_t)loops*((t->aalcycles*2*Freq)/x);
-	loopconst = (cpufreq/1000)/t->aalcycles;	/* AAM+LOOP's for 1 ms */
-
-	if(havetsc){
-		/* counter goes up by 2*Freq */
-		b = (b-a)<<1;
-		b *= Freq;
-		b /= x;
-
-		/*
-		 *  round to the nearest megahz
-		 */
-		cpumhz = (b+500000)/1000000L;
-		cpuhz = b;
-	}
-	else{
-		/*
-		 *  add in possible .5% error and convert to MHz
-		 */
-		cpumhz = (cpufreq + cpufreq/200)/1000000;
-		cpuhz = cpufreq;
-	}
-
-	if(debug){
-		int timeo;
-
-		print("%dMHz %s loop %d\n", cpumhz, t->name, loopconst);
-		print("tick...");
-		for(timeo = 0; timeo < 10; timeo++)
-			delay(1000);
-		print("tock...\n");
-	}
-}

+ 0 - 596
sys/src/9/w/pxeload/conf.c

@@ -1,596 +0,0 @@
-/*
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
-
-#include "u.h"
-#include "lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-
-#include "fs.h"
-
-/*
- * Where configuration info is left for the loaded programme.
- * This will turn into a structure as more is done by the boot loader
- * (e.g. why parse the .ini file twice?).
- * There are 3584 bytes available at CONFADDR.
- *
- * The low-level boot routines in l.s leave data for us at CONFADDR,
- * which we pick up before reading the plan9.ini file.
- */
-#define BOOTLINELEN	64
-#define BOOTARGS	((char*)(CONFADDR+BOOTLINELEN))
-#define	BOOTARGSLEN	(3584-0x200-BOOTLINELEN)
-#define	MAXCONF		100
-
-static char *confname[MAXCONF];
-static char *confval[MAXCONF];
-static int nconf;
-
-extern char **ini;
-
-typedef struct {
-	char*	name;
-	int	start;
-	int	end;
-} Mblock;
-
-typedef struct {
-	char*	tag;
-	Mblock*	mb;
-} Mitem;
-
-static Mblock mblock[MAXCONF];
-static int nmblock;
-static Mitem mitem[MAXCONF];
-static int nmitem;
-static char* mdefault;
-static char mdefaultbuf[10];
-static int mtimeout;
-
-static char*
-comma(char* line, char** residue)
-{
-	char *q, *r;
-
-	if((q = strchr(line, ',')) != nil){
-		*q++ = 0;
-		if(*q == ' ')
-			q++;
-	}
-	*residue = q;
-
-	if((r = strchr(line, ' ')) != nil)
-		*r = 0;
-
-	if(*line == ' ')
-		line++;
-	return line;
-}
-
-static Mblock*
-findblock(char* name, char** residue)
-{
-	int i;
-	char *p;
-
-	p = comma(name, residue);
-	for(i = 0; i < nmblock; i++){
-		if(strcmp(p, mblock[i].name) == 0)
-			return &mblock[i];
-	}
-	return nil;
-}
-
-static Mitem*
-finditem(char* name, char** residue)
-{
-	int i;
-	char *p;
-
-	p = comma(name, residue);
-	for(i = 0; i < nmitem; i++){
-		if(strcmp(p, mitem[i].mb->name) == 0)
-			return &mitem[i];
-	}
-	return nil;
-}
-
-static void
-parsemenu(char* str, char* scratch, int len)
-{
-	Mitem *mi;
-	Mblock *mb, *menu;
-	char buf[20], *p, *q, *line[MAXCONF];
-	int i, inblock, n, show;
-
-	inblock = 0;
-	menu = nil;
-	memmove(scratch, str, len);
-	n = getfields(scratch, line, MAXCONF, '\n');
-	if(n >= MAXCONF)
-		print("warning: possibly too many lines in plan9.ini\n");
-	for(i = 0; i < n; i++){
-		p = line[i];
-		if(inblock && *p == '['){
-			mblock[nmblock].end = i;
-			if(strcmp(mblock[nmblock].name, "menu") == 0)
-				menu = &mblock[nmblock];
-			nmblock++;
-			inblock = 0;
-		}
-		if(*p == '['){
-			if(nmblock == 0 && i != 0){
-				mblock[nmblock].name = "common";
-				mblock[nmblock].start = 0;
-				mblock[nmblock].end = i;
-				nmblock++;
-			}
-			q = strchr(p+1, ']');
-			if(q == nil || *(q+1) != 0){
-				print("malformed menu block header - %s\n", p);
-				return;
-			}
-			*q = 0;
-			mblock[nmblock].name = p+1;
-			mblock[nmblock].start = i+1;
-			inblock = 1;
-		}
-	}
-
-	if(inblock){
-		mblock[nmblock].end = i;
-		nmblock++;
-	}
-	if(menu == nil)
-		return;
-	if(nmblock < 2){
-		print("incomplete menu specification\n");
-		return;
-	}
-
-	for(i = menu->start; i < menu->end; i++){
-		p = line[i];
-		if(cistrncmp(p, "menuitem=", 9) == 0){
-			p += 9;
-			if((mb = findblock(p, &q)) == nil){
-				print("no block for menuitem %s\n", p);
-				return;
-			}
-			if(q != nil)
-				mitem[nmitem].tag = q;
-			else
-				mitem[nmitem].tag = mb->name;
-			mitem[nmitem].mb = mb;
-			nmitem++;
-		}
-		else if(cistrncmp(p, "menudefault=", 12) == 0){
-			p += 12;
-			if((mi = finditem(p, &q)) == nil){
-				print("no item for menudefault %s\n", p);
-				return;
-			}
-			if(q != nil)
-				mtimeout = strtol(q, 0, 0);
-			sprint(mdefaultbuf, "%ld", mi-mitem+1);
-			mdefault = mdefaultbuf;
-		}
-		else if(cistrncmp(p, "menuconsole=", 12) == 0){
-			p += 12;
-			p = comma(p, &q);
-			consinit(p, q);
-		}
-		else{
-			print("invalid line in [menu] block - %s\n", p);
-			return;
-		}
-	}
-
-again:
-	print("\nPlan 9 Startup Menu:\n====================\n");
-	for(i = 0; i < nmitem; i++)
-		print("    %d. %s\n", i+1, mitem[i].tag);
-	for(;;){
-		getstr("Selection", buf, sizeof(buf), mdefault, mtimeout);
-		mtimeout = 0;
-		i = strtol(buf, &p, 0)-1;
-		if(i < 0 || i >= nmitem)
-			goto again;
-		switch(*p){
-		case 'p':
-		case 'P':
-			show = 1;
-			print("\n");
-			break;
-		case 0:
-			show = 0;
-			break;
-		default:
-			continue;
-
-		}
-		mi = &mitem[i];
-
-		p = str;
-		p += sprint(p, "menuitem=%s\n", mi->mb->name);
-		for(i = 0; i < nmblock; i++){
-			mb = &mblock[i];
-			if(mi->mb != mb && cistrcmp(mb->name, "common") != 0)
-				continue;
-			for(n = mb->start; n < mb->end; n++)
-				p += sprint(p, "%s\n", line[n]);
-		}
-
-		if(show){
-			for(q = str; q < p; q += i){
-				if((i = print(q)) <= 0)
-					break;
-			}
-			goto again;
-		}
-		break;
-	}
-	print("\n");
-}
-
-/*
-static void
-msleep(int msec)
-{
-	ulong start;
-
-	for(start = machp()->ticks; TK2MS(machp()->ticks - start) < msec; )
-		;
-}
-*/
-
-void
-readlsconf(void)
-{
-	int i, n;
-	uint8_t *p;
-	MMap *map;
-	uint64_t addr, len;
-
-	p = (uint8_t*)ROUND((uint32_t)end, BY2PG);
-	for(n = 0; n < 20; n++){
-		if(*p == 0)
-			break;
-		if(memcmp(p, "APM\0", 4) == 0){
-			apm.haveinfo = 1;
-			apm.ax = *(uint16_t*)(p+4);
-			apm.cx = *(uint16_t*)(p+6);
-			apm.dx = *(uint16_t*)(p+8);
-			apm.di = *(uint16_t*)(p+10);
-			apm.ebx = *(uint32_t*)(p+12);
-			apm.esi = *(uint32_t*)(p+16);
-			print("apm ax=%x cx=%x dx=%x di=%x ebx=%x esi=%x\n",
-				apm.ax, apm.cx, apm.dx,
-				apm.di, apm.ebx, apm.esi);
-			p += 20;
-			continue;
-		}
-		else if(memcmp(p, "MAP\0", 4) == 0){
-			map = (MMap*)p;
-
-			switch(map->type){
-			default:
-				if(vflag)
-					print("type %ud", map->type);
-				break;
-			case 1:
-				if(vflag)
-					print("Memory");
-				break;
-			case 2:
-				if(vflag)
-					print("reserved");
-				break;
-			case 3:
-				if(vflag)
-					print("ACPI Reclaim Memory");
-				break;
-			case 4:
-				if(vflag)
-					print("ACPI NVS Memory");
-				break;
-			}
-			addr = (((uint64_t)map->base[1])<<32)|map->base[0];
-			len = (((uint64_t)map->length[1])<<32)|map->length[0];
-			if(vflag)
-				print("\n\t0x%16.16lluX 0x%16.16lluX (%llud)\n",
-					addr, addr+len, len);
-
-			if(nmmap < nelem(mmap)){
-				memmove(&mmap[nmmap], map, sizeof(MMap));
-				mmap[nmmap].size = 20;
-				nmmap++;
-			}
-			p += 24;
-			continue;
-		}
-		else{
-			for(i = 0; i < 24; i++)
-				print(" %2.2uX", *(p+i));
-			print("\n");
-		}
-		break;
-	}
-}
-
-char*
-getconf(char *name)
-{
-	int i, n, nmatch;
-	char buf[20];
-
-	nmatch = 0;
-	for(i = 0; i < nconf; i++)
-		if(cistrcmp(confname[i], name) == 0)
-			nmatch++;
-
-	switch(nmatch) {
-	default:
-		print("\n");
-		nmatch = 0;
-		for(i = 0; i < nconf; i++)
-			if(cistrcmp(confname[i], name) == 0)
-				print("%d. %s\n", ++nmatch, confval[i]);
-		print("%d. none of the above\n", ++nmatch);
-		do {
-			getstr(name, buf, sizeof(buf), nil, 0);
-			n = atoi(buf);
-		} while(n < 1 || n > nmatch);
-
-		for(i = 0; i < nconf; i++)
-			if(cistrcmp(confname[i], name) == 0)
-				if(--n == 0)
-					return confval[i];
-		break;
-
-	case 1:
-		for(i = 0; i < nconf; i++)
-			if(cistrcmp(confname[i], name) == 0)
-				return confval[i];
-		break;
-
-	case 0:
-		break;
-	}
-	return nil;
-}
-
-void
-addconf(char *fmt, ...)
-{
-	va_list arg;
-
-	va_start(arg, fmt);
-	vseprint(BOOTARGS+strlen(BOOTARGS), BOOTARGS+BOOTARGSLEN, fmt, arg);
-	va_end(arg);
-}
-
-void
-changeconf(char *fmt, ...)
-{
-	va_list arg;
-	char *p, *q, pref[20], buf[128];
-
-	va_start(arg, fmt);
-	vseprint(buf, buf+sizeof buf, fmt, arg);
-	va_end(arg);
-	strncpy(pref+1, buf, 19);
-	pref[19] = '\0';
-	if(p = strchr(pref, '='))
-		*(p+1) = '\0';
-	else
-		print("warning: did not change %s in plan9.ini\n", buf);
-
-	/* find old line by looking for \nwhat= */
-	pref[0] = '\n';
-	if(strncmp(BOOTARGS, pref+1, strlen(pref+1)) == 0)
-		p = BOOTARGS;
-	else if(p = strstr(BOOTARGS, pref))
-		p++;
-	else
-		p = nil;
-
-	/* move rest of args up, deleting what= line. */
-	if(p != nil && (q = strchr(p, '\n')) != nil)
-		memmove(p, q+1, strlen(q+1)+1);
-
-	/* add replacement to end */
-	addconf("%s", buf);
-}
-
-/*
- *  read configuration file
- */
-static char inibuf[BOOTARGSLEN];
-static char id[8] = "ZORT 0\r\n";
-
-int
-dotini(Fs *fs)
-{
-	File rc;
-	int blankline, i, incomment, inspace, n;
-	char *cp, *p, *q, *line[MAXCONF];
-
-	if(fswalk(fs, *ini, &rc) <= 0)
-		return -1;
-
-	cp = inibuf;
-	*cp = 0;
-	n = fsread(&rc, cp, BOOTARGSLEN-1);
-	if(n <= 0)
-		return -1;
-
-	cp[n] = 0;
-
-	/*
-	 * Strip out '\r', change '\t' -> ' '.
-	 * Change runs of spaces into single spaces.
-	 * Strip out trailing spaces, blank lines.
-	 *
-	 * We do this before we make the copy so that if we
-	 * need to change the copy, it is already fairly clean.
-	 * The main need is in the case when plan9.ini has been
-	 * padded with lots of trailing spaces, as is the case
-	 * for those created during a distribution install.
-	 */
-	p = cp;
-	blankline = 1;
-	incomment = inspace = 0;
-	for(q = cp; *q; q++){
-		if(*q == '\r')
-			continue;
-		if(*q == '\t')
-			*q = ' ';
-		if(*q == ' '){
-			inspace = 1;
-			continue;
-		}
-		if(*q == '\n'){
-			if(!blankline){
-				if(!incomment)
-					*p++ = '\n';
-				blankline = 1;
-			}
-			incomment = inspace = 0;
-			continue;
-		}
-		if(inspace){
-			if(!blankline && !incomment)
-				*p++ = ' ';
-			inspace = 0;
-		}
-		if(blankline && *q == '#')
-			incomment = 1;
-		blankline = 0;
-		if(!incomment)
-			*p++ = *q;
-	}
-	if(p > cp && p[-1] != '\n')
-		*p++ = '\n';
-	*p++ = 0;
-	n = p-cp;
-
-	parsemenu(cp, BOOTARGS, n);
-
-	/*
-	 * Keep a copy.
-	 * We could change this to pass the parsed strings
-	 * to the booted programme instead of the raw
-	 * string, then it only gets done once.
-	 */
-	if(strncmp(cp, id, sizeof(id))){
-		memmove(BOOTARGS, id, sizeof(id));
-		if(n+1+sizeof(id) >= BOOTARGSLEN)
-			n -= sizeof(id);
-		memmove(BOOTARGS+sizeof(id), cp, n+1);
-	}
-	else
-		memmove(BOOTARGS, cp, n+1);
-
-	n = getfields(cp, line, MAXCONF, '\n');
-	for(i = 0; i < n; i++){
-		cp = strchr(line[i], '=');
-		if(cp == 0)
-			continue;
-		*cp++ = 0;
-		if(cp - line[i] >= NAMELEN+1)
-			*(line[i]+NAMELEN-1) = 0;
-		confname[nconf] = line[i];
-		confval[nconf] = cp;
-		nconf++;
-	}
-	return 0;
-}
-
-static int
-parseether(uint8_t *to, char *from)
-{
-	char nip[4];
-	char *p;
-	int i;
-
-	p = from;
-	while(*p == ' ')
-		++p;
-	for(i = 0; i < 6; i++){
-		if(*p == 0)
-			return -1;
-		nip[0] = *p++;
-		if(*p == 0)
-			return -1;
-		nip[1] = *p++;
-		nip[2] = 0;
-		to[i] = strtoul(nip, 0, 16);
-		if(*p == ':')
-			p++;
-	}
-	return 0;
-}
-
-int
-isaconfig(char *class, int ctlrno, ISAConf *isa)
-{
-	int i;
-	char cc[NAMELEN], *p, *r;
-
-	snprint(cc, sizeof cc, "%s%d", class, ctlrno);
-	if((p = getconf(cc)) == nil)
-		return 0;
-
-	isa->nopt = 0;
-	while(*p){
-		/*
-		 * Like tokenize, but non-destructive.
-		 */
-		while(*p == ' ' || *p == '\t')
-			p++;
-		if(*p == 0)
-			break;
-		if(isa->nopt < NISAOPT){
-			r = isa->opt[isa->nopt];
-			while(*p != 0 && *p != ' ' && *p != '\t'){
-				*r++ = *p++;
-				if(r-isa->opt[isa->nopt] >= ISAOPTLEN-1)
-					break;
-			}
-			*r = '\0';
-			isa->nopt++;
-		}
-		while(*p != 0 && *p != ' ' && *p != '\t')
-			p++;
-	}
-	for(i = 0; i < isa->nopt; i++){
-		p = isa->opt[i];
-		if(cistrncmp(p, "type=", 5) == 0)
-			isa->type = p + 5;
-		else if(cistrncmp(p, "port=", 5) == 0)
-			isa->port = strtoul(p+5, &p, 0);
-		else if(cistrncmp(p, "irq=", 4) == 0)
-			isa->irq = strtoul(p+4, &p, 0);
-		else if(cistrncmp(p, "dma=", 4) == 0)
-			isa->dma = strtoul(p+4, &p, 0);
-		else if(cistrncmp(p, "mem=", 4) == 0)
-			isa->mem = strtoul(p+4, &p, 0);
-		else if(cistrncmp(p, "size=", 5) == 0)
-			isa->size = strtoul(p+5, &p, 0);
-		else if(cistrncmp(p, "freq=", 5) == 0)
-			isa->freq = strtoul(p+5, &p, 0);
-		else if(cistrncmp(p, "ea=", 3) == 0){
-			if(parseether(isa->ea, p+3) == -1)
-				memset(isa->ea, 0, 6);
-		}
-	}
-	return 1;
-}

+ 0 - 235
sys/src/9/w/pxeload/console.c

@@ -1,235 +0,0 @@
-/*
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
-
-#include "u.h"
-#include "lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-
-IOQ consiq;
-IOQ consoq;
-
-static int useuart;
-
-void
-kbdchar(int c)
-{
-	c &= 0x7F;
-	if(c == 0x10)
-		warp86("\n^P\n", 0);
-	if(c == 0x12)
-		debug = !debug;
-	consiq.putc(&consiq, c);
-}
-
-static int
-consputc(void)
-{
-	return consoq.getc(&consoq);
-}
-
-void
-kbdinit(void)
-{
-	i8042init();
-	qinit(&consiq);
-}
-
-int
-consinit(char* name, char* speed)
-{
-	int baud, port;
-
-	if(name == nil || cistrcmp(name, "cga") == 0)
-		return 0;
-	port = strtoul(name, 0, 0);
-	if(port < 0 || port > 1)
-		return 0;
-	if(speed == nil || (baud = strtoul(speed, 0, 0)) == 0)
-		baud = 9600;
-
-	qinit(&consoq);
-
-	if(uartspecial(port, kbdchar, consputc, baud) == 0)
-		return 0;
-	useuart = 1;
-	uartputs(&consoq, "\n", 1);
-
-	return 1;
-}
-
-void
-consdrain(void)
-{
-	if(useuart)
-		uartdrain(&consoq);
-}
-
-void
-consputs(char* s, int n)
-{
-	cgaconsputs(s, n);
-	if(useuart)
-		uartputs(&consoq, s, n);
-}
-
-void
-warp86(char* s, uint32_t)
-{
-	if(s == nil)
-		s = "Warp86\n";
-	print(s);
-	spllo();
-
-	impulse();
-
-	i8042reset();
-
-	/*
-	 * Often the BIOS hangs during restart if a conventional 8042
-	 * warm-boot sequence is tried. The following is Intel specific and
-	 * seems to perform a cold-boot, but at least it comes back.
-	 * And sometimes there is no keyboard...
-	 *
-	 * The reset register (0xcf9) is usually in one of the bridge
-	 * chips. The actual location and sequence could be extracted from
-	 * ACPI but why bother, this is the end of the line anyway.
-	 */
-	print("Takes a licking and keeps on ticking...\n");
-	*(uint16_t*)KADDR(0x472) = 0x1234;	/* BIOS warm-boot flag */
-	outb(0xcf9, 0x02);
-	outb(0xcf9, 0x06);
-
-	for(;;)
-		idle();
-}
-
-static int
-getline(char *buf, int size, int timeout)
-{
-	int c, i=0;
-	uint32_t start;
-	char echo;
-
-	for (;;) {
-		start = machp()->ticks;
-		do{
-			/* timeout seconds to first char */
-			if(timeout && ((machp()->ticks - start) > timeout*HZ))
-				return -2;
-			c = consiq.getc(&consiq);
-		}while(c == -1);
-		timeout = 0;
-
-		if(c == '\r')
-			c = '\n'; 		/* turn carriage return into newline */
-		if(c == '\177')
-			c = '\010';		/* turn delete into backspace */
-		if(c == '\025')
-			echo = '\n';		/* echo ^U as a newline */
-		else
-			echo = c;
-		consputs(&echo, 1);
-
-		if(c == '\010'){
-			if(i > 0)
-				i--; /* bs deletes last character */
-			continue;
-		}
-		/* a newline ends a line */
-		if (c == '\n')
-			break;
-		/* ^U wipes out the line */
-		if (c =='\025')
-			return -1;
-		if(i == size)
-			return size;
-		buf[i++] = c;
-	}
-	buf[i] = 0;
-	return i;
-}
-
-int
-getstr(char *prompt, char *buf, int size, char *def, int timeout)
-{
-	int len, isdefault;
-	char pbuf[PRINTSIZE];
-
-	buf[0] = 0;
-	isdefault = (def && *def);
-	if(isdefault == 0){
-		timeout = 0;
-		sprint(pbuf, "%s: ", prompt);
-	}
-	else if(timeout)
-		sprint(pbuf, "%s[default==%s (%ds timeout)]: ", prompt, def, timeout);
-	else
-		sprint(pbuf, "%s[default==%s]: ", prompt, def);
-	for (;;) {
-		print(pbuf);
-		len = getline(buf, size, timeout);
-		switch(len){
-		case 0:
-			/* RETURN */
-			if(isdefault)
-				break;
-			continue;
-		case -1:
-			/* ^U typed */
-			continue;
-		case -2:
-			/* timeout, use default */
-			consputs("\n", 1);
-			len = 0;
-			break;
-		default:
-			break;
-		}
-		if(len >= size){
-			print("line too long\n");
-			continue;
-		}
-		break;
-	}
-	if(len == 0 && isdefault)
-		strcpy(buf, def);
-	return 0;
-}
-
-void
-panic(char *fmt, ...)
-{
-	int n;
-	va_list arg;
-	char buf[PRINTSIZE];
-
-	strcpy(buf, "panic: ");
-	va_start(arg, fmt);
-	n = vseprint(buf+7, buf+sizeof(buf), fmt, arg) - buf;
-	va_end(arg);
-	buf[n] = '\n';
-	consputs(buf, n+1);
-
-//floppymemwrite();
-splhi(); for(;;);
-	if(etherdetach)
-		etherdetach();
-	if(sddetach)
-		sddetach();
-
-	consputs("\nPress almost any key to reset...", 32);
-	spllo();
-	while(consiq.getc(&consiq) == -1)
-		;
-
-	warp86(nil, 0);
-}

+ 0 - 334
sys/src/9/w/pxeload/dat.h

@@ -1,334 +0,0 @@
-/* 
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
-
-typedef struct List {
-	void	*next;
-} List;
-
-typedef struct Alarm Alarm;
-typedef struct Alarm {
-	List;
-	int	busy;
-	long	dt;
-	void	(*f)(Alarm*);
-	void	*arg;
-} Alarm;
-
-typedef struct Apminfo {
-	int haveinfo;
-	int ax;
-	int cx;
-	int dx;
-	int di;
-	int ebx;
-	int esi;
-} Apminfo;
-
-typedef struct Block Block;
-struct Block {
-	Block*	next;
-	uchar*	rp;			/* first unconsumed byte */
-	uchar*	wp;			/* first empty byte */
-	uchar*	lim;			/* 1 past the end of the buffer */
-	uchar*	base;			/* start of the buffer */
-	uint32_t	flag;
-};
-#define BLEN(s)	((s)->wp - (s)->rp)
-
-typedef struct IOQ IOQ;
-typedef struct IOQ {
-	uchar	buf[4096];
-	uchar	*in;
-	uchar	*out;
-	int	state;
-	int	(*getc)(IOQ*);
-	int	(*putc)(IOQ*, int);
-	void	*ptr;
-};
-
-enum {
-	Eaddrlen	= 6,
-	/* next two exclude 4-byte ether CRC */
-	ETHERMINTU	= 60,		/* minimum transmit size */
-	ETHERMAXTU	= 1514,		/* maximum transmit size */
-	ETHERHDRSIZE	= 14,		/* size of an ethernet header */
-
-	MaxEther	= 6,
-};
-
-typedef struct {
-	uchar	d[Eaddrlen];
-	uchar	s[Eaddrlen];
-	uchar	type[2];
-	uchar	data[1500];
-	uchar	crc[4];
-} Etherpkt;
-
-extern uchar broadcast[Eaddrlen];
-
-typedef struct Ureg Ureg;
-
-typedef struct Segdesc {
-	uint32_t	d0;
-	uint32_t	d1;
-} Segdesc;
-
-typedef struct Mach {
-	int	machno;			/* physical id of processor (KNOWN TO ASSEMBLY) */
-	uint32_t	splpc;			/* pc of last caller to splhi */
-
-	uint32_t*	pdb;			/* page directory base for this processor (va) */
-	Segdesc	*gdt;			/* gdt for this processor */
-
-	uint32_t	ticks;			/* of the clock since boot time */
-	void	*alarm;			/* alarms bound to this clock */
-} Mach;
-
-extern Mach *m;
-
-#define I_MAGIC		((((4*11)+0)*11)+7)		/* intel 386 */
-#define S_MAGIC		(0x8000|((((4*26)+0)*26)+7))	/* amd64 */
-
-typedef struct Exec Exec;
-struct	Exec
-{
-	uchar	magic[4];		/* magic number */
-	uchar	text[4];	 	/* size of text segment */
-	uchar	data[4];	 	/* size of initialized data */
-	uchar	bss[4];	  		/* size of uninitialized data */
-	uchar	syms[4];	 	/* size of symbol table */
-	uchar	entry[4];	 	/* entry point */
-	uchar	spsz[4];		/* size of sp/pc offset table */
-	uchar	pcsz[4];		/* size of pc/line number table */
-};
-
-/*
- *  a parsed .ini line
- */
-#define ISAOPTLEN	32
-#define NISAOPT		8
-
-typedef struct  ISAConf {
-	char*	type;
-	uint32_t	port;
-	uint32_t	irq;
-	uint32_t	dma;
-	uint32_t	mem;
-	uint32_t	size;
-	uint32_t	freq;
-	uchar	ea[6];
-
-	int	nopt;
-	char	opt[NISAOPT][ISAOPTLEN];
-} ISAConf;
-
-typedef struct Pcidev Pcidev;
-typedef struct PCMmap PCMmap;
-typedef struct PCMslot PCMslot;
-
-#define BOOTLINE	((char*)CONFADDR)
-
-#define ROUND(s, sz)	(((s)+((sz)-1))&~((sz)-1))
-
-
-typedef struct Type Type;
-typedef struct Medium Medium;
-typedef struct Boot Boot;
-
-enum {					/* type */
-	Tnil		= 0x00,
-
-	Tfloppy		= 0x01,
-	Tsd		= 0x02,
-	Tether		= 0x03,
-	Tcd		= 0x04,
-
-	Tany		= -1,
-};
-
-enum {					/* name and flag */
-	Fnone		= 0x00,
-
-	Nfs		= 0x00,
-	Ffs		= (1<<Nfs),
-	Nboot		= 0x01,
-	Fboot		= (1<<Nboot),
-	Nbootp		= 0x02,
-	Fbootp		= (1<<Nbootp),
-	NName		= 3,
-
-	Fany		= Fbootp|Fboot|Ffs,
-
-	Fini		= 0x10,
-	Fprobe		= 0x80,
-};
-
-typedef struct Type {
-	int	type;
-	int	flag;
-	int	(*init)(void);
-	void	(*initdev)(int, char*);
-	void*	(*getfspart)(int, char*, int);	/* actually returns Dos* */
-	void	(*addconf)(int);
-	int	(*boot)(int, char*, Boot*);
-	void	(*printdevs)(int);
-	char**	parts;
-	char**	inis;
-	int	mask;
-	Medium*	media;
-} Type;
-
-extern void (*etherdetach)(void);
-extern void (*floppydetach)(void);
-extern void (*sddetach)(void);
-
-typedef struct Lock {	/* for ilock, iunlock */
-	int locked;
-	int spl;
-} Lock;
-
-enum {	/* returned by bootpass */
-	MORE, ENOUGH, FAIL
-};
-enum {
-	INITKERNEL,
-	READEXEC,
-	READ9TEXT,
-	READ9DATA,
-	READGZIP,
-	READEHDR,
-	READPHDR,
-	READEPAD,
-	READEDATA,
-	TRYBOOT,
-	TRYEBOOT,
-	INIT9LOAD,
-	READ9LOAD,
-	FAILED
-};
-
-typedef struct {
-	Exec;
-	uvlong uvl[1];
-} Hdr;
-
-struct Boot {
-	int state;
-
-	Hdr hdr;
-
-	char *bp;	/* base ptr */
-	char *wp;	/* write ptr */
-	char *ep;	/* end ptr */
-};
-
-/*
- * Multiboot grot.
- */
-typedef struct Mbi Mbi;
-struct Mbi {
-	u32int	flags;
-	u32int	memlower;
-	u32int	memupper;
-	u32int	bootdevice;
-	u32int	cmdline;
-	u32int	modscount;
-	u32int	modsaddr;
-	u32int	syms[4];
-	u32int	mmaplength;
-	u32int	mmapaddr;
-	u32int	driveslength;
-	u32int	drivesaddr;
-	u32int	configtable;
-	u32int	bootloadername;
-	u32int	apmtable;
-	u32int	vbe[6];
-};
-
-enum {						/* flags */
-	Fmem		= 0x00000001,		/* mem* valid */
-	Fbootdevice	= 0x00000002,		/* bootdevice valid */
-	Fcmdline	= 0x00000004,		/* cmdline valid */
-	Fmods		= 0x00000008,		/* mod* valid */
-	Fsyms		= 0x00000010,		/* syms[] has a.out info */
-	Felf		= 0x00000020,		/* syms[] has ELF info */
-	Fmmap		= 0x00000040,		/* mmap* valid */
-	Fdrives		= 0x00000080,		/* drives* valid */
-	Fconfigtable	= 0x00000100,		/* configtable* valid */
-	Fbootloadername	= 0x00000200,		/* bootloadername* valid */
-	Fapmtable	= 0x00000400,		/* apmtable* valid */
-	Fvbe		= 0x00000800,		/* vbe[] valid */
-};
-
-typedef struct Mod Mod;
-struct Mod {
-	u32int	modstart;
-	u32int	modend;
-	u32int	string;
-	u32int	reserved;
-};
-
-typedef struct MMap MMap;
-struct MMap {
-	u32int	size;
-	u32int	base[2];
-	u32int	length[2];
-	u32int	type;
-};
-
-extern int	debug;
-extern Apminfo	apm;
-extern int	vflag;
-extern u32int	memstart;
-
-extern MMap	mmap[20];
-extern int	nmmap;
-extern char	*defaultpartition;
-extern int	iniread;
-extern int	pxe;
-
-/*
- * Compatibility hacks.
- */
-typedef struct QLock {
-	int r;
-} QLock;
-
-#define qlock(i)	{/* nothing to do */;}
-#define qunlock(i)	{/* nothing to do */;}
-
-#define READSTR		0
-
-#define waserror()	(0)
-#define nexterror()
-#define poperror()
-
-#define mallocalign(n, a, o, s)	ialloc((n), (a))
-
-#define iprint		print
-
-#define readstr(offset, a, n, p) 0; USED(offset, a, n, p)
-
-#define wmb()		coherence()
-
-#define addethercard(a, b)
-
-typedef struct Netif Netif;
-typedef struct Ether Ether;
-struct Netif {
-	/* Ether */
-	long	(*ifstat)(Ether*, void*, long, uint32_t);
-	long 	(*ctl)(Ether*, void*, long);
-
-	/* Netif */
-	int	mbps;
-	void	*arg;
-	void	(*promiscuous)(void*, int);
-	void	(*multicast)(void*, uchar*, int);
-};

+ 0 - 862
sys/src/9/w/pxeload/devfloppy.c

@@ -1,862 +0,0 @@
-/*
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
-
-#include <u.h>
-
-#include	"lib.h"
-#include	"mem.h"
-#include	"dat.h"
-#include	"fns.h"
-#include	"io.h"
-#include	"ureg.h"
-
-#include	"fs.h"
-#include	"devfloppy.h"
-
-
-/* Intel 82077A (8272A compatible) floppy controller */
-
-/* This module expects the following functions to be defined
- * elsewhere:
- *
- * inb()
- * outb()
- * floppyexec()
- * floppyeject()
- * floppysetup0()
- * floppysetup1()
- * dmainit()
- * dmasetup()
- * dmaend()
- *
- * On DMA systems, floppyexec() should be an empty function;
- * on non-DMA systems, dmaend() should be an empty function;
- * dmasetup() may enforce maximum transfer sizes.
- */
-
-enum {
-	/* file types */
-	Qdir=		0,
-	Qdata=		(1<<2),
-	Qctl=		(2<<2),
-	Qmask=		(3<<2),
-
-	DMAchan=	2,	/* floppy dma channel */
-};
-
-#define DPRINT if(0)print
-
-FType floppytype[] =
-{
- { "3½HD",	T1440kb, 512, 18, 2, 1, 80, 0x1B, 0x54,	0, },
- { "3½DD",	T1440kb, 512,  9, 2, 1, 80, 0x1B, 0x54, 2, },
- { "3½DD",	T720kb,  512,  9, 2, 1, 80, 0x1B, 0x54, 2, },
- { "5¼HD",	T1200kb, 512, 15, 2, 1, 80, 0x2A, 0x50, 0, },
- { "5¼DD",	T1200kb, 512,  9, 2, 2, 40, 0x2A, 0x50, 1, },
- { "ATT3B1",	T1200kb, 512,  8, 2, 2, 48, 0x2A, 0x50, 1, },
- { "5¼DD",	T360kb,  512,  9, 2, 1, 40, 0x2A, 0x50, 2, },
-};
-
-/*
- *  bytes per sector encoding for the controller.
- *  - index for b2c is is (bytes per sector/128).
- *  - index for c2b is code from b2c
- */
-static int b2c[] =
-{
-[1]	0,
-[2]	1,
-[4]	2,
-[8]	3,
-};
-static int c2b[] =
-{
-	128,
-	256,
-	512,
-	1024,
-};
-
-FController	fl;
-
-#define MOTORBIT(i)	(1<<((i)+4))
-
-/*
- *  predeclared
- */
-static int	cmddone(void*);
-static void	floppyformat(FDrive*, char*);
-static void	floppykproc(void*);
-static void	floppypos(FDrive*,int32_t);
-static int	floppyrecal(FDrive*);
-static int	floppyresult(void);
-static void	floppyrevive(void);
-static int64_t	pcfloppyseek(FDrive*, int64_t);
-static int	floppysense(void);
-static void	floppywait(int);
-static int32_t	floppyxfer(FDrive*, int, void*, int32_t, int32_t);
-
-static void
-fldump(void)
-{
-	DPRINT("sra %ux srb %ux dor %ux msr %ux dir %ux\n", inb(Psra), inb(Psrb),
-		inb(Pdor), inb(Pmsr), inb(Pdir));
-}
-
-static void
-floppyalarm(Alarm* a)
-{
-	FDrive *dp;
-
-	for(dp = fl.d; dp < &fl.d[fl.ndrive]; dp++){
-		if((fl.motor&MOTORBIT(dp->dev)) && TK2SEC(machp()->ticks - dp->lasttouched) > 5)
-			floppyoff(dp);
-	}
-
-	alarm(5*1000, floppyalarm, 0);
-	cancel(a);
-}
-
-/*
- *  set floppy drive to its default type
- */
-static void
-floppysetdef(FDrive *dp)
-{
-	FType *t;
-
-	for(t = floppytype; t < &floppytype[nelem(floppytype)]; t++)
-		if(dp->dt == t->dt){
-			dp->t = t;
-			break;
-		}
-}
-
-static void
-_floppydetach(void)
-{
-	/*
-	 *  stop the motors
-	 */
-	fl.motor = 0;
-	delay(10);
-	outb(Pdor, fl.motor | Fintena | Fena);
-	delay(10);
-}
-
-int
-floppyinit(void)
-{
-	FDrive *dp;
-	FType *t;
-	uint32_t maxtsize;
-	int mask;
-
-	dmainit(DMAchan);
-
-	floppysetup0(&fl);
-
-	/*
-	 *  init dependent parameters
-	 */
-	maxtsize = 0;
-	for(t = floppytype; t < &floppytype[nelem(floppytype)]; t++){
-		t->cap = t->bytes * t->heads * t->sectors * t->tracks;
-		t->bcode = b2c[t->bytes/128];
-		t->tsize = t->bytes * t->sectors;
-		if(maxtsize < t->tsize)
-			maxtsize = t->tsize;
-	}
-
-	fl.selected = fl.d;
-
-	floppydetach = _floppydetach;
-	floppydetach();
-
-	/*
-	 *  init drives
-	 */
-	mask = 0;
-	for(dp = fl.d; dp < &fl.d[fl.ndrive]; dp++){
-		dp->dev = dp - fl.d;
-		if(dp->dt == Tnone)
-			continue;
-		mask |= 1<<dp->dev;
-		floppysetdef(dp);
-		dp->cyl = -1;			/* because we don't know */
-		dp->cache = (uint8_t*)xspanalloc(maxtsize, BY2PG, 64*1024);
-		dp->ccyl = -1;
-		dp->vers = 0;
-		dp->maxtries = 5;
-	}
-
-	/*
-	 *  first operation will recalibrate
-	 */
-	fl.confused = 1;
-
-	floppysetup1(&fl);
-
-	/* to turn the motor off when inactive */
-	alarm(5*1000, floppyalarm, 0);
-
-	return mask;
-}
-
-void
-floppyinitdev(int i, char *name)
-{
-	if(i >= fl.ndrive)
-		panic("floppyinitdev");
-	sprint(name, "fd%d", i);
-}
-
-void
-floppyprintdevs(int i)
-{
-	if(i >= fl.ndrive)
-		panic("floppyprintdevs");
-	print(" fd%d", i);
-}
-
-int
-floppyboot(int dev, char *file, Boot *b)
-{
-	Fs *fs;
-
-	if(strncmp(file, "dos!", 4) == 0)
-		file += 4;
-	else if(strchr(file, '!') || strcmp(file, "")==0) {
-		print("syntax is fd0!file\n");
-		return -1;
-	}
-
-	fs = floppygetfspart(dev, "dos", 1);
-	if(fs == nil)
-		return -1;
-
-	return fsboot(fs, file, b);
-}
-
-void
-floppyprintbootdevs(int dev)
-{
-	print(" fd%d", dev);
-}
-
-/*
- *  check if the floppy has been replaced under foot.  cause
- *  an error if it has.
- *
- *  a seek and a read clears the condition.  this was determined
- *  experimentally, there has to be a better way.
- *
- *  if the read fails, cycle through the possible floppy
- *  density till one works or we've cycled through all
- *  possibilities for this drive.
- */
-static int
-changed(FDrive *dp)
-{
-	FType *start;
-
-	/*
-	 *  if floppy has changed or first time through
-	 */
-	if((inb(Pdir)&Fchange) || dp->vers == 0){
-		DPRINT("changed\n");
-		fldump();
-		dp->vers++;
-		floppysetdef(dp);
-		dp->maxtries = 3;
-		start = dp->t;
-
-		/* flopppyon fails if there's no drive */
-		dp->confused = 1;	/* make floppyon recal */
-		if(floppyon(dp) < 0)
-			return -1;
-
-		pcfloppyseek(dp, dp->t->heads*dp->t->tsize);
-
-		while(floppyxfer(dp, Fread, dp->cache, 0, dp->t->tsize) <= 0){
-
-			/*
-			 *  if the xfer attempt doesn't clear the changed bit,
-			 *  there's no floppy in the drive
-			 */
-			if(inb(Pdir)&Fchange)
-				return -1;
-
-			while(++dp->t){
-				if(dp->t == &floppytype[nelem(floppytype)])
-					dp->t = floppytype;
-				if(dp->dt == dp->t->dt)
-					break;
-			}
-
-			/* flopppyon fails if there's no drive */
-			if(floppyon(dp) < 0)
-				return -1;
-
-			DPRINT("changed: trying %s\n", dp->t->name);
-			fldump();
-			if(dp->t == start)
-				return -1;
-		}
-	}
-
-	return 0;
-}
-
-static int
-readtrack(FDrive *dp, int cyl, int head)
-{
-	int i, nn, sofar;
-	uint32_t pos;
-
-	nn = dp->t->tsize;
-	if(dp->ccyl==cyl && dp->chead==head)
-		return nn;
-	pos = (cyl*dp->t->heads+head) * nn;
-	for(sofar = 0; sofar < nn; sofar += i){
-		dp->ccyl = -1;
-		i = floppyxfer(dp, Fread, dp->cache + sofar, pos + sofar, nn - sofar);
-		if(i <= 0)
-			return -1;
-	}
-	dp->ccyl = cyl;
-	dp->chead = head;
-	return nn;
-}
-
-int32_t
-floppyread(Fs *fs, void *a, int32_t n)
-{
-	FDrive *dp;
-	int32_t rv, offset;
-	int sec, head, cyl;
-	int32_t len;
-	uint8_t *aa;
-
-	aa = a;
-	dp = &fl.d[fs->dev];
-
-	offset = dp->offset;
-	floppyon(dp);
-	if(changed(dp))
-		return -1;
-
-	for(rv = 0; rv < n; rv += len){
-		/*
-		 *  all xfers come out of the track cache
-		 */
-		dp->len = n - rv;
-		floppypos(dp, offset+rv);
-		cyl = dp->tcyl;
-		head = dp->thead;
-		len = dp->len;
-		sec = dp->tsec;
-		if(readtrack(dp, cyl, head) < 0)
-			break;
-		memmove(aa+rv, dp->cache + (sec-1)*dp->t->bytes, len);
-	}
-	dp->offset = offset+rv;
-
-	return rv;
-}
-
-void*
-floppygetfspart(int i, char *name, int chatty)
-{
-	static Fs fs;
-
-	if(strcmp(name, "dos") != 0){
-		if(chatty)
-			print("unknown partition fd%d!%s (use fd%d!dos)\n", i, name, i);
-		return nil;
-	}
-
-	fs.dev = i;
-	fs.diskread = floppyread;
-	fs.diskseek = floppyseek;
-
-	/* sometimes we get spurious errors and doing it again works */
-	if(dosinit(&fs) < 0 && dosinit(&fs) < 0){
-		if(chatty)
-			print("fd%d!%s does not contain a FAT file system\n", i, name);
-		return nil;
-	}
-	return &fs;
-}
-
-static int
-return0(void*)
-{
-	return 0;
-}
-
-static void
-timedsleep(int (*f)(void*), void* arg, int ms)
-{
-	int s;
-	uint32_t end;
-
-	end = machp()->ticks + 1 + MS2TK(ms);
-	while(machp()->ticks < end && !(*f)(arg)){
-		s = spllo();
-		delay(10);
-		splx(s);
-	}
-}
-
-/*
- *  start a floppy drive's motor.
- */
-static int
-floppyon(FDrive *dp)
-{
-	int alreadyon;
-	int tries;
-
-	if(fl.confused)
-		floppyrevive();
-
-	/* start motor and select drive */
-	dp->lasttouched = machp()->ticks;
-	alreadyon = fl.motor & MOTORBIT(dp->dev);
-	if(!alreadyon){
-		fl.motor |= MOTORBIT(dp->dev);
-		outb(Pdor, fl.motor | Fintena | Fena | dp->dev);
-		/* wait for drive to spin up */
-		timedsleep(return0, 0, 750);
-
-		/* clear any pending interrupts */
-		floppysense();
-	}
-
-	/* set transfer rate */
-	if(fl.rate != dp->t->rate){
-		fl.rate = dp->t->rate;
-		outb(Pdsr, fl.rate);
-	}
-
-	/* get drive to a known cylinder */
-	if(dp->confused)
-		for(tries = 0; tries < 4; tries++)
-			if(floppyrecal(dp) >= 0)
-				break;
-	dp->lasttouched = machp()->ticks;
-	fl.selected = dp;
-	if(dp->confused)
-		return -1;
-	return 0;
-}
-
-/*
- *  stop the floppy if it hasn't been used in 5 seconds
- */
-static void
-floppyoff(FDrive *dp)
-{
-	fl.motor &= ~MOTORBIT(dp->dev);
-	outb(Pdor, fl.motor | Fintena | Fena | dp->dev);
-}
-
-/*
- *  send a command to the floppy
- */
-static int
-floppycmd(void)
-{
-	int i;
-	int tries;
-
-	fl.nstat = 0;
-	for(i = 0; i < fl.ncmd; i++){
-		for(tries = 0; ; tries++){
-			if((inb(Pmsr)&(Ffrom|Fready)) == Fready)
-				break;
-			if(tries > 1000){
-				DPRINT("cmd %ux can't be sent (%d)\n", fl.cmd[0], i);
-				fldump();
-
-				/* empty fifo, might have been a bad command */
-				floppyresult();
-				return -1;
-			}
-			microdelay(1);
-		}
-		outb(Pfdata, fl.cmd[i]);
-	}
-	return 0;
-}
-
-/*
- *  get a command result from the floppy
- *
- *  when the controller goes ready waiting for a command
- *  (instead of sending results), we're done
- *
- */
-static int
-floppyresult(void)
-{
-	int i, s;
-	int tries;
-
-	/* get the result of the operation */
-	for(i = 0; i < sizeof(fl.stat); i++){
-		/* wait for status byte */
-		for(tries = 0; ; tries++){
-			s = inb(Pmsr)&(Ffrom|Fready);
-			if(s == Fready){
-				fl.nstat = i;
-				return fl.nstat;
-			}
-			if(s == (Ffrom|Fready))
-				break;
-			if(tries > 1000){
-				DPRINT("floppyresult: %d stats\n", i);
-				fldump();
-				fl.confused = 1;
-				return -1;
-			}
-			microdelay(1);
-		}
-		fl.stat[i] = inb(Pfdata);
-	}
-	fl.nstat = sizeof(fl.stat);
-	return fl.nstat;
-}
-
-/*
- *  calculate physical address of a logical byte offset into the disk
- *
- *  truncate dp->length if it crosses a track boundary
- */
-static void
-floppypos(FDrive *dp, int32_t off)
-{
-	int lsec;
-	int ltrack;
-	int end;
-
-	lsec = off/dp->t->bytes;
-	ltrack = lsec/dp->t->sectors;
-	dp->tcyl = ltrack/dp->t->heads;
-	dp->tsec = (lsec % dp->t->sectors) + 1;
-	dp->thead = (lsec/dp->t->sectors) % dp->t->heads;
-
-	/*
-	 *  can't read across track boundaries.
-	 *  if so, decrement the bytes to be read.
-	 */
-	end = (ltrack+1)*dp->t->sectors*dp->t->bytes;
-	if(off+dp->len > end)
-		dp->len = end - off;
-}
-
-/*
- *  get the interrupt cause from the floppy.
- */
-static int
-floppysense(void)
-{
-	fl.ncmd = 0;
-	fl.cmd[fl.ncmd++] = Fsense;
-	if(floppycmd() < 0)
-		return -1;
-	if(floppyresult() < 2){
-		DPRINT("can't read sense response\n");
-		fldump();
-		fl.confused = 1;
-		return -1;
-	}
-	return 0;
-}
-
-static int
-cmddone(void *a)
-{
-	USED(a);
-	return fl.ncmd == 0;
-}
-
-/*
- *  Wait for a floppy interrupt.  If none occurs in 5 seconds, we
- *  may have missed one.  This only happens on some portables which
- *  do power management behind our backs.  Call the interrupt
- *  routine to try to clear any conditions.
- */
-static void
-floppywait(int slow)
-{
-	timedsleep(cmddone, 0, slow ? 5000 : 1000);
-	if(!cmddone(0)){
-		floppyintr(0);
-		fl.confused = 1;
-	}
-}
-
-/*
- *  we've lost the floppy position, go to cylinder 0.
- */
-static int
-floppyrecal(FDrive *dp)
-{
-	dp->ccyl = -1;
-	dp->cyl = -1;
-
-	fl.ncmd = 0;
-	fl.cmd[fl.ncmd++] = Frecal;
-	fl.cmd[fl.ncmd++] = dp->dev;
-	if(floppycmd() < 0)
-		return -1;
-	floppywait(1);
-	if(fl.nstat < 2){
-		DPRINT("recalibrate: confused %ux\n", inb(Pmsr));
-		fl.confused = 1;
-		return -1;
-	}
-	if((fl.stat[0] & (Codemask|Seekend)) != Seekend){
-		DPRINT("recalibrate: failed\n");
-		dp->confused = 1;
-		return -1;
-	}
-	dp->cyl = fl.stat[1];
-	if(dp->cyl != 0){
-		DPRINT("recalibrate: wrong cylinder %d\n", dp->cyl);
-		dp->cyl = -1;
-		dp->confused = 1;
-		return -1;
-	}
-
-	dp->confused = 0;
-	return 0;
-}
-
-/*
- *  if the controller or a specific drive is in a confused state,
- *  reset it and get back to a kown state
- */
-static void
-floppyrevive(void)
-{
-	FDrive *dp;
-
-	/*
-	 *  reset the controller if it's confused
-	 */
-	if(fl.confused){
-		DPRINT("floppyrevive in\n");
-		fldump();
-
-		/* reset controller and turn all motors off */
-		splhi();
-		fl.ncmd = 1;
-		fl.cmd[0] = 0;
-		outb(Pdor, 0);
-		delay(10);
-		outb(Pdor, Fintena|Fena);
-		delay(10);
-		spllo();
-		fl.motor = 0;
-		fl.confused = 0;
-		floppywait(0);
-
-		/* mark all drives in an unknown state */
-		for(dp = fl.d; dp < &fl.d[fl.ndrive]; dp++)
-			dp->confused = 1;
-
-		/* set rate to a known value */
-		outb(Pdsr, 0);
-		fl.rate = 0;
-
-		DPRINT("floppyrevive out\n");
-		fldump();
-	}
-}
-
-/*
- *  seek to the target cylinder
- *
- *	interrupt, no results
- */
-static int64_t
-pcfloppyseek(FDrive *dp, int64_t off)
-{
-	floppypos(dp, off);
-	if(dp->cyl == dp->tcyl){
-		dp->offset = off;
-		return off;
-	}
-	dp->cyl = -1;
-
-	fl.ncmd = 0;
-	fl.cmd[fl.ncmd++] = Fseek;
-	fl.cmd[fl.ncmd++] = (dp->thead<<2) | dp->dev;
-	fl.cmd[fl.ncmd++] = dp->tcyl * dp->t->steps;
-	if(floppycmd() < 0)
-		return -1;
-	floppywait(1);
-	if(fl.nstat < 2){
-		DPRINT("seek: confused\n");
-		fl.confused = 1;
-		return -1;
-	}
-	if((fl.stat[0] & (Codemask|Seekend)) != Seekend){
-		DPRINT("seek: failed\n");
-		dp->confused = 1;
-		return -1;
-	}
-
-	dp->cyl = dp->tcyl;
-	dp->offset = off;
-	DPRINT("seek to %d succeeded\n", dp->offset);
-
-	return dp->offset;
-}
-
-/*
- *  read or write to floppy.  try up to three times.
- */
-static int32_t
-floppyxfer(FDrive *dp, int cmd, void *a, int32_t off, int32_t n)
-{
-	int32_t offset;
-	int tries;
-
-	if(off >= dp->t->cap)
-		return 0;
-	if(off + n > dp->t->cap)
-		n = dp->t->cap - off;
-
-	/* retry on error (until it gets ridiculous) */
-	for(tries = 0; tries < dp->maxtries; tries++){
-
-		dp->len = n;
-		if(pcfloppyseek(dp, off) < 0){
-			DPRINT("xfer: seek failed\n");
-			dp->confused = 1;
-			continue;
-		}
-
-		/*
-		 *  set up the dma (dp->len may be trimmed)
-		 */
-		dp->len = dmasetup(DMAchan, a, dp->len, cmd==Fread);
-		if(dp->len < 0){
-	buggery:
-			dmaend(DMAchan);
-			continue;
-		}
-
-		/*
-		 *  start operation
-		 */
-		fl.ncmd = 0;
-		fl.cmd[fl.ncmd++] = cmd | (dp->t->heads > 1 ? Fmulti : 0);
-		fl.cmd[fl.ncmd++] = (dp->thead<<2) | dp->dev;
-		fl.cmd[fl.ncmd++] = dp->tcyl;
-		fl.cmd[fl.ncmd++] = dp->thead;
-		fl.cmd[fl.ncmd++] = dp->tsec;
-		fl.cmd[fl.ncmd++] = dp->t->bcode;
-		fl.cmd[fl.ncmd++] = dp->t->sectors;
-		fl.cmd[fl.ncmd++] = dp->t->gpl;
-		fl.cmd[fl.ncmd++] = 0xFF;
-		if(floppycmd() < 0)
-			goto buggery;
-
-		/*
-		 *  give bus to DMA, floppyintr() will read result
-		 */
-		floppywait(0);
-		dmaend(DMAchan);
-
-		/*
-		 *  check for errors
-		 */
-		if(fl.nstat < 7){
-			DPRINT("xfer: confused\n");
-			fl.confused = 1;
-			continue;
-		}
-		if((fl.stat[0] & Codemask)!=0 || fl.stat[1] || fl.stat[2]){
-			DPRINT("xfer: failed %ux %ux %ux\n", fl.stat[0],
-				fl.stat[1], fl.stat[2]);
-			DPRINT("offset %lud len %ld\n", off, dp->len);
-			if((fl.stat[0]&Codemask)==Cmdexec && fl.stat[1]==Overrun){
-				DPRINT("DMA overrun: retry\n");
-			} else
-				dp->confused = 1;
-			continue;
-		}
-
-		/*
-		 *  check for correct cylinder
-		 */
-		offset = fl.stat[3] * dp->t->heads + fl.stat[4];
-		offset = offset*dp->t->sectors + fl.stat[5] - 1;
-		offset = offset * c2b[fl.stat[6]];
-		if(offset != off+dp->len){
-			DPRINT("xfer: ends on wrong cyl\n");
-			dp->confused = 1;
-			continue;
-		}
-
-		dp->lasttouched = machp()->ticks;
-		dp->maxtries = 20;
-		return dp->len;
-	}
-
-	return -1;
-}
-
-/*
-void
-floppymemwrite(void)
-{
-	int i;
-	int n;
-	uchar *a;
-	FDrive *dp;
-
-	dp = &fl.d[0];
-	a = (uchar*)0x80000000;
-	n = 0;
-	while(n < 1440*1024){
-		i = floppyxfer(dp, Fwrite, a+n, n, 1440*1024-n);
-		if(i <= 0)
-			break;
-		n += i;
-	}
-	print("floppymemwrite wrote %d bytes\n", n);
-splhi(); for(;;);
-}
-*/
-
-static void
-floppyintr(Ureg *ur)
-{
-	USED(ur);
-	switch(fl.cmd[0]&~Fmulti){
-	case Fread:
-	case Fwrite:
-	case Fformat:
-	case Fdumpreg:
-		floppyresult();
-		break;
-	case Fseek:
-	case Frecal:
-	default:
-		floppysense();	/* to clear interrupt */
-		break;
-	}
-	fl.ncmd = 0;
-}

+ 0 - 205
sys/src/9/w/pxeload/devfloppy.h

@@ -1,205 +0,0 @@
-/* 
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
-
-typedef	struct FController FController;
-typedef	struct FDrive FDrive;
-typedef struct FType FType;
-
-static void floppyintr(Ureg*);
-static int floppyon(FDrive*);
-static void floppyoff(FDrive*);
-static void floppysetdef(FDrive*);
-
-/*
- *  a floppy drive
- */
-struct FDrive
-{
-	FType	*t;		/* floppy type */
-	int	dt;		/* drive type */
-	int	dev;
-
-	uint32_t	lasttouched;	/* time last touched */
-	int	cyl;		/* current arm position */
-	int	confused;	/* needs to be recalibrated */
-	int	offset;		/* current offset */
-	int	vers;
-	int	maxtries;
-
-	int	tcyl;		/* target cylinder */
-	int	thead;		/* target head */
-	int	tsec;		/* target sector */
-	long	len;		/* size of xfer */
-
-	uchar	*cache;		/* track cache */
-	int	ccyl;
-	int	chead;
-
-//	Rendez	r;		/* waiting here for motor to spin up */
-	void	*aux;
-};
-
-/*
- *  controller for 4 floppys
- */
-struct FController
-{
-//	QLock;			/* exclusive access to the contoller */
-
-	int	ndrive;
-	FDrive	*d;		/* the floppy drives */
-	FDrive	*selected;
-	int	rate;		/* current rate selected */
-	uchar	cmd[14];	/* command */
-	int	ncmd;		/* # command bytes */
-	uchar	stat[14];	/* command status */
-	int	nstat;		/* # status bytes */
-	int	confused;	/* controler needs to be reset */
-//	Rendez	r;		/* wait here for command termination */
-	int	motor;		/* bit mask of spinning disks */
-//	Rendez	kr;		/* for motor watcher */
-};
-
-/*
- *  floppy types (all MFM encoding)
- */
-struct FType
-{
-	char	*name;
-	int	dt;		/* compatible drive type */
-	int	bytes;		/* bytes/sector */
-	int	sectors;	/* sectors/track */
-	int	heads;		/* number of heads */
-	int	steps;		/* steps per cylinder */
-	int	tracks;		/* tracks/disk */
-	int	gpl;		/* intersector gap length for read/write */
-	int	fgpl;		/* intersector gap length for format */
-	int	rate;		/* rate code */
-
-	/*
-	 *  these depend on previous entries and are set filled in
-	 *  by floppyinit
-	 */
-	int	bcode;		/* coded version of bytes for the controller */
-	long	cap;		/* drive capacity in bytes */
-	long	tsize;		/* track size in bytes */
-};
-/* bits in the registers */
-enum
-{
-	/* status registers a & b */
-	Psra=		0x3f0,
-	Psrb=		0x3f1,
-
-	/* digital output register */
-	Pdor=		0x3f2,
-	Fintena=	0x8,	/* enable floppy interrupt */
-	Fena=		0x4,	/* 0 == reset controller */
-
-	/* main status register */
-	Pmsr=		0x3f4,
-	Fready=		0x80,	/* ready to be touched */
-	Ffrom=		0x40,	/* data from controller */
-	Ffloppybusy=	0x10,	/* operation not over */
-
-	/* data register */
-	Pfdata=		0x3f5,
-	Frecal=		0x07,	/* recalibrate cmd */
-	Fseek=		0x0f,	/* seek cmd */
-	Fsense=		0x08,	/* sense cmd */
-	Fread=		0x66,	/* read cmd */
-	Freadid=	0x4a,	/* read track id */
-	Fspec=		0x03,	/* set hold times */
-	Fwrite=		0x45,	/* write cmd */
-	Fformat=	0x4d,	/* format cmd */
-	Fmulti=		0x80,	/* or'd with Fread or Fwrite for multi-head */
-	Fdumpreg=	0x0e,	/* dump internal registers */
-
-	/* digital input register */
-	Pdir=		0x3F7,	/* disk changed port (read only) */
-	Pdsr=		0x3F7,	/* data rate select port (write only) */
-	Fchange=	0x80,	/* disk has changed */
-
-	/* status 0 byte */
-	Drivemask=	3<<0,
-	Seekend=	1<<5,
-	Codemask=	(3<<6)|(3<<3),
-	Cmdexec=	1<<6,
-
-	/* status 1 byte */
-	Overrun=	0x10,
-};
-
-/*
- *  types of drive (from PC equipment byte)
- */
-enum
-{
-	Tnone=		0,
-	T360kb=		1,
-	T1200kb=	2,
-	T720kb=		3,
-	T1440kb=	4,
-};
-
-static void
-pcfloppyintr(Ureg *ur, void *a)
-{
-	USED(a);
-
-	floppyintr(ur);
-}
-
-void
-floppysetup0(FController *fl)
-{
-	uchar equip;
-
-	/*
-	 * Read nvram for types of floppies 0 & 1.
-	 * Always try floppy 0.
-	 */
-	equip = nvramread(0x10);
-	fl->ndrive = 1;
-
-	if(equip & 0xf)
-		fl->ndrive++;
-
-	/*
-	 * Allocate the drive storage.
-	 * There's always one.
-	 */
-	fl->d = xalloc(fl->ndrive*sizeof(FDrive));
-	fl->d[0].dt = (equip >> 4) & 0xf;
-	if(fl->d[0].dt == Tnone)
-		fl->d[0].dt = T1440kb;
-
-	if(fl->ndrive == 2)
-		fl->d[1].dt = equip & 0xf;
-}
-
-void
-floppysetup1(FController*)
-{
-//	intrenable(VectorFLOPPY, pcfloppyintr, fl, BUSUNKNOWN);
-	setvec(VectorFLOPPY, pcfloppyintr, 0);
-}
-
-
-static vlong pcfloppyseek(FDrive*, vlong);
-FController	fl;
-
-vlong
-floppyseek(Fs *fs, vlong off)
-{
-	FDrive *dp;
-
-	dp = &fl.d[fs->dev];
-	return pcfloppyseek(dp, off);
-}

+ 0 - 254
sys/src/9/w/pxeload/dma.c

@@ -1,254 +0,0 @@
-/*
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
-
-#include	"u.h"
-#include	"lib.h"
-#include	"mem.h"
-#include	"dat.h"
-#include	"fns.h"
-
-typedef struct DMAport	DMAport;
-typedef struct DMA	DMA;
-typedef struct DMAxfer	DMAxfer;
-
-enum
-{
-	/*
-	 *  the byte registers for DMA0 are all one byte apart
-	 */
-	Dma0=		0x00,
-	Dma0status=	Dma0+0x8,	/* status port */
-	Dma0reset=	Dma0+0xD,	/* reset port */
-
-	/*
-	 *  the byte registers for DMA1 are all two bytes apart (why?)
-	 */
-	Dma1=		0xC0,
-	Dma1status=	Dma1+2*0x8,	/* status port */
-	Dma1reset=	Dma1+2*0xD,	/* reset port */
-};
-
-/*
- *  state of a dma transfer
- */
-struct DMAxfer
-{
-	uint32_t	bpa;		/* bounce buffer physical address */
-	void*	bva;		/* bounce buffer virtual address */
-	void*	va;		/* virtual address destination/src */
-	int32_t	len;		/* bytes to be transferred */
-	int	isread;
-};
-
-/*
- *  the dma controllers.  the first half of this structure specifies
- *  the I/O ports used by the DMA controllers.
- */
-struct DMAport
-{
-	uint8_t	addr[4];	/* current address (4 channels) */
-	uint8_t	count[4];	/* current count (4 channels) */
-	uint8_t	page[4];	/* page registers (4 channels) */
-	uint8_t	cmd;		/* command status register */
-	uint8_t	req;		/* request registers */
-	uint8_t	sbm;		/* single bit mask register */
-	uint8_t	mode;		/* mode register */
-	uint8_t	cbp;		/* clear byte pointer */
-	uint8_t	mc;		/* master clear */
-	uint8_t	cmask;		/* clear mask register */
-	uint8_t	wam;		/* write all mask register bit */
-};
-
-struct DMA
-{
-	DMAport;
-	int	shift;
-	Lock;
-	DMAxfer	x[4];
-};
-
-DMA dma[2] = {
-	{ 0x00, 0x02, 0x04, 0x06,
-	  0x01, 0x03, 0x05, 0x07,
-	  0x87, 0x83, 0x81, 0x82,
-	  0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
-	 0 },
-
-	{ 0xc0, 0xc4, 0xc8, 0xcc,
-	  0xc2, 0xc6, 0xca, 0xce,
-	  0x8f, 0x8b, 0x89, 0x8a,
-	  0xd0, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde,
-	 1 },
-};
-
-/*
- *  DMA must be in the first 16MB.  This gets called early by the
- *  initialisation routines of any devices which require DMA to ensure
- *  the allocated bounce buffers are below the 16MB limit.
- */
-void
-dmainit(int chan)
-{
-	DMA *dp;
-	DMAxfer *xp;
-	uint32_t v;
-	static int once;
-
-	if(once == 0){
-//		if(ioalloc(0x00, 0x10, 0, "dma") < 0
-//		|| ioalloc(0x80, 0x10, 0, "dma") < 0
-//		|| ioalloc(0xd0, 0x10, 0, "dma") < 0)
-//			panic("dmainit");
-		outb(dma[0].mc, 0);
-		outb(dma[1].mc, 0);
-		outb(dma[0].cmask, 0);
-		outb(dma[1].cmask, 0);
-		outb(dma[1].mode, 0xC0);
-		once = 1;
-	}
-
-	dp = &dma[(chan>>2)&1];
-	chan = chan & 3;
-	xp = &dp->x[chan];
-	if(xp->bva != nil)
-		return;
-
-	v = (uint32_t)xalloc(BY2PG+BY2PG);
-	if(v == 0 || PADDR(v) >= 16*MiB){
-		print("dmainit: chan %d: 0x%luX out of range\n", chan, v);
-		xfree((void*)v);
-		v = 0;
-	}
-	xp->bva = (void*)ROUND(v, BY2PG);
-	xp->bpa = PADDR(xp->bva);
-	xp->len = 0;
-	xp->isread = 0;
-}
-
-/*
- *  setup a dma transfer.  if the destination is not in kernel
- *  memory, allocate a page for the transfer.
- *
- *  we assume BIOS has set up the command register before we
- *  are booted.
- *
- *  return the updated transfer length (we can't transfer across 64k
- *  boundaries)
- */
-int32_t
-dmasetup(int chan, void *va, int32_t len, int isread)
-{
-	DMA *dp;
-	uint32_t pa;
-	uint8_t mode;
-	DMAxfer *xp;
-
-	dp = &dma[(chan>>2)&1];
-	chan = chan & 3;
-	xp = &dp->x[chan];
-
-	/*
-	 *  if this isn't kernel memory or crossing 64k boundary or above 16 meg
-	 *  use the allocated low memory page.
-	 */
-	pa = PADDR(va);
-	if((((uint32_t)va)&0xF0000000) != KZERO
-	|| (pa&0xFFFF0000) != ((pa+len)&0xFFFF0000)
-	|| pa > 16*MiB) {
-		if(xp->bva == nil)
-			return -1;
-		if(len > BY2PG)
-			len = BY2PG;
-		if(!isread)
-			memmove(xp->bva, va, len);
-		xp->va = va;
-		xp->len = len;
-		xp->isread = isread;
-		pa = xp->bpa;
-	}
-	else
-		xp->len = 0;
-
-	/*
-	 * this setup must be atomic
-	 */
-	ilock(dp);
-	mode = (isread ? 0x44 : 0x48) | chan;
-	outb(dp->mode, mode);	/* single mode dma (give CPU a chance at mem) */
-	outb(dp->page[chan], pa>>16);
-	outb(dp->cbp, 0);		/* set count & address to their first byte */
-	outb(dp->addr[chan], pa>>dp->shift);		/* set address */
-	outb(dp->addr[chan], pa>>(8+dp->shift));
-	outb(dp->count[chan], (len>>dp->shift)-1);		/* set count */
-	outb(dp->count[chan], ((len>>dp->shift)-1)>>8);
-	outb(dp->sbm, chan);		/* enable the channel */
-	iunlock(dp);
-
-	return len;
-}
-
-int
-dmadone(int chan)
-{
-	DMA *dp;
-
-	dp = &dma[(chan>>2)&1];
-	chan = chan & 3;
-
-	return inb(dp->cmd) & (1<<chan);
-}
-
-/*
- *  this must be called after a dma has been completed.
- *
- *  if a page has been allocated for the dma,
- *  copy the data into the actual destination
- *  and free the page.
- */
-void
-dmaend(int chan)
-{
-	DMA *dp;
-	DMAxfer *xp;
-
-	dp = &dma[(chan>>2)&1];
-	chan = chan & 3;
-
-	/*
-	 *  disable the channel
-	 */
-	ilock(dp);
-	outb(dp->sbm, 4|chan);
-	iunlock(dp);
-
-	xp = &dp->x[chan];
-	if(xp->len == 0 || !xp->isread)
-		return;
-
-	/*
-	 *  copy out of temporary page
-	 */
-	memmove(xp->va, xp->bva, xp->len);
-	xp->len = 0;
-}
-
-/*
-int
-dmacount(int chan)
-{
-	int     retval;
-	DMA     *dp;
-
-	dp = &dma[(chan>>2)&1];
-	outb(dp->cbp, 0);
-	retval = inb(dp->count[chan]);
-	retval |= inb(dp->count[chan]) << 8;
-	return((retval<<dp->shift)+1);
-}
- */

+ 0 - 594
sys/src/9/w/pxeload/dosboot.c

@@ -1,594 +0,0 @@
-/*
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
-
-#include	"u.h"
-#include	"lib.h"
-#include	"mem.h"
-#include	"dat.h"
-#include	"fns.h"
-#include	"fs.h"
-
-struct Dosboot{
-	uint8_t	magic[3];
-	uint8_t	version[8];
-	uint8_t	sectsize[2];
-	uint8_t	clustsize;
-	uint8_t	nresrv[2];
-	uint8_t	nfats;
-	uint8_t	rootsize[2];
-	uint8_t	volsize[2];
-	uint8_t	mediadesc;
-	uint8_t	fatsize[2];
-	uint8_t	trksize[2];
-	uint8_t	nheads[2];
-	uint8_t	nhidden[4];
-	uint8_t	bigvolsize[4];
-/* fat 32 */
-	uint8_t	bigfatsize[4];
-	uint8_t	extflags[2];
-	uint8_t	fsversion[2];
-	uint8_t	rootdirstartclust[4];
-	uint8_t	fsinfosect[2];
-	uint8_t	backupbootsect[2];
-/* ???
-	uchar	driveno;
-	uchar	reserved0;
-	uchar	bootsig;
-	uchar	volid[4];
-	uchar	label[11];
-	uchar	reserved1[8];
-*/
-};
-
-struct Dosdir{
-	uint8_t	name[8];
-	uint8_t	ext[3];
-	uint8_t	attr;
-	uint8_t	lowercase;
-	uint8_t	hundredth;
-	uint8_t	ctime[2];
-	uint8_t	cdate[2];
-	uint8_t	adate[2];
-	uint8_t	highstart[2];
-	uint8_t	mtime[2];
-	uint8_t	mdate[2];
-	uint8_t	start[2];
-	uint8_t	length[4];
-};
-
-#define	DOSRONLY	0x01
-#define	DOSHIDDEN	0x02
-#define	DOSSYSTEM	0x04
-#define	DOSVLABEL	0x08
-#define	DOSDIR	0x10
-#define	DOSARCH	0x20
-
-/*
- *  predeclared
- */
-static void	bootdump(Dosboot*);
-static void	setname(Dosfile*, char*);
-
-/*
- *  debugging
- */
-#define chatty	0
-#define chat	if(chatty)print
-
-/*
- *  block io buffers
- */
-enum
-{
-	Nbio=	16,
-};
-typedef struct	Clustbuf	Clustbuf;
-struct Clustbuf
-{
-	int	age;
-	int32_t	sector;
-	uint8_t	*iobuf;
-	Dos	*dos;
-	int	size;
-};
-Clustbuf	bio[Nbio];
-
-/*
- *  get an io block from an io buffer
- */
-Clustbuf*
-getclust(Dos *dos, int32_t sector)
-{
-	Fs *fs;
-	Clustbuf *p, *oldest;
-	int size;
-
-	chat("getclust @ %ld\n", sector);
-
-	/*
-	 *  if we have it, just return it
-	 */
-	for(p = bio; p < &bio[Nbio]; p++){
-		if(sector == p->sector && dos == p->dos){
-			p->age = machp()->ticks;
-			chat("getclust %ld in cache\n", sector);
-			return p;
-		}
-	}
-
-	/*
-	 *  otherwise, reuse the oldest entry
-	 */
-	oldest = bio;
-	for(p = &bio[1]; p < &bio[Nbio]; p++){
-		if(p->age <= oldest->age)
-			oldest = p;
-	}
-	p = oldest;
-
-	/*
-	 *  make sure the buffer is big enough
-	 */
-	size = dos->clustsize*dos->sectsize;
-	if(p->iobuf==0 || p->size < size)
-		p->iobuf = ialloc(size, 0);
-	p->size = size;
-
-	/*
-	 *  read in the cluster
-	 */
-	fs = (Fs*)dos;
-	chat("getclust addr %lud %p %p %p\n",
-	     (uint32_t)((sector+dos->start)*(int64_t)dos->sectsize),
-		fs, fs->diskseek, fs->diskread);
-	if(fs->diskseek(fs, (sector+dos->start)*(int64_t)dos->sectsize) < 0){
-		chat("can't seek block\n");
-		return 0;
-	}
-	if(fs->diskread(fs, p->iobuf, size) != size){
-		chat("can't read block\n");
-		return 0;
-	}
-
-	p->age = machp()->ticks;
-	p->dos = dos;
-	p->sector = sector;
-	chat("getclust %ld read\n", sector);
-	return p;
-}
-
-/*
- *  walk the fat one level ( n is a current cluster number ).
- *  return the new cluster number or -1 if no more.
- */
-static int32_t
-fatwalk(Dos *dos, int n)
-{
-	uint32_t k, sect;
-	Clustbuf *p;
-	int o;
-
-	chat("fatwalk %d\n", n);
-
-	if(n < 2 || n >= dos->fatclusters)
-		return -1;
-
-	switch(dos->fatbits){
-	case 12:
-		k = (3*n)/2; break;
-	case 16:
-		k = 2*n; break;
-	case 32:
-		k = 4*n; break;
-	default:
-		return -1;
-	}
-	if(k >= dos->fatsize*dos->sectsize)
-		panic("getfat");
-
-	sect = (k/(dos->sectsize*dos->clustsize))*dos->clustsize + dos->fataddr;
-	o = k%(dos->sectsize*dos->clustsize);
-	p = getclust(dos, sect);
-	k = p->iobuf[o++];
-	if(o >= dos->sectsize*dos->clustsize){
-		p = getclust(dos, sect+dos->clustsize);
-		o = 0;
-	}
-	k |= p->iobuf[o++]<<8;
-	if(dos->fatbits == 12){
-		if(n&1)
-			k >>= 4;
-		else
-			k &= 0xfff;
-		if(k >= 0xff8)
-			k = -1;
-	}
-	else if (dos->fatbits == 32){
-		if(o >= dos->sectsize*dos->clustsize){
-			p = getclust(dos, sect+dos->clustsize);
-			o = 0;
-		}
-		k |= p->iobuf[o++]<<16;
-		k |= p->iobuf[o]<<24;
-		if (k >= 0xfffffff8)
-			k = -1;
-	}
-	else
-		k = k < 0xfff8 ? k : -1;
-	chat("fatwalk %d -> %lud\n", n, k);
-	return k;
-}
-
-/*
- *  map a file's logical cluster address to a physical sector address
- */
-static int32_t
-fileaddr(Dosfile *fp, int32_t ltarget)
-{
-	Dos *dos = fp->dos;
-	int32_t l;
-	int32_t p;
-
-	chat("fileaddr %8.8s %ld\n", fp->name, ltarget);
-	/*
-	 *  root directory is contiguous and easy (unless FAT32)
-	 */
-	if(fp->pstart == 0 && dos->rootsize != 0) {
-		if(ltarget*dos->sectsize*dos->clustsize >= dos->rootsize*sizeof(Dosdir))
-			return -1;
-		l = dos->rootaddr + ltarget*dos->clustsize;
-		chat("fileaddr %ld -> %ld\n", ltarget, l);
-		return l;
-	}
-
-	/*
-	 *  anything else requires a walk through the fat
-	 */
-	if(ltarget >= fp->lcurrent && fp->pcurrent){
-		/* start at the currrent point */
-		l = fp->lcurrent;
-		p = fp->pcurrent;
-	} else {
-		/* go back to the beginning */
-		l = 0;
-		p = fp->pstart;
-	}
-	while(l != ltarget){
-		/* walk the fat */
-		p = fatwalk(dos, p);
-		if(p < 0)
-			return -1;
-		l++;
-	}
-	fp->lcurrent = l;
-	fp->pcurrent = p;
-
-	/*
-	 *  clusters start at 2 instead of 0 (why? - presotto)
-	 */
-	l =  dos->dataaddr + (p-2)*dos->clustsize;
-	chat("fileaddr %ld -> %ld\n", ltarget, l);
-	return l;
-}
-
-/*
- *  read from a dos file
- */
-int32_t
-dosread(Dosfile *fp, void *a, int32_t n)
-{
-	int32_t addr;
-	int32_t rv;
-	int i;
-	int off;
-	Clustbuf *p;
-	uint8_t *from, *to;
-
-	if((fp->attr & DOSDIR) == 0){
-		if(fp->offset >= fp->length)
-			return 0;
-		if(fp->offset+n > fp->length)
-			n = fp->length - fp->offset;
-	}
-
-	to = a;
-	for(rv = 0; rv < n; rv+=i){
-		/*
-		 *  read the cluster
-		 */
-		addr = fileaddr(fp, fp->offset/fp->dos->clustbytes);
-		if(addr < 0)
-			return -1;
-		p = getclust(fp->dos, addr);
-		if(p == 0)
-			return -1;
-
-		/*
-		 *  copy the bytes we need
-		 */
-		off = fp->offset % fp->dos->clustbytes;
-		from = &p->iobuf[off];
-		i = n - rv;
-		if(i > fp->dos->clustbytes - off)
-			i = fp->dos->clustbytes - off;
-		memmove(to, from, i);
-		to += i;
-		fp->offset += i;
-	}
-
-	return rv;
-}
-
-/*
- *  walk a directory returns
- * 	-1 if something went wrong
- *	 0 if not found
- *	 1 if found
- */
-int
-doswalk(File *f, char *name)
-{
-	Dosdir d;
-	int32_t n;
-	Dosfile *file;
-
-	chat("doswalk %s\n", name);
-
-	file = &f->dos;
-
-	if((file->attr & DOSDIR) == 0){
-		chat("walking non-directory!\n");
-		return -1;
-	}
-
-	setname(file, name);
-
-	file->offset = 0;	/* start at the beginning */
-	while((n = dosread(file, &d, sizeof(d))) == sizeof(d)){
-		chat("comparing to %8.8s.%3.3s\n", (char*)d.name,
-		     (char*)d.ext);
-		if(memcmp(file->name, d.name, sizeof(d.name)) != 0)
-			continue;
-		if(memcmp(file->ext, d.ext, sizeof(d.ext)) != 0)
-			continue;
-		if(d.attr & DOSVLABEL){
-			chat("%8.8s.%3.3s is a LABEL\n", (char*)d.name,
-			     (char*)d.ext);
-			continue;
-		}
-		file->attr = d.attr;
-		file->pstart = GSHORT(d.start);
-		if (file->dos->fatbits == 32)
-			file->pstart |= GSHORT(d.highstart) << 16;
-		file->length = GLONG(d.length);
-		file->pcurrent = 0;
-		file->lcurrent = 0;
-		file->offset = 0;
-		return 1;
-	}
-	return n >= 0 ? 0 : -1;
-}
-
-/*
- *  instructions that boot blocks can start with
- */
-#define	JMPSHORT	0xeb
-#define JMPNEAR		0xe9
-
-/*
- *  read in a segment
- */
-int32_t
-dosreadseg(File *f, void *va, int32_t len)
-{
-	char *a;
-	int32_t n, sofar;
-	Dosfile *fp;
-
-	fp = &f->dos;
-	a = va;
-	for(sofar = 0; sofar < len; sofar += n){
-		n = 8*1024;
-		if(len - sofar < n)
-			n = len - sofar;
-		n = dosread(fp, a + sofar, n);
-		if(n <= 0)
-			break;
-		print(".");
-	}
-	return sofar;
-}
-
-int
-dosinit(Fs *fs)
-{
-	Clustbuf *p;
-	Dosboot *b;
-	int i;
-	Dos *dos;
-	Dosfile *root;
-
-chat("dosinit0 %p %p %p\n", fs, fs->diskseek, fs->diskread);
-
-	dos = &fs->dos;
-	/* defaults till we know better */
-	dos->sectsize = 512;
-	dos->clustsize = 1;
-
-	/* get first sector */
-	p = getclust(dos, 0);
-	if(p == 0){
-		chat("can't read boot block\n");
-		return -1;
-	}
-
-chat("dosinit0a\n");
-
-	p->dos = 0;
-	b = (Dosboot *)p->iobuf;
-	if(b->magic[0] != JMPNEAR && (b->magic[0] != JMPSHORT || b->magic[2] != 0x90)){
-		chat("no dos file system %x %x %x %x\n",
-			b->magic[0], b->magic[1], b->magic[2], b->magic[3]);
-		return -1;
-	}
-
-	if(chatty)
-		bootdump(b);
-
-	if(b->clustsize == 0) {
-unreasonable:
-		if(chatty){
-			print("unreasonable FAT BPB: ");
-			for(i=0; i<3+8+2+1; i++)
-				print(" %.2ux", p->iobuf[i]);
-			print("\n");
-		}
-		return -1;
-	}
-
-chat("dosinit1\n");
-
-	/*
-	 * Determine the systems' wondrous properties.
-	 * There are heuristics here, but there's no real way
-	 * of knowing if this is a reasonable FAT.
-	 */
-	dos->fatbits = 0;
-	dos->sectsize = GSHORT(b->sectsize);
-	if(dos->sectsize & 0xFF)
-		goto unreasonable;
-	dos->clustsize = b->clustsize;
-	dos->clustbytes = dos->sectsize*dos->clustsize;
-	dos->nresrv = GSHORT(b->nresrv);
-	dos->nfats = b->nfats;
-	dos->fatsize = GSHORT(b->fatsize);
-	dos->rootsize = GSHORT(b->rootsize);
-	dos->volsize = GSHORT(b->volsize);
-	if(dos->volsize == 0)
-		dos->volsize = GLONG(b->bigvolsize);
-	dos->mediadesc = b->mediadesc;
-	if(dos->fatsize == 0) {
-		chat("fat32\n");
-		dos->rootsize = 0;
-		dos->fatsize = GLONG(b->bigfatsize);
-		dos->fatbits = 32;
-	}
-	dos->fataddr = dos->nresrv;
-	if (dos->rootsize == 0) {
-		dos->rootaddr = 0;
-		dos->rootclust = GLONG(b->rootdirstartclust);
-		dos->dataaddr = dos->fataddr + dos->nfats*dos->fatsize;
-	} else {
-		dos->rootaddr = dos->fataddr + dos->nfats*dos->fatsize;
-		i = dos->rootsize*sizeof(Dosdir) + dos->sectsize - 1;
-		i = i/dos->sectsize;
-		dos->dataaddr = dos->rootaddr + i;
-	}
-	dos->fatclusters = 2+(dos->volsize - dos->dataaddr)/dos->clustsize;
-	if(dos->fatbits != 32) {
-		if(dos->fatclusters < 4087)
-			dos->fatbits = 12;
-		else
-			dos->fatbits = 16;
-	}
-	dos->freeptr = 2;
-
-	if(dos->clustbytes < 512 || dos->clustbytes > 64*1024)
-		goto unreasonable;
-
-chat("dosinit2\n");
-
-	/*
-	 *  set up the root
-	 */
-
-	fs->root.fs = fs;
-	root = &fs->root.dos;
-	root->dos = dos;
-	root->pstart = dos->rootsize == 0 ? dos->rootclust : 0;
-	root->pcurrent = root->lcurrent = 0;
-	root->offset = 0;
-	root->attr = DOSDIR;
-	root->length = dos->rootsize*sizeof(Dosdir);
-
-chat("dosinit3\n");
-
-	fs->read = dosreadseg;
-	fs->walk = doswalk;
-	return 0;
-}
-
-static void
-bootdump(Dosboot *b)
-{
-	if(chatty == 0)
-		return;
-	print("magic: 0x%2.2x 0x%2.2x 0x%2.2x ",
-		b->magic[0], b->magic[1], b->magic[2]);
-	print("version: \"%8.8s\"\n", (char*)b->version);
-	print("sectsize: %d ", GSHORT(b->sectsize));
-	print("allocsize: %d ", b->clustsize);
-	print("nresrv: %d ", GSHORT(b->nresrv));
-	print("nfats: %d\n", b->nfats);
-	print("rootsize: %d ", GSHORT(b->rootsize));
-	print("volsize: %d ", GSHORT(b->volsize));
-	print("mediadesc: 0x%2.2x\n", b->mediadesc);
-	print("fatsize: %d ", GSHORT(b->fatsize));
-	print("trksize: %d ", GSHORT(b->trksize));
-	print("nheads: %d ", GSHORT(b->nheads));
-	print("nhidden: %d ", GLONG(b->nhidden));
-	print("bigvolsize: %d\n", GLONG(b->bigvolsize));
-/*
-	print("driveno: %d\n", b->driveno);
-	print("reserved0: 0x%2.2x\n", b->reserved0);
-	print("bootsig: 0x%2.2x\n", b->bootsig);
-	print("volid: 0x%8.8x\n", GLONG(b->volid));
-	print("label: \"%11.11s\"\n", b->label);
-*/
-}
-
-
-/*
- *  set up a dos file name
- */
-static void
-setname(Dosfile *fp, char *from)
-{
-	char *to;
-
-	to = fp->name;
-	for(; *from && to-fp->name < 8; from++, to++){
-		if(*from == '.'){
-			from++;
-			break;
-		}
-		if(*from >= 'a' && *from <= 'z')
-			*to = *from + 'A' - 'a';
-		else
-			*to = *from;
-	}
-	while(to - fp->name < 8)
-		*to++ = ' ';
-
-	/* from might be 12345678.123: don't save the '.' in ext */
-	if(*from == '.')
-		from++;
-
-	to = fp->ext;
-	for(; *from && to-fp->ext < 3; from++, to++){
-		if(*from >= 'a' && *from <= 'z')
-			*to = *from + 'A' - 'a';
-		else
-			*to = *from;
-	}
-	while(to-fp->ext < 3)
-		*to++ = ' ';
-
-	chat("name is %8.8s.%3.3s\n", fp->name, fp->ext);
-}

+ 0 - 71
sys/src/9/w/pxeload/dosfs.h

@@ -1,71 +0,0 @@
-/* 
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
-
-typedef struct Dosboot	Dosboot;
-typedef struct Dos	Dos;
-typedef struct Dosdir	Dosdir;
-typedef struct Dosfile	Dosfile;
-typedef struct Dospart	Dospart;
-
-struct Dospart
-{
-	uchar flag;		/* active flag */
-	uchar shead;		/* starting head */
-	uchar scs[2];		/* starting cylinder/sector */
-	uchar type;		/* partition type */
-	uchar ehead;		/* ending head */
-	uchar ecs[2];		/* ending cylinder/sector */
-	uchar start[4];		/* starting sector */
-	uchar len[4];		/* length in sectors */
-};
-
-#define FAT12	0x01
-#define FAT16	0x04
-#define EXTEND	0x05
-#define FATHUGE	0x06
-#define FAT32	0x0b
-#define FAT32X	0x0c
-#define EXTHUGE	0x0f
-#define DMDDO	0x54
-#define PLAN9	0x39
-#define LEXTEND 0x85
-
-struct Dosfile{
-	Dos	*dos;		/* owning dos file system */
-	char	name[8];
-	char	ext[3];
-	uchar	attr;
-	long	length;
-	long	pstart;		/* physical start cluster address */
-	long	pcurrent;	/* physical current cluster address */
-	long	lcurrent;	/* logical current cluster address */
-	long	offset;
-};
-
-struct Dos{
-	long	start;		/* start of file system */
-	int	sectsize;	/* in bytes */
-	int	clustsize;	/* in sectors */
-	int	clustbytes;	/* in bytes */
-	int	nresrv;		/* sectors */
-	int	nfats;		/* usually 2 */
-	int	rootsize;	/* number of entries */
-	int	volsize;	/* in sectors */
-	int	mediadesc;
-	int	fatsize;	/* in sectors */
-	int	fatclusters;
-	int	fatbits;	/* 12 or 16 */
-	long	fataddr;	/* sector number */
-	long	rootaddr;
-	long	rootclust;
-	long	dataaddr;
-	long	freeptr;
-};
-
-extern int	dosinit(Fs*);

+ 0 - 58
sys/src/9/w/pxeload/error.h

@@ -1,58 +0,0 @@
-extern char Enoerror[];		/* no error */
-extern char Emount[];		/* inconsistent mount */
-extern char Eunmount[];		/* not mounted */
-extern char Eunion[];		/* not in union */
-extern char Emountrpc[];	/* mount rpc error */
-extern char Eshutdown[];	/* mounted device shut down */
-extern char Enocreate[];	/* mounted directory forbids creation */
-extern char Enonexist[];	/* file does not exist */
-extern char Eexist[];		/* file already exists */
-extern char Ebadsharp[];	/* unknown device in # filename */
-extern char Enotdir[];		/* not a directory */
-extern char Eisdir[];		/* file is a directory */
-extern char Ebadchar[];		/* bad character in file name */
-extern char Efilename[];	/* file name syntax */
-extern char Eperm[];		/* permission denied */
-extern char Ebadusefd[];	/* inappropriate use of fd */
-extern char Ebadarg[];		/* bad arg in system call */
-extern char Einuse[];		/* device or object already in use */
-extern char Eio[];		/* i/o error */
-extern char Etoobig[];		/* read or write too large */
-extern char Etoosmall[];	/* read or write too small */
-extern char Enetaddr[];		/* bad network address */
-extern char Emsgsize[];		/* message is too big for protocol */
-extern char Enetbusy[];		/* network device is busy or allocated */
-extern char Enoproto[];		/* network protocol not supported */
-extern char Enoport[];		/* network port not available */
-extern char Enoifc[];		/* bad interface or no free interface slots */
-extern char Enolisten[];	/* not announced */
-extern char Ehungup[];		/* write to hungup channel */
-extern char Ebadctl[];		/* bad process or channel control request */
-extern char Enodev[];		/* no free devices */
-extern char Enoenv[];		/* no free environment resources */
-extern char Emuxshutdown[];	/* mux server shut down */
-extern char Emuxbusy[];		/* all mux channels busy */
-extern char Emuxmsg[];		/* bad mux message format or mismatch */
-extern char Eprocdied[];	/* process exited */
-extern char Enochild[];		/* no living children */
-extern char Eioload[];		/* i/o error in demand load */
-extern char Enovmem[];		/* virtual memory allocation failed */
-extern char Ebadld[];		/* illegal line discipline */
-extern char Ebadfd[];		/* fd out of range or not open */
-extern char Eisstream[];	/* seek on a stream */
-extern char Ebadexec[];		/* exec header invalid */
-extern char Etimedout[];	/* connection timed out */
-extern char Econrefused[];	/* connection refused */
-extern char Enetunreach[];	/* network unreachable */
-extern char Eintr[];		/* interrupted */
-extern char Eneedservice[];	/* service required for tcp/udp/il calls */
-extern char Enomem[];		/* kernel allocate failed */
-extern char Enoswap[];		/* swap space full */
-extern char Esfnotcached[];	/* subfont not cached */
-extern char Esoverlap[];	/* segments overlap */
-extern char Emouseset[];	/* mouse type already set */
-extern char Erecover[];		/* failed to recover fd */
-extern char Eshort[];		/* i/o count too small */
-extern char Egreg[];		/* ken scheduled it */
-extern char Ebadspec[];		/* bad attach specifier */
-extern char Enoreg[];		/* process has no saved registers */

+ 0 - 280
sys/src/9/w/pxeload/ether.c

@@ -1,280 +0,0 @@
-/*
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
-
-#include "u.h"
-#include "lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#include "ip.h"
-
-#include "etherif.h"
-
-static Ether ether[MaxEther];
-
-extern int amd79c970reset(Ether*);
-extern int ether2114xreset(Ether*);
-extern int etherbcm4401pnp(Ether*);
-extern int i82557reset(Ether*);
-extern int i82563pnp(Ether*);
-extern int igbepnp(Ether *);
-extern int rtl8139pnp(Ether*);
-extern int rtl8169pnp(Ether*);
-extern int vgbepnp(Ether*);
-
-struct {
-	char	*type;
-	int	(*reset)(Ether*);
-	int	noprobe;
-} ethercards[] = {
-	{ "21140", ether2114xreset, 0, },
-	{ "2114x", ether2114xreset, 0, },
-	{ "bcm4401", etherbcm4401pnp, 0, },
-	{ "i82557", i82557reset, 0, },
-	{ "i82563", i82563pnp, 0, },
-	{ "igbe",  igbepnp, 0, },
-	{ "RTL8139", rtl8139pnp, 0, },
-	{ "RTL8169", rtl8169pnp, 0, },
-	{ "AMD79C970", amd79c970reset, 0, },
-	{ "vgbe", vgbepnp, 0, },
-
-	{ 0, }
-};
-
-static void xetherdetach(void);
-
-int
-etherinit(void)
-{
-	Ether *ctlr;
-	int ctlrno, i, mask, n, x;
-
-	fmtinstall('E', eipfmt);
-
-	etherdetach = xetherdetach;
-	mask = 0;
-	for(ctlrno = 0; ctlrno < MaxEther; ctlrno++){
-		ctlr = &ether[ctlrno];
-		memset(ctlr, 0, sizeof(Ether));
-		if(iniread && isaconfig("ether", ctlrno, ctlr) == 0)
-			continue;
-
-		for(n = 0; ethercards[n].type; n++){
-			if(!iniread){
-				if(ethercards[n].noprobe)
-					continue;
-				memset(ctlr, 0, sizeof(Ether));
-				ctlr->type = ethercards[n].type;
-			}
-			else if(cistrcmp(ethercards[n].type, ctlr->type))
-				continue;
-			ctlr->ctlrno = ctlrno;
-
-			x = splhi();
-			if((*ethercards[n].reset)(ctlr)){
-				splx(x);
-				if(iniread)
-					break;
-				else
-					continue;
-			}
-
-			ctlr->state = 1;
-			mask |= 1<<ctlrno;
-			if(ctlr->irq == 2)
-				ctlr->irq = 9;
-			setvec(VectorPIC + ctlr->irq, ctlr->interrupt, ctlr);
-
-			print("ether#%d: %s: port 0x%luX irq %lud",
-				ctlr->ctlrno, ctlr->type, ctlr->port, ctlr->irq);
-			if(ctlr->mem)
-				print(" addr 0x%luX", ctlr->mem & ~KZERO);
-			if(ctlr->size)
-				print(" size 0x%luX", ctlr->size);
-			print(": %E\n", ctlr->ea);
-
-			if(ctlr->nrb == 0)
-				ctlr->nrb = Nrb;
-			ctlr->rb = ialloc(sizeof(RingBuf)*ctlr->nrb, 0);
-			if(ctlr->ntb == 0)
-				ctlr->ntb = Ntb;
-			ctlr->tb = ialloc(sizeof(RingBuf)*ctlr->ntb, 0);
-
-			ctlr->rh = 0;
-			ctlr->ri = 0;
-			for(i = 0; i < ctlr->nrb; i++)
-				ctlr->rb[i].owner = Interface;
-
-			ctlr->th = 0;
-			ctlr->ti = 0;
-			for(i = 0; i < ctlr->ntb; i++)
-				ctlr->tb[i].owner = Host;
-
-			splx(x);
-			break;
-		}
-	}
-
-	return mask;
-}
-
-void
-etherinitdev(int i, char *s)
-{
-	sprint(s, "ether%d", i);
-}
-
-void
-etherprintdevs(int i)
-{
-	print(" ether%d", i);
-}
-
-static Ether*
-attach(int ctlrno)
-{
-	Ether *ctlr;
-
-	if(ctlrno >= MaxEther || ether[ctlrno].state == 0)
-		return 0;
-
-	ctlr = &ether[ctlrno];
-	if(ctlr->state == 1){
-		ctlr->state = 2;
-		(*ctlr->attach)(ctlr);
-	}
-
-	return ctlr;
-}
-
-static void
-xetherdetach(void)
-{
-	Ether *ctlr;
-	int ctlrno, x;
-
-	x = splhi();
-	for(ctlrno = 0; ctlrno < MaxEther; ctlrno++){
-		ctlr = &ether[ctlrno];
-		if(ctlr->detach && ctlr->state != 0)
-			ctlr->detach(ctlr);
-	}
-	splx(x);
-}
-
-uint8_t*
-etheraddr(int ctlrno)
-{
-	Ether *ctlr;
-
-	if((ctlr = attach(ctlrno)) == 0)
-		return 0;
-
-	return ctlr->ea;
-}
-
-static int
-wait(RingBuf* ring, uint8_t owner, int timo)
-{
-	uint32_t start;
-	extern void hlt(void);
-
-	start = machp()->ticks;
-	while(TK2MS(machp()->ticks - start) < timo){
-		if(ring->owner != owner)
-			return 1;
-		hlt();
-	}
-
-	return 0;
-}
-
-int
-etherrxpkt(int ctlrno, Etherpkt* pkt, int timo)
-{
-	int n;
-	Ether *ctlr;
-	RingBuf *ring;
-
-	if((ctlr = attach(ctlrno)) == 0)
-		return 0;
-
-	ring = &ctlr->rb[ctlr->rh];
-	if(wait(ring, Interface, timo) == 0){
-		if(debug)
-			print("ether%d: rx timeout\n", ctlrno);
-		return 0;
-	}
-
-	n = ring->len;
-	memmove(pkt, ring->pkt, n);
-	ring->owner = Interface;
-	ctlr->rh = NEXT(ctlr->rh, ctlr->nrb);
-
-	return n;
-}
-
-int
-etherrxflush(int ctlrno)
-{
-	int n;
-	Ether *ctlr;
-	RingBuf *ring;
-
-	if((ctlr = attach(ctlrno)) == 0)
-		return 0;
-
-	n = 0;
-	for(;;){
-		ring = &ctlr->rb[ctlr->rh];
-		if(wait(ring, Interface, 100) == 0)
-			break;
-
-		ring->owner = Interface;
-		ctlr->rh = NEXT(ctlr->rh, ctlr->nrb);
-		n++;
-	}
-
-	return n;
-}
-
-int
-ethertxpkt(int ctlrno, Etherpkt* pkt, int len, int)
-{
-	Ether *ctlr;
-	RingBuf *ring;
-	int s;
-
-	if((ctlr = attach(ctlrno)) == 0)
-		return 0;
-
-	ring = &ctlr->tb[ctlr->th];
-	if(wait(ring, Interface, 1000) == 0){
-		print("ether%d: tx buffer timeout\n", ctlrno);
-		return 0;
-	}
-
-	memmove(pkt->s, ctlr->ea, Eaddrlen);
-	if(debug)
-		print("%E to %E...\n", pkt->s, pkt->d);
-	memmove(ring->pkt, pkt, len);
-	if(len < ETHERMINTU){
-		memset(ring->pkt+len, 0, ETHERMINTU-len);
-		len = ETHERMINTU;
-	}
-	ring->len = len;
-	ring->owner = Interface;
-	ctlr->th = NEXT(ctlr->th, ctlr->ntb);
-	s = splhi();
-	(*ctlr->transmit)(ctlr);
-	splx(s);
-
-	return 1;
-}

+ 0 - 1688
sys/src/9/w/pxeload/ether2114x.c

@@ -1,1688 +0,0 @@
-/*
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
-
-/*
- * Digital Semiconductor DECchip 21140 PCI Fast Ethernet LAN Controller
- * as found on the Digital Fast EtherWORKS PCI 10/100 adapter (DE-500-X).
- * To do:
- *	thresholds;
- *	ring sizing;
- *	handle more error conditions;
- *	all the rest of it...
- */
-#include "u.h"
-#include "lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-
-#include "etherif.h"
-
-#define DEBUG		(0)
-#define debug		if(DEBUG)print
-
-enum {
-	Nrde		= 32,
-	Ntde		= 4,
-};
-
-#define Rbsz		ROUNDUP(sizeof(Etherpkt)+4, 4)
-
-enum {					/* CRS0 - Bus Mode */
-	Swr		= 0x00000001,	/* Software Reset */
-	Bar		= 0x00000002,	/* Bus Arbitration */
-	Dsl		= 0x0000007C,	/* Descriptor Skip Length (field) */
-	Ble		= 0x00000080,	/* Big/Little Endian */
-	Pbl		= 0x00003F00,	/* Programmable Burst Length (field) */
-	Cal		= 0x0000C000,	/* Cache Alignment (field) */
-	Cal8		= 0x00004000,	/* 8 longword boundary alignment */
-	Cal16		= 0x00008000,	/* 16 longword boundary alignment */
-	Cal32		= 0x0000C000,	/* 32 longword boundary alignment */
-	Tap		= 0x000E0000,	/* Transmit Automatic Polling (field) */
-	Dbo		= 0x00100000,	/* Descriptor Byte Ordering Mode */
-	Rml		= 0x00200000,	/* Read Multiple */
-};
-
-enum {					/* CSR[57] - Status and Interrupt Enable */
-	Ti		= 0x00000001,	/* Transmit Interrupt */
-	Tps		= 0x00000002,	/* Transmit Process Stopped */
-	Tu		= 0x00000004,	/* Transmit buffer Unavailable */
-	Tjt		= 0x00000008,	/* Transmit Jabber Timeout */
-	Unf		= 0x00000020,	/* transmit UNderFlow */
-	Ri		= 0x00000040,	/* Receive Interrupt */
-	Ru		= 0x00000080,	/* Receive buffer Unavailable */
-	Rps		= 0x00000100,	/* Receive Process Stopped */
-	Rwt		= 0x00000200,	/* Receive Watchdog Timeout */
-	Eti		= 0x00000400,	/* Early Transmit Interrupt */
-	Gte		= 0x00000800,	/* General purpose Timer Expired */
-	Fbe		= 0x00002000,	/* Fatal Bit Error */
-	Ais		= 0x00008000,	/* Abnormal Interrupt Summary */
-	Nis		= 0x00010000,	/* Normal Interrupt Summary */
-	Rs		= 0x000E0000,	/* Receive process State (field) */
-	Ts		= 0x00700000,	/* Transmit process State (field) */
-	Eb		= 0x03800000,	/* Error bits */
-};
-
-enum {					/* CSR6 - Operating Mode */
-	Hp		= 0x00000001,	/* Hash/Perfect receive filtering mode */
-	Sr		= 0x00000002,	/* Start/stop Receive */
-	Ho		= 0x00000004,	/* Hash-Only filtering mode */
-	Pb		= 0x00000008,	/* Pass Bad frames */
-	If		= 0x00000010,	/* Inverse Filtering */
-	Sb		= 0x00000020,	/* Start/stop Backoff counter */
-	Pr		= 0x00000040,	/* Promiscuous Mode */
-	Pm		= 0x00000080,	/* Pass all Multicast */
-	Fd		= 0x00000200,	/* Full Duplex mode */
-	Om		= 0x00000C00,	/* Operating Mode (field) */
-	Fc		= 0x00001000,	/* Force Collision */
-	St		= 0x00002000,	/* Start/stop Transmission Command */
-	Tr		= 0x0000C000,	/* ThReshold control bits (field) */
-	Tr128		= 0x00000000,
-	Tr256		= 0x00004000,
-	Tr512		= 0x00008000,
-	Tr1024		= 0x0000C000,
-	Ca		= 0x00020000,	/* CApture effect enable */
-	Ps		= 0x00040000,	/* Port Select */
-	Hbd		= 0x00080000,	/* HeartBeat Disable */
-	Imm		= 0x00100000,	/* IMMediate mode */
-	Sf		= 0x00200000,	/* Store and Forward */
-	Ttm		= 0x00400000,	/* Transmit Threshold Mode */
-	Pcs		= 0x00800000,	/* PCS function */
-	Scr		= 0x01000000,	/* SCRambler mode */
-	Mbo		= 0x02000000,	/* Must Be One */
-	Ra		= 0x40000000,	/* Receive All */
-	Sc		= 0x80000000,	/* Special Capture effect enable */
-
-	TrMODE		= Tr512,	/* default transmission threshold */
-};
-
-enum {					/* CSR9 - ROM and MII Management */
-	Scs		= 0x00000001,	/* serial ROM chip select */
-	Sclk		= 0x00000002,	/* serial ROM clock */
-	Sdi		= 0x00000004,	/* serial ROM data in */
-	Sdo		= 0x00000008,	/* serial ROM data out */
-	Ss		= 0x00000800,	/* serial ROM select */
-	Wr		= 0x00002000,	/* write */
-	Rd		= 0x00004000,	/* read */
-
-	Mdc		= 0x00010000,	/* MII management clock */
-	Mdo		= 0x00020000,	/* MII management write data */
-	Mii		= 0x00040000,	/* MII management operation mode (W) */
-	Mdi		= 0x00080000,	/* MII management data in */
-};
-
-enum {					/* CSR12 - General-Purpose Port */
-	Gpc		= 0x00000100,	/* General Purpose Control */
-};
-
-typedef struct Des {
-	int	status;
-	int	control;
-	uint32_t	addr;
-	void*	bp;
-} Des;
-
-enum {					/* status */
-	Of		= 0x00000001,	/* Rx: OverFlow */
-	Ce		= 0x00000002,	/* Rx: CRC Error */
-	Db		= 0x00000004,	/* Rx: Dribbling Bit */
-	Re		= 0x00000008,	/* Rx: Report on MII Error */
-	Rw		= 0x00000010,	/* Rx: Receive Watchdog */
-	Ft		= 0x00000020,	/* Rx: Frame Type */
-	Cs		= 0x00000040,	/* Rx: Collision Seen */
-	Tl		= 0x00000080,	/* Rx: Frame too Long */
-	Ls		= 0x00000100,	/* Rx: Last deScriptor */
-	Fs		= 0x00000200,	/* Rx: First deScriptor */
-	Mf		= 0x00000400,	/* Rx: Multicast Frame */
-	Rf		= 0x00000800,	/* Rx: Runt Frame */
-	Dt		= 0x00003000,	/* Rx: Data Type (field) */
-	De		= 0x00004000,	/* Rx: Descriptor Error */
-	Fl		= 0x3FFF0000,	/* Rx: Frame Length (field) */
-	Ff		= 0x40000000,	/* Rx: Filtering Fail */
-
-	Def		= 0x00000001,	/* Tx: DEFerred */
-	Uf		= 0x00000002,	/* Tx: UnderFlow error */
-	Lf		= 0x00000004,	/* Tx: Link Fail report */
-	Cc		= 0x00000078,	/* Tx: Collision Count (field) */
-	Hf		= 0x00000080,	/* Tx: Heartbeat Fail */
-	Ec		= 0x00000100,	/* Tx: Excessive Collisions */
-	Lc		= 0x00000200,	/* Tx: Late Collision */
-	Nc		= 0x00000400,	/* Tx: No Carrier */
-	Lo		= 0x00000800,	/* Tx: LOss of carrier */
-	To		= 0x00004000,	/* Tx: Transmission jabber timeOut */
-
-	Es		= 0x00008000,	/* [RT]x: Error Summary */
-	Own		= 0x80000000,	/* [RT]x: OWN bit */
-};
-
-enum {					/* control */
-	Bs1		= 0x000007FF,	/* [RT]x: Buffer 1 Size */
-	Bs2		= 0x003FF800,	/* [RT]x: Buffer 2 Size */
-
-	Ch		= 0x01000000,	/* [RT]x: second address CHained */
-	Er		= 0x02000000,	/* [RT]x: End of Ring */
-
-	Ft0		= 0x00400000,	/* Tx: Filtering Type 0 */
-	Dpd		= 0x00800000,	/* Tx: Disabled PaDding */
-	Ac		= 0x04000000,	/* Tx: Add CRC disable */
-	Set		= 0x08000000,	/* Tx: SETup packet */
-	Ft1		= 0x10000000,	/* Tx: Filtering Type 1 */
-	Fseg		= 0x20000000,	/* Tx: First SEGment */
-	Lseg		= 0x40000000,	/* Tx: Last SEGment */
-	Ic		= 0x80000000,	/* Tx: Interrupt on Completion */
-};
-
-enum {					/* PHY registers */
-	Bmcr		= 0,		/* Basic Mode Control */
-	Bmsr		= 1,		/* Basic Mode Status */
-	Phyidr1		= 2,		/* PHY Identifier #1 */
-	Phyidr2		= 3,		/* PHY Identifier #2 */
-	Anar		= 4,		/* Auto-Negotiation Advertisment */
-	Anlpar		= 5,		/* Auto-Negotiation Link Partner Ability */
-	Aner		= 6,		/* Auto-Negotiation Expansion */
-};
-
-enum {					/* Variants */
-	Tulip0		= (0x0009<<16)|0x1011,
-	Tulip1		= (0x0014<<16)|0x1011,
-	Tulip3		= (0x0019<<16)|0x1011,
-	Pnic		= (0x0002<<16)|0x11AD,
-	Pnic2		= (0xC115<<16)|0x11AD,
-	CentaurP	= (0x0985<<16)|0x1317,
-	CentaurPcb	= (0x1985<<16)|0x1317,
-};
-
-typedef struct Ctlr Ctlr;
-typedef struct Ctlr {
-	int	port;
-	Pcidev*	pcidev;
-	Ctlr*	next;
-	int	active;
-	int	id;			/* (pcidev->did<<16)|pcidev->vid */
-
-	uint8_t	*srom;
-	int	sromsz;
-	uint8_t*	sromea;			/* MAC address */
-	uint8_t*	leaf;
-	int	sct;			/* selected connection type */
-	int	k;			/* info block count */
-	uint8_t*	infoblock[16];
-	int	sctk;			/* sct block index */
-	int	curk;			/* current block index */
-	uint8_t*	type5block;
-
-	int	phy[32];		/* logical to physical map */
-	int	phyreset;		/* reset bitmap */
-	int	curphyad;
-	int	fdx;
-	int	ttm;
-
-	uint8_t	fd;			/* option */
-	int	medium;			/* option */
-
-	int	csr6;			/* CSR6 - operating mode */
-	int	mask;			/* CSR[57] - interrupt mask */
-	int	mbps;
-
-	Des*	rdr;			/* receive descriptor ring */
-	int	nrdr;			/* size of rdr */
-	int	rdrx;			/* index into rdr */
-
-	Des*	tdr;			/* transmit descriptor ring */
-	int	ntdr;			/* size of tdr */
-	int	tdrh;			/* host index into tdr */
-	int	tdri;			/* interface index into tdr */
-	int	ntq;			/* descriptors active */
-	Block*	setupbp;
-
-	uint32_t	of;			/* receive statistics */
-	uint32_t	ce;
-	uint32_t	cs;
-	uint32_t	tl;
-	uint32_t	rf;
-	uint32_t	de;
-
-	uint32_t	uf;			/* transmit statistics */
-	uint32_t	ec;
-	uint32_t	lc;
-	uint32_t	nc;
-	uint32_t	lo;
-	uint32_t	to;
-
-} Ctlr;
-
-static Ctlr* ctlrhead;
-static Ctlr* ctlrtail;
-
-#define csr32r(c, r)	(inl((c)->port+((r)*8)))
-#define csr32w(c, r, l)	(outl((c)->port+((r)*8), (uint32_t)(l)))
-
-static void
-attach(Ether* ether)
-{
-	Ctlr *ctlr;
-
-	ctlr = ether->ctlr;
-	if(!(ctlr->csr6 & Sr)){
-		ctlr->csr6 |= Sr;
-		csr32w(ctlr, 6, ctlr->csr6);
-	}
-}
-
-static void
-transmit(Ether* ether)
-{
-	Ctlr *ctlr;
-	Block *bp;
-	Des *des;
-	int control;
-	RingBuf *tb;
-
-	ctlr = ether->ctlr;
-	while(ctlr->ntq < (ctlr->ntdr-1)){
-		if(ctlr->setupbp){
-			bp = ctlr->setupbp;
-			ctlr->setupbp = 0;
-			control = Ic|Set|BLEN(bp);
-		}
-		else{
-			if(ether->ntb == 0)
-				break;
-			tb = &ether->tb[ether->ti];
-			if(tb->owner != Interface)
-				break;
-			bp = allocb(tb->len);
-			memmove(bp->wp, tb->pkt, tb->len);
-			memmove(bp->wp+Eaddrlen, ether->ea, Eaddrlen);
-			bp->wp += tb->len;
-
-			tb->owner = Host;
-			ether->ti = NEXT(ether->ti, ether->ntb);
-
-			control = Ic|Lseg|Fseg|BLEN(bp);
-		}
-
-		ctlr->tdr[PREV(ctlr->tdrh, ctlr->ntdr)].control &= ~Ic;
-		des = &ctlr->tdr[ctlr->tdrh];
-		des->bp = bp;
-		des->addr = PADDR(bp->rp);
-		des->control |= control;
-		ctlr->ntq++;
-		//coherence();
-		des->status = Own;
-		csr32w(ctlr, 1, 0);
-		ctlr->tdrh = NEXT(ctlr->tdrh, ctlr->ntdr);
-	}
-}
-
-static void
-interrupt(Ureg*, void* arg)
-{
-	Ctlr *ctlr;
-	Ether *ether;
-	int len, status;
-	Des *des;
-	RingBuf *ring;
-
-	ether = arg;
-	ctlr = ether->ctlr;
-
-	while((status = csr32r(ctlr, 5)) & (Nis|Ais)){
-		/*
-		 * Acknowledge the interrupts and mask-out
-		 * the ones that are implicitly handled.
-		 */
-		csr32w(ctlr, 5, status);
-		status &= (ctlr->mask & ~(Nis|Ais|Ti));
-
-		/*
-		 * Received packets.
-		 */
-		if(status & Ri){
-			des = &ctlr->rdr[ctlr->rdrx];
-			while((des->status & Own) == 0){
-				len = ((des->status & Fl)>>16)-4;
-				if(des->status & Es){
-					if(des->status & Of)
-						ctlr->of++;
-					if(des->status & Ce)
-						ctlr->ce++;
-					if(des->status & Cs)
-						ctlr->cs++;
-					if(des->status & Tl)
-						ctlr->tl++;
-					if(des->status & Rf)
-						ctlr->rf++;
-					if(des->status & De)
-						ctlr->de++;
-				}
-				else{
-					ring = &ether->rb[ether->ri];
-					if(ring->owner == Interface){
-						ring->owner = Host;
-						ring->len = len;
-						memmove(ring->pkt, des->bp, len);
-						ether->ri = NEXT(ether->ri, ether->nrb);
-					}
-				}
-
-				des->control &= Er;
-				des->control |= Rbsz;
-				des->status = Own;
-
-				ctlr->rdrx = NEXT(ctlr->rdrx, ctlr->nrdr);
-				des = &ctlr->rdr[ctlr->rdrx];
-			}
-			status &= ~Ri;
-		}
-
-		/*
-		 * Check the transmit side:
-		 *	check for Transmit Underflow and Adjust
-		 *	the threshold upwards;
-		 *	free any transmitted buffers and try to
-		 *	top-up the ring.
-		 */
-		if(status & Unf){
-			csr32w(ctlr, 6, ctlr->csr6 & ~St);
-			switch(ctlr->csr6 & Tr){
-			case Tr128:
-				len = Tr256;
-				break;
-			case Tr256:
-				len = Tr512;
-				break;
-			case Tr512:
-				len = Tr1024;
-				break;
-			default:
-			case Tr1024:
-				len = Sf;
-				break;
-			}
-			ctlr->csr6 = (ctlr->csr6 & ~Tr)|len;
-			csr32w(ctlr, 6, ctlr->csr6);
-			csr32w(ctlr, 5, Tps);
-			status &= ~(Unf|Tps);
-		}
-
-		while(ctlr->ntq){
-			des = &ctlr->tdr[ctlr->tdri];
-			if(des->status & Own)
-				break;
-
-			if(des->status & Es){
-				if(des->status & Uf)
-					ctlr->uf++;
-				if(des->status & Ec)
-					ctlr->ec++;
-				if(des->status & Lc)
-					ctlr->lc++;
-				if(des->status & Nc)
-					ctlr->nc++;
-				if(des->status & Lo)
-					ctlr->lo++;
-				if(des->status & To)
-					ctlr->to++;
-			}
-
-			freeb(des->bp);
-			des->control &= Er;
-
-			ctlr->ntq--;
-			ctlr->tdri = NEXT(ctlr->tdri, ctlr->ntdr);
-		}
-		transmit(ether);
-
-		/*
-		 * Anything left not catered for?
-		 */
-		if(status)
-			panic("#l%d: status %8.8uX\n", ether->ctlrno, status);
-	}
-}
-
-static void
-ctlrinit(Ether* ether)
-{
-	Ctlr *ctlr;
-	Des *des;
-	Block *bp;
-	int i;
-	uint8_t bi[Eaddrlen*2];
-
-	ctlr = ether->ctlr;
-
-	/*
-	 * Allocate and initialise the receive ring;
-	 * allocate and initialise the transmit ring;
-	 * unmask interrupts and start the transmit side;
-	 * create and post a setup packet to initialise
-	 * the physical ethernet address.
-	 */
-	ctlr->rdr = malloc(ctlr->nrdr*sizeof(Des));
-	for(des = ctlr->rdr; des < &ctlr->rdr[ctlr->nrdr]; des++){
-		des->bp = malloc(Rbsz);
-		des->status = Own;
-		des->control = Rbsz;
-		des->addr = PADDR(des->bp);
-	}
-	ctlr->rdr[ctlr->nrdr-1].control |= Er;
-	ctlr->rdrx = 0;
-	csr32w(ctlr, 3, PADDR(ctlr->rdr));
-
-	ctlr->tdr = ialloc(ctlr->ntdr*sizeof(Des), 32);
-	ctlr->tdr[ctlr->ntdr-1].control |= Er;
-	ctlr->tdrh = 0;
-	ctlr->tdri = 0;
-	csr32w(ctlr, 4, PADDR(ctlr->tdr));
-
-	/*
-	 * Clear any bits in the Status Register (CSR5) as
-	 * the PNIC has a different reset value from a true 2114x.
-	 */
-	ctlr->mask = Nis|Ais|Fbe|Rwt|Rps|Ru|Ri|Unf|Tjt|Tps|Ti;
-	csr32w(ctlr, 5, ctlr->mask);
-	csr32w(ctlr, 7, ctlr->mask);
-	ctlr->csr6 |= St;
-	csr32w(ctlr, 6, ctlr->csr6);
-
-	for(i = 0; i < Eaddrlen/2; i++){
-		bi[i*4] = ether->ea[i*2];
-		bi[i*4+1] = ether->ea[i*2+1];
-		bi[i*4+2] = ether->ea[i*2+1];
-		bi[i*4+3] = ether->ea[i*2];
-	}
-	bp = allocb(Eaddrlen*2*16);
-	memset(bp->rp, 0xFF, sizeof(bi));
-	for(i = sizeof(bi); i < sizeof(bi)*16; i += sizeof(bi))
-		memmove(bp->rp+i, bi, sizeof(bi));
-	bp->wp += sizeof(bi)*16;
-
-	ctlr->setupbp = bp;
-	transmit(ether);
-}
-
-static void
-csr9w(Ctlr* ctlr, int data)
-{
-	csr32w(ctlr, 9, data);
-	microdelay(1);
-}
-
-static int
-miimdi(Ctlr* ctlr, int n)
-{
-	int data, i;
-
-	/*
-	 * Read n bits from the MII Management Register.
-	 */
-	data = 0;
-	for(i = n-1; i >= 0; i--){
-		if(csr32r(ctlr, 9) & Mdi)
-			data |= (1<<i);
-		csr9w(ctlr, Mii|Mdc);
-		csr9w(ctlr, Mii);
-	}
-	csr9w(ctlr, 0);
-
-	return data;
-}
-
-static void
-miimdo(Ctlr* ctlr, int bits, int n)
-{
-	int i, mdo;
-
-	/*
-	 * Write n bits to the MII Management Register.
-	 */
-	for(i = n-1; i >= 0; i--){
-		if(bits & (1<<i))
-			mdo = Mdo;
-		else
-			mdo = 0;
-		csr9w(ctlr, mdo);
-		csr9w(ctlr, mdo|Mdc);
-		csr9w(ctlr, mdo);
-	}
-}
-
-static int
-miir(Ctlr* ctlr, int phyad, int regad)
-{
-	int data, i;
-
-	if(ctlr->id == Pnic){
-		i = 1000;
-		csr32w(ctlr, 20, 0x60020000|(phyad<<23)|(regad<<18));
-		do{
-			microdelay(1);
-			data = csr32r(ctlr, 20);
-		}while((data & 0x80000000) && --i);
-
-		if(i == 0)
-			return -1;
-		return data & 0xFFFF;
-	}
-
-	/*
-	 * Preamble;
-	 * ST+OP+PHYAD+REGAD;
-	 * TA + 16 data bits.
-	 */
-	miimdo(ctlr, 0xFFFFFFFF, 32);
-	miimdo(ctlr, 0x1800|(phyad<<5)|regad, 14);
-	data = miimdi(ctlr, 18);
-
-	if(data & 0x10000)
-		return -1;
-
-	return data & 0xFFFF;
-}
-
-static void
-miiw(Ctlr* ctlr, int phyad, int regad, int data)
-{
-	/*
-	 * Preamble;
-	 * ST+OP+PHYAD+REGAD+TA + 16 data bits;
-	 * Z.
-	 */
-	miimdo(ctlr, 0xFFFFFFFF, 32);
-	data &= 0xFFFF;
-	data |= (0x05<<(5+5+2+16))|(phyad<<(5+2+16))|(regad<<(2+16))|(0x02<<16);
-	miimdo(ctlr, data, 32);
-	csr9w(ctlr, Mdc);
-	csr9w(ctlr, 0);
-}
-
-static int
-sromr(Ctlr* ctlr, int r)
-{
-	int i, op, data, size;
-
-	if(ctlr->id == Pnic){
-		i = 1000;
-		csr32w(ctlr, 19, 0x600|r);
-		do{
-			microdelay(1);
-			data = csr32r(ctlr, 19);
-		}while((data & 0x80000000) && --i);
-
-		if(ctlr->sromsz == 0)
-			ctlr->sromsz = 6;
-
-		return csr32r(ctlr, 9) & 0xFFFF;
-	}
-
-	/*
-	 * This sequence for reading a 16-bit register 'r'
-	 * in the EEPROM is taken (pretty much) straight from Section
-	 * 7.4 of the 21140 Hardware Reference Manual.
-	 */
-reread:
-	csr9w(ctlr, Rd|Ss);
-	csr9w(ctlr, Rd|Ss|Scs);
-	csr9w(ctlr, Rd|Ss|Sclk|Scs);
-	csr9w(ctlr, Rd|Ss);
-
-	op = 0x06;
-	for(i = 3-1; i >= 0; i--){
-		data = Rd|Ss|(((op>>i) & 0x01)<<2)|Scs;
-		csr9w(ctlr, data);
-		csr9w(ctlr, data|Sclk);
-		csr9w(ctlr, data);
-	}
-
-	/*
-	 * First time through must work out the EEPROM size.
-	 * This doesn't seem to work on the 21041 as implemented
-	 * in Virtual PC for the Mac, so wire any 21041 to 6,
-	 * it's the only 21041 this code will ever likely see.
-	 */
-	if((size = ctlr->sromsz) == 0){
-		if(ctlr->id == Tulip1)
-			ctlr->sromsz = size = 6;
-		else
-			size = 8;
-	}
-
-	for(size = size-1; size >= 0; size--){
-		data = Rd|Ss|(((r>>size) & 0x01)<<2)|Scs;
-		csr9w(ctlr, data);
-		csr9w(ctlr, data|Sclk);
-		csr9w(ctlr, data);
-		microdelay(1);
-		if(ctlr->sromsz == 0 && !(csr32r(ctlr, 9) & Sdo))
-			break;
-	}
-
-	data = 0;
-	for(i = 16-1; i >= 0; i--){
-		csr9w(ctlr, Rd|Ss|Sclk|Scs);
-		if(csr32r(ctlr, 9) & Sdo)
-			data |= (1<<i);
-		csr9w(ctlr, Rd|Ss|Scs);
-	}
-
-	csr9w(ctlr, 0);
-
-	if(ctlr->sromsz == 0){
-		ctlr->sromsz = 8-size;
-		goto reread;
-	}
-
-	return data & 0xFFFF;
-}
-
-static void
-softreset(Ctlr* ctlr)
-{
-	/*
-	 * Soft-reset the controller and initialise bus mode.
-	 * Delay should be >= 50 PCI cycles (2×S @ 25MHz).
-	 */
-	csr32w(ctlr, 0, Swr);
-	microdelay(10);
-	csr32w(ctlr, 0, Rml|Cal16);
-	delay(1);
-}
-
-static int
-type5block(Ctlr* ctlr, uint8_t* block)
-{
-	int csr15, i, len;
-
-	/*
-	 * Reset or GPR sequence. Reset should be once only,
-	 * before the GPR sequence.
-	 * Note 'block' is not a pointer to the block head but
-	 * a pointer to the data in the block starting at the
-	 * reset length value so type5block can be used for the
-	 * sequences contained in type 1 and type 3 blocks.
-	 * The SROM docs state the 21140 type 5 block is the
-	 * same as that for the 21143, but the two controllers
-	 * use different registers and sequence-element lengths
-	 * so the 21140 code here is a guess for a real type 5
-	 * sequence.
-	 */
-	len = *block++;
-	if(ctlr->id != Tulip3){
-		for(i = 0; i < len; i++){
-			csr32w(ctlr, 12, *block);
-			block++;
-		}
-		return len;
-	}
-
-	for(i = 0; i < len; i++){
-		csr15 = *block++<<16;
-		csr15 |= *block++<<24;
-		csr32w(ctlr, 15, csr15);
-		debug("%8.8uX ", csr15);
-	}
-	return 2*len;
-}
-
-static int
-typephylink(Ctlr* ctlr, uint8_t*)
-{
-	int an, bmcr, bmsr, csr6, x;
-
-	/*
-	 * Fail if
-	 *	auto-negotiataion enabled but not complete;
-	 *	no valid link established.
-	 */
-	bmcr = miir(ctlr, ctlr->curphyad, Bmcr);
-	miir(ctlr, ctlr->curphyad, Bmsr);
-	bmsr = miir(ctlr, ctlr->curphyad, Bmsr);
-	debug("bmcr 0x%2.2uX bmsr 0x%2.2uX\n", bmcr, bmsr);
-	if(((bmcr & 0x1000) && !(bmsr & 0x0020)) || !(bmsr & 0x0004))
-		return 0;
-
-	if(bmcr & 0x1000){
-		an = miir(ctlr, ctlr->curphyad, Anar);
-		an &= miir(ctlr, ctlr->curphyad, Anlpar) & 0x3E0;
-		debug("an 0x%2.uX 0x%2.2uX 0x%2.2uX\n",
-	    		miir(ctlr, ctlr->curphyad, Anar),
-			miir(ctlr, ctlr->curphyad, Anlpar),
-			an);
-
-		if(an & 0x0100)
-			x = 0x4000;
-		else if(an & 0x0080)
-			x = 0x2000;
-		else if(an & 0x0040)
-			x = 0x1000;
-		else if(an & 0x0020)
-			x = 0x0800;
-		else
-			x = 0;
-	}
-	else if((bmcr & 0x2100) == 0x2100)
-		x = 0x4000;
-	else if(bmcr & 0x2000){
-		/*
-		 * If FD capable, force it if necessary.
-		 */
-		if((bmsr & 0x4000) && ctlr->fd){
-			miiw(ctlr, ctlr->curphyad, Bmcr, 0x2100);
-			x = 0x4000;
-		}
-		else
-			x = 0x2000;
-	}
-	else if(bmcr & 0x0100)
-		x = 0x1000;
-	else
-		x = 0x0800;
-
-	csr6 = Sc|Mbo|Hbd|Ps|Ca|TrMODE|Sb;
-	if(ctlr->fdx & x)
-		csr6 |= Fd;
-	if(ctlr->ttm & x)
-		csr6 |= Ttm;
-	debug("csr6 0x%8.8uX 0x%8.8uX 0x%8.8luX\n",
-		csr6, ctlr->csr6, csr32r(ctlr, 6));
-	if(csr6 != ctlr->csr6){
-		ctlr->csr6 = csr6;
-		csr32w(ctlr, 6, csr6);
-	}
-
-	return 1;
-}
-
-static int
-typephymode(Ctlr* ctlr, uint8_t* block, int wait)
-{
-	uint8_t *p;
-	int len, mc, nway, phyx, timeo;
-
-	if(DEBUG){
-		int i;
-
-		len = (block[0] & ~0x80)+1;
-		for(i = 0; i < len; i++)
-			debug("%2.2uX ", block[i]);
-		debug("\n");
-	}
-
-	if(block[1] == 1)
-		len = 1;
-	else if(block[1] == 3)
-		len = 2;
-	else
-		return -1;
-
-	/*
-	 * Snarf the media capabilities, nway advertisment,
-	 * FDX and TTM bitmaps.
-	 */
-	p = &block[5+len*block[3]+len*block[4+len*block[3]]];
-	mc = *p++;
-	mc |= *p++<<8;
-	nway = *p++;
-	nway |= *p++<<8;
-	ctlr->fdx = *p++;
-	ctlr->fdx |= *p++<<8;
-	ctlr->ttm = *p++;
-	ctlr->ttm |= *p<<8;
-	debug("mc %4.4uX nway %4.4uX fdx %4.4uX ttm %4.4uX\n",
-		mc, nway, ctlr->fdx, ctlr->ttm);
-	USED(mc);
-
-	phyx = block[2];
-	ctlr->curphyad = ctlr->phy[phyx];
-
-	ctlr->csr6 = 0;//Sc|Mbo|Hbd|Ps|Ca|TrMODE|Sb;
-	//csr32w(ctlr, 6, ctlr->csr6);
-	if(typephylink(ctlr, block))
-		return 0;
-
-	if(!(ctlr->phyreset & (1<<phyx))){
-		debug("reset seq: len %d: ", block[3]);
-		if(ctlr->type5block)
-			type5block(ctlr, &ctlr->type5block[2]);
-		else
-			type5block(ctlr, &block[4+len*block[3]]);
-		debug("\n");
-		ctlr->phyreset |= (1<<phyx);
-	}
-
-	/*
-	 * GPR sequence.
-	 */
-	debug("gpr seq: len %d: ", block[3]);
-	type5block(ctlr, &block[3]);
-	debug("\n");
-
-	ctlr->csr6 = 0;//Sc|Mbo|Hbd|Ps|Ca|TrMODE|Sb;
-	//csr32w(ctlr, 6, ctlr->csr6);
-	if(typephylink(ctlr, block))
-		return 0;
-
-	/*
-	 * Turn off auto-negotiation, set the auto-negotiation
-	 * advertisment register then start the auto-negotiation
-	 * process again.
-	 */
-	miiw(ctlr, ctlr->curphyad, Bmcr, 0);
-	miiw(ctlr, ctlr->curphyad, Anar, nway|1);
-	miiw(ctlr, ctlr->curphyad, Bmcr, 0x1000);
-
-	if(!wait)
-		return 0;
-
-	for(timeo = 0; timeo < 30; timeo++){
-		if(typephylink(ctlr, block))
-			return 0;
-		delay(100);
-	}
-
-	return -1;
-}
-
-static int
-typesymmode(Ctlr *ctlr, uint8_t *block, int wait)
-{
-	uint gpmode, gpdata, command;
-
-	USED(wait);
-	gpmode = block[3] | ((uint) block[4] << 8);
-	gpdata = block[5] | ((uint) block[6] << 8);
-	command = (block[7] | ((uint) block[8] << 8)) & 0x71;
-	if (command & 0x8000) {
-		print("ether2114x.c: FIXME: handle type 4 mode blocks where cmd.active_invalid != 0\n");
-		return -1;
-	}
-	csr32w(ctlr, 15, gpmode);
-	csr32w(ctlr, 15, gpdata);
-	ctlr->csr6 = (command & 0x71) << 18;
-	csr32w(ctlr, 6, ctlr->csr6);
-	return 0;
-}
-
-static int
-type2mode(Ctlr* ctlr, uint8_t* block, int)
-{
-	uint8_t *p;
-	int csr6, csr13, csr14, csr15, gpc, gpd;
-
-	csr6 = Sc|Mbo|Ca|TrMODE|Sb;
-	debug("type2mode: medium 0x%2.2uX\n", block[2]);
-
-	/*
-	 * Don't attempt full-duplex
-	 * unless explicitly requested.
-	 */
-	if((block[2] & 0x3F) == 0x04){	/* 10BASE-TFD */
-		if(!ctlr->fd)
-			return -1;
-		csr6 |= Fd;
-	}
-
-	/*
-	 * Operating mode programming values from the datasheet
-	 * unless media specific data is explicitly given.
-	 */
-	p = &block[3];
-	if(block[2] & 0x40){
-		csr13 = (block[4]<<8)|block[3];
-		csr14 = (block[6]<<8)|block[5];
-		csr15 = (block[8]<<8)|block[7];
-		p += 6;
-	}
-	else switch(block[2] & 0x3F){
-	default:
-		return -1;
-	case 0x00:			/* 10BASE-T */
-		csr13 = 0x00000001;
-		csr14 = 0x00007F3F;
-		csr15 = 0x00000008;
-		break;
-	case 0x01:			/* 10BASE-2 */
-		csr13 = 0x00000009;
-		csr14 = 0x00000705;
-		csr15 = 0x00000006;
-		break;
-	case 0x02:			/* 10BASE-5 (AUI) */
-		csr13 = 0x00000009;
-		csr14 = 0x00000705;
-		csr15 = 0x0000000E;
-		break;
-	case 0x04:			/* 10BASE-TFD */
-		csr13 = 0x00000001;
-		csr14 = 0x00007F3D;
-		csr15 = 0x00000008;
-		break;
-	}
-	gpc = *p++<<16;
-	gpc |= *p++<<24;
-	gpd = *p++<<16;
-	gpd |= *p<<24;
-
-	csr32w(ctlr, 13, 0);
-	csr32w(ctlr, 14, csr14);
-	csr32w(ctlr, 15, gpc|csr15);
-	delay(10);
-	csr32w(ctlr, 15, gpd|csr15);
-	csr32w(ctlr, 13, csr13);
-
-	ctlr->csr6 = csr6;
-	csr32w(ctlr, 6, ctlr->csr6);
-
-	debug("type2mode: csr13 %8.8uX csr14 %8.8uX csr15 %8.8uX\n",
-		csr13, csr14, csr15);
-	debug("type2mode: gpc %8.8uX gpd %8.8uX csr6 %8.8uX\n",
-		gpc, gpd, csr6);
-
-	return 0;
-}
-
-static int
-type0link(Ctlr* ctlr, uint8_t* block)
-{
-	int m, polarity, sense;
-
-	m = (block[3]<<8)|block[2];
-	sense = 1<<((m & 0x000E)>>1);
-	if(m & 0x0080)
-		polarity = sense;
-	else
-		polarity = 0;
-
-	return (csr32r(ctlr, 12) & sense)^polarity;
-}
-
-static int
-type0mode(Ctlr* ctlr, uint8_t* block, int wait)
-{
-	int csr6, m, timeo;
-
-	csr6 = Sc|Mbo|Hbd|Ca|TrMODE|Sb;
-debug("type0: medium 0x%uX, fd %d: 0x%2.2uX 0x%2.2uX 0x%2.2uX 0x%2.2uX\n",
-    ctlr->medium, ctlr->fd, block[0], block[1], block[2], block[3]);
-	switch(block[0]){
-	default:
-		break;
-
-	case 0x04:			/* 10BASE-TFD */
-	case 0x05:			/* 100BASE-TXFD */
-	case 0x08:			/* 100BASE-FXFD */
-		/*
-		 * Don't attempt full-duplex
-		 * unless explicitly requested.
-		 */
-		if(!ctlr->fd)
-			return -1;
-		csr6 |= Fd;
-		break;
-	}
-
-	m = (block[3]<<8)|block[2];
-	if(m & 0x0001)
-		csr6 |= Ps;
-	if(m & 0x0010)
-		csr6 |= Ttm;
-	if(m & 0x0020)
-		csr6 |= Pcs;
-	if(m & 0x0040)
-		csr6 |= Scr;
-
-	csr32w(ctlr, 12, block[1]);
-	microdelay(10);
-	csr32w(ctlr, 6, csr6);
-	ctlr->csr6 = csr6;
-
-	if(!wait)
-		return 0;
-
-	for(timeo = 0; timeo < 30; timeo++){
-		if(type0link(ctlr, block))
-			return 0;
-		delay(100);
-	}
-
-	return -1;
-}
-
-static int
-media21041(Ether* ether, int wait)
-{
-	Ctlr* ctlr;
-	uint8_t *block;
-	int csr6, csr13, csr14, csr15, medium, timeo;
-
-	ctlr = ether->ctlr;
-	block = ctlr->infoblock[ctlr->curk];
-	debug("media21041: block[0] %2.2uX, medium %4.4uX sct %4.4uX\n",
-		block[0], ctlr->medium, ctlr->sct);
-
-	medium = block[0] & 0x3F;
-	if(ctlr->medium >= 0 && medium != ctlr->medium)
-		return 0;
-	if(ctlr->sct != 0x0800 && (ctlr->sct & 0x3F) != medium)
-		return 0;
-
-	csr6 = Sc|Mbo|Ca|TrMODE|Sb;
-	if(block[0] & 0x40){
-		csr13 = (block[2]<<8)|block[1];
-		csr14 = (block[4]<<8)|block[3];
-		csr15 = (block[6]<<8)|block[5];
-	}
-	else switch(medium){
-	default:
-		return -1;
-	case 0x00:		/* 10BASE-T */
-		csr13 = 0xEF01;
-		csr14 = 0xFF3F;
-		csr15 = 0x0008;
-		break;
-	case 0x01:		/* 10BASE-2 */
-		csr13 = 0xEF09;
-		csr14 = 0xF73D;
-		csr15 = 0x0006;
-		break;
-	case 0x02:		/* 10BASE-5 */
-		csr13 = 0xEF09;
-		csr14 = 0xF73D;
-		csr15 = 0x000E;
-		break;
-	case 0x04:		/* 10BASE-TFD */
-		csr13 = 0xEF01;
-		csr14 = 0xFF3D;
-		csr15 = 0x0008;
-		break;
-	}
-
-	csr32w(ctlr, 13, 0);
-	csr32w(ctlr, 14, csr14);
-	csr32w(ctlr, 15, csr15);
-	csr32w(ctlr, 13, csr13);
-	delay(10);
-
-	if(medium == 0x04)
-		csr6 |= Fd;
-	ctlr->csr6 = csr6;
-	csr32w(ctlr, 6, ctlr->csr6);
-
-	debug("media21041: csr6 %8.8uX csr13 %4.4uX csr14 %4.4uX csr15 %4.4uX\n",
-		csr6, csr13, csr14, csr15);
-
-	if(!wait)
-		return 0;
-
-	for(timeo = 0; timeo < 30; timeo++){
-		if(!(csr32r(ctlr, 12) & 0x0002)){
-			debug("media21041: ok: csr12 %4.4luX timeo %d\n",
-				csr32r(ctlr, 12), timeo);
-			return 10;
-		}
-		delay(100);
-	}
-	debug("media21041: !ok: csr12 %4.4luX\n", csr32r(ctlr, 12));
-
-	return -1;
-}
-
-static int
-mediaxx(Ether* ether, int wait)
-{
-	Ctlr* ctlr;
-	uint8_t *block;
-
-	ctlr = ether->ctlr;
-	block = ctlr->infoblock[ctlr->curk];
-	if(block[0] & 0x80){
-		switch(block[1]){
-		default:
-			return -1;
-		case 0:
-			if(ctlr->medium >= 0 && block[2] != ctlr->medium)
-				return 0;
-/* need this test? */	if(ctlr->sct != 0x0800 && (ctlr->sct & 0x3F) != block[2])
-				return 0;
-			if(type0mode(ctlr, block+2, wait))
-				return 0;
-			break;
-		case 1:
-			if(typephymode(ctlr, block, wait))
-				return 0;
-			break;
-		case 2:
-			debug("type2: medium %d block[2] %d\n",
-				ctlr->medium, block[2]);
-			if(ctlr->medium >= 0 && ((block[2] & 0x3F) != ctlr->medium))
-				return 0;
-			if(type2mode(ctlr, block, wait))
-				return 0;
-			break;
-		case 3:
-			if(typephymode(ctlr, block, wait))
-				return 0;
-			break;
-		case 4:
-			debug("type4: medium %d block[2] %d\n",
-				ctlr->medium, block[2]);
-			if(ctlr->medium >= 0 && ((block[2] & 0x3F) != ctlr->medium))
-				return 0;
-			if(typesymmode(ctlr, block, wait))
-				return 0;
-			break;
-		}
-	}
-	else{
-		if(ctlr->medium >= 0 && block[0] != ctlr->medium)
-			return 0;
-/* need this test? */if(ctlr->sct != 0x0800 && (ctlr->sct & 0x3F) != block[0])
-			return 0;
-		if(type0mode(ctlr, block, wait))
-			return 0;
-	}
-
-	if(ctlr->csr6){
-		if(!(ctlr->csr6 & Ps) || (ctlr->csr6 & Ttm))
-			return 10;
-		return 100;
-	}
-
-	return 0;
-}
-
-static int
-media(Ether* ether, int wait)
-{
-	Ctlr* ctlr;
-	int k, mbps;
-
-	ctlr = ether->ctlr;
-	for(k = 0; k < ctlr->k; k++){
-		switch(ctlr->id){
-		default:
-			mbps = mediaxx(ether, wait);
-			break;
-		case Tulip1:			/* 21041 */
-			mbps = media21041(ether, wait);
-			break;
-		}
-		if(mbps > 0)
-			return mbps;
-		if(ctlr->curk == 0)
-			ctlr->curk = ctlr->k-1;
-		else
-			ctlr->curk--;
-	}
-
-	return 0;
-}
-
-static char* mediatable[9] = {
-	"10BASE-T",			/* TP */
-	"10BASE-2",			/* BNC */
-	"10BASE-5",			/* AUI */
-	"100BASE-TX",
-	"10BASE-TFD",
-	"100BASE-TXFD",
-	"100BASE-T4",
-	"100BASE-FX",
-	"100BASE-FXFD",
-};
-
-static uint8_t en1207[] = {		/* Accton EN1207-COMBO */
-	0x00, 0x00, 0xE8,		/* [0]  vendor ethernet code */
-	0x00,				/* [3]  spare */
-
-	0x00, 0x08,			/* [4]  connection (LSB+MSB = 0x0800) */
-	0x1F,				/* [6]  general purpose control */
-	2,				/* [7]  block count */
-
-	0x00,				/* [8]  media code (10BASE-TX) */
-	0x0B,				/* [9]  general purpose port data */
-	0x9E, 0x00,			/* [10] command (LSB+MSB = 0x009E) */
-
-	0x03,				/* [8]  media code (100BASE-TX) */
-	0x1B,				/* [9]  general purpose port data */
-	0x6D, 0x00,			/* [10] command (LSB+MSB = 0x006D) */
-
-					/* There is 10BASE-2 as well, but... */
-};
-
-static uint8_t ana6910fx[] = {		/* Adaptec (Cogent) ANA-6910FX */
-	0x00, 0x00, 0x92,		/* [0]  vendor ethernet code */
-	0x00,				/* [3]  spare */
-
-	0x00, 0x08,			/* [4]  connection (LSB+MSB = 0x0800) */
-	0x3F,				/* [6]  general purpose control */
-	1,				/* [7]  block count */
-
-	0x07,				/* [8]  media code (100BASE-FX) */
-	0x03,				/* [9]  general purpose port data */
-	0x2D, 0x00			/* [10] command (LSB+MSB = 0x000D) */
-};
-
-static uint8_t smc9332[] = {		/* SMC 9332 */
-	0x00, 0x00, 0xC0,		/* [0]  vendor ethernet code */
-	0x00,				/* [3]  spare */
-
-	0x00, 0x08,			/* [4]  connection (LSB+MSB = 0x0800) */
-	0x1F,				/* [6]  general purpose control */
-	2,				/* [7]  block count */
-
-	0x00,				/* [8]  media code (10BASE-TX) */
-	0x00,				/* [9]  general purpose port data */
-	0x9E, 0x00,			/* [10] command (LSB+MSB = 0x009E) */
-
-	0x03,				/* [8]  media code (100BASE-TX) */
-	0x09,				/* [9]  general purpose port data */
-	0x6D, 0x00,			/* [10] command (LSB+MSB = 0x006D) */
-};
-
-static uint8_t* leaf21140[] = {
-	en1207,				/* Accton EN1207-COMBO */
-	ana6910fx,			/* Adaptec (Cogent) ANA-6910FX */
-	smc9332,			/* SMC 9332 */
-	0,
-};
-
-/*
- * Copied to ctlr->srom at offset 20.
- */
-static uint8_t leafpnic[] = {
-	0x00, 0x00, 0x00, 0x00,		/* MAC address */
-	0x00, 0x00,
-	0x00,				/* controller 0 device number */
-	0x1E, 0x00,			/* controller 0 info leaf offset */
-	0x00,				/* reserved */
-	0x00, 0x08,			/* selected connection type */
-	0x00,				/* general purpose control */
-	0x01,				/* block count */
-
-	0x8C,				/* format indicator and count */
-	0x01,				/* block type */
-	0x00,				/* PHY number */
-	0x00,				/* GPR sequence length */
-	0x00,				/* reset sequence length */
-	0x00, 0x78,			/* media capabilities */
-	0xE0, 0x01,			/* Nway advertisment */
-	0x00, 0x50,			/* FDX bitmap */
-	0x00, 0x18,			/* TTM bitmap */
-};
-
-static int
-srom(Ctlr* ctlr)
-{
-	int i, k, oui, phy, x;
-	uint8_t *p;
-
-	/*
-	 * This is a partial decoding of the SROM format described in
-	 * 'Digital Semiconductor 21X4 Serial ROM Format, Version 4.05,
-	 * 2-Mar-98'. Only the 2114[03] are handled, support for other
-	 * controllers can be added as needed.
-	 */
-	sromr(ctlr, 0);
-	if(ctlr->srom == nil)
-		ctlr->srom = malloc((1<<ctlr->sromsz)*sizeof(ushort));
-	for(i = 0; i < (1<<ctlr->sromsz); i++){
-		x = sromr(ctlr, i);
-		ctlr->srom[2*i] = x;
-		ctlr->srom[2*i+1] = x>>8;
-	}
-
-	if(DEBUG){
-		print("srom:");
-		for(i = 0; i < ((1<<ctlr->sromsz)*sizeof(ushort)); i++){
-			if(i && ((i & 0x0F) == 0))
-				print("\n     ");
-			print(" %2.2uX", ctlr->srom[i]);
-		}
-		print("\n");
-	}
-
-	/*
-	 * There are 2 SROM layouts:
-	 *	e.g. Digital EtherWORKS	station address at offset 20;
-	 *				this complies with the 21140A SROM
-	 *				application note from Digital;
-	 * 	e.g. SMC9332		station address at offset 0 followed by
-	 *				2 additional bytes, repeated at offset
-	 *				6; the 8 bytes are also repeated in
-	 *				reverse order at offset 8.
-	 * To check which it is, read the SROM and check for the repeating
-	 * patterns of the non-compliant cards; if that fails use the one at
-	 * offset 20.
-	 */
-	ctlr->sromea = ctlr->srom;
-	for(i = 0; i < 8; i++){
-		x = ctlr->srom[i];
-		if(x != ctlr->srom[15-i] || x != ctlr->srom[16+i]){
-			ctlr->sromea = &ctlr->srom[20];
-			break;
-		}
-	}
-
-	/*
-	 * Fake up the SROM for the PNIC.
-	 * It looks like a 21140 with a PHY.
-	 * The MAC address is byte-swapped in the orginal SROM data.
-	 */
-	if(ctlr->id == Pnic){
-		memmove(&ctlr->srom[20], leafpnic, sizeof(leafpnic));
-		for(i = 0; i < Eaddrlen; i += 2){
-			ctlr->srom[20+i] = ctlr->srom[i+1];
-			ctlr->srom[20+i+1] = ctlr->srom[i];
-		}
-	}
-	if(ctlr->id == CentaurP || ctlr->id == CentaurPcb){
-		memmove(&ctlr->srom[20], leafpnic, sizeof(leafpnic));
-		for(i = 0; i < Eaddrlen; i += 2){
-			ctlr->srom[20+i] = ctlr->srom[8+i];
-			ctlr->srom[20+i+1] = ctlr->srom[8+i+1];
-		}
-	}
-
-	/*
-	 * Next, try to find the info leaf in the SROM for media detection.
-	 * If it's a non-conforming card try to match the vendor ethernet code
-	 * and point p at a fake info leaf with compact 21140 entries.
-	 */
-	if(ctlr->sromea == ctlr->srom){
-		p = nil;
-		for(i = 0; leaf21140[i] != nil; i++){
-			if(memcmp(leaf21140[i], ctlr->sromea, 3) == 0){
-				p = &leaf21140[i][4];
-				break;
-			}
-		}
-		if(p == nil)
-			return -1;
-	}
-	else
-		p = &ctlr->srom[(ctlr->srom[28]<<8)|ctlr->srom[27]];
-
-	/*
-	 * Set up the info needed for later media detection.
-	 * For the 21140, set the general-purpose mask in CSR12.
-	 * The info block entries are stored in order of increasing
-	 * precedence, so detection will work backwards through the
-	 * stored indexes into ctlr->srom.
-	 * If an entry is found which matches the selected connection
-	 * type, save the index. Otherwise, start at the last entry.
-	 * If any MII entries are found (type 1 and 3 blocks), scan
-	 * for PHYs.
-	 */
-	ctlr->leaf = p;
-	ctlr->sct = *p++;
-	ctlr->sct |= *p++<<8;
-	if(ctlr->id != Tulip3 && ctlr->id != Tulip1){
-		csr32w(ctlr, 12, Gpc|*p++);
-		delay(200);
-	}
-	ctlr->k = *p++;
-	if(ctlr->k >= nelem(ctlr->infoblock))
-		ctlr->k = nelem(ctlr->infoblock)-1;
-	ctlr->sctk = ctlr->k-1;
-	phy = 0;
-	for(k = 0; k < ctlr->k; k++){
-		ctlr->infoblock[k] = p;
-		if(ctlr->id == Tulip1){
-			debug("type21041: 0x%2.2uX\n", p[0]);
-			if(ctlr->sct != 0x0800 && *p == (ctlr->sct & 0xFF))
-				ctlr->sctk = k;
-			if(*p & 0x40)
-				p += 7;
-			else
-				p += 1;
-		}
-		/*
-		 * The RAMIX PMC665 has a badly-coded SROM,
-		 * hence the test for 21143 and type 3.
-		 */
-		else if((*p & 0x80) || (ctlr->id == Tulip3 && *(p+1) == 3)){
-			*p |= 0x80;
-			if(*(p+1) == 1 || *(p+1) == 3)
-				phy = 1;
-			if(*(p+1) == 5)
-				ctlr->type5block = p;
-			p += (*p & ~0x80)+1;
-		}
-		else{
-			debug("type0: 0x%2.2uX 0x%2.2uX 0x%2.2uX 0x%2.2uX\n",
-				p[0], p[1], p[2], p[3]);
-			if(ctlr->sct != 0x0800 && *p == (ctlr->sct & 0xFF))
-				ctlr->sctk = k;
-			p += 4;
-		}
-	}
-	ctlr->curk = ctlr->sctk;
-	debug("sct 0x%uX medium 0x%uX k %d curk %d phy %d\n",
-		ctlr->sct, ctlr->medium, ctlr->k, ctlr->curk, phy);
-
-	if(phy){
-		x = 0;
-		for(k = 0; k < nelem(ctlr->phy); k++){
-			if((ctlr->id == CentaurP || ctlr->id == CentaurPcb) && k != 1)
-				continue;
-			if((oui = miir(ctlr, k, 2)) == -1 || oui == 0)
-				continue;
-			if(DEBUG){
-				oui = (oui & 0x3FF)<<6;
-				oui |= miir(ctlr, k, 3)>>10;
-				miir(ctlr, k, 1);
-				debug("phy%d: index %d oui %uX reg1 %uX\n",
-					x, k, oui, miir(ctlr, k, 1));
-				USED(oui);
-			}
-			ctlr->phy[x] = k;
-		}
-	}
-
-	ctlr->fd = 0;
-	ctlr->medium = -1;
-
-	return 0;
-}
-
-static void
-dec2114xpci(void)
-{
-	Ctlr *ctlr;
-	Pcidev *p;
-	int x;
-
-	p = nil;
-	while(p = pcimatch(p, 0, 0)){
-		if(p->ccrb != 0x02 || p->ccru != 0)
-			continue;
-		switch((p->did<<16)|p->vid){
-		default:
-			continue;
-
-		case Tulip3:			/* 21143 */
-			/*
-			 * Exit sleep mode.
-			 */
-			x = pcicfgr32(p, 0x40);
-			x &= ~0xC0000000;
-			pcicfgw32(p, 0x40, x);
-			/*FALLTHROUGH*/
-
-		case Tulip0:			/* 21140 */
-		case Tulip1:			/* 21041 */
-		case Pnic:			/* PNIC */
-		case Pnic2:			/* PNIC-II */
-		case CentaurP:			/* ADMtek */
-		case CentaurPcb:		/* ADMtek CardBus */
-			break;
-		}
-
-		/*
-		 * bar[0] is the I/O port register address and
-		 * bar[1] is the memory-mapped register address.
-		 */
-		ctlr = malloc(sizeof(Ctlr));
-		ctlr->port = p->mem[0].bar & ~0x01;
-		ctlr->pcidev = p;
-		ctlr->id = (p->did<<16)|p->vid;
-		debug("2114x: type 0x%8.8uX rev 0x%4.4uX at port 0x%4.4uX\n",
-			ctlr->id, p->rid, ctlr->port);
-
-		/*
-		 * Some cards (e.g. ANA-6910FX) seem to need the Ps bit
-		 * set or they don't always work right after a hardware
-		 * reset.
-		 */
-		csr32w(ctlr, 6, Mbo|Ps);
-		softreset(ctlr);
-
-		if(srom(ctlr)){
-			free(ctlr);
-			break;
-		}
-
-		switch(ctlr->id){
-		default:
-			break;
-		case Pnic:			/* PNIC */
-			/*
-			 * Turn off the jabber timer.
-			 */
-			csr32w(ctlr, 15, 0x00000001);
-			break;
-		case CentaurP:
-		case CentaurPcb:
-			/*
-			 * Nice - the register offsets change from *8 to *4
-			 * for CSR16 and up...
-			 * CSR25/26 give the MAC address read from the SROM.
-			 * Don't really need to use this other than as a check,
-			 * the SROM will be read in anyway so the value there
-			 * can be used directly.
-			 */
-			debug("csr25 %8.8luX csr26 %8.8luX\n",
-				inl(ctlr->port+0xA4), inl(ctlr->port+0xA8));
-			debug("phyidr1 %4.4luX phyidr2 %4.4luX\n",
-				inl(ctlr->port+0xBC), inl(ctlr->port+0xC0));
-			break;
-		}
-
-		if(ctlrhead != nil)
-			ctlrtail->next = ctlr;
-		else
-			ctlrhead = ctlr;
-		ctlrtail = ctlr;
-	}
-}
-
-static void
-detach(Ether* ether)
-{
-	softreset(ether->ctlr);
-}
-
-int
-ether2114xreset(Ether* ether)
-{
-	Ctlr *ctlr;
-	int i, x;
-	uint8_t ea[Eaddrlen];
-	static int scandone;
-
-	if(scandone == 0){
-		dec2114xpci();
-		scandone = 1;
-	}
-
-	/*
-	 * Any adapter matches if no ether->port is supplied,
-	 * otherwise the ports must match.
-	 */
-	for(ctlr = ctlrhead; ctlr != nil; ctlr = ctlr->next){
-		if(ctlr->active)
-			continue;
-		if(ether->port == 0 || ether->port == ctlr->port){
-			ctlr->active = 1;
-			break;
-		}
-	}
-	if(ctlr == nil)
-		return -1;
-
-	ether->ctlr = ctlr;
-	ether->port = ctlr->port;
-	ether->irq = ctlr->pcidev->intl;
-	ether->tbdf = ctlr->pcidev->tbdf;
-
-	/*
-	 * Check if the adapter's station address is to be overridden.
-	 * If not, read it from the EEPROM and set in ether->ea prior to
-	 * loading the station address in the hardware.
-	 */
-	memset(ea, 0, Eaddrlen);
-	if(memcmp(ea, ether->ea, Eaddrlen) == 0)
-		memmove(ether->ea, ctlr->sromea, Eaddrlen);
-
-	/*
-	 * Look for a medium override in case there's no autonegotiation
-	 * (no MII) or the autonegotiation fails.
-	 */
-	for(i = 0; i < ether->nopt; i++){
-		if(cistrcmp(ether->opt[i], "FD") == 0){
-			ctlr->fd = 1;
-			continue;
-		}
-		for(x = 0; x < nelem(mediatable); x++){
-			debug("compare <%s> <%s>\n", mediatable[x],
-				ether->opt[i]);
-			if(cistrcmp(mediatable[x], ether->opt[i]))
-				continue;
-			ctlr->medium = x;
-
-			switch(ctlr->medium){
-			default:
-				ctlr->fd = 0;
-				break;
-
-			case 0x04:		/* 10BASE-TFD */
-			case 0x05:		/* 100BASE-TXFD */
-			case 0x08:		/* 100BASE-FXFD */
-				ctlr->fd = 1;
-				break;
-			}
-			break;
-		}
-	}
-
-	/*
-	 * Determine media.
-	 */
-	ctlr->mbps = media(ether, 1);
-
-	/*
-	 * Initialise descriptor rings, ethernet address.
-	 */
-	ctlr->nrdr = Nrde;
-	ctlr->ntdr = Ntde;
-	pcisetbme(ctlr->pcidev);
-	ctlrinit(ether);
-
-	/*
-	 * Linkage to the generic ethernet driver.
-	 */
-	ether->attach = attach;
-	ether->transmit = transmit;
-	ether->interrupt = interrupt;
-	ether->detach = detach;
-
-	return 0;
-}

+ 0 - 548
sys/src/9/w/pxeload/ether79c970.c

@@ -1,548 +0,0 @@
-/*
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
-
-/*
- * AMD79C970
- * PCnet-PCI Single-Chip Ethernet Controller for PCI Local Bus
- * To do:
- *	finish this rewrite
- */
-#include "u.h"
-#include "lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-
-#include "etherif.h"
-
-enum {
-	Lognrdre	= 6,
-	Nrdre		= (1<<Lognrdre),/* receive descriptor ring entries */
-	Logntdre	= 4,
-	Ntdre		= (1<<Logntdre),/* transmit descriptor ring entries */
-
-	Rbsize		= ETHERMAXTU+4,	/* ring buffer size (+4 for CRC) */
-};
-
-enum {					/* DWIO I/O resource map */
-	Aprom		= 0x0000,	/* physical address */
-	Rdp		= 0x0010,	/* register data port */
-	Rap		= 0x0014,	/* register address port */
-	Sreset		= 0x0018,	/* software reset */
-	Bdp		= 0x001C,	/* bus configuration register data port */
-};
-
-enum {					/* CSR0 */
-	Init		= 0x0001,	/* begin initialisation */
-	Strt		= 0x0002,	/* enable chip */
-	Stop		= 0x0004,	/* disable chip */
-	Tdmd		= 0x0008,	/* transmit demand */
-	Txon		= 0x0010,	/* transmitter on */
-	Rxon		= 0x0020,	/* receiver on */
-	Iena		= 0x0040,	/* interrupt enable */
-	Intr		= 0x0080,	/* interrupt flag */
-	Idon		= 0x0100,	/* initialisation done */
-	Tint		= 0x0200,	/* transmit interrupt */
-	Rint		= 0x0400,	/* receive interrupt */
-	Merr		= 0x0800,	/* memory error */
-	Miss		= 0x1000,	/* missed frame */
-	Cerr		= 0x2000,	/* collision */
-	Babl		= 0x4000,	/* transmitter timeout */
-	Err		= 0x8000,	/* Babl|Cerr|Miss|Merr */
-};
-
-enum {					/* CSR3 */
-	Bswp		= 0x0004,	/* byte swap */
-	Emba		= 0x0008,	/* enable modified back-off algorithm */
-	Dxmt2pd		= 0x0010,	/* disable transmit two part deferral */
-	Lappen		= 0x0020,	/* look-ahead packet processing enable */
-};
-
-enum {					/* CSR4 */
-	ApadXmt		= 0x0800,	/* auto pad transmit */
-};
-
-enum {					/* CSR15 */
-	Prom		= 0x8000,	/* promiscuous mode */
-};
-
-typedef struct {			/* Initialisation Block */
-	uint16_t	mode;
-	uint8_t	rlen;			/* upper 4 bits */
-	uint8_t	tlen;			/* upper 4 bits */
-	uint8_t	padr[6];
-	uint8_t	res[2];
-	uint8_t	ladr[8];
-	uint32_t	rdra;
-	uint32_t	tdra;
-} Iblock;
-
-typedef struct {			/* descriptor ring entry */
-	uint32_t	addr;
-	uint32_t	md1;			/* status|bcnt */
-	uint32_t	md2;			/* rcc|rpc|mcnt */
-	void*	data;
-} Dre;
-
-enum {					/* md1 */
-	Enp		= 0x01000000,	/* end of packet */
-	Stp		= 0x02000000,	/* start of packet */
-	RxBuff		= 0x04000000,	/* buffer error */
-	Def		= 0x04000000,	/* deferred */
-	Crc		= 0x08000000,	/* CRC error */
-	One		= 0x08000000,	/* one retry needed */
-	Oflo		= 0x10000000,	/* overflow error */
-	More		= 0x10000000,	/* more than one retry needed */
-	Fram		= 0x20000000,	/* framing error */
-	RxErr		= 0x40000000,	/* Fram|Oflo|Crc|RxBuff */
-	TxErr		= 0x40000000,	/* Uflo|Lcol|Lcar|Rtry */
-	Own		= 0x80000000,
-};
-
-enum {					/* md2 */
-	Rtry		= 0x04000000,	/* failed after repeated retries */
-	Lcar		= 0x08000000,	/* loss of carrier */
-	Lcol		= 0x10000000,	/* late collision */
-	Uflo		= 0x40000000,	/* underflow error */
-	TxBuff		= 0x80000000,	/* buffer error */
-};
-
-typedef struct Ctlr Ctlr;
-struct Ctlr {
-	Lock;
-	int	port;
-	Pcidev*	pcidev;
-	Ctlr*	next;
-	int	active;
-
-	int	init;			/* initialisation in progress */
-	Iblock	iblock;
-
-	Dre*	rdr;			/* receive descriptor ring */
-	int	rdrx;
-
-	Dre*	tdr;			/* transmit descriptor ring */
-	int	tdrh;			/* host index into tdr */
-	int	tdri;			/* interface index into tdr */
-	int	ntq;			/* descriptors active */
-
-	ulong	rxbuff;			/* receive statistics */
-	ulong	crc;
-	ulong	oflo;
-	ulong	fram;
-
-	ulong	rtry;			/* transmit statistics */
-	ulong	lcar;
-	ulong	lcol;
-	ulong	uflo;
-	ulong	txbuff;
-
-	ulong	merr;			/* bobf is such a whiner */
-	ulong	miss;
-	ulong	babl;
-
-	int		(*ior)(Ctlr*, int);
-	void		(*iow)(Ctlr*, int, int);
-};
-
-static Ctlr* ctlrhead;
-static Ctlr* ctlrtail;
-
-/*
- * The Rdp, Rap, Sreset, Bdp ports are 32-bit port offset in the enumeration above.
- * To get to 16-bit offsets, scale down with 0x10 staying the same.
- */
-static int
-io16r(Ctlr* c, int r)
-{
-	if(r >= Rdp)
-		r = (r-Rdp)/2+Rdp;
-	return ins(c->port+r);
-}
-
-static void
-io16w(Ctlr* c, int r, int v)
-{
-	if(r >= Rdp)
-		r = (r-Rdp)/2+Rdp;
-	outs(c->port+r, v);
-}
-
-static int
-io32r(Ctlr* c, int r)
-{
-	return inl(c->port+r);
-}
-
-static void
-io32w(Ctlr* c, int r, int v)
-{
-	outl(c->port+r, v);
-}
-
-static void
-attach(Ether*)
-{
-}
-
-static void
-detach(Ether* ether)
-{
-	Ctlr *ctlr;
-
-	ctlr = ether->ctlr;
-	ctlr->iow(ctlr, Rdp, Iena|Stop);
-}
-
-static void
-ringinit(Ctlr* ctlr)
-{
-	Dre *dre;
-
-	/*
-	 * Initialise the receive and transmit buffer rings.
-	 * The ring entries must be aligned on 16-byte boundaries.
-	 *
-	 * This routine is protected by ctlr->init.
-	 */
-	if(ctlr->rdr == 0){
-		ctlr->rdr = ialloc(Nrdre*sizeof(Dre), 0x10);
-		for(dre = ctlr->rdr; dre < &ctlr->rdr[Nrdre]; dre++){
-			dre->data = malloc(Rbsize);
-			dre->addr = PADDR(dre->data);
-			dre->md2 = 0;
-			dre->md1 = Own|(-Rbsize & 0xFFFF);
-		}
-	}
-	ctlr->rdrx = 0;
-
-	if(ctlr->tdr == 0)
-		ctlr->tdr = ialloc(Ntdre*sizeof(Dre), 0x10);
-	memset(ctlr->tdr, 0, Ntdre*sizeof(Dre));
-	ctlr->tdrh = ctlr->tdri = 0;
-}
-
-static void
-transmit(Ether* ether)
-{
-	Ctlr *ctlr;
-	Block *bp;
-	Dre *dre;
-	RingBuf *tb;
-
-	ctlr = ether->ctlr;
-
-	if(ctlr->init)
-		return;
-
-	while(ctlr->ntq < (Ntdre-1)){
-		tb = &ether->tb[ether->ti];
-		if(tb->owner != Interface)
-			break;
-
-		bp = allocb(tb->len);
-		memmove(bp->wp, tb->pkt, tb->len);
-		memmove(bp->wp+Eaddrlen, ether->ea, Eaddrlen);
-		bp->wp += tb->len;
-
-		/*
-		 * Give ownership of the descriptor to the chip,
-		 * increment the software ring descriptor pointer
-		 * and tell the chip to poll.
-		 * There's no need to pad to ETHERMINTU
-		 * here as ApadXmt is set in CSR4.
-		 */
-		dre = &ctlr->tdr[ctlr->tdrh];
-		dre->data = bp;
-		dre->addr = PADDR(bp->rp);
-		dre->md2 = 0;
-		dre->md1 = Own|Stp|Enp|Oflo|(-BLEN(bp) & 0xFFFF);
-		ctlr->ntq++;
-		ctlr->iow(ctlr, Rap, 0);
-		ctlr->iow(ctlr, Rdp, Iena|Tdmd);
-		ctlr->tdrh = NEXT(ctlr->tdrh, Ntdre);
-
-		tb->owner = Host;
-		ether->ti = NEXT(ether->ti, ether->ntb);
-	}
-}
-
-static void
-interrupt(Ureg*, void* arg)
-{
-	Ctlr *ctlr;
-	Ether *ether;
-	int csr0;
-	Dre *dre;
-	RingBuf *rb;
-
-	ether = arg;
-	ctlr = ether->ctlr;
-
-	/*
-	 * Acknowledge all interrupts and whine about those that shouldn't
-	 * happen.
-	 */
-intrloop:
-	csr0 = ctlr->ior(ctlr, Rdp) & 0xFFFF;
-	ctlr->iow(ctlr, Rdp, Babl|Cerr|Miss|Merr|Rint|Tint|Iena);
-	if(csr0 & Merr)
-		ctlr->merr++;
-	if(csr0 & Miss)
-		ctlr->miss++;
-	if(csr0 & Babl)
-		ctlr->babl++;
-	//if(csr0 & (Babl|Miss|Merr))
-	//	print("#l%d: csr0 = 0x%uX\n", ether->ctlrno, csr0);
-	if(!(csr0 & (Rint|Tint)))
-		return;
-
-	/*
-	 * Receiver interrupt: run round the descriptor ring logging
-	 * errors and passing valid receive data up to the higher levels
-	 * until a descriptor is encountered still owned by the chip.
-	 */
-	if(csr0 & Rint){
-		dre = &ctlr->rdr[ctlr->rdrx];
-		while(!(dre->md1 & Own)){
-			rb = &ether->rb[ether->ri];
-			if(dre->md1 & RxErr){
-				if(dre->md1 & RxBuff)
-					ctlr->rxbuff++;
-				if(dre->md1 & Crc)
-					ctlr->crc++;
-				if(dre->md1 & Oflo)
-					ctlr->oflo++;
-				if(dre->md1 & Fram)
-					ctlr->fram++;
-			}
-			else if(rb->owner == Interface){
-				rb->owner = Host;
-				rb->len = (dre->md2 & 0x0FFF)-4;
-				memmove(rb->pkt, dre->data, rb->len);
-				ether->ri = NEXT(ether->ri, ether->nrb);
-			}
-
-			/*
-			 * Finished with this descriptor, reinitialise it,
-			 * give it back to the chip, then on to the next...
-			 */
-			dre->md2 = 0;
-			dre->md1 = Own|(-Rbsize & 0xFFFF);
-
-			ctlr->rdrx = NEXT(ctlr->rdrx, Nrdre);
-			dre = &ctlr->rdr[ctlr->rdrx];
-		}
-	}
-
-	/*
-	 * Transmitter interrupt: wakeup anyone waiting for a free descriptor.
-	 */
-	if(csr0 & Tint){
-		lock(ctlr);
-		while(ctlr->ntq){
-			dre = &ctlr->tdr[ctlr->tdri];
-			if(dre->md1 & Own)
-				break;
-
-			if(dre->md1 & TxErr){
-				if(dre->md2 & Rtry)
-					ctlr->rtry++;
-				if(dre->md2 & Lcar)
-					ctlr->lcar++;
-				if(dre->md2 & Lcol)
-					ctlr->lcol++;
-				if(dre->md2 & Uflo)
-					ctlr->uflo++;
-				if(dre->md2 & TxBuff)
-					ctlr->txbuff++;
-			}
-
-			freeb(dre->data);
-
-			ctlr->ntq--;
-			ctlr->tdri = NEXT(ctlr->tdri, Ntdre);
-		}
-		transmit(ether);
-		unlock(ctlr);
-	}
-	goto intrloop;
-}
-
-static void
-amd79c970pci(void)
-{
-	Ctlr *ctlr;
-	Pcidev *p;
-
-	p = nil;
-	while(p = pcimatch(p, 0x1022, 0x2000)){
-		ctlr = malloc(sizeof(Ctlr));
-		ctlr->port = p->mem[0].bar & ~0x01;
-		ctlr->pcidev = p;
-
-		if(ctlrhead != nil)
-			ctlrtail->next = ctlr;
-		else
-			ctlrhead = ctlr;
-		ctlrtail = ctlr;
-	}
-}
-
-int
-amd79c970reset(Ether* ether)
-{
-	int x;
-	uint8_t ea[Eaddrlen];
-	Ctlr *ctlr;
-
-	if(ctlrhead == nil)
-		amd79c970pci();
-
-	/*
-	 * Any adapter matches if no port is supplied,
-	 * otherwise the ports must match.
-	 */
-	for(ctlr = ctlrhead; ctlr != nil; ctlr = ctlr->next){
-		if(ctlr->active)
-			continue;
-		if(ether->port == 0 || ether->port == ctlr->port){
-			ctlr->active = 1;
-			break;
-		}
-	}
-	if(ctlr == nil)
-		return -1;
-
-	/*
-	 * Allocate a controller structure and start to initialise it.
-	 */
-	ether->ctlr = ctlr;
-	ether->port = ctlr->port;
-	ether->irq = ctlr->pcidev->intl;
-	ether->tbdf = ctlr->pcidev->tbdf;
-	pcisetbme(ctlr->pcidev);
-	ilock(ctlr);
-	ctlr->init = 1;
-
-	io32r(ctlr, Sreset);
-	io16r(ctlr, Sreset);
-
-	if(io16w(ctlr, Rap, 0), io16r(ctlr, Rdp) == 4){
-		ctlr->ior = io16r;
-		ctlr->iow = io16w;
-	}else if(io32w(ctlr, Rap, 0), io32r(ctlr, Rdp) == 4){
-		ctlr->ior = io32r;
-		ctlr->iow = io32w;
-	}else{
-		print("#l%d: card doesn't talk right\n", ether->ctlrno);
-		iunlock(ctlr);
-		return -1;
-	}
-
-	ctlr->iow(ctlr, Rap, 88);
-	x = ctlr->ior(ctlr, Rdp);
-	ctlr->iow(ctlr, Rap, 89);
-	x |= ctlr->ior(ctlr, Rdp)<<16;
-
-	switch(x&0xFFFFFFF){
-	case 0x2420003:	/* PCnet/PCI 79C970 */
-	case 0x2621003:	/* PCnet/PCI II 79C970A */
-		break;
-	default:
-		print("unknown PCnet card version %.7ux\n", x&0xFFFFFFF);
-		iunlock(ctlr);
-		return -1;
-	}
-
-	/*
-	 * Set the software style in BCR20 to be PCnet-PCI to ensure 32-bit access.
-	 * Set the auto pad transmit in CSR4.
-	 */
-	ctlr->iow(ctlr, Rap, 20);
-	ctlr->iow(ctlr, Bdp, 0x0002);
-
-	ctlr->iow(ctlr, Rap, 4);
-	x = ctlr->ior(ctlr, Rdp) & 0xFFFF;
-	ctlr->iow(ctlr, Rdp, ApadXmt|x);
-
-	ctlr->iow(ctlr, Rap, 0);
-
-	/*
-	 * Check if the adapter's station address is to be overridden.
-	 * If not, read it from the I/O-space and set in ether->ea prior to
-	 * loading the station address in the initialisation block.
-	 */
-	memset(ea, 0, Eaddrlen);
-	if(!memcmp(ea, ether->ea, Eaddrlen)){
-		x = ctlr->ior(ctlr, Aprom);
-		ether->ea[0] = x;
-		ether->ea[1] = x>>8;
-		if(ctlr->ior == io16r)
-			x = ctlr->ior(ctlr, Aprom+2);
-		else
-			x >>= 16;
-		ether->ea[2] = x;
-		ether->ea[3] = x>>8;
-		x = ctlr->ior(ctlr, Aprom+4);
-		ether->ea[4] = x;
-		ether->ea[5] = x>>8;
-	}
-
-	/*
-	 * Start to fill in the initialisation block
-	 * (must be DWORD aligned).
-	 */
-	ctlr->iblock.rlen = Lognrdre<<4;
-	ctlr->iblock.tlen = Logntdre<<4;
-	memmove(ctlr->iblock.padr, ether->ea, sizeof(ctlr->iblock.padr));
-
-	ringinit(ctlr);
-	ctlr->iblock.rdra = PADDR(ctlr->rdr);
-	ctlr->iblock.tdra = PADDR(ctlr->tdr);
-
-	/*
-	 * Point the chip at the initialisation block and tell it to go.
-	 * Mask the Idon interrupt and poll for completion. Strt and interrupt
-	 * enables will be set later when attaching to the network.
-	 */
-	x = PADDR(&ctlr->iblock);
-	ctlr->iow(ctlr, Rap, 1);
-	ctlr->iow(ctlr, Rdp, x & 0xFFFF);
-	ctlr->iow(ctlr, Rap, 2);
-	ctlr->iow(ctlr, Rdp, (x>>16) & 0xFFFF);
-	ctlr->iow(ctlr, Rap, 3);
-	ctlr->iow(ctlr, Rdp, Idon);
-	ctlr->iow(ctlr, Rap, 0);
-	ctlr->iow(ctlr, Rdp, Init);
-
-	while(!(ctlr->ior(ctlr, Rdp) & Idon))
-		;
-
-	/*
-	 * We used to set CSR0 to Idon|Stop here, and then
-	 * in attach change it to Iena|Strt.  Apparently the simulated
-	 * 79C970 in VMware never enables after a write of Idon|Stop,
-	 * so we enable the device here now.
-	 */
-	ctlr->iow(ctlr, Rdp, Iena|Strt);
-	ctlr->init = 0;
-	iunlock(ctlr);
-
-	/*
-	 * Linkage to the generic ethernet driver.
-	 */
-	ether->attach = attach;
-	ether->transmit = transmit;
-	ether->interrupt = interrupt;
-	ether->detach = detach;
-
-	return 0;
-}

+ 0 - 623
sys/src/9/w/pxeload/ether8139.c

@@ -1,623 +0,0 @@
-/*
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
-
-/*
- * Realtek 8139 (but not the 8129).
- * Error recovery for the various over/under -flow conditions
- * may need work.
- */
-#include "u.h"
-#include "lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-
-#include "etherif.h"
-
-enum {					/* registers */
-	Idr0		= 0x0000,	/* MAC address */
-	Mar0		= 0x0008,	/* Multicast address */
-	Tsd0		= 0x0010,	/* Transmit Status Descriptor0 */
-	Tsad0		= 0x0020,	/* Transmit Start Address Descriptor0 */
-	Rbstart		= 0x0030,	/* Receive Buffer Start Address */
-	Erbcr		= 0x0034,	/* Early Receive Byte Count */
-	Ersr		= 0x0036,	/* Early Receive Status */
-	Cr		= 0x0037,	/* Command Register */
-	Capr		= 0x0038,	/* Current Address of Packet Read */
-	Cbr		= 0x003A,	/* Current Buffer Address */
-	Imr		= 0x003C,	/* Interrupt Mask */
-	Isr		= 0x003E,	/* Interrupt Status */
-	Tcr		= 0x0040,	/* Transmit Configuration */
-	Rcr		= 0x0044,	/* Receive Configuration */
-	Tctr		= 0x0048,	/* Timer Count */
-	Mpc		= 0x004C,	/* Missed Packet Counter */
-	Cr9346		= 0x0050,	/* 9346 Command Register */
-	Config0		= 0x0051,	/* Configuration Register 0 */
-	Config1		= 0x0052,	/* Configuration Register 1 */
-	TimerInt	= 0x0054,	/* Timer Interrupt */
-	Msr		= 0x0058,	/* Media Status */
-	Config3		= 0x0059,	/* Configuration Register 3 */
-	Config4		= 0x005A,	/* Configuration Register 4 */
-	Mulint		= 0x005C,	/* Multiple Interrupt Select */
-	RerID		= 0x005E,	/* PCI Revision ID */
-	Tsad		= 0x0060,	/* Transmit Status of all Descriptors */
-
-	Bmcr		= 0x0062,	/* Basic Mode Control */
-	Bmsr		= 0x0064,	/* Basic Mode Status */
-	Anar		= 0x0066,	/* Auto-Negotiation Advertisment */
-	Anlpar		= 0x0068,	/* Auto-Negotiation Link Partner */
-	Aner		= 0x006A,	/* Auto-Negotiation Expansion */
-	Dis		= 0x006C,	/* Disconnect Counter */
-	Fcsc		= 0x006E,	/* False Carrier Sense Counter */
-	Nwaytr		= 0x0070,	/* N-way Test */
-	Rec		= 0x0072,	/* RX_ER Counter */
-	Cscr		= 0x0074,	/* CS Configuration */
-	Phy1parm	= 0x0078,	/* PHY Parameter 1 */
-	Twparm		= 0x007C,	/* Twister Parameter */
-	Phy2parm	= 0x0080,	/* PHY Parameter 2 */
-};
-
-enum {					/* Cr */
-	Bufe		= 0x01,		/* Rx Buffer Empty */
-	Te		= 0x04,		/* Transmitter Enable */
-	Re		= 0x08,		/* Receiver Enable */
-	Rst		= 0x10,		/* Software Reset */
-};
-
-enum {					/* Imr/Isr */
-	Rok		= 0x0001,	/* Receive OK */
-	Rer		= 0x0002,	/* Receive Error */
-	Tok		= 0x0004,	/* Transmit OK */
-	Ter		= 0x0008,	/* Transmit Error */
-	Rxovw		= 0x0010,	/* Receive Buffer Overflow */
-	PunLc		= 0x0020,	/* Packet Underrun or Link Change */
-	Fovw		= 0x0040,	/* Receive FIFO Overflow */
-	Clc		= 0x2000,	/* Cable Length Change */
-	Timer		= 0x4000,	/* Timer */
-	Serr		= 0x8000,	/* System Error */
-};
-
-enum {					/* Tcr */
-	Clrabt		= 0x00000001,	/* Clear Abort */
-	TxrrSHIFT	= 4,		/* Transmit Retry Count */
-	TxrrMASK	= 0x000000F0,
-	MtxdmaSHIFT	= 8,		/* Max. DMA Burst Size */
-	MtxdmaMASK	= 0x00000700,
-	Mtxdma2048	= 0x00000700,
-	Acrc		= 0x00010000,	/* Append CRC (not) */
-	LbkSHIFT	= 17,		/* Loopback Test */
-	LbkMASK		= 0x00060000,
-	IfgSHIFT	= 24,		/* Interframe Gap */
-	IfgMASK		= 0x03000000,
-	HwveridSHIFT	= 22,		/* Hardware Version ID */
-	HwveridMASK	= 0x7CC00000,
-};
-
-enum {					/* Rcr */
-	Aap		= 0x00000001,	/* Accept All Packets */
-	Apm		= 0x00000002,	/* Accept Physical Match */
-	Am		= 0x00000004,	/* Accept Multicast */
-	Ab		= 0x00000008,	/* Accept Broadcast */
-	Ar		= 0x00000010,	/* Accept Runt */
-	Aer		= 0x00000020,	/* Accept Error */
-	Sel9356		= 0x00000040,	/* 9356 EEPROM used */
-	Wrap		= 0x00000080,	/* Rx Buffer Wrap Control */
-	MrxdmaSHIFT	= 8,		/* Max. DMA Burst Size */
-	MrxdmaMASK	= 0x00000700,
-	Mrxdmaunlimited	= 0x00000700,
-	RblenSHIFT	= 11,		/* Receive Buffer Length */
-	RblenMASK	= 0x00001800,
-	Rblen8K		= 0x00000000,	/* 8KB+16 */
-	Rblen16K	= 0x00000800,	/* 16KB+16 */
-	Rblen32K	= 0x00001000,	/* 32KB+16 */
-	Rblen64K	= 0x00001800,	/* 64KB+16 */
-	RxfthSHIFT	= 13,		/* Receive Buffer Length */
-	RxfthMASK	= 0x0000E000,
-	Rxfth256	= 0x00008000,
-	Rxfthnone	= 0x0000E000,
-	Rer8		= 0x00010000,	/* Accept Error Packets > 8 bytes */
-	MulERINT	= 0x00020000,	/* Multiple Early Interrupt Select */
-	ErxthSHIFT	= 24,		/* Early Rx Threshold */
-	ErxthMASK	= 0x0F000000,
-	Erxthnone	= 0x00000000,
-};
-
-enum {					/* Received Packet Status */
-	Rcok		= 0x0001,	/* Receive Completed OK */
-	Fae		= 0x0002,	/* Frame Alignment Error */
-	Crc		= 0x0004,	/* CRC Error */
-	Long		= 0x0008,	/* Long Packet */
-	Runt		= 0x0010,	/* Runt Packet Received */
-	Ise		= 0x0020,	/* Invalid Symbol Error */
-	Bar		= 0x2000,	/* Broadcast Address Received */
-	Pam		= 0x4000,	/* Physical Address Matched */
-	Mar		= 0x8000,	/* Multicast Address Received */
-};
-
-enum {					/* Media Status Register */
-	Rxpf		= 0x01,		/* Pause Flag */
-	Txpf		= 0x02,		/* Pause Flag */
-	Linkb		= 0x04,		/* Inverse of Link Status */
-	Speed10		= 0x08,		/* 10Mbps */
-	Auxstatus	= 0x10,		/* Aux. Power Present Status */
-	Rxfce		= 0x40,		/* Receive Flow Control Enable */
-	Txfce		= 0x80,		/* Transmit Flow Control Enable */
-};
-
-typedef struct {			/* Soft Transmit Descriptor */
-	int	tsd;
-	int	tsad;
-	uint8_t*	data;
-} Td;
-
-enum {					/* Tsd0 */
-	SizeSHIFT	= 0,		/* Descriptor Size */
-	SizeMASK	= 0x00001FFF,
-	Own		= 0x00002000,
-	Tun		= 0x00004000,	/* Transmit FIFO Underrun */
-	Tcok		= 0x00008000,	/* Transmit COmpleted OK */
-	EtxthSHIFT	= 16,		/* Early Tx Threshold */
-	EtxthMASK	= 0x001F0000,
-	NccSHIFT	= 24,		/* Number of Collisions Count */
-	NccMASK		= 0x0F000000,
-	Cdh		= 0x10000000,	/* CD Heartbeat */
-	Owc		= 0x20000000,	/* Out of Window Collision */
-	Tabt		= 0x40000000,	/* Transmit Abort */
-	Crs		= 0x80000000,	/* Carrier Sense Lost */
-};
-
-enum {
-	Rblen		= Rblen64K,	/* Receive Buffer Length */
-	Ntd		= 4,		/* Number of Transmit Descriptors */
-	Tdbsz		= ROUNDUP(sizeof(Etherpkt), 4),
-};
-
-typedef struct Ctlr Ctlr;
-typedef struct Ctlr {
-	int	port;
-	Pcidev*	pcidev;
-	Ctlr*	next;
-	int	active;
-	int	id;
-
-	Lock	ilock;			/* init */
-	void*	alloc;			/* base of per-Ctlr allocated data */
-
-	int	rcr;			/* receive configuration register */
-	uint8_t*	rbstart;		/* receive buffer */
-	int	rblen;			/* receive buffer length */
-	int	ierrs;			/* receive errors */
-
-	Lock	tlock;			/* transmit */
-	Td	td[Ntd];
-	int	ntd;			/* descriptors active */
-	int	tdh;			/* host index into td */
-	int	tdi;			/* interface index into td */
-	int	etxth;			/* early transmit threshold */
-	int	taligned;		/* packet required no alignment */
-	int	tunaligned;		/* packet required alignment */
-
-	int	dis;			/* disconnect counter */
-	int	fcsc;			/* false carrier sense counter */
-	int	rec;			/* RX_ER counter */
-} Ctlr;
-
-static Ctlr* ctlrhead;
-static Ctlr* ctlrtail;
-
-#define csr8r(c, r)	(inb((c)->port+(r)))
-#define csr16r(c, r)	(ins((c)->port+(r)))
-#define csr32r(c, r)	(inl((c)->port+(r)))
-#define csr8w(c, r, b)	(outb((c)->port+(r), (int)(b)))
-#define csr16w(c, r, w)	(outs((c)->port+(r), (ushort)(w)))
-#define csr32w(c, r, l)	(outl((c)->port+(r), (ulong)(l)))
-
-static int
-rtl8139reset(Ctlr* ctlr)
-{
-	/*
-	 * Soft reset the controller.
-	 */
-	csr8w(ctlr, Cr, Rst);
-	while(csr8r(ctlr, Cr) & Rst)
-		;
-
-	return 0;
-}
-
-static void
-rtl8139detach(Ether* edev)
-{
-	rtl8139reset(edev->ctlr);
-}
-
-static void
-rtl8139halt(Ctlr* ctlr)
-{
-	csr8w(ctlr, Cr, 0);
-	csr16w(ctlr, Imr, 0);
-	csr16w(ctlr, Isr, ~0);
-}
-
-static void
-rtl8139init(Ether* edev)
-{
-	int i;
-	uint32_t r;
-	Ctlr *ctlr;
-	uint8_t *alloc;
-
-	ctlr = edev->ctlr;
-	ilock(&ctlr->ilock);
-
-	rtl8139halt(ctlr);
-
-	/*
-	 * MAC Address.
-	 */
-	r = (edev->ea[3]<<24)|(edev->ea[2]<<16)|(edev->ea[1]<<8)|edev->ea[0];
-	csr32w(ctlr, Idr0, r);
-	r = (edev->ea[5]<<8)|edev->ea[4];
-	csr32w(ctlr, Idr0+4, r);
-
-	/*
-	 * Receiver
-	 */
-	alloc = (uint8_t*)ROUNDUP((uint32_t)ctlr->alloc, 32);
-	ctlr->rbstart = alloc;
-	alloc += ctlr->rblen+16;
-	memset(ctlr->rbstart, 0, ctlr->rblen+16);
-	csr32w(ctlr, Rbstart, PADDR(ctlr->rbstart));
-	ctlr->rcr = Rxfth256|Rblen|Mrxdmaunlimited|Ab|Apm;
-
-	/*
-	 * Transmitter.
-	 */
-	for(i = 0; i < Ntd; i++){
-		ctlr->td[i].tsd = Tsd0+i*4;
-		ctlr->td[i].tsad = Tsad0+i*4;
-		ctlr->td[i].data = alloc;
-		alloc += Tdbsz;
-	}
-	ctlr->ntd = ctlr->tdh = ctlr->tdi = 0;
-	ctlr->etxth = 128/32;
-
-	/*
-	 * Interrupts.
-	 */
-	csr32w(ctlr, TimerInt, 0);
-	csr16w(ctlr, Imr, Serr|Timer|Fovw|PunLc|Rxovw|Ter|Tok|Rer|Rok);
-	csr32w(ctlr, Mpc, 0);
-
-	/*
-	 * Enable receiver/transmitter.
-	 * Need to enable before writing the Rcr or it won't take.
-	 */
-	csr8w(ctlr, Cr, Te|Re);
-	csr32w(ctlr, Tcr, Mtxdma2048);
-	csr32w(ctlr, Rcr, ctlr->rcr);
-
-	iunlock(&ctlr->ilock);
-}
-
-static void
-rtl8139attach(Ether* edev)
-{
-	Ctlr *ctlr;
-
-	ctlr = edev->ctlr;
-	if(ctlr->alloc == nil){
-		ctlr->rblen = 1<<((Rblen>>RblenSHIFT)+13);
-		ctlr->alloc = mallocz(ctlr->rblen+16 + Ntd*Tdbsz + 32, 0);
-		rtl8139init(edev);
-	}
-}
-
-static void
-rtl8139txstart(Ether* edev)
-{
-	Td *td;
-	Ctlr *ctlr;
-	RingBuf *tb;
-
-	ctlr = edev->ctlr;
-	while(ctlr->ntd < Ntd){
-		tb = &edev->tb[edev->ti];
-		if(tb->owner != Interface)
-			break;
-
-		td = &ctlr->td[ctlr->tdh];
-		memmove(td->data, tb->pkt, tb->len);
-		csr32w(ctlr, td->tsad, PADDR(tb->pkt));
-		csr32w(ctlr, td->tsd, (ctlr->etxth<<EtxthSHIFT)|tb->len);
-
-		ctlr->ntd++;
-		ctlr->tdh = NEXT(ctlr->tdh, Ntd);
-		tb->owner = Host;
-		edev->ti = NEXT(edev->ti, edev->ntb);
-	}
-}
-
-static void
-rtl8139transmit(Ether* edev)
-{
-	Ctlr *ctlr;
-
-	ctlr = edev->ctlr;
-	ilock(&ctlr->tlock);
-	rtl8139txstart(edev);
-	iunlock(&ctlr->tlock);
-}
-
-static void
-rtl8139receive(Ether* edev)
-{
-	Ctlr *ctlr;
-	RingBuf *rb;
-	uint16_t capr;
-	uint8_t cr, *p;
-	int l, length, status;
-
-	ctlr = edev->ctlr;
-
-	/*
-	 * Capr is where the host is reading from,
-	 * Cbr is where the NIC is currently writing.
-	 */
-	capr = (csr16r(ctlr, Capr)+16) % ctlr->rblen;
-	while(!(csr8r(ctlr, Cr) & Bufe)){
-		p = ctlr->rbstart+capr;
-
-		/*
-		 * Apparently the packet length may be 0xFFF0 if
-		 * the NIC is still copying the packet into memory.
-		 */
-		length = (*(p+3)<<8)|*(p+2);
-		if(length == 0xFFF0)
-			break;
-		status = (*(p+1)<<8)|*p;
-
-		if(!(status & Rcok)){
-			/*
-			 * Reset the receiver.
-			 * Also may have to restore the multicast list
-			 * here too if it ever gets used.
-			 */
-			cr = csr8r(ctlr, Cr);
-			csr8w(ctlr, Cr, cr & ~Re);
-			csr32w(ctlr, Rbstart, PADDR(ctlr->rbstart));
-			csr8w(ctlr, Cr, cr);
-			csr32w(ctlr, Rcr, ctlr->rcr);
-
-			continue;
-		}
-
-		/*
-		 * Receive Completed OK.
-		 * Very simplistic; there are ways this could be done
-		 * without copying, but the juice probably isn't worth
-		 * the squeeze.
-		 * The packet length includes a 4 byte CRC on the end.
-		 */
-		capr = (capr+4) % ctlr->rblen;
-		p = ctlr->rbstart+capr;
-		capr = (capr+length) % ctlr->rblen;
-
-		rb = &edev->rb[edev->ri];
-		l = 0;
-		if(p+length >= ctlr->rbstart+ctlr->rblen){
-			l = ctlr->rbstart+ctlr->rblen - p;
-			if(rb->owner == Interface)
-				memmove(rb->pkt, p, l);
-			length -= l;
-			p = ctlr->rbstart;
-		}
-		if(length > 0 && rb->owner == Interface){
-			memmove(rb->pkt+l, p, length);
-			l += length;
-		}
-		if(rb->owner == Interface){
-			rb->owner = Host;
-			rb->len = l-4;
-			edev->ri = NEXT(edev->ri, edev->nrb);
-		}
-
-		capr = ROUNDUP(capr, 4);
-		csr16w(ctlr, Capr, capr-16);
-	}
-}
-
-static void
-rtl8139interrupt(Ureg*, void* arg)
-{
-	Td *td;
-	Ctlr *ctlr;
-	Ether *edev;
-	int isr, tsd;
-
-	edev = arg;
-	ctlr = edev->ctlr;
-
-	while((isr = csr16r(ctlr, Isr)) != 0){
-		csr16w(ctlr, Isr, isr);
-		if(isr & (Fovw|PunLc|Rxovw|Rer|Rok)){
-			rtl8139receive(edev);
-			if(!(isr & Rok))
-				ctlr->ierrs++;
-			isr &= ~(Fovw|Rxovw|Rer|Rok);
-		}
-
-		if(isr & (Ter|Tok)){
-			ilock(&ctlr->tlock);
-			while(ctlr->ntd){
-				td = &ctlr->td[ctlr->tdi];
-				tsd = csr32r(ctlr, td->tsd);
-				if(!(tsd & (Tabt|Tun|Tcok)))
-					break;
-
-				if(!(tsd & Tcok)){
-					if(tsd & Tun){
-						if(ctlr->etxth < ETHERMAXTU/32)
-							ctlr->etxth++;
-					}
-				}
-
-				ctlr->ntd--;
-				ctlr->tdi = NEXT(ctlr->tdi, Ntd);
-			}
-			rtl8139txstart(edev);
-			iunlock(&ctlr->tlock);
-			isr &= ~(Ter|Tok);
-		}
-
-		if(isr & PunLc)
-			isr &= ~(Clc|PunLc);
-
-		/*
-		 * Only Serr|Timer should be left by now.
-		 * Should anything be done to tidy up? TimerInt isn't
-		 * used so that can be cleared. A PCI bus error is indicated
-		 * by Serr, that's pretty serious; is there anyhing to do
-		 * other than try to reinitialise the chip?
-		 */
-		if((isr & (Serr|Timer)) != 0){
-			print("rtl8139interrupt: imr %4.4uX isr %4.4uX\n",
-				csr16r(ctlr, Imr), isr);
-			if(isr & Timer)
-				csr32w(ctlr, TimerInt, 0);
-			if(isr & Serr)
-				rtl8139init(edev);
-		}
-	}
-}
-
-static Ctlr*
-rtl8139match(Ether* edev, int id)
-{
-	int port;
-	Pcidev *p;
-	Ctlr *ctlr;
-
-	/*
-	 * Any adapter matches if no edev->port is supplied,
-	 * otherwise the ports must match.
-	 */
-	for(ctlr = ctlrhead; ctlr != nil; ctlr = ctlr->next){
-		if(ctlr->active)
-			continue;
-		p = ctlr->pcidev;
-		if(((p->did<<16)|p->vid) != id)
-			continue;
-		port = p->mem[0].bar & ~0x01;
-		if(edev->port != 0 && edev->port != port)
-			continue;
-
-		ctlr->port = port;
-		if(rtl8139reset(ctlr))
-			continue;
-		pcisetbme(p);
-
-		ctlr->active = 1;
-		return ctlr;
-	}
-	return nil;
-}
-
-static struct {
-	char*	name;
-	int	id;
-} rtl8139pci[] = {
-	{ "rtl8139",	(0x8139<<16)|0x10EC, },	/* generic */
-	{ "smc1211",	(0x1211<<16)|0x1113, },	/* SMC EZ-Card */
-	{ "dfe-538tx",	(0x1300<<16)|0x1186, }, /* D-Link DFE-538TX */
-	{ "dfe-560txd",	(0x1340<<16)|0x1186, }, /* D-Link DFE-560TXD */
-	{ nil },
-};
-
-int
-rtl8139pnp(Ether* edev)
-{
-	int i, id;
-	Pcidev *p;
-	Ctlr *ctlr;
-	uint8_t ea[Eaddrlen];
-
-	/*
-	 * Make a list of all ethernet controllers
-	 * if not already done.
-	 */
-	if(ctlrhead == nil){
-		p = nil;
-		while(p = pcimatch(p, 0, 0)){
-			if(p->ccrb != 0x02 || p->ccru != 0)
-				continue;
-			ctlr = malloc(sizeof(Ctlr));
-			ctlr->pcidev = p;
-			ctlr->id = (p->did<<16)|p->vid;
-
-			if(ctlrhead != nil)
-				ctlrtail->next = ctlr;
-			else
-				ctlrhead = ctlr;
-			ctlrtail = ctlr;
-		}
-	}
-
-	/*
-	 * Is it an RTL8139 under a different name?
-	 * Normally a search is made through all the found controllers
-	 * for one which matches any of the known vid+did pairs.
-	 * If a vid+did pair is specified a search is made for that
-	 * specific controller only.
-	 */
-	id = 0;
-	for(i = 0; i < edev->nopt; i++){
-		if(cistrncmp(edev->opt[i], "id=", 3) == 0)
-			id = strtol(&edev->opt[i][3], nil, 0);
-	}
-
-	ctlr = nil;
-	if(id != 0)
-		ctlr = rtl8139match(edev, id);
-	else for(i = 0; rtl8139pci[i].name; i++){
-		if((ctlr = rtl8139match(edev, rtl8139pci[i].id)) != nil)
-			break;
-	}
-	if(ctlr == nil)
-		return -1;
-
-	edev->ctlr = ctlr;
-	edev->port = ctlr->port;
-	edev->irq = ctlr->pcidev->intl;
-	edev->tbdf = ctlr->pcidev->tbdf;
-
-	/*
-	 * Check if the adapter's station address is to be overridden.
-	 * If not, read it from the device and set in edev->ea.
-	 */
-	memset(ea, 0, Eaddrlen);
-	if(memcmp(ea, edev->ea, Eaddrlen) == 0){
-		i = csr32r(ctlr, Idr0);
-		edev->ea[0] = i;
-		edev->ea[1] = i>>8;
-		edev->ea[2] = i>>16;
-		edev->ea[3] = i>>24;
-		i = csr32r(ctlr, Idr0+4);
-		edev->ea[4] = i;
-		edev->ea[5] = i>>8;
-	}
-
-	edev->attach = rtl8139attach;
-	edev->transmit = rtl8139transmit;
-	edev->interrupt = rtl8139interrupt;
-	edev->detach = rtl8139detach;
-
-	return 0;
-}

+ 0 - 957
sys/src/9/w/pxeload/ether8169.c

@@ -1,957 +0,0 @@
-/*
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
-
-/*
- * Realtek RTL8110S/8169S.
- * Mostly there. There are some magic register values used
- * which are not described in any datasheet or driver but seem
- * to be necessary.
- * Why is the Fovf descriptor bit set for every received packet?
- * Occasionally the hardware indicates an input TCP checksum error
- * although the higher-level software seems to check the packet OK?
- * No tuning has been done. Only tested on an RTL8110S, there
- * are slight differences between the chips in the series so some
- * tweaks may be needed.
- */
-#include "u.h"
-#include "lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-
-#include "etherif.h"
-#include "ethermii.h"
-
-enum {					/* registers */
-	Idr0		= 0x00,		/* MAC address */
-	Mar0		= 0x08,		/* Multicast address */
-	Dtccr		= 0x10,		/* Dump Tally Counter Command */
-	Tnpds		= 0x20,		/* Transmit Normal Priority Descriptors */
-	Thpds		= 0x28,		/* Transmit High Priority Descriptors */
-	Flash		= 0x30,		/* Flash Memory Read/Write */
-	Erbcr		= 0x34,		/* Early Receive Byte Count */
-	Ersr		= 0x36,		/* Early Receive Status */
-	Cr		= 0x37,		/* Command Register */
-	Tppoll		= 0x38,		/* Transmit Priority Polling */
-	Imr		= 0x3C,		/* Interrupt Mask */
-	Isr		= 0x3E,		/* Interrupt Status */
-	Tcr		= 0x40,		/* Transmit Configuration */
-	Rcr		= 0x44,		/* Receive Configuration */
-	Tctr		= 0x48,		/* Timer Count */
-	Mpc		= 0x4C,		/* Missed Packet Counter */
-	Cr9346		= 0x50,		/* 9346 Command Register */
-	Config0		= 0x51,		/* Configuration Register 0 */
-	Config1		= 0x52,		/* Configuration Register 1 */
-	Config2		= 0x53,		/* Configuration Register 2 */
-	Config3		= 0x54,		/* Configuration Register 3 */
-	Config4		= 0x55,		/* Configuration Register 4 */
-	Config5		= 0x56,		/* Configuration Register 5 */
-	Timerint	= 0x58,		/* Timer Interrupt */
-	Mulint		= 0x5C,		/* Multiple Interrupt Select */
-	Phyar		= 0x60,		/* PHY Access */
-	Tbicsr0		= 0x64,		/* TBI Control and Status */
-	Tbianar		= 0x68,		/* TBI Auto-Negotiation Advertisment */
-	Tbilpar		= 0x6A,		/* TBI Auto-Negotiation Link Partner */
-	Phystatus	= 0x6C,		/* PHY Status */
-
-	Rms		= 0xDA,		/* Receive Packet Maximum Size */
-	Cplusc		= 0xE0,		/* C+ Command */
-	Rdsar		= 0xE4,		/* Receive Descriptor Start Address */
-	Mtps		= 0xEC,		/* Max. Transmit Packet Size */
-};
-
-enum {					/* Dtccr */
-	Cmd		= 0x00000008,	/* Command */
-};
-
-enum {					/* Cr */
-	Te		= 0x04,		/* Transmitter Enable */
-	Re		= 0x08,		/* Receiver Enable */
-	Rst		= 0x10,		/* Software Reset */
-};
-
-enum {					/* Tppoll */
-	Fswint		= 0x01,		/* Forced Software Interrupt */
-	Npq		= 0x40,		/* Normal Priority Queue polling */
-	Hpq		= 0x80,		/* High Priority Queue polling */
-};
-
-enum {					/* Imr/Isr */
-	Rok		= 0x0001,	/* Receive OK */
-	Rer		= 0x0002,	/* Receive Error */
-	Tok		= 0x0004,	/* Transmit OK */
-	Ter		= 0x0008,	/* Transmit Error */
-	Rdu		= 0x0010,	/* Receive Descriptor Unavailable */
-	Punlc		= 0x0020,	/* Packet Underrun or Link Change */
-	Fovw		= 0x0040,	/* Receive FIFO Overflow */
-	Tdu		= 0x0080,	/* Transmit Descriptor Unavailable */
-	Swint		= 0x0100,	/* Software Interrupt */
-	Timeout		= 0x4000,	/* Timer */
-	Serr		= 0x8000,	/* System Error */
-};
-
-enum {					/* Tcr */
-	MtxdmaSHIFT	= 8,		/* Max. DMA Burst Size */
-	MtxdmaMASK	= 0x00000700,
-	Mtxdmaunlimited	= 0x00000700,
-	Acrc		= 0x00010000,	/* Append CRC (not) */
-	Lbk0		= 0x00020000,	/* Loopback Test 0 */
-	Lbk1		= 0x00040000,	/* Loopback Test 1 */
-	Ifg2		= 0x00080000,	/* Interframe Gap 2 */
-	HwveridSHIFT	= 23,		/* Hardware Version ID */
-	HwveridMASK	= 0x7C800000,
-	Macv01		= 0x00000000,	/* RTL8169 */
-	Macv02		= 0x00800000,	/* RTL8169S/8110S */
-	Macv03		= 0x04000000,	/* RTL8169S/8110S */
-	Macv04		= 0x10000000,	/* RTL8169SB/8110SB */
-	Macv05		= 0x18000000,	/* RTL8169SC/8110SC */
-	Macv11		= 0x30000000,	/* RTL8168B/8111B */
-	Macv12		= 0x38000000,	/* RTL8169B/8111B */
-	Macv13		= 0x34000000,	/* RTL8101E */
-	Macv14		= 0x30800000,	/* RTL8100E */
-	Macv15		= 0x38800000,	/* RTL8100E */
-	Ifg0		= 0x01000000,	/* Interframe Gap 0 */
-	Ifg1		= 0x02000000,	/* Interframe Gap 1 */
-};
-
-enum {					/* Rcr */
-	Aap		= 0x00000001,	/* Accept All Packets */
-	Apm		= 0x00000002,	/* Accept Physical Match */
-	Am		= 0x00000004,	/* Accept Multicast */
-	Ab		= 0x00000008,	/* Accept Broadcast */
-	Ar		= 0x00000010,	/* Accept Runt */
-	Aer		= 0x00000020,	/* Accept Error */
-	Sel9356		= 0x00000040,	/* 9356 EEPROM used */
-	MrxdmaSHIFT	= 8,		/* Max. DMA Burst Size */
-	MrxdmaMASK	= 0x00000700,
-	Mrxdmaunlimited	= 0x00000700,
-	RxfthSHIFT	= 13,		/* Receive Buffer Length */
-	RxfthMASK	= 0x0000E000,
-	Rxfth256	= 0x00008000,
-	Rxfthnone	= 0x0000E000,
-	Rer8		= 0x00010000,	/* Accept Error Packets > 8 bytes */
-	MulERINT	= 0x01000000,	/* Multiple Early Interrupt Select */
-};
-
-enum {					/* Cr9346 */
-	Eedo		= 0x01,		/* */
-	Eedi		= 0x02,		/* */
-	Eesk		= 0x04,		/* */
-	Eecs		= 0x08,		/* */
-	Eem0		= 0x40,		/* Operating Mode */
-	Eem1		= 0x80,
-};
-
-enum {					/* Phyar */
-	DataMASK	= 0x0000FFFF,	/* 16-bit GMII/MII Register Data */
-	DataSHIFT	= 0,
-	RegaddrMASK	= 0x001F0000,	/* 5-bit GMII/MII Register Address */
-	RegaddrSHIFT	= 16,
-	Flag		= 0x80000000,	/* */
-};
-
-enum {					/* Phystatus */
-	Fd		= 0x01,		/* Full Duplex */
-	Linksts		= 0x02,		/* Link Status */
-	Speed10		= 0x04,		/* */
-	Speed100	= 0x08,		/* */
-	Speed1000	= 0x10,		/* */
-	Rxflow		= 0x20,		/* */
-	Txflow		= 0x40,		/* */
-	Entbi		= 0x80,		/* */
-};
-
-enum {					/* Cplusc */
-	Mulrw		= 0x0008,	/* PCI Multiple R/W Enable */
-	Dac		= 0x0010,	/* PCI Dual Address Cycle Enable */
-	Rxchksum	= 0x0020,	/* Receive Checksum Offload Enable */
-	Rxvlan		= 0x0040,	/* Receive VLAN De-tagging Enable */
-	Endian		= 0x0200,	/* Endian Mode */
-};
-
-typedef struct D D;			/* Transmit/Receive Descriptor */
-struct D {
-	uint32_t	control;
-	uint32_t	vlan;
-	uint32_t	addrlo;
-	uint32_t	addrhi;
-};
-
-enum {					/* Transmit Descriptor control */
-	TxflMASK	= 0x0000FFFF,	/* Transmit Frame Length */
-	TxflSHIFT	= 0,
-	Tcps		= 0x00010000,	/* TCP Checksum Offload */
-	Udpcs		= 0x00020000,	/* UDP Checksum Offload */
-	Ipcs		= 0x00040000,	/* IP Checksum Offload */
-	Lgsen		= 0x08000000,	/* Large Send */
-};
-
-enum {					/* Receive Descriptor control */
-	RxflMASK	= 0x00003FFF,	/* Receive Frame Length */
-	RxflSHIFT	= 0,
-	Tcpf		= 0x00004000,	/* TCP Checksum Failure */
-	Udpf		= 0x00008000,	/* UDP Checksum Failure */
-	Ipf		= 0x00010000,	/* IP Checksum Failure */
-	Pid0		= 0x00020000,	/* Protocol ID0 */
-	Pid1		= 0x00040000,	/* Protocol ID1 */
-	Crce		= 0x00080000,	/* CRC Error */
-	Runt		= 0x00100000,	/* Runt Packet */
-	Res		= 0x00200000,	/* Receive Error Summary */
-	Rwt		= 0x00400000,	/* Receive Watchdog Timer Expired */
-	Fovf		= 0x00800000,	/* FIFO Overflow */
-	Bovf		= 0x01000000,	/* Buffer Overflow */
-	Bar		= 0x02000000,	/* Broadcast Address Received */
-	Pam		= 0x04000000,	/* Physical Address Matched */
-	Mar		= 0x08000000,	/* Multicast Address Received */
-};
-
-enum {					/* General Descriptor control */
-	Ls		= 0x10000000,	/* Last Segment Descriptor */
-	Fs		= 0x20000000,	/* First Segment Descriptor */
-	Eor		= 0x40000000,	/* End of Descriptor Ring */
-	Own		= 0x80000000,	/* Ownership */
-};
-
-/*
- */
-enum {					/* Ring sizes  (<= 1024) */
-	Ntd		= 8,		/* Transmit Ring */
-	Nrd		= 32,		/* Receive Ring */
-
-	Mps		= ROUNDUP(ETHERMAXTU+4, 128),
-};
-
-typedef struct Dtcc Dtcc;
-struct Dtcc {
-	uint64_t	txok;
-	uint64_t	rxok;
-	uint64_t	txer;
-	uint32_t	rxer;
-	uint16_t	misspkt;
-	uint16_t	fae;
-	uint32_t	tx1col;
-	uint32_t	txmcol;
-	uint64_t	rxokph;
-	uint64_t	rxokbrd;
-	uint32_t	rxokmu;
-	uint16_t	txabt;
-	uint16_t	txundrn;
-};
-
-enum {						/* Variants */
-	Rtl8100e	= (0x8136<<16)|0x10EC,	/* RTL810[01]E ? */
-	Rtl8169sc	= (0x8167<<16)|0x10EC,	/* RTL8169SC */
-	Rtl8168b	= (0x8168<<16)|0x10EC,	/* RTL8168B */
-	Rtl8169		= (0x8169<<16)|0x10EC,	/* RTL8169 */
-};
-
-typedef struct Ctlr Ctlr;
-typedef struct Ctlr {
-	int	port;
-	Pcidev*	pcidev;
-	Ctlr*	next;
-	int	active;
-
-	void*	nic;
-
-	QLock	alock;			/* attach */
-	Lock	ilock;			/* init */
-	int	init;			/*  */
-
-	int	pciv;			/*  */
-	int	macv;			/* MAC version */
-	int	phyv;			/* PHY version */
-
-	Mii*	mii;
-
-	Lock	tlock;			/* transmit */
-	D*	td;			/* descriptor ring */
-	Block**	tb;			/* transmit buffers */
-	int	ntd;
-
-	int	tdh;			/* head - producer index (host) */
-	int	tdt;			/* tail - consumer index (NIC) */
-	int	ntdfree;
-	int	ntq;
-
-	int	mtps;			/* Max. Transmit Packet Size */
-
-	Lock	rlock;			/* receive */
-	D*	rd;			/* descriptor ring */
-	void**	rb;			/* receive buffers */
-	int	nrd;
-
-	int	rdh;			/* head - producer index (NIC) */
-	int	rdt;			/* tail - consumer index (host) */
-	int	nrdfree;
-
-	int	rcr;			/* receive configuration register */
-
-	QLock	slock;			/* statistics */
-	Dtcc*	dtcc;
-	uint	txdu;
-	uint	tcpf;
-	uint	udpf;
-	uint	ipf;
-	uint	fovf;
-	uint	ierrs;
-	uint	rer;
-	uint	rdu;
-	uint	punlc;
-	uint	fovw;
-} Ctlr;
-
-static Ctlr* rtl8169ctlrhead;
-static Ctlr* rtl8169ctlrtail;
-
-#define csr8r(c, r)	(inb((c)->port+(r)))
-#define csr16r(c, r)	(ins((c)->port+(r)))
-#define csr32r(c, r)	(inl((c)->port+(r)))
-#define csr8w(c, r, b)	(outb((c)->port+(r), (int)(b)))
-#define csr16w(c, r, w)	(outs((c)->port+(r), (ushort)(w)))
-#define csr32w(c, r, l)	(outl((c)->port+(r), (ulong)(l)))
-
-static int
-rtl8169miimir(Mii* mii, int pa, int ra)
-{
-	uint r;
-	int timeo;
-	Ctlr *ctlr;
-
-	if(pa != 1)
-		return -1;
-	ctlr = mii->ctlr;
-
-	r = (ra<<16) & RegaddrMASK;
-	csr32w(ctlr, Phyar, r);
-	delay(1);
-	for(timeo = 0; timeo < 2000; timeo++){
-		if((r = csr32r(ctlr, Phyar)) & Flag)
-			break;
-		microdelay(100);
-	}
-	if(!(r & Flag))
-		return -1;
-
-	return (r & DataMASK)>>DataSHIFT;
-}
-
-static int
-rtl8169miimiw(Mii* mii, int pa, int ra, int data)
-{
-	uint r;
-	int timeo;
-	Ctlr *ctlr;
-
-	if(pa != 1)
-		return -1;
-	ctlr = mii->ctlr;
-
-	r = Flag|((ra<<16) & RegaddrMASK)|((data<<DataSHIFT) & DataMASK);
-	csr32w(ctlr, Phyar, r);
-	delay(1);
-	for(timeo = 0; timeo < 2000; timeo++){
-		if(!((r = csr32r(ctlr, Phyar)) & Flag))
-			break;
-		microdelay(100);
-	}
-	if(r & Flag)
-		return -1;
-
-	return 0;
-}
-
-static int
-rtl8169mii(Ctlr* ctlr)
-{
-	MiiPhy *phy;
-
-	/*
-	 * Link management.
-	 */
-	if((ctlr->mii = malloc(sizeof(Mii))) == nil)
-		return -1;
-	ctlr->mii->mir = rtl8169miimir;
-	ctlr->mii->miw = rtl8169miimiw;
-	ctlr->mii->ctlr = ctlr;
-
-	/*
-	 * Get rev number out of Phyidr2 so can config properly.
-	 * There's probably more special stuff for Macv0[234] needed here.
-	 */
-	ctlr->phyv = rtl8169miimir(ctlr->mii, 1, Phyidr2) & 0x0F;
-	if(ctlr->macv == Macv02){
-		csr8w(ctlr, 0x82, 1);				/* magic */
-		rtl8169miimiw(ctlr->mii, 1, 0x0B, 0x0000);	/* magic */
-	}
-
-	if(mii(ctlr->mii, (1<<1)) == 0 || (phy = ctlr->mii->curphy) == nil){
-		free(ctlr->mii);
-		ctlr->mii = nil;
-		return -1;
-	}
-	print("oui %#ux phyno %d, macv = %#8.8ux phyv = %#4.4ux\n",
-		phy->oui, phy->phyno, ctlr->macv, ctlr->phyv);
-
-	miiane(ctlr->mii, ~0, ~0, ~0);
-
-	return 0;
-}
-
-static void
-rtl8169halt(Ctlr* ctlr)
-{
-	csr8w(ctlr, Cr, 0);
-	csr16w(ctlr, Imr, 0);
-	csr16w(ctlr, Isr, ~0);
-}
-
-static int
-rtl8169reset(Ctlr* ctlr)
-{
-	uint32_t r;
-	int timeo;
-
-	/*
-	 * Soft reset the controller.
-	 */
-	csr8w(ctlr, Cr, Rst);
-	for(r = timeo = 0; timeo < 1000; timeo++){
-		r = csr8r(ctlr, Cr);
-		if(!(r & Rst))
-			break;
-		delay(1);
-	}
-	rtl8169halt(ctlr);
-
-	if(r & Rst)
-		return -1;
-	return 0;
-}
-
-static void
-rtl8169detach(Ether* edev)
-{
-	rtl8169reset(edev->ctlr);
-}
-
-static void
-rtl8169replenish(Ctlr* ctlr)
-{
-	D *d;
-	int rdt;
-	void *bp;
-
-	rdt = ctlr->rdt;
-	while(NEXT(rdt, ctlr->nrd) != ctlr->rdh){
-		d = &ctlr->rd[rdt];
-		if(ctlr->rb[rdt] == nil){
-			/*
-			 * simple allocation for now
-			 */
-			bp = mallocalign(Mps, 8, 0, 0);
-			ctlr->rb[rdt] = bp;
-			d->addrlo = PCIWADDR(bp);
-			d->addrhi = 0;
-		}
-		coherence();
-		d->control |= Own|Mps;
-		rdt = NEXT(rdt, ctlr->nrd);
-		ctlr->nrdfree++;
-	}
-	ctlr->rdt = rdt;
-}
-
-static int
-rtl8169init(Ether* edev)
-{
-	uint32_t r;
-	Ctlr *ctlr;
-	uint8_t cplusc;
-
-	ctlr = edev->ctlr;
-	ilock(&ctlr->ilock);
-
-	rtl8169halt(ctlr);
-
-	/*
-	 * MAC Address.
-	 * Must put chip into config register write enable mode.
-	 */
-	csr8w(ctlr, Cr9346, Eem1|Eem0);
-	r = (edev->ea[3]<<24)|(edev->ea[2]<<16)|(edev->ea[1]<<8)|edev->ea[0];
-	csr32w(ctlr, Idr0, r);
-	r = (edev->ea[5]<<8)|edev->ea[4];
-	csr32w(ctlr, Idr0+4, r);
-
-	/*
-	 * Transmitter.
-	 */
-	memset(ctlr->td, 0, sizeof(D)*ctlr->ntd);
-	ctlr->tdh = ctlr->tdt = 0;
-	ctlr->td[ctlr->ntd-1].control = Eor;
-
-	/*
-	 * Receiver.
-	 * Need to do something here about the multicast filter.
-	 */
-	memset(ctlr->rd, 0, sizeof(D)*ctlr->nrd);
-	ctlr->rdh = ctlr->rdt = 0;
-	ctlr->rd[ctlr->nrd-1].control = Eor;
-	rtl8169replenish(ctlr);
-	ctlr->rcr = Rxfthnone|Mrxdmaunlimited|Ab|Apm;
-
-	/*
-	 * Mtps is in units of 128 except for the RTL8169
-	 * where is is 32. If using jumbo frames should be
-	 * set to 0x3F.
-	 * Setting Mulrw in Cplusc disables the Tx/Rx DMA burst
-	 * settings in Tcr/Rcr; the (1<<14) is magic.
-	 */
-	ctlr->mtps = HOWMANY(Mps, 128);
-	cplusc = csr16r(ctlr, Cplusc) & ~(1<<14);
-	cplusc |= Rxchksum|Mulrw;
-	switch(ctlr->macv){
-	default:
-		return -1;
-	case Macv01:
-		ctlr->mtps = HOWMANY(Mps, 32);
-		break;
-	case Macv02:
-	case Macv03:
-		cplusc |= (1<<14);			/* magic */
-		break;
-	case Macv05:
-		/*
-		 * This is interpreted from clearly bogus code
-		 * in the manufacturer-supplied driver, it could
-		 * be wrong. Untested.
-		 */
-		r = csr8r(ctlr, Config2) & 0x07;
-		if(r == 0x01)				/* 66MHz PCI */
-			csr32w(ctlr, 0x7C, 0x0007FFFF);	/* magic */
-		else
-			csr32w(ctlr, 0x7C, 0x0007FF00);	/* magic */
-		pciclrmwi(ctlr->pcidev);
-		break;
-	case Macv13:
-		/*
-		 * This is interpreted from clearly bogus code
-		 * in the manufacturer-supplied driver, it could
-		 * be wrong. Untested.
-		 */
-		pcicfgw8(ctlr->pcidev, 0x68, 0x00);	/* magic */
-		pcicfgw8(ctlr->pcidev, 0x69, 0x08);	/* magic */
-		break;
-	case Macv04:
-	case Macv11:
-	case Macv12:
-	case Macv14:
-	case Macv15:
-		break;
-	}
-
-	/*
-	 * Enable receiver/transmitter.
-	 * Need to do this first or some of the settings below
-	 * won't take.
-	 */
-	switch(ctlr->pciv){
-	default:
-		csr8w(ctlr, Cr, Te|Re);
-		csr32w(ctlr, Tcr, Ifg1|Ifg0|Mtxdmaunlimited);
-		csr32w(ctlr, Rcr, ctlr->rcr);
-	case Rtl8169sc:
-	case Rtl8168b:
-		break;
-	}
-
-	/*
-	 * Interrupts.
-	 * Disable Tdu|Tok for now, the transmit routine will tidy.
-	 * Tdu means the NIC ran out of descriptors to send, so it
-	 * doesn't really need to ever be on.
-	 */
-	csr32w(ctlr, Timerint, 0);
-	csr16w(ctlr, Imr, Serr|Timeout|Fovw|Punlc|Rdu|Ter|Rer|Rok);
-
-	/*
-	 * Clear missed-packet counter;
-	 * initial early transmit threshold value;
-	 * set the descriptor ring base addresses;
-	 * set the maximum receive packet size;
-	 * no early-receive interrupts.
-	 */
-	csr32w(ctlr, Mpc, 0);
-	csr8w(ctlr, Mtps, ctlr->mtps);
-	csr32w(ctlr, Tnpds+4, 0);
-	csr32w(ctlr, Tnpds, PCIWADDR(ctlr->td));
-	csr32w(ctlr, Rdsar+4, 0);
-	csr32w(ctlr, Rdsar, PCIWADDR(ctlr->rd));
-	csr16w(ctlr, Rms, Mps);
-	r = csr16r(ctlr, Mulint) & 0xF000;
-	csr16w(ctlr, Mulint, r);
-	csr16w(ctlr, Cplusc, cplusc);
-
-	/*
-	 * Set configuration.
-	 */
-	switch(ctlr->pciv){
-	default:
-		break;
-	case Rtl8169sc:
-		csr16w(ctlr, 0xE2, 0);			/* magic */
-		csr8w(ctlr, Cr, Te|Re);
-		csr32w(ctlr, Tcr, Ifg1|Ifg0|Mtxdmaunlimited);
-		csr32w(ctlr, Rcr, ctlr->rcr);
-		break;
-	case Rtl8168b:
-		csr16w(ctlr, 0xE2, 0);			/* magic */
-		csr16w(ctlr, Cplusc, 0x2000);		/* magic */
-		csr8w(ctlr, Cr, Te|Re);
-		csr32w(ctlr, Tcr, Ifg1|Ifg0|Mtxdmaunlimited);
-		csr32w(ctlr, Rcr, ctlr->rcr);
-		csr16w(ctlr, Rms, 0x0800);
-		csr8w(ctlr, Mtps, 0x3F);
-		break;
-	}
-
-	csr8w(ctlr, Cr9346, 0);
-
-	iunlock(&ctlr->ilock);
-
-//	rtl8169mii(ctlr);
-
-	return 0;
-}
-
-static void
-rtl8169attach(Ether* edev)
-{
-	int timeo;
-	Ctlr *ctlr;
-
-	ctlr = edev->ctlr;
-	qlock(&ctlr->alock);
-	if(ctlr->init == 0){
-		/*
-		 * Handle allocation/init errors here.
-		 */
-		ctlr->td = xspanalloc(sizeof(D)*Ntd, 256, 0);
-		ctlr->tb = malloc(Ntd*sizeof(Block*));
-		ctlr->ntd = Ntd;
-		ctlr->rd = xspanalloc(sizeof(D)*Nrd, 256, 0);
-		ctlr->rb = malloc(Nrd*sizeof(Block*));
-		ctlr->nrd = Nrd;
-		ctlr->dtcc = xspanalloc(sizeof(Dtcc), 64, 0);
-		rtl8169init(edev);
-		ctlr->init = 1;
-	}
-	qunlock(&ctlr->alock);
-
-	for(timeo = 0; timeo < 3500; timeo++){
-		if(miistatus(ctlr->mii) == 0)
-			break;
-		delay(10);
-	}
-}
-
-static void
-rtl8169transmit(Ether* edev)
-{
-	D *d;
-	Block *bp;
-	Ctlr *ctlr;
-	int control, x;
-	RingBuf *tb;
-
-	ctlr = edev->ctlr;
-
-	ilock(&ctlr->tlock);
-	for(x = ctlr->tdh; ctlr->ntq > 0; x = NEXT(x, ctlr->ntd)){
-		d = &ctlr->td[x];
-		if((control = d->control) & Own)
-			break;
-
-		/*
-		 * Check errors and log here.
-		 */
-		USED(control);
-
-		/*
-		 * Free it up.
-		 * Need to clean the descriptor here? Not really.
-		 * Simple freeb for now (no chain and freeblist).
-		 * Use ntq count for now.
-		 */
-		freeb(ctlr->tb[x]);
-		ctlr->tb[x] = nil;
-		d->control &= Eor;
-
-		ctlr->ntq--;
-	}
-	ctlr->tdh = x;
-
-	x = ctlr->tdt;
-	while(ctlr->ntq < (ctlr->ntd-1)){
-		tb = &edev->tb[edev->ti];
-		if(tb->owner != Interface)
-			break;
-
-		bp = allocb(tb->len);
-		memmove(bp->wp, tb->pkt, tb->len);
-		memmove(bp->wp+Eaddrlen, edev->ea, Eaddrlen);
-		bp->wp += tb->len;
-
-		tb->owner = Host;
-		edev->ti = NEXT(edev->ti, edev->ntb);
-
-		d = &ctlr->td[x];
-		d->addrlo = PCIWADDR(bp->rp);
-		d->addrhi = 0;
-		ctlr->tb[x] = bp;
-		coherence();
-		d->control |= Own|Fs|Ls|((BLEN(bp)<<TxflSHIFT) & TxflMASK);
-
-		x = NEXT(x, ctlr->ntd);
-		ctlr->ntq++;
-	}
-	if(x != ctlr->tdt){
-		ctlr->tdt = x;
-		csr8w(ctlr, Tppoll, Npq);
-	}
-	else if(ctlr->ntq >= (ctlr->ntd-1))
-		ctlr->txdu++;
-
-	iunlock(&ctlr->tlock);
-}
-
-static void
-rtl8169receive(Ether* edev)
-{
-	D *d;
-	int len, rdh;
-	Ctlr *ctlr;
-	uint32_t control;
-	RingBuf *ring;
-
-	ctlr = edev->ctlr;
-
-	rdh = ctlr->rdh;
-	for(;;){
-		d = &ctlr->rd[rdh];
-
-		if(d->control & Own)
-			break;
-
-		control = d->control;
-		if((control & (Fs|Ls|Res)) == (Fs|Ls)){
-			len = ((control & RxflMASK)>>RxflSHIFT) - 4;
-
-			ring = &edev->rb[edev->ri];
-			if(ring->owner == Interface){
-				ring->owner = Host;
-				ring->len = len;
-				memmove(ring->pkt, ctlr->rb[rdh], len);
-				edev->ri = NEXT(edev->ri, edev->nrb);
-			}
-		}
-		else{
-			/*
-			 * Error stuff here.
-			print("control %#8.8ux\n", control);
-			 */
-		}
-		d->control &= Eor;
-		ctlr->nrdfree--;
-		rdh = NEXT(rdh, ctlr->nrd);
-	}
-	ctlr->rdh = rdh;
-
-	if(ctlr->nrdfree < ctlr->nrd/2)
-		rtl8169replenish(ctlr);
-}
-
-static void
-rtl8169interrupt(Ureg*, void* arg)
-{
-	Ctlr *ctlr;
-	Ether *edev;
-	uint32_t isr;
-
-	edev = arg;
-	ctlr = edev->ctlr;
-
-	while((isr = csr16r(ctlr, Isr)) != 0 && isr != 0xFFFF){
-		csr16w(ctlr, Isr, isr);
-		if(isr & (Fovw|Punlc|Rdu|Rer|Rok)){
-			rtl8169receive(edev);
-			if(!(isr & (Punlc|Rok)))
-				ctlr->ierrs++;
-			if(isr & Rer)
-				ctlr->rer++;
-			if(isr & Rdu)
-				ctlr->rdu++;
-			if(isr & Punlc)
-				ctlr->punlc++;
-			if(isr & Fovw)
-				ctlr->fovw++;
-			isr &= ~(Fovw|Rdu|Rer|Rok);
-		}
-
-		if(isr & (Tdu|Ter|Tok)){
-			rtl8169transmit(edev);
-			isr &= ~(Tdu|Ter|Tok);
-		}
-
-		if(isr & Punlc){
-//			rtl8169link(edev);
-			isr &= ~Punlc;
-		}
-
-		/*
-		 * Some of the reserved bits get set sometimes...
-		 */
-		if(isr & (Serr|Timeout|Tdu|Fovw|Punlc|Rdu|Ter|Tok|Rer|Rok))
-			panic("rtl8169interrupt: imr %#4.4ux isr %#4.4ux\n",
-				csr16r(ctlr, Imr), isr);
-	}
-}
-
-static void
-rtl8169pci(void)
-{
-	Pcidev *p;
-	Ctlr *ctlr;
-	int i, port;
-	uint32_t bar;
-
-	p = nil;
-	while(p = pcimatch(p, 0, 0)){
-		if(p->ccrb != 0x02 || p->ccru != 0)
-			continue;
-
-		switch(i = ((p->did<<16)|p->vid)){
-		default:
-			continue;
-		case Rtl8100e:			/* RTL810[01]E ? */
-		case Rtl8169sc:			/* RTL8169SC */
-		case Rtl8168b:			/* RTL8168B */
-		case Rtl8169:			/* RTL8169 */
-			break;
-		case (0xC107<<16)|0x1259:	/* Corega CG-LAPCIGT */
-			i = Rtl8169;
-			break;
-		}
-
-		bar = p->mem[0].bar;
-		port = bar & ~0x01;
-		if(ioalloc(port, p->mem[0].size, 0, "rtl8169") < 0){
-			print("rtl8169: port %#ux in use\n", port);
-			continue;
-		}
-		ctlr = malloc(sizeof(Ctlr));
-		ctlr->port = port;
-		ctlr->pcidev = p;
-		ctlr->pciv = i;
-
-		if(pcigetpms(p) > 0){
-			pcisetpms(p, 0);
-
-			for(i = 0; i < 6; i++)
-				pcicfgw32(p, PciBAR0+i*4, p->mem[i].bar);
-			pcicfgw8(p, PciINTL, p->intl);
-			pcicfgw8(p, PciLTR, p->ltr);
-			pcicfgw8(p, PciCLS, p->cls);
-			pcicfgw16(p, PciPCR, p->pcr);
-		}
-
-		if(rtl8169reset(ctlr)){
-			iofree(port);
-			free(ctlr);
-			continue;
-		}
-
-		/*
-		 * Extract the chip hardware version,
-		 * needed to configure each properly.
-		 */
-		ctlr->macv = csr32r(ctlr, Tcr) & HwveridMASK;
-
-		rtl8169mii(ctlr);
-
-		pcisetbme(p);
-
-		if(rtl8169ctlrhead != nil)
-			rtl8169ctlrtail->next = ctlr;
-		else
-			rtl8169ctlrhead = ctlr;
-		rtl8169ctlrtail = ctlr;
-	}
-}
-
-int
-rtl8169pnp(Ether* edev)
-{
-	uint32_t r;
-	Ctlr *ctlr;
-
-	if(rtl8169ctlrhead == nil)
-		rtl8169pci();
-
-	/*
-	 * Any adapter matches if no edev->port is supplied,
-	 * otherwise the ports must match.
-	 */
-	for(ctlr = rtl8169ctlrhead; ctlr != nil; ctlr = ctlr->next){
-		if(ctlr->active)
-			continue;
-		if(edev->port == 0 || edev->port == ctlr->port){
-			ctlr->active = 1;
-			break;
-		}
-	}
-	if(ctlr == nil)
-		return -1;
-
-	edev->ctlr = ctlr;
-	edev->port = ctlr->port;
-	edev->irq = ctlr->pcidev->intl;
-	edev->tbdf = ctlr->pcidev->tbdf;
-	edev->mbps = 100;
-
-	/*
-	 * Pull the MAC address out of the chip.
-	 */
-	r = csr32r(ctlr, Idr0);
-	edev->ea[0] = r;
-	edev->ea[1] = r>>8;
-	edev->ea[2] = r>>16;
-	edev->ea[3] = r>>24;
-	r = csr32r(ctlr, Idr0+4);
-	edev->ea[4] = r;
-	edev->ea[5] = r>>8;
-
-	/*
-	 * Linkage to the generic ethernet driver.
-	 */
-	edev->attach = rtl8169attach;
-	edev->transmit = rtl8169transmit;
-	edev->interrupt = rtl8169interrupt;
-	edev->detach = rtl8169detach;
-//	edev->ifstat = rtl8169ifstat;
-//	edev->ctl = nil;
-//
-//	edev->arg = edev;
-//	edev->promiscuous = rtl8169promiscuous;
-//	edev->multicast = rtl8169multicast;
-
-	return 0;
-}

+ 0 - 892
sys/src/9/w/pxeload/ether82557.c

@@ -1,892 +0,0 @@
-/*
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
-
-/*
- * Intel 82557 Fast Ethernet PCI Bus LAN Controller
- * as found on the Intel EtherExpress PRO/100B. This chip is full
- * of smarts, unfortunately none of them are in the right place.
- * To do:
- *	the PCI scanning code could be made common to other adapters;
- *	PCI code needs rewritten to handle byte, word, dword accesses
- *	  and using the devno as a bus+dev+function triplet.
- */
-#include "u.h"
-#include "lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-
-#include "etherif.h"
-
-enum {
-	Nrfd		= 4,		/* receive frame area */
-
-	NullPointer	= 0xFFFFFFFF,	/* 82557 NULL pointer */
-};
-
-enum {					/* CSR */
-	Status		= 0x00,		/* byte or word (word includes Ack) */
-	Ack		= 0x01,		/* byte */
-	CommandR	= 0x02,		/* byte or word (word includes Interrupt) */
-	Interrupt	= 0x03,		/* byte */
-	Pointer		= 0x04,		/* dword */
-	Port		= 0x08,		/* dword */
-	Fcr		= 0x0C,		/* Flash control register */
-	Ecr		= 0x0E,		/* EEPROM control register */
-	Mcr		= 0x10,		/* MDI control register */
-};
-
-enum {					/* Status */
-	RUidle		= 0x0000,
-	RUsuspended	= 0x0004,
-	RUnoresources	= 0x0008,
-	RUready		= 0x0010,
-	RUrbd		= 0x0020,	/* bit */
-	RUstatus	= 0x003F,	/* mask */
-
-	CUidle		= 0x0000,
-	CUsuspended	= 0x0040,
-	CUactive	= 0x0080,
-	CUstatus	= 0x00C0,	/* mask */
-
-	StatSWI		= 0x0400,	/* SoftWare generated Interrupt */
-	StatMDI		= 0x0800,	/* MDI r/w done */
-	StatRNR		= 0x1000,	/* Receive unit Not Ready */
-	StatCNA		= 0x2000,	/* Command unit Not Active (Active->Idle) */
-	StatFR		= 0x4000,	/* Finished Receiving */
-	StatCX		= 0x8000,	/* Command eXecuted */
-	StatTNO		= 0x8000,	/* Transmit NOT OK */
-};
-
-enum {					/* Command (byte) */
-	CUnop		= 0x00,
-	CUstart		= 0x10,
-	CUresume	= 0x20,
-	LoadDCA		= 0x40,		/* Load Dump Counters Address */
-	DumpSC		= 0x50,		/* Dump Statistical Counters */
-	LoadCUB		= 0x60,		/* Load CU Base */
-	ResetSA		= 0x70,		/* Dump and Reset Statistical Counters */
-
-	RUstart		= 0x01,
-	RUresume	= 0x02,
-	RUabort		= 0x04,
-	LoadHDS		= 0x05,		/* Load Header Data Size */
-	LoadRUB		= 0x06,		/* Load RU Base */
-	RBDresume	= 0x07,		/* Resume frame reception */
-};
-
-enum {					/* Interrupt (byte) */
-	InterruptM	= 0x01,		/* interrupt Mask */
-	InterruptSI	= 0x02,		/* Software generated Interrupt */
-};
-
-enum {					/* Ecr */
-	EEsk		= 0x01,		/* serial clock */
-	EEcs		= 0x02,		/* chip select */
-	EEdi		= 0x04,		/* serial data in */
-	EEdo		= 0x08,		/* serial data out */
-
-	EEstart		= 0x04,		/* start bit */
-	EEread		= 0x02,		/* read opcode */
-};
-
-enum {					/* Mcr */
-	MDIread		= 0x08000000,	/* read opcode */
-	MDIwrite	= 0x04000000,	/* write opcode */
-	MDIready	= 0x10000000,	/* ready bit */
-	MDIie		= 0x20000000,	/* interrupt enable */
-};
-
-typedef struct Rfd {
-	int	field;
-	ulong	link;
-	ulong	rbd;
-	ushort	count;
-	ushort	size;
-
-	Etherpkt;
-} Rfd;
-
-enum {					/* field */
-	RfdCollision	= 0x00000001,
-	RfdIA		= 0x00000002,	/* IA match */
-	RfdRxerr	= 0x00000010,	/* PHY character error */
-	RfdType		= 0x00000020,	/* Type frame */
-	RfdRunt		= 0x00000080,
-	RfdOverrun	= 0x00000100,
-	RfdBuffer	= 0x00000200,
-	RfdAlignment	= 0x00000400,
-	RfdCRC		= 0x00000800,
-
-	RfdOK		= 0x00002000,	/* frame received OK */
-	RfdC		= 0x00008000,	/* reception Complete */
-	RfdSF		= 0x00080000,	/* Simplified or Flexible (1) Rfd */
-	RfdH		= 0x00100000,	/* Header RFD */
-
-	RfdI		= 0x20000000,	/* Interrupt after completion */
-	RfdS		= 0x40000000,	/* Suspend after completion */
-	RfdEL		= 0x80000000,	/* End of List */
-};
-
-enum {					/* count */
-	RfdF		= 0x00004000,
-	RfdEOF		= 0x00008000,
-};
-
-typedef struct Cb {
-	int	command;
-	uint32_t	link;
-	uint8_t	data[24];	/* CbIAS + CbConfigure */
-} Cb;
-
-typedef struct TxCB {
-	int	command;
-	uint32_t	link;
-	uint32_t	tbd;
-	uint16_t	count;
-	uint8_t	threshold;
-	uint8_t	number;
-} TxCB;
-
-enum {					/* action command */
-	CbOK		= 0x00002000,	/* DMA completed OK */
-	CbC		= 0x00008000,	/* execution Complete */
-
-	CbNOP		= 0x00000000,
-	CbIAS		= 0x00010000,	/* Indvidual Address Setup */
-	CbConfigure	= 0x00020000,
-	CbMAS		= 0x00030000,	/* Multicast Address Setup */
-	CbTransmit	= 0x00040000,
-	CbDump		= 0x00060000,
-	CbDiagnose	= 0x00070000,
-	CbCommand	= 0x00070000,	/* mask */
-
-	CbSF		= 0x00080000,	/* CbTransmit */
-
-	CbI		= 0x20000000,	/* Interrupt after completion */
-	CbS		= 0x40000000,	/* Suspend after completion */
-	CbEL		= 0x80000000,	/* End of List */
-};
-
-enum {					/* CbTransmit count */
-	CbEOF		= 0x00008000,
-};
-
-typedef struct Ctlr Ctlr;
-typedef struct Ctlr {
-	int	port;
-	Pcidev*	pcidev;
-	Ctlr*	next;
-	int	active;
-
-	int	eepromsz;		/* address size in bits */
-	uint16_t*	eeprom;
-
-	int	ctlrno;
-	char*	type;
-
-	uint8_t	configdata[24];
-
-	Rfd	rfd[Nrfd];
-	int	rfdl;
-	int	rfdx;
-
-	Block*	cbqhead;
-	Block*	cbqtail;
-	int	cbqbusy;
-} Ctlr;
-
-static Ctlr* ctlrhead;
-static Ctlr* ctlrtail;
-
-static uint8_t configdata[24] = {
-	0x16,				/* byte count */
-	0x44,				/* Rx/Tx FIFO limit */
-	0x00,				/* adaptive IFS */
-	0x00,
-	0x04,				/* Rx DMA maximum byte count */
-	0x84,				/* Tx DMA maximum byte count */
-	0x33,				/* late SCB, CNA interrupts */
-	0x01,				/* discard short Rx frames */
-	0x00,				/* 503/MII */
-
-	0x00,
-	0x2E,				/* normal operation, NSAI */
-	0x00,				/* linear priority */
-	0x60,				/* inter-frame spacing */
-	0x00,
-	0xF2,
-	0x48,				/* promiscuous mode off */
-	0x00,
-	0x40,
-	0xF2,				/* transmit padding enable */
-	0x80,				/* full duplex pin enable */
-	0x3F,				/* no Multi IA */
-	0x05,				/* no Multi Cast ALL */
-};
-
-#define csr8r(c, r)	(inb((c)->port+(r)))
-#define csr16r(c, r)	(ins((c)->port+(r)))
-#define csr32r(c, r)	(inl((c)->port+(r)))
-#define csr8w(c, r, b)	(outb((c)->port+(r), (int)(b)))
-#define csr16w(c, r, w)	(outs((c)->port+(r), (uint16_t)(w)))
-#define csr32w(c, r, l)	(outl((c)->port+(r), (uint32_t)(l)))
-
-static void
-custart(Ctlr* ctlr)
-{
-	if(ctlr->cbqhead == 0){
-		ctlr->cbqbusy = 0;
-		return;
-	}
-	ctlr->cbqbusy = 1;
-
-	csr32w(ctlr, Pointer, PADDR(ctlr->cbqhead->rp));
-	while(csr8r(ctlr, CommandR))
-		;
-	csr8w(ctlr, CommandR, CUstart);
-}
-
-static void
-action(Ctlr* ctlr, Block* bp)
-{
-	Cb *cb;
-
-	cb = (Cb*)bp->rp;
-	cb->command |= CbEL;
-
-	if(ctlr->cbqhead){
-		ctlr->cbqtail->next = bp;
-		cb = (Cb*)ctlr->cbqtail->rp;
-		cb->link = PADDR(bp->rp);
-		cb->command &= ~CbEL;
-	}
-	else
-		ctlr->cbqhead = bp;
-	ctlr->cbqtail = bp;
-
-	if(ctlr->cbqbusy == 0)
-		custart(ctlr);
-}
-
-static void
-attach(Ether* ether)
-{
-	int status;
-	Ctlr *ctlr;
-
-	ctlr = ether->ctlr;
-	status = csr16r(ctlr, Status);
-	if((status & RUstatus) == RUidle){
-		csr32w(ctlr, Pointer, PADDR(&ctlr->rfd[ctlr->rfdx]));
-		while(csr8r(ctlr, CommandR))
-			;
-		csr8w(ctlr, CommandR, RUstart);
-	}
-}
-
-static void
-configure(void* arg, int promiscuous)
-{
-	Ctlr *ctlr;
-	Block *bp;
-	Cb *cb;
-
-	ctlr = ((Ether*)arg)->ctlr;
-
-	bp = allocb(sizeof(Cb));
-	cb = (Cb*)bp->rp;
-	bp->wp += sizeof(Cb);
-
-	cb->command = CbConfigure;
-	cb->link = NullPointer;
-	memmove(cb->data, ctlr->configdata, sizeof(ctlr->configdata));
-	if(promiscuous)
-		cb->data[15] |= 0x01;
-	action(ctlr, bp);
-}
-
-static void
-transmit(Ether* ether)
-{
-	Block *bp;
-	TxCB *txcb;
-	RingBuf *tb;
-
-	for(tb = &ether->tb[ether->ti]; tb->owner == Interface; tb = &ether->tb[ether->ti]){
-		bp = allocb(tb->len+sizeof(TxCB));
-		txcb = (TxCB*)bp->wp;
-		bp->wp += sizeof(TxCB);
-
-		txcb->command = CbTransmit;
-		txcb->link = NullPointer;
-		txcb->tbd = NullPointer;
-		txcb->count = CbEOF|tb->len;
-		txcb->threshold = 2;
-		txcb->number = 0;
-
-		memmove(bp->wp, tb->pkt, tb->len);
-		memmove(bp->wp+Eaddrlen, ether->ea, Eaddrlen);
-		bp->wp += tb->len;
-
-		action(ether->ctlr, bp);
-
-		tb->owner = Host;
-		ether->ti = NEXT(ether->ti, ether->ntb);
-	}
-}
-
-static void
-interrupt(Ureg*, void* arg)
-{
-	Rfd *rfd;
-	Block *bp;
-	Ctlr *ctlr;
-	Ether *ether;
-	int status;
-	RingBuf *rb;
-
-	ether = arg;
-	ctlr = ether->ctlr;
-
-	for(;;){
-		status = csr16r(ctlr, Status);
-		csr8w(ctlr, Ack, (status>>8) & 0xFF);
-
-		if((status & (StatCX|StatFR|StatCNA|StatRNR)) == 0)
-			return;
-
-		if(status & StatFR){
-			rfd = &ctlr->rfd[ctlr->rfdx];
-			while(rfd->field & RfdC){
-				rb = &ether->rb[ether->ri];
-				if(rb->owner == Interface){
-					rb->owner = Host;
-					rb->len = rfd->count & 0x3FFF;
-					memmove(rb->pkt, rfd->d, rfd->count & 0x3FFF);
-					ether->ri = NEXT(ether->ri, ether->nrb);
-				}
-
-				/*
-				 * Reinitialise the frame for reception and bump
-				 * the receive frame processing index;
-				 * bump the sentinel index, mark the new sentinel
-				 * and clear the old sentinel suspend bit;
-				 * set bp and rfd for the next receive frame to
-				 * process.
-				 */
-				rfd->field = 0;
-				rfd->count = 0;
-				ctlr->rfdx = NEXT(ctlr->rfdx, Nrfd);
-
-				rfd = &ctlr->rfd[ctlr->rfdl];
-				ctlr->rfdl = NEXT(ctlr->rfdl, Nrfd);
-				ctlr->rfd[ctlr->rfdl].field |= RfdS;
-				rfd->field &= ~RfdS;
-
-				rfd = &ctlr->rfd[ctlr->rfdx];
-			}
-			status &= ~StatFR;
-		}
-
-		if(status & StatRNR){
-			while(csr8r(ctlr, CommandR))
-				;
-			csr8w(ctlr, CommandR, RUresume);
-
-			status &= ~StatRNR;
-		}
-
-		if(status & StatCNA){
-			while(bp = ctlr->cbqhead){
-				if((((Cb*)bp->rp)->command & CbC) == 0)
-					break;
-				ctlr->cbqhead = bp->next;
-				freeb(bp);
-			}
-			custart(ctlr);
-
-			status &= ~StatCNA;
-		}
-
-		if(status & (StatCX|StatFR|StatCNA|StatRNR|StatMDI|StatSWI))
-			panic("%s#%d: status %uX\n", ctlr->type,  ctlr->ctlrno, status);
-	}
-}
-
-static void
-ctlrinit(Ctlr* ctlr)
-{
-	int i;
-	Rfd *rfd;
-	uint32_t link;
-
-	link = NullPointer;
-	for(i = Nrfd-1; i >= 0; i--){
-		rfd = &ctlr->rfd[i];
-
-		rfd->field = 0;
-		rfd->link = link;
-		link = PADDR(rfd);
-		rfd->rbd = NullPointer;
-		rfd->count = 0;
-		rfd->size = sizeof(Etherpkt);
-	}
-	ctlr->rfd[Nrfd-1].link = PADDR(&ctlr->rfd[0]);
-
-	ctlr->rfdl = 0;
-	ctlr->rfd[0].field |= RfdS;
-	ctlr->rfdx = 2;
-
-	memmove(ctlr->configdata, configdata, sizeof(configdata));
-}
-
-static int
-miir(Ctlr* ctlr, int phyadd, int regadd)
-{
-	int mcr, timo;
-
-	csr32w(ctlr, Mcr, MDIread|(phyadd<<21)|(regadd<<16));
-	mcr = 0;
-	for(timo = 64; timo; timo--){
-		mcr = csr32r(ctlr, Mcr);
-		if(mcr & MDIready)
-			break;
-		microdelay(1);
-	}
-
-	if(mcr & MDIready)
-		return mcr & 0xFFFF;
-
-	return -1;
-}
-
-static int
-miiw(Ctlr* ctlr, int phyadd, int regadd, int data)
-{
-	int mcr, timo;
-
-	csr32w(ctlr, Mcr, MDIwrite|(phyadd<<21)|(regadd<<16)|(data & 0xFFFF));
-	mcr = 0;
-	for(timo = 64; timo; timo--){
-		mcr = csr32r(ctlr, Mcr);
-		if(mcr & MDIready)
-			break;
-		microdelay(1);
-	}
-
-	if(mcr & MDIready)
-		return 0;
-
-	return -1;
-}
-
-static int
-hy93c46r(Ctlr* ctlr, int r)
-{
-	int data, i, op, size;
-
-	/*
-	 * Hyundai HY93C46 or equivalent serial EEPROM.
-	 * This sequence for reading a 16-bit register 'r'
-	 * in the EEPROM is taken straight from Section
-	 * 3.3.4.2 of the Intel 82557 User's Guide.
-	 */
-reread:
-	csr16w(ctlr, Ecr, EEcs);
-	op = EEstart|EEread;
-	for(i = 2; i >= 0; i--){
-		data = (((op>>i) & 0x01)<<2)|EEcs;
-		csr16w(ctlr, Ecr, data);
-		csr16w(ctlr, Ecr, data|EEsk);
-		microdelay(1);
-		csr16w(ctlr, Ecr, data);
-		microdelay(1);
-	}
-
-	/*
-	 * First time through must work out the EEPROM size.
-	 */
-	if((size = ctlr->eepromsz) == 0)
-		size = 8;
-
-	for(size = size-1; size >= 0; size--){
-		data = (((r>>size) & 0x01)<<2)|EEcs;
-		csr16w(ctlr, Ecr, data);
-		csr16w(ctlr, Ecr, data|EEsk);
-		delay(1);
-		csr16w(ctlr, Ecr, data);
-		microdelay(1);
-		if(!(csr16r(ctlr, Ecr) & EEdo))
-			break;
-	}
-
-	data = 0;
-	for(i = 15; i >= 0; i--){
-		csr16w(ctlr, Ecr, EEcs|EEsk);
-		microdelay(1);
-		if(csr16r(ctlr, Ecr) & EEdo)
-			data |= (1<<i);
-		csr16w(ctlr, Ecr, EEcs);
-		microdelay(1);
-	}
-
-	csr16w(ctlr, Ecr, 0);
-
-	if(ctlr->eepromsz == 0){
-		ctlr->eepromsz = 8-size;
-		ctlr->eeprom = malloc((1<<ctlr->eepromsz)*sizeof(uint16_t));
-		goto reread;
-	}
-
-	return data;
-}
-
-static void
-i82557pci(void)
-{
-	Pcidev *p;
-	Ctlr *ctlr;
-
-	p = nil;
-	while(p = pcimatch(p, 0x8086, 0)){
-		switch(p->did){
-		default:
-			continue;
-		case 0x1031:		/* Intel 82562EM */
-		case 0x1050:		/* Intel 82562EZ */
-		case 0x1039:		/* Intel 82801BD PRO/100 VE */
-		case 0x103A:		/* Intel 82562 PRO/100 VE */
-		case 0x1064:		/* Intel 82562 PRO/100 VE */
-		case 0x2449:		/* Intel 82562ET */
-		case 0x1209:		/* Intel 82559ER */
-		case 0x1229:		/* Intel 8255[789] */
-		case 0x1030:		/* Intel 82559 InBusiness 10/100  */
-			break;
-		}
-
-		/*
-		 * bar[0] is the memory-mapped register address (4KB),
-		 * bar[1] is the I/O port register address (32 bytes) and
-		 * bar[2] is for the flash ROM (1MB).
-		 */
-		ctlr = malloc(sizeof(Ctlr));
-		ctlr->port = p->mem[1].bar & ~0x01;
-		ctlr->pcidev = p;
-
-		if(ctlrhead != nil)
-			ctlrtail->next = ctlr;
-		else
-			ctlrhead = ctlr;
-		ctlrtail = ctlr;
-
-		pcisetbme(p);
-	}
-}
-
-static void
-detach(Ether* ether)
-{
-	Ctlr *ctlr;
-
-	ctlr = ether->ctlr;
-
-	csr32w(ctlr, Port, 0);
-	delay(1);
-
-	while(csr8r(ctlr, CommandR))
-		;
-pciclrbme(ctlr->pcidev);
-}
-
-static int
-scanphy(Ctlr* ctlr)
-{
-	int i, oui, x;
-
-	for(i = 0; i < 32; i++){
-		if((oui = miir(ctlr, i, 2)) == -1 || oui == 0 || oui == 0xFFFF)
-			continue;
-		oui <<= 6;
-		x = miir(ctlr, i, 3);
-		oui |= x>>10;
-		//print("phy%d: oui %uX reg1 %uX\n", i, oui, miir(ctlr, i, 1));
-
-		if(oui == 0xAA00)
-			ctlr->eeprom[6] = 0x07<<8;
-		else if(oui == 0x80017){
-			if(x & 0x01)
-				ctlr->eeprom[6] = 0x0A<<8;
-			else
-				ctlr->eeprom[6] = 0x04<<8;
-		}
-		return i;
-	}
-	return -1;
-}
-
-int
-i82557reset(Ether* ether)
-{
-	int anar, anlpar, bmcr, bmsr, force, i, phyaddr, x;
-	unsigned short sum;
-	Block *bp;
-	uint8_t ea[Eaddrlen];
-	Ctlr *ctlr;
-	Cb *cb;
-
-
-	if(ctlrhead == nil)
-		i82557pci();
-
-	/*
-	 * Any adapter matches if no ether->port is supplied,
-	 * otherwise the ports must match.
-	 */
-	for(ctlr = ctlrhead; ctlr != nil; ctlr = ctlr->next){
-		if(ctlr->active)
-			continue;
-		if(ether->port == 0 || ether->port == ctlr->port){
-			ctlr->active = 1;
-			break;
-		}
-	}
-	if(ctlr == nil)
-		return -1;
-
-	/*
-	 * Initialise the Ctlr structure.
-	 * Perform a software reset after which need to ensure busmastering
-	 * is still enabled. The EtherExpress PRO/100B appears to leave
-	 * the PCI configuration alone (see the 'To do' list above) so punt
-	 * for now.
-	 * Load the RUB and CUB registers for linear addressing (0).
-	 */
-	ether->ctlr = ctlr;
-	ether->port = ctlr->port;
-	ether->irq = ctlr->pcidev->intl;
-	ether->tbdf = ctlr->pcidev->tbdf;
-	ctlr->ctlrno = ether->ctlrno;
-	ctlr->type = ether->type;
-
-	csr32w(ctlr, Port, 0);
-	delay(1);
-
-	while(csr8r(ctlr, CommandR))
-		;
-	csr32w(ctlr, Pointer, 0);
-	csr8w(ctlr, CommandR, LoadRUB);
-	while(csr8r(ctlr, CommandR))
-		;
-	csr8w(ctlr, CommandR, LoadCUB);
-
-	/*
-	 * Initialise the action and receive frame areas.
-	 */
-	ctlrinit(ctlr);
-
-	/*
-	 * Read the EEPROM.
-	 * Do a dummy read first to get the size
-	 * and allocate ctlr->eeprom.
-	 */
-	hy93c46r(ctlr, 0);
-	sum = 0;
-	for(i = 0; i < (1<<ctlr->eepromsz); i++){
-		x = hy93c46r(ctlr, i);
-		ctlr->eeprom[i] = x;
-		sum += x;
-	}
-	if(sum != 0xBABA)
-		print("#l%d: EEPROM checksum - 0x%4.4uX\n", ether->ctlrno, sum);
-
-	/*
-	 * Eeprom[6] indicates whether there is a PHY and whether
-	 * it's not 10Mb-only, in which case use the given PHY address
-	 * to set any PHY specific options and determine the speed.
-	 * Unfortunately, sometimes the EEPROM is blank except for
-	 * the ether address and checksum; in this case look at the
-	 * controller type and if it's am 82558 or 82559 it has an
-	 * embedded PHY so scan for that.
-	 * If no PHY, assume 82503 (serial) operation.
-	 */
-	if((ctlr->eeprom[6] & 0x1F00) && !(ctlr->eeprom[6] & 0x8000))
-		phyaddr = ctlr->eeprom[6] & 0x00FF;
-	else
-	switch(ctlr->pcidev->rid){
-	case 0x01:			/* 82557 A-step */
-	case 0x02:			/* 82557 B-step */
-	case 0x03:			/* 82557 C-step */
-	default:
-		phyaddr = -1;
-		break;
-	case 0x04:			/* 82558 A-step */
-	case 0x05:			/* 82558 B-step */
-	case 0x06:			/* 82559 A-step */
-	case 0x07:			/* 82559 B-step */
-	case 0x08:			/* 82559 C-step */
-	case 0x09:			/* 82559ER A-step */
-		phyaddr = scanphy(ctlr);
-		break;
-	}
-	if(phyaddr >= 0){
-		/*
-		 * Resolve the highest common ability of the two
-		 * link partners. In descending order:
-		 *	0x0100		100BASE-TX Full Duplex
-		 *	0x0200		100BASE-T4
-		 *	0x0080		100BASE-TX
-		 *	0x0040		10BASE-T Full Duplex
-		 *	0x0020		10BASE-T
-		 */
-		anar = miir(ctlr, phyaddr, 0x04);
-		anlpar = miir(ctlr, phyaddr, 0x05) & 0x03E0;
-		anar &= anlpar;
-		bmcr = 0;
-		if(anar & 0x380)
-			bmcr = 0x2000;
-		if(anar & 0x0140)
-			bmcr |= 0x0100;
-
-		switch((ctlr->eeprom[6]>>8) & 0x001F){
-
-		case 0x04:				/* DP83840 */
-		case 0x0A:				/* DP83840A */
-			/*
-			 * The DP83840[A] requires some tweaking for
-			 * reliable operation.
-			 * The manual says bit 10 should be unconditionally
-			 * set although it supposedly only affects full-duplex
-			 * operation (an & 0x0140).
-			 */
-			x = miir(ctlr, phyaddr, 0x17) & ~0x0520;
-			x |= 0x0420;
-			for(i = 0; i < ether->nopt; i++){
-				if(cistrcmp(ether->opt[i], "congestioncontrol"))
-					continue;
-				x |= 0x0100;
-				break;
-			}
-			miiw(ctlr, phyaddr, 0x17, x);
-
-			/*
-			 * If the link partner can't autonegotiate, determine
-			 * the speed from elsewhere.
-			 */
-			if(anlpar == 0){
-				miir(ctlr, phyaddr, 0x01);
-				bmsr = miir(ctlr, phyaddr, 0x01);
-				x = miir(ctlr, phyaddr, 0x19);
-				if((bmsr & 0x0004) && !(x & 0x0040))
-					bmcr = 0x2000;
-			}
-			break;
-
-		case 0x07:				/* Intel 82555 */
-			/*
-			 * Auto-negotiation may fail if the other end is
-			 * a DP83840A and the cable is short.
-			 */
-			bmsr = miir(ctlr, phyaddr, 0x01);
-			if((miir(ctlr, phyaddr, 0) & 0x1000) && !(bmsr & 0x0020)){
-				miiw(ctlr, phyaddr, 0x1A, 0x2010);
-				x = miir(ctlr, phyaddr, 0);
-				miiw(ctlr, phyaddr, 0, 0x0200|x);
-				for(i = 0; i < 3000; i++){
-					delay(1);
-					if(miir(ctlr, phyaddr, 0x01) & 0x0020)
-						break;
-				}
-				miiw(ctlr, phyaddr, 0x1A, 0x2000);
-
-				anar = miir(ctlr, phyaddr, 0x04);
-				anlpar = miir(ctlr, phyaddr, 0x05) & 0x03E0;
-				anar &= anlpar;
-				bmcr = 0;
-				if(anar & 0x380)
-					bmcr = 0x2000;
-				if(anar & 0x0140)
-					bmcr |= 0x0100;
-			}
-			break;
-		}
-
-		/*
-		 * Force speed and duplex if no auto-negotiation.
-		 */
-		if(anlpar == 0){
-			force = 0;
-			for(i = 0; i < ether->nopt; i++){
-				if(cistrcmp(ether->opt[i], "fullduplex") == 0){
-					force = 1;
-					bmcr |= 0x0100;
-					ctlr->configdata[19] |= 0x40;
-				}
-				else if(cistrcmp(ether->opt[i], "speed") == 0){
-					force = 1;
-					x = strtol(&ether->opt[i][6], 0, 0);
-					if(x == 10)
-						bmcr &= ~0x2000;
-					else if(x == 100)
-						bmcr |= 0x2000;
-					else
-						force = 0;
-				}
-			}
-			if(force)
-				miiw(ctlr, phyaddr, 0x00, bmcr);
-		}
-
-		ctlr->configdata[8] = 1;
-		ctlr->configdata[15] &= ~0x80;
-	}
-	else{
-		ctlr->configdata[8] = 0;
-		ctlr->configdata[15] |= 0x80;
-	}
-
-	/*
-	 * Load the chip configuration
-	 */
-	configure(ether, 0);
-
-	/*
-	 * Check if the adapter's station address is to be overridden.
-	 * If not, read it from the EEPROM and set in ether->ea prior to loading
-	 * the station address with the Individual Address Setup command.
-	 */
-	memset(ea, 0, Eaddrlen);
-	if(memcmp(ea, ether->ea, Eaddrlen) == 0){
-		for(i = 0; i < Eaddrlen/2; i++){
-			x = ctlr->eeprom[i];
-			ether->ea[2*i] = x & 0xFF;
-			ether->ea[2*i+1] = (x>>8) & 0xFF;
-		}
-	}
-
-	bp = allocb(sizeof(Cb));
-	cb = (Cb*)bp->rp;
-	bp->wp += sizeof(Cb);
-
-	cb->command = CbIAS;
-	cb->link = NullPointer;
-	memmove(cb->data, ether->ea, Eaddrlen);
-	action(ctlr, bp);
-
-	/*
-	 * Linkage to the generic ethernet driver.
-	 */
-	ether->attach = attach;
-	ether->transmit = transmit;
-	ether->interrupt = interrupt;
-	ether->detach = detach;
-
-	return 0;
-}

+ 0 - 1175
sys/src/9/w/pxeload/ether82563.c

@@ -1,1175 +0,0 @@
-/*
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
-
-/*
- * Bootstrap driver for
- * Intel 82563, 82571, 82573, 82575, 82576
- * GbE PCI-Express Controllers.
- */
-#include "u.h"
-#include "lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-
-#include "etherif.h"
-
-/* compatibility with cpu kernels */
-#define iallocb allocb
-#ifndef CACHELINESZ
-#define CACHELINESZ	32		/* pentium & later */
-#endif
-
-/* from pci.c */
-enum
-{					/* command register pcidev->pcr */
-	IOen		= 1<<0,
-	MEMen		= 1<<1,
-	MASen		= 1<<2,
-	MemWrInv	= 1<<4,
-	PErrEn		= 1<<6,
-	SErrEn		= 1<<8,
-};
-
-/*
- * these are in the order they appear in the manual, not numeric order.
- * It was too hard to find them in the book. Ref 21489, rev 2.6
- */
-
-enum {
-	/* General */
-
-	Ctrl		= 0x00000000,	/* Device Control */
-	Status		= 0x00000008,	/* Device Status */
-	Eec		= 0x00000010,	/* EEPROM/Flash Control/Data */
-	Eerd		= 0x00000014,	/* EEPROM Read */
-	Ctrlext		= 0x00000018,	/* Extended Device Control */
-	Fla		= 0x0000001c,	/* Flash Access */
-	Mdic		= 0x00000020,	/* MDI Control */
-	Seresctl	= 0x00000024,	/* Serdes ana */
-	Fcal		= 0x00000028,	/* Flow Control Address Low */
-	Fcah		= 0x0000002C,	/* Flow Control Address High */
-	Fct		= 0x00000030,	/* Flow Control Type */
-	Kumctrlsta	= 0x00000034,	/* MAC-PHY Interface */
-	Vet		= 0x00000038,	/* VLAN EtherType */
-	Fcttv		= 0x00000170,	/* Flow Control Transmit Timer Value */
-	Txcw		= 0x00000178,	/* Transmit Configuration Word */
-	Rxcw		= 0x00000180,	/* Receive Configuration Word */
-	Ledctl		= 0x00000E00,	/* LED control */
-	Pba		= 0x00001000,	/* Packet Buffer Allocation */
-	Pbs		= 0x00001008,	/* Packet Buffer Size */
-
-	/* Interrupt */
-
-	Icr		= 0x000000C0,	/* Interrupt Cause Read */
-	Ics		= 0x000000C8,	/* Interrupt Cause Set */
-	Ims		= 0x000000D0,	/* Interrupt Mask Set/Read */
-	Imc		= 0x000000D8,	/* Interrupt mask Clear */
-	Iam		= 0x000000E0,	/* Interrupt acknowledge Auto Mask */
-
-	/* Receive */
-
-	Rctl		= 0x00000100,	/* Receive Control */
-	Ert		= 0x00002008,	/* Early Receive Threshold (573[EVL] only) */
-	Fcrtl		= 0x00002160,	/* Flow Control RX Threshold Low */
-	Fcrth		= 0x00002168,	/* Flow Control Rx Threshold High */
-	Psrctl		= 0x00002170,	/* Packet Split Receive Control */
-	Rdbal		= 0x00002800,	/* Rdesc Base Address Low Queue 0 */
-	Rdbah		= 0x00002804,	/* Rdesc Base Address High Queue 0 */
-	Rdlen		= 0x00002808,	/* Receive Descriptor Length Queue 0 */
-	Rdh		= 0x00002810,	/* Receive Descriptor Head Queue 0 */
-	Rdt		= 0x00002818,	/* Receive Descriptor Tail Queue 0 */
-	Rdtr		= 0x00002820,	/* Receive Descriptor Timer Ring */
-	Rxdctl		= 0x00002828,	/* Receive Descriptor Control */
-	Radv		= 0x0000282C,	/* Receive Interrupt Absolute Delay Timer */
-	Rdbal1		= 0x00002900,	/* Rdesc Base Address Low Queue 1 */
-	Rdbah1		= 0x00002804,	/* Rdesc Base Address High Queue 1 */
-	Rdlen1		= 0x00002908,	/* Receive Descriptor Length Queue 1 */
-	Rdh1		= 0x00002910,	/* Receive Descriptor Head Queue 1 */
-	Rdt1		= 0x00002918,	/* Receive Descriptor Tail Queue 1 */
-	Rxdctl1		= 0x00002928,	/* Receive Descriptor Control Queue 1 */
-	Rsrpd		= 0x00002c00,	/* Receive Small Packet Detect */
-	Raid		= 0x00002c08,	/* Receive ACK interrupt delay */
-	Cpuvec		= 0x00002c10,	/* CPU Vector */
-	Rxcsum		= 0x00005000,	/* Receive Checksum Control */
-	Rfctl		= 0x00005008,	/* Receive Filter Control */
-	Mta		= 0x00005200,	/* Multicast Table Array */
-	Ral		= 0x00005400,	/* Receive Address Low */
-	Rah		= 0x00005404,	/* Receive Address High */
-	Vfta		= 0x00005600,	/* VLAN Filter Table Array */
-	Mrqc		= 0x00005818,	/* Multiple Receive Queues Command */
-	Rssim		= 0x00005864,	/* RSS Interrupt Mask */
-	Rssir		= 0x00005868,	/* RSS Interrupt Request */
-	Reta		= 0x00005c00,	/* Redirection Table */
-	Rssrk		= 0x00005c80,	/* RSS Random Key */
-
-	/* Transmit */
-
-	Tctl		= 0x00000400,	/* Transmit Control */
-	Tipg		= 0x00000410,	/* Transmit IPG */
-	Tdbal		= 0x00003800,	/* Tdesc Base Address Low */
-	Tdbah		= 0x00003804,	/* Tdesc Base Address High */
-	Tdlen		= 0x00003808,	/* Transmit Descriptor Length */
-	Tdh		= 0x00003810,	/* Transmit Descriptor Head */
-	Tdt		= 0x00003818,	/* Transmit Descriptor Tail */
-	Tidv		= 0x00003820,	/* Transmit Interrupt Delay Value */
-	Txdctl		= 0x00003828,	/* Transmit Descriptor Control */
-	Tadv		= 0x0000382C,	/* Transmit Interrupt Absolute Delay Timer */
-	Tarc0		= 0x00003840,	/* Transmit Arbitration Counter Queue 0 */
-	Tdbal1		= 0x00003900,	/* Transmit Descriptor Base Low Queue 1 */
-	Tdbah1		= 0x00003904,	/* Transmit Descriptor Base High Queue 1 */
-	Tdlen1		= 0x00003908,	/* Transmit Descriptor Length Queue 1 */
-	Tdh1		= 0x00003910,	/* Transmit Descriptor Head Queue 1 */
-	Tdt1		= 0x00003918,	/* Transmit Descriptor Tail Queue 1 */
-	Txdctl1		= 0x00003928,	/* Transmit Descriptor Control 1 */
-	Tarc1		= 0x00003940,	/* Transmit Arbitration Counter Queue 1 */
-
-	/* Statistics */
-
-	Statistics	= 0x00004000,	/* Start of Statistics Area */
-	Gorcl		= 0x88/4,	/* Good Octets Received Count */
-	Gotcl		= 0x90/4,	/* Good Octets Transmitted Count */
-	Torl		= 0xC0/4,	/* Total Octets Received */
-	Totl		= 0xC8/4,	/* Total Octets Transmitted */
-	Nstatistics	= 64,
-
-};
-
-enum {					/* Ctrl */
-	GIOmd		= 1<<2,		/* BIO master disable */
-	Lrst		= 1<<3,		/* link reset */
-	Slu		= 1<<6,		/* Set Link Up */
-	SspeedMASK	= 3<<8,		/* Speed Selection */
-	SspeedSHIFT	= 8,
-	Sspeed10	= 0x00000000,	/* 10Mb/s */
-	Sspeed100	= 0x00000100,	/* 100Mb/s */
-	Sspeed1000	= 0x00000200,	/* 1000Mb/s */
-	Frcspd		= 1<<11,	/* Force Speed */
-	Frcdplx		= 1<<12,	/* Force Duplex */
-	SwdpinsloMASK	= 0x003C0000,	/* Software Defined Pins - lo nibble */
-	SwdpinsloSHIFT	= 18,
-	SwdpioloMASK	= 0x03C00000,	/* Software Defined Pins - I or O */
-	SwdpioloSHIFT	= 22,
-	Devrst		= 1<<26,	/* Device Reset */
-	Rfce		= 1<<27,	/* Receive Flow Control Enable */
-	Tfce		= 1<<28,	/* Transmit Flow Control Enable */
-	Vme		= 1<<30,	/* VLAN Mode Enable */
-	Phy_rst		= 1<<31,	/* Phy Reset */
-};
-
-enum {					/* Status */
-	Lu		= 1<<1,		/* Link Up */
-	Lanid		= 3<<2,		/* mask for Lan ID. */
-	Txoff		= 1<<4,		/* Transmission Paused */
-	Tbimode		= 1<<5,		/* TBI Mode Indication */
-	SpeedMASK	= 0x000000C0,
-	Speed10		= 0x00000000,	/* 10Mb/s */
-	Speed100	= 0x00000040,	/* 100Mb/s */
-	Speed1000	= 0x00000080,	/* 1000Mb/s */
-	Phyra		= 1<<10,	/* PHY Reset Asserted */
-	GIOme		= 1<<19,	/* GIO Master Enable Status */
-};
-
-enum {					/* Ctrl and Status */
-	Fd		= 0x00000001,	/* Full-Duplex */
-	AsdvMASK	= 0x00000300,
-	Asdv10		= 0x00000000,	/* 10Mb/s */
-	Asdv100		= 0x00000100,	/* 100Mb/s */
-	Asdv1000	= 0x00000200,	/* 1000Mb/s */
-};
-
-enum {					/* Eec */
-	Sk		= 1<<0,		/* Clock input to the EEPROM */
-	Cs		= 1<<1,		/* Chip Select */
-	Di		= 1<<2,		/* Data Input to the EEPROM */
-	Do		= 1<<3,		/* Data Output from the EEPROM */
-	Areq		= 1<<6,		/* EEPROM Access Request */
-	Agnt		= 1<<7,		/* EEPROM Access Grant */
-};
-
-enum {					/* Eerd */
-	ee_start	= 1<<0,		/* Start Read */
-	ee_done		= 1<<1,		/* Read done */
-	ee_addr		= 0xfff8<<2,	/* Read address [15:2] */
-	ee_data		= 0xffff<<16,	/* Read Data; Data returned from eeprom/nvm */
-};
-
-enum {					/* Ctrlext */
-	Asdchk		= 1<<12,	/* ASD Check */
-	Eerst		= 1<<13,	/* EEPROM Reset */
-	Spdbyps		= 1<<15,	/* Speed Select Bypass */
-};
-
-enum {					/* EEPROM content offsets */
-	Ea		= 0x00,		/* Ethernet Address */
-	Cf		= 0x03,		/* Compatibility Field */
-	Icw1		= 0x0A,		/* Initialization Control Word 1 */
-	Sid		= 0x0B,		/* Subsystem ID */
-	Svid		= 0x0C,		/* Subsystem Vendor ID */
-	Did		= 0x0D,		/* Device ID */
-	Vid		= 0x0E,		/* Vendor ID */
-	Icw2		= 0x0F,		/* Initialization Control Word 2 */
-};
-
-enum {					/* Mdic */
-	MDIdMASK	= 0x0000FFFF,	/* Data */
-	MDIdSHIFT	= 0,
-	MDIrMASK	= 0x001F0000,	/* PHY Register Address */
-	MDIrSHIFT	= 16,
-	MDIpMASK	= 0x03E00000,	/* PHY Address */
-	MDIpSHIFT	= 21,
-	MDIwop		= 0x04000000,	/* Write Operation */
-	MDIrop		= 0x08000000,	/* Read Operation */
-	MDIready	= 0x10000000,	/* End of Transaction */
-	MDIie		= 0x20000000,	/* Interrupt Enable */
-	MDIe		= 0x40000000,	/* Error */
-};
-
-enum {					/* Icr, Ics, Ims, Imc */
-	Txdw		= 0x00000001,	/* Transmit Descriptor Written Back */
-	Txqe		= 0x00000002,	/* Transmit Queue Empty */
-	Lsc		= 0x00000004,	/* Link Status Change */
-	Rxseq		= 0x00000008,	/* Receive Sequence Error */
-	Rxdmt0		= 0x00000010,	/* Rdesc Minimum Threshold Reached */
-	Rxo		= 0x00000040,	/* Receiver Overrun */
-	Rxt0		= 0x00000080,	/* Receiver Timer Interrupt */
-	Mdac		= 0x00000200,	/* MDIO Access Completed */
-	Rxcfg		= 0x00000400,	/* Receiving /C/ ordered sets */
-	Gpi0		= 0x00000800,	/* General Purpose Interrupts */
-	Gpi1		= 0x00001000,
-	Gpi2		= 0x00002000,
-	Gpi3		= 0x00004000,
-	Ack		= 0x00020000,	/* receive ACK frame */
-};
-
-enum {					/* Txcw */
-	TxcwFd		= 0x00000020,	/* Full Duplex */
-	TxcwHd		= 0x00000040,	/* Half Duplex */
-	TxcwPauseMASK	= 0x00000180,	/* Pause */
-	TxcwPauseSHIFT	= 7,
-	TxcwPs		= 1<<TxcwPauseSHIFT,	/* Pause Supported */
-	TxcwAs		= 2<<TxcwPauseSHIFT,	/* Asymmetric FC desired */
-	TxcwRfiMASK	= 0x00003000,	/* Remote Fault Indication */
-	TxcwRfiSHIFT	= 12,
-	TxcwNpr		= 0x00008000,	/* Next Page Request */
-	TxcwConfig	= 0x40000000,	/* Transmit Config Control */
-	TxcwAne		= 0x80000000,	/* Auto-Negotiation Enable */
-};
-
-enum {					/* Rctl */
-	Rrst		= 0x00000001,	/* Receiver Software Reset */
-	Ren		= 0x00000002,	/* Receiver Enable */
-	Sbp		= 0x00000004,	/* Store Bad Packets */
-	Upe		= 0x00000008,	/* Unicast Promiscuous Enable */
-	Mpe		= 0x00000010,	/* Multicast Promiscuous Enable */
-	Lpe		= 0x00000020,	/* Long Packet Reception Enable */
-	LbmMASK		= 0x000000C0,	/* Loopback Mode */
-	LbmOFF		= 0x00000000,	/* No Loopback */
-	LbmTBI		= 0x00000040,	/* TBI Loopback */
-	LbmMII		= 0x00000080,	/* GMII/MII Loopback */
-	LbmXCVR		= 0x000000C0,	/* Transceiver Loopback */
-	RdtmsMASK	= 0x00000300,	/* Rdesc Minimum Threshold Size */
-	RdtmsHALF	= 0x00000000,	/* Threshold is 1/2 Rdlen */
-	RdtmsQUARTER	= 0x00000100,	/* Threshold is 1/4 Rdlen */
-	RdtmsEIGHTH	= 0x00000200,	/* Threshold is 1/8 Rdlen */
-	MoMASK		= 0x00003000,	/* Multicast Offset */
-	Bam		= 0x00008000,	/* Broadcast Accept Mode */
-	BsizeMASK	= 0x00030000,	/* Receive Buffer Size */
-	Bsize2048	= 0x00000000,
-	Bsize1024	= 0x00010000,
-	Bsize512	= 0x00020000,
-	Bsize256	= 0x00030000,
-	Vfe		= 0x00040000,	/* VLAN Filter Enable */
-	Cfien		= 0x00080000,	/* Canonical Form Indicator Enable */
-	Cfi		= 0x00100000,	/* Canonical Form Indicator value */
-	Dpf		= 0x00400000,	/* Discard Pause Frames */
-	Pmcf		= 0x00800000,	/* Pass MAC Control Frames */
-	Bsex		= 0x02000000,	/* Buffer Size Extension */
-	Secrc		= 0x04000000,	/* Strip CRC from incoming packet */
-};
-
-enum {					/* Tctl */
-	Trst		= 0x00000001,	/* Transmitter Software Reset */
-	Ten		= 0x00000002,	/* Transmit Enable */
-	Psp		= 0x00000008,	/* Pad Short Packets */
-	Mulr		= 0x10000000,	/* Allow multiple concurrent requests */
-	CtMASK		= 0x00000FF0,	/* Collision Threshold */
-	CtSHIFT		= 4,
-	ColdMASK	= 0x003FF000,	/* Collision Distance */
-	ColdSHIFT	= 12,
-	Swxoff		= 0x00400000,	/* Sofware XOFF Transmission */
-	Pbe		= 0x00800000,	/* Packet Burst Enable */
-	Rtlc		= 0x01000000,	/* Re-transmit on Late Collision */
-	Nrtu		= 0x02000000,	/* No Re-transmit on Underrrun */
-};
-
-enum {					/* [RT]xdctl */
-	PthreshMASK	= 0x0000003F,	/* Prefetch Threshold */
-	PthreshSHIFT	= 0,
-	HthreshMASK	= 0x00003F00,	/* Host Threshold */
-	HthreshSHIFT	= 8,
-	WthreshMASK	= 0x003F0000,	/* Writeback Threshold */
-	WthreshSHIFT	= 16,
-	Gran		= 0x01000000,	/* Granularity */
-	Qenable		= 0x02000000,	/* Queue Enable (82575eb) */
-};
-
-enum {					/* Rxcsum */
-	PcssMASK	= 0x000000FF,	/* Packet Checksum Start */
-	PcssSHIFT	= 0,
-	Ipofl		= 0x00000100,	/* IP Checksum Off-load Enable */
-	Tuofl		= 0x00000200,	/* TCP/UDP Checksum Off-load Enable */
-};
-
-typedef struct Rdesc {			/* Receive Descriptor */
-	uint	addr[2];
-	uint16_t	length;
-	uint16_t	checksum;
-	uint8_t	status;
-	uint8_t	errors;
-	uint16_t	special;
-} Rdesc;
-
-enum {					/* Rdesc status */
-	Rdd		= 0x01,		/* Descriptor Done */
-	Reop		= 0x02,		/* End of Packet */
-	Ixsm		= 0x04,		/* Ignore Checksum Indication */
-	Vp		= 0x08,		/* Packet is 802.1Q (matched VET) */
-	Tcpcs		= 0x20,		/* TCP Checksum Calculated on Packet */
-	Ipcs		= 0x40,		/* IP Checksum Calculated on Packet */
-	Pif		= 0x80,		/* Passed in-exact filter */
-};
-
-enum {					/* Rdesc errors */
-	Ce		= 0x01,		/* CRC Error or Alignment Error */
-	Se		= 0x02,		/* Symbol Error */
-	Seq		= 0x04,		/* Sequence Error */
-	Cxe		= 0x10,		/* Carrier Extension Error */
-	Tcpe		= 0x20,		/* TCP/UDP Checksum Error */
-	Ipe		= 0x40,		/* IP Checksum Error */
-	Rxe		= 0x80,		/* RX Data Error */
-};
-
-typedef struct Tdesc {			/* Legacy+Normal Transmit Descriptor */
-	uint	addr[2];
-	uint	control;		/* varies with descriptor type */
-	uint	status;			/* varies with descriptor type */
-} Tdesc;
-
-enum {					/* Tdesc control */
-	LenMASK		= 0x000FFFFF,	/* Data/Packet Length Field */
-	LenSHIFT	= 0,
-	DtypeCD		= 0x00000000,	/* Data Type 'Context Descriptor' */
-	DtypeDD		= 0x00100000,	/* Data Type 'Data Descriptor' */
-	PtypeTCP	= 0x01000000,	/* TCP/UDP Packet Type (CD) */
-	Teop		= 0x01000000,	/* End of Packet (DD) */
-	PtypeIP		= 0x02000000,	/* IP Packet Type (CD) */
-	Ifcs		= 0x02000000,	/* Insert FCS (DD) */
-	Tse		= 0x04000000,	/* TCP Segmentation Enable */
-	Rs		= 0x08000000,	/* Report Status */
-	Rps		= 0x10000000,	/* Report Status Sent */
-	Dext		= 0x20000000,	/* Descriptor Extension */
-	Vle		= 0x40000000,	/* VLAN Packet Enable */
-	Ide		= 0x80000000,	/* Interrupt Delay Enable */
-};
-
-enum {					/* Tdesc status */
-	Tdd		= 0x00000001,	/* Descriptor Done */
-	Ec		= 0x00000002,	/* Excess Collisions */
-	Lc		= 0x00000004,	/* Late Collision */
-	Tu		= 0x00000008,	/* Transmit Underrun */
-	CssMASK		= 0x0000FF00,	/* Checksum Start Field */
-	CssSHIFT	= 8,
-};
-
-typedef struct {
-	uint16_t	*reg;
-	uint32_t	*reg32;
-	int	sz;
-} Flash;
-
-enum {
-	/* 16 and 32-bit flash registers for ich flash parts */
-	Bfpr	= 0x00/4,		/* flash base 0:12; lim 16:28 */
-	Fsts	= 0x04/2,		/* flash status;  Hsfsts */
-	Fctl	= 0x06/2,		/* flash control; Hsfctl */
-	Faddr	= 0x08/4,		/* flash address to r/w */
-	Fdata	= 0x10/4,		/* data @ address */
-
-	/* status register */
-	Fdone	= 1<<0,			/* flash cycle done */
-	Fcerr	= 1<<1,			/* cycle error; write 1 to clear */
-	Ael	= 1<<2,			/* direct access error log; 1 to clear */
-	Scip	= 1<<5,			/* spi cycle in progress */
-	Fvalid	= 1<<14,		/* flash descriptor valid */
-
-	/* control register */
-	Fgo	= 1<<0,			/* start cycle */
-	Flcycle	= 1<<1,			/* two bits: r=0; w=2 */
-	Fdbc	= 1<<8,			/* bytes to read; 5 bits */
-};
-
-enum {
-	Nrdesc		= 32,		/* multiple of 8 */
-	Ntdesc		= 8,		/* multiple of 8 */
-};
-
-enum {
-	i82563,
-	i82566,
-	i82567,
-	i82571,
-	i82572,
-	i82573,
-	i82575,
-	i82576,
-};
-
-static char *tname[] = {
-	"i82563",
-	"i82566",
-	"i82567",
-	"i82571",
-	"i82572",
-	"i82573",
-	"i82575",
-	"i82576",
-};
-
-typedef struct Ctlr Ctlr;
-struct Ctlr {
-	int	port;
-	Pcidev	*pcidev;
-	Ctlr	*next;
-	int	active;
-	int	cls;
-	uint16_t	eeprom[0x40];
-	uint8_t	ra[Eaddrlen];		/* receive address */
-	int	type;
-
-	uint32_t*	nic;
-	Lock	imlock;
-	int	im;			/* interrupt mask */
-
-	Lock	slock;
-	uint	statistics[Nstatistics];
-
-	Rdesc	*rdba;			/* receive descriptor base address */
-	Block	**rb;			/* receive buffers */
-	int	rdh;			/* receive descriptor head */
-	int	rdt;			/* receive descriptor tail */
-
-	Tdesc	*tdba;			/* transmit descriptor base address */
-	Lock	tdlock;
-	Block	**tb;			/* transmit buffers */
-	int	tdh;			/* transmit descriptor head */
-	int	tdt;			/* transmit descriptor tail */
-
-	int	txcw;
-	int	fcrtl;
-	int	fcrth;
-
-	/* bootstrap goo */
-	Block	*bqhead;		/* transmission queue */
-	Block	*bqtail;
-};
-
-static Ctlr	*ctlrhead;
-static Ctlr	*ctlrtail;
-
-#define csr32r(c, r)	(*((c)->nic+((r)/4)))
-#define csr32w(c, r, v)	(*((c)->nic+((r)/4)) = (v))
-
-static void
-i82563im(Ctlr* ctlr, int im)
-{
-	ilock(&ctlr->imlock);
-	ctlr->im |= im;
-	csr32w(ctlr, Ims, ctlr->im);
-	iunlock(&ctlr->imlock);
-}
-
-static void
-i82563attach(Ether* edev)
-{
-	int ctl;
-	Ctlr *ctlr;
-
-	ctlr = edev->ctlr;
-	i82563im(ctlr, 0);
-	ctl = csr32r(ctlr, Rctl)|Ren;
-	csr32w(ctlr, Rctl, ctl);
-	ctl = csr32r(ctlr, Tctl)|Ten;
-	csr32w(ctlr, Tctl, ctl);
-}
-
-
-static void
-txstart(Ether *edev)
-{
-	int tdh, tdt;
-	Ctlr *ctlr = edev->ctlr;
-	Block *bp;
-	Tdesc *tdesc;
-
-	/*
-	 * Try to fill the ring back up, moving buffers from the transmit q.
-	 */
-	tdh = PREV(ctlr->tdh, Ntdesc);
-	for(tdt = ctlr->tdt; tdt != tdh; tdt = NEXT(tdt, Ntdesc)){
-		/* pull off the head of the transmission queue */
-		if((bp = ctlr->bqhead) == nil)	/* was qget(edev->oq) */
-			break;
-		ctlr->bqhead = bp->next;
-		if (ctlr->bqtail == bp)
-			ctlr->bqtail = nil;
-
-		/* set up a descriptor for it */
-		tdesc = &ctlr->tdba[tdt];
-		tdesc->addr[0] = PCIWADDR(bp->rp);
-		tdesc->addr[1] = 0;
-		tdesc->control = /* Ide | */ Rs | Ifcs | Teop | BLEN(bp);
-
-		ctlr->tb[tdt] = bp;
-	}
-	ctlr->tdt = tdt;
-	csr32w(ctlr, Tdt, tdt);
-	i82563im(ctlr, Txdw);
-}
-
-static Block *
-fromringbuf(Ether *ether)
-{
-	RingBuf *tb = &ether->tb[ether->ti];
-	Block *bp = allocb(tb->len);
-
-	memmove(bp->wp, tb->pkt, tb->len);
-	memmove(bp->wp+Eaddrlen, ether->ea, Eaddrlen);
-	bp->wp += tb->len;
-	return bp;
-}
-
-static void
-i82563transmit(Ether* edev)
-{
-	Block *bp;
-	Ctlr *ctlr;
-	Tdesc *tdesc;
-	RingBuf *tb;
-	int tdh;
-
-	ctlr = edev->ctlr;
-	ilock(&ctlr->tdlock);
-
-	/*
-	 * Free any completed packets
-	 * - try to get the soft tdh to catch the tdt;
-	 * - if the packet had an underrun bump the threshold
-	 *   - the Tu bit doesn't seem to ever be set, perhaps
-	 *     because Rs mode is used?
-	 */
-	tdh = ctlr->tdh;
-	for(;;){
-		tdesc = &ctlr->tdba[tdh];
-		if(!(tdesc->status & Tdd))
-			break;
-		if(ctlr->tb[tdh] != nil){
-			freeb(ctlr->tb[tdh]);
-			ctlr->tb[tdh] = nil;
-		}
-		tdesc->status = 0;
-		tdh = NEXT(tdh, Ntdesc);
-	}
-	ctlr->tdh = tdh;
-
-	/* copy packets from the software RingBuf to the transmission q */
-	while((tb = &edev->tb[edev->ti])->owner == Interface){
-		bp = fromringbuf(edev);
-//		print("#l%d: tx %d %E %E\n", edev->ctlrno, edev->ti, bp->rp,
-//			bp->rp+6);
-
-		if(ctlr->bqhead)
-			ctlr->bqtail->next = bp;
-		else
-			ctlr->bqhead = bp;
-		ctlr->bqtail = bp;
-
-		txstart(edev);		/* kick transmitter */
-		tb->owner = Host;	/* give descriptor back */
-		edev->ti = NEXT(edev->ti, edev->ntb);
-	}
-	iunlock(&ctlr->tdlock);
-}
-
-static void
-i82563replenish(Ctlr* ctlr)
-{
-	int rdt;
-	Block *bp;
-	Rdesc *rdesc;
-
-	rdt = ctlr->rdt;
-	while(NEXT(rdt, Nrdesc) != ctlr->rdh){
-		rdesc = &ctlr->rdba[rdt];
-		if(ctlr->rb[rdt] != nil){
-			/* nothing to do */
-		}
-		else if((bp = iallocb(2048)) != nil){
-			ctlr->rb[rdt] = bp;
-			rdesc->addr[0] = PCIWADDR(bp->rp);
-			rdesc->addr[1] = 0;
-		}
-		else
-			break;
-		rdesc->status = 0;
-
-		rdt = NEXT(rdt, Nrdesc);
-	}
-	ctlr->rdt = rdt;
-	csr32w(ctlr, Rdt, rdt);
-}
-
-static void
-toringbuf(Ether *ether, Block *bp)
-{
-	RingBuf *rb = &ether->rb[ether->ri];
-
-	if (rb->owner == Interface) {
-		rb->len = BLEN(bp);
-		memmove(rb->pkt, bp->rp, rb->len);
-		rb->owner = Host;
-		ether->ri = NEXT(ether->ri, ether->nrb);
-	} else if (debug)
-		print("#l%d: toringbuf: dropping packets @ ri %d\n",
-			ether->ctlrno, ether->ri);
-}
-
-int	interesting(void*);
-
-static void
-i82563interrupt(Ureg*, void* arg)
-{
-	int icr, im, rdh, txdw = 0, rxcnt;
-	Block *bp;
-	Ctlr *ctlr;
-	Ether *edev;
-	Rdesc *rdesc;
-
-	edev = arg;
-	ctlr = edev->ctlr;
-
-	ilock(&ctlr->imlock);
-	csr32w(ctlr, Imc, ~0);
-	im = ctlr->im;
-
-	rxcnt = 0;
-	for(icr = csr32r(ctlr, Icr); icr & ctlr->im; icr = csr32r(ctlr, Icr)){
-		if(icr & (Rxseq|Lsc)){
-			/* should be more here */
-		}
-
-		rdh = ctlr->rdh;
-		for (;;) {
-			rdesc = &ctlr->rdba[rdh];
-			if(!(rdesc->status & Rdd))
-				break;
-			if ((rdesc->status & Reop) && rdesc->errors == 0) {
-				bp = ctlr->rb[rdh];
-				if(0 && memcmp(bp->rp, broadcast, 6) != 0)
-					print("#l%d: rx %d %E %E %d\n",
-						edev->ctlrno, rdh, bp->rp,
-						bp->rp+6, rdesc->length);
-				ctlr->rb[rdh] = nil;
-				bp->wp += rdesc->length;
-				if (interesting(bp->rp))
-					toringbuf(edev, bp);
-				freeb(bp);
-			} else if (rdesc->status & Reop && rdesc->errors)
-				print("%s: input packet error %#ux\n",
-					tname[ctlr->type], rdesc->errors);
-			rdesc->status = 0;
-			rdh = NEXT(rdh, Nrdesc);
-			if (++rxcnt >= 16 && ctlr->type == i82576) {
-				i82563replenish(ctlr);
-				rxcnt = 0;
-			}
-		}
-		ctlr->rdh = rdh;
-		if(icr & Rxdmt0 || ctlr->type == i82576)
-			i82563replenish(ctlr);
-		if(icr & Txdw){
-			im &= ~Txdw;
-			txdw++;
-		}
-	}
-	ctlr->im = im;
-	csr32w(ctlr, Ims, im);
-	iunlock(&ctlr->imlock);
-	if(txdw)
-		i82563transmit(edev);
-}
-
-static void
-i82563init(Ether* edev)
-{
-	Ctlr *ctlr;
-	uint32_t r, rctl;
-
-	ctlr = edev->ctlr;
-
-	rctl = Dpf | Bsize2048 | Bam | RdtmsHALF;
-	if(ctlr->type == i82575 || ctlr->type == i82576){
-		/*
-		 * Setting Qenable in Rxdctl does not
-		 * appear to stick unless Ren is on.
-		 */
-		csr32w(ctlr, Rctl, Ren|rctl);
-		r = csr32r(ctlr, Rxdctl);
-		r |= Qenable;
-		csr32w(ctlr, Rxdctl, r);
-	}
-	csr32w(ctlr, Rctl, rctl);
-	ctlr->rdba = mallocalign(Nrdesc*sizeof(Rdesc), 256, 0, 0); /* 256 was 128 */
-	csr32w(ctlr, Rdbal, PCIWADDR(ctlr->rdba));
-	csr32w(ctlr, Rdbah, 0);
-	csr32w(ctlr, Rdlen, Nrdesc*sizeof(Rdesc));
-	ctlr->rdh = 0;
-	csr32w(ctlr, Rdh, ctlr->rdh);
-	ctlr->rdt = 0;
-	csr32w(ctlr, Rdt, ctlr->rdt);
-	ctlr->rb = malloc(sizeof(Block*)*Nrdesc);
-	i82563replenish(ctlr);
-	csr32w(ctlr, Rdtr, 0);
-	csr32w(ctlr, Radv, 0);
-
-	if(ctlr->type == i82573)
-		csr32w(ctlr, Ert, 1024/8);
-	if(ctlr->type == i82566 || ctlr->type == i82567)
-		csr32w(ctlr, Pbs, 16);
-	i82563im(ctlr, Rxt0 | Rxo | Rxdmt0 | Rxseq | Ack);
-
-	csr32w(ctlr, Tctl, 0x0F<<CtSHIFT | Psp | 0x3f<<ColdSHIFT | Mulr);
-	csr32w(ctlr, Tipg, 6<<20 | 8<<10 | 8);
-	csr32w(ctlr, Tidv, 1);
-
-	ctlr->tdba = mallocalign(Ntdesc*sizeof(Tdesc), 256, 0, 0); /* 256 was 128 */
-	memset(ctlr->tdba, 0, Ntdesc*sizeof(Tdesc));
-	csr32w(ctlr, Tdbal, PCIWADDR(ctlr->tdba));
-
-	csr32w(ctlr, Tdbah, 0);
-	csr32w(ctlr, Tdlen, Ntdesc*sizeof(Tdesc));
-	ctlr->tdh = 0;
-	csr32w(ctlr, Tdh, ctlr->tdh);
-	ctlr->tdt = 0;
-	csr32w(ctlr, Tdt, ctlr->tdt);
-	ctlr->tb = malloc(sizeof(Block*)*Ntdesc);
-
-	r = csr32r(ctlr, Txdctl);
-	r &= ~(WthreshMASK|PthreshMASK);
-	r |= 4<<WthreshSHIFT | 4<<PthreshSHIFT;
-	if(ctlr->type == i82575 || ctlr->type == i82576)
-		r |= Qenable;
-	csr32w(ctlr, Txdctl, r);
-
-	/*
-	 * Don't enable checksum offload.  In practice, it interferes with
-	 * tftp booting on at least the 82575.
-	 */
-//	csr32w(ctlr, Rxcsum, Tuofl | Ipofl | ETHERHDRSIZE<<PcssSHIFT);
-	csr32w(ctlr, Rxcsum, 0);
-	r = csr32r(ctlr, Tctl);
-	r |= Ten;
-	csr32w(ctlr, Tctl, r);
-}
-
-
-static uint16_t
-eeread(Ctlr* ctlr, int adr)
-{
-	csr32w(ctlr, Eerd, ee_start | adr << 2);
-	while ((csr32r(ctlr, Eerd) & ee_done) == 0)
-		;
-	return csr32r(ctlr, Eerd) >> 16;
-}
-
-static int
-eeload(Ctlr* ctlr)
-{
-	uint16_t sum;
-	int data, adr;
-
-	sum = 0;
-	for (adr = 0; adr < 0x40; adr++) {
-		data = eeread(ctlr, adr);
-		ctlr->eeprom[adr] = data;
-		sum += data;
-	}
-	return sum;
-}
-
-
-static void
-detach(Ctlr *ctlr)
-{
-	int r;
-
-	csr32w(ctlr, Imc, ~0);
-	csr32w(ctlr, Rctl, 0);
-	csr32w(ctlr, Tctl, 0);
-
-	delay(10);
-
-	r = csr32r(ctlr, Ctrl);
-	if(ctlr->type == i82566 || ctlr->type == i82567)
-		r |= Phy_rst;
-	csr32w(ctlr, Ctrl, Devrst | r);
-	/* apparently needed on multi-GHz processors to avoid infinite loops */
-	delay(1);
-	while(csr32r(ctlr, Ctrl) & Devrst)
-		;
-
-	if(1 || ctlr->type != i82563){
-		r = csr32r(ctlr, Ctrl);
-		csr32w(ctlr, Ctrl, Slu | r);
-	}
-
-	csr32w(ctlr, Ctrlext, Eerst | csr32r(ctlr, Ctrlext));
-	delay(1);
-	while(csr32r(ctlr, Ctrlext) & Eerst)
-		;
-
-	csr32w(ctlr, Imc, ~0);
-	delay(1);
-	while(csr32r(ctlr, Icr))
-		;
-}
-
-static void
-i82563detach(Ether *edev)
-{
-	detach(edev->ctlr);
-}
-
-static void
-i82563shutdown(Ether* ether)
-{
-	i82563detach(ether);
-}
-
-static int
-fcycle(Ctlr *, Flash *f)
-{
-	uint16_t s, i;
-
-	s = f->reg[Fsts];
-	if((s&Fvalid) == 0)
-		return -1;
-	f->reg[Fsts] |= Fcerr | Ael;
-	for(i = 0; i < 10; i++){
-		if((s&Scip) == 0)
-			return 0;
-		delay(1);
-		s = f->reg[Fsts];
-	}
-	return -1;
-}
-
-static int
-fread(Ctlr *c, Flash *f, int ladr)
-{
-	uint16_t s;
-
-	delay(1);
-	if(fcycle(c, f) == -1)
-		return -1;
-	f->reg[Fsts] |= Fdone;
-	f->reg32[Faddr] = ladr;
-
-	/* setup flash control register */
-	s = f->reg[Fctl];
-	s &= ~(0x1f << 8);
-	s |= (2-1) << 8;		/* 2 bytes */
-	s &= ~(2*Flcycle);		/* read */
-	f->reg[Fctl] = s | Fgo;
-
-	while((f->reg[Fsts] & Fdone) == 0)
-		;
-	if(f->reg[Fsts] & (Fcerr|Ael))
-		return -1;
-	return f->reg32[Fdata] & 0xffff;
-}
-
-static int
-fload(Ctlr *c)
-{
-	uint32_t data, io, r, adr;
-	uint16_t sum;
-	Flash f;
-	Pcidev *p;
-
-//	io = c->pcidev->mem[1].bar & ~0x0f;
-//	f.reg = vmap(io, c->pcidev->mem[1].size);
-//	if(f.reg == nil)
-//		return -1;
-
-	p = c->pcidev;
-	io = upamalloc(p->mem[1].bar & ~0x0F, p->mem[1].size, 0);
-	if(io == 0){
-		print("igbepcie: can't map flash @ 0x%8.8lux\n", p->mem[1].bar);
-		return -1;
-	}
-	f.reg = KADDR(io);
-
-	f.reg32 = (uint32_t*)f.reg;
-	f.sz = f.reg32[Bfpr];
-	r = f.sz & 0x1fff;
-	if(csr32r(c, Eec) & (1<<22))
-		++r;
-	r <<= 12;
-
-	sum = 0;
-	for (adr = 0; adr < 0x40; adr++) {
-		data = fread(c, &f, r + adr*2);
-		if(data == -1)
-			break;
-		c->eeprom[adr] = data;
-		sum += data;
-	}
-//	vunmap(f.reg, c->pcidev->mem[1].size);
-	return sum;
-}
-
-static int
-i82563reset(Ctlr* ctlr)
-{
-	int i, r;
-
-	detach(ctlr);
-
-	if(ctlr->type == i82566 || ctlr->type == i82567)
-		r = fload(ctlr);
-	else
-		r = eeload(ctlr);
-	if (r != 0 && r != 0xBABA){
-		print("%s: bad EEPROM checksum - 0x%4.4ux\n",
-			tname[ctlr->type], r);
-		return -1;
-	}
-
-	for(i = Ea; i < Eaddrlen/2; i++){
-		ctlr->ra[2*i]   = ctlr->eeprom[i];
-		ctlr->ra[2*i+1] = ctlr->eeprom[i]>>8;
-	}
-	r = (csr32r(ctlr, Status) & Lanid) >> 2;
-	ctlr->ra[5] += r;		/* ea ctlr[1] = ea ctlr[0]+1 */
-
-	r = ctlr->ra[3]<<24 | ctlr->ra[2]<<16 | ctlr->ra[1]<<8 | ctlr->ra[0];
-	csr32w(ctlr, Ral, r);
-	r = 0x80000000 | ctlr->ra[5]<<8 | ctlr->ra[4];
-	csr32w(ctlr, Rah, r);
-	for(i = 1; i < 16; i++){
-		csr32w(ctlr, Ral+i*8, 0);
-		csr32w(ctlr, Rah+i*8, 0);
-	}
-
-	for(i = 0; i < 128; i++)
-		csr32w(ctlr, Mta+i*4, 0);
-
-	csr32w(ctlr, Fcal, 0x00C28001);
-	csr32w(ctlr, Fcah, 0x00000100);
-	csr32w(ctlr, Fct,  0x00008808);
-	csr32w(ctlr, Fcttv, 0x00000100);
-
-	csr32w(ctlr, Fcrtl, ctlr->fcrtl);
-	csr32w(ctlr, Fcrth, ctlr->fcrth);
-
-	ilock(&ctlr->imlock);
-	csr32w(ctlr, Imc, ~0);
-	ctlr->im = 0;		/* was = Lsc, which hangs some controllers */
-	csr32w(ctlr, Ims, ctlr->im);
-	iunlock(&ctlr->imlock);
-
-	return 0;
-}
-
-static void
-i82563pci(void)
-{
-	int port, type, cls;
-	Pcidev *p;
-	Ctlr *ctlr;
-	static int first = 1;
-
-	if (first)
-		first = 0;
-	else
-		return;
-
-	p = nil;
-	while(p = pcimatch(p, 0x8086, 0)){
-		if(p->ccrb != 0x02 || p->ccru != 0)
-			continue;
-//print("i82563pci: did %4.4#x\n", p->did);
-		switch(p->did){
-		case 0x1096:
-		case 0x10ba:
-			type = i82563;
-			break;
-		case 0x1049:		/* mm */
-		case 0x104a:		/* dm */
-		case 0x104b:		/* dc */
-		case 0x104d:		/* mc */
-		case 0x10bd:		/* dm */
-		case 0x294c:		/* dc-2 */
-			type = i82566;
-			break;
-		case 0x10cd:		/* lf */
-		case 0x10ce:		/* v-2 */
-		case 0x10de:		/* lm-3 */
-		case 0x10f5:		/* lm-2 */
-			type = i82567;
-			break;
-		case 0x10a4:
-		case 0x105e:
-			type = i82571;
-			break;
-		case 0x10b9:		/* sic, 82572gi */
-		case 0x107d:
-			type = i82572;
-			break;
-		case 0x108b:		/*  v */
-		case 0x108c:		/*  e (iamt) */
-		case 0x109a:		/*  l */
-			type = i82573;
-			break;
-//		case 0x10d3:		/* l */
-//			type = i82574;	/* never heard of it */
-//			break;
-		case 0x10a7:		/* 82575eb */
-			type = i82575;
-			break;
-		case 0x10c9:		/* 82576 copper */
-		case 0x10e6:		/* 82576 fiber */
-		case 0x10e7:		/* 82576 serdes */
-			type = i82576;
-			break;
-		default:
-			continue;
-		}
-
-		port = upamalloc(p->mem[0].bar & ~0x0F, p->mem[0].size, 0);
-		if(port == 0){
-			print("%s: can't map %d @ 0x%8.8lux\n", tname[type],
-				p->mem[0].size, p->mem[0].bar);
-			continue;
-		}
-
-		if(p->pcr & MemWrInv){
-			cls = pcicfgr8(p, PciCLS) * 4;
-			if(cls != CACHELINESZ)
-				pcicfgw8(p, PciCLS, CACHELINESZ/4);
-		}
-
-		cls = pcicfgr8(p, PciCLS);
-		switch(cls){
-		default:
-			print("%s: unexpected CLS - %d bytes\n",
-				tname[type], cls*sizeof(int32_t));
-			break;
-		case 0x00:
-		case 0xFF:
-			/* alphapc 164lx returns 0 */
-			print("%s: unusable PciCLS: %d, using %d longs\n",
-				tname[type], cls, CACHELINESZ/sizeof(int32_t));
-			cls = CACHELINESZ/sizeof(int32_t);
-			pcicfgw8(p, PciCLS, cls);
-			break;
-		case 0x08:
-		case 0x10:
-			break;
-		}
-
-		ctlr = malloc(sizeof(Ctlr));
-		ctlr->port = port;
-		ctlr->pcidev = p;
-		ctlr->cls = cls*4;
-		ctlr->type = type;
-		ctlr->nic = KADDR(ctlr->port);
-		if(i82563reset(ctlr)){
-			free(ctlr);
-			continue;
-		}
-		pcisetbme(p);
-
-		if(ctlrhead != nil)
-			ctlrtail->next = ctlr;
-		else
-			ctlrhead = ctlr;
-		ctlrtail = ctlr;
-	}
-}
-
-static uint8_t nilea[Eaddrlen];
-
-int
-i82563pnp(Ether* edev)
-{
-	Ctlr *ctlr;
-
-	if(ctlrhead == nil)
-		i82563pci();
-
-	/*
-	 * Any adapter matches if no edev->port is supplied,
-	 * otherwise the ports must match.
-	 */
-	for(ctlr = ctlrhead; ctlr != nil; ctlr = ctlr->next){
-		if(ctlr->active)
-			continue;
-		if(edev->port == 0 || edev->port == ctlr->port){
-			ctlr->active = 1;
-			break;
-		}
-	}
-	if(ctlr == nil)
-		return -1;
-
-	edev->ctlr = ctlr;
-	edev->port = ctlr->port;
-	edev->irq = ctlr->pcidev->intl;
-	edev->tbdf = ctlr->pcidev->tbdf;
-//	edev->mbps = 1000;
-
-	if(memcmp(edev->ea, nilea, Eaddrlen) == 0)
-		memmove(edev->ea, ctlr->ra, Eaddrlen);
-	i82563init(edev);
-
-	/*
-	 * Linkage to the generic ethernet driver.
-	 */
-	edev->attach = i82563attach;
-	edev->transmit = i82563transmit;
-	edev->interrupt = i82563interrupt;
-	edev->detach = i82563detach;
-
-	/*
-	 * with the current structure, there is no right place for this.
-	 * ideally, we recognize the interface, note it's down and move on.
-	 * currently either we can skip the interface or note it is down,
-	 * but not both.
-	if((csr32r(ctlr, Status)&Lu) == 0){
-		print("ether#%d: 82563 (%s): link down\n",
-			edev->ctlrno, tname[ctlr->type]);
-		return -1;
-	}
-	 */
-
-	return 0;
-}

+ 0 - 1136
sys/src/9/w/pxeload/etherbcm4401.c

@@ -1,1136 +0,0 @@
-/*
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
-
-/*
- * Broadcom BCM4401.
- */
-#include "u.h"
-#include "lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#include "ip.h"
-
-#include "etherif.h"
-#include "ethermii.h"
-
-enum {						/* Broadcom Registers */
-	Bdctl		= 0x0000,		/* Device Control */
-	Bis		= 0x0020,		/* Interrupt Status */
-	Bim		= 0x0024,		/* Interrupt Mask */
-	Bmctl		= 0x00A8,		/* MAC Control */
-	Blictl		= 0x0100,		/* Lazy Interrupt Control */
-
-	TDMActl		= 0x0200,		/* Tx DMA Control */
-	TDMAra		= 0x0204,		/* Tx DMA Ring Address */
-	TDMAld		= 0x0208,		/* Tx DMA Last Descriptor */
-	TDMAstatus	= 0x020C,		/* Tx DMA Status */
-
-	RDMActl		= 0x0210,		/* Rx DMA Control */
-	RDMAra		= 0x0214,		/* Rx DMA Ring Address */
-	RDMAld		= 0x0218,		/* Rx DMA Last Descriptor */
-	RDMAstatus	= 0x021C,		/* Rx DMA Status */
-
-	Rxcfg		= 0x0400,		/* Rx Config */
-	Rxmax		= 0x0404,		/* Rx Max. Packet Length */
-	Txmax		= 0x0408,		/* Tx Max. Packet Length */
-	MDIOctl		= 0x0410,		/* */
-	MDIOdata	= 0x0414,		/* */
-	MDIOstatus	= 0x041C,		/* */
-	CAMdlo		= 0x0420,		/* CAM Data Low */
-	CAMdhi		= 0x0424,		/* CAM Data High */
-	CAMctl		= 0x0428,		/* CAM Control */
-	EMACctl		= 0x042C,		/* */
-	EMACtxwmark	= 0x0434,		/* Transmit Watermark */
-	MIBctl		= 0x0438,		/* */
-	MIB		= 0x0500,		/* */
-
-	Eeprom		= 0x1000,		/* EEPROM base */
-	Eao		= Eeprom+78,		/* MAC address offset */
-	Pao		= Eeprom+90,		/* Phy address offset */
-};
-
-enum {						/* Bdctl */
-	Bpfe		= 0x00000080,		/* Pattern Filtering Enable */
-	Bipp		= 0x00000400,		/* Internal PHY Present */
-	Bpme		= 0x00001000,		/* PHY Mode Enable */
-	Bpmce		= 0x00002000,		/* PHY Mode Clock Enable */
-	Bepr		= 0x00008000,		/* External PHY Reset */
-};
-
-enum {						/* Bis/Bim */
-	Ilc		= 0x00000020,		/* Link Change */
-	Ipme		= 0x00000040,		/* Power Management Event */
-	Igpt		= 0x00000080,		/* General Purpose Timeout */
-	Idesce		= 0x00000400,		/* Descriptor Error */
-	Idatae		= 0x00000800,		/* Data Error */
-	Idpe		= 0x00001000,		/* Descriptor Protocol Error */
-	Irdu		= 0x00002000,		/* Rx Descriptor Underflow */
-	Irfo		= 0x00004000,		/* Rx FIFO Overflow */
-	Itfu		= 0x00008000,		/* Tx FIFO Underflow */
-	Ir		= 0x00010000,		/* Rx */
-	It		= 0x01000000,		/* Tx */
-	Ie		= 0x04000000,		/* EMAC */
-	Imw		= 0x08000000,		/* MII Write */
-	Imr		= 0x10000000,		/* MII Read */
-
-	Ierror		= Itfu|Irfo|Irdu|Idpe|Idatae|Idesce,
-};
-
-enum {						/* Bmctl */
-	Mcge		= 0x00000001,		/* CRC32 Generation Enable */
-	Mppd		= 0x00000004,		/* Onchip PHY Power Down */
-	Mped		= 0x00000008,		/* Onchip PHY Energy Detected */
-	MlcMASK		= 0x000000E0,		/* Onchip PHY LED Control */
-	MlcSHIFT	= 5,
-};
-
-enum {						/* Blictl */
-	MtoMASK		= 0x00FFFFFF,		/* Timeout */
-	MtoSHIFT	= 0,
-	MfcMASK		= 0xFF000000,		/* Frame Count */
-	MfcSHIFT	= 24,
-};
-
-enum {						/* TDMActl */
-	Te		= 0x00000001,		/* Enable */
-};
-
-enum {						/* RDMActl */
-	Re		= 0x00000001,		/* Enable */
-	RfoMASK		= 0x000000FE,		/* Receive Frame Offset */
-	RfoSHIFT	= 1,
-};
-
-enum {						/* RDMAstatus */
-	DcdMASK		= 0x00000FFF,		/* Current Descriptor */
-	DcdSHIFT	= 0,
-	Dactive		= 0x00001000,		/* Active */
-	Didle		= 0x00002000,		/* Idle */
-	Dstopped	= 0x00003000,		/* Stopped */
-	Dsm		= 0x0000F000,		/* State Mask */
-	Dem		= 0x000F0000,		/* Error mask */
-};
-
-enum {						/* MDIOctl */
-	Mfreq		= 0x0000000D,		/* MDC Frequency (62.5MHz) */
-	Mpe		= 0x00000080,		/* Preamble Enable */
-};
-
-enum {						/* MDIOdata */
-	Mack		= 0x00020000,		/* Ack */
-	Mwop		= 0x10000000,		/* Write Op. */
-	Mrop		= 0x20000000,		/* Read Op. */
-	Msof		= 0x40000000,		/* Start of Frame */
-};
-
-enum {						/* MDIOstatus */
-	Mmi		= 0x00000001,		/* MDIO Interrupt */
-};
-
-enum {						/* Rxcfg */
-	Rbd		= 0x00000001,		/* Broadcast Disable */
-	Raam		= 0x00000002,		/* Accept All Multicast */
-	Rdtx		= 0x00000004,		/* Disable while Transmitting */
-	Rpe		= 0x00000008,		/* Promiscuous Enable */
-	Rle		= 0x00000010,		/* Loopback Enable */
-	Rfce		= 0x00000020,		/* Flow Control Enable */
-	Rafcf		= 0x00000040,		/* Accept Unicast FC Frame */
-	Rrf		= 0x00000080,		/* Reject Filter */
-};
-
-enum {						/* CAMctl */
-	Ce		= 0x00000001,		/* Enable */
-	Cms		= 0x00000002,		/* Mask Select */
-	Cr		= 0x00000004,		/* Read */
-	Cw		= 0x00000008,		/* Write */
-	CiMASK		= 0x003F0000,		/* Index Mask */
-	CiSHIFT		= 16,
-	Cbusy		= 0x80000000,		/* Busy */
-};
-
-enum {						/* CAMdhi */
-	Cv		= 0x00010000,		/* Valid */
-};
-
-enum {						/* EMACctl */
-	Eena		= 0x00000001,		/* Enable */
-	Edis		= 0x00000002,		/* Disable */
-	Erst		= 0x00000004,		/* Reset */
-	Eeps		= 0x00000008,		/* External PHY Select */
-};
-
-enum {						/* MIBctl */
-	MIBcor		= 0x00000001,		/* Clear On Read */
-};
-
-enum {						/* SonicsBackplane Registers */
-	SBs2pci2	= 0x0108,		/* Sonics to PCI translation */
-	SBias		= 0x0F90,		/* Initiator Agent State */
-	SBim		= 0x0F94,		/* Interrupt Mask */
-	SBtslo		= 0x0F98,		/* Target State Low */
-	SBtshi		= 0x0F9C,		/* Target State High */
-};
-
-enum {						/* SBs2pci2 */
-	Spref		= 0x00000004,		/* Prefetch Enable */
-	Sburst		= 0x00000008,		/* Burst Enable */
-};
-
-enum {						/* SBias */
-	Sibe		= 0x00020000,		/* In-Band Error */
-	Sto		= 0x00040000,		/* Timeout */
-};
-
-enum {						/* SBim */
-	Senet0		= 0x00000002,		/* Ethernet 0 */
-};
-
-enum {						/* SBtslo */
-	Sreset		= 0x00000001,		/*  */
-	Sreject		= 0x00000002,		/*  */
-	Sclock		= 0x00010000,		/*  */
-	Sfgc		= 0x00020000,		/* Force Gated Clocks On */
-};
-
-enum {						/* SBtshi */
-	Sserr		= 0x00000001,		/*  */
-	Sbusy		= 0x00000004,		/*  */
-};
-
-// dma descriptor. must be 4096 aligned and fit in single 4096 page.
-// rx and tx descriptors can't share the same page apparently so we'll
-// have to malloc that even though we don't use it all.
-// descriptors are only ever read by the nic, not written back.
-typedef struct {
-	uint32_t	control;
-	uint32_t	address;
-} DD;
-
-enum {						/* DD.control */
-	DDbbcMASK	= 0x00001FFF,		/* Buffer Byte Count */
-	DDbbcSHIFT	= 0,
-	DDeot		= 0x10000000,		/* End of Descriptor Table */
-	DDioc		= 0x20000000,		/* Interrupt on Completion */
-	DDeof		= 0x40000000,		/* End of Frame */
-	DDsof		= 0x80000000,		/* Start of Frame */
-};
-
-// the core returns 8 bytes - 4 bytes length and status
-// and 4 bytes undefined.
-// so we pad for alignment of the data...? but why in the struct
-// since the offset is defined in a register and the struct is
-// 28 and the offset is usually set to 30?
-// bollocks. it looks to me like the status written is 28 bytes.
-typedef struct {
-	uint32_t	status;
-	uint32_t	undefined;
-	uint32_t	pad[5];
-
-	void*	bp;				/* software */
-
-	uint8_t	data[];				/* flexible array member... */
-} H;
-
-enum {						/* H.status */
-	HflMASK		= 0x0000FFFF,		/* Frame Length */
-	HflSHIFT	= 0,
-	Hfo		= 0x00010000,		/* FIFO Overflow */
-	Hce		= 0x00020000,		/* CRC Error */
-	Hse		= 0x00040000,		/* Symbol Error */
-	Hodd		= 0x00080000,		/* Odd Number of Nibbles */
-	Hl		= 0x00100000,		/* Frame too Large */
-	Hmf		= 0x00200000,		/* Multicast Frame */
-	Hbf		= 0x00400000,		/* Broadcast Frame */
-	Hpf		= 0x00800000,		/* Promiscuous Frame */
-	Hlbf		= 0x08000000,		/* Last Buffer in Frame */
-};
-
-enum {
-	Ncam		= 64,
-	Nmib		= 55,
-
-	SBPCIWADDR	= 0x40000000,
-
-	Nrd		= 8,
-	Ntd		= 8,
-
-	Rbhsz		= sizeof(H),		/* 28 + space for a pointer */
-	Rbdsz		= 1522+Rbhsz,
-};
-
-typedef struct Ctlr Ctlr;
-typedef struct Ctlr {
-	uint32_t	port;
-	Pcidev*	pcidev;
-	Ctlr*	next;
-	int	active;
-	int	id;
-	uint8_t	pa[Eaddrlen];
-
-	void*	nic;
-
-	QLock	alock;				/* attach */
-	void*	alloc;				/*  */
-
-	uint32_t	im;
-	uint32_t	rcr;
-
-	Lock	tlock;				/* transmit */
-	DD*	td;				/* descriptor ring */
-	Block**	tb;				/* transmit buffers */
-	int	ntd;
-
-	int	tdh;				/* head - producer index (host) */
-	int	tdt;				/* tail - consumer index (NIC) */
-	int	ntdfree;
-	int	ntq;
-
-	Lock	rlock;				/* receive */
-	DD*	rd;				/* descriptor ring */
-	void**	rb;				/* receive buffers */
-	int	nrd;
-
-	int	rdh;				/* head - producer index (NIC) */
-	int	rdt;				/* tail - consumer index (host) */
-	int	nrdfree;
-
-
-	DD*	tddr;
-
-	Mii*	mii;
-
-	uint	intr;				/* statistics */
-	uint	lintr;
-	uint	lsleep;
-	uint	rintr;
-	uint	tintr;
-
-	uint	txdu;
-
-	uint	mib[Nmib];
-} Ctlr;
-
-#define csr8r(c, r)	(*((uint8_t*)((c)->nic)+(r)))
-#define csr16r(c, r)	(*((uint16_t*)((c)->nic)+((r)/2)))
-#define csr32p(c, r)	((uint32_t*)((c)->nic)+((r)/4))
-#define csr32r(c, r)	(*csr32p(c, r))
-#define csr32w(c, r, v)	(*csr32p(c, r) = (v))
-#define csr32a(c, r)	{ uint32_t dummy = csr32r(c, r); USED(dummy);}
-// hmmm. maybe we need a csr32wrb instead, write and read back?
-
-static Ctlr* bcm4401ctlrhead;
-static Ctlr* bcm4401ctlrtail;
-
-static char* statistics[Nmib] = {
-	"Tx Good Octets",
-	"Tx Good Pkts",
-	"Tx Octets",
-	"Tx Pkts",
-	"Tx Broadcast Pkts",
-	"Tx Multicast Pkts",
-	"Tx (64)",
-	"Tx (65-127)",
-	"Tx (128-255)",
-	"Tx (256-511)",
-	"Tx (512-1023)",
-	"Tx (1024-max)",
-	"Tx Jabber Pkts",
-	"Tx Oversize Pkts",
-	"Tx Fragment Pkts",
-	"Tx Underruns",
-	"Tx Total Cols",
-	"Tx Single Cols",
-	"Tx Multiple Cols",
-	"Tx Excessive Cols",
-	"Tx Late Cols",
-	"Tx Defered",
-	"Tx Carrier Lost",
-	"Tx Pause Pkts",
-
-	nil,
-	nil,
-	nil,
-	nil,
-	nil,
-	nil,
-	nil,
-	nil,
-
-	"Rx Good Octets",
-	"Rx Good Pkts",
-	"Rx Octets",
-	"Rx Pkts",
-	"Rx Broadcast Pkts",
-	"Rx Multicast Pkts",
-	"Rx (64)",
-	"Rx (65-127)",
-	"Rx (128-255)",
-	"Rx (256-511)",
-	"Rx (512-1023)",
-	"Rx (1024-Max)",
-	"Rx Jabber Pkts",
-	"Rx Oversize Pkts",
-	"Rx Fragment Pkts",
-	"Rx Missed Pkts",
-	"Rx CRC Align Errs",
-	"Rx Undersize",
-	"Rx CRC Errs",
-	"Rx Align Errs",
-	"Rx Symbol Errs",
-	"Rx Pause Pkts",
-	"Rx Non-pause Pkts",
-};
-
-static void
-bcm4401mib(Ctlr* ctlr, uint* mib)
-{
-	int i;
-	uint32_t r;
-
-	csr32w(ctlr, MIBctl, MIBcor);
-	for(i = 0; i < Nmib; i++){
-		r = csr32r(ctlr, MIB+i*sizeof(uint32_t));
-		if(mib == nil)
-			continue;
-		if(statistics[i] != nil)
-			*mib += r;
-		mib++;
-	}
-}
-
-static int32_t
-bcm4401ifstat(Ether* edev, void* a, int32_t n, uint32_t offset)
-{
-	char *p;
-	Ctlr *ctlr;
-	int i, l, r;
-
-	ctlr = edev->ctlr;
-
-	p = malloc(2*READSTR);
-	l = 0;
-	l += snprint(p+l, 2*READSTR-l, "intr: %ud\n", ctlr->intr);
-	l += snprint(p+l, 2*READSTR-l, "lintr: %ud\n", ctlr->lintr);
-	l += snprint(p+l, 2*READSTR-l, "lsleep: %ud\n", ctlr->lsleep);
-	l += snprint(p+l, 2*READSTR-l, "rintr: %ud\n", ctlr->rintr);
-	l += snprint(p+l, 2*READSTR-l, "tintr: %ud\n", ctlr->tintr);
-
-	if(ctlr->mii != nil && ctlr->mii->curphy != nil){
-		l += snprint(p+l, 2*READSTR, "phy:   ");
-		for(i = 0; i < NMiiPhyr; i++){
-			if(i && ((i & 0x07) == 0))
-				l += snprint(p+l, 2*READSTR-l, "\n       ");
-			r = miimir(ctlr->mii, i);
-			l += snprint(p+l, 2*READSTR-l, " %4.4ux", r);
-		}
-		snprint(p+l, 2*READSTR-l, "\n");
-	}
-	snprint(p+l, 2*READSTR-l, "\n");
-
-	n = readstr(offset, a, n, p);
-	free(p);
-
-	return n;
-}
-
-static void
-_bcm4401promiscuous(Ctlr* ctlr, int on)
-{
-	uint32_t r;
-
-	r = csr32r(ctlr, CAMctl);
-	if(on){
-		ctlr->rcr |= Rpe;
-		r &= ~Ce;
-	}
-	else{
-		ctlr->rcr &= ~Rpe;
-		r |= Ce;
-	}
-	csr32w(ctlr, Rxcfg, ctlr->rcr);
-	csr32w(ctlr, CAMctl, r);
-}
-
-static void
-bcm4401promiscuous(void* arg, int on)
-{
-	_bcm4401promiscuous(((Ether*)arg)->ctlr, on);
-}
-
-static void
-bcm4401multicast(void* arg, uint8_t* addr, int on)
-{
-	USED(arg, addr, on);
-}
-
-static void
-bcm4401attach(Ether* edev)
-{
-	Ctlr *ctlr;
-
-	ctlr = edev->ctlr;
-	qlock(&ctlr->alock);
-	if(ctlr->alloc != nil){
-		qunlock(&ctlr->alock);
-		return;
-	}
-
-	if(waserror()){
-		nexterror();
-	}
-
-	qunlock(&ctlr->alock);
-	poperror();
-}
-
-static void
-bcm4401transmit(Ether* edev)
-{
-	DD *d;
-	Block *bp;
-	Ctlr *ctlr;
-	int control, s, tdh, tdt;
-	RingBuf *ring;
-
-	ctlr = edev->ctlr;
-
-	ilock(&ctlr->tlock);
-	s = csr32r(ctlr, TDMAstatus);
-	tdt = ((s & DcdMASK) >> DcdSHIFT)/sizeof(DD);
-	for(tdh = ctlr->tdh; tdh != tdt; tdh = NEXT(tdh, ctlr->ntd)){
-		d = &ctlr->td[tdh];
-
-		/*
-		 * Check errors and log here.
-		 */
-		SET(control);
-		USED(control);
-		// seems to be no way to tell whether the packet
-		// went out or not or had errors?
-
-		/*
-		 * Free it up.
-		 * Need to clean the descriptor here? Not really.
-		 * Simple freeb for now (no chain and freeblist).
-		 * Use ntq count for now.
-		 */
-		freeb(ctlr->tb[tdh]);
-		ctlr->tb[tdh] = nil;
-		d->control &= DDeot;
-		d->address = 0;
-
-		ctlr->ntq--;
-	}
-	ctlr->tdh = tdh;
-
-	tdt = ctlr->tdt;
-	while(ctlr->ntq < (ctlr->ntd-1)){
-		ring = &edev->tb[edev->ti];
-		if(ring->owner != Interface)
-			break;
-
-		bp = allocb(ring->len);
-		memmove(bp->wp, ring->pkt, ring->len);
-		memmove(bp->wp+Eaddrlen, edev->ea, Eaddrlen);
-		bp->wp += ring->len;
-
-		ring->owner = Host;
-		edev->ti = NEXT(edev->ti, edev->ntb);
-
-		d = &ctlr->td[tdt];
-		d->address = PCIWADDR(bp->rp) + SBPCIWADDR;
-		ctlr->tb[tdt] = bp;
-		wmb();
-		d->control |= DDsof|DDeof|((BLEN(bp)<<DDbbcSHIFT) & DDbbcMASK);
-d->control |= DDioc;
-
-		tdt = NEXT(tdt, ctlr->ntd);
-		ctlr->ntq++;
-	}
-	if(tdt != ctlr->tdt){
-		ctlr->tdt = tdt;
-		csr32w(ctlr, TDMAld, tdt*sizeof(DD));
-	}
-	else if(ctlr->ntq >= (ctlr->ntd-1))
-		ctlr->txdu++;
-
-	iunlock(&ctlr->tlock);
-}
-
-static void
-bcm4401replenish(Ctlr* ctlr)
-{
-	DD *d;
-	int rdt;
-	void *bp;
-	H* h;
-
-	rdt = ctlr->rdt;
-	while(NEXT(rdt, ctlr->nrd) != ctlr->rdh){
-		d = &ctlr->rd[rdt];
-		if((bp = ctlr->rb[rdt]) == nil){
-			/*
-			 * simple allocation for now
-			 */
-			bp = malloc(Rbdsz);
-			ctlr->rb[rdt] = bp;
-		}
-		d->address = PCIWADDR(bp) + SBPCIWADDR;
-		d->control |= (((Rbdsz-Rbhsz)<<DDbbcSHIFT) & DDbbcMASK);
-		h = ctlr->rb[rdt];
-		h->status = 0;
-		h->bp = bp;
-		wmb();
-		rdt = NEXT(rdt, ctlr->nrd);
-		ctlr->nrdfree++;
-	}
-	ctlr->rdt = rdt;
-}
-
-static void
-bcm4401receive(Ether* edev)
-{
-	DD *d;
-	H* h;
-	uint8_t *p;
-	int len, rdh, rdt, s;
-	Ctlr *ctlr;
-	uint32_t status;
-	RingBuf *ring;
-
-	ctlr = edev->ctlr;
-
-	s = csr32r(ctlr, RDMAstatus);
-	rdt = ((s & DcdMASK) >> DcdSHIFT)/sizeof(DD);
-
-	for(rdh = ctlr->rdh; rdh != rdt; rdh = NEXT(rdh, ctlr->nrd)){
-		d = &ctlr->rd[rdh];
-		h = ctlr->rb[rdh];
-		p = h->data;
-
-		status = h->status;
-		len = ((status & HflMASK)>>HflSHIFT);
-		if(len == 0 ||len >(Rbdsz-Rbhsz))
-			continue;
-		if(!(status & (Hl|Hodd|Hse|Hce|Hfo))){
-			ring = &edev->rb[edev->ri];
-			if(ring->owner == Interface){
-				ring->owner = Host;
-				ring->len = len;
-				memmove(ring->pkt, p, len-4);
-				edev->ri = NEXT(edev->ri, edev->nrb);
-			}
-		}
-		else{
-			/*
-			 * Error stuff here.
-			print("status %8.8uX\n", status);
-			 */
-		}
-		h->status = 0;
-		d->address = 0;
-		d->control &= DDeot;
-		ctlr->nrdfree--;
-	}
-	ctlr->rdh = rdh;
-
-	if(ctlr->nrdfree < ctlr->nrd/2)
-		bcm4401replenish(ctlr);
-}
-
-static void
-bcm4401interrupt(Ureg*, void* arg)
-{
-	Ctlr *ctlr;
-	Ether *edev;
-	uint32_t im, is;
-
-	edev = arg;
-	ctlr = edev->ctlr;
-
-	ctlr->intr++;
-	for(;;){
-		is = csr32r(ctlr, Bis);
-		im = csr32r(ctlr, Bim);
-		is &= im;
-		if(is == 0)
-			break;
-		csr32w(ctlr, Bis, is);
-		csr32a(ctlr, Bis);
-
-		if(is & Ir)
-			bcm4401receive(edev);
-		if(is & It)
-			bcm4401transmit(edev);
-		if(is & ~(It|Ir))
-			panic("is %ux\n", is);
-	}
-}
-
-static int
-bcm4401spin(u32int* csr32, int bit, int set, int µs)
-{
-	int t;
-	u32int r;
-
-	if(µs < 10)
-		µs = 10;
-
-	for(t = 0; t < µs; t += 10){
-		r = *csr32;
-		if(set){
-			if(r & bit)
-				return 0;
-		}
-		else if(!(r & bit))
-			return 0;
-
-		microdelay(10);
-	}
-
-	return -1;
-}
-
-static void
-bcm4401cam(Ctlr* ctlr, int cvix, uint8_t* a)
-{
-	csr32w(ctlr, CAMdlo, (a[2]<<24)|(a[3]<<16)|(a[4]<<8)|a[5]);
-	csr32w(ctlr, CAMdhi, (cvix & Cv)|(a[0]<<8)|a[1]);
-	csr32w(ctlr, CAMctl, ((cvix<<CiSHIFT) & CiMASK)|Cw);
-	bcm4401spin(csr32p(ctlr, CAMctl), Cbusy, 0, 1000);
-}
-
-static void
-bcm4401sbreset(Ctlr* ctlr)
-{
-	uint32_t bar0, r;
-
-	/*
-	 * If the core is running, stop it.
-	 */
-	r = csr32r(ctlr, SBtslo);
-	if((r & (Sclock|Sreject|Sreset)) == Sclock){
-		csr32w(ctlr, Blictl, 0);
-		csr32w(ctlr, EMACctl, Edis);
-		bcm4401spin(csr32p(ctlr, EMACctl), Edis, 0, 1000);
-
-		csr32w(ctlr, TDMActl, 0);
-
-		r = csr32r(ctlr, RDMAstatus);
-		if(r & Dem)
-			bcm4401spin(csr32p(ctlr, RDMAstatus), Didle, 1, 1000);
-		csr32w(ctlr, RDMActl, 0);
-
-		csr32w(ctlr, EMACctl, Erst);
-	}
-	else{
-		// set up sonic pci
-		// reg80 holds the window space accessed - 0x18000000 is
-		// the emac, 0x18002000 are the pci registers
-		bar0 = pcicfgr32(ctlr->pcidev, 0x80);
-		pcicfgw32(ctlr->pcidev, 0x80, 0x18002000);
-
-		r = pcicfgr32(ctlr->pcidev, SBim);
-		r |= Senet0;
-		pcicfgw32(ctlr->pcidev, SBim, r);
-
-		r = pcicfgr32(ctlr->pcidev, SBs2pci2);
-		r |= Sburst|Spref;
-		pcicfgw32(ctlr->pcidev, SBs2pci2, r);
-
-		pcicfgw32(ctlr->pcidev, 0x80, bar0);
-	}
-
-	// disable core
-	// must return if core is already in reset
-	// set the reject bit
-	// spin until reject is set
-	// spin until sbtmstatehigh.busy is clear
-	// set reset and reject while enabling the clocks
-	// leave reset and reject asserted
-	r = csr32r(ctlr, SBtslo);
-	if(!(r & Sreset)){
-		csr32w(ctlr, SBtslo, Sclock|Sreject);
-		bcm4401spin(csr32p(ctlr, SBtslo), Sreject, 1, 1000000);
-		bcm4401spin(csr32p(ctlr, SBtshi), Sbusy, 0, 1000000);
-
-		csr32w(ctlr, SBtslo, Sfgc|Sclock|Sreject|Sreset);
-		csr32a(ctlr, SBtslo);
-		microdelay(10);
-
-		csr32w(ctlr, SBtslo, Sreject|Sreset);
-		microdelay(10);
-	}
-
-	// core reset - initialisation, surely?
-	/*
-	 * Now do the initialization sequence.
-	 */
-	// set reset while enabling the clock and forcing them on
-	// throughout the core
-	// clear any error bits that may be o
-	// clear reset and allow it to propagate throughout the core
-	// leave clock enabled
-	csr32w(ctlr, SBtslo, Sfgc|Sclock|Sreset);
-	csr32a(ctlr, SBtslo);
-	microdelay(1);
-	if(csr32r(ctlr, SBtshi) & Sserr)
-		csr32w(ctlr, SBtshi, 0);
-	r = csr32r(ctlr, SBias);
-	if(r & (Sto|Sibe))
-		csr32w(ctlr, SBias, r & ~(Sto|Sibe));
-	csr32w(ctlr, SBtslo, Sfgc|Sclock);
-	csr32a(ctlr, SBtslo);
-	microdelay(1);
-	csr32w(ctlr, SBtslo, Sclock);
-	csr32a(ctlr, SBtslo);
-	microdelay(1);
-}
-
-static int
-bcm4401detach(Ctlr* ctlr)
-{
-	/*
-	 * Soft reset the controller.
-	 */
-	bcm4401sbreset(ctlr);
-
-	// need to clean up software state somewhere
-
-	return 0;
-}
-
-static int
-bcm4401init(Ctlr* ctlr)
-{
-	uint32_t r;
-
-	// Clear the stats on reset.
-	bcm4401mib(ctlr, nil);
-
-	// Enable CRC32, set proper LED modes and power on PHY
-	csr32w(ctlr, Bmctl, ((7<<MlcSHIFT) & MlcMASK)|Mcge);
-	csr32w(ctlr, Blictl, ((1<<MfcSHIFT) & MfcMASK));
-
-	// is this the max length of a packet or the max length of the buffer?
-	// packet is 1522 (mtu+header+crc+vlantag = 1522), buffer is that +30
-	// for prepended rx header
-	csr32w(ctlr, Rxmax, Rbdsz);
-	csr32w(ctlr, Txmax, 1522);
-	// no explanation of this anywhere
-	csr32w(ctlr, EMACtxwmark, 56);
-
-	// this is software init - elsewhere before this (attach?)
-	ctlr->ntd = Ntd;
-	ctlr->td = mallocalign(4096/*sizeof(DD)*ctlr->ntd*/, 4096, 0, 0);
-	ctlr->td[ctlr->ntd-1].control = DDeot;
-	ctlr->tdh = ctlr->tdt = 0;
-	ctlr->tb = malloc(ctlr->ntd*sizeof(Block*));
-	ctlr->ntq = 0;
-
-	// ring dma address is the phys address of the rx ring
-	// plus where the sb core sees the phys memory base
-	csr32w(ctlr, TDMAra, PCIWADDR(ctlr->td)+SBPCIWADDR);
-	csr32w(ctlr, TDMActl, Te);
-
-	// this is software init - elsewhere (attach?)
-	ctlr->nrd = Nrd;
-	ctlr->rd = mallocalign(4096/*sizeof(DD)*ctlr->nrd*/, 4096, 0, 0);
-	ctlr->rd[ctlr->nrd-1].control = DDeot;
-	ctlr->rdh = ctlr->rdt = 0;
-	ctlr->rb = malloc(ctlr->nrd*sizeof(void*));
-	bcm4401replenish(ctlr);
-
-	csr32w(ctlr, RDMAra, PCIWADDR(ctlr->rd)+SBPCIWADDR);
-	csr32w(ctlr, RDMAld, 0);
-
-	// pre-packet header (usually 30)
-	csr32w(ctlr, RDMActl, ((Rbhsz<<RfoSHIFT) & RfoMASK)|Re);
-	csr32w(ctlr, RDMAld, (ctlr->nrd)*sizeof(DD));
-
-	// this is done in mib read too - only need once
-	csr32w(ctlr, MIBctl, MIBcor);
-
-	// EMACctl? ENETctl?
-	r = csr32r(ctlr, EMACctl);
-	csr32w(ctlr, EMACctl, Eena|r);
-
-	return 0;
-}
-
-static int
-bcm4401miimir(Mii* mii, int pa, int ra)
-{
-	uint32_t r;
-	int timeo;
-	Ctlr *ctlr;
-
-	ctlr = mii->ctlr;
-
-	csr32w(ctlr, MDIOstatus, 1);
-	csr32w(ctlr, MDIOdata, Msof|Mrop|(pa<<23)|(ra<<18)|Mack);
-	for(r = timeo = 0; timeo < 100; timeo++){
-		if((r = csr32r(ctlr, MDIOstatus)) & Mmi)
-			break;
-		microdelay(10);
-	}
-	if(!(r & Mmi))
-		return -1;
-
-	return csr32r(ctlr, MDIOdata) & 0xFFFF;
-}
-
-static int
-bcm4401miimiw(Mii* mii, int pa, int ra, int data)
-{
-	uint32_t r;
-	int timeo;
-	Ctlr *ctlr;
-
-	ctlr = mii->ctlr;
-
-	csr32w(ctlr, MDIOstatus, 1);
-	csr32w(ctlr, MDIOdata, Msof|Mwop|(pa<<23)|(ra<<18)|Mack|data);
-	for(r = timeo = 0; timeo < 100; timeo++){
-		if((r = csr32r(ctlr, MDIOstatus)) & Mmi)
-			break;
-		microdelay(10);
-	}
-	if(!(r & Mmi))
-		return -1;
-
-	return csr32r(ctlr, MDIOdata) & 0xFFFF;
-}
-
-static int
-bcm4401reset(Ctlr* ctlr)
-{
-	int i;
-	uint32_t r;
-	MiiPhy *phy;
-	uint8_t ea[Eaddrlen];
-
-	// disable ints - here or where?
-	csr32w(ctlr, Bim, 0);
-	csr32a(ctlr, Bim);
-
-	if(bcm4401detach(ctlr) < 0)
-		return -1;
-
-	// make the phy accessible; depends on internal/external.
-	csr32w(ctlr, MDIOctl, Mpe|Mfreq);
-	r = csr32r(ctlr, Bdctl);
-	if(!(r & Bipp))
-		csr32w(ctlr, EMACctl, Eeps);
-	else if(r & Bepr){
-		csr32w(ctlr, Bdctl, r & ~Bepr);
-		microdelay(100);
-	}
-
-	/*
-	 * Read the MAC address.
-	 */
-	for(i = 0; i < Eaddrlen; i += 2){
-		ctlr->pa[i] = csr8r(ctlr, Eao+i+1);
-		ctlr->pa[i+1] = csr8r(ctlr, Eao+i);
-	}
-
-	// initialise the mac address and cam
-	bcm4401cam(ctlr, Cv|0, ctlr->pa);
-	memset(ea, 0, Eaddrlen);
-	for(i = 1; i < Ncam; i++)
-		bcm4401cam(ctlr, i, ea);
-
-	// default initial Rxcfg. set Rxcfg reg here? call promiscuous?
-	ctlr->rcr = 0/*Raam*/;
-
-	bcm4401init(ctlr);
-
-	_bcm4401promiscuous(ctlr, 0);
-
-	// default initial interrupt mask.
-	ctlr->im = Ierror|It|Ir|Igpt;
-	csr32w(ctlr, Bim, ctlr->im);
-	csr32a(ctlr, Bim);
-
-	/*
-	 * Link management.
-	 */
-	if((ctlr->mii = malloc(sizeof(Mii))) == nil)
-		return -1;
-	ctlr->mii->mir = bcm4401miimir;
-	ctlr->mii->miw = bcm4401miimiw;
-	ctlr->mii->ctlr = ctlr;
-
-	/*
-	 * Read the PHY address.
-	 */
-	r = csr8r(ctlr, Pao);
-	r = 1<<(r & 0x1F);
-	if(mii(ctlr->mii, r) == 0 || (phy = ctlr->mii->curphy) == nil){
-		free(ctlr->mii);
-		ctlr->mii = nil;
-		return -1;
-	}
-	miireset(ctlr->mii);
-
-	// need to do some phy-specific init somewhere - why not here?
-	// enable activity led
-	i = miimir(ctlr->mii, 26);
-	miimiw(ctlr->mii, 26, i & 0x7FFF);
-	// enable traffic meter led mode
-	i = miimir(ctlr->mii, 27);
-	miimiw(ctlr->mii, 27, i|0x0040);
-
-	print("oui %#ux phyno %d\n", phy->oui, phy->phyno);
-
-	// need to set rxconfig before this and then call promiscuous
-	// later once we know the link settings
-	// By default, auto-negotiate PAUSE
-	miiane(ctlr->mii, ~0, ~0, ~0);
-	// set rcr according to pause, etc.
-
-	return 0;
-}
-
-static void
-bcm4401pci(void)
-{
-	Pcidev *p;
-	Ctlr *ctlr;
-	int i, port;
-	uint32_t bar;
-
-	p = nil;
-	while(p = pcimatch(p, 0, 0)){
-		if(p->ccrb != 0x02 || p->ccru != 0)
-			continue;
-
-		switch((p->did<<16)|p->vid){
-		default:
-			continue;
-		case (0x170C<<16)|0x14E4:	/* BCM4401-B0 */
-		case (0x4401<<16)|0x14E4:	/* BCM4401 */
-		case (0x4402<<16)|0x14E4:	/* BCM440? */
-			break;
-		}
-
-		bar = p->mem[0].bar;
-		if(bar & 0x01){
-			port = bar & ~0x01;
-			if(ioalloc(port, p->mem[0].size, 0, "bcm4401") < 0){
-				print("bcm4401: port %#ux in use\n", port);
-				continue;
-			}
-		}
-		else{
-			port = upamalloc(bar & ~0x0F, p->mem[0].size, 0);
-			if(port == 0){
-				print("bcm4401: can't map %#ux\n", bar);
-				continue;
-			}
-		}
-		ctlr = malloc(sizeof(Ctlr));
-		ctlr->port = port;
-		ctlr->pcidev = p;
-		ctlr->id = (p->did<<16)|p->vid;
-		ctlr->nic = KADDR(ctlr->port);
-
-		if(pcigetpms(p) > 0){
-			pcisetpms(p, 0);
-
-			for(i = 0; i < 6; i++)
-				pcicfgw32(p, PciBAR0+i*4, p->mem[i].bar);
-			pcicfgw8(p, PciINTL, p->intl);
-			pcicfgw8(p, PciLTR, p->ltr);
-			pcicfgw8(p, PciCLS, p->cls);
-			pcicfgw16(p, PciPCR, p->pcr);
-		}
-
-		if(bcm4401reset(ctlr)){
-			if(bar & 0x01){
-				/* may be empty... */
-				iofree(port);
-			}
-			else
-				upafree(port, p->mem[0].size);
-			free(ctlr);
-			continue;
-		}
-		pcisetbme(p);
-
-		if(bcm4401ctlrhead != nil)
-			bcm4401ctlrtail->next = ctlr;
-		else
-			bcm4401ctlrhead = ctlr;
-		bcm4401ctlrtail = ctlr;
-	}
-}
-
-static int
-bcm4401pnp(Ether* edev)
-{
-	Ctlr *ctlr;
-
-	if(bcm4401ctlrhead == nil)
-		bcm4401pci();
-
-	/*
-	 * Any adapter matches if no edev->port is supplied,
-	 * otherwise the ports must match.
-	 */
-	for(ctlr = bcm4401ctlrhead; ctlr != nil; ctlr = ctlr->next){
-		if(ctlr->active)
-			continue;
-		if(edev->port == 0 || edev->port == ctlr->port){
-			ctlr->active = 1;
-			break;
-		}
-	}
-	if(ctlr == nil)
-		return -1;
-
-	edev->ctlr = ctlr;
-	edev->port = ctlr->port;
-	edev->irq = ctlr->pcidev->intl;
-	edev->tbdf = ctlr->pcidev->tbdf;
-	edev->mbps = 100;
-
-	memmove(edev->ea, ctlr->pa, Eaddrlen);
-
-	/*
-	 * Linkage to the generic ethernet driver.
-	 */
-	edev->attach = bcm4401attach;
-	edev->transmit = bcm4401transmit;
-	edev->interrupt = bcm4401interrupt;
-//TODO	edev->detach = bcm4401detach;
-	edev->ifstat = bcm4401ifstat;
-	edev->ctl = nil;
-
-	edev->arg = edev;
-	edev->promiscuous = bcm4401promiscuous;
-	edev->multicast = bcm4401multicast;
-
-	return 0;
-}
-
-void
-etherbcm4401link(void)
-{
-	addethercard("bcm4401", bcm4401pnp);
-}
-
-int
-etherbcm4401pnp(Ether* edev)
-{
-	return bcm4401pnp(edev);
-}

+ 0 - 57
sys/src/9/w/pxeload/etherif.h

@@ -1,57 +0,0 @@
-/* 
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
-
-typedef struct RingBuf {
-	uchar	owner;
-	uchar	unused;
-	ushort	len;
-	uchar	pkt[sizeof(Etherpkt)];
-} RingBuf;
-
-enum {
-	Host		= 0,		/* buffer owned by host */
-	Interface	= 1,		/* buffer owned by card */
-
-	Nrb		= 32,		/* default number of receive buffers */
-	Ntb		= 8,		/* default number of transmit buffers */
-};
-
-typedef struct Ether Ether;
-struct Ether {
-	ISAConf;			/* hardware info */
-	int	ctlrno;
-	int	state;
-	int	tbdf;
-
-	void	(*attach)(Ether*);	/* filled in by reset routine */
-	void	(*transmit)(Ether*);
-	void	(*interrupt)(Ureg*, void*);
-	void	(*detach)(Ether*);
-	void	*ctlr;
-
-	ushort	nrb;			/* number of software receive buffers */
-	ushort	ntb;			/* number of software transmit buffers */
-	RingBuf *rb;			/* software receive buffers */
-	RingBuf *tb;			/* software transmit buffers */
-
-	ushort	rh;			/* first receive buffer belonging to host */
-	ushort	ri;			/* first receive buffer belonging to card */
-
-	ushort	th;			/* first transmit buffer belonging to host */
-	ushort	ti;			/* first transmit buffer belonging to card */
-	int	tbusy;			/* transmitter is busy */
-
-	Netif;
-};
-
-extern void etherrloop(Ether*, Etherpkt*, long);
-extern void addethercard(char*, int(*)(Ether*));
-
-#define NEXT(x, l)	(((x)+1)%(l))
-#define PREV(x, l)	(((x) == 0) ? (l)-1: (x)-1)

+ 0 - 1728
sys/src/9/w/pxeload/etherigbe.c

@@ -1,1728 +0,0 @@
-/*
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
-
-/*
- * bootstrap driver for
- * Intel RS-82543GC Gigabit Ethernet Controller
- * as found on the Intel PRO/1000[FT] Server Adapter.
- * The older non-[FT] cards use the 82542 (LSI L2A1157) chip; no attempt
- * is made to handle the older chip although it should be possible.
- *
- * updated just enough to cope with the
- * Intel 8254[0347]NN Gigabit Ethernet Controller
- * as found on the Intel PRO/1000 series of adapters:
- *	82540EM Intel PRO/1000 MT
- *	82543GC	Intel PRO/1000 T
- *	82544EI Intel PRO/1000 XT
- *	82547EI built-in
- *
- * The datasheet is not very clear about running on a big-endian system
- * and this driver assumes little-endian throughout.
- * To do:
- *	GMII/MII
- *	check recovery from receive no buffers condition
- *	automatic ett adjustment
- */
-#include "u.h"
-#include "lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-
-#include "etherif.h"
-#include "ethermii.h"
-
-enum {
-	i82542     = (0x1000<<16)|0x8086,
-	i82543gc   = (0x1004<<16)|0x8086,
-	i82544ei   = (0x1008<<16)|0x8086,
-	i82540em   = (0x100E<<16)|0x8086,
-	i82546eb   = (0x1010<<16)|0x8086,
-	i82547ei   = (0x1019<<16)|0x8086,
-	i82540eplp = (0x101E<<16)|0x8086,
-	i82547gi   = (0x1075<<16)|0x8086,
-	i82541gi   = (0x1076<<16)|0x8086,
-	i82546gb   = (0x1079<<16)|0x8086,
-	i82541pi   = (0x107c<<16)|0x8086,
-};
-
-/* compatibility with cpu kernels */
-#define iallocb allocb
-#ifndef CACHELINESZ
-#define CACHELINESZ	32		/* pentium & later */
-#endif
-
-/* from pci.c */
-enum
-{					/* command register (pcidev->pcr) */
-	IOen		= (1<<0),
-	MEMen		= (1<<1),
-	MASen		= (1<<2),
-	MemWrInv	= (1<<4),
-	PErrEn		= (1<<6),
-	SErrEn		= (1<<8),
-};
-enum {
-	Ctrl		= 0x00000000,	/* Device Control */
-	Status		= 0x00000008,	/* Device Status */
-	Eecd		= 0x00000010,	/* EEPROM/Flash Control/Data */
-	Ctrlext		= 0x00000018,	/* Extended Device Control */
-	Mdic		= 0x00000020,	/* MDI Control */
-	Fcal		= 0x00000028,	/* Flow Control Address Low */
-	Fcah		= 0x0000002C,	/* Flow Control Address High */
-	Fct		= 0x00000030,	/* Flow Control Type */
-	Icr		= 0x000000C0,	/* Interrupt Cause Read */
-	Ics		= 0x000000C8,	/* Interrupt Cause Set */
-	Ims		= 0x000000D0,	/* Interrupt Mask Set/Read */
-	Imc		= 0x000000D8,	/* Interrupt mask Clear */
-	Rctl		= 0x00000100,	/* Receive Control */
-	Fcttv		= 0x00000170,	/* Flow Control Transmit Timer Value */
-	Txcw		= 0x00000178,	/* Transmit Configuration Word */
-	Tctl		= 0x00000400,	/* Transmit Control */
-	Tipg		= 0x00000410,	/* Transmit IPG */
-	Tbt		= 0x00000448,	/* Transmit Burst Timer */
-	Ait		= 0x00000458,	/* Adaptive IFS Throttle */
-	Fcrtl		= 0x00002160,	/* Flow Control RX Threshold Low */
-	Fcrth		= 0x00002168,	/* Flow Control Rx Threshold High */
-	Rdbal		= 0x00002800,	/* Rdesc Base Address Low */
-	Rdbah		= 0x00002804,	/* Rdesc Base Address High */
-	Rdlen		= 0x00002808,	/* Receive Descriptor Length */
-	Rdh		= 0x00002810,	/* Receive Descriptor Head */
-	Rdt		= 0x00002818,	/* Receive Descriptor Tail */
-	Rdtr		= 0x00002820,	/* Receive Descriptor Timer Ring */
-	Rxdctl		= 0x00002828,	/* Receive Descriptor Control */
-	Radv		= 0x0000282C,	/* Receive Interrupt Absolute Delay Timer */
-	Txdmac		= 0x00003000,	/* Transfer DMA Control */
-	Ett		= 0x00003008,	/* Early Transmit Control */
-	Tdbal		= 0x00003800,	/* Tdesc Base Address Low */
-	Tdbah		= 0x00003804,	/* Tdesc Base Address High */
-	Tdlen		= 0x00003808,	/* Transmit Descriptor Length */
-	Tdh		= 0x00003810,	/* Transmit Descriptor Head */
-	Tdt		= 0x00003818,	/* Transmit Descriptor Tail */
-	Tidv		= 0x00003820,	/* Transmit Interrupt Delay Value */
-	Txdctl		= 0x00003828,	/* Transmit Descriptor Control */
-	Tadv		= 0x0000382C,	/* Transmit Interrupt Absolute Delay Timer */
-
-	Statistics	= 0x00004000,	/* Start of Statistics Area */
-	Gorcl		= 0x88/4,	/* Good Octets Received Count */
-	Gotcl		= 0x90/4,	/* Good Octets Transmitted Count */
-	Torl		= 0xC0/4,	/* Total Octets Received */
-	Totl		= 0xC8/4,	/* Total Octets Transmitted */
-	Nstatistics	= 64,
-
-	Rxcsum		= 0x00005000,	/* Receive Checksum Control */
-	Mta		= 0x00005200,	/* Multicast Table Array */
-	Ral		= 0x00005400,	/* Receive Address Low */
-	Rah		= 0x00005404,	/* Receive Address High */
-	Manc		= 0x00005820,	/* Management Control */
-};
-
-enum {					/* Ctrl */
-	Bem		= 0x00000002,	/* Big Endian Mode */
-	Prior		= 0x00000004,	/* Priority on the PCI bus */
-	Lrst		= 0x00000008,	/* Link Reset */
-	Asde		= 0x00000020,	/* Auto-Speed Detection Enable */
-	Slu		= 0x00000040,	/* Set Link Up */
-	Ilos		= 0x00000080,	/* Invert Loss of Signal (LOS) */
-	SspeedMASK	= 0x00000300,	/* Speed Selection */
-	SspeedSHIFT	= 8,
-	Sspeed10	= 0x00000000,	/* 10Mb/s */
-	Sspeed100	= 0x00000100,	/* 100Mb/s */
-	Sspeed1000	= 0x00000200,	/* 1000Mb/s */
-	Frcspd		= 0x00000800,	/* Force Speed */
-	Frcdplx		= 0x00001000,	/* Force Duplex */
-	SwdpinsloMASK	= 0x003C0000,	/* Software Defined Pins - lo nibble */
-	SwdpinsloSHIFT	= 18,
-	SwdpioloMASK	= 0x03C00000,	/* Software Defined Pins - I or O */
-	SwdpioloSHIFT	= 22,
-	Devrst		= 0x04000000,	/* Device Reset */
-	Rfce		= 0x08000000,	/* Receive Flow Control Enable */
-	Tfce		= 0x10000000,	/* Transmit Flow Control Enable */
-	Vme		= 0x40000000,	/* VLAN Mode Enable */
-};
-
-enum {					/* Status */
-	Lu		= 0x00000002,	/* Link Up */
-	Tckok		= 0x00000004,	/* Transmit clock is running */
-	Rbcok		= 0x00000008,	/* Receive clock is running */
-	Txoff		= 0x00000010,	/* Transmission Paused */
-	Tbimode		= 0x00000020,	/* TBI Mode Indication */
-	SpeedMASK	= 0x000000C0,
-	Speed10		= 0x00000000,	/* 10Mb/s */
-	Speed100	= 0x00000040,	/* 100Mb/s */
-	Speed1000	= 0x00000080,	/* 1000Mb/s */
-	Mtxckok		= 0x00000400,	/* MTX clock is running */
-	Pci66		= 0x00000800,	/* PCI Bus speed indication */
-	Bus64		= 0x00001000,	/* PCI Bus width indication */
-};
-
-enum {					/* Ctrl and Status */
-	Fd		= 0x00000001,	/* Full-Duplex */
-	AsdvMASK	= 0x00000300,
-	Asdv10		= 0x00000000,	/* 10Mb/s */
-	Asdv100		= 0x00000100,	/* 100Mb/s */
-	Asdv1000	= 0x00000200,	/* 1000Mb/s */
-};
-
-enum {					/* Eecd */
-	Sk		= 0x00000001,	/* Clock input to the EEPROM */
-	Cs		= 0x00000002,	/* Chip Select */
-	Di		= 0x00000004,	/* Data Input to the EEPROM */
-	Do		= 0x00000008,	/* Data Output from the EEPROM */
-	Areq		= 0x00000040,	/* EEPROM Access Request */
-	Agnt		= 0x00000080,	/* EEPROM Access Grant */
-	Eepresent	= 0x00000100,	/* EEPROM Present */
-	Eesz256		= 0x00000200,	/* EEPROM is 256 words not 64 */
-	Eeszaddr	= 0x00000400,	/* EEPROM size for 8254[17] */
-	Spi		= 0x00002000,	/* EEPROM is SPI not Microwire */
-};
-
-enum {					/* Ctrlext */
-	Gpien		= 0x0000000F,	/* General Purpose Interrupt Enables */
-	SwdpinshiMASK	= 0x000000F0,	/* Software Defined Pins - hi nibble */
-	SwdpinshiSHIFT	= 4,
-	SwdpiohiMASK	= 0x00000F00,	/* Software Defined Pins - I or O */
-	SwdpiohiSHIFT	= 8,
-	Asdchk		= 0x00001000,	/* ASD Check */
-	Eerst		= 0x00002000,	/* EEPROM Reset */
-	Ips		= 0x00004000,	/* Invert Power State */
-	Spdbyps		= 0x00008000,	/* Speed Select Bypass */
-};
-
-enum {					/* EEPROM content offsets */
-	Ea		= 0x00,		/* Ethernet Address */
-	Cf		= 0x03,		/* Compatibility Field */
-	Pba		= 0x08,		/* Printed Board Assembly number */
-	Icw1		= 0x0A,		/* Initialization Control Word 1 */
-	Sid		= 0x0B,		/* Subsystem ID */
-	Svid		= 0x0C,		/* Subsystem Vendor ID */
-	Did		= 0x0D,		/* Device ID */
-	Vid		= 0x0E,		/* Vendor ID */
-	Icw2		= 0x0F,		/* Initialization Control Word 2 */
-};
-
-enum {					/* Mdic */
-	MDIdMASK	= 0x0000FFFF,	/* Data */
-	MDIdSHIFT	= 0,
-	MDIrMASK	= 0x001F0000,	/* PHY Register Address */
-	MDIrSHIFT	= 16,
-	MDIpMASK	= 0x03E00000,	/* PHY Address */
-	MDIpSHIFT	= 21,
-	MDIwop		= 0x04000000,	/* Write Operation */
-	MDIrop		= 0x08000000,	/* Read Operation */
-	MDIready	= 0x10000000,	/* End of Transaction */
-	MDIie		= 0x20000000,	/* Interrupt Enable */
-	MDIe		= 0x40000000,	/* Error */
-};
-
-enum {					/* Icr, Ics, Ims, Imc */
-	Txdw		= 0x00000001,	/* Transmit Descriptor Written Back */
-	Txqe		= 0x00000002,	/* Transmit Queue Empty */
-	Lsc		= 0x00000004,	/* Link Status Change */
-	Rxseq		= 0x00000008,	/* Receive Sequence Error */
-	Rxdmt0		= 0x00000010,	/* Rdesc Minimum Threshold Reached */
-	Rxo		= 0x00000040,	/* Receiver Overrun */
-	Rxt0		= 0x00000080,	/* Receiver Timer Interrupt */
-	Mdac		= 0x00000200,	/* MDIO Access Completed */
-	Rxcfg		= 0x00000400,	/* Receiving /C/ ordered sets */
-	Gpi0		= 0x00000800,	/* General Purpose Interrupts */
-	Gpi1		= 0x00001000,
-	Gpi2		= 0x00002000,
-	Gpi3		= 0x00004000,
-};
-
-/*
- * The Mdic register isn't implemented on the 82543GC,
- * the software defined pins are used instead.
- * These definitions work for the Intel PRO/1000 T Server Adapter.
- * The direction pin bits are read from the EEPROM.
- */
-enum {
-	Mdd		= ((1<<2)<<SwdpinsloSHIFT),	/* data */
-	Mddo		= ((1<<2)<<SwdpioloSHIFT),	/* pin direction */
-	Mdc		= ((1<<3)<<SwdpinsloSHIFT),	/* clock */
-	Mdco		= ((1<<3)<<SwdpioloSHIFT),	/* pin direction */
-	Mdr		= ((1<<0)<<SwdpinshiSHIFT),	/* reset */
-	Mdro		= ((1<<0)<<SwdpiohiSHIFT),	/* pin direction */
-};
-
-enum {					/* Txcw */
-	TxcwFd		= 0x00000020,	/* Full Duplex */
-	TxcwHd		= 0x00000040,	/* Half Duplex */
-	TxcwPauseMASK	= 0x00000180,	/* Pause */
-	TxcwPauseSHIFT	= 7,
-	TxcwPs		= (1<<TxcwPauseSHIFT),	/* Pause Supported */
-	TxcwAs		= (2<<TxcwPauseSHIFT),	/* Asymmetric FC desired */
-	TxcwRfiMASK	= 0x00003000,	/* Remote Fault Indication */
-	TxcwRfiSHIFT	= 12,
-	TxcwNpr		= 0x00008000,	/* Next Page Request */
-	TxcwConfig	= 0x40000000,	/* Transmit COnfig Control */
-	TxcwAne		= 0x80000000,	/* Auto-Negotiation Enable */
-};
-
-enum {					/* Rctl */
-	Rrst		= 0x00000001,	/* Receiver Software Reset */
-	Ren		= 0x00000002,	/* Receiver Enable */
-	Sbp		= 0x00000004,	/* Store Bad Packets */
-	Upe		= 0x00000008,	/* Unicast Promiscuous Enable */
-	Mpe		= 0x00000010,	/* Multicast Promiscuous Enable */
-	Lpe		= 0x00000020,	/* Long Packet Reception Enable */
-	LbmMASK		= 0x000000C0,	/* Loopback Mode */
-	LbmOFF		= 0x00000000,	/* No Loopback */
-	LbmTBI		= 0x00000040,	/* TBI Loopback */
-	LbmMII		= 0x00000080,	/* GMII/MII Loopback */
-	LbmXCVR		= 0x000000C0,	/* Transceiver Loopback */
-	RdtmsMASK	= 0x00000300,	/* Rdesc Minimum Threshold Size */
-	RdtmsHALF	= 0x00000000,	/* Threshold is 1/2 Rdlen */
-	RdtmsQUARTER	= 0x00000100,	/* Threshold is 1/4 Rdlen */
-	RdtmsEIGHTH	= 0x00000200,	/* Threshold is 1/8 Rdlen */
-	MoMASK		= 0x00003000,	/* Multicast Offset */
-	Bam		= 0x00008000,	/* Broadcast Accept Mode */
-	BsizeMASK	= 0x00030000,	/* Receive Buffer Size */
-	Bsize2048	= 0x00000000,
-	Bsize1024	= 0x00010000,
-	Bsize512	= 0x00020000,
-	Bsize256	= 0x00030000,
-	Vfe		= 0x00040000,	/* VLAN Filter Enable */
-	Cfien		= 0x00080000,	/* Canonical Form Indicator Enable */
-	Cfi		= 0x00100000,	/* Canonical Form Indicator value */
-	Dpf		= 0x00400000,	/* Discard Pause Frames */
-	Pmcf		= 0x00800000,	/* Pass MAC Control Frames */
-	Bsex		= 0x02000000,	/* Buffer Size Extension */
-	Secrc		= 0x04000000,	/* Strip CRC from incoming packet */
-};
-
-enum {					/* Tctl */
-	Trst		= 0x00000001,	/* Transmitter Software Reset */
-	Ten		= 0x00000002,	/* Transmit Enable */
-	Psp		= 0x00000008,	/* Pad Short Packets */
-	CtMASK		= 0x00000FF0,	/* Collision Threshold */
-	CtSHIFT		= 4,
-	ColdMASK	= 0x003FF000,	/* Collision Distance */
-	ColdSHIFT	= 12,
-	Swxoff		= 0x00400000,	/* Sofware XOFF Transmission */
-	Pbe		= 0x00800000,	/* Packet Burst Enable */
-	Rtlc		= 0x01000000,	/* Re-transmit on Late Collision */
-	Nrtu		= 0x02000000,	/* No Re-transmit on Underrrun */
-};
-
-enum {					/* [RT]xdctl */
-	PthreshMASK	= 0x0000003F,	/* Prefetch Threshold */
-	PthreshSHIFT	= 0,
-	HthreshMASK	= 0x00003F00,	/* Host Threshold */
-	HthreshSHIFT	= 8,
-	WthreshMASK	= 0x003F0000,	/* Writebacj Threshold */
-	WthreshSHIFT	= 16,
-	Gran		= 0x01000000,	/* Granularity */
-};
-
-enum {					/* Rxcsum */
-	PcssMASK	= 0x000000FF,	/* Packet Checksum Start */
-	PcssSHIFT	= 0,
-	Ipofl		= 0x00000100,	/* IP Checksum Off-load Enable */
-	Tuofl		= 0x00000200,	/* TCP/UDP Checksum Off-load Enable */
-};
-
-enum {					/* Manc */
-	Arpen		= 0x00002000,	/* Enable ARP Request Filtering */
-};
-
-typedef struct Rdesc {			/* Receive Descriptor */
-	uint	addr[2];
-	uint16_t	length;
-	uint16_t	checksum;
-	uint8_t	status;
-	uint8_t	errors;
-	uint16_t	special;
-} Rdesc;
-
-enum {					/* Rdesc status */
-	Rdd		= 0x01,		/* Descriptor Done */
-	Reop		= 0x02,		/* End of Packet */
-	Ixsm		= 0x04,		/* Ignore Checksum Indication */
-	Vp		= 0x08,		/* Packet is 802.1Q (matched VET) */
-	Tcpcs		= 0x20,		/* TCP Checksum Calculated on Packet */
-	Ipcs		= 0x40,		/* IP Checksum Calculated on Packet */
-	Pif		= 0x80,		/* Passed in-exact filter */
-};
-
-enum {					/* Rdesc errors */
-	Ce		= 0x01,		/* CRC Error or Alignment Error */
-	Se		= 0x02,		/* Symbol Error */
-	Seq		= 0x04,		/* Sequence Error */
-	Cxe		= 0x10,		/* Carrier Extension Error */
-	Tcpe		= 0x20,		/* TCP/UDP Checksum Error */
-	Ipe		= 0x40,		/* IP Checksum Error */
-	Rxe		= 0x80,		/* RX Data Error */
-};
-
-typedef struct Tdesc {			/* Legacy+Normal Transmit Descriptor */
-	uint	addr[2];
-	uint	control;		/* varies with descriptor type */
-	uint	status;			/* varies with descriptor type */
-} Tdesc;
-
-enum {					/* Tdesc control */
-	LenMASK		= 0x000FFFFF,	/* Data/Packet Length Field */
-	LenSHIFT	= 0,
-	DtypeCD		= 0x00000000,	/* Data Type 'Context Descriptor' */
-	DtypeDD		= 0x00100000,	/* Data Type 'Data Descriptor' */
-	PtypeTCP	= 0x01000000,	/* TCP/UDP Packet Type (CD) */
-	Teop		= 0x01000000,	/* End of Packet (DD) */
-	PtypeIP		= 0x02000000,	/* IP Packet Type (CD) */
-	Ifcs		= 0x02000000,	/* Insert FCS (DD) */
-	Tse		= 0x04000000,	/* TCP Segmentation Enable */
-	Rs		= 0x08000000,	/* Report Status */
-	Rps		= 0x10000000,	/* Report Status Sent */
-	Dext		= 0x20000000,	/* Descriptor Extension */
-	Vle		= 0x40000000,	/* VLAN Packet Enable */
-	Ide		= 0x80000000,	/* Interrupt Delay Enable */
-};
-
-enum {					/* Tdesc status */
-	Tdd		= 0x00000001,	/* Descriptor Done */
-	Ec		= 0x00000002,	/* Excess Collisions */
-	Lc		= 0x00000004,	/* Late Collision */
-	Tu		= 0x00000008,	/* Transmit Underrun */
-	CssMASK		= 0x0000FF00,	/* Checksum Start Field */
-	CssSHIFT	= 8,
-};
-
-enum {
-	Nrdesc		= 32,		/* multiple of 8 */
-	Ntdesc		= 8,		/* multiple of 8 */
-};
-
-typedef struct Ctlr Ctlr;
-typedef struct Ctlr {
-	int	port;
-	Pcidev*	pcidev;
-	Ctlr*	next;
-	int	active;
-	int	id;
-	int	cls;
-	uint16_t	eeprom[0x40];
-
-	int*	nic;
-	Lock	imlock;
-	int	im;			/* interrupt mask */
-
-	Mii*	mii;
-
-	Lock	slock;
-	uint	statistics[Nstatistics];
-
-	uint8_t	ra[Eaddrlen];		/* receive address */
-	uint32_t	mta[128];		/* multicast table array */
-
-	Rdesc*	rdba;			/* receive descriptor base address */
-	Block**	rb;			/* receive buffers */
-	int	rdh;			/* receive descriptor head */
-	int	rdt;			/* receive descriptor tail */
-
-	Tdesc*	tdba;			/* transmit descriptor base address */
-	Lock	tdlock;
-	Block**	tb;			/* transmit buffers */
-	int	tdh;			/* transmit descriptor head */
-	int	tdt;			/* transmit descriptor tail */
-	int	ett;			/* early transmit threshold */
-
-	int	txcw;
-	int	fcrtl;
-	int	fcrth;
-
-	/* bootstrap goo */
-	Block*	bqhead;	/* transmission queue */
-	Block*	bqtail;
-} Ctlr;
-
-static Ctlr* ctlrhead;
-static Ctlr* ctlrtail;
-
-#define csr32r(c, r)	(*((c)->nic+((r)/4)))
-#define csr32w(c, r, v)	(*((c)->nic+((r)/4)) = (v))
-
-static void
-igbeim(Ctlr* ctlr, int im)
-{
-	ilock(&ctlr->imlock);
-	ctlr->im |= im;
-	csr32w(ctlr, Ims, ctlr->im);
-	iunlock(&ctlr->imlock);
-}
-
-static void
-igbeattach(Ether* edev)
-{
-	int ctl;
-	Ctlr *ctlr;
-
-	/*
-	 * To do here:
-	 *	one-time stuff;
-	 *	start off a kproc for link status change:
-	 *		adjust queue length depending on speed;
-	 *		flow control.
-	 *	more needed here...
-	 */
-	ctlr = edev->ctlr;
-	igbeim(ctlr, 0);
-	ctl = csr32r(ctlr, Rctl)|Ren;
-	csr32w(ctlr, Rctl, ctl);
-	ctl = csr32r(ctlr, Tctl)|Ten;
-	csr32w(ctlr, Tctl, ctl);
-}
-
-static char* statistics[Nstatistics] = {
-	"CRC Error",
-	"Alignment Error",
-	"Symbol Error",
-	"RX Error",
-	"Missed Packets",
-	"Single Collision",
-	"Excessive Collisions",
-	"Multiple Collision",
-	"Late Collisions",
-	nil,
-	"Collision",
-	"Transmit Underrun",
-	"Defer",
-	"Transmit - No CRS",
-	"Sequence Error",
-	"Carrier Extension Error",
-	"Receive Error Length",
-	nil,
-	"XON Received",
-	"XON Transmitted",
-	"XOFF Received",
-	"XOFF Transmitted",
-	"FC Received Unsupported",
-	"Packets Received (64 Bytes)",
-	"Packets Received (65-127 Bytes)",
-	"Packets Received (128-255 Bytes)",
-	"Packets Received (256-511 Bytes)",
-	"Packets Received (512-1023 Bytes)",
-	"Packets Received (1024-1522 Bytes)",
-	"Good Packets Received",
-	"Broadcast Packets Received",
-	"Multicast Packets Received",
-	"Good Packets Transmitted",
-	nil,
-	"Good Octets Received",
-	nil,
-	"Good Octets Transmitted",
-	nil,
-	nil,
-	nil,
-	"Receive No Buffers",
-	"Receive Undersize",
-	"Receive Fragment",
-	"Receive Oversize",
-	"Receive Jabber",
-	nil,
-	nil,
-	nil,
-	"Total Octets Received",
-	nil,
-	"Total Octets Transmitted",
-	nil,
-	"Total Packets Received",
-	"Total Packets Transmitted",
-	"Packets Transmitted (64 Bytes)",
-	"Packets Transmitted (65-127 Bytes)",
-	"Packets Transmitted (128-255 Bytes)",
-	"Packets Transmitted (256-511 Bytes)",
-	"Packets Transmitted (512-1023 Bytes)",
-	"Packets Transmitted (1024-1522 Bytes)",
-	"Multicast Packets Transmitted",
-	"Broadcast Packets Transmitted",
-	"TCP Segmentation Context Transmitted",
-	"TCP Segmentation Context Fail",
-};
-
-static void
-txstart(Ether *edev)
-{
-	int tdh, tdt, len, olen;
-	Ctlr *ctlr = edev->ctlr;
-	Block *bp;
-	Tdesc *tdesc;
-
-	/*
-	 * Try to fill the ring back up, moving buffers from the transmit q.
-	 */
-	tdh = PREV(ctlr->tdh, Ntdesc);
-	for(tdt = ctlr->tdt; tdt != tdh; tdt = NEXT(tdt, Ntdesc)){
-		/* pull off the head of the transmission queue */
-		if((bp = ctlr->bqhead) == nil)		/* was qget(edev->oq) */
-			break;
-		ctlr->bqhead = bp->next;
-		if (ctlr->bqtail == bp)
-			ctlr->bqtail = nil;
-		len = olen = BLEN(bp);
-
-		/*
-		 * if packet is too short, make it longer rather than relying
-		 * on ethernet interface to pad it and complain so the caller
-		 * will get fixed.  I don't think Psp is working right, or it's
-		 * getting cleared.
-		 */
-		if (len < ETHERMINTU) {
-			if (bp->rp + ETHERMINTU <= bp->lim)
-				bp->wp = bp->rp + ETHERMINTU;
-			else
-				bp->wp = bp->lim;
-			len = BLEN(bp);
-			print("txstart: extended short pkt %d -> %d bytes\n",
-				olen, len);
-		}
-
-		/* set up a descriptor for it */
-		tdesc = &ctlr->tdba[tdt];
-		tdesc->addr[0] = PCIWADDR(bp->rp);
-		tdesc->addr[1] = 0;
-		tdesc->control = /* Ide| */ Rs|Dext|Ifcs|Teop|DtypeDD|len;
-		tdesc->status = 0;
-
-		ctlr->tb[tdt] = bp;
-	}
-	ctlr->tdt = tdt;
-	csr32w(ctlr, Tdt, tdt);
-	igbeim(ctlr, Txdw);
-}
-
-static Block *
-fromringbuf(Ether *ether)
-{
-	RingBuf *tb = &ether->tb[ether->ti];
-	Block *bp = allocb(tb->len);
-
-	memmove(bp->wp, tb->pkt, tb->len);
-	memmove(bp->wp+Eaddrlen, ether->ea, Eaddrlen);
-	bp->wp += tb->len;
-	return bp;
-}
-
-static void
-igbetransmit(Ether* edev)
-{
-	Block *bp;
-	Ctlr *ctlr;
-	Tdesc *tdesc;
-	RingBuf *tb;
-	int tdh;
-
-	/*
-	 * For now there are no smarts here. Tuning comes later.
-	 */
-	ctlr = edev->ctlr;
-	ilock(&ctlr->tdlock);
-
-	/*
-	 * Free any completed packets
-	 * - try to get the soft tdh to catch the tdt;
-	 * - if the packet had an underrun bump the threshold
-	 *   - the Tu bit doesn't seem to ever be set, perhaps
-	 *     because Rs mode is used?
-	 */
-	tdh = ctlr->tdh;
-	for(;;){
-		tdesc = &ctlr->tdba[tdh];
-		if(!(tdesc->status & Tdd))
-			break;
-		if(tdesc->status & Tu){
-			ctlr->ett++;
-			csr32w(ctlr, Ett, ctlr->ett);
-		}
-		tdesc->status = 0;
-		if(ctlr->tb[tdh] != nil){
-			freeb(ctlr->tb[tdh]);
-			ctlr->tb[tdh] = nil;
-		}
-		tdh = NEXT(tdh, Ntdesc);
-	}
-	ctlr->tdh = tdh;
-
-	/* copy packets from the software RingBuf to the transmission q */
-	/* from boot ether83815.c */
-	while((tb = &edev->tb[edev->ti])->owner == Interface){
-		bp = fromringbuf(edev);
-
-		/* put the buffer on the transmit queue */
-		if(ctlr->bqhead)
-			ctlr->bqtail->next = bp;
-		else
-			ctlr->bqhead = bp;
-		ctlr->bqtail = bp;
-
-		txstart(edev);		/* kick transmitter */
-		tb->owner = Host;	/* give descriptor back */
-
-		edev->ti = NEXT(edev->ti, edev->ntb);
-	}
-	iunlock(&ctlr->tdlock);
-}
-
-static void
-igbereplenish(Ctlr* ctlr)
-{
-	int rdt;
-	Block *bp;
-	Rdesc *rdesc;
-
-	rdt = ctlr->rdt;
-	while(NEXT(rdt, Nrdesc) != ctlr->rdh){
-		rdesc = &ctlr->rdba[rdt];
-		if(ctlr->rb[rdt] != nil){
-			/* nothing to do */
-		}
-		else if((bp = iallocb(2048)) != nil){
-			ctlr->rb[rdt] = bp;
-			rdesc->addr[0] = PCIWADDR(bp->rp);
-			rdesc->addr[1] = 0;
-		}
-		else
-			break;
-		rdesc->status = 0;
-
-		rdt = NEXT(rdt, Nrdesc);
-	}
-	ctlr->rdt = rdt;
-	csr32w(ctlr, Rdt, rdt);
-}
-
-static void
-toringbuf(Ether *ether, Block *bp)
-{
-	RingBuf *rb = &ether->rb[ether->ri];
-
-	if (rb->owner == Interface) {
-		rb->len = BLEN(bp);
-		memmove(rb->pkt, bp->rp, rb->len);
-		rb->owner = Host;
-		ether->ri = NEXT(ether->ri, ether->nrb);
-	}
-	/* else no one is expecting packets from the network */
-}
-
-static void
-igbeinterrupt(Ureg*, void* arg)
-{
-	Block *bp;
-	Ctlr *ctlr;
-	Ether *edev;
-	Rdesc *rdesc;
-	int icr, im, rdh, txdw = 0;
-
-	edev = arg;
-	ctlr = edev->ctlr;
-
-	ilock(&ctlr->imlock);
-	csr32w(ctlr, Imc, ~0);
-	im = ctlr->im;
-
-	if((icr = csr32r(ctlr, Icr)) & ctlr->im){
-		/*
-		 * Link status changed.
-		 */
-		if(icr & (Rxseq|Lsc)){
-			/*
-			 * More here...
-			 */
-		}
-
-		/*
-		 * Process any received packets.
-		 */
-		rdh = ctlr->rdh;
-		for(;;){
-			rdesc = &ctlr->rdba[rdh];
-			if(!(rdesc->status & Rdd))
-				break;
-			if ((rdesc->status & Reop) && rdesc->errors == 0) {
-				bp = ctlr->rb[rdh];
-				ctlr->rb[rdh] = nil;
-				/*
-				 * it appears that the original 82543 needed
-				 * to have the Ethernet CRC excluded, but that
-				 * the newer chips do not?
-				 */
-				bp->wp += rdesc->length /* -4 */;
-				toringbuf(edev, bp);
-				freeb(bp);
-			} else if ((rdesc->status & Reop) && rdesc->errors)
-				print("igbe: input packet error 0x%ux\n",
-					rdesc->errors);
-			rdesc->status = 0;
-			rdh = NEXT(rdh, Nrdesc);
-		}
-		ctlr->rdh = rdh;
-
-		if(icr & Rxdmt0)
-			igbereplenish(ctlr);
-		if(icr & Txdw){
-			im &= ~Txdw;
-			txdw++;
-		}
-	}
-
-	ctlr->im = im;
-	csr32w(ctlr, Ims, im);
-	iunlock(&ctlr->imlock);
-
-	if(txdw)
-		igbetransmit(edev);
-}
-
-static int
-igbeinit(Ether* edev)
-{
-	int csr, i, r, ctrl, timeo;
-	MiiPhy *phy;
-	Ctlr *ctlr;
-
-	ctlr = edev->ctlr;
-
-	/*
-	 * Set up the receive addresses.
-	 * There are 16 addresses. The first should be the MAC address.
-	 * The others are cleared and not marked valid (MS bit of Rah).
-	 */
-	csr = (edev->ea[3]<<24)|(edev->ea[2]<<16)|(edev->ea[1]<<8)|edev->ea[0];
-	csr32w(ctlr, Ral, csr);
-	csr = 0x80000000|(edev->ea[5]<<8)|edev->ea[4];
-	csr32w(ctlr, Rah, csr);
-	for(i = 1; i < 16; i++){
-		csr32w(ctlr, Ral+i*8, 0);
-		csr32w(ctlr, Rah+i*8, 0);
-	}
-
-	/*
-	 * Clear the Multicast Table Array.
-	 * It's a 4096 bit vector accessed as 128 32-bit registers.
-	 */
-	for(i = 0; i < 128; i++)
-		csr32w(ctlr, Mta+i*4, 0);
-
-	/*
-	 * Receive initialisation.
-	 * Mostly defaults from the datasheet, will
-	 * need some tuning for performance:
-	 *	Rctl	descriptor mimimum threshold size
-	 *		discard pause frames
-	 *		strip CRC
-	 * 	Rdtr	interrupt delay
-	 * 	Rxdctl	all the thresholds
-	 */
-	csr32w(ctlr, Rctl, 0);
-
-	/*
-	 * Allocate the descriptor ring and load its
-	 * address and length into the NIC.
-	 */
-	ctlr->rdba = xspanalloc(Nrdesc*sizeof(Rdesc), 128 /* was 16 */, 0);
-	csr32w(ctlr, Rdbal, PCIWADDR(ctlr->rdba));
-	csr32w(ctlr, Rdbah, 0);
-	csr32w(ctlr, Rdlen, Nrdesc*sizeof(Rdesc));
-
-	/*
-	 * Initialise the ring head and tail pointers and
-	 * populate the ring with Blocks.
-	 * The datasheet says the tail pointer is set to beyond the last
-	 * descriptor hardware can process, which implies the initial
-	 * condition is Rdh == Rdt. However, experience shows Rdt must
-	 * always be 'behind' Rdh; the replenish routine ensures this.
-	 */
-	ctlr->rdh = 0;
-	csr32w(ctlr, Rdh, ctlr->rdh);
-	ctlr->rdt = 0;
-	csr32w(ctlr, Rdt, ctlr->rdt);
-	ctlr->rb = malloc(sizeof(Block*)*Nrdesc);
-	igbereplenish(ctlr);
-
-	/*
-	 * Set up Rctl but don't enable receiver (yet).
-	 */
-	csr32w(ctlr, Rdtr, 0);
-	switch(ctlr->id){
-	case i82540em:
-	case i82540eplp:
-	case i82541gi:
-	case i82541pi:
-	case i82546gb:
-	case i82546eb:
-	case i82547gi:
-		csr32w(ctlr, Radv, 64);
-		break;
-	}
-	csr32w(ctlr, Rxdctl, (8<<WthreshSHIFT)|(8<<HthreshSHIFT)|4);
-	/*
-	 * Enable checksum offload.
-	 */
-	csr32w(ctlr, Rxcsum, Tuofl|Ipofl|(ETHERHDRSIZE<<PcssSHIFT));
-
-	csr32w(ctlr, Rctl, Dpf|Bsize2048|Bam|RdtmsHALF);
- 	/*
-	 * VirtualBox does not like Rxt0,
-	 * it continually interrupts.
-	 */
-	ctlr->im |= /*Rxt0|*/Rxo|Rxdmt0|Rxseq;
-
-	/*
-	 * Transmit initialisation.
-	 * Mostly defaults from the datasheet, will
-	 * need some tuning for performance. The normal mode will
-	 * be full-duplex and things to tune for half-duplex are
-	 *	Tctl	re-transmit on late collision
-	 *	Tipg	all IPG times
-	 *	Tbt	burst timer
-	 *	Ait	adaptive IFS throttle
-	 * and in general
-	 *	Txdmac	packet prefetching
-	 *	Ett	transmit early threshold
-	 *	Tidv	interrupt delay value
-	 *	Txdctl	all the thresholds
-	 */
-	csr32w(ctlr, Tctl, (0x0F<<CtSHIFT)|Psp|(66<<ColdSHIFT));	/* Fd */
-	switch(ctlr->id){
-	default:
-		r = 6;
-		break;
-	case i82543gc:
-	case i82544ei:
-	case i82547ei:
-	case i82540em:
-	case i82540eplp:
-	case i82541gi:
-	case i82541pi:
-	case i82546gb:
-	case i82546eb:
-	case i82547gi:
-		r = 8;
-		break;
-	}
-	csr32w(ctlr, Tipg, (6<<20)|(8<<10)|r);
-	csr32w(ctlr, Ait, 0);
-	csr32w(ctlr, Txdmac, 0);
-	csr32w(ctlr, Tidv, 128);
-
-	/*
-	 * Allocate the descriptor ring and load its
-	 * address and length into the NIC.
-	 */
-	ctlr->tdba = xspanalloc(Ntdesc*sizeof(Tdesc), 128 /* was 16 */, 0);
-	csr32w(ctlr, Tdbal, PCIWADDR(ctlr->tdba));
-	csr32w(ctlr, Tdbah, 0);
-	csr32w(ctlr, Tdlen, Ntdesc*sizeof(Tdesc));
-
-	/*
-	 * Initialise the ring head and tail pointers.
-	 */
-	ctlr->tdh = 0;
-	csr32w(ctlr, Tdh, ctlr->tdh);
-	ctlr->tdt = 0;
-	csr32w(ctlr, Tdt, ctlr->tdt);
-	ctlr->tb = malloc(sizeof(Block*)*Ntdesc);
-//	ctlr->im |= Txqe|Txdw;
-
-	r = (4<<WthreshSHIFT)|(4<<HthreshSHIFT)|(8<<PthreshSHIFT);
-	switch(ctlr->id){
-	default:
-		break;
-	case i82540em:
-	case i82540eplp:
-	case i82547gi:
-	case i82541pi:
-	case i82546gb:
-	case i82546eb:
-	case i82541gi:
-		r = csr32r(ctlr, Txdctl);
-		r &= ~WthreshMASK;
-		r |= Gran|(4<<WthreshSHIFT);
-
-		csr32w(ctlr, Tadv, 64);
-		break;
-	}
-	csr32w(ctlr, Txdctl, r);
-
-	r = csr32r(ctlr, Tctl);
-	r |= Ten;
-	csr32w(ctlr, Tctl, r);
-
-	igbeim(ctlr, ctlr->im);
-
-	if(ctlr->mii == nil || ctlr->mii->curphy == nil) {
-		print("igbe: no mii (yet)\n");
-		return 0;
-	}
-	/* wait for the link to come up */
-	for(timeo = 0; timeo < 3500; timeo++){
-		if(miistatus(ctlr->mii) == 0)
-			break;
-		delay(10);
-	}
-	print("igbe: phy: ");
-	phy = ctlr->mii->curphy;
-	if (phy->fd)
-		print("full duplex");
-	else
-		print("half duplex");
-	print(", %d Mb/s\n", phy->speed);
-
-	/*
-	 * Flow control.
-	 */
-	ctrl = csr32r(ctlr, Ctrl);
-	if(phy->rfc)
-		ctrl |= Rfce;
-	if(phy->tfc)
-		ctrl |= Tfce;
-	csr32w(ctlr, Ctrl, ctrl);
-
-	return 0;
-}
-
-static int
-i82543mdior(Ctlr* ctlr, int n)
-{
-	int ctrl, data, i, r;
-
-	/*
-	 * Read n bits from the Management Data I/O Interface.
-	 */
-	ctrl = csr32r(ctlr, Ctrl);
-	r = (ctrl & ~Mddo)|Mdco;
-	data = 0;
-	for(i = n-1; i >= 0; i--){
-		if(csr32r(ctlr, Ctrl) & Mdd)
-			data |= (1<<i);
-		csr32w(ctlr, Ctrl, Mdc|r);
-		csr32w(ctlr, Ctrl, r);
-	}
-	csr32w(ctlr, Ctrl, ctrl);
-
-	return data;
-}
-
-static int
-i82543mdiow(Ctlr* ctlr, int bits, int n)
-{
-	int ctrl, i, r;
-
-	/*
-	 * Write n bits to the Management Data I/O Interface.
-	 */
-	ctrl = csr32r(ctlr, Ctrl);
-	r = Mdco|Mddo|ctrl;
-	for(i = n-1; i >= 0; i--){
-		if(bits & (1<<i))
-			r |= Mdd;
-		else
-			r &= ~Mdd;
-		csr32w(ctlr, Ctrl, Mdc|r);
-		csr32w(ctlr, Ctrl, r);
-	}
-	csr32w(ctlr, Ctrl, ctrl);
-
-	return 0;
-}
-
-static int
-i82543miimir(Mii* mii, int pa, int ra)
-{
-	int data;
-	Ctlr *ctlr;
-
-	ctlr = mii->ctlr;
-
-	/*
-	 * MII Management Interface Read.
-	 *
-	 * Preamble;
-	 * ST+OP+PHYAD+REGAD;
-	 * TA + 16 data bits.
-	 */
-	i82543mdiow(ctlr, 0xFFFFFFFF, 32);
-	i82543mdiow(ctlr, 0x1800|(pa<<5)|ra, 14);
-	data = i82543mdior(ctlr, 18);
-
-	if(data & 0x10000)
-		return -1;
-
-	return data & 0xFFFF;
-}
-
-static int
-i82543miimiw(Mii* mii, int pa, int ra, int data)
-{
-	Ctlr *ctlr;
-
-	ctlr = mii->ctlr;
-
-	/*
-	 * MII Management Interface Write.
-	 *
-	 * Preamble;
-	 * ST+OP+PHYAD+REGAD+TA + 16 data bits;
-	 * Z.
-	 */
-	i82543mdiow(ctlr, 0xFFFFFFFF, 32);
-	data &= 0xFFFF;
-	data |= (0x05<<(5+5+2+16))|(pa<<(5+2+16))|(ra<<(2+16))|(0x02<<16);
-	i82543mdiow(ctlr, data, 32);
-
-	return 0;
-}
-
-static int
-igbemiimir(Mii* mii, int pa, int ra)
-{
-	Ctlr *ctlr;
-	int mdic, timo;
-
-	ctlr = mii->ctlr;
-
-	csr32w(ctlr, Mdic, MDIrop|(pa<<MDIpSHIFT)|(ra<<MDIrSHIFT));
-	mdic = 0;
-	for(timo = 64; timo; timo--){
-		mdic = csr32r(ctlr, Mdic);
-		if(mdic & (MDIe|MDIready))
-			break;
-		microdelay(1);
-	}
-
-	if((mdic & (MDIe|MDIready)) == MDIready)
-		return mdic & 0xFFFF;
-	return -1;
-}
-
-static int
-igbemiimiw(Mii* mii, int pa, int ra, int data)
-{
-	Ctlr *ctlr;
-	int mdic, timo;
-
-	ctlr = mii->ctlr;
-
-	data &= MDIdMASK;
-	csr32w(ctlr, Mdic, MDIwop|(pa<<MDIpSHIFT)|(ra<<MDIrSHIFT)|data);
-	mdic = 0;
-	for(timo = 64; timo; timo--){
-		mdic = csr32r(ctlr, Mdic);
-		if(mdic & (MDIe|MDIready))
-			break;
-		microdelay(1);
-	}
-	if((mdic & (MDIe|MDIready)) == MDIready)
-		return 0;
-	return -1;
-}
-
-static int
-igbemii(Ctlr* ctlr)
-{
-	MiiPhy *phy = (MiiPhy *)1;
-	int ctrl, p, r;
-
-	USED(phy);
-	r = csr32r(ctlr, Status);
-	if(r & Tbimode)
-		return -1;
-	if((ctlr->mii = malloc(sizeof(Mii))) == nil)
-		return -1;
-	ctlr->mii->ctlr = ctlr;
-
-	ctrl = csr32r(ctlr, Ctrl);
-	ctrl |= Slu;
-
-	switch(ctlr->id){
-	case i82543gc:
-		ctrl |= Frcdplx|Frcspd;
-		csr32w(ctlr, Ctrl, ctrl);
-
-		/*
-		 * The reset pin direction (Mdro) should already
-		 * be set from the EEPROM load.
-		 * If it's not set this configuration is unexpected
-		 * so bail.
-		 */
-		r = csr32r(ctlr, Ctrlext);
-		if(!(r & Mdro))
-			return -1;
-		csr32w(ctlr, Ctrlext, r);
-		delay(20);
-		r = csr32r(ctlr, Ctrlext);
-		r &= ~Mdr;
-		csr32w(ctlr, Ctrlext, r);
-		delay(20);
-		r = csr32r(ctlr, Ctrlext);
-		r |= Mdr;
-		csr32w(ctlr, Ctrlext, r);
-		delay(20);
-
-		ctlr->mii->mir = i82543miimir;
-		ctlr->mii->miw = i82543miimiw;
-		break;
-	case i82544ei:
-	case i82547ei:
-	case i82540em:
-	case i82540eplp:
-	case i82547gi:
-	case i82541gi:
-	case i82541pi:
-	case i82546gb:
-	case i82546eb:
-		ctrl &= ~(Frcdplx|Frcspd);
-		csr32w(ctlr, Ctrl, ctrl);
-		ctlr->mii->mir = igbemiimir;
-		ctlr->mii->miw = igbemiimiw;
-		break;
-	default:
-		free(ctlr->mii);
-		ctlr->mii = nil;
-		return -1;
-	}
-
-	if(mii(ctlr->mii, ~0) == 0 || (phy = ctlr->mii->curphy) == nil){
-		if (0)
-			print("phy trouble: phy = 0x%lux\n", (uint32_t)phy);
-		free(ctlr->mii);
-		ctlr->mii = nil;
-		return -1;
-	}
-	//print("oui %X phyno %d\n", phy->oui, phy->phyno);
-	USED(phy);
-
-	/*
-	 * 8254X-specific PHY registers not in 802.3:
-	 *	0x10	PHY specific control
-	 *	0x14	extended PHY specific control
-	 * Set appropriate values then reset the PHY to have
-	 * changes noted.
-	 */
-	switch(ctlr->id){
-	case i82547gi:
-	case i82541gi:
-	case i82541pi:
-	case i82546gb:
-	case i82546eb:
-		break;
-	default:
-		r = miimir(ctlr->mii, 16);
-		r |= 0x0800;			/* assert CRS on Tx */
-		r |= 0x0060;			/* auto-crossover all speeds */
-		r |= 0x0002;			/* polarity reversal enabled */
-		miimiw(ctlr->mii, 16, r);
-
-		r = miimir(ctlr->mii, 20);
-		r |= 0x0070;			/* +25MHz clock */
-		r &= ~0x0F00;
-		r |= 0x0100;			/* 1x downshift */
-		miimiw(ctlr->mii, 20, r);
-
-		miireset(ctlr->mii);
-		break;
-	}
-	p = 0;
-	if(ctlr->txcw & TxcwPs)
-		p |= AnaP;
-	if(ctlr->txcw & TxcwAs)
-		p |= AnaAP;
-	miiane(ctlr->mii, ~0, p, ~0);
-
-	return 0;
-}
-
-static int
-at93c46io(Ctlr* ctlr, char* op, int data)
-{
-	char *lp, *p;
-	int i, loop, eecd, r;
-
-	eecd = csr32r(ctlr, Eecd);
-
-	r = 0;
-	loop = -1;
-	lp = nil;
-	for(p = op; *p != '\0'; p++){
-		switch(*p){
-		default:
-			return -1;
-		case ' ':
-			continue;
-		case ':':			/* start of loop */
-			loop = strtol(p+1, &lp, 0)-1;
-			lp--;
-			if(p == lp)
-				loop = 7;
-			p = lp;
-			continue;
-		case ';':			/* end of loop */
-			if(lp == nil)
-				return -1;
-			loop--;
-			if(loop >= 0)
-				p = lp;
-			else
-				lp = nil;
-			continue;
-		case 'C':			/* assert clock */
-			eecd |= Sk;
-			break;
-		case 'c':			/* deassert clock */
-			eecd &= ~Sk;
-			break;
-		case 'D':			/* next bit in 'data' byte */
-			if(loop < 0)
-				return -1;
-			if(data & (1<<loop))
-				eecd |= Di;
-			else
-				eecd &= ~Di;
-			break;
-		case 'O':			/* collect data output */
-			i = (csr32r(ctlr, Eecd) & Do) != 0;
-			if(loop >= 0)
-				r |= (i<<loop);
-			else
-				r = i;
-			continue;
-		case 'I':			/* assert data input */
-			eecd |= Di;
-			break;
-		case 'i':			/* deassert data input */
-			eecd &= ~Di;
-			break;
-		case 'S':			/* enable chip select */
-			eecd |= Cs;
-			break;
-		case 's':			/* disable chip select */
-			eecd &= ~Cs;
-			break;
-		}
-		csr32w(ctlr, Eecd, eecd);
-		microdelay(50);
-	}
-	if(loop >= 0)
-		return -1;
-	return r;
-}
-
-static int
-at93c46r(Ctlr* ctlr)
-{
-	uint16_t sum;
-	char rop[20];
-	int addr, areq, bits, data, eecd, i;
-
-	eecd = csr32r(ctlr, Eecd);
-	if(eecd & Spi){
-		print("igbe: SPI EEPROM access not implemented\n");
-		return 0;
-	}
-	if(eecd & (Eeszaddr|Eesz256))
-		bits = 8;
-	else
-		bits = 6;
-	sum = 0;
-
-	switch(ctlr->id){
-	default:
-		areq = 0;
-		break;
-	case i82540em:
-	case i82540eplp:
-	case i82541gi:
-	case i82541pi:
-	case i82547gi:
-	case i82546gb:
-	case i82546eb:
-		areq = 1;
-		csr32w(ctlr, Eecd, eecd|Areq);
-		for(i = 0; i < 1000; i++){
-			if((eecd = csr32r(ctlr, Eecd)) & Agnt)
-				break;
-			microdelay(5);
-		}
-		if(!(eecd & Agnt)){
-			print("igbe: not granted EEPROM access\n");
-			goto release;
-		}
-		break;
-	}
-	snprint(rop, sizeof(rop), "S :%dDCc;", bits+3);
-
-	for(addr = 0; addr < 0x40; addr++){
-		/*
-		 * Read a word at address 'addr' from the Atmel AT93C46
-		 * 3-Wire Serial EEPROM or compatible. The EEPROM access is
-		 * controlled by 4 bits in Eecd. See the AT93C46 datasheet
-		 * for protocol details.
-		 */
-		if(at93c46io(ctlr, rop, (0x06<<bits)|addr) != 0){
-			print("igbe: can't set EEPROM address 0x%2.2X\n", addr);
-			goto release;
-		}
-		data = at93c46io(ctlr, ":16COc;", 0);
-		at93c46io(ctlr, "sic", 0);
-		ctlr->eeprom[addr] = data;
-		sum += data;
-
-		//if(addr && ((addr & 0x07) == 0))
-		//	print("\n");
-		//print(" %4.4ux", data);
-	}
-	//print("\n");
-
-release:
-	if(areq)
-		csr32w(ctlr, Eecd, eecd & ~Areq);
-	return sum;
-}
-
-static void
-detach(Ctlr *ctlr)
-{
-	int r;
-
-	/*
-	 * Perform a device reset to get the chip back to the
-	 * power-on state, followed by an EEPROM reset to read
-	 * the defaults for some internal registers.
-	 */
-	csr32w(ctlr, Imc, ~0);
-	csr32w(ctlr, Rctl, 0);
-	csr32w(ctlr, Tctl, 0);
-
-	delay(20);
-
-	csr32w(ctlr, Ctrl, Devrst);
-	/* apparently needed on multi-GHz processors to avoid infinite loops */
-	delay(1);
-	while(csr32r(ctlr, Ctrl) & Devrst)
-		;
-
-	csr32w(ctlr, Ctrlext, Eerst | csr32r(ctlr, Ctrlext));
-	delay(1);
-	while(csr32r(ctlr, Ctrlext) & Eerst)
-		;
-
-	switch(ctlr->id){
-	default:
-		break;
-	case i82540em:
-	case i82540eplp:
-	case i82541gi:
-	case i82541pi:
-	case i82547gi:
-	case i82546gb:
-	case i82546eb:
-		r = csr32r(ctlr, Manc);
-		r &= ~Arpen;
-		csr32w(ctlr, Manc, r);
-		break;
-	}
-
-	csr32w(ctlr, Imc, ~0);
-	delay(1);
-	while(csr32r(ctlr, Icr))
-		;
-}
-
-static void
-igbedetach(Ether *edev)
-{
-	detach(edev->ctlr);
-}
-
-static void
-igbeshutdown(Ether* ether)
-{
-print("igbeshutdown\n");
-	igbedetach(ether);
-}
-
-static int
-igbereset(Ctlr* ctlr)
-{
-	int ctrl, i, pause, r, swdpio, txcw;
-
-	detach(ctlr);
-
-	/*
-	 * Read the EEPROM, validate the checksum
-	 * then get the device back to a power-on state.
-	 */
-	r = at93c46r(ctlr);
-	/* zero return means no SPI EEPROM access */
-	if (r != 0 && r != 0xBABA){
-		print("igbe: bad EEPROM checksum - 0x%4.4uX\n", r);
-		return -1;
-	}
-
-	/*
-	 * Snarf and set up the receive addresses.
-	 * There are 16 addresses. The first should be the MAC address.
-	 * The others are cleared and not marked valid (MS bit of Rah).
-	 */
-	if ((ctlr->id == i82546gb || ctlr->id == i82546eb) && BUSFNO(ctlr->pcidev->tbdf) == 1)
-		ctlr->eeprom[Ea+2] += 0x100;	// second interface
-	for(i = Ea; i < Eaddrlen/2; i++){
-		ctlr->ra[2*i] = ctlr->eeprom[i];
-		ctlr->ra[2*i+1] = ctlr->eeprom[i]>>8;
-	}
-	r = (ctlr->ra[3]<<24)|(ctlr->ra[2]<<16)|(ctlr->ra[1]<<8)|ctlr->ra[0];
-	csr32w(ctlr, Ral, r);
-	r = 0x80000000|(ctlr->ra[5]<<8)|ctlr->ra[4];
-	csr32w(ctlr, Rah, r);
-	for(i = 1; i < 16; i++){
-		csr32w(ctlr, Ral+i*8, 0);
-		csr32w(ctlr, Rah+i*8, 0);
-	}
-
-	/*
-	 * Clear the Multicast Table Array.
-	 * It's a 4096 bit vector accessed as 128 32-bit registers.
-	 */
-	memset(ctlr->mta, 0, sizeof(ctlr->mta));
-	for(i = 0; i < 128; i++)
-		csr32w(ctlr, Mta+i*4, 0);
-
-	/*
-	 * Just in case the Eerst didn't load the defaults
-	 * (doesn't appear to fully on the 8243GC), do it manually.
-	 */
-	if (ctlr->id == i82543gc) {
-		txcw = csr32r(ctlr, Txcw);
-		txcw &= ~(TxcwAne|TxcwPauseMASK|TxcwFd);
-		ctrl = csr32r(ctlr, Ctrl);
-		ctrl &= ~(SwdpioloMASK|Frcspd|Ilos|Lrst|Fd);
-
-		if(ctlr->eeprom[Icw1] & 0x0400){
-			ctrl |= Fd;
-			txcw |= TxcwFd;
-		}
-		if(ctlr->eeprom[Icw1] & 0x0200)
-			ctrl |= Lrst;
-		if(ctlr->eeprom[Icw1] & 0x0010)
-			ctrl |= Ilos;
-		if(ctlr->eeprom[Icw1] & 0x0800)
-			ctrl |= Frcspd;
-		swdpio = (ctlr->eeprom[Icw1] & 0x01E0)>>5;
-		ctrl |= swdpio<<SwdpioloSHIFT;
-		csr32w(ctlr, Ctrl, ctrl);
-
-		ctrl = csr32r(ctlr, Ctrlext);
-		ctrl &= ~(Ips|SwdpiohiMASK);
-		swdpio = (ctlr->eeprom[Icw2] & 0x00F0)>>4;
-		if(ctlr->eeprom[Icw1] & 0x1000)
-			ctrl |= Ips;
-		ctrl |= swdpio<<SwdpiohiSHIFT;
-		csr32w(ctlr, Ctrlext, ctrl);
-
-		if(ctlr->eeprom[Icw2] & 0x0800)
-			txcw |= TxcwAne;
-		pause = (ctlr->eeprom[Icw2] & 0x3000)>>12;
-		txcw |= pause<<TxcwPauseSHIFT;
-		switch(pause){
-		default:
-			ctlr->fcrtl = 0x00002000;
-			ctlr->fcrth = 0x00004000;
-			txcw |= TxcwAs|TxcwPs;
-			break;
-		case 0:
-			ctlr->fcrtl = 0x00002000;
-			ctlr->fcrth = 0x00004000;
-			break;
-		case 2:
-			ctlr->fcrtl = 0;
-			ctlr->fcrth = 0;
-			txcw |= TxcwAs;
-			break;
-		}
-		ctlr->txcw = txcw;
-		csr32w(ctlr, Txcw, txcw);
-	}
-	/*
-	 * Flow control - values from the datasheet.
-	 */
-	csr32w(ctlr, Fcal, 0x00C28001);
-	csr32w(ctlr, Fcah, 0x00000100);
-	csr32w(ctlr, Fct, 0x00008808);
-	csr32w(ctlr, Fcttv, 0x00000100);
-
-	csr32w(ctlr, Fcrtl, ctlr->fcrtl);
-	csr32w(ctlr, Fcrth, ctlr->fcrth);
-
-	ilock(&ctlr->imlock);
-	csr32w(ctlr, Imc, ~0);
-	ctlr->im = Lsc;
-	csr32w(ctlr, Ims, ctlr->im);
-	iunlock(&ctlr->imlock);
-
-	if(!(csr32r(ctlr, Status) & Tbimode) && igbemii(ctlr) < 0) {
-		print("igbe: igbemii failed\n");
-		return -1;
-	}
-
-	return 0;
-}
-
-static void
-igbepci(void)
-{
-	int port, cls;
-	Pcidev *p;
-	Ctlr *ctlr;
-	static int first = 1;
-
-	if (first)
-		first = 0;
-	else
-		return;
-
-	p = nil;
-	while(p = pcimatch(p, 0x8086, 0)){
-		if(p->ccrb != 0x02 || p->ccru != 0)
-			continue;
-
-		switch((p->did<<16)|p->vid){
-		case i82542:
-		default:
-			continue;
-
-		case (0x1001<<16)|0x8086:	/* Intel PRO/1000 F */
-			break;
-		case i82543gc:
-		case i82544ei:
-		case i82547ei:
-		case i82540em:
-		case i82540eplp:
-		case i82547gi:
-		case i82541gi:
-		case i82541pi:
-		case i82546gb:
-		case i82546eb:
-			break;
-		}
-
-		/* the 82547EI is on the CSA bus, whatever that is */
-		port = upamalloc(p->mem[0].bar & ~0x0F, p->mem[0].size, 0);
-		if(port == 0){
-			print("igbe: can't map %d @ 0x%8.8luX\n",
-				p->mem[0].size, p->mem[0].bar);
-			continue;
-		}
-
-		/*
-		 * from etherga620.c:
-		 * If PCI Write-and-Invalidate is enabled set the max write DMA
-		 * value to the host cache-line size (32 on Pentium or later).
-		 */
-		if(p->pcr & MemWrInv){
-			cls = pcicfgr8(p, PciCLS) * 4;
-			if(cls != CACHELINESZ)
-				pcicfgw8(p, PciCLS, CACHELINESZ/4);
-		}
-
-		cls = pcicfgr8(p, PciCLS);
-		switch(cls){
-			default:
-				print("igbe: unexpected CLS - %d bytes\n",
-					cls*sizeof(int32_t));
-				break;
-			case 0x00:
-			case 0xFF:
-				/* alphapc 164lx returns 0 */
-				print("igbe: unusable PciCLS: %d, using %d longs\n",
-					cls, CACHELINESZ/sizeof(int32_t));
-				cls = CACHELINESZ/sizeof(int32_t);
-				pcicfgw8(p, PciCLS, cls);
-				break;
-			case 0x08:
-			case 0x10:
-				break;
-		}
-
-		ctlr = malloc(sizeof(Ctlr));
-		ctlr->port = port;
-		ctlr->pcidev = p;
-		ctlr->id = (p->did<<16)|p->vid;
-		ctlr->cls = cls*4;
-		ctlr->nic = KADDR(ctlr->port);
-		if(igbereset(ctlr)){
-			free(ctlr);
-			continue;
-		}
-		pcisetbme(p);
-
-		if(ctlrhead != nil)
-			ctlrtail->next = ctlr;
-		else
-			ctlrhead = ctlr;
-		ctlrtail = ctlr;
-	}
-}
-
-int
-igbepnp(Ether* edev)
-{
-	int i;
-	Ctlr *ctlr;
-	uint8_t ea[Eaddrlen];
-
-	if(ctlrhead == nil)
-		igbepci();
-
-	/*
-	 * Any adapter matches if no edev->port is supplied,
-	 * otherwise the ports must match.
-	 */
-	for(ctlr = ctlrhead; ctlr != nil; ctlr = ctlr->next){
-		if(ctlr->active)
-			continue;
-		if(edev->port == 0 || edev->port == ctlr->port){
-			ctlr->active = 1;
-			break;
-		}
-	}
-	if(ctlr == nil)
-		return -1;
-
-	edev->ctlr = ctlr;
-	edev->port = ctlr->port;
-	edev->irq = ctlr->pcidev->intl;
-	edev->tbdf = ctlr->pcidev->tbdf;
-//	edev->mbps = 1000;
-
-	/*
-	 * Check if the adapter's station address is to be overridden.
-	 * If not, read it from the EEPROM and set in ether->ea prior to
-	 * loading the station address in the hardware.
-	 */
-	memset(ea, 0, Eaddrlen);
-	if(memcmp(ea, edev->ea, Eaddrlen) == 0){
-		for(i = 0; i < Eaddrlen/2; i++){
-			edev->ea[2*i] = ctlr->eeprom[i];
-			edev->ea[2*i+1] = ctlr->eeprom[i]>>8;
-		}
-	}
-	igbeinit(edev);
-
-	/*
-	 * Linkage to the generic ethernet driver.
-	 */
-	edev->attach = igbeattach;
-	edev->transmit = igbetransmit;
-	edev->interrupt = igbeinterrupt;
-	edev->detach = igbedetach;
-
-	return 0;
-}

+ 0 - 233
sys/src/9/w/pxeload/ethermii.c

@@ -1,233 +0,0 @@
-/*
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
-
-#include "u.h"
-#include "lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-
-#include "etherif.h"
-#include "ethermii.h"
-
-int
-mii(Mii* mii, int mask)
-{
-	MiiPhy *miiphy;
-	int bit, phyno, r, rmask;
-
-	/*
-	 * Probe through mii for PHYs in mask;
-	 * return the mask of those found in the current probe.
-	 * If the PHY has not already been probed, update
-	 * the Mii information.
-	 */
-	rmask = 0;
-	for(phyno = 0; phyno < NMiiPhy; phyno++){
-		bit = 1<<phyno;
-		if(!(mask & bit))
-			continue;
-		if(mii->mask & bit){
-			rmask |= bit;
-			continue;
-		}
-		if(mii->mir(mii, phyno, Bmsr) == -1)
-			continue;
-		if((miiphy = malloc(sizeof(MiiPhy))) == nil)
-			continue;
-
-		miiphy->mii = mii;
-		r = mii->mir(mii, phyno, Phyidr1);
-		miiphy->oui = (r & 0x3FFF)<<6;
-		r = mii->mir(mii, phyno, Phyidr2);
-		miiphy->oui |= r>>10;
-		miiphy->phyno = phyno;
-
-		miiphy->anar = ~0;
-		miiphy->fc = ~0;
-		miiphy->mscr = ~0;
-
-		mii->phy[phyno] = miiphy;
-		if(mii->curphy == nil)
-			mii->curphy = miiphy;
-		mii->mask |= bit;
-		mii->nphy++;
-
-		rmask |= bit;
-	}
-	return rmask;
-}
-
-int
-miimir(Mii* mii, int r)
-{
-	if(mii == nil || mii->ctlr == nil || mii->curphy == nil)
-		return -1;
-	return mii->mir(mii, mii->curphy->phyno, r);
-}
-
-int
-miimiw(Mii* mii, int r, int data)
-{
-	if(mii == nil || mii->ctlr == nil || mii->curphy == nil)
-		return -1;
-	return mii->miw(mii, mii->curphy->phyno, r, data);
-}
-
-int
-miireset(Mii* mii)
-{
-	int bmcr;
-
-	if(mii == nil || mii->ctlr == nil || mii->curphy == nil)
-		return -1;
-	bmcr = mii->mir(mii, mii->curphy->phyno, Bmcr);
-	bmcr |= BmcrR;
-	mii->miw(mii, mii->curphy->phyno, Bmcr, bmcr);
-	microdelay(1);
-
-	return 0;
-}
-
-int
-miiane(Mii* mii, int a, int p, int e)
-{
-	int anar, bmsr, mscr, r, phyno;
-
-	if(mii == nil || mii->ctlr == nil || mii->curphy == nil)
-		return -1;
-	phyno = mii->curphy->phyno;
-
-	bmsr = mii->mir(mii, phyno, Bmsr);
-	if(!(bmsr & BmsrAna))
-		return -1;
-
-	if(a != ~0)
-		anar = (AnaTXFD|AnaTXHD|Ana10FD|Ana10HD) & a;
-	else if(mii->curphy->anar != ~0)
-		anar = mii->curphy->anar;
-	else{
-		anar = mii->mir(mii, phyno, Anar);
-		anar &= ~(AnaAP|AnaP|AnaT4|AnaTXFD|AnaTXHD|Ana10FD|Ana10HD);
-		if(bmsr & Bmsr10THD)
-			anar |= Ana10HD;
-		if(bmsr & Bmsr10TFD)
-			anar |= Ana10FD;
-		if(bmsr & Bmsr100TXHD)
-			anar |= AnaTXHD;
-		if(bmsr & Bmsr100TXFD)
-			anar |= AnaTXFD;
-	}
-	mii->curphy->anar = anar;
-
-	if(p != ~0)
-		anar |= (AnaAP|AnaP) & p;
-	else if(mii->curphy->fc != ~0)
-		anar |= mii->curphy->fc;
-	mii->curphy->fc = (AnaAP|AnaP) & anar;
-
-	if(bmsr & BmsrEs){
-		mscr = mii->mir(mii, phyno, Mscr);
-		mscr &= ~(Mscr1000TFD|Mscr1000THD);
-		if(e != ~0)
-			mscr |= (Mscr1000TFD|Mscr1000THD) & e;
-		else if(mii->curphy->mscr != ~0)
-			mscr = mii->curphy->mscr;
-		else{
-			r = mii->mir(mii, phyno, Esr);
-			if(r & Esr1000THD)
-				mscr |= Mscr1000THD;
-			if(r & Esr1000TFD)
-				mscr |= Mscr1000TFD;
-		}
-		mii->curphy->mscr = mscr;
-		mii->miw(mii, phyno, Mscr, mscr);
-	}
-	mii->miw(mii, phyno, Anar, anar);
-
-	r = mii->mir(mii, phyno, Bmcr);
-	if(!(r & BmcrR)){
-		r |= BmcrAne|BmcrRan;
-		mii->miw(mii, phyno, Bmcr, r);
-	}
-
-	return 0;
-}
-
-int
-miistatus(Mii* mii)
-{
-	MiiPhy *phy;
-	int anlpar, bmsr, p, r, phyno;
-
-	if(mii == nil || mii->ctlr == nil || mii->curphy == nil)
-		return -1;
-	phy = mii->curphy;
-	phyno = phy->phyno;
-
-	/*
-	 * Check Auto-Negotiation is complete and link is up.
-	 * (Read status twice as the Ls bit is sticky).
-	 */
-	bmsr = mii->mir(mii, phyno, Bmsr);
-	if(!(bmsr & (BmsrAnc|BmsrAna)))
-		return -1;
-
-	bmsr = mii->mir(mii, phyno, Bmsr);
-	if(!(bmsr & BmsrLs)){
-		phy->link = 0;
-		return -1;
-	}
-
-	phy->speed = phy->fd = phy->rfc = phy->tfc = 0;
-	if(phy->mscr){
-		r = mii->mir(mii, phyno, Mssr);
-		if((phy->mscr & Mscr1000TFD) && (r & Mssr1000TFD)){
-			phy->speed = 1000;
-			phy->fd = 1;
-		}
-		else if((phy->mscr & Mscr1000THD) && (r & Mssr1000THD))
-			phy->speed = 1000;
-	}
-
-	anlpar = mii->mir(mii, phyno, Anlpar);
-	if(phy->speed == 0){
-		r = phy->anar & anlpar;
-		if(r & AnaTXFD){
-			phy->speed = 100;
-			phy->fd = 1;
-		}
-		else if(r & AnaTXHD)
-			phy->speed = 100;
-		else if(r & Ana10FD){
-			phy->speed = 10;
-			phy->fd = 1;
-		}
-		else if(r & Ana10HD)
-			phy->speed = 10;
-	}
-	if(phy->speed == 0)
-		return -1;
-
-	if(phy->fd){
-		p = phy->fc;
-		r = anlpar & (AnaAP|AnaP);
-		if(p == AnaAP && r == (AnaAP|AnaP))
-			phy->tfc = 1;
-		else if(p == (AnaAP|AnaP) && r == AnaAP)
-			phy->rfc = 1;
-		else if((p & AnaP) && (r & AnaP))
-			phy->rfc = phy->tfc = 1;
-	}
-
-	phy->link = 1;
-
-	return 0;
-}

+ 0 - 125
sys/src/9/w/pxeload/ethermii.h

@@ -1,125 +0,0 @@
-/* 
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
-
-typedef struct Mii Mii;
-typedef struct MiiPhy MiiPhy;
-
-enum {					/* registers */
-	Bmcr		= 0x00,		/* Basic Mode Control */
-	Bmsr		= 0x01,		/* Basic Mode Status */
-	Phyidr1		= 0x02,		/* PHY Identifier #1 */
-	Phyidr2		= 0x03,		/* PHY Identifier #2 */
-	Anar		= 0x04,		/* Auto-Negotiation Advertisement */
-	Anlpar		= 0x05,		/* AN Link Partner Ability */
-	Aner		= 0x06,		/* AN Expansion */
-	Annptr		= 0x07,		/* AN Next Page TX */
-	Annprr		= 0x08,		/* AN Next Page RX */
-	Mscr		= 0x09,		/* MASTER-SLAVE Control */
-	Mssr		= 0x0A,		/* MASTER-SLAVE Status */
-	Esr		= 0x0F,		/* Extended Status */
-
-	NMiiPhyr	= 32,
-	NMiiPhy		= 32,
-};
-
-enum {					/* Bmcr */
-	BmcrSs1		= 0x0040,	/* Speed Select[1] */
-	BmcrCte		= 0x0080,	/* Collision Test Enable */
-	BmcrDm		= 0x0100,	/* Duplex Mode */
-	BmcrRan		= 0x0200,	/* Restart Auto-Negotiation */
-	BmcrI		= 0x0400,	/* Isolate */
-	BmcrPd		= 0x0800,	/* Power Down */
-	BmcrAne		= 0x1000,	/* Auto-Negotiation Enable */
-	BmcrSs0		= 0x2000,	/* Speed Select[0] */
-	BmcrLe		= 0x4000,	/* Loopback Enable */
-	BmcrR		= 0x8000,	/* Reset */
-};
-
-enum {					/* Bmsr */
-	BmsrEc		= 0x0001,	/* Extended Capability */
-	BmsrJd		= 0x0002,	/* Jabber Detect */
-	BmsrLs		= 0x0004,	/* Link Status */
-	BmsrAna		= 0x0008,	/* Auto-Negotiation Ability */
-	BmsrRf		= 0x0010,	/* Remote Fault */
-	BmsrAnc		= 0x0020,	/* Auto-Negotiation Complete */
-	BmsrPs		= 0x0040,	/* Preamble Suppression Capable */
-	BmsrEs		= 0x0100,	/* Extended Status */
-	Bmsr100T2HD	= 0x0200,	/* 100BASE-T2 HD Capable */
-	Bmsr100T2FD	= 0x0400,	/* 100BASE-T2 FD Capable */
-	Bmsr10THD	= 0x0800,	/* 100BASE-T HD Capable */
-	Bmsr10TFD	= 0x1000,	/* 10BASE-T FD Capable */
-	Bmsr100TXHD	= 0x2000,	/* 100BASE-TX HD Capable */
-	Bmsr100TXFD	= 0x4000,	/* 100BASE-TX FD Capable */
-	Bmsr100T4	= 0x8000,	/* 100BASE-T4 Capable */
-};
-
-enum {					/* Anar/Anlpar */
-	Ana10HD		= 0x0020,	/* Advertise 10BASE-T */
-	Ana10FD		= 0x0040,	/* Advertise 10BASE-T FD */
-	AnaTXHD		= 0x0080,	/* Advertise 100BASE-TX */
-	AnaTXFD		= 0x0100,	/* Advertise 100BASE-TX FD */
-	AnaT4		= 0x0200,	/* Advertise 100BASE-T4 */
-	AnaP		= 0x0400,	/* Pause */
-	AnaAP		= 0x0800,	/* Asymmetrical Pause */
-	AnaRf		= 0x2000,	/* Remote Fault */
-	AnaAck		= 0x4000,	/* Acknowledge */
-	AnaNp		= 0x8000,	/* Next Page Indication */
-};
-
-enum {					/* Mscr */
-	Mscr1000THD	= 0x0100,	/* Advertise 1000BASE-T HD */
-	Mscr1000TFD	= 0x0200,	/* Advertise 1000BASE-T FD */
-};
-
-enum {					/* Mssr */
-	Mssr1000THD	= 0x0400,	/* Link Partner 1000BASE-T HD able */
-	Mssr1000TFD	= 0x0800,	/* Link Partner 1000BASE-T FD able */
-};
-
-enum {					/* Esr */
-	Esr1000THD	= 0x1000,	/* 1000BASE-T HD Capable */
-	Esr1000TFD	= 0x2000,	/* 1000BASE-T FD Capable */
-	Esr1000XHD	= 0x4000,	/* 1000BASE-X HD Capable */
-	Esr1000XFD	= 0x8000,	/* 1000BASE-X FD Capable */
-};
-
-typedef struct Mii {
-	Lock;
-	int	nphy;
-	int	mask;
-	MiiPhy*	phy[NMiiPhy];
-	MiiPhy*	curphy;
-
-	void*	ctlr;
-	int	(*mir)(Mii*, int, int);
-	int	(*miw)(Mii*, int, int, int);
-} Mii;
-
-typedef struct MiiPhy {
-	Mii*	mii;
-	int	oui;
-	int	phyno;
-
-	int	anar;
-	int	fc;
-	int	mscr;
-
-	int	link;
-	int	speed;
-	int	fd;
-	int	rfc;
-	int	tfc;
-};
-
-extern int mii(Mii*, int);
-extern int miiane(Mii*, int, int, int);
-extern int miimir(Mii*, int);
-extern int miimiw(Mii*, int, int);
-extern int miireset(Mii*);
-extern int miistatus(Mii*);

+ 0 - 1050
sys/src/9/w/pxeload/ethervgbe.c

@@ -1,1050 +0,0 @@
-/*
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
-
-/*
- * VIA Velocity gigabit ethernet.
- * Register info has been stolen from FreeBSD driver.
- *
- * Has been tested on:
- *	- VIA8237 (ABIT AV8): 100Mpbs Full duplex only.
- *	  It works enough to run replica/pull, vncv, ...
- *
- * To do:
- *	- 64/48 bits
- *	- autonegotiation
- *	- thresholds
- *	- dynamic ring sizing ??
- *	- link status change
- *	- shutxbufown
- *	- promiscuous
- *	- report error
- *	- Rx/Tx Csum
- *	- Jumbo frames
- *
- * Philippe Anel, xigh@free.fr
- */
-
-#include "u.h"
-#include "lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-
-#include "etherif.h"
-#include "ethermii.h"
-
-#define DEBUG
-
-
-enum
-{
-	DumpIntr	= (1<<0),
-	DumpRx		= (1<<1),
-	DumpTx		= (1<<2),
-};
-
-#define htole16(x) (x)
-#define htole32(x) (x)
-#define le32toh(x) (x)
-
-enum
-{
-	Timeout		= 50000, // 10000000, //
-	RxCount		= 16,
-	TxCount		= 4,
-	RxSize		= 2048,
-
-	EthAddr		= 0x00,
-
-	/* Command registers. */
-	Cr0S		= 0x08,			/* Global command 0 (Set) */
-	Cr0C		= 0x0c,			/* Global command 0 (Clear) */
-		Cr0_Start	= 0x01,		/* - start MAC */
-		Cr0_Stop	= 0x02,		/* - stop MAC */
-		Cr0_EnableRx	= 0x04,		/* - turn on Rx engine */
-		Cr0_EnableTx	= 0x08,		/* - turn on Tx engine */
-
-	Cr1S		= 0x09,			/* Global command 1 (Set) */
-	Cr1C		= 0x0d,			/* Global command 1 (Clear) */
-		Cr1_NoPool	= 0x08,		/* - disable Rx/Tx desc pool */
-		Cr1_reset	= 0x80,		/* - software reset */
-
-	Cr2S		= 0x0a,			/* Global command 2 (Set) */
-		Cr2_XonEnable	= 0x80,		/* - 802.3x XON/XOFF flow control */
-
-	Cr3S		= 0x0b,			/* Global command 3 (Set) */
-	Cr3C		= 0x0f,			/* Global command 3 (Set) */
-		Cr3_IntMask	= 0x02,		/* - Mask all interrupts */
-
-	/* Eeprom registers. */
-	Eecsr		= 0x93,			/* EEPROM control/status */
-		Eecsr_Autold	= 0x20,		/* - trigger reload from EEPROM */
-
-	/* Mii registers. */
-	MiiStatus	= 0x6D,			/* MII port status */
-		MiiStatus_idle	= 0x80,		/* - idle */
-
-	MiiCmd		= 0x70,			/* MII command */
-		MiiCmd_write	= 0x20,		/* - write */
-		MiiCmd_read	= 0x40,		/* - read */
-		MiiCmd_auto	= 0x80,		/* - enable autopolling */
-
-	MiiAddr		= 0x71,			/* MII address */
-	MiiData		= 0x72,			/* MII data */
-
-	/* 64 bits related registers. */
-	TdHi	= 0x18,
-	DataBufHi	= 0x1d,
-
-	/* Rx engine registers. */
-	RdLo	= 0x38,			/* Rx descriptor base address (lo 32 bits) */
-	RxCsrS		= 0x32,			/* Rx descriptor queue control/status (Set) */
-	RxCsrC		= 0x36,			/* Rx descriptor queue control/status (Clear) */
-		RxCsr_RunQueue	= 0x01,		/* 	- enable queue */
-		RxCsr_Active	= 0x02,		/* - queue active indicator */
-		RxCsr_Wakeup	= 0x04,		/* - wake up queue */
-		RxCsr_Dead	= 0x08,		/* - queue dead indicator */
-	Rdcsize		= 0x50,			/* Size of Rx desc ring */
-	Rdindex	= 0x3c,			/* Current Rx descriptor index */
-	RxResCnt	= 0x5e,			/* Rx descriptor residue count */
-	Txesr = 0x22,
-		Tfdbs = (1<<19),
-		Tdwbs = (1<<18),
-		Tdrbs = (1<<17),
-		Tdstr = (1<<16),
-	Rxesr	= 0x23,			/* Rx host error status */
-		Rfdbs = (1<<19),
-		Rdwbs = (1<<18),
-		Rdrbs = (1<<17),
-		Rdstr = (1<<16),
-	RxTimer		= 0x3e,			/* Rx queue timer pend */
-	RxControl	= 0x06,			/* MAC Rx control */
-		RxControl_BadFrame = 0x01,	/* - accept CRC error frames */
-		RxControl_Runt = 0x02,		/* - accept runts */
-		RxControl_MultiCast = 0x04,	/* - accept multicasts */
-		RxControl_BroadCast = 0x08,	/* - accept broadcasts */
-		RxControl_Promisc = 0x10,	/* - promisc mode */
-		RxControl_Giant = 0x20,		/* - accept VLAN tagged frames */
-		RxControl_UniCast = 0x40,	/* - use perfect filtering */
-		RxControl_SymbolErr = 0x80,	/* - accept symbol err packet */
-	RxConfig	= 0x7e,			/* MAC Rx config */
-		RxConfig_VlanFilter = 0x01,	/* - filter VLAN ID mismatches */
-		RxConfig_VlanOpt0 = (0<<1),	/* - TX: no tag insert, RX: all, no extr */
-		RxConfig_VlanOpt1 = (1<<1),	/* - TX: no tag insert, RX: tagged pkts, no extr */
-		RxConfig_VlanOpt2 = (2<<1),	/* - TX: tag insert, RX: all, extract tags */
-		RxConfig_VlanOpt3 = (3<<1),	/* - TX: tag insert, RX: tagged pkts, with extr */
-		RxConfig_FifoLowWat = 0x08,	/* - RX FIFO low watermark (7QW/15QW) */
-		RxConfig_FifoTh128 = (0<<4),	/* - RX FIFO threshold 128 bytes */
-		RxConfig_FifoTh512 = (1<<4),	/* - RX FIFO threshold 512 bytes */
-		RxConfig_FifoTh1024 = (2<<4),	/* - RX FIFO threshold 1024 bytes */
-		RxConfig_FifoThFwd = (3<<4),	/* - RX FIFO threshold ??? */
-		RxConfig_ArbPrio = 0x80,	/* - arbitration priority */
-
-	/* Tx engine registers. */
-	TdLo	= 0x40,			/* Tx descriptor base address (lo 32 bits) */
-	TxCsrS		= 0x30,			/* Tx descriptor queue control/status (Set) */
-	TxCsrC		= 0x38,			/* Tx descriptor queue control/status (Clear) */
-		TxCsr_RunQueue	= 0x01,		/* 	- enable queue */
-		TxCsr_Active	= 0x02,		/* - queue active indicator */
-		TxCsr_Wakeup	= 0x04,		/* - wake up queue */
-		TxCsr_Dead	= 0x08,		/* - queue dead indicator */
-	TxNum		= 0x52,			/* Size of Tx desc ring */
-	TxDscIdx	= 0x54,			/* Current Tx descriptor index */
-	TxHostErr	= 0x22,			/* Tx host error status */
-	TxTimer		= 0x3f,			/* Tx queue timer pend */
-	TxControl	= 0x07,			/* MAC Rx control */
-		TxControl_LC_Off = (0<<0),	/* - loopback control off */
-		TxControl_LC_Mac = (1<<0),	/* - loopback control MAC internal */
-		TxControl_LC_Ext = (2<<0),	/* - loopback control external */
-		TxControl_Coll16 = (0<<2),	/* - one set of 16 retries */
-		TxControl_Coll32 = (1<<2),	/* - two sets of 16 retries */
-		TxControl_Coll48 = (2<<2),	/* - three sets of 16 retries */
-		TxControl_CollInf = (3<<2),	/* - retry forever */
-
-	TxConfig	= 0x7f,			/* MAC Tx config */
-		TxConfig_SnapOpt = 0x01,	/* - 1 == insert VLAN tag at 13th byte, */
-										/*	  0 == insert VLAN tag after SNAP header (21st byte) */
-		TxConfig_NonBlk	= 0x02,		/* - priority TX/non-blocking mode */
-		TxConfig_Blk64	= (0<<3),	/* - non-blocking threshold 64 packets */
-		TxConfig_Blk32	= (1<<3),	/* - non-blocking threshold 32 packets */
-		TxConfig_Blk128	= (2<<3),	/* - non-blocking threshold 128 packets */
-		TxConfig_Blk8	= (3<<3),	/* - non-blocking threshold 8 packets */
-		TxConfig_ArbPrio	= 0x80,	/* - arbitration priority */
-
-	/* Timer registers. */
-	Timer0		= 0x74,			/* single-shot timer */
-	Timer1		= 0x76,			/* periodic timer */
-
-	/* Chip config registers. */
-	ChipCfgA	= 0x78,			/* chip config A */
-	ChipCfgB	= 0x79,			/* chip config B */
-	ChipCfgC	= 0x7a,			/* chip config C */
-	ChipCfgD	= 0x7b,			/* chip config D */
-
-	/* DMA config registers. */
-	DmaCfg0		= 0x7C,			/* DMA config 0 */
-	DmaCfg1		= 0x7D,			/* DMA config 1 */
-
-	/* Interrupt registers. */
-	IntCtl		= 0x20,			/* Interrupt control */
-	Imr		= 0x28,			/* Interrupt mask */
-	isr		= 0x24,			/* Interrupt status */
-		Pprx	= (1<<0),	/* - hi prio Rx int */
-		Pptx	= (1<<1),	/* - hi prio Tx int */
-		Prx	= (1<<2),	/* - Rx queue completed */
-		Ptx	= (1<<3),	/* - One of Tx queues completed */
-
-		Ptx0	= (1<<4),	/* - Tx queue 0 completed */
-		Ptx1	= (1<<5),	/* - Tx queue 1 completed */
-		Ptx2	= (1<<6),	/* - Tx queue 2 completed */
-		Ptx3	= (1<<7),	/* - Tx queue 3 completed */
-
-		isr_Reserved8	= (1<<8),	/* - reserved */
-		isr_Reserver9	= (1<<9),	/* - reserved */
-		Race = (1<<10),	/* - Rx packet count overflow */
-		Flon	= (1<<11),	/* - pause frame Rx */
-
-		Ovf = (1<<12),	/* - RX FIFO overflow */
-		Lste	= (1<<13),	/* - ran out of Rx descriptors */
-		Lstpe	= (1<<14),	/* - running out of Rx descriptors */
-		Src	= (1<<15),	/* - link status change */
-
-		Tmr0	= (1<<16),	/* - one shot timer expired */
-		Tmr1	= (1<<17),	/* - periodic timer expired */
-		Pwe	= (1<<18),	/* - wake up power event */
-		Phyint	= (1<<19),	/* - PHY interrupt */
-
-		Shdn	= (1<<20),	/* - software shutxbufown complete */
-		isr_MibOvflow	= (1<<21),	/* - MIB counter overflow warning */
-		isr_SoftIntr	= (1<<22),	/* - software interrupt */
-		isr_HoldOffReload = (1<<23),	/* - reload hold timer */
-
-		Rxstl	= (1<<24),	/* - Rx DMA stall */
-		Txstl	= (1<<25),	/* - Tx DMA stall */
-		isr_Reserved26	= (1<<26),	/* - reserved */
-		isr_Reserved27	= (1<<27),	/* - reserved */
-
-		Isr0	= (1<<28),	/* - interrupt source indication */
-		Isr1	= (1<<29),	/* - interrupt source indication */
-		Isr2	= (1<<30),	/* - interrupt source indication */
-		Isr3	= (1<<31),	/* - interrupt source indication */
-
-	isr_Mask = Ptx0|Prx|Shdn|
-			Ovf|Phyint|Src|
-			Lste|Rxstl|Txstl
-};
-
-typedef struct Frag Frag;
-struct Frag
-{
-	uint32_t	addr_lo;
-	uint16_t	addr_hi;
-	uint16_t	length;
-};
-
-typedef struct Rd Rd;
-struct Rd
-{
-	uint32_t	status;
-	uint32_t	control;
-	Frag;
-};
-
-typedef struct Td Td;
-struct Td
-{
-	uint32_t	status;
-	uint32_t	control;
-	Frag	frags[7];
-};
-
-enum
-{
-	Vidm	= (1<<0),	/* VLAN tag filter miss */
-	Crc	= (1<<1),	/* bad CRC error */
-	Fae	= (1<<3),	/* frame alignment error */
-	Ce	= (1<<3),	/* bad TCP/IP checksum */
-	Rl	= (1<<4),	/* Rx length error */
-	Rxer	= (1<<5),	/* PCS symbol error */
-	Sntag	= (1<<6),	/* RX'ed tagged SNAP pkt */
-	Detag	= (1<<7),	/* VLAN tag extracted */
-
-	RDOneFrag	= (0<<8),	/* only one fragment */
-	RDFirstFrag	= (1<<8),	/* first frag in frame */
-	RDLastFrag	= (2<<8),	/* last frag in frame */
-	RDMidFrag	= (3<<8),	/* intermediate frag */
-
-	Vtag	= (1<<10),	/* VLAN tag indicator */
-	Phy	= (1<<11),	/* unicast frame */
-	Bar	= (1<<12),	/* broadcast frame */
-	Mar	= (1<<13),	/* multicast frame */
-	Pft	= (1<<14),	/* perfect filter hit */
-	Rxok	= (1<<15),	/* frame is good. */
-
-	RDSizShift	= 16,		/* received frame len shift */
-	RDSizMask	= 0x3FFF,	/* received frame len mask */
-
-	RDShutxbufown	= (1<<30),	/* shutxbufown during RX */
-	Own	= (1<<31),	/* own bit */
-
-	/* ... */
-
-	/* ... */
-	Td_Control_Intr	= (1<<23),	/* Tx intr request */
-	Td_Control_Normal	= (3<<24),	/* normal frame */
-};
-
-typedef struct Stats Stats;
-struct Stats
-{
-	uint32_t	rx;
-	uint32_t	tx;
-	uint32_t	txe;
-	uint32_t	intr;
-};
-
-enum {
-	Rblen64K	= 0x00001800,	/* 64KB+16 */
-
-	Rblen		= Rblen64K,	/* Receive Buffer Length */
-	Tdbsz		= ROUNDUP(sizeof(Etherpkt), 4),
-};
-
-typedef struct Ctlr Ctlr;
-struct Ctlr
-{
-	int	port;
-	Pcidev*	pcidev;
-	Ctlr	*next;
-	int	id;
-
-	int	inited;
-	Lock	ilock;
-
-	uint32_t	debugflags;
-	uint32_t	debugcount;
-
-	Mii*	mii;
-	int	active;
-	uint8_t	ea[6];
-
-	Rd*	rdring;
-	uint8_t*	rxbuf[RxCount];
-
-	Lock	tlock;
-	Td*	td;
-	uint8_t	txpkt[TxCount][sizeof(Etherpkt)];
-	uint32_t	tx_count;
-
-	Stats	stats;
-};
-
-static Ctlr* vgbectlrhead;
-static Ctlr* vgbectlrtail;
-
-#define riob(c, r)	inb((c)->port + (r))
-#define riow(c, r)	ins((c)->port + (r))
-#define riol(c, r)	inl((c)->port + (r))
-#define wiob(c, r, d)	outb((c)->port + (r), (d))
-#define wiow(c, r, d)	outs((c)->port + (r), (d))
-#define wiol(c, r, d)	outl((c)->port + (r), (d))
-
-#define siob(c, r, b)	wiob((c), (r), riob((c), (r)) | (b))
-#define siow(c, r, b)	wiow((c), (r), riob((c), r) | b)
-#define siol(c, r, b)	wiol(c, r, riob(c, r) | b)
-#define ciob(c, r, b)	wiob(c, r, riob(c, r) & ~b)
-#define ciow(c, r, b)	wiow(c, r, riob(c, r) & ~b)
-#define ciol(c, r, b)	wiol(c, r, riob(c, r) & ~b)
-
-static int
-vgbemiiw(Mii* mii, int phy, int addr, int data)
-{
-	Ctlr* ctlr;
-	int i;
-
-	if(phy != 1)
-		return -1;
-
-	ctlr = mii->ctlr;
-
-	// write our addr to the Mii
-	wiob(ctlr, MiiAddr, addr);
-	// write our data to the Mii data reg
-	wiow(ctlr, MiiData, (uint16_t) data);
-	wiob(ctlr, MiiCmd, MiiCmd_write);
-
-	// poll the mii
-	for(i = 0; i < Timeout; i++)
-		if((riob(ctlr, MiiCmd) & MiiCmd_write) == 0)
-			break;
-
-	if(i >= Timeout){
-		print("vgbe: miiw timeout\n");
-		return -1;
-	}
-
-	return 0;
-}
-
-static int
-vgbemiir(Mii* mii, int phy, int addr)
-{
-	Ctlr* ctlr;
-	int i;
-
-	if(phy != 1)
-		return -1;
-
-	ctlr = mii->ctlr;
-
-	wiob(ctlr, MiiAddr, addr);
-	wiob(ctlr, MiiCmd, MiiCmd_read);
-
-	for(i = 0; i < Timeout; i++)
-		if((riob(ctlr, MiiCmd) & MiiCmd_read) == 0)
-			break;
-
-	if(i >= Timeout){
-		print("vgbe: miir timeout\n");
-		return -1;
-	}
-
-	return riow(ctlr, MiiData);
-}
-
-
-static char* vgbeisr_info[] = {
-	"hi prio Rx int",
-	"hi prio Tx int",
-	"Rx queue completed",
-	"One of Tx queues completed",
-	"Tx queue 0 completed",
-	"Tx queue 1 completed",
-	"Tx queue 2 completed",
-	"Tx queue 3 completed",
-	"reserved",
-	"reserved",
-	"Rx packet count overflow",
-	"pause frame Rx'ed",
-	"RX FIFO overflow",
-	"ran out of Rx descriptors",
-	"running out of Rx descriptors",
-	"link status change",
-	"one shot timer expired",
-	"periodic timer expired",
-	"wake up power event",
-	"PHY interrupt",
-	"software shutxbufown complete",
-	"MIB counter overflow warning",
-	"software interrupt",
-	"reload hold timer",
-	"Rx DMA stall",
-	"Tx DMA stall",
-	"reserved",
-	"reserved",
-	"interrupt source indication 0",
-	"interrupt source indication 1",
-	"interrupt source indication 2",
-	"interrupt source indication 3",
-};
-
-static void
-vgbedumpisr(uint32_t isr)
-{
-	int i;
-	uint32_t mask;
-
-	for(i = 0; i < 32; i++){
-		mask = 1<<i;
-		if(isr & mask)
-			print("vgbe: irq:  - %02d : %c %s\n", i,
-			 	isr_Mask & mask ? '*' : '-', vgbeisr_info[i]);
-	}
-}
-
-static void
-noop(Block *)
-{
-}
-
-static int
-vgbenewrx(Ether* edev, int i)
-{
-	Rd* rd;
-	uint8_t *rb;
-	Ctlr* ctlr;
-
-	ctlr = edev->ctlr;
-
-	/*
-	 * allocate a receive Block.  we're maintaining
-	 * a private pool of Blocks, so we don't want freeb
-	 * to actually free them, thus we set block->free.
-	 */
-	rb = mallocz(RxSize, 1);
-	rb = (uint8_t*)ROUNDUP((uint32_t)rb, 64);
-	ctlr->rxbuf[i] = rb;
-
-	/* Initialize Rx descriptor. (TODO: 48/64 bits support ?) */
-	rd = &ctlr->rdring[i];
-	rd->status = htole32(Own);
-	rd->control = htole32(0);
-
-	rd->addr_lo = htole32((uint32_t)PADDR(rb));
-	rd->addr_hi = htole16(0);
-	rd->length = htole16(RxSize | 0x8000);
-
-	return 0;
-}
-
-static void
-toringbuf(Ether* edev, uint8_t* data, int len)
-{
-	RingBuf *rb;
-	extern int interesting(void*);
-
-	if(!interesting(data))
-		return;
-
-	rb = &edev->rb[edev->ri];
-	if(rb->owner == Interface){
-		if(len > sizeof(rb->pkt))
-			len = sizeof(rb->pkt);
-		rb->len = len;
-		memmove(rb->pkt, data, rb->len);
-		rb->owner = Host;
-		edev->ri = NEXT(edev->ri, edev->nrb);
-	}
-	else if(debug){
-		print("#l%d: toringbuf: dropping packets @ ri %d\n",
-			edev->ctlrno, edev->ri);
-	}
-}
-
-static void
-vgberxeof(Ether* edev)
-{
-	Ctlr* ctlr;
-	int i;
-	uint32_t length, status;
-	Rd* rd;
-	uint8_t *rb;
-
-	ctlr = edev->ctlr;
-
-	if(ctlr->debugflags & DumpRx)
-		print("vgbe: rx_eof\n");
-
-	for(i = 0; i < RxCount; i++){
-		rd = &ctlr->rdring[i];
-
-		status = le32toh(rd->status);
-
-		if(status & Own)
-			continue;
-
-		if(status & Rxok){
-			if(ctlr->debugflags & DumpRx)
-				print("vgbe: Receive successful!\n");
-			length = status >> RDSizShift;
-			length &= RDSizMask;
-
-			if(ctlr->debugflags & DumpRx)
-				print("vgbe: Rx-rd[%03d] status=%#08ulx ctl=%#08ulx len=%uld bytes\n",
-					i, status, rd->control, length);
-
-			rb = ctlr->rxbuf[i];
-			ctlr->stats.rx++;
-			if(ctlr->debugflags & DumpRx){
-				print("&edev->rb[edev->ri] %ulx rb %ulx length %uld\n",  &edev->rb[edev->ri], rb, length);
-				for(i = 0; i < length; i++)
-					print("%x ", rb[i]);
-				print("\n");
-			}
-			toringbuf(edev, rb, length);
-		}else
-			print("vgbe: Rx-rd[%#02x] *BAD FRAME* status=%#08ulx ctl=%#08ulx\n",
-				i, status, rd->control);
-
-		/* reset packet ... */
-		rd->status = htole32(Own);
-		rd->control = htole32(0);
-	}
-
-	if(ctlr->debugflags & DumpRx)
-		print("vgbe: rx_eof: done\n");
-
-	wiow(ctlr, RxResCnt, RxCount);
-	wiob(ctlr, RxCsrS, RxCsr_Wakeup);
-}
-
-static void
-vgbetxeof(Ether* edev)
-{
-	Ctlr* ctlr;
-	int i, count;
-	uint32_t status;
-
-	ctlr = edev->ctlr;
-
-	ilock(&ctlr->tlock);
-
-	if(ctlr->debugflags & DumpTx)
-		print("vgbe: tx_eof\n");
-
-	for(count = 0, i = 0; i < TxCount; i++){
-		status = le32toh(ctlr->td[i].status);
-		if(status & Own)
-			continue;
-
-		/* Todo add info if it failed */
-		ctlr->stats.tx++;
-
-		count++;
-	}
-	ctlr->tx_count -= count;
-
-	if(ctlr->debugflags & DumpTx)
-		print("vgbe: tx_eof: done [count=%d]\n", count);
-
-	iunlock(&ctlr->tlock);
-
-	if(ctlr->tx_count)
-		wiob(ctlr, TxCsrS, TxCsr_Wakeup);
-}
-
-static void
-vgbetransmit(Ether* edev)
-{
-	uint8_t *pkt;
-	Ctlr* ctlr;
-	int i, index, start, count;
-	Td* desc;
-	RingBuf *rb;
-	uint32_t status, length;
-
-	ctlr = edev->ctlr;
-
-	ilock(&ctlr->tlock);
-
-	/* find empty slot */
-	start = riow(ctlr, TxDscIdx);
-	for(count = 0, i = 0; i < TxCount; i++){
-		index = (i + start) % TxCount;
-
-		desc = &ctlr->td[index];
-		status = le32toh(desc->status);
-		if(status & Own)
-			continue;
-
-		rb = &edev->tb[edev->ti];
-		if(rb->owner != Interface)
-			break;
-
-		pkt = ctlr->txpkt[index];
-		length = rb->len;
-		memmove(pkt, rb->pkt, length);
-
-		count++;
-
-		/* Initialize Tx descriptor. */
-		desc->status = htole32((length<<16)|Own);
-		desc->control = htole32(Td_Control_Intr|Td_Control_Normal|((1+1)<<28));
-
-		desc->frags[0].addr_lo = htole32((uint32_t) PCIWADDR(pkt));
-		desc->frags[0].addr_hi = htole16(0);
-		desc->frags[0].length = htole16(length);
-		rb->owner = Host;
-		edev->ti = NEXT(edev->ti, edev->ntb);
-	}
-	ctlr->tx_count += count;
-
-	if(ctlr->debugflags & DumpTx)
-		print("vgbe: transmit: done [count=%d]\n", count);
-
-	iunlock(&ctlr->tlock);
-
-	if(ctlr->tx_count)
-		wiob(ctlr, TxCsrS, TxCsr_Wakeup);
-
-	if(count == 0)
-		print("vgbe: transmit: no Tx entry available\n");
-}
-
-static void
-vgbeattach(Ether* edev)
-{
-	Ctlr* ctlr;
-	Rd* rd;
-	Td* td;
-	int i;
-
-	ctlr = edev->ctlr;
-
-	// ctlr->debugflags |= DumpRx;
-//	ctlr->debugflags |= DumpRx|DumpTx;
-
-	// XXX: lock occurs in init
-	lock(&ctlr->ilock);
-	if(ctlr->inited){
-		unlock(&ctlr->ilock);
-		return;
-	}
-
-//	print("vgbe: attach\n");
-
-	/* Allocate Rx ring.  (TODO: Alignment ?) */
-	/*
-		ctlr->rblen == RxCount
-		ctlr->alloc = rd
-
-
-
-
-	*/
-	// he's making
-	rd = mallocalign(RxCount* sizeof(Rd), 256, 0, 0);
-	if(rd == nil){
-		print("vgbe: unable to alloc Rx ring\n");
-		unlock(&ctlr->ilock);
-		return;
-	}
-	ctlr->rdring = rd;
-
-	/* Allocate Rx blocks, initialize Rx ring. */
-	for(i = 0; i < RxCount; i++)
-		vgbenewrx(edev, i);
-
-	/* Init Rx MAC. */
-	wiob(ctlr, RxControl,
-		RxControl_MultiCast|RxControl_BroadCast|RxControl_UniCast);
-	wiob(ctlr, RxConfig, RxConfig_VlanOpt0);
-
-	/* Load Rx ring. */
-	wiol(ctlr, RdLo, (uint32_t) PCIWADDR(rd));
-	wiow(ctlr, Rdcsize, RxCount - 1);
-	wiow(ctlr, Rdindex, 0);
-	wiow(ctlr, RxResCnt, RxCount);
-
-	/* Allocate Tx ring. */
-	td = mallocalign(TxCount* sizeof(Td), 256, 0, 0);
-	if(td == nil){
-		print("vgbe: unable to alloc Tx ring\n");
-		unlock(&ctlr->ilock);
-		return;
-	}
-	ctlr->td = td;
-
-	/* Init DMAs */
-	wiob(ctlr, DmaCfg0, 4);
-
-	/* Init Tx MAC. */
-	wiob(ctlr, TxControl, 0);
-	wiob(ctlr, TxConfig, TxConfig_NonBlk|TxConfig_ArbPrio);
-
-	/* Load Tx ring. */
-	wiol(ctlr, TdLo, (uint32_t) PCIWADDR(td));
-	wiow(ctlr, TxNum, TxCount - 1);
-	wiow(ctlr, TxDscIdx, 0);
-
-	/* Enable Xon/Xoff */
-	wiob(ctlr, Cr2S, 0xb|Cr2_XonEnable);
-
-	/* Enable Rx queue */
-	wiob(ctlr, RxCsrS, RxCsr_RunQueue);
-
-	/* Enable Tx queue */
-	wiob(ctlr, TxCsrS, TxCsr_RunQueue);
-
-	/* Done */
-	ctlr->inited = 1;
-	unlock(&ctlr->ilock);
-
-	/* Enable interrupts */
-	wiol(ctlr, isr, 0xffffffff);
-	wiob(ctlr, Cr3S, Cr3_IntMask);
-
-	/* Wake up Rx queue */
-	wiob(ctlr, RxCsrS, RxCsr_Wakeup);
-}
-
-static int
-vgbereset(Ctlr* ctlr)
-{
-//	MiiPhy* phy;
-	int timeo, i;
-
-//	print("vgbe: reset: cr1s port: %x contents: %x\n", ctlr->port + Cr1S, riob(ctlr, Cr1S));
-
-	/* Soft reset the controller. */
-	wiob(ctlr, Cr1S, Cr1_reset);
-
-	for(timeo = 0; timeo < Timeout; timeo++)
-		if((riob(ctlr, Cr1S) & Cr1_reset) == 0)
-			break;
-
-	if(timeo >= Timeout){
-		print("vgbe: softreset timeout\n");
-		return -1;
-	}
-
-	/* Reload eeprom. */
-	siob(ctlr, Eecsr, Eecsr_Autold);
-
-	for(timeo = 0; timeo < Timeout; timeo++)
-		if((riob(ctlr, Eecsr) & Eecsr_Autold) == 0)
-			break;
-
-	if(timeo >= Timeout){
-		print("vgbe: eeprom reload timeout\n");
-		return -1;
-	}
-
-	/* Load the MAC address. */
-	for(i = 0; i < Eaddrlen; i++)
-		ctlr->ea[i] = riob(ctlr, EthAddr+i);
-//	print("vgbe: EA %E\n", ctlr->ea);
-
-	/* Initialize interrupts. */
-	wiol(ctlr, isr, 0xffffffff);
-	wiol(ctlr, Imr, 0xffffffff);
-
-	/* Disable interrupts. */
-	wiol(ctlr, Cr3C, Cr3_IntMask);
-
-	/* 32 bits addresses only. (TODO: 64 bits ?) */
-	wiol(ctlr, TdHi, 0);
-	wiow(ctlr, DataBufHi, 0);
-
-	/* Enable MAC (turning off Rx/Tx engines for the moment). */
-	wiob(ctlr, Cr0C, Cr0_Stop|Cr0_EnableRx|Cr0_EnableTx);
-	wiob(ctlr, Cr0S, Cr0_Start);
-
-	/* Initialize Rx engine. */
-	wiow(ctlr, RxCsrC, RxCsr_RunQueue);
-
-	/* Initialize Tx engine. */
-	wiow(ctlr, TxCsrC, TxCsr_RunQueue);
-
-	/* Enable Rx/Tx engines. */
-	wiob(ctlr, Cr0S, Cr0_EnableRx|Cr0_EnableTx);
-
-	/* Initialize link management. */
-	ctlr->mii = malloc(sizeof(Mii));
-	if(ctlr->mii == nil){
-		print("vgbe: unable to alloc Mii\n");
-		return -1;
-	}
-
-	ctlr->mii->mir = vgbemiir;
-	ctlr->mii->miw = vgbemiiw;
-	ctlr->mii->ctlr = ctlr;
-
-	if(mii(ctlr->mii, 1<<1) == 0){
-		print("vgbe: no phy found\n");
-		return -1;
-	}
-
-	return 0;
-//	phy = ctlr->mii->curphy;
-//	print("vgbe: phy:oui %#x\n", phy->oui);
-}
-
-void
-vgbedetach(Ether* edev)
-{
-	vgbereset(edev->ctlr);
-}
-
-
-
-static void
-vgbeinterrupt(Ureg *, void* arg)
-{
-	/* now we need to do something special to empty the ring buffer since we don't have the process */
-	Ether* edev;
-	Ctlr* ctlr;
-	uint32_t status;
-	uint32_t err;
-
-//	print("vgbe: Intr: entering interrupt\n");
-	edev = arg;
-	ctlr = edev->ctlr;
-
-	/* Mask interrupts. */
-	wiol(ctlr, Imr, 0);
-
-	status = riol(ctlr, isr);
-
-
-	if(status == 0xffff)
-		goto end;
-
-	/* acknowledge */
-	if(status)
-		wiol(ctlr, isr, status);
-
-	if((status & isr_Mask) == 0)
-		goto end;
-
-	ctlr->stats.intr++;
-
-	if(ctlr->debugflags & DumpIntr)
-		if(ctlr->debugcount){
-			print("vgbe: irq: status = %#08ulx\n", status);
-			vgbedumpisr(status);
-			ctlr->debugcount--;
-		}
-
-	if(status & Prx)
-		vgberxeof(edev);
-
-	if(status & Ptx0)
-		vgbetxeof(edev);
-
-	if(status & Shdn){
-		//print("vgbe: irq: software shutxbufown complete\n");
-	}
-	if(status & Ovf)
-		print("vgbe: irq: RX FIFO overflow\n");
-
-	if(status & Phyint)
-		print("vgbe: irq: PHY interrupt\n");
-
-	if(status & Src)
-		print("vgbe: irq: link status change\n");
-
-	if(status & Lste)
-		print("vgbe: irq: ran out of Rx descriptors\n");
-
-	if(status & Rxstl){
-		//print("vgbe: irq: Rx DMA stall\n");
-		err = riol(ctlr, Rxesr);
-		//print("vgbe: Rxesr %ulx\n", err);
-		if(err & Rfdbs)
-			print("Rx fifo dma bus error\n");
-		if(err & Rdwbs)
-			print("Rd write back host bus error\n");
-		if(err & Rdrbs)
-			print("Rd fetch host bus error.\n");
-		if(err & Rdstr)
-			print("Valid RD with linked buffer size zero.\n");
-		wiol(ctlr, Rxesr, 0);
-		wiol(ctlr, Cr3C, Cr3_IntMask);
-		return;
-	}
-
-	if(status & Txstl){
-		print("vgbe: irq: Tx DMA stall\n");
-		wiol(ctlr, Cr3C, Cr3_IntMask);
-		return;
-	}
-
-end:
-	/* Unmask interrupts. */
-	wiol(ctlr, Imr, ~0);
-}
-
-static void
-vgbepci(void)
-{
-	Pcidev *p;
-	Ctlr *ctlr;
-	int i, port;
-	uint32_t bar;
-
-	p = nil;
-	while(p = pcimatch(p, 0, 0)){
-		if(p->ccrb != 0x02 || p->ccru != 0)
-			continue;
-
-		switch((p->did<<16)|p->vid){
-		default:
-			continue;
-		case (0x3119<<16)|0x1106:
-			break;
-		}
-
-		bar = p->mem[0].bar;
-		port = bar & ~0x01;
-		if(ioalloc(port, p->mem[0].size, 0, "vgbe") < 0){
-			print("vgbe: port %#ux in use\n", port);
-			continue;
-		}
-		ctlr = malloc(sizeof(Ctlr));
-		ctlr->port = port;
-		ctlr->pcidev = p;
-
-		if(pcigetpms(p) > 0){
-			pcisetpms(p, 0);
-
-			for(i = 0; i < 6; i++)
-				pcicfgw32(p, PciBAR0+i*4, p->mem[i].bar);
-			pcicfgw8(p, PciINTL, p->intl);
-			pcicfgw8(p, PciLTR, p->ltr);
-			pcicfgw8(p, PciCLS, p->cls);
-			pcicfgw16(p, PciPCR, p->pcr);
-		}
-
-		if(vgbereset(ctlr)){
-			iofree(port);
-			free(ctlr);
-			continue;
-		}
-		pcisetbme(p);
-
-		if(vgbectlrhead != nil)
-			vgbectlrtail->next = ctlr;
-		else
-			vgbectlrhead = ctlr;
-		vgbectlrtail = ctlr;
-	}
-}
-
-int
-vgbepnp(Ether* edev)
-{
-	Ctlr *ctlr;
-
-	if(vgbectlrhead == nil)
-		vgbepci();
-
-	/*
-	 * Any adapter matches if no edev->port is supplied,
-	 * otherwise the ports must match.
-	 */
-	for(ctlr = vgbectlrhead; ctlr != nil; ctlr = ctlr->next){
-		if(ctlr->active)
-			continue;
-		if(edev->port == 0 || edev->port == ctlr->port){
-			ctlr->active = 1;
-			break;
-		}
-	}
-	if(ctlr == nil)
-		return -1;
-
-	edev->ctlr = ctlr;
-	edev->port = ctlr->port;
-	edev->irq = ctlr->pcidev->intl;
-	edev->tbdf = ctlr->pcidev->tbdf;
-
-	memmove(edev->ea, ctlr->ea, Eaddrlen);
-
-	/*
-	 * Linkage to the generic ethernet driver.
-	 */
-	edev->attach = vgbeattach;
-	edev->transmit = vgbetransmit;
-	edev->interrupt = vgbeinterrupt;
-	edev->detach = vgbedetach;
-
-	return 0;
-}

+ 0 - 192
sys/src/9/w/pxeload/fns.h

@@ -1,192 +0,0 @@
-/* 
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
-
-void	aamloop(int);
-void	addconf(char*, ...);
-Alarm*	alarm(int, void (*)(Alarm*), void*);
-void	alarminit(void);
-Block*	allocb(int);
-void	apminit(void);
-int	bootpboot(int, char*, Boot*);
-int	bootpass(Boot*, void*, int);
-void	cancel(Alarm*);
-int	cdinit(void);
-void	check(char*);
-void	cgaconsputs(char*, int);
-void	cgainit(void);
-void	cgapost(int);
-int	cistrcmp(char*, char*);
-int	cistrncmp(char*, char*, int);
-void	changeconf(char*, ...);
-void	checkalarms(void);
-void	clockinit(void);
-#define coherence()	mb386()
-void	consdrain(void);
-int	consinit(char*, char*);
-void	consputs(char*, int);
-void	delay(int);
-uchar*	etheraddr(int);
-int	etherinit(void);
-void	etherinitdev(int, char*);
-void	etherprintdevs(int);
-int	etherrxflush(int);
-int	etherrxpkt(int, Etherpkt*, int);
-int	ethertxpkt(int, Etherpkt*, int, int);
-#define	evenaddr(x)		/* 386 doesn't care */
-int	floppyboot(int, char*, Boot*);
-int	floppyinit(void);
-void	floppyinitdev(int, char*);
-void	floppyprintdevs(int);
-void*	floppygetfspart(int, char*, int);
-void	freeb(Block*);
-char*	getconf(char*);
-uint32_t	getcr0(void);
-uint32_t	getcr2(void);
-uint32_t	getcr3(void);
-uint32_t	getcr4(void);
-int	getfields(char*, char**, int, char);
-int	getstr(char*, char*, int, char*, int);
-int	gunzip(uchar*, int, uchar*, int);
-void	i8042a20(void);
-void	i8042init(void);
-void	i8042reset(void);
-void*	ialloc(uint32_t, int);
-void	idle(void);
-void	ilock(Lock*);
-void	impulse(void);
-int	inb(int);
-ushort	ins(int);
-uint32_t	inl(int);
-void	insb(int, void*, int);
-void	inss(int, void*, int);
-void	insl(int, void*, int);
-#define ioalloc(addr, len, align, name)	(addr)
-#define iofree(addr)
-void	iunlock(Lock*);
-int	isaconfig(char*, int, ISAConf*);
-void	kbdinit(void);
-void	kbdchar(int);
-void	lgdt(ushort[3]);
-void	lidt(ushort[3]);
-void	machinit(void);
-void	mapraminit(uvlong, uint32_t);
-void	mapupainit(uvlong, uint32_t);
-void	mb386(void);
-void	meminit(u32int);
-void	microdelay(int);
-void	mkmultiboot(void);
-void	mmuinit(void);
-#define	nelem(x)	(sizeof(x)/sizeof(x[0]))
-char*	nextelem(char*, char*);
-uchar	nvramread(int);
-void	outb(int, int);
-void	outs(int, ushort);
-void	outl(int, uint32_t);
-void	outsb(int, void*, int);
-void	outss(int, void*, int);
-void	outsl(int, void*, int);
-void	panic(char*, ...);
-uint32_t	pcibarsize(Pcidev*, int);
-int	pcicfgr8(Pcidev*, int);
-int	pcicfgr16(Pcidev*, int);
-int	pcicfgr32(Pcidev*, int);
-void	pcicfgw8(Pcidev*, int, int);
-void	pcicfgw16(Pcidev*, int, int);
-void	pcicfgw32(Pcidev*, int, int);
-void	pciclrbme(Pcidev*);
-void	pciclrioe(Pcidev*);
-void	pciclrmwi(Pcidev*);
-int	pcigetpms(Pcidev*);
-void	pcihinv(Pcidev*);
-uchar	pciipin(Pcidev*, uchar);
-Pcidev* pcimatch(Pcidev*, int, int);
-Pcidev* pcimatchtbdf(int);
-void	pcireset(void);
-void	pcisetbme(Pcidev*);
-void	pcisetioe(Pcidev*);
-void	pcisetmwi(Pcidev*);
-int	pcisetpms(Pcidev*, int);
-void	pcmcisread(PCMslot*);
-int	pcmcistuple(int, int, int, void*, int);
-PCMmap*	pcmmap(int, uint32_t, int, int);
-int	pcmspecial(char*, ISAConf*);
-void	pcmspecialclose(int);
-void	pcmunmap(int, PCMmap*);
-void	ptcheck(char*);
-void	putcr3(uint32_t);
-void	putidt(Segdesc*, int);
-void*	pxegetfspart(int, char*, int);
-void	qinit(IOQ*);
-void	readlsconf(void);
-void	sdaddconf(int);
-int	sdboot(int, char*, Boot*);
-void	sdcheck(char*);
-void*	sdgetfspart(int, char*, int);
-int	sdinit(void);
-void	sdinitdev(int, char*);
-void	sdprintdevs(int);
-int	sdsetpart(int, char*);
-void	setvec(int, void (*)(Ureg*, void*), void*);
-int	splhi(void);
-int	spllo(void);
-void	splx(int);
-void	startwheel(void);
-void	stopwheel(void);
-void	trapdisable(void);
-void	trapenable(void);
-void	trapinit(void);
-void	turnwheel(int);
-void	uartdrain(IOQ*);
-int	uartspecial(int, void (*)(int), int (*)(void), int);
-void	uartputs(IOQ*, char*, int);
-uint32_t	umbmalloc(uint32_t, int, int);
-void	umbfree(uint32_t, int);
-uint32_t	umbrwmalloc(uint32_t, int, int);
-void	upafree(uint32_t, int);
-uint32_t	upamalloc(uint32_t, int, int);
-void	warp64(uvlong);
-void	warp86(char*, uint32_t);
-void	warp9(uint32_t);
-int	x86cpuid(int*, int*);
-void*	xspanalloc(uint32_t, int, uint32_t);
-
-#define malloc(n)	ialloc(n, 0)
-#define mallocz(n, c)	ialloc(n, 0)
-#define free(v)		while(0)
-
-#define	GSHORT(p)	(((p)[1]<<8)|(p)[0])
-#define	GLONG(p)	((GSHORT(p+2)<<16)|GSHORT(p))
-#define	GLSHORT(p)	(((p)[0]<<8)|(p)[1])
-#define	GLLONG(p)	(((uint32_t)GLSHORT(p)<<16)|GLSHORT(p+2))
-#define	PLLONG(p,v)	(p)[3]=(v);(p)[2]=(v)>>8;(p)[1]=(v)>>16;(p)[0]=(v)>>24
-
-#define KADDR(a)	((void*)((uint32_t)(a)|KZERO))
-#define PADDR(a)	((uint32_t)(a)&~0xF0000000)
-
-#define	HOWMANY(x, y)	(((x)+((y)-1))/(y))
-#define ROUNDUP(x, y)	(HOWMANY((x), (y))*(y))
-
-
-#define xalloc(n)	ialloc(n, 0)
-#define xfree(v)	while(0)
-#define lock(l)		if(l){/* nothing to do */;}else{/* nothing to do */;}
-#define unlock(l)	if(l){/* nothing to do */;}else{/* nothing to do */;}
-
-int	dmacount(int);
-int	dmadone(int);
-void	dmaend(int);
-void	dmainit(int);
-long	dmasetup(int, void*, long, int);
-
-extern int (*_pcmspecial)(char *, ISAConf *);
-extern void (*_pcmspecialclose)(int);
-extern void devi82365link(void);
-extern void devpccardlink(void);
-
-#pragma incomplete Ureg

+ 0 - 103
sys/src/9/w/pxeload/fs.c

@@ -1,103 +0,0 @@
-/*
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
-
-#include	"u.h"
-#include	"lib.h"
-#include	"mem.h"
-#include	"dat.h"
-#include	"fns.h"
-#include	"io.h"
-
-#include	"fs.h"
-
-/*
- *  grab next element from a path, return the pointer to unprocessed portion of
- *  path.
- */
-char *
-nextelem(char *path, char *elem)
-{
-	int i;
-
-	while(*path == '/')
-		path++;
-	if(*path==0 || *path==' ')
-		return 0;
-	for(i=0; *path!='\0' && *path!='/' && *path!=' '; i++){
-		if(i==NAMELEN){
-			print("name component too long\n");
-			return 0;
-		}
-		*elem++ = *path++;
-	}
-	*elem = '\0';
-	return path;
-}
-
-int
-fswalk(Fs *fs, char *path, File *f)
-{
-	char element[NAMELEN];
-
-	*f = fs->root;
-	if(BADPTR(fs->walk))
-		panic("fswalk bad pointer fs->walk");
-
-	f->path = path;
-	while(path = nextelem(path, element)){
-		switch(fs->walk(f, element)){
-		case -1:
-			return -1;
-		case 0:
-			return 0;
-		}
-	}
-	return 1;
-}
-
-/*
- *  boot
- */
-int
-fsboot(Fs *fs, char *path, Boot *b)
-{
-	File file;
-	int32_t n;
-	static char buf[8192];
-
-	switch(fswalk(fs, path, &file)){
-	case -1:
-		print("error walking to %s\n", path);
-		return -1;
-	case 0:
-		print("%s not found\n", path);
-		return -1;
-	case 1:
-		print("found %s\n", path);
-		break;
-	}
-
-	while((n = fsread(&file, buf, sizeof buf)) > 0) {
-		if(bootpass(b, buf, n) != MORE)
-			break;
-	}
-
-	bootpass(b, nil, 0);	/* tries boot */
-	return -1;
-}
-
-int
-fsread(File *file, void *a, int32_t n)
-{
-	if(BADPTR(file->fs))
-		panic("bad pointer file->fs in fsread");
-	if(BADPTR(file->fs->read))
-		panic("bad pointer file->fs->read in fsread");
-	return file->fs->read(file, a, n);
-}

+ 0 - 45
sys/src/9/w/pxeload/fs.h

@@ -1,45 +0,0 @@
-/* 
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
-
-typedef struct File File;
-typedef struct Fs Fs;
-
-#include "dosfs.h"
-#include "kfs.h"
-
-struct File{
-	union{
-		Dosfile	dos;
-		Kfsfile	kfs;
-		int walked;
-	};
-	Fs	*fs;
-	char	*path;
-};
-
-struct Fs{
-	union {
-		Dos dos;
-		Kfs kfs;
-	};
-	int	dev;				/* device id */
-	long	(*diskread)(Fs*, void*, long);	/* disk read routine */
-	vlong	(*diskseek)(Fs*, vlong);	/* disk seek routine */
-	long	(*read)(File*, void*, long);
-	int	(*walk)(File*, char*);
-	File	root;
-};
-
-extern int chatty;
-extern int dotini(Fs*);
-extern int fswalk(Fs*, char*, File*);
-extern int fsread(File*, void*, long);
-extern int fsboot(Fs*, char*, Boot*);
-
-#define BADPTR(x) ((uint32_t)x < (uint32_t)(KZERO+0x7c00))

+ 0 - 355
sys/src/9/w/pxeload/i8250.c

@@ -1,355 +0,0 @@
-/*
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
-
-#include "u.h"
-#include "lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-
-/*
- *  INS8250 uart
- */
-enum
-{
-	/*
-	 *  register numbers
-	 */
-	Data=	0,		/* xmit/rcv buffer */
-	Iena=	1,		/* interrupt enable */
-	 Ircv=	(1<<0),		/*  for char rcv'd */
-	 Ixmt=	(1<<1),		/*  for xmit buffer empty */
-	 Irstat=(1<<2),		/*  for change in rcv'er status */
-	 Imstat=(1<<3),		/*  for change in modem status */
-	Istat=	2,		/* interrupt flag (read) */
-	Tctl=	2,		/* test control (write) */
-	Format=	3,		/* byte format */
-	 Bits8=	(3<<0),		/*  8 bits/byte */
-	 Stop2=	(1<<2),		/*  2 stop bits */
-	 Pena=	(1<<3),		/*  generate parity */
-	 Peven=	(1<<4),		/*  even parity */
-	 Pforce=(1<<5),		/*  force parity */
-	 Break=	(1<<6),		/*  generate a break */
-	 Dra=	(1<<7),		/*  address the divisor */
-	Mctl=	4,		/* modem control */
-	 Dtr=	(1<<0),		/*  data terminal ready */
-	 Rts=	(1<<1),		/*  request to send */
-	 Ri=	(1<<2),		/*  ring */
-	 Inton=	(1<<3),		/*  turn on interrupts */
-	 Loop=	(1<<4),		/*  loop back */
-	Lstat=	5,		/* line status */
-	 Inready=(1<<0),	/*  receive buffer full */
-	 Oerror=(1<<1),		/*  receiver overrun */
-	 Perror=(1<<2),		/*  receiver parity error */
-	 Ferror=(1<<3),		/*  rcv framing error */
-	 Outready=(1<<5),	/*  output buffer empty */
-	Mstat=	6,		/* modem status */
-	 Ctsc=	(1<<0),		/*  clear to send changed */
-	 Dsrc=	(1<<1),		/*  data set ready changed */
-	 Rire=	(1<<2),		/*  rising edge of ring indicator */
-	 Dcdc=	(1<<3),		/*  data carrier detect changed */
-	 Cts=	(1<<4),		/*  complement of clear to send line */
-	 Dsr=	(1<<5),		/*  complement of data set ready line */
-	 Ring=	(1<<6),		/*  complement of ring indicator line */
-	 Dcd=	(1<<7),		/*  complement of data carrier detect line */
-	Scratch=7,		/* scratchpad */
-	Dlsb=	0,		/* divisor lsb */
-	Dmsb=	1,		/* divisor msb */
-
-	Serial=	0,
-	Modem=	1,
-};
-
-typedef struct Uart	Uart;
-struct Uart
-{
-	int	port;
-	int	freq;
-	uint8_t	sticky[8];	/* sticky write register values */
-	uint8_t	txbusy;
-
-	void	(*rx)(int);	/* routine to take a received character */
-	int	(*tx)(void);	/* routine to get a character to transmit */
-
-	uint32_t	frame;
-	uint32_t	overrun;
-};
-
-static Uart com[2];
-static Uart* uart;
-
-#define UartFREQ 1843200
-
-#define uartwrreg(u,r,v)	outb((u)->port + r, (u)->sticky[r] | (v))
-#define uartrdreg(u,r)		inb((u)->port + r)
-
-/*
- *  set the baud rate by calculating and setting the baudrate
- *  generator constant.  This will work with fairly non-standard
- *  baud rates.
- */
-static void
-uartsetbaud(Uart *up, int rate)
-{
-	uint32_t brconst;
-
-	brconst = (up->freq+8*rate-1)/(16*rate);
-
-	uartwrreg(up, Format, Dra);
-	outb(up->port+Dmsb, (brconst>>8) & 0xff);
-	outb(up->port+Dlsb, brconst & 0xff);
-	uartwrreg(up, Format, 0);
-}
-
-/*
- *  toggle DTR
- */
-static void
-uartdtr(Uart *up, int n)
-{
-	if(n)
-		up->sticky[Mctl] |= Dtr;
-	else
-		up->sticky[Mctl] &= ~Dtr;
-	uartwrreg(up, Mctl, 0);
-}
-
-/*
- *  toggle RTS
- */
-static void
-uartrts(Uart *up, int n)
-{
-	if(n)
-		up->sticky[Mctl] |= Rts;
-	else
-		up->sticky[Mctl] &= ~Rts;
-	uartwrreg(up, Mctl, 0);
-}
-
-static void
-uartintr(Ureg*, void *arg)
-{
-	Uart *up;
-	int ch;
-	int s, l, loops;
-
-	up = arg;
-	for(loops = 0; loops < 1024; loops++){
-		s = uartrdreg(up, Istat);
-		switch(s & 0x3F){
-		case 6:	/* receiver line status */
-			l = uartrdreg(up, Lstat);
-			if(l & Ferror)
-				up->frame++;
-			if(l & Oerror)
-				up->overrun++;
-			break;
-
-		case 4:	/* received data available */
-		case 12:
-			ch = inb(up->port+Data);
-			if(up->rx)
-				(*up->rx)(ch);
-			break;
-
-		case 2:	/* transmitter empty */
-			ch = -1;
-			if(up->tx)
-				ch = (*up->tx)();
-			if(ch != -1)
-				outb(up->port+Data, ch);
-			else
-				up->txbusy = 0;
-			break;
-
-		case 0:	/* modem status */
-			uartrdreg(up, Mstat);
-			break;
-
-		default:
-			if(s&1)
-				return;
-			print("weird modem interrupt #%2.2ux\n", s);
-			break;
-		}
-	}
-	panic("uartintr: 0x%2.2ux\n", uartrdreg(up, Istat));
-}
-
-/*
- *  turn on a port's interrupts.  set DTR and RTS
- */
-static void
-uartenable(Uart *up)
-{
-	/*
- 	 *  turn on interrupts
-	 */
-	up->sticky[Iena] = 0;
-	if(up->tx)
-		up->sticky[Iena] |= Ixmt;
-	if(up->rx)
-		up->sticky[Iena] |= Ircv|Irstat;
-	uartwrreg(up, Iena, 0);
-
-	/*
-	 *  turn on DTR and RTS
-	 */
-	uartdtr(up, 1);
-	uartrts(up, 1);
-}
-
-static void
-uartdisable(Uart* up)
-{
-	/*
- 	 * Disable interrupts.
-	 */
-	up->sticky[Iena] = 0;
-	uartwrreg(up, Iena, 0);
-	uartdtr(up, 0);
-	uartrts(up, 0);
-}
-
-static void
-i8250thre(Uart* up)
-{
-	int i;
-
-	for(i = 0; i < 100; i++){
-		if(uartrdreg(up, Lstat) & Outready)
-			break;
-		delay(1);
-	}
-}
-
-int
-uartspecial(int which, void (*rx)(int), int (*tx)(void), int baud)
-{
-	Uart *up;
-	int freq, port, vector;
-	ISAConf isa;
-
-	switch(which){
-	case 0:
-		port = 0x3F8;
-		vector = VectorUART0;
-		freq = UartFREQ;
-		up = &com[0];
-		break;
-	case 1:
-		port = 0x2F8;
-		vector = VectorUART1;
-		freq = UartFREQ;
-		up = &com[1];
-		break;
-	default:
-		return 0;
-	}
-	memset(&isa, 0, sizeof(isa));
-	if(isaconfig("eia", which, &isa) != 0){
-		if(isa.port != 0)
-			port = isa.port;
-		if(isa.irq != 0)
-			vector = VectorPIC+isa.irq;
-		if(isa.freq != 0)
-			freq = isa.freq;
-	}
-
-	/*
-	 * Does it exist?
-	 * Should be able to write/read
-	 * the Scratch Pad.
-	 */
-	outb(port+Scratch, 0x55);
-	if(inb(port+Scratch) != 0x55)
-		return 0;
-
-	if(uart != nil && uart != up)
-		uartdisable(uart);
-	uart = up;
-
-	if(up->port == 0){
-		up->port = port;
-		setvec(vector, uartintr, up);
-	}
-
-	i8250thre(up);
-
-	/*
-	 *  set rate to 9600 baud.
-	 *  8 bits/character.
-	 *  1 stop bit.
-	 *  interrupts enabled.
-	 */
-	up->freq = freq;
-	uartsetbaud(up, 9600);
-	up->sticky[Format] = Bits8;
-	uartwrreg(up, Format, 0);
-	up->sticky[Mctl] |= Inton;
-	uartwrreg(up, Mctl, 0x0);
-
-	up->rx = rx;
-	up->tx = tx;
-	uartenable(up);
-	if(baud)
-		uartsetbaud(up, baud);
-
-	return 1;
-}
-
-void
-uartputc(int c)
-{
-	Uart *up;
-
-	if((up = uart) == nil)
-		return;
-	i8250thre(up);
-	outb(up->port+Data, c);
-}
-
-void
-uartputs(IOQ *q, char *s, int n)
-{
-	Uart *up;
-	int c, x;
-
-	if((up = uart) == nil)
-		return;
-	while(n--){
-		if(*s == '\n')
-			q->putc(q, '\r');
-		q->putc(q, *s++);
-	}
-	x = splhi();
-	if(up->txbusy == 0 && (c = q->getc(q)) != -1){
-		uartputc(c & 0xFF);
-		up->txbusy = 1;
-	}
-	splx(x);
-}
-
-void
-uartdrain(IOQ *q)
-{
-	Uart *up;
-	int c, timeo;
-
-	if((up = uart) == nil)
-		return;
-	for(timeo = 0; timeo < 10000 && up->txbusy; timeo++)
-		delay(1);
-	while((c = q->getc(q)) != -1)
-		uartputc(c & 0xFF);
-
-	uartdisable(up);
-}

+ 0 - 33
sys/src/9/w/pxeload/ilock.c

@@ -1,33 +0,0 @@
-/*
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
-
-#include "u.h"
-#include "lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-
-void
-ilock(Lock *lk)
-{
-	if(lk->locked != 0)
-		panic("ilock");
-	lk->spl = splhi();
-	lk->locked = 1;
-}
-
-void
-iunlock(Lock *lk)
-{
-	if(lk->locked != 1)
-		panic("iunlock");
-	lk->locked = 0;
-	splx(lk->spl);
-}

+ 0 - 208
sys/src/9/w/pxeload/inflate.c

@@ -1,208 +0,0 @@
-/*
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
-
-#include "u.h"
-#include "lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#include <flate.h>
-
-typedef struct Biobuf	Biobuf;
-
-struct Biobuf
-{
-	uint8_t *bp;
-	uint8_t *p;
-	uint8_t *ep;
-};
-
-static int	header(Biobuf*);
-static int	trailer(Biobuf*, Biobuf*);
-static int	getc(void*);
-static uint32_t	offset(Biobuf*);
-static int	crcwrite(void *out, void *buf, int n);
-static uint32_t	get4(Biobuf *b);
-static uint32_t	Boffset(Biobuf *bp);
-
-/* GZIP flags */
-enum {
-	Ftext=		(1<<0),
-	Fhcrc=		(1<<1),
-	Fextra=		(1<<2),
-	Fname=		(1<<3),
-	Fcomment=	(1<<4),
-
-	GZCRCPOLY	= 0xedb88320UL,
-};
-
-static uint32_t	*crctab;
-static uint32_t	crc;
-
-extern void diff(char*);	//XXX
-int
-gunzip(uint8_t *out, int outn, uint8_t *in, int inn)
-{
-	Biobuf bin, bout;
-	int err;
-
-	crc = 0;
-	crctab = mkcrctab(GZCRCPOLY);
-	err = inflateinit();
-	if(err != FlateOk)
-		print("inflateinit failed: %s\n", flateerr(err));
-
-	bin.bp = bin.p = in;
-	bin.ep = in+inn;
-	bout.bp = bout.p = out;
-	bout.ep = out+outn;
-
-	err = header(&bin);
-	if(err != FlateOk)
-		return err;
-
-	err = inflate(&bout, crcwrite, &bin, getc);
-	if(err != FlateOk)
-		print("inflate failed: %s\n", flateerr(err));
-
-	err = trailer(&bout, &bin);
-	if(err != FlateOk)
-		return err;
-
-	return Boffset(&bout);
-}
-
-static int
-header(Biobuf *bin)
-{
-	int i, flag;
-
-	if(getc(bin) != 0x1f || getc(bin) != 0x8b){
-		print("bad magic\n");
-		return FlateCorrupted;
-	}
-	if(getc(bin) != 8){
-		print("unknown compression type\n");
-		return FlateCorrupted;
-	}
-
-	flag = getc(bin);
-
-	/* mod time */
-	get4(bin);
-
-	/* extra flags */
-	getc(bin);
-
-	/* OS type */
-	getc(bin);
-
-	if(flag & Fextra)
-		for(i=getc(bin); i>0; i--)
-			getc(bin);
-
-	/* name */
-	if(flag&Fname)
-		while(getc(bin) != 0)
-			;
-
-	/* comment */
-	if(flag&Fcomment)
-		while(getc(bin) != 0)
-			;
-
-	/* crc16 */
-	if(flag&Fhcrc) {
-		getc(bin);
-		getc(bin);
-	}
-
-	return FlateOk;
-}
-
-static int
-trailer(Biobuf *bout, Biobuf *bin)
-{
-	/* crc32 */
-	if(crc != get4(bin)){
-		print("crc mismatch\n");
-		return FlateCorrupted;
-	}
-
-	/* length */
-	if(get4(bin) != Boffset(bout)){
-		print("bad output len\n");
-		return FlateCorrupted;
-	}
-	return FlateOk;
-}
-
-static uint32_t
-get4(Biobuf *b)
-{
-	uint32_t v;
-	int i, c;
-
-	v = 0;
-	for(i = 0; i < 4; i++){
-		c = getc(b);
-		v |= c << (i * 8);
-	}
-	return v;
-}
-
-static int
-getc(void *in)
-{
-	Biobuf *bp = in;
-
-//	if((bp->p - bp->bp) % 10000 == 0)
-//		print(".");
-	if(bp->p >= bp->ep)
-		return -1;
-	return *bp->p++;
-}
-
-static uint32_t
-Boffset(Biobuf *bp)
-{
-	return bp->p - bp->bp;
-}
-
-static int
-crcwrite(void *out, void *buf, int n)
-{
-	Biobuf *bp;
-	int nn;
-
-	crc = blockcrc(crctab, crc, buf, n);
-	bp = out;
-	nn = n;
-	if(nn > bp->ep-bp->p)
-		nn = bp->ep-bp->p;
-	if(nn > 0)
-		memmove(bp->p, buf, nn);
-	bp->p += n;
-	return n;
-}
-
-#undef malloc
-#undef free
-
-void *
-malloc(uint32_t n)
-{
-	return ialloc(n, 8);
-}
-
-void
-free(void *)
-{
-}

+ 0 - 279
sys/src/9/w/pxeload/io.h

@@ -1,279 +0,0 @@
-/* 
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
-
-/*
- *  programmable interrupt vectors (for the 8259's)
- */
-enum
-{
-	Bptvec=		3,		/* breakpoints */
-	Mathemuvec=	7,		/* math coprocessor emulation interrupt */
-	Mathovervec=	9,		/* math coprocessor overrun interrupt */
-	Matherr1vec=	16,		/* math coprocessor error interrupt */
-	Faultvec=	14,		/* page fault */
-
-	Syscallvec=	64,
-
-	VectorPIC	= 24,		/* external [A]PIC interrupts */
-	VectorCLOCK	= VectorPIC+0,
-	VectorKBD	= VectorPIC+1,
-	VectorUART1	= VectorPIC+3,
-	VectorUART0	= VectorPIC+4,
-	VectorPCMCIA	= VectorPIC+5,
-	VectorFLOPPY	= VectorPIC+6,
-	VectorLPT	= VectorPIC+7,
-	VectorIRQ7	= VectorPIC+7,
-	VectorAUX	= VectorPIC+12,	/* PS/2 port */
-	VectorIRQ13	= VectorPIC+13,	/* coprocessor on x386 */
-	VectorATA0	= VectorPIC+14,
-	VectorATA1	= VectorPIC+15,
-	MaxVectorPIC	= VectorPIC+15,
-};
-
-enum {
-	BusCBUS		= 0,		/* Corollary CBUS */
-	BusCBUSII,			/* Corollary CBUS II */
-	BusEISA,			/* Extended ISA */
-	BusFUTURE,			/* IEEE Futurebus */
-	BusINTERN,			/* Internal bus */
-	BusISA,				/* Industry Standard Architecture */
-	BusMBI,				/* Multibus I */
-	BusMBII,			/* Multibus II */
-	BusMCA,				/* Micro Channel Architecture */
-	BusMPI,				/* MPI */
-	BusMPSA,			/* MPSA */
-	BusNUBUS,			/* Apple Macintosh NuBus */
-	BusPCI,				/* Peripheral Component Interconnect */
-	BusPCMCIA,			/* PC Memory Card International Association */
-	BusTC,				/* DEC TurboChannel */
-	BusVL,				/* VESA Local bus */
-	BusVME,				/* VMEbus */
-	BusXPRESS,			/* Express System Bus */
-};
-
-#define MKBUS(t,b,d,f)	(((t)<<24)|(((b)&0xFF)<<16)|(((d)&0x1F)<<11)|(((f)&0x07)<<8))
-#define BUSFNO(tbdf)	(((tbdf)>>8)&0x07)
-#define BUSDNO(tbdf)	(((tbdf)>>11)&0x1F)
-#define BUSBNO(tbdf)	(((tbdf)>>16)&0xFF)
-#define BUSTYPE(tbdf)	((tbdf)>>24)
-#define BUSBDF(tbdf)	((tbdf)&0x00FFFF00)
-#define BUSUNKNOWN	(-1)
-
-enum {
-	MaxEISA		= 16,
-	CfgEISA		= 0xC80,
-};
-
-/*
- * PCI support code.
- */
-enum {					/* type 0 and type 1 pre-defined header */
-	PciVID		= 0x00,		/* vendor ID */
-	PciDID		= 0x02,		/* device ID */
-	PciPCR		= 0x04,		/* command */
-	PciPSR		= 0x06,		/* status */
-	PciRID		= 0x08,		/* revision ID */
-	PciCCRp		= 0x09,		/* programming interface class code */
-	PciCCRu		= 0x0A,		/* sub-class code */
-	PciCCRb		= 0x0B,		/* base class code */
-	PciCLS		= 0x0C,		/* cache line size */
-	PciLTR		= 0x0D,		/* latency timer */
-	PciHDT		= 0x0E,		/* header type */
-	PciBST		= 0x0F,		/* BIST */
-
-	PciBAR0		= 0x10,		/* base address */
-	PciBAR1		= 0x14,
-
-	PciINTL		= 0x3C,		/* interrupt line */
-	PciINTP		= 0x3D,		/* interrupt pin */
-};
-
-enum {					/* type 0 pre-defined header */
-	PciBAR2		= 0x18,
-	PciBAR3		= 0x1C,
-	PciBAR4		= 0x20,
-	PciBAR5		= 0x24,
-	PciCIS		= 0x28,		/* cardbus CIS pointer */
-	PciSVID		= 0x2C,		/* subsystem vendor ID */
-	PciSID		= 0x2E,		/* cardbus CIS pointer */
-	PciEBAR0	= 0x30,		/* expansion ROM base address */
-	PciMGNT		= 0x3E,		/* burst period length */
-	PciMLT		= 0x3F,		/* maximum latency between bursts */
-};
-
-enum {					/* type 1 pre-defined header */
-	PciPBN		= 0x18,		/* primary bus number */
-	PciSBN		= 0x19,		/* secondary bus number */
-	PciUBN		= 0x1A,		/* subordinate bus number */
-	PciSLTR		= 0x1B,		/* secondary latency timer */
-	PciIBR		= 0x1C,		/* I/O base */
-	PciILR		= 0x1D,		/* I/O limit */
-	PciSPSR		= 0x1E,		/* secondary status */
-	PciMBR		= 0x20,		/* memory base */
-	PciMLR		= 0x22,		/* memory limit */
-	PciPMBR		= 0x24,		/* prefetchable memory base */
-	PciPMLR		= 0x26,		/* prefetchable memory limit */
-	PciPUBR		= 0x28,		/* prefetchable base upper 32 bits */
-	PciPULR		= 0x2C,		/* prefetchable limit upper 32 bits */
-	PciIUBR		= 0x30,		/* I/O base upper 16 bits */
-	PciIULR		= 0x32,		/* I/O limit upper 16 bits */
-	PciEBAR1	= 0x28,		/* expansion ROM base address */
-	PciBCR		= 0x3E,		/* bridge control register */
-};
-
-enum {					/* type 2 pre-defined header */
-	PciCBExCA	= 0x10,
-	PciCBSPSR	= 0x16,
-	PciCBPBN	= 0x18,		/* primary bus number */
-	PciCBSBN	= 0x19,		/* secondary bus number */
-	PciCBUBN	= 0x1A,		/* subordinate bus number */
-	PciCBSLTR	= 0x1B,		/* secondary latency timer */
-	PciCBMBR0	= 0x1C,
-	PciCBMLR0	= 0x20,
-	PciCBMBR1	= 0x24,
-	PciCBMLR1	= 0x28,
-	PciCBIBR0	= 0x2C,		/* I/O base */
-	PciCBILR0	= 0x30,		/* I/O limit */
-	PciCBIBR1	= 0x34,		/* I/O base */
-	PciCBILR1	= 0x38,		/* I/O limit */
-	PciCBBCTL	= 0x3E,		/* Bridge control */
-	PciCBSVID	= 0x40,		/* subsystem vendor ID */
-	PciCBSID	= 0x42,		/* subsystem ID */
-	PciCBLMBAR	= 0x44,		/* legacy mode base address */
-};
-
-typedef struct Pcisiz Pcisiz;
-struct Pcisiz
-{
-	Pcidev*	dev;
-	int	siz;
-	int	bar;
-};
-
-typedef struct Pcidev Pcidev;
-typedef struct Pcidev {
-	int	tbdf;			/* type+bus+device+function */
-	ushort	vid;			/* vendor ID */
-	ushort	did;			/* device ID */
-
-	ushort	pcr;
-
-	uchar	rid;
-	uchar	ccrp;
-	uchar	ccru;
-	uchar	ccrb;
-	uchar	cls;
-	uchar	ltr;
-
-	struct {
-		uint32_t	bar;		/* base address */
-		int	size;
-	} mem[6];
-
-	struct {
-		uint32_t	bar;
-		int	size;
-	} rom;
-	uchar	intl;			/* interrupt line */
-	uchar	intp;			/* interrupt pin */
-
-	Pcidev*	list;
-	Pcidev*	link;			/* next device on this bno */
-
-	Pcidev*	bridge;			/* down a bus */
-	struct {
-		uint32_t	bar;
-		int	size;
-	} ioa, mema;
-
-	int	pmrb;			/* power management register block */
-};
-
-#define PCIWINDOW	0
-#define PCIWADDR(va)	(PADDR(va)+PCIWINDOW)
-#define ISAWINDOW	0
-#define ISAWADDR(va)	(PADDR(va)+ISAWINDOW)
-
-/*
- * PCMCIA support code.
- */
-typedef struct PCMslot		PCMslot;
-typedef struct PCMconftab	PCMconftab;
-
-/*
- * Map between ISA memory space and PCMCIA card memory space.
- */
-struct PCMmap {
-	uint32_t	ca;			/* card address */
-	uint32_t	cea;			/* card end address */
-	uint32_t	isa;			/* ISA address */
-	int	len;			/* length of the ISA area */
-	int	attr;			/* attribute memory */
-	int	ref;
-};
-
-/* configuration table entry */
-struct PCMconftab
-{
-	int	index;
-	ushort	irqs;		/* legal irqs */
-	uchar	irqtype;
-	uchar	bit16;		/* true for 16 bit access */
-	struct {
-		uint32_t	start;
-		uint32_t	len;
-	} io[16];
-	int	nio;
-	uchar	vpp1;
-	uchar	vpp2;
-	uchar	memwait;
-	uint32_t	maxwait;
-	uint32_t	readywait;
-	uint32_t	otherwait;
-};
-
-/* a card slot */
-struct PCMslot
-{
-	Lock;
-	int	ref;
-
-	void	*cp;		/* controller for this slot */
-	long	memlen;		/* memory length */
-	uchar	base;		/* index register base */
-	uchar	slotno;		/* slot number */
-
-	/* status */
-	uchar	special;	/* in use for a special device */
-	uchar	already;	/* already inited */
-	uchar	occupied;
-	uchar	battery;
-	uchar	wrprot;
-	uchar	powered;
-	uchar	configed;
-	uchar	enabled;
-	uchar	busy;
-
-	/* cis info */
-	ulong	msec;		/* time of last slotinfo call */
-	char	verstr[512];	/* version string */
-	int	ncfg;		/* number of configurations */
-	struct {
-		ushort	cpresent;	/* config registers present */
-		ulong	caddr;		/* relative address of config registers */
-	} cfg[8];
-	int	nctab;		/* number of config table entries */
-	PCMconftab	ctab[8];
-	PCMconftab	*def;	/* default conftab */
-
-	/* memory maps */
-	Lock	mlock;		/* lock down the maps */
-	int	time;
-	PCMmap	mmap[4];	/* maps, last is always for the kernel */
-};

+ 0 - 109
sys/src/9/w/pxeload/ip.h

@@ -1,109 +0,0 @@
-/* 
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
-
-typedef struct Udphdr Udphdr;
-struct Udphdr
-{
-	uchar	d[6];		/* Ethernet destination */
-	uchar	s[6];		/* Ethernet source */
-	uchar	type[2];	/* Ethernet packet type */
-
-	uchar	vihl;		/* Version and header length */
-	uchar	tos;		/* Type of service */
-	uchar	length[2];	/* packet length */
-	uchar	id[2];		/* Identification */
-	uchar	frag[2];	/* Fragment information */
-
-	/* Udp pseudo ip really starts here */
-	uchar	ttl;
-	uchar	udpproto;	/* Protocol */
-	uchar	udpplen[2];	/* Header plus data length */
-	uchar	udpsrc[4];	/* Ip source */
-	uchar	udpdst[4];	/* Ip destination */
-	uchar	udpsport[2];	/* Source port */
-	uchar	udpdport[2];	/* Destination port */
-	uchar	udplen[2];	/* data length */
-	uchar	udpcksum[2];	/* Checksum */
-};
-
-typedef struct Etherhdr Etherhdr;
-struct Etherhdr
-{
-	uchar	d[6];
-	uchar	s[6];
-	uchar	type[2];
-
-	/* Now we have the ip fields */
-	uchar	vihl;		/* Version and header length */
-	uchar	tos;		/* Type of service */
-	uchar	length[2];	/* packet length */
-	uchar	id[2];		/* Identification */
-	uchar	frag[2];	/* Fragment information */
-	uchar	ttl;		/* Time to live */
-	uchar	proto;		/* Protocol */
-	uchar	cksum[2];	/* Header checksum */
-	uchar	src[4];		/* Ip source */
-	uchar	dst[4];		/* Ip destination */
-};
-
-enum
-{
-	IP_VER		= 0x40,
-	IP_HLEN		= 0x05,		/* v4: Header length in 32-bit words */
- 	UDP_EHSIZE	= 22,
-	UDP_PHDRSIZE	= 12,
-	UDP_HDRSIZE	= 20,
-	ETHER_HDR	= 14,
-	IP_UDPPROTO	= 17,
-	ET_IP		= 0x800,
-	Bcastip		= 0xffffffff,
-	BPportsrc	= 68,
-	BPportdst	= 67,
-	TFTPport	= 69,
-	Timeout		= 5000,	/* milliseconds */
-	Bootrequest 	= 1,
-	Bootreply   	= 2,
-	Tftp_READ	= 1,
-	Tftp_WRITE	= 2,
-	Tftp_DATA	= 3,
-	Tftp_ACK	= 4,
-	Tftp_ERROR	= 5,
-	TFTP_SEGSIZE	= 512,
-	TFTP_HDRSIZE	= 4,
-};
-
-typedef struct Bootp Bootp;
-struct Bootp
-{
-	uchar	op;		/* opcode */
-	uchar	htype;		/* hardware type */
-	uchar	hlen;		/* hardware address len */
-	uchar	hops;		/* hops */
-	uchar	xid[4];		/* a random number */
-	uchar	secs[2];	/* elapsed since client started booting */
-	uchar	pad[2];
-	uchar	ciaddr[4];	/* client IP address (client tells server) */
-	uchar	yiaddr[4];	/* client IP address (server tells client) */
-	uchar	siaddr[4];	/* server IP address */
-	uchar	giaddr[4];	/* gateway IP address */
-	uchar	chaddr[16];	/* client hardware address */
-	char	sname[64];	/* server host name (optional) */
-	char	file[128];	/* boot file name */
-	char	vend[128];	/* vendor-specific goo */
-};
-
-typedef struct Netaddr Netaddr;
-struct Netaddr
-{
-	uint32_t	ip;
-	ushort	port;
-	char	ea[Eaddrlen];
-};
-
-extern int	eipfmt(Fmt*);

+ 0 - 516
sys/src/9/w/pxeload/kbd.c

@@ -1,516 +0,0 @@
-#include	"u.h"
-#include	"lib.h"
-#include	"mem.h"
-#include	"dat.h"
-#include	"fns.h"
-#include	"io.h"
-
-enum {
-	Data=		0x60,	/* data port */
-
-	Status=		0x64,	/* status port */
-	 Inready=	0x01,	/*  input character ready */
-	 Outbusy=	0x02,	/*  output busy */
-	 Sysflag=	0x04,	/*  system flag */
-	 Cmddata=	0x08,	/*  cmd==0, data==1 */
-	 Inhibit=	0x10,	/*  keyboard/mouse inhibited */
-	 Minready=	0x20,	/*  mouse character ready */
-	 Rtimeout=	0x40,	/*  general timeout */
-	 Parity=	0x80,
-
-	Cmd=		0x64,	/* command port (write only) */
-
-	Spec=	0x80,
-
-	PF=	Spec|0x20,	/* num pad function key */
-	View=	Spec|0x00,	/* view (shift window up) */
-	KF=	Spec|0x40,	/* function key */
-	Shift=	Spec|0x60,
-	Break=	Spec|0x61,
-	Ctrl=	Spec|0x62,
-	Latin=	Spec|0x63,
-	Caps=	Spec|0x64,
-	Num=	Spec|0x65,
-	No=	Spec|0x7F,	/* no mapping */
-
-	Home=	KF|13,
-	Up=	KF|14,
-	Pgup=	KF|15,
-	Print=	KF|16,
-	Left=	View,
-	Right=	View,
-	End=	'\r',
-	Down=	View,
-	Pgdown=	View,
-	Ins=	KF|20,
-	Del=	0x7F,
-};
-
-uchar kbtab[] =
-{
-[0x00]	No,	0x1b,	'1',	'2',	'3',	'4',	'5',	'6',
-[0x08]	'7',	'8',	'9',	'0',	'-',	'=',	'\b',	'\t',
-[0x10]	'q',	'w',	'e',	'r',	't',	'y',	'u',	'i',
-[0x18]	'o',	'p',	'[',	']',	'\n',	Ctrl,	'a',	's',
-[0x20]	'd',	'f',	'g',	'h',	'j',	'k',	'l',	';',
-[0x28]	'\'',	'`',	Shift,	'\\',	'z',	'x',	'c',	'v',
-[0x30]	'b',	'n',	'm',	',',	'.',	'/',	Shift,	No,
-[0x38]	Latin,	' ',	Caps,	KF|1,	KF|2,	KF|3,	KF|4,	KF|5,
-[0x40]	KF|6,	KF|7,	KF|8,	KF|9,	KF|10,	Num,	KF|12,	Home,
-[0x48]	No,	No,	No,	No,	No,	No,	No,	No,
-[0x50]	No,	No,	No,	No,	No,	No,	No,	KF|11,
-[0x58]	KF|12,	No,	No,	No,	No,	No,	No,	No,
-};
-
-uchar kbtabshift[] =
-{
-[0x00]	No,	0x1b,	'!',	'@',	'#',	'$',	'%',	'^',
-[0x08]	'&',	'*',	'(',	')',	'_',	'+',	'\b',	'\t',
-[0x10]	'Q',	'W',	'E',	'R',	'T',	'Y',	'U',	'I',
-[0x18]	'O',	'P',	'{',	'}',	'\n',	Ctrl,	'A',	'S',
-[0x20]	'D',	'F',	'G',	'H',	'J',	'K',	'L',	':',
-[0x28]	'"',	'~',	Shift,	'|',	'Z',	'X',	'C',	'V',
-[0x30]	'B',	'N',	'M',	'<',	'>',	'?',	Shift,	No,
-[0x38]	Latin,	' ',	Caps,	KF|1,	KF|2,	KF|3,	KF|4,	KF|5,
-[0x40]	KF|6,	KF|7,	KF|8,	KF|9,	KF|10,	Num,	KF|12,	Home,
-[0x48]	No,	No,	No,	No,	No,	No,	No,	No,
-[0x50]	No,	No,	No,	No,	No,	No,	No,	KF|11,
-[0x58]	KF|12,	No,	No,	No,	No,	No,	No,	No,
-};
-
-uchar kbtabesc1[] =
-{
-[0x00]	No,	No,	No,	No,	No,	No,	No,	No,
-[0x08]	No,	No,	No,	No,	No,	No,	No,	No,
-[0x10]	No,	No,	No,	No,	No,	No,	No,	No,
-[0x18]	No,	No,	No,	No,	No,	Ctrl,	No,	No,
-[0x20]	No,	No,	No,	No,	No,	No,	No,	No,
-[0x28]	No,	No,	No,	No,	No,	No,	No,	No,
-[0x30]	No,	No,	No,	No,	No,	No,	No,	Print,
-[0x38]	Latin,	No,	No,	No,	No,	No,	No,	No,
-[0x40]	No,	No,	No,	No,	No,	No,	Break,	Home,
-[0x48]	Up,	Pgup,	No,	Down,	No,	Right,	No,	End,
-[0x50]	Left,	Pgdown,	Ins,	Del,	No,	No,	No,	No,
-[0x58]	No,	No,	No,	No,	No,	No,	No,	No,
-};
-
-struct latin
-{
-	uint8_t	l;
-	char	c[2];
-}latintab[] = {
-	L'¡',	"!!",	/* spanish initial ! */
-	L'¢',	"c|",	/* cent */
-	L'¢',	"c$",	/* cent */
-	L'£',	"l$",	/* pound sterling */
-	L'¤',	"g$",	/* general currency */
-	L'¥',	"y$",	/* yen */
-	L'¥',	"j$",	/* yen */
-	L'¦',	"||",	/* broken vertical bar */
-	L'§',	"SS",	/* section symbol */
-	L'¨',	"\"\"",	/* dieresis */
-	L'©',	"cr",	/* copyright */
-	L'©',	"cO",	/* copyright */
-	L'ª',	"sa",	/* super a, feminine ordinal */
-	L'«',	"<<",	/* left angle quotation */
-	L'¬',	"no",	/* not sign, hooked overbar */
-	L'­',	"--",	/* soft hyphen */
-	L'®',	"rg",	/* registered trademark */
-	L'¯',	"__",	/* macron */
-	L'°',	"s0",	/* degree (sup o) */
-	L'±',	"+-",	/* plus-minus */
-	L'²',	"s2",	/* sup 2 */
-	L'³',	"s3",	/* sup 3 */
-	L'´',	"''",	/* grave accent */
-	L'µ',	"mu",	/* mu */
-	L'¶',	"pg",	/* paragraph (pilcrow) */
-	L'·',	"..",	/* centered . */
-	L'¸',	",,",	/* cedilla */
-	L'¹',	"s1",	/* sup 1 */
-	L'º',	"so",	/* sup o */
-	L'»',	">>",	/* right angle quotation */
-	L'¼',	"14",	/* 1/4 */
-	L'½',	"12",	/* 1/2 */
-	L'¾',	"34",	/* 3/4 */
-	L'¿',	"??",	/* spanish initial ? */
-	L'À',	"A`",	/* A grave */
-	L'Á',	"A'",	/* A acute */
-	L'Â',	"A^",	/* A circumflex */
-	L'Ã',	"A~",	/* A tilde */
-	L'Ä',	"A\"",	/* A dieresis */
-	L'Ä',	"A:",	/* A dieresis */
-	L'Å',	"Ao",	/* A circle */
-	L'Å',	"AO",	/* A circle */
-	L'Æ',	"Ae",	/* AE ligature */
-	L'Æ',	"AE",	/* AE ligature */
-	L'Ç',	"C,",	/* C cedilla */
-	L'È',	"E`",	/* E grave */
-	L'É',	"E'",	/* E acute */
-	L'Ê',	"E^",	/* E circumflex */
-	L'Ë',	"E\"",	/* E dieresis */
-	L'Ë',	"E:",	/* E dieresis */
-	L'Ì',	"I`",	/* I grave */
-	L'Í',	"I'",	/* I acute */
-	L'Î',	"I^",	/* I circumflex */
-	L'Ï',	"I\"",	/* I dieresis */
-	L'Ï',	"I:",	/* I dieresis */
-	L'Ð',	"D-",	/* Eth */
-	L'Ñ',	"N~",	/* N tilde */
-	L'Ò',	"O`",	/* O grave */
-	L'Ó',	"O'",	/* O acute */
-	L'Ô',	"O^",	/* O circumflex */
-	L'Õ',	"O~",	/* O tilde */
-	L'Ö',	"O\"",	/* O dieresis */
-	L'Ö',	"O:",	/* O dieresis */
-	L'Ö',	"OE",	/* O dieresis */
-	L'Ö',	"Oe",	/* O dieresis */
-	L'×',	"xx",	/* times sign */
-	L'Ø',	"O/",	/* O slash */
-	L'Ù',	"U`",	/* U grave */
-	L'Ú',	"U'",	/* U acute */
-	L'Û',	"U^",	/* U circumflex */
-	L'Ü',	"U\"",	/* U dieresis */
-	L'Ü',	"U:",	/* U dieresis */
-	L'Ü',	"UE",	/* U dieresis */
-	L'Ü',	"Ue",	/* U dieresis */
-	L'Ý',	"Y'",	/* Y acute */
-	L'Þ',	"P|",	/* Thorn */
-	L'Þ',	"Th",	/* Thorn */
-	L'Þ',	"TH",	/* Thorn */
-	L'ß',	"ss",	/* sharp s */
-	L'à',	"a`",	/* a grave */
-	L'á',	"a'",	/* a acute */
-	L'â',	"a^",	/* a circumflex */
-	L'ã',	"a~",	/* a tilde */
-	L'ä',	"a\"",	/* a dieresis */
-	L'ä',	"a:",	/* a dieresis */
-	L'å',	"ao",	/* a circle */
-	L'æ',	"ae",	/* ae ligature */
-	L'ç',	"c,",	/* c cedilla */
-	L'è',	"e`",	/* e grave */
-	L'é',	"e'",	/* e acute */
-	L'ê',	"e^",	/* e circumflex */
-	L'ë',	"e\"",	/* e dieresis */
-	L'ë',	"e:",	/* e dieresis */
-	L'ì',	"i`",	/* i grave */
-	L'í',	"i'",	/* i acute */
-	L'î',	"i^",	/* i circumflex */
-	L'ï',	"i\"",	/* i dieresis */
-	L'ï',	"i:",	/* i dieresis */
-	L'ð',	"d-",	/* eth */
-	L'ñ',	"n~",	/* n tilde */
-	L'ò',	"o`",	/* o grave */
-	L'ó',	"o'",	/* o acute */
-	L'ô',	"o^",	/* o circumflex */
-	L'õ',	"o~",	/* o tilde */
-	L'ö',	"o\"",	/* o dieresis */
-	L'ö',	"o:",	/* o dieresis */
-	L'ö',	"oe",	/* o dieresis */
-	L'÷',	"-:",	/* divide sign */
-	L'ø',	"o/",	/* o slash */
-	L'ù',	"u`",	/* u grave */
-	L'ú',	"u'",	/* u acute */
-	L'û',	"u^",	/* u circumflex */
-	L'ü',	"u\"",	/* u dieresis */
-	L'ü',	"u:",	/* u dieresis */
-	L'ü',	"ue",	/* u dieresis */
-	L'ý',	"y'",	/* y acute */
-	L'þ',	"th",	/* thorn */
-	L'þ',	"p|",	/* thorn */
-	L'ÿ',	"y\"",	/* y dieresis */
-	L'ÿ',	"y:",	/* y dieresis */
-	0,	0,
-};
-
-enum
-{
-	/* controller command byte */
-	Cscs1=		(1<<6),		/* scan code set 1 */
-	Cmousedis=	(1<<5),		/* mouse disable */
-	Ckbddis=	(1<<4),		/* kbd disable */
-	Csf=		(1<<2),		/* system flag */
-	Cmouseint=	(1<<1),		/* mouse interrupt enable */
-	Ckbdint=	(1<<0),		/* kbd interrupt enable */
-};
-
-static uint8_t ccc;
-static int nokbd = 1;
-
-int
-latin1(int k1, int k2)
-{
-	struct latin *l;
-
-	for(l=latintab; l->l; l++)
-		if(k1==l->c[0] && k2==l->c[1])
-			return l->l;
-	return 0;
-}
-
-/*
- *  wait for output no longer busy
- */
-static int
-outready(void)
-{
-	int tries;
-
-	for(tries = 0; (inb(Status) & Outbusy); tries++){
-		if(tries > 500)
-			return -1;
-		delay(2);
-	}
-	return 0;
-}
-
-/*
- *  wait for input
- */
-static int
-inready(void)
-{
-	int tries;
-
-	for(tries = 0; !(inb(Status) & Inready); tries++){
-		if(tries > 500)
-			return -1;
-		delay(2);
-	}
-	return 0;
-}
-
-/*
- *  ask 8042 to enable the use of address bit 20
- */
-void
-i8042a20(void)
-{
-	outready();
-	outb(Cmd, 0xD1);
-	outready();
-	outb(Data, 0xDF);
-	outready();
-}
-
-/*
- *  ask 8042 to reset the machine
- */
-void
-i8042reset(void)
-{
-	int i, x;
-
-	if(nokbd)
-		return;
-
-	*((uint16_t*)KADDR(0x472)) = 0x1234;	/* BIOS warm-boot flag */
-
-	/*
-	 *  newer reset the machine command
-	 */
-	outready();
-	outb(Cmd, 0xFE);
-	outready();
-
-	/*
-	 *  Pulse it by hand (old somewhat reliable)
-	 */
-	x = 0xDF;
-	for(i = 0; i < 5; i++){
-		x ^= 1;
-		outready();
-		outb(Cmd, 0xD1);
-		outready();
-		outb(Data, x);	/* toggle reset */
-		delay(100);
-	}
-}
-
-/*
- *  keyboard interrupt
- */
-static void
-i8042intr(Ureg*, void*)
-{
-	int s, c;
-	static int esc1, esc2;
-	static int alt, caps, ctl, num, shift;
-	static int lstate, k1, k2;
-	int keyup;
-
-	/*
-	 *  get status
-	 */
-	s = inb(Status);
-	if(!(s&Inready))
-		return;
-
-	/*
-	 *  get the character
-	 */
-	c = inb(Data);
-
-	/*
-	 *  if it's the aux port...
-	 */
-	if(s & Minready)
-		return;
-
-	/*
-	 *  e0's is the first of a 2 character sequence
-	 */
-	if(c == 0xe0){
-		esc1 = 1;
-		return;
-	} else if(c == 0xe1){
-		esc2 = 2;
-		return;
-	}
-
-	keyup = c&0x80;
-	c &= 0x7f;
-	if(c > sizeof kbtab){
-		c |= keyup;
-		if(c != 0xFF)	/* these come fairly often: CAPSLOCK U Y */
-			print("unknown key %ux\n", c);
-		return;
-	}
-
-	if(esc1){
-		c = kbtabesc1[c];
-		esc1 = 0;
-	} else if(esc2){
-		esc2--;
-		return;
-	} else if(shift)
-		c = kbtabshift[c];
-	else
-		c = kbtab[c];
-
-	if(caps && c<='z' && c>='a')
-		c += 'A' - 'a';
-
-	/*
-	 *  keyup only important for shifts
-	 */
-	if(keyup){
-		switch(c){
-		case Latin:
-			alt = 0;
-			break;
-		case Shift:
-			shift = 0;
-			break;
-		case Ctrl:
-			ctl = 0;
-			break;
-		}
-		return;
-	}
-
-	/*
- 	 *  normal character
-	 */
-	if(!(c & Spec)){
-		if(ctl){
-			if(alt && c == Del)
-				warp86("\nCtrl-Alt-Del\n", 0);
-			c &= 0x1f;
-		}
-		switch(lstate){
-		case 1:
-			k1 = c;
-			lstate = 2;
-			return;
-		case 2:
-			k2 = c;
-			lstate = 0;
-			c = latin1(k1, k2);
-			if(c == 0){
-				kbdchar(k1);
-				c = k2;
-			}
-			/* fall through */
-		default:
-			break;
-		}
-	} else {
-		switch(c){
-		case Caps:
-			caps ^= 1;
-			return;
-		case Num:
-			num ^= 1;
-			return;
-		case Shift:
-			shift = 1;
-			return;
-		case Latin:
-			alt = 1;
-			lstate = 1;
-			return;
-		case Ctrl:
-			ctl = 1;
-			return;
-		}
-	}
-	kbdchar(c);
-}
-
-static char *initfailed = "i8042: kbdinit failed\n";
-
-static int
-outbyte(int port, int c)
-{
-	outb(port, c);
-	if(outready() < 0) {
-//		vga = 0;
-		print(initfailed);
-		return -1;
-	}
-	return 0;
-}
-
-void
-i8042init(void)
-{
-	int c, try;
-
-	/* wait for a quiescent controller */
-	try = 1000;
-	while(try-- > 0 && (c = inb(Status)) & (Outbusy | Inready)) {
-		if(c & Inready)
-			inb(Data);
-		delay(1);
-	}
-	if (try <= 0) {
-//		vga = 0;
-		print(initfailed);
-		return;
-	}
-
-	/* get current controller command byte */
-	outb(Cmd, 0x20);
-	if(inready() < 0){
-		print("i8042: kbdinit can't read ccc\n");
-		ccc = 0;
-	} else
-		ccc = inb(Data);
-
-	/* enable kbd xfers and interrupts */
-	ccc &= ~Ckbddis;
-	ccc |= Csf | Ckbdint | Cscs1;
-	if(outready() < 0) {
-//		vga = 0;
-		print(initfailed);
-		return;
-	}
-
-	nokbd = 0;
-
-	/* disable mouse */
-	if (outbyte(Cmd, 0x60) < 0 || outbyte(Data, ccc) < 0)
-		print("i8042: kbdinit mouse disable failed\n");
-
-	setvec(VectorKBD, i8042intr, 0);
-}

+ 0 - 66
sys/src/9/w/pxeload/kfs.h

@@ -1,66 +0,0 @@
-/* 
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
-
-typedef struct Qid9p1 Qid9p1;
-typedef struct Dentry Dentry;
-typedef struct Kfsfile Kfsfile;
-typedef struct Kfs Kfs;
-
-/* DONT TOUCH, this is the disk structure */
-struct	Qid9p1
-{
-	long	path;
-	long	version;
-};
-
-//#define	NAMELEN		28		/* size of names */
-#define	NDBLOCK		6		/* number of direct blocks in Dentry */
-
-/* DONT TOUCH, this is the disk structure */
-struct	Dentry
-{
-	char	name[NAMELEN];
-	short	uid;
-	short	gid;
-	ushort	mode;
-/*
-		#define	DALLOC	0x8000
-		#define	DDIR	0x4000
-		#define	DAPND	0x2000
-		#define	DLOCK	0x1000
-		#define	DREAD	0x4
-		#define	DWRITE	0x2
-		#define	DEXEC	0x1
-*/
-	Qid9p1	qid;
-	long	size;
-	long	dblock[NDBLOCK];
-	long	iblock;
-	long	diblock;
-	long	atime;
-	long	mtime;
-};
-
-struct Kfsfile
-{
-	Dentry;
-	long off;
-};
-
-struct Kfs
-{
-	int	RBUFSIZE;
-	int	BUFSIZE;
-	int	DIRPERBUF;
-	int	INDPERBUF;
-	int	INDPERBUF2;
-};
-
-extern int kfsinit(Fs*);
-

+ 0 - 265
sys/src/9/w/pxeload/kfsboot.c

@@ -1,265 +0,0 @@
-/*
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
-
-#include	"u.h"
-#include	"lib.h"
-#include	"mem.h"
-#include	"dat.h"
-#include	"fns.h"
-#include	"fs.h"
-
-typedef struct Tag Tag;
-
-/*
- * tags on block
- */
-enum
-{
-	Tnone		= 0,
-	Tsuper,			/* the super block */
-	Tdir,			/* directory contents */
-	Tind1,			/* points to blocks */
-	Tind2,			/* points to Tind1 */
-	Tfile,			/* file contents */
-	Tfree,			/* in free list */
-	Tbuck,			/* cache fs bucket */
-	Tvirgo,			/* fake worm virgin bits */
-	Tcache,			/* cw cache things */
-	MAXTAG
-};
-
-#define	QPDIR	0x80000000L
-#define	QPNONE	0
-#define	QPROOT	1
-#define	QPSUPER	2
-
-/* DONT TOUCH, this is the disk structure */
-struct	Tag
-{
-	int16_t	pad;
-	int16_t	tag;
-	int32_t	path;
-};
-
-static int thisblock = -1;
-static Fs *thisfs;
-static uint8_t *block;
-
-/*
- * we end up reading 2x or 3x the number of blocks we need to read.
- * this is okay because we need to read so few.  if it wasn't okay, we could
- * have getblock return a pointer to a block, and keep a cache of the last
- * three read blocks.  that would get us down to the minimum.
- * but this is fine.
- */
-static int
-getblock(Fs *fs, uint32_t n)
-{
-	if(!block)
-		block = malloc(16384);
-
-	if(thisblock == n && thisfs == fs)
-		return 0;
-	thisblock = -1;
-	if(fs->diskseek(fs, (int64_t)n*fs->kfs.RBUFSIZE) < 0)
-		return -1;
-	if(fs->diskread(fs, block, fs->kfs.RBUFSIZE) != fs->kfs.RBUFSIZE)
-		return -1;
-	thisblock = n;
-	thisfs = fs;
-
-	return 1;
-}
-
-static int
-checktag(Fs *fs, uint8_t *block, int tag, int32_t qpath)
-{
-	Tag *t;
-
-	t = (Tag*)(block+fs->kfs.BUFSIZE);
-	if(t->tag != tag)
-		return -1;
-	if(qpath != QPNONE && (qpath&~QPDIR) != t->path)
-		return -1;
-	return 1;
-}
-
-static int
-getblocktag(Fs *fs, uint32_t n, int tag, int32_t qpath)
-{
-	if(getblock(fs, n) < 0 || checktag(fs, block, tag, qpath) < 0)
-		return -1;
-	return 1;
-}
-
-static int
-readinfo(Fs *fs)
-{
-	fs->kfs.RBUFSIZE = 512;
-	if(getblock(fs, 0) < 0)
-		return -1;
-
-	if(memcmp(block+256, "kfs wren device\n", 16) != 0)
-		return -1;
-
-	fs->kfs.RBUFSIZE = atoi((char*)block+256+16);
-	if(!fs->kfs.RBUFSIZE || (fs->kfs.RBUFSIZE&(fs->kfs.RBUFSIZE-1)))
-		return -1;
-
-	fs->kfs.BUFSIZE = fs->kfs.RBUFSIZE - sizeof(Tag);
-	fs->kfs.DIRPERBUF = fs->kfs.BUFSIZE / sizeof(Dentry);
-	fs->kfs.INDPERBUF = fs->kfs.BUFSIZE / sizeof(int32_t);
-	fs->kfs.INDPERBUF2 = fs->kfs.INDPERBUF * fs->kfs.INDPERBUF;
-
-	return 1;
-}
-
-static int
-readroot(Fs *fs, Dentry *d)
-{
-	Dentry *d2;
-
-	if(getblocktag(fs, 2, Tdir, QPROOT) < 0)
-		return -1;
-	d2 = (Dentry*)block;
-	if(strcmp(d2->name, "/") != 0)
-		return -1;
-	*d = *(Dentry*)block;
-	return 1;
-}
-
-static int32_t
-indfetch(Fs *fs, int32_t addr, int32_t off, int tag, int32_t path)
-{
-	if(getblocktag(fs, addr, tag, path) < 0)
-		return -1;
-	return ((int32_t*)block)[off];
-}
-
-static int32_t
-rel2abs(Fs *fs, Dentry *d, int32_t a)
-{
-	int32_t addr;
-
-	if(a < NDBLOCK)
-		return d->dblock[a];
-	a -= NDBLOCK;
-	if(a < fs->kfs.INDPERBUF){
-		if(d->iblock == 0)
-			return 0;
-		addr = indfetch(fs, d->iblock, a, Tind1, d->qid.path);
-		if(addr == 0)
-			print("rel2abs indfetch 0 %s %ld\n", d->name, a);
-		return addr;
-	}
-	a -= fs->kfs.INDPERBUF;
-	if(a < fs->kfs.INDPERBUF2){
-		if(d->diblock == 0)
-			return 0;
-		addr = indfetch(fs, d->diblock, a/fs->kfs.INDPERBUF, Tind2, d->qid.path);
-		if(addr == 0){
-			print("rel2abs indfetch 0 %s %ld\n", d->name, a/fs->kfs.INDPERBUF);
-			return 0;
-		}
-		addr = indfetch(fs, addr, a%fs->kfs.INDPERBUF, Tind1, d->qid.path);
-		return addr;
-	}
-	print("rel2abs trip ind %s %ld\n", d->name, a);
-	return -1;
-}
-
-static int
-readdentry(Fs *fs, Dentry *d, int n, Dentry *e)
-{
-	int32_t addr, m;
-
-	m = n/fs->kfs.DIRPERBUF;
-	if((addr = rel2abs(fs, d, m)) <= 0)
-		return addr;
-	if(getblocktag(fs, addr, Tdir, d->qid.path) < 0)
-		return -1;
-	*e = *(Dentry*)(block+(n%fs->kfs.DIRPERBUF)*sizeof(Dentry));
-	return 1;
-}
-
-static int
-getdatablock(Fs *fs, Dentry *d, int32_t a)
-{
-	int32_t addr;
-
-	if((addr = rel2abs(fs, d, a)) == 0)
-		return -1;
-	return getblocktag(fs, addr, Tfile, QPNONE);
-}
-
-static int
-walk(Fs *fs, Dentry *d, char *name, Dentry *e)
-{
-	int i, n;
-	Dentry x;
-
-	for(i=0;; i++){
-		if((n=readdentry(fs, d, i, &x)) <= 0)
-			return n;
-		if(strcmp(x.name, name) == 0){
-			*e = x;
-			return 1;
-		}
-	}
-}
-
-static int32_t
-kfsread(File *f, void *va, int32_t len)
-{
-	uint8_t *a;
-	int32_t tot, off, o, n;
-	Fs *fs;
-
-	a = va;
-	fs = f->fs;
-	off = f->kfs.off;
-	tot = 0;
-	while(tot < len){
-		if(getdatablock(fs, &f->kfs, off/fs->kfs.BUFSIZE) < 0)
-			return -1;
-		o = off%fs->kfs.BUFSIZE;
-		n = fs->kfs.BUFSIZE - o;
-		if(n > len-tot)
-			n = len-tot;
-		memmove(a+tot, block+o, n);
-		off += n;
-		tot += n;
-	}
-	f->kfs.off = off;
-	return tot;
-}
-
-static int
-kfswalk(File *f, char *name)
-{
-	int n;
-
-	n = walk(f->fs, &f->kfs, name, &f->kfs);
-	if(n < 0)
-		return -1;
-	f->kfs.off = 0;
-	return 1;
-}
-
-int
-kfsinit(Fs *fs)
-{
-	if(readinfo(fs) < 0 || readroot(fs, &fs->root.kfs) < 0)
-		return -1;
-
-	fs->root.fs = fs;
-	fs->read = kfsread;
-	fs->walk = kfswalk;
-	return 0;
-}

+ 0 - 249
sys/src/9/w/pxeload/l16r.s

@@ -1,249 +0,0 @@
-/*
- * Protected-mode bootstrap, to be jumped to by a Primary Bootstrap Sector.
- * Load with -H3 -R4 -T0xNNNNNNNN to get a binary image with no header.
- * Note that the processor is in 'real' mode on entry, so care must be taken
- * as the assembler assumes protected mode, hence the sometimes weird-looking
- * code to assure 16-bit instructions are issued.
- */
-#include "mem.h"
-#include "x16.h"
-
-#define CMPL(r0, r1)	BYTE $0x66; CMP(r0, r1)
-#define LLI(i, rX)	BYTE $0x66;		/* i -> rX */		\
-			BYTE $(0xB8+rX);				\
-			LONG $i;
-
-/*
- * Start:
- *	disable interrupts;
- *	set all segments;
- *	create temporary stack.
- */
-TEXT _start16r(SB), $0
-	CLI
-	CLD
-
-	MFSR(rCS, rAX)
-	MTSR(rAX, rDS)			/* set the data and stack segments */
-//NO	MTSR(rAX, rSS)
-//NO
-//NO	LWI(_start16r(SB), rSP)		/* set the stack */
-
-/*
- * Do any real-mode BIOS calls before going to protected mode.
- * Data will be stored at ROUND(end, BY2PG).
- */
-_biosstart:
-
-/*
- * Check for CGA mode.
- */
-_cgastart:
-	LWI(0x0F00, rAX)		/* get current video mode in AL */
-	BIOSCALL(0x10)
-	ANDI(0x007F, rAX)
-	SUBI(0x0003, rAX)		/* is it mode 3? */
-	JEQ	_cgaputs
-
-	LWI(0x0003, rAX)		/* turn on text mode 3 */
-	BIOSCALL(0x10)
-
-_cgaputs:				/* output a cheery wee message */
-	LWI(_hello(SB), rSI)
-	CLR(rBX)
-_cgaputsloop:
-	LODSB
-	ORB(rAL, rAL)
-	JEQ	_cgaend
-
-	LBI(0x0E,rAH)
-	BIOSCALL(0x10)
-	JMP	_cgaputsloop
-_cgaend:
-
-/*
- * Reset floppy disc system.
- * If successful, make sure the motor is off.
- */
-_floppystart:
-	CLR(rAX)
-	CLR(rDX)
-	BIOSCALL(0x13)
-	ORB(rAL, rAL)
-	JNE	_floppyend
-	OUTPORTB(0x3F2, 0x00)		/* turn off motor */
-_floppyend:
-
-	LLI(end+4095(SB), rAX)
-	OPSIZE; ANDL $~(BY2PG-1), AX
-	OPSIZE; SHRL $4, AX
-	SW(rAX, _ES(SB))
-	CLR(rDI)
-	SW(rDI, _DI(SB))
-
-	MTSR(rAX, rES)
-
-/*
- * Check for APM1.2 BIOS support.
- */
-_apmstart:
-	LWI(0x5304, rAX)		/* disconnect anyone else */
-	CLR(rBX)
-	BIOSCALL(0x15)
-
-	LWI(0x5303, rAX)		/* connect */
-	CLR(rBX)
-	CLC
-	BIOSCALL(0x15)
-
-	JCC	_apmpush
-	LW(_ES(SB), rAX)
-	MTSR(rAX, rES)
-	LW(_DI(SB), rDI)
-	JCS	_apmend
-
-_apmpush:
-	OPSIZE; PUSHR(rSI)		/* save returned APM data on stack */
-	OPSIZE; PUSHR(rBX)
-	PUSHR(rDI)
-	PUSHR(rDX)
-	PUSHR(rCX)
-	PUSHR(rAX)
-
-	LW(_ES(SB), rAX)
-	MTSR(rAX, rES)
-	LW(_DI(SB), rDI)
-
-	LWI(0x5041, rAX)		/* first 4 bytes are APM\0 */
-	STOSW
-	LWI(0x004D, rAX)
-	STOSW
-
-	LWI(8, rCX)			/* pop the saved APM data */
-_apmpop:
-	POPR(rAX)
-	STOSW
-	LOOP	_apmpop
-_apmend:
-
-/*
- * Try to retrieve the 0xE820 memory map.
- * This is weird because some BIOS do not seem to preserve
- * ES/DI on failure. Consequently they may not be valid
- * at _e820end:.
- */
-
-_e820start:
-	SW(rDI, _DI(SB))		/* save DI */
-	CLR(rAX)			/* write terminator */
-	STOSW
-	STOSW
-
-	CLR(rBX)
-	PUSHR(rBX)			/* keep loop count on stack */
-					/* BX is the continuation value */
-_e820loop:
-	POPR(rAX)
-	INC(rAX)
-	PUSHR(rAX)			/* doesn't affect FLAGS */
-	CMPI(32, rAX)
-	JGT	_e820pop
-
-	LLI(20, rCX)			/* buffer size */
-	LLI(0x534D4150, rDX)		/* signature - ASCII "SMAP" */
-	LLI(0x0000E820, rAX)		/* function code */
-
-	BIOSCALL(0x15)
-
-	JCS	_e820pop		/* some kind of error */
-	LLI(0x534D4150, rDX)
-	CMPL(rDX, rAX)			/* verify correct BIOS version */
-	JNE	_e820pop
-	LLI(20, rDX)
-	CMPL(rDX, rCX)			/* verify correct count */
-	JNE	_e820pop
-
-	SUBI(4, rDI)			/* overwrite terminator */
-	LWI(0x414D, rAX)		/* first 4 bytes are "MAP\0" */
-	STOSW
-	LWI(0x0050, rAX)
-	STOSW
-
-	ADDI(20, rDI)			/* bump to next entry */
-
-	SW(rDI, _DI(SB))		/* save DI */
-	CLR(rAX)			/* write terminator */
-	STOSW
-	STOSW
-
-	OR(rBX, rBX)			/* zero if last entry */
-	JNE	_e820loop
-
-_e820pop:
-	POPR(rAX)			/* loop count */
-	LW(_DI(SB), rDI)
-	CLR(rAX)
-	MTSR(rAX, rES)
-_e820end:
-
-_biosend:
-
-/*
- * Load a basic GDT to map 4GB, turn on the protected mode bit in CR0,
- * set all the segments to point to the new GDT then jump to the 32-bit code.
- */
-_real:
-	LGDT(_gdtptr16r(SB))		/* load a basic gdt */
-
-	MFCR(rCR0, rAX)
-	ORI(1, rAX)
-	MTCR(rAX, rCR0)			/* turn on protected mode */
-	DELAY				/* JMP .+2 */
-
-	LWI(SELECTOR(1, SELGDT, 0), rAX)/* set all segments */
-	MTSR(rAX, rDS)
-	MTSR(rAX, rES)
-	MTSR(rAX, rFS)
-	MTSR(rAX, rGS)
-	MTSR(rAX, rSS)
-
-	FARJUMP32(SELECTOR(2, SELGDT, 0), _start32p-KZERO(SB))
-
-/*
- * There's no way with 8[al] to make this into local data, hence
- * the TEXT definitions. Also, it should be in the same segment as
- * the LGDT instruction.
- * In real mode only 24-bits of the descriptor are loaded so the
- * -KZERO is superfluous for the usual mappings.
- * The segments are
- *	NULL
- *	DATA 32b 4GB PL0
- *	EXEC 32b 4GB PL0
- *	EXEC 16b 4GB PL0
- */
-TEXT _gdt16r(SB), $0
-	LONG $0x0000; LONG $0
-	LONG $0xFFFF; LONG $(SEGG|SEGB|(0xF<<16)|SEGP|SEGPL(0)|SEGDATA|SEGW)
-	LONG $0xFFFF; LONG $(SEGG|SEGD|(0xF<<16)|SEGP|SEGPL(0)|SEGEXEC|SEGR)
-	LONG $0xFFFF; LONG $(SEGG     |(0xF<<16)|SEGP|SEGPL(0)|SEGEXEC|SEGR)
-TEXT _gdtptr16r(SB), $0
-	WORD	$(4*8)
-	LONG	$_gdt16r-KZERO(SB)
-
-TEXT _hello(SB), $0
-	BYTE $'P'; BYTE $'r'; BYTE $'o'; BYTE $'t';
-	BYTE $'e'; BYTE $'c'; BYTE $'t'; BYTE $'e';
-	BYTE $'d'; BYTE $'-'; BYTE $'m'; BYTE $'o';
-	BYTE $'d'; BYTE $'e'; BYTE $' '; BYTE $'b';
-	BYTE $'o'; BYTE $'o'; BYTE $'t'; BYTE $'s';
-	BYTE $'t'; BYTE $'r'; BYTE $'a'; BYTE $'p';
-	BYTE $'.'; BYTE $'.'; BYTE $'.';
-	BYTE $'\r';
-	BYTE $'\n';
-	BYTE $'\z';
-
-TEXT _DI(SB), $0
-	BYTE $0; BYTE $0; BYTE $0; BYTE $0;
-
-TEXT _ES(SB), $0
-	BYTE $0; BYTE $0; BYTE $0; BYTE $0;

+ 0 - 172
sys/src/9/w/pxeload/l32p.s

@@ -1,172 +0,0 @@
-#include "mem.h"
-
-/*
- * Some machine instructions not handled by 8[al].
- */
-#define	DELAY		BYTE $0xEB; BYTE $0x00	/* JMP .+2 */
-#define FARJUMP(s, o)	BYTE $0xEA;		/* far jump to ptr32:16 */\
-			LONG $o; WORD $s
-
-/*
- * Macro for calculating offset within the page directory base.
- * Note that this is assembler-specific hence the '<<2'.
- */
-#define PDO(a)		(((((a))>>22) & 0x03FF)<<2)
-
-/*
- * May enter here either from the 16-bit real-mode startup or
- * from other 32-bit protected mode code. For the latter case must
- * make sure the GDT is set as it would be by the 16-bit code:
- *	disable interrupts;
- *	load the GDT with the table in _gdt32p;
- *	load all the data segments
- *	load the code segment via a far jump.
- */
-TEXT _start32p(SB), $0
-	BYTE $0xEB; BYTE $0x58;			/* jmp .+ 0x58  (_start32p58) */
-	BYTE $0x90; BYTE $0x90			/* nop */
-
-/*
- * Must be 4-byte aligned.
- */
-TEXT _multibootheader(SB), $0
-	LONG	$0x1BADB002			/* magic */
-	LONG	$0x00010003			/* flags */
-	LONG	$-(0x1BADB002 + 0x00010003)	/* checksum */
-	LONG	$_multibootheader-KZERO(SB)	/* header_addr */
-	LONG	$_start32p-KZERO(SB)		/* load_addr */
-	LONG	$edata-KZERO(SB)		/* load_end_addr */
-	LONG	$end-KZERO(SB)			/* bss_end_addr */
-	LONG	$_start32p-KZERO(SB)		/* entry_addr */
-	LONG	$0				/* mode_type */
-	LONG	$0				/* width */
-	LONG	$0				/* height */
-	LONG	$0				/* depth */
-
-	LONG	$0				/* +48: saved AX - magic */
-	LONG	$0				/* +52: saved BX - info* */
-
-TEXT _gdt32p(SB), $0
-	LONG	$0x0000; LONG $0
-	LONG	$0xFFFF; LONG $(SEGG|SEGB|(0xF<<16)|SEGP|SEGPL(0)|SEGDATA|SEGW)
-	LONG	$0xFFFF; LONG $(SEGG|SEGD|(0xF<<16)|SEGP|SEGPL(0)|SEGEXEC|SEGR)
-
-TEXT _gdtptr32p(SB), $0
-	WORD	$(3*8)
-	LONG	$_gdt32p-KZERO(SB)
-
-_start32p58:
-	CLI
-
-	MOVL	AX, _multibootheader+(48-KZERO)(SB)
-	MOVL	BX, _multibootheader+(52-KZERO)(SB)
-
-	MOVL	$_gdtptr32p-KZERO(SB), AX
-	MOVL	(AX), GDTR
-
-	MOVL	$SELECTOR(1, SELGDT, 0), AX
-	MOVW	AX, DS
-	MOVW	AX, ES
-	MOVW	AX, FS
-	MOVW	AX, GS
-	MOVW	AX, SS
-
-	FARJUMP(SELECTOR(2, SELGDT, 0), _start32pg-KZERO(SB))
-
-/*
- * Make the basic page tables for processor 0. Five pages are needed for
- * the basic set:
- * a page directory, a page table for mapping the first 4MB of physical
- * memory, a separate physical and virtual page for the Mach structure
- * and a page to be used later for the GDT.
- * The remaining PTEs will be allocated later when memory is sized.
- * Could clear BSS here too when clearing the space for the tables,
- * but that would violate the separation of church and state.
- * The first aligned page after end[] is where the real-mode startup
- * puts any BIOS parameters (APM, MAP).
- */
-TEXT _start32pg(SB), $0
-	MOVL	$end-KZERO(SB), DX	/* clear pages for the tables etc. */
-	ADDL	$(2*BY2PG-1), DX	/* start must be page aligned */
-	ANDL	$~(BY2PG-1), DX
-
-	MOVL	DX, DI
-	XORL	AX, AX
-	MOVL	$(5*BY2PG), CX
-	SHRL	$2, CX
-
-	CLD
-	REP;	STOSL
-
-	MOVL	DX, AX			/* bootstrap processor PDB */
-	MOVL	DX, DI			/* save it for later */
-	ADDL	$BY2PG, DX		/* -> PA of first page of page table */
-	ADDL	$PDO(KZERO), AX		/* page directory offset for KZERO */
-	MOVL	DX, (AX)		/* PTE's for KZERO */
-	MOVL	$(PTEWRITE|PTEVALID), BX/* page permissions */
-	ORL	BX, (AX)
-
-	MOVL	DX, AX			/* PA of first page of page table */
-	MOVL	$1024, CX		/* 1024 pages in 4MB */
-_setpte:
-	MOVL	BX, (AX)
-	ADDL	$(1<<PGSHIFT), BX
-	ADDL	$4, AX
-	LOOP	_setpte
-
-	MOVL	DX, AX			/* PA of first page of page table */
-	ADDL	$BY2PG, DX		/* -> PA of Mach structure */
-
-	MOVL	DX, BX
-	ADDL	$(KZERO+BY2PG), BX	/* VA of Mach structure */
-	SHRL	$10, BX			/* create offset into PTEs */
-	ANDL	$(0x3FF<<2), BX
-
-	ADDL	BX, AX			/* PTE offset for Mach structure */
-	MOVL	DX, (AX)		/* create PTE for Mach */
-	MOVL	$(PTEWRITE|PTEVALID), BX/* page permissions */
-	ORL	BX, (AX)
-
-/*
- * Now ready to use the new map. Initialise CR0 (assume the BIOS gets
- * it mostly correct for this processor type w.r.t. caches and FPU).
- * It is necessary on some processors to follow mode switching
- * with a JMP instruction to clear the prefetch queues.
- * The instruction to switch modes and the following jump instruction
- * should be identity-mapped; to this end double map KZERO at
- * virtual 0 and undo the mapping once virtual nirvana has been attained.
- * If paging is already on, don't load CR3 before setting CR0, in which
- * case most of this is a NOP and the 2nd load of CR3 actually does
- * the business.
- */
-	MOVL	DI, CX			/* load address of PDB */
-	MOVL	PDO(KZERO)(CX), DX	/* double-map KZERO at 0 */
-	MOVL	DX, PDO(0)(CX)
-
-	MOVL	CR0, DX
-	MOVL	DX, AX
-	ANDL	$0x80000000, AX		/* check paging not already on */
-	JNE	_nocr3load
-	MOVL	CX, CR3
-
-_nocr3load:
-	ORL	$0x80010000, DX		/* PG|WP */
-	ANDL	$~0x6000000A, DX	/* ~(CD|NW|TS|MP) */
-
-	MOVL	$_startpg(SB), AX
-	TESTL	$KZERO, AX		/* want to run protected or virtual? */
-	JNE	_dorkness
-
-	MOVL	$_start32v(SB), AX
-	JMP*	AX			/* into the dorkness */
-
-_dorkness:
-	MOVL	DX, CR0			/* turn on paging */
-	JMP*	AX			/* headfirst into the new world */
-
-TEXT _startpg(SB), $0
-//	MOVL	$0, PDO(0)(CX)		/* undo double-map of KZERO at 0 */
-//	MOVL	CX, CR3			/* load and flush the mmu */
-
-	MOVL	$_start32v(SB), AX
-	JMP*	AX			/* into the dorkness */

+ 0 - 557
sys/src/9/w/pxeload/l32v.s

@@ -1,557 +0,0 @@
-#include "x16.h"
-#include "mem.h"
-
-#define WRMSR		BYTE $0x0F; BYTE $0x30	/* WRMSR, argument in AX/DX (lo/hi) */
-#define RDTSC 		BYTE $0x0F; BYTE $0x31	/* RDTSC, result in AX/DX (lo/hi) */
-#define RDMSR		BYTE $0x0F; BYTE $0x32	/* RDMSR, result in AX/DX (lo/hi) */
-
-TEXT _start32v(SB),$0
-	CLI
-
-	MOVL	$edata(SB), DI
-	XORL	AX, AX
-	MOVL	$end(SB), CX
-	SUBL	DI, CX			/* end-edata bytes */
-	SHRL	$2, CX			/* end-edata doublewords */
-
-	CLD
-	REP; STOSL			/* clear BSS */
-
-	MOVL	CR3, AX
-	ADDL	$KZERO, AX		/* VA of PDB */
-	MOVL	AX, mach0pdb(SB)
-	ADDL	$(3*BY2PG), AX
-	MOVL	AX, mach0m(SB)
-	MOVL	AX, m(SB)		/* initialise global Mach pointer */
-	MOVL	$0, 0(AX)		/* initialise machp()->machno */
-	ADDL	$MACHSIZE, AX
-	MOVL	AX, SP			/* initialise stack */
-	MOVL	AX, mach0gdt(SB)
-	ADDL	$BY2PG, AX
-	MOVL	AX, memstart(SB)
-
-	MOVL	$0x240000, AX		/* try to set Id|Ac in EFLAGS */
-	PUSHL	AX
-	POPFL
-
-	PUSHFL				/* retrieve EFLAGS -> BX */
-	POPL	BX
-
-	MOVL	$0, AX			/* clear Id|Ac, EFLAGS initialised */
-	PUSHL	AX
-	POPFL
-
-	PUSHFL				/* retrieve EFLAGS -> AX */
-
-	XORL	BX, (SP)		/* togglable bits */
-	CALL	main(SB)
-
-/*
- * Park a processor. Should never fall through a return from main to here,
- * should only be called by application processors when shutting down.
- */
-TEXT idle(SB), $0
-_idle:
-	STI
-	HLT
-	JMP	_idle
-
-TEXT hlt(SB), $0
-	STI
-	HLT
-	RET
-
-/*
- */
-TEXT _warp9o(SB), $0
-	MOVL	entry+0(FP), CX
-	MOVL	$multibootheader-KZERO(SB), BX	/* multiboot data pointer */
-	MOVL	$0x2badb002, AX			/* multiboot magic */
-
-	CLI
-	JMP*	CX
-
-	JMP	_idle
-
-/*
- * Macro for calculating offset within the page directory base.
- * Note that this is assembler-specific hence the '<<2'.
- */
-#define PDO(a)		(((((a))>>22) & 0x03FF)<<2)
-
-/*
- */
-TEXT _warp9(SB), $0
-	CLI
-	MOVL	entry+0(FP), BP
-
-	MOVL	CR3, CX				/* load address of PDB */
-	ADDL	$KZERO, CX
-	MOVL	PDO(KZERO)(CX), DX		/* double-map KZERO at 0 */
-	MOVL	DX, PDO(0)(CX)
-
-	MOVL	CR3, CX
-	MOVL	CX, CR3				/* load and flush the mmu */
-
-	MOVL	$_start32id<>-KZERO(SB), AX
-	JMP*	AX				/* jump to identity-map */
-
-TEXT _start32id<>(SB), $0
-	MOVL	CR0, DX				/* turn off paging */
-	ANDL	$~0x80000000, DX		/* ~(PG) */
-
-	MOVL	$_stop32pg<>-KZERO(SB), AX
-	MOVL	DX, CR0
-	JMP*	AX				/* forward into the past */
-
-TEXT _stop32pg<>(SB), $0
-	MOVL	$multibootheader-KZERO(SB), BX	/* multiboot data pointer */
-	MOVL	$0x2badb002, AX			/* multiboot magic */
-
-	JMP*	BP
-
-	JMP	_idle
-
-/*
- *  input a byte
- */
-TEXT	inb(SB),$0
-
-	MOVL	p+0(FP),DX
-	XORL	AX,AX
-	INB
-	RET
-
-/*
- * input a short from a port
- */
-TEXT	ins(SB), $0
-
-	MOVL	p+0(FP), DX
-	XORL	AX, AX
-	OPSIZE; INL
-	RET
-
-/*
- * input a long from a port
- */
-TEXT	inl(SB), $0
-
-	MOVL	p+0(FP), DX
-	XORL	AX, AX
-	INL
-	RET
-
-/*
- *  output a byte
- */
-TEXT	outb(SB),$0
-
-	MOVL	p+0(FP),DX
-	MOVL	b+4(FP),AX
-	OUTB
-	RET
-
-/*
- * output a short to a port
- */
-TEXT	outs(SB), $0
-	MOVL	p+0(FP), DX
-	MOVL	s+4(FP), AX
-	OPSIZE; OUTL
-	RET
-
-/*
- * output a long to a port
- */
-TEXT	outl(SB), $0
-	MOVL	p+0(FP), DX
-	MOVL	s+4(FP), AX
-	OUTL
-	RET
-
-/*
- *  input a string of bytes from a port
- */
-TEXT	insb(SB),$0
-
-	MOVL	p+0(FP),DX
-	MOVL	a+4(FP),DI
-	MOVL	c+8(FP),CX
-	CLD; REP; INSB
-	RET
-
-/*
- *  input a string of shorts from a port
- */
-TEXT	inss(SB),$0
-	MOVL	p+0(FP),DX
-	MOVL	a+4(FP),DI
-	MOVL	c+8(FP),CX
-	CLD
-	REP; OPSIZE; INSL
-	RET
-
-/*
- *  output a string of bytes to a port
- */
-TEXT	outsb(SB),$0
-
-	MOVL	p+0(FP),DX
-	MOVL	a+4(FP),SI
-	MOVL	c+8(FP),CX
-	CLD; REP; OUTSB
-	RET
-
-/*
- *  output a string of shorts to a port
- */
-TEXT	outss(SB),$0
-	MOVL	p+0(FP),DX
-	MOVL	a+4(FP),SI
-	MOVL	c+8(FP),CX
-	CLD
-	REP; OPSIZE; OUTSL
-	RET
-
-/*
- *  input a string of longs from a port
- */
-TEXT	insl(SB),$0
-
-	MOVL	p+0(FP),DX
-	MOVL	a+4(FP),DI
-	MOVL	c+8(FP),CX
-	CLD; REP; INSL
-	RET
-
-/*
- *  output a string of longs to a port
- */
-TEXT	outsl(SB),$0
-
-	MOVL	p+0(FP),DX
-	MOVL	a+4(FP),SI
-	MOVL	c+8(FP),CX
-	CLD; REP; OUTSL
-	RET
-
-/*
- *  routines to load/read various system registers
- */
-TEXT lgdt(SB), $0			/* GDTR - global descriptor table */
-	MOVL	gdtptr+0(FP), AX
-	MOVL	(AX), GDTR
-	RET
-
-TEXT lidt(SB), $0			/* IDTR - interrupt descriptor table */
-	MOVL	idtptr+0(FP), AX
-	MOVL	(AX), IDTR
-	RET
-
-TEXT	putcr3(SB),$0		/* top level page table pointer */
-	MOVL	t+0(FP),AX
-	MOVL	AX,CR3
-	RET
-
-TEXT	getcr0(SB),$0		/* coprocessor bits */
-	MOVL	CR0,AX
-	RET
-
-TEXT	getcr2(SB),$0		/* fault address */
-	MOVL	CR2,AX
-	RET
-
-TEXT	getcr3(SB),$0		/* page directory base */
-	MOVL	CR3,AX
-	RET
-
-TEXT	getcr4(SB), $0		/* CR4 - extensions */
-	MOVL	CR4, AX
-	RET
-
-TEXT _cycles(SB), $0				/* time stamp counter */
-	RDTSC
-	MOVL	vlong+0(FP), CX			/* &vlong */
-	MOVL	AX, 0(CX)			/* lo */
-	MOVL	DX, 4(CX)			/* hi */
-	RET
-
-TEXT rdmsr(SB), $0				/* model-specific register */
-	MOVL	index+0(FP), CX
-	RDMSR
-	MOVL	vlong+4(FP), CX			/* &vlong */
-	MOVL	AX, 0(CX)			/* lo */
-	MOVL	DX, 4(CX)			/* hi */
-	RET
-
-TEXT wrmsr(SB), $0
-	MOVL	index+0(FP), CX
-	MOVL	lo+4(FP), AX
-	MOVL	hi+8(FP), DX
-	WRMSR
-	RET
-
-TEXT mb386(SB), $0
-	POPL	AX				/* return PC */
-	PUSHFL
-	PUSHL	CS
-	PUSHL	AX
-	IRETL
-
-/*
- *  special traps
- */
-TEXT	intr0(SB),$0
-	PUSHL	$0
-	PUSHL	$0
-	JMP	intrcommon
-TEXT	intr1(SB),$0
-	PUSHL	$0
-	PUSHL	$1
-	JMP	intrcommon
-TEXT	intr2(SB),$0
-	PUSHL	$0
-	PUSHL	$2
-	JMP	intrcommon
-TEXT	intr3(SB),$0
-	PUSHL	$0
-	PUSHL	$3
-	JMP	intrcommon
-TEXT	intr4(SB),$0
-	PUSHL	$0
-	PUSHL	$4
-	JMP	intrcommon
-TEXT	intr5(SB),$0
-	PUSHL	$0
-	PUSHL	$5
-	JMP	intrcommon
-TEXT	intr6(SB),$0
-	PUSHL	$0
-	PUSHL	$6
-	JMP	intrcommon
-TEXT	intr7(SB),$0
-	PUSHL	$0
-	PUSHL	$7
-	JMP	intrcommon
-TEXT	intr8(SB),$0
-	PUSHL	$8
-	JMP	intrcommon
-TEXT	intr9(SB),$0
-	PUSHL	$0
-	PUSHL	$9
-	JMP	intrcommon
-TEXT	intr10(SB),$0
-	PUSHL	$10
-	JMP	intrcommon
-TEXT	intr11(SB),$0
-	PUSHL	$11
-	JMP	intrcommon
-TEXT	intr12(SB),$0
-	PUSHL	$12
-	JMP	intrcommon
-TEXT	intr13(SB),$0
-	PUSHL	$13
-	JMP	intrcommon
-TEXT	intr14(SB),$0
-	PUSHL	$14
-	JMP	intrcommon
-TEXT	intr15(SB),$0
-	PUSHL	$0
-	PUSHL	$15
-	JMP	intrcommon
-TEXT	intr16(SB),$0
-	PUSHL	$0
-	PUSHL	$16
-	JMP	intrcommon
-TEXT	intr24(SB),$0
-	PUSHL	$0
-	PUSHL	$24
-	JMP	intrcommon
-TEXT	intr25(SB),$0
-	PUSHL	$0
-	PUSHL	$25
-	JMP	intrcommon
-TEXT	intr26(SB),$0
-	PUSHL	$0
-	PUSHL	$26
-	JMP	intrcommon
-TEXT	intr27(SB),$0
-	PUSHL	$0
-	PUSHL	$27
-	JMP	intrcommon
-TEXT	intr28(SB),$0
-	PUSHL	$0
-	PUSHL	$28
-	JMP	intrcommon
-TEXT	intr29(SB),$0
-	PUSHL	$0
-	PUSHL	$29
-	JMP	intrcommon
-TEXT	intr30(SB),$0
-	PUSHL	$0
-	PUSHL	$30
-	JMP	intrcommon
-TEXT	intr31(SB),$0
-	PUSHL	$0
-	PUSHL	$31
-	JMP	intrcommon
-TEXT	intr32(SB),$0
-	PUSHL	$0
-	PUSHL	$32
-	JMP	intrcommon
-TEXT	intr33(SB),$0
-	PUSHL	$0
-	PUSHL	$33
-	JMP	intrcommon
-TEXT	intr34(SB),$0
-	PUSHL	$0
-	PUSHL	$34
-	JMP	intrcommon
-TEXT	intr35(SB),$0
-	PUSHL	$0
-	PUSHL	$35
-	JMP	intrcommon
-TEXT	intr36(SB),$0
-	PUSHL	$0
-	PUSHL	$36
-	JMP	intrcommon
-TEXT	intr37(SB),$0
-	PUSHL	$0
-	PUSHL	$37
-	JMP	intrcommon
-TEXT	intr38(SB),$0
-	PUSHL	$0
-	PUSHL	$38
-	JMP	intrcommon
-TEXT	intr39(SB),$0
-	PUSHL	$0
-	PUSHL	$39
-	JMP	intrcommon
-TEXT	intr64(SB),$0
-	PUSHL	$0
-	PUSHL	$64
-	JMP	intrcommon
-TEXT	intrbad(SB),$0
-	PUSHL	$0
-	PUSHL	$0x1ff
-	JMP	intrcommon
-
-intrcommon:
-	PUSHL	DS
-	PUSHL	ES
-	PUSHL	FS
-	PUSHL	GS
-	PUSHAL
-	MOVL	$(KDSEL),AX
-	MOVW	AX,DS
-	MOVW	AX,ES
-	LEAL	0(SP),AX
-	PUSHL	AX
-	CALL	trap(SB)
-	POPL	AX
-	POPAL
-	POPL	GS
-	POPL	FS
-	POPL	ES
-	POPL	DS
-	ADDL	$8,SP	/* error code and trap type */
-	IRETL
-
-
-/*
- *  interrupt level is interrupts on or off
- */
-TEXT	spllo(SB),$0
-	PUSHFL
-	POPL	AX
-	STI
-	RET
-
-TEXT	splhi(SB),$0
-	PUSHFL
-	POPL	AX
-	CLI
-	RET
-
-TEXT	splx(SB),$0
-	MOVL	s+0(FP),AX
-	PUSHL	AX
-	POPFL
-	RET
-
-/*
- * Try to determine the CPU type which requires fiddling with EFLAGS.
- * If the Id bit can be toggled then the CPUID instruciton can be used
- * to determine CPU identity and features. First have to check if it's
- * a 386 (Ac bit can't be set). If it's not a 386 and the Id bit can't be
- * toggled then it's an older 486 of some kind.
- *
- *	cpuid(id[], &ax, &dx);
- */
-#define CPUID		BYTE $0x0F; BYTE $0xA2	/* CPUID, argument in AX */
-TEXT cpuid(SB), $0
-	MOVL	$0x240000, AX
-	PUSHL	AX
-	POPFL					/* set Id|Ac */
-
-	PUSHFL
-	POPL	BX				/* retrieve value */
-
-	MOVL	$0, AX
-	PUSHL	AX
-	POPFL					/* clear Id|Ac, EFLAGS initialised */
-
-	PUSHFL
-	POPL	AX				/* retrieve value */
-	XORL	BX, AX
-	TESTL	$0x040000, AX			/* Ac */
-	JZ	_cpu386				/* can't set this bit on 386 */
-	TESTL	$0x200000, AX			/* Id */
-	JZ	_cpu486				/* can't toggle this bit on some 486 */
-
-	MOVL	$0, AX
-	CPUID
-	MOVL	id+0(FP), BP
-	MOVL	BX, 0(BP)			/* "Genu" "Auth" "Cyri" */
-	MOVL	DX, 4(BP)			/* "ineI" "enti" "xIns" */
-	MOVL	CX, 8(BP)			/* "ntel" "cAMD" "tead" */
-
-	MOVL	$1, AX
-	CPUID
-	JMP	_cpuid
-
-_cpu486:
-	MOVL	$0x400, AX
-	MOVL	$0, DX
-	JMP	_cpuid
-
-_cpu386:
-	MOVL	$0x300, AX
-	MOVL	$0, DX
-
-_cpuid:
-	MOVL	ax+4(FP), BP
-	MOVL	AX, 0(BP)
-	MOVL	dx+8(FP), BP
-	MOVL	DX, 0(BP)
-	RET
-
-
-/*
- *  basic timing loop to determine CPU frequency
- */
-TEXT	aamloop(SB),$0
-
-	MOVL	c+0(FP),CX
-aaml1:
-	AAM
-	LOOP	aaml1
-	RET
-
-GLOBL pxe(SB), $4
-#ifdef PXE
-DATA	pxe+0(SB)/4, $1
-#else
-DATA	pxe+0(SB)/4, $0
-#endif /* PXE */

+ 0 - 85
sys/src/9/w/pxeload/l64p.s

@@ -1,85 +0,0 @@
-#include "mem.h"
-
-/*
- * Some machine instructions not handled by 8[al].
- */
-#define WRMSR		BYTE $0x0F; BYTE $0x30	/* WRMSR, lo argument in AX */
-						/*	  hi argument in DX */
-#define RDMSR		BYTE $0x0F; BYTE $0x32	/* RDMSR, lo result in AX */
-						/*	  hi result in DX */
-#define FARJUMP(s, o)	BYTE $0xEA;		/* far jump to ptr32:16 */\
-			LONG $o; WORD $s
-
-/*
- * Macro for calculating offset within the page directory base.
- * Note that this is assembler-specific hence the '<<2'.
- */
-#define PDO(a)		(((((a))>>22) & 0x03FF)<<2)
-
-TEXT _warp64(SB), $0
-	CLI
-	MOVL	cr3+0(FP), BP			/* pml4 */
-
-	MOVL	CR3, CX				/* load address of PDB */
-	ADDL	$KZERO, CX
-	MOVL	PDO(KZERO)(CX), DX		/* double-map KZERO at 0 */
-	MOVL	DX, PDO(0)(CX)
-
-	MOVL	CR3, CX
-	MOVL	CX, CR3				/* load and flush the mmu */
-
-	MOVL	$_start32id<>-KZERO(SB), AX
-	JMP*	AX				/* jump to identity-map */
-
-TEXT _start32id<>(SB), $0
-	MOVL	CR0, DX				/* turn off paging */
-	ANDL	$~0x80000000, DX		/* ~(PG) */
-
-	MOVL	$_stop32pg<>-KZERO(SB), AX
-	MOVL	DX, CR0
-	JMP*	AX				/* forward into the past */
-
-TEXT _stop32pg<>(SB), $0
-MOVL $multibootheader-KZERO(SB), BX
-MOVL $0x2badb002, AX
-MOVL $0x00110000, CX
-JMP* CX
-	MOVL	CR4, AX
-	ORL	$0x00000020, AX			/* Pae */
-	MOVL	AX, CR4
-
-	MOVL	BP, CR3				/* pml4 */
-
-	MOVL	$0xC0000080, CX			/* Extended Feature Enable */
-	RDMSR
-	ORL	$0x00000100, AX			/* Long Mode Enable */
-	MOVL	$0xC0000080, CX
-	WRMSR
-
-	MOVL	CR0, DX				/* enable paging */
-	ORL	$0x80010000, DX
-	MOVL	$_start32cm<>-KZERO(SB), AX
-	MOVL	DX, CR0
-	JMP*	AX
-
-TEXT _start32cm<>(SB), $0			/* compatibility mode */
-	MOVL	$_gdtptr64<>-KZERO(SB), AX	/* load a long-mode GDT */
-	MOVL	(AX), GDTR
-	MOVL	$_start64lm<>-KZERO(SB), AX
-	JMP*	AX
-
-TEXT _start64lm<>(SB), $0			/* finally - long mode */
-	MOVL	$multibootheader-KZERO(SB), BX	/* multiboot data pointer */
-	MOVL	$0x2badb002, AX			/* multiboot magic */
-	FARJUMP((1<<3), 0x00110000)		/* selector 1, in  GDT, RPL 0 */
-_idle:
-	JMP	_idle
-
-TEXT _gdt64<>(SB), $0
-	LONG	$0x00000000; LONG $0x00000000	/* NULL descriptor */
-	LONG	$0x00000000; LONG $0x00209800	/* CS */
-	LONG	$0x00000000; LONG $0x00008000	/* DS */
-
-TEXT _gdtptr64<>(SB), $0
-	WORD	$(3*8-1)
-	LONG	$_gdt64<>-KZERO(SB)

+ 0 - 114
sys/src/9/w/pxeload/lib.h

@@ -1,114 +0,0 @@
-/* 
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
-
-/*
- * functions (possibly) linked in, complete, from libc.
- */
-
-/*
- * mem routines
- */
-extern	void*	memccpy(void*, void*, int, uint32_t);
-extern	void*	memset(void*, int, uint32_t);
-extern	int	memcmp(void*, void*, uint32_t);
-extern	void*	memmove(void*, void*, uint32_t);
-extern	void*	memchr(void*, int, uint32_t);
-
-/*
- * string routines
- */
-extern	char*	strcat(char*, char*);
-extern	char*	strchr(char*, int);
-extern	int	strcmp(char*, char*);
-extern	char*	strcpy(char*, char*);
-extern  char*	strecpy(char*, char*, char*);
-extern	char*	strncat(char*, char*, long);
-extern	char*	strncpy(char*, char*, long);
-extern	int	strncmp(char*, char*, long);
-extern	long	strlen(char*);
-extern	char*	strrchr(char*, char);
-extern	char*	strstr(char*, char*);
-
-
-/*
- * print routines
- */
-typedef struct Fmt	Fmt;
-typedef int (*Fmts)(Fmt*);
-struct Fmt{
-	uchar	runes;			/* output buffer is runes or chars? */
-	void	*start;			/* of buffer */
-	void	*to;			/* current place in the buffer */
-	void	*stop;			/* end of the buffer; overwritten if flush fails */
-	int	(*flush)(Fmt *);	/* called when to == stop */
-	void	*farg;			/* to make flush a closure */
-	int	nfmt;			/* num chars formatted so far */
-	va_list	args;			/* args passed to dofmt */
-	int	r;			/* % format Rune */
-	int	width;
-	int	prec;
-	uint32_t	flags;
-};
-extern	int	print(char*, ...);
-extern	char*	vseprint(char*, char*, char*, va_list);
-extern	int	sprint(char*, char*, ...);
-extern 	int	snprint(char*, int, char*, ...);
-extern	int	fmtinstall(int, int (*)(Fmt*));
-extern	int	fmtstrcpy(Fmt*, char*);
-
-#pragma	varargck	argpos	fmtprint	2
-#pragma	varargck	argpos	print		1
-#pragma	varargck	argpos	seprint		3
-#pragma	varargck	argpos	snprint		3
-#pragma	varargck	argpos	sprint		2
-#pragma varargck	type	"H" void*
-
-#pragma	varargck	type	"lld"	vlong
-#pragma	varargck	type	"llx"	vlong
-#pragma	varargck	type	"lld"	uvlong
-#pragma	varargck	type	"llx"	uvlong
-#pragma	varargck	type	"ld"	long
-#pragma	varargck	type	"lx"	long
-#pragma	varargck	type	"ld"	ulong
-#pragma	varargck	type	"lx"	ulong
-#pragma	varargck	type	"d"	int
-#pragma	varargck	type	"x"	int
-#pragma	varargck	type	"c"	int
-#pragma	varargck	type	"C"	int
-#pragma	varargck	type	"d"	uint
-#pragma	varargck	type	"x"	uint
-#pragma	varargck	type	"c"	uint
-#pragma	varargck	type	"C"	uint
-#pragma	varargck	type	"f"	double
-#pragma	varargck	type	"e"	double
-#pragma	varargck	type	"g"	double
-#pragma	varargck	type	"s"	char*
-#pragma	varargck	type	"q"	char*
-#pragma	varargck	type	"S"	Rune*
-#pragma	varargck	type	"Q"	Rune*
-#pragma	varargck	type	"r"	void
-#pragma	varargck	type	"%"	void
-#pragma	varargck	type	"|"	int
-#pragma	varargck	type	"p"	uintptr
-#pragma	varargck	type	"p"	void*
-#pragma varargck	type	"lux"	void*
-#pragma	varargck	type	"E"	uchar*
-
-#define PRINTSIZE	256
-
-/*
- * one-of-a-kind
- */
-extern	int	atoi(char*);
-extern	uint32_t	getcallerpc(void*);
-extern	long	strtol(char*, char**, int);
-extern	uint32_t	strtoul(char*, char**, int);
-extern	char	end[];
-
-#define	NAMELEN	28

+ 0 - 654
sys/src/9/w/pxeload/load.c

@@ -1,654 +0,0 @@
-/*
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
-
-#include "u.h"
-#include "lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-
-#include "fs.h"
-
-Mach* m;
-
-uint32_t* mach0pdb;
-Mach* mach0m;
-Segdesc* mach0gdt;
-uint32_t memstart;
-uint32_t memend;
-
-int vflag = 0;
-int debug = 0;
-
-static char *diskparts[] = { "dos", "9fat", "fs", "data", "cdboot", 0 };
-static char *etherparts[] = { "*", 0 };
-
-static char *diskinis[] = {
-	"plan9/plan9.ini",
-	"plan9.ini",
-	0
-};
-static char *etherinis[] = {
-	"/cfg/pxe/%E",
-	0
-};
-
-#define NODISCS
-
-Type types[] = {
-	{	Tfloppy,
-		Fini|Ffs,
-		floppyinit, floppyinitdev,
-		floppygetfspart, 0, floppyboot,
-		floppyprintdevs,
-		diskparts,
-		diskinis,
-	},
-#ifndef NODISCS
-	{	Tcd,
-		Fini|Ffs,
-		cdinit, sdinitdev,
-		sdgetfspart, sdaddconf, sdboot,
-		sdprintdevs,
-		diskparts,
-		diskinis,
-	},
-#endif /* NODISCS */
-	{	Tether,
-		Fini|Fbootp,
-		etherinit, etherinitdev,
-		pxegetfspart, 0, bootpboot,
-		etherprintdevs,
-		etherparts,
-		etherinis,
-	},
-#ifndef NODISCS
-	{	Tsd,
-		Fini|Ffs,
-		sdinit, sdinitdev,
-		sdgetfspart, sdaddconf, sdboot,
-		sdprintdevs,
-		diskparts,
-		diskinis,
-	},
-#endif /* NODISCS */
-	{	Tnil,
-		0,
-		nil, nil, nil, nil, nil, nil,
-		nil,
-		nil,
-		0,
-		nil,
-	},
-};
-
-#ifndef NODISCS
-
-#include "sd.h"
-
-extern SDifc sdataifc;
-
-#ifdef NOSCSI
-
-SDifc* sdifc[] = {
-	&sdataifc,
-	nil,
-};
-
-#else
-
-extern SDifc sdmylexifc;
-extern SDifc sd53c8xxifc;
-SDifc* sdifc[] = {
-	&sdataifc,
-	&sdmylexifc,
-	&sd53c8xxifc,
-	nil,
-};
-
-#endif NOSCSI
-#endif /* NODISCS */
-
-typedef struct Mode Mode;
-
-enum {
-	Maxdev		= 7,
-	Dany		= -1,
-	Nmedia		= 16,
-	Nini		= 10,
-};
-
-enum {					/* mode */
-	Mauto		= 0x00,
-	Mlocal		= 0x01,
-	Manual		= 0x02,
-	NMode		= 0x03,
-};
-
-typedef struct Medium Medium;
-struct Medium {
-	Type*	type;
-	int	flag;
-	int	dev;
-	char name[NAMELEN];
-
-	Fs *inifs;
-	char *part;
-	char *ini;
-
-	Medium*	next;
-};
-
-typedef struct Mode {
-	char*	name;
-	int	mode;
-} Mode;
-
-static Medium media[Nmedia];
-static Medium *curmedium = media;
-
-static Mode modes[NMode+1] = {
-	[Mauto]		{ "auto",   Mauto,  },
-	[Mlocal]	{ "local",  Mlocal, },
-	[Manual]	{ "manual", Manual, },
-};
-
-char **ini;
-
-int scsi0port;
-char *defaultpartition;
-int iniread;
-
-static Medium*
-parse(char *line, char **file)
-{
-	char *p;
-	Type *tp;
-	Medium *mp;
-
-	if(p = strchr(line, '!')) {
-		*p++ = 0;
-		*file = p;
-	} else
-		*file = "";
-
-	for(tp = types; tp->type != Tnil; tp++)
-		for(mp = tp->media; mp; mp = mp->next)
-			if(strcmp(mp->name, line) == 0)
-				return mp;
-	if(p)
-		*--p = '!';
-	return nil;
-}
-
-static int
-boot(Medium *mp, char *file)
-{
-	Type *tp;
-	Medium *xmp;
-	static int didaddconf;
-	Boot b;
-	char *p;
-
-	memset(&b, 0, sizeof b);
-	b.state = INITKERNEL;
-
-	if(didaddconf == 0) {
-		didaddconf = 1;
-		for(tp = types; tp->type != Tnil; tp++)
-			if(tp->addconf)
-				for(xmp = tp->media; xmp; xmp = xmp->next)
-					(*tp->addconf)(xmp->dev);
-	}
-
-	sprint(BOOTLINE, "%s!%s", mp->name, file);
-	for(p = file; *p != '\0'; p++){
-		if(*p != ' ' && *p != '\t')
-			continue;
-		*p = '\0';
-		break;
-	}
-	return (*mp->type->boot)(mp->dev, file, &b);
-}
-
-static Medium*
-allocm(Type *tp)
-{
-	Medium **l;
-
-	if(curmedium >= &media[Nmedia])
-		return 0;
-
-	for(l = &tp->media; *l; l = &(*l)->next)
-		;
-	*l = curmedium++;
-	return *l;
-}
-
-Medium*
-probe(int type, int flag, int dev)
-{
-	Type *tp;
-	int i;
-	Medium *mp;
-	File f;
-	Fs *fs;
-	char **partp;
-
-	for(tp = types; tp->type != Tnil; tp++){
-		if(type != Tany && type != tp->type)
-			continue;
-
-		if(flag != Fnone){
-			for(mp = tp->media; mp; mp = mp->next){
-				if((flag & mp->flag) && (dev == Dany || dev == mp->dev))
-					return mp;
-			}
-		}
-
-		if((tp->flag & Fprobe) == 0){
-			tp->flag |= Fprobe;
-			tp->mask = (*tp->init)();
-		}
-
-		for(i = 0; tp->mask; i++){
-			if((tp->mask & (1<<i)) == 0)
-				continue;
-			tp->mask &= ~(1<<i);
-
-			if((mp = allocm(tp)) == 0)
-				continue;
-
-			mp->dev = i;
-			mp->flag = tp->flag;
-			mp->type = tp;
-			(*tp->initdev)(i, mp->name);
-
-			if(mp->flag & Fini){
-				mp->flag &= ~Fini;
-				for(partp = tp->parts; *partp; partp++){
-					if((fs = (*tp->getfspart)(i, *partp, 0)) == nil)
-						continue;
-
-					for(ini = tp->inis; *ini; ini++){
-						if(fswalk(fs, *ini, &f) > 0){
-							mp->inifs = fs;
-							mp->part = *partp;
-							mp->ini = f.path;
-							mp->flag |= Fini;
-							goto Break2;
-						}
-					}
-				}
-			}
-		Break2:
-			if((flag & mp->flag) && (dev == Dany || dev == i))
-				return mp;
-		}
-	}
-
-	return 0;
-}
-
-void
-main(void)
-{
-	Medium *mp;
-	int cons, flag, i, mode, tried;
-	char def[2*NAMELEN], line[80], *p, *file;
-	Type *tp;
-
-	i8042a20();
-	cgapost(0x9B);
-
-	memset(m, 0, sizeof(Mach));
-	m->pdb = mach0pdb;
-	m->gdt = mach0gdt;
-
-	/*
-	 * Memstart is set by the low-level bootstrap
-	 * code to the first free memory location after
-	 * text+data+bss+conf+pdb+pt+pmach+vmach+gdt.
-	 * This is where allocatable memory starts.
-	 * However, the E820 map indicates 0x000A0000
-	 * is UPA memory although the VGA memory is
-	 * probably there and meminit will get that wrong.
-	 * Hacks are needed to make this work until it
-	 * is all rewritten.
-	 * Memstart->memend could be memstart->KZERO|0x9xxxx
-	 * to keep all the memory use below 1MiB.
-	 *
-	 * Sigh. Accomodate the bloated Plan 9 kernel to prevent
-	 * having different PXE loaders for different systems.
-	memstart = KZERO|(3*MiB+512*KiB);
-	memend = KZERO|(4*MiB);
-	 */
-	memstart = KZERO|(8*MiB);
-	memend = KZERO|(16*MiB);
-
-	cgainit();
-	trapinit();
-	clockinit();
-	alarminit();
-	spllo();
-	kbdinit();
-cons = consinit("0", 0);
-	readlsconf();
-	meminit(0);
-
-	if(end > KADDR(640*1024))
-		panic("i'm too big\n");
-
-	for(tp = types; tp->type != Tnil; tp++){
-		//if(tp->type == Tether)
-		//	continue;
-		if((mp = probe(tp->type, Fini, Dany)) && (mp->flag & Fini)){
-			print("using %s!%s!%s\n", mp->name, mp->part, mp->ini);
-			iniread = !dotini(mp->inifs);
-			break;
-		}
-	}
-	apminit();
-
-	if(iniread && !cons && (p = getconf("console")) != nil)
-		cons = consinit(p, getconf("baud"));
-	USED(cons);
-	//devpccardlink();
-	//devi82365link();
-if(vflag){
-    pcihinv(nil);
-    delay(5000);
-}
-
-	/*
- 	 * Even after we find the ini file, we keep probing disks,
-	 * because we have to collect the partition tables and
-	 * have boot devices for parse.
-	 */
-	probe(Tany, Fnone, Dany);
-	tried = 0;
-	mode = Mauto;
-
-	p = getconf("bootfile");
-
-	if(p != 0) {
-		strecpy(line, line+sizeof(line), p);
-		p = line;
-
-		mode = Manual;
-		for(i = 0; i < NMode; i++){
-			if(strcmp(p, modes[i].name) == 0){
-				mode = modes[i].mode;
-				goto done;
-			}
-		}
-		if((mp = parse(p, &file)) == nil) {
-			print("Unknown boot device: %s\n", p);
-			goto done;
-		}
-		tried = boot(mp, file);
-	}
-done:
-	if(tried == 0 && mode != Manual){
-		flag = Fany;
-		if(mode == Mlocal)
-			flag &= ~Fbootp;
-		if((mp = probe(Tany, flag, Dany)) && mp->type->type != Tfloppy)
-			boot(mp, "");
-	}
-
-	def[0] = 0;
-	probe(Tany, Fnone, Dany);
-	if(p = getconf("bootdef"))
-		strecpy(def, def+sizeof(def), p);
-
-	flag = 0;
-	for(tp = types; tp->type != Tnil; tp++){
-		for(mp = tp->media; mp; mp = mp->next){
-			if(flag == 0){
-				flag = 1;
-				print("Boot devices:");
-			}
-			(*tp->printdevs)(mp->dev);
-		}
-	}
-	if(flag)
-		print("\n");
-
-	for(;;){
-		if(getstr("boot from", line, sizeof(line), def, (mode != Manual)*15) >= 0)
-			if(mp = parse(line, &file))
-				boot(mp, file);
-		def[0] = 0;
-	}
-}
-
-int
-getfields(char *lp, char **fields, int n, char sep)
-{
-	int i;
-
-	for(i = 0; lp && *lp && i < n; i++){
-		while(*lp == sep)
-			*lp++ = 0;
-		if(*lp == 0)
-			break;
-		fields[i] = lp;
-		while(*lp && *lp != sep){
-			if(*lp == '\\' && *(lp+1) == '\n')
-				*lp++ = ' ';
-			lp++;
-		}
-	}
-	return i;
-}
-
-int
-cistrcmp(char *a, char *b)
-{
-	int ac, bc;
-
-	for(;;){
-		ac = *a++;
-		bc = *b++;
-
-		if(ac >= 'A' && ac <= 'Z')
-			ac = 'a' + (ac - 'A');
-		if(bc >= 'A' && bc <= 'Z')
-			bc = 'a' + (bc - 'A');
-		ac -= bc;
-		if(ac)
-			return ac;
-		if(bc == 0)
-			break;
-	}
-	return 0;
-}
-
-int
-cistrncmp(char *a, char *b, int n)
-{
-	unsigned ac, bc;
-
-	while(n > 0){
-		ac = *a++;
-		bc = *b++;
-		n--;
-
-		if(ac >= 'A' && ac <= 'Z')
-			ac = 'a' + (ac - 'A');
-		if(bc >= 'A' && bc <= 'Z')
-			bc = 'a' + (bc - 'A');
-
-		ac -= bc;
-		if(ac)
-			return ac;
-		if(bc == 0)
-			break;
-	}
-
-	return 0;
-}
-
-uint32_t palloc = 0;
-
-void*
-ialloc(uint32_t n, int align)
-{
-	uint32_t p;
-	int a;
-
-	if(palloc == 0)
-		palloc = memstart;
-
-	p = palloc;
-	if(align <= 0)
-		align = 4;
-	if(a = n % align)
-		n += align - a;
-	if(a = p % align)
-		p += align - a;
-
-
-	palloc = p+n;
-	if(palloc > memend)
-		panic("ialloc(%lud, %d) called from 0x%lux\n",
-			n, align, getcallerpc());
-	return memset((void*)p, 0, n);
-}
-
-void*
-xspanalloc(uint32_t size, int align, uint32_t span)
-{
-	uint32_t a, v;
-
-	if((palloc + (size+align+span)) > memend)
-		panic("xspanalloc(%lud, %d, 0x%lux) called from 0x%lux\n",
-			size, align, span, getcallerpc());
-
-	a = (uint32_t)ialloc(size+align+span, 0);
-
-	if(span > 2)
-		v = (a + span) & ~(span-1);
-	else
-		v = a;
-
-	if(align > 1)
-		v = (v + align) & ~(align-1);
-
-	return (void*)v;
-}
-
-static Block *allocbp;
-
-Block*
-allocb(int size)
-{
-	Block *bp, **lbp;
-	uint32_t addr;
-
-	lbp = &allocbp;
-	for(bp = *lbp; bp; bp = bp->next){
-		if((bp->lim - bp->base) >= size){
-			*lbp = bp->next;
-			break;
-		}
-		lbp = &bp->next;
-	}
-	if(bp == 0){
-		if((palloc + (sizeof(Block)+size+64)) > memend)
-			panic("allocb(%d) called from 0x%lux\n",
-				size, getcallerpc());
-		bp = ialloc(sizeof(Block)+size+64, 0);
-		addr = (uint32_t)bp;
-		addr = ROUNDUP(addr + sizeof(Block), 8);
-		bp->base = (uint8_t*)addr;
-		bp->lim = ((uint8_t*)bp) + sizeof(Block)+size+64;
-	}
-
-	if(bp->flag)
-		panic("allocb reuse\n");
-
-	bp->rp = bp->base;
-	bp->wp = bp->rp;
-	bp->next = 0;
-	bp->flag = 1;
-
-	return bp;
-}
-
-void
-freeb(Block* bp)
-{
-	bp->next = allocbp;
-	allocbp = bp;
-
-	bp->flag = 0;
-}
-
-enum {
-	Paddr=		0x70,	/* address port */
-	Pdata=		0x71,	/* data port */
-};
-
-uint8_t
-nvramread(int offset)
-{
-	outb(Paddr, offset);
-	return inb(Pdata);
-}
-
-void (*etherdetach)(void);
-void (*floppydetach)(void);
-void (*sddetach)(void);
-
-void
-impulse(void)
-{
-	if(etherdetach)
-		etherdetach();
-	if(floppydetach)
-		floppydetach();
-	if(sddetach)
-		sddetach();
-
-	consdrain();
-
-	trapdisable();
-}
-
-void
-warp9(uint32_t entry)
-{
-	extern void _warp9(uint32_t);
-
-	print("warp9(%#lux) %d\n", entry, nmmap);
-	if(vflag)
-		print("mkmultiboot\n");
-	mkmultiboot();
-	if(vflag)
-		print("impulse\n");
-
-	/*
-	 * No output after impulse().
-	 */
-	impulse();
-	_warp9(PADDR(entry));
-
-	/*
-	 * Instead, this is where to push things on the stack to
-	 * boot *BSD systems, e.g.
-	(*(void(*)(void*, void*, void*, void*, ulong, ulong))(PADDR(entry)))(0, 0, 0, 0, 8196, 640);
-	 * will enable NetBSD boot (the real memory size needs to
-	 * go in the 5th argument).
-	(*(void(*)(void))(PADDR(entry)))();
-	 */
-
-}

+ 0 - 185
sys/src/9/w/pxeload/lxxx.s

@@ -1,185 +0,0 @@
-#include "386l.h"
-
-#define KZERO		(0)
-
-#define	DELAY		BYTE $0xeb;		/* JMP .+2 */		\
-			BYTE $0x00
-#define NOP		BYTE $0x90		/* NOP */
-
-#define pFARJMP32(s, o)	BYTE $0xea;		/* far jmp ptr32:16 */	\
-			LONG $o; WORD $s
-
-#define rFARJMP16(s, o)	BYTE $0xea;		/* far jump ptr16:16 */	\
-			WORD $o; WORD $s;
-#define rFARJMP32(s, o)	BYTE $0x66;		/* far jump ptr32:16 */	\
-			pFARJMP32(s, o)
-#define rLGDT(gdtptr)	BYTE $0x0f;		/* LGDT */		\
-			BYTE $0x01; BYTE $0x16;				\
-			WORD $gdtptr
-
-#define rAX		0			/* rX  */
-#define rCX		1
-#define rDX		2
-#define rBX		3
-#define rSP		4			/* SP */
-#define rBP		5			/* BP */
-#define rSI		6			/* SI */
-#define rDI		7			/* DI */
-
-#define rMOV16(i, rX)	BYTE $(0xB8+rX);	/* i -> rX */		\
-			WORD $i;
-#define rMOV32(i, rX)	BYTE $0x66;		/* i -> rX */		\
-			BYTE $(0xB8+rX);				\
-			LONG $i;
-
-/*
- * Real mode. Welcome to 1978.
- */
-TEXT _real<>(SB), 1, $-4
-	rFARJMP16(0, _endofheader<>-KZERO(SB))	/*  */
-	NOP; NOP; NOP				/* align */
-
-_startofheader:
-	WORD $0; WORD $0			/* flags */
-
-TEXT _gdt32p<>(SB), 1, $-4
-	LONG	$0x0000; LONG $0		/* NULL descriptor */
-	LONG	$0xffff; LONG $0x00cf9a00	/* CS */
-	LONG	$0xffff; LONG $0x00cf9200	/* DS */
-
-TEXT _gdtptr32p<>(SB), 1, $-4
-	WORD	$(3*8-1)
-	LONG	$_gdt32p<>-KZERO(SB)
-
-TEXT _hello<>(SB), $0
-	BYTE $'H'; BYTE $'e'; BYTE $'l'; BYTE $'l';
-	BYTE $'o'; BYTE $' '; BYTE $'f'; BYTE $'r';
-	BYTE $'o'; BYTE $'m'; BYTE $' '; BYTE $'1';
-	BYTE $'9'; BYTE $'7'; BYTE $'8'; BYTE $'.';
-	BYTE $'\r';
-	BYTE $'\n';
-	BYTE $'\z';
-	BYTE $'\z';
-
-TEXT _endofheader<>(SB), 1, $-4
-	CLI
-	CLD
-
-	XORL	AX, AX
-	MOVW	AX, DS				/* initialise DS */
-	MOVW	AX, ES				/* initialise ES */
-	MOVW	AX, SS				/* initialise SS */
-
-	rMOV16(_real<>-KZERO(SB), rSP)		/* stack */
-	PUSHL	AX				/* CS segment */
-	rMOV16(_setCS<>-KZERO(SB), rAX)		/* address within segment */
-	PUSHL	AX
-	BYTE	$0xcb				/* far return */
-
-TEXT _setCS<>(SB), 1, $-4
-	MOVB	$0x0f, AH			/* get current display mode */
-	INT	$0x10
-
-	SUBB	$3, AL				/* is it text mode 3? */
-	JEQ	_cgaputs
-
-	MOVB	$0x0f, AH			/* text mode 3 */
-	MOVB	$0x03, AL
-	INT	$0x10
-
-_cgaputs:
-	rMOV16(_hello<>-KZERO(SB), rAX)		/* a cheery wee message */
-	MOVL	AX, SI
-
-	XORL	BX, BX				/* page number, colour */
-_cgaputsloop:
-	LODSB					/* next character in string */
-	ORB	AL, AL				/* \0? */
-	JEQ	_cgaend
-
-	MOVB	$0x0e, AH			/* teletype output */
-	INT	$0x10
-	JMP	_cgaputsloop
-_cgaend:
-
-	rMOV16(_real<>+(8-KZERO)(SB), rSI)	/* flag */
-	LODSW
-	ORL	AX, AX
-	JNE	_e820
-
-	INCL	AX
-	rMOV16(_real<>+(8-KZERO)(SB), rDI)	/* flag */
-	STOSW
-
-	rMOV16(0x0467, rDI)			/* reset entry point */
-	rMOV16(_endofheader<>-KZERO(SB), rAX)
-	STOSW
-	MOVW	CS, AX
-	STOSW
-
-	rMOV16(0x70, rDX)
-	MOVB	$0x8f, AL
-	OUTB
-	DELAY
-	INCL	DX
-	MOVB	$0x0a, AL
-	OUTB
-	DELAY
-
-rMOV16(0x1234, rBP)
-rMOV16(0x5678, rDX)
-	rFARJMP16(0xffff, 0)			/* reset */
-
-_e820:
-	rMOV16(_real<>-(KZERO+1024)(SB), rDI)	/* e820 save area */
-
-//	XORL	AX, AX				/* nothing to see here (yet) */
-//	STOSL
-//	STOSL
-
-	XORL	BX, BX				/* continuation */
-_e820int:
-	rMOV32(40, rCX)				/* buffer size */
-	rMOV32(0x534d4150, rDX)			/* signature - ASCII "SMAP" */
-	rMOV32(0xe820, rAX)			/* function code */
-
-	INT	$0x15				/* query system address map */
-	JCS	_e820end
-
-	INCL	AX
-_e820end:
-	STOSL
-	MOVL	CX, AX
-	STOSL
-//	MOVL	BX, AX
-//	STOSL
-	rMOV16(0xaabb, rAX)
-	STOSL
-	MOVW	CS, AX
-	STOSL
-
-	rLGDT(_gdtptr32p<>-KZERO(SB))		/* load a basic gdt */
-
-	MOVL	CR0, AX
-	ORL	$Pe, AX
-	MOVL	AX, CR0				/* turn on protected mode */
-	DELAY					/* JMP .+2 */
-
-	rMOV16(SSEL(SiDS, SsTIGDT|SsRPL0), rAX)	/*  */
-	MOVW	AX, DS
-	MOVW	AX, ES
-	MOVW	AX, FS
-	MOVW	AX, GS
-	MOVW	AX, SS
-
-	rFARJMP32(SSEL(SiCS, SsTIGDT|SsRPL0), _start32p-KZERO(SB))
-
-#ifdef standalone
-/*
- * Protected mode. Welcome to 1982.
- */
-TEXT _start32p(SB), 1, $-4
-_ndnr:
-	JMP	_ndnr
-	RET
-#endif /* standalone */

+ 0 - 259
sys/src/9/w/pxeload/mbr.s

@@ -1,259 +0,0 @@
-/*
- * Hard disc boot block. Loaded at 0x7C00, relocates to 0x0600:
- *	8a mbr.s; 8l -o mbr -l -H3 -T0x0600 mbr.8
- */
-#include "x16.h"
-#include "mem.h"
-
-/*#define FLOPPY	1		/* test on a floppy */
-#define TRACE(C)	PUSHA;\
-			CLR(rBX);\
-			MOVB $C, AL;\
-			LBI(0x0E, rAH);\
-			BIOSCALL(0x10);\
-			POPA
-
-/*
- * We keep data on the stack, indexed by BP.
- */
-#define Xdap		0x00		/* disc address packet */
-#define Xtable		0x10		/* partition table entry */
-#define Xdrive		0x12		/* starting disc */
-#define Xtotal		0x14		/* sum of allocated data above */
-
-/*
- * Start: loaded at 0000:7C00, relocate to 0000:0600.
- * Boot drive is in rDL.
- */
-TEXT _start(SB), $0
-	CLI
-	CLR(rAX)
-	MTSR(rAX, rSS)			/* 0000 -> rSS */
-	LWI((0x7C00-Xtotal), rSP)	/* 7Bxx -> rSP */
-	MW(rSP, rBP)			/* set the indexed-data pointer */
-
-	MTSR(rAX, rDS)			/* 0000 -> rDS, source segment */
-	LWI(0x7C00, rSI)		/* 7C00 -> rSI, source offset */
-	MTSR(rAX, rES)			/* 0000 -> rES, destination segment */
-	LWI(0x600, rDI)			/* 0600 -> rDI, destination offset */
-	LWI(0x100, rCX)			/* 0100 -> rCX, loop count (words) */
-
-	CLD
-	REP; MOVSL			/* MOV DS:[(E)SI] -> ES:[(E)DI] */
-
-	FARJUMP16(0x0000, _start0600(SB))
-
-TEXT _start0600(SB), $0
-#ifdef FLOPPY
-	LBI(0x80, rDL)
-#else
-	CLRB(rAL)			/* some systems pass 0 */
-	CMPBR(rAL, rDL)
-	JNE _save
-	LBI(0x80, rDL)
-#endif /* FLOPPY */
-_save:
-	SXB(rDL, Xdrive, xBP)		/* save disc */
-
-	LWI(confidence(SB), rSI)	/* for that warm, fuzzy feeling */
-	CALL16(BIOSputs(SB))
-
-	LWI(_start+0x01BE(SB), rSI)	/* address of partition table */
-	LWI(0x04, rCX)			/* 4 entries in table */
-	LBI(0x80, rAH)			/* active entry value */
-	CLRB(rAL)			/* inactive entry value */
-
-_activeloop0:
-	LXB(0x00, xSI, rBL)		/* get active entry from table */
-	CMPBR(rBL, rAH)			/* is this an active entry? */
-	JEQ _active
-
-	CMPBR(rBL, rAL)			/* if not active it should be 0 */
-	JNE _invalidMBR
-
-	ADDI(0x10, rSI)			/* next table entry */
-	DEC(rCX)
-	JNE _activeloop0
-
-	LWI(noentry(SB), rSI)
-	CALL16(buggery(SB))
-
-_active:
-	MW(rSI, rDI)			/* save table address */
-
-_activeloop1:
-	ADDI(0x10, rSI)			/* next table entry */
-	DEC(rCX)
-	JEQ _readsector
-
-	LXB(0x00, xSI, rBL)		/* get active entry from table */
-	CMPBR(rBL, rAH)			/* is this an active entry? */
-	JNE _activeloop1		/* should only be one active */
-
-_invalidMBR:
-	LWI(invalidMBR(SB), rSI)
-	CALL16(buggery(SB))
-
-_readsector:
-	LBI(0x41, rAH)			/* check extensions present */
-	LWI(0x55AA, rBX)
-	LXB(Xdrive, xBP, rDL)		/* drive */
-	BIOSCALL(0x13)			/* CF set on failure */
-	JCS _readsector2
-	CMPI(0xAA55, rBX)
-	JNE _readsector2
-	ANDI(0x0001, rCX)
-	JEQ _readsector2
-
-_readsector42:
-	SBPBI(0x10, Xdap+0)		/* packet size */
-	SBPBI(0x00, Xdap+1)		/* reserved */
-	SBPBI(0x01, Xdap+2)		/* number of blocks to transfer */
-	SBPBI(0x00, Xdap+3)		/* reserved */
-	SBPWI(0x7C00, Xdap+4)		/* transfer buffer :offset */
-	SBPWI(0x0000, Xdap+6)		/* transfer buffer seg: */
-	LXW(0x08, xDI, rAX)		/* LBA (64-bits) */
-	SBPW(rAX, Xdap+8)
-	LXW(0x0A, xDI, rAX)
-	SBPW(rAX, Xdap+10)
-	SBPWI(0x0000, Xdap+12)
-	SBPWI(0x0000, Xdap+14)
-
-	MW(rBP, rSI)			/* disk address packet */
-	LBI(0x42, rAH)			/* extended read */
-	BIOSCALL(0x13)			/* CF set on failure */
-	JCC _readsectorok
-
-	LWI(ioerror(SB), rSI)
-	CALL16(buggery(SB))
-
-/*
- * Read a sector from a disc using the traditional BIOS call.
- * For BIOSCALL(0x13/AH=0x02):
- *   rAH	0x02
- *   rAL	number of sectors to read (1)
- *   rCH	low 8 bits of cylinder
- *   rCL	high 2 bits of cylinder (7-6), sector (5-0)
- *   rDH	head
- *   rDL	drive
- *   rES:rBX	buffer address
- */
-_readsector2:
-	LXB(0x01, xDI, rDH)		/* head */
-	LXW(0x02, xDI, rCX)		/* save active cylinder/sector */
-
-	LWI(0x0201, rAX)		/* read one sector */
-	LXB(Xdrive, xBP, rDL)		/* drive */
-	LWI(0x7C00, rBX)		/* buffer address (rES already OK) */
-	BIOSCALL(0x13)			/* CF set on failure */
-	JCC _readsectorok
-
-	LWI(ioerror(SB), rSI)
-	CALL16(buggery(SB))
-
-_readsectorok:
-	LWI(0x7C00, rBX)		/* buffer address (rES already OK) */
-	LXW(0x1FE, xBX, rAX)
-	CMPI(0xAA55, rAX)
-	JNE _bbnotok
-
-	/*
-	 * Jump to the loaded PBS.
-	 * rDL and rSI should still contain the drive
-	 * and partition table pointer respectively.
-	 */
-	MW(rDI, rSI)
-	FARJUMP16(0x0000, 0x7C00)
-
-_bbnotok:
-	LWI(invalidPBS(SB), rSI)
-
-TEXT buggery(SB), $0
-	CALL16(BIOSputs(SB))
-	LWI(reboot(SB), rSI)
-	CALL16(BIOSputs(SB))
-
-_wait:
-	CLR(rAX)			/* wait for any key */
-	BIOSCALL(0x16)
-
-_reset:
-	CLR(rBX)			/* set ES segment for BIOS area */
-	MTSR(rBX, rES)
-
-	LWI(0x0472, rBX)		/* warm-start code address */
-	LWI(0x1234, rAX)		/* warm-start code */
-	POKEW				/* MOVW	AX, ES:[BX] */
-
-	FARJUMP16(0xFFFF, 0x0000)	/* reset */
-
-/*
- * Output a string to the display.
- * String argument is in rSI.
- */
-TEXT BIOSputs(SB), $0
-	PUSHA
-	CLR(rBX)
-_BIOSputs:
-	LODSB
-	ORB(rAL, rAL)
-	JEQ _BIOSputsret
-
-	LBI(0x0E, rAH)
-	BIOSCALL(0x10)
-	JMP _BIOSputs
-
-_BIOSputsret:
-	POPA
-	RET
-
-/* "No active entry in MBR" */
-TEXT noentry(SB), $0
-	BYTE $'N'; BYTE $'o'; BYTE $' '; BYTE $'a';
-	BYTE $'c'; BYTE $'t'; BYTE $'i'; BYTE $'v';
-	BYTE $'e'; BYTE $' '; BYTE $'e'; BYTE $'n';
-	BYTE $'t'; BYTE $'r'; BYTE $'y'; BYTE $' ';
-	BYTE $'i'; BYTE $'n'; BYTE $' '; BYTE $'M';
-	BYTE $'B'; BYTE $'R';
-	BYTE $'\z';
-
-/* "Invalid MBR" */
-TEXT invalidMBR(SB), $0
-	BYTE $'I'; BYTE $'n'; BYTE $'v'; BYTE $'a';
-	BYTE $'l'; BYTE $'i'; BYTE $'d'; BYTE $' ';
-	BYTE $'M'; BYTE $'B'; BYTE $'R';
-	BYTE $'\z';
-
-/* "I/O error" */
-TEXT ioerror(SB), $0
-	BYTE $'I'; BYTE $'/'; BYTE $'O'; BYTE $' ';
-	BYTE $'e'; BYTE $'r'; BYTE $'r'; BYTE $'o';
-	BYTE $'r';
-	BYTE $'\z';
-
-/* "Invalid PBS" */
-TEXT invalidPBS(SB), $0
-	BYTE $'I'; BYTE $'n'; BYTE $'v'; BYTE $'a';
-	BYTE $'l'; BYTE $'i'; BYTE $'d'; BYTE $' ';
-	BYTE $'P'; BYTE $'B'; BYTE $'S';
-	BYTE $'\z';
-
-/* "\r\nPress almost any key to reboot..." */
-TEXT reboot(SB), $0
-	BYTE $'\r';BYTE $'\n';
-	BYTE $'P'; BYTE $'r'; BYTE $'e'; BYTE $'s';
-	BYTE $'s'; BYTE $' '; BYTE $'a'; BYTE $'l';
-	BYTE $'m'; BYTE $'o'; BYTE $'s'; BYTE $'t';
-	BYTE $' '; BYTE $'a'; BYTE $'n'; BYTE $'y';
-	BYTE $' '; BYTE $'k'; BYTE $'e'; BYTE $'y';
-	BYTE $' '; BYTE $'t'; BYTE $'o'; BYTE $' ';
-	BYTE $'r'; BYTE $'e'; BYTE $'b'; BYTE $'o';
-	BYTE $'o'; BYTE $'t'; BYTE $'.'; BYTE $'.';
-	BYTE $'.';
-	BYTE $'\z';
-
-/* "MBR..." */
-TEXT confidence(SB), $0
-	BYTE $'M'; BYTE $'B'; BYTE $'R'; BYTE $'.';
-	BYTE $'.'; BYTE $'.';
-	BYTE $'\z';

+ 0 - 121
sys/src/9/w/pxeload/mem.h

@@ -1,121 +0,0 @@
-/* 
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
-
-/*
- * Memory and machine-specific definitions.  Used in C and assembler.
- */
-#define KiB	1024u			/* 0x00000400 */
-#define MiB	1048576u		/* 0x00100000 */
-#define GiB	1073741824u		/* 0x40000000 */
-
-/*
- * Sizes
- */
-#define	BI2BY		8			/* bits per byte */
-#define BI2WD		32			/* bits per word */
-#define	BY2WD		4			/* bytes per word */
-#define	BY2PG		4096			/* bytes per page */
-#define	PGSHIFT		12			/* log(BY2PG) */
-#define PGROUND(s)	(((s)+(BY2PG-1))&~(BY2PG-1))
-
-#define	MAXMACH		1			/* max # cpus system can run */
-
-/*
- * Time
- */
-#define	HZ		(100)				/* clock frequency */
-#define	MS2HZ		(1000/HZ)			/* millisec per clock tick */
-#define	TK2SEC(t)	((t)/HZ)			/* ticks to seconds */
-#define	TK2MS(x)	((x)*(1000/HZ))
-#define	MS2TK(t)	((((ulong)(t))*HZ)/1000)	/* milliseconds to ticks */
-
-/*
- * Fundamental addresses
- * To run in only protected mode (paging off),
- * #define KZERO	0
- * else
- * #define KZERO	0x80000000
- */
-#define KZERO		0			/* base of kernel address space */
-#define	KTZERO		KZERO			/* first address in kernel text */
-#define ROMBIOS		(KZERO|0xF0000)
-#define CONFADDR	(KZERO+0x1200)		/* info passed from boot loader */
-
-#define MACHSIZE	(BY2PG*8)			/* stack size */
-
-/*
- *  known 80386 segments (in GDT) and their selectors
- */
-#define	NULLSEG		0	/* null segment */
-#define	KDSEG		1	/* kernel data/stack */
-#define	KESEG		2	/* kernel executable */
-#define	UDSEG		3	/* user data/stack */
-#define	UESEG		4	/* user executable */
-#define	SYSGATE		5	/* system call gate */
-#define TSSSEG		6	/* task segment */
-#define	APMCSEG		6	/* APM code segment */
-#define	APMCSEG16	7	/* APM 16-bit code segment */
-#define	APMDSEG		8	/* APM data segment */
-#define	NGDT		10	/* number of GDT entries required */
-
-#define SELGDT	(0<<3)	/* selector is in gdt */
-#define	SELLDT	(1<<3)	/* selector is in ldt */
-
-#define SELECTOR(i, t, p)	(((i)<<3) | (t) | (p))
-
-#define NULLSEL	SELECTOR(NULLSEG, SELGDT, 0)
-#define KESEL	SELECTOR(KESEG, SELGDT, 0)
-#define KDSEL	SELECTOR(KDSEG, SELGDT, 0)
-#define UESEL	SELECTOR(UESEG, SELGDT, 3)
-#define UDSEL	SELECTOR(UDSEG, SELGDT, 3)
-#define TSSSEL	SELECTOR(TSSSEG, SELGDT, 0)
-
-/*
- *  fields in segment descriptors
- */
-#define SEGDATA	(0x10<<8)	/* data/stack segment */
-#define SEGEXEC	(0x18<<8)	/* executable segment */
-#define	SEGTSS	(0x9<<8)	/* TSS segment */
-#define SEGCG	(0x0C<<8)	/* call gate */
-#define	SEGIG	(0x0E<<8)	/* interrupt gate */
-#define SEGTG	(0x0F<<8)	/* task gate */
-#define SEGTYPE	(0x1F<<8)
-
-#define SEGP	(1<<15)		/* segment present */
-#define SEGPL(x) ((x)<<13)	/* priority level */
-#define SEGB	(1<<22)		/* granularity 1==4k (for expand-down) */
-#define SEGG	(1<<23)		/* granularity 1==4k (for other) */
-#define SEGE	(1<<10)		/* expand down */
-#define SEGW	(1<<9)		/* writable (for data/stack) */
-#define	SEGR	(1<<9)		/* readable (for code) */
-#define SEGD	(1<<22)		/* default 1==32bit (for code) */
-
-/*
- *  virtual MMU
- */
-#define PTEMAPMEM	(1024*1024)	/* ??? */
-#define SEGMAPSIZE	16		/* ??? */
-#define	PTEPERTAB	(PTEMAPMEM/BY2PG)	/* ??? */
-#define PPN(x)		((x)&~(BY2PG-1))
-
-/*
- *  physical MMU
- */
-#define	PTEVALID	(1<<0)
-#define	PTEUNCACHED	0		/* everything is uncached */
-#define PTEWRITE	(1<<1)
-#define	PTERONLY	(0<<1)
-#define	PTEKERNEL	(0<<2)
-#define	PTEUSER		(1<<2)
-#define PTESIZE		(1<<7)
-
-/*
- *  flag register bits that we care about
- */
-#define IFLAG	0x200

+ 0 - 587
sys/src/9/w/pxeload/memory.c

@@ -1,587 +0,0 @@
-/*
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
-
-/*
- * Size memory and create the kernel page-tables on the fly while doing so.
- * Called from main(), this code should only be run by the bootstrap processor.
- */
-#include "u.h"
-#include "lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-
-#define MEMDEBUG	0
-
-#define PDX(va)		((((ulong)(va))>>22) & 0x03FF)
-#define PTX(va)		((((ulong)(va))>>12) & 0x03FF)
-
-enum {
-	MemUPA		= 0,		/* unbacked physical address */
-	MemRAM		= 1,		/* physical memory */
-	MemUMB		= 2,		/* upper memory block (<16MiB) */
-	NMemType	= 3,
-
-	MemMinMiB	= 4,		/* minimum physical memory (<=4MiB) */
-	MemMaxMiB	= 768,		/* maximum physical memory to check */
-
-	NMemBase	= 10,
-};
-
-typedef struct Map Map;
-struct Map {
-	uintptr	addr;
-	uint32_t	size;
-};
-
-typedef struct {
-	char*	name;
-	Map*	map;
-	Map*	mapend;
-
-	Lock;
-} RMap;
-
-static Map mapupa[8];
-static RMap rmapupa = {
-	"unallocated unbacked physical memory",
-	mapupa,
-	&mapupa[7],
-};
-
-static Map xmapupa[8];
-static RMap xrmapupa = {
-	"unbacked physical memory",
-	xmapupa,
-	&xmapupa[7],
-};
-
-static Map mapram[8];
-static RMap rmapram = {
-	"physical memory",
-	mapram,
-	&mapram[7],
-};
-
-static Map mapumb[64];
-static RMap rmapumb = {
-	"upper memory block",
-	mapumb,
-	&mapumb[63],
-};
-
-static Map mapumbrw[8];
-static RMap rmapumbrw = {
-	"UMB device memory",
-	mapumbrw,
-	&mapumbrw[7],
-};
-
-void
-mapprint(RMap* rmap)
-{
-	Map *mp;
-
-	print("%s\n", rmap->name);
-	for(mp = rmap->map; mp->size; mp++){
-		print("\t%#16.16p %#8.8lux %#16.16p\n",
-			mp->addr, mp->size, mp->addr+mp->size);
-	}
-}
-
-void
-memdebug(void)
-{
-	uintptr maxpa, maxpa1, maxpa2;
-
-	if(!MEMDEBUG)
-		return;
-
-	maxpa = (nvramread(0x18)<<8)|nvramread(0x17);
-	maxpa1 = (nvramread(0x31)<<8)|nvramread(0x30);
-	maxpa2 = (nvramread(0x16)<<8)|nvramread(0x15);
-	print("maxpa = %#p -> %#p, maxpa1 = %#p maxpa2 = %#p\n",
-		maxpa, MiB+maxpa*KiB, maxpa1, maxpa2);
-
-	mapprint(&rmapram);
-	mapprint(&rmapumb);
-	mapprint(&rmapumbrw);
-	mapprint(&rmapupa);
-}
-
-void
-mapfree(RMap* rmap, uint32_t addr, uint32_t size)
-{
-	Map *mp;
-	uint32_t t;
-
-	if(size == 0)
-		return;
-
-	lock(rmap);
-	for(mp = rmap->map; mp->addr <= addr && mp->size; mp++)
-		;
-
-	if(mp > rmap->map && (mp-1)->addr+(mp-1)->size == addr){
-		(mp-1)->size += size;
-		if(addr+size == mp->addr){
-			(mp-1)->size += mp->size;
-			while(mp->size){
-				mp++;
-				(mp-1)->addr = mp->addr;
-				(mp-1)->size = mp->size;
-			}
-		}
-	}
-	else{
-		if(addr+size == mp->addr && mp->size){
-			mp->addr -= size;
-			mp->size += size;
-		}
-		else do{
-			if(mp >= rmap->mapend){
-				print("mapfree: %s: losing 0x%luX, %lud\n",
-					rmap->name, addr, size);
-				break;
-			}
-			t = mp->addr;
-			mp->addr = addr;
-			addr = t;
-			t = mp->size;
-			mp->size = size;
-			mp++;
-		}while(size = t);
-	}
-	unlock(rmap);
-}
-
-uint32_t
-mapalloc(RMap* rmap, uint32_t addr, int size, int align)
-{
-	Map *mp;
-	uint32_t maddr, oaddr;
-
-	lock(rmap);
-	for(mp = rmap->map; mp->size; mp++){
-		maddr = mp->addr;
-
-		if(addr){
-			/*
-			 * A specific address range has been given:
-			 *   if the current map entry is greater then
-			 *   the address is not in the map;
-			 *   if the current map entry does not overlap
-			 *   the beginning of the requested range then
-			 *   continue on to the next map entry;
-			 *   if the current map entry does not entirely
-			 *   contain the requested range then the range
-			 *   is not in the map.
-			 */
-			if(maddr > addr)
-				break;
-			if(mp->size < addr - maddr)	/* maddr+mp->size < addr, but no overflow */
-				continue;
-			if(addr - maddr > mp->size - size)	/* addr+size > maddr+mp->size, but no overflow */
-				break;
-			maddr = addr;
-		}
-
-		if(align > 0)
-			maddr = ((maddr+align-1)/align)*align;
-		if(mp->addr+mp->size-maddr < size)
-			continue;
-
-		oaddr = mp->addr;
-		mp->addr = maddr+size;
-		mp->size -= maddr-oaddr+size;
-		if(mp->size == 0){
-			do{
-				mp++;
-				(mp-1)->addr = mp->addr;
-			}while((mp-1)->size = mp->size);
-		}
-
-		unlock(rmap);
-		if(oaddr != maddr)
-			mapfree(rmap, oaddr, maddr-oaddr);
-
-		return maddr;
-	}
-	unlock(rmap);
-
-	return 0;
-}
-
-static void
-umbscan(void)
-{
-	uint8_t *p;
-
-	/*
-	 * Scan the Upper Memory Blocks (0xA0000->0xF0000) for pieces
-	 * which aren't used; they can be used later for devices which
-	 * want to allocate some virtual address space.
-	 * Check for two things:
-	 * 1) device BIOS ROM. This should start with a two-byte header
-	 *    of 0x55 0xAA, followed by a byte giving the size of the ROM
-	 *    in 512-byte chunks. These ROM's must start on a 2KiB boundary.
-	 * 2) device memory. This is read-write.
-	 * There are some assumptions: there's VGA memory at 0xA0000 and
-	 * the VGA BIOS ROM is at 0xC0000. Also, if there's no ROM signature
-	 * at 0xE0000 then the whole 64KiB up to 0xF0000 is theoretically up
-	 * for grabs; check anyway.
-	 */
-	p = KADDR(0xD0000);	/*RSC: changed from 0xC0000 */
-	while(p < (uint8_t*)KADDR(0xE0000)){
-		if (p[0] == 0x55 && p[1] == 0xAA) {
-			/* Skip p[2] chunks of 512 bytes.  Test for 0x55 AA before
-			     poking obtrusively, or else the Thinkpad X20 dies when
-			     setting up the cardbus (PB) */
-			p += p[2] * 512;
-			continue;
-		}
-
-		p[0] = 0xCC;
-		p[2*KiB-1] = 0xCC;
-		if(p[0] != 0xCC || p[2*KiB-1] != 0xCC){
-			p[0] = 0x55;
-			p[1] = 0xAA;
-			p[2] = 4;
-			if(p[0] == 0x55 && p[1] == 0xAA){
-				p += p[2]*512;
-				continue;
-			}
-			if(p[0] == 0xFF && p[1] == 0xFF)
-				mapfree(&rmapumb, PADDR(p), 2*KiB);
-		}
-		else
-			mapfree(&rmapumbrw, PADDR(p), 2*KiB);
-		p += 2*KiB;
-	}
-
-	p = KADDR(0xE0000);
-	if(p[0] != 0x55 || p[1] != 0xAA){
-		p[0] = 0xCC;
-		p[64*KiB-1] = 0xCC;
-		if(p[0] != 0xCC && p[64*KiB-1] != 0xCC)
-			mapfree(&rmapumb, PADDR(p), 64*KiB);
-	}
-}
-
-
-void
-meminit(uint32_t)
-{
-	MMap *map;
-	uint32_t modend;
-	uint64_t addr, last, len;
-
-	umbscan();
-
-	modend = PADDR(memstart);
-	last = 0;
-	for(map = mmap; map < &mmap[nmmap]; map++){
-		addr = (((uint64_t)map->base[1])<<32)|map->base[0];
-		len = (((uint64_t)map->length[1])<<32)|map->length[0];
-
-		switch(map->type){
-		default:
-		case 2:				/* reserved */
-		case 3:				/* ACPI Reclaim Memory */
-		case 4:				/* ACPI NVS Memory */
-			break;
-		case 1:				/* Memory */
-			if(addr < 1*MiB || addr+len < modend)
-				break;
-			if(addr < modend){
-				len -= modend - addr;
-				addr = modend;
-			}
-			mapraminit(addr, len);
-			break;
-		}
-
-		if(addr != last && addr > modend){
-			/*
-			 * See the comments in main about space < 1MiB.
-			 */
-			if(addr >= 1*MiB || addr < 0x000A0000)
-				mapupainit(last, addr-last);
-		}
-		last = addr+len;
-	}
-
-	/*
-	changeconf("*noe820scan=1\n");
-	 */
-
-	if(MEMDEBUG)
-		memdebug();
-}
-
-uint32_t
-umbmalloc(uint32_t addr, int size, int align)
-{
-	uint32_t a;
-
-	if(a = mapalloc(&rmapumb, addr, size, align))
-		return (uint32_t)KADDR(a);
-
-	return 0;
-}
-
-void
-umbfree(uint32_t addr, int size)
-{
-	mapfree(&rmapumb, PADDR(addr), size);
-}
-
-uint32_t
-umbrwmalloc(uint32_t addr, int size, int align)
-{
-	uint32_t a;
-	uint8_t *p;
-
-	if(a = mapalloc(&rmapumbrw, addr, size, align))
-		return(uint32_t)KADDR(a);
-
-	/*
-	 * Perhaps the memory wasn't visible before
-	 * the interface is initialised, so try again.
-	 */
-	if((a = umbmalloc(addr, size, align)) == 0)
-		return 0;
-	p = (uint8_t*)a;
-	p[0] = 0xCC;
-	p[size-1] = 0xCC;
-	if(p[0] == 0xCC && p[size-1] == 0xCC)
-		return a;
-	umbfree(a, size);
-
-	return 0;
-}
-
-void
-umbrwfree(uint32_t addr, int size)
-{
-	mapfree(&rmapumbrw, PADDR(addr), size);
-}
-
-uint32_t*
-mmuwalk(uint32_t* pdb, uint32_t va, int level, int create)
-{
-	uint32_t pa, *table;
-
-	/*
-	 * Walk the page-table pointed to by pdb and return a pointer
-	 * to the entry for virtual address va at the requested level.
-	 * If the entry is invalid and create isn't requested then bail
-	 * out early. Otherwise, for the 2nd level walk, allocate a new
-	 * page-table page and register it in the 1st level.
-	 */
-	table = &pdb[PDX(va)];
-	if(!(*table & PTEVALID) && create == 0)
-		return 0;
-
-	switch(level){
-
-	default:
-		return 0;
-
-	case 1:
-		return table;
-
-	case 2:
-		if(*table & PTESIZE)
-			panic("mmuwalk2: va 0x%ux entry 0x%ux\n", va, *table);
-		if(!(*table & PTEVALID)){
-			pa = PADDR(ialloc(BY2PG, BY2PG));
-			*table = pa|PTEWRITE|PTEVALID;
-		}
-		table = KADDR(PPN(*table));
-
-		return &table[PTX(va)];
-	}
-}
-
-static Lock mmukmaplock;
-
-uint32_t
-mmukmap(uint32_t pa, uint32_t va, int size)
-{
-	uint32_t pae, *table, *pdb, pgsz, *pte, x;
-	int pse, sync;
-	extern int cpuidax, cpuiddx;
-
-	pdb = KADDR(getcr3());
-	if((cpuiddx & 0x08) && (getcr4() & 0x10))
-		pse = 1;
-	else
-		pse = 0;
-	sync = 0;
-
-	pa = PPN(pa);
-	if(va == 0)
-		va = (uint32_t)KADDR(pa);
-	else
-		va = PPN(va);
-
-	pae = pa + size;
-	lock(&mmukmaplock);
-	while(pa < pae){
-		table = &pdb[PDX(va)];
-		/*
-		 * Possibly already mapped.
-		 */
-		if(*table & PTEVALID){
-			if(*table & PTESIZE){
-				/*
-				 * Big page. Does it fit within?
-				 * If it does, adjust pgsz so the correct end can be
-				 * returned and get out.
-				 * If not, adjust pgsz up to the next 4MiB boundary
-				 * and continue.
-				 */
-				x = PPN(*table);
-				if(x != pa)
-					panic("mmukmap1: pa 0x%ux  entry 0x%ux\n",
-						pa, *table);
-				x += 4*MiB;
-				if(pae <= x){
-					pa = pae;
-					break;
-				}
-				pgsz = x - pa;
-				pa += pgsz;
-				va += pgsz;
-
-				continue;
-			}
-			else{
-				/*
-				 * Little page. Walk to the entry.
-				 * If the entry is valid, set pgsz and continue.
-				 * If not, make it so, set pgsz, sync and continue.
-				 */
-				pte = mmuwalk(pdb, va, 2, 0);
-				if(pte && *pte & PTEVALID){
-					x = PPN(*pte);
-					if(x != pa)
-						panic("mmukmap2: pa 0x%ux entry 0x%ux\n",
-							pa, *pte);
-					pgsz = BY2PG;
-					pa += pgsz;
-					va += pgsz;
-					sync++;
-
-					continue;
-				}
-			}
-		}
-
-		/*
-		 * Not mapped. Check if it can be mapped using a big page -
-		 * starts on a 4MiB boundary, size >= 4MiB and processor can do it.
-		 * If not a big page, walk the walk, talk the talk.
-		 * Sync is set.
-		 */
-		if(pse && (pa % (4*MiB)) == 0 && (pae >= pa+4*MiB)){
-			*table = pa|PTESIZE|PTEWRITE|PTEUNCACHED|PTEVALID;
-			pgsz = 4*MiB;
-		}
-		else{
-			pte = mmuwalk(pdb, va, 2, 1);
-			*pte = pa|PTEWRITE|PTEUNCACHED|PTEVALID;
-			pgsz = BY2PG;
-		}
-		pa += pgsz;
-		va += pgsz;
-		sync++;
-	}
-	unlock(&mmukmaplock);
-
-	/*
-	 * If something was added
-	 * then need to sync up.
-	 */
-	if(sync)
-		putcr3(PADDR(pdb));
-
-	return pa;
-}
-
-uint32_t
-upamalloc(uint32_t addr, int size, int align)
-{
-	uint32_t ae, a;
-
-	USED(align);
-
-	if((a = mapalloc(&rmapupa, addr, size, align)) == 0){
-		memdebug();
-		return 0;
-	}
-
-	/*
-	 * This is a travesty, but they all are.
-	 */
-	ae = mmukmap(a, 0, size);
-
-	/*
-	 * Should check here that it was all delivered
-	 * and put it back and barf if not.
-	 */
-	USED(ae);
-
-	/*
-	 * Be very careful this returns a PHYSICAL address.
-	 */
-	return a;
-}
-
-void
-upafree(uint32_t pa, int size)
-{
-	USED(pa, size);
-}
-
-void
-mapraminit(uint64_t addr, uint32_t size)
-{
-	uint32_t s;
-	uint64_t a;
-
-	/*
-	 * Careful - physical address.
-	 * Boot time only to populate map.
-	 */
-	a = PGROUND(addr);
-	s = a - addr;
-	if(s >= size)
-		return;
-	mapfree(&rmapram, a, size-s);
-}
-
-void
-mapupainit(uint64_t addr, uint32_t size)
-{
-	uint32_t s;
-	uint64_t a;
-
-	/*
-	 * Careful - physical address.
-	 * Boot time only to populate map.
-	 */
-	a = PGROUND(addr);
-	s = a - addr;
-	if(s >= size)
-		return;
-	mapfree(&rmapupa, a, size-s);
-}

+ 0 - 109
sys/src/9/w/pxeload/mkfile

@@ -1,109 +0,0 @@
-objtype=386					# sic
-</$objtype/mkfile
-BIN=/dev/null
-
-p=p
-EXT=load
-K=0
-L16=l16r
-
-TARG=\
-	${p}pxe${EXT}\
-	${p}pxe${EXT}acid\
-
-CORE=\
-	alarm.$O\
-	cga.$O\
-	clock.$O\
-	console.$O\
-	dosboot.$O\
-	devfloppy.$O\
-	dma.$O\
-	fs.$O\
-	ilock.$O\
-	kbd.$O\
-	print.$O\
-	queue.$O\
-	trap.$O\
-
-LOAD=\
-	apm.$O\
-	boot.$O\
-	conf.$O\
-	i8250.$O\
-	inflate.$O\
-	load.$O\
-	memory.$O\
-	multiboot.$O\
-	pci.$O\
-	warp64.$O\
-
-ETHER=\
-	bootp.$O\
-	ether.$O\
-	ether2114x.$O\
-	ether79c970.$O\
-	ether8139.$O\
-	ether8169.$O\
-	ether82557.$O\
-	ether82563.$O\
-	etherigbe.$O\
-	ethermii.$O\
-	etherbcm4401.$O\
-	ethervgbe.$O\
-
-HFILES=\
-	lib.h\
-	mem.h\
-	dat.h\
-	fns.h\
-	io.h\
-
-AFLAGS=-I.
-CFLAGS=-FTVw -I.
-
-all:V:	$TARG
-
-install:V:	$TARG
-	cp $TARG /$objtype
-	test -d /n/9/$objtype && cp $TARG /n/9/$objtype
-
-${p}${EXT}:	$L16.$O l32p.$O l32v.$O l64p.$O $CORE $LOAD $ETHER
-	$LD -o $target -H3 -T0x$K^0010000 -l $prereq -lflate -lc -lip
-	ls -l $target
-
-${p}${EXT}acid:	$L16.$O l32p.$O l32v.$O l64p.$O $CORE $LOAD $ETHER
-	$LD -o $target -T0x$K^0007c00 -l $prereq -lflate -lc -lip
-	ls -l $target
-	# acid $target
-	# map({"text", 0x$K^0007c00, 0x${K}0090000, 0x00000020})
-
-${p}pxe${EXT}:	$L16.$O l32p.$O lpxe.$O l64p.$O $CORE $LOAD $ETHER
-#	$LD -o $target -H3 -T0x$K^0007C00 -l $prereq -lflate -lc -lip
-	$LD -o $target -H3 -T0x$K^0007C00 -l $prereq -lflate -lc -lip
-	ls -l $target
-${p}pxe${EXT}acid:	$L16.$O l32p.$O lpxe.$O l64p.$O $CORE $LOAD $ETHER
-	$LD -o $target -T0x$K^0007c00 -l $prereq -lflate -lc -lip
-	ls -l $target
-	# acid $target
-	# map({"text", 0x${K}0007c00, 0x${K}0090000, 0x00000020})
-
-lpxe.$O: l32v.s
-	$AS $AFLAGS -DPXE -o $target l32v.s
-
-%.$O:	%.s
-	$AS $AFLAGS $stem.s
-
-%.$O:	%.c
-	$CC $CFLAGS $stem.c
-
-%.$O:	$HFILES
-
-l.$O:	x16.h
-
-clock.$O floppy.$O trap.$O:	ureg.h
-ether.$O:	etherif.h
-bootp.$O:	ip.h
-
-clean:
-	rm -f *.[$OS] [$OS].out y.tab.? y.debug y.output $TARG

+ 0 - 80
sys/src/9/w/pxeload/mmu64.h

@@ -1,80 +0,0 @@
-/* 
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
-
-enum {						/* MSRs */
-	Efer		= 0xC0000080,		/* Extended Feature Enable */
-};
-
-enum {						/* Cr0 */
-	Pe		= 0x00000001,		/* Protected Mode Enable */
-	Mp		= 0x00000002,		/* Monitor Coprocessor */
-	Em		= 0x00000004,		/* Emulate Coprocessor */
-	Ts		= 0x00000008,		/* Task Switched */
-	Et		= 0x00000010,		/* Extension Type */
-	Ne		= 0x00000020,		/* Numeric Error  */
-	Wp		= 0x00010000,		/* Write Protect */
-	Am		= 0x00040000,		/* Alignment Mask */
-	Nw		= 0x20000000,		/* Not Writethrough */
-	Cd		= 0x40000000,		/* Cache Disable */
-	Pg		= 0x80000000,		/* Paging Enable */
-};
-
-enum {						/* Cr3 */
-	Pwt		= 0x00000008,		/* Page-Level Writethrough */
-	Pcd		= 0x00000010,		/* Page-Level Cache Disable */
-};
-
-enum {						/* Cr4 */
-	Vme		= 0x00000001,		/* Virtual-8086 Mode Extensions */
-	Pvi		= 0x00000002,		/* Protected Mode Virtual Interrupts */
-	//Tsd		= 0x00000004,		/* Time-Stamp Disable */
-	De		= 0x00000008,		/* Debugging Extensions */
-	Pse		= 0x00000010,		/* Page-Size Extensions */
-	Pae		= 0x00000020,		/* Physical Address Extension */
-	Mce		= 0x00000040,		/* Machine Check Enable */
-	Pge		= 0x00000080,		/* Page-Global Enable */
-	Pce		= 0x00000100,		/* Performance Monitoring Counter Enable */
-	Osfxsr		= 0x00000200,		/* FXSAVE/FXRSTOR Support */
-	Osxmmexcpt	= 0x00000400,		/* Unmasked Exception Support */
-};
-
-enum {						/* Efer */
-	Sce		= 0x00000001,		/* System Call Extension */
-	Lme		= 0x00000100,		/* Long Mode Enable */
-	Lma		= 0x00000400,		/* Long Mode Active */
-	Nxe		= 0x00000800,		/* No-Execute Enable */
-	Ffxsr		= 0x00004000,		/* Fast FXSAVE/FXRSTOR */
-};
-
-enum {						/* Pte */
-	PteP		= 0x0000000000000001ULL,/* Present */
-	PteRW		= 0x0000000000000002ULL,/* Read/Write */
-	PteUS		= 0x0000000000000004ULL,/* User/Supervisor */
-	PtePWT		= 0x0000000000000008ULL,/* Page-Level Write Through */
-	PtePCD		= 0x0000000000000010ULL,/* Page Level Cache Disable */
-	PteA		= 0x0000000000000020ULL,/* Accessed */
-	PteD		= 0x0000000000000040ULL,/* Dirty */
-	PtePS		= 0x0000000000000080ULL,/* Page Size */
-	PtePAT0		= PtePS,		/* Level 0 PAT */
-	PteG		= 0x0000000000000100ULL,/* Global */
-	PtePAT1		= 0x0000000000000800ULL,/* Level 1 PAT */
-	PteNX		= 0x8000000000000000ULL,/* No Execute */
-};
-
-typedef u64int PTE;
-
-#define KZERO64		0xFFFFFFFF80000000ULL
-
-#define PGSIZE64	4096
-#define PGSHIFT64	12			/* log(PGSIZE) */
-#define PTESIZE64	512
-#define PTESHIFT64	9			/* log(PTESIZE) */
-
-#define PTEX64(pi, l)	(((pi)>>((((l)-1)*9)+12)) & ((1<<PTESHIFT64)-1))
-#define PPN64(pi)	((pi) & ~((1<<PTESHIFT64)-1))

+ 0 - 34
sys/src/9/w/pxeload/multiboot.c

@@ -1,34 +0,0 @@
-/*
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
-
-#include "u.h"
-#include "lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-
-MMap mmap[20];
-int nmmap;
-
-Mbi multibootheader;
-
-void
-mkmultiboot(void)
-{
-	if(nmmap != 0){
-		multibootheader.cmdline = PADDR(BOOTLINE);
-		multibootheader.flags |= Fcmdline;
-		multibootheader.mmapaddr = PADDR(mmap);
-		multibootheader.mmaplength = nmmap*sizeof(MMap);
-		multibootheader.flags |= Fmmap;
-		if(vflag)
-			print("&multibootheader %#p\n", &multibootheader);
-	}
-}

+ 0 - 354
sys/src/9/w/pxeload/part.c

@@ -1,354 +0,0 @@
-/*
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
-
-#include	"u.h"
-#include	"lib.h"
-#include	"mem.h"
-#include	"dat.h"
-#include	"fns.h"
-
-#include	"sd.h"
-#include	"fs.h"
-
-enum {
-	Npart = 32
-};
-
-uint8_t *mbrbuf, *partbuf;
-int nbuf;
-#define trace 0
-
-int
-tsdbio(SDunit *unit, SDpart *part, void *a, int64_t off, int mbr)
-{
-	uint8_t *b;
-
-	if(sdbio(unit, part, a, unit->secsize, off) != unit->secsize){
-		if(trace)
-			print("%s: read %lud at %lld failed\n", unit->name,
-				unit->secsize,
-			      (int64_t)part->start*unit->secsize+off);
-		return -1;
-	}
-	b = a;
-	if(mbr && (b[0x1FE] != 0x55 || b[0x1FF] != 0xAA)){
-		if(trace)
-			print("%s: bad magic %.2ux %.2ux at %lld\n",
-				unit->name, b[0x1FE], b[0x1FF],
-				(int64_t)part->start*unit->secsize+off);
-		return -1;
-	}
-	return 0;
-}
-
-/*
- *  read partition table.  The partition table is just ascii strings.
- */
-#define MAGIC "plan9 partitions"
-static void
-oldp9part(SDunit *unit)
-{
-	SDpart *pp;
-	char *field[3], *line[Npart+1];
-	uint32_t n, start, end;
-	int i;
-
-	/*
-	 *  We have some partitions already.
-	 */
-	pp = &unit->part[unit->npart];
-
-	/*
-	 * We prefer partition tables on the second to last sector,
-	 * but some old disks use the last sector instead.
-	 */
-	strcpy(pp->name, "partition");
-	pp->start = unit->sectors - 2;
-	pp->end = unit->sectors - 1;
-
-	if(tsdbio(unit, pp, partbuf, 0, 0) < 0)
-		return;
-
-	if(strncmp((char*)partbuf, MAGIC, sizeof(MAGIC)-1) != 0) {
-		/* not found on 2nd last sector; look on last sector */
-		pp->start++;
-		pp->end++;
-		if(tsdbio(unit, pp, partbuf, 0, 0) < 0)
-			return;
-		if(strncmp((char*)partbuf, MAGIC, sizeof(MAGIC)-1) != 0)
-			return;
-		print("%s: using old plan9 partition table on last sector\n", unit->name);
-	}else
-		print("%s: using old plan9 partition table on 2nd-to-last sector\n", unit->name);
-
-	/* we found a partition table, so add a partition partition */
-	unit->npart++;
-	partbuf[unit->secsize-1] = '\0';
-
-	/*
-	 * parse partition table
-	 */
-	n = getfields((char*)partbuf, line, Npart+1, '\n');
-	if(n && strncmp(line[0], MAGIC, sizeof(MAGIC)-1) == 0){
-		for(i = 1; i < n && unit->npart < SDnpart; i++){
-			if(getfields(line[i], field, 3, ' ') != 3)
-				break;
-			start = strtoul(field[1], 0, 0);
-			end = strtoul(field[2], 0, 0);
-			if(start >= end || end > unit->sectors)
-				break;
-			sdaddpart(unit, field[0], start, end);
-		}
-	}
-}
-
-static void
-p9part(SDunit *unit, char *name)
-{
-	SDpart *p;
-	char *field[4], *line[Npart+1];
-	uint32_t start, end;
-	int i, n;
-
-	p = sdfindpart(unit, name);
-	if(p == nil)
-		return;
-
-	if(tsdbio(unit, p, partbuf, unit->secsize, 0) < 0)
-		return;
-	partbuf[unit->secsize-1] = '\0';
-
-	if(strncmp((char*)partbuf, "part ", 5) != 0)
-		return;
-
-	n = getfields((char*)partbuf, line, Npart+1, '\n');
-	if(n == 0)
-		return;
-	for(i = 0; i < n && unit->npart < SDnpart; i++){
-		if(strncmp(line[i], "part ", 5) != 0)
-			break;
-		if(getfields(line[i], field, 4, ' ') != 4)
-			break;
-		start = strtoul(field[2], 0, 0);
-		end = strtoul(field[3], 0, 0);
-		if(start >= end || end > unit->sectors)
-			break;
-		sdaddpart(unit, field[1], p->start+start, p->start+end);
-	}
-}
-
-int
-isdos(int t)
-{
-	return t==FAT12 || t==FAT16 || t==FATHUGE || t==FAT32 || t==FAT32X;
-}
-
-int
-isextend(int t)
-{
-	return t==EXTEND || t==EXTHUGE || t==LEXTEND;
-}
-
-/*
- * Fetch the first dos and all plan9 partitions out of the MBR partition table.
- * We return -1 if we did not find a plan9 partition.
- */
-static int
-mbrpart(SDunit *unit)
-{
-	Dospart *dp;
-	uint32_t taboffset, start, end;
-	uint32_t firstxpart, nxtxpart;
-	int havedos, i, nplan9;
-	char name[10];
-
-	taboffset = 0;
-	dp = (Dospart*)&mbrbuf[0x1BE];
-	if(1) {
-		/* get the MBR (allowing for DMDDO) */
-		if(tsdbio(unit, &unit->part[0], mbrbuf, (int64_t)taboffset*unit->secsize, 1) < 0)
-			return -1;
-		for(i=0; i<4; i++)
-			if(dp[i].type == DMDDO) {
-				if(trace)
-					print("DMDDO partition found\n");
-				taboffset = 63;
-				if(tsdbio(unit, &unit->part[0], mbrbuf, (int64_t)taboffset*unit->secsize, 1) < 0)
-					return -1;
-				i = -1;	/* start over */
-			}
-	}
-
-	/*
-	 * Read the partitions, first from the MBR and then
-	 * from successive extended partition tables.
-	 */
-	nplan9 = 0;
-	havedos = 0;
-	firstxpart = 0;
-	for(;;) {
-		if(tsdbio(unit, &unit->part[0], mbrbuf, (int64_t)taboffset*unit->secsize, 1) < 0)
-			return -1;
-		if(trace) {
-			if(firstxpart)
-				print("%s ext %lud ", unit->name, taboffset);
-			else
-				print("%s mbr ", unit->name);
-		}
-		nxtxpart = 0;
-		for(i=0; i<4; i++) {
-			if(trace)
-				print("dp %d...", dp[i].type);
-			start = taboffset+GLONG(dp[i].start);
-			end = start+GLONG(dp[i].len);
-
-			if(dp[i].type == PLAN9) {
-				if(nplan9 == 0)
-					strcpy(name, "plan9");
-				else
-					sprint(name, "plan9.%d", nplan9);
-				sdaddpart(unit, name, start, end);
-				p9part(unit, name);
-				nplan9++;
-			}
-
-			/*
-			 * We used to take the active partition (and then the first
-			 * when none are active).  We have to take the first here,
-			 * so that the partition we call ``dos'' agrees with the
-			 * partition disk/fdisk calls ``dos''.
-			 */
-			if(havedos==0 && isdos(dp[i].type)){
-				havedos = 1;
-				sdaddpart(unit, "dos", start, end);
-			}
-
-			/* nxtxpart is relative to firstxpart (or 0), not taboffset */
-			if(isextend(dp[i].type)){
-				nxtxpart = start-taboffset+firstxpart;
-				if(trace)
-					print("link %lud...", nxtxpart);
-			}
-		}
-		if(trace)
-			print("\n");
-
-		if(!nxtxpart)
-			break;
-		if(!firstxpart)
-			firstxpart = nxtxpart;
-		taboffset = nxtxpart;
-	}
-	return nplan9 ? 0 : -1;
-}
-
-/*
- * To facilitate booting from CDs, we create a partition for
- * the boot floppy image embedded in a bootable CD.
- */
-static int
-part9660(SDunit *unit)
-{
-	uint8_t buf[2048];
-	uint32_t a, n;
-	uint8_t *p;
-
-	if(unit->secsize != 2048)
-		return -1;
-
-	if(sdbio(unit, &unit->part[0], buf, 2048, 17*2048) < 0)
-		return -1;
-
-	if(buf[0] || strcmp((char*)buf+1, "CD001\x01EL TORITO SPECIFICATION") != 0)
-		return -1;
-
-
-	p = buf+0x47;
-	a = p[0] | (p[1]<<8) | (p[2]<<16) | (p[3]<<24);
-
-	if(sdbio(unit, &unit->part[0], buf, 2048, a*2048) < 0)
-		return -1;
-
-	if(memcmp(buf, "\x01\x00\x00\x00", 4) != 0
-	|| memcmp(buf+30, "\x55\xAA", 2) != 0
-	|| buf[0x20] != 0x88)
-		return -1;
-
-	p = buf+0x28;
-	a = p[0] | (p[1]<<8) | (p[2]<<16) | (p[3]<<24);
-
-	switch(buf[0x21]){
-	case 0x01:
-		n = 1200*1024;
-		break;
-	case 0x02:
-		n = 1440*1024;
-		break;
-	case 0x03:
-		n = 2880*1024;
-		break;
-	default:
-		return -1;
-	}
-	n /= 2048;
-
-	print("found partition %s!cdboot; %lud+%lud\n", unit->name, a, n);
-	sdaddpart(unit, "cdboot", a, a+n);
-	return 0;
-}
-
-enum {
-	NEW = 1<<0,
-	OLD = 1<<1
-};
-
-void
-partition(SDunit *unit)
-{
-	int type;
-	char *p;
-
-	if(unit->part == 0)
-		return;
-
-	if(part9660(unit) == 0)
-		return;
-
-	p = getconf("partition");
-	if(p == nil)
-		p = defaultpartition;
-
-	if(p != nil && strncmp(p, "new", 3) == 0)
-		type = NEW;
-	else if(p != nil && strncmp(p, "old", 3) == 0)
-		type = OLD;
-	else
-		type = NEW|OLD;
-
-	if(nbuf < unit->secsize) {
-		free(mbrbuf);
-		free(partbuf);
-		mbrbuf = malloc(unit->secsize);
-		partbuf = malloc(unit->secsize);
-		if(mbrbuf==nil || partbuf==nil) {
-			free(mbrbuf);
-			free(partbuf);
-			partbuf = mbrbuf = nil;
-			nbuf = 0;
-			return;
-		}
-		nbuf = unit->secsize;
-	}
-
-	if((type & NEW) && mbrpart(unit) >= 0){
-		/* nothing to do */;
-	}
-	else if(type & OLD)
-		oldp9part(unit);
-}

+ 0 - 372
sys/src/9/w/pxeload/pbs.s

@@ -1,372 +0,0 @@
-/*
- * FAT Partition Boot Sector. Loaded at 0x7C00:
- *	8a pbs.s; 8l -o pbs -l -H3 -T0x7C00 pbs.8
- * Will load the target at LOADSEG*16+LOADOFF, so the target
- * should be probably be loaded with LOADOFF added to the
- * -Taddress.
- * If LOADSEG is a multiple of 64KB and LOADOFF is 0 then
- * targets larger than 64KB can be loaded.
- *
- * This code uses the traditional INT13 BIOS interface and can
- * therefore only access the first 8.4GB of the disc.
- *
- * It relies on the _volid field in the FAT header containing
- * the LBA of the root directory.
- */
-#include "x16.h"
-#include "mem.h"
-
-#define LOADSEG		(0x10000/16)	/* where to load code (64KB) */
-#define LOADOFF		0
-#define DIROFF		0x0200		/* where to read the root directory */
-
-/*
- * FAT directory entry.
- */
-#define Dname		0x00
-#define Dext		0x08
-#define Dattr		0x0B
-#define Dtime		0x16
-#define Ddate		0x18
-#define Dstart		0x1A
-#define Dlengthlo	0x1C
-#define Dlengthhi	0x1E
-
-#define Dirsz		0x20
-
-/*
- * Data is kept on the stack, indexed by rBP.
- */
-#define Xdap		0x00		/* disc address packet */
-#define Xrootsz		0x10		/* file data area */
-#define Xdrive		0x12		/* boot drive, passed by BIOS or MBR */
-#define Xtotal		0x14		/* sum of allocated data above */
-
-TEXT _magic(SB), $0
-	BYTE $0xEB; BYTE $0x3C;		/* jmp .+ 0x3C  (_start0x3E) */
-	BYTE $0x90			/* nop */
-TEXT _version(SB), $0
-	BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00;
-	BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00
-TEXT _sectsize(SB), $0
-	BYTE $0x00; BYTE $0x00
-TEXT _clustsize(SB), $0
-	BYTE $0x00
-TEXT _nresrv(SB), $0
-	BYTE $0x00; BYTE $0x00
-TEXT _nfats(SB), $0
-	BYTE $0x00
-TEXT _rootsize(SB), $0
-	BYTE $0x00; BYTE $0x00
-TEXT _volsize(SB), $0
-	BYTE $0x00; BYTE $0x00
-TEXT _mediadesc(SB), $0
-	BYTE $0x00
-TEXT _fatsize(SB), $0
-	BYTE $0x00; BYTE $0x00
-TEXT _trksize(SB), $0
-	BYTE $0x00; BYTE $0x00
-TEXT _nheads(SB), $0
-	BYTE $0x00; BYTE $0x00
-TEXT _nhiddenlo(SB), $0
-	BYTE $0x00; BYTE $0x00
-TEXT _nhiddenhi(SB), $0
-	BYTE $0x00; BYTE $0x00;
-TEXT _bigvolsize(SB), $0
-	BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00;
-TEXT _driveno(SB), $0
-	BYTE $0x00
-TEXT _reserved0(SB), $0
-	BYTE $0x00
-TEXT _bootsig(SB), $0
-	BYTE $0x00
-TEXT _volid(SB), $0
-	BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00;
-TEXT _label(SB), $0
-	BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00;
-	BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00
-	BYTE $0x00; BYTE $0x00; BYTE $0x00
-TEXT _type(SB), $0
-	BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00;
-	BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00;
-
-_start0x3E:
-	CLI
-	CLR(rAX)
-	MTSR(rAX, rSS)			/* 0000 -> rSS */
-	MTSR(rAX, rDS)			/* 0000 -> rDS, source segment */
-	MTSR(rAX, rES)
-	LWI(_magic-Xtotal(SB), rSP)
-	MW(rSP, rBP)			/* set the indexed-data pointer */
-
-	SBPB(rDL, Xdrive)		/* save the boot drive */
-
-	/* booting from a CD starts us at 7C0:0.  Move to 0:7C00 */
-	PUSHR(rAX)
-	LWI(_nxt(SB), rAX)
-	PUSHR(rAX)
-	BYTE $0xCB	/* FAR RET */
-
-TEXT _nxt(SB), $0
-	STI
-
-	LWI(confidence(SB), rSI)	/* for that warm, fuzzy feeling */
-	CALL16(BIOSputs(SB))
-
-	CALL16(dreset(SB))
-
-_jmp00:
-	LW(_volid(SB), rAX)		/* Xrootlo */
-	LW(_volid+2(SB), rDX)		/* Xroothi */
-
-	LWI(_magic+DIROFF(SB), rBX)
-	CALL16(BIOSread(SB))		/* read the root directory */
-
-	LWI((512/Dirsz), rBX)
-
-	LWI(_magic+DIROFF(SB), rDI)	/* compare first directory entry */
-
-_cmp00:
-	PUSHR(rDI)			/* save for later if it matches */
-	LWI(bootfile(SB), rSI)
-	LWI(Dattr, rCX)
-	REP
-	CMPSB
-	POPR(rDI)
-	JEQ _jmp02
-
-	DEC(rBX)
-	JEQ _jmp01
-
-	ADDI(Dirsz, rDI)
-	JMP _cmp00
-_jmp01:
-	CALL16(buggery(SB))
-
-_jmp02:
-	CLR(rBX)			/* a handy value */
-	LW(_rootsize(SB), rAX)		/* calculate and save Xrootsz */
-	LWI(Dirsz, rCX)
-	MUL(rCX)
-	LW(_sectsize(SB), rCX)
-	PUSHR(rCX)
-	DEC(rCX)
-	ADD(rCX, rAX)
-	ADC(rBX, rDX)
-	POPR(rCX)			/* _sectsize(SB) */
-	DIV(rCX)
-	PUSHR(rAX)			/* Xrootsz */
-
-	/*
-	 * rDI points to the matching directory entry.
-	 */
-	LXW(Dstart, xDI, rAX)		/* starting sector address */
-	DEC(rAX)			/* that's just the way it is */
-	DEC(rAX)
-	LB(_clustsize(SB), rCL)
-	CLRB(rCH)
-	MUL(rCX)
-	LW(_volid(SB), rCX)		/* Xrootlo */
-	ADD(rCX, rAX)
-	LW(_volid+2(SB), rCX)		/* Xroothi */
-	ADC(rCX, rDX)
-	POPR(rCX)			/* Xrootsz */
-	ADD(rCX, rAX)
-	ADC(rBX, rDX)
-
-	PUSHR(rAX)			/* calculate how many sectors to read */
-	PUSHR(rDX)
-	LXW(Dlengthlo, xDI, rAX)
-	LXW(Dlengthhi, xDI, rDX)
-	LW(_sectsize(SB), rCX)
-	PUSHR(rCX)
-	DEC(rCX)
-	ADD(rCX, rAX)
-	ADC(rBX, rDX)
-	POPR(rCX)			/* _sectsize(SB) */
-	DIV(rCX)
-	MW(rAX, rCX)
-	POPR(rDX)
-	POPR(rAX)
-
-	LWI(LOADSEG, rBX)		/* address to load into (seg+offset) */
-	MTSR(rBX, rES)			/*  seg */
-	LWI(LOADOFF, rBX)		/*  offset */
-
-_readboot:
-	CALL16(BIOSread(SB))		/* read the sector */
-
-	LW(_sectsize(SB), rDI)		/* bump addresses/counts */
-	ADD(rDI, rBX)
-	JCC _incsecno
-
-	MFSR(rES, rDI)			/* next 64KB segment */
-	ADDI(0x1000, rDI)
-	MTSR(rDI, rES)
-
-_incsecno:
-	CLR(rDI)
-	INC(rAX)
-	ADC(rDI, rDX)
-	LOOP _readboot
-
-	LWI(LOADSEG, rDI)		/* set rDS for loaded code */
-	MTSR(rDI, rDS)
-	FARJUMP16(LOADSEG, LOADOFF)	/* no deposit, no return */
-
-TEXT buggery(SB), $0
-	LWI(error(SB), rSI)
-	CALL16(BIOSputs(SB))
-
-_wait:
-	CLR(rAX)			/* wait for almost any key */
-	BIOSCALL(0x16)
-
-_reset:
-	CLR(rBX)			/* set ES segment for BIOS area */
-	MTSR(rBX, rES)
-
-	LWI(0x0472, rBX)		/* warm-start code address */
-	LWI(0x1234, rAX)		/* warm-start code */
-	POKEW				/* MOVW	AX, ES:[BX] */
-
-	FARJUMP16(0xFFFF, 0x0000)	/* reset */
-
-/*
- * Read a sector from a disc. On entry:
- *   rDX:rAX	sector number
- *   rES:rBX	buffer address
- * For BIOSCALL(0x13):
- *   rAH	0x02
- *   rAL	number of sectors to read (1)
- *   rCH	low 8 bits of cylinder
- *   rCL	high 2 bits of cylinder (7-6), sector (5-0)
- *   rDH	head
- *   rDL	drive
- *   rES:rBX	buffer address
- */
-TEXT BIOSread(SB), $0
-	LWI(5, rDI)			/* retry count (ATAPI ZIPs suck) */
-_retry:
-	PUSHA				/* may be trashed by BIOSCALL */
-	PUSHR(rBX)
-
-	LW(_trksize(SB), rBX)
-	LW(_nheads(SB), rDI)
-	IMUL(rDI, rBX)
-	OR(rBX, rBX)
-	JZ _ioerror
-
-_okay:
-	DIV(rBX)			/* cylinder -> rAX, track,sector -> rDX */
-
-	MW(rAX, rCX)			/* save cylinder */
-	ROLI(0x08, rCX)			/* swap rC[HL] */
-	SHLBI(0x06, rCL)		/* move high bits up */
-
-	MW(rDX, rAX)
-	CLR(rDX)
-	LW(_trksize(SB), rBX)
-
-	DIV(rBX)			/* head -> rAX, sector -> rDX */
-
-	INC(rDX)			/* sector numbers are 1-based */
-	ANDI(0x003F, rDX)		/* should not be necessary */
-	OR(rDX, rCX)
-
-	MW(rAX, rDX)
-	SHLI(0x08, rDX)			/* form head */
-	LBPB(Xdrive, rDL)		/* form drive */
-
-	POPR(rBX)
-	LWI(0x0201, rAX)		/* form command and sectors */
-	BIOSCALL(0x13)			/* CF set on failure */
-	JCC _BIOSreadret
-
-	POPA
-	DEC(rDI)			/* too many retries? */
-	JEQ _ioerror
-
-	CALL16(dreset(SB))
-	JMP _retry
-
-_ioerror:
-	LWI(ioerror(SB), rSI)
-	CALL16(BIOSputs(SB))
-	JMP _wait
-
-_BIOSreadret:
-	POPA
-	RET
-
-TEXT dreset(SB), $0
-	PUSHA
-	CLR(rAX)			/* rAH == 0 == reset disc system */
-	LBPB(Xdrive, rDL)
-	BIOSCALL(0x13)
-	ORB(rAH, rAH)			/* status (0 == success) */
-	POPA
-	JNE _ioerror
-	RET
-
-/*
- * Output a string to the display.
- * String argument is in rSI.
- */
-TEXT BIOSputs(SB), $0
-	PUSHA
-	CLR(rBX)
-_BIOSputs:
-	LODSB
-	ORB(rAL, rAL)
-	JEQ _BIOSputsret
-
-	LBI(0x0E, rAH)
-	BIOSCALL(0x10)
-	JMP _BIOSputs
-
-_BIOSputsret:
-	POPA
-	RET
-
-/* "Bad format or I/O error\r\nPress almost any key to reboot..."*/
-TEXT error(SB), $0
-	BYTE $'B'; BYTE $'a'; BYTE $'d'; BYTE $' ';
-	BYTE $'f'; BYTE $'o'; BYTE $'r'; BYTE $'m';
-	BYTE $'a'; BYTE $'t'; BYTE $' '; BYTE $'o';
-	BYTE $'r'; BYTE $' ';
-/* "I/O error\r\nPress almost any key to reboot..." */
-TEXT ioerror(SB), $0
-	BYTE $'I'; BYTE $'/'; BYTE $'O'; BYTE $' ';
-	BYTE $'e'; BYTE $'r'; BYTE $'r'; BYTE $'o';
-	BYTE $'r'; BYTE $'\r';BYTE $'\n';
-	BYTE $'P'; BYTE $'r'; BYTE $'e'; BYTE $'s';
-	BYTE $'s'; BYTE $' '; BYTE $'a'; BYTE $' ';
-	BYTE $'k'; BYTE $'e'; BYTE $'y';
-	BYTE $' '; BYTE $'t'; BYTE $'o'; BYTE $' ';
-	BYTE $'r'; BYTE $'e'; BYTE $'b'; BYTE $'o';
-	BYTE $'o'; BYTE $'t';
-	BYTE $'.'; BYTE $'.'; BYTE $'.';
-	BYTE $'\z';
-
-#ifdef USEBCOM
-/* "B       COM" */
-TEXT bootfile(SB), $0
-	BYTE $'B'; BYTE $' '; BYTE $' '; BYTE $' ';
-	BYTE $' '; BYTE $' '; BYTE $' '; BYTE $' ';
-	BYTE $'C'; BYTE $'O'; BYTE $'M';
-	BYTE $'\z';
-#else
-/* "9LOAD      " */
-TEXT bootfile(SB), $0
-	BYTE $'9'; BYTE $'L'; BYTE $'O'; BYTE $'A';
-	BYTE $'D'; BYTE $' '; BYTE $' '; BYTE $' ';
-	BYTE $' '; BYTE $' '; BYTE $' ';
-	BYTE $'\z';
-#endif /* USEBCOM */
-
-/* "PBS..." */
-TEXT confidence(SB), $0
-	BYTE $'P'; BYTE $'B'; BYTE $'S'; BYTE $'1';
-	BYTE $'.'; BYTE $'.'; BYTE $'.';
-	BYTE $'\z';

+ 0 - 362
sys/src/9/w/pxeload/pbslba.s

@@ -1,362 +0,0 @@
-/*
- * FAT Partition Boot Sector. Loaded at 0x7C00:
- *	8a pbslba.s; 8l -o pbslba -l -H3 -T0x7C00 pbslba.8
- * Will load the target at LOADSEG*16+LOADOFF, so the target
- * should be probably be loaded with LOADOFF added to the
- * -Taddress.
- * If LOADSEG is a multiple of 64KB and LOADOFF is 0 then
- * targets larger than 64KB can be loaded.
- *
- * This code is uses Enhanced BIOS Services for Disc Drives and
- * can be used with discs up to 137GB in capacity.
- *
- * It relies on the _volid field in the FAT header containing
- * the LBA of the root directory.
- */
-#include "x16.h"
-#include "mem.h"
-
-#define LOADSEG		(0x10000/16)	/* where to load code (64KB) */
-#define LOADOFF		0
-#define DIROFF		0x0200		/* where to read the root directory */
-
-/*
- * FAT directory entry.
- */
-#define Dname		0x00
-#define Dext		0x08
-#define Dattr		0x0B
-#define Dtime		0x16
-#define Ddate		0x18
-#define Dstart		0x1A
-#define Dlengthlo	0x1C
-#define Dlengthhi	0x1E
-
-#define Dirsz		0x20
-
-/*
- * Data is kept on the stack, indexed by rBP.
- */
-#define Xdap		0x00		/* disc address packet */
-#define Xrootsz		0x10		/* file data area */
-#define Xdrive		0x12		/* boot drive, passed by BIOS or MBR */
-#define Xtotal		0x14		/* sum of allocated data above */
-
-TEXT _magic(SB), $0
-	BYTE $0xEB; BYTE $0x3C;		/* jmp .+ 0x3C  (_start0x3E) */
-	BYTE $0x90			/* nop */
-TEXT _version(SB), $0
-	BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00;
-	BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00
-TEXT _sectsize(SB), $0
-	BYTE $0x00; BYTE $0x00
-TEXT _clustsize(SB), $0
-	BYTE $0x00
-TEXT _nresrv(SB), $0
-	BYTE $0x00; BYTE $0x00
-TEXT _nfats(SB), $0
-	BYTE $0x00
-TEXT _rootsize(SB), $0
-	BYTE $0x00; BYTE $0x00
-TEXT _volsize(SB), $0
-	BYTE $0x00; BYTE $0x00
-TEXT _mediadesc(SB), $0
-	BYTE $0x00
-TEXT _fatsize(SB), $0
-	BYTE $0x00; BYTE $0x00
-TEXT _trksize(SB), $0
-	BYTE $0x00; BYTE $0x00
-TEXT _nheads(SB), $0
-	BYTE $0x00; BYTE $0x00
-TEXT _nhiddenlo(SB), $0
-	BYTE $0x00; BYTE $0x00
-TEXT _nhiddenhi(SB), $0
-	BYTE $0x00; BYTE $0x00;
-TEXT _bigvolsize(SB), $0
-	BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00;
-TEXT _driveno(SB), $0
-	BYTE $0x00
-TEXT _reserved0(SB), $0
-	BYTE $0x00
-TEXT _bootsig(SB), $0
-	BYTE $0x00
-TEXT _volid(SB), $0
-	BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00;
-TEXT _label(SB), $0
-	BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00;
-	BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00
-	BYTE $0x00; BYTE $0x00; BYTE $0x00
-TEXT _type(SB), $0
-	BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00;
-	BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00;
-
-_start0x3E:
-	CLI
-	CLR(rAX)
-	MTSR(rAX, rSS)			/* 0000 -> rSS */
-	MTSR(rAX, rDS)			/* 0000 -> rDS, source segment */
-	MTSR(rAX, rES)
-	LWI(_magic-Xtotal(SB), rSP)
-	MW(rSP, rBP)			/* set the indexed-data pointer */
-
-	SBPB(rDL, Xdrive)		/* save the boot drive */
-
-	/* booting from a CD starts us at 7C0:0.  Move to 0:7C00 */
-	PUSHR(rAX)
-	LWI(_nxt(SB), rAX)
-	PUSHR(rAX)
-	BYTE $0xCB	/* FAR RET */
-
-TEXT _nxt(SB), $0
-	STI
-
-	LWI(confidence(SB), rSI)	/* for that warm, fuzzy feeling */
-	CALL16(BIOSputs(SB))
-
-	LBI(0x41, rAH)			/* check extensions present */
-	LWI(0x55AA, rBX)
-	LXB(Xdrive, xBP, rDL)		/* drive */
-	BIOSCALL(0x13)			/* CF set on failure */
-	JCS _jmp01
-	CMPI(0xAA55, rBX)
-	JNE _jmp01
-	ANDI(0x0001, rCX)
-	JEQ _jmp01
-
-					/* rCX contains 0x0001 */
-	SBPWI(0x0010, Xdap+0)		/* reserved + packet size */
-	SBPWI(rCX, Xdap+2)		/* reserved + # of blocks to transfer */
-
-	DEC(rCX)
-	SBPW(rCX, Xdap+12)
-	SBPW(rCX, Xdap+14)
-
-	CALL16(dreset(SB))
-
-_jmp00:
-	LW(_volid(SB), rAX)		/* Xrootlo */
-	LW(_volid+2(SB), rDX)		/* Xroothi */
-
-	LWI(_magic+DIROFF(SB), rBX)
-	CALL16(BIOSread(SB))		/* read the root directory */
-
-	LWI((512/Dirsz), rBX)
-
-	LWI(_magic+DIROFF(SB), rDI)	/* compare first directory entry */
-
-_cmp00:
-	PUSHR(rDI)			/* save for later if it matches */
-	LWI(bootfile(SB), rSI)
-	LWI(Dattr, rCX)
-	REP
-	CMPSB
-	POPR(rDI)
-	JEQ _jmp02
-
-	DEC(rBX)
-	JEQ _jmp01
-
-	ADDI(Dirsz, rDI)
-	JMP _cmp00
-_jmp01:
-	CALL16(buggery(SB))
-
-_jmp02:
-	CLR(rBX)			/* a handy value */
-	LW(_rootsize(SB), rAX)		/* calculate and save Xrootsz */
-	LWI(Dirsz, rCX)
-	MUL(rCX)
-	LW(_sectsize(SB), rCX)
-	PUSHR(rCX)
-	DEC(rCX)
-	ADD(rCX, rAX)
-	ADC(rBX, rDX)
-	POPR(rCX)			/* _sectsize(SB) */
-	DIV(rCX)
-	PUSHR(rAX)			/* Xrootsz */
-
-	/*
-	 * rDI points to the matching directory entry.
-	 */
-	LXW(Dstart, xDI, rAX)		/* starting sector address */
-	DEC(rAX)			/* that's just the way it is */
-	DEC(rAX)
-	LB(_clustsize(SB), rCL)
-	CLRB(rCH)
-	MUL(rCX)
-	LW(_volid(SB), rCX)		/* Xrootlo */
-	ADD(rCX, rAX)
-	LW(_volid+2(SB), rCX)		/* Xroothi */
-	ADC(rCX, rDX)
-	POPR(rCX)			/* Xrootsz */
-	ADD(rCX, rAX)
-	ADC(rBX, rDX)
-
-	PUSHR(rAX)			/* calculate how many sectors to read */
-	PUSHR(rDX)
-	LXW(Dlengthlo, xDI, rAX)
-	LXW(Dlengthhi, xDI, rDX)
-	LW(_sectsize(SB), rCX)
-	PUSHR(rCX)
-	DEC(rCX)
-	ADD(rCX, rAX)
-	ADC(rBX, rDX)
-	POPR(rCX)			/* _sectsize(SB) */
-	DIV(rCX)
-	MW(rAX, rCX)
-	POPR(rDX)
-	POPR(rAX)
-
-	LWI(LOADSEG, rBX)		/* address to load into (seg+offset) */
-	MTSR(rBX, rES)			/*  seg */
-	LWI(LOADOFF, rBX)		/*  offset */
-
-_readboot:
-	CALL16(BIOSread(SB))		/* read the sector */
-
-	LW(_sectsize(SB), rDI)		/* bump addresses/counts */
-	ADD(rDI, rBX)
-	JCC _incsecno
-
-	MFSR(rES, rDI)			/* next 64KB segment */
-	ADDI(0x1000, rDI)
-	MTSR(rDI, rES)
-
-_incsecno:
-	CLR(rDI)
-	INC(rAX)
-	ADC(rDI, rDX)
-	LOOP _readboot
-
-	LWI(LOADSEG, rDI)		/* set rDS for loaded code */
-	MTSR(rDI, rDS)
-	FARJUMP16(LOADSEG, LOADOFF)	/* no deposit, no return */
-
-TEXT buggery(SB), $0
-	LWI(error(SB), rSI)
-	CALL16(BIOSputs(SB))
-
-_wait:
-	CLR(rAX)			/* wait for almost any key */
-	BIOSCALL(0x16)
-
-_reset:
-	CLR(rBX)			/* set ES segment for BIOS area */
-	MTSR(rBX, rES)
-
-	LWI(0x0472, rBX)		/* warm-start code address */
-	LWI(0x1234, rAX)		/* warm-start code */
-	POKEW				/* MOVW	AX, ES:[BX] */
-
-	FARJUMP16(0xFFFF, 0x0000)	/* reset */
-
-
-/*
- * Read a sector from a disc. On entry:
- *   rDX:rAX	sector number
- *   rES:rBX	buffer address
- */
-TEXT BIOSread(SB), $0
-	LWI(5, rDI)			/* retry count (ATAPI ZIPs suck) */
-_retry:
-	PUSHA				/* may be trashed by BIOSCALL */
-
-	SBPW(rBX, Xdap+4)		/* transfer buffer :offset */
-	MFSR(rES, rDI)			/* transfer buffer seg: */
-	SBPW(rDI, Xdap+6)
-	SBPW(rAX, Xdap+8)		/* LBA (64-bits) */
-	SBPW(rDX, Xdap+10)
-
-	MW(rBP, rSI)			/* disk address packet */
-	LBI(0x42, rAH)			/* extended read */
-	LBPB(Xdrive, rDL)		/* form drive */
-	BIOSCALL(0x13)			/* CF set on failure */
-	JCC _BIOSreadret
-
-	POPA
-	DEC(rDI)			/* too many retries? */
-	JEQ _ioerror
-
-	CALL16(dreset(SB))
-	JMP _retry
-
-_ioerror:
-	LWI(ioerror(SB), rSI)
-	CALL16(BIOSputs(SB))
-	JMP _wait
-
-_BIOSreadret:
-	POPA
-	RET
-
-TEXT dreset(SB), $0
-	PUSHA
-	CLR(rAX)			/* rAH == 0 == reset disc system */
-	LBPB(Xdrive, rDL)
-	BIOSCALL(0x13)
-	ORB(rAH, rAH)			/* status (0 == success) */
-	POPA
-	JNE _ioerror
-	RET
-
-/*
- * Output a string to the display.
- * String argument is in rSI.
- */
-TEXT BIOSputs(SB), $0
-	PUSHA
-	CLR(rBX)
-_BIOSputs:
-	LODSB
-	ORB(rAL, rAL)
-	JEQ _BIOSputsret
-
-	LBI(0x0E, rAH)
-	BIOSCALL(0x10)
-	JMP _BIOSputs
-
-_BIOSputsret:
-	POPA
-	RET
-
-/* "Bad format or I/O error\r\nPress almost any key to reboot..." */
-TEXT error(SB), $0
-	BYTE $'B'; BYTE $'a'; BYTE $'d'; BYTE $' ';
-	BYTE $'f'; BYTE $'o'; BYTE $'r'; BYTE $'m';
-	BYTE $'a'; BYTE $'t'; BYTE $' '; BYTE $'o';
-	BYTE $'r'; BYTE $' ';
-/* "I/O error\r\nPress almost any key to reboot..." */
-TEXT ioerror(SB), $0
-	BYTE $'I'; BYTE $'/'; BYTE $'O'; BYTE $' ';
-	BYTE $'e'; BYTE $'r'; BYTE $'r'; BYTE $'o';
-	BYTE $'r'; BYTE $'\r';BYTE $'\n';
-	BYTE $'P'; BYTE $'r'; BYTE $'e'; BYTE $'s';
-	BYTE $'s'; BYTE $' '; BYTE $'a'; BYTE $' ';
-	BYTE $'k'; BYTE $'e'; BYTE $'y';
-	BYTE $' '; BYTE $'t'; BYTE $'o'; BYTE $' ';
-	BYTE $'r'; BYTE $'e'; BYTE $'b'; BYTE $'o';
-	BYTE $'o'; BYTE $'t';
-	BYTE $'.'; BYTE $'.'; BYTE $'.';
-	BYTE $'\z';
-
-#ifdef USEBCOM
-/* "B       COM" */
-TEXT bootfile(SB), $0
-	BYTE $'B'; BYTE $' '; BYTE $' '; BYTE $' ';
-	BYTE $' '; BYTE $' '; BYTE $' '; BYTE $' ';
-	BYTE $'C'; BYTE $'O'; BYTE $'M';
-	BYTE $'\z';
-#else
-/* "9LOAD      " */
-TEXT bootfile(SB), $0
-	BYTE $'9'; BYTE $'L'; BYTE $'O'; BYTE $'A';
-	BYTE $'D'; BYTE $' '; BYTE $' '; BYTE $' ';
-	BYTE $' '; BYTE $' '; BYTE $' ';
-	BYTE $'\z';
-#endif /* USEBCOM */
-
-/* "PBS..." */
-TEXT confidence(SB), $0
-	BYTE $'P'; BYTE $'B'; BYTE $'S'; BYTE $'2';
-	BYTE $'.'; BYTE $'.'; BYTE $'.';
-	BYTE $'\z';

+ 0 - 1020
sys/src/9/w/pxeload/pci.c

@@ -1,1020 +0,0 @@
-/*
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
-
-/*
- * PCI support code.
- * To do:
- *	initialise bridge mappings if the PCI BIOS didn't.
- */
-#include "u.h"
-#include "lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#include "error.h"
-
-enum {					/* configuration mechanism #1 */
-	PciADDR		= 0xCF8,	/* CONFIG_ADDRESS */
-	PciDATA		= 0xCFC,	/* CONFIG_DATA */
-
-					/* configuration mechanism #2 */
-	PciCSE		= 0xCF8,	/* configuration space enable */
-	PciFORWARD	= 0xCFA,	/* which bus */
-
-	MaxFNO		= 7,
-	MaxUBN		= 255,
-};
-
-enum
-{					/* command register */
-	IOen		= (1<<0),
-	MEMen		= (1<<1),
-	MASen		= (1<<2),
-	MemWrInv	= (1<<4),
-	PErrEn		= (1<<6),
-	SErrEn		= (1<<8),
-};
-
-static Lock pcicfglock;
-static Lock pcicfginitlock;
-static int pcicfgmode = -1;
-static int pcimaxbno = 7;
-static int pcimaxdno;
-static Pcidev* pciroot;
-static Pcidev* pcilist;
-static Pcidev* pcitail;
-
-static int pcicfgrw32(int, int, int, int);
-static int pcicfgrw8(int, int, int, int);
-
-uint32_t
-pcibarsize(Pcidev *p, int rno)
-{
-	uint32_t v, size;
-
-	v = pcicfgrw32(p->tbdf, rno, 0, 1);
-	pcicfgrw32(p->tbdf, rno, 0xFFFFFFF0, 0);
-	size = pcicfgrw32(p->tbdf, rno, 0, 1);
-	if(v & 1)
-		size |= 0xFFFF0000;
-	pcicfgrw32(p->tbdf, rno, v, 0);
-
-	return -(size & ~0x0F);
-}
-
-int
-pciscan(int bno, Pcidev** list)
-{
-	Pcidev *p, *head, *tail;
-	int dno, fno, i, hdt, l, maxfno, maxubn, rno, sbn, tbdf, ubn;
-
-	maxubn = bno;
-	head = nil;
-	tail = nil;
-	for(dno = 0; dno <= pcimaxdno; dno++){
-		maxfno = 0;
-		for(fno = 0; fno <= maxfno; fno++){
-			/*
-			 * For this possible device, form the
-			 * bus+device+function triplet needed to address it
-			 * and try to read the vendor and device ID.
-			 * If successful, allocate a device struct and
-			 * start to fill it in with some useful information
-			 * from the device's configuration space.
-			 */
-			tbdf = MKBUS(BusPCI, bno, dno, fno);
-			l = pcicfgrw32(tbdf, PciVID, 0, 1);
-			if(l == 0xFFFFFFFF || l == 0)
-				continue;
-			p = malloc(sizeof(*p));
-			p->tbdf = tbdf;
-			p->vid = l;
-			p->did = l>>16;
-
-			if(pcilist != nil)
-				pcitail->list = p;
-			else
-				pcilist = p;
-			pcitail = p;
-
-			p->rid = pcicfgr8(p, PciRID);
-			p->ccrp = pcicfgr8(p, PciCCRp);
-			p->ccru = pcicfgr8(p, PciCCRu);
-			p->ccrb = pcicfgr8(p, PciCCRb);
-			p->pcr = pcicfgr32(p, PciPCR);
-
-			p->intl = pcicfgr8(p, PciINTL);
-			p->intp = pcicfgr8(p, PciINTP);
-
-			/*
-			 * If the device is a multi-function device adjust the
-			 * loop count so all possible functions are checked.
-			 */
-			hdt = pcicfgr8(p, PciHDT);
-			if(hdt & 0x80)
-				maxfno = MaxFNO;
-
-			/*
-			 * If appropriate, read the base address registers
-			 * and work out the sizes.
-			 */
-			switch(p->ccrb){
-
-			case 0x01:		/* mass storage controller */
-			case 0x02:		/* network controller */
-			case 0x03:		/* display controller */
-			case 0x04:		/* multimedia device */
-			case 0x07:		/* simple comm. controllers */
-			case 0x08:		/* base system peripherals */
-			case 0x09:		/* input devices */
-			case 0x0A:		/* docking stations */
-			case 0x0B:		/* processors */
-			case 0x0C:		/* serial bus controllers */
-				if((hdt & 0x7F) != 0)
-					break;
-				rno = PciBAR0 - 4;
-				for(i = 0; i < nelem(p->mem); i++){
-					rno += 4;
-					p->mem[i].bar = pcicfgr32(p, rno);
-					p->mem[i].size = pcibarsize(p, rno);
-				}
-				break;
-
-			case 0x00:
-			case 0x05:		/* memory controller */
-			case 0x06:		/* bridge device */
-			default:
-				break;
-			}
-
-			if(head != nil)
-				tail->link = p;
-			else
-				head = p;
-			tail = p;
-		}
-	}
-
-	*list = head;
-	for(p = head; p != nil; p = p->link){
-		/*
-		 * Find PCI-PCI and PCI-Cardbus bridges
-		 * and recursively descend the tree.
-		 */
-		if(p->ccrb != 0x06 || p->ccru != 0x04)
-			continue;
-
-		/*
-		 * If the secondary or subordinate bus number is not
-		 * initialised try to do what the PCI BIOS should have
-		 * done and fill in the numbers as the tree is descended.
-		 * On the way down the subordinate bus number is set to
-		 * the maximum as it's not known how many buses are behind
-		 * this one; the final value is set on the way back up.
-		 */
-		ubn = pcicfgr8(p, PciUBN);
-		sbn = pcicfgr8(p, PciSBN);
-
-		if(sbn == 0 || ubn == 0){
-			sbn = maxubn+1;
-			/*
-			 * Make sure memory, I/O and master enables are
-			 * off, set the primary, secondary and subordinate
-			 * bus numbers and clear the secondary status before
-			 * attempting to scan the secondary bus.
-			 *
-			 * Initialisation of the bridge should be done here.
-			 */
-			pcicfgw32(p, PciPCR, 0xFFFF0000);
-			l = (MaxUBN<<16)|(sbn<<8)|bno;
-			pcicfgw32(p, PciPBN, l);
-			pcicfgw16(p, PciSPSR, 0xFFFF);
-			maxubn = pciscan(sbn, &p->bridge);
-			l = (maxubn<<16)|(sbn<<8)|bno;
-
-			pcicfgw32(p, PciPBN, l);
-		}
-		else{
-			/*
-			 * You can't go back.
-			 * This shouldn't be possible, but the
-			 * Iwill DK8-HTX seems to have subordinate
-			 * bus numbers which get smaller on the
-			 * way down. Need to look more closely at
-			 * this.
-			 */
-			if(ubn > maxubn)
-				maxubn = ubn;
-			pciscan(sbn, &p->bridge);
-		}
-	}
-
-	return maxubn;
-}
-
-static uint8_t
-pIIx_link(Pcidev *router, uint8_t link)
-{
-	uint8_t pirq;
-
-	/* link should be 0x60, 0x61, 0x62, 0x63 */
-	pirq = pcicfgr8(router, link);
-	return (pirq < 16)? pirq: 0;
-}
-
-static void
-pIIx_init(Pcidev *router, uint8_t link, uint8_t irq)
-{
-	pcicfgw8(router, link, irq);
-}
-
-static uint8_t
-via_link(Pcidev *router, uint8_t link)
-{
-	uint8_t pirq;
-
-	/* link should be 1, 2, 3, 5 */
-	pirq = (link < 6)? pcicfgr8(router, 0x55 + (link>>1)): 0;
-
-	return (link & 1)? (pirq >> 4): (pirq & 15);
-}
-
-static void
-via_init(Pcidev *router, uint8_t link, uint8_t irq)
-{
-	uint8_t pirq;
-
-	pirq = pcicfgr8(router, 0x55 + (link >> 1));
-	pirq &= (link & 1)? 0x0f: 0xf0;
-	pirq |= (link & 1)? (irq << 4): (irq & 15);
-	pcicfgw8(router, 0x55 + (link>>1), pirq);
-}
-
-static uint8_t
-opti_link(Pcidev *router, uint8_t link)
-{
-	uint8_t pirq = 0;
-
-	/* link should be 0x02, 0x12, 0x22, 0x32 */
-	if ((link & 0xcf) == 0x02)
-		pirq = pcicfgr8(router, 0xb8 + (link >> 5));
-	return (link & 0x10)? (pirq >> 4): (pirq & 15);
-}
-
-static void
-opti_init(Pcidev *router, uint8_t link, uint8_t irq)
-{
-	uint8_t pirq;
-
-	pirq = pcicfgr8(router, 0xb8 + (link >> 5));
-    	pirq &= (link & 0x10)? 0x0f : 0xf0;
-    	pirq |= (link & 0x10)? (irq << 4): (irq & 15);
-	pcicfgw8(router, 0xb8 + (link >> 5), pirq);
-}
-
-static uint8_t
-ali_link(Pcidev *router, uint8_t link)
-{
-	/* No, you're not dreaming */
-	static const uint8_t map[] = { 0, 9, 3, 10, 4, 5, 7, 6, 1, 11, 0, 12, 0, 14, 0, 15 };
-	uint8_t pirq;
-
-	/* link should be 0x01..0x08 */
-	pirq = pcicfgr8(router, 0x48 + ((link-1)>>1));
-	return (link & 1)? map[pirq&15]: map[pirq>>4];
-}
-
-static void
-ali_init(Pcidev *router, uint8_t link, uint8_t irq)
-{
-	/* Inverse of map in ali_link */
-	static const uint8_t map[] = { 0, 8, 0, 2, 4, 5, 7, 6, 0, 1, 3, 9, 11, 0, 13, 15 };
-	uint8_t pirq;
-
-	pirq = pcicfgr8(router, 0x48 + ((link-1)>>1));
-	pirq &= (link & 1)? 0x0f: 0xf0;
-	pirq |= (link & 1)? (map[irq] << 4): (map[irq] & 15);
-	pcicfgw8(router, 0x48 + ((link-1)>>1), pirq);
-}
-
-static uint8_t
-cyrix_link(Pcidev *router, uint8_t link)
-{
-	uint8_t pirq;
-
-	/* link should be 1, 2, 3, 4 */
-	pirq = pcicfgr8(router, 0x5c + ((link-1)>>1));
-	return ((link & 1)? pirq >> 4: pirq & 15);
-}
-
-static void
-cyrix_init(Pcidev *router, uint8_t link, uint8_t irq)
-{
-	uint8_t pirq;
-
-	pirq = pcicfgr8(router, 0x5c + (link>>1));
-	pirq &= (link & 1)? 0x0f: 0xf0;
-	pirq |= (link & 1)? (irq << 4): (irq & 15);
-	pcicfgw8(router, 0x5c + (link>>1), pirq);
-}
-
-enum {
-	Intel = 0x8086,
-		Intel_82371FB_0 = 0x122e,
-		Intel_82371MX_0 = 0x1234,
-		Intel_82371SB_0 = 0x7000,
-		Intel_82371AB_0 = 0x7110,
-		Intel_82443MX_1 = 0x7198,
-		Intel_82801AA_0 = 0x2410,
-		Intel_82801AB_0 = 0x2420,
-		Intel_82801BA_0 = 0x2440,
-		Intel_82801BAM_0 = 0x244c,
-		Intel_82801CAM_0 = 0x248c,
-		Intel_82801DBM_0 = 0x24cc,
-		Intel_82801EB_0 = 0x24d0,
-		Intel_82801FB_0 = 0x2640,
-	Viatech = 0x1106,
-		Via_82C586_0 = 0x0586,
-		Via_82C596 = 0x0596,
-		Via_82C686 = 0x0686,
-	Opti = 0x1045,
-		Opti_82C700 = 0xc700,
-	Al = 0x10b9,
-		Al_M1533 = 0x1533,
-	SI = 0x1039,
-		SI_503 = 0x0008,
-		SI_496 = 0x0496,
-	Cyrix = 0x1078,
-		Cyrix_5530_Legacy = 0x0100,
-};
-
-typedef struct {
-	uint16_t	sb_vid, sb_did;
-	uint8_t	(*sb_translate)(Pcidev *, uint8_t);
-	void	(*sb_initialize)(Pcidev *, uint8_t, uint8_t);
-} bridge_t;
-
-static bridge_t southbridges[] = {
-{	Intel, Intel_82371FB_0,		pIIx_link,	pIIx_init },
-{	Intel, Intel_82371MX_0,		pIIx_link,	pIIx_init },
-{	Intel, Intel_82371SB_0,		pIIx_link,	pIIx_init },
-{	Intel, Intel_82371AB_0,		pIIx_link,	pIIx_init },
-{	Intel, Intel_82443MX_1,		pIIx_link,	pIIx_init },
-{	Intel, Intel_82801AA_0,		pIIx_link,	pIIx_init },
-{	Intel, Intel_82801AB_0,		pIIx_link,	pIIx_init },
-{	Intel, Intel_82801BA_0,		pIIx_link,	pIIx_init },
-{	Intel, Intel_82801BAM_0,	pIIx_link,	pIIx_init },
-{	Intel, Intel_82801CAM_0,	pIIx_link,	pIIx_init },
-{	Intel, Intel_82801DBM_0,	pIIx_link,	pIIx_init },
-{	Intel, Intel_82801EB_0,		pIIx_link,	pIIx_init },
-{	Intel, Intel_82801FB_0,		pIIx_link,	pIIx_init },
-{	Viatech, Via_82C586_0,		via_link,	via_init },
-{	Viatech, Via_82C596,		via_link,	via_init },
-{	Viatech, Via_82C686,		via_link,	via_init },
-{	Opti, Opti_82C700,		opti_link,	opti_init },
-{	Al, Al_M1533,			ali_link,	ali_init },
-{	SI, SI_503,			pIIx_link,	pIIx_init },
-{	SI, SI_496,			pIIx_link,	pIIx_init },
-{	Cyrix, Cyrix_5530_Legacy,	cyrix_link,	cyrix_init }
-};
-
-typedef struct {
-	uint8_t	e_bus;			// Pci bus number
-	uint8_t	e_dev;			// Pci device number
-	uint8_t	e_maps[12];		// Avoid structs!  Link and mask.
-	uint8_t	e_slot;			// Add-in/built-in slot
-	uint8_t	e_reserved;
-} slot_t;
-
-typedef struct {
-	uint8_t	rt_signature[4];	// Routing table signature
-	uint8_t	rt_version[2];		// Version number
-	uint8_t	rt_size[2];			// Total table size
-	uint8_t	rt_bus;			// Interrupt router bus number
-	uint8_t	rt_devfn;			// Router's devfunc
-	uint8_t	rt_pciirqs[2];		// Exclusive PCI irqs
-	uint8_t	rt_compat[4];		// Compatible PCI interrupt router
-	uint8_t	rt_miniport[4];		// Miniport data
-	uint8_t	rt_reserved[11];
-	uint8_t	rt_checksum;
-} router_t;
-
-static uint16_t pciirqs;			// Exclusive PCI irqs
-static bridge_t *southbridge;	// Which southbridge to use.
-
-static void
-pcirouting(void)
-{
-	uint8_t *p, pin, irq;
-	uint32_t tbdf, vdid;
-	uint16_t vid, did;
-	router_t *r;
-	slot_t *e;
-	int size, i, fn;
-	Pcidev *sbpci, *pci;
-
-	// Peek in the BIOS
-	for (p = (uint8_t *)KADDR(0xf0000); p < (uint8_t *)KADDR(0xfffff); p += 16)
-		if (p[0] == '$' && p[1] == 'P' && p[2] == 'I' && p[3] == 'R')
-			break;
-
-	if (p >= (uint8_t *)KADDR(0xfffff))
-		return;
-
-	r = (router_t *)p;
-
-	// print("PCI interrupt routing table version %d.%d at %.6uX\n",
-	// 	r->rt_version[0], r->rt_version[1], (ulong)r & 0xfffff);
-
-	tbdf = (BusPCI << 24)|(r->rt_bus << 16)|(r->rt_devfn << 8);
-	vdid = pcicfgrw32(tbdf, PciVID, 0, 1);
-	vid = vdid;
-	did = vdid >> 16;
-
-	for (i = 0; i != nelem(southbridges); i++)
-		if (vid == southbridges[i].sb_vid && did == southbridges[i].sb_did)
-			break;
-
-	if (i == nelem(southbridges)) {
-		print("pcirouting: South bridge %.4uX, %.4uX not found\n", vid, did);
-		return;
-	}
-	southbridge = &southbridges[i];
-
-	if ((sbpci = pcimatch(nil, vid, did)) == nil) {
-		print("pcirouting: Cannot match south bridge %.4uX, %.4uX\n",
-			  vid, did);
-		return;
-	}
-
-	pciirqs = (r->rt_pciirqs[1] << 8)|r->rt_pciirqs[0];
-
-	size = (r->rt_size[1] << 8)|r->rt_size[0];
-	for (e = (slot_t *)&r[1]; (uint8_t *)e < p + size; e++) {
-		// print("%.2uX/%.2uX %.2uX: ", e->e_bus, e->e_dev, e->e_slot);
-		// for (i = 0; i != 4; i++) {
-		// 	uchar *m = &e->e_maps[i * 3];
-		// 	print("[%d] %.2uX %.4uX ",
-		// 		i, m[0], (m[2] << 8)|m[1]);
-		// }
-		// print("\n");
-
-		for (fn = 0; fn != 8; fn++) {
-			uint8_t *m;
-
-			// Retrieve the did and vid through the devfn before
-			// obtaining the Pcidev structure.
-			tbdf = (BusPCI << 24)|(e->e_bus << 16)|((e->e_dev | fn) << 8);
-			vdid = pcicfgrw32(tbdf, PciVID, 0, 1);
-			if (vdid == 0xFFFFFFFF || vdid == 0)
-				continue;
-
-			vid = vdid;
-			did = vdid >> 16;
-
-			pci = nil;
-			while ((pci = pcimatch(pci, vid, did)) != nil) {
-
-				if (pci->intl != 0 && pci->intl != 0xFF)
-					continue;
-
-				pin = pcicfgr8(pci, PciINTP);
-				if (pin == 0 || pin == 0xff)
-					continue;
-
-				m = &e->e_maps[(pin - 1) * 3];
-				irq = southbridge->sb_translate(sbpci, m[0]);
-				if (irq) {
-					print("pcirouting: %.4uX/%.4uX at pin %d irq %d\n",
-						  vid, did, pin, irq);
-					pcicfgw8(pci, PciINTL, irq);
-					pci->intl = irq;
-				}
-			}
-		}
-	}
-}
-
-static void
-pcicfginit(void)
-{
-	char *p;
-	int bno, n;
-	Pcidev **list;
-
-	lock(&pcicfginitlock);
-	if(pcicfgmode != -1)
-		goto out;
-
-	/*
-	 * Try to determine which PCI configuration mode is implemented.
-	 * Mode2 uses a byte at 0xCF8 and another at 0xCFA; Mode1 uses
-	 * a DWORD at 0xCF8 and another at 0xCFC and will pass through
-	 * any non-DWORD accesses as normal I/O cycles. There shouldn't be
-	 * a device behind these addresses so if Mode1 accesses fail try
-	 * for Mode2 (Mode2 is deprecated).
-	 */
-
-	/*
-	 * Bits [30:24] of PciADDR must be 0,
-	 * according to the spec.
-	 */
-	n = inl(PciADDR);
-	if(!(n & 0x7FF00000)){
-		outl(PciADDR, 0x80000000);
-		outb(PciADDR+3, 0);
-		if(inl(PciADDR) & 0x80000000){
-			pcicfgmode = 1;
-			pcimaxdno = 31;
-		}
-	}
-	outl(PciADDR, n);
-
-	if(pcicfgmode < 0){
-		/*
-		 * The 'key' part of PciCSE should be 0.
-		 */
-		n = inb(PciCSE);
-		if(!(n & 0xF0)){
-			outb(PciCSE, 0x0E);
-			if(inb(PciCSE) == 0x0E){
-				pcicfgmode = 2;
-				pcimaxdno = 15;
-			}
-		}
-		outb(PciCSE, n);
-	}
-
-	if(pcicfgmode < 0)
-		goto out;
-
-
-	if(p = getconf("*pcimaxbno"))
-		pcimaxbno = strtoul(p, 0, 0);
-	if(p = getconf("*pcimaxdno"))
-		pcimaxdno = strtoul(p, 0, 0);
-
-	list = &pciroot;
-	for(bno = 0; bno <= pcimaxbno; bno++) {
-		bno = pciscan(bno, list);
-		while(*list)
-			list = &(*list)->link;
-	}
-
-	pcirouting();
-
-out:
-	unlock(&pcicfginitlock);
-
-	if(getconf("*pcihinv"))
-		pcihinv(nil);
-}
-
-
-static int
-pcicfgrw8(int tbdf, int rno, int data, int read)
-{
-	int o, type, x;
-
-	if(pcicfgmode == -1)
-		pcicfginit();
-
-	if(BUSBNO(tbdf))
-		type = 0x01;
-	else
-		type = 0x00;
-	x = -1;
-	if(BUSDNO(tbdf) > pcimaxdno)
-		return x;
-
-	lock(&pcicfglock);
-	switch(pcicfgmode){
-
-	case 1:
-		o = rno & 0x03;
-		rno &= ~0x03;
-		outl(PciADDR, 0x80000000|BUSBDF(tbdf)|rno|type);
-		if(read)
-			x = inb(PciDATA+o);
-		else
-			outb(PciDATA+o, data);
-		outl(PciADDR, 0);
-		break;
-
-	case 2:
-		outb(PciCSE, 0x80|(BUSFNO(tbdf)<<1));
-		outb(PciFORWARD, BUSBNO(tbdf));
-		if(read)
-			x = inb((0xC000|(BUSDNO(tbdf)<<8)) + rno);
-		else
-			outb((0xC000|(BUSDNO(tbdf)<<8)) + rno, data);
-		outb(PciCSE, 0);
-		break;
-	}
-	unlock(&pcicfglock);
-
-	return x;
-}
-
-int
-pcicfgr8(Pcidev* pcidev, int rno)
-{
-	return pcicfgrw8(pcidev->tbdf, rno, 0, 1);
-}
-
-void
-pcicfgw8(Pcidev* pcidev, int rno, int data)
-{
-	pcicfgrw8(pcidev->tbdf, rno, data, 0);
-}
-
-static int
-pcicfgrw16(int tbdf, int rno, int data, int read)
-{
-	int o, type, x;
-
-	if(pcicfgmode == -1)
-		pcicfginit();
-
-	if(BUSBNO(tbdf))
-		type = 0x01;
-	else
-		type = 0x00;
-	x = -1;
-	if(BUSDNO(tbdf) > pcimaxdno)
-		return x;
-
-	lock(&pcicfglock);
-	switch(pcicfgmode){
-
-	case 1:
-		o = rno & 0x02;
-		rno &= ~0x03;
-		outl(PciADDR, 0x80000000|BUSBDF(tbdf)|rno|type);
-		if(read)
-			x = ins(PciDATA+o);
-		else
-			outs(PciDATA+o, data);
-		outl(PciADDR, 0);
-		break;
-
-	case 2:
-		outb(PciCSE, 0x80|(BUSFNO(tbdf)<<1));
-		outb(PciFORWARD, BUSBNO(tbdf));
-		if(read)
-			x = ins((0xC000|(BUSDNO(tbdf)<<8)) + rno);
-		else
-			outs((0xC000|(BUSDNO(tbdf)<<8)) + rno, data);
-		outb(PciCSE, 0);
-		break;
-	}
-	unlock(&pcicfglock);
-
-	return x;
-}
-
-int
-pcicfgr16(Pcidev* pcidev, int rno)
-{
-	return pcicfgrw16(pcidev->tbdf, rno, 0, 1);
-}
-
-void
-pcicfgw16(Pcidev* pcidev, int rno, int data)
-{
-	pcicfgrw16(pcidev->tbdf, rno, data, 0);
-}
-
-static int
-pcicfgrw32(int tbdf, int rno, int data, int read)
-{
-	int type, x;
-
-	if(pcicfgmode == -1)
-		pcicfginit();
-
-	if(BUSBNO(tbdf))
-		type = 0x01;
-	else
-		type = 0x00;
-	x = -1;
-	if(BUSDNO(tbdf) > pcimaxdno)
-		return x;
-
-	lock(&pcicfglock);
-	switch(pcicfgmode){
-
-	case 1:
-		rno &= ~0x03;
-		outl(PciADDR, 0x80000000|BUSBDF(tbdf)|rno|type);
-		if(read)
-			x = inl(PciDATA);
-		else
-			outl(PciDATA, data);
-		outl(PciADDR, 0);
-		break;
-
-	case 2:
-		outb(PciCSE, 0x80|(BUSFNO(tbdf)<<1));
-		outb(PciFORWARD, BUSBNO(tbdf));
-		if(read)
-			x = inl((0xC000|(BUSDNO(tbdf)<<8)) + rno);
-		else
-			outl((0xC000|(BUSDNO(tbdf)<<8)) + rno, data);
-		outb(PciCSE, 0);
-		break;
-	}
-	unlock(&pcicfglock);
-
-	return x;
-}
-
-int
-pcicfgr32(Pcidev* pcidev, int rno)
-{
-	return pcicfgrw32(pcidev->tbdf, rno, 0, 1);
-}
-
-void
-pcicfgw32(Pcidev* pcidev, int rno, int data)
-{
-	pcicfgrw32(pcidev->tbdf, rno, data, 0);
-}
-
-Pcidev*
-pcimatch(Pcidev* prev, int vid, int did)
-{
-	if(pcicfgmode == -1)
-		pcicfginit();
-
-	if(prev == nil)
-		prev = pcilist;
-	else
-		prev = prev->list;
-
-	while(prev != nil) {
-		if((vid == 0 || prev->vid == vid)
-		&& (did == 0 || prev->did == did))
-			break;
-		prev = prev->list;
-	}
-	return prev;
-}
-
-uint8_t
-pciipin(Pcidev *pci, uint8_t pin)
-{
-	if (pci == nil)
-		pci = pcilist;
-
-	while (pci) {
-		uint8_t intl;
-
-		if (pcicfgr8(pci, PciINTP) == pin && pci->intl != 0 && pci->intl != 0xff)
-			return pci->intl;
-
-		if (pci->bridge && (intl = pciipin(pci->bridge, pin)) != 0)
-			return intl;
-
-		pci = pci->list;
-	}
-	return 0;
-}
-
-static uint16_t
-pciimask(Pcidev *pci)
-{
-	uint16_t imask;
-
-	imask = 0;
-	while (pci) {
-		if (pcicfgr8(pci, PciINTP) && pci->intl < 16)
-			imask |= 1 << pci->intl;
-
-		if (pci->bridge)
-			imask |= pciimask(pci->bridge);
-
-		pci = pci->list;
-	}
-	return imask;
-}
-
-uint8_t
-pciintl(Pcidev *pci)
-{
-	uint16_t imask;
-	int i;
-
-	if (pci == nil)
-		pci = pcilist;
-
-	imask = pciimask(pci) | 1;
-	for (i = 0; i != 16; i++)
-		if ((imask & (1 << i)) == 0)
-			return i;
-	return 0;
-}
-
-void
-pcihinv(Pcidev* p)
-{
-	int i;
-	Pcidev *t;
-
-	if(pcicfgmode == -1)
-		pcicfginit();
-
-	if(p == nil) {
-		p = pciroot;
-		print("bus dev type vid  did intl intp memory\n");
-	}
-	for(t = p; t != nil; t = t->link) {
-		print("%d  %2d/%d %.2ux %.2ux %.2ux %.4ux %.4ux %3d %3d  ",
-			BUSBNO(t->tbdf), BUSDNO(t->tbdf), BUSFNO(t->tbdf),
-			t->ccrb, t->ccru, t->ccrp, t->vid, t->did, t->intl,
-			t->intp);
-
-		for(i = 0; i < nelem(p->mem); i++) {
-			if(t->mem[i].size == 0)
-				continue;
-			print("%d:%.8lux %d ", i,
-				t->mem[i].bar, t->mem[i].size);
-		}
-		print("\n");
-	}
-	while(p != nil) {
-		if(p->bridge != nil)
-			pcihinv(p->bridge);
-		p = p->link;
-	}
-}
-
-void
-pcireset(void)
-{
-	Pcidev *p;
-	int pcr;
-
-	if(pcicfgmode == -1)
-		pcicfginit();
-
-	for(p = pcilist; p != nil; p = p->list){
-		pcr = pcicfgr16(p, PciPSR);
-		pcicfgw16(p, PciPSR, pcr & ~0x04);
-	}
-}
-
-void
-pcisetioe(Pcidev* p)
-{
-	p->pcr |= IOen;
-	pcicfgw16(p, PciPCR, p->pcr);
-}
-
-void
-pciclrioe(Pcidev* p)
-{
-	p->pcr &= ~IOen;
-	pcicfgw16(p, PciPCR, p->pcr);
-}
-
-void
-pcisetbme(Pcidev* p)
-{
-	p->pcr |= MASen;
-	pcicfgw16(p, PciPCR, p->pcr);
-}
-
-void
-pciclrbme(Pcidev* p)
-{
-	p->pcr &= ~MASen;
-	pcicfgw16(p, PciPCR, p->pcr);
-}
-
-void
-pcisetmwi(Pcidev* p)
-{
-	p->pcr |= MemWrInv;
-	pcicfgw16(p, PciPCR, p->pcr);
-}
-
-void
-pciclrmwi(Pcidev* p)
-{
-	p->pcr &= ~MemWrInv;
-	pcicfgw16(p, PciPCR, p->pcr);
-}
-
-static int
-pcigetpmrb(Pcidev* p)
-{
-	int ptr;
-
-	if(p->pmrb != 0)
-		return p->pmrb;
-	p->pmrb = -1;
-
-	/*
-	 * If there are no extended capabilities implemented,
-	 * (bit 4 in the status register) assume there's no standard
-	 * power management method.
-	 * Find the capabilities pointer based on PCI header type.
-	 */
-	if(!(p->pcr & 0x0010))
-		return -1;
-	switch(pcicfgr8(p, PciHDT)){
-	default:
-		return -1;
-	case 0:					/* all other */
-	case 1:					/* PCI to PCI bridge */
-		ptr = 0x34;
-		break;
-	case 2:					/* CardBus bridge */
-		ptr = 0x14;
-		break;
-	}
-	ptr = pcicfgr32(p, ptr);
-
-	while(ptr != 0){
-		/*
-		 * Check for validity.
-		 * Can't be in standard header and must be double
-		 * word aligned.
-		 */
-		if(ptr < 0x40 || (ptr & ~0xFC))
-			return -1;
-		if(pcicfgr8(p, ptr) == 0x01){
-			p->pmrb = ptr;
-			return ptr;
-		}
-
-		ptr = pcicfgr8(p, ptr+1);
-	}
-
-	return -1;
-}
-
-int
-pcigetpms(Pcidev* p)
-{
-	int pmcsr, ptr;
-
-	if((ptr = pcigetpmrb(p)) == -1)
-		return -1;
-
-	/*
-	 * Power Management Register Block:
-	 *  offset 0:	Capability ID
-	 *	   1:	next item pointer
-	 *	   2:	capabilities
-	 *	   4:	control/status
-	 *	   6:	bridge support extensions
-	 *	   7:	data
-	 */
-	pmcsr = pcicfgr16(p, ptr+4);
-
-	return pmcsr & 0x0003;
-}
-
-int
-pcisetpms(Pcidev* p, int state)
-{
-	int ostate, pmc, pmcsr, ptr;
-
-	if((ptr = pcigetpmrb(p)) == -1)
-		return -1;
-
-	pmc = pcicfgr16(p, ptr+2);
-	pmcsr = pcicfgr16(p, ptr+4);
-	ostate = pmcsr & 0x0003;
-	pmcsr &= ~0x0003;
-
-	switch(state){
-	default:
-		return -1;
-	case 0:
-		break;
-	case 1:
-		if(!(pmc & 0x0200))
-			return -1;
-		break;
-	case 2:
-		if(!(pmc & 0x0400))
-			return -1;
-		break;
-	case 3:
-		break;
-	}
-	pmcsr |= state;
-	pcicfgw16(p, ptr+4, pmcsr);
-
-	return ostate;
-}

BIN
sys/src/9/w/pxeload/ppxeload


BIN
sys/src/9/w/pxeload/ppxeloadacid


+ 0 - 85
sys/src/9/w/pxeload/print.c

@@ -1,85 +0,0 @@
-/*
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
-
-#include "u.h"
-#include "lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-
-static int spinning;
-static char* wheel[4] = { "\b|", "\b/", "\b-", "\b\\", };
-static int spoke;
-
-void
-startwheel(void)
-{
-	spoke = 1;
-	consputs("|", 1);
-	spinning = 1;
-}
-
-void
-turnwheel(int dir)
-{
-	if(!spinning)
-		return;
-	spoke += dir;
-	consputs(wheel[spoke & 3], 2);
-}
-
-void
-stopwheel(void)
-{
-	consputs("\b", 1);
-	spinning = 0;
-}
-
-int
-print(char* fmt, ...)
-{
-	va_list arg;
-	char buf[PRINTSIZE], *e, *p;
-
-	p = buf;
-	if(spinning)
-		*p++ = '\b';
-
-	va_start(arg, fmt);
-	e = vseprint(p, buf+sizeof(buf), fmt, arg);
-	va_end(arg);
-
-	if(spinning && e < &buf[PRINTSIZE-2]){
-		*e++ = ' ';
-		*e = 0;
-	}
-	consputs(buf, e-buf);
-
-	return e-buf;
-}
-
-static Lock fmtl;
-
-void
-_fmtlock(void)
-{
-	lock(&fmtl);
-}
-
-void
-_fmtunlock(void)
-{
-	unlock(&fmtl);
-}
-
-int
-_efgfmt(Fmt*)
-{
-	return -1;
-}

+ 0 - 53
sys/src/9/w/pxeload/queue.c

@@ -1,53 +0,0 @@
-/*
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
-
-#include	"u.h"
-#include	"lib.h"
-#include	"mem.h"
-#include	"dat.h"
-#include	"fns.h"
-#include	"io.h"
-
-int
-qgetc(IOQ *q)
-{
-	int c;
-
-	if(q->in == q->out)
-		return -1;
-	c = *q->out;
-	if(q->out == q->buf+sizeof(q->buf)-1)
-		q->out = q->buf;
-	else
-		q->out++;
-	return c;
-}
-
-static int
-qputc(IOQ *q, int c)
-{
-	uint8_t *nextin;
-	if(q->in >= &q->buf[sizeof(q->buf)-1])
-		nextin = q->buf;
-	else
-		nextin = q->in+1;
-	if(nextin == q->out)
-		return -1;
-	*q->in = c;
-	q->in = nextin;
-	return 0;
-}
-
-void
-qinit(IOQ *q)
-{
-	q->in = q->out = q->buf;
-	q->getc = qgetc;
-	q->putc = qputc;
-}

+ 0 - 362
sys/src/9/w/pxeload/trap.c

@@ -1,362 +0,0 @@
-/*
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
-
-#include	"u.h"
-#include	"lib.h"
-#include	"mem.h"
-#include	"dat.h"
-#include	"fns.h"
-#include	"io.h"
-#include	"ureg.h"
-
-#define	DATASEGM(p) 	{ 0xFFFF, SEGG|SEGB|(0xF<<16)|SEGP|SEGPL(p)|SEGDATA|SEGW }
-#define	EXECSEGM(p) 	{ 0xFFFF, SEGG|SEGD|(0xF<<16)|SEGP|SEGPL(p)|SEGEXEC|SEGR }
-
-Segdesc gdt[NGDT] =
-{
-[NULLSEG]	{ 0, 0},		/* null descriptor */
-[KDSEG]		DATASEGM(0),		/* kernel data/stack */
-[KESEG]		EXECSEGM(0),		/* kernel code */
-};
-
-void	intr0(void), intr1(void), intr2(void), intr3(void);
-void	intr4(void), intr5(void), intr6(void), intr7(void);
-void	intr8(void), intr9(void), intr10(void), intr11(void);
-void	intr12(void), intr13(void), intr14(void), intr15(void);
-void	intr16(void);
-void	intr24(void), intr25(void), intr26(void), intr27(void);
-void	intr28(void), intr29(void), intr30(void), intr31(void);
-void	intr32(void), intr33(void), intr34(void), intr35(void);
-void	intr36(void), intr37(void), intr38(void), intr39(void);
-void	intr64(void);
-void	intrbad(void);
-
-/*
- *  8259 interrupt controllers
- */
-enum
-{
-	Int0ctl=	0x20,		/* control port (ICW1, OCW2, OCW3) */
-	Int0aux=	0x21,		/* everything else (ICW2, ICW3, ICW4, OCW1) */
-	Int1ctl=	0xA0,		/* control port */
-	Int1aux=	0xA1,		/* everything else (ICW2, ICW3, ICW4, OCW1) */
-
-	Icw1=		0x10,		/* select bit in ctl register */
-	Ocw2=		0x00,
-	Ocw3=		0x08,
-
-	EOI=		0x20,		/* non-specific end of interrupt */
-
-	Elcr1=		0x4D0,		/* Edge/Level Triggered Register */
-	Elcr2=		0x4D1,
-};
-
-int	int0mask = 0xff;	/* interrupts enabled for first 8259 */
-int	int1mask = 0xff;	/* interrupts enabled for second 8259 */
-int	i8259elcr;		/* mask of level-triggered interrupts */
-
-/*
- *  trap/interrupt gates
- */
-Segdesc ilt[256];
-
-enum
-{
-	Maxhandler=	32,		/* max number of interrupt handlers */
-};
-
-typedef struct Handler	Handler;
-struct Handler
-{
-	void	(*r)(Ureg*, void*);
-	void	*arg;
-	Handler	*next;
-};
-
-struct
-{
-	Handler	*ivec[256];
-	Handler	h[Maxhandler];
-	int	nextfree;
-} halloc;
-
-void
-sethvec(int v, void (*r)(void), int type, int pri)
-{
-	ilt[v].d0 = ((uint32_t)r)&0xFFFF|(KESEL<<16);
-	ilt[v].d1 = ((uint32_t)r)&0xFFFF0000|SEGP|SEGPL(pri)|type;
-}
-
-void
-setvec(int v, void (*r)(Ureg*, void*), void *arg)
-{
-	Handler *h;
-
-	if(halloc.nextfree >= Maxhandler)
-		panic("out of interrupt handlers");
-	h = &halloc.h[halloc.nextfree++];
-	h->next = halloc.ivec[v];
-	h->r = r;
-	h->arg = arg;
-	halloc.ivec[v] = h;
-
-	/*
-	 *  enable corresponding interrupt in 8259
-	 */
-	if((v&~0x7) == VectorPIC){
-		int0mask &= ~(1<<(v&7));
-		outb(Int0aux, int0mask);
-	} else if((v&~0x7) == VectorPIC+8){
-		int1mask &= ~(1<<(v&7));
-		outb(Int1aux, int1mask);
-	}
-}
-
-void
-trapdisable(void)
-{
-	outb(Int0aux, 0xFF);
-	outb(Int1aux, 0xFF);
-
-	outb(Int0ctl, EOI);
-	outb(Int1ctl, EOI);
-}
-
-void
-trapenable(void)
-{
-	outb(Int0aux, int0mask);
-	outb(Int1aux, int1mask);
-}
-
-/*
- *  set up the interrupt/trap gates
- */
-void
-trapinit(void)
-{
-	int i, x;
-	uint32_t a;
-	uint16_t ptr[3];
-
-	/*
-	 *  set all interrupts to panics
-	 */
-	for(i = 0; i < 256; i++)
-		sethvec(i, intrbad, SEGTG, 0);
-
-	/*
-	 *  80386 processor (and coprocessor) traps
-	 */
-	sethvec(0, intr0, SEGTG, 0);
-	sethvec(1, intr1, SEGTG, 0);
-	sethvec(2, intr2, SEGTG, 0);
-	sethvec(3, intr3, SEGTG, 0);
-	sethvec(4, intr4, SEGTG, 0);
-	sethvec(5, intr5, SEGTG, 0);
-	sethvec(6, intr6, SEGTG, 0);
-	sethvec(7, intr7, SEGTG, 0);
-	sethvec(8, intr8, SEGTG, 0);
-	sethvec(9, intr9, SEGTG, 0);
-	sethvec(10, intr10, SEGTG, 0);
-	sethvec(11, intr11, SEGTG, 0);
-	sethvec(12, intr12, SEGTG, 0);
-	sethvec(13, intr13, SEGTG, 0);
-	sethvec(14, intr14, SEGTG, 0);
-	sethvec(15, intr15, SEGTG, 0);
-	sethvec(16, intr16, SEGTG, 0);
-
-	/*
-	 *  device interrupts
-	 */
-	sethvec(24, intr24, SEGIG, 0);
-	sethvec(25, intr25, SEGIG, 0);
-	sethvec(26, intr26, SEGIG, 0);
-	sethvec(27, intr27, SEGIG, 0);
-	sethvec(28, intr28, SEGIG, 0);
-	sethvec(29, intr29, SEGIG, 0);
-	sethvec(30, intr30, SEGIG, 0);
-	sethvec(31, intr31, SEGIG, 0);
-	sethvec(32, intr32, SEGIG, 0);
-	sethvec(33, intr33, SEGIG, 0);
-	sethvec(34, intr34, SEGIG, 0);
-	sethvec(35, intr35, SEGIG, 0);
-	sethvec(36, intr36, SEGIG, 0);
-	sethvec(37, intr37, SEGIG, 0);
-	sethvec(38, intr38, SEGIG, 0);
-	sethvec(39, intr39, SEGIG, 0);
-
-	/*
-	 *  tell the hardware where the table is (and how long)
-	 */
-	memmove(m->gdt, gdt, sizeof gdt);
-
-	ptr[0] = sizeof(gdt)-1;
-	a = (uint32_t)m->gdt;
-	ptr[1] = a & 0xFFFF;
-	ptr[2] = (a>>16) & 0xFFFF;
-	lgdt(ptr);
-
-	ptr[0] = sizeof(Segdesc)*256-1;
-	a = (uint32_t)ilt;
-	ptr[1] = a & 0xFFFF;
-	ptr[2] = (a>>16) & 0xFFFF;
-	lidt(ptr);
-
-	/*
-	 *  Set up the first 8259 interrupt processor.
-	 *  Make 8259 interrupts start at CPU vector VectorPIC.
-	 *  Set the 8259 as master with edge triggered
-	 *  input with fully nested interrupts.
-	 */
-	outb(Int0ctl, Icw1|0x01);	/* ICW1 - edge triggered, master,
-					   ICW4 will be sent */
-	outb(Int0aux, VectorPIC);	/* ICW2 - interrupt vector offset */
-	outb(Int0aux, 0x04);		/* ICW3 - have slave on level 2 */
-	outb(Int0aux, 0x01);		/* ICW4 - 8086 mode, not buffered */
-
-	/*
-	 *  Set up the second 8259 interrupt processor.
-	 *  Make 8259 interrupts start at CPU vector VectorPIC+8.
-	 *  Set the 8259 as master with edge triggered
-	 *  input with fully nested interrupts.
-	 */
-	outb(Int1ctl, Icw1|0x01);	/* ICW1 - edge triggered, master,
-					   ICW4 will be sent */
-	outb(Int1aux, VectorPIC+8);	/* ICW2 - interrupt vector offset */
-	outb(Int1aux, 0x02);		/* ICW3 - I am a slave on level 2 */
-	outb(Int1aux, 0x01);		/* ICW4 - 8086 mode, not buffered */
-	outb(Int1aux, int1mask);
-
-	/*
-	 *  pass #2 8259 interrupts to #1
-	 */
-	int0mask &= ~0x04;
-	outb(Int0aux, int0mask);
-
-	/*
-	 * Set Ocw3 to return the ISR when ctl read.
-	 */
-	outb(Int0ctl, Ocw3|0x03);
-	outb(Int1ctl, Ocw3|0x03);
-
-	/*
-	 * Check for Edge/Level register.
-	 * This check may not work for all chipsets.
-	 * First try a non-intrusive test - the bits for
-	 * IRQs 13, 8, 2, 1 and 0 must be edge (0). If
-	 * that's OK try a R/W test.
-	 */
-	x = (inb(Elcr2)<<8)|inb(Elcr1);
-	if(!(x & 0x2107)){
-		outb(Elcr1, 0);
-		if(inb(Elcr1) == 0){
-			outb(Elcr1, 0x20);
-			if(inb(Elcr1) == 0x20)
-				i8259elcr = x;
-			outb(Elcr1, x & 0xFF);
-			print("ELCR: %4.4uX\n", i8259elcr);
-		}
-	}
-}
-
-/*
- *  dump registers
- */
-static void
-dumpregs(Ureg *ur)
-{
-	print("FLAGS=%lux TRAP=%lux ECODE=%lux PC=%lux\n",
-		ur->flags, ur->trap, ur->ecode, ur->pc);
-	print("  AX %8.8lux  BX %8.8lux  CX %8.8lux  DX %8.8lux\n",
-		ur->ax, ur->bx, ur->cx, ur->dx);
-	print("  SI %8.8lux  DI %8.8lux  BP %8.8lux\n",
-		ur->si, ur->di, ur->bp);
-	print("  CS %4.4lux DS %4.4lux  ES %4.4lux  FS %4.4lux  GS %4.4lux\n",
-		ur->cs & 0xFF, ur->ds & 0xFFFF, ur->es & 0xFFFF, ur->fs & 0xFFFF, ur->gs & 0xFFFF);
-	print("  CR0 %8.8lux CR2 %8.8lux CR3 %8.8lux\n",
-		getcr0(), getcr2(), getcr3());
-}
-
-/*
- *  All traps
- */
-void
-trap(Ureg *ur)
-{
-	int v;
-	int c;
-	Handler *h;
-	uint16_t isr;
-
-	v = ur->trap;
-	/*
-	 *  tell the 8259 that we're done with the
-	 *  highest level interrupt (interrupts are still
-	 *  off at this point)
-	 */
-	c = v&~0x7;
-	isr = 0;
-	if(c==VectorPIC || c==VectorPIC+8){
-		isr = inb(Int0ctl);
-		outb(Int0ctl, EOI);
-		if(c == VectorPIC+8){
-			isr |= inb(Int1ctl)<<8;
-			outb(Int1ctl, EOI);
-		}
-	}
-
-	if(v>=256 || (h = halloc.ivec[v]) == 0){
-		if(v >= VectorPIC && v < VectorPIC+16){
-			v -= VectorPIC;
-			/*
-			 * Check for a default IRQ7. This can happen when
-			 * the IRQ input goes away before the acknowledge.
-			 * In this case, a 'default IRQ7' is generated, but
-			 * the corresponding bit in the ISR isn't set.
-			 * In fact, just ignore all such interrupts.
-			 */
-			if(isr & (1<<v))
-				print("unknown interrupt %d pc=0x%lux\n", v, ur->pc);
-			return;
-		}
-
-		switch(v){
-
-		case 0x02:				/* NMI */
-			print("NMI: nmisc=0x%2.2ux, nmiertc=0x%2.2ux, nmiesc=0x%2.2ux\n",
-				inb(0x61), inb(0x70), inb(0x461));
-			return;
-
-		case 0x06:
-			{
-				uint8_t *p = (uint8_t*)(ur->pc-20);
-				int i;
-
-				for(i = 0; i < 40; i++){
-					print(" %2.2ux", *p);
-					p++;
-				}
-			}
-
-		default:
-			dumpregs(ur);
-			panic("exception/interrupt %d", v);
-			return;
-		}
-	}
-
-	/*
-	 *  call the trap routines
-	 */
-	do {
-		(*h->r)(ur, h->arg);
-		h = h->next;
-	} while(h);
-}

+ 0 - 36
sys/src/9/w/pxeload/ureg.h

@@ -1,36 +0,0 @@
-/* 
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
-
-typedef struct Ureg	Ureg;
-
-struct Ureg
-{
-	uint32_t	di;		/* general registers */
-	uint32_t	si;		/* ... */
-	uint32_t	bp;		/* ... */
-	uint32_t	nsp;
-	uint32_t	bx;		/* ... */
-	uint32_t	dx;		/* ... */
-	uint32_t	cx;		/* ... */
-	uint32_t	ax;		/* ... */
-	uint32_t	gs;		/* data segments */
-	uint32_t	fs;		/* ... */
-	uint32_t	es;		/* ... */
-	uint32_t	ds;		/* ... */
-	uint32_t	trap;		/* trap type */
-	uint32_t	ecode;		/* error code (or zero) */
-	uint32_t	pc;		/* pc */
-	uint32_t	cs;		/* old context */
-	uint32_t	flags;		/* old flags */
-	union {
-		uint32_t	usp;
-		uint32_t	sp;
-	};
-	uint32_t	ss;		/* old stack segment */
-};

+ 0 - 157
sys/src/9/w/pxeload/warp64.c

@@ -1,157 +0,0 @@
-/*
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
-
-#include "u.h"
-#include "lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-
-#include "mmu64.h"
-
-#define Pml4	0x00108000
-
-typedef unsigned long long u64intptr;
-
-#define u64ptr2int(p)	((u64intptr)(p))
-#define u64int2ptr(i)	((void*)(i))
-
-static u64intptr
-mach0ptalloc(int l)
-{
-	static u64intptr table = Pml4;
-	static int ntable = 6;
-
-	if(ntable <= 0)
-		return ~0ULL;
-
-	table += PGSIZE64;
-	memset(KADDR(table), 0, PGSIZE64);
-	ntable--;
-	if(vflag)
-		print("table[%d] used 0x%llux\n", l, table);
-
-	return table;
-}
-
-PTE*
-mmuwalk64(PTE* pml4, u64intptr va, int level, u64intptr (*alloc)(int))
-{
-	int l, idx;
-	PTE *pte;
-	u64intptr pa;
-
-	idx = PTEX64(va, 4);
-	pte = &pml4[idx];
-	for(l = 4; l > 0; l--){
-		if(vflag)
-			print("mmuwalk64 0x%p 0x%llux %d: entry %d\n",
-				pml4, va, l, idx);
-		if(l == level)
-			return pte;
-		if(l == 2 && (*pte & PtePS))
-			break;
-		if(!(*pte & PteP)){
-			if(alloc == nil)
-				break;
-			pa = alloc(l);
-			if(pa == ~0ULL)
-				break;
-			*pte = pa|PteRW|PteP;
-			if(vflag)
-				print("mmuwalk64 0x%p 0x%llux %d: alloc 0x%llux\n",
-					pml4, va, l, pa);
-		}
-		pte = u64int2ptr(KADDR(PPN64(*pte)));
-		idx = PTEX64(va, l-1);
-		pte += idx;
-	}
-
-	return nil;
-}
-
-void
-mkmach0pt(u64intptr kzero64)
-{
-	//u32int r;
-	u64intptr pa, va;
-	PTE *pml4, *pte, *pte0;
-	//uvlong uvlr;
-
-	pml4 = u64int2ptr(KADDR(Pml4));
-	if(vflag)
-		print("pml4 = %p\n", pml4);
-	memset(pml4, 0, PGSIZE64);
-
-	va = kzero64;
-	for(pa = 0; pa < 4*MiB; pa += 2*MiB){
-		pte = mmuwalk64(pml4, va, 2, mach0ptalloc);
-		*pte = (PPN64(pa))|PtePS|PteRW|PteP;
-		if(vflag)
-			print("va %#llux pte %#p *pte %#llux\n", va, pte, *pte);
-		va += 2*MiB;
-	}
-	pte = mmuwalk64(pml4, kzero64, 4, 0);
-	if(vflag)
-		print("pte l4 %llux == 0x%llux\n", kzero64, *pte);
-
-	pte0 = mmuwalk64(pml4, 0ULL, 2, mach0ptalloc);
-	pte0 += PTEX64(0, 2);
-	if(vflag)
-		print("pte0 l2 @ 0x%p  0 == 0x%llux\n", pte0, *pte0);
-	*pte0 = (PPN64(0))|PtePS|PteRW|PteP;
-	if(vflag)
-		print("pte0 l2 @ 0x%p  0 == 0x%llux\n", pte0, *pte0);
-
-	/*
-	 * Have to do this with paging turned off. Bugger.
-	r = getcr4();
-	r |= Pae;
-	putcr4(r);
-
-	r = getcr3();
-	putcr3(Pml4);
-
-	rdmsr(Efer, &uvlr);
-	uvlr |= Lme;
-	wrmsr(Efer, uvlr);
-	 */
-}
-
-void
-warp64(uint64_t entry)
-{
-	u64intptr kzero64;
-	extern void _warp64(ulong);
-
-//	kzero64 = KZERO64;
-//	if(entry != 0xFFFFFFFF80110000ULL){
-//		print("bad entry address %#llux\n", entry);
-//		return;
-//	}
-kzero64 = entry & ~0x000000000fffffffull;
-	print("warp64(%#llux) %#llux %d\n", entry, kzero64, nmmap);
-	if(vflag)
-		print("mkmultiboot\n");
-	mkmultiboot();
-	if(vflag)
-		print("mkmach0pt\n");
-	mkmach0pt(kzero64);
-	if(vflag)
-		print("impulse\n");
-
-	/*
-	 * No output after impulse().
-	 */
-	if(vflag)
-		print("_warp64\n");
-	impulse();
-	_warp64(Pml4);
-}

+ 0 - 168
sys/src/9/w/pxeload/x16.h

@@ -1,168 +0,0 @@
-/* 
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
-
-/*
- * Can't write 16-bit code for 8a without getting into
- * lots of bother, so define some simple commands and
- * output the code directly.
- *
- * N.B. CALL16(x) kills DI, so don't expect it to be
- * saved across calls.
- */
-#define rAX		0		/* rX  */
-#define rCX		1
-#define rDX		2
-#define rBX		3
-#define rSP		4		/* SP */
-#define rBP		5		/* BP */
-#define rSI		6		/* SI */
-#define rDI		7		/* DI */
-
-#define rAL		0		/* rL  */
-#define rCL		1
-#define rDL		2
-#define rBL		3
-#define rAH		4		/* rH */
-#define rCH		5
-#define rDH		6
-#define rBH		7
-
-#define rES		0		/* rS */
-#define rCS		1
-#define rSS		2
-#define rDS		3
-#define rFS		4
-#define rGS		5
-
-#define xSI		4		/* rI (index) */
-#define xDI		5
-#define xBP		6
-#define xBX		7
-
-#define rCR0		0		/* rC */
-#define rCR2		2
-#define rCR3		3
-#define rCR4		4
-
-#define OP(o, m, ro, rm)	BYTE $o;	/* op + modr/m byte */	\
-			BYTE $(((m)<<6)|((ro)<<3)|(rm))
-#define OPrm(o, r, m)	OP(o, 0x00, r, 0x06);	/* general r <-> m */	\
-			WORD $m;
-#define OPrr(o, r0, r1)	OP(o, 0x03, r0, r1);	/* general r -> r */
-
-#define LW(m, rX)	OPrm(0x8B, rX, m)	/* m -> rX */
-#define LXW(x, rI, r)	OP(0x8B, 0x02, r, rI);	/* x(rI) -> r */	\
-			WORD $x
-#define LBPW(x, r)	OP(0x8B, 0x02, r, xBP);	/* x(rBP) -> r */	\
-			WORD $x
-#define LB(m, rB)	OPrm(0x8A, rB, m)	/* m -> r[HL] */
-#define LXB(x, rI, r)	OP(0x8A, 0x01, r, rI);	/* x(rI) -> r */	\
-			BYTE $x
-#define LBPB(x, r)	OP(0x8A, 0x01, r, xBP);	/* x(rBP) -> r */	\
-			BYTE $x
-#define SW(rX, m)	OPrm(0x89, rX, m)	/* rX -> m */
-#define SXW(r, x, rI)	OP(0x89, 0x02, r, rI);	/* r -> x(rI) */	\
-			WORD $x
-#define SBPW(r, x)	OP(0x89, 0x02, r, xBP);	/* r -> x(rBP) */	\
-			WORD $(x)
-#define SBPWI(i, x)	OP(0xC7, 0x01, 0, xBP);	/* i -> x(rBP) */	\
-			BYTE $(x); WORD $(i)
-#define STB(rB, m)	OPrm(0x88, rB, m)	/* rB -> m */
-#define SXB(r, x, rI)	OP(0x88, 0x01, r, rI);	/* rB -> x(rI) */	\
-			BYTE $x
-#define SBPB(r, x)	OP(0x88, 0x01, r, xBP);	/* r -> x(rBP) */	\
-			BYTE $x
-#define SBPBI(i, x)	OP(0xC6, 0x01, 0, xBP);	/* i -> x(rBP) */	\
-			BYTE $(x); BYTE $(i)
-#define LWI(i, rX)	BYTE $(0xB8+rX);	/* i -> rX */		\
-			WORD $i;
-#define LBI(i, rB)	BYTE $(0xB0+rB);	/* i -> r[HL] */	\
-			BYTE $i
-
-#define MW(r0, r1)	OPrr(0x89, r0, r1)	/* r0 -> r1 */
-#define MFSR(rS, rX)	OPrr(0x8C, rS, rX)	/* rS -> rX */
-#define MTSR(rX, rS)	OPrr(0x8E, rS, rX)	/* rX -> rS */
-#define MFCR(rC, rX)	BYTE $0x0F;		/* rC -> rX */		\
-			OP(0x20, 0x03, rC, rX)
-#define MTCR(rX, rC)	BYTE $0x0F;		/* rX -> rC */		\
-			OP(0x22, 0x03, rC, rX)
-
-#define ADC(r0, r1)	OPrr(0x11, r0, r1)	/* r0 + r1 -> r1 */
-#define ADD(r0, r1)	OPrr(0x01, r0, r1)	/* r0 + r1 -> r1 */
-#define ADDI(i, r)	OP(0x81, 0x03, 0x00, r);/* i+r -> r */		\
-			WORD $i;
-#define AND(r0, r1)	OPrr(0x21, r0, r1)	/* r0&r1 -> r1 */
-#define ANDI(i, r)	OP(0x81, 0x03, 0x04, r);/* i&r -> r */		\
-			WORD $i;
-#define CLR(r)		OPrr(0x31, r, r)	/* r^r -> r */
-#define CLRB(r)		OPrr(0x30, r, r)	/* r^r -> r */
-#define CMP(r0, r1)	OPrr(0x39, r0, r1)	/* r1-r0 -> flags */
-#define CMPI(i, r)	OP(0x81, 0x03, 0x07, r);/* r-i -> flags */	\
-			WORD $i;
-#define CMPBR(r0, r1)	OPrr(0x38, r0, r1)	/* r1-r0 -> flags */
-#define DEC(r)		BYTE $(0x48|r)		/* r-1 -> r */
-#define DIV(r)		OPrr(0xF7, 0x06, r)	/* rDX:rAX/r -> rAX, rDX:rAX%r -> rDX */
-#define INC(r)		BYTE $(0x40|r)		/* r+1 -> r */
-#define MUL(r)		OPrr(0xF7, 0x04, r)	/* r*rAX -> rDX:rAX */
-#define IMUL(r0, r1)	BYTE $0x0F;		/* r0*r1 -> r1 */	\
-			OPrr(0xAF, r1, r0)	/* (signed) */
-#define OR(r0, r1)	OPrr(0x09, r0, r1)	/* r0|r1 -> r1 */
-#define ORB(r0, r1)	OPrr(0x08, r0, r1)	/* r0|r1 -> r1 */
-#define ORI(i, r)	OP(0x81, 0x03, 0x01, r);/* i|r -> r */		\
-			WORD $i;
-#define ROLI(i, r)	OPrr(0xC1, 0x00, r);	/* r<<>>i -> r */	\
-			BYTE $i;
-#define SHLI(i, r)	OPrr(0xC1, 0x04, r);	/* r<<i -> r */		\
-			BYTE $i;
-#define SHLBI(i, r)	OPrr(0xC0, 0x04, r);	/* r<<i -> r */		\
-			BYTE $i;
-#define SHRI(i, r)	OPrr(0xC1, 0x05, r);	/* r>>i -> r */		\
-			BYTE $i;
-#define SHRBI(i, r)	OPrr(0xC0, 0x05, r);	/* r>>i -> r */		\
-			BYTE $i;
-#define SUB(r0, r1)	OPrr(0x29, r0, r1)	/* r1-r0 -> r1 */
-#define SUBI(i, r)	OP(0x81, 0x03, 0x05, r);/* r-i -> r */		\
-			WORD $i;
-
-#define STOSW		STOSL
-
-#define CALL16(f)	LWI(f, rDI);		/* &f -> rDI */		\
-			BYTE $0xFF;		/* (*rDI) */		\
-			BYTE $0xD7;
-#define FARJUMP16(s, o)	BYTE $0xEA;		/* jump to ptr16:16 */	\
-			WORD $o; WORD $s
-#define FARJUMP32(s, o)	BYTE $0x66;		/* jump to ptr32:16 */	\
-			BYTE $0xEA; LONG $o; WORD $s
-#define	DELAY		BYTE $0xEB;		/* jmp .+2 */		\
-			BYTE $0x00
-#define BIOSCALL(b)	INT $b			/* INT $b */
-
-#define PEEKW		BYTE $0x26;		/* MOVW	rES:[rBX], rAX  */	\
-			BYTE $0x8B; BYTE $0x07
-#define POKEW		BYTE $0x26;		/* MOVW	rAX, rES:[rBX] */	\
-			BYTE $0x89; BYTE $0x07
-#define OUTPORTB(p, d)	LBI(d, rAL);		/* d -> I/O port p */	\
-			BYTE $0xE6;					\
-			BYTE $p; DELAY
-#define PUSHA		BYTE $0x60
-#define PUSHR(r)	BYTE $(0x50|r)		/* r  -> (--rSP) */
-#define PUSHS(rS)	BYTE $(0x06|((rS)<<3))	/* rS  -> (--rSP) */
-#define PUSHI(i)	BYTE $0x68; WORD $i;	/* i -> --(rSP) */
-#define POPA		BYTE $0x61
-#define POPR(r)		BYTE $(0x58|r)		/* (rSP++) -> r */
-#define POPS(rS)	BYTE $$(0x07|((rS)<<3))	/* (rSP++) -> r */
-#define NOP		BYTE $0x90		/* nop */
-
-#define LGDT(gdtptr)	BYTE $0x0F;		/* LGDT */			\
-			BYTE $0x01; BYTE $0x16;					\
-			WORD $gdtptr
-
-/* operand size switch. */
-#define OPSIZE		BYTE $0x66
-

+ 0 - 1
sys/src/9/w/words

@@ -1 +0,0 @@
-this should go away in favour of 9boot

+ 0 - 20
sys/src/boot/mkfile

@@ -1,20 +0,0 @@
-ARCH=\
-	pc\
-
-all:V:
-	for(i in $ARCH)@{
-		cd $i
-		mk
-	}
-
-installall install:V:
-	for(i in $ARCH) @{
-		cd $i
-		mk install
-	}
-
-clean:V:
-	for(i in $ARCH) @{
-		cd $i
-		mk clean
-	}

+ 0 - 71
sys/src/boot/pc/dosfs.h

@@ -1,71 +0,0 @@
-/*
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
-
-typedef struct Dosboot	Dosboot;
-typedef struct Dos	Dos;
-typedef struct Dosdir	Dosdir;
-typedef struct Dosfile	Dosfile;
-typedef struct Dospart	Dospart;
-
-struct Dospart
-{
-	uchar flag;		/* active flag */
-	uchar shead;		/* starting head */
-	uchar scs[2];		/* starting cylinder/sector */
-	uchar type;		/* partition type */
-	uchar ehead;		/* ending head */
-	uchar ecs[2];		/* ending cylinder/sector */
-	uchar start[4];		/* starting sector */
-	uchar len[4];		/* length in sectors */
-};
-
-#define FAT12	0x01
-#define FAT16	0x04
-#define EXTEND	0x05
-#define FATHUGE	0x06
-#define FAT32	0x0b
-#define FAT32X	0x0c
-#define EXTHUGE	0x0f
-#define DMDDO	0x54
-#define PLAN9	0x39
-#define LEXTEND 0x85
-
-struct Dosfile{
-	Dos	*dos;		/* owning dos file system */
-	char	name[8];
-	char	ext[3];
-	uchar	attr;
-	long	length;
-	long	pstart;		/* physical start cluster address */
-	long	pcurrent;	/* physical current cluster address */
-	long	lcurrent;	/* logical current cluster address */
-	long	offset;
-};
-
-struct Dos{
-	long	start;		/* start of file system */
-	int	sectsize;	/* in bytes */
-	int	clustsize;	/* in sectors */
-	int	clustbytes;	/* in bytes */
-	int	nresrv;		/* sectors */
-	int	nfats;		/* usually 2 */
-	int	rootsize;	/* number of entries */
-	int	volsize;	/* in sectors */
-	int	mediadesc;
-	int	fatsize;	/* in sectors */
-	int	fatclusters;
-	int	fatbits;	/* 12 or 16 */
-	long	fataddr;	/* sector number */
-	long	rootaddr;
-	long	rootclust;
-	long	dataaddr;
-	long	freeptr;
-};
-
-extern int	dosinit(Fs*);

+ 0 - 258
sys/src/boot/pc/mbr.s

@@ -1,258 +0,0 @@
-/*
- * Hard disc boot block. Loaded at 0x7C00, relocates to 0x0600:
- *	8a mbr.s; 8l -o mbr -l -H3 -T0x0600 mbr.8
- */
-#include "x16.h"
-
-/*#define FLOPPY	1		/* test on a floppy */
-#define TRACE(C)	PUSHA;\
-			CLR(rBX);\
-			MOVB $C, AL;\
-			LBI(0x0E, rAH);\
-			BIOSCALL(0x10);\
-			POPA
-
-/*
- * We keep data on the stack, indexed by BP.
- */
-#define Xdap		0x00		/* disc address packet */
-#define Xtable		0x10		/* partition table entry */
-#define Xdrive		0x12		/* starting disc */
-#define Xtotal		0x14		/* sum of allocated data above */
-
-/*
- * Start: loaded at 0000:7C00, relocate to 0000:0600.
- * Boot drive is in rDL.
- */
-TEXT _start(SB), $0
-	CLI
-	CLR(rAX)
-	MTSR(rAX, rSS)			/* 0000 -> rSS */
-	LWI((0x7C00-Xtotal), rSP)	/* 7Bxx -> rSP */
-	MW(rSP, rBP)			/* set the indexed-data pointer */
-
-	MTSR(rAX, rDS)			/* 0000 -> rDS, source segment */
-	LWI(0x7C00, rSI)		/* 7C00 -> rSI, source offset */
-	MTSR(rAX, rES)			/* 0000 -> rES, destination segment */
-	LWI(0x600, rDI)			/* 0600 -> rDI, destination offset */
-	LWI(0x100, rCX)			/* 0100 -> rCX, loop count (words) */
-
-	CLD
-	REP; MOVSL			/* MOV DS:[(E)SI] -> ES:[(E)DI] */
-
-	FARJUMP16(0x0000, _start0600(SB))
-
-TEXT _start0600(SB), $0
-#ifdef FLOPPY
-	LBI(0x80, rDL)
-#else
-	CLRB(rAL)			/* some systems pass 0 */
-	CMPBR(rAL, rDL)
-	JNE _save
-	LBI(0x80, rDL)
-#endif /* FLOPPY */
-_save:
-	SXB(rDL, Xdrive, xBP)		/* save disc */
-
-	LWI(confidence(SB), rSI)	/* for that warm, fuzzy feeling */
-	CALL16(BIOSputs(SB))
-
-	LWI(_start+0x01BE(SB), rSI)	/* address of partition table */
-	LWI(0x04, rCX)			/* 4 entries in table */
-	LBI(0x80, rAH)			/* active entry value */
-	CLRB(rAL)			/* inactive entry value */
-
-_activeloop0:
-	LXB(0x00, xSI, rBL)		/* get active entry from table */
-	CMPBR(rBL, rAH)			/* is this an active entry? */
-	JEQ _active
-
-	CMPBR(rBL, rAL)			/* if not active it should be 0 */
-	JNE _invalidMBR
-
-	ADDI(0x10, rSI)			/* next table entry */
-	DEC(rCX)
-	JNE _activeloop0
-
-	LWI(noentry(SB), rSI)
-	CALL16(buggery(SB))
-
-_active:
-	MW(rSI, rDI)			/* save table address */
-
-_activeloop1:
-	ADDI(0x10, rSI)			/* next table entry */
-	DEC(rCX)
-	JEQ _readsector
-
-	LXB(0x00, xSI, rBL)		/* get active entry from table */
-	CMPBR(rBL, rAH)			/* is this an active entry? */
-	JNE _activeloop1		/* should only be one active */
-
-_invalidMBR:
-	LWI(invalidMBR(SB), rSI)
-	CALL16(buggery(SB))
-
-_readsector:
-	LBI(0x41, rAH)			/* check extensions present */
-	LWI(0x55AA, rBX)
-	LXB(Xdrive, xBP, rDL)		/* drive */
-	BIOSCALL(0x13)			/* CF set on failure */
-	JCS _readsector2
-	CMPI(0xAA55, rBX)
-	JNE _readsector2
-	ANDI(0x0001, rCX)
-	JEQ _readsector2
-
-_readsector42:
-	SBPBI(0x10, Xdap+0)		/* packet size */
-	SBPBI(0x00, Xdap+1)		/* reserved */
-	SBPBI(0x01, Xdap+2)		/* number of blocks to transfer */
-	SBPBI(0x00, Xdap+3)		/* reserved */
-	SBPWI(0x7C00, Xdap+4)		/* transfer buffer :offset */
-	SBPWI(0x0000, Xdap+6)		/* transfer buffer seg: */
-	LXW(0x08, xDI, rAX)		/* LBA (64-bits) */
-	SBPW(rAX, Xdap+8)
-	LXW(0x0A, xDI, rAX)
-	SBPW(rAX, Xdap+10)
-	SBPWI(0x0000, Xdap+12)
-	SBPWI(0x0000, Xdap+14)
-
-	MW(rBP, rSI)			/* disk address packet */
-	LBI(0x42, rAH)			/* extended read */
-	BIOSCALL(0x13)			/* CF set on failure */
-	JCC _readsectorok
-
-	LWI(ioerror(SB), rSI)
-	CALL16(buggery(SB))
-
-/*
- * Read a sector from a disc using the traditional BIOS call.
- * For BIOSCALL(0x13/AH=0x02):
- *   rAH	0x02
- *   rAL	number of sectors to read (1)
- *   rCH	low 8 bits of cylinder
- *   rCL	high 2 bits of cylinder (7-6), sector (5-0)
- *   rDH	head
- *   rDL	drive
- *   rES:rBX	buffer address
- */
-_readsector2:
-	LXB(0x01, xDI, rDH)		/* head */
-	LXW(0x02, xDI, rCX)		/* save active cylinder/sector */
-
-	LWI(0x0201, rAX)		/* read one sector */
-	LXB(Xdrive, xBP, rDL)		/* drive */
-	LWI(0x7C00, rBX)		/* buffer address (rES already OK) */
-	BIOSCALL(0x13)			/* CF set on failure */
-	JCC _readsectorok
-
-	LWI(ioerror(SB), rSI)
-	CALL16(buggery(SB))
-
-_readsectorok:
-	LWI(0x7C00, rBX)		/* buffer address (rES already OK) */
-	LXW(0x1FE, xBX, rAX)
-	CMPI(0xAA55, rAX)
-	JNE _bbnotok
-
-	/*
-	 * Jump to the loaded PBS.
-	 * rDL and rSI should still contain the drive
-	 * and partition table pointer respectively.
-	 */
-	MW(rDI, rSI)
-	FARJUMP16(0x0000, 0x7C00)
-
-_bbnotok:
-	LWI(invalidPBS(SB), rSI)
-
-TEXT buggery(SB), $0
-	CALL16(BIOSputs(SB))
-	LWI(reboot(SB), rSI)
-	CALL16(BIOSputs(SB))
-
-_wait:
-	CLR(rAX)			/* wait for any key */
-	BIOSCALL(0x16)
-
-_reset:
-	CLR(rBX)			/* set ES segment for BIOS area */
-	MTSR(rBX, rES)
-
-	LWI(0x0472, rBX)		/* warm-start code address */
-	LWI(0x1234, rAX)		/* warm-start code */
-	POKEW				/* MOVW	AX, ES:[BX] */
-
-	FARJUMP16(0xFFFF, 0x0000)	/* reset */
-
-/*
- * Output a string to the display.
- * String argument is in rSI.
- */
-TEXT BIOSputs(SB), $0
-	PUSHA
-	CLR(rBX)
-_BIOSputs:
-	LODSB
-	ORB(rAL, rAL)
-	JEQ _BIOSputsret
-
-	LBI(0x0E, rAH)
-	BIOSCALL(0x10)
-	JMP _BIOSputs
-
-_BIOSputsret:
-	POPA
-	RET
-
-/* "No active entry in MBR" */
-TEXT noentry(SB), $0
-	BYTE $'N'; BYTE $'o'; BYTE $' '; BYTE $'a';
-	BYTE $'c'; BYTE $'t'; BYTE $'i'; BYTE $'v';
-	BYTE $'e'; BYTE $' '; BYTE $'e'; BYTE $'n';
-	BYTE $'t'; BYTE $'r'; BYTE $'y'; BYTE $' ';
-	BYTE $'i'; BYTE $'n'; BYTE $' '; BYTE $'M';
-	BYTE $'B'; BYTE $'R';
-	BYTE $'\z';
-
-/* "Invalid MBR" */
-TEXT invalidMBR(SB), $0
-	BYTE $'I'; BYTE $'n'; BYTE $'v'; BYTE $'a';
-	BYTE $'l'; BYTE $'i'; BYTE $'d'; BYTE $' ';
-	BYTE $'M'; BYTE $'B'; BYTE $'R';
-	BYTE $'\z';
-
-/* "I/O error" */
-TEXT ioerror(SB), $0
-	BYTE $'I'; BYTE $'/'; BYTE $'O'; BYTE $' ';
-	BYTE $'e'; BYTE $'r'; BYTE $'r'; BYTE $'o';
-	BYTE $'r';
-	BYTE $'\z';
-
-/* "Invalid PBS" */
-TEXT invalidPBS(SB), $0
-	BYTE $'I'; BYTE $'n'; BYTE $'v'; BYTE $'a';
-	BYTE $'l'; BYTE $'i'; BYTE $'d'; BYTE $' ';
-	BYTE $'P'; BYTE $'B'; BYTE $'S';
-	BYTE $'\z';
-
-/* "\r\nPress almost any key to reboot..." */
-TEXT reboot(SB), $0
-	BYTE $'\r';BYTE $'\n';
-	BYTE $'P'; BYTE $'r'; BYTE $'e'; BYTE $'s';
-	BYTE $'s'; BYTE $' '; BYTE $'a'; BYTE $'l'; 
-	BYTE $'m'; BYTE $'o'; BYTE $'s'; BYTE $'t';
-	BYTE $' '; BYTE $'a'; BYTE $'n'; BYTE $'y';
-	BYTE $' '; BYTE $'k'; BYTE $'e'; BYTE $'y';
-	BYTE $' '; BYTE $'t'; BYTE $'o'; BYTE $' ';
-	BYTE $'r'; BYTE $'e'; BYTE $'b'; BYTE $'o';
-	BYTE $'o'; BYTE $'t'; BYTE $'.'; BYTE $'.';
-	BYTE $'.';
-	BYTE $'\z';
-
-/* "MBR..." */
-TEXT confidence(SB), $0
-	BYTE $'M'; BYTE $'B'; BYTE $'R'; BYTE $'.';
-	BYTE $'.'; BYTE $'.';
-	BYTE $'\z';

+ 0 - 62
sys/src/boot/pc/mkfile

@@ -1,62 +0,0 @@
-objtype=386
-</$objtype/mkfile
-BIN=/386
-EXTRACOPIES=
-
-TARG=\
-	mbr\
-	pbs\
-	pbslba\
-	pbsraw\
-
-HFILES=\
-	x16.h\
-
-all:V:	$TARG
-
-%.$O:	%.s
-	$AS $stem.s
-
-%.$O:	$HFILES
-
-mbr:	mbr.$O
-	$LD -o $target -H3 -T0x0600 -l $prereq
-	ls -l $target
-
-pbs&:	pbs%.$O
-	$LD -o $target -H3 -T0x7C00 -l $prereq
-	ls -l $target
-
-pbs&.debug:	pbs%.$O
-	$LD -o $target -T0x7C00 -l $prereq
-	ls -l $target
-	# acid $target
-	# map({"text", 0x7C00, 0x7E00, 0x00000020})
-	
-clean:
-	rm -f *.[$OS] [$OS].out y.tab.? y.debug y.output $TARG
-
-install:V:
-	for (i in $TARG)
-		mk $MKFLAGS $i.install
-
-%.install:V:	$BIN/%
-	for (fs in $EXTRACOPIES)
-		9fs $fs && cp $prereq /n/$fs/$prereq
-
-$BIN/%:	%
-	cp $stem $BIN/$stem
-
-UPDATE=\
-	mkfile\
-	$HFILES\
-	l.s\
-	pbs.s\
-	pbslba.s\
-	mbr.s\
-	x16.h\
-	${TARG:%=/386/%}\
-
-update:V:
-	update $UPDATEFLAGS $UPDATE
-

+ 0 - 371
sys/src/boot/pc/pbs.s

@@ -1,371 +0,0 @@
-/*
- * FAT Partition Boot Sector. Loaded at 0x7C00:
- *	8a pbs.s; 8l -o pbs -l -H3 -T0x7C00 pbs.8
- * Will load the target at LOADSEG*16+LOADOFF, so the target
- * should be probably be loaded with LOADOFF added to the
- * -Taddress.
- * If LOADSEG is a multiple of 64KB and LOADOFF is 0 then
- * targets larger than 64KB can be loaded.
- *
- * This code uses the traditional INT13 BIOS interface and can
- * therefore only access the first 8.4GB of the disc.
- *
- * It relies on the _volid field in the FAT header containing
- * the LBA of the root directory.
- */
-#include "x16.h"
-
-#define LOADSEG		(0x10000/16)	/* where to load code (64KB) */
-#define LOADOFF		0
-#define DIROFF		0x0200		/* where to read the root directory */
-
-/*
- * FAT directory entry.
- */
-#define Dname		0x00
-#define Dext		0x08
-#define Dattr		0x0B
-#define Dtime		0x16
-#define Ddate		0x18
-#define Dstart		0x1A
-#define Dlengthlo	0x1C
-#define Dlengthhi	0x1E
-
-#define Dirsz		0x20
-
-/*
- * Data is kept on the stack, indexed by rBP.
- */
-#define Xdap		0x00		/* disc address packet */
-#define Xrootsz		0x10		/* file data area */
-#define Xdrive		0x12		/* boot drive, passed by BIOS or MBR */
-#define Xtotal		0x14		/* sum of allocated data above */
-
-TEXT _magic(SB), $0
-	BYTE $0xEB; BYTE $0x3C;		/* jmp .+ 0x3C  (_start0x3E) */
-	BYTE $0x90			/* nop */
-TEXT _version(SB), $0
-	BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00;
-	BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00
-TEXT _sectsize(SB), $0
-	BYTE $0x00; BYTE $0x00
-TEXT _clustsize(SB), $0
-	BYTE $0x00
-TEXT _nresrv(SB), $0
-	BYTE $0x00; BYTE $0x00
-TEXT _nfats(SB), $0
-	BYTE $0x00
-TEXT _rootsize(SB), $0
-	BYTE $0x00; BYTE $0x00
-TEXT _volsize(SB), $0
-	BYTE $0x00; BYTE $0x00
-TEXT _mediadesc(SB), $0
-	BYTE $0x00
-TEXT _fatsize(SB), $0
-	BYTE $0x00; BYTE $0x00
-TEXT _trksize(SB), $0
-	BYTE $0x00; BYTE $0x00
-TEXT _nheads(SB), $0
-	BYTE $0x00; BYTE $0x00
-TEXT _nhiddenlo(SB), $0
-	BYTE $0x00; BYTE $0x00
-TEXT _nhiddenhi(SB), $0
-	BYTE $0x00; BYTE $0x00;
-TEXT _bigvolsize(SB), $0
-	BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00;
-TEXT _driveno(SB), $0
-	BYTE $0x00
-TEXT _reserved0(SB), $0
-	BYTE $0x00
-TEXT _bootsig(SB), $0
-	BYTE $0x00
-TEXT _volid(SB), $0
-	BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00;
-TEXT _label(SB), $0
-	BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00;
-	BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00
-	BYTE $0x00; BYTE $0x00; BYTE $0x00
-TEXT _type(SB), $0
-	BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00;
-	BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00;
-
-_start0x3E:
-	CLI
-	CLR(rAX)
-	MTSR(rAX, rSS)			/* 0000 -> rSS */
-	MTSR(rAX, rDS)			/* 0000 -> rDS, source segment */
-	MTSR(rAX, rES)
-	LWI(_magic-Xtotal(SB), rSP)
-	MW(rSP, rBP)			/* set the indexed-data pointer */
-
-	SBPB(rDL, Xdrive)		/* save the boot drive */
-
-	/* booting from a CD starts us at 7C0:0.  Move to 0:7C00 */
-	PUSHR(rAX)
-	LWI(_nxt(SB), rAX)
-	PUSHR(rAX)
-	BYTE $0xCB	/* FAR RET */
-
-TEXT _nxt(SB), $0
-	STI
-
-	LWI(confidence(SB), rSI)	/* for that warm, fuzzy feeling */
-	CALL16(BIOSputs(SB))
-
-	CALL16(dreset(SB))
-
-_jmp00:
-	LW(_volid(SB), rAX)		/* Xrootlo */
-	LW(_volid+2(SB), rDX)		/* Xroothi */
-
-	LWI(_magic+DIROFF(SB), rBX)
-	CALL16(BIOSread(SB))		/* read the root directory */
-
-	LWI((512/Dirsz), rBX)
-
-	LWI(_magic+DIROFF(SB), rDI)	/* compare first directory entry */
-
-_cmp00:
-	PUSHR(rDI)			/* save for later if it matches */
-	LWI(bootfile(SB), rSI)
-	LWI(Dattr, rCX)
-	REP
-	CMPSB
-	POPR(rDI)
-	JEQ _jmp02
-
-	DEC(rBX)
-	JEQ _jmp01
-
-	ADDI(Dirsz, rDI)
-	JMP _cmp00
-_jmp01:
-	CALL16(buggery(SB))
-
-_jmp02:
-	CLR(rBX)			/* a handy value */
-	LW(_rootsize(SB), rAX)		/* calculate and save Xrootsz */
-	LWI(Dirsz, rCX)
-	MUL(rCX)
-	LW(_sectsize(SB), rCX)
-	PUSHR(rCX)
-	DEC(rCX)
-	ADD(rCX, rAX)
-	ADC(rBX, rDX)
-	POPR(rCX)			/* _sectsize(SB) */
-	DIV(rCX)
-	PUSHR(rAX)			/* Xrootsz */
-
-	/*
-	 * rDI points to the matching directory entry.
-	 */
-	LXW(Dstart, xDI, rAX)		/* starting sector address */
-	DEC(rAX)			/* that's just the way it is */
-	DEC(rAX)
-	LB(_clustsize(SB), rCL)
-	CLRB(rCH)
-	MUL(rCX)
-	LW(_volid(SB), rCX)		/* Xrootlo */
-	ADD(rCX, rAX)
-	LW(_volid+2(SB), rCX)		/* Xroothi */
-	ADC(rCX, rDX)
-	POPR(rCX)			/* Xrootsz */
-	ADD(rCX, rAX)
-	ADC(rBX, rDX)
-
-	PUSHR(rAX)			/* calculate how many sectors to read */
-	PUSHR(rDX)
-	LXW(Dlengthlo, xDI, rAX)
-	LXW(Dlengthhi, xDI, rDX)
-	LW(_sectsize(SB), rCX)
-	PUSHR(rCX)
-	DEC(rCX)
-	ADD(rCX, rAX)
-	ADC(rBX, rDX)
-	POPR(rCX)			/* _sectsize(SB) */
-	DIV(rCX)
-	MW(rAX, rCX)
-	POPR(rDX)
-	POPR(rAX)
-
-	LWI(LOADSEG, rBX)		/* address to load into (seg+offset) */
-	MTSR(rBX, rES)			/*  seg */
-	LWI(LOADOFF, rBX)		/*  offset */
-
-_readboot:
-	CALL16(BIOSread(SB))		/* read the sector */
-
-	LW(_sectsize(SB), rDI)		/* bump addresses/counts */
-	ADD(rDI, rBX)
-	JCC _incsecno
-
-	MFSR(rES, rDI)			/* next 64KB segment */
-	ADDI(0x1000, rDI)
-	MTSR(rDI, rES)
-
-_incsecno:
-	CLR(rDI)
-	INC(rAX)
-	ADC(rDI, rDX)
-	LOOP _readboot
-
-	LWI(LOADSEG, rDI)		/* set rDS for loaded code */
-	MTSR(rDI, rDS)
-	FARJUMP16(LOADSEG, LOADOFF)	/* no deposit, no return */
-
-TEXT buggery(SB), $0
-	LWI(error(SB), rSI)
-	CALL16(BIOSputs(SB))
-
-_wait:
-	CLR(rAX)			/* wait for almost any key */
-	BIOSCALL(0x16)
-
-_reset:
-	CLR(rBX)			/* set ES segment for BIOS area */
-	MTSR(rBX, rES)
-
-	LWI(0x0472, rBX)		/* warm-start code address */
-	LWI(0x1234, rAX)		/* warm-start code */
-	POKEW				/* MOVW	AX, ES:[BX] */
-
-	FARJUMP16(0xFFFF, 0x0000)	/* reset */
-
-/*
- * Read a sector from a disc. On entry:
- *   rDX:rAX	sector number
- *   rES:rBX	buffer address
- * For BIOSCALL(0x13):
- *   rAH	0x02
- *   rAL	number of sectors to read (1)
- *   rCH	low 8 bits of cylinder
- *   rCL	high 2 bits of cylinder (7-6), sector (5-0)
- *   rDH	head
- *   rDL	drive
- *   rES:rBX	buffer address
- */
-TEXT BIOSread(SB), $0
-	LWI(5, rDI)			/* retry count (ATAPI ZIPs suck) */
-_retry:
-	PUSHA				/* may be trashed by BIOSCALL */
-	PUSHR(rBX)
-
-	LW(_trksize(SB), rBX)
-	LW(_nheads(SB), rDI)
-	IMUL(rDI, rBX)
-	OR(rBX, rBX)
-	JZ _ioerror
-
-_okay:
-	DIV(rBX)			/* cylinder -> rAX, track,sector -> rDX */
-
-	MW(rAX, rCX)			/* save cylinder */
-	ROLI(0x08, rCX)			/* swap rC[HL] */
-	SHLBI(0x06, rCL)		/* move high bits up */
-
-	MW(rDX, rAX)
-	CLR(rDX)
-	LW(_trksize(SB), rBX)
-
-	DIV(rBX)			/* head -> rAX, sector -> rDX */
-
-	INC(rDX)			/* sector numbers are 1-based */
-	ANDI(0x003F, rDX)		/* should not be necessary */
-	OR(rDX, rCX)
-
-	MW(rAX, rDX)
-	SHLI(0x08, rDX)			/* form head */
-	LBPB(Xdrive, rDL)		/* form drive */
-
-	POPR(rBX)
-	LWI(0x0201, rAX)		/* form command and sectors */
-	BIOSCALL(0x13)			/* CF set on failure */
-	JCC _BIOSreadret
-
-	POPA
-	DEC(rDI)			/* too many retries? */
-	JEQ _ioerror
-
-	CALL16(dreset(SB))
-	JMP _retry
-
-_ioerror:
-	LWI(ioerror(SB), rSI)
-	CALL16(BIOSputs(SB))
-	JMP _wait
-
-_BIOSreadret:
-	POPA
-	RET
-
-TEXT dreset(SB), $0
-	PUSHA
-	CLR(rAX)			/* rAH == 0 == reset disc system */
-	LBPB(Xdrive, rDL)
-	BIOSCALL(0x13)
-	ORB(rAH, rAH)			/* status (0 == success) */
-	POPA
-	JNE _ioerror
-	RET
-
-/*
- * Output a string to the display.
- * String argument is in rSI.
- */
-TEXT BIOSputs(SB), $0
-	PUSHA
-	CLR(rBX)
-_BIOSputs:
-	LODSB
-	ORB(rAL, rAL)
-	JEQ _BIOSputsret
-
-	LBI(0x0E, rAH)
-	BIOSCALL(0x10)
-	JMP _BIOSputs
-
-_BIOSputsret:
-	POPA
-	RET
-
-/* "Bad format or I/O error\r\nPress almost any key to reboot..."*/
-TEXT error(SB), $0
-	BYTE $'B'; BYTE $'a'; BYTE $'d'; BYTE $' ';
-	BYTE $'f'; BYTE $'o'; BYTE $'r'; BYTE $'m';
-	BYTE $'a'; BYTE $'t'; BYTE $' '; BYTE $'o';
-	BYTE $'r'; BYTE $' ';
-/* "I/O error\r\nPress almost any key to reboot..." */
-TEXT ioerror(SB), $0
-	BYTE $'I'; BYTE $'/'; BYTE $'O'; BYTE $' ';
-	BYTE $'e'; BYTE $'r'; BYTE $'r'; BYTE $'o';
-	BYTE $'r'; BYTE $'\r';BYTE $'\n';
-	BYTE $'P'; BYTE $'r'; BYTE $'e'; BYTE $'s';
-	BYTE $'s'; BYTE $' '; BYTE $'a'; BYTE $' ';
-	BYTE $'k'; BYTE $'e'; BYTE $'y';
-	BYTE $' '; BYTE $'t'; BYTE $'o'; BYTE $' ';
-	BYTE $'r'; BYTE $'e'; BYTE $'b'; BYTE $'o';
-	BYTE $'o'; BYTE $'t';
-	BYTE $'.'; BYTE $'.'; BYTE $'.';
-	BYTE $'\z';
-
-#ifdef USEBCOM
-/* "B       COM" */
-TEXT bootfile(SB), $0
-	BYTE $'B'; BYTE $' '; BYTE $' '; BYTE $' ';
-	BYTE $' '; BYTE $' '; BYTE $' '; BYTE $' ';
-	BYTE $'C'; BYTE $'O'; BYTE $'M';
-	BYTE $'\z';
-#else
-/* "9LOAD      " */
-TEXT bootfile(SB), $0
-	BYTE $'9'; BYTE $'L'; BYTE $'O'; BYTE $'A';
-	BYTE $'D'; BYTE $' '; BYTE $' '; BYTE $' ';
-	BYTE $' '; BYTE $' '; BYTE $' ';
-	BYTE $'\z';
-#endif /* USEBCOM */
-
-/* "PBS..." */
-TEXT confidence(SB), $0
-	BYTE $'P'; BYTE $'B'; BYTE $'S'; BYTE $'1'; 
-	BYTE $'.'; BYTE $'.'; BYTE $'.';
-	BYTE $'\z';

+ 0 - 344
sys/src/boot/pc/pbsdebug.s

@@ -1,344 +0,0 @@
-/*
- * Debugging boot sector.  Reads the first directory
- * sector from disk and displays it.
- *
- * It relies on the _volid field in the FAT header containing
- * the LBA of the root directory.
- */
-#include "x16.h"
-
-#define DIROFF		0x00200		/* where to read the root directory (offset) */
-#define LOADSEG		(0x10000/16)	/* where to load code (64KB) */
-#define LOADOFF		0
-
-/*
- * FAT directory entry.
- */
-#define Dname		0x00
-#define Dext		0x08
-#define Dattr		0x0B
-#define Dtime		0x16
-#define Ddate		0x18
-#define Dstart		0x1A
-#define Dlengthlo	0x1C
-#define Dlengthhi	0x1E
-
-#define Dirsz		0x20
-
-/*
- * We keep data on the stack, indexed by rBP.
- */
-#define Xdrive		0x00		/* boot drive, passed by BIOS in rDL */
-#define Xrootlo		0x02		/* offset of root directory */
-#define Xroothi		0x04
-#define Xrootsz		0x06		/* file data area */
-#define Xtotal		0x08		/* sum of allocated data above */
-#define Xdap		0x00		/* disc address packet */
-
-TEXT _magic(SB), $0
-	BYTE $0xEB; BYTE $0x3C;		/* jmp .+ 0x3C  (_start0x3E) */
-	BYTE $0x90			/* nop */
-TEXT _version(SB), $0
-	BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00;
-	BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00
-TEXT _sectsize(SB), $0
-	BYTE $0x00; BYTE $0x00
-TEXT _clustsize(SB), $0
-	BYTE $0x00
-TEXT _nresrv(SB), $0
-	BYTE $0x00; BYTE $0x00
-TEXT _nfats(SB), $0
-	BYTE $0x00
-TEXT _rootsize(SB), $0
-	BYTE $0x00; BYTE $0x00
-TEXT _volsize(SB), $0
-	BYTE $0x00; BYTE $0x00
-TEXT _mediadesc(SB), $0
-	BYTE $0x00
-TEXT _fatsize(SB), $0
-	BYTE $0x00; BYTE $0x00
-TEXT _trksize(SB), $0
-	BYTE $0x00; BYTE $0x00
-TEXT _nheads(SB), $0
-	BYTE $0x00; BYTE $0x00
-TEXT _nhiddenlo(SB), $0
-	BYTE $0x00; BYTE $0x00
-TEXT _nhiddenhi(SB), $0
-	BYTE $0x00; BYTE $0x00;
-TEXT _bigvolsize(SB), $0
-	BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00;
-TEXT _driveno(SB), $0
-	BYTE $0x00
-TEXT _reserved0(SB), $0
-	BYTE $0x00
-TEXT _bootsig(SB), $0
-	BYTE $0x00
-TEXT _volid(SB), $0
-	BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00;
-TEXT _label(SB), $0
-	BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00;
-	BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00
-	BYTE $0x00; BYTE $0x00; BYTE $0x00
-TEXT _type(SB), $0
-	BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00;
-	BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00;
-
-_start0x3E:
-	CLI
-	CLR(rAX)
-	MTSR(rAX, rSS)			/* 0000 -> rSS */
-	MTSR(rAX, rDS)			/* 0000 -> rDS, source segment */
-	MTSR(rAX, rES)
-	LWI(_magic-Xtotal(SB), rSP)
-	MW(rSP, rBP)			/* set the indexed-data pointer */
-	SBPB(rDL, Xdrive)		/* save the boot drive */
-
-	/* VMware starts us at 7C0:0.  Move to 0:7C00 */
-	PUSHR(rAX)
-	LWI(_nxt(SB), rAX)
-	PUSHR(rAX)
-	BYTE $0xCB	/* FAR RET */
-
-TEXT _nxt(SB), $0
-	STI
-	LWI(confidence(SB), rSI)	/* for that warm, fuzzy feeling */
-	CALL16(BIOSputs(SB))
-
-	CALL16(dreset(SB))
-
-_jmp00:
-	LW(_volid(SB), rAX)		/* Xrootlo */
-	LW(_volid+2(SB), rDX)		/* Xroothi */
-
-	LWI(_magic+DIROFF(SB), rBX)
-	CALL16(BIOSread(SB))		/* read the root directory */
-
-	CALL16(printnl(SB))
-	LWI(_magic+DIROFF(SB), rBX)
-	LWI((512/2), rCX)
-	CALL16(printbuf(SB))
-
-xloop:
-	JMP xloop
-
-
-TEXT buggery(SB), $0
-	LWI(error(SB), rSI)
-	CALL16(BIOSputs(SB))
-
-TEXT quietbuggery(SB), $0
-xbuggery:
-	JMP xbuggery
-
-/*
- * Read a sector from a disc. On entry:
- *   rDX:rAX	sector number
- *   rES:rBX	buffer address
- * For BIOSCALL(0x13):
- *   rAH	0x02
- *   rAL	number of sectors to read (1)
- *   rCH	low 8 bits of cylinder
- *   rCL	high 2 bits of cylinder (7-6), sector (5-0)
- *   rDH	head
- *   rDL	drive
- *   rES:rBX	buffer address
- */
-TEXT BIOSread(SB), $0
-	LWI(5, rDI)			/* retry count (ATAPI ZIPs suck) */
-_retry:
-	PUSHA				/* may be trashed by BIOSCALL */
-	PUSHR(rBX)
-
-	LW(_trksize(SB), rBX)
-	LW(_nheads(SB), rDI)
-	IMUL(rDI, rBX)
-	OR(rBX, rBX)
-	JZ _ioerror
-
-_okay:
-	DIV(rBX)			/* cylinder -> rAX, track,sector -> rDX */
-
-	MW(rAX, rCX)			/* save cylinder */
-	ROLI(0x08, rCX)			/* swap rC[HL] */
-	SHLBI(0x06, rCL)		/* move high bits up */
-
-	MW(rDX, rAX)
-	CLR(rDX)
-	LW(_trksize(SB), rBX)
-
-	DIV(rBX)			/* head -> rAX, sector -> rDX */
-
-	INC(rDX)			/* sector numbers are 1-based */
-	ANDI(0x003F, rDX)		/* should not be necessary */
-	OR(rDX, rCX)
-
-	MW(rAX, rDX)
-	SHLI(0x08, rDX)			/* form head */
-	LBPB(Xdrive, rDL)		/* form drive */
-
-	POPR(rBX)
-	LWI(0x0201, rAX)		/* form command and sectors */
-	BIOSCALL(0x13)			/* CF set on failure */
-	JCC _BIOSreadret
-
-	POPA
-	DEC(rDI)			/* too many retries? */
-	JEQ _ioerror
-
-	CALL16(dreset(SB))
-	JMP _retry
-
-_ioerror:
-	LWI(ioerror(SB), rSI)
-	CALL16(BIOSputs(SB))
-	JMP xbuggery
-
-_BIOSreadret:
-	POPA
-	RET
-
-TEXT dreset(SB), $0
-	PUSHA
-	CLR(rAX)			/* rAH == 0 == reset disc system */
-	LBPB(Xdrive, rDL)
-	BIOSCALL(0x13)
-	ORB(rAH, rAH)			/* status (0 == success) */
-	POPA
-	JNE _ioerror
-	RET
-
-TEXT printsharp(SB), $0
-	LWI(sharp(SB), rSI)
-_doprint:
-	CALL16(BIOSputs(SB))
-	RET
-
-TEXT printspace(SB), $0
-	LWI(space(SB), rSI)
-	JMP _doprint
-
-TEXT printnl(SB), $0
-	LWI(nl(SB), rSI)
-	JMP _doprint
-
-/*
- * Output a string to the display.
- * String argument is in rSI.
- */
-TEXT BIOSputs(SB), $0
-	PUSHA
-	CLR(rBX)
-_BIOSputs:
-	LODSB
-	ORB(rAL, rAL)
-	JEQ _BIOSputsret
-
-	LBI(0x0E, rAH)
-	BIOSCALL(0x10)
-	JMP _BIOSputs
-
-_BIOSputsret:
-	POPA
-	RET
-
-/*
- * Output a register to the display.
- */
-TEXT printAX(SB), $0
-	PUSHW(rAX)
-	PUSHW(rBX)
-	PUSHW(rCX)
-	PUSHW(rDI)
-
-	LWI(4, rCX)
-	LWI(numbuf+4(SB), rSI)
-
-_nextchar:
-	DEC(rSI)
-	MW(rAX, rBX)
-	ANDI(0x000F, rBX)
-	ADDI(0x30, rBX)	/* 0x30 = '0' */
-	CMPI(0x39, rBX)	/* 0x39 = '9' */
-	JLE _dowrite
-	ADDI(0x07, rBX)	/* 0x07 = 'A'-(1+'9')*/
-
-_dowrite:
-	SXB(rBL, 0, xSI)
-	SHRI(4, rAX)
-
-	DEC(rCX)
-	JNE _nextchar
-
-	LWI(numbuf(SB), rSI)
-	CALL16(BIOSputs(SB))
-
-	POPW(rDI)
-	POPW(rCX)
-	POPW(rBX)
-	POPW(rAX)
-
-	CALL16(printspace(SB))
-	RET
-
-TEXT printDXAX(SB), $0
-	PUSHW(rAX)
-	MW(rDX, rAX)
-	CALL16(printAX(SB))
-	POPW(rAX)
-	CALL16(printAX(SB))
-	RET
-
-TEXT printBX(SB), $0
-	PUSHW(rAX)
-	MW(rBX, rAX)
-	CALL16(printAX(SB))
-	POPW(rAX)
-	RET
-
-/*
- * Output some number of words to the display
- * rDS:rDI - buffer
- * rCX: number of words
- */
-TEXT printbuf(SB), $0
-	PUSHW(rAX)
-	PUSHW(rBX)
-	PUSHW(rCX)
-
-_nextword:
-	LXW(0, xBX, rAX)
-	CALL16(printAX(SB))
-	INC(rBX)
-	INC(rBX)
-	DEC(rCX)
-	JNE _nextword
-
-	POPW(rCX)
-	POPW(rBX)
-	POPW(rAX)
-	RET
-
-TEXT error(SB), $0
-	BYTE $'E'; 
-
-TEXT ioerror(SB), $0
-	BYTE $'I'; 
-
-TEXT nl(SB), $0
-	BYTE $'\r';
-	BYTE $'\n';
-	BYTE $'\z';
-
-TEXT numbuf(SB), $0
-	BYTE $'X'; BYTE $'X'; BYTE $'X'; BYTE $'X';
-	BYTE $'\z';
-
-TEXT space(SB), $0
-	BYTE $' ';
-	BYTE $'\z';
-
-TEXT sharp(SB), $0
-	BYTE $'#'; BYTE $'\z';
-
-TEXT confidence(SB), $0
-	BYTE $'P'; BYTE $'\z'

+ 0 - 362
sys/src/boot/pc/pbslba.s

@@ -1,362 +0,0 @@
-/*
- * FAT Partition Boot Sector. Loaded at 0x7C00:
- *	8a pbslba.s; 8l -o pbslba -l -H3 -T0x7C00 pbslba.8
- * Will load the target at LOADSEG*16+LOADOFF, so the target
- * should be probably be loaded with LOADOFF added to the
- * -Taddress.
- * If LOADSEG is a multiple of 64KB and LOADOFF is 0 then
- * targets larger than 64KB can be loaded.
- *
- * This code is uses Enhanced BIOS Services for Disc Drives and
- * can be used with discs up to 137GB in capacity.
- *
- * It relies on the _volid field in the FAT header containing
- * the LBA of the root directory.
- */
-#include "x16.h"
-
-#define LOADSEG		(0x10000/16)	/* where to load code (64KB) */
-#define LOADOFF		0
-#define DIROFF		0x0200		/* where to read the root directory */
-
-/*
- * FAT directory entry.
- */
-#define Dname		0x00
-#define Dnamesz	0x0B
-#define Dext		0x08
-#define Dattr		0x0B
-#define Dtime		0x16
-#define Ddate		0x18
-#define Dstart		0x1A
-#define Dlengthlo	0x1C
-#define Dlengthhi	0x1E
-
-#define Dirsz		0x20
-
-/*
- * Data is kept on the stack, indexed by rBP.
- */
-#define Xdap		0x00		/* disc address packet */
-#define Xrootsz		0x10		/* file data area */
-#define Xdrive		0x12		/* boot drive, passed by BIOS or MBR */
-#define Xtotal		0x14		/* sum of allocated data above */
-
-TEXT _magic(SB), $0
-	BYTE $0xEB; BYTE $0x3C;		/* jmp .+ 0x3C  (_start0x3E) */
-	BYTE $0x90			/* nop */
-TEXT _version(SB), $0
-	BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00;
-	BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00
-TEXT _sectsize(SB), $0
-	BYTE $0x00; BYTE $0x00
-TEXT _clustsize(SB), $0
-	BYTE $0x00
-TEXT _nresrv(SB), $0
-	BYTE $0x00; BYTE $0x00
-TEXT _nfats(SB), $0
-	BYTE $0x00
-TEXT _rootsize(SB), $0
-	BYTE $0x00; BYTE $0x00
-TEXT _volsize(SB), $0
-	BYTE $0x00; BYTE $0x00
-TEXT _mediadesc(SB), $0
-	BYTE $0x00
-TEXT _fatsize(SB), $0
-	BYTE $0x00; BYTE $0x00
-TEXT _trksize(SB), $0
-	BYTE $0x00; BYTE $0x00
-TEXT _nheads(SB), $0
-	BYTE $0x00; BYTE $0x00
-TEXT _nhiddenlo(SB), $0
-	BYTE $0x00; BYTE $0x00
-TEXT _nhiddenhi(SB), $0
-	BYTE $0x00; BYTE $0x00;
-TEXT _bigvolsize(SB), $0
-	BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00;
-TEXT _driveno(SB), $0
-	BYTE $0x00
-TEXT _reserved0(SB), $0
-	BYTE $0x00
-TEXT _bootsig(SB), $0
-	BYTE $0x00
-TEXT _volid(SB), $0
-	BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00;
-TEXT _label(SB), $0
-	BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00;
-	BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00
-	BYTE $0x00; BYTE $0x00; BYTE $0x00
-TEXT _type(SB), $0
-	BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00;
-	BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00;
-
-_start0x3E:
-	CLI
-	CLR(rAX)
-	MTSR(rAX, rSS)			/* 0000 -> rSS */
-	MTSR(rAX, rDS)			/* 0000 -> rDS, source segment */
-	MTSR(rAX, rES)
-	LWI(_magic-Xtotal(SB), rSP)
-	MW(rSP, rBP)			/* set the indexed-data pointer */
-
-	SBPB(rDL, Xdrive)		/* save the boot drive */
-
-	/* booting from a CD starts us at 7C0:0.  Move to 0:7C00 */
-	PUSHR(rAX)
-	LWI(_nxt(SB), rAX)
-	PUSHR(rAX)
-	BYTE $0xCB	/* FAR RET */
-
-TEXT _nxt(SB), $0
-	STI
-
-	LWI(confidence(SB), rSI)	/* for that warm, fuzzy feeling */
-	CALL16(BIOSputs(SB))
-
-	LBI(0x41, rAH)			/* check extensions present */
-	LWI(0x55AA, rBX)
-	LXB(Xdrive, xBP, rDL)		/* drive */
-	BIOSCALL(0x13)			/* CF set on failure */
-	JCS _jmp01
-	CMPI(0xAA55, rBX)
-	JNE _jmp01
-	ANDI(0x0001, rCX)
-	JEQ _jmp01
-
-					/* rCX contains 0x0001 */
-	SBPWI(0x0010, Xdap+0)		/* reserved + packet size */
-	SBPW(rCX, Xdap+2)		/* reserved + # of blocks to transfer */
-
-	DEC(rCX)
-	SBPW(rCX, Xdap+12)
-	SBPW(rCX, Xdap+14)
-
-	CALL16(dreset(SB))
-
-_jmp00:
-	LW(_volid(SB), rAX)		/* Xrootlo */
-	LW(_volid+2(SB), rDX)		/* Xroothi */
-
-	LWI(_magic+DIROFF(SB), rBX)
-	CALL16(BIOSread(SB))		/* read the root directory */
-
-	LWI((512/Dirsz), rBX)
-
-	LWI(_magic+DIROFF(SB), rDI)	/* compare first directory entry */
-
-_cmp00:
-	PUSHR(rDI)			/* save for later if it matches */
-	LWI(bootfile(SB), rSI)
-	LWI(Dnamesz, rCX)
-	REP
-	CMPSB
-	POPR(rDI)
-	JEQ _jmp02
-
-	DEC(rBX)
-	JEQ _jmp01
-
-	ADDI(Dirsz, rDI)
-	JMP _cmp00
-_jmp01:
-	CALL16(buggery(SB))
-
-_jmp02:
-	CLR(rBX)			/* a handy value */
-	LW(_rootsize(SB), rAX)		/* calculate and save Xrootsz */
-	LWI(Dirsz, rCX)
-	MUL(rCX)
-	LW(_sectsize(SB), rCX)
-	PUSHR(rCX)
-	DEC(rCX)
-	ADD(rCX, rAX)
-	ADC(rBX, rDX)
-	POPR(rCX)			/* _sectsize(SB) */
-	DIV(rCX)
-	PUSHR(rAX)			/* Xrootsz */
-
-	/*
-	 * rDI points to the matching directory entry.
-	 */
-	LXW(Dstart, xDI, rAX)		/* starting sector address */
-	DEC(rAX)			/* that's just the way it is */
-	DEC(rAX)
-	LB(_clustsize(SB), rCL)
-	CLRB(rCH)
-	MUL(rCX)
-	LW(_volid(SB), rCX)		/* Xrootlo */
-	ADD(rCX, rAX)
-	LW(_volid+2(SB), rCX)		/* Xroothi */
-	ADC(rCX, rDX)
-	POPR(rCX)			/* Xrootsz */
-	ADD(rCX, rAX)
-	ADC(rBX, rDX)
-
-	PUSHR(rAX)			/* calculate how many sectors to read */
-	PUSHR(rDX)
-	LXW(Dlengthlo, xDI, rAX)
-	LXW(Dlengthhi, xDI, rDX)
-	LW(_sectsize(SB), rCX)
-	PUSHR(rCX)
-	DEC(rCX)
-	ADD(rCX, rAX)
-	ADC(rBX, rDX)
-	POPR(rCX)			/* _sectsize(SB) */
-	DIV(rCX)
-	MW(rAX, rCX)
-	POPR(rDX)
-	POPR(rAX)
-
-	LWI(LOADSEG, rBX)		/* address to load into (seg+offset) */
-	MTSR(rBX, rES)			/*  seg */
-	LWI(LOADOFF, rBX)		/*  offset */
-
-_readboot:
-	CALL16(BIOSread(SB))		/* read the sector */
-
-	LW(_sectsize(SB), rDI)		/* bump addresses/counts */
-	ADD(rDI, rBX)
-	JCC _incsecno
-
-	MFSR(rES, rDI)			/* next 64KB segment */
-	ADDI(0x1000, rDI)
-	MTSR(rDI, rES)
-
-_incsecno:
-	CLR(rDI)
-	INC(rAX)
-	ADC(rDI, rDX)
-	LOOP _readboot
-
-	LWI(LOADSEG, rDI)		/* set rDS for loaded code */
-	MTSR(rDI, rDS)
-	FARJUMP16(LOADSEG, LOADOFF)	/* no deposit, no return */
-
-TEXT buggery(SB), $0
-	LWI(error(SB), rSI)
-	CALL16(BIOSputs(SB))
-
-_wait:
-	CLR(rAX)			/* wait for almost any key */
-	BIOSCALL(0x16)
-
-_reset:
-	CLR(rBX)			/* set ES segment for BIOS area */
-	MTSR(rBX, rES)
-
-	LWI(0x0472, rBX)		/* warm-start code address */
-	LWI(0x1234, rAX)		/* warm-start code */
-	POKEW				/* MOVW	AX, ES:[BX] */
-
-	FARJUMP16(0xFFFF, 0x0000)	/* reset */
-
-
-/*
- * Read a sector from a disc. On entry:
- *   rDX:rAX	sector number
- *   rES:rBX	buffer address
- */
-TEXT BIOSread(SB), $0
-	LWI(5, rDI)			/* retry count (ATAPI ZIPs suck) */
-_retry:
-	PUSHA				/* may be trashed by BIOSCALL */
-
-	SBPW(rBX, Xdap+4)		/* transfer buffer :offset */
-	MFSR(rES, rDI)			/* transfer buffer seg: */
-	SBPW(rDI, Xdap+6)
-	SBPW(rAX, Xdap+8)		/* LBA (64-bits) */
-	SBPW(rDX, Xdap+10)
-
-	MW(rBP, rSI)			/* disk address packet */
-	LBI(0x42, rAH)			/* extended read */
-	LBPB(Xdrive, rDL)		/* form drive */
-	BIOSCALL(0x13)			/* CF set on failure */
-	JCC _BIOSreadret
-
-	POPA
-	DEC(rDI)			/* too many retries? */
-	JEQ _ioerror
-
-	CALL16(dreset(SB))
-	JMP _retry
-
-_ioerror:
-	LWI(ioerror(SB), rSI)
-	CALL16(BIOSputs(SB))
-	JMP _wait
-
-_BIOSreadret:
-	POPA
-	RET
-
-TEXT dreset(SB), $0
-	PUSHA
-	CLR(rAX)			/* rAH == 0 == reset disc system */
-	LBPB(Xdrive, rDL)
-	BIOSCALL(0x13)
-	ORB(rAH, rAH)			/* status (0 == success) */
-	POPA
-	JNE _ioerror
-	RET
-
-/*
- * Output a string to the display.
- * String argument is in rSI.
- */
-TEXT BIOSputs(SB), $0
-	PUSHA
-	CLR(rBX)
-_BIOSputs:
-	LODSB
-	ORB(rAL, rAL)
-	JEQ _BIOSputsret
-
-	LBI(0x0E, rAH)
-	BIOSCALL(0x10)
-	JMP _BIOSputs
-
-_BIOSputsret:
-	POPA
-	RET
-
-/* "Bad format or I/O error\r\nPress almost any key to reboot..." */
-TEXT error(SB), $0
-	BYTE $'B'; BYTE $'a'; BYTE $'d'; BYTE $' ';
-	BYTE $'f'; BYTE $'o'; BYTE $'r'; BYTE $'m';
-	BYTE $'a'; BYTE $'t'; BYTE $' '; BYTE $'o';
-	BYTE $'r'; BYTE $' ';
-/* "I/O error\r\nPress almost any key to reboot..." */
-TEXT ioerror(SB), $0
-	BYTE $'I'; BYTE $'/'; BYTE $'O'; BYTE $' ';
-	BYTE $'e'; BYTE $'r'; BYTE $'r'; BYTE $'o';
-	BYTE $'r'; BYTE $'\r';BYTE $'\n';
-	BYTE $'P'; BYTE $'r'; BYTE $'e'; BYTE $'s';
-	BYTE $'s'; BYTE $' '; BYTE $'a'; BYTE $' ';
-	BYTE $'k'; BYTE $'e'; BYTE $'y';
-	BYTE $' '; BYTE $'t'; BYTE $'o'; BYTE $' ';
-	BYTE $'r'; BYTE $'e'; BYTE $'b'; BYTE $'o';
-	BYTE $'o'; BYTE $'t';
-	BYTE $'.'; BYTE $'.'; BYTE $'.';
-	BYTE $'\z';
-
-#ifdef USEBCOM
-/* "B       COM" */
-TEXT bootfile(SB), $0
-	BYTE $'B'; BYTE $' '; BYTE $' '; BYTE $' ';
-	BYTE $' '; BYTE $' '; BYTE $' '; BYTE $' ';
-	BYTE $'C'; BYTE $'O'; BYTE $'M';
-	BYTE $'\z';
-#else
-/* "9LOAD      " */
-TEXT bootfile(SB), $0
-	BYTE $'9'; BYTE $'L'; BYTE $'O'; BYTE $'A';
-	BYTE $'D'; BYTE $' '; BYTE $' '; BYTE $' ';
-	BYTE $' '; BYTE $' '; BYTE $' ';
-	BYTE $'\z';
-#endif /* USEBCOM */
-
-/* "PBS..." */
-TEXT confidence(SB), $0
-	BYTE $'P'; BYTE $'B'; BYTE $'S'; BYTE $'2';
-	BYTE $'.'; BYTE $'.'; BYTE $'.';
-	BYTE $'\z';

+ 0 - 327
sys/src/boot/pc/pbslbadebug.s

@@ -1,327 +0,0 @@
-/*
- * Debugging boot sector.  Reads the first directory
- * sector from disk and displays it.
- *
- * It relies on the _volid field in the FAT header containing
- * the LBA of the root directory.
- */
-#include "x16.h"
-
-#define DIROFF		0x00200		/* where to read the root directory (offset) */
-#define LOADSEG		(0x10000/16)	/* where to load code (64KB) */
-#define LOADOFF		0
-
-/*
- * FAT directory entry.
- */
-#define Dname		0x00
-#define Dext		0x08
-#define Dattr		0x0B
-#define Dtime		0x16
-#define Ddate		0x18
-#define Dstart		0x1A
-#define Dlengthlo	0x1C
-#define Dlengthhi	0x1E
-
-#define Dirsz		0x20
-
-/*
- * We keep data on the stack, indexed by rBP.
- */
-#define Xdrive		0x00		/* boot drive, passed by BIOS in rDL */
-#define Xrootlo		0x02		/* offset of root directory */
-#define Xroothi		0x04
-#define Xrootsz		0x06		/* file data area */
-#define Xtotal		0x08		/* sum of allocated data above */
-#define Xdap		0x00		/* disc address packet */
-
-TEXT _magic(SB), $0
-	BYTE $0xEB; BYTE $0x3C;		/* jmp .+ 0x3C  (_start0x3E) */
-	BYTE $0x90			/* nop */
-TEXT _version(SB), $0
-	BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00;
-	BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00
-TEXT _sectsize(SB), $0
-	BYTE $0x00; BYTE $0x00
-TEXT _clustsize(SB), $0
-	BYTE $0x00
-TEXT _nresrv(SB), $0
-	BYTE $0x00; BYTE $0x00
-TEXT _nfats(SB), $0
-	BYTE $0x00
-TEXT _rootsize(SB), $0
-	BYTE $0x00; BYTE $0x00
-TEXT _volsize(SB), $0
-	BYTE $0x00; BYTE $0x00
-TEXT _mediadesc(SB), $0
-	BYTE $0x00
-TEXT _fatsize(SB), $0
-	BYTE $0x00; BYTE $0x00
-TEXT _trksize(SB), $0
-	BYTE $0x00; BYTE $0x00
-TEXT _nheads(SB), $0
-	BYTE $0x00; BYTE $0x00
-TEXT _nhiddenlo(SB), $0
-	BYTE $0x00; BYTE $0x00
-TEXT _nhiddenhi(SB), $0
-	BYTE $0x00; BYTE $0x00;
-TEXT _bigvolsize(SB), $0
-	BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00;
-TEXT _driveno(SB), $0
-	BYTE $0x00
-TEXT _reserved0(SB), $0
-	BYTE $0x00
-TEXT _bootsig(SB), $0
-	BYTE $0x00
-TEXT _volid(SB), $0
-	BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00;
-TEXT _label(SB), $0
-	BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00;
-	BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00
-	BYTE $0x00; BYTE $0x00; BYTE $0x00
-TEXT _type(SB), $0
-	BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00;
-	BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00;
-
-_start0x3E:
-	CLI
-	CLR(rAX)
-	MTSR(rAX, rSS)			/* 0000 -> rSS */
-	MTSR(rAX, rDS)			/* 0000 -> rDS, source segment */
-	MTSR(rAX, rES)
-	LWI(_magic-Xtotal(SB), rSP)
-	MW(rSP, rBP)			/* set the indexed-data pointer */
-
-	SBPB(rDL, Xdrive)		/* save the boot drive */
-
-	STI
-
-	LWI(confidence(SB), rSI)	/* for that warm, fuzzy feeling */
-	CALL(BIOSputs(SB))
-
-	LBI(0x41, rAH)			/* check extensions present */
-	LWI(0x55AA, rBX)
-	LXB(Xdrive, xBP, rDL)		/* drive */
-	SYSCALL(0x13)			/* CF set on failure */
-	JCS _jmp01
-	CMPI(0xAA55, rBX)
-	JNE _jmp01
-	ANDI(0x0001, rCX)
-	JEQ _jmp01
-
-					/* rCX contains 0x0001 */
-	SBPWI(0x0010, Xdap+0)		/* reserved + packet size */
-	SBPW(rCX, Xdap+2)		/* reserved + # of blocks to transfer */
-
-	DEC(rCX)
-	SBPW(rCX, Xdap+12)
-	SBPW(rCX, Xdap+14)
-
-/* BIOSread will do this 	CALL(dreset(SB)) */
-
-_jmp00:
-	LW(_volid(SB), rAX)		/* Xrootlo */
-	LW(_volid+2(SB), rDX)		/* Xroothi */
-
-	LWI(_magic+DIROFF(SB), rBX)
-	CALL(BIOSread(SB))		/* read the root directory */
-
-	CALL(printnl(SB))
-	LWI(_magic+DIROFF(SB), rBX)
-	LWI((512/2), rCX)
-	CALL(printbuf(SB))
-
-xloop:
-	JMP xloop
-
-
-_jmp01:
-
-TEXT buggery(SB), $0
-	LWI(error(SB), rSI)
-	CALL(BIOSputs(SB))
-
-xbuggery:
-	JMP xbuggery
-
-/*
- * Read a sector from a disc. On entry:
- *   rDX:rAX	sector number
- *   rES:rBX	buffer address
- */
-TEXT BIOSread(SB), $0
-	LWI(5, rDI)			/* retry count (ATAPI ZIPs suck) */
-_retry:
-	PUSHA				/* may be trashed by SYSCALL */
-
-	SBPW(rBX, Xdap+4)		/* transfer buffer :offset */
-	MFSR(rES, rDI)			/* transfer buffer seg: */
-	SBPW(rDI, Xdap+6)
-	SBPW(rAX, Xdap+8)		/* LBA (64-bits) */
-	SBPW(rDX, Xdap+10)
-
-	MW(rBP, rSI)			/* disk address packet */
-	LBI(0x42, rAH)			/* extended read */
-	LBPB(Xdrive, rDL)		/* form drive */
-	SYSCALL(0x13)			/* CF set on failure */
-	JCC _BIOSreadret
-
-	POPA
-	DEC(rDI)			/* too many retries? */
-	JEQ _ioerror
-
-	CALL(dreset(SB))
-	JMP _retry
-
-_ioerror:
-	LWI(ioerror(SB), rSI)
-	CALL(BIOSputs(SB))
-	JMP xbuggery
-
-_BIOSreadret:
-	POPA
-	RET
-
-TEXT dreset(SB), $0
-	PUSHA
-	CLR(rAX)			/* rAH == 0 == reset disc system */
-	LBPB(Xdrive, rDL)
-	SYSCALL(0x13)
-	ORB(rAH, rAH)			/* status (0 == success) */
-	POPA
-	JNE _ioerror
-	RET
-
-
-TEXT printsharp(SB), $0
-	LWI(sharp(SB), rSI)
-_doprint:
-	CALL(BIOSputs(SB))
-	RET
-
-TEXT printspace(SB), $0
-	LWI(space(SB), rSI)
-	JMP _doprint
-
-TEXT printnl(SB), $0
-	LWI(nl(SB), rSI)
-	JMP _doprint
-
-/*
- * Output a string to the display.
- * String argument is in rSI.
- */
-TEXT BIOSputs(SB), $0
-	PUSHA
-	CLR(rBX)
-_BIOSputs:
-	LODSB
-	ORB(rAL, rAL)
-	JEQ _BIOSputsret
-
-	LBI(0x0E, rAH)
-	SYSCALL(0x10)
-	JMP _BIOSputs
-
-_BIOSputsret:
-	POPA
-	RET
-
-/*
- * Output a register to the display.
- */
-TEXT printAX(SB), $0
-	PUSHW(rAX)
-	PUSHW(rBX)
-	PUSHW(rCX)
-	PUSHW(rDI)
-
-	LWI(4, rCX)
-	LWI(numbuf+4(SB), rSI)
-
-_nextchar:
-	DEC(rSI)
-	MW(rAX, rBX)
-	ANDI(0x000F, rBX)
-	ADDI(0x30, rBX)	/* 0x30 = '0' */
-	CMPI(0x39, rBX)	/* 0x39 = '9' */
-	JLE _dowrite
-	ADDI(0x07, rBX)	/* 0x07 = 'A'-(1+'9')*/
-
-_dowrite:
-	SXB(rBL, 0, xSI)
-	SHRI(4, rAX)
-
-	DEC(rCX)
-	JNE _nextchar
-
-	LWI(numbuf(SB), rSI)
-	CALL(BIOSputs(SB))
-
-	POPW(rDI)
-	POPW(rCX)
-	POPW(rBX)
-	POPW(rAX)
-
-	CALL(printspace(SB))
-	RET
-
-TEXT printDXAX(SB), $0
-	PUSHW(rAX)
-	MW(rDX, rAX)
-	CALL(printAX(SB))
-	POPW(rAX)
-	CALL(printAX(SB))
-	RET
-
-TEXT printBX(SB), $0
-	PUSHW(rAX)
-	MW(rBX, rAX)
-	CALL(printAX(SB))
-	POPW(rAX)
-	RET
-
-/*
- * Output some number of words to the display
- * rDS:rDI - buffer
- * rCX: number of words
- */
-TEXT printbuf(SB), $0
-	PUSHW(rAX)
-	PUSHW(rBX)
-	PUSHW(rCX)
-
-_nextword:
-	LXW(0, xBX, rAX)
-	CALL(printAX(SB))
-	INC(rBX)
-	INC(rBX)
-	DEC(rCX)
-	JNE _nextword
-
-	POPW(rCX)
-	POPW(rBX)
-	POPW(rAX)
-	RET
-
-TEXT error(SB), $0
-	BYTE $'E'; 
-
-TEXT ioerror(SB), $0
-	BYTE $'I'; 
-
-TEXT nl(SB), $0
-	BYTE $'\r';
-	BYTE $'\n';
-	BYTE $'\z';
-
-TEXT numbuf(SB), $0
-	BYTE $'X'; BYTE $'X'; BYTE $'X'; BYTE $'X';
-	BYTE $'\z';
-
-TEXT space(SB), $0
-	BYTE $' ';
-	BYTE $'\z';
-
-TEXT sharp(SB), $0
-	BYTE $'#'; BYTE $'\z';

+ 0 - 320
sys/src/boot/pc/pbsraw.s

@@ -1,320 +0,0 @@
-/*
- *  Partition Boot Sector. Loaded at 0x7C00:
- *	8a pbsraw.s; 8l -o pbsraw -l -H3 -T0x7C00 pbsraw.8
- * Will load the target at LOADSEG*16+LOADOFF, so the target
- * should be probably be loaded with LOADOFF added to the
- * -Taddress.
- * If LOADSEG is a multiple of 64KB and LOADOFF is 0 then
- * targets larger than 64KB can be loaded.
- *
- * This code is uses Enhanced BIOS Services for Disc Drives and
- * can be used with discs up to 137GB in capacity.
- *
- * It relies on the _startlba,  _filesz and _sectsz containing the start lba of
- * the loader and filesz to contain the size of the file and the sector size.
- * The sector size can be probably detected by the bios.
- */
-#include "x16.h"
-
-#define LOADSEG		(0x10000/16)	/* where to load code (64KB) */
-#define LOADOFF		0
-
-/*
- * Data is kept on the stack, indexed by rBP.
- */
-#define Xdap		0x00		/* disc address packet */
-#define Xrootsz		0x10		/* file data area */
-#define Xdrive		0x12		/* boot drive, passed by BIOS or MBR */
-#define Xtotal		0x14		/* sum of allocated data above */
-
-TEXT _magic(SB), $0
-	BYTE $0xEB; BYTE $0x3C;		/* jmp .+ 0x3C  (_start0x3E) */
-	BYTE $0x90			/* nop */
-TEXT _startlba(SB), $0
-	BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00
-TEXT _filesz(SB), $0
-	BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00
-TEXT _sectsz(SB), $0
-	BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00
-TEXT _pad(SB), $0
-	BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00
-	BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00
-	BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00
-	BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00
-	BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00
-	BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00
-	BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00
-	BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00
-	BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00
-	BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00
-	BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00
-	BYTE $0x00; BYTE $0x00; BYTE $0x00
-
-_start0x3E:
-	CLI
-	CLR(rAX)
-	MTSR(rAX, rSS)			/* 0000 -> rSS */
-	MTSR(rAX, rDS)			/* 0000 -> rDS, source segment */
-	MTSR(rAX, rES)
-	LWI(_magic-Xtotal(SB), rSP)
-	MW(rSP, rBP)			/* set the indexed-data pointer */
-
-	SBPB(rDL, Xdrive)		/* save the boot drive */
-
-	/* booting from a CD starts us at 7C0:0.  Move to 0:7C00 */
-	PUSHR(rAX)
-	LWI(_nxt(SB), rAX)
-	PUSHR(rAX)
-	BYTE $0xCB			/* FAR RET */
-
-TEXT _nxt(SB), $0
-	STI
-
-	LWI(confidence(SB), rSI)	/* for that warm, fuzzy feeling */
-	CALL16(BIOSputs(SB))
-
-	LBI(0x41, rAH)			/* check extensions present */
-	LWI(0x55AA, rBX)
-	LXB(Xdrive, xBP, rDL)		/* drive */
-	BIOSCALL(0x13)			/* CF set on failure */
-	JCS _jmp00
-	CMPI(0xAA55, rBX)
-	JNE _jmp00
-	ANDI(0x0001, rCX)
-	JNE _jmp01
-
-_jmp00:
-	CALL16(buggery(SB))
-
-_jmp01:
-	SBPWI(0x0010, Xdap+0)		/* reserved + packet size */
-	SBPW(rCX, Xdap+2)		/* reserved + # of blocks to transfer */
-
-	DEC(rCX)
-	SBPW(rCX, Xdap+12)
-	SBPW(rCX, Xdap+14)
-
-	CALL16(dreset(SB))
-
-_jmp02:
-	CLR(rBX)			/* a handy value */
-
-	LW(_startlba(SB), rAX)
-	LW(_startlba+2(SB), rDX)
-	CALL16(printDXAX(SB))
-	PUSHR(rAX)
-	PUSHR(rDX)
-	LW(_filesz(SB), rAX)
-	LW(_filesz+2(SB), rDX)
-	CALL16(printDXAX(SB))
-
-	MW(rAX, rCX)
-	POPR(rDX)
-	POPR(rAX)
-
-	LWI(LOADSEG, rBX)		/* address to load into (seg+offset) */
-	MTSR(rBX, rES)			/*  seg */
-	LWI(LOADOFF, rBX)		/*  offset */
-
-_readboot:
-	CALL16(BIOSread(SB))		/* read the sector */
-
-	LW(_sectsz(SB), rDI)		/* bump addresses/counts */
-	ADD(rDI, rBX)
-	JCC _incsecno
-
-	MFSR(rES, rDI)			/* next 64KB segment */
-	ADDI(0x1000, rDI)
-	MTSR(rDI, rES)
-
-_incsecno:
-	CLR(rDI)
-	INC(rAX)
-	ADC(rDI, rDX)
-	LOOP _readboot
-
-	LWI(LOADSEG, rDI)		/* set rDS for loaded code */
-	MTSR(rDI, rDS)
-	FARJUMP16(LOADSEG, LOADOFF)	/* no deposit, no return */
-
-TEXT buggery(SB), $0
-	LWI(error(SB), rSI)
-	CALL16(BIOSputs(SB))
-
-_wait:
-	CLR(rAX)			/* wait for almost any key */
-	BIOSCALL(0x16)
-
-_reset:
-	CLR(rBX)			/* set ES segment for BIOS area */
-	MTSR(rBX, rES)
-
-	LWI(0x0472, rBX)		/* warm-start code address */
-	LWI(0x1234, rAX)		/* warm-start code */
-	POKEW				/* MOVW	AX, ES:[BX] */
-
-	FARJUMP16(0xFFFF, 0x0000)	/* reset */
-
-/*
- * Read a sector from a disc. On entry:
- *   rDX:rAX	sector number
- *   rES:rBX	buffer address
- */
-TEXT BIOSread(SB), $0
-	LWI(5, rDI)			/* retry count (ATAPI ZIPs suck) */
-_retry:
-	PUSHA				/* may be trashed by BIOSCALL */
-
-	SBPW(rBX, Xdap+4)		/* transfer buffer :offset */
-	MFSR(rES, rDI)			/* transfer buffer seg: */
-	SBPW(rDI, Xdap+6)
-	SBPW(rAX, Xdap+8)		/* LBA (64-bits) */
-	SBPW(rDX, Xdap+10)
-
-	MW(rBP, rSI)			/* disk address packet */
-	LBI(0x42, rAH)			/* extended read */
-	LBPB(Xdrive, rDL)		/* form drive */
-	BIOSCALL(0x13)			/* CF set on failure */
-	JCC _BIOSreadret
-
-	POPA
-	DEC(rDI)			/* too many retries? */
-	JEQ _ioerror
-
-	CALL16(dreset(SB))
-	JMP _retry
-
-_ioerror:
-	LWI(ioerror(SB), rSI)
-	CALL16(BIOSputs(SB))
-	JMP _wait
-
-_BIOSreadret:
-	POPA
-	RET
-
-TEXT dreset(SB), $0
-	PUSHA
-	CLR(rAX)			/* rAH == 0 == reset disc system */
-	LBPB(Xdrive, rDL)
-	BIOSCALL(0x13)
-	ORB(rAH, rAH)			/* status (0 == success) */
-	POPA
-	JNE _ioerror
-	RET
-
-TEXT printsharp(SB), $0
-	LWI(sharp(SB), rSI)
-_doprint:
-	CALL16(BIOSputs(SB))
-	RET
-
-TEXT printspace(SB), $0
-	LWI(space(SB), rSI)
-	JMP _doprint
-
-TEXT printnl(SB), $0
-	LWI(nl(SB), rSI)
-	JMP _doprint
-
-/*
- * Output a string to the display.
- * String argument is in rSI.
- */
-TEXT BIOSputs(SB), $0
-	PUSHA
-	CLR(rBX)
-_BIOSputs:
-	LODSB
-	ORB(rAL, rAL)
-	JEQ _BIOSputsret
-
-	LBI(0x0E, rAH)
-	BIOSCALL(0x10)
-	JMP _BIOSputs
-
-_BIOSputsret:
-	POPA
-	RET
-
-/*
- * Output a register to the display.
- */
-TEXT printAX(SB), $0
-	PUSHR(rAX)
-	PUSHR(rBX)
-	PUSHR(rCX)
-	PUSHR(rDI)
-
-	LWI(4, rCX)
-	LWI(numbuf+4(SB), rSI)
-
-_nextchar:
-	DEC(rSI)
-	MW(rAX, rBX)
-	ANDI(0x000F, rBX)
-	ADDI(0x30, rBX)	/* 0x30 = '0' */
-	CMPI(0x39, rBX)	/* 0x39 = '9' */
-	JLE _dowrite
-	ADDI(0x07, rBX)	/* 0x07 = 'A'-(1+'9')*/
-
-_dowrite:
-	SXB(rBL, 0, xSI)
-	SHRI(4, rAX)
-
-	DEC(rCX)
-	JNE _nextchar
-
-	LWI(numbuf(SB), rSI)
-	CALL16(BIOSputs(SB))
-
-	POPR(rDI)
-	POPR(rCX)
-	POPR(rBX)
-	POPR(rAX)
-
-	CALL16(printspace(SB))
-	RET
-
-TEXT printDXAX(SB), $0
-	PUSHR(rAX)
-	MW(rDX, rAX)
-	CALL16(printAX(SB))
-	POPR(rAX)
-	CALL16(printAX(SB))
-	RET
-
-TEXT printBX(SB), $0
-	PUSHR(rAX)
-	MW(rBX, rAX)
-	CALL16(printAX(SB))
-	POPR(rAX)
-	RET
-
-TEXT error(SB), $0
-	BYTE $'E';
-
-TEXT ioerror(SB), $0
-	BYTE $'I';
-
-TEXT nl(SB), $0
-	BYTE $'\r';
-	BYTE $'\n';
-	BYTE $'\z';
-
-TEXT numbuf(SB), $0
-	BYTE $'X'; BYTE $'X'; BYTE $'X'; BYTE $'X';
-	BYTE $'\z';
-
-TEXT space(SB), $0
-	BYTE $' ';
-	BYTE $'\z';
-
-TEXT sharp(SB), $0
-	BYTE $'#'; BYTE $'\z';
-
-/* "PBSR..." */
-TEXT confidence(SB), $0
-	BYTE $'P'; BYTE $'B'; BYTE $'S'; BYTE $'R';
-	BYTE $'.'; BYTE $'.'; BYTE $'.';
-	BYTE $'\z';

+ 0 - 168
sys/src/boot/pc/x16.h

@@ -1,168 +0,0 @@
-/*
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
-
-/*
- * Can't write 16-bit code for 8a without getting into
- * lots of bother, so define some simple commands and
- * output the code directly.
- * 
- * N.B. CALL16(x) kills DI, so don't expect it to be
- * saved across calls.
- */
-#define rAX		0		/* rX  */
-#define rCX		1
-#define rDX		2
-#define rBX		3
-#define rSP		4		/* SP */
-#define rBP		5		/* BP */
-#define rSI		6		/* SI */
-#define rDI		7		/* DI */
-
-#define rAL		0		/* rL  */
-#define rCL		1
-#define rDL		2
-#define rBL		3
-#define rAH		4		/* rH */
-#define rCH		5
-#define rDH		6
-#define rBH		7
-
-#define rES		0		/* rS */
-#define rCS		1
-#define rSS		2
-#define rDS		3
-#define rFS		4
-#define rGS		5
-
-#define xSI		4		/* rI (index) */
-#define xDI		5
-#define xBP		6
-#define xBX		7
-
-#define rCR0		0		/* rC */
-#define rCR2		2
-#define rCR3		3
-#define rCR4		4
-
-#define OP(o, m, ro, rm)	BYTE $o;	/* op + modr/m byte */	\
-			BYTE $(((m)<<6)|((ro)<<3)|(rm))
-#define OPrm(o, r, m)	OP(o, 0x00, r, 0x06);	/* general r <-> m */	\
-			WORD $m;
-#define OPrr(o, r0, r1)	OP(o, 0x03, r0, r1);	/* general r -> r */
-
-#define LW(m, rX)	OPrm(0x8B, rX, m)	/* m -> rX */
-#define LXW(x, rI, r)	OP(0x8B, 0x02, r, rI);	/* x(rI) -> r */	\
-			WORD $x
-#define LBPW(x, r)	OP(0x8B, 0x02, r, xBP);	/* x(rBP) -> r */	\
-			WORD $x
-#define LB(m, rB)	OPrm(0x8A, rB, m)	/* m -> r[HL] */
-#define LXB(x, rI, r)	OP(0x8A, 0x01, r, rI);	/* x(rI) -> r */	\
-			BYTE $x
-#define LBPB(x, r)	OP(0x8A, 0x01, r, xBP);	/* x(rBP) -> r */	\
-			BYTE $x
-#define SW(rX, m)	OPrm(0x89, rX, m)	/* rX -> m */
-#define SXW(r, x, rI)	OP(0x89, 0x02, r, rI);	/* r -> x(rI) */	\
-			WORD $x
-#define SBPW(r, x)	OP(0x89, 0x02, r, xBP);	/* r -> x(rBP) */	\
-			WORD $(x)
-#define SBPWI(i, x)	OP(0xC7, 0x01, 0, xBP);	/* i -> x(rBP) */	\
-			BYTE $(x); WORD $(i)
-#define STB(rB, m)	OPrm(0x88, rB, m)	/* rB -> m */
-#define SXB(r, x, rI)	OP(0x88, 0x01, r, rI);	/* rB -> x(rI) */	\
-			BYTE $x
-#define SBPB(r, x)	OP(0x88, 0x01, r, xBP);	/* r -> x(rBP) */	\
-			BYTE $x
-#define SBPBI(i, x)	OP(0xC6, 0x01, 0, xBP);	/* i -> x(rBP) */	\
-			BYTE $(x); BYTE $(i)
-#define LWI(i, rX)	BYTE $(0xB8+rX);	/* i -> rX */		\
-			WORD $i;
-#define LBI(i, rB)	BYTE $(0xB0+rB);	/* i -> r[HL] */	\
-			BYTE $i
-
-#define MW(r0, r1)	OPrr(0x89, r0, r1)	/* r0 -> r1 */
-#define MFSR(rS, rX)	OPrr(0x8C, rS, rX)	/* rS -> rX */
-#define MTSR(rX, rS)	OPrr(0x8E, rS, rX)	/* rX -> rS */
-#define MFCR(rC, rX)	BYTE $0x0F;		/* rC -> rX */		\
-			OP(0x20, 0x03, rC, rX)
-#define MTCR(rX, rC)	BYTE $0x0F;		/* rX -> rC */		\
-			OP(0x22, 0x03, rC, rX)
-
-#define ADC(r0, r1)	OPrr(0x11, r0, r1)	/* r0 + r1 -> r1 */
-#define ADD(r0, r1)	OPrr(0x01, r0, r1)	/* r0 + r1 -> r1 */
-#define ADDI(i, r)	OP(0x81, 0x03, 0x00, r);/* i+r -> r */		\
-			WORD $i;
-#define AND(r0, r1)	OPrr(0x21, r0, r1)	/* r0&r1 -> r1 */
-#define ANDI(i, r)	OP(0x81, 0x03, 0x04, r);/* i&r -> r */		\
-			WORD $i;
-#define CLR(r)		OPrr(0x31, r, r)	/* r^r -> r */
-#define CLRB(r)		OPrr(0x30, r, r)	/* r^r -> r */
-#define CMP(r0, r1)	OPrr(0x39, r0, r1)	/* r1-r0 -> flags */
-#define CMPI(i, r)	OP(0x81, 0x03, 0x07, r);/* r-i -> flags */	\
-			WORD $i;
-#define CMPBR(r0, r1)	OPrr(0x38, r0, r1)	/* r1-r0 -> flags */
-#define DEC(r)		BYTE $(0x48|r)		/* r-1 -> r */
-#define DIV(r)		OPrr(0xF7, 0x06, r)	/* rDX:rAX/r -> rAX, rDX:rAX%r -> rDX */
-#define INC(r)		BYTE $(0x40|r)		/* r+1 -> r */
-#define MUL(r)		OPrr(0xF7, 0x04, r)	/* r*rAX -> rDX:rAX */
-#define IMUL(r0, r1)	BYTE $0x0F;		/* r0*r1 -> r1 */	\
-			OPrr(0xAF, r1, r0)	/* (signed) */
-#define OR(r0, r1)	OPrr(0x09, r0, r1)	/* r0|r1 -> r1 */
-#define ORB(r0, r1)	OPrr(0x08, r0, r1)	/* r0|r1 -> r1 */
-#define ORI(i, r)	OP(0x81, 0x03, 0x01, r);/* i|r -> r */		\
-			WORD $i;
-#define ROLI(i, r)	OPrr(0xC1, 0x00, r);	/* r<<>>i -> r */	\
-			BYTE $i;
-#define SHLI(i, r)	OPrr(0xC1, 0x04, r);	/* r<<i -> r */		\
-			BYTE $i;
-#define SHLBI(i, r)	OPrr(0xC0, 0x04, r);	/* r<<i -> r */		\
-			BYTE $i;
-#define SHRI(i, r)	OPrr(0xC1, 0x05, r);	/* r>>i -> r */		\
-			BYTE $i;
-#define SHRBI(i, r)	OPrr(0xC0, 0x05, r);	/* r>>i -> r */		\
-			BYTE $i;
-#define SUB(r0, r1)	OPrr(0x29, r0, r1)	/* r1-r0 -> r1 */
-#define SUBI(i, r)	OP(0x81, 0x03, 0x05, r);/* r-i -> r */		\
-			WORD $i;
-
-#define STOSW		STOSL
-
-#define CALL16(f)	LWI(f, rDI);		/* &f -> rDI */		\
-			BYTE $0xFF;		/* (*rDI) */		\
-			BYTE $0xD7;
-#define FARJUMP16(s, o)	BYTE $0xEA;		/* jump to ptr16:16 */	\
-			WORD $o; WORD $s
-#define FARJUMP32(s, o)	BYTE $0x66;		/* jump to ptr32:16 */	\
-			BYTE $0xEA; LONG $o; WORD $s
-#define	DELAY		BYTE $0xEB;		/* jmp .+2 */		\
-			BYTE $0x00
-#define BIOSCALL(b)	INT $b			/* INT $b */
-
-#define PEEKW		BYTE $0x26;		/* MOVW	rES:[rBX], rAX  */	\
-			BYTE $0x8B; BYTE $0x07
-#define POKEW		BYTE $0x26;		/* MOVW	rAX, rES:[rBX] */	\
-			BYTE $0x89; BYTE $0x07
-#define OUTPORTB(p, d)	LBI(d, rAL);		/* d -> I/O port p */	\
-			BYTE $0xE6;					\
-			BYTE $p; DELAY
-#define PUSHA		BYTE $0x60
-#define PUSHR(r)	BYTE $(0x50|r)		/* r  -> (--rSP) */
-#define PUSHS(rS)	BYTE $(0x06|((rS)<<3))	/* rS  -> (--rSP) */
-#define PUSHI(i)	BYTE $0x68; WORD $i;	/* i -> --(rSP) */
-#define POPA		BYTE $0x61
-#define POPR(r)		BYTE $(0x58|r)		/* (rSP++) -> r */
-#define POPS(rS)	BYTE $(0x07|((rS)<<3))	/* (rSP++) -> r */
-#define NOP		BYTE $0x90		/* nop */
-
-#define LGDT(gdtptr)	BYTE $0x0F;		/* LGDT */			\
-			BYTE $0x01; BYTE $0x16;					\
-			WORD $gdtptr
-
-/* operand size switch. */
-#define OPSIZE		BYTE $0x66
-