ARM64: zynqmp: Generate handoff structure for ATF
authorMichal Simek <michal.simek@xilinx.com>
Mon, 9 Jan 2017 09:05:16 +0000 (10:05 +0100)
committerMichal Simek <michal.simek@xilinx.com>
Tue, 10 Jan 2017 09:22:05 +0000 (10:22 +0100)
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>
arch/arm/cpu/armv8/zynqmp/Makefile
arch/arm/cpu/armv8/zynqmp/handoff.c [new file with mode: 0644]
arch/arm/cpu/armv8/zynqmp/spl.c
arch/arm/include/asm/arch-zynqmp/hardware.h
arch/arm/include/asm/arch-zynqmp/sys_proto.h

index be8673a7db4410a4e2a3039030a67723c8cb29cc..013f136707b5ce891bbaae529fbd2259174d8a39 100644 (file)
@@ -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 (file)
index 0000000..25d6ef3
--- /dev/null
@@ -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
index f5f550f9e2b4707de3ecd05bea8ed4013b756afa..0a5f4306e8222e56b3e2e8339aa4f8ab790fb536 100644 (file)
@@ -128,6 +128,8 @@ __weak void psu_init(void)
 #ifdef CONFIG_SPL_OS_BOOT
 int spl_start_uboot(void)
 {
+       handoff_setup();
+
        return 0;
 }
 #endif
index 041b43cfe044385b7e5b61928b38a07b7218adb9..cf187f31110b987fd254004b2e9094699e6c1e68 100644 (file)
@@ -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 */
index 95fd91da291582d11665ffd76c125d9c4db20c7a..8c54fcedf40108fcc297e825c21e3ef3fbd28d80 100644 (file)
@@ -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 */