Index: xf86pciBus.c =================================================================== RCS file: /cvs/xorg/xc/programs/Xserver/hw/xfree86/common/xf86pciBus.c,v retrieving revision 1.4.2.2 retrieving revision 1.15 diff -u -r1.4.2.2 -r1.15 --- xf86pciBus.c 25 Jan 2005 02:52:42 -0000 1.4.2.2 +++ xf86pciBus.c 4 Jul 2005 18:41:02 -0000 1.15 @@ -172,6 +176,17 @@ return (!base || (base == mask)); } +static Bool +IsBaseUnassigned64(CARD32 base0, CARD32 base1) +{ + base0 &= ~PCI_MAP_MEMORY_ATTR_MASK; + base1 &= 0xffffffff; + + return ((!base0 && !base1) + || ((base0 == ~PCI_MAP_MEMORY_ATTR_MASK) + && (base1 == 0xffffffff))); +} + static void FindPCIVideoInfo(void) { @@ -275,138 +296,67 @@ } if (PCINONSYSTEMCLASSES(baseclass, subclass)) { - if (info->size[0] && IsBaseUnassigned(pcrp->pci_base0)) - pcrp->pci_base0 = pciCheckForBrokenBase(pcrp->tag, 0); - if (info->size[1] && IsBaseUnassigned(pcrp->pci_base1)) - pcrp->pci_base1 = pciCheckForBrokenBase(pcrp->tag, 1); - if (info->size[2] && IsBaseUnassigned(pcrp->pci_base2)) - pcrp->pci_base2 = pciCheckForBrokenBase(pcrp->tag, 2); - if (info->size[3] && IsBaseUnassigned(pcrp->pci_base3)) - pcrp->pci_base3 = pciCheckForBrokenBase(pcrp->tag, 3); - if (info->size[4] && IsBaseUnassigned(pcrp->pci_base4)) - pcrp->pci_base4 = pciCheckForBrokenBase(pcrp->tag, 4); - if (info->size[5] && IsBaseUnassigned(pcrp->pci_base5)) - pcrp->pci_base5 = pciCheckForBrokenBase(pcrp->tag, 5); + /* + * Check of a PCI base is unassigned. If so + * attempt to fix it. Validation will determine + * if the value was correct later on. + */ + CARD32 *base = &pcrp->pci_base0; + + for (j = 0; j < 6; j++) { + if (!PCI_MAP_IS64BITMEM(base[j])) { + if (info->size[j] && IsBaseUnassigned(base[j])) + base[j] = pciCheckForBrokenBase(pcrp->tag, j); + } else { + if (j == 5) /* bail out */ + break; + if (info->size[j] + && IsBaseUnassigned64(base[j],base[j+1])) { + base[j] = pciCheckForBrokenBase(pcrp->tag, j); + j++; + base[j] = pciCheckForBrokenBase(pcrp->tag, j); + } + } + } } /* * 64-bit base addresses are checked for and avoided on 32-bit * platforms. */ - if (pcrp->pci_base0) { - if (pcrp->pci_base0 & PCI_MAP_IO) { - info->ioBase[0] = (memType)PCIGETIO(pcrp->pci_base0); - info->type[0] = pcrp->pci_base0 & PCI_MAP_IO_ATTR_MASK; - } else { - info->type[0] = pcrp->pci_base0 & PCI_MAP_MEMORY_ATTR_MASK; - info->memBase[0] = (memType)PCIGETMEMORY(pcrp->pci_base0); - if (PCI_MAP_IS64BITMEM(pcrp->pci_base0)) { - mem64 = TRUE; -#if defined(LONG64) || defined(WORD64) - info->memBase[0] |= - (memType)PCIGETMEMORY64HIGH(pcrp->pci_base0) << 32; -#else - if (pcrp->pci_base1) - info->memBase[0] = 0; -#endif - } - } - } + for (j = 0; j < 6; ++j) { + CARD32 bar = (&pcrp->pci_base0)[j]; - if (pcrp->pci_base1 && !mem64) { - if (pcrp->pci_base1 & PCI_MAP_IO) { - info->ioBase[1] = (memType)PCIGETIO(pcrp->pci_base1); - info->type[1] = pcrp->pci_base1 & PCI_MAP_IO_ATTR_MASK; - } else { - info->type[1] = pcrp->pci_base1 & PCI_MAP_MEMORY_ATTR_MASK; - info->memBase[1] = (memType)PCIGETMEMORY(pcrp->pci_base1); - if (PCI_MAP_IS64BITMEM(pcrp->pci_base1)) { - mem64 = TRUE; + if (bar != 0) { + if (bar & PCI_MAP_IO) { + info->ioBase[j] = (memType)PCIGETIO(bar); + info->type[j] = bar & PCI_MAP_IO_ATTR_MASK; + } else { + info->type[j] = bar & PCI_MAP_MEMORY_ATTR_MASK; + info->memBase[j] = (memType)PCIGETMEMORY(bar); + if (PCI_MAP_IS64BITMEM(bar)) { + if (j == 5) { + xf86MsgVerb(X_WARNING, 0, + "****BAR5 specified as 64-bit wide, " + "which is not possible. " + "Ignoring BAR5.****\n"); + info->memBase[j] = 0; + } else { + CARD32 bar_hi = PCIGETMEMORY64HIGH((&pcrp->pci_base0)[j]); #if defined(LONG64) || defined(WORD64) - info->memBase[1] |= - (memType)PCIGETMEMORY64HIGH(pcrp->pci_base1) << 32; + /* 64 bit architecture */ + info->memBase[j] |= + (memType)bar_hi << 32; #else - if (pcrp->pci_base2) - info->memBase[1] = 0; -#endif - } - } - } else - mem64 = FALSE; - - if (pcrp->pci_base2 && !mem64) { - if (pcrp->pci_base2 & PCI_MAP_IO) { - info->ioBase[2] = (memType)PCIGETIO(pcrp->pci_base2); - info->type[2] = pcrp->pci_base2 & PCI_MAP_IO_ATTR_MASK; - } else { - info->type[2] = pcrp->pci_base2 & PCI_MAP_MEMORY_ATTR_MASK; - info->memBase[2] = (memType)PCIGETMEMORY(pcrp->pci_base2); - if (PCI_MAP_IS64BITMEM(pcrp->pci_base2)) { - mem64 = TRUE; -#if defined(LONG64) || defined(WORD64) - info->memBase[2] |= - (memType)PCIGETMEMORY64HIGH(pcrp->pci_base2) << 32; -#else - if (pcrp->pci_base3) - info->memBase[2] = 0; -#endif - } - } - } else - mem64 = FALSE; - - if (pcrp->pci_base3 && !mem64) { - if (pcrp->pci_base3 & PCI_MAP_IO) { - info->ioBase[3] = (memType)PCIGETIO(pcrp->pci_base3); - info->type[3] = pcrp->pci_base3 & PCI_MAP_IO_ATTR_MASK; - } else { - info->type[3] = pcrp->pci_base3 & PCI_MAP_MEMORY_ATTR_MASK; - info->memBase[3] = (memType)PCIGETMEMORY(pcrp->pci_base3); - if (PCI_MAP_IS64BITMEM(pcrp->pci_base3)) { - mem64 = TRUE; -#if defined(LONG64) || defined(WORD64) - info->memBase[3] |= - (memType)PCIGETMEMORY64HIGH(pcrp->pci_base3) << 32; -#else - if (pcrp->pci_base4) - info->memBase[3] = 0; -#endif - } - } - } else - mem64 = FALSE; - - if (pcrp->pci_base4 && !mem64) { - if (pcrp->pci_base4 & PCI_MAP_IO) { - info->ioBase[4] = (memType)PCIGETIO(pcrp->pci_base4); - info->type[4] = pcrp->pci_base4 & PCI_MAP_IO_ATTR_MASK; - } else { - info->type[4] = pcrp->pci_base4 & PCI_MAP_MEMORY_ATTR_MASK; - info->memBase[4] = (memType)PCIGETMEMORY(pcrp->pci_base4); - if (PCI_MAP_IS64BITMEM(pcrp->pci_base4)) { - mem64 = TRUE; -#if defined(LONG64) || defined(WORD64) - info->memBase[4] |= - (memType)PCIGETMEMORY64HIGH(pcrp->pci_base4) << 32; -#else - if (pcrp->pci_base5) - info->memBase[4] = 0; + if (bar_hi != 0) + info->memBase[j] = 0; #endif + ++j; /* Step over the next BAR */ + } + } } } - } else - mem64 = FALSE; - - if (pcrp->pci_base5 && !mem64) { - if (pcrp->pci_base5 & PCI_MAP_IO) { - info->ioBase[5] = (memType)PCIGETIO(pcrp->pci_base5); - info->type[5] = pcrp->pci_base5 & PCI_MAP_IO_ATTR_MASK; - } else { - info->type[5] = pcrp->pci_base5 & PCI_MAP_MEMORY_ATTR_MASK; - info->memBase[5] = (memType)PCIGETMEMORY(pcrp->pci_base5); - } - } else - mem64 = FALSE; + } info->listed_class = pcrp->listed_class; } i++;