112 Commits
Author SHA1 Message Date
Acelogic 940eeb95ba docs: run the gadget-NCM link with Q1N1_UDP_RETRIES 2026-10-25 00:18:35 -04:00
Acelogic 78e648cc60 tools: let the control guard journal recovered write losses
On q1n1's gadget-NCM link one lost datagram in a memory write surfaces
as a transport read timeout; with Q1N1_UDP_RETRIES the q1n1 Link then
resynchronises (filler, drain, NOP round trip) and repeats the write.
The guard froze the session on that first inner timeout, so the
recovery could never run under the launcher (next3g).

Inside link.writemem on a datagram transport whose Link recovers
losses, and with no native call unresolved, a transport timeout is now
journaled (transport_loss, transport_loss_recovered) instead of
freezing. A write that still fails freezes the session as before; P_
requests, reads and everything else are unchanged.

replay-a16-control-guard.py adds four datagram-loss cases (recovered,
retries off, lost on every attempt, resync NOP lost); the recovered
case fails against the previous guard.
2026-10-25 00:18:35 -04:00
Acelogic 83b600d98e cycle: bind installed-fresh boots to the gadget-NCM stage too
next3c refused at the loader (exit 2): the native Image4 path binds the resident q1n1 stage to its ELF (probes/stagebind.py), and the launch named only q1n1's build/uefi, while the A16 ran the gadget-NCM stage that tools/a16-link-rearm.py arms after a reset without a replug (q1n1 build/uefi-gadget-ncm, Q1N1_GADGET_NCM). SNAP_STAGE_BUILDS now also lists that build when it exists; each stage still binds only to its own ELF.
2026-10-24 22:55:38 -04:00
Acelogic dbd816aa6a cycle: pin the early-done AuxKC for --edp-backlight runs with --gpu-coherent or --present-early-done
early-done-20261025 (9aff1d3e), linked from 822226c with KEXT_PROFILE=desktop-early-done I2C_PROFILE=desktop-fnkeys: the coherent backlight build (swap brightness, head rule, IOMFB trace, CS samplers) plus ADRENO_PRESENT_EARLY_DONE.
2026-10-24 21:59:45 -04:00
Acelogic 822226cfed repo: merge the 60 fps present batch (perf-60)
Busy desktop windows ran at ~50 copies/s because WindowServer, holding at most two swaps, got one refresh per frame while the kext completed each swap a tick after its copy, and the kext's per-IB cache maintenance (3.4 ms over ~98 MiB) sat on WindowServer's path. The GPU is not the limit: 94% of the time at 1700 MHz, ~7% busy. ADRENO_PRESENT_EARLY_DONE (--present-early-done, adaptive mode 2) completes a layer-0 swap at its scanout copy after a late frame; the desktop-early-done profile adds it to the coherent backlight build so --gpu-coherent can drop the maintenance. Replay: busy 49.8 -> 56.3 copies/s, 57.9 with coherent.
2026-10-24 21:59:20 -04:00
Acelogic b2f1fa031f tools: replay next2c's sporadic frames with coherent maintenance
The quiet desktop's sporadic heavy frames (next2c: 3 IBs a second,
57.9 copies/s) with b12v23's coherent maintenance: the kext time per
IB falls from 13 ms to 6.5-8.5 ms (the preparation stays), and the
model then delivers every refresh (59.5 copies/s) in every mode, so
the adaptive mode never engages there.
2026-10-24 21:56:03 -04:00
Acelogic 00cecdf061 tools: summarize a run's present pacing windows
tools/summarize-present-pacing.py reduces a console's AdrenoDisplay
perf windows to busy and quiet groups: copies per second, the copy
interval buckets, ready / missed / true-miss ticks, per-IB GPU,
submission, cache and preparation time, the copy, tick lateness and
q, the perf done line's early completions and arrival histograms,
and with --report the GPU's time per clock (DVFSREP1). Its host test
runs it on a synthetic console.
2026-10-24 21:54:41 -04:00
Acelogic 63d237b6bb tests: cover early swap completion and its cycle flags
tools/test-adreno-early-done.c unit-tests AdrenoDisplayEarlyDone.h
(modes, arrival bins, late frames and what is not one, adaptive
engagement, renewal and expiry, windows, the perf done line at its
caps). tools/test-present-early-done.py runs it, requires it to fail
on eight mutants of the header, checks that the kext touches the
feature only under ADRENO_PRESENT_EARLY_DONE, that desktop-early-done
differs from desktop-backlight only in AdrenoDisplay.o, the cycle
flags, refusals and AuxKC choice, and the replay (earlier outputs
unchanged by the define, no failure or cost failure in
early-done.json).
2026-10-24 21:54:41 -04:00
Acelogic 6605245ba5 cycle: add --present-early-done and its AuxKC slot
--present-early-done MODE (needs --edp-backlight and its chain) adds
the guest boot-arg adreno_present_early_done=MODE and
--present-early-hold-ms (mode 2 only) adreno_present_early_hold_ms;
both are refused with --present-hold on. --edp-backlight with
--present-early-done or --gpu-coherent now takes the collection
pinned as INPUT_AUXKC_DESKTOP_EARLY_DONE (SnapAdreno
desktop-early-done: the coherent desktop kext with the backlight
service and early completion) instead of the nocoherent
INPUT_AUXKC_DESKTOP_BACKLIGHT, and is refused until that collection
is linked and pinned. Without the new flags the boot arguments, the
AuxKC and the monitor are unchanged: the next3 argument list still
builds monitor 97be2b80 (459,904 bytes).
2026-10-24 21:54:41 -04:00
Acelogic 1fffff784d tools: replay early swap completion in the pacing world
With -DADRENO_PRESENT_EARLY_DONE=1 the presentation replay mirrors
AdrenoDisplayEarlyDone.h step for step (the completion at the copy
in l_present, arrivals in l_swap_begin, the tick state in l_tick) and
runs early_done_scenarios (early-done.json): the 2026-10-24 busy
desktop (org2's 117 windows: 49.8 copies/s with a SLOT WindowServer
of 5-9 ms frames, 20% of them 14-30 ms), the same with b12v23's
coherent maintenance, a FREE WindowServer, a quiet cursor desktop and
next2c's sporadic heavy frames, each with the mode off, always and
adaptive, under the deployed switches (relatch, urgent polling,
EP1/EP2, no EP3 assist).

Every earlier output (beam, damage, latency, pacing, pipeline,
presentation, presentsync, relatch, vsync .json) is byte for byte the
define-off build's, and the define-off build's equal the previous
tree's. Busy SLOT: 49.8 -> 56.3 copies/s (coherent 51.8 -> 57.9),
input latency mean +7 ms; quiet: unchanged in adaptive mode, +14 ms
always; sporadic: 56.5 -> 58.1 adaptive, 59.4 always.
2026-10-24 21:54:41 -04:00
Acelogic c77dd9974e repo: move SnapAdreno to early swap completion
SnapAdreno a2d43d0: ADRENO_PRESENT_EARLY_DONE in AdrenoDisplay
(src/AdrenoDisplayEarlyDone.h, boot-arg adreno_present_early_done)
and the desktop-early-done profile (desktop-backlight plus the
define). Define off, the desktop-next profile still builds the
deployed swap-path-20261024 AdrenoX2 section for section.
2026-10-24 21:54:41 -04:00
Acelogic 06333e0680 cycle: pin the swap-path AuxKC for --edp-backlight runs
swap-path-20261024 (9e916a41), built by the backlight-path work from 8f9eeb5 / SnapAdreno e1cf072 / SnapI2CHID f0b7984 with KEXT_PROFILE=desktop-next I2C_PROFILE=desktop-fnkeys: AdrenoBacklight takes the brightness from the swap record instead of a brightness-nits write WindowServer's sandbox refuses. next2-20261024 (cc07dfd3) stays as the rollback.
2026-10-24 20:22:21 -04:00
Acelogic 5e7b890849 repo: merge the icon pixel probe and the CS table fix set (icon-pixels-next)
The on-device CoreImage pixel test (tools/run-icon-pixels.py, compare-icon-pixels.py, SnapMetal harness/icon-pixels) and SnapMetal 8fe64cb's ADRENO_CS_TABLES=1 build (SP_CS_CONFIG NTEX equal to NSAMP, as Mesa programs every stage), trusted and deployable as metal-stage-iconfix-20261024 (AdrenoMetal ba3a3fd6, CDHash 11d5ff9a; the icon-pixels tool 25f07e86). next1/next1b showed partial System Settings icons with no plug-in or kext refusal.
2026-10-24 20:21:48 -04:00
Acelogic 6e634e62e5 repo: merge the swap brightness path (backlight-path)
next2c showed WindowServer bind the panel to AdrenoBacklight but its sandbox refuse every brightness-nits write (iokit-set-properties is allowed only on AppleARMBacklight). The brightness now comes from the swap record IOMobileFramebufferSwapSetBrightness fills (+0x354 present, +0x35e nits as a double): AdrenoDisplay overrides swap_submit and hands the value to AdrenoBacklight as source swap, at most one monitor call per 33 ms. force-brightness-control is no longer published (SnapAdreno e1cf072).
2026-10-24 20:21:48 -04:00
Acelogic 8f9eeb5ba2 docs: say --edp-backlight brightness arrives in the swaps
RUNNING.md no longer says BrightnessControl writes brightness-nits to
the service (WindowServer's sandbox refuses that): the service lets
WindowServer bind the panel's framebuffer, CoreBrightness's nits
arrive in the swaps as on a DCP Mac, and the kext logs "SET <level>
from swap".
2026-10-24 20:19:43 -04:00
Acelogic 774f13dfc8 tests: check the swap brightness path of AdrenoBacklight
test-edp-backlight.py follows the kext's move from BrightnessControl
writes to the swap record:
- Wiring: AdrenoDisplay overrides swap_submit, reads the record at the
  expected offsets through edp_bl_double_to_q16, returns the family's
  answer and hands the value on as source "swap" from
  swap_begin_gated, all under ADRENO_BACKLIGHT; the service no longer
  publishes force-brightness-control.
- UserspaceContract (26A428 host with ipsw, else SKIP): besides the
  BrightnessControl names the IOMFB bind needs, IOMobileFramebuffer
  exports IOMobileFramebufferSwapSetBrightness, QuartzCore has
  IOMFBDisplay::swap_brightness, and the framework's setter and swap
  submit still use the kext's record offsets and size.
- Kext (--kext-reference): both backlight profiles override
  swap_submit, the default kext does not.
check-iomfb-vtable.py's help names the new override.
2026-10-24 20:19:43 -04:00
Acelogic 463c4036c5 repo: point SnapAdreno at the swap brightness path
SnapAdreno e1cf072 (branch backlight-path, not pushed): AdrenoDisplay
overrides swap_submit and hands the brightness each swap carries to
AdrenoBacklight as source "swap"; AdrenoBacklight no longer publishes
force-brightness-control, whose writes WindowServer's sandbox refused
in run next2c. The default kext is section for section unchanged.
2026-10-24 20:19:28 -04:00
Acelogic 3c995cc8d8 compat: convert a swap record's brightness to 16.16 nits
The A16 kext now takes the panel brightness from the swap record
IOMobileFramebufferSwapSetBrightness fills: an IEEE double in nits,
unaligned, straight from a client. edp_bl_double_to_q16 turns its bits
into 16.16 nits in integer arithmetic, rounded to nearest and capped,
refuses NaN, infinities and negative values (which name no
brightness), and maps zero and subnormals to 0 (the darkest request).

The model test checks it bit-exact against the host's double
arithmetic for chosen values and for every exponent with a spread of
mantissas, and four mutations (NaN or negative accepted, truncation,
no cap) must fail it. Header-only and unused by the monitor: the
SNAP_EDP_BACKLIGHT monitors built with run next1b's flags, with and
without the define, are byte-identical to org next's.
2026-10-24 20:19:14 -04:00
Acelogic b66e1d0e2b cycle: trust and deploy the iconfix plug-in set
The next installed run boots with the settings-icons executable
378ff525 installed and replaces it from single-user mode with SnapMetal
icon-pixels-next built the same way (lenient, ADRENO_PIPELINE,
ADRENO_SETTINGS_ICONS, runtime v7) plus ADRENO_CS_TABLES=1: AdrenoMetal
ba3a3fd6, CDHash 11d5ff9a. CoreImage's compute kernels then get
SP_CS_CONFIG NTEX = NSAMP = their T#/S# count and NUAV = their UAV
count; a process started with ADRENO_CS_TABLES=0 keeps the
settings-icons counts, so icon-pixels can compare both in one boot.

installed_fresh: the trust additions become the iconfix set's (the
settings-icons set's 47 rows plus 11d5ff9a and the icon-pixels probe
25f07e86: 501a90b6, payload 7857aabc); the settings-icons set stays as
ADDITIONS_SETTINGSICONS for rollback, and every earlier CDHash stays
trusted, so --restore (back to 378ff525) still boots. deploy-guest-
plugin: the executable's base is the settings-icons 378ff525 and its
payload the 27,627-byte AdrenoMetal-378ff525.bsdiff; the runtime and
CodeResources are already the installed ones and are skipped.

The probe's row: the guest's TXM service reports the code-signing
monitor disabled and answers only static trust-cache lookups
(compat/txm.h), so code outside the cache is left to in-kernel AMFI,
whose ad-hoc handling has never been observed in the guest; every
executable of ours that ran there (metal-triangle-probe,
metal-clear-probe) had its CDHash in the trust additions. The row costs
nothing and follows that pattern.

The set, build/current-assets/metal-stage-iconfix-20261024, is a local
(ignored) input: AdrenoMetal, AdrenoMetal-378ff525.bsdiff,
trust-additions.json, trustcache.payload and SET.json.

Evidence: the prepare-time trust check (configure_guest, then
trust_cache_spec(ADDITIONS).load(FIRMWARE) against TRUST_PAYLOAD and
TRUST_SHA) passes for the installed, -input and -input-touchpad
profiles, for this set and the settings-icons rollback; the payload
holds 11d5ff9a, 25f07e86, c76a4677 and runtime v7's ab4ccbd4;
tools/test-deploy-guest-plugin.py PASS 21 checks (install, again,
restore, refuse) over the console stand-in with 3% loss.
2026-10-24 20:03:11 -04:00
Acelogic bad2b992dc repo: merge the ADRENO_CS_TABLES candidate (icon-pixels-fix)
The --cs-tables expectations of test-adreno-settings-ci-encoding.py,
and SnapMetal at icon-pixels-next (8fe64cb): ADRENO_CS_TABLES (51d07a1,
ef0c80a) merged with the icon-pixels probe (713dab1, 263dd47).
2026-10-24 19:55:32 -04:00
Acelogic 88fac86a26 repo: merge the icon-pixels pixel test (icon-pixels)
icon-pixels (SnapMetal harness/icon-pixels*.m) and the tools that
build it, run it in the guest over the console and compare its lines
with this Mac's reference; docs/RUNNING.md describes the check.
2026-10-24 19:55:22 -04:00
Acelogic 7e8bf82b3a cycle: pin the next2 AuxKC for --edp-backlight runs
next2-20261024 (cc07dfd3), built from fbed1ca with KEXT_PROFILE=desktop-next I2C_PROFILE=desktop-fnkeys: AdrenoX2 d88a2620 now publishes force-brightness-control and maps nits proportionally (SnapAdreno 9cc1e92). SnapI2CHID's code sections are identical to next-20261024's. next-20261024 (57965a84) stays as the rollback.
2026-10-24 19:52:33 -04:00
Acelogic fbed1cad82 repo: merge the brightness path (backlight-path)
BrightnessControl writes brightness-nits only to a backlight service that carries force-brightness-control; AdrenoBacklight now publishes it (SnapAdreno 9cc1e92), so CoreBrightness's slider and keys reach the panel instead of dimming in software (next1b: RequestsNits 0). The floor drops from 10% to 2% (level 41 of 2047) and nits map proportionally onto levels.
2026-10-24 19:50:41 -04:00
Acelogic 07839e46f7 tools: run icon-pixels a second time with --ab-env
The synth-ab step runs the synthetic cases again with one VAR=VALUE in
the tool's environment, into synth-ab.txt, compared with the same
reference. With a plug-in that has a per-process switch installed (the
ADRENO_CS_TABLES candidate honours ADRENO_CS_TABLES=0), one boot then
measures both encodings on the GPU. test-icon-pixels.py runs it over
the console stand-in (55 checks pass).
2026-10-24 19:48:11 -04:00
Acelogic 15336488b9 docs: describe how --edp-backlight brightness reaches the panel
RUNNING.md now gives the 2% floor, how CoreBrightness's nits reach
AdrenoBacklight (WindowServer's BrightnessControl, enabled by the
service's force-brightness-control) and the two boot-args that move
the nits-to-level curve. It no longer names the pinned collection's
folder, which the next pin will change.
2026-10-24 19:47:13 -04:00
Acelogic 1421e52e29 repo: point SnapMetal at the per-process ADRENO_CS_TABLES opt-out
SnapMetal ef0c80a lets a process started with ADRENO_CS_TABLES=0 keep the
old compute counts, so icon-pixels can compare both encodings in one
boot with the candidate installed.
2026-10-24 19:47:06 -04:00
Acelogic e273ff6475 tests: check AdrenoBacklight's BrightnessControl path
test-edp-backlight.py gains three checks for the path SnapAdreno's
AdrenoBacklight.h describes:
- Wiring: the service publishes force-brightness-control as data with
  a nonzero first byte, backlight-control and IODisplayParameters,
  takes brightness-nits, and maps every request through the one curve
  with the configured minimum.
- UserspaceContract: on a 26A428 host (the guest's userspace) with
  ipsw, the dyld cache's BrightnessControl and IOMobileFramebuffer
  still carry the names the path relies on; SKIP elsewhere.
- Kext (--kext-reference): desktop-next builds too, both backlight
  profiles carry force-brightness-control, the default kext does not.
2026-10-24 19:47:06 -04:00
Acelogic 8351bc0674 repo: point SnapAdreno at its backlight-path branch
SnapAdreno 9cc1e92 (branch backlight-path, not pushed): AdrenoBacklight
maps nits proportionally onto levels with the compat helpers of the
previous commit, publishes force-brightness-control so WindowServer's
BrightnessControl writes brightness-nits to it, and publishes its
DPCD700 diagnostic as 64 bits. The default kext is section for section
the base commit's.
2026-10-24 19:46:45 -04:00
Acelogic b8e2e042f2 compat: lower the eDP backlight floor and map nits linearly
The monitor's floor was 10% of full scale (level 205 of 2047) and the
kext's helpers mapped [min_nits, max_nits] affinely onto [floor, max].
If the panel's DPCD level is linear in luminance, the darkest macOS
request was ~50 nits: ten times the 5-nit minimum the A16's panel
table gives Windows (BrightnessRangeLevel0 5000..500000 millinits,
BrightnessRangeLowOffset 10000).

EDP_BL_FLOOR_PERMILLE is now 20: level 41, ~10 nits under the linear
model (the table's low offset), very dark but never off if the TCON
applied a 2.2 power law instead. Nothing has measured the panel's
curve; the header says so and the hardware run must check the bottom
of the slider. The helpers now model luminance proportional to level
(edp_bl_nits_to_level/edp_bl_level_to_nits with the top level at
max_nits) and edp_bl_min_nits_q16 raises the darkest request to the
floor's luminance; the slider helpers take 16.16 bounds.

The SNAP_EDP_BACKLIGHT=1 monitor built with run next1b's flags differs
from next1b's qualified one in one byte (same size, 200 bytes of code
budget left); without the define the monitor is byte-identical. The
model test checks the floor and the curve, and four new mutations (no
floor change back to 10%, an affine curve, a top short of max, a
minimum below the floor) must fail it.

The SnapAdreno kext with ADRENO_BACKLIGHT uses the new signatures; it
builds once the submodule pointer moves (next commit). The default
kext does not include this header.
2026-10-24 19:46:34 -04:00
Acelogic bc5846fb4e repo: point SnapMetal at icon-pixels without --bundle
SnapMetal 263dd47 removes icon-pixels' second-plug-in mode, which
cannot work in the guest (Metal's device list loads the installed
plug-in first).
2026-10-24 19:42:46 -04:00
Acelogic b5da7dd434 tests: expect Mesa's CS state counts with --cs-tables
test-adreno-settings-ci-encoding.py pins the single and two-input
packages' T#/sampler units, TSIZE and SP_CS_CONFIG NTEX/NSAMP/NUAV.
--cs-tables expects a plug-in built with ADRENO_CS_TABLES: NTEX 2 /
NSAMP 2 / NUAV 1 for the single shape, 3 / 3 / 1 and a zero third
sampler entry for the two-input one; units and TSIZE are unchanged.

ADRENO_CS_TABLES build: PASS 352 checks (production and CS-sampler
validators). Unchanged build with --cs-tables --expect-before: fails
27 checks, as it must. Unchanged build without the flag: PASS 351.
2026-10-24 19:40:25 -04:00
Acelogic 9e64bbb125 repo: point SnapMetal at the ADRENO_CS_TABLES candidate
SnapMetal 51d07a1 adds ADRENO_CS_TABLES (default off): CoreImage's
compute kernels get SP_CS_CONFIG NTEX = NSAMP = their T#/S# count and
NUAV = their UAV count, as Mesa programs every stage. A candidate for
the partial Settings icons, to be decided by the icon-pixels check.
2026-10-24 19:40:25 -04:00
Acelogic b3e916a6bb docs: describe the icon-pixels check in RUNNING.md
How to run icon-pixels in the guest, what it compares, where the
references come from and which offline test covers it.
2026-10-24 19:31:58 -04:00
Acelogic d43df34e40 tools: add the icon-pixels guest pixel test
The A16 showed partial System Settings icons while neither the plug-in
nor the kext refused anything, so the GPU ran the icon kernels and some
produced wrong or empty pixels; the encoding tests cannot see that.

build-icon-pixels.py builds and ad-hoc signs SnapMetal's icon-pixels
for arm64e and records its size, SHA-256 and CDHash (and the trust
row the guest would need if its AMFI refused an ad-hoc executable).

run-icon-pixels.py runs it in the guest from the root console shell:
pushes it with deploy-guest-plugin.py's checked chunk transfer, checks
that it executes, runs the synthetic CoreImage cases as root and the
system icons both in-process (root) and through NSWorkspace as the
console user (launchctl asuser + sudo -u), fetches every output file
three CRC-checked lines per command, optionally renames the icon
caches aside and restarts iconservicesd, iconservicesagent, the Dock
and System Settings (multi-user), collects the plug-in's per-process
and unified-log diagnostics, and compares. Offline it refuses the
steps that would act on this Mac's own processes.

compare-icon-pixels.py compares the guest's lines with this Mac's
within a tolerance and names the first matching explanation per case:
unwritten or partial output, readback or repeat differences, black or
transparent output, swapped red/blue, an extra or missing sRGB decode,
the missing or foreign input of a multi-input kernel (with its Metal
texture index), a broken blend band, otherwise the channels and tiles
that are off; for icons empty, black, partial, wrong colour or shape.
--census-only compares the dispatched kernels and formats of an
intercepted plug-in run.

icon-pixels-reference-synth.txt is this Mac's synthetic reference
(generated inputs only; M3 Max, 26A428, capabilities answered like the
deployed plug-in 378ff525). The icons reference summarises Apple's
icons and is not committed.

test-icon-pixels.py: the reference reproduces exactly on this Mac;
the plug-in device (commits intercepted) dispatches the same kernels
and formats with 8 CS sampler units and drops the multi-input ones
without; 20 injected faults are each diagnosed and a within-tolerance
perturbation passes; the whole console procedure runs over the
console stand-in with loss and noise and fetches lines identical to a
direct run.
2026-10-24 19:31:58 -04:00
Acelogic 2986fc3ba9 repo: point SnapMetal at the icon-pixels probe
SnapMetal 713dab1 adds harness/icon-pixels*.m, the on-device pixel
probe of the CoreImage kernels behind the System Settings icons.
2026-10-24 19:31:58 -04:00
Acelogic ee727e83c3 cycle: add --watchdog and --session for two-hour desktop runs
--watchdog SECONDS sets the run's watchdog from 1800 (the default, unchanged) to 7200 s; above 1800 the boot
preflight requires the A16 on AC. --session (with --console) leaves the guest trigger out of SNAP_EARLY_STOP, so the
kext never requests its first-present stop and a desktop session lasts until the watchdog, the thermal guard or
tools/request-stop.py. --early-stop-delay is checked against the run's watchdog. tools/test-session-watchdog.py
covers the default, the bounds, the delay check and the session's triggers.
2026-10-24 19:22:49 -04:00
Acelogic 80da17a462 repo: merge the kernel view pool reclaim (view-reclaim)
A 256-table kernel view pool with lazy reclaim of copies that no longer hold a protected leaf, behind --view-reclaim (SNAP_VIEW_RECLAIM); CODE_AT moves down 16 KiB so the monitor keeps 15 KiB of headroom with --edp-backlight; the pool's count, high-water mark and reclaims are reported as VIEWRCL1. next1 stopped at 1104 s when the 128-table pool was full (exit 7, ROZONE RETYPE refused).
2026-10-24 19:05:41 -04:00
Acelogic 49ccf6bf9b tests: cover kernel view reclaim and the 256-table pool
tools/test-view-reclaim.c drives a monitor-shaped kernel tree (one root,
one level 1, four level 2, 512 level 3) the way the retypes do: prepare,
detach, commit, refresh, with kernel_views_quiesce's steps as the
quiesce. After every step, independently of the library: each CPU's
walk of all 16,384 leaves gives the canonical descriptor or, for
selector2/4, its translation under that CPU's PPERM; no reachable page
holds an unpublished store; copies are distinct and never sources; no
store reaches a retired page before the TLBI after its unlinking.
Scenarios: fill to 256, a full pool and a one-slot-short path refuse
with no change, release and reclaim (TXM import, the level-2 ancestor),
reuse of the retired pages before any allocation, reclaim down to the
root, the restart of a two-frame change, read failure, nothing to
retire, unconfigured views and a failed quiesce. A quiesce without its
TLBI and a dropped protected table are caught (harness self-checks).

tools/test-view-reclaim.py runs it, nine weakened sprr-view.c copies
(each must fail: all do), test-kernel-pperm-variants.c with and without
the define, the wiring (default off, guarded uses, cycle, report place
and decoder) and, with --build, the monitor identities.
test-kernel-pperm-variants.c gains reclaim steps under the define:
positions move under the reuse snapshot, publication rows and variant
columns while both machines keep agreeing.

Tests that hard-coded the 128-table shape now derive it from
SPRR_VIEW_TABLES / USER_PUBLISH_MAX (test-tpro-view.c's RAM,
test-user-prepare-fused.c, test-user-fused-compare.c,
test-user-publish.c, test-user-tree-memo.c); define-off they check
exactly what they did.

Results on this tree (host, ASan/UBSan):
  python3 tools/test-view-reclaim.py              PASS (model 20,578
      checks; 9/9 mutants caught; consumers; wiring)
  python3 tools/test-view-reclaim.py --build --qualification
      .../installed-fresh-desktop-20261024-next1/qualification.json
                                                  PASS (absent == =0 ==
      86bb02ea9e03...; =1 459,904 bytes, 15,232 headroom)
  the 26 C suites linking sprr-view.c, with and without
      -DSNAP_VIEW_RECLAIM=1                      PASS (define-off check
      counts equal the base commit's)
Hardware: not run.
2026-10-24 18:53:55 -04:00
Acelogic 7b729890ef cycle: add --view-reclaim
installed-fresh --view-reclaim appends -DSNAP_VIEW_RECLAIM=1 after every
other monitor define. It is a monitor define only: no AuxKC, boot-arg
or loader change. docs/RUNNING.md describes it.
tools/test-edp-backlight.py's "appended last" check now lets this newer
define follow its own.

With next1's qualification flags plus the define the monitor is 459,904
bytes, 15,232 under the 464 KiB reservation; without it the monitor is
byte-identical to next1's (458,552 bytes, 16,584 under).
Hardware: not run.
2026-10-24 18:53:24 -04:00
Acelogic 411e17fd1b probes: report the kernel view pool as VIEWRCL1
With SNAP_VIEW_RECLAIM the report carries, behind "VIEWRCL1" and a word
of value bytes << 32, the kernel views' count, its high-water mark, the
reclaims that retired tables and how many, the refusals that found
nothing to retire, and the capacity. The record sits at a fixed place
just below the IB async slot (used or not); every chained record is
asserted to end before it. tools/perf_counters.py decode_view_reclaim
reads it (refusing a record whose counts disagree), decode_report adds
it as view_reclaim, the speed/installed-fresh summary keeps it, and
probes/run.py prints one line. 88 bytes of monitor code.
Hardware: not run.

probes/run.py's reservation note now gives the reclaim's exact cost with
this record: 1,352 bytes.
2026-10-24 18:53:18 -04:00
Acelogic b69884f31a probes: lower CODE_AT for a 464 KiB monitor reservation
With --edp-backlight the next1 monitor left 200 bytes of the 448 KiB
reservation, and SNAP_VIEW_RECLAIM adds about 1.3 KiB.

OUT_AT cannot rise: the report ends exactly at heap+0x480000, where the
stopped-probe scratch begins (tools/probe-a16-cpus.py, code at 0x480000,
output at 0x490000), and tools/secondary-runtime.py collect runs that
probe after the monitor returns and before probes/run.py reads the
report, so a higher report would lose its tail (the thermal and DVFS
records). CODE_AT moves down 16 KiB instead. Nothing in q1n1's heap
below CODE_AT is used during a run; the only other user of that range
is tools/qualify-txm-image4-native.py (heap+0x100000, 3 MiB), which
requires a fresh stage. q1n1 does not know these offsets, every tool
reads run.CODE_AT, and the monitor is position independent.

tools/test-monitor-reservation.py checks the new order (code, report,
stopped-probe scratch, SMP page, work locator), that the two stopped
probes use the scratch after the report, and the fresh-stage tool's
workspace. tools/test-reuse-match-mapped.py's budget follows.
Hardware: not run.
2026-10-24 18:53:06 -04:00
Acelogic e128ca1abe shadow: reclaim kernel view copies in a 256-table pool
installed-fresh-desktop-20261024-next1 stopped after 1,104 s with exit
7: a RETYPE to ROZONE was refused because sprr_views_prepare found the
kernel views at SPRR_VIEW_TABLES (128). Its context.bin shows that 114
of the 118 level-3 copies still held selector2 leaves (122 ROZONE
protects, 3 releases): each RO-zone frame lands in its own 2 MiB table,
so the live set itself reached the pool. In the 86 preserved runs of
6 minutes or more, releases stayed at 2 to 8.

SNAP_VIEW_RECLAIM (opt-in, default 0):

- SPRR_VIEW_TABLES becomes 256. struct sprr_views grows by 8,192 bytes
  and 65 of them precede pauth_bank, so PAUTH_BANK_CONTEXT moves under
  the define (still asserted). The publication rows, the row-empty
  checks (sprr_publish_row_empty) and USER_PUBLISH_MAX follow the
  capacity. Context +1.0 MiB, root_ext +1.5 MiB of the arena.
- sprr_views_reclaim retires every copied table no CPU needs: a level-3
  table without a valid selector2/4/9 leaf, an upper table none of
  whose entries leads to a needed copy, never the root. It reads every
  source before changing anything, compacts the metadata (kept tables
  in order, retired sets parked past count at SPRR_VIEW_RETIRED), then
  calls quiesce. kernel_views_quiesce drops the reuse snapshot and the
  publication rows, and shadow_tlb_sync syncs all six views (a retired
  table's parent entry names its canonical source again, an identical
  translation), publishes them and runs TLBI ALLE1IS. Only after that
  may add() reuse the six pages at that position; after a failed
  quiesce they stay unusable.

The trigger is lazy: kernel_views_prepare_change, used by the ROZONE
and TXM-default retypes, reclaims only when a prepare is refused with
fewer than three free slots, then prepares the whole change again,
because the reclaim also retires paths an earlier leaf of the change
prepared (not protected until the commit). prepare_path refuses a path
that does not fit before adding any of it. Nothing runs before the pool
is full: the refresh, PPERM and sync paths are unchanged.

Off, the monitor is byte-identical: next1's flags give 458,552 bytes,
sha256 86bb02ea9e03...; so does the build without SNAP_EDP_BACKLIGHT
and the define-free one. On, the code grows by about 1.3 KiB, which
needs the code reservation of the next commit. kernel_sync_view's
frame grows from 2,336 to 4,528 bytes (64 KiB EL2 stacks; worst
direct-call chain 13.2 KiB, unchanged).

The mirrored multipage_close in tools/test-multipage-fast.c and the
source check in tools/test-kernel-ops-perf-source.py follow the row
helper. Hardware: not run.
2026-10-24 18:52:53 -04:00
Acelogic 67013604d7 cycle: pin the next AuxKC for --edp-backlight runs
INPUT_AUXKC_DESKTOP_BACKLIGHT, the collection --edp-backlight selects
(the only route the next1 run's flags reach), becomes next-20261024:
KEXT_PROFILE=desktop-next I2C_PROFILE=desktop-fnkeys
tools/build-auxkc-desktop.sh at umbrella 78920c5, SnapAdreno b5bfcb4,
SnapI2CHID f0b7984 (sources.txt, no uncommitted changes).

  adreno-input.kc      57965a84916986eed68988b174d699eba06050207945af742c6dd57f616cbd82
  adreno-input.raw.kc  444b0cd1c732071075ca19668a16ca800cd0b752f6c84d072739251eb7e99f40
  AdrenoX2             3202fd6f (desktop-next)
  SnapI2CHID           4a81f74e (desktop-fnkeys)

The brightness branch named this pin for a PROFILE=desktop-backlight
AdrenoX2, which adds the service to desktop (coherent maintenance
skipping, for --gpu-coherent). The run has no --gpu-coherent, so the
pin holds desktop-next instead: desktop-nocoherent plus the service,
with the head rule, the IOMFB trace and the CS sampler opt-in. The
SnapI2CHID in it carries the Fn-key layer, so --input-fnkeys needs no
pin of its own. Both kexts are section-identical (12 of 12) to
separate builds of those profiles from the same tree.

Runs without --edp-backlight keep the latch collection
org-desktop-nocoherent-20261023 (ccf0c8f4, 353756d), which is also
the rollback. docs/RUNNING.md says which profile the pin holds.
tools/test-edp-backlight.py test_cycle now takes its pinned branch
and passes.
2026-10-24 04:14:34 -04:00
Acelogic 78920c59b6 docs: describe --input-fnkeys with the input flags
The fn-keys branch added installed-fresh --input-fnkeys and the
desktop-fnkeys SnapI2CHID profile but left docs/RUNNING.md without
them. List the flag in the Input row and say what it adds, which
SnapI2CHID build reads it, what its bits do and which test covers it.
2026-10-24 04:10:05 -04:00
Acelogic b78c12e1f2 repo: point the submodules at their next branches
SnapAdreno f54b9ec..b5bfcb4 (next):
  adreno-kext: add the desktop-next build profile
  (desktop-nocoherent plus ADRENO_BACKLIGHT in AdrenoDisplay.o, the
  kext of an --edp-backlight run without --gpu-coherent)
SnapMetal 936d51b..7bc40ef (next): the --no-ff merge of
  feature/settings-icons onto migrate-private 40a1864 (same tree as
  936d51b)
SnapI2CHID 816aad8..f0b7984 (next): the merge of feature/fn-keys
  (abaa501 Fn-key layer, 7c0a059 desktop-fnkeys profile). fn-keys made
  no pointer commit, so this is the first one that carries it; the
  umbrella's tests and build-auxkc-desktop.sh I2C_PROFILE need it.

Default builds stay section-identical to migrate-private
(tools/macho-sections.py, ZERO_AR_DATE=1): AdrenoX2 default 12 of 12,
SnapI2CHID default and desktop 12 of 12 each.
2026-10-24 03:58:07 -04:00
Acelogic fb02fa99c2 tests: check --edp-backlight and --input-fnkeys reach the boot-args
Both options already add their guest boot-args; the tests only called
boot_addition with hand-built namespaces. Parse real command lines
with cycle.py's parser and check the addition:

- test-edp-backlight.py test_cycle: no adreno_backlight=1 without the
  flag, adreno_backlight=1 with --edp-backlight (and no mode word),
  and both words, in order, with --edp-backlight-mode;
- test-input-fnkeys.py: --input-fnkeys 0x3, 3, 0x13 and 0b111 each
  give exactly one snap_i2c_fnkeys=<decimal value>, none without it.

For the next1 run's arguments (org2's plus --single-user,
--edp-backlight, --input-fnkeys 0x3, --adreno-cs-samplers) the
addition carries adreno_cs_samplers=1, adreno_backlight=1 and
snap_i2c_fnkeys=3.
2026-10-24 03:49:44 -04:00
Acelogic cf01e689d7 cycle: add --adreno-cs-samplers for the CS sampler opt-in
installed-fresh --adreno-cs-samplers appends the guest boot-arg
adreno_cs_samplers=1, the run-time half of SnapAdreno's
ADRENO_IB_CS_SAMPLERS: the IB validator admits CS sampler loads of up
to 8 units and AdrenoX2 publishes AdrenoIBComputeSamplers, so the
ADRENO_SETTINGS_ICONS plug-in encodes CoreImage's multi-input kernels.
An AdrenoX2 built without the define ignores the boot-arg. Without the
option the boot-argument addition is unchanged.

tools/test-adreno-cs-samplers.py: the default addition is unchanged,
the flag adds the boot-arg once (also beside --edp-backlight,
--input-fnkeys and --single-user), cycle.py's parser reaches the
namespace, AdrenoX2 reads exactly this name under the define, and the
desktop, desktop-nocoherent, desktop-backlight and desktop-next
profiles build AdrenoX2 and adreno-ib-command with it. A misspelt
boot-arg in installed_fresh.py fails it. docs/RUNNING.md lists the
flag and drops "no option yet".
2026-10-24 03:48:50 -04:00
Acelogic a254f01fc9 repo: merge the Settings pane icons (settings-icons)
Merge feature/settings-icons (b9c12cb..22aad4b). docs/RUNNING.md and
tools/cycle_lib/installed_fresh.py merge without conflict: the
settings-icons trust set (ADDITIONS/TRUST_PAYLOAD, mirror-slab kept as
ADDITIONS_MIRRORSLAB for rollback) sits beside the brightness and
fn-keys options.

gpu/adreno-kext/kext: SnapAdreno next f54b9ec, the merge of all three
SnapAdreno feature branches; gpu/adreno-kext/plugin: SnapMetal 936d51b
(feature/settings-icons).
2026-10-24 03:46:49 -04:00
Acelogic c993f8151f repo: merge the Fn-key layer tools (fn-keys) 2026-10-24 03:46:39 -04:00
Acelogic 5b35148492 repo: merge the eDP panel brightness (brightness)
Merge feature/brightness (7da9adf..f189da7) onto the display-modes
merge.

tools/check-iomfb-vtable.py: both branches added an AdrenoDisplay
define option (display-modes --display-define, applied to
AdrenoDisplay.cpp only; brightness --define, applied to every .cpp).
Keep one implementation: --display-define, with --define as an alias
of the same list, compiles AdrenoDisplay.cpp alone with the defines,
which is what both branches' help text promises and what
test-adreno-display-trace.py passes.

gpu/adreno-kext/kext: SnapAdreno next 53c0054, the merge of
feature/display-modes and feature/brightness.
2026-10-24 03:46:35 -04:00