1 /* 2 * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are met: 6 * 7 * Redistributions of source code must retain the above copyright notice, this 8 * list of conditions and the following disclaimer. 9 * 10 * Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 14 * Neither the name of ARM nor the names of its contributors may be used 15 * to endorse or promote products derived from this software without specific 16 * prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * POSSIBILITY OF SUCH DAMAGE. 29 */ 30 #include <assert.h> 31 #include <debug.h> 32 #include <firmware_image_package.h> 33 #include <io_driver.h> 34 #include <io_fip.h> 35 #include <io_memmap.h> 36 #include <io_storage.h> 37 #include <platform_def.h> 38 #include <string.h> 39 #include <utils.h> 40 41 /* IO devices */ 42 static const io_dev_connector_t *fip_dev_con; 43 static uintptr_t fip_dev_handle; 44 static const io_dev_connector_t *memmap_dev_con; 45 static uintptr_t memmap_dev_handle; 46 47 static const io_block_spec_t fip_block_spec = { 48 .offset = PLAT_ARM_FIP_BASE, 49 .length = PLAT_ARM_FIP_MAX_SIZE 50 }; 51 52 static const io_uuid_spec_t bl2_uuid_spec = { 53 .uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2, 54 }; 55 56 static const io_uuid_spec_t scp_bl2_uuid_spec = { 57 .uuid = UUID_SCP_FIRMWARE_SCP_BL2, 58 }; 59 60 static const io_uuid_spec_t bl31_uuid_spec = { 61 .uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31, 62 }; 63 64 static const io_uuid_spec_t bl32_uuid_spec = { 65 .uuid = UUID_SECURE_PAYLOAD_BL32, 66 }; 67 68 static const io_uuid_spec_t bl33_uuid_spec = { 69 .uuid = UUID_NON_TRUSTED_FIRMWARE_BL33, 70 }; 71 72 #if TRUSTED_BOARD_BOOT 73 static const io_uuid_spec_t tb_fw_cert_uuid_spec = { 74 .uuid = UUID_TRUSTED_BOOT_FW_CERT, 75 }; 76 77 static const io_uuid_spec_t trusted_key_cert_uuid_spec = { 78 .uuid = UUID_TRUSTED_KEY_CERT, 79 }; 80 81 static const io_uuid_spec_t scp_fw_key_cert_uuid_spec = { 82 .uuid = UUID_SCP_FW_KEY_CERT, 83 }; 84 85 static const io_uuid_spec_t soc_fw_key_cert_uuid_spec = { 86 .uuid = UUID_SOC_FW_KEY_CERT, 87 }; 88 89 static const io_uuid_spec_t tos_fw_key_cert_uuid_spec = { 90 .uuid = UUID_TRUSTED_OS_FW_KEY_CERT, 91 }; 92 93 static const io_uuid_spec_t nt_fw_key_cert_uuid_spec = { 94 .uuid = UUID_NON_TRUSTED_FW_KEY_CERT, 95 }; 96 97 static const io_uuid_spec_t scp_fw_cert_uuid_spec = { 98 .uuid = UUID_SCP_FW_CONTENT_CERT, 99 }; 100 101 static const io_uuid_spec_t soc_fw_cert_uuid_spec = { 102 .uuid = UUID_SOC_FW_CONTENT_CERT, 103 }; 104 105 static const io_uuid_spec_t tos_fw_cert_uuid_spec = { 106 .uuid = UUID_TRUSTED_OS_FW_CONTENT_CERT, 107 }; 108 109 static const io_uuid_spec_t nt_fw_cert_uuid_spec = { 110 .uuid = UUID_NON_TRUSTED_FW_CONTENT_CERT, 111 }; 112 #endif /* TRUSTED_BOARD_BOOT */ 113 114 115 static int open_fip(const uintptr_t spec); 116 static int open_memmap(const uintptr_t spec); 117 118 struct plat_io_policy { 119 uintptr_t *dev_handle; 120 uintptr_t image_spec; 121 int (*check)(const uintptr_t spec); 122 }; 123 124 /* By default, ARM platforms load images from the FIP */ 125 static const struct plat_io_policy policies[] = { 126 [FIP_IMAGE_ID] = { 127 &memmap_dev_handle, 128 (uintptr_t)&fip_block_spec, 129 open_memmap 130 }, 131 [BL2_IMAGE_ID] = { 132 &fip_dev_handle, 133 (uintptr_t)&bl2_uuid_spec, 134 open_fip 135 }, 136 [SCP_BL2_IMAGE_ID] = { 137 &fip_dev_handle, 138 (uintptr_t)&scp_bl2_uuid_spec, 139 open_fip 140 }, 141 [BL31_IMAGE_ID] = { 142 &fip_dev_handle, 143 (uintptr_t)&bl31_uuid_spec, 144 open_fip 145 }, 146 [BL32_IMAGE_ID] = { 147 &fip_dev_handle, 148 (uintptr_t)&bl32_uuid_spec, 149 open_fip 150 }, 151 [BL33_IMAGE_ID] = { 152 &fip_dev_handle, 153 (uintptr_t)&bl33_uuid_spec, 154 open_fip 155 }, 156 #if TRUSTED_BOARD_BOOT 157 [TRUSTED_BOOT_FW_CERT_ID] = { 158 &fip_dev_handle, 159 (uintptr_t)&tb_fw_cert_uuid_spec, 160 open_fip 161 }, 162 [TRUSTED_KEY_CERT_ID] = { 163 &fip_dev_handle, 164 (uintptr_t)&trusted_key_cert_uuid_spec, 165 open_fip 166 }, 167 [SCP_FW_KEY_CERT_ID] = { 168 &fip_dev_handle, 169 (uintptr_t)&scp_fw_key_cert_uuid_spec, 170 open_fip 171 }, 172 [SOC_FW_KEY_CERT_ID] = { 173 &fip_dev_handle, 174 (uintptr_t)&soc_fw_key_cert_uuid_spec, 175 open_fip 176 }, 177 [TRUSTED_OS_FW_KEY_CERT_ID] = { 178 &fip_dev_handle, 179 (uintptr_t)&tos_fw_key_cert_uuid_spec, 180 open_fip 181 }, 182 [NON_TRUSTED_FW_KEY_CERT_ID] = { 183 &fip_dev_handle, 184 (uintptr_t)&nt_fw_key_cert_uuid_spec, 185 open_fip 186 }, 187 [SCP_FW_CONTENT_CERT_ID] = { 188 &fip_dev_handle, 189 (uintptr_t)&scp_fw_cert_uuid_spec, 190 open_fip 191 }, 192 [SOC_FW_CONTENT_CERT_ID] = { 193 &fip_dev_handle, 194 (uintptr_t)&soc_fw_cert_uuid_spec, 195 open_fip 196 }, 197 [TRUSTED_OS_FW_CONTENT_CERT_ID] = { 198 &fip_dev_handle, 199 (uintptr_t)&tos_fw_cert_uuid_spec, 200 open_fip 201 }, 202 [NON_TRUSTED_FW_CONTENT_CERT_ID] = { 203 &fip_dev_handle, 204 (uintptr_t)&nt_fw_cert_uuid_spec, 205 open_fip 206 }, 207 #endif /* TRUSTED_BOARD_BOOT */ 208 }; 209 210 211 /* Weak definitions may be overridden in specific ARM standard platform */ 212 #pragma weak plat_arm_io_setup 213 #pragma weak plat_arm_get_alt_image_source 214 215 216 static int open_fip(const uintptr_t spec) 217 { 218 int result; 219 uintptr_t local_image_handle; 220 221 /* See if a Firmware Image Package is available */ 222 result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID); 223 if (result == 0) { 224 result = io_open(fip_dev_handle, spec, &local_image_handle); 225 if (result == 0) { 226 VERBOSE("Using FIP\n"); 227 io_close(local_image_handle); 228 } 229 } 230 return result; 231 } 232 233 234 static int open_memmap(const uintptr_t spec) 235 { 236 int result; 237 uintptr_t local_image_handle; 238 239 result = io_dev_init(memmap_dev_handle, (uintptr_t)NULL); 240 if (result == 0) { 241 result = io_open(memmap_dev_handle, spec, &local_image_handle); 242 if (result == 0) { 243 VERBOSE("Using Memmap\n"); 244 io_close(local_image_handle); 245 } 246 } 247 return result; 248 } 249 250 251 void arm_io_setup(void) 252 { 253 int io_result; 254 255 io_result = register_io_dev_fip(&fip_dev_con); 256 assert(io_result == 0); 257 258 io_result = register_io_dev_memmap(&memmap_dev_con); 259 assert(io_result == 0); 260 261 /* Open connections to devices and cache the handles */ 262 io_result = io_dev_open(fip_dev_con, (uintptr_t)NULL, 263 &fip_dev_handle); 264 assert(io_result == 0); 265 266 io_result = io_dev_open(memmap_dev_con, (uintptr_t)NULL, 267 &memmap_dev_handle); 268 assert(io_result == 0); 269 270 /* Ignore improbable errors in release builds */ 271 (void)io_result; 272 } 273 274 void plat_arm_io_setup(void) 275 { 276 arm_io_setup(); 277 } 278 279 int plat_arm_get_alt_image_source( 280 unsigned int image_id __unused, 281 uintptr_t *dev_handle __unused, 282 uintptr_t *image_spec __unused) 283 { 284 /* By default do not try an alternative */ 285 return -ENOENT; 286 } 287 288 /* Return an IO device handle and specification which can be used to access 289 * an image. Use this to enforce platform load policy */ 290 int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle, 291 uintptr_t *image_spec) 292 { 293 int result; 294 const struct plat_io_policy *policy; 295 296 assert(image_id < ARRAY_SIZE(policies)); 297 298 policy = &policies[image_id]; 299 result = policy->check(policy->image_spec); 300 if (result == 0) { 301 *image_spec = policy->image_spec; 302 *dev_handle = *(policy->dev_handle); 303 } else { 304 VERBOSE("Trying alternative IO\n"); 305 result = plat_arm_get_alt_image_source(image_id, dev_handle, 306 image_spec); 307 } 308 309 return result; 310 } 311 312 /* 313 * See if a Firmware Image Package is available, 314 * by checking if TOC is valid or not. 315 */ 316 int arm_io_is_toc_valid(void) 317 { 318 int result; 319 320 result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID); 321 322 return (result == 0); 323 } 324 325