plat/arm: enable support for Plat owned SPs

For Arm platforms SPs are loaded by parsing tb_fw_config.dts and
adding them to SP structure sequentially, which in-turn is appended to
loadable image list.

With recently introduced dualroot CoT for SPs where they are owned
either by SiP or by Platform. SiP owned SPs index starts at SP_PKG1_ID
and Plat owned SPs index starts at SP_PKG5_ID. As the start index of SP
depends on the owner, there should be a mechanism to parse owner of a SP
and put it at the correct index in SP structure.

This patch adds support for parsing a new optional field "owner" and
based on it put SP details(UUID & Load-address) at the correct index in
SP structure.

Change-Id: Ibd255b60d5c45023cc7fdb10971bef6626cb560b
Signed-off-by: Manish Pandey <manish.pandey2@arm.com>
This commit is contained in:
Manish Pandey 2020-07-31 16:15:16 +01:00
parent 2947412d54
commit 990d972f1b
3 changed files with 66 additions and 21 deletions

View File

@ -14,11 +14,13 @@
#define arm__sp_getter(prop) arm_sp.prop
#define ARM_SP_MAX_SIZE U(0x80000)
#define ARM_SP_OWNER_NAME_LEN U(8)
struct arm_sp_t {
unsigned int number_of_sp;
union uuid_helper_t uuids[MAX_SP_IDS];
uintptr_t load_addr[MAX_SP_IDS];
char owner[MAX_SP_IDS][ARM_SP_OWNER_NAME_LEN];
};
int fconf_populate_arm_sp(uintptr_t config);

View File

@ -52,6 +52,7 @@ const io_uuid_spec_t arm_uuid_spec[MAX_NUMBER_IDS] = {
[NON_TRUSTED_FW_CONTENT_CERT_ID] = {UUID_NON_TRUSTED_FW_CONTENT_CERT},
#if defined(SPD_spmd)
[SIP_SP_CONTENT_CERT_ID] = {UUID_SIP_SECURE_PARTITION_CONTENT_CERT},
[PLAT_SP_CONTENT_CERT_ID] = {UUID_PLAT_SECURE_PARTITION_CONTENT_CERT},
#endif
#endif /* ARM_IO_IN_DTB */
#endif /* TRUSTED_BOARD_BOOT */
@ -189,6 +190,11 @@ struct plat_io_policy policies[MAX_NUMBER_IDS] = {
(uintptr_t)&arm_uuid_spec[SIP_SP_CONTENT_CERT_ID],
open_fip
},
[PLAT_SP_CONTENT_CERT_ID] = {
&fip_dev_handle,
(uintptr_t)&arm_uuid_spec[PLAT_SP_CONTENT_CERT_ID],
open_fip
},
#endif
#endif /* ARM_IO_IN_DTB */
#endif /* TRUSTED_BOARD_BOOT */
@ -197,7 +203,7 @@ struct plat_io_policy policies[MAX_NUMBER_IDS] = {
#ifdef IMAGE_BL2
#if TRUSTED_BOARD_BOOT
#define FCONF_ARM_IO_UUID_NUMBER U(20)
#define FCONF_ARM_IO_UUID_NUMBER U(21)
#else
#define FCONF_ARM_IO_UUID_NUMBER U(10)
#endif
@ -234,6 +240,7 @@ static const struct policies_load_info load_info[FCONF_ARM_IO_UUID_NUMBER] = {
{NON_TRUSTED_FW_CONTENT_CERT_ID, "nt_fw_content_cert_uuid"},
#if defined(SPD_spmd)
{SIP_SP_CONTENT_CERT_ID, "sip_sp_content_cert_uuid"},
{PLAT_SP_CONTENT_CERT_ID, "plat_sp_content_cert_uuid"},
#endif
#endif /* TRUSTED_BOARD_BOOT */
};

View File

@ -30,7 +30,13 @@ int fconf_populate_arm_sp(uintptr_t config)
union uuid_helper_t uuid_helper;
unsigned int index = 0;
uint32_t val32;
const unsigned int sp_start_index = SP_PKG1_ID;
bool is_plat_owned = false;
const unsigned int sip_start = SP_PKG1_ID;
unsigned int sip_index = sip_start;
const unsigned int sip_end = sip_start + MAX_SP_IDS / 2;
const unsigned int plat_start = SP_PKG5_ID;
unsigned int plat_index = plat_start;
const unsigned int plat_end = plat_start + MAX_SP_IDS / 2;
/* As libfdt use void *, we can't avoid this cast */
const void *dtb = (void *)config;
@ -45,27 +51,20 @@ int fconf_populate_arm_sp(uintptr_t config)
}
fdt_for_each_subnode(sp_node, dtb, node) {
if (index == MAX_SP_IDS) {
if ((index == MAX_SP_IDS) || (sip_index == sip_end)
|| (plat_index == plat_end)) {
ERROR("FCONF: Reached max number of SPs\n");
return -1;
}
/* Read UUID */
err = fdt_read_uint32_array(dtb, sp_node, "uuid", 4,
uuid_helper.word);
if (err < 0) {
ERROR("FCONF: cannot read SP uuid\n");
return -1;
}
arm_sp.uuids[index] = uuid_helper;
err = fdt_read_uint32(dtb, sp_node, "load-address", &val32);
if (err < 0) {
ERROR("FCONF: cannot read SP load address\n");
return -1;
}
arm_sp.load_addr[index] = val32;
VERBOSE("FCONF: %s UUID %x-%x-%x-%x load_addr=%lx\n",
__func__,
uuid_helper.word[0],
@ -74,8 +73,52 @@ int fconf_populate_arm_sp(uintptr_t config)
uuid_helper.word[3],
arm_sp.load_addr[index]);
/* Add SP information in mem param descriptor */
sp_mem_params_descs[index].image_id = sp_start_index + index;
/* Read Load address */
err = fdt_read_uint32(dtb, sp_node, "load-address", &val32);
if (err < 0) {
ERROR("FCONF: cannot read SP load address\n");
return -1;
}
arm_sp.load_addr[index] = val32;
/* Read owner field only for dualroot CoT */
#if defined(ARM_COT_dualroot)
/* Owner is an optional field, no need to catch error */
fdtw_read_string(dtb, sp_node, "owner",
arm_sp.owner[index], ARM_SP_OWNER_NAME_LEN);
#endif
/* If owner is empty mark it as SiP owned */
if ((strncmp(arm_sp.owner[index], "SiP",
ARM_SP_OWNER_NAME_LEN) == 0) ||
(strncmp(arm_sp.owner[index], "",
ARM_SP_OWNER_NAME_LEN) == 0)) {
is_plat_owned = false;
} else if (strcmp(arm_sp.owner[index], "Plat") == 0) {
is_plat_owned = true;
} else {
ERROR("FCONF: %s is not a valid SP owner\n",
arm_sp.owner[index]);
return -1;
}
/*
* Add SP information in mem param descriptor and IO policies
* structure.
*/
if (is_plat_owned) {
sp_mem_params_descs[index].image_id = plat_index;
policies[plat_index].image_spec =
(uintptr_t)&arm_sp.uuids[index];
policies[plat_index].dev_handle = &fip_dev_handle;
policies[plat_index].check = open_fip;
plat_index++;
} else {
sp_mem_params_descs[index].image_id = sip_index;
policies[sip_index].image_spec =
(uintptr_t)&arm_sp.uuids[index];
policies[sip_index].dev_handle = &fip_dev_handle;
policies[sip_index].check = open_fip;
sip_index++;
}
SET_PARAM_HEAD(&sp_mem_params_descs[index].image_info,
PARAM_IMAGE_BINARY, VERSION_2, 0);
sp_mem_params_descs[index].image_info.image_max_size =
@ -84,13 +127,6 @@ int fconf_populate_arm_sp(uintptr_t config)
INVALID_IMAGE_ID;
sp_mem_params_descs[index].image_info.image_base =
arm_sp.load_addr[index];
/* Add SP information in IO policies structure */
policies[sp_start_index + index].image_spec =
(uintptr_t)&arm_sp.uuids[index];
policies[sp_start_index + index].dev_handle = &fip_dev_handle;
policies[sp_start_index + index].check = open_fip;
index++;
}