1 /* 2 * Copyright (c) 2017-2022, 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 <string.h> 10 11 #include <platform_def.h> 12 13 #include <arch_helpers.h> 14 #include <common/debug.h> 15 #include <drivers/ufs.h> 16 #include <drivers/io/io_block.h> 17 #include <drivers/io/io_driver.h> 18 #include <drivers/io/io_fip.h> 19 #include <drivers/io/io_memmap.h> 20 #include <drivers/io/io_storage.h> 21 #include <drivers/partition/partition.h> 22 #include <lib/mmio.h> 23 #include <lib/semihosting.h> 24 #include <tools_share/firmware_image_package.h> 25 26 struct plat_io_policy { 27 uintptr_t *dev_handle; 28 uintptr_t image_spec; 29 int (*check)(const uintptr_t spec); 30 }; 31 32 static const io_dev_connector_t *ufs_dev_con, *fip_dev_con; 33 static uintptr_t ufs_dev_handle, fip_dev_handle; 34 35 static int check_ufs(const uintptr_t spec); 36 static int check_fip(const uintptr_t spec); 37 size_t ufs_read_lun3_blks(int lba, uintptr_t buf, size_t size); 38 size_t ufs_write_lun3_blks(int lba, const uintptr_t buf, size_t size); 39 40 static io_block_spec_t ufs_fip_spec; 41 42 static const io_block_spec_t ufs_gpt_spec = { 43 .offset = 0, 44 .length = PLAT_PARTITION_BLOCK_SIZE * 45 (PLAT_PARTITION_MAX_ENTRIES / 4 + 2), 46 }; 47 48 static const io_block_dev_spec_t ufs_dev_spec = { 49 /* It's used as temp buffer in block driver. */ 50 .buffer = { 51 .offset = HIKEY960_UFS_DATA_BASE, 52 .length = HIKEY960_UFS_DATA_SIZE, 53 }, 54 .ops = { 55 .read = ufs_read_lun3_blks, 56 .write = ufs_write_lun3_blks, 57 }, 58 .block_size = UFS_BLOCK_SIZE, 59 }; 60 61 static const io_uuid_spec_t scp_bl2_uuid_spec = { 62 .uuid = UUID_SCP_FIRMWARE_SCP_BL2, 63 }; 64 65 static const io_uuid_spec_t bl31_uuid_spec = { 66 .uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31, 67 }; 68 69 static const io_uuid_spec_t bl32_uuid_spec = { 70 .uuid = UUID_SECURE_PAYLOAD_BL32, 71 }; 72 73 static const io_uuid_spec_t bl32_extra1_uuid_spec = { 74 .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA1, 75 }; 76 77 static const io_uuid_spec_t bl32_extra2_uuid_spec = { 78 .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA2, 79 }; 80 81 #ifdef SPD_spmd 82 static const io_uuid_spec_t bl32_tos_fw_spec = { 83 .uuid = UUID_TOS_FW_CONFIG, 84 }; 85 #endif 86 87 static const io_uuid_spec_t bl33_uuid_spec = { 88 .uuid = UUID_NON_TRUSTED_FIRMWARE_BL33, 89 }; 90 91 #if TRUSTED_BOARD_BOOT 92 static const io_uuid_spec_t trusted_key_cert_uuid_spec = { 93 .uuid = UUID_TRUSTED_KEY_CERT, 94 }; 95 96 static const io_uuid_spec_t scp_fw_key_cert_uuid_spec = { 97 .uuid = UUID_SCP_FW_KEY_CERT, 98 }; 99 100 static const io_uuid_spec_t soc_fw_key_cert_uuid_spec = { 101 .uuid = UUID_SOC_FW_KEY_CERT, 102 }; 103 104 static const io_uuid_spec_t tos_fw_key_cert_uuid_spec = { 105 .uuid = UUID_TRUSTED_OS_FW_KEY_CERT, 106 }; 107 108 static const io_uuid_spec_t nt_fw_key_cert_uuid_spec = { 109 .uuid = UUID_NON_TRUSTED_FW_KEY_CERT, 110 }; 111 112 static const io_uuid_spec_t scp_fw_cert_uuid_spec = { 113 .uuid = UUID_SCP_FW_CONTENT_CERT, 114 }; 115 116 static const io_uuid_spec_t soc_fw_cert_uuid_spec = { 117 .uuid = UUID_SOC_FW_CONTENT_CERT, 118 }; 119 120 static const io_uuid_spec_t tos_fw_cert_uuid_spec = { 121 .uuid = UUID_TRUSTED_OS_FW_CONTENT_CERT, 122 }; 123 124 static const io_uuid_spec_t nt_fw_cert_uuid_spec = { 125 .uuid = UUID_NON_TRUSTED_FW_CONTENT_CERT, 126 }; 127 #endif /* TRUSTED_BOARD_BOOT */ 128 129 static const struct plat_io_policy policies[] = { 130 [FIP_IMAGE_ID] = { 131 &ufs_dev_handle, 132 (uintptr_t)&ufs_fip_spec, 133 check_ufs 134 }, 135 [SCP_BL2_IMAGE_ID] = { 136 &fip_dev_handle, 137 (uintptr_t)&scp_bl2_uuid_spec, 138 check_fip 139 }, 140 [BL31_IMAGE_ID] = { 141 &fip_dev_handle, 142 (uintptr_t)&bl31_uuid_spec, 143 check_fip 144 }, 145 [BL32_IMAGE_ID] = { 146 &fip_dev_handle, 147 (uintptr_t)&bl32_uuid_spec, 148 check_fip 149 }, 150 [BL32_EXTRA1_IMAGE_ID] = { 151 &fip_dev_handle, 152 (uintptr_t)&bl32_extra1_uuid_spec, 153 check_fip 154 }, 155 [BL32_EXTRA2_IMAGE_ID] = { 156 &fip_dev_handle, 157 (uintptr_t)&bl32_extra2_uuid_spec, 158 check_fip 159 }, 160 161 #ifdef SPD_spmd 162 [TOS_FW_CONFIG_ID] = { 163 &fip_dev_handle, 164 (uintptr_t)&bl32_tos_fw_spec, 165 check_fip 166 }, 167 #endif 168 169 [BL33_IMAGE_ID] = { 170 &fip_dev_handle, 171 (uintptr_t)&bl33_uuid_spec, 172 check_fip 173 }, 174 #if TRUSTED_BOARD_BOOT 175 [TRUSTED_KEY_CERT_ID] = { 176 &fip_dev_handle, 177 (uintptr_t)&trusted_key_cert_uuid_spec, 178 check_fip 179 }, 180 [SCP_FW_KEY_CERT_ID] = { 181 &fip_dev_handle, 182 (uintptr_t)&scp_fw_key_cert_uuid_spec, 183 check_fip 184 }, 185 [SOC_FW_KEY_CERT_ID] = { 186 &fip_dev_handle, 187 (uintptr_t)&soc_fw_key_cert_uuid_spec, 188 check_fip 189 }, 190 [TRUSTED_OS_FW_KEY_CERT_ID] = { 191 &fip_dev_handle, 192 (uintptr_t)&tos_fw_key_cert_uuid_spec, 193 check_fip 194 }, 195 [NON_TRUSTED_FW_KEY_CERT_ID] = { 196 &fip_dev_handle, 197 (uintptr_t)&nt_fw_key_cert_uuid_spec, 198 check_fip 199 }, 200 [SCP_FW_CONTENT_CERT_ID] = { 201 &fip_dev_handle, 202 (uintptr_t)&scp_fw_cert_uuid_spec, 203 check_fip 204 }, 205 [SOC_FW_CONTENT_CERT_ID] = { 206 &fip_dev_handle, 207 (uintptr_t)&soc_fw_cert_uuid_spec, 208 check_fip 209 }, 210 [TRUSTED_OS_FW_CONTENT_CERT_ID] = { 211 &fip_dev_handle, 212 (uintptr_t)&tos_fw_cert_uuid_spec, 213 check_fip 214 }, 215 [NON_TRUSTED_FW_CONTENT_CERT_ID] = { 216 &fip_dev_handle, 217 (uintptr_t)&nt_fw_cert_uuid_spec, 218 check_fip 219 }, 220 #endif /* TRUSTED_BOARD_BOOT */ 221 [GPT_IMAGE_ID] = { 222 &ufs_dev_handle, 223 (uintptr_t)&ufs_gpt_spec, 224 check_ufs 225 }, 226 }; 227 228 static int check_ufs(const uintptr_t spec) 229 { 230 int result; 231 uintptr_t local_handle; 232 233 result = io_dev_init(ufs_dev_handle, (uintptr_t)NULL); 234 if (result == 0) { 235 result = io_open(ufs_dev_handle, spec, &local_handle); 236 if (result == 0) 237 io_close(local_handle); 238 } 239 return result; 240 } 241 242 static int check_fip(const uintptr_t spec) 243 { 244 int result; 245 uintptr_t local_image_handle; 246 247 /* See if a Firmware Image Package is available */ 248 result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID); 249 if (result == 0) { 250 result = io_open(fip_dev_handle, spec, &local_image_handle); 251 if (result == 0) { 252 VERBOSE("Using FIP\n"); 253 io_close(local_image_handle); 254 } 255 } 256 return result; 257 } 258 259 void hikey960_io_setup(void) 260 { 261 int result; 262 263 result = register_io_dev_block(&ufs_dev_con); 264 assert(result == 0); 265 266 result = register_io_dev_fip(&fip_dev_con); 267 assert(result == 0); 268 269 result = io_dev_open(ufs_dev_con, (uintptr_t)&ufs_dev_spec, 270 &ufs_dev_handle); 271 assert(result == 0); 272 273 result = io_dev_open(fip_dev_con, (uintptr_t)NULL, &fip_dev_handle); 274 assert(result == 0); 275 276 /* Ignore improbable errors in release builds */ 277 (void)result; 278 } 279 280 int hikey960_set_fip_addr(unsigned int image_id, const char *name) 281 { 282 const partition_entry_t *entry; 283 284 if (ufs_fip_spec.length == 0) { 285 partition_init(GPT_IMAGE_ID); 286 entry = get_partition_entry(name); 287 if (entry == NULL) { 288 ERROR("Could NOT find the %s partition!\n", name); 289 return -ENOENT; 290 } 291 ufs_fip_spec.offset = entry->start; 292 ufs_fip_spec.length = entry->length; 293 } 294 return 0; 295 } 296 297 /* Return an IO device handle and specification which can be used to access 298 * an image. Use this to enforce platform load policy 299 */ 300 int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle, 301 uintptr_t *image_spec) 302 { 303 int result; 304 const struct plat_io_policy *policy; 305 306 assert(image_id < ARRAY_SIZE(policies)); 307 308 policy = &policies[image_id]; 309 result = policy->check(policy->image_spec); 310 assert(result == 0); 311 312 *image_spec = policy->image_spec; 313 *dev_handle = *(policy->dev_handle); 314 315 return result; 316 } 317 318 size_t ufs_read_lun3_blks(int lba, uintptr_t buf, size_t size) 319 { 320 return ufs_read_blocks(3, lba, buf, size); 321 } 322 323 size_t ufs_write_lun3_blks(int lba, const uintptr_t buf, size_t size) 324 { 325 return ufs_write_blocks(3, lba, buf, size); 326 } 327