49 lines
1.4 KiB
C
49 lines
1.4 KiB
C
// HAL PCI configuration access. This file owns legacy mechanism-1 PCI config port I/O.
|
|
|
|
#include <stdint.h>
|
|
#include <intrin.h>
|
|
#include <kernel/hal/hal_api.h>
|
|
|
|
#define PCI_CONFIG_ADDR 0xCF8
|
|
#define PCI_CONFIG_DATA 0xCFC
|
|
|
|
// Creates addr.
|
|
static uint32_t MakeAddr(uint8_t bus, uint8_t dev, uint8_t fn, uint16_t offset) {
|
|
return 0x80000000UL
|
|
| ((uint32_t)bus << 16)
|
|
| ((uint32_t)(dev & 0x1F) << 11)
|
|
| ((uint32_t)(fn & 0x07) << 8)
|
|
| ((uint32_t)offset & 0xFCu);
|
|
}
|
|
|
|
static uint32_t PciRead32(uint16_t segment,
|
|
uint8_t bus,
|
|
uint8_t dev,
|
|
uint8_t fn,
|
|
uint16_t offset) {
|
|
if (segment != 0 || offset > 0xFCu)
|
|
return 0xFFFFFFFFu;
|
|
|
|
__outdword(PCI_CONFIG_ADDR, MakeAddr(bus, dev, fn, offset));
|
|
return __indword(PCI_CONFIG_DATA);
|
|
}
|
|
|
|
static void PciWrite32(uint16_t segment,
|
|
uint8_t bus,
|
|
uint8_t dev,
|
|
uint8_t fn,
|
|
uint16_t offset,
|
|
uint32_t value) {
|
|
if (segment != 0 || offset > 0xFCu)
|
|
return;
|
|
|
|
__outdword(PCI_CONFIG_ADDR, MakeAddr(bus, dev, fn, offset));
|
|
__outdword(PCI_CONFIG_DATA, value);
|
|
}
|
|
|
|
// Implements the pci Initialize operation.
|
|
void HalPciInitialize(HAL_PCI* out) {
|
|
out->Read32 = PciRead32;
|
|
out->Write32 = PciWrite32;
|
|
}
|