feat: reformatted driver code and linkage. Some optimizations

This commit is contained in:
2021-03-06 19:57:47 +01:00
parent 645e18018d
commit 01efc5e98a
13 changed files with 110 additions and 130 deletions

View File

@@ -5,6 +5,9 @@
#ifndef NEW_KERNEL_ATTRIBUTES_H #ifndef NEW_KERNEL_ATTRIBUTES_H
#define NEW_KERNEL_ATTRIBUTES_H #define NEW_KERNEL_ATTRIBUTES_H
// generic
#define used __attribute((used))
// function // function
#define noreturn __attribute((noreturn)) #define noreturn __attribute((noreturn))
#define cdecl __attribute((cdecl)) #define cdecl __attribute((cdecl))

20
kernel/driver.h Normal file
View File

@@ -0,0 +1,20 @@
//
// Created by rick on 06-03-21.
//
#ifndef NEW_KERNEL_DRIVER_H
#define NEW_KERNEL_DRIVER_H
#include <attributes.h>
#ifndef STRUCT_ALIGNMENT
#define STRUCT_ALIGNMENT 16
#endif
#define DRIVER_CAT(a, b) DRIVER_DUMMY() a ## _ ## b
#define DRIVER_DUMMY()
#define GENERIC_DRIVER(drivername, data...) \
static struct drivername DRIVER_CAT(drivername, __COUNTER__) \
__attribute((__used__, __section__(#drivername))) \
= { data }
#endif //NEW_KERNEL_DRIVER_H

View File

@@ -322,34 +322,6 @@ unsigned char ide_print_error(unsigned int drive, unsigned char err) {
return err; return err;
} }
uint8_t ide_pci_validate(const pci_device *device);
uint8_t ide_pci_initialize(pci_device *device);
PCI_DRIVER(
.name = "pci-ide",
.description = "Default PCI IDE Driver",
.order = 0xFF, // let other block_dev_drivers precede if they can
.pci_use_subclass = true,
.validatable = true,
.initialisable = true,
.pci_class = PCI_CLASS_MASS_STORAGE,
.pci_subclass = PCI_SUB_CLASS_IDE,
.validate = ide_pci_validate,
.initialize = ide_pci_initialize,
);
uint8_t ide_pci_validate(const pci_device *device) {
if (device->class != PCI_CLASS_MASS_STORAGE
|| device->subclass != PCI_SUB_CLASS_IDE
|| (device->programInterface != 0x8A && device->programInterface != 0x80)) {
return PCI_VALIDATE_FAIL;
}
// todo other validations
return PCI_VALIDATE_OK;
}
void ide_fix_bar(bar_info *bar, uint32_t default_address, uint32_t size) { void ide_fix_bar(bar_info *bar, uint32_t default_address, uint32_t size) {
if (bar->address == 0x0) { if (bar->address == 0x0) {
// no need to actually write ti back // no need to actually write ti back
@@ -365,6 +337,7 @@ bool ide_pci_init_channels(pci_device *device) {
pci_config_write_byte(device->bus, device->slot, device->func, PCI_CONFIG_INTERRUPT_LINE, 0xFE); pci_config_write_byte(device->bus, device->slot, device->func, PCI_CONFIG_INTERRUPT_LINE, 0xFE);
if (pci_config_read_byte(device->bus, device->slot, device->func, PCI_CONFIG_INTERRUPT_LINE) == 0xFE) { if (pci_config_read_byte(device->bus, device->slot, device->func, PCI_CONFIG_INTERRUPT_LINE) == 0xFE) {
#ifdef IDE_ENABLE_INTERRUPT #ifdef IDE_ENABLE_INTERRUPT
#error "Interrupt not supported"
k_panics("NOT SUPPORTED"); k_panics("NOT SUPPORTED");
#else #else
pci_config_write_byte(device->bus, device->slot, device->func, PCI_CONFIG_INTERRUPT_LINE, pci_config_write_byte(device->bus, device->slot, device->func, PCI_CONFIG_INTERRUPT_LINE,
@@ -399,7 +372,8 @@ bool ide_pci_init_channels(pci_device *device) {
return true; return true;
} }
uint8_t ide_block_dev_access(const block_device *device, uint8_t direction, uint32_t lba, uint8_t sectors, void *target) { uint8_t
ide_block_dev_access(const block_device *device, uint8_t direction, uint32_t lba, uint8_t sectors, void *target) {
ide_block_device_info *info = device->device_info; ide_block_device_info *info = device->device_info;
uint8_t result = ide_access(direction, info->device_number, lba, sectors, target); uint8_t result = ide_access(direction, info->device_number, lba, sectors, target);
if (result != 0) { if (result != 0) {
@@ -436,7 +410,17 @@ void ide_register_block_devices() {
} }
} }
uint8_t ide_pci_initialize(pci_device *device) { uint8_t used ide_pci_validate(const pci_device *device) {
if (device->class != PCI_CLASS_MASS_STORAGE
|| device->subclass != PCI_SUB_CLASS_IDE
|| (device->programInterface != 0x8A && device->programInterface != 0x80)) {
return PCI_VALIDATE_FAIL;
}
// todo other validations
return PCI_VALIDATE_OK;
}
uint8_t used ide_pci_initialize(pci_device *device) {
if (!ide_pci_init_channels(device)) { if (!ide_pci_init_channels(device)) {
return PCI_INIT_FAIL; return PCI_INIT_FAIL;
@@ -686,3 +670,18 @@ uint8_t ide_access(uint8_t direction, uint8_t drive, uint32_t lba, uint8_t numse
mutex_release(ide_lock); mutex_release(ide_lock);
return result; return result;
} }
PCI_DRIVER(
.name = "pci-ide",
.description = "Default PCI IDE Driver",
.order = 0xFF, // let other block_dev_drivers precede if they can
.pci_use_subclass = true,
.validatable = true,
.initialisable = true,
.pci_class = PCI_CLASS_MASS_STORAGE,
.pci_subclass = PCI_SUB_CLASS_IDE,
.validate = ide_pci_validate,
.initialize = ide_pci_initialize,
);

View File

@@ -46,10 +46,10 @@ const struct pci_driver pci_internal_secondary_bus = {
}; };
//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 __start_pci_driver[];
extern struct pci_driver __stop_pci_drivers[]; extern struct pci_driver __stop_pci_driver[];
#define NUM_DRIVERS ((size_t)(__stop_pci_drivers - __start_pci_drivers)) #define NUM_DRIVERS ((size_t)(__stop_pci_driver - __start_pci_driver))
#define DRIVER(i) ((__start_pci_drivers) + (i)) #define DRIVER(i) ((__start_pci_driver) + (i))
int last_pci_device_index = 0; int last_pci_device_index = 0;
pci_device pci_devices[MAX_PCI_DEVICES]; pci_device pci_devices[MAX_PCI_DEVICES];
@@ -126,18 +126,20 @@ uint8_t pci_get_header_type(uint8_t bus, uint8_t slot, uint8_t func) {
void pci_pick_driver(pci_device *device) { void pci_pick_driver(pci_device *device) {
// check special drivers // check special drivers
// PCI Secondary bus // PCI Secondary bus
if (device->class == pci_internal_secondary_bus.pci_class && device->subclass == pci_internal_secondary_bus.pci_subclass) { if (device->class == pci_internal_secondary_bus.pci_class &&
uint8_t secondary_bus = pci_config_read_byte(device->bus, device->slot, device->func, PCI_CONFIG_SECONDARY_BUS_NUMBER); device->subclass == pci_internal_secondary_bus.pci_subclass) {
uint8_t secondary_bus = pci_config_read_byte(device->bus, device->slot, device->func,
PCI_CONFIG_SECONDARY_BUS_NUMBER);
device->pci_driver = &pci_internal_secondary_bus; device->pci_driver = &pci_internal_secondary_bus;
pci_check_bus(secondary_bus); pci_check_bus(secondary_bus);
return; return;
} }
// use normal drivers // use normal drivers
for (int i = 0; i < NUM_DRIVERS; ++i) { for (size_t i = 0; i < NUM_DRIVERS; ++i) {
// if (DRIVER(i) == NULL) { if (DRIVER(i) == NULL) {
// continue; continue;
// } }
if (device->class != DRIVER(i)->pci_class) { if (device->class != DRIVER(i)->pci_class) {
continue; continue;
} }

View File

@@ -6,6 +6,7 @@
#define NEW_KERNEL_PCI_H #define NEW_KERNEL_PCI_H
#include <types.h> #include <types.h>
#include <driver.h>
#include <stdbool.h> #include <stdbool.h>
#include <attributes.h> #include <attributes.h>
@@ -76,14 +77,6 @@
#define PCI_INTERRUPT_LINE_DISABLED 0xff #define PCI_INTERRUPT_LINE_DISABLED 0xff
#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 struct pci_device pci_device;
typedef uint8_t (*pci_driver_validate)(const pci_device *); typedef uint8_t (*pci_driver_validate)(const pci_device *);
@@ -103,16 +96,9 @@ struct pci_driver {
}; };
pci_driver_validate validate; pci_driver_validate validate;
pci_driver_initialize initialize; pci_driver_initialize initialize;
} __attribute__((__aligned__(PCI_DRIVER_ALIGNMENT))); } __attribute__((__aligned__(STRUCT_ALIGNMENT)));
#define PCI_DRIVER_NAME(counter) DRIVER_CAT(pci_driver_, counter) #define PCI_DRIVER(data...) GENERIC_DRIVER(pci_driver, data)
#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 { typedef struct {
uint32_t address; uint32_t address;

View File

@@ -12,34 +12,28 @@
#include "blockdev.h" #include "blockdev.h"
#define MAX_BLOCK_DEVS 64 #define MAX_BLOCK_DEVS 64
#define MAX_BLOCK_DRIVERS 64
int last_block_dev = 0; int last_block_dev = 0;
block_device block_devices[MAX_BLOCK_DEVS]; block_device block_devices[MAX_BLOCK_DEVS] = {0};
int last_block_driver = 0;
block_dev_driver block_dev_drivers[MAX_BLOCK_DRIVERS]; extern struct block_dev_driver __start_block_dev_driver[];
extern struct block_dev_driver __stop_block_dev_driver[];
#define NUM_DRIVERS ((size_t)(__stop_block_dev_driver - __start_block_dev_driver))
#define DRIVER(i) ((__start_block_dev_driver) + (i))
semaphore_t *block_semaphore; semaphore_t *block_semaphore;
bool blockdev_task_running = false; bool blockdev_task_running = false;
uint8_t block_dev_register_driver(block_dev_driver *driver) {
if (last_block_dev >= MAX_BLOCK_DEVS - 1) {
return BLOCK_DEV_REGISTER_DRIVER_FULL;
}
memcpy((uint8_t *) &block_dev_drivers[last_block_driver++], (const uint8_t *) driver, sizeof(block_dev_driver));
return BLOCK_DEV_REGISTER_DRIVER_OK;
}
uint8_t block_dev_register(block_device *device) { uint8_t block_dev_register(block_device *device) {
if (last_block_dev >= MAX_BLOCK_DEVS - 1) { if (last_block_dev >= MAX_BLOCK_DEVS - 1) {
return BLOCK_DEV_REGISTER_FULL; return BLOCK_DEV_REGISTER_FULL;
} }
memcpy((uint8_t *) &block_devices[last_block_dev++], (const uint8_t *) device, sizeof(block_device));
if (blockdev_task_running) { if (blockdev_task_running) {
semaphore_signal(block_semaphore); semaphore_signal(block_semaphore);
} }
memcpy((uint8_t *) &block_devices[last_block_dev++], (const uint8_t *) device, sizeof(block_device));
return BLOCK_DEV_REGISTER_OK; return BLOCK_DEV_REGISTER_OK;
} }
@@ -66,15 +60,15 @@ void block_dev_scan() {
block_devices[i].flags.unreadable = 1; block_devices[i].flags.unreadable = 1;
goto _block_dev_scan_free; goto _block_dev_scan_free;
} }
for (int j = 0; j < last_block_driver; ++j) { for (size_t j = 0; j < NUM_DRIVERS; ++j) {
// validate if driver is appropriate at all // validate if driver is appropriate at all
// don't use a root device driver (i.e. mbr) for a non-root device // don't use a root device driver (i.e. mbr) for a non-root device
if (block_dev_drivers[j].flags.root_only && !block_devices[i].flags.root_device) continue; if (DRIVER(j)->flags.root_only && !block_devices[i].flags.root_device) continue;
// let the driver test the disk // let the driver test the disk
uint8_t driver_result = block_dev_drivers[j].check_device(&block_devices[i], lba0); uint8_t driver_result = DRIVER(j)->check_device(&block_devices[i], lba0);
if (driver_result == BLOCK_DEV_DRIVER_CHECK_OK) { if (driver_result == BLOCK_DEV_DRIVER_CHECK_OK) {
block_devices[i].driver = &block_dev_drivers[j]; block_devices[i].driver = DRIVER(j);
block_devices[i].flags.driver_installed = 1; block_devices[i].flags.driver_installed = 1;
break; break;
} }

View File

@@ -6,6 +6,7 @@
#define NEW_KERNEL_BLOCKDEV_H #define NEW_KERNEL_BLOCKDEV_H
#include <types.h> #include <types.h>
#include <driver.h>
#define BLOCK_DEV_ACCESS_OK 0 #define BLOCK_DEV_ACCESS_OK 0
#define BLOCK_DEV_ACCESS_ERR 1 #define BLOCK_DEV_ACCESS_ERR 1
@@ -31,15 +32,16 @@ typedef uint8_t (*block_device_driver_free)(const block_device *device);
typedef uint8_t (*block_device_access)(const block_device *device, uint8_t direction, uint32_t lba, uint8_t sectors, void *target); typedef uint8_t (*block_device_access)(const block_device *device, uint8_t direction, uint32_t lba, uint8_t sectors, void *target);
struct block_dev_driver {
typedef struct {
char name[16]; char name[16];
struct { struct {
uint8_t root_only: 1; uint8_t root_only: 1;
} flags; } flags;
block_device_driver_check_device check_device; block_device_driver_check_device check_device;
block_device_driver_free free_device; block_device_driver_free free_device;
} block_dev_driver; } __attribute__((__aligned__(STRUCT_ALIGNMENT)));
#define BLOCK_DEV_DRIVER(data...) GENERIC_DRIVER(block_dev_driver, data)
typedef struct block_device { typedef struct block_device {
struct { struct {
@@ -53,13 +55,11 @@ typedef struct block_device {
uint32_t num_lba; uint32_t num_lba;
uint16_t block_size; uint16_t block_size;
block_device_access access; block_device_access access;
block_dev_driver *driver; struct block_dev_driver *driver;
void *device_info; // pointer to driver defined structure void *device_info; // pointer to driver defined structure
// todo device info // todo device info
} block_device; } block_device;
uint8_t block_dev_register_driver(block_dev_driver *driver);
uint8_t block_dev_register(block_device *device); uint8_t block_dev_register(block_device *device);
void block_dev_free(block_device *device); void block_dev_free(block_device *device);

View File

@@ -101,18 +101,6 @@ typedef struct {
}; };
} packed fat_directory_entry; } packed fat_directory_entry;
uint8_t fat_check_device(const block_device *device, uint8_t *first_sector);
block_dev_driver fat_driver = {
.name = "fat",
.check_device = fat_check_device,
.free_device = NULL, // todo
};
void fat_register_block_driver() {
block_dev_register_driver(&fat_driver);
}
void print_chars(char *chars, int amount) { void print_chars(char *chars, int amount) {
for (int i = 0; i < amount; ++i) { for (int i = 0; i < amount; ++i) {
if (chars[i] == 0) break; if (chars[i] == 0) break;
@@ -120,7 +108,7 @@ void print_chars(char *chars, int amount) {
} }
} }
uint8_t fat_check_device(const block_device *device, uint8_t *first_sector) { uint8_t used fat_check_device(const block_device *device, uint8_t *first_sector) {
fat_bpb bpb; fat_bpb bpb;
memcpy((uint8_t *) &bpb, first_sector, sizeof(fat_bpb)); memcpy((uint8_t *) &bpb, first_sector, sizeof(fat_bpb));
if (bpb.bpb.sectors_per_fat == 0 || bpb.bpb.sectors_per_cluster == 0) { if (bpb.bpb.sectors_per_fat == 0 || bpb.bpb.sectors_per_cluster == 0) {
@@ -205,5 +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(
.name = "fat",
.check_device = fat_check_device,
.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

View File

@@ -5,6 +5,4 @@
#ifndef NEW_KERNEL_FAT_H #ifndef NEW_KERNEL_FAT_H
#define NEW_KERNEL_FAT_H #define NEW_KERNEL_FAT_H
void fat_register_block_driver();
#endif //NEW_KERNEL_FAT_H #endif //NEW_KERNEL_FAT_H

View File

@@ -36,19 +36,6 @@ typedef struct {
uint32_t start_lba; uint32_t start_lba;
} mbr_block_driver_info; } mbr_block_driver_info;
uint8_t mbr_check_device(const block_device *device, uint8_t *first_sector);
block_dev_driver mbr_driver = {
.name = "mbr",
.flags.root_only = 1,
.check_device = mbr_check_device,
.free_device = NULL, // todo
};
void mbr_register_block_driver() {
block_dev_register_driver(&mbr_driver);
}
uint8_t mbr_block_dev_access(const block_device *device, uint8_t direction, uint32_t lba, uint8_t sectors, void *target) { uint8_t mbr_block_dev_access(const block_device *device, uint8_t direction, uint32_t lba, uint8_t sectors, void *target) {
if (!device->flags.present || lba > device->num_lba) { if (!device->flags.present || lba > device->num_lba) {
return BLOCK_DEV_ACCESS_ERR; return BLOCK_DEV_ACCESS_ERR;
@@ -63,7 +50,7 @@ uint8_t mbr_block_dev_access(const block_device *device, uint8_t direction, uint
return info->device->access(info->device, direction, actual_lba, sectors, target); return info->device->access(info->device, direction, actual_lba, sectors, target);
} }
uint8_t mbr_check_device(const block_device *device, uint8_t *first_sector) { uint8_t used mbr_check_device(const block_device *device, uint8_t *first_sector) {
mbr_table table; mbr_table table;
memcpy((uint8_t *) &table, first_sector + (device->block_size - sizeof(mbr_table)), sizeof(mbr_table)); memcpy((uint8_t *) &table, first_sector + (device->block_size - sizeof(mbr_table)), sizeof(mbr_table));
if (table.signature[0] != 0x55 && table.signature[1] != 0xAA) { // AA 55 but in little endian if (table.signature[0] != 0x55 && table.signature[1] != 0xAA) { // AA 55 but in little endian
@@ -112,3 +99,10 @@ void mbr_read_from_ide(uint8_t ide_drive) {
printf("Start at %d, count: %d\n", entry->start_lba, entry->num_lbas); printf("Start at %d, count: %d\n", entry->start_lba, entry->num_lbas);
free(mbr_data); free(mbr_data);
} }
BLOCK_DEV_DRIVER(
.name = "mbr",
.flags.root_only = 1,
.check_device = mbr_check_device,
.free_device = NULL, // todo
);

View File

@@ -7,8 +7,6 @@
#include <types.h> #include <types.h>
void mbr_register_block_driver();
void mbr_read_from_ide(uint8_t ide_drive); void mbr_read_from_ide(uint8_t ide_drive);
#endif //NEW_KERNEL_MBR_H #endif //NEW_KERNEL_MBR_H

View File

@@ -8,11 +8,8 @@
#include <libk/kprint.h> #include <libk/kprint.h>
#include <libk/libk.h> #include <libk/libk.h>
#include <drivers/pci.h> #include <drivers/pci.h>
#include <drivers/ide.h>
#include <libc/kprintf.h> #include <libc/kprintf.h>
#include <fs/mbr.h>
#include <fs/blockdev.h> #include <fs/blockdev.h>
#include <fs/fat.h>
#include <cpu/cpuidx.h> #include <cpu/cpuidx.h>
#include <tasks/task.h> #include <tasks/task.h>
#include <libk/syscall.h> #include <libk/syscall.h>
@@ -38,13 +35,7 @@ void init_pci_system() {
pci_init_drivers(); pci_init_drivers();
} }
void init_block_devices() { void noreturn used kmain(multiboot_info_t *multiboot_info, uint32_t mb_name) {
// register drivers
mbr_register_block_driver();
fat_register_block_driver();
}
void noreturn kmain(multiboot_info_t *multiboot_info, uint32_t mb_name) {
// early init // early init
isr_install(); isr_install();
vga_clear_screen(); vga_clear_screen();
@@ -77,9 +68,6 @@ void noreturn kmain(multiboot_info_t *multiboot_info, uint32_t mb_name) {
init_keyboard(); init_keyboard();
init_pci_system(); init_pci_system();
// register block device drivers
init_block_devices();
printf("Booted successfully v%d.%d.%d\n", version_major, version_minor, version_patch); printf("Booted successfully v%d.%d.%d\n", version_major, version_minor, version_patch);
// initialize tasking // initialize tasking

View File

@@ -29,10 +29,15 @@ SECTIONS
/* Read-write data (initialized) */ /* Read-write data (initialized) */
.data BLOCK(4K) : ALIGN(4K) .data BLOCK(4K) : ALIGN(4K)
{ {
__start_pci_drivers = .;
*(pci_drivers)
__stop_pci_drivers = .;
*(.data) *(.data)
. = ALIGN(16);
__start_pci_driver = .;
*(pci_driver)
__stop_pci_driver = .;
. = ALIGN(16);
__start_block_dev_driver = .;
*(block_dev_driver)
__stop_block_dev_driver = .;
} }
/* Read-write data (uninitialized) and stack */ /* Read-write data (uninitialized) and stack */