Add pcilist debug command and bonus cleanup

This commit is contained in:
Ali Mashtizadeh 2022-12-10 01:08:20 -05:00
parent 54e9da89c5
commit f5eaced208
2 changed files with 199 additions and 96 deletions

View File

@ -6,18 +6,18 @@
#include <sys/kdebug.h> #include <sys/kdebug.h>
#include <sys/pci.h> #include <sys/pci.h>
void PCI_ScanBus(); static void PCIScan();
// Platform functions // Platform functions
uint8_t PCICfgRead8(uint32_t bus, uint32_t slot, uint32_t func, uint32_t reg); 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); 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); 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, 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, 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, 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 // Supported Devices
void AHCI_Init(uint32_t bus, uint32_t device, uint32_t func); void AHCI_Init(uint32_t bus, uint32_t device, uint32_t func);
@ -27,7 +27,7 @@ void
PCI_Init() PCI_Init()
{ {
kprintf("PCI: Initializing ...\n"); kprintf("PCI: Initializing ...\n");
PCI_ScanBus(); PCIScan();
kprintf("PCI: Initialization Done!\n"); kprintf("PCI: Initialization Done!\n");
} }
@ -127,7 +127,12 @@ PCI_GetHeaderType(PCIDevice *dev)
return PCI_CfgRead8(dev, PCI_OFFSET_HEADERTYPE); 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) PCICheckFunction(uint32_t bus, uint32_t device, uint32_t func)
{ {
uint8_t baseClass, subClass; uint8_t baseClass, subClass;
@ -139,47 +144,47 @@ PCICheckFunction(uint32_t bus, uint32_t device, uint32_t func)
deviceId = PCIGetDeviceID(bus, device, func); deviceId = PCIGetDeviceID(bus, device, func);
if (baseClass == PCI_CLASS_BRIDGE) { if (baseClass == PCI_CLASS_BRIDGE) {
if (subClass == PCI_SCLASS_BRIDGE_HOST) { if (subClass == PCI_SCLASS_BRIDGE_HOST) {
kprintf("PCI: (%d,%d,%d) Host Bridge (%04x:%04x)\n", kprintf("PCI: (%d,%d,%d) Host Bridge (%04x:%04x)\n",
bus, device, func, vendorId, deviceId); bus, device, func, vendorId, deviceId);
} else if (subClass == PCI_SCLASS_BRIDGE_ISA) { } else if (subClass == PCI_SCLASS_BRIDGE_ISA) {
kprintf("PCI: (%d,%d,%d) ISA Bridge (%04x:%04x)\n", kprintf("PCI: (%d,%d,%d) ISA Bridge (%04x:%04x)\n",
bus, device, func, vendorId, deviceId); bus, device, func, vendorId, deviceId);
} else if (subClass == PCI_SCLASS_BRIDGE_PCI) { } else if (subClass == PCI_SCLASS_BRIDGE_PCI) {
kprintf("PCI: (%d,%d,%d) PCI-PCI Bridge (%04x:%04x)\n", kprintf("PCI: (%d,%d,%d) PCI-PCI Bridge (%04x:%04x)\n",
bus, device, func, vendorId, deviceId); bus, device, func, vendorId, deviceId);
// Scan sub-bus // Scan sub-bus
} else if (subClass == PCI_SCLASS_BRIDGE_MISC) { } else if (subClass == PCI_SCLASS_BRIDGE_MISC) {
kprintf("PCI: (%d,%d,%d) Other Bridge (%04x:%04x)\n", kprintf("PCI: (%d,%d,%d) Other Bridge (%04x:%04x)\n",
bus, device, func, vendorId, deviceId); bus, device, func, vendorId, deviceId);
} }
} else if (baseClass == PCI_CLASS_STORAGE) { } else if (baseClass == PCI_CLASS_STORAGE) {
if (subClass == PCI_SCLASS_STORAGE_SATA) { if (subClass == PCI_SCLASS_STORAGE_SATA) {
kprintf("PCI: (%d,%d,%d) SATA Controller (%04x:%04x)\n", kprintf("PCI: (%d,%d,%d) SATA Controller (%04x:%04x)\n",
bus, device, func, vendorId, deviceId); bus, device, func, vendorId, deviceId);
AHCI_Init(bus, device, func); AHCI_Init(bus, device, func);
} else if (subClass == PCI_SCLASS_STORAGE_IDE) { } else if (subClass == PCI_SCLASS_STORAGE_IDE) {
kprintf("PCI: (%d,%d,%d) IDE Controller (%04x:%04x)\n", kprintf("PCI: (%d,%d,%d) IDE Controller (%04x:%04x)\n",
bus, device, func, vendorId, deviceId); bus, device, func, vendorId, deviceId);
} }
} else if ((baseClass == PCI_CLASS_NETWORK) && (subClass == 0x00)) { } else if ((baseClass == PCI_CLASS_NETWORK) && (subClass == 0x00)) {
kprintf("PCI: (%d,%d,%d) Ethernet (%04x:%04x)\n", kprintf("PCI: (%d,%d,%d) Ethernet (%04x:%04x)\n",
bus, device, func, vendorId, deviceId); bus, device, func, vendorId, deviceId);
E1000_Init(bus, device, func); E1000_Init(bus, device, func);
} else if ((baseClass == PCI_CLASS_GRAPHICS) && (subClass == 0x00)) { } else if ((baseClass == PCI_CLASS_GRAPHICS) && (subClass == 0x00)) {
kprintf("PCI: (%d,%d,%d) VGA (%04x:%04x)\n", kprintf("PCI: (%d,%d,%d) VGA (%04x:%04x)\n",
bus, device, func, vendorId, deviceId); bus, device, func, vendorId, deviceId);
} else if ((baseClass == PCI_CLASS_BUS) && (subClass == PCI_SCLASS_BUS_SMBUS)) { } else if ((baseClass == PCI_CLASS_BUS) && (subClass == PCI_SCLASS_BUS_SMBUS)) {
kprintf("PCI: (%d,%d,%d) SMBUS (%04x:%04x)\n", kprintf("PCI: (%d,%d,%d) SMBUS (%04x:%04x)\n",
bus, device, func, vendorId, deviceId); bus, device, func, vendorId, deviceId);
} else { } else {
kprintf("PCI: (%d,%d,%d) Unsupported (%04x:%04x %02x:%02x)\n", kprintf("PCI: (%d,%d,%d) Unsupported (%04x:%04x %02x:%02x)\n",
bus, device, func, vendorId, deviceId, baseClass, subClass); bus, device, func, vendorId, deviceId, baseClass, subClass);
} }
} }
void static void
PCIScanDevice(uint32_t bus, uint32_t device) PCIScanDevice(uint32_t bus, uint32_t device)
{ {
uint8_t headerType; uint8_t headerType;
@ -187,49 +192,59 @@ PCIScanDevice(uint32_t bus, uint32_t device)
vendorId = PCIGetVendorID(bus, device, 0); vendorId = PCIGetVendorID(bus, device, 0);
if (vendorId == 0xFFFF) if (vendorId == 0xFFFF)
return; return;
PCICheckFunction(bus, device, 0); PCICheckFunction(bus, device, 0);
headerType = PCIGetHeaderType(bus, device, 0); headerType = PCIGetHeaderType(bus, device, 0);
if ((headerType & 0x80) != 0) { if ((headerType & 0x80) != 0) {
uint8_t func; uint8_t func;
for (func = 0; func < 8; func++) { for (func = 0; func < 8; func++) {
if (PCIGetVendorID(bus, device, func) != 0xFFFF) { if (PCIGetVendorID(bus, device, func) != 0xFFFF) {
PCICheckFunction(bus, device, func); PCICheckFunction(bus, device, func);
} }
} }
} }
} }
void static void
PCIScanBus(uint8_t bus) PCIScanBus(uint8_t bus)
{ {
uint8_t device; uint8_t device;
for (device = 0; device < 32; 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); uint8_t headerType = PCIGetHeaderType(0, 0, 0);
if ((headerType & 0x80) == 0) { if ((headerType & 0x80) == 0) {
PCIScanBus(0); PCIScanBus(0);
} else { } else {
uint8_t busNo; uint8_t busNo;
for (busNo = 0; busNo < 8; busNo++) { for (busNo = 0; busNo < 8; busNo++) {
if (PCIGetVendorID(0, 0, busNo) != 0xFFFF) if (PCIGetVendorID(0, 0, busNo) != 0xFFFF)
break; break;
PCIScanBus(busNo); PCIScanBus(busNo);
} }
} }
} }
/*
* PCI_Configure --
*
* Configure a PCI device BAR registers.
*/
void void
PCI_Configure(PCIDevice *dev) PCI_Configure(PCIDevice *dev)
{ {
@ -238,48 +253,143 @@ PCI_Configure(PCIDevice *dev)
dev->irq = PCI_CfgRead8(dev, PCI_OFFSET_IRQLINE); dev->irq = PCI_CfgRead8(dev, PCI_OFFSET_IRQLINE);
PCI_CfgWrite16(dev, PCI_OFFSET_COMMAND, 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++) for (bar = 0; bar < PCI_MAX_BARS; bar++)
{ {
dev->bars[bar].base = 0; dev->bars[bar].base = 0;
dev->bars[bar].size = 0; dev->bars[bar].size = 0;
dev->bars[bar].type = PCIBAR_TYPE_NULL; dev->bars[bar].type = PCIBAR_TYPE_NULL;
} }
for (bar = 0; bar < PCI_MAX_BARS; bar++) for (bar = 0; bar < PCI_MAX_BARS; bar++)
{ {
uint32_t barReg = PCI_OFFSET_BARFIRST + 4 * bar; uint32_t barReg = PCI_OFFSET_BARFIRST + 4 * bar;
uint32_t base, size; uint32_t base, size;
uint32_t origValue = PCI_CfgRead32(dev, barReg); uint32_t origValue = PCI_CfgRead32(dev, barReg);
PCI_CfgWrite32(dev, barReg, 0xFFFFFFFF); PCI_CfgWrite32(dev, barReg, 0xFFFFFFFF);
size = PCI_CfgRead32(dev, barReg); size = PCI_CfgRead32(dev, barReg);
if (size == 0) if (size == 0)
continue; continue;
PCI_CfgWrite32(dev, barReg, origValue); PCI_CfgWrite32(dev, barReg, origValue);
if (origValue & 0x1) if (origValue & 0x1)
{ {
dev->bars[bar].type = PCIBAR_TYPE_IO; dev->bars[bar].type = PCIBAR_TYPE_IO;
base = origValue & 0xFFFFFFFC; base = origValue & 0xFFFFFFFC;
size = size & 0xFFFFFFFC; size = size & 0xFFFFFFFC;
size = ~size + 1; size = ~size + 1;
} else { } else {
dev->bars[bar].type = PCIBAR_TYPE_MEM; dev->bars[bar].type = PCIBAR_TYPE_MEM;
base = origValue & 0xFFFFFFF0; base = origValue & 0xFFFFFFF0;
size = size & 0xFFFFFFF0; size = size & 0xFFFFFFF0;
size = ~size + 1; size = ~size + 1;
// XXX: Support 64-bit // XXX: Support 64-bit
ASSERT((origValue & 0x06) == 0x00); ASSERT((origValue & 0x06) == 0x00);
} }
dev->bars[bar].base = base; dev->bars[bar].base = base;
dev->bars[bar].size = size; 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 void
Debug_PCIDump(int argc, const char *argv[]) Debug_PCIDump(int argc, const char *argv[])
{ {
@ -287,8 +397,8 @@ Debug_PCIDump(int argc, const char *argv[])
uint32_t bar; uint32_t bar;
if (argc != 4) { if (argc != 4) {
kprintf("Requires 3 arguments!\n"); kprintf("Requires 3 arguments!\n");
return; return;
} }
bus = Debug_StrToInt(argv[1]); bus = Debug_StrToInt(argv[1]);
@ -303,9 +413,9 @@ Debug_PCIDump(int argc, const char *argv[])
for (bar = 0; bar < PCI_MAX_BARS; bar++) 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));
} }
} }

View File

@ -67,14 +67,7 @@ typedef struct PCIDevice
} PCIDevice; } PCIDevice;
void PCI_Init(); 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); uint8_t PCI_CfgRead8(PCIDevice *dev, uint32_t reg);
uint16_t PCI_CfgRead16(PCIDevice *dev, uint32_t reg); uint16_t PCI_CfgRead16(PCIDevice *dev, uint32_t reg);
uint32_t PCI_CfgRead32(PCIDevice *dev, uint32_t reg); uint32_t PCI_CfgRead32(PCIDevice *dev, uint32_t reg);