[U-Boot] [PATCH] ARM64: zynqmp: Generate handoff structure for ATF

Michal Simek michal.simek at xilinx.com
Mon Jan 9 10:56:23 CET 2017


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 <michal.simek at xilinx.com>
---

 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 be8673a7db44..013f136707b5 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 000000000000..25d6ef3f60fb
--- /dev/null
+++ b/arch/arm/cpu/armv8/zynqmp/handoff.c
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2016 - 2017 Xilinx, Inc.
+ *
+ * Michal Simek <michal.simek at xilinx.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/sys_proto.h>
+
+/*
+ * 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 f5f550f9e2b4..0a5f4306e822 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 eb6f7a4ae447..6f83c0de65ef 100644
--- a/arch/arm/include/asm/arch-zynqmp/hardware.h
+++ b/arch/arm/include/asm/arch-zynqmp/hardware.h
@@ -141,4 +141,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 95fd91da2915..8c54fcedf401 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 */
-- 
1.9.1



More information about the U-Boot mailing list