From be0fa1f63aa6db7ad3e39b35815f1af014606fa1 Mon Sep 17 00:00:00 2001 From: Alexander Boettcher Date: Wed, 20 Feb 2013 11:44:12 +0100 Subject: [PATCH] dde_kit: enable pci lookup by device_class Instead of trying all PCI devices by a specific PCI driver, now the device or the device class can be limited to the one actually supported by the specific driver. --- dde_ipxe/src/lib/dde_ipxe/nic.c | 7 ++++++- dde_oss/src/drivers/oss/driver.cc | 16 +++++++--------- os/include/dde_kit/pci.h | 22 +++++++++++++++++++++- os/src/lib/dde_kit/pci.cc | 9 +++++---- os/src/lib/dde_kit/pci_tree.cc | 13 +++++++------ os/src/lib/dde_kit/pci_tree.h | 2 +- os/src/test/dde_kit/test.cc | 2 +- 7 files changed, 48 insertions(+), 23 deletions(-) diff --git a/dde_ipxe/src/lib/dde_ipxe/nic.c b/dde_ipxe/src/lib/dde_ipxe/nic.c index 798347eea..5f40d1d5e 100644 --- a/dde_ipxe/src/lib/dde_ipxe/nic.c +++ b/dde_ipxe/src/lib/dde_ipxe/nic.c @@ -293,7 +293,12 @@ int dde_ipxe_nic_init(void) { dde_kit_init(); dde_kit_timer_init(0, 0); - dde_kit_pci_init(); + enum { + CLASS_MASK = 0xff0000, + CLASS_NETWORK = PCI_BASE_CLASS_NETWORK << 16 + }; + dde_kit_pci_init(CLASS_NETWORK, CLASS_MASK); + dde_kit_lock_init(&ipxe_lock); slab_init(); diff --git a/dde_oss/src/drivers/oss/driver.cc b/dde_oss/src/drivers/oss/driver.cc index de6903b61..e395d95b2 100644 --- a/dde_oss/src/drivers/oss/driver.cc +++ b/dde_oss/src/drivers/oss/driver.cc @@ -30,14 +30,18 @@ class Driver { private: - enum { MAX_DRIVER = 10 }; + enum { + MAX_DRIVER = 10, + PCI_CLASS_MASK = 0xff0000, + PCI_CLASS_MULTIMEDIA = 0x40000, /* class multimedia */ + }; oss_driver *_drivers[MAX_DRIVER + 1]; /* registered drivers */ Driver() { Genode::memset(_drivers, 0, sizeof(oss_driver *) * (MAX_DRIVER + 1)); - dde_kit_pci_init(); + dde_kit_pci_init(PCI_CLASS_MULTIMEDIA, PCI_CLASS_MASK); } /** @@ -81,19 +85,13 @@ class Driver Pci::Device_capability _scan_pci(Pci::Device_capability const &prev, Pci::Connection &pci) { - /* check for audio device class */ - enum { - CLASS_MASK = 0xff0000, - CLASS_MULTIMEDIA = 0x40000, /* class multimedia */ - }; - /* * Just test for multimedia class, since some devices (e.g., Intel * hda) do set the subclass to something different then audio (0x1). */ Pci::Device_capability cap; - cap = pci.next_device(prev, CLASS_MULTIMEDIA, CLASS_MASK); + cap = pci.next_device(prev, PCI_CLASS_MULTIMEDIA, PCI_CLASS_MASK); if (prev.valid()) pci.release_device(prev); return cap; diff --git a/os/include/dde_kit/pci.h b/os/include/dde_kit/pci.h index 434861023..d22a6db11 100644 --- a/os/include/dde_kit/pci.h +++ b/os/include/dde_kit/pci.h @@ -137,8 +137,28 @@ int dde_kit_pci_next_device(int *bus, int *dev, int *fun); /** * Initialize PCI subsystem + * + * The PCI subsystem can be instructed to request solely a specific PCI device + * or a specific PCI subset (one class or multiple). The parameters are + * described by the parameters device_class and class_mask, which are used to + * filter PCI class codes as described by the pseudo code: + * + * for each 'pci_device' out of 'all_pci_devices' try + * { + * bool nohit = (pci_device.class_code() ^ device_class) & class_mask + * if (!nohit) + * use 'pci_device' with this PCI subsystem + * } + * + * If no restriction to the PCI subsystem should be applied, use 0 for the + * device_class and class_mask. + * + * \param device_class filter applied with 'bitwise XOR' operand to the class + * code of each PCI device + * \param class_mask filter applied with 'bitwise AND' operand to the result + * out of device_class and PCI class code of each device */ -void dde_kit_pci_init(void); +void dde_kit_pci_init(unsigned device_class, unsigned class_mask); #endif /* _INCLUDE__DDE_KIT__PCI_H_ */ diff --git a/os/src/lib/dde_kit/pci.cc b/os/src/lib/dde_kit/pci.cc index 3f706093b..37f3970f7 100644 --- a/os/src/lib/dde_kit/pci.cc +++ b/os/src/lib/dde_kit/pci.cc @@ -31,9 +31,10 @@ extern "C" { static const bool verbose = false; -static Dde_kit::Pci_tree *pci_tree() +static Dde_kit::Pci_tree *pci_tree(unsigned device_class = 0, + unsigned class_mask = 0) { - static Dde_kit::Pci_tree _pci_tree; + static Dde_kit::Pci_tree _pci_tree(device_class, class_mask); return &_pci_tree; } @@ -141,10 +142,10 @@ extern "C" int dde_kit_pci_next_device(int *bus, int *dev, int *fun) ** Initialization ** ********************/ -extern "C" void dde_kit_pci_init(void) +extern "C" void dde_kit_pci_init(unsigned device_class, unsigned class_mask) { try { - pci_tree(); + pci_tree(device_class, class_mask); } catch (...) { PERR("PCI initialization failed"); } diff --git a/os/src/lib/dde_kit/pci_tree.cc b/os/src/lib/dde_kit/pci_tree.cc index 1780c010c..2227470a1 100644 --- a/os/src/lib/dde_kit/pci_tree.cc +++ b/os/src/lib/dde_kit/pci_tree.cc @@ -49,24 +49,25 @@ void Pci_device::config_write(unsigned char address, uint32_t val, ** PCI bus ** *************/ -Pci_tree::Pci_tree() +Pci_tree::Pci_tree(unsigned device_class, unsigned class_mask) { /* * Iterate through all accessible devices and populate virtual * PCI bus tree. */ - Pci::Device_capability prev_device_cap, - device_cap = _pci_drv.first_device(); + Pci::Device_capability prev_device_cap; + Pci::Device_capability device_cap = _pci_drv.first_device(device_class, + class_mask); while (device_cap.valid()) { - Pci_device *device = new (env()->heap()) - Pci_device(device_cap); + Pci_device *device = new (env()->heap()) Pci_device(device_cap); _devices.insert(device); prev_device_cap = device_cap; - device_cap = _pci_drv.next_device(prev_device_cap); + device_cap = _pci_drv.next_device(prev_device_cap, device_class, + class_mask); } if (verbose) diff --git a/os/src/lib/dde_kit/pci_tree.h b/os/src/lib/dde_kit/pci_tree.h index 5b10325a6..809c06f2b 100644 --- a/os/src/lib/dde_kit/pci_tree.h +++ b/os/src/lib/dde_kit/pci_tree.h @@ -198,7 +198,7 @@ namespace Dde_kit { public: - Pci_tree(); + Pci_tree(unsigned device_class, unsigned class_mask); uint32_t config_read(int bus, int dev, int fun, unsigned char address, Pci::Device::Access_size size) diff --git a/os/src/test/dde_kit/test.cc b/os/src/test/dde_kit/test.cc index c17a3597f..6462b3740 100644 --- a/os/src/test/dde_kit/test.cc +++ b/os/src/test/dde_kit/test.cc @@ -478,7 +478,7 @@ static void test_pci() { PDBG("=== starting PCI test ==="); - dde_kit_pci_init(); + dde_kit_pci_init(0, 0); enum { BUS_MAX = 4, DEV_MAX = 8 };