real-hw-test: init - #71
Conversation
1de6fe5 to
9bc95d0
Compare
phip1611
left a comment
There was a problem hiding this comment.
Almost. Let's drop the ci feature. The crate should not know anything required for a CI run. IF this means a QEMU CI run is not feasible than drop that entirely. If it is possible, keep the QEMU CI run.
The dev shell supplies QEMU, OVMF, and rustup. The .envrc enables direnv integration.
Manual hardware checks can wait forever for an operator. Disable the UEFI image watchdog so a long session does not reset the machine. Report firmware failures on screen.
MMIO addresses do not describe a Rust allocation, so use the wrapping pointer primitive rather than an in-bounds pointer offset. The UART constructor already rejects a register range that would wrap.
Mirror every test diagnostic to a dated file below /uart_16550_test_logs while retaining UEFI console output. Keep one flushed FAT file handle so a failed write is reported as critical and aborts the test instead of losing failure evidence.
A real UART can still be draining the byte accepted by try_send_byte when send_bytes is called. Retry the nonblocking API for one second instead of treating temporary backpressure as a driver failure. Preserve an earlier modem-signal warning if a later driver check fails.
Report the dated USB-drive log path before each normal test exit. This keeps the result on screen when the automated checks fail as well as when they complete successfully.
3924328 to
d8f46d9
Compare
Run the unmodified interactive image headlessly under TCG. The harness answers the operator prompts through QEMU-monitor sendkey and judges the run by the log persisted on the boot volume plus both serial captures. Require automatic checks for legacy COM1 and a PCI UART.
Port I/O instructions, legacy COM probing, and the PIO driver backend exist only on x86. Compiler-enforced cfg gates keep every port-address path out of the builds of other architectures.
Without x86 port instructions, PCI I/O space is a memory-mapped window behind the root bridge. Firmware hides the CPU-side base inside its protocol implementation, but AML resource templates embed plain address space descriptors, so a strictly validated DSDT byte scan recovers the translated window without an AML interpreter. Firmware also leaves the decoding of endpoints it never binds disabled; an assigned BAR of an unambiguous UART is therefore enabled explicitly.
ARCH selects the Rust target, the removable-media file name, and the matching QEMU machine: q35 with OVMF on x86_64, virt with pflash EDK2, ramfb, and a USB keyboard on aarch64. The dev shell switches to the full QEMU because qemu_kvm only carries the host architecture.
The aarch64 virt machine has no 16550 except the PCI serial device, so the run must reject the PL011 console via SPCR and drive the PCI UART through the translated I/O window with the MMIO backend.
One USB stick can carry runs from several machines; the architecture in the log file name and the on-screen banner keeps them apart.
'make artifacts' cross-compiles all supported architectures, and the USB install copies every artifact under build/ to its removable-media path, so one stick boots the test on any supported machine.
d8f46d9 to
128bac2
Compare
| @@ -0,0 +1,177 @@ | |||
| #!/usr/bin/env bash | |||
| set -euo pipefail | |||
|
|
|||
There was a problem hiding this comment.
Lot's of complexity here. do you see chance for simpliciation / less code?
There was a problem hiding this comment.
Some, but most of the weight is load-bearing. Roughly: ~35 lines per-arch machine/firmware setup, ~25 per-arch assertions, ~40 failure diagnostics (fail_run/dump_logs — what makes a red CI run debuggable from the job log alone), ~25 the two-phase key driving. The phases themselves are semantic, not accidental: no key may be sent before the first prompt (Escape during BDS would enter firmware setup), and the final extraction must happen after QEMU quits for the FAT state to be committed.
Cuttable, at a cost: the tool preflight loop (-8 lines, cryptic late failures instead of one clear message), the CI_RUN_DIR rm-guard (-4, safety), mid-run log polling could poll the console log instead of the FAT image (-0, and it would couple the gate to firmware console mirroring, which aarch64 does not have for the app output). I would leave it as is; happy to trim any of the above if you prefer less code over the diagnostics.
Init a new crate member that builds a EFI file that can be easily booted on real hardware.