diff options
author | Vikram Kanigiri <vikram.kanigiri@arm.com> | 2014-05-15 18:27:15 +0100 |
---|---|---|
committer | Vikram Kanigiri <vikram.kanigiri@arm.com> | 2014-05-22 15:43:23 +0100 |
commit | 29fb905d5f36a415a170a4bffeadf13b5f084345 (patch) | |
tree | 4cf20542c5219393010b1285dd88de5b0e2a519e /bl1 | |
parent | 23ff9baa7e01eac3a451f2e8ed768c9b90d3567a (diff) |
Rework handover interface between BL stages
This patch reworks the handover interface from: BL1 to BL2 and
BL2 to BL3-1. It removes the raise_el(), change_el(), drop_el()
and run_image() functions as they catered for code paths that were
never exercised.
BL1 calls bl1_run_bl2() to jump into BL2 instead of doing the same
by calling run_image(). Similarly, BL2 issues the SMC to transfer
execution to BL3-1 through BL1 directly. Only x0 and x1 are used
to pass arguments to BL31. These arguments and parameters for
running BL3-1 are passed through a reference to a
'el_change_info_t' structure. They were being passed value in
general purpose registers earlier.
Change-Id: Id4fd019a19a9595de063766d4a66295a2c9307e1
Diffstat (limited to 'bl1')
-rw-r--r-- | bl1/aarch64/bl1_exceptions.S | 97 | ||||
-rw-r--r-- | bl1/bl1_main.c | 61 |
2 files changed, 85 insertions, 73 deletions
diff --git a/bl1/aarch64/bl1_exceptions.S b/bl1/aarch64/bl1_exceptions.S index a87b20f5..3613b9f4 100644 --- a/bl1/aarch64/bl1_exceptions.S +++ b/bl1/aarch64/bl1_exceptions.S @@ -112,13 +112,51 @@ SErrorSPx: */ .align 7 SynchronousExceptionA64: - /* --------------------------------------------- + /* ------------------------------------------------ * Only a single SMC exception from BL2 to ask * 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 + * describing the BL3-1 entrypoint + * ------------------------------------------------ */ - b process_exception + mov x19, x0 + mov x20, x1 + + mrs x0, esr_el3 + ubfx x1, x0, #ESR_EC_SHIFT, #ESR_EC_LENGTH + cmp x1, #EC_AARCH64_SMC + b.ne panic + + mov x0, #RUN_IMAGE + cmp x19, x0 + b.ne panic + + mov x0, x20 + bl display_boot_progress + + ldp x0, x1, [x20, #EL_CHANGE_INFO_PC_OFFSET] + msr elr_el3, x0 + msr spsr_el3, x1 + ubfx x0, x1, #MODE_EL_SHIFT, #2 + cmp x0, #MODE_EL3 + b.ne panic + + 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)] + eret +panic: + mov x0, #SYNC_EXCEPTION_AARCH64 + bl plat_report_exception + + wfi + b panic check_vector_size SynchronousExceptionA64 .align 7 @@ -173,56 +211,3 @@ SErrorA32: bl plat_report_exception b SErrorA32 check_vector_size SErrorA32 - - .align 7 - -func process_exception - sub sp, sp, #0x40 - stp x0, x1, [sp, #0x0] - stp x2, x3, [sp, #0x10] - stp x4, x5, [sp, #0x20] - stp x6, x7, [sp, #0x30] - - mov x19, x0 - mov x20, x1 - mov x21, x2 - mov x0, #SYNC_EXCEPTION_AARCH64 - bl plat_report_exception - - mrs x0, esr_el3 - ubfx x1, x0, #ESR_EC_SHIFT, #ESR_EC_LENGTH - cmp x1, #EC_AARCH64_SMC - b.ne panic - mov x1, #RUN_IMAGE - cmp x19, x1 - b.ne panic - mov x0, x20 - mov x1, x21 - mov x2, x3 - mov x3, x4 - bl display_boot_progress - msr elr_el3, x20 - msr spsr_el3, x21 - ubfx x0, x21, #MODE_EL_SHIFT, #2 - cmp x0, #MODE_EL3 - b.ne skip_mmu_teardown - - /* --------------------------------------------- - * If BL31 is to be executed in EL3 as well - * then turn off the MMU so that it can perform - * its own setup. - * --------------------------------------------- - */ - bl disable_mmu_icache_el3 - tlbi alle3 -skip_mmu_teardown: - ldp x6, x7, [sp, #0x30] - ldp x4, x5, [sp, #0x20] - ldp x2, x3, [sp, #0x10] - ldp x0, x1, [sp, #0x0] - add sp, sp, #0x40 - eret - -panic: - wfi - b panic diff --git a/bl1/bl1_main.c b/bl1/bl1_main.c index ecf25506..80e52ca1 100644 --- a/bl1/bl1_main.c +++ b/bl1/bl1_main.c @@ -38,6 +38,34 @@ #include "bl1_private.h" /******************************************************************************* + * 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) +{ + 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); + + write_spsr_el3(bl2_ep->spsr); + write_elr_el3(bl2_ep->entrypoint); + + eret(bl2_ep->args.arg0, + bl2_ep->args.arg1, + bl2_ep->args.arg2, + bl2_ep->args.arg3, + bl2_ep->args.arg4, + bl2_ep->args.arg5, + bl2_ep->args.arg6, + bl2_ep->args.arg7); +} + + +/******************************************************************************* * Function to perform late architectural and platform specific initialization. * It also locates and loads the BL2 raw binary image in the trusted DRAM. Only * called by the primary cpu after a cold boot. @@ -50,9 +78,10 @@ void bl1_main(void) unsigned long sctlr_el3 = read_sctlr_el3(); #endif unsigned long bl2_base; - unsigned int load_type = TOP_LOAD, spsr; + unsigned int load_type = TOP_LOAD; meminfo_t *bl1_tzram_layout; meminfo_t *bl2_tzram_layout = 0x0; + el_change_info_t bl2_ep = {0}; /* * Ensure that MMU/Caches and coherency are turned on @@ -94,20 +123,19 @@ void bl1_main(void) bl2_base); if (bl2_base) { - bl1_arch_next_el_setup(); - spsr = SPSR_64(MODE_EL1, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS); + 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"); #if DEBUG printf("BL2 address = 0x%llx \n\r", (unsigned long long) bl2_base); - printf("BL2 cpsr = 0x%x \n\r", spsr); + 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); #endif - run_image(bl2_base, - spsr, - SECURE, - (void *) bl2_tzram_layout, - NULL); + bl1_run_bl2(&bl2_ep); } /* @@ -122,17 +150,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(unsigned long entrypoint, - unsigned long spsr, - unsigned long mem_layout, - unsigned long ns_image_info) +void display_boot_progress(el_change_info_t *bl31_ep_info) { printf("Booting trusted firmware boot loader stage 3\n\r"); #if DEBUG - printf("BL31 address = 0x%llx \n\r", (unsigned long long) entrypoint); - printf("BL31 cpsr = 0x%llx \n\r", (unsigned long long)spsr); - printf("BL31 memory layout address = 0x%llx \n\r", (unsigned long long)mem_layout); - printf("BL31 non-trusted image info address = 0x%llx\n\r", (unsigned long long)ns_image_info); + 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", + (unsigned long long)bl31_ep_info->args.arg0); #endif return; } |