summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorMichal Simek <michal.simek@xilinx.com>2017-01-09 09:05:16 (GMT)
committerMichal Simek <michal.simek@xilinx.com>2017-01-10 09:22:05 (GMT)
commit509d4b9545d82179d5854eddb928c0055702dc67 (patch)
tree486574b9828156fd9930b29f0d27b3bc31439164 /arch
parent5cf22289aeaf0c84dcb55c629ae4ed72112024cc (diff)
downloadu-boot-509d4b9545d82179d5854eddb928c0055702dc67.tar.xz
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 <michal.simek@xilinx.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/cpu/armv8/zynqmp/Makefile2
-rw-r--r--arch/arm/cpu/armv8/zynqmp/handoff.c87
-rw-r--r--arch/arm/cpu/armv8/zynqmp/spl.c2
-rw-r--r--arch/arm/include/asm/arch-zynqmp/hardware.h9
-rw-r--r--arch/arm/include/asm/arch-zynqmp/sys_proto.h2
5 files changed, 101 insertions, 1 deletions
diff --git a/arch/arm/cpu/armv8/zynqmp/Makefile b/arch/arm/cpu/armv8/zynqmp/Makefile
index be8673a..013f136 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 0000000..25d6ef3
--- /dev/null
+++ b/arch/arm/cpu/armv8/zynqmp/handoff.c
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2016 - 2017 Xilinx, Inc.
+ *
+ * Michal Simek <michal.simek@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 f5f550f..0a5f430 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 041b43c..cf187f3 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 95fd91d..8c54fce 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 */