1*e9b5e360SHadi Asyrafi /* 2*e9b5e360SHadi Asyrafi * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. 3*e9b5e360SHadi Asyrafi * Copyright (c) 2019, Intel Corporation. All rights reserved. 4*e9b5e360SHadi Asyrafi * 5*e9b5e360SHadi Asyrafi * SPDX-License-Identifier: BSD-3-Clause 6*e9b5e360SHadi Asyrafi */ 7*e9b5e360SHadi Asyrafi 8*e9b5e360SHadi Asyrafi #include <arch_helpers.h> 9*e9b5e360SHadi Asyrafi #include <assert.h> 10*e9b5e360SHadi Asyrafi #include <common/debug.h> 11*e9b5e360SHadi Asyrafi #include <common/tbbr/tbbr_img_def.h> 12*e9b5e360SHadi Asyrafi #include <drivers/io/io_block.h> 13*e9b5e360SHadi Asyrafi #include <drivers/io/io_driver.h> 14*e9b5e360SHadi Asyrafi #include <drivers/io/io_fip.h> 15*e9b5e360SHadi Asyrafi #include <drivers/io/io_memmap.h> 16*e9b5e360SHadi Asyrafi #include <drivers/io/io_storage.h> 17*e9b5e360SHadi Asyrafi #include <drivers/mmc.h> 18*e9b5e360SHadi Asyrafi #include <drivers/partition/partition.h> 19*e9b5e360SHadi Asyrafi #include <lib/mmio.h> 20*e9b5e360SHadi Asyrafi #include <tools_share/firmware_image_package.h> 21*e9b5e360SHadi Asyrafi 22*e9b5e360SHadi Asyrafi #include "socfpga_private.h" 23*e9b5e360SHadi Asyrafi 24*e9b5e360SHadi Asyrafi #define PLAT_FIP_BASE (0) 25*e9b5e360SHadi Asyrafi #define PLAT_FIP_MAX_SIZE (0x1000000) 26*e9b5e360SHadi Asyrafi #define PLAT_MMC_DATA_BASE (0xffe3c000) 27*e9b5e360SHadi Asyrafi #define PLAT_MMC_DATA_SIZE (0x2000) 28*e9b5e360SHadi Asyrafi #define PLAT_QSPI_DATA_BASE (0x3C00000) 29*e9b5e360SHadi Asyrafi #define PLAT_QSPI_DATA_SIZE (0x1000000) 30*e9b5e360SHadi Asyrafi 31*e9b5e360SHadi Asyrafi 32*e9b5e360SHadi Asyrafi static const io_dev_connector_t *fip_dev_con; 33*e9b5e360SHadi Asyrafi static const io_dev_connector_t *boot_dev_con; 34*e9b5e360SHadi Asyrafi 35*e9b5e360SHadi Asyrafi static uintptr_t fip_dev_handle; 36*e9b5e360SHadi Asyrafi static uintptr_t boot_dev_handle; 37*e9b5e360SHadi Asyrafi 38*e9b5e360SHadi Asyrafi static const io_uuid_spec_t bl2_uuid_spec = { 39*e9b5e360SHadi Asyrafi .uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2, 40*e9b5e360SHadi Asyrafi }; 41*e9b5e360SHadi Asyrafi 42*e9b5e360SHadi Asyrafi static const io_uuid_spec_t bl31_uuid_spec = { 43*e9b5e360SHadi Asyrafi .uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31, 44*e9b5e360SHadi Asyrafi }; 45*e9b5e360SHadi Asyrafi 46*e9b5e360SHadi Asyrafi static const io_uuid_spec_t bl33_uuid_spec = { 47*e9b5e360SHadi Asyrafi .uuid = UUID_NON_TRUSTED_FIRMWARE_BL33, 48*e9b5e360SHadi Asyrafi }; 49*e9b5e360SHadi Asyrafi 50*e9b5e360SHadi Asyrafi uintptr_t a2_lba_offset; 51*e9b5e360SHadi Asyrafi const char a2[] = {0xa2, 0x0}; 52*e9b5e360SHadi Asyrafi 53*e9b5e360SHadi Asyrafi static const io_block_spec_t gpt_block_spec = { 54*e9b5e360SHadi Asyrafi .offset = 0, 55*e9b5e360SHadi Asyrafi .length = MMC_BLOCK_SIZE 56*e9b5e360SHadi Asyrafi }; 57*e9b5e360SHadi Asyrafi 58*e9b5e360SHadi Asyrafi static int check_fip(const uintptr_t spec); 59*e9b5e360SHadi Asyrafi static int check_dev(const uintptr_t spec); 60*e9b5e360SHadi Asyrafi 61*e9b5e360SHadi Asyrafi static io_block_dev_spec_t boot_dev_spec; 62*e9b5e360SHadi Asyrafi static int (*register_io_dev)(const io_dev_connector_t **); 63*e9b5e360SHadi Asyrafi 64*e9b5e360SHadi Asyrafi static io_block_spec_t fip_spec = { 65*e9b5e360SHadi Asyrafi .offset = PLAT_FIP_BASE, 66*e9b5e360SHadi Asyrafi .length = PLAT_FIP_MAX_SIZE, 67*e9b5e360SHadi Asyrafi }; 68*e9b5e360SHadi Asyrafi 69*e9b5e360SHadi Asyrafi struct plat_io_policy { 70*e9b5e360SHadi Asyrafi uintptr_t *dev_handle; 71*e9b5e360SHadi Asyrafi uintptr_t image_spec; 72*e9b5e360SHadi Asyrafi int (*check)(const uintptr_t spec); 73*e9b5e360SHadi Asyrafi }; 74*e9b5e360SHadi Asyrafi 75*e9b5e360SHadi Asyrafi static const struct plat_io_policy policies[] = { 76*e9b5e360SHadi Asyrafi [FIP_IMAGE_ID] = { 77*e9b5e360SHadi Asyrafi &boot_dev_handle, 78*e9b5e360SHadi Asyrafi (uintptr_t)&fip_spec, 79*e9b5e360SHadi Asyrafi check_dev 80*e9b5e360SHadi Asyrafi }, 81*e9b5e360SHadi Asyrafi [BL2_IMAGE_ID] = { 82*e9b5e360SHadi Asyrafi &fip_dev_handle, 83*e9b5e360SHadi Asyrafi (uintptr_t)&bl2_uuid_spec, 84*e9b5e360SHadi Asyrafi check_fip 85*e9b5e360SHadi Asyrafi }, 86*e9b5e360SHadi Asyrafi [BL31_IMAGE_ID] = { 87*e9b5e360SHadi Asyrafi &fip_dev_handle, 88*e9b5e360SHadi Asyrafi (uintptr_t)&bl31_uuid_spec, 89*e9b5e360SHadi Asyrafi check_fip 90*e9b5e360SHadi Asyrafi }, 91*e9b5e360SHadi Asyrafi [BL33_IMAGE_ID] = { 92*e9b5e360SHadi Asyrafi &fip_dev_handle, 93*e9b5e360SHadi Asyrafi (uintptr_t) &bl33_uuid_spec, 94*e9b5e360SHadi Asyrafi check_fip 95*e9b5e360SHadi Asyrafi }, 96*e9b5e360SHadi Asyrafi [GPT_IMAGE_ID] = { 97*e9b5e360SHadi Asyrafi &boot_dev_handle, 98*e9b5e360SHadi Asyrafi (uintptr_t) &gpt_block_spec, 99*e9b5e360SHadi Asyrafi check_dev 100*e9b5e360SHadi Asyrafi }, 101*e9b5e360SHadi Asyrafi }; 102*e9b5e360SHadi Asyrafi 103*e9b5e360SHadi Asyrafi static int check_dev(const uintptr_t spec) 104*e9b5e360SHadi Asyrafi { 105*e9b5e360SHadi Asyrafi int result; 106*e9b5e360SHadi Asyrafi uintptr_t local_handle; 107*e9b5e360SHadi Asyrafi 108*e9b5e360SHadi Asyrafi result = io_dev_init(boot_dev_handle, (uintptr_t)NULL); 109*e9b5e360SHadi Asyrafi if (result == 0) { 110*e9b5e360SHadi Asyrafi result = io_open(boot_dev_handle, spec, &local_handle); 111*e9b5e360SHadi Asyrafi if (result == 0) 112*e9b5e360SHadi Asyrafi io_close(local_handle); 113*e9b5e360SHadi Asyrafi } 114*e9b5e360SHadi Asyrafi return result; 115*e9b5e360SHadi Asyrafi } 116*e9b5e360SHadi Asyrafi 117*e9b5e360SHadi Asyrafi static int check_fip(const uintptr_t spec) 118*e9b5e360SHadi Asyrafi { 119*e9b5e360SHadi Asyrafi int result; 120*e9b5e360SHadi Asyrafi uintptr_t local_image_handle; 121*e9b5e360SHadi Asyrafi 122*e9b5e360SHadi Asyrafi result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID); 123*e9b5e360SHadi Asyrafi if (result == 0) { 124*e9b5e360SHadi Asyrafi result = io_open(fip_dev_handle, spec, &local_image_handle); 125*e9b5e360SHadi Asyrafi if (result == 0) 126*e9b5e360SHadi Asyrafi io_close(local_image_handle); 127*e9b5e360SHadi Asyrafi } 128*e9b5e360SHadi Asyrafi return result; 129*e9b5e360SHadi Asyrafi } 130*e9b5e360SHadi Asyrafi 131*e9b5e360SHadi Asyrafi void socfpga_io_setup(int boot_source) 132*e9b5e360SHadi Asyrafi { 133*e9b5e360SHadi Asyrafi int result; 134*e9b5e360SHadi Asyrafi 135*e9b5e360SHadi Asyrafi switch (boot_source) { 136*e9b5e360SHadi Asyrafi case BOOT_SOURCE_SDMMC: 137*e9b5e360SHadi Asyrafi register_io_dev = ®ister_io_dev_block; 138*e9b5e360SHadi Asyrafi boot_dev_spec.buffer.offset = PLAT_MMC_DATA_BASE; 139*e9b5e360SHadi Asyrafi boot_dev_spec.buffer.length = MMC_BLOCK_SIZE; 140*e9b5e360SHadi Asyrafi boot_dev_spec.ops.read = mmc_read_blocks; 141*e9b5e360SHadi Asyrafi boot_dev_spec.ops.write = mmc_write_blocks; 142*e9b5e360SHadi Asyrafi boot_dev_spec.block_size = MMC_BLOCK_SIZE; 143*e9b5e360SHadi Asyrafi break; 144*e9b5e360SHadi Asyrafi 145*e9b5e360SHadi Asyrafi case BOOT_SOURCE_QSPI: 146*e9b5e360SHadi Asyrafi register_io_dev = ®ister_io_dev_memmap; 147*e9b5e360SHadi Asyrafi fip_spec.offset = fip_spec.offset + PLAT_QSPI_DATA_BASE; 148*e9b5e360SHadi Asyrafi break; 149*e9b5e360SHadi Asyrafi 150*e9b5e360SHadi Asyrafi default: 151*e9b5e360SHadi Asyrafi ERROR("Unsupported boot source\n"); 152*e9b5e360SHadi Asyrafi panic(); 153*e9b5e360SHadi Asyrafi break; 154*e9b5e360SHadi Asyrafi } 155*e9b5e360SHadi Asyrafi 156*e9b5e360SHadi Asyrafi result = (*register_io_dev)(&boot_dev_con); 157*e9b5e360SHadi Asyrafi assert(result == 0); 158*e9b5e360SHadi Asyrafi 159*e9b5e360SHadi Asyrafi result = register_io_dev_fip(&fip_dev_con); 160*e9b5e360SHadi Asyrafi assert(result == 0); 161*e9b5e360SHadi Asyrafi 162*e9b5e360SHadi Asyrafi result = io_dev_open(boot_dev_con, (uintptr_t)&boot_dev_spec, 163*e9b5e360SHadi Asyrafi &boot_dev_handle); 164*e9b5e360SHadi Asyrafi assert(result == 0); 165*e9b5e360SHadi Asyrafi 166*e9b5e360SHadi Asyrafi result = io_dev_open(fip_dev_con, (uintptr_t)NULL, &fip_dev_handle); 167*e9b5e360SHadi Asyrafi assert(result == 0); 168*e9b5e360SHadi Asyrafi 169*e9b5e360SHadi Asyrafi if (boot_source == BOOT_SOURCE_SDMMC) { 170*e9b5e360SHadi Asyrafi partition_init(GPT_IMAGE_ID); 171*e9b5e360SHadi Asyrafi fip_spec.offset = get_partition_entry(a2)->start; 172*e9b5e360SHadi Asyrafi } 173*e9b5e360SHadi Asyrafi 174*e9b5e360SHadi Asyrafi (void)result; 175*e9b5e360SHadi Asyrafi } 176*e9b5e360SHadi Asyrafi 177*e9b5e360SHadi Asyrafi int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle, 178*e9b5e360SHadi Asyrafi uintptr_t *image_spec) 179*e9b5e360SHadi Asyrafi { 180*e9b5e360SHadi Asyrafi int result; 181*e9b5e360SHadi Asyrafi const struct plat_io_policy *policy; 182*e9b5e360SHadi Asyrafi 183*e9b5e360SHadi Asyrafi assert(image_id < ARRAY_SIZE(policies)); 184*e9b5e360SHadi Asyrafi 185*e9b5e360SHadi Asyrafi policy = &policies[image_id]; 186*e9b5e360SHadi Asyrafi result = policy->check(policy->image_spec); 187*e9b5e360SHadi Asyrafi assert(result == 0); 188*e9b5e360SHadi Asyrafi 189*e9b5e360SHadi Asyrafi *image_spec = policy->image_spec; 190*e9b5e360SHadi Asyrafi *dev_handle = *(policy->dev_handle); 191*e9b5e360SHadi Asyrafi 192*e9b5e360SHadi Asyrafi return result; 193*e9b5e360SHadi Asyrafi } 194