From 87f46249a3f95bbae050600c8039ad1f04eea73b Mon Sep 17 00:00:00 2001 From: Manupa Wickramasinghe <73810867+manupawickramasinghe@users.noreply.github.com> Date: Sun, 6 Sep 2026 01:27:01 +0530 Subject: [PATCH] =?UTF-8?q?=F0=9F=93=9D=20Document=20the=20CPU=20identific?= =?UTF-8?q?ation=20table=20and=20the=20rule=20that=20keeps=20it=20honest?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The codename table restored in #33 is a competitive feature and a fragile one, and neither fact was written down anywhere outside the code. README gains a differentiator paragraph: every entry is traceable to `intel-family.h` or libcpuid's `recog_amd.c`, and LibreHardwareMonitor's own table matches only families 06h and 0Fh, so Intel's 12h/13h parts are unreachable for it. The System Summary bullet now says what that panel actually shows, including the decoded SMBIOS memory type. app/README gains the two rules a contributor adding a CPU needs: cite the source or fall back to a generation, and match a single model rather than a high-nibble range — the range mistake is what put an EPYC codename on three Threadrippers. TODO records the ExtendedModel deviation at sysinfo.rs:49, which was found during review and deliberately left unfixed. It only existed in a PR description before this, which does not survive the merge. PROJECT_SUMMARY's sysinfo.rs line said ~427 lines; it is ~1300. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_018o7QQhLP2tNHG62b1d2q7R --- README.md | 16 +++++++++++++++- TODO.md | 10 ++++++++++ app/PROJECT_SUMMARY.md | 5 +++-- app/README.md | 20 ++++++++++++++++++++ 4 files changed, 48 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 36e35e94..922a9f2b 100644 --- a/README.md +++ b/README.md @@ -57,6 +57,17 @@ for every tool on that platform. WebSocket feed and Prometheus exporter are part of the normal build. Bind it to loopback for local scripting or to your LAN for a headless box. +**The CPU names itself, even when the part is new.** On x86 the System Summary +decodes the CPUID signature into a microarchitecture codename — *Raphael (Zen +4)*, *Arrow Lake*, *Granite Ridge (Zen 5)* — and every entry in that table is +traceable to a primary source: Intel's `arch/x86/include/asm/intel-family.h` and +libcpuid's `recog_amd.c`. That reaches parts the sensor library underneath +cannot name: LibreHardwareMonitor's own CPU table matches only families 06h and +0Fh, so Intel's newest families — Nova Lake (12h) and Diamond Rapids (13h) — +are structurally unreachable for it, and several family-6 parts sit past the end +of its model list. Where no source names a specific part, SensorView prints the +*generation* it can prove instead of inventing a codename. + **Honest blanks.** Where a value genuinely isn't available on a platform — CPUID on ARM, ACPI tables on Apple Silicon, S.M.A.R.T. behind Apple's storage controller — the field renders `—` rather than a plausible-looking guess. @@ -69,7 +80,10 @@ controller — the field renders `—` rather than a plausible-looking guess. - Dense, sortable **Sensors Status** table with current / min / max / average columns, per-type icons, draggable column widths and font zoom - Per-sensor **history graphs** in their own windows -- **System Summary** — CPU, motherboard, memory, GPU, drives, OS, ISA feature grid +- **System Summary** — CPU (CPUID signature and microarchitecture codename on + x86), motherboard, memory modules with their real SMBIOS type — LPDDR4 and + LPDDR5 read as themselves, not as a generic "DRAM" — GPU, drives, OS and + the ISA feature grid - **Hex Viewer** for raw firmware blobs (ACPI/SMBIOS on Windows and Linux) - Configurable poll interval, min/max reset, light/dark/grey themes diff --git a/TODO.md b/TODO.md index 7ecce74a..8ef56cd3 100644 --- a/TODO.md +++ b/TODO.md @@ -167,6 +167,16 @@ missed: process down. - **`settings.val_col_width`** is declared, persisted and never read. +- **`cpuid_info` applies ExtendedModel unconditionally** (`app/src/sysinfo.rs:49`). + Both the Intel SDM and the AMD APM say the ExtendedModel field is only to be + folded into the model number when the *base* family is 6h or Fh; the code does + `(ext_model << 4) | base_model` for every family. It is benign today, because + every family the codename table names has base family 6 or Fh, so the computed + model is the correct one in each case. It would start lying if a vendor + shipped a part on some other base family with a non-zero ExtendedModel. The + fix is a one-line guard; it was deliberately left out of the codename restore + so that a bug-fix PR stayed a restore. + ## Release - **`release.yml` has never completed successfully.** The last manual run failed diff --git a/app/PROJECT_SUMMARY.md b/app/PROJECT_SUMMARY.md index 6d4d3dd7..7d83e7f5 100644 --- a/app/PROJECT_SUMMARY.md +++ b/app/PROJECT_SUMMARY.md @@ -72,7 +72,8 @@ app/ │ ├── mod.rs # SensorSource trait, Diagnostics, default_source() │ ├── lhm_bridge.rs # spawn/parse the .NET sidecar (Windows) │ └── demo.rs # synthetic data — driverless fallback / CI / non-Windows - ├── sysinfo.rs # WMI static info, CPUID, is_elevated() (~427 lines) + ├── sysinfo.rs # per-platform static info, CPUID decode, SMBIOS memory + │ # types, is_elevated() (~1300 lines) ├── settings.rs # AppSettings (JSON in %APPDATA%\SensorView\settings.json) ├── logging.rs # CsvLogger ├── report.rs # write_report() → SensorView_Report_.txt @@ -190,7 +191,7 @@ stats, history, graph windows, and CSV columns. | --- | --- | --- | | **Main** | `main_window.rs` | Toolbar (Summary / Save Report / Sensors / Memory / About / Settings), left device tree with painted icons (`Computer, Central Processor(s), Motherboard, Memory, Video Adapter, Drives, Network`), right "Feature" detail pane fed by `sysinfo`, machine-name status bar | | **Sensors Status** | `sensors_window.rs` | HWiNFO flow-column dense sensor table: grouped bands, Current/Min/Max/Average columns, type-colored values, collapsible groups, right-click → Show Graph, CSV logging toggle, uptime clock, **diagnostic banners** | -| **System Summary** | `summary_window.rs` | CPU / motherboard / memory-module / GPU / drive panels from WMI + CPUID | +| **System Summary** | `summary_window.rs` | CPU / motherboard / memory-module / GPU / drive panels from WMI + CPUID. The CPU panel prints the raw CPUID signature *and* the decoded microarchitecture codename (`sysinfo::codename_for`); memory modules print the decoded SMBIOS type-17 code (`sysinfo::smbios_memory_type`), so LPDDR parts name themselves instead of collapsing to "DRAM" | | **Settings** | `settings_dialog.rs` | 5 tabs: *General / User Interface* (live), *Safety* (stub), *SMBus / I2C* (stub), *Driver Management* (live — shows real ring0 report + elevation), *License Management* (stub) | | **Graph** (n instances) | `graph_window.rs` | One deferred viewport per sensor identifier in `Shared.graphs`; hand-painted autoscaled polyline (no plotting dependency) | diff --git a/app/README.md b/app/README.md index ffff17bc..05a7a90c 100644 --- a/app/README.md +++ b/app/README.md @@ -49,6 +49,26 @@ The data model mirrors OpenHardwareMonitor's `Hardware/ISensor.cs` and `Hardware/IHardware.cs`, so the C# reference in the repository root and this port share a vocabulary. +## Adding a CPU codename + +`sysinfo.rs` decodes the CPUID signature into a microarchitecture name. Two +rules keep that table honest, and both are enforced by tests: + +1. **Cite the source in the comment.** Intel entries come from + `arch/x86/include/asm/intel-family.h`, AMD entries from libcpuid's + `recog_amd.c`. If neither names the part, do not invent a codename — extend + the family's catch-all arm, which reports only the generation. +2. **Match a single model unless a whole block really is one part.** A + `0x00..=0x0f` range written around one sourced model silently swallows its + neighbours. AMD families 17h, 19h and 1Ah each ship a Threadripper at model + `08h` right beside the server part at `01h`/`02h`; three such ranges had all + three Threadrippers reporting an EPYC codename. See the + `a_threadripper_is_not_an_epyc` test. + +`intel-family.h` writes its family numbers in **decimal**. Family 18 in that +header is 12h, not 18h — and 19h is AMD's Zen 3/Zen 4 family, so the mistake +reads as a real entry. + ## Checks These are exactly what CI runs: