Home | History | Annotate | Download | only in fvp
      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