blob: 2fd0e97ebaeaea5037548d5c7e9f865e5e71b307 [file] [log] [blame]
Gary Morrison3d7f6542021-01-27 13:08:47 -06001/*
2 * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <assert.h>
8
9#include "../../../../bl1/bl1_private.h"
10#include <arch.h>
11#include <arch_features.h>
12#include <arch_helpers.h>
13#include <bl1/bl1.h>
14#include <common/bl_common.h>
15#include <common/debug.h>
16#include <drivers/auth/auth_mod.h>
17#include <drivers/console.h>
18#include <lib/cpus/errata_report.h>
19#include <lib/utils.h>
20#include <smccc_helpers.h>
21#include <tools_share/uuid.h>
laurenw-arm56f1e3e2021-03-03 14:19:38 -060022#include <plat/arm/common/plat_arm.h>
Gary Morrison3d7f6542021-01-27 13:08:47 -060023#include <plat/common/platform.h>
24
25#include <platform_def.h>
26
27
laurenw-arm56f1e3e2021-03-03 14:19:38 -060028void bl1_run_next_image(const struct entry_point_info *bl_ep_info);
29
30/*******************************************************************************
31 * Function to perform late architectural and platform specific initialization.
32 * It also queries the platform to load and run next BL image. Only called
33 * by the primary cpu after a cold boot.
34 ******************************************************************************/
35void bl1_transfer_bl33(void)
36{
37 unsigned int image_id;
38
39 /* Get the image id of next image to load and run. */
40 image_id = bl1_plat_get_next_image_id();
41
42#if ENABLE_PAUTH
43 /*
44 * Disable pointer authentication before running next boot image
45 */
46 pauth_disable_el2();
47#endif /* ENABLE_PAUTH */
48
49#if !ARM_DISABLE_TRUSTED_WDOG
50 /* Disable watchdog before leaving BL1 */
51 plat_arm_secure_wdt_stop();
52#endif
53
54 bl1_run_next_image(&bl1_plat_get_image_desc(image_id)->ep_info);
55}
56
57/*******************************************************************************
58 * This function locates and loads the BL33 raw binary image in the trusted SRAM.
59 * Called by the primary cpu after a cold boot.
60 * TODO: Add support for alternative image load mechanism e.g using virtio/elf
61 * loader etc.
62 ******************************************************************************/
63void bl1_load_bl33(void)
64{
65 image_desc_t *desc;
66 image_info_t *info;
67 int err;
68
69 /* Get the image descriptor */
70 desc = bl1_plat_get_image_desc(BL33_IMAGE_ID);
71 assert(desc != NULL);
72
73 /* Get the image info */
74 info = &desc->image_info;
75 INFO("BL1: Loading BL33\n");
76
77 err = bl1_plat_handle_pre_image_load(BL33_IMAGE_ID);
78 if (err != 0) {
79 ERROR("Failure in pre image load handling of BL33 (%d)\n", err);
80 plat_error_handler(err);
81 }
82
83 err = load_auth_image(BL33_IMAGE_ID, info);
84 if (err != 0) {
85 ERROR("Failed to load BL33 firmware.\n");
86 plat_error_handler(err);
87 }
88
89 /* Allow platform to handle image information. */
90 err = bl1_plat_handle_post_image_load(BL33_IMAGE_ID);
91 if (err != 0) {
92 ERROR("Failure in post image load handling of BL33 (%d)\n", err);
93 plat_error_handler(err);
94 }
95
96 NOTICE("BL1: Booting BL33\n");
97}
98
Gary Morrison3d7f6542021-01-27 13:08:47 -060099static void bl1_load_bl2(void);
100
101#if ENABLE_PAUTH
102uint64_t bl1_apiakey[2];
103#endif
104
105/*******************************************************************************
106 * Helper utility to calculate the BL2 memory layout taking into consideration
107 * the BL1 RW data assuming that it is at the top of the memory layout.
108 ******************************************************************************/
109void bl1_calc_bl2_mem_layout(const meminfo_t *bl1_mem_layout,
110 meminfo_t *bl2_mem_layout)
111{
112 assert(bl1_mem_layout != NULL);
113 assert(bl2_mem_layout != NULL);
114
115 /*
116 * Remove BL1 RW data from the scope of memory visible to BL2.
117 * This is assuming BL1 RW data is at the top of bl1_mem_layout.
118 */
119 assert(bl1_mem_layout->total_base < BL1_RW_BASE);
120 bl2_mem_layout->total_base = bl1_mem_layout->total_base;
121 bl2_mem_layout->total_size = BL1_RW_BASE - bl1_mem_layout->total_base;
122
123 flush_dcache_range((uintptr_t)bl2_mem_layout, sizeof(meminfo_t));
124}
125
126/*******************************************************************************
127 * Setup function for BL1.
128 ******************************************************************************/
129void bl1_setup(void)
130{
131 /* Perform early platform-specific setup */
132 bl1_early_platform_setup();
133
134 /* Perform late platform-specific setup */
135 bl1_plat_arch_setup();
136
137#if CTX_INCLUDE_PAUTH_REGS
138 /*
139 * Assert that the ARMv8.3-PAuth registers are present or an access
140 * fault will be triggered when they are being saved or restored.
141 */
142 assert(is_armv8_3_pauth_present());
143#endif /* CTX_INCLUDE_PAUTH_REGS */
144}
145
146/*******************************************************************************
147 * Function to perform late architectural and platform specific initialization.
148 * It also queries the platform to load and run next BL image. Only called
149 * by the primary cpu after a cold boot.
150 ******************************************************************************/
151void bl1_main(void)
152{
153 unsigned int image_id;
154
155 /* Announce our arrival */
156 NOTICE(FIRMWARE_WELCOME_STR);
157 NOTICE("BL1: %s\n", version_string);
158 NOTICE("BL1: %s\n", build_message);
159
160 INFO("BL1: RAM %p - %p\n", (void *)BL1_RAM_BASE, (void *)BL1_RAM_LIMIT);
161
162 print_errata_status();
163
164#if ENABLE_ASSERTIONS
165 u_register_t val;
166 /*
167 * Ensure that MMU/Caches and coherency are turned on
168 */
169 val = read_sctlr_el2();
170
171 assert((val & SCTLR_M_BIT) != 0U);
172 assert((val & SCTLR_C_BIT) != 0U);
173 assert((val & SCTLR_I_BIT) != 0U);
174 /*
175 * Check that Cache Writeback Granule (CWG) in CTR_EL0 matches the
176 * provided platform value
177 */
178 val = (read_ctr_el0() >> CTR_CWG_SHIFT) & CTR_CWG_MASK;
179 /*
180 * If CWG is zero, then no CWG information is available but we can
181 * at least check the platform value is less than the architectural
182 * maximum.
183 */
184 if (val != 0) {
185 assert(SIZE_FROM_LOG2_WORDS(val) == CACHE_WRITEBACK_GRANULE);
186 } else {
laurenw-arm56f1e3e2021-03-03 14:19:38 -0600187 assert(MAX_CACHE_LINE_SIZE >= CACHE_WRITEBACK_GRANULE);
Gary Morrison3d7f6542021-01-27 13:08:47 -0600188 }
189#endif /* ENABLE_ASSERTIONS */
190
laurenw-arm56f1e3e2021-03-03 14:19:38 -0600191 /* Perform remaining generic architectural setup from ELmax */
Gary Morrison3d7f6542021-01-27 13:08:47 -0600192 bl1_arch_setup();
193
194#if TRUSTED_BOARD_BOOT
195 /* Initialize authentication module */
196 auth_mod_init();
197#endif /* TRUSTED_BOARD_BOOT */
198
199 /* Perform platform setup in BL1. */
200 bl1_platform_setup();
201
202#if ENABLE_PAUTH
203 /* Store APIAKey_EL1 key */
204 bl1_apiakey[0] = read_apiakeylo_el1();
205 bl1_apiakey[1] = read_apiakeyhi_el1();
206#endif /* ENABLE_PAUTH */
207
208 /* Get the image id of next image to load and run. */
209 image_id = bl1_plat_get_next_image_id();
210
211 /*
212 * We currently interpret any image id other than
213 * BL2_IMAGE_ID as the start of firmware update.
214 */
215 if (image_id == BL2_IMAGE_ID) {
216 bl1_load_bl2();
laurenw-arm56f1e3e2021-03-03 14:19:38 -0600217 } else if (image_id == BL33_IMAGE_ID) {
218 bl1_load_bl33();
Gary Morrison3d7f6542021-01-27 13:08:47 -0600219 } else {
220 NOTICE("BL1-FWU: *******FWU Process Started*******\n");
221 }
laurenw-arm56f1e3e2021-03-03 14:19:38 -0600222
Gary Morrison3d7f6542021-01-27 13:08:47 -0600223 bl1_prepare_next_image(image_id);
224
225 console_flush();
laurenw-arm56f1e3e2021-03-03 14:19:38 -0600226
227 bl1_transfer_bl33();
Gary Morrison3d7f6542021-01-27 13:08:47 -0600228}
229
230/*******************************************************************************
231 * This function locates and loads the BL2 raw binary image in the trusted SRAM.
232 * Called by the primary cpu after a cold boot.
233 * TODO: Add support for alternative image load mechanism e.g using virtio/elf
234 * loader etc.
235 ******************************************************************************/
236static void bl1_load_bl2(void)
237{
238 image_desc_t *desc;
239 image_info_t *info;
240 int err;
241
242 /* Get the image descriptor */
243 desc = bl1_plat_get_image_desc(BL2_IMAGE_ID);
244 assert(desc != NULL);
245
246 /* Get the image info */
247 info = &desc->image_info;
248 INFO("BL1: Loading BL2\n");
249
250 err = bl1_plat_handle_pre_image_load(BL2_IMAGE_ID);
251 if (err != 0) {
252 ERROR("Failure in pre image load handling of BL2 (%d)\n", err);
253 plat_error_handler(err);
254 }
255
256 err = load_auth_image(BL2_IMAGE_ID, info);
257 if (err != 0) {
258 ERROR("Failed to load BL2 firmware.\n");
259 plat_error_handler(err);
260 }
261
262 /* Allow platform to handle image information. */
263 err = bl1_plat_handle_post_image_load(BL2_IMAGE_ID);
264 if (err != 0) {
265 ERROR("Failure in post image load handling of BL2 (%d)\n", err);
266 plat_error_handler(err);
267 }
268
269 NOTICE("BL1: Booting BL2\n");
270}
271
272/*******************************************************************************
273 * Function called just before handing over to the next BL to inform the user
274 * about the boot progress. In debug mode, also print details about the BL
275 * image's execution context.
276 ******************************************************************************/
277void bl1_print_next_bl_ep_info(const entry_point_info_t *bl_ep_info)
278{
279 NOTICE("BL1: Booting BL31\n");
280 print_entry_point_info(bl_ep_info);
281}
282
283#if SPIN_ON_BL1_EXIT
284void print_debug_loop_message(void)
285{
286 NOTICE("BL1: Debug loop, spinning forever\n");
287 NOTICE("BL1: Please connect the debugger to continue\n");
288}
289#endif
290