1e35d0edbSJorge Ramirez-Ortiz /* 2e35d0edbSJorge Ramirez-Ortiz * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. 3e35d0edbSJorge Ramirez-Ortiz * 4e35d0edbSJorge Ramirez-Ortiz * SPDX-License-Identifier: BSD-3-Clause 5e35d0edbSJorge Ramirez-Ortiz */ 6e35d0edbSJorge Ramirez-Ortiz 7e35d0edbSJorge Ramirez-Ortiz #include <assert.h> 8e35d0edbSJorge Ramirez-Ortiz #include <string.h> 9*09d40e0eSAntonio Nino Diaz 10*09d40e0eSAntonio Nino Diaz #include <platform_def.h> 11*09d40e0eSAntonio Nino Diaz 12*09d40e0eSAntonio Nino Diaz #include <arch_helpers.h> 13*09d40e0eSAntonio Nino Diaz #include <common/debug.h> 14*09d40e0eSAntonio Nino Diaz #include <common/tbbr/tbbr_img_def.h> 15*09d40e0eSAntonio Nino Diaz #include <drivers/io/io_block.h> 16*09d40e0eSAntonio Nino Diaz #include <drivers/io/io_driver.h> 17*09d40e0eSAntonio Nino Diaz #include <drivers/io/io_fip.h> 18*09d40e0eSAntonio Nino Diaz #include <drivers/io/io_memmap.h> 19*09d40e0eSAntonio Nino Diaz #include <drivers/io/io_storage.h> 20*09d40e0eSAntonio Nino Diaz #include <drivers/mmc.h> 21*09d40e0eSAntonio Nino Diaz #include <drivers/partition/partition.h> 22*09d40e0eSAntonio Nino Diaz #include <lib/mmio.h> 23*09d40e0eSAntonio Nino Diaz #include <lib/semihosting.h> 24*09d40e0eSAntonio Nino Diaz #include <lib/utils.h> 25*09d40e0eSAntonio Nino Diaz #include <tools_share/firmware_image_package.h> 26e35d0edbSJorge Ramirez-Ortiz 2715b54e7bSVictor Chong #if !POPLAR_RECOVERY 2859149bbeSVictor Chong static const io_dev_connector_t *emmc_dev_con; 2959149bbeSVictor Chong static uintptr_t emmc_dev_handle; 3059149bbeSVictor Chong static int open_emmc(const uintptr_t spec); 31e35d0edbSJorge Ramirez-Ortiz 3259149bbeSVictor Chong static const io_block_spec_t emmc_fip_spec = { 3359149bbeSVictor Chong .offset = FIP_BASE_EMMC, 34e35d0edbSJorge Ramirez-Ortiz .length = FIP_SIZE 35e35d0edbSJorge Ramirez-Ortiz }; 36e35d0edbSJorge Ramirez-Ortiz 3759149bbeSVictor Chong static const io_block_dev_spec_t emmc_dev_spec = { 3859149bbeSVictor Chong .buffer = { 3959149bbeSVictor Chong .offset = POPLAR_EMMC_DATA_BASE, 4059149bbeSVictor Chong .length = POPLAR_EMMC_DATA_SIZE, 4159149bbeSVictor Chong }, 4259149bbeSVictor Chong .ops = { 43eba1b6b3SHaojian Zhuang .read = mmc_read_blocks, 44eba1b6b3SHaojian Zhuang .write = mmc_write_blocks, 4559149bbeSVictor Chong }, 46eba1b6b3SHaojian Zhuang .block_size = MMC_BLOCK_SIZE, 4759149bbeSVictor Chong }; 4815b54e7bSVictor Chong #else 4915b54e7bSVictor Chong static const io_dev_connector_t *mmap_dev_con; 5015b54e7bSVictor Chong static uintptr_t mmap_dev_handle; 5115b54e7bSVictor Chong static int open_mmap(const uintptr_t spec); 5215b54e7bSVictor Chong 5315b54e7bSVictor Chong static const io_block_spec_t loader_fip_spec = { 5415b54e7bSVictor Chong .offset = FIP_BASE, 5515b54e7bSVictor Chong .length = FIP_SIZE 5615b54e7bSVictor Chong }; 5715b54e7bSVictor Chong #endif 5815b54e7bSVictor Chong 5915b54e7bSVictor Chong static const io_dev_connector_t *fip_dev_con; 6015b54e7bSVictor Chong static uintptr_t fip_dev_handle; 6115b54e7bSVictor Chong static int open_fip(const uintptr_t spec); 6259149bbeSVictor Chong 63e35d0edbSJorge Ramirez-Ortiz static const io_uuid_spec_t bl2_uuid_spec = { 64e35d0edbSJorge Ramirez-Ortiz .uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2, 65e35d0edbSJorge Ramirez-Ortiz }; 66e35d0edbSJorge Ramirez-Ortiz 67e35d0edbSJorge Ramirez-Ortiz static const io_uuid_spec_t bl31_uuid_spec = { 68e35d0edbSJorge Ramirez-Ortiz .uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31, 69e35d0edbSJorge Ramirez-Ortiz }; 70e35d0edbSJorge Ramirez-Ortiz 71f336774bSVictor Chong static const io_uuid_spec_t bl32_uuid_spec = { 72f336774bSVictor Chong .uuid = UUID_SECURE_PAYLOAD_BL32, 73f336774bSVictor Chong }; 74f336774bSVictor Chong 75f3d522beSVictor Chong static const io_uuid_spec_t bl32_extra1_uuid_spec = { 76f3d522beSVictor Chong .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA1, 77f3d522beSVictor Chong }; 78f3d522beSVictor Chong 79f3d522beSVictor Chong static const io_uuid_spec_t bl32_extra2_uuid_spec = { 80f3d522beSVictor Chong .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA2, 81f3d522beSVictor Chong }; 82f3d522beSVictor Chong 83e35d0edbSJorge Ramirez-Ortiz static const io_uuid_spec_t bl33_uuid_spec = { 84e35d0edbSJorge Ramirez-Ortiz .uuid = UUID_NON_TRUSTED_FIRMWARE_BL33, 85e35d0edbSJorge Ramirez-Ortiz }; 86e35d0edbSJorge Ramirez-Ortiz 87e35d0edbSJorge Ramirez-Ortiz struct plat_io_policy { 88e35d0edbSJorge Ramirez-Ortiz uintptr_t *dev_handle; 89e35d0edbSJorge Ramirez-Ortiz uintptr_t image_spec; 90e35d0edbSJorge Ramirez-Ortiz int (*check)(const uintptr_t spec); 91e35d0edbSJorge Ramirez-Ortiz }; 92e35d0edbSJorge Ramirez-Ortiz 93e35d0edbSJorge Ramirez-Ortiz static const struct plat_io_policy policies[] = { 9415b54e7bSVictor Chong #if !POPLAR_RECOVERY 95e35d0edbSJorge Ramirez-Ortiz [FIP_IMAGE_ID] = { 9659149bbeSVictor Chong &emmc_dev_handle, 9759149bbeSVictor Chong (uintptr_t)&emmc_fip_spec, 9859149bbeSVictor Chong open_emmc 99e35d0edbSJorge Ramirez-Ortiz }, 10015b54e7bSVictor Chong #else 10115b54e7bSVictor Chong [FIP_IMAGE_ID] = { 10215b54e7bSVictor Chong &mmap_dev_handle, 10315b54e7bSVictor Chong (uintptr_t)&loader_fip_spec, 10415b54e7bSVictor Chong open_mmap 10515b54e7bSVictor Chong }, 10615b54e7bSVictor Chong #endif 107e35d0edbSJorge Ramirez-Ortiz [BL2_IMAGE_ID] = { 108e35d0edbSJorge Ramirez-Ortiz &fip_dev_handle, 109e35d0edbSJorge Ramirez-Ortiz (uintptr_t)&bl2_uuid_spec, 110e35d0edbSJorge Ramirez-Ortiz open_fip 111e35d0edbSJorge Ramirez-Ortiz }, 112e35d0edbSJorge Ramirez-Ortiz [BL31_IMAGE_ID] = { 113e35d0edbSJorge Ramirez-Ortiz &fip_dev_handle, 114e35d0edbSJorge Ramirez-Ortiz (uintptr_t)&bl31_uuid_spec, 115e35d0edbSJorge Ramirez-Ortiz open_fip 116e35d0edbSJorge Ramirez-Ortiz }, 117f336774bSVictor Chong [BL32_IMAGE_ID] = { 118f336774bSVictor Chong &fip_dev_handle, 119f336774bSVictor Chong (uintptr_t)&bl32_uuid_spec, 120f336774bSVictor Chong open_fip 121f336774bSVictor Chong }, 122f3d522beSVictor Chong [BL32_EXTRA1_IMAGE_ID] = { 123f3d522beSVictor Chong &fip_dev_handle, 124f3d522beSVictor Chong (uintptr_t)&bl32_extra1_uuid_spec, 125f3d522beSVictor Chong open_fip 126f3d522beSVictor Chong }, 127f3d522beSVictor Chong [BL32_EXTRA2_IMAGE_ID] = { 128f3d522beSVictor Chong &fip_dev_handle, 129f3d522beSVictor Chong (uintptr_t)&bl32_extra2_uuid_spec, 130f3d522beSVictor Chong open_fip 131f3d522beSVictor Chong }, 132e35d0edbSJorge Ramirez-Ortiz [BL33_IMAGE_ID] = { 133e35d0edbSJorge Ramirez-Ortiz &fip_dev_handle, 134e35d0edbSJorge Ramirez-Ortiz (uintptr_t)&bl33_uuid_spec, 135e35d0edbSJorge Ramirez-Ortiz open_fip 136e35d0edbSJorge Ramirez-Ortiz }, 137e35d0edbSJorge Ramirez-Ortiz }; 138e35d0edbSJorge Ramirez-Ortiz 13915b54e7bSVictor Chong #if !POPLAR_RECOVERY 14059149bbeSVictor Chong static int open_emmc(const uintptr_t spec) 141e35d0edbSJorge Ramirez-Ortiz { 142e35d0edbSJorge Ramirez-Ortiz int result; 143e35d0edbSJorge Ramirez-Ortiz uintptr_t local_image_handle; 144e35d0edbSJorge Ramirez-Ortiz 14559149bbeSVictor Chong result = io_dev_init(emmc_dev_handle, (uintptr_t)NULL); 146e35d0edbSJorge Ramirez-Ortiz if (result == 0) { 14759149bbeSVictor Chong result = io_open(emmc_dev_handle, spec, &local_image_handle); 148e35d0edbSJorge Ramirez-Ortiz if (result == 0) { 14959149bbeSVictor Chong INFO("Using eMMC\n"); 150e35d0edbSJorge Ramirez-Ortiz io_close(local_image_handle); 15159149bbeSVictor Chong } else { 15259149bbeSVictor Chong ERROR("error opening emmc\n"); 153e35d0edbSJorge Ramirez-Ortiz } 15459149bbeSVictor Chong } else { 15559149bbeSVictor Chong ERROR("error initializing emmc\n"); 156e35d0edbSJorge Ramirez-Ortiz } 15759149bbeSVictor Chong 158e35d0edbSJorge Ramirez-Ortiz return result; 159e35d0edbSJorge Ramirez-Ortiz } 16015b54e7bSVictor Chong #else 16115b54e7bSVictor Chong static int open_mmap(const uintptr_t spec) 16215b54e7bSVictor Chong { 16315b54e7bSVictor Chong int result; 16415b54e7bSVictor Chong uintptr_t local_image_handle; 16515b54e7bSVictor Chong 16615b54e7bSVictor Chong result = io_dev_init(mmap_dev_handle, (uintptr_t)NULL); 16715b54e7bSVictor Chong if (result == 0) { 16815b54e7bSVictor Chong result = io_open(mmap_dev_handle, spec, &local_image_handle); 16915b54e7bSVictor Chong if (result == 0) { 17015b54e7bSVictor Chong INFO("Using mmap\n"); 17115b54e7bSVictor Chong io_close(local_image_handle); 17215b54e7bSVictor Chong } else { 17315b54e7bSVictor Chong ERROR("error opening mmap\n"); 17415b54e7bSVictor Chong } 17515b54e7bSVictor Chong } else { 17615b54e7bSVictor Chong ERROR("error initializing mmap\n"); 17715b54e7bSVictor Chong } 17815b54e7bSVictor Chong 17915b54e7bSVictor Chong return result; 18015b54e7bSVictor Chong } 18115b54e7bSVictor Chong #endif 182e35d0edbSJorge Ramirez-Ortiz 183e35d0edbSJorge Ramirez-Ortiz static int open_fip(const uintptr_t spec) 184e35d0edbSJorge Ramirez-Ortiz { 185e35d0edbSJorge Ramirez-Ortiz uintptr_t local_image_handle; 186e35d0edbSJorge Ramirez-Ortiz int result; 187e35d0edbSJorge Ramirez-Ortiz 188e35d0edbSJorge Ramirez-Ortiz result = io_dev_init(fip_dev_handle, (uintptr_t) FIP_IMAGE_ID); 189e35d0edbSJorge Ramirez-Ortiz if (result == 0) { 190e35d0edbSJorge Ramirez-Ortiz result = io_open(fip_dev_handle, spec, &local_image_handle); 191e35d0edbSJorge Ramirez-Ortiz if (result == 0) { 19259149bbeSVictor Chong INFO("Using FIP\n"); 193e35d0edbSJorge Ramirez-Ortiz io_close(local_image_handle); 194e35d0edbSJorge Ramirez-Ortiz } else { 19559149bbeSVictor Chong ERROR("error opening fip\n"); 196e35d0edbSJorge Ramirez-Ortiz } 197e35d0edbSJorge Ramirez-Ortiz } else { 19859149bbeSVictor Chong ERROR("error initializing fip\n"); 199e35d0edbSJorge Ramirez-Ortiz } 200e35d0edbSJorge Ramirez-Ortiz 201e35d0edbSJorge Ramirez-Ortiz return result; 202e35d0edbSJorge Ramirez-Ortiz } 203e35d0edbSJorge Ramirez-Ortiz 204e35d0edbSJorge Ramirez-Ortiz int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle, 205e35d0edbSJorge Ramirez-Ortiz uintptr_t *image_spec) 206e35d0edbSJorge Ramirez-Ortiz { 207e35d0edbSJorge Ramirez-Ortiz const struct plat_io_policy *policy; 208e35d0edbSJorge Ramirez-Ortiz int result; 209e35d0edbSJorge Ramirez-Ortiz 210e35d0edbSJorge Ramirez-Ortiz assert(image_id < ARRAY_SIZE(policies)); 211e35d0edbSJorge Ramirez-Ortiz 212e35d0edbSJorge Ramirez-Ortiz policy = &policies[image_id]; 213e35d0edbSJorge Ramirez-Ortiz result = policy->check(policy->image_spec); 214e35d0edbSJorge Ramirez-Ortiz assert(result == 0); 215e35d0edbSJorge Ramirez-Ortiz 216e35d0edbSJorge Ramirez-Ortiz *image_spec = policy->image_spec; 217e35d0edbSJorge Ramirez-Ortiz *dev_handle = *(policy->dev_handle); 218e35d0edbSJorge Ramirez-Ortiz 219e35d0edbSJorge Ramirez-Ortiz return result; 220e35d0edbSJorge Ramirez-Ortiz } 221e35d0edbSJorge Ramirez-Ortiz 222e35d0edbSJorge Ramirez-Ortiz void plat_io_setup(void) 223e35d0edbSJorge Ramirez-Ortiz { 224e35d0edbSJorge Ramirez-Ortiz int result; 225e35d0edbSJorge Ramirez-Ortiz 22615b54e7bSVictor Chong #if !POPLAR_RECOVERY 22759149bbeSVictor Chong result = register_io_dev_block(&emmc_dev_con); 22815b54e7bSVictor Chong #else 22915b54e7bSVictor Chong result = register_io_dev_memmap(&mmap_dev_con); 23015b54e7bSVictor Chong #endif 231e35d0edbSJorge Ramirez-Ortiz assert(result == 0); 232e35d0edbSJorge Ramirez-Ortiz 233e35d0edbSJorge Ramirez-Ortiz result = register_io_dev_fip(&fip_dev_con); 234e35d0edbSJorge Ramirez-Ortiz assert(result == 0); 235e35d0edbSJorge Ramirez-Ortiz 23615b54e7bSVictor Chong #if !POPLAR_RECOVERY 23759149bbeSVictor Chong result = io_dev_open(fip_dev_con, (uintptr_t)NULL, 238e35d0edbSJorge Ramirez-Ortiz &fip_dev_handle); 23915b54e7bSVictor Chong #else 24015b54e7bSVictor Chong result = io_dev_open(fip_dev_con, (uintptr_t)&loader_fip_spec, 24115b54e7bSVictor Chong &fip_dev_handle); 24215b54e7bSVictor Chong #endif 243e35d0edbSJorge Ramirez-Ortiz assert(result == 0); 244e35d0edbSJorge Ramirez-Ortiz 24515b54e7bSVictor Chong #if !POPLAR_RECOVERY 24659149bbeSVictor Chong result = io_dev_open(emmc_dev_con, (uintptr_t)&emmc_dev_spec, 24759149bbeSVictor Chong &emmc_dev_handle); 24815b54e7bSVictor Chong #else 24915b54e7bSVictor Chong result = io_dev_open(mmap_dev_con, (uintptr_t)NULL, &mmap_dev_handle); 25015b54e7bSVictor Chong #endif 251e35d0edbSJorge Ramirez-Ortiz assert(result == 0); 252e35d0edbSJorge Ramirez-Ortiz 253e35d0edbSJorge Ramirez-Ortiz (void) result; 254e35d0edbSJorge Ramirez-Ortiz } 255