blob: d034e001970a7ed8941146ba1633e7ca6821bfc2 [file] [log] [blame]
Michal Simekef8f5592015-06-15 14:22:50 +02001/*
Michal Simek2a47faa2023-04-14 08:43:51 +02002 * Copyright (c) 2014-2020, Arm Limited and Contributors. All rights reserved.
Prasad Kummarie0783112023-04-26 11:02:07 +05303 * Copyright (c) 2023, Advanced Micro Devices, Inc. All rights reserved.
Michal Simekef8f5592015-06-15 14:22:50 +02004 *
dp-armfa3cf0b2017-05-03 09:38:09 +01005 * SPDX-License-Identifier: BSD-3-Clause
Michal Simekef8f5592015-06-15 14:22:50 +02006 */
7
Michal Simekef8f5592015-06-15 14:22:50 +02008#include <assert.h>
Scott Brandene5dcf982020-08-25 13:49:32 -07009#include <inttypes.h>
10#include <stdint.h>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +000011
12#include <arch_helpers.h>
13#include <common/debug.h>
Venkatesh Yadav Abbarapu1463dd52020-01-07 03:25:16 -070014#include <plat_startup.h>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +000015
Michal Simekef8f5592015-06-15 14:22:50 +020016
17/*
Prasad Kummarie0783112023-04-26 11:02:07 +053018 * TFAHandoffParams
Michal Simekef8f5592015-06-15 14:22:50 +020019 * Parameter bitfield encoding
20 * -----------------------------------------------------------------------------
21 * Exec State 0 0 -> Aarch64, 1-> Aarch32
Soren Brinkmann8bcd3052016-05-29 09:48:26 -070022 * endianness 1 0 -> LE, 1 -> BE
Michal Simekef8f5592015-06-15 14:22:50 +020023 * secure (TZ) 2 0 -> Non secure, 1 -> secure
24 * EL 3:4 00 -> EL0, 01 -> EL1, 10 -> EL2, 11 -> EL3
25 * CPU# 5:6 00 -> A53_0, 01 -> A53_1, 10 -> A53_2, 11 -> A53_3
26 */
27
Venkatesh Yadav Abbarapua2ca35d2022-07-04 11:40:27 +053028#define FSBL_FLAGS_ESTATE_SHIFT 0U
29#define FSBL_FLAGS_ESTATE_MASK (1U << FSBL_FLAGS_ESTATE_SHIFT)
30#define FSBL_FLAGS_ESTATE_A64 0U
31#define FSBL_FLAGS_ESTATE_A32 1U
Michal Simekef8f5592015-06-15 14:22:50 +020032
Venkatesh Yadav Abbarapua2ca35d2022-07-04 11:40:27 +053033#define FSBL_FLAGS_ENDIAN_SHIFT 1U
34#define FSBL_FLAGS_ENDIAN_MASK (1U << FSBL_FLAGS_ENDIAN_SHIFT)
35#define FSBL_FLAGS_ENDIAN_LE 0U
36#define FSBL_FLAGS_ENDIAN_BE 1U
Michal Simekef8f5592015-06-15 14:22:50 +020037
Venkatesh Yadav Abbarapua2ca35d2022-07-04 11:40:27 +053038#define FSBL_FLAGS_TZ_SHIFT 2U
39#define FSBL_FLAGS_TZ_MASK (1U << FSBL_FLAGS_TZ_SHIFT)
40#define FSBL_FLAGS_NON_SECURE 0U
41#define FSBL_FLAGS_SECURE 1U
Michal Simekef8f5592015-06-15 14:22:50 +020042
Venkatesh Yadav Abbarapua2ca35d2022-07-04 11:40:27 +053043#define FSBL_FLAGS_EL_SHIFT 3U
44#define FSBL_FLAGS_EL_MASK (3U << FSBL_FLAGS_EL_SHIFT)
45#define FSBL_FLAGS_EL0 0U
46#define FSBL_FLAGS_EL1 1U
47#define FSBL_FLAGS_EL2 2U
48#define FSBL_FLAGS_EL3 3U
Michal Simekef8f5592015-06-15 14:22:50 +020049
Venkatesh Yadav Abbarapua2ca35d2022-07-04 11:40:27 +053050#define FSBL_FLAGS_CPU_SHIFT 5U
51#define FSBL_FLAGS_CPU_MASK (3U << FSBL_FLAGS_CPU_SHIFT)
52#define FSBL_FLAGS_A53_0 0U
53#define FSBL_FLAGS_A53_1 1U
54#define FSBL_FLAGS_A53_2 2U
55#define FSBL_FLAGS_A53_3 3U
Michal Simekef8f5592015-06-15 14:22:50 +020056
Michal Simekef8f5592015-06-15 14:22:50 +020057/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +053058 * get_fsbl_cpu() - Get the target CPU for partition.
59 * @partition: Pointer to partition struct.
Michal Simekef8f5592015-06-15 14:22:50 +020060 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +053061 * Return: FSBL_FLAGS_A53_0, FSBL_FLAGS_A53_1, FSBL_FLAGS_A53_2 or
62 * FSBL_FLAGS_A53_3.
Michal Simekef8f5592015-06-15 14:22:50 +020063 *
Michal Simekef8f5592015-06-15 14:22:50 +020064 */
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +053065static int32_t get_fsbl_cpu(const struct xfsbl_partition *partition)
Michal Simekef8f5592015-06-15 14:22:50 +020066{
67 uint64_t flags = partition->flags & FSBL_FLAGS_CPU_MASK;
68
69 return flags >> FSBL_FLAGS_CPU_SHIFT;
70}
71
72/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +053073 * get_fsbl_el() - Get the target exception level for partition.
74 * @partition: Pointer to partition struct.
Michal Simekef8f5592015-06-15 14:22:50 +020075 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +053076 * Return: FSBL_FLAGS_EL0, FSBL_FLAGS_EL1, FSBL_FLAGS_EL2 or FSBL_FLAGS_EL3.
Michal Simekef8f5592015-06-15 14:22:50 +020077 *
Michal Simekef8f5592015-06-15 14:22:50 +020078 */
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +053079static int32_t get_fsbl_el(const struct xfsbl_partition *partition)
Michal Simekef8f5592015-06-15 14:22:50 +020080{
81 uint64_t flags = partition->flags & FSBL_FLAGS_EL_MASK;
82
Soren Brinkmanndeba2af2016-05-29 09:48:44 -070083 return flags >> FSBL_FLAGS_EL_SHIFT;
Michal Simekef8f5592015-06-15 14:22:50 +020084}
85
86/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +053087 * get_fsbl_ss() - Get the target security state for partition.
88 * @partition: Pointer to partition struct.
Michal Simekef8f5592015-06-15 14:22:50 +020089 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +053090 * Return: FSBL_FLAGS_NON_SECURE or FSBL_FLAGS_SECURE.
Michal Simekef8f5592015-06-15 14:22:50 +020091 *
Michal Simekef8f5592015-06-15 14:22:50 +020092 */
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +053093static int32_t get_fsbl_ss(const struct xfsbl_partition *partition)
Michal Simekef8f5592015-06-15 14:22:50 +020094{
95 uint64_t flags = partition->flags & FSBL_FLAGS_TZ_MASK;
96
97 return flags >> FSBL_FLAGS_TZ_SHIFT;
98}
99
100/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530101 * get_fsbl_endian() - Get the target endianness for partition.
102 * @partition: Pointer to partition struct.
Michal Simekef8f5592015-06-15 14:22:50 +0200103 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530104 * Return: SPSR_E_LITTLE or SPSR_E_BIG.
Michal Simekef8f5592015-06-15 14:22:50 +0200105 *
Michal Simekef8f5592015-06-15 14:22:50 +0200106 */
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +0530107static int32_t get_fsbl_endian(const struct xfsbl_partition *partition)
Michal Simekef8f5592015-06-15 14:22:50 +0200108{
109 uint64_t flags = partition->flags & FSBL_FLAGS_ENDIAN_MASK;
110
111 flags >>= FSBL_FLAGS_ENDIAN_SHIFT;
112
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530113 if (flags == FSBL_FLAGS_ENDIAN_BE) {
Michal Simekef8f5592015-06-15 14:22:50 +0200114 return SPSR_E_BIG;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530115 } else {
Michal Simekef8f5592015-06-15 14:22:50 +0200116 return SPSR_E_LITTLE;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530117 }
Michal Simekef8f5592015-06-15 14:22:50 +0200118}
119
120/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530121 * get_fsbl_estate() - Get the target execution state for partition.
122 * @partition: Pointer to partition struct.
Michal Simekef8f5592015-06-15 14:22:50 +0200123 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530124 * Return: FSBL_FLAGS_ESTATE_A32 or FSBL_FLAGS_ESTATE_A64.
Michal Simekef8f5592015-06-15 14:22:50 +0200125 *
Michal Simekef8f5592015-06-15 14:22:50 +0200126 */
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +0530127static int32_t get_fsbl_estate(const struct xfsbl_partition *partition)
Michal Simekef8f5592015-06-15 14:22:50 +0200128{
129 uint64_t flags = partition->flags & FSBL_FLAGS_ESTATE_MASK;
130
131 return flags >> FSBL_FLAGS_ESTATE_SHIFT;
132}
133
134/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530135 * fsbl_tfa_handover() - Populates the bl32 and bl33 image info structures.
136 * @bl32: BL32 image info structure.
137 * @bl33: BL33 image info structure.
138 * @tfa_handoff_addr: TF-A handoff address.
Michal Simekef8f5592015-06-15 14:22:50 +0200139 *
Elyes Haouas2be03c02023-02-13 09:14:48 +0100140 * Process the handoff parameters from the FSBL and populate the BL32 and BL33
Michal Simekef8f5592015-06-15 14:22:50 +0200141 * image info structures accordingly.
Siva Durga Prasad Paladugu8f499722018-05-17 15:17:46 +0530142 *
143 * Return: Return the status of the handoff. The value will be from the
144 * fsbl_handoff enum.
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530145 *
Michal Simekef8f5592015-06-15 14:22:50 +0200146 */
Prasad Kummarie0783112023-04-26 11:02:07 +0530147enum fsbl_handoff fsbl_tfa_handover(entry_point_info_t *bl32,
Venkatesh Yadav Abbarapu1463dd52020-01-07 03:25:16 -0700148 entry_point_info_t *bl33,
Prasad Kummarie0783112023-04-26 11:02:07 +0530149 uint64_t tfa_handoff_addr)
Michal Simekef8f5592015-06-15 14:22:50 +0200150{
Prasad Kummarie0783112023-04-26 11:02:07 +0530151 const struct xfsbl_tfa_handoff_params *TFAHandoffParams;
152 if (!tfa_handoff_addr) {
153 WARN("BL31: No TFA handoff structure passed\n");
Siva Durga Prasad Paladugu8f499722018-05-17 15:17:46 +0530154 return FSBL_HANDOFF_NO_STRUCT;
Michal Simekef8f5592015-06-15 14:22:50 +0200155 }
156
Prasad Kummarie0783112023-04-26 11:02:07 +0530157 TFAHandoffParams = (struct xfsbl_tfa_handoff_params *)tfa_handoff_addr;
158 if ((TFAHandoffParams->magic[0] != 'X') ||
159 (TFAHandoffParams->magic[1] != 'L') ||
160 (TFAHandoffParams->magic[2] != 'N') ||
161 (TFAHandoffParams->magic[3] != 'X')) {
162 ERROR("BL31: invalid TF-A handoff structure at %" PRIx64 "\n",
163 tfa_handoff_addr);
Siva Durga Prasad Paladugu8f499722018-05-17 15:17:46 +0530164 return FSBL_HANDOFF_INVAL_STRUCT;
Michal Simekef8f5592015-06-15 14:22:50 +0200165 }
166
Prasad Kummarie0783112023-04-26 11:02:07 +0530167 VERBOSE("BL31: TF-A handoff params at:0x%" PRIx64 ", entries:%u\n",
168 tfa_handoff_addr, TFAHandoffParams->num_entries);
169 if (TFAHandoffParams->num_entries > FSBL_MAX_PARTITIONS) {
170 ERROR("BL31: TF-A handoff params: too many partitions (%u/%u)\n",
171 TFAHandoffParams->num_entries, FSBL_MAX_PARTITIONS);
Siva Durga Prasad Paladugu8f499722018-05-17 15:17:46 +0530172 return FSBL_HANDOFF_TOO_MANY_PARTS;
Michal Simekef8f5592015-06-15 14:22:50 +0200173 }
174
175 /*
176 * we loop over all passed entries but only populate two image structs
177 * (bl32, bl33). I.e. the last applicable images in the handoff
178 * structure will be used for the hand off
179 */
Prasad Kummarie0783112023-04-26 11:02:07 +0530180 for (size_t i = 0; i < TFAHandoffParams->num_entries; i++) {
Michal Simekef8f5592015-06-15 14:22:50 +0200181 entry_point_info_t *image;
Venkatesh Yadav Abbarapua2ca35d2022-07-04 11:40:27 +0530182 int32_t target_estate, target_secure, target_cpu;
183 uint32_t target_endianness, target_el;
Michal Simekef8f5592015-06-15 14:22:50 +0200184
Scott Brandene5dcf982020-08-25 13:49:32 -0700185 VERBOSE("BL31: %zd: entry:0x%" PRIx64 ", flags:0x%" PRIx64 "\n", i,
Prasad Kummarie0783112023-04-26 11:02:07 +0530186 TFAHandoffParams->partition[i].entry_point,
187 TFAHandoffParams->partition[i].flags);
Michal Simekef8f5592015-06-15 14:22:50 +0200188
Prasad Kummarie0783112023-04-26 11:02:07 +0530189 target_cpu = get_fsbl_cpu(&TFAHandoffParams->partition[i]);
Michal Simekef8f5592015-06-15 14:22:50 +0200190 if (target_cpu != FSBL_FLAGS_A53_0) {
191 WARN("BL31: invalid target CPU (%i)\n", target_cpu);
192 continue;
193 }
194
Prasad Kummarie0783112023-04-26 11:02:07 +0530195 target_el = get_fsbl_el(&TFAHandoffParams->partition[i]);
Michal Simekef8f5592015-06-15 14:22:50 +0200196 if ((target_el == FSBL_FLAGS_EL3) ||
197 (target_el == FSBL_FLAGS_EL0)) {
198 WARN("BL31: invalid exception level (%i)\n", target_el);
199 continue;
200 }
201
Prasad Kummarie0783112023-04-26 11:02:07 +0530202 target_secure = get_fsbl_ss(&TFAHandoffParams->partition[i]);
Michal Simekef8f5592015-06-15 14:22:50 +0200203 if (target_secure == FSBL_FLAGS_SECURE &&
204 target_el == FSBL_FLAGS_EL2) {
205 WARN("BL31: invalid security state (%i) for exception level (%i)\n",
206 target_secure, target_el);
207 continue;
208 }
209
Prasad Kummarie0783112023-04-26 11:02:07 +0530210 target_estate = get_fsbl_estate(&TFAHandoffParams->partition[i]);
211 target_endianness = get_fsbl_endian(&TFAHandoffParams->partition[i]);
Michal Simekef8f5592015-06-15 14:22:50 +0200212
213 if (target_secure == FSBL_FLAGS_SECURE) {
214 image = bl32;
215
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530216 if (target_estate == FSBL_FLAGS_ESTATE_A32) {
Michal Simekef8f5592015-06-15 14:22:50 +0200217 bl32->spsr = SPSR_MODE32(MODE32_svc, SPSR_T_ARM,
Soren Brinkmann8bcd3052016-05-29 09:48:26 -0700218 target_endianness,
Michal Simekef8f5592015-06-15 14:22:50 +0200219 DISABLE_ALL_EXCEPTIONS);
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530220 } else {
Michal Simekef8f5592015-06-15 14:22:50 +0200221 bl32->spsr = SPSR_64(MODE_EL1, MODE_SP_ELX,
222 DISABLE_ALL_EXCEPTIONS);
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530223 }
Michal Simekef8f5592015-06-15 14:22:50 +0200224 } else {
225 image = bl33;
226
227 if (target_estate == FSBL_FLAGS_ESTATE_A32) {
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530228 if (target_el == FSBL_FLAGS_EL2) {
Michal Simekef8f5592015-06-15 14:22:50 +0200229 target_el = MODE32_hyp;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530230 } else {
Michal Simekef8f5592015-06-15 14:22:50 +0200231 target_el = MODE32_sys;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530232 }
Michal Simekef8f5592015-06-15 14:22:50 +0200233
234 bl33->spsr = SPSR_MODE32(target_el, SPSR_T_ARM,
Soren Brinkmann8bcd3052016-05-29 09:48:26 -0700235 target_endianness,
Michal Simekef8f5592015-06-15 14:22:50 +0200236 DISABLE_ALL_EXCEPTIONS);
237 } else {
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530238 if (target_el == FSBL_FLAGS_EL2) {
Michal Simekef8f5592015-06-15 14:22:50 +0200239 target_el = MODE_EL2;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530240 } else {
Michal Simekef8f5592015-06-15 14:22:50 +0200241 target_el = MODE_EL1;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530242 }
Michal Simekef8f5592015-06-15 14:22:50 +0200243
244 bl33->spsr = SPSR_64(target_el, MODE_SP_ELX,
245 DISABLE_ALL_EXCEPTIONS);
246 }
247 }
248
Scott Brandene5dcf982020-08-25 13:49:32 -0700249 VERBOSE("Setting up %s entry point to:%" PRIx64 ", el:%x\n",
Michal Simekef8f5592015-06-15 14:22:50 +0200250 target_secure == FSBL_FLAGS_SECURE ? "BL32" : "BL33",
Prasad Kummarie0783112023-04-26 11:02:07 +0530251 TFAHandoffParams->partition[i].entry_point,
Michal Simekef8f5592015-06-15 14:22:50 +0200252 target_el);
Prasad Kummarie0783112023-04-26 11:02:07 +0530253 image->pc = TFAHandoffParams->partition[i].entry_point;
Michal Simekef8f5592015-06-15 14:22:50 +0200254
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530255 if (target_endianness == SPSR_E_BIG) {
Michal Simekef8f5592015-06-15 14:22:50 +0200256 EP_SET_EE(image->h.attr, EP_EE_BIG);
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530257 } else {
Michal Simekef8f5592015-06-15 14:22:50 +0200258 EP_SET_EE(image->h.attr, EP_EE_LITTLE);
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530259 }
Michal Simekef8f5592015-06-15 14:22:50 +0200260 }
Siva Durga Prasad Paladugu8f499722018-05-17 15:17:46 +0530261
262 return FSBL_HANDOFF_SUCCESS;
Michal Simekef8f5592015-06-15 14:22:50 +0200263}