Agilex5 HPS running bare-metal code does not access FPGA fabric
I started with the following "Hello World" HPS OCRAM example: https://altera-fpga.github.io/rel-25.1/baremetal-embedded/agilex-5/e-series/premium/ug-baremetal-agx5e-premium/
I built the GHRD image with FPGA boot load set to "fabric first" and compiled the C code. With these changes, I am able to run the code and I can see the heartbeat LED toggle on the A5E premium development kit board. I am also able transmit data by writing the UART transmit register with my REG32 macro.
However, I cannot access either H2F or LWH2F interfaces. I put Signal Tap on all arvalid/awvalid signals I and I do not see them toggle (I sanity checked the setup using the heartbeat counter). After looking at the documentation and the provided bare-metal drivers code, I cobbled together the following code to attempt to enable the HPS2 FPGA bridges:
#define REG32(address) (*(volatile uint32_t*)address)
#define REG64(address) (*(volatile uint64_t*)address)
// Read the Reset manager registers
uint32_t value32;
value32 = REG32(0x10D1102C);
printf("Reset manager initial value = 0x%08x \n", value32);
// Drop the reset for SOC2FPGA bridges
REG32(0x10D1102C) = 0;
value32 = REG32(0x10D1102C);
printf("Reset manager value after modification = 0x%08x \n", value32);
printf("Enable FPGA bridges (NOTE: is this really an enable?)\n");
REG32(0x10D1205C) = 0x3;
value32 = REG32(0x10D1205C);
printf("Bridge enable register value after modification = 0x%08x \n", value32);Running this code I see:
Reset manager initial value = 0x0000004f
Reset manager value after modification = 0x00000000
Enable FPGA bridges
Bridge enable register value after modification = 0x00000003However, this loop does not show AWVALID come up on either AXI interface (I tried two different write macros to see if there is a difference):
while (1) {
printf("H2F: FPGA OCRAM write\n");
REG64(0x40000000) = 0x11223344;
printf("H2LWF: LED controller write\n");
mem_quick_write_32(0x20010080, 0);
}I feel like I am missing something obvious (like another enable) but I keep going over the code examples and the documentation and I can't find anything that could help. Any help is greatly appreciated.
Hi,
I do not have time to look into it now, and will be out Monday But if you want to use FreeRTOS, see below the instructions on how to make it work there:# install cmake and ninja build tools sudo apt-get install cmake ninja-build # create a top folder sudo rm -rf artifacts && mkdir artifacts && cd artifacts export TOP_FOLDER=`pwd` # add quartus tool to path export QUARTUS_ROOTDIR=~/altera_pro/25.3.1/quartus/ export PATH=$QUARTUS_ROOTDIR/bin:$QUARTUS_ROOTDIR/linux64:$QUARTUS_ROOTDIR/../qsys/bin:$PATH # download toolchain and add to path cd $TOP_FOLDER wget https://developer.arm.com/-/media/Files/downloads/gnu/14.3.rel1/binrel/arm-gnu-toolchain-14.3.rel1-x86_64-aarch64-none-elf.tar.xz tar xf arm-gnu-toolchain-14.3.rel1-x86_64-aarch64-none-elf.tar.xz rm -f arm-gnu-toolchain-14.3.rel1-x86_64-aarch64-none-elf.tar.xz export PATH=`pwd`/arm-gnu-toolchain-14.3.rel1-x86_64-aarch64-none-elf/bin/:$PATH # get freertos cd $TOP_FOLDER git clone https://github.com/Ignitarium-Technology/freertos-socfpga cd freertos-socfpga git checkout -b test v25.4 git submodule update --init --recursive # get sof file cd $TOP_FOLDER wget -O ghrd_a5ed065bb32ae6sr0.sof https://releases.rocketboards.org/2026.01/gsrd/agilex5_dk_a5e065bb32aes1_gsrd.baseline-a55/baseline_a55_hps.sof # build the bridge example cd $TOP_FOLDER/freertos-socfpga/samples/bridge cmake -B build . -G Ninja -DSOF_PATH=$TOP_FOLDER/ghrd_a5ed065bb32ae6sr0.sof cmake --build build --parallel -t sd-imageOnce you build it,you will get the following files:
- JIC QSPI Image: $TOP_FOLDER/freertos-socfpga/samples/bridge/build/sd_atf_binaries/qspi_image.jic
- SD Card Image: $TOP_FOLDER/freertos-socfpga/samples/bridge/build/sd_atf_binaries/sd.img
Write the above images and boot the board. You will see this:
... NOTICE: DDR: Reset type is 'Power-On' NOTICE: IOSSM: Calibration success status check... NOTICE: IOSSM: All EMIF instances within the IO96 have calibrated successfully! NOTICE: DDR: Calibration success NOTICE: DDR: ECC is enabled NOTICE: IOSSM: Memory initialized successfully on IO96B NOTICE: ###DDR:init success### NOTICE: DFI interface selected successfully to SDEMMC NOTICE: SOCFPGA: SDMMC boot NOTICE: BL2: v2.13.0(release): NOTICE: BL2: Built : 20:29:07, Feb 13 2026 NOTICE: BL2: Booting BL31 NOTICE: SOCFPGA: Boot Core = 0 NOTICE: SOCFPGA: CPU ID = 0 NOTICE: SOCFPGA: Setting CLUSTERECTRL_EL1 NOTICE: BL31: v2.13.0(release): NOTICE: BL31: Built : 20:29:07, Feb 13 2026 Starting the bridge sample application Read 217000 bytes from sdmmc drive successfully Bitstream data send successfully bitstream configuration successful Bitstream loaded successfully Starting h2f sample Write data buffer 1 : 1111111111111111 buffer 2 : 2222222222222222 Writing data to memory 0x40000000 Writing data to memory 0x7ffffff8 Reading data from memory 0x40000000 Reading data from memory 0x7ffffff8 Read data buffer 1 : 1111111111111111 buffer 2 : 2222222222222222 Validating the buffers Buffer validation successful HPS2FPGA sample completed successfully Completed h2f sample Starting lwh2f sample SYSID_ID : 1 WRITE DATA write buffer : 11111111 READ DATA read buffer : 11111111 LWHPS2FPGA sample completed successfully Completed lwh2f sample Bridge sample completedI actually prefer using an RTOS versus pure bare-metal, as it offers a lot of convenience. If you do not need the features, you can just put all your code in a single task (like the above example) and ignore them.
Note the above example uses HPS First (the default for the GSRD) and it configures the fabric with the file core.rbf which it builds and puts in the SD card image. It also uses DDR instead of OCRAM.
Regards,
Radu