diff --git a/plat/juno/aarch64/plat_common.c b/plat/juno/aarch64/plat_common.c index af00a26..5319fe3 100644 --- a/plat/juno/aarch64/plat_common.c +++ b/plat/juno/aarch64/plat_common.c @@ -118,27 +118,28 @@ }; /******************************************************************************* -+ * Macro generating the code for the function setting up the pagetables as per -+ * the platform memory map & initialize the mmu, for the given exception level -+ ******************************************************************************/ -#define DEFINE_CONFIGURE_MMU_EL(_el) \ - void configure_mmu_el##_el(meminfo_t *mem_layout, \ - unsigned long ro_start, \ - unsigned long ro_limit, \ - unsigned long coh_start, \ - unsigned long coh_limit) \ - { \ - mmap_add_region(mem_layout->total_base, \ - mem_layout->total_size, \ - MT_MEMORY | MT_RW | MT_SECURE); \ - mmap_add_region(ro_start, ro_limit - ro_start, \ - MT_MEMORY | MT_RO | MT_SECURE); \ - mmap_add_region(coh_start, coh_limit - coh_start, \ - MT_DEVICE | MT_RW | MT_SECURE); \ - mmap_add(juno_mmap); \ - init_xlat_tables(); \ - \ - enable_mmu_el##_el(); \ + * Macro generating the code for the function setting up the pagetables as per + * the platform memory map & initialize the mmu, for the given exception level + ******************************************************************************/ +#define DEFINE_CONFIGURE_MMU_EL(_el) \ + void configure_mmu_el##_el(unsigned long total_base, \ + unsigned long total_size, \ + unsigned long ro_start, \ + unsigned long ro_limit, \ + unsigned long coh_start, \ + unsigned long coh_limit) \ + { \ + mmap_add_region(total_base, \ + total_size, \ + MT_MEMORY | MT_RW | MT_SECURE); \ + mmap_add_region(ro_start, ro_limit - ro_start, \ + MT_MEMORY | MT_RO | MT_SECURE); \ + mmap_add_region(coh_start, coh_limit - coh_start,\ + MT_DEVICE | MT_RW | MT_SECURE); \ + mmap_add(juno_mmap); \ + init_xlat_tables(); \ + \ + enable_mmu_el##_el(); \ } /* Define EL1 and EL3 variants of the function initialising the MMU */ diff --git a/plat/juno/bl1_plat_setup.c b/plat/juno/bl1_plat_setup.c index 1b84317..badfae4 100644 --- a/plat/juno/bl1_plat_setup.c +++ b/plat/juno/bl1_plat_setup.c @@ -228,9 +228,23 @@ */ cci_enable_coherency(read_mpidr()); - configure_mmu_el3(&bl1_tzram_layout, - TZROM_BASE, - TZROM_BASE + TZROM_SIZE, - BL1_COHERENT_RAM_BASE, - BL1_COHERENT_RAM_LIMIT); + configure_mmu_el3(bl1_tzram_layout.total_base, + bl1_tzram_layout.total_size, + TZROM_BASE, + TZROM_BASE + TZROM_SIZE, + 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 Juno 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); } diff --git a/plat/juno/bl2_plat_setup.c b/plat/juno/bl2_plat_setup.c index d8812b7..5e98f1d 100644 --- a/plat/juno/bl2_plat_setup.c +++ b/plat/juno/bl2_plat_setup.c @@ -75,18 +75,80 @@ __attribute__ ((aligned(PLATFORM_CACHE_LINE_SIZE), section("tzfw_coherent_mem"))); -static bl31_args_t bl2_to_bl31_args -__attribute__ ((aligned(PLATFORM_CACHE_LINE_SIZE), - section("tzfw_coherent_mem"))); +/******************************************************************************* + * Reference to structures which holds the arguments which need to be passed + * to BL31 + ******************************************************************************/ +static bl31_params_t *bl2_to_bl31_params; +static entry_point_info_t *bl31_ep_info; meminfo_t *bl2_plat_sec_mem_layout(void) { return &bl2_tzram_layout; } -bl31_args_t *bl2_get_bl31_args_ptr(void) +/******************************************************************************* + * 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) { - return &bl2_to_bl31_args; + bl2_to_bl31_params_mem_t *bl31_params_mem; + + /* + * 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 */ + /* Juno TODO: Pass the primary CPU MPID to UEFI. Must be in x0. */ + 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; } /******************************************************************************* @@ -94,10 +156,8 @@ * in x0. This memory layout is sitting at the base of the free trusted RAM. * Copy it to a safe loaction before its reclaimed by later BL2 functionality. ******************************************************************************/ -void bl2_early_platform_setup(meminfo_t *mem_layout, - void *data) +void bl2_early_platform_setup(meminfo_t *mem_layout) { - /* Initialize the console to provide early debug support */ console_init(PL011_UART0_BASE); @@ -117,6 +177,9 @@ * the image into. When this function exits, the RAM layout remains untouched * so the BL2 can load BL3-1 as normal. ******************************************************************************/ +/* + * Juno TODO: revisit, it won't compile. + */ static int load_bl30(void) { meminfo_t *bl2_tzram_layout; @@ -163,7 +226,7 @@ * image and initialise the memory location to use for passing arguments to * BL3-1. ******************************************************************************/ -void bl2_platform_setup() +void bl2_platform_setup(void) { /* Initialise the IO layer and register platform IO devices */ io_setup(); @@ -171,26 +234,13 @@ /* Load BL3-0 */ if (load_bl30() != 0) panic(); +} - /* Populate the extents of memory available for loading BL3-3 */ - 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 = BOT_LOAD; - bl2_to_bl31_args.bl33_meminfo.next = 0; - - /* Populate the extents of memory available for loading BL3-2 */ - 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 = - (TSP_SEC_MEM_BASE + TSP_SEC_MEM_SIZE) - BL32_BASE; - bl2_to_bl31_args.bl32_meminfo.free_size = - (TSP_SEC_MEM_BASE + TSP_SEC_MEM_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)); } /******************************************************************************* @@ -199,9 +249,106 @@ ******************************************************************************/ 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_LIMIT, 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 Juno 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 Juno 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 Juno 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); +} + +/******************************************************************************* + * Populate the extents of memory available for loading BL3-2 + ******************************************************************************/ +void bl2_plat_get_bl32_meminfo(meminfo_t *bl32_meminfo) +{ + /* + * Populate the extents of memory available for loading BL3-2. + */ + bl32_meminfo->total_base = BL32_BASE; + bl32_meminfo->free_base = BL32_BASE; + bl32_meminfo->total_size = + (TSP_SEC_MEM_BASE + TSP_SEC_MEM_SIZE) - BL32_BASE; + bl32_meminfo->free_size = + (TSP_SEC_MEM_BASE + TSP_SEC_MEM_SIZE) - BL32_BASE; + bl32_meminfo->attr = BOT_LOAD; + bl32_meminfo->next = 0; +} + + +/******************************************************************************* + * Populate the extents of memory available for loading BL3-3 + ******************************************************************************/ +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; +} diff --git a/plat/juno/bl31_plat_setup.c b/plat/juno/bl31_plat_setup.c index c967d14..5edc6af 100644 --- a/plat/juno/bl31_plat_setup.c +++ b/plat/juno/bl31_plat_setup.c @@ -29,6 +29,7 @@ */ #include +#include #include #include #include @@ -66,34 +67,28 @@ #define BL31_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__) #define BL31_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__) -static bl31_args_t bl2_to_bl31_args; - -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; -} +/****************************************************************************** + * Reference to structures which hold the arguments that have been passed to + * BL31 from BL2. + ******************************************************************************/ +static bl31_params_t *bl2_to_bl31_params; /******************************************************************************* - * Return a pointer to the 'el_change_info' structure of the next image for the - * security state specified. BL3-3 corresponds to the non-secure image type + * Return a pointer to the 'entry_point_info' structure of the next image for + * the security state specified. BL3-3 corresponds to the non-secure image type * while BL3-2 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; @@ -108,13 +103,16 @@ * Also, BL2 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, + void *plat_params_from_bl2) { /* Initialize the console to provide early debug support */ console_init(PL011_UART0_BASE); - 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; /* UEFI expects x0 to be primary CPU MPID */ bl2_to_bl31_args.bl33_image_info.args.arg0 = PRIMARY_CPU; @@ -140,7 +138,8 @@ ******************************************************************************/ void bl31_plat_arch_setup() { - configure_mmu_el3(&bl2_to_bl31_args.bl31_meminfo, + configure_mmu_el3(TZRAM_BASE, + TZRAM_SIZE, BL31_RO_BASE, BL31_RO_LIMIT, BL31_COHERENT_RAM_BASE, diff --git a/plat/juno/bl32_plat_setup.c b/plat/juno/bl32_plat_setup.c index 9dff42a..cb76da3 100644 --- a/plat/juno/bl32_plat_setup.c +++ b/plat/juno/bl32_plat_setup.c @@ -63,36 +63,16 @@ #define BL32_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__) #define BL32_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__) -/* Data structure which holds the extents of the trusted SRAM for BL3-2 */ -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 BL3-2's disposal. - * Initialize the BL3-2 data structure with the memory extends and initialize - * the UART + * Initialize the UART ******************************************************************************/ -void bl32_early_platform_setup(meminfo_t *mem_layout, void *data) +void bl32_early_platform_setup(void) { /* * Initialize a different console than already in use to display * messages from TSP */ console_init(PL011_UART1_BASE); - - /* Setup the BL3-2 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; } /******************************************************************************* @@ -108,7 +88,8 @@ ******************************************************************************/ void bl32_plat_arch_setup(void) { - configure_mmu_el1(&bl32_tzdram_layout, + configure_mmu_el1(BL32_RO_BASE, + BL32_COHERENT_RAM_LIMIT - BL32_RO_BASE, BL32_RO_BASE, BL32_RO_LIMIT, BL32_COHERENT_RAM_BASE, diff --git a/plat/juno/platform.h b/plat/juno/platform.h index aa1398e..0ac74e6 100644 --- a/plat/juno/platform.h +++ b/plat/juno/platform.h @@ -134,6 +134,10 @@ #define DRAM_BASE 0x80000000 #define DRAM_SIZE 0x80000000 +/* Base address where parameters to BL31 are stored */ +/* Juno TODO: Move BL3-1 arguments somewhere in trusted memory */ +#define PARAMS_BASE DRAM_BASE + /* Memory mapped Generic timer interfaces */ #define SYS_CNTCTL_BASE 0x2a430000 @@ -313,12 +317,31 @@ #ifndef __ASSEMBLY__ #include +#include /******************************************************************************* * Forward declarations ******************************************************************************/ struct plat_pm_ops; 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 @@ -343,12 +366,14 @@ extern unsigned int platform_get_core_pos(unsigned long mpidr); extern void enable_mmu_el1(void); extern void enable_mmu_el3(void); -extern void configure_mmu_el1(meminfo_t *mem_layout, +extern void configure_mmu_el1(unsigned long total_base, + unsigned long total_size, unsigned long ro_start, unsigned long ro_limit, unsigned long coh_start, unsigned long coh_limit); -extern void configure_mmu_el3(meminfo_t *mem_layout, +extern void configure_mmu_el3(unsigned long total_base, + unsigned long total_size, unsigned long ro_start, unsigned long ro_limit, unsigned long coh_start, @@ -375,6 +400,48 @@ extern int plat_get_image_source(const char *image_name, uintptr_t *dev_handle, uintptr_t *image_spec); +/* + * 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 BL3-2 */ +extern void bl2_plat_get_bl32_meminfo(struct meminfo *mem_info); + +/* Gets the memory layout for BL3-3 */ +extern void bl2_plat_get_bl33_meminfo(struct meminfo *mem_info); + #endif /*__ASSEMBLY__*/ #endif /* __PLATFORM_H__ */