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.
This commit is contained in:
Alexander Boettcher 2013-02-20 11:44:12 +01:00 committed by Norman Feske
parent ce075c05b9
commit be0fa1f63a
7 changed files with 48 additions and 23 deletions

View File

@ -293,7 +293,12 @@ int dde_ipxe_nic_init(void)
{ {
dde_kit_init(); dde_kit_init();
dde_kit_timer_init(0, 0); 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); dde_kit_lock_init(&ipxe_lock);
slab_init(); slab_init();

View File

@ -30,14 +30,18 @@ class Driver
{ {
private: 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 */ oss_driver *_drivers[MAX_DRIVER + 1]; /* registered drivers */
Driver() Driver()
{ {
Genode::memset(_drivers, 0, sizeof(oss_driver *) * (MAX_DRIVER + 1)); 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::Device_capability _scan_pci(Pci::Device_capability const &prev,
Pci::Connection &pci) 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 * Just test for multimedia class, since some devices (e.g., Intel
* hda) do set the subclass to something different then audio (0x1). * hda) do set the subclass to something different then audio (0x1).
*/ */
Pci::Device_capability cap; 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()) if (prev.valid())
pci.release_device(prev); pci.release_device(prev);
return cap; return cap;

View File

@ -137,8 +137,28 @@ int dde_kit_pci_next_device(int *bus, int *dev, int *fun);
/** /**
* Initialize PCI subsystem * 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_ */ #endif /* _INCLUDE__DDE_KIT__PCI_H_ */

View File

@ -31,9 +31,10 @@ extern "C" {
static const bool verbose = false; 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; return &_pci_tree;
} }
@ -141,10 +142,10 @@ extern "C" int dde_kit_pci_next_device(int *bus, int *dev, int *fun)
** Initialization ** ** Initialization **
********************/ ********************/
extern "C" void dde_kit_pci_init(void) extern "C" void dde_kit_pci_init(unsigned device_class, unsigned class_mask)
{ {
try { try {
pci_tree(); pci_tree(device_class, class_mask);
} catch (...) { } catch (...) {
PERR("PCI initialization failed"); PERR("PCI initialization failed");
} }

View File

@ -49,24 +49,25 @@ void Pci_device::config_write(unsigned char address, uint32_t val,
** PCI bus ** ** PCI bus **
*************/ *************/
Pci_tree::Pci_tree() Pci_tree::Pci_tree(unsigned device_class, unsigned class_mask)
{ {
/* /*
* Iterate through all accessible devices and populate virtual * Iterate through all accessible devices and populate virtual
* PCI bus tree. * PCI bus tree.
*/ */
Pci::Device_capability prev_device_cap, Pci::Device_capability prev_device_cap;
device_cap = _pci_drv.first_device(); Pci::Device_capability device_cap = _pci_drv.first_device(device_class,
class_mask);
while (device_cap.valid()) { while (device_cap.valid()) {
Pci_device *device = new (env()->heap()) Pci_device *device = new (env()->heap()) Pci_device(device_cap);
Pci_device(device_cap);
_devices.insert(device); _devices.insert(device);
prev_device_cap = device_cap; 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) if (verbose)

View File

@ -198,7 +198,7 @@ namespace Dde_kit {
public: public:
Pci_tree(); Pci_tree(unsigned device_class, unsigned class_mask);
uint32_t config_read(int bus, int dev, int fun, unsigned char address, uint32_t config_read(int bus, int dev, int fun, unsigned char address,
Pci::Device::Access_size size) Pci::Device::Access_size size)

View File

@ -478,7 +478,7 @@ static void test_pci()
{ {
PDBG("=== starting PCI test ==="); PDBG("=== starting PCI test ===");
dde_kit_pci_init(); dde_kit_pci_init(0, 0);
enum { BUS_MAX = 4, DEV_MAX = 8 }; enum { BUS_MAX = 4, DEV_MAX = 8 };