Browse Source
The code managing legacy boot (without FIP) that was under STM32MP_USE_STM32IMAGE flag is remove. Change-Id: I04452453ed84567b0de39e900594a81526562259 Signed-off-by: Yann Gautier <yann.gautier@st.com>pull/1989/head
Yann Gautier
2 years ago
23 changed files with 10 additions and 1674 deletions
@ -1,366 +0,0 @@ |
|||
/*
|
|||
* Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved. |
|||
* |
|||
* SPDX-License-Identifier: BSD-3-Clause |
|||
*/ |
|||
|
|||
#include <assert.h> |
|||
#include <errno.h> |
|||
#include <stdint.h> |
|||
#include <string.h> |
|||
|
|||
#include <platform_def.h> |
|||
|
|||
#include <common/debug.h> |
|||
#include <drivers/io/io_driver.h> |
|||
#include <drivers/io/io_storage.h> |
|||
#include <drivers/st/io_stm32image.h> |
|||
#include <lib/utils.h> |
|||
#include <plat/common/platform.h> |
|||
|
|||
static uintptr_t backend_dev_handle; |
|||
static uintptr_t backend_image_spec; |
|||
static uint32_t *stm32_img; |
|||
static uint8_t first_lba_buffer[MAX_LBA_SIZE] __aligned(4); |
|||
static struct stm32image_part_info *current_part; |
|||
|
|||
/* STM32 Image driver functions */ |
|||
static int stm32image_dev_open(const uintptr_t init_params, |
|||
io_dev_info_t **dev_info); |
|||
static int stm32image_partition_open(io_dev_info_t *dev_info, |
|||
const uintptr_t spec, io_entity_t *entity); |
|||
static int stm32image_partition_size(io_entity_t *entity, size_t *length); |
|||
static int stm32image_partition_read(io_entity_t *entity, uintptr_t buffer, |
|||
size_t length, size_t *length_read); |
|||
static int stm32image_partition_close(io_entity_t *entity); |
|||
static int stm32image_dev_init(io_dev_info_t *dev_info, |
|||
const uintptr_t init_params); |
|||
static int stm32image_dev_close(io_dev_info_t *dev_info); |
|||
|
|||
/* Identify the device type as a virtual driver */ |
|||
static io_type_t device_type_stm32image(void) |
|||
{ |
|||
return IO_TYPE_STM32IMAGE; |
|||
} |
|||
|
|||
static const io_dev_connector_t stm32image_dev_connector = { |
|||
.dev_open = stm32image_dev_open |
|||
}; |
|||
|
|||
static const io_dev_funcs_t stm32image_dev_funcs = { |
|||
.type = device_type_stm32image, |
|||
.open = stm32image_partition_open, |
|||
.size = stm32image_partition_size, |
|||
.read = stm32image_partition_read, |
|||
.close = stm32image_partition_close, |
|||
.dev_init = stm32image_dev_init, |
|||
.dev_close = stm32image_dev_close, |
|||
}; |
|||
|
|||
static io_dev_info_t stm32image_dev_info = { |
|||
.funcs = &stm32image_dev_funcs, |
|||
.info = (uintptr_t)0, |
|||
}; |
|||
|
|||
static struct stm32image_device_info stm32image_dev; |
|||
|
|||
static int get_part_idx_by_binary_type(uint32_t binary_type) |
|||
{ |
|||
int i; |
|||
|
|||
for (i = 0; i < STM32_PART_NUM; i++) { |
|||
if (stm32image_dev.part_info[i].binary_type == binary_type) { |
|||
return i; |
|||
} |
|||
} |
|||
|
|||
return -EINVAL; |
|||
} |
|||
|
|||
/* Open a connection to the STM32IMAGE device */ |
|||
static int stm32image_dev_open(const uintptr_t init_params, |
|||
io_dev_info_t **dev_info) |
|||
{ |
|||
int i; |
|||
struct stm32image_device_info *device_info = |
|||
(struct stm32image_device_info *)init_params; |
|||
|
|||
assert(dev_info != NULL); |
|||
*dev_info = (io_dev_info_t *)&stm32image_dev_info; |
|||
|
|||
stm32image_dev.device_size = device_info->device_size; |
|||
stm32image_dev.lba_size = device_info->lba_size; |
|||
|
|||
for (i = 0; i < STM32_PART_NUM; i++) { |
|||
memcpy(stm32image_dev.part_info[i].name, |
|||
device_info->part_info[i].name, MAX_PART_NAME_SIZE); |
|||
stm32image_dev.part_info[i].binary_type = |
|||
device_info->part_info[i].binary_type; |
|||
stm32image_dev.part_info[i].part_offset = |
|||
device_info->part_info[i].part_offset; |
|||
stm32image_dev.part_info[i].bkp_offset = |
|||
device_info->part_info[i].bkp_offset; |
|||
} |
|||
|
|||
return 0; |
|||
} |
|||
|
|||
/* Do some basic package checks */ |
|||
static int stm32image_dev_init(io_dev_info_t *dev_info, |
|||
const uintptr_t init_params) |
|||
{ |
|||
int result; |
|||
|
|||
if ((backend_dev_handle != 0U) || (backend_image_spec != 0U)) { |
|||
ERROR("STM32 Image io supports only one session\n"); |
|||
return -ENOMEM; |
|||
} |
|||
|
|||
/* Obtain a reference to the image by querying the platform layer */ |
|||
result = plat_get_image_source(STM32_IMAGE_ID, &backend_dev_handle, |
|||
&backend_image_spec); |
|||
if (result != 0) { |
|||
ERROR("STM32 image error (%i)\n", result); |
|||
return -EINVAL; |
|||
} |
|||
|
|||
return result; |
|||
} |
|||
|
|||
/* Close a connection to the STM32 Image device */ |
|||
static int stm32image_dev_close(io_dev_info_t *dev_info) |
|||
{ |
|||
backend_dev_handle = 0U; |
|||
backend_image_spec = 0U; |
|||
stm32_img = NULL; |
|||
|
|||
return 0; |
|||
} |
|||
|
|||
/* Open a partition */ |
|||
static int stm32image_partition_open(io_dev_info_t *dev_info, |
|||
const uintptr_t spec, io_entity_t *entity) |
|||
{ |
|||
const struct stm32image_part_info *partition_spec; |
|||
int idx; |
|||
|
|||
assert(entity != NULL); |
|||
|
|||
partition_spec = (struct stm32image_part_info *)spec; |
|||
assert(partition_spec != NULL); |
|||
|
|||
idx = get_part_idx_by_binary_type(partition_spec->binary_type); |
|||
if ((idx < 0) || (idx > STM32_PART_NUM)) { |
|||
ERROR("Wrong partition index (%d)\n", idx); |
|||
return -EINVAL; |
|||
} |
|||
|
|||
current_part = &stm32image_dev.part_info[idx]; |
|||
stm32_img = (uint32_t *)¤t_part->part_offset; |
|||
|
|||
return 0; |
|||
} |
|||
|
|||
/* Return the size of a partition */ |
|||
static int stm32image_partition_size(io_entity_t *entity, size_t *length) |
|||
{ |
|||
int result; |
|||
uintptr_t backend_handle; |
|||
size_t bytes_read; |
|||
boot_api_image_header_t *header = |
|||
(boot_api_image_header_t *)first_lba_buffer; |
|||
|
|||
assert(entity != NULL); |
|||
assert(length != NULL); |
|||
|
|||
/* Attempt to access the image */ |
|||
result = io_open(backend_dev_handle, backend_image_spec, |
|||
&backend_handle); |
|||
|
|||
if (result < 0) { |
|||
ERROR("%s: io_open (%i)\n", __func__, result); |
|||
return result; |
|||
} |
|||
|
|||
/* Reset magic header value */ |
|||
header->magic = 0; |
|||
|
|||
while (header->magic == 0U) { |
|||
result = io_seek(backend_handle, IO_SEEK_SET, *stm32_img); |
|||
if (result != 0) { |
|||
ERROR("%s: io_seek (%i)\n", __func__, result); |
|||
break; |
|||
} |
|||
|
|||
result = io_read(backend_handle, (uintptr_t)header, |
|||
MAX_LBA_SIZE, (size_t *)&bytes_read); |
|||
if (result != 0) { |
|||
if (current_part->bkp_offset == 0U) { |
|||
ERROR("%s: io_read (%i)\n", __func__, result); |
|||
} |
|||
header->magic = 0; |
|||
} |
|||
|
|||
if ((header->magic != BOOT_API_IMAGE_HEADER_MAGIC_NB) || |
|||
(header->binary_type != current_part->binary_type) || |
|||
(header->image_length >= stm32image_dev.device_size)) { |
|||
VERBOSE("%s: partition %s not found at %x\n", |
|||
__func__, current_part->name, *stm32_img); |
|||
|
|||
if (current_part->bkp_offset == 0U) { |
|||
result = -ENOMEM; |
|||
break; |
|||
} |
|||
|
|||
/* Header not correct, check next offset for backup */ |
|||
*stm32_img += current_part->bkp_offset; |
|||
if (*stm32_img > stm32image_dev.device_size) { |
|||
/* No backup found, end of device reached */ |
|||
WARN("%s : partition %s not found\n", |
|||
__func__, current_part->name); |
|||
result = -ENOMEM; |
|||
break; |
|||
} |
|||
header->magic = 0; |
|||
} |
|||
} |
|||
|
|||
io_close(backend_handle); |
|||
|
|||
if (result != 0) { |
|||
return result; |
|||
} |
|||
|
|||
if (header->image_length < stm32image_dev.lba_size) { |
|||
*length = stm32image_dev.lba_size; |
|||
} else { |
|||
*length = header->image_length; |
|||
} |
|||
|
|||
INFO("STM32 Image size : %lu\n", (unsigned long)*length); |
|||
|
|||
return 0; |
|||
} |
|||
|
|||
/* Read data from a partition */ |
|||
static int stm32image_partition_read(io_entity_t *entity, uintptr_t buffer, |
|||
size_t length, size_t *length_read) |
|||
{ |
|||
int result = -EINVAL; |
|||
uint8_t *local_buffer; |
|||
boot_api_image_header_t *header = |
|||
(boot_api_image_header_t *)first_lba_buffer; |
|||
size_t hdr_sz = sizeof(boot_api_image_header_t); |
|||
|
|||
assert(entity != NULL); |
|||
assert(buffer != 0U); |
|||
assert(length_read != NULL); |
|||
|
|||
local_buffer = (uint8_t *)buffer; |
|||
*length_read = 0U; |
|||
|
|||
while (*length_read == 0U) { |
|||
int offset; |
|||
int local_length; |
|||
uintptr_t backend_handle; |
|||
|
|||
if (header->magic != BOOT_API_IMAGE_HEADER_MAGIC_NB) { |
|||
/* Check for backup as image is corrupted */ |
|||
if (current_part->bkp_offset == 0U) { |
|||
result = -ENOMEM; |
|||
break; |
|||
} |
|||
|
|||
*stm32_img += current_part->bkp_offset; |
|||
if (*stm32_img >= stm32image_dev.device_size) { |
|||
/* End of device reached */ |
|||
result = -ENOMEM; |
|||
break; |
|||
} |
|||
|
|||
local_buffer = (uint8_t *)buffer; |
|||
|
|||
result = stm32image_partition_size(entity, &length); |
|||
if (result != 0) { |
|||
break; |
|||
} |
|||
} |
|||
|
|||
/* Part of image already loaded with the header */ |
|||
memcpy(local_buffer, (uint8_t *)first_lba_buffer + hdr_sz, |
|||
MAX_LBA_SIZE - hdr_sz); |
|||
local_buffer += MAX_LBA_SIZE - hdr_sz; |
|||
offset = MAX_LBA_SIZE; |
|||
|
|||
/* New image length to be read */ |
|||
local_length = round_up(length - ((MAX_LBA_SIZE) - hdr_sz), |
|||
stm32image_dev.lba_size); |
|||
|
|||
if ((header->load_address != 0U) && |
|||
(header->load_address != buffer)) { |
|||
ERROR("Wrong load address\n"); |
|||
panic(); |
|||
} |
|||
|
|||
result = io_open(backend_dev_handle, backend_image_spec, |
|||
&backend_handle); |
|||
|
|||
if (result != 0) { |
|||
ERROR("%s: io_open (%i)\n", __func__, result); |
|||
break; |
|||
} |
|||
|
|||
result = io_seek(backend_handle, IO_SEEK_SET, |
|||
*stm32_img + offset); |
|||
|
|||
if (result != 0) { |
|||
ERROR("%s: io_seek (%i)\n", __func__, result); |
|||
*length_read = 0; |
|||
io_close(backend_handle); |
|||
break; |
|||
} |
|||
|
|||
result = io_read(backend_handle, (uintptr_t)local_buffer, |
|||
local_length, length_read); |
|||
|
|||
/* Adding part of size already read from header */ |
|||
*length_read += MAX_LBA_SIZE - hdr_sz; |
|||
|
|||
if (result != 0) { |
|||
ERROR("%s: io_read (%i)\n", __func__, result); |
|||
*length_read = 0; |
|||
header->magic = 0; |
|||
continue; |
|||
} |
|||
|
|||
inv_dcache_range(round_up((uintptr_t)(local_buffer + length - hdr_sz), |
|||
CACHE_WRITEBACK_GRANULE), *length_read - length + hdr_sz); |
|||
|
|||
io_close(backend_handle); |
|||
} |
|||
|
|||
return result; |
|||
} |
|||
|
|||
/* Close a partition */ |
|||
static int stm32image_partition_close(io_entity_t *entity) |
|||
{ |
|||
current_part = NULL; |
|||
|
|||
return 0; |
|||
} |
|||
|
|||
/* Register the stm32image driver with the IO abstraction */ |
|||
int register_io_dev_stm32image(const io_dev_connector_t **dev_con) |
|||
{ |
|||
int result; |
|||
|
|||
assert(dev_con != NULL); |
|||
|
|||
result = io_register_device(&stm32image_dev_info); |
|||
if (result == 0) { |
|||
*dev_con = &stm32image_dev_connector; |
|||
} |
|||
|
|||
return result; |
|||
} |
@ -1,32 +0,0 @@ |
|||
/*
|
|||
* Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. |
|||
* |
|||
* SPDX-License-Identifier: BSD-3-Clause |
|||
*/ |
|||
|
|||
#ifndef IO_STM32IMAGE_H |
|||
#define IO_STM32IMAGE_H |
|||
|
|||
#include <drivers/io/io_driver.h> |
|||
#include <drivers/partition/partition.h> |
|||
|
|||
#define MAX_LBA_SIZE 512 |
|||
#define MAX_PART_NAME_SIZE (EFI_NAMELEN + 1) |
|||
#define STM32_PART_NUM (PLAT_PARTITION_MAX_ENTRIES - STM32_TF_A_COPIES) |
|||
|
|||
struct stm32image_part_info { |
|||
char name[MAX_PART_NAME_SIZE]; |
|||
uint32_t binary_type; |
|||
uintptr_t part_offset; |
|||
uint32_t bkp_offset; |
|||
}; |
|||
|
|||
struct stm32image_device_info { |
|||
struct stm32image_part_info part_info[STM32_PART_NUM]; |
|||
unsigned long long device_size; |
|||
uint32_t lba_size; |
|||
}; |
|||
|
|||
int register_io_dev_stm32image(const io_dev_connector_t **dev_con); |
|||
|
|||
#endif /* IO_STM32IMAGE_H */ |
@ -1,667 +0,0 @@ |
|||
/*
|
|||
* Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved. |
|||
* |
|||
* SPDX-License-Identifier: BSD-3-Clause |
|||
*/ |
|||
|
|||
#include <assert.h> |
|||
#include <string.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_mtd.h> |
|||
#include <drivers/io/io_storage.h> |
|||
#include <drivers/mmc.h> |
|||
#include <drivers/partition/partition.h> |
|||
#include <drivers/raw_nand.h> |
|||
#include <drivers/spi_nand.h> |
|||
#include <drivers/spi_nor.h> |
|||
#include <drivers/st/io_mmc.h> |
|||
#include <drivers/st/io_stm32image.h> |
|||
#include <drivers/st/stm32_fmc2_nand.h> |
|||
#include <drivers/st/stm32_qspi.h> |
|||
#include <drivers/st/stm32_sdmmc2.h> |
|||
#include <lib/mmio.h> |
|||
#include <lib/utils.h> |
|||
#include <plat/common/platform.h> |
|||
|
|||
#include <platform_def.h> |
|||
|
|||
/* IO devices */ |
|||
#ifndef AARCH32_SP_OPTEE |
|||
static const io_dev_connector_t *dummy_dev_con; |
|||
static uintptr_t dummy_dev_handle; |
|||
static uintptr_t dummy_dev_spec; |
|||
#endif |
|||
|
|||
static uintptr_t image_dev_handle; |
|||
static uintptr_t storage_dev_handle; |
|||
|
|||
#if STM32MP_SDMMC || STM32MP_EMMC |
|||
static struct mmc_device_info mmc_info; |
|||
static io_block_spec_t gpt_block_spec = { |
|||
.offset = 0U, |
|||
.length = 34U * 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, |
|||
}; |
|||
|
|||
#if STM32MP_EMMC_BOOT |
|||
static io_block_spec_t emmc_boot_ssbl_block_spec = { |
|||
.offset = PLAT_EMMC_BOOT_SSBL_OFFSET, |
|||
.length = MMC_BLOCK_SIZE, /* We are interested only in first 4 bytes */ |
|||
}; |
|||
|
|||
static const io_block_dev_spec_t mmc_block_dev_boot_part_spec = { |
|||
/* It's used as temp buffer in block driver */ |
|||
.buffer = { |
|||
.offset = (size_t)&block_buffer, |
|||
.length = MMC_BLOCK_SIZE, |
|||
}, |
|||
.ops = { |
|||
.read = mmc_boot_part_read_blocks, |
|||
.write = NULL, |
|||
}, |
|||
.block_size = MMC_BLOCK_SIZE, |
|||
}; |
|||
#endif |
|||
|
|||
static struct io_mmc_dev_spec mmc_device_spec = { |
|||
.use_boot_part = false, |
|||
}; |
|||
|
|||
static const io_dev_connector_t *mmc_dev_con; |
|||
#endif /* STM32MP_SDMMC || STM32MP_EMMC */ |
|||
|
|||
#if STM32MP_SPI_NOR |
|||
static io_mtd_dev_spec_t spi_nor_dev_spec = { |
|||
.ops = { |
|||
.init = spi_nor_init, |
|||
.read = spi_nor_read, |
|||
}, |
|||
}; |
|||
#endif |
|||
|
|||
#if STM32MP_RAW_NAND |
|||
static io_mtd_dev_spec_t nand_dev_spec = { |
|||
.ops = { |
|||
.init = nand_raw_init, |
|||
.read = nand_read, |
|||
}, |
|||
}; |
|||
|
|||
static const io_dev_connector_t *nand_dev_con; |
|||
#endif |
|||
|
|||
#if STM32MP_SPI_NAND |
|||
static io_mtd_dev_spec_t spi_nand_dev_spec = { |
|||
.ops = { |
|||
.init = spi_nand_init, |
|||
.read = nand_read, |
|||
}, |
|||
}; |
|||
#endif |
|||
|
|||
#if STM32MP_SPI_NAND || STM32MP_SPI_NOR |
|||
static const io_dev_connector_t *spi_dev_con; |
|||
#endif |
|||
|
|||
#ifdef AARCH32_SP_OPTEE |
|||
static const struct stm32image_part_info optee_header_partition_spec = { |
|||
.name = OPTEE_HEADER_IMAGE_NAME, |
|||
.binary_type = OPTEE_HEADER_BINARY_TYPE, |
|||
}; |
|||
|
|||
static const struct stm32image_part_info optee_core_partition_spec = { |
|||
.name = OPTEE_CORE_IMAGE_NAME, |
|||
.binary_type = OPTEE_CORE_BINARY_TYPE, |
|||
}; |
|||
|
|||
static const struct stm32image_part_info optee_paged_partition_spec = { |
|||
.name = OPTEE_PAGED_IMAGE_NAME, |
|||
.binary_type = OPTEE_PAGED_BINARY_TYPE, |
|||
}; |
|||
#else |
|||
static const io_block_spec_t bl32_block_spec = { |
|||
.offset = BL32_BASE, |
|||
.length = STM32MP_BL32_SIZE |
|||
}; |
|||
#endif |
|||
|
|||
static const struct stm32image_part_info bl33_partition_spec = { |
|||
.name = BL33_IMAGE_NAME, |
|||
.binary_type = BL33_BINARY_TYPE, |
|||
}; |
|||
|
|||
enum { |
|||
IMG_IDX_BL33, |
|||
#ifdef AARCH32_SP_OPTEE |
|||
IMG_IDX_OPTEE_HEADER, |
|||
IMG_IDX_OPTEE_CORE, |
|||
IMG_IDX_OPTEE_PAGED, |
|||
#endif |
|||
IMG_IDX_NUM |
|||
}; |
|||
|
|||
static struct stm32image_device_info stm32image_dev_info_spec __unused = { |
|||
.lba_size = MMC_BLOCK_SIZE, |
|||
.part_info[IMG_IDX_BL33] = { |
|||
.name = BL33_IMAGE_NAME, |
|||
.binary_type = BL33_BINARY_TYPE, |
|||
}, |
|||
#ifdef AARCH32_SP_OPTEE |
|||
.part_info[IMG_IDX_OPTEE_HEADER] = { |
|||
.name = OPTEE_HEADER_IMAGE_NAME, |
|||
.binary_type = OPTEE_HEADER_BINARY_TYPE, |
|||
}, |
|||
.part_info[IMG_IDX_OPTEE_CORE] = { |
|||
.name = OPTEE_CORE_IMAGE_NAME, |
|||
.binary_type = OPTEE_CORE_BINARY_TYPE, |
|||
}, |
|||
.part_info[IMG_IDX_OPTEE_PAGED] = { |
|||
.name = OPTEE_PAGED_IMAGE_NAME, |
|||
.binary_type = OPTEE_PAGED_BINARY_TYPE, |
|||
}, |
|||
#endif |
|||
}; |
|||
|
|||
static io_block_spec_t stm32image_block_spec = { |
|||
.offset = 0U, |
|||
.length = 0U, |
|||
}; |
|||
|
|||
static const io_dev_connector_t *stm32image_dev_con __unused; |
|||
|
|||
#ifndef AARCH32_SP_OPTEE |
|||
static int open_dummy(const uintptr_t spec); |
|||
#endif |
|||
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[] = { |
|||
#ifdef AARCH32_SP_OPTEE |
|||
[BL32_IMAGE_ID] = { |
|||
.dev_handle = &image_dev_handle, |
|||
.image_spec = (uintptr_t)&optee_header_partition_spec, |
|||
.check = open_image |
|||
}, |
|||
[BL32_EXTRA1_IMAGE_ID] = { |
|||
.dev_handle = &image_dev_handle, |
|||
.image_spec = (uintptr_t)&optee_core_partition_spec, |
|||
.check = open_image |
|||
}, |
|||
[BL32_EXTRA2_IMAGE_ID] = { |
|||
.dev_handle = &image_dev_handle, |
|||
.image_spec = (uintptr_t)&optee_paged_partition_spec, |
|||
.check = open_image |
|||
}, |
|||
#else |
|||
[BL32_IMAGE_ID] = { |
|||
.dev_handle = &dummy_dev_handle, |
|||
.image_spec = (uintptr_t)&bl32_block_spec, |
|||
.check = open_dummy |
|||
}, |
|||
#endif |
|||
[BL33_IMAGE_ID] = { |
|||
.dev_handle = &image_dev_handle, |
|||
.image_spec = (uintptr_t)&bl33_partition_spec, |
|||
.check = open_image |
|||
}, |
|||
#if STM32MP_SDMMC || STM32MP_EMMC |
|||
[GPT_IMAGE_ID] = { |
|||
.dev_handle = &storage_dev_handle, |
|||
.image_spec = (uintptr_t)&gpt_block_spec, |
|||
.check = open_storage |
|||
}, |
|||
#endif |
|||
[STM32_IMAGE_ID] = { |
|||
.dev_handle = &storage_dev_handle, |
|||
.image_spec = (uintptr_t)&stm32image_block_spec, |
|||
.check = open_storage |
|||
} |
|||
}; |
|||
|
|||
#ifndef AARCH32_SP_OPTEE |
|||
static int open_dummy(const uintptr_t spec) |
|||
{ |
|||
return io_dev_init(dummy_dev_handle, 0); |
|||
} |
|||
#endif |
|||
|
|||
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); |
|||
} |
|||
|
|||
#if STM32MP_EMMC_BOOT |
|||
static uint32_t get_boot_part_ssbl_header(void) |
|||
{ |
|||
uint32_t magic = 0U; |
|||
int io_result; |
|||
size_t bytes_read; |
|||
|
|||
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_boot_part_spec, |
|||
&storage_dev_handle); |
|||
assert(io_result == 0); |
|||
|
|||
io_result = io_open(storage_dev_handle, (uintptr_t)&emmc_boot_ssbl_block_spec, |
|||
&image_dev_handle); |
|||
assert(io_result == 0); |
|||
|
|||
io_result = io_read(image_dev_handle, (uintptr_t)&magic, sizeof(magic), |
|||
&bytes_read); |
|||
assert(io_result == 0); |
|||
assert(bytes_read == sizeof(magic)); |
|||
|
|||
io_result = io_dev_close(storage_dev_handle); |
|||
assert(io_result == 0); |
|||
|
|||
return magic; |
|||
} |
|||
#endif |
|||
|
|||
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; |
|||
case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NOR_QSPI: |
|||
INFO("Using QSPI NOR\n"); |
|||
break; |
|||
case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_FMC: |
|||
INFO("Using FMC NAND\n"); |
|||
break; |
|||
case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_QSPI: |
|||
INFO("Using SPI NAND\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 stm32image_io_setup(void) |
|||
{ |
|||
int io_result __unused; |
|||
|
|||
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); |
|||
} |
|||
|
|||
#if STM32MP_SDMMC || STM32MP_EMMC |
|||
static void boot_mmc(enum mmc_device_type mmc_dev_type, |
|||
uint16_t boot_interface_instance) |
|||
{ |
|||
int io_result __unused; |
|||
uint8_t idx; |
|||
struct stm32image_part_info *part; |
|||
struct stm32_sdmmc2_params params; |
|||
const partition_entry_t *entry __unused; |
|||
uint32_t magic __unused; |
|||
|
|||
zeromem(¶ms, sizeof(struct stm32_sdmmc2_params)); |
|||
|
|||
mmc_info.mmc_dev_type = mmc_dev_type; |
|||
|
|||
switch (boot_interface_instance) { |
|||
case 1: |
|||
params.reg_base = STM32MP_SDMMC1_BASE; |
|||
break; |
|||
case 2: |
|||
params.reg_base = STM32MP_SDMMC2_BASE; |
|||
break; |
|||
case 3: |
|||
params.reg_base = STM32MP_SDMMC3_BASE; |
|||
break; |
|||
default: |
|||
WARN("SDMMC instance not found, using default\n"); |
|||
if (mmc_dev_type == MMC_IS_SD) { |
|||
params.reg_base = STM32MP_SDMMC1_BASE; |
|||
} else { |
|||
params.reg_base = STM32MP_SDMMC2_BASE; |
|||
} |
|||
break; |
|||
} |
|||
|
|||
params.device_info = &mmc_info; |
|||
if (stm32_sdmmc2_mmc_init(¶ms) != 0) { |
|||
ERROR("SDMMC%u init failed\n", boot_interface_instance); |
|||
panic(); |
|||
} |
|||
|
|||
stm32image_dev_info_spec.device_size = |
|||
stm32_sdmmc2_mmc_get_device_size(); |
|||
|
|||
#if STM32MP_EMMC_BOOT |
|||
if (mmc_dev_type == MMC_IS_EMMC) { |
|||
magic = get_boot_part_ssbl_header(); |
|||
|
|||
if (magic == BOOT_API_IMAGE_HEADER_MAGIC_NB) { |
|||
VERBOSE("%s, header found, jump to emmc load\n", __func__); |
|||
idx = IMG_IDX_BL33; |
|||
part = &stm32image_dev_info_spec.part_info[idx]; |
|||
part->part_offset = PLAT_EMMC_BOOT_SSBL_OFFSET; |
|||
part->bkp_offset = 0U; |
|||
mmc_device_spec.use_boot_part = true; |
|||
|
|||
goto emmc_boot; |
|||
} else { |
|||
WARN("%s: Can't find STM32 header on a boot partition\n", __func__); |
|||
} |
|||
} |
|||
#endif |
|||
|
|||
/* 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); |
|||
|
|||
for (idx = 0U; idx < IMG_IDX_NUM; idx++) { |
|||
part = &stm32image_dev_info_spec.part_info[idx]; |
|||
entry = get_partition_entry(part->name); |
|||
if (entry == NULL) { |
|||
ERROR("Partition %s not found\n", part->name); |
|||
panic(); |
|||
} |
|||
|
|||
part->part_offset = entry->start; |
|||
part->bkp_offset = 0U; |
|||
} |
|||
|
|||
#if STM32MP_EMMC_BOOT |
|||
emmc_boot: |
|||
#endif |
|||
/*
|
|||
* 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, (uintptr_t)&mmc_device_spec, |
|||
&storage_dev_handle); |
|||
assert(io_result == 0); |
|||
} |
|||
#endif /* STM32MP_SDMMC || STM32MP_EMMC */ |
|||
|
|||
#if STM32MP_SPI_NOR |
|||
static void boot_spi_nor(boot_api_context_t *boot_context) |
|||
{ |
|||
int io_result __unused; |
|||
uint8_t idx; |
|||
struct stm32image_part_info *part; |
|||
|
|||
io_result = stm32_qspi_init(); |
|||
assert(io_result == 0); |
|||
|
|||
io_result = register_io_dev_mtd(&spi_dev_con); |
|||
assert(io_result == 0); |
|||
|
|||
/* Open connections to device */ |
|||
io_result = io_dev_open(spi_dev_con, |
|||
(uintptr_t)&spi_nor_dev_spec, |
|||
&storage_dev_handle); |
|||
assert(io_result == 0); |
|||
|
|||
stm32image_dev_info_spec.device_size = spi_nor_dev_spec.device_size; |
|||
|
|||
idx = IMG_IDX_BL33; |
|||
part = &stm32image_dev_info_spec.part_info[idx]; |
|||
part->part_offset = STM32MP_NOR_BL33_OFFSET; |
|||
part->bkp_offset = 0U; |
|||
|
|||
#ifdef AARCH32_SP_OPTEE |
|||
idx = IMG_IDX_OPTEE_HEADER; |
|||
part = &stm32image_dev_info_spec.part_info[idx]; |
|||
part->part_offset = STM32MP_NOR_TEEH_OFFSET; |
|||
part->bkp_offset = 0U; |
|||
|
|||
idx = IMG_IDX_OPTEE_PAGED; |
|||
part = &stm32image_dev_info_spec.part_info[idx]; |
|||
part->part_offset = STM32MP_NOR_TEED_OFFSET; |
|||
part->bkp_offset = 0U; |
|||
|
|||
idx = IMG_IDX_OPTEE_CORE; |
|||
part = &stm32image_dev_info_spec.part_info[idx]; |
|||
part->part_offset = STM32MP_NOR_TEEX_OFFSET; |
|||
part->bkp_offset = 0U; |
|||
#endif |
|||
} |
|||
#endif /* STM32MP_SPI_NOR */ |
|||
|
|||
#if STM32MP_RAW_NAND |
|||
static void boot_fmc2_nand(boot_api_context_t *boot_context) |
|||
{ |
|||
int io_result __unused; |
|||
uint8_t idx; |
|||
struct stm32image_part_info *part; |
|||
|
|||
io_result = stm32_fmc2_init(); |
|||
assert(io_result == 0); |
|||
|
|||
/* Register the IO device on this platform */ |
|||
io_result = register_io_dev_mtd(&nand_dev_con); |
|||
assert(io_result == 0); |
|||
|
|||
/* Open connections to device */ |
|||
io_result = io_dev_open(nand_dev_con, (uintptr_t)&nand_dev_spec, |
|||
&storage_dev_handle); |
|||
assert(io_result == 0); |
|||
|
|||
stm32image_dev_info_spec.device_size = nand_dev_spec.device_size; |
|||
|
|||
idx = IMG_IDX_BL33; |
|||
part = &stm32image_dev_info_spec.part_info[idx]; |
|||
part->part_offset = STM32MP_NAND_BL33_OFFSET; |
|||
part->bkp_offset = nand_dev_spec.erase_size; |
|||
|
|||
#ifdef AARCH32_SP_OPTEE |
|||
idx = IMG_IDX_OPTEE_HEADER; |
|||
part = &stm32image_dev_info_spec.part_info[idx]; |
|||
part->part_offset = STM32MP_NAND_TEEH_OFFSET; |
|||
part->bkp_offset = nand_dev_spec.erase_size; |
|||
|
|||
idx = IMG_IDX_OPTEE_PAGED; |
|||
part = &stm32image_dev_info_spec.part_info[idx]; |
|||
part->part_offset = STM32MP_NAND_TEED_OFFSET; |
|||
part->bkp_offset = nand_dev_spec.erase_size; |
|||
|
|||
idx = IMG_IDX_OPTEE_CORE; |
|||
part = &stm32image_dev_info_spec.part_info[idx]; |
|||
part->part_offset = STM32MP_NAND_TEEX_OFFSET; |
|||
part->bkp_offset = nand_dev_spec.erase_size; |
|||
#endif |
|||
} |
|||
#endif /* STM32MP_RAW_NAND */ |
|||
|
|||
#if STM32MP_SPI_NAND |
|||
static void boot_spi_nand(boot_api_context_t *boot_context) |
|||
{ |
|||
int io_result __unused; |
|||
uint8_t idx; |
|||
struct stm32image_part_info *part; |
|||
|
|||
io_result = stm32_qspi_init(); |
|||
assert(io_result == 0); |
|||
|
|||
io_result = register_io_dev_mtd(&spi_dev_con); |
|||
assert(io_result == 0); |
|||
|
|||
/* Open connections to device */ |
|||
io_result = io_dev_open(spi_dev_con, |
|||
(uintptr_t)&spi_nand_dev_spec, |
|||
&storage_dev_handle); |
|||
assert(io_result == 0); |
|||
|
|||
stm32image_dev_info_spec.device_size = |
|||
spi_nand_dev_spec.device_size; |
|||
|
|||
idx = IMG_IDX_BL33; |
|||
part = &stm32image_dev_info_spec.part_info[idx]; |
|||
part->part_offset = STM32MP_NAND_BL33_OFFSET; |
|||
part->bkp_offset = spi_nand_dev_spec.erase_size; |
|||
|
|||
#ifdef AARCH32_SP_OPTEE |
|||
idx = IMG_IDX_OPTEE_HEADER; |
|||
part = &stm32image_dev_info_spec.part_info[idx]; |
|||
part->part_offset = STM32MP_NAND_TEEH_OFFSET; |
|||
part->bkp_offset = spi_nand_dev_spec.erase_size; |
|||
|
|||
idx = IMG_IDX_OPTEE_PAGED; |
|||
part = &stm32image_dev_info_spec.part_info[idx]; |
|||
part->part_offset = STM32MP_NAND_TEED_OFFSET; |
|||
part->bkp_offset = spi_nand_dev_spec.erase_size; |
|||
|
|||
idx = IMG_IDX_OPTEE_CORE; |
|||
part = &stm32image_dev_info_spec.part_info[idx]; |
|||
part->part_offset = STM32MP_NAND_TEEX_OFFSET; |
|||
part->bkp_offset = spi_nand_dev_spec.erase_size; |
|||
#endif |
|||
} |
|||
#endif /* STM32MP_SPI_NAND */ |
|||
|
|||
void stm32mp_io_setup(void) |
|||
{ |
|||
int io_result __unused; |
|||
boot_api_context_t *boot_context = |
|||
(boot_api_context_t *)stm32mp_get_boot_ctx_address(); |
|||
|
|||
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%u\n", |
|||
boot_context->boot_partition_used_toboot); |
|||
} |
|||
|
|||
#ifndef AARCH32_SP_OPTEE |
|||
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); |
|||
#endif |
|||
|
|||
switch (boot_context->boot_interface_selected) { |
|||
#if STM32MP_SDMMC |
|||
case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_SD: |
|||
dmbsy(); |
|||
boot_mmc(MMC_IS_SD, boot_context->boot_interface_instance); |
|||
stm32image_io_setup(); |
|||
break; |
|||
#endif |
|||
#if STM32MP_EMMC |
|||
case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_EMMC: |
|||
dmbsy(); |
|||
boot_mmc(MMC_IS_EMMC, boot_context->boot_interface_instance); |
|||
stm32image_io_setup(); |
|||
break; |
|||
#endif |
|||
#if STM32MP_SPI_NOR |
|||
case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NOR_QSPI: |
|||
dmbsy(); |
|||
boot_spi_nor(boot_context); |
|||
stm32image_io_setup(); |
|||
break; |
|||
#endif |
|||
#if STM32MP_RAW_NAND |
|||
case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_FMC: |
|||
dmbsy(); |
|||
boot_fmc2_nand(boot_context); |
|||
stm32image_io_setup(); |
|||
break; |
|||
#endif |
|||
#if STM32MP_SPI_NAND |
|||
case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_QSPI: |
|||
dmbsy(); |
|||
boot_spi_nand(boot_context); |
|||
stm32image_io_setup(); |
|||
break; |
|||
#endif |
|||
|
|||
default: |
|||
ERROR("Boot interface %d not supported\n", |
|||
boot_context->boot_interface_selected); |
|||
panic(); |
|||
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; |
|||
} |
@ -1,103 +0,0 @@ |
|||
/*
|
|||
* Copyright (c) 2016-2021, ARM Limited and Contributors. All rights reserved. |
|||
* |
|||
* SPDX-License-Identifier: BSD-3-Clause |
|||
*/ |
|||
|
|||
#include <common/bl_common.h> |
|||
#include <common/desc_image_load.h> |
|||
#include <plat/common/platform.h> |
|||
|
|||
#include <platform_def.h> |
|||
|
|||
/*******************************************************************************
|
|||
* Following descriptor provides BL image/ep information that gets used |
|||
* by BL2 to load the images and also subset of this information is |
|||
* passed to next BL image. The image loading sequence is managed by |
|||
* populating the images in required loading order. The image execution |
|||
* sequence is managed by populating the `next_handoff_image_id` with |
|||
* the next executable image id. |
|||
******************************************************************************/ |
|||
static bl_mem_params_node_t bl2_mem_params_descs[] = { |
|||
/* Fill BL32 related information */ |
|||
{ |
|||
.image_id = BL32_IMAGE_ID, |
|||
|
|||
SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP, |
|||
VERSION_2, entry_point_info_t, |
|||
SECURE | EXECUTABLE | EP_FIRST_EXE), |
|||
|
|||
/* Updated at runtime if OP-TEE is loaded */ |
|||
.ep_info.pc = STM32MP_BL32_BASE, |
|||
|
|||
.ep_info.spsr = SPSR_MODE32(MODE32_svc, SPSR_T_ARM, |
|||
SPSR_E_LITTLE, |
|||
DISABLE_ALL_EXCEPTIONS), |
|||
|
|||
SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, |
|||
VERSION_2, image_info_t, |
|||
IMAGE_ATTRIB_PLAT_SETUP), |
|||
|
|||
/* Updated at runtime if OP-TEE is loaded */ |
|||
.image_info.image_base = STM32MP_BL32_BASE, |
|||
.image_info.image_max_size = STM32MP_BL32_SIZE, |
|||
|
|||
.next_handoff_image_id = BL33_IMAGE_ID, |
|||
}, |
|||
|
|||
#if defined(AARCH32_SP_OPTEE) |
|||
/* Fill BL32 external 1 image related information */ |
|||
{ |
|||
.image_id = BL32_EXTRA1_IMAGE_ID, |
|||
|
|||
SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP, |
|||
VERSION_2, entry_point_info_t, |
|||
SECURE | NON_EXECUTABLE), |
|||
|
|||
SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, |
|||
VERSION_2, image_info_t, |
|||
IMAGE_ATTRIB_SKIP_LOADING), |
|||
|
|||
.next_handoff_image_id = INVALID_IMAGE_ID, |
|||
}, |
|||
/* Fill BL32 external 2 image related information */ |
|||
{ |
|||
.image_id = BL32_EXTRA2_IMAGE_ID, |
|||
|
|||
SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP, |
|||
VERSION_2, entry_point_info_t, |
|||
SECURE | NON_EXECUTABLE), |
|||
|
|||
SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, |
|||
VERSION_2, image_info_t, |
|||
IMAGE_ATTRIB_SKIP_LOADING), |
|||
|
|||
.next_handoff_image_id = INVALID_IMAGE_ID, |
|||
}, |
|||
#endif /* AARCH32_SP_OPTEE */ |
|||
|
|||
/* Fill BL33 related information */ |
|||
{ |
|||
.image_id = BL33_IMAGE_ID, |
|||
|
|||
SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP, |
|||
VERSION_2, entry_point_info_t, |
|||
NON_SECURE | EXECUTABLE), |
|||
|
|||
.ep_info.pc = PLAT_STM32MP_NS_IMAGE_OFFSET, |
|||
.ep_info.spsr = SPSR_MODE32(MODE32_svc, SPSR_T_ARM, |
|||
SPSR_E_LITTLE, |
|||
DISABLE_ALL_EXCEPTIONS), |
|||
|
|||
SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, |
|||
VERSION_2, image_info_t, 0U), |
|||
|
|||
.image_info.image_base = PLAT_STM32MP_NS_IMAGE_OFFSET, |
|||
.image_info.image_max_size = STM32MP_DDR_MAX_SIZE - |
|||
(PLAT_STM32MP_NS_IMAGE_OFFSET - STM32MP_DDR_BASE), |
|||
|
|||
.next_handoff_image_id = INVALID_IMAGE_ID, |
|||
} |
|||
}; |
|||
|
|||
REGISTER_BL_IMAGE_DESCS(bl2_mem_params_descs) |
@ -1,136 +0,0 @@ |
|||
/*
|
|||
* Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved. |
|||
* |
|||
* SPDX-License-Identifier: BSD-3-Clause |
|||
*/ |
|||
|
|||
#include <stdint.h> |
|||
|
|||
#include <platform_def.h> |
|||
|
|||
#include <common/debug.h> |
|||
#include <drivers/arm/tzc400.h> |
|||
#include <drivers/clk.h> |
|||
#include <drivers/st/stm32mp1_clk.h> |
|||
#include <dt-bindings/clock/stm32mp1-clks.h> |
|||
#include <dt-bindings/soc/stm32mp15-tzc400.h> |
|||
#include <lib/mmio.h> |
|||
|
|||
static unsigned int region_nb; |
|||
|
|||
static void init_tzc400_begin(unsigned int region0_attr) |
|||
{ |
|||
tzc400_init(STM32MP1_TZC_BASE); |
|||
tzc400_disable_filters(); |
|||
|
|||
/* Region 0 set to cover all DRAM at 0xC000_0000 */ |
|||
tzc400_configure_region0(region0_attr, 0); |
|||
|
|||
region_nb = 1U; |
|||
} |
|||
|
|||
static void init_tzc400_end(unsigned int action) |
|||
{ |
|||
tzc400_set_action(action); |
|||
tzc400_enable_filters(); |
|||
} |
|||
|
|||
static void tzc400_add_region(unsigned long long region_base, |
|||
unsigned long long region_top, bool sec) |
|||
{ |
|||
unsigned int sec_attr; |
|||
unsigned int nsaid_permissions; |
|||
|
|||
if (sec) { |
|||
sec_attr = TZC_REGION_S_RDWR; |
|||
nsaid_permissions = 0; |
|||
} else { |
|||
sec_attr = TZC_REGION_S_NONE; |
|||
nsaid_permissions = TZC_REGION_NSEC_ALL_ACCESS_RDWR; |
|||
} |
|||
|
|||
tzc400_configure_region(STM32MP1_FILTER_BIT_ALL, region_nb, region_base, |
|||
region_top, sec_attr, nsaid_permissions); |
|||
|
|||
region_nb++; |
|||
} |
|||
|
|||
/*******************************************************************************
|
|||
* Initialize the TrustZone Controller. Configure Region 0 with Secure RW access |
|||
* and allow Non-Secure masters full access. |
|||
******************************************************************************/ |
|||
static void init_tzc400(void) |
|||
{ |
|||
unsigned long long region_base, region_top; |
|||
unsigned long long ddr_base = STM32MP_DDR_BASE; |
|||
unsigned long long ddr_ns_size = |
|||
(unsigned long long)stm32mp_get_ddr_ns_size(); |
|||
unsigned long long ddr_ns_top = ddr_base + (ddr_ns_size - 1U); |
|||
unsigned long long ddr_top __unused; |
|||
|
|||
init_tzc400_begin(TZC_REGION_S_NONE); |
|||
|
|||
/*
|
|||
* Region 1 set to cover all non-secure DRAM at 0xC000_0000. Apply the |
|||
* same configuration to all filters in the TZC. |
|||
*/ |
|||
region_base = ddr_base; |
|||
region_top = ddr_ns_top; |
|||
tzc400_add_region(region_base, region_top, false); |
|||
|
|||
#ifdef AARCH32_SP_OPTEE |
|||
/* Region 2 set to cover all secure DRAM. */ |
|||
region_base = region_top + 1U; |
|||
region_top += STM32MP_DDR_S_SIZE; |
|||
tzc400_add_region(region_base, region_top, true); |
|||
|
|||
ddr_top = STM32MP_DDR_BASE + dt_get_ddr_size() - 1U; |
|||
if (region_top < ddr_top) { |
|||
/* Region 3 set to cover non-secure memory DRAM after BL32. */ |
|||
region_base = region_top + 1U; |
|||
region_top = ddr_top; |
|||
tzc400_add_region(region_base, region_top, false); |
|||
} |
|||
#endif |
|||
|
|||
/*
|
|||
* Raise an interrupt (secure FIQ) if a NS device tries to access |
|||
* secure memory |
|||
*/ |
|||
init_tzc400_end(TZC_ACTION_INT); |
|||
} |
|||
|
|||
/*******************************************************************************
|
|||
* Initialize the TrustZone Controller. |
|||
* Early initialization create only one region with full access to secure. |
|||
* This setting is used before and during DDR initialization. |
|||
******************************************************************************/ |
|||
static void early_init_tzc400(void) |
|||
{ |
|||
clk_enable(TZC1); |
|||
clk_enable(TZC2); |
|||
|
|||
/* Region 0 set to cover all DRAM secure at 0xC000_0000 */ |
|||
init_tzc400_begin(TZC_REGION_S_RDWR); |
|||
|
|||
/* Raise an exception if a NS device tries to access secure memory */ |
|||
init_tzc400_end(TZC_ACTION_ERR); |
|||
} |
|||
|
|||
/*******************************************************************************
|
|||
* Initialize the secure environment. At this moment only the TrustZone |
|||
* Controller is initialized. |
|||
******************************************************************************/ |
|||
void stm32mp1_arch_security_setup(void) |
|||
{ |
|||
early_init_tzc400(); |
|||
} |
|||
|
|||
/*******************************************************************************
|
|||
* Initialize the secure environment. At this moment only the TrustZone |
|||
* Controller is initialized. |
|||
******************************************************************************/ |
|||
void stm32mp1_security_setup(void) |
|||
{ |
|||
init_tzc400(); |
|||
} |
@ -1,78 +0,0 @@ |
|||
/*
|
|||
* Copyright (C) 2021-2022, STMicroelectronics - All Rights Reserved |
|||
* |
|||
* SPDX-License-Identifier: BSD-3-Clause |
|||
*/ |
|||
|
|||
#ifndef STM32MP1_STM32IMAGE_DEF_H |
|||
#define STM32MP1_STM32IMAGE_DEF_H |
|||
|
|||
#ifdef AARCH32_SP_OPTEE |
|||
#if STM32MP15_OPTEE_RSV_SHM |
|||
#define STM32MP_DDR_S_SIZE U(0x01E00000) /* 30 MB */ |
|||
#define STM32MP_DDR_SHMEM_SIZE U(0x00200000) /* 2 MB */ |
|||
#else |
|||
#define STM32MP_DDR_S_SIZE U(0x02000000) /* 32 MB */ |
|||
#define STM32MP_DDR_SHMEM_SIZE U(0) /* empty */ |
|||
#endif |
|||
#else |
|||
#define STM32MP_DDR_S_SIZE U(0) |
|||
#define STM32MP_DDR_SHMEM_SIZE U(0) |
|||
#endif |
|||
|
|||
#define STM32MP_BL2_SIZE U(0x0001C000) /* 112 KB for BL2 */ |
|||
#define STM32MP_DTB_SIZE U(0x00006000) /* 24 KB for DTB */ |
|||
|
|||
#ifdef AARCH32_SP_OPTEE |
|||
#define STM32MP_BL32_BASE STM32MP_SEC_SYSRAM_BASE |
|||
|
|||
#define STM32MP_BL2_BASE (STM32MP_SEC_SYSRAM_BASE + \ |
|||
STM32MP_SEC_SYSRAM_SIZE - \ |
|||
STM32MP_BL2_SIZE) |
|||
|
|||
/* OP-TEE loads from SYSRAM base to BL2 DTB start address */ |
|||
#define STM32MP_OPTEE_BASE STM32MP_BL32_BASE |
|||
#define STM32MP_OPTEE_SIZE (STM32MP_SEC_SYSRAM_SIZE - \ |
|||
STM32MP_BL2_SIZE - STM32MP_DTB_SIZE) |
|||
#define STM32MP_BL32_SIZE STM32MP_OPTEE_SIZE |
|||
#else /* AARCH32_SP_OPTEE */ |
|||
#define STM32MP_BL32_SIZE U(0x00019000) /* 96 KB for BL32 */ |
|||
|
|||
#define STM32MP_BL32_BASE (STM32MP_SEC_SYSRAM_BASE + \ |
|||
STM32MP_SEC_SYSRAM_SIZE - \ |
|||
STM32MP_BL32_SIZE) |
|||
|
|||
#define STM32MP_BL2_BASE (STM32MP_BL32_BASE - \ |
|||
STM32MP_BL2_SIZE) |
|||
#endif /* AARCH32_SP_OPTEE */ |
|||
|
|||
/* DTB initialization value */ |
|||
#define STM32MP_DTB_BASE (STM32MP_BL2_BASE - \ |
|||
STM32MP_DTB_SIZE) |
|||
|
|||
/*
|
|||
* MAX_MMAP_REGIONS is usually: |
|||
* BL stm32mp1_mmap size + mmap regions in *_plat_arch_setup |
|||
*/ |
|||
#if defined(IMAGE_BL32) |
|||
#define MAX_MMAP_REGIONS 6 |
|||
#endif |
|||
|
|||
/*******************************************************************************
|
|||
* STM32MP1 RAW partition offset for MTD devices |
|||
******************************************************************************/ |
|||
#define STM32MP_NOR_BL33_OFFSET U(0x00080000) |
|||
#ifdef AARCH32_SP_OPTEE |
|||
#define STM32MP_NOR_TEEH_OFFSET U(0x00280000) |
|||
#define STM32MP_NOR_TEED_OFFSET U(0x002C0000) |
|||
#define STM32MP_NOR_TEEX_OFFSET U(0x00300000) |
|||
#endif |
|||
|
|||
#define STM32MP_NAND_BL33_OFFSET U(0x00200000) |
|||
#ifdef AARCH32_SP_OPTEE |
|||
#define STM32MP_NAND_TEEH_OFFSET U(0x00600000) |
|||
#define STM32MP_NAND_TEED_OFFSET U(0x00680000) |
|||
#define STM32MP_NAND_TEEX_OFFSET U(0x00700000) |
|||
#endif |
|||
|
|||
#endif /* STM32MP1_STM32IMAGE_DEF_H */ |
Loading…
Reference in new issue