feat: reworked driver pci setup
This commit is contained in:
@@ -6,14 +6,39 @@
|
||||
#include <types.h>
|
||||
#include <kprint.h>
|
||||
#include <drivers/pci.h>
|
||||
#include <libc/stdbool.h>
|
||||
|
||||
const char* ide_pci_driver_name = "pci-ide";
|
||||
|
||||
void ide_handle_pci_device(u8 bus, u8 slot, u8 func) {
|
||||
u8 ide_pci_validate(const pci_device *device);
|
||||
u8 ide_pci_initialize(const pci_device *device);
|
||||
|
||||
const pci_driver ide_pci_driver = {
|
||||
.name = "pci-ide",
|
||||
.description = "Default PCI IDE Driver",
|
||||
.order = 0xFF, // let other drivers precede if they can
|
||||
.pci_use_subclass = true,
|
||||
.pci_class = PCI_CLASS_MASS_STORAGE,
|
||||
.pci_subclass = PCI_SUB_CLASS_IDE,
|
||||
|
||||
.validate = ide_pci_validate,
|
||||
.initialize = ide_pci_initialize,
|
||||
};
|
||||
|
||||
u8 ide_pci_validate(const pci_device *device) {
|
||||
if (device->class != PCI_CLASS_MASS_STORAGE
|
||||
|| device->subclass != PCI_SUB_CLASS_IDE) {
|
||||
return PCI_VALIDATE_FAIL;
|
||||
}
|
||||
// todo other validations
|
||||
return PCI_VALIDATE_OK;
|
||||
}
|
||||
|
||||
u8 ide_pci_initialize(const pci_device *device) {
|
||||
kprint("IDE registered");
|
||||
// todo
|
||||
return PCI_VALIDATE_OK;
|
||||
}
|
||||
|
||||
void ide_register() {
|
||||
pci_register_driver(PCI_CLASS_MASS_STORAGE, PCI_SUB_CLASS_IDE, PCI_FLAG_USE_SUBCLASS, ide_handle_pci_device, ide_pci_driver_name);
|
||||
pci_register_driver(&ide_pci_driver);
|
||||
}
|
||||
|
||||
@@ -53,65 +53,17 @@
|
||||
#define MAX_PCI_DRIVERS 64
|
||||
#define MAX_PCI_DEVICES 64
|
||||
|
||||
typedef struct {
|
||||
pci_driver driver;
|
||||
const char *driver_name;
|
||||
u8 pci_class;
|
||||
u8 pci_subclass;
|
||||
union {
|
||||
u8 flags;
|
||||
struct {
|
||||
u8 pci_use_subclass: 1;
|
||||
};
|
||||
};
|
||||
} pci_driver_info;
|
||||
|
||||
typedef struct {
|
||||
u8 bus;
|
||||
u8 slot;
|
||||
u8 func;
|
||||
union {
|
||||
struct {
|
||||
u16 vendorId;
|
||||
u16 deviceId;
|
||||
};
|
||||
u32 config_line_0;
|
||||
};
|
||||
union {
|
||||
struct {
|
||||
u8 revisionId;
|
||||
u8 programInterface;
|
||||
u8 subclass;
|
||||
u8 class;
|
||||
};
|
||||
u32 config_line_2;
|
||||
};
|
||||
union {
|
||||
struct {
|
||||
u8 cacheLineSize;
|
||||
u8 latencyTimer;
|
||||
u8 headerType;
|
||||
u8 bist;
|
||||
};
|
||||
u32 config_line_3;
|
||||
};
|
||||
pci_driver_info *driver_info;
|
||||
} pci_device;
|
||||
|
||||
pci_driver_info pci_drivers[MAX_PCI_DRIVERS];
|
||||
const pci_driver *pci_drivers[MAX_PCI_DRIVERS];
|
||||
int last_pci_device_index = 0;
|
||||
pci_device pci_devices[MAX_PCI_DEVICES];
|
||||
|
||||
u32 pci_register_driver(u8 pci_class, u8 pci_subclass, u8 flags, pci_driver driver, const char *driver_name) {
|
||||
u32 pci_register_driver(const pci_driver *pci_driver) {
|
||||
for (int i = 0; i < MAX_PCI_DRIVERS; ++i) {
|
||||
if (pci_drivers[i].driver == NULL) {
|
||||
pci_drivers[i].driver = driver;
|
||||
pci_drivers[i].pci_class = pci_class;
|
||||
pci_drivers[i].pci_subclass = pci_subclass;
|
||||
pci_drivers[i].flags = flags;
|
||||
pci_drivers[i].driver_name = driver_name;
|
||||
return PCI_REGISTER_OK;
|
||||
if (pci_drivers[i] != NULL) {
|
||||
continue;
|
||||
}
|
||||
pci_drivers[i] = pci_driver;
|
||||
return PCI_REGISTER_OK;
|
||||
}
|
||||
return PCI_REGISTER_ERR_FULL;
|
||||
}
|
||||
@@ -185,15 +137,19 @@ void print_u16(u16 val) {
|
||||
|
||||
void pci_pick_driver(pci_device *device) {
|
||||
for (int i = 0; i < MAX_PCI_DRIVERS; ++i) {
|
||||
if (pci_drivers[i].driver == NULL) {
|
||||
if (pci_drivers[i] == NULL) {
|
||||
continue;
|
||||
}
|
||||
if (device->class == pci_drivers[i].pci_class) {
|
||||
if (!pci_drivers[i].pci_use_subclass || device->subclass == pci_drivers[i].pci_subclass) {
|
||||
pci_drivers[i].driver(device->bus, device->slot, device->func);
|
||||
device->driver_info = &pci_drivers[i];
|
||||
}
|
||||
if (device->class != pci_drivers[i]->pci_class) {
|
||||
continue;
|
||||
}
|
||||
if (pci_drivers[i]->pci_use_subclass && device->subclass != pci_drivers[i]->pci_subclass) {
|
||||
continue;
|
||||
}
|
||||
if (pci_drivers[i]->validate(device) != PCI_VALIDATE_OK) {
|
||||
continue;
|
||||
}
|
||||
device->pci_driver = pci_drivers[i];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -204,6 +160,7 @@ void pci_check_function(u8 bus, u8 slot, u8 func) {
|
||||
pci_devices[last_pci_device_index].config_line_0 = pci_config_read_double_word(bus, slot, func, PCI_CONFIG_LINE_0);
|
||||
pci_devices[last_pci_device_index].config_line_2 = pci_config_read_double_word(bus, slot, func, PCI_CONFIG_LINE_2);
|
||||
pci_devices[last_pci_device_index].config_line_3 = pci_config_read_double_word(bus, slot, func, PCI_CONFIG_LINE_3);
|
||||
pci_devices[last_pci_device_index].device_state.present = 1;
|
||||
pci_pick_driver(&pci_devices[last_pci_device_index]);
|
||||
last_pci_device_index++;
|
||||
|
||||
@@ -230,6 +187,9 @@ void pci_check_bus(u8 bus) {
|
||||
pci_check_device(bus, device);
|
||||
}
|
||||
}
|
||||
void pci_sort_drivers() {
|
||||
// todo
|
||||
}
|
||||
|
||||
void pci_scan() {
|
||||
if (last_pci_device_index != 0) {
|
||||
@@ -246,6 +206,22 @@ void pci_scan() {
|
||||
}
|
||||
}
|
||||
|
||||
void pci_init_drivers() {
|
||||
for (int device_index = 0; device_index < MAX_PCI_DEVICES; ++device_index) {
|
||||
if (!pci_devices[device_index].device_state.present) {
|
||||
continue;
|
||||
}
|
||||
if (pci_devices[device_index].driver_state.initialized) {
|
||||
continue; // already done
|
||||
}
|
||||
if (pci_devices[device_index].pci_driver == NULL) {
|
||||
continue; // no driver found
|
||||
}
|
||||
pci_devices[device_index].pci_driver->initialize(&pci_devices[device_index]);
|
||||
pci_devices[device_index].driver_state.initialized = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void pci_print_info() {
|
||||
for (int i = 0; i < last_pci_device_index; ++i) {
|
||||
kprint("PCI BSF: ");
|
||||
@@ -267,10 +243,10 @@ void pci_print_info() {
|
||||
print_u16(pci_devices[i].deviceId);
|
||||
kprint(" driver_info: ");
|
||||
|
||||
if (pci_devices[i].driver_info == NULL) {
|
||||
if (pci_devices[i].pci_driver == NULL) {
|
||||
kprint("NULL");
|
||||
} else {
|
||||
kprint(pci_devices[i].driver_info->driver_name);
|
||||
kprint(pci_devices[i].pci_driver->name);
|
||||
}
|
||||
|
||||
kprint("\n");
|
||||
|
||||
@@ -4,21 +4,87 @@
|
||||
|
||||
#ifndef NEW_KERNEL_PCI_H
|
||||
#define NEW_KERNEL_PCI_H
|
||||
|
||||
#include <types.h>
|
||||
|
||||
#define PCI_CLASS_MASS_STORAGE 0x01
|
||||
|
||||
// class MASS STORAGE 1
|
||||
#define PCI_SUB_CLASS_IDE 0x01
|
||||
|
||||
#define PCI_FLAG_USE_SUBCLASS (1 << 0)
|
||||
#define PCI_REGISTER_OK 0;
|
||||
#define PCI_REGISTER_ERR_FULL -1;
|
||||
#define PCI_REGISTER_OK 0
|
||||
#define PCI_REGISTER_ERR_FULL (-1)
|
||||
|
||||
typedef void (*pci_driver)(u8 bus, u8 slot, u8 func);
|
||||
#define PCI_VALIDATE_OK 0
|
||||
#define PCI_VALIDATE_FAIL 1
|
||||
|
||||
#define PCI_INIT_OK 0
|
||||
#define PCI_INIT_FAIL 1
|
||||
|
||||
typedef struct pci_driver pci_driver;
|
||||
typedef struct pci_device pci_device;
|
||||
|
||||
typedef u8 (*pci_driver_validate)(const pci_device *);
|
||||
typedef u8 (*pci_driver_initialize)(const pci_device *);
|
||||
|
||||
typedef struct pci_driver {
|
||||
const char *name;
|
||||
const char *description;
|
||||
u8 order;
|
||||
u8 pci_class;
|
||||
u8 pci_subclass;
|
||||
struct {
|
||||
u8 pci_use_subclass: 1;
|
||||
};
|
||||
pci_driver_validate validate;
|
||||
pci_driver_initialize initialize;
|
||||
} pci_driver;
|
||||
|
||||
typedef struct pci_device {
|
||||
u8 bus;
|
||||
u8 slot;
|
||||
u8 func;
|
||||
union {
|
||||
struct {
|
||||
u16 vendorId;
|
||||
u16 deviceId;
|
||||
};
|
||||
u32 config_line_0;
|
||||
};
|
||||
union {
|
||||
struct {
|
||||
u8 revisionId;
|
||||
u8 programInterface;
|
||||
u8 subclass;
|
||||
u8 class;
|
||||
};
|
||||
u32 config_line_2;
|
||||
};
|
||||
union {
|
||||
struct {
|
||||
u8 cacheLineSize;
|
||||
u8 latencyTimer;
|
||||
u8 headerType;
|
||||
u8 bist;
|
||||
};
|
||||
u32 config_line_3;
|
||||
};
|
||||
const pci_driver *pci_driver;
|
||||
struct {
|
||||
u8 present: 1;
|
||||
} device_state;
|
||||
struct {
|
||||
u8 initialized: 1;
|
||||
} driver_state;
|
||||
} pci_device;
|
||||
|
||||
void pci_print_info();
|
||||
|
||||
u32 pci_register_driver(u8 pci_class, u8 pci_subclass, u8 flags, pci_driver driver, const char *driver_name);
|
||||
u32 pci_register_driver(const pci_driver *pci_driver);
|
||||
|
||||
void pci_sort_drivers();
|
||||
|
||||
void pci_init_drivers();
|
||||
|
||||
void pci_scan();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user