Conversation
|
Requires wolfSSL/wolfTPM#574 |
There was a problem hiding this comment.
Pull request overview
Warning
Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.
Adds a bare-metal MicroBlaze V (rv32imc) firmware-TPM (wolfTPM fwtpm) example for the AMD Spartan UltraScale+ SCU35, including an FPGA overlay to instantiate SYSMONE4 as a hardware entropy source so a minimal ECC-only build can fit in 192 KB BRAM.
Changes:
- Introduces Vivado TCL scripts to rebuild the AMD SCU35 Zephyr TRD bitstream with an AXI System Management Wizard (SYSMONE4) mapped for a TRNG seed source.
- Adds bare-metal MicroBlaze V HAL, a hello-world bring-up image, and the fwTPM UART server with NV/clock/TRNG integrations and size-tuned build settings.
- Adds SCU35-specific documentation and top-level README entry describing capabilities, constraints, and build/run steps.
Reviewed changes
Copilot reviewed 24 out of 25 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| Xilinx/fwtpm-scu35-microblazev/fpga/build_sysmon.tcl | Vivado batch build driver to regenerate TRD design and produce a PDI with SYSMON added. |
| Xilinx/fwtpm-scu35-microblazev/fpga/add_sysmon.tcl | Block-design overlay that instantiates and connects SYSMONE4 AXI System Management Wizard. |
| Xilinx/fwtpm-scu35-microblazev/fpga/README.md | FPGA rebuild instructions, memory sizing discussion, and address map for SYSMON integration. |
| Xilinx/fwtpm-scu35-microblazev/firmware/hello/mbv-bram.ld | Linker script for the hello-world BRAM-resident image. |
| Xilinx/fwtpm-scu35-microblazev/firmware/hello/main.c | Hello-world UART output + timer heartbeat bring-up program. |
| Xilinx/fwtpm-scu35-microblazev/firmware/hello/Makefile | Build recipe for the hello-world image using the Vitis RISC-V toolchain. |
| Xilinx/fwtpm-scu35-microblazev/firmware/fwtpm-mbv/vivado.log | Checked-in Vivado run log for SYSMON validation. |
| Xilinx/fwtpm-scu35-microblazev/firmware/fwtpm-mbv/vivado.jou | Checked-in Vivado journal for SYSMON validation. |
| Xilinx/fwtpm-scu35-microblazev/firmware/fwtpm-mbv/user_settings.h | wolfSSL/wolfTPM configuration tuned for tiny ECC-only + optional SYSMON-seeded DRBG. |
| Xilinx/fwtpm-scu35-microblazev/firmware/fwtpm-mbv/mbv-bram.ld | Linker script for the fwTPM image (larger BRAM target for full build). |
| Xilinx/fwtpm-scu35-microblazev/firmware/fwtpm-mbv/main.c | fwTPM initialization + UART server loop implementing swtpm/mssim framing. |
| Xilinx/fwtpm-scu35-microblazev/firmware/fwtpm-mbv/fwtpm_trng_sysmon.c | SYSMONE4 oversampling seed generator for Hash-DRBG under FWTPM_TINY_HWTRNG. |
| Xilinx/fwtpm-scu35-microblazev/firmware/fwtpm-mbv/fwtpm_nv_ram.c | Volatile RAM-backed NV HAL implementation with tiny-build sizing. |
| Xilinx/fwtpm-scu35-microblazev/firmware/fwtpm-mbv/fwtpm_clock_mbv.c | Clock HAL using AXI Timer + XSLEEP_MS shim + entropy hi-res timer. |
| Xilinx/fwtpm-scu35-microblazev/firmware/fwtpm-mbv/Makefile | fwTPM build recipe (wolfSSL/wolfTPM sibling trees) plus tiny-build flags guidance. |
| Xilinx/fwtpm-scu35-microblazev/firmware/common/startup.S | Minimal RV32 startup code for MicroBlaze V. |
| Xilinx/fwtpm-scu35-microblazev/firmware/common/scu35_board.h | Board constants (addresses, console UART choice, clock frequency). |
| Xilinx/fwtpm-scu35-microblazev/firmware/common/retarget.c | Newlib syscall stubs mapping stdio to UARTLite and implementing _sbrk. |
| Xilinx/fwtpm-scu35-microblazev/firmware/common/mbv_uart.h | AXI UARTLite minimal polled driver header. |
| Xilinx/fwtpm-scu35-microblazev/firmware/common/mbv_uart.c | AXI UARTLite minimal polled driver implementation. |
| Xilinx/fwtpm-scu35-microblazev/firmware/common/mbv_time.h | AXI Timer timekeeping API with wrap-handling requirements. |
| Xilinx/fwtpm-scu35-microblazev/firmware/common/mbv_time.c | AXI Timer timekeeping implementation (32-bit hw counter extended to 64-bit). |
| Xilinx/fwtpm-scu35-microblazev/README.md | Top-level SCU35 example documentation (layout, build, run). |
| Xilinx/fwtpm-scu35-microblazev/.gitignore | Ignores build artifacts and FPGA outputs for this example. |
| README.md | Adds a repository-level entry pointing to the new SCU35 MicroBlaze V example. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| static int UartRecvTO(uint8_t* buf, uint32_t sz, uint32_t timeoutMs) | ||
| { | ||
| uint32_t i; | ||
| uint64_t deadline; | ||
|
|
||
| for (i = 0; i < sz; i++) { | ||
| deadline = mbv_millis() + timeoutMs; | ||
| while (mbv_uart_getc(SCU35_CONSOLE_UART_BASE, &buf[i]) == 0) { | ||
| (void)mbv_ticks(); | ||
| if (mbv_millis() >= deadline) { | ||
| return -1; | ||
| } | ||
| } | ||
| } | ||
| return 0; | ||
| } |
| * Volatile RAM-backed FWTPM_NV_HAL for the MicroBlaze V fwTPM bring-up. A 64 KiB | ||
| * buffer whose contents are lost across power cycles. The wolfTPM core owns the |
| # 2. Add one master port to the MicroBlaze V AXI SmartConnect (19 -> 20) and | ||
| # wire it to the wizard's AXI4-Lite slave. | ||
| set_property CONFIG.NUM_MI {20} [get_bd_cells microblaze_riscv_0_axi_periph] | ||
| connect_bd_intf_net \ | ||
| [get_bd_intf_pins microblaze_riscv_0_axi_periph/M19_AXI] \ |
| minimal ECC-only build (`FWTPM_TINY_ECC`) fits the stock 192 KB of block RAM | ||
| (no DDR on this part): ~190 KB via wolfTPM's `FWTPM_MINIMAL` command gating and an | ||
| on-die SYSMONE4 fabric TRNG (added by `fpga/add_sysmon.tcl`) in place of MemUse |
| 3. Read the console (`axi_uartlite_0`) over the SCU35 FT4232H UART with `uart-monitor`. | ||
|
|
||
| ## Address map (from the TRD, for the firmware `scu35_board.h`) | ||
|
|
||
| | Block | Base | | ||
| |-------|------| | ||
| | Local BRAM (reset vector) | `0x00000000` | | ||
| | AXI UARTLite 0 (console) | `0x40600000` | | ||
| | AXI UARTLite 1 | `0x40700000` | |
…only fits 192KB via SYSMON TRNG + per-command-group gating)
Summary
A firmware-TPM 2.0 server (wolfTPM
fwtpm) on a MicroBlaze V (RISC-V rv32imc) soft core instantiated in the fabric of an AMD Spartan UltraScale+ SCU35 (xcsu35p) - a pure FPGA with no hardened CPU. It is the AMD analog of the PolarFire Mi-V example: driven from a host over UART with the same raw swtpm / mssim framing, so the stock wolfTPM swtpm client drives it unmodified.The interesting problem: fitting a TPM in 192 KB
The
xcsu35phas only 48 block-RAM primitives = 192 KB total, no UltraRAM, and the board has no external DDR. The full RSA+ECC fwTPM is ~652 KB and does not fit. This example shows how a genuinely minimal fwTPM is brought under the device limit and validates it on hardware.A minimal ECC-only build (
-DFWTPM_TINY_ECC) fits in ~190 KB (1.9 KB to spare) via:FWTPM_NO_*command-group macros, selected explicitly inuser_settings.h(there is no umbrella macro; each gate is a deliberate choice) - compiling out the key-migration / ECDH / hash-command / context / symmetric-encrypt / clock command groups (~20 KB).What is included
fwtpm-mbv/) with clock and volatile-NV HALs and the SYSMONE4 TRNG seed source (fwtpm_trng_sysmon.c,-DFWTPM_TINY_HWTRNG).fpga/add_sysmon.tcl(overlay that adds the System Management Wizard at 0x44A30000) andfpga/build_sysmon.tcl(build driver that sources the stock TRD block design unmodified, applies the overlay, and produces a device image).hellosanity image and sizing analysis.Hardware validation (SCU35, Vivado 2025.1)
Hart #0:TPM2_StartupandTPM2_GetRandomreturnrc=0x00000000, and GetRandom returns different bytes across three cold boots - end-to-end proof the Hash-DRBG is seeded from real System-Monitor entropy.Notes
The full RSA+ECC firmware also builds and is ready for a larger MicroBlaze V target. No vendor bitstream or BSP is redistributed; the TRD is obtained from AMD and wolfSSL/wolfTPM are sibling source trees.