uboot/board/freescale/common/fsl_chain_of_trust.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright 2015 Freescale Semiconductor, Inc.
   4 */
   5
   6#include <common.h>
   7#include <dm.h>
   8#include <env.h>
   9#include <fsl_validate.h>
  10#include <fsl_secboot_err.h>
  11#include <fsl_sfp.h>
  12#include <log.h>
  13#include <dm/root.h>
  14
  15#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_FRAMEWORK)
  16#include <spl.h>
  17#endif
  18
  19#ifdef CONFIG_ADDR_MAP
  20#include <asm/mmu.h>
  21#endif
  22
  23#ifdef CONFIG_FSL_CORENET
  24#include <asm/fsl_pamu.h>
  25#endif
  26
  27#ifdef CONFIG_ARCH_LS1021A
  28#include <asm/arch/immap_ls102xa.h>
  29#endif
  30
  31#if defined(CONFIG_MPC85xx)
  32#define CONFIG_DCFG_ADDR        CONFIG_SYS_MPC85xx_GUTS_ADDR
  33#else
  34#define CONFIG_DCFG_ADDR        CONFIG_SYS_FSL_GUTS_ADDR
  35#endif
  36
  37#ifdef CONFIG_SYS_FSL_CCSR_GUR_LE
  38#define gur_in32(a)       in_le32(a)
  39#else
  40#define gur_in32(a)       in_be32(a)
  41#endif
  42
  43/* Check the Boot Mode. If Secure, return 1 else return 0 */
  44int fsl_check_boot_mode_secure(void)
  45{
  46        uint32_t val;
  47        struct ccsr_sfp_regs *sfp_regs = (void *)(CONFIG_SYS_SFP_ADDR);
  48        struct ccsr_gur __iomem *gur = (void *)(CONFIG_DCFG_ADDR);
  49
  50        val = sfp_in32(&sfp_regs->ospr) & ITS_MASK;
  51        if (val == ITS_MASK)
  52                return 1;
  53
  54#if defined(CONFIG_FSL_CORENET) || !defined(CONFIG_MPC85xx)
  55        /* For PBL based platforms check the SB_EN bit in RCWSR */
  56        val = gur_in32(&gur->rcwsr[RCW_SB_EN_REG_INDEX - 1]) & RCW_SB_EN_MASK;
  57        if (val == RCW_SB_EN_MASK)
  58                return 1;
  59#endif
  60
  61#if defined(CONFIG_MPC85xx) && !defined(CONFIG_FSL_CORENET)
  62        /* For Non-PBL Platforms, check the Device Status register 2*/
  63        val = gur_in32(&gur->pordevsr2) & MPC85xx_PORDEVSR2_SBC_MASK;
  64        if (val != MPC85xx_PORDEVSR2_SBC_MASK)
  65                return 1;
  66
  67#endif
  68        return 0;
  69}
  70
  71#ifndef CONFIG_SPL_BUILD
  72int fsl_setenv_chain_of_trust(void)
  73{
  74        /* Check Boot Mode
  75         * If Boot Mode is Non-Secure, no changes are required
  76         */
  77        if (fsl_check_boot_mode_secure() == 0)
  78                return 0;
  79
  80        /* If Boot mode is Secure, set the environment variables
  81         * bootdelay = 0 (To disable Boot Prompt)
  82         * bootcmd = CONFIG_CHAIN_BOOT_CMD (Validate and execute Boot script)
  83         */
  84        env_set("bootdelay", "-2");
  85
  86#ifdef CONFIG_ARM
  87        env_set("secureboot", "y");
  88#else
  89        env_set("bootcmd", CONFIG_CHAIN_BOOT_CMD);
  90#endif
  91
  92        return 0;
  93}
  94#endif
  95
  96#ifdef CONFIG_SPL_BUILD
  97void spl_validate_uboot(uint32_t hdr_addr, uintptr_t img_addr)
  98{
  99        int res;
 100
 101        /*
 102         * Check Boot Mode
 103         * If Boot Mode is Non-Secure, skip validation
 104         */
 105        if (fsl_check_boot_mode_secure() == 0)
 106                return;
 107
 108        printf("SPL: Validating U-Boot image\n");
 109
 110#ifdef CONFIG_ADDR_MAP
 111        init_addr_map();
 112#endif
 113
 114#ifdef CONFIG_FSL_CORENET
 115        if (pamu_init() < 0)
 116                fsl_secboot_handle_error(ERROR_ESBC_PAMU_INIT);
 117#endif
 118
 119#ifdef CONFIG_FSL_CAAM
 120        if (sec_init() < 0)
 121                fsl_secboot_handle_error(ERROR_ESBC_SEC_INIT);
 122#endif
 123
 124/*
 125 * dm_init_and_scan() is called as part of common SPL framework, so no
 126 * need to call it again but in case of powerpc platforms which currently
 127 * do not use common SPL framework, so need to call this function here.
 128 */
 129#if defined(CONFIG_SPL_DM) && (!defined(CONFIG_SPL_FRAMEWORK))
 130        dm_init_and_scan(true);
 131#endif
 132        res = fsl_secboot_validate(hdr_addr, CONFIG_SPL_UBOOT_KEY_HASH,
 133                                   &img_addr);
 134
 135        if (res == 0)
 136                printf("SPL: Validation of U-boot successful\n");
 137}
 138
 139#ifdef CONFIG_SPL_FRAMEWORK
 140/* Override weak funtion defined in SPL framework to enable validation
 141 * of main u-boot image before jumping to u-boot image.
 142 */
 143void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image)
 144{
 145        typedef void __noreturn (*image_entry_noargs_t)(void);
 146        uint32_t hdr_addr;
 147
 148        image_entry_noargs_t image_entry =
 149                (image_entry_noargs_t)(unsigned long)spl_image->entry_point;
 150
 151        hdr_addr = (spl_image->entry_point + spl_image->size -
 152                        CONFIG_U_BOOT_HDR_SIZE);
 153        spl_validate_uboot(hdr_addr, (uintptr_t)spl_image->entry_point);
 154        /*
 155         * In case of failure in validation, spl_validate_uboot would
 156         * not return back in case of Production environment with ITS=1.
 157         * Thus U-Boot will not start.
 158         * In Development environment (ITS=0 and SB_EN=1), the function
 159         * may return back in case of non-fatal failures.
 160         */
 161
 162        debug("image entry point: 0x%lX\n", spl_image->entry_point);
 163        image_entry();
 164}
 165#endif /* ifdef CONFIG_SPL_FRAMEWORK */
 166#endif /* ifdef CONFIG_SPL_BUILD */
 167