diff --git a/kernel/drivers/ide.c b/kernel/drivers/ide.c index 95dcc94..1404ce6 100644 --- a/kernel/drivers/ide.c +++ b/kernel/drivers/ide.c @@ -6,14 +6,39 @@ #include #include #include +#include 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); } diff --git a/kernel/drivers/pci.c b/kernel/drivers/pci.c index 405d4fb..c53d416 100644 --- a/kernel/drivers/pci.c +++ b/kernel/drivers/pci.c @@ -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"); diff --git a/kernel/drivers/pci.h b/kernel/drivers/pci.h index 7e4fecb..5abe0c7 100644 --- a/kernel/drivers/pci.h +++ b/kernel/drivers/pci.h @@ -4,21 +4,87 @@ #ifndef NEW_KERNEL_PCI_H #define NEW_KERNEL_PCI_H + #include #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(); diff --git a/kernel/kernel.c b/kernel/kernel.c index 7a80aad..6a4faac 100644 --- a/kernel/kernel.c +++ b/kernel/kernel.c @@ -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);