1 /* 2 * Copyright (c) 2015, 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 <io_driver.h> 33 #include <io_fip.h> 34 #include <io_memmap.h> 35 #include <io_storage.h> 36 #include <platform_def.h> 37 #include <semihosting.h> /* For FOPEN_MODE_... */ 38 #include <string.h> 39 40 /* IO devices */ 41 static const io_dev_connector_t *fip_dev_con; 42 static uintptr_t fip_dev_handle; 43 static const io_dev_connector_t *memmap_dev_con; 44 static uintptr_t memmap_dev_handle; 45 46 static const io_block_spec_t fip_block_spec = { 47 .offset = PLAT_ARM_FIP_BASE, 48 .length = PLAT_ARM_FIP_MAX_SIZE 49 }; 50 51 static const io_file_spec_t bl2_file_spec = { 52 .path = BL2_IMAGE_NAME, 53 .mode = FOPEN_MODE_RB 54 }; 55 56 static const io_file_spec_t bl30_file_spec = { 57 .path = BL30_IMAGE_NAME, 58 .mode = FOPEN_MODE_RB 59 }; 60 61 static const io_file_spec_t bl31_file_spec = { 62 .path = BL31_IMAGE_NAME, 63 .mode = FOPEN_MODE_RB 64 }; 65 66 static const io_file_spec_t bl32_file_spec = { 67 .path = BL32_IMAGE_NAME, 68 .mode = FOPEN_MODE_RB 69 }; 70 71 static const io_file_spec_t bl33_file_spec = { 72 .path = BL33_IMAGE_NAME, 73 .mode = FOPEN_MODE_RB 74 }; 75 76 #if TRUSTED_BOARD_BOOT 77 static const io_file_spec_t bl2_cert_file_spec = { 78 .path = BL2_CERT_NAME, 79 .mode = FOPEN_MODE_RB 80 }; 81 82 static const io_file_spec_t trusted_key_cert_file_spec = { 83 .path = TRUSTED_KEY_CERT_NAME, 84 .mode = FOPEN_MODE_RB 85 }; 86 87 static const io_file_spec_t bl30_key_cert_file_spec = { 88 .path = BL30_KEY_CERT_NAME, 89 .mode = FOPEN_MODE_RB 90 }; 91 92 static const io_file_spec_t bl31_key_cert_file_spec = { 93 .path = BL31_KEY_CERT_NAME, 94 .mode = FOPEN_MODE_RB 95 }; 96 97 static const io_file_spec_t bl32_key_cert_file_spec = { 98 .path = BL32_KEY_CERT_NAME, 99 .mode = FOPEN_MODE_RB 100 }; 101 102 static const io_file_spec_t bl33_key_cert_file_spec = { 103 .path = BL33_KEY_CERT_NAME, 104 .mode = FOPEN_MODE_RB 105 }; 106 107 static const io_file_spec_t bl30_cert_file_spec = { 108 .path = BL30_CERT_NAME, 109 .mode = FOPEN_MODE_RB 110 }; 111 112 static const io_file_spec_t bl31_cert_file_spec = { 113 .path = BL31_CERT_NAME, 114 .mode = FOPEN_MODE_RB 115 }; 116 117 static const io_file_spec_t bl32_cert_file_spec = { 118 .path = BL32_CERT_NAME, 119 .mode = FOPEN_MODE_RB 120 }; 121 122 static const io_file_spec_t bl33_cert_file_spec = { 123 .path = BL33_CERT_NAME, 124 .mode = FOPEN_MODE_RB 125 }; 126 #endif /* TRUSTED_BOARD_BOOT */ 127 128 static int open_fip(const uintptr_t spec); 129 static int open_memmap(const uintptr_t spec); 130 131 struct plat_io_policy { 132 const char *image_name; 133 uintptr_t *dev_handle; 134 uintptr_t image_spec; 135 int (*check)(const uintptr_t spec); 136 }; 137 138 static const struct plat_io_policy policies[] = { 139 { 140 FIP_IMAGE_NAME, 141 &memmap_dev_handle, 142 (uintptr_t)&fip_block_spec, 143 open_memmap 144 }, { 145 BL2_IMAGE_NAME, 146 &fip_dev_handle, 147 (uintptr_t)&bl2_file_spec, 148 open_fip 149 }, { 150 BL30_IMAGE_NAME, 151 &fip_dev_handle, 152 (uintptr_t)&bl30_file_spec, 153 open_fip 154 }, { 155 BL31_IMAGE_NAME, 156 &fip_dev_handle, 157 (uintptr_t)&bl31_file_spec, 158 open_fip 159 }, { 160 BL32_IMAGE_NAME, 161 &fip_dev_handle, 162 (uintptr_t)&bl32_file_spec, 163 open_fip 164 }, { 165 BL33_IMAGE_NAME, 166 &fip_dev_handle, 167 (uintptr_t)&bl33_file_spec, 168 open_fip 169 }, { 170 #if TRUSTED_BOARD_BOOT 171 BL2_CERT_NAME, 172 &fip_dev_handle, 173 (uintptr_t)&bl2_cert_file_spec, 174 open_fip 175 }, { 176 TRUSTED_KEY_CERT_NAME, 177 &fip_dev_handle, 178 (uintptr_t)&trusted_key_cert_file_spec, 179 open_fip 180 }, { 181 BL30_KEY_CERT_NAME, 182 &fip_dev_handle, 183 (uintptr_t)&bl30_key_cert_file_spec, 184 open_fip 185 }, { 186 BL31_KEY_CERT_NAME, 187 &fip_dev_handle, 188 (uintptr_t)&bl31_key_cert_file_spec, 189 open_fip 190 }, { 191 BL32_KEY_CERT_NAME, 192 &fip_dev_handle, 193 (uintptr_t)&bl32_key_cert_file_spec, 194 open_fip 195 }, { 196 BL33_KEY_CERT_NAME, 197 &fip_dev_handle, 198 (uintptr_t)&bl33_key_cert_file_spec, 199 open_fip 200 }, { 201 BL30_CERT_NAME, 202 &fip_dev_handle, 203 (uintptr_t)&bl30_cert_file_spec, 204 open_fip 205 }, { 206 BL31_CERT_NAME, 207 &fip_dev_handle, 208 (uintptr_t)&bl31_cert_file_spec, 209 open_fip 210 }, { 211 BL32_CERT_NAME, 212 &fip_dev_handle, 213 (uintptr_t)&bl32_cert_file_spec, 214 open_fip 215 }, { 216 BL33_CERT_NAME, 217 &fip_dev_handle, 218 (uintptr_t)&bl33_cert_file_spec, 219 open_fip 220 }, { 221 #endif /* TRUSTED_BOARD_BOOT */ 222 0, 0, 0 223 } 224 }; 225 226 227 /* Weak definitions may be overridden in specific ARM standard platform */ 228 #pragma weak plat_arm_io_setup 229 #pragma weak plat_arm_get_alt_image_source 230 231 232 static int open_fip(const uintptr_t spec) 233 { 234 int result; 235 uintptr_t local_image_handle; 236 237 /* See if a Firmware Image Package is available */ 238 result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_NAME); 239 if (result == IO_SUCCESS) { 240 result = io_open(fip_dev_handle, spec, &local_image_handle); 241 if (result == IO_SUCCESS) { 242 VERBOSE("Using FIP\n"); 243 io_close(local_image_handle); 244 } 245 } 246 return result; 247 } 248 249 250 static int open_memmap(const uintptr_t spec) 251 { 252 int result; 253 uintptr_t local_image_handle; 254 255 result = io_dev_init(memmap_dev_handle, (uintptr_t)NULL); 256 if (result == IO_SUCCESS) { 257 result = io_open(memmap_dev_handle, spec, &local_image_handle); 258 if (result == IO_SUCCESS) { 259 VERBOSE("Using Memmap\n"); 260 io_close(local_image_handle); 261 } 262 } 263 return result; 264 } 265 266 267 void arm_io_setup(void) 268 { 269 int io_result; 270 271 io_result = register_io_dev_fip(&fip_dev_con); 272 assert(io_result == IO_SUCCESS); 273 274 io_result = register_io_dev_memmap(&memmap_dev_con); 275 assert(io_result == IO_SUCCESS); 276 277 /* Open connections to devices and cache the handles */ 278 io_result = io_dev_open(fip_dev_con, (uintptr_t)NULL, 279 &fip_dev_handle); 280 assert(io_result == IO_SUCCESS); 281 282 io_result = io_dev_open(memmap_dev_con, (uintptr_t)NULL, 283 &memmap_dev_handle); 284 assert(io_result == IO_SUCCESS); 285 286 /* Ignore improbable errors in release builds */ 287 (void)io_result; 288 } 289 290 void plat_arm_io_setup(void) 291 { 292 arm_io_setup(); 293 } 294 295 int plat_arm_get_alt_image_source( 296 const uintptr_t image_spec __attribute__((unused)), 297 uintptr_t *dev_handle __attribute__((unused))) 298 { 299 /* By default do not try an alternative */ 300 return IO_FAIL; 301 } 302 303 /* Return an IO device handle and specification which can be used to access 304 * an image. Use this to enforce platform load policy */ 305 int plat_get_image_source(const char *image_name, uintptr_t *dev_handle, 306 uintptr_t *image_spec) 307 { 308 int result = IO_FAIL; 309 const struct plat_io_policy *policy; 310 311 if ((image_name != NULL) && (dev_handle != NULL) && 312 (image_spec != NULL)) { 313 policy = policies; 314 while (policy->image_name != NULL) { 315 if (strcmp(policy->image_name, image_name) == 0) { 316 result = policy->check(policy->image_spec); 317 if (result == IO_SUCCESS) { 318 *image_spec = policy->image_spec; 319 *dev_handle = *(policy->dev_handle); 320 break; 321 } 322 VERBOSE("Trying alternative IO\n"); 323 result = plat_arm_get_alt_image_source( 324 policy->image_spec, 325 dev_handle); 326 if (result == IO_SUCCESS) { 327 *image_spec = policy->image_spec; 328 break; 329 } 330 } 331 policy++; 332 } 333 } else { 334 result = IO_FAIL; 335 } 336 return result; 337 } 338