summaryrefslogtreecommitdiff
path: root/cpu
diff options
context:
space:
mode:
authorEric Sun <jian.sun@freescale.com>2012-07-13 15:27:10 +0800
committerEric Sun <jian.sun@freescale.com>2012-07-13 15:45:12 +0800
commitdb5d1e6606540706e91dec47c78b468c7d94a339 (patch)
tree1119747233ecb05416adf517bce26c64051b150d /cpu
parent86a3cb55b2685aa6cd47adfb1753225e333572e6 (diff)
downloadu-boot-imx-db5d1e6606540706e91dec47c78b468c7d94a339.zip
u-boot-imx-db5d1e6606540706e91dec47c78b468c7d94a339.tar.gz
u-boot-imx-db5d1e6606540706e91dec47c78b468c7d94a339.tar.bz2
ENGR00217114-1 MX6 U-Boot, Secure Boot, one code base for MX6Q/DL/SL
Move the secure boot related implementation code from mx6q_arm2.c to mx6/generic.c. In this way the HAB feature can be shared by all MX6 platforms Signed-off-by: Eric Sun <jian.sun@freescale.com>
Diffstat (limited to 'cpu')
-rw-r--r--cpu/arm_cortexa8/mx6/generic.c177
1 files changed, 177 insertions, 0 deletions
diff --git a/cpu/arm_cortexa8/mx6/generic.c b/cpu/arm_cortexa8/mx6/generic.c
index a762498..c844594 100644
--- a/cpu/arm_cortexa8/mx6/generic.c
+++ b/cpu/arm_cortexa8/mx6/generic.c
@@ -47,6 +47,10 @@
#include <usb/regs-usbphy-mx6.h>
+#if defined(CONFIG_SECURE_BOOT)
+#include <asm/arch/mx6_secure.h>
+#endif
+
enum pll_clocks {
CPU_PLL1, /* System PLL */
BUS_PLL2, /* System Bus PLL*/
@@ -1208,6 +1212,179 @@ U_BOOT_CMD(
"");
#endif
+#ifdef CONFIG_SECURE_BOOT
+/* -------- start of HAB API updates ------------*/
+#define hab_rvt_report_event ((hab_rvt_report_event_t *)HAB_RVT_REPORT_EVENT)
+#define hab_rvt_report_status ((hab_rvt_report_status_t *)HAB_RVT_REPORT_STATUS)
+#define hab_rvt_authenticate_image \
+ ((hab_rvt_authenticate_image_t *)HAB_RVT_AUTHENTICATE_IMAGE)
+#define hab_rvt_entry ((hab_rvt_entry_t *) HAB_RVT_ENTRY)
+#define hab_rvt_exit ((hab_rvt_exit_t *) HAB_RVT_EXIT)
+#define hab_rvt_clock_init HAB_RVT_CLOCK_INIT
+
+/*
+ * +------------+ 0x0 (DDR_UIMAGE_START) -
+ * | Header | |
+ * +------------+ 0x40 |
+ * | | |
+ * | | |
+ * | | |
+ * | | |
+ * | Image Data | |
+ * . | |
+ * . | > Stuff to be authenticated ----+
+ * . | | |
+ * | | | |
+ * | | | |
+ * +------------+ | |
+ * | | | |
+ * | Fill Data | | |
+ * | | | |
+ * +------------+ 0x003F_DFE0 | |
+ * | IVT | | |
+ * +------------+ 0x003F_E000 - |
+ * | | |
+ * | CSF DATA | <---------------------------------------------------------+
+ * | |
+ * +------------+
+ * | |
+ * | Fill Data |
+ * | |
+ * +------------+ 0x0040_0000
+ */
+
+#ifndef CONFIG_MX6SL
+#define DDR_UIMAGE_START 0x10800000
+#else
+#define DDR_UIMAGE_START 0x80800000
+#endif
+
+#define DDR_UIMAGE_LENGTH 0x400000
+#define DDR_IVT_OFFSET 0x3FDFE0
+#define OCOTP_CFG5_OFFSET 0x460
+
+int check_hab_enable(void)
+{
+ u32 reg = 0;
+ int result = 0;
+
+ reg = readl(IMX_OTP_BASE + OCOTP_CFG5_OFFSET);
+ if ((reg & 0x2) == 0x2)
+ result = 1;
+
+ return result;
+}
+
+void display_event(uint8_t *event_data, size_t bytes)
+{
+ uint32_t i;
+ if ((event_data) && (bytes > 0)) {
+ for (i = 0; i < bytes; i++) {
+ if (i == 0)
+ printf("\t0x%02x", event_data[i]);
+ else if ((i % 8) == 0)
+ printf("\n\t0x%02x", event_data[i]);
+ else
+ printf(" 0x%02x", event_data[i]);
+ }
+ }
+}
+
+int get_hab_status(void)
+{
+ uint32_t index = 0; /* Loop index */
+ uint8_t event_data[128]; /* Event data buffer */
+ size_t bytes = sizeof(event_data); /* Event size in bytes */
+ hab_config_t config = 0;
+ hab_state_t state = 0;
+
+ /* Check HAB status */
+ if (hab_rvt_report_status(&config, &state) != HAB_SUCCESS) {
+ printf("\nHAB Configuration: 0x%02x, HAB State: 0x%02x\n",
+ config, state);
+
+ /* Display HAB Error events */
+ while (hab_rvt_report_event(HAB_FAILURE, index, event_data,
+ &bytes) == HAB_SUCCESS) {
+ printf("\n");
+ printf("--------- HAB Event %d -----------------\n",
+ index + 1);
+ printf("event data:\n");
+ display_event(event_data, bytes);
+ printf("\n");
+ bytes = sizeof(event_data);
+ index++;
+ }
+ }
+ /* Display message if no HAB events are found */
+ else {
+ printf("\nHAB Configuration: 0x%02x, HAB State: 0x%02x\n",
+ config, state);
+ printf("No HAB Events Found!\n\n");
+ }
+ return 0;
+}
+
+void hab_caam_clock_enable(void)
+{
+ u32 reg = 0;
+
+ reg = readl(CCM_BASE_ADDR + CLKCTL_CCGR0); /* CCGR0 */
+ reg |= 0x3F00; /*CG4 ~ CG6, enable CAAM clocks*/
+ writel(reg, CCM_BASE_ADDR + CLKCTL_CCGR0);
+}
+
+
+void hab_caam_clock_disable(void)
+{
+ u32 reg = 0;
+
+ reg = readl(CCM_BASE_ADDR + CLKCTL_CCGR0); /* CCGR0 */
+ reg &= ~0x3F00; /*CG4 ~ CG6, disable CAAM clocks*/
+ writel(reg, CCM_BASE_ADDR + CLKCTL_CCGR0);
+}
+
+uint32_t authenticate_image(void)
+{
+ uint32_t load_addr = 0;
+ size_t bytes;
+ ptrdiff_t ivt_offset = DDR_IVT_OFFSET;
+ int result = 0;
+ ulong start;
+
+ if (check_hab_enable() == 1) {
+ printf("\nAuthenticate uImage from DDR location 0x%lx...\n",
+ DDR_UIMAGE_START);
+
+ hab_caam_clock_enable();
+
+ if (hab_rvt_entry() == HAB_SUCCESS) {
+ start = DDR_UIMAGE_START;
+ bytes = DDR_UIMAGE_LENGTH;
+ load_addr = (uint32_t)hab_rvt_authenticate_image(
+ HAB_CID_UBOOT,
+ ivt_offset, (void **)&start,
+ (size_t *)&bytes, NULL);
+ if (hab_rvt_exit() != HAB_SUCCESS) {
+ printf("hab exit function fail\n");
+ load_addr = 0;
+ }
+ } else
+ printf("hab entry function fail\n");
+
+ hab_caam_clock_disable();
+
+ get_hab_status();
+ }
+
+ if ((!check_hab_enable()) || (load_addr != 0))
+ result = 1;
+
+ return result;
+}
+/* ----------- end of HAB API updates ------------*/
+#endif
+
#ifdef CONFIG_ANDROID_RECOVERY
struct reco_envs supported_reco_envs[BOOT_DEV_NUM] = {