Add pcilist debug command and bonus cleanup
This commit is contained in:
parent
54e9da89c5
commit
f5eaced208
286
sys/dev/pci.c
286
sys/dev/pci.c
@ -6,18 +6,18 @@
|
||||
#include <sys/kdebug.h>
|
||||
#include <sys/pci.h>
|
||||
|
||||
void PCI_ScanBus();
|
||||
static void PCIScan();
|
||||
|
||||
// Platform functions
|
||||
uint8_t PCICfgRead8(uint32_t bus, uint32_t slot, uint32_t func, uint32_t reg);
|
||||
uint16_t PCICfgRead16(uint32_t bus, uint32_t slot, uint32_t func, uint32_t reg);
|
||||
uint32_t PCICfgRead32(uint32_t bus, uint32_t slot, uint32_t func, uint32_t reg);
|
||||
void PCICfgWrite8(uint32_t bus, uint32_t slot, uint32_t func,
|
||||
uint32_t reg, uint8_t data);
|
||||
uint32_t reg, uint8_t data);
|
||||
void PCICfgWrite16(uint32_t bus, uint32_t slot, uint32_t func,
|
||||
uint32_t reg, uint16_t data);
|
||||
uint32_t reg, uint16_t data);
|
||||
void PCICfgWrite32(uint32_t bus, uint32_t slot, uint32_t func,
|
||||
uint32_t reg, uint32_t data);
|
||||
uint32_t reg, uint32_t data);
|
||||
|
||||
// Supported Devices
|
||||
void AHCI_Init(uint32_t bus, uint32_t device, uint32_t func);
|
||||
@ -27,7 +27,7 @@ void
|
||||
PCI_Init()
|
||||
{
|
||||
kprintf("PCI: Initializing ...\n");
|
||||
PCI_ScanBus();
|
||||
PCIScan();
|
||||
kprintf("PCI: Initialization Done!\n");
|
||||
}
|
||||
|
||||
@ -127,7 +127,12 @@ PCI_GetHeaderType(PCIDevice *dev)
|
||||
return PCI_CfgRead8(dev, PCI_OFFSET_HEADERTYPE);
|
||||
}
|
||||
|
||||
void
|
||||
/*
|
||||
* PCICheckFunction --
|
||||
*
|
||||
* Identify device type and initialize known devices.
|
||||
*/
|
||||
static void
|
||||
PCICheckFunction(uint32_t bus, uint32_t device, uint32_t func)
|
||||
{
|
||||
uint8_t baseClass, subClass;
|
||||
@ -139,47 +144,47 @@ PCICheckFunction(uint32_t bus, uint32_t device, uint32_t 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);
|
||||
}
|
||||
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);
|
||||
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);
|
||||
}
|
||||
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);
|
||||
E1000_Init(bus, device, func);
|
||||
kprintf("PCI: (%d,%d,%d) Ethernet (%04x:%04x)\n",
|
||||
bus, device, func, vendorId, deviceId);
|
||||
E1000_Init(bus, device, func);
|
||||
} else if ((baseClass == PCI_CLASS_GRAPHICS) && (subClass == 0x00)) {
|
||||
kprintf("PCI: (%d,%d,%d) VGA (%04x:%04x)\n",
|
||||
bus, device, func, vendorId, deviceId);
|
||||
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);
|
||||
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);
|
||||
kprintf("PCI: (%d,%d,%d) Unsupported (%04x:%04x %02x:%02x)\n",
|
||||
bus, device, func, vendorId, deviceId, baseClass, subClass);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
PCIScanDevice(uint32_t bus, uint32_t device)
|
||||
{
|
||||
uint8_t headerType;
|
||||
@ -187,49 +192,59 @@ PCIScanDevice(uint32_t bus, uint32_t device)
|
||||
|
||||
vendorId = PCIGetVendorID(bus, device, 0);
|
||||
if (vendorId == 0xFFFF)
|
||||
return;
|
||||
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);
|
||||
}
|
||||
}
|
||||
uint8_t func;
|
||||
for (func = 0; func < 8; func++) {
|
||||
if (PCIGetVendorID(bus, device, func) != 0xFFFF) {
|
||||
PCICheckFunction(bus, device, func);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
PCIScanBus(uint8_t bus)
|
||||
{
|
||||
uint8_t device;
|
||||
|
||||
for (device = 0; device < 32; device++) {
|
||||
PCIScanDevice(bus, device);
|
||||
PCIScanDevice(bus, device);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PCI_ScanBus()
|
||||
/*
|
||||
* PCIScan --
|
||||
*
|
||||
* Scan all busses and devices.
|
||||
*/
|
||||
static void
|
||||
PCIScan()
|
||||
{
|
||||
uint8_t headerType = PCIGetHeaderType(0, 0, 0);
|
||||
|
||||
if ((headerType & 0x80) == 0) {
|
||||
PCIScanBus(0);
|
||||
PCIScanBus(0);
|
||||
} else {
|
||||
uint8_t busNo;
|
||||
uint8_t busNo;
|
||||
|
||||
for (busNo = 0; busNo < 8; busNo++) {
|
||||
if (PCIGetVendorID(0, 0, busNo) != 0xFFFF)
|
||||
break;
|
||||
PCIScanBus(busNo);
|
||||
}
|
||||
for (busNo = 0; busNo < 8; busNo++) {
|
||||
if (PCIGetVendorID(0, 0, busNo) != 0xFFFF)
|
||||
break;
|
||||
PCIScanBus(busNo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* PCI_Configure --
|
||||
*
|
||||
* Configure a PCI device BAR registers.
|
||||
*/
|
||||
void
|
||||
PCI_Configure(PCIDevice *dev)
|
||||
{
|
||||
@ -238,48 +253,143 @@ PCI_Configure(PCIDevice *dev)
|
||||
dev->irq = PCI_CfgRead8(dev, PCI_OFFSET_IRQLINE);
|
||||
|
||||
PCI_CfgWrite16(dev, PCI_OFFSET_COMMAND,
|
||||
PCI_COMMAND_IOENABLE | PCI_COMMAND_MEMENABLE | PCI_COMMAND_BUSMASTER);
|
||||
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;
|
||||
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);
|
||||
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, 0xFFFFFFFF);
|
||||
size = PCI_CfgRead32(dev, barReg);
|
||||
if (size == 0)
|
||||
continue;
|
||||
|
||||
PCI_CfgWrite32(dev, barReg, origValue);
|
||||
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);
|
||||
}
|
||||
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;
|
||||
dev->bars[bar].base = base;
|
||||
dev->bars[bar].size = size;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
DebugPCICheckFunction(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);
|
||||
// XXX: 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);
|
||||
} 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);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
DebugPCIScanBus(uint8_t bus)
|
||||
{
|
||||
uint8_t device;
|
||||
uint8_t headerType;
|
||||
uint16_t vendorId;
|
||||
|
||||
for (device = 0; device < 32; device++) {
|
||||
vendorId = PCIGetVendorID(bus, device, 0);
|
||||
if (vendorId == 0xFFFF)
|
||||
return;
|
||||
|
||||
DebugPCICheckFunction(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) {
|
||||
DebugPCICheckFunction(bus, device, func);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Debug_PCIList(int argc, const char *argv[])
|
||||
{
|
||||
uint8_t headerType = PCIGetHeaderType(0, 0, 0);
|
||||
|
||||
if ((headerType & 0x80) == 0) {
|
||||
DebugPCIScanBus(0);
|
||||
} else {
|
||||
uint8_t busNo;
|
||||
|
||||
for (busNo = 0; busNo < 8; busNo++) {
|
||||
if (PCIGetVendorID(0, 0, busNo) != 0xFFFF)
|
||||
break;
|
||||
DebugPCIScanBus(busNo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
REGISTER_DBGCMD(pcilist, "PCI Device List", Debug_PCIList);
|
||||
|
||||
void
|
||||
Debug_PCIDump(int argc, const char *argv[])
|
||||
{
|
||||
@ -287,8 +397,8 @@ Debug_PCIDump(int argc, const char *argv[])
|
||||
uint32_t bar;
|
||||
|
||||
if (argc != 4) {
|
||||
kprintf("Requires 3 arguments!\n");
|
||||
return;
|
||||
kprintf("Requires 3 arguments!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
bus = Debug_StrToInt(argv[1]);
|
||||
@ -303,9 +413,9 @@ Debug_PCIDump(int argc, const char *argv[])
|
||||
|
||||
for (bar = 0; bar < PCI_MAX_BARS; bar++)
|
||||
{
|
||||
uint32_t barReg = PCI_OFFSET_BARFIRST + 4 * bar;
|
||||
uint32_t barReg = PCI_OFFSET_BARFIRST + 4 * bar;
|
||||
|
||||
kprintf("BAR%d: %016llx\n", bar, PCICfgRead32(bus, device, func, barReg));
|
||||
kprintf("BAR%d: %016llx\n", bar, PCICfgRead32(bus, device, func, barReg));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -67,14 +67,7 @@ typedef struct PCIDevice
|
||||
} PCIDevice;
|
||||
|
||||
void PCI_Init();
|
||||
/*
|
||||
uint8_t PCICfgRead8(uint32_t bus, uint32_t slot, uint32_t func, uint32_t reg);
|
||||
uint16_t PCICfgRead16(uint32_t bus, uint32_t slot, uint32_t func, uint32_t reg);
|
||||
uint32_t PCICfgRead32(uint32_t bus, uint32_t slot, uint32_t func, uint32_t reg);
|
||||
void PCICfgWrite8(uint32_t bus, uint32_t slot, uint32_t func, uint32_t reg, uint8_t data);
|
||||
void PCICfgWrite16(uint32_t bus, uint32_t slot, uint32_t func, uint32_t reg, uint16_t data);
|
||||
void PCICfgWrite32(uint32_t bus, uint32_t slot, uint32_t func, uint32_t reg, uint32_t data);
|
||||
*/
|
||||
|
||||
uint8_t PCI_CfgRead8(PCIDevice *dev, uint32_t reg);
|
||||
uint16_t PCI_CfgRead16(PCIDevice *dev, uint32_t reg);
|
||||
uint32_t PCI_CfgRead32(PCIDevice *dev, uint32_t reg);
|
||||
|
Loading…
Reference in New Issue
Block a user