Status: LIVE AND VERIFIED — blade 115 runs 8C/16T (mask 0xFF, forced from
an abnormal 0xD7), 0 MCE, two clean per-core stress sweeps, boot unit enabled.
Full validation + ops log: docs/ops/blade115-validation-log.md (internal
record, not part of upstream PRs).
Scope: the aputune cores feature, kernel patch 28, and the fleet rollout
plan. All conclusions below come from the 2026-08-18 investigation of the
community 8-core unlock forks, plus the live validation on blade 115.
- The primitive, once: core-presence mask SMN
0x5A870(SMU space0x115A870). Stock0x77= 6C/12T (cores 3 and 7 masked),0xFF= 8C/16T. Only writable through the SMU queue-3 msg0x98, which does a raw SMN-window write of a hardcoded0xFFto the address in arg0 — all-or-nothing, no value argument, no address validation. - Semantics: a warm reboot re-enumerates the topology and preserves the mask; a cold boot (power removed) reverts it. Nothing is written to flash.
- Surface:
arieltune apu cores …CLI verbs + a TUI Core Map panel +aputune-cores.serviceboot unit + kernel patch 28 (8-core telemetry). - Safety invariants: no automatic reboots, ever · refuse unknown masks on
every safe path · post-write readback verification · advisory-only
verify(cloned-image lineage makes persisted verdicts untrustworthy). - Escape hatch (deliberate, explicit): boards with an abnormal live mask
(we met 0xD7 on blade 115) are refused by every safe path, but
cores apply --force-abnormal(CLI) and[F]in the Core Map panel (TUI, warning popup + confirm) force the same 0x98 write. No force path exists at boot (the unit never forces).
| Repo | Method | Verdict |
|---|---|---|
rw-r-r-0644/bc250-core-unlock |
Runtime: Python sends SMU queue-3 msg 0x98 → writes 0xFF to core-presence mask SMN 0x5A870. Refuses non-0x77 masks by default. |
Reference writeup. The primitive. |
GabriWar/bc250-core-cu-unlock |
Runtime script + systemd persistence + kernel telemetry patch 0001 + ACPI fix + P5.00_clv BIOS ROM with "Unlock CPU Cores" Setup toggle (default OFF). |
Best integrated package; adopted for Phase 1. Documents a real bootloop lesson. |
RescueMei/BC250-DXE-SMU-Core-Unlock (v1) |
DXE driver in BIOS performing the same q3 0x98 exploit pre-OS, auto warm-reset. |
Superseded by V2. |
RescueMei/BC250-DXEv2-BIOSMOD |
V2: core-unlock + ACPI-autoinject + cold-boot DXE drivers, xdelta against BC250_3.00_CHIPSETMENU.ROM, Setup toggle. |
Phase 2 option for P3 boards only. |
keyboardspecialist metrics patch |
Assumes a uniformly expanded 8-wide metrics table. | Wrong — contradicted by measurement. Rejected. |
rw-r-r-0644/bc250-smu-unlock |
q2 msg 0x23 exploit → full arbitrary SMN read/write + code exec; firmware patch metrics-8core.s; arbitrary core masks via set_core_mask.py. BIOS-3 offsets only. |
Research-only. The experimental roadmap (section 10). |
mikael2df-ux/bc250-40cu-unlock |
GPU CU-only content. | Not relevant to cores. |
- Core presence mask: SMN
0x5A870(SMU space0x115A870). Stock0x77= 6C/12T (cores 3 and 7 masked),0xFF= 8C/16T. - Only writable through the SMU: queue-3 msg
0x98does a raw SMN-window write of a hardcoded0xFFto the address passed as arg0 — all-or-nothing, no value argument, no address validation. - Warm reboot re-enumerates the topology and preserves the mask; a cold boot
(power removed) reverts to
0x77. Nothing is written to flash.
- Runtime unlock via q3
0x98in arieltune (not DXE, not BIOS) — same primitive, zero flashing, BIOS-version-agnostic (works on P3 and P5). arieltune already owns the exact machinery:ariel_hal::SmnAperture(PCI-config 0xB8/0xBC index/data) andariel_smu::ocq3::OcQ3(the queue-3 mailbox with the exact terminal status codes the DXE driver uses). This is a thin typed wrapper, not a port of shell script. - No automatic reboots, ever. GabriWar's earlier systemd version rebooted
after applying and bootlooped a real board (the reset didn't preserve the
mask;
/varstate wasn't durable early enough;systemctl rebootcan't run before D-Bus). Our unit applies the mask and stops; cores appear on the next operator-chosen reboot. - Refuse abnormal masks — with one explicit escape hatch.
cores apply/bootproceed only when the live mask reads0x77(or already0xFF). Anything else is refused, same rule as GabriWar, rw-r-r, and the DXE driver ("avoid lockout on abnormal masks"). Because blade 115 shipped with a genuine abnormal mask (0xD7 — stock 0x77 with bit 6 set), the refusal is bypassable only throughapply --force-abnormalor the TUI[F]confirmation popup: the same 0x98 write, the same 0xFF readback, an explicit warning, and never any auto-reboot.boot(the unit path) has no force. - No verdict cache / no hardware identity. The fleet clones OS images
across blades, so any persisted "this blade passed verification" state is
untrustworthy lineage. The only trusted checks are live reads of the current
hardware.
cores verifyis therefore an on-demand advisory tool, never a gate.cores applygates only on live facts: BC-250 silicon present, live mask ==0x77(or forced), post-write live mask ==0xFF. - Granularity = live OS offlining, not firmware masks. Firmware-level
arbitrary masks exist but require the q2
0x23exploit (SMU code-exec class, BIOS-3-validated offsets) — see the roadmap (section 10). Every practical core count (2C test runs, skip a defective core) is achieved by0xFFunlock +/sys/devices/system/cpu/cpuN/onlineofflining, which is proven, instant, and reversible. Offlining keeps the SMU-visible topology at the exact 8-core shape all community fixes were validated against. - Patch 28 (8-core telemetry) ships with the feature. After unlock,
pp_dpm_sclk's starred value, OD_SCLK,gpu_metrics.current_gfxclk, and hwmonfreq1_inputall read a residency counter (the firmware redistributed the 116-byte metrics table;GfxclkFrequency's 0x44 slot is nowC0Residency[6]). Patch 28 is the kernel-side fix, ported to use our battle-testedSMU_MSG_QueryGfxclk(section 6). filippor's userspace bind-overlay fix was reviewed and rejected for us: it only patches hwmon, needs a mount dance, and we ship the kernel. - GabriWar's
0002(rocm-vm-flush) is redundant here — our applied patch 14(e) already forcesflush_pasid_uses_kiq = falsefor gfx10.1.x (same line0002touches). Not staged; documented only. - ACPI: stock CST/PST tables stop at C00B (12 threads); after unlock,
threads 12–15 get zero C-states. The 8-core fix (
mendesrr/ bc250-acpi-fix-updated-8cSSDT-CST + SSDT-PST) extends to C00F and over-covers every mask 0–16 threads, so it is installed once when unlocking. Over-coverage is harmless; under-coverage is the only failure mode. - Governor safety verified: arieltune's fence-rate governor never reads the
metrics table for its control loop (fence counters +
temperature_gfxat offset 4, which keeps its 0x46 slot in the hybrid layout). Only TUI/status display reads were exposed. Patch 28 still fixes them; the governor is immune regardless. - Phase 2 (BIOS persistence) revised for fleet reality: the hive runs a
custom P5 BIOS (UMA memory options); the dev blade is P3. GabriWar's
BC250_P5clv_8core_v2.ROMis P5.00_clv-based — a same-lineage upgrade for the hive. Rollout: dev blade stays runtime/P3 for development; later crossgrade dev to stock custom P5, validate, then flash GabriWar's ROM on one hive blade (backup first, sha256 pin, CMOS-clear escape — the ROM defaults cores OFF so CMOS clear is always recovery), then the rest. A full-image flash path inarieltune bios(in-systemflashrom -p internalalready exists there) is a candidate but not required now.
cold boot (mask reverts)
LOCKED ─────────────────────────────────────────┐
0x77 mask, 12 threads │
│ apply/boot (q3 0x98, verified 0xFF) │
▼ │
PENDING-REBOOT ── warm reboot ──▶ UNLOCKED ──────┘
0xFF mask, 12 threads 0xFF mask, 16 threads
│
└─ any mask ∉ {0x77, 0xFF} ⇒ ABNORMAL (safe writes refuse;
only the explicit force hatch writes)
LOCKED: mask0x77, 12 visible threads.PENDING-REBOOT: mask0xFF, still 12 visible threads → "warm reboot needed".UNLOCKED: mask0xFF, 16 visible threads.ABNORMAL: any other mask → status explains; every safe mutating verb refuses. The force hatch (--force-abnormal/ TUI[F]) is the only writer and always asks first.
Hard gates on every mutating verb, all live reads:
ariel_apu_present()— PCI1002:13fepresent (it really is a BC-250).SmnApertureopen + short-transfer sanity.- Live mask read; proceed only from
0x77(or no-op on0xFF). - Post-write live mask verify ==
0xFF; on failure report SMU status and stop.
Soft output (advisory, never blocking):
- "MCE entries in dmesg: N" in
status. - Post-apply warning: the SoC power/thermal envelope changes with 2 extra cores; existing CPU OC/UV and GPU VDDC settings must be re-validated.
- "cold boot reverts this; the service re-applies the mask but cores appear only after the next reboot."
aputune cores status # mask, state, visible cores, MCE count
aputune cores apply [--reboot] [--force-abnormal] # unlock now; force bypasses the 0x77 gate
aputune cores boot # idempotent boot path for the unit (never forces)
aputune cores install # install /usr/local/bin + systemd unit, enable
aputune cores uninstall # remove unit + binary
aputune cores verify [seconds_per_core] # on-demand stress-ng --verify sweep (advisory)
aputune cores acpi {status|install|revert} # 8-core SSDT-CST/PST initcpio override
aputune cores offline {core|all} [..] # live OS-layer per-core toggle (instant)
aputune cores online {core|all} [..]
Root-gated by the existing ariel_hal::require_root() in run_cli. All verbs
print a final state line parseable as state=LOCKED|PENDING-REBOOT|UNLOCKED| ABNORMAL.
Details:
apply: sets/sys/kernel/reboot/modetowarmonly with--reboot, thensystemctl reboot. Default: no reboot, print the PENDING-REBOOT reminder.--force-abnormalskips the 0x77 gate (prints the starting mask + an EXPERIMENTAL warning first); the write and readback are identical to the safe path.boot: same safe write path, never reboots, exit 0 on already-unlocked and on refused (unknown mask) with a journal note — designed to be safe in a unit.verify: per-corestress-ng --cpu 1 --cpu-method all --verifysweep pinned to one thread per physical core, then an all-core sustained run, then a dmesg MCE grep. Prints bogo-ops, verify pass/fail, deviation-from-median table, and flags cores 3/7 as NEW. Writes a timestamped report to/var/lib/aputune/cores-verify-<date>.txtfor records — nothing reads it back for decisions (cloned-image lineage problem).acpi install: fetches/stages the two 8-core AML tables into/etc/initcpio/acpi_override/(backups kept), appends theacpi_overridehook to/etc/mkinitcpio.confif absent, rebuilds the initramfs.statuscountsC0xxprocessor objects vs live thread count;revertrestores the backup.offline/online: writes/sys/devices/system/cpu/cpuN/online(0/1), skips cpu0 (never offlinable), reports resulting thread count. Instant, no reboot.
The APU screen keeps its panel layout; the Core Map is its own panel between
the CPU panel and the GPU/CU row (the GPU/CU row shrank to make room), and it
is its own Tab focus target — focus order: system → CPU → Core Map → GPU →
CU. Only the focused panel lights and takes keys. The grid cells are rendered
by a fixed-width builder (padding computed from the styled parts), so rows can
never drift against the border; glyphs are ██/·· only, with reverse video
on the selected cell.
╭ Core Map ──────────────────────────────────────────────────────────────╮
│ UNLOCKED mask 0xFF · 8C/16T · 0 offline │
│ ╭─────────┬─────────┬─────────┬─────────┬─────────┬─────────┬─────────┬─────────╮
│ │ core 0 │ core 1 │ core 2 │ core 3 │ core 4 │ core 5 │ core 6 │ core 7 │
│ │ fw ██ │ fw ██ │ fw ██ │ fw ██ │ fw ██ │ fw ██ │ fw ██ │ fw ██ │
│ │ os ██ │ os ██ │ os ██ │ os ██ │ os ██ │ os ██ │ os ·· │ os ██ │
│ ╰─────────┴─────────┴─────────┴─────────┴─────────┴─────────┴─────────┴─────────╯
│ keys: [space] toggle · [[]/[]] select · [o]/[O] all off/on · [u] unlock · [F] force-unlock · [i] unit · [v] verify │
╰─────────────────────────────────────────────────────────────────────────╯
Key bindings and rules:
- The OS-layer toggles are draft-then-apply:
[space](toggle core),[o](all except 0 offline) and[O](all online) only edit the draft — nothing touches hardware until[a]apply.[esc]discards the draft,[r]resets (onlines every CPU immediately — the recovery route). The title shows· draft [a] apply [esc] canceland pending cells render yellow. [←]/[→](and[[]/[]]) move the selected cell;[u]performs the firmware unlock (same gates ascores apply); the fw row re-renders from a live mask read andPENDING-REBOOTshows with a reminder after success.[F]is the forced unlock for abnormal masks: a modal warning popup shows the current mask, states that the 0x98 write is all-or-nothing (0xFF), and lists warm-reboot/cold-revert semantics;[y]writes,[esc]cancels. The popup owns every key until answered, and the TUI still never reboots.- Offlined CPUs lose their
topology/subtree on this kernel, so the map's grouping falls back core_id -> online SMT sibling -> adjacent-pair index, andonline(all) writes every hotpluggable CPU dir with no topology dependency — offlined cores can always be recovered. [o]/[O]offline/online all cores (except 0) — the preset shapes (2C/4T etc.) are reached by offlining, the presets menu itself is deferred ([p]is the global patch popup).[v]runs the sweep in a worker (the keys line is replaced by the verdict while a report exists);[i]installs the boot unit ("unit not installed" badge clears).- The fw row shows the SMU mask bits (green
██= present), the os row shows live per-thread online state (██both,█·mixed,··none/masked). ABNORMALrenders red with· writes refusedon every safe key;[F]remains the only writer.
Unit aputune-cores.service (written by cores install):
[Unit]
Description=BC-250 8-core unlock (SMU msg 0x98)
Documentation=file:///usr/share/doc/aputune/arieltune-core.md
After=multi-user.target
ConditionPathExists=/sys/bus/pci/devices/0000:00:00.0/config
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/local/bin/arieltune apu cores boot
[Install]
WantedBy=multi-user.targetRules that MUST survive any edit:
- The unit never reboots (bootloop lesson, section 1.3).
bootis idempotent:0xFF→ exit 0 silently;0x77→ apply and exit 0; anything else → journal the refusal, exit 0 (not a service failure, no restart storm). The unit has no force path, so a board with an abnormal mask is only re-unlocked by an operator runningapply --force-abnormal.- Cold-boot UX: after a cold boot the mask is re-set within seconds; the cores
appear on the next reboot.
statusmakes this legible ("mask set, cores pending next reboot").
Source: GabriWar 0001-bc250-8core-telemetry.patch. Ported onto the
01–27-patched tree; new file
arieltune/crates/apu/patches/bc250-cachyos-7.0.9/28-bc250-8core-telemetry.patch.
Content (both files below):
smu11_driver_if_cyan_skillfish.h:SmuMetricsTable_hybrid_t(empirical 116-byte layout:CoreFrequency[8]@0x00,CorePower[7]@0x10,CoreTemperature[2]@0x2C, L3 @0x30/0x34,C0Residency[7]@0x38,GfxTemperature@0x46 — the 0x44 gfxclk slot is absorbed) +static_assert(sizeof == 116).cyan_skillfish_ppt.c:#include <linux/topology.h>+<linux/cpumask.h>- module param
cs_eight_core_map(bool, 0644) — force hybrid layout for debugging; auto-detect is the default. cyan_skillfish_core_count()— count physical cores via topology sibling groups (credited FilippoR).cyan_skillfish_get_smu_metrics_dataMETRICS_CURR_GFXCLKcase → direct SMU query with metrics-table fallback. Port divergence: usesSMU_MSG_QueryGfxclk(0x0F), not GabriWar'sGetGfxclkFrequency(msgid-0 map entry). Reason:QueryGfxclkis already mapped by our patch 02 and battle-tested live on our blades by patch 05's paths; msgid 0 is not proven on our firmware. Both serialize undermsg_ctl.lockidentically. This also means the port does not touch the message map.cyan_skillfish_get_gpu_metrics: gfxclk via the same SMU query (fallback to table), and whencs_eight_core_map || core_count >= 8, reinterpret the Current table as the hybrid layout forcurrent_coreclk[8],average_core_power[1..7],temperature_core[4..5](exactly GabriWar's field mapping); else the stock 6-wide loop.
Registration: SERIES entry 28, tell = Tell::ModParam("cs_eight_core_map"),
touches cyan_skillfish_ppt.c + smu11_driver_if_cyan_skillfish.h. Safe to
always apply: auto-detect keeps 6-core blades on the stock layout. SERIES.md
gets rows for 28 and a note that GabriWar 0002 is superseded by applied
14(e) and deliberately not staged.
Verification before commit: fresh pristine cachyos-7.0.9-1 + patch -p1 --forward --fuzz=0 for 01–28 in order must apply cleanly, and the result must
byte-match the port source for the touched files.
| File | Change |
|---|---|
arieltune-core.md |
this document |
crates/ariel-smu/src/ocq3.rs |
add q3::WRITE_SMN = 0x98; public typed unlock_cores() + unlock_cores_any() on OcQ3 (mask read/guard/write/verify); unit tests |
crates/apu/src/cores.rs |
new: state machine, status/apply/boot (safe + forced), presets, offlining, verify, acpi, unit install |
crates/apu/src/cli.rs |
Cmd::Cores { action: CoreCmd } + dispatch; apply gains --force-abnormal |
crates/apu/src/lib.rs |
mod cores; |
crates/apu/src/screen.rs |
Core Map panel + [F] force-confirm popup (section 4) |
crates/apu/src/cpu.rs |
read-only awareness: 8-core-safe core iteration (topology-derived, no hardcoded 6) |
crates/apu/src/telemetry.rs |
gfxclk_mhz(): prefer direct SMU query, fall back to pp_dpm_sclk with a <350 MHz sanity floor; use in TUI/status |
crates/apu/patches/bc250-cachyos-7.0.9/28-bc250-8core-telemetry.patch |
new (section 6) |
crates/apu/patches/bc250-cachyos-7.0.9/SERIES.md |
rows for 28 + 0002-redundancy note |
crates/apu/src/patches.rs |
SERIES entry 28 |
crates/apu/systemd/… |
reference copy of aputune-cores.service |
| tests | apu unit tests: state machine, unlock guard paths (safe + forced), offline parse; full cargo test -p apu green (37/37) |
Not implemented now (roadmap, section 10): arbitrary firmware masks, q2 0x23
exploit port, DXE/BIOS flashing tooling, full-image bios flash path.
On a P3 dev blade, after building and installing:
aputune cores status→LOCKED, mask 0x77, 12 threads.aputune cores verify→ clean sweep (or note defects).aputune cores apply→ PENDING-REBOOT;sudo reboot(warm).- After boot:
UNLOCKED, 16 threads;lscpu8C/16T. - TUI gfxclk matches
SMU_MSG_QueryGfxclkreading;gfx_temp_csane. patchestell for 28 (ModParamcs_eight_core_map) present; series fully patched.cores acpi install+ reboot → all 16 threads have C-states.- Cold power-cycle → boots 6C, unit re-applies mask, status shows PENDING-REBOOT; next reboot → 16 threads.
- Governor behaves normally (fence-driven) through all of this.
Status on blade 115 (2026-08-18): items 1–6 and 9 executed and passed (from an
abnormal 0xD7 start via the force hatch); item 7 (ACPI override) intentionally
not installed; item 8 confirmed in part — the mask survived even a
reboot/mode=cold reset on this board. See
docs/ops/blade115-validation-log.md.
- Dev blade (P3): Phase 1 runtime unlock only. No flashing.
- When proven: crossgrade dev blade to the stock custom P5 (UMA options) to match hive lineage; re-run the checklist.
- One hive blade: backup current ROM, flash
BC250_P5clv_8core_v2.ROM(sha256e7347f3a…), enableAdvanced → Advanced CPU Settings → Unlock CPU Cores, re-apply UMA settings (the ROM ships/clrcfgdefaults), verify. - Roll across hive one blade at a time. CMOS clear is always the recovery path (ROM defaults cores OFF). SPI programmer on hand before the first boot-block write.
What it is: writing any 8-bit mask (e.g. 0x03 = 2C, 0x7F = skip core 7)
to SMN 0x5A870 via the q2 msg 0x23 SMU exploit (bc250-smu-unlock:
ring-subqueue overflow → fake transfer-table pointer → arbitrary SMU write +
code exec), then a warm reboot. Proven only as a PoC on BIOS 3;
set_core_mask.py demonstrates arbitrary values but no production deployment
exists anywhere in the community.
What it would enable:
- Firmware-level core counts: the SMU, AGESA, and ACPI enumerate fewer cores for real — smaller power budget, fewer C-state slots needed, and no offlining housekeeping. The right tool if you want a permanent 2C low-power blade or to permanently exclude a defective core.
- Permanent exclusion of defective harvested silicon (not all BC-250s are golden) without the unlock+offline dance.
Why it's not shipped now:
- The exploit is memory-corruption class (SMU code exec) with BIOS-3-only validated offsets; the hive is P5. Unexplored blast radius.
- Telemetry cannot be trusted: the firmware's 116-byte metrics layout has
only been mapped for
0x77(6-wide) and0xFF(hybrid). For any other mask the layout is unknown — the firmware could key off "mask == stock", off bit 7, or off the enabled count; rw-r-r'smetrics-8core.sshows literal 6-wide store loops in firmware code, so it is not clearly data-driven. Patch 28's auto-detect (core_count >= 8) would mis-decode e.g. a 7-core system. - ACPI is static per boot; over-coverage with the 8-core tables should work for any mask ≤ 16 threads (unmatched processor objects are ignored), but this is inference, never verified on a non-standard mask.
What must happen before telemetry can be trusted for a given mask M:
- Port the q2
0x23unlock exploit to P5 firmware offsets and re-validate it (BIOS-3-only today). - Re-run GabriWar's differential core-offline probe with mask M live: sweep cores offline one at a time and record which metric fields move, to map the firmware's per-mask layout empirically.
- Extend patch 28's auto-detect from a boolean into a mask-keyed layout table
(and decide the
GetGfxclkFrequency-style fallback stays the gfxclk source, since direct SMU queries are layout-independent). - Verify ACPI over-coverage on mask M (C-states present for all enumerated threads).
- Only then consider an experimental
cores mask <0xNN>verb, hidden behind an explicit--experimentalflag with the exploit's risk stated.
Verdict: not proven anywhere; parked as research. Everything the fleet
needs today is covered by the proven 0xFF + OS-offline combination.