Home | History | Annotate | Download | only in uniphier
      1 /*
      2  * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
      3  *
      4  * SPDX-License-Identifier: BSD-3-Clause
      5  */
      6 
      7 #include <assert.h>
      8 #include <errno.h>
      9 #include <firmware_image_package.h>
     10 #include <io/io_block.h>
     11 #include <io/io_driver.h>
     12 #include <io/io_fip.h>
     13 #include <io/io_memmap.h>
     14 #include <platform_def.h>
     15 #include <types.h>
     16 #include <utils_def.h>
     17 #include <xlat_tables_v2.h>
     18 
     19 #include "uniphier.h"
     20 
     21 #define UNIPHIER_ROM_REGION_BASE	0x00000000
     22 #define UNIPHIER_ROM_REGION_SIZE	0x10000000
     23 
     24 static const io_dev_connector_t *uniphier_fip_dev_con;
     25 static uintptr_t uniphier_fip_dev_handle;
     26 
     27 static const io_dev_connector_t *uniphier_backend_dev_con;
     28 static uintptr_t uniphier_backend_dev_handle;
     29 
     30 static io_block_spec_t uniphier_fip_spec = {
     31 	/* .offset will be set by the io_setup func */
     32 	.length = 0x00200000,
     33 };
     34 
     35 static const io_uuid_spec_t uniphier_bl2_spec = {
     36 	.uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2,
     37 };
     38 
     39 static const io_uuid_spec_t uniphier_scp_spec = {
     40 	.uuid = UUID_SCP_FIRMWARE_SCP_BL2,
     41 };
     42 
     43 static const io_uuid_spec_t uniphier_bl31_spec = {
     44 	.uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31,
     45 };
     46 
     47 static const io_uuid_spec_t uniphier_bl32_spec = {
     48 	.uuid = UUID_SECURE_PAYLOAD_BL32,
     49 };
     50 
     51 static const io_uuid_spec_t uniphier_bl33_spec = {
     52 	.uuid = UUID_NON_TRUSTED_FIRMWARE_BL33,
     53 };
     54 
     55 #if TRUSTED_BOARD_BOOT
     56 static const io_uuid_spec_t uniphier_tb_fw_cert_spec = {
     57 	.uuid = UUID_TRUSTED_BOOT_FW_CERT,
     58 };
     59 
     60 static const io_uuid_spec_t uniphier_trusted_key_cert_spec = {
     61 	.uuid = UUID_TRUSTED_KEY_CERT,
     62 };
     63 
     64 static const io_uuid_spec_t uniphier_scp_fw_key_cert_spec = {
     65 	.uuid = UUID_SCP_FW_KEY_CERT,
     66 };
     67 
     68 static const io_uuid_spec_t uniphier_soc_fw_key_cert_spec = {
     69 	.uuid = UUID_SOC_FW_KEY_CERT,
     70 };
     71 
     72 static const io_uuid_spec_t uniphier_tos_fw_key_cert_spec = {
     73 	.uuid = UUID_TRUSTED_OS_FW_KEY_CERT,
     74 };
     75 
     76 static const io_uuid_spec_t uniphier_nt_fw_key_cert_spec = {
     77 	.uuid = UUID_NON_TRUSTED_FW_KEY_CERT,
     78 };
     79 
     80 static const io_uuid_spec_t uniphier_scp_fw_cert_spec = {
     81 	.uuid = UUID_SCP_FW_CONTENT_CERT,
     82 };
     83 
     84 static const io_uuid_spec_t uniphier_soc_fw_cert_spec = {
     85 	.uuid = UUID_SOC_FW_CONTENT_CERT,
     86 };
     87 
     88 static const io_uuid_spec_t uniphier_tos_fw_cert_spec = {
     89 	.uuid = UUID_TRUSTED_OS_FW_CONTENT_CERT,
     90 };
     91 
     92 static const io_uuid_spec_t uniphier_nt_fw_cert_spec = {
     93 	.uuid = UUID_NON_TRUSTED_FW_CONTENT_CERT,
     94 };
     95 #endif /* TRUSTED_BOARD_BOOT */
     96 
     97 struct uniphier_io_policy {
     98 	uintptr_t *dev_handle;
     99 	uintptr_t image_spec;
    100 	uintptr_t init_params;
    101 };
    102 
    103 static const struct uniphier_io_policy uniphier_io_policies[] = {
    104 	[FIP_IMAGE_ID] = {
    105 		.dev_handle = &uniphier_backend_dev_handle,
    106 		.image_spec = (uintptr_t)&uniphier_fip_spec,
    107 	},
    108 	[BL2_IMAGE_ID] = {
    109 		.dev_handle = &uniphier_fip_dev_handle,
    110 		.image_spec = (uintptr_t)&uniphier_bl2_spec,
    111 		.init_params = FIP_IMAGE_ID,
    112 	},
    113 	[SCP_BL2_IMAGE_ID] = {
    114 		.dev_handle = &uniphier_fip_dev_handle,
    115 		.image_spec = (uintptr_t)&uniphier_scp_spec,
    116 		.init_params = FIP_IMAGE_ID,
    117 	},
    118 	[BL31_IMAGE_ID] = {
    119 		.dev_handle = &uniphier_fip_dev_handle,
    120 		.image_spec = (uintptr_t)&uniphier_bl31_spec,
    121 		.init_params = FIP_IMAGE_ID,
    122 	},
    123 	[BL32_IMAGE_ID] = {
    124 		.dev_handle = &uniphier_fip_dev_handle,
    125 		.image_spec = (uintptr_t)&uniphier_bl32_spec,
    126 		.init_params = FIP_IMAGE_ID,
    127 	},
    128 	[BL33_IMAGE_ID] = {
    129 		.dev_handle = &uniphier_fip_dev_handle,
    130 		.image_spec = (uintptr_t)&uniphier_bl33_spec,
    131 		.init_params = FIP_IMAGE_ID,
    132 	},
    133 #if TRUSTED_BOARD_BOOT
    134 	[TRUSTED_BOOT_FW_CERT_ID] = {
    135 		.dev_handle = &uniphier_fip_dev_handle,
    136 		.image_spec = (uintptr_t)&uniphier_tb_fw_cert_spec,
    137 		.init_params = FIP_IMAGE_ID,
    138 	},
    139 	[TRUSTED_KEY_CERT_ID] = {
    140 		.dev_handle = &uniphier_fip_dev_handle,
    141 		.image_spec = (uintptr_t)&uniphier_trusted_key_cert_spec,
    142 		.init_params = FIP_IMAGE_ID,
    143 	},
    144 	[SCP_FW_KEY_CERT_ID] = {
    145 		.dev_handle = &uniphier_fip_dev_handle,
    146 		.image_spec = (uintptr_t)&uniphier_scp_fw_key_cert_spec,
    147 		.init_params = FIP_IMAGE_ID,
    148 	},
    149 	[SOC_FW_KEY_CERT_ID] = {
    150 		.dev_handle = &uniphier_fip_dev_handle,
    151 		.image_spec = (uintptr_t)&uniphier_soc_fw_key_cert_spec,
    152 		.init_params = FIP_IMAGE_ID,
    153 	},
    154 	[TRUSTED_OS_FW_KEY_CERT_ID] = {
    155 		.dev_handle = &uniphier_fip_dev_handle,
    156 		.image_spec = (uintptr_t)&uniphier_tos_fw_key_cert_spec,
    157 		.init_params = FIP_IMAGE_ID,
    158 	},
    159 	[NON_TRUSTED_FW_KEY_CERT_ID] = {
    160 		.dev_handle = &uniphier_fip_dev_handle,
    161 		.image_spec = (uintptr_t)&uniphier_nt_fw_key_cert_spec,
    162 		.init_params = FIP_IMAGE_ID,
    163 	},
    164 	[SCP_FW_CONTENT_CERT_ID] = {
    165 		.dev_handle = &uniphier_fip_dev_handle,
    166 		.image_spec = (uintptr_t)&uniphier_scp_fw_cert_spec,
    167 		.init_params = FIP_IMAGE_ID,
    168 	},
    169 	[SOC_FW_CONTENT_CERT_ID] = {
    170 		.dev_handle = &uniphier_fip_dev_handle,
    171 		.image_spec = (uintptr_t)&uniphier_soc_fw_cert_spec,
    172 		.init_params = FIP_IMAGE_ID,
    173 	},
    174 	[TRUSTED_OS_FW_CONTENT_CERT_ID] = {
    175 		.dev_handle = &uniphier_fip_dev_handle,
    176 		.image_spec = (uintptr_t)&uniphier_tos_fw_cert_spec,
    177 		.init_params = FIP_IMAGE_ID,
    178 	},
    179 	[NON_TRUSTED_FW_CONTENT_CERT_ID] = {
    180 		.dev_handle = &uniphier_fip_dev_handle,
    181 		.image_spec = (uintptr_t)&uniphier_nt_fw_cert_spec,
    182 		.init_params = FIP_IMAGE_ID,
    183 	},
    184 #endif
    185 };
    186 
    187 static int uniphier_io_block_setup(size_t fip_offset, uintptr_t block_dev_spec)
    188 {
    189 	int ret;
    190 
    191 	uniphier_fip_spec.offset = fip_offset;
    192 
    193 	ret = register_io_dev_block(&uniphier_backend_dev_con);
    194 	if (ret)
    195 		return ret;
    196 
    197 	return io_dev_open(uniphier_backend_dev_con, block_dev_spec,
    198 			   &uniphier_backend_dev_handle);
    199 }
    200 
    201 static int uniphier_io_memmap_setup(size_t fip_offset)
    202 {
    203 	int ret;
    204 
    205 	uniphier_fip_spec.offset = fip_offset;
    206 
    207 	ret = mmap_add_dynamic_region(fip_offset, fip_offset,
    208 				      uniphier_fip_spec.length,
    209 				      MT_RO_DATA | MT_SECURE);
    210 	if (ret)
    211 		return ret;
    212 
    213 	ret = register_io_dev_memmap(&uniphier_backend_dev_con);
    214 	if (ret)
    215 		return ret;
    216 
    217 	return io_dev_open(uniphier_backend_dev_con, 0,
    218 			   &uniphier_backend_dev_handle);
    219 }
    220 
    221 static int uniphier_io_fip_setup(void)
    222 {
    223 	int ret;
    224 
    225 	ret = register_io_dev_fip(&uniphier_fip_dev_con);
    226 	if (ret)
    227 		return ret;
    228 
    229 	return io_dev_open(uniphier_fip_dev_con, 0, &uniphier_fip_dev_handle);
    230 }
    231 
    232 static int uniphier_io_emmc_setup(unsigned int soc_id)
    233 {
    234 	uintptr_t block_dev_spec;
    235 	int ret;
    236 
    237 	ret = uniphier_emmc_init(&block_dev_spec);
    238 	if (ret)
    239 		return ret;
    240 
    241 	return uniphier_io_block_setup(0x20000, block_dev_spec);
    242 }
    243 
    244 static int uniphier_io_nand_setup(unsigned int soc_id)
    245 {
    246 	uintptr_t block_dev_spec;
    247 	int ret;
    248 
    249 	ret = uniphier_nand_init(&block_dev_spec);
    250 	if (ret)
    251 		return ret;
    252 
    253 	return uniphier_io_block_setup(0x20000, block_dev_spec);
    254 }
    255 
    256 static int uniphier_io_nor_setup(unsigned int soc_id)
    257 {
    258 	return uniphier_io_memmap_setup(0x70000);
    259 }
    260 
    261 static int uniphier_io_usb_setup(unsigned int soc_id)
    262 {
    263 	uintptr_t block_dev_spec;
    264 	int ret;
    265 
    266 	/* use ROM API for loading images from USB storage */
    267 	ret = mmap_add_dynamic_region(UNIPHIER_ROM_REGION_BASE,
    268 				      UNIPHIER_ROM_REGION_BASE,
    269 				      UNIPHIER_ROM_REGION_SIZE,
    270 				      MT_CODE | MT_SECURE);
    271 	if (ret)
    272 		return ret;
    273 
    274 	ret = uniphier_usb_init(soc_id, &block_dev_spec);
    275 	if (ret)
    276 		return ret;
    277 
    278 	return uniphier_io_block_setup(0x20000, block_dev_spec);
    279 }
    280 
    281 static int (* const uniphier_io_setup_table[])(unsigned int) = {
    282 	[UNIPHIER_BOOT_DEVICE_EMMC] = uniphier_io_emmc_setup,
    283 	[UNIPHIER_BOOT_DEVICE_NAND] = uniphier_io_nand_setup,
    284 	[UNIPHIER_BOOT_DEVICE_NOR] = uniphier_io_nor_setup,
    285 	[UNIPHIER_BOOT_DEVICE_USB] = uniphier_io_usb_setup,
    286 };
    287 
    288 int uniphier_io_setup(unsigned int soc_id)
    289 {
    290 	int (*io_setup)(unsigned int soc_id);
    291 	unsigned int boot_dev;
    292 	int ret;
    293 
    294 	boot_dev = uniphier_get_boot_device(soc_id);
    295 	if (boot_dev == UNIPHIER_BOOT_DEVICE_RSV)
    296 		return -EINVAL;
    297 
    298 	io_setup = uniphier_io_setup_table[boot_dev];
    299 	ret = io_setup(soc_id);
    300 	if (ret)
    301 		return ret;
    302 
    303 	ret = uniphier_io_fip_setup();
    304 	if (ret)
    305 		return ret;
    306 
    307 	return 0;
    308 }
    309 
    310 int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
    311 			  uintptr_t *image_spec)
    312 {
    313 	uintptr_t init_params;
    314 
    315 	assert(image_id < ARRAY_SIZE(uniphier_io_policies));
    316 
    317 	*dev_handle = *(uniphier_io_policies[image_id].dev_handle);
    318 	*image_spec = uniphier_io_policies[image_id].image_spec;
    319 	init_params = uniphier_io_policies[image_id].init_params;
    320 
    321 	return io_dev_init(*dev_handle, init_params);
    322 }
    323 
    324 int uniphier_check_image(unsigned int image_id)
    325 {
    326 	uintptr_t dev_handle, image_spec, image_handle;
    327 	int ret;
    328 
    329 	ret = plat_get_image_source(image_id, &dev_handle, &image_spec);
    330 	if (ret)
    331 		return ret;
    332 
    333 	ret = io_open(dev_handle, image_spec, &image_handle);
    334 	if (ret)
    335 		return ret;
    336 
    337 	io_close(image_handle);
    338 
    339 	return 0;
    340 }
    341