← Blog
KERNEL · 0.6.0

Apple Silicon HAL Batch 15: DART2 IOMMU, Thunderbolt 3/4, NVMe SSD, SPI Controller + PPC OHCI/HyperTransport/L1 Cache/DBDMA

June 22, 2026 · sigil-kernel · Sigil-Docs
kernel hal apple-silicon powerpc hardware 0.6.0

sigil-kernel's fifteenth HAL batch adds 8 more seams — Apple Silicon DART2 IOMMU (4 domains × 8 page tables, domain alloc, map/translate, TLB flush, fault reporting), Thunderbolt 3/4/USB4 (2 ports, PCIe+DP tunnels, 8-slot DMA TX ring, hotplug), Apple NVMe SSD (1.4 spec, CC.EN/CSTS.RDY, admin identify, 8-slot I/O SQ+CQ, 4K-LBA namespace), Apple MacBook SPI (kbd/trackpad CPOL/CPHA, 8-byte TX+RX FIFO, full-duplex state machine, 3-device CS). PowerPC side: USB OHCI 1.1 (HcRevision/Control/Cmd/ISR, 2-port root hub, SOF tick), G5 HyperTransport (2 links, 200–1000MHz, 8-slot cmd FIFO, CRC error inject), G3/G4/G5 L1 cache (D+I-cache, 8-way set-assoc 32 sets × 32B, dcbf/dcbz/icbi), PowerPC DBDMA (4 channels, 16-descriptor S/G ring, OUTPUT/INPUT/STOP/NOOP opcodes). All QEMU PASS. (sigil-kernel 692a1c2, 45aca72, dc146a0, 055ee55)

Apple Silicon and Pi HAL seams passing QEMU harness
Apple Silicon IOMMU + PPC DBDMA seams — QEMU harness green across all 8 new drivers

apple_iommu.sg — Apple Silicon DART2 IOMMU

Commit 692a1c2. The DART2 (Device Address Resolution Table, second generation) is Apple Silicon's IOMMU — it sits between peripheral DMA engines and physical RAM, enforcing that a GPU or Neural Engine can only access the memory it has been explicitly mapped into. Without an IOMMU, any DMA-capable peripheral is a potential vector for physical memory reads across process boundaries.

4 domains
diommu_domain_alloc() returns a domain ID (0–3). Each domain is an independent address space. DMA from a peripheral assigned to domain 0 cannot reach pages mapped only into domain 1.
Page table
8 page-table entries per domain (virt→phys mappings). diommu_map(domain, virt, phys) loads an entry into the domain's page table.
Translation
diommu_translate(domain, virt) walks the page table. Hit: returns phys. Miss: sets fault flag, logs faulting virtual address, returns 0.
TLB flush
diommu_flush(domain) increments the TLB flush counter. Required after remap operations to invalidate stale cached translations.
Fault reporting
Fault flag + fault_va (virtual address that triggered the fault). The kernel's IOMMU fault handler reads these to identify which peripheral issued a bad DMA request.

Base address 0x48A000. PASS: DIOMMU init=1 xlat=1 flt=1


apple_thunderbolt.sg — Thunderbolt 3/4 + USB4

Commit 45aca72. Thunderbolt 3/4 is the external interconnect on every Apple Silicon Mac — 40Gbps, carrying PCIe and DisplayPort simultaneously over a single USB-C connector. USB4 is the VESA/USB-IF standardization of the same protocol. The seam models both at the controller level.

2 ports
Each port tracks: PCIe tunnel flag (a PCIe device is connected and the PCIe lane is active), DP tunnel flag (a DisplayPort display is connected), USB4 link flag (USB4 negotiation complete).
8-slot DMA TX ring
Enqueue a descriptor → DMA transfer counter increments. Models the ring-buffer DMA path used for bulk data movement over the Thunderbolt fabric.
Hotplug
Hotplug event counter increments on connect/disconnect. The kernel's plug event handler watches this counter to enumerate newly attached devices.

Base address 0x48C000. PASS: TB init=1 tun=1 dma=1


apple_nvme.sg — Apple Embedded NVMe SSD

Commit dc146a0. Apple's embedded NVMe controller is NVMe 1.4-spec-compatible but tightly integrated — it sits on the Apple Silicon die fabric rather than on a PCIe lane. The seam models the full bring-up and I/O path.

Controller enable
CC.EN bit starts the controller. CSTS.RDY bit confirms readiness. Standard NVMe power-on sequence: write CC.EN=1, poll CSTS.RDY=1 before issuing any commands.
Admin queue: Identify
Identify Controller command (opcode 0x06) — returns model string + namespace count. The first command any NVMe driver issues after bring-up to discover what's attached.
I/O queues
8-slot SQ (Submission Queue) + 8-slot CQ (Completion Queue). SQ tail advances on submit; CQ head advances on completion. The standard NVMe doorbell model.
4K-LBA namespace
512B physical sector, 4096B logical block. Read/write LBA counters track total sectors transferred. Namespace ID 1.

Base address 0x48E000. PASS: NVM init=1 rdy=1 io=1


apple_spi.sg — Apple MacBook SPI Controller

Commit 055ee55. The SPI bus is how Apple Silicon MacBooks talk to the keyboard and trackpad. The controller runs at SPI mode 0 (CPOL=0, CPHA=0) in full-duplex mode — TX and RX happen simultaneously in the same clock cycle.

TX + RX FIFOs
8-byte TX FIFO + 8-byte RX FIFO. Full-duplex: TX bytes shift out while RX bytes shift in on the same clock edges.
Transfer state machine
idle → busy → complete → TXEI (TX empty interrupt) / RXNEI (RX not-empty interrupt) assert. The driver waits for RXNEI before reading the RX FIFO.
3 chip-select lines
CS0 = keyboard, CS1 = trackpad, CS2 = spare. CS assertion gates which peripheral is addressed on the shared bus.

Base address 0x490000. PASS: SPI init=1 xfr=1 rx=1


ppc_usb_ohci.sg — PowerPC G3/G4 USB OHCI 1.1

Commit 692a1c2. OHCI (Open Host Controller Interface) 1.1 is the USB 1.1 host controller standard found in Power Mac G3, G4, and early G5 systems. It provides full-speed (12Mbps) and low-speed (1.5Mbps) USB via a register-mapped interface.

OHCI registers
HcRevision (0x0110 = OHCI 1.1), HcControl (UsbOperational), HcCommandStatus (HostControllerReset), HcInterruptStatus, HcFmInterval (11999 for full-speed USB), HcFmNumber (frame counter).
2-port root hub
Each port has an LS (low-speed, 1.5Mbps) device connect flag and an FS (full-speed, 12Mbps) device connect flag. Port status reflects what device is physically attached.
SOF tick
ohci_sof_tick() advances the frame number. USB is a polled bus; the host controller emits a Start-of-Frame packet every 1ms. Frame number wraps at 2^16.

Base address 0x48B000. PASS: OHCI init=1 run=1 prt=1


ppc_ht.sg — G5 HyperTransport Interconnect

Commit 45aca72. HyperTransport (HT) is the high-speed point-to-point interconnect used in the Power Mac G5 to connect the CPU to the Uni-N bridge, PCIe fabric, and inter-processor links on dual-CPU models. It replaced the older MPC107 and Uni-N single-bus designs.

2 HT links
Per link: width (8-bit or 16-bit data bus), frequency (200/400/800/1000 MHz), link-up flag. Dual-CPU G5s use 16-bit 1GHz links between CPUs and the fabric.
8-slot command FIFO
Posted-write counter + response counter. HT is a posted-write protocol: the sender does not stall waiting for acknowledgment on every write, improving latency for MMIO-heavy workloads.
CRC error injection
ht_inject_crc(link) sets the CRC error flag on a specific link. Used for fault-tolerance testing — the kernel's error handler must detect and recover from CRC failures on degraded links.

Base address 0x48D000. PASS: HT init=1 lnk=1 crc=1


ppc_l1cache.sg — G3/G4/G5 L1 Cache Model

Commit dc146a0. The PowerPC L1 cache model covers the data and instruction caches present in all three generations: G3 (32K D + 32K I), G4 (32K D + 32K I, also AltiVec-aware), G5 (64K D + 64K I). The seam models the architectural behavior exposed to the Sigil kernel — cache maintenance instructions and the fill/probe interface.

D-cache + I-cache
32 sets × 8 ways = 256 cache lines, 32 bytes per line. Set = (addr / 32) % 32. Way selection is round-robin (LRU-approximating).
Fill + probe
l1c_fill(addr) loads a cache line. l1c_probe(addr) checks if the line is present (returns hit/miss without side effects).
PowerPC cache instructions
dcbf (data cache block flush — write dirty line to RAM and invalidate), dcbz (zero a cache line — allocate + zero without a load, used for fast buffer init), icbi (instruction cache block invalidate — required after JIT or self-modifying code).

Base address 0x48F000. PASS: L1C init=1 hit=1 ops=1


ppc_dbdma.sg — PowerPC DBDMA

Commit 055ee55. DBDMA (Descriptor-Based DMA) is the DMA engine found in all PowerPC Macs from the Power Mac 6100 (1994) through the G5 (2004). It uses a linked-list scatter-gather descriptor ring, allowing the DMA engine to transfer discontiguous memory regions without CPU intervention between segments. DBDMA drives audio I/O, IDE, FireWire, and USB on PPC Macs.

4 channels
Each channel has an independent 16-descriptor scatter-gather ring. Channels run independently; the kernel can have an audio output, audio input, IDE read, and IDE write all in flight simultaneously.
Descriptor opcodes
OUTPUT_MORE (continue TX chain), OUTPUT_LAST (end of TX — assert EOT), INPUT_MORE (continue RX chain), INPUT_LAST (end of RX — assert EOT), STOP (halt channel), NOOP (skip descriptor, continue).
Per-descriptor accounting
Byte count + transfer counter per descriptor. Channel byte accumulator tracks total bytes moved since last reset — used by audio drivers to synchronize sample position.

Base address 0x491000. PASS: DMA init=1 run=1 byt=1


Seam address map — batch 15

Address Seam Commit PASS
0x48A000 apple_iommu.sg — DART2 IOMMU 692a1c2 DIOMMU init=1 xlat=1 flt=1
0x48B000 ppc_usb_ohci.sg — USB OHCI 1.1 692a1c2 OHCI init=1 run=1 prt=1
0x48C000 apple_thunderbolt.sg — TB3/4/USB4 45aca72 TB init=1 tun=1 dma=1
0x48D000 ppc_ht.sg — G5 HyperTransport 45aca72 HT init=1 lnk=1 crc=1
0x48E000 apple_nvme.sg — embedded NVMe SSD dc146a0 NVM init=1 rdy=1 io=1
0x48F000 ppc_l1cache.sg — G3/G4/G5 L1 cache dc146a0 L1C init=1 hit=1 ops=1
0x490000 apple_spi.sg — MacBook SPI (kbd/trackpad) 055ee55 SPI init=1 xfr=1 rx=1
0x491000 ppc_dbdma.sg — PowerPC DBDMA 055ee55 DMA init=1 run=1 byt=1

Batch 15 closes out the Apple Silicon peripheral fabric (IOMMU, Thunderbolt, NVMe, SPI) and the PowerPC system bus (USB, HyperTransport, L1 cache, DBDMA). The kernel now has full modeled coverage of the hardware paths that matter for storage, display, input, and inter-chip DMA on both architectures.