Conversation
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 wolfTPM fwTPM server port for AMD Zynq-7000 (ZC702) Cortex-A9, including a sibling “hello” bring-up image and host-side UART tooling, with optional QSPI-backed NV storage and an SRAM-PUF–derived NV integrity key.
Changes:
- Introduces Zynq-7000 bare-metal HAL (startup, MMU, UART, timers, newlib retarget) plus a hello-world heartbeat image.
- Adds fwTPM firmware (UART swtpm/mssim framing), SRAM PUF integration (incl. synthetic selftest), and NV backends (RAM default, QSPI optional).
- Adds host-side Python utilities (swtpm TCP↔UART bridge, UART functional test, NV persistence test) and documentation.
Reviewed changes
Copilot reviewed 27 out of 27 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| Xilinx/fwtpm-zc702-a9/firmware/hello/zynq7000-ddr.ld | Adds DDR linker script for hello-world image. |
| Xilinx/fwtpm-zc702-a9/firmware/hello/main.c | Implements UART banner + global-timer heartbeat sanity test. |
| Xilinx/fwtpm-zc702-a9/firmware/hello/Makefile | Builds the hello-world image with the common HAL. |
| Xilinx/fwtpm-zc702-a9/firmware/fwtpm-a9/zynq7000-fwtpm.ld | Adds DDR linker script sized for fwTPM (larger heap/stack). |
| Xilinx/fwtpm-zc702-a9/firmware/fwtpm-a9/user_settings.h | Defines wolfSSL/wolfTPM build configuration for bare-metal + PUF/MemUse. |
| Xilinx/fwtpm-zc702-a9/firmware/fwtpm-a9/main.c | Implements fwTPM init, self-test, and UART swtpm/mssim command server. |
| Xilinx/fwtpm-zc702-a9/firmware/fwtpm-a9/host-client/swtpm_uart_bridge.py | Adds TCP mssim ↔ UART bridge for existing wolfTPM swtpm clients. |
| Xilinx/fwtpm-zc702-a9/firmware/fwtpm-a9/host-client/fwtpm_uart_test.py | Adds direct UART functional test client (caps/PCR/random). |
| Xilinx/fwtpm-zc702-a9/firmware/fwtpm-a9/host-client/fwtpm_nv_persist_test.py | Adds TPM NV persistence test over UART. |
| Xilinx/fwtpm-zc702-a9/firmware/fwtpm-a9/fwtpm_puf_selftest.c | Adds on-target synthetic SRAM PUF regression (build-time opt-in). |
| Xilinx/fwtpm-zc702-a9/firmware/fwtpm-a9/fwtpm_puf.h | Declares PUF init/key hook + helper persistence seam. |
| Xilinx/fwtpm-zc702-a9/firmware/fwtpm-a9/fwtpm_puf.c | Implements OCM SRAM PUF enroll/reconstruct and integrity-key derivation. |
| Xilinx/fwtpm-zc702-a9/firmware/fwtpm-a9/fwtpm_nv_ram.c | Implements volatile RAM-backed NV HAL. |
| Xilinx/fwtpm-zc702-a9/firmware/fwtpm-a9/fwtpm_nv_qspi.c | Implements QSPI-backed NV HAL + persistent PUF helper store. |
| Xilinx/fwtpm-zc702-a9/firmware/fwtpm-a9/fwtpm_clock_zynq.c | Implements fwTPM clock HAL + sleep shim + entropy timer. |
| Xilinx/fwtpm-zc702-a9/firmware/fwtpm-a9/Makefile | Builds fwTPM image from sibling wolfSSL/wolfTPM source trees. |
| Xilinx/fwtpm-zc702-a9/firmware/common/zynq_uart.h | Declares minimal polled Cadence UART API. |
| Xilinx/fwtpm-zc702-a9/firmware/common/zynq_uart.c | Implements polled Cadence UART driver (+ optional baud configuration). |
| Xilinx/fwtpm-zc702-a9/firmware/common/zynq_time.h | Declares Global Timer + PMU cycle-counter timing API. |
| Xilinx/fwtpm-zc702-a9/firmware/common/zynq_time.c | Implements Global Timer ticks/ms/delays and PMU cycle counter enable/read. |
| Xilinx/fwtpm-zc702-a9/firmware/common/zynq7000.h | Adds Zynq-7000 address/clock definitions (UART, timers, QSPI, OCM). |
| Xilinx/fwtpm-zc702-a9/firmware/common/startup.S | Adds bare-metal A9 reset/startup: vectors, stacks, cache/MMU/VFP, BSS, main. |
| Xilinx/fwtpm-zc702-a9/firmware/common/retarget.c | Adds newlib syscall stubs (stdio→UART, _sbrk heap, gettimeofday). |
| Xilinx/fwtpm-zc702-a9/firmware/common/mmu.c | Adds minimal 1MB-section MMU mapping enabling Normal DDR for printf correctness. |
| Xilinx/fwtpm-zc702-a9/README.md | Adds ZC702 fwTPM build/run docs and design notes. |
| Xilinx/fwtpm-zc702-a9/.gitignore | Ignores build artifacts and Python cache files for the new port. |
| README.md | Links the new ZC702 port from the repo root README. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
|
|
||
| uint64_t zynq_millis(void) | ||
| { | ||
| return zynq_global_ticks() / (uint64_t)(ZYNQ_GLOBAL_TIMER_FREQ / 1000u); |
Comment on lines
+216
to
+221
| if (cmdSize < 10 || cmdSize > FWTPM_MAX_COMMAND_SIZE) { | ||
| if (cmdSize > 10U) { | ||
| UartDrain(cmdSize - 10U); | ||
| } | ||
| UartSend(g_tpmRcFailure, sizeof(g_tpmRcFailure)); | ||
| continue; |
Comment on lines
+286
to
+294
| cmdSize = LoadU32BE(hdr); | ||
| if (cmdSize == 0 || cmdSize > FWTPM_MAX_COMMAND_SIZE) { | ||
| if (cmdSize > 0U) { | ||
| UartDrain(cmdSize); | ||
| } | ||
| StoreU32BE(rspHdr, 0); | ||
| UartSend(rspHdr, 4); | ||
| UartSendAck(); | ||
| continue; |
Comment on lines
+237
to
+246
| static int spi_flash_wait_ready(void) | ||
| { | ||
| uint8_t status = 0xFF; | ||
| do { | ||
| if (spi_flash_status(&status) != 0) { | ||
| return -1; | ||
| } | ||
| } while ((status & SPI_STATUS_WIP) != 0); | ||
| return 0; | ||
| } |
Comment on lines
+268
to
+271
| static int qspi_addr_safe(uint32_t address) | ||
| { | ||
| return (address >= FWTPM_QSPI_MIN_SAFE); | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
A bare-metal firmware-TPM 2.0 server (wolfTPM
fwtpm) running on a single Cortex-A9 of an AMD Zynq-7000 (ZC702), driven from a host over UART with the same raw swtpm + Microsoft-simulator ("mssim") framing as the existing STM32H5 and Mi-V ports, so the stock wolfTPM swtpm client drives it unmodified.Distinguishing feature: PUF-derived NV integrity key
The TPM NV-journal integrity key is a device-unique key derived from the Cortex-A9 on-chip-memory (OCM) SRAM power-on state, using wolfCrypt's configurable SRAM PUF (a BCH(127,k,t) fuzzy extractor plus HKDF). No root key is stored in flash - it is regenerated from silicon on each boot. Persistent NV and the PUF helper data live in QSPI flash (
-DFWTPM_NV_QSPI).What is included
-DFWTPM_PUF_SELFTEST) with selectable BCH profile.hellosanity image.-DFWTPM_ENABLE_PQC) for an ECC + ML-DSA / ML-KEM TPM instead of the default RSA + ECC.Hardware validation
Validated on the ZC702 bench over JTAG (prebuilt FSBL does
ps7_init, app loaded over the top): fwTPM boots, self-test passes, and the SRAM PUF regenerates a stable device-unique integrity key across boots.Notes
Self-contained bare-metal server model (the dual-A9 second core and PetaLinux are not used; the coprocessor + Linux-client model is the separate ZCU102 R5 example). No vendor BSP is redistributed; wolfSSL and wolfTPM are consumed as sibling source trees.