arm-trusted-firmware/plat/st/stm32mp1/bl2_io_storage.c
Antonio Nino Diaz 09d40e0e08 Sanitise includes across codebase
Enforce full include path for includes. Deprecate old paths.

The following folders inside include/lib have been left unchanged:

- include/lib/cpus/${ARCH}
- include/lib/el3_runtime/${ARCH}

The reason for this change is that having a global namespace for
includes isn't a good idea. It defeats one of the advantages of having
folders and it introduces problems that are sometimes subtle (because
you may not know the header you are actually including if there are two
of them).

For example, this patch had to be created because two headers were
called the same way: e0ea0928d5 ("Fix gpio includes of mt8173 platform
to avoid collision."). More recently, this patch has had similar
problems: 46f9b2c3a2 ("drivers: add tzc380 support").

This problem was introduced in commit 4ecca33988 ("Move include and
source files to logical locations"). At that time, there weren't too
many headers so it wasn't a real issue. However, time has shown that
this creates problems.

Platforms that want to preserve the way they include headers may add the
removed paths to PLAT_INCLUDES, but this is discouraged.

Change-Id: I39dc53ed98f9e297a5966e723d1936d6ccf2fc8f
Signed-off-by: Antonio Nino Diaz <antonio.ninodiaz@arm.com>
2019-01-04 10:43:17 +00:00

368 lines
8.7 KiB
C

/*
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <assert.h>
#include <string.h>
#include <platform_def.h>
#include <arch_helpers.h>
#include <common/debug.h>
#include <drivers/io/io_block.h>
#include <drivers/io/io_driver.h>
#include <drivers/io/io_dummy.h>
#include <drivers/io/io_storage.h>
#include <drivers/mmc.h>
#include <drivers/partition/partition.h>
#include <drivers/st/io_mmc.h>
#include <drivers/st/io_stm32image.h>
#include <drivers/st/stm32_sdmmc2.h>
#include <drivers/st/stm32mp1_rcc.h>
#include <lib/mmio.h>
#include <lib/utils.h>
#include <plat/common/platform.h>
#include <boot_api.h>
#include <stm32mp1_private.h>
/* IO devices */
static const io_dev_connector_t *dummy_dev_con;
static uintptr_t dummy_dev_handle;
static uintptr_t dummy_dev_spec;
static uintptr_t image_dev_handle;
static io_block_spec_t gpt_block_spec = {
.offset = 0,
.length = 34 * MMC_BLOCK_SIZE, /* Size of GPT table */
};
static uint32_t block_buffer[MMC_BLOCK_SIZE] __aligned(MMC_BLOCK_SIZE);
static const io_block_dev_spec_t mmc_block_dev_spec = {
/* It's used as temp buffer in block driver */
.buffer = {
.offset = (size_t)&block_buffer,
.length = MMC_BLOCK_SIZE,
},
.ops = {
.read = mmc_read_blocks,
.write = NULL,
},
.block_size = MMC_BLOCK_SIZE,
};
static uintptr_t storage_dev_handle;
static const io_dev_connector_t *mmc_dev_con;
#define IMG_IDX_BL33 0
static const struct stm32image_part_info bl33_partition_spec = {
.name = BL33_IMAGE_NAME,
.binary_type = BL33_BINARY_TYPE,
};
static struct stm32image_device_info stm32image_dev_info_spec = {
.lba_size = MMC_BLOCK_SIZE,
.part_info[IMG_IDX_BL33] = {
.name = BL33_IMAGE_NAME,
.binary_type = BL33_BINARY_TYPE,
},
};
static io_block_spec_t stm32image_block_spec;
static const io_dev_connector_t *stm32image_dev_con;
static const io_block_spec_t bl32_block_spec = {
.offset = BL32_BASE,
.length = STM32MP1_BL32_SIZE
};
static const io_block_spec_t bl2_block_spec = {
.offset = BL2_BASE,
.length = STM32MP1_BL2_SIZE,
};
static int open_dummy(const uintptr_t spec);
static int open_image(const uintptr_t spec);
static int open_storage(const uintptr_t spec);
struct plat_io_policy {
uintptr_t *dev_handle;
uintptr_t image_spec;
int (*check)(const uintptr_t spec);
};
static const struct plat_io_policy policies[] = {
[BL2_IMAGE_ID] = {
.dev_handle = &dummy_dev_handle,
.image_spec = (uintptr_t)&bl2_block_spec,
.check = open_dummy
},
[BL32_IMAGE_ID] = {
.dev_handle = &dummy_dev_handle,
.image_spec = (uintptr_t)&bl32_block_spec,
.check = open_dummy
},
[BL33_IMAGE_ID] = {
.dev_handle = &image_dev_handle,
.image_spec = (uintptr_t)&bl33_partition_spec,
.check = open_image
},
[GPT_IMAGE_ID] = {
.dev_handle = &storage_dev_handle,
.image_spec = (uintptr_t)&gpt_block_spec,
.check = open_storage
},
[STM32_IMAGE_ID] = {
.dev_handle = &storage_dev_handle,
.image_spec = (uintptr_t)&stm32image_block_spec,
.check = open_storage
}
};
static int open_dummy(const uintptr_t spec)
{
return io_dev_init(dummy_dev_handle, 0);
}
static int open_image(const uintptr_t spec)
{
return io_dev_init(image_dev_handle, 0);
}
static int open_storage(const uintptr_t spec)
{
return io_dev_init(storage_dev_handle, 0);
}
static void print_boot_device(boot_api_context_t *boot_context)
{
switch (boot_context->boot_interface_selected) {
case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_SD:
INFO("Using SDMMC\n");
break;
case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_EMMC:
INFO("Using EMMC\n");
break;
default:
ERROR("Boot interface not found\n");
panic();
break;
}
if (boot_context->boot_interface_instance != 0U) {
INFO(" Instance %d\n", boot_context->boot_interface_instance);
}
}
static void print_reset_reason(void)
{
uint32_t rstsr = mmio_read_32(RCC_BASE + RCC_MP_RSTSCLRR);
if (rstsr == 0U) {
WARN("Reset reason unknown\n");
return;
}
INFO("Reset reason (0x%x):\n", rstsr);
if ((rstsr & RCC_MP_RSTSCLRR_PADRSTF) == 0U) {
if ((rstsr & RCC_MP_RSTSCLRR_STDBYRSTF) != 0U) {
INFO("System exits from STANDBY\n");
return;
}
if ((rstsr & RCC_MP_RSTSCLRR_CSTDBYRSTF) != 0U) {
INFO("MPU exits from CSTANDBY\n");
return;
}
}
if ((rstsr & RCC_MP_RSTSCLRR_PORRSTF) != 0U) {
INFO(" Power-on Reset (rst_por)\n");
return;
}
if ((rstsr & RCC_MP_RSTSCLRR_BORRSTF) != 0U) {
INFO(" Brownout Reset (rst_bor)\n");
return;
}
if ((rstsr & RCC_MP_RSTSCLRR_MPSYSRSTF) != 0U) {
INFO(" System reset generated by MPU (MPSYSRST)\n");
return;
}
if ((rstsr & RCC_MP_RSTSCLRR_HCSSRSTF) != 0U) {
INFO(" Reset due to a clock failure on HSE\n");
return;
}
if ((rstsr & RCC_MP_RSTSCLRR_IWDG1RSTF) != 0U) {
INFO(" IWDG1 Reset (rst_iwdg1)\n");
return;
}
if ((rstsr & RCC_MP_RSTSCLRR_IWDG2RSTF) != 0U) {
INFO(" IWDG2 Reset (rst_iwdg2)\n");
return;
}
if ((rstsr & RCC_MP_RSTSCLRR_PADRSTF) != 0U) {
INFO(" Pad Reset from NRST\n");
return;
}
if ((rstsr & RCC_MP_RSTSCLRR_VCORERSTF) != 0U) {
INFO(" Reset due to a failure of VDD_CORE\n");
return;
}
ERROR(" Unidentified reset reason\n");
}
void stm32mp1_io_setup(void)
{
int io_result __unused;
struct stm32_sdmmc2_params params;
struct mmc_device_info device_info;
uintptr_t mmc_default_instance;
boot_api_context_t *boot_context =
(boot_api_context_t *)stm32mp1_get_boot_ctx_address();
print_reset_reason();
print_boot_device(boot_context);
if ((boot_context->boot_partition_used_toboot == 1U) ||
(boot_context->boot_partition_used_toboot == 2U)) {
INFO("Boot used partition fsbl%d\n",
boot_context->boot_partition_used_toboot);
}
io_result = register_io_dev_dummy(&dummy_dev_con);
assert(io_result == 0);
io_result = io_dev_open(dummy_dev_con, dummy_dev_spec,
&dummy_dev_handle);
assert(io_result == 0);
switch (boot_context->boot_interface_selected) {
case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_SD:
case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_EMMC:
dmb();
memset(&params, 0, sizeof(struct stm32_sdmmc2_params));
if (boot_context->boot_interface_selected ==
BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_EMMC) {
device_info.mmc_dev_type = MMC_IS_EMMC;
mmc_default_instance = STM32MP1_SDMMC2_BASE;
} else {
device_info.mmc_dev_type = MMC_IS_SD;
mmc_default_instance = STM32MP1_SDMMC1_BASE;
}
switch (boot_context->boot_interface_instance) {
case 1:
params.reg_base = STM32MP1_SDMMC1_BASE;
break;
case 2:
params.reg_base = STM32MP1_SDMMC2_BASE;
break;
case 3:
params.reg_base = STM32MP1_SDMMC3_BASE;
break;
default:
WARN("SDMMC instance not found, using default\n");
params.reg_base = mmc_default_instance;
break;
}
params.device_info = &device_info;
if (stm32_sdmmc2_mmc_init(&params) != 0) {
ERROR("SDMMC%u init failed\n",
boot_context->boot_interface_instance);
panic();
}
/* Open MMC as a block device to read GPT table */
io_result = register_io_dev_block(&mmc_dev_con);
if (io_result != 0) {
panic();
}
io_result = io_dev_open(mmc_dev_con,
(uintptr_t)&mmc_block_dev_spec,
&storage_dev_handle);
assert(io_result == 0);
partition_init(GPT_IMAGE_ID);
io_result = io_dev_close(storage_dev_handle);
assert(io_result == 0);
stm32image_dev_info_spec.device_size =
stm32_sdmmc2_mmc_get_device_size();
stm32image_dev_info_spec.part_info[IMG_IDX_BL33].part_offset =
get_partition_entry(BL33_IMAGE_NAME)->start;
stm32image_dev_info_spec.part_info[IMG_IDX_BL33].bkp_offset =
get_partition_entry(BL33_IMAGE_NAME)->length;
stm32image_block_spec.offset = 0;
stm32image_block_spec.length =
get_partition_entry(BL33_IMAGE_NAME)->length;
/*
* Re-open MMC with io_mmc, for better perfs compared to
* io_block.
*/
io_result = register_io_dev_mmc(&mmc_dev_con);
assert(io_result == 0);
io_result = io_dev_open(mmc_dev_con, 0, &storage_dev_handle);
assert(io_result == 0);
io_result = register_io_dev_stm32image(&stm32image_dev_con);
assert(io_result == 0);
io_result = io_dev_open(stm32image_dev_con,
(uintptr_t)&stm32image_dev_info_spec,
&image_dev_handle);
assert(io_result == 0);
break;
default:
ERROR("Boot interface %d not supported\n",
boot_context->boot_interface_selected);
break;
}
}
/*
* Return an IO device handle and specification which can be used to access
* an image. Use this to enforce platform load policy.
*/
int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
uintptr_t *image_spec)
{
int rc;
const struct plat_io_policy *policy;
assert(image_id < ARRAY_SIZE(policies));
policy = &policies[image_id];
rc = policy->check(policy->image_spec);
if (rc == 0) {
*image_spec = policy->image_spec;
*dev_handle = *(policy->dev_handle);
}
return rc;
}