diff --git a/local/recipes/system/redbear-power/source/src/platform.rs b/local/recipes/system/redbear-power/source/src/platform.rs index 9596739994..01466f0966 100644 --- a/local/recipes/system/redbear-power/source/src/platform.rs +++ b/local/recipes/system/redbear-power/source/src/platform.rs @@ -2,12 +2,16 @@ //! //! Probes the host kernel once at startup and selects the correct //! path for each data source (MSR, ACPI PSS, /proc/stat, cpufreq -//! sysfs, hwmon temperatures). On Redox OS the `/scheme/sys/...` +//! sysfs, hwmon temperatures). On Red Bear OS the `/scheme/sys/...` //! paths are tried first; on Linux the equivalent `/dev/cpu/*/msr`, //! `/proc/stat`, and `/sys/devices/system/cpu/cpu*/cpufreq/` paths //! are used as fallbacks so the TUI shows live data on a developer //! host too. //! +//! Red Bear OS data sources are now real (not stubs): the kernel +//! serves hardware MSRs through `/scheme/sys/msr/` and per-CPU +//! scheduler statistics through `/scheme/sys/cpu/{n}/stat`. +//! //! Each probe emits exactly one `eprintln!` line at startup naming //! the data source and the failure mode. This matches cpu-x's //! `MSG_VERBOSE` pattern (core.cpp:380-410) and lets the user know diff --git a/local/recipes/system/redbear-power/source/src/sensor.rs b/local/recipes/system/redbear-power/source/src/sensor.rs index a40afe6487..2eabb54c72 100644 --- a/local/recipes/system/redbear-power/source/src/sensor.rs +++ b/local/recipes/system/redbear-power/source/src/sensor.rs @@ -11,16 +11,19 @@ //! - `curr*_input` — current in milli-Amps //! - `*_label` — human-readable label for the corresponding `_input` //! -//! On Redox, the `hwmon` scheme is not yet implemented, so when the sysfs -//! path is absent the module falls back to reading the CPU package -//! temperature via the `IA32_THERM_STATUS` MSR exposed through -//! `/scheme/sys/msr/`. +//! On Red Bear OS the thermal surface is provided by daemons: +//! - `/scheme/thermal/zones/` — thermal zones from `thermald` (ACPI + CPU die) +//! - `/scheme/coretemp/` — per-CPU die temperatures from `coretempd` +//! - `/scheme/sys/msr/` — direct MSR fallback for CPU package temperature +//! +//! The Redox sources are preferred over the Linux sysfs path when present. use std::fs; use std::path::{Path, PathBuf}; const SYS_HWMON: &str = "/sys/class/hwmon"; const REDOX_THERMAL: &str = "/scheme/thermal"; +const REDOX_CORETEMP: &str = "/scheme/coretemp"; #[derive(Default, Clone, Debug)] pub struct SensorReading { @@ -175,6 +178,37 @@ fn read_redox_thermal_zones() -> Vec { chips } +/// Enumerate Redox `/scheme/coretemp/` directories and return one +/// `HwmonChip`-like entry per CPU with a temperature reading. +fn read_redox_coretemp() -> Vec { + let root = Path::new(REDOX_CORETEMP); + let Ok(entries) = fs::read_dir(root) else { + return Vec::new(); + }; + let mut chips = Vec::new(); + for entry in entries.flatten() { + let name = match entry.file_name().into_string() { + Ok(n) => n, + Err(_) => continue, + }; + let temp_path = root.join(&name).join("temperature"); + let Some(temp_raw) = read_sysfs_i64(&temp_path) else { + continue; + }; + chips.push(HwmonChip { + name: "coretemp".to_string(), + path: root.join(&name), + readings: vec![SensorReading { + kind: SensorKind::Temp, + label: Some(format!("CPU {}", name)), + raw_value: temp_raw * 1000, + display_value: format_sensor(SensorKind::Temp, temp_raw * 1000), + }], + }); + } + chips +} + /// Read all `*_input` files in the chip directory, grouped by prefix. fn read_chip_readings(chip_dir: &Path) -> Vec { let entries = match fs::read_dir(chip_dir) { @@ -250,6 +284,12 @@ impl SensorInfo { return Self { chips }; } } + if Path::new(REDOX_CORETEMP).exists() { + let chips = read_redox_coretemp(); + if !chips.is_empty() { + return Self { chips }; + } + } let Ok(dirs) = fs::read_dir(SYS_HWMON) else { if let Some(temp_c) = read_first_cpu_temp_msr() { return Self {