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