1 /* 2 * Copyright (c) 2017-2018, 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_dev_spec_t ufs_dev_spec = { 43 /* It's used as temp buffer in block driver. */ 44 .buffer = { 45 .offset = HIKEY960_UFS_DATA_BASE, 46 .length = HIKEY960_UFS_DATA_SIZE, 47 }, 48 .ops = { 49 .read = ufs_read_lun3_blks, 50 .write = ufs_write_lun3_blks, 51 }, 52 .block_size = UFS_BLOCK_SIZE, 53 }; 54 55 static const io_uuid_spec_t scp_bl2_uuid_spec = { 56 .uuid = UUID_SCP_FIRMWARE_SCP_BL2, 57 }; 58 59 static const io_uuid_spec_t bl31_uuid_spec = { 60 .uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31, 61 }; 62 63 static const io_uuid_spec_t bl32_uuid_spec = { 64 .uuid = UUID_SECURE_PAYLOAD_BL32, 65 }; 66 67 static const io_uuid_spec_t bl32_extra1_uuid_spec = { 68 .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA1, 69 }; 70 71 static const io_uuid_spec_t bl32_extra2_uuid_spec = { 72 .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA2, 73 }; 74 75 static const io_uuid_spec_t bl33_uuid_spec = { 76 .uuid = UUID_NON_TRUSTED_FIRMWARE_BL33, 77 }; 78 79 #if TRUSTED_BOARD_BOOT 80 static const io_uuid_spec_t trusted_key_cert_uuid_spec = { 81 .uuid = UUID_TRUSTED_KEY_CERT, 82 }; 83 84 static const io_uuid_spec_t scp_fw_key_cert_uuid_spec = { 85 .uuid = UUID_SCP_FW_KEY_CERT, 86 }; 87 88 static const io_uuid_spec_t soc_fw_key_cert_uuid_spec = { 89 .uuid = UUID_SOC_FW_KEY_CERT, 90 }; 91 92 static const io_uuid_spec_t tos_fw_key_cert_uuid_spec = { 93 .uuid = UUID_TRUSTED_OS_FW_KEY_CERT, 94 }; 95 96 static const io_uuid_spec_t nt_fw_key_cert_uuid_spec = { 97 .uuid = UUID_NON_TRUSTED_FW_KEY_CERT, 98 }; 99 100 static const io_uuid_spec_t scp_fw_cert_uuid_spec = { 101 .uuid = UUID_SCP_FW_CONTENT_CERT, 102 }; 103 104 static const io_uuid_spec_t soc_fw_cert_uuid_spec = { 105 .uuid = UUID_SOC_FW_CONTENT_CERT, 106 }; 107 108 static const io_uuid_spec_t tos_fw_cert_uuid_spec = { 109 .uuid = UUID_TRUSTED_OS_FW_CONTENT_CERT, 110 }; 111 112 static const io_uuid_spec_t nt_fw_cert_uuid_spec = { 113 .uuid = UUID_NON_TRUSTED_FW_CONTENT_CERT, 114 }; 115 #endif /* TRUSTED_BOARD_BOOT */ 116 117 static const struct plat_io_policy policies[] = { 118 [FIP_IMAGE_ID] = { 119 &ufs_dev_handle, 120 (uintptr_t)&ufs_fip_spec, 121 check_ufs 122 }, 123 [SCP_BL2_IMAGE_ID] = { 124 &fip_dev_handle, 125 (uintptr_t)&scp_bl2_uuid_spec, 126 check_fip 127 }, 128 [BL31_IMAGE_ID] = { 129 &fip_dev_handle, 130 (uintptr_t)&bl31_uuid_spec, 131 check_fip 132 }, 133 [BL32_IMAGE_ID] = { 134 &fip_dev_handle, 135 (uintptr_t)&bl32_uuid_spec, 136 check_fip 137 }, 138 [BL32_EXTRA1_IMAGE_ID] = { 139 &fip_dev_handle, 140 (uintptr_t)&bl32_extra1_uuid_spec, 141 check_fip 142 }, 143 [BL32_EXTRA2_IMAGE_ID] = { 144 &fip_dev_handle, 145 (uintptr_t)&bl32_extra2_uuid_spec, 146 check_fip 147 }, 148 [BL33_IMAGE_ID] = { 149 &fip_dev_handle, 150 (uintptr_t)&bl33_uuid_spec, 151 check_fip 152 }, 153 #if TRUSTED_BOARD_BOOT 154 [TRUSTED_KEY_CERT_ID] = { 155 &fip_dev_handle, 156 (uintptr_t)&trusted_key_cert_uuid_spec, 157 check_fip 158 }, 159 [SCP_FW_KEY_CERT_ID] = { 160 &fip_dev_handle, 161 (uintptr_t)&scp_fw_key_cert_uuid_spec, 162 check_fip 163 }, 164 [SOC_FW_KEY_CERT_ID] = { 165 &fip_dev_handle, 166 (uintptr_t)&soc_fw_key_cert_uuid_spec, 167 check_fip 168 }, 169 [TRUSTED_OS_FW_KEY_CERT_ID] = { 170 &fip_dev_handle, 171 (uintptr_t)&tos_fw_key_cert_uuid_spec, 172 check_fip 173 }, 174 [NON_TRUSTED_FW_KEY_CERT_ID] = { 175 &fip_dev_handle, 176 (uintptr_t)&nt_fw_key_cert_uuid_spec, 177 check_fip 178 }, 179 [SCP_FW_CONTENT_CERT_ID] = { 180 &fip_dev_handle, 181 (uintptr_t)&scp_fw_cert_uuid_spec, 182 check_fip 183 }, 184 [SOC_FW_CONTENT_CERT_ID] = { 185 &fip_dev_handle, 186 (uintptr_t)&soc_fw_cert_uuid_spec, 187 check_fip 188 }, 189 [TRUSTED_OS_FW_CONTENT_CERT_ID] = { 190 &fip_dev_handle, 191 (uintptr_t)&tos_fw_cert_uuid_spec, 192 check_fip 193 }, 194 [NON_TRUSTED_FW_CONTENT_CERT_ID] = { 195 &fip_dev_handle, 196 (uintptr_t)&nt_fw_cert_uuid_spec, 197 check_fip 198 }, 199 #endif /* TRUSTED_BOARD_BOOT */ 200 }; 201 202 static int check_ufs(const uintptr_t spec) 203 { 204 int result; 205 uintptr_t local_handle; 206 207 result = io_dev_init(ufs_dev_handle, (uintptr_t)NULL); 208 if (result == 0) { 209 result = io_open(ufs_dev_handle, spec, &local_handle); 210 if (result == 0) 211 io_close(local_handle); 212 } 213 return result; 214 } 215 216 static int check_fip(const uintptr_t spec) 217 { 218 int result; 219 uintptr_t local_image_handle; 220 221 /* See if a Firmware Image Package is available */ 222 result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID); 223 if (result == 0) { 224 result = io_open(fip_dev_handle, spec, &local_image_handle); 225 if (result == 0) { 226 VERBOSE("Using FIP\n"); 227 io_close(local_image_handle); 228 } 229 } 230 return result; 231 } 232 233 void hikey960_io_setup(void) 234 { 235 int result; 236 237 result = register_io_dev_block(&ufs_dev_con); 238 assert(result == 0); 239 240 result = register_io_dev_fip(&fip_dev_con); 241 assert(result == 0); 242 243 result = io_dev_open(ufs_dev_con, (uintptr_t)&ufs_dev_spec, 244 &ufs_dev_handle); 245 assert(result == 0); 246 247 result = io_dev_open(fip_dev_con, (uintptr_t)NULL, &fip_dev_handle); 248 assert(result == 0); 249 250 /* Ignore improbable errors in release builds */ 251 (void)result; 252 } 253 254 /* Return an IO device handle and specification which can be used to access 255 * an image. Use this to enforce platform load policy 256 */ 257 int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle, 258 uintptr_t *image_spec) 259 { 260 int result; 261 const struct plat_io_policy *policy; 262 263 assert(image_id < ARRAY_SIZE(policies)); 264 265 policy = &policies[image_id]; 266 result = policy->check(policy->image_spec); 267 assert(result == 0); 268 269 *image_spec = policy->image_spec; 270 *dev_handle = *(policy->dev_handle); 271 272 return result; 273 } 274 275 size_t ufs_read_lun3_blks(int lba, uintptr_t buf, size_t size) 276 { 277 return ufs_read_blocks(3, lba, buf, size); 278 } 279 280 size_t ufs_write_lun3_blks(int lba, const uintptr_t buf, size_t size) 281 { 282 return ufs_write_blocks(3, lba, buf, size); 283 } 284