1*c9d75b3cSYann Gautier /* 2*c9d75b3cSYann Gautier * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. 3*c9d75b3cSYann Gautier * 4*c9d75b3cSYann Gautier * SPDX-License-Identifier: BSD-3-Clause 5*c9d75b3cSYann Gautier */ 6*c9d75b3cSYann Gautier 7*c9d75b3cSYann Gautier #include <assert.h> 8*c9d75b3cSYann Gautier #include <string.h> 9*c9d75b3cSYann Gautier 10*c9d75b3cSYann Gautier #include <platform_def.h> 11*c9d75b3cSYann Gautier 12*c9d75b3cSYann Gautier #include <arch_helpers.h> 13*c9d75b3cSYann Gautier #include <common/debug.h> 14*c9d75b3cSYann Gautier #include <drivers/io/io_block.h> 15*c9d75b3cSYann Gautier #include <drivers/io/io_driver.h> 16*c9d75b3cSYann Gautier #include <drivers/io/io_dummy.h> 17*c9d75b3cSYann Gautier #include <drivers/io/io_storage.h> 18*c9d75b3cSYann Gautier #include <drivers/mmc.h> 19*c9d75b3cSYann Gautier #include <drivers/partition/partition.h> 20*c9d75b3cSYann Gautier #include <drivers/st/io_mmc.h> 21*c9d75b3cSYann Gautier #include <drivers/st/io_stm32image.h> 22*c9d75b3cSYann Gautier #include <drivers/st/stm32_sdmmc2.h> 23*c9d75b3cSYann Gautier #include <drivers/st/stm32mp1_rcc.h> 24*c9d75b3cSYann Gautier #include <lib/mmio.h> 25*c9d75b3cSYann Gautier #include <lib/utils.h> 26*c9d75b3cSYann Gautier #include <plat/common/platform.h> 27*c9d75b3cSYann Gautier 28*c9d75b3cSYann Gautier /* IO devices */ 29*c9d75b3cSYann Gautier static const io_dev_connector_t *dummy_dev_con; 30*c9d75b3cSYann Gautier static uintptr_t dummy_dev_handle; 31*c9d75b3cSYann Gautier static uintptr_t dummy_dev_spec; 32*c9d75b3cSYann Gautier 33*c9d75b3cSYann Gautier static uintptr_t image_dev_handle; 34*c9d75b3cSYann Gautier 35*c9d75b3cSYann Gautier static io_block_spec_t gpt_block_spec = { 36*c9d75b3cSYann Gautier .offset = 0, 37*c9d75b3cSYann Gautier .length = 34 * MMC_BLOCK_SIZE, /* Size of GPT table */ 38*c9d75b3cSYann Gautier }; 39*c9d75b3cSYann Gautier 40*c9d75b3cSYann Gautier static uint32_t block_buffer[MMC_BLOCK_SIZE] __aligned(MMC_BLOCK_SIZE); 41*c9d75b3cSYann Gautier 42*c9d75b3cSYann Gautier static const io_block_dev_spec_t mmc_block_dev_spec = { 43*c9d75b3cSYann Gautier /* It's used as temp buffer in block driver */ 44*c9d75b3cSYann Gautier .buffer = { 45*c9d75b3cSYann Gautier .offset = (size_t)&block_buffer, 46*c9d75b3cSYann Gautier .length = MMC_BLOCK_SIZE, 47*c9d75b3cSYann Gautier }, 48*c9d75b3cSYann Gautier .ops = { 49*c9d75b3cSYann Gautier .read = mmc_read_blocks, 50*c9d75b3cSYann Gautier .write = NULL, 51*c9d75b3cSYann Gautier }, 52*c9d75b3cSYann Gautier .block_size = MMC_BLOCK_SIZE, 53*c9d75b3cSYann Gautier }; 54*c9d75b3cSYann Gautier 55*c9d75b3cSYann Gautier static uintptr_t storage_dev_handle; 56*c9d75b3cSYann Gautier static const io_dev_connector_t *mmc_dev_con; 57*c9d75b3cSYann Gautier 58*c9d75b3cSYann Gautier static const io_block_spec_t bl32_block_spec = { 59*c9d75b3cSYann Gautier .offset = BL32_BASE, 60*c9d75b3cSYann Gautier .length = STM32MP1_BL32_SIZE 61*c9d75b3cSYann Gautier }; 62*c9d75b3cSYann Gautier 63*c9d75b3cSYann Gautier static const io_block_spec_t bl2_block_spec = { 64*c9d75b3cSYann Gautier .offset = BL2_BASE, 65*c9d75b3cSYann Gautier .length = STM32MP1_BL2_SIZE, 66*c9d75b3cSYann Gautier }; 67*c9d75b3cSYann Gautier 68*c9d75b3cSYann Gautier static const struct stm32image_part_info bl33_partition_spec = { 69*c9d75b3cSYann Gautier .name = BL33_IMAGE_NAME, 70*c9d75b3cSYann Gautier .binary_type = BL33_BINARY_TYPE, 71*c9d75b3cSYann Gautier }; 72*c9d75b3cSYann Gautier 73*c9d75b3cSYann Gautier enum { 74*c9d75b3cSYann Gautier IMG_IDX_BL33, 75*c9d75b3cSYann Gautier IMG_IDX_NUM 76*c9d75b3cSYann Gautier }; 77*c9d75b3cSYann Gautier 78*c9d75b3cSYann Gautier static struct stm32image_device_info stm32image_dev_info_spec = { 79*c9d75b3cSYann Gautier .lba_size = MMC_BLOCK_SIZE, 80*c9d75b3cSYann Gautier .part_info[IMG_IDX_BL33] = { 81*c9d75b3cSYann Gautier .name = BL33_IMAGE_NAME, 82*c9d75b3cSYann Gautier .binary_type = BL33_BINARY_TYPE, 83*c9d75b3cSYann Gautier }, 84*c9d75b3cSYann Gautier }; 85*c9d75b3cSYann Gautier 86*c9d75b3cSYann Gautier static io_block_spec_t stm32image_block_spec = { 87*c9d75b3cSYann Gautier .offset = 0, 88*c9d75b3cSYann Gautier .length = 0, 89*c9d75b3cSYann Gautier }; 90*c9d75b3cSYann Gautier 91*c9d75b3cSYann Gautier static const io_dev_connector_t *stm32image_dev_con; 92*c9d75b3cSYann Gautier 93*c9d75b3cSYann Gautier static int open_dummy(const uintptr_t spec); 94*c9d75b3cSYann Gautier static int open_image(const uintptr_t spec); 95*c9d75b3cSYann Gautier static int open_storage(const uintptr_t spec); 96*c9d75b3cSYann Gautier 97*c9d75b3cSYann Gautier struct plat_io_policy { 98*c9d75b3cSYann Gautier uintptr_t *dev_handle; 99*c9d75b3cSYann Gautier uintptr_t image_spec; 100*c9d75b3cSYann Gautier int (*check)(const uintptr_t spec); 101*c9d75b3cSYann Gautier }; 102*c9d75b3cSYann Gautier 103*c9d75b3cSYann Gautier static const struct plat_io_policy policies[] = { 104*c9d75b3cSYann Gautier [BL2_IMAGE_ID] = { 105*c9d75b3cSYann Gautier .dev_handle = &dummy_dev_handle, 106*c9d75b3cSYann Gautier .image_spec = (uintptr_t)&bl2_block_spec, 107*c9d75b3cSYann Gautier .check = open_dummy 108*c9d75b3cSYann Gautier }, 109*c9d75b3cSYann Gautier [BL32_IMAGE_ID] = { 110*c9d75b3cSYann Gautier .dev_handle = &dummy_dev_handle, 111*c9d75b3cSYann Gautier .image_spec = (uintptr_t)&bl32_block_spec, 112*c9d75b3cSYann Gautier .check = open_dummy 113*c9d75b3cSYann Gautier }, 114*c9d75b3cSYann Gautier [BL33_IMAGE_ID] = { 115*c9d75b3cSYann Gautier .dev_handle = &image_dev_handle, 116*c9d75b3cSYann Gautier .image_spec = (uintptr_t)&bl33_partition_spec, 117*c9d75b3cSYann Gautier .check = open_image 118*c9d75b3cSYann Gautier }, 119*c9d75b3cSYann Gautier [GPT_IMAGE_ID] = { 120*c9d75b3cSYann Gautier .dev_handle = &storage_dev_handle, 121*c9d75b3cSYann Gautier .image_spec = (uintptr_t)&gpt_block_spec, 122*c9d75b3cSYann Gautier .check = open_storage 123*c9d75b3cSYann Gautier }, 124*c9d75b3cSYann Gautier [STM32_IMAGE_ID] = { 125*c9d75b3cSYann Gautier .dev_handle = &storage_dev_handle, 126*c9d75b3cSYann Gautier .image_spec = (uintptr_t)&stm32image_block_spec, 127*c9d75b3cSYann Gautier .check = open_storage 128*c9d75b3cSYann Gautier } 129*c9d75b3cSYann Gautier }; 130*c9d75b3cSYann Gautier 131*c9d75b3cSYann Gautier static int open_dummy(const uintptr_t spec) 132*c9d75b3cSYann Gautier { 133*c9d75b3cSYann Gautier return io_dev_init(dummy_dev_handle, 0); 134*c9d75b3cSYann Gautier } 135*c9d75b3cSYann Gautier 136*c9d75b3cSYann Gautier static int open_image(const uintptr_t spec) 137*c9d75b3cSYann Gautier { 138*c9d75b3cSYann Gautier return io_dev_init(image_dev_handle, 0); 139*c9d75b3cSYann Gautier } 140*c9d75b3cSYann Gautier 141*c9d75b3cSYann Gautier static int open_storage(const uintptr_t spec) 142*c9d75b3cSYann Gautier { 143*c9d75b3cSYann Gautier return io_dev_init(storage_dev_handle, 0); 144*c9d75b3cSYann Gautier } 145*c9d75b3cSYann Gautier 146*c9d75b3cSYann Gautier static void print_boot_device(boot_api_context_t *boot_context) 147*c9d75b3cSYann Gautier { 148*c9d75b3cSYann Gautier switch (boot_context->boot_interface_selected) { 149*c9d75b3cSYann Gautier case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_SD: 150*c9d75b3cSYann Gautier INFO("Using SDMMC\n"); 151*c9d75b3cSYann Gautier break; 152*c9d75b3cSYann Gautier case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_EMMC: 153*c9d75b3cSYann Gautier INFO("Using EMMC\n"); 154*c9d75b3cSYann Gautier break; 155*c9d75b3cSYann Gautier default: 156*c9d75b3cSYann Gautier ERROR("Boot interface not found\n"); 157*c9d75b3cSYann Gautier panic(); 158*c9d75b3cSYann Gautier break; 159*c9d75b3cSYann Gautier } 160*c9d75b3cSYann Gautier 161*c9d75b3cSYann Gautier if (boot_context->boot_interface_instance != 0U) { 162*c9d75b3cSYann Gautier INFO(" Instance %d\n", boot_context->boot_interface_instance); 163*c9d75b3cSYann Gautier } 164*c9d75b3cSYann Gautier } 165*c9d75b3cSYann Gautier 166*c9d75b3cSYann Gautier void stm32mp1_io_setup(void) 167*c9d75b3cSYann Gautier { 168*c9d75b3cSYann Gautier int io_result __unused; 169*c9d75b3cSYann Gautier uint8_t idx; 170*c9d75b3cSYann Gautier struct stm32image_part_info *part; 171*c9d75b3cSYann Gautier struct stm32_sdmmc2_params params; 172*c9d75b3cSYann Gautier struct mmc_device_info device_info; 173*c9d75b3cSYann Gautier uintptr_t mmc_default_instance; 174*c9d75b3cSYann Gautier const partition_entry_t *entry; 175*c9d75b3cSYann Gautier boot_api_context_t *boot_context = 176*c9d75b3cSYann Gautier (boot_api_context_t *)stm32mp1_get_boot_ctx_address(); 177*c9d75b3cSYann Gautier 178*c9d75b3cSYann Gautier print_boot_device(boot_context); 179*c9d75b3cSYann Gautier 180*c9d75b3cSYann Gautier if ((boot_context->boot_partition_used_toboot == 1U) || 181*c9d75b3cSYann Gautier (boot_context->boot_partition_used_toboot == 2U)) { 182*c9d75b3cSYann Gautier INFO("Boot used partition fsbl%d\n", 183*c9d75b3cSYann Gautier boot_context->boot_partition_used_toboot); 184*c9d75b3cSYann Gautier } 185*c9d75b3cSYann Gautier 186*c9d75b3cSYann Gautier io_result = register_io_dev_dummy(&dummy_dev_con); 187*c9d75b3cSYann Gautier assert(io_result == 0); 188*c9d75b3cSYann Gautier 189*c9d75b3cSYann Gautier io_result = io_dev_open(dummy_dev_con, dummy_dev_spec, 190*c9d75b3cSYann Gautier &dummy_dev_handle); 191*c9d75b3cSYann Gautier assert(io_result == 0); 192*c9d75b3cSYann Gautier 193*c9d75b3cSYann Gautier switch (boot_context->boot_interface_selected) { 194*c9d75b3cSYann Gautier case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_SD: 195*c9d75b3cSYann Gautier case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_EMMC: 196*c9d75b3cSYann Gautier dmbsy(); 197*c9d75b3cSYann Gautier 198*c9d75b3cSYann Gautier memset(¶ms, 0, sizeof(struct stm32_sdmmc2_params)); 199*c9d75b3cSYann Gautier 200*c9d75b3cSYann Gautier if (boot_context->boot_interface_selected == 201*c9d75b3cSYann Gautier BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_EMMC) { 202*c9d75b3cSYann Gautier device_info.mmc_dev_type = MMC_IS_EMMC; 203*c9d75b3cSYann Gautier mmc_default_instance = STM32MP1_SDMMC2_BASE; 204*c9d75b3cSYann Gautier } else { 205*c9d75b3cSYann Gautier device_info.mmc_dev_type = MMC_IS_SD; 206*c9d75b3cSYann Gautier mmc_default_instance = STM32MP1_SDMMC1_BASE; 207*c9d75b3cSYann Gautier } 208*c9d75b3cSYann Gautier 209*c9d75b3cSYann Gautier switch (boot_context->boot_interface_instance) { 210*c9d75b3cSYann Gautier case 1: 211*c9d75b3cSYann Gautier params.reg_base = STM32MP1_SDMMC1_BASE; 212*c9d75b3cSYann Gautier break; 213*c9d75b3cSYann Gautier case 2: 214*c9d75b3cSYann Gautier params.reg_base = STM32MP1_SDMMC2_BASE; 215*c9d75b3cSYann Gautier break; 216*c9d75b3cSYann Gautier case 3: 217*c9d75b3cSYann Gautier params.reg_base = STM32MP1_SDMMC3_BASE; 218*c9d75b3cSYann Gautier break; 219*c9d75b3cSYann Gautier default: 220*c9d75b3cSYann Gautier WARN("SDMMC instance not found, using default\n"); 221*c9d75b3cSYann Gautier params.reg_base = mmc_default_instance; 222*c9d75b3cSYann Gautier break; 223*c9d75b3cSYann Gautier } 224*c9d75b3cSYann Gautier 225*c9d75b3cSYann Gautier params.device_info = &device_info; 226*c9d75b3cSYann Gautier if (stm32_sdmmc2_mmc_init(¶ms) != 0) { 227*c9d75b3cSYann Gautier ERROR("SDMMC%u init failed\n", 228*c9d75b3cSYann Gautier boot_context->boot_interface_instance); 229*c9d75b3cSYann Gautier panic(); 230*c9d75b3cSYann Gautier } 231*c9d75b3cSYann Gautier 232*c9d75b3cSYann Gautier /* Open MMC as a block device to read GPT table */ 233*c9d75b3cSYann Gautier io_result = register_io_dev_block(&mmc_dev_con); 234*c9d75b3cSYann Gautier if (io_result != 0) { 235*c9d75b3cSYann Gautier panic(); 236*c9d75b3cSYann Gautier } 237*c9d75b3cSYann Gautier 238*c9d75b3cSYann Gautier io_result = io_dev_open(mmc_dev_con, 239*c9d75b3cSYann Gautier (uintptr_t)&mmc_block_dev_spec, 240*c9d75b3cSYann Gautier &storage_dev_handle); 241*c9d75b3cSYann Gautier assert(io_result == 0); 242*c9d75b3cSYann Gautier 243*c9d75b3cSYann Gautier partition_init(GPT_IMAGE_ID); 244*c9d75b3cSYann Gautier 245*c9d75b3cSYann Gautier io_result = io_dev_close(storage_dev_handle); 246*c9d75b3cSYann Gautier assert(io_result == 0); 247*c9d75b3cSYann Gautier 248*c9d75b3cSYann Gautier stm32image_dev_info_spec.device_size = 249*c9d75b3cSYann Gautier stm32_sdmmc2_mmc_get_device_size(); 250*c9d75b3cSYann Gautier 251*c9d75b3cSYann Gautier for (idx = 0U; idx < IMG_IDX_NUM; idx++) { 252*c9d75b3cSYann Gautier part = &stm32image_dev_info_spec.part_info[idx]; 253*c9d75b3cSYann Gautier entry = get_partition_entry(part->name); 254*c9d75b3cSYann Gautier if (entry == NULL) { 255*c9d75b3cSYann Gautier ERROR("Partition %s not found\n", 256*c9d75b3cSYann Gautier part->name); 257*c9d75b3cSYann Gautier panic(); 258*c9d75b3cSYann Gautier } 259*c9d75b3cSYann Gautier 260*c9d75b3cSYann Gautier part->part_offset = entry->start; 261*c9d75b3cSYann Gautier part->bkp_offset = 0U; 262*c9d75b3cSYann Gautier } 263*c9d75b3cSYann Gautier 264*c9d75b3cSYann Gautier /* 265*c9d75b3cSYann Gautier * Re-open MMC with io_mmc, for better perfs compared to 266*c9d75b3cSYann Gautier * io_block. 267*c9d75b3cSYann Gautier */ 268*c9d75b3cSYann Gautier io_result = register_io_dev_mmc(&mmc_dev_con); 269*c9d75b3cSYann Gautier assert(io_result == 0); 270*c9d75b3cSYann Gautier 271*c9d75b3cSYann Gautier io_result = io_dev_open(mmc_dev_con, 0, &storage_dev_handle); 272*c9d75b3cSYann Gautier assert(io_result == 0); 273*c9d75b3cSYann Gautier 274*c9d75b3cSYann Gautier io_result = register_io_dev_stm32image(&stm32image_dev_con); 275*c9d75b3cSYann Gautier assert(io_result == 0); 276*c9d75b3cSYann Gautier 277*c9d75b3cSYann Gautier io_result = io_dev_open(stm32image_dev_con, 278*c9d75b3cSYann Gautier (uintptr_t)&stm32image_dev_info_spec, 279*c9d75b3cSYann Gautier &image_dev_handle); 280*c9d75b3cSYann Gautier assert(io_result == 0); 281*c9d75b3cSYann Gautier break; 282*c9d75b3cSYann Gautier 283*c9d75b3cSYann Gautier default: 284*c9d75b3cSYann Gautier ERROR("Boot interface %d not supported\n", 285*c9d75b3cSYann Gautier boot_context->boot_interface_selected); 286*c9d75b3cSYann Gautier break; 287*c9d75b3cSYann Gautier } 288*c9d75b3cSYann Gautier } 289*c9d75b3cSYann Gautier 290*c9d75b3cSYann Gautier /* 291*c9d75b3cSYann Gautier * Return an IO device handle and specification which can be used to access 292*c9d75b3cSYann Gautier * an image. Use this to enforce platform load policy. 293*c9d75b3cSYann Gautier */ 294*c9d75b3cSYann Gautier int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle, 295*c9d75b3cSYann Gautier uintptr_t *image_spec) 296*c9d75b3cSYann Gautier { 297*c9d75b3cSYann Gautier int rc; 298*c9d75b3cSYann Gautier const struct plat_io_policy *policy; 299*c9d75b3cSYann Gautier 300*c9d75b3cSYann Gautier assert(image_id < ARRAY_SIZE(policies)); 301*c9d75b3cSYann Gautier 302*c9d75b3cSYann Gautier policy = &policies[image_id]; 303*c9d75b3cSYann Gautier rc = policy->check(policy->image_spec); 304*c9d75b3cSYann Gautier if (rc == 0) { 305*c9d75b3cSYann Gautier *image_spec = policy->image_spec; 306*c9d75b3cSYann Gautier *dev_handle = *(policy->dev_handle); 307*c9d75b3cSYann Gautier } 308*c9d75b3cSYann Gautier 309*c9d75b3cSYann Gautier return rc; 310*c9d75b3cSYann Gautier } 311