Skip to content

[BUG] Base M5: CPU frequency never updates — voltage-states22-sram does not exist on base M5, so FrequencyReader.read() always returns early #3439

Description

@Abrar118

On a base M5, the CPU frequency values are static and never update. "Super cores" frequency is blank; "Efficiency cores" / "All cores" show stale values that never change.

Follow-up to #3325 (closed as "covered in #3414"). #3414 is an M5 Pro menu-bar color bug; its fix (68b7e5f) does not touch the frequency reader, so the base-M5 frequency bug is still present in v3.0.8.

Details

  • Device: MacBook Pro, base Apple M5 (4 Super + 6 Efficiency, 2 clusters)
  • macOS: 26.5.2 (25F84)
  • Stats: 3.0.8 (825)

Root cause (probable)

SystemKit.getFrequencies(for:) (Kit/plugins/SystemKit.swift:510-528) reads the performance-cluster DVFS table from voltage-states22-sram on all M5-gen chips:

if isM5GenOrNewer {
    if let data = props.value(forKey: "voltage-states1-sram")  { eFreq = ... }
    if let data = props.value(forKey: "voltage-states22-sram") { pFreq = ... }
    if let data = props.value(forKey: "voltage-states5-sram")  { sFreq = ... }
}

voltage-states22-sram does not exist on the base M5 — that key appears to be M5 Pro/Max only. So pFreq == [].

FrequencyReader.read() (Modules/CPU/readers.swift:357) then bails out on every tick:

guard !self.isReading,
      (!self.eCoreFreqs.isEmpty || !self.sCoreFreqs.isEmpty) && !self.pCoreFreqs.isEmpty,
      ...
else { return }

!self.pCoreFreqs.isEmpty is falseno frequency is ever emitted at all (not E, not S, not the aggregate). This matches the symptom exactly: values frozen rather than wrong.

Introduced by 5432cc2 (#3250), which broadened isM5ProMaxOrNewerisM5GenOrNewer and thereby routed the base M5 through the Pro/Max voltage-states22-sram path.

Secondary (currently masked by the guard): since sCoreCount != 0 on M5-gen, readers.swift:375-385 looks for an MCPU IOReport channel for p-cores. The base M5 has no M cluster, so that would stay empty regardless.


System dumps (base M5)

ioreg -p IODeviceTree -n pmgr -rno voltage-states22-sram:

"voltage-states0"   "voltage-states1"  "voltage-states1-sram"  "voltage-states2"
"voltage-states5"   "voltage-states5-sram"  "voltage-states8"
"voltage-states9"   "voltage-states9-sram"  "voltage-states11"

ioreg -p IODeviceTree -n cpus -r -d 1no m-core-count:

"cpu-cluster-count" = <02000000>   // 2
"p-core-count"      = <04000000>   // 4
"e-core-count"      = <06000000>   // 6

ioreg -p IOService -n AppleARMPE -r -l | grep cluster-type — normal E/P, not the M/P seen on M5 Pro in #3414:

"cluster-type" = <"E">   x6
"cluster-type" = <"P">   x4

sysctl:

hw.nperflevels: 2
hw.perflevel0.name: Super       hw.perflevel0.physicalcpu: 4
hw.perflevel1.name: Efficiency  hw.perflevel1.physicalcpu: 6

Suggested fix

On M5-gen, treat the M (performance) cluster as optional:

  1. In getFrequencies, fall back when voltage-states22-sram is absent — base M5 is E + S only, so leave pFreq empty rather than assuming it exists.
  2. Relax the read() guard so it doesn't require pCoreFreqs to be non-empty; gate each cluster independently.

Happy to test a build — I have the affected hardware.

Preview

Image

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    Status
    Todo

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions