feat: taken qsort from PDCLIB, Sorting drivers. Generic driver
structure. Driver ranking
This commit is contained in:
@@ -674,13 +674,13 @@ uint8_t ide_access(uint8_t direction, uint8_t drive, uint32_t lba, uint8_t numse
|
||||
PCI_DRIVER(
|
||||
.name = "pci-ide",
|
||||
.description = "Default PCI IDE Driver",
|
||||
.order = 0xFF, // let other block_dev_drivers precede if they can
|
||||
.pci_use_subclass = true,
|
||||
.rank = 10000, // let other block_dev_drivers precede if they can
|
||||
.validatable = true,
|
||||
.initialisable = true,
|
||||
.pci_class = PCI_CLASS_MASS_STORAGE,
|
||||
.pci_subclass = PCI_SUB_CLASS_IDE,
|
||||
|
||||
.match.class = PCI_CLASS_MASS_STORAGE,
|
||||
.match.subclass = PCI_SUB_CLASS_IDE,
|
||||
.mask.class = true,
|
||||
.mask.subclass = true,
|
||||
.validate = ide_pci_validate,
|
||||
.initialize = ide_pci_initialize,
|
||||
);
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#ifdef ENABLE_PCIPP
|
||||
|
||||
#include <drivers/pci_devices.h>
|
||||
#include <libc/sort.h>
|
||||
|
||||
#endif
|
||||
|
||||
@@ -34,17 +35,6 @@
|
||||
#define MASK_BAR_IOSPACE 0xFFFFFFFC
|
||||
#define MASK_BAR_MEMSPACE 0xFFFFFFF0
|
||||
|
||||
const struct pci_driver pci_internal_secondary_bus = {
|
||||
.name = "pci-secondary-bus",
|
||||
.description = "A PCI bus connected to the primary bus",
|
||||
.order = 0,
|
||||
.pci_class = 0x06,
|
||||
.pci_subclass = 0x04,
|
||||
.pci_use_subclass = true,
|
||||
.validate = NULL,
|
||||
.initialize = NULL,
|
||||
};
|
||||
|
||||
//const pci_driver *pci_drivers[MAX_PCI_DRIVERS];
|
||||
extern struct pci_driver __start_pci_driver[];
|
||||
extern struct pci_driver __stop_pci_driver[];
|
||||
@@ -55,6 +45,13 @@ pci_device pci_devices[MAX_PCI_DEVICES];
|
||||
|
||||
void pci_check_bus(uint8_t bus);
|
||||
|
||||
uint8_t used pci_secondary_bus_use(const pci_device *device) {
|
||||
uint8_t secondary_bus = pci_config_read_byte(device->bus, device->slot, device->func,
|
||||
PCI_CONFIG_SECONDARY_BUS_NUMBER);
|
||||
pci_check_bus(secondary_bus);
|
||||
return PCI_USE_OK;
|
||||
}
|
||||
|
||||
uint32_t pci_config_address(uint8_t bus, uint8_t slot, uint8_t func, uint8_t offset) {
|
||||
return PCI_CONFIG_ENABLE
|
||||
| ((uint32_t) bus << PCI_CONFIG_SHIFT_BUS_NUMBER)
|
||||
@@ -124,32 +121,35 @@ uint8_t pci_get_header_type(uint8_t bus, uint8_t slot, uint8_t func) {
|
||||
}
|
||||
|
||||
void pci_pick_driver(pci_device *device) {
|
||||
// check special drivers
|
||||
// PCI Secondary bus
|
||||
if (device->class == pci_internal_secondary_bus.pci_class &&
|
||||
device->subclass == pci_internal_secondary_bus.pci_subclass) {
|
||||
uint8_t secondary_bus = pci_config_read_byte(device->bus, device->slot, device->func,
|
||||
PCI_CONFIG_SECONDARY_BUS_NUMBER);
|
||||
device->pci_driver = &pci_internal_secondary_bus;
|
||||
pci_check_bus(secondary_bus);
|
||||
return;
|
||||
}
|
||||
|
||||
// use normal drivers
|
||||
for (size_t i = 0; i < NUM_DRIVERS; ++i) {
|
||||
if (DRIVER(i) == NULL) {
|
||||
struct pci_driver *driver = DRIVER(i);
|
||||
if (driver == NULL) {
|
||||
continue;
|
||||
}
|
||||
if (device->class != DRIVER(i)->pci_class) {
|
||||
if (driver->mask.class && driver->match.class != device->class) {
|
||||
continue;
|
||||
}
|
||||
if (DRIVER(i)->pci_use_subclass && device->subclass != DRIVER(i)->pci_subclass) {
|
||||
if (driver->mask.subclass && driver->match.subclass != device->subclass) {
|
||||
continue;
|
||||
}
|
||||
if (!DRIVER(i)->validatable) {
|
||||
if (driver->mask.interface && driver->match.interface != device->programInterface) {
|
||||
continue;
|
||||
}
|
||||
if (DRIVER(i)->validate(device) != PCI_VALIDATE_OK) {
|
||||
if (driver->mask.vendor && driver->match.vendor != device->vendorId) {
|
||||
continue;
|
||||
}
|
||||
if (driver->mask.device && driver->match.device != device->deviceId) {
|
||||
continue;
|
||||
}
|
||||
if (driver->direct_use) {
|
||||
if (driver->use(device) != PCI_USE_OK) {
|
||||
continue;
|
||||
}
|
||||
} else if (driver->validatable) {
|
||||
if (driver->validate(device) != PCI_VALIDATE_OK) {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
device->pci_driver = DRIVER(i);
|
||||
@@ -192,8 +192,19 @@ void pci_check_bus(uint8_t bus) {
|
||||
}
|
||||
}
|
||||
|
||||
int pci_driver_compare(const void* a, const void* b) {
|
||||
int rank_a = ((struct pci_driver *) a)->rank;
|
||||
int rank_b = ((struct pci_driver *) b)->rank;
|
||||
if (rank_a > rank_b) {
|
||||
return 1;
|
||||
} else if (rank_a < rank_b) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void pci_sort_drivers() {
|
||||
// todo
|
||||
qsort(DRIVER(0), NUM_DRIVERS, sizeof(struct pci_driver), pci_driver_compare);
|
||||
}
|
||||
|
||||
void pci_scan() {
|
||||
@@ -373,4 +384,17 @@ void pci_init_bar(pci_device *device, uint8_t bar_index) {
|
||||
bar->present = 1;
|
||||
}
|
||||
|
||||
// internal drivers
|
||||
PCI_DRIVER(
|
||||
.name = "pci-secondary-bus",
|
||||
.description = "A PCI bus connected to the primary bus",
|
||||
.rank = 0, // internal driver for PCI bus
|
||||
.match.class = PCI_CLASS_BRIDGE,
|
||||
.match.subclass = PCI_SUB_CLASS_PCI_PCI_BRIDGE_4,
|
||||
.mask.class = true,
|
||||
.mask.subclass = true,
|
||||
.direct_use = true,
|
||||
.use = pci_secondary_bus_use,
|
||||
);
|
||||
|
||||
// todo https://wiki.osdev.org/Universal_Serial_Bus if i dare
|
||||
@@ -10,10 +10,15 @@
|
||||
#include <stdbool.h>
|
||||
#include <attributes.h>
|
||||
|
||||
#define PCI_CLASS_MASS_STORAGE 0x01
|
||||
#define PCI_CLASS_MASS_STORAGE 0x01
|
||||
#define PCI_CLASS_BRIDGE 0x06
|
||||
|
||||
// class MASS STORAGE 1
|
||||
#define PCI_SUB_CLASS_IDE 0x01
|
||||
// class MASS STORAGE 0x01
|
||||
#define PCI_SUB_CLASS_IDE 0x01
|
||||
|
||||
// class BRIDGE 0x06
|
||||
#define PCI_SUB_CLASS_PCI_PCI_BRIDGE_4 0x04
|
||||
#define PCI_SUB_CLASS_PCI_PCI_BRIDGE_9 0x09
|
||||
|
||||
#define PCI_REGISTER_OK 0
|
||||
#define PCI_REGISTER_ERR_FULL (-1)
|
||||
@@ -24,6 +29,9 @@
|
||||
#define PCI_INIT_OK 0
|
||||
#define PCI_INIT_FAIL 1
|
||||
|
||||
#define PCI_USE_OK 0
|
||||
#define PCI_USE_FAIL 1
|
||||
|
||||
#define PCI_HEADER_TYPE_MULTI_FUNC 0x80
|
||||
#define PCI_HEADER_TYPE_ENDPOINT 0x00
|
||||
#define PCI_HEADER_TYPE_PCI_PCI_BRIDGE 0x01
|
||||
@@ -79,6 +87,8 @@
|
||||
|
||||
typedef struct pci_device pci_device;
|
||||
|
||||
typedef uint8_t (*pci_driver_use)(const pci_device *);
|
||||
|
||||
typedef uint8_t (*pci_driver_validate)(const pci_device *);
|
||||
|
||||
typedef uint8_t (*pci_driver_initialize)(pci_device *);
|
||||
@@ -86,14 +96,27 @@ typedef uint8_t (*pci_driver_initialize)(pci_device *);
|
||||
struct pci_driver {
|
||||
const char *name;
|
||||
const char *description;
|
||||
uint8_t order;
|
||||
uint8_t pci_class;
|
||||
uint8_t pci_subclass;
|
||||
uint16_t rank;
|
||||
struct {
|
||||
bool pci_use_subclass: 1;
|
||||
uint8_t class;
|
||||
uint8_t subclass;
|
||||
uint8_t interface;
|
||||
uint16_t vendor;
|
||||
uint16_t device;
|
||||
} match;
|
||||
struct {
|
||||
bool class: 1;
|
||||
bool subclass: 1;
|
||||
bool interface: 1;
|
||||
bool vendor: 1;
|
||||
bool device: 1;
|
||||
} mask;
|
||||
struct {
|
||||
bool direct_use: 1;
|
||||
bool validatable: 1;
|
||||
bool initialisable: 1;
|
||||
};
|
||||
pci_driver_use use;
|
||||
pci_driver_validate validate;
|
||||
pci_driver_initialize initialize;
|
||||
} __attribute__((__aligned__(STRUCT_ALIGNMENT)));
|
||||
|
||||
Reference in New Issue
Block a user