#include #include "assembly.h" #include "core.h" #include "list.h" #include "memory.h" #define CONFIG_ADDR_ENABLE (31) #define CONFIG_ADDR_BUS (16) #define CONFIG_ADDR_PORT (11) #define CONFIG_ADDR_FUNC (8) #define CONFIG_ADDR_REG (0) #define VENDOR_DEVICE_ID_REGISTER (0x00) #define VENDOR_ID_BIT_MASK (0x0000FFFF) #define VENDOR_ID_BIT_SHIFT (0) #define DEVICE_ID_BIT_MASK (0xFFFF0000) #define DEVICE_ID_BIT_SHIFT (16) struct pci_device { uint8_t bus; uint8_t port; uint16_t vendor_id; uint16_t device_id; struct list_node node; }; struct list pci_devices = LIST_INIT(); static int pci_read_register(struct pci_device *dev, uint8_t func, uint8_t reg, uint32_t *res) { uint32_t config_addr = 0; config_addr |= (1U << CONFIG_ADDR_ENABLE); config_addr |= (uint32_t)(dev->bus) << CONFIG_ADDR_BUS; config_addr |= (uint32_t)(dev->port) << CONFIG_ADDR_PORT; config_addr |= (uint32_t)(func) << CONFIG_ADDR_FUNC; config_addr |= (uint32_t)(reg) << CONFIG_ADDR_REG; outl(config_addr, 0xCF8); *res = inl(0xCFC); return 0; } int pci_init(void) { int num_devices = 0; for (int bus = 0; bus < 256; bus++) { for (int port = 0; port < 256; port++) { struct pci_device dev = { .bus = (uint8_t)(bus), .port = (uint8_t)(port), }; uint32_t reg_value = 0; pci_read_register(&dev, 0, VENDOR_DEVICE_ID_REGISTER, ®_value); uint16_t vendor_id = (reg_value & VENDOR_ID_BIT_MASK) >> VENDOR_ID_BIT_SHIFT; uint16_t device_id = (reg_value & DEVICE_ID_BIT_MASK) >> DEVICE_ID_BIT_SHIFT; if (vendor_id == 0xFFFF) { continue; } struct pci_device *list_entry = malloc(sizeof(struct pci_device)); list_entry->bus = dev.bus; list_entry->port = dev.port; list_entry->vendor_id = vendor_id; list_entry->device_id = device_id; printk("list before first %p last %p\n", pci_devices.first, pci_devices.last); list_append(&pci_devices, &(list_entry->node)); printk("list after first %p last %p\n", pci_devices.first, pci_devices.last); num_devices++; } } printk("\nfound %i PCI devices:\n", num_devices); printk("\n BUS : PORT VENDOR : DEVICE\n"); struct pci_device *entry; LIST_FOR_EACH_ENTRY(&pci_devices, struct pci_device, node, entry) { printk("- %x:%x %x:%x\n", entry->bus, entry->port, entry->vendor_id, entry->device_id); } return 0; }