Commit Graph

3379 Commits

Author SHA1 Message Date
Red Bear OS 717bc436be ixgbed: use MSI-X (via pci_allocate_interrupt_vector) when available
The previous code unconditionally required a legacy INTX line, which
on bare metal is missing for nearly every modern 82599/X540/X550
board that has its IRQ lines wired to MSI-X only. pcid_interface
allocates MSI-X when the device advertises it, falls back to MSI,
then to legacy INTX, so the change preserves every existing path
while unlocking the much higher line-rate headroom of MSI-X
per-vector queuing that the device's enable_msix_interrupt code
already implements in device.rs.

The IRQ-acknowledge-and-write pattern is unchanged: the kernel
masks the line on delivery, we must re-arm unconditionally or a
foreign interrupt on a shared line leaves the line masked forever.
2026-07-26 17:28:21 +09:00
Red Bear OS 887718da49 acpid: wire lid-open to exit_s2idle (symmetric with lid-closed)
Round 2 follow-up to lid-closed → enter_s2idle wiring. Without
the symmetric lid-open → exit_s2idle call, the system stays in
'wake devices armed' state after the lid opens (until the kernel
kstop reason=2 path fires, which only happens if MWAIT actually
engaged).

Lid-open now runs the AML wake sequence (_SST(2) → _WAK(0) →
_SST(1) + wake-device disarming). The kernel-side MWAIT-return
path also calls exit_s2idle(); the double-call is safe because
AML _WAK/_SST methods are spec-required to be idempotent in the
working state (ACPI 6.5 §3.5.3).

External-display detection (Linux's HandleLidSwitchDocked=ignore)
is still not wired — every lid-close triggers s2idle. Documented
as a follow-up in the LG Gram assessment doc.
2026-07-26 17:25:50 +09:00
Red Bear OS 1331b8c017 rtl8168d: DMA barriers + drop false RTL8125 claim from config.toml
- device.rs: release fence before tppoll doorbell write; acquire
  fence after the OWN-bit read on the receive descriptor. The
  Realtek descriptor hand-off is the same OWN-bit protocol as
  e1000d, and the same reordering argument applies: on aarch64
  with relaxed ordering the device can clear OWN and update
  length+status in any order, and without a fence we can
  observe OWN=0 paired with a stale length and compute a partial
  read.
- config.toml: drop the description's RTL8125 reference. The
  rtl8168d register layout does not support rtl8125 (a 2.5GbE
  chip with its own register layout and PHY init sequence); the
  description now matches the actual capability.
2026-07-26 17:19:16 +09:00
Red Bear OS 28e356d598 acpid: fix common path bug (was depth-3 notation in depth-2 crate)
acpid lives at drivers/acpid/ (depth 2 in the base workspace). All
other depth-2 crates (pcid, hwd, inputd, vboxd, rtcd, thermald,
virtio-core, redoxerd) correctly use path = "../common" (1 '..') to
reach drivers/common/. acpid was the sole outlier using "../../common"
(2 '..'), which resolves to base/common/ — a path that has never
existed in this fork.

The build script's overlay-integrity auto-repair mechanism normally
papers over this (creating a transient symlink or rewriting the path
during staging). When that mechanism fails — as it did during
LG Gram Round 1 verification ("5 recipe.toml files could not be
restored") — the bug surfaces as a hard manifest-load failure:

  error: failed to load manifest for workspace member
    .../local/sources/base/drivers/acpid
    failed to load manifest for dependency 'common'
    failed to read .../local/sources/base/common/Cargo.toml
    No such file or directory (os error 2)

The fix is one character: "../../common" → "../common". This makes
acpid consistent with the 8 other depth-2 crates and removes the
dependency on the build-script overlay-repair hack.

No semantic change — same crate, same workspace membership, just a
correctly-resolving path.
2026-07-26 17:14:34 +09:00
Red Bear OS b3fd5cc682 e1000d: DMA barriers on RX and TX descriptor paths
Without explicit memory ordering, the Rust compiler is free to
reorder loads of the device-written descriptor (status, length)
relative to the writeback of the descriptor ownership flag. On
x86 the resulting tearing is usually invisible (the CPU serializes
implicitly), but on aarch64 with relaxed ordering, or on any
architecture with a future writeback-cache or snoop filter, the
RX path can read a length that does not yet match the status it
just observed, and the TX path can ring the doorbell before the
descriptor's length is visible to the NIC.

Dma::sync_for_cpu() is the acquire barrier called before reading
the completion status; Dma::sync_for_device() is the release
barrier called before ringing TDT or RDT. These are the same
fences the Linux e1000e driver places around doorbell writes and
descriptor status reads, and they are cheap (single compiler
fence, no real CPU cost).
2026-07-26 17:12:18 +09:00
Red Bear OS 263a41a926 bootstrap: fix broken INITNSMGR-CONCURRENCY-DESIGN.md reference
After commit 589a1044e6 (parent repo) moved
local/docs/INITNSMGR-CONCURRENCY-DESIGN.md to
local/docs/legacy-obsolete-2026-07-25/, the doc reference in
bootstrap/src/initnsmgr.rs became broken. Update it to point at
the archive path so future readers can find the design rationale.

Companion to the LG Gram Round 1 parent-repo commit (same date).
2026-07-26 16:58:00 +09:00
Red Bear OS 20d805ed37 netstack: parse_endpoint accepts bracketed IPv6
The endpoint parser previously only handled dotted IPv4 syntax
('10.0.2.15:80'). Extend it to accept the dual form that this same
change adds to relibc:

    [hh:hh:hh:hh:hh:hh:hh:hh]:port      (global)
    [hh:hh:hh:hh:hh:hh:hh:hh%scope]:port (link-local w/ scope)

The presence of '[' at the start is the unambiguous discriminator: in
that case the rest up to ']' is the host and everything after is the
port. Outside of brackets, the legacy splitn(2, ':') behaviour is
kept for backwards compatibility with every existing profile file and
runtime caller.

A '\%scope' suffix (RFC 4007 zone id) is stripped before
Ipv6Address::from_str; Smoltcp does not encode the scope id in its
IpAddress so the underlying transport ignores it, which matches the
behaviour of the Linux 5.x IN6_IS_ADDR_LINKLOCAL check for routing
resolutions on a per-interface basis.
2026-07-26 16:56:28 +09:00
Red Bear OS b887d2b450 netstack: bump smoltcp 0.12.0 -> 0.13.1 in Cargo.toml
The 0.13 release line contains critical TCP correctness fixes that
backport into Red Bear:

- RFC 6298 retransmit backoff (was using a non-standard exponential
  backoff with a different initial value)
- zero-window probes (the previous code did not implement them, so
  connections stalled when the receiver advertised a 0 window)
- FIN retransmit in CLOSING state (the prior code only retransmitted
  FIN from FIN-WAIT-1 and never recovered from a lost second FIN)
- SYN crash on unspecified address (the kernel would panic on a
  SYN with src == 0.0.0.0; the 0.13.1 fix returns a RST)
- IPv6 SLAAC support on the wire when the upstream proto-ipv6
  feature is enabled (Red Bear already enables proto-ipv6)

The code in scheme/ip.rs is already in 0.13.1 form (RawSocket::new
takes IpVersion directly, not Option<IpVersion>) and scheme/icmp.rs
already uses the 0.13.1 ip_protocol() signature, so the migration is
intentionally restricted to the version field. The Cargo.lock will be
regenerated by the canonical build (cookbook uses --locked, so the
next build-redbear.sh run will refresh the lockfile after the
workspace can resolve smoltcp 0.13.1).
2026-07-26 16:36:50 +09:00
Red Bear OS 45452c5a8e acpid+ps2d: wire SystemQuirkFlags consumers (LG Gram Round 1)
acpid: load SystemQuirkFlags from in-memory DMI at init via
redox-driver-sys::quirks::toml_loader::load_dmi_system_quirks.
Store as a field on AcpiContext and expose via system_quirks().
Wire two consumers:

  - FORCE_S2IDLE in set_global_s_state(3): routes S3 entry to
    s2idle preparation instead. LG Gram 16Z90TP, Framework 16,
    late Dell XPS advertise \_S3 in DSDT but the firmware refuses
    the SLP_TYP write and hangs / silently no-ops.

  - NO_LEGACY_PM1B in set_global_s_state(*): skips the PM1b write
    even when FADT reports a non-zero pm1b_control_block. LG
    firmware reports a PM1b block that does not exist on the
    platform; writes wedge the controller.

ps2d: load SystemQuirkFlags from /scheme/acpi/dmi at init via
redox_driver_sys::quirks::system_quirks(). Wire one consumer:

  - KBD_DEACTIVATE_FIXUP in Ps2::init(): skips SetDefaultsDisable
    (0xF5) during keyboard init. LG Gram + some Dell/HP/Lenovo
    keyboards wedge or drop keys when 0xF5 is sent (Linux
    atkbd.c keyboard_broken[] / atkbd_deactivate_input tables).

acpid/src/dmi.rs: reframe misleading 'stub' docstring on
try_load_existing() — the function is a real round-trip reader
for /scheme/acpi/dmi, not a stub.

Cargo.lock regenerated to include the new redox-driver-sys path
dependency in acpid and ps2d.

This is the consumer-wiring deliverable for LG Gram Round 1
(local/docs/evidence/lg-gram/ASSESSMENT-2026-07-26.md). The
matching redox-driver-sys stub-replacement work
(load_dmi_acpi_quirks real loader, PANEL_ORIENTATION_TABLE
populated with Linux DRM entries, ACPI_FLAG_NAMES + TOML parser)
lands in the parent repo in the same Round 1 push.

acpi_irq1_skip_override remains documented as needing kernel IRQ
setup work (out of scope for Round 1).
2026-07-26 16:30:50 +09:00
Red Bear OS 9e5f915d42 netstack+drivers: TCP write_buf return, dhcpd iface arg, virtio DMA sync, ip fpath
- tcp/scheme/tcp.rs: write_buf now returns the actual bytes from
  send_slice() instead of buf.len(). Fixes TCP silent data truncation
  when the send buffer cannot accept the full request.
- netstack/scheme/ip.rs: fpath() uses .expect() with a message in place
  of .unwrap() for clearer diagnostics on buffer write failure.
- dhcpd/main.rs: parse the first non-flag positional argument as the
  interface name. Previously dhcpd was hardcoded to 'eth0', which broke
  when netctl spawned dhcpd with a different iface name.
- drivers/common/dma.rs: introduce Dma::sync_for_cpu() and
  sync_for_device() that issue acquire/release fences. Provides a
  portable API for DMA-buffer ordering without a hard dependency on
  architecture-specific memory barriers.
- drivers/net/virtio-netd/scheme.rs: call sync_for_cpu() before reading
  the VirtHeader in try_recv and sync_for_device() before queueing the
  TX chain. Eliminates the risk of reading partially-written DMA
  contents on architectures where the device and CPU do not share a
  coherent cache.
2026-07-26 16:26:58 +09:00
kellito 8c7f6172a2 v5.3: initnsmgr event-driven deferred retry on O_NONBLOCK (Design B)
Implement Design B from local/docs/INITNSMGR-CONCURRENCY-DESIGN.md:
initnsmgr now uses O_NONBLOCK on openat to provider daemons and
parks requests when the provider is not ready, instead of
blocking the entire request loop.

Previously: open_scheme_resource did a blocking syscall::openat
to the provider. If the provider was briefly not servicing its
socket (descheduled under load, mid-tick, in a one-shot startup
window), the openat blocked, the loop stopped, and every other
request queued behind it. The wedge surfaced at whatever boot
stage was in flight (e.g. 'ahcid' in the logs) - that stage was
the symptom location, not the cause.

Now:
- openat to a provider is called with O_NONBLOCK.
- On Ok(fd), return the fd immediately.
- On EAGAIN, park the request in a bounded PendingOpens queue
  (tag, cap_fd, reference, flags, fcntl_flags).
- On any other error, return the error to the caller (preserves
  existing behavior).
- After each next_request cycle, retry ALL parked opens with
  O_NONBLOCK. Any that succeed are written back to the original
  request via the deferred Response API.
- The park queue is bounded (64 entries). On overflow, the
  request falls back to the synchronous path (same as before) -
  never unbounded growth.

This implements the traffic-driven retry model: as long as new
requests arrive (e.g. processes starting), parked opens are
re-attempted frequently. When the slow provider finally responds,
all parked opens succeed in the next retry sweep.

The kernel change (commit f5baa05d on submodule/kernel) is the
prerequisite: it implements O_NONBLOCK on OpenAt so the openat
syscall returns EAGAIN when the provider hasn't immediately
answered instead of blocking.

Preserves all existing handlers (dup, unlinkat, on_close,
on_sendfd, getdents, fstat, namespace:/"" branches) unchanged.
Only the openat -> open_scheme_resource path is changed.

Per local/AGENTS.md:
- No new branches (work on submodule/base)
- No stubs, no todo!/unimplemented!
- Cat 2 fork - changes committed to submodule/base branch

Closes v5.3 Design B (base side). Kernel side is the companion
commit on submodule/kernel.
2026-07-26 06:10:16 +09:00
kellito d98330a7de events: monotonic seq numbers + larger buffer for AER/pciehp dedup
G-A1/G-A3 fix: replace order-dependent content-hash dedup with
monotonic AtomicU64 sequence numbers. Each event line is prefixed
with seq=<n>: so consumers can track last_seq and skip already-
processed events. MAX_EVENTS raised from 64 to 256 for headroom.

G-A5 support: add /scheme/pci/aer_seq and /scheme/pci/pciehp_seq
endpoints returning latest_seq() as UTF-8, so consumers can query
'what is the latest?' atomically without parsing the whole log.

Changes:
- events.rs: AtomicU64 seq_counter + high_water_mark in EventLog
- events.rs: next_seq() allocates monotonic seq, CAS-updates HWM
- events.rs: push() prepends seq=<n>: to every line
- events.rs: latest_seq() returns high_water_mark
- events.rs: MAX_EVENTS 64 -> 256
- scheme.rs: Handle::AerSeq, Handle::PciehpSeq variants
- scheme.rs: aer_seq/pciehp_seq path, fstat, read, getdents wiring
2026-07-25 23:49:09 +09:00
Red Bear OS 29166263bb dhcpd: stop calling connect() to broadcast (filter drops OFFER)
UDP connect() to 255.255.255.255:67 sets the socket's source-filter to
broadcast peers only. The DHCP server (e.g. QEMU SLIRP at 10.0.2.2)
responds from its own IP, which the filter rejects. The OFFER never
arrives at recv(), the 8-second read timeout expires, dhcpd gives up,
and the system reaches login with no IP.

Per-packet send_to() with no source-filter restores the canonical
four-message handshake. Applied at all four broadcast points:
DISCOVER, REQUEST, RENEW, REBIND.

Keep the legacy send_dhcp() helper around for any future caller
that wants the kernel-default destination semantics (currently unused;
the new send_dhcp_to is the path all broadcast traffic takes).

Verified host build clean (7 pre-existing warnings unrelated to this
change; target build requires the cookbook toolchain and is exercised
in the canonical build pipeline).
2026-07-25 21:38:31 +09:00
Red Bear OS e54484e553 init: pin daemon stdio to boot-log VT1 so the login prompt lands last
Daemon stdio (fd 0/1/2) is inherited from bootstrap pointing at /scheme/debug
— the kernel console — which fbcond renders onto the *active* VT. Once
29_activate_console switches the active VT to 2 for the getty login, any daemon
that logs afterwards paints on top of the login banner/prompt: late async
driver attach (i2c-hidd, evdevd, dw-acpi-i2cd, all via common::setup_logging ->
stderr) and smolnetd's bounded NIC wait. So the banner ended up "near the end"
but never last.

Re-enable switch_stdio, redirecting daemon stdio to a fixed boot-log VT
(/scheme/fbcon/1) right after the /usr switchroot, before the /usr units run.
VT1 is the active console during boot (so the full boot stays visible there),
fbcond still mirrors it to serial, and VT2 is left clean for a prompt that
lands last. This is NOT the old /scheme/log redirect that went dark: that
relied on fbbootlogd surfacing /scheme/log to the framebuffer (racy). A real VT
renders directly. Best-effort: if fbcon/1 can't be opened, stdio stays on the
kernel console exactly as before.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-25 17:51:03 +09:00
Red Bear OS 2e5e516587 net: wait for async NIC attach instead of one-shot-exit (fixes no-eth0 boot)
driver-manager attaches NIC drivers asynchronously, so on a fresh boot the
network.* scheme does not exist yet when smolnetd/dhcpd run (both gated only on
the driver-manager service having *started*). smolnetd scanned /scheme once,
found nothing, and exited -> /scheme/netcfg never came up -> dhcpd/netctl failed
with "Can't open /scheme/netcfg/ifaces/eth0/mac" and DHCP timed out.

- smolnetd: poll (bounded 20s) for a network.* adapter to appear before giving
  up; oneshot_async so this never blocks boot. Give-up log now distinguishes
  genuinely-NIC-less from a NIC-present-but-driver-failed (stale driver) case.
- dhcpd: wait (bounded 20s) for /scheme/netcfg/ifaces/eth0/mac to appear before
  attempting DHCP, instead of one-shot "Can't open"; exit clean if no NIC.
2026-07-25 16:02:50 +09:00
Red Bear OS b906ad688a acpid: allow PCI fd replacement; eagerly init AML symbols on sendfd
Closes the v4.0 plan P3 'acpid pci_fd is not registered' item.

Two related defects:

1. scheme.rs::on_sendfd had a one-shot EINVAL when self.pci_fd was
   already Some. Combined with the lazy AML context init in
   AcpiContext::aml_symbols, this created a permanent failure mode:
   - pcid starts AFTER acpid (per the requires_weak chain)
   - if a /scheme/acpi/symbols request arrives before pcid's sendfd
     reaches acpid, the aml init runs with pci_fd = None and logs
     'pci_fd is not registered' at error level
   - the resulting aml_context state makes subsequent retries fail
     the same way; the next pcid sendfd hits the one-shot EINVAL and
     is rejected
   - aml stays broken for the entire boot

   Fix: allow replacement (warn-and-replace on subsequent sendfd).
   Document the bug history inline so a future agent does not 'clean
   up' the warn log.

2. aml_physmem.rs::AmlPhysMemHandler::new logged the missing fd at
   log::error. Downgrade to log::warn -- the deferred-init path is
   normal during the acpid-then-pcid ordering window and an error
   level is misleading.

3. scheme.rs::on_sendfd now eagerly calls self.ctx.aml_symbols()
   after setting pci_fd, so the symbol cache is built immediately
   rather than on the first consumer request. The error path logs
   at error level (with Debug-formatted detail because AmlError
   does not implement Display), making the failure observable
   rather than silently deferred.

Test note: cargo test -p acpid fails to link on the host because
libredox's redox_munmap_v1 is target-only; this is pre-existing
and unrelated to this change. cargo check -p acpid is clean.
2026-07-25 00:11:55 +09:00
Red Bear OS 0ca545d35a acpid: WMI (PNP0C14) subsystem — _WDG parsing + event GUID dispatch + _WED (Phase 9.2)
Bounded WMI subsystem ported from Linux 7.1 drivers/platform/wmi/core.c
and drivers/platform/x86/lg-laptop.c:

- wmi.rs: guid_block (20-byte _WDG entry) parser, PNP0C14 device discovery
  (candidate-path _HID probe mirroring EC discovery), _WDG buffer read via
  aml_eval (AmlSerdeValue::Buffer), event-GUID enumeration (flags &
  ACPI_WMI_EVENT), _WED evaluation for eventcode decode, LG keymap
  (0x70 control-panel / 0x74 touchpad-toggle / 0xf020000 read-mode /
  0x10000000 kbd-backlight). 4 unit tests cover guid_block parsing,
  event flag detection, short-input rejection, and keymap coverage.

- power_events.rs: WMI notify handling in the AML notification drain —
  when a Notify fires on the WMI device, _WED is evaluated to decode the
  eventcode, mapped to a key name, and emitted as PowerEvent::Wmi.

- main.rs: WMI discovery at init (after wake registry). PowerEvent::Wmi
  logged in the main loop.

- acpi.rs: wmi_registry field on AcpiContext.

Works on any x86 WMI laptop (LG, Dell, HP, Lenovo, ASUS, etc.).
On QEMU (no PNP0C14) it is a no-op.
2026-07-24 13:29:31 +09:00
Red Bear OS 5a43628d58 pcid: AER + pciehp event producers (P2-1)
New events module: a 500ms poller thread scans every enumerated device
and produces two read-only event streams:
- /scheme/pci/aer — uncorrectable (NonFatal) and correctable AER status
  from the PCIe AER extended capability, emitted as
  'severity=<level> device=<bdf> raw=...' lines and W1C-cleared
- /scheme/pci/pciehp — Slot Status events from hot-plug-capable ports
  (presence detect, DLL state, attention button, MRL sensor, power
  fault), emitted as 'kind=<event> device=<bdf>' lines and W1C-cleared

Events accumulate in capped in-memory logs (64 lines) served by the
scheme; device strings use the scheme dir-name format
(0000--00--1f.2) so driver-manager's route_to_driver matches bound
paths. The Pcie handle is now Arc-shared with the poller. Extended
capabilities need ECAM; on PCI 3.0 fallback machines the scanners
gracefully produce nothing. This wires driver-manager's previously
inert unified event listener to real producers.
2026-07-24 12:32:05 +09:00
Red Bear OS 9cd43d8d8c inputd: exclusive input grab (EVIOCGRAB equivalent)
Complete the Linux-aligned seat-takeover primitive set: a raw consumer can take
an EXCLUSIVE grab of the input stream by writing a single control byte to its
own consumer_raw handle (1=grab, 0=ungrab) — self-identifying, unlike the
shared control fd. While a grab is held:

  * events route ONLY to the grabbing handle;
  * the text console AND every other raw tap are suspended; and
  * the grab is released automatically when the handle closes, so a compositor
    that crashes cannot wedge input away from the console (Linux
    __input_release_device).

A second grab attempt by a different handle returns EBUSY. Additive and
behaviour-preserving: grab defaults to None, so nothing changes until a client
grabs. new_raw() now opens read+write and ConsumerHandle::set_grab() drives it.

Together with set_vt_mode (KDSKBMODE) this gives seatd/a compositor the full
grab + VT-mode takeover surface. Compile-checked for x86_64-unknown-redox;
boot-validation pending build-green.
2026-07-24 12:11:10 +09:00
Red Bear OS a916a6612c inputd: add VT graphics-mode control op (console suppress)
Add control kinds 3/4 (set VT graphics/text mode) and a graphics_vts set.
When a VT is claimed by a graphical client, the console `Consumer` for that VT
is suspended — cooked bytes stop being delivered to the text console — while
the raw device tap (consumer_raw) keeps feeding the compositor. This is the
RedBear equivalent of Linux KDSKBMODE(K_OFF)/KD_GRAPHICS silencing the console
keyboard + n_tty for a VT owned by a Wayland compositor.

Behaviour-preserving by default: graphics_vts is empty until a compositor
opts in via ControlHandle::set_vt_mode(vt, true), so text-console delivery is
unchanged. Two control kinds are used instead of a bool to keep the
ControlEvent ABI unchanged.

Full device-grab arbitration (exclusive routing / EVIOCGRAB) and the
VT_PROCESS switch-ack handshake remain TODO — the raw broadcast is sufficient
for a single compositor. Part of the Linux-aligned input-stack consolidation.
Compile-checked for x86_64-unknown-redox; boot-validation pending build-green.
2026-07-24 12:01:03 +09:00
Red Bear OS bd5e3db32a inputd: add raw evdev peer tap (consumer_raw) for libinput/Wayland
Add a new `consumer_raw` handle to scheme:input — a raw, always-on device
tap modelled on the Linux evdev handler. Unlike the console `consumer`, it:

  * is NOT bound to a VT, so it receives events regardless of which VT is
    foregrounded (a background compositor keeps getting input); and
  * receives the *pre-keymap* event stream — the console keymap is now
    applied only on the console `consumer` path, never on the raw tap.

The producer write path snapshots the raw event bytes before the keymap
stamping loop and fans them out to every ConsumerRaw handle unconditionally,
in parallel with the existing VT-gated, keymapped console fan-out (which is
byte-for-byte unchanged — no console-login regression).

This is the RedBear equivalent of evdev being a peer handle off the raw input
core: libinput/xkbcommon (via evdevd) require raw scancodes, which the old
wiring — evdevd reading the keymapped, VT-gated console consumer — could not
provide. Adds ConsumerHandle::new_raw() for consumers.

Part of the Linux-aligned input-stack consolidation
(local/docs/INPUT-STACK-LINUX-ALIGNMENT-PLAN.md). Compile-checked for
x86_64-unknown-redox; boot-validation pending build-green (acpi-rs).
2026-07-24 11:57:36 +09:00
Red Bear OS 2d03559d14 init.d: final pcid-spawner reference sweep
30_redox-drm.service requires_weak now targets
40_driver-manager-initfs.service; stale dormant-era comments updated in
00_driver-manager.service and 45_loop_mnt.service.
2026-07-24 10:42:42 +09:00
Red Bear OS aa1c267a45 init.d: retarget base graph from retired pcid-spawner to driver-manager
00_base.target, 10_evdevd, 10_smolnetd referenced 00_pcid-spawner.service
in requires_weak — after the retirement init logged 'unit
00_pcid-spawner.service not found'. All three now depend on
00_driver-manager.service.
2026-07-24 10:38:29 +09:00
Red Bear OS 3ba37444a0 acpi-rs: add connect_op_regions() + repair initialize_namespace
Add public connect_op_regions() (ACPICA evrgnini.c): \_SB._REG(space, 1)
per installed handler space plus <device>._REG(space, 1) per device holding
an OpRegion of that space. initialize_namespace() now delegates to it and
its ACPICA-order opening (_INI, _SB._INI) is restored after 0c11c2b5
captured a broken intermediate edit. Completes the _REG wiring begun in
c3a27717 (which delivered the acpid-side call).
2026-07-24 10:01:12 +09:00
Red Bear OS c3a2771780 acpi-rs/acpid: fix broken initialize_namespace + wire _REG connect
Commit 0c11c2b5 captured a broken intermediate edit of initialize_namespace
(unterminated comment, missing _INI and the _REG hook) via git add -A, which
left the tree not compiling. Restore the correct opening (ACPICA init order)
and extract the _REG opregion connect into a public connect_op_regions()
(ACPICA evrgnini.c): \_SB._REG(space, 1) per installed handler space plus
<device>._REG(space, 1) per device holding an OpRegion of that space.
initialize_namespace() delegates to it. Call it from acpid's interpreter
init (AmlSymbols::init) after region handlers are installed — runs once
before the main loop, so a blocking _REG cannot wedge the scheme.
2026-07-24 09:48:28 +09:00
Red Bear OS 0c11c2b515 retire pcid-spawner: remove crate, service files, and build wiring
Operator-ratified full retirement — driver-manager superseded
pcid-spawner in every role (boot-time PCI match/claim/spawn, initfs
storage path, hotplug). Removes:
- drivers/pcid-spawner/ crate (source preserved in git history)
- init.d/00_pcid-spawner.service and
  init.initfs.d/40_pcid-spawner-initfs.service
- Cargo workspace member + Makefile bin entries
- 40_drivers.target reference to pcid-spawner-initfs
- the /etc/driver-manager.d/disabled fallback gates on driver-manager
  services (no fallback exists anymore; driver-manager runs
  unconditionally)
2026-07-24 08:47:02 +09:00
Red Bear OS 62e7651fe7 dw-i2c: deliver scheme capability fd to init in endpoint::serve (fix boot hang)
endpoint::serve used register_sync_scheme, which registers the scheme to
the daemon's own namespace but never returns the capability fd to init.
For type={scheme} services init blocks in call_ro(FD) waiting for that
fd, so the boot deadlocked right after 'Started Intel LPSS I2C
controller' (CPU halted, init asleep) — the ptyd-class bug.

Replace register_sync_scheme with an explicit capability-fd creation +
notify_init_scheme_fd() that writes the fd to the INIT_NOTIFY pipe
(same mechanism as SchemeDaemon::ready_with_fd / ready_sync_scheme,
which i2cd, ucsid, and ptyd already use). init then registers
/scheme/<name> and the boot proceeds.

Affects intel-lpss-i2cd and dw-acpi-i2cd, both type={scheme} services
using this endpoint.
2026-07-24 03:33:42 +09:00
Red Bear OS 374a95aca7 acpid: gate general GPE _Lxx/_Exx dispatch behind REDBEAR_ACPI_GPE_DISPATCH
The general GPE dispatch runs on acpid's single main-loop thread, which
also serves /scheme/acpi. A blocking _Lxx/_Exx AML method (e.g. spinning
on a PCI/EC condition that never becomes true) freezes the scheme and
deadlocks every ACPI-reading daemon and therefore the whole boot. Linux
avoids this with a dedicated kacpid thread. Until Red Bear has one, gate
the general dispatch behind REDBEAR_ACPI_GPE_DISPATCH=1 (default OFF);
EC + PM1 fixed events stay always-on (bounded and proven).
2026-07-24 01:59:26 +09:00
Red Bear OS 92bf05c20a pcid: EOF config reads at the config-space boundary (256 fallback / 4096 ECAM)
The Handle::Config read handler never returned 0, so fs::read /
read_to_end on /scheme/pci/<addr>/config streamed dwords forever —
any unbounded read of a config file hung. Found by the initfs
driver-manager hang: propose_msix_vectors' unbounded config read never
terminated, stalling the oneshot initfs service and the whole boot.

- cfg_access: Pcie::has_ecam() reports ECAM availability.
- scheme: config_space_size() = 4096 with ECAM, 256 in PCI 3.0
  fallback; the read handler returns Ok(0) at the boundary and fstat
  advertises the correct size.
2026-07-23 22:19:19 +09:00
Red Bear OS f2fbf7ad83 initfs: wire driver-manager-initfs into the drivers target
40_drivers.target referenced only pcid-spawner-initfs, so the initfs
driver-manager service (staged, gated, with its storage TOML and the
binary already copied into initfs/bin) never entered the boot graph.
The target now lists driver-manager-initfs first and keeps
pcid-spawner-initfs as the gated fallback — the initfs cutover is
complete. Also correct the initfs-storage.toml header comment (the
content is driver-manager format).
2026-07-23 20:34:14 +09:00
Red Bear OS b0e760659c pcid: no panic on PCI 3.0 fallback config access; warning sweep
- fallback.rs: config reads at offset >= 256 (PCIe extended space) now
  return the PCI-standard 0xFFFFFFFF 'absent' value and writes are
  dropped, instead of panicking the PCI daemon. This is the exact
  behavior of real hardware and Linux's CF8 path on MCFG-less machines,
  and it lets MSI-X feature discovery degrade to INTx cleanly. Found by
  the first driver-manager QEMU gate (i440fx): pcid panicked at
  fallback.rs:65 and the boot hung.
- driver_handler.rs: drop vestigial func param from read_full_device_id.
- driver_interface/mod.rs: use Option::insert's return value directly
  (must_use) instead of discarding and re-reading as_ref.
2026-07-23 20:13:17 +09:00
Red Bear OS c72d4247a6 init: cutover — driver-manager owns the boot path, pcid-spawner gated as fallback
- 00_driver-manager.service: resident daemon args (--hotplug); runs
  unless /etc/driver-manager.d/disabled exists.
- 40_driver-manager-initfs.service: gate flipped from opt-in
  (initfs-active) to default-on (!/etc/driver-manager.d/disabled).
- 00_pcid-spawner.service + 40_pcid-spawner-initfs.service: gated to
  start only when /etc/driver-manager.d/disabled exists — the legacy
  spawner remains staged as the operator fallback, never deleted.
2026-07-23 17:51:44 +09:00
Red Bear OS e30f24997c init: ConditionPathExists service gate (systemd-style, with ! negation)
init's Service parser used deny_unknown_fields, so the C0
driver-manager service files (which use ConditionPathExists) were
rejected wholesale — driver-manager stayed dormant by parser accident
instead of by design.

- service.rs: new optional ConditionPathExists field + condition_met()
  gate. A leading '!' negates: the service starts only when the path
  does NOT exist.
- scheduler.rs: skip services whose condition is not met (status_skip,
  same pattern as skip_cmd).
- 00_driver-manager.service: fix inverted polarity — the intent is
  'run unless /etc/driver-manager.d/disabled exists', i.e.
  ConditionPathExists = "!/etc/driver-manager.d/disabled".
- Drop two pre-existing unused imports (Write in service.rs,
  status_fail in main.rs).
2026-07-23 16:55:42 +09:00
Red Bear OS c836fffb66 ihdad: graceful failure on DSP/cAVS platforms (Phase 8.1)
On cAVS/SOF platforms (e.g. LG Gram 8086:7728), STATESTS reads 0
because the codec sits behind the audio DSP; the legacy HDA codec-wake
mechanism cannot reach it. enumerate() previously hardcoded codec 0 and
would hang reading a non-existent codec via CORB/RIRB. Now, if no
codecs respond after reset_controller(), log the DSP-platform diagnosis
and fail honestly with ENODEV instead of hanging. A SOF/cAVS driver
(Phase 8.2) is required for these platforms.
2026-07-23 06:34:35 +09:00
Red Bear OS b5f84b44df acpid/acpi-rs: _REG opregion connect + LPIT parse fix + thermal active + PM timer + HW-reduced + GPE dispatch
acpi-rs (vendored fork):
- _REG opregion connect (ACPICA evrgnini.c): run \_SB._REG(space, 1)
  per installed handler after \_INI — firmware gates EC access behind
  this. Device-level _REG for each device holding an OpRegion of an
  installed space. Fills the last big TODO in initialize_namespace.
- RegionSpace: add From<RegionSpace> for u8 (region-space ID for _REG).

acpid:
- LPIT parser BUG FIX: GAS (Generic Address Structure) is 12 bytes
  (4-byte header + 8-byte address); the parser previously read
  entry_trigger/residency/latency/counter_frequency 4 bytes early and
  required length>=48 instead of 56. Fixed offsets, added
  entry_trigger_space_id, and mwait_hint()/best_mwait_hint() for the
  FFH MWAIT hint. Tests rewritten with correct 56-byte layout.
- Thermal active cooling: /scheme/acpi/thermal/<zone>/active evaluates
  _AC0.._AC9 and returns defined trip points (tenths of K).
- ACPI PM timer: pm_timer_read() from FADT pm_timer_block;
  /scheme/acpi/pmtimer endpoint (3.579545 MHz).
- HW-reduced ACPI: Fadt::is_hardware_reduced() (FADT bit 20); skip
  PM1/GPE setup on such platforms.
- General GPE dispatch: enabled_active_gpes() + \_GPE._Lxx/_Exx method
  evaluation (evgpe.c acpi_ev_gpe_detect).
2026-07-22 22:08:23 +09:00
Red Bear OS 0485ae662a acpid: general GPE _Lxx/_Exx dispatch + ACPI PM timer (ACPICA port)
- GpeBlocks::enabled_active_gpes(): scans all GPE block status+enable
  register pairs, returns every GPE with both bits set (evgpe detect
  semantics — a GPE only fires the SCI when enabled AND active).

- handle_sci general GPE dispatch (acpi_ev_gpe_detect): every
  enabled+active GPE that is not the EC GPE gets its \_GPE._L{gpe:02X}
  (level, tried first) or \_GPE._E{gpe:02X} (edge) control method
  evaluated; status cleared after. This is the ACPICA core GPE model
  that drives lid, device wake, and all non-EC GPE events — previously
  only the EC GPE and PM1 fixed events were dispatched.

- pm_timer_read(): reads the FADT pm_timer_block free-running counter
  (3.579545 MHz, PM_TIMER_FREQUENCY_HZ). Exposed at
  /scheme/acpi/pmtimer for precise sleep-path timing.
2026-07-22 19:09:42 +09:00
Red Bear OS 94d1b92d91 acpid: thermal zone method evaluation (_TMP/_PSV/_CRT)
Add ThermalZone handle kind to the scheme: per-zone ACPI thermal
data at /scheme/acpi/thermal/<zone>/{temperature,passive,critical}.
Each path evaluates the corresponding AML method (_TMP, _PSV, _CRT)
and returns the raw integer value. ThermalFileKind enum dispatches
to the correct method. thermald can now read real thermal zone
temperatures and thresholds instead of relying on hardcoded values.
Ported from Linux drivers/acpi/thermal.c thermal_zone_device_ops.
2026-07-22 17:30:05 +09:00
Red Bear OS 7071c4529e acpid: _DSW/_PSW wake arming + sleep state discovery + GPE wake re-arm
- WakeRegistry::arm_wake_devices(): evaluates _DSW(1,0,Sx) per wake
  device (falls back to _PSW(1)), enables wake GPEs in the GPE block.
  Wired into enter_s2idle() — wake devices are now armed before
  the kernel MWAIT loop. Ported from Linux acpi_enable_wakeup_devices.

- WakeRegistry::disarm_wake_devices(): evaluates _DSW(0,0,0) per
  wake device (falls back to _PSW(0)), clears wake GPE status bits.
  Wired into exit_s2idle() — wake devices are disarmed on resume.
  Ported from Linux acpi_disable_wakeup_devices.

- SleepStates::discover(): enumerates _S0 through _S5 to find
  available sleep states. s3_supported() and s2idle_only() helpers
  identify the platform's sleep capability profile.

- AcpiContext.wake_registry: new field storing the populated
  WakeRegistry for use by enter_s2idle/exit_s2idle.
2026-07-22 15:41:51 +09:00
Red Bear OS 9c571e2942 pcid: guard config access against out-of-range offsets (fixes boot panic)
An extended-capability walk (pci_types capabilities()) that follows a
chain running to/past the end of config space read at offset 4096,
which tripped the dword-offset assert in bus_addr_offset_in_dwords
("pcie offset larger than 4095") and aborted pcid with an Invalid
opcode fault / UNHANDLED EXCEPTION on boot — after switchroot to /usr,
so it blocked reaching login.

PCIe config space is exactly 4096 bytes (offsets 0..=4095). Fix at two
levels:

- ConfigRegionAccess::read/write (cfg_access/mod.rs): guard the single
  access choke point — an out-of-range read returns the PCI "no
  response" pattern (0xFFFFFFFF, which also terminates a capability
  walk cleanly) and an out-of-range write is a no-op. This catches any
  caller (capability walk, scheme reads, driver access).

- scheme.rs config read/write loop: clamp the loop bound with
  saturating_add(...).min(4096) so a consumer requesting offset+len
  past the boundary reads only the valid part instead of looping to
  offset 4096.

Verified: boot no longer panics in pcid (progresses past the previous
crash point through switchroot and the /usr driver set).
2026-07-22 14:20:57 +09:00
Red Bear OS a12fb9fc7c acpid: LPIT parser + _PRW wake enumeration + FADT S0-idle detection (ACPICA port)
Port useful ACPICA components into the existing Rust ACPI stack:

- LPIT (Low Power Idle Table) parser in new acpid/wake.rs.
  Parses native C-state LPI entries (entry trigger, residency,
  latency, residency counter, counter frequency). Computes total
  residency and deepest LPI state. 4 unit tests cover parsing,
  empty input, short input, and deepest-entry selection.
  Reference: Linux include/acpi/actbl2.h struct acpi_lpit_native.

- _PRW wake device enumeration in acpid/wake.rs.
  WakeRegistry::enumerate() evaluates _PRW on known wake-capable
  device paths (LID, PWRB, SLPB, XHCI, HDAS, CNVW, I2C0/1, THC0/1).
  Extracts GPE number and sleep state from the _PRW package.
  Reference: Linux drivers/acpi/scan.c acpi_bus_get_wakeup_device_flags.

- FADT S0-idle detection: Fadt::supports_s0_idle() checks bit 21
  (ACPI_FADT_LOW_POWER_S0) to detect platforms that support s2idle.
  Reference: Linux include/acpi/actbl.h.

- acpid/main.rs: LPIT parse + wake enumeration + S0-idle detection
  wired into init after AcpiContext::init() and before power events.

ACPICA assessment: do NOT port ACPICA as a C library. Port its
useful data structures and algorithms into the existing Rust stack
(acpi-rs vendored fork + acpid daemon). The AML interpreter already
has comprehensive opcode coverage (only DefLoad/DefLoadTable remain
unimplemented, both optional). The GPE/EC/fixed-event infrastructure
is already in acpid. LPIT + _PRW + S0-idle detection fill the
remaining gaps for Phase 9.1 s2idle completion.
2026-07-22 12:22:36 +09:00
Red Bear OS cf2abc64b0 ided: implement PCI native mode for primary and secondary IDE channels
The PCI IDE Programming Interface byte (PCI spec §3.1.1) encodes
per-channel mode: bit 0 = primary native, bit 2 = secondary native.
The previous code panicked on native-mode channels and also had a
bug checking bit 0 for both channels (secondary should check bit 2).

Native mode now reads I/O and control bases from PCI BARs (BAR0/1 for
primary, BAR2/3 for secondary) instead of hardcoded legacy ports.
Interrupt line comes from legacy_interrupt_line when available.
2026-07-22 05:25:59 +09:00
Red Bear OS 6571df7802 acpi-rs: eliminate all AML stubs (resource descriptors, ConnectionField, Match, Index ref)
resource.rs — implement all ~20 stubbed resource descriptor parsers:
  - QWord/DWord/Word AddressSpace, IRQ, DMA, I/O, FixedI/O, FixedDMA
  - StartDependentFunctions, VendorDefined (small+large)
  - GPIOConnection, GenericSerialBus (I2C/SPI/UART subtypes)
  - PinFunction, PinConfiguration, PinGroup, PinGroupFunction, PinGroupConfiguration
  - ExtendedAddressSpace, GenericRegister
  - Both large/small dispatch tables now call real parsers
  - ACPI 6.5 §6.4 coverage complete, cross-referenced with ACPICA amlresrc.h

mod.rs — eliminate 3 remaining stubs:
  - ConnectionField in parse_field_list: namestring + inline buffer forms
  - Opcode::Match: full opcode handler with ResolveBehaviour::ByteData intercept,
    10-arg OpInFlight, do_match executor with 7 match operators
  - ReferenceKind::Index in do_copy_object: merged with Named/Local path

virtio-core: replace arch stubs (aarch64, riscv64) with real Error::Probe returns

usbscsid/uas: full UAS transport implementation (1006 lines) replacing
stub-heavy version — IUs, pipe detection, stream/non-stream modes,
task tag management, cross-referenced with Linux 7.1 uas.c

initnsmgr: Rc<RefCell<>> -> Arc<Mutex<>> for namespace concurrency safety

xhcid/quirks: fix comment (3 hci_version-dependent entries, not 2)

cargo check -p acpi: clean (3 pre-existing warnings only)
cargo test -p acpi --lib: 5/5 pass
2026-07-22 05:00:29 +09:00
Red Bear OS f315a9be3b acpid + i2c-hidd: Phase 5 (GPE/EC/lid/buttons/fan) + Phase 4.4 (HID descriptor parser)
Phase 5 — Laptop ACPI events (LG Gram 16Z90TP compatibility plan):
- Vendor acpi-rs crate (rev 90cbe88) into base fork with a real
  Opcode::Notify executor; upstream panicked on every Notify opcode,
  which is the backbone of ACPI event flow on real laptop firmware.
  Handler::handle_notify hook added; acpid + amlserde pointed at the
  path dep so every consumer sees the same fork.
- gpe.rs: FADT-driven GPE block register map (status half + enable
  half), write-1-to-clear status bits, read-modify-write enable
  preserving every other GPE's firmware state. PM1 fixed-event bits
  (PWRBTN/SLPBTN/RTC) per ACPI 6.4 §4.8.3.1.
- power_events.rs: init builds the GPE map, discovers the EC via ECDT
  (ACPI 6.4 §5.2.16) with a _HID=PNP0C09 probe fallback over conven-
  tional paths, enables the EC GPE + PM1 fixed events, discovers lid
  and ACPI 4.0 fan devices. handle_sci dispatches PM1 → EC query loop
  (bounded at 32) → AML notification drain, following Linux 7.1
  evgpe.c / ec.c / button.c.
- notifications.rs: shared AmlNotifications queue (parking_lot::Mutex)
  populated by the vendored acpi-rs handle_notify hook, drained by the
  SCI handler and redbear-upower.
- ec.rs: sci_evt_set() and query() exposed on Ec for the SCI handler.
- scheme.rs: new handle kinds Lid, LidState, ButtonDir, Button,
  Notifications, Fan, FanState, FanSpeed with proper dir/file
  separation. Fan _FST on read, _FSL on write (percent clamped 0-100).
- main.rs: subscribes /scheme/irq/{sci_irq} (default 9) on the event
  queue, dispatches SCI events through handle_sci. PowerButton incre-
  ments edge counter and triggers the shutdown path; SleepButton incre-
  ments counter and calls enter_s2idle.
- acpi.rs: AcpiContext gained gpe, ec_device, lid_device, lid_state,
  power_button_events, sleep_button_events, fan_devices fields (all
  RwLock-guarded). evaluate_acpi_method and enter_s2idle changed from
  &mut self to &self (AML mutation goes through RwLock inner state).
- aml_physmem.rs: handle_notify impl pushes onto the shared queue.

Phase 4.4 — HID report descriptor parser (i2c-hidd):
- report_desc.rs: HID 1.11 §6.2.2 descriptor parser + decoder. Global-
  state stack (Push/Pop), usage-min/max expansion, sign-extended
  fields, contact reconstruction (id, tip, x, y). 3 unit tests.
- input.rs: forward_layout_report dispatches descriptor-driven reports
  through forward_decoded: first touching contact → absolute
  MouseEvent; two simultaneous contacts → vertical ScrollEvent (two-
  finger scroll); buttons → ButtonEvent; keyboard-page reports fall
  back to the existing boot-protocol path.
- hid.rs: stream_input_reports parses the descriptor once and uses
  forward_layout_report when layouts are non-empty, otherwise keeps the
  boot-protocol summary path.

Reference: Linux 7.1 drivers/acpi/{evgpeblk.c,evgpe.c,ec.c,button.c}
and drivers/hid/hid-core.c.

All affected crates compile for x86_64-unknown-redox; i2c-hidd 3/3
unit tests pass on host; acpid host-side tests still can't link
(pre-existing libredox limitation — must run via redoxer).
2026-07-21 21:36:07 +09:00
Red Bear OS ddcd08709f pcid: read REDBEAR_DRIVER_PCI_IRQ_MODE / DISABLE_ACCEL env vars
The pcid_interface crate now reads the two env vars emitted by
driver-manager's SpawnDecision committee:
- REDBEAR_DRIVER_PCI_IRQ_MODE: lets the spawned child know
  whether to fall back to MSI / INTx instead of MSI-X
- REDBEAR_DRIVER_DISABLE_ACCEL: lets the spawned child suppress
  hardware acceleration (matches PciQuirkFlags::DISABLE_ACCEL)

Both values are stored on PciFunctionHandle and exposed via
accessors (irq_mode_hint / disable_accel_hint) so the driver
daemons can read them at startup. 6 new unit tests cover the
env-var parsing.

Refs: local/docs/DRIVER-MANAGER-MIGRATION-PLAN.md § 5.2 D2.7.
2026-07-21 12:07:49 +09:00
Red Bear OS 6db0f48170 i2c: review-fix round — hardware-correct DesignWare engine + LPSS bring-up
Post-implementation review returned FAIL with two verified-CRITICAL
findings; all legitimate findings fixed in this round:

CRITICAL — engine wrote IC_CON/IC_TAR while enabled (DesignWare
databook forbids; Linux i2c_dw_xfer_init disables first). Engine
restructured: wait-idle -> disable -> program -> enable with
IC_ENABLE_STATUS polling on every transfer.

CRITICAL — Intel LPSS PCI bring-up skipped parent-device init.
intel-lpss-i2cd now claims functions via pcid_interface
(connect_by_path + enable_device), validates the real BAR size, and
performs intel_lpss_init_dev's sequence (reset-deassert + 64-bit
remap address at BAR0+0x200), ported from Linux drivers/mfd/intel-lpss.c.

MAJOR fixes:
- wait_for checks TX_ABRT before success predicates — a NACKed write
  no longer reports success via post-abort idle state
- SCL timing corrected to Linux's formulas: HCNT uses sda_fall_ns,
  round-to-nearest division (FS 100/200, SS 552/652 for bxt 133 MHz)
- stop=false rejected honestly instead of hanging on the idle wait
- recover(): ABORT-bit cycle + disable + state flush after any failed
  transfer
- validate_request: segment/byte/address/10-bit limits before any MMIO
- i2cd + endpoint: exact-first adapter resolution; last-component
  matching accepted only when unambiguous
- i2cd registration validates provider_scheme as a single safe
  scheme-name component
- I2cTransferResponse gains typed status (I2cTransferStatus,
  serde-defaulted, wire-compatible)
- endpoint::serve takes a Result-returning on_ready callback;
  setrens failure is fatal (fail-closed namespace reduction)
- unexpected i2cd registration responses are fatal for that controller

Tests: dw-i2c 5 (timing vectors, validation, resolution),
intel-lpss-i2cd 1 (PCI ID table coverage), full workspace cargo check
clean, base cooks for x86_64-unknown-redox.

Refs: local/docs/LG-GRAM-16Z90TP-COMPATIBILITY-PLAN.md review-fix round
2026-07-21 12:03:00 +09:00
Red Bear OS 8dd8fb3b20 acpid: harden AML handler — bounded stall, mutex owner-check, static cache, panic-free path, observability
Five daemon-local hardening items on top of the AML-mutex fix. acpid is
single-threaded and serves the `acpi` scheme on the same thread that
evaluates AML, so any way it can stall or die stalls or kills every
consumer. These reduce or bound each such way (verified against
local/reference/linux-7.1 ACPICA):

- stall(): refuse >255us and warn >100us instead of an unbounded CPU
  busy-spin on the serving thread (ACPICA exsystem.c:129-147). The spec
  caps Stall at 100us; a long busy-spin here would delay scheme requests.

- AML mutex release(): a release of a not-currently-held mutex, or by a
  non-owning thread, is now logged (ACPICA AE_NOT_ACQUIRED / owner
  mismatch, exmutex.c:287,376) rather than silently decrementing depth.

- Static processor-method cache: _PSS/_PSD/_CST/_CPC are fixed after boot
  but cpufreqd polls them; cache the first evaluation so later reads never
  re-run the AML interpreter under the global lock. Removes acpid's
  dominant recurring head-of-line source. Dynamic methods are not cached.

- Panic-free scheme path: every release_global_lock().expect(...) on the
  AML-evaluation path is now log-and-continue, and a result.ok()?.unwrap()
  that panicked on Ok(None) (absent method) is now `?`. A scheme-daemon
  panic kills the `acpi` scheme and wedges every consumer.

- Observability: log AML evaluations >=50ms and mutex-acquire timeouts —
  the early-warning signal before a stall becomes a wedge.

Context: the residual under-load boot wedge is NOT in acpid (a mutex-only
baseline wedges identically under load); it is head-of-line blocking in
the single-threaded initnsmgr. See
local/docs/INIT-NAMESPACE-MANAGER-SCALABILITY-PLAN.md and
local/docs/INITNSMGR-CONCURRENCY-DESIGN.md.
2026-07-21 08:33:26 +09:00
Red Bear OS 0407d9ccbb init: add dormant driver-manager service files (C0)
Adds the two dormant service files for the driver-manager
post-switchroot + initfs spawner paths. Both files are dormant by
default — they require /etc/driver-manager.d/{disabled,initfs-active}
to be absent before they activate. The cutover (C1-C4) is
operator-ratified; this commit only adds the file presence so
the C0 wiring exists.

Refs: local/docs/DRIVER-MANAGER-MIGRATION-PLAN.md § 5.2 C0.
2026-07-21 06:58:10 +09:00
Red Bear OS 452452e453 i2c: real DesignWare transfer chain — engine, PCI discovery, provider routing
The I2C transfer chain was stubbed end-to-end:

- i2cd's transfer path returned 'not implemented yet' for every
  transfer, and its wire format didn't match the only in-tree consumer
  (i2c-hidd sends a bare I2cTransferRequest, i2cd expected
  I2cControlRequest::Transfer).
- intel-lpss-i2cd / dw-acpi-i2cd / amd-mp2-i2cd registered an adapter
  name and parked forever without initializing the controller or
  executing a transfer.
- intel-lpss-i2cd matched only legacy ACPI HIDs, which do not exist on
  Meteor Lake / Arrow Lake platforms (LPSS I2C binds by PCI ID there,
  per Linux drivers/mfd/intel-lpss-pci.c).

Replace with real implementations:

- New shared crate drivers/i2c/designware (dw-i2c): DesignWare I2C
  master engine ported from Linux 7.1 i2c-designware-master.c and
  i2c-designware-common.c — IC_CON + SCL timing computed from ic_clk
  with Linux's exact hcnt/lcnt formulas (bxt_i2c_info 133 MHz for
  LPSS, 100 MHz for ACPI-designated blocks), SDA hold with RX-hold
  workaround, polling transfer engine with RESTART/STOP sequencing,
  TX_ABRT decode (Nack/arbitration-lost/abort/timeout), 7/10-bit
  addressing, bounded timeouts. Also provides the shared
  /scheme/<name> transfer endpoint with register-then-ready ordering.
- intel-lpss-i2cd: PCI discovery for ARL-H (0x7750/0x7751,
  0x7778-0x777b) and MTL-P (0x7e50/0x7e51, 0x7e78-0x7e7b) with 32/64-bit
  BAR0 decode, ACPI alias resolution via FixedMemory32 == BAR0 across
  /scheme/acpi/resources, legacy ACPI-HID path kept, i2cd registration
  with bounded retry, serves /scheme/i2c-lpss.
- dw-acpi-i2cd: converted from register-and-park to the shared engine,
  serves /scheme/dw-acpi-i2c.
- i2cd: real transfer routing — adapter resolution by name/alias
  (exact, normalized, last-component) and forwarding to the provider
  daemon's /scheme/<provider>/transfer endpoint.
- i2c-interface: I2cAdapterInfo gains provider_scheme + aliases
  (serde-default, wire-compatible).

Tests: dw-i2c 3, intel-lpss-i2cd 3; full workspace cargo check clean;
base cooks for x86_64-unknown-redox.

Refs: local/docs/LG-GRAM-16Z90TP-COMPATIBILITY-PLAN.md Phase 4
2026-07-21 06:02:31 +09:00
Red Bear OS d78fd44a07 acpid: fix AML mutex acquire — recursion, ownership, and timeout units
The AML mutex `acquire` handler had two defects that let a routine
`_ACQ` on ACPI processor P-state objects (`processor/CPUn/pss`, opened
by cpufreqd) deadlock acpid permanently:

1. Timeout units. ACPI `_ACQ` timeouts are milliseconds and 0xFFFF is
   the spec's "wait forever" (ACPICA ACPI_WAIT_FOREVER,
   actypes.h:459). The code multiplied the value by 1000, treating it
   as seconds, so 0xFFFF became ~18 hours.

2. No ownership. ACPI mutexes are recursive: the owning thread may
   re-acquire, each Acquire paired with a Release (ACPICA
   acpi_ex_acquire_mutex_object, exmutex.c:140). The old code tracked
   only a "held" set with no owner, so a nested acquire by the single
   AML thread waited for a release only it could perform — a
   self-deadlock.

Because acpid is single-threaded and the same thread serves the
`acpi` scheme socket, a stuck acquire stops acpid answering scheme
requests. The init namespace manager then blocks in the openat it was
proxying, and — since every restricted-namespace path resolution goes
through that single manager — the whole system's open path wedges
(observed: mini never reaches a usable brush login).

Fix: track (owner ThreadId, recursion depth) per mutex, treat a
nested acquire by the owner as a depth bump, interpret the timeout as
milliseconds, and bound any wait to MAX_MUTEX_WAIT (5s) so a
misbehaving AML method can never freeze the scheme-serving thread.
2026-07-21 04:47:00 +09:00
Red Bear OS 94a99f02ed usbhidd: reset global endpoint counter per candidate configuration
usbhidd already accumulated prior interfaces' endpoint counts (global
enumeration index, matching xhcid's PortState::get_endp_desc), but the
counter was never reset between candidate configurations — a HID device
whose usable config is not the first would get endpoint numbers offset
by the first config's endpoints. xhcid indexes within the selected
configuration only, so reset per config.
2026-07-20 21:09:05 +09:00