This page is intended to complement UG1186 "LibMetal and OpenAMP User Guide" for Zynq-7000 and Zynq UltraScale+ MPSoC.
host shell$ tar xvf xilinx-zcu102-v2020.2-final.bsp --strip-components=4 --wildcards */BOOT.BIN */image.ub */openamp.dtb host shell$ cp BOOT.BIN image.ub openamp.dtb <your sd card> |
... Hit any key to stop autoboot: 0 u-boot> fatload mmc 0 0x3000000 Image u-boot> fatload mmc 0 0x2000000 openamp.dtb u-boot> fatload mmc 0 0x2A00000 rootfs.cpio.gz.u-boot u-boot> bootm 0x3000000 0x2A00000 0x2000000 ... |
plnx_aarch64 login: root Password: root@plnx_aarch64:~# echo image_echo_test > /sys/class/remoteproc/remoteproc0/firmware root@plnx_aarch64:~# echo start > /sys/class/remoteproc/remoteproc0/state [ 177.375451] remoteproc remoteproc0: powering up ff9a0100.zynqmp_r5_rproc [ 177.384705] remoteproc remoteproc0: Booting fw image image_echo_test, size 644144 [ 177.396832] remoteproc remoteproc0: registered virtio0 (type 7) [ 177.399108] virtio_rpmsg_bus virtio0: rpmsg host is online [ 177.412370] zynqmp_r5_remoteproc ff9a0100.zynqmp_r5_rproc: RPU boot from TCM. [ 17Starting application... Try to init remoteproc resource Init remoteproc resource succeeded Waiting for events... 7.422089] remoteproc remoteproc0: remote processor ff9a0100.zynqmp_r5_rproc is now up [ 177.442121] virtio_rpmsg_bus virtio0: creating channel rpmsg-openamp-demo-channel addr 0x1 root@plnx_aarch64:~# echo_test Echo test start Open rpmsg dev! |
When running with RPU in split mode and only one RPU is an OpenAMP slave, the second RPU can still run another non-openamp application.
Firmware:
Device Tree:
/ { reserved-memory { #address-cells = <2>; #size-cells = <2>; ranges; rpu0vdev0vring0: rpu0vdev0vring0@3ed40000 { no-map; reg = <0x0 0x3ed40000 0x0 0x4000>; }; rpu0vdev0vring1: rpu0vdev0vring1@3ed44000 { no-map; reg = <0x0 0x3ed44000 0x0 0x4000>; }; rpu0vdev0buffer: rpu0vdev0buffer@3ed48000 { no-map; reg = <0x0 0x3ed48000 0x0 0x100000>; }; rproc_0_reserved: rproc@3ed00000 { no-map; reg = <0x0 0x3ed00000 0x0 0x40000>; }; }; zynqmp-rpu { compatible = "xlnx,zynqmp-r5-remoteproc-1.0"; #address-cells = <2>; #size-cells = <2>; ranges; core_conf = "split"; reg = <0x0 0xFF9A0000 0x0 0x10000>; r5_0: r5@0 { #address-cells = <2>; #size-cells = <2>; ranges; memory-region = <&rproc_0_reserved>, <&rpu0vdev0buffer>, <&rpu0vdev0vring0>, <&rpu0vdev0vring1>; pnode-id = <0x7>; mboxes = <&ipi_mailbox_rpu0 0>, <&ipi_mailbox_rpu0 1>; mbox-names = "tx", "rx"; tcm_0_a: tcm_0@0 { reg = <0x0 0xFFE00000 0x0 0x10000>; pnode-id = <0xf>; }; tcm_0_b: tcm_0@1 { reg = <0x0 0xFFE20000 0x0 0x10000>; pnode-id = <0x10>; }; }; /* if instead for RPU1 use the following: r5_1: r5@1 { #address-cells = <2>; #size-cells = <2>; ranges; memory-region = <&rproc_0_fw_reserved>, <&rproc_0_dma_reserved>; pnode-id = <0x8>; mboxes = <&ipi_mailbox_rpu0 0>, <&ipi_mailbox_rpu0 1>; mbox-names = "tx", "rx"; tcm_a: tcm@0 { reg = <0x0 0xFFE90000 0x0 0x10000>; pnode-id = <0x11>; }; tcm_b: tcm@1 { reg = <0x0 0xFFEb0000 0x0 0x10000>; pnode-id = <0x12>; }; }; */ }; zynqmp_ipi1 { compatible = "xlnx,zynqmp-ipi-mailbox"; interrupt-parent = <&gic>; interrupts = <0 29 4>; xlnx,ipi-id = <7>; #address-cells = <1>; #size-cells = <1>; ranges; /* APU<->RPU0 IPI mailbox controller */ ipi_mailbox_rpu0: mailbox@ff990600 { reg = <0xff990600 0x20>, <0xff990620 0x20>, <0xff9900c0 0x20>, <0xff9900e0 0x20>; reg-names = "local_request_region", "local_response_region", "remote_request_region", "remote_response_region"; #mbox-cells = <1>; xlnx,ipi-id = <1>; }; }; }; |
NOTE: rpu slave applications right are only supported by default to run in TCM. What this means in practice is that for RPU to load and start other RPU, the entirety of the slave application must be loaded and run in TCM. APU remoteproc slave does support running application in DDR.
set (CMAKE_SYSTEM_PROCESSOR "arm" CACHE STRING "") set (MACHINE "zynqmp_r5" CACHE STRING "") set (CROSS_PREFIX "armr5-none-eabi-" CACHE STRING "") set (CMAKE_C_FLAGS "-mfloat-abi=hard -mcpu=cortex-r5 -mfpu=vfpv3-d16 -Wall -Werror -Wextra \ -flto -Os -I<path to bsp>/bsp/psu_cortexr5_0/include" CACHE STRING "") link_directories( <path to bsp>/bsp/psu_cortexr5_0/lib ) set (PLATFORM_LIB_DEPS " -lxil -lxilstandalone -lc -lm -lxilpm " CACHE STRING "") SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -flto") SET(CMAKE_AR "gcc-ar" CACHE STRING "") SET(CMAKE_C_ARCHIVE_CREATE "<CMAKE_AR> qcs <TARGET> <LINK_FLAGS> <OBJECTS>") SET(CMAKE_C_ARCHIVE_FINISH true) include (cross-generic-gcc) |
script to build libmetal
git clone https://github.com/OpenAMP/libmetal.git cd libmetal mkdir build_r5 cd build_r5 cmake .. -DCMAKE_TOOLCHAIN_FILE=<toolchain_file> \ -DCMAKE_LIBRARY_PATH=<path to bsp>/bsp/psu_cortexr5_0/lib make DESTDIR=. install VERBOSE=1 |
build openamp for r5 standalone
toolchain file for openamp
set (CMAKE_SYSTEM_PROCESSOR "arm" CACHE STRING "") set (MACHINE zynqmp_r5 ) set (CROSS_PREFIX "armr5-none-eabi-" CACHE STRING "") set (CMAKE_C_FLAGS "-mfloat-abi=hard -mcpu=cortex-r5 -Os -flto -mfpu=vfpv3-d16 -DUNDEFINE_FILE_OPS \ -I<path to libmetal repo>/libmetal/build_r5/usr/local/include \ -I<bsp path>/bsp/psu_cortexr5_0/include" CACHE STRING "") set (CMAKE_ASM_FLAGS " -mcpu=cortex-r5 " CACHE STRING "") set (PLATFORM_LIB_DEPS " -lxil -lxilstandalone -lxilpm -lxilmem -lc -lm" CACHE STRING "") SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -flto ") SET(CMAKE_AR "gcc-ar" CACHE STRING "") SET(CMAKE_C_ARCHIVE_CREATE "<CMAKE_AR> qcs <TARGET> <LINK_FLAGS> <OBJECTS>") SET(CMAKE_C_ARCHIVE_FINISH true) link_directories( <path to libmetal repo>/libmetal/build_r5/usr/local/include/ <path to libmetal repo>/libmetal/build_r5/usr/local/lib/ ) set (WITH_LOAD_FW ON) set (CMAKE_FIND_ROOT_PATH <path to libmetal repo>/libmetal/build/usr/local/lib <bsp path>/bsp/psu_cortexr5_0/lib ) include (cross_generic_gcc) string (TOLOWER "FreeRTOS" PROJECT_SYSTEM) string (TOUPPER "FreeRTOS" PROJECT_SYSTEM_UPPER) # vim: expandtab:ts=2:sw=2:smartindent |
srcipt using toolchain file for openamp
git clone https://github.com/OpenAMP/open-amp.git cd open-amp mkdir build cd build cmake .. \ -DCMAKE_TOOLCHAIN_FILE=toolchain \ -DCMAKE_INCLUDE_PATH="<path to libmetal repo>/libmetal/build_r5/lib/include/;<path to bsp>/bsp/psu_cortexr5_0/include/" \ -DCMAKE_LIBRARY_PATH="<path to libmetal repo>/libmetal/build_r5/usr/local/lib/<path to bsp>/bsp/psu_cortexr5_0/lib/" -DWITH_APPS=on -DWITH_LOAD_FW=ON make DESTDIR=$(pwd) install VERBOSE=1 |
start r5 0
ta 6 # set r5 to split mwr 0xFF9A0000 0x08 # reset tcm ta 7 rst -processor mwr 0xFFE00000 0 10000 after 1000 mwr 0xFFE20000 0 10000 after 1000 # load apu dow -data <a53 app> 0x3ed00000 # load rpu ta 6 dow load_fw.out # start rpu con |
Download 2020.1 Versal BSP
$ petalinux-boot --jtag --prebuilt 3 |
After starting firmware on target the output from running Linux-side the output is as follows:
$ echo_test -d <rpmsg channel name> Echo test start Open rpmsg dev /dev/rpmsg0! ************************************** |
Below is example to have RPU with OpenAMP boot up Linux on Versal platform
Generate linux_boot.elf with .S file and script below
/* * Drops EL from 3 down to 2 and sets up the CPU for AArch64 execution. * * The kernel start address and DTB location can easily be patched at runtime * before jumping to this code-snippet if needed. * To for example build and link to 0xfffc8000: * aarch64-none-elf-gcc -nostartfiles -nodefaultlibs -Wl,--build-id=none,-Ttext=0xfffc8000 linux-boot.s -o linux-boot * */ .section .text .global _start _start: ldr x17, kernel_start ldr x0, kernel_dts mov x1, xzr mov x2, xzr mov x3, xzr blr x17 .balign 8 kernel_start: .dword 0x00080000 kernel_dts: .dword 0x1000 |
generate linux_boot.elf with the following script
#!/bin/bash aarch64-none-elf-gcc -nostartfiles -nodefaultlibs -Wl,--build-id=none,-Ttext=8000000 linux_boot.s -o linux_boot.elf |
new_bif: { id_code = 0x04ca8093 extended_id_code = 0x01 id = 0x2 image { name = pmc_subsys, id = 0x1c000001 {type = bootloader, file = plm.elf} {type = pmcdata, load = 0xf2000000, file = pmc_data.cdo} } image { name = ss_psm, id = 0x4210002 {type = cdo,file = lpd_data.cdo} {core = psm, file = psm.elf} } image { name = pl_cfi, id = 0x1c000009 {type = cdo, file = project_1.rcdo} {type = cdo, file = project_1.rnpi} } image { name = fpd, id = 0x420c003 {type = cdo, file = fpd_data.cdo} } image { name = subsystem, id = 0x1c000000 {type = cdo, file = subsystem.cdo} { file = linux_boot.elf } { load = 0x1000, file = images/linux/system.dtb } { load = 0x80000, file = images/linux/Image } } } |
$ bootgen -arch versal -padimageheader=0 -log trace -w -o BOOT.BIN -image <bif> |
Generate RPU openamp application to load ATF and boot linux
libmetal
Create R5-0 standalone BSP for versal with PM library enabled and builtbelow is sample xsct script to do so. The hw design/ xsa can be found ina versal vck190 petalinux project
setws . platform create -name rpumaster -hw <plnx project vck190 xsa> platform active rpumaster domain create -name rpu0-master-domain -os standalone -proc psv_cortexr5_0 bsp setlib -name xilpm bsp getlibs platform generate |
Build libmetal for R5 standalone using below toolchain file and steps
set (CMAKE_SYSTEM_PROCESSOR "arm" CACHE STRING "") set (MACHINE "zynqmp_r5" CACHE STRING "") set (CROSS_PREFIX "armr5-none-eabi-" CACHE STRING "") set (CMAKE_C_FLAGS "-mfloat-abi=hard -mcpu=cortex-r5 -mfpu=vfpv3-d16 -Wall -Werror -Wextra \ -flto -Os -I<path to bsp>/bsp/psv_cortexr5_0/include" CACHE STRING "") link_directories( <path to bsp>/bsp/psv_cortexr5_0/lib ) set (PLATFORM_LIB_DEPS " -lxil -lxilstandalone -lc -lm -lxilpm " CACHE STRING "") SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -flto") SET(CMAKE_AR "gcc-ar" CACHE STRING "") SET(CMAKE_C_ARCHIVE_CREATE "<CMAKE_AR> qcs <TARGET> <LINK_FLAGS> <OBJECTS>") SET(CMAKE_C_ARCHIVE_FINISH true) include (cross-generic-gcc) |
clone libmetal repo and build in directory like so:
git clone https://github.com/OpenAMP/libmetal.git cd libmetal mkdir build_r5 cd build_r5 cmake .. -DCMAKE_TOOLCHAIN_FILE=<toolchain_file> \ -DCMAKE_LIBRARY_PATH=<path to bsp>/bsp/psv_cortexr5_0/lib make DESTDIR=. install VERBOSE=1 |
build openamp demos with sample toolchain file
set (CMAKE_SYSTEM_PROCESSOR "arm" CACHE STRING "") set (MACHINE zynqmp_r5 ) set (CROSS_PREFIX "armr5-none-eabi-" CACHE STRING "") set (CMAKE_C_FLAGS "-mfloat-abi=hard -mcpu=cortex-r5 -Os -flto -mfpu=vfpv3-d16 -DUNDEFINE_FILE_OPS \ -I<path to libmetal repo>/libmetal/build_r5/usr/local/include \ -I<bsp path>/bsp/psv_cortexr5_0/include" CACHE STRING "") set (CMAKE_ASM_FLAGS " -mcpu=cortex-r5 " CACHE STRING "") set (PLATFORM_LIB_DEPS " -lxil -lxilstandalone -lxilpm -lxilmem -lc -lm" CACHE STRING "") SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -flto ") SET(CMAKE_AR "gcc-ar" CACHE STRING "") SET(CMAKE_C_ARCHIVE_CREATE "<CMAKE_AR> qcs <TARGET> <LINK_FLAGS> <OBJECTS>") SET(CMAKE_C_ARCHIVE_FINISH true) link_directories( <path to libmetal repo>/libmetal/build_r5/usr/local/include/ <path to libmetal repo>/libmetal/build_r5/usr/local/lib/ ) set (WITH_LOAD_FW ON) set (CMAKE_FIND_ROOT_PATH <path to libmetal repo>/libmetal/build/usr/local/lib <bsp path>/bsp/psv_cortexr5_0/lib ) include (cross_generic_gcc) string (TOLOWER "FreeRTOS" PROJECT_SYSTEM) string (TOUPPER "FreeRTOS" PROJECT_SYSTEM_UPPER) add_definitions(-DLOAD_FW_TARGET=NODE_APU_0) # vim: expandtab:ts=2:sw=2:smartindent |
how to build:
git clone https://github.com/OpenAMP/open-amp.git cd open-amp mkdir build cd build cmake .. \ -DCMAKE_TOOLCHAIN_FILE=toolchain \ -DCMAKE_INCLUDE_PATH="<path to libmetal repo>/libmetal/build_r5/lib/include/;<path to bsp>/bsp/psu_cortexr5_0/include/" \ -DCMAKE_LIBRARY_PATH="<path to libmetal repo>/libmetal/build_r5/usr/local/lib/<path to bsp>/bsp/psu_cortexr5_0/lib/" -DWITH_APPS=on -DWITH_LOAD_FW=ON make DESTDIR=$(pwd) install VERBOSE=1 |
petalinux-build -c arm-trusted-firmware vi build/conf/local.conf ## apend the following to local.conf ATF_MEM_BASE="0xfffc0000" ATF_MEM_SIZE="0x20000" ## # rebuild atf with new base addr petalinux-build -c arm-trusted-firmware |
xsdb device program <generated boot.bin from earlier> # download using boot.bin ta 2 # select RPU mwr 0xFF9A0000 0x08 # set rpu to split # clear tcm banks. This is needed as rpu application is loaded into tcm. mwr -force 0xFFE00000 0 20000 mwr -force 0xFFE20000 0 20000 # load ATF into memory application that openamp load_fw application is expecting dow -f -data <ATF from petalinux project> 0x3ed00000 # reset rpu 0 ta 3 rst -proc # download and run rpu application dow <load_fw app> con |
console
Xilinx Versal Platform Loader and Manager Release 2019.2 Oct 10 2019 - 02:25:47 Silicon: v0, PMC: v1.0, PS: v1.0 STDOUT: PS UART **************************************** [19.720003 ms.] PLM Initialization Time ***********Boot PDI Load: Started*********** Loading PDI from JTAG Monolithic/Master Device +++++++Loading Image No: 0x1, Name: psmfw.elf, Id: 0x1C000000 +++++++Loading Prtn No: 0x1 0.687106 ms. for PrtnNum: 1, Size: 48 Bytes +++++++Loading Prtn No: 0x2 14.326318 ms. for PrtnNum: 2, Size: 28336 Bytes +++++++Loading Prtn No: 0x3 0.009337 ms. for PrtnNum: 3, Size: 2224 Bytes PSM Firmware version: 2018.1 [Build: Oct 10 2019 02:24:59 ] 41.570971 ms.for Image: 1 +++++++Loading Image No: 0x2, Name: tenzing_se1., Id: 0x1C000000 +++++++Loading Prtn No: 0x4 0.004256 ms. for PrtnNum: 4, Size: 32 Bytes 12.152443 ms.for Image: 2 +++++++Loading Image No: 0x3, Name: tenzing_se1., Id: 0x1C000000 +++++++Loading Prtn No: 0x5 XPlmi_MaskPoll: Addr: 0xF12B0000, Mask: 0x4, ExpVal: 0x0, Timeout: 1000000 ...ERROR 11989.724343 ms. for PrtnNum: 5, Size: 707584 Bytes 12002.600528 ms.for Image: 3 +++++++Loading Image No: 0x4, Name: tenzing_se1., Id: 0x1C000000 +++++++Loading Prtn No: 0x6 200.541612 ms. for PrtnNum: 6, Size: 274624 Bytes 210.389731 ms.for Image: 4 +++++++Loading Image No: 0x5, Name: ps_data.cdo, Id: 0x1C000000 +++++++Loading Prtn No: 0x7 0.147315 ms. for PrtnNum: 7, Size: 1024 Bytes 12.247290 ms.for Image: 5 +++++++Loading Image No: 0x6, Name: subsystem.cd, Id: 0x1C000000 +++++++Loading Prtn No: 0x8 0.142906 ms. for PrtnNum: 8, Size: 336 Bytes 12.250128 ms.for Image: 6 +++++++Loading Image No: 0x7, Name: out.dtb, Id: 0x1C000000 +++++++Loading Prtn No: 0x9 19.101556 ms. for PrtnNum: 9, Size: 28096 Bytes 28.340815 ms.for Image: 7 +++++++Loading Image No: 0x8, Name: out.dtb, Id: 0x1C000000 +++++++Loading Prtn No: 0xA 15.924825 ms. for PrtnNum: 10, Size: 28096 Bytes 25.253390 ms.for Image: 8 +++++++Loading Image No: 0x9, Name: Image, Id: 0x1C000000 +++++++Loading Prtn No: 0xB 43787.185934 ms. for PrtnNum: 11, Size: 80156688 Bytes 43796.878234 ms.for Image: 9 +++++++Loading Image No: 0xA, Name: linux_boot.e, Id: 0x1C000000 +++++++Loading Prtn No: 0xC 0.002946 ms. for PrtnNum: 12, Size: 48 Bytes 12.264296 ms.for Image: 10 ***********Boot PDI Load: Done************* 7756.737153 ms.: ROM Time [56216.499743 ms.] Total PLM Boot Time Loading Exectuable Demo metal: debug: registered generic bus RPU0: Running in split mode apu_rproc_init: node id: 403750915 Start to load executable with remoteproc_load() metal: debug: remoteproc_load: check remoteproc status metal: debug: remoteproc_load: open executable image metal: debug: remoteproc_load: check loader metal: debug: remoteproc_load: loading headers metal: debug: Loading ELF headering metal: debug: Loading ELF program header. metal: debug: Loading ELF section header. metal: debug: remoteproc_load, load header 0x0, 0x100, next 0x8ca30, 0x540 mem_image_load: offset=0x8CA30, size=0x540 metal: debug: Loading ELF section header. metal: debug: Loading ELF section header complete. metal: debug: Loading ELF shstrtab. metal: debug: remoteproc_load, load header 0x8ca30, 0x540, next 0x8c958, 0xd6 mem_image_load: offset=0x8C958, size=0xD6 metal: debug: Loading ELF shstrtab. metal: debug: remoteproc_load, load header 0x8c958, 0xd6, next 0x8c958, 0x0 metal: debug: remoteproc_load: load executable data metal: debug: segment: 1, total segs 2 metal: debug: load data: da 0xfffc0000, offset 0x10000, len = 0xd7b0, memsize = 0x15000, state 0x10801 apu_rproc_mmap: pa=0xFFFFFFFF, da=0xFFFC0000, size=0x15000, atrribute=0x0 RPU0: XPm_RequestNode(18314007, 1, 0, 1, 0) RPU0: XPm_RequestNode(18314008, 1, 0, 1, 0) mem_image_load: offset=0x10000, size=0xD7B0 metal: debug: cannot find more segment metal: debug: load data: da 0x0, offset 0x0, len = 0x0, memsize = 0x0, state 0x10802 apu_rproc_mmap: pa=0xFFFFFFFF, da=0x0, size=0x0, atrribute=0x0 RPU0: XPm_RequestNode(18320010, 1, 0, 1, 0) metal: debug: cannot find more segment metal: debug: load data: da 0xffffffff, offset 0x0, len = 0x0, memsize = 0x0, state 0x10802 metal: debug: remoteproc_load: successfully load firmware RPU0: XPm_RequestWakeUp(1810C003, FFFC0001, 0, 1, 0) successfully started the processor NOTICE: ATF running on Xilinx Versal Silicon NOTICE: BL31: Secure code at 0x60000000 NOTICE: BL31: Non secure code at 0x8000000 NOTICE: BL31: v2.0(debug):v2.0-813-g68ec008f3fde NOTICE: BL31: Built : 10:20:28, May 8 2019 INFO: GICv3 with legacy support detected. ARM GICV3 driver initialized in EL3 INFO: BL31: Initializing runtime services WARNING: BL31: cortex_a72: CPU workaround for 859971 was missing! INFO: BL31: cortex_a72: CPU workaround for cve_2017_5715 was applied INFO: BL31: cortex_a72: CPU workaround for cve_2018_3639 was applied INFO: BL31: Preparing for EL3 exit to normal world INFO: Entry point address = 0x8000000 INFO: SPSR = 0x3c9 [ 0.000000] Booting Linux on physical CPU 0x0000000000 [0x410fd083] [ 0.000000] Linux version 4.19.0-xilinx-v2019.2 (oe-user@oe-host) (gcc version 8.2.0 (GCC)) #1 SMP Thu Oct 10 02:21:01 UTC 2019 [ 0.000000] Machine model: Xilinx Versal vck190 Eval board revA [ 0.000000] earlycon: pl11 at MMIO32 0x00000000ff000000 (options '115200n8') [ 0.000000] bootconsole [pl11] enabled [ 0.000000] cma: Reserved 256 MiB at 0x0000000070000000 [ 0.000000] psci: probing for conduit method from DT. [ 0.000000] psci: PSCIv1.1 detected in firmware. |
Module Name | Change | Link |
Xen Dom0 and DomU support for OpenAMP running in RPMsg userspace on Versal | support for these two configurations in 2020.1 | |
RPU as Lifecycle master |