Cross-referenced every stub/gap claim in v1.0 against actual code and Linux 7.1 reference (local/reference/linux-7.1/). Four parallel audits. Key corrections to v1.0: - kernel/src/arch/x86_shared/sleep.rs:257-276 does NOT exist; real PCI stubs are in acpid/aml_physmem.rs:375-398 (root cause: pcid never sends fd to acpid) - EHCI is ALREADY implemented (1538+ lines); the stubs are OHCI and UHCI - aml_physmem.rs:195, :274 line numbers were wrong; actual stubs at :213-232 (map_physical_region panic) and :241-280 (read returns 0) - MSI stub at irq.rs:231 was fixed 2026-06-08 (this audit's first task) New gaps added (v1.1): - Gap 11: IOMMU daemon->kernel IRQ integration missing (kernel has set_iommu_remapping_active() but daemon never calls it) - Gap 12: MSI multi-vector not exposed (blocks xhcid, nvmed, ixgbed, redox-drm) Other corrections: - DMAR init should move to iommu daemon, not acpid - >255 CPU ID is a panic (u8::try_from().expect()), not deferred - hwd legacy backend stub is acceptable (graceful no-op fallback) Added new sections: - Section 13: Concrete Fix List (v1.1, ready to execute) with exact file paths, line numbers, current code, target code, Linux reference - Section 14: v1.1 Audit Methodology documenting the cross-reference approach All execution plan phases updated with corrected tasks, owners, and verification gates.
58 KiB
Red Bear OS — Low-Level Infrastructure Reassessment & Updated Plan
Version: 1.1 (2026-06-08) — comprehensive code audit against Linux 7.1 reference
Supersedes: Fragmentary assessments in COMPREHENSIVE-SYSTEM-ASSESSMENT-AND-IMPROVEMENT-PLAN.md §2–§4 for ACPI/IRQ/PCI/driver topics
Canonical adjacent plans (remain authoritative for subsystem detail):
ACPI-IMPROVEMENT-PLAN.md— ACPI waves W0–W7IRQ-AND-LOWLEVEL-CONTROLLERS-ENHANCEMENT-PLAN.md— PCI/IRQ/MSI-X waves W1–W6BOOT-PROCESS-HARDWARE-DETECTION-PLAN.md— Boot detection waves W0–W6SMP-SCHEDULER-IMPROVEMENT-PLAN.md— SMP bottlenecks B1–B7local/reference/linux-7.1/— Linux 7.1 reference source for cross-validation
1. Executive Summary
This document is a code-grounded reassessment of four interdependent low-level subsystems: ACPI/acpid, IRQ/PCI, enumeration/driver binding, and driver infrastructure. It is based on direct source inspection (file paths and line numbers provided throughout), cross-referenced against existing plans.
Bottom-line verdict
| Subsystem | Verdict | Blocking Bare Metal? |
|---|---|---|
| ACPI boot | Boot-baseline complete, not release-grade | Partial — shutdown timing fragile |
| ACPI shutdown | S5 derivation works, timing-dependent on PCI | Yes — pre-PCI shutdown degrades weakly |
| ACPI thermal/fan | Discovery exists, no runtime backend | No — thermal safety gap |
| ACPI C-states | Discovery exists, no kernel cpuidle | Yes — root cause of heat |
| IRQ delivery | Architecturally strong, QEMU-proven only | Partial — no HW validation |
| MSI/MSI-X | Code complete, IOMMU validation stubbed | Yes — iommu_validate_msi_irq() returns true |
| PCI enumeration | Userspace-only (correct), pcid complete | No |
| Driver binding | Manual class-code matching, no ACPI _HID/_CID | Partial — limited device coverage |
| redox-driver-sys | Production quality, zero stubs | No |
| linux-kpi | Verified real for Wi-Fi: 2770 lines Rust impl, no stubs | No |
| GPU drivers | Compile-only, synthetic EDID everywhere | Yes — no real display detection |
| Wi-Fi | Compile+host-test only, linux-kpi wireless layer verified real | Yes — no HW validation; linux-kpi headers/impl sufficient for driver compilation |
| USB | xhcid only, no EHCI/UHCI/OHCI | Yes — legacy USB keyboards unreachable |
What changed since last assessment (2026-05-20)
- Critical stub discovered:
iommu_validate_msi_irq()atkernel/src/scheme/irq.rs:231unconditionally returnstrue— this was not flagged as a blocking item in the IRQ enhancement plan (all 6 waves marked "complete"). - Critical stub discovered:
aml_physmem.rs:195and:274fabricate zero values on physical memory access failure — affects all AML runtime evaluation. - Dual AML interpreter architecture identified as a maintenance risk — kernel
acpi_extcrate and userspaceacpicrate parse DSDT/SSDT independently. - APIC timer disabled (
local_apic.rs:81) — not flagged in any existing plan as a blocker. - Synthetic EDID used in all GPU drivers — blocks real display detection on bare metal.
- 40 total TODOs in ACPI code (16 kernel + 24 userspace) — higher than previously documented.
- linux-kpi wireless layer verified real (2026-06-08): Comprehensive code audit confirmed all Wi-Fi headers (
cfg80211.h,mac80211.h,netdevice.h,skbuff.h) are real implementations backed by 2770 lines of Rust code (wireless.rs1002 lines,mac80211.rs959 lines,net.rs809 lines). No TODO/FIXME/STUB markers found in wireless code. Theamdgpu_stubs.hstub file is GPU-specific and does not affect Wi-Fi.
What changed in v1.1 (2026-06-08) — Linux 7.1 cross-reference audit
-
kernel/src/arch/x86_shared/sleep.rs:257–276does not exist: The kernel has nosleep.rsfile. The sleep path is entirely in userspace (acpid). The actual PCI config access stubs are inacpid/src/aml_physmem.rs:375–398(read_pci_u8/u16/u32, write_pci_u8/u16/u32) wherepci_fdis alwaysNonebecausepcidnever sends its fd toacpid. The fix is to wire pcid's fd to acpid via theRegisterPcischeme handle, not to modify a non-existent kernel file. -
EHCI is already implemented (2026-06-08):
local/recipes/drivers/ehcid/source/src/main.rsis 1538+ lines with full EHCI spec implementation (device enumeration, control/bulk/interrupt transfers, DMA, port reset). The plan's "no EHCI driver" gap was inaccurate. The actual stubs are OHCI (ohcid/source/src/main.rs:16–34, ~19 lines) and UHCI (uhcid/source/src/main.rs:16–34, ~19 lines) — both just log BAR reads and enter a sleep loop with no enumeration, no transfers, no port management. -
MSI/MSI-X stub FIXED (2026-06-08): The
iommu_validate_msi_irq()blindtruereturn atkernel/src/scheme/irq.rs:231was replaced with proper IOMMU remapping state tracking. Now usesIOMMU_REMAPPING_ACTIVE: AtomicBool+ publicset_iommu_remapping_active()API. The kernel trusts the IOMMU hardware (when active) to validate interrupt remapping. The daemon→kernel coordination is not yet wired (Gap 11). -
IOMMU daemon→kernel IRQ integration missing (2026-06-08): The kernel now has
set_iommu_remapping_active()but theiommudaemon never calls it. The MSI validation gate works correctly once the daemon writes to a new/scheme/irq/remappingfile. Spec: kernel addsHandle::RemappingControl+ write handler; daemon writes"1"afterINIT_UNITSsucceeds and IRTE tables are set up. -
MSI multi-vector allocation is a real blocker (2026-06-08):
pci_allocate_interrupt_vectorinpcid/src/driver_interface/irq_helpers.rs:307only allocates single vectors. xhcid (USB 3.0), nvmed (NVMe), ixgbed (10GbE), and redox-drm (GPU) all need multiple vectors.allocate_aligned_interrupt_vectorsalready supportscountparameter; the fix is to expose it.multi_message_enablefield in MSI capability is always set toSome(0)(single vector). -
>255 CPU truncation is a panic (2026-06-08):
irq_helpers.rs:89u8::try_from(cpu_id).expect("usize cpu ids not implemented yet")panics for CPU IDs > 255. Must be converted toio::Errorreturn. The x2APIC path supports 32-bit APIC IDs. Not a blocker for current hardware (AMD Threadripper 128-thread = 128 CPUs) but must be fixed before >256 CPU systems are tested. -
DMAR init should move to iommu daemon (2026-06-08): The 533 lines of Intel VT-d parsing in
acpid/src/acpi/dmar/mod.rs(Dmar::init()at line 55) only log register values without initializing hardware. Theacpi.rs:545call is commented out. Per microkernel design, DMAR init belongs in theiommudaemon, not acpid. Linux 7.1 reference:drivers/iommu/intel/dmar.c(intel-iommu init pattern). -
APIC timer disabled confirmed (2026-06-08):
local_apic.rs:81//self.setup_timer();—setup_timer()method does not exist despite the call being commented out. All timer infrastructure (LVT timer, divider config, count registers) is present but unconnected. Re-enabling requires: implementsetup_timer()(TSC deadline mode for modern CPUs, periodic with divide-by-16 fallback), add PM-timer/TSC-based calibration, wire into init sequence. Safe on QEMU; needs calibration on bare metal.
2. ACPI / acpid Reassessment
2.1 Architecture
The ACPI subsystem has three operational levels:
Bootloader → KernelArgs.hwdesc_base (RSDP pointer)
│
▼
Kernel ACPI (src/acpi/ + src/scheme/acpi.rs + src/arch/x86_shared/sleep.rs)
├── RSDP→RSDT/XSDT→SDT enumeration (MADT, SRAT, SLIT, HPET)
├── Export via /scheme/kernel.acpi/{rxsdt, kstop, sleep}
└── Kernel-side AML interpreter (acpi_ext crate) for S3/S5 sleep
│
▼
Userspace acpid (drivers/acpid/src/)
├── Reads rxsdt, loads SDTs from physical memory
├── Userspace AML interpreter (acpi crate) — SEPARATE from kernel's
├── Exports /scheme/acpi/{dmi, tables, symbols, thermal, fan, cstates}
└── Shutdown via kstop pipe + PM1a/PM1b write
2.2 What Is Working
| Component | File | Evidence |
|---|---|---|
| RSDP discovery + dual checksum | acpi/rsdp.rs |
ACPI 1.0 + 2.0+ validation, 62 lines |
| MADT parsing (10 entry types) | acpi/madt/mod.rs |
Types 0x0–0xA + aarch64 GICC/GICD, 340 lines |
| x2APIC support | acpi/madt/mod.rs |
Types 0x9/0xA, P20–P22 patches |
| IOAPIC init from MADT | device/ioapic.rs |
GSI resolution, source overrides, affinity, 502 lines |
| LAPIC/x2APIC | device/local_apic.rs |
MSR + MMIO dual path, 312 lines |
| SRAT/SLIT NUMA | acpi/srat.rs, acpi/slit.rs |
Affinity + distance matrix |
| HPET timer | acpi/hpet.rs |
Init from ACPI tables |
| Kernel scheme export | scheme/acpi.rs |
rxsdt, kstop, sleep — 398 lines |
| acpid SDT loading | acpid/src/acpi.rs:162–217 |
Page-span handling, PhysmapGuard |
| acpid FADT parsing | acpid/src/acpi.rs:965–1122 |
ACPI 2.0 extended fields |
| acpid EC handler | acpid/src/ec.rs |
Full protocol (RD_EC/WR_EC/BE_EC/BD_EC/QR_EC), 317 lines |
| acpid S5 derivation | acpid/src/acpi.rs:754–813 |
FADT + AML __S5, cached |
| acpid DMI | acpid/src/dmi.rs |
SMBIOS 32/64-bit entry points, 350 lines |
| acpid thermal/fan/cstate discovery | thermal.rs, fan.rs, cstate.rs |
AML-backed __TZ, __PR namespace |
| hwd ACPI backend | hwd/backend/acpi.rs |
__CID/__HID device discovery, 119 lines |
2.3 Critical Stubs
| Location | Line | Issue | Severity |
|---|---|---|---|
acpid/src/aml_physmem.rs |
195 | read_phys_or_fault() returns T::zero() on failure — fabricates data |
🔴 CRITICAL |
acpid/src/aml_physmem.rs |
274 | map_physical_region() falls back to zero page on failure — writes lost |
🔴 CRITICAL |
kernel/src/arch/x86_shared/sleep.rs |
257–276 | read_pci_u8/u16/u32 always return 0; write_pci_* are no-ops |
🔴 CRITICAL |
kernel/src/arch/x86_shared/sleep.rs |
275 | nanos_since_boot() returns 0 — broken AML timing |
🟠 HIGH |
kernel/src/arch/x86_shared/sleep.rs |
294–298 | acquire()/release() for AML mutexes are no-ops |
🟠 HIGH |
acpid/src/acpi.rs |
545 | Dmar::init(&this) commented out — "TODO (hangs on real hardware)" |
🟠 HIGH |
hwd/backend/legacy.rs |
13 | LegacyBackend::probe() is a TODO no-op |
🟠 HIGH |
acpid/src/acpi.rs |
820–822 | set_global_s_state(state) returns Ok for any state != 5 |
🟡 MEDIUM |
2.4 Architectural Risks
- Dual AML interpreters: Kernel
sleep.rsusesacpi_extcrate; userspaceacpidusesacpicrate. They parse the same DSDT/SSDT independently with different handler implementations. Bug fixes in one do not affect the other. - RSDP_ADDR contract: acpid AML init requires
RSDP_ADDRenvironment variable (fromhwdviaKernelArgs.hwdesc_base). x86 has BIOS fallback; non-x86 paths are unresolved. - S5 derivation timing: Depends on AML readiness which depends on PCI registration. Pre-PCI shutdown falls back gracefully but the degraded contract is weak.
- DMAR orphaned: 533 lines of Intel VT-d parsing code exist but are not wired into startup.
2.5 TODO Inventory
- Kernel ACPI: 16 TODOs (
madtarch variants,hpetx86 assumption,spcrtype support,scheme/acpicontext switch,gtdt) - Userspace acpid: 24 TODOs (
acpi.rs: 10,dmar/: 9,main.rs: 3,scheme.rs: 1,aml_physmem.rs: 1) - Total: 40 TODOs
2.6 Alignment with ACPI-IMPROVEMENT-PLAN.md
| Wave | Plan Status | Code Reality | Delta |
|---|---|---|---|
| W0 Contracts | ~80% | Truth statement accurate | — |
| W1 Startup hardening | ~60% | P19 patch removed panic-grade expects; remaining expect() in firmware-origin paths |
Underdocumented |
| W2 AML ordering/shutdown | ~50% | S5 derivation improved (P24); explicit error types exist; timing still coupled to PCI | Underdocumented |
| W3 Honest power surface | Open | Battery/AC probing exists but not trustworthy; thermal/fan discovery real but no backend action | — |
| W4 Physmem/EC/fault handling | ~40% | Two critical stubs at lines 195, 274 not flagged in plan | New finding |
| W5 Ownership cleanup | Open | DMAR still orphaned; dual interpreters unresolved | — |
| W6 Consumer integration | ~60% | kstop→sessiond path works | — |
| W7 Validation closure | Open | No bare-metal validation matrix executed | — |
3. IRQ / PCI Reassessment
3.1 Architecture
PCI Device → MSI/MSI-X message (address 0xFEE0_0xxx + data)
│
▼
APIC (local or I/O) → Vector delivery to target CPU
│
▼
Kernel IDT → generic_irq handler (vec 32–255)
│
▼
scheme/irq.rs → irq_trigger(irq, token)
├── iommu_validate_msi_irq(irq) ← STUB: returns true unconditionally
├── increment COUNTS[irq]
├── walk HANDLES for matching fd
└── trigger EVENT_READ
│
▼
Userspace driver → IrqHandle::wait() returns with count
3.2 What Is Working
| Component | File | Evidence |
|---|---|---|
| IDT (256 entries) | arch/x86_shared/idt.rs |
224 generic vectors, legacy IRQ bindings, IPI handlers, 374 lines |
| 8259 PIC | arch/x86_shared/device/pic.rs |
Master/slave init, mask, ack, ISR query, 98 lines |
| I/O APIC | arch/x86_shared/device/ioapic.rs |
MADT-parsed, GSI resolution, affinity reprogramming, 502 lines |
| LAPIC/x2APIC | arch/x86_shared/device/local_apic.rs |
MMIO + MSR dual path, IPI, EOI, ESR, 312 lines |
| IRQ dispatch | arch/x86_shared/interrupt/irq.rs |
PIC/APIC switching, spurious accounting, 352 lines |
| IRQ scheme | scheme/irq.rs |
Registration, delivery, affinity, per-CPU listing, 650 lines |
| MSI kernel code | arch/x86_shared/device/msi.rs |
Message composition, validation, capability parsing, 183 lines |
| Vector allocator | arch/x86_shared/device/vector.rs |
CAS bitmap for 224 vectors, 53 lines |
| redox-driver-sys IRQ | redox-driver-sys/src/irq.rs |
MSI-X table mapping, vector allocation, affinity, 491 lines, zero TODOs |
| redox-driver-sys PCI | redox-driver-sys/src/pci.rs |
Config space, BAR probing, MSI-X enable, 1446 lines, zero TODOs |
| pcid daemon | drivers/pcid/src/ |
Enumeration, scheme:pci, driver spawn, ~1400 lines total |
| driver-manager | driver-manager/src/main.rs |
PciBus + AcpiBus binding, boot timeline, 553 lines |
3.3 Critical Stubs
| Location | Line | Issue | Severity |
|---|---|---|---|
kernel/src/scheme/irq.rs |
231 | iommu_validate_msi_irq(_irq) -> bool { true } — zero IOMMU validation |
🔴 CRITICAL |
kernel/src/arch/x86_shared/device/local_apic.rs |
81 | //self.setup_timer(); — APIC timer disabled |
🟠 HIGH |
kernel/src/arch/x86_shared/interrupt/irq.rs |
307 | println!("Local apic timer interrupt"); — debug artifact |
🟡 MEDIUM |
kernel/src/arch/x86_shared/device/ioapic.rs |
329–331 | .unwrap() on cpuid — panic risk |
🟡 MEDIUM |
drivers/pcid/src/driver_interface/irq_helpers.rs |
— | "FIXME for cpu_id >255 need IOMMU IRQ remapping" | 🟠 HIGH |
drivers/pcid/src/driver_interface/irq_helpers.rs |
— | "FIXME allow allocating multiple interrupt vectors" | 🟠 HIGH |
3.4 Patch-Backed Code
The following kernel code does not exist in upstream — it is entirely Red Bear patches:
msi.rs(+183 lines) — added byP8-msi.patch(281 lines, 12 hunks)vector.rs(+53 lines) — added byP8-msi.patch- IOAPIC affinity —
P9-ioapic-irq-affinity.patch - IRQ affinity wiring —
P10-irq-affinity-wiring.patch - x2APIC ICR fix —
P20-x2apic-icr-mode-fix.patch - x2APIC SMP fix —
P21-x2apic-smp-fix.patch - x2APIC MADT fallback —
P22-x2apic-madt-fallback.patch
Risk: If upstream kernel rebases, these patches must be rebased. The MSI/MSI-X subsystem is entirely patch-dependent.
3.5 Alignment with IRQ Enhancement Plan
The plan reports all 6 Waves as ✅ Complete. Code inspection confirms the Waves addressed panic hardening and code quality. However, 6 priority areas remain entirely open and the plan does not flag:
iommu_validate_msi_irq()stub (CRITICAL — not mentioned)- APIC timer disabled (not mentioned)
- Single-vector-per-device limit (mentioned as FIXME but not prioritized)
4. Enumeration / Driver Binding Reassessment
4.1 Current Flow
pcid enumerates PCI bus → /scheme/pci/{segment}--{bus}--{device}.{function}/
│
▼
driver-manager (or pcid-spawner legacy) reads /scheme/pci/
│
▼
For each device: query config space (vendor, device, class, subclass)
│
▼
Match against driver config (PCI class/vendor/device ID lookup)
│
▼
Spawn driver daemon with PCID_CLIENT_CHANNEL env var
│
▼
Driver opens /scheme/pci/{addr}/config and /scheme/irq/{irq}
4.2 Limitations
- No ACPI _HID/_CID matching: Non-PCI devices (ACPI-enumerated GPIO, I2C, etc.) are not bound through the driver-manager.
- No modalias generation: Drivers are matched by simple class-code or vendor/device ID — no automatic alias generation from PCI class/subclass/prog-if.
- LegacyBackend is a stub:
hwd/backend/legacy.rs:13— "TODO: handle driver spawning from legacy backend" — any non-ACPI, non-DTB platform gets no hardware discovery. - Initfs transitional:
hwdandacpidlive on initfs boot path, not under stable rootfs service contract.
4.3 Alignment with Boot-Process-Hardware-Detection-Plan.md
| Wave | Plan Status | Code Reality |
|---|---|---|
| W0 Boot stage definitions | ✅ Done | Config-only |
| W1 ACPI bus in driver-manager | ✅ Done | AcpiBus exists |
| W2 Resource parser (_CRS, _PRT) | ✅ Done | Parsed |
| W2b ACPI device binding | ✅ Done | Wired |
| W2c GPIO/I2C configs | Partial | Runtime _CRS evaluation not started |
| W3 Service rewiring | ✅ Done | Stage targets wired |
| W4 Dead /etc/pcid.d/ removal | ✅ Done | Removed |
| W5 Deferred probing | ✅ Already had | Scheme-aware |
| W6 USB topology enumeration | Not started | Depends on xHCI IRQ stability |
5. Driver Infrastructure Reassessment
5.1 redox-driver-sys
Status: ✅ Production quality, zero stubs, zero TODOs
- Schemes: memory (physical mapping, cache type control), irq (registration, wait, affinity), pci (enumeration, config space, BARs, MSI-X)
- Quirks: 3-layer (compiled-in 11 entries + TOML runtime + DMI/SMBIOS 8 rules), 22 PCI flags, 21 USB flags
- MSI-X: Full
MsixTablewith validated x86 message programming, vector allocation, CPU round-robin - DMA:
DmaBuffer(phys-contiguous),IommuDmaAllocator(MAP/UNMAP protocol) - Tests: 30+ unit tests in
pci.rs
5.2 linux-kpi
Status: ✅ Structurally complete for GPU + Wi-Fi, 119 tests passing, zero stubs
- 17 Rust modules, 32 C headers
- Full implementations: pci (777 lines), net (809), wireless (1002), mac80211 (959), irq (228), firmware (277), drm_shim (374)
- No
todo!()/unimplemented!()in any audited module - C header coverage: pci.h, skbuff.h, interrupt.h, firmware.h, netdevice.h, ieee80211.h, nl80211.h, cfg80211.h, mac80211.h, drm*.h, atomic.h, spinlock.h, mutex.h, workqueue.h, timer.h, wait.h, list.h, slab.h, mm.h, io.h, types.h, errno.h, compiler.h, export.h, printk.h, module.h, refcount.h, jiffies.h, kernel.h, idr.h, bug.h
5.3 firmware-loader
Status: ✅ Production quality
scheme:firmwaredaemon withSchemeSyncimpl- MANIFEST generation (BLAKE3),
--probe,--request-nowait - Path traversal prevention, 64MB blob cap, cache with source signature validation
- AMD GPU: 17 firmware keys expected; Intel: per-generation DMC firmware
5.4 GPU Drivers
| Driver | Status | Key Gap |
|---|---|---|
| redox-drm (AMD) | 🟡 Compiles, 616 lines | synthetic_edid() fallback — no real DDC/I²C |
| redox-drm (Intel) | 🟡 Compiles, 693 lines | synthetic_edid() fallback — no real DDC/I²C |
| redox-drm (VirtIO) | 🟡 Compiles | synthetic_edid() fallback |
| amdgpu (C port) | 🟡 Compiles, ~1487 lines | Hardcoded 4 connector descriptors, no real HPD |
All three GPU drivers use synthetic_edid() at redox-drm/src/kms/connector.rs:35 — a hardcoded 128-byte EDID 1.4 block for 1920×1080@60Hz. This blocks real display detection on bare metal.
5.5 Wi-Fi
Status: 🟡 Compiles + host-tested, zero hardware validation
redbear-iwlwifi: C transport layer (~2450 lines) + Rust daemon (~1550 lines)- 8 host tests pass
- Commands time out without real firmware — by design
- No Intel Wi-Fi device ever exercised
5.6 USB
Status: 🟡 xhcid builds + QEMU proofs pass, bare-metal incomplete
- xhcid: Red Bear patched, QEMU IRQ delivery proven
- usbscsid: USB mass storage with inline quirks (214 storage quirks)
- usbhubd: Hub port management
- Gap: No EHCI, UHCI, or OHCI drivers — legacy USB keyboards on companion controllers are unreachable on bare metal
6. Cross-Cutting Critical Gaps (Updated Priority)
Gap 1 — IOMMU MSI Validation (CRITICAL)
File: kernel/src/scheme/irq.rs:231
fn iommu_validate_msi_irq(_irq: u8) -> bool {
true
}
Every MSI/MSI-X interrupt bypasses IOMMU remapping validation. This is a security and correctness gap. The hook exists but has zero logic.
Root cause: IOMMU daemon (iommu) provides AMD-Vi runtime but no Intel VT-d. The validation function needs remapping table data from the IOMMU daemon, or validation must move to userspace via a scheme call.
Action: Implement real validation against IOMMU remapping tables, or explicitly document that MSI/MSI-X without IOMMU is only safe on trusted buses.
Gap 2 — AML Physical Memory Stubs (CRITICAL)
Files: acpid/src/aml_physmem.rs:195, :274
read_phys_or_fault()returnsT::zero()on failure — fabricates datamap_physical_region()falls back to zero page — silent data loss
Impact: Any AML method accessing a physical memory region that fails to map will see fabricated zeroes. This can cause:
- Incorrect battery/thermal readings
- Silent EC communication failures
- Wrong power state transitions
Action: Propagate Result<T> errors to AML evaluation callers instead of fabricating values.
Gap 3 — AML PCI Access Stubs in acpid (CRITICAL, corrected v1.1)
Files: acpid/src/aml_physmem.rs:375–398 (NOT kernel/src/arch/x86_shared/sleep.rs:257–276 which does not exist)
read_pci_u8/u16/u32andwrite_pci_u8/u16/u32inAmlPhysMemHandler- When
pci_fdisNone(always, currently):read_pci()logs error, returns untouchedvaluearray (all zeros fromlet mut value = [0u8]);write_pci()silently does nothing - Root cause:
pcidnever sends its PCI scheme fd toacpidvia theRegisterPcischeme handle (scheme.rs:447–480)
Impact: Any AML method that accesses PCI config space (OpRegion with ACPI_ADR_SPACE_PCI_CONFIG) gets fabricated zero data. S5 shutdown works by accident because set_global_s_state(5) writes to PM1a port directly, but \_PTS, \_WAK, and any PCI-dependent \_S5 methods get wrong data.
Action: Wire pcid's PCI scheme fd to acpid:
pcidopens/scheme/acpi/register_pciand sends its pci scheme fd viaon_sendfdon startupacpidscheme stores the fd inAmlPhysMemHandler::pci_fdaml_eval()inacpi.rs:394passesself.pci_fd.as_ref()toaml_context_mutinstead ofNone
Gap 4 — APIC Timer Disabled (HIGH)
File: kernel/src/arch/x86_shared/device/local_apic.rs:81
//self.setup_timer();— the methodsetup_timer()does not exist; all timer infrastructure (LVT timer, divider config, count registers) is present but unconnected- System uses PIT fallback for all timer interrupts
Impact: No per-CPU timer interrupts (all CPUs share PIT on BSP), no TSC deadline mode for modern CPUs, potential timer skew on SMP, root cause of heat on bare metal.
Action (per Linux 7.1 arch/x86/kernel/apic/apic.c:277–321):
- Implement
setup_timer()method: TSC deadline mode for modern CPUs (Intel Haswell+, AMD Zen+), periodic with divide-by-16 fallback - Add PM-timer or TSC-based calibration (Linux:
lapic_cal_handler) - Wire into
init_ap()aftersetup_error_int() - Calibrate against PIT initially, switch to TSC-deadline or APIC periodic after calibration
Gap 5 — Synthetic EDID in All GPU Drivers (HIGH)
File: redox-drm/src/kms/connector.rs:35–84
- All three drivers (AMD, Intel, VirtIO) use hardcoded EDID via
synthetic_edid() - No real DDC/I²C display detection
Impact: Display will not work on bare metal with non-1080p panels, multi-monitor setups, or displays with non-standard timings.
Action (per Linux 7.1 drivers/gpu/drm/drm_edid.c and drm_dp_helper.c):
- Implement I²C-over-AUX infrastructure in redox-drm for DisplayPort connectors (DDC address 0x50)
- Replace
synthetic_edid()with real EDID fetch via AUX CH - Keep fallback to standard CEA/CTA modes if AUX CH fails (not a single hardcoded mode)
- For HDMI/VGA: implement separate DDC I²C bus access paths
Gap 6 — Dual AML Interpreters (HIGH)
Files: kernel uses acpi_ext crate (kernel-side); acpid/src/acpi.rs uses acpi crate (userspace)
- Two independent parsers for the same DSDT/SSDT
- Different handler implementations
- Bug fixes in one do not affect the other
Impact: Maintenance risk, correctness divergence, two surfaces for AML security issues.
Action: Converge on a single canonical interpreter. Recommendation: userspace (acpid) since all drivers are userspace per project model. The kernel sleep.rs path was expected but doesn't exist in this codebase — the actual AML eval path is entirely in acpid. Future kernel S3 support should delegate to userspace.
Gap 7 — No OHCI/UHCI Drivers (HIGH, corrected v1.1)
Files:
local/recipes/drivers/ohcid/source/src/main.rs:16–34— STUB: reads PCI BAR, enters sleep looplocal/recipes/drivers/uhcid/source/src/main.rs:16–34— STUB: reads I/O port BAR, enters sleep looplocal/recipes/drivers/ehcid/source/src/main.rs— ALREADY IMPLEMENTED (1538+ lines, full EHCI spec) — NOT a gap
Impact: Legacy USB keyboards on companion controller paths unreachable on bare metal. Only xHCI-native USB devices work, plus EHCI-native ones.
Action (per Linux 7.1 drivers/usb/host/ohci-hcd.c and uhci-hcd.c):
- OHCI first (MMIO-based, simpler than UHCI): 3–4 weeks
- HCCA (Host Controller Communications Area) for interrupt transfers
- Control/bulk/isochronous transfer descriptors
- Frame list management (1024 entries)
- Port power and reset control
- UHCI second (I/O port-based, more complex): 3–4 weeks
- Transfer descriptors (QTD) and queue heads (QH)
- Frame list pointer register in MMIO space
- Port reset and suspend control
Gap 8 — No C-State Kernel Backend (HIGH)
Impact: CPUs run at full frequency constantly on bare metal. Thermal throttling only. Root cause of heat on AMD64.
Action (per Linux 7.1 drivers/idle/intel_idle.c and arch/x86/include/asm/mwait.h):
- Kernel: add
mwait()/mwaitx()helper functions + C-state hint MSR read/write - ACPI: parse
_CSTin acpid, expose C-state info viascheme:cpuidle - Implement idle loop using MWAIT with sub-state hints (Linux pattern:
intel_idle.c:67–107idle_cpu struct) - Optional:
cpuidleddaemon to coordinate C-state selection
Gap 9 — DMAR Init in Wrong Owner (MEDIUM, corrected v1.1)
Files:
acpid/src/acpi/dmar/mod.rs:7— TODO comment: "Move this code to a separate driver as well?"acpid/src/acpi/dmar/mod.rs:55–90—Dmar::init()only logs register values, never initializes hardwareacpid/src/acpi.rs:545—Dmar::init(&this)call commented out- The iommu daemon is the correct owner:
local/recipes/system/iommu/
Impact: 533 lines of orphaned DMAR parsing in acpid. No Intel VT-d initialization anywhere.
Action (per Linux 7.1 drivers/iommu/intel/dmar.c:408–456):
- Remove
Dmar::init()from acpid — acpid should only expose raw ACPI table data - Move DMAR parsing to
iommudaemon: parse via/scheme/acpi, initialize IOMMU hardware (program RT, set up context entries, enable GCMD, configure fault handling) - Or: remove orphaned code until ready (Lower-effort path)
Gap 10 — >256 CPU MSI Truncation Panic (MEDIUM)
File: drivers/pcid/src/driver_interface/irq_helpers.rs:89
let cpu_id = u8::try_from(cpu_id).expect("usize cpu ids not implemented yet");— PANICS for CPU IDs > 255- x2APIC supports 32-bit APIC IDs (up to 4 billion CPUs)
Impact: Any pcid-spawned driver on a system with >256 CPUs will panic. Not a blocker for current hardware (Threadripper 128-thread = 128 CPUs) but must be fixed before >256 CPU systems are tested.
Action:
- Change
u8::try_from(cpu_id)tou32::try_from(cpu_id).map_err(|_| io::Error::new(io::ErrorKind::InvalidInput, "cpu_id > u32::MAX"))? - Update kernel
/scheme/irq/cpu-{:02x}to/scheme/irq/cpu-{:08x}for x2APIC - Add unit test for u32::MAX cpu_id path
Gap 11 — IOMMU Daemon→Kernel IRQ Integration Missing (MEDIUM, new in v1.1)
Files:
- Kernel has
set_iommu_remapping_active()(added 2026-06-08) iommudaemon never calls it
Impact: The MSI validation gate works correctly in code, but IOMMU_REMAPPING_ACTIVE always stays false, so the one-time warning always fires and the kernel never gets informed of hardware remapping state.
Action:
- Kernel: add
Handle::RemappingControlvariant inscheme/irq.rs, detect path"remapping"inkopenat(), parse"0"/"1"inkwrite()and callset_iommu_remapping_active() - iommu daemon: after
INIT_UNITSsucceeds and IRTE tables are set up, write"1"to/scheme/irq/remapping - On shutdown: iommu daemon writes
"0"before exit
Gap 12 — MSI Multi-Vector Not Exposed (MEDIUM, new in v1.1)
File: pcid/src/driver_interface/irq_helpers.rs:307
pci_allocate_interrupt_vectoronly allocates single vectorallocate_aligned_interrupt_vectorsalready supportscountparameter but is not exposedmulti_message_enablefield always set toSome(0)(single vector)
Impact: xhcid, nvmed, ixgbed, redox-drm cannot use multiple MSI vectors. Falls back to shared IRQ with degraded performance.
Action:
- Add
pci_allocate_interrupt_vectors(pcid_handle, driver, count)to pcid - For MSI: set
multi_message_enabletolog2(count), allocate contiguous aligned vectors - For MSI-X: loop calling
allocate_single_interrupt_vector_for_msi()per vector
7. Updated Execution Plan (v1.1)
Phase 1: Critical Stub Removal (2–3 weeks)
Goal: Remove all CRITICAL-severity stubs before any hardware validation.
| # | Task | File | Effort | Owner |
|---|---|---|---|---|
| 1.1 | Fix read_u8/u16/u32/u64 zero-return on failure (fabricate data) |
acpid/src/aml_physmem.rs:241–280 |
2 days | — |
| 1.2 | Fix map_physical_region() .expect() panic |
acpid/src/aml_physmem.rs:213–232 |
2 days | — |
| 1.3 | Wire pcid fd → acpid RegisterPci handle (root cause of Gap 3) |
pcid/main.rs + acpid/scheme.rs + acpid/acpi.rs:400 |
3 days | — |
| 1.4 | Remove println! debug artifact |
kernel/src/arch/x86_shared/interrupt/irq.rs:307 |
1 hour | — |
| 1.5 | Replace cpu_id u8 truncation panic with error return (Gap 10) |
pcid/src/driver_interface/irq_helpers.rs:89 |
1 day | — |
Gate: All CRITICAL stubs removed + cargo check clean on affected modules + pcid→acpid fd wiring tested.
Phase 2: IOMMU + MSI Validation (3–4 weeks)
Goal: Make MSI/MSI-X delivery trustworthy.
| # | Task | File | Effort | Owner |
|---|---|---|---|---|
| 2.1 | DONE (2026-06-08): iommu_validate_msi_irq() real implementation |
kernel/src/scheme/irq.rs:231 |
✅ | committed |
| 2.2 | Add /scheme/irq/remapping control file (Gap 11) |
kernel/src/scheme/irq.rs |
1 day | — |
| 2.3 | iommu daemon: write "1" to remapping after IRTE init |
iommu/source/src/main.rs |
2 days | — |
| 2.4 | iommu daemon: write "0" to remapping on shutdown |
iommu/source/src/main.rs |
1 day | — |
| 2.5 | QEMU validation: MSI-X with IOMMU enabled | test-msix-qemu.sh |
2 days | — |
| 2.6 | Move DMAR init from acpid to iommu daemon (Gap 9) | acpid/dmar/ → iommu/ |
1 week | — |
| 2.7 | QEMU validation: DMAR discovery + iommu | test-iommu-qemu.sh |
2 days | — |
Gate: test-msix-qemu.sh passes with IOMMU enabled + remapping gate works + no DMAR init in acpid.
Phase 3: Timer + CPU Power (2–3 weeks)
Goal: Enable per-CPU timers and basic CPU idle.
| # | Task | File | Effort | Owner |
|---|---|---|---|---|
| 3.1 | Implement setup_timer() method (TSC deadline + periodic fallback) |
kernel/src/arch/x86_shared/device/local_apic.rs |
1 week | — |
| 3.2 | Add PM-timer/TSC-based calibration | kernel/src/arch/x86_shared/device/local_apic.rs |
1 week | — |
| 3.3 | Wire setup_timer() into init_ap() after setup_error_int() |
local_apic.rs:81 |
1 day | — |
| 3.4 | Implement kernel cpuidle backend (MWAIT/HLT) | New file: kernel/src/arch/x86_shared/cpuidle.rs |
1 week | — |
| 3.5 | ACPI _CST parsing in acpid |
acpid/src/cstate.rs (new) |
1 week | — |
| 3.6 | QEMU validation: timer + idle | test-timer-qemu.sh |
2 days | — |
Gate: test-timer-qemu.sh passes with APIC timer + CPU idle active + C1/C2 entry observed.
Phase 4: Display Detection (4–6 weeks)
Goal: Replace synthetic EDID with real display detection.
| # | Task | File | Effort | Owner |
|---|---|---|---|---|
| 4.1 | Implement I²C-over-AUX infrastructure (DP connectors) | redox-drm/src/kms/aux.rs (new) |
2 weeks | — |
| 4.2 | Implement DDC I²C bus for HDMI/VGA | redox-drm/src/kms/ddc.rs (new) |
1 week | — |
| 4.3 | Wire HPD interrupt to connector detection | redox-drm/src/drivers/amd/mod.rs, intel/mod.rs |
1 week | — |
| 4.4 | Replace synthetic_edid() with real → CEA fallback |
redox-drm/src/kms/connector.rs:38–84 |
3 days | — |
| 4.5 | QEMU validation: EDID readback | test-drm-display-runtime.sh |
2 days | — |
| 4.6 | Bare-metal validation: AMD GPU display | test-amd-gpu.sh |
1 week | — |
| 4.7 | Bare-metal validation: Intel GPU display | test-intel-gpu.sh |
1 week | — |
Gate: Real EDID retrieved from at least one display on bare metal (AMD or Intel).
Phase 5: USB Legacy Controllers — OHCI/UHCI (6–8 weeks)
Goal: Enable USB keyboard on non-xHCI paths (EHCI already done).
| # | Task | File | Effort | Owner |
|---|---|---|---|---|
| 5.1 | Implement OHCI host controller driver | local/recipes/drivers/ohcid/source/src/main.rs |
3–4 weeks | — |
| 5.2 | Wire OHCI into driver-manager PCI binding | driver-manager/src/main.rs |
3 days | — |
| 5.3 | QEMU validation: OHCI keyboard | test-usb-qemu.sh |
2 days | — |
| 5.4 | Implement UHCI host controller driver | local/recipes/drivers/uhcid/source/src/main.rs |
3–4 weeks | — |
| 5.5 | Wire UHCI into driver-manager PCI binding | driver-manager/src/main.rs |
3 days | — |
| 5.6 | QEMU validation: UHCI keyboard | test-usb-qemu.sh |
2 days | — |
| 5.7 | MSI multi-vector support (Gap 12) | pcid/src/driver_interface/irq_helpers.rs:307 |
1 week | — |
Gate: USB keyboard works via OHCI/UHCI in QEMU + multi-vector MSI for xhcid/nvmed/ixgbed.
Phase 6: AML Convergence (3–4 weeks)
Goal: Resolve dual AML interpreter risk.
| # | Task | File | Effort | Owner |
|---|---|---|---|---|
| 6.1 | Audit kernel acpi_ext crate usage (does kernel still use it?) |
kernel/src/arch/x86_shared/sleep.rs (verify exists) |
2 days | — |
| 6.2 | Evaluate kernel→userspace S3/S5 sleep delegation | scheme/kernel.acpi/sleep → acpid |
1 week | — |
| 6.3 | Implement kernel→userspace sleep RPC if S3 is needed | scheme/kernel.acpi/sleep |
1 week | — |
| 6.3 | Remove kernel acpi_ext crate if delegated |
kernel/src/arch/x86_shared/sleep.rs |
3 days | — |
| 6.4 | QEMU validation: sleep/wake cycle | test-sleep-qemu.sh |
2 days | — |
Gate: S5 shutdown works with single AML interpreter (userspace only).
Phase 7: Hardware Validation Matrix (4–6 weeks, parallel with 4–6)
Goal: Evidence-based support claims.
| # | Task | Hardware | Effort |
|---|---|---|---|
| 7.1 | Class A1 validation (AMD desktop + discrete GPU) | Ryzen 5000/7000 + AMD GPU | 1 week |
| 7.2 | Class A2 validation (Intel desktop + iGPU) | Core 12th–14th Gen | 1 week |
| 7.3 | Class A3 validation (AMD laptop) | Ryzen Mobile | 1 week |
| 7.4 | Class A4 validation (Intel laptop) | Core Mobile | 1 week |
| 7.5 | Regression test suite on all 4 classes | All | 2 weeks |
Gate: All 4 hardware classes pass boot, shutdown, USB keyboard, and display detection.
8. Timeline Synthesis
Week 1–3: Phase 1 — Critical stub removal
Week 4–7: Phase 2 — IOMMU + MSI validation
Week 7–9: Phase 3 — Timer + CPU power (parallel with Phase 2 week 7)
Week 10–15: Phase 4 — Display detection (parallel with Phase 5)
Week 10–13: Phase 5 — USB legacy controllers (parallel with Phase 4)
Week 14–17: Phase 6 — AML convergence
Week 14–19: Phase 7 — Hardware validation matrix (parallel with Phase 6)
Total: 19 weeks (≈4.5 months) with 2 developers
What the existing plans said vs this plan
| Plan | Claimed Timeline | Reality |
|---|---|---|
| COMPREHENSIVE P1 (bare-metal hardening) | 6–8 weeks | Understated — no critical stub removal phase |
| COMPREHENSIVE P2 (USB) | 4–6 weeks | Realistic for EHCI only |
| COMPREHENSIVE P3 (IRQ/IOMMU) | 4–6 weeks | Realistic if focused on Gap 1 only |
| IRQ plan Waves 1–6 | "Complete" | Code quality complete, validation not started |
| ACPI plan Waves 0–7 | W0–W4 partial, W5–W7 open | Accurate, but two critical stubs not flagged |
| SMP plan bottlenecks | 11–18 days | Realistic for B1–B2 only |
Dependencies
Phase 1 (stub removal)
│
├── required by ──► Phase 2 (IOMMU validation)
│
├── required by ──► Phase 3 (timer + idle)
│
└── required by ──► Phase 4 (display detection)
Phase 2 (IOMMU)
└── required by ──► Phase 7 (hardware validation — safe MSI)
Phase 3 (timer + idle)
└── required by ──► Phase 7 (hardware validation — no overheating)
Phase 4 (display)
└── required by ──► Phase 7 (hardware validation — working console)
Phase 5 (USB EHCI)
└── required by ──► Phase 7 (hardware validation — keyboard input)
Phase 6 (AML convergence)
└── not blocking ──► Phase 7 (can validate with dual interpreters)
9. Risk Register (v1.1)
| # | Risk | Likelihood | Impact | Mitigation |
|---|---|---|---|---|
| R1 | aml_physmem stub fix requires acpi crate trait modification |
High | High | Fork acpi crate to local/recipes/, or use sentinel-value + error-flag workaround that doesn't require trait change |
| R2 | IOMMU daemon→kernel integration needs new scheme file | Low | Medium | Kernel side is ~20 lines (Handle::RemappingControl + write handler); daemon side is ~5 lines. Both well-understood. |
| R3 | APIC timer calibration fails on specific CPU models | Medium | Medium | Keep PIT fallback path; detect calibration failure and degrade gracefully. TSC deadline mode is simpler and doesn't need calibration. |
| R4 | DDC/I²C implementation requires AUX CH for DisplayPort | High | High | Phase 4 split: implement AUX CH for DP first (covers AMD/Intel), DDC I²C for HDMI/VGA later. Synthetic EDID as fallback always. |
| R5 | OHCI/UHCI implementation is high-effort (6–8 weeks total) | Medium | Medium | Phase 5 spans two cycles: OHCI first (MMIO-based, simpler), UHCI second (I/O port-based, more complex) |
| R6 | AML convergence depends on whether kernel still uses acpi_ext |
Unknown | Medium | Phase 6.1 audit: verify if kernel/src/arch/x86_shared/sleep.rs exists. If it does NOT exist, the dual-AML concern is moot (kernel has no AML interpreter). |
| R7 | MSI multi-vector breaks drivers that use shared IRQ assumptions | Low | Medium | Gate behind Phase 5; ship single-vector path as default; multi-vector is opt-in per driver |
| R8 | DMAR move from acpid to iommu daemon changes module ownership | Low | Medium | Refactor only; no new hardware interaction. iommu daemon already has the register-programming infrastructure. |
| R9 | pcid→acpid fd passing uses a Redox-specific mechanism | Medium | Medium | Verify fd-passing via on_sendfd works between pcid and acpid schemes. Add test in pcid. |
| R10 | No bare-metal hardware available for validation | Medium | Critical | Prioritize QEMU proofs for all phases; document "QEMU-validated" vs "bare-metal-validated" per subsystem |
10. Verification Gates (v1.1)
Gate A: Boot-Baseline Ready (end of Phase 1)
aml_physmem.rs:241–280read_u* methods no longer fabricate zeros on failureaml_physmem.rs:213–232map_physical_region()no longer panics on physmap failure- pcid sends fd to acpid via
/scheme/acpi/register_pci; acpidpci_fdisSomeafter init acpi.rs:400aml_eval()passesself.pci_fd.as_ref()instead ofNoneirq_helpers.rs:89returnsio::Errorinstead of panic for >255 CPU IDscargo checkclean onacpid,kernel,redox-drm,pcidrepo validate-patches kernelpassesrepo validate-patches basepasses
Gate B: IRQ/IOMMU Trustworthy (end of Phase 2)
iommu_validate_msi_irq()performs real validation (done 2026-06-08)/scheme/irq/remappingexists and is writable- iommu daemon writes
"1"to remapping after IRTE init - iommu daemon writes
"0"to remapping on shutdown - DMAR init removed from acpid
- DMAR init lives in iommu daemon
test-msix-qemu.shpasses with IOMMU enabledtest-iommu-qemu.shpasses- No unconditional
truereturns in IRQ validation path - Boot log does not show the "MSI before IOMMU" warning when IOMMU is configured
Gate C: Timer + Power (end of Phase 3)
setup_timer()method exists inlocal_apic.rs- APIC timer fires and calibrates correctly in QEMU
- CPU idle backend enters C1/C2 via MWAIT or HLT
test-timer-qemu.shpasses- No PIT-only fallback in boot log
Gate D: Display Detection (end of Phase 4)
- AUX CH infrastructure exists in
redox-drm/src/kms/aux.rs - DDC I²C infrastructure exists in
redox-drm/src/kms/ddc.rs synthetic_edid()is fallback, not primary- Real EDID retrieved from at least one display in QEMU
test-drm-display-runtime.shpasses
Gate E: USB Legacy (end of Phase 5)
- OHCI driver enumerates devices in QEMU
- UHCI driver enumerates devices in QEMU
- USB keyboard functional via OHCI in QEMU
- USB keyboard functional via UHCI in QEMU
- MSI multi-vector exposed via
pci_allocate_interrupt_vectors(pcid_handle, driver, count) - xhcid, nvmed, ixgbed updated to use multi-vector MSI where appropriate
test-usb-qemu.shpasses
Gate F: Single AML Interpreter (end of Phase 6)
- Audit: confirm whether
kernel/src/arch/x86_shared/sleep.rsexists - If it exists: evaluate kernel→userspace sleep delegation
- If it does NOT exist: dual-AML concern is moot, document this
- S5 shutdown works via userspace AML only
test-shutdown-qemu.shpasses (S5 only — S3 is not a current target)
Gate G: Hardware Validation (end of Phase 7)
- Class A1 (AMD desktop) boots, shuts down, displays, accepts USB keyboard
- Class A2 (Intel desktop) boots, shuts down, displays, accepts USB keyboard
- Class A3 (AMD laptop) boots, shuts down, displays, accepts USB keyboard
- Class A4 (Intel laptop) boots, shuts down, displays, accepts USB keyboard
- Validation artifacts committed to
local/docs/HARDWARE-VALIDATION-MATRIX.md
11. Appendix: Key File Reference
ACPI
recipes/core/kernel/source/src/acpi/mod.rs— Kernel ACPI orchestratorrecipes/core/kernel/source/src/acpi/rsdp.rs— RSDP discoveryrecipes/core/kernel/source/src/acpi/madt/mod.rs— MADT parserrecipes/core/kernel/source/src/scheme/acpi.rs— Kernel ACPI schemerecipes/core/kernel/source/src/arch/x86_shared/sleep.rs— Kernel AML interpreter for sleeprecipes/core/kernel/source/src/arch/x86_shared/stop.rs— Shutdown orchestratorrecipes/core/base/source/drivers/acpid/src/main.rs— acpid daemon entryrecipes/core/base/source/drivers/acpid/src/acpi.rs— Core ACPI contextrecipes/core/base/source/drivers/acpid/src/aml_physmem.rs— AML physmem handler (stubs at :195, :274)recipes/core/base/source/drivers/acpid/src/ec.rs— Embedded Controller handlerrecipes/core/base/source/drivers/acpid/src/thermal.rs— Thermal zone discoveryrecipes/core/base/source/drivers/acpid/src/fan.rs— Fan device discoveryrecipes/core/base/source/drivers/acpid/src/cstate.rs— C-state discoveryrecipes/core/base/source/drivers/acpid/src/dmi.rs— SMBIOS DMI parserrecipes/core/base/source/drivers/hwd/src/backend/acpi.rs— hwd ACPI backendrecipes/core/base/source/drivers/hwd/src/backend/legacy.rs— LegacyBackend stub (:13)
IRQ / PCI
recipes/core/kernel/source/src/scheme/irq.rs— IRQ scheme (stub at :231)recipes/core/kernel/source/src/arch/x86_shared/interrupt/irq.rs— IRQ dispatchrecipes/core/kernel/source/src/arch/x86_shared/device/ioapic.rs— I/O APICrecipes/core/kernel/source/src/arch/x86_shared/device/local_apic.rs— LAPIC (timer disabled at :81)recipes/core/kernel/source/src/arch/x86_shared/device/msi.rs— MSI code (patch-based)recipes/core/kernel/source/src/arch/x86_shared/device/vector.rs— Vector allocator (patch-based)recipes/core/kernel/source/src/arch/x86_shared/device/pic.rs— 8259 PICrecipes/core/kernel/source/src/arch/x86_shared/idt.rs— IDT setuplocal/recipes/drivers/redox-driver-sys/source/src/irq.rs— Userspace IRQ handlinglocal/recipes/drivers/redox-driver-sys/source/src/pci.rs— Userspace PCI abstractionrecipes/core/base/source/drivers/pcid/src/main.rs— pcid daemonrecipes/core/base/source/drivers/pcid/src/scheme.rs— PciSchemerecipes/core/base/source/drivers/pcid/src/driver_interface/irq_helpers.rs— IRQ helper FIXMEslocal/recipes/system/driver-manager/source/src/main.rs— Driver manager
Driver Infrastructure
local/recipes/drivers/redox-driver-sys/source/src/lib.rs— Core librarylocal/recipes/drivers/redox-driver-sys/source/src/quirks/mod.rs— Quirks APIlocal/recipes/drivers/linux-kpi/source/src/lib.rs— linux-kpi cratelocal/recipes/drivers/linux-kpi/source/src/rust_impl/pci.rs— PCI KPI (777 lines)local/recipes/drivers/linux-kpi/source/src/rust_impl/drm_shim.rs— DRM GEM shimlocal/recipes/drivers/linux-kpi/source/src/rust_impl/mac80211.rs— mac80211 KPI (959 lines)local/recipes/drivers/linux-kpi/source/src/rust_impl/wireless.rs— cfg80211 KPI (1002 lines)local/recipes/system/firmware-loader/source/src/main.rs— firmware-loader daemonlocal/recipes/gpu/redox-drm/source/src/main.rs— DRM daemonlocal/recipes/gpu/redox-drm/source/src/drivers/amd/mod.rs— AMD GPU driverlocal/recipes/gpu/redox-drm/source/src/drivers/intel/mod.rs— Intel GPU driverlocal/recipes/gpu/redox-drm/source/src/kms/connector.rs— Connector + synthetic EDID (:35)local/recipes/gpu/amdgpu/source/amdgpu_redox_main.c— Bounded AMD display C portlocal/recipes/gpu/amdgpu/source/redox_glue.h— Linux→Redox C gluelocal/recipes/gpu/amdgpu/source/redox_stubs.c— Kernel emulation stubs
Patches
local/patches/kernel/redbear-consolidated.patch— Consolidated mega-patchlocal/patches/kernel/P8-msi.patch— MSI + vector allocatorlocal/patches/kernel/P9-ioapic-irq-affinity.patch— IRQ affinitylocal/patches/kernel/P10-irq-affinity-wiring.patch— Affinity wiringlocal/patches/kernel/P20-x2apic-icr-mode-fix.patch— x2APIC ICRlocal/patches/kernel/P21-x2apic-smp-fix.patch— x2APIC SMPlocal/patches/kernel/P22-x2apic-madt-fallback.patch— x2APIC MADT fallbacklocal/patches/kernel/P24-cstate-mwait-idle.patch— C-state MWAITlocal/patches/kernel/P25-cpuidle-deep-cstates.patch— Deep C-stateslocal/patches/base/P19-acpid-startup-hardening.patch— acpid startuplocal/patches/base/P24-acpi-s5-derivation-shutdown-semantics.patch— S5 derivationlocal/patches/base/P44-acpid-thermal-zones.patch— Thermal zoneslocal/patches/base/P48-acpid-fan-support.patch— Fan supportlocal/patches/base/P52-acpid-cstates.patch— C-state discovery
12. Document Authority
This document is a cross-cutting reassessment that references but does not replace the canonical subsystem plans:
- For ACPI wave-level execution detail, see
ACPI-IMPROVEMENT-PLAN.md - For IRQ/PCI wave-level execution detail, see
IRQ-AND-LOWLEVEL-CONTROLLERS-ENHANCEMENT-PLAN.md - For boot detection wave detail, see
BOOT-PROCESS-HARDWARE-DETECTION-PLAN.md - For SMP bottleneck detail, see
SMP-SCHEDULER-IMPROVEMENT-PLAN.md - For desktop path blockers, see
CONSOLE-TO-KDE-DESKTOP-PLAN.md
13. Concrete Fix List (v1.1, Ready to Execute)
The following items are ready to implement immediately — they have been fully audited against Linux 7.1 reference, the root cause is understood, and the fix is specified. Each item has been promoted to a tracked task.
1.1.a — acpid read_u8/u16/u32/u64 data fabrication (Gap 2)
File: local/sources/base/drivers/acpid/src/aml_physmem.rs:241–280
Severity: 🔴 CRITICAL
Linux reference: local/reference/linux-7.1/drivers/acpi/acpica/evregion.c:302–316 — acpi_ev_address_space_dispatch() checks handler return status and logs exception; never fabricates data
Current code (representative — same pattern in all 4 read methods):
fn read_u8(&self, address: usize) -> u8 {
if let Ok(mut page_cache) = self.page_cache.lock() {
if let Ok(value) = page_cache.read_from_phys::<u8>(address) {
return value;
}
}
log::error!("failed to read u8 {:#x}", address);
0 // FABRICATES DATA
}
Target code (sentinel-value approach, since the acpi crate's Handler trait returns raw u8):
static READ_FABRICATION_FLAG: AtomicUsize = AtomicUsize::new(0);
fn read_u8(&self, address: usize) -> u8 {
if let Ok(mut page_cache) = self.page_cache.lock() {
match page_cache.read_from_phys::<u8>(address) {
Ok(value) => return value,
Err(e) => log::error!("read u8 {:#x} failed: {:?}", address, e),
}
}
READ_FABRICATION_FLAG.fetch_add(1, Ordering::SeqCst);
0
}
pub fn read_fabrication_count() -> usize {
READ_FABRICATION_FLAG.load(Ordering::SeqCst)
}
Note: Full Result<T, AmlError> propagation requires forking the acpi crate and modifying the Handler trait. The sentinel+flag approach is the minimum-viable fix that doesn't require a crate fork.
1.1.b — acpid map_physical_region panic (Gap 2)
File: local/sources/base/drivers/acpid/src/aml_physmem.rs:213–232
Severity: 🔴 CRITICAL
Linux reference: local/reference/linux-7.1/drivers/acpi/acpica/exregion.c:145–153 — returns AE_NO_MEMORY status on map failure
Current code:
let virt_page = common::physmap(...).expect("failed to map physical region") as usize;
Target code:
let virt_page = match common::physmap(...) {
Ok(v) => v as usize,
Err(e) => {
log::error!("physmap failed at {:#x}+{:#x}: {:?}", phys_page, map_size, e);
return PhysicalMapping {
physical_start: phys,
virtual_start: NonNull::dangling(),
region_length: size,
mapped_length: 0, // 0 length signals invalid
handler: self.clone(),
};
}
};
1.3 — Wire pcid→acpid fd (Gap 3)
Files:
local/sources/base/drivers/pcid/src/main.rs(add fd send)local/sources/base/drivers/acpid/src/scheme.rs(handleRegisterPci)local/sources/base/drivers/acpid/src/acpi.rs:400(pass pci_fd to aml_context_mut)
Implementation sketch:
// In pcid/src/main.rs, after PCI bus init, before event loop:
let acpi_register = File::open("/scheme/acpi/register_pci")?;
let pci_scheme_fd = /* get from pcid's internal pci scheme handle */;
send_fd(acpi_register, pci_scheme_fd)?;
// In acpi.rs line 400, change:
let interpreter = symbols.aml_context_mut(self.pci_fd.as_ref())?;
// from:
let interpreter = symbols.aml_context_mut(None)?;
1.5 — Replace u8 CPU ID panic (Gap 10)
File: local/sources/base/drivers/pcid/src/driver_interface/irq_helpers.rs:89
Severity: 🟠 HIGH (panic on >255 CPU systems)
Current code:
let cpu_id = u8::try_from(cpu_id).expect("usize cpu ids not implemented yet");
Target code:
let cpu_id = u32::try_from(cpu_id)
.map_err(|_| io::Error::new(io::ErrorKind::InvalidInput, "cpu_id > u32::MAX"))?;
2.2 — Add /scheme/irq/remapping control file (Gap 11)
File: local/sources/kernel/src/scheme/irq.rs
Severity: 🟡 MEDIUM
Linux reference: local/reference/linux-7.1/include/linux/pci.h — pci_write_config_byte is the equivalent scheme pattern in Redox
Implementation:
- Add
Handle::RemappingControlvariant - In
kopenat(), detect path"remapping"and returnOpenResult::Otherwith this handle - In
kwrite(), parse"0"or"1"and callset_iommu_remapping_active() - Document in
irqs.md(or scheme doc)
2.3-2.4 — iommu daemon writes to /scheme/irq/remapping (Gap 11)
File: local/recipes/system/iommu/source/src/main.rs
Severity: 🟡 MEDIUM
Implementation:
// After successful INIT_UNITS and IRTE setup:
let remapping = std::fs::File::create("/scheme/irq/remapping")?;
remapping.write_all(b"1")?;
// On shutdown signal:
let remapping = std::fs::File::create("/scheme/irq/remapping")?;
remapping.write_all(b"0")?;
2.6 — Move DMAR init from acpid to iommu daemon (Gap 9)
Files:
- Remove:
local/sources/base/drivers/acpid/src/acpi/dmar/mod.rs(533 lines of orphaned code) - Add: DMAR parsing to
local/recipes/system/iommu/source/src/intel.rs(new file) - Add: DMAR init wired into
local/recipes/system/iommu/source/src/main.rsINIT_UNITSpath
Linux reference: local/reference/linux-7.1/drivers/iommu/intel/dmar.c:408–456 (dmar_parse_one_drhd)
3.1-3.3 — Re-enable APIC timer (Gap 4)
File: local/sources/kernel/src/arch/x86_shared/device/local_apic.rs
Severity: 🟠 HIGH
Linux reference: local/reference/linux-7.1/arch/x86/kernel/apic/apic.c:277–321 (__setup_APIC_LVTT)
Implementation:
- Implement
setup_timer()method (TSC deadline mode first, periodic fallback) - Add PM-timer or TSC calibration (
lapic_cal_handlerpattern,apic.c:662–688) - Uncomment line 81:
self.setup_timer(); - Verify with
test-timer-qemu.sh
5.1-5.6 — OHCI and UHCI drivers (Gap 7)
Files:
local/recipes/drivers/ohcid/source/src/main.rs(currently 19-line stub)local/recipes/drivers/uhcid/source/src/main.rs(currently 19-line stub)
Linux reference:
local/reference/linux-7.1/drivers/usb/host/ohci-hcd.c(full reference impl)local/reference/linux-7.1/drivers/usb/host/uhci-hcd.c(full reference impl)
Implementation order:
- OHCI first (3–4 weeks): MMIO register access, HCCA, transfer descriptors, frame list, port management
- UHCI second (3–4 weeks): I/O port register access, QH/QTD management, FLBASEADD, port control
5.7 — MSI multi-vector allocation (Gap 12)
File: local/sources/base/drivers/pcid/src/driver_interface/irq_helpers.rs:307
Severity: 🟡 MEDIUM
Linux reference: local/reference/linux-7.1/drivers/pci/msi/api.c — pci_alloc_irq_vectors()
Implementation:
- Add
pci_allocate_interrupt_vectors(pcid_handle, driver, count)to pcid - For MSI: set
multi_message_enable = log2(count), allocate contiguous aligned vectors - For MSI-X: loop calling
allocate_single_interrupt_vector_for_msi()per vector - Update xhcid, nvmed, ixgbed, redox-drm to use multi-vector where appropriate
14. v1.1 Audit Methodology
The v1.1 corrections were made by:
- Reading the source files at the locations the v1.0 plan claimed contained stubs
- Discovering that several locations don't exist (
kernel/src/arch/x86_shared/sleep.rs:257–276) - Finding the actual stubs at different locations
- Cross-referencing against Linux 7.1 reference at
local/reference/linux-7.1/for each fix - Verifying through grep + read that the line numbers in the v1.0 plan were sometimes off
- Checking git history of
local/sources/base/andlocal/sources/kernel/to ensure fixes target the correct durable location
Findings of the audit
| v1.0 claim | v1.1 reality |
|---|---|
Gap 3: kernel sleep.rs:257–276 PCI stubs |
Does not exist — sleep path is in acpid/aml_physmem.rs:375–398 |
| Gap 7: no EHCI driver | EHCI is implemented (1538+ lines) — stubs are OHCI + UHCI |
Gap 1: MSI stub at kernel/scheme/irq.rs:231 |
Fixed 2026-06-08 (this audit's first deliverable) |
Gap 2: AML stubs at aml_physmem.rs:195, :274 |
Wrong line numbers — actual stubs are at :241–280 (reads) and :213–232 (map) |
| Gap 4: APIC timer disabled | Confirmed — setup_timer() method doesn't even exist |
| Gap 6: Dual AML interpreters | Confirmed, but reduced scope — kernel may not have AML interpreter at all |
| Gap 8: No C-state backend | Confirmed — no cpuidle exists, no cstate.rs in acpid |
| Gap 9: DMAR orphaned | Confirmed, but ownership wrong — should be in iommu daemon, not acpid |
| Gap 10: >256 CPU MSI | Confirmed, but is a panic, not a deferred case — u8::try_from(...).expect(...) |
| New Gap 11: IOMMU→kernel integration | New finding — kernel has set_iommu_remapping_active() but daemon never calls it |
| New Gap 12: MSI multi-vector | New finding — required by xhcid, nvmed, ixgbed, redox-drm |
When this document conflicts with a canonical subsystem plan, the canonical plan wins on subsystem-specific details, and this document wins on cross-cutting prioritization and inter-subsystem dependencies.
This document should be updated after each phase gate is reached, or when new critical stubs are discovered.