blob: 85d90686f68043eae0b1eeb1136dd0412c3cabb9 [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Stefano Babic83fd8582013-06-28 00:20:21 +02002/*
Ulises Cardenas8df2acd2015-07-02 21:26:30 -05003 * Copyright (C) 2010-2015 Freescale Semiconductor, Inc.
Stefano Babic83fd8582013-06-28 00:20:21 +02004 */
5
Simon Glassed38aef2020-05-10 11:40:03 -06006#include <command.h>
Adrian Alonso1f3029f2015-10-12 13:48:14 -05007#include <config.h>
Simon Glass1ab16922022-07-31 12:28:48 -06008#include <display_options.h>
Adrian Alonso1f3029f2015-10-12 13:48:14 -05009#include <fuse.h>
Parthiban Nallathambi2c88aa62018-11-21 14:50:40 +010010#include <mapmem.h>
11#include <image.h>
Stefano Babic83fd8582013-06-28 00:20:21 +020012#include <asm/io.h>
Peng Fan4f3cf8f2021-03-25 17:30:07 +080013#include <asm/global_data.h>
Nitin Gargb1ce7012014-09-16 13:33:25 -050014#include <asm/system.h>
Nitin Gargb1ce7012014-09-16 13:33:25 -050015#include <asm/arch/clock.h>
Stefano Babic14404422014-06-10 10:26:22 +020016#include <asm/arch/sys_proto.h>
Stefano Babic33731bc2017-06-29 10:16:06 +020017#include <asm/mach-imx/hab.h>
Peng Fan4f3cf8f2021-03-25 17:30:07 +080018#include <linux/arm-smccc.h>
19
20DECLARE_GLOBAL_DATA_PTR;
Stefano Babic83fd8582013-06-28 00:20:21 +020021
Nitin Gargb1ce7012014-09-16 13:33:25 -050022#define ALIGN_SIZE 0x1000
Nitin Gargb1ce7012014-09-16 13:33:25 -050023#define MX6DQ_PU_IROM_MMU_EN_VAR 0x009024a8
24#define MX6DLS_PU_IROM_MMU_EN_VAR 0x00901dd0
Breno Matheus Lima25d93482019-05-07 20:19:17 +000025#define MX6SL_PU_IROM_MMU_EN_VAR 0x00901c60
Adrian Alonso00a0b562015-10-12 13:48:15 -050026#define IS_HAB_ENABLED_BIT \
Peng Fana26ba6d2017-02-22 16:21:53 +080027 (is_soc_type(MXC_SOC_MX7ULP) ? 0x80000000 : \
Peng Fan4f3cf8f2021-03-25 17:30:07 +080028 ((is_soc_type(MXC_SOC_MX7) || is_soc_type(MXC_SOC_IMX8M)) ? 0x2000000 : 0x2))
Nitin Gargb1ce7012014-09-16 13:33:25 -050029
Breno Lima3adb6f02021-03-25 17:30:13 +080030#ifdef CONFIG_MX7ULP
31#define HAB_M4_PERSISTENT_START ((soc_rev() >= CHIP_REV_2_0) ? 0x20008040 : \
32 0x20008180)
33#define HAB_M4_PERSISTENT_BYTES 0xB80
34#endif
35
Bryan O'Donoghue5ee19b32018-01-12 12:40:03 +000036static int ivt_header_error(const char *err_str, struct ivt_header *ivt_hdr)
37{
38 printf("%s magic=0x%x length=0x%02x version=0x%x\n", err_str,
39 ivt_hdr->magic, ivt_hdr->length, ivt_hdr->version);
40
41 return 1;
42}
43
44static int verify_ivt_header(struct ivt_header *ivt_hdr)
45{
46 int result = 0;
47
48 if (ivt_hdr->magic != IVT_HEADER_MAGIC)
49 result = ivt_header_error("bad magic", ivt_hdr);
50
51 if (be16_to_cpu(ivt_hdr->length) != IVT_TOTAL_LENGTH)
52 result = ivt_header_error("bad length", ivt_hdr);
53
Breno Limad03a4d32021-03-25 17:30:12 +080054 if ((ivt_hdr->version & HAB_MAJ_MASK) != HAB_MAJ_VER)
Bryan O'Donoghue5ee19b32018-01-12 12:40:03 +000055 result = ivt_header_error("bad version", ivt_hdr);
56
57 return result;
58}
59
Peng Fan4f3cf8f2021-03-25 17:30:07 +080060#ifdef CONFIG_ARM64
61#define FSL_SIP_HAB 0xC2000007
62#define FSL_SIP_HAB_AUTHENTICATE 0x00
63#define FSL_SIP_HAB_ENTRY 0x01
64#define FSL_SIP_HAB_EXIT 0x02
65#define FSL_SIP_HAB_REPORT_EVENT 0x03
66#define FSL_SIP_HAB_REPORT_STATUS 0x04
67#define FSL_SIP_HAB_FAILSAFE 0x05
68#define FSL_SIP_HAB_CHECK_TARGET 0x06
69static volatile gd_t *gd_save;
70#endif
71
72static inline void save_gd(void)
73{
74#ifdef CONFIG_ARM64
75 gd_save = gd;
76#endif
77}
78
79static inline void restore_gd(void)
80{
81#ifdef CONFIG_ARM64
82 /*
83 * Make will already error that reserving x18 is not supported at the
84 * time of writing, clang: error: unknown argument: '-ffixed-x18'
85 */
86 __asm__ volatile("mov x18, %0\n" : : "r" (gd_save));
87#endif
88}
89
90enum hab_status hab_rvt_report_event(enum hab_status status, u32 index,
91 u8 *event, size_t *bytes)
92{
93 enum hab_status ret;
94 hab_rvt_report_event_t *hab_rvt_report_event_func;
95 struct arm_smccc_res res __maybe_unused;
96
97 hab_rvt_report_event_func = (hab_rvt_report_event_t *)HAB_RVT_REPORT_EVENT;
98#if defined(CONFIG_ARM64)
99 if (current_el() != 3) {
100 /* call sip */
101 arm_smccc_smc(FSL_SIP_HAB, FSL_SIP_HAB_REPORT_EVENT, (unsigned long)index,
102 (unsigned long)event, (unsigned long)bytes, 0, 0, 0, &res);
103 return (enum hab_status)res.a0;
104 }
105#endif
106
107 save_gd();
108 ret = hab_rvt_report_event_func(status, index, event, bytes);
109 restore_gd();
110
111 return ret;
112
113}
114
115enum hab_status hab_rvt_report_status(enum hab_config *config, enum hab_state *state)
116{
117 enum hab_status ret;
118 hab_rvt_report_status_t *hab_rvt_report_status_func;
119 struct arm_smccc_res res __maybe_unused;
120
121 hab_rvt_report_status_func = (hab_rvt_report_status_t *)HAB_RVT_REPORT_STATUS;
122#if defined(CONFIG_ARM64)
123 if (current_el() != 3) {
124 /* call sip */
125 arm_smccc_smc(FSL_SIP_HAB, FSL_SIP_HAB_REPORT_STATUS, (unsigned long)config,
126 (unsigned long)state, 0, 0, 0, 0, &res);
127 return (enum hab_status)res.a0;
128 }
129#endif
130
131 save_gd();
132 ret = hab_rvt_report_status_func(config, state);
133 restore_gd();
134
135 return ret;
136}
137
138enum hab_status hab_rvt_entry(void)
139{
140 enum hab_status ret;
141 hab_rvt_entry_t *hab_rvt_entry_func;
142 struct arm_smccc_res res __maybe_unused;
143
144 hab_rvt_entry_func = (hab_rvt_entry_t *)HAB_RVT_ENTRY;
145#if defined(CONFIG_ARM64)
146 if (current_el() != 3) {
147 /* call sip */
148 arm_smccc_smc(FSL_SIP_HAB, FSL_SIP_HAB_ENTRY, 0, 0, 0, 0, 0, 0, &res);
149 return (enum hab_status)res.a0;
150 }
151#endif
152
153 save_gd();
154 ret = hab_rvt_entry_func();
155 restore_gd();
156
157 return ret;
158}
159
160enum hab_status hab_rvt_exit(void)
161{
162 enum hab_status ret;
163 hab_rvt_exit_t *hab_rvt_exit_func;
164 struct arm_smccc_res res __maybe_unused;
165
166 hab_rvt_exit_func = (hab_rvt_exit_t *)HAB_RVT_EXIT;
167#if defined(CONFIG_ARM64)
168 if (current_el() != 3) {
169 /* call sip */
170 arm_smccc_smc(FSL_SIP_HAB, FSL_SIP_HAB_EXIT, 0, 0, 0, 0, 0, 0, &res);
171 return (enum hab_status)res.a0;
172 }
173#endif
174
175 save_gd();
176 ret = hab_rvt_exit_func();
177 restore_gd();
178
179 return ret;
180}
181
182void hab_rvt_failsafe(void)
183{
184 hab_rvt_failsafe_t *hab_rvt_failsafe_func;
185
186 hab_rvt_failsafe_func = (hab_rvt_failsafe_t *)HAB_RVT_FAILSAFE;
187#if defined(CONFIG_ARM64)
188 if (current_el() != 3) {
189 /* call sip */
190 arm_smccc_smc(FSL_SIP_HAB, FSL_SIP_HAB_FAILSAFE, 0, 0, 0, 0, 0, 0, NULL);
191 return;
192 }
193#endif
194
195 save_gd();
196 hab_rvt_failsafe_func();
197 restore_gd();
198}
199
200enum hab_status hab_rvt_check_target(enum hab_target type, const void *start,
201 size_t bytes)
202{
203 enum hab_status ret;
204 hab_rvt_check_target_t *hab_rvt_check_target_func;
205 struct arm_smccc_res res __maybe_unused;
206
207 hab_rvt_check_target_func = (hab_rvt_check_target_t *)HAB_RVT_CHECK_TARGET;
208#if defined(CONFIG_ARM64)
209 if (current_el() != 3) {
210 /* call sip */
211 arm_smccc_smc(FSL_SIP_HAB, FSL_SIP_HAB_CHECK_TARGET, (unsigned long)type,
212 (unsigned long)start, (unsigned long)bytes, 0, 0, 0, &res);
213 return (enum hab_status)res.a0;
214 }
215#endif
216
217 save_gd();
218 ret = hab_rvt_check_target_func(type, start, bytes);
219 restore_gd();
220
221 return ret;
222}
223
224void *hab_rvt_authenticate_image(uint8_t cid, ptrdiff_t ivt_offset,
225 void **start, size_t *bytes, hab_loader_callback_f_t loader)
226{
227 void *ret;
228 hab_rvt_authenticate_image_t *hab_rvt_authenticate_image_func;
229 struct arm_smccc_res res __maybe_unused;
230
231 hab_rvt_authenticate_image_func = (hab_rvt_authenticate_image_t *)HAB_RVT_AUTHENTICATE_IMAGE;
232#if defined(CONFIG_ARM64)
233 if (current_el() != 3) {
234 /* call sip */
235 arm_smccc_smc(FSL_SIP_HAB, FSL_SIP_HAB_AUTHENTICATE, (unsigned long)ivt_offset,
236 (unsigned long)start, (unsigned long)bytes, 0, 0, 0, &res);
237 return (void *)res.a0;
238 }
239#endif
240
241 save_gd();
242 ret = hab_rvt_authenticate_image_func(cid, ivt_offset, start, bytes, loader);
243 restore_gd();
244
245 return ret;
246}
247
Sven Ebenfeldeba5e332016-11-06 16:37:55 +0100248#if !defined(CONFIG_SPL_BUILD)
249
Ulises Cardenas8df2acd2015-07-02 21:26:30 -0500250#define MAX_RECORD_BYTES (8*1024) /* 4 kbytes */
251
252struct record {
253 uint8_t tag; /* Tag */
254 uint8_t len[2]; /* Length */
255 uint8_t par; /* Version */
256 uint8_t contents[MAX_RECORD_BYTES];/* Record Data */
257 bool any_rec_flag;
258};
259
Bryan O'Donoghuee92a5f92018-01-12 12:40:12 +0000260static char *rsn_str[] = {
261 "RSN = HAB_RSN_ANY (0x00)\n",
262 "RSN = HAB_ENG_FAIL (0x30)\n",
263 "RSN = HAB_INV_ADDRESS (0x22)\n",
264 "RSN = HAB_INV_ASSERTION (0x0C)\n",
265 "RSN = HAB_INV_CALL (0x28)\n",
266 "RSN = HAB_INV_CERTIFICATE (0x21)\n",
267 "RSN = HAB_INV_COMMAND (0x06)\n",
268 "RSN = HAB_INV_CSF (0x11)\n",
269 "RSN = HAB_INV_DCD (0x27)\n",
270 "RSN = HAB_INV_INDEX (0x0F)\n",
271 "RSN = HAB_INV_IVT (0x05)\n",
272 "RSN = HAB_INV_KEY (0x1D)\n",
273 "RSN = HAB_INV_RETURN (0x1E)\n",
274 "RSN = HAB_INV_SIGNATURE (0x18)\n",
275 "RSN = HAB_INV_SIZE (0x17)\n",
276 "RSN = HAB_MEM_FAIL (0x2E)\n",
277 "RSN = HAB_OVR_COUNT (0x2B)\n",
278 "RSN = HAB_OVR_STORAGE (0x2D)\n",
279 "RSN = HAB_UNS_ALGORITHM (0x12)\n",
280 "RSN = HAB_UNS_COMMAND (0x03)\n",
281 "RSN = HAB_UNS_ENGINE (0x0A)\n",
282 "RSN = HAB_UNS_ITEM (0x24)\n",
283 "RSN = HAB_UNS_KEY (0x1B)\n",
284 "RSN = HAB_UNS_PROTOCOL (0x14)\n",
285 "RSN = HAB_UNS_STATE (0x09)\n",
286 "RSN = INVALID\n",
287 NULL
288};
Ulises Cardenas8df2acd2015-07-02 21:26:30 -0500289
Bryan O'Donoghuee92a5f92018-01-12 12:40:12 +0000290static char *sts_str[] = {
Ye Li236ef9d2023-06-15 18:09:15 +0800291 "STS = HAB_STS_ANY (0x00)\n",
Bryan O'Donoghuee92a5f92018-01-12 12:40:12 +0000292 "STS = HAB_FAILURE (0x33)\n",
293 "STS = HAB_WARNING (0x69)\n",
Ye Li236ef9d2023-06-15 18:09:15 +0800294 "STS = HAB_SUCCESS (0xF0)\n",
Bryan O'Donoghuee92a5f92018-01-12 12:40:12 +0000295 "STS = INVALID\n",
296 NULL
297};
Ulises Cardenas8df2acd2015-07-02 21:26:30 -0500298
Bryan O'Donoghuee92a5f92018-01-12 12:40:12 +0000299static char *eng_str[] = {
300 "ENG = HAB_ENG_ANY (0x00)\n",
301 "ENG = HAB_ENG_SCC (0x03)\n",
302 "ENG = HAB_ENG_RTIC (0x05)\n",
303 "ENG = HAB_ENG_SAHARA (0x06)\n",
304 "ENG = HAB_ENG_CSU (0x0A)\n",
305 "ENG = HAB_ENG_SRTC (0x0C)\n",
306 "ENG = HAB_ENG_DCP (0x1B)\n",
307 "ENG = HAB_ENG_CAAM (0x1D)\n",
308 "ENG = HAB_ENG_SNVS (0x1E)\n",
309 "ENG = HAB_ENG_OCOTP (0x21)\n",
310 "ENG = HAB_ENG_DTCP (0x22)\n",
311 "ENG = HAB_ENG_ROM (0x36)\n",
312 "ENG = HAB_ENG_HDCP (0x24)\n",
313 "ENG = HAB_ENG_RTL (0x77)\n",
314 "ENG = HAB_ENG_SW (0xFF)\n",
315 "ENG = INVALID\n",
316 NULL
317};
Ulises Cardenas8df2acd2015-07-02 21:26:30 -0500318
Bryan O'Donoghuee92a5f92018-01-12 12:40:12 +0000319static char *ctx_str[] = {
320 "CTX = HAB_CTX_ANY(0x00)\n",
321 "CTX = HAB_CTX_FAB (0xFF)\n",
322 "CTX = HAB_CTX_ENTRY (0xE1)\n",
323 "CTX = HAB_CTX_TARGET (0x33)\n",
324 "CTX = HAB_CTX_AUTHENTICATE (0x0A)\n",
325 "CTX = HAB_CTX_DCD (0xDD)\n",
326 "CTX = HAB_CTX_CSF (0xCF)\n",
327 "CTX = HAB_CTX_COMMAND (0xC0)\n",
328 "CTX = HAB_CTX_AUT_DAT (0xDB)\n",
329 "CTX = HAB_CTX_ASSERT (0xA0)\n",
330 "CTX = HAB_CTX_EXIT (0xEE)\n",
331 "CTX = INVALID\n",
332 NULL
333};
Ulises Cardenas8df2acd2015-07-02 21:26:30 -0500334
Bryan O'Donoghuee92a5f92018-01-12 12:40:12 +0000335static uint8_t hab_statuses[5] = {
Ulises Cardenas8df2acd2015-07-02 21:26:30 -0500336 HAB_STS_ANY,
337 HAB_FAILURE,
338 HAB_WARNING,
Ye Li236ef9d2023-06-15 18:09:15 +0800339 HAB_SUCCESS
Ulises Cardenas8df2acd2015-07-02 21:26:30 -0500340};
341
Bryan O'Donoghuee92a5f92018-01-12 12:40:12 +0000342static uint8_t hab_reasons[26] = {
Ulises Cardenas8df2acd2015-07-02 21:26:30 -0500343 HAB_RSN_ANY,
344 HAB_ENG_FAIL,
345 HAB_INV_ADDRESS,
346 HAB_INV_ASSERTION,
347 HAB_INV_CALL,
348 HAB_INV_CERTIFICATE,
349 HAB_INV_COMMAND,
350 HAB_INV_CSF,
351 HAB_INV_DCD,
352 HAB_INV_INDEX,
353 HAB_INV_IVT,
354 HAB_INV_KEY,
355 HAB_INV_RETURN,
356 HAB_INV_SIGNATURE,
357 HAB_INV_SIZE,
358 HAB_MEM_FAIL,
359 HAB_OVR_COUNT,
360 HAB_OVR_STORAGE,
361 HAB_UNS_ALGORITHM,
362 HAB_UNS_COMMAND,
363 HAB_UNS_ENGINE,
364 HAB_UNS_ITEM,
365 HAB_UNS_KEY,
366 HAB_UNS_PROTOCOL,
Ye Li236ef9d2023-06-15 18:09:15 +0800367 HAB_UNS_STATE
Ulises Cardenas8df2acd2015-07-02 21:26:30 -0500368};
369
Bryan O'Donoghuee92a5f92018-01-12 12:40:12 +0000370static uint8_t hab_contexts[12] = {
Ulises Cardenas8df2acd2015-07-02 21:26:30 -0500371 HAB_CTX_ANY,
372 HAB_CTX_FAB,
373 HAB_CTX_ENTRY,
374 HAB_CTX_TARGET,
375 HAB_CTX_AUTHENTICATE,
376 HAB_CTX_DCD,
377 HAB_CTX_CSF,
378 HAB_CTX_COMMAND,
379 HAB_CTX_AUT_DAT,
380 HAB_CTX_ASSERT,
Ye Li236ef9d2023-06-15 18:09:15 +0800381 HAB_CTX_EXIT
Ulises Cardenas8df2acd2015-07-02 21:26:30 -0500382};
383
Bryan O'Donoghuee92a5f92018-01-12 12:40:12 +0000384static uint8_t hab_engines[16] = {
Ulises Cardenas8df2acd2015-07-02 21:26:30 -0500385 HAB_ENG_ANY,
386 HAB_ENG_SCC,
387 HAB_ENG_RTIC,
388 HAB_ENG_SAHARA,
389 HAB_ENG_CSU,
390 HAB_ENG_SRTC,
391 HAB_ENG_DCP,
392 HAB_ENG_CAAM,
393 HAB_ENG_SNVS,
394 HAB_ENG_OCOTP,
395 HAB_ENG_DTCP,
396 HAB_ENG_ROM,
397 HAB_ENG_HDCP,
398 HAB_ENG_RTL,
Ye Li236ef9d2023-06-15 18:09:15 +0800399 HAB_ENG_SW
Ulises Cardenas8df2acd2015-07-02 21:26:30 -0500400};
401
Ye Li236ef9d2023-06-15 18:09:15 +0800402static inline u32 get_idx(u8 *list, u8 tgt, u32 size)
Ulises Cardenas8df2acd2015-07-02 21:26:30 -0500403{
Ye Li236ef9d2023-06-15 18:09:15 +0800404 u32 idx = 0;
405 u8 element;
406
407 while (idx < size) {
408 element = list[idx];
Ulises Cardenas8df2acd2015-07-02 21:26:30 -0500409 if (element == tgt)
410 return idx;
Ye Li236ef9d2023-06-15 18:09:15 +0800411 ++idx;
Ulises Cardenas8df2acd2015-07-02 21:26:30 -0500412 }
Ye Li236ef9d2023-06-15 18:09:15 +0800413 return idx;
Ulises Cardenas8df2acd2015-07-02 21:26:30 -0500414}
415
Bryan O'Donoghuee92a5f92018-01-12 12:40:12 +0000416static void process_event_record(uint8_t *event_data, size_t bytes)
Ulises Cardenas8df2acd2015-07-02 21:26:30 -0500417{
418 struct record *rec = (struct record *)event_data;
419
Ye Li236ef9d2023-06-15 18:09:15 +0800420 printf("\n\n%s", sts_str[get_idx(hab_statuses, rec->contents[0],
421 ARRAY_SIZE(hab_statuses))]);
422 printf("%s", rsn_str[get_idx(hab_reasons, rec->contents[1],
423 ARRAY_SIZE(hab_reasons))]);
424 printf("%s", ctx_str[get_idx(hab_contexts, rec->contents[2],
425 ARRAY_SIZE(hab_contexts))]);
426 printf("%s", eng_str[get_idx(hab_engines, rec->contents[3],
427 ARRAY_SIZE(hab_engines))]);
Ulises Cardenas8df2acd2015-07-02 21:26:30 -0500428}
429
Bryan O'Donoghuee92a5f92018-01-12 12:40:12 +0000430static void display_event(uint8_t *event_data, size_t bytes)
Stefano Babic83fd8582013-06-28 00:20:21 +0200431{
432 uint32_t i;
433
434 if (!(event_data && bytes > 0))
435 return;
436
437 for (i = 0; i < bytes; i++) {
438 if (i == 0)
439 printf("\t0x%02x", event_data[i]);
440 else if ((i % 8) == 0)
441 printf("\n\t0x%02x", event_data[i]);
442 else
443 printf(" 0x%02x", event_data[i]);
444 }
Ulises Cardenas8df2acd2015-07-02 21:26:30 -0500445
446 process_event_record(event_data, bytes);
Stefano Babic83fd8582013-06-28 00:20:21 +0200447}
448
Bryan O'Donoghuee92a5f92018-01-12 12:40:12 +0000449static int get_hab_status(void)
Stefano Babic83fd8582013-06-28 00:20:21 +0200450{
451 uint32_t index = 0; /* Loop index */
452 uint8_t event_data[128]; /* Event data buffer */
453 size_t bytes = sizeof(event_data); /* Event size in bytes */
454 enum hab_config config = 0;
455 enum hab_state state = 0;
Stefano Babic83fd8582013-06-28 00:20:21 +0200456
Bryan O'Donoghue899cab02018-01-12 12:40:14 +0000457 if (imx_hab_is_enabled())
Stefano Babic83fd8582013-06-28 00:20:21 +0200458 puts("\nSecure boot enabled\n");
459 else
460 puts("\nSecure boot disabled\n");
461
462 /* Check HAB status */
463 if (hab_rvt_report_status(&config, &state) != HAB_SUCCESS) {
464 printf("\nHAB Configuration: 0x%02x, HAB State: 0x%02x\n",
465 config, state);
466
Utkarsh Gupta1115bed2021-03-25 17:30:11 +0800467 /* Display HAB events */
468 while (hab_rvt_report_event(HAB_STS_ANY, index, event_data,
Stefano Babic83fd8582013-06-28 00:20:21 +0200469 &bytes) == HAB_SUCCESS) {
470 puts("\n");
471 printf("--------- HAB Event %d -----------------\n",
472 index + 1);
473 puts("event data:\n");
474 display_event(event_data, bytes);
475 puts("\n");
476 bytes = sizeof(event_data);
477 index++;
478 }
479 }
480 /* Display message if no HAB events are found */
481 else {
482 printf("\nHAB Configuration: 0x%02x, HAB State: 0x%02x\n",
483 config, state);
484 puts("No HAB Events Found!\n\n");
485 }
486 return 0;
487}
488
Breno Lima3adb6f02021-03-25 17:30:13 +0800489#ifdef CONFIG_MX7ULP
490
491static int get_record_len(struct record *rec)
492{
493 return (size_t)((rec->len[0] << 8) + (rec->len[1]));
494}
495
496static int get_hab_status_m4(void)
497{
498 unsigned int index = 0;
499 uint8_t event_data[128];
500 size_t record_len, offset = 0;
501 enum hab_config config = 0;
502 enum hab_state state = 0;
503
504 if (imx_hab_is_enabled())
505 puts("\nSecure boot enabled\n");
506 else
507 puts("\nSecure boot disabled\n");
508
509 /*
510 * HAB in both A7 and M4 gather the security state
511 * and configuration of the chip from
512 * shared SNVS module
513 */
514 hab_rvt_report_status(&config, &state);
515 printf("\nHAB Configuration: 0x%02x, HAB State: 0x%02x\n",
516 config, state);
517
518 struct record *rec = (struct record *)(HAB_M4_PERSISTENT_START);
519
520 record_len = get_record_len(rec);
521
522 /* Check if HAB persistent memory is valid */
523 if (rec->tag != HAB_TAG_EVT_DEF ||
524 record_len != sizeof(struct evt_def) ||
525 (rec->par & HAB_MAJ_MASK) != HAB_MAJ_VER) {
526 puts("\nERROR: Invalid HAB persistent memory\n");
527 return 1;
528 }
529
530 /* Parse events in HAB M4 persistent memory region */
531 while (offset < HAB_M4_PERSISTENT_BYTES) {
532 rec = (struct record *)(HAB_M4_PERSISTENT_START + offset);
533
534 record_len = get_record_len(rec);
535
536 if (rec->tag == HAB_TAG_EVT) {
537 memcpy(&event_data, rec, record_len);
538 puts("\n");
539 printf("--------- HAB Event %d -----------------\n",
540 index + 1);
541 puts("event data:\n");
542 display_event(event_data, record_len);
543 puts("\n");
544 index++;
545 }
546
547 offset += record_len;
548
549 /* Ensure all records start on a word boundary */
550 if ((offset % 4) != 0)
551 offset = offset + (4 - (offset % 4));
552 }
553
554 if (!index)
555 puts("No HAB Events Found!\n\n");
556
557 return 0;
558}
559#endif
560
Simon Glassed38aef2020-05-10 11:40:03 -0600561static int do_hab_status(struct cmd_tbl *cmdtp, int flag, int argc,
562 char *const argv[])
Sven Ebenfeldeba5e332016-11-06 16:37:55 +0100563{
Breno Lima3adb6f02021-03-25 17:30:13 +0800564#ifdef CONFIG_MX7ULP
565 if ((argc > 2)) {
566 cmd_usage(cmdtp);
567 return 1;
568 }
569
570 if (strcmp("m4", argv[1]) == 0)
571 get_hab_status_m4();
572 else
573 get_hab_status();
574#else
Sven Ebenfeldeba5e332016-11-06 16:37:55 +0100575 if ((argc != 1)) {
576 cmd_usage(cmdtp);
577 return 1;
578 }
579
580 get_hab_status();
Breno Lima3adb6f02021-03-25 17:30:13 +0800581#endif
Sven Ebenfeldeba5e332016-11-06 16:37:55 +0100582
583 return 0;
584}
585
Parthiban Nallathambi2c88aa62018-11-21 14:50:40 +0100586static ulong get_image_ivt_offset(ulong img_addr)
587{
588 const void *buf;
589
590 buf = map_sysmem(img_addr, 0);
591 switch (genimg_get_format(buf)) {
Tom Rinic220bd92019-05-23 07:14:07 -0400592#if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT)
Parthiban Nallathambi2c88aa62018-11-21 14:50:40 +0100593 case IMAGE_FORMAT_LEGACY:
Simon Glassbb7d3bb2022-09-06 20:26:52 -0600594 return (image_get_image_size((struct legacy_img_hdr *)img_addr)
Parthiban Nallathambi2c88aa62018-11-21 14:50:40 +0100595 + 0x1000 - 1) & ~(0x1000 - 1);
596#endif
Simon Glasse719d3b2021-09-25 19:43:20 -0600597#if CONFIG_IS_ENABLED(FIT)
Parthiban Nallathambi2c88aa62018-11-21 14:50:40 +0100598 case IMAGE_FORMAT_FIT:
599 return (fit_get_size(buf) + 0x1000 - 1) & ~(0x1000 - 1);
600#endif
601 default:
602 return 0;
603 }
604}
605
Simon Glassed38aef2020-05-10 11:40:03 -0600606static int do_authenticate_image(struct cmd_tbl *cmdtp, int flag, int argc,
607 char *const argv[])
Sven Ebenfeldeba5e332016-11-06 16:37:55 +0100608{
Bryan O'Donoghue88919962018-01-12 12:40:01 +0000609 ulong addr, length, ivt_offset;
Sven Ebenfeldeba5e332016-11-06 16:37:55 +0100610 int rcode = 0;
611
Parthiban Nallathambi2c88aa62018-11-21 14:50:40 +0100612 if (argc < 3)
Sven Ebenfeldeba5e332016-11-06 16:37:55 +0100613 return CMD_RET_USAGE;
614
Simon Glass3ff49ec2021-07-24 09:03:29 -0600615 addr = hextoul(argv[1], NULL);
616 length = hextoul(argv[2], NULL);
Parthiban Nallathambi2c88aa62018-11-21 14:50:40 +0100617 if (argc == 3)
618 ivt_offset = get_image_ivt_offset(addr);
619 else
Simon Glass3ff49ec2021-07-24 09:03:29 -0600620 ivt_offset = hextoul(argv[3], NULL);
Sven Ebenfeldeba5e332016-11-06 16:37:55 +0100621
Bryan O'Donoghue1efba6a2018-01-12 12:40:13 +0000622 rcode = imx_hab_authenticate_image(addr, length, ivt_offset);
Bryan O'Donoghue79987a12018-01-12 12:39:56 +0000623 if (rcode == 0)
624 rcode = CMD_RET_SUCCESS;
625 else
626 rcode = CMD_RET_FAILURE;
Bryan O'Donoghue88919962018-01-12 12:40:01 +0000627
Sven Ebenfeldeba5e332016-11-06 16:37:55 +0100628 return rcode;
629}
630
Simon Glassed38aef2020-05-10 11:40:03 -0600631static int do_hab_failsafe(struct cmd_tbl *cmdtp, int flag, int argc,
632 char *const argv[])
Bryan O'Donoghuefaa15022018-01-12 12:40:19 +0000633{
Bryan O'Donoghuefaa15022018-01-12 12:40:19 +0000634 if (argc != 1) {
635 cmd_usage(cmdtp);
636 return 1;
637 }
638
Bryan O'Donoghuefaa15022018-01-12 12:40:19 +0000639 hab_rvt_failsafe();
640
641 return 0;
642}
643
Simon Glassed38aef2020-05-10 11:40:03 -0600644static int do_hab_version(struct cmd_tbl *cmdtp, int flag, int argc,
645 char *const argv[])
Sjoerd Simons27f3fae2019-06-18 23:08:59 +0200646{
647 struct hab_hdr *hdr = (struct hab_hdr *)HAB_RVT_BASE;
648
649 if (hdr->tag != HAB_TAG_RVT) {
650 printf("Unexpected header tag: %x\n", hdr->tag);
651 return CMD_RET_FAILURE;
652 }
653
654 printf("HAB version: %d.%d\n", hdr->par >> 4, hdr->par & 0xf);
655
656 return 0;
657}
658
Simon Glassed38aef2020-05-10 11:40:03 -0600659static int do_authenticate_image_or_failover(struct cmd_tbl *cmdtp, int flag,
660 int argc, char *const argv[])
Bryan O'Donoghue933092f2018-03-26 15:36:46 +0100661{
662 int ret = CMD_RET_FAILURE;
663
Eduard Strehlau3552d662023-09-06 22:47:25 -0300664 if (argc < 3) {
Bryan O'Donoghue933092f2018-03-26 15:36:46 +0100665 ret = CMD_RET_USAGE;
666 goto error;
667 }
668
669 if (!imx_hab_is_enabled()) {
670 printf("error: secure boot disabled\n");
671 goto error;
672 }
673
674 if (do_authenticate_image(NULL, flag, argc, argv) != CMD_RET_SUCCESS) {
675 fprintf(stderr, "authentication fail -> %s %s %s %s\n",
676 argv[0], argv[1], argv[2], argv[3]);
677 do_hab_failsafe(0, 0, 1, NULL);
678 };
679 ret = CMD_RET_SUCCESS;
680error:
681 return ret;
682}
683
Breno Lima3adb6f02021-03-25 17:30:13 +0800684#ifdef CONFIG_MX7ULP
685U_BOOT_CMD(
686 hab_status, CONFIG_SYS_MAXARGS, 2, do_hab_status,
687 "display HAB status and events",
688 "hab_status - A7 HAB event and status\n"
689 "hab_status m4 - M4 HAB event and status"
690 );
691#else
Sven Ebenfeldeba5e332016-11-06 16:37:55 +0100692U_BOOT_CMD(
693 hab_status, CONFIG_SYS_MAXARGS, 1, do_hab_status,
694 "display HAB status",
695 ""
696 );
Breno Lima3adb6f02021-03-25 17:30:13 +0800697#endif
Sven Ebenfeldeba5e332016-11-06 16:37:55 +0100698
699U_BOOT_CMD(
Bryan O'Donoghue88919962018-01-12 12:40:01 +0000700 hab_auth_img, 4, 0, do_authenticate_image,
Sven Ebenfeldeba5e332016-11-06 16:37:55 +0100701 "authenticate image via HAB",
Bryan O'Donoghue88919962018-01-12 12:40:01 +0000702 "addr length ivt_offset\n"
Sven Ebenfeldeba5e332016-11-06 16:37:55 +0100703 "addr - image hex address\n"
Bryan O'Donoghue88919962018-01-12 12:40:01 +0000704 "length - image hex length\n"
Fabio Estevam76cda332023-09-06 22:47:27 -0300705 "ivt_offset - hex offset of IVT in the image (optional)"
Sven Ebenfeldeba5e332016-11-06 16:37:55 +0100706 );
707
Bryan O'Donoghuefaa15022018-01-12 12:40:19 +0000708U_BOOT_CMD(
709 hab_failsafe, CONFIG_SYS_MAXARGS, 1, do_hab_failsafe,
710 "run BootROM failsafe routine",
711 ""
712 );
Sven Ebenfeldeba5e332016-11-06 16:37:55 +0100713
Bryan O'Donoghue933092f2018-03-26 15:36:46 +0100714U_BOOT_CMD(
715 hab_auth_img_or_fail, 4, 0,
716 do_authenticate_image_or_failover,
Fabio Estevam7014d9d2023-09-06 22:47:26 -0300717 "authenticate image via HAB. Switch to USB BootROM mode on failure",
Bryan O'Donoghue933092f2018-03-26 15:36:46 +0100718 "addr length ivt_offset\n"
719 "addr - image hex address\n"
720 "length - image hex length\n"
Fabio Estevam76cda332023-09-06 22:47:27 -0300721 "ivt_offset - hex offset of IVT in the image (optional)"
Bryan O'Donoghue933092f2018-03-26 15:36:46 +0100722 );
723
Sjoerd Simons27f3fae2019-06-18 23:08:59 +0200724U_BOOT_CMD(
725 hab_version, 1, 0, do_hab_version,
726 "print HAB major/minor version",
727 ""
728 );
729
Sven Ebenfeldeba5e332016-11-06 16:37:55 +0100730#endif /* !defined(CONFIG_SPL_BUILD) */
731
Utkarsh Gupta2b1f4142018-02-20 01:19:24 +0000732/* Get CSF Header length */
733static int get_hab_hdr_len(struct hab_hdr *hdr)
734{
735 return (size_t)((hdr->len[0] << 8) + (hdr->len[1]));
736}
737
738/* Check whether addr lies between start and
739 * end and is within the length of the image
740 */
741static int chk_bounds(u8 *addr, size_t bytes, u8 *start, u8 *end)
742{
743 size_t csf_size = (size_t)((end + 1) - addr);
744
745 return (addr && (addr >= start) && (addr <= end) &&
746 (csf_size >= bytes));
747}
748
749/* Get Length of each command in CSF */
750static int get_csf_cmd_hdr_len(u8 *csf_hdr)
751{
752 if (*csf_hdr == HAB_CMD_HDR)
753 return sizeof(struct hab_hdr);
754
755 return get_hab_hdr_len((struct hab_hdr *)csf_hdr);
756}
757
758/* Check if CSF is valid */
759static bool csf_is_valid(struct ivt *ivt, ulong start_addr, size_t bytes)
760{
761 u8 *start = (u8 *)start_addr;
762 u8 *csf_hdr;
763 u8 *end;
764
765 size_t csf_hdr_len;
766 size_t cmd_hdr_len;
767 size_t offset = 0;
768
769 if (bytes != 0)
770 end = start + bytes - 1;
771 else
772 end = start;
773
774 /* Verify if CSF pointer content is zero */
775 if (!ivt->csf) {
776 puts("Error: CSF pointer is NULL\n");
777 return false;
778 }
779
Peng Fan4f3cf8f2021-03-25 17:30:07 +0800780 csf_hdr = (u8 *)(ulong)ivt->csf;
Utkarsh Gupta2b1f4142018-02-20 01:19:24 +0000781
782 /* Verify if CSF Header exist */
783 if (*csf_hdr != HAB_CMD_HDR) {
784 puts("Error: CSF header command not found\n");
785 return false;
786 }
787
788 csf_hdr_len = get_hab_hdr_len((struct hab_hdr *)csf_hdr);
789
790 /* Check if the CSF lies within the image bounds */
791 if (!chk_bounds(csf_hdr, csf_hdr_len, start, end)) {
792 puts("Error: CSF lies outside the image bounds\n");
793 return false;
794 }
795
796 do {
Utkarsh Gupta09af35c2018-02-20 01:19:25 +0000797 struct hab_hdr *cmd;
798
799 cmd = (struct hab_hdr *)&csf_hdr[offset];
800
801 switch (cmd->tag) {
802 case (HAB_CMD_WRT_DAT):
803 puts("Error: Deprecated write command found\n");
804 return false;
805 case (HAB_CMD_CHK_DAT):
806 puts("Error: Deprecated check command found\n");
807 return false;
808 case (HAB_CMD_SET):
809 if (cmd->par == HAB_PAR_MID) {
810 puts("Error: Deprecated Set MID command found\n");
811 return false;
812 }
813 default:
814 break;
815 }
816
Utkarsh Gupta2b1f4142018-02-20 01:19:24 +0000817 cmd_hdr_len = get_csf_cmd_hdr_len(&csf_hdr[offset]);
818 if (!cmd_hdr_len) {
819 puts("Error: Invalid command length\n");
820 return false;
821 }
822 offset += cmd_hdr_len;
823
824 } while (offset < csf_hdr_len);
825
826 return true;
827}
828
Utkarsh Guptaaac4ab52021-03-25 17:30:08 +0800829/*
830 * Validate IVT structure of the image being authenticated
831 */
832static int validate_ivt(struct ivt *ivt_initial)
833{
834 struct ivt_header *ivt_hdr = &ivt_initial->hdr;
835
836 if ((ulong)ivt_initial & 0x3) {
837 puts("Error: Image's start address is not 4 byte aligned\n");
838 return 0;
839 }
840
841 /* Check IVT fields before allowing authentication */
842 if ((!verify_ivt_header(ivt_hdr)) && \
843 (ivt_initial->entry != 0x0) && \
844 (ivt_initial->reserved1 == 0x0) && \
845 (ivt_initial->self == \
846 (uint32_t)((ulong)ivt_initial & 0xffffffff)) && \
847 (ivt_initial->csf != 0x0) && \
848 (ivt_initial->reserved2 == 0x0)) {
849 /* Report boot failure if DCD pointer is found in IVT */
850 if (ivt_initial->dcd != 0x0)
851 puts("Error: DCD pointer must be 0\n");
852 else
853 return 1;
854 }
855
856 puts("Error: Invalid IVT structure\n");
857 debug("\nAllowed IVT structure:\n");
858 debug("IVT HDR = 0x4X2000D1\n");
859 debug("IVT ENTRY = 0xXXXXXXXX\n");
860 debug("IVT RSV1 = 0x0\n");
861 debug("IVT DCD = 0x0\n"); /* Recommended */
862 debug("IVT BOOT_DATA = 0xXXXXXXXX\n"); /* Commonly 0x0 */
863 debug("IVT SELF = 0xXXXXXXXX\n"); /* = ddr_start + ivt_offset */
864 debug("IVT CSF = 0xXXXXXXXX\n");
865 debug("IVT RSV2 = 0x0\n");
866
867 /* Invalid IVT structure */
868 return 0;
869}
870
Bryan O'Donoghue47b3f342018-01-12 12:40:16 +0000871bool imx_hab_is_enabled(void)
Sven Ebenfeldeba5e332016-11-06 16:37:55 +0100872{
873 struct imx_sec_config_fuse_t *fuse =
874 (struct imx_sec_config_fuse_t *)&imx_sec_config_fuse;
875 uint32_t reg;
876 int ret;
877
878 ret = fuse_read(fuse->bank, fuse->word, &reg);
879 if (ret) {
880 puts("\nSecure boot fuse read error\n");
881 return ret;
882 }
883
884 return (reg & IS_HAB_ENABLED_BIT) == IS_HAB_ENABLED_BIT;
885}
886
Bryan O'Donoghue1efba6a2018-01-12 12:40:13 +0000887int imx_hab_authenticate_image(uint32_t ddr_start, uint32_t image_size,
888 uint32_t ivt_offset)
Nitin Gargb1ce7012014-09-16 13:33:25 -0500889{
Peng Fan4f3cf8f2021-03-25 17:30:07 +0800890 ulong load_addr = 0;
Nitin Gargb1ce7012014-09-16 13:33:25 -0500891 size_t bytes;
Peng Fan4f3cf8f2021-03-25 17:30:07 +0800892 ulong ivt_addr = 0;
Bryan O'Donoghue79987a12018-01-12 12:39:56 +0000893 int result = 1;
Nitin Gargb1ce7012014-09-16 13:33:25 -0500894 ulong start;
Bryan O'Donoghue5ee19b32018-01-12 12:40:03 +0000895 struct ivt *ivt;
Bryan O'Donoghue13513252018-01-12 12:40:10 +0000896 enum hab_status status;
Nitin Gargb1ce7012014-09-16 13:33:25 -0500897
Breno Lima5deb9302021-03-25 17:30:10 +0800898 if (!imx_hab_is_enabled())
Bryan O'Donoghue19369c72018-01-12 12:39:57 +0000899 puts("hab fuse not enabled\n");
Nitin Gargb1ce7012014-09-16 13:33:25 -0500900
Bryan O'Donoghue19369c72018-01-12 12:39:57 +0000901 printf("\nAuthenticate image from DDR location 0x%x...\n",
902 ddr_start);
Nitin Gargb1ce7012014-09-16 13:33:25 -0500903
Bryan O'Donoghue19369c72018-01-12 12:39:57 +0000904 hab_caam_clock_enable(1);
Nitin Gargb1ce7012014-09-16 13:33:25 -0500905
Bryan O'Donoghue88919962018-01-12 12:40:01 +0000906 /* Calculate IVT address header */
Peng Fan4f3cf8f2021-03-25 17:30:07 +0800907 ivt_addr = (ulong) (ddr_start + ivt_offset);
Bryan O'Donoghue5ee19b32018-01-12 12:40:03 +0000908 ivt = (struct ivt *)ivt_addr;
Bryan O'Donoghue5ee19b32018-01-12 12:40:03 +0000909
910 /* Verify IVT header bugging out on error */
Utkarsh Guptaaac4ab52021-03-25 17:30:08 +0800911 if (!validate_ivt(ivt))
Breno Lima52d389c2018-02-20 01:19:22 +0000912 goto hab_authentication_exit;
Utkarsh Guptaf79f75e2018-02-20 01:19:23 +0000913
Bryan O'Donoghueb8dd7a62018-01-12 12:39:58 +0000914 start = ddr_start;
Bryan O'Donoghue88919962018-01-12 12:40:01 +0000915 bytes = image_size;
Bryan O'Donoghued525a282018-01-12 12:40:05 +0000916
Utkarsh Gupta2b1f4142018-02-20 01:19:24 +0000917 /* Verify CSF */
918 if (!csf_is_valid(ivt, start, bytes))
919 goto hab_authentication_exit;
920
Bryan O'Donoghued525a282018-01-12 12:40:05 +0000921 if (hab_rvt_entry() != HAB_SUCCESS) {
922 puts("hab entry function fail\n");
Bryan O'Donoghue3bf65de2018-01-12 12:40:11 +0000923 goto hab_exit_failure_print_status;
Bryan O'Donoghued525a282018-01-12 12:40:05 +0000924 }
925
Peng Fan4f3cf8f2021-03-25 17:30:07 +0800926 status = hab_rvt_check_target(HAB_TGT_MEMORY, (void *)(ulong)ddr_start, bytes);
Bryan O'Donoghue13513252018-01-12 12:40:10 +0000927 if (status != HAB_SUCCESS) {
Peng Fan4f3cf8f2021-03-25 17:30:07 +0800928 printf("HAB check target 0x%08x-0x%08lx fail\n",
Breno Lima9807f552021-03-25 17:30:14 +0800929 ddr_start, ddr_start + (ulong)bytes);
Bryan O'Donoghue3bf65de2018-01-12 12:40:11 +0000930 goto hab_exit_failure_print_status;
Bryan O'Donoghue13513252018-01-12 12:40:10 +0000931 }
Nitin Gargb1ce7012014-09-16 13:33:25 -0500932#ifdef DEBUG
Breno Lima9807f552021-03-25 17:30:14 +0800933 printf("\nivt_offset = 0x%x, ivt addr = 0x%lx\n", ivt_offset, ivt_addr);
Bryan O'Donoghueeb031502018-01-12 12:40:07 +0000934 printf("ivt entry = 0x%08x, dcd = 0x%08x, csf = 0x%08x\n", ivt->entry,
935 ivt->dcd, ivt->csf);
Bryan O'Donoghueb8dd7a62018-01-12 12:39:58 +0000936 puts("Dumping IVT\n");
Marek Vasut18eceae2023-05-29 01:29:20 +0200937 print_buffer(ivt_addr, (void *)(uintptr_t)(ivt_addr), 4, 0x8, 0);
Nitin Gargb1ce7012014-09-16 13:33:25 -0500938
Bryan O'Donoghueb8dd7a62018-01-12 12:39:58 +0000939 puts("Dumping CSF Header\n");
Marek Vasut18eceae2023-05-29 01:29:20 +0200940 print_buffer(ivt->csf, (void *)(uintptr_t)(ivt->csf), 4, 0x10, 0);
Nitin Gargb1ce7012014-09-16 13:33:25 -0500941
Sven Ebenfeldeba5e332016-11-06 16:37:55 +0100942#if !defined(CONFIG_SPL_BUILD)
Bryan O'Donoghueb8dd7a62018-01-12 12:39:58 +0000943 get_hab_status();
Sven Ebenfeldeba5e332016-11-06 16:37:55 +0100944#endif
Nitin Gargb1ce7012014-09-16 13:33:25 -0500945
Bryan O'Donoghueb8dd7a62018-01-12 12:39:58 +0000946 puts("\nCalling authenticate_image in ROM\n");
947 printf("\tivt_offset = 0x%x\n", ivt_offset);
948 printf("\tstart = 0x%08lx\n", start);
Marek Vasut18eceae2023-05-29 01:29:20 +0200949 printf("\tbytes = 0x%lx\n", (ulong)bytes);
Nitin Gargb1ce7012014-09-16 13:33:25 -0500950#endif
Peng Fan4f3cf8f2021-03-25 17:30:07 +0800951
952#ifndef CONFIG_ARM64
Bryan O'Donoghueb8dd7a62018-01-12 12:39:58 +0000953 /*
954 * If the MMU is enabled, we have to notify the ROM
955 * code, or it won't flush the caches when needed.
956 * This is done, by setting the "pu_irom_mmu_enabled"
957 * word to 1. You can find its address by looking in
958 * the ROM map. This is critical for
959 * authenticate_image(). If MMU is enabled, without
960 * setting this bit, authentication will fail and may
961 * crash.
962 */
963 /* Check MMU enabled */
964 if (is_soc_type(MXC_SOC_MX6) && get_cr() & CR_M) {
965 if (is_mx6dq()) {
966 /*
967 * This won't work on Rev 1.0.0 of
968 * i.MX6Q/D, since their ROM doesn't
969 * do cache flushes. don't think any
970 * exist, so we ignore them.
971 */
972 if (!is_mx6dqp())
973 writel(1, MX6DQ_PU_IROM_MMU_EN_VAR);
974 } else if (is_mx6sdl()) {
975 writel(1, MX6DLS_PU_IROM_MMU_EN_VAR);
976 } else if (is_mx6sl()) {
977 writel(1, MX6SL_PU_IROM_MMU_EN_VAR);
Bryan O'Donoghue19369c72018-01-12 12:39:57 +0000978 }
Bryan O'Donoghueb8dd7a62018-01-12 12:39:58 +0000979 }
Peng Fan4f3cf8f2021-03-25 17:30:07 +0800980#endif
Nitin Gargb1ce7012014-09-16 13:33:25 -0500981
Peng Fan4f3cf8f2021-03-25 17:30:07 +0800982 load_addr = (ulong)hab_rvt_authenticate_image(
Bryan O'Donoghueb8dd7a62018-01-12 12:39:58 +0000983 HAB_CID_UBOOT,
984 ivt_offset, (void **)&start,
985 (size_t *)&bytes, NULL);
986 if (hab_rvt_exit() != HAB_SUCCESS) {
987 puts("hab exit function fail\n");
988 load_addr = 0;
Bryan O'Donoghue19369c72018-01-12 12:39:57 +0000989 }
Nitin Gargb1ce7012014-09-16 13:33:25 -0500990
Bryan O'Donoghue3bf65de2018-01-12 12:40:11 +0000991hab_exit_failure_print_status:
Sven Ebenfeldeba5e332016-11-06 16:37:55 +0100992#if !defined(CONFIG_SPL_BUILD)
Bryan O'Donoghue19369c72018-01-12 12:39:57 +0000993 get_hab_status();
Sven Ebenfeldeba5e332016-11-06 16:37:55 +0100994#endif
Bryan O'Donoghue3bf65de2018-01-12 12:40:11 +0000995
Breno Lima52d389c2018-02-20 01:19:22 +0000996hab_authentication_exit:
Bryan O'Donoghue3bf65de2018-01-12 12:40:11 +0000997
Breno Lima5deb9302021-03-25 17:30:10 +0800998 if (load_addr != 0 || !imx_hab_is_enabled())
Bryan O'Donoghue79987a12018-01-12 12:39:56 +0000999 result = 0;
Nitin Gargb1ce7012014-09-16 13:33:25 -05001000
1001 return result;
1002}
Ye Lif66fd7b2021-03-25 17:30:06 +08001003
1004int authenticate_image(u32 ddr_start, u32 raw_image_size)
1005{
1006 u32 ivt_offset;
1007 size_t bytes;
1008
1009 ivt_offset = (raw_image_size + ALIGN_SIZE - 1) &
1010 ~(ALIGN_SIZE - 1);
1011 bytes = ivt_offset + IVT_SIZE + CSF_PAD_SIZE;
1012
1013 return imx_hab_authenticate_image(ddr_start, bytes, ivt_offset);
1014}