Skip to content

bhill00/corsair300ai-bazzite-widget

Repository files navigation

corsair300ai-bazzite-widget

Read performance mode, fan speeds, and temperatures from the Corsair AI Workstation 300 on Linux — directly from ACPI MMIO, no kernel module required.

Status: Working on Bazzite 40+ / Fedora Atomic · KDE Plasma 6 · AMD Strix Halo

Widget showing Quiet mode, fans off, CPU 37°C


What it does

  • Reports the current performance mode (Balanced / Max / Quiet) as set by Corsair iCUE on Windows or the hardware Fn keys
  • Reads live fan speeds in RPM for both chassis fans (correctly shows off when fans stop at idle)
  • Reads CPU and GPU temperatures and EC-reported power draw from the embedded controller
  • Provides a KDE Plasma 6 panel widget — mode name (color-coded) plus fan RPMs, no sudo at runtime

How it works

The Corsair AI Workstation 300 exposes a custom ACPI region named ERAX at physical address 0xFEC40400. It is declared as a SystemMemory operation region in the machine's DSDT and is read/written by the Corsair WMI ACPI driver (WMAA) to communicate mode changes and sensor data between firmware and iCUE on Windows.

On Linux, we map this region directly through /dev/mem using Python's mmap. Decompiling the DSDT with iasl revealed the field names and byte offsets for mode, fans, and temperatures — confirmed by cross-referencing against live readings at known mode states.

Note: /dev/mem access is gated by CONFIG_STRICT_DEVMEM. Bazzite and Fedora ship with strict devmem enabled, but the ERAX region at 0xFEC40400 falls outside the protected range and is readable without patching the kernel.

Repository contents

File Description
corsair-status-writer.py Daemon. Reads ERAX every second, writes /run/corsair-status (JSON). Run as root via systemd.
corsair-mode.py One-shot or live mode watcher. Reads FCMO at ERAX+0x31 directly. Requires sudo.
corsair-power.py Full live monitor: mode + fans + EC temps + EC power + RAPL cross-check, 1s samples. Requires sudo.
corsair-monitor.service Systemd unit for the daemon.
plasmoid/com.user.corsair-monitor/ KDE Plasma 6 widget source. Reads /run/corsair-status — no sudo at runtime.

Quick start

Prerequisites

  • Python 3 (stdlib only — no pip installs)
  • acpica-tools if you want to re-derive the offsets: sudo dnf install acpica-tools
  • Bazzite 40+ or Fedora Atomic with kernel 6.11+ (other distros likely work if /dev/mem is accessible)

1. Copy files

git clone https://github.com/bhill00/corsair300ai-bazzite-widget.git
cd corsair300ai-bazzite-widget
sudo cp corsair-status-writer.py /usr/local/bin/corsair-status-writer.py

2. Install the systemd service

sudo cp corsair-monitor.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now corsair-monitor.service
sudo systemctl status corsair-monitor.service

3. Verify

cat /run/corsair-status
# {"mode":"Balanced","mode_raw":0,"fan1":1250,"fan2":1260,"cput":45,"gput":38}

One-off tools (sudo required)

# Check the current performance mode
sudo python3 corsair-mode.py

# Watch for mode changes in real time
sudo python3 corsair-mode.py --watch

# Full live power and thermal table
sudo python3 corsair-power.py

KDE Plasma 6 widget

The widget reads /run/corsair-status via a Plasma5Support executable DataSource. No elevated privileges needed after the daemon is running.

mkdir -p ~/.local/share/plasma/plasmoids/
cp -r plasmoid/com.user.corsair-monitor ~/.local/share/plasma/plasmoids/

# Restart the shell to register the widget
plasmashell --replace &

Then: right-click panel → Add or Manage Widgets → search Corsair → drag to panel.

The compact view shows mode name (color-coded) and fan1/fan2 RPM. Click to expand for CPU temperature.


ERAX field reference

Physical base: 0xFEC40400. Offsets derived from DSDT decompile (iasl -d dsdt.dat).

To extract your own DSDT:

sudo cat /sys/firmware/acpi/tables/DSDT > dsdt.dat
iasl -d dsdt.dat
DSDT name Offset Size Description
FCMO 0x31 1 byte Current performance mode
FN1L 0x35 1 byte Fan 1 high byte
FN1H 0x36 1 byte Fan 1 low byte — RPM = `(FN1L<<8)
FN2L 0x37 1 byte Fan 2 high byte
FN2H 0x38 1 byte Fan 2 low byte — RPM = `(FN2L<<8)
CPUT 0x70 1 byte CPU temperature (°C)
GPUT 0x71 1 byte GPU temperature (°C, 0 when idle)
CPAD 0x72 1 byte EC-reported CPU power (W)
GPAD 0x73 1 byte EC-reported GPU power (W)

Performance mode reference

FCMO Mode Approx. TDP Fan behavior
0 Balanced ~85 W Stop-on-idle; spin up under load
1 Max ~120 W Always spinning
2 Quiet ~55 W Stop-on-idle; aggressive fan-stop threshold
3 Super TBD Present in DSDT; not yet characterized

Mode is set by iCUE on Windows and persists across reboots. These scripts are read-only — they never write to ERAX.


Notes

EC power double-counting: On AMD Strix Halo, the CPU complex and integrated GPU share a single die. The sum of CPAD + GPAD will often exceed actual package power. Cross-check with RAPL (/sys/class/powercap/amd_energy/ or the amd_energy kernel module).

Fan stop at idle: In Balanced and Quiet modes, both fans stop completely at idle. fan1 and fan2 reading 0 is normal, not a sensor error.

Portability: The ERAX base address and byte offsets are specific to the Corsair AI Workstation 300. They are unlikely to apply to other Corsair products without re-deriving from that machine's DSDT.


Background

The WMI GUID and ACPI method structure were identified by examining the DSDT. The ERAX field mappings were discovered by correlating DSDT field definitions with live memory readings taken while switching modes on Windows and observing which bytes changed.

There is no upstream Linux kernel driver for this hardware. This is a read-only userspace approach — it cannot change performance modes or modify firmware state.


Acknowledgements


GPL-2.0-or-later

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors