diff options
author | Eric Sun <jian.sun@freescale.com> | 2012-07-13 15:27:10 +0800 |
---|---|---|
committer | Eric Sun <jian.sun@freescale.com> | 2012-07-13 15:45:12 +0800 |
commit | db5d1e6606540706e91dec47c78b468c7d94a339 (patch) | |
tree | 1119747233ecb05416adf517bce26c64051b150d /cpu | |
parent | 86a3cb55b2685aa6cd47adfb1753225e333572e6 (diff) | |
download | u-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.c | 177 |
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] = { |