Espresso 0.0.1c
This commit is contained in:
118
drivers/pci.c
118
drivers/pci.c
@ -1,59 +1,97 @@
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include <drivers/pci.h>
|
||||
#include <drivers/ahci.h>
|
||||
#include <port_io.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <drivers/pci.h>
|
||||
|
||||
#define PCI_CONFIG_ADDRESS 0xCF8
|
||||
#define PCI_CONFIG_DATA 0xCFC
|
||||
|
||||
/*
|
||||
Register Offset Bits 31-24 Bits 23-16 Bits 15-8 Bits 7-0
|
||||
0x0 0x0 Device ID Vendor ID
|
||||
0x1 0x4 Status Command
|
||||
0x2 0x8 Class code Subclass Prog IF Revision ID
|
||||
0x3 0xC BIST Header type Latency Timer Cache Line Size
|
||||
*/
|
||||
|
||||
uint32_t pci_config_read(uint8_t bus, uint8_t device, uint8_t function, uint8_t offset)
|
||||
{
|
||||
uint32_t address = 0;
|
||||
address |= (bus << 16); // Bus number (bits 23-16)
|
||||
address |= (device << 11); // Device number (bits 15-11)
|
||||
address |= (function << 8); // Function number (bits 10-8)
|
||||
address |= (offset & 0xFC); // Register offset (bits 7-0)
|
||||
address |= (1 << 31); // Enable configuration access
|
||||
uint32_t address = 0;
|
||||
address |= (bus << 16); /* Bus number (bits 23-16) */
|
||||
address |= (device << 11); /* Device number (bits 15-11) */
|
||||
address |= (function << 8); /* Function number (bits 10-8) */
|
||||
address |= (offset & 0xFC); /* Register offset (bits 7-0) */
|
||||
address |= (1 << 31); /* Enable configuration access */
|
||||
|
||||
outl(PCI_CONFIG_ADDRESS, address); // Write address to PCI config space
|
||||
return inl(PCI_CONFIG_DATA); // Read data from PCI config space
|
||||
outl(PCI_CONFIG_ADDRESS, address); /* Write address to PCI config space */
|
||||
return inl(PCI_CONFIG_DATA); /* Read data from PCI config space */
|
||||
}
|
||||
|
||||
void pci_config_write(uint8_t bus, uint8_t device, uint8_t function, uint8_t offset, uint32_t value)
|
||||
{
|
||||
uint32_t address = 0x80000000 | (bus << 16) | (device << 11) | (function << 8) | (offset & 0xFC);
|
||||
outl(PCI_CONFIG_ADDRESS, address); // Send the address to PCI config space
|
||||
outl(PCI_CONFIG_DATA, value); // Write data to PCI config space
|
||||
uint32_t address = 0x80000000 | (bus << 16) | (device << 11) | (function << 8) | (offset & 0xFC);
|
||||
outl(PCI_CONFIG_ADDRESS, address); /* Send the address to PCI config space */
|
||||
outl(PCI_CONFIG_DATA, value); /* Write data to PCI config space */
|
||||
}
|
||||
|
||||
void pci_enumerate()
|
||||
void pci_config_read_block(uint8_t bus, uint8_t device, uint8_t function, uint8_t offset, void* buffer, size_t size)
|
||||
{
|
||||
for (uint16_t bus = 0; bus < 256; bus++) // Maximum 256 buses
|
||||
uint8_t* buf = (uint8_t*)buffer;
|
||||
|
||||
for (size_t i = 0; i < size; i += 4)
|
||||
{
|
||||
uint32_t value = pci_config_read(bus, device, function, offset + i);
|
||||
|
||||
size_t remaining = size - i;
|
||||
if (remaining >= 4)
|
||||
{
|
||||
for (uint8_t device = 0; device < 32; device++) // Maximum 32 devices per bus
|
||||
{
|
||||
for (uint8_t function = 0; function < 8; function++) // Maximum 8 functions per device
|
||||
{
|
||||
uint32_t vendor_id = pci_config_read(bus, device, function, 0x00);
|
||||
if (vendor_id == 0xFFFFFFFF) continue; // No device present
|
||||
|
||||
uint32_t device_id = pci_config_read(bus, device, function, 0x02);
|
||||
uint32_t class_code = pci_config_read(bus, device, function, 0x08);
|
||||
printf("Found PCI device: Vendor ID: 0x%X Device ID: 0x%X Class: 0x%X\n", vendor_id, device_id, class_code);
|
||||
|
||||
printf("0x%X", class_code);
|
||||
printf(" --- ");
|
||||
printf("0x%X\n", (class_code >> 8));
|
||||
|
||||
|
||||
if ((class_code >> 8) == 0x0C) {
|
||||
printf("Found USB controller (Class: 0x%02X)\n", class_code);
|
||||
// Now, you can initialize and configure the USB controller.
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
*(uint32_t*)(buf + i) = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (size_t j = 0; j < remaining; ++j)
|
||||
{
|
||||
buf[i + j] = (value >> (8 * j)) & 0xFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void pci_enumerate(void)
|
||||
{
|
||||
for (uint16_t bus = 0; bus < 256; bus++) /* Maximum 256 buses */
|
||||
{
|
||||
for (uint8_t device = 0; device < 32; device++) /* Maximum 32 devices per bus */
|
||||
{
|
||||
for (uint8_t function = 0; function < 8; function++) /* Maximum 8 functions per device */
|
||||
{
|
||||
struct pci_header pre_header;
|
||||
pci_config_read_block(bus, device, function, 0x00, &pre_header, sizeof(pre_header));
|
||||
|
||||
if (pre_header.vendor_id == 0xFFFF)
|
||||
{
|
||||
continue; /* No device present */
|
||||
}
|
||||
|
||||
if (pre_header.class_code == 0xB)
|
||||
{
|
||||
printf("Processor found on PCI bus, what?!?!\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (pre_header.header_type == 0x00)
|
||||
{
|
||||
struct pci_header_type_0 hdr;
|
||||
pci_config_read_block(bus, device, function, 0x00, &hdr, sizeof(hdr));
|
||||
|
||||
if (hdr.class_code == 0x1 && hdr.subclass == 0x6 && hdr.prog_if == 0x1)
|
||||
{
|
||||
/*configure_ahci_controller(hdr);*/
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user