"plat/vscode:/vscode.git/clone" did not exist on "95c3f422d843f00076088ad39075af1ec4c93d8e"
Commit 4112bfa0 authored by Vikram Kanigiri's avatar Vikram Kanigiri
Browse files

Populate BL31 input parameters as per new spec

This patch is based on spec published at
https://github.com/ARM-software/tf-issues/issues/133

It rearranges the bl31_args struct into
bl31_params and bl31_plat_params which provide the
information needed for Trusted firmware and platform
specific data via x0 and x1

On the FVP platform BL3-1 params and BL3-1 plat params
and its constituents are stored at the start of TZDRAM.

The information about memory availability and size for
BL3-1, BL3-2 and BL3-3 is moved into platform specific data.

Change-Id: I8b32057a3d0dd3968ea26c2541a0714177820da9
parent 29fb905d
......@@ -117,7 +117,7 @@ SynchronousExceptionA64:
* BL1 to pass EL3 control to BL31 is expected
* here.
* It expects X0 with RUN_IMAGE SMC function id
* X1 with address of a el_change_info_t structure
* X1 with address of a entry_point_info_t structure
* describing the BL3-1 entrypoint
* ------------------------------------------------
*/
......@@ -136,7 +136,7 @@ SynchronousExceptionA64:
mov x0, x20
bl display_boot_progress
ldp x0, x1, [x20, #EL_CHANGE_INFO_PC_OFFSET]
ldp x0, x1, [x20, #ENTRY_POINT_INFO_PC_OFFSET]
msr elr_el3, x0
msr spsr_el3, x1
ubfx x0, x1, #MODE_EL_SHIFT, #2
......@@ -146,10 +146,10 @@ SynchronousExceptionA64:
bl disable_mmu_icache_el3
tlbi alle3
ldp x6, x7, [x20, #(EL_CHANGE_INFO_ARGS_OFFSET + 0x30)]
ldp x4, x5, [x20, #(EL_CHANGE_INFO_ARGS_OFFSET + 0x20)]
ldp x2, x3, [x20, #(EL_CHANGE_INFO_ARGS_OFFSET + 0x10)]
ldp x0, x1, [x20, #(EL_CHANGE_INFO_ARGS_OFFSET + 0x0)]
ldp x6, x7, [x20, #(ENTRY_POINT_INFO_ARGS_OFFSET + 0x30)]
ldp x4, x5, [x20, #(ENTRY_POINT_INFO_ARGS_OFFSET + 0x20)]
ldp x2, x3, [x20, #(ENTRY_POINT_INFO_ARGS_OFFSET + 0x10)]
ldp x0, x1, [x20, #(ENTRY_POINT_INFO_ARGS_OFFSET + 0x0)]
eret
panic:
mov x0, #SYNC_EXCEPTION_AARCH64
......
......@@ -33,6 +33,7 @@
#include <assert.h>
#include <bl_common.h>
#include <bl1.h>
#include <debug.h>
#include <platform.h>
#include <stdio.h>
#include "bl1_private.h"
......@@ -41,18 +42,18 @@
* Runs BL2 from the given entry point. It results in dropping the
* exception level
******************************************************************************/
static void __dead2 bl1_run_bl2(el_change_info_t *bl2_ep)
static void __dead2 bl1_run_bl2(entry_point_info_t *bl2_ep)
{
bl1_arch_next_el_setup();
/* Tell next EL what we want done */
bl2_ep->args.arg0 = RUN_IMAGE;
if (bl2_ep->security_state == NON_SECURE)
change_security_state(bl2_ep->security_state);
if (GET_SECURITY_STATE(bl2_ep->h.attr) == NON_SECURE)
change_security_state(GET_SECURITY_STATE(bl2_ep->h.attr));
write_spsr_el3(bl2_ep->spsr);
write_elr_el3(bl2_ep->entrypoint);
write_elr_el3(bl2_ep->pc);
eret(bl2_ep->args.arg0,
bl2_ep->args.arg1,
......@@ -77,11 +78,12 @@ void bl1_main(void)
#if DEBUG
unsigned long sctlr_el3 = read_sctlr_el3();
#endif
unsigned long bl2_base;
unsigned int load_type = TOP_LOAD;
image_info_t bl2_image_info = { {0} };
entry_point_info_t bl2_ep = { {0} };
meminfo_t *bl1_tzram_layout;
meminfo_t *bl2_tzram_layout = 0x0;
el_change_info_t bl2_ep = {0};
int err;
/*
* Ensure that MMU/Caches and coherency are turned on
......@@ -100,15 +102,28 @@ void bl1_main(void)
printf(FIRMWARE_WELCOME_STR);
printf("%s\n\r", build_message);
SET_PARAM_HEAD(&bl2_image_info, PARAM_IMAGE_BINARY, VERSION_1, 0);
SET_PARAM_HEAD(&bl2_ep, PARAM_EP, VERSION_1, 0);
/*
* Find out how much free trusted ram remains after BL1 load
* & load the BL2 image at its top
*/
bl1_tzram_layout = bl1_plat_sec_mem_layout();
bl2_base = load_image(bl1_tzram_layout,
err = load_image(bl1_tzram_layout,
(const char *) BL2_IMAGE_NAME,
load_type, BL2_BASE);
load_type,
BL2_BASE,
&bl2_image_info,
&bl2_ep);
if (err) {
/*
* TODO: print failure to load BL2 but also add a tzwdog timer
* which will reset the system eventually.
*/
printf("Failed to load boot loader stage 2 (BL2) firmware.\n");
panic();
}
/*
* Create a new layout of memory for BL2 as seen by BL1 i.e.
* tell it the amount of total and free memory available.
......@@ -120,29 +135,20 @@ void bl1_main(void)
init_bl2_mem_layout(bl1_tzram_layout,
bl2_tzram_layout,
load_type,
bl2_base);
if (bl2_base) {
bl2_ep.spsr =
SPSR_64(MODE_EL1, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
bl2_ep.entrypoint = bl2_base;
bl2_ep.security_state = SECURE;
bl2_ep.args.arg1 = (unsigned long)bl2_tzram_layout;
printf("Booting trusted firmware boot loader stage 2\n\r");
bl2_image_info.image_base);
bl1_plat_set_bl2_ep_info(&bl2_image_info, &bl2_ep);
bl2_ep.args.arg1 = (unsigned long)bl2_tzram_layout;
printf("Booting trusted firmware boot loader stage 2\n");
#if DEBUG
printf("BL2 address = 0x%llx \n\r", (unsigned long long) bl2_base);
printf("BL2 cpsr = 0x%x \n\r", bl2_ep.spsr);
printf("BL2 memory layout address = 0x%llx \n\r",
(unsigned long long) bl2_tzram_layout);
printf("BL2 address = 0x%llx\n",
(unsigned long long) bl2_ep.pc);
printf("BL2 cpsr = 0x%x\n", bl2_ep.spsr);
printf("BL2 memory layout address = 0x%llx\n",
(unsigned long long) bl2_tzram_layout);
#endif
bl1_run_bl2(&bl2_ep);
}
bl1_run_bl2(&bl2_ep);
/*
* TODO: print failure to load BL2 but also add a tzwdog timer
* which will reset the system eventually.
*/
printf("Failed to load boot loader stage 2 (BL2) firmware.\n\r");
return;
}
......@@ -150,16 +156,16 @@ void bl1_main(void)
* Temporary function to print the fact that BL2 has done its job and BL31 is
* about to be loaded. This is needed as long as printfs cannot be used
******************************************************************************/
void display_boot_progress(el_change_info_t *bl31_ep_info)
void display_boot_progress(entry_point_info_t *bl31_ep_info)
{
printf("Booting trusted firmware boot loader stage 3\n\r");
#if DEBUG
printf("BL31 address = 0x%llx\n",
(unsigned long long)bl31_ep_info->entrypoint);
printf("BL31 cpsr = 0x%llx\n",
(unsigned long long)bl31_ep_info->spsr);
printf("BL31 args address = 0x%llx\n",
printf("BL31 address = 0x%llx\n", (unsigned long long)bl31_ep_info->pc);
printf("BL31 cpsr = 0x%llx\n", (unsigned long long)bl31_ep_info->spsr);
printf("BL31 params address = 0x%llx\n",
(unsigned long long)bl31_ep_info->args.arg0);
printf("BL31 plat params address = 0x%llx\n",
(unsigned long long)bl31_ep_info->args.arg1);
#endif
return;
}
......@@ -42,20 +42,18 @@
* Runs BL31 from the given entry point. It jumps to a higher exception level
* through an SMC.
******************************************************************************/
static void __dead2 bl2_run_bl31(bl31_args_t *bl2_to_bl31_args,
static void __dead2 bl2_run_bl31(entry_point_info_t *bl31_ep_info,
unsigned long arg1,
unsigned long arg2)
{
/* Set the args pointers for X0 and X1 to BL31 */
bl2_to_bl31_args->bl31_image_info.args.arg0 = arg1;
bl2_to_bl31_args->bl31_image_info.args.arg1 = arg2;
/* Set the args pointer */
bl31_ep_info->args.arg0 = arg1;
bl31_ep_info->args.arg1 = arg2;
/* Flush the entire BL31 args buffer */
flush_dcache_range((unsigned long) bl2_to_bl31_args,
sizeof(*bl2_to_bl31_args));
/* Flush the params to be passed to memory */
bl2_plat_flush_bl31_params();
smc(RUN_IMAGE, (unsigned long)&bl2_to_bl31_args->bl31_image_info,
0, 0, 0, 0, 0, 0);
smc(RUN_IMAGE, (unsigned long)bl31_ep_info, 0, 0, 0, 0, 0, 0);
}
......@@ -68,9 +66,11 @@ static void __dead2 bl2_run_bl31(bl31_args_t *bl2_to_bl31_args,
void bl2_main(void)
{
meminfo_t *bl2_tzram_layout;
bl31_args_t *bl2_to_bl31_args;
unsigned long bl31_base, bl32_base = 0, bl33_base, el_status;
unsigned int bl2_load, bl31_load, mode;
bl31_params_t *bl2_to_bl31_params;
bl31_plat_params_t *bl2_to_bl31_plat_params;
unsigned int bl2_load, bl31_load;
entry_point_info_t *bl31_ep_info;
int e;
/* Perform remaining generic architectural setup in S-El1 */
bl2_arch_setup();
......@@ -83,6 +83,14 @@ void bl2_main(void)
/* Find out how much free trusted ram remains after BL2 load */
bl2_tzram_layout = bl2_plat_sec_mem_layout();
/*
* Get a pointer to the memory the platform has set aside to pass
* information to BL31.
*/
bl2_to_bl31_params = bl2_plat_get_bl31_params();
bl2_to_bl31_plat_params = bl2_plat_get_bl31_plat_params();
bl31_ep_info = bl2_plat_get_bl31_ep_info();
/*
* Load BL31. BL1 tells BL2 whether it has been TOP or BOTTOM loaded.
* To avoid fragmentation of trusted SRAM memory, BL31 is always
......@@ -92,67 +100,45 @@ void bl2_main(void)
bl2_load = bl2_tzram_layout->attr & LOAD_MASK;
assert((bl2_load == TOP_LOAD) || (bl2_load == BOT_LOAD));
bl31_load = (bl2_load == TOP_LOAD) ? BOT_LOAD : TOP_LOAD;
bl31_base = load_image(bl2_tzram_layout, BL31_IMAGE_NAME,
bl31_load, BL31_BASE);
e = load_image(bl2_tzram_layout,
BL31_IMAGE_NAME,
bl31_load,
BL31_BASE,
bl2_to_bl31_params->bl31_image_info,
bl31_ep_info);
/* Assert if it has not been possible to load BL31 */
if (bl31_base == 0) {
if (e) {
ERROR("Failed to load BL3-1.\n");
panic();
}
/*
* Get a pointer to the memory the platform has set aside to pass
* information to BL31.
*/
bl2_to_bl31_args = bl2_get_bl31_args_ptr();
bl2_to_bl31_args->bl31_image_info.entrypoint = bl31_base;
bl2_to_bl31_args->bl31_image_info.spsr =
SPSR_64(MODE_EL3, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
bl2_plat_set_bl31_ep_info(bl2_to_bl31_params->bl31_image_info,
bl31_ep_info);
/*
* Create a new layout of memory for BL31 as seen by BL2. This
* will gobble up all the BL2 memory.
*/
init_bl31_mem_layout(bl2_tzram_layout,
&bl2_to_bl31_args->bl31_meminfo,
&bl2_to_bl31_plat_params->bl31_meminfo,
bl31_load);
/* Load the BL33 image in non-secure memory provided by the platform */
bl33_base = load_image(&bl2_to_bl31_args->bl33_meminfo,
BL33_IMAGE_NAME,
BOT_LOAD,
plat_get_ns_image_entrypoint());
e = load_image(&bl2_to_bl31_plat_params->bl33_meminfo,
BL33_IMAGE_NAME,
BOT_LOAD,
plat_get_ns_image_entrypoint(),
bl2_to_bl31_params->bl33_image_info,
bl2_to_bl31_params->bl33_ep_info);
/* Halt if failed to load normal world firmware. */
if (bl33_base == 0) {
if (e) {
ERROR("Failed to load BL3-3.\n");
panic();
}
/*
* BL2 also needs to tell BL31 where the non-trusted software image
* is located.
*/
bl2_to_bl31_args->bl33_image_info.entrypoint = bl33_base;
/* Figure out what mode we enter the non-secure world in */
el_status = read_id_aa64pfr0_el1() >> ID_AA64PFR0_EL2_SHIFT;
el_status &= ID_AA64PFR0_ELX_MASK;
if (el_status)
mode = MODE_EL2;
else
mode = MODE_EL1;
/*
* TODO: Consider the possibility of specifying the SPSR in
* the FIP ToC and allowing the platform to have a say as
* well.
*/
bl2_to_bl31_args->bl33_image_info.spsr =
SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
bl2_to_bl31_args->bl33_image_info.security_state = NON_SECURE;
bl2_plat_set_bl33_ep_info(bl2_to_bl31_params->bl33_image_info,
bl2_to_bl31_params->bl33_ep_info);
/*
* Load the BL32 image if there's one. It is upto to platform
......@@ -161,29 +147,31 @@ void bl2_main(void)
* completely different memory. A zero size indicates that the
* platform does not want to load a BL32 image.
*/
if (bl2_to_bl31_args->bl32_meminfo.total_size)
bl32_base = load_image(&bl2_to_bl31_args->bl32_meminfo,
BL32_IMAGE_NAME,
bl2_to_bl31_args->bl32_meminfo.attr &
LOAD_MASK,
BL32_BASE);
if (bl32_base) {
/* Fill BL32 image info */
bl2_to_bl31_args->bl32_image_info.entrypoint = bl32_base;
bl2_to_bl31_args->bl32_image_info.security_state = SECURE;
/*
* The Secure Payload Dispatcher service is responsible for
* setting the SPSR prior to entry into the BL32 image.
*/
bl2_to_bl31_args->bl32_image_info.spsr = 0;
if (bl2_to_bl31_plat_params->bl32_meminfo.total_size) {
e = load_image(&bl2_to_bl31_plat_params->bl32_meminfo,
BL32_IMAGE_NAME,
bl2_to_bl31_plat_params->bl32_meminfo.attr &
LOAD_MASK,
BL32_BASE,
bl2_to_bl31_params->bl32_image_info,
bl2_to_bl31_params->bl32_ep_info);
/* Halt if failed to load normal world firmware. */
if (e) {
WARN("Failed to load BL3-2.\n");
} else {
bl2_plat_set_bl32_ep_info(
bl2_to_bl31_params->bl32_image_info,
bl2_to_bl31_params->bl32_ep_info);
}
}
/*
* Run BL31 via an SMC to BL1. Information on how to pass control to
* the BL32 (if present) and BL33 software images will be passed to
* BL31 as an argument.
*/
bl2_run_bl31(bl2_to_bl31_args, (unsigned long)bl2_to_bl31_args, 0);
bl2_run_bl31(bl31_ep_info, (unsigned long)bl2_to_bl31_params,
(unsigned long)bl2_to_bl31_plat_params);
}
......@@ -44,11 +44,11 @@
*/
func bl31_entrypoint
/* ---------------------------------------------
* Preceding bootloader has populated x0 with a
* pointer to a 'bl31_args' structure & x1
* with any other optional information
* ---------------------------------------------
/* ---------------------------------------------------------------
* Preceding bootloader has populated x0 with a pointer to a
* 'bl31_params' structure & x1 with a pointer to platform
* specific structure
* ---------------------------------------------------------------
*/
mov x20, x0
mov x21, x1
......
......@@ -152,7 +152,7 @@ uint32_t bl31_get_next_image_type(void)
******************************************************************************/
void bl31_prepare_next_image_entry()
{
el_change_info_t *next_image_info;
entry_point_info_t *next_image_info;
uint32_t scr, image_type;
/* Determine which image to execute next */
......@@ -176,13 +176,13 @@ void bl31_prepare_next_image_entry()
* Tell the context mgmt. library to ensure that SP_EL3 points to
* the right context to exit from EL3 correctly.
*/
cm_set_el3_eret_context(next_image_info->security_state,
next_image_info->entrypoint,
cm_set_el3_eret_context(GET_SECURITY_STATE(next_image_info->h.attr),
next_image_info->pc,
next_image_info->spsr,
scr);
/* Finally set the next context */
cm_set_next_eret_context(next_image_info->security_state);
cm_set_next_eret_context(GET_SECURITY_STATE(next_image_info->h.attr));
}
/*******************************************************************************
......
......@@ -35,6 +35,7 @@
#include <debug.h>
#include <io_storage.h>
#include <platform.h>
#include <errno.h>
#include <stdio.h>
unsigned long page_align(unsigned long value, unsigned dir)
......@@ -229,12 +230,15 @@ unsigned long image_size(const char *image_name)
* Generic function to load an image into the trusted RAM,
* given a name, extents of free memory & whether the image should be loaded at
* the bottom or top of the free memory. It updates the memory layout if the
* load is successful.
* load is successful. It also updates the image information and the entry point
* information in the params passed
******************************************************************************/
unsigned long load_image(meminfo_t *mem_layout,
int load_image(meminfo_t *mem_layout,
const char *image_name,
unsigned int load_type,
unsigned long fixed_addr)
unsigned long fixed_addr,
image_info_t *image_data,
entry_point_info_t *entry_point_info)
{
uintptr_t dev_handle;
uintptr_t image_handle;
......@@ -248,13 +252,14 @@ unsigned long load_image(meminfo_t *mem_layout,
assert(mem_layout != NULL);
assert(image_name != 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);
if (io_result != IO_SUCCESS) {
WARN("Failed to obtain reference to image '%s' (%i)\n",
image_name, io_result);
return 0;
return io_result;
}
/* Attempt to access the image */
......@@ -262,7 +267,7 @@ unsigned long load_image(meminfo_t *mem_layout,
if (io_result != IO_SUCCESS) {
WARN("Failed to access image '%s' (%i)\n",
image_name, io_result);
return 0;
return io_result;
}
/* Find the size of the image */
......@@ -270,7 +275,7 @@ unsigned long load_image(meminfo_t *mem_layout,
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);
goto fail;
goto exit;
}
/* See if we have enough space */
......@@ -278,7 +283,7 @@ unsigned long load_image(meminfo_t *mem_layout,
WARN("Cannot load '%s' file: Not enough space.\n",
image_name);
dump_load_info(0, image_size, mem_layout);
goto fail;
goto exit;
}
switch (load_type) {
......@@ -297,7 +302,8 @@ unsigned long load_image(meminfo_t *mem_layout,
WARN("Cannot load '%s' file: Not enough space.\n",
image_name);
dump_load_info(image_base, image_size, mem_layout);
goto fail;
io_result = -ENOMEM;
goto exit;
}
/* Calculate the amount of extra memory used due to alignment */
......@@ -315,10 +321,11 @@ unsigned long load_image(meminfo_t *mem_layout,
/* Page align base address and check whether the image still fits */
if (image_base + image_size >
mem_layout->free_base + mem_layout->free_size) {
WARN("Cannot load '%s' file: Not enough space.\n",
image_name);
dump_load_info(image_base, image_size, mem_layout);
goto fail;
WARN("Cannot load '%s' file: Not enough space.\n",
image_name);
dump_load_info(image_base, image_size, mem_layout);
io_result = -ENOMEM;
goto exit;
}
/* Calculate the amount of extra memory used due to alignment */
......@@ -383,14 +390,16 @@ unsigned long load_image(meminfo_t *mem_layout,
WARN("Cannot load '%s' file: Not enough space.\n",
image_name);
dump_load_info(image_base, image_size, mem_layout);
goto fail;
io_result = -ENOMEM;
goto exit;
}
/* Check whether the fixed load address is page-aligned. */
if (!is_page_aligned(image_base)) {
WARN("Cannot load '%s' file at unaligned address 0x%lx\n",
image_name, fixed_addr);
goto fail;
io_result = -ENOMEM;
goto exit;
}
/*
......@@ -440,9 +449,14 @@ unsigned long load_image(meminfo_t *mem_layout,
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);
goto fail;
goto exit;
}
image_data->image_base = image_base;
image_data->image_size = image_size;
entry_point_info->pc = image_base;
/*
* File has been successfully loaded. Update the free memory
* data structure & flush the contents of the TZRAM so that
......@@ -458,15 +472,12 @@ unsigned long load_image(meminfo_t *mem_layout,
mem_layout->free_base += offset + image_size;
exit:
io_result = io_close(image_handle);
io_close(image_handle);
/* Ignore improbable/unrecoverable error in 'close' */
/* TODO: Consider maintaining open device connection from this bootloader stage */
io_result = io_dev_close(dev_handle);
io_dev_close(dev_handle);
/* Ignore improbable/unrecoverable error in 'dev_close' */
return image_base;
fail: image_base = 0;
goto exit;
return io_result;
}
......@@ -47,6 +47,32 @@ struct bl31_args;
*****************************************/
extern void bl2_platform_setup(void);
extern struct meminfo *bl2_plat_sec_mem_layout(void);
extern struct bl31_args *bl2_get_bl31_args_ptr(void);
/*******************************************************************************
* This function returns a pointer to the shared memory that the platform has
* kept aside to pass trusted firmware related information that BL3-1
* could need
******************************************************************************/
extern struct bl31_params *bl2_plat_get_bl31_params(void);
/*******************************************************************************
* This function returns a pointer to the shared memory that the platform has
* kept aside to pass platform related information that BL3-1 could need
******************************************************************************/
extern struct bl31_plat_params *bl2_plat_get_bl31_plat_params(void);
/*******************************************************************************
* This function returns a pointer to the shared memory that the platform
* has kept to point to entry point information of BL31 to BL2
******************************************************************************/
extern struct entry_point_info *bl2_plat_get_bl31_ep_info(void);
/************************************************************************
* This function flushes to main memory all the params that are
* passed to BL3-1
**************************************************************************/
extern void bl2_plat_flush_bl31_params(void);
#endif /* __BL2_H__ */
......@@ -42,7 +42,7 @@ extern unsigned long bl31_entrypoint;
* Forward declarations
*****************************************/
struct meminfo;
struct el_change_info;
struct entry_point_info;
/*******************************************************************************
* Function prototypes
......@@ -52,7 +52,7 @@ extern void bl31_next_el_arch_setup(uint32_t security_state);
extern void bl31_set_next_image_type(uint32_t type);
extern uint32_t bl31_get_next_image_type(void);
extern void bl31_prepare_next_image_entry();
extern struct el_change_info *bl31_get_next_image_info(uint32_t type);
extern struct entry_point_info *bl31_get_next_image_info(uint32_t type);
extern void bl31_platform_setup(void);
extern struct meminfo *bl31_plat_get_bl32_mem_layout(void);
extern struct meminfo *bl31_plat_sec_mem_layout(void);
......
......@@ -31,8 +31,9 @@
#ifndef __BL_COMMON_H__
#define __BL_COMMON_H__
#define SECURE 0
#define NON_SECURE 1
#define SECURE 0x0
#define NON_SECURE 0x1
#define PARAM_EP_SECURITY_MASK 0x1
#define UP 1
#define DOWN 0
......@@ -58,15 +59,32 @@
/*******************************************************************************
* Constants that allow assembler code to access members of and the
* 'el_change_info' structure at their correct offsets.
* 'entry_point_info' structure at their correct offsets.
******************************************************************************/
#define EL_CHANGE_INFO_PC_OFFSET 0x0
#define EL_CHANGE_INFO_ARGS_OFFSET 0x18
#define ENTRY_POINT_INFO_PC_OFFSET 0x08
#define ENTRY_POINT_INFO_ARGS_OFFSET 0x18
#ifndef __ASSEMBLY__
#define GET_SECURITY_STATE(x) (x & PARAM_EP_SECURITY_MASK)
#define SET_SECURITY_STATE(x, security) \
((x) = ((x) & ~PARAM_EP_SECURITY_MASK) | (security))
#define PARAM_EP 0x01
#define PARAM_IMAGE_BINARY 0x02
#define PARAM_BL31 0x03
#define VERSION_1 0x01
#define SET_PARAM_HEAD(_p, _type, _ver, _attr) do { \
(_p)->h.type = (uint8_t)(_type); \
(_p)->h.version = (uint8_t)(_ver); \
(_p)->h.size = (uint16_t)sizeof(*_p); \
(_p)->h.attr = (uint32_t)(_attr) ; \
} while (0)
#ifndef __ASSEMBLY__
#include <cdefs.h> /* For __dead2 */
#include <cassert.h>
#include <stdint.h>
/*******************************************************************************
* Structure used for telling the next BL how much of a particular type of
......@@ -92,50 +110,97 @@ typedef struct aapcs64_params {
unsigned long arg7;
} aapcs64_params_t;
/*******************************************************************************
* This structure represents the superset of information needed while switching
* exception levels. The only two mechanisms to do so are ERET & SMC. In case of
* SMC all members apart from 'aapcs64_params' will be ignored.
* NOTE: BL1 expects entrypoint followed by spsr while processing SMC to jump
* to BL31 from the start of el_change_info
******************************************************************************/
typedef struct el_change_info {
unsigned long entrypoint;
unsigned long spsr;
unsigned long security_state;
/***************************************************************************
* This structure provides version information and the size of the
* structure, attributes for the structure it represents
***************************************************************************/
typedef struct param_header {
uint8_t type; /* type of the structure */
uint8_t version; /* version of this structure */
uint16_t size; /* size of this structure in bytes */
uint32_t attr; /* attributes: unused bits SBZ */
} param_header_t;
/*****************************************************************************
* This structure represents the superset of information needed while
* switching exception levels. The only two mechanisms to do so are
* ERET & SMC. Security state is indicated using bit zero of header
* attribute
* NOTE: BL1 expects entrypoint followed by spsr while processing
* SMC to jump to BL31 from the start of entry_point_info
*****************************************************************************/
typedef struct entry_point_info {
param_header_t h;
uintptr_t pc;
uint32_t spsr;
aapcs64_params_t args;
} el_change_info_t;
} entry_point_info_t;
/*****************************************************************************
* Image info binary provides information from the image loader that
* can be used by the firmware to manage available trusted RAM.
* More advanced firmware image formats can provide additional
* information that enables optimization or greater flexibility in the
* common firmware code
*****************************************************************************/
typedef struct image_info {
param_header_t h;
uintptr_t image_base; /* physical address of base of image */
uint32_t image_size; /* bytes read from image file */
} image_info_t;
/*******************************************************************************
* This structure represents the superset of information that can be passed to
* BL31 e.g. while passing control to it from BL2. The BL32 parameters will be
* populated only if BL2 detects its presence.
* populated only if BL2 detects its presence. A pointer to a structure of this
* type should be passed in X3 to BL31's cold boot entrypoint
*
* Use of this structure and the X3 parameter is not mandatory: the BL3-1
* platform code can use other mechanisms to provide the necessary information
* about BL3-2 and BL3-3 to the common and SPD code.
*
* BL3-1 image information is mandatory if this structure is used. If either of
* the optional BL3-2 and BL3-3 image information is not provided, this is
* indicated by the respective image_info pointers being zero.
******************************************************************************/
typedef struct bl31_args {
el_change_info_t bl31_image_info;
typedef struct bl31_params {
param_header_t h;
image_info_t *bl31_image_info;
entry_point_info_t *bl32_ep_info;
image_info_t *bl32_image_info;
entry_point_info_t *bl33_ep_info;
image_info_t *bl33_image_info;
} bl31_params_t;
/***************************************************************************
* This structure provides platform specific data that needs to be known to
* BL31. Currently, The loader updates the memory information available for
* each binary
***************************************************************************/
typedef struct bl31_plat_params {
meminfo_t bl31_meminfo;
el_change_info_t bl32_image_info;
meminfo_t bl32_meminfo;
el_change_info_t bl33_image_info;
meminfo_t bl33_meminfo;
} bl31_args_t;
} bl31_plat_params_t;
/*
* Compile time assertions related to the 'el_change_info' structure to
* Compile time assertions related to the 'entry_point_info' structure to
* ensure that the assembler and the compiler view of the offsets of
* the structure members is the same.
*/
CASSERT(EL_CHANGE_INFO_PC_OFFSET == \
__builtin_offsetof(el_change_info_t, entrypoint), \
assert_BL31_pc_offset_mismatch);
CASSERT(ENTRY_POINT_INFO_PC_OFFSET ==
__builtin_offsetof(entry_point_info_t, pc), \
assert_BL31_pc_offset_mismatch);
CASSERT(EL_CHANGE_INFO_ARGS_OFFSET == \
__builtin_offsetof(el_change_info_t, args), \
CASSERT(ENTRY_POINT_INFO_ARGS_OFFSET == \
__builtin_offsetof(entry_point_info_t, args), \
assert_BL31_args_offset_mismatch);
CASSERT(sizeof(unsigned long) == __builtin_offsetof(el_change_info_t, spsr) - \
__builtin_offsetof(el_change_info_t, entrypoint), \
CASSERT(sizeof(unsigned long) ==
__builtin_offsetof(entry_point_info_t, spsr) - \
__builtin_offsetof(entry_point_info_t, pc), \
assert_entrypoint_and_spsr_should_be_adjacent);
/*******************************************************************************
......@@ -151,10 +216,12 @@ extern void init_bl31_mem_layout(const meminfo_t *,
meminfo_t *,
unsigned int) __attribute__((weak));
extern unsigned long image_size(const char *);
extern unsigned long load_image(meminfo_t *,
extern int load_image(meminfo_t *,
const char *,
unsigned int,
unsigned long);
unsigned long,
image_info_t *,
entry_point_info_t *);
extern unsigned long *get_el_change_mem_ptr(void);
extern const char build_message[];
......
......@@ -144,3 +144,17 @@ void bl1_plat_arch_setup(void)
BL1_COHERENT_RAM_BASE,
BL1_COHERENT_RAM_LIMIT);
}
/*******************************************************************************
* Before calling this function BL2 is loaded in memory and its entrypoint
* is set by load_image. This is a placeholder for the platform to change
* the entrypoint of BL2 and set SPSR and security state.
* On FVP we are only setting the security state, entrypoint
******************************************************************************/
void bl1_plat_set_bl2_ep_info(image_info_t *bl2_image,
entry_point_info_t *bl2_ep)
{
SET_SECURITY_STATE(bl2_ep->h.attr, SECURE);
bl2_ep->spsr = SPSR_64(MODE_EL1, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
}
......@@ -34,6 +34,7 @@
#include <bl2.h>
#include <console.h>
#include <platform.h>
#include <string.h>
/*******************************************************************************
* Declarations of linker defined symbols which will help us find the layout
......@@ -73,25 +74,117 @@ __attribute__ ((aligned(PLATFORM_CACHE_LINE_SIZE),
section("tzfw_coherent_mem")));
/*******************************************************************************
* Reference to structure which holds the arguments which need to be passed
* Reference to structures which holds the arguments which need to be passed
* to BL31
******************************************************************************/
static bl31_args_t *bl2_to_bl31_args;
static bl31_params_t *bl2_to_bl31_params;
static bl31_plat_params_t *bl2_to_bl31_plat_params;
static entry_point_info_t *bl31_ep_info;
meminfo_t *bl2_plat_sec_mem_layout(void)
{
return &bl2_tzram_layout;
}
/*******************************************************************************
* This function assigns a pointer to the memory that the platform has kept
* aside to pass platform specific and trusted firmware related information
* to BL31. This memory is allocated by allocating memory to
* bl2_to_bl31_params_mem_t structure which is a superset of all the
* structure whose information is passed to BL31
* NOTE: This function should be called only once and should be done
* before generating params to BL31
******************************************************************************/
bl31_params_t *bl2_plat_get_bl31_params(void)
{
bl2_to_bl31_params_mem_t *bl31_params_mem;
/*
* Ensure that the secure DRAM memory used for passing BL31 arguments
* does not overlap with the BL32_BASE.
*/
assert(BL32_BASE > PARAMS_BASE + sizeof(bl2_to_bl31_params_mem_t));
/*
* Allocate the memory for all the arguments that needs to
* be passed to BL31
*/
bl31_params_mem = (bl2_to_bl31_params_mem_t *)PARAMS_BASE;
memset((void *)PARAMS_BASE, 0, sizeof(bl2_to_bl31_params_mem_t));
/* Assign memory for TF related information */
bl2_to_bl31_params = &bl31_params_mem->bl31_params;
SET_PARAM_HEAD(bl2_to_bl31_params, PARAM_BL31, VERSION_1, 0);
/* Assign memory for platform specific information */
bl2_to_bl31_plat_params = &bl31_params_mem->bl31_plat_params;
/* Fill BL31 related information */
bl31_ep_info = &bl31_params_mem->bl31_ep_info;
bl2_to_bl31_params->bl31_image_info = &bl31_params_mem->bl31_image_info;
SET_PARAM_HEAD(bl2_to_bl31_params->bl31_image_info, PARAM_IMAGE_BINARY,
VERSION_1, 0);
/* Fill BL32 related information if it exists */
if (BL32_BASE) {
bl2_to_bl31_params->bl32_ep_info =
&bl31_params_mem->bl32_ep_info;
SET_PARAM_HEAD(bl2_to_bl31_params->bl32_ep_info,
PARAM_EP, VERSION_1, 0);
bl2_to_bl31_params->bl32_image_info =
&bl31_params_mem->bl32_image_info;
SET_PARAM_HEAD(bl2_to_bl31_params->bl32_image_info,
PARAM_IMAGE_BINARY,
VERSION_1, 0);
/*
* Populate the extents of memory available for loading BL32.
* TODO: We are temporarily executing BL2 from TZDRAM;
* will eventually move to Trusted SRAM
*/
bl2_to_bl31_plat_params->bl32_meminfo.total_base = BL32_BASE;
bl2_to_bl31_plat_params->bl32_meminfo.free_base = BL32_BASE;
bl2_to_bl31_plat_params->bl32_meminfo.total_size =
(TZDRAM_BASE + TZDRAM_SIZE) - BL32_BASE;
bl2_to_bl31_plat_params->bl32_meminfo.free_size =
(TZDRAM_BASE + TZDRAM_SIZE) - BL32_BASE;
bl2_to_bl31_plat_params->bl32_meminfo.attr = BOT_LOAD;
}
/* Fill BL33 related information */
bl2_to_bl31_params->bl33_ep_info = &bl31_params_mem->bl33_ep_info;
SET_PARAM_HEAD(bl2_to_bl31_params->bl33_ep_info,
PARAM_EP, VERSION_1, 0);
bl2_to_bl31_params->bl33_image_info = &bl31_params_mem->bl33_image_info;
SET_PARAM_HEAD(bl2_to_bl31_params->bl33_image_info, PARAM_IMAGE_BINARY,
VERSION_1, 0);
/* Populate the extents of memory available for loading BL33 */
bl2_to_bl31_plat_params->bl33_meminfo.total_base = DRAM_BASE;
bl2_to_bl31_plat_params->bl33_meminfo.total_size = DRAM_SIZE;
bl2_to_bl31_plat_params->bl33_meminfo.free_base = DRAM_BASE;
bl2_to_bl31_plat_params->bl33_meminfo.free_size = DRAM_SIZE;
return bl2_to_bl31_params;
}
/*******************************************************************************
* This function returns a pointer to the memory that the platform has kept
* aside to pass all the information that BL31 could need.
* aside to pass platform related information that BL31 could need
******************************************************************************/
bl31_plat_params_t *bl2_plat_get_bl31_plat_params(void)
{
return bl2_to_bl31_plat_params;
}
/*******************************************************************************
* This function returns a pointer to the shared memory that the platform
* has kept to point to entry point information of BL31 to BL2
******************************************************************************/
bl31_args_t *bl2_get_bl31_args_ptr(void)
struct entry_point_info *bl2_plat_get_bl31_ep_info(void)
{
return bl2_to_bl31_args;
return bl31_ep_info;
}
/*******************************************************************************
* BL1 has passed the extents of the trusted SRAM that should be visible to BL2
* in x0. This memory layout is sitting at the base of the free trusted SRAM.
......@@ -118,7 +211,7 @@ void bl2_early_platform_setup(meminfo_t *mem_layout)
* Perform platform specific setup. For now just initialize the memory location
* to use for passing arguments to BL31.
******************************************************************************/
void bl2_platform_setup()
void bl2_platform_setup(void)
{
/*
* Do initial security configuration to allow DRAM/device access. On
......@@ -130,41 +223,16 @@ void bl2_platform_setup()
/* Initialise the IO layer and register platform IO devices */
io_setup();
}
/*
* Ensure that the secure DRAM memory used for passing BL31 arguments
* does not overlap with the BL32_BASE.
*/
assert (BL32_BASE > TZDRAM_BASE + sizeof(bl31_args_t));
/* Use the Trusted DRAM for passing args to BL31 */
bl2_to_bl31_args = (bl31_args_t *) TZDRAM_BASE;
/* Populate the extents of memory available for loading BL33 */
bl2_to_bl31_args->bl33_meminfo.total_base = DRAM_BASE;
bl2_to_bl31_args->bl33_meminfo.total_size = DRAM_SIZE;
bl2_to_bl31_args->bl33_meminfo.free_base = DRAM_BASE;
bl2_to_bl31_args->bl33_meminfo.free_size = DRAM_SIZE;
bl2_to_bl31_args->bl33_meminfo.attr = 0;
bl2_to_bl31_args->bl33_meminfo.next = 0;
/*
* Populate the extents of memory available for loading BL32.
* TODO: We are temporarily executing BL2 from TZDRAM; will eventually
* move to Trusted SRAM
*/
bl2_to_bl31_args->bl32_meminfo.total_base = BL32_BASE;
bl2_to_bl31_args->bl32_meminfo.free_base = BL32_BASE;
bl2_to_bl31_args->bl32_meminfo.total_size =
(TZDRAM_BASE + TZDRAM_SIZE) - BL32_BASE;
bl2_to_bl31_args->bl32_meminfo.free_size =
(TZDRAM_BASE + TZDRAM_SIZE) - BL32_BASE;
bl2_to_bl31_args->bl32_meminfo.attr = BOT_LOAD;
bl2_to_bl31_args->bl32_meminfo.next = 0;
/* Flush the TF params and the TF plat params */
void bl2_plat_flush_bl31_params(void)
{
flush_dcache_range((unsigned long)PARAMS_BASE, \
sizeof(bl2_to_bl31_params_mem_t));
}
/*******************************************************************************
* Perform the very early platform specific architectural setup here. At the
* moment this is only intializes the mmu in a quick and dirty way.
......@@ -177,3 +245,66 @@ void bl2_plat_arch_setup()
BL2_COHERENT_RAM_BASE,
BL2_COHERENT_RAM_LIMIT);
}
/*******************************************************************************
* Before calling this function BL31 is loaded in memory and its entrypoint
* is set by load_image. This is a placeholder for the platform to change
* the entrypoint of BL31 and set SPSR and security state.
* On FVP we are only setting the security state, entrypoint
******************************************************************************/
void bl2_plat_set_bl31_ep_info(image_info_t *bl31_image_info,
entry_point_info_t *bl31_ep_info)
{
SET_SECURITY_STATE(bl31_ep_info->h.attr, SECURE);
bl31_ep_info->spsr = SPSR_64(MODE_EL3, MODE_SP_ELX,
DISABLE_ALL_EXCEPTIONS);
}
/*******************************************************************************
* Before calling this function BL32 is loaded in memory and its entrypoint
* is set by load_image. This is a placeholder for the platform to change
* the entrypoint of BL32 and set SPSR and security state.
* On FVP we are only setting the security state, entrypoint
******************************************************************************/
void bl2_plat_set_bl32_ep_info(image_info_t *bl32_image_info,
entry_point_info_t *bl32_ep_info)
{
SET_SECURITY_STATE(bl32_ep_info->h.attr, SECURE);
/*
* The Secure Payload Dispatcher service is responsible for
* setting the SPSR prior to entry into the BL32 image.
*/
bl32_ep_info->spsr = 0;
}
/*******************************************************************************
* Before calling this function BL33 is loaded in memory and its entrypoint
* is set by load_image. This is a placeholder for the platform to change
* the entrypoint of BL33 and set SPSR and security state.
* On FVP we are only setting the security state, entrypoint
******************************************************************************/
void bl2_plat_set_bl33_ep_info(image_info_t *image,
entry_point_info_t *bl33_ep_info)
{
unsigned long el_status;
unsigned int mode;
/* Figure out what mode we enter the non-secure world in */
el_status = read_id_aa64pfr0_el1() >> ID_AA64PFR0_EL2_SHIFT;
el_status &= ID_AA64PFR0_ELX_MASK;
if (el_status)
mode = MODE_EL2;
else
mode = MODE_EL1;
/*
* TODO: Consider the possibility of specifying the SPSR in
* the FIP ToC and allowing the platform to have a say as
* well.
*/
bl33_ep_info->spsr = SPSR_64(mode, MODE_SP_ELX,
DISABLE_ALL_EXCEPTIONS);
SET_SECURITY_STATE(bl33_ep_info->h.attr, NON_SECURE);
}
......@@ -29,6 +29,7 @@
*/
#include <arch.h>
#include <assert.h>
#include <bl_common.h>
#include <bl31.h>
#include <console.h>
......@@ -70,34 +71,35 @@ extern unsigned long __COHERENT_RAM_END__;
* Reference to structure which holds the arguments that have been passed to
* BL31 from BL2.
******************************************************************************/
static bl31_args_t *bl2_to_bl31_args;
static bl31_params_t *bl2_to_bl31_params;
static bl31_plat_params_t *bl2_to_bl31_plat_params;
meminfo_t *bl31_plat_sec_mem_layout(void)
{
return &bl2_to_bl31_args->bl31_meminfo;
return &bl2_to_bl31_plat_params->bl31_meminfo;
}
meminfo_t *bl31_plat_get_bl32_mem_layout(void)
{
return &bl2_to_bl31_args->bl32_meminfo;
return &bl2_to_bl31_plat_params->bl32_meminfo;
}
/*******************************************************************************
* Return a pointer to the 'el_change_info' structure of the next image for the
* Return a pointer to the 'entry_point_info' structure of the next image for the
* security state specified. BL33 corresponds to the non-secure image type
* while BL32 corresponds to the secure image type. A NULL pointer is returned
* if the image does not exist.
******************************************************************************/
el_change_info_t *bl31_get_next_image_info(uint32_t type)
entry_point_info_t *bl31_get_next_image_info(uint32_t type)
{
el_change_info_t *next_image_info;
entry_point_info_t *next_image_info;
next_image_info = (type == NON_SECURE) ?
&bl2_to_bl31_args->bl33_image_info :
&bl2_to_bl31_args->bl32_image_info;
bl2_to_bl31_params->bl33_ep_info :
bl2_to_bl31_params->bl32_ep_info;
/* None of the images on this platform can have 0x0 as the entrypoint */
if (next_image_info->entrypoint)
if (next_image_info->pc)
return next_image_info;
else
return NULL;
......@@ -114,10 +116,15 @@ el_change_info_t *bl31_get_next_image_info(uint32_t type)
* has flushed this information to memory, so we are guaranteed to pick up good
* data
******************************************************************************/
void bl31_early_platform_setup(bl31_args_t *from_bl2,
void *data)
void bl31_early_platform_setup(bl31_params_t *from_bl2,
bl31_plat_params_t *plat_info_from_bl2)
{
bl2_to_bl31_args = from_bl2;
assert(from_bl2->h.type == PARAM_BL31);
assert(from_bl2->h.version >= VERSION_1);
bl2_to_bl31_params = from_bl2;
bl2_to_bl31_plat_params = plat_info_from_bl2;
/* Initialize the console to provide early debug support */
console_init(PL011_UART0_BASE);
......@@ -172,7 +179,7 @@ void bl31_platform_setup()
******************************************************************************/
void bl31_plat_arch_setup()
{
configure_mmu_el3(&bl2_to_bl31_args->bl31_meminfo,
configure_mmu_el3(&bl2_to_bl31_plat_params->bl31_meminfo,
BL31_RO_BASE,
BL31_RO_LIMIT,
BL31_COHERENT_RAM_BASE,
......
......@@ -134,6 +134,10 @@
#define TZDRAM_SIZE 0x02000000
#define MBOX_OFF 0x1000
/* Base address where parameters to BL31 are stored */
#define PARAMS_BASE TZDRAM_BASE
#define DRAM_BASE 0x80000000ull
#define DRAM_SIZE 0x80000000ull
......@@ -339,7 +343,7 @@
#ifndef __ASSEMBLY__
#include <stdint.h>
#include <bl_common.h>
typedef volatile struct mailbox {
unsigned long value
......@@ -351,6 +355,28 @@ typedef volatile struct mailbox {
******************************************************************************/
struct plat_pm_ops;
struct meminfo;
struct bl31_params;
struct bl31_plat_params;
struct image_info;
struct entry_point_info;
/*******************************************************************************
* This structure represents the superset of information that is passed to
* BL31 e.g. while passing control to it from BL2 which is bl31_params
* and bl31_plat_params and its elements
******************************************************************************/
typedef struct bl2_to_bl31_params_mem {
struct bl31_params bl31_params;
struct bl31_plat_params bl31_plat_params;
struct image_info bl31_image_info;
struct image_info bl32_image_info;
struct image_info bl33_image_info;
struct entry_point_info bl33_ep_info;
struct entry_point_info bl32_ep_info;
struct entry_point_info bl31_ep_info;
} bl2_to_bl31_params_mem_t;
/*******************************************************************************
* Function and variable prototypes
......@@ -412,6 +438,42 @@ extern int plat_get_image_source(const char *image_name,
/* Declarations for plat_security.c */
extern void plat_security_setup(void);
/*
* Before calling this function BL2 is loaded in memory and its entrypoint
* is set by load_image. This is a placeholder for the platform to change
* the entrypoint of BL2 and set SPSR and security state.
* On FVP we are only setting the security state, entrypoint
*/
extern void bl1_plat_set_bl2_ep_info(struct image_info *image,
struct entry_point_info *ep);
/*
* Before calling this function BL31 is loaded in memory and its entrypoint
* is set by load_image. This is a placeholder for the platform to change
* the entrypoint of BL31 and set SPSR and security state.
* On FVP we are only setting the security state, entrypoint
*/
extern void bl2_plat_set_bl31_ep_info(struct image_info *image,
struct entry_point_info *ep);
/*
* Before calling this function BL32 is loaded in memory and its entrypoint
* is set by load_image. This is a placeholder for the platform to change
* the entrypoint of BL32 and set SPSR and security state.
* On FVP we are only setting the security state, entrypoint
*/
extern void bl2_plat_set_bl32_ep_info(struct image_info *image,
struct entry_point_info *ep);
/*
* Before calling this function BL33 is loaded in memory and its entrypoint
* is set by load_image. This is a placeholder for the platform to change
* the entrypoint of BL33 and set SPSR and security state.
* On FVP we are only setting the security state, entrypoint
*/
extern void bl2_plat_set_bl33_ep_info(struct image_info *image,
struct entry_point_info *ep);
#endif /*__ASSEMBLY__*/
......
......@@ -76,7 +76,7 @@ int32_t tspd_init(meminfo_t *bl32_meminfo);
******************************************************************************/
int32_t tspd_setup(void)
{
el_change_info_t *image_info;
entry_point_info_t *image_info;
int32_t rc;
uint64_t mpidr = read_mpidr();
uint32_t linear_id;
......@@ -96,7 +96,7 @@ int32_t tspd_setup(void)
* signalling failure initializing the service. We bail out without
* registering any handlers
*/
if (!image_info->entrypoint)
if (!image_info->pc)
return 1;
/*
......@@ -104,7 +104,7 @@ int32_t tspd_setup(void)
* state i.e whether AArch32 or AArch64. Assuming it's AArch64
* for the time being.
*/
rc = tspd_init_secure_context(image_info->entrypoint,
rc = tspd_init_secure_context(image_info->pc,
TSP_AARCH64,
mpidr,
&tspd_sp_context[linear_id]);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment