Browse Source
Use the firmware configuration framework to retrieve information about Secure Partitions to facilitate loading them into memory. To load a SP image we need UUID look-up into FIP and the load address where it needs to be loaded in memory. This patch introduces a SP populator function which gets UUID and load address from firmware config device tree and updates its C data structure. Change-Id: I17faec41803df9a76712dcc8b67cadb1c9daf8cd Signed-off-by: Olivier Deprez <olivier.deprez@arm.com> Signed-off-by: Manish Pandey <manish.pandey2@arm.com>pull/1938/head
Olivier Deprez
5 years ago
committed by
Manish Pandey
4 changed files with 118 additions and 0 deletions
@ -0,0 +1,26 @@ |
|||
/*
|
|||
* Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. |
|||
* |
|||
* SPDX-License-Identifier: BSD-3-Clause |
|||
*/ |
|||
|
|||
#ifndef FCONF_ARM_SP_GETTER_H |
|||
#define FCONF_ARM_SP_GETTER_H |
|||
|
|||
#include <lib/fconf/fconf.h> |
|||
#include <tools_share/uuid.h> |
|||
|
|||
/* arm_sp getter */ |
|||
#define arm__sp_getter(prop) arm_sp.prop |
|||
|
|||
struct arm_sp_t { |
|||
unsigned int number_of_sp; |
|||
union uuid_helper_t uuids[MAX_SP_IDS]; |
|||
uintptr_t load_addr[MAX_SP_IDS]; |
|||
}; |
|||
|
|||
int fconf_populate_arm_sp(uintptr_t config); |
|||
|
|||
extern struct arm_sp_t arm_sp; |
|||
|
|||
#endif /* FCONF_ARM_SP_GETTER_H */ |
@ -0,0 +1,84 @@ |
|||
/*
|
|||
* Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. |
|||
* |
|||
* SPDX-License-Identifier: BSD-3-Clause |
|||
*/ |
|||
|
|||
#include <assert.h> |
|||
|
|||
#include <common/debug.h> |
|||
#include <common/fdt_wrappers.h> |
|||
#include <drivers/io/io_storage.h> |
|||
#include <lib/object_pool.h> |
|||
#include <libfdt.h> |
|||
#include <plat/arm/common/arm_fconf_getter.h> |
|||
#include <plat/arm/common/arm_fconf_io_storage.h> |
|||
#include <plat/arm/common/fconf_arm_sp_getter.h> |
|||
#include <platform_def.h> |
|||
#include <tools_share/firmware_image_package.h> |
|||
|
|||
#ifdef IMAGE_BL2 |
|||
|
|||
struct arm_sp_t arm_sp; |
|||
|
|||
int fconf_populate_arm_sp(uintptr_t config) |
|||
{ |
|||
int sp_node, node, err; |
|||
union uuid_helper_t uuid_helper; |
|||
|
|||
/* As libfdt use void *, we can't avoid this cast */ |
|||
const void *dtb = (void *)config; |
|||
|
|||
/* Assert the node offset point to "arm,sp" compatible property */ |
|||
const char *compatible_str = "arm,sp"; |
|||
|
|||
node = fdt_node_offset_by_compatible(dtb, -1, compatible_str); |
|||
if (node < 0) { |
|||
ERROR("FCONF: Can't find %s in dtb\n", compatible_str); |
|||
return node; |
|||
} |
|||
|
|||
fdt_for_each_subnode(sp_node, dtb, node) { |
|||
err = fdtw_read_array(dtb, sp_node, "uuid", 4, |
|||
&uuid_helper.word); |
|||
if (err < 0) { |
|||
ERROR("FCONF: cannot read SP uuid\n"); |
|||
return -1; |
|||
} |
|||
|
|||
arm_sp.uuids[arm_sp.number_of_sp] = uuid_helper; |
|||
|
|||
err = fdtw_read_cells(dtb, sp_node, "load-address", 1, |
|||
&arm_sp.load_addr[arm_sp.number_of_sp]); |
|||
if (err < 0) { |
|||
ERROR("FCONF: cannot read SP load address\n"); |
|||
return -1; |
|||
} |
|||
|
|||
VERBOSE("FCONF: %s UUID %x-%x-%x-%x load_addr=%lx\n", |
|||
__func__, |
|||
uuid_helper.word[0], |
|||
uuid_helper.word[1], |
|||
uuid_helper.word[2], |
|||
uuid_helper.word[3], |
|||
arm_sp.load_addr[arm_sp.number_of_sp]); |
|||
|
|||
arm_sp.number_of_sp++; |
|||
|
|||
if (arm_sp.number_of_sp >= MAX_SP_IDS) { |
|||
ERROR("FCONF: reached max number of SPs\n"); |
|||
return -1; |
|||
} |
|||
} |
|||
|
|||
if ((sp_node < 0) && (sp_node != -FDT_ERR_NOTFOUND)) { |
|||
ERROR("%d: fdt_for_each_subnode(): %d\n", __LINE__, node); |
|||
return sp_node; |
|||
} |
|||
|
|||
return 0; |
|||
} |
|||
|
|||
FCONF_REGISTER_POPULATOR(arm_sp, fconf_populate_arm_sp); |
|||
|
|||
#endif /* IMAGE_BL2 */ |
Loading…
Reference in new issue