diff --git a/docs/porting-guide.md b/docs/porting-guide.md index 0f10fd4..81cbe1b 100644 --- a/docs/porting-guide.md +++ b/docs/porting-guide.md @@ -468,9 +468,6 @@ This function is called before any access to data is made by the firmware, in order to carry out any essential memory initialization. -The ARM FVP port uses this function to initialize the mailbox memory used for -providing the warm-boot entry-point addresses. - ### Function: plat_get_rotpk_info() diff --git a/include/plat/arm/css/common/css_def.h b/include/plat/arm/css/common/css_def.h index 268438f..e3dd2b0 100644 --- a/include/plat/arm/css/common/css_def.h +++ b/include/plat/arm/css/common/css_def.h @@ -39,8 +39,7 @@ *************************************************************************/ #define MHU_PAYLOAD_CACHED 0 -#define TRUSTED_MAILBOXES_BASE ARM_TRUSTED_SRAM_BASE -#define TRUSTED_MAILBOX_SHIFT 4 +#define TRUSTED_MAILBOX_BASE ARM_TRUSTED_SRAM_BASE #define NSROM_BASE 0x1f000000 #define NSROM_SIZE 0x00001000 diff --git a/plat/arm/board/fvp/aarch64/fvp_helpers.S b/plat/arm/board/fvp/aarch64/fvp_helpers.S index 2787ee6..9cf3c73 100644 --- a/plat/arm/board/fvp/aarch64/fvp_helpers.S +++ b/plat/arm/board/fvp/aarch64/fvp_helpers.S @@ -96,29 +96,30 @@ b cb_panic endfunc plat_secondary_cold_boot_setup - - /* ----------------------------------------------------- + /* --------------------------------------------------------------------- * unsigned long plat_get_my_entrypoint (void); * - * Main job of this routine is to distinguish between - * a cold and warm boot on the current CPU. - * On a cold boot the secondaries first wait for the - * platform to be initialized after which they are - * hotplugged in. The primary proceeds to perform the - * platform initialization. - * On a warm boot, each cpu jumps to the address in its - * mailbox. + * Main job of this routine is to distinguish between a cold and warm + * boot. On FVP, this information can be queried from the power + * controller. The Power Control SYS Status Register (PSYSR) indicates + * the wake-up reason for the CPU. * - * TODO: Not a good idea to save lr in a temp reg + * For a cold boot, return 0. + * For a warm boot, read the mailbox and return the address it contains. + * * TODO: PSYSR is a common register and should be * accessed using locks. Since its not possible * to use locks immediately after a cold reset * we are relying on the fact that after a cold * reset all cpus will read the same WK field - * ----------------------------------------------------- + * --------------------------------------------------------------------- */ func plat_get_my_entrypoint - mov x9, x30 // lr + /* --------------------------------------------------------------------- + * When bit PSYSR.WK indicates either "Wake by PPONR" or "Wake by GIC + * WakeRequest signal" then it is a warm boot. + * --------------------------------------------------------------------- + */ mrs x2, mpidr_el1 ldr x1, =PWRC_BASE str w2, [x1, #PSYSR_OFF] @@ -128,46 +129,41 @@ beq warm_reset cmp w2, #WKUP_GICREQ beq warm_reset + + /* Cold reset */ mov x0, #0 - b exit + ret + warm_reset: - /* --------------------------------------------- - * A per-cpu mailbox is maintained in the tru- - * sted DRAM. Its flushed out of the caches - * after every update using normal memory so - * its safe to read it here with SO attributes - * --------------------------------------------- + /* --------------------------------------------------------------------- + * A mailbox is maintained in the trusted SRAM. It is flushed out of the + * caches after every update using normal memory so it is safe to read + * it here with SO attributes. + * --------------------------------------------------------------------- */ - ldr x10, =MBOX_BASE - bl plat_my_core_pos - lsl x0, x0, #ARM_CACHE_WRITEBACK_SHIFT - ldr x0, [x10, x0] + mov_imm x0, MBOX_BASE + ldr x0, [x0] cbz x0, _panic -exit: - ret x9 -_panic: b _panic + ret + + /* --------------------------------------------------------------------- + * The power controller indicates this is a warm reset but the mailbox + * is empty. This should never happen! + * --------------------------------------------------------------------- + */ +_panic: + b _panic endfunc plat_get_my_entrypoint - /* ----------------------------------------------------- + /* --------------------------------------------------------------------- * void platform_mem_init (void); * - * Zero out the mailbox registers in the shared memory. - * The mmu is turned off right now and only the primary can - * ever execute this code. Secondaries will read the - * mailboxes using SO accesses. In short, BL31 will - * update the mailboxes after mapping the tzdram as - * normal memory. It will flush its copy after update. - * BL1 will always read the mailboxes with the MMU off - * ----------------------------------------------------- + * Nothing to do on FVP, the Trusted SRAM is available straight away + * after reset. + * --------------------------------------------------------------------- */ func platform_mem_init - ldr x0, =MBOX_BASE - mov w1, #PLATFORM_CORE_COUNT -loop: - str xzr, [x0], #CACHE_WRITEBACK_GRANULE - subs w1, w1, #1 - b.gt loop ret endfunc platform_mem_init diff --git a/plat/arm/board/fvp/fvp_def.h b/plat/arm/board/fvp/fvp_def.h index 842a287..6929481 100644 --- a/plat/arm/board/fvp/fvp_def.h +++ b/plat/arm/board/fvp/fvp_def.h @@ -139,7 +139,6 @@ /* Entrypoint mailboxes */ #define MBOX_BASE ARM_SHARED_RAM_BASE -#define MBOX_SIZE 0x200 #endif /* __FVP_DEF_H__ */ diff --git a/plat/arm/board/fvp/fvp_pm.c b/plat/arm/board/fvp/fvp_pm.c index 56d6502..8be5105 100644 --- a/plat/arm/board/fvp/fvp_pm.c +++ b/plat/arm/board/fvp/fvp_pm.c @@ -43,11 +43,6 @@ #include "fvp_def.h" #include "fvp_private.h" -unsigned long wakeup_address; - -typedef volatile struct mailbox { - unsigned long value __aligned(CACHE_WRITEBACK_GRANULE); -} mailbox_t; #if ARM_RECOM_STATE_ID_ENC /* @@ -74,16 +69,11 @@ * Private FVP function to program the mailbox for a cpu before it is released * from reset. ******************************************************************************/ -static void fvp_program_mailbox(uint64_t mpidr, uint64_t address) +static void fvp_program_mailbox(uintptr_t address) { - uint64_t linear_id; - mailbox_t *fvp_mboxes; - - linear_id = plat_arm_calc_core_pos(mpidr); - fvp_mboxes = (mailbox_t *)MBOX_BASE; - fvp_mboxes[linear_id].value = address; - flush_dcache_range((unsigned long) &fvp_mboxes[linear_id], - sizeof(unsigned long)); + uintptr_t *mailbox = (void *) MBOX_BASE; + *mailbox = address; + flush_dcache_range((uintptr_t) mailbox, sizeof(*mailbox)); } /******************************************************************************* @@ -150,9 +140,7 @@ psysr = fvp_pwrc_read_psysr(mpidr); } while (psysr & PSYSR_AFF_L0); - fvp_program_mailbox(mpidr, wakeup_address); fvp_pwrc_write_pponr(mpidr); - return rc; } @@ -200,9 +188,6 @@ /* Get the mpidr for this cpu */ mpidr = read_mpidr_el1(); - /* Program the jump address for the this cpu */ - fvp_program_mailbox(mpidr, wakeup_address); - /* Program the power controller to enable wakeup interrupts. */ fvp_pwrc_set_wen(mpidr); @@ -254,9 +239,6 @@ */ fvp_pwrc_clr_wen(mpidr); - /* Zero the jump address in the mailbox for this cpu */ - fvp_program_mailbox(mpidr, 0); - /* Enable the gic cpu interface */ arm_gic_cpuif_setup(); @@ -332,9 +314,8 @@ const plat_psci_ops_t **psci_ops) { *psci_ops = &fvp_plat_psci_ops; - wakeup_address = sec_entrypoint; - flush_dcache_range((unsigned long)&wakeup_address, - sizeof(wakeup_address)); + /* Program the jump address */ + fvp_program_mailbox(sec_entrypoint); return 0; } diff --git a/plat/arm/css/common/aarch64/css_helpers.S b/plat/arm/css/common/aarch64/css_helpers.S index a8c558b..478d5cf 100644 --- a/plat/arm/css/common/aarch64/css_helpers.S +++ b/plat/arm/css/common/aarch64/css_helpers.S @@ -53,28 +53,24 @@ b cb_panic endfunc plat_secondary_cold_boot_setup - /* ----------------------------------------------------- + /* --------------------------------------------------------------------- * unsigned long plat_get_my_entrypoint (void); * - * Main job of this routine is to distinguish between - * a cold and warm boot on the current CPU. - * On a cold boot the secondaries first wait for the - * platform to be initialized after which they are - * hotplugged in. The primary proceeds to perform the - * platform initialization. - * On a warm boot, each cpu jumps to the address in its - * mailbox. + * Main job of this routine is to distinguish between a cold and a warm + * boot. On CSS platforms, this distinction is based on the contents of + * the Trusted Mailbox. It is initialised to zero by the SCP before the + * AP cores are released from reset. Therefore, a zero mailbox means + * it's a cold reset. * - * TODO: Not a good idea to save lr in a temp reg - * ----------------------------------------------------- + * This functions returns the contents of the mailbox, i.e.: + * - 0 for a cold boot; + * - the warm boot entrypoint for a warm boot. + * --------------------------------------------------------------------- */ func plat_get_my_entrypoint - mov x9, x30 // lr - bl plat_my_core_pos - ldr x1, =TRUSTED_MAILBOXES_BASE - lsl x0, x0, #TRUSTED_MAILBOX_SHIFT - ldr x0, [x1, x0] - ret x9 + mov_imm x0, TRUSTED_MAILBOX_BASE + ldr x0, [x0] + ret endfunc plat_get_my_entrypoint /* ----------------------------------------------------------- diff --git a/plat/arm/css/common/css_pm.c b/plat/arm/css/common/css_pm.c index 49c364d..435ed2a 100644 --- a/plat/arm/css/common/css_pm.c +++ b/plat/arm/css/common/css_pm.c @@ -41,7 +41,6 @@ #include #include "css_scpi.h" -unsigned long wakeup_address; #if ARM_RECOM_STATE_ID_ENC /* @@ -68,15 +67,11 @@ * Private function to program the mailbox for a cpu before it is released * from reset. ******************************************************************************/ -static void css_program_mailbox(uint64_t mpidr, uint64_t address) +static void css_program_mailbox(uintptr_t address) { - uint64_t linear_id; - uint64_t mbox; - - linear_id = plat_arm_calc_core_pos(mpidr); - mbox = TRUSTED_MAILBOXES_BASE + (linear_id << TRUSTED_MAILBOX_SHIFT); - *((uint64_t *) mbox) = address; - flush_dcache_range(mbox, sizeof(mbox)); + uintptr_t *mailbox = (void *) TRUSTED_MAILBOX_BASE; + *mailbox = address; + flush_dcache_range((uintptr_t) mailbox, sizeof(*mailbox)); } /******************************************************************************* @@ -89,12 +84,6 @@ * SCP takes care of powering up parent power domains so we * only need to care about level 0 */ - - /* - * Setup mailbox with address for CPU entrypoint when it next powers up - */ - css_program_mailbox(mpidr, wakeup_address); - scpi_set_css_power_state(mpidr, scpi_power_on, scpi_power_on, scpi_power_on); @@ -124,9 +113,6 @@ /* todo: Is this setup only needed after a cold boot? */ arm_gic_pcpu_distif_setup(); - - /* Clear the mailbox for this cpu. */ - css_program_mailbox(read_mpidr_el1(), 0); } /******************************************************************************* @@ -188,11 +174,6 @@ assert(target_state->pwr_domain_state[ARM_PWR_LVL0] == ARM_LOCAL_STATE_OFF); - /* - * Setup mailbox with address for CPU entrypoint when it next powers up. - */ - css_program_mailbox(read_mpidr_el1(), wakeup_address); - css_power_down_common(target_state); } @@ -297,8 +278,7 @@ { *psci_ops = &css_ops; - wakeup_address = sec_entrypoint; - flush_dcache_range((unsigned long)&wakeup_address, - sizeof(wakeup_address)); + /* Setup mailbox with entry point. */ + css_program_mailbox(sec_entrypoint); return 0; }