e22ae71cb5
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.
1018 lines
58 KiB
Markdown
1018 lines
58 KiB
Markdown
# 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–W7
|
||
- `IRQ-AND-LOWLEVEL-CONTROLLERS-ENHANCEMENT-PLAN.md` — PCI/IRQ/MSI-X waves W1–W6
|
||
- `BOOT-PROCESS-HARDWARE-DETECTION-PLAN.md` — Boot detection waves W0–W6
|
||
- `SMP-SCHEDULER-IMPROVEMENT-PLAN.md` — SMP bottlenecks B1–B7
|
||
- `local/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)
|
||
|
||
1. **Critical stub discovered**: `iommu_validate_msi_irq()` at `kernel/src/scheme/irq.rs:231` unconditionally returns `true` — this was not flagged as a blocking item in the IRQ enhancement plan (all 6 waves marked "complete").
|
||
2. **Critical stub discovered**: `aml_physmem.rs:195` and `:274` fabricate zero values on physical memory access failure — affects all AML runtime evaluation.
|
||
3. **Dual AML interpreter architecture** identified as a maintenance risk — kernel `acpi_ext` crate and userspace `acpi` crate parse DSDT/SSDT independently.
|
||
4. **APIC timer disabled** (`local_apic.rs:81`) — not flagged in any existing plan as a blocker.
|
||
5. **Synthetic EDID used in all GPU drivers** — blocks real display detection on bare metal.
|
||
6. **40 total TODOs** in ACPI code (16 kernel + 24 userspace) — higher than previously documented.
|
||
7. **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.rs` 1002 lines, `mac80211.rs` 959 lines, `net.rs` 809 lines). No TODO/FIXME/STUB markers found in wireless code. The `amdgpu_stubs.h` stub file is GPU-specific and does not affect Wi-Fi.
|
||
|
||
### What changed in v1.1 (2026-06-08) — Linux 7.1 cross-reference audit
|
||
|
||
8. **`kernel/src/arch/x86_shared/sleep.rs:257–276` does not exist**: The kernel has no `sleep.rs` file. The sleep path is entirely in userspace (`acpid`). The actual PCI config access stubs are in `acpid/src/aml_physmem.rs:375–398` (read_pci_u8/u16/u32, write_pci_u8/u16/u32) where `pci_fd` is always `None` because `pcid` never sends its fd to `acpid`. The fix is to wire pcid's fd to acpid via the `RegisterPci` scheme handle, not to modify a non-existent kernel file.
|
||
|
||
9. **EHCI is already implemented** (2026-06-08): `local/recipes/drivers/ehcid/source/src/main.rs` is 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.
|
||
|
||
10. **MSI/MSI-X stub FIXED** (2026-06-08): The `iommu_validate_msi_irq()` blind `true` return at `kernel/src/scheme/irq.rs:231` was replaced with proper IOMMU remapping state tracking. Now uses `IOMMU_REMAPPING_ACTIVE: AtomicBool` + public `set_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).
|
||
|
||
11. **IOMMU daemon→kernel IRQ integration missing** (2026-06-08): The kernel now has `set_iommu_remapping_active()` but the `iommu` daemon never calls it. The MSI validation gate works correctly once the daemon writes to a new `/scheme/irq/remapping` file. Spec: kernel adds `Handle::RemappingControl` + write handler; daemon writes `"1"` after `INIT_UNITS` succeeds and IRTE tables are set up.
|
||
|
||
12. **MSI multi-vector allocation is a real blocker** (2026-06-08): `pci_allocate_interrupt_vector` in `pcid/src/driver_interface/irq_helpers.rs:307` only allocates single vectors. xhcid (USB 3.0), nvmed (NVMe), ixgbed (10GbE), and redox-drm (GPU) all need multiple vectors. `allocate_aligned_interrupt_vectors` already supports `count` parameter; the fix is to expose it. `multi_message_enable` field in MSI capability is always set to `Some(0)` (single vector).
|
||
|
||
13. **>255 CPU truncation is a panic** (2026-06-08): `irq_helpers.rs:89` `u8::try_from(cpu_id).expect("usize cpu ids not implemented yet")` panics for CPU IDs > 255. Must be converted to `io::Error` return. 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.
|
||
|
||
14. **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. The `acpi.rs:545` call is commented out. Per microkernel design, DMAR init belongs in the `iommu` daemon, not acpid. Linux 7.1 reference: `drivers/iommu/intel/dmar.c` (intel-iommu init pattern).
|
||
|
||
15. **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: implement `setup_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
|
||
|
||
1. **Dual AML interpreters**: Kernel `sleep.rs` uses `acpi_ext` crate; userspace `acpid` uses `acpi` crate. They parse the same DSDT/SSDT independently with different handler implementations. Bug fixes in one do not affect the other.
|
||
2. **RSDP_ADDR contract**: acpid AML init requires `RSDP_ADDR` environment variable (from `hwd` via `KernelArgs.hwdesc_base`). x86 has BIOS fallback; non-x86 paths are unresolved.
|
||
3. **S5 derivation timing**: Depends on AML readiness which depends on PCI registration. Pre-PCI shutdown falls back gracefully but the degraded contract is weak.
|
||
4. **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 (`madt` arch variants, `hpet` x86 assumption, `spcr` type support, `scheme/acpi` context 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 by `P8-msi.patch` (281 lines, 12 hunks)
|
||
- `vector.rs` (+53 lines) — added by `P8-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
|
||
|
||
1. **No ACPI _HID/_CID matching**: Non-PCI devices (ACPI-enumerated GPIO, I2C, etc.) are not bound through the driver-manager.
|
||
2. **No modalias generation**: Drivers are matched by simple class-code or vendor/device ID — no automatic alias generation from PCI class/subclass/prog-if.
|
||
3. **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.
|
||
4. **Initfs transitional**: `hwd` and `acpid` live 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 `MsixTable` with 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:firmware` daemon with `SchemeSync` impl
|
||
- 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`
|
||
```rust
|
||
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()` returns `T::zero()` on failure — fabricates data
|
||
- `map_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/u32` and `write_pci_u8/u16/u32` in `AmlPhysMemHandler`
|
||
- When `pci_fd` is `None` (always, currently): `read_pci()` logs error, returns untouched `value` array (all zeros from `let mut value = [0u8]`); `write_pci()` silently does nothing
|
||
- Root cause: `pcid` never sends its PCI scheme fd to `acpid` via the `RegisterPci` scheme 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:
|
||
1. `pcid` opens `/scheme/acpi/register_pci` and sends its pci scheme fd via `on_sendfd` on startup
|
||
2. `acpid` scheme stores the fd in `AmlPhysMemHandler::pci_fd`
|
||
3. `aml_eval()` in `acpi.rs:394` passes `self.pci_fd.as_ref()` to `aml_context_mut` instead of `None`
|
||
|
||
### Gap 4 — APIC Timer Disabled (HIGH)
|
||
**File**: `kernel/src/arch/x86_shared/device/local_apic.rs:81`
|
||
- `//self.setup_timer();` — the method `setup_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`):
|
||
1. Implement `setup_timer()` method: TSC deadline mode for modern CPUs (Intel Haswell+, AMD Zen+), periodic with divide-by-16 fallback
|
||
2. Add PM-timer or TSC-based calibration (Linux: `lapic_cal_handler`)
|
||
3. Wire into `init_ap()` after `setup_error_int()`
|
||
4. 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`):
|
||
1. Implement I²C-over-AUX infrastructure in redox-drm for DisplayPort connectors (DDC address 0x50)
|
||
2. Replace `synthetic_edid()` with real EDID fetch via AUX CH
|
||
3. Keep fallback to standard CEA/CTA modes if AUX CH fails (not a single hardcoded mode)
|
||
4. 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 loop
|
||
- `local/recipes/drivers/uhcid/source/src/main.rs:16–34` — STUB: reads I/O port BAR, enters sleep loop
|
||
- `local/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`):
|
||
1. **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
|
||
2. **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`):
|
||
1. Kernel: add `mwait()`/`mwaitx()` helper functions + C-state hint MSR read/write
|
||
2. ACPI: parse `_CST` in acpid, expose C-state info via `scheme:cpuidle`
|
||
3. Implement idle loop using MWAIT with sub-state hints (Linux pattern: `intel_idle.c:67–107` idle_cpu struct)
|
||
4. Optional: `cpuidled` daemon 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 hardware
|
||
- `acpid/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`):
|
||
1. Remove `Dmar::init()` from acpid — acpid should only expose raw ACPI table data
|
||
2. Move DMAR parsing to `iommu` daemon: parse via `/scheme/acpi`, initialize IOMMU hardware (program RT, set up context entries, enable GCMD, configure fault handling)
|
||
3. 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**:
|
||
1. Change `u8::try_from(cpu_id)` to `u32::try_from(cpu_id).map_err(|_| io::Error::new(io::ErrorKind::InvalidInput, "cpu_id > u32::MAX"))?`
|
||
2. Update kernel `/scheme/irq/cpu-{:02x}` to `/scheme/irq/cpu-{:08x}` for x2APIC
|
||
3. 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)
|
||
- `iommu` daemon 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**:
|
||
1. Kernel: add `Handle::RemappingControl` variant in `scheme/irq.rs`, detect path `"remapping"` in `kopenat()`, parse `"0"`/`"1"` in `kwrite()` and call `set_iommu_remapping_active()`
|
||
2. iommu daemon: after `INIT_UNITS` succeeds and IRTE tables are set up, write `"1"` to `/scheme/irq/remapping`
|
||
3. 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_vector` only allocates single vector
|
||
- `allocate_aligned_interrupt_vectors` already supports `count` parameter but is not exposed
|
||
- `multi_message_enable` field always set to `Some(0)` (single vector)
|
||
|
||
**Impact**: xhcid, nvmed, ixgbed, redox-drm cannot use multiple MSI vectors. Falls back to shared IRQ with degraded performance.
|
||
|
||
**Action**:
|
||
1. Add `pci_allocate_interrupt_vectors(pcid_handle, driver, count)` to pcid
|
||
2. For MSI: set `multi_message_enable` to `log2(count)`, allocate contiguous aligned vectors
|
||
3. 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–280` read_u* methods no longer fabricate zeros on failure
|
||
- [ ] `aml_physmem.rs:213–232` `map_physical_region()` no longer panics on physmap failure
|
||
- [ ] pcid sends fd to acpid via `/scheme/acpi/register_pci`; acpid `pci_fd` is `Some` after init
|
||
- [ ] `acpi.rs:400` `aml_eval()` passes `self.pci_fd.as_ref()` instead of `None`
|
||
- [ ] `irq_helpers.rs:89` returns `io::Error` instead of panic for >255 CPU IDs
|
||
- [ ] `cargo check` clean on `acpid`, `kernel`, `redox-drm`, `pcid`
|
||
- [ ] `repo validate-patches kernel` passes
|
||
- [ ] `repo validate-patches base` passes
|
||
|
||
### Gate B: IRQ/IOMMU Trustworthy (end of Phase 2)
|
||
- [x] `iommu_validate_msi_irq()` performs real validation (done 2026-06-08)
|
||
- [ ] `/scheme/irq/remapping` exists 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.sh` passes with IOMMU enabled
|
||
- [ ] `test-iommu-qemu.sh` passes
|
||
- [ ] No unconditional `true` returns 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 in `local_apic.rs`
|
||
- [ ] APIC timer fires and calibrates correctly in QEMU
|
||
- [ ] CPU idle backend enters C1/C2 via MWAIT or HLT
|
||
- [ ] `test-timer-qemu.sh` passes
|
||
- [ ] 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.sh` passes
|
||
|
||
### 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.sh` passes
|
||
|
||
### Gate F: Single AML Interpreter (end of Phase 6)
|
||
- [ ] Audit: confirm whether `kernel/src/arch/x86_shared/sleep.rs` exists
|
||
- [ ] 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.sh` passes (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 orchestrator
|
||
- `recipes/core/kernel/source/src/acpi/rsdp.rs` — RSDP discovery
|
||
- `recipes/core/kernel/source/src/acpi/madt/mod.rs` — MADT parser
|
||
- `recipes/core/kernel/source/src/scheme/acpi.rs` — Kernel ACPI scheme
|
||
- `recipes/core/kernel/source/src/arch/x86_shared/sleep.rs` — Kernel AML interpreter for sleep
|
||
- `recipes/core/kernel/source/src/arch/x86_shared/stop.rs` — Shutdown orchestrator
|
||
- `recipes/core/base/source/drivers/acpid/src/main.rs` — acpid daemon entry
|
||
- `recipes/core/base/source/drivers/acpid/src/acpi.rs` — Core ACPI context
|
||
- `recipes/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 handler
|
||
- `recipes/core/base/source/drivers/acpid/src/thermal.rs` — Thermal zone discovery
|
||
- `recipes/core/base/source/drivers/acpid/src/fan.rs` — Fan device discovery
|
||
- `recipes/core/base/source/drivers/acpid/src/cstate.rs` — C-state discovery
|
||
- `recipes/core/base/source/drivers/acpid/src/dmi.rs` — SMBIOS DMI parser
|
||
- `recipes/core/base/source/drivers/hwd/src/backend/acpi.rs` — hwd ACPI backend
|
||
- `recipes/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 dispatch
|
||
- `recipes/core/kernel/source/src/arch/x86_shared/device/ioapic.rs` — I/O APIC
|
||
- `recipes/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 PIC
|
||
- `recipes/core/kernel/source/src/arch/x86_shared/idt.rs` — IDT setup
|
||
- `local/recipes/drivers/redox-driver-sys/source/src/irq.rs` — Userspace IRQ handling
|
||
- `local/recipes/drivers/redox-driver-sys/source/src/pci.rs` — Userspace PCI abstraction
|
||
- `recipes/core/base/source/drivers/pcid/src/main.rs` — pcid daemon
|
||
- `recipes/core/base/source/drivers/pcid/src/scheme.rs` — PciScheme
|
||
- `recipes/core/base/source/drivers/pcid/src/driver_interface/irq_helpers.rs` — IRQ helper FIXMEs
|
||
- `local/recipes/system/driver-manager/source/src/main.rs` — Driver manager
|
||
|
||
### Driver Infrastructure
|
||
- `local/recipes/drivers/redox-driver-sys/source/src/lib.rs` — Core library
|
||
- `local/recipes/drivers/redox-driver-sys/source/src/quirks/mod.rs` — Quirks API
|
||
- `local/recipes/drivers/linux-kpi/source/src/lib.rs` — linux-kpi crate
|
||
- `local/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 shim
|
||
- `local/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 daemon
|
||
- `local/recipes/gpu/redox-drm/source/src/main.rs` — DRM daemon
|
||
- `local/recipes/gpu/redox-drm/source/src/drivers/amd/mod.rs` — AMD GPU driver
|
||
- `local/recipes/gpu/redox-drm/source/src/drivers/intel/mod.rs` — Intel GPU driver
|
||
- `local/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 port
|
||
- `local/recipes/gpu/amdgpu/source/redox_glue.h` — Linux→Redox C glue
|
||
- `local/recipes/gpu/amdgpu/source/redox_stubs.c` — Kernel emulation stubs
|
||
|
||
### Patches
|
||
- `local/patches/kernel/redbear-consolidated.patch` — Consolidated mega-patch
|
||
- `local/patches/kernel/P8-msi.patch` — MSI + vector allocator
|
||
- `local/patches/kernel/P9-ioapic-irq-affinity.patch` — IRQ affinity
|
||
- `local/patches/kernel/P10-irq-affinity-wiring.patch` — Affinity wiring
|
||
- `local/patches/kernel/P20-x2apic-icr-mode-fix.patch` — x2APIC ICR
|
||
- `local/patches/kernel/P21-x2apic-smp-fix.patch` — x2APIC SMP
|
||
- `local/patches/kernel/P22-x2apic-madt-fallback.patch` — x2APIC MADT fallback
|
||
- `local/patches/kernel/P24-cstate-mwait-idle.patch` — C-state MWAIT
|
||
- `local/patches/kernel/P25-cpuidle-deep-cstates.patch` — Deep C-states
|
||
- `local/patches/base/P19-acpid-startup-hardening.patch` — acpid startup
|
||
- `local/patches/base/P24-acpi-s5-derivation-shutdown-semantics.patch` — S5 derivation
|
||
- `local/patches/base/P44-acpid-thermal-zones.patch` — Thermal zones
|
||
- `local/patches/base/P48-acpid-fan-support.patch` — Fan support
|
||
- `local/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):
|
||
```rust
|
||
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`):
|
||
```rust
|
||
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**:
|
||
```rust
|
||
let virt_page = common::physmap(...).expect("failed to map physical region") as usize;
|
||
```
|
||
|
||
**Target code**:
|
||
```rust
|
||
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` (handle `RegisterPci`)
|
||
- `local/sources/base/drivers/acpid/src/acpi.rs:400` (pass pci_fd to aml_context_mut)
|
||
|
||
**Implementation sketch**:
|
||
```rust
|
||
// 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**:
|
||
```rust
|
||
let cpu_id = u8::try_from(cpu_id).expect("usize cpu ids not implemented yet");
|
||
```
|
||
**Target code**:
|
||
```rust
|
||
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**:
|
||
1. Add `Handle::RemappingControl` variant
|
||
2. In `kopenat()`, detect path `"remapping"` and return `OpenResult::Other` with this handle
|
||
3. In `kwrite()`, parse `"0"` or `"1"` and call `set_iommu_remapping_active()`
|
||
4. 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**:
|
||
```rust
|
||
// 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.rs` `INIT_UNITS` path
|
||
|
||
**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**:
|
||
1. Implement `setup_timer()` method (TSC deadline mode first, periodic fallback)
|
||
2. Add PM-timer or TSC calibration (`lapic_cal_handler` pattern, `apic.c:662–688`)
|
||
3. Uncomment line 81: `self.setup_timer();`
|
||
4. 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**:
|
||
1. **OHCI first** (3–4 weeks): MMIO register access, HCCA, transfer descriptors, frame list, port management
|
||
2. **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**:
|
||
1. Add `pci_allocate_interrupt_vectors(pcid_handle, driver, count)` to pcid
|
||
2. For MSI: set `multi_message_enable = log2(count)`, allocate contiguous aligned vectors
|
||
3. For MSI-X: loop calling `allocate_single_interrupt_vector_for_msi()` per vector
|
||
4. Update xhcid, nvmed, ixgbed, redox-drm to use multi-vector where appropriate
|
||
|
||
## 14. v1.1 Audit Methodology
|
||
|
||
The v1.1 corrections were made by:
|
||
|
||
1. **Reading** the source files at the locations the v1.0 plan claimed contained stubs
|
||
2. **Discovering** that several locations don't exist (`kernel/src/arch/x86_shared/sleep.rs:257–276`)
|
||
3. **Finding** the actual stubs at different locations
|
||
4. **Cross-referencing** against Linux 7.1 reference at `local/reference/linux-7.1/` for each fix
|
||
5. **Verifying** through grep + read that the line numbers in the v1.0 plan were sometimes off
|
||
6. **Checking** git history of `local/sources/base/` and `local/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.
|