Altera® (Intel®) SoC FPGAs use U-Boot as the boot loader on the HPS (hard processor system) side, and read/write access to a given address can be performed by using the command function implemented in U-Boot.
This function can be used for simple testing before the production software and OS/driver are ready, such as when checking board startup.
1. Preparation: U-Boot Settings
No special customization is required for the U-Boot to be used. Just make the Preloader/U-Boot project generated by BSP-Editor, which is included in the SoC FPGA Embedded Development Suite (SoC EDS) tool.
Power on the target board with the serial terminal connected, and press Enter while U-Boot counts down to display the prompt for waiting commands.
U-Boot 2013.01.01-00140-g0c9a3bd (Sep 19 2018 - 18:06:10)
CPU : Altera SOCFPGA Platform
BOARD : Altera SOCFPGA Cyclone V Board
I2C: ready
DRAM: 1 GiB
MMC: ALTERA DWMMC: 0
*** Warning - bad CRC, using default environment
In: serial
Out: serial
Err: serial
Net: mii0
Hit any key to stop autoboot: 0 ⇒ Enter key during U-Boot countdown display
SOCFPGA_CYCLONE5 #
This article is based on our testing with U-Boot on a Cyclone® V SoC target, but you should be able to follow the same procedure for other device families. It is assumed that you are familiar with how to build and write the U-Boot beforehand.
Reference: Beginner's Guide to SoC - How to use Preloader Generator
2. Commands to be used
The following four commands are available for read/write access.
- md - memory display
- mw - memory write (fill)
- mm - memory modify (auto-incrementing address)
- nm - memory modify (constant address)
The specifications for each command line are as follows. Read/Write accesses are performed by simply entering the command line as specified.
<md - memory display
Usage: md[.b, .w, .l] address [# of objects]
<mw - memory write (fill)>
Usage: mw[.b, .w, .l] address value [count]
<mm - memory modify (auto-incrementing address)
Usage: mm[.b, .w, .l] address
<nm - memory modify (constant address)> Usage: mm [.b, .w, .l] address
Usage: nm[.b, .w, .l] address
※ [.b, .w, .l] part specifies the access width.
{.b: Byte access, .w: Word (2Byte) access, .l: LongWord (4Byte)}
Note :
Note that the numbers you specify for address, value, count, etc. are treated as hexadecimal numbers.
For example, even if 40 is specified without a leading 0x, it will be processed as 0x40 (64).
3. Execution example
For reference, an example execution of each command is shown below. The logs listed here are executed on the U-Boot of a board with a Cyclone® V SoC. As mentioned earlier, the same method should be available for U-Boot for other device families.
[Memory Dump]
Byte Access
SOCFPGA_CYCLONE5 # md.b 0x10000000 0x40
10000000: b7 bc eb 3d e9 ff fe f7 ef df bf 77 ea f5 ff e7 ...=.......w....
10000010: d7 a1 af be df f6 bb fe df f6 d5 fd 77 f2 bf f1 ............w...
10000020: 4e 5f ff aa df bf 1a f2 bb df cd fa 7f e9 7b 6f N.............{o
10000030: bf af de a5 df f7 68 7f ff f6 ec e7 93 fb b9 ff ......h.........
Word Access
SOCFPGA_CYCLONE5 # md.w 0x10000000 0x20
10000000: bcb7 3deb ffe9 f7fe dfef 77bf f5ea e7ff ...=.......w....
10000010: a1d7 beaf f6df febb f6df fdd5 f277 f1bf ............w...
10000020: 5f4e aaff bfdf f21a dfbb facd e97f 6f7b N.............{o
10000030: afbf a5de f7df 7f68 f6ff e7ec fb93 ffb9 ......h.........
LongWord Access
SOCFPGA_CYCLONE5 # md.w 0x10000000 0x10
10000000: 3debbcb7 f7feffe9 77bfdfef e7fff5ea ...=.......w....
10000010: beafa1d7 febbf6df fdd5f6df f1bff277 ............w...
10000020: aaff5f4e f21abfdf facddfbb 6f7be97f N.............{o
10000030: a5deafbf 7f68f7df e7ecf6ff ffb9fb93 ......h.........
[Memory modify (incremental address)]
SOCFPGA_CYCLONE5 # mm.b 0x10000030
10000030: bf ? 0
10000031: af ? 1
10000032: de ? 2
10000033: a5 ? 3
: <Ctrl+C> to exit
[Memory modify (fixed address)]
SOCFPGA_CYCLONE5 # nm.b 0x10000030
10000030: be ? a
10000030: 0a ? b
10000030: 0b ? c
10000030: 0c ? d
: <Ctrl+C> to exit
[Memory Write]
SOCFPGA_CYCLONE5 # mw.b 0x10000000 0 1 # Write 0 in 1Byte x 1
SOCFPGA_CYCLONE5 # mw.b 0x10000008 0 4 # Write 0 in 1Byte x 4
SOCFPGA_CYCLONE5 # mw.w 0x10000010 0 1 # Write 0 in 2Bytes x 1
SOCFPGA_CYCLONE5 # mw.w 0x10000018 0 2 # Write 0 in 2Bytes x 2
SOCFPGA_CYCLONE5 # mw.l 0x10000020 0 1 # Write 0 in 4Bytes x 1
SOCFPGA_CYCLONE5 # mw.l 0x10000028 0 2 # Write 0 in 4Bytes x 2
SOCFPGA_CYCLONE5 # md.b 0x10000000 0x40 # Check write result (memory dump)
10000000: 00 bc eb 3d e9 ff fe f7 00 00 00 00 ea f5 ff e7 ...=............
10000010: 00 00 af be df f6 bb fe 00 00 00 00 77 f2 bf f1 ............w...
10000020: 00 00 00 00 df bf 1a f2 00 00 00 00 00 00 00 00 ................
10000030: bf af de a5 df f7 68 7f ff f6 ec e7 93 fb b9 ff ......h.........
※ The blue areas in the last memory dump result are the areas that were memory-written in advance.
Conclusion
As introduced, this command is very useful because you can try Read/Write access easily, but there is one point you should pay attention to.
Note:
When using this command to check access to memory and registers on the FPGA side, it is necessary to open the H2F and LWH2F bridges on the assumption that the configuration on the FPGA side has been completed in advance.
The U-Boot command can be used to open the bridge.
<In case of Cyclone® V / Arria® V SoC>
# run bridge_enable_handoff
<In case of Arria® 10 SoC>
# fpgabr 1
Please also refer to the following article for more information on bridge openings. Reference: HPS to FPGA interface opening