Browse Source

Use numbers to identify images instead of names

The Trusted firmware code identifies BL images by name. The platform
port defines a name for each image e.g. the IO framework uses this
mechanism in the platform function plat_get_image_source(). For
a given image name, it returns the handle to the image file which
involves comparing images names. In addition, if the image is
packaged in a FIP, a name comparison is required to find the UUID
for the image. This method is not optimal.

This patch changes the interface between the generic and platform
code with regard to identifying images. The platform port must now
allocate a unique number (ID) for every image. The generic code will
use the image ID instead of the name to access its attributes.

As a result, the plat_get_image_source() function now takes an image
ID as an input parameter. The organisation of data structures within
the IO framework has been rationalised to use an image ID as an index
into an array which contains attributes of the image such as UUID and
name. This prevents the name comparisons.

A new type 'io_uuid_spec_t' has been introduced in the IO framework
to specify images identified by UUID (i.e. when the image is contained
in a FIP file). There is no longer need to maintain a look-up table
[iname_name --> uuid] in the io_fip driver code.

Because image names are no longer mandatory in the platform port, the
debug messages in the generic code will show the image identifier
instead of the file name. The platforms that support semihosting to
load images (i.e. FVP) must provide the file names as definitions
private to the platform.

The ARM platform ports and documentation have been updated accordingly.
All ARM platforms reuse the image IDs defined in the platform common
code. These IDs will be used to access other attributes of an image in
subsequent patches.

IMPORTANT: applying this patch breaks compatibility for platforms that
use TF BL1 or BL2 images or the image loading code. The platform port
must be updated to match the new interface.

Change-Id: I9c1b04cb1a0684c6ee65dee66146dd6731751ea5
pull/315/head
Juan Castillo 10 years ago
parent
commit
16948ae1d9
  1. 6
      bl1/bl1_main.c
  2. 54
      bl2/bl2_main.c
  3. 41
      common/bl_common.c
  4. 143
      docs/porting-guide.md
  5. 78
      drivers/io/io_fip.c
  6. 4
      include/common/bl_common.h
  7. 6
      include/drivers/io/io_storage.h
  8. 5
      include/plat/arm/common/plat_arm.h
  9. 42
      include/plat/common/common_def.h
  10. 2
      include/plat/common/platform.h
  11. 86
      plat/arm/board/fvp/fvp_io_storage.c
  12. 221
      plat/arm/common/arm_io_storage.c

6
bl1/bl1_main.c

@ -157,6 +157,8 @@ void bl1_main(void)
/* Find out how much free trusted ram remains after BL1 load */
bl1_tzram_layout = bl1_plat_sec_mem_layout();
INFO("BL1: Loading BL2\n");
#if TRUSTED_BOARD_BOOT
/* Initialize authentication module */
auth_init();
@ -168,7 +170,7 @@ void bl1_main(void)
* etc.) so it can be used later.
*/
err = load_image(bl1_tzram_layout,
BL2_CERT_NAME,
BL2_CERT_ID,
BL2_BASE,
&bl2_image_info,
NULL);
@ -187,7 +189,7 @@ void bl1_main(void)
/* Load the BL2 image */
err = load_image(bl1_tzram_layout,
BL2_IMAGE_NAME,
BL2_IMAGE_ID,
BL2_BASE,
&bl2_image_info,
&bl2_ep);

54
bl2/bl2_main.c

@ -36,6 +36,7 @@
#include <debug.h>
#include <platform.h>
#include <platform_def.h>
#include <stdint.h>
#include "bl2_private.h"
#if TRUSTED_BOARD_BOOT
@ -45,20 +46,24 @@ static int bl32_cert_error;
#endif
/*
* Load and authenticate the key and content certificates for a BL3-x image
* Load and authenticate the key and content certificates for a BL3-x image.
* The _blob values identify the authentication objects (an object may be seen
* as a single stage in the authentication process). See auth.h for the complete
* list of objects. The _id values are passed to the IO framework to identify
* the images to load.
*
* Parameters:
* key_cert_blob: key certificate blob id (see auth.h)
* key_cert_name: key certificate filename
* key_cert_id: key certificate image identifier (for IO framework)
* cont_cert_blob: content certificate blob id (see auth.h)
* cont_cert_name: content certificate filename
* cont_cert_id: content certificate image identifier (for IO framework)
* mem_layout: Trusted SRAM memory layout
* load_addr: load the certificates at this address
*
* Return: 0 = success, Otherwise = error
*/
static int load_cert_bl3x(int key_cert_blob, const char *key_cert_name,
int cont_cert_blob, const char *cont_cert_name,
static int load_cert_bl3x(unsigned int key_cert_blob, unsigned int key_cert_id,
unsigned int cont_cert_blob, unsigned int cont_cert_id,
meminfo_t *mem_layout, uint64_t load_addr)
{
image_info_t image_info;
@ -66,31 +71,32 @@ static int load_cert_bl3x(int key_cert_blob, const char *key_cert_name,
/* Load Key certificate */
image_info.h.version = VERSION_1;
err = load_image(mem_layout, key_cert_name, load_addr, &image_info, NULL);
err = load_image(mem_layout, key_cert_id, load_addr, &image_info, NULL);
if (err) {
ERROR("Cannot load %s.\n", key_cert_name);
ERROR("Cannot load key certificate id=%u\n", key_cert_id);
return err;
}
err = auth_verify_obj(key_cert_blob, image_info.image_base,
image_info.image_size);
if (err) {
ERROR("Invalid key certificate %s.\n", key_cert_name);
ERROR("Invalid key certificate id=%u\n", key_cert_id);
return err;
}
/* Load Content certificate */
image_info.h.version = VERSION_1;
err = load_image(mem_layout, cont_cert_name, load_addr, &image_info, NULL);
err = load_image(mem_layout, cont_cert_id, load_addr, &image_info, NULL);
if (err) {
ERROR("Cannot load %s.\n", cont_cert_name);
ERROR("Cannot load content certificate id=%u\n",
cont_cert_id);
return err;
}
err = auth_verify_obj(cont_cert_blob, image_info.image_base,
image_info.image_size);
if (err) {
ERROR("Invalid content certificate %s.\n", cont_cert_name);
ERROR("Invalid content certificate id=%u\n", cont_cert_id);
return err;
}
@ -115,7 +121,7 @@ static int load_certs(void)
/* Load the Trusted Key certificate in the BL31 region */
image_info.h.version = VERSION_1;
err = load_image(mem_layout, TRUSTED_KEY_CERT_NAME, load_addr,
err = load_image(mem_layout, TRUSTED_KEY_CERT_ID, load_addr,
&image_info, NULL);
if (err) {
ERROR("Failed to load Trusted Key certificate.\n");
@ -132,8 +138,8 @@ static int load_certs(void)
/* Load and validate Key and Content certificates for BL3-x images */
#ifdef BL30_BASE
err = load_cert_bl3x(AUTH_BL30_KEY_CERT, BL30_KEY_CERT_NAME,
AUTH_BL30_IMG_CERT, BL30_CERT_NAME,
err = load_cert_bl3x(AUTH_BL30_KEY_CERT, BL30_KEY_CERT_ID,
AUTH_BL30_IMG_CERT, BL30_CERT_ID,
mem_layout, load_addr);
if (err) {
ERROR("Failed to verify BL3-0 authenticity\n");
@ -141,8 +147,8 @@ static int load_certs(void)
}
#endif /* BL30_BASE */
err = load_cert_bl3x(AUTH_BL31_KEY_CERT, BL31_KEY_CERT_NAME,
AUTH_BL31_IMG_CERT, BL31_CERT_NAME,
err = load_cert_bl3x(AUTH_BL31_KEY_CERT, BL31_KEY_CERT_ID,
AUTH_BL31_IMG_CERT, BL31_CERT_ID,
mem_layout, load_addr);
if (err) {
ERROR("Failed to verify BL3-1 authenticity\n");
@ -152,8 +158,8 @@ static int load_certs(void)
#ifdef BL32_BASE
/* BL3-2 image is optional, but keep the return value in case the
* image is present but the certificate is missing */
err = load_cert_bl3x(AUTH_BL32_KEY_CERT, BL32_KEY_CERT_NAME,
AUTH_BL32_IMG_CERT, BL32_CERT_NAME,
err = load_cert_bl3x(AUTH_BL32_KEY_CERT, BL32_KEY_CERT_ID,
AUTH_BL32_IMG_CERT, BL32_CERT_ID,
mem_layout, load_addr);
if (err) {
WARN("Failed to verify BL3-2 authenticity\n");
@ -161,8 +167,8 @@ static int load_certs(void)
bl32_cert_error = err;
#endif /* BL32_BASE */
err = load_cert_bl3x(AUTH_BL33_KEY_CERT, BL33_KEY_CERT_NAME,
AUTH_BL33_IMG_CERT, BL33_CERT_NAME,
err = load_cert_bl3x(AUTH_BL33_KEY_CERT, BL33_KEY_CERT_ID,
AUTH_BL33_IMG_CERT, BL33_CERT_ID,
mem_layout, load_addr);
if (err) {
ERROR("Failed to verify BL3-3 authenticity\n");
@ -200,7 +206,7 @@ static int load_bl30(void)
bl2_plat_get_bl30_meminfo(&bl30_mem_info);
bl30_image_info.h.version = VERSION_1;
e = load_image(&bl30_mem_info,
BL30_IMAGE_NAME,
BL30_IMAGE_ID,
BL30_BASE,
&bl30_image_info,
NULL);
@ -257,7 +263,7 @@ static int load_bl31(bl31_params_t *bl2_to_bl31_params,
/* Load the BL3-1 image */
e = load_image(bl2_tzram_layout,
BL31_IMAGE_NAME,
BL31_IMAGE_ID,
BL31_BASE,
bl2_to_bl31_params->bl31_image_info,
bl31_ep_info);
@ -309,7 +315,7 @@ static int load_bl32(bl31_params_t *bl2_to_bl31_params)
*/
bl2_plat_get_bl32_meminfo(&bl32_mem_info);
e = load_image(&bl32_mem_info,
BL32_IMAGE_NAME,
BL32_IMAGE_ID,
BL32_BASE,
bl2_to_bl31_params->bl32_image_info,
bl2_to_bl31_params->bl32_ep_info);
@ -362,7 +368,7 @@ static int load_bl33(bl31_params_t *bl2_to_bl31_params)
/* Load the BL3-3 image in non-secure memory provided by the platform */
e = load_image(&bl33_mem_info,
BL33_IMAGE_NAME,
BL33_IMAGE_ID,
plat_get_ns_image_entrypoint(),
bl2_to_bl31_params->bl33_image_info,
bl2_to_bl31_params->bl33_ep_info);

41
common/bl_common.c

@ -156,7 +156,7 @@ static void dump_load_info(unsigned long image_load_addr,
}
/* Generic function to return the size of an image */
unsigned long image_size(const char *image_name)
unsigned long image_size(unsigned int image_id)
{
uintptr_t dev_handle;
uintptr_t image_handle;
@ -164,29 +164,27 @@ unsigned long image_size(const char *image_name)
size_t image_size = 0;
int io_result = IO_FAIL;
assert(image_name != NULL);
/* Obtain a reference to the image by querying the platform layer */
io_result = plat_get_image_source(image_name, &dev_handle, &image_spec);
io_result = plat_get_image_source(image_id, &dev_handle, &image_spec);
if (io_result != IO_SUCCESS) {
WARN("Failed to obtain reference to image '%s' (%i)\n",
image_name, io_result);
WARN("Failed to obtain reference to image id=%u (%i)\n",
image_id, io_result);
return 0;
}
/* Attempt to access the image */
io_result = io_open(dev_handle, image_spec, &image_handle);
if (io_result != IO_SUCCESS) {
WARN("Failed to access image '%s' (%i)\n",
image_name, io_result);
WARN("Failed to access image id=%u (%i)\n",
image_id, io_result);
return 0;
}
/* Find the size of the image */
io_result = io_size(image_handle, &image_size);
if ((io_result != IO_SUCCESS) || (image_size == 0)) {
WARN("Failed to determine the size of the image '%s' file (%i)\n",
image_name, io_result);
WARN("Failed to determine the size of the image id=%u (%i)\n",
image_id, io_result);
}
io_result = io_close(image_handle);
/* Ignore improbable/unrecoverable error in 'close' */
@ -210,7 +208,7 @@ unsigned long image_size(const char *image_name)
* Returns 0 on success, a negative error code otherwise.
******************************************************************************/
int load_image(meminfo_t *mem_layout,
const char *image_name,
unsigned int image_id,
uint64_t image_base,
image_info_t *image_data,
entry_point_info_t *entry_point_info)
@ -223,33 +221,32 @@ int load_image(meminfo_t *mem_layout,
int io_result = IO_FAIL;
assert(mem_layout != NULL);
assert(image_name != NULL);
assert(image_data != NULL);
assert(image_data->h.version >= VERSION_1);
/* Obtain a reference to the image by querying the platform layer */
io_result = plat_get_image_source(image_name, &dev_handle, &image_spec);
io_result = plat_get_image_source(image_id, &dev_handle, &image_spec);
if (io_result != IO_SUCCESS) {
WARN("Failed to obtain reference to image '%s' (%i)\n",
image_name, io_result);
WARN("Failed to obtain reference to image id=%u (%i)\n",
image_id, io_result);
return io_result;
}
/* Attempt to access the image */
io_result = io_open(dev_handle, image_spec, &image_handle);
if (io_result != IO_SUCCESS) {
WARN("Failed to access image '%s' (%i)\n",
image_name, io_result);
WARN("Failed to access image id=%u (%i)\n",
image_id, io_result);
return io_result;
}
INFO("Loading file '%s' at address 0x%lx\n", image_name, image_base);
INFO("Loading image id=%u at address 0x%lx\n", image_id, image_base);
/* Find the size of the image */
io_result = io_size(image_handle, &image_size);
if ((io_result != IO_SUCCESS) || (image_size == 0)) {
WARN("Failed to determine the size of the image '%s' file (%i)\n",
image_name, io_result);
WARN("Failed to determine the size of the image id=%u (%i)\n",
image_id, io_result);
goto exit;
}
@ -267,7 +264,7 @@ int load_image(meminfo_t *mem_layout,
/* TODO: Consider whether to try to recover/retry a partially successful read */
io_result = io_read(image_handle, image_base, image_size, &bytes_read);
if ((io_result != IO_SUCCESS) || (bytes_read < image_size)) {
WARN("Failed to load '%s' file (%i)\n", image_name, io_result);
WARN("Failed to load image id=%u (%i)\n", image_id, io_result);
goto exit;
}
@ -298,7 +295,7 @@ int load_image(meminfo_t *mem_layout,
*/
flush_dcache_range(image_base, image_size);
INFO("File '%s' loaded: 0x%lx - 0x%lx\n", image_name, image_base,
INFO("Image id=%u loaded: 0x%lx - 0x%lx\n", image_id, image_base,
image_base + image_size);
exit:

143
docs/porting-guide.md

@ -134,51 +134,6 @@ platform port to define additional platform porting constants in
Defines the character string printed by BL1 upon entry into the `bl1_main()`
function.
* **#define : BL2_IMAGE_NAME**
Name of the BL2 binary image on the host file-system. This name is used by
BL1 to load BL2 into secure memory from non-volatile storage.
* **#define : BL31_IMAGE_NAME**
Name of the BL3-1 binary image on the host file-system. This name is used by
BL2 to load BL3-1 into secure memory from platform storage.
* **#define : BL33_IMAGE_NAME**
Name of the BL3-3 binary image on the host file-system. This name is used by
BL2 to load BL3-3 into non-secure memory from platform storage.
* **#define : BL2_CERT_NAME**
Name of the BL2 content certificate on the host file-system (mandatory when
Trusted Board Boot is enabled).
* **#define : TRUSTED_KEY_CERT_NAME**
Name of the Trusted Key certificate on the host file-system (mandatory when
Trusted Board Boot is enabled).
* **#define : BL31_KEY_CERT_NAME**
Name of the BL3-1 Key certificate on the host file-system (mandatory when
Trusted Board Boot is enabled).
* **#define : BL31_CERT_NAME**
Name of the BL3-1 Content certificate on the host file-system (mandatory
when Trusted Board Boot is enabled).
* **#define : BL33_KEY_CERT_NAME**
Name of the BL3-3 Key certificate on the host file-system (mandatory when
Trusted Board Boot is enabled).
* **#define : BL33_CERT_NAME**
Name of the BL3-3 Content certificate on the host file-system (mandatory
when Trusted Board Boot is enabled).
* **#define : PLATFORM_CORE_COUNT**
Defines the total number of CPUs implemented by the platform across all
@ -243,42 +198,93 @@ platform port to define additional platform porting constants in
Defines the base address in non-secure DRAM where BL2 loads the BL3-3 binary
image. Must be aligned on a page-size boundary.
For every image, the platform must define individual identifiers that will be
used by BL1 or BL2 to load the corresponding image into memory from non-volatile
storage. For the sake of performance, integer numbers will be used as
identifiers. The platform will use those identifiers to return the relevant
information about the image to be loaded (file handler, load address,
authentication information, etc.). The following image identifiers are
mandatory:
* **#define : BL2_IMAGE_ID**
BL2 image identifier, used by BL1 to load BL2.
* **#define : BL31_IMAGE_ID**
BL3-1 image identifier, used by BL2 to load BL3-1.
* **#define : BL33_IMAGE_ID**
BL3-3 image identifier, used by BL2 to load BL3-3.
If Trusted Board Boot is enabled, the following certificate identifiers must
also be defined:
* **#define : BL2_CERT_ID**
BL2 content certificate identifier, used by BL1 to load the BL2 content
certificate.
* **#define : TRUSTED_KEY_CERT_ID**
Trusted key certificate identifier, used by BL2 to load the trusted key
certificate.
* **#define : BL31_KEY_CERT_ID**
BL3-1 key certificate identifier, used by BL2 to load the BL3-1 key
certificate.
* **#define : BL31_CERT_ID**
BL3-1 content certificate identifier, used by BL2 to load the BL3-1 content
certificate.
* **#define : BL33_KEY_CERT_ID**
BL3-3 key certificate identifier, used by BL2 to load the BL3-3 key
certificate.
* **#define : BL33_CERT_ID**
BL3-3 content certificate identifier, used by BL2 to load the BL3-3 content
certificate.
If a BL3-0 image is supported by the platform, the following constants must
also be defined:
* **#define : BL30_IMAGE_NAME**
* **#define : BL30_IMAGE_ID**
Name of the BL3-0 binary image on the host file-system. This name is used by
BL2 to load BL3-0 into secure memory from platform storage before being
transfered to the SCP.
BL3-0 image identifier, used by BL2 to load BL3-0 into secure memory from
platform storage before being transfered to the SCP.
* **#define : BL30_KEY_CERT_NAME**
* **#define : BL30_KEY_CERT_ID**
Name of the BL3-0 Key certificate on the host file-system (mandatory when
Trusted Board Boot is enabled).
BL3-0 key certificate identifier, used by BL2 to load the BL3-0 key
certificate (mandatory when Trusted Board Boot is enabled).
* **#define : BL30_CERT_NAME**
* **#define : BL30_CERT_ID**
Name of the BL3-0 Content certificate on the host file-system (mandatory
when Trusted Board Boot is enabled).
BL3-0 content certificate identifier, used by BL2 to load the BL3-0 content
certificate (mandatory when Trusted Board Boot is enabled).
If a BL3-2 image is supported by the platform, the following constants must
also be defined:
* **#define : BL32_IMAGE_NAME**
* **#define : BL32_IMAGE_ID**
Name of the BL3-2 binary image on the host file-system. This name is used by
BL2 to load BL3-2 into secure memory from platform storage.
BL3-2 image identifier, used by BL2 to load BL3-2.
* **#define : BL32_KEY_CERT_NAME**
* **#define : BL32_KEY_CERT_ID**
Name of the BL3-2 Key certificate on the host file-system (mandatory when
Trusted Board Boot is enabled).
BL3-2 key certificate identifier, used by BL2 to load the BL3-2 key
certificate (mandatory when Trusted Board Boot is enabled).
* **#define : BL32_CERT_NAME**
* **#define : BL32_CERT_ID**
Name of the BL3-2 Content certificate on the host file-system (mandatory
when Trusted Board Boot is enabled).
BL3-2 content certificate identifier, used by BL2 to load the BL3-2 content
certificate (mandatory when Trusted Board Boot is enabled).
* **#define : BL32_BASE**
@ -1528,10 +1534,11 @@ provide at least one driver for a device capable of supporting generic
operations such as loading a bootloader image.
The current implementation only allows for known images to be loaded by the
firmware. These images are specified by using their names, as defined in
[include/plat/common/platform.h]. The platform layer (`plat_get_image_source()`)
then returns a reference to a device and a driver-specific `spec` which will be
understood by the driver to allow access to the image data.
firmware. These images are specified by using their identifiers, as defined in
[include/plat/common/platform_def.h] (or a separate header file included from
there). The platform layer (`plat_get_image_source()`) then returns a reference
to a device and a driver-specific `spec` which will be understood by the driver
to allow access to the image data.
The layer is designed in such a way that is it possible to chain drivers with
other drivers. For example, file-system drivers may be implemented on top of

78
drivers/io/io_fip.c

@ -50,11 +50,6 @@
x.node[0], x.node[1], x.node[2], x.node[3], \
x.node[4], x.node[5]
typedef struct {
const char *name;
const uuid_t uuid;
} plat_fip_name_uuid_t;
typedef struct {
/* Put file_pos above the struct to allow {0} on static init.
* It is a workaround for a known bug in GCC
@ -64,37 +59,6 @@ typedef struct {
fip_toc_entry_t entry;
} file_state_t;
static const plat_fip_name_uuid_t name_uuid[] = {
{BL2_IMAGE_NAME, UUID_TRUSTED_BOOT_FIRMWARE_BL2},
#ifdef BL30_IMAGE_NAME
/* BL3-0 is optional in the platform */
{BL30_IMAGE_NAME, UUID_SCP_FIRMWARE_BL30},
#endif /* BL30_IMAGE_NAME */
{BL31_IMAGE_NAME, UUID_EL3_RUNTIME_FIRMWARE_BL31},
#ifdef BL32_IMAGE_NAME
/* BL3-2 is optional in the platform */
{BL32_IMAGE_NAME, UUID_SECURE_PAYLOAD_BL32},
#endif /* BL32_IMAGE_NAME */
{BL33_IMAGE_NAME, UUID_NON_TRUSTED_FIRMWARE_BL33},
#if TRUSTED_BOARD_BOOT
/* Certificates */
{BL2_CERT_NAME, UUID_TRUSTED_BOOT_FIRMWARE_BL2_CERT},
{TRUSTED_KEY_CERT_NAME, UUID_TRUSTED_KEY_CERT},
#ifdef BL30_KEY_CERT_NAME
{BL30_KEY_CERT_NAME, UUID_SCP_FIRMWARE_BL30_KEY_CERT},
#endif
{BL31_KEY_CERT_NAME, UUID_EL3_RUNTIME_FIRMWARE_BL31_KEY_CERT},
{BL32_KEY_CERT_NAME, UUID_SECURE_PAYLOAD_BL32_KEY_CERT},
{BL33_KEY_CERT_NAME, UUID_NON_TRUSTED_FIRMWARE_BL33_KEY_CERT},
#ifdef BL30_CERT_NAME
{BL30_CERT_NAME, UUID_SCP_FIRMWARE_BL30_CERT},
#endif
{BL31_CERT_NAME, UUID_EL3_RUNTIME_FIRMWARE_BL31_CERT},
{BL32_CERT_NAME, UUID_SECURE_PAYLOAD_BL32_CERT},
{BL33_CERT_NAME, UUID_NON_TRUSTED_FIRMWARE_BL33_CERT},
#endif /* TRUSTED_BOARD_BOOT */
};
static const uuid_t uuid_null = {0};
static file_state_t current_file = {0};
static uintptr_t backend_dev_handle;
@ -113,13 +77,6 @@ static int fip_dev_init(io_dev_info_t *dev_info, const uintptr_t init_params);
static int fip_dev_close(io_dev_info_t *dev_info);
static inline int copy_uuid(uuid_t *dst, const uuid_t *src)
{
memcpy(dst, src, sizeof(uuid_t));
return 0;
}
/* Return 0 for equal uuids. */
static inline int compare_uuids(const uuid_t *uuid1, const uuid_t *uuid2)
{
@ -138,22 +95,6 @@ static inline int is_valid_header(fip_toc_header_t *header)
}
static int file_to_uuid(const char *filename, uuid_t *uuid)
{
int i;
int status = -EINVAL;
for (i = 0; i < ARRAY_SIZE(name_uuid); i++) {
if (strcmp(filename, name_uuid[i].name) == 0) {
copy_uuid(uuid, &name_uuid[i].uuid);
status = 0;
break;
}
}
return status;
}
/* Identify the device type as a virtual driver */
io_type_t device_type_fip(void)
{
@ -201,17 +142,17 @@ static int fip_dev_open(const uintptr_t dev_spec __attribute__((unused)),
static int fip_dev_init(io_dev_info_t *dev_info, const uintptr_t init_params)
{
int result = IO_FAIL;
char *image_name = (char *)init_params;
unsigned int image_id = (unsigned int)init_params;
uintptr_t backend_handle;
fip_toc_header_t header;
size_t bytes_read;
/* Obtain a reference to the image by querying the platform layer */
result = plat_get_image_source(image_name, &backend_dev_handle,
result = plat_get_image_source(image_id, &backend_dev_handle,
&backend_image_spec);
if (result != IO_SUCCESS) {
WARN("Failed to obtain reference to image '%s' (%i)\n",
image_name, result);
WARN("Failed to obtain reference to image id=%u (%i)\n",
image_id, result);
result = IO_FAIL;
goto fip_dev_init_exit;
}
@ -220,7 +161,7 @@ static int fip_dev_init(io_dev_info_t *dev_info, const uintptr_t init_params)
result = io_open(backend_dev_handle, backend_image_spec,
&backend_handle);
if (result != IO_SUCCESS) {
WARN("Failed to access image '%s' (%i)\n", image_name, result);
WARN("Failed to access image id=%u (%i)\n", image_id, result);
result = IO_FAIL;
goto fip_dev_init_exit;
}
@ -261,12 +202,11 @@ static int fip_file_open(io_dev_info_t *dev_info, const uintptr_t spec,
{
int result = IO_FAIL;
uintptr_t backend_handle;
uuid_t file_uuid;
const io_file_spec_t *file_spec = (io_file_spec_t *)spec;
const io_uuid_spec_t *uuid_spec = (io_uuid_spec_t *)spec;
size_t bytes_read;
int found_file = 0;
assert(file_spec != NULL);
assert(uuid_spec != NULL);
assert(entity != NULL);
/* Can only have one file open at a time for the moment. We need to
@ -297,8 +237,6 @@ static int fip_file_open(io_dev_info_t *dev_info, const uintptr_t spec,
goto fip_file_open_close;
}
file_to_uuid(file_spec->path, &file_uuid);
found_file = 0;
do {
result = io_read(backend_handle,
@ -307,7 +245,7 @@ static int fip_file_open(io_dev_info_t *dev_info, const uintptr_t spec,
&bytes_read);
if (result == IO_SUCCESS) {
if (compare_uuids(&current_file.entry.uuid,
&file_uuid) == 0) {
&uuid_spec->uuid) == 0) {
found_file = 1;
break;
}

4
include/common/bl_common.h

@ -226,9 +226,9 @@ CASSERT(sizeof(unsigned long) ==
******************************************************************************/
unsigned long page_align(unsigned long, unsigned);
void change_security_state(unsigned int);
unsigned long image_size(const char *);
unsigned long image_size(unsigned int image_id);
int load_image(meminfo_t *mem_layout,
const char *image_name,
unsigned int image_id,
uint64_t image_base,
image_info_t *image_data,
entry_point_info_t *entry_point_info);

6
include/drivers/io/io_storage.h

@ -33,6 +33,7 @@
#include <stdint.h>
#include <stdio.h> /* For ssize_t */
#include <uuid.h>
/* Device type which can be used to enable policy decisions about which device
@ -67,6 +68,11 @@ typedef struct io_file_spec {
unsigned int mode;
} io_file_spec_t;
/* UUID specification - used to refer to data accessed using UUIDs (i.e. FIP
* images) */
typedef struct io_uuid_spec {
const uuid_t uuid;
} io_uuid_spec_t;
/* Block specification - used to refer to data on a device supporting
* block-like entities */

5
include/plat/arm/common/plat_arm.h

@ -196,8 +196,9 @@ void plat_arm_pwrc_setup(void);
*/
void plat_arm_io_setup(void);
int plat_arm_get_alt_image_source(
const uintptr_t image_spec,
uintptr_t *dev_handle);
unsigned int image_id,
uintptr_t *dev_handle,
uintptr_t *image_spec);
void plat_arm_topology_setup(void);

42
include/plat/common/common_def.h

@ -47,38 +47,40 @@
*/
#define FIRMWARE_WELCOME_STR "Booting Trusted Firmware\n"
/* Firmware Image Package */
#define FIP_IMAGE_ID 0
/* Trusted Boot Firmware BL2 */
#define BL2_IMAGE_NAME "bl2.bin"
#define BL2_IMAGE_ID 1
/* SCP Firmware BL3-0 */
#define BL30_IMAGE_NAME "bl30.bin"
#define BL30_IMAGE_ID 2
/* EL3 Runtime Firmware BL31 */
#define BL31_IMAGE_NAME "bl31.bin"
#define BL31_IMAGE_ID 3
/* Secure Payload BL32 (Trusted OS) */
#define BL32_IMAGE_NAME "bl32.bin"
#define BL32_IMAGE_ID 4
/* Non-Trusted Firmware BL33 */
#define BL33_IMAGE_NAME "bl33.bin"
/* Firmware Image Package */
#define FIP_IMAGE_NAME "fip.bin"
#define BL33_IMAGE_ID 5
#if TRUSTED_BOARD_BOOT
/* Certificates */
# define BL2_CERT_NAME "bl2.crt"
# define TRUSTED_KEY_CERT_NAME "trusted_key.crt"
# define BL30_KEY_CERT_NAME "bl30_key.crt"
# define BL31_KEY_CERT_NAME "bl31_key.crt"
# define BL32_KEY_CERT_NAME "bl32_key.crt"
# define BL33_KEY_CERT_NAME "bl33_key.crt"
# define BL30_CERT_NAME "bl30.crt"
# define BL31_CERT_NAME "bl31.crt"
# define BL32_CERT_NAME "bl32.crt"
# define BL33_CERT_NAME "bl33.crt"
#define BL2_CERT_ID 6
#define TRUSTED_KEY_CERT_ID 7
#define BL30_KEY_CERT_ID 8
#define BL31_KEY_CERT_ID 9
#define BL32_KEY_CERT_ID 10
#define BL33_KEY_CERT_ID 11
#define BL30_CERT_ID 12
#define BL31_CERT_ID 13
#define BL32_CERT_ID 14
#define BL33_CERT_ID 15
#endif /* TRUSTED_BOARD_BOOT */
/*

2
include/plat/common/platform.h

@ -50,7 +50,7 @@ struct bl31_params;
* Mandatory common functions
******************************************************************************/
uint64_t plat_get_syscnt_freq(void);
int plat_get_image_source(const char *image_name,
int plat_get_image_source(unsigned int image_id,
uintptr_t *dev_handle,
uintptr_t *image_spec);
unsigned long plat_get_ns_image_entrypoint(void);

86
plat/arm/board/fvp/fvp_io_storage.c

@ -29,16 +29,88 @@
*/
#include <assert.h>
#include <common_def.h>
#include <debug.h>
#include <io_driver.h>
#include <io_storage.h>
#include <io_semihosting.h>
#include <plat_arm.h>
#include <semihosting.h> /* For FOPEN_MODE_... */
/* Semihosting filenames */
#define BL2_IMAGE_NAME "bl2.bin"
#define BL31_IMAGE_NAME "bl31.bin"
#define BL32_IMAGE_NAME "bl32.bin"
#define BL33_IMAGE_NAME "bl33.bin"
#if TRUSTED_BOARD_BOOT
#define BL2_CERT_NAME "bl2.crt"
#define TRUSTED_KEY_CERT_NAME "trusted_key.crt"
#define BL31_KEY_CERT_NAME "bl31_key.crt"
#define BL32_KEY_CERT_NAME "bl32_key.crt"
#define BL33_KEY_CERT_NAME "bl33_key.crt"
#define BL31_CERT_NAME "bl31.crt"
#define BL32_CERT_NAME "bl32.crt"
#define BL33_CERT_NAME "bl33.crt"
#endif /* TRUSTED_BOARD_BOOT */
/* IO devices */
static const io_dev_connector_t *sh_dev_con;
static uintptr_t sh_dev_handle;
static const io_file_spec_t sh_file_spec[] = {
[BL2_IMAGE_ID] = {
.path = BL2_IMAGE_NAME,
.mode = FOPEN_MODE_RB
},
[BL31_IMAGE_ID] = {
.path = BL31_IMAGE_NAME,
.mode = FOPEN_MODE_RB
},
[BL32_IMAGE_ID] = {
.path = BL32_IMAGE_NAME,
.mode = FOPEN_MODE_RB
},
[BL33_IMAGE_ID] = {
.path = BL33_IMAGE_NAME,
.mode = FOPEN_MODE_RB
},
#if TRUSTED_BOARD_BOOT
[BL2_CERT_ID] = {
.path = BL2_CERT_NAME,
.mode = FOPEN_MODE_RB
},
[TRUSTED_KEY_CERT_ID] = {
.path = TRUSTED_KEY_CERT_NAME,
.mode = FOPEN_MODE_RB
},
[BL31_KEY_CERT_ID] = {
.path = BL31_KEY_CERT_NAME,
.mode = FOPEN_MODE_RB
},
[BL32_KEY_CERT_ID] = {
.path = BL32_KEY_CERT_NAME,
.mode = FOPEN_MODE_RB
},
[BL33_KEY_CERT_ID] = {
.path = BL33_KEY_CERT_NAME,
.mode = FOPEN_MODE_RB
},
[BL31_CERT_ID] = {
.path = BL31_CERT_NAME,
.mode = FOPEN_MODE_RB
},
[BL32_CERT_ID] = {
.path = BL32_CERT_NAME,
.mode = FOPEN_MODE_RB
},
[BL33_CERT_ID] = {
.path = BL33_CERT_NAME,
.mode = FOPEN_MODE_RB
},
#endif /* TRUSTED_BOARD_BOOT */
};
static int open_semihosting(const uintptr_t spec)
{
@ -75,13 +147,17 @@ void plat_arm_io_setup(void)
(void)io_result;
}
int plat_arm_get_alt_image_source(
const uintptr_t image_spec,
uintptr_t *dev_handle)
/*
* FVP provides semihosting as an alternative to load images
*/
int plat_arm_get_alt_image_source(unsigned int image_id, uintptr_t *dev_handle,
uintptr_t *image_spec)
{
int result = open_semihosting(image_spec);
if (result == IO_SUCCESS)
int result = open_semihosting((const uintptr_t)&sh_file_spec[image_id]);
if (result == IO_SUCCESS) {
*dev_handle = sh_dev_handle;
*image_spec = (uintptr_t)&sh_file_spec[image_id];
}
return result;
}

221
plat/arm/common/arm_io_storage.c

@ -28,13 +28,14 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <assert.h>
#include <bl_common.h> /* For ARRAY_SIZE */
#include <debug.h>
#include <firmware_image_package.h>
#include <io_driver.h>
#include <io_fip.h>
#include <io_memmap.h>
#include <io_storage.h>
#include <platform_def.h>
#include <semihosting.h> /* For FOPEN_MODE_... */
#include <string.h>
/* IO devices */
@ -48,179 +49,162 @@ static const io_block_spec_t fip_block_spec = {
.length = PLAT_ARM_FIP_MAX_SIZE
};
static const io_file_spec_t bl2_file_spec = {
.path = BL2_IMAGE_NAME,
.mode = FOPEN_MODE_RB
static const io_uuid_spec_t bl2_uuid_spec = {
.uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2,
};
static const io_file_spec_t bl30_file_spec = {
.path = BL30_IMAGE_NAME,
.mode = FOPEN_MODE_RB
static const io_uuid_spec_t bl30_uuid_spec = {
.uuid = UUID_SCP_FIRMWARE_BL30,
};
static const io_file_spec_t bl31_file_spec = {
.path = BL31_IMAGE_NAME,
.mode = FOPEN_MODE_RB
static const io_uuid_spec_t bl31_uuid_spec = {
.uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31,
};
static const io_file_spec_t bl32_file_spec = {
.path = BL32_IMAGE_NAME,
.mode = FOPEN_MODE_RB
static const io_uuid_spec_t bl32_uuid_spec = {
.uuid = UUID_SECURE_PAYLOAD_BL32,
};
static const io_file_spec_t bl33_file_spec = {
.path = BL33_IMAGE_NAME,
.mode = FOPEN_MODE_RB
static const io_uuid_spec_t bl33_uuid_spec = {
.uuid = UUID_NON_TRUSTED_FIRMWARE_BL33,
};
#if TRUSTED_BOARD_BOOT
static const io_file_spec_t bl2_cert_file_spec = {
.path = BL2_CERT_NAME,
.mode = FOPEN_MODE_RB
static const io_uuid_spec_t bl2_cert_uuid_spec = {
.uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2_CERT,
};
static const io_file_spec_t trusted_key_cert_file_spec = {
.path = TRUSTED_KEY_CERT_NAME,
.mode = FOPEN_MODE_RB
static const io_uuid_spec_t trusted_key_cert_uuid_spec = {
.uuid = UUID_TRUSTED_KEY_CERT,
};
static const io_file_spec_t bl30_key_cert_file_spec = {
.path = BL30_KEY_CERT_NAME,
.mode = FOPEN_MODE_RB
static const io_uuid_spec_t bl30_key_cert_uuid_spec = {
.uuid = UUID_SCP_FIRMWARE_BL30_KEY_CERT,
};
static const io_file_spec_t bl31_key_cert_file_spec = {
.path = BL31_KEY_CERT_NAME,
.mode = FOPEN_MODE_RB
static const io_uuid_spec_t bl31_key_cert_uuid_spec = {
.uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31_KEY_CERT,
};
static const io_file_spec_t bl32_key_cert_file_spec = {
.path = BL32_KEY_CERT_NAME,
.mode = FOPEN_MODE_RB
static const io_uuid_spec_t bl32_key_cert_uuid_spec = {
.uuid = UUID_SECURE_PAYLOAD_BL32_KEY_CERT,
};
static const io_file_spec_t bl33_key_cert_file_spec = {
.path = BL33_KEY_CERT_NAME,
.mode = FOPEN_MODE_RB
static const io_uuid_spec_t bl33_key_cert_uuid_spec = {
.uuid = UUID_NON_TRUSTED_FIRMWARE_BL33_KEY_CERT,
};
static const io_file_spec_t bl30_cert_file_spec = {
.path = BL30_CERT_NAME,
.mode = FOPEN_MODE_RB
static const io_uuid_spec_t bl30_cert_uuid_spec = {
.uuid = UUID_SCP_FIRMWARE_BL30_CERT,
};
static const io_file_spec_t bl31_cert_file_spec = {
.path = BL31_CERT_NAME,
.mode = FOPEN_MODE_RB
static const io_uuid_spec_t bl31_cert_uuid_spec = {
.uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31_CERT,
};
static const io_file_spec_t bl32_cert_file_spec = {
.path = BL32_CERT_NAME,
.mode = FOPEN_MODE_RB
static const io_uuid_spec_t bl32_cert_uuid_spec = {
.uuid = UUID_SECURE_PAYLOAD_BL32_CERT,
};
static const io_file_spec_t bl33_cert_file_spec = {
.path = BL33_CERT_NAME,
.mode = FOPEN_MODE_RB
static const io_uuid_spec_t bl33_cert_uuid_spec = {
.uuid = UUID_NON_TRUSTED_FIRMWARE_BL33_CERT,
};
#endif /* TRUSTED_BOARD_BOOT */
static int open_fip(const uintptr_t spec);
static int open_memmap(const uintptr_t spec);
struct plat_io_policy {
const char *image_name;
uintptr_t *dev_handle;
uintptr_t image_spec;
int (*check)(const uintptr_t spec);
};
/* By default, ARM platforms load images from the FIP */
static const struct plat_io_policy policies[] = {
{
FIP_IMAGE_NAME,
[FIP_IMAGE_ID] = {
&memmap_dev_handle,
(uintptr_t)&fip_block_spec,
open_memmap
}, {
BL2_IMAGE_NAME,
},
[BL2_IMAGE_ID] = {
&fip_dev_handle,
(uintptr_t)&bl2_file_spec,
(uintptr_t)&bl2_uuid_spec,
open_fip
}, {
BL30_IMAGE_NAME,
},
[BL30_IMAGE_ID] = {
&fip_dev_handle,
(uintptr_t)&bl30_file_spec,
(uintptr_t)&bl30_uuid_spec,
open_fip
}, {
BL31_IMAGE_NAME,
},
[BL31_IMAGE_ID] = {
&fip_dev_handle,
(uintptr_t)&bl31_file_spec,
(uintptr_t)&bl31_uuid_spec,
open_fip
}, {
BL32_IMAGE_NAME,
},
[BL32_IMAGE_ID] = {
&fip_dev_handle,
(uintptr_t)&bl32_file_spec,
(uintptr_t)&bl32_uuid_spec,
open_fip
}, {
BL33_IMAGE_NAME,
},
[BL33_IMAGE_ID] = {
&fip_dev_handle,
(uintptr_t)&bl33_file_spec,
(uintptr_t)&bl33_uuid_spec,
open_fip
}, {
},
#if TRUSTED_BOARD_BOOT
BL2_CERT_NAME,
[BL2_CERT_ID] = {
&fip_dev_handle,
(uintptr_t)&bl2_cert_file_spec,
(uintptr_t)&bl2_cert_uuid_spec,
open_fip
}, {
TRUSTED_KEY_CERT_NAME,
},
[TRUSTED_KEY_CERT_ID] = {
&fip_dev_handle,
(uintptr_t)&trusted_key_cert_file_spec,
(uintptr_t)&trusted_key_cert_uuid_spec,
open_fip
}, {
BL30_KEY_CERT_NAME,
},
[BL30_KEY_CERT_ID] = {
&fip_dev_handle,
(uintptr_t)&bl30_key_cert_file_spec,
(uintptr_t)&bl30_key_cert_uuid_spec,
open_fip
}, {
BL31_KEY_CERT_NAME,
},
[BL31_KEY_CERT_ID] = {
&fip_dev_handle,
(uintptr_t)&bl31_key_cert_file_spec,
(uintptr_t)&bl31_key_cert_uuid_spec,
open_fip
}, {
BL32_KEY_CERT_NAME,
},
[BL32_KEY_CERT_ID] = {
&fip_dev_handle,
(uintptr_t)&bl32_key_cert_file_spec,
(uintptr_t)&bl32_key_cert_uuid_spec,
open_fip
}, {
BL33_KEY_CERT_NAME,
},
[BL33_KEY_CERT_ID] = {
&fip_dev_handle,
(uintptr_t)&bl33_key_cert_file_spec,
(uintptr_t)&bl33_key_cert_uuid_spec,
open_fip
}, {
BL30_CERT_NAME,
},
[BL30_CERT_ID] = {
&fip_dev_handle,
(uintptr_t)&bl30_cert_file_spec,
(uintptr_t)&bl30_cert_uuid_spec,
open_fip
}, {
BL31_CERT_NAME,
},
[BL31_CERT_ID] = {
&fip_dev_handle,
(uintptr_t)&bl31_cert_file_spec,
(uintptr_t)&bl31_cert_uuid_spec,
open_fip
}, {
BL32_CERT_NAME,
},
[BL32_CERT_ID] = {
&fip_dev_handle,
(uintptr_t)&bl32_cert_file_spec,
(uintptr_t)&bl32_cert_uuid_spec,
open_fip
}, {
BL33_CERT_NAME,
},
[BL33_CERT_ID] = {
&fip_dev_handle,
(uintptr_t)&bl33_cert_file_spec,
(uintptr_t)&bl33_cert_uuid_spec,
open_fip
}, {
},
#endif /* TRUSTED_BOARD_BOOT */
0, 0, 0
}
};
@ -235,7 +219,7 @@ static int open_fip(const uintptr_t spec)
uintptr_t local_image_handle;
/* See if a Firmware Image Package is available */
result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_NAME);
result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID);
if (result == IO_SUCCESS) {
result = io_open(fip_dev_handle, spec, &local_image_handle);
if (result == IO_SUCCESS) {
@ -293,8 +277,9 @@ void plat_arm_io_setup(void)
}
int plat_arm_get_alt_image_source(
const uintptr_t image_spec __attribute__((unused)),
uintptr_t *dev_handle __attribute__((unused)))
unsigned int image_id __attribute__((unused)),
uintptr_t *dev_handle __attribute__((unused)),
uintptr_t *image_spec __attribute__((unused)))
{
/* By default do not try an alternative */
return IO_FAIL;
@ -302,36 +287,24 @@ int plat_arm_get_alt_image_source(
/* 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(const char *image_name, uintptr_t *dev_handle,
int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
uintptr_t *image_spec)
{
int result = IO_FAIL;
const struct plat_io_policy *policy;
if ((image_name != NULL) && (dev_handle != NULL) &&
(image_spec != NULL)) {
policy = policies;
while (policy->image_name != NULL) {
if (strcmp(policy->image_name, image_name) == 0) {
result = policy->check(policy->image_spec);
if (result == IO_SUCCESS) {
*image_spec = policy->image_spec;
*dev_handle = *(policy->dev_handle);
break;
}
VERBOSE("Trying alternative IO\n");
result = plat_arm_get_alt_image_source(
policy->image_spec,
dev_handle);
if (result == IO_SUCCESS) {
*image_spec = policy->image_spec;
break;
}
}
policy++;
}
assert(image_id < ARRAY_SIZE(policies));
policy = &policies[image_id];
result = policy->check(policy->image_spec);
if (result == IO_SUCCESS) {
*image_spec = policy->image_spec;
*dev_handle = *(policy->dev_handle);
} else {
result = IO_FAIL;
VERBOSE("Trying alternative IO\n");
result = plat_arm_get_alt_image_source(image_id, dev_handle,
image_spec);
}
return result;
}

Loading…
Cancel
Save