bus_managers/pci: Properly handle 64-bit BAR addresses.
We need to call pci_ram_address() on the whole address, not just the lower 32 bits, and then store both components inside the PCI info (previously we were leaving the high bits unset.) Very few drivers bother to check if the address is 64-bit or not, and for the most part they don't need to care, since the PCI bus is at 0x0 physically and will pretty much never get anywhere near 4GB in size. But the XHCI driver read these, and so would get bogus values for the high 32 bits, as we were never setting those. Probably fixes #15040.
This commit is contained in:
@@ -1301,8 +1301,17 @@ PCI::_ReadHeaderInfo(PCIDev *dev)
|
|||||||
&dev->info.u.h0.base_register_sizes[i],
|
&dev->info.u.h0.base_register_sizes[i],
|
||||||
&dev->info.u.h0.base_register_flags[i],
|
&dev->info.u.h0.base_register_flags[i],
|
||||||
i < 5 ? &dev->info.u.h0.base_registers_pci[i + 1] : NULL);
|
i < 5 ? &dev->info.u.h0.base_registers_pci[i + 1] : NULL);
|
||||||
dev->info.u.h0.base_registers[i] = (uint32)pci_ram_address(
|
|
||||||
dev->info.u.h0.base_registers_pci[i]);
|
phys_addr_t addr = dev->info.u.h0.base_registers_pci[i];
|
||||||
|
if (barSize == 2) {
|
||||||
|
addr += ((phys_addr_t)dev->info.u.h0.base_registers_pci[i + 1])
|
||||||
|
<< 32;
|
||||||
|
}
|
||||||
|
addr = pci_ram_address(addr);
|
||||||
|
dev->info.u.h0.base_registers[i] = (uint32)addr;
|
||||||
|
if (barSize == 2)
|
||||||
|
dev->info.u.h0.base_registers[i + 1] = (uint32)(addr >> 32);
|
||||||
|
|
||||||
i += barSize;
|
i += barSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1346,9 +1355,17 @@ PCI::_ReadHeaderInfo(PCIDev *dev)
|
|||||||
&dev->info.u.h1.base_registers_pci[i],
|
&dev->info.u.h1.base_registers_pci[i],
|
||||||
&dev->info.u.h1.base_register_sizes[i],
|
&dev->info.u.h1.base_register_sizes[i],
|
||||||
&dev->info.u.h1.base_register_flags[i],
|
&dev->info.u.h1.base_register_flags[i],
|
||||||
i < 5 ? &dev->info.u.h1.base_registers_pci[i + 1] : NULL);
|
i < 2 ? &dev->info.u.h1.base_registers_pci[i + 1] : NULL);
|
||||||
dev->info.u.h1.base_registers[i] = (uint32)pci_ram_address(
|
|
||||||
dev->info.u.h1.base_registers_pci[i]);
|
phys_addr_t addr = dev->info.u.h1.base_registers_pci[i];
|
||||||
|
if (barSize == 2) {
|
||||||
|
addr += ((phys_addr_t)dev->info.u.h0.base_registers_pci[i + 1])
|
||||||
|
<< 32;
|
||||||
|
}
|
||||||
|
addr = pci_ram_address(addr);
|
||||||
|
dev->info.u.h1.base_registers[i] = (uint32)addr;
|
||||||
|
if (barSize == 2)
|
||||||
|
dev->info.u.h1.base_registers[i + 1] = (uint32)(addr >> 32);
|
||||||
i += barSize;
|
i += barSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user