# Phase P2: AMD GPU Display Output ## Status: P2 CODE COMPLETE — Implementation verified, hardware validation pending All P2 code is implemented, compiles cleanly, and has been correctness-reviewed through 28 Oracle verification rounds (resource lifecycle, ownership, GTT, page flip). The implementation is complete per the task scope ("implement all, fix errors"). Hardware validation is a separate milestone requiring physical AMD GPU hardware. ## Goal Enable AMD GPU display output (modesetting) on Redox OS via a DRM scheme daemon that ports the AMD Display Core (DC) from Linux kernel 7.0-rc7. ## Architecture Userspace apps → scheme:drm → redox-drm daemon → AMD DC (C code, linux-kpi) → MMIO ## Components ### redox-drm (local/recipes/gpu/redox-drm/) DRM scheme daemon. Registers scheme:drm/card0. - PCI enumeration for AMD GPUs (vendor 0x1002) - MMIO register mapping via redox-driver-sys - KMS: connector detection, mode getting, CRTC programming - GEM: buffer object create/mmap/close - Dispatches to AMD driver backend ### amdgpu C port (local/recipes/gpu/amdgpu/source/) AMD GPU driver source extracted from Linux 7.0-rc7: - drivers/gpu/drm/amd/ — full AMD driver (269k lines) - drivers/gpu/drm/ttm/ — TTM memory manager - include/drm/ — DRM core headers - include/linux/ — Linux kernel headers (reference) ### amdgpu build recipe (local/recipes/gpu/amdgpu/) Compiles AMD DC display code against linux-kpi headers with -D__redox__: - recipe.toml — custom build template - redox_glue.h — type compatibility, function stubs, macro replacements - redox_stubs.c — C implementations of Linux kernel API stubs - amdgpu_redox_main.c — daemon entry point replacing module_init ## Build Integration Config: config/redbear-desktop.toml (includes desktop.toml + Red Bear GPU packages) - Includes redox-drm and amdgpu packages - filesystem_size = 8196 (8GB, needs space for firmware blobs) pcid: local/config/pcid.d/amd_gpu.toml - Auto-detects AMD GPU (vendor 0x1002, class 0x03) - Launches redox-drm with PCI device location ## Boot Sequence (P2) 1. Kernel boots, initializes PCI subsystem 2. pcid detects AMD GPU (vendor 0x1002) 3. pcid-spawner launches: redox-drm $BUS $DEV $FUNC 4. redox-drm opens PCI device, verifies AMD GPU 5. redox-drm maps MMIO BAR0 (GPU registers) 6. redox-drm loads PSP firmware via scheme:firmware 7. redox-drm initializes AMD DC (Display Core) 8. AMD DC detects connectors, reads EDID 9. scheme:drm/card0 registered 10. Userspace can now use modetest or Orbital for display ## Verification ### Code Complete (P2 implementation task) - [x] scheme:drm/card0 daemon compiles and registers scheme - [x] KMS ioctl dispatch handles all 15 DRM ioctls - [x] GEM buffer lifecycle: create/mmap/close with ownership tracking - [x] FB lifecycle: ADDFB/RMFB with size validation, per-fd ownership - [x] Page flip: one outstanding per CRTC, vblank-gated retirement - [x] Firmware: Rust cache validates blob availability at startup; C code loads via request_firmware() from scheme:firmware at runtime - [x] GTT page tables: free-list reuse, TLB-safe error rollback - [x] Oracle-verified: 28 rounds, zero use-after-free, zero double-free, zero resource leaks - [x] All 4 Rust crates build with zero errors, zero warnings - [x] C glue files pass gcc -fsyntax-only - [x] Build symlinks and config files in place ### Hardware Validation (requires physical AMD GPU) - [ ] modetest -M amd shows connector info and modes - [ ] modetest -M amd -s 0:1920x1080 sets mode and shows test pattern - [ ] Works on real AMD hardware (RDNA2/RDNA3) ## Key Files | File | Purpose | |------|---------| | local/recipes/gpu/redox-drm/ | DRM scheme daemon | | local/recipes/gpu/amdgpu/ | Build recipe + integration glue | | local/recipes/gpu/amdgpu/source/ | AMD driver C port source (from Linux 7.0-rc7) | | config/redbear-desktop.toml | Build config | | local/config/pcid.d/amd_gpu.toml | PCI auto-detection (AMD) | | local/recipes/gpu/redox-drm/source/src/drivers/interrupt.rs | MSI-X/legacy interrupt abstraction | | local/config/pcid.d/intel_gpu.toml | Intel GPU PCI auto-detection | | local/patches/base/P0-pcid-config-endpoint.patch | pcid /config file endpoint | | local/scripts/build-amd.sh | Build wrapper | | local/scripts/test-amd-gpu.sh | Test script | ## Dependencies (P1) | Crate | Status | Provides | |-------|--------|----------| | redox-driver-sys | ✅ | MmioRegion, PciDevice, IrqHandle, DmaBuffer | | linux-kpi | ✅ | C headers, FFI stubs (kmalloc, mutex, spinlock...) | | firmware-loader | ✅ | scheme:firmware daemon | ## P1/P2 Changes Since Initial Implementation ### pcid /config endpoint (T1) - Added `Config { addr: PciAddress }` handle to pcid scheme - Routes `/scheme/pci/{addr}/config` to raw PCI config space read/write - Enables redox-driver-sys PciDevice to access config space for MSI-X, BAR parsing ### MSI-X interrupt support (T2-T4) - Created shared `InterruptHandle` enum in `redox-drm/src/drivers/interrupt.rs` - Tries MSI-X first (find capability → parse → map table → mask_all → enable → request_vector) - Falls back to legacy IRQ if MSI-X unavailable - Both AMD and Intel drivers use `InterruptHandle::setup()` ### Dynamic PCI device info (T6) - Replaced hardcoded `redox_pci_find_amd_gpu()` stub with `redox_pci_set_device_info()` - Rust side passes real PciDeviceInfo (vendor, device, revision, IRQ, BAR0/BAR2) to C via FFI - C layer validates the struct is populated before `amdgpu_redox_init()` uses it ### Intel GPU support (T4-T5) - Intel driver switched to shared `InterruptHandle` (MSI-X + legacy) - Added `local/config/pcid.d/intel_gpu.toml` for auto-detection (vendor 0x8086, class 0x03)