1 /* 2 * Copyright 2016 NXP Semiconductor, Inc. 3 * 4 * SPDX-License-Identifier: GPL-2.0+ 5 */ 6 #include <common.h> 7 #include <malloc.h> 8 #include <config.h> 9 #include <errno.h> 10 #include <asm/system.h> 11 #include <asm/types.h> 12 #include <asm/arch/soc.h> 13 #ifdef CONFIG_FSL_LSCH3 14 #include <asm/arch/immap_lsch3.h> 15 #elif defined(CONFIG_FSL_LSCH2) 16 #include <asm/arch/immap_lsch2.h> 17 #endif 18 #ifdef CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT 19 #include <asm/armv8/sec_firmware.h> 20 #endif 21 #ifdef CONFIG_CHAIN_OF_TRUST 22 #include <fsl_validate.h> 23 #endif 24 25 #ifdef CONFIG_SYS_LS_PPA_FW_IN_NAND 26 #include <nand.h> 27 #elif defined(CONFIG_SYS_LS_PPA_FW_IN_MMC) 28 #include <mmc.h> 29 #endif 30 31 DECLARE_GLOBAL_DATA_PTR; 32 33 int ppa_init(void) 34 { 35 unsigned int el = current_el(); 36 void *ppa_fit_addr; 37 u32 *boot_loc_ptr_l, *boot_loc_ptr_h; 38 int ret; 39 40 #ifdef CONFIG_CHAIN_OF_TRUST 41 uintptr_t ppa_esbc_hdr = 0; 42 uintptr_t ppa_img_addr = 0; 43 #if defined(CONFIG_SYS_LS_PPA_FW_IN_MMC) || \ 44 defined(CONFIG_SYS_LS_PPA_FW_IN_NAND) 45 void *ppa_hdr_ddr; 46 #endif 47 #endif 48 49 /* Skip if running at lower exception level */ 50 if (el < 3) { 51 debug("Skipping PPA init, running at EL%d\n", el); 52 return 0; 53 } 54 55 #ifdef CONFIG_SYS_LS_PPA_FW_IN_XIP 56 ppa_fit_addr = (void *)CONFIG_SYS_LS_PPA_FW_ADDR; 57 debug("%s: PPA image load from XIP\n", __func__); 58 #ifdef CONFIG_CHAIN_OF_TRUST 59 ppa_esbc_hdr = CONFIG_SYS_LS_PPA_ESBC_ADDR; 60 #endif 61 #else /* !CONFIG_SYS_LS_PPA_FW_IN_XIP */ 62 size_t fw_length, fdt_header_len = sizeof(struct fdt_header); 63 64 /* Copy PPA image from MMC/SD/NAND to allocated memory */ 65 #ifdef CONFIG_SYS_LS_PPA_FW_IN_MMC 66 struct mmc *mmc; 67 int dev = CONFIG_SYS_MMC_ENV_DEV; 68 struct fdt_header *fitp; 69 u32 cnt; 70 u32 blk; 71 72 debug("%s: PPA image load from eMMC/SD\n", __func__); 73 74 ret = mmc_initialize(gd->bd); 75 if (ret) { 76 printf("%s: mmc_initialize() failed\n", __func__); 77 return ret; 78 } 79 mmc = find_mmc_device(dev); 80 if (!mmc) { 81 printf("PPA: MMC cannot find device for PPA firmware\n"); 82 return -ENODEV; 83 } 84 85 ret = mmc_init(mmc); 86 if (ret) { 87 printf("%s: mmc_init() failed\n", __func__); 88 return ret; 89 } 90 91 fitp = malloc(roundup(fdt_header_len, 512)); 92 if (!fitp) { 93 printf("PPA: malloc failed for FIT header(size 0x%zx)\n", 94 roundup(fdt_header_len, 512)); 95 return -ENOMEM; 96 } 97 98 blk = CONFIG_SYS_LS_PPA_FW_ADDR / 512; 99 cnt = DIV_ROUND_UP(fdt_header_len, 512); 100 debug("%s: MMC read PPA FIT header: dev # %u, block # %u, count %u\n", 101 __func__, dev, blk, cnt); 102 ret = mmc->block_dev.block_read(&mmc->block_dev, blk, cnt, fitp); 103 if (ret != cnt) { 104 free(fitp); 105 printf("MMC/SD read of PPA FIT header at offset 0x%x failed\n", 106 CONFIG_SYS_LS_PPA_FW_ADDR); 107 return -EIO; 108 } 109 110 /* flush cache after read */ 111 flush_cache((ulong)fitp, cnt * 512); 112 113 ret = fdt_check_header(fitp); 114 if (ret) { 115 free(fitp); 116 printf("%s: fdt_check_header() failed\n", __func__); 117 return ret; 118 } 119 120 #ifdef CONFIG_CHAIN_OF_TRUST 121 ppa_hdr_ddr = malloc(CONFIG_LS_PPA_ESBC_HDR_SIZE); 122 if (!ppa_hdr_ddr) { 123 printf("PPA: malloc failed for PPA header\n"); 124 return -ENOMEM; 125 } 126 127 blk = CONFIG_SYS_LS_PPA_ESBC_ADDR >> 9; 128 cnt = DIV_ROUND_UP(CONFIG_LS_PPA_ESBC_HDR_SIZE, 512); 129 ret = mmc->block_dev.block_read(&mmc->block_dev, blk, cnt, ppa_hdr_ddr); 130 if (ret != cnt) { 131 free(ppa_hdr_ddr); 132 printf("MMC/SD read of PPA header failed\n"); 133 return -EIO; 134 } 135 debug("Read PPA header to 0x%p\n", ppa_hdr_ddr); 136 137 /* flush cache after read */ 138 flush_cache((ulong)ppa_hdr_ddr, cnt * 512); 139 140 ppa_esbc_hdr = (uintptr_t)ppa_hdr_ddr; 141 #endif 142 143 fw_length = fdt_totalsize(fitp); 144 free(fitp); 145 146 fw_length = roundup(fw_length, 512); 147 ppa_fit_addr = malloc(fw_length); 148 if (!ppa_fit_addr) { 149 printf("PPA: malloc failed for PPA image(size 0x%zx)\n", 150 fw_length); 151 return -ENOMEM; 152 } 153 154 blk = CONFIG_SYS_LS_PPA_FW_ADDR / 512; 155 cnt = DIV_ROUND_UP(fw_length, 512); 156 debug("%s: MMC read PPA FIT image: dev # %u, block # %u, count %u\n", 157 __func__, dev, blk, cnt); 158 ret = mmc->block_dev.block_read(&mmc->block_dev, 159 blk, cnt, ppa_fit_addr); 160 if (ret != cnt) { 161 free(ppa_fit_addr); 162 printf("MMC/SD read of PPA FIT header at offset 0x%x failed\n", 163 CONFIG_SYS_LS_PPA_FW_ADDR); 164 return -EIO; 165 } 166 167 /* flush cache after read */ 168 flush_cache((ulong)ppa_fit_addr, cnt * 512); 169 170 #elif defined(CONFIG_SYS_LS_PPA_FW_IN_NAND) 171 struct fdt_header fit; 172 173 debug("%s: PPA image load from NAND\n", __func__); 174 175 nand_init(); 176 ret = nand_read(get_nand_dev_by_index(0), 177 (loff_t)CONFIG_SYS_LS_PPA_FW_ADDR, 178 &fdt_header_len, (u_char *)&fit); 179 if (ret == -EUCLEAN) { 180 printf("NAND read of PPA FIT header at offset 0x%x failed\n", 181 CONFIG_SYS_LS_PPA_FW_ADDR); 182 return -EIO; 183 } 184 185 ret = fdt_check_header(&fit); 186 if (ret) { 187 printf("%s: fdt_check_header() failed\n", __func__); 188 return ret; 189 } 190 191 #ifdef CONFIG_CHAIN_OF_TRUST 192 ppa_hdr_ddr = malloc(CONFIG_LS_PPA_ESBC_HDR_SIZE); 193 if (!ppa_hdr_ddr) { 194 printf("PPA: malloc failed for PPA header\n"); 195 return -ENOMEM; 196 } 197 198 fw_length = CONFIG_LS_PPA_ESBC_HDR_SIZE; 199 200 ret = nand_read(get_nand_dev_by_index(0), 201 (loff_t)CONFIG_SYS_LS_PPA_ESBC_ADDR, 202 &fw_length, (u_char *)ppa_hdr_ddr); 203 if (ret == -EUCLEAN) { 204 free(ppa_hdr_ddr); 205 printf("NAND read of PPA firmware at offset 0x%x failed\n", 206 CONFIG_SYS_LS_PPA_FW_ADDR); 207 return -EIO; 208 } 209 debug("Read PPA header to 0x%p\n", ppa_hdr_ddr); 210 211 /* flush cache after read */ 212 flush_cache((ulong)ppa_hdr_ddr, fw_length); 213 214 ppa_esbc_hdr = (uintptr_t)ppa_hdr_ddr; 215 #endif 216 217 fw_length = fdt_totalsize(&fit); 218 219 ppa_fit_addr = malloc(fw_length); 220 if (!ppa_fit_addr) { 221 printf("PPA: malloc failed for PPA image(size 0x%zx)\n", 222 fw_length); 223 return -ENOMEM; 224 } 225 226 ret = nand_read(get_nand_dev_by_index(0), 227 (loff_t)CONFIG_SYS_LS_PPA_FW_ADDR, 228 &fw_length, (u_char *)ppa_fit_addr); 229 if (ret == -EUCLEAN) { 230 free(ppa_fit_addr); 231 printf("NAND read of PPA firmware at offset 0x%x failed\n", 232 CONFIG_SYS_LS_PPA_FW_ADDR); 233 return -EIO; 234 } 235 236 /* flush cache after read */ 237 flush_cache((ulong)ppa_fit_addr, fw_length); 238 #else 239 #error "No CONFIG_SYS_LS_PPA_FW_IN_xxx defined" 240 #endif 241 242 #endif 243 244 #ifdef CONFIG_CHAIN_OF_TRUST 245 ppa_img_addr = (uintptr_t)ppa_fit_addr; 246 if (fsl_check_boot_mode_secure() != 0) { 247 /* 248 * In case of failure in validation, fsl_secboot_validate 249 * would not return back in case of Production environment 250 * with ITS=1. In Development environment (ITS=0 and 251 * SB_EN=1), the function may return back in case of 252 * non-fatal failures. 253 */ 254 ret = fsl_secboot_validate(ppa_esbc_hdr, 255 PPA_KEY_HASH, 256 &ppa_img_addr); 257 if (ret != 0) 258 printf("PPA validation failed\n"); 259 else 260 printf("PPA validation Successful\n"); 261 } 262 #if defined(CONFIG_SYS_LS_PPA_FW_IN_MMC) || \ 263 defined(CONFIG_SYS_LS_PPA_FW_IN_NAND) 264 free(ppa_hdr_ddr); 265 #endif 266 #endif 267 268 #ifdef CONFIG_FSL_LSCH3 269 struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR); 270 boot_loc_ptr_l = &gur->bootlocptrl; 271 boot_loc_ptr_h = &gur->bootlocptrh; 272 #elif defined(CONFIG_FSL_LSCH2) 273 struct ccsr_scfg __iomem *scfg = (void *)(CONFIG_SYS_FSL_SCFG_ADDR); 274 boot_loc_ptr_l = &scfg->scratchrw[1]; 275 boot_loc_ptr_h = &scfg->scratchrw[0]; 276 #endif 277 278 debug("fsl-ppa: boot_loc_ptr_l = 0x%p, boot_loc_ptr_h =0x%p\n", 279 boot_loc_ptr_l, boot_loc_ptr_h); 280 ret = sec_firmware_init(ppa_fit_addr, boot_loc_ptr_l, boot_loc_ptr_h); 281 282 #if defined(CONFIG_SYS_LS_PPA_FW_IN_MMC) || \ 283 defined(CONFIG_SYS_LS_PPA_FW_IN_NAND) 284 free(ppa_fit_addr); 285 #endif 286 287 return ret; 288 } 289