Add wolfBoot FIT support for loading bitstream#786
Conversation
134b701 to
a5d0255
Compare
a5d0255 to
ab6b3b4
Compare
fcc8bc3 to
01e3612
Compare
01e3612 to
9fe5512
Compare
9fe5512 to
3a4e990
Compare
| int hal_fpga_load(uint32_t flags, uintptr_t addr, size_t size) | ||
| { | ||
| uint32_t sts; | ||
| uint32_t words = (uint32_t)((size + 3U) / 4U); |
There was a problem hiding this comment.
I would suggest a check on size being < 4GB when casting to uint32_t
| /* arg0=addr_low, arg1=addr_high, arg2=size(bytes), arg3=flags */ | ||
| pmu_request(PM_FPGA_LOAD, | ||
| (uint32_t)(addr & 0xFFFFFFFF), (uint32_t)((uint64_t)addr >> 32), | ||
| (uint32_t)size, pmflags, ret_payload); |
There was a problem hiding this comment.
size cast to uint32_t: original value was size_t. Ensure to check the size parameter fits in 4GB
| /* 1. Unlock DevC and select PCAP (not ICAP). */ | ||
| Z7_DEVC_UNLOCK = Z7_DEVC_UNLOCK_KEY; | ||
| Z7_DEVC_CTRL |= (Z7_DEVC_CTRL_PCAP_MODE | Z7_DEVC_CTRL_PCAP_PR); |
There was a problem hiding this comment.
It looks like you're enabling ICAP instead, according to the comment in zynq7000.h (ICAP is PCAP_PR (bit 27) = 1, PCAP is PCAP_PR = 0
Either the flag setting here is accidental, or the comment is wrong in zynq7000.h:
#define Z7_DEVC_CTRL_PCAP_PR 0x08000000U /* bit 27: 1=PCAP, 0=ICAP */
| Z7_DEVC_DMA_SRC = ((uint32_t)addr) | Z7_DEVC_DMA_LAST; | ||
| Z7_DEVC_DMA_DST = Z7_DEVC_DMA_DEST_PCAP; | ||
| Z7_DEVC_DMA_SRC_LEN = words; | ||
| Z7_DEVC_DMA_DST_LEN = words; |
There was a problem hiding this comment.
this should probably check if DMA is full via Z7_DEVC_STATUS_DMA_CMD_FULL.
If the transaction is silently lost, next step "7." might loop forever.
Features
fpgasub-image in a signed FIT, using the standard U-Boot convention: sub-imagetype = "fpga", configurationfpga = "<node>"reference, and acompatiblestring selecting the load method (partialin the string selects partial reconfiguration, otherwise full). Programmed before the kernel/DTB load so PL-dependent clocks/peripherals come up first.hal_fpga_load()HAL abstraction with a weak default (returns not-implemented) and per-target implementations.TARGET=zynq): full bitstream via the PMU firmwarePM_FPGA_LOADEEMI call (xilfpga / CSU DMA / PCAP).TARGET=zynq7000): full bitstream via a new DevC/PCAP DMA driver (UG585 ch.6) with bounded poll-loop timeouts.TARGET=versal): documented not-implemented stub (PL config is a PLM Load-PDI IPI).fit_load_fpga()stages the bitstream to a configurable DDR address (WOLFBOOT_LOAD_FPGA_ADDRESS), decompressing gzip bitstreams (the typicalmkimageoutput, which has noloadproperty) bounded byWOLFBOOT_FIT_MAX_FPGAand validated by the gzip CRC32 + ISIZE.FIT_CONFIG_SELECT=1plus a weakhal_fit_config_name()hook lets an integrator boot a non-defaultconfiguration (e.g.conf-<board>); the default returns NULL (use the FITdefault). No board-detection (GPIO/CHIPID) logic is shipped upstream.FPGA_BITSTREAM,FPGA_NONFATAL(failed PL load warns and continues instead of panicking),WOLFBOOT_LOAD_FPGA_ADDRESS,FIT_CONFIG_SELECT. All opt-in; default builds are unchanged.fit_find_images()extended to discover the fpga node (configfpgaproperty andtype == "fpga"fallback); newfit_get_compatible()helper.unit-fit-fpgaunit test covering fpga discovery and compatible parsing; docs and.itstemplate updated.Fixes
PM_FPGA_LOADsize is passed in bytes (not 32-bit words), matching stock Xilinx U-Boot and the PMU firmware xilfpga, which divides by the word length internally.loadproperty to the staging address, instead of failing closed.hal_fpga_load()/hal_fit_config_name()defaults inhal/hal.c(linked into every target) rather than a region oflibwolfboot.cthat is compiled out for the Xilinx targets, fixing an undefined-reference link error.Testing
Results testing FIT image boot with FPGA image on ZCU102: