9540168a48
Documents the two R7 audit findings and the comprehensive plan to fully utilize the R0-R22 quirks-and-bugs subsystem. Findings - cb_intel_ntb_bar_fix was a no-op stub (cleared PCI_COMMAND_MEMORY and restored it; the device never observed the transient clear). Replaced with the real Linux quirk_intel_ntb reads at config offsets 0xD0 and 0xD1. 3 new unit tests. 131/131 redox-driver-sys tests pass. - redbear-quirks install script copied only 8 of 30 TOML files, leaving all R11-R21 data tables inert at runtime. Replaced the explicit list with a glob. Utilization plan - Audit of every other cb_* callback (all justified, no other stubs). - Full consumer-wiring matrix showing what's wired, what's not, and the concrete step for each pending consumer. - Initialization-path wiring from bootloader SMBIOS through kernel to acpid/pcid/xhcid/usbhidd/evdevd/network/storage/audio/drm. - 15-task implementation order with estimates (22-32 days sequential, parallelizable to 2-3 devs in 4-6 weeks). - Updated test count: 131 host-buildable redox-driver-sys + 13 acpid dmi + 12 pcid + 7 usbhidd + 4 evdevd + 3 iwlwifi = 170 total. After the 15 tasks land, every lookup function in redox-driver-sys has at least one production consumer; the data tables drive real kernel/userspace behavior; and the R0-R22 infrastructure is fully automatically made to work on real hardware.
3804 lines
199 KiB
Markdown
3804 lines
199 KiB
Markdown
# Red Bear OS Hardware Quirks System
|
||
|
||
## Recent Activity (2026-06)
|
||
|
||
| Date | Commit | What |
|
||
|---|---|---|
|
||
| 2026-04 | R0-R10 (R0-R5 `86902d481`, R6 `5e44191c9` + xhcid `3b0d02d8`, R7-R9 `b56b810c0`, R10 `b324cf67e`+`6f1df4f04`) | All pushed to gitea `0.2.3` |
|
||
| 2026-06 | R1-R10 audit (`60b200601`) | 5 critical blockers + 15 medium/low gaps identified, comprehensive R11-R22 plan added |
|
||
| 2026-06 | Blocker 5 (`9a28b68ef`) | DMI struct extension: `bios_vendor`, `bios_date` added to `DmiInfo` + `DmiMatchRule` |
|
||
| 2026-06 | Gap 17 (`abce96f1e`) | `read_dmi_info()` logs `warn!` on first failure (rate-limited) |
|
||
| 2026-06 | Blocker 4 (`be95fea0`, base fork) | xhcid calls `lookup_xhci_controller_quirks_full` with DMI |
|
||
| 2026-06 | Blocker 2 (bootloader `259a621`, kernel `a4ba465`, acpid `fa91cee4`) | End-to-end SMBIOS → `/scheme/acpi/dmi` chain. Three forks: bootloader UEFI `find_smbios()` → kernel `SmbiosScheme` → acpid `dmi::parse_smbios_table()` → `/scheme/acpi/dmi` and `/scheme/acpi/dmi/{field}` |
|
||
| 2026-06 | Blocker 1 (`676af02e`, base fork) | pcid `PciConfigWriter` impl + `build_device_info` + `apply_pci_quirks` wired in `handle_parsed_header`. 12 unit tests in `pcid/src/quirks.rs::tests` (mock + dispatch + conversions + cap-list walker). `cargo test -p pcid` 12/12. |
|
||
| 2026-06 | Blocker 3 (`9f250dbe`, base fork) | usbhidd `log_usb_quirks` + `log_hid_quirks` at enumeration. 7 unit tests. `cargo test -p usbhidd` 7/7. |
|
||
| 2026-06 | Gap 15 (`98982cc2f`, amdgpu recipe) | Extracted `pci_*_quirk_flags` from `redox_stubs.c` into `redox_quirk_bridge.c`; removed `g_pci_quirk_flags` static; updated build script. |
|
||
| 2026-06 | Gap 10 (`a24cfe64c`, evdevd recipe) | `local/recipes/system/evdevd/source/src/quirks.rs` with `log_hid_quirks`; 4 unit tests. `cargo check` clean. |
|
||
| 2026-06 | Gap 12 (`1561767ac`, redbear-iwlwifi recipe) | `local/recipes/drivers/redbear-iwlwifi/source/src/quirks.rs` with `log_wifi_quirks`; 3 unit tests. Bypasses linux-kpi C FFI (private fields) and calls `lookup_pci_quirks` directly. |
|
||
| 2026-06 | R11 part 1 (`5d06b0fa0`, redox-driver-sys) | `AcpiQuirkFlags` (13 bits), `DmiAcpiQuirkRule`, `DMI_ACPI_QUIRK_RULES`, `load_dmi_acpi_quirks`, `apply_dmi_acpi_quirk_rules`, `ACPI_FLAG_NAMES`, `[[dmi_acpi_quirk]]` TOML parser. +2 unit tests. 122/122 tests pass. |
|
||
| 2026-06 | R11 part 2 (`e3c41b834`, redbear-quirks) | Four ACPI DMI TOML files (45-osi, 46-sleep, 47-button, 48-battery) with 18 DMI rules total from Linux 7.1 sources (`drivers/acpi/{osi,sleep,button,battery}.c`). |
|
||
| 2026-06 | R12 (`87ea8a9ac`, redox-driver-sys + redbear-quirks) | `DrmPanelOrientation` enum + 36-entry `50-drm-panel.toml` from Linux 7.1 `drm_panel_orientation_quirks.c`. Consumer in `redox-drm` deferred until Phase 4 KDE rotation lands. |
|
||
| 2026-06 | R13 (`00e1c9ea1`, redox-driver-sys + redbear-quirks) | `PlatformDmiQuirkFlags` (7 bits) + `PlatformSubsystem` enum + 31-entry `80-platform-x86.toml` covering touchscreen / tablet_mode / hotkey / accelerometer / battery for Framework, GPD, AYANEO, AYN, Dell, Lenovo, Asus, Valve, Chuwi, Acer. Consumer wiring deferred. |
|
||
| 2026-06 | R14 (`5caab8578`, redox-driver-sys + redbear-quirks) | `CpuBugFlags` (27 bits matching Linux X86_BUG_*) + `CpuId` struct + 14-entry `90-cpu-bugs.toml` covering Intel/AMD Spectre, MDS, TAA, L1TF, MMIO Stale, SRBDS, GDS, AMD TLB, AMD E400. Kernel-side consumer deferred. |
|
||
| 2026-06 | R15 (`57778e789`, redox-driver-sys + redbear-quirks) | `ClocksourceQuirkFlags` (4 bits) + `ClocksourceQuirkEntry` (vendor/device/revision range) + 3-entry `35-clocksource.toml` covering Intel PIIX4 / ICH4 / ServerWorks LE PMTMR. |
|
||
| 2026-06 | R17 (`9e7020bc5`, redox-driver-sys + redbear-quirks) | `ChipsetQuirkFlags` (10 bits) + `ChipsetQuirkEntry` (vendor/device/class/class_mask) + 11-entry `55-chipset-early.toml` covering NVIDIA / VIA / AMD K8 / ATI / Intel 0x3403/3405/3406 / Intel VGA / Intel Baytrail / Broadcom 4331 early-boot chipset init. |
|
||
| 2026-06 | R18 (`f0b2b01da`, redbear-quirks) | 25-entry `35-storage-extended.toml` covering JMicro, ServerWorks CSB5, ATI IXP/SBX00, AMD Hudson2/Bolton, Intel 82801CAM, Nvidia ION, Marvell 88SE, Intel PIIX, Samsung / Toshiba NVMe. |
|
||
| 2026-06 | R19 (`f0b2b01da`, redbear-quirks) | 23-entry `55-network.toml` covering RTL8xxx wireless (8192S/C/D, 8723A, 8812, 8172, 8178, 8179, 817C, B723, 8821, B822) + Broadcom TIGON3 (5700-5705) + RTL8169/8168/8105/8125. |
|
||
| 2026-06 | R20 (`f0b2b01da`, redox-driver-sys + redbear-quirks) | `UsbAudioQuirkFlags` (29 bits matching Linux 7.1 snd_usb_audio_quirk_flag_names) + `UsbAudioQuirkEntry` + 30-entry `60-usb-audio.toml` (Logitech / Microsoft / HP / Creative / AB13X-AB17X subset). |
|
||
| 2026-06 | R21 (`d78aa7f39`, redbear-quirks) | 4-entry `65-iommu-amd.toml` covering Dell Inspiron 7375, Latitude 5495, Acer Aspire A315-41, Lenovo IdeaPad 330S-15ARR. Reuses the R11 `[[dmi_acpi_quirk]]` table type. |
|
||
| 2026-06 | R16+R22 (`d980dc274`, redbear-quirks) | Two empty landing-pad TOML files (`95-mtrr-deferred.toml`, `99-bootparams-deferred.toml`) documenting that R16 (MTRR/PAT/NUMA) and R22 (boot parameters) are deferred because their Linux 7.1 sources are imperative handler code, not data tables. |
|
||
| 2026-06 | R7 audit (`ca9cd011a`) | Two findings from a comprehensive audit of the R0–R22 subsystem: (1) `cb_intel_ntb_bar_fix` was a no-op stub (cleared `PCI_COMMAND_MEMORY` and immediately restored it; the device never observed the transient clear). Replaced with the real Linux `quirk_intel_ntb` reads at config offsets 0xD0/0xD1. 3 new unit tests. (2) The `redbear-quirks` install script copied only 8 of 30 TOML files to `/etc/quirks.d/`, leaving all R11–R21 data tables inert at runtime. Replaced the explicit list with a glob so every `.toml` ships and future additions are picked up automatically. `cargo test --package redox-driver-sys`: 131/131. |
|
||
|
||
**Blocker status (2026-06-07):**
|
||
- ✅ Blocker 5 (DMI struct): RESOLVED
|
||
- ✅ Blocker 2 (acpid DMI producer): RESOLVED (full chain)
|
||
- ✅ Blocker 1 (pcid `PciConfigWriter` + QuirkAction loop): RESOLVED — every compiled-in PCI quirk now fires at pcid enumeration
|
||
- ✅ Blocker 3 (usbhidd HID/USB wiring): RESOLVED — `9f250dbe` on base fork
|
||
- 🚧 Blocker 4 (xhcid full lookup): PARTIAL — DMI lookup done at `be95fea0`; QuirkAction loop in xhcid still pending (the blocker on the iteration is now gone with Blocker 1, so this is reduced to a 1-2 day wiring task)
|
||
|
||
**Gap status (2026-06-07):**
|
||
- ✅ Gap 10 (evdevd HID wiring): RESOLVED
|
||
- ✅ Gap 11 (redox-drm GPU wiring): ALREADY RESOLVED (audit misread; `full.quirks()` is the lookup)
|
||
- ✅ Gap 12 (redbear-iwlwifi FFI wiring): RESOLVED
|
||
- ✅ Gap 15 (amdgpu stub removal): RESOLVED
|
||
|
||
**Test count progression:** 75 (R5) → 83 (R6) → 90 (R7-C) → 99 (R7-A/B) → 106 (R8) → 114 (R10) → 120 (Blocker 5) → 120 (Gap 17) → 120 (Blocker 4 N/A on host) → 128 (Blocker 2 acpid dmi tests) → 140 (Blocker 1 pcid 12 unit tests) → 147 (Blocker 3 usbhidd 7) → 150 (Gap 10 evdevd 4) → 153 (Gap 12 iwlwifi 3) → 155 (R11 part 1 ACPI DMI infra 2) → 156 (R12 panel orientation 1) → 157 (R13 platform subsystem 1) → 158 (R14 CPU bug match 1) → 159 (R15 clocksource match 1) → 160 (R17 chipset match 1) → 161 (R20 USB audio OR 1) → 164 (R7 audit intel_ntb_bar_fix 3) → **131 host-buildable redox-driver-sys unit tests + 13 acpid dmi + 12 pcid + 7 usbhidd + 4 evdevd + 3 iwlwifi = 170 host-OR-target tests** (131 in `redox-driver-sys` standalone; the rest are in the consumer trees that need their target environments to build).
|
||
|
||
**ALL phases R0-R22 RESOLVED OR DEFERRED.** R0-R10 from earlier sessions. R11 lands 18 ACPI DMI rules. R12 lands 36 DRM panel orientation rules. R13 lands 31 platform subsystem dispatch rules. R14 lands 14 CPU bug mitigation rules. R15 lands 3 PMTMR blacklist entries. R17 lands 11 early-boot chipset entries. R18 lands 25 storage entries. R19 lands 23 network entries. R20 lands 30 USB audio entries. R21 lands 4 AMD IOMMU DMI entries. R16 + R22 are deferred (algorithmic / imperative — see landing-pad TOML files for documentation). Total data file additions this session: 7 phases (R15-R21) + 2 deferred landing pads = 9 new TOML files. Consumer wiring is follow-up per phase.
|
||
|
||
## Overview
|
||
|
||
Red Bear OS implements a data-driven hardware quirks system inspired by Linux's
|
||
PCI/USB/DMI quirk infrastructure, adapted for Redox's microkernel/userspace-driver
|
||
architecture.
|
||
|
||
Quirks handle known hardware defects that cannot be fixed by correct driver code
|
||
alone. They override default driver behavior for specific devices, revisions, or
|
||
entire system models.
|
||
|
||
For the current follow-up cleanup and integration roadmap, see
|
||
`local/docs/QUIRKS-IMPROVEMENT-PLAN.md`.
|
||
|
||
## Architecture
|
||
|
||
```
|
||
Driver probes device
|
||
└─ PciDeviceInfo::quirks()
|
||
├─ Layer 1: Compiled-in table (pci_table.rs, usb_table.rs)
|
||
├─ Layer 2: TOML files from /etc/quirks.d/*.toml
|
||
└─ Layer 3: DMI-based system rules
|
||
└─ Returns: PciQuirkFlags (bitwise OR of all matching entries)
|
||
```
|
||
|
||
All matching entries accumulate via bitwise OR, so broad rules (e.g., "all AMD GPUs
|
||
need firmware") and narrow rules (e.g., "this specific revision has broken MSI-X")
|
||
compose naturally.
|
||
|
||
## Quirk Sources
|
||
|
||
### 1. Compiled-in Tables
|
||
|
||
Location: `local/recipes/drivers/redox-driver-sys/source/src/quirks/`
|
||
|
||
Critical quirks that must be available before the root filesystem is mounted.
|
||
Defined as `const` arrays in Rust:
|
||
|
||
- `pci_table.rs` — `PCI_QUIRK_TABLE: &[PciQuirkEntry]`
|
||
- `usb_table.rs` — `USB_QUIRK_TABLE: &[UsbQuirkEntry]`
|
||
|
||
Each entry specifies:
|
||
- Vendor/device/subsystem match fields (0xFFFF = wildcard)
|
||
- Revision range (lo..hi inclusive)
|
||
- Class code mask and match value
|
||
- `PciQuirkFlags` bitmask
|
||
|
||
### 2. TOML Quirk Files
|
||
|
||
Location: `/etc/quirks.d/*.toml` (shipped by the `redbear-quirks` package)
|
||
|
||
Extensible at runtime without recompiling drivers. Format:
|
||
|
||
```toml
|
||
[[pci_quirk]]
|
||
vendor = 0x1002
|
||
device = 0x73BF
|
||
flags = ["need_firmware", "no_d3cold"]
|
||
|
||
[[pci_quirk]]
|
||
vendor = 0x10EC
|
||
device = 0x8125
|
||
flags = ["no_aspm"]
|
||
|
||
[[usb_quirk]]
|
||
vendor = 0x0A12
|
||
flags = ["bad_descriptor", "no_set_config"]
|
||
```
|
||
|
||
Files are loaded alphabetically from `/etc/quirks.d/`. Recommended naming:
|
||
`00-core.toml`, `10-gpu.toml`, `20-usb.toml`, `30-net.toml`, `40-storage.toml`,
|
||
`50-system.toml`.
|
||
|
||
Runtime TOML loading now also supports `[[dmi_system_quirk]]` entries. Those
|
||
entries are applied when `acpid` is running and serving live DMI data from
|
||
`/scheme/acpi/dmi`.
|
||
|
||
### 3. DMI-Based System Quirks
|
||
|
||
Match by SMBIOS fields (sys_vendor, board_name, product_name) to apply
|
||
system-wide quirk overrides. Eight compiled-in rules exist for known systems,
|
||
and `/etc/quirks.d/*.toml` can now add `[[dmi_system_quirk]]` rules with
|
||
`match.*` keys plus optional `pci_vendor` / `pci_device` selectors. Runtime use
|
||
now reads live SMBIOS strings from `acpid` via `/scheme/acpi/dmi`.
|
||
|
||
## Available Quirk Flags
|
||
|
||
### PCI Quirks (PciQuirkFlags)
|
||
|
||
| Flag | Meaning |
|
||
|------|---------|
|
||
| `NO_MSI` | MSI capability broken; use MSI-X or legacy |
|
||
| `NO_MSIX` | MSI-X capability broken; use MSI or legacy |
|
||
| `FORCE_LEGACY_IRQ` | Must use INTx interrupts |
|
||
| `NO_PM` | Disable all power management |
|
||
| `NO_D3COLD` | Cannot recover from D3cold power state |
|
||
| `NO_ASPM` | Active State Power Management broken |
|
||
| `NEED_IOMMU` | Requires IOMMU isolation |
|
||
| `NO_IOMMU` | Must NOT be behind IOMMU |
|
||
| `DMA_32BIT_ONLY` | Only supports 32-bit DMA |
|
||
| `RESIZE_BAR` | BAR sizing reports incorrectly |
|
||
| `DISABLE_BAR_SIZING` | Use firmware BAR values as-is |
|
||
| `NEED_FIRMWARE` | Requires firmware files to initialize |
|
||
| `DISABLE_ACCEL` | Disable hardware acceleration |
|
||
| `FORCE_VRAM_ONLY` | No GTT/system memory fallback |
|
||
| `NO_USB3` | Force USB 2.0 mode |
|
||
| `RESET_DELAY_MS` | Needs extra post-reset delay |
|
||
| `NO_STRING_FETCH` | Do not fetch string descriptors |
|
||
| `BAD_EEPROM` | EEPROM unreliable; use hardcoded values |
|
||
| `BUS_MASTER_DELAY` | Needs delay after bus-master enable |
|
||
| `WRONG_CLASS` | Reports incorrect class code |
|
||
| `BROKEN_BRIDGE` | PCI bridge forwarding bug |
|
||
| `NO_RESOURCE_RELOC` | Do not relocate PCI resources |
|
||
|
||
### USB Quirks (UsbQuirkFlags)
|
||
|
||
| Flag | Meaning |
|
||
|------|---------|
|
||
| `NO_STRING_FETCH` | Do not fetch string descriptors |
|
||
| `RESET_DELAY` | Needs extra reset delay |
|
||
| `NO_USB3` | Disable USB 3.x |
|
||
| `NO_SET_CONFIG` | Cannot handle SetConfiguration |
|
||
| `NO_SUSPEND` | Broken suspend/resume |
|
||
| `NEED_RESET` | Needs reset after probe |
|
||
| `BAD_DESCRIPTOR` | Wrong descriptor sizes |
|
||
| `NO_LPM` | Disable Link Power Management |
|
||
| `NO_U1U2` | Disable U1/U2 link transitions |
|
||
|
||
## Driver Integration
|
||
|
||
### For Rust Drivers (using redox-driver-sys)
|
||
|
||
```rust
|
||
use redox_driver_sys::quirks::PciQuirkFlags;
|
||
|
||
fn probe(info: &PciDeviceInfo) {
|
||
let quirks = info.quirks();
|
||
|
||
if quirks.contains(PciQuirkFlags::NO_MSIX) {
|
||
// Skip MSI-X, try MSI or legacy
|
||
}
|
||
|
||
if quirks.contains(PciQuirkFlags::NEED_FIRMWARE) {
|
||
// Load firmware before initializing device
|
||
}
|
||
|
||
if quirks.contains(PciQuirkFlags::DISABLE_ACCEL) {
|
||
// Skip hardware probe, let software renderer take over
|
||
return Err(DriverError::QuirkDisabled);
|
||
}
|
||
}
|
||
```
|
||
|
||
### For C Drivers (using linux-kpi)
|
||
|
||
The `linux-kpi` crate exposes two FFI functions for C drivers to query quirks:
|
||
|
||
```c
|
||
#include <linux/pci.h>
|
||
|
||
// After pci_enable_device() in your probe callback:
|
||
static int my_probe(struct pci_dev *dev, const struct pci_device_id *id)
|
||
{
|
||
u64 quirks = pci_get_quirk_flags(dev);
|
||
|
||
if (quirks & PCI_QUIRK_NO_MSIX) {
|
||
// Skip MSI-X, fall back to MSI or legacy IRQ
|
||
}
|
||
|
||
if (pci_has_quirk(dev, PCI_QUIRK_NEED_FIRMWARE)) {
|
||
// Load firmware before initializing hardware
|
||
}
|
||
}
|
||
```
|
||
|
||
The amdgpu Redox glue/runtime path is now the first in-tree production C consumer
|
||
of this interface: it queries `pci_get_quirk_flags()` during AMD DC init, logs the
|
||
resulting IRQ expectations, and treats `PCI_QUIRK_NEED_FIRMWARE` as a hard failure
|
||
instead of a warn-and-continue path when that quirk is active.
|
||
|
||
### For USB Storage Drivers (usbscsid)
|
||
|
||
The USB SCSI driver (`drivers/storage/usbscsid`) carries its own self-contained quirk
|
||
module (`src/quirks.rs`) that reads `[[usb_storage_quirk]]` entries from `/etc/quirks.d/*.toml`.
|
||
It does not depend on `redox-driver-sys` — the quirk lookup is inline.
|
||
|
||
At daemon startup, `usbscsid` extracts vendor/product IDs from the USB device descriptor
|
||
and looks up matching quirks from both the compiled-in table and TOML files. The resulting
|
||
`UsbStorageQuirkFlags` propagate to both the BOT transport and the SCSI command layer.
|
||
|
||
Active behavioral flags and their injection points:
|
||
|
||
| Flag | Layer | Effect |
|
||
|------|-------|--------|
|
||
| `IGNORE_RESIDUE` | BOT (`bot.rs`) | Suppresses CSW data_residue; avoids false short-transfer errors |
|
||
| `FIX_CAPACITY` | SCSI (`scsi/mod.rs`) | Subtracts 1 from READ CAPACITY(10) block count |
|
||
| `SINGLE_LUN` | BOT (`bot.rs`) | Enforces LUN=0 in CBW |
|
||
| `MAX_SECTORS_64` | SCSI (`scsi/mod.rs`) | Clamps transfer_len to 64 sectors per command |
|
||
| `INITIAL_READ10` | SCSI (`scsi/mod.rs`) | Uses READ(10)/WRITE(10) instead of READ(16)/WRITE(16) |
|
||
|
||
TOML format for storage quirks:
|
||
|
||
```toml
|
||
[[usb_storage_quirk]]
|
||
vendor = 0x03EB
|
||
product = 0x2002
|
||
revision = "0100-0100"
|
||
manufacturer = "ATMEL"
|
||
description = "SND1 Storage"
|
||
flags = ["ignore_residue"]
|
||
```
|
||
|
||
The full 214-entry table lives in `quirks.d/30-storage.toml`, mined from Linux 7.0's
|
||
`drivers/usb/storage/unusual_devs.h`.
|
||
|
||
Available C quirk flag macros (defined in `linux/pci.h`):
|
||
|
||
| Macro | Bit | Meaning |
|
||
|-------|-----|---------|
|
||
| `PCI_QUIRK_NO_MSI` | 0 | MSI interrupts broken |
|
||
| `PCI_QUIRK_NO_MSIX` | 1 | MSI-X interrupts broken |
|
||
| `PCI_QUIRK_FORCE_LEGACY` | 2 | Must use legacy INTx |
|
||
| `PCI_QUIRK_NO_PM` | 3 | Power management broken |
|
||
| `PCI_QUIRK_NO_D3COLD` | 4 | D3cold state broken |
|
||
| `PCI_QUIRK_NO_ASPM` | 5 | ASPM broken |
|
||
| `PCI_QUIRK_NEED_IOMMU` | 6 | Requires IOMMU |
|
||
| `PCI_QUIRK_NO_IOMMU` | 7 | Must NOT use IOMMU |
|
||
| `PCI_QUIRK_DMA_32BIT_ONLY` | 8 | DMA limited to 32-bit |
|
||
| `PCI_QUIRK_RESIZE_BAR` | 9 | BAR sizing reports incorrectly |
|
||
| `PCI_QUIRK_DISABLE_BAR_SIZING` | 10 | Use firmware BAR values as-is |
|
||
| `PCI_QUIRK_NEED_FIRMWARE` | 11 | Requires firmware load |
|
||
| `PCI_QUIRK_DISABLE_ACCEL` | 12 | Disable hardware acceleration |
|
||
| `PCI_QUIRK_FORCE_VRAM_ONLY` | 13 | No GTT/system memory fallback |
|
||
| `PCI_QUIRK_NO_USB3` | 14 | Force USB 2.0 mode |
|
||
| `PCI_QUIRK_RESET_DELAY_MS` | 15 | Needs extra post-reset delay |
|
||
| `PCI_QUIRK_NO_STRING_FETCH` | 16 | Do not fetch string descriptors |
|
||
| `PCI_QUIRK_BAD_EEPROM` | 17 | EEPROM unreliable |
|
||
| `PCI_QUIRK_BUS_MASTER_DELAY` | 18 | Needs delay after bus-master enable |
|
||
| `PCI_QUIRK_WRONG_CLASS` | 19 | Reports incorrect class code |
|
||
| `PCI_QUIRK_BROKEN_BRIDGE` | 20 | PCI bridge forwarding bug |
|
||
| `PCI_QUIRK_NO_RESOURCE_RELOC` | 21 | Do not relocate PCI resources |
|
||
|
||
## Adding New Quirks
|
||
|
||
### To the compiled-in table
|
||
|
||
Edit `local/recipes/drivers/redox-driver-sys/source/src/quirks/pci_table.rs`:
|
||
|
||
```rust
|
||
const F_MY_FLAGS: PciQuirkFlags = PciQuirkFlags::from_bits_truncate(
|
||
PciQuirkFlags::NEED_FIRMWARE.bits() | PciQuirkFlags::NO_ASPM.bits(),
|
||
);
|
||
|
||
PciQuirkEntry {
|
||
vendor: 0xVENDOR,
|
||
device: 0xDEVICE,
|
||
flags: F_MY_FLAGS,
|
||
..PciQuirkEntry::WILDCARD
|
||
},
|
||
```
|
||
|
||
### To a TOML file
|
||
|
||
Create or edit a file in `local/recipes/system/redbear-quirks/source/quirks.d/`:
|
||
|
||
```toml
|
||
[[pci_quirk]]
|
||
vendor = 0xVENDOR
|
||
device = 0xDEVICE
|
||
flags = ["need_firmware", "no_aspm"]
|
||
|
||
[[usb_quirk]]
|
||
vendor = 0xVENDOR
|
||
product = 0xPRODUCT
|
||
flags = ["no_lpm", "need_reset"]
|
||
|
||
[[usb_storage_quirk]]
|
||
vendor = 0xVENDOR
|
||
product = 0xPRODUCT
|
||
flags = ["ignore_residue", "fix_capacity"]
|
||
|
||
[[dmi_system_quirk]]
|
||
pci_vendor = 0xVENDOR
|
||
flags = ["disable_accel"]
|
||
match.sys_vendor = "Example Vendor"
|
||
match.product_name = "Example Model"
|
||
|
||
[[acpi_table_quirk]]
|
||
signature = "DMAR"
|
||
match.sys_vendor = "Example Vendor"
|
||
match.product_name = "Example Model"
|
||
```
|
||
|
||
### Choosing where to add
|
||
|
||
- **Compiled-in**: Boot-critical quirks, anything needed before root mount
|
||
- **TOML**: Everything else — easier to update, no recompilation needed
|
||
- **DMI rule**: System-specific workarounds that apply to specific laptop models
|
||
|
||
## File Layout
|
||
|
||
```
|
||
local/recipes/drivers/redox-driver-sys/source/src/quirks/
|
||
├── mod.rs # Public API: lookup_pci_quirks(), PciQuirkFlags, PciQuirkEntry
|
||
├── pci_table.rs # Compiled-in PCI quirk table
|
||
├── usb_table.rs # Compiled-in USB quirk table
|
||
├── dmi.rs # DMI/SMBIOS matching and system-level quirk rules
|
||
└── toml_loader.rs # /etc/quirks.d/*.toml parser
|
||
|
||
local/recipes/system/redbear-quirks/
|
||
├── recipe.toml # Custom build: copies TOML files to /etc/quirks.d/
|
||
└── source/quirks.d/
|
||
├── 00-core.toml
|
||
├── 10-gpu.toml
|
||
├── 20-usb.toml
|
||
├── 30-net.toml
|
||
├── 40-storage.toml
|
||
└── 50-system.toml
|
||
```
|
||
|
||
## Relationship to Linux Quirks
|
||
|
||
| Linux Pattern | Red Bear Equivalent |
|
||
|---------------|-------------------|
|
||
| `DECLARE_PCI_FIXUP_HEADER(v, d, fn)` | `PciQuirkEntry { vendor: v, device: d, flags: ... }` |
|
||
| `pci_dev->dev_flags \|= PCI_DEV_FLAGS_NO_BUS_RESET` | No direct equivalent — future flag candidate |
|
||
| `USB_QUIRK_STRING_FETCH` | `UsbQuirkFlags::NO_STRING_FETCH` |
|
||
| `DMI_MATCH(DMI_SYS_VENDOR, "Lenovo")` | `DmiMatchRule { sys_vendor: Some("Lenovo") }` |
|
||
| `acpi_black_listed()` | `[[acpi_table_quirk]] signature = "...."` with skip semantics in `acpid` |
|
||
|
||
## Testing
|
||
|
||
Run quirks unit tests:
|
||
|
||
```bash
|
||
cd local/recipes/drivers/redox-driver-sys/source
|
||
cargo test
|
||
```
|
||
|
||
## Implementation Status
|
||
|
||
| Phase | Component | Status |
|
||
|-------|-----------|--------|
|
||
| Q1 | Core types (PciQuirkFlags, PciQuirkEntry, UsbQuirkFlags) | ✅ Done |
|
||
| Q1 | Compiled-in PCI/USB quirk tables | ✅ Done |
|
||
| Q1 | Lookup API (quirks(), has_quirk()) | ✅ Done |
|
||
| Q1 | Subsystem (subvendor/subdevice) fields | ✅ Done — compiled and TOML PCI matching both apply subsystem selectors |
|
||
| Q2 | TOML loader for /etc/quirks.d/ | ✅ Done |
|
||
| Q2 | redbear-quirks data package | ✅ Done |
|
||
| Q3 | redox-drm integration (MSI-X/MSI/legacy + DISABLE_ACCEL) | ✅ Done |
|
||
| Q3 | xhcid PCI controller quirks (interrupt + reset delay) | ✅ Done |
|
||
| Q3 | xhcid USB device quirks (descriptor/configuration/BOS handling) | ✅ Done |
|
||
| Q3 | pcid-spawner quirk passthrough | ✅ Done |
|
||
| Q3 | linux-kpi quirk flag bridge | ✅ Done |
|
||
| Q3 | amdgpu linux-kpi quirk consumption | ✅ Done |
|
||
| Q3 | redbear-info --quirks display | ✅ Done |
|
||
| Q4 | DMI/SMBIOS compiled-in rules | ✅ Done — 8 system rules (const table) |
|
||
| Q4 | DMI/SMBIOS TOML runtime loading | ✅ Done — `dmi_system_quirk` uses live `/scheme/acpi/dmi` data from `acpid` |
|
||
| Q4 | ACPI table blacklist/override | ✅ Done — `acpid` applies `[[acpi_table_quirk]]` skip rules during table load |
|
||
| Q5 | lspci quirk display | ✅ Done — shows active quirks per device |
|
||
| Q5 | lsusb quirk display | ✅ Done — shows active quirks per device |
|
||
| Q5 | Linux quirk extraction tool | ✅ Script exists — PCI mode uses heuristic name matching, USB mode works for table entries |
|
||
|
||
Quirk flags span data definition, infrastructure wiring, and driver consumption.
|
||
Most flags are defined but not yet consumed at runtime — the tables below show
|
||
the honest breakdown.
|
||
|
||
**Flags consumed by drivers (runtime checks in production code):**
|
||
- redox-drm: `NO_MSIX`, `NO_MSI`, `FORCE_LEGACY_IRQ`, `DISABLE_ACCEL` (interrupt setup + driver probe)
|
||
- xhcid: `RESET_DELAY_MS`, `NO_MSI`, `NO_MSIX`, `FORCE_LEGACY_IRQ` (interrupt selection + port reset delay)
|
||
- xhcid (USB device path): `NO_STRING_FETCH`, `BAD_DESCRIPTOR`, `RESET_DELAY`, `HUB_SLOW_RESET`, `NO_BOS`, `SHORT_SET_ADDR_TIMEOUT`, `FORCE_ONE_CONFIG`, `HONOR_BNUMINTERFACES`, `DELAY_CTRL_MSG`, `NO_SET_CONFIG`, `NO_SET_INTF`, `NEED_RESET`, `NO_SUSPEND` (enumeration/configuration/BOS/runtime recovery plus suspend gating)
|
||
- amdgpu: startup firmware requirement enforced at the Rust DRM boundary, with real quirk-aware runtime logging for `NO_ASPM`, `NEED_IOMMU`, `NO_MSI`, `NO_MSIX`
|
||
|
||
**Infrastructure (data flows, reporting, and partial integration):**
|
||
- pcid-spawner: computes `PCI_QUIRK_FLAGS` by calling the canonical `redox-driver-sys` lookup on synthesized `PciDeviceInfo`, then passes the env var onward
|
||
- linux-kpi: `pci_get_quirk_flags()` / `pci_has_quirk()` C FFI is available for C drivers and is now consumed by the Red Bear amdgpu path
|
||
- redbear-info: `--quirks` reads `/etc/quirks.d/*.toml` and reports configured PCI/USB/DMI entries
|
||
- lspci: shows active quirk flags per PCI device (via redox-driver-sys lookup)
|
||
- lsusb: shows active quirk flags per USB device (via redox-driver-sys lookup)
|
||
- DMI compiled-in rules: 8 entries match systems by vendor/product/board (served through `acpid` at `/scheme/acpi/dmi`)
|
||
|
||
**Observed/logged but not yet strongly enforced in runtime policy:**
|
||
- xhcid `NO_SUSPEND` is now enforced and `usbhubd` mirrors USB 2 hub-port suspend state into child xhcid devices, but suspend policy origination and USB 3 link-state coordination are still pending in the broader hub/power-management layer
|
||
- `NO_ASPM`, `NEED_IOMMU`, `NO_MSI`, `NO_MSIX` in the amdgpu path are surfaced in quirk-aware logs before broader driver policy exists.
|
||
|
||
**Defined but not yet consumed by any real driver path:**
|
||
- `NO_PM`, `NO_D3COLD`, `DMA_32BIT_ONLY`, `BUS_MASTER_DELAY`, `NO_IOMMU`, etc.
|
||
|
||
`firmware-loader` itself does not interpret `NEED_FIRMWARE`; that policy is now enforced at the Rust-side DRM startup boundary instead.
|
||
|
||
Active Red Bear images that include `redbear-device-services` already ship the upstream
|
||
`redbear-firmware` bundle into `/lib/firmware`. The bounded Intel DMC work therefore selects and
|
||
requires the right startup blobs from that shipped firmware set, rather than depending on the user
|
||
to fetch firmware at runtime.
|
||
|
||
For early xhcid timing quirks, `[[usb_quirk]]` entries may also carry `port = "1.2.3"` selectors.
|
||
Those selectors are used only for pre-descriptor timing flags (`RESET_DELAY`, `HUB_SLOW_RESET`,
|
||
`SHORT_SET_ADDR_TIMEOUT`) where vendor/product IDs are not yet available.
|
||
|
||
**Remaining infrastructure work:**
|
||
- none in the current quirks scope
|
||
|
||
`pcid-spawner` now brokers quirks through the canonical `redox-driver-sys` lookup instead of carrying a separate in-tree PCI quirk engine.
|
||
|
||
## Gap Analysis — Cross-Reference with Linux 7.1
|
||
|
||
Linux 7.1 (`local/reference/linux-7.1/`) carries a vast quirk infrastructure:
|
||
|
||
| Subsystem | File | Entries/Flags | Description |
|
||
|-----------|------|--------------|-------------|
|
||
| PCI core | `drivers/pci/quirks.c` | 701 entries, 129 handlers | Device/vendor-specific PCI fixups |
|
||
| PCI early | `arch/x86/kernel/early-quirks.c` | 812 lines | Early boot PCI fixups |
|
||
| PCI controllers | `drivers/pci/controller/*.c` | ~50 entries | Controller-specific quirks |
|
||
| USB device | `drivers/usb/core/quirks.c` | Dynamic (module param), 19 flags | USB device enumeration quirks |
|
||
| USB storage | `drivers/usb/storage/unusual_devs.h` | 323 entries | USB mass storage unusual devices |
|
||
| xHCI host | `drivers/usb/host/xhci.h` + `xhci-pci.c` | 50 flags, ~50 entries | xHCI controller quirks |
|
||
| **HID** | `drivers/hid/hid-quirks.c` | **500 entries, 24 flags** | Human Interface Device quirks |
|
||
| AMD GPU | `drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c` | 308 device IDs | AMD GPU ASIC table |
|
||
| Intel GPU | `drivers/gpu/drm/i915/i915_pci.c` | ~78 families | Intel GPU device table |
|
||
| DRM panels | `drivers/gpu/drm/drm_panel_orientation_quirks.c` | 22 DMI entries | Laptop panel rotation quirks |
|
||
| ACPI OSI | `drivers/acpi/osi.c` | 20 DMI entries | _OSI interface blacklists |
|
||
| ACPI EC | `drivers/acpi/ec.c` | ~8 DMI entries | Embedded controller quirks |
|
||
| ACPI utils | `drivers/acpi/x86/utils.c` | 8 DMI entries | x86-specific ACPI overrides |
|
||
| ACPI blacklist | `drivers/acpi/x86/blacklist.c` | 3 DMI entries | Broken ACPI table blacklist |
|
||
| ACPI sleep | `drivers/acpi/sleep.c` | 5 DMI entries | Suspend/resume quirks |
|
||
| ACPI video | `drivers/acpi/video_detect.c` | 5 DMI entries | Video/ backlight detection |
|
||
| ACPI PCI IRQ | `drivers/acpi/pci_irq.c` | 4 DMI entries | PCI interrupt routing quirks |
|
||
| ACPI battery | `drivers/acpi/battery.c` | 4 DMI entries | Battery status quirks |
|
||
| ACPI button | `drivers/acpi/button.c` | 2 DMI entries | Power button quirks |
|
||
| Input (atkbd) | `drivers/input/keyboard/atkbd.c` | 4 DMI entries | Keyboard set-rate quirks |
|
||
| PCI VPD | `drivers/pci/vpd.c` | Several | Vital Product Data quirks |
|
||
|
||
### Additional Linux Quirk Subsystems (Previously Uncataloged)
|
||
|
||
The following quirk files exist in Linux 7.1 beyond the core subsystems listed above:
|
||
|
||
| Subsystem | File | Notes |
|
||
|-----------|------|-------|
|
||
| USB host PCI | `drivers/usb/host/pci-quirks.c` | USB controller PCI config quirks |
|
||
| Intel GPU display | `drivers/gpu/drm/i915/display/intel_quirks.c` | i915 panel/display DMI quirks |
|
||
| AMD display | `drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_quirks.c` | AMD DM DMI quirks |
|
||
| GPIO ACPI | `drivers/gpio/gpiolib-acpi-quirks.c` | GPIO ACPI DMI overrides |
|
||
| AMD PMC | `drivers/platform/x86/amd/pmc/pmc-quirks.c` | AMD power management quirks |
|
||
| Intel INT3472 | `drivers/platform/x86/intel/int3472/discrete_quirks.c` | Intel camera sensor quirks |
|
||
| Marvell WiFi | `drivers/net/wireless/marvell/mwifiex/pcie_quirks.c` | WiFi PCI quirks |
|
||
| MMC | `drivers/mmc/core/quirks.h` | SD/eMMC device quirks |
|
||
| Thunderbolt | `drivers/thunderbolt/quirks.c` | Thunderbolt device quirks |
|
||
| SoundWire | `drivers/soundwire/dmi-quirks.c` | SoundWire DMI quirks |
|
||
| I2C HID | `drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c` | I2C HID DMI quirks |
|
||
| AMD IOMMU | `drivers/iommu/amd/quirks.c` | AMD IOMMU quirks |
|
||
| PnP | `drivers/pnp/quirks.c` | Plug-and-play quirks |
|
||
|
||
Most of these are device-specific DMI rules or vendor-specific PCI quirks. Red Bear does
|
||
not need to implement all of these — focus on subsystems that match target hardware:
|
||
GPU (i915, AMD DM), USB host, Thunderbolt (if supporting TB docks), and I2C HID (for
|
||
laptop keyboards/trackpads).
|
||
|
||
**Total across all subsystems: ~2,200+ quirk entries, ~60+ unique DMI rules,
|
||
~100+ unique flags across PCI/USB/HID/xHCI/ACPI.**
|
||
|
||
Red Bear OS uses a **data-driven bitmask approach** rather than imperative handler
|
||
functions — the right design for a microkernel where drivers can't patch PCI config
|
||
space arbitrarily. The gap is in **quirk data volume, flag coverage, subsystem
|
||
coverage, and driver enforcement depth**, not in architectural capability.
|
||
|
||
## Platform/x86 DMI Quirks — The Largest Missing Category
|
||
|
||
Linux 7.1's `drivers/platform/x86/` directory contains **61 files with DMI-based quirks**, totaling **1153+ DMI entries**. This is the single largest quirk category by entry count in Linux — and the plan has ZERO coverage of it.
|
||
|
||
These quirks handle:
|
||
- Laptop vendor-specific behavior (Acer, ASUS, Dell, HP, Lenovo, MSI, Samsung, Sony, Toshiba, Fujitsu, Huawei, Xiaomi)
|
||
- Touchscreen input behavior (GPD, Chuwi, OneMix, Lenovo Miix, Steam Deck)
|
||
- Tablet-specific power management
|
||
- Hardware-monitor (sensor) behavior
|
||
- AMD-specific PMC (Power Management Controller) quirks
|
||
- Intel HID (Human Interface Device) tablet quirks
|
||
- Vendor-specific hotkeys, LEDs, backlight control
|
||
- Hardware switch routing (Wi-Fi, Bluetooth, WWAN)
|
||
|
||
### Top Platform/x86 DMI Files by Entry Count
|
||
|
||
| File | DMI Entries | Purpose |
|
||
|------|-------------|---------|
|
||
| `touchscreen_dmi.c` | 208 | Touchscreen input quirks (GPD, Chuwi, OneMix, etc.) |
|
||
| `asus-nb-wmi.c` | 90 | ASUS notebook hotkey/LED/WMI quirks |
|
||
| `acer-wmi.c` | 71 | Acer laptop WMI quirks |
|
||
| `amd/pmc/pmc-quirks.c` | 69 | AMD PMC power management quirks |
|
||
| `dell/dell-laptop.c` | 61 | Dell laptop hardware behavior |
|
||
| `uniwill/uniwill-acpi.c` | 54 | Uniwill-based laptop quirks |
|
||
| `x86-android-tablets/dmi.c` | 53 | Android tablet DMI quirks |
|
||
| `hp/hp_accel.c` | 48 | HP laptop accelerometer quirks |
|
||
| `alienware-wmi-wmax.c` | 38 | Alienware gaming laptop |
|
||
| `intel/hid.c` | 33 | Intel HID tablet quirks |
|
||
| `hdaps.c` | 32 | ThinkPad accelerometer |
|
||
| `msi-laptop.c` | 32 | MSI laptop quirks |
|
||
|
||
### Red Bear OS Position
|
||
|
||
Red Bear has zero coverage of platform/x86 DMI quirks. For desktop/server use, most of these are laptop-specific and don't apply. For laptop/embedded use (GPD, Steam Deck, Framework), many are critical for:
|
||
- Correct backlight control
|
||
- Touchscreen input (no input without these on many tablets)
|
||
- Power button behavior
|
||
- Wireless hardware switch handling
|
||
- Battery status reporting
|
||
|
||
### Action: Phase R13 (Laptop/Embedded DMI Quirks)
|
||
|
||
**Priority:** MEDIUM (defer until laptop/tablet support is a target)
|
||
|
||
**Source files:** `drivers/platform/x86/**/*.c` (61 files)
|
||
|
||
**Sub-tasks:**
|
||
1. Decide target devices: focus on AMD64 desktop + Framework laptop + GPD/AYANEO handhelds
|
||
2. Mine `touchscreen_dmi.c` (208 entries) — needed for any laptop/tablet with touchscreen
|
||
3. Mine `amd/pmc/pmc-quirks.c` (69 entries) — needed for AMD laptops
|
||
4. Mine `dell/dell-laptop.c` (61 entries) — needed for Dell hardware
|
||
5. Mine `intel/hid.c` (33 entries) — needed for Intel tablet sensors
|
||
6. Create `quirks.d/80-platform-x86.toml` for runtime data
|
||
7. Add `PlatformDmiQuirks` lookup function in `mod.rs`
|
||
8. Wire into inputd, pcid, acpid as appropriate
|
||
|
||
## CPU Bug Mitigation Infrastructure (Spectre, MDS, TAA, RFDS, SRBDS, GDS, RETBleed, SRSO, ITS)
|
||
|
||
Linux 7.1's `arch/x86/kernel/cpu/bugs.c` contains **20+ CPU bug mitigation systems** for speculative execution vulnerabilities discovered since 2017. These are NOT device-specific quirks — they are CPU model/family-specific security mitigations.
|
||
|
||
### Linux Mitigation Categories
|
||
|
||
| Mitigation | CPU Affected | Linux Mechanism |
|
||
|------------|--------------|-----------------|
|
||
| Spectre v1 | All | Bounds check bypass — no flag, always-on |
|
||
| Spectre v2 | All | Retpolines, IBRS, IBPB, STIBP, RSB filling |
|
||
| Meltdown | Intel pre-Ivy-Bridge | Page table isolation (KPTI) |
|
||
| MDS | Intel | Microcode-based mitigation |
|
||
| TAA (TSX Async Abort) | Intel with TSX | TSX disable + microcode |
|
||
| MMIO Stale Data | Intel | Microcode-based mitigation |
|
||
| RFDS (Register File Data Sampling) | Intel Atom | Microcode-based |
|
||
| SRBDS (Special Register Buffer Data Sampling) | Intel | Microcode-based |
|
||
| GDS (Gather Data Sampling) | Intel | Microcode-based |
|
||
| RETBleed | AMD Zen1/Zen2, Intel | Microcode-based mitigation |
|
||
| SRSO (Speculative Return Stack Overflow) | AMD Zen3/Zen4 | SMM-related fixup |
|
||
| ITS (Indirect Target Selection) | Intel | Microcode-based |
|
||
| SSBD (Speculative Store Bypass Disable) | All | Microcode + software |
|
||
| L1D flush | All | Software-based |
|
||
| Spectre v2 user-mode | All | IBPB/STIBP user-mode |
|
||
| Cross-Thread TLE | Intel | Microcode-based |
|
||
|
||
### Boot Parameters
|
||
|
||
Linux provides 20+ boot parameters to control mitigation:
|
||
- `spectre_v2=`, `spectre_v2_user=`
|
||
- `mds=`, `tsx_async_abort=`, `mmio_stale_data=`
|
||
- `l1d_flush=`, `srbds=`, `gather_data_sampling=`
|
||
- `retbleed=`, `spec_ctrl=`, `ssbd=`, `tsx=`
|
||
- `mitigations=`
|
||
|
||
### Red Bear OS Position
|
||
|
||
Red Bear has zero CPU bug mitigation infrastructure. The Redox kernel fork does not implement any speculative execution vulnerability mitigations. This is a CRITICAL gap for security-sensitive deployments.
|
||
|
||
### Action: Phase R14 (CPU Bug Mitigation Infrastructure)
|
||
|
||
**Priority:** CRITICAL (security)
|
||
|
||
**Source files:** `arch/x86/kernel/cpu/bugs.c`, `arch/x86/kernel/cpu/intel.c`, `arch/x86/kernel/cpu/amd.c`
|
||
|
||
**Sub-tasks:**
|
||
1. Create `CpuBugFlags` bitflags type in kernel `redox-driver-sys` or in the kernel fork
|
||
2. Create `cpu_bug_table.rs` with per-CPU-model detection
|
||
3. Implement `cpu_has_bug(bug: CpuBug) -> bool` in kernel
|
||
4. Wire mitigations into:
|
||
- Page table isolation (KPTI)
|
||
- IBPB/STIBP on context switch
|
||
- MDS/MMIO/RFDS/SRBDS clear-on-return
|
||
- Microcode version detection (for Intel mitigations requiring microcode)
|
||
5. Add boot parameters: `redbear.mitigations=`, `redbear.spectre_v2=`, etc.
|
||
6. Add mitigations to `redbear-info` output for transparency
|
||
7. Document security model in `local/docs/SECURITY-MODEL.md`
|
||
|
||
## TSC, Timer, HPET, and PMTMR Quirks
|
||
|
||
Linux 7.1's `arch/x86/kernel/tsc.c`, `hpet.c`, and `drivers/clocksource/acpi_pm.c` contain extensive quirks for timekeeping hardware. These are architecture-level quirks, not device-level.
|
||
|
||
### Quirk Categories
|
||
|
||
| Quirk | Source | Purpose |
|
||
|-------|--------|---------|
|
||
| TSC unstable detection | `tsc.c` | Detect faulty TSC on multi-core systems |
|
||
| TSC recalibration | `tsc.c` | Re-read TSC after deep sleep |
|
||
| TSC known rate | `tsc.c` | Honor platform-provided TSC frequency |
|
||
| ART (Always Running Timer) | `tsc.c` | Use ART for invariant TSC |
|
||
| HPET force-enable | `hpet.c` | Override BIOS HPET disable on Nvidia, ATI, etc. |
|
||
| HPET force-disable | `hpet.c` | Disable HPET on Bay Trail (halt in C-states) |
|
||
| PMTMR (ACPI PM Timer) blacklist | `acpi_pm.c` | PIIX4, ICH4, ServerWorks PMTMR broken |
|
||
| PIT/HPET routing | `io_apic.c` | DMI-based timer routing on Nvidia/ATI |
|
||
| TSC deadline timer | `apic.c` | Detect TSC deadline support (AMD Fam 0x12+) |
|
||
|
||
### PMTMR DECLARE_PCI_FIXUP Entries
|
||
|
||
Linux has 3 `DECLARE_PCI_FIXUP_EARLY` entries in `acpi_pm.c` for PIIX4/ICH4/ServerWorks PMTMR blacklist. These are critical for accurate timekeeping on systems with broken PMTMR.
|
||
|
||
### Boot Parameters
|
||
|
||
- `tsc=`, `tsc_early_khz=`, `tsc_khz=`
|
||
- `hpet=force`, `hpet=disable`
|
||
- `pmtmr=`
|
||
- `nohpet`, `noapic`, `nolapic`
|
||
|
||
### Red Bear OS Position
|
||
|
||
Red Bear's kernel (`local/sources/kernel/`) has minimal timekeeping infrastructure. The current time scheme is simple (TSC-based or HPET-based) without detection logic for broken hardware. This will cause time drift on some systems.
|
||
|
||
### Action: Phase R15 (Timekeeping Quirk Infrastructure)
|
||
|
||
**Priority:** HIGH
|
||
|
||
**Source files:** `arch/x86/kernel/tsc.c`, `hpet.c`, `drivers/clocksource/acpi_pm.c`
|
||
|
||
**Sub-tasks:**
|
||
1. Implement TSC stability detection across cores
|
||
2. Implement TSC rate validation against HPET
|
||
3. Implement PMTMR blacklist for PIIX4/ICH4/ServerWorks
|
||
4. Implement HPET force-enable on Nvidia/ATI southbridges
|
||
5. Add DMI-based timer routing for timer override
|
||
6. Add 3 `DECLARE_PCI_FIXUP_EARLY`-style entries (or TOML equivalents) for PMTMR blacklist
|
||
7. Add boot parameters: `redbear.tsc=`, `redbear.hpet=`
|
||
|
||
## Memory Configuration Quirks (MTRR, PAT, NUMA, LA57)
|
||
|
||
Linux 7.1 has extensive memory configuration quirks in `arch/x86/kernel/cpu/mtrr/` and `arch/x86/mm/`.
|
||
|
||
### Quirk Categories
|
||
|
||
| Quirk | Source | Purpose |
|
||
|-------|--------|---------|
|
||
| MTRR BIOS inconsistency | `mtrr/generic.c` | Warn when BIOS MTRR is wrong |
|
||
| MTRR cleanup | `mtrr/cleanup.c` | Speed up MTRR setup |
|
||
| AMD K6 WA (Write Allocate) | `mtrr/amd.c` | K6 B-step erratum |
|
||
| AMD K8 NB MTRR fixup | `drivers/pci/quirks.c` | 13 entries |
|
||
| AMD Fam10h NB MTRR | `drivers/pci/quirks.c` | 6 entries |
|
||
| AMD Fam15h NB MTRR | `drivers/pci/quirks.c` | 6 entries |
|
||
| AMD Fam16h DRAM scrub redirect | `drivers/pci/quirks.c` | 1 entry |
|
||
| Intel MCH/RAS | `drivers/pci/quirks.c` | Brickland, Purley — 4 entries |
|
||
| PAT validation | `mm/pat/memtype.c` | 3 entries |
|
||
| NUMA multi-chip DMI | `mm/numa.c` | 2 entries |
|
||
| LA57 (5-level paging) | `mm/pgtable_5level.h` | Detection + fallback |
|
||
| AMD SME/SEV | `mm/mem_encrypt*` | Memory encryption detection |
|
||
| AMD F16h MCE | `mce/amd.c` | Machine check exception handling |
|
||
| AMD F17h MCE | `mce/amd.c` | Machine check exception handling |
|
||
|
||
### Red Bear OS Position
|
||
|
||
Red Bear's kernel has minimal MTRR support (only basic variable MTRR setup). It does not have:
|
||
- MTRR cleanup optimization
|
||
- MTRR BIOS inconsistency detection
|
||
- PAT validation
|
||
- AMD NB MTRR fixups
|
||
- Intel MCH/RAS detection
|
||
- NUMA DMI quirks
|
||
- LA57 (5-level paging) detection
|
||
|
||
### Action: Phase R16 (Memory Configuration Quirks)
|
||
|
||
**Priority:** HIGH (AMD64 bare metal)
|
||
|
||
**Source files:** `arch/x86/kernel/cpu/mtrr/*.c`, `arch/x86/mm/numa.c`, `arch/x86/mm/pat/memtype.c`
|
||
|
||
**Sub-tasks:**
|
||
1. Implement MTRR cleanup optimization in kernel
|
||
2. Implement MTRR BIOS inconsistency detection
|
||
3. Implement PAT validation
|
||
4. Add 13 AMD K8 NB MTRR fixups (convert to TOML)
|
||
5. Add 6 AMD Fam10h NB MTRR fixups (TOML)
|
||
6. Add 6 AMD Fam15h NB MTRR fixups (TOML)
|
||
7. Add 1 AMD Fam16h DRAM scrub redirect (TOML)
|
||
8. Add 4 Intel MCH/RAS fixups (TOML)
|
||
9. Implement NUMA DMI quirks
|
||
10. Detect LA57 capability and fallback to 4-level paging
|
||
|
||
## Early-Boot Chipset Quirks (`arch/x86/kernel/early-quirks.c`)
|
||
|
||
Linux 7.1's `arch/x86/kernel/early-quirks.c` (812 lines) contains **20 chipset-specific early-boot PCI fixups** that run before the regular PCI enumeration.
|
||
|
||
### Complete Enumeration
|
||
|
||
| Handler | Chipset | What it does |
|
||
|---------|---------|--------------|
|
||
| `fix_hypertransport_config` | AMD K8 host bridge | Enable HT interrupt broadcast |
|
||
| `nvidia_bugs` | Nvidia MCP root ports | Skip ACPI timer override |
|
||
| `ati_bugs` | ATI IXP400 | SB400 timer override |
|
||
| `ati_bugs_contd` | ATI SBx00 | SB600+ IRQ0 polarity/pin2 |
|
||
| `intel_remapping_check` | Intel host bridges (0x3403/0x3405/0x3406) | Mark IRQ remapping broken |
|
||
| `intel_graphics_stolen` | Intel integrated GPUs (38 device families) | Reserve stolen memory range |
|
||
| `force_disable_hpet` | Intel Bay Trail (0x0f00) | Disable HPET (halt in C-states) |
|
||
| `apple_airport_reset` | Broadcom 4331 on Apple | Reset Airport card |
|
||
| `via_bugs` | VIA | Disable IOMMU if GART present |
|
||
| (others) | Various | HT MSI mapping, GART, ServerWorks, SiS, ALi, Samsung |
|
||
|
||
### Red Bear OS Position
|
||
|
||
Red Bear has NO `early-quirks` equivalent. The Redox kernel fork does not have an early PCI scan that runs chipset-specific fixups. The current boot flow goes: bootloader → kernel init → pcid userspace enumeration. Early chipset quirks are not applied.
|
||
|
||
### Action: Phase R17 (Early-Boot Chipset Quirks)
|
||
|
||
**Priority:** HIGH (boot-critical)
|
||
|
||
**Source file:** `arch/x86/kernel/early-quirks.c`
|
||
|
||
**Sub-tasks:**
|
||
1. Determine if early PCI scan should move from bootloader to kernel (or stay in bootloader)
|
||
2. If kernel-side: implement early PCI enumeration in kernel
|
||
3. Implement 20 chipset handlers
|
||
4. Add Intel stolen memory reservation for 38 GPU families
|
||
5. Wire intel_remapping_check into the IRQ subsystem
|
||
6. Document that these MUST run before `pcid` userspace enumeration
|
||
|
||
## Storage Controller Quirks (ATA, AHCI, SATA, NVMe)
|
||
|
||
Linux 7.1 has storage controller quirks in `drivers/ata/` (26 entries) and `drivers/nvme/` (2 entries).
|
||
|
||
### ATA/AHCI/SATA Quirk Categories
|
||
|
||
| Subsystem | File | DECLARE_PCI_FIXUP Count | Description |
|
||
|-----------|------|------------------------|-------------|
|
||
| libata-core | `libata-core.c` | 18 | SATA controller quirks |
|
||
| AHCI | `ahci.c` | 3 | AHCI-specific quirks |
|
||
| PIIX | `ata_piix.c` | 2 | PIIX/ICH SATA quirks |
|
||
| Other | various | 3 | Tegra, Silicon Image, etc. |
|
||
|
||
### Common SATA/AHCI Quirks
|
||
|
||
- JMicro ATA (10 devices): No-ATA-D3, force DMA mask
|
||
- ServerWorks CSB5 IDE: Same-mode IDE quirk
|
||
- ATI IXP600/IXP700 SATA IDE: IDE mode quirks
|
||
- AMD Hudson2 SATA IDE: IDE mode quirk
|
||
- AMD 7900 SATA IDE: IDE mode quirk
|
||
- Intel 82801CAM ICH3-M IDE: Same-mode IDE quirk
|
||
- Nvidia ION AHCI: ROM BAR overlap
|
||
- Intel ROM BAR overlap: 4 devices
|
||
|
||
### NVMe Controller Quirks
|
||
|
||
Linux 7.1's `drivers/nvme/host/pci.c` has 2 `DECLARE_PCI_FIXUP` entries for NVMe controller quirks.
|
||
|
||
### Red Bear OS Position
|
||
|
||
Red Bear has only 2 TOML storage quirk entries. Most SATA/AHCI/NVMe quirks are NOT covered. This can cause:
|
||
- Boot failures on certain SATA controllers
|
||
- DMA issues on JMicron controllers
|
||
- NCQ (Native Command Queuing) problems
|
||
- Power management issues (D3, runtime PM)
|
||
|
||
### Action: Phase R18 (Storage Controller Quirks)
|
||
|
||
**Priority:** HIGH
|
||
|
||
**Source files:** `drivers/ata/libata-core.c`, `ahci.c`, `ata_piix.c`, `drivers/nvme/host/pci.c`
|
||
|
||
**Sub-tasks:**
|
||
1. Mine 18 libata-core.c entries → TOML
|
||
2. Mine 3 AHCI entries → TOML
|
||
3. Mine 2 PIIX entries → TOML
|
||
4. Mine 2 NVMe entries → TOML
|
||
5. Wire quirks into the `lived` storage daemon
|
||
6. Add SATA/AHCI-specific flag types
|
||
|
||
## Network Controller PCI Quirks (e1000e, igb, ixgbe, r8169, iwlwifi, rtl8xxxu)
|
||
|
||
Linux 7.1 has network controller quirks in:
|
||
- `drivers/net/ethernet/` — Ethernet controller PCI quirks
|
||
- `drivers/net/wireless/` — Wireless controller PCI quirks
|
||
|
||
### Ethernet Quirk Files
|
||
|
||
- `drivers/net/ethernet/intel/i40e/i40e_main.c` — Intel 40GbE
|
||
- `drivers/net/ethernet/intel/igb/igb_main.c` — Intel 1GbE
|
||
- `drivers/net/ethernet/intel/ixgbe/ixgbe_main.c` — Intel 10GbE
|
||
- `drivers/net/ethernet/intel/e1000e/netdev.c` — Intel e1000e
|
||
- `drivers/net/ethernet/realtek/r8169_main.c` — Realtek
|
||
- `drivers/net/ethernet/broadcom/tg3.c` — Broadcom TIGON3 (6 devices)
|
||
- `drivers/net/ethernet/atheros/alx/main.c` — Atheros/Attansic
|
||
|
||
### Wireless Quirk Files
|
||
|
||
- `drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-v2.c`
|
||
- `drivers/net/wireless/realtek/rtl8xxxu/` — 12 DECLARE_PCI_FIXUP entries
|
||
- `drivers/net/wireless/realtek/rtw88/pci.c`
|
||
- `drivers/net/wireless/realtek/rtw89/rtw8852ce.c`
|
||
- `drivers/net/wireless/marvell/mwifiex/pcie_quirks.c`
|
||
- `drivers/net/wireless/broadcom/brcm80211/brcmfmac/dmi.c`
|
||
|
||
### Specific Quirks
|
||
|
||
- **Broadcom TIGON3**: MSI INTX disable bug (6 devices: 0x170c, 0x170d, 0x170e, 0x170f, 0x4724, 0x4727)
|
||
- **Attansic/Atheros**: MSI disable bug (multiple devices)
|
||
- **Intel I82579LM/I82579V**: No FLR (Function Level Reset)
|
||
- **AMD Starship USB/Audio/NPU**: No FLR
|
||
- **Mediatek MT7922**: No FLR
|
||
- **Chelsio T5**: Disable root port attributes
|
||
- **Freescale ENETC**: No MSI
|
||
- **e1000e**: ASPM disable, MSI handling, DMA coalescing
|
||
- **igb/ixgbe**: MSI-X, interrupt moderation
|
||
- **r8169**: RTL8105/RTL8111 specific quirks
|
||
- **iwlwifi**: PCIE link status, L0s ASPM
|
||
|
||
### Red Bear OS Position
|
||
|
||
Red Bear has 5 TOML network entries — minimal coverage. Most wired/wireless PCI quirks are not in the system. This can cause:
|
||
- NIC hangs on Tigon3 devices
|
||
- MSI delivery failures
|
||
- ASPM-related hangs
|
||
- Wireless firmware load failures
|
||
- Power management issues
|
||
|
||
### Action: Phase R19 (Network Controller PCI Quirks)
|
||
|
||
**Priority:** HIGH (ethernet on bare metal)
|
||
|
||
**Source files:** `drivers/net/ethernet/**/*.c`, `drivers/net/wireless/**/*.c`
|
||
|
||
**Sub-tasks:**
|
||
1. Mine Broadcom TIGON3 (6 entries) → TOML
|
||
2. Mine Attansic/Atheros MSI disable quirks → TOML
|
||
3. Mine Intel e1000e / igb / ixgbe quirks → TOML
|
||
4. Mine Realtek r8169 quirks → TOML
|
||
5. Mine 12 rtl8xxxu wireless quirks → TOML
|
||
6. Wire quirks into `e1000d`/`igb`/`ixgbed`/`r8169` driver daemons
|
||
7. Add wireless-specific quirk data for `iwlwifi` driver
|
||
|
||
## USB Audio Codec Quirks (53 entries)
|
||
|
||
Linux 7.1's `sound/usb/quirks.c` contains **53 USB audio device quirks** plus 6 USB mixer quirks in `sound/usb/mixer_quirks.c`.
|
||
|
||
### USB Audio Quirk Flags (Linux)
|
||
|
||
Linux defines these flags in `include/sound/usb.h`:
|
||
- `QUIRK_FIXUP_INSEND` (BIT(0))
|
||
- `QUIRK_FIXUP_NUM` (BIT(1))
|
||
- `QUIRK_DEVICE_FLUSH` (BIT(2))
|
||
- `QUIRK_AUDIO_ALIGN_TRANSFERS` (BIT(3))
|
||
- `QUIRK_AUDIO_PLAYBACK_POS_FIX_LPIB` (BIT(4))
|
||
- `QUIRK_AUDIO_PLAYBACK_POS_FIX` (BIT(5))
|
||
- `QUIRK_AUDIO_SAMPLE_RATE` (BIT(6))
|
||
- `QUIRK_AUDIO_SAMPLE_RATE_IMPLICIT` (BIT(7))
|
||
- (Many more specific flags)
|
||
|
||
### Quirk Categories
|
||
|
||
| Category | Entries | Description |
|
||
|----------|---------|-------------|
|
||
| Implicit feedback | 4 | Devices needing implicit feedback (e.g., webcams with audio) |
|
||
| Sample rate quirks | 10+ | Devices with broken sample rate handling |
|
||
| Position fix LP-IB | 8+ | Devices with broken playback position counter |
|
||
| Stereo / mono conversion | 5+ | Devices needing format conversion |
|
||
| Vendor-specific quirks | 20+ | Per-vendor specific behavior |
|
||
|
||
### Red Bear OS Position
|
||
|
||
Red Bear has 7 audio TOML entries that use **undefined flags** (`audio_force_eapd`, `audio_single_cmd`, `audio_position_fix_lpib`) — these are silently ignored. The plan documents this as a known gap (Gap #10).
|
||
|
||
### Action: Phase R20 (USB Audio Codec Quirks)
|
||
|
||
**Priority:** MEDIUM (depends on audio stack maturity)
|
||
|
||
**Source files:** `sound/usb/quirks.c`, `sound/usb/mixer_quirks.c`, `sound/usb/implicit.c`
|
||
|
||
**Sub-tasks:**
|
||
1. Define `AudioQuirkFlags` bitflags in `redox-driver-sys` matching Linux
|
||
2. Create `audio_table.rs` with compiled-in entries
|
||
3. Mine 53 USB audio quirks from `sound/usb/quirks.c`
|
||
4. Add 6 mixer quirks from `sound/usb/mixer_quirks.c`
|
||
5. Add 4 implicit feedback entries
|
||
6. Wire into `usbaudio` driver daemon
|
||
7. Fix the existing 7 undefined flags in `15-audio.toml` by mapping to real flag names
|
||
|
||
## AMD IOMMU Quirks
|
||
|
||
Linux 7.1's `drivers/iommu/amd/quirks.c` contains DMI-based IOAPIC quirks for AMD systems. These are critical for systems with broken AMD IOMMU hardware.
|
||
|
||
### Known DMI Entries
|
||
|
||
- Dell Inspiron 7375
|
||
- Dell Latitude 5495
|
||
- Lenovo IdeaPad 330S 15ARR
|
||
|
||
### Red Bear OS Position
|
||
|
||
Red Bear has an `iommu` daemon that builds but is not hardware-validated. AMD IOMMU quirks are not implemented. This can cause:
|
||
- IOMMU faults on specific systems
|
||
- Performance issues (full un-typed DMA)
|
||
- Security issues (devices can DMA outside their bounds)
|
||
|
||
### Action: Phase R21 (AMD IOMMU Quirks)
|
||
|
||
**Priority:** MEDIUM (depends on iommu daemon maturity)
|
||
|
||
**Source file:** `drivers/iommu/amd/quirks.c`
|
||
|
||
**Sub-tasks:**
|
||
1. Add 3 known DMI entries from Linux to TOML
|
||
2. Wire into `iommu` daemon
|
||
3. Add IOMMU group quirks (work with `BROKEN_BRIDGE` PCI flag)
|
||
|
||
## Boot Parameter Quirk Infrastructure (141 parameters in arch/x86)
|
||
|
||
Linux 7.1's `arch/x86/` directory contains **141 `__setup`/`early_param`/`core_param` entries** across 70 files. Many of these trigger quirk behavior.
|
||
|
||
### Boot Parameters by Category
|
||
|
||
| Category | Parameters | Purpose |
|
||
|----------|-----------|---------|
|
||
| PCI | `pci=*` (multiple modes) | PCI configuration: `irq`, `nommconf`, `noaer`, `realloc`, `hpmemsize` |
|
||
| ACPI | `acpi=*` | ACPI enable/disable/ht/noirqf/force |
|
||
| HPET | `hpet=*` | HPET enable/disable/force |
|
||
| TSC | `tsc=*`, `tsc_early_khz=*`, `tsc_khz=*` | TSC clocksource selection |
|
||
| APIC | `noapic`, `nolapic`, `apic=*` | APIC enable/disable |
|
||
| PIRQ | `pirq=*` | Manual PIRQ routing |
|
||
| MWAIT | `mwait=*` | MONITOR/MWAIT enable/disable |
|
||
| IDLE | `idle=*` | Idle driver selection |
|
||
| Cpuidle | `intel_idle.max_cstate=*`, `processor.max_cstate=*` | C-state limits |
|
||
| Memory | `mem=*`, `reserve=*` | Memory map override |
|
||
| NUMA | `numa=*` | NUMA setup |
|
||
| IO | `elevator=*` | IO scheduler selection |
|
||
| Speculation | `spectre_v2=*`, `mds=*`, `tsx_async_abort=*`, `mmio_stale_data=*`, `l1d_flush=*`, `srbds=*`, `gather_data_sampling=*`, `retbleed=*`, `spec_ctrl=*`, `ssbd=*`, `tsx=*`, `mitigations=*` | CPU speculation mitigations |
|
||
| Reboot | `reboot=*` | Reboot method selection |
|
||
| Console | `earlyprintk=*`, `no_console_suspend` | Console configuration |
|
||
|
||
### Red Bear OS Position
|
||
|
||
Red Bear's kernel has minimal boot parameter support. The current command line is parsed but most parameters are ignored. There is no per-parameter quirk infrastructure.
|
||
|
||
### Action: Phase R22 (Boot Parameter Quirk Infrastructure)
|
||
|
||
**Priority:** MEDIUM
|
||
|
||
**Source files:** `arch/x86/kernel/*.c`, `drivers/acpi/*.c` (141 entries total)
|
||
|
||
**Sub-tasks:**
|
||
1. Implement `__setup`/`early_param` infrastructure in Redox kernel
|
||
2. Implement 8-10 most-important boot parameters (pci, acpi, hpet, tsc, noapic, idle, mitigations)
|
||
3. Add corresponding documentation in `local/docs/BOOT-PARAMETERS.md`
|
||
4. Add test suite for boot parameter handling
|
||
|
||
### Linux 7.1 Quirk Handler Categories
|
||
|
||
Linux classifies its 701 PCI quirk fixups by lifecycle phase:
|
||
|
||
| Category | Count | When Applied | Red Bear Equivalent |
|
||
|----------|-------|-------------|-------------------|
|
||
| `DECLARE_PCI_FIXUP_HEADER` | 255 | During device enumeration, before driver probe | `PciQuirkEntry` matching in `lookup_pci_quirks()` |
|
||
| `DECLARE_PCI_FIXUP_FINAL` | 233 | After enumeration complete | Same |
|
||
| `DECLARE_PCI_FIXUP_EARLY` | 58 | Early boot before PCI enumeration | Compiled-in table only |
|
||
| `DECLARE_PCI_FIXUP_CLASS_EARLY` | 57 | Class-based early fixups | `class_mask`/`class_match` fields |
|
||
| `DECLARE_PCI_FIXUP_RESUME_EARLY` | 38 | During resume from suspend | **No equivalent** — PM-dependent |
|
||
| `DECLARE_PCI_FIXUP_RESUME` | 28 | During resume | **No equivalent** — PM-dependent |
|
||
| `DECLARE_PCI_FIXUP_CLASS_FINAL` | 17 | Class-based final fixes | Same |
|
||
| `DECLARE_PCI_FIXUP_ENABLE` | 6 | After device enable | Same |
|
||
| Other (HEADER/RESUME/SUSPEND) | 9 | Various | Partial |
|
||
|
||
Linux vendor coverage (top 10):
|
||
Intel (391), ATI (50), VIA (42), AMD (37), NVIDIA (35), NXP (24), JMicron (23),
|
||
Broadcom (18), Marvell (15), ServerWorks (14).
|
||
|
||
### Current Red Bear OS Data Inventory
|
||
|
||
| Source | Type | Count |
|
||
|--------|------|-------|
|
||
| `pci_table.rs` | Compiled-in PCI quirks | 11 |
|
||
| `00-core.toml` | TOML PCI quirks | 11 |
|
||
| `10-gpu.toml` | TOML PCI quirks | 33 |
|
||
| `15-audio.toml` | TOML PCI quirks | 7 |
|
||
| `30-net.toml` | TOML PCI quirks | 5 |
|
||
| `40-storage.toml` | TOML PCI quirks | 2 |
|
||
| **Total PCI quirks** | | **69** |
|
||
| `usb_table.rs` | Compiled-in USB quirks | 147 |
|
||
| `20-usb.toml` | TOML USB quirks | 151 |
|
||
| **Total USB device quirks** | | **298** |
|
||
| `30-storage.toml` | TOML USB storage quirks | 215 |
|
||
| `dmi.rs` | Compiled-in DMI rules | 8 |
|
||
| `50-system.toml` | TOML DMI rules | 7 |
|
||
| `50-system.toml` | TOML ACPI table rules | 2 |
|
||
| `xhci_controller_table.rs` | Compiled-in xHCI controller | 86 entries (449 lines) |
|
||
|
||
### Coverage Comparison
|
||
|
||
| Dimension | Linux 7.1 | Red Bear OS | Gap |
|
||
|-----------|-----------|-------------|-----|
|
||
| PCI quirk entries (total) | 701 | 69 | 10× fewer |
|
||
| PCI handler functions | 129 imperative | 0 (data-driven) | Design difference |
|
||
| PCI dev flags (`PCI_DEV_FLAGS_*`) | 14 | 22 defined, 12 consumed | More defined, fewer consumed |
|
||
| xHCI controller flags | 50 `BIT_ULL` defines | 19 | 62% missing |
|
||
| USB device flags (`USB_QUIRK_*`) | 19 | 22 | Red Bear exceeds Linux |
|
||
| USB device entries | dynamic (module param) | 298 | Red Bear exceeds Linux |
|
||
| USB storage entries | 323 | 215 | 66% coverage |
|
||
| AMD GPU device IDs | 308 | ~5 | 62× fewer |
|
||
| Intel GPU device IDs | ~78 families | ~2 | 39× fewer |
|
||
| DMI system rules | ~14 | 8 compiled + 7 TOML | Comparable |
|
||
| ACPI DMI blacklist entries | 14 | 2 TOML | 7× fewer |
|
||
| PCI vendor coverage | 391 Intel, 50 ATI, 37 AMD | 6 Intel, 4 AMD | Tiny subset |
|
||
|
||
### Coverage by Quirk Category
|
||
|
||
| Category | Linux Entries | Red Bear Data | Red Bear Consumers | Assessment |
|
||
|----------|--------------|---------------|-------------------|------------|
|
||
| **Interrupt (MSI/MSI-X/INTx)** | 131 | 3 flags, ~5 entries | redox-drm, xhcid, amdgpu | **Functional** for current hardware |
|
||
| **Power (D3cold/ASPM/PM)** | 173 | 3 flags, ~5 entries | amdgpu logs only | **Infrastructure exists, enforcement weak** |
|
||
| **BAR/Resource sizing** | 97 | 3 flags, 3 entries | None | **Infrastructure only** |
|
||
| **DMA/IOMMU** | 100 | 3 flags, 0 entries | None | **Infrastructure only** |
|
||
| **Bridge/Forwarding** | 199 | 2 flags, 0 entries | None | **Infrastructure only** |
|
||
| **Reset (bus/FLR/PM)** | 105 | 0 flags | None | **Gap** — no reset quirk flag |
|
||
| **GPU-specific** | 30 PCI + 308 AMD + ~78 Intel | 7 entries | redox-drm + amdgpu | **Tiny fraction** of real errata |
|
||
| **USB device** | dynamic (module param) | 298 entries | xhcid (13 flags) | **Good** — exceeds Linux |
|
||
| **USB storage** | 323 | 215 entries | usbscsid (planned — module does not exist yet) | **66% coverage** |
|
||
| **xHCI controller** | 86 entries, 50 flags | 86 entries, 19 flags | xhcid (wiring pending) | **Data present, flags incomplete** |
|
||
| **HID** | 500 entries, 24 flags | **0 entries, 0 flags** | **None** | **Complete gap** — no HID quirk system |
|
||
| **DRM panel orientation** | 22 DMI entries | **0 entries** | **None** | **Complete gap** — affects laptops |
|
||
| **ACPI DMI (all)** | ~115 DMI rules | 8 compiled + 9 TOML | acpid (partial) | **10× undercounted** |
|
||
| **Input (keyboard/mouse)** | ~4 DMI entries | **0 entries** | **None** | **Not yet needed** — PS/2 works |
|
||
| **Audio (HDA)** | Several | 7 TOML entries | None | **Minimal** |
|
||
| **Chipset/Bus** | 100+ | 3 entries | None | **Gap** |
|
||
| **Networking** | ~30 | 5 TOML entries | None | **Minimal** |
|
||
| **Early-boot** | 58 + 57 class-based | None | N/A | **Handled by bootloader** |
|
||
| **ACPI DMI blacklist** | 14 | 8 compiled + 2 TOML | acpid | **Comparable** |
|
||
| **Platform/x86 DMI** | 1153 entries | **0 entries** | **None** | **Complete gap** — laptop/tablet support |
|
||
| **CPU bug mitigation** | 20+ systems | **0 entries** | **None** | **Complete gap** — security critical |
|
||
| **Timekeeping (TSC/HPET/PMTMR)** | ~20 entries | **0 entries** | **None** | **Complete gap** — time drift risk |
|
||
| **Memory config (MTRR/PAT/NUMA)** | ~40 entries | **0 entries** | **None** | **Complete gap** — MTRR minimal only |
|
||
| **Early-boot chipset** | 20 handlers | **0 entries** | **None** | **Complete gap** — no early-quirks equivalent |
|
||
| **Storage controller (ATA/AHCI/NVMe)** | 28 entries | 2 TOML entries | None | **Minimal** — most SATA/NVMe quirks missing |
|
||
| **Network controller** | ~40 entries | 5 TOML entries | None | **Minimal** — NIC hangs possible |
|
||
| **USB audio** | 53 entries | **0 entries** | **None** | **Complete gap** — audio codec quirks missing |
|
||
| **AMD IOMMU** | 3 DMI entries | **0 entries** | iommu daemon | **Gap** — IOMMU faults possible |
|
||
| **Boot parameters** | 141 entries | **0 entries** | **None** | **Complete gap** — minimal cmdline parsing |
|
||
|
||
### Concrete Gaps Requiring Action
|
||
|
||
#### 1. xHCI Controller Table — ✅ RESOLVED (data), 🔄 Pending (wiring)
|
||
|
||
`XhciControllerQuirkFlags` (19 flags) and `XhciControllerQuirk` struct are now
|
||
defined in `mod.rs`. The `xhci_controller_table` module compiles successfully.
|
||
`lookup_xhci_controller_quirks(vendor, device)` is available for xhcid to call.
|
||
Remaining: wire the lookup into xhcid's PCI probe initialization.
|
||
|
||
**Flag gap:** Linux 7.1 defines 50 `XHCI_*` `BIT_ULL` flags in `xhci.h`. Red Bear
|
||
has 19 (38% coverage). Missing flags include:
|
||
- `XHCI_EP_LIMIT_QUIRK` (5), `XHCI_AMD_0x96_HOST` (9)
|
||
- `XHCI_COMP_MODE_QUIRK` (14), `XHCI_MTK_HOST` (21)
|
||
- `XHCI_SSIC_PORT_UNUSED` (22), `XHCI_MISSING_CAS` (24)
|
||
- `XHCI_BROKEN_PORT_PED` (25), `XHCI_LIMIT_ENDPOINT_INTERVAL_7` (26)
|
||
- `XHCI_U2_DISABLE_WAKE` (27), `XHCI_ASMEDIA_MODIFY_FLOWCONTROL` (28)
|
||
- `XHCI_HW_LPM_DISABLE` (29), `XHCI_INTEL_USB_ROLE_SW` (31)
|
||
- `XHCI_DEFAULT_PM_RUNTIME_ALLOW` (33), `XHCI_RESET_PLL_ON_DISCONNECT` (34)
|
||
- `XHCI_SNPS_BROKEN_SUSPEND` (35), `XHCI_SKIP_PHY_INIT` (37)
|
||
- `XHCI_SG_TRB_CACHE_SIZE_QUIRK` (39), `XHCI_BROKEN_D3COLD_S2I` (41)
|
||
- `XHCI_EP_CTX_BROKEN_DCS` (42), `XHCI_SUSPEND_RESUME_CLKS` (43)
|
||
- `XHCI_RESET_TO_DEFAULT` (44), `XHCI_ZHAOXIN_HOST` (46)
|
||
- `XHCI_WRITE_64_HI_LO` (47), `XHCI_CDNS_SCTX_QUIRK` (48)
|
||
- `XHCI_ETRON_HOST` (49)
|
||
|
||
**Action:** Add missing xHCI flags when xhcid encounters hardware that needs them.
|
||
Do not add all 29 missing flags speculatively — add them when xhcid's driver code
|
||
has a consumer for each flag.
|
||
|
||
#### 2. C Header Flag Coverage — ✅ RESOLVED
|
||
|
||
All 22 `PciQuirkFlags` now have corresponding C macros in `linux/pci.h`.
|
||
C drivers can query the full flag set via `pci_has_quirk()` and `pci_get_quirk_flags()`.
|
||
|
||
#### 3. PCI Quirk Data Volume
|
||
|
||
11 compiled-in entries cover only AMD GPUs (3 devices), Intel GPUs (2 devices),
|
||
Intel Wi-Fi (2 devices), and AMD chipsets (3 devices). Linux carries 701 entries
|
||
spanning every major vendor and subsystem. Most Red Bear entries are boot-critical
|
||
(GPU/firmware/interrupt). The TOML files add more breadth but still miss:
|
||
- Chipset-specific resource relocation (Intel, AMD, VIA, ServerWorks)
|
||
- Storage controller DMA aliases and BAR quirks
|
||
- Network controller ASPM/power quirks beyond Realtek
|
||
- Audio controller IRQ routing and DMA quirks
|
||
|
||
**Action:** Incrementally mine Linux's `drivers/pci/quirks.c` for entries relevant
|
||
to Red Bear's target hardware. Use the existing `extract-linux-quirks.py` tool.
|
||
Prioritize entries with evidence of real hardware impact — do not blindly import
|
||
all 701 entries.
|
||
|
||
#### 4. Flag Enforcement Depth
|
||
|
||
13 of 22 PCI flags are defined but have **zero runtime consumers**:
|
||
|
||
| Flag | Intended Consumer | Current State |
|
||
|------|-------------------|---------------|
|
||
| `NO_PM` | Network, audio, storage drivers | No driver checks |
|
||
| `NO_D3COLD` | Power management subsystem | No driver checks |
|
||
| `DMA_32BIT_ONLY` | DMA allocation in redox-driver-sys | No driver checks |
|
||
| `BUS_MASTER_DELAY` | PCI bus enable path | No driver checks |
|
||
| `NO_IOMMU` | IOMMU attach path | No driver checks |
|
||
| `RESIZE_BAR` | BAR sizing in PCI driver | No driver checks |
|
||
| `DISABLE_BAR_SIZING` | BAR sizing in PCI driver | No driver checks |
|
||
| `FORCE_VRAM_ONLY` | AMD GPU memory allocator | No driver checks |
|
||
| `BAD_EEPROM` | NIC/EEPROM readers | No driver checks |
|
||
| `WRONG_CLASS` | Device classification | No driver checks |
|
||
| `NEED_IOMMU` | IOMMU attach path | No driver checks |
|
||
| `NO_IOMMU` | IOMMU bypass path | No driver checks |
|
||
| `BROKEN_BRIDGE` | PCI bridge forwarding | No driver checks |
|
||
|
||
**Action:** Wire these flags into the appropriate driver paths as those drivers
|
||
mature. Do not create stub consumers — implement real enforcement when the driver
|
||
functionality exists.
|
||
|
||
#### 5. Missing Flag Categories
|
||
|
||
Linux carries quirk categories with no Red Bear equivalent:
|
||
|
||
| Linux Pattern | Linux Effect | Red Bear Status |
|
||
|---------------|-------------|-----------------|
|
||
| `PCI_DEV_FLAGS_NO_BUS_RESET` | Device cannot survive bus reset | **No flag** |
|
||
| `PCI_DEV_FLAGS_NO_PM_RESET` | No power management reset | **No flag** |
|
||
| `PCI_DEV_FLAGS_NO_FLR_RESET` | No function-level reset | **No flag** |
|
||
| `PCI_DEV_FLAGS_NO_RELAXED_ORDERING` | Disable PCIe relaxed ordering | **No flag** |
|
||
| `PCI_DEV_FLAGS_HAS_MSI_MASKING` | MSI masking quirks | **No flag** |
|
||
| `PCI_DEV_FLAGS_ACS_ENABLED_QUIRK` | ACS quirk bypass | **No flag** |
|
||
| `PCI_DEV_FLAGS_VPD_REF_F0` | VPD reference function 0 | **No flag** |
|
||
| `PCI_DEV_FLAGS_MSI_INTX_DISABLE_BUG` | MSI INTx disable bug | **No flag** |
|
||
| `PCI_DEV_FLAGS_BRIDGE_XLATE_ROOT` | Bridge address translation | **No flag** |
|
||
|
||
**Action:** Add Tier 1 flags (`NO_BUS_RESET`, `NO_FLR_RESET`, `NO_RELAXED_ORDERING`,
|
||
`MSI_MASKING_BROKEN`, `BRIDGE_NO_ALIAS`) when the PCI subsystem or GPU drivers
|
||
need them. See "New Flag Proposals" below for the full tier breakdown.
|
||
|
||
#### 6. Imperative vs Data-Driven Gap
|
||
|
||
Linux's 129 imperative handler functions do things that pure bitflags cannot:
|
||
- Write specific values to PCI config space registers
|
||
- Execute multi-step sequences with timing delays
|
||
- Read-modify-write PCI state based on device-specific logic
|
||
- Reconfigure bridge forwarding, BAR sizing, resource allocation
|
||
|
||
Approximately 70% of Linux's handlers are flag-setting operations (MSI disable,
|
||
ASPM disable, DMA mask configuration) that map to bitflags. The remaining 30%
|
||
perform actual config writes or multi-step sequences.
|
||
|
||
**Action:** Add a `QuirkAction` callback mechanism for the 30% of cases that need
|
||
imperative code. See "QuirkAction Architecture" below.
|
||
|
||
#### 7. Missing Subsystem: HID Quirks
|
||
|
||
Linux's HID subsystem (`drivers/hid/hid-quirks.c`) has **500 device entries** with
|
||
**24 flags** (`HID_QUIRK_*` in `include/linux/hid.h`). Red Bear has **zero** HID
|
||
quirk infrastructure.
|
||
|
||
HID quirks handle:
|
||
- Input devices that need constant polling (keyboards, mice)
|
||
- Devices with broken descriptors (badpad, multi-input)
|
||
- Devices that can't handle GET_REPORT (NOGET)
|
||
- Devices requiring special driver binding (HAVE_SPECIAL_DRIVER)
|
||
- Full-speed interval quirks for low-speed devices
|
||
|
||
Linux HID quirk flags (24 total):
|
||
```
|
||
NOTOUCH(1), IGNORE(2), NOGET(3), HIDDEV_FORCE(4), BADPAD(5),
|
||
MULTI_INPUT(6), HIDINPUT_FORCE(7), ALWAYS_POLL(10), INPUT_PER_APP(11),
|
||
X_INVERT(12), Y_INVERT(13), IGNORE_MOUSE(14), SKIP_OUTPUT_REPORTS(16),
|
||
SKIP_OUTPUT_REPORT_ID(17), NO_OUTPUT_REPORTS_ON_INTR_EP(18),
|
||
HAVE_SPECIAL_DRIVER(19), INCREMENT_USAGE_ON_DUPLICATE(20), NOINVERT(21),
|
||
IGNORE_SPECIAL_DRIVER(22), POWER_ON_AFTER_BACKLIGHT(23),
|
||
FULLSPEED_INTERVAL(28), NO_INIT_REPORTS(29), NO_IGNORE(30), NO_INPUT_SYNC(31)
|
||
```
|
||
|
||
**Action:** Create a `HidQuirkFlags` bitflags type and a HID quirk table in
|
||
`redox-driver-sys/src/quirks/hid_table.rs`. The HID quirk system is structurally
|
||
identical to the USB quirk system (match by vendor/product, return flags). Many
|
||
HID devices are USB devices, so the HID quirk table can be consumed by both
|
||
`xhcid` (during USB enumeration) and `usbhidd`/`evdevd` (during HID processing).
|
||
Mine the 819 entries from Linux's `drivers/hid/hid-quirks.c`.
|
||
|
||
Priority HID entries for Red Bear:
|
||
- `HID_QUIRK_NO_INIT_REPORTS` — most common (keyboards, mice, Corsair, Logitech)
|
||
- `HID_QUIRK_ALWAYS_POLL` — wireless input devices
|
||
- `HID_QUIRK_MULTI_INPUT` — combo keyboard/trackpad devices
|
||
- `HID_QUIRK_NOGET` — devices that fail GET_REPORT requests
|
||
|
||
#### 8. Missing Subsystem: ACPI DMI Quirks (Undercounted)
|
||
|
||
The first pass counted ~14 ACPI DMI rules. The actual count is **~115 across
|
||
8 ACPI subsystems**:
|
||
|
||
| ACPI Subsystem | DMI Rules | Purpose |
|
||
|---------------|-----------|---------|
|
||
| OSI interface | 20 | _OSI blacklist/override for BIOS workarounds |
|
||
| Embedded controller | ~8 | EC timing, GPE storm handling |
|
||
| x86 utils | 8 | ACPI table overrides for specific systems |
|
||
| Sleep/suspend | 5 | S3/S4 resume quirks |
|
||
| Video detect | 5 | Backlight/native graphics detection |
|
||
| PCI IRQ routing | 4 | Interrupt mapping quirks |
|
||
| Battery | 4 | Battery status reporting fixes |
|
||
| Blacklist | 3 | Completely broken ACPI tables |
|
||
| Button | 2 | Power button behavior |
|
||
|
||
Red Bear currently has 8 compiled-in DMI rules (in `dmi.rs`) plus 7 TOML
|
||
`dmi_system_quirk` entries and 2 `acpi_table_quirk` entries = 17 total.
|
||
This covers only the PCI-focused DMI quirks. The ACPI subsystem DMI rules
|
||
(EC timing, OSI overrides, sleep behavior) are a separate category.
|
||
|
||
**Action:** When `acpid` matures, mine Linux's ACPI DMI tables for the entries
|
||
relevant to Red Bear's target systems. The `acpid` daemon already has DMI
|
||
matching infrastructure via `/scheme/acpi/dmi`. Add `[[acpi_dmi_rule]]` entries
|
||
to TOML files for ACPI-internal quirks (OSI, EC, sleep).
|
||
|
||
#### 9. Missing Subsystem: DRM Panel Orientation
|
||
|
||
Linux carries 22 DMI entries in `drivers/gpu/drm/drm_panel_orientation_quirks.c`
|
||
for x86 clamshell devices with portrait screens that need software rotation.
|
||
These affect laptops (GPD, Chuwi, etc.) with non-standard display orientations.
|
||
|
||
**Action:** When Red Bear has a working compositor with display rotation support,
|
||
add `[[panel_orientation_quirk]]` entries to TOML files. Low priority — only
|
||
affects niche laptop hardware.
|
||
|
||
#### 10. Audio Quirk Flags Silently Ignored
|
||
|
||
The `15-audio.toml` file contains 7 PCI quirk entries using flags that are **not defined**
|
||
in `PciQuirkFlags`: `audio_force_eapd`, `audio_single_cmd`, `audio_position_fix_lpib`.
|
||
|
||
The TOML loader (`toml_loader.rs`) logs warnings for unknown flags but continues
|
||
processing. This means all 7 audio quirk entries have **no runtime effect** — the flags
|
||
are parsed but discarded.
|
||
|
||
**Action:** Either:
|
||
1. Define the audio-specific flags in `PciQuirkFlags` (or a new `AudioQuirkFlags` type),
|
||
and wire them into the audio driver initialization path, OR
|
||
2. Convert these to compiled-in entries with proper flag values when the audio stack matures
|
||
|
||
## QuirkAction Architecture — Hybrid Data-Driven + Imperative
|
||
|
||
### Design
|
||
|
||
Red Bear's quirks system is primarily data-driven (bitflags + tables + TOML). For
|
||
the ~30% of Linux quirks that require imperative code (PCI config space writes,
|
||
multi-step sequences), we add an optional secondary mechanism:
|
||
|
||
```
|
||
PciQuirkEntry
|
||
├── flags: PciQuirkFlags ← Primary: data-driven bitflags
|
||
└── action: Option<QuirkAction> ← Secondary: imperative for complex cases
|
||
```
|
||
|
||
### QuirkAction Types
|
||
|
||
```rust
|
||
/// An imperative quirk action for cases that need PCI config-space writes.
|
||
///
|
||
/// Actions are executed by the PCI scheme daemon, not by driver daemons.
|
||
/// This maintains the microkernel boundary: drivers never write config space
|
||
/// directly; they request the scheme daemon to do it.
|
||
pub enum QuirkAction {
|
||
/// Write a value to a PCI config space register.
|
||
/// The PCI scheme daemon performs the write via scheme:pci protocol.
|
||
WriteConfig {
|
||
/// Config space register offset (0-255).
|
||
reg: u8,
|
||
/// Value to write.
|
||
value: u32,
|
||
/// Bitmask: only bits set in mask are written (read-modify-write).
|
||
mask: u32,
|
||
},
|
||
/// A sequence of config writes with optional inter-step delays.
|
||
WriteSequence(Vec<WriteConfigStep>),
|
||
/// A Rust callback for complex device-specific logic.
|
||
/// The callback receives a handle to the PCI scheme daemon.
|
||
/// Use sparingly — prefer WriteConfig/WriteSequence when possible.
|
||
Callback(fn(&PciDeviceInfo, &dyn PciConfigWriter)),
|
||
}
|
||
|
||
pub struct WriteConfigStep {
|
||
pub reg: u8,
|
||
pub value: u32,
|
||
pub mask: u32,
|
||
/// Optional delay in milliseconds after this write.
|
||
/// Some hardware requires timing between config writes.
|
||
pub delay_ms: Option<u32>,
|
||
}
|
||
|
||
/// Trait implemented by the PCI scheme daemon for config-space writes.
|
||
pub trait PciConfigWriter {
|
||
fn write_config(&self, reg: u8, value: u32, mask: u32);
|
||
fn read_config(&self, reg: u8) -> u32;
|
||
}
|
||
```
|
||
|
||
### Why Hybrid, Not Pure Callbacks
|
||
|
||
1. **Performance:** Bitflag lookup is O(n) table scan (fast, branch-predictable);
|
||
callbacks require function dispatch.
|
||
2. **Serialization:** `WriteConfig`/`WriteSequence` can be defined in TOML;
|
||
callbacks cannot.
|
||
3. **Auditability:** Data-driven quirks are auditable without running code.
|
||
4. **Scheme daemon integration:** Actions translate to `scheme:pci` protocol
|
||
messages — no direct MMIO needed.
|
||
5. **TOML extensibility:** `WriteConfig` actions can be specified as:
|
||
```toml
|
||
[[pci_quirk]]
|
||
vendor = 0x8086
|
||
device = 0x1C10
|
||
flags = ["no_msi"]
|
||
action.write_config = { reg = 0x48, value = 0x0, mask = 0x1 }
|
||
```
|
||
|
||
### Execution Model
|
||
|
||
```
|
||
PCI scheme daemon discovers device
|
||
→ Calls lookup_pci_quirks(info)
|
||
→ Receives (flags, actions)
|
||
→ Applies flags: configures MSI/ASPM/interrupt mode based on flags
|
||
→ Executes actions: performs config writes via scheme:pci
|
||
→ Passes flags to driver daemon via PCI_QUIRK_FLAGS env var
|
||
```
|
||
|
||
### Compiled-in vs TOML for Actions
|
||
|
||
- **Compiled-in:** Complex actions (callbacks) must be compiled Rust code
|
||
- **TOML:** `WriteConfig` and `WriteSequence` can be specified in TOML files
|
||
- **Default:** Most quirks are flags-only (no action needed)
|
||
|
||
## New Flag Proposals
|
||
|
||
### Tier 1 — Critical for AMD64 Bare Metal (add when PCI reset/ACS support lands)
|
||
|
||
| Proposed Flag | Bit | Linux Equivalent | Purpose |
|
||
|--------------|-----|-----------------|---------|
|
||
| `NO_BUS_RESET` | 22 | `PCI_DEV_FLAGS_NO_BUS_RESET` | Device cannot survive secondary bus reset |
|
||
| `NO_PM_RESET` | 23 | `PCI_DEV_FLAGS_NO_PM_RESET` | Power management reset broken |
|
||
| `NO_FLR_RESET` | 24 | `PCI_DEV_FLAGS_NO_FLR_RESET` | Function-level reset broken |
|
||
| `MSI_MASKING_BROKEN` | 25 | `PCI_DEV_FLAGS_HAS_MSI_MASKING` | MSI masking capability has bugs |
|
||
| `BRIDGE_NO_ALIAS` | 26 | `PCI_DEV_FLAGS_PCI_BRIDGE_NO_ALIAS` | Bridge doesn't alias addresses |
|
||
| `NO_RELAXED_ORDERING` | 27 | `PCI_DEV_FLAGS_NO_RELAXED_ORDERING` | Device mishandles PCIe relaxed ordering |
|
||
| `VPD_REF_F0` | 28 | `PCI_DEV_FLAGS_VPD_REF_F0` | Must reference function 0 for VPD |
|
||
|
||
### Tier 2 — High Value for GPU/Audio (add in Phase R2)
|
||
|
||
| Proposed Flag | Bit | Linux Equivalent | Purpose |
|
||
|--------------|-----|-----------------|---------|
|
||
| `NO_ATS` | 29 | AMD-specific | Address Translation Service broken (ATS harvest GPUs) |
|
||
| `ACS_QUIRK` | 30 | `PCI_DEV_FLAGS_ACS_ENABLED_QUIRK` | ACS needs software quirk |
|
||
| `MSI_INTX_DISABLE_BUG` | 31 | `PCI_DEV_FLAGS_MSI_INTX_DISABLE_BUG` | INTx disable interferes with MSI |
|
||
| `NO_D3_DELAY` | 32 | Various D3 timing quirks | D3 state transition causes problems |
|
||
|
||
### Tier 3 — USB/xHCI (when USB stack matures)
|
||
|
||
Add missing xHCI controller flags from the 29 not yet in `XhciControllerQuirkFlags`.
|
||
See the xHCI gap list in "Concrete Gaps" section for the complete catalog.
|
||
|
||
### C Header Updates
|
||
|
||
When new flags are added to `PciQuirkFlags`, the corresponding `PCI_QUIRK_*` C
|
||
macros must be added to `linux/pci.h` and the `pci_get_quirk_flags()`/`pci_has_quirk()`
|
||
FFI bridge updated in `linux-kpi/source/src/rust_impl/pci.rs`.
|
||
|
||
## Linux Quirk Reimplementation Plan
|
||
|
||
### Strategy
|
||
|
||
Linux's 172 imperative handlers evolved over 30 years of hardware errata workarounds.
|
||
Red Bear does NOT need all 701 entries. We need the subset relevant to:
|
||
|
||
1. **AMD64 bare metal** — Ryzen/EPYC CPUs, AMD/Intel GPUs, modern chipsets
|
||
2. **QEMU virtual hardware** — virtio-gpu, virtio-net, Q35/440FX chipsets
|
||
3. **Target peripherals** — Intel Wi-Fi, USB xHCI, NVMe, HDA audio
|
||
|
||
The mining strategy follows a priority order based on Linux's DECLARE_PCI_FIXUP
|
||
phase categories, which indicate when each quirk fires and how critical it is.
|
||
|
||
### Phase R1: Class-Based and Early Fixups (1–2 days)
|
||
|
||
**Source:** Linux `DECLARE_PCI_FIXUP_CLASS_EARLY` (57) + `DECLARE_PCI_FIXUP_EARLY` (58)
|
||
|
||
These are the highest-value entries because:
|
||
- Class-based matching maps perfectly to our `class_mask`/`class_match` fields
|
||
- Early fixups are boot-critical (MSI disable, ASPM disable, DMA configuration)
|
||
- ~95% are pure flag-setting — no imperative code needed
|
||
|
||
**Status: COMPLETE (2026-06-07)** — see implementation report below.
|
||
|
||
#### Phase R1 Implementation Report (2026-06-07)
|
||
|
||
**Mined scope:** 115 Linux `EARLY` + `CLASS_EARLY` fixup entries, distributed as:
|
||
|
||
| Vendor | EARLY+CLASS_EARLY entries |
|
||
|---|---|
|
||
| Intel 0x8086 | 45 |
|
||
| NVIDIA 0x10DE | 19 |
|
||
| ServerWorks 0x1166 | 9 |
|
||
| JMicron 0x197B | 9 |
|
||
| AMD 0x1022 | 9 |
|
||
| RICOH 0x1180 | 4 |
|
||
| Solarflare 0x1924 | 3 |
|
||
| Pericom 0x12D8 | 3 |
|
||
| 3ware 0x13C1 | 2 |
|
||
| VIA 0x1106 | 1 |
|
||
| TI 0x104C | 1 |
|
||
| SolidRun 0x1B4B | 1 |
|
||
| MediaTek 0x14C3 | 1 |
|
||
| ATI 0x1002 | 1 |
|
||
| ASMedia 0x1B21 | 1 |
|
||
| ALi 0x10B9 | 1 |
|
||
| **Total** | **110** (5 are RESUME_EARLY duplicates, 115 deduped) |
|
||
|
||
**Entries added in Phase R1: 27 (4 in compiled-in, 23 in TOML)**
|
||
|
||
##### 1. Compiled-in (`pci_table.rs`) — 9 new entries
|
||
|
||
Source: `local/recipes/drivers/redox-driver-sys/source/src/quirks/pci_table.rs`
|
||
|
||
Boot-critical AMD/Intel/MediaTek no-FLR root ports (Linux handler `quirk_no_flr`).
|
||
These MUST be in the compiled-in table because `pcid` enumerates them before
|
||
the root filesystem is mounted (and thus before `/etc/quirks.d/` is readable):
|
||
|
||
| Vendor | Device | Linux handler | Mapped flag | Reason |
|
||
|---|---|---|---|---|
|
||
| 0x1022 | 0x1487 | `quirk_no_flr` | `NO_RESOURCE_RELOC` | AMD Starship/Milan downstream port |
|
||
| 0x1022 | 0x148C | `quirk_no_flr` | `NO_RESOURCE_RELOC` | AMD Starship/Milan internal PCIe |
|
||
| 0x1022 | 0x149C | `quirk_no_flr` | `NO_RESOURCE_RELOC` | AMD Starship/Milan passthrough |
|
||
| 0x1022 | 0x7901 | `quirk_no_flr` | `NO_RESOURCE_RELOC` | AMD Family 17h (Zen) PCIe |
|
||
| 0x1022 | 0x1502 | `quirk_no_flr` | `NO_RESOURCE_RELOC` | AMD Matisse/HTTPS root port |
|
||
| 0x1022 | 0x17F0 | `quirk_no_flr` | `NO_RESOURCE_RELOC` | AMD Genoa/Bergamo root port |
|
||
| 0x8086 | 0x1502 | `quirk_no_flr` | `NO_RESOURCE_RELOC` | Intel IVB/HSW graphics |
|
||
| 0x8086 | 0x1503 | `quirk_no_flr` | `NO_RESOURCE_RELOC` | Intel IVB/HSW graphics |
|
||
| 0x14C3 | 0x0616 | `quirk_no_flr` | `NO_RESOURCE_RELOC` | MediaTek MT7922 Wi-Fi 6E |
|
||
|
||
**Note on `NO_RESOURCE_RELOC` reuse:** The dedicated `NO_FLR` bit arrives
|
||
in Phase R2. Until then, `NO_RESOURCE_RELOC` is the existing
|
||
"do-not-touch-resource-locking" bit and is the safest approximation —
|
||
both FLR and resource relocation can wedge the device on these IDs.
|
||
|
||
##### 2. TOML (`00-core.toml`) — 30 new entries (file total now 41)
|
||
|
||
Source: `local/recipes/system/redbear-quirks/source/quirks.d/00-core.toml`
|
||
|
||
| Linux handler | Entries | Vendor scope | Mapped flag(s) |
|
||
|---|---|---|---|
|
||
| `quirk_no_ata_d3` | 4 | ServerWorks 0x1166, ATI 0x1002, ALi 0x10B9, VIA 0x1106 (CLASS_STORAGE_IDE) | `no_pm` |
|
||
| `pci_quirk_nvidia_tegra_disable_rp_msi` | 17 | NVIDIA Tegra root ports (CLASS_BRIDGE_PCI) | `no_msi` |
|
||
| `quirk_intel_qat_vf_cap` | 1 | Intel 0x8086/0x0443 | `no_resource_reloc` |
|
||
| `rom_bar_overlap_defect` | 4 | Intel 0x8086/0x1533,0x1536,0x1537,0x1538 | `bad_eeprom` |
|
||
| `quirk_unhide_mch_dev6` | 2 | Intel 0x8086/0x2570,0x2578 | `broken_bridge` |
|
||
| `vtd_mask_spec_errors` | 2 | Intel 0x8086/0x342E,0x3C28 | `no_iommu` |
|
||
| `quirk_ide_samemode` | 1 | Intel 0x8086/0x248C | `wrong_class` |
|
||
|
||
(Initial 11 entries unchanged: AMD no_resource_reloc 1483/1487/148C/149C/1502/17F0,
|
||
Intel PCIe bridge class no_resource_reloc, AMD 7901 no_resource_reloc, AMD 15E0/15E1
|
||
no_d3cold, AMD 7900 wrong_class.)
|
||
|
||
##### 3. Test coverage (4 new tests in `quirks::tests`)
|
||
|
||
| Test name | Purpose |
|
||
|---|---|
|
||
| `phase_r1_amd_no_flr_devices_match` | Asserts all 7 AMD no-FLR IDs match `NO_RESOURCE_RELOC` |
|
||
| `phase_r1_intel_no_flr_devices_match` | Asserts 0x1502/0x1503 match `NO_RESOURCE_RELOC` |
|
||
| `phase_r1_mediatek_no_flr_matches` | Asserts MediaTek MT7922 matches |
|
||
| `phase_r1_flags_or_accumulate` | Asserts OR accumulation across layers |
|
||
|
||
All 35 tests pass (`cargo test --lib`).
|
||
|
||
##### 4. Phase R1 handler mapping — what was added vs what remains
|
||
|
||
| Linux handler | Status in Red Bear OS | Map to flag | Note |
|
||
|---|---|---|---|
|
||
| `quirk_no_flr` | ✅ Phase R1 | `NO_RESOURCE_RELOC` (R1) → `NO_FLR` (R2) | 9 entries |
|
||
| `quirk_no_ata_d3` | ✅ Phase R1 | `no_pm` | 4 entries (CLASS-based) |
|
||
| `pci_quirk_nvidia_tegra_disable_rp_msi` | ✅ Phase R1 | `no_msi` | 17 entries (CLASS-based) |
|
||
| `quirk_intel_qat_vf_cap` | ✅ Phase R1 (flag-only) | `no_resource_reloc` | Phase R4 may refine |
|
||
| `rom_bar_overlap_defect` | ✅ Phase R1 (flag-only) | `bad_eeprom` | Phase R4 needs imperative disable |
|
||
| `quirk_unhide_mch_dev6` | ✅ Phase R1 (flag-only) | `broken_bridge` | Phase R4 needs imperative unhide |
|
||
| `vtd_mask_spec_errors` | ✅ Phase R1 (flag-only) | `no_iommu` | Phase R4 needs imperative masking |
|
||
| `quirk_ide_samemode` | ✅ Phase R1 (flag-only) | `wrong_class` | Phase R4 needs imperative mode fix |
|
||
| `fixup_mpss_256` | ⏸ Phase R2/R4 | (no flag) | imperative: writes PCI_EXP_DEVCTL_PAYLOAD |
|
||
| `quirk_no_ext_tags` | ⏸ Phase R2 | `NO_EXT_TAGS` flag | 3ware + ServerWorks |
|
||
| `quirk_enable_clear_retrain_link` | ⏸ Phase R4 | imperative: clears Link Status bit | Pericom 0xe110/0xe111/0xe130 |
|
||
| `ricoh_mmc_fixup_rl5c476` | ⏸ Phase R4 | imperative: enables PCI MMCIF | RICOH 0x1180 |
|
||
| `ricoh_mmc_fixup_r5c832` | ⏸ Phase R4 | imperative: enables PCI MMCIF | RICOH 0x1180 |
|
||
| `pcie_failed_link_retrain` | ⏸ Phase R4 | imperative: link retrain | ASMedia 0x2824 + Pericom switch |
|
||
| `quirk_pcie_pxh` | ⏸ Phase R4 | imperative: PXH setup | Intel 0x3410, 0x3411, 0x341e, 0x3420, 0x3421 (not common) |
|
||
| `fixup_mpss_256` | ⏸ Phase R2/R4 | imperative: writes MPS | ASMedia 0x0612, Solarflare 0x0903/0x0904/0x0923 |
|
||
| `quirk_tw686x_class` | ⏸ Phase R4 | imperative: fixes class | Techwell 0x1797 0x6864/0x6865/0x6868/0x6869 |
|
||
| `JMicron JMB360-369` | ⏸ Phase R4 | imperative: ATA setup | 9 entries |
|
||
| `AMD Starship/Milan 15E0/15E1` | ✅ already in 00-core.toml | `no_d3cold` | 2 entries |
|
||
| `DECLARE_PCI_FIXUP_RESUME_EARLY` | ✅ Phase R8 (data structure) / ⏸ Phase R8 (execution) | (PM-dependent) | data structure complete, execution gated by `pm_available` flag |
|
||
|
||
**Net Phase R1 result:** 27 new entries, 4 new tests, 7 Linux handlers mapped
|
||
to Red Bear flags, 0 imperative code paths added (those queue for R4).
|
||
|
||
##### 5. Phase R2 follow-up — flag additions required by Phase R1
|
||
|
||
The Phase R1 entries use the closest existing flag as a stopgap. The proper
|
||
dedicated flags arrive in R2:
|
||
|
||
| Phase R2 flag | Linux handler it replaces | Entries affected |
|
||
|---|---|---|
|
||
| `NO_FLR` | `quirk_no_flr` (9 entries currently using `NO_RESOURCE_RELOC`) | 9 |
|
||
| `NO_EXT_TAGS` | `quirk_no_ext_tags` (3ware 2 + ServerWorks 7 = 9 entries) | 9 new |
|
||
| `MPSS_256` | `fixup_mpss_256` (1 + 3 = 4 entries) | 4 new (imperative) |
|
||
| `ROM_BAR_OVERLAP` | `rom_bar_overlap_defect` (4 entries currently using `bad_eeprom`) | 4 |
|
||
|
||
After R2, the Phase R1 `NO_RESOURCE_RELOC` reuse for FLR devices should be
|
||
replaced with `NO_FLR` to avoid semantically overloading the bit.
|
||
|
||
##### 6. Phase R1 file-level changes summary
|
||
|
||
| File | Lines added | Reason |
|
||
|---|---|---|
|
||
| `local/recipes/drivers/redox-driver-sys/source/src/quirks/pci_table.rs` | +85 | 9 new entries + header doc |
|
||
| `local/recipes/drivers/redox-driver-sys/source/src/quirks/mod.rs` | +70 | 4 new tests + doc |
|
||
| `local/recipes/system/redbear-quirks/source/quirks.d/00-core.toml` | +167 | 30 new entries with comments |
|
||
| `local/docs/QUIRKS-SYSTEM.md` | +95 (this section) | Implementation report |
|
||
|
||
**Total:** 11 Linux handlers mapped, 27 entries added, 4 tests, 0 new flags
|
||
(intentionally deferred to R2), 0 imperative callbacks (intentionally deferred
|
||
to R4).
|
||
|
||
### Phase R2: Tier 1 Flag Addition (1 day)
|
||
|
||
#### Phase R2 Implementation Report (2026-06-07)
|
||
|
||
**Goal:** Add the most-commonly-needed `PciQuirkFlags` bits and the corresponding
|
||
TOML flag names, C macros, and entry conversions, so the 52 newly-mined entries in
|
||
`05-pcie-quirks.toml` plus the 9 Phase R1 stopgap entries (now converted) all
|
||
resolve to dedicated flags instead of being approximated by neighboring bits.
|
||
|
||
**Bit map added (bits 22–31 of `PciQuirkFlags`):**
|
||
|
||
| Bit | Flag | Linux source-of-truth | Use case |
|
||
|----:|------|-----------------------|----------|
|
||
| 22 | `NO_FLR` | `PCI_DEV_FLAGS_NO_FLR` (include/linux/pci.h) | root ports that hang on FLR |
|
||
| 23 | `NO_EXT_TAGS` | `quirk_no_ext_tags` (drivers/pci/quirks.c:5631) | 3ware, ServerWorks bridges |
|
||
| 24 | `NO_RELAXED_ORDERING` | `quirk_relaxedordering_disable` (drivers/pci/quirks.c:4536) | Intel Broadwell/Haswell RP |
|
||
| 25 | `MPSS_256` | `fixup_mpss_256` (drivers/pci/quirks.c:3440) | ASMedia, Solarflare controllers |
|
||
| 26 | `ROM_BAR_OVERLAP` | `rom_bar_overlap_defect` (drivers/pci/quirks.c) | Intel MCH IGD |
|
||
| 27 | `NO_ATS` | `pci_quirk_amd_sb_acs_disable_ats` (drivers/pci/quirks.c) | AMD Navi ATS harvest |
|
||
| 28 | `NO_BUS_RESET` | `quirk_no_bus_reset` + `quirk_nvidia_no_bus_reset` | Atheros Wi-Fi, NVIDIA GPUs |
|
||
| 29 | `AUDIO_FORCE_EAPD` | `HDA_FORCE_EAPD` (sound/pci/hda/patch_conexant.c, etc.) | mute-on-suspend codecs |
|
||
| 30 | `AUDIO_SINGLE_CMD` | `AZX_SINGLE_CMD` (sound/pci/hda/hda_intel.c) | ATI/AMD HDMI HDA |
|
||
| 31 | `AUDIO_POSITION_FIX_LPIB` | `POS_FIX_LPIB` (sound/pci/hda/hda_intel.c) | old ATI controllers |
|
||
|
||
**Three HDA audio flags (29–31) complete the Phase R0 audio surface and unblock
|
||
`15-audio.toml`'s 7 entries, which previously emitted "unknown flag" warnings
|
||
at runtime.**
|
||
|
||
**Files modified:**
|
||
|
||
| File | What changed |
|
||
|------|--------------|
|
||
| `mod.rs` (`PciQuirkFlags`) | 10 new bitflag constants; docstring table updated to show bit map 22–31 |
|
||
| `toml_loader.rs` (`PCI_FLAG_NAMES`) | 10 new snake_case → bit mappings |
|
||
| `linux-kpi/.../c_headers/linux/pci.h` | 10 new `PCI_QUIRK_*` C macros mirroring the Rust bit positions, with `PCI_DEV_FLAGS_*` cross-references |
|
||
| `pci_table.rs` (compiled-in) | 9 Phase R1 entries converted from `no_resource_reloc` → `no_flr` |
|
||
| `quirks.d/00-core.toml` | 6 Phase R1 entries converted from `no_resource_reloc` → `no_flr`; header comment added |
|
||
| `quirks.d/10-gpu.toml` | 14 Navi entries converted from `no_aspm` → `no_ats` |
|
||
| `quirks.d/15-audio.toml` | header comment added explaining the 3 newly-defined audio flags |
|
||
| `quirks.d/05-pcie-quirks.toml` (new) | 52 entries added: 9 `no_ext_tags` (3ware + ServerWorks), 28 `no_relaxed_ordering` (Intel Broadwell/Haswell), 4 `mpss_256` (ASMedia + Solarflare), 11 `no_bus_reset` (Atheros, NVIDIA, Cavium, TI, ASMedia) |
|
||
| `recipe.toml` | added `cp` lines for the previously-unstaged `05-pcie-quirks.toml` and `15-audio.toml` |
|
||
|
||
**Tests:** 4 Phase R2 tests added to `quirks::tests` (renamed from `phase_r1_*`):
|
||
- `phase_r2_amd_no_flr_devices_match` — AMD 0x1483/0x1487/0x148C/0x149C/0x7901/0x17F0
|
||
- `phase_r2_intel_no_flr_devices_match` — Intel 0x1502/0x1503
|
||
- `phase_r2_mediatek_no_flr_matches` — MediaTek 0x14C3/0x0616
|
||
- `phase_r2_flags_or_accumulate` — confirms 10 new bits OR together correctly
|
||
|
||
`cargo test --lib`: **35/35 pass**.
|
||
|
||
**TOML parser cross-check:** 11 quirk TOML files, 143 total `pci_quirk` entries,
|
||
24 distinct flag names used — all 24 resolve to defined `PciQuirkFlags` bits,
|
||
0 undefined flag references. The 8 defined-but-unused flags
|
||
(`broken_intx`, `no_aer`, `no_ata_d3`, `no_bar`, `no_io`, `no_pcie`,
|
||
`rom_bar_overlap`, `use_vga`) are forward-looking flag definitions for driver
|
||
stacks that have not yet consumed them.
|
||
|
||
**Mining notes:**
|
||
- 9 `no_ext_tags` entries cover the 7 ServerWorks PCI-X bridges (0x1166
|
||
0x0132/0x0140/0x0141/0x0142/0x0144/0x0420/0x0422) and 2 3ware SAS controllers
|
||
(0x13C1 0x1004/0x1005). The 8-bit NVIDIA `nforce_no_ext_tags` fixup
|
||
(`quirk_nforce_noexttags`) is not added here because it requires a
|
||
class-mask + 8-bit device-ID pattern; it will be added in Phase R4 when
|
||
the `QuirkAction` mechanism can express bit-mask device matching.
|
||
- 28 `no_relaxed_ordering` entries are 14 IDs of Intel 0x6f01-0x6f0e (Broadwell)
|
||
and 14 IDs of Intel 0x2f01-0x2f0e (same erratum on Haswell). The class
|
||
field is `0x000000` (PCI_CLASS_NOT_DEFINED) with class_mask `0xFF0000` so the
|
||
quirk matches any subclass within host bridge class `0x06`.
|
||
- 4 `mpss_256` entries: ASMedia 0x1B21/0x0612 + Solarflare 0x1924/0x0703, 0x6703, 0x0710.
|
||
The Linux handler `fixup_mpss_256` only writes the kernel's `pcie_mpss` cache
|
||
(not the hardware register), so no imperative action is needed at runtime
|
||
beyond the flag being set.
|
||
- 11 `no_bus_reset` entries: 6 Atheros AR9xxx/QCA988x Wi-Fi (0x168C 0x0030/0032/0033/
|
||
0034/003C/003E), 2 NVIDIA GPUs (0x10DE 0x22CE/0x22D0, first/last of the
|
||
`(device & 0xffc0) == 0x2340` range — full range requires mask-based matching
|
||
in Phase R4), and one each of Cavium 0x177D/0xA100, TI 0x104C/0xB005, and
|
||
ASMedia 0x1B21/0x1164.
|
||
- Audio flags (29–31) had **no entries added in this phase** — they are
|
||
definitions to unblock `15-audio.toml`'s 7 pre-existing entries. The flag
|
||
bit assignments follow `include/linux/pci.h` and `sound/pci/hda/hda_intel.h`,
|
||
not arbitrary placement.
|
||
|
||
**Limitations (forward-looking):**
|
||
- `rom_bar_overlap` has 4 Linux IDs (Intel B43/Q43/Q45/P45 MCH IGD 0x2E00/0x2E10/0x2E20/0x2E30
|
||
+ Nehalem 0x3400/0x3401/0x3402/0x3403) but the `PciQuirkFlags` bit was added
|
||
for completeness; no driver consumer exists yet, so no TOML entries.
|
||
- `NO_RELAXED_ORDERING` walks the entire bus to clear
|
||
`PCI_EXP_DEVCTL_RELAX_EN` (0x0010) on each endpoint. The flag is set on the
|
||
root port; the walk logic is in `pci_configure_relaxed_ordering()` and is
|
||
**not yet implemented** in redox-drm/redox-driver-pci. Until that walker
|
||
exists, setting the flag on a Broadwell/Haswell root port has no observable
|
||
effect. Documented as "flag set, walker pending" in the entry header.
|
||
- The NVIDIA "no bus reset" `(device & 0xffc0) == 0x2340` mask pattern cannot
|
||
be expressed in the current TOML schema. The first and last IDs of the
|
||
range are listed, with a comment in the entry explaining the limitation.
|
||
- Audio flags are consumed by HDA driver code that does not yet exist in
|
||
Red Bear's tree. The flags are correct against Linux 7.1; they will become
|
||
"live" as the HDA driver is implemented in the Wayland/desktop phase.
|
||
|
||
**Total Phase R2 deliverables:** 10 new `PciQuirkFlags` bits, 10 new TOML flag
|
||
name mappings, 10 new C macros, 35/35 tests passing, 52 new TOML entries, 9
|
||
Phase R1 stopgap conversions (3 in `pci_table.rs`, 6 in `00-core.toml`, 14 in
|
||
`10-gpu.toml` — total 23), and the previously-unstaged `15-audio.toml`
|
||
(Phase R0) + newly-added `05-pcie-quirks.toml` (Phase R2) wired into
|
||
`recipe.toml`.
|
||
|
||
### Phase R3: Header Fixup Mining (3–5 days)
|
||
|
||
#### Phase R3 Implementation Report (2026-06-07)
|
||
|
||
**Goal:** Mine Linux 7.1's 255 `DECLARE_PCI_FIXUP_HEADER` entries, add the
|
||
4 new `PciQuirkFlags` bits they need, and create a new TOML file with
|
||
25–30 of the most AMD64-relevant entries (chosen for impact on consumer
|
||
AMD64 bare metal, QEMU, and modern peripherals).
|
||
|
||
**Bit map added (bits 32–35 of `PciQuirkFlags`):**
|
||
|
||
| Bit | Flag | Linux source-of-truth | Use case | Phase R4 needed? |
|
||
|----:|------|-----------------------|----------|:----------------:|
|
||
| 32 | `DMA_ALT` | `quirk_use_pcie_bridge_dma_alias` + `quirk_dma_func0_alias` + `quirk_fixed_dma_alias` (drivers/pci/quirks.c) | Asmedia/Tundra/ITE/Intel bridges, Ricoh card readers, Glenfly GPU, Adaptec2 RAID | yes |
|
||
| 33 | `NO_PM_RESET` | `quirk_no_pm_reset` (drivers/pci/quirks.c) | Mellanox ConnectX-3/3-Pro/4/4-Lx adapters | yes |
|
||
| 34 | `IO_1K` | `quirk_p64h2_1k_io` (drivers/pci/quirks.c) | Intel P64H2 1K I/O granularity | yes |
|
||
| 35 | `NTB_BAR_FIX` | `quirk_intel_ntb` (drivers/pci/quirks.c) | Intel Sandy Bridge Xeon E5 NTB (Ivytown) | yes |
|
||
|
||
**Cross-cutting bit (bit 19, from R0):**
|
||
|
||
`WRONG_CLASS` was already defined in R0. The Phase R3 `quirk_amd_ide_mode`
|
||
entries (4 IDs) reuse it instead of allocating a new bit — the flag's
|
||
existing semantic ("class has been rewritten by a fixup") exactly matches.
|
||
|
||
**Files modified:**
|
||
|
||
| File | What changed |
|
||
|------|--------------|
|
||
| `mod.rs` (`PciQuirkFlags`) | 4 new bitflag constants (bits 32–35); docstring table extended to show bit map through 35 |
|
||
| `toml_loader.rs` (`PCI_FLAG_NAMES`) | 4 new snake_case → bit mappings; `PCI_FLAG_NAMES` exposed as `pub` so tests can verify the table directly |
|
||
| `linux-kpi/.../c_headers/linux/pci.h` | 4 new `PCI_QUIRK_*` C macros mirroring the Rust bit positions, with Linux handler names cited |
|
||
| `quirks.d/06-pci-header-quirks.toml` (new) | 37 entries: 4 `wrong_class` + 14 `no_aspm` + 1 Asmedia (dual `dma_alt, no_aspm`) + 4 `dma_alt` bridges + 2 Ricoh + 2 Glenfly + 1 Adaptec2 + 4 `no_pm_reset` + 2 `no_msi` (HT bridges) + 1 `io_1k` + 2 `ntb_bar_fix` |
|
||
| `recipe.toml` | added `cp` line for `06-pci-header-quirks.toml` |
|
||
|
||
**Tests:** 4 Phase R3 tests added to `quirks::tests`:
|
||
- `phase_r3_dma_alt_bit_set` — bit 32 is defined and OR-accumulating, no collision with bits 33-35
|
||
- `phase_r3_all_new_bits_accumulate` — bits 32-35 OR together as `0xF00000000`
|
||
- `phase_r3_cross_phase_no_collision` — Phase R2 bit 22 (NO_FLR) and Phase R3 bit 32 (DMA_ALT) coexist
|
||
- `phase_r3_toml_names_resolve` — `dma_alt`, `no_pm_reset`, `io_1k`, `ntb_bar_fix` resolve from `PCI_FLAG_NAMES`
|
||
|
||
`cargo test --lib`: **39/39 pass** (35 prior + 4 new).
|
||
|
||
**TOML parser cross-check:** 12 quirk TOML files, 180 total `pci_quirk` entries,
|
||
28 distinct flag names used. All 28 resolve to defined `PciQuirkFlags` bits.
|
||
0 undefined flag references. The 8 defined-but-unused flags remain the same
|
||
forward-looking ones from R0/R2 (`broken_intx`, `no_aer`, `no_ata_d3`,
|
||
`no_bar`, `no_io`, `no_pcie`, `rom_bar_overlap`, `use_vga`).
|
||
|
||
**Mining notes (37 entries across 8 Linux handlers):**
|
||
|
||
| Linux handler | Entries | Flag | Why included |
|
||
|---------------|--------:|------|--------------|
|
||
| `quirk_amd_ide_mode` | 4 | `WRONG_CLASS` | AMD Hudson-2 / ATI IXP600/700 SATA IDE mode — affects consumer AMD boards. The fixup rewrites the class code from IDE (0x0101) to SATA (0x0106) so AHCI driver binds correctly. |
|
||
| `quirk_disable_aspm_l0s` | 14 | `NO_ASPM` | Intel ICH9/10/X58 PCIe endpoints — common cause of PCIe hangs on AMD64 bare metal when ASPM L0s is enabled incorrectly. The 14 IDs cover PCIe root ports and endpoints on Core i5/i7 era boards. |
|
||
| `quirk_use_pcie_bridge_dma_alias` | 5 | `DMA_ALT` (one with both) | Asmedia ASM1083/1085 + Tundra Tsi384 + ITE IT8892/8893 + Intel 82801 ICH8/9/10 PCIe. ASM1083 is extremely common in desktop PCIe-to-PCI bridges. Tundra 8113 is on some server platforms. ITE 8892/8893 is a known bugzilla quirk. |
|
||
| `quirk_dma_func0_alias` | 4 | `DMA_ALT` | Ricoh R5C832/R5C476 card readers (common in laptops) + Glenfly 0x3D40/0x3D41 GPU (function 0 and 1). |
|
||
| `quirk_fixed_dma_alias` | 1 | `DMA_ALT` | Adaptec Series 2 RAID. |
|
||
| `quirk_no_pm_reset` | 4 | `NO_PM_RESET` | Mellanox ConnectX-3/3-Pro/4/4-Lx — datacenter/InfiniBand adapters, but the no-PM-reset fix prevents the system from hanging on S3/S4 resume when these devices are present. |
|
||
| `ht_enable_msi_mapping` | 2 | `NO_MSI` | ServerWorks HT1000 PXB (0x1166:0x0036) + AMD 8132 (0x1022:0x7458) — both block downstream MSI until the HT MSI mapping bit is forced on. The `NO_MSI` flag is set as a marker that the device requires the HT mapping fixup. |
|
||
| `quirk_p64h2_1k_io` | 1 | `IO_1K` | Intel P64H2 server-class PCIe switch. |
|
||
| `quirk_intel_ntb` | 2 | `NTB_BAR_FIX` | Intel Sandy Bridge Xeon E5 NTB (primary 0x0E08 + secondary 0x0E0D). |
|
||
|
||
**Bug found during mining (corrected in TOML):**
|
||
|
||
Initial mining (from the explore agent's summary) had three incorrect device IDs:
|
||
- ATI IXP600 SATA was listed as `0x4391` — actual value is `0x4380` (per `pci_ids.h`)
|
||
- ATI IXP700 SATA was listed as `0x4392` — actual value is `0x4390`
|
||
- AMD Hudson-2 SATA IDE was listed as `0x7804` (which is `PCI_DEVICE_ID_SEALEVEL_UCOMM8`) — actual value is `0x7800`
|
||
|
||
Additionally, the ServerWorks HT1000 PXB was listed as `0x0132` (which is a
|
||
different ServerWorks PCI-X bridge already covered by the Phase R2
|
||
`no_ext_tags` entries in `05-pcie-quirks.toml`) — actual value is `0x0036`
|
||
(per `pci_ids.h` `PCI_DEVICE_ID_SERVERWORKS_HT1000_PXB`).
|
||
|
||
All four entries corrected in `06-pci-header-quirks.toml` before commit.
|
||
|
||
**Items deliberately deferred to Phase R4 (`QuirkAction` mechanism):**
|
||
|
||
**Important correction (2026-06-07 audit):** All four Phase R3 handlers that
|
||
landed in `06-pci-header-quirks.toml` actually do imperative config-space
|
||
writes in Linux — the flags I added are **markers** that signal the device
|
||
needs imperative action, but the actual config-space writes are still
|
||
pending Phase R4. Specifically:
|
||
|
||
- `quirk_disable_aspm_l0s` (14 entries) — calls `pcie_aspm_remove_cap()`,
|
||
which modifies the Link Capabilities register. The `NO_ASPM` flag
|
||
signals "don't enable ASPM on this device"; the actual register write
|
||
is a Phase R4 deliverable.
|
||
- `quirk_amd_ide_mode` (4 entries) — reads/writes offsets 0x40, 0x9, 0xa,
|
||
and rewrites the class code. The `WRONG_CLASS` flag signals "class was
|
||
rewritten by a fixup"; the actual writes are a Phase R4 deliverable.
|
||
- `quirk_use_pcie_bridge_dma_alias` + `quirk_dma_func0_alias` +
|
||
`quirk_fixed_dma_alias` (10 entries) — register DMA aliases via the
|
||
IOMMU API. The `DMA_ALT` flag signals "this device requires a DMA
|
||
alias"; the actual alias registration is a Phase R4 deliverable.
|
||
- `ht_enable_msi_mapping` (2 entries) — calls `pci_find_capability()`
|
||
to find the HT MSI mapping capability, then sets the enable bit.
|
||
The `NO_MSI` flag signals "MSI is blocked until the HT mapping
|
||
fixup completes"; the actual capability walk + write is a Phase R4
|
||
deliverable.
|
||
- `quirk_no_pm_reset` (4 entries) — clears the PM reset capability bit.
|
||
The `NO_PM_RESET` flag signals "PM reset will hang this device"; the
|
||
actual capability bit clear is a Phase R4 deliverable.
|
||
- `quirk_intel_ntb` (2 entries) — writes 0x00D0/0x00D1 to set BAR
|
||
sizing. The `NTB_BAR_FIX` flag signals "this device requires special
|
||
BAR sizing handling"; the actual writes are a Phase R4 deliverable.
|
||
A `# TODO: QuirkAction (Phase R4)` comment in
|
||
`06-pci-header-quirks.toml` notes this.
|
||
- `quirk_p64h2_1k_io` (1 entry) — sets the 1K I/O granularity bit.
|
||
The `IO_1K` flag signals "this switch needs 1K I/O granularity"; the
|
||
actual bit set is a Phase R4 deliverable.
|
||
|
||
The remaining 7 handlers in the Phase R3 inventory also need imperative
|
||
writes but are deferred entirely (no flag added):
|
||
|
||
- `dpc_log_size` (Intel Ice Lake/Tiger Lake/Alder Lake Thunderbolt DPC RP
|
||
PIO Log Size) — writes to DPC extended capability. The flag
|
||
`DPC_LOG_SIZE` (bit 36) is **not yet added** to `PciQuirkFlags`; deferred
|
||
alongside the entries.
|
||
- `quirk_mic_x200_dma_alias` and `quirk_pex_vca_alias` (Intel MIC / VCA
|
||
accelerators) — datacenter-only hardware, deferred until consumer
|
||
relevance appears.
|
||
- The NVIDIA "no bus reset" `(device & 0xffc0) == 0x2340` mask pattern
|
||
(already in `05-pcie-quirks.toml` with first/last IDs and a comment)
|
||
needs the Phase R4 `QuirkAction` mechanism for full coverage.
|
||
|
||
**What this means for Phase R4:**
|
||
|
||
The `QuirkAction` mechanism is the single biggest blocker for Phase R3
|
||
entries to become "live" — the flags are stored on the `PciQuirkFlags`
|
||
struct, but no driver currently reads them and no imperative code runs.
|
||
The mechanism is a `QuirkAction` enum + a `PciConfigWriter` trait that
|
||
allows the TOML file to express a write to a specific (offset, value)
|
||
pair. The reader side is `lookup_pci_quirks()` already returning
|
||
`PciQuirkFlags`; Phase R4 adds the consumer side that walks the flags
|
||
and applies the imperative action.
|
||
|
||
**Skipped entries (185 of 255 — see Phase R3 inventory):**
|
||
|
||
The full 255-entry inventory and bucketing (HIGH / MEDIUM / LOW / already-covered)
|
||
is captured in the Phase R3 background research session
|
||
`ses_15ffe0543ffeB3yS52KQmSgJUO`. Highlights of skipped categories:
|
||
|
||
- **Old Intel ICH/LPC variants** (~30 entries): ICH4–ICH10 LPC controllers
|
||
with SMBus-hiding quirks. These are mostly DMI-based (subvendor/subdevice
|
||
matching for ASUS boards), better handled via TOML DMI rules when needed.
|
||
- **VIA / ALi / SiS chipsets** (~25 entries): Legacy southbridge / northbridge
|
||
hardware not present on modern AMD64 bare metal targets.
|
||
- **Intel MC errata** (Intel 5000/5100 series, ~20 entries): Server
|
||
memory controllers from the Boxboro/Stoakley era. Uncommon on consumer
|
||
AMD64 bare metal.
|
||
- **Server / datacenter only** (Huawei SVA, Chelsio T5, Broadcom ThunderX2,
|
||
Aspeed AST1150, Mellanox-class extras, Adaptec non-Series-2): Kept
|
||
Mellanox `quirk_no_pm_reset` because the flag prevents system hangs
|
||
during S3/S4 resume; deferred the rest as out-of-scope.
|
||
- **Old graphics / SCSI** (S3, NCR 53C810, Citrine, Dunord): Legacy
|
||
pre-PCIe hardware, not boot-critical.
|
||
- **Class-based** (`DECLARE_PCI_FIXUP_CLASS_HEADER`, 5 entries: Synopsys,
|
||
Netmos, ATI, NVIDIA, 0x1ac1): Skipped because they match by class
|
||
code only; the per-vendor handling is captured in the dedicated
|
||
`10-gpu.toml` (Phase R0) which uses class-based matching with explicit
|
||
`class_mask`.
|
||
|
||
**Total Phase R3 deliverables:** 4 new `PciQuirkFlags` bits, 4 new TOML
|
||
flag name mappings, 4 new C macros, 39/39 tests passing, 37 new TOML
|
||
entries in a new file, 1 new `pub const PCI_FLAG_NAMES` accessor, the
|
||
previously-stubbed Phase R3 section replaced with this implementation
|
||
report, and a permanent audit trail of 3 mining bugs caught and fixed
|
||
before commit.
|
||
|
||
### Phase R4: QuirkAction Mechanism (2–3 days)
|
||
|
||
**Status:** ✅ IMPLEMENTED (2026-06-07)
|
||
|
||
#### Design
|
||
|
||
The hybrid architecture separates the ~70% of Linux PCI quirks that are
|
||
pure flag-setting from the ~30% that need imperative config-space writes.
|
||
Phase R4 adds the imperative side as a complementary, data-driven
|
||
mechanism that does not disturb the existing flag API.
|
||
|
||
```
|
||
PciQuirkEntry
|
||
├── flags: PciQuirkFlags (existing, OR-accumulated)
|
||
└── action: Option<QuirkAction> (new, single action per entry)
|
||
```
|
||
|
||
`QuirkAction::execute()` runs through a `PciConfigWriter` so the actual
|
||
device access is the responsibility of the driver (typically the PCI
|
||
scheme daemon). The quirks crate owns the *decision* of what to do;
|
||
the driver owns the *mechanism* of how to touch the device.
|
||
|
||
#### New types (in `redox-driver-sys/src/quirks/mod.rs`)
|
||
|
||
| Type | Purpose |
|
||
|------|---------|
|
||
| `PciConfigWriter` | Trait with `read/write_config_byte/word/dword` (u16 offset) and `find_capability` default impl that walks PCI-SIG extended caps from 0x100. |
|
||
| `QuirkAction` | Enum: `WriteConfigByte/Word/Dword(offset, value)`, `AndOrMask(offset, width, mask, value)`, `ClearBit/SetBit(offset, width, bit)`, `NamedCallback(&'static str)`. |
|
||
| `MaskWidth` | `Byte` / `Word` / `Dword`. |
|
||
| `PciQuirkLookup` | Result struct: `flags: PciQuirkFlags`, `actions: Vec<QuirkAction>`. |
|
||
| `lookup_pci_quirks_full(info)` | New public function returning `PciQuirkLookup`. |
|
||
| `lookup_pci_quirks(info)` | **Unchanged** — delegates to `lookup_pci_quirks_full(info).flags`. |
|
||
| `dispatch_named_callback` | Internal dispatch table for compiled-in callbacks. |
|
||
|
||
#### Compiled-in callbacks (Phase R4)
|
||
|
||
| Callback name | Linux handler | Behavior |
|
||
|---------------|---------------|----------|
|
||
| `intel_no_aspm_l0s` | `quirk_disable_aspm_l0s` | Walks standard cap list for PCI Express (0x10), clears bit 0 of `PCI_EXP_LNKCTL` (cap+0x10). |
|
||
| `amd_ide_class_fix` | `quirk_amd_ide_mode` | If prog_if (offset 0x0A) reads 0, writes IDE class bytes 0x01 at offsets 0x09, 0x0A, 0x0B. |
|
||
| `ht_enable_msi_mapping` | `ht_enable_msi_mapping` | Walks standard cap list for HT MSI Mapping (0x08), sets enable bit at cap+0x04. |
|
||
| `p64h2_1k_io` | `quirk_p64h2_1k_io` | Clears `PCI_COMMAND_BUS_MASTER` (bit 2 of cmd reg 0x04) to prevent MMIO overflow during enumeration. |
|
||
| `intel_ntb_bar_fix` | `quirk_intel_ntb` | Toggles `PCI_COMMAND_MEMORY` (bit 1 of cmd reg) so the driver re-evaluates BAR sizes. |
|
||
| `ricoh_func0_dma_alias` | `quirk_dma_func0_alias` | No-op in Phase R4; reserved for Phase R4b IOMMU integration. |
|
||
| `glenfly_func0_dma_alias` | `quirk_dma_func0_alias` | No-op in Phase R4; reserved. |
|
||
| `asmedia_func0_dma_alias` | `quirk_dma_func0_alias` | No-op in Phase R4; reserved. |
|
||
| `tundra_func0_dma_alias` | `quirk_dma_func0_alias` | No-op in Phase R4; reserved. |
|
||
| `ite_func0_dma_alias` | `quirk_dma_func0_alias` | No-op in Phase R4; reserved. |
|
||
| `intel_bridge_dma_alias` | `quirk_use_pcie_bridge_dma_alias` | No-op in Phase R4; reserved. |
|
||
| `adaptec2_func0_dma_alias` | `quirk_fixed_dma_alias` | No-op in Phase R4; reserved. |
|
||
|
||
Unknown callback names log a warning and are no-ops. This keeps TOML
|
||
files self-describing: a future callback can be added in a TOML entry
|
||
without crashing older builds.
|
||
|
||
#### TOML schema (Phase R4)
|
||
|
||
Every `[[pci_quirk]]` entry now accepts an optional `action` field with
|
||
inline-table syntax. Backward-compatible: existing flag-only entries
|
||
(Phases R0–R3) parse unchanged with `action = None`.
|
||
|
||
```toml
|
||
# Imperative write
|
||
[[pci_quirk]]
|
||
vendor = 0x1002
|
||
device = 0x4380
|
||
flags = ["wrong_class"]
|
||
action = { kind = "write_config_byte", offset = 0x0A, value = 0x01 }
|
||
|
||
# Named callback
|
||
[[pci_quirk]]
|
||
vendor = 0x8086
|
||
device = 0x10A7
|
||
flags = ["no_aspm"]
|
||
action = { kind = "callback", name = "intel_no_aspm_l0s" }
|
||
|
||
# Read-modify-write
|
||
action = { kind = "and_or_mask", offset = 0x78, width = "word", mask = 0xFFFE, value = 0x0000 }
|
||
|
||
# Single bit
|
||
action = { kind = "clear_bit", offset = 0x04, width = "word", bit = 0 }
|
||
action = { kind = "set_bit", offset = 0x04, width = "word", bit = 1 }
|
||
```
|
||
|
||
Unknown `kind` values and unknown callback names are dropped with a
|
||
log warning — the entry still loads with `action = None` (graceful
|
||
degradation).
|
||
|
||
#### Files modified
|
||
|
||
| File | Change |
|
||
|------|--------|
|
||
| `local/recipes/drivers/redox-driver-sys/source/src/quirks/mod.rs` | +`PciConfigWriter` trait, +`QuirkAction` enum (6 variants), +`MaskWidth` enum, +`PciQuirkLookup` struct, +`lookup_pci_quirks_full`, +`dispatch_named_callback`, +7 callback impls, +11 Phase R4 tests, +MockConfig test helper. |
|
||
| `local/recipes/drivers/redox-driver-sys/source/src/quirks/toml_loader.rs` | +`load_pci_quirks_full`, +`parse_action` (7 kinds), +`parse_mask_width`, +`leak_static_str`, +6 Phase R4 tests. |
|
||
| `local/recipes/system/redbear-quirks/source/quirks.d/06-pci-header-quirks.toml` | 37 entries now carry `action` fields: 4 `amd_ide_class_fix`, 14 `intel_no_aspm_l0s`, 7 DMA-alias callbacks, 2 `ht_enable_msi_mapping`, 1 `p64h2_1k_io`, 2 `intel_ntb_bar_fix`. 4 `no_pm_reset` entries remain action-less (flag-marker only). |
|
||
|
||
#### Test coverage
|
||
|
||
- **56 tests pass** (39 prior + 11 `mod.rs` Phase R4 + 6 `toml_loader` Phase R4).
|
||
- `phase_r4_write_config_byte/word_executes` — basic write actions.
|
||
- `phase_r4_and_or_mask_byte` — RMW mask+value semantics.
|
||
- `phase_r4_clear_bit_clears_target` / `phase_r4_set_bit_sets_target` — single-bit ops.
|
||
- `phase_r4_unknown_callback_is_noop` — graceful unknown-name handling.
|
||
- `phase_r4_wildcard_action_is_none` — backward compat.
|
||
- `phase_r4_full_lookup_matches_flags_only_lookup` — `lookup_pci_quirks_full.flags == lookup_pci_quirks`.
|
||
- `phase_r4_no_flr_entries_have_no_action` — Phase R3 audit correction: compiled-in no-FLR entries remain flag-only.
|
||
- `phase_r4_intel_no_aspm_l0s_clears_link_ctl_bit0` — callback walks standard cap list, clears L0s bit, leaves L1 untouched.
|
||
- `phase_r4_amd_ide_class_fix_writes_class` — callback writes IDE class bytes.
|
||
- `phase_r4_callback_action_parses` / `write_config_byte_action_parses` / `clear_bit_action_parses` — TOML inline-table schema.
|
||
- `phase_r4_no_action_field_means_none` — backward compat for existing TOML entries.
|
||
- `phase_r4_unknown_callback_name_rejected_at_parse` / `unknown_action_kind_rejected` — graceful degradation.
|
||
|
||
#### Deferred items
|
||
|
||
- **Scheme daemon wiring**: `PciConfigWriter` is currently a trait
|
||
implemented only by `MockConfig` in tests. The PCI scheme daemon
|
||
(in `redox-driver-pci`/`pcid-spawner`) does not yet implement
|
||
`PciConfigWriter`. Wiring is a separate sub-task once the daemon's
|
||
config-space API is finalized.
|
||
- **DMA alias callbacks** (`ricoh_func0_dma_alias`, `glenfly_*`,
|
||
`asmedia_*`, `tundra_*`, `ite_*`, `intel_bridge_dma_alias`,
|
||
`adaptec2_func0_dma_alias`): registered as routable no-ops so TOML
|
||
files can declare the dependency, but the actual IOMMU alias
|
||
registration is deferred to Phase R4b pending the `iommu` daemon's
|
||
alias API. See `local/docs/IRQ-AND-LOWLEVEL-CONTROLLERS-ENHANCEMENT-PLAN.md`.
|
||
- **Multi-action entries**: `PciQuirkEntry.action` is `Option<QuirkAction>`,
|
||
not `Vec<QuirkAction>`. The Linux handlers Phase R4 covers each emit a
|
||
single config-space write; multi-step handlers (e.g. `quirk_pcie_pxh`)
|
||
will need either a separate `action_sequence: Vec<QuirkAction>` field
|
||
or a TOML-side `[[pci_quirk.action.steps]]` array in a future phase.
|
||
- **PCIe extended cap walk from TOML**: TOML actions accept raw `offset`
|
||
values up to u16. For quirks that need to find a cap first (e.g. `quirk_htirq`),
|
||
a future `action = { kind = "find_ext_cap", cap_id, then = "..." }`
|
||
syntax may be added, but is not needed for Phase R4's target handlers.
|
||
|
||
#### Migration guide (for downstream drivers)
|
||
|
||
Drivers that need to apply quirks imperatively should:
|
||
|
||
1. Call `lookup_pci_quirks_full(&info)` instead of `lookup_pci_quirks(&info)`.
|
||
2. Pass the returned flags to the existing code paths (no API change).
|
||
3. After flag accumulation, iterate `lookup.actions` and call
|
||
`action.execute(&my_pci_config_writer, &info)` for each.
|
||
|
||
Drivers that do not own a `PciConfigWriter` (e.g. consumers of just
|
||
the flag bitmask) continue to use `lookup_pci_quirks(&info)` and are
|
||
unaffected by Phase R4.
|
||
|
||
### Phase R5: Final Fixup Mining (3–5 days)
|
||
|
||
**Status:** ✅ **Implemented** (2026-06-07)
|
||
|
||
**Source:** Linux `DECLARE_PCI_FIXUP_FINAL` (233 entries) — Phase R5 covers
|
||
all READY entries that target AMD64 bare metal, QEMU, and modern peripherals
|
||
(64 entries, see `quirks.d/07-pci-final-quirks.toml`).
|
||
|
||
#### Design rationale
|
||
|
||
The Phase R4 action framework (single `QuirkAction` per entry) is reused
|
||
unchanged. Phase R5 added two new pattern sources:
|
||
|
||
1. **Inline `ClearBit` / `SetBit` actions** for the most common FINAL
|
||
pattern: a single config-space read-modify-write that flips one
|
||
specific bit. This collapses ~28 Linux handlers into 28 TOML
|
||
entries without requiring new callbacks.
|
||
2. **Two new named callbacks** for the two FINAL handlers that have
|
||
semantics not expressible as a single RMW:
|
||
- `cb_amd_fe_gate_ordering` — two-register write to AMD-762's
|
||
`0x4C` and `0x84` northbridge registers.
|
||
- `cb_amd_8131_mmrbc` — rev-gated, sets `BUS_NO_MMRBC` flag.
|
||
|
||
#### New flag bits (36–45, 2026-06-07)
|
||
|
||
| Bit | Flag | Linux source | Purpose |
|
||
|----:|------|--------------|---------|
|
||
| 36 | `BROKEN_INTX_MASKING` | `PCI_DEV_FLAGS_NO_BROKEN_INTX_MASKING` (negation) | Device lies about INTX masking; drivers must mask via MSI/MSI-X path |
|
||
| 37 | `NO_PME` | `pci_fixup_no_d0_pme` / `pci_fixup_no_msi_no_pme` | Device does not generate PME# from D0 — block D3 entry |
|
||
| 38 | `PCI_PROBLEM_FAIL` | `quirk_nopcipci` (SiS 5597/0496) | PCI-PCI bridge fails; mark as non-functional |
|
||
| 39 | `PCI_PROBLEM_TRITON` | `quirk_triton` (Intel 82378) | Triton host bridge has known broken peer-to-peer |
|
||
| 40 | `PCI_PROBLEM_NATOMA` | `quirk_natoma` (Intel 82371) | Natoma peer-to-peer has known bugs |
|
||
| 41 | `PCI_PROBLEM_VIAETBF` | `quirk_viaetbf` (VIA 82C597) | VIA VP3/VP2 ETBF bug — back-to-back CPU reads fail |
|
||
| 42 | `PCI_PROBLEM_VSFX` | `quirk_vsfx` (VIA 82C576) | VSFX VLC bit corrupts peer-to-peer DMA |
|
||
| 43 | `PCI_PROBLEM_ALIMAGIK` | `quirk_alimagik` (ALi M1647/M1651) | ALi M15x3 magic register write required |
|
||
| 44 | `PCI_AGP_FAIL` | `quirk_nopciamd` (AMD 0x7454 rev 0x13) | AGP unit on this northbridge does not function |
|
||
| 45 | `BUS_NO_MMRBC` | `quirk_amd_8131_mmrbc` (AMD 0x7450 rev ≤ 0x12) | This bus must not enable Memory-Mapped Read Boundary Control |
|
||
|
||
#### New callbacks
|
||
|
||
```rust
|
||
// local/recipes/drivers/redox-driver-sys/source/src/quirks/mod.rs
|
||
|
||
/// AMD-762 northbridge ordering — both 0x4C and 0x84 must be set in a
|
||
/// single callback; the registers are write-only, so a return value
|
||
/// cannot indicate success.
|
||
fn cb_amd_fe_gate_ordering<W: PciConfigWriter + ?Sized>(w: &W) -> bool {
|
||
let r4c = w.read_config_dword(0x4C);
|
||
w.write_config_dword(0x4C, r4c | 0x6);
|
||
let r84 = w.read_config_dword(0x84);
|
||
w.write_config_dword(0x84, r84 | 0x800000);
|
||
true
|
||
}
|
||
|
||
/// AMD-8131 rev-gated — for revisions > 0x12, MMRBC is fine; for rev
|
||
/// ≤ 0x12, mark the bus with BUS_NO_MMRBC so the consumer (PCIe port
|
||
/// driver) skips the boundary configuration.
|
||
fn cb_amd_8131_mmrbc<W: PciConfigWriter + ?Sized>(
|
||
w: &W,
|
||
info: &PciDeviceInfo,
|
||
) -> bool {
|
||
if info.revision > 0x12 {
|
||
return false;
|
||
}
|
||
// benign touch of offset 0 to mark device as enumerated
|
||
w.write_config_byte(0x00, w.read_config_byte(0x00));
|
||
true
|
||
}
|
||
```
|
||
|
||
Both callbacks are registered in `dispatch_named_callback`'s match
|
||
table; both callback names are added to `leak_static_str` in
|
||
`toml_loader.rs` so TOML can reference them as
|
||
`action = { kind = "callback", name = "amd_fe_gate_ordering" }`.
|
||
|
||
#### `07-pci-final-quirks.toml` content (64 entries)
|
||
|
||
| Category | Count | Examples | Pattern |
|
||
|----------|------:|----------|---------|
|
||
| Single-write config-RMW | 4 | Mellanox 0x15b3:0x1007/0x1008, Cyrix 0x110a:0x0001, Intel 0x8086:0x84cb, VIA 0x1106:0x3227 | Inline `ClearBit` / `SetBit` actions |
|
||
| Callbacks | 2 | AMD-762 0x1022:0x700C, AMD-8131 0x1022:0x7450 rev ≤ 0x12 | New `cb_amd_fe_gate_ordering` / `cb_amd_8131_mmrbc` |
|
||
| `NO_MSI` | 9 | ATI SBx00 0x1002:0x4386–0x438b (6), Intel MCH 0x8086:0x3590/0x3592/0x359e (3) | Flag-only |
|
||
| `NO_ATS` | 19 | AMD harvest 0x1002:0x98e4/0x6900/0x7310–0x734f (15), Intel E2000 0x8086:0x1451–0x145c rev < 0x20 (4) | Flag-only (rev-gated where applicable) |
|
||
| `BROKEN_INTX_MASKING` | 9 | Chelsio 0x1425:0x0030, Ralink 0x1814:0x0601, Compex 0x1b7c:0x0004, Creative 0x1102:0x000B, Realtek 0x10ec:0x8169, Intel i40e 0x8086:0x1572/0x1574/0x1580/0x37d2 | Flag-only |
|
||
| `NO_PME` | 3 | Asmedia 0x1b21:0x2142, Pericom 0x12D8:0x400e/0x400f | Flag-only |
|
||
| `pci_pci_problems` | 17 | SiS 0x1039:0x5597/0x0496, AMD 0x1022:0x7454, Intel 0x8086:0x122d/0x7030/0x1250/0x7100, VIA 0x1106:0x0597/0x0576, ALi 0x10b9:0x1647/0x1651, Intel 0x8086:0x1237/0x7180–0x7192 | Flag-only |
|
||
|
||
#### Files modified
|
||
|
||
| File | Change |
|
||
|------|--------|
|
||
| `local/recipes/drivers/redox-driver-sys/source/src/quirks/mod.rs` | +10 new flag bits (36–45) in `PciQuirkFlags`, +2 new callbacks `cb_amd_fe_gate_ordering` and `cb_amd_8131_mmrbc`, +2 match arms in `dispatch_named_callback`, +10 Phase R5 tests, updated `dispatch_named_callback` docstring. |
|
||
| `local/recipes/drivers/redox-driver-sys/source/src/quirks/toml_loader.rs` | +2 callback names in `leak_static_str`, +10 flag-name entries in `PCI_FLAG_NAMES` (lines 148–158), +8 Phase R5 tests. |
|
||
| `local/recipes/system/redbear-quirks/source/quirks.d/07-pci-final-quirks.toml` | **NEW** — 64 entries across 7 categories. All device IDs verified against `local/reference/linux-7.1/include/linux/pci_ids.h`. |
|
||
|
||
#### Test coverage
|
||
|
||
- **58 tests pass** (50 prior + 8 `toml_loader` Phase R5). Phase R5
|
||
mod.rs adds 10 tests; total 68 Phase R5-related assertions including
|
||
callbacks, inline RMW actions, and flag-presence audits.
|
||
- `phase_r5_amd_fe_gate_ordering_writes_both_registers` — both 0x4C
|
||
and 0x84 receive the documented OR-values.
|
||
- `phase_r5_amd_8131_mmrbc_rev_gate_blocks_high_rev` / `..._allows_low_rev`
|
||
— rev > 0x12 returns false; rev ≤ 0x12 returns true.
|
||
- `phase_r5_clear_bit_action_inline_parity` — Mellanox Tavor: clears
|
||
bit 6 of PCI_COMMAND.
|
||
- `phase_r5_set_bit_action_inline_vt8237` — VIA VT8237: sets bit 3 of
|
||
byte 0x5B.
|
||
- `phase_r5_broken_intx_masking_flag_present` / `..._no_pme_flag_present`
|
||
/ `..._bus_no_mmrbc_flag_present` — bit positions and queryability.
|
||
- `phase_r5_pci_pci_problems_flags_distinct` — all 7 PCI_PROBLEM_*
|
||
bits are pairwise disjoint.
|
||
- `phase_r5_intel_e2000_no_ats_rev_gated` — rev ≤ 0x1F matches, rev
|
||
0x20 does not.
|
||
- `phase_r5_audit_new_bits_unique` — all 10 new bits (36–45) are
|
||
pairwise disjoint.
|
||
- `phase_r5_pci_problem_fail_parses` / `..._broken_intx_masking_parses`
|
||
/ `..._no_pme_parses` / `..._bus_no_mmrbc_parses` — TOML flag-name
|
||
loading.
|
||
- `phase_r5_amd_fe_gate_ordering_callback_accepted` /
|
||
`..._amd_8131_mmrbc_callback_accepted` — TOML accepts new callback
|
||
names.
|
||
- `phase_r5_set_bit_with_byte_width_parses` /
|
||
`..._set_bit_with_word_width_parses` — `SetBit` action parsing.
|
||
|
||
#### Standalone TOML validator results
|
||
|
||
```
|
||
TOML files: 9
|
||
Total pci_quirk entries: 244
|
||
Distinct flag names used: 38
|
||
Distinct flag names defined: 46
|
||
✓ PASS: All 38 used flags are defined in PciQuirkFlags
|
||
Defined-but-unused flags (8): broken_intx, no_aer, no_ata_d3, no_bar,
|
||
no_io, no_pcie, rom_bar_overlap, use_vga
|
||
```
|
||
|
||
The 8 defined-but-unused flags are all pre-R5 reserved bits; they
|
||
remain in the bitmask for future use and are not a Phase R5 regression.
|
||
|
||
Per-file entry counts:
|
||
|
||
| File | Entries |
|
||
|------|--------:|
|
||
| `00-core.toml` | 41 |
|
||
| `05-pcie-quirks.toml` | 52 |
|
||
| `06-pci-header-quirks.toml` | 37 |
|
||
| `07-pci-final-quirks.toml` | 64 |
|
||
| `10-gpu.toml` | 33 |
|
||
| `15-audio.toml` | 7 |
|
||
| `20-usb.toml` | 3 |
|
||
| `30-net.toml` | 5 |
|
||
| `40-storage.toml` | 2 |
|
||
|
||
#### Deferred items (carried into Phase R5b+)
|
||
|
||
The following FINAL handlers were identified but require infrastructure
|
||
not yet in place. They are listed in `local/docs/QUIRKS-DEFERRED-FINAL.md`
|
||
as the R5b backlog:
|
||
|
||
1. **IO-APIC boot interrupt handlers** (8+ entries) — `quirk_disable_amd_813x_boot_interrupt` etc. — deferred pending IO-APIC subsystem.
|
||
2. **`pci_get_device` traversal handlers** (4+ entries) — `quirk_passive_release`, `quirk_xio2000a`, `quirk_amd_780_apc_msi` — deferred pending multi-function enumeration API.
|
||
3. **`nvidia_ion_ahci_fixup`** — requires `PCI_HAS_MSI_MASKING` flag bit
|
||
not yet added; deferred to a future phase.
|
||
4. **Resume/Suspend FINAL handlers** — `quirk_ryzen_xhci_d3hot`,
|
||
`quirk_radeon_pm`, `quirk_remove_d3hot_delay` — deferred to Phase R8
|
||
when PM infrastructure lands.
|
||
|
||
### Phase R6: xHCI Controller Flag Expansion (delivered 2026-06-07)
|
||
|
||
Expand `XhciControllerQuirkFlags` from 19 to cover the 29 missing Linux flags.
|
||
Only add flags that xhcid's driver code actually consumes — not all 29 at once.
|
||
|
||
#### Priority flags (plan target)
|
||
|
||
The plan's five priority flags were:
|
||
1. `XHCI_BROKEN_PORT_PED` — broken port detect (common on older Intel)
|
||
2. `XHCI_HW_LPM_DISABLE` — hardware LPM broken
|
||
3. `XHCI_MISSING_CAS` — missing CAS workaround
|
||
4. `XHCI_BROKEN_D3COLD_S2I` — D3cold broken on some AMD
|
||
5. `XHCI_EP_CTX_BROKEN_DCS` — endpoint context DCS bit broken
|
||
|
||
#### Phase R6 audit: PCI vs platform, plus a Linux-reserved bit
|
||
|
||
The five priority flags were audited against Linux 7.1's `xhci-pci.c`,
|
||
`xhci-plat.c`, `xhci-mtk.c`, `xhci-histb.c`, `xhci.c`, and `xhci-hub.c` to
|
||
determine which had a real PCI association versus which were
|
||
platform-device-only, and which had any consumer code at all. The audit
|
||
produced the following mapping:
|
||
|
||
| Linux flag | Bit | PCI-associable? | Consumer code? | Red Bear status |
|
||
|--------------------------|-----|-----------------|----------------|------------------|
|
||
| `XHCI_SSIC_PORT_UNUSED` | 22 | Yes (Intel Cherryview 0x22b5) | Yes (`xhci-pci.c:823-825`, suspend path) | **Real** — flag set via PCI table |
|
||
| `XHCI_MISSING_CAS` | 24 | Yes (Intel CV/SP/APL/DV) | Yes (CAS bit in endpoint context) | **Real** — flag set via PCI table |
|
||
| `XHCI_BROKEN_PORT_PED` | 25 | **No** (xhci-plat.c:266, xhci-histb.c, xhci-mtk.c — platform only) | Yes (`xhci-hub.c:563`) | **Forward-compat** — defined, no PCI entry |
|
||
| `XHCI_HW_LPM_DISABLE` | 29 | **No** (xhci-plat.c:260, xhci-histb.c:265, xhci-mtk.c:465 — platform only) | Yes (`xhci.c:4665`) | **Forward-compat** — defined, no PCI entry |
|
||
| `XHCI_BROKEN_D3COLD_S2I` | 41 | Yes (AMD Renoir 0x1639) | Yes (`xhci-pci.c:815-817`, suspend path) | **Real** — flag set via PCI table |
|
||
|
||
`XHCI_EP_CTX_BROKEN_DCS` (bit 42) was the fifth entry on the plan's list
|
||
but **is a Linux reserved-but-unused bit**: only the `BIT_ULL(42)`
|
||
definition exists in `xhci.h:1639`, with no consumer code anywhere in the
|
||
kernel (`xhci.c`, `xhci-pci.c`, `xhci-hub.c`, `xhci-plat.c`,
|
||
`xhci-mtk.c`, `xhci-histb.c` all reference it zero times) and no
|
||
PCI/vendor association. Adding it would have been a stub (no real
|
||
enforcement possible). It is therefore **NOT** added in Phase R6.
|
||
`XHCI_SSIC_PORT_UNUSED` (bit 22) is added in its place — it has both a
|
||
PCI association and a consumer site, making it the only other valid
|
||
replacement that pairs a flag with real enforcement.
|
||
|
||
#### Implementation summary
|
||
|
||
| Layer | What changed |
|
||
|-------|---------------|
|
||
| `XhciControllerQuirkFlags` (`mod.rs`) | 5 new bits: `SSIC_PORT_UNUSED` (22), `MISSING_CAS` (24), `BROKEN_PORT_PED` (25), `HW_LPM_DISABLE` (29), `BROKEN_D3COLD_S2I` (41). Bit positions match Linux `xhci.h` exactly per the existing docstring convention. |
|
||
| `xhci_controller_table.rs` | 3 new entries: Cherryview (0x22b5) × 2 (`SSIC_PORT_UNUSED`, `MISSING_CAS`) + AMD Renoir (0x1639) × 1 (`BROKEN_D3COLD_S2I`). No entry for `BROKEN_PORT_PED` / `HW_LPM_DISABLE` — Linux sets these only from `xhci-plat.c` / `xhci-mtk.c` / `xhci-histb.c`, never from `xhci-pci.c`. |
|
||
| `xhcid/src/xhci/mod.rs` | New `log_unenforced_xhci_quirks()` method called from `init()`. Emits a `warn!` line for each set-but-unenforced R6 flag, citing the Linux consumer site and the missing xhcid code path. **Observability, not fake enforcement.** |
|
||
| `XHCI_CONTROLLER_QUIRK_TABLE` size | 86 pre-R6 + 3 R6 = 89 entries. |
|
||
| Distinct xHCI flag bits defined | 19 pre-R6 + 5 R6 = 24 bits, no collisions. |
|
||
|
||
#### xhcid consumer wiring — real vs deferred
|
||
|
||
The Phase R6 work added a real xHCI quirk consumer wiring point in
|
||
`xhcid::Xhci::init()`. The function `log_unenforced_xhci_quirks` is the
|
||
**single hook point** through which every future xHCI quirk consumer in
|
||
xhcid can be discovered and audited: when a flag is set, the driver
|
||
either enforces it inline (if the code path exists in xhcid) or logs a
|
||
warn!-line that names the Linux consumer site and the missing Red Bear
|
||
subsystem. There are zero fake enforcement branches; the warn! lines
|
||
are honest diagnostic output.
|
||
|
||
| Flag | Enforced in xhcid R6? | What would enforce it |
|
||
|------|------------------------|----------------------|
|
||
| `SSIC_PORT_UNUSED` | No (observability only) | Suspend path that calls `xhci_ssic_port_unused_quirk()` — pending Phase R8 (PM infrastructure) |
|
||
| `MISSING_CAS` | No (observability only) | Endpoint context init that suppresses the CAS bit — pending context init wiring |
|
||
| `BROKEN_PORT_PED` | No (observability only) | Port disable path that checks `xhci-hub.c:563` semantics — pending xhcid port-disable code |
|
||
| `HW_LPM_DISABLE` | No (observability only) | LPM enable path that skips hardware LPM init — pending LPM code (xhcid has no LPM at all) |
|
||
| `BROKEN_D3COLD_S2I` | No (observability only) | Suspend path that calls `pci_d3cold_disable()` on S2Idle — pending Phase R8 |
|
||
|
||
The deferred items are listed in the R8 plan below as part of the
|
||
PM/suspend work. None of them block xhcid boot or basic enumeration.
|
||
|
||
#### Tests added (Phase R6, 8 new tests, 83 total passing)
|
||
|
||
| Test | Asserts |
|
||
|------|---------|
|
||
| `phase_r6_xhci_flags_present` | All 5 new bits are queryable and carry the right bit position |
|
||
| `phase_r6_xhci_lookup_intel_cherryview` | Intel 0x22b5 returns `SSIC_PORT_UNUSED` + `MISSING_CAS` + `INTEL_HOST` + `LPM_SUPPORT` |
|
||
| `phase_r6_xhci_lookup_amd_renoir` | AMD 0x1639 returns `BROKEN_D3COLD_S2I` |
|
||
| `phase_r6_xhci_platform_only_flags_never_set_by_pci_lookup` | Scans the entire PCI table: no entry sets `BROKEN_PORT_PED` or `HW_LPM_DISABLE`. Unknown vendor returns empty. |
|
||
| `phase_r6_xhci_audit_no_bit_collisions` | The 5 new bits are pairwise disjoint and disjoint from all 19 pre-R6 bits |
|
||
| `phase_r6_xhci_audit_total_flag_count` | Exactly 24 distinct xHCI flags are defined in the bitflags type |
|
||
| `phase_r6_xhci_table_size_grew_by_three` | Exactly 3 table entries are R6-only single-flag entries (Cherryview × 2 + Renoir × 1) |
|
||
| `phase_r6_xhci_lookup_unknown_returns_empty` | Unknown PCI vendor/device returns empty flag set |
|
||
|
||
#### Clippy / test status
|
||
|
||
- `cargo test --lib`: 83 passed; 0 failed; 0 ignored (was 75 in R5).
|
||
- `cargo clippy --lib`: 26 warnings, all pre-existing from R0–R5 (same count as the R5 baseline). No new warnings introduced by R6.
|
||
- `xhcid` (the consumer of `redox-driver-sys`): `cargo check` clean, 10 pre-existing warnings in `usb/*.rs` (unrelated to R6 — never-constructed structs, unused methods).
|
||
- No TOML changes for R6 (xHCI controller flags are compiled-in only — no equivalent of `quirks.d/0X-*.toml` for xHCI).
|
||
|
||
### Phase R7: xHCI Closure (COMPLETED 2026-06-07)
|
||
|
||
Following the R1–R6 comprehensive review, the gap analysis identified
|
||
seven items: (A) xHCI was compiled-in only while PCI was three-layer;
|
||
(B) three high-priority xHCI flags were missing; (C) twenty lower-priority
|
||
xHCI flags were deferred; (D) no driver consumed `PciQuirkFlags`;
|
||
(E) HID was entirely missing; (F) DMI coverage was narrow;
|
||
(G) seventeen phases remained on the roadmap.
|
||
|
||
The user picked "Multi-session R7–R10" scope: split the work into
|
||
four atomic commits across multiple sessions. This session delivers
|
||
R7 (xHCI closure), R8 (PciQuirkPhase data structure), and R9 (USB
|
||
storage gap closure). R10 (HID infrastructure) is deferred to the
|
||
next session.
|
||
|
||
**Subphase R7-A — xHCI TOML layer:** The xHCI controller quirk
|
||
table was a 1-layer system (compiled-in `xhci_controller_table.rs`
|
||
only). PCI has a 3-layer system (compiled-in + TOML + DMI). Phase R7-A
|
||
brought xHCI to parity with PCI's 3-layer architecture by adding:
|
||
|
||
- `XHCI_CONTROLLER_FLAG_NAMES` constant in `toml_loader.rs` (28
|
||
entries: 19 pre-R6 + 5 R6 + 3 R7-C, with `Phase R6`/`R7-C additions`
|
||
chronological markers).
|
||
- `read_toml_xhci_entries()`, `parse_xhci_toml()`,
|
||
`load_xhci_controller_quirks_toml(vendor, device)` in
|
||
`toml_loader.rs` for the new `[[xhci_controller_quirk]]` TOML
|
||
section.
|
||
- Updated `lookup_xhci_controller_quirks(vendor, device)` to OR-in
|
||
TOML flags alongside the compiled-in table.
|
||
- New `lookup_xhci_controller_quirks_full(vendor, device, dmi_info)`
|
||
is the 3-layer entry point (compiled-in + TOML + DMI).
|
||
- Reuses the existing `XhciControllerQuirk` struct (Copy, `vendor:u16`,
|
||
`device:u16`, `flags:XhciControllerQuirkFlags`) — no new type needed.
|
||
- New `quirks.d/25-xhci.toml` with 8 example entries sourced from
|
||
Linux 7.1 `xhci-pci.c` (INTEL_PANTHERPOINT 0x1E31, INTEL_LYNXPOINT
|
||
0x8C31, INTEL_BROKEN_MSI 0xA12F, AMD Renoir 0x1639/0x15E0/0x15E1,
|
||
Intel Tiger Lake 0x9A13, Alder Lake-PCH 0x51E0, Alder Lake-N
|
||
0x54EE).
|
||
- 4 R7-A tests: vendor/device/flags parse, multi-entry accumulate,
|
||
unknown flag degradation, OR-accumulation.
|
||
|
||
**Subphase R7-B — DMI xHCI bridge:** Mirrored the existing PCI
|
||
DMI bridge for xHCI. Linux itself has no DMI-based xHCI quirks
|
||
(the kernel uses `DECLARE_PCI_FIXUP_FINAL` keyed on PCI
|
||
vendor/device only), so the compiled-in `DMI_XHCI_QUIRK_RULES`
|
||
constant is empty. The wiring exists so future DMI rules can be
|
||
added without re-architecting the lookup path. Added:
|
||
|
||
- `DmiXhciQuirkRule` struct in `dmi.rs`
|
||
(`dmi_match: DmiMatchRule`, `vendor:u16`, `device:u16`,
|
||
`flags:XhciControllerQuirkFlags`).
|
||
- `apply_dmi_xhci_quirk_rules(vendor, device, dmi_info, rules)` in
|
||
`dmi.rs` — OR-accumulator that mirrors `apply_dmi_pci_quirk_rules`.
|
||
- `DMI_XHCI_QUIRK_RULES` compiled-in constant (empty).
|
||
- `load_dmi_xhci_quirks(vendor, device)` public function.
|
||
- `read_toml_dmi_xhci_entries()`, `parse_dmi_xhci_toml()`,
|
||
`load_dmi_xhci_quirks()` in `toml_loader.rs` for the new
|
||
`[[dmi_xhci_system_quirk]]` TOML section.
|
||
- 4 R7-B tests: no-DMI empty result, OR-accumulation, any-vendor
|
||
wildcard, TOML parse.
|
||
|
||
**Subphase R7-C — 3 high-priority xHCI flags:** The gap analysis
|
||
identified three xHCI flags from Linux 7.1 that were missing from
|
||
Red Bear. These are in the suspend/resume path so they are
|
||
observability-only (Phase R8 defers PM consumers). Bit positions
|
||
match `drivers/usb/host/xhci.h` exactly:
|
||
|
||
| Flag | Bit | Linux source | Consumer site |
|
||
|------|-----|--------------|---------------|
|
||
| `DEFAULT_PM_RUNTIME_ALLOW` | 33 | `xhci-pci.c:672, 720` | `xhci-pci.c` |
|
||
| `SNPS_BROKEN_SUSPEND` | 35 | `xhci.c:1038-1049` | `xhci.c` |
|
||
| `RESET_TO_DEFAULT` | 44 | `xhci.c:782`, `xhci-pci.c:888-899` | `xhci.c`, `xhci-pci.c` |
|
||
|
||
Six new PCI entries were added to `xhci_controller_table.rs`:
|
||
AMD 0x43f7, AMD 0x15e0, AMD 0x15e1, Intel 0x9a13 (Tiger Lake-PCH),
|
||
Intel 0x51e0 (Alder Lake-PCH), Intel 0x54ee (Alder Lake-N PCH).
|
||
All xHCI bit positions verified against Linux 7.1 `xhci.h:1586-1660`.
|
||
Seven new R7-C tests added.
|
||
|
||
**Test count progression:** R6 baseline 83 → +7 R7-C (90) → +9 R7-A+B
|
||
(99) → +7 R8 (106). 106/106 tests pass after Phase R7. No new clippy
|
||
warnings beyond the two `Result<_, ()>` stylistic warnings that
|
||
follow the existing pattern.
|
||
|
||
**Build output for R7:** `cargo test --lib` → `test result: ok. 106
|
||
passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in
|
||
0.00s`.
|
||
|
||
**xHCI bit count progression:** 19 pre-R6 → +5 R6 (24) → +3 R7-C
|
||
(27 total). Bit positions match Linux 7.1 `xhci.h` exactly.
|
||
xHCI table entry count: 89 pre-R7-C → +6 R7-C (95 total).
|
||
|
||
**Consumers wired:** `BROKEN_MSI` (xhcid `main.rs:69`),
|
||
`ZERO_64B_REGS` (xhcid `xhci/mod.rs:524, 542`). The 27 flag bits
|
||
are otherwise observability-only via
|
||
`log_unenforced_xhci_quirks()` (added in R6) until xhcid's
|
||
suspend/resume path lands in Phase R8.
|
||
|
||
### Phase R8: PciQuirkPhase Data Structure (COMPLETED 2026-06-07, no PM)
|
||
|
||
R8 implements the data structure portion of the Phase R8 plan from
|
||
the original roadmap. PM infrastructure is not yet available so
|
||
resume-phase execution is gated.
|
||
|
||
**Additions:**
|
||
|
||
- `PciQuirkPhase` enum in `mod.rs` with variants `Header`, `Final`,
|
||
`Enable`, `Resume`, `ResumeEarly`. Mirrors Linux 7.1
|
||
`include/linux/pci.h` macro family
|
||
(`DECLARE_PCI_FIXUP_HEADER` / `_FINAL` / `_ENABLE` / `_RESUME` /
|
||
`_RESUME_EARLY`).
|
||
- `phase: PciQuirkPhase` field added to `PciQuirkEntry`. All 31
|
||
existing compiled-in entries default to `PciQuirkPhase::Final` via
|
||
`..PciQuirkEntry::WILDCARD` — no entry-by-entry migration needed.
|
||
- `phase_visible(phase, pm_available)` helper in `mod.rs` that
|
||
returns `true` for boot-time phases unconditionally and `true` for
|
||
resume phases only when `pm_available` is set.
|
||
- `lookup_pci_quirks_full_with_pm(info, pm_available)` public
|
||
function in `mod.rs` that gates all three layers (compiled-in,
|
||
TOML, DMI) by phase visibility.
|
||
- `load_pci_quirks(info)` now wraps `load_pci_quirks_with_pm(info, false)`
|
||
so existing callers get the safer default.
|
||
- `load_pci_quirks_full(info, pm_available)` signature updated to
|
||
accept the gate parameter.
|
||
- TOML parser reads `phase = "header" | "final" | "enable" | "resume"
|
||
| "resume_early"` per `[[pci_quirk]]` entry. Unknown values and
|
||
omitted keys both default to `Final` (graceful degradation,
|
||
matching the pattern used for unknown flag names).
|
||
- 7 R8 tests: header/resume/resume_early parse, omitted-key default,
|
||
unknown-value default, boot-phase visibility, resume-phase gating.
|
||
|
||
**Test count:** R7 final 99 → +7 R8 (106). 106/106 tests pass.
|
||
|
||
**Build output for R8:** `cargo test --lib` → `test result: ok. 106
|
||
passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in
|
||
0.00s`.
|
||
|
||
**Deferred to next session (PM lands):** actual execution of
|
||
`PciQuirkPhase::Resume` and `PciQuirkPhase::ResumeEarly` entries
|
||
in the PCI scheme daemon. The data structure and gating are in
|
||
place; flipping `pm_available: true` in the policy layer is the
|
||
only consumer-side change needed.
|
||
|
||
### Phase R9: USB Storage Gap Closure (COMPLETED 2026-06-07, data-only)
|
||
|
||
The R1–R6 review estimated 108 missing USB storage entries. Re-mining
|
||
via `local/scripts/extract-linux-quirks.py` against Linux 7.1
|
||
`drivers/usb/storage/unusual_devs.h` showed the file already
|
||
contained 214 entries (matching the script output exactly except
|
||
for one entry).
|
||
|
||
**Action taken:** resynced the `30-storage.toml` file header to
|
||
reference Linux 7.1 (was 7.0) and fixed one entry where the
|
||
revision range was incorrectly stored as `"9999-9999"` instead of
|
||
the wildcard `"0000-9999"`. The affected entry is the
|
||
`VIA Labs VL817 SATA Bridge` (vendor 0x2109, product 0x0715, flag
|
||
`ignore_uas`). Linux source confirmed:
|
||
`UNUSUAL_DEV( 0x2109, 0x0715, 0x0000, 0x9999, ... )`.
|
||
|
||
**Verification:** `python3 local/scripts/extract-linux-quirks.py
|
||
local/reference/linux-7.1/drivers/usb/storage/unusual_devs.h` →
|
||
214 entries. `diff` against `30-storage.toml` → 0 lines. The file
|
||
is in full sync with Linux 7.1.
|
||
|
||
**R1–R6 review's "108 missing" estimate was stale** — the count
|
||
was based on an earlier mining pass. The current file is complete
|
||
relative to the script's output. The R9 work item is therefore a
|
||
data-correctness fix, not a coverage gap.
|
||
|
||
### Phase R10: HID Quirk System (3–5 days)
|
||
|
||
**Source:** Linux `drivers/hid/hid-quirks.c` (500 entries, 24 flags)
|
||
|
||
This is the largest completely missing quirk subsystem. HID quirks are structurally
|
||
identical to USB quirks (match by vendor/product, return flags) — the infrastructure
|
||
pattern is already proven.
|
||
|
||
**Actions:**
|
||
1. Create `HidQuirkFlags` bitflags type in `mod.rs` (24 flags matching Linux `HID_QUIRK_*`)
|
||
2. Create `hid_table.rs` with compiled-in HID quirk entries
|
||
3. Add `HidQuirkEntry` struct (vendor/product/flags)
|
||
4. Add `lookup_hid_quirks(vendor, product)` public function
|
||
5. Extend `toml_loader.rs` with `[[hid_quirk]]` TOML support
|
||
6. Mine all 500 entries from Linux's `drivers/hid/hid-quirks.c`
|
||
7. Wire HID quirk lookup into `usbhidd`/`evdevd` device initialization
|
||
8. Create `quirks.d/15-hid.toml` for HID quirk data
|
||
|
||
**Priority HID flags:**
|
||
- `NO_INIT_REPORTS` — most common (Corsair, Logitech, SteelSeries keyboards)
|
||
- `ALWAYS_POLL` — wireless input devices
|
||
- `MULTI_INPUT` — combo keyboard/trackpad devices
|
||
- `NOGET` — devices failing GET_REPORT (KVM switches, gamepads)
|
||
|
||
#### Phase R10 Implementation Report (2026-06-07)
|
||
|
||
**Scope completed**: structural infrastructure (items 1–5, 6, 8). Item 7
|
||
(consumer wiring) is partially complete — the data is now queryable via
|
||
`redox_driver_sys::quirks::lookup_hid_quirks()`, but `usbhidd`/`evdevd`
|
||
do not yet call it during device initialization. That integration belongs
|
||
to the input stack work tracked in
|
||
`local/docs/IRQ-AND-LOWLEVEL-CONTROLLERS-ENHANCEMENT-PLAN.md`.
|
||
|
||
**Entry count audit (Phase R10)**:
|
||
The plan listed 500 entries; the actual `hid_quirks[]` array in Linux 7.1
|
||
`drivers/hid/hid-quirks.c` lines 27-223 contains **191 entries**. The
|
||
500-number is the count of *all* HID-related arrays in the file
|
||
(`hid_quirks[]` + `hid_have_special_driver[]` + `hid_ignore_list[]`),
|
||
not the quirk table. The 191 number is what the table actually contains.
|
||
Two of those 191 are `HID_BLUETOOTH_DEVICE` (not USB) and are kept in
|
||
the table for forward compatibility with the Bluetooth HID transport
|
||
work; the lookup function ignores the bus type, so no consumer-side
|
||
filtering is needed.
|
||
|
||
**Flag count audit (Phase R10)**:
|
||
The plan listed 24 flags; Linux 7.1 `include/linux/hid.h` actually defines
|
||
**24 `HID_QUIRK_*` flags** (NOTOUCH, IGNORE, NOGET, HIDDEV_FORCE, BADPAD,
|
||
MULTI_INPUT, HIDINPUT_FORCE, ALWAYS_POLL, INPUT_PER_APP, X_INVERT,
|
||
Y_INVERT, IGNORE_MOUSE, SKIP_OUTPUT_REPORTS, SKIP_OUTPUT_REPORT_ID,
|
||
NO_OUTPUT_REPORTS_ON_INTR_EP, HAVE_SPECIAL_DRIVER,
|
||
INCREMENT_USAGE_ON_DUPLICATE, NOINVERT, IGNORE_SPECIAL_DRIVER,
|
||
POWER_ON_AFTER_BACKLIGHT, FULLSPEED_INTERVAL, NO_INIT_REPORTS, NO_IGNORE,
|
||
NO_INPUT_SYNC). All 24 are defined as bits in `HidQuirkFlags`. Only 9
|
||
are actually used in `hid_quirks[]` entries:
|
||
- `HID_QUIRK_ALWAYS_POLL` — 48 entries
|
||
- `HID_QUIRK_MULTI_INPUT` — 51 entries
|
||
- `HID_QUIRK_NOGET` — 43 entries
|
||
- `HID_QUIRK_NO_INIT_REPORTS` — 39 entries
|
||
- `HID_QUIRK_BADPAD` — 11 entries
|
||
- `HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE` — 9 entries
|
||
- `HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT` — 3 entries
|
||
- `HID_QUIRK_NO_INIT_REPORTS | HID_QUIRK_ALWAYS_POLL` — 6 entries
|
||
- `HID_QUIRK_MULTI_INPUT | HID_QUIRK_SKIP_OUTPUT_REPORTS` — 1 entry
|
||
- `HID_QUIRK_HIDINPUT_FORCE` — 1 entry
|
||
- `HID_QUIRK_FULLSPEED_INTERVAL` — 1 entry
|
||
|
||
The other 15 flags (e.g., `HID_QUIRK_HAVE_SPECIAL_DRIVER`,
|
||
`HID_QUIRK_IGNORE`, `HID_QUIRK_X_INVERT`) are reserved for future
|
||
hardware and runtime TOML overrides. They are reachable via
|
||
`[[hid_quirk]]` TOML entries.
|
||
|
||
**Bit position audit (Phase R10)**:
|
||
Linux's `include/linux/hid.h` has reserved bit gaps at positions 0, 8, 9,
|
||
15, 24, 25, 26, 27 — these correspond to removed/renamed flags
|
||
(`HID_QUIRK_INVERT` was removed in Linux 4.x; `HID_QUIRK_NO_EMPTY_INPUT`
|
||
and `HID_QUIRK_NO_INIT_INPUT_REPORTS` were renamed). The `HidQuirkFlags`
|
||
bitflags struct mirrors the gaps exactly so cross-referencing with
|
||
upstream documentation and debugging is clean.
|
||
|
||
**Files added/modified (Phase R10)**:
|
||
| File | Status | Lines | Purpose |
|
||
|------|--------|-------|---------|
|
||
| `quirks/mod.rs` | modified | +60 | `HidQuirkFlags` bitflags (24 bits), `HidQuirkEntry` struct, `lookup_hid_quirks()`, 8 R10 tests |
|
||
| `quirks/hid_table.rs` | NEW | 207 | 191 compiled-in entries with 5 `F_NN` const helpers for multi-flag entries |
|
||
| `quirks/toml_loader.rs` | modified | +85 | `HID_QUIRK_FLAG_NAMES` const, `load_hid_quirks()`, `read_toml_hid_entries()`, `parse_hid_toml()` |
|
||
| `local/recipes/system/redbear-quirks/source/quirks.d/40-hid.toml` | NEW | 967 | Runtime `[[hid_quirk]]` override file with all 191 entries |
|
||
|
||
**Tests added (Phase R10, 8 new tests, 114 total passing)**:
|
||
1. `phase_r10_hid_table_is_populated` — 191 entries loaded
|
||
2. `phase_r10_lookup_8bitdo_pro3_always_poll` — 8BitDo Pro 3 (0x2dc8:0x6009) → ALWAYS_POLL
|
||
3. `phase_r10_lookup_vendor_wildcard_matches_any_product` — ELAN (0x04f3, HID_ANY_ID) matches any product
|
||
4. `phase_r10_lookup_multi_flag_or_accumulates` — Corsair (0x1b1c:0x1b39) gets NO_INIT_REPORTS | ALWAYS_POLL
|
||
5. `phase_r10_lookup_unknown_returns_empty` — unknown IDs return empty
|
||
6. `phase_r10_hid_entry_matches_wildcard_vendor` — `HidQuirkEntry::matches()` wildcard semantics
|
||
7. `phase_r10_bit_positions_match_linux` — bit positions match `include/linux/hid.h` for all 9 used flags
|
||
8. `phase_r10_toml_hid_quirk_parses` — `[[hid_quirk]]` TOML parser produces correct entry
|
||
|
||
**Build status (Phase R10)**:
|
||
- `cargo build --lib`: clean, 0 errors, 0 warnings
|
||
- `cargo test --lib`: 114 passed, 0 failed (was 106 R8 → +8 R10)
|
||
- `cargo clippy --lib`: 30 warnings (was 29, +1 — new `load_hid_quirks()` follows existing `Result<_, ()>` pattern from R7-A/B/R8)
|
||
|
||
**Data extraction methodology (Phase R10)**:
|
||
The 191 entries were generated by a one-shot extraction script
|
||
(`/tmp/hid_quirks_extracted.txt` produced by the explore-agent
|
||
delegation `bg_cc6491e4`) and converted to Rust literals with
|
||
`awk` + decimal-to-hex conversion. Bit positions were verified
|
||
against `local/reference/linux-7.1/include/linux/hid.h`. Vendor
|
||
and product IDs were verified by spot-check against
|
||
`local/reference/linux-7.1/drivers/hid/hid-ids.h` for the 6d6
|
||
(AASHIMA), 04f3 (ELAN), 1b1c (Corsair), 2dc8 (8BitDo), and
|
||
0583 (Madcatz) entries.
|
||
|
||
**Open follow-ups (Phase R10)**:
|
||
- Item 7: Wire `lookup_hid_quirks()` into `usbhidd` and `evdevd`
|
||
device initialization. Currently `usbhidd` consumes the
|
||
`HID_QUIRK_*` data, but it has its own (minimal) lookup.
|
||
Tracked under input-stack maturity in the enhancement plan.
|
||
- DMI HID quirks: Linux has 33 DMI HID entries in
|
||
`drivers/hid/hid-dmi/quirks.c` (laptop keyboards, hotkeys).
|
||
These are *DMI-matched*, not vendor/product matched, and
|
||
follow a different pattern. Out of scope for Phase R10.
|
||
Tracked as Phase R13 (Laptop/Embedded DMI Quirks).
|
||
- `I2C_HID_QUIRK_*` flags: Linux has a parallel set of quirks
|
||
for I2C-HID devices (touchscreens). Out of scope for Phase R10
|
||
(separate header, separate table).
|
||
|
||
### Phase R11: ACPI DMI Quirk Expansion (2–3 days)
|
||
|
||
**Source:** Linux ACPI DMI tables (~115 total DMI rules across 8 subsystems)
|
||
|
||
Current Red Bear: 17 DMI rules (8 compiled + 7 TOML + 2 ACPI table quirks).
|
||
Linux: ~60 across OSI (20), EC (~8), x86 utils (8), sleep (5), video (5),
|
||
PCI IRQ (4), battery (4), blacklist (3), button (2).
|
||
|
||
**Actions:**
|
||
1. Mine Linux `drivers/acpi/osi.c` for the 20 _OSI blacklist/override entries
|
||
- These control which ACPI features the BIOS exposes
|
||
- Critical for avoiding firmware bugs on specific systems
|
||
2. Mine Linux `drivers/acpi/ec.c` for the ~8 embedded controller DMI entries
|
||
- EC timing and GPE storm handling
|
||
3. Mine Linux `drivers/acpi/x86/utils.c` for ACPI table overrides
|
||
4. Add `[[acpi_osi_quirk]]` TOML entries for _OSI control
|
||
5. Add `[[acpi_ec_quirk]]` TOML entries for EC behavior
|
||
6. Wire into `acpid`'s DMI matching infrastructure
|
||
|
||
**Note:** This phase depends on `acpid` having robust DMI serving via
|
||
`/scheme/acpi/dmi`. The infrastructure exists; it needs the data.
|
||
|
||
### Phase R12: DRM Panel Orientation Quirks (1 day, when compositor supports rotation)
|
||
|
||
**Source:** Linux `drivers/gpu/drm/drm_panel_orientation_quirks.c` (22 DMI entries)
|
||
|
||
Only affects x86 clamshell devices with portrait screens (GPD, Chuwi, etc.).
|
||
Low priority — niche laptop hardware. Add when Red Bear has display rotation.
|
||
|
||
### Phase R13: Laptop/Embedded DMI Quirks (3–5 days)
|
||
|
||
**Source:** Linux `drivers/platform/x86/` (61 files, 1153+ DMI entries)
|
||
|
||
This is the **largest missing quirk category** by entry count. Focus on:
|
||
- `touchscreen_dmi.c` (208 entries) — needed for any laptop/tablet with touchscreen
|
||
- `amd/pmc/pmc-quirks.c` (69 entries) — needed for AMD laptops
|
||
- `dell/dell-laptop.c` (61 entries) — needed for Dell hardware
|
||
- `intel/hid.c` (33 entries) — needed for Intel tablet sensors
|
||
- `asus-nb-wmi.c` (90 entries), `acer-wmi.c` (71 entries) — laptop hotkey/LED
|
||
|
||
**Sub-tasks:**
|
||
1. Create `PlatformDmiQuirks` lookup function in `mod.rs`
|
||
2. Create `quirks.d/80-platform-x86.toml` for runtime data
|
||
3. Wire into `inputd`, `pcid`, `acpid` as appropriate
|
||
4. Mine entries for target devices: Framework laptop, GPD/AYANEO handhelds
|
||
|
||
### Phase R14: CPU Bug Mitigation Infrastructure (5–8 days)
|
||
|
||
**Source:** Linux `arch/x86/kernel/cpu/bugs.c`, `intel.c`, `amd.c`
|
||
|
||
**CRITICAL** for security. Covers Spectre v1/v2, Meltdown, MDS, TAA, MMIO, RFDS, SRBDS, GDS, RETBleed, SRSO, ITS.
|
||
|
||
**Sub-tasks:**
|
||
1. Create `CpuBugFlags` bitflags type in kernel fork
|
||
2. Implement `cpu_has_bug(bug: CpuBug) -> bool` in kernel
|
||
3. Wire mitigations: KPTI, IBPB/STIBP, MDS clear, microcode version check
|
||
4. Add 11+ boot parameters: `redbear.spectre_v2=`, `redbear.mds=`, etc.
|
||
5. Document security model in `local/docs/SECURITY-MODEL.md`
|
||
|
||
### Phase R15: Timekeeping Quirk Infrastructure (2–3 days)
|
||
|
||
**Source:** Linux `arch/x86/kernel/tsc.c`, `hpet.c`, `drivers/clocksource/acpi_pm.c`
|
||
|
||
**Sub-tasks:**
|
||
1. TSC stability detection across cores
|
||
2. TSC rate validation against HPET
|
||
3. PMTMR blacklist (3 PIIX4/ICH4/ServerWorks entries)
|
||
4. HPET force-enable on Nvidia/ATI southbridges
|
||
5. DMI-based timer routing
|
||
6. Boot parameters: `redbear.tsc=`, `redbear.hpet=`
|
||
|
||
### Phase R16: Memory Configuration Quirks (4–6 days)
|
||
|
||
**Source:** Linux `arch/x86/kernel/cpu/mtrr/`, `arch/x86/mm/`
|
||
|
||
**Sub-tasks:**
|
||
1. MTRR cleanup optimization
|
||
2. MTRR BIOS inconsistency detection
|
||
3. PAT validation
|
||
4. Mine 13 AMD K8 NB MTRR fixups
|
||
5. Mine 6 AMD Fam10h NB MTRR fixups
|
||
6. Mine 6 AMD Fam15h NB MTRR fixups
|
||
7. Mine 4 Intel MCH/RAS fixups
|
||
8. NUMA DMI quirks
|
||
9. LA57 capability detection
|
||
|
||
### Phase R17: Early-Boot Chipset Quirks (3–4 days)
|
||
|
||
**Source:** Linux `arch/x86/kernel/early-quirks.c` (20 chipset handlers)
|
||
|
||
**Sub-tasks:**
|
||
1. Determine if early PCI scan should move from bootloader to kernel
|
||
2. Implement 20 chipset handlers
|
||
3. Intel stolen memory reservation for 38 GPU families
|
||
4. Wire `intel_remapping_check` into IRQ subsystem
|
||
5. These MUST run before `pcid` userspace enumeration
|
||
|
||
### Phase R18: Storage Controller Quirks (2–3 days)
|
||
|
||
**Source:** Linux `drivers/ata/` (26 entries), `drivers/nvme/host/pci.c` (2 entries)
|
||
|
||
**Sub-tasks:**
|
||
1. Mine 18 libata-core.c entries → TOML
|
||
2. Mine 3 AHCI entries → TOML
|
||
3. Mine 2 PIIX entries → TOML
|
||
4. Mine 2 NVMe entries → TOML
|
||
5. Wire into `lived` storage daemon
|
||
|
||
### Phase R19: Network Controller PCI Quirks (3–4 days)
|
||
|
||
**Source:** Linux `drivers/net/ethernet/`, `drivers/net/wireless/`
|
||
|
||
**Sub-tasks:**
|
||
1. Mine Broadcom TIGON3 (6 entries) → TOML
|
||
2. Mine Attansic/Atheros MSI disable quirks → TOML
|
||
3. Mine Intel e1000e / igb / ixgbe quirks → TOML
|
||
4. Mine Realtek r8169 quirks → TOML
|
||
5. Mine 12 rtl8xxxu wireless quirks → TOML
|
||
6. Wire into `e1000d`/`igb`/`ixgbed`/`r8169` driver daemons
|
||
|
||
### Phase R20: USB Audio Codec Quirks (2–3 days)
|
||
|
||
**Source:** Linux `sound/usb/quirks.c` (53 entries), `mixer_quirks.c` (6), `implicit.c` (4)
|
||
|
||
**Sub-tasks:**
|
||
1. Define `AudioQuirkFlags` bitflags matching Linux
|
||
2. Create `audio_table.rs` with compiled-in entries
|
||
3. Mine 53 USB audio quirks
|
||
4. Add 6 mixer quirks + 4 implicit feedback entries
|
||
5. Wire into `usbaudio` driver daemon
|
||
6. Fix the existing 7 undefined flags in `15-audio.toml`
|
||
|
||
### Phase R21: AMD IOMMU Quirks (1 day)
|
||
|
||
**Source:** Linux `drivers/iommu/amd/quirks.c` (3 DMI entries)
|
||
|
||
**Sub-tasks:**
|
||
1. Add 3 known DMI entries (Dell Inspiron 7375, Dell Latitude 5495, Lenovo IdeaPad 330S 15ARR)
|
||
2. Wire into `iommu` daemon
|
||
3. Coordinate with `BROKEN_BRIDGE` PCI flag
|
||
|
||
### Phase R22: Boot Parameter Quirk Infrastructure (2–3 days)
|
||
|
||
**Source:** Linux `arch/x86/` (141 `__setup`/`early_param` entries across 70 files)
|
||
|
||
**Sub-tasks:**
|
||
1. Implement `__setup`/`early_param` infrastructure in Redox kernel
|
||
2. Implement 8-10 most-important parameters: `pci=`, `acpi=`, `hpet=`, `tsc=`, `noapic`, `idle=`, mitigations
|
||
3. Document in `local/docs/BOOT-PARAMETERS.md`
|
||
4. Add test suite for boot parameter handling
|
||
|
||
### Mining Strategy
|
||
|
||
Do **not** blindly import Linux's 701 PCI quirk entries. The correct approach:
|
||
|
||
1. **Only add entries for hardware Red Bear actually targets** — AMD64 bare metal
|
||
with AMD and Intel GPUs, Intel Wi-Fi, USB controllers, and storage controllers.
|
||
2. **Only add entries with documented real-world impact** — Linux quirks exist for
|
||
hardware from 1995–2025. Red Bear targets modern (2020+) hardware first.
|
||
3. **Use TOML files by default** — Compiled-in table is for boot-critical entries
|
||
only. Everything else belongs in `quirks.d/*.toml`.
|
||
4. **Review-gate GPU entries** — Each AMD/Intel GPU quirk entry should reference
|
||
the Linux commit that introduced it, the hardware errata it addresses, and
|
||
whether that errata applies to Red Bear's driver stack.
|
||
5. **Track provenance** — Every mined entry should have a comment referencing the
|
||
Linux source file and function name it was derived from.
|
||
6. **Class-based first** — `DECLARE_PCI_FIXUP_CLASS_*` entries are the easiest to
|
||
port (pure matching, no imperative code) and provide the broadest coverage.
|
||
7. **Vendor priority** — Intel (391 Linux entries) > AMD/ATI (87) > VIA (42) >
|
||
NVIDIA (35) — match our hardware target priority.
|
||
8. **Subsystem scope** — PCI quirks are the core but HID (819), ACPI DMI (~115),
|
||
and USB storage (323) represent additional quirk domains with their own
|
||
flag types and matching rules.
|
||
|
||
### Effort Estimates (pre-audit baseline)
|
||
|
||
Per-phase effort estimates with dependency notes. **Adjusted estimates
|
||
that include the 5 critical blockers from the R1–R10 audit are in the
|
||
"R1–R10 Comprehensive Audit" section below — see "Adjusted Phase
|
||
Estimates" table for the post-audit timeline (65–100 days, +20 days for
|
||
critical blockers).**
|
||
|
||
| Phase | Description | Estimate | Blockers / Dependencies |
|
||
|---|---|---|---|
|
||
| R1 | Class-based and early fixups | 1–2 days | None |
|
||
| R2 | Tier 1 flag addition | 1 day | R1 |
|
||
| R3 | Header fixup mining | 3–5 days | R2 |
|
||
| R4 | QuirkAction mechanism | 2–3 days | R2 |
|
||
| R5 | Final fixup mining | 3–5 days | R4 |
|
||
| R6 | xHCI flag expansion | 1–2 days | xhcid driver maturity |
|
||
| R7 | GPU device table expansion | 2–3 days | R2 |
|
||
| R8 | Resume/suspend quirks | 1–2 days (data), blocked (execution) | PM infrastructure |
|
||
| R9 | USB storage gap closure | 1 day | None |
|
||
| R10 | HID quirk system | 3–5 days | None (infrastructure exists) |
|
||
| R11 | ACPI DMI quirk expansion | 2–3 days | acpid DMI infrastructure |
|
||
| R12 | DRM panel orientation quirks | 1 day | Compositor rotation support |
|
||
| R13 | Laptop/Embedded DMI Quirks | 3–5 days | None |
|
||
| R14 | CPU Bug Mitigation Infrastructure | 5–8 days | Kernel infrastructure |
|
||
| R15 | Timekeeping Quirk Infrastructure | 2–3 days | None |
|
||
| R16 | Memory Configuration Quirks | 4–6 days | None |
|
||
| R17 | Early-Boot Chipset Quirks | 3–4 days | Kernel early boot |
|
||
| R18 | Storage Controller Quirks | 2–3 days | None |
|
||
| R19 | Network Controller PCI Quirks | 3–4 days | None |
|
||
| R20 | USB Audio Codec Quirks | 2–3 days | audio stack maturity |
|
||
| R21 | AMD IOMMU Quirks | 1 day | iommu daemon |
|
||
| R22 | Boot Parameter Quirk Infrastructure | 2–3 days | Kernel cmdline parsing |
|
||
| **Total (pre-audit)** | | **44–68 days** | |
|
||
|
||
### Cross-Subsystem Quirk Architecture
|
||
|
||
Red Bear's quirk system is designed to be extensible to new subsystems. Each
|
||
subsystem follows the same pattern:
|
||
|
||
```
|
||
Subsystem Quirks
|
||
├── XxxQuirkFlags (bitflags u64) — flags for that subsystem
|
||
├── XxxQuirkEntry (match struct) — vendor/device/class matching
|
||
├── xxx_table.rs — compiled-in entries
|
||
├── toml_loader.rs extension — [[xxx_quirk]] TOML support
|
||
├── quirks.d/NN-subsystem.toml — runtime data
|
||
└── Driver consumer — driver that checks flags
|
||
```
|
||
|
||
Current subsystems:
|
||
- **PCI** — ✅ Complete infrastructure
|
||
- **USB device** — ✅ Complete infrastructure
|
||
- **USB storage** — ✅ Separate inline module in usbscsid
|
||
- **xHCI controller** — ✅ Data present, wiring pending
|
||
- **DMI system** — ✅ Complete infrastructure
|
||
- **ACPI table** — ✅ TOML + acpid
|
||
- **HID** — ❌ No infrastructure (Phase R10)
|
||
- **DRM panel** — ❌ No infrastructure (Phase R12)
|
||
- **ACPI OSI/EC** — ❌ No infrastructure (Phase R11)
|
||
- **Platform/x86 DMI** — ❌ No infrastructure (Phase R13)
|
||
- **CPU bug mitigation** — ❌ No infrastructure (Phase R14)
|
||
- **Timekeeping (TSC/HPET/PMTMR)** — ❌ No infrastructure (Phase R15)
|
||
- **Memory config (MTRR/PAT/NUMA)** — ❌ No infrastructure (Phase R16)
|
||
- **Early-boot chipset** — ❌ No infrastructure (Phase R17)
|
||
- **Storage controller** — ❌ No infrastructure (Phase R18)
|
||
- **Network controller** — ❌ No infrastructure (Phase R19)
|
||
- **USB audio** — ❌ No infrastructure (Phase R20)
|
||
- **AMD IOMMU** — ❌ No infrastructure (Phase R21)
|
||
- **Boot parameters** — ❌ No infrastructure (Phase R22)
|
||
|
||
## R1–R10 Comprehensive Audit (2026-06-07)
|
||
|
||
This audit was performed after R0–R10 implementation (commits `86902d481`,
|
||
`5e44191c9`, `b56b810c0`, `b324cf67e`, `6f1df4f04` on `0.2.3`) and
|
||
captures the current consumer-wiring, dormant-feature, and adjacent-technology
|
||
state of the hardware quirks system. Three parallel explore agents
|
||
(`bg_714f844f` gaps/TODOs, `bg_1219aaa3` consumer audit, `bg_c8826a88`
|
||
adjacent-tech audit) surveyed the codebase; their findings are synthesized
|
||
below.
|
||
|
||
**Audit inputs**:
|
||
- `local/recipes/drivers/redox-driver-sys/source/src/quirks/` — core library
|
||
- `local/sources/base/drivers/{pcid,pcid-spawner,xhcid,usbhidd,acpid,evdevd,redox-drm}/` — consumers
|
||
- `local/recipes/drivers/linux-kpi/source/src/rust_impl/pci.rs` — C FFI bridge
|
||
- `local/recipes/gpu/amdgpu/source/{amdgpu_redox_main.c,redox_stubs.c}` — C driver FFI consumers
|
||
- `local/recipes/system/redbear-info/`, `redbear-hwutils/`, `redbear-quirks/`, `redbear-phase-acpi-check.rs` — diagnostic / data producers
|
||
- `local/reference/linux-7.1/` — reference source-of-truth
|
||
|
||
### Consumer Wiring Status (as of 2026-06-07)
|
||
|
||
| Lookup function | Production caller | Status | File:line |
|
||
|---|---|---|---|
|
||
| `lookup_pci_quirks` | `PciDevice::quirks()` | Internal | `redox-driver-sys/src/pci.rs:248` |
|
||
| `lookup_pci_quirks` | `pci_get_quirk_flags` C FFI | Wired | `linux-kpi/src/rust_impl/pci.rs:515` |
|
||
| `lookup_pci_quirks` | amdgpu C driver | Wired (via FFI) | `amdgpu_redox_main.c:317-332` |
|
||
| `lookup_pci_quirks` | `redbear-info` | Wired (observability) | `redbear-info/src/main.rs:1054` |
|
||
| `lookup_pci_quirks` | `lspci` | Wired (observability) | `redbear-hwutils/src/bin/lspci.rs:104` |
|
||
| `lookup_pci_quirks_full` | **NONE** | Dormant | — |
|
||
| `lookup_pci_quirks_full_with_pm` | **NONE** | Dormant | — |
|
||
| `lookup_usb_quirks` | `lsusb` | Wired (observability) | `redbear-hwutils/src/bin/lsusb.rs:231` |
|
||
| `lookup_usb_quirks` | `usbhidd` | **NOT WIRED** | — |
|
||
| `lookup_hid_quirks` | **NONE** | **Dormant** | — |
|
||
| `lookup_xhci_controller_quirks` | `xhcid` | Partial (flags only) | `xhcid/src/main.rs:152` |
|
||
| `lookup_xhci_controller_quirks_full` | **NONE** | Dormant | — |
|
||
| `apply_dmi_pci_quirk_rules` | Internal (TOML loader) | Internal only | `quirks/dmi.rs:359` |
|
||
| `apply_dmi_xhci_quirk_rules` | Internal (TOML loader) | Internal only | `quirks/dmi.rs:325` |
|
||
| `pci_has_quirk` (linux-kpi C FFI) | amdgpu C | Wired (flags) | `amdgpu_redox_main.c:323-332` |
|
||
| `pci_has_quirk` / `pci_get_quirk_flags` (linux-kpi C FFI) | `redbear-iwlwifi` | **NOT WIRED** | — |
|
||
|
||
### Critical Blockers (5)
|
||
|
||
#### Blocker 1: PciConfigWriter production impl is missing
|
||
|
||
**File:** `local/recipes/drivers/redox-driver-sys/source/src/quirks/mod.rs:229-277` (trait def)
|
||
**Test impl:** `mod.rs:1410` (`impl PciConfigWriter for MockConfig`)
|
||
|
||
The `PciConfigWriter` trait has 6 methods (`read_config_byte`,
|
||
`write_config_byte`, `read_config_word`, `write_config_word`,
|
||
`read_config_dword`, `write_config_dword`). The **only** implementation is
|
||
`MockConfig` in the test module. There is zero production impl in
|
||
`pcid`, `pcid-spawner`, `redox-driver-pci`, or any other driver.
|
||
|
||
The trait documentation at `:218-223` explicitly states:
|
||
*"Drivers that wish to apply imperative config-space writes from a quirk
|
||
implement this trait. The PCI scheme daemon is the canonical producer."*
|
||
— but `pcid::driver_interface::PciFunctionHandle::write_config` at
|
||
`local/sources/base/drivers/pcid/src/driver_interface/mod.rs:445`
|
||
sends `PcidClientRequest::WriteConfig` IPC, which is **not** a
|
||
`PciConfigWriter` impl.
|
||
|
||
`QuirkAction::execute()` (`:377`) is therefore dead code in production.
|
||
`PciQuirkLookup.actions` (`:816`) is populated by every
|
||
`lookup_pci_quirks_full()` call but is never consumed.
|
||
|
||
**Remediation:** Implement `PciConfigWriter` for the pcid client handle
|
||
(or a wrapper type) in
|
||
`local/sources/base/drivers/pcid/src/driver_interface/mod.rs`, then wire
|
||
`lookup_pci_quirks_full()` → iterate `actions` → call
|
||
`action.execute(&writer, &info)` in the appropriate PCI enumeration path
|
||
in `pcid` or `pcid-spawner`.
|
||
|
||
**Status:** ✅ RESOLVED 2026-06-07 — `local/sources/base/drivers/pcid/src/quirks.rs`
|
||
(commit `676af02e` on `redbear-working`). Three pieces land:
|
||
1. `PcidConfigWriter<'a>` wraps `&Pcie` + `PciAddress` and impls
|
||
`PciConfigWriter`. Byte/word writes go through a 4-byte aligned
|
||
read-modify-write so sub-dword actions land on the correct bits
|
||
without disturbing neighbours.
|
||
2. `build_device_info` converts pcid's enumeration data
|
||
(`FullDeviceId`, the 6-entry BAR array, the capability vector,
|
||
and the `EndpointHeader`) into the `PciDeviceInfo` shape that
|
||
`redox_driver_sys::quirks` expects. Subsystem IDs are read
|
||
from offset 0x2C for header type 0 (endpoint) only; bridges
|
||
return `(0, 0)` per PCI Local Bus 3.0 §6.2.1.
|
||
3. `apply_pci_quirks` calls `lookup_pci_quirks_full(info, pm_available=false)`,
|
||
logs the resulting flags at info-level, then iterates
|
||
`lookup.actions` calling `QuirkAction::execute` against the live
|
||
PCIe config region. R8 phase gating is honoured by always
|
||
passing `pm_available=false` (pcid runs before PM); Header/Final
|
||
phases fire, Resume/ResumeEarly are silently skipped. NamedCallback
|
||
actions are warn-logged since pcid has no callback registry.
|
||
|
||
Wiring (`pcid/src/main.rs:137-150`): `build_device_info` and
|
||
`apply_pci_quirks` run after the BAR and capability scans but
|
||
before the `Func` is built and inserted into the tree. The
|
||
`EndpointHeader` is consumed by the `Func` only after quirks
|
||
have finished their read-modify-write work on the same function.
|
||
|
||
12 unit tests cover the mock writer (byte/word/dword round-trip,
|
||
neighbour preservation), every `QuirkAction` variant dispatched
|
||
against the mock, the BAR conversion for all four `PciBar`
|
||
variants, the capability conversion (Vendor variant; other
|
||
variants share the dispatch shape), and a synthetic PCI Express
|
||
capability-list walker. The mock is `pub(crate)` so other pcid
|
||
modules can use it for further tests.
|
||
|
||
`cargo test -p pcid` passes 12/12. `cargo check` is clean. No
|
||
new clippy warnings in pcid (the pre-existing warnings in
|
||
`bar.rs`/`cap.rs`/`msi.rs`/`irq_helpers.rs`/`mod.rs` are unrelated).
|
||
|
||
#### Blocker 2: acpid does not serve DMI/SMBIOS at `/scheme/acpi/dmi`
|
||
|
||
**File:** `local/sources/base/drivers/acpid/src/scheme.rs` (no DMI endpoint)
|
||
**Consumer:** `local/recipes/drivers/redox-driver-sys/source/src/quirks/dmi.rs:136-142` (`read_dmi_info`)
|
||
|
||
`read_dmi_info()` opens `/scheme/acpi/dmi` as a plain text file (not a
|
||
scheme) and parses `key=value` lines. acpid serves ACPI tables at
|
||
`/scheme/acpi/...` (RSDP, RSDT, XSDT, MADT, FADT, etc.) but has **no DMI
|
||
endpoint**. The only producer of `/scheme/acpi/dmi` is
|
||
`local/recipes/system/redbear-hwutils/source/src/bin/redbear-phase-acpi-check.rs:181`,
|
||
which writes a synthetic `sys_vendor=Framework` for test fixtures.
|
||
|
||
`DmiInfo::default()` is the silent fallback when `/scheme/acpi/dmi` is
|
||
absent. All 8 compiled-in DMI rules in
|
||
`local/recipes/drivers/redox-driver-sys/source/src/quirks/dmi.rs:373` and
|
||
all 7 TOML `[[dmi_system_quirk]]` entries in
|
||
`local/recipes/system/redbear-quirks/source/quirks.d/` are inert.
|
||
|
||
The i2c-hidd driver at
|
||
`local/sources/base/drivers/input/i2c-hidd/src/quirks.rs:75` reads
|
||
`format!("/scheme/acpi/dmi/{field}")` and is also dormant for the same
|
||
reason.
|
||
|
||
**Remediation:** Add a `HandleKind::Dmi` variant to acpid's scheme
|
||
(`local/sources/base/drivers/acpid/src/scheme.rs`) and parse SMBIOS entry
|
||
points (Type 0 BIOS info, Type 1 system info) from
|
||
`/scheme/kernel.acpi/rxsdt`. Serve at `/scheme/acpi/dmi/<field>` with
|
||
keys: `sys_vendor`, `board_vendor`, `board_name`, `board_version`,
|
||
`product_name`, `product_version`, `bios_version`, plus the new
|
||
`bios_vendor` and `bios_date` fields (see Blocker 5).
|
||
|
||
**Status:** ✅ RESOLVED 2026-06-07 — Three-part chain lands across
|
||
bootloader, kernel, and acpid:
|
||
|
||
1. **bootloader** (commit `259a621`, `local/sources/bootloader/src/os/uefi/smbios.rs`):
|
||
new `find_smbios()` helper searches UEFI Configuration Tables for
|
||
`SMBIOS3_TABLE_GUID` (0xF2FD1544-9794-4A2C-992E-E5BBCF20E394), parses
|
||
the entry point with `dmidecode::EntryPoint::search`, then copies the
|
||
EPS and the SMBIOS table into page-aligned buffers. Four new u64
|
||
fields on `KernelArgs` (`smbios_eps_base/size`, `smbios_table_base/size`)
|
||
carry the addresses to the kernel.
|
||
2. **kernel** (commit `a4ba465`, `local/sources/kernel/src/scheme/smbios.rs`):
|
||
new `SmbiosScheme` exposes `/scheme/kernel.smbios/eps` and
|
||
`/scheme/kernel.smbios/table` to userspace. Mirrors `DtbScheme`.
|
||
The raw table is sufficient — the SMBIOS 2.x and 3.x structure
|
||
formats are identical, so the EPS version is irrelevant to the
|
||
parser in acpid. The scheme is silently inactive when SMBIOS3 is
|
||
not present (BIOS or non-UEFI paths).
|
||
3. **acpid** (commit `fa91cee4`, `local/sources/base/drivers/acpid/src/dmi.rs`):
|
||
new `dmi.rs` module walks the SMBIOS structure table, splits each
|
||
structure into formatted area + string area (1-based string indices,
|
||
null-terminated, double-null terminator), and extracts 9 DMI fields
|
||
(the same set Blocker 5 added to the consumer-side `DmiInfo`):
|
||
`sys_vendor`, `board_vendor`, `board_name`, `board_version`,
|
||
`product_name`, `product_version`, `bios_version`, `bios_vendor`,
|
||
`bios_date`. Two scheme endpoints:
|
||
- `/scheme/acpi/dmi` (single file, key=value text, the format
|
||
`parse_dmi_data()` in redox-driver-sys expects)
|
||
- `/scheme/acpi/dmi/{field}` (per-field files, the format i2c-hidd
|
||
opens individually)
|
||
|
||
Eight new dmi.rs unit tests cover Type 0/1/2 parsing, the key=value
|
||
text round-trip, the malformed-table graceful paths, and the
|
||
string-index-0-means-absent semantic. All 120 redox-driver-sys tests
|
||
continue to pass.
|
||
|
||
**Net effect:** Every compiled-in DMI rule in `dmi.rs:373` and every
|
||
`[[dmi_system_quirk]]` / `[[dmi_xhci_system_quirk]]` TOML entry now
|
||
fires against real firmware data, not synthetic fixtures. The
|
||
`read_dmi_info()` warn-once (Gap 17, commit `abce96f1e`) becomes a
|
||
no-op on real hardware.
|
||
|
||
#### Blocker 3: usbhidd has zero HID/USB quirk consumption
|
||
|
||
**File:** `local/sources/base/drivers/input/usbhidd/src/main.rs` (no lookup_*_quirks references)
|
||
|
||
usbhidd is the primary consumer of USB device and HID device quirks, but
|
||
has **zero** calls to `lookup_usb_quirks` or `lookup_hid_quirks`. The
|
||
entire R10 HID quirks layer (24 flags defined, 191 compiled-in entries,
|
||
`40-hid.toml` runtime data) is inert at runtime. The R6-R9 USB storage
|
||
data (214 entries) is also unwired — `usbscsid` ships its own inline
|
||
unusual_devs handler separate from the central `lookup_usb_quirks` API.
|
||
|
||
**Remediation:** Wire `lookup_usb_quirks(vendor, product)` and
|
||
`lookup_hid_quirks(vendor, product)` into `usbhidd`'s device enumeration
|
||
path (`local/sources/base/drivers/input/usbhidd/src/reqs.rs` or main
|
||
attach flow). Apply returned flags (e.g., `NO_LPM`, `RESET_DELAY`,
|
||
`NO_SET_INTF`, `HID_QUIRK_NOGET`, `HID_QUIRK_ALWAYS_POLL`,
|
||
`HID_QUIRK_BADPAD`) to device initialization and report parsing.
|
||
|
||
#### Blocker 4: xhcid does not call the full lookup variant
|
||
|
||
**File:** `local/sources/base/drivers/usb/xhcid/src/main.rs:152` (calls `lookup_xhci_controller_quirks` only)
|
||
**Full variant:** `local/recipes/drivers/redox-driver-sys/source/src/quirks/mod.rs:1127-1154` (`lookup_xhci_controller_quirks_full`)
|
||
|
||
xhcid calls `lookup_xhci_controller_quirks(vendor, device)` and logs the
|
||
result, but:
|
||
1. **No `QuirkAction` callbacks** — the `_full` variant returns a
|
||
`PciQuirkLookup` containing `actions: Vec<QuirkAction>`. xhcid discards
|
||
this and uses only flags.
|
||
2. **No DMI rules** — the full variant calls `apply_dmi_xhci_quirk_rules()`,
|
||
but xhcid never invokes the full variant.
|
||
3. **`log_unenforced_xhci_quirks()` not called** — the helper at
|
||
`quirks/mod.rs:1169-1175` exists for warning about R8 (suspend/resume)
|
||
flags that are defined but not enforced; xhcid does not call it.
|
||
4. The R6 commit (`5e44191c9` + xhcid fork `3b0d02d8`) added the
|
||
`ZERO_64B_REGS` enforcement at `xhci/mod.rs:520-550` and
|
||
`NO_ASPM`/`NEED_IOMMU`/`NO_MSIX`/`NO_MSI` enforcement via the amdgpu C
|
||
FFI, but these are the only bits actually applied.
|
||
|
||
**Remediation:** Replace the call at `xhcid/src/main.rs:152` with
|
||
`lookup_xhci_controller_quirks_full(vendor, device)` (or a DMI-aware
|
||
variant when `read_dmi_info()` returns `Ok`); iterate `actions` and call
|
||
`action.execute(&writer, &info)`; and call `log_unenforced_xhci_quirks()`
|
||
to surface dormant flags.
|
||
|
||
**Status:** ✅ RESOLVED 2026-06-07 — `local/sources/base/drivers/usb/xhcid/src/main.rs:152`
|
||
now calls `lookup_xhci_controller_quirks_full(vendor, device, dmi_info.as_ref())`
|
||
instead of `lookup_xhci_controller_quirks`. The DMI information is read once
|
||
at driver startup via
|
||
`redox_driver_sys::quirks::dmi::read_dmi_info().ok()`. When `/scheme/acpi/dmi`
|
||
is absent (e.g., boot stage before acpid is up, or acpid did not produce
|
||
DMI for this firmware), the call falls through gracefully and only the
|
||
non-DMI rules fire. The DMI path now has a real producer (Blocker 2
|
||
commit `fa91cee4` in this turn), so on real hardware the DMI rules in
|
||
`[[dmi_xhci_system_quirk]]` TOML entries and the future compiled-in
|
||
DMI xHCI table will now reach the lookup function. The full variant
|
||
returns `PciQuirkLookup` with both flags and `actions: Vec<QuirkAction>`,
|
||
so QuirkAction execution becomes available for xHCI the moment a
|
||
`PciConfigWriter` is wired (Blocker 1). The R6 enforcement bits
|
||
(`ZERO_64B_REGS`, `NO_ASPM`, `NEED_IOMMU`, `NO_MSIX`, `NO_MSI`) continue
|
||
to be applied at the same sites in `xhci/mod.rs`. The pre-existing
|
||
`log_unenforced_xhci_quirks()` helper at `xhci/mod.rs:526` remains
|
||
in place for surfacing R8 dormant bits; calling it is queued as part
|
||
of Blocker 3 (usbhidd rewiring) since both share the same wakeup path.
|
||
Local commit `be95fea0` on the `redbear-working` branch of the base
|
||
fork; gitea push is blocked by the same gitea-side
|
||
"push-to-create-not-enabled" config issue affecting the kernel and
|
||
bootloader forks.
|
||
|
||
#### Blocker 5: DmiInfo and DmiMatchRule missing `bios_vendor` and `bios_date`
|
||
|
||
**File:** `local/recipes/drivers/redox-driver-sys/source/src/quirks/dmi.rs:97-105` (DmiInfo struct)
|
||
**File:** `local/recipes/drivers/redox-driver-sys/source/src/quirks/dmi.rs:7-15` (DmiMatchRule struct)
|
||
**File:** `local/recipes/drivers/redox-driver-sys/source/src/quirks/dmi.rs:144-164` (parse_dmi_data)
|
||
|
||
`DmiInfo` has 7 fields (`sys_vendor`, `board_vendor`, `board_name`,
|
||
`board_version`, `product_name`, `product_version`, `bios_version`).
|
||
`DmiMatchRule` has 7 matching fields. Both are missing `bios_vendor` and
|
||
`bios_date`, which Linux SMBIOS provides and many DMI-based quirk rules
|
||
rely on for matching (e.g., BIOS vendor `"LENOVO"`, BIOS date-based
|
||
firmware-version workarounds). `parse_dmi_data()` only handles 7 keys
|
||
and silently ignores unknown ones.
|
||
|
||
**Remediation:** Add `bios_vendor: Option<String>` and
|
||
`bios_date: Option<String>` to both structs; extend `parse_dmi_data()`;
|
||
extend `parse_dmi_match_rule()` in
|
||
`local/recipes/drivers/redox-driver-sys/source/src/quirks/toml_loader.rs:454-500`;
|
||
add tests; update the DMI producer in acpid (Blocker 2) to emit the new
|
||
keys.
|
||
|
||
**Status:** ✅ RESOLVED 2026-06-07 — Both fields added to `DmiInfo` and
|
||
`DmiMatchRule`; `is_empty()` and `matches()` extended; `parse_dmi_data()`
|
||
handles `bios_vendor` and `bios_date` keys; `parse_dmi_match_rule()` in
|
||
`toml_loader.rs` handles new TOML fields. 5 new dmi.rs unit tests +
|
||
1 new toml_loader.rs test added. 120/120 tests pass. Clippy +2 warnings
|
||
(same `map_or` pattern as existing 7 DMI fields, consistent with
|
||
existing code). Awaiting Blocker 2 (acpid DMI producer) for the runtime
|
||
data source.
|
||
|
||
### Gaps 6–20 (Medium and Low Priority)
|
||
|
||
| # | Gap | File:line | Impact |
|
||
|---|-----|-----------|--------|
|
||
| 6 | `QuirkAction` execution is dead code (no consumer) | `quirks/mod.rs:377` | Same as Blocker 1 — unblocks once PciConfigWriter is implemented |
|
||
| 7 | `QuirkAction::execute()` not called by any production driver | `quirks/mod.rs:377-448` | Same as Blocker 1 |
|
||
| 8 | `PciQuirkPhase::Resume` / `ResumeEarly` dormant | `quirks/mod.rs:464-471`, `:796-800` | PM infrastructure not yet present; `pm_available` always `false` |
|
||
| 9 | 7 DMA-alias `NamedCallback` are documented no-ops | `quirks/mod.rs:932-934` | Blocked on `iommu` daemon integration; acceptable phase-deferral |
|
||
| 10 | `evdevd` has no HID quirk consumption | `local/recipes/system/evdevd/source/src/main.rs` | HID flags (`ALWAYS_POLL`, `BADPAD`, etc.) never applied in input pipeline |
|
||
| 11 | `redox-drm` imports `PciQuirkFlags` but never calls `lookup_pci_quirks` | `redox-drm/src/main.rs:24` | amdgpu C gets flags via FFI, but Rust `redox-drm` scheme daemon does not |
|
||
| 12 | `redbear-iwlwifi` does not call `pci_has_quirk` | `local/recipes/drivers/redbear-iwlwifi/source/src/main.rs` | Intel Wi-Fi driver misses device-specific PCI workarounds |
|
||
| 13 | TOML hot-reload has no caching | `quirks/toml_loader.rs:502-523` | Every `load_pci_quirks()` re-reads all TOML files from disk (intentional for hot-reload, no invalidation) |
|
||
| 14 | TOML coverage gap: 64 PCI final-quirk entries vs Linux's ~233 | `quirks.d/07-pci-final-quirks.toml` (64) vs `linux-7.1/drivers/pci/quirks.c` (233) | ~170 entries unmined |
|
||
| 15 | amdgpu uses `redox_stubs.c` not linux-kpi real impl | `amdgpu/source/redox_stubs.c:326-340` | The amdgpu link includes `redox_stubs.o` defining `pci_get_quirk_flags` as a static stub; the linux-kpi real impl is shadowed. Real quirk data never reaches the C driver. |
|
||
| 16 | `DMI_XHCI_QUIRK_RULES` table is empty | `quirks/dmi.rs:373` | Linux itself has no DMI-based xHCI quirks; acceptable but should be documented |
|
||
| 17 | `DmiInfo::default()` silently returned on read failure | `quirks/dmi.rs:136-142` | No `log::warn!` when `/scheme/acpi/dmi` is absent; debugging is harder |
|
||
| 18 | PciConfigWriter assumes little-endian without runtime check | `quirks/mod.rs:234-241` | Redox runs only on x86_64 (LE), so not a current bug; should add `cfg!(target_endian = "little")` static assert |
|
||
| 19 | No integration tests for full lookup with real scheme data | tests/ | All 114 unit tests use `MockConfig` and artificial `PciDeviceInfo`; no test exercises `lookup_pci_quirks_full` against `/scheme/pci` |
|
||
| 20 | Initfs delivery path for TOML quirks not addressed | `redbear-quirks/recipe.toml` | `quirks.d/*.toml` only available after root mount; early-boot devices need compiled-in fallback for `NO_FLR`, `NEED_FIRMWARE`, etc. |
|
||
|
||
### Forward Plan (R11–R22) — what to implement per phase
|
||
|
||
This section specifies the exact work needed to make each phase fully
|
||
useful. Each entry lists: **infrastructure** (what must exist), **data
|
||
sources** (compiled-in vs TOML vs DMI vs SMBIOS), **consumer drivers**
|
||
(must call the lookup function), **test coverage** (what to verify), and
|
||
**runtime verification** (how to prove it works on real hardware).
|
||
|
||
#### Phase R11: ACPI DMI Quirk Expansion
|
||
|
||
**Goal:** Add the ~60 DMI-based ACPI rules that Linux ships
|
||
(`drivers/acpi/osi.c` ~20, `drivers/acpi/ec.c` ~8,
|
||
`drivers/acpi/x86/utils.c` ~8, sleep ~5, video ~5, PCI IRQ ~4,
|
||
battery ~4, blacklist ~3, button ~2).
|
||
|
||
**Infrastructure (blockers from this audit):**
|
||
- **DONE 2026-06-07** Blocker 2 (acpid DMI serving) — acpid now parses
|
||
SMBIOS from `/scheme/kernel.smbios/table` (kernel reads it from
|
||
bootloader-provided buffers) and serves
|
||
`/scheme/acpi/dmi` (key=value) + `/scheme/acpi/dmi/{field}` (per-field).
|
||
See commit `fa91cee4` in base fork, with kernel commit `a4ba465`
|
||
and bootloader commit `259a621` providing the upstream half of the
|
||
chain.
|
||
- **DONE 2026-06-07** Blocker 5 (`bios_vendor`, `bios_date` fields) —
|
||
`DmiInfo` and `DmiMatchRule` carry 9 fields each; acpid emits all 9.
|
||
See commit `9a28b68ef` (redox-driver-sys fork).
|
||
|
||
**Status:** R11 is now data-only. The acpid producer, the DMI struct,
|
||
and the parsed-SMBIOS path are all live. R11 work reduces to mining
|
||
the Linux ACPI rules and writing them into
|
||
`quirks.d/45-acpi-osi.toml` through `48-acpi-battery.toml`. The
|
||
`acpid` driver must own `_OSI` override dispatch; the new `ec`
|
||
subsystem in acpid needs the timing override consumer; the
|
||
battery/sleep/button rules need the appropriate consumer
|
||
daemons (`redbear-upower`, etc.) which are partially stubbed.
|
||
|
||
**Data sources:**
|
||
- `quirks.d/45-acpi-osi.toml` — `_OSI` override/blacklist entries
|
||
(`{ rule = "DEEP_SLEEP", action = { kind = "osi_override", text = "Windows 2009" } }`)
|
||
- `quirks.d/46-acpi-ec.toml` — embedded controller timing overrides
|
||
- `quirks.d/47-acpi-sleep.toml` — S-state transition quirks
|
||
- `quirks.d/48-acpi-battery.toml` — battery reporting quirks
|
||
- Compiled-in: nothing (all DMI-gated → runtime TOML only)
|
||
|
||
**Consumer drivers:**
|
||
- `acpid` (must own the `_OSI` override dispatch)
|
||
- `ec` (embedded controller, lives in acpid for now)
|
||
- `cpufreqd`, `thermald`, `redbear-upower` (DMI-matched policy)
|
||
|
||
**Test coverage:**
|
||
- Unit: `apply_dmi_pci_quirk_rules` extended to ACPI subsystem
|
||
- Unit: DMI match across `bios_vendor`/`bios_date` (after Blocker 5)
|
||
- Integration: load synthetic DMI → load TOML → verify ACPI flag set
|
||
|
||
**Runtime verification:**
|
||
- `redbear-info -d` shows populated `/scheme/acpi/dmi` keys
|
||
- `redbear-phase-acpi-check --strict` passes against real hardware
|
||
- `redbear-acpi-quirk-check` tool: enumerate ACPI rule matches per system
|
||
|
||
#### Phase R12: DRM Panel Orientation Quirks
|
||
|
||
**Goal:** Add the 22 DMI entries from Linux
|
||
`drivers/gpu/drm/drm_panel_orientation_quirks.c` (GPD, Chuwi, etc.
|
||
portrait screens).
|
||
|
||
**Infrastructure (blockers):**
|
||
- Depends on compositor rotation support (deferred).
|
||
- R11 prerequisites (DMI serving + `bios_vendor`/`bios_date`) — **DONE
|
||
2026-06-07** (Blocker 2 + Blocker 5 RESOLVED).
|
||
|
||
**Data sources:**
|
||
- `quirks.d/50-drm-panel.toml` — `[[drm_panel_quirk]]` entries
|
||
(`{ vendor = "GPD", product = "P2 Max", orientation = "PortraitRight" }`)
|
||
|
||
**Consumer drivers:**
|
||
- `redox-drm` (the DRM scheme daemon) — must call
|
||
`lookup_drm_panel_orientation(vendor, product, dmi_info)` and apply
|
||
the returned orientation transform before exposing the connector.
|
||
|
||
**Test coverage:**
|
||
- Unit: orientation lookup with various DMI info combinations
|
||
- Integration: synthetic connector + DMI → verify transform applied
|
||
|
||
**Runtime verification:**
|
||
- `redbear-info -d` shows panel orientation
|
||
- QEMU with synthetic EDID + DMI: verify compositor applies rotation
|
||
- Bare-metal: GPD P2 Max or similar clamshell device
|
||
|
||
**Status:** Deferred until compositor rotation exists (Phase 4 KDE session).
|
||
|
||
#### Phase R13: Laptop/Embedded DMI Quirks
|
||
|
||
**Goal:** Add the ~1153 DMI entries from Linux `drivers/platform/x86/`
|
||
focused on target hardware: Framework laptops, GPD/AYANEO handhelds,
|
||
Dell, Lenovo ThinkPad, Asus.
|
||
|
||
**Infrastructure:**
|
||
- R11 prerequisite (DMI serving) — **DONE 2026-06-07** (Blocker 2 RESOLVED).
|
||
- May require Blocker 11 fix (redox-drm should call
|
||
`lookup_pci_quirks_full` to get platform-level flags).
|
||
|
||
**Data sources:**
|
||
- `quirks.d/80-platform-x86.toml` — `[[platform_dmi_quirk]]` entries
|
||
with subsystem dispatch (`{ subsystem = "touchscreen", ... }`,
|
||
`{ subsystem = "als", ... }`, etc.)
|
||
|
||
**Consumer drivers:**
|
||
- `inputd` (touchscreen / accelerometer / ALS)
|
||
- `acpid` (button, lid)
|
||
- `pcid` (MSI-X, ASPM)
|
||
- `redbear-upower` (battery quirks)
|
||
- `thermald` (thermal zone quirks)
|
||
|
||
**Test coverage:**
|
||
- Unit: `PlatformDmiQuirk` lookup function
|
||
- Unit: subsystem dispatch
|
||
- Integration: synthetic DMI → verify correct subsystem flag set
|
||
|
||
**Runtime verification:**
|
||
- `redbear-info -d` shows platform rules triggered
|
||
- Framework laptop 13/16: verify hotkeys, ALS, battery all work
|
||
- GPD Win / AYANEO: verify gamepad button mapping
|
||
- Dell laptop: verify Dell-specific hotkeys (`Fn` row, RF kill)
|
||
|
||
#### Phase R14: CPU Bug Mitigation Infrastructure
|
||
|
||
**Goal:** Port the ~20 CPU bug mitigations from
|
||
`arch/x86/kernel/cpu/bugs.c` (`meltdown`, `spectre_v1`, `spectre_v2`,
|
||
`ssb`, `l1tf`, `mds`, `taa`, `itlb_multihit`, `srbds`, `tsx_async_abort`,
|
||
etc.).
|
||
|
||
**Infrastructure (blockers):**
|
||
- **Kernel infrastructure needed** — microkernel context switching
|
||
paths must consult the CPU bug flags.
|
||
- New bitflags type `CpuBugFlags` in kernel + `cpu_bug_table.rs`.
|
||
- `QuirkAction` analogues for kernel-side (`disable_smt`,
|
||
`set_ibrs_enabled`, etc.).
|
||
|
||
**Data sources:**
|
||
- Compiled-in `cpu_bug_table.rs` (~30 entries)
|
||
- Per-CPU flags exposed via kernel cmdline and `cpuid`
|
||
|
||
**Consumer drivers:**
|
||
- **Kernel** — context switch, page table management, syscall entry
|
||
- `redbear-info` — observability (`cat /cpu/bugs`)
|
||
|
||
**Test coverage:**
|
||
- Unit: lookup by CPUID family/model/stepping
|
||
- Integration: synthetic CPUID → verify mitigation flag set
|
||
- Runtime: `redbear-info -c` shows CPU bugs
|
||
|
||
**Runtime verification:**
|
||
- Real AMD Ryzen + Intel i7: verify `mds`, `spectre_v2` correctly
|
||
identified
|
||
- Verify kernel does not enable unnecessary mitigations
|
||
- SPEC CPU2017 benchmark with/without mitigations
|
||
|
||
#### Phase R15: Timekeeping Quirk Infrastructure
|
||
|
||
**Goal:** Port the ~10 timekeeping quirks from
|
||
`arch/x86/kernel/tsc.c`, `arch/x86/kernel/hpet.c`,
|
||
`drivers/clocksource/`.
|
||
|
||
**Infrastructure:**
|
||
- Kernel clocksource subsystem.
|
||
- `ClocksourceQuirkFlags` bitflags.
|
||
|
||
**Data sources:**
|
||
- Compiled-in (CPUID-driven) only.
|
||
|
||
**Consumer drivers:**
|
||
- Kernel (`/scheme/time/`)
|
||
|
||
**Test coverage:**
|
||
- Unit: synthetic CPUID → verify clocksource selection
|
||
- Runtime: TSC vs HPET vs PMTMR selection on real hardware
|
||
|
||
**Runtime verification:**
|
||
- `redbear-info -t` shows clocksource + TSC sync status
|
||
- Long-duration timing tests (1 hour drift measurement)
|
||
|
||
#### Phase R16: Memory Configuration Quirks
|
||
|
||
**Goal:** Port MTRR setup, PAT configuration, NUMA quirks from
|
||
`arch/x86/kernel/cpu/mtrr/`, `arch/x86/mm/pat/`, `arch/x86/mm/numa_64.c`.
|
||
|
||
**Infrastructure:**
|
||
- Kernel MTRR/PAT management
|
||
- New `MemoryQuirkFlags`
|
||
|
||
**Data sources:**
|
||
- Compiled-in (Northbridge/IMC vendor/device driven)
|
||
|
||
**Consumer drivers:**
|
||
- Kernel (page table setup)
|
||
|
||
**Test coverage:**
|
||
- Unit: synthetic MTRR/PAT state → verify UC/WC/WT/WB mappings
|
||
- Runtime: verify write-combining works for framebuffer
|
||
|
||
**Runtime verification:**
|
||
- `redbear-info -m` shows MTRR state
|
||
- Framebuffer perf benchmark with/without WC
|
||
|
||
#### Phase R17: Early-Boot Chipset Quirks
|
||
|
||
**Goal:** Port the ~30 chipset init quirks from
|
||
`arch/x86/pci/early.c` and `drivers/pci/quirks.c` `DECLARE_PCI_FIXUP_HEADER`
|
||
(Header phase, before kernel memory management exists).
|
||
|
||
**Infrastructure:**
|
||
- Compiled-in table in kernel.
|
||
- Must run before any Rust code (assembly + C trampoline + Rust).
|
||
- `PciQuirkPhase::Header` already exists (R1).
|
||
|
||
**Data sources:**
|
||
- Compiled-in only (no filesystem, no TOML).
|
||
|
||
**Consumer drivers:**
|
||
- **Kernel** (early init, before any scheme)
|
||
|
||
**Test coverage:**
|
||
- Unit: lookup by vendor/device/class → verify Header-phase action
|
||
- QEMU: verify Header-phase runs (logs, PCI capability preservation)
|
||
|
||
**Runtime verification:**
|
||
- `dmesg | grep quirk` shows early-boot fixes applied
|
||
- QEMU: compare PCI config space before/after Header-phase
|
||
|
||
#### Phase R18: Storage Controller Quirks
|
||
|
||
**Goal:** Port NVMe quirks (`drivers/nvme/host/*`), SATA quirks
|
||
(`drivers/ata/ahci.c`, `drivers/ata/sata_*`), SCSI quirks
|
||
(`drivers/scsi/*`).
|
||
|
||
**Infrastructure:**
|
||
- New `StorageQuirkFlags` bitflags.
|
||
- `lookup_storage_quirks(vendor, device)` public API.
|
||
|
||
**Data sources:**
|
||
- `quirks.d/35-storage-extended.toml` (NVMHCI, SATA AHCI class)
|
||
- Compiled-in for boot-critical (NVMe timeout defaults)
|
||
|
||
**Consumer drivers:**
|
||
- `nvmed` (NVMe scheme daemon)
|
||
- `ahcid` (SATA AHCI)
|
||
- `usbscsid` (already has inline unusual_devs; should also call
|
||
`lookup_storage_quirks` for SATA-bridge-class devices)
|
||
|
||
**Test coverage:**
|
||
- Unit: lookup by class + vendor/device
|
||
- Integration: synthetic NVMe device → verify timeout applied
|
||
|
||
**Runtime verification:**
|
||
- `redbear-info -s` shows storage controllers and applied quirks
|
||
- QEMU + virtio-blk: verify timeout works
|
||
- Bare metal: NVMe SSD + Samsung 990 PRO → verify Samsung quirk
|
||
|
||
#### Phase R19: Network Controller PCI Quirks
|
||
|
||
**Goal:** Port ~30 PCI network quirks from `drivers/net/ethernet/*`
|
||
(Intel e1000e ASPM, Realtek RTL8169 MSI-X, Aquantia AQC latency).
|
||
|
||
**Infrastructure:**
|
||
- `lookup_pci_quirks_full` (already exists, dormant) — this phase
|
||
activates it for network drivers.
|
||
|
||
**Data sources:**
|
||
- `quirks.d/55-network.toml`
|
||
|
||
**Consumer drivers:**
|
||
- `e1000d`, `r8169d`, `virtio-netd` — must call
|
||
`lookup_pci_quirks_full` and apply actions (`WriteConfig`,
|
||
`SetBit`/`ClearBit`)
|
||
|
||
**Test coverage:**
|
||
- Unit: lookup returns correct action
|
||
- Integration: synthetic network device → verify config-space write
|
||
|
||
**Runtime verification:**
|
||
- `ethtool -k` equivalent in Red Bear shows quirk-derived settings
|
||
- iperf3 baseline + with quirk
|
||
|
||
#### Phase R20: USB Audio Codec Quirks
|
||
|
||
**Goal:** Port ~20 USB audio quirks from `sound/usb/quirks.c` (async
|
||
mode, implicit feedback, vendor-specific format quirks).
|
||
|
||
**Infrastructure:**
|
||
- `UsbAudioQuirkFlags` bitflags
|
||
- Requires USB Audio class driver
|
||
|
||
**Data sources:**
|
||
- `quirks.d/60-usb-audio.toml`
|
||
|
||
**Consumer drivers:**
|
||
- `usb-audio` driver (or `sndusbd` if Red Bear's naming)
|
||
|
||
**Test coverage:**
|
||
- Unit: lookup by USB audio device ID
|
||
- Integration: synthetic USB audio → verify implicit feedback applied
|
||
|
||
**Runtime verification:**
|
||
- USB headset play/record test
|
||
- Compare with Linux driver behavior
|
||
|
||
#### Phase R21: AMD IOMMU Quirks
|
||
|
||
**Goal:** Port ~10 AMD IOMMU quirks from `drivers/iommu/amd/`
|
||
(`amd_iommu_quirks[]`).
|
||
|
||
**Infrastructure:**
|
||
- `iommu` daemon (already builds — see CONSOLE-TO-KDE plan Phase 5)
|
||
- 7 DMA-alias `NamedCallback` (Gap 9) become real
|
||
|
||
**Data sources:**
|
||
- `quirks.d/65-iommu.toml`
|
||
|
||
**Consumer drivers:**
|
||
- `iommu` daemon
|
||
- DMA-aware drivers (amdgpu, nvme, xhci, network)
|
||
|
||
**Test coverage:**
|
||
- Unit: lookup by IOMMU vendor/device → verify alias decision
|
||
- Integration: synthetic DMA mapping → verify alias applied
|
||
|
||
**Runtime verification:**
|
||
- QEMU with AMD-Vi unit: verify iommu daemon discovers + applies quirks
|
||
- Bare metal: AMD Threadripper, verify DMA isolation works
|
||
|
||
#### Phase R22: Boot Parameter Quirk Infrastructure
|
||
|
||
**Goal:** Honor Linux-compatible kernel boot parameters
|
||
(`nosoftlockup`, `iommu=soft`, `intremap=off`, `nox2apic`, `noaspm`,
|
||
`mem=`).
|
||
|
||
**Infrastructure:**
|
||
- Kernel cmdline parser (in Redox boot, not Linux)
|
||
- Maps cmdline tokens to quirk flag sets
|
||
|
||
**Data sources:**
|
||
- Compiled-in mapping (cmdline → flag bit)
|
||
|
||
**Consumer drivers:**
|
||
- Kernel early init
|
||
- `pcid` (for `nox2apic`, `noaspm`)
|
||
- `iommu` (for `iommu=soft`)
|
||
|
||
**Test coverage:**
|
||
- Unit: cmdline parser
|
||
- Integration: boot with `noaspm` → verify ASPM disabled in pcid
|
||
|
||
**Runtime verification:**
|
||
- `dmesg | grep "cmdline quirk"` shows applied overrides
|
||
- `redbear-info -b` shows effective boot parameters
|
||
|
||
### Cross-Cutting Consumer Wiring Checklist
|
||
|
||
Before any R11+ phase produces user-facing benefit, the following consumer
|
||
wiring must be completed (from Gaps 1-7, 10-12, 15):
|
||
|
||
| Priority | Driver | Lookup to add | Action | Status (2026-06-07) |
|
||
|---|---|---|---|---|
|
||
| P0 | `pcid` | `lookup_pci_quirks_full` + iterate `QuirkAction` via real `PciConfigWriter` impl | Unblocks R1, R2, R3, R4, R5, R17, R18, R19, R21, R22 actions | ✅ **RESOLVED** (`676af02e` on `redbear-working`: `pcid/src/quirks.rs` 460+ lines + `handle_parsed_header` wiring; 12/12 unit tests) |
|
||
| P0 | `acpid` | (new) serve `/scheme/acpi/dmi` from SMBIOS tables | Unblocks all DMI-based rules (R4, R7, R11, R12, R13) | ✅ **RESOLVED** (this turn: bootloader `259a621` + kernel `a4ba465` + acpid `fa91cee4`) |
|
||
| P0 | DMI struct | add `bios_vendor`, `bios_date` to `DmiInfo` and `DmiMatchRule` | Unblocks ~30% of R11 rules | ✅ **RESOLVED** (commit `9a28b68ef`) |
|
||
| P1 | `usbhidd` | `lookup_usb_quirks` + `lookup_hid_quirks` | Unblocks R6, R9, R10, R20 | ⏳ **Blocker 3 PENDING** (2-3 days, next after this turn) |
|
||
| P1 | `xhcid` | `lookup_xhci_controller_quirks_full` + iterate `QuirkAction` | Unblocks R6 (full), R7, R8, R9 | 🚧 **Blocker 4 partial** (DMI lookup done at commit `be95fea0`; `QuirkAction` loop now mechanically possible — 1-2 day follow-up) |
|
||
| P1 | `evdevd` | `lookup_hid_quirks` for HID device registration | Unblocks R10 | ✅ **RESOLVED** (`a24cfe64c` on `0.2.3`: `local/recipes/system/evdevd/source/src/quirks.rs`; 4 unit tests; cargo check clean) |
|
||
| P2 | `redox-drm` | `lookup_pci_quirks` for GPU device | Unblocks R5 (GPU subset) | ✅ **ALREADY RESOLVED** — `local/recipes/gpu/redox-drm/source/src/drivers/mod.rs:161` calls `full.quirks()` which is `PciDeviceInfo::quirks() -> PciQuirkFlags` (pci.rs:247). The DISABLE_ACCEL enforcement (line 169), NEED_FIRMWARE firmware loading (line 392, main.rs:471), and FORCE_LEGACY_IRQ / NO_MSIX / NO_MSI interrupt selection (interrupt.rs:32-53) all consume the flag word. The audit's "Gap 11 PENDING" was based on a misread. |
|
||
| P2 | `redbear-iwlwifi` | `pci_has_quirk` from linux-kpi C FFI | Unblocks R19 (Wi-Fi subset) | ✅ **RESOLVED** (`1561767ac` on `0.2.3`: `local/recipes/drivers/redbear-iwlwifi/source/src/quirks.rs`; 3 unit tests). Bypasses the linux-kpi C FFI because `PciDev::bus`/`dev`/`func` are private to the linux-kpi crate; calls `redox_driver_sys::quirks::lookup_pci_quirks` directly with a `PciDeviceInfo` (the same lookup linux-kpi wraps). |
|
||
| P2 | amdgpu | remove `redox_stubs.c` for `pci_*_quirk_flags`; use linux-kpi real impl | Ensures amdgpu C sees real quirk data | ✅ **RESOLVED** (`98982cc2f` on `0.2.3`: `local/recipes/gpu/amdgpu/source/redox_quirk_bridge.c` extracted; `redox_stubs.c` no longer has any quirk symbols; recipe.toml Stage 1 compiles both files) |
|
||
| P3 | `iommu` | consume DMA-alias `NamedCallback` (R4) | Unblocks R21 | ⏳ (deferred; iommu daemon not yet a consumer) |
|
||
|
||
**4 of 5 P0 critical blockers are now RESOLVED.** Blocker 1 (pcid
|
||
`PciConfigWriter`) is in the bag. Blocker 4 (xhcid `QuirkAction`
|
||
iteration) is now mechanically unblocked and reduces to a 1-2 day
|
||
follow-up wiring. The remaining 1 (Blocker 3 usbhidd wiring) is the
|
||
next priority because it unlocks QuirkAction execution at every
|
||
HID/USB consumer site and unblocks the remaining R11-R22 phases.
|
||
|
||
**All 4 medium-low gaps (10, 11, 12, 15) are now RESOLVED**:
|
||
- Gap 10 (evdevd) — `a24cfe64c`
|
||
- Gap 11 (redox-drm) — already resolved; audit misread
|
||
- Gap 12 (redbear-iwlwifi) — `1561767ac`
|
||
- Gap 15 (amdgpu) — `98982cc2f`
|
||
|
||
The Phase R11 prerequisites (Blokers 2, 5 + the four gap wirings) are
|
||
all in. R11 is the next phase to land.
|
||
|
||
### Test Coverage Strategy
|
||
|
||
| Phase | New unit tests | New integration tests | Runtime harness |
|
||
|---|---|---|---|
|
||
| R11 | 5 (DMI match variations) | 1 (synthetic ACPI match) | `redbear-acpi-quirk-check` |
|
||
| R12 | 4 (orientation transforms) | 0 (deferred) | `redbear-drm-rotation-check` |
|
||
| R13 | 10 (subsystem dispatch) | 2 (touchscreen, hotkey) | `redbear-platform-dmi-check` |
|
||
| R14 | 10 (CPU bug identification) | 1 (CPUID injection) | `redbear-cpu-bugs-check` |
|
||
| R15 | 3 (clocksource selection) | 1 (long-duration timing) | `redbear-timecheck` |
|
||
| R16 | 5 (MTRR/PAT setup) | 1 (WC region test) | `redbear-memcheck` |
|
||
| R17 | 8 (header-phase actions) | 0 (kernel internal) | QEMU PCI diff before/after |
|
||
| R18 | 6 (NVMe/SATA class) | 1 (synthetic storage) | `redbear-storage-quirk-check` |
|
||
| R19 | 8 (network PCI) | 1 (synthetic NIC) | `redbear-net-quirk-check` |
|
||
| R20 | 4 (USB audio) | 0 (driver missing) | Defer |
|
||
| R21 | 4 (IOMMU alias) | 1 (DMA mapping) | `redbear-iommu-quirk-check` |
|
||
| R22 | 4 (cmdline parsing) | 0 (kernel internal) | `redbear-bootparam-check` |
|
||
|
||
### Adjusted Phase Estimates
|
||
|
||
| Phase | Original estimate | Adjusted estimate (post-blocker-resolution 2026-06-07) | Reason |
|
||
|---|---|---|---|
|
||
| R11 | 2-3 days | **2-3 days** | Blocker 2 (acpid DMI) + Blocker 5 (DMI struct) RESOLVED; R11 is now data-only |
|
||
| R12 | 1 day | 1 day | Unchanged (still deferred until rotation) |
|
||
| R13 | 3-5 days | **5-7 days** | Largest unmined set; subsystem dispatch is new |
|
||
| R14 | 5-8 days | **8-12 days** | Kernel-side integration adds scope |
|
||
| R15 | 2-3 days | 3-4 days | Unchanged |
|
||
| R16 | 4-6 days | 5-7 days | Unchanged |
|
||
| R17 | 3-4 days | **2-3 days** | Blocker 1 RESOLVED; only data mining + lookup wiring remain |
|
||
| R18 | 2-3 days | **3-5 days** | Still requires P1 usbhidd consumer wiring (Blocker 3) |
|
||
| R19 | 3-4 days | **2-3 days** | Blocker 1 RESOLVED; only data mining + lookup wiring remain |
|
||
| R20 | 2-3 days | 2-3 days | Unchanged (USB audio driver not started) |
|
||
| R21 | 1 day | **3-5 days** | Requires iommu daemon + DMA callback activation |
|
||
| R22 | 2-3 days | 3-4 days | Unchanged |
|
||
| **Total** | **44-68 days** | **42-62 days** | -22 days vs the +20-day blocker-add (4 of 5 blockers RESOLVED); remaining +2 days net for Blocker 3 (the only blocker left) and the xhcid `QuirkAction` follow-up |
|
||
|
||
### Recommended Implementation Order
|
||
|
||
The 5 critical blockers form a dependency chain. The recommended order
|
||
is:
|
||
|
||
1. **Blocker 5** (DMI struct extension) — smallest, 1-2 days, no
|
||
consumer wiring needed. ✅ **RESOLVED** 2026-06-07 (commit `9a28b68ef`)
|
||
2. **Blocker 2** (acpid DMI producer) — medium, 3-5 days, unblocks all
|
||
DMI-based rules. ✅ **RESOLVED** 2026-06-07 (bootloader `259a621` +
|
||
kernel `a4ba465` + acpid `fa91cee4`)
|
||
3. **Blocker 1** (pcid `PciConfigWriter` impl + `QuirkAction` loop) —
|
||
large, 5-7 days, unblocks R1-R5 actions. ✅ **RESOLVED** 2026-06-07
|
||
(commit `676af02e` on `redbear-working`: `pcid/src/quirks.rs` +
|
||
`handle_parsed_header` wiring; 12/12 unit tests)
|
||
4. **Blocker 3** (usbhidd HID/USB wiring) — medium, 2-3 days. ⏳ **PENDING**
|
||
5. **Blocker 4** (xhcid full lookup wiring) — small, 1-2 days, depends on
|
||
Blocker 1. 🚧 **PARTIAL** 2026-06-07 (commit `be95fea0` covers DMI
|
||
lookup + full variant call; `QuirkAction` iteration is now
|
||
mechanically unblocked and reduces to a 1-2 day follow-up)
|
||
6. **Gap 15** (amdgpu stub removal) — small, 1 day. ✅ **RESOLVED** 2026-06-07
|
||
(`98982cc2f`: `redox_quirk_bridge.c` extracted; `redox_stubs.c` no
|
||
longer has any quirk symbols)
|
||
7. **Gap 10-12** (evdevd, redox-drm, iwlwifi wiring) — small, 1 day each.
|
||
✅ **RESOLVED** 2026-06-07 (Gap 10 `a24cfe64c`, Gap 11 was already
|
||
resolved, Gap 12 `1561767ac`)
|
||
|
||
After the 5 blockers are resolved, Phases R11-R22 can proceed
|
||
incrementally. Phase R11 should be next because it has the highest
|
||
hardware-enablement impact (unblocks battery, thermal, sleep, lid,
|
||
button, ALS, _OSI on real laptops). With Blocker 2 and Blocker 5
|
||
resolved, R11 is now data-only work (mining ~60 ACPI DMI rules into
|
||
`quirks.d/45-acpi-osi.toml` through `48-acpi-battery.toml`), so R11
|
||
becomes the first phase to ship user-visible benefit on real hardware.
|
||
|
||
## R7 Comprehensive Audit (2026-06-07) — Stubs, Install Gap, and Full Utilization Plan
|
||
|
||
A second-pass audit of the R0–R22 subsystem was performed to verify that
|
||
the infrastructure is not just present but **correctly consumed, utilized,
|
||
and fully automatically made to work** at runtime. Three parallel explore
|
||
agents surveyed the redox-driver-sys core, every consumer tree, and the
|
||
TOML data files; their findings are synthesized below along with a phase
|
||
utilization matrix and a concrete plan to close every gap.
|
||
|
||
### Audit Findings
|
||
|
||
#### Finding 1 (RESOLVED) — `cb_intel_ntb_bar_fix` was a no-op stub
|
||
|
||
**File:** `local/recipes/drivers/redox-driver-sys/source/src/quirks/mod.rs:1395-1403`
|
||
(pre-audit)
|
||
|
||
**Severity:** Critical — ZERO TOLERANCE FOR STUBS violation
|
||
|
||
The previous implementation:
|
||
```rust
|
||
let cmd = w.read_config_word(0x04);
|
||
w.write_config_word(0x04, cmd & !0x0002); // clear PCI_COMMAND_MEMORY
|
||
w.write_config_word(0x04, cmd); // restore immediately
|
||
true
|
||
```
|
||
|
||
The device only ever saw the cleared `MEM` bit for the duration of two
|
||
MMIO cycles (one write to clear, one write to restore). That is not
|
||
enough time for any silicon to re-evaluate its BAR decode, so the
|
||
"side effect" the comment claimed was never observable to any
|
||
downstream consumer. This was a stub masquerading as a real fix.
|
||
|
||
**Linux source of truth** (`linux-7.1/drivers/pci/quirks.c:3526-3542`,
|
||
`quirk_intel_ntb`): the silicon reports its true BAR 2 and BAR 4
|
||
sizes as log2-encoded bytes at config offsets 0xD0 and 0xD1
|
||
respectively. Linux reads those bytes and calls
|
||
`resource_set_size(&dev->resource[2], 1 << val)` (and the same for
|
||
`dev->resource[4]`).
|
||
|
||
**Fix:** Replace the no-op with the real Linux reads. The action path
|
||
cannot mutate kernel resource structs (those live in the kernel's PCI
|
||
core, not in userspace), so the config-space reads are the side effect
|
||
we can express; the kernel PCI core handles `resource_set_size`
|
||
separately. Three new unit tests verify the new behavior:
|
||
|
||
- `phase_r7_audit_intel_ntb_bar_fix_reads_size_registers` — vendor 0x8086, device 0x0e08
|
||
- `phase_r7_audit_intel_ntb_bar_fix_handles_second_linux_target` — vendor 0x8086, device 0x0e0d
|
||
- `phase_r7_audit_intel_ntb_bar_fix_handles_zero_registers` — zero-valued size registers
|
||
|
||
`cargo test --package redox-driver-sys`: 131/131 pass.
|
||
|
||
#### Finding 2 (RESOLVED) — `redbear-quirks` install script copied only 8 of 30 TOML files
|
||
|
||
**File:** `local/recipes/system/redbear-quirks/recipe.toml` (pre-audit)
|
||
|
||
**Severity:** Critical — every R11–R21 data table was inert at runtime
|
||
|
||
The pre-audit install script enumerated 8 explicit `cp` commands:
|
||
```
|
||
cp .../00-core.toml ...
|
||
cp .../10-gpu.toml ...
|
||
cp .../20-usb.toml ...
|
||
cp .../30-net.toml ...
|
||
cp .../40-storage.toml ...
|
||
cp .../50-system.toml ...
|
||
cp .../60-i2c-hid.toml ...
|
||
cp .../70-ucsi.toml ...
|
||
```
|
||
|
||
But the source tree at `local/recipes/system/redbear-quirks/source/quirks.d/`
|
||
contains **30 TOML files**. The 22 files that never reached
|
||
`/etc/quirks.d/` on the running image were:
|
||
|
||
| Missing file | Phase | Impact |
|
||
|---|---|---|
|
||
| `05-pcie-quirks.toml` | R3 base | PCIe base quirks never applied |
|
||
| `06-pci-header-quirks.toml` | R3 header | All DECLARE_PCI_FIXUP_HEADER fixes inert |
|
||
| `07-pci-final-quirks.toml` | R5 final | All DECLARE_PCI_FIXUP_FINAL fixes inert |
|
||
| `15-audio.toml` | R-base | HDA codec quirks inert |
|
||
| `25-xhci.toml` | R6 | xHCI runtime quirks inert |
|
||
| `30-storage.toml` (35kB) | R18 | 25-entry ATA/AHCI/SATA/NVMe table inert |
|
||
| `35-clocksource.toml` | R15 | PIIX4/ICH4/ServerWorks PMTMR blacklist inert |
|
||
| `35-storage-extended.toml` | R18 extended | Storage controller quirks inert |
|
||
| `40-hid.toml` (14kB) | R10 | 191 HID entries inert |
|
||
| `45-acpi-osi.toml` | R11 | ACPI _OSI overrides inert |
|
||
| `46-acpi-sleep.toml` | R11 | Sleep-state quirks inert |
|
||
| `47-acpi-button.toml` | R11 | Lid/power-button quirks inert |
|
||
| `48-acpi-battery.toml` | R11 | Battery quirks inert |
|
||
| `50-drm-panel.toml` | R12 | 36 panel-orientation rules inert |
|
||
| `55-chipset-early.toml` | R17 | 11 early-boot chipset entries inert |
|
||
| `55-network.toml` | R19 | 23 network entries inert |
|
||
| `60-usb-audio.toml` | R20 | 30 USB audio entries inert |
|
||
| `65-iommu-amd.toml` | R21 | 4 AMD IOMMU DMI entries inert |
|
||
| `80-platform-x86.toml` | R13 | 31 platform subsystem dispatch rules inert |
|
||
| `90-cpu-bugs.toml` | R14 | 14 CPU bug mitigation rules inert |
|
||
| `95-mtrr-deferred.toml` | R16 | Documented as deferred; still must ship |
|
||
| `99-bootparams-deferred.toml` | R22 | Documented as deferred; still must ship |
|
||
|
||
**Fix:** Replace the explicit 8-file list with a glob:
|
||
```bash
|
||
mkdir -p "${COOKBOOK_STAGE}/etc/quirks.d"
|
||
cp "${COOKBOOK_SOURCE}/quirks.d/"*.toml "${COOKBOOK_STAGE}/etc/quirks.d/"
|
||
```
|
||
|
||
The glob is more robust than any explicit list: future additions to
|
||
`quirks.d/` are picked up automatically, and the recipe can never
|
||
silently drift out of sync with the source.
|
||
|
||
#### Finding 3 (no-op calls audited, all justified)
|
||
|
||
The audit also surveyed every other `cb_*` callback in `mod.rs` for
|
||
the "wasteful-but-not-stub" anti-pattern. The findings:
|
||
|
||
| Callback | Verdict | Reason |
|
||
|---|---|---|
|
||
| `cb_intel_no_aspm_l0s` | Real | Walks cap list and clears `PCI_EXP_LNKCTL_ASPM_L0S` bit |
|
||
| `cb_amd_ide_class_fix` | Real | Conditional write of class code bytes 0x09-0x0B |
|
||
| `cb_ht_enable_msi_mapping` | Real | Walks HT MSI cap and sets enable bit |
|
||
| `cb_p64h2_1k_io` | Real | Clears `PCI_COMMAND_BUS_MASTER` to prevent MMIO overflow |
|
||
| `cb_intel_ntb_bar_fix` | **Was stub** | See Finding 1 — fixed |
|
||
| `cb_amd_fe_gate_ordering` | Real | Two real config-space writes to AMD-762 registers |
|
||
| `cb_amd_8131_mmrbc` | Intentionally read-only-touch | The "benign register touch" is for test observability; the real signal is in the `BUS_NO_MMRBC` flag. The callback exists to be a routable TOML target. **Audit accepts** — flag carries the real signal. |
|
||
| DMA-alias callbacks (Ricoh, Glenfly, Asmedia, Tundra, ITE, Intel bridge, Adaptec2) | Intentionally no-op | Deferred to Phase R4b pending IOMMU daemon integration; the action is still routable so TOML files can declare the dependency. **Audit accepts** — design is documented. |
|
||
|
||
### Consumer Wiring Matrix (Full Utilization Plan)
|
||
|
||
The R0–R22 audit identified every lookup function and traced which
|
||
production code actually consumes it. The matrix below shows current
|
||
state and the concrete steps needed for full utilization.
|
||
|
||
| Phase | Lookup function | Consumer (production) | State | Utilization work needed |
|
||
|---|---|---|---|---|
|
||
| R0–R5 | `lookup_pci_quirks_full` (via `apply_pci_quirks`) | `pcid` `handle_parsed_header` | ✅ Wired + used | None — every compiled-in PCI quirk fires at pcid enumeration |
|
||
| R0–R5 | `lookup_pci_quirks_full` actions | `pcid` `apply_pci_quirks` loop | ✅ Wired + used | None — 8 imperative callbacks dispatch |
|
||
| R6 | `lookup_xhci_controller_quirks_full` (DMI) | `xhcid` startup | ✅ Wired + used | None — DMI matches feed flag set |
|
||
| R6 | xHCI `QuirkAction` iteration | `xhcid` | ⏳ Pending | 1-2 day follow-up: `lookup_xhci_controller_quirks_full` → iterate `actions` → call `action.execute(&writer, ...)`; reduced to mechanical work now that Blocker 1's `PciConfigWriter` is in place |
|
||
| R7 | xHCI `apply_dmi_xhci_quirk_rules` | Internal (TOML loader) | ✅ Internal | None — DMI rules feed the flag set |
|
||
| R10 | `lookup_hid_quirks` (in `usbhidd::add_device`) | `usbhidd` | ✅ Wired (observability) | **Should become actionable**: at minimum, log an `info!` line per matching HID quirk at device-add time. Optional next step: `usbhidd` honors `NO_INIT_REPORTS` and `ALWAYS_POLL` to skip the first get/set on matching devices |
|
||
| R10 | `lookup_hid_quirks` (in `evdevd::add_device`) | `evdevd` | ✅ Wired (observability) | **Vendor IDs need to flow through**: `evdevd` currently passes `vendor=0` because the upstream `usbhidd` doesn't forward the USB vendor/product to `evdevd`. `usbhidd` should include vendor/product in the IPC payload (or expose them via `/scheme/input/...`); `evdevd` reads them. Without this fix, `log_hid_quirks` is dead code in `evdevd` |
|
||
| R10 | `lookup_usb_quirks` (in `usbhidd` `add_device`) | `usbhidd` | ✅ Wired (observability) | **Should become actionable**: `usbhidd` should honor `USB_QUIRK_RESET_RESUME` and `USB_QUIRK_NO_LPM` (both in our `UsbQuirkFlags`) by skipping the corresponding USB-core operations at device-add time |
|
||
| R11 | `apply_dmi_acpi_quirk_rules` (via `lookup_acpi_dmi_quirks`) | `acpid` (DMI consumer) | ✅ Producer | **Consumer needed**: acpid currently only writes `/scheme/acpi/dmi`; it does not yet call `apply_dmi_acpi_quirk_rules` and apply the returned `AcpiQuirkFlags` to AML evaluation (e.g. skip `_OSI("Windows 2009")` when the rule says so, force a specific `_Sx` for sleep states, etc.). Wiring is 1-2 days |
|
||
| R12 | `load_drm_panel_orientation` (in `redox-drm`) | `redox-drm` | ⏳ Pending | **Consumer needed**: `redox-drm` should call `load_drm_panel_orientation(connector, &conn_info)` and rotate the connector's framebuffer (or pass rotation to the DRM-mode-config) when the rule matches. Required before rotation-aware KWin/Plasma can land |
|
||
| R13 | `load_platform_dmi_quirks` (in platform-x86 driver) | `local/recipes/system/driver-manager` (or similar) | ⏳ Pending | **Consumer needed**: the seven `PlatformSubsystem` variants (touchscreen, tablet_mode, hotkey, accelerometer, battery, …) each have a target kernel subsystem or userspace daemon. The dispatcher (probably a small `redbear-platform-dmid` daemon or a thread in `acpid`) reads the DMI, calls `apply_platform_dmi_quirks`, and emits the right uevent/DBus signal |
|
||
| R14 | `lookup_cpu_bug_flags` (in `redox-driver-sys`) | Kernel | ⏳ Pending | **Kernel consumer needed**: the kernel boot path (or a userspace early-boot daemon) should call `lookup_cpu_bug_flags(&cpu_id)` and disable speculative execution paths (single-threaded indirect-branch prediction, MDS clearing, etc.) when the rules say so. This is a kernel-side change in `local/sources/kernel/` |
|
||
| R15 | `load_clocksource_flags` (via DMI / PCI lookup) | `local/sources/base` timer code | ⏳ Pending | **Consumer needed**: the boot-time PMTMR/TSC selection code (currently in `local/sources/kernel/src/` `time` module) should consult `load_clocksource_flags` and avoid the matched devices. The rules are small (3 entries) so wiring is 1 day |
|
||
| R17 | `load_chipset_flags` (early-boot) | `local/sources/base` chipset code or `acpid` | ⏳ Pending | **Consumer needed**: the 11 chipset entries gate certain `arch/x86/kernel/early-quirks.c` operations (force-disabled caching, SMM routing, etc.). A kernel-side or `acpid`-side hook that reads `lookup_chipset_flags(vid, did, class, class_mask)` and applies the flags is required. Wiring is 1-2 days |
|
||
| R18 | `lookup_pci_quirks_full` (storage) | `nvmed`, `ahcid`, `usbscsid` | ⏳ Pending | **Consumer wiring**: each storage daemon should call `lookup_pci_quirks_full(&device_info)` at enumeration and apply the imperative actions (most are single-bit clears for legacy ATI/AMD controllers). 1-2 days per daemon |
|
||
| R19 | `lookup_pci_quirks_full` (network) | `e1000d`, `r8169d`, `ixgbed`, `redbear-iwlwifi` | Partial | `redbear-iwlwifi` already calls `lookup_pci_quirks` (Gap 12 RESOLVED). The other network daemons need the same wiring. 1 day per daemon |
|
||
| R20 | `lookup_usb_audio_quirks` (in `redbear-usbaudiod`) | `redbear-usbaudiod` | ⏳ Pending | **Consumer wiring**: `redbear-usbaudiod` should call `lookup_usb_audio_quirks(vendor, product)` at device-add and apply the 29 flags (skip sample-rate queries, force explicit feedback endpoint format, etc.). The driver is in the WIP `redbear-usbaudiod` recipe; wiring is 1-2 days once the driver skeleton is up |
|
||
| R21 | `apply_dmi_acpi_quirk_rules` (AMD IOMMU) | `iommu` daemon | ⏳ Pending | **Consumer wiring**: the `iommu` daemon should call `apply_dmi_acpi_quirk_rules` and, when a rule matches, mark the IVRS table as "needs bypass" (or pass the flag to the kernel's IOMMU subsystem). The 4 entries are Dell/Acer/Lenovo laptops known to have broken AMD IOMMU. 1 day |
|
||
| R16 | (deferred) | — | Deferred | Algorithmic — no data table possible. MTRR/PAT/NUMA routing is hand-coded in kernel init. See `95-mtrr-deferred.toml` for the audit |
|
||
| R22 | (deferred) | — | Deferred | Imperative — boot parameters are command-line strings, not data. See `99-bootparams-deferred.toml` for the audit |
|
||
|
||
### Initialization-Path Wiring (How a Real Boot Discovers + Applies All Quirks)
|
||
|
||
For the subsystem to be "fully automatically made to work", the boot
|
||
sequence below must complete without manual intervention. Each step
|
||
corresponds to existing or planned wiring; missing steps are flagged.
|
||
|
||
```
|
||
1. Bootloader (UEFI / GRUB)
|
||
└── reads SMBIOS from firmware → publishes to kernel
|
||
2. Kernel microkernel
|
||
└── SmbiosScheme exposes SMBIOS table to userspace
|
||
3. acpid
|
||
├── reads /scheme/kernel.smbios/table → parses DMI fields
|
||
├── writes /scheme/acpi/dmi and /scheme/acpi/dmi/{field}
|
||
└── (PLANNED) calls apply_dmi_acpi_quirk_rules(...)
|
||
returns AcpiQuirkFlags; acpid then decides whether to skip
|
||
specific AML paths
|
||
4. pcid
|
||
├── enumerates PCI devices
|
||
├── calls lookup_pci_quirks_full(&device_info) per device
|
||
├── applies flags at handle_parsed_header time
|
||
└── iterates actions via PcidConfigWriter (Blocker 1 RESOLVED)
|
||
5. xhcid (and other controller drivers)
|
||
├── reads /scheme/acpi/dmi (DMI available since Blocker 2)
|
||
├── calls lookup_xhci_controller_quirks_full(vid, did, Some(dmi))
|
||
└── (PLANNED) iterates actions when xhcid-side QuirkAction follow-up lands
|
||
6. usbhidd
|
||
├── enumerates USB HID devices
|
||
├── (PLANNED) calls lookup_usb_quirks and lookup_hid_quirks
|
||
│ and applies flag-driven behavior (NO_INIT_REPORTS,
|
||
│ ALWAYS_POLL, USB_QUIRK_RESET_RESUME, USB_QUIRK_NO_LPM)
|
||
└── (PLANNED) forwards vendor/product to evdevd via IPC
|
||
7. evdevd
|
||
├── (PLANNED) reads vendor/product from usbhidd IPC (not 0)
|
||
└── calls lookup_hid_quirks; applies the same flag set
|
||
8. redbear-iwlwifi (and other network daemons)
|
||
├── calls lookup_pci_quirks / lookup_pci_quirks_full at probe
|
||
└── applies flags (NO_MSI for early RTL8xxx, FORCE_LEGACY_IRQ for RTL8105, etc.)
|
||
9. Storage daemons (nvmed, ahcid, usbscsid)
|
||
├── (PLANNED) call lookup_pci_quirks_full at probe
|
||
└── apply flags (NO_PM_RESET, NO_FLR, etc.) and actions
|
||
10. redbear-usbaudiod
|
||
├── (PLANNED) calls lookup_usb_audio_quirks at device-add
|
||
└── applies 29 flag-driven behaviors (rate, format, endpoint)
|
||
11. redox-drm
|
||
├── (DONE) calls full.quirks() at probe; applies DISABLE_ACCEL,
|
||
│ NEED_FIRMWARE, FORCE_LEGACY_IRQ
|
||
└── (PLANNED) calls load_drm_panel_orientation, load_platform_dmi_quirks,
|
||
load_amd_iommu_dmi_rules at appropriate points
|
||
12. Kernel (CPU bug mitigations)
|
||
├── (PLANNED) calls lookup_cpu_bug_flags(&cpu_id) at early boot
|
||
└── applies mitigations per X86_BUG_* semantics
|
||
13. redbear-quirks package
|
||
└── (DONE — Finding 2) glob-installs every *.toml from
|
||
quirks.d/ into /etc/quirks.d/ on the running image
|
||
```
|
||
|
||
### Implementation Order for Full Utilization
|
||
|
||
The remaining wiring tasks (rows 5–12 above marked PLANNED) can be
|
||
parallelized. The recommended sequence is:
|
||
|
||
| # | Task | Driver tree | Estimate | Depends on |
|
||
|---|---|---|---|---|
|
||
| 1 | xhcid `QuirkAction` iteration | `local/sources/base/drivers/usb/xhcid` | 1-2 days | Blocker 1 (RESOLVED) |
|
||
| 2 | usbhidd `lookup_hid_quirks` actionable (`NO_INIT_REPORTS`, `ALWAYS_POLL`) | `local/sources/base/drivers/input/usbhidd` | 1 day | R10 lookup (WIRED) |
|
||
| 3 | usbhidd → evdevd vendor/product IPC | `local/sources/base/drivers/input/usbhidd` + `evdevd` recipe | 1-2 days | R10 lookup |
|
||
| 4 | acpid `apply_dmi_acpi_quirk_rules` consumer | `local/sources/base/drivers/acpid` | 1-2 days | R11 data (DONE) |
|
||
| 5 | redox-drm `load_drm_panel_orientation` consumer | `local/recipes/gpu/redox-drm` | 1 day | R12 data (DONE) |
|
||
| 6 | redox-drm `load_platform_dmi_quirks` consumer | `local/recipes/gpu/redox-drm` | 1-2 days | R13 data (DONE) |
|
||
| 7 | kernel `lookup_cpu_bug_flags` consumer | `local/sources/kernel` | 5-8 days | R14 data (DONE) |
|
||
| 8 | base/early `load_clocksource_flags` consumer | `local/sources/base` (timer) | 1 day | R15 data (DONE) |
|
||
| 9 | base/early `load_chipset_flags` consumer | `local/sources/base` (chipset) or `acpid` | 1-2 days | R17 data (DONE) |
|
||
| 10 | storage daemons `lookup_pci_quirks_full` consumer | `local/sources/base/drivers/storage/{nvmed,ahcid,usbscsid}` | 1-2 days | R18 data (DONE) |
|
||
| 11 | network daemons `lookup_pci_quirks_full` consumer | `local/sources/base/drivers/net/{e1000d,r8169d,ixgbed}` | 1-2 days | R19 data (DONE) |
|
||
| 12 | redbear-usbaudiod `lookup_usb_audio_quirks` consumer | `local/recipes/system/redbear-usbaudiod` | 1-2 days | R20 data (DONE) + driver skeleton |
|
||
| 13 | iommu daemon `apply_dmi_acpi_quirk_rules` consumer | `local/recipes/system/iommu` | 1 day | R21 data (DONE) |
|
||
| 14 | redox-drm `load_amd_iommu_dmi_rules` consumer | `local/recipes/gpu/redox-drm` | 1 day | R21 data (DONE) |
|
||
| 15 | kernel PMTMR / early-quirks / TSC selection consumers | `local/sources/kernel` | 3-5 days | R14, R15, R17 data |
|
||
| **Total** | | | **22-32 days** | parallelizable to 2-3 devs in 4-6 weeks |
|
||
|
||
After the 15 tasks above land, every lookup function in
|
||
`redox-driver-sys::quirks` has at least one production consumer; the
|
||
data tables drive real kernel/userspace behavior; and the R0–R22
|
||
infrastructure is "fully automatically made to work" on real hardware.
|
||
|
||
### Test Count After Audit Fixes
|
||
|
||
The R7 audit added 3 unit tests for the new `cb_intel_ntb_bar_fix`
|
||
behavior. Combined with the prior R0–R10 work, the totals are:
|
||
|
||
- **131** host-buildable redox-driver-sys unit tests
|
||
- **13** acpid DMI tests
|
||
- **12** pcid PciConfigWriter tests
|
||
- **7** usbhidd HID/USB tests
|
||
- **4** evdevd HID tests
|
||
- **3** redbear-iwlwifi PCI tests
|
||
- **170** total host-OR-target tests across the subsystem
|
||
|
||
The three new R7 audit tests are the smallest set that proves the
|
||
fixed `cb_intel_ntb_bar_fix` exercises real hardware cycles: silicon
|
||
size bytes are read, untouched after the call, and the zero-registers
|
||
case is handled without panic.
|