Hi Nitin, On 04/09/2014 03:18, Nitin Garg wrote: > When CONFIG_SECURE_BOOT is enabled, the signed images > like kernel and dtb can be authenticated using iMX6 CAAM. > The added command hab_auth_img can be used for HAB > authentication of images. The command takes the image > DDR location, IVT (Image Vector Table) offset inside > image as parameters. Detailed info about signing images > can be found in Freescale AppNote AN4581. > > Signed-off-by: Nitin Garg <nitin.g...@freescale.com> > > --- > > Changes in v3: > - Remove typecast of get_cpu_rev since its not required > > Changes in v2: > - Cleaned up clock code as per review comments > - Removed dead code as per review comments > - Re-written commit log as per review comments > > arch/arm/cpu/armv7/mx6/clock.c | 32 ++++++- > arch/arm/cpu/armv7/mx6/hab.c | 165 > ++++++++++++++++++++++++++++++++- > arch/arm/cpu/armv7/mx6/soc.c | 15 +++ > arch/arm/include/asm/arch-mx6/clock.h | 4 + > 4 files changed, 214 insertions(+), 2 deletions(-) > > diff --git a/arch/arm/cpu/armv7/mx6/clock.c b/arch/arm/cpu/armv7/mx6/clock.c > index 820b8d5..db6a8fc 100644 > --- a/arch/arm/cpu/armv7/mx6/clock.c > +++ b/arch/arm/cpu/armv7/mx6/clock.c > @@ -1,5 +1,5 @@ > /* > - * Copyright (C) 2010-2011 Freescale Semiconductor, Inc. > + * Copyright (C) 2010-2014 Freescale Semiconductor, Inc. > * > * SPDX-License-Identifier: GPL-2.0+ > */ > @@ -543,6 +543,36 @@ int enable_pcie_clock(void) > BM_ANADIG_PLL_ENET_ENABLE_PCIE); > } > > +#ifdef CONFIG_SECURE_BOOT > +void hab_caam_clock_enable(void) > +{ > + struct mxc_ccm_reg *const imx_ccm = > + (struct mxc_ccm_reg *)CCM_BASE_ADDR; > + > + /*CG4 ~ CG6, enable CAAM clocks*/ > + setbits_le32(&imx_ccm->CCGR0, MXC_CCM_CCGR0_CAAM_WRAPPER_IPG_MASK | > + MXC_CCM_CCGR0_CAAM_WRAPPER_ACLK_MASK | > + MXC_CCM_CCGR0_CAAM_SECURE_MEM_MASK); > + > + /* Enable EMI slow clk */ > + setbits_le32(&imx_ccm->CCGR6, MXC_CCM_CCGR6_EMI_SLOW_MASK); > +} > + > +void hab_caam_clock_disable(void) > +{ > + struct mxc_ccm_reg *const imx_ccm = > + (struct mxc_ccm_reg *)CCM_BASE_ADDR; > + > + /*CG4 ~ CG6, disable CAAM clocks*/ > + clrbits_le32(&imx_ccm->CCGR0, MXC_CCM_CCGR0_CAAM_WRAPPER_IPG_MASK | > + MXC_CCM_CCGR0_CAAM_WRAPPER_ACLK_MASK | > + MXC_CCM_CCGR0_CAAM_SECURE_MEM_MASK); > + > + /* Disable EMI slow clk */ > + clrbits_le32(&imx_ccm->CCGR6, MXC_CCM_CCGR6_EMI_SLOW_MASK); > +} > +#endif
Generally, we have in clock.c one function per clock, getting as enable_uart_clkparameter a boolean for enabling/disabling (i.e. enable_ocotp_clk(), enable_uart_clk(),...) Please stick with the same rule. > + > unsigned int mxc_get_clock(enum mxc_clock clk) > { > switch (clk) { > diff --git a/arch/arm/cpu/armv7/mx6/hab.c b/arch/arm/cpu/armv7/mx6/hab.c > index f6810a6..61a94a1 100644 > --- a/arch/arm/cpu/armv7/mx6/hab.c > +++ b/arch/arm/cpu/armv7/mx6/hab.c > @@ -1,5 +1,5 @@ > /* > - * Copyright (C) 2010-2013 Freescale Semiconductor, Inc. > + * Copyright (C) 2010-2014 Freescale Semiconductor, Inc. > * > * SPDX-License-Identifier: GPL-2.0+ > */ > @@ -7,8 +7,12 @@ > #include <common.h> > #include <asm/io.h> > #include <asm/arch/hab.h> > +#include <asm/arch/clock.h> > #include <asm/arch/sys_proto.h> > > +/* HAB (High Assurance Boot) debug */ > +#undef DEBUG_AUTHENTICATE_IMAGE This is never defined, you do not need to undefine it. > + > /* -------- start of HAB API updates ------------*/ > > #define hab_rvt_report_event_p \ > @@ -71,6 +75,41 @@ > ((hab_rvt_exit_t *)HAB_RVT_EXIT) \ > ) > > +#define IVT_SIZE 0x20 > +#define ALIGN_SIZE 0x1000 > +#define CSF_PAD_SIZE 0x2000 > + > +/* > + * +------------+ 0x0 (DDR_UIMAGE_START) - > + * | Header | | > + * +------------+ 0x40 | > + * | | | > + * | | | > + * | | | > + * | | | > + * | Image Data | | > + * . | | > + * . | > Stuff to be authenticated ----+ > + * . | | | > + * | | | | > + * | | | | > + * +------------+ | | > + * | | | | > + * | Fill Data | | | > + * | | | | > + * +------------+ Align to ALIGN_SIZE | | > + * | IVT | | | > + * +------------+ + IVT_SIZE - | > + * | | | > + * | CSF DATA | <---------------------------------------------------------+ > + * | | > + * +------------+ > + * | | > + * | Fill Data | > + * | | > + * +------------+ + CSF_PAD_SIZE > + */ > + > bool is_hab_enabled(void) > { > struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR; > @@ -144,6 +183,105 @@ int get_hab_status(void) > return 0; > } > > +uint32_t authenticate_image(uint32_t ddr_start, uint32_t image_size) > +{ > + uint32_t load_addr = 0; > + size_t bytes; > + ptrdiff_t ivt_offset = 0; > + int result = 0; > + ulong start; > + hab_rvt_authenticate_image_t *hab_rvt_authenticate_image; > + hab_rvt_entry_t *hab_rvt_entry; > + hab_rvt_exit_t *hab_rvt_exit; > + > + hab_rvt_authenticate_image = hab_rvt_authenticate_image_p; > + hab_rvt_entry = hab_rvt_entry_p; > + hab_rvt_exit = hab_rvt_exit_p; > + > + if (is_hab_enabled()) { > + printf("\nAuthenticate image from DDR location 0x%x...\n", > + ddr_start); > + > + hab_caam_clock_enable(); > + > + if (hab_rvt_entry() == HAB_SUCCESS) { > + /* If not already aligned, Align to ALIGN_SIZE */ > + ivt_offset = (image_size + ALIGN_SIZE - 1) & > + ~(ALIGN_SIZE - 1); > + > + start = ddr_start; > + bytes = ivt_offset + IVT_SIZE + CSF_PAD_SIZE; > + > +#ifdef DEBUG_AUTHENTICATE_IMAGE We have already a way for adding debugging. Use debug() instead of printf(), and you can simply use #ifdef DEBUG for conditional branches. We decided some times ago to avoid adding any flavour of specific DEBUG_ switches. > + printf("\nivt_offset = 0x%x, ivt addr = 0x%x\n", > + ivt_offset, ddr_start + ivt_offset); > + printf("Dumping IVT\n"); > + print_buffer(ddr_start + ivt_offset, > + (void *)(ddr_start + ivt_offset), > + 4, 0x8, 0); > + > + printf("Dumping CSF Header\n"); > + print_buffer(ddr_start + ivt_offset+IVT_SIZE, > + (void *)(ddr_start + ivt_offset+IVT_SIZE), > + 4, 0x10, 0); > + > + get_hab_status(); > + > + printf("\nCalling authenticate_image in ROM\n"); > + printf("\tivt_offset = 0x%x\n", ivt_offset); > + printf("\tstart = 0x%08lx\n", start); > + printf("\tbytes = 0x%x\n", bytes); > +#endif > + /* > + * If the MMU is enabled, we have to notify the ROM > + * code, or it won't flush the caches when needed. > + * This is done, by setting the "pu_irom_mmu_enabled" > + * word to 1. You can find its address by looking in > + * the ROM map. This is critical for > + * authenticate_image(). If MMU is enabled, without > + * setting this but, authentication will fail and may > + * crash. > + */ > + if (is_cpu_type(MXC_CPU_MX6Q) || > + is_cpu_type(MXC_CPU_MX6D)) { > + /* > + * This won't work on Rev 1.0.0 of i.MX6Q/D, > + * since their ROM doesn't do cache flushes. > + * I don't think any exist, so we ignore them. > + */ > + writel(1, 0x009024a8); Can you add defines or (better) structures for this ? Writing in this way into the hardware is generally not allowed in u-boot. In the comments you say that it must be checked if MMU is on (generally on when cache is enabled), but there is no check afterward, only a different behavior depending on CPU. Does it mean that pu_irom_mmu_enabled is set independently from MMU status ? > + } else if (is_cpu_type(MXC_CPU_MX6DL) || > + is_cpu_type(MXC_CPU_MX6SOLO)) { > + writel(1, 0x00901dd0); > + } else if (is_cpu_type(MXC_CPU_MX6SL)) { > + writel(1, 0x00900a18); > + } > + > + 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"); Use puts() instead of printf() when you want to output a constant string. > + } > + > + hab_caam_clock_disable(); > + > + get_hab_status(); > + } else { > + printf("hab fuse not enabled\n"); > + } > + > + if ((!is_hab_enabled()) || (load_addr != 0)) > + result = 1; > + > + return result; > +} > + > int do_hab_status(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) > { > if ((argc != 1)) { > @@ -156,8 +294,33 @@ int do_hab_status(cmd_tbl_t *cmdtp, int flag, int argc, > char * const argv[]) > return 0; > } > > +static int do_authenticate_image(cmd_tbl_t *cmdtp, int flag, int argc, > + char * const argv[]) > +{ > + ulong addr, ivt_offset; > + int rcode = 0; > + > + if (argc < 3) > + return CMD_RET_USAGE; > + > + addr = simple_strtoul(argv[1], NULL, 16); > + ivt_offset = simple_strtoul(argv[2], NULL, 16); > + > + rcode = authenticate_image(addr, ivt_offset); > + > + return rcode; > +} > + > U_BOOT_CMD( > hab_status, CONFIG_SYS_MAXARGS, 1, do_hab_status, > "display HAB status", > "" > ); > + > +U_BOOT_CMD( > + hab_auth_img, 3, 1, do_authenticate_image, > + "authenticate image via HAB", > + "addr ivt_offset\n" > + "addr - image hex address\n" > + "ivt_offset - hex offset of IVT in the image" > + ); > diff --git a/arch/arm/cpu/armv7/mx6/soc.c b/arch/arm/cpu/armv7/mx6/soc.c > index b0c1306..9842efb 100644 > --- a/arch/arm/cpu/armv7/mx6/soc.c > +++ b/arch/arm/cpu/armv7/mx6/soc.c > @@ -409,10 +409,25 @@ int board_postclk_init(void) > #ifndef CONFIG_SYS_DCACHE_OFF > void enable_caches(void) > { > +#if defined(CONFIG_SYS_ARM_CACHE_WRITETHROUGH) > + enum dcache_option option = DCACHE_WRITETHROUGH; > +#else > + enum dcache_option option = DCACHE_WRITEBACK; > +#endif > + > /* Avoid random hang when download by usb */ > invalidate_dcache_all(); > + > /* Enable D-cache. I-cache is already enabled in start.S */ > dcache_enable(); > + > + /* Enable caching on OCRAM and ROM */ > + mmu_set_region_dcache_behaviour(ROMCP_ARB_BASE_ADDR, > + ROMCP_ARB_END_ADDR, > + option); > + mmu_set_region_dcache_behaviour(IRAM_BASE_ADDR, > + IRAM_SIZE, > + option); > } > #endif > > diff --git a/arch/arm/include/asm/arch-mx6/clock.h > b/arch/arm/include/asm/arch-mx6/clock.h > index 339c789..2482e1a 100644 > --- a/arch/arm/include/asm/arch-mx6/clock.h > +++ b/arch/arm/include/asm/arch-mx6/clock.h > @@ -2,6 +2,8 @@ > * (C) Copyright 2009 > * Stefano Babic, DENX Software Engineering, sba...@denx.de. > * > + * (C) Copyright 2014 Freescale Semiconductor, Inc. > + * > * SPDX-License-Identifier: GPL-2.0+ > */ > > @@ -60,4 +62,6 @@ int enable_i2c_clk(unsigned char enable, unsigned i2c_num); > int enable_spi_clk(unsigned char enable, unsigned spi_num); > void enable_ipu_clock(void); > int enable_fec_anatop_clock(enum enet_freq freq); > +void hab_caam_clock_enable(void); > +void hab_caam_clock_disable(void); > #endif /* __ASM_ARCH_CLOCK_H */ > I have not found enough documentation to verify this: is this code suitable for MX53, too ? I can see in MX53 manual that a "CAAM" is available, but nothing more as that. Best regards, Stefano Babic -- ===================================================================== DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sba...@denx.de ===================================================================== _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot