Skip to content
Draft
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
1 change: 1 addition & 0 deletions build/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3106,6 +3106,7 @@ mod tests {
"tests/images/proctreecase.toml",
"tests/images/scalecase.toml",
"tests/images/testcases.toml",
"tests/images/undeclaredcase.toml",
"tests/images/virtclaimcase.toml",
"tests/images/virtjobcase.toml",
"tests/images/virtpaniccase.toml",
Expand Down
6 changes: 3 additions & 3 deletions build/licence.rs
Original file line number Diff line number Diff line change
Expand Up @@ -406,9 +406,9 @@ pub const COMMITTED_FILES: &[(&str, &str, &str, Terms)] = &[
Terms::Spdx("MIT OR Apache-2.0"),
),
(
"lib/acpi/fixtures/ovmf-pure-efi/root-bridge-0.bin",
"eb00e68be746a09ac7f0ce1ca492ce8c858e3af1152112b49ffb4708883acbfb",
"ours: OVMF's answer on a q35 guest, read off that boot's own loader log",
"lib/acpi/fixtures/qemu-11.1.1-virt/dsdt.bin",
"908d068d6d70db725bd139ac5a8fe9511373ab59a0570a0f285c3c59d60cd227",
"ours: QEMU `virt`'s own DSDT, captured by the commit that declares its root bridge's `_CRS`",
Terms::Spdx("MIT OR Apache-2.0"),
),
// A bcachefs volume upstream's own tools wrote, gzipped. The bytes inside
Expand Down
4 changes: 3 additions & 1 deletion images/system.toml
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,9 @@ serves = ["log"]
# firmware's own access: the kernel makes the AML's reads and writes for it,
# inside the fences of `toyos_userbound::firmware`. `power` is how a press
# stops the machine: through the supervisor, which has `logkeeper` make the
# log whole.
# log whole. It declares the memory the PCI root bridges decode out of each
# root's `_CRS`, which every PCI claim waits for, so the supervisor starts it
# before every other row; an image that claims a PCI function starts it.
[programs.acpiserver]
service = true
devices = ["acpi"]
Expand Down
48 changes: 0 additions & 48 deletions issues/an-aarch64-cargo-run-boot-hands-over-no-pci-claim.md

This file was deleted.

30 changes: 30 additions & 0 deletions issues/an-x86-machine-with-no-acpi-row-hands-over-no-pci-claim.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
---
status: open
kind: defect
opened: 2026-10-15
---

# An x86 machine with no ACPI row hands over no PCI claim

Every PCI claim waits for the holder of the `acpi` claim to declare the root
bridges (`kernel/src/pcidev`'s `declare`, made by `/system/bin/acpiserver`),
and on x86-64 that claim exists only over a row `acpi_mode::init`
(`kernel/src/arch/x86_64/acpi_mode.rs`) fills. It fills none where the FADT is
unusable, its fixed hardware is refused (`HW_REDUCED_ACPI` among the
refusals), no PM1a control block is declared, its `SMI_CMD` was not declared,
no I/O APIC carries the SCI, or the SCI's line is another row's. On such a
machine acpiserver gets no claim and declares nothing, so the first PCI claim
waits its 30 s deadline and every claim of the boot is refused, the block
service's NVMe among them. Before #935 the loader's window list handed those
claims over.

Measured: none of the machines in reach is such a machine. q35, the
ThinkPad T14 and the AMD bench each fill the row (their `acpi: the ACPI row:`
lines); a hardware-reduced x86 guest (Cloud Hypervisor, QEMU's `microvm`)
would not, as `issues/a-hardware-reduced-x86-machine-has-no-power-off-and-no-power-button.md`
records for its power-off.

**Owner**: the PCI apertures track (#916, #935).

**Exit**: such a machine declares its root bridges through a path that needs
no `acpi` claim row, or the gap is measured absent on every supported machine.
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,10 @@ pure and tested, `a_released_address_is_offered_again` pins the give-back
arithmetic, and `https_tls13_e1000e` asserts the count of BARs kept back by
name, so deleting the `BarReferenceEmpty` refusal reds.

**Exit condition.** A guest whose claimed function sits behind a `pcie-root-port`
given a memory window of a few MiB. **The port's window is the thing to arrange**:
it produces the case only because `KernelArgs::root_bridge_windows` carries the
loader's free GCD MMIO ranges, which are the host bridge's whole aperture and not
the port's slice of it — on q35 that range is `0xc1100000+0x3af00000` — so a
candidate past the port's window is an address this kernel may name and the
function does not answer at. Booted with an arm asserting the `left {at:#x}`
record, that the BAR ended at a later candidate, and that deleting the comparison
reds that arm.
**Exit condition.** A guest that offers a claimed function a candidate it does
not answer at, booted with an arm asserting the `left {at:#x}` record, that the
BAR ended at a later candidate, and that deleting the comparison reds that arm.
The declared windows are now each root's `_CRS`, and a function behind a bridge
is offered only what every bridge on its path forwards, so the loader's
over-wide list this once relied on is gone and a new way to arrange the case is
owed.
4 changes: 2 additions & 2 deletions kernel/pci/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ edition = "2021"
license = "MIT OR Apache-2.0"

[dependencies]
# The window type the bootloader hands the kernel, declared once in the ABI and
# read here rather than mirrored: a second spelling of a base and a length is
# The window type an ACPI server declares to the kernel, declared once in the
# ABI and read here rather than mirrored: a second spelling of a base and a length is
# two readers that can disagree about one machine's aperture.
toyos-abi = { path = "../../sdk/abi" }
Loading