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