Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion build/qemu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,10 @@ fn machine(arch: Arch, iommu: bool) -> String {
match (arch, iommu) {
(Arch::X86_64, true) => format!("{base},kernel-irqchip=split"),
(Arch::X86_64, false) => base.to_string(),
(Arch::Aarch64, true) => format!("{base},gic-version=3,iommu=smmuv3"),
// HVF's GIC has no ITS; PCI claims need QEMU's GIC to remap their messages.
(Arch::Aarch64, true) => {
format!("{base},gic-version=3,iommu=smmuv3,its=on,kernel-irqchip=off")
}
(Arch::Aarch64, false) => format!("{base},gic-version=3"),
}
}
Expand Down
30 changes: 30 additions & 0 deletions issues/the-arm-desktop-starts-with-no-keyboard-or-mouse.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
---
status: open
kind: defect
opened: 2026-10-11
---

# The ARM desktop starts with no keyboard or mouse

An AArch64 boot of `images/system.toml` under QEMU `virt` reaches the
supervisor and initializes virtio-gpu, but the compositor exits 101 at
`system/compositor/src/session.rs` because its keyboard endowment is absent.
The supervisor reports both keyboard and mouse absent. This was read in
the owner's boot of `57616a067` and reproduced with the shipping image.

The launcher attaches a USB keyboard and tablet to its xHCI. The kernel's
xHCI driver refuses to arm on AArch64: `arch/aarch64/irqchip/its.rs::msi`
refuses kernel drivers. Enabling the ITS makes PCI claims possible but
does not give that driver an interrupt. `system/usbd` currently enumerates
devices without binding their classes and is not started by the shipped
manifest. There is no virtio-input driver.

Owner: `issues/toyos-runs-on-arm64.md`, stages 6 and 7, with the userland
USB move in `issues/the-kernel-is-small-interrupts-post-and-threads-wait.md`.
DMA and interrupt isolation remain required.

Exit: an ARM boot of the shipped manifest supplies real keyboard and mouse
input to the compositor; injected key transitions and pointer events reach
the desktop and an application's window in a test that fails when delivery
is removed. The compositor starts and presents a frame without the missing
keyboard panic.
5 changes: 5 additions & 0 deletions kernel/src/pcidev/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -495,6 +495,11 @@ pub fn publish(devices: &[PciDevice], segment: u16, maps: &[MemoryMapEntry], fir
let mut decoded = Vec::new();
let mut taken: Vec<Window> =
maps.iter().map(|entry| Window { start: entry.start, end: entry.end }).collect();
// ECAM decodes configuration space even when firmware lists it as free MMIO.
taken.extend(crate::drivers::pci::windows().into_iter().map(|ecam| {
let (start, bytes) = ecam.decoded();
Window { start, end: start.saturating_add(bytes) }
}));
for device in devices {
// Bounded by the header's own declaration: a bridge has two BAR slots
// and four registers past them that are not BARs, and `bar_size` below
Expand Down
18 changes: 17 additions & 1 deletion tests/toyos.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2246,7 +2246,8 @@ fn virt_no_seed_refused(profile: qemu::Profile, test_config: &Path) -> Result<()

/// A machine whose MCFG decodes sixteen buses, with RAM past them: the kernel
/// maps those sixteen buses' megabytes and no more, and enumerates the
/// functions QEMU put there and nothing else, and the boot goes on.
/// functions QEMU put there and nothing else. BAR placement keeps the
/// configuration window out of its free runs, and the boot goes on.
fn virt_low_ecam(profile: qemu::Profile, test_config: &Path) -> Result<(), String> {
const WINDOW: &str = "ACPI: ECAM window: segment 0 buses 0x00..=0x0f, bus 0 at 0x3f000000";
const MAPPED: &str = "mmio: 0x3f000000+0x1000000 ";
Expand Down Expand Up @@ -2281,6 +2282,21 @@ fn virt_low_ecam(profile: qemu::Profile, test_config: &Path) -> Result<(), Strin
return Err(format!("{want:?} not on the PL011\nserial:\n{serial}"));
}
}
let mut runs = 0;
for line in serial.lines().filter_map(|l| l.split_once("pcidev: ").map(|(_, run)| run)) {
let range = line.split_whitespace().next().ok_or("an empty PCI free run")?;
let (start, end) = range.split_once("..").ok_or("a PCI free run without its end")?;
let address = |word: &str| u64::from_str_radix(word.trim_start_matches("0x"), 16)
.map_err(|why| format!("invalid PCI free-run address {word:?}: {why}"));
let (start, end) = (address(start)?, address(end)?);
if start < 0x4000_0000 && end > 0x3f00_0000 {
return Err(format!("BAR placement offers ECAM configuration space in {range}\nserial:\n{serial}"));
}
runs += 1;
}
if runs == 0 {
return Err(format!("the boot reported no PCI free runs\nserial:\n{serial}"));
}
eprintln!(" [virt] {WINDOW}; {} functions: {found:?}", found.len());
Ok(())
}
Expand Down