On 05/03/12 23:12, Gerd Hoffmann wrote: > Hi, > >> I can either send a patch over existing patches, or send new series or both. > For testing a incremental patch is fine, for merge a new series with the > fixes squashed into the buggy patches is needed. > > cheers, > Gerd Sure. Here are the hot fixes for the "bridge" test, please apply the patch over this series:
diff --git a/src/pciinit.c b/src/pciinit.c index 9c41e3c..384209d 100644 --- a/src/pciinit.c +++ b/src/pciinit.c @@ -326,10 +326,14 @@ pci_bios_init_bus(void) static u64 pci_size_roundup(u64 size) { - int index = __fls((u32)((size - 1) >> 32)); - if (!index) - index = __fls((u32)(size - 1)); - return 0x1 << (index + 1); + int rest = !!(size & (size - 1)); + int index; + if (size >> 32) { + index = __fls((u32)(size >> 32)); + return 0x1ULL << (index + rest + 32); + } + index = __fls((u32)(size)); + return 0x1ULL << (index + rest); } static u64 @@ -372,6 +376,18 @@ pci_get_bar_size(struct pci_device *pci, int bar, return (u32)((~(sz & mask)) + 1); } +static int pci_bridge_is64bit(struct pci_device *pci) +{ + u32 pmem = pci_config_readl(pci->bdf, PCI_PREF_MEMORY_BASE); + if (!pmem) { + pci_config_writel(pci->bdf, PCI_PREF_MEMORY_BASE, 0xfff0fff0); + pmem = pci_config_readl(pci->bdf, PCI_PREF_MEMORY_BASE); + pci_config_writel(pci->bdf, PCI_PREF_MEMORY_BASE, 0x0); + } + if ((pmem & PCI_PREF_RANGE_TYPE_MASK) == PCI_PREF_RANGE_TYPE_64) + return 1; + return 0; +} static u64 pci_region_max_size(struct pci_region *r) { u64 max = 0; @@ -446,7 +462,9 @@ static int pci_bios_fill_regions(struct pci_region *regions) for (type = 0; type < PCI_REGION_TYPE_COUNT; type++, this_region++, parent++) { /* Only prefetchable bridge regions can be 64bit */ - is64bit = (type == PCI_REGION_TYPE_PREFMEM); + is64bit = 0; + if (type == PCI_REGION_TYPE_PREFMEM) + is64bit = pci_bridge_is64bit(pci); entry = pci_region_create_entry(parent, pci, 0, type, is64bit); if (!entry) return -1; @@ -475,7 +493,7 @@ static int pci_bios_fill_regions(struct pci_region *regions) } } - for (i = (MaxPCIBus + 1) * PCI_REGION_TYPE_COUNT ; i < 0; i--) { + for (i = (MaxPCIBus + 1) * PCI_REGION_TYPE_COUNT; i > 0; i--) { struct pci_region_entry *this_entry = regions[i-1].this_entry; if(!this_entry) continue; @@ -491,7 +509,7 @@ static int pci_bios_fill_regions(struct pci_region *regions) size = (size > min_size) ? size : min_size; this_entry->is64bit = is64bit; this_entry->size = pci_size_roundup(size); - dump_entry(entry); + dump_entry(this_entry); } return 0; }