diff options
| author | Aleksa Vuckovic <aleksa@vuckovic.cc> | 2023-03-09 01:22:07 +0100 |
|---|---|---|
| committer | Aleksa Vuckovic <aleksa@vuckovic.cc> | 2023-03-09 01:22:07 +0100 |
| commit | eb3b263b11e90902841dc21c5a55c45e59128542 (patch) | |
| tree | aa06c0e5f04907c4f92ec51b3b94f07e98ebd4ee | |
| parent | 48a4f607403c074252d3e77b2e0b3c1a8f3b86c7 (diff) | |
pcie device enumeration
| -rw-r--r-- | kernel/include/mcfg.h | 4 | ||||
| -rw-r--r-- | kernel/include/pci.h | 49 | ||||
| -rw-r--r-- | kernel/src/devices/pci.c | 96 | ||||
| -rw-r--r-- | kernel/src/main.c | 2 | ||||
| -rw-r--r-- | kernel/src/mem/pmm.c | 2 | ||||
| -rw-r--r-- | kernel/src/scheduler/ap_startup.c | 2 |
6 files changed, 146 insertions, 9 deletions
diff --git a/kernel/include/mcfg.h b/kernel/include/mcfg.h index 9f062c0..2e238cf 100644 --- a/kernel/include/mcfg.h +++ b/kernel/include/mcfg.h @@ -6,8 +6,8 @@ struct config_space_mcfgt { uint64_t base_addr; uint16_t pci_seg_group; - uint8_t start_pci_bus; - uint8_t end_pci_bus; + uint8_t start_bus; + uint8_t end_bus; uint32_t reserved; } __attribute__((packed)); typedef struct config_space_mcfgt config_space_mcfgt; diff --git a/kernel/include/pci.h b/kernel/include/pci.h new file mode 100644 index 0000000..01d97fc --- /dev/null +++ b/kernel/include/pci.h @@ -0,0 +1,49 @@ +#ifndef PCI_H +#define PCI_H + +#include <types.h> + +struct pci_dev { + uint16_t vendor_id; + uint16_t device_id; + uint16_t command; + uint16_t status; + uint8_t revision_id; + uint8_t progif; + uint8_t subclass; + uint8_t class_; + uint8_t cache_line_size; + uint8_t latency_timer; + uint8_t header_type; + uint8_t bist; +}; +typedef struct pci_dev pci_dev; + +const char *class_string[] = { + "Unclassified", + "Mass Storage Controller", + "Network Controller", + "Display Controller", + "Multimedia Controller", + "Memory Controller", + "Bridge", + "Simple Communication Controller", + "Base System Peripheral", + "Input Device Controller", + "Docking Station", + "Processor", + "Serial Bus Controller", + "Wireless Controller", + "Intelligent Controller", + "Satellite Communication Controller", + "Encryption Controller", + "Signal Processing Controller", + "Processing Accelerator", + "Non-Essential Instrumentation", +}; + +const char *subclass_string[] = { + +}; + +#endif diff --git a/kernel/src/devices/pci.c b/kernel/src/devices/pci.c index af0308a..978e9e9 100644 --- a/kernel/src/devices/pci.c +++ b/kernel/src/devices/pci.c @@ -1,10 +1,100 @@ #include <types.h> #include <rsdp.h> #include <libk/stdio.h> +#include <libk/serial_stdio.h> #include <mcfg.h> #include <heap.h> #include <paging.h> #include <libk/string.h> +#include <pci.h> + +const char *vendor_name(uint64_t vendor_id) +{ + switch (vendor_id) { + case 0x8086: + return "Intel"; + case 0x1022: + return "AMD"; + default: + return "Unknown"; + } +} + +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)); + + if (pci_func->device_id == 0) + goto error; + if (pci_func->device_id == 0xFFFF) + goto error; + + const char *vendor_str = vendor_name(pci_func->vendor_id); + size_t class_str = + pci_func->class_ < sizeof(class_string) ? pci_func->class_ : 0; + + printf("%s, 0x%x, %s, 0x%x\n", vendor_str, pci_func->device_id, + class_string[class_str], pci_func->subclass); + +error: + kfree(pci_func); +} + +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)); + + if (pci_device->device_id == 0) + goto error; + if (pci_device->device_id == 0xFFFF) + goto error; + + 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) +{ + 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)); + + if (pci_device->device_id == 0) + goto error; + if (pci_device->device_id == 0xFFFF) + goto error; + + 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) +{ + size_t i; + for (i = cfg_space->start_bus; i < cfg_space->end_bus; i++) { + enumerate_bus(cfg_space->base_addr, i); + } +} void read_mcfgt() { @@ -31,9 +121,9 @@ 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_pci_bus, cfg_space->end_pci_bus); + /* 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/main.c b/kernel/src/main.c index 2e142ca..ceba990 100644 --- a/kernel/src/main.c +++ b/kernel/src/main.c @@ -41,14 +41,12 @@ int kernel_main(mb2_tag_header *multiboot_bootinfo, uint32_t multiboot_magic) init_mutex(&serial_stdio_lock); /* framebuffer is enabled from this point */ init_pmm(); - memory_usage(); init_keyboard(); init_timer(TICKS_PER_SECOND); init_idt(); disc_init(); ext2_init(); init_tss(); - list_sys_tables(); parse_madt(); apic_remap_interrupts(); enable_interrupts(); diff --git a/kernel/src/mem/pmm.c b/kernel/src/mem/pmm.c index d0c8a9f..e79cccf 100644 --- a/kernel/src/mem/pmm.c +++ b/kernel/src/mem/pmm.c @@ -42,7 +42,7 @@ void init_pmm() void memory_usage() { - printf("memory used: %dMB\n", + printf("memory used: %dMB", (MEM_USED_BELOW + (all_mem_cnt - free_mem_cnt) * PAGE_SIZE) / 1024 / 1024); printf("memory free: %dMB\n", free_mem_cnt * PAGE_SIZE / 1024 / 1024); diff --git a/kernel/src/scheduler/ap_startup.c b/kernel/src/scheduler/ap_startup.c index 92fc51c..d2baaec 100644 --- a/kernel/src/scheduler/ap_startup.c +++ b/kernel/src/scheduler/ap_startup.c @@ -15,7 +15,7 @@ void ap_startup(void) __asm__ __volatile__("pause;"); } - printf("curr_cpu_apic_id: 0x%x\n", curr_cpu_apic_id()); + /* printf("curr_cpu_apic_id: 0x%x\n", curr_cpu_apic_id()); */ lock(cnt_lock); ap_cnt++; unlock(cnt_lock); |
