← Blog
0.7.0 · KERNEL · HAL

HAL Batch 5 — BT5/HID-KB/Ampere CPU + PPC Decrementer/OpenPIC/SPI (sigil-kernel a4e93a1→a955e44)

June 22, 2026 · sigil-kernel a4e93a1 + cadcdb6 + a955e44 · Sigil-Docs
kernel hal apple-silicon powerpc hardware 0.7.0

Three more sigil-kernel commits extend the arch matrix from 0x4D4000 to 0x4D9000, adding 6 HAL seams: Apple Bluetooth 5 (BCM4387 HCI), PPC decrementer + 64-bit time-base, Apple HID USB keyboard, G3/G4/G5 OpenPIC interrupt controller, Apple Ampere CPU cluster manager (Icestorm/Firestorm E/P), and Heathrow/K2 SPI controller.


a4e93a1 — Bluetooth 5 + PPC decrementer

apple_bluetooth.sg
(0x4D4000)
BCM4387 Bluetooth 5 HCI transport (kernel side). bt_init(): powers on the BCM4387, initiates firmware load sequence; sets BLT_FW_LOADED flag on completion. bt_bd_addr(addr): records the 6-byte BD_ADDR (Bluetooth device address) in the BT state area. 4-slot ACL (Asynchronous Connection-Less) connection table: bt_acl_connect(handle, bd_addr) occupies a slot; bt_acl_disconnect(handle) clears it. bt_le_scan_start(mode): initiates LE (Bluetooth Low Energy) scan — mode 0=passive (no scan requests), mode 1=active (sends scan requests). Scan interval: 100ms, window: 10ms. bt_le_scan_stop(): stops LE scan. BLT init=1 acl=1 scn=1 K.
ppc_decrementer.sg
(0x4D5000)
PPC decrementer + 64-bit time-base. The PPC decrementer is the hardware timer that fires the OS scheduler tick. dec_init(reload): sets the decrementer reload value (counts down from reload to 0, then fires interrupt). dec_tick(): decrements counter by 1; if it reaches 0: reloads from dec_reload, increments interrupt-fire accumulator (dec_fires), advances the 64-bit time-base by 1. dec_jiffies(): returns the decrementer fire count (equivalent to jiffies in Linux PPC). dec_tb(): returns the 64-bit time-base value (pair of 32-bit halves stored at 0x4D5010/14). dec_pending(): returns 1 if a decrementer interrupt is pending (fired but not yet acknowledged). dec_clear(): clears PENDING flag. Note: tests use small reload=10 to avoid large loop counts on QEMU. DEC init=1 tck=1 tb=1 K.

cadcdb6 — HID keyboard + OpenPIC

apple_hid_kb.sg
(0x4D6000)
USB HID boot-protocol keyboard. USB HID boot-protocol keyboard is the standard HID keyboard interface — 8-byte HID report: modifier byte + reserved + 6 keycodes. hid_kb_report(modifier, keys[3]): processes a HID keyboard report; decodes modifier byte (bits: L-Ctrl/L-Shift/L-Alt/L-GUI/R-Ctrl/R-Shift/R-Alt/R-GUI). Stores up to 3 non-zero keycodes in a 3-slot rollover buffer. hid_kb_pressed(keycode): returns 1 if keycode is in the rollover buffer. hid_kb_mod_shift() / hid_kb_mod_ctrl() / hid_kb_mod_alt(): check specific modifier bits. hid_kb_overflow(): returns 1 if any keycode slot is 0x01 (phantom key / rollover overflow). hid_kb_press_count(): returns total key-report count. HKB init=1 rpt=1 mod=1 K.
ppc_pic.sg
(0x4D7000)
Grand Central / OpenPIC interrupt controller. OpenPIC is the interrupt controller on G3/G4/G5 Macs (Grand Central on G3, Uni-N I2S + OpenPIC on G4/G5). pic_init(): zeroes all IRQ state. pic_irq_raise(irq): sets the pending bit for irq in the pending mask. pic_irq_ack(irq): clears pending bit + in-service bit for irq. Priority model: pic_get_pending() returns the lowest-numbered pending unmasked IRQ (lowest bit = highest priority). pic_irq_mask(irq) / pic_irq_unmask(irq): block/unblock delivery of irq. In-service tracking: pic_isr_set(irq) marks in-service; pic_eoi(irq) (end-of-interrupt) calls pic_irq_ack and clears in-service. pic_spurious(): returns the count of spurious interrupts (IRQs acknowledged with no pending request). Tests verified: masked IRQ blocked until unmask, priority ordering (IRQ 0 preempts IRQ 7). PIC init=1 irq=1 msk=1 K.

a955e44 — Ampere CPU cluster + SPI

apple_ampere_cpu.sg
(0x4D8000)
Icestorm/Firestorm efficiency/performance cluster manager. Apple Silicon uses heterogeneous CPU clusters: Icestorm (efficiency, lower power) and Firestorm (performance, higher clock). M1 has 4 Icestorm (E) + 4 Firestorm (P) = 8 cores. amp_init(e_count, p_count): configures the cluster topology. amp_cluster_power(cluster, on): powers E-cluster (0) or P-cluster (1) on or off. amp_cluster_sleep(cluster) / amp_cluster_wake(cluster): arms/exits cluster deep sleep. amp_cluster_freq(cluster, mhz): sets per-cluster frequency target. amp_cluster_load(cluster): returns synthetic load (idle counter ratio). amp_cluster_temp(cluster): returns cluster temperature in °C (from the Matrix PMU thermal sensor). amp_online_mask(): returns bitmask of active CPUs (bit N = core N is online). M1 preset: amp_preset_m1() sets 4E(Icestorm)+4P(Firestorm), frequency 3228 MHz for P, 2064 MHz for E. AMP init=1 frq=1 slp=1 K.
ppc_spi.sg
(0x4D9000)
Heathrow/K2 SPI controller. Heathrow and K2 are the I/O ASICs on G3/G4 Macs; both include an SPI controller used for serial EEPROM, PMU communication, and board ID reads. spi_init(mode, clk_div): sets SPI mode (0=CPOL0/CPHA0, 1=CPOL0/CPHA1, 2=CPOL1/CPHA0, 3=CPOL1/CPHA1) and clock divider (1–255). spi_cs_assert(cs) / spi_cs_deassert(cs): asserts/deasserts one of 4 chip-select lines. spi_transfer(tx): sends tx byte and returns received byte (loopback: rx = 255 - tx in the test model — simulates a SPI device that returns the bitwise complement). spi_tx_count() / spi_rx_count(): return total bytes sent/received. SPI init=1 xfr=1 cs=1 K.

Arch matrix now at 0x4D9000. HAL batch 5 completes the connectivity/CPU cluster tier: BT5, keyboard, interrupt controller, CPU topology management, and SPI bus all seamed.