sigil-kernel's eighteenth HAL batch adds 8 more seams. Apple: ISP image signal processor (4-frame NV12/RGB888 output ring, AGC gain, exposure, VSync counter, drop on full); AIC2 interrupt controller (256 IRQs, per-IRQ enable/inject/EOI, 8-word pending bitmask, IPI slots); Metal GPU command queue (8-slot CB ring with render/compute/blit types, 8 fence signals, gcmdq_tick_one); PCIe Root Complex (M-series 4-port Gen4, link-train Gen4×4, endpoint plug vid/did/bar0, D0–D3 PM). PowerPC: Screamer/Tumbler sound (256-slot stereo play ring, vol L/R, mute, underrun per slot); PPC timebase + decrement (64-bit TB, 2-CPU DEC regs, dec_tick fires IRQ, EOI, nfire_tot); G5 L3 cache (256-entry 16S×16W 128B-line, round-robin evict, l3_probe/flush); G5 Hash Page Table (1024 PTEGs × 8 PTEs, primary hash insert, lookup hit/miss, TLBIE invalidate). All QEMU PASS. (sigil-kernel edb7c20, ef8ec97, 582d79d, 256b0ce)
apple_isp.sg (edb7c20): M-series Image Signal Processor
The ISP is the dedicated camera processing pipeline — converts raw sensor data to NV12 (YUV 4:2:0 planar, the standard video format) or RGB888. On Apple Silicon, the ISP is a separate coprocessor with a DMA output ring.
- 4-frame output ring: 4 frame slots. The ISP writes to the next available slot; when the ring is full, the incoming frame is dropped and a drop counter increments.
- NV12 output: Y plane (luma) + UV plane (interleaved chroma). Sizes calculated from width×height.
- RGB888 output: alternate mode — 3 bytes per pixel, row-major.
- AGC (Automatic Gain Control):
isp_set_gain(gain)— gain is in 1/10 units (10 = 1.0×, 20 = 2.0×). Stored in the gain register. - Exposure:
isp_set_exposure(exp)— exposure time in normalized units. Stored separately from gain. - VSync counter:
isp_vsync()→ increments the frame counter, writes a new frame to the ring if space is available.isp_get_frame()→ returns the oldest unread frame.
Base address 0x4A5000. PASS: ISP init=1 frm=1 drp=1
ppc_sound.sg (edb7c20): G3/G4 Screamer/Tumbler Sound Controller
Screamer (G3 Power Mac) and Tumbler (G4 PowerBook) are the two audio controllers covering the late Power Mac G3 and G4 era. Both use a DMA play ring fed from system memory.
- 256-slot stereo ring: 256 audio sample slots, each containing left + right PCM samples. The DAC reads slots in order; the driver fills them ahead.
- Volume:
snd_set_vol(L, R)— separate left/right volume registers (0–255). - Mute bitmask: per-channel mute.
snd_mute(mask)— bit0=left, bit1=right. snd_tick(): advances the play ring one slot. If the slot has not been filled by the driver (underrun), the underrun counter for that slot is incremented and the DAC outputs silence. Underrun is tracked per-slot (not per-tick), so a late-arriving slot doesn't inflate the underrun count.
Base address 0x4A6000. PASS: SND init=1 buf=1 und=1
apple_aic.sg (ef8ec97): AIC2 Interrupt Controller
The AIC2 (Apple Interrupt Controller 2) is the primary interrupt controller on Apple Silicon. It manages all hardware interrupt routing to the CPUs.
- 256 IRQs: each IRQ line has an independent enable register, a config register, and a pending flag.
aic_irq_enable(irq)/aic_irq_disable(irq): enable or disable a specific IRQ line.aic_irq_inject(irq): assert an IRQ line (simulates a hardware interrupt). If the IRQ is disabled, returns 97 (masked — correct behavior; the pending bit is NOT set for a disabled IRQ in the AIC2 model).aic_irq_eoi(irq): End Of Interrupt — clears the pending bit forirq.- 8-word pending bitmask: 8 × 32-bit words = 256 bits, one per IRQ.
aic_pending_word(word_idx)→ the 32-bit word at that index. - IPI slots: inter-processor interrupt slots for multicore signaling.
aic_ipi_send(cpu)/aic_ipi_clear(cpu).
Base address 0x4A7000. PASS: AIC init=1 irq=1 eoi=1
ppc_dec.sg (ef8ec97): PowerPC Timebase and Decrement Registers
The PowerPC Timebase (TB) and Decrement (DEC) registers are the fundamental timer mechanism on all PowerPC processors. They drive the OS scheduler tick.
- 64-bit timebase:
tb_lo(lower 32 bits) andtb_hi(upper 32 bits). The timebase counts up continuously at a fixed frequency (bus clock ÷ 4 on G3/G4).dec_tick(n)increments the timebase by n. - 2-CPU DEC registers: each CPU has its own Decrement register. The DEC counts down from the value set by the OS (the scheduler quantum). When DEC reaches 0, it fires a decrement interrupt (the scheduler tick).
dec_tick(n): advances the timebase by n. Decrements both DEC registers by n. When DEC0 or DEC1 → 0 (or below), fires the interrupt for that CPU. The interrupt is cleared bydec_eoi(cpu).nfire_totcounts total fired interrupts.
Base address 0x4A8000. PASS: DEC init=1 fir=1 eoi=1
apple_gpu_cmdq.sg (582d79d): Metal GPU Command Queue
Metal is Apple's GPU programming model. The HAL seam models the Metal command processor — the GPU-side queue that receives command buffers from the CPU and executes them.
- 8-slot command buffer (CB) ring: the CPU enqueues command buffers; the GPU dequeues and executes them. 3 types: RENDER (draw calls), COMPUTE (compute shader), BLIT (memory copy / texture copy).
gcmdq_submit(type, payload): enqueues a command buffer. Returns error if the ring is full.- 8 fence signals: fences are synchronization primitives — the CPU can wait for a specific fence to be signaled (indicating a CB has completed).
gcmdq_signal_fence(fence_id)sets a fence. gcmdq_tick_one(): dequeues and "executes" the oldest pending CB. Marks it done, signals its fence, incrementsgpu_us(GPU time counter).
Base address 0x4A9000. PASS: GPU init=1 sub=1 fnc=1
ppc_l3cache.sg (582d79d): Power Mac G5 L3 Cache Controller
The G5 (PowerPC 970) had an external L3 cache (2 MB on the dual-2.0 GHz, 512 KB on the single). The L3 is a write-back, set-associative cache controlled by a dedicated controller.
- 256-entry cache: 16 sets × 16 ways, 128-byte cache lines. Cache tag format: (address >> 7) for the tag, (address >> 7) % 16 for the set index.
l3_probe(addr): checks if the address is in cache. On hit: returns the way index. On miss: inserts into the LRU way (round-robin evict). If all ways of a set are occupied and the 17th probe hits the same set, the oldest entry is evicted (evict counter increments).l3_flush(addr): invalidates the cache line foraddrif present.
Base address 0x4AA000. PASS: L3C init=1 hit=1 fls=1
apple_pcie_rc.sg (256b0ce): M-series PCIe Root Complex
The PCIe Root Complex is the top-level PCIe entity — it owns the bus and presents the PCIe tree to the CPU. Apple Silicon's RC supports PCIe 4.0 (Gen4).
- 4 ports: Port 0 (typically the NVMe SSD), Port 1 (Ethernet), Port 2 (USB4/TB4), Port 3 (expansion / unused).
- Link train:
pcie_link_train(port)→ negotiates Gen4×4 (16 GT/s per lane × 4 lanes = 64 Gbps per port). Link speed and width stored per-port. - Endpoint plug:
pcie_plug_ep(port, vid, did, bar0)→ registers a device on a port with its PCI VID/DID and BAR0 (the primary MMIO address). - D0–D3 power management:
pcie_set_pm(port, state)→ D0 (active), D1 (light sleep), D2 (deep sleep), D3 (off). Per-port PM state tracked.
Base address 0x4AB000. PASS: PCI init=1 lnk=1 pm=1
ppc_htab.sg (256b0ce): G5 Hash Page Table
The PowerPC 970 (G5) uses a hardware-managed hash page table (HTAB) for virtual memory translation. Unlike x86 page tables (software-walked), the PPC HTAB is walked by hardware.
- 1024 PTEGs × 8 PTEs: PTEG = Page Table Entry Group. Each PTEG holds 8 PTEs (primary group). Total: 8192 PTEs = 8192 × 4 KB = 32 MB virtual address coverage at minimum (scales with HTAB size register).
- Primary hash: for a given virtual address, the primary hash selects a PTEG index.
htab_insert(ea, pa, flags)→ computes the primary hash, finds an empty PTE in the PTEG, inserts the (EA, PA) mapping. Returns 1 on success, 0 if the PTEG is full (secondary hash overflow not implemented — model matches hardware behavior for the non-overflow path). - Lookup:
htab_lookup(ea)→ returns the PA if found, or -1 (miss). Hit/miss counters. - TLBIE: TLB Invalidation Entry.
htab_tlbie(ea)→ removes the mapping foreafrom the HTAB and increments the miss counter (the next lookup foreawill miss and take a page fault). This is how the OS flushes a page mapping on unmap/remap.
Base address 0x4AC000. PASS: HTA init=1 ins=1 tlb=1
Batch 18 seam table (0x4A5000–0x4AC000)
| Address | Seam | Platform | Commit | Status |
|---|---|---|---|---|
0x4A5000 | apple_isp.sg | Apple Silicon | edb7c20 | PASS |
0x4A6000 | ppc_sound.sg | PowerPC G3/G4 | edb7c20 | PASS |
0x4A7000 | apple_aic.sg | Apple Silicon | ef8ec97 | PASS |
0x4A8000 | ppc_dec.sg | PowerPC G3/G4/G5 | ef8ec97 | PASS |
0x4A9000 | apple_gpu_cmdq.sg | Apple Silicon | 582d79d | PASS |
0x4AA000 | ppc_l3cache.sg | PowerPC G5 | 582d79d | PASS |
0x4AB000 | apple_pcie_rc.sg | Apple Silicon | 256b0ce | PASS |
0x4AC000 | ppc_htab.sg | PowerPC G5 | 256b0ce | PASS |
Batch 18 brings the total HAL seam count to approximately 134 — spanning Apple Silicon (M1/M2/M3), PowerPC G3/G4/G5, x86/x86_64, ARM Cortex-A, and RISC-V platforms.