Phriction Trusted Firmware Trusted Firmware-A (TF-A) Patchdescription Platarmboardfvpaarch64fvp Helperssvsplatarmboardfvp Rfvp R Helperss
Platarmboardfvpaarch64fvp Helperssvsplatarmboardfvp Rfvp R Helperss
Platarmboardfvpaarch64fvp Helperssvsplatarmboardfvp Rfvp R Helperss
/* /* * Copyright (c) 2013-2019, ARM Limited and Contributors. | * Copyright (c) 2013-2021, ARM Limited and Contributors. * * * SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause */ */ #include <arch.h> #include <arch.h> #include <asm_macros.S> #include <asm_macros.S> #include <drivers/arm/gicv2.h> #include <drivers/arm/gicv2.h> #include <drivers/arm/gicv3.h> #include <drivers/arm/gicv3.h> #include <drivers/arm/fvp/fvp_pwrc.h> #include <drivers/arm/fvp/fvp_pwrc.h> #include <platform_def.h> #include <platform_def.h> .globl plat_secondary_cold_boot_setup .globl plat_secondary_cold_boot_setup .globl plat_get_my_entrypoint .globl plat_get_my_entrypoint .globl plat_is_my_cpu_primary .globl plat_is_my_cpu_primary .globl plat_arm_calc_core_pos .globl plat_arm_calc_core_pos /* ----------------------------------------------- /* ----------------------------------------------- * void plat_secondary_cold_boot_setup (void); * void plat_secondary_cold_boot_setup (void); * * * This function performs any platform specific ac * This function performs any platform specific ac * needed for a secondary cpu after a cold reset e * needed for a secondary cpu after a cold reset e * mark the cpu's presence, mechanism to place it * mark the cpu's presence, mechanism to place it * holding pen etc. * holding pen etc. * TODO: Should we read the PSYS register to make * TODO: Should we read the PSYS register to make * that the request has gone through. * that the request has gone through. * ----------------------------------------------- * ----------------------------------------------- */ */ func plat_secondary_cold_boot_setup func plat_secondary_cold_boot_setup #ifndef EL3_PAYLOAD_BASE < /* --------------------------------------------- /* --------------------------------------------- * Power down this cpu. * Power down this cpu. * TODO: Do we need to worry about powering the * TODO: Do we need to worry about powering the * cluster down as well here. That will need | * cluster down as well here? That will need * locks which we won't have unless an elf- * locks which we won't have unless an elf- * loader zeroes out the zi section. * loader zeroes out the zi section. * --------------------------------------------- * --------------------------------------------- */ */ mrs x0, mpidr_el1 mrs x0, mpidr_el1 mov_imm x1, PWRC_BASE mov_imm x1, PWRC_BASE str w0, [x1, #PPOFFR_OFF] str w0, [x1, #PPOFFR_OFF] /* --------------------------------------------- /* --------------------------------------------- * There is no sane reason to come out of this * There is no sane reason to come out of this * wfi so panic if we do. This cpu will be pow- * wfi so panic if we do. This cpu will be pow- * ered on and reset by the cpu_on pm api * ered on and reset by the cpu_on pm api * --------------------------------------------- * --------------------------------------------- */ */ dsb sy dsb sy wfi wfi no_ret plat_panic_handler no_ret plat_panic_handler #else < mov_imm x0, PLAT_ARM_TRUSTED_MAILBOX_BASE < < /* Wait until the entrypoint gets populated */ < poll_mailbox: < ldr x1, [x0] < cbz x1, 1f < br x1 < 1: < wfe < b poll_mailbox < #endif /* EL3_PAYLOAD_BASE */ < endfunc plat_secondary_cold_boot_setup endfunc plat_secondary_cold_boot_setup /* ----------------------------------------------- /* ----------------------------------------------- * uintptr_t plat_get_my_entrypoint (void); * uintptr_t plat_get_my_entrypoint (void); * * * Main job of this routine is to distinguish betw * Main job of this routine is to distinguish betw * boot. On FVP, this information can be queried f | * boot. On FVP_R, this information can be queried * controller. The Power Control SYS Status Regist * controller. The Power Control SYS Status Regist * the wake-up reason for the CPU. * the wake-up reason for the CPU. * * * For a cold boot, return 0. * For a cold boot, return 0. * For a warm boot, read the mailbox and return th * For a warm boot, read the mailbox and return th * * * TODO: PSYSR is a common register and should be * TODO: PSYSR is a common register and should be * accessed using locks. Since it is not poss * accessed using locks. Since it is not poss * to use locks immediately after a cold rese * to use locks immediately after a cold rese * we are relying on the fact that after a co * we are relying on the fact that after a co * reset all cpus will read the same WK field * reset all cpus will read the same WK field * ----------------------------------------------- * ----------------------------------------------- */ */ func plat_get_my_entrypoint func plat_get_my_entrypoint /* ----------------------------------------------- /* ----------------------------------------------- * When bit PSYSR.WK indicates either "Wake by PPO * When bit PSYSR.WK indicates either "Wake by PPO * WakeRequest signal" then it is a warm boot. * WakeRequest signal" then it is a warm boot. * ----------------------------------------------- * ----------------------------------------------- */ */ mrs x2, mpidr_el1 mrs x2, mpidr_el1 mov_imm x1, PWRC_BASE mov_imm x1, PWRC_BASE str w2, [x1, #PSYSR_OFF] str w2, [x1, #PSYSR_OFF] ldr w2, [x1, #PSYSR_OFF] ldr w2, [x1, #PSYSR_OFF] ubfx w2, w2, #PSYSR_WK_SHIFT, #PSYSR_WK_WIDTH ubfx w2, w2, #PSYSR_WK_SHIFT, #PSYSR_WK_WIDTH cmp w2, #WKUP_PPONR cmp w2, #WKUP_PPONR beq warm_reset beq warm_reset cmp w2, #WKUP_GICREQ cmp w2, #WKUP_GICREQ beq warm_reset beq warm_reset /* Cold reset */ /* Cold reset */ mov x0, #0 mov x0, #0 ret ret warm_reset: warm_reset: /* ----------------------------------------------- /* ----------------------------------------------- * A mailbox is maintained in the trusted SRAM. It * A mailbox is maintained in the trusted SRAM. It * caches after every update using normal memory s * caches after every update using normal memory s * it here with SO attributes. * it here with SO attributes. * ----------------------------------------------- * ----------------------------------------------- */ */ mov_imm x0, PLAT_ARM_TRUSTED_MAILBOX_BASE mov_imm x0, PLAT_ARM_TRUSTED_MAILBOX_BASE ldr x0, [x0] ldr x0, [x0] cbz x0, _panic_handler cbz x0, _panic_handler ret ret /* ----------------------------------------------- /* ----------------------------------------------- * The power controller indicates this is a warm r * The power controller indicates this is a warm r * is empty. This should never happen! * is empty. This should never happen! * ----------------------------------------------- * ----------------------------------------------- */ */ _panic_handler: _panic_handler: no_ret plat_panic_handler no_ret plat_panic_handler endfunc plat_get_my_entrypoint endfunc plat_get_my_entrypoint /* ----------------------------------------------- /* ----------------------------------------------- * unsigned int plat_is_my_cpu_primary (void); * unsigned int plat_is_my_cpu_primary (void); * * * Find out whether the current cpu is the primary * Find out whether the current cpu is the primary * cpu. * cpu. * ----------------------------------------------- * ----------------------------------------------- */ */ func plat_is_my_cpu_primary func plat_is_my_cpu_primary mrs x0, mpidr_el1 mrs x0, mpidr_el1 mov_imm x1, MPIDR_AFFINITY_MASK mov_imm x1, MPIDR_AFFINITY_MASK and x0, x0, x1 and x0, x0, x1 cmp x0, #FVP_PRIMARY_CPU | cmp x0, #FVP_R_PRIMARY_CPU cset w0, eq cset w0, eq ret ret endfunc plat_is_my_cpu_primary endfunc plat_is_my_cpu_primary /* ----------------------------------------------- /* ----------------------------------------------- * unsigned int plat_arm_calc_core_pos(u_register_ * unsigned int plat_arm_calc_core_pos(u_register_ * * * Function to calculate the core position on FVP. | * Function to calculate the core position on FVP_ * * * (ClusterId * FVP_MAX_CPUS_PER_CLUSTER * FVP_MAX | * (ClusterId * FVP_R_MAX_CPUS_PER_CLUSTER * FVP_R * (CPUId * FVP_MAX_PE_PER_CPU) + | * (CPUId * FVP_R_MAX_PE_PER_CPU) + * ThreadId * ThreadId * * * which can be simplified as: * which can be simplified as: * * * ((ClusterId * FVP_MAX_CPUS_PER_CLUSTER + CPUId) | * ((ClusterId * FVP_R_MAX_CPUS_PER_CLUSTER + CPUI * + ThreadId * + ThreadId * ----------------------------------------------- * ----------------------------------------------- */ */ func plat_arm_calc_core_pos func plat_arm_calc_core_pos /* /* * Check for MT bit in MPIDR. If not set, shift MP * Check for MT bit in MPIDR. If not set, shift MP * look as if in a multi-threaded implementation. * look as if in a multi-threaded implementation. */ */ tst x0, #MPIDR_MT_MASK tst x0, #MPIDR_MT_MASK lsl x3, x0, #MPIDR_AFFINITY_BITS lsl x3, x0, #MPIDR_AFFINITY_BITS csel x3, x3, x0, eq csel x3, x3, x0, eq /* Extract individual affinity fields from MPIDR * /* Extract individual affinity fields from MPIDR * ubfx x0, x3, #MPIDR_AFF0_SHIFT, #MPIDR_AFFINITY ubfx x0, x3, #MPIDR_AFF0_SHIFT, #MPIDR_AFFINITY ubfx x1, x3, #MPIDR_AFF1_SHIFT, #MPIDR_AFFINITY ubfx x1, x3, #MPIDR_AFF1_SHIFT, #MPIDR_AFFINITY ubfx x2, x3, #MPIDR_AFF2_SHIFT, #MPIDR_AFFINITY ubfx x2, x3, #MPIDR_AFF2_SHIFT, #MPIDR_AFFINITY /* Compute linear position */ /* Compute linear position */ mov x4, #FVP_MAX_CPUS_PER_CLUSTER | mov x4, #FVP_R_MAX_CPUS_PER_CLUSTER madd x1, x2, x4, x1 madd x1, x2, x4, x1 mov x5, #FVP_MAX_PE_PER_CPU | mov x5, #FVP_R_MAX_PE_PER_CPU madd x0, x1, x5, x0 madd x0, x1, x5, x0 ret ret endfunc plat_arm_calc_core_pos endfunc plat_arm_calc_core_pos
Tags
None
Subscribers
None
- Last Author
- garymorrison-arm
- Last Edited
- Jul 2 2021, 10:47 PM