Repository navigation
tgl-display: the T14's display engine lets memory idle (stage 1), and the display track - #1125
Merged
Merged
Conversation
Japabu
added a commit
that referenced
this pull request
Nov 1, 2026
…one keeps it
The owner's ruling of 2026-10-04 ("Display and USB only") now decides each
function an RMRR names, at the DMAR walk: `kernel::rmrr::verdict`, pure and
host-tested, keeps the range for a display or USB controller named alone in
whole 4 KiB pages, and refuses every other function by name in VT-d's
`unclaimable`, as AMD-Vi refuses an IVMD's. A scope behind a bridge is
followed through the bridges this kernel enumerated, a sub-hierarchy names
every function below it, and a path that cannot be followed is another device
sharing the range. So `keep_reserved` cannot fail and spends no domain id on a
refusal, and a kept range is mapped in 2 MiB leaves where it covers one and
4 KiB pages at its ends, which a usual small xHCI RMRR needs.
tgl-display: the frame counter and its time are read together; a plane
rotated 90/270 or decompressing is refused; PLANE_BUF_CFG's Buffer End is
inclusive (Vol 12's own 0x009F0000 for blocks 0-159), so the T14's plane has
682 blocks; level 0 is a value, not an option; the window covers only the
registers reached; dead registers are gone. New host tests: method 1 under a
short allocation, a mailbox that stays busy, rotation and decompression.
Records: the track's rulings are only the owner's, with the earlier ones
cited; stage 1's transition and SAGV lines match the code; its exit states
the residency. The IOMMU track's exit and the identity-domain defect say
what the claim now keeps.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Japabu
added a commit
that referenced
this pull request
Nov 1, 2026
…nknown scope shares `kernel::rmrr::classify` now decides every function the RMRRs name once the DMAR walk is whole, over scopes vtd resolved: a function's memory is its alone only where every region overlapping any of its own names it and nothing else, so two overlapping RMRRs of two functions refuse both. One function's identical or overlapping RMRRs merge, so each address is placed once and a firmware table cannot make keep_reserved map a leaf twice. A scope that is not an endpoint or a sub-hierarchy that resolves - another kind, an ACPI namespace device among them, a path through an unconfigured bridge, or a malformed entry and the rest of its list - is a device sharing the range. The leaves a kept range is mapped with are `kernel::rmrr::leaves`, host-tested across a 2 MiB boundary. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Japabu
added a commit
that referenced
this pull request
Nov 1, 2026
…from, and a region off segment 0 shares A function's overlapping or adjacent RMRRs merge into one kept range, which no single avoided region contains: `Domains::reserved_space` now asserts the range lies inside their union (`kernel::rmrr::covered`), which a host test holds for every kept range against the RMRRs it came from. Every function is enumerated on one segment group, so an RMRR on another names devices this kernel cannot tell from its own: its scopes are unknown, and it shares. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The display-engine track, with the owner's rulings of 2026-10-31: release-1 scope on both benches; several outputs, extended or mirrored; Intel a Rust driver from Intel's PRMs; AMD an adapter around AMD's Display Core; a panic surface the driver registers. It records the ownership between each GPU's driver and the compositor over a `display-output` port, the kernel's two generic mechanisms, the defaults for display audio, docks and backlight, the stages, and what the read-only scout of the T14's GOP found that stage 1 rests on. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e 1) The T14's GOP enables watermark level 0 alone, so its scan-out never lets memory reach a low-power latency level; the package stays in PC2 with the panel lit. A new userland driver claims the iGPU (8086:9a49), keeps the firmware's mode and surface, reads pcode's memory latencies and SAGV block time (IHD-OS-TGL-Vol 12-12.21 "Memory Values"), and programs PLANE_WM levels 0-7 by Vol 12's "Watermark Algorithm", with level 0 carrying the SAGV block time where the plane tolerates it. Anything of the firmware's state it does not understand - more than one plane or pipe, the cursor on, a YUV plane, a stopped pipe, a line time not the mode's, a mailbox error, a plane that cannot tolerate SAGV - is refused by name and nothing is written. The pixel rate is measured off the frame counter over 30 frames and held against the firmware's own WM_LINETIME, rather than decoded from the PLL, which the modesetting stage owns. The transition watermark stays disabled: it tunes Isochronous Priority Control, not power. Kernel: a claimed function's own IOMMU domain now maps every RMRR whose scope names it, at its own address, when the domain is made and before the function attaches (VT-d Rev. 4.0 §8.4). The T14's plane reads the firmware framebuffer through a GGTT entry inside its RMRR, so without this the claim would fault every scan-out read. AMD-Vi already refuses claims of functions an IVMD names; AArch64 reads no such table. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
DC is vendored with a patch set that covers only its OS interface and build, and passes the licence evaluator and NOTICE. ToyOS's side is written clean-room from amdgpu_dm and the DRM helpers. Every sink byte DC takes from its OS side reaches a Rust parser first; what DC parses straight off its AUX hardware is a recorded compromise with an exit. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…one keeps it
The owner's ruling of 2026-10-04 ("Display and USB only") now decides each
function an RMRR names, at the DMAR walk: `kernel::rmrr::verdict`, pure and
host-tested, keeps the range for a display or USB controller named alone in
whole 4 KiB pages, and refuses every other function by name in VT-d's
`unclaimable`, as AMD-Vi refuses an IVMD's. A scope behind a bridge is
followed through the bridges this kernel enumerated, a sub-hierarchy names
every function below it, and a path that cannot be followed is another device
sharing the range. So `keep_reserved` cannot fail and spends no domain id on a
refusal, and a kept range is mapped in 2 MiB leaves where it covers one and
4 KiB pages at its ends, which a usual small xHCI RMRR needs.
tgl-display: the frame counter and its time are read together; a plane
rotated 90/270 or decompressing is refused; PLANE_BUF_CFG's Buffer End is
inclusive (Vol 12's own 0x009F0000 for blocks 0-159), so the T14's plane has
682 blocks; level 0 is a value, not an option; the window covers only the
registers reached; dead registers are gone. New host tests: method 1 under a
short allocation, a mailbox that stays busy, rotation and decompression.
Records: the track's rulings are only the owner's, with the earlier ones
cited; stage 1's transition and SAGV lines match the code; its exit states
the residency. The IOMMU track's exit and the identity-domain defect say
what the claim now keeps.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nknown scope shares `kernel::rmrr::classify` now decides every function the RMRRs name once the DMAR walk is whole, over scopes vtd resolved: a function's memory is its alone only where every region overlapping any of its own names it and nothing else, so two overlapping RMRRs of two functions refuse both. One function's identical or overlapping RMRRs merge, so each address is placed once and a firmware table cannot make keep_reserved map a leaf twice. A scope that is not an endpoint or a sub-hierarchy that resolves - another kind, an ACPI namespace device among them, a path through an unconfigured bridge, or a malformed entry and the rest of its list - is a device sharing the range. The leaves a kept range is mapped with are `kernel::rmrr::leaves`, host-tested across a 2 MiB boundary. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…from, and a region off segment 0 shares A function's overlapping or adjacent RMRRs merge into one kept range, which no single avoided region contains: `Domains::reserved_space` now asserts the range lies inside their union (`kernel::rmrr::covered`), which a host test holds for every kept range against the RMRRs it came from. Every function is enumerated on one segment group, so an RMRR on another names devices this kernel cannot tell from its own: its scopes are unknown, and it shares. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Japabu
force-pushed
the
display-stage1
branch
from
November 1, 2026 09:37
230c620 to
5fc1ba8
Compare
Japabu
marked this pull request as ready for review
November 1, 2026 09:38
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.
Problem
With the panel lit, the T14's idle package stays in PC2. The display as the firmware's GOP left it holds the package there: about 1.2 W at idle and 1.6 W under a 10 ms sleeper, against Linux's driver (pr-1100 r7).
A read-only scout of the GOP's display engine found:
The display therefore never lets memory reach a low-power latency level.
What this PR does
issues/each-gpu-drives-its-displays-from-a-userland-driver.md).display-outputport;tgl-display, a new driver claiming the T14's iGPU (8086:9a49). It keeps the firmware's mode and surface. It reads pcode's memory latencies and SAGV block time and programs PLANE_WM levels 0-7 by Vol 12's "Watermark Algorithm".toyos-tgl-display, host-tested against a modelled engine.kernel::rmrr::classify(pure, host-tested) decides every function the RMRRs name, over scopes vtd resolved.kernel::rmrr::covered).kernel::rmrr::leavesnames: 2 MiB where one fits, 4 KiB pages at the ends.unclaimable, as AMD-Vi refuses an IVMD's.9c800001) inside its RMRR, so without this the claim would fault every scan-out read.Decisions
0x009F0000.Checks
At the head rebased onto
3add613c1,5fc1ba8ad:cargo run -- --ci hostexit 0, 107 steps green;cargo run -- --build-onlyexit 0. The rebase changed no content:git range-diffshows every commit identical except one context line inimages/system.toml, where main reworded netstack's comment.The rest is at review r3's head,
230c6201d. Main's commits since touch none of the kernel files this PR changes, so they still apply. Evidence: https://github.com/ToyOSOrg/evidence/blob/e5a6e65e83e8a27da540398c9f1e2e2296e1b42d/r5/README.md. Review r2's checks are at https://github.com/ToyOSOrg/evidence/blob/4faea3bcd84adefdae5564697eac69a775e1d6bb/r4/README.md.cargo run -- --ci host: exit 0, 107 steps green.cargo test -p toyos-tgl-display: 19 pass.kernel::rmrr: 11 pass, including every kept range covered by its source RMRRs' union. They cover one endpoint, two endpoints, a sub-hierarchy, an unknown scope (unfollowable, kind 5 or malformed), the class rule, partial pages, overlapping RMRRs of two functions, duplicates of one, and the 2 MiB leaf split.coveredchecking one RMRR at a time (r5);Unknownscope that does not share (r4);cedde3c90). The watermark arithmetic they mutate is unchanged since.the_compositor_drives_the_virtio_gpu, exit 0. It is the one test whose claims cross VT-d (intel-iommu, which publishes no RMRR).amdvi_selftest(exit 0 at r1) runs onamd-iommuand covers only the changedOwnSpace::createcaller.table::put_4kare established by inspection only. No planned machine has a second segment. The T14's range is 2 MiB-aligned, so no planned machine runs it. The split that drives it is host-tested.T14 A/B result (at
bb1f335f7, before review r1's kernel changes)The A/B runs from measurement branch
display-stage1-ab, which is this branch merged with #1100's energy bench. That branch is not for landing.Evidence: https://github.com/ToyOSOrg/evidence/blob/58471e7d2c0e8a08c8a223d6778be0654e9725fc/r2/README.md
Two boots, both exit 0.
Boot B's lines:
04:00.0and i21900:1f.6behave as in A: the same hand-over, queues, link-up and interrupt lines, with only timings differing. usbd claims nothing in either boot, because its rows match QEMU's xHCI and the boot xHCI, and the T14 boots off its NVMe.display-stage1-abd0dc7c34a, imagea8f0d1ec…, exit 0, 228 s; evidence r4):iommu: rmrr0 is 00:02.0's alone, kept in its own domain, then keeps → moves.Risks still open (measured by the first T14 boot)
issues/the-t14s-igpu-faults-read-permission-after-translation-goes-off-and-on-under-its-scanout.md, about 1 in 27 cycles) means one boot does not rule it out.Integration tests
T14 only: this is the Tiger Lake display engine, and the AMD bench's display is AMD DCN.
The A/B is two boots, one with the driver and one without. The driver holds its claim for the boot, so A and B cannot share one. Both are
osbench_energyon the bench image, compared against pr-1100 r7's Linux rows.🤖 Generated with Claude Code