Renesas R-Car Gen5 X5H Ironhide board
Renesas R-Car Gen5 X5H Ironhide board U-Boot can be built for two separate cores:
Cortex-M33 RSIP core, which is the boot core
Cortex-A720AE core, which is the application core
Cortex-A720AE target
Build U-Boot
Please follow Renesas 64-bit ARM SoC build environment setup to correctly set up the build environment before attempting to build U-Boot.
Clone up to date U-Boot source code and change directory into the newly cloned source directory:
$ git clone https://source.denx.de/u-boot/u-boot.git/
$ cd u-boot
Configure U-Boot:
$ make r8a78000_ironhide_defconfig
Compile U-Boot:
$ make
To speed up build process, -jN option can be passed to make to start multiple jobs at the same time, this is beneficial especially on SMP systems. The following example starts up to number of CPUs in the system jobs, which is the recommended amount:
$ make -j$(nproc)
Install U-Boot
In order to install U-Boot for Cortex-A720AE into UFS, first build U-Boot
for this target and collect u-boot-elf.srec build artifact.
Next, configure the board for SCIF loader boot. Upload IPL flash_writer
mot binary. Use the tool to write u-boot-elf.srec into HyperFlash
at offset 0x8e300000 . Finally, power off the board and configure the
board back to HyperFlash boot mode.
Cortex-M33 RSIP target
Build U-Boot
Please follow Renesas 32-bit ARM SoC build environment setup to correctly set up the build environment before attempting to build U-Boot.
Clone up to date U-Boot source code and change directory into the newly cloned source directory:
$ git clone https://source.denx.de/u-boot/u-boot.git/
$ cd u-boot
Configure U-Boot:
$ make r8a78000_ironhide_cm33_defconfig
Compile U-Boot:
$ make
To speed up build process, -jN option can be passed to make to start multiple jobs at the same time, this is beneficial especially on SMP systems. The following example starts up to number of CPUs in the system jobs, which is the recommended amount:
$ make -j$(nproc)
Install U-Boot
In order to install U-Boot for RSIP into HyperFlash, first build U-Boot
for this target and collect u-boot-elf.shdr and u-boot-elf.srec
build artifacts.
Next, configure the board for SCIF loader boot. Upload IPL flash_writer
mot binary. Use the tool to write u-boot-elf.shdr into HyperFlash
at offset 0, and u-boot-elf.srec into HyperFlash at offset 0x40000 .
Finally, power off the board and configure the board back to HyperFlash
boot mode.
Power on the board, U-Boot on RSIP will start. Interaction with U-Boot on RSIP is possible via HSCIF1, which is the second serial console that is available on the USB-to-Serial adapter port. HSCIF1 is used in order to avoid interference with software running on the Cortex-A720AE cores, which uses HSCIF0.
Ethernet boot of bootloader components
The U-Boot for RSIP is capable of ethernet access, which allows download of bootloader components via TFTP. This is useful during development and can be used for fast iterative testing of either SCP firmware, TFA BL31, OPTEE-OS, U-Boot or Linux on the SCP core and Cortex-A720AE cores respectively.
An example U-Boot environment applicable to include/configs/rcar-gen5-common.h
or executable manually is listed below. The environment script rsip_ipl_boot_ca0
implements download of SCP firmware scp.bin, TFA BL31 bl31.bin,
U-Boot u-boot.bin and Linux fitImage from TFTP server at address
192.168.1.1/24 and starts those components on the SCP and Cortex-A720AE
cores respectively. OPTEE-OS is loaded from UFS to retain at least this
example of UFS loading, however, it perfectly fine to download OPTEE-OS
via TFTP in the same manner as the other components are downloaded:
rsip_ipl_params_base=0x8c100000
rsip_ipl_params_optee=0x8c100088
rsip_ipl_params_uboot=0x8c100030
rsip_ipl_scp_ep=0x8c180000
rsip_ipl_optee_ep=0x8c400000
rsip_ipl_tfa_ep=0x8c200000
rsip_ipl_uboot_ep=0x8e300000
rsip_ipl_linux_ep=0x91000000
rsip_ipl_params_write= /* Build handoff structure */ \
base ${rsip_ipl_params_base} ; \
mw 0x00 0 0x9e ; /* Clear the area */ \
mw 0x00 0x00300103 ; /* type, version, size */ \
mw 0x20 0x${rsip_ipl_params_uboot} ; /* U-Boot descriptor */ \
\
base ${rsip_ipl_params_uboot} ; \
mw 0x00 0x00580101 ; /* type, version, size */ \
mw 0x04 0x00000001 ; /* attr */ \
mw 0x08 ${rsip_ipl_uboot_ep} ; /* U-Boot entry point */ \
mw 0x10 0x000003c5 ; /* SPSR */ \
\
base ${rsip_ipl_params_optee} ; \
mw 0x00 0x00580201 ; /* type, version, size */ \
mw 0x04 0x00000008 ; /* attr */ \
mw 0x08 ${rsip_ipl_optee_ep} ; /* OPTEE-OS entry point */ \
mw 0x10 0x000003c5 ; /* SPSR */ \
\
base 0
rsip_ipl_boot_ca0= /* Start TFA BL31, OPTEE-OS, U-Boot, Linux on Cortex-A720AE core 0 */ \
env set ipaddr 192.168.1.10 && \
env set serverip 192.168.1.1 && \
env set netmask 255.255.255.0 && \
\
tftp ${rsip_ipl_scp_ep} scp.bin && \
tftp ${rsip_ipl_tfa_ep} bl31.bin && \
tftp ${rsip_ipl_uboot_ep} u-boot.bin && \
tftp ${rsip_ipl_linux_ep} fitImage && \
\
scsi scan && /* Scan for UFS devices */ \
rproc init && /* Start remoteproc */ \
rproc load 0 ${rsip_ipl_scp_ep} 0x60000 && /* Load SCP STCM */ \
rproc start 0 && /* Start SCP */ \
scsi read ${rsip_ipl_optee_ep} 0x5200 0x200 && /* Load OPTEE-OS from UFS */ \
run rsip_ipl_params_write && /* Write entry point descriptors */ \
\
rproc load 13 ${rsip_ipl_tfa_ep} 4 && /* Set up Cortex-A720AE Core 0 */ \
rproc start 13 /* Start Cortex-A720AE Core 0 */
Note
U-Boot on RSIP environment is not persistent across reboots, but this will likely change in the upcoming U-Boot release.
Note
U-Boot on RSIP can start the SCP core via rproc command, but it can not stop SCP after it was started. This was intended as a safety mechanism, since SCP is central component of the system, however, this will likely change in the upcoming U-Boot release.
Note
U-Boot on RSIP can start non-SCP cores via rproc command only
after the SCP got started, because those cores are started via
SCMI calls to the SCP.
Cortex-R52 core start
The U-Boot for RSIP remoteproc implementation is capable of starting the SCP core, and using the SCP it is capable of starting additional CPU cores in the SoC, Cortex-R52 and Cortex-A720AE. This subchapter demonstrates how to start example code on Cortex-R52 cores using the U-Boot on RSIP remoteproc and SCP.
The piece of position independent assembler code below can be compiled for the Cortex-R52 core, can be started from any 4-Byte aligned address and prints CPU core program counter (PC) address and MPIDR onto HSCIF1. The MPIDR register encodes CPU cluster and core position and is useful when identifying on which specific CPU core does the code execute. The program counter (PC) can be used to determine from which address did the code running on the Cortex-R52 core start executing.
#define HSTDR 0xc
#define HSFSR 0x10
#define TEND 0x40
.macro mprintchr, chr, rt
mov \rt, \chr
bl printchr
.endm
.macro mprintnl, rt
mprintchr #'\r', \rt
mprintchr #'\n', \rt
.endm
start:
# Set up HSCIF1 output
mov r0, #0xc0000000
orr r0, r0, #0x00710000
orr r0, r0, #0x00004000
# Print newline
mprintnl r1
# Print PC:
mprintchr #'P', r1
mprintchr #'C', r1
mprintchr #':', r1
mprintchr #' ', r1
bl printchr
bl printchr
bl printchr
mprintchr #'0', r1
mprintchr #'x', r1
# Figure out start address and print it
adr r2, start
bl printhex
# Print newline
mprintnl r1
# Print MPIDR:
mprintchr #'M', r1
mprintchr #'P', r1
mprintchr #'I', r1
mprintchr #'D', r1
mprintchr #'R', r1
mprintchr #':', r1
mprintchr #' ', r1
mprintchr #'0', r1
mprintchr #'x', r1
# Read MPIDR
mrc p15, 0, r2, c0, c0, 5
bl printhex
# Print newline
mprintnl r1
# Halt and do nothing
3: wfi
b 3b
# Print char byte of register r1 (clobber: r9)
printchr:
2: ldrh r9, [r0, #HSFSR]
tst r9, #TEND
beq 2b
strb r1, [r0, #HSTDR]
ldrh r9, [r0, #HSFSR]
bic r9, #TEND
strh r9, [r0, #HSFSR]
bx lr
# Print hex content of register r2 (clobber: r6, r7, r8, r9)
printhex:
mov r8, #8
1: and r1, r2, #0xf0000000
lsl r2, r2, #4
lsr r1, r1, #28
add r1, r1, #'0'
cmp r1, #'9'
# >= '9' => add 'a' - ':'
addgt r1, r1, #('a' - ':')
mov r6, lr
bl printchr
mov lr, r6
sub r8, r8, #1
cmp r8, #0
bne 1b
bx lr
Compile the piece of position independent assembler code above for the Cortex-R52 core as follows:
$ cpp code.s > temp.S
$ arm-linux-gnueabi-as -march=armv8-r -o temp.o temp.S
$ arm-linux-gnueabi-objcopy -O binary temp.o output.bin
Load the piece of compiled assembler code into memory, and start the code on the Cortex-R52 cluster 0 core 0 as follows:
Important
It is mandatory for the SCP core to be started before the following
procedure can be performed, because the Cortex-R52 core is started
by the SCP. The SCP is usually started by the default boot command
of the U-Boot on RSIP, which contains rproc start 0 invocation to
start the SCP core.
Note
The example below does use ethernet loading of the Cortex-R52 firmware, however, it is perfectly fine to load the firmware from either HyperFlash, UFS, or other storage media.
Note
The example below does use load address 0x86000000 for the Cortex-R52 firmware. This address is located in DRAM and is only ever used as a temporary load buffer. The firmware is copied into the RT-VRAM which is accessible from the RSIP at remapped address 0xb0200000 and from the Cortex-R52 at address 0x10200000, which is also the address from which the firmware executes on Cortex-R52.
# Configure ethernet address, adjust as needed:
=> env set ipaddr 192.168.1.10
=> env set serverip 192.168.1.1
=> env set netmask 255.255.255.0
# Load Cortex-R52 firmware into DRAM at address 0x86000000
=> tftp 0x86000000 output.bin
# Copy Cortex-R52 firmware into RT-VRAM
=> cp.b 0x86000000 0xb0200000 ${filesize}
# Configure Cortex-R52 cluster 0 core 0 entry point
=> rproc load 1 0x10200000 ${filesize}
# Start Cortex-R52 cluster 0 core 0
=> rproc start 1
The expected output of rproc start 1 a print of both MPIDR and PC register
values on HSCIF1.
Load Remote Processor 1 with data@addr=0x10200000 304 bytes: Success!
PC: 0x10200000
MPIDR: 0x80000000
Note
The MPIDR register value above is 0x80000000 . Cortex-R52 MPIDR register bit 31 is always set to 1, bitfields AFF2[23:16], AFF1[15:8], AFF0[7:0] describe core affinity, in this case this is cluster 0, core 0.
Other Cortex-R52 cores in other clusters can be started by passing a
matching core number to both rproc load and rproc start. Example:
=> rproc list
...
1 - Name:'rcar-rsip-cr.0-scp@c1340000' type:'internal memory mapped' supports: load start stop reset is_running
2 - Name:'rcar-rsip-cr.1-scp@c1340000' type:'internal memory mapped' supports: load start stop reset is_running
3 - Name:'rcar-rsip-cr.2-scp@c1340000' type:'internal memory mapped' supports: load start stop reset is_running
4 - Name:'rcar-rsip-cr.3-scp@c1340000' type:'internal memory mapped' supports: load start stop reset is_running
5 - Name:'rcar-rsip-cr.4-scp@c1340000' type:'internal memory mapped' supports: load start stop reset is_running
6 - Name:'rcar-rsip-cr.5-scp@c1340000' type:'internal memory mapped' supports: load start stop reset is_running
7 - Name:'rcar-rsip-cr.6-scp@c1340000' type:'internal memory mapped' supports: load start stop reset is_running
8 - Name:'rcar-rsip-cr.7-scp@c1340000' type:'internal memory mapped' supports: load start stop reset is_running
9 - Name:'rcar-rsip-cr.8-scp@c1340000' type:'internal memory mapped' supports: load start stop reset is_running
10 - Name:'rcar-rsip-cr.9-scp@c1340000' type:'internal memory mapped' supports: load start stop reset is_running
11 - Name:'rcar-rsip-cr.10-scp@c1340000' type:'internal memory mapped' supports: load start stop reset is_running
12 - Name:'rcar-rsip-cr.11-scp@c1340000' type:'internal memory mapped' supports: load start stop reset is_running
...
=> rproc load 10 0x10200000 ${filesize} && rproc start 10
Load Remote Processor 10 with data@addr=0x10200000 304 bytes: Success!
PC: 0x10200000
MPIDR: 0x80000201
Note
The MPIDR register value above is 0x80000201 . Cortex-R52 MPIDR register bit 31 is always set to 1, bitfields AFF2[23:16], AFF1[15:8], AFF0[7:0] describe core affinity, in this case this is cluster 2, core 1.