feat: Parallels Desktop ARM64 platform support#237
Merged
Conversation
Add complete UEFI boot chain for running Breenix on Parallels Desktop (Apple Silicon). This includes a UEFI loader that discovers hardware via ACPI, loads the kernel ELF from the ESP filesystem, and hands off to the existing kernel_main with a HardwareConfig struct. Key components: - parallels-loader: UEFI application (aarch64-unknown-uefi) that parses ACPI tables (MADT, MCFG, SPCR/DBG2) to discover GIC, PCI, and UART addresses, loads the kernel ELF, sets up identity+HHDM page tables, and jumps to kernel_main with hardware config in x0. - platform_config: Runtime hardware configuration with atomic accessors defaulting to QEMU virt addresses. When x0 != 0 at kernel_main entry, the HardwareConfig from the UEFI loader overrides these. - GICv3 driver: Runtime GICv2/v3 dispatch based on platform_config. GICv3 uses ICC system registers for CPU interface and GICR redistributor frames instead of MMIO GICC. - PCI ECAM: ARM64 read/write implementation using memory-mapped config space at the platform-discovered ECAM base address. - VirtIO PCI transport: Modern VirtIO 1.0 PCI capability parsing for network and GPU devices on Parallels (vs VirtIO MMIO on QEMU). - AHCI storage driver: HBA initialization, port discovery, and BlockDevice trait implementation for SATA disks on Parallels. - Dynamic UART: All hardcoded 0x09000000 UART references replaced with platform_config::uart_virt() calls across serial, tracing, context switch, SMP, and syscall entry paths. - run.sh --parallels: Single-command build and deploy to Parallels VM. The existing QEMU ARM64 boot path is unchanged — platform_config defaults to QEMU virt addresses when no HardwareConfig is provided (x0 = 0). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…for Parallels ARM64 - run.sh: ext2 disk image creation and AHCI attachment for Parallels - ELF loader: add cache maintenance (dc cvau + ic iallu) after loading segments - UART diagnostics: DIAG_UART_VIRT global for assembly-level debug output - Exception vectors: diagnostic breadcrumbs for IRQ/sync from EL0 debugging - handle_irq: serial breadcrumbs for interrupt flow tracing - TTBR0 TLB flush: in progress, currently debugging user mapping visibility - Interrupt enable/disable fixes around init process loading - ext2 filesystem: AHCI-backed block reads, superblock/inode/block_group parsing - parallels-loader: GOP framebuffer discovery, improved kernel entry setup - GPT/ESP patching script for disk image preparation Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Expert panel analysis confirmed TLBI instructions execute natively on Apple Silicon via Hypervisor.framework (not trapped). The original "TLBI hangs on Parallels" diagnosis was incorrect — the real bugs were MAIR attribute index mismatch and HHDM address space issues, both previously fixed. Remove all is_qemu() guards around TLBI sequences so both QEMU (TCG software emulation) and Parallels (native hardware execution) use identical ARM64 instruction sequences. Follow Linux's canonical TLB flush pattern: dsb ishst → tlbi → dsb ish → isb. Key changes: - boot.S: use x1 as branch register, pass x0=0 (no HardwareConfig) - context_switch.rs: unconditional TLBI on TTBR0 switch, ASID=1 tagging - exception.rs: unconditional TLBI for CoW fault handling - syscall_entry.S: full TLBI sequences on all TTBR0 switch paths - main_aarch64.rs: unified TTBR0 switch with ASID tagging, HHDM switch - parallels-loader: fix MAIR index order to match kernel boot.S - Remove all diagnostic breadcrumb characters from hot paths Tested: QEMU ARM64 boot test passes, Parallels boots with all 5 fork+exit tests passing, 52K syscalls/sec sustained. Co-Authored-By: Ryan Breen <ryanbreen@gmail.com> Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add VirtIO GPU PCI driver and XHCI USB HID driver for Parallels Desktop ARM64 support. The display uses a hybrid approach: VirtIO GPU PCI controls the display mode (resolution/stride via set_scanout) while pixels are written to the GOP/BAR0 framebuffer address, enabling 1280x800 resolution beyond the GOP-limited 1024x768. Key changes: - VirtIO GPU PCI driver with modern transport, VIRTIO_F_VERSION_1 feature negotiation, and full 2D command set (create_resource, attach_backing, set_scanout, transfer_to_host, resource_flush) - GPU PCI+GOP hybrid framebuffer: VirtIO GPU for mode setting, GOP memory for pixel output with DSB barrier flush - XHCI USB host controller driver with device enumeration, HID boot protocol keyboard support, and EP0 GET_REPORT fallback polling - UEFI GOP mode enumeration with raw UART serial logging - Correct syscall flush path routing through arm64_fb::flush_dirty_rect() - FB_INFO_CACHE for lock-free dimension queries on all backends Tested on Parallels Desktop 20 (Apple Silicon): clean 1280x800 display, full userspace (init, bwm, bsh, telnetd), USB keyboard polling at ~100Hz. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… architecture Increase VirtIO GPU PCI default resolution from 1280x800 to 2560x1600, the maximum that fits in the ~16MB GOP BAR0 region on Parallels. On Retina Macs, Parallels applies 2x scaling so this appears as ~1280x800 window points with crisp rendering. Key insight documented: on Parallels, VirtIO GPU set_scanout changes the display's reading stride but pixels are scanned from GOP memory (0x10000000), not the VirtIO backing buffer. The kernel must write at the GPU-configured stride, not the UEFI GOP stride, to avoid tiling artifacts. Also adds VirtIO Input PCI driver stub and suppresses dead_code warning on xhci max_ports field. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… index collision Three fixes to the XHCI driver for spec compliance and correctness: 1. Max Packet Size placement: moved from DW4 bits[31:16] to DW1 bits[31:16] per xHCI spec section 6.2.3. DW4 now correctly contains Max ESIT Payload. 2. Full slot context copy: ConfigureEndpoint now copies all 4 DWORDs of the slot context from the device context (previously only DW0 and DW1). 3. Transfer ring index collision: HID interrupt endpoints (keyboard/mouse) now use separate ring indices (HID_RING_BASE + hid_idx) instead of sharing indices 0/1 with EP0 control rings for slots 1/2. Note: Parallels Desktop's virtual XHCI controller still returns CC=12 (Endpoint Not Enabled) on interrupt transfers despite correct endpoint context (verified: state=1, CErr=3, EPtype=7, maxPkt=64). EP0 GET_REPORT fallback also non-functional (controller echoes SETUP packet as data). These are Parallels emulation limitations, not driver bugs. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…diagnostics Add EHCI USB 2.0 host controller driver to test alternate USB path on Parallels ARM64. All 15 EHCI ports show CCS=0 — Parallels routes all USB devices exclusively through xHCI SuperSpeed ports. EHCI is a confirmed dead end but retained for reference. Key xHCI improvements for Parallels ARM64 keyboard input: - Add USE_BULK_FOR_INTERRUPT workaround: configure interrupt endpoints as Bulk IN (ep_type=6) to bypass Parallels' broken periodic scheduler. CC=12 occurs because Parallels doesn't implement SuperSpeed interrupt endpoint scheduling despite reporting the endpoint as Running. - Add synchronous GET_REPORT/GET_PROTOCOL/GET_DESCRIPTOR tests during init to diagnose whether the setup packet echo (every GET_REPORT returns the 8-byte setup packet a1 01 00 01 00 00 08 00 instead of actual HID data) is a Parallels emulation bug or an async path issue. - Parse xHCI Extended Capabilities to discover USB protocol port mapping: ports 1-12 = USB 3.x, ports 13-14 = USB 2.0 (both empty on Parallels). - Add DMA sentinel diagnostic counters (DS/DR in heartbeat) to track whether the xHCI DMA actually writes to report buffers. - Add HID Report Descriptor fetching and hex dump for diagnostic purposes. - Add GICv2m MSI support for xHCI interrupts (SPI allocation, edge-triggered). - Make PCI config access functions pub(crate) for cross-driver use. - Add EHCI polling and diagnostic counters to ARM64 timer interrupt. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Test plan
🤖 Generated with Claude Code