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(nand_info[0], (loff_t)CONFIG_SYS_LS_PPA_FW_ADDR, 177 &fdt_header_len, (u_char *)&fit); 178 if (ret == -EUCLEAN) { 179 printf("NAND read of PPA FIT header at offset 0x%x failed\n", 180 CONFIG_SYS_LS_PPA_FW_ADDR); 181 return -EIO; 182 } 183 184 ret = fdt_check_header(&fit); 185 if (ret) { 186 printf("%s: fdt_check_header() failed\n", __func__); 187 return ret; 188 } 189 190 #ifdef CONFIG_CHAIN_OF_TRUST 191 ppa_hdr_ddr = malloc(CONFIG_LS_PPA_ESBC_HDR_SIZE); 192 if (!ppa_hdr_ddr) { 193 printf("PPA: malloc failed for PPA header\n"); 194 return -ENOMEM; 195 } 196 197 fw_length = CONFIG_LS_PPA_ESBC_HDR_SIZE; 198 199 ret = nand_read(nand_info[0], (loff_t)CONFIG_SYS_LS_PPA_ESBC_ADDR, 200 &fw_length, (u_char *)ppa_hdr_ddr); 201 if (ret == -EUCLEAN) { 202 free(ppa_hdr_ddr); 203 printf("NAND read of PPA firmware at offset 0x%x failed\n", 204 CONFIG_SYS_LS_PPA_FW_ADDR); 205 return -EIO; 206 } 207 debug("Read PPA header to 0x%p\n", ppa_hdr_ddr); 208 209 /* flush cache after read */ 210 flush_cache((ulong)ppa_hdr_ddr, fw_length); 211 212 ppa_esbc_hdr = (uintptr_t)ppa_hdr_ddr; 213 #endif 214 215 fw_length = fdt_totalsize(&fit); 216 217 ppa_fit_addr = malloc(fw_length); 218 if (!ppa_fit_addr) { 219 printf("PPA: malloc failed for PPA image(size 0x%zx)\n", 220 fw_length); 221 return -ENOMEM; 222 } 223 224 ret = nand_read(nand_info[0], (loff_t)CONFIG_SYS_LS_PPA_FW_ADDR, 225 &fw_length, (u_char *)ppa_fit_addr); 226 if (ret == -EUCLEAN) { 227 free(ppa_fit_addr); 228 printf("NAND read of PPA firmware at offset 0x%x failed\n", 229 CONFIG_SYS_LS_PPA_FW_ADDR); 230 return -EIO; 231 } 232 233 /* flush cache after read */ 234 flush_cache((ulong)ppa_fit_addr, fw_length); 235 #else 236 #error "No CONFIG_SYS_LS_PPA_FW_IN_xxx defined" 237 #endif 238 239 #endif 240 241 #ifdef CONFIG_CHAIN_OF_TRUST 242 ppa_img_addr = (uintptr_t)ppa_fit_addr; 243 if (fsl_check_boot_mode_secure() != 0) { 244 /* 245 * In case of failure in validation, fsl_secboot_validate 246 * would not return back in case of Production environment 247 * with ITS=1. In Development environment (ITS=0 and 248 * SB_EN=1), the function may return back in case of 249 * non-fatal failures. 250 */ 251 ret = fsl_secboot_validate(ppa_esbc_hdr, 252 PPA_KEY_HASH, 253 &ppa_img_addr); 254 if (ret != 0) 255 printf("PPA validation failed\n"); 256 else 257 printf("PPA validation Successful\n"); 258 } 259 #if defined(CONFIG_SYS_LS_PPA_FW_IN_MMC) || \ 260 defined(CONFIG_SYS_LS_PPA_FW_IN_NAND) 261 free(ppa_hdr_ddr); 262 #endif 263 #endif 264 265 #ifdef CONFIG_FSL_LSCH3 266 struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR); 267 boot_loc_ptr_l = &gur->bootlocptrl; 268 boot_loc_ptr_h = &gur->bootlocptrh; 269 #elif defined(CONFIG_FSL_LSCH2) 270 struct ccsr_scfg __iomem *scfg = (void *)(CONFIG_SYS_FSL_SCFG_ADDR); 271 boot_loc_ptr_l = &scfg->scratchrw[1]; 272 boot_loc_ptr_h = &scfg->scratchrw[0]; 273 #endif 274 275 debug("fsl-ppa: boot_loc_ptr_l = 0x%p, boot_loc_ptr_h =0x%p\n", 276 boot_loc_ptr_l, boot_loc_ptr_h); 277 ret = sec_firmware_init(ppa_fit_addr, boot_loc_ptr_l, boot_loc_ptr_h); 278 279 #if defined(CONFIG_SYS_LS_PPA_FW_IN_MMC) || \ 280 defined(CONFIG_SYS_LS_PPA_FW_IN_NAND) 281 free(ppa_fit_addr); 282 #endif 283 284 return ret; 285 } 286