2 * Copyright (C) 2010-2014 Freescale Semiconductor, Inc.
4 * SPDX-License-Identifier: GPL-2.0+
8 #include <asm/system.h>
9 #include <asm/arch/clock.h>
10 #include <asm/arch/sys_proto.h>
11 #include <asm/arch/hab.h>
13 HAB_FUNC(entry, hab_status_t)
14 HAB_FUNC(exit, hab_status_t)
15 HAB_FUNC5(authenticate_image, void *, uint8_t, size_t, void **, size_t *, hab_loader_callback_f_t)
16 //HAB_FUNC1(run_dcd, hab_status_t, const uint8_t *)
17 HAB_FUNC2(run_csf, hab_status_t, const uint8_t *, uint8_t)
18 HAB_FUNC2(report_status, hab_status_t, hab_config_t *, hab_state_t *)
19 HAB_FUNC4(report_event, hab_status_t, hab_status_t, uint32_t, uint8_t *, size_t *)
20 HAB_FUNC3(check_target, hab_status_t, uint8_t, const void *, size_t)
21 HAB_FUNC3(assert, hab_status_t, uint8_t, const void *, size_t)
28 struct mx6_boot_data *boot_data;
34 struct mx6_boot_data {
41 #define ALIGN_SIZE 0x400
42 #define CSF_PAD_SIZE 0x2000
43 #define MX6DQ_PU_IROM_MMU_EN_VAR 0x009024a8
44 #define MX6DLS_PU_IROM_MMU_EN_VAR 0x00901dd0
45 #define MX6SL_PU_IROM_MMU_EN_VAR 0x00900a18
48 * +------------+ 0x0 (DDR_UIMAGE_START) -
50 * +------------+ 0x40 |
57 * . | > Stuff to be authenticated ----+
65 * +------------+ Align to ALIGN_SIZE | |
67 * +------------+ + IVT_SIZE - |
69 * | CSF DATA | <---------------------------------------------------------+
75 * +------------+ + CSF_PAD_SIZE
78 static bool is_hab_enabled(void)
80 struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
81 struct fuse_bank *bank = &ocotp->bank[0];
82 struct fuse_bank0_regs *fuse =
83 (struct fuse_bank0_regs *)bank->fuse_regs;
84 uint32_t reg = readl(&fuse->cfg5);
88 debug("rvt_base=%p\n", hab_rvt_base());
89 debug("hab_rvt_entry=%p\n", hab_rvt_entry_p);
90 debug("hab_rvt_exit=%p\n", hab_rvt_exit_p);
91 debug("hab_rvt_check_target=%p\n", hab_rvt_check_target_p);
92 debug("hab_rvt_authenticate_image=%p\n", hab_rvt_authenticate_image_p);
93 debug("hab_rvt_report_event=%p\n", hab_rvt_report_event_p);
94 debug("hab_rvt_report_status=%p\n", hab_rvt_report_status_p);
95 debug("hab_rvt_assert=%p\n", hab_rvt_assert_p);
98 return (reg & 0x2) == 0x2;
101 static void display_event(uint8_t *event_data, size_t bytes)
105 if (!(event_data && bytes > 0))
108 for (i = 0; i < bytes; i++) {
110 printf("\t0x%02x", event_data[i]);
111 else if ((i % 8) == 0)
112 printf("\n\t0x%02x", event_data[i]);
114 printf(" 0x%02x", event_data[i]);
118 int get_hab_status(void)
120 static uint32_t last_hab_event __attribute__((section(".data")));
121 uint32_t index = last_hab_event; /* Loop index */
122 uint8_t event_data[128]; /* Event data buffer */
123 size_t bytes = sizeof(event_data); /* Event size in bytes */
124 enum hab_config config;
125 enum hab_state state;
128 if (is_hab_enabled())
129 puts("Secure boot enabled\n");
131 puts("Secure boot disabled\n");
133 /* Check HAB status */
134 config = state = 0; /* ROM code assumes short enums! */
135 ret = hab_rvt_report_status(&config, &state);
136 printf("HAB Configuration: 0x%02x, HAB State: 0x%02x\n",
138 if (ret != HAB_SUCCESS) {
139 /* Display HAB Error events */
140 while (hab_rvt_report_event(HAB_STS_ANY, index, event_data,
141 &bytes) == HAB_SUCCESS) {
143 printf("--------- HAB Event %d -----------------\n",
145 puts("event data:\n");
146 display_event(event_data, bytes);
148 bytes = sizeof(event_data);
151 ret = index - last_hab_event;
152 last_hab_event = index;
154 /* Display message if no HAB events are found */
155 puts("No HAB Events Found!\n");
161 static inline hab_status_t hab_init(void)
165 if (!is_hab_enabled()) {
166 puts("hab fuse not enabled\n");
170 hab_caam_clock_enable(1);
172 ret = hab_rvt_entry();
173 debug("hab_rvt_entry() returned %02x\n", ret);
174 if (ret != HAB_SUCCESS) {
175 printf("hab entry function failed: %02x\n", ret);
176 hab_caam_clock_enable(0);
182 static inline hab_status_t hab_exit(void)
186 ret = hab_rvt_exit();
187 if (ret != HAB_SUCCESS)
188 printf("hab exit function failed: %02x\n", ret);
190 hab_caam_clock_enable(0);
195 static hab_status_t hab_check_target(hab_target_t type, uint32_t addr, size_t len)
200 if (ret != HAB_SUCCESS)
203 ret = hab_rvt_check_target(type, (void *)addr, len);
204 if (ret != HAB_SUCCESS) {
205 printf("check_target(0x%08x, 0x%08x) failed: %d\n",
211 if (ret == HAB_SUCCESS && get_hab_status() > 0) {
217 static hab_status_t hab_assert(uint32_t type, uint32_t addr, size_t len)
222 if (ret != HAB_SUCCESS)
225 ret = hab_rvt_assert(type, (void *)addr, len);
226 if (ret != HAB_SUCCESS) {
227 printf("assert(0x%08x, 0x%08x) failed: %d\n",
233 if (ret == HAB_SUCCESS && get_hab_status() > 0) {
239 static int do_hab_status(cmd_tbl_t *cmdtp, int flag, int argc,
243 return CMD_RET_USAGE;
247 return CMD_RET_SUCCESS;
250 static int do_hab_check_target(cmd_tbl_t *cmdtp, int flag, int argc,
253 hab_target_t type = HAB_TGT_ANY;
258 return CMD_RET_USAGE;
260 addr = simple_strtoul(argv[1], NULL, 16);
261 len = simple_strtoul(argv[2], NULL, 16);
263 switch (argv[3][0]) {
266 type = HAB_TGT_PERIPHERAL;
270 type = HAB_TGT_MEMORY;
276 printf("Invalid type '%s'\n", argv[3]);
277 return CMD_RET_USAGE;
280 if (hab_check_target(type, addr, len) != HAB_SUCCESS)
281 return CMD_RET_FAILURE;
283 return CMD_RET_SUCCESS;
286 static int do_hab_assert(cmd_tbl_t *cmdtp, int flag, int argc,
294 return CMD_RET_USAGE;
296 addr = simple_strtoul(argv[1], NULL, 16);
297 len = simple_strtoul(argv[2], NULL, 16);
299 type = simple_strtoul(argv[3], NULL, 16);
302 if (hab_assert(type, addr, len) != HAB_SUCCESS)
303 return CMD_RET_FAILURE;
305 return CMD_RET_SUCCESS;
309 hab_status, CONFIG_SYS_MAXARGS, 1, do_hab_status,
310 "display HAB status",
315 hab_check_target, 4, 0, do_hab_check_target,
316 "verify an address range via HAB",
318 "\t\taddr -\taddress to verify\n"
319 "\t\tlen -\tlength of addr range to verify\n"
323 hab_assert, 4, 0, do_hab_assert,
324 "Test an assertion against the HAB audit log",
326 "\t\taddr -\taddress to verify\n"
327 "\t\tlen -\tlength of addr range to verify\n"