Adds support for understanding bus:dev.func to the -d option of testbios
You may specify '-d bus:dev.func' or '-d dev.func'.  If you do '-d <value>'
then the behavior reverts back to the orginal where <value> is taken to be
the 16-bit packed notation of busdevfn.

It also add a sanity check to try and detect when people have not specified
the -d option and they should have, or when the -d bus:dev.fn evals to a packed
busdevfn of 0x0000.



git-svn-id: svn://svn.coreboot.org/coreboot/trunk@2271 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
diff --git a/util/vgabios/testbios.c b/util/vgabios/testbios.c
index 9ffdd06..06f6109 100644
--- a/util/vgabios/testbios.c
+++ b/util/vgabios/testbios.c
@@ -5,6 +5,7 @@
 #include <sys/mman.h>
 #include <fcntl.h>
 #include <getopt.h>
+#include <string.h>
 
 #define die(x) { perror(x); exit(1); }
 #define warn(x) { perror(x);  }
@@ -24,6 +25,8 @@
 
 void pushw(u16 val);
 
+unsigned short get_device(char *arg_val);
+
 extern int teststart, testend;
 
 _ptr p;
@@ -128,6 +131,7 @@
 	size_t size = 0;
 	int base = 0;
 	int have_size = 0, have_base = 0, have_ip = 0, have_cs = 0;
+	int have_devfn = 0;
 	int parse_rom = 0;
 	char *fsegname = 0;
 	unsigned char *fsegptr;
@@ -198,7 +202,8 @@
 			absegname = optarg;
 			break;
 		case 'd':
-			devfn = strtol(optarg, 0, 0);
+			devfn = get_device(optarg);
+			have_devfn = 1;
 			break;
 		case 'D':
 			debugflag = strtol(optarg, 0, 0);
@@ -247,6 +252,22 @@
 
 	//printf("Point 1 int%x vector at %x\n", 0x42, getIntVect(0x42));
 
+	if (initialip == 0x0003) {
+		if ((devfn == 0) || (have_devfn == 0)) {
+			printf("WARNING! It appears you are trying to run an option ROM.\n");
+			printf("  (initial ip = 0x0003)\n");
+			if (have_devfn) {
+				printf("  However, the device you have specified is 0x00\n");
+				printf("  It is very unlikely that your device is at this address\n");
+				printf("  Please check your -d option\n");
+			}
+			else {
+				printf("  Please specify a device with -d\n");
+				printf("  The default is not likely to work\n");
+			}
+		}
+	}
+	
 	if (absegname) {
 		abseg = mapitin(absegname, (off_t) 0xa0000, 0x20000);
 		if (!abseg)
@@ -278,6 +299,10 @@
 	X86EMU_setupIntrFuncs(intFuncs);
 	cp = mapitin(filename, (off_t) 0, size);
 
+	if (devfn) {
+		printf("Loading ax with BusDevFn = %x\n",devfn);
+	}
+	
 	current->ax = devfn   ? devfn : 0xff;
 	current->dx = 0x80;
 	//      current->ip = 0;
@@ -328,3 +353,42 @@
 
 	return 0;
 }
+
+unsigned short get_device(char *arg_val)
+{
+	unsigned short devfn=0;
+	long bus=0,dev=0,fn=0,need_pack=0;
+	char *tok;
+	
+	tok = strsep(&arg_val,":");
+	if (arg_val != NULL) {
+		bus = strtol(tok,0,16);
+		need_pack = 1;
+	}
+	else {
+		arg_val = tok;
+	}
+
+	tok = strsep(&arg_val,".");
+	if (arg_val != NULL) {
+		dev = strtol(tok,0,16);
+		fn  = strtol(arg_val,0,16);
+		need_pack = 1;
+	}
+	else {
+		if (need_pack ==1 && (strlen(tok))) {
+			dev = strtol(tok,0,16);			
+		}
+	}
+	
+	if ( need_pack == 1) {
+		devfn = bus<<8 | (dev<<3) | fn;
+	}
+	else {
+		devfn = strtol(tok, 0, 0);
+	}
+
+
+	return devfn;
+}
+