From 645e18018d43417cab2dd8fc2aad7e128cf6880e Mon Sep 17 00:00:00 2001 From: Rick Rongen Date: Sat, 6 Mar 2021 15:29:31 +0100 Subject: [PATCH] feat: used linker to link pci drivers --- kernel/drivers/ide.c | 8 ++------ kernel/drivers/ide.h | 2 -- kernel/drivers/pci.c | 37 +++++++++++++++---------------------- kernel/drivers/pci.h | 26 ++++++++++++++++++++------ kernel/kernel.c | 5 ----- linker.ld | 3 +++ 6 files changed, 40 insertions(+), 41 deletions(-) diff --git a/kernel/drivers/ide.c b/kernel/drivers/ide.c index fe10ec3..1bd22d8 100644 --- a/kernel/drivers/ide.c +++ b/kernel/drivers/ide.c @@ -326,7 +326,7 @@ uint8_t ide_pci_validate(const pci_device *device); uint8_t ide_pci_initialize(pci_device *device); -const pci_driver ide_pci_driver = { +PCI_DRIVER( .name = "pci-ide", .description = "Default PCI IDE Driver", .order = 0xFF, // let other block_dev_drivers precede if they can @@ -338,7 +338,7 @@ const pci_driver ide_pci_driver = { .validate = ide_pci_validate, .initialize = ide_pci_initialize, -}; +); uint8_t ide_pci_validate(const pci_device *device) { if (device->class != PCI_CLASS_MASS_STORAGE @@ -549,10 +549,6 @@ void ide_print_devices() { } } -void ide_register() { - pci_register_driver(&ide_pci_driver); -} - uint8_t ide_read_ata_access(uint8_t direction, uint8_t drive, uint32_t lba, uint8_t numsects, void *target) { uint8_t lba_mode /* 0: CHS, 1:LBA28, 2: LBA48 */, dma /* 0: No DMA, 1: DMA */, cmd; uint8_t lba_io[6]; diff --git a/kernel/drivers/ide.h b/kernel/drivers/ide.h index 26e7c01..5b7e5cd 100644 --- a/kernel/drivers/ide.h +++ b/kernel/drivers/ide.h @@ -7,8 +7,6 @@ #include -void ide_register(); - uint8_t ide_access(uint8_t direction, uint8_t drive, uint32_t lba, uint8_t numsects, void *target); void ide_print_devices(); diff --git a/kernel/drivers/pci.c b/kernel/drivers/pci.c index 813e35c..6120474 100644 --- a/kernel/drivers/pci.c +++ b/kernel/drivers/pci.c @@ -34,7 +34,7 @@ #define MASK_BAR_IOSPACE 0xFFFFFFFC #define MASK_BAR_MEMSPACE 0xFFFFFFF0 -const pci_driver pci_internal_secondary_bus = { +const struct pci_driver pci_internal_secondary_bus = { .name = "pci-secondary-bus", .description = "A PCI bus connected to the primary bus", .order = 0, @@ -45,23 +45,16 @@ const pci_driver pci_internal_secondary_bus = { .initialize = NULL, }; -const pci_driver *pci_drivers[MAX_PCI_DRIVERS]; +//const pci_driver *pci_drivers[MAX_PCI_DRIVERS]; +extern struct pci_driver __start_pci_drivers[]; +extern struct pci_driver __stop_pci_drivers[]; +#define NUM_DRIVERS ((size_t)(__stop_pci_drivers - __start_pci_drivers)) +#define DRIVER(i) ((__start_pci_drivers) + (i)) int last_pci_device_index = 0; pci_device pci_devices[MAX_PCI_DEVICES]; void pci_check_bus(uint8_t bus); -uint32_t pci_register_driver(const pci_driver *pci_driver) { - for (int i = 0; i < MAX_PCI_DRIVERS; ++i) { - if (pci_drivers[i] != NULL) { - continue; - } - pci_drivers[i] = pci_driver; - return PCI_REGISTER_OK; - } - return PCI_REGISTER_ERR_FULL; -} - 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) @@ -141,23 +134,23 @@ void pci_pick_driver(pci_device *device) { } // use normal drivers - for (int i = 0; i < MAX_PCI_DRIVERS; ++i) { - if (pci_drivers[i] == NULL) { + for (int i = 0; i < NUM_DRIVERS; ++i) { +// if (DRIVER(i) == NULL) { +// continue; +// } + if (device->class != DRIVER(i)->pci_class) { continue; } - if (device->class != pci_drivers[i]->pci_class) { + if (DRIVER(i)->pci_use_subclass && device->subclass != DRIVER(i)->pci_subclass) { continue; } - if (pci_drivers[i]->pci_use_subclass && device->subclass != pci_drivers[i]->pci_subclass) { + if (!DRIVER(i)->validatable) { continue; } - if (!pci_drivers[i]->validatable) { + if (DRIVER(i)->validate(device) != PCI_VALIDATE_OK) { continue; } - if (pci_drivers[i]->validate(device) != PCI_VALIDATE_OK) { - continue; - } - device->pci_driver = pci_drivers[i]; + device->pci_driver = DRIVER(i); } } diff --git a/kernel/drivers/pci.h b/kernel/drivers/pci.h index 21c1219..a428e00 100644 --- a/kernel/drivers/pci.h +++ b/kernel/drivers/pci.h @@ -76,14 +76,21 @@ #define PCI_INTERRUPT_LINE_DISABLED 0xff -typedef struct pci_driver pci_driver; +#ifndef PCI_DRIVER_ALIGNMENT +#if defined(__LP64__) +#define PCI_DRIVER_ALIGNMENT 16 +#else +#define PCI_DRIVER_ALIGNMENT 8 +#endif +#endif + typedef struct pci_device pci_device; typedef uint8_t (*pci_driver_validate)(const pci_device *); typedef uint8_t (*pci_driver_initialize)(pci_device *); -typedef struct pci_driver { +struct pci_driver { const char *name; const char *description; uint8_t order; @@ -96,7 +103,16 @@ typedef struct pci_driver { }; pci_driver_validate validate; pci_driver_initialize initialize; -} pci_driver; +} __attribute__((__aligned__(PCI_DRIVER_ALIGNMENT))); + +#define PCI_DRIVER_NAME(counter) DRIVER_CAT(pci_driver_, counter) +#define DRIVER_CAT(a, b) DRIVER_DUMMY() a ## b +#define DRIVER_DUMMY() + +#define PCI_DRIVER(data...) \ + static struct pci_driver PCI_DRIVER_NAME(__COUNTER__) \ + __attribute((__used__, __section__("pci_drivers"))) \ + = { data } typedef struct { uint32_t address; @@ -142,7 +158,7 @@ typedef struct pci_device { bar_info bar3; bar_info bar4; bar_info bar5; - const pci_driver *pci_driver; + const struct pci_driver *pci_driver; struct { uint8_t present: 1; } device_state; @@ -198,8 +214,6 @@ void pci_pretty_print(); #endif -uint32_t pci_register_driver(const pci_driver *pci_driver); - void pci_sort_drivers(); void pci_init_drivers(); diff --git a/kernel/kernel.c b/kernel/kernel.c index 6b61e9b..a517381 100644 --- a/kernel/kernel.c +++ b/kernel/kernel.c @@ -32,12 +32,7 @@ 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(); diff --git a/linker.ld b/linker.ld index 654b1be..37d9276 100644 --- a/linker.ld +++ b/linker.ld @@ -29,6 +29,9 @@ SECTIONS /* Read-write data (initialized) */ .data BLOCK(4K) : ALIGN(4K) { + __start_pci_drivers = .; + *(pci_drivers) + __stop_pci_drivers = .; *(.data) }