[haiku-commits] haiku: hrev45772 - src/add-ons/kernel/bus_managers/pci

  • From: korli@xxxxxxxxxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Wed, 19 Jun 2013 21:05:27 +0200 (CEST)

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);


Other related posts: