M15: interrupts for PCI devices (ECAM config space + MSI)
Two parts, both blockers for real PCI drivers. ECAM config space per function: enumeratePci now gives every pci_device its own 4 KiB configuration window as resource 0. A claimed PCI driver mmio_maps that to reach its command register, BARs, and — the point — its capability list (MSI/MSI-X, PCIe extended caps), with no new syscall. Verified in the discovery test (QEMU q35's functions each carry it). MSI: msi_bind(device_id, endpoint) -> address (rax), data (rdx) allocates a per-device edge-triggered vector, binds it to the endpoint, and returns the (address, data) the driver programs into its own MSI capability. Unlike irq_bind there's no GSI, no I/O APIC entry, no sharing, and no ack cycle — dispatch recognises an MSI vector (vector_gsi == none, msi_bound set), EOIs, and notifies. Owner-keyed release drops the binding on exit. Legacy INTx (_PRT parsing + shared lines) is deliberately skipped; MSI is the real answer. QEMU's HPET has no MSI, so the new `msi` test proves the vector-routing path with a self-IPI (new apic.selfIpi) standing in for the device's MSI write: bind a vector, fire it, the bound endpoint is notified. The msi_bind syscall wraps irq.msiBind with the claim check and lands its first real use with the first PCI driver. Suite 39/39 plus host tests.
This commit is contained in:
@@ -564,6 +564,15 @@ fn enumeratePci(
|
||||
bridge.name(), bus, device, function,
|
||||
}) catch "pcidev";
|
||||
const node = try device_tree.addChild(bridge, .pci_device, nm);
|
||||
// Resource 0 is the function's own 4 KiB ECAM configuration space. A
|
||||
// claimed PCI driver mmio_maps this to reach its command register,
|
||||
// BARs, and — the point — its capability list (MSI/MSI-X, PCIe
|
||||
// extended caps), without any new syscall. Physical address per the
|
||||
// ECAM formula (same as pciConfigurationPtr).
|
||||
const config_physical = alloc.base_address +
|
||||
(@as(u64, @as(u8, @intCast(bus)) - alloc.start_bus) << 20) +
|
||||
(@as(u64, device) << 15) + (@as(u64, function) << 12);
|
||||
_ = node.addResource(.memory, config_physical, abi.page_size);
|
||||
node.ids.pci_vendor = h.vendor_id;
|
||||
node.ids.pci_device = h.device_id;
|
||||
node.ids.pci_class = (@as(u24, h.class_code) << 16) |
|
||||
|
||||
Reference in New Issue
Block a user