Index: driver/xf86-video-ati/src/radeon_driver.c
===================================================================
RCS file: /cvs/xorg/driver/xf86-video-ati/src/radeon_driver.c,v
retrieving revision 1.116
diff -b -p -u -r1.116 radeon_driver.c
--- driver/xf86-video-ati/src/radeon_driver.c	29 Apr 2006 21:30:23 -0000	1.116
+++ driver/xf86-video-ati/src/radeon_driver.c	1 May 2006 02:37:05 -0000
@@ -584,6 +584,7 @@ RADEONPreInt10Save(ScrnInfoPtr pScrn, vo
 
     /*
      * Zap MEM_CNTL and set MPP_TB_CONFIG<31:24> to 4
+     * Fix from ATI for problem with Radeon hardware not leaving ROM enabled
      */
     OUTREG(RADEON_MEM_CNTL, 0);
     CardTmp = SaveStruct.MPP_TB_CONFIG & 0x00ffffffu;
@@ -4871,8 +4872,14 @@ _X_EXPORT Bool RADEONPreInit(ScrnInfoPtr
 
 #if !defined(__alpha__)
     if (xf86GetPciDomain(info->PciTag) ||
-	!xf86IsPrimaryPci(info->PciInfo))
+	!xf86IsPrimaryPci(info->PciInfo)) {
 	RADEONPreInt10Save(pScrn, &int10_save);
+
+	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "PreInt10Save PCI:%d:%d:%d\n", 
+		   info->PciInfo->bus, 
+		   info->PciInfo->device,
+		   info->PciInfo->func);
+    }
 #else
     /* [Alpha] On the primary, the console already ran the BIOS and we're
      *         going to run it again - so make sure to "fix up" the card
Index: xserver/xorg/hw/xfree86/int10/helper_mem.c
===================================================================
RCS file: /cvs/xorg/xserver/xorg/hw/xfree86/int10/helper_mem.c,v
retrieving revision 1.4
diff -b -p -u -r1.4 helper_mem.c
--- xserver/xorg/hw/xfree86/int10/helper_mem.c	10 Feb 2006 22:00:25 -0000	1.4
+++ xserver/xorg/hw/xfree86/int10/helper_mem.c	1 May 2006 02:37:07 -0000
@@ -298,8 +298,8 @@ xf86int10ParseBiosLocation(void* options
     s = xstrdup(str);
     p = strtok(s,":");
     if (xf86NameCmp(p,"pci") == 0) bios->bus = BUS_PCI;
-    else
-	if (xf86NameCmp(p,"primary") == 0) bios->bus = BUS_ISA;
+    else if (xf86NameCmp(p,"primary") == 0) bios->bus = BUS_ISA;
+    else if (xf86NameCmp(p,"file") == 0) bios->bus = BUS_last;
 
     xfree(s);
     
@@ -311,7 +311,7 @@ xf86int10ParseBiosLocation(void* options
     switch (bios->bus) {
     case BUS_ISA:
 	if (p)
-	    bios->location.legacy = atoi(++p);
+	    bios->location.legacy = strtol(++p,NULL,0);
 	else
 	    bios->location.legacy = 0;
 	break;
@@ -329,6 +329,18 @@ xf86int10ParseBiosLocation(void* options
 	/* fall through */
 	bios->bus = BUS_NONE;
 	break;
+    case BUS_last:
+      if(p) {
+	int len=strlen(++p);
+	if(len<sizeof(bios->location.pathname)) {
+	  strcpy(bios->location.pathname, p);
+	  break;
+	}
+      }
+      /* fall through */
+      bios->bus = BUS_NONE;
+      break;
+
     default:
 	break;
     }
Index: xserver/xorg/hw/xfree86/int10/pci.c
===================================================================
RCS file: /cvs/xorg/xserver/xorg/hw/xfree86/int10/pci.c,v
retrieving revision 1.4
diff -b -p -u -r1.4 pci.c
--- xserver/xorg/hw/xfree86/int10/pci.c	10 Feb 2006 22:00:25 -0000	1.4
+++ xserver/xorg/hw/xfree86/int10/pci.c	1 May 2006 02:37:07 -0000
@@ -43,9 +43,10 @@ mapPciRom(int pciEntity, unsigned char *
     /* unmap/close/disable PCI bios mem */
     xfree(mem);
 
-#ifdef DEBUG
     if (!length)
-	ErrorF("mapPciRom: no BIOS found\n");
+      xf86MsgVerb(X_INFO,2,"mapPciRom: no BIOS found at PCI:%i:%i:%i"
+		  " size=%i\n", pvp->bus,pvp->device,pvp->func, pvp->biosSize);
+#ifdef DEBUG
 #ifdef PRINT_PCI
     else
 	dprint(address,0x20);
Index: xserver/xorg/hw/xfree86/int10/xf86int10.h
===================================================================
RCS file: /cvs/xorg/xserver/xorg/hw/xfree86/int10/xf86int10.h,v
retrieving revision 1.5
diff -b -p -u -r1.5 xf86int10.h
--- xserver/xorg/hw/xfree86/int10/xf86int10.h	24 Aug 2005 11:18:35 -0000	1.5
+++ xserver/xorg/hw/xfree86/int10/xf86int10.h	1 May 2006 02:37:07 -0000
@@ -70,6 +70,7 @@ typedef struct {
 	    int func;
 	} pci;
 	int legacy;
+	char pathname[256];
     } location;
 } xf86int10BiosLocation, *xf86int10BiosLocationPtr;
     
Index: xserver/xorg/hw/xfree86/os-support/bus/Pci.c
===================================================================
RCS file: /cvs/xorg/xserver/xorg/hw/xfree86/os-support/bus/Pci.c,v
retrieving revision 1.14
diff -b -p -u -r1.14 Pci.c
--- xserver/xorg/hw/xfree86/os-support/bus/Pci.c	26 Apr 2006 11:40:58 -0000	1.14
+++ xserver/xorg/hw/xfree86/os-support/bus/Pci.c	1 May 2006 02:37:07 -0000
@@ -1151,16 +1151,20 @@ handlePciBIOS( PCITAG Tag, int basereg, 
 	    b_reg = i;
 	}
 
-	if (!(newbase = getValidBIOSBase(Tag, b_reg)))
+	if (!(newbase = getValidBIOSBase(Tag, b_reg))) {
+	  xf86MsgVerb(X_INFO,2,"xf86ReadPciBios: PCI:%i:%i:%i b_reg=%i"
+		      " no valid address\n", 
+		      (int)PCI_BUS_FROM_TAG(Tag), (int)PCI_DEV_FROM_TAG(Tag),
+		      (int)PCI_FUNC_FROM_TAG(Tag), b_reg);
 	    continue;  /* no valid address found */
-
+	}
 	romaddr = PCIGETROM(newbase);
 
 	/* if we use a mem base save it and move it out of the way */
 	if (b_reg >= 0 && b_reg <= 5) {
 	    savebase = pciReadLong(Tag, PCI_MAP_REG_START+(b_reg<<2));
-	    xf86MsgVerb(X_INFO,5,"xf86ReadPciBios: modifying membase[%i]"
-			" for device %i:%i:%i\n", basereg,
+	    xf86MsgVerb(X_INFO,2,"xf86ReadPciBios: modifying membase[%i]"
+			" for device %i:%i:%i\n", b_reg,
 			(int)PCI_BUS_FROM_TAG(Tag), (int)PCI_DEV_FROM_TAG(Tag),
 			(int)PCI_FUNC_FROM_TAG(Tag));
 	    pciWriteLong(Tag, PCI_MAP_REG_START + (b_reg << 2),
@@ -1170,7 +1174,7 @@ handlePciBIOS( PCITAG Tag, int basereg, 
 	pciWriteLong(Tag, PCI_MAP_ROM_REG, romaddr
 		     | PCI_MAP_ROM_DECODE_ENABLE);
 
-	hostbase = pciBusAddrToHostAddr(Tag, PCI_MEM, PCIGETROM(romaddr));
+	hostbase = pciBusAddrToHostAddr(Tag, PCI_MEM, romaddr);
 
 	if ((xf86ReadDomainMemory(Tag, hostbase, sizeof(tmp), tmp) !=
 	     sizeof(tmp)) ||
@@ -1180,6 +1184,11 @@ handlePciBIOS( PCITAG Tag, int basereg, 
 	    if (savebase) pciWriteLong(Tag, PCI_MAP_REG_START + (b_reg << 2),
 				       (CARD32) savebase);
 
+	  xf86MsgVerb(X_INFO,2,"xf86ReadPciBios: %i:%i:%i br=%i at"
+		      " 0x%08lx 0x%08lx bad signature %02x %02x\n", 
+		      (int)PCI_BUS_FROM_TAG(Tag), (int)PCI_DEV_FROM_TAG(Tag),
+		      (int)PCI_FUNC_FROM_TAG(Tag), b_reg, romaddr, hostbase, 
+		      (unsigned )tmp[0], (unsigned )tmp[1]);
 	    /* No BIOS found: try another address */
 	    continue;
 	}
Index: xserver/xorg/hw/xfree86/os-support/linux/int10/linux.c
===================================================================
RCS file: /cvs/xorg/xserver/xorg/hw/xfree86/os-support/linux/int10/linux.c,v
retrieving revision 1.6
diff -b -p -u -r1.6 linux.c
--- xserver/xorg/hw/xfree86/os-support/linux/int10/linux.c	13 Feb 2006 04:56:27 -0000	1.6
+++ xserver/xorg/hw/xfree86/os-support/linux/int10/linux.c	1 May 2006 02:37:07 -0000
@@ -104,6 +105,7 @@ xf86ExtendedInitInt10(int entityIndex, i
     legacyVGARec vga;
     xf86int10BiosLocation bios;
     Bool videoBiosMapped = FALSE;
+    Bool videoBiosSearch = FALSE;
     
     if (int10Generation != serverGeneration) {
 	counter = 0;
@@ -273,132 +275,173 @@ xf86ExtendedInitInt10(int entityIndex, i
     
     xf86int10ParseBiosLocation(options,&bios);
 
-    if (xf86IsEntityPrimary(entityIndex) 
-	&& !(initPrimary(options))) {
-	if (bios.bus == BUS_ISA && bios.location.legacy) {
-	    xf86DrvMsg(screen, X_CONFIG,
-		       "Overriding BIOS location: 0x%x\n",
-		       bios.location.legacy);
+    cs = 0x0;
+    if (bios.bus == BUS_ISA) { 
+      /* user specifed ISA lower 1 MB memory location */
+      if(bios.location.legacy) {
+	xf86DrvMsg(screen,X_CONFIG,"Overriding bios location:"
+		   " primary:0x%05x\n", (unsigned )bios.location.legacy);
+
 	    cs = bios.location.legacy >> 4;
 	    bios_base = (unsigned char *)(cs << 4);
 	    if (!int10_check_bios(screen, cs, bios_base)) {
-		xf86DrvMsg(screen, X_ERROR,
-			   "No V_BIOS at specified address 0x%lx\n",cs << 4);
+	  xf86DrvMsg(screen, X_ERROR, "No V_BIOS at specified address %p\n",
+		     bios_base);
 		goto error3;
 	    }
 	} else {
-	    if (bios.bus == BUS_PCI) {
-		xf86DrvMsg(screen, X_WARNING,
-			   "Option BiosLocation for primary device ignored: "
-			   "It points to PCI.\n");
+	xf86DrvMsg(screen,X_CONFIG,"Overriding bios location: Legacy\n");
+	videoBiosSearch = TRUE;
+      }
+
+    } else if (xf86IsEntityPrimary(entityIndex) && !(initPrimary(options))) {
+      /* BIOS of primary card has been mapped in ISA space by POST */
+      videoBiosSearch = TRUE;
+
+      if (bios.bus != BUS_NONE) {
+	char *msg= bios.bus==BUS_PCI ? "PCI" : "FILE";
+
+	xf86DrvMsg(screen, X_WARNING, "Option BiosLocation for primary device"
+		   " ignored: It points to %s.\n", msg);
 		xf86DrvMsg(screen, X_WARNING,
 			   "You must set Option InitPrimary also\n");
 	    }
 
-	    cs = ((CARD16*)0)[(0x10<<1) + 1];
+    } else {
+      /* soft coldboot of a secondary card */
+      int pci_entity=-1;
 
-	    bios_base = (unsigned char *)(cs << 4);
+      if(bios.bus == BUS_NONE) {        /* auto */
+	EntityInfoPtr pEnt = xf86GetEntityInfo(entityIndex);
+	BusType loc_type = pEnt->location.type;
+	xfree(pEnt);
 
-	    if (!int10_check_bios(screen, cs, bios_base)) {
-		cs = ((CARD16*)0)[(0x42 << 1) + 1];
-		bios_base = (unsigned char *)(cs << 4);
-		if (!int10_check_bios(screen, cs, bios_base)) {
-		    cs = V_BIOS >> 4;
-		    bios_base = (unsigned char *)(cs << 4);
-		    if (!int10_check_bios(screen, cs, bios_base)) {
-			xf86DrvMsg(screen, X_ERROR, "No V_BIOS found\n");
+	switch(loc_type) {
+	case BUS_ISA:
+	  videoBiosSearch = TRUE;
+	  break;
+	case BUS_PCI:
+	  cs = V_BIOS>>4;
+	  pci_entity = entityIndex;
+	  break;
+	default:
+	  xf86DrvMsg(screen, X_ERROR, "Unknown entity location.type %i\n", 
+		     loc_type);
 			goto error3;
 		    }
+      } else if(bios.bus == BUS_PCI) { /* user specified PCI:b:d:f */
+	int pb=bios.location.pci.bus;
+	int pd=bios.location.pci.dev;
+	int pf=bios.location.pci.func;
+
+	xf86DrvMsg(screen,X_CONFIG,"Overriding bios location: PCI:%i:%i:%i\n", 
+		   pb, pd, pf);
+	if((pci_entity = xf86GetPciEntity(pb, pd, pf)) < 0) {
+	  xf86DrvMsg(screen, X_ERROR, "Cannot find specified PCI entity,"
+		     " got %i\n", pci_entity);
+	  goto error3;
 		}
-	    }
+	cs = V_BIOS>>4;
+      } else if(bios.bus == BUS_last) { /* user specified file:pathname */
+	char *path=bios.location.pathname;
+	unsigned char *bbase=(unsigned char *)V_BIOS;
+	int fd, bsize=512, bcnt, i;
+
+	if((fd=open(path, O_RDONLY)) < 0) {
+	  xf86DrvMsg(screen, X_ERROR, "Cannot read V_BIOS file:%s: %s\n", 
+		     path, strerror(errno));
+	  goto error3;
 	}
 
-	xf86DrvMsg(screen, X_INFO, "Primary V_BIOS segment is: 0x%lx\n", cs);
+	for(i=0, bcnt=1; i<bcnt; i++) {
+	  int len;
 
-	pInt->BIOSseg = cs;
-	set_return_trap(pInt);
-#ifdef _PC	
-	pInt->Flags = Flags & (SET_BIOS_SCRATCH | RESTORE_BIOS_SCRATCH);
-	if (! (pInt->Flags & SET_BIOS_SCRATCH))
-	    pInt->Flags &= ~RESTORE_BIOS_SCRATCH;
-  	xf86Int10SaveRestoreBIOSVars(pInt, TRUE);
-#endif
-    } else {
-        EntityInfoPtr pEnt = xf86GetEntityInfo(pInt->entityIndex);
-	BusType location_type;
-
-	if (bios.bus != BUS_NONE) {
-	    switch (location_type = bios.bus) {
-	    case BUS_PCI:
-		xf86DrvMsg(screen,X_CONFIG,"Overriding bios location: "
-			   "PCI:%i:%i%i\n",bios.location.pci.bus,
-			   bios.location.pci.dev,bios.location.pci.func);
-		break;
-	    case BUS_ISA:
-		if (bios.location.legacy)
-		    xf86DrvMsg(screen,X_CONFIG,"Overriding bios location: "
-			       "Legacy:0x%x\n",bios.location.legacy);
-		else
-		    xf86DrvMsg(screen,X_CONFIG,"Overriding bios location: "
-			       "Legacy\n");
-		break;
-	    default:
-		break;
+	  if((len=read(fd, &bbase[i*bsize], bsize)) < 0) {
+	    xf86DrvMsg(screen, X_ERROR, "Cannot read V_BIOS file:%s:"
+		       " %s\n", path, strerror(errno));
+	  errorfd:
+	    close(fd);
+	    goto error3;
+	  }
+	  if(len < bsize) {
+	    xf86DrvMsg(screen, X_ERROR, "Cannot read V_BIOS file:%s:"
+		       " EOF read %i/%i bytes for block %i\n", path, 
+		       len, bsize, i);
+	    goto errorfd;
+	  }
+	  if(i == 0) {
+	    if (bbase[0]!=0x55 || bbase[1]!=0xAA || bbase[2]==0) {
+	      xf86DrvMsg(screen, X_ERROR, "V_BIOS file:%s bad signature"
+			 " %02x %02x %02x\n", path, 
+			 bbase[0], bbase[1], bbase[2]);
+	      goto errorfd;
+	    }
+	    bcnt = bbase[2];
 	    }
+	}
+	close(fd);
+	xf86DrvMsg(screen, X_INFO, "Read %i kB V_BIOS from file:%s\n", 
+		   bcnt>>1, path);
+	cs = V_BIOS>>4;
+#if 0
+	fd=open("/root/out.bio", O_WRONLY | O_CREAT);
+	write(fd, bbase, bsize*bcnt);
+	close(fd);
+	goto error3;
+#endif
 	} else
-	    location_type = pEnt->location.type;
+	videoBiosSearch = TRUE;
 
-	switch (location_type) {
-	case BUS_PCI:
-	{
-	    int pci_entity;
-	    
-	    if (bios.bus == BUS_PCI)
-		pci_entity = xf86GetPciEntity(bios.location.pci.bus,
-					      bios.location.pci.dev,
-					      bios.location.pci.func);
-	    else 
-		pci_entity = pInt->entityIndex;
+      if(pci_entity>=0) {
 	    if (!mapPciRom(pci_entity, (unsigned char *)(V_BIOS))) {
-	        xf86DrvMsg(screen, X_ERROR, "Cannot read V_BIOS\n");
+	  xf86DrvMsg(screen, X_ERROR, "Cannot read V_BIOS from"
+		     " pci_entity %i\n", pci_entity);
 		goto error3;
 	    }
-	    pInt->BIOSseg = V_BIOS >> 4;
-	    break;
 	}
-	case BUS_ISA:
-	    if (bios.bus == BUS_ISA && bios.location.legacy) {
-		cs = bios.location.legacy >> 4;
-		bios_base = (unsigned char *)(cs << 4);
-		if (!int10_check_bios(screen, cs, bios_base)) {
-		    xf86DrvMsg(screen,X_ERROR,"No V_BIOS found "
-			       "on override address %p\n",bios_base);
-		    goto error3;
 		}
-	    } else {
-		cs = ((CARD16*)0)[(0x10<<1)+1];
+
+    if(videoBiosSearch) {
+      cs = ((CARD16*)0)[(0x10 << 1) + 1];
 		bios_base = (unsigned char *)(cs << 4);
 		
 		if (!int10_check_bios(screen, cs, bios_base)) {
-		    cs = ((CARD16*)0)[(0x42<<1)+1];
+	cs = ((CARD16*)0)[(0x42 << 1) + 1];
 		    bios_base = (unsigned char *)(cs << 4);
 		    if (!int10_check_bios(screen, cs, bios_base)) {
 			cs = V_BIOS >> 4;
 			bios_base = (unsigned char *)(cs << 4);
 			if (!int10_check_bios(screen, cs, bios_base)) {
-			    xf86DrvMsg(screen,X_ERROR,"No V_BIOS found\n");
+	    xf86DrvMsg(screen, X_ERROR, "No V_BIOS found\n");
 			    goto error3;
 			}
 		    }
 		}
+
+      xf86DrvMsg(screen, X_INFO, "Primary V_BIOS segment is: 0x%04lx\n", cs);
 	    }
-	    xf86DrvMsg(screen,X_INFO,"Primary V_BIOS segment is: 0x%lx\n",cs);
-	    pInt->BIOSseg = cs;
-	    break;
-	default:
+
+    { /* failsafe test: should always succeed */
+      unsigned char *bbase=(unsigned char *)(cs << 4);
+      if (bbase[0]!=0x55 || bbase[1]!=0xAA || bbase[2]==0) {
+	xf86DrvMsg(screen, X_ERROR, "V_BIOS at %p bad signature"
+		   " %02x %02x %02x\n", bbase, bbase[0], bbase[1], bbase[2]);
 	    goto error3;
 	}
-	xfree(pEnt);
+    }
+
+    pInt->BIOSseg = cs;
+
+    if (xf86IsEntityPrimary(entityIndex) && !(initPrimary(options))) {
+
+	set_return_trap(pInt);
+#ifdef _PC	
+	pInt->Flags = Flags & (SET_BIOS_SCRATCH | RESTORE_BIOS_SCRATCH);
+	if (! (pInt->Flags & SET_BIOS_SCRATCH))
+	    pInt->Flags &= ~RESTORE_BIOS_SCRATCH;
+  	xf86Int10SaveRestoreBIOSVars(pInt, TRUE);
+#endif
+    } else {
 	pInt->num = 0xe6;
 	reset_int_vect(pInt);
 	set_return_trap(pInt);
