feat: reworked driver pci setup

This commit is contained in:
2021-02-04 21:02:14 +01:00
parent 706147c123
commit dc8a0444f9
4 changed files with 149 additions and 75 deletions

View File

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

View File

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

View File

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

View File

@@ -122,6 +122,17 @@ void init_mmap(multiboot_info_t *multiboot_info) {
}
}
void register_pci_drivers() {
ide_register();
}
void init_pci_system() {
register_pci_drivers();
pci_sort_drivers();
pci_scan();
pci_init_drivers();
}
void kmain(multiboot_info_t *multiboot_info) {
isr_install();
vga_clear_screen();
@@ -133,11 +144,7 @@ void kmain(multiboot_info_t *multiboot_info) {
store_bootloader_info(multiboot_info);
init_mmap(multiboot_info);
// register drivers
ide_register();
// scan PCI
pci_scan();
init_pci_system();
kprint(msg_booted);
kprint(newline);