Asahi Linux makes progress: webcams, microphones and Thunderbolt work on M3

Written by Jason Miller

On all chip machines in the series M3 they work now webcam, integrated microphones, USB 3.0 and Thunderbolt. The project writes it Asahi Linux in its latest report on work in progress, which brings together months of reverse engineering on three distinct fronts: the completion of M3 support, the energy saving of application cores and the recovery of the hypervisor on M4 machines. Support lives for now in the downstream branches of the project, not in the official Linux kernel.

The project is now said to be close to completion release with working M3 support for those using downstream code, with more details expected in the coming weeks; bringing the same work into the official kernel will take much longer, because each piece must be proposed and discussed upstream. Also in the works is direct scan-out for the GPU, which however is not yet in a condition to be delivered to users.

The changes introduced by Apple on the M3 series are largely incremental. The webcam’s image signal processor remained nearly identical, save for a skipped initialization message on the solo M3 Max: chaos_princess has added support for that case to the Linux driver, and with that the webcam works on all M3 devices that have one. The integrated microphones required similar work: the M3 series introduces a high-frequency decimator that requires a new set of coefficients and a much more substantial initialization message.

The block ATCPHYwhich negotiates USB3, DisplayPort and Thunderbolt connections on USB Type-C ports, required a new sequence of calibration values ​​during the initialization phase, a consequence of the transition to the production node TSMC N3. The most substantial change concerns the USB port controller. From the M1 through to the base M3 Apple used a custom-built Texas Instruments controller, the CD3217 (or ACE2), connected to the I2C bus; starting from M3 Pro and M3 Max has passed to ACE3speaking on the SPMI bus. Reverse engineering of mildsunrise and chaos_princess showed that ACE3 has basically the same register set as its predecessor, just wrapped in an SPMI interface instead of routed via I2C.

Core power saving and the PSCI constraint

The most basic way to put an ARM core to rest is education WFIwhich stops execution until an interrupt arrives, but leaves the core powered and with its state intact. Apple cores offer a deep variant of the same instruction, which turns off much more at the cost of losing state: Asahi’s cpuidle driver configures WFI in that mode, saves the core state, and then enters the wait loop. That driver can’t end up in the official kernel, because the arm64 code maintainers dictate that all upstream hardware handle core power through PSCIthe standard interface with which the operating system calls functions implemented by the system firmware.

PSCI expects those calls to travel on precise channels, and the kernel supports two of them: the SMC and HVC instructions, both intended to yield execution to a higher exception level. Linux runs in EL2 and expects to find the firmware in EL3which does not exist on Apple cores. The way out goes through m1n1the project’s bootloader, which loads U-Boot on real installations precisely to exploit its UEFI implementation: Sven modified m1n1 to reserve a memory region and leave a PSCI implementation inside, reachable from the kernel through the Runtime Services UEFI rather than with a jump to a higher exception level. The reading is that the specification published by Arm defines the API without tying it to a specific channel, and cites SMC and HVC only as examples. The patches that enable the mechanism are already on the mailing list as RFC.

On M4 WFI causes the core to lose state

The ARM specification expects a WFI-looped core to retain all of its state, but on Apple Silicon that is not the default behavior. From the M1 to M3 series, retention is configured core by core using low-level control bits, the so-called chicken bits. With the series M4 Apple sets them in mBoot and then locks the registers that govern them: m1n1 has marginally less work to do, but the behavior of the cores is no longer finely adjustable. The result is that on M4 calling WFI causes the core to lose state e it crashes whatever was running on it.

The issue surfaced during porting work on M4, and Yureka added a kernel command line parameter that makes idle loop behavior configurable, down to simple idle looping. The change avoids the crash in the early initialization phases, before the cpuidle driver has been loaded; when the driver takes over, it saves the state that would be lost and only then emits the WFI. The relevant patches are already in linux-next.

SPTM and the return of the hypervisor on M4

On the security front, Apple has moved memory management out of the kernel. The Page Protection Layerintroduced years ago in XNU, hardware-isolated page table management from the rest of the kernel, and it worked well until attackers found a way to break in and gain full access to the system. From there the Secure Page Table Monitorwhich takes PPL and places it inside the Guarded Execution Frameworka set of exception levels parallel to the standard ARM64 ones, with its own page table permission system, SPRR.

At startup, iBoot or mBoot checks whether the configured payload is an XNU image: in that case they first load SPTM into GL2, which sets up the page tables and reserves control of memory management. XNU starts later and communicates with you through a further IPC protocol; if it is unable to contact SPTM it panics before even completing initialization. So long as SPTM is mandatory for XNU from M4 onwardsthe m1n1 hypervisor on those machines was useless: loading XNU without SPTM crashed the system, and presenting m1n1 to mBoot as an XNU binary crashed m1n1, unable to manage the memory as it needs it.

Sven taught the hypervisor to emulate GXF and SPRRbased on the reverse engineering done at the beginning of the project. m1n1 can thus load Apple’s SPTM blob exactly the way XNU expects it, fix the XNU binary enough, load it and then observe the MMIO accesses of both as already happened from M1 to M3. Tracking on these machines is slower, but not to the point of being unusable, and with this the path to porting Linux to new hardware remains open.

Of the three lines of work, only one has already touched the kernel tree: the parameter on idle behavior is in linux-next, while the patches for the PSCI channel on Runtime Services UEFI remain an RFC on the mailing list. Everything else lives in the project branches, where work on M4 and M5 continues.

Jason Miller

I'm Jason Miller, and I've been passionate about technology and storytelling for over a decade. As a lead writer at Herald Editorials, I strive to bring clarity and creativity to complex tech topics. When I'm not writing, you'll find me exploring the latest gadgets or hiking in the great outdoors.