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