diff options
author | Sandrine Bailleux <sandrine.bailleux@arm.com> | 2018-10-09 11:12:55 +0200 |
---|---|---|
committer | Sandrine Bailleux <sandrine.bailleux@arm.com> | 2018-10-10 12:34:34 +0200 |
commit | 3cd87d77947ec4fc04440268ed122b4ed81c7781 (patch) | |
tree | 78fdee12b026b931029e434f29b4fe09835fe4c9 /el3_payload |
Trusted Firmware-A Tests, version 2.0
This is the first public version of the tests for the Trusted
Firmware-A project. Please see the documentation provided in the
source tree for more details.
Change-Id: I6f3452046a1351ac94a71b3525c30a4ca8db7867
Signed-off-by: Sandrine Bailleux <sandrine.bailleux@arm.com>
Co-authored-by: amobal01 <amol.balasokamble@arm.com>
Co-authored-by: Antonio Nino Diaz <antonio.ninodiaz@arm.com>
Co-authored-by: Asha R <asha.r@arm.com>
Co-authored-by: Chandni Cherukuri <chandni.cherukuri@arm.com>
Co-authored-by: David Cunado <david.cunado@arm.com>
Co-authored-by: Dimitris Papastamos <dimitris.papastamos@arm.com>
Co-authored-by: Douglas Raillard <douglas.raillard@arm.com>
Co-authored-by: dp-arm <dimitris.papastamos@arm.com>
Co-authored-by: Jeenu Viswambharan <jeenu.viswambharan@arm.com>
Co-authored-by: Jonathan Wright <jonathan.wright@arm.com>
Co-authored-by: Kévin Petit <kevin.petit@arm.com>
Co-authored-by: Roberto Vargas <roberto.vargas@arm.com>
Co-authored-by: Sathees Balya <sathees.balya@arm.com>
Co-authored-by: Shawon Roy <Shawon.Roy@arm.com>
Co-authored-by: Soby Mathew <soby.mathew@arm.com>
Co-authored-by: Thomas Abraham <thomas.abraham@arm.com>
Co-authored-by: Vikram Kanigiri <vikram.kanigiri@arm.com>
Co-authored-by: Yatharth Kochar <yatharth.kochar@arm.com>
Diffstat (limited to 'el3_payload')
-rw-r--r-- | el3_payload/.gitignore | 6 | ||||
-rw-r--r-- | el3_payload/Makefile | 91 | ||||
-rw-r--r-- | el3_payload/README | 141 | ||||
-rw-r--r-- | el3_payload/arch.h | 20 | ||||
-rw-r--r-- | el3_payload/asm_macros.S | 22 | ||||
-rw-r--r-- | el3_payload/el3_payload.ld.S | 28 | ||||
-rw-r--r-- | el3_payload/entrypoint.S | 65 | ||||
-rw-r--r-- | el3_payload/plat/fvp/platform.S | 51 | ||||
-rw-r--r-- | el3_payload/plat/fvp/platform.h | 21 | ||||
-rw-r--r-- | el3_payload/plat/fvp/platform.mk | 8 | ||||
-rw-r--r-- | el3_payload/plat/juno/platform.S | 34 | ||||
-rw-r--r-- | el3_payload/plat/juno/platform.h | 17 | ||||
-rw-r--r-- | el3_payload/plat/juno/platform.mk | 8 | ||||
-rwxr-xr-x | el3_payload/scripts/fvp/run_foundation.sh | 51 | ||||
-rwxr-xr-x | el3_payload/scripts/fvp/run_fvp.sh | 56 | ||||
-rw-r--r-- | el3_payload/scripts/juno/load_el3_payload.ds | 11 | ||||
-rwxr-xr-x | el3_payload/scripts/juno/run_ds5_script.sh | 49 | ||||
-rw-r--r-- | el3_payload/spin.S | 77 | ||||
-rw-r--r-- | el3_payload/uart.S | 56 |
19 files changed, 812 insertions, 0 deletions
diff --git a/el3_payload/.gitignore b/el3_payload/.gitignore new file mode 100644 index 0000000..381e354 --- /dev/null +++ b/el3_payload/.gitignore @@ -0,0 +1,6 @@ +*.o +*~ +*.elf +*.bin +*.ld +*.dump diff --git a/el3_payload/Makefile b/el3_payload/Makefile new file mode 100644 index 0000000..f6e809f --- /dev/null +++ b/el3_payload/Makefile @@ -0,0 +1,91 @@ +# +# Copyright (c) 2018, Arm Limited. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +CROSS_COMPILE := aarch64-linux-gnu- +CC := ${CROSS_COMPILE}gcc +AS := ${CROSS_COMPILE}as +LD := ${CROSS_COMPILE}ld +OC := ${CROSS_COMPILE}objcopy +OD := ${CROSS_COMPILE}objdump + +PLAT ?= fvp + +ASFLAGS := -nostdinc -ffreestanding -Wa,--fatal-warnings -Werror +ASFLAGS += -Iplat/${PLAT}/ -I. + +PLAT_BUILD_DIR := build/${PLAT} +SOURCES := entrypoint.S spin.S uart.S plat/${PLAT}/platform.S +OBJS := $(patsubst %,$(PLAT_BUILD_DIR)/%,$(notdir $(SOURCES:.S=.o))) + +PROGRAM := el3_payload +LINKER_SCRIPT := ${PLAT_BUILD_DIR}/${PROGRAM}.ld +ELF := ${PLAT_BUILD_DIR}/${PROGRAM}.elf +BIN := ${PLAT_BUILD_DIR}/${PROGRAM}.bin +DUMP := ${PLAT_BUILD_DIR}/${PROGRAM}.dump + +include plat/${PLAT}/platform.mk + +all: ${BIN} + +${PLAT_BUILD_DIR}: + mkdir -p $@ + +${PLAT_BUILD_DIR}/%.o: %.S ${PLAT_BUILD_DIR} + @echo " CC $<" + ${CC} ${ASFLAGS} -c $< -o $@ + +# Specific rule for this '.o' file to avoid worrying about +# plat/${PLAT}/platform.S being in a sub-directory... +# TODO: Fix this workaround. +${PLAT_BUILD_DIR}/platform.o: plat/${PLAT}/platform.S ${PLAT_BUILD_DIR} + @echo " CC $<" + ${CC} ${ASFLAGS} -c $< -o $@ + +${PLAT_BUILD_DIR}/%.ld: %.ld.S ${PLAT_BUILD_DIR} + @echo " PP $<" + ${CC} -DDRAM_BASE=${DRAM_BASE} -DDRAM_SIZE=${DRAM_SIZE} -E -P -o $@ $< + +${ELF}: ${LINKER_SCRIPT} ${OBJS} + @echo " LD $<" + ${LD} ${LDFLAGS} ${OBJS} --script ${LINKER_SCRIPT} -o $@ + +${BIN}: ${ELF} + @echo " BIN $@" + ${OC} -O binary $< $@ + +${DUMP}: $(ELF) + @echo " OD $$@" + ${OD} -dx $< > $@ + +dump: ${DUMP} + +clean: + rm -rf ${PLAT_BUILD_DIR} + +distclean: clean + rm -rf build/ + +run: run_${PLAT} + +run_juno: ${ELF} scripts/juno/run_ds5_script.sh scripts/juno/load_el3_payload.ds + scripts/juno/run_ds5_script.sh scripts/juno/load_el3_payload.ds + +run_fvp: scripts/fvp/run_fvp.sh + scripts/fvp/run_fvp.sh + +help: + @echo "EL3 test payload" + @echo + @echo "To build:" + @echo "make [PLAT=fvp|juno] [TARGETS]" + @echo "" + @echo "The default platform is fvp." + @echo + @echo "TARGETS:" + @echo " all Build the payload [default target]" + @echo " dump Generate a dump file of the program" + @echo " run Run the payload on the given platform." + @echo " /!\ For Juno, requires a connection to a Juno board via DSTREAM" diff --git a/el3_payload/README b/el3_payload/README new file mode 100644 index 0000000..fcb3ae1 --- /dev/null +++ b/el3_payload/README @@ -0,0 +1,141 @@ +EL3 test payload +================ + +This program is a very simple EL3 baremetal application. It has been developed +to test the ability of the Trusted Firmware-A to load an EL3 payload. All it +does is making sure that all CPUs enter this image and if so, reports it through +the UART. + + +Building +-------- + +$ make PLAT=juno +or +$ make PLAT=fvp + + +Preparing Juno board configuration files +---------------------------------------- + +You should have the following line in your 'SITE1/HBI0262X/board.txt' Juno +configuration file on the SD card (where X depends on the revision of your Juno +board): + + SCC: 0x0F4 0x000003F8 + +This: + - ensures all CPUs are powered on at reset; + - designates the Cortex-A53 #0 as the primary CPU. + +See the 'Assumptions' section below' for more details. + + +Running on Juno +--------------- + +The Trusted Firmware-A must be compiled with SPIN_ON_BL1_EXIT=1. This will +introduce an infinite loop in BL1 that gives you some time to load and run the +EL3 payload over JTAG. + +Boot the board and wait until you see the following messages on the UART. +(Note that the "INFO" messages appear only in a debug build of the Trusted +Firmware but you should see the "NOTICE" messages in any case.) + + NOTICE: BL1: Booting BL31 + INFO: BL1: BL31 address = 0x80000000 + INFO: BL1: BL31 spsr = 0x3cd + INFO: BL1: BL31 params address = 0x0 + INFO: BL1: BL31 plat params address = 0xf1e2d3c4b5a6978 + INFO: BL1: BL31 address = 0x80000000 + INFO: BL1: BL31 spsr = 0x3cd + INFO: BL1: BL31 params address = 0x0 + INFO: BL1: BL31 plat params address = 0xf1e2d3c4b5a6978 + NOTICE: BL1: Debug loop, spinning forever + NOTICE: BL1: Please connect the debugger to jump over it + +TODO: Update the above messages. + +At this point, type the following command in a shell from the EL3 test payload +top directory: + +$ make PLAT=juno run + +You should see something like this in your shell (it takes a few seconds): + + Trying to detect your DSTREAM unit... + Available connections: + USB:000765 + Connecting to USB:000765... + Connected to running target Cortex-A53_0 + Execution stopped in EL3h mode at EL3:0x000000000BEC2548 + EL3:0x000000000BEC2548 B {pc} ; 0xbec2548 + Loaded section ro: EL3:0x0000000080000000 ~ EL3:0x0000000080000123 (size 0x124) + Loaded section .data: EL3:0x0000000080000128 ~ EL3:0x0000000080000197 (size 0x70) + Entry point EL3:0x0000000080000000 + Disconnected from running target Cortex-A53_0 + +And on the Juno UART, this should print the following messages: + + Booting the EL3 test payload + All CPUs booted! + + +Running on FVP (AEMv8A) +----------------------- + +First, copy the "bl1.bin" and "fip.bin" files into the current directory. +Alternatively, symbolic links might be created. + +Then run: + +$ make PLAT=fvp run + +Note: The EL3 payload does not work on the Foundation FVP. +(This is because it expects 8 CPUs and the Foundation FVP has maximum 4.) + + +How does it work? +----------------- + +There is a per-cpu array. Each entry is initialised to a "dead" value. On entry +into the payload, each CPU writes its MPID to its entry, which allows it to +signal its presence. + +Secondary CPUs then spin forever. + +The primary CPU carries on. + 1) It prints a "welcome" string. + 2) It waits for each entry in the CPUs array to be updated. + 3) Once all CPUs have been detected in that way, it prints a success message. + 4) Finally, it spins forever. + + +Assumptions +----------- + +- All CPUs enter the EL3 test payload at some point. + The order doesn't matter, though. + If some CPU doesn't boot then the EL3 payload will wait forever. + +- On FVP, the number of cores is hard-coded to 8. + If the FVP model is configured to disable some CPUs then the EL3 payload will + hang, waiting forever for absent CPUs. + For the same reason, the EL3 payload hangs on the Foundation FVP (which has + 4 CPUs only). + +- The UART is already configured. + +- On Juno, the primary CPU is hard-coded to the Cortex-A53 #0. + Any CPU could be the primary CPU, though. However, the DS-5 scripts launched + by 'make run' assumes the Cortex-A53 #0 is the primary CPU. + + On FVP, the primary CPU is hard-coded to the CPU with MPID 0x0. + + Designating a CPU as the primary one simplifies the code, More particularly, + only the primary CPU accesses the UART, which removes the need for + synchronisation locks to avoid interleaved messages. + +- The EL3 test pyaload runs from RAM. + It can't execute from flash, as we would need to relocate the .data section + in RAM at run-time and this is not implemented for now. diff --git a/el3_payload/arch.h b/el3_payload/arch.h new file mode 100644 index 0000000..a6a480c --- /dev/null +++ b/el3_payload/arch.h @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2018, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __ARCH_H__ +#define __ARCH_H__ + +#define MPIDR_MT_MASK (1 << 24) +#define MPIDR_AFFLVL_MASK 0xff +#define MPIDR_AFFINITY_BITS 8 +#define MPIDR_CPU_MASK MPIDR_AFFLVL_MASK +#define MPIDR_CLUSTER_MASK (MPIDR_AFFLVL_MASK << MPIDR_AFFINITY_BITS) +#define MPIDR_AFF0_SHIFT 0 +#define MPIDR_AFF1_SHIFT 8 +#define MPIDR_AFF2_SHIFT 16 +#define MPIDR_AFFINITY_MASK 0xff00ffffff + +#endif /* __ARCH_H__ */ diff --git a/el3_payload/asm_macros.S b/el3_payload/asm_macros.S new file mode 100644 index 0000000..d02afba --- /dev/null +++ b/el3_payload/asm_macros.S @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2018, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + + /* + * This macro is used to create a function label. + */ + .macro func _name + .type \_name, %function + .func \_name + \_name: + .endm + + /* + * This macro is used to mark the end of a function. + */ + .macro endfunc _name + .endfunc + .size \_name, . - \_name + .endm diff --git a/el3_payload/el3_payload.ld.S b/el3_payload/el3_payload.ld.S new file mode 100644 index 0000000..b1c28dc --- /dev/null +++ b/el3_payload/el3_payload.ld.S @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2018, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +OUTPUT_FORMAT("elf64-littleaarch64") +OUTPUT_ARCH("aarch64") +ENTRY(entrypoint) + +MEMORY { + RAM (rwx): ORIGIN = DRAM_BASE, LENGTH = (DRAM_BASE + DRAM_SIZE) +} + +SECTIONS +{ + . = DRAM_BASE; + + ro . : { + */entrypoint.o(.text) + *(.text*) + *(.rodata*) + } >RAM + + .data : { + *(.data*) + } >RAM +} diff --git a/el3_payload/entrypoint.S b/el3_payload/entrypoint.S new file mode 100644 index 0000000..2da4936 --- /dev/null +++ b/el3_payload/entrypoint.S @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2018, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "arch.h" +#include "asm_macros.S" +#include "platform.h" + +#define EOT_ASCII_CODE 4 + + .data +welcome_str: + .asciz "Booting the EL3 test payload\r\n" +all_cpus_booted_str: + .asciz "All CPUs booted!\r\n" + + .text + .global entrypoint + +func entrypoint + bl mark_cpu_presence + + /* Distinguish primary from secondary CPUs */ + mrs x0, mpidr_el1 + ldr x1, =MPIDR_AFFINITY_MASK + and x0, x0, x1 + + ldr x1, =PRIMARY_CPU_MPID + cmp x0, x1 + b.ne spin_forever + + /* + * Only the primary CPU executes the code below + */ + + adr x0, welcome_str + bl print_string + + /* Wait to see each CPU */ + mov x3, xzr +1: + mov x0, x3 + bl is_cpu_present + cbz x0, 1b + + /* Next CPU, if any */ + add x3, x3, #1 + mov x0, #CPUS_COUNT + cmp x3, x0 + b.lt 1b + + /* All CPUs have been detected, announce the good news! */ + adr x0, all_cpus_booted_str + bl print_string + + /* Send EOT (End of Transmission character) character over the UART */ + mov x0, #EOT_ASCII_CODE + bl print_char + +spin_forever: + wfe + b spin_forever +endfunc entrypoint diff --git a/el3_payload/plat/fvp/platform.S b/el3_payload/plat/fvp/platform.S new file mode 100644 index 0000000..5855ca7 --- /dev/null +++ b/el3_payload/plat/fvp/platform.S @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2018, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "arch.h" +#include "asm_macros.S" +#include "platform.h" + + .text + .global platform_get_core_pos + +/*---------------------------------------------------------------------- + * unsigned int platform_get_core_pos(unsigned long mpid) + * + * Function to calculate the core position on FVP. + * + * (ClusterId * FVP_MAX_CPUS_PER_CLUSTER * FVP_MAX_PE_PER_CPU) + + * (CPUId * FVP_MAX_PE_PER_CPU) + + * ThreadId + * + * which can be simplified as: + * + * ((ClusterId * FVP_MAX_CPUS_PER_CLUSTER + CPUId) * FVP_MAX_PE_PER_CPU) + * + ThreadId + * + * clobbers: x0, x1, x3, x4 + * --------------------------------------------------------------------- + */ +func platform_get_core_pos + /* + * Check for MT bit in MPIDR. If not set, shift MPIDR to left to make it + * look as if in a multi-threaded implementation. + */ + tst x0, #MPIDR_MT_MASK + lsl x3, x0, #MPIDR_AFFINITY_BITS + csel x3, x3, x0, eq + + /* Extract individual affinity fields from MPIDR */ + ubfx x0, x3, #MPIDR_AFF0_SHIFT, #MPIDR_AFFINITY_BITS + ubfx x1, x3, #MPIDR_AFF1_SHIFT, #MPIDR_AFFINITY_BITS + ubfx x4, x3, #MPIDR_AFF2_SHIFT, #MPIDR_AFFINITY_BITS + + /* Compute linear position */ + mov x3, #FVP_MAX_CPUS_PER_CLUSTER + madd x1, x4, x3, x1 + mov x3, #FVP_MAX_PE_PER_CPU + madd x0, x1, x3, x0 + ret +endfunc platform_get_core_pos diff --git a/el3_payload/plat/fvp/platform.h b/el3_payload/plat/fvp/platform.h new file mode 100644 index 0000000..809ae7e --- /dev/null +++ b/el3_payload/plat/fvp/platform.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2018, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __PLATFORM_H__ +#define __PLATFORM_H__ + +#define PRIMARY_CPU_MPID 0x0 + +/* Always expect 8 cores, although this is configurable on FVP */ +#define CPUS_COUNT 8 + +#define UART_BASE 0x1c090000 + +#define FVP_MAX_CPUS_PER_CLUSTER 4 +/* Currently multi-threaded CPUs only have a single thread */ +#define FVP_MAX_PE_PER_CPU 1 + +#endif /* __PLATFORM_H__ */ diff --git a/el3_payload/plat/fvp/platform.mk b/el3_payload/plat/fvp/platform.mk new file mode 100644 index 0000000..b4cda9b --- /dev/null +++ b/el3_payload/plat/fvp/platform.mk @@ -0,0 +1,8 @@ +# +# Copyright (c) 2018, Arm Limited. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +DRAM_BASE := 0x80000000 +DRAM_SIZE := 0x80000000 diff --git a/el3_payload/plat/juno/platform.S b/el3_payload/plat/juno/platform.S new file mode 100644 index 0000000..6c8773b --- /dev/null +++ b/el3_payload/plat/juno/platform.S @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2018, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "arch.h" +#include "asm_macros.S" + + .text + .global platform_get_core_pos + + /* -------------------------------------------------------------------- + * unsigned int get_core_pos(uint64_t mpidr); + * + * Helper function to calculate the core position from its MPID. + * Core positions must be consecutive, there must be no holes. + * + * MPID -> core position: + * 0x100 -> 0 + * 0x101 -> 1 + * 0x102 -> 2 + * 0x103 -> 3 + * 0x0 -> 4 + * 0x1 -> 5 + * -------------------------------------------------------------------- + */ +func platform_get_core_pos + and x1, x0, #MPIDR_CPU_MASK + and x0, x0, #MPIDR_CLUSTER_MASK + eor x0, x0, #(1 << MPIDR_AFFINITY_BITS) /* swap cluster order */ + add x0, x1, x0, LSR #6 + ret +endfunc platform_get_core_pos diff --git a/el3_payload/plat/juno/platform.h b/el3_payload/plat/juno/platform.h new file mode 100644 index 0000000..7fdcb3e --- /dev/null +++ b/el3_payload/plat/juno/platform.h @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2018, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __PLATFORM_H__ +#define __PLATFORM_H__ + +/* Designate the Cortex-A53 #0 as the primary CPU */ +#define PRIMARY_CPU_MPID 0x100 + +#define CPUS_COUNT 6 + +#define UART_BASE 0x7ff80000 + +#endif /* __PLATFORM_H__ */ diff --git a/el3_payload/plat/juno/platform.mk b/el3_payload/plat/juno/platform.mk new file mode 100644 index 0000000..b4cda9b --- /dev/null +++ b/el3_payload/plat/juno/platform.mk @@ -0,0 +1,8 @@ +# +# Copyright (c) 2018, Arm Limited. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +DRAM_BASE := 0x80000000 +DRAM_SIZE := 0x80000000 diff --git a/el3_payload/scripts/fvp/run_foundation.sh b/el3_payload/scripts/fvp/run_foundation.sh new file mode 100755 index 0000000..f8ec343 --- /dev/null +++ b/el3_payload/scripts/fvp/run_foundation.sh @@ -0,0 +1,51 @@ +#! /bin/bash + +# +# Script to run the EL3 payload on the Foundation FVP. +# +# /!\ The EL3 payload is not supported on the Foundation FVP without tweaking +# the code. You need to modify the number of expected cores in +# plat/fvp/platform.h: +# -#define CPUS_COUNT 8 +# +#define CPUS_COUNT 4 +# + +set -e + +# usage: check_file_is_present <filename> +# Check that <filename> exists in the current directory. +# If not, print an error message and exit. +function check_file_is_present +{ + BIN_FILE=$1 + if [ ! -e "$BIN_FILE" ]; then + echo "ERROR: Can't find \"$BIN_FILE\" file" + echo "Please copy $BIN_FILE into the current working directory." + echo "Alternatively, a symbolic link might be created." + echo + exit 1 + fi +} + +check_file_is_present "bl1.bin" +check_file_is_present "fip.bin" + +# Create an 8-byte file containing all zero bytes. +# It will be loaded at the beginning of the Trusted SRAM to zero the mailbox. +MAILBOX_FILE=mailbox.dat +rm -f $MAILBOX_FILE +dd if=/dev/zero of=$MAILBOX_FILE bs=1 count=8 + +# The path to the Foundation model must be provided by the user. +MODEL_EXEC="${MODEL_EXEC:?}" +MODEL_PARAMETERS=" \ + --cores=4 \ + --visualization \ + --data=bl1.bin@0x0 \ + --data=fip.bin@0x08000000 \ + --data=$MAILBOX_FILE@0x04000000 \ + --data=build/fvp/el3_payload.bin@0x80000000 \ +" + +echo $MODEL_EXEC $MODEL_PARAMETERS +$MODEL_EXEC $MODEL_PARAMETERS diff --git a/el3_payload/scripts/fvp/run_fvp.sh b/el3_payload/scripts/fvp/run_fvp.sh new file mode 100755 index 0000000..788c90c --- /dev/null +++ b/el3_payload/scripts/fvp/run_fvp.sh @@ -0,0 +1,56 @@ +#! /bin/bash + +set -e + +UART_OUTPUT_FILE=uart0.log + +# usage: check_file_is_present <filename> +# Check that <filename> exists in the current directory. +# If not, print an error message and exit. +function check_file_is_present +{ + BIN_FILE=$1 + if [ ! -e "$BIN_FILE" ]; then + echo "ERROR: Can't find \"$BIN_FILE\" file" + echo "Please copy $BIN_FILE into the current working directory." + echo "Alternatively, a symbolic link might be created." + echo + exit 1 + fi +} + +check_file_is_present "bl1.bin" +check_file_is_present "fip.bin" + +# The path to the Foundation model must be provided by the user. +MODEL_EXEC="${MODEL_EXEC:?}" +MODEL_PARAMETERS=" + -C pctl.startup=0.0.*.*,0.1.*.* \ + -C bp.secureflashloader.fname=bl1.bin \ + -C bp.flashloader0.fname=fip.bin \ + --data cluster0.cpu0=build/fvp/el3_payload.bin@0x80000000 \ + -C bp.secureSRAM.fill1=0x00000000 \ + -C bp.secureSRAM.fill2=0x00000000 \ + -C bp.pl011_uart0.out_file=$UART_OUTPUT_FILE \ + -C bp.pl011_uart0.shutdown_on_eot=1 \ +" + +echo $MODEL_EXEC $MODEL_PARAMETERS +$MODEL_EXEC $MODEL_PARAMETERS + +# Print results +green='\033[1;32;40m' +no_color='\033[0m' +echo +echo -e "$green" +echo "============" +echo " COMPLETE!" +echo "============" +echo -e "$no_color" +echo "UART output:" +echo "--------------------------------8<------------------------------" +cat $UART_OUTPUT_FILE +echo "--------------------------------8<------------------------------" +echo +echo "Output saved in $UART_OUTPUT_FILE file." +echo diff --git a/el3_payload/scripts/juno/load_el3_payload.ds b/el3_payload/scripts/juno/load_el3_payload.ds new file mode 100644 index 0000000..23db44d --- /dev/null +++ b/el3_payload/scripts/juno/load_el3_payload.ds @@ -0,0 +1,11 @@ +# Stop target +interrupt + +# Load EL3 payload +load build/juno/el3_payload.elf + +# Jump over BL1 infinite loop +set var $pc = $pc + 4 + +# Resume execution +continue diff --git a/el3_payload/scripts/juno/run_ds5_script.sh b/el3_payload/scripts/juno/run_ds5_script.sh new file mode 100755 index 0000000..67d0736 --- /dev/null +++ b/el3_payload/scripts/juno/run_ds5_script.sh @@ -0,0 +1,49 @@ +#! /bin/sh + +set -e + +# Expect the script to run in argument +if [ $# != 1 ]; then + echo "ERROR: No script provided" + echo "usage: $(basename $0) <ds5_script_to_run>" + exit 1 +fi + +# Is DS-5 command-line debugger found? +if [ ! $(which debugger) ]; then + echo 'ERROR: Failed to find DS-5 command-line debugger.' + echo 'Please add the path to the command-line debugger in your PATH.' + echo 'E.g.: export PATH=<DS-5 install dir>/bin:$PATH' + exit 1 +fi + +# DS-5 configuration database entry for Juno r0 +juno_cdb_entry='ARM Development Boards::Juno ARM Development Platform (r0)::Bare Metal Debug::Bare Metal Debug::Debug Cortex-A53_0::DSTREAM' + +# Browse for available DSTREAM connections and lists targets that match the +# connection type specified in the configuration database entry +echo "Trying to detect your DSTREAM unit..." +connections_list=available_connections +debugger --cdb-entry "$juno_cdb_entry" --browse \ + | tee $connections_list + +# Remove first line in the file (i.e. "Available connections:") +tail -n +2 $connections_list > ${connections_list}_stripped +mv ${connections_list}_stripped ${connections_list} + +# Use first available connection +read connection < $connections_list || true +rm $connections_list + +if [ -z "$connection" ] ; then + echo "ERROR: Found no connection" + exit 1 +fi + +# Run DS-5 script +echo "Connecting to $connection..." +debugger \ + --cdb-entry "$juno_cdb_entry" \ + --cdb-entry-param "Connection=$connection" \ + --stop_on_connect=false \ + --script=$1 diff --git a/el3_payload/spin.S b/el3_payload/spin.S new file mode 100644 index 0000000..8cf067f --- /dev/null +++ b/el3_payload/spin.S @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2018, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "arch.h" +#include "asm_macros.S" +#include "platform.h" + +/* Initial value of each entry in the cpus_table[] array */ +#define NO_CPU 0xDEADDEADDEADDEAD + +/* + * Declare a per-CPU array to mark the CPUs presence. + * + * If cpus_table[i] == NO_CPU then CPU 'i' hasn't successfully booted to the + * to the EL3 test payload yet. + * + * Otherwise, it successfully booted (and cpus_table[i] should contain the + * CPU MPID). + */ + .data + .align 3 +cpus_table: + .rept CPUS_COUNT + .quad NO_CPU + .endr + + + .text + .global mark_cpu_presence + .global is_cpu_present + + /* + * void mark_cpu_presence(); + * Mark the calling CPU present in the CPUs array. + * clobbers: x0, x1, x2, x9 + */ +func mark_cpu_presence + /* Store masked MPID in x2 */ + mrs x0, mpidr_el1 + ldr x1, =MPIDR_AFFINITY_MASK + and x2, x0, x1 + + /* Store core position in x0 */ + mov x9, x30 + bl platform_get_core_pos + mov x30, x9 + + /* Write masked CPU MPID in the CPU entry */ + adr x1, cpus_table + add x1, x1, x0, lsl #3 + str x2, [x1] + + ret +endfunc mark_cpu_presence + + /* + * unsigned int is_cpu_present(unsigned int core_pos); + * Return 0 if CPU is absent, 1 if it is present. + * clobbers: x0, x1 + */ +func is_cpu_present + adr x1, cpus_table + add x1, x1, x0, lsl #3 + ldr x0, [x1] + + ldr x1, =NO_CPU + cmp x0, x1 + b.eq 1f + mov x0, #1 + ret +1: + mov x0, #0 + ret +endfunc is_cpu_present diff --git a/el3_payload/uart.S b/el3_payload/uart.S new file mode 100644 index 0000000..b7c5e94 --- /dev/null +++ b/el3_payload/uart.S @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2018, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "asm_macros.S" +#include "platform.h" + +/* + * PL011 UART registers + */ +/* UART Flag Register */ +#define UARTFR 0x018 +/* Transmit FIFO full bit in UARTFR register */ +#define PL011_UARTFR_TXFF_BIT 5 +/* UART Data Register */ +#define UARTDR 0x000 + + .text + .global print_string + .global print_char + + /* + * void print_char(unsigned int c); + * clobbers: x3, x4 + */ +func print_char + ldr x3, =UART_BASE +1: + /* Check if the transmit FIFO is full */ + ldr w4, [x3, #UARTFR] + tbnz w4, #PL011_UARTFR_TXFF_BIT, 1b + str w0, [x3, #UARTDR] + ret +endfunc print_char + + /* + * void print_string(const char *str); + * clobbers: x0, x1, x2, x9 + */ +func print_string + ldr x1, =UART_BASE + mov x2, x0 +1: + ldrb w0, [x2], #1 + cmp wzr, w0 + b.eq 2f + + mov x9, x30 + bl print_char + mov x30, x9 + b 1b +2: + ret +endfunc print_string |