hrev45772 adds 1 changeset to branch 'master' old head: e2a87acacdba3d08deae06280d4d75ecab8d89b6 new head: 343751a96c43a0c3074d6f1d5526ff3ae80fb267 overview: http://cgit.haiku-os.org/haiku/log/?qt=range&q=343751a+%5Ee2a87ac ---------------------------------------------------------------------------- 343751a: pci: takes into account the 64bit address type * when the 64bit address type is used, it means a BAR takes the size of two. For the moment we just set the next base_registers to the high address and skip to the next valid BAR. The struct is now zeroed on creation. * the pci device information is more correct now, though it would be easier to have BAR address and size with a 64bit types in the struct pci_info. [ Jérôme Duval <jerome.duval@xxxxxxxxx> ] ---------------------------------------------------------------------------- Revision: hrev45772 Commit: 343751a96c43a0c3074d6f1d5526ff3ae80fb267 URL: http://cgit.haiku-os.org/haiku/commit/?id=343751a Author: Jérôme Duval <jerome.duval@xxxxxxxxx> Date: Wed Jun 19 18:44:52 2013 UTC ---------------------------------------------------------------------------- 2 files changed, 26 insertions(+), 19 deletions(-) src/add-ons/kernel/bus_managers/pci/pci.cpp | 41 +++++++++++++++---------- src/add-ons/kernel/bus_managers/pci/pci.h | 4 +-- ---------------------------------------------------------------------------- diff --git a/src/add-ons/kernel/bus_managers/pci/pci.cpp b/src/add-ons/kernel/bus_managers/pci/pci.cpp index e7980ad..67f0585 100644 --- a/src/add-ons/kernel/bus_managers/pci/pci.cpp +++ b/src/add-ons/kernel/bus_managers/pci/pci.cpp @@ -1138,6 +1138,7 @@ PCI::_CreateDevice(PCIBus *parent, uint8 device, uint8 function) newDev->bus = parent->bus; newDev->device = device; newDev->function = function; + memset(&newDev->info, 0, sizeof(newDev->info)); _ReadBasicInfo(newDev); @@ -1172,9 +1173,9 @@ PCI::_BarSize(uint32 bits, uint32 mask) } -void +size_t PCI::_GetBarInfo(PCIDev *dev, uint8 offset, uint32 *_address, uint32 *_size, - uint8 *_flags) + uint8 *_flags, uint32 *_highAddress) { uint32 oldValue = ReadConfig(dev->domain, dev->bus, dev->device, dev->function, offset, 4); @@ -1186,14 +1187,20 @@ PCI::_GetBarInfo(PCIDev *dev, uint8 offset, uint32 *_address, uint32 *_size, oldValue); uint32 mask = PCI_address_memory_32_mask; + bool is64bit = (oldValue & PCI_address_type_64) != 0; if ((oldValue & PCI_address_space) == PCI_address_space) mask = PCI_address_io_mask; + else if (is64bit && _highAddress != NULL) { + *_highAddress = ReadConfig(dev->domain, dev->bus, dev->device, + dev->function, offset + 4, 4); + } *_address = oldValue & mask; if (_size != NULL) *_size = _BarSize(newValue, mask); if (_flags != NULL) - *_flags = newValue & ~mask; + *_flags = oldValue & ~mask; + return is64bit ? 2 : 1; } @@ -1274,11 +1281,15 @@ PCI::_ReadHeaderInfo(PCIDev *dev) // get BAR size infos _GetRomBarInfo(dev, PCI_rom_base, &dev->info.u.h0.rom_base_pci, &dev->info.u.h0.rom_size); - for (int i = 0; i < 6; i++) { - _GetBarInfo(dev, PCI_base_registers + 4*i, + for (int i = 0; i < 6;) { + size_t barSize = _GetBarInfo(dev, PCI_base_registers + 4 * i, &dev->info.u.h0.base_registers_pci[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); + dev->info.u.h0.base_registers[i] = (addr_t)pci_ram_address( + (void *)(addr_t)dev->info.u.h0.base_registers_pci[i]); + i += barSize; } // restore PCI device address decoding @@ -1287,10 +1298,6 @@ PCI::_ReadHeaderInfo(PCIDev *dev) dev->info.u.h0.rom_base = (addr_t)pci_ram_address( (void *)(addr_t)dev->info.u.h0.rom_base_pci); - for (int i = 0; i < 6; i++) { - dev->info.u.h0.base_registers[i] = (addr_t)pci_ram_address( - (void *)(addr_t)dev->info.u.h0.base_registers_pci[i]); - } dev->info.u.h0.cardbus_cis = ReadConfig(dev->domain, dev->bus, dev->device, dev->function, PCI_cardbus_cis, 4); @@ -1320,11 +1327,15 @@ PCI::_ReadHeaderInfo(PCIDev *dev) _GetRomBarInfo(dev, PCI_bridge_rom_base, &dev->info.u.h1.rom_base_pci); - for (int i = 0; i < 2; i++) { - _GetBarInfo(dev, PCI_base_registers + 4*i, + for (int i = 0; i < 2;) { + size_t barSize = _GetBarInfo(dev, PCI_base_registers + 4 * i, &dev->info.u.h1.base_registers_pci[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); + dev->info.u.h1.base_registers[i] = (addr_t)pci_ram_address( + (void *)(addr_t)dev->info.u.h1.base_registers_pci[i]); + i += barSize; } // restore PCI device address decoding @@ -1333,10 +1344,6 @@ PCI::_ReadHeaderInfo(PCIDev *dev) dev->info.u.h1.rom_base = (addr_t)pci_ram_address( (void *)(addr_t)dev->info.u.h1.rom_base_pci); - for (int i = 0; i < 2; i++) { - dev->info.u.h1.base_registers[i] = (addr_t)pci_ram_address( - (void *)(addr_t)dev->info.u.h1.base_registers_pci[i]); - } dev->info.u.h1.primary_bus = ReadConfig(dev->domain, dev->bus, dev->device, dev->function, PCI_primary_bus, 1); diff --git a/src/add-ons/kernel/bus_managers/pci/pci.h b/src/add-ons/kernel/bus_managers/pci/pci.h index 921aebc..c86676f 100644 --- a/src/add-ons/kernel/bus_managers/pci/pci.h +++ b/src/add-ons/kernel/bus_managers/pci/pci.h @@ -134,9 +134,9 @@ private: void _RefreshDeviceInfo(PCIBus *bus); uint32 _BarSize(uint32 bits, uint32 mask); - void _GetBarInfo(PCIDev *dev, uint8 offset, + size_t _GetBarInfo(PCIDev *dev, uint8 offset, uint32 *address, uint32 *size = 0, - uint8 *flags = 0); + uint8 *flags = 0, uint32 *highAddress = 0); void _GetRomBarInfo(PCIDev *dev, uint8 offset, uint32 *address, uint32 *size = 0, uint8 *flags = 0);