Home | History | Annotate | Download | only in hikey960
      1 /*
      2  * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
      3  *
      4  * SPDX-License-Identifier: BSD-3-Clause
      5  */
      6 
      7 #include <arch_helpers.h>
      8 #include <assert.h>
      9 #include <debug.h>
     10 #include <errno.h>
     11 #include <firmware_image_package.h>
     12 #include <io_block.h>
     13 #include <io_driver.h>
     14 #include <io_fip.h>
     15 #include <io_memmap.h>
     16 #include <io_storage.h>
     17 #include <mmio.h>
     18 #include <platform_def.h>
     19 #include <semihosting.h>	/* For FOPEN_MODE_... */
     20 #include <string.h>
     21 #include <ufs.h>
     22 
     23 struct plat_io_policy {
     24 	uintptr_t *dev_handle;
     25 	uintptr_t image_spec;
     26 	int (*check)(const uintptr_t spec);
     27 };
     28 
     29 static const io_dev_connector_t *ufs_dev_con, *fip_dev_con;
     30 static uintptr_t ufs_dev_handle, fip_dev_handle;
     31 
     32 static int check_ufs(const uintptr_t spec);
     33 static int check_fip(const uintptr_t spec);
     34 size_t ufs_read_lun3_blks(int lba, uintptr_t buf, size_t size);
     35 size_t ufs_write_lun3_blks(int lba, const uintptr_t buf, size_t size);
     36 
     37 static const io_block_spec_t ufs_fip_spec = {
     38 	.offset		= HIKEY960_FIP_BASE,
     39 	.length		= HIKEY960_FIP_MAX_SIZE,
     40 };
     41 
     42 static const io_block_spec_t ufs_data_spec = {
     43 	.offset		= 0,
     44 	.length		= 256 << 20,
     45 };
     46 
     47 static const io_block_dev_spec_t ufs_dev_spec = {
     48 	/* It's used as temp buffer in block driver. */
     49 	.buffer		= {
     50 		.offset	= HIKEY960_UFS_DATA_BASE,
     51 		.length	= HIKEY960_UFS_DATA_SIZE,
     52 	},
     53 	.ops		= {
     54 		.read	= ufs_read_lun3_blks,
     55 		.write	= ufs_write_lun3_blks,
     56 	},
     57 	.block_size	= UFS_BLOCK_SIZE,
     58 };
     59 
     60 static const io_uuid_spec_t bl2_uuid_spec = {
     61 	.uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2,
     62 };
     63 
     64 static const io_uuid_spec_t scp_bl2_uuid_spec = {
     65 	.uuid = UUID_SCP_FIRMWARE_SCP_BL2,
     66 };
     67 
     68 static const io_uuid_spec_t bl31_uuid_spec = {
     69 	.uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31,
     70 };
     71 
     72 static const io_uuid_spec_t bl32_uuid_spec = {
     73 	.uuid = UUID_SECURE_PAYLOAD_BL32,
     74 };
     75 
     76 static const io_uuid_spec_t bl32_extra1_uuid_spec = {
     77 	.uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA1,
     78 };
     79 
     80 static const io_uuid_spec_t bl32_extra2_uuid_spec = {
     81 	.uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA2,
     82 };
     83 
     84 static const io_uuid_spec_t bl33_uuid_spec = {
     85 	.uuid = UUID_NON_TRUSTED_FIRMWARE_BL33,
     86 };
     87 
     88 static const struct plat_io_policy policies[] = {
     89 	[FIP_IMAGE_ID] = {
     90 		&ufs_dev_handle,
     91 		(uintptr_t)&ufs_fip_spec,
     92 		check_ufs
     93 	},
     94 	[BL2_IMAGE_ID] = {
     95 		&fip_dev_handle,
     96 		(uintptr_t)&bl2_uuid_spec,
     97 		check_fip
     98 	},
     99 	[SCP_BL2_IMAGE_ID] = {
    100 		&fip_dev_handle,
    101 		(uintptr_t)&scp_bl2_uuid_spec,
    102 		check_fip
    103 	},
    104 	[BL31_IMAGE_ID] = {
    105 		&fip_dev_handle,
    106 		(uintptr_t)&bl31_uuid_spec,
    107 		check_fip
    108 	},
    109 	[BL32_IMAGE_ID] = {
    110 		&fip_dev_handle,
    111 		(uintptr_t)&bl32_uuid_spec,
    112 		check_fip
    113 	},
    114 	[BL32_EXTRA1_IMAGE_ID] = {
    115 		&fip_dev_handle,
    116 		(uintptr_t)&bl32_extra1_uuid_spec,
    117 		check_fip
    118 	},
    119 	[BL32_EXTRA2_IMAGE_ID] = {
    120 		&fip_dev_handle,
    121 		(uintptr_t)&bl32_extra2_uuid_spec,
    122 		check_fip
    123 	},
    124 	[BL33_IMAGE_ID] = {
    125 		&fip_dev_handle,
    126 		(uintptr_t)&bl33_uuid_spec,
    127 		check_fip
    128 	},
    129 	[BL2U_IMAGE_ID] = {
    130 		&ufs_dev_handle,
    131 		(uintptr_t)&ufs_data_spec,
    132 		check_ufs
    133 	}
    134 };
    135 
    136 static int check_ufs(const uintptr_t spec)
    137 {
    138 	int result;
    139 	uintptr_t local_handle;
    140 
    141 	result = io_dev_init(ufs_dev_handle, (uintptr_t)NULL);
    142 	if (result == 0) {
    143 		result = io_open(ufs_dev_handle, spec, &local_handle);
    144 		if (result == 0)
    145 			io_close(local_handle);
    146 	}
    147 	return result;
    148 }
    149 
    150 static int check_fip(const uintptr_t spec)
    151 {
    152 	int result;
    153 	uintptr_t local_image_handle;
    154 
    155 	/* See if a Firmware Image Package is available */
    156 	result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID);
    157 	if (result == 0) {
    158 		result = io_open(fip_dev_handle, spec, &local_image_handle);
    159 		if (result == 0) {
    160 			VERBOSE("Using FIP\n");
    161 			io_close(local_image_handle);
    162 		}
    163 	}
    164 	return result;
    165 }
    166 
    167 void hikey960_io_setup(void)
    168 {
    169 	int result;
    170 
    171 	result = register_io_dev_block(&ufs_dev_con);
    172 	assert(result == 0);
    173 
    174 	result = register_io_dev_fip(&fip_dev_con);
    175 	assert(result == 0);
    176 
    177 	result = io_dev_open(ufs_dev_con, (uintptr_t)&ufs_dev_spec,
    178 			     &ufs_dev_handle);
    179 	assert(result == 0);
    180 
    181 	result = io_dev_open(fip_dev_con, (uintptr_t)NULL, &fip_dev_handle);
    182 	assert(result == 0);
    183 
    184 	/* Ignore improbable errors in release builds */
    185 	(void)result;
    186 }
    187 
    188 /* Return an IO device handle and specification which can be used to access
    189  * an image. Use this to enforce platform load policy
    190  */
    191 int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
    192 			  uintptr_t *image_spec)
    193 {
    194 	int result;
    195 	const struct plat_io_policy *policy;
    196 
    197 	assert(image_id < ARRAY_SIZE(policies));
    198 
    199 	policy = &policies[image_id];
    200 	result = policy->check(policy->image_spec);
    201 	assert(result == 0);
    202 
    203 	*image_spec = policy->image_spec;
    204 	*dev_handle = *(policy->dev_handle);
    205 
    206 	return result;
    207 }
    208 
    209 size_t ufs_read_lun3_blks(int lba, uintptr_t buf, size_t size)
    210 {
    211 	return ufs_read_blocks(3, lba, buf, size);
    212 }
    213 
    214 size_t ufs_write_lun3_blks(int lba, const uintptr_t buf, size_t size)
    215 {
    216 	return ufs_write_blocks(3, lba, buf, size);
    217 }
    218