Commit db0de0eb authored by Andrew Thoelke's avatar Andrew Thoelke
Browse files

Merge pull request #99 from vikramkanigiri:vk/tf-issues-133_V3

parents 3ea8540d dbad1bac
Showing with 377 additions and 145 deletions
+377 -145
...@@ -33,7 +33,6 @@ ...@@ -33,7 +33,6 @@
#include <bl_common.h> #include <bl_common.h>
#include <bl1.h> #include <bl1.h>
#include <console.h> #include <console.h>
#include <cci400.h>
#include <mmio.h> #include <mmio.h>
#include <platform.h> #include <platform.h>
...@@ -126,21 +125,26 @@ void bl1_platform_setup(void) ...@@ -126,21 +125,26 @@ void bl1_platform_setup(void)
******************************************************************************/ ******************************************************************************/
void bl1_plat_arch_setup(void) void bl1_plat_arch_setup(void)
{ {
unsigned long cci_setup; fvp_cci_setup();
/* configure_mmu_el3(bl1_tzram_layout.total_base,
* Enable CCI-400 for this cluster. No need bl1_tzram_layout.total_size,
* for locks as no other cpu is active at the
* moment
*/
cci_setup = platform_get_cfgvar(CONFIG_HAS_CCI);
if (cci_setup) {
cci_enable_coherency(read_mpidr());
}
configure_mmu_el3(&bl1_tzram_layout,
TZROM_BASE, TZROM_BASE,
TZROM_BASE + TZROM_SIZE, TZROM_BASE + TZROM_SIZE,
BL1_COHERENT_RAM_BASE, BL1_COHERENT_RAM_BASE,
BL1_COHERENT_RAM_LIMIT); 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 @@ ...@@ -34,6 +34,7 @@
#include <bl2.h> #include <bl2.h>
#include <console.h> #include <console.h>
#include <platform.h> #include <platform.h>
#include <string.h>
/******************************************************************************* /*******************************************************************************
* Declarations of linker defined symbols which will help us find the layout * Declarations of linker defined symbols which will help us find the layout
...@@ -73,10 +74,11 @@ __attribute__ ((aligned(PLATFORM_CACHE_LINE_SIZE), ...@@ -73,10 +74,11 @@ __attribute__ ((aligned(PLATFORM_CACHE_LINE_SIZE),
section("tzfw_coherent_mem"))); 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 * to BL31
******************************************************************************/ ******************************************************************************/
static bl31_args_t *bl2_to_bl31_args; static bl31_params_t *bl2_to_bl31_params;
static entry_point_info_t *bl31_ep_info;
meminfo_t *bl2_plat_sec_mem_layout(void) meminfo_t *bl2_plat_sec_mem_layout(void)
{ {
...@@ -84,21 +86,82 @@ meminfo_t *bl2_plat_sec_mem_layout(void) ...@@ -84,21 +86,82 @@ meminfo_t *bl2_plat_sec_mem_layout(void)
} }
/******************************************************************************* /*******************************************************************************
* This function returns a pointer to the memory that the platform has kept * This function assigns a pointer to the memory that the platform has kept
* aside to pass all the information that BL31 could need. * 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_args_t *bl2_get_bl31_args_ptr(void) bl31_params_t *bl2_plat_get_bl31_params(void)
{ {
return bl2_to_bl31_args; 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);
/* 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);
}
/* 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);
return bl2_to_bl31_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
******************************************************************************/
struct entry_point_info *bl2_plat_get_bl31_ep_info(void)
{
return bl31_ep_info;
}
/******************************************************************************* /*******************************************************************************
* BL1 has passed the extents of the trusted SRAM that should be visible to BL2 * 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. * in x0. This memory layout is sitting at the base of the free trusted SRAM.
* Copy it to a safe loaction before its reclaimed by later BL2 functionality. * Copy it to a safe loaction before its reclaimed by later BL2 functionality.
******************************************************************************/ ******************************************************************************/
void bl2_early_platform_setup(meminfo_t *mem_layout, void bl2_early_platform_setup(meminfo_t *mem_layout)
void *data)
{ {
/* Initialize the console to provide early debug support */ /* Initialize the console to provide early debug support */
console_init(PL011_UART0_BASE); console_init(PL011_UART0_BASE);
...@@ -119,7 +182,7 @@ void bl2_early_platform_setup(meminfo_t *mem_layout, ...@@ -119,7 +182,7 @@ void bl2_early_platform_setup(meminfo_t *mem_layout,
* Perform platform specific setup. For now just initialize the memory location * Perform platform specific setup. For now just initialize the memory location
* to use for passing arguments to BL31. * 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 * Do initial security configuration to allow DRAM/device access. On
...@@ -131,50 +194,100 @@ void bl2_platform_setup() ...@@ -131,50 +194,100 @@ void bl2_platform_setup()
/* Initialise the IO layer and register platform IO devices */ /* Initialise the IO layer and register platform IO devices */
io_setup(); io_setup();
}
/* /* Flush the TF params and the TF plat params */
* Ensure that the secure DRAM memory used for passing BL31 arguments void bl2_plat_flush_bl31_params(void)
* does not overlap with the BL32_BASE. {
*/ flush_dcache_range((unsigned long)PARAMS_BASE, \
assert (BL32_BASE > TZDRAM_BASE + sizeof(bl31_args_t)); sizeof(bl2_to_bl31_params_mem_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;
} }
/******************************************************************************* /*******************************************************************************
* Perform the very early platform specific architectural setup here. At the * Perform the very early platform specific architectural setup here. At the
* moment this is only intializes the mmu in a quick and dirty way. * moment this is only intializes the mmu in a quick and dirty way.
******************************************************************************/ ******************************************************************************/
void bl2_plat_arch_setup() void bl2_plat_arch_setup()
{ {
configure_mmu_el1(&bl2_tzram_layout, configure_mmu_el1(bl2_tzram_layout.total_base,
bl2_tzram_layout.total_size,
BL2_RO_BASE, BL2_RO_BASE,
BL2_RO_LIMIT, BL2_RO_LIMIT,
BL2_COHERENT_RAM_BASE, BL2_COHERENT_RAM_BASE,
BL2_COHERENT_RAM_LIMIT); 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)
{
fvp_set_bl32_ep_info(bl32_ep_info);
}
/*******************************************************************************
* 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)
{
fvp_set_bl33_ep_info(bl33_ep_info);
}
/*******************************************************************************
* Populate the extents of memory available for loading BL32
******************************************************************************/
void bl2_plat_get_bl32_meminfo(meminfo_t *bl32_meminfo)
{
/*
* Populate the extents of memory available for loading BL32.
* TODO: We are temporarily executing BL2 from TZDRAM;
* will eventually move to Trusted SRAM
*/
bl32_meminfo->total_base = BL32_BASE;
bl32_meminfo->free_base = BL32_BASE;
bl32_meminfo->total_size =
(TZDRAM_BASE + TZDRAM_SIZE) - BL32_BASE;
bl32_meminfo->free_size =
(TZDRAM_BASE + TZDRAM_SIZE) - BL32_BASE;
bl32_meminfo->attr = BOT_LOAD;
bl32_meminfo->next = 0;
}
/*******************************************************************************
* Populate the extents of memory available for loading BL33
******************************************************************************/
void bl2_plat_get_bl33_meminfo(meminfo_t *bl33_meminfo)
{
bl33_meminfo->total_base = DRAM_BASE;
bl33_meminfo->total_size = DRAM_SIZE;
bl33_meminfo->free_base = DRAM_BASE;
bl33_meminfo->free_size = DRAM_SIZE;
bl33_meminfo->attr = 0;
bl33_meminfo->attr = 0;
}
...@@ -29,6 +29,8 @@ ...@@ -29,6 +29,8 @@
*/ */
#include <arch.h> #include <arch.h>
#include <arch_helpers.h>
#include <assert.h>
#include <bl_common.h> #include <bl_common.h>
#include <bl31.h> #include <bl31.h>
#include <console.h> #include <console.h>
...@@ -66,38 +68,47 @@ extern unsigned long __COHERENT_RAM_END__; ...@@ -66,38 +68,47 @@ extern unsigned long __COHERENT_RAM_END__;
#define BL31_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__) #define BL31_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__)
#define BL31_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__) #define BL31_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__)
#if RESET_TO_BL31
static entry_point_info_t bl32_entrypoint_info;
static entry_point_info_t bl33_entrypoint_info;
#else
/******************************************************************************* /*******************************************************************************
* Reference to structure which holds the arguments that have been passed to * Reference to structure which holds the arguments that have been passed to
* BL31 from BL2. * BL31 from BL2.
******************************************************************************/ ******************************************************************************/
static bl31_args_t *bl2_to_bl31_args; static bl31_params_t *bl2_to_bl31_params;
#endif
meminfo_t *bl31_plat_sec_mem_layout(void)
{
return &bl2_to_bl31_args->bl31_meminfo;
}
meminfo_t *bl31_plat_get_bl32_mem_layout(void)
{
return &bl2_to_bl31_args->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 * security state specified. BL33 corresponds to the non-secure image type
* while BL32 corresponds to the secure image type. A NULL pointer is returned * while BL32 corresponds to the secure image type. A NULL pointer is returned
* if the image does not exist. * 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;
#if RESET_TO_BL31
if (type == NON_SECURE)
plat_get_entry_point_info(NON_SECURE, &bl33_entrypoint_info);
else
plat_get_entry_point_info(SECURE, &bl32_entrypoint_info);
next_image_info = (type == NON_SECURE) ? next_image_info = (type == NON_SECURE) ?
&bl2_to_bl31_args->bl33_image_info : &bl33_entrypoint_info :
&bl2_to_bl31_args->bl32_image_info; &bl32_entrypoint_info;
#else
next_image_info = (type == NON_SECURE) ?
bl2_to_bl31_params->bl33_ep_info :
bl2_to_bl31_params->bl32_ep_info;
#endif
/* None of the images on this platform can have 0x0 as the entrypoint */ /* 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; return next_image_info;
else else
return NULL; return NULL;
...@@ -114,16 +125,39 @@ el_change_info_t *bl31_get_next_image_info(uint32_t type) ...@@ -114,16 +125,39 @@ 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 * has flushed this information to memory, so we are guaranteed to pick up good
* data * data
******************************************************************************/ ******************************************************************************/
void bl31_early_platform_setup(bl31_args_t *from_bl2, void bl31_early_platform_setup(bl31_params_t *from_bl2,
void *data) void *plat_params_from_bl2)
{ {
bl2_to_bl31_args = from_bl2;
/* Initialize the console to provide early debug support */ /* Initialize the console to provide early debug support */
console_init(PL011_UART0_BASE); console_init(PL011_UART0_BASE);
/* Initialize the platform config for future decision making */ /* Initialize the platform config for future decision making */
platform_config_setup(); platform_config_setup();
#if RESET_TO_BL31
/* There are no parameters from BL2 if BL31 is a reset vector */
assert(from_bl2 == NULL);
assert(plat_params_from_bl2 == NULL);
/*
* Do initial security configuration to allow DRAM/device access. On
* Base FVP only DRAM security is programmable (via TrustZone), but
* other platforms might have more programmable security devices
* present.
*/
plat_security_setup();
#else
/* Check params passed from BL2 should not be NULL,
* We are not checking plat_params_from_bl2 as NULL as we are not
* using it on FVP
*/
assert(from_bl2 != NULL);
assert(from_bl2->h.type == PARAM_BL31);
assert(from_bl2->h.version >= VERSION_1);
bl2_to_bl31_params = from_bl2;
#endif
} }
/******************************************************************************* /*******************************************************************************
...@@ -172,9 +206,49 @@ void bl31_platform_setup() ...@@ -172,9 +206,49 @@ void bl31_platform_setup()
******************************************************************************/ ******************************************************************************/
void bl31_plat_arch_setup() void bl31_plat_arch_setup()
{ {
configure_mmu_el3(&bl2_to_bl31_args->bl31_meminfo, #if RESET_TO_BL31
fvp_cci_setup();
#endif
configure_mmu_el3(TZRAM_BASE,
TZRAM_SIZE,
BL31_RO_BASE, BL31_RO_BASE,
BL31_RO_LIMIT, BL31_RO_LIMIT,
BL31_COHERENT_RAM_BASE, BL31_COHERENT_RAM_BASE,
BL31_COHERENT_RAM_LIMIT); BL31_COHERENT_RAM_LIMIT);
} }
#if RESET_TO_BL31
/*******************************************************************************
* Generate the entry point info for Non Secure and Secure images
* for transferring control from BL31
******************************************************************************/
void plat_get_entry_point_info(unsigned long target_security,
entry_point_info_t *target_entry_info)
{
if (target_security == NON_SECURE) {
SET_PARAM_HEAD(target_entry_info,
PARAM_EP,
VERSION_1,
0);
/*
* Tell BL31 where the non-trusted software image
* is located and the entry state information
*/
target_entry_info->pc = plat_get_ns_image_entrypoint();
fvp_set_bl33_ep_info(target_entry_info);
} else {
SET_PARAM_HEAD(target_entry_info,
PARAM_EP,
VERSION_1,
0);
if (BL32_BASE != 0) {
/* Hard coding entry point to the base of the BL32 */
target_entry_info->pc = BL32_BASE;
fvp_set_bl32_ep_info(target_entry_info);
}
}
}
#endif
...@@ -63,38 +63,16 @@ extern unsigned long __COHERENT_RAM_END__; ...@@ -63,38 +63,16 @@ extern unsigned long __COHERENT_RAM_END__;
#define BL32_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__) #define BL32_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__)
#define BL32_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__) #define BL32_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__)
/* Data structure which holds the extents of the trusted SRAM for BL32 */
static meminfo_t bl32_tzdram_layout
__attribute__ ((aligned(PLATFORM_CACHE_LINE_SIZE),
section("tzfw_coherent_mem")));
meminfo_t *bl32_plat_sec_mem_layout(void)
{
return &bl32_tzdram_layout;
}
/******************************************************************************* /*******************************************************************************
* BL1 has passed the extents of the trusted SRAM that's at BL32's disposal. * Initialize the UART
* Initialize the BL32 data structure with the memory extends and initialize
* the UART
******************************************************************************/ ******************************************************************************/
void bl32_early_platform_setup(meminfo_t *mem_layout, void bl32_early_platform_setup(void)
void *data)
{ {
/* /*
* Initialize a different console than already in use to display * Initialize a different console than already in use to display
* messages from TSP * messages from TSP
*/ */
console_init(PL011_UART1_BASE); console_init(PL011_UART1_BASE);
/* Setup the BL32 memory layout */
bl32_tzdram_layout.total_base = mem_layout->total_base;
bl32_tzdram_layout.total_size = mem_layout->total_size;
bl32_tzdram_layout.free_base = mem_layout->free_base;
bl32_tzdram_layout.free_size = mem_layout->free_size;
bl32_tzdram_layout.attr = mem_layout->attr;
bl32_tzdram_layout.next = 0;
} }
/******************************************************************************* /*******************************************************************************
...@@ -111,7 +89,8 @@ void bl32_platform_setup() ...@@ -111,7 +89,8 @@ void bl32_platform_setup()
******************************************************************************/ ******************************************************************************/
void bl32_plat_arch_setup() void bl32_plat_arch_setup()
{ {
configure_mmu_el1(&bl32_tzdram_layout, configure_mmu_el1(BL32_RO_BASE,
(BL32_COHERENT_RAM_LIMIT - BL32_RO_BASE),
BL32_RO_BASE, BL32_RO_BASE,
BL32_RO_LIMIT, BL32_RO_LIMIT,
BL32_COHERENT_RAM_BASE, BL32_COHERENT_RAM_BASE,
......
...@@ -285,7 +285,7 @@ int fvp_affinst_on_finish(unsigned long mpidr, ...@@ -285,7 +285,7 @@ int fvp_affinst_on_finish(unsigned long mpidr,
unsigned int state) unsigned int state)
{ {
int rc = PSCI_E_SUCCESS; int rc = PSCI_E_SUCCESS;
unsigned long linear_id, cpu_setup, cci_setup; unsigned long linear_id, cpu_setup;
mailbox_t *fvp_mboxes; mailbox_t *fvp_mboxes;
unsigned int gicd_base, gicc_base, reg_val, ectlr; unsigned int gicd_base, gicc_base, reg_val, ectlr;
...@@ -308,10 +308,7 @@ int fvp_affinst_on_finish(unsigned long mpidr, ...@@ -308,10 +308,7 @@ int fvp_affinst_on_finish(unsigned long mpidr,
*/ */
fvp_pwrc_write_pponr(mpidr); fvp_pwrc_write_pponr(mpidr);
cci_setup = platform_get_cfgvar(CONFIG_HAS_CCI); fvp_cci_setup();
if (cci_setup) {
cci_enable_coherency(mpidr);
}
} }
break; break;
......
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#define __PLATFORM_H__ #define __PLATFORM_H__
#include <arch.h> #include <arch.h>
#include <bl_common.h>
/******************************************************************************* /*******************************************************************************
...@@ -134,6 +135,10 @@ ...@@ -134,6 +135,10 @@
#define TZDRAM_SIZE 0x02000000 #define TZDRAM_SIZE 0x02000000
#define MBOX_OFF 0x1000 #define MBOX_OFF 0x1000
/* Base address where parameters to BL31 are stored */
#define PARAMS_BASE TZDRAM_BASE
#define DRAM_BASE 0x80000000ull #define DRAM_BASE 0x80000000ull
#define DRAM_SIZE 0x80000000ull #define DRAM_SIZE 0x80000000ull
...@@ -339,7 +344,7 @@ ...@@ -339,7 +344,7 @@
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
#include <stdint.h> #include <stdint.h>
#include <bl_common.h>
typedef volatile struct mailbox { typedef volatile struct mailbox {
unsigned long value unsigned long value
...@@ -351,6 +356,26 @@ typedef volatile struct mailbox { ...@@ -351,6 +356,26 @@ typedef volatile struct mailbox {
******************************************************************************/ ******************************************************************************/
struct plat_pm_ops; struct plat_pm_ops;
struct meminfo; struct meminfo;
struct bl31_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 another platform specific params
******************************************************************************/
typedef struct bl2_to_bl31_params_mem {
struct bl31_params bl31_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 * Function and variable prototypes
...@@ -375,12 +400,14 @@ extern int platform_setup_pm(const struct plat_pm_ops **); ...@@ -375,12 +400,14 @@ extern int platform_setup_pm(const struct plat_pm_ops **);
extern unsigned int platform_get_core_pos(unsigned long mpidr); extern unsigned int platform_get_core_pos(unsigned long mpidr);
extern void enable_mmu_el1(void); extern void enable_mmu_el1(void);
extern void enable_mmu_el3(void); extern void enable_mmu_el3(void);
extern void configure_mmu_el1(struct meminfo *mem_layout, extern void configure_mmu_el1(unsigned long total_base,
unsigned long total_size,
unsigned long ro_start, unsigned long ro_start,
unsigned long ro_limit, unsigned long ro_limit,
unsigned long coh_start, unsigned long coh_start,
unsigned long coh_limit); unsigned long coh_limit);
extern void configure_mmu_el3(struct meminfo *mem_layout, extern void configure_mmu_el3(unsigned long total_base,
unsigned long total_size,
unsigned long ro_start, unsigned long ro_start,
unsigned long ro_limit, unsigned long ro_limit,
unsigned long coh_start, unsigned long coh_start,
...@@ -391,6 +418,12 @@ extern void plat_report_exception(unsigned long); ...@@ -391,6 +418,12 @@ extern void plat_report_exception(unsigned long);
extern unsigned long plat_get_ns_image_entrypoint(void); extern unsigned long plat_get_ns_image_entrypoint(void);
extern unsigned long platform_get_stack(unsigned long mpidr); extern unsigned long platform_get_stack(unsigned long mpidr);
extern uint64_t plat_get_syscnt_freq(void); extern uint64_t plat_get_syscnt_freq(void);
#if RESET_TO_BL31
extern void plat_get_entry_point_info(unsigned long target_security,
struct entry_point_info *target_entry_info);
#endif
extern void fvp_cci_setup(void);
/* Declarations for fvp_gic.c */ /* Declarations for fvp_gic.c */
extern void gic_cpuif_deactivate(unsigned int); extern void gic_cpuif_deactivate(unsigned int);
...@@ -412,6 +445,54 @@ extern int plat_get_image_source(const char *image_name, ...@@ -412,6 +445,54 @@ extern int plat_get_image_source(const char *image_name,
/* Declarations for plat_security.c */ /* Declarations for plat_security.c */
extern void plat_security_setup(void); 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);
/* Gets the memory layout for BL32 */
extern void bl2_plat_get_bl32_meminfo(struct meminfo *mem_info);
/* Gets the memory layout for BL33 */
extern void bl2_plat_get_bl33_meminfo(struct meminfo *mem_info);
/* Sets the entrypoint for BL32 */
extern void fvp_set_bl32_ep_info(struct entry_point_info *bl32_ep_info);
/* Sets the entrypoint for BL33 */
extern void fvp_set_bl33_ep_info(struct entry_point_info *bl33_ep_info);
#endif /*__ASSEMBLY__*/ #endif /*__ASSEMBLY__*/
......
...@@ -45,7 +45,6 @@ PLAT_BL_COMMON_SOURCES := drivers/arm/pl011/pl011.c \ ...@@ -45,7 +45,6 @@ PLAT_BL_COMMON_SOURCES := drivers/arm/pl011/pl011.c \
BL1_SOURCES += drivers/arm/cci400/cci400.c \ BL1_SOURCES += drivers/arm/cci400/cci400.c \
plat/common/aarch64/platform_up_stack.S \ plat/common/aarch64/platform_up_stack.S \
plat/fvp/bl1_plat_setup.c \ plat/fvp/bl1_plat_setup.c \
plat/fvp/aarch64/bl1_plat_helpers.S \
plat/fvp/aarch64/plat_common.c \ plat/fvp/aarch64/plat_common.c \
plat/fvp/aarch64/plat_helpers.S plat/fvp/aarch64/plat_helpers.S
...@@ -67,3 +66,8 @@ BL31_SOURCES += drivers/arm/gic/gic_v2.c \ ...@@ -67,3 +66,8 @@ BL31_SOURCES += drivers/arm/gic/gic_v2.c \
plat/fvp/aarch64/plat_helpers.S \ plat/fvp/aarch64/plat_helpers.S \
plat/fvp/aarch64/plat_common.c \ plat/fvp/aarch64/plat_common.c \
plat/fvp/drivers/pwrc/fvp_pwrc.c plat/fvp/drivers/pwrc/fvp_pwrc.c
ifeq (${RESET_TO_BL31}, 1)
BL31_SOURCES += drivers/arm/tzc400/tzc400.c \
plat/fvp/plat_security.c
endif
...@@ -91,7 +91,7 @@ int32_t tspd_init_secure_context(uint64_t entrypoint, ...@@ -91,7 +91,7 @@ int32_t tspd_init_secure_context(uint64_t entrypoint,
tsp_ctx->mpidr = mpidr; tsp_ctx->mpidr = mpidr;
cm_set_context(mpidr, &tsp_ctx->cpu_ctx, SECURE); cm_set_context(mpidr, &tsp_ctx->cpu_ctx, SECURE);
spsr = make_spsr(MODE_EL1, MODE_SP_ELX, rw); spsr = SPSR_64(MODE_EL1, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
cm_set_el3_eret_context(SECURE, entrypoint, spsr, scr); cm_set_el3_eret_context(SECURE, entrypoint, spsr, scr);
return 0; return 0;
......
...@@ -66,7 +66,7 @@ DEFINE_SVC_UUID(tsp_uuid, ...@@ -66,7 +66,7 @@ DEFINE_SVC_UUID(tsp_uuid,
0x5b3056a0, 0x3291, 0x427b, 0x98, 0x11, 0x5b3056a0, 0x3291, 0x427b, 0x98, 0x11,
0x71, 0x68, 0xca, 0x50, 0xf3, 0xfa); 0x71, 0x68, 0xca, 0x50, 0xf3, 0xfa);
int32_t tspd_init(meminfo_t *bl32_meminfo); int32_t tspd_init(void);
/******************************************************************************* /*******************************************************************************
...@@ -76,7 +76,7 @@ int32_t tspd_init(meminfo_t *bl32_meminfo); ...@@ -76,7 +76,7 @@ int32_t tspd_init(meminfo_t *bl32_meminfo);
******************************************************************************/ ******************************************************************************/
int32_t tspd_setup(void) int32_t tspd_setup(void)
{ {
el_change_info_t *image_info; entry_point_info_t *image_info;
int32_t rc; int32_t rc;
uint64_t mpidr = read_mpidr(); uint64_t mpidr = read_mpidr();
uint32_t linear_id; uint32_t linear_id;
...@@ -96,7 +96,7 @@ int32_t tspd_setup(void) ...@@ -96,7 +96,7 @@ int32_t tspd_setup(void)
* signalling failure initializing the service. We bail out without * signalling failure initializing the service. We bail out without
* registering any handlers * registering any handlers
*/ */
if (!image_info->entrypoint) if (!image_info->pc)
return 1; return 1;
/* /*
...@@ -104,7 +104,7 @@ int32_t tspd_setup(void) ...@@ -104,7 +104,7 @@ int32_t tspd_setup(void)
* state i.e whether AArch32 or AArch64. Assuming it's AArch64 * state i.e whether AArch32 or AArch64. Assuming it's AArch64
* for the time being. * for the time being.
*/ */
rc = tspd_init_secure_context(image_info->entrypoint, rc = tspd_init_secure_context(image_info->pc,
TSP_AARCH64, TSP_AARCH64,
mpidr, mpidr,
&tspd_sp_context[linear_id]); &tspd_sp_context[linear_id]);
...@@ -126,28 +126,15 @@ int32_t tspd_setup(void) ...@@ -126,28 +126,15 @@ int32_t tspd_setup(void)
* It also assumes that a valid non-secure context has been initialised by PSCI * It also assumes that a valid non-secure context has been initialised by PSCI
* so it does not need to save and restore any non-secure state. This function * so it does not need to save and restore any non-secure state. This function
* performs a synchronous entry into the Secure payload. The SP passes control * performs a synchronous entry into the Secure payload. The SP passes control
* back to this routine through a SMC. It also passes the extents of memory made * back to this routine through a SMC.
* available to BL32 by BL31.
******************************************************************************/ ******************************************************************************/
int32_t tspd_init(meminfo_t *bl32_meminfo) int32_t tspd_init(void)
{ {
uint64_t mpidr = read_mpidr(); uint64_t mpidr = read_mpidr();
uint32_t linear_id = platform_get_core_pos(mpidr); uint32_t linear_id = platform_get_core_pos(mpidr);
uint64_t rc; uint64_t rc;
tsp_context_t *tsp_ctx = &tspd_sp_context[linear_id]; tsp_context_t *tsp_ctx = &tspd_sp_context[linear_id];
/*
* Arrange for passing a pointer to the meminfo structure
* describing the memory extents available to the secure
* payload.
* TODO: We are passing a pointer to BL31 internal memory
* whereas this structure should be copied to a communication
* buffer between the SP and SPD.
*/
write_ctx_reg(get_gpregs_ctx(&tsp_ctx->cpu_ctx),
CTX_GPREG_X0,
(uint64_t) bl32_meminfo);
/* /*
* Arrange for an entry into the test secure payload. We expect an array * Arrange for an entry into the test secure payload. We expect an array
* of vectors in return * of vectors in return
......
...@@ -303,6 +303,7 @@ int psci_set_ns_entry_info(unsigned int index, ...@@ -303,6 +303,7 @@ int psci_set_ns_entry_info(unsigned int index,
unsigned int rw, mode, ee, spsr = 0; unsigned int rw, mode, ee, spsr = 0;
unsigned long id_aa64pfr0 = read_id_aa64pfr0_el1(), scr = read_scr(); unsigned long id_aa64pfr0 = read_id_aa64pfr0_el1(), scr = read_scr();
unsigned long el_status; unsigned long el_status;
unsigned long daif;
/* Figure out what mode do we enter the non-secure world in */ /* Figure out what mode do we enter the non-secure world in */
el_status = (id_aa64pfr0 >> ID_AA64PFR0_EL2_SHIFT) & el_status = (id_aa64pfr0 >> ID_AA64PFR0_EL2_SHIFT) &
...@@ -330,24 +331,18 @@ int psci_set_ns_entry_info(unsigned int index, ...@@ -330,24 +331,18 @@ int psci_set_ns_entry_info(unsigned int index,
ee = read_sctlr_el1() & SCTLR_EE_BIT; ee = read_sctlr_el1() & SCTLR_EE_BIT;
} }
spsr = DAIF_DBG_BIT | DAIF_ABT_BIT; spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
spsr |= DAIF_IRQ_BIT | DAIF_FIQ_BIT;
spsr <<= PSR_DAIF_SHIFT;
spsr |= make_spsr(mode, MODE_SP_ELX, !rw);
psci_ns_entry_info[index].sctlr |= ee; psci_ns_entry_info[index].sctlr |= ee;
psci_ns_entry_info[index].scr |= SCR_RW_BIT; psci_ns_entry_info[index].scr |= SCR_RW_BIT;
} else { } else {
/* Check whether aarch32 has to be entered in Thumb mode */
if (entrypoint & 0x1)
spsr = SPSR32_T_BIT;
if (el_status && (scr & SCR_HCE_BIT)) { if (el_status && (scr & SCR_HCE_BIT)) {
mode = AARCH32_MODE_HYP; mode = MODE32_hyp;
ee = read_sctlr_el2() & SCTLR_EE_BIT; ee = read_sctlr_el2() & SCTLR_EE_BIT;
} else { } else {
mode = AARCH32_MODE_SVC; mode = MODE32_svc;
ee = read_sctlr_el1() & SCTLR_EE_BIT; ee = read_sctlr_el1() & SCTLR_EE_BIT;
} }
...@@ -355,11 +350,9 @@ int psci_set_ns_entry_info(unsigned int index, ...@@ -355,11 +350,9 @@ int psci_set_ns_entry_info(unsigned int index,
* TODO: Choose async. exception bits if HYP mode is not * TODO: Choose async. exception bits if HYP mode is not
* implemented according to the values of SCR.{AW, FW} bits * implemented according to the values of SCR.{AW, FW} bits
*/ */
spsr |= DAIF_ABT_BIT | DAIF_IRQ_BIT | DAIF_FIQ_BIT; daif = DAIF_ABT_BIT | DAIF_IRQ_BIT | DAIF_FIQ_BIT;
spsr <<= PSR_DAIF_SHIFT;
if (ee) spsr = SPSR_MODE32(mode, entrypoint & 0x1, ee, daif);
spsr |= SPSR32_EE_BIT;
spsr |= mode;
/* Ensure that the CSPR.E and SCTLR.EE bits match */ /* Ensure that the CSPR.E and SCTLR.EE bits match */
psci_ns_entry_info[index].sctlr |= ee; psci_ns_entry_info[index].sctlr |= ee;
......
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