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