From 509d4b9545d82179d5854eddb928c0055702dc67 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Mon, 9 Jan 2017 10:05:16 +0100 Subject: [PATCH] ARM64: zynqmp: Generate handoff structure for ATF Xilinx ATF extending options for passing images from BL2(FSBL) to BL31. U-Boot SPL is FSBL replacement that's why it should generate handoff structure the same. Support only one entry which is U-Boot in EL2 itself. When FIT image is adopted structure generate should be data driven. Currently ATF is placing this structure at the beggining of OCM which is rewriting early parts of ATF which should be unused at that time. Signed-off-by: Michal Simek --- arch/arm/cpu/armv8/zynqmp/Makefile | 2 +- arch/arm/cpu/armv8/zynqmp/handoff.c | 87 ++++++++++++++++++++ arch/arm/cpu/armv8/zynqmp/spl.c | 2 + arch/arm/include/asm/arch-zynqmp/hardware.h | 9 ++ arch/arm/include/asm/arch-zynqmp/sys_proto.h | 2 + 5 files changed, 101 insertions(+), 1 deletion(-) create mode 100644 arch/arm/cpu/armv8/zynqmp/handoff.c diff --git a/arch/arm/cpu/armv8/zynqmp/Makefile b/arch/arm/cpu/armv8/zynqmp/Makefile index be8673a7db..013f136707 100644 --- a/arch/arm/cpu/armv8/zynqmp/Makefile +++ b/arch/arm/cpu/armv8/zynqmp/Makefile @@ -9,4 +9,4 @@ obj-y += clk.o obj-y += cpu.o obj-$(CONFIG_MP) += mp.o obj-y += slcr.o -obj-$(CONFIG_SPL_BUILD) += spl.o +obj-$(CONFIG_SPL_BUILD) += spl.o handoff.o diff --git a/arch/arm/cpu/armv8/zynqmp/handoff.c b/arch/arm/cpu/armv8/zynqmp/handoff.c new file mode 100644 index 0000000000..25d6ef3f60 --- /dev/null +++ b/arch/arm/cpu/armv8/zynqmp/handoff.c @@ -0,0 +1,87 @@ +/* + * Copyright 2016 - 2017 Xilinx, Inc. + * + * Michal Simek + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include + +/* + * atfhandoffparams + * Parameter bitfield encoding + * ----------------------------------------------------------------------------- + * Exec State 0 0 -> Aarch64, 1-> Aarch32 + * endianness 1 0 -> LE, 1 -> BE + * secure (TZ) 2 0 -> Non secure, 1 -> secure + * EL 3:4 00 -> EL0, 01 -> EL1, 10 -> EL2, 11 -> EL3 + * CPU# 5:6 00 -> A53_0, 01 -> A53_1, 10 -> A53_2, 11 -> A53_3 + */ + +#define FSBL_FLAGS_ESTATE_SHIFT 0 +#define FSBL_FLAGS_ESTATE_MASK (1 << FSBL_FLAGS_ESTATE_SHIFT) +#define FSBL_FLAGS_ESTATE_A64 0 +#define FSBL_FLAGS_ESTATE_A32 1 + +#define FSBL_FLAGS_ENDIAN_SHIFT 1 +#define FSBL_FLAGS_ENDIAN_MASK (1 << FSBL_FLAGS_ENDIAN_SHIFT) +#define FSBL_FLAGS_ENDIAN_LE 0 +#define FSBL_FLAGS_ENDIAN_BE 1 + +#define FSBL_FLAGS_TZ_SHIFT 2 +#define FSBL_FLAGS_TZ_MASK (1 << FSBL_FLAGS_TZ_SHIFT) +#define FSBL_FLAGS_NON_SECURE 0 +#define FSBL_FLAGS_SECURE 1 + +#define FSBL_FLAGS_EL_SHIFT 3 +#define FSBL_FLAGS_EL_MASK (3 << FSBL_FLAGS_EL_SHIFT) +#define FSBL_FLAGS_EL0 0 +#define FSBL_FLAGS_EL1 1 +#define FSBL_FLAGS_EL2 2 +#define FSBL_FLAGS_EL3 3 + +#define FSBL_FLAGS_CPU_SHIFT 5 +#define FSBL_FLAGS_CPU_MASK (3 << FSBL_FLAGS_CPU_SHIFT) +#define FSBL_FLAGS_A53_0 0 +#define FSBL_FLAGS_A53_1 1 +#define FSBL_FLAGS_A53_2 2 +#define FSBL_FLAGS_A53_3 3 + +#define FSBL_MAX_PARTITIONS 8 + +/* Structure corresponding to each partition entry */ +struct xfsbl_partition { + uint64_t entry_point; + uint64_t flags; +}; + +/* Structure for handoff parameters to ARM Trusted Firmware (ATF) */ +struct xfsbl_atf_handoff_params { + uint8_t magic[4]; + uint32_t num_entries; + struct xfsbl_partition partition[FSBL_MAX_PARTITIONS]; +}; + +#ifdef CONFIG_SPL_OS_BOOT +void handoff_setup(void) +{ + struct xfsbl_atf_handoff_params *atfhandoffparams; + + atfhandoffparams = (void *)CONFIG_SPL_TEXT_BASE; + atfhandoffparams->magic[0] = 'X'; + atfhandoffparams->magic[1] = 'L'; + atfhandoffparams->magic[2] = 'N'; + atfhandoffparams->magic[3] = 'X'; + + atfhandoffparams->num_entries = 1; + atfhandoffparams->partition[0].entry_point = CONFIG_SYS_TEXT_BASE; + atfhandoffparams->partition[0].flags = FSBL_FLAGS_EL2 << + FSBL_FLAGS_EL_SHIFT; + + writel(CONFIG_SPL_TEXT_BASE, &pmu_base->gen_storage6); +} +#endif diff --git a/arch/arm/cpu/armv8/zynqmp/spl.c b/arch/arm/cpu/armv8/zynqmp/spl.c index f5f550f9e2..0a5f4306e8 100644 --- a/arch/arm/cpu/armv8/zynqmp/spl.c +++ b/arch/arm/cpu/armv8/zynqmp/spl.c @@ -128,6 +128,8 @@ __weak void psu_init(void) #ifdef CONFIG_SPL_OS_BOOT int spl_start_uboot(void) { + handoff_setup(); + return 0; } #endif diff --git a/arch/arm/include/asm/arch-zynqmp/hardware.h b/arch/arm/include/asm/arch-zynqmp/hardware.h index 041b43cfe0..cf187f3111 100644 --- a/arch/arm/include/asm/arch-zynqmp/hardware.h +++ b/arch/arm/include/asm/arch-zynqmp/hardware.h @@ -144,4 +144,13 @@ struct csu_regs { #define csu_base ((struct csu_regs *)ZYNQMP_CSU_BASEADDR) +#define ZYNQMP_PMU_BASEADDR 0xFFD80000 + +struct pmu_regs { + u32 reserved[18]; + u32 gen_storage6; /* 0x48 */ +}; + +#define pmu_base ((struct pmu_regs *)ZYNQMP_PMU_BASEADDR) + #endif /* _ASM_ARCH_HARDWARE_H */ diff --git a/arch/arm/include/asm/arch-zynqmp/sys_proto.h b/arch/arm/include/asm/arch-zynqmp/sys_proto.h index 95fd91da29..8c54fcedf4 100644 --- a/arch/arm/include/asm/arch-zynqmp/sys_proto.h +++ b/arch/arm/include/asm/arch-zynqmp/sys_proto.h @@ -21,4 +21,6 @@ unsigned int zynqmp_get_silicon_version(void); void psu_init(void); +void handoff_setup(void); + #endif /* _ASM_ARCH_SYS_PROTO_H */ -- 2.39.5