1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-26 03:37:43 +00:00

Kernel/PCI: Add a bunch of debug output to accessors

This was useful for debugging this issue.
This commit is contained in:
Luke 2020-12-22 04:22:32 +00:00 committed by Andreas Kling
parent 9ab9e548f4
commit 69d7a34bc2
3 changed files with 90 additions and 9 deletions

View file

@ -28,6 +28,8 @@
#include <Kernel/PCI/Access.h> #include <Kernel/PCI/Access.h>
#include <Kernel/PCI/IOAccess.h> #include <Kernel/PCI/IOAccess.h>
//#define PCI_DEBUG
namespace Kernel { namespace Kernel {
namespace PCI { namespace PCI {
@ -73,29 +75,44 @@ PhysicalID Access::get_physical_id(Address address) const
u8 Access::early_read8_field(Address address, u32 field) u8 Access::early_read8_field(Address address, u32 field)
{ {
#ifdef PCI_DEBUG
dbg() << "PCI: Early reading 8-bit field 0x" << String::formatted("{:08x}", field) << " for " << address;
#endif
IO::out32(PCI_ADDRESS_PORT, address.io_address_for_field(field)); IO::out32(PCI_ADDRESS_PORT, address.io_address_for_field(field));
return IO::in8(PCI_VALUE_PORT + (field & 3)); return IO::in8(PCI_VALUE_PORT + (field & 3));
} }
u16 Access::early_read16_field(Address address, u32 field) u16 Access::early_read16_field(Address address, u32 field)
{ {
#ifdef PCI_DEBUG
dbg() << "PCI: Early reading 16-bit field 0x" << String::formatted("{:08x}", field) << " for " << address;
#endif
IO::out32(PCI_ADDRESS_PORT, address.io_address_for_field(field)); IO::out32(PCI_ADDRESS_PORT, address.io_address_for_field(field));
return IO::in16(PCI_VALUE_PORT + (field & 2)); return IO::in16(PCI_VALUE_PORT + (field & 2));
} }
u32 Access::early_read32_field(Address address, u32 field) u32 Access::early_read32_field(Address address, u32 field)
{ {
#ifdef PCI_DEBUG
dbg() << "PCI: Early reading 32-bit field 0x" << String::formatted("{:08x}", field) << " for " << address;
#endif
IO::out32(PCI_ADDRESS_PORT, address.io_address_for_field(field)); IO::out32(PCI_ADDRESS_PORT, address.io_address_for_field(field));
return IO::in32(PCI_VALUE_PORT); return IO::in32(PCI_VALUE_PORT);
} }
u16 Access::early_read_type(Address address) u16 Access::early_read_type(Address address)
{ {
#ifdef PCI_DEBUG
dbg() << "PCI: Early reading type for " << address;
#endif
return (early_read8_field(address, PCI_CLASS) << 8u) | early_read8_field(address, PCI_SUBCLASS); return (early_read8_field(address, PCI_CLASS) << 8u) | early_read8_field(address, PCI_SUBCLASS);
} }
void Access::enumerate_functions(int type, u8 bus, u8 slot, u8 function, Function<void(Address, ID)>& callback) void Access::enumerate_functions(int type, u8 bus, u8 slot, u8 function, Function<void(Address, ID)>& callback)
{ {
#ifdef PCI_DEBUG
dbg() << "PCI: Enumerating function type=" << type << ", bus=" << bus << ", slot=" << slot << ", function=" << function;
#endif
Address address(0, bus, slot, function); Address address(0, bus, slot, function);
if (type == -1 || type == early_read_type(address)) if (type == -1 || type == early_read_type(address))
callback(address, { early_read16_field(address, PCI_VENDOR_ID), early_read16_field(address, PCI_DEVICE_ID) }); callback(address, { early_read16_field(address, PCI_VENDOR_ID), early_read16_field(address, PCI_DEVICE_ID) });
@ -111,6 +128,9 @@ void Access::enumerate_functions(int type, u8 bus, u8 slot, u8 function, Functio
void Access::enumerate_slot(int type, u8 bus, u8 slot, Function<void(Address, ID)>& callback) void Access::enumerate_slot(int type, u8 bus, u8 slot, Function<void(Address, ID)>& callback)
{ {
#ifdef PCI_DEBUG
dbg() << "PCI: Enumerating slot type=" << type << ", bus=" << bus << ", slot=" << slot;
#endif
Address address(0, bus, slot, 0); Address address(0, bus, slot, 0);
if (early_read16_field(address, PCI_VENDOR_ID) == PCI_NONE) if (early_read16_field(address, PCI_VENDOR_ID) == PCI_NONE)
return; return;
@ -126,6 +146,9 @@ void Access::enumerate_slot(int type, u8 bus, u8 slot, Function<void(Address, ID
void Access::enumerate_bus(int type, u8 bus, Function<void(Address, ID)>& callback) void Access::enumerate_bus(int type, u8 bus, Function<void(Address, ID)>& callback)
{ {
#ifdef PCI_DEBUG
dbg() << "PCI: Enumerating bus type=" << type << ", bus=" << bus;
#endif
for (u8 slot = 0; slot < 32; ++slot) for (u8 slot = 0; slot < 32; ++slot)
enumerate_slot(type, bus, slot, callback); enumerate_slot(type, bus, slot, callback);
} }
@ -144,9 +167,18 @@ void enumerate(Function<void(Address, ID)> callback)
Optional<u8> get_capabilities_pointer(Address address) Optional<u8> get_capabilities_pointer(Address address)
{ {
#ifdef PCI_DEBUG
dbg() << "PCI: Getting capabilities pointer for " << address;
#endif
if (PCI::read16(address, PCI_STATUS) & (1 << 4)) { if (PCI::read16(address, PCI_STATUS) & (1 << 4)) {
#ifdef PCI_DEBUG
dbg() << "PCI: Found capabilities pointer for " << address;
#endif
return PCI::read8(address, PCI_CAPABILITIES_POINTER); return PCI::read8(address, PCI_CAPABILITIES_POINTER);
} }
#ifdef PCI_DEBUG
dbg() << "PCI: No capabilities pointer for " << address;
#endif
return {}; return {};
} }
@ -157,12 +189,22 @@ PhysicalID get_physical_id(Address address)
Vector<Capability> get_capabilities(Address address) Vector<Capability> get_capabilities(Address address)
{ {
#ifdef PCI_DEBUG
dbg() << "PCI: Getting capabilities for " << address;
#endif
auto capabilities_pointer = PCI::get_capabilities_pointer(address); auto capabilities_pointer = PCI::get_capabilities_pointer(address);
if (!capabilities_pointer.has_value()) if (!capabilities_pointer.has_value()) {
#ifdef PCI_DEBUG
dbg() << "PCI: No capabilities for " << address;
#endif
return {}; return {};
}
Vector<Capability> capabilities; Vector<Capability> capabilities;
auto capability_pointer = capabilities_pointer.value(); auto capability_pointer = capabilities_pointer.value();
while (capability_pointer != 0) { while (capability_pointer != 0) {
#ifdef PCI_DEBUG
dbg() << "PCI: Reading in capability at 0x" << String::formatted("{:02x}", capability_pointer) << " for " << address;
#endif
u16 capability_header = PCI::read16(address, capability_pointer); u16 capability_header = PCI::read16(address, capability_pointer);
u8 capability_id = capability_header & 0xff; u8 capability_id = capability_header & 0xff;
capability_pointer = capability_header >> 8; capability_pointer = capability_header >> 8;

View file

@ -27,13 +27,19 @@
#include <Kernel/IO.h> #include <Kernel/IO.h>
#include <Kernel/PCI/IOAccess.h> #include <Kernel/PCI/IOAccess.h>
//#define PCI_DEBUG
namespace Kernel { namespace Kernel {
namespace PCI { namespace PCI {
void IOAccess::initialize() void IOAccess::initialize()
{ {
if (!Access::is_initialized()) if (!Access::is_initialized()) {
new IOAccess(); new IOAccess();
#ifdef PCI_DEBUG
dbg() << "PCI: IO access initialised.";
#endif
}
} }
IOAccess::IOAccess() IOAccess::IOAccess()
@ -46,37 +52,58 @@ IOAccess::IOAccess()
u8 IOAccess::read8_field(Address address, u32 field) u8 IOAccess::read8_field(Address address, u32 field)
{ {
#ifdef PCI_DEBUG
dbg() << "PCI: IO Reading 8-bit field 0x" << String::formatted("{:08x}", field) << " for " << address;
#endif
return Access::early_read8_field(address, field); return Access::early_read8_field(address, field);
} }
u16 IOAccess::read16_field(Address address, u32 field) u16 IOAccess::read16_field(Address address, u32 field)
{ {
#ifdef PCI_DEBUG
dbg() << "PCI: IO Reading 16-bit field 0x" << String::formatted("{:08x}", field) << " for " << address;
#endif
return Access::early_read16_field(address, field); return Access::early_read16_field(address, field);
} }
u32 IOAccess::read32_field(Address address, u32 field) u32 IOAccess::read32_field(Address address, u32 field)
{ {
#ifdef PCI_DEBUG
dbg() << "PCI: IO Reading 32-bit field 0x" << String::formatted("{:08x}", field) << " for " << address;
#endif
return Access::early_read32_field(address, field); return Access::early_read32_field(address, field);
} }
void IOAccess::write8_field(Address address, u32 field, u8 value) void IOAccess::write8_field(Address address, u32 field, u8 value)
{ {
#ifdef PCI_DEBUG
dbg() << "PCI: IO Writing to 8-bit field 0x" << String::formatted("{:08x}", field) << ", value=0x" << String::formatted("{:02x}", value) << " for " << address;
#endif
IO::out32(PCI_ADDRESS_PORT, address.io_address_for_field(field)); IO::out32(PCI_ADDRESS_PORT, address.io_address_for_field(field));
IO::out8(PCI_VALUE_PORT + (field & 3), value); IO::out8(PCI_VALUE_PORT + (field & 3), value);
} }
void IOAccess::write16_field(Address address, u32 field, u16 value) void IOAccess::write16_field(Address address, u32 field, u16 value)
{ {
#ifdef PCI_DEBUG
dbg() << "PCI: IO Writing to 16-bit field 0x" << String::formatted("{:08x}", field) << ", value=0x" << String::formatted("{:04x}", value) << " for " << address;
#endif
IO::out32(PCI_ADDRESS_PORT, address.io_address_for_field(field)); IO::out32(PCI_ADDRESS_PORT, address.io_address_for_field(field));
IO::out16(PCI_VALUE_PORT + (field & 2), value); IO::out16(PCI_VALUE_PORT + (field & 2), value);
} }
void IOAccess::write32_field(Address address, u32 field, u32 value) void IOAccess::write32_field(Address address, u32 field, u32 value)
{ {
#ifdef PCI_DEBUG
dbg() << "PCI: IO Writing to 32-bit field 0x" << String::formatted("{:08x}", field) << ", value=0x" << String::formatted("{:08x}", value) << " for " << address;
#endif
IO::out32(PCI_ADDRESS_PORT, address.io_address_for_field(field)); IO::out32(PCI_ADDRESS_PORT, address.io_address_for_field(field));
IO::out32(PCI_VALUE_PORT, value); IO::out32(PCI_VALUE_PORT, value);
} }
void IOAccess::enumerate_hardware(Function<void(Address, ID)> callback) void IOAccess::enumerate_hardware(Function<void(Address, ID)> callback)
{ {
#ifdef PCI_DEBUG
dbg() << "PCI: IO enumerating hardware";
#endif
// Single PCI host controller. // Single PCI host controller.
if ((read8_field(Address(), PCI_HEADER_TYPE) & 0x80) == 0) { if ((read8_field(Address(), PCI_HEADER_TYPE) & 0x80) == 0) {
enumerate_bus(-1, 0, callback); enumerate_bus(-1, 0, callback);

View file

@ -29,6 +29,8 @@
#include <Kernel/PCI/MMIOAccess.h> #include <Kernel/PCI/MMIOAccess.h>
#include <Kernel/VM/MemoryManager.h> #include <Kernel/VM/MemoryManager.h>
//#define PCI_DEBUG
namespace Kernel { namespace Kernel {
namespace PCI { namespace PCI {
@ -80,8 +82,12 @@ uint8_t MMIOAccess::segment_end_bus(u32 seg) const
void MMIOAccess::initialize(PhysicalAddress mcfg) void MMIOAccess::initialize(PhysicalAddress mcfg)
{ {
if (!Access::is_initialized()) if (!Access::is_initialized()) {
new MMIOAccess(mcfg); new MMIOAccess(mcfg);
#ifdef PCI_DEBUG
dbg() << "PCI: MMIO access initialised.";
#endif
}
} }
MMIOAccess::MMIOAccess(PhysicalAddress p_mcfg) MMIOAccess::MMIOAccess(PhysicalAddress p_mcfg)
@ -133,6 +139,9 @@ MMIOAccess::MMIOAccess(PhysicalAddress p_mcfg)
Optional<VirtualAddress> MMIOAccess::get_device_configuration_space(Address address) Optional<VirtualAddress> MMIOAccess::get_device_configuration_space(Address address)
{ {
#ifdef PCI_DEBUG
dbg() << "PCI: Getting device configuration space for " << address;
#endif
for (auto& mapping : m_mapped_device_regions) { for (auto& mapping : m_mapped_device_regions) {
auto checked_address = mapping.address(); auto checked_address = mapping.address();
#ifdef PCI_DEBUG #ifdef PCI_DEBUG
@ -148,6 +157,9 @@ Optional<VirtualAddress> MMIOAccess::get_device_configuration_space(Address addr
return mapping.vaddr(); return mapping.vaddr();
} }
} }
#ifdef PCI_DEBUG
dbg() << "PCI: No device configuration space found for " << address;
#endif
return {}; return {};
} }
@ -156,7 +168,7 @@ u8 MMIOAccess::read8_field(Address address, u32 field)
InterruptDisabler disabler; InterruptDisabler disabler;
ASSERT(field <= 0xfff); ASSERT(field <= 0xfff);
#ifdef PCI_DEBUG #ifdef PCI_DEBUG
dbg() << "PCI: Reading field " << field << ", Address(" << String::format("%w", address.seg()) << ":" << String::format("%b", address.bus()) << ":" << String::format("%b", address.slot()) << "." << String::format("%b", address.function()) << ")"; dbg() << "PCI: MMIO Reading 8-bit field 0x" << String::formatted("{:08x}", field) << " for " << address;
#endif #endif
return *((u8*)(get_device_configuration_space(address).value().get() + (field & 0xfff))); return *((u8*)(get_device_configuration_space(address).value().get() + (field & 0xfff)));
} }
@ -166,7 +178,7 @@ u16 MMIOAccess::read16_field(Address address, u32 field)
InterruptDisabler disabler; InterruptDisabler disabler;
ASSERT(field < 0xfff); ASSERT(field < 0xfff);
#ifdef PCI_DEBUG #ifdef PCI_DEBUG
dbg() << "PCI: Reading field " << field << ", Address(" << String::format("%w", address.seg()) << ":" << String::format("%b", address.bus()) << ":" << String::format("%b", address.slot()) << "." << String::format("%b", address.function()) << ")"; dbg() << "PCI: MMIO Reading 16-bit field 0x" << String::formatted("{:08x}", field) << " for " << address;
#endif #endif
return *((u16*)(get_device_configuration_space(address).value().get() + (field & 0xfff))); return *((u16*)(get_device_configuration_space(address).value().get() + (field & 0xfff)));
} }
@ -176,7 +188,7 @@ u32 MMIOAccess::read32_field(Address address, u32 field)
InterruptDisabler disabler; InterruptDisabler disabler;
ASSERT(field <= 0xffc); ASSERT(field <= 0xffc);
#ifdef PCI_DEBUG #ifdef PCI_DEBUG
dbg() << "PCI: Reading field " << field << ", Address(" << String::format("%w", address.seg()) << ":" << String::format("%b", address.bus()) << ":" << String::format("%b", address.slot()) << "." << String::format("%b", address.function()) << ")"; dbg() << "PCI: MMIO Reading 32-bit field 0x" << String::formatted("{:08x}", field) << " for " << address;
#endif #endif
return *((u32*)(get_device_configuration_space(address).value().get() + (field & 0xfff))); return *((u32*)(get_device_configuration_space(address).value().get() + (field & 0xfff)));
} }
@ -186,7 +198,7 @@ void MMIOAccess::write8_field(Address address, u32 field, u8 value)
InterruptDisabler disabler; InterruptDisabler disabler;
ASSERT(field <= 0xfff); ASSERT(field <= 0xfff);
#ifdef PCI_DEBUG #ifdef PCI_DEBUG
dbg() << "PCI: Writing to field " << field << ", Address(" << String::format("%w", address.seg()) << ":" << String::format("%b", address.bus()) << ":" << String::format("%b", address.slot()) << "." << String::format("%b", address.function()) << ") value 0x" << String::format("%x", value); dbg() << "PCI: MMIO Writing to 8-bit field 0x" << String::formatted("{:08x}", field) << ", value=0x" << String::formatted("{:02x}", value) << " for " << address;
#endif #endif
*((u8*)(get_device_configuration_space(address).value().get() + (field & 0xfff))) = value; *((u8*)(get_device_configuration_space(address).value().get() + (field & 0xfff))) = value;
} }
@ -195,7 +207,7 @@ void MMIOAccess::write16_field(Address address, u32 field, u16 value)
InterruptDisabler disabler; InterruptDisabler disabler;
ASSERT(field < 0xfff); ASSERT(field < 0xfff);
#ifdef PCI_DEBUG #ifdef PCI_DEBUG
dbg() << "PCI: Writing to field " << field << ", Address(" << String::format("%w", address.seg()) << ":" << String::format("%b", address.bus()) << ":" << String::format("%b", address.slot()) << "." << String::format("%b", address.function()) << ") value 0x" << String::format("%x", value); dbg() << "PCI: MMIO Writing to 16-bit field 0x" << String::formatted("{:08x}", field) << ", value=0x" << String::formatted("{:04x}", value) << " for " << address;
#endif #endif
*((u16*)(get_device_configuration_space(address).value().get() + (field & 0xfff))) = value; *((u16*)(get_device_configuration_space(address).value().get() + (field & 0xfff))) = value;
} }
@ -204,7 +216,7 @@ void MMIOAccess::write32_field(Address address, u32 field, u32 value)
InterruptDisabler disabler; InterruptDisabler disabler;
ASSERT(field <= 0xffc); ASSERT(field <= 0xffc);
#ifdef PCI_DEBUG #ifdef PCI_DEBUG
dbg() << "PCI: Writing to field " << field << ", Address(" << String::format("%w", address.seg()) << ":" << String::format("%b", address.bus()) << ":" << String::format("%b", address.slot()) << "." << String::format("%b", address.function()) << ") value 0x" << String::format("%x", value); dbg() << "PCI: MMIO Writing to 32-bit field 0x" << String::formatted("{:08x}", field) << ", value=0x" << String::formatted("{:08x}", value) << " for " << address;
#endif #endif
*((u32*)(get_device_configuration_space(address).value().get() + (field & 0xfff))) = value; *((u32*)(get_device_configuration_space(address).value().get() + (field & 0xfff))) = value;
} }