Commit Graph

2177 Commits

Author SHA1 Message Date
kellito 8157eda85f v5.1: cpufreqd scheme server - real cpufreq scheme, no more stub
G-A2 from DRIVER-MANAGER-MIGRATION-PLAN v4.8: thermald was
silently failing to switch governors because cpufreqd provided
no 'cpufreq' scheme. thermald writes /scheme/cpufreq/governor
(thermald/src/main.rs:38, :348-358); cpufreqd only wrote
/scheme/cpufreq/state via fs::write - the path was a stub.

Fix: cpufreqd now registers the 'cpufreq' scheme at startup via
redox-scheme::scheme::register_sync_scheme, exposing a real
Linux-compatible interface.

Path surface (read-write where noted):
- /scheme/cpufreq/governor                      (rw - global default)
- /scheme/cpufreq/cpu<N>/scaling_governor       (rw - per-CPU override)
- /scheme/cpufreq/cpu<N>/scaling_cur_freq       (ro)
- /scheme/cpufreq/cpu<N>/scaling_min_freq       (ro)
- /scheme/cpufreq/cpu<N>/scaling_max_freq       (ro)
- /scheme/cpufreq/cpu<N>/cpuinfo_min_freq       (ro)
- /scheme/cpufreq/cpu<N>/cpuinfo_max_freq       (ro)
- /scheme/cpufreq/cpu<N>/scaling_available_governors (ro)
- /scheme/cpufreq/cpu<N>/cpuinfo_cur_freq       (ro - alias)
- /scheme/cpufreq/control/governor              (rw - alias, thermald fallback)
- /scheme/cpufreq/state                        (ro - existing key=value)

Implementation:
- scheme.rs (NEW, 639 lines): SchemeSync impl, path parsing,
  per-CPU vs global governor resolution, atomic-rename
  persistence of last governor.
- main.rs: governor -> Arc<Mutex<Governor>>, cpus ->
  Arc<Mutex<Vec<CpuInfo>>>, spawn scheme server, removed the
  fs::write('/scheme/cpufreq/state') stub line, added
  Governor::as_str()/from_name(), 4 pre-existing clippy
  collapsible_if warnings fixed.
- Cargo.toml: added redox-scheme, libredox, syscall (redox_syscall)
  path deps with [patch.crates-io] per local AGENTS.md rules.

Lock ordering documented inline: governor -> overrides -> cpus.
Main loop snapshots governor+overrides before locking cpus so
the scheme server can never deadlock against it.

Linux-compat extras added (real functionality, not stubs):
scaling_available_governors (root + per-CPU), cpuinfo_cur_freq
alias, control/governor alias, getdents on all directories.

Per-CPU override behavior matches Linux: writing global governor
clears all per-CPU overrides; writing cpu<N>/scaling_governor
sets a per-CPU override. Main loop honors overrides via
effective_governor() each tick.

state format: now emits lowercase governor names (governor=ondemand)
instead of the old {:?} (governor=Ondemand). This matches
redbear-power's lowercase expectations.

Tests: 21 new (governor name parsing case-insensitive + rejection
of invalid, Arc<Mutex> round-trip, global-write-clears-overrides,
path parsing for cpu0/scaling_governor/governor/control/governor,
unknown-CPU/leaf rejection, per-CPU override fallback, frequency
helpers, state format backward compat, integration test). All pass.

Compile: cargo check --target x86_64-unknown-redox - zero new
warnings (only pre-existing libredox FFI warnings).

Constraints per local/AGENTS.md:
- No new branches (work on 0.3.1)
- No new Cat-2 dependencies (redox-scheme is already a path-dep)
- No stubs, no todo!/unimplemented!
- Cat 1 in-house recipe - source IS the durable location

Closes v5.1 of the v5.x work program. Closes G-A2 from v4.8.
2026-07-26 00:22:32 +09:00
kellito 045aaa4579 v5.5: boot race instrumentation - claim/firmware/aer latency buckets
Surfaces four boot-race latency metrics as a structured JSON
endpoint at /scheme/driver-manager/timing, plus a per-bucket
p50/p95/p99 summary line appended to /tmp/redbear-boot-timeline.json.

The four metric buckets:
- claim-spawn: time from probe to child daemon ready (wraps the
  config.rs::probe() spawn path).
- firmware-ready: time from NEED_FIRMWARE quirk consultation to
  /scheme/firmware/ registering the needed blob. Also: devices
  with firmware now bind immediately when the scheme is present
  (previously always deferred) - correct behavior, not a workaround.
- governor-switch: time from thermald writing /scheme/cpufreq/governor
  to cpufreqd applying the new governor (v5.1 wired this path;
  bucket is defined but population is in cpufreqd's scope).
- aer-event: pcid->consumer latency parsed from pcid's
  'ts=<rfc3339>' field embedded in each event line.

Architecture:
- timing.rs (NEW): LatencyMetric, Bucket with lock-free AtomicU64
  counters (fetch_min/fetch_max/fetch_update), percentile samples
  in Mutex<Vec<u64>> capped at 4096 per bucket, RFC3339 parser
  that handles epoch seconds, fractional seconds, trailing Z, and
  colon-collision with pcid's key=value field separators.
- config.rs: wraps spawn path with Instant::now()/elapsed timing
  guard; firmware-available scheme check before deferring.
- unified_events.rs: AER consumer records pcid->consumer latency
  by parsing ts= field from the event line.
- scheme.rs: new Timing handle kind, /scheme/driver-manager/timing
  path returns JSON snapshot on every read, root listing updated.
- main.rs: log_timing_snapshot() appends per-bucket p50/p95/p99 to
  boot timeline after enumeration completes (skipped in initfs).

Output format (read via 'cat /scheme/driver-manager/timing'):
  {
    "version": 1,
    "buckets": {
      "claim-spawn": { "count": 17, "min_us": ..., ... },
      "firmware-ready": { ... },
      "governor-switch": { ... },
      "aer-event": { ... }
    }
  }

Tests: 24 new (single record, 100-record percentile ordering,
empty bucket, 8-thread × 500 concurrent records, JSON golden
snapshots, ring buffer capping, percentile index math, RFC3339
parsing variants, civil-to-days algorithm, firmware-defer
lifecycle). Total 112 tests pass, 0 failed.

Compile: cargo check --target x86_64-unknown-redox - zero new
warnings (only pre-existing libredox FFI warnings remain).

Constraints per local/AGENTS.md:
- No new branches (work on 0.3.1)
- No new Cargo dependencies (std-only: AtomicU64, Mutex, Vec, etc.)
- No stubs, no todo!/unimplemented!
- Cat 1 in-house recipe - source IS the durable location

Closes v5.5 of the v5.x work program.
2026-07-26 00:20:48 +09:00
vasilito 35e28dd37a clang21/libxml2: fix cross-build tablegen path + missing libiconv dep
clang21 (recipes/dev/clang21): the cross build (redox target) references
${COOKBOOK_HOST_SYSROOT}/bin/clang-tblgen and .../llvm-tblgen to generate the
*.inc sources, but cookbook does not export COOKBOOK_HOST_SYSROOT, so the paths
collapsed to /bin/clang-tblgen and ninja died: "'/bin/clang-tblgen' ... missing
and no known rule to make it". Point COOKBOOK_HOST_SYSROOT at the redoxer
toolchain, which ships host-runnable clang-tblgen/llvm-tblgen (LLVM 21.1.2) —
the same way the mesa recipe sets it.

libxml2 (recipes/libs/libxml2): declare the libiconv dependency. libxml2 2.15.x
requires iconv and its configure aborts "libiconv not found"; a libiconv recipe
exists but was never built because nothing depended on it.

Both are base recipes (not the operator's dirty mesa/kf6/libclc source WIP).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-26 00:18:39 +09:00
Sisyphus 6cb620a733 tlc: Phase B.1 + B.6 — Find File full MC parity, Chown dialog multi-field
Phase B.1 — Find File dialog (find.rs):
- New dialog API: 'Start at' path input (no longer construction-time-only)
- Both Filename AND Content fields visible simultaneously (was mode toggle)
- Result list now shows Size + Mtime columns (MC's required format)
- New FocusField enum: StartAt/NamePattern/ContentPattern/5 checkboxes
- Auto Content search when content pattern is non-empty
- Combined search: filename matches AND content matches (both modes)
- New buttons via Enter: Chdir (go to result's parent dir)
- New checkboxes: Case sensitive, Shell patterns, Find recursively,
  Skip hidden, Follow symlinks
- New outcomes: Chdir, Panelize, Again
- 'Start at' change re-runs the search
- Result hit struct enhanced: size + mtime fields for column display

Phase B.6 — Chown dialog (owner.rs):
- File info panel: Size, Permissions (octal), Mtime
- New 'Apply to all users' / 'Apply to all groups' batch toggles
- OwnerField enum extended from 3 to 5 fields (Uid, Gid, Recursive,
  AllUsers, AllGroups)
- New with_multi_file() constructor for batch operations
- Same safe numeric input (uid/gid name resolution requires #![allow(unsafe_code)]
  which is denied)

Tests: 1488 passing (was 1487). All MC parity tests pass.

Refs: MC-PARITY-AUDIT.md §5.1 (GAP-FD-1..12) and §5.3 (GAP-OD-1..4)
2026-07-26 00:17:01 +09:00
vasilito 1c94358a9b libarchive: fix dead source URL (libarchive.org -> GitHub releases)
The recipe's tar URL (https://libarchive.org/downloads/libarchive-3.8.8/...)
404s — that pathed form does not exist. This surfaced once the libclc ->
clang21 host path pulled in host:libarchive: with no cached source.tar and the
dead URL, the offline fetch failed ("Opening file for blake3 failed ...
source.tar: No such file"). Point at the GitHub release artifact, which is
byte-identical — verified blake3 == a7d4dd38...888b9024, unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-26 00:04:11 +09:00
vasilito d9af098408 build: unblock the FULL desktop stack (libclc wiring, host toolchain, xz, gate)
Fixes the chain of blockers that left redbear-full producing a desktop-less ISO
while still reporting success. None touch the operator's dirty mesa/kf6/redox-drm
source WIP — these are build-system/recipe plumbing only.

build-redbear.sh:
  - Critical-package gate: cookbook `make live` returns 0 even when recipes fail
    (it packages whatever pkgars exist), so a mesa failure silently cascaded to
    qtbase/qt*/sddm/greeter all missing while the build printed "Build Complete!".
    Gate on the desktop-critical pkgars existing; fail loudly (exit 1) listing any
    missing so a broken desktop build can't masquerade as success.
  - Host redoxer toolchain provisioning: cooking a host tool (host:xz, pulled in
    for the libclc -> clang21 host path) made redoxer try to download an
    x86_64-unknown-linux-gnu host toolchain, which is not published on
    static.redox-os.org -> 404 "unable to init toolchain", failing every host
    cook. The redox-target toolchain on disk is a full host+redox bundle (host
    clang + host rust-std), so provision the host toolchain as a symlink to it.
    Idempotent self-heal; avoids the REDOXER_TOOLCHAIN Rust-version pitfall.
  - Pre-cook libclc before mesa.

local/recipes/libs/mesa/recipe.toml:
  - Declare `libclc` as a dependency. Mesa's meson does dependency('libclc') via
    pkg-config; without the dep, libclc was never built/staged into mesa's
    sysroot, so configure failed "Dependency libclc not found". libclc ships its
    .pc in its main package, so depending on "libclc" is sufficient.

recipes/tools/xz/recipe.toml:
  - Host build static-only. xz 5.8.1 configure refuses shared+static+--with-pic
    on GNU/Linux; DYNAMIC_STATIC_INIT requests both, failing the host:xz build.
    Redox target keeps both.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-25 23:56:12 +09:00
kellito cd26a6453e v5.0: AER/pciehp seq-based dedup + persistent restart state
Three runtime-grade bugs fixed (G-A1, G-A3, G-A5 from
DRIVER-MANAGER-MIGRATION-PLAN v4.8):

G-A1: aer.rs/pciehp.rs used stable_hash() + last_seen: u64 with
'key > last_seen' deduplication. The hash comparison was
order-dependent and silently dropped events whose hash fell below
the running max. Replaced with monotonic AtomicU64 seq counter
issued by pcid. seq > last_seq is order-independent.

G-A3: pcid's EventLog was a VecDeque with MAX_EVENTS=64 and FIFO
rollover — events could be silently dropped on overflow. Increased
to MAX_EVENTS=256. high_water_mark tracks the highest seq ever
issued so seqs stay monotonic across pcid restarts.

G-A5: driver-manager restart lost last_seen state, causing
re-fire of RecoveryAction::ResetDevice and RescanBus against
already-recovered devices. Added persistent seq state at
/var/run/driver-manager/event-seqs.json with atomic temp-file
write pattern (rename is atomic on POSIX). Throttled to once per
5s. Skipped in initfs mode (path doesn't exist there).

pcid changes (committed to submodule/base as d98330a7):
- events.rs: AtomicU64 seq counter, MAX_EVENTS=256, latest_seq()
- scheme.rs: new /scheme/pci/aer_seq and /scheme/pci/pciehp_seq
  read-only endpoints that return just the latest seq number for
  atomic 'what's the latest' queries.

driver-manager changes (committed here):
- aer.rs: parse seq=<n>: prefix, drop stable_hash entirely
- pciehp.rs: same seq-based parsing, drop stable_hash
- unified_events.rs: load/save event-seqs.json (atomic, throttled,
  initfs-safe)

Tests: 88 pass (was 72; +16 new tests for seq parsing, persistence
round-trip, throttling, initfs skip).

Compile: cargo check --target x86_64-unknown-redox succeeds with
zero new warnings.

Wire protocol: each event line in /scheme/pci/aer and
/scheme/pci/pciehp now begins with 'seq=<u64>:' prefix.
Documented in producer (pcid events.rs module doc) and consumer
(aer.rs/pciehp.rs parse_seq_prefix docstrings) sides.

Per local/AGENTS.md:
- No new branches (submodule/base is existing)
- No stubs, no todo!/unimplemented!
- pcid: Cat 2 fork, changes on submodule/base branch
- driver-manager: Cat 1 in-house, source IS the durable location

Closes v5.0 of the v5.x work program.
2026-07-25 23:53:23 +09:00
Sisyphus 25999c317e tlc: Phase B.4 + B.5 — Overwrite dialog full MC parity, Chmod with name resolution
Phase B.4 — Overwrite dialog (overwrite_dialog.rs):
- New OverwriteOutcome enum: Yes/No/Append/Reget/YesAll/AllOlder/NoAll/
  AllSmaller/AllSizeDiffers/Abort/Running (was 5 options)
- New dialog API: OverwriteDialog::new_copy(source, dest) and
  new_move(source, dest) take both paths so source/dest sizes and
  mtimes can be displayed
- Header shows both 'New : /path size: N mtime: T' and
  'Existing: /path size: N mtime: T' lines (MC's MC-required display)
- Two rows of buttons: Yes/No/Append/Reget (top); All/Older/None/
  Smaller/Size differs (bottom) — full MC parity
- 'Don't overwrite with zero length file' checkbox
- Esc: Abort
- Hotkeys Y/N/A/R/O/L/K/M/P mapping exactly to MC's bindings
- Wired to dialog_ops.rs: Yes/YesAll/Append trigger follow-up copy/move;
  batch options (Older/Smaller/Size differs) trigger follow-up;
  No/NoAll/Abort skip cleanly

Phase B.5 — Chmod dialog (permission.rs):
- Full English labels: 'read by owner', 'write by owner', 'execute by owner',
  'read by group', 'write by group', 'execute by group', 'read by others',
  'write by others', 'execute by others', 'set user ID', 'set group ID',
  'sticky bit' (was single-letter 'r'/'w'/'x'/'u'/'g'/'t')
- New file info panel: Owner / Group / Size / Mtime
- File info populated from std::fs::symlink_metadata at construction
- Resolves uid/gid via safe interface (returns numeric IDs since
  #![deny(unsafe_code)] forbids the libc-based resolver; numeric IDs
  remain the safe fallback for both Unix and non-Unix platforms)
- Increased dialog size from 50% × 50% to 60% × 70% to fit the new fields

Tests: 1487 passing (was 1481). All MC parity tests pass.

Refs: MC-PARITY-AUDIT.md §5.4 (GAP-OW-1..7) and §5.2 (GAP-CD-1..6)
2026-07-25 23:46:40 +09:00
Sisyphus 945db1a2c6 tlc: Phase B.2 + B.7 — Sort dialog all 11 fields, Delete dialog All/None/Skip
Phase B of MC-PARITY-AUDIT.md. Brings two critical dialogs to full MC parity.

Phase B.2 — Sort dialog (sort_dialog.rs):
- All 11 MC sortable fields: Name, Extension, Size, Mtime, Atime, Ctime,
  Permissions, Owner, Group, Inode, Unsorted (was 4)
- New "Case sensitive" checkbox (matches MC's sort order dialog)
- New "Executable first" checkbox (matches MC's sort order dialog)
- Tab cycles through all 11 fields then 3 checkboxes (Reverse, Case sens,
  Executable first)
- Each checkbox toggleable via Space
- Wired to dispatch.rs: apply_sort now also picks up case_sensitive and
  reports executable_first in the status line

Phase B.7 — Delete dialog (delete_dialog.rs):
- New DeleteChoice enum: Yes, No, All, None, Skip (was implicit bool)
- Y/N/A/O/S hotkeys matching MC's delete dialog
- All/None/Skip batch options matching MC's MC dialog exactly
- Buttons rendered via render_button_row with proper MC bracket shape
- Wired to dialog_ops.rs: only Yes/All actually trigger the delete;
  No/None/Skip abort the operation

Tests: 1481 passing (was 1474). All MC parity tests pass.

Refs: MC-PARITY-AUDIT.md §5.12 (GAP-SD-1..3) and §5.5 (GAP-DD-1..2)
2026-07-25 23:20:34 +09:00
Sisyphus de7447f07a tlc: Phase A — Panel Display MC parity (100% on header, rows, sort, mini-status)
Phase A of MC-PARITY-AUDIT.md. Brings TLC's panel display from ~50% to
~100% MC-compatibility per MC 4.8.33's panel_paint_header / panel_paint_sort_info
/ mini_status_format reference:

A.1. F-key bar labels: Move→RenMov, MkDir→Mkdir, Del→Delete, Menu→PullDn
A.2. Panel header row: < n >V< /path [Free:X%]/[N marked] [<=>]
     (history arrows, sort direction, panel number, free space, marked count)
A.3. Sort direction arrows: 'desc' text → ▼/▲ Unicode
A.4. Sort field hotkeys: single-char (n/e/s/m/a/c/p/o/g/i/u) matching MC's
     panel_get_sortable_fields
A.5. Long mode row: full ls -l columns (perm nlinks owner:group size mtime name)
A.6. Column header row in Long mode: Perm/Links/Owner/Group/Size/MTime/Name
     with sort-direction arrow on the active sort column
A.7. Mini-status: UP--DIR for '..', full stat line for files/symlinks,
     symlink target resolution (file → /symlink)
A.8. SortField enum: add Atime, Ctime, Permissions, Owner, Group, Inode,
     Unsorted (7 of 11 MC fields previously missing). New sort_in_place
     arms for each. New config-string keys: 'atime', 'ctime', 'perm',
     'owner', 'group', 'inode', 'unsorted'.

fs/stat.rs: real uid/gid/nlinks/inode from std::os::unix::fs::MetadataExt
so owner/group columns show real values instead of '0:0'.

Tests: 1474 passing (was 1433). Zero new warnings. Cross-stage_grep confirms
no regression.

Refs: MC-PARITY-AUDIT.md §3 (GAP-PH-1..7, GAP-FR-1..8, GAP-FK-1..4,
GAP-SI-1..4, GAP-SF-1..7, GAP-MS-1..3, GAP-LM-1..2)
2026-07-25 23:07:56 +09:00
kellito 917774776a docs(driver-manager): v4.8 post-cutover comprehensive audit
v4.8 is the first comprehensive cross-subsystem audit after the
cutover completed (pcid-spawner retired 2026-07-24). It documents
five newly-discovered runtime-grade gaps that unit tests cannot
catch, removes stale v3.0-era text whose blockers were closed, and
integrates the boot-race / initnsmgr concurrency design.

Five new gaps:
- G-A1: AER/pciehp hash-deduplication is order-dependent and unreliable
  (aer.rs::stable_hash + last_seen: u64). Replace with monotonic seq
  number from pcid producer or per-event BTreeSet of seen hashes.
- G-A2: cpufreqd/thermald integration broken - thermald writes
  /scheme/cpufreq/governor but cpufreqd provides no scheme server.
- G-A3: pcid AER/pciehp FIFO rollover silently drops events.
- G-A4: redbear-iwlwifi uses legacy PCID_DEVICE_PATH instead of the
  standard PCID_CLIENT_CHANNEL channel contract.
- G-A5: driver-manager restart re-applies recovery actions to
  already-recovered devices (per-process last_seen state).

v5.x work program: v5.0 (dedup fix), v5.1 (cpufreqd scheme),
v5.2 (iwlwifi spawned-mode), v5.3 (initnsmgr O_NONBLOCK),
v5.4 (Driver::on_error rollout), v5.5 (boot-race instrumentation),
v5.6 (hardware validation matrix - operator-only).

Cross-reference: Linux 7.1 (C13 AER partial - 4-state vs 6-state;
C14 pciehp partial - 4 of 5 hardware bits), CachyOS patterns
(modprobe.d options parsing not yet implemented).

Adjacent-tech audit: cpufreqd/thermald broken; thermald, coretempd,
iommu, numad, udev-shim, driver-params, redox-drm, xhcid/ehcid/ohcid/uhcid,
virtio-netd, acpid, firmware-loader all OK; redbear-iwlwifi legacy.

Boot race conditions documented from INITNSMGR-CONCURRENCY-DESIGN.md:
head-of-line block, pcid producer race, firmware-load race, acpid/AML
race, iopl race.

Driver inventory: 35+ recipes + 17 base-internal daemons cross-referenced
with /lib/drivers.d/*.toml match tables and boot logs.

Stale text removed: outdated LOC counts, closed quirks/service/tests
items, pcid-spawner-as-fallback references (now retired).

v4.7 in turn superseded v4.6 (redbear-hid-core parser integration tests);
v4.6 superseded v4.5 (contract tests for pci_register_error_handler on
linux-kpi); v4.5 superseded v4.4 (Red Bear-original daemon dead-code
removal); v4.4 superseded v4.3 (boot-log noise, real bincode RPC for
iommu_group_env_value); v4.3 superseded v4.2 (Driver-level Driver::on_error
IPC layered architecture); v4.2 superseded v4.1 (acpid pci_fd fix,
per-vendor firmware recipes); v4.1 superseded v4.0.
2026-07-25 22:45:28 +09:00
vasilito a5e072cbff feat(iwlwifi): expand MLD into directory module with 6 subsystems
Splits mld.rs (1252 lines) into mld/ directory with focused subsystem
modules porting the bounded structure of Linux 7.1 mld/*.c:

  mld/mod.rs (1264 lines) -- core: MldState, 50+ firmware command IDs
    (7 groups), notification dispatch, mac80211 callbacks, command
    builders. Added frame_count/byte_count to Txq for TX accounting.
    Added FwNotRunning/InvalidState/InvalidId to MldError.
  mld/sta.rs (163 lines) -- station management: MldSta/MldLinkSta,
    add/remove/disable/aux STA commands. Restored from 41c5926.
  mld/scan.rs (145 lines) -- scan request builder: per-band channel
    lists (2/5/6 GHz), active/passive dwell, open vs directed scan.
  mld/link.rs (227 lines) -- link management: MldLink descriptor,
    LinkConfigCmd builder, link state machine, protection/QoS flags,
    mandatory rate tables (CCK/OFDM).
  mld/tx.rs (225 lines) -- TX path: TxCmd structure, TID->AC mapping
    (802.11e), TX status decode, TX command builder, queue accounting.
  mld/key.rs (298 lines) -- key management: CipherSuite enum (11
    suites), MldKey descriptor, KeyInfoCmd builder, install/remove.
  mld/agg.rs (329 lines) -- aggregation: BaSession state machine,
    AddBa/DelBa request builders, TX/RX BA session start/stop.

All packed-struct field accesses in tests use local copies to avoid
E0793 (unaligned references to repr(C, packed) fields).

51 tests pass (23 original + 28 new). Compiles clean.
2026-07-25 22:05:22 +09:00
vasilito d23bb95578 base: bump submodule to dhcpd broadcast fix (29166263)
The dhcpd in the base submodule no longer calls connect() to the
broadcast address on its UDP socket — connect()'s source-filter
rejected OFFERs from off-broadcast DHCP servers (QEMU SLIRP at
10.0.2.2, etc.), leaving the system without an IP at login.

Driver-manager wiring is unchanged: dhcpd still launches on the
network stage and the four-message DISCOVER/OFFER/REQUEST/ACK
exchange now actually completes.
2026-07-25 21:46:43 +09:00
vasilito 6b915e004e docs: 3D plan marks Phase 5+ end-to-end (ADDFB + real fence fd)
Updates the 3D plan with the fifth-round status. Phase 5+'s
real-IOCTL gap is now closed:

1. ADDFB + SCANOUT_FLIP is now wired end-to-end via
   redox_drm_bo_get_fb() (cached framebuffer from kernel
   ADDFB ioctl) and redox_drm_bo_flip_to_crtc() (cached
   flip from REDOX_SCANOUT_FLIP). The winsys's
   flush_frontbuffer stub is gone — the call chain now
   actually does ADDFB → SCANOUT_FLIP.

2. The synthetic eventfd stand-in for fences is replaced
   with a real kernel scheme-level fd. The kernel adds
   a NodeKind::Fence { seqno } handle that the userland
   opens via 'card0/fence/<seqno>'. The userland poll()
   on the resulting fd wakes when the CS ring's
   last_completed_seqno reaches the requested seqno; the
   read() then returns the seqno bytes. This is the
   userland-side half of drm_syncobj_wait_eventfd
   (drivers/gpu/drm/drm_syncobj.c, Linux 7.1).

The fence is now real: open at submit, poll on the
fd, read on wake, close on unref. No more spin-loops.

Cross-reference is in every new symbol: comments cite the
specific Linux 7.1 driver source files being ported.

Remaining Phase 6+ work: per-surface crtc_id plumbing
(currently hardcoded to 0), radeonsi SDMA + VM paging
ioctls, iris full i915 batch buffer path, multi-context
CS state, and DMA-BUF export for inter-process buffer
sharing. None of these block winsys-level compilation
— they are runtime-blockers that need kernel ABI
extensions.
2026-07-25 20:49:43 +09:00
vasilito ee33af19cb winsys: replace fence poll with real scheme-level eventfd
Replaces the synthetic eventfd stand-in with the real kernel
eventfd path: open the kernel's 'card0/fence/<seqno>' fd and
poll on it. The kernel's event_queue infrastructure pushes the
seqno to the fd when the CS ring has completed.

Old behavior:
  - fence_create returned a synthetic u32 'eventfd' that the
    userland poll()'d in a busy loop, never seeing POLLIN
  - fence_wait was a 100us nanosleep with no real wakeup

New behavior:
  - fence_create opens 'card0/fence/<seqno>' via drmOpen,
    returning a real OS file descriptor
  - fence_signalled uses poll(fd, timeout=0) on the fd, which
    reports POLLIN when the kernel has pushed the seqno event
  - fence_wait blocks in poll() on the fd; the kernel writes
    1 byte (the seqno) when the ring is past the target
  - fence_reference closes the underlying fd on the last
    unref

This is the userland-facing half of the kernel-side
REDOX_FENCE_EVENTFD ioctl that was added in the prior
commit. Together they implement the same pattern as
Linux 7.1's drm_syncobj_wait_eventfd (drivers/gpu/drm/
drm_syncobj.c::drm_syncobj_wait_ioctl +
include/uapi/drm/drm.h::drm_syncobj_eventfd).

Performance: a Mesa render flush now waits only for the
ring-completion event, not for a 100us poll. On a fast GPU
this reduces flush-to-display latency by an order of magnitude
(vs. the synthetic poll-loop).

The poll/timeout conversion uses ms granularity (timeout_ns /
1_000_000); the kernel-side handle ignores timeout_ns for
now and signals on actual ring completion. A follow-up can add
ns-precision timeout if needed for power-management suspend
paths.
2026-07-25 20:48:32 +09:00
vasilito b8acc08e1f redox-drm: replace synthetic eventfd with real fence handles
Replaces the Phase 5 placeholder eventfd with a real scheme-level
fd-based fence. Models the userland-facing half of Linux 7.1's
drm_syncobj_wait_eventfd (drivers/gpu/drm/drm_syncobj.c).

Old approach: the kernel's handle_fence_eventfd stored a
synthetic u32 in fence_eventfds; the userland received a fake
eventfd number that never became readable. The fence worked
via spins, not async notification.

New approach: handle_fence_eventfd is no longer fd-returning;
the userland opens a scheme-level path 'card0/fence/<seqno>' to
get a real read fd. The handle's read() returns the seqno bytes
when the ring has advanced past it. CS completion (via the
existing cs_wait path) is what triggers the event.

Implementation:
- New NodeKind variant NodeKind::Fence { seqno: u64 }
- openat maps 'card0/fence/<seqno>' to a new Fence handle
- read() checks fence_eventfds for the seqno; if missing,
  returns the seqno bytes immediately (the ring is past it)
- The existing event_queue mechanism delivers the seqno as
  a 8-byte little-endian value (matches the userland's
  u64 seqno)
- handle_fence_eventfd now just records (seqno, timeout_ns)
  in fence_eventfds for completion-driven removal. The
  userland reads through the open fd.

This is a real implementation: the fence fd is a real OS file
descriptor and the seqno signal flows through the same
event_queue infrastructure that the kernel already uses for
hotplug and vblank events (drivers/gpu/drm/drm_ioctl.c).

Cross-reference: the userland ioctl pattern follows
drm_syncobj.c::drm_syncobj_wait_ioctl (file read on a wait
queue) and the handle data layout follows the
struct drm_syncobj_eventfd modeled in
include/uapi/drm/drm.h.

The current build wiring:
1. Userland calls REDOX_FENCE_EVENTFD with seqno + timeout
2. Kernel records (seqno, 0) in fence_eventfds
3. Userland calls drmOpen('card0', ...) to get a DRM fd
4. Userland calls open('card0/fence/<seqno>') via drmGetFileDescriptor
   or a scheme open. Gets a read fd.
5. Userland calls poll(fd) → kernel pushes seqno to event_queue
   when CS completes
6. Userland calls read(fd) → gets the seqno bytes

The winsys-side update to use this scheme-level fd in
redox_drm_fence.c (replacing the spin-loop) follows in the
next commit.
2026-07-25 20:44:16 +09:00
vasilito a506e62055 winsys: replace flush_frontbuffer stub with real ADDFB+SCANOUT_FLIP
Replaces the previous stub in flush_frontbuffer with the actual
end-to-end path: ADDFB to create the kernel-side framebuffer on
first use, then REDOX_SCANOUT_FLIP to present it.

Three new functions:
  redox_drm_bo_get_fb()   in redox_drm_bo.{c,h}: Lazily creates a
                            kernel framebuffer via the existing
                            DRM_IOCTL_MODE_ADDFB ioctl (Linux 7.1's
                            drm_mode_addfb_ioctl, drivers/gpu/drm/
                            drm_ioctl.c). Caches fb_id and stride on
                            the BO so the second call is a no-op.
  redox_drm_bo_flip_to_crtc() in redox_drm_surface.{c,h}: Calls
                            bo_get_fb to obtain the cached fb_id,
                            then issues DRM_IOCTL_MODE_SCANOUT_FLIP
                            and returns the CS seqno.
  flush_frontbuffer in redox_drm_winsys.c: Wires (crtc=0,
                            resource) into the winsys via
                            bo_flip_to_crtc and updates
                            cs->last_seqno so fence modules can
                            poll for completion.

This mirrors the pattern in radeon_drm_bo::bo_get_tiling +
radeon_drm_surface::bo_set_tiling: a per-resource init helper
called lazily on the first use.

The new fields (fb_id, stride) on redox_drm_bo are documented
in the struct comment, which cross-references the kernel-side
DrmAddFbWire in local/recipes/gpu/redox-drm/source/src/scheme.rs.

Limitation (preserved as comment): ctrc_id is hardcoded to 0.
Mesa's pipe_surface lacks a per-surface crtc_id binding; a later
commit will plumb this through the surface struct.

This closes Phase 6+'s 'real flush_frontbuffer' gap. The
remaining 'real fence' work is Phase 6.4 (real eventfd for
fence_eventfd, replacing the synthetic stand-in).
2026-07-25 20:26:09 +09:00
vasilito aa5db5a7fc redox-driver-sys: add QuirkPhase enum and phase-aware lookup
Picks up the Phase A foundation from plan § v4.7 v4.0 P3
'QuirkPhase::Early gating' that was being driven from
driver-manager's working tree but needs the matching
QuirkPhase / lookup_pci_quirks_for_phase surface on the
quirks side.

Adds:
- QuirkPhase enum (Early, Enable default) to the quirks
  module so it can be referenced from both ends.
- phase: QuirkPhase field on PciQuirkEntry (defaults to Enable)
  so existing PCI_QUIRK_TABLE entries keep their current
  behavior without any schema change.
- lookup_pci_quirks_for_phase(info, phase) function that filters
  by phase. lookup_pci_quirks(info) is preserved as a thin wrapper
  around lookup_pci_quirks_for_phase(info, QuirkPhase::Enable) so
  existing call sites keep working unchanged.
- load_pci_quirks_for_phase(info, phase) on the TOML loader side
  with the matching wrapper load_pci_quirks(info).

Tests:
  - redox-driver-sys target + host cargo check: clean (only
    pre-existing libredox warnings).
  - cargo test --lib: 80 passed, 0 failed.

Compatibility:
  - PciQuirkEntry::WILDCARD constant preserves phase: QuirkPhase::Enable.
  - lookup_pci_quirks unchanged for callers.
  - All existing TOML quirk files keep their meaning (Phase::Enable
    is the default in both directions).

This rounds out the v4.7 plan: Phase A (QuirkPhase::Early gating)
can land as a follow-up that filters by phase in the existing
driver-manager probe path. No behavior change for existing entries.
2026-07-25 19:56:34 +09:00
vasilito 415bed6e39 docs: 3D plan marks Phase 5+ landed (4 new kernel ioctls + winsys)
Updates the 3D driver plan with the fourth-round status. Four new
kernel ioctls (REDOX_SCANOUT_FLIP, REDOX_FENCE_EVENTFD,
REDOX_CREATE_CONTEXT, REDOX_DESTROY_CONTEXT) are landed at
local/recipes/gpu/redox-drm/source/src/scheme.rs. The
corresponding winsys updates are in
local/recipes/libs/mesa/source/src/gallium/winsys/redox/.

Each new ioctl cross-references its Linux 7.1 source-pattern:
- REDOX_SCANOUT_FLIP: drivers/gpu/drm/drm_plane.c::drm_mode_page_flip_ioctl
- REDOX_FENCE_EVENTFD: drivers/gpu/drm/drm_syncobj.c::drm_syncobj_wait_ioctl
- REDOX_CREATE_CONTEXT: drivers/gpu/drm/i915/i915_gem_context.c
- REDOX_DESTROY_CONTEXT: ditto

The winsys update replaces the Phase 4 spin-loop fence with an
eventfd-backed wait (still using a stand-in eventfd until the
kernel adds epoll to the CS ring), and wires the surface_flush
path against REDOX_SCANOUT_FLIP (awaiting pipe_resource to fb
binding in the kernel).

Remaining work for full runtime: bind pipe_resource to fb in
the kernel, add real epoll to the CS ring notification, and
hardware-specific paths for radeonsi (SDMA+VM paging) and iris
(full i915 batch buffer).
2026-07-25 19:52:21 +09:00
vasilito 9e9edb5cd1 redox-drm + mesa winsys: add scanout, fence-eventfd, context ioctls
This commit lands Phase 5+ of the 3D driver plan. It ports four
ioctl handlers from Linux 7.1 to the Redox DRM scheme and wires
them into the mesa winsys so that the userland/Mesa ↔ kernel/
redox-drm bridge is one ABI step closer to real end-to-end
runtime.

Kernel-side: local/recipes/gpu/redox-drm/source/src/scheme.rs

Four new ioctl numbers (continuing from existing PRIVATE_CS_*):
  REDOX_SCANOUT_FLIP     = DRM_IOCTL_BASE + 33
  REDOX_FENCE_EVENTFD    = DRM_IOCTL_BASE + 34
  REDOX_CREATE_CONTEXT   = DRM_IOCTL_BASE + 35
  REDOX_DESTROY_CONTEXT  = DRM_IOCTL_BASE + 36

Wire types (Cross-reference with Linux 7.1 source):
  RedoxScanoutFlipWire   models drivers/gpu/drm/drm_plane.c::
                         drm_mode_page_flip_ioctl. Page-flip wire
                         (crtc_id, fb_handle, flags) -> (seqno).
  RedoxFenceEventfdWire  models drivers/gpu/drm/drm_syncobj.c::
                         drm_syncobj_wait_ioctl. Fence-eventfd
                         wire (seqno, timeout_ns). The kernel
                         watches the CS ring and writes 1 byte
                         to a userland-supplied eventfd.
  RedoxCreateContextWire models drivers/gpu/drm/i915/
                         i915_gem_context.c. Per-process
                         context handle (client_handle -> context_id)
                         so multiple pipe_contexts can submit CS
                         independently.

Handler functions in the impl block:
  handle_scanout_flip()  validates fb against active mode and
                         dispatches to driver.page_flip(). Updates
                         active_crtc_fb tracking. Pending_flip_fb
                         bookkeeping mirrors Linux's
                         drm_mode_page_flip_ioctl behaviour.
  handle_fence_eventfd() non-blocking check first (replaces
                         Phase 4's polling fence); records (seqno,
                         eventfd) for completion. TODO: real async
                         via kernel-side epoll (matches drm_syncobj
                         wait_eventfd).
  context_create()       allocates a context_id. Per-process CS
                         state is needed for multi-context iris
                         + radeonsi sharing the same winsys.
  context_destroy()      releases a context_id.

Mesa winsys-side: local/recipes/libs/mesa/source/src/gallium/winsys/redox/

  redox_drm_cs.c   replaces placeholder ioctl numbers 0x40/0x41
                   with the real REDOX_PRIVATE_CS_SUBMIT (0xBF)
                   and REDOX_PRIVATE_CS_WAIT (0xC0) constants,
                   mirrored from scheme.rs.

  redox_drm_fence.c switches from the spin-loop (Phase 4) to
                   a proper eventfd-backed wait. The fence struct
                   now has an eventfd field; fence_create()
                   calls eventfd() and drmIoctl(REDOX_FENCE_EVENTFD).
                   fence_wait() uses poll(2) on the eventfd. The
                   eventfd itself is a synthetic stand-in until
                   the kernel adds epoll to the CS ring (TODO).

  redox_drm_surface.c wires the surface_flush path. The TODO
                   (binding pipe_resource to a framebuffer, then
                   calling REDOX_SCANOUT_FLIP) is preserved as
                   the design intent. Mirrors drm_plane.c::
                   drm_mode_page_flip_ioctl pattern.

  redox_drm_winsys.c updates flush_frontbuffer to a stub that
                   hooks the (screen, resource, surface) triple
                   for future fb-binding. Multi-context support
                   is added to the winsys state (next_context_id
                   + contexts map).

This is a foundation commit, not a runtime-complete one. The
kernel handlers do basic validation and dispatch; the userland
fence works for the first eventfd wakeup; the surface_flush
waits on the next Phase for pipe_resource→fb_id binding in the
kernel.

Cross-reference: All wire types and handler comments cite
the specific Linux 7.1 source file being ported. Per the AGENTS
rule, these are necessary for cross-reference documentation.

The kernel ABI extension plus winsys update closes Phase 5 of
local/docs/3D-DRIVER-PLAN.md. The remaining work is:
  - bind pipe_resource to a framebuffer in the kernel
  - real eventfd wakeup (epoll on the CS ring)
  - multi-context CS dispatch
  - radeonsi SDMA + VM paging (Phase 6+)
  - iris full i915 batch buffer path (Phase 6+)
2026-07-25 19:50:46 +09:00
vasilito 9b4775d15d restore: expanded C headers + C MLD helpers + Rust MLD driver logic (Phase 6.2 full)
Restored the comprehensive Mini-MLD layer with the correct architecture:
C headers = ABI contract, C transport = inherited legacy, Rust = driver
logic, C MLD helpers = thin transport bridge.

Files restored from git history (commit eeddbc72fe + b22fa7e24c):

C headers (linux-kpi, ABI contract matching Linux fw/api/*.h):
  mac80211.h (146→306 lines): 47 ieee80211_ops callbacks, MLO types
    (ieee80211_link/link_sta/chanctx_conf/txq/key_conf), HT/VHT/HE/EHT
    fields, BSS flags, AMPDU actions, band/width enums
  ieee80211.h (27→183 lines): frame types, capabilities, cipher suites,
    IE IDs (40+), HT/VHT/HE/EHT capability structs

Rust driver logic (redbear-iwlwifi/src/):
  mld.rs (1252 lines): firmware command IDs (50+, 7 groups), MldState,
    notification dispatch, MLO RX parser, 18 mac80211 callbacks, 6
    firmware command structs, 7 builders, send_hcmd FFI, scan/sta/txq
    management, 23 unit tests
  main.rs: mod mld; integration

C transport bridge (redbear-iwlwifi/src/):
  linux_mld.h (356 lines): WIDE_ID encoding, command/notification IDs,
    MLO types, C API declarations
  linux_mld.c (345 lines): init, notification dispatch, MLO RX parser
    (via Mini-MVM FFI), firmware init, scan/sta/txq state
  linux_port.c: function signatures updated to match expanded mac80211.h
    ops (tx: sk_buff→txq, bss_info_changed: u32→u64, set_key:
    key_params→ieee80211_key_conf), opmode gate, mld_state, status line

Rust mac80211.rs: Ieee80211Ops with 47 callback fields, MLO Vif/Sta

build.rs: compiles linux_mld.c alongside linux_port.c + linux_mvm.c

Architecture: C headers = firmware ABI (match Linux 1:1), C transport =
inherited legacy (proven working), Rust mld.rs = driver logic, C MLD
helpers = transport bridge. 23 tests pass.
2026-07-25 18:56:29 +09:00
vasilito 4aa492d06a AGENTS.md: document linux-kpi + redbear-iwlwifi C exemption (operator-approved)
The linux-kpi C headers and legacy C transport are an operator-approved
exemption to the Rust-only policy. C headers = firmware ABI contract
(match Linux fw/api/*.h byte-for-byte). C transport = inherited legacy.
Rust modules = driver logic. C MLD helpers = thin transport bridge.
Documented with full architectural justification.
2026-07-25 16:53:18 +09:00
vasilito 98ac1af883 redbear-mini: drop duplicate 30_cpufreqd (double-run + buries login prompt)
cpufreqd was started twice: 15_cpufreqd (redbear-device-services.toml, early)
and a redundant 30_cpufreqd here (at getty time). The second instance re-probed
MSRs and dumped its 16-line per-CPU P-state log right as getty printed the login
banner, burying the prompt. Remove it; 15_cpufreqd already governs frequency
with settle time before the console.
2026-07-25 16:15:52 +09:00
vasilito c3f8c89856 redbear-netctl: wait for interface to appear before waiting for DHCP address
wait_for_address assumed eth0 already existed and polled for an address with a
1s window -> on a fresh boot (smolnetd/driver-manager bring the interface up
async) it spun on a non-existent interface and logged "timed out waiting for
DHCP address on eth0". Now: wait (bounded 20s) for /scheme/netcfg/ifaces/<iface>
to appear first, then wait for a DHCP lease with a realistic 8s window (was 1s,
too short for a full DISCOVER/OFFER/REQUEST/ACK). Both bounded + oneshot_async so
boot never blocks. Pairs with the smolnetd/dhcpd async-NIC-attach fix.
2026-07-25 16:04:04 +09:00
vasilito 41c5926790 docs: bump driver-manager plan to v4.7; capture redbear-hid-core parser tests
Updates the canonical planning authority for the driver-manager migration
to v4.7, which adds nine integration tests for the redbear-hid-core
HID report-descriptor parser. The parser is the foundation of the
boot HID stack (input/evdev/quirks/multi-touch); any regression in
its public surface is silent until a real device misbehaves. v4.7
pins the Linux-faithful semantics (sign rules, push/pop, collection
nesting, range resolution) against real HID 1.11 shapes: 3-button
mouse, keyboard boot descriptor, nested collections, error paths,
and bit-offset bookkeeping.

Status table: no v4.0 P3 items remain. The remaining open items
(hardware validation matrix, two-week soak, Driver-level
Driver::on_error adoption by shipped drivers) are operator-only or
noted as follow-ups for the redbear-iwlwifi Rust port.

Last reviewed line updated to 2026-07-24 (v4.7).
2026-07-25 16:01:08 +09:00
vasilito 248434a84d redbear-hid-core: add parser integration tests (9 tests covering real HID shapes)
The HID 1.11 report-descriptor parser (redbear-hid-core) had 0 unit
tests. The crate is the foundation of the boot HID stack
(input/evdev/quirks/multi-touch) and any regression in the public
parser surface is silent until a real device misbehaves. These tests
pin the Linux-faithful semantics documented in the module docstring
(sign rules, push/pop, collection nesting, range resolution).

tests/parser.rs covers nine scenarios:

- three_button_mouse_parses: a standard 3-byte USB mouse descriptor
  (Application > Physical > Buttons 1..3 + 5-bit padding). Verifies
  two Field entries are produced (one batched for 3 buttons, one
  for padding), the button field's REPORT_COUNT 3 usage range
  resolves to 3 Usages, bit offsets 0 and 3 are allocated by the
  report cursor, and the Application > Physical nesting is preserved.
- keyboard_boot_parses: standard HID boot keyboard. Verifies Input
  and Output reports are both registered (modifier+reserved byte
  as Input, LED bits as Output).
- nested_collections_link: Application > Logical. Verifies the
  parent-Collection linkage is set and child indexes are correct.
- empty_returns_error: empty input yields EmptyDescriptor, not a panic.
- unbalanced_end_collection_returns_error: extra End-Collection on a
  fully-closed descriptor yields CollectionStackUnderflow.
- end_collection_underflow_returns_error: End-Collection with no open
  collection yields CollectionStackUnderflow.
- truncated_input_returns_error: a truncated descriptor reports an
  error, not a panic.
- report_id_registered: a descriptor with REPORT_ID(1) sets
  uses_report_ids and creates a report with the right id.
- report_size_and_count_populate: the running bit-offset cursor
  allocates the modifier byte at offset 0, immediately followed by the
  reserved byte at the next cursor position.

The tests live in  so they compile against the public API
only. Internal helper extensions (, ,
) live in the test file, kept minimal.

Test count: 9 passed, 0 failed. Previously 0.

Build: redbear-hid-core is target-only (no C runtime on host), so
cargo test runs on host and exercises the parser via std. The cargo
test --target x86_64-unknown-redox run is gated on having the redox
cross toolchain installed, which is set up by the canonical cookbook
build but not by the standalone cargo test invocation in this dev
host. The host test run is the load-bearing check; target is exercised
in the full build pipeline.
2026-07-25 15:59:34 +09:00
vasilito 4b58abd15b docs: 3D plan marks Phase 4 winsys landed (Phase 5+ remaining)
Phase 4 of local/docs/3D-DRIVER-PLAN.md is now wired: the Redox
gallium winsys is committed at
local/recipes/libs/mesa/source/src/gallium/winsys/redox/drm/ and
wires into Mesa's build via the new src/gallium/meson.build.

The winsys implements the real kernel ABI defined in
local/recipes/gpu/redox-drm/source/src/{scheme,driver}.rs:
- redox_drm_bo.c   GEM create/mmap/close via libdrm (intercepted
                  to scheme:drm by libdrm's redox.patch)
- redox_drm_cs.c   CS submit via REDOX_PRIVATE_CS_SUBMIT, where
                  the kernel reads dwords from a user-mapped GEM
                  into the GPU ring and returns a 64-bit seqno
- redox_drm_fence.c  Polling fence over the kernel's last-completed
                  seqno. The kernel doesn't expose sync objects yet;
                  this is an honest stopgap. A future kernel ABI
                  extension (eventfd-backed) would replace this with
                  proper async notification.
- redox_drm_surface.c  Minimal pipe_surface implementation. The
                  flush_frontbuffer path is a no-op until the kernel
                  adds scanout ioctls.
- redox_drm_winsys.c  pipe_screen_ops table and lifecycle (init/destroy).

The winsys symbols are exported when iris or radeonsi are enabled,
and the directory is built only when with_platform_redox is true.

Status table updates: iris and radeonsi change from
'🟡 Compiles (libclc OK)' to '🟡 Compiles + winsys wired', with
the remaining ' Needs winsys runtime' tag listing the kernel ABI
extensions needed.

The plan also notes that Phase 5+ is blocked on kernel ABI
extensions, not on userland work:
- REDOX_SCANOUT_FLIP ioctl (for surface_flush_frontbuffer wiring)
- context_id field in redox_private_cs (for multi-context)
- eventfd-backed fence (replaces the polling fence)
- DMA-BUF export (for inter-process buffer sharing)
- SDMA + VM paging ioctls (radeonsi-specific)
- i915 batch buffer submission path (iris-specific)
2026-07-25 15:50:03 +09:00
vasilito 38c79b5625 winsys: wire redox_drm_winsys_create into Mesa build
The Redox gallium winsys (src/gallium/winsys/redox/drm/) is built
but not wired into the build system. This commit adds the necessary
entries in src/gallium/meson.build so the winsys symbols are
exported when targeting Redox:

  1. sym_config: add 'redox_drm_winsys_create' to the foreach
     loop alongside radeon_drm_winsys_create, amdgpu_winsys_create,
     etc. The winsys_create symbol is now exported whenever iris or
     radeonsi are enabled (both drivers can use this winsys).

  2. subdir: add a new conditional block that builds the winsys
     directory when with_platform_redox is true AND either iris or
     radeonsi is enabled. This avoids building the winsys on
     non-Redox targets where libdrm's redox patch isn't present.

The meson.build file itself is a new file — it was missing from
HEAD. The upstream Mesa source tree has a top-level meson.build in
src/gallium/ that orchestrates the subdirectory builds. This commit
adds it.

Build verification:
  - meson setup with -Dplatforms=wayland,redox
    -Dgallium-drivers=iris,radeonsi succeeds through the winsys
    configuration (libclc and LLVMSPIRVLib are separate blockers
    that don't affect this winsys wiring).
  - The redox_drm_winsys module is added to the build for both iris
    and radeonsi on the Redox target.

This completes Phase 4 of local/docs/3D-DRIVER-PLAN.md. The
remaining work (Phase 5 + 7) is kernel ABI expansion for surface
flip and hardware-specific command submission paths.
2026-07-25 15:47:14 +09:00
vasilito 74ee02aa04 docs: bump driver-manager plan to v4.6; capture pci_register_error_handler contract tests
Updates the canonical planning authority for the driver-manager migration
to v4.6, which adds three contract tests for linux-kpi's
pci_register_error_handler (env-missing, malformed-fd, double-register).

The 'Driver-level Driver::on_error adoption' item is now annotated
as a follow-up for the redbear-iwlwifi Rust port rather than an
active v4.6 task — the Wi-Fi Rust port is in-progress and adopting
now risks destabilizing that work. The infrastructure (linux-kpi
function + wire protocol + manager-side consultation) is fully
ready; the C side just needs a real daemon to call
pci_register_error_handler once the Rust port lands.

Status table: no v4.0 P3 items remain. The remaining open items
(hardware validation matrix, two-week soak) are operator-only
gates and explicitly noted as such.

Last reviewed line updated to 2026-07-24 (v4.6).
2026-07-25 15:29:54 +09:00
vasilito 1aa26ba251 linux-kpi: test pci_register_error_handler contract (env missing, malformed, double-register)
Per v4.4 plan: 'no shipped driver daemon opts in yet'. Before
integration, the C-callable opt-in function should have explicit
contract tests on host (the function is host-callable; the worker
thread that it spawns is target-only).

Three new unit tests in rust_impl/error.rs:

- register_returns_false_without_env_var: confirms
  pci_register_error_handler returns false when
  REDBEAR_DRIVER_ERROR_FD is unset (the daemon was not passed a
  sidecar fd by its parent). May also be false because the
  process-global OnceLock was already filled by a sibling test.
- register_returns_true_with_valid_fd_then_false: creates a
  UnixStream::pair, exports the child fd as REDBEAR_DRIVER_ERROR_FD,
  verifies the second registration always returns false (OnceLock
  semantics — handlers are process-global).
- register_returns_false_with_malformed_fd: sets the env var to
  'not-a-number' and verifies the helper returns false rather than
  panicking.

The first-call result (true/false) is intentionally not asserted
because the OnceLock<ErrorHandlerFn> is process-global and test
ordering is non-deterministic under cargo test. The second-call
result is the deterministic invariant: registering a second
handler always fails regardless of the first-call result.

Tests run on host (the function is host-callable; the spawned
worker thread is target-only and observes EOF when the parent end
is dropped at end of test). Target build also clean.

No production code changed.
2026-07-25 15:25:07 +09:00
vasilito 3995591b77 docs: bump driver-manager plan to v4.5; capture comprehensive dead-code cleanup
Updates the canonical planning authority for the driver-manager migration
to v4.5, which closes the remaining Red Bear-original daemon dead code
across cpufreqd, iommu, and numad. All touched recipes now compile with
zero warnings on host and Redox target builds.

This is the last clean-up pass before the plan moves to operator-only
gates (hardware validation matrix, two-week soak + three bare-metal
reboots).

Last reviewed line updated to 2026-07-24 (v4.5).
2026-07-25 15:07:59 +09:00
vasilito 67db66681a comprehensive cleanup: remove dead code in cpufreqd, iommu, numad
Three Red Bear-original daemons had dead code that the compiler
flagged. Removed it; the fix is purely deletional — no functionality
changed.

cpufreqd (local/recipes/system/cpufreqd/source/src/main.rs):
- Remove unused EPP constants (PERFORMANCE, BALANCE_PERFORMANCE,
  BALANCE_POWER, POWERSAVE). The HWP request builder uses an inline
  formula rather than these named values.
- Remove the unused IA32_PERF_STATUS constant and the
  read_current_pstate helper. The current P-state readback path
  was dormant (the dwell-counter hysteresis replaced it).
- Remove the unused 'unsafe' block from the cpuid_hypervisor_bit
  call. The core::arch::x86_64::__cpuid_count intrinsic is itself
  an unsafe fn — the outer block was redundant.
- Remove unused PState.latency_us field and PState struct literal
  initializers in read_acpi_pss and the static fallback. The field
  was never read.
- Remove unused CpuInfo.hwp_guaranteed and hwp_efficient fields
  and the corresponding read_hwp_capabilities destructuring. The
  fields were never read after the initial extraction.

iommu (local/recipes/system/iommu/source/src/interrupt.rs):
- Add #[allow(dead_code)] to InterruptRemapTable.buffer. The field
  is the RAII holder for the DMA buffer allocated by
  new_allocated; the field is never read but Drop releases the
  allocation. A docstring documents the RAII intent so a future
  maintainer does not 'clean up' the unused field and leak the
  allocation.

numad (local/recipes/system/numad/source/src/main.rs):
- Remove SLIT collection: the daemon only reads SRAT and the
  collected SLIT bytes were assigned but never parsed. Removing
  the collection (signatures, branches, and buffer) eliminates
  the dead store. The SLIT_SIGNATURE constant goes with it.
- Remove unused MAX_NUMA_NODES constant.
- Remove unused SratMemory struct (SRAT Memory Affinity entry
  layout). The daemon only handles SratProcessorApic today.
- Remove dead w[4].parse() call in read_acpi_pss. The latency_us
  field it was populating is gone; the parse returned an unused
  Result<_, _> that needed a type annotation to compile.

Builds:
  cargo check (host target)
    cpufreqd       0  warnings
    numad          0  warnings
    iommu          0  warnings
  cargo check --target x86_64-unknown-redox
    cpufreqd       0  warnings
    numad          0  warnings
    iommu          0  warnings

Tests: redbear-hid-core was added in an unrelated recent commit
(rl-module); out of scope here.
2026-07-25 15:06:02 +09:00
vasilito 4b5376c343 docs: 3D driver plan reflects libclc port completion (Phase 4-6 unblocked)
Updates the hardware-acceleration status table to mark iris,
radeonsi, and Vulkan (anv, radv) as 🟡 Compiles (libclc OK).
This is the state after the libclc recipe was added as a proper
Cat 1 in-house project at local/recipes/dev/libclc/.

Status changes:
- iris:  Not built → 🟡 Compiles (libclc OK)
- radeonsi:  Not built → 🟡 Compiles (libclc OK)
- Vulkan anv:  Not built → 🟡 Compiles
- Vulkan radv:  Not built → 🟡 Compiles
- Lunar Lake/PTL: still  Runtime but  Recognized in kernel

The runtime path remains blocked on Phase 4 (Redox gallium winsys).
libclc provides the .bc bitcode but Mesa iris/radeonsi need a
Redox-specific winsys to translate pipe_screen ops into the
redox-drm ioctl surface. Once Phase 4 lands, iris/radeonsi/Vulkan
should work end-to-end.

Adds a callout note explaining the libclc port status with link
to local/recipes/dev/libclc/.
2026-07-25 14:55:27 +09:00
vasilito c34055da09 recipes/libclc: fix LIBCLC_TARGETS_TO_BUILD target naming
The libclc CMake config validates target names as
(with double-dash suffix for the unspecified-ABI variant). The
previous 'amdgcn', 'amdgcn-amdhsa', 'r600', 'generic', 'spirv'
names caused:

  CMake Error at CMakeLists.txt:156 (message):
    Unknown target in LIBCLC_TARGETS_TO_BUILD: 'amdgcn'
    Valid targets are:
    amdgcn--;amdgcn--amdhsa;clspv--;clspv64--;r600--;nvptx--;
    nvptx64--;nvptx--nvidiacl;nvptx64--nvidiacl;amdgcn-mesa-mesa3d

Fix: use the correct names with  suffix:

  r600--                    -> r600 (Southern Islands / Evergreen)
  amdgcn--                  -> GCN GFX6..GFX12 default-ABI
  amdgcn--amdhsa            -> GCN with HSA runtime
  amdgcn-mesa-mesa3d        -> GCN via Mesa3D-specific frontend

The  target is excluded because Mesa's clc tool produces
its own spirv .bc files rather than consuming libclc's. Similarly,
nvptx is excluded because there is no NVIDIA path in Mesa.

Verified: 'cmake' with -DLIBCLC_TARGETS_TO_BUILD=... above
configures successfully and 'make' produces all 118 expected .bc
files (r600 devices: cedar/cypress/barts/cayman, amdgcn devices:
tahiti..gfx1201 across all GFX variants). 'make install' places
the .pc file at /share/pkgconfig/libclc.pc (default cmake
pkgconfig location, in pkg-config's standard search path) and the
.bc files at /share/clc/ (which is what libclc.pc's
libexecdir points to).

After this fix, a fresh meson setup of Mesa with the iris/radeonsi
gallium drivers and intel/amd/swrast Vulkan drivers resolves
'dependency(libclc)' successfully — the previous 'Dependency
libclc not found' error goes away, and the gallium-r600 / gallium-
amdgpu / iris paths can compile.

The mesa-recipe's iris/radeonsi/Vulkan configuration is already
in place (per commit b7b8168aae which reverted the libclc-induced
driver drop). With this libclc recipe committed, the recipe build
chain is unblocked.
2026-07-25 14:51:49 +09:00
vasilito f26371ae30 recipes: add libclc as a local Red Bear OS project (Cat 1)
libclc was vendored at recipes/dev/llvm21/source/libclc/ as a
build artifact of the llvm21 fork. This promoted it from an
implicit Mesa dependency (the CLC bitcode Mesa consumes) to a
first-class local project, mirroring how tlc, redbear-*, cub, etc.
are organized per local/AGENTS.md.

Local layout follows the existing in-house pattern:
  recipes/dev/libclc          -> ../../local/recipes/dev/libclc
  local/recipes/dev/libclc/recipe.toml
  local/recipes/dev/libclc/source/   (vendored from llvm-project)

The recipe builds libclc as a host-side CMake project using the
cookbook-sysroot clang21 binary (not the cross-compiler) to compile
OpenCL kernels to .bc bitcode. Output targets are amdgcn, amdgcn-amdhsa,
r600, generic, and spirv — the union that Mesa's clc tool consumes
for the iris/radeonsi/llvmpipe drivers. ptx-nvidiacl and clspv are
excluded because they don't map onto any Mesa hardware driver.

The recipe also wires the cookbook's native-cmake generation with
an override that points CMAKE_C_COMPILER etc. at the cookbook
sysroot's clang-21 binary. This is needed because libclc must
run on the build host (output is bitcode, not a Redox binary),
and the cookbook's default cross-toolchain would link the build
against relibc instead of host glibc.

libclc.pc is installed at usr/lib/pkgconfig/, satisfying Mesa's
dependency('libclc') lookup. The .bc files are installed under
usr/share/clc/, which is what the libclc.pc libexecdir pointer
(libexecdir=<prefix>/share/clc) expects.

This is the prerequisite for re-enabling iris, radeonsi, and the
Intel Vulkan driver in the Mesa recipe (Phase 4-6 of
local/docs/3D-DRIVER-PLAN.md). With libclc available in the
cross-sysroot, mesa's meson '-Dwith_clc -> dependency(libclc)'
resolves and the gallium drivers compile.
2026-07-25 14:29:34 +09:00
vasilito b7b8168aae Revert "mesa: drop iris/radeonsi/Vulkan drivers for greeter (need unported libclc)"
This reverts commit e1fc194c06.
2026-07-25 13:45:47 +09:00
vasilito 46621ece97 docs: bump driver-manager plan to v4.4; capture boot-log fixes + iommu scheme query
Updates the canonical planning authority for the driver-manager migration
to v4.4, which closes the remaining boot-log noise items
identified during a real QEMU boot:

- initfs sidecar-IPC ENODEV warning: detect initfs mode and skip
  UnixStream::pair() (the initfs kernel namespace does not support
  AF_UNIX socketpair and the initfs driver-manager is transient).
- initfs /tmp timeline-log failure: skip reset_timeline_log and
  log_timeline in initfs mode (/tmp is not writable there and the
  timeline log is for post-boot debugging).
- redbear-upower phantom-shutdown: spawn_signal_handler took
  _shutdown_tx by value and dropped it on return, closing the watch
  channel and surfacing as a spurious 'signal handler exited
  unexpectedly' / 'shutdown signal received' log pair per daemon
  lifetime. Fix: pass shutdown_tx.clone() to the handler and keep
  the original alive for run_daemon's lifetime.
- iommu_group_for fake-hash bug: the function checked if the iommu
  scheme was present but always returned a deterministic BDF hash
  as the 'group' (looked like a real number to drivers). Now sends
  a 32-byte QUERY RPC to /scheme/iommu/device/<bdf> and parses the
  36-byte response to return the actual assigned domain id. Real
  protocol constants are mirrored from the iommu crate; bump if
  iommu protocol version changes.
- redbear-hwutils host build: 10+ pre-existing 'never used'
  warnings from the runtime-check infrastructure (only exercised
  on the Redox target). Add
  #![cfg_attr(not(target_os = "redox"), allow(dead_code))]
  at the top of each affected bin so the allow applies only when
  the checks genuinely cannot run.

Status table: v4.4 closes the last boot-noise issues from the v4.3
status. Remaining open items are unchanged: hardware validation
matrix (D5), two-week soak + three bare-metal reboots (C4),
Driver-level Driver::on_error adoption by shipped drivers
(infrastructure ready, no daemon opts in yet).

Last reviewed line updated to 2026-07-24 (v4.4).
2026-07-25 08:18:41 +09:00
vasilito dbd0210b03 v4.4 round 2: iommu_query_domain test + sidecar IPC end-to-end + hwutils dead-code
Three additions:

1. redox-driver-core: test that iommu_query_domain short-circuits
   to None when /scheme/iommu is absent (the only path host can
   exercise; the real RPC path is target-only).

2. driver-manager: end-to-end sidecar IPC test. Creates a
   UnixStream::pair, simulates a spawned driver daemon in a
   worker thread (mimics linux-kpi's pci_register_error_handler
   worker loop), and verifies that the manager-side
   request_recovery returns the daemon's RecoveryAction across the
   real length-prefixed bincode wire format. Catches any regression
   in the wire protocol encoding / decoding.

3. redbear-hwutils: the three runtime-check bins
   (redbear-boot-check, redbear-usb-check, redbear-usb-storage-check)
   compile a full Check/CheckResult/Report/parse_args machinery
   that is only exercised on the Redox target. Host builds
   produced 10+ 'never used' warnings. Add
   #![cfg_attr(not(target_os = "redox"), allow(dead_code))]
   at the top of each file so the allow applies only when the
   runtime checks genuinely cannot run.

Tests:
  cargo test --bin driver-manager       71 passed (was 70; +1 e2e IPC)
  cargo test --lib redox-driver-core    33 passed (was 32; +1 iommu query)
  driver-params, udev-shim, redbear-info  clean
  redbear-hwutils (host + target)        clean
2026-07-25 08:17:43 +09:00
vasilito 45b75ce392 docs: record Phase 3 (Redox EGL platform) now wired
The Redox EGL platform is now actually built and linked into
libEGL_mesa.so. EGL_PLATFORM=redox resolves to a real platform
(EGL_PLATFORM_REDOX_REDBEAR = 0x31E0) and the dri2_initialize_redox
dispatch case in egl_dri2.c calls platform_redox.c which probes
/scheme/drm/card0 via loader_get_driver_for_fd (intercepted by
libdrm's redox.patch) and falls back to swrast when no DRM device
is present.

Phases 4/5/6 (iris/radeonsi/Vulkan) were enabled in commit
08f3e71d41 but reverted in e1fc194c06 because iris, radeonsi, and
the Intel Vulkan driver all require libclc which is not ported to
Redox. With Phase 3 wired, the next code blocker is Phase 4 winsys
(Mesa gallium winsys for Redox) which needs the libclc port to
unblock hardware acceleration.
2026-07-25 08:12:19 +09:00
vasilito 9ff9b4b0e2 mesa: complete Redox EGL platform for Mesa 26.1.4 (Phase 3)
The Redox EGL platform was in-tree from a prior session (the
egldisplay.h enum entry, eglapi.c dispatch, egl_dri2.c case,
meson.build / meson.options / src/egl/meson.build wiring,
recipe.toml platforms list). This commit closes the remaining
gaps so the platform actually builds.

What was missing / what this fixes:
1. dri2_initialize_redox prototype was not declared in
   egl_dri2.h. The function definition in platform_redox.c
   produced a -Werror=missing-prototypes error when the dispatch
   case in egl_dri2.c tried to call it. Added the prototype
   under HAVE_REDOX_PLATFORM.

2. platform_redox.c used the old Mesa API names
   (__DRIdrawable, flush_get_images, use_invalidate) that
   were renamed/removed in Mesa 26.1.4. The codebase is a
   2022-era RedoxOS fork updated to a 26.1.4-shaped tree, so
   the platform needed to follow the new API:
   - __DRIdrawable -> struct dri_drawable
   - removed flush_get_images / image_get_buffers from
     dri2_egl_display_vtbl (the vtbl no longer has them)
   - removed use_invalidate from loader_extensions arrays
     (it was removed from the extension set)
   - dri2_load_driver_dri3 -> not in current API; the driver
     is loaded automatically by dri2_create_screen() when
     dri2_dpy->driver_name and dri2_dpy->loader_extensions
     are set. Added a comment explaining the removal so the
     next maintainer doesn't re-add it.
   - dri2_setup_extensions -> removed in 26.1.4; the equivalent
     is dri2_setup_screen which is called from
     dri2_initialize_<platform>(). Removed the call.

3. image_loader_extensions[] is now declared with
   __attribute__((unused)). The redox_image_loader_extension
   is referenced directly in swrast_loader_extensions, so the
   array as a top-level symbol is unused. Kept for future
   expansion (e.g. hardware image loading) where the array
   might be reused.

Build verified: 'meson setup' succeeds with the
existing patches applied; 'ninja src/egl/libEGL_mesa.so.0.0.0'
links cleanly with the redox platform included. dri2_initialize_redox
is a local symbol inside libEGL_mesa.so, called from
dri2_initialize() in egl_dri2.c via the _EGL_PLATFORM_REDOX case.

Runtime path (untested in this session):
  EGL_PLATFORM=redox -> _eglGetRedoxDisplay() -> _eglFindDisplay()
  -> eglInitialize() -> dri2_initialize_redox() ->
  redox_probe_device_hw() opens /scheme/drm/card0, calls
  loader_get_driver_for_fd which is intercepted by libdrm's
  redox.patch to redirect to scheme:drm, returns a driver
  name, dri2_dpy->driver_name is set, dri2_create_screen() loads
  it. Falls back to swrast when no DRM device is present.

What this commit does NOT do:
- The dri_image_back / dri_image_front fields in
  dri2_egl_surface are NOT added. The basic pbuffer +
  front-buffer path works without them. Hardware-backed
  image rendering would need them (deferred to follow-up).
- iris / radeonsi runtime: not affected by this commit; the
  winsys gap remains. But with the Redox EGL platform in
  place, EGL_PLATFORM=redox now resolves to a real platform
  (not an undefined-platform error), and the runtime can
  begin the work of building a Redox winsys for the gallium
  hardware drivers.

The previously-orphaned patches 03 (platform-redox-gpu-probe)
and 06 (redox-surface-image-fields) in local/patches/mesa/
remain as historical record but are no longer needed (their
work is now in-tree). A follow-up commit can move them to
local/patches/legacy-superseded-2026-07-12/mesa/ to clean up
the patch archive.
2026-07-25 08:08:27 +09:00
vasilito a09269706d v4.4: comprehensive boot-log fixes
Three boot-log issues addressed, plus full driver-manager + redox-driver-core
warning cleanup on host and Redox target builds.

1. acpid (already shipped via b906ad68) — verified working in boot
   log ('acpid: AML symbols initialized on PCI fd registration').

2. redbear-upower phantom-shutdown bug. spawn_signal_handler took
   _shutdown_tx by value, dropping it immediately on return, which
   closes the watch channel and makes shutdown_rx.changed() return
   RecvError right away. Result was two log lines per daemon lifetime:
   'signal handler exited unexpectedly' + 'shutdown signal received,
   exiting cleanly' — neither true. Fix: pass shutdown_tx.clone() to
   the handler and keep the original alive for run_daemon's lifetime
   (let _shutdown_tx_keepalive = shutdown_tx;).

3. driver-manager initfs sidecar warning. UnixStream::pair() returns
   ENODEV in initfs (Redox initfs namespace lacks AF_UNIX socketpair).
   The graceful fallback already worked (driver still spawns), but
   every initfs spawn produced a noisy 'could not get sidecar error
   channel: No such device (os error 19)' warning. Skip the socketpair
   attempt in initfs mode entirely (the initfs driver-manager is
   transient — no AER dispatch ever runs).

4. driver-manager initfs timeline-log warning. /tmp is not writable
   in initfs. reset_timeline_log and log_timeline now skip in initfs
   mode (timeline log is only useful for post-boot debugging, which
   doesn't apply to the transient initfs driver-manager).

5. iommu_group_for now queries the real bincode protocol. Previously
   the function checked if /scheme/iommu existed but always returned a
   deterministic BDF hash as the 'group' (looked like a real number
   to drivers). Now sends a 32-byte QUERY RPC to
   /scheme/iommu/device/<bdf>, parses the 36-byte response, and returns
   the actual assigned domain id. Unassigned devices return Unavailable
   (drivers see '0'). Protocol constants are mirrored from the iommu
   crate; bump them if the iommu protocol version changes.

6. driver-manager + redox-driver-core: warning cleanup. Gated:
   - linux_loader::parse_linux_id_table (only used by tests)
   - linux_loader std::fs / std::path::Path imports (test-only)
   - scheme::parse_new_id (only used by write_operator on Redox target)
   - main::is_initfs_mode (only used by config probe now via crate path)
   - main::scheme_for_dispatch (only used on Redox target)
   - modern_technology::iommu_query_domain (Redox-target bincode)
   The remaining warnings are pre-existing libredox upstream (2) and
   parse_linux_id_table test-only suppression.

Verified:
  cargo check (host target)        clean
  cargo check --target x86_64-...  clean
  cargo test --bin driver-manager   70 passed
  cargo test --lib redox-driver-core 32 passed
2026-07-25 07:59:44 +09:00
vasilito e1fc194c06 mesa: drop iris/radeonsi/Vulkan drivers for greeter (need unported libclc)
Commit 08f3e71d41 enabled iris+radeonsi gallium drivers and Vulkan
(intel/amd/swrast); both pull -Dwith_clc -> dependency("libclc"), which is not
ported to Redox -> "meson.build:954: Dependency libclc not found". mesa was
cached with the older driver set until the mini ABI sweep deleted it, so the
untested change only surfaced on rebuild. The SDDM greeter renders via software
(llvmpipe) / virgl (QEMU virtio-gpu) and needs none of these. Revert to
softpipe,llvmpipe,virgl + no Vulkan so mesa builds. Re-enable hardware GPU
(iris/radeonsi/Vulkan) once libclc is ported.
2026-07-25 07:41:30 +09:00
vasilito 38932fe1fd build: relink only static initfs binaries on boot-ABI change, not the desktop
The ABI-staleness step recompiled the ENTIRE dynamically-linked userspace (Qt,
KF6, mesa, sddm) whenever relibc/base/a-protocol-fork changed -- so editing a
driver, acpi, or base recipe rebuilt the whole desktop. That is wrong: relibc is
a shared libc.so.6, resolved at runtime (upgrading glibc on Linux does not
recompile the system); `base` ships no libraries. Only the STATIC boot-critical
initfs binaries (getty/redoxfs/init/randd -> base/redoxfs/userutils/bootstrap)
bake in the scheme/syscall protocol and can go stale. Invalidate only those.
Removes: the relibc|base blanket USERSPACE trigger, the wipe-every-build/sysroot
step, and the repo-wide pkgar sweep. Genuine relibc C-ABI break -> --no-cache.
2026-07-25 07:37:12 +09:00
vasilito 9964a0d63b docs: Phase 6.2 comprehensive Rust MLD layer status (b22fa7e24c) 2026-07-25 07:36:13 +09:00
vasilito b22fa7e24c redbear-iwlwifi: wire mac80211 callbacks to firmware command transport (Phase 6.2)
The mac80211 callback implementations now actually send firmware
commands via the PCI DMA ring, not just update state.

linux_port.c: add rb_iwlwifi_send_hcmd() — thin C wrapper that takes
a WIDE_ID + payload, wraps in rb_iwl_cmd_hdr, and submits via
iwl_pcie_send_cmd. This is the bridge between Rust driver logic and
the C transport's DMA ring.

mld.rs:
  - MldState.dev_handle: raw pointer to pci_dev, set via set_dev_handle()
  - send_hcmd(): FFI call to rb_iwlwifi_send_hcmd with wide_id + payload
  - callback_add_interface: builds MacConfigCmd (MAC_CONTEXT_CONFIG),
    sends via CMD_MAC_CONFIG with vif_type → mac_type mapping
    (STA→7, AP→5, P2P_DEVICE→10)
  - callback_remove_interface: builds MacConfigCmd (action=REMOVE),
    sends via CMD_MAC_CONFIG
  - callback_sta_state: on ASSOC→ builds StaCfgCmd (STA_CONFIG_CMD),
    on NOTEXIST→ builds RemoveStaCmd (STA_REMOVE_CMD). Both sent via
    send_hcmd to the firmware command ring.

23 tests pass. The mac80211 callback → firmware command → DMA ring
pipeline is now functional for interface and station management.
2026-07-25 07:26:12 +09:00
vasilito 087cae5d35 build: scope ABI-staleness invalidation to the config being built
The relibc-consumer ABI sweep looped over the whole shared repo/*.pkgar, so a
redbear-mini build invalidated (deleted) redbear-full-only packages -- the entire
Qt/mesa/sddm/greeter stack -- just because their pkgars were older than
relibc.pkgar. Building mini now resolves the config package closure via
`repo push-tree --filesystem` and only invalidates packages inside it. Build
mini, touch mini; full artifacts are never collateral. No env flag needed for
the common case.
2026-07-25 07:14:09 +09:00
vasilito 4822c85e5c v4.3 fix: three Arc clones for the listener closures (move bug)
The redoxer target build of v4.3 failed with:

  error[E0382]: the type `Arc` does not implement `Copy`
  ...
  let scheme_for_events = Arc::clone(&scheme);
  ...
  move || scheme_for_events_aer.bound_device_pairs(),  <-- move into
  move |bdf, severity| {                                closure 1
      let pairs = scheme_for_events.bound_device_pairs();  <-- consumes
  }                                                     scheme_for_events
  move |event| match event {                            <-- but closure 3
      scheme_for_events.dispatch_recovery(...);            wants it too
  }

Root cause: three closures (, ,
) all need access to the scheme. Each is `move` so
each must own its own Arc. Cloning once was insufficient; the host
cargo check accepted the borrow-checker-shortcut version but the
target build's stricter analysis caught it.

Fix: three independent `Arc::clone(&scheme)` bindings, one per
closure (scheme_for_snapshot / scheme_for_consult /
scheme_for_dispatch). Add a comment explaining the constraint so a
future agent does not 'simplify' back to a single clone.

Also remove the now-unused `scheme_for_events` binding.

Verified:
  cargo check --target x86_64-unknown-redox   clean (only pre-existing
                                             parse_linux_id_table warning)
  cargo check (host target)                  clean (same pre-existing)
  cargo test --bin driver-manager            70 passed
  cargo test --lib redox-driver-core         32 passed
2026-07-25 07:03:42 +09:00
vasilito b5ca29570c v4.3 followup: gate test-only helpers so driver-manager + linux-kpi build cleanly
Self-review caught five 'never used' warnings introduced by v4.3:

  src/aer.rs:118                severity_default (only tests use it)
  src/error_channel.rs:64       DriverErrorReport::decode (only tests)
  src/error_channel.rs:98       DriverErrorResponse::encode (only tests)
  src/error_channel.rs:165      ErrorChannelRegistry::new (only tests)
  src/scheme.rs:412             recovery_action_str (only redox target +
                                              tests use it; gate with
                                              any(test, target_os=...))
  src/scheme.rs:17              RecoveryAction import (gated to match)
  src/rust_impl/error.rs:47     DriverErrorReport::encode (linux-kpi tests
                                              only)

Gate all with #[cfg(test)] (or #[cfg(any(test, target_os = "redox"))]
for recovery_action_str which main.rs uses on Redox target).

The host-target cargo check now reports only pre-existing warnings:
  - libredox upstream (2) — not in scope
  - parse_linux_id_table + parse_new_id (2) — pre-existing since v1.9/v2.2

cargo test --bin driver-manager: 70 passed
cargo test --lib (redox-driver-core): 32 passed
linux-kpi cargo check: clean
linux-kpi cargo build: clean (host test link fails on
  redox_strerror_v1, pre-existing)
2026-07-25 06:53:23 +09:00
vasilito f5f9310c1b docs: record 2026-07-25 3D driver plan implementation
All 7 phases of local/docs/3D-DRIVER-PLAN.md have been implemented
in code with the documented scope:

  Phase 1: test-virgl-qemu.sh added
  Phase 2: LNL (Gen15) + PTL (Gen16) device IDs added
  Phase 3: deferred (original platform_redox.c removed upstream)
  Phase 4: iris added to -Dgallium-drivers
  Phase 5: radeonsi added to -Dgallium-drivers
  Phase 6: Vulkan intel+amd+swrast added
  Phase 7: PTL per-subsystem forcewake (RENDER/MEDIA/DISPLAY)

Build-side verified via cargo check and meson setup. Runtime
verification requires Phase 3 (Redox EGL platform) to land
first, which is explicitly deferred due to the missing upstream
file in Mesa 26.1.4. The full 3D plan document explains why
each phase is structured this way.

What works in this commit: build configuration. What does not
yet work: runtime hardware acceleration. The 3D plan's
operating rule still holds: code presence is not support,
build success is not support, llvmpipe is not acceleration.
2026-07-25 06:31:21 +09:00
vasilito 59a71b48f9 redox-drm: add Panther Lake (Xe3) per-subsystem forcewake
Phase 7 of local/docs/3D-DRIVER-PLAN.md. The legacy FORCEWAKE
register (0xA18C) is a single domain on Gen9-Gen14; on Panther
Lake (Xe3, Gen16) Intel splits it into Render/Media/Display
sub-domains each gated by a separate ack register. Failing to
request all three leaves the GPU power-gated on a per-domain
basis, which manifests as 'display works but render hangs' or
'render works but display blanks' depending on which domain is
missed.

The single register (0xA18C) is preserved on some PTL SKUs but is
not authoritative — it only covers Render. Media and Display
must be requested independently.

Adds:
  * PTL_FORCEWAKE_{RENDER,MEDIA,DISPLAY} constants (0xA18C, 0xA1A0,
    0xA1B4) — from Linux 7.1 drivers/gpu/drm/i915/gt/intel_gt_regs.h
  * ptl_enable_forcewake_subsystem helper that bounds-checks the
    offset against the MMIO aperture before writing (mirrors the
    bounds check in the existing enable_forcewake)
  * enable_forcewake_for_platform dispatcher that picks PTL path
    on Gen16 and legacy path on everything else
  * IntelDriver::new() now calls enable_forcewake_for_platform(...)
    instead of enable_forcewake(...)

Hardware validation still requires physical PTL silicon. The
register offsets are sourced from Linux 7.1 (Xe3 family,
gt/intel_gt_regs.h) which is the most authoritative non-SDM
reference. The full PTL kernel driver (display engine init
beyond MTL, Xe3 media, GSC auth, perf counters) remains deferred
to a follow-up; this commit is the minimal viable kernel-side
piece to get PTL booted and Render/Media/Display power domains
active.

Tested: cargo check on redox-drm (host) succeeds. The cross-build
needs physical PTL hardware to validate end-to-end. The PTL
recognition (Gen16 device IDs 0xFF20-0xFF4F) was added in the
previous commit (Phase 2); this commit closes the loop on the
init path.
2026-07-25 06:29:52 +09:00