1 /* 2 * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <assert.h> 8 9 #include <common/debug.h> 10 #include <drivers/io/io_block.h> 11 #include <drivers/io/io_driver.h> 12 #include <drivers/io/io_fip.h> 13 #include <drivers/io/io_memmap.h> 14 #include <drivers/mmc.h> 15 #include <lib/utils_def.h> 16 #include <tbbr_img_def.h> 17 #include <tools_share/firmware_image_package.h> 18 19 #include <platform_def.h> 20 21 static const io_dev_connector_t *fip_dev_con; 22 static uintptr_t fip_dev_handle; 23 24 #ifndef IMX_FIP_MMAP 25 static const io_dev_connector_t *mmc_dev_con; 26 static uintptr_t mmc_dev_handle; 27 28 static const io_block_spec_t mmc_fip_spec = { 29 .offset = IMX_FIP_MMC_BASE, 30 .length = IMX_FIP_SIZE 31 }; 32 33 static const io_block_dev_spec_t mmc_dev_spec = { 34 /* It's used as temp buffer in block driver. */ 35 .buffer = { 36 .offset = IMX_FIP_BASE, 37 /* do we need a new value? */ 38 .length = IMX_FIP_SIZE 39 }, 40 .ops = { 41 .read = mmc_read_blocks, 42 .write = mmc_write_blocks, 43 }, 44 .block_size = MMC_BLOCK_SIZE, 45 }; 46 47 static int open_mmc(const uintptr_t spec); 48 49 #else 50 static const io_dev_connector_t *memmap_dev_con; 51 static uintptr_t memmap_dev_handle; 52 53 static const io_block_spec_t fip_block_spec = { 54 .offset = IMX_FIP_BASE, 55 .length = IMX_FIP_SIZE 56 }; 57 static int open_memmap(const uintptr_t spec); 58 #endif 59 60 static int open_fip(const uintptr_t spec); 61 62 static const io_uuid_spec_t bl31_uuid_spec = { 63 .uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31, 64 }; 65 66 static const io_uuid_spec_t bl32_uuid_spec = { 67 .uuid = UUID_SECURE_PAYLOAD_BL32, 68 }; 69 70 static const io_uuid_spec_t bl32_extra1_uuid_spec = { 71 .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA1, 72 }; 73 74 static const io_uuid_spec_t bl32_extra2_uuid_spec = { 75 .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA2, 76 }; 77 78 static const io_uuid_spec_t bl33_uuid_spec = { 79 .uuid = UUID_NON_TRUSTED_FIRMWARE_BL33, 80 }; 81 82 #if TRUSTED_BOARD_BOOT 83 static const io_uuid_spec_t tb_fw_cert_uuid_spec = { 84 .uuid = UUID_TRUSTED_BOOT_FW_CERT, 85 }; 86 87 static const io_uuid_spec_t trusted_key_cert_uuid_spec = { 88 .uuid = UUID_TRUSTED_KEY_CERT, 89 }; 90 91 static const io_uuid_spec_t soc_fw_key_cert_uuid_spec = { 92 .uuid = UUID_SOC_FW_KEY_CERT, 93 }; 94 95 static const io_uuid_spec_t tos_fw_key_cert_uuid_spec = { 96 .uuid = UUID_TRUSTED_OS_FW_KEY_CERT, 97 }; 98 99 static const io_uuid_spec_t tos_fw_cert_uuid_spec = { 100 .uuid = UUID_TRUSTED_OS_FW_CONTENT_CERT, 101 }; 102 103 static const io_uuid_spec_t soc_fw_content_cert_uuid_spec = { 104 .uuid = UUID_SOC_FW_CONTENT_CERT, 105 }; 106 107 static const io_uuid_spec_t nt_fw_key_cert_uuid_spec = { 108 .uuid = UUID_NON_TRUSTED_FW_KEY_CERT, 109 }; 110 111 static const io_uuid_spec_t nt_fw_cert_uuid_spec = { 112 .uuid = UUID_NON_TRUSTED_FW_CONTENT_CERT, 113 }; 114 #endif /* TRUSTED_BOARD_BOOT */ 115 116 /* TODO: this structure is replicated multiple times. rationalize it ! */ 117 struct plat_io_policy { 118 uintptr_t *dev_handle; 119 uintptr_t image_spec; 120 int (*check)(const uintptr_t spec); 121 }; 122 123 static const struct plat_io_policy policies[] = { 124 #ifndef IMX_FIP_MMAP 125 [FIP_IMAGE_ID] = { 126 &mmc_dev_handle, 127 (uintptr_t)&mmc_fip_spec, 128 open_mmc 129 }, 130 #else 131 [FIP_IMAGE_ID] = { 132 &memmap_dev_handle, 133 (uintptr_t)&fip_block_spec, 134 open_memmap 135 }, 136 #endif 137 [BL31_IMAGE_ID] = { 138 &fip_dev_handle, 139 (uintptr_t)&bl31_uuid_spec, 140 open_fip 141 }, 142 [BL32_IMAGE_ID] = { 143 &fip_dev_handle, 144 (uintptr_t)&bl32_uuid_spec, 145 open_fip 146 }, 147 [BL32_EXTRA1_IMAGE_ID] = { 148 &fip_dev_handle, 149 (uintptr_t)&bl32_extra1_uuid_spec, 150 open_fip 151 }, 152 [BL32_EXTRA2_IMAGE_ID] = { 153 &fip_dev_handle, 154 (uintptr_t)&bl32_extra2_uuid_spec, 155 open_fip 156 }, 157 [BL33_IMAGE_ID] = { 158 &fip_dev_handle, 159 (uintptr_t)&bl33_uuid_spec, 160 open_fip 161 }, 162 #if TRUSTED_BOARD_BOOT 163 [TRUSTED_BOOT_FW_CERT_ID] = { 164 &fip_dev_handle, 165 (uintptr_t)&tb_fw_cert_uuid_spec, 166 open_fip 167 }, 168 [SOC_FW_KEY_CERT_ID] = { 169 &fip_dev_handle, 170 (uintptr_t)&soc_fw_key_cert_uuid_spec, 171 open_fip 172 }, 173 [TRUSTED_KEY_CERT_ID] = { 174 &fip_dev_handle, 175 (uintptr_t)&trusted_key_cert_uuid_spec, 176 open_fip 177 }, 178 [TRUSTED_OS_FW_KEY_CERT_ID] = { 179 &fip_dev_handle, 180 (uintptr_t)&tos_fw_key_cert_uuid_spec, 181 open_fip 182 }, 183 [NON_TRUSTED_FW_KEY_CERT_ID] = { 184 &fip_dev_handle, 185 (uintptr_t)&nt_fw_key_cert_uuid_spec, 186 open_fip 187 }, 188 [SOC_FW_CONTENT_CERT_ID] = { 189 &fip_dev_handle, 190 (uintptr_t)&soc_fw_content_cert_uuid_spec, 191 open_fip 192 }, 193 [TRUSTED_OS_FW_CONTENT_CERT_ID] = { 194 &fip_dev_handle, 195 (uintptr_t)&tos_fw_cert_uuid_spec, 196 open_fip 197 }, 198 [NON_TRUSTED_FW_CONTENT_CERT_ID] = { 199 &fip_dev_handle, 200 (uintptr_t)&nt_fw_cert_uuid_spec, 201 open_fip 202 }, 203 #endif /* TRUSTED_BOARD_BOOT */ 204 }; 205 206 static int open_fip(const uintptr_t spec) 207 { 208 int result; 209 uintptr_t local_image_handle; 210 211 /* See if a Firmware Image Package is available */ 212 result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID); 213 if (result == 0) { 214 result = io_open(fip_dev_handle, spec, &local_image_handle); 215 if (result == 0) { 216 VERBOSE("Using FIP\n"); 217 io_close(local_image_handle); 218 } 219 } 220 return result; 221 } 222 223 #ifndef IMX_FIP_MMAP 224 static int open_mmc(const uintptr_t spec) 225 { 226 int result; 227 uintptr_t local_handle; 228 229 result = io_dev_init(mmc_dev_handle, (uintptr_t)NULL); 230 if (result == 0) { 231 result = io_open(mmc_dev_handle, spec, &local_handle); 232 if (result == 0) { 233 io_close(local_handle); 234 } 235 } 236 return result; 237 } 238 #else 239 static int open_memmap(const uintptr_t spec) 240 { 241 int result; 242 uintptr_t local_image_handle; 243 244 result = io_dev_init(memmap_dev_handle, (uintptr_t)NULL); 245 if (result == 0) { 246 result = io_open(memmap_dev_handle, spec, &local_image_handle); 247 if (result == 0) { 248 VERBOSE("Using Memmap\n"); 249 io_close(local_image_handle); 250 } 251 } 252 return result; 253 } 254 #endif 255 256 int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle, 257 uintptr_t *image_spec) 258 { 259 int result; 260 const struct plat_io_policy *policy; 261 262 assert(image_id < ARRAY_SIZE(policies)); 263 264 policy = &policies[image_id]; 265 result = policy->check(policy->image_spec); 266 assert(result == 0); 267 268 *image_spec = policy->image_spec; 269 *dev_handle = *policy->dev_handle; 270 271 return result; 272 } 273 274 void plat_imx_io_setup(void) 275 { 276 int result __unused; 277 278 #ifndef IMX_FIP_MMAP 279 result = register_io_dev_block(&mmc_dev_con); 280 assert(result == 0); 281 282 result = io_dev_open(mmc_dev_con, (uintptr_t)&mmc_dev_spec, 283 &mmc_dev_handle); 284 assert(result == 0); 285 286 #else 287 result = register_io_dev_memmap(&memmap_dev_con); 288 assert(result == 0); 289 290 result = io_dev_open(memmap_dev_con, (uintptr_t)NULL, 291 &memmap_dev_handle); 292 assert(result == 0); 293 #endif 294 295 result = register_io_dev_fip(&fip_dev_con); 296 assert(result == 0); 297 298 result = io_dev_open(fip_dev_con, (uintptr_t)NULL, 299 &fip_dev_handle); 300 assert(result == 0); 301 } 302