2 * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
4 * SPDX-License-Identifier: BSD-3-Clause
9 #include <platform_def.h>
12 #include <arch_helpers.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 <plat/common/platform.h>
21 #include <smccc_helpers.h>
22 #include <tools_share/uuid.h>
24 #include "bl1_private.h"
26 /* BL1 Service UUID */
27 DEFINE_SVC_UUID2(bl1_svc_uid
,
28 0xd46739fd, 0xcb72, 0x9a4d, 0xb5, 0x75,
29 0x67, 0x15, 0xd6, 0xf4, 0xbb, 0x4a);
31 static void bl1_load_bl2(void);
33 /*******************************************************************************
34 * Helper utility to calculate the BL2 memory layout taking into consideration
35 * the BL1 RW data assuming that it is at the top of the memory layout.
36 ******************************************************************************/
37 void bl1_calc_bl2_mem_layout(const meminfo_t
*bl1_mem_layout
,
38 meminfo_t
*bl2_mem_layout
)
40 assert(bl1_mem_layout
!= NULL
);
41 assert(bl2_mem_layout
!= NULL
);
44 * Remove BL1 RW data from the scope of memory visible to BL2.
45 * This is assuming BL1 RW data is at the top of bl1_mem_layout.
47 assert(BL1_RW_BASE
> bl1_mem_layout
->total_base
);
48 bl2_mem_layout
->total_base
= bl1_mem_layout
->total_base
;
49 bl2_mem_layout
->total_size
= BL1_RW_BASE
- bl1_mem_layout
->total_base
;
51 flush_dcache_range((unsigned long)bl2_mem_layout
, sizeof(meminfo_t
));
54 /*******************************************************************************
55 * Function to perform late architectural and platform specific initialization.
56 * It also queries the platform to load and run next BL image. Only called
57 * by the primary cpu after a cold boot.
58 ******************************************************************************/
61 unsigned int image_id
;
63 /* Announce our arrival */
64 NOTICE(FIRMWARE_WELCOME_STR
);
65 NOTICE("BL1: %s\n", version_string
);
66 NOTICE("BL1: %s\n", build_message
);
68 INFO("BL1: RAM %p - %p\n", (void *)BL1_RAM_BASE
,
69 (void *)BL1_RAM_LIMIT
);
71 print_errata_status();
76 * Ensure that MMU/Caches and coherency are turned on
81 val
= read_sctlr_el3();
83 assert(val
& SCTLR_M_BIT
);
84 assert(val
& SCTLR_C_BIT
);
85 assert(val
& SCTLR_I_BIT
);
87 * Check that Cache Writeback Granule (CWG) in CTR_EL0 matches the
88 * provided platform value
90 val
= (read_ctr_el0() >> CTR_CWG_SHIFT
) & CTR_CWG_MASK
;
92 * If CWG is zero, then no CWG information is available but we can
93 * at least check the platform value is less than the architectural
97 assert(CACHE_WRITEBACK_GRANULE
== SIZE_FROM_LOG2_WORDS(val
));
99 assert(CACHE_WRITEBACK_GRANULE
<= MAX_CACHE_LINE_SIZE
);
100 #endif /* ENABLE_ASSERTIONS */
102 /* Perform remaining generic architectural setup from EL3 */
105 #if TRUSTED_BOARD_BOOT
106 /* Initialize authentication module */
108 #endif /* TRUSTED_BOARD_BOOT */
110 /* Perform platform setup in BL1. */
111 bl1_platform_setup();
113 /* Get the image id of next image to load and run. */
114 image_id
= bl1_plat_get_next_image_id();
117 * We currently interpret any image id other than
118 * BL2_IMAGE_ID as the start of firmware update.
120 if (image_id
== BL2_IMAGE_ID
)
123 NOTICE("BL1-FWU: *******FWU Process Started*******\n");
125 bl1_prepare_next_image(image_id
);
130 /*******************************************************************************
131 * This function locates and loads the BL2 raw binary image in the trusted SRAM.
132 * Called by the primary cpu after a cold boot.
133 * TODO: Add support for alternative image load mechanism e.g using virtio/elf
135 ******************************************************************************/
136 static void bl1_load_bl2(void)
138 image_desc_t
*image_desc
;
139 image_info_t
*image_info
;
142 /* Get the image descriptor */
143 image_desc
= bl1_plat_get_image_desc(BL2_IMAGE_ID
);
146 /* Get the image info */
147 image_info
= &image_desc
->image_info
;
148 INFO("BL1: Loading BL2\n");
150 err
= bl1_plat_handle_pre_image_load(BL2_IMAGE_ID
);
152 ERROR("Failure in pre image load handling of BL2 (%d)\n", err
);
153 plat_error_handler(err
);
156 err
= load_auth_image(BL2_IMAGE_ID
, image_info
);
158 ERROR("Failed to load BL2 firmware.\n");
159 plat_error_handler(err
);
162 /* Allow platform to handle image information. */
163 err
= bl1_plat_handle_post_image_load(BL2_IMAGE_ID
);
165 ERROR("Failure in post image load handling of BL2 (%d)\n", err
);
166 plat_error_handler(err
);
169 NOTICE("BL1: Booting BL2\n");
172 /*******************************************************************************
173 * Function called just before handing over to the next BL to inform the user
174 * about the boot progress. In debug mode, also print details about the BL
175 * image's execution context.
176 ******************************************************************************/
177 void bl1_print_next_bl_ep_info(const entry_point_info_t
*bl_ep_info
)
180 NOTICE("BL1: Booting BL32\n");
182 NOTICE("BL1: Booting BL31\n");
184 print_entry_point_info(bl_ep_info
);
188 void print_debug_loop_message(void)
190 NOTICE("BL1: Debug loop, spinning forever\n");
191 NOTICE("BL1: Please connect the debugger to continue\n");
195 /*******************************************************************************
196 * Top level handler for servicing BL1 SMCs.
197 ******************************************************************************/
198 register_t
bl1_smc_handler(unsigned int smc_fid
,
208 #if TRUSTED_BOARD_BOOT
210 * Dispatch FWU calls to FWU SMC handler and return its return
213 if (is_fwu_fid(smc_fid
)) {
214 return bl1_fwu_smc_handler(smc_fid
, x1
, x2
, x3
, x4
, cookie
,
220 case BL1_SMC_CALL_COUNT
:
221 SMC_RET1(handle
, BL1_NUM_SMC_CALLS
);
224 SMC_UUID_RET(handle
, bl1_svc_uid
);
226 case BL1_SMC_VERSION
:
227 SMC_RET1(handle
, BL1_SMC_MAJOR_VER
| BL1_SMC_MINOR_VER
);
233 WARN("Unimplemented BL1 SMC Call: 0x%x \n", smc_fid
);
234 SMC_RET1(handle
, SMC_UNK
);
237 /*******************************************************************************
238 * BL1 SMC wrapper. This function is only used in AArch32 mode to ensure ABI
239 * compliance when invoking bl1_smc_handler.
240 ******************************************************************************/
241 register_t
bl1_smc_wrapper(uint32_t smc_fid
,
246 register_t x1
, x2
, x3
, x4
;
250 get_smc_params_from_ctx(handle
, x1
, x2
, x3
, x4
);
251 return bl1_smc_handler(smc_fid
, x1
, x2
, x3
, x4
, cookie
, handle
, flags
);