Home | History | Annotate | Download | only in qemu
      1 /*
      2  * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
      3  *
      4  * SPDX-License-Identifier: BSD-3-Clause
      5  */
      6 
      7 #include <assert.h>
      8 #include <bl_common.h>		/* For ARRAY_SIZE */
      9 #include <debug.h>
     10 #include <firmware_image_package.h>
     11 #include <io_driver.h>
     12 #include <io_fip.h>
     13 #include <io_memmap.h>
     14 #include <io_semihosting.h>
     15 #include <io_storage.h>
     16 #include <platform_def.h>
     17 #include <semihosting.h>
     18 #include <string.h>
     19 
     20 /* Semihosting filenames */
     21 #define BL2_IMAGE_NAME			"bl2.bin"
     22 #define BL31_IMAGE_NAME			"bl31.bin"
     23 #define BL32_IMAGE_NAME			"bl32.bin"
     24 #define BL32_EXTRA1_IMAGE_NAME		"bl32_extra1.bin"
     25 #define BL32_EXTRA2_IMAGE_NAME		"bl32_extra2.bin"
     26 #define BL33_IMAGE_NAME			"bl33.bin"
     27 
     28 #if TRUSTED_BOARD_BOOT
     29 #define TRUSTED_BOOT_FW_CERT_NAME	"tb_fw.crt"
     30 #define TRUSTED_KEY_CERT_NAME		"trusted_key.crt"
     31 #define SOC_FW_KEY_CERT_NAME		"soc_fw_key.crt"
     32 #define TOS_FW_KEY_CERT_NAME		"tos_fw_key.crt"
     33 #define NT_FW_KEY_CERT_NAME		"nt_fw_key.crt"
     34 #define SOC_FW_CONTENT_CERT_NAME	"soc_fw_content.crt"
     35 #define TOS_FW_CONTENT_CERT_NAME	"tos_fw_content.crt"
     36 #define NT_FW_CONTENT_CERT_NAME		"nt_fw_content.crt"
     37 #endif /* TRUSTED_BOARD_BOOT */
     38 
     39 
     40 
     41 /* IO devices */
     42 static const io_dev_connector_t *fip_dev_con;
     43 static uintptr_t fip_dev_handle;
     44 static const io_dev_connector_t *memmap_dev_con;
     45 static uintptr_t memmap_dev_handle;
     46 static const io_dev_connector_t *sh_dev_con;
     47 static uintptr_t sh_dev_handle;
     48 
     49 static const io_block_spec_t fip_block_spec = {
     50 	.offset = PLAT_QEMU_FIP_BASE,
     51 	.length = PLAT_QEMU_FIP_MAX_SIZE
     52 };
     53 
     54 static const io_uuid_spec_t bl2_uuid_spec = {
     55 	.uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2,
     56 };
     57 
     58 static const io_uuid_spec_t bl31_uuid_spec = {
     59 	.uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31,
     60 };
     61 
     62 static const io_uuid_spec_t bl32_uuid_spec = {
     63 	.uuid = UUID_SECURE_PAYLOAD_BL32,
     64 };
     65 
     66 static const io_uuid_spec_t bl32_extra1_uuid_spec = {
     67 	.uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA1,
     68 };
     69 
     70 static const io_uuid_spec_t bl32_extra2_uuid_spec = {
     71 	.uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA2,
     72 };
     73 
     74 static const io_uuid_spec_t bl33_uuid_spec = {
     75 	.uuid = UUID_NON_TRUSTED_FIRMWARE_BL33,
     76 };
     77 
     78 #if TRUSTED_BOARD_BOOT
     79 static const io_uuid_spec_t tb_fw_cert_uuid_spec = {
     80 	.uuid = UUID_TRUSTED_BOOT_FW_CERT,
     81 };
     82 
     83 static const io_uuid_spec_t trusted_key_cert_uuid_spec = {
     84 	.uuid = UUID_TRUSTED_KEY_CERT,
     85 };
     86 
     87 static const io_uuid_spec_t soc_fw_key_cert_uuid_spec = {
     88 	.uuid = UUID_SOC_FW_KEY_CERT,
     89 };
     90 
     91 static const io_uuid_spec_t tos_fw_key_cert_uuid_spec = {
     92 	.uuid = UUID_TRUSTED_OS_FW_KEY_CERT,
     93 };
     94 
     95 static const io_uuid_spec_t nt_fw_key_cert_uuid_spec = {
     96 	.uuid = UUID_NON_TRUSTED_FW_KEY_CERT,
     97 };
     98 
     99 static const io_uuid_spec_t soc_fw_cert_uuid_spec = {
    100 	.uuid = UUID_SOC_FW_CONTENT_CERT,
    101 };
    102 
    103 static const io_uuid_spec_t tos_fw_cert_uuid_spec = {
    104 	.uuid = UUID_TRUSTED_OS_FW_CONTENT_CERT,
    105 };
    106 
    107 static const io_uuid_spec_t nt_fw_cert_uuid_spec = {
    108 	.uuid = UUID_NON_TRUSTED_FW_CONTENT_CERT,
    109 };
    110 #endif /* TRUSTED_BOARD_BOOT */
    111 
    112 static const io_file_spec_t sh_file_spec[] = {
    113 	[BL2_IMAGE_ID] = {
    114 		.path = BL2_IMAGE_NAME,
    115 		.mode = FOPEN_MODE_RB
    116 	},
    117 	[BL31_IMAGE_ID] = {
    118 		.path = BL31_IMAGE_NAME,
    119 		.mode = FOPEN_MODE_RB
    120 	},
    121 	[BL32_IMAGE_ID] = {
    122 		.path = BL32_IMAGE_NAME,
    123 		.mode = FOPEN_MODE_RB
    124 	},
    125 	[BL32_EXTRA1_IMAGE_ID] = {
    126 		.path = BL32_EXTRA1_IMAGE_NAME,
    127 		.mode = FOPEN_MODE_RB
    128 	},
    129 	[BL32_EXTRA2_IMAGE_ID] = {
    130 		.path = BL32_EXTRA2_IMAGE_NAME,
    131 		.mode = FOPEN_MODE_RB
    132 	},
    133 	[BL33_IMAGE_ID] = {
    134 		.path = BL33_IMAGE_NAME,
    135 		.mode = FOPEN_MODE_RB
    136 	},
    137 #if TRUSTED_BOARD_BOOT
    138 	[TRUSTED_BOOT_FW_CERT_ID] = {
    139 		.path = TRUSTED_BOOT_FW_CERT_NAME,
    140 		.mode = FOPEN_MODE_RB
    141 	},
    142 	[TRUSTED_KEY_CERT_ID] = {
    143 		.path = TRUSTED_KEY_CERT_NAME,
    144 		.mode = FOPEN_MODE_RB
    145 	},
    146 	[SOC_FW_KEY_CERT_ID] = {
    147 		.path = SOC_FW_KEY_CERT_NAME,
    148 		.mode = FOPEN_MODE_RB
    149 	},
    150 	[TRUSTED_OS_FW_KEY_CERT_ID] = {
    151 		.path = TOS_FW_KEY_CERT_NAME,
    152 		.mode = FOPEN_MODE_RB
    153 	},
    154 	[NON_TRUSTED_FW_KEY_CERT_ID] = {
    155 		.path = NT_FW_KEY_CERT_NAME,
    156 		.mode = FOPEN_MODE_RB
    157 	},
    158 	[SOC_FW_CONTENT_CERT_ID] = {
    159 		.path = SOC_FW_CONTENT_CERT_NAME,
    160 		.mode = FOPEN_MODE_RB
    161 	},
    162 	[TRUSTED_OS_FW_CONTENT_CERT_ID] = {
    163 		.path = TOS_FW_CONTENT_CERT_NAME,
    164 		.mode = FOPEN_MODE_RB
    165 	},
    166 	[NON_TRUSTED_FW_CONTENT_CERT_ID] = {
    167 		.path = NT_FW_CONTENT_CERT_NAME,
    168 		.mode = FOPEN_MODE_RB
    169 	},
    170 #endif /* TRUSTED_BOARD_BOOT */
    171 };
    172 
    173 
    174 
    175 static int open_fip(const uintptr_t spec);
    176 static int open_memmap(const uintptr_t spec);
    177 
    178 struct plat_io_policy {
    179 	uintptr_t *dev_handle;
    180 	uintptr_t image_spec;
    181 	int (*check)(const uintptr_t spec);
    182 };
    183 
    184 /* By default, ARM platforms load images from the FIP */
    185 static const struct plat_io_policy policies[] = {
    186 	[FIP_IMAGE_ID] = {
    187 		&memmap_dev_handle,
    188 		(uintptr_t)&fip_block_spec,
    189 		open_memmap
    190 	},
    191 	[BL2_IMAGE_ID] = {
    192 		&fip_dev_handle,
    193 		(uintptr_t)&bl2_uuid_spec,
    194 		open_fip
    195 	},
    196 	[BL31_IMAGE_ID] = {
    197 		&fip_dev_handle,
    198 		(uintptr_t)&bl31_uuid_spec,
    199 		open_fip
    200 	},
    201 	[BL32_IMAGE_ID] = {
    202 		&fip_dev_handle,
    203 		(uintptr_t)&bl32_uuid_spec,
    204 		open_fip
    205 	},
    206 	[BL32_EXTRA1_IMAGE_ID] = {
    207 		&fip_dev_handle,
    208 		(uintptr_t)&bl32_extra1_uuid_spec,
    209 		open_fip
    210 	},
    211 	[BL32_EXTRA2_IMAGE_ID] = {
    212 		&fip_dev_handle,
    213 		(uintptr_t)&bl32_extra2_uuid_spec,
    214 		open_fip
    215 	},
    216 	[BL33_IMAGE_ID] = {
    217 		&fip_dev_handle,
    218 		(uintptr_t)&bl33_uuid_spec,
    219 		open_fip
    220 	},
    221 #if TRUSTED_BOARD_BOOT
    222 	[TRUSTED_BOOT_FW_CERT_ID] = {
    223 		&fip_dev_handle,
    224 		(uintptr_t)&tb_fw_cert_uuid_spec,
    225 		open_fip
    226 	},
    227 	[TRUSTED_KEY_CERT_ID] = {
    228 		&fip_dev_handle,
    229 		(uintptr_t)&trusted_key_cert_uuid_spec,
    230 		open_fip
    231 	},
    232 	[SOC_FW_KEY_CERT_ID] = {
    233 		&fip_dev_handle,
    234 		(uintptr_t)&soc_fw_key_cert_uuid_spec,
    235 		open_fip
    236 	},
    237 	[TRUSTED_OS_FW_KEY_CERT_ID] = {
    238 		&fip_dev_handle,
    239 		(uintptr_t)&tos_fw_key_cert_uuid_spec,
    240 		open_fip
    241 	},
    242 	[NON_TRUSTED_FW_KEY_CERT_ID] = {
    243 		&fip_dev_handle,
    244 		(uintptr_t)&nt_fw_key_cert_uuid_spec,
    245 		open_fip
    246 	},
    247 	[SOC_FW_CONTENT_CERT_ID] = {
    248 		&fip_dev_handle,
    249 		(uintptr_t)&soc_fw_cert_uuid_spec,
    250 		open_fip
    251 	},
    252 	[TRUSTED_OS_FW_CONTENT_CERT_ID] = {
    253 		&fip_dev_handle,
    254 		(uintptr_t)&tos_fw_cert_uuid_spec,
    255 		open_fip
    256 	},
    257 	[NON_TRUSTED_FW_CONTENT_CERT_ID] = {
    258 		&fip_dev_handle,
    259 		(uintptr_t)&nt_fw_cert_uuid_spec,
    260 		open_fip
    261 	},
    262 #endif /* TRUSTED_BOARD_BOOT */
    263 };
    264 
    265 static int open_fip(const uintptr_t spec)
    266 {
    267 	int result;
    268 	uintptr_t local_image_handle;
    269 
    270 	/* See if a Firmware Image Package is available */
    271 	result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID);
    272 	if (result == 0) {
    273 		result = io_open(fip_dev_handle, spec, &local_image_handle);
    274 		if (result == 0) {
    275 			VERBOSE("Using FIP\n");
    276 			io_close(local_image_handle);
    277 		}
    278 	}
    279 	return result;
    280 }
    281 
    282 static int open_memmap(const uintptr_t spec)
    283 {
    284 	int result;
    285 	uintptr_t local_image_handle;
    286 
    287 	result = io_dev_init(memmap_dev_handle, (uintptr_t)NULL);
    288 	if (result == 0) {
    289 		result = io_open(memmap_dev_handle, spec, &local_image_handle);
    290 		if (result == 0) {
    291 			VERBOSE("Using Memmap\n");
    292 			io_close(local_image_handle);
    293 		}
    294 	}
    295 	return result;
    296 }
    297 
    298 static int open_semihosting(const uintptr_t spec)
    299 {
    300 	int result;
    301 	uintptr_t local_image_handle;
    302 
    303 	/* See if the file exists on semi-hosting.*/
    304 	result = io_dev_init(sh_dev_handle, (uintptr_t)NULL);
    305 	if (result == 0) {
    306 		result = io_open(sh_dev_handle, spec, &local_image_handle);
    307 		if (result == 0) {
    308 			VERBOSE("Using Semi-hosting IO\n");
    309 			io_close(local_image_handle);
    310 		}
    311 	}
    312 	return result;
    313 }
    314 
    315 void plat_qemu_io_setup(void)
    316 {
    317 	int io_result;
    318 
    319 	io_result = register_io_dev_fip(&fip_dev_con);
    320 	assert(io_result == 0);
    321 
    322 	io_result = register_io_dev_memmap(&memmap_dev_con);
    323 	assert(io_result == 0);
    324 
    325 	/* Open connections to devices and cache the handles */
    326 	io_result = io_dev_open(fip_dev_con, (uintptr_t)NULL,
    327 				&fip_dev_handle);
    328 	assert(io_result == 0);
    329 
    330 	io_result = io_dev_open(memmap_dev_con, (uintptr_t)NULL,
    331 				&memmap_dev_handle);
    332 	assert(io_result == 0);
    333 
    334 	/* Register the additional IO devices on this platform */
    335 	io_result = register_io_dev_sh(&sh_dev_con);
    336 	assert(io_result == 0);
    337 
    338 	/* Open connections to devices and cache the handles */
    339 	io_result = io_dev_open(sh_dev_con, (uintptr_t)NULL, &sh_dev_handle);
    340 	assert(io_result == 0);
    341 
    342 	/* Ignore improbable errors in release builds */
    343 	(void)io_result;
    344 }
    345 
    346 static int get_alt_image_source(unsigned int image_id, uintptr_t *dev_handle,
    347 				  uintptr_t *image_spec)
    348 {
    349 	int result = open_semihosting((const uintptr_t)&sh_file_spec[image_id]);
    350 
    351 	if (result == 0) {
    352 		*dev_handle = sh_dev_handle;
    353 		*image_spec = (uintptr_t)&sh_file_spec[image_id];
    354 	}
    355 
    356 	return result;
    357 }
    358 
    359 /*
    360  * Return an IO device handle and specification which can be used to access
    361  * an image. Use this to enforce platform load policy
    362  */
    363 int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
    364 			  uintptr_t *image_spec)
    365 {
    366 	int result;
    367 	const struct plat_io_policy *policy;
    368 
    369 	assert(image_id < ARRAY_SIZE(policies));
    370 
    371 	policy = &policies[image_id];
    372 	result = policy->check(policy->image_spec);
    373 	if (result == 0) {
    374 		*image_spec = policy->image_spec;
    375 		*dev_handle = *(policy->dev_handle);
    376 	} else {
    377 		VERBOSE("Trying alternative IO\n");
    378 		result = get_alt_image_source(image_id, dev_handle, image_spec);
    379 	}
    380 
    381 	return result;
    382 }
    383