Newer
Older
tree-os / src / kernel / drivers / pci / pci.c
#include <_stdio.h>
#include <pci.h>
#include <ports.h>
#include <stdint.h>
#include <task.h>
#include <util.h>

uint8_t pciConfigReadByte(uint8_t bus, uint8_t device, uint8_t function,
                          uint8_t offset) {
    uint32_t lbus = (uint32_t)bus;
    uint32_t lslot = (uint32_t)device;
    uint32_t lfunc = (uint32_t)function;

    uint32_t address = (uint32_t)((lbus << 16) | (lslot << 11) | (lfunc << 8) |
                                  (offset & 0xFC) | ((uint32_t)0x80000000));
    outi(0xCF8, address);
    ioWait();
    return (uint8_t)(ini(0xCFC) >> ((offset & 3) * 8));
}

uint16_t pciConfigReadWord(uint8_t bus, uint8_t device, uint8_t function,
                           uint8_t offset) {
    return (uint16_t)pciConfigReadByte(bus, device, function, offset) << 8 |
           (uint16_t)pciConfigReadByte(bus, device, function, offset + 1);
}

uint8_t getHeaderType(uint8_t bus, uint8_t device, uint8_t function) {
    return pciConfigReadByte(bus, device, function, 0x0D);
}

uint16_t getVendorID(uint8_t bus, uint8_t device, uint8_t function) {
    return pciConfigReadWord(bus, device, function, 2);
}

void checkDevice(uint8_t bus, uint8_t device) {
    uint16_t vendorID = getVendorID(bus, device, 0);
    if (vendorID == 0xFFFF)
        return;
    printf("checking device %i;%i\n", bus, device);
}

void checkBus(uint8_t bus) {
    printf("checking bus %i...\n", bus);
    yields();
    for (uint8_t device = 0; device < 32; device++) {
        checkDevice(bus, device);
        yields();
    }
}

void scanPCIDevices() {
    printf("scanning pci devices...\n");
    yields();
    if (!(getHeaderType(0, 0, 0) & 0x80)) {
        printf("discovored a single pci bus\n");
        yields();
        // singe bus
        checkBus(0);
        return;
    }
    printf("multiple pci buses are not implemented yet!\n");
    yields();
}