Home | History | Annotate | Download | only in common
      1 /*
      2  * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
      3  *
      4  * SPDX-License-Identifier: BSD-3-Clause
      5  */
      6 #include <assert.h>
      7 #include <debug.h>
      8 #include <firmware_image_package.h>
      9 #include <io_driver.h>
     10 #include <io_fip.h>
     11 #include <io_memmap.h>
     12 #include <io_storage.h>
     13 #include <platform_def.h>
     14 #include <string.h>
     15 #include <utils.h>
     16 
     17 /* IO devices */
     18 static const io_dev_connector_t *fip_dev_con;
     19 static uintptr_t fip_dev_handle;
     20 static const io_dev_connector_t *memmap_dev_con;
     21 static uintptr_t memmap_dev_handle;
     22 
     23 static const io_block_spec_t fip_block_spec = {
     24 	.offset = PLAT_ARM_FIP_BASE,
     25 	.length = PLAT_ARM_FIP_MAX_SIZE
     26 };
     27 
     28 static const io_uuid_spec_t bl2_uuid_spec = {
     29 	.uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2,
     30 };
     31 
     32 static const io_uuid_spec_t scp_bl2_uuid_spec = {
     33 	.uuid = UUID_SCP_FIRMWARE_SCP_BL2,
     34 };
     35 
     36 static const io_uuid_spec_t bl31_uuid_spec = {
     37 	.uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31,
     38 };
     39 
     40 static const io_uuid_spec_t bl32_uuid_spec = {
     41 	.uuid = UUID_SECURE_PAYLOAD_BL32,
     42 };
     43 
     44 static const io_uuid_spec_t bl32_extra1_uuid_spec = {
     45 	.uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA1,
     46 };
     47 
     48 static const io_uuid_spec_t bl32_extra2_uuid_spec = {
     49 	.uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA2,
     50 };
     51 
     52 static const io_uuid_spec_t bl33_uuid_spec = {
     53 	.uuid = UUID_NON_TRUSTED_FIRMWARE_BL33,
     54 };
     55 
     56 #if TRUSTED_BOARD_BOOT
     57 static const io_uuid_spec_t tb_fw_cert_uuid_spec = {
     58 	.uuid = UUID_TRUSTED_BOOT_FW_CERT,
     59 };
     60 
     61 static const io_uuid_spec_t trusted_key_cert_uuid_spec = {
     62 	.uuid = UUID_TRUSTED_KEY_CERT,
     63 };
     64 
     65 static const io_uuid_spec_t scp_fw_key_cert_uuid_spec = {
     66 	.uuid = UUID_SCP_FW_KEY_CERT,
     67 };
     68 
     69 static const io_uuid_spec_t soc_fw_key_cert_uuid_spec = {
     70 	.uuid = UUID_SOC_FW_KEY_CERT,
     71 };
     72 
     73 static const io_uuid_spec_t tos_fw_key_cert_uuid_spec = {
     74 	.uuid = UUID_TRUSTED_OS_FW_KEY_CERT,
     75 };
     76 
     77 static const io_uuid_spec_t nt_fw_key_cert_uuid_spec = {
     78 	.uuid = UUID_NON_TRUSTED_FW_KEY_CERT,
     79 };
     80 
     81 static const io_uuid_spec_t scp_fw_cert_uuid_spec = {
     82 	.uuid = UUID_SCP_FW_CONTENT_CERT,
     83 };
     84 
     85 static const io_uuid_spec_t soc_fw_cert_uuid_spec = {
     86 	.uuid = UUID_SOC_FW_CONTENT_CERT,
     87 };
     88 
     89 static const io_uuid_spec_t tos_fw_cert_uuid_spec = {
     90 	.uuid = UUID_TRUSTED_OS_FW_CONTENT_CERT,
     91 };
     92 
     93 static const io_uuid_spec_t nt_fw_cert_uuid_spec = {
     94 	.uuid = UUID_NON_TRUSTED_FW_CONTENT_CERT,
     95 };
     96 #endif /* TRUSTED_BOARD_BOOT */
     97 
     98 
     99 static int open_fip(const uintptr_t spec);
    100 static int open_memmap(const uintptr_t spec);
    101 
    102 struct plat_io_policy {
    103 	uintptr_t *dev_handle;
    104 	uintptr_t image_spec;
    105 	int (*check)(const uintptr_t spec);
    106 };
    107 
    108 /* By default, ARM platforms load images from the FIP */
    109 static const struct plat_io_policy policies[] = {
    110 	[FIP_IMAGE_ID] = {
    111 		&memmap_dev_handle,
    112 		(uintptr_t)&fip_block_spec,
    113 		open_memmap
    114 	},
    115 	[BL2_IMAGE_ID] = {
    116 		&fip_dev_handle,
    117 		(uintptr_t)&bl2_uuid_spec,
    118 		open_fip
    119 	},
    120 	[SCP_BL2_IMAGE_ID] = {
    121 		&fip_dev_handle,
    122 		(uintptr_t)&scp_bl2_uuid_spec,
    123 		open_fip
    124 	},
    125 	[BL31_IMAGE_ID] = {
    126 		&fip_dev_handle,
    127 		(uintptr_t)&bl31_uuid_spec,
    128 		open_fip
    129 	},
    130 	[BL32_IMAGE_ID] = {
    131 		&fip_dev_handle,
    132 		(uintptr_t)&bl32_uuid_spec,
    133 		open_fip
    134 	},
    135 	[BL32_EXTRA1_IMAGE_ID] = {
    136 		&fip_dev_handle,
    137 		(uintptr_t)&bl32_extra1_uuid_spec,
    138 		open_fip
    139 	},
    140 	[BL32_EXTRA2_IMAGE_ID] = {
    141 		&fip_dev_handle,
    142 		(uintptr_t)&bl32_extra2_uuid_spec,
    143 		open_fip
    144 	},
    145 	[BL33_IMAGE_ID] = {
    146 		&fip_dev_handle,
    147 		(uintptr_t)&bl33_uuid_spec,
    148 		open_fip
    149 	},
    150 #if TRUSTED_BOARD_BOOT
    151 	[TRUSTED_BOOT_FW_CERT_ID] = {
    152 		&fip_dev_handle,
    153 		(uintptr_t)&tb_fw_cert_uuid_spec,
    154 		open_fip
    155 	},
    156 	[TRUSTED_KEY_CERT_ID] = {
    157 		&fip_dev_handle,
    158 		(uintptr_t)&trusted_key_cert_uuid_spec,
    159 		open_fip
    160 	},
    161 	[SCP_FW_KEY_CERT_ID] = {
    162 		&fip_dev_handle,
    163 		(uintptr_t)&scp_fw_key_cert_uuid_spec,
    164 		open_fip
    165 	},
    166 	[SOC_FW_KEY_CERT_ID] = {
    167 		&fip_dev_handle,
    168 		(uintptr_t)&soc_fw_key_cert_uuid_spec,
    169 		open_fip
    170 	},
    171 	[TRUSTED_OS_FW_KEY_CERT_ID] = {
    172 		&fip_dev_handle,
    173 		(uintptr_t)&tos_fw_key_cert_uuid_spec,
    174 		open_fip
    175 	},
    176 	[NON_TRUSTED_FW_KEY_CERT_ID] = {
    177 		&fip_dev_handle,
    178 		(uintptr_t)&nt_fw_key_cert_uuid_spec,
    179 		open_fip
    180 	},
    181 	[SCP_FW_CONTENT_CERT_ID] = {
    182 		&fip_dev_handle,
    183 		(uintptr_t)&scp_fw_cert_uuid_spec,
    184 		open_fip
    185 	},
    186 	[SOC_FW_CONTENT_CERT_ID] = {
    187 		&fip_dev_handle,
    188 		(uintptr_t)&soc_fw_cert_uuid_spec,
    189 		open_fip
    190 	},
    191 	[TRUSTED_OS_FW_CONTENT_CERT_ID] = {
    192 		&fip_dev_handle,
    193 		(uintptr_t)&tos_fw_cert_uuid_spec,
    194 		open_fip
    195 	},
    196 	[NON_TRUSTED_FW_CONTENT_CERT_ID] = {
    197 		&fip_dev_handle,
    198 		(uintptr_t)&nt_fw_cert_uuid_spec,
    199 		open_fip
    200 	},
    201 #endif /* TRUSTED_BOARD_BOOT */
    202 };
    203 
    204 
    205 /* Weak definitions may be overridden in specific ARM standard platform */
    206 #pragma weak plat_arm_io_setup
    207 #pragma weak plat_arm_get_alt_image_source
    208 
    209 
    210 static int open_fip(const uintptr_t spec)
    211 {
    212 	int result;
    213 	uintptr_t local_image_handle;
    214 
    215 	/* See if a Firmware Image Package is available */
    216 	result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID);
    217 	if (result == 0) {
    218 		result = io_open(fip_dev_handle, spec, &local_image_handle);
    219 		if (result == 0) {
    220 			VERBOSE("Using FIP\n");
    221 			io_close(local_image_handle);
    222 		}
    223 	}
    224 	return result;
    225 }
    226 
    227 
    228 static int open_memmap(const uintptr_t spec)
    229 {
    230 	int result;
    231 	uintptr_t local_image_handle;
    232 
    233 	result = io_dev_init(memmap_dev_handle, (uintptr_t)NULL);
    234 	if (result == 0) {
    235 		result = io_open(memmap_dev_handle, spec, &local_image_handle);
    236 		if (result == 0) {
    237 			VERBOSE("Using Memmap\n");
    238 			io_close(local_image_handle);
    239 		}
    240 	}
    241 	return result;
    242 }
    243 
    244 
    245 void arm_io_setup(void)
    246 {
    247 	int io_result;
    248 
    249 	io_result = register_io_dev_fip(&fip_dev_con);
    250 	assert(io_result == 0);
    251 
    252 	io_result = register_io_dev_memmap(&memmap_dev_con);
    253 	assert(io_result == 0);
    254 
    255 	/* Open connections to devices and cache the handles */
    256 	io_result = io_dev_open(fip_dev_con, (uintptr_t)NULL,
    257 				&fip_dev_handle);
    258 	assert(io_result == 0);
    259 
    260 	io_result = io_dev_open(memmap_dev_con, (uintptr_t)NULL,
    261 				&memmap_dev_handle);
    262 	assert(io_result == 0);
    263 
    264 	/* Ignore improbable errors in release builds */
    265 	(void)io_result;
    266 }
    267 
    268 void plat_arm_io_setup(void)
    269 {
    270 	arm_io_setup();
    271 }
    272 
    273 int plat_arm_get_alt_image_source(
    274 	unsigned int image_id __unused,
    275 	uintptr_t *dev_handle __unused,
    276 	uintptr_t *image_spec __unused)
    277 {
    278 	/* By default do not try an alternative */
    279 	return -ENOENT;
    280 }
    281 
    282 /* Return an IO device handle and specification which can be used to access
    283  * an image. Use this to enforce platform load policy */
    284 int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
    285 			  uintptr_t *image_spec)
    286 {
    287 	int result;
    288 	const struct plat_io_policy *policy;
    289 
    290 	assert(image_id < ARRAY_SIZE(policies));
    291 
    292 	policy = &policies[image_id];
    293 	result = policy->check(policy->image_spec);
    294 	if (result == 0) {
    295 		*image_spec = policy->image_spec;
    296 		*dev_handle = *(policy->dev_handle);
    297 	} else {
    298 		VERBOSE("Trying alternative IO\n");
    299 		result = plat_arm_get_alt_image_source(image_id, dev_handle,
    300 						       image_spec);
    301 	}
    302 
    303 	return result;
    304 }
    305 
    306 /*
    307  * See if a Firmware Image Package is available,
    308  * by checking if TOC is valid or not.
    309  */
    310 int arm_io_is_toc_valid(void)
    311 {
    312 	int result;
    313 
    314 	result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID);
    315 
    316 	return (result == 0);
    317 }
    318 
    319