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