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 <platform_def.h> 38 #include <semihosting.h> /* For FOPEN_MODE_... */ 39 #include <string.h> 40 41 /* IO devices */ 42 static const io_dev_connector_t *fip_dev_con; 43 static uintptr_t fip_dev_spec; 44 static uintptr_t fip_dev_handle; 45 static const io_dev_connector_t *memmap_dev_con; 46 static uintptr_t memmap_dev_spec; 47 static uintptr_t memmap_init_params; 48 static uintptr_t memmap_dev_handle; 49 50 static const io_block_spec_t fip_block_spec = { 51 .offset = FLASH_BASE, 52 .length = FLASH_SIZE 53 }; 54 55 static const io_file_spec_t bl2_file_spec = { 56 .path = BL2_IMAGE_NAME, 57 .mode = FOPEN_MODE_RB 58 }; 59 60 static const io_file_spec_t bl30_file_spec = { 61 .path = BL30_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 const 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 BL30_IMAGE_NAME, 155 &fip_dev_handle, 156 (uintptr_t)&bl30_file_spec, 157 open_fip 158 }, { 159 BL31_IMAGE_NAME, 160 &fip_dev_handle, 161 (uintptr_t)&bl31_file_spec, 162 open_fip 163 }, { 164 BL32_IMAGE_NAME, 165 &fip_dev_handle, 166 (uintptr_t)&bl32_file_spec, 167 open_fip 168 }, { 169 BL33_IMAGE_NAME, 170 &fip_dev_handle, 171 (uintptr_t)&bl33_file_spec, 172 open_fip 173 }, { 174 #if TRUSTED_BOARD_BOOT 175 BL2_CERT_NAME, 176 &fip_dev_handle, 177 (uintptr_t)&bl2_cert_file_spec, 178 open_fip 179 }, { 180 TRUSTED_KEY_CERT_NAME, 181 &fip_dev_handle, 182 (uintptr_t)&trusted_key_cert_file_spec, 183 open_fip 184 }, { 185 BL30_KEY_CERT_NAME, 186 &fip_dev_handle, 187 (uintptr_t)&bl30_key_cert_file_spec, 188 open_fip 189 }, { 190 BL31_KEY_CERT_NAME, 191 &fip_dev_handle, 192 (uintptr_t)&bl31_key_cert_file_spec, 193 open_fip 194 }, { 195 BL32_KEY_CERT_NAME, 196 &fip_dev_handle, 197 (uintptr_t)&bl32_key_cert_file_spec, 198 open_fip 199 }, { 200 BL33_KEY_CERT_NAME, 201 &fip_dev_handle, 202 (uintptr_t)&bl33_key_cert_file_spec, 203 open_fip 204 }, { 205 BL30_CERT_NAME, 206 &fip_dev_handle, 207 (uintptr_t)&bl30_cert_file_spec, 208 open_fip 209 }, { 210 BL31_CERT_NAME, 211 &fip_dev_handle, 212 (uintptr_t)&bl31_cert_file_spec, 213 open_fip 214 }, { 215 BL32_CERT_NAME, 216 &fip_dev_handle, 217 (uintptr_t)&bl32_cert_file_spec, 218 open_fip 219 }, { 220 BL33_CERT_NAME, 221 &fip_dev_handle, 222 (uintptr_t)&bl33_cert_file_spec, 223 open_fip 224 }, { 225 #endif /* TRUSTED_BOARD_BOOT */ 226 0, 0, 0 227 } 228 }; 229 230 231 static int open_fip(const uintptr_t spec) 232 { 233 int result = IO_FAIL; 234 235 /* See if a Firmware Image Package is available */ 236 result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_NAME); 237 if (result == IO_SUCCESS) { 238 INFO("Using FIP\n"); 239 /*TODO: Check image defined in spec is present in FIP. */ 240 } 241 return result; 242 } 243 244 245 static int open_memmap(const uintptr_t spec) 246 { 247 int result = IO_FAIL; 248 uintptr_t local_image_handle; 249 250 result = io_dev_init(memmap_dev_handle, memmap_init_params); 251 if (result == IO_SUCCESS) { 252 result = io_open(memmap_dev_handle, spec, &local_image_handle); 253 if (result == IO_SUCCESS) { 254 /* INFO("Using Memmap IO\n"); */ 255 io_close(local_image_handle); 256 } 257 } 258 return result; 259 } 260 261 void io_setup(void) 262 { 263 int io_result = IO_FAIL; 264 265 /* Register the IO devices on this platform */ 266 io_result = register_io_dev_fip(&fip_dev_con); 267 assert(io_result == IO_SUCCESS); 268 269 io_result = register_io_dev_memmap(&memmap_dev_con); 270 assert(io_result == IO_SUCCESS); 271 272 /* Open connections to devices and cache the handles */ 273 io_result = io_dev_open(fip_dev_con, fip_dev_spec, &fip_dev_handle); 274 assert(io_result == IO_SUCCESS); 275 276 io_result = io_dev_open(memmap_dev_con, memmap_dev_spec, 277 &memmap_dev_handle); 278 assert(io_result == IO_SUCCESS); 279 280 /* Ignore improbable errors in release builds */ 281 (void)io_result; 282 } 283 284 285 /* Return an IO device handle and specification which can be used to access 286 * an image. Use this to enforce platform load policy */ 287 int plat_get_image_source(const char *image_name, uintptr_t *dev_handle, 288 uintptr_t *image_spec) 289 { 290 int result = IO_FAIL; 291 const struct plat_io_policy *policy; 292 293 if ((image_name != NULL) && (dev_handle != NULL) && 294 (image_spec != NULL)) { 295 policy = policies; 296 while (policy->image_name != NULL) { 297 if (strcmp(policy->image_name, image_name) == 0) { 298 result = policy->check(policy->image_spec); 299 if (result == IO_SUCCESS) { 300 *image_spec = policy->image_spec; 301 *dev_handle = *(policy->dev_handle); 302 break; 303 } 304 } 305 policy++; 306 } 307 } else { 308 result = IO_FAIL; 309 } 310 return result; 311 } 312