diff --git a/local/docs/redbear-power-improvement-plan.md b/local/docs/redbear-power-improvement-plan.md index 451a974c18..70ed513728 100644 --- a/local/docs/redbear-power-improvement-plan.md +++ b/local/docs/redbear-power-improvement-plan.md @@ -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::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` → `/dev/cpu/{cpu}/msr` + `pread` at given offset + - `linux_load_path() → Option` → `/proc/stat` + - `linux_pss_path(cpu) → Option` → `/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