1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright 2016 - 2017 Xilinx, Inc.
4 *
5 * Michal Simek <michal.simek@amd.com>
6 */
7
8#include <common.h>
9#include <asm/io.h>
10#include <asm/arch/hardware.h>
11#include <asm/arch/sys_proto.h>
12#include <spl.h>
13
14/*
15 * atfhandoffparams
16 * Parameter	bitfield	encoding
17 * -----------------------------------------------------------------------------
18 * Exec State	0	0 -> Aarch64, 1-> Aarch32
19 * endianness	1	0 -> LE, 1 -> BE
20 * secure (TZ)	2	0 -> Non secure, 1 -> secure
21 * EL		3:4	00 -> EL0, 01 -> EL1, 10 -> EL2, 11 -> EL3
22 * CPU#		5:6	00 -> A53_0, 01 -> A53_1, 10 -> A53_2, 11 -> A53_3
23 */
24
25#define FSBL_FLAGS_ESTATE_SHIFT		0
26#define FSBL_FLAGS_ESTATE_MASK		(1 << FSBL_FLAGS_ESTATE_SHIFT)
27#define FSBL_FLAGS_ESTATE_A64		0
28#define FSBL_FLAGS_ESTATE_A32		1
29
30#define FSBL_FLAGS_ENDIAN_SHIFT		1
31#define FSBL_FLAGS_ENDIAN_MASK		(1 << FSBL_FLAGS_ENDIAN_SHIFT)
32#define FSBL_FLAGS_ENDIAN_LE		0
33#define FSBL_FLAGS_ENDIAN_BE		1
34
35#define FSBL_FLAGS_TZ_SHIFT		2
36#define FSBL_FLAGS_TZ_MASK		(1 << FSBL_FLAGS_TZ_SHIFT)
37#define FSBL_FLAGS_NON_SECURE		0
38#define FSBL_FLAGS_SECURE		1
39
40#define FSBL_FLAGS_EL_SHIFT		3
41#define FSBL_FLAGS_EL_MASK		(3 << FSBL_FLAGS_EL_SHIFT)
42#define FSBL_FLAGS_EL0			0
43#define FSBL_FLAGS_EL1			1
44#define FSBL_FLAGS_EL2			2
45#define FSBL_FLAGS_EL3			3
46
47#define FSBL_FLAGS_CPU_SHIFT		5
48#define FSBL_FLAGS_CPU_MASK		(3 << FSBL_FLAGS_CPU_SHIFT)
49#define FSBL_FLAGS_A53_0		0
50#define FSBL_FLAGS_A53_1		1
51#define FSBL_FLAGS_A53_2		2
52#define FSBL_FLAGS_A53_3		3
53
54#define FSBL_MAX_PARTITIONS		8
55
56/* Structure corresponding to each partition entry */
57struct xfsbl_partition {
58	uint64_t entry_point;
59	uint64_t flags;
60};
61
62/* Structure for handoff parameters to ARM Trusted Firmware (ATF) */
63struct xfsbl_atf_handoff_params {
64	uint8_t magic[4];
65	uint32_t num_entries;
66	struct xfsbl_partition partition[FSBL_MAX_PARTITIONS];
67};
68
69#ifdef CONFIG_SPL_ATF
70struct bl31_params *bl2_plat_get_bl31_params(uintptr_t bl32_entry,
71					     uintptr_t bl33_entry,
72					     uintptr_t fdt_addr)
73{
74	struct xfsbl_atf_handoff_params *atfhandoffparams;
75	u32 index = 0;
76
77	atfhandoffparams = (void *)CONFIG_SPL_TEXT_BASE;
78	atfhandoffparams->magic[0] = 'X';
79	atfhandoffparams->magic[1] = 'L';
80	atfhandoffparams->magic[2] = 'N';
81	atfhandoffparams->magic[3] = 'X';
82
83	debug("Creating handoff:\n");
84
85	if (bl32_entry) {
86		debug(" to BL32 at 0x%x EL-1, Secure\n", (u32)bl32_entry);
87		atfhandoffparams->partition[index].entry_point = bl32_entry;
88		atfhandoffparams->partition[index].flags = FSBL_FLAGS_EL1 << FSBL_FLAGS_EL_SHIFT |
89							   FSBL_FLAGS_SECURE << FSBL_FLAGS_TZ_SHIFT;
90		index++;
91	}
92
93	if (bl33_entry) {
94		debug(" to BL33 at 0x%x EL-2\n", (u32)bl33_entry);
95		atfhandoffparams->partition[index].entry_point = bl33_entry;
96		atfhandoffparams->partition[index].flags = FSBL_FLAGS_EL2 <<
97							   FSBL_FLAGS_EL_SHIFT;
98		index++;
99	}
100
101	atfhandoffparams->num_entries = index;
102
103	writel(CONFIG_SPL_TEXT_BASE, &pmu_base->gen_storage6);
104
105	return NULL;
106}
107#endif
108