Decode PCI class codes in device discovery
`pci_device` alone says nothing — an ISA bridge, an AHCI controller, and an xHCI USB
controller are all just `pci_device` by DeviceClass. The identity lives in the 24-bit
class code (base class / subclass / prog-IF) that discovery already recorded in
ids.pci_class but the dump threw away.
New system/devices/pci-class.zig (module `pci-class`): pure reference data from the PCI
spec (per the OSDev PCI table) decoding the triple into names — className, subclassName,
progIfName, plus ClassCode.unpack. No hardware access, so it's shared by kernel
discovery and any future user-space PCI tool. device_tree.dump now prints, under each
PCI function, its class/subclass/prog-IF as both hex and name:
pci0:00:1f.0 [pci_device]
class 0x06 (Bridge) subclass 0x01 (ISA Bridge) progif 0x00
pci0:00:1f.2 [pci_device]
class 0x01 (Mass Storage Controller) subclass 0x06 (Serial ATA Controller) progif 0x01 (AHCI 1.0)
Host test covers the decoder (bridge/AHCI/xHCI, the "Other" 0x80 convention, unknowns).
Suite 41/41 plus host tests.
This commit is contained in:
@@ -13,6 +13,7 @@
|
||||
|
||||
const std = @import("std");
|
||||
const device_abi = @import("device-abi");
|
||||
const pci_class = @import("pci-class");
|
||||
|
||||
/// The hardware primitives a discovery backend needs but can't express portably.
|
||||
/// The kernel injects an implementation (the architecture VMM + port I/O), so the device
|
||||
@@ -195,6 +196,21 @@ fn dumpNode(device: *const Device, depth: usize, emit: *const fn ([]const u8) vo
|
||||
std.fmt.bufPrint(buffer[indent..], "{s} [{s}]\n", .{ device.name(), @tagName(device.class) }) catch return;
|
||||
emit(buffer[0 .. indent + body.len]);
|
||||
|
||||
// For a PCI function, decode its class code — the (class / subclass / prog-IF)
|
||||
// triple that says what it actually is, which the coarse `DeviceClass` can't.
|
||||
if (device.ids.pci_class) |packed_code| {
|
||||
const cc = pci_class.ClassCode.unpack(packed_code);
|
||||
var cbuf: [200]u8 = undefined;
|
||||
const pad = @min(indent + 2, 42);
|
||||
@memset(cbuf[0..pad], ' ');
|
||||
const pif = pci_class.progIfName(cc.base, cc.subclass, cc.prog_if);
|
||||
const cline = if (pif.len != 0)
|
||||
std.fmt.bufPrint(cbuf[pad..], "class 0x{x:0>2} ({s}) subclass 0x{x:0>2} ({s}) progif 0x{x:0>2} ({s})\n", .{ cc.base, pci_class.className(cc.base), cc.subclass, pci_class.subclassName(cc.base, cc.subclass), cc.prog_if, pif }) catch return
|
||||
else
|
||||
std.fmt.bufPrint(cbuf[pad..], "class 0x{x:0>2} ({s}) subclass 0x{x:0>2} ({s}) progif 0x{x:0>2}\n", .{ cc.base, pci_class.className(cc.base), cc.subclass, pci_class.subclassName(cc.base, cc.subclass), cc.prog_if }) catch return;
|
||||
emit(cbuf[0 .. pad + cline.len]);
|
||||
}
|
||||
|
||||
for (device.resources[0..device.resource_count]) |r| {
|
||||
var rbuf: [200]u8 = undefined;
|
||||
const pad = @min(indent + 2, 42);
|
||||
|
||||
Reference in New Issue
Block a user