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(lenlocation.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; iBIOSseg = 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);