Merge branch 'u-boot-imx/master' into 'u-boot-arm/master'
[karo-tx-uboot.git] / arch / arm / cpu / armv7 / mx6 / hab.c
1 /*
2  * Copyright (C) 2010-2013 Freescale Semiconductor, Inc.
3  *
4  * SPDX-License-Identifier:    GPL-2.0+
5  */
6
7 #include <common.h>
8 #include <asm/io.h>
9 #include <asm/arch/hab.h>
10 #include <asm/arch/sys_proto.h>
11
12 /* -------- start of HAB API updates ------------*/
13
14 #define hab_rvt_report_event_p                                  \
15 (                                                               \
16         ((is_cpu_type(MXC_CPU_MX6Q) ||                          \
17           is_cpu_type(MXC_CPU_MX6D)) &&                         \
18           (soc_rev() >= CHIP_REV_1_5)) ?                        \
19         ((hab_rvt_report_event_t *)HAB_RVT_REPORT_EVENT_NEW) :  \
20         (is_cpu_type(MXC_CPU_MX6DL) &&                          \
21          (soc_rev() >= CHIP_REV_1_2)) ?                         \
22         ((hab_rvt_report_event_t *)HAB_RVT_REPORT_EVENT_NEW) :  \
23         ((hab_rvt_report_event_t *)HAB_RVT_REPORT_EVENT)        \
24 )
25
26 #define hab_rvt_report_status_p                                 \
27 (                                                               \
28         ((is_cpu_type(MXC_CPU_MX6Q) ||                          \
29           is_cpu_type(MXC_CPU_MX6D)) &&                         \
30           (soc_rev() >= CHIP_REV_1_5)) ?                        \
31         ((hab_rvt_report_status_t *)HAB_RVT_REPORT_STATUS_NEW) :\
32         (is_cpu_type(MXC_CPU_MX6DL) &&                          \
33          (soc_rev() >= CHIP_REV_1_2)) ?                         \
34         ((hab_rvt_report_status_t *)HAB_RVT_REPORT_STATUS_NEW) :\
35         ((hab_rvt_report_status_t *)HAB_RVT_REPORT_STATUS)      \
36 )
37
38 #define hab_rvt_authenticate_image_p                            \
39 (                                                               \
40         ((is_cpu_type(MXC_CPU_MX6Q) ||                          \
41           is_cpu_type(MXC_CPU_MX6D)) &&                         \
42           (soc_rev() >= CHIP_REV_1_5)) ?                        \
43         ((hab_rvt_authenticate_image_t *)HAB_RVT_AUTHENTICATE_IMAGE_NEW) : \
44         (is_cpu_type(MXC_CPU_MX6DL) &&                          \
45          (soc_rev() >= CHIP_REV_1_2)) ?                         \
46         ((hab_rvt_authenticate_image_t *)HAB_RVT_AUTHENTICATE_IMAGE_NEW) : \
47         ((hab_rvt_authenticate_image_t *)HAB_RVT_AUTHENTICATE_IMAGE)    \
48 )
49
50 #define hab_rvt_entry_p                                         \
51 (                                                               \
52         ((is_cpu_type(MXC_CPU_MX6Q) ||                          \
53           is_cpu_type(MXC_CPU_MX6D)) &&                         \
54           (soc_rev() >= CHIP_REV_1_5)) ?                        \
55         ((hab_rvt_entry_t *)HAB_RVT_ENTRY_NEW) :                \
56         (is_cpu_type(MXC_CPU_MX6DL) &&                          \
57          (soc_rev() >= CHIP_REV_1_2)) ?                         \
58         ((hab_rvt_entry_t *)HAB_RVT_ENTRY_NEW) :                \
59         ((hab_rvt_entry_t *)HAB_RVT_ENTRY)                      \
60 )
61
62 #define hab_rvt_exit_p                                          \
63 (                                                               \
64         ((is_cpu_type(MXC_CPU_MX6Q) ||                          \
65           is_cpu_type(MXC_CPU_MX6D)) &&                         \
66           (soc_rev() >= CHIP_REV_1_5)) ?                        \
67         ((hab_rvt_exit_t *)HAB_RVT_EXIT_NEW) :                  \
68         (is_cpu_type(MXC_CPU_MX6DL) &&                          \
69          (soc_rev() >= CHIP_REV_1_2)) ?                         \
70         ((hab_rvt_exit_t *)HAB_RVT_EXIT_NEW) :                  \
71         ((hab_rvt_exit_t *)HAB_RVT_EXIT)                        \
72 )
73
74 bool is_hab_enabled(void)
75 {
76         struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
77         struct fuse_bank *bank = &ocotp->bank[0];
78         struct fuse_bank0_regs *fuse =
79                 (struct fuse_bank0_regs *)bank->fuse_regs;
80         uint32_t reg = readl(&fuse->cfg5);
81
82         return (reg & 0x2) == 0x2;
83 }
84
85 void display_event(uint8_t *event_data, size_t bytes)
86 {
87         uint32_t i;
88
89         if (!(event_data && bytes > 0))
90                 return;
91
92         for (i = 0; i < bytes; i++) {
93                 if (i == 0)
94                         printf("\t0x%02x", event_data[i]);
95                 else if ((i % 8) == 0)
96                         printf("\n\t0x%02x", event_data[i]);
97                 else
98                         printf(" 0x%02x", event_data[i]);
99         }
100 }
101
102 int get_hab_status(void)
103 {
104         uint32_t index = 0; /* Loop index */
105         uint8_t event_data[128]; /* Event data buffer */
106         size_t bytes = sizeof(event_data); /* Event size in bytes */
107         enum hab_config config = 0;
108         enum hab_state state = 0;
109         hab_rvt_report_event_t *hab_rvt_report_event;
110         hab_rvt_report_status_t *hab_rvt_report_status;
111
112         hab_rvt_report_event = hab_rvt_report_event_p;
113         hab_rvt_report_status = hab_rvt_report_status_p;
114
115         if (is_hab_enabled())
116                 puts("\nSecure boot enabled\n");
117         else
118                 puts("\nSecure boot disabled\n");
119
120         /* Check HAB status */
121         if (hab_rvt_report_status(&config, &state) != HAB_SUCCESS) {
122                 printf("\nHAB Configuration: 0x%02x, HAB State: 0x%02x\n",
123                        config, state);
124
125                 /* Display HAB Error events */
126                 while (hab_rvt_report_event(HAB_FAILURE, index, event_data,
127                                         &bytes) == HAB_SUCCESS) {
128                         puts("\n");
129                         printf("--------- HAB Event %d -----------------\n",
130                                index + 1);
131                         puts("event data:\n");
132                         display_event(event_data, bytes);
133                         puts("\n");
134                         bytes = sizeof(event_data);
135                         index++;
136                 }
137         }
138         /* Display message if no HAB events are found */
139         else {
140                 printf("\nHAB Configuration: 0x%02x, HAB State: 0x%02x\n",
141                        config, state);
142                 puts("No HAB Events Found!\n\n");
143         }
144         return 0;
145 }
146
147 int do_hab_status(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
148 {
149         if ((argc != 1)) {
150                 cmd_usage(cmdtp);
151                 return 1;
152         }
153
154         get_hab_status();
155
156         return 0;
157 }
158
159 U_BOOT_CMD(
160                 hab_status, CONFIG_SYS_MAXARGS, 1, do_hab_status,
161                 "display HAB status",
162                 ""
163           );