Skip to content

services: Add the OCP recovery register layouts - #628

Draft
chrysh wants to merge 1 commit into
OpenPRoT:ocp-global-demo-wipfrom
9elements:ocp-recovery-registers
Draft

chrysh wants to merge 1 commit into
OpenPRoT:ocp-global-demo-wipfrom
9elements:ocp-recovery-registers

Conversation

@chrysh

@chrysh chrysh commented Oct 28, 2026

Copy link
Copy Markdown
Contributor

Q4 task 4c, first piece. The eRoT serves the OCP Recovery interface as the Device and the BMC drives it as the Recovery Agent. This crate holds the half that does not depend on the transport: the command codes 0x22 to 0x2f with their access rule, length and availability scope, the byte layouts, the field encodings, and the rules for which accesses the Device refuses.

Scope stops at the AMD design gate: no SMBus framing, no PEC, no staging or verify path, no state machine. Those answers (I2C vs I3C, forced recovery, whether the i2c read path is in scope) change the transport and the entry path, not the byte layouts.

The AST1030 has no OCP recovery silicon, so firmware keeps the access semantics the agent expects from hardware. Write 1, Device Clears on RECOVERY_CTRL byte 2, DEVICE_RESET byte 0 and INDIRECT_FIFO_CTRL byte 1 means the agent writes the command value and the Device zeroes the field once it has acted, not a bitwise clear of the written bits. Each of the three has an apply_agent_write and a clear_*, and writing 0x1 to the activate field is refused rather than leaving 0xe behind.

Writes take a fixed-size array so the length is settled by the type, and from_wire resolves it once where the bytes arrive. ImageIndex and VendorStatusLen bound the two fields the Device fills, so a Device-side mistake cannot be reported to the agent as a protocol error.

Follows the services/<proto>/api pattern: rust_library plus rust_test(crate = ...), zerocopy only, no kernel tags, host-testable.

Checked with bazel test //services/ocp-recovery/api:ocp_recovery_api_test, the clippy aspect, and ./pw format --all --check.

Stacked PR with the device dispatch follows.

The eRoT serves the OCP Recovery interface as the device and the BMC
drives it as the Recovery Agent. This crate holds the half that does not
depend on the transport: the command codes 0x22 to 0x2f, the byte
layouts, the field encodings and the rules for which accesses the device
refuses. The SMBus framing, the PEC and the register file the
server-runtime owns come later, so the crate stays host-testable and
free of kernel dependencies.

The AST1030 has no OCP recovery silicon, so firmware has to keep the
access semantics the agent expects from hardware. "Write 1, Device
Clears" means the agent writes the command value and the device zeroes
the field once it has acted, not a bitwise clear of the written bits:
each of the three fields that work that way has an apply_agent_write and
a clear_*, and writing 0x1 to the activate field is refused rather than
leaving 0xe behind.

The writes take a fixed-size array so the length is settled by the type,
and RecoveryCommand::check_write resolves it where the bytes arrive off
the wire.

Signed-off-by: Christina Quast <christina.quast@9elements.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant