mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-18 02:24:18 +00:00
Merge changes Iaa189c54,I8856b495 into integration
* changes: feat(intel): enable query of fip offset on RSU feat(intel): support query of fip offset using RSU
This commit is contained in:
commit
b3a7396d0e
10 changed files with 277 additions and 15 deletions
|
@ -28,6 +28,7 @@
|
|||
#include "socfpga_mailbox.h"
|
||||
#include "socfpga_private.h"
|
||||
#include "socfpga_reset_manager.h"
|
||||
#include "socfpga_ros.h"
|
||||
#include "socfpga_system_manager.h"
|
||||
#include "wdt/watchdog.h"
|
||||
|
||||
|
@ -92,6 +93,7 @@ void bl2_el3_early_platform_setup(u_register_t x0, u_register_t x1,
|
|||
void bl2_el3_plat_arch_setup(void)
|
||||
{
|
||||
|
||||
unsigned long offset = 0;
|
||||
const mmap_region_t bl_regions[] = {
|
||||
MAP_REGION_FLAT(BL2_BASE, BL2_END - BL2_BASE,
|
||||
MT_MEMORY | MT_RW | MT_SECURE),
|
||||
|
@ -123,14 +125,17 @@ void bl2_el3_plat_arch_setup(void)
|
|||
switch (boot_source) {
|
||||
case BOOT_SOURCE_SDMMC:
|
||||
dw_mmc_init(¶ms, &mmc_info);
|
||||
socfpga_io_setup(boot_source);
|
||||
socfpga_io_setup(boot_source, PLAT_SDMMC_DATA_BASE);
|
||||
break;
|
||||
|
||||
case BOOT_SOURCE_QSPI:
|
||||
cad_qspi_init(0, QSPI_CONFIG_CPHA, QSPI_CONFIG_CPOL,
|
||||
QSPI_CONFIG_CSDA, QSPI_CONFIG_CSDADS,
|
||||
QSPI_CONFIG_CSEOT, QSPI_CONFIG_CSSOT, 0);
|
||||
socfpga_io_setup(boot_source);
|
||||
if (ros_qspi_get_ssbl_offset(&offset) != ROS_RET_OK) {
|
||||
offset = PLAT_QSPI_DATA_BASE;
|
||||
}
|
||||
socfpga_io_setup(boot_source, offset);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
@ -47,6 +47,7 @@ BL2_SOURCES += \
|
|||
plat/intel/soc/agilex/soc/agilex_pinmux.c \
|
||||
plat/intel/soc/common/bl2_plat_mem_params_desc.c \
|
||||
plat/intel/soc/common/socfpga_image_load.c \
|
||||
plat/intel/soc/common/socfpga_ros.c \
|
||||
plat/intel/soc/common/socfpga_storage.c \
|
||||
plat/intel/soc/common/soc/socfpga_emac.c \
|
||||
plat/intel/soc/common/soc/socfpga_firewall.c \
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include "socfpga_mailbox.h"
|
||||
#include "socfpga_private.h"
|
||||
#include "socfpga_reset_manager.h"
|
||||
#include "socfpga_ros.h"
|
||||
#include "wdt/watchdog.h"
|
||||
|
||||
|
||||
|
@ -96,6 +97,7 @@ void bl2_el3_early_platform_setup(u_register_t x0, u_register_t x1,
|
|||
void bl2_el3_plat_arch_setup(void)
|
||||
{
|
||||
handoff reverse_handoff_ptr;
|
||||
unsigned long offset = 0;
|
||||
|
||||
struct cdns_sdmmc_params params = EMMC_INIT_PARAMS((uintptr_t) &cdns_desc, get_mmc_clk());
|
||||
|
||||
|
@ -109,7 +111,7 @@ void bl2_el3_plat_arch_setup(void)
|
|||
case BOOT_SOURCE_SDMMC:
|
||||
NOTICE("SDMMC boot\n");
|
||||
sdmmc_init(&reverse_handoff_ptr, ¶ms, &mmc_info);
|
||||
socfpga_io_setup(boot_source);
|
||||
socfpga_io_setup(boot_source, PLAT_SDMMC_DATA_BASE);
|
||||
break;
|
||||
|
||||
case BOOT_SOURCE_QSPI:
|
||||
|
@ -117,13 +119,16 @@ void bl2_el3_plat_arch_setup(void)
|
|||
cad_qspi_init(0, QSPI_CONFIG_CPHA, QSPI_CONFIG_CPOL,
|
||||
QSPI_CONFIG_CSDA, QSPI_CONFIG_CSDADS,
|
||||
QSPI_CONFIG_CSEOT, QSPI_CONFIG_CSSOT, 0);
|
||||
socfpga_io_setup(boot_source);
|
||||
if (ros_qspi_get_ssbl_offset(&offset) != ROS_RET_OK) {
|
||||
offset = PLAT_QSPI_DATA_BASE;
|
||||
}
|
||||
socfpga_io_setup(boot_source, offset);
|
||||
break;
|
||||
|
||||
case BOOT_SOURCE_NAND:
|
||||
NOTICE("NAND boot\n");
|
||||
nand_init(&reverse_handoff_ptr);
|
||||
socfpga_io_setup(boot_source);
|
||||
socfpga_io_setup(boot_source, PLAT_NAND_DATA_BASE);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
@ -60,6 +60,7 @@ BL2_SOURCES += \
|
|||
plat/intel/soc/agilex5/soc/agilex5_power_manager.c \
|
||||
plat/intel/soc/common/bl2_plat_mem_params_desc.c \
|
||||
plat/intel/soc/common/socfpga_image_load.c \
|
||||
plat/intel/soc/common/socfpga_ros.c \
|
||||
plat/intel/soc/common/socfpga_storage.c \
|
||||
plat/intel/soc/common/socfpga_vab.c \
|
||||
plat/intel/soc/common/soc/socfpga_emac.c \
|
||||
|
|
|
@ -44,6 +44,10 @@
|
|||
#define PLAT_HANDOFF_OFFSET 0xFFE3F000
|
||||
#endif
|
||||
|
||||
#define PLAT_QSPI_DATA_BASE (0x3C00000)
|
||||
#define PLAT_NAND_DATA_BASE (0x0200000)
|
||||
#define PLAT_SDMMC_DATA_BASE (0x0)
|
||||
|
||||
/*******************************************************************************
|
||||
* Platform binary types for linking
|
||||
******************************************************************************/
|
||||
|
|
|
@ -33,7 +33,7 @@ typedef enum {
|
|||
|
||||
void enable_nonsecure_access(void);
|
||||
|
||||
void socfpga_io_setup(int boot_source);
|
||||
void socfpga_io_setup(int boot_source, unsigned long offset);
|
||||
|
||||
void socfgpa_configure_mmu_el3(unsigned long total_base,
|
||||
unsigned long total_size,
|
||||
|
|
62
plat/intel/soc/common/include/socfpga_ros.h
Normal file
62
plat/intel/soc/common/include/socfpga_ros.h
Normal file
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* Copyright (c) 2024, Intel Corporation. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef SOCFPGA_ROS_H
|
||||
#define SOCFPGA_ROS_H
|
||||
|
||||
#include <arch_helpers.h>
|
||||
#include <lib/utils_def.h>
|
||||
|
||||
/** status response*/
|
||||
#define ROS_RET_OK (0x00U)
|
||||
#define ROS_RET_INVALID (0x01U)
|
||||
#define ROS_RET_NOT_RSU_MODE (0x02U)
|
||||
#define ROS_QSPI_READ_ERROR (0x03U)
|
||||
#define ROS_SPT_BAD_MAGIC_NUM (0x04U)
|
||||
#define ROS_SPT_CRC_ERROR (0x05U)
|
||||
#define ROS_IMAGE_INDEX_ERR (0x06U)
|
||||
#define ROS_IMAGE_PARTNUM_OVFL (0x07U)
|
||||
|
||||
#define ADDR_64(h, l) (((((unsigned long)(h)) & 0xffffffff) << 32) | \
|
||||
(((unsigned long)(l)) & 0xffffffff))
|
||||
|
||||
#define RSU_GET_SPT_RESP_SIZE (4U)
|
||||
|
||||
#define RSU_STATUS_RES_SIZE (9U)
|
||||
|
||||
#define SPT_MAGIC_NUMBER (0x57713427U)
|
||||
#define SPT_VERSION (0U)
|
||||
#define SPT_FLAG_RESERVED (1U)
|
||||
#define SPT_FLAG_READONLY (2U)
|
||||
|
||||
#define SPT_MAX_PARTITIONS (127U)
|
||||
#define SPT_PARTITION_NAME_LENGTH (16U)
|
||||
#define SPT_RSVD_LENGTH (4U)
|
||||
#define SPT_SIZE (4096U)
|
||||
/*BOOT_INFO + FACTORY_IMAGE + SPT0 + SPT1 + CPB0 + CPB1 + FACTORY_IM.SSBL+ *APP* + *APP*.SSBL*/
|
||||
#define SPT_MIN_PARTITIONS (9U)
|
||||
|
||||
#define FACTORY_IMAGE "FACTORY_IMAGE"
|
||||
#define FACTORY_SSBL "FACTORY_IM.SSBL"
|
||||
#define SSBL_SUFFIX ".SSBL"
|
||||
|
||||
typedef struct {
|
||||
const uint32_t magic_number;
|
||||
const uint32_t version;
|
||||
const uint32_t partitions;
|
||||
uint32_t checksum;
|
||||
const uint32_t __RSVD[SPT_RSVD_LENGTH];
|
||||
struct {
|
||||
const char name[SPT_PARTITION_NAME_LENGTH];
|
||||
const uint64_t offset;
|
||||
const uint32_t length;
|
||||
const uint32_t flags;
|
||||
} partition[SPT_MAX_PARTITIONS];
|
||||
} __packed spt_table_t;
|
||||
|
||||
uint32_t ros_qspi_get_ssbl_offset(unsigned long *offset);
|
||||
|
||||
#endif /* SOCFPGA_ROS_H */
|
188
plat/intel/soc/common/socfpga_ros.c
Normal file
188
plat/intel/soc/common/socfpga_ros.c
Normal file
|
@ -0,0 +1,188 @@
|
|||
/*
|
||||
* Copyright (c) 2024, Intel Corporation. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/* system header files*/
|
||||
#include <assert.h>
|
||||
#include <endian.h>
|
||||
#include <string.h>
|
||||
|
||||
/* CRC function header */
|
||||
#include <common/tf_crc32.h>
|
||||
|
||||
/* Cadense qspi driver*/
|
||||
#include <qspi/cadence_qspi.h>
|
||||
|
||||
/* Mailbox driver*/
|
||||
#include <socfpga_mailbox.h>
|
||||
|
||||
#include <socfpga_ros.h>
|
||||
|
||||
static void swap_bits(char *const data, uint32_t len)
|
||||
{
|
||||
uint32_t x, y;
|
||||
char tmp;
|
||||
|
||||
for (x = 0U; x < len; x++) {
|
||||
tmp = 0U;
|
||||
for (y = 0U; y < 8; y++) {
|
||||
tmp <<= 1;
|
||||
if (data[x] & 1) {
|
||||
tmp |= 1;
|
||||
}
|
||||
data[x] >>= 1;
|
||||
}
|
||||
data[x] = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t get_current_image_index(spt_table_t *spt_buf, uint32_t *const img_index)
|
||||
{
|
||||
if (spt_buf == NULL || img_index == NULL) {
|
||||
return ROS_RET_INVALID;
|
||||
}
|
||||
|
||||
uint32_t ret;
|
||||
unsigned long current_image;
|
||||
uint32_t rsu_status[RSU_STATUS_RES_SIZE];
|
||||
|
||||
if (spt_buf->partitions < SPT_MIN_PARTITIONS || spt_buf->partitions > SPT_MAX_PARTITIONS) {
|
||||
return ROS_IMAGE_PARTNUM_OVFL;
|
||||
}
|
||||
|
||||
ret = mailbox_rsu_status(rsu_status, RSU_STATUS_RES_SIZE);
|
||||
if (ret != MBOX_RET_OK) {
|
||||
return ROS_RET_NOT_RSU_MODE;
|
||||
}
|
||||
|
||||
current_image = ADDR_64(rsu_status[1], rsu_status[0]);
|
||||
NOTICE("ROS: Current image is at 0x%08lx\n", current_image);
|
||||
|
||||
*img_index = 0U;
|
||||
for (uint32_t index = 0U ; index < spt_buf->partitions; index++) {
|
||||
if (spt_buf->partition[index].offset == current_image) {
|
||||
*img_index = index;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (*img_index == 0U) {
|
||||
return ROS_IMAGE_INDEX_ERR;
|
||||
}
|
||||
|
||||
return ROS_RET_OK;
|
||||
}
|
||||
|
||||
static uint32_t load_and_check_spt(spt_table_t *spt_ptr, size_t offset)
|
||||
{
|
||||
|
||||
if (spt_ptr == NULL || offset == 0U) {
|
||||
return ROS_RET_INVALID;
|
||||
}
|
||||
|
||||
int ret;
|
||||
uint32_t calc_crc;
|
||||
static spt_table_t spt_data;
|
||||
|
||||
ret = cad_qspi_read(spt_ptr, offset, SPT_SIZE);
|
||||
if (ret != 0U) {
|
||||
return ROS_QSPI_READ_ERROR;
|
||||
}
|
||||
|
||||
if (spt_ptr->magic_number != SPT_MAGIC_NUMBER) {
|
||||
return ROS_SPT_BAD_MAGIC_NUM;
|
||||
}
|
||||
|
||||
if (spt_ptr->partitions < SPT_MIN_PARTITIONS || spt_ptr->partitions > SPT_MAX_PARTITIONS) {
|
||||
return ROS_IMAGE_PARTNUM_OVFL;
|
||||
}
|
||||
|
||||
memcpy_s(&spt_data, SPT_SIZE, spt_ptr, SPT_SIZE);
|
||||
spt_data.checksum = 0U;
|
||||
swap_bits((char *)&spt_data, SPT_SIZE);
|
||||
|
||||
calc_crc = tf_crc32(0, (uint8_t *)&spt_data, SPT_SIZE);
|
||||
if (bswap32(spt_ptr->checksum) != calc_crc) {
|
||||
return ROS_SPT_CRC_ERROR;
|
||||
}
|
||||
|
||||
NOTICE("ROS: SPT table at 0x%08lx is verified\n", offset);
|
||||
return ROS_RET_OK;
|
||||
}
|
||||
|
||||
static uint32_t get_spt(spt_table_t *spt_buf)
|
||||
{
|
||||
if (spt_buf == NULL) {
|
||||
return ROS_RET_INVALID;
|
||||
}
|
||||
|
||||
uint32_t ret;
|
||||
uint32_t spt_offset[RSU_GET_SPT_RESP_SIZE];
|
||||
|
||||
/* Get SPT offset from SDM via mailbox commands */
|
||||
ret = mailbox_rsu_get_spt_offset(spt_offset, RSU_GET_SPT_RESP_SIZE);
|
||||
if (ret != MBOX_RET_OK) {
|
||||
WARN("ROS: Not booted in RSU mode\n");
|
||||
return ROS_RET_NOT_RSU_MODE;
|
||||
}
|
||||
|
||||
/* Print the SPT table addresses */
|
||||
VERBOSE("ROS: SPT0 0x%08lx\n", ADDR_64(spt_offset[0], spt_offset[1]));
|
||||
VERBOSE("ROS: SPT1 0x%08lx\n", ADDR_64(spt_offset[2], spt_offset[3]));
|
||||
|
||||
/* Load and validate SPT1*/
|
||||
ret = load_and_check_spt(spt_buf, ADDR_64(spt_offset[2], spt_offset[3]));
|
||||
if (ret != ROS_RET_OK) {
|
||||
/* Load and validate SPT0*/
|
||||
ret = load_and_check_spt(spt_buf, ADDR_64(spt_offset[0], spt_offset[1]));
|
||||
if (ret != ROS_RET_OK) {
|
||||
WARN("Both SPT tables are unusable\n");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return ROS_RET_OK;
|
||||
}
|
||||
|
||||
uint32_t ros_qspi_get_ssbl_offset(unsigned long *offset)
|
||||
{
|
||||
if (offset == NULL) {
|
||||
return ROS_RET_INVALID;
|
||||
}
|
||||
|
||||
uint32_t ret, img_index;
|
||||
char ssbl_name[SPT_PARTITION_NAME_LENGTH];
|
||||
static spt_table_t spt;
|
||||
|
||||
ret = get_spt(&spt);
|
||||
if (ret != ROS_RET_OK) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = get_current_image_index(&spt, &img_index);
|
||||
if (ret != ROS_RET_OK) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (strncmp(spt.partition[img_index].name, FACTORY_IMAGE,
|
||||
SPT_PARTITION_NAME_LENGTH) == 0U) {
|
||||
strlcpy(ssbl_name, FACTORY_SSBL, SPT_PARTITION_NAME_LENGTH);
|
||||
} else {
|
||||
strlcpy(ssbl_name, spt.partition[img_index].name,
|
||||
SPT_PARTITION_NAME_LENGTH);
|
||||
strlcat(ssbl_name, SSBL_SUFFIX, SPT_PARTITION_NAME_LENGTH);
|
||||
}
|
||||
|
||||
for (uint32_t index = 0U; index < spt.partitions; index++) {
|
||||
if (strncmp(spt.partition[index].name, ssbl_name,
|
||||
SPT_PARTITION_NAME_LENGTH) == 0U) {
|
||||
*offset = spt.partition[index].offset;
|
||||
NOTICE("ROS: Corresponding SSBL is at 0x%08lx\n", *offset);
|
||||
return ROS_RET_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return ROS_IMAGE_INDEX_ERR;
|
||||
}
|
|
@ -24,16 +24,13 @@
|
|||
|
||||
#include "drivers/sdmmc/sdmmc.h"
|
||||
#include "socfpga_private.h"
|
||||
#include "socfpga_ros.h"
|
||||
|
||||
|
||||
#define PLAT_FIP_BASE (0)
|
||||
#define PLAT_FIP_MAX_SIZE (0x1000000)
|
||||
#define PLAT_MMC_DATA_BASE (0xffe3c000)
|
||||
#define PLAT_MMC_DATA_SIZE (0x2000)
|
||||
#define PLAT_QSPI_DATA_BASE (0x3C00000)
|
||||
#define PLAT_QSPI_DATA_SIZE (0x1000000)
|
||||
#define PLAT_NAND_DATA_BASE (0x0200000)
|
||||
#define PLAT_NAND_DATA_SIZE (0x1000000)
|
||||
|
||||
static const io_dev_connector_t *fip_dev_con;
|
||||
static const io_dev_connector_t *boot_dev_con;
|
||||
|
@ -136,9 +133,10 @@ static int check_fip(const uintptr_t spec)
|
|||
return result;
|
||||
}
|
||||
|
||||
void socfpga_io_setup(int boot_source)
|
||||
void socfpga_io_setup(int boot_source, unsigned long offset)
|
||||
{
|
||||
int result;
|
||||
fip_spec.offset = offset;
|
||||
|
||||
switch (boot_source) {
|
||||
case BOOT_SOURCE_SDMMC:
|
||||
|
@ -152,7 +150,6 @@ void socfpga_io_setup(int boot_source)
|
|||
|
||||
case BOOT_SOURCE_QSPI:
|
||||
register_io_dev = ®ister_io_dev_memmap;
|
||||
fip_spec.offset = PLAT_QSPI_DATA_BASE;
|
||||
break;
|
||||
|
||||
#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
|
||||
|
@ -161,7 +158,6 @@ void socfpga_io_setup(int boot_source)
|
|||
nand_dev_spec.ops.init = cdns_nand_init_mtd;
|
||||
nand_dev_spec.ops.read = cdns_nand_read;
|
||||
nand_dev_spec.ops.write = NULL;
|
||||
fip_spec.offset = PLAT_NAND_DATA_BASE;
|
||||
break;
|
||||
#endif
|
||||
|
||||
|
|
|
@ -122,14 +122,14 @@ void bl2_el3_plat_arch_setup(void)
|
|||
switch (boot_source) {
|
||||
case BOOT_SOURCE_SDMMC:
|
||||
dw_mmc_init(¶ms, &mmc_info);
|
||||
socfpga_io_setup(boot_source);
|
||||
socfpga_io_setup(boot_source, PLAT_SDMMC_DATA_BASE);
|
||||
break;
|
||||
|
||||
case BOOT_SOURCE_QSPI:
|
||||
cad_qspi_init(0, QSPI_CONFIG_CPHA, QSPI_CONFIG_CPOL,
|
||||
QSPI_CONFIG_CSDA, QSPI_CONFIG_CSDADS,
|
||||
QSPI_CONFIG_CSEOT, QSPI_CONFIG_CSSOT, 0);
|
||||
socfpga_io_setup(boot_source);
|
||||
socfpga_io_setup(boot_source, PLAT_QSPI_DATA_BASE);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
Loading…
Add table
Reference in a new issue