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:
+13
-1
@@ -145,6 +145,13 @@ If a class driver needs `mmio`, it has become an HCD and should be one.
|
||||
`dma_below_4g` caps the address for legacy engines; `dma_write_combining` is accepted
|
||||
but falls back to coherent until PAT is programmed. hpet is refactored onto `/lib/mmio`;
|
||||
no DMA driver consumes `dma_alloc` yet.
|
||||
- **M15** — interrupts for PCI devices, the MSI half. Discovery now gives every PCI
|
||||
function its 4 KiB ECAM config space as resource 0 (unblocking the capability walk
|
||||
with no new syscall), and `msi_bind(device_id, endpoint) -> address, data` allocates a
|
||||
per-device edge-triggered vector, delivered as an IPC notification with no mask and no
|
||||
ack cycle. Legacy INTx (`_PRT` parsing + shared lines) is deliberately skipped — MSI
|
||||
is the real answer. QEMU's HPET has no MSI, so delivery is proven with a self-IPI; the
|
||||
first PCI driver is the first real consumer.
|
||||
- **`system_spawn`** — a user-space supervisor starts a driver: `system_spawn(name)`
|
||||
loads a binary bundled in the initial-ramdisk as a fresh ring-3 process. This is what
|
||||
turned the device manager from "log the match" into "run the driver": the kernel now
|
||||
@@ -271,7 +278,12 @@ condition. Build the abstraction while there is one caller to fix.
|
||||
(Zig note: `@fence` was **removed in 0.16**. Use `@atomicRmw(..., .seq_cst)` for a full
|
||||
barrier, or per-arch inline asm — which is what `library/mmio.zig` should hide.)
|
||||
|
||||
## M15 — interrupts for PCI devices
|
||||
## M15 — interrupts for PCI devices ✅ done (MSI)
|
||||
|
||||
*Implemented the MSI half: ECAM config space per PCI function (resource 0) and
|
||||
`msi_bind` (per-device edge-triggered vector, delivered as a notification). Legacy INTx
|
||||
`_PRT` parsing is skipped on purpose. `msi_bind` returns (address, data) as two values
|
||||
rather than an out-struct. The rest of this section is the original design note.*
|
||||
|
||||
**The blocker, and it's a hard one.** No PCI device can take an interrupt today.
|
||||
[`addBars`](system/devices/acpi.zig) records `.memory` and `.io_port` BARs and never an
|
||||
|
||||
Reference in New Issue
Block a user