ASELSANMicrokernel
S3 · SOURCE-BOUND GATE EVIDENCE

Workspace test harness çakışması düzeltildi

Operations komutu/kapı ailesi → gerçek repository yürütme sözleşmesi Bu sayfa yalnız S3 kapısına aittir; komşu kapıların kaynakları bu kabulün içine katılmaz.

S3Komut / fiziksel sözleşmeOperations id exactsource SHA exact

operation: workspace-test-harness

script/Makefile/config · Operations · 2 exact excerpt

sequence-bound=true · implementation-bound=false
01 · Yürütme sözleşmesi

Gerçek script / Makefile / config kaynağı

tam dosyaL1–L978
kernel/Cargo.toml::Cargo.toml
[package]
name = "aselsan_kernel"
version.workspace = true
edition.workspace = true
license.workspace = true
description = "ASELSAN Milli Telefon - Gerçek aarch64 Microkernel (EL1 + Capability + IPC)"

[[bin]]
name = "aselsan_kernel"
path = "src/main.rs"
# Bare-metal binary kendi panic handler'ına sahiptir. `cargo test --workspace`
# std test harness'ini bu binary'ye bağlamaya çalışırsa duplicate panic_impl oluşur.
test = false
bench = false

[dependencies]
aselsan_abi = { path = "../abi" }
# AselBrowser motoru telefon imajinin icinde. `default-features = false` ->
# no_std + alloc; std yok, unsafe yok (crate `#![forbid(unsafe_code)]`).
asel_browser = { path = "../userspace/asel_browser", default-features = false }
linked_list_allocator = { version = "0.10", default-features = false, features = ["use_spin"] }

# 0.9.8 was yanked on 2026-07-13; 0.9.9 is the un-yanked republish of the
# same 0.9 Mutex/RwLock API. Do not float back onto a yanked 0.9.8 pin.
spin = { version = "0.9.9", default-features = false, features = ["spin_mutex", "rwlock"] }
heapless = { version = "0.8", default-features = false }

# Bare-metal aarch64 için temel crate'ler (ileride eklenecek)
# aarch64 = "0.14"     # CPU register erişimi
# log = "0.4"          # Logging facade

# Profiller workspace root'ta tanımlı (Cargo.toml)

[features]
# R120: BCM43455'te BT ve WLAN ayni kalipta PMU/saat paylasir.  Bu bayrak
# SADECE BT-A1 bring_up'ini (BT_ON surme + UARTA yazma) atlar; salt-okunur
# BT envanteri ve Wi-Fi yolu aynen kalir.  Tek degiskenli cikarma deneyi.
rpi5-bt-isolate = []

# BT-B01: Raspberry Pi 5 D0 DTB'sindeki `uarta_24_pins` bias planini uygula.
# Yalniz gpio24..27 pad pull alanlarini degistirir: RTS/TX bias-disable,
# CTS/RX bias-pull-up. UART hizi, MCR/AFE, HCI komutu ve R211 Wi-Fi yolu
# degismez; fiziksel HCI Reset cevabi gelmeden tarama iddiasi yoktur.
rpi5-bt-uart-pulls = ["rpi5-radio-inventory"]

# BT-B02: BT-B01 pad bias tabani uzerinde BCM7271'in 8250 AFE bitini acar.
# Resmi DTS `uart-has-rtscts` + `auto-flow-control` ister. Tek davranis farki
# MCR 0x03 -> 0x23; baud, BT_ON, HCI Reset ve Wi-Fi yolu aynidir.
rpi5-bt-auto-flow-control = ["rpi5-bt-uart-pulls"]

# BT-B03: kartla eslesen BCM4345C0 HCD patchram dosyasini, Linux btbcm
# sirasiyla (Start Download, 50 ms, 323 kayit, 250 ms) yukler. B02'nin
# fiziksel ROM-speed HCI cevabi bu ozelligin taban kapisidir.
rpi5-bt-hcd = ["rpi5-bt-auto-flow-control"]

# BT-B04: HCD tamamlandiktan sonra Linux controller-first 0xfc18 dizisiyle
# UARTA'yi resmi RPi5 max-speed=3_000_000 hizina gecirir; post-patch Reset,
# Local Version ve Broadcom verbose config kimligini okur.
rpi5-bt-3mbps = ["rpi5-bt-hcd"]

# BT-B05: kalici, paket-turu/uzunluk farkinda H4 decoder; opcode/status
# esleme, tasma-drain ve sinirli beklenmeyen olay kuyrugu. Fiziksel kapida
# post-patch 3 Mbit/s hat uzerinde 100 ard arda kimlik komutu kosar.
rpi5-bt-h4-engine = ["rpi5-bt-3mbps"]

# BT-B06: B05 motoru uzerinde BR/EDR General Inquiry, RSSI/EIR ayristirma ve
# adi EIR'da olmayan aygitlar icin sinirli Remote Name Request.
rpi5-bt-classic-inquiry = ["rpi5-bt-h4-engine"]

# BT-B07: B06 tabani uzerinde yalniz legacy LE pasif tarama. Event mask,
# 10 ms scan interval/window, advertising report parser ve scan-disable kapanisi.
# Baglanti, esleme ve aktif scan request gondermez.
rpi5-bt-le-passive-scan = ["rpi5-bt-classic-inquiry"]

# BT-B08 name resolution: request legacy Scan Response payloads without
# creating a connection or pairing. B07 remains independently passive.
rpi5-bt-le-active-scan = ["rpi5-bt-le-passive-scan"]

# BT-B08: copies the physically measured B06/B07 receipts into a bounded,
# signal-sorted Settings model. No pairing, connection, or synthetic rows.
rpi5-bt-ui-model = ["rpi5-bt-le-passive-scan"]

# BT-B09: run a second bounded passive LE collection concurrently with an
# accepted R211 Wi-Fi scan generation. Both transports are polled from the
# screen loop; Classic remains the separate B06 control in the same boot.
rpi5-bt-wifi-coexistence = ["rpi5-bt-ui-model", "rpi5-wifi-scan"]

# BT-B11: an explicit Settings row selection starts a BR/EDR ACL connection,
# negotiates Secure Simple Pairing as DisplayYesNo, publishes only the
# controller-originated numeric-comparison value, and returns Eşle/Vazgeç to
# HCI. It inherits the physically passed B09 transport/coexistence base.
rpi5-bt-pairing = ["rpi5-bt-wifi-coexistence"]

# BT-B13: keep consuming controller link-state events after SSP completes.
# A successful bond and a live ACL are separate facts: Disconnection Complete
# keeps the device in Aygitlarim but changes its status to Bagli Degil; an
# authenticated reconnect changes it back to Bagli.
rpi5-bt-link-state = ["rpi5-bt-pairing"]

# BT-B14: the discovery model remains bounded at sixteen measured identities,
# but the Settings document renders every retained row and exposes it through
# pixel-precise kinetic scrolling instead of truncating the UI at four rows.
rpi5-bt-all-devices = ["rpi5-bt-link-state"]

# BT-B15: equal human-facing names remain distinguishable without inventing a
# model or serial number. The list shows the final three octets of the current
# measured controller address as an explicitly non-persistent session ID.
rpi5-bt-session-id = ["rpi5-bt-all-devices"]

# BT-B16: publish the successful B09 runtime BLE receipt into Settings and
# re-arm bounded discovery after a quiet interval. Failed/empty refreshes keep
# the last measured rows; pairing/link-state ownership always takes priority.
rpi5-bt-live-refresh = ["rpi5-bt-session-id"]

# BT-B17: decode the already-captured Apple Manufacturer Specific Data into
# explicit evidence rows. Company 0x004C and Continuity type/length are shown;
# an exact model is named only when the packet carries a model field. Nearby
# Info never becomes a guessed iPhone generation.
rpi5-bt-apple-ad-facts = ["rpi5-bt-live-refresh"]

# BT-B18: UI-only correction for BT-B17's optional third evidence line. Row
# height, painting, hit testing and scroll extent all use the same measured
# font geometry; radio discovery/pairing bytes remain inherited from B17.
rpi5-bt-row-layout = ["rpi5-bt-apple-ad-facts"]
# BT-B19: carry the measured source of every discovered name through HCI,
# the bounded UI snapshot and UART acceptance without changing scan policy.
rpi5-bt-name-provenance = ["rpi5-bt-row-layout"]

# BT-B20: change only the bounded B09 runtime scan parameter from passive to
# active so Scan Response Local Names can refresh the UI. This sends standard
# Scan Requests only; connection, pairing and GATT authority are unchanged.
rpi5-bt-runtime-active-scan = ["rpi5-bt-name-provenance", "rpi5-bt-le-active-scan"]

# BT-B21: retain advertisement and Scan Response AD structures independently,
# preserve the advertisement event type/connectability evidence, and choose a
# stable best measured name regardless of packet order or repetition.
rpi5-bt-adv-scan-merge = ["rpi5-bt-runtime-active-scan"]

# BT-B22: retry missing Classic names through one bounded asynchronous Remote
# Name Request at a time. Pairing and BLE scan ownership remain higher
# priority; a silent peer advances by timeout instead of parking the UI loop.
rpi5-bt-runtime-remote-name = ["rpi5-bt-adv-scan-merge"]

# BT-B23 host/runtime name hierarchy and authenticated cache model. The image
# keeps persistence writes disabled until a real device-secret/backend exists.
rpi5-bt-identity-cache = ["rpi5-bt-runtime-remote-name"]

# BT-B24: Bluetooth `ah`/IRK resolution and encrypted SMP identity
# distribution. It can merge an observed RPA only after an authenticated bond
# supplied the IRK; unmatched random addresses remain separate.
rpi5-bt-irk-resolution = ["rpi5-bt-identity-cache"]

# BT-B25/B26 transport-independent ATT/GATT admission and GAP/DIS evidence
# parsers. Actual LE ACL/L2CAP transport is still absent and is reported so.
rpi5-bt-gatt-profile-model = ["rpi5-bt-irk-resolution"]
rpi5-bt-dis-evidence = ["rpi5-bt-gatt-profile-model"]

# BT-B25/B26 transport: the real LE ACL/L2CAP/ATT client that carries the
# admission + DIS parsers over the wire. Isolated leaf feature so the frozen
# B21-B30 evidence images are untouched. It connects to exactly one measured
# connectable, user-selected row, reads only the open GAP/DIS profile
# characteristics (no serial / System ID), and disconnects immediately. Adds
# LE Create Connection, the ACL data path and CID-4 L2CAP framing that the
# scan-only path never had. Physical acceptance still pending.
rpi5-bt-gatt-transport = ["rpi5-bt-dis-evidence"]

# BT-B27 strict SDP Device ID data-element/PDU parser. Classic L2CAP/SDP
# transport remains a separate physical prerequisite.
rpi5-bt-sdp-device-id = ["rpi5-bt-dis-evidence"]

# BT-B28 official advertisement formats only: Google Fast Pair Service Data
# model ID and Microsoft Swift Pair Display Name.
rpi5-bt-vendor-pair-names = ["rpi5-bt-sdp-device-id"]

# BT-B29: render measured name provenance/identity decision separately from
# product-model evidence while keeping the established priority chain.
rpi5-bt-name-evidence-ui = ["rpi5-bt-vendor-pair-names"]

# BT-B30: release-candidate instrumentation only. Physical acceptance still
# requires three independent boots and the documented real-device matrix.
rpi5-bt-release-matrix = ["rpi5-bt-name-evidence-ui"]

default = ["board-qemu"]
# SMP / Multi-core desteği (henüz aktif değil, sadece iskelet)
smp = []

# M8.1 — Board / Platform seçimi (feature flag ile)
board-qemu = []
board-rpi4 = []
board-rpi5 = []
# Opt-in Touch Display 2 bring-up image.  It is deliberately separate from
# the frozen board-rpi5 image so a screen probe can never silently replace the
# R1/R2 physical evidence payload.
rpi5-screen-demo = []
# Dedicated foreground GT911 polling image. It deliberately diverges after
# SCREEN0 and never enters the frozen two-task G7 scheduler proof.
rpi5-touch-demo = ["rpi5-screen-demo"]
# Dedicated UI-Server live-frame image. It diverges after SCREEN0, owns the
# DSI heap through FramebufferManager::create_cap, and never enters the
# GT911 poll loop or the frozen two-task G7 scheduler proof.
rpi5-ui-server-demo = ["rpi5-screen-demo"]
# Attempt-23: iPhone-like pager + GT911 consumer. Separate from Path B
# ACCEPTED=0 poll image and from A21/A22 freezes.
rpi5-ios-home-demo = ["rpi5-touch-demo"]
# Isolated phone integration candidate. Frozen modem/screen profiles retain
# their independent loops and historical acceptance records.
phone-services = []
phone-ipc-smoke = ["phone-services"]
browser-ipc-smoke = ["phone-services"]
phone-app-runtime = ["phone-services"]
phone-app-smoke = ["phone-app-runtime", "phone-ipc-smoke", "rpi5-phone-storage"]
phone-messaging-smoke = ["phone-app-smoke"]
phone-call-smoke = ["phone-messaging-smoke"]
# Independent QEMU virt fixture: real EL0 TCP IPC and packet gateway, with a
# deterministic RAM peer. This profile never enables RPi5 modem or boot paths.
phone-tcp-qemu-smoke = ["phone-app-runtime"]
rpi5-phone-services = ["phone-app-runtime", "rpi5-ios-home-demo", "rpi5-ebd050-runtime", "rpi5-phone-storage"]
# SD driver capability only; does not enable W3-W7 boot write experiments.
rpi5-phone-storage = []
# Dedicated SIM8262 control-plane image. It keeps the proven DSI/touch stack,
# adds only RP1 UART0 MMIO, and never claims that AT registration is QMI/IP.
rpi5-sim8262-uart-control = ["rpi5-ios-home-demo"]
# EBD-M10.1: RP1 xHCI halt/reset, DCBAA, command ring, event ring and the poll
# path. The EBD050 occupies the 40-pin header, so this profile is deliberately
# headless and must not inherit the Touch Display 2 / iOS-home stack.
# A running controller is not enumeration and not packet data.
rpi5-ebd050-xhci-host = []
# EBD-M10.2: opt-in physical USB enumeration layered on the accepted M10.1
# host. It may reset a connected SuperSpeed port, ring command/EP0 doorbells,
# address one slot and read descriptors. It still has no serial/MBIM data path.
rpi5-ebd050-usb-enumerator = ["rpi5-ebd050-xhci-host"]
# EBD-M10.2b: start only the modem controller (xhci-hcd.1 / usb@300000).
# No Enable Slot, hot reset, or doorbell. The other controller is not reset.
rpi5-ebd050-xhci-link = ["rpi5-ebd050-xhci-host"]
# EBD-M10.2c: masked RP1 DWC3 host quirks. Off until a PORTSC snapshot shows
# the link still stuck and the read-only GSNPSID block differs from the DT.
rpi5-ebd050-dwc3-phy = ["rpi5-ebd050-xhci-link"]
# EBD-M10.2h: take over only the firmware-stopped modem controller without
# HCRST, port-power, DWC3, command-doorbell, or enumeration writes.
rpi5-ebd050-xhci-handoff = ["rpi5-ebd050-xhci-host"]
# EBD-M10.3: enumerate the physically accepted USB2 high-speed modem on CTL1
# after reset-free handoff. Packet data remains blocked.
rpi5-ebd050-usb2-enumerator = ["rpi5-ebd050-xhci-handoff"]
# EBD-M10.4: configure only the measured interface-2 vendor bulk pair and
# require one bounded AT/OK exchange. CDC-WDM, MBIM and packet data stay off.
rpi5-ebd050-usb-at = ["rpi5-ebd050-usb2-enumerator"]
# EBD-M10.5: bind the interface-8 CDC-WDM control transport, wait for the
# response-available interrupt, and require MBIM OPEN_DONE success. No data EP.
rpi5-ebd050-mbim-control = ["rpi5-ebd050-usb-at"]
# EBD-M10.6: select the measured MBIM data alternate setting and install only
# its bulk endpoint contexts. No packet transfer or network interface yet.
rpi5-ebd050-mbim-data = ["rpi5-ebd050-mbim-control", "rpi5-uart-reset"]
# EBD-M10.7a: read mandatory CDC NCM NTB parameters and publish only a bound
# RustOS MBIM netdev. Session activation, IP configuration and DNS stay off.
rpi5-ebd050-network-interface = ["rpi5-ebd050-mbim-data"]
# EBD-M10.7b: query SIM/radio/registration/attach, activate session 0 with the
# measured APN and accept only modem-returned IPv4/gateway/DNS/MTU values.
rpi5-ebd050-ipv4-session = ["rpi5-ebd050-network-interface"]
# EBD-M10.7c: frame one IPS0/NDP16 IPv4 packet, perform a checksummed UDP DNS
# A lookup against the modem-returned resolver, then and only then open DATA.
rpi5-ebd050-dns = ["rpi5-ebd050-ipv4-session"]
# EBD-M10.8a: keep the accepted DATA=READY stage alive as an owned runtime.
# The WFI loop drains the xHCI event ring and prints its own uptime heartbeat.
# Owning the loop is not liveness and not recovery; no new traffic is sent.
rpi5-ebd050-runtime = ["rpi5-ebd050-dns"]
# EBD-M10.8b: repeat the accepted M10.7c DNS round on a fixed interval and
# count NTB/ring/DMA overflow. Every answer is a dated measurement; no address
# or TTL is pinned, and a repeated round is not a recovered one.
rpi5-ebd050-liveness = ["rpi5-ebd050-runtime"]
# EBD-M10.8c: after a kernel-initiated session loss, reactivate session 0 with
# bounded backoff and modem-returned IPv4 only. One session, no operator
# action, no USB reset. Session recovery is not USB recovery.
rpi5-ebd050-session-recovery = ["rpi5-ebd050-liveness"]
# EBD-M10.8d: after a kernel-initiated modem restart, re-enumerate the same
# CTL1 USB2 port into a single slot and reopen one session. No HCRST, no
# port-power write, no SuperSpeed path.
rpi5-ebd050-usb-reconnect = ["rpi5-ebd050-session-recovery"]
# EBD-M10.8d retry 2: the first physical candidate proved that an acknowledged
# AT+CFUN=1,1 can leave the EBD050 USB port disconnected indefinitely. Permit
# exactly one documented board-level MODEM RESET pulse and the USB2 port reset
# required to re-enable a physically returned device. HCRST and PP stay closed.
rpi5-ebd050-usb-reconnect-reset = ["rpi5-ebd050-usb-reconnect"]
rpi5-ebd050-usb-reconnect-reset-retry = ["rpi5-ebd050-usb-reconnect-reset"]
rpi5-ebd050-usb-reconnect-power-key = ["rpi5-ebd050-usb-reconnect-reset"]
rpi5-ebd050-usb-reconnect-power-key-long = ["rpi5-ebd050-usb-reconnect-power-key"]
rpi5-ebd050-usb-reconnect-mbim-trace = ["rpi5-ebd050-usb-reconnect-power-key-long"]
rpi5-ebd050-usb-reconnect-mbim-poll = ["rpi5-ebd050-usb-reconnect-mbim-trace"]
rpi5-ebd050-usb-reconnect-mbim-poll-initial = ["rpi5-ebd050-usb-reconnect-mbim-poll"]
rpi5-ebd050-usb-reconnect-hard-reset = ["rpi5-ebd050-usb-reconnect-mbim-poll-initial"]
rpi5-ebd050-usb-reconnect-hard-reset-long = ["rpi5-ebd050-usb-reconnect-hard-reset"]
rpi5-ebd050-usb-reconnect-hard-reset-superspeed = ["rpi5-ebd050-usb-reconnect-hard-reset-long"]
# EBD-M10.8d retry 12: the R8 replay proved that a modem already present on
# CTL1 SuperSpeed port 3 was misclassified as absent because boot rescue read
# only USB2 port 1.  Preserve either measured link, emit no board-level pulse
# for a live modem, and enumerate the link that is actually connected.
rpi5-ebd050-usb-reconnect-adaptive-link = ["rpi5-ebd050-usb-reconnect-mbim-poll-initial"]
# EBD-M10.8d retry 13: keep R12's measured-link selection, then close any
# prior MBIM control session with a bounded CLOSE/CLOSE_DONE exchange before
# issuing the ordinary OPEN. Packet data remains fail-closed throughout.
rpi5-ebd050-usb-reconnect-mbim-close = ["rpi5-ebd050-usb-reconnect-adaptive-link"]
# EBD-M10.8d retry 14: libmbim-compatible consecutive transaction sequence:
# CLOSE=base+1, OPEN=base+2, then the six session messages at base+3..8.
rpi5-ebd050-usb-reconnect-mbim-sequence = ["rpi5-ebd050-usb-reconnect-mbim-close"]
# EBD-M10.8d retry 15: initialize the measured CDC NCM function before MBIM
# OPEN in the order used by Linux cdc_ncm: read/validate NTB parameters,
# select NTB16, set NTB input size, pause 10 ms, then select data alt 1.
rpi5-ebd050-usb-reconnect-mbim-preopen-ncm = ["rpi5-ebd050-usb-reconnect-mbim-sequence"]
# EBD-M10.8d retry 16: use the boot-time measured link again after a real
# modem restart. The accepted R15 boot can own CTL1 SuperSpeed port 3, so
# runtime re-enumeration must not fall back to its legacy USB2-port-1 helper.
rpi5-ebd050-usb-reconnect-adaptive-runtime = ["rpi5-ebd050-usb-reconnect-mbim-preopen-ncm"]
# EBD-M10.8d retry 17: a fresh USB configuration is already in MBIM's closed
# state. Do the USB-IF NCM preparation and issue OPEN directly; an unsolicited
# CLOSE on this modem can produce no CLOSE_DONE and stall EP0 completion 6.
rpi5-ebd050-usb-reconnect-direct-open = ["rpi5-ebd050-usb-reconnect-adaptive-runtime"]
# EBD-M10.8d retry 18: CFUN=1,1 is already a modem reboot request. Give the
# module its documented long restart window before the existing one-shot
# PWRKEY escalation, instead of perturbing a natural return after ten seconds.
rpi5-ebd050-usb-reconnect-return-grace = ["rpi5-ebd050-usb-reconnect-direct-open"]
# EBD-M10.8d retry 19: the USB descriptors return before the modem's vendor AT
# service. Preserve the freshly enumerated slot for a bounded 30 s settle,
# then give the first AT exchange a bounded 10 s response window.
rpi5-ebd050-usb-reconnect-service-settle = ["rpi5-ebd050-usb-reconnect-return-grace"]
# EBD-M10.8d retry 20: R19 measured one completion from the retired AT ring
# arriving during the 30 s service settle. Drain only already-pending events
# through the live ERDP cursor before configuring the fresh AT endpoints.
rpi5-ebd050-usb-reconnect-stale-event-drain = ["rpi5-ebd050-usb-reconnect-service-settle"]
# EBD-M10.8d retry 21: R20 proved the controller can report the just-consumed
# bulk-IN TRB again after the next TRB is armed. Admit only that exact previous
# pointer with a success/short-packet completion, and cap the discard count.
rpi5-ebd050-usb-reconnect-duplicate-at-event = ["rpi5-ebd050-usb-reconnect-stale-event-drain"]
# EBD-M10.8d retry 22: R21 localized the mismatch to the Setup TRB immediately
# before the expected EP0 Status TRB. Observe its completion code; skip at most
# one successful setup-stage event and still require the status-stage event.
rpi5-ebd050-usb-reconnect-ep0-setup-event = ["rpi5-ebd050-usb-reconnect-duplicate-at-event"]
# EBD-M10.8d retry 23: R22 measured completion 4 on the SET_CONFIGURATION
# Setup TRB after preserving a slot for 30 s. Let the modem's USB identity
# settle first, drain its PSC events, then address the final device instance.
rpi5-ebd050-usb-reconnect-pre-enum-settle = ["rpi5-ebd050-usb-reconnect-ep0-setup-event"]
# EBD-M10.8d retry 24: R23 closed the data plane but its terminal receipt kept
# the legacy USB2-only SUPERSPEED=0 literal. Report the measured final speed so
# the enum and terminal receipts cannot contradict one another.
rpi5-ebd050-usb-reconnect-terminal-link-receipt = ["rpi5-ebd050-usb-reconnect-pre-enum-settle"]
# EBD-M10.8e: keep R24 wire behavior unchanged and add one terminal receipt
# only after ten successful real USB reconnect epochs in the same runtime.
# The host drives each epoch; the image never manufactures a loss or PASS.
rpi5-ebd050-usb-reconnect-soak = ["rpi5-ebd050-usb-reconnect-terminal-link-receipt"]
# EBD-M10.8e-R2: keep the failed soak immutable; wait for the measured CTL1
# SuperSpeed link to remain fully ready before each reconnect enumeration.
rpi5-ebd050-usb-reconnect-soak-readiness = ["rpi5-ebd050-usb-reconnect-soak"]
# EBD-M10.8e-R3: retain R2's exact SuperSpeed readiness requirement. After a
# measured 240 s disconnected/AT-unavailable interval, permit one 1000 ms
# PWRKEY pulse per epoch and bound the post-pulse wait to 120 s. The inherited
# R24 chain already supplies the long-pulse GPIO implementation.
rpi5-ebd050-usb-reconnect-soak-power-key = ["rpi5-ebd050-usb-reconnect-soak-readiness"]
# EBD-M10.8e-R4: preserve R3 byte-path policy and identify the measured epoch-2
# failure after MBIM OPEN_DONE at the data-interface/configure-endpoint stage.
rpi5-ebd050-usb-reconnect-soak-data-trace = ["rpi5-ebd050-usb-reconnect-soak-power-key"]
# EBD-M10.8e-R5: PWRKEY is not a restart primitive. After 240 s of measured
# USB/AT absence, admit at most one separately receipted 500 ms MODEM_RESET
# pulse, then require 30 s of exact SuperSpeed stability within 120 s.
rpi5-ebd050-usb-reconnect-soak-reset = ["rpi5-ebd050-usb-reconnect-soak-readiness"]
# EBD-M10.8e-R6: retain the complete R5 board-control boundary. Only after
# that boundary fails with CTL1 port 3 still powered and in RxDetect, admit one
# targeted USB3 Warm Port Reset and require WRC plus 30 s stable SuperSpeed.
rpi5-ebd050-usb-reconnect-soak-warm-reset = ["rpi5-ebd050-usb-reconnect-soak-reset"]
# EBD-M10.8e-R7: when the natural-return deadline samples the measured USB3
# Polling state (CCS=1/PED=0/PLS=6/PP=1/SPEED=4), wait write-free for at most
# 60 s before falling back to the unchanged R6 reset/WPR policy.
rpi5-ebd050-usb-reconnect-soak-link-training = ["rpi5-ebd050-usb-reconnect-soak-warm-reset"]
# EBD-M10.8e-R8: R7 measured the same Polling state only after the one allowed
# MODEM_RESET and its complete 120 s observation window. Move the single,
# write-free 60 s training grace to that exact post-reset boundary. No new
# GPIO pulse, xHCI reset, port-power transition, or WPR authority is added.
rpi5-ebd050-usb-reconnect-soak-post-reset-link-training = ["rpi5-ebd050-usb-reconnect-soak-link-training"]
# EBD-M10.8e-R9: physical boots measured PLS=Polling at either the natural or
# post-RESET boundary. Admit exactly one write-free grace window at the first
# measured boundary per epoch; never allow a second window or new authority.
rpi5-ebd050-usb-reconnect-soak-first-training = ["rpi5-ebd050-usb-reconnect-soak-post-reset-link-training"]
# R177 saha teshis overlay'i: diag_print ciktisini DSI framebuffer'ina da
# basar. VARSAYILAN KAPALI -- ana ekranin ustunde siyah bir log penceresi
# birakiyordu. Yalniz UART erisilemezken acin.
rpi5-diag-overlay = []
# SD-A0: read-only SDHCI register inventory for the microSD controller.
# One new MMIO page, zero commands, zero writes.  Separate from the screen
# and ios-home images so a mapping mistake cannot reach them.
rpi5-sd-inventory = ["rpi5-ios-home-demo"]
# SD-A1: the first real SD command.  READ_SINGLE_BLOCK only; the module can
# emit no other command index.  Still zero card writes.
rpi5-sd-read = ["rpi5-sd-inventory"]

# SD-C W3: the first card write.  Only this image contains a write command
# index; every earlier stage is built without it and can be shown to be
# write-incapable rather than merely well behaved.
rpi5-sd-write = ["rpi5-sd-read"]

# SD-C W4: the superblock commit protocol.  Its own feature so the W3 image
# provably writes one data sector and nothing else, and the W4 image provably
# writes superblocks and no data sector.
rpi5-sd-write-superblock = ["rpi5-sd-write"]

# SD-C W5: codec-free bulk timing.  1024 data sectors of a fixed pattern, so
# the first throughput number belongs to the card and the write path and not
# to a scaler or an encoder that does not exist yet.
rpi5-sd-write-bulk = ["rpi5-sd-write"]

# SD-C W6: the same 1024 sectors and the same pattern, via CMD25 bursts of at
# most one cluster.  Built on bulk so the bytes on the card can be compared
# with W5's; the W5 loop is compiled out of this image.
rpi5-sd-write-multi = ["rpi5-sd-write-bulk"]

# SD-C W7: one real frame.  Scaler + RGB565 + ROW_RLE16 enter here.  Built on
# multi so the frame uses CMD25; the W6 pattern loop is compiled out.
rpi5-sd-write-frame = ["rpi5-sd-write-multi"]
# SENSORS: the four things this board can measure about itself -- hardware
# RNG, CPU temperature, the power button, and the CPU's own performance
# counters.  Three of the four are read-only; the RNG must start its block
# before it produces words, so it is the only one that writes.  Its own
# feature so the frozen ios-home image can be shown to map neither the AVS
# monitor, the RNG, nor the GPIO bank.
rpi5-sensors = ["rpi5-ios-home-demo"]

# RTC (saat) — DA9091 PMIC üzerindeki yedek pilli saat.  Pi 5'te RTC'ye YALNIZCA
# VideoCore firmware mailbox'ından erişilir; CPU'nun adresleyebildiği bir I²C/SPI
# register arayüzü yoktur.  Tag'ler GET 0x00030087 / SET 0x00038087, seçiciler
# 0=TIME ... 7=BBAT_VOLTS (yedek pil voltajı, mikrovolt).  J5'e CR2032
# 2026-09-16'da takıldı.  Bu bayrak okuma yolunu derler; bugün üretim boot'unda
# ÇAĞRISI YOKTUR ve `simulation/tests/rpi5_rtc_source.rs` bunu kaynaktan
# doğrular.  İlk çağrı yeri (RTCPROBE makbuzu) bu bayrağın arkasına girer;
# varsayılan board-rpi5 imajı ve mühürlü R99-R181 makbuzları değişmez.
rpi5-rtc-read = []

# Yalnız saat YAZMA yolunu derler.  `RtcWriteGrant`'ı üretebilen kod olmadığı
# için çağrılamaz; bayrağın ayrı durması, okuma imajının yazma KABİLİYETİ
# olmadığının gösterilebilmesi içindir — SD yazma aşamalarındaki disiplinin
# aynısı.
rpi5-rtc-set = []

# WIFI-A0 + BT-A0: read-only inventory of the WiFi SDIO2 page and the
# Bluetooth UARTA page.  Zero commands, zero writes, zero HCI.  Separate
# from the SD and screen images so a mapping mistake cannot reach them.
rpi5-radio-inventory = ["rpi5-ios-home-demo"]

# Polled FullMAC control/escan path. Diagnostic radio images remain separate.
rpi5-wifi-scan = ["rpi5-radio-inventory"]

# R127: one-boot prerequisite sweep.  The scan image tries a single
# prerequisite-block configuration and dies on the first unanswered control
# request; this image walks a bounded matrix of configurations in one power
# cycle, re-arming ONLY on ControlTimeout and only while trial budget remains.
# Its own feature for two reasons.  First, the CCCR CARDCAP (0x000f0) write and
# the trial receipt fields exist nowhere else, so every earlier image can be
# shown to be incapable of them rather than merely not using them.  Second, the
# default path stays byte-for-byte the R126 straight-line block, so no sealed
# R99-R126 receipt is disturbed.
rpi5-wifi-sweep = ["rpi5-wifi-scan"]

# R130: add exactly one card-side recovery action to the R129 sweep.  Before
# every re-armed function-2 write, issue CCCR IO_ABORT for function 2 and
# record whether that CMD52 completed.  Kept in its own feature so rebuilding
# R127-R129 cannot silently acquire the abort.
rpi5-wifi-f2-abort = ["rpi5-wifi-sweep"]

# R131: replace R130's IO_ABORT with one verified function-2 lifecycle.  Clear
# F2 in CCCR IO_ENABLE, observe IO_READY clear, restore F2, and observe ready
# set before the re-armed write.  Block-size programming remains untouched.
rpi5-wifi-f2-reenable = ["rpi5-wifi-sweep"]

# R132: keep the verified R131 lifecycle, then sample/ack the new HOST_INT
# before the re-armed F2 write.  Kept separate from block-size programming.
rpi5-wifi-f2-post-irq = ["rpi5-wifi-f2-reenable"]

# R133: preserve the R132 chain, then reassert and verify the 512-byte
# function-2 block size immediately before the re-armed control write.
rpi5-wifi-f2-block-size = ["rpi5-wifi-f2-post-irq"]

# R134: preserve R133, then issue one host-controller-only SDHCI DATA reset
# immediately before the re-armed function-2 control write.  R134's physical
# run eliminated this action (same 0x0020 second-write failure); the feature
# remains so the sealed R134 image stays rebuildable byte-for-byte.
rpi5-wifi-host-data-reset = ["rpi5-wifi-f2-block-size"]

# R135: preserve the R133 chain (R134's eliminated send-boundary reset is NOT
# part of this image), then shape the re-armed function-2 control write with
# Linux's 64-byte short-write unit (16 zero-pad bytes).  The first bootstrap
# write keeps the R126 shape unchanged.  No card command, no host reset.
rpi5-wifi-f2-write-64 = ["rpi5-wifi-f2-block-size"]

# R138: complete the dongle host-mailbox handshake on EVERY mailbox read the
# way Linux's brcmf_sdio_hostmail does: acknowledge the data (SMB_INT_ACK to
# tosbmailbox) whether or not the value changed, and rewrite the protocol
# version to tosbmailboxdata whenever DEVREADY/FWREADY is reported.  R137
# measured zero mailbox changes with FWREADY never set; this feature changes
# only the timing of two writes that already exist.  No new register, reset,
# card command or frame byte.
rpi5-wifi-hostmail-complete = ["rpi5-wifi-sweep"]

# R139: write the CR4 reset vector the way Linux's brcmf_sdio_buscore_activate
# does — a 4-byte CMD53 with the SB_ACCESS_4B flag at backplane address 0 —
# with the validated CMD52 write as a bounded fallback.  R88 tried this before
# R94 reworked the CMD53 data-line discipline and it failed with data CRC
# 0x0060; the R139 desk measurement showed every other CR4-start value already
# matches Linux, so the transport of this one write is the remaining
# structural difference on the critical path.
rpi5-wifi-rstvec-cmd53 = ["rpi5-wifi-scan"]

# R140: the "host ready" handshake moves to the position Linux measured.  Linux
# writes SDPCM_PROT_VERSION << 16 to tosbmailboxdata (0x18004048) inside
# brcmf_sdio_firmware_callback (sdio.c:4261-4262) immediately after the CR4 is
# released — the R139 Linux wire trace puts it 74 us after the release ioctl and
# *before* F2 enable and before hostintmask — while R136-R139 wrote the same
# value seconds later, in the protocol-phase mail watch.  One write changes
# place; the protocol-phase watch keeps R138's acknowledgement but no longer
# repeats the version.  The same feature adds a read-only early witness that
# samples tohostmailboxdata/intstatus for ~600 ms after the write, so the
# dongle's DEVREADY and FWREADY timings become visible.
rpi5-wifi-hostready-at-start = ["rpi5-wifi-rstvec-cmd53"]

# R141: answer the dongle's mailbox interrupt where it happens.  R140 moved the
# "host ready" version write to the Linux position and the dongle answered with
# FWREADY 30 ms later (INTSTATUS 0x208000c0) — the first such signal in this
# project — but the R140 window was read-only, so the handshake was never
# acknowledged and the mailbox fell back to DEVREADY.  This feature performs
# exactly what Linux's ISR does in the same window: acknowledge the mailbox
# (SMB_INT_ACK to tosbmailbox) after each read and write-1-to-clear the observed
# intstatus bits, then close the window early once the handshake settles.
rpi5-wifi-mailbox-answer-at-start = ["rpi5-wifi-hostready-at-start"]

# R142: in a polling design the card must not drive the DAT1 interrupt line.
# R141's failure receipt measured HOST_CARD_INT=true with
# SDHCI_INT_SIGNAL_ENABLE=0 while the F1 4-byte CMD53 reads died with data CRC,
# and the permission to drive DAT1 comes from the CCCR INT_ENABLE pair this
# driver writes (0x03 then 0x07).  The same two writes now clear the master
# interrupt bit (0x02 then 0x06); the F1/F2 function bits are unchanged.
rpi5-wifi-int-enable-off = ["rpi5-wifi-mailbox-answer-at-start"]

# R143: the card's permission to drive DAT1 is the SDIO core host interrupt mask
# (0x18004024), which the R121 prerequisite block writes as 0x200000f0 to mimic
# Linux.  R142 cleared the CCCR master bit and the card still drove DAT1
# (HOST_CARD_INT=true, READ_FAILURES=5 again), so the gate is here.  A polling
# design reads intstatus directly and needs no host interrupt line: the mask is
# written as 0 instead.
rpi5-wifi-hostintmask-off = ["rpi5-wifi-int-enable-off"]

# R193: the DTB's sdio2_30_pins asks for bias-pull-up on CMD and DAT0..3 and no
# pull on CLK; Linux applies that before the card is powered, AselsanOS only
# wrote the mux.  This applies exactly those twelve pad bits (words 5 and 6 on
# D0, Linux pinctrl-bcm2712.c layout) before WL_ON and CMD0.
rpi5-wifi-sdio-pulls = ["rpi5-radio-inventory"]

# R194: Linux keeps tx_hdrlen at 12 and only adds the 8-byte glom extension
# after the dongle accepts "bus:rxglom = 1" (brcmf_sdio_bus_preinit).  This
# image never sends that request yet has used the glom layout since its first
# control frame.  R193 cleared the bus (CMD52_FAIL=0, no data CRC) and the
# frame went out (SENT=1) with no reply; the layout is the remaining measured
# difference, so this feature encodes control frames without the extension.
rpi5-wifi-plain-control = ["rpi5-wifi-scan"]

# R195: the dongle answers a SET request with the BCDC SET bit CLEARED.  R194's
# sealed capture measured it: request cmd=263 id=3 set=1, reply flags=0x00030000
# (id=3, set=0).  The reply was the right one ("bus:txglom") but the parser
# rejected it as DirectionMismatch and the session timed out.  brcmfmac matches
# a reply on the request id alone (brcmf_proto_bcdc_cmplt), so this feature
# drops the direction bit from the match.
rpi5-wifi-set-reply = []

# R196: R195'in FWREADY sonrasindaki ilk F1 INTSTATUS CMD53 okuması,
# SDHCI PRESENT_STATE=0x01ff0206 ile 100k pasif yoklama sonunda hâlâ
# DAT_INHIBIT/data-active durumunda kaldı ve hiç CMD53 issue edilmedi.  Bu
# deney, daha önce CR4 hazırlığında ölçülmüş host-only SOFTWARE_RESET.DAT
# yolunu yalnızca bu erken busy kapısında dener; reset doğrulanmazsa komut
# yine gönderilmez.  Kart/core reseti, CMD52 ve sağlıklı transfer yolu yok.
rpi5-wifi-preissue-data-reset = ["rpi5-radio-inventory"]

# R198: cr4_start Activation fazinda INTSTATUS clear (0x18004020 → 0xFFFFFFFF)
# CMD52 ile yazilirken ERROR_STATUS=0x0010 aliyor ve preinit baslayamadan
# abort ediliyor.  Bu feature, CMD52 hatasi durumunda settle_card() + 100 µs
# bekleme ardindan CMD53 (backplane_write32_cmd53) ile bir kez retry yapar.
# Retry de basarisizsa hatayi logla ama devam et — firmware zaten INTSTATUS'u
# kendi icinde temizleyebilir.
rpi5-wifi-intstatus-retry = ["rpi5-radio-inventory"]

# R199a: INTSTATUS clear'i tamamen atla.  CMD52 ERROR_STATUS=0x0010 ile
# basarisiz oluyor, CMD53 retry de basarisiz (R198).  Firmware kendi
# INTSTATUS latch'larini temizliyor olabilir; bu imaj clear adimini atlayip
# FWREADY'nin gelip gelmedigini olcer.
rpi5-wifi-intstatus-skip = ["rpi5-radio-inventory"]

# R199b: CMD52 basarisiz → 200 µs bekle → tekrar CMD52 dene.
# R197'de CMD52 ERROR_STATUS=0x0010, R198'de CMD53 retry de basarisiz.
# Belki SDIO bus daha fazla zamana ihtiyac duyuyor; 200 µs bekleyip
# ayni CMD52 yolunu tekrar denemek tek degisken.
rpi5-wifi-intstatus-cmd52-retry = ["rpi5-radio-inventory"]

# R199c: INTSTATUS clear'i HT clock gecisinden sonraya tasi.
# Belki HT aktif olmadan INTSTATUS yazilmiyor; clear'i cr4_start
# icinde HT gecisinden sonraya kaydir.
rpi5-wifi-intstatus-post-ht = ["rpi5-radio-inventory"]

# R200: after session.start(), leave Function 2 FIFO traffic to the SDPCM
# transport. The old R185/R190 debug block issued five unconditional F2 reads
# before Function 2 readiness was checked, then reset DAT and waited 19 ms.
# This opt-in candidate removes that entire out-of-band diagnostic sequence.
rpi5-wifi-runtime-owned-fifo = ["rpi5-wifi-scan"]

# R201: a consumed header-only SDPCM frame completes the pending receive
# indication. A fresh INTSTATUS/host-mailbox indication can arm the next read;
# do not issue a second F2 read solely because the old flag stayed set.
rpi5-wifi-header-only-one-shot = ["rpi5-wifi-scan"]

# R202: the measured preinit second frame is a 64-byte F2 transfer. R201
# reaches it twice but block mode returns SDHCI DATA_TIMEOUT=0x0010 after
# transfer complete. Test byte mode for this exact length only.
rpi5-wifi-f2-64-byte-mode = ["rpi5-wifi-scan"]

# R203: keep the R202 frame bytes and transfer modes, but run the post-stage
# SDIO clock at 25 MHz instead of 50 MHz to test the repeated DATA_CRC latch.
rpi5-wifi-sdio-25mhz = ["rpi5-radio-inventory"]

# R205: for the discovered SDIO core INTSTATUS only, use checked CMD52x4
# instead of a CMD53 read that repeatedly latches the host data engine.
rpi5-wifi-intstatus-cmd52 = ["rpi5-radio-inventory"]

# R206: R194's physically answered bootstrap (plain GET cur_etheraddr,
# SDPCM sequence 255, no preinit burst) on top of R205's checked INTSTATUS.
# This affects the bootstrap only; subsequent controls still use the current
# transport, including SET-reply matching. It is an A/B trial, not a claim
# that the measured Linux preinit is invalid.
rpi5-wifi-r194-bootstrap = ["rpi5-wifi-scan"]

# R144: an intermittent data-line CRC on the poll's intstatus read must not end
# the trial.  The transport layer already performs a bounded recovery (SDHCI
# reset + one read; WIFIREAD_RECOVERY reports RECOVERY_OK=1 POST_READ_OK=1
# POST_VALUE=Some(0)) but still propagates the error, and R141/R142/R143 all
# died exactly there.  With this feature the read is taken once more after that
# recovery and only a second failure fails the trial.  Error path only: no new
# register, value, frame, clock or reset.
rpi5-wifi-poll-retry = ["rpi5-wifi-hostintmask-off"]

# R145: the same single-retry rule moves to the F2 frame reads.  R144 reached
# the protocol phase for the first time (interrupt_status_or=0xc0, FRAME_IND=1,
# HOST_INT=1) and died on the first F2 read: Cmd53Read fn=2 addr=0x8000,
# command_complete=true, buffer_ready=true, transfer_complete=false,
# bytes_read=64, error_status=0x20, timeout_transfer=true.  With this feature
# both FIFO reads are taken once more after the transport layer's bounded
# recovery; a second failure stays fatal.  Read geometry unchanged.
rpi5-wifi-fifo-retry = ["rpi5-wifi-poll-retry"]

# R146: read-only.  brcmfmac learns the dongle's state from the SDPCM shared
# area whose address sits in the last 4 bytes of RAM (brcmf_sdio_readshared);
# its flags word reports the firmware's own ASSERT/TRAP/FAIL state and carries
# the assert line/file and console addresses.  R145 measured a transport that
# carries eight trials with the mailbox parked at DEVREADY and no interrupt, so
# the missing information is what the dongle itself publishes.  This feature
# reads that pointer and the structure once, at the END of the run, with the
# ChipCommon chipid as a before/after sentinel; it writes nothing.
rpi5-wifi-shared-witness = ["rpi5-wifi-fifo-retry"]

# R147: read-only continuation of R146.  The dongle reported itself healthy and
# published a console address (W5_CONSOLE=0x0025debc), which is where the
# firmware keeps its own log text (Linux dumps it in brcmf_sdio_dump_console).
# This feature reads the console header, picks the first aligned RAM pointer
# found in it as the log buffer, dumps 128 bytes from it and 128 bytes from the
# console address itself, and prints the printable characters.  Nothing is
# written; the read stays at the end of the run behind a chipid sentinel.
rpi5-wifi-console-witness = ["rpi5-wifi-shared-witness"]

# R148: the console dump reads the WHOLE log.  R147's second boot read the first
# 128 bytes and showed the firmware's own wl0 lines ("wlc_channels_commit: no
# valid channel ...", "Broadcom BCM4345"), with the header measuring the buffer
# (W2=buf 0x0025dab4, W3=size 0x400, W4=idx 0x177 = 367 bytes written).  This
# feature reads the full buffer (<=1024 bytes) and prints all printable text,
# and retries the chipid sentinel a bounded number of times before the console
# read (R147 recorded SENT_B_OK=0 after the shared-area read).  Read-only.
rpi5-wifi-console-full = ["rpi5-wifi-console-witness"]

# R149: one bit — FORCE_HT.  Linux writes CHIPCLKCSR = saveclk | FORCE_HT
# (0xd2) immediately after releasing the CR4 (R139 wire trace t=143.630589);
# this driver's terminal value is 0xd0.  R148's full console dump shows the
# firmware writing "wl0: wlc_stf_txcore_shmem_write: No clock" and then losing
# its SDPCM datapath ("sdpcmd_dpc: Disable" -> "sdpcmd_tx: device disabled" ->
# "sdpcmd_sendheader: tx submit failed!!") exactly when our control frame was
# submitted.  This feature writes Linux's measured value.
rpi5-wifi-force-ht = ["rpi5-wifi-console-full"]

# R150: leave the D11 (PHY/TX) core out of reset.  R148/R149's firmware console
# reports "wl0: wlc_stf_txcore_shmem_write: No clock"; the R139 Linux wire trace
# contains no D11 reset-control write at all (only ioctl 0x07 =
# PHYCLOCKEN|FGC|CLK), while this driver asserts the reset and leaves it — and a
# core held in reset has no clock.  The reset is still asserted and verified as
# before; this feature releases it afterwards.
rpi5-wifi-d11-release = ["rpi5-wifi-force-ht"]

# R151: host-side timeline.  R150's console log carries the firmware's own
# timestamps ("000006.082 sdpcmd_dpc: Disable") while the host side has none, so
# the trigger of the repeating datapath-disable cannot be identified.  This
# feature records the CR4 release instant and stamps the critical host events
# (trial start/result, between-trial recovery, F2 enable, console read) with ms
# since that instant.  No behaviour changes; values, frames and resets are
# untouched.
rpi5-wifi-host-timeline = ["rpi5-wifi-d11-release"]

# R152: the R151 timeline produced T_MS=0 for every event because
# host_now_ms() divided by a frequency that is not yet cached on its first call
# (the T0 line printed 2018624513 = raw counter ticks).  This feature makes the
# ms source initialise the frequency itself, so the measurement R151 armed can
# actually be read.  Nothing else changes: still measurement only.
rpi5-wifi-timeline-fix = ["rpi5-wifi-host-timeline"]

# R153: the first control frame's SDPCM sequence byte.  This driver started at
# 255 (SDPCM_SEQ_WRAP-1); Linux's sealed measurement
# (linux-r136-first-frame-v3/decoded-pass1.txt) shows a small, increasing value
# (byte4_seq=0x02), and brcmfmac sets its counter to SDPCM_SEQ_WRAP-1 but
# increments before sending, so its first frame carries 0.  R152's aligned
# timeline showed that our frame is what makes the dongle disable its datapath
# and fail the tx submit; this is the one measured frame-byte difference left.
rpi5-wifi-seq-zero = ["rpi5-wifi-timeline-fix"]

# R154: the FIRST control frame's content.  Linux's sealed first (preinit) frame
# is a SET, not the GET this driver sends: cmd=263 (WLC_SET_VAR),
# flags=0x00040002 (id=4, SET), len=20, data "cur_etheraddr\0" + the 6-byte MAC
# measured on the same card (linux-r136-first-frame-v3).  The wire format stays
# R136's glom layout with dat_offset=20; only the dcmd content changes, and only
# for the first frame of the session.
rpi5-wifi-preinit-first = ["rpi5-wifi-seq-zero"]

# R155: measurement only.  The read-error recovery receipts (WIFIREAD_RECOVERY)
# carry an SDHCI line reset and had no timestamp, so the dongle's repeating
# "sdpcmd_dpc: Disable" could not be attributed to either our control frame
# (constant ~326 ms earlier) or our own bus reset.  This feature adds T_MS to
# that receipt; nothing else changes.
rpi5-wifi-recovery-timeline = ["rpi5-wifi-preinit-first"]

# R157: glom negotiation.  Linux's sealed preinit sequence sends its first two
# control frames WITHOUT the glom extension (data_offset 12) and negotiates glom
# only in the second frame (SET bus:rxglom = 1); this driver has been sending
# glom frames from the very first one.  R156's alignment showed the dongle
# disables its datapath right after our frame, so this feature replays the
# measured three-frame sequence byte for byte (two plain, then the glom
# cur_etheraddr frame).
rpi5-wifi-glom-negotiation = ["rpi5-wifi-recovery-timeline"]

# R158: drain before write.  In both R157 boots the F2 write failed
# (WriteFifo, F2 0x8000) while the dongle had frames indicated
# (CORE_OR=0xc0), so the measured preinit sequence never went out (SENT=0).
# Linux drains the pending SDPCM frames before its DPC writes a control frame;
# this feature keeps the preinit send behind the existing idle-queue gate.
rpi5-wifi-drain-first = ["rpi5-wifi-glom-negotiation"]

# R159: the F2 write unit for the plain (pre-negotiation) control frames.  Linux
# writes every short control frame to F2 0x8000 as a 64-byte unit (all R80/R136
# trace writes are 64 bytes; R135's note: "never 48 B").  Our first plain frame
# is 57 bytes, 4-byte aligned to 60, and that write is the one that failed with
# WriteFifo in both R157 boots and in R158's third boot, while the 8-byte-aligned
# glom frames had been accepted earlier.
rpi5-wifi-f2-write-unit = ["rpi5-wifi-drain-first"]

# R160: the ACCEPTANCE rule for that one F2 write.  R159's sealed WIFIREAD
# receipt shows the write was not refused by the card: ISSUED=1
# COMMAND_COMPLETE=1 BUFFER_READY=1 TRANSFER_COMPLETE=1 BYTES_READ=64,
# R5_FLAGS=0x10 (no bit of R5_ERROR_MASK) and the only complaint is SDHCI's
# data-CRC flag (ERROR_STATUS=0x0020).  The completeness predicate nevertheless
# fails the transfer because it requires error_status == 0, so the measured
# preinit sequence dies on its first frame.  This feature accepts exactly that
# measured class - a COMPLETED write with the exact requested byte count whose
# only error bit is the data CRC - counts it, prints it and continues.  Every
# other failure stays fatal; nothing is forgiven silently.
rpi5-wifi-f2-crc-accept = ["rpi5-wifi-f2-write-unit"]

# R161: the SCOPE of that verified rule.  R160 proved the class (completed
# transfer, exact byte count, no R5 error, only SDHCI's data-CRC bit) and the
# measured Linux preinit sequence went out for the first time (SENT=3, console
# "Disable" 0).  The run then died on the very next write - the ordinary 56-byte
# control frame in `send_control` - with the SAME measured class, because R160
# scoped the acceptance to the preinit sequence only.  This feature applies the
# identical pure rule to every SDPCM F2 write and counts them separately.
rpi5-wifi-f2-crc-scope = ["rpi5-wifi-f2-crc-accept"]

# R162: the IDENTITY of the control frames that follow the measured preinit
# sequence.  R161's sealed log (and R160's) shows the same requests going out
# twice: the preinit sequence sends dcmd ids 2, 3, 4 and the trial path then
# sends 4, 2, 3, 4.  The sealed Linux frame list increments the dcmd id for every
# single request (0x8f, 0x90, 0x91 ...) - ids are unique and monotonic.  At each
# of our repeated frames the dongle's own console disables its SDPCM TX
# ("sdpcmd_dpc: Disable", "sdpcmd_tx: device disabled",
# "sdpcmd_sendheader: tx submit failed!!").  This feature continues the id after
# the preinit sequence and stops replaying a request the dongle already received.
rpi5-wifi-ctrl-id-continuation = ["rpi5-wifi-f2-crc-scope"]

# R163: yazma öncesi F2 yaşam döngüsü "önce SOR" olur.  R162'nin mühürlü
# kaydı, her deneme öncesi yapılan F2 disable/re-enable toggle'ının dongle'ın
# kendi `sdpcmd_dpc: Disable` + `sdpcmd_tx: device disabled` +
# `sdpcmd_sendheader: tx submit failed!!` üçlüsüyle milisaniye düzeyinde
# çakıştığını ölçtü (her denemede bir kez, ≈2,98 s periyot); toggle yapmayan
# preinit yazmalarında ise o üçlü hiç görünmüyor.  Bu özellik F2 zaten açık ve
# READY ise dongle'ın SDIO cihazını kapatmaz; yalnız gerçekten hazır değilse
# R131 yaşam döngüsünü uygular.  Kayıt değerleri, çerçeve baytları ve diğer her
# şey aynı kalır.
rpi5-wifi-f2-ready-first = ["rpi5-wifi-ctrl-id-continuation"]

# Hands-free koşu altyapısı (RADYO DEĞİŞKENİ DEĞİL): BCM2712 PM watchdog'unu
# kurup saniyede bir besler ve konsol UART'ından `R` baytı gelince donanım
# resetini tetikler. Çerçeve baytlarına, SDPCM sırasına, kabul kuralına ve
# hiçbir SDIO kaydına dokunmaz; adresler kendi DTB'mizden ölçülmüştür
# (`watchdog@7d200000` -> 0x107d200000). Makbuzları: WIFIAUTORESET_PLAN,
# WIFIAUTORESET ARMED/RESET/RESULT. Açık olduğu imajlar mühründe
# `automation=rpi5-auto-reset` yazar.
rpi5-auto-reset = []
# Runtime-safe remote reset: polls the console UART for `R` and performs an
# immediate PM reset, but never arms a countdown watchdog. EBD050 production
# profiles use this so an idle or stalled service cannot reboot periodically.
rpi5-uart-reset = []

# R164 (ALTYAPI, radyo değişkeni DEĞİL): soğuk kart SD başlatması. Bugüne kadar
# her koşu SD'den boot ediyordu ve firmware kartı bizim için başlatıyordu;
# `read_block` bu "devralınan durum"a sessizce bağımlıydı. Netboot'ta bootloader
# karta hiç dokunmaz, bu yüzden FWREAD PART_LBA=0 VOL_OK=0 ölçüldü (2026-09-14,
# attempt-r163-f2-ready-first-uart-capture-repeat-01). Bu özellik açıkken önce
# devralınan yol denenir; yalnız kullanılamıyorsa SD spesifikasyonunun zorunlu
# kıldığı soğuk başlatma dizisi uygulanır ve okuma yinelenir. SD boot'ta dal hiç
# çalışmaz; karta yazma komutu üretilmez (CARD_WRITES=0).
rpi5-sd-cold-init = []

# Hands-free (ALTYAPI, radyo değişkeni DEĞİL): Wi-Fi payload'ını (BRCMFW.BIN,
# BRCMNVR.TXT, BRCMCLM.BLB) firmware'in `initramfs` mekanizmasıyla ağdan taşı ve
# FAT bölümü okunamadığında oradan kullan. Netboot'ta bootloader SD karta hiç
# dokunmadığı için FAT yolu düşüyor (ölçüldü: FWREAD PART_LBA=0); SD boot'ta bu
# dal hiç çalışmaz ve mevcut tüm makbuzlar yeniden kurulabilir kalır.
rpi5-fw-initramfs = []

# R165: okuma öncesi SINIRLI host-idle kapısı.  R163'te süpürmenin ikinci
# denemesi F1 INTSTATUS okumasında (`PRESENT_STATE=0x01ff0206` =
# DAT_INHIBIT|DAT_LINE_ACTIVE) düştü; R164 netboot koşusunda aynı nokta
# `Session(CommandDeadline(Mac))` olarak göründü.  Kapı, R114/R115'te fiziksel
# olarak kanıtlanmış `bounded_host_idle_poll`/`runtime_host_idle` çiftini okuma
# yoluna uygular: bekleme SINIRLIDIR ve sayıları makbuza girer.  Yazma yolu,
# çerçeve baytları ve tüm kayıt değerleri değişmez.
rpi5-wifi-read-gate = ["rpi5-fw-initramfs"]

# R166: okuma-hatti kurtarmasinin SINIRLI reset butcesi.  R163'un muhurlu
# makbuzu latch'in ILK olayda R116 reset'iyle acildigini (RESET_POLLS=2,
# ELAPSED_US=10, CLEARED=1) ve AYNI trial icinde tekrar armedigini olctu; ikinci
# olayda butce yoktu (USED_BEFORE=1 ELIGIBLE=0) ve supurme TRIALS_RUN=1'de
# kapandi.  R166 yalnizca kac olayin karsilanacagini degistirir; adres, hata
# sinifi, pasif sinir, DAT0/CMD kosullari ve reset dizisi aynen kalir.
rpi5-wifi-reset-budget = []

# R167: R127'nin State::Failed'dan TEK sinirli cikisina kabul edilen hata
# sinifini genisletir: ControlTimeout -> ControlTimeout + CommandDeadline.
# R166'nin muhurlu makbuzu duvari adiyla verdi: butce tukenmedi (BUDGET=4,
# USED_BEFORE 0->1->2) ve uc kurtarma da kabul edildi, ama kosu
# `STOP=NOT_REARMABLE` ile kapandi: oturum katmaninin adim zaman asimi
# (`Error::CommandDeadline(Step)`, brcmf_scan.rs) transport poll'undan ONCE
# donuyor, bu yuzden R127 uygunlugu (yalniz ControlTimeout'ta latch'li) hic
# kurulmuyor.  Baska hicbir sey degismez: kredi kurali, silahli supurme kosulu,
# profil siniri, prereq_stop adlari, reset butcesi, okuma kapisi, yazma yolu,
# cerceve bicimi ve Transport/Wire/Firmware siniflarinin fatal davranisi aynen.
rpi5-wifi-rearm-deadline = ["rpi5-wifi-sweep"]

# R168: okuma latch'inin NEDEN yeniden armlan-digini olcen SALT-OKUNUR tanik.
# R167'nin muhurlu makbuzu ayni okuma adresinde dort kurtarmanin da kabul
# edildigini ve butcenin 4/4 tukendigini gosterdi; latch her alisveriste yeniden
# armlaniyor ama nedeni olculmedi (kart kredisi mi, bekleyen veri sahipligi mi).
# Tanik yalniz CMD52 OKUMALARI yapar (CCCR IO_ENABLE/IO_READY/INT_PENDING/
# BUS_IFACE) ve R116/R119 karari HESAPLANDIKTAN SONRA kosar (R117 matrisi gibi);
# donen degeri ya da yuzeye cikan hatayi degistiremez.  Deponun sirasi once
# tanik sonra mekanizmadir (R114/R115 -> R116, R117 -> R119, R146 -> kullanim).
rpi5-wifi-read-owner = []

# R169: R168'in tanigi latch aninda karti SAGLIKLI buldu (F2 hem etkin hem
# hazir, komut inhibit temiz, DAT0 birakilmis, host bosta), yani yeniden
# armlanmanin nedeni kart sahipligi degil.  Kalan aday kredi: R169, tasima
# katmaninin tx_window/tx_sequence alanlarini her mutasyonda brcmf_sdio icindeki
# census tarzi atomiklere yayinlar ve okuma yolu latch aninda onlari SALT OKUR.
# Yeni kayit yazimi, yeni komut dizisi, reset/retry/CMD53 yinelemesi yok; makbuz
# WRITES=0 Kanitlar.
rpi5-wifi-credit-witness = []

# R170: R169'un kredi tanigi latch anina bagliydi ve latch alti boot'ta bir
# goruldu; degisken uc boot'ta da ICRA EDILEMEDI.  Olcumun kendisi tetikleyiciyi
# adlandirdi: kredi latch aninda degil, HER TUR SINIRINDA okunabilir.  R170
# yalnizca ornekleme anini degistirir (latch -> tur siniri); ayni atomikler,
# ayni salt-okuma, ayni WRITES=0.  Boylece kredi, latch'e bagli olmadan boot
# basina 11 ornekle karakterize edilir.
rpi5-wifi-credit-sample = []

# R171: do not transmit a control frame until the dongle has reported
# HMB_DATA_FWREADY. The gate is a bounded mailbox-read barrier only; it adds
# no frame, reset, retry or register write to the R170 path.
rpi5-wifi-fwready-gate = []

# R172: enable function 2 where Linux does — inside the early mailbox window,
# right after the "host ready" version write — instead of seconds later in the
# protocol phase.  R171's own sealed capture shows the dongle DID answer with
# FWREADY (WIFIEARLYMBOX ... FWREADY_MS=25, WIFIMBOXANSWER SETTLED=1) while the
# R171 gate, armed in the protocol phase, still read FWREADY_SEEN=0, because the
# pulse had already reverted to DEVREADY-only.  This feature moves one write
# (CCCR IO_ENABLE bit for F2) and adds a read-only persistence witness; frame
# bytes, SDPCM sequence, credit, resets and retries are unchanged.
rpi5-wifi-f2-at-start = []

# R173: the protocol-phase mailbox watch stops deferring the version rewrite
# and re-arms it whenever the dongle still reports a readiness bit.  R140
# deferred the write because it was measuring WHERE the "host ready" write
# happens; R172 then measured what the deferral costs — the ACK path consumes
# the readiness interrupt on every read, the dongle drops the bit unless the
# host confirms it again, and the eleven trials still went unanswered.  This
# feature issues the same write (same register, value and command) whenever
# DEVREADY/FWREADY is still present, and records when the bit had already
# reverted.  No frame, sequence, credit, reset or retry is added.
rpi5-wifi-fwready-preserve = []

# R174: after the sweep ends, read the dongle's own shared area ONCE and print
# the structure pointer, its flags word and the console address.  R173 left two
# possibilities that need different next gates — the control frame never
# reaches the firmware's data path, or it arrives and is not answered.  The
# end-of-run console dump that already exists reads the same structure, so the
# write index of the two reads can be compared: if the firmware kept writing
# while our control frames were pending, the index moves.  Read-only; no
# register is written and the frame path is untouched.
rpi5-wifi-fw-probe-at-end = []

# R175: the host-side half of the R174 decision.  R174 measured that the dongle
# wrote nothing during the protocol phase (console index identical to R173,
# flags unchanged, no trap/assert), so the frame did not reach a live data path;
# the next gate is the exact bytes of our first control frame against Linux's
# measured first control frame on the same card.  Deriving those bytes from the
# sealed trace (scripts/extract-linux-preinit-frames.py) shows the first frame
# is the transport-start `bus:txglomalign` SET that R157's three-frame sequence
# skipped, that the measured `ulp_sdioctrl` reply area is 16 bytes (not 15), and
# that Linux writes ALIGN8(frame_len) bytes (48/64/48/56) rather than a fixed
# 64-byte unit.  This feature sends the measured sequence frame for frame and
# records each frame's raw bytes; it adds no register write, reset or retry.
rpi5-wifi-preinit-measured = []

# R175: retire an eliminated hypothesis.  R173 re-armed the readiness version
# write on every protocol-phase mailbox read and the sealed run wrote it 113
# times without the dongle returning to FWREADY.  Hypothesis eliminated; the
# operator decision is to stop chasing it: the same write may be issued at most
# FWREADY_PRESERVE_MAX_WRITES (3) times per run and is then abandoned, with a
# receipt flag.  Same register, value and command; only the repetition bound is
# added.
rpi5-wifi-fwready-cap = []

# R176: the single remaining host-side frame difference.  R175 made the four
# preinit frames byte-identical to Linux's measured sequence on the same card
# and the dongle still answered nothing (REPLIED=0), so frame content and
# ordering are eliminated.  The first frame we still do not match is the
# measured sequence's FIFTH: glom layout, seq=3, cmd=98 (not GET_VAR/SET_VAR),
# id=5, declared dcmd len 68, and a data area that carries no iovar name -
# `evidence/rpi5/radio/linux-r136-first-frame-v3/trace-pass1.raw` line 160,
# where the dongle ANSWERS it (lines 162/164, 96 bytes, vendorid 0x14e4).  Our
# sweep sends GET `cur_etheraddr` at that same point.  This feature makes the
# measured fifth frame the first control frame; `Step::Mac` follows it.  The
# preinit sequence, the transfer unit, the sequence continuation (3), the
# acceptance rule and R173's 3-write bound are all frozen.
rpi5-wifi-revinfo-first = []

# R177 TEK DEGISKEN: CR4 birakildiktan SONRA, tosbmailboxdata yazisindan ONCE
# CHIPCLKCSR'ye HT clock istek dizisi gonder (Linux brcmf_sdio_firmware_callback).
# Firmware konsolundaki "No clock" satirinin karsiligi: PMU, CR4 birakildiktan
# sonra HT taleplerini sifirlamis olabilir; Linux bu noktada CHIPCLKCSR'yi
# temizleyip yeniden HT_AVAIL_REQ yazar ve HT_AVAIL gelene kadar bekler.
rpi5-wifi-post-cr4-clock = []

# R180 TEK DEGISKENI: send_control() F2 yazmasindan HEMEN SONRA, bekleme
# dongusune girmeden ONCE, INTSTATUS oku + kosulsuz F2 FIFO okumasi yap.
# Amac: REPLIED=0 gercek sessizlik mi yoksa olcum artefakti mi?
# FIFO_READS=0 kesme gelmedigi icin mi yoksa okuma yolu hic kosmadigi icin mi
# oldugunu ayirir. SDPCM basligi cozulurse tumleyen gelmesi REPLIED'dan
# bagimsiz gorunur olur. Yazma yolu, cerceve icerigi, preinit sirasi ve
# sinirlar DONUK kalir.
rpi5-wifi-f2-post-send = []

# Source-only Layer-2 ownership/rate-graph contracts. This feature exposes no
# production callsite and performs no automatic MMIO.
rpi5-layer2-source = []
snippet sha256: 05de495405ca…file sha256: 05de495405ca…
02 · Kapı kimlik kaydı

Operations sıra, kimlik ve başlık bağı

tam Operations kaydıL35237–L35254
website/src/lib/operations.ts::workspace-test-harness
  {
    id: "workspace-test-harness",
    date: "2026-08-19",
    sequence: 3,
    status: "fixed",
    title: "Workspace test harness çakışması düzeltildi",
    summary:
      "Bare-metal kernel binary'sinin std test harness'e bağlanıp ikinci panic handler üretmesi engellendi.",
    evidence: [
      "kernel/Cargo.toml içindeki explicit bin hedefinde test=false ve bench=false tanımlandı.",
      "Önceki duplicate panic_impl bağlama hatası kalktı.",
      "cargo test --workspace exit 0 ile tamamlandı.",
    ],
    commands: ["cargo test --workspace"],
    limitations: [
      "Bu tarihsel koşuda simülasyon paketi 0 test bildirmişti; daha sonra eklenen dört davranışsal testin sonucu en üstteki tam doğrulama kaydında tutulur.",
    ],
  },
snippet sha256: c6b0a20a7cdb…file sha256: 9726dbf00f84…
Kayıtlı yürütme/kanıt komutu
cargo test --workspace
Registry schema v5 · generator website/scripts/generate-code-gates.mjs · Tam SHA-256: e6b8ce4d7b482f438654456fa8860f0bf0a1086ec522ad20d9bfd83cfffc0520