feat: rank drivers at compile time
This commit is contained in:
@@ -5,16 +5,18 @@
|
|||||||
#ifndef NEW_KERNEL_DRIVER_H
|
#ifndef NEW_KERNEL_DRIVER_H
|
||||||
#define NEW_KERNEL_DRIVER_H
|
#define NEW_KERNEL_DRIVER_H
|
||||||
#include <attributes.h>
|
#include <attributes.h>
|
||||||
|
#include <preprocessor_format_zero.h>
|
||||||
|
|
||||||
#ifndef STRUCT_ALIGNMENT
|
#ifndef STRUCT_ALIGNMENT
|
||||||
#define STRUCT_ALIGNMENT 16
|
#define STRUCT_ALIGNMENT 16
|
||||||
#endif
|
#endif
|
||||||
#define DRIVER_CAT(a, b) DRIVER_DUMMY() a ## _ ## b
|
#define DRIVER_CAT(a, b) DRIVER_DUMMY() a ## _ ## b
|
||||||
#define DRIVER_DUMMY()
|
#define DRIVER_DUMMY()
|
||||||
|
#define SECT_NAME_(a,b) "." #a "." #b
|
||||||
|
#define SECT_NAME(a,b) SECT_NAME_(a, b)
|
||||||
|
|
||||||
#define GENERIC_DRIVER(drivername, data...) \
|
#define GENERIC_DRIVER(drivername, order) \
|
||||||
static struct drivername DRIVER_CAT(drivername, __COUNTER__) \
|
static struct drivername DRIVER_CAT(drivername, counter) \
|
||||||
__attribute((__used__, __section__(#drivername))) \
|
__attribute((__used__, __section__(SECT_NAME(drivername, FORMAT_3_ZERO(order)))))
|
||||||
= { data }
|
|
||||||
|
|
||||||
#endif //NEW_KERNEL_DRIVER_H
|
#endif //NEW_KERNEL_DRIVER_H
|
||||||
|
|||||||
@@ -671,10 +671,9 @@ uint8_t ide_access(uint8_t direction, uint8_t drive, uint32_t lba, uint8_t numse
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
PCI_DRIVER(
|
PCI_DRIVER(900) = {
|
||||||
.name = "pci-ide",
|
.name = "pci-ide",
|
||||||
.description = "Default PCI IDE Driver",
|
.description = "Default PCI IDE Driver",
|
||||||
.rank = 10000, // let other block_dev_drivers precede if they can
|
|
||||||
.validatable = true,
|
.validatable = true,
|
||||||
.initialisable = true,
|
.initialisable = true,
|
||||||
.match.class = PCI_CLASS_MASS_STORAGE,
|
.match.class = PCI_CLASS_MASS_STORAGE,
|
||||||
@@ -683,5 +682,5 @@ PCI_DRIVER(
|
|||||||
.mask.subclass = true,
|
.mask.subclass = true,
|
||||||
.validate = ide_pci_validate,
|
.validate = ide_pci_validate,
|
||||||
.initialize = ide_pci_initialize,
|
.initialize = ide_pci_initialize,
|
||||||
);
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,6 @@
|
|||||||
#ifdef ENABLE_PCIPP
|
#ifdef ENABLE_PCIPP
|
||||||
|
|
||||||
#include <drivers/pci_devices.h>
|
#include <drivers/pci_devices.h>
|
||||||
#include <libc/sort.h>
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -192,21 +191,6 @@ 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() {
|
|
||||||
qsort(DRIVER(0), NUM_DRIVERS, sizeof(struct pci_driver), pci_driver_compare);
|
|
||||||
}
|
|
||||||
|
|
||||||
void pci_scan() {
|
void pci_scan() {
|
||||||
if (last_pci_device_index != 0) {
|
if (last_pci_device_index != 0) {
|
||||||
k_panics("Can only scan once!");
|
k_panics("Can only scan once!");
|
||||||
@@ -385,16 +369,15 @@ void pci_init_bar(pci_device *device, uint8_t bar_index) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// internal drivers
|
// internal drivers
|
||||||
PCI_DRIVER(
|
PCI_DRIVER(0) = {
|
||||||
.name = "pci-secondary-bus",
|
.name = "pci-secondary-bus",
|
||||||
.description = "A PCI bus connected to the primary bus",
|
.description = "A PCI bus connected to the primary bus",
|
||||||
.rank = 0, // internal driver for PCI bus
|
|
||||||
.match.class = PCI_CLASS_BRIDGE,
|
.match.class = PCI_CLASS_BRIDGE,
|
||||||
.match.subclass = PCI_SUB_CLASS_PCI_PCI_BRIDGE_4,
|
.match.subclass = PCI_SUB_CLASS_PCI_PCI_BRIDGE_4,
|
||||||
.mask.class = true,
|
.mask.class = true,
|
||||||
.mask.subclass = true,
|
.mask.subclass = true,
|
||||||
.direct_use = true,
|
.direct_use = true,
|
||||||
.use = pci_secondary_bus_use,
|
.use = pci_secondary_bus_use,
|
||||||
);
|
};
|
||||||
|
|
||||||
// todo https://wiki.osdev.org/Universal_Serial_Bus if i dare
|
// todo https://wiki.osdev.org/Universal_Serial_Bus if i dare
|
||||||
@@ -96,7 +96,6 @@ typedef uint8_t (*pci_driver_initialize)(pci_device *);
|
|||||||
struct pci_driver {
|
struct pci_driver {
|
||||||
const char *name;
|
const char *name;
|
||||||
const char *description;
|
const char *description;
|
||||||
uint16_t rank;
|
|
||||||
struct {
|
struct {
|
||||||
uint8_t class;
|
uint8_t class;
|
||||||
uint8_t subclass;
|
uint8_t subclass;
|
||||||
@@ -121,7 +120,7 @@ struct pci_driver {
|
|||||||
pci_driver_initialize initialize;
|
pci_driver_initialize initialize;
|
||||||
} __attribute__((__aligned__(STRUCT_ALIGNMENT)));
|
} __attribute__((__aligned__(STRUCT_ALIGNMENT)));
|
||||||
|
|
||||||
#define PCI_DRIVER(data...) GENERIC_DRIVER(pci_driver, data)
|
#define PCI_DRIVER(order) GENERIC_DRIVER(pci_driver, order)
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t address;
|
uint32_t address;
|
||||||
@@ -223,8 +222,6 @@ void pci_pretty_print();
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void pci_sort_drivers();
|
|
||||||
|
|
||||||
void pci_init_drivers();
|
void pci_init_drivers();
|
||||||
|
|
||||||
void pci_scan();
|
void pci_scan();
|
||||||
|
|||||||
@@ -9,7 +9,6 @@
|
|||||||
#include <tasks/task.h>
|
#include <tasks/task.h>
|
||||||
#include <tasks/locking.h>
|
#include <tasks/locking.h>
|
||||||
#include <attributes.h>
|
#include <attributes.h>
|
||||||
#include <libc/sort.h>
|
|
||||||
#include "blockdev.h"
|
#include "blockdev.h"
|
||||||
|
|
||||||
#define MAX_BLOCK_DEVS 64
|
#define MAX_BLOCK_DEVS 64
|
||||||
@@ -80,21 +79,6 @@ void block_dev_scan() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int block_dev_driver_comp(const void *a, const void *b) {
|
|
||||||
int rank_a = ((struct block_dev_driver *) a)->rank;
|
|
||||||
int rank_b = ((struct block_dev_driver *) b)->rank;
|
|
||||||
if (rank_a > rank_b) {
|
|
||||||
return 1;
|
|
||||||
} else if (rank_a < rank_b) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void block_dev_pre_init() {
|
|
||||||
qsort(DRIVER(0), NUM_DRIVERS, sizeof(struct block_dev_driver), block_dev_driver_comp);
|
|
||||||
}
|
|
||||||
|
|
||||||
void noreturn block_dev_task(void *data) {
|
void noreturn block_dev_task(void *data) {
|
||||||
while (true) {
|
while (true) {
|
||||||
semaphore_wait(block_semaphore);
|
semaphore_wait(block_semaphore);
|
||||||
|
|||||||
@@ -34,7 +34,6 @@ typedef uint8_t (*block_device_access)(const block_device *device, uint8_t direc
|
|||||||
|
|
||||||
struct block_dev_driver {
|
struct block_dev_driver {
|
||||||
char name[16];
|
char name[16];
|
||||||
uint16_t rank;
|
|
||||||
struct {
|
struct {
|
||||||
uint8_t root_only: 1;
|
uint8_t root_only: 1;
|
||||||
} flags;
|
} flags;
|
||||||
@@ -42,7 +41,7 @@ struct block_dev_driver {
|
|||||||
block_device_driver_free free_device;
|
block_device_driver_free free_device;
|
||||||
} __attribute__((__aligned__(STRUCT_ALIGNMENT)));
|
} __attribute__((__aligned__(STRUCT_ALIGNMENT)));
|
||||||
|
|
||||||
#define BLOCK_DEV_DRIVER(data...) GENERIC_DRIVER(block_dev_driver, data)
|
#define BLOCK_DEV_DRIVER(order) GENERIC_DRIVER(block_dev_driver, order)
|
||||||
|
|
||||||
typedef struct block_device {
|
typedef struct block_device {
|
||||||
struct {
|
struct {
|
||||||
@@ -65,8 +64,6 @@ uint8_t block_dev_register(block_device *device);
|
|||||||
|
|
||||||
void block_dev_free(block_device *device);
|
void block_dev_free(block_device *device);
|
||||||
|
|
||||||
void block_dev_pre_init();
|
|
||||||
|
|
||||||
void block_dev_start_task();
|
void block_dev_start_task();
|
||||||
|
|
||||||
void block_dev_print_info();
|
void block_dev_print_info();
|
||||||
|
|||||||
@@ -193,11 +193,10 @@ get_fat_table_value(uint8_t fat_type, const uint8_t *fat_table, uint32_t active_
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
BLOCK_DEV_DRIVER(
|
BLOCK_DEV_DRIVER(900) = {
|
||||||
.name = "fat",
|
.name = "fat",
|
||||||
.rank = 10000,
|
|
||||||
.check_device = fat_check_device,
|
.check_device = fat_check_device,
|
||||||
.free_device = NULL, // todo
|
.free_device = NULL, // todo
|
||||||
);
|
};
|
||||||
|
|
||||||
// steal validation code from here https://github.com/torvalds/linux/blob/fcadab740480e0e0e9fa9bd272acd409884d431a/fs/fat/inode.c#L1456
|
// steal validation code from here https://github.com/torvalds/linux/blob/fcadab740480e0e0e9fa9bd272acd409884d431a/fs/fat/inode.c#L1456
|
||||||
@@ -100,10 +100,9 @@ void mbr_read_from_ide(uint8_t ide_drive) {
|
|||||||
free(mbr_data);
|
free(mbr_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
BLOCK_DEV_DRIVER(
|
BLOCK_DEV_DRIVER(200) = {
|
||||||
.name = "mbr",
|
.name = "mbr",
|
||||||
.rank = 100,
|
|
||||||
.flags.root_only = 1,
|
.flags.root_only = 1,
|
||||||
.check_device = mbr_check_device,
|
.check_device = mbr_check_device,
|
||||||
.free_device = NULL, // todo
|
.free_device = NULL, // todo
|
||||||
);
|
};
|
||||||
|
|||||||
@@ -30,7 +30,6 @@ void init_mmap(multiboot_info_t *multiboot_info) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void init_pci_system() {
|
void init_pci_system() {
|
||||||
pci_sort_drivers();
|
|
||||||
pci_scan();
|
pci_scan();
|
||||||
pci_init_drivers();
|
pci_init_drivers();
|
||||||
}
|
}
|
||||||
@@ -60,9 +59,6 @@ void noreturn used kmain(multiboot_info_t *multiboot_info, uint32_t mb_name) {
|
|||||||
// identify cpu
|
// identify cpu
|
||||||
cpuidx_print_info();
|
cpuidx_print_info();
|
||||||
|
|
||||||
// pre init drivers
|
|
||||||
block_dev_pre_init();
|
|
||||||
|
|
||||||
// enable interrupts
|
// enable interrupts
|
||||||
__asm__ __volatile__("sti");
|
__asm__ __volatile__("sti");
|
||||||
// start the timer
|
// start the timer
|
||||||
|
|||||||
1236
kernel/preprocessor_format_zero.h
Normal file
1236
kernel/preprocessor_format_zero.h
Normal file
File diff suppressed because it is too large
Load Diff
@@ -32,11 +32,11 @@ SECTIONS
|
|||||||
*(.data)
|
*(.data)
|
||||||
. = ALIGN(16);
|
. = ALIGN(16);
|
||||||
__start_pci_driver = .;
|
__start_pci_driver = .;
|
||||||
*(pci_driver)
|
*(SORT(.pci_driver.*))
|
||||||
__stop_pci_driver = .;
|
__stop_pci_driver = .;
|
||||||
. = ALIGN(16);
|
. = ALIGN(16);
|
||||||
__start_block_dev_driver = .;
|
__start_block_dev_driver = .;
|
||||||
*(block_dev_driver)
|
*(SORT(.block_dev_driver.*))
|
||||||
__stop_block_dev_driver = .;
|
__stop_block_dev_driver = .;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user