Skip to content

target/ast10x0: Add the mock BMC integration test - #538

Open
chrysh wants to merge 5 commits into
OpenPRoT:ocp-global-demo-wipfrom
9elements:mock-bmc-itest
Open

chrysh wants to merge 5 commits into
OpenPRoT:ocp-global-demo-wipfrom
9elements:mock-bmc-itest

Conversation

@chrysh

@chrysh chrysh commented Oct 3, 2026

Copy link
Copy Markdown
Contributor

Review the last commit only. The four before it are #532, #533, #536 and
#537; the fork cannot host a real stack.

First scenario of the QEMU black-box test: the RoT releases a managed
device from reset, the device boots, and the RoT sees it report ready
inside the window it allows.

Two processes stand in for two chips. The wires between them are IPC
channels rather than GPIO, because QEMU models one chip and both ends
live inside it, so a GPIO block would connect to nothing. Commands go out
on reset_cmd, evidence comes back on boot_evt. The split matters:
EvidenceReader::read is synchronous and must not block, so the
orchestrator holds a latch and the device pushes to it, rather than the
orchestrator asking.

What this costs: the GPIO adapters in board/src/bmc.rs are swapped at the
trait seam rather than exercised. The test proves the orchestrator logic
and, as it grows, the update path. It does not prove the pin wiring, and
that stays with the hardware tests.

Checked that it fails for the right reason: with the device set to Hangs
the orchestrator's window expires, it logs "mock BMC never reported
ready", and the test fails.

App flash is the window between the kernel's flash and its RAM, 0x20500
to 0x60000, so 254.8 KB. Two apps at 128 KB fill it exactly. A third at
that size is placed over kernel RAM and still builds, with only PMSAv7
MPU subregion overlap warnings to say the protection is wrong, so adding
the PLDM firmware device means the apps drop to 84 KB or less.

Assisted-by: Claude

chrysh added 5 commits October 3, 2026 13:58
The QEMU runner filled each FMC backing image with one byte, so a test
could hand the device erased flash and nothing else. The integration
test needs the device to already hold a firmware image the update agent
can offer.

cs0_contents and cs1_contents name a file to copy in at offset 0; the
remainder stays 0xFF. Without them the fill byte behaves as before, so
every existing test is unchanged.

A contents file longer than flash_size is an error rather than a
truncation. A half-written image still parses far enough to fail
verification, which would make a verify-failure scenario pass for the
wrong reason.

Assisted-by: Claude
A QEMU test that offers a firmware image needs that image on flash
before the guest boots. The harness can now seed a chip select from a
file; this makes the file.

The layout arrives as arguments but is built with the same Region, Slot
and ImageLayout constructors the board tables use, so a layout this tool
accepts is one the orchestrator would accept: unique slot ids, no
overlap, no zero-length region, nothing past the end of the offset
space. Re-deriving those rules here would let a test image drift from
what the firmware believes about the same flash.

Everything no image covers stays 0xFF, and a payload too large for its
slot is an error rather than a truncation.

The flash_image rule wraps the tool so a BUILD file can hand the result
straight to cs0_contents or cs1_contents.

Assisted-by: Claude
The QEMU integration test needs something on the other end of the RoT's
reset and ready lines. This is that device: held in reset the ready line
stays inactive, and once reset is released it goes active after a delay,
or never.

Generic over InputPin and OutputPin, so the lines can be GPIO on a board
or whatever the wiring supplies in a test image. Time arrives as an
argument to poll and nothing waits, so the same model runs from a kernel
event loop or from a test that moves the clock by hand.

Asserting reset drops the ready line and restarts the delay. The RoT has
to see evidence disappear when it resets a device, or a stale ready line
would answer for the new boot.

Boots and Hangs are the only behaviours. A late boot is Boots with a
delay past the window the RoT waits, which makes lateness a property of
the deadline rather than of the device.

Assisted-by: Claude
A QEMU test has no wire and no second chip, but the PLDM firmware device
still has to reach an update agent. This is the transport for that: each
server queues what its router fragments, and the caller feeds that queue
to the other server's inbound. One server's outbox is the other's wire.

Two servers, not one looping back to itself. A message addressed to a
server's own EID has no route out and back, which the router reports as
BadArgument before the sender is ever consulted.

The queue belongs to the caller rather than to the sender, because the
router takes the sender by value and offers no way back to it. Draining
in the caller's loop also keeps the send path non-blocking.

The fragment buffer holds the MTU plus the four-byte MCTP header. A
buffer of exactly the MTU makes the router refuse the send rather than
truncate it.

The arrangement comes from services/mctp/echo/tests/echo_host.rs, which
does the same thing with test-local helpers. This is the library version,
so an app can use it.

Assisted-by: Claude
First scenario of the QEMU black-box test: the RoT releases a managed
device from reset, the device boots, and the RoT sees it report ready
inside the window it allows.

Two processes stand in for two chips. The wires between them are IPC
channels rather than GPIO, because QEMU models one chip and both ends
live inside it, so a GPIO block would connect to nothing. Commands go
out on reset_cmd, evidence comes back on boot_evt. The split matters:
EvidenceReader::read is synchronous and must not block, so the
orchestrator holds a latch and the device pushes to it, rather than the
orchestrator asking.

The device's behaviour is openprot_mock_bmc, which is pin-generic and
host-tested, wired here to two cells. What it costs is that the GPIO
adapters in board/src/bmc.rs are swapped at the trait seam rather than
exercised; the pin wiring stays with the hardware tests.

App flash is the window between the kernel's flash and its RAM, 0x20500
to 0x60000, so 254.8 KB. Two apps at 128 KB fill it exactly. A third at
that size is placed over kernel RAM and still builds, with only PMSAv7
MPU subregion overlap warnings to say the protection is wrong, so the
PLDM firmware device needs the apps at 84 KB or less. The hardware card
already runs pldm_fd at 64 KB.

Assisted-by: Claude

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