Releases: Paradoxdov/memforge
v0.4.28 - honest turbo-lift logging
Honest turbo-lift logging + peaks block in JSON
Two diagnostic gaps fixed (no behaviour change):
-
Pre-Skylake CPUs (Sandy/Ivy/Haswell/Broadwell) use legacy PERF_CTL turbo lift instead of HWP. The fallback was already implemented in try_enable_max_perf() but never counted, so the per-run [PERF] summary read 'HWP write status: OK=0 FAIL=0' on those CPUs - looking like nothing happened even though turbo was being properly requested. Now bumps a separate counter and the summary prints the actual mechanism: HWP / legacy PERF_CTL with core count / AMD CPPC2 / none.
-
report.json gained a peaks block with temp_c, pkg_power_w, freq_mhz, bw_mbps and GB/s, bw_pct_of_theoretical, throttle_events_total, and per-mechanism turbo-lift core counts. Lets an automated analyzer verify the CPU was actually loaded without re-running the test.
v0.4.27 - About screen rewrite
About screen rewrite
The in-app About content was outdated and a bit embarrassing - it claimed 12 tests when there are 14 since L3 Cache Stress and Stride BW were added, knocked competitors by name in a petty way, cited academic papers meaningless to shop techs, and was missing key recent features (Marathon mode, auto-isolation, cold/warm delta, per-error environmental snapshot).
New structure:
- WHAT IT IS - one breath
- TESTS - all 14 in plain language
- RUN MODES - Quick / Full / MultiPass / Marathon
- SMART FEATURES - auto-isolation, SPD readout, MCA capture, per-error snapshot, cold/warm delta, turbo P-state push
- REPORT - what files end up on USB
No competitor name-calling. README still has the longer-form discussion if anyone wants comparisons.
v0.4.26 - histogram line wrap
Histogram line wrap - fix overflow on right edge
The address histogram row on the technical detail screen would extend past the right edge with 14+ entries (~120 chars), which doesn't fit any common screen size. Pre-v0.4.22 it was a short label, but the v0.4.22 rename to a more descriptive label made overflow worse.
Now: short label on its own row, data wraps across multiple rows based on actual screen width. Works identically on 800x600 / 1024x768 / 1920x1080.
Install
Copy MemForge2.efi to EFI/BOOT/loader.efi on a FAT32 USB along with quantai.ini at root.
v0.4.25 - auto-trigger isolation
Auto-trigger isolation - no [I] press needed
Pre-v0.4.25 user had to press [I] on the verdict screen to start isolation. That created an unnecessary decision point - most users wouldn't act on it and would be left with the imprecise REPLACE BOTH answer when the tool could have given a definitive one.
Now: after the test loop completes, if conditions for isolation are met (distributed errors + block-mapped Type 20 + 2..4 affected DIMMs), it runs automatically with no user input.
Flow:
- All 14 tests complete
- Splash: 'Found errors in N DIMMs - testing each separately, ~5 min'
- Isolation runs
- User sees the definitive REPLACE answer directly
No intermediate 'REPLACE BOTH but press [I] to find out which' step. The [I] key still works manually if the user navigates back to the simple verdict via [D] toggle.
Install
Copy MemForge2.efi to EFI/BOOT/loader.efi on a FAT32 USB along with quantai.ini at root.
v0.4.24 - auto-isolation feature
Auto-isolation - definitive REPLACE answer without pulling DIMMs
When the post-test verdict detects errors distributed across 2+ DIMMs in a block-mapped Type 20 layout (typical Intel consumer board with disjoint DIMM ranges), the user no longer needs to physically pull sticks one-by-one to identify which is bad.
Press [I] on the verdict screen and the program automatically:
- Picks the kernel that found the most errors (e.g. AVX2 Sustained for the Habr case)
- For each affected DIMM: frees the whole-RAM buffer, allocates 256 MB pinned to that DIMM's physical range, runs the kernel 3x, records errors, frees
- Re-allocates the whole-RAM buffer
- Shows a definitive verdict: per-DIMM error counts + TOCNO REPLACE X with HIGH confidence
Total time: ~5 min for a 2-DIMM isolation.
Why gated on block-mapped Type 20
On real cache-line interleave (overlapping Type 20 ranges) TestOnlyDimm cannot physically isolate because the iMC continues alternating cache lines between channels regardless of which logical DIMM range we allocate into. Detected via type20_has_overlapping_ranges() - if any DIMM ranges overlap, the [I] offer is suppressed and the user gets the existing manual-isolation instructions instead.
UI
- Verdict footer gains [I] when applicable
- Pressing [I] shows live progress panel (current DIMM, pass counter, elapsed time, errors so far)
- ESC during isolation aborts and returns to verdict
- After isolation: result screen with per-DIMM table and definitive REPLACE answer
- [D] takes user back to original verdict, [M] to menu, [ESC] reboots
Install
Copy MemForge2.efi to EFI/BOOT/loader.efi on a FAT32 USB along with quantai.ini at root.
v0.4.23 - UX cleanup
UX cleanup - drop debug column + cleaner footer
- Removed Smesch / Off column from core panel (per-core buffer offset, developer-debug only, freed up 9 chars for the activity bar)
- Cleared the countdown footer once the test actually starts; replaced with a useful in-test hint (Q to abort, logs are on USB)
No behaviour change.
v0.4.22 - UX clarity pass
UX clarity pass
Critical fix: ESC was reversed during pre-test countdown. Before, pressing ESC started the test instead of skipping it. Now Enter starts now, ESC skips this test, Q aborts the run.
Also: header time fields labelled (proshlo / ostalos instead of bare MM:SS), AVX2 status word changed from 'da/prop' to 'vkl/net', core panel column 'C0 %' replaced with 'Zagruzka / Load%', verdict text drops abbreviations and explains the tilde marker as approximate, focused-card layout (g_h<900) now shows test description next to its name.
v0.4.21 - smarter interleave verdict
Smarter interleave verdict
Pre-v0.4.21 verdict always said "REPLACE ONE of A2/B2" when errors were distributed across DIMMs - assuming the iMC is cache-line-interleaving the channel pair. But that's not always true. Field log from Gigabyte B760M showed SMBIOS Type 20 with disjoint ranges (A2 = 0..8GB, B2 = 8..16GB) - block mode, no interleave. With disjoint ranges, errors on both DIMMs really happened on physically separate sticks, so "REPLACE BOTH" is the honest verdict.
New logic
The verdict now classifies distributed-error patterns into three categories:
- Type 20 ranges overlap -> real cache-line interleave -> "REPLACE ONE of X/Y - physical isolation needed"
- Type 20 ranges disjoint, no interleave claim -> block mode -> "REPLACE BOTH X, Y" with HIGH confidence
- Type 20 conflict (disjoint ranges but interleave depth > 1) -> fall back to bit-6 channel polarity:
- bit-6 strongly skewed (>=85% on one side) -> "REPLACE ONE of X/Y" + show which bit-6 value
- bit-6 mixed -> "REPLACE: check X, Y - BIOS data is conflicting"
Honest limitations
PassMark forum (quoted in commit) acknowledges Intel/AMD don't document iMC channel hash functions, and even commercial MemTest86 Pro Edition requires months of per-platform reverse engineering. This heuristic-based approach won't match that ground truth but it's significantly better than the previous blanket "REPLACE ONE of pair" - especially on the common case (block-mapped BIOS) where it now correctly identifies BOTH bad sticks.
The bit-6 polarity hint is honest about its scope: works on standard Intel/AMD client DDR4/DDR5 dual-channel (where bit 6 is the channel selector); fails on Skylake-X with page-stride hash or some server configs. When uncertain, the verdict still tells the user "physical isolation needed".
Install
Copy MemForge2.efi to EFI/BOOT/loader.efi on a FAT32 USB along with quantai.ini at root.
v0.4.20 - critical fixes: kernel name lookup + summary aggregation
Two critical data-integrity fixes
Found by re-reading a Habr user's 16-hour marathon log on an Intel i3-12100 + 2x Netac DDR4-3200 that caught 24 real errors but had been misreported for months.
Bug 1 - Kernel name misattribution
g_err_records[i].test stores the kernel_id_t enum value, but display code used g_tests[r->test].name to look up a name - indexing the test catalogue array by an enum value rather than by array position. Enum values do NOT match array positions: KER_AVX2_SUSTAINED = 12 but position 12 in g_tests[] happens to be L3 Cache Stress. Result: every error from AVX2 Sustained was labelled "L3 Cache Stress" everywhere - verdict screen, [ERR] log lines, report.json. Total misattribution that broke field triage.
Fix: added tests_idx_for_kernel(k) / name_for_kernel(k) helpers that walk g_tests[] looking for the matching .k field. All 14 kernel IDs now resolve to the right name regardless of enum-vs-position mismatch.
Bug 2 - Per-test summary overwritten instead of accumulated
g_summary[i] = r assigned the LAST pass's result to each test's summary. In a 16-hour marathon (726 passes) with intermittent errors (1 per pass), the FINAL pass would be clean, so the summary table showed "errors: 0" for every test - hiding 24 cumulative errors. This also fed JSON: summary.total_errors: 0 and verdict: "PASS" even when error_records_total: 24. Automated analyzer would tell user "all good" while UI screen said "REPLACE" - direct contradiction.
Fix: accumulate errors/bytes/time across passes, keep status "sticky" (FAIL beats PASS beats SKIP). JSON now reflects real cumulative totals.
Bug 3 - "DIMM2" instead of "DDR4-B2" in verdict
The verdict text used didx+1 ("DIMM2"), an internal array index, when the user-facing SMBIOS Type 17 locator string ("DDR4-B2") was available in g_dimms[didx].locator. Replaced with the locator string.
Install
Copy MemForge2.efi to EFI/BOOT/loader.efi on a FAT32 USB along with quantai.ini at root.
v0.4.19 - human-readable verdict text
Human-readable verdict text
Field feedback (Habr): users were asking the developer what "?" "(chip ?)" and the "missing glyph" boxes on the verdict screen mean. The verdict is supposed to be for a shop technician or end-user, not a developer reading source. If text needs explanation, it's bad text.
Fixes
-
Bullet character
.was missing from the bundled bitmap font and rendered as a "missing glyph" box?before every list item on the FAIL screen. Replaced with?(which IS in the font). -
(chip ?)appeared when SPD did not expose chip width (typical on DDR4 x4 modules). Now shows explicit prose: "Stuck bit D[53] on DIMM (24 errors). SPD did not expose chip width - exact chip U-number unknown." Verdict now branches: if SPD width known, show exact chip designator (U1..U16); if not, say so plainly instead of leaving a dangling?. -
?in the "Affected DIMMs: A2 (8), B2 (11), ? (5)" line meant "errors at addresses not in any SMBIOS Type 20 region" - but nobody knew that. Now displayed asunmapped region. Section header changed from "?????????:" / "Affected DIMMs:" to "?????? ?? ???????:" / "Errors by DIMM:" so the intent is obvious without context. -
When DIMM is identifiable but chip is not, the technical detail line now shows DIMM info (
DIMM2 (exact chip unknown per SPD)) instead of dropping to a generic "stuck bit + XOR mask" line that hid the DIMM number.
No behavior changes; this is purely UI text + font glyph fix.
Install
Copy MemForge2.efi to EFI/BOOT/loader.efi on a FAT32 USB along with quantai.ini at root.