Splitting up PCI code into platform dependent parts
This commit is contained in:
parent
162c27767e
commit
c6e56a25f6
@ -20,6 +20,7 @@ src_amd64 = [
|
|||||||
"amd64/ioapic.c",
|
"amd64/ioapic.c",
|
||||||
"dev/x86/vgacons.c",
|
"dev/x86/vgacons.c",
|
||||||
"dev/ahci.c",
|
"dev/ahci.c",
|
||||||
|
"dev/pci.c",
|
||||||
]
|
]
|
||||||
|
|
||||||
src_common = [
|
src_common = [
|
||||||
|
258
sys/amd64/pci.c
258
sys/amd64/pci.c
@ -7,16 +7,6 @@
|
|||||||
#include "amd64.h"
|
#include "amd64.h"
|
||||||
#include "amd64op.h"
|
#include "amd64op.h"
|
||||||
|
|
||||||
void PCI_ScanBus();
|
|
||||||
|
|
||||||
void
|
|
||||||
PCI_Init()
|
|
||||||
{
|
|
||||||
kprintf("Initializing PCI\n");
|
|
||||||
PCI_ScanBus();
|
|
||||||
kprintf("PCI Initialization Done\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
#define PCI_PORT_ADDR 0xCF8
|
#define PCI_PORT_ADDR 0xCF8
|
||||||
#define PCI_PORT_DATABASE 0xCFC
|
#define PCI_PORT_DATABASE 0xCFC
|
||||||
|
|
||||||
@ -94,251 +84,3 @@ PCICfgWrite32(uint32_t bus, uint32_t slot, uint32_t func, uint32_t reg,
|
|||||||
outl(port, data);
|
outl(port, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t
|
|
||||||
PCIGetDeviceID(uint32_t bus, uint32_t device, uint32_t func)
|
|
||||||
{
|
|
||||||
return PCICfgRead16(bus, device, func, PCI_OFFSET_DEVICEID);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint16_t
|
|
||||||
PCIGetVendorID(uint32_t bus, uint32_t device, uint32_t func)
|
|
||||||
{
|
|
||||||
return PCICfgRead16(bus, device, func, PCI_OFFSET_VENDORID);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t
|
|
||||||
PCIGetBaseClass(uint32_t bus, uint32_t device, uint32_t func)
|
|
||||||
{
|
|
||||||
return PCICfgRead8(bus, device, func, PCI_OFFSET_CLASS);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t
|
|
||||||
PCIGetSubClass(uint32_t bus, uint32_t device, uint32_t func)
|
|
||||||
{
|
|
||||||
return PCICfgRead8(bus, device, func, PCI_OFFSET_SUBCLASS);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t
|
|
||||||
PCIGetHeaderType(uint32_t bus, uint32_t device, uint32_t func)
|
|
||||||
{
|
|
||||||
return PCICfgRead8(bus, device, func, PCI_OFFSET_HEADERTYPE);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t
|
|
||||||
PCI_CfgRead8(PCIDevice *dev, uint32_t reg)
|
|
||||||
{
|
|
||||||
return PCICfgRead8(dev->bus, dev->slot, dev->func, reg);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint16_t
|
|
||||||
PCI_CfgRead16(PCIDevice *dev, uint32_t reg)
|
|
||||||
{
|
|
||||||
return PCICfgRead16(dev->bus, dev->slot, dev->func, reg);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t
|
|
||||||
PCI_CfgRead32(PCIDevice *dev, uint32_t reg)
|
|
||||||
{
|
|
||||||
return PCICfgRead32(dev->bus, dev->slot, dev->func, reg);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
PCI_CfgWrite8(PCIDevice *dev, uint32_t reg, uint8_t data)
|
|
||||||
{
|
|
||||||
return PCICfgWrite8(dev->bus, dev->slot, dev->func, reg, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
PCI_CfgWrite16(PCIDevice *dev, uint32_t reg, uint16_t data)
|
|
||||||
{
|
|
||||||
return PCICfgWrite16(dev->bus, dev->slot, dev->func, reg, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
PCI_CfgWrite32(PCIDevice *dev, uint32_t reg, uint32_t data)
|
|
||||||
{
|
|
||||||
return PCICfgWrite32(dev->bus, dev->slot, dev->func, reg, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint16_t
|
|
||||||
PCI_GetDeviceID(PCIDevice *dev)
|
|
||||||
{
|
|
||||||
return PCI_CfgRead16(dev, PCI_OFFSET_DEVICEID);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint16_t
|
|
||||||
PCI_GetVendorID(PCIDevice *dev)
|
|
||||||
{
|
|
||||||
return PCI_CfgRead16(dev, PCI_OFFSET_VENDORID);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t
|
|
||||||
PCI_GetBaseClass(PCIDevice *dev)
|
|
||||||
{
|
|
||||||
return PCI_CfgRead8(dev, PCI_OFFSET_CLASS);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t
|
|
||||||
PCI_GetSubClass(PCIDevice *dev)
|
|
||||||
{
|
|
||||||
return PCI_CfgRead8(dev, PCI_OFFSET_SUBCLASS);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t
|
|
||||||
PCI_GetHeaderType(PCIDevice *dev)
|
|
||||||
{
|
|
||||||
return PCI_CfgRead8(dev, PCI_OFFSET_HEADERTYPE);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
PCICheckFunction(uint32_t bus, uint32_t device, uint32_t func)
|
|
||||||
{
|
|
||||||
uint8_t baseClass, subClass;
|
|
||||||
uint16_t vendorId, deviceId;
|
|
||||||
|
|
||||||
baseClass = PCIGetBaseClass(bus, device, func);
|
|
||||||
subClass = PCIGetSubClass(bus, device, func);
|
|
||||||
vendorId = PCIGetVendorID(bus, device, func);
|
|
||||||
deviceId = PCIGetDeviceID(bus, device, func);
|
|
||||||
|
|
||||||
if (baseClass == PCI_CLASS_BRIDGE) {
|
|
||||||
if (subClass == PCI_SCLASS_BRIDGE_HOST) {
|
|
||||||
kprintf("PCI(%d,%d,%d): Host Bridge (%04x:%04x)\n",
|
|
||||||
bus, device, func, vendorId, deviceId);
|
|
||||||
} else if (subClass == PCI_SCLASS_BRIDGE_ISA) {
|
|
||||||
kprintf("PCI(%d,%d,%d): ISA Bridge (%04x:%04x)\n",
|
|
||||||
bus, device, func, vendorId, deviceId);
|
|
||||||
} else if (subClass == PCI_SCLASS_BRIDGE_PCI) {
|
|
||||||
kprintf("PCI(%d,%d,%d): PCI-PCI Bridge (%04x:%04x)\n",
|
|
||||||
bus, device, func, vendorId, deviceId);
|
|
||||||
// Scan sub-bus
|
|
||||||
} else if (subClass == PCI_SCLASS_BRIDGE_MISC) {
|
|
||||||
kprintf("PCI(%d,%d,%d): Other Bridge (%04x:%04x)\n",
|
|
||||||
bus, device, func, vendorId, deviceId);
|
|
||||||
}
|
|
||||||
} else if (baseClass == PCI_CLASS_STORAGE) {
|
|
||||||
if (subClass == PCI_SCLASS_STORAGE_SATA) {
|
|
||||||
kprintf("PCI(%d,%d,%d): SATA Controller (%04x:%04x)\n",
|
|
||||||
bus, device, func, vendorId, deviceId);
|
|
||||||
|
|
||||||
AHCI_Init(bus, device, func);
|
|
||||||
} else if (subClass == PCI_SCLASS_STORAGE_IDE) {
|
|
||||||
kprintf("PCI(%d,%d,%d): IDE Controller (%04x:%04x)\n",
|
|
||||||
bus, device, func, vendorId, deviceId);
|
|
||||||
}
|
|
||||||
} else if ((baseClass == PCI_CLASS_NETWORK) && (subClass == 0x00)) {
|
|
||||||
kprintf("PCI(%d,%d,%d): Ethernet (%04x:%04x)\n",
|
|
||||||
bus, device, func, vendorId, deviceId);
|
|
||||||
} else if ((baseClass == PCI_CLASS_GRAPHICS) && (subClass == 0x00)) {
|
|
||||||
kprintf("PCI(%d,%d,%d): VGA (%04x:%04x)\n",
|
|
||||||
bus, device, func, vendorId, deviceId);
|
|
||||||
} else if ((baseClass == PCI_CLASS_BUS) && (subClass == PCI_SCLASS_BUS_SMBUS)) {
|
|
||||||
kprintf("PCI(%d,%d,%d): SMBUS (%04x:%04x)\n",
|
|
||||||
bus, device, func, vendorId, deviceId);
|
|
||||||
} else {
|
|
||||||
kprintf("PCI(%d,%d,%d): Unsupported (%04x:%04x %02x:%02x)\n",
|
|
||||||
bus, device, func, vendorId, deviceId, baseClass, subClass);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
PCIScanDevice(uint32_t bus, uint32_t device)
|
|
||||||
{
|
|
||||||
uint8_t headerType;
|
|
||||||
uint16_t vendorId;
|
|
||||||
|
|
||||||
vendorId = PCIGetVendorID(bus, device, 0);
|
|
||||||
if (vendorId == 0xFFFF)
|
|
||||||
return;
|
|
||||||
|
|
||||||
PCICheckFunction(bus, device, 0);
|
|
||||||
|
|
||||||
headerType = PCIGetHeaderType(bus, device, 0);
|
|
||||||
if ((headerType & 0x80) != 0) {
|
|
||||||
uint8_t func;
|
|
||||||
for (func = 0; func < 8; func++) {
|
|
||||||
if (PCIGetVendorID(bus, device, func) != 0xFFFF) {
|
|
||||||
PCICheckFunction(bus, device, func);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
PCIScanBus(uint8_t bus)
|
|
||||||
{
|
|
||||||
uint8_t device;
|
|
||||||
|
|
||||||
for (device = 0; device < 32; device++) {
|
|
||||||
PCIScanDevice(bus, device);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
PCI_ScanBus()
|
|
||||||
{
|
|
||||||
uint8_t headerType = PCIGetHeaderType(0, 0, 0);
|
|
||||||
|
|
||||||
if ((headerType & 0x80) == 0) {
|
|
||||||
PCIScanBus(0);
|
|
||||||
} else {
|
|
||||||
uint8_t busNo;
|
|
||||||
|
|
||||||
for (busNo = 0; busNo < 8; busNo++) {
|
|
||||||
if (PCIGetVendorID(0, 0, busNo) != 0xFFFF)
|
|
||||||
break;
|
|
||||||
PCIScanBus(busNo);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
PCI_Configure(PCIDevice *dev)
|
|
||||||
{
|
|
||||||
int bar;
|
|
||||||
|
|
||||||
dev->irq = PCI_CfgRead8(dev, PCI_OFFSET_IRQLINE);
|
|
||||||
|
|
||||||
PCI_CfgWrite16(dev, PCI_OFFSET_COMMAND,
|
|
||||||
PCI_COMMAND_IOENABLE | PCI_COMMAND_MEMENABLE | PCI_COMMAND_BUSMASTER);
|
|
||||||
|
|
||||||
for (bar = 0; bar < PCI_MAX_BARS; bar++)
|
|
||||||
{
|
|
||||||
dev->bars[bar].base = 0;
|
|
||||||
dev->bars[bar].size = 0;
|
|
||||||
dev->bars[bar].type = PCIBAR_TYPE_NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (bar = 0; bar < PCI_MAX_BARS; bar++)
|
|
||||||
{
|
|
||||||
uint32_t barReg = PCI_OFFSET_BARFIRST + 4 * bar;
|
|
||||||
uint32_t base, size;
|
|
||||||
uint32_t origValue = PCI_CfgRead32(dev, barReg);
|
|
||||||
|
|
||||||
PCI_CfgWrite32(dev, barReg, 0xFFFFFFFF);
|
|
||||||
size = PCI_CfgRead32(dev, barReg);
|
|
||||||
if (size == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
PCI_CfgWrite32(dev, barReg, origValue);
|
|
||||||
|
|
||||||
if (origValue & 0x1)
|
|
||||||
{
|
|
||||||
dev->bars[bar].type = PCIBAR_TYPE_IO;
|
|
||||||
base = origValue & 0xFFFFFFFC;
|
|
||||||
size = size & 0xFFFFFFFC;
|
|
||||||
size = ~size + 1;
|
|
||||||
} else {
|
|
||||||
dev->bars[bar].type = PCIBAR_TYPE_MEM;
|
|
||||||
base = origValue & 0xFFFFFFF0;
|
|
||||||
size = size & 0xFFFFFFF0;
|
|
||||||
size = ~size + 1;
|
|
||||||
// XXX: Support 64-bit
|
|
||||||
ASSERT((origValue & 0x06) == 0x00);
|
|
||||||
}
|
|
||||||
|
|
||||||
dev->bars[bar].base = base;
|
|
||||||
dev->bars[bar].size = size;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
264
sys/dev/pci.c
Normal file
264
sys/dev/pci.c
Normal file
@ -0,0 +1,264 @@
|
|||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include <kassert.h>
|
||||||
|
#include <pci.h>
|
||||||
|
|
||||||
|
void PCI_ScanBus();
|
||||||
|
|
||||||
|
void
|
||||||
|
PCI_Init()
|
||||||
|
{
|
||||||
|
kprintf("Initializing PCI\n");
|
||||||
|
PCI_ScanBus();
|
||||||
|
kprintf("PCI Initialization Done\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t
|
||||||
|
PCIGetDeviceID(uint32_t bus, uint32_t device, uint32_t func)
|
||||||
|
{
|
||||||
|
return PCICfgRead16(bus, device, func, PCI_OFFSET_DEVICEID);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t
|
||||||
|
PCIGetVendorID(uint32_t bus, uint32_t device, uint32_t func)
|
||||||
|
{
|
||||||
|
return PCICfgRead16(bus, device, func, PCI_OFFSET_VENDORID);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t
|
||||||
|
PCIGetBaseClass(uint32_t bus, uint32_t device, uint32_t func)
|
||||||
|
{
|
||||||
|
return PCICfgRead8(bus, device, func, PCI_OFFSET_CLASS);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t
|
||||||
|
PCIGetSubClass(uint32_t bus, uint32_t device, uint32_t func)
|
||||||
|
{
|
||||||
|
return PCICfgRead8(bus, device, func, PCI_OFFSET_SUBCLASS);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t
|
||||||
|
PCIGetHeaderType(uint32_t bus, uint32_t device, uint32_t func)
|
||||||
|
{
|
||||||
|
return PCICfgRead8(bus, device, func, PCI_OFFSET_HEADERTYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t
|
||||||
|
PCI_CfgRead8(PCIDevice *dev, uint32_t reg)
|
||||||
|
{
|
||||||
|
return PCICfgRead8(dev->bus, dev->slot, dev->func, reg);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t
|
||||||
|
PCI_CfgRead16(PCIDevice *dev, uint32_t reg)
|
||||||
|
{
|
||||||
|
return PCICfgRead16(dev->bus, dev->slot, dev->func, reg);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
PCI_CfgRead32(PCIDevice *dev, uint32_t reg)
|
||||||
|
{
|
||||||
|
return PCICfgRead32(dev->bus, dev->slot, dev->func, reg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PCI_CfgWrite8(PCIDevice *dev, uint32_t reg, uint8_t data)
|
||||||
|
{
|
||||||
|
return PCICfgWrite8(dev->bus, dev->slot, dev->func, reg, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PCI_CfgWrite16(PCIDevice *dev, uint32_t reg, uint16_t data)
|
||||||
|
{
|
||||||
|
return PCICfgWrite16(dev->bus, dev->slot, dev->func, reg, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PCI_CfgWrite32(PCIDevice *dev, uint32_t reg, uint32_t data)
|
||||||
|
{
|
||||||
|
return PCICfgWrite32(dev->bus, dev->slot, dev->func, reg, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t
|
||||||
|
PCI_GetDeviceID(PCIDevice *dev)
|
||||||
|
{
|
||||||
|
return PCI_CfgRead16(dev, PCI_OFFSET_DEVICEID);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t
|
||||||
|
PCI_GetVendorID(PCIDevice *dev)
|
||||||
|
{
|
||||||
|
return PCI_CfgRead16(dev, PCI_OFFSET_VENDORID);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t
|
||||||
|
PCI_GetBaseClass(PCIDevice *dev)
|
||||||
|
{
|
||||||
|
return PCI_CfgRead8(dev, PCI_OFFSET_CLASS);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t
|
||||||
|
PCI_GetSubClass(PCIDevice *dev)
|
||||||
|
{
|
||||||
|
return PCI_CfgRead8(dev, PCI_OFFSET_SUBCLASS);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t
|
||||||
|
PCI_GetHeaderType(PCIDevice *dev)
|
||||||
|
{
|
||||||
|
return PCI_CfgRead8(dev, PCI_OFFSET_HEADERTYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PCICheckFunction(uint32_t bus, uint32_t device, uint32_t func)
|
||||||
|
{
|
||||||
|
uint8_t baseClass, subClass;
|
||||||
|
uint16_t vendorId, deviceId;
|
||||||
|
|
||||||
|
baseClass = PCIGetBaseClass(bus, device, func);
|
||||||
|
subClass = PCIGetSubClass(bus, device, func);
|
||||||
|
vendorId = PCIGetVendorID(bus, device, func);
|
||||||
|
deviceId = PCIGetDeviceID(bus, device, func);
|
||||||
|
|
||||||
|
if (baseClass == PCI_CLASS_BRIDGE) {
|
||||||
|
if (subClass == PCI_SCLASS_BRIDGE_HOST) {
|
||||||
|
kprintf("PCI(%d,%d,%d): Host Bridge (%04x:%04x)\n",
|
||||||
|
bus, device, func, vendorId, deviceId);
|
||||||
|
} else if (subClass == PCI_SCLASS_BRIDGE_ISA) {
|
||||||
|
kprintf("PCI(%d,%d,%d): ISA Bridge (%04x:%04x)\n",
|
||||||
|
bus, device, func, vendorId, deviceId);
|
||||||
|
} else if (subClass == PCI_SCLASS_BRIDGE_PCI) {
|
||||||
|
kprintf("PCI(%d,%d,%d): PCI-PCI Bridge (%04x:%04x)\n",
|
||||||
|
bus, device, func, vendorId, deviceId);
|
||||||
|
// Scan sub-bus
|
||||||
|
} else if (subClass == PCI_SCLASS_BRIDGE_MISC) {
|
||||||
|
kprintf("PCI(%d,%d,%d): Other Bridge (%04x:%04x)\n",
|
||||||
|
bus, device, func, vendorId, deviceId);
|
||||||
|
}
|
||||||
|
} else if (baseClass == PCI_CLASS_STORAGE) {
|
||||||
|
if (subClass == PCI_SCLASS_STORAGE_SATA) {
|
||||||
|
kprintf("PCI(%d,%d,%d): SATA Controller (%04x:%04x)\n",
|
||||||
|
bus, device, func, vendorId, deviceId);
|
||||||
|
|
||||||
|
AHCI_Init(bus, device, func);
|
||||||
|
} else if (subClass == PCI_SCLASS_STORAGE_IDE) {
|
||||||
|
kprintf("PCI(%d,%d,%d): IDE Controller (%04x:%04x)\n",
|
||||||
|
bus, device, func, vendorId, deviceId);
|
||||||
|
}
|
||||||
|
} else if ((baseClass == PCI_CLASS_NETWORK) && (subClass == 0x00)) {
|
||||||
|
kprintf("PCI(%d,%d,%d): Ethernet (%04x:%04x)\n",
|
||||||
|
bus, device, func, vendorId, deviceId);
|
||||||
|
} else if ((baseClass == PCI_CLASS_GRAPHICS) && (subClass == 0x00)) {
|
||||||
|
kprintf("PCI(%d,%d,%d): VGA (%04x:%04x)\n",
|
||||||
|
bus, device, func, vendorId, deviceId);
|
||||||
|
} else if ((baseClass == PCI_CLASS_BUS) && (subClass == PCI_SCLASS_BUS_SMBUS)) {
|
||||||
|
kprintf("PCI(%d,%d,%d): SMBUS (%04x:%04x)\n",
|
||||||
|
bus, device, func, vendorId, deviceId);
|
||||||
|
} else {
|
||||||
|
kprintf("PCI(%d,%d,%d): Unsupported (%04x:%04x %02x:%02x)\n",
|
||||||
|
bus, device, func, vendorId, deviceId, baseClass, subClass);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PCIScanDevice(uint32_t bus, uint32_t device)
|
||||||
|
{
|
||||||
|
uint8_t headerType;
|
||||||
|
uint16_t vendorId;
|
||||||
|
|
||||||
|
vendorId = PCIGetVendorID(bus, device, 0);
|
||||||
|
if (vendorId == 0xFFFF)
|
||||||
|
return;
|
||||||
|
|
||||||
|
PCICheckFunction(bus, device, 0);
|
||||||
|
|
||||||
|
headerType = PCIGetHeaderType(bus, device, 0);
|
||||||
|
if ((headerType & 0x80) != 0) {
|
||||||
|
uint8_t func;
|
||||||
|
for (func = 0; func < 8; func++) {
|
||||||
|
if (PCIGetVendorID(bus, device, func) != 0xFFFF) {
|
||||||
|
PCICheckFunction(bus, device, func);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PCIScanBus(uint8_t bus)
|
||||||
|
{
|
||||||
|
uint8_t device;
|
||||||
|
|
||||||
|
for (device = 0; device < 32; device++) {
|
||||||
|
PCIScanDevice(bus, device);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PCI_ScanBus()
|
||||||
|
{
|
||||||
|
uint8_t headerType = PCIGetHeaderType(0, 0, 0);
|
||||||
|
|
||||||
|
if ((headerType & 0x80) == 0) {
|
||||||
|
PCIScanBus(0);
|
||||||
|
} else {
|
||||||
|
uint8_t busNo;
|
||||||
|
|
||||||
|
for (busNo = 0; busNo < 8; busNo++) {
|
||||||
|
if (PCIGetVendorID(0, 0, busNo) != 0xFFFF)
|
||||||
|
break;
|
||||||
|
PCIScanBus(busNo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PCI_Configure(PCIDevice *dev)
|
||||||
|
{
|
||||||
|
int bar;
|
||||||
|
|
||||||
|
dev->irq = PCI_CfgRead8(dev, PCI_OFFSET_IRQLINE);
|
||||||
|
|
||||||
|
PCI_CfgWrite16(dev, PCI_OFFSET_COMMAND,
|
||||||
|
PCI_COMMAND_IOENABLE | PCI_COMMAND_MEMENABLE | PCI_COMMAND_BUSMASTER);
|
||||||
|
|
||||||
|
for (bar = 0; bar < PCI_MAX_BARS; bar++)
|
||||||
|
{
|
||||||
|
dev->bars[bar].base = 0;
|
||||||
|
dev->bars[bar].size = 0;
|
||||||
|
dev->bars[bar].type = PCIBAR_TYPE_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (bar = 0; bar < PCI_MAX_BARS; bar++)
|
||||||
|
{
|
||||||
|
uint32_t barReg = PCI_OFFSET_BARFIRST + 4 * bar;
|
||||||
|
uint32_t base, size;
|
||||||
|
uint32_t origValue = PCI_CfgRead32(dev, barReg);
|
||||||
|
|
||||||
|
PCI_CfgWrite32(dev, barReg, 0xFFFFFFFF);
|
||||||
|
size = PCI_CfgRead32(dev, barReg);
|
||||||
|
if (size == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
PCI_CfgWrite32(dev, barReg, origValue);
|
||||||
|
|
||||||
|
if (origValue & 0x1)
|
||||||
|
{
|
||||||
|
dev->bars[bar].type = PCIBAR_TYPE_IO;
|
||||||
|
base = origValue & 0xFFFFFFFC;
|
||||||
|
size = size & 0xFFFFFFFC;
|
||||||
|
size = ~size + 1;
|
||||||
|
} else {
|
||||||
|
dev->bars[bar].type = PCIBAR_TYPE_MEM;
|
||||||
|
base = origValue & 0xFFFFFFF0;
|
||||||
|
size = size & 0xFFFFFFF0;
|
||||||
|
size = ~size + 1;
|
||||||
|
// XXX: Support 64-bit
|
||||||
|
ASSERT((origValue & 0x06) == 0x00);
|
||||||
|
}
|
||||||
|
|
||||||
|
dev->bars[bar].base = base;
|
||||||
|
dev->bars[bar].size = size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user