diff options
| author | Aleksa Vuckovic <aleksa@vuckovic.cc> | 2023-06-07 01:23:03 +0200 |
|---|---|---|
| committer | Aleksa Vuckovic <aleksa@vuckovic.cc> | 2023-06-07 01:23:03 +0200 |
| commit | 90e2de72ef2688986c206fd08605aec81b5890d6 (patch) | |
| tree | 0a72bf0b2f2a564f3fc18314e6ea1cbe524eb28f /kernel/src | |
| parent | f5826164936359560ef5b88b97fc953065eb7794 (diff) | |
Diffstat (limited to 'kernel/src')
| -rw-r--r-- | kernel/src/devices/pci.c | 67 | ||||
| -rw-r--r-- | kernel/src/devices/sata.c | 73 | ||||
| -rw-r--r-- | kernel/src/main.c | 2 |
3 files changed, 112 insertions, 30 deletions
diff --git a/kernel/src/devices/pci.c b/kernel/src/devices/pci.c index 9862dee..ea6c80e 100644 --- a/kernel/src/devices/pci.c +++ b/kernel/src/devices/pci.c @@ -9,7 +9,9 @@ #include <pci.h> #include <pci_info.h> -inline void pci_print_dev(pci_dev *pci_func) +pci_dev_list_t pci_dev_list; + +inline void pci_print_dev(pci_dev_t *pci_func) { const char *vendor_str = get_vendor(pci_func->vendor_id); const char *class_str = get_class(pci_func->class_); @@ -54,18 +56,20 @@ void enumerate_function(uint64_t dev_addr, uint64_t function) uint64_t func_addr = dev_addr + (function << 12); map_addr(func_addr, func_addr, FLAG_PRESENT); - pci_dev *pci_func = (pci_dev *)kalloc(sizeof(pci_dev)); - memcpy(pci_func, (uint64_t *)func_addr, sizeof(pci_dev)); + pci_dev0_t *pci_func = (pci_dev0_t *)kalloc(sizeof(pci_dev0_t)); + memcpy(pci_func, (uint64_t *)func_addr, sizeof(pci_dev0_t)); - if (pci_func->device_id == 0) - goto error; - if (pci_func->device_id == 0xFFFF) - goto error; + int id = pci_func->pci_dev.device_id; + if (id == 0 || id == 0xFFFF) { + kfree(pci_func); + return; + } - pci_print_dev(pci_func); + pci_dev_list_t *dev_list = kalloc(sizeof(pci_dev_list_t)); + dev_list->dev = pci_func; -error: - kfree(pci_func); + add_to_list(&dev_list->list, &pci_dev_list.list, + pci_dev_list.list.next); } void enumerate_device(uint64_t bus_addr, uint64_t device) @@ -73,21 +77,18 @@ void enumerate_device(uint64_t bus_addr, uint64_t device) uint64_t dev_addr = bus_addr + (device << 15); map_addr(dev_addr, dev_addr, FLAG_PRESENT); - pci_dev *pci_device = (pci_dev *)kalloc(sizeof(pci_dev)); - memcpy(pci_device, (uint64_t *)bus_addr, sizeof(pci_dev)); + pci_dev_t *pci_device = (pci_dev_t *)kalloc(sizeof(pci_dev_t)); + memcpy(pci_device, (uint64_t *)bus_addr, sizeof(pci_dev_t)); - if (pci_device->device_id == 0) - goto error; - if (pci_device->device_id == 0xFFFF) - goto error; + if (pci_device->device_id == 0 || pci_device->device_id == 0xFFFF) { + kfree(pci_device); + return; + } size_t func; for (func = 0; func < 8; func++) { enumerate_function(dev_addr, func); } - -error: - kfree(pci_device); } void enumerate_bus(uint64_t base_addr, uint64_t bus) @@ -95,31 +96,39 @@ void enumerate_bus(uint64_t base_addr, uint64_t bus) uint64_t bus_addr = base_addr + (bus << 20); map_addr(bus_addr, bus_addr, FLAG_PRESENT); - pci_dev *pci_device = (pci_dev *)kalloc(sizeof(pci_dev)); - memcpy(pci_device, (uint64_t *)bus_addr, sizeof(pci_dev)); + pci_dev_t *pci_device = (pci_dev_t *)kalloc(sizeof(pci_dev_t)); + memcpy(pci_device, (uint64_t *)bus_addr, sizeof(pci_dev_t)); - if (pci_device->device_id == 0) - goto error; - if (pci_device->device_id == 0xFFFF) - goto error; + if (pci_device->device_id == 0 || pci_device->device_id == 0xFFFF) { + kfree(pci_device); + return; + } size_t dev; for (dev = 0; dev < 32; dev++) { enumerate_device(bus_addr, dev); } - -error: - kfree(pci_device); } void enumerate_cfg_space(config_space_mcfgt *cfg_space) { + INIT_LIST(pci_dev_list.list); + size_t i; for (i = cfg_space->start_bus; i < cfg_space->end_bus; i++) { enumerate_bus(cfg_space->base_addr, i); } } +void pci_print_all() +{ + pci_dev_list_t *curr; + list_for_each_entry(curr, (&pci_dev_list.list), list) { + pci_print_dev(&curr->dev->pci_dev); + } + printf("\n"); +} + void read_mcfgt() { uint64_t *mcfgt_addr = find_sys_table_addr("MCFG"); @@ -145,9 +154,7 @@ void read_mcfgt() for (i = 0; i < len; i++) { memcpy(cfg_space, (uint64_t *)mcfgt_cfg_addr, sizeof(config_space_mcfgt)); - /* printf("addr: 0x%x, group: %d, start: %d, stop: %d\n", cfg_space->base_addr, cfg_space->pci_seg_group, cfg_space->start_bus, cfg_space->end_bus); */ enumerate_cfg_space(cfg_space); } - printf("\n"); kfree(cfg_space); } diff --git a/kernel/src/devices/sata.c b/kernel/src/devices/sata.c new file mode 100644 index 0000000..d091941 --- /dev/null +++ b/kernel/src/devices/sata.c @@ -0,0 +1,73 @@ +#include <sata.h> +#include <libk/string.h> +#include <libk/stdio.h> +#include <heap.h> +#include <paging.h> +#include <pci.h> +#include <ahci.h> + +// Check device type +static int check_type(HBA_PORT *port) +{ + uint32_t ssts = port->ssts; + + uint8_t ipm = (ssts >> 8) & 0x0F; + uint8_t det = ssts & 0x0F; + + if (det != HBA_PORT_DET_PRESENT) // Check drive status + return AHCI_DEV_NULL; + if (ipm != HBA_PORT_IPM_ACTIVE) + return AHCI_DEV_NULL; + + switch (port->sig) { + case SATA_SIG_ATAPI: + return AHCI_DEV_SATAPI; + case SATA_SIG_SEMB: + return AHCI_DEV_SEMB; + case SATA_SIG_PM: + return AHCI_DEV_PM; + default: + return AHCI_DEV_SATA; + } +} + +void probe_port(HBA_MEM *abar) +{ + // Search disk in implemented ports + uint32_t pi = abar->pi; + int i = 0; + while (i < 32) { + if (pi & 1) { + int dt = check_type(&abar->ports[i]); + if (dt == AHCI_DEV_SATA) { + printf("SATA drive found at port %d\n", i); + } else if (dt == AHCI_DEV_SATAPI) { + printf("SATAPI drive found at port %d\n", i); + } else if (dt == AHCI_DEV_SEMB) { + printf("SEMB drive found at port %d\n", i); + } else if (dt == AHCI_DEV_PM) { + printf("PM drive found at port %d\n", i); + } + } + + pi >>= 1; + i++; + } +} + +void ahci() +{ + pci_dev_list_t *pos; + list_for_each_entry(pos, (&pci_dev_list.list), list) { + pci_dev_t *dev = &pos->dev->pci_dev; + if (dev->class_ != 0x1 || dev->subclass != 0x6) + continue; + + HBA_MEM *abar = (HBA_MEM *)(uint64_t)pos->dev->bar[5]; + printf("AHCI: %x\n", abar); + map_addr((uint64_t)abar, (uint64_t)abar, + FLAG_PRESENT | FLAG_WRITABLE | FLAG_HUGE); + + probe_port(abar); + } +} diff --git a/kernel/src/main.c b/kernel/src/main.c index ceba990..465c4b3 100644 --- a/kernel/src/main.c +++ b/kernel/src/main.c @@ -26,6 +26,7 @@ #include <scheduler.h> #include <process.h> #include <mcfg.h> +#include <sata.h> int kernel_main(mb2_tag_header *multiboot_bootinfo, uint32_t multiboot_magic); int kernel_main(mb2_tag_header *multiboot_bootinfo, uint32_t multiboot_magic) @@ -52,6 +53,7 @@ int kernel_main(mb2_tag_header *multiboot_bootinfo, uint32_t multiboot_magic) enable_interrupts(); init_userspace(); read_mcfgt(); + ahci(); init_scheduler(); |
