docs: redbear-power §26 — cpu-x cross-reference for Linux-host gaps

Adds comprehensive analysis answering the user's "no per-core info"
question. Documents:

§26.1 Why every per-CPU column is empty on Linux (root cause)
  - 6-column trace (Freq, PkgW, Temp, P-state, State, Flags) + Load%
  - Maps Redox scheme paths to Linux equivalents (where they exist)
  - Identifies that two paths already have Linux fallbacks (detect_cpus,
    read_cpu_id) and four do not

§26.2 cpu-x patterns reviewed
  - 6-row comparison table: missing-MSR / daemon / per-source UI /
    refresh logic / CLI flags / temperature fallback
  - Concludes: redbear-power's "n/a" placeholder is already better UX
    than cpu-x's empty cells; daemon broker pattern is NOT applicable;
    retry-cache and per-source logging ARE worth adopting

§26.3 Recommended Phase A/B/C (v1.3)
  - Phase A: new platform.rs with /dev/cpu/*/msr + /proc/stat +
    /sys/devices/system/cpu/cpu*/cpufreq/ fallbacks, ~80-120 LoC
  - Phase B: replace hardcoded P0..P5 fallback (acpi.rs:101-108) with
    real sysfs reads; generalize read_load to /proc/stat
  - Phase C: header per-source availability badge

§26.4 AMD-specific concerns (separate from Linux fallback)
  - msr.rs reader is Intel-only by design (file comment)
  - AMD Zen uses 0xC0010063/0xC0010064 for P-states and k10temp for
    temp, not Intel MSR 0x19c
  - Recommended: vendor detection branch + Linux hwmon fallback

§26.5 Conclusion
  - Screenshot is NOT a bug — TUI is working as designed
  - Three substantive gaps: no Linux fallbacks, no per-source
    startup logging, no header availability summary
  - All three addressable without violating zero-stub policy

Source: cpu-x v4.7 at /tmp/cpu-x-src/ (cloned in earlier session).
This commit is contained in:
2026-06-20 14:45:53 +03:00
parent 0ca2cdd1f4
commit 91b2011db3
@@ -1344,6 +1344,88 @@ ISO rebuild status: still blocked by pre-existing upstream nix-0.30.1 vs
Redox relibc incompatibility in uutils. v1.2 binary is staged and will
be packaged into the next successful ISO build once that issue is resolved.
## 26. Cross-Reference: cpu-x Patterns for Missing Data Sources
A user observed that running v1.2 on a Linux host produces a screenshot
where every per-CPU column shows `?`/`n/a`/`—` while the header shows
`MSR: not available (QEMU?)`, `cpufreqd=DOWN`, `thermald=DOWN`, `Cache: n/a`,
`Hybrid: non-hybrid`. This triggered a comprehensive root-cause analysis
+ cross-reference with cpu-x v4.7.
### 26.1 Why every per-CPU column is empty on Linux (root cause)
| Column | Source path (in code) | Linux equivalent | Status |
|--------|----------------------|------------------|--------|
| `Freq/MHz` | `/scheme/sys/msr/{cpu}/0x199` (msr.rs:46) | `/dev/cpu/{cpu}/msr` char dev, offset 0x199 | **No fallback exists** |
| `PkgW` | Same MSR 0x199 + in-memory `PState.power_mw` | sysfs `powercap` RAPL | **Two-stage failure**: PSS data is in memory (hardcoded fallback) but `current_idx` lookup fails (MSR 0x199) |
| `Temp°C` | `/scheme/sys/msr/{cpu}/0x19c` (msr.rs:46) | `/dev/cpu/{cpu}/msr` char dev, offset 0x19c; or `/sys/class/hwmon/hwmon*/temp*_input` | **No fallback exists**; Intel MSR layout assumed (AMD uses k10temp/Tdie) |
| `P-state` | Same MSR 0x199 | `/sys/devices/system/cpu/cpu*/cpufreq/scaling_cur_freq` | **No fallback exists**; reader is Intel-only by design |
| `State` | Derived from `current_idx` (app.rs:77-84) | — | **Cascades from P-state failure** |
| `Flags` | `/scheme/sys/msr/{cpu}/0x19c` (msr.rs:46) | hwmon or AMD-specific MSR | **No fallback exists**; defaults to `false`/empty when read fails |
| `Load %` | `/scheme/sys/cpu/{n}/stat` (acpi.rs:49) | `/proc/stat` per-CPU `cpuN` lines | **No fallback exists**; silently reads 0% (no `?` placeholder) |
Two paths **do** have Linux fallbacks:
- `acpi.rs:detect_cpus()` line 29 — probes `/scheme/sys/cpu` then `/dev/cpu``Cores: 24` populates
- `acpi.rs:read_cpu_id()` line 115-116 — probes `/scheme/sys/uname` then `/proc/cpuinfo` → Vendor/Model populate
The header line `MSR: not available (QEMU?)` is **misleading on bare metal**: the `?` is the production-common case (QEMU without MSR), but the same message appears on any non-Redox kernel.
### 26.2 cpu-x patterns reviewed (source: `/tmp/cpu-x-src/`)
| Pattern | cpu-x approach | redbear-power current | Recommendation |
|---------|---------------|-----------------------|----------------|
| Missing MSR | `Label.value == ""`, `?` in calculated strings | `Option<u64>::None`, `"n/a"` placeholder | **Keep `"n/a"`** — strictly better UX than empty cells |
| Daemon broker | `cpuxd` Unix socket + `DAEMON_UP` predicate (daemon.h:27) | None — Redox `scheme:sys/msr` already gates capability | **Do NOT adopt** — Redox kernel already enforces capability via scheme permissions |
| Per-source UI feedback | Per-field emptiness | `cpufreqd=up/DOWN`, `thermald=up/DOWN` header line | **Adopt pattern**: extend to MSR/PSS/Load availability |
| Refresh logic | `err_func()` retry cache (core.cpp:48-57) + per-source fallback chain | `Option`-based, no per-source logging | **Add startup logging**: one `eprintln!` per data source at startup, naming the failure mode |
| CLI disable flags | None — build-time `#if HAS_*` only | None | **Do NOT add** — runtime per-source probes are the right model |
| Temperature fallback | Real `hwmon` chain (`coretemp`/`k10temp``vcgencmd`) with `MSG_ERROR` on total failure | Hardcoded P0..P5 table (acpi.rs:101-108) | **Replace with real sysfs** — current fake data violates zero-stub policy |
### 26.3 Recommended Phase A/B/C (planned for v1.3)
**Phase A — Platform detection layer** (new `platform.rs`):
- At startup, probe `cfg!(target_os = "redox")` plus a runtime probe of `/scheme/sys/uname` accessibility.
- If non-Redox, expose three helper functions:
- `linux_msr_path(cpu, msr) → Option<PathBuf>``/dev/cpu/{cpu}/msr` + `pread` at given offset
- `linux_load_path() → Option<PathBuf>``/proc/stat`
- `linux_pss_path(cpu) → Option<PathBuf>``/sys/devices/system/cpu/cpu{cpu}/cpufreq/scaling_available_frequencies`
- Each helper emits one `eprintln!` at startup naming the data source and the failure mode.
- ~80-120 LoC.
**Phase B — Honest degradation**:
- Replace `acpi.rs:101-108` (hardcoded P0..P5 P-state table) with a real Linux sysfs reader.
- Generalize `acpi.rs:read_load` to also try `/proc/stat` on non-Redox (the delta logic in lines 56-74 already exists — just generalize the path).
- `cpufreq.rs:read_governor_state` falls back to `/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor` when `/scheme/cpufreq/state` is absent.
**Phase C — Header per-source availability badge**:
- Extend `render_header()` to surface the new per-source availability flags in a single status line. Mirrors cpu-x's "daemon up/down" idea but applied to all data sources.
**What NOT to adopt from cpu-x**:
- The daemon broker pattern (`cpuxd` + Unix socket + pkexec). Redox's `scheme:sys/msr` already enforces the capability gate; on Linux, `/dev/cpu/*/msr` does the same with `CAP_SYS_RAWIO`.
- Runtime CLI flags to disable individual sensors (`--no-msr`, etc.). cpu-x does this at build time; per-source availability probes are the right runtime analog.
- Empty-string rendering for missing cells. `"n/a"` in `VALUE_OFF` style is already better UX.
### 26.4 AMD-specific concerns (separate from Linux fallback)
The `msr.rs` reader is **Intel-only by design** (file-level comment: `//! Intel MSR constants and readers.`). AMD Zen uses different MSRs:
- `0xC0010063` — P-State Current Limit (analog of IA32_PERF_CTL 0x199)
- `0xC0010064` — P-State Control (analog)
- `0xC0010062``PStateCmd`
- Temperature: AMD uses `k10temp` driver + `Tdie` from SMU, not MSR 0x19c
A real AMD path would require either (a) a vendor detection branch in `cpuid.rs` (read `cpuid(0).ebx/ecx/edx` for vendor string), or (b) Linux hwmon fallback that auto-detects `k10temp`/`coretemp`. Recommended: ship Intel support as v1.2 today, AMD support as v1.4 with explicit `is_amd_cpu()` gate.
### 26.5 Conclusion
The screenshot at `/tmp/1.png` is **not a bug**. Every empty cell honestly reports an unavailable data source. The TUI is working as designed for a Redox-OS-only tool run on a Linux build host.
The three substantive gaps vs. cpu-x maturity are:
1. **No Linux fallback paths** for the three hardcoded `/scheme/sys/...` routes.
2. **No per-source logging** at startup to tell the user *why* a source is unavailable.
3. **No header-level summary** of all data-source availability (today only daemons are listed).
All three are addressable without violating the Red Bear zero-stub policy. Phase A/B/C above outline the implementation plan; deferred to v1.3.
---
## See Also