Merge pull request #169 from achingupta/ag/tf-issues#198
Ag/tf issues#198
This commit is contained in:
commit
d9b1128b43
|
@ -130,14 +130,16 @@ func bl1_entrypoint
|
||||||
ldr x2, =__DATA_SIZE__
|
ldr x2, =__DATA_SIZE__
|
||||||
bl memcpy16
|
bl memcpy16
|
||||||
|
|
||||||
/* ---------------------------------------------
|
/* --------------------------------------------
|
||||||
* Give ourselves a small coherent stack to
|
* Allocate a stack whose memory will be marked
|
||||||
* ease the pain of initializing the MMU and
|
* as Normal-IS-WBWA when the MMU is enabled.
|
||||||
* CCI in assembler
|
* There is no risk of reading stale stack
|
||||||
* ---------------------------------------------
|
* memory after enabling the MMU as only the
|
||||||
|
* primary cpu is running at the moment.
|
||||||
|
* --------------------------------------------
|
||||||
*/
|
*/
|
||||||
mrs x0, mpidr_el1
|
mrs x0, mpidr_el1
|
||||||
bl platform_set_coherent_stack
|
bl platform_set_stack
|
||||||
|
|
||||||
/* ---------------------------------------------
|
/* ---------------------------------------------
|
||||||
* Architectural init. can be generic e.g.
|
* Architectural init. can be generic e.g.
|
||||||
|
@ -150,14 +152,6 @@ func bl1_entrypoint
|
||||||
bl bl1_early_platform_setup
|
bl bl1_early_platform_setup
|
||||||
bl bl1_plat_arch_setup
|
bl bl1_plat_arch_setup
|
||||||
|
|
||||||
/* ---------------------------------------------
|
|
||||||
* Give ourselves a stack allocated in Normal
|
|
||||||
* -IS-WBWA memory
|
|
||||||
* ---------------------------------------------
|
|
||||||
*/
|
|
||||||
mrs x0, mpidr_el1
|
|
||||||
bl platform_set_stack
|
|
||||||
|
|
||||||
/* --------------------------------------------------
|
/* --------------------------------------------------
|
||||||
* Initialize platform and jump to our c-entry point
|
* Initialize platform and jump to our c-entry point
|
||||||
* for this type of reset. Panic if it returns
|
* for this type of reset. Panic if it returns
|
||||||
|
|
|
@ -96,12 +96,15 @@ func bl2_entrypoint
|
||||||
bl zeromem16
|
bl zeromem16
|
||||||
|
|
||||||
/* --------------------------------------------
|
/* --------------------------------------------
|
||||||
* Give ourselves a small coherent stack to
|
* Allocate a stack whose memory will be marked
|
||||||
* ease the pain of initializing the MMU
|
* as Normal-IS-WBWA when the MMU is enabled.
|
||||||
|
* There is no risk of reading stale stack
|
||||||
|
* memory after enabling the MMU as only the
|
||||||
|
* primary cpu is running at the moment.
|
||||||
* --------------------------------------------
|
* --------------------------------------------
|
||||||
*/
|
*/
|
||||||
mrs x0, mpidr_el1
|
mrs x0, mpidr_el1
|
||||||
bl platform_set_coherent_stack
|
bl platform_set_stack
|
||||||
|
|
||||||
/* ---------------------------------------------
|
/* ---------------------------------------------
|
||||||
* Perform early platform setup & platform
|
* Perform early platform setup & platform
|
||||||
|
@ -112,14 +115,6 @@ func bl2_entrypoint
|
||||||
bl bl2_early_platform_setup
|
bl bl2_early_platform_setup
|
||||||
bl bl2_plat_arch_setup
|
bl bl2_plat_arch_setup
|
||||||
|
|
||||||
/* ---------------------------------------------
|
|
||||||
* Give ourselves a stack allocated in Normal
|
|
||||||
* -IS-WBWA memory
|
|
||||||
* ---------------------------------------------
|
|
||||||
*/
|
|
||||||
mrs x0, mpidr_el1
|
|
||||||
bl platform_set_stack
|
|
||||||
|
|
||||||
/* ---------------------------------------------
|
/* ---------------------------------------------
|
||||||
* Jump to main function.
|
* Jump to main function.
|
||||||
* ---------------------------------------------
|
* ---------------------------------------------
|
||||||
|
|
|
@ -152,12 +152,15 @@ func bl31_entrypoint
|
||||||
msr spsel, #0
|
msr spsel, #0
|
||||||
|
|
||||||
/* --------------------------------------------
|
/* --------------------------------------------
|
||||||
* Give ourselves a small coherent stack to
|
* Allocate a stack whose memory will be marked
|
||||||
* ease the pain of initializing the MMU
|
* as Normal-IS-WBWA when the MMU is enabled.
|
||||||
|
* There is no risk of reading stale stack
|
||||||
|
* memory after enabling the MMU as only the
|
||||||
|
* primary cpu is running at the moment.
|
||||||
* --------------------------------------------
|
* --------------------------------------------
|
||||||
*/
|
*/
|
||||||
mrs x0, mpidr_el1
|
mrs x0, mpidr_el1
|
||||||
bl platform_set_coherent_stack
|
bl platform_set_stack
|
||||||
|
|
||||||
/* ---------------------------------------------
|
/* ---------------------------------------------
|
||||||
* Perform platform specific early arch. setup
|
* Perform platform specific early arch. setup
|
||||||
|
@ -174,14 +177,6 @@ func bl31_entrypoint
|
||||||
bl bl31_early_platform_setup
|
bl bl31_early_platform_setup
|
||||||
bl bl31_plat_arch_setup
|
bl bl31_plat_arch_setup
|
||||||
|
|
||||||
/* ---------------------------------------------
|
|
||||||
* Give ourselves a stack allocated in Normal
|
|
||||||
* -IS-WBWA memory
|
|
||||||
* ---------------------------------------------
|
|
||||||
*/
|
|
||||||
mrs x0, mpidr_el1
|
|
||||||
bl platform_set_stack
|
|
||||||
|
|
||||||
/* ---------------------------------------------
|
/* ---------------------------------------------
|
||||||
* Jump to main function.
|
* Jump to main function.
|
||||||
* ---------------------------------------------
|
* ---------------------------------------------
|
||||||
|
|
|
@ -43,23 +43,9 @@
|
||||||
.global el3_sysregs_context_save
|
.global el3_sysregs_context_save
|
||||||
func el3_sysregs_context_save
|
func el3_sysregs_context_save
|
||||||
|
|
||||||
mrs x10, sctlr_el3
|
mrs x10, cptr_el3
|
||||||
str x10, [x0, #CTX_SCTLR_EL3]
|
mrs x11, cntfrq_el0
|
||||||
|
stp x10, x11, [x0, #CTX_CPTR_EL3]
|
||||||
mrs x11, cptr_el3
|
|
||||||
stp x11, xzr, [x0, #CTX_CPTR_EL3]
|
|
||||||
|
|
||||||
mrs x13, cntfrq_el0
|
|
||||||
mrs x14, mair_el3
|
|
||||||
stp x13, x14, [x0, #CTX_CNTFRQ_EL0]
|
|
||||||
|
|
||||||
mrs x15, tcr_el3
|
|
||||||
mrs x16, ttbr0_el3
|
|
||||||
stp x15, x16, [x0, #CTX_TCR_EL3]
|
|
||||||
|
|
||||||
mrs x17, daif
|
|
||||||
and x17, x17, #(DAIF_ABT_BIT | DAIF_DBG_BIT)
|
|
||||||
stp x17, xzr, [x0, #CTX_DAIF_EL3]
|
|
||||||
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
@ -78,27 +64,9 @@ func el3_sysregs_context_save
|
||||||
.global el3_sysregs_context_restore
|
.global el3_sysregs_context_restore
|
||||||
func el3_sysregs_context_restore
|
func el3_sysregs_context_restore
|
||||||
|
|
||||||
ldp x11, xzr, [x0, #CTX_CPTR_EL3]
|
ldp x13, x14, [x0, #CTX_CPTR_EL3]
|
||||||
msr cptr_el3, x11
|
msr cptr_el3, x13
|
||||||
|
msr cntfrq_el0, x14
|
||||||
ldp x13, x14, [x0, #CTX_CNTFRQ_EL0]
|
|
||||||
msr cntfrq_el0, x13
|
|
||||||
msr mair_el3, x14
|
|
||||||
|
|
||||||
ldp x15, x16, [x0, #CTX_TCR_EL3]
|
|
||||||
msr tcr_el3, x15
|
|
||||||
msr ttbr0_el3, x16
|
|
||||||
|
|
||||||
ldp x17, xzr, [x0, #CTX_DAIF_EL3]
|
|
||||||
mrs x11, daif
|
|
||||||
orr x17, x17, x11
|
|
||||||
msr daif, x17
|
|
||||||
|
|
||||||
/* Make sure all the above changes are observed */
|
|
||||||
isb
|
|
||||||
|
|
||||||
ldr x10, [x0, #CTX_SCTLR_EL3]
|
|
||||||
msr sctlr_el3, x10
|
|
||||||
isb
|
isb
|
||||||
|
|
||||||
ret
|
ret
|
||||||
|
|
|
@ -403,7 +403,7 @@ smc_handler64:
|
||||||
mrs x17, elr_el3
|
mrs x17, elr_el3
|
||||||
mrs x18, scr_el3
|
mrs x18, scr_el3
|
||||||
stp x16, x17, [x6, #CTX_EL3STATE_OFFSET + CTX_SPSR_EL3]
|
stp x16, x17, [x6, #CTX_EL3STATE_OFFSET + CTX_SPSR_EL3]
|
||||||
stp x18, xzr, [x6, #CTX_EL3STATE_OFFSET + CTX_SCR_EL3]
|
str x18, [x6, #CTX_EL3STATE_OFFSET + CTX_SCR_EL3]
|
||||||
|
|
||||||
/* Copy SCR_EL3.NS bit to the flag to indicate caller's security */
|
/* Copy SCR_EL3.NS bit to the flag to indicate caller's security */
|
||||||
bfi x7, x18, #0, #1
|
bfi x7, x18, #0, #1
|
||||||
|
@ -446,7 +446,7 @@ el3_exit: ; .type el3_exit, %function
|
||||||
* Restore SPSR_EL3, ELR_EL3 and SCR_EL3 prior to ERET
|
* Restore SPSR_EL3, ELR_EL3 and SCR_EL3 prior to ERET
|
||||||
* -----------------------------------------------------
|
* -----------------------------------------------------
|
||||||
*/
|
*/
|
||||||
ldp x18, xzr, [sp, #CTX_EL3STATE_OFFSET + CTX_SCR_EL3]
|
ldr x18, [sp, #CTX_EL3STATE_OFFSET + CTX_SCR_EL3]
|
||||||
ldp x16, x17, [sp, #CTX_EL3STATE_OFFSET + CTX_SPSR_EL3]
|
ldp x16, x17, [sp, #CTX_EL3STATE_OFFSET + CTX_SPSR_EL3]
|
||||||
msr scr_el3, x18
|
msr scr_el3, x18
|
||||||
msr spsr_el3, x16
|
msr spsr_el3, x16
|
||||||
|
|
|
@ -48,6 +48,7 @@ BL31_SOURCES += bl31/bl31_main.c \
|
||||||
services/std_svc/psci/psci_afflvl_suspend.c \
|
services/std_svc/psci/psci_afflvl_suspend.c \
|
||||||
services/std_svc/psci/psci_common.c \
|
services/std_svc/psci/psci_common.c \
|
||||||
services/std_svc/psci/psci_entry.S \
|
services/std_svc/psci/psci_entry.S \
|
||||||
|
services/std_svc/psci/psci_helpers.S \
|
||||||
services/std_svc/psci/psci_main.c \
|
services/std_svc/psci/psci_main.c \
|
||||||
services/std_svc/psci/psci_setup.c
|
services/std_svc/psci/psci_setup.c
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include <arch.h>
|
#include <arch.h>
|
||||||
#include <asm_macros.S>
|
#include <asm_macros.S>
|
||||||
#include <tsp.h>
|
#include <tsp.h>
|
||||||
|
#include <xlat_tables.h>
|
||||||
|
|
||||||
|
|
||||||
.globl tsp_entrypoint
|
.globl tsp_entrypoint
|
||||||
|
@ -111,12 +112,15 @@ func tsp_entrypoint
|
||||||
bl zeromem16
|
bl zeromem16
|
||||||
|
|
||||||
/* --------------------------------------------
|
/* --------------------------------------------
|
||||||
* Give ourselves a small coherent stack to
|
* Allocate a stack whose memory will be marked
|
||||||
* ease the pain of initializing the MMU
|
* as Normal-IS-WBWA when the MMU is enabled.
|
||||||
|
* There is no risk of reading stale stack
|
||||||
|
* memory after enabling the MMU as only the
|
||||||
|
* primary cpu is running at the moment.
|
||||||
* --------------------------------------------
|
* --------------------------------------------
|
||||||
*/
|
*/
|
||||||
mrs x0, mpidr_el1
|
mrs x0, mpidr_el1
|
||||||
bl platform_set_coherent_stack
|
bl platform_set_stack
|
||||||
|
|
||||||
/* ---------------------------------------------
|
/* ---------------------------------------------
|
||||||
* Perform early platform setup & platform
|
* Perform early platform setup & platform
|
||||||
|
@ -126,14 +130,6 @@ func tsp_entrypoint
|
||||||
bl bl32_early_platform_setup
|
bl bl32_early_platform_setup
|
||||||
bl bl32_plat_arch_setup
|
bl bl32_plat_arch_setup
|
||||||
|
|
||||||
/* ---------------------------------------------
|
|
||||||
* Give ourselves a stack allocated in Normal
|
|
||||||
* -IS-WBWA memory
|
|
||||||
* ---------------------------------------------
|
|
||||||
*/
|
|
||||||
mrs x0, mpidr_el1
|
|
||||||
bl platform_set_stack
|
|
||||||
|
|
||||||
/* ---------------------------------------------
|
/* ---------------------------------------------
|
||||||
* Jump to main function.
|
* Jump to main function.
|
||||||
* ---------------------------------------------
|
* ---------------------------------------------
|
||||||
|
@ -209,26 +205,48 @@ func tsp_cpu_on_entry
|
||||||
isb
|
isb
|
||||||
|
|
||||||
/* --------------------------------------------
|
/* --------------------------------------------
|
||||||
* Give ourselves a small coherent stack to
|
* Give ourselves a stack whose memory will be
|
||||||
* ease the pain of initializing the MMU
|
* marked as Normal-IS-WBWA when the MMU is
|
||||||
|
* enabled.
|
||||||
* --------------------------------------------
|
* --------------------------------------------
|
||||||
*/
|
*/
|
||||||
mrs x0, mpidr_el1
|
mrs x0, mpidr_el1
|
||||||
bl platform_set_coherent_stack
|
bl platform_set_stack
|
||||||
|
|
||||||
/* ---------------------------------------------
|
/* --------------------------------------------
|
||||||
* Initialise the MMU
|
* Enable the MMU with the DCache disabled. It
|
||||||
* ---------------------------------------------
|
* is safe to use stacks allocated in normal
|
||||||
|
* memory as a result. All memory accesses are
|
||||||
|
* marked nGnRnE when the MMU is disabled. So
|
||||||
|
* all the stack writes will make it to memory.
|
||||||
|
* All memory accesses are marked Non-cacheable
|
||||||
|
* when the MMU is enabled but D$ is disabled.
|
||||||
|
* So used stack memory is guaranteed to be
|
||||||
|
* visible immediately after the MMU is enabled
|
||||||
|
* Enabling the DCache at the same time as the
|
||||||
|
* MMU can lead to speculatively fetched and
|
||||||
|
* possibly stale stack memory being read from
|
||||||
|
* other caches. This can lead to coherency
|
||||||
|
* issues.
|
||||||
|
* --------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
mov x0, #DISABLE_DCACHE
|
||||||
bl bl32_plat_enable_mmu
|
bl bl32_plat_enable_mmu
|
||||||
|
|
||||||
/* ---------------------------------------------
|
/* ---------------------------------------------
|
||||||
* Give ourselves a stack allocated in Normal
|
* Enable the Data cache now that the MMU has
|
||||||
* -IS-WBWA memory
|
* been enabled. The stack has been unwound. It
|
||||||
|
* will be written first before being read. This
|
||||||
|
* will invalidate any stale cache lines resi-
|
||||||
|
* -dent in other caches. We assume that
|
||||||
|
* interconnect coherency has been enabled for
|
||||||
|
* this cluster by EL3 firmware.
|
||||||
* ---------------------------------------------
|
* ---------------------------------------------
|
||||||
*/
|
*/
|
||||||
mrs x0, mpidr_el1
|
mrs x0, sctlr_el1
|
||||||
bl platform_set_stack
|
orr x0, x0, #SCTLR_C_BIT
|
||||||
|
msr sctlr_el1, x0
|
||||||
|
isb
|
||||||
|
|
||||||
/* ---------------------------------------------
|
/* ---------------------------------------------
|
||||||
* Enter C runtime to perform any remaining
|
* Enter C runtime to perform any remaining
|
||||||
|
|
|
@ -104,12 +104,6 @@ file is found in [plat/fvp/include/platform_def.h].
|
||||||
by [plat/common/aarch64/platform_mp_stack.S] and
|
by [plat/common/aarch64/platform_mp_stack.S] and
|
||||||
[plat/common/aarch64/platform_up_stack.S].
|
[plat/common/aarch64/platform_up_stack.S].
|
||||||
|
|
||||||
* **#define : PCPU_DV_MEM_STACK_SIZE**
|
|
||||||
|
|
||||||
Defines the coherent stack memory available to each CPU. This constant is used
|
|
||||||
by [plat/common/aarch64/platform_mp_stack.S] and
|
|
||||||
[plat/common/aarch64/platform_up_stack.S].
|
|
||||||
|
|
||||||
* **#define : FIRMWARE_WELCOME_STR**
|
* **#define : FIRMWARE_WELCOME_STR**
|
||||||
|
|
||||||
Defines the character string printed by BL1 upon entry into the `bl1_main()`
|
Defines the character string printed by BL1 upon entry into the `bl1_main()`
|
||||||
|
@ -395,31 +389,6 @@ maximum of 4 CPUs:
|
||||||
cluster_id = 8-bit value in MPIDR at affinity level 1
|
cluster_id = 8-bit value in MPIDR at affinity level 1
|
||||||
|
|
||||||
|
|
||||||
### Function : platform_set_coherent_stack()
|
|
||||||
|
|
||||||
Argument : unsigned long
|
|
||||||
Return : void
|
|
||||||
|
|
||||||
A platform may need stack memory that is coherent with main memory to perform
|
|
||||||
certain operations like:
|
|
||||||
|
|
||||||
* Turning the MMU on, or
|
|
||||||
* Flushing caches prior to powering down a CPU or cluster.
|
|
||||||
|
|
||||||
Each BL stage allocates this coherent stack memory for each CPU in the
|
|
||||||
`tzfw_coherent_mem` section.
|
|
||||||
|
|
||||||
This function sets the current stack pointer to the coherent stack that
|
|
||||||
has been allocated for the CPU specified by MPIDR. For BL images that only
|
|
||||||
require a stack for the primary CPU the parameter is ignored. The size of
|
|
||||||
the stack allocated to each CPU is specified by the platform defined constant
|
|
||||||
`PCPU_DV_MEM_STACK_SIZE`.
|
|
||||||
|
|
||||||
Common implementations of this function for the UP and MP BL images are
|
|
||||||
provided in [plat/common/aarch64/platform_up_stack.S] and
|
|
||||||
[plat/common/aarch64/platform_mp_stack.S]
|
|
||||||
|
|
||||||
|
|
||||||
### Function : platform_is_primary_cpu()
|
### Function : platform_is_primary_cpu()
|
||||||
|
|
||||||
Argument : unsigned long
|
Argument : unsigned long
|
||||||
|
@ -1116,11 +1085,6 @@ the calling CPU is the last powered on CPU in the cluster, after powering down
|
||||||
affinity level 0 (CPU), the platform port should power down affinity level 1
|
affinity level 0 (CPU), the platform port should power down affinity level 1
|
||||||
(the cluster) as well.
|
(the cluster) as well.
|
||||||
|
|
||||||
This function is called with coherent stacks. This allows the PSCI
|
|
||||||
implementation to flush caches at a given affinity level without running into
|
|
||||||
stale stack state after turning off the caches. On ARMv8-A cache hits do not
|
|
||||||
occur after the cache has been turned off.
|
|
||||||
|
|
||||||
#### plat_pm_ops.affinst_suspend()
|
#### plat_pm_ops.affinst_suspend()
|
||||||
|
|
||||||
Perform the platform specific setup to power off an affinity instance in the
|
Perform the platform specific setup to power off an affinity instance in the
|
||||||
|
@ -1143,11 +1107,6 @@ case, the affinity instance is expected to save enough state so that it can
|
||||||
resume execution by restoring this state when its powered on (see
|
resume execution by restoring this state when its powered on (see
|
||||||
`affinst_suspend_finish()`).
|
`affinst_suspend_finish()`).
|
||||||
|
|
||||||
This function is called with coherent stacks. This allows the PSCI
|
|
||||||
implementation to flush caches at a given affinity level without running into
|
|
||||||
stale stack state after turning off the caches. On ARMv8-A cache hits do not
|
|
||||||
occur after the cache has been turned off.
|
|
||||||
|
|
||||||
#### plat_pm_ops.affinst_on_finish()
|
#### plat_pm_ops.affinst_on_finish()
|
||||||
|
|
||||||
This function is called by the PSCI implementation after the calling CPU is
|
This function is called by the PSCI implementation after the calling CPU is
|
||||||
|
@ -1159,11 +1118,6 @@ services.
|
||||||
The `MPIDR` (first argument), `affinity level` (second argument) and `state`
|
The `MPIDR` (first argument), `affinity level` (second argument) and `state`
|
||||||
(third argument) have a similar meaning as described in the previous operations.
|
(third argument) have a similar meaning as described in the previous operations.
|
||||||
|
|
||||||
This function is called with coherent stacks. This allows the PSCI
|
|
||||||
implementation to flush caches at a given affinity level without running into
|
|
||||||
stale stack state after turning off the caches. On ARMv8-A cache hits do not
|
|
||||||
occur after the cache has been turned off.
|
|
||||||
|
|
||||||
#### plat_pm_ops.affinst_on_suspend()
|
#### plat_pm_ops.affinst_on_suspend()
|
||||||
|
|
||||||
This function is called by the PSCI implementation after the calling CPU is
|
This function is called by the PSCI implementation after the calling CPU is
|
||||||
|
@ -1176,11 +1130,6 @@ and also provide secure runtime firmware services.
|
||||||
The `MPIDR` (first argument), `affinity level` (second argument) and `state`
|
The `MPIDR` (first argument), `affinity level` (second argument) and `state`
|
||||||
(third argument) have a similar meaning as described in the previous operations.
|
(third argument) have a similar meaning as described in the previous operations.
|
||||||
|
|
||||||
This function is called with coherent stacks. This allows the PSCI
|
|
||||||
implementation to flush caches at a given affinity level without running into
|
|
||||||
stale stack state after turning off the caches. On ARMv8-A cache hits do not
|
|
||||||
occur after the cache has been turned off.
|
|
||||||
|
|
||||||
BL3-1 platform initialization code must also detect the system topology and
|
BL3-1 platform initialization code must also detect the system topology and
|
||||||
the state of each affinity instance in the topology. This information is
|
the state of each affinity instance in the topology. This information is
|
||||||
critical for the PSCI runtime service to function correctly. More details are
|
critical for the PSCI runtime service to function correctly. More details are
|
||||||
|
|
|
@ -76,21 +76,13 @@
|
||||||
* 32-bits wide but are stored as 64-bit values for convenience
|
* 32-bits wide but are stored as 64-bit values for convenience
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
#define CTX_EL3STATE_OFFSET (CTX_GPREGS_OFFSET + CTX_GPREGS_END)
|
#define CTX_EL3STATE_OFFSET (CTX_GPREGS_OFFSET + CTX_GPREGS_END)
|
||||||
#define CTX_VBAR_EL3 0x0 /* Currently unused */
|
#define CTX_SCR_EL3 0x0
|
||||||
#define CTX_RUNTIME_SP 0x8
|
#define CTX_RUNTIME_SP 0x8
|
||||||
#define CTX_SPSR_EL3 0x10
|
#define CTX_SPSR_EL3 0x10
|
||||||
#define CTX_ELR_EL3 0x18
|
#define CTX_ELR_EL3 0x18
|
||||||
#define CTX_SCR_EL3 0x20
|
#define CTX_CPTR_EL3 0x20
|
||||||
#define CTX_SCTLR_EL3 0x28
|
#define CTX_CNTFRQ_EL0 0x28
|
||||||
#define CTX_CPTR_EL3 0x30
|
#define CTX_EL3STATE_END 0x30
|
||||||
/* Unused space to allow registers to be stored as pairs */
|
|
||||||
#define CTX_CNTFRQ_EL0 0x40
|
|
||||||
#define CTX_MAIR_EL3 0x48
|
|
||||||
#define CTX_TCR_EL3 0x50
|
|
||||||
#define CTX_TTBR0_EL3 0x58
|
|
||||||
#define CTX_DAIF_EL3 0x60
|
|
||||||
/* Unused space to honour alignment requirements */
|
|
||||||
#define CTX_EL3STATE_END 0x70
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Constants that allow assembler code to access members of and the
|
* Constants that allow assembler code to access members of and the
|
||||||
|
|
|
@ -31,6 +31,14 @@
|
||||||
#ifndef __XLAT_TABLES_H__
|
#ifndef __XLAT_TABLES_H__
|
||||||
#define __XLAT_TABLES_H__
|
#define __XLAT_TABLES_H__
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Flags to override default values used to program system registers while
|
||||||
|
* enabling the MMU.
|
||||||
|
*/
|
||||||
|
#define DISABLE_DCACHE (1 << 0)
|
||||||
|
|
||||||
|
#ifndef __ASSEMBLY__
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -67,7 +75,8 @@ void mmap_add(const mmap_region_t *mm);
|
||||||
|
|
||||||
void init_xlat_tables(void);
|
void init_xlat_tables(void);
|
||||||
|
|
||||||
void enable_mmu_el1(void);
|
void enable_mmu_el1(uint32_t flags);
|
||||||
void enable_mmu_el3(void);
|
void enable_mmu_el3(uint32_t flags);
|
||||||
|
|
||||||
|
#endif /*__ASSEMBLY__*/
|
||||||
#endif /* __XLAT_TABLES_H__ */
|
#endif /* __XLAT_TABLES_H__ */
|
||||||
|
|
|
@ -180,7 +180,7 @@ unsigned int plat_get_aff_state(unsigned int, unsigned long);
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Optional BL3-1 functions (may be overridden)
|
* Optional BL3-1 functions (may be overridden)
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
void bl31_plat_enable_mmu(void);
|
void bl31_plat_enable_mmu(uint32_t flags);
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Mandatory BL3-2 functions (only if platform contains a BL3-2)
|
* Mandatory BL3-2 functions (only if platform contains a BL3-2)
|
||||||
|
@ -190,6 +190,6 @@ void bl32_platform_setup(void);
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Optional BL3-2 functions (may be overridden)
|
* Optional BL3-2 functions (may be overridden)
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
void bl32_plat_enable_mmu(void);
|
void bl32_plat_enable_mmu(uint32_t flags);
|
||||||
|
|
||||||
#endif /* __PLATFORM_H__ */
|
#endif /* __PLATFORM_H__ */
|
||||||
|
|
|
@ -292,7 +292,7 @@ void init_xlat_tables(void)
|
||||||
* exception level
|
* exception level
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
#define DEFINE_ENABLE_MMU_EL(_el, _tcr_extra, _tlbi_fct) \
|
#define DEFINE_ENABLE_MMU_EL(_el, _tcr_extra, _tlbi_fct) \
|
||||||
void enable_mmu_el##_el(void) \
|
void enable_mmu_el##_el(uint32_t flags) \
|
||||||
{ \
|
{ \
|
||||||
uint64_t mair, tcr, ttbr; \
|
uint64_t mair, tcr, ttbr; \
|
||||||
uint32_t sctlr; \
|
uint32_t sctlr; \
|
||||||
|
@ -330,7 +330,13 @@ void init_xlat_tables(void)
|
||||||
\
|
\
|
||||||
sctlr = read_sctlr_el##_el(); \
|
sctlr = read_sctlr_el##_el(); \
|
||||||
sctlr |= SCTLR_WXN_BIT | SCTLR_M_BIT | SCTLR_I_BIT; \
|
sctlr |= SCTLR_WXN_BIT | SCTLR_M_BIT | SCTLR_I_BIT; \
|
||||||
sctlr |= SCTLR_A_BIT | SCTLR_C_BIT; \
|
sctlr |= SCTLR_A_BIT; \
|
||||||
|
\
|
||||||
|
if (flags & DISABLE_DCACHE) \
|
||||||
|
sctlr &= ~SCTLR_C_BIT; \
|
||||||
|
else \
|
||||||
|
sctlr |= SCTLR_C_BIT; \
|
||||||
|
\
|
||||||
write_sctlr_el##_el(sctlr); \
|
write_sctlr_el##_el(sctlr); \
|
||||||
\
|
\
|
||||||
/* Ensure the MMU enable takes effect immediately */ \
|
/* Ensure the MMU enable takes effect immediately */ \
|
||||||
|
|
|
@ -38,12 +38,12 @@
|
||||||
#pragma weak bl31_plat_enable_mmu
|
#pragma weak bl31_plat_enable_mmu
|
||||||
#pragma weak bl32_plat_enable_mmu
|
#pragma weak bl32_plat_enable_mmu
|
||||||
|
|
||||||
void bl31_plat_enable_mmu(void)
|
void bl31_plat_enable_mmu(uint32_t flags)
|
||||||
{
|
{
|
||||||
enable_mmu_el3();
|
enable_mmu_el3(flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
void bl32_plat_enable_mmu(void)
|
void bl32_plat_enable_mmu(uint32_t flags)
|
||||||
{
|
{
|
||||||
enable_mmu_el1();
|
enable_mmu_el1(flags);
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,28 +33,11 @@
|
||||||
#include <platform_def.h>
|
#include <platform_def.h>
|
||||||
|
|
||||||
|
|
||||||
.local pcpu_dv_mem_stack
|
|
||||||
.local platform_normal_stacks
|
.local platform_normal_stacks
|
||||||
.weak platform_set_stack
|
.weak platform_set_stack
|
||||||
.weak platform_get_stack
|
.weak platform_get_stack
|
||||||
.weak platform_set_coherent_stack
|
|
||||||
|
|
||||||
|
|
||||||
/* -----------------------------------------------------
|
|
||||||
* void platform_set_coherent_stack (unsigned long mpidr)
|
|
||||||
*
|
|
||||||
* For a given CPU, this function sets the stack pointer
|
|
||||||
* to a stack allocated in device memory. This stack can
|
|
||||||
* be used by C code which enables/disables the SCTLR.M
|
|
||||||
* SCTLR.C bit e.g. while powering down a cpu
|
|
||||||
* -----------------------------------------------------
|
|
||||||
*/
|
|
||||||
func platform_set_coherent_stack
|
|
||||||
mov x5, x30 // lr
|
|
||||||
get_mp_stack pcpu_dv_mem_stack, PCPU_DV_MEM_STACK_SIZE
|
|
||||||
mov sp, x0
|
|
||||||
ret x5
|
|
||||||
|
|
||||||
/* -----------------------------------------------------
|
/* -----------------------------------------------------
|
||||||
* unsigned long platform_get_stack (unsigned long mpidr)
|
* unsigned long platform_get_stack (unsigned long mpidr)
|
||||||
*
|
*
|
||||||
|
@ -81,22 +64,9 @@ func platform_set_stack
|
||||||
ret x9
|
ret x9
|
||||||
|
|
||||||
/* -----------------------------------------------------
|
/* -----------------------------------------------------
|
||||||
* Per-cpu stacks in normal memory.
|
* Per-cpu stacks in normal memory. Each cpu gets a
|
||||||
* Used for C code during runtime execution (when coherent
|
* stack of PLATFORM_STACK_SIZE bytes.
|
||||||
* stacks are not required).
|
|
||||||
* Each cpu gets a stack of PLATFORM_STACK_SIZE bytes.
|
|
||||||
* -----------------------------------------------------
|
* -----------------------------------------------------
|
||||||
*/
|
*/
|
||||||
declare_stack platform_normal_stacks, tzfw_normal_stacks, \
|
declare_stack platform_normal_stacks, tzfw_normal_stacks, \
|
||||||
PLATFORM_STACK_SIZE, PLATFORM_CORE_COUNT
|
PLATFORM_STACK_SIZE, PLATFORM_CORE_COUNT
|
||||||
|
|
||||||
/* -----------------------------------------------------
|
|
||||||
* Per-cpu stacks in device memory.
|
|
||||||
* Used for C code just before power down or right after
|
|
||||||
* power up when the MMU or caches need to be turned on
|
|
||||||
* or off.
|
|
||||||
* Each cpu gets a stack of PCPU_DV_MEM_STACK_SIZE bytes.
|
|
||||||
* -----------------------------------------------------
|
|
||||||
*/
|
|
||||||
declare_stack pcpu_dv_mem_stack, tzfw_coherent_mem, \
|
|
||||||
PCPU_DV_MEM_STACK_SIZE, PLATFORM_CORE_COUNT
|
|
||||||
|
|
|
@ -33,26 +33,9 @@
|
||||||
#include <platform_def.h>
|
#include <platform_def.h>
|
||||||
|
|
||||||
|
|
||||||
.local pcpu_dv_mem_stack
|
|
||||||
.local platform_normal_stacks
|
.local platform_normal_stacks
|
||||||
.globl platform_set_stack
|
.globl platform_set_stack
|
||||||
.globl platform_get_stack
|
.globl platform_get_stack
|
||||||
.globl platform_set_coherent_stack
|
|
||||||
|
|
||||||
|
|
||||||
/* -----------------------------------------------------
|
|
||||||
* void platform_set_coherent_stack (unsigned long)
|
|
||||||
*
|
|
||||||
* For cold-boot BL images, only the primary CPU needs a
|
|
||||||
* stack. This function sets the stack pointer to a stack
|
|
||||||
* allocated in device memory.
|
|
||||||
* -----------------------------------------------------
|
|
||||||
*/
|
|
||||||
func platform_set_coherent_stack
|
|
||||||
get_up_stack pcpu_dv_mem_stack, PCPU_DV_MEM_STACK_SIZE
|
|
||||||
mov sp, x0
|
|
||||||
ret
|
|
||||||
|
|
||||||
|
|
||||||
/* -----------------------------------------------------
|
/* -----------------------------------------------------
|
||||||
* unsigned long platform_get_stack (unsigned long)
|
* unsigned long platform_get_stack (unsigned long)
|
||||||
|
@ -87,11 +70,3 @@ func platform_set_stack
|
||||||
*/
|
*/
|
||||||
declare_stack platform_normal_stacks, tzfw_normal_stacks, \
|
declare_stack platform_normal_stacks, tzfw_normal_stacks, \
|
||||||
PLATFORM_STACK_SIZE, 1
|
PLATFORM_STACK_SIZE, 1
|
||||||
|
|
||||||
/* -----------------------------------------------------
|
|
||||||
* Single cpu stack in device/coherent memory.
|
|
||||||
* PCPU_DV_MEM_STACK_SIZE bytes are allocated.
|
|
||||||
* -----------------------------------------------------
|
|
||||||
*/
|
|
||||||
declare_stack pcpu_dv_mem_stack, tzfw_coherent_mem, \
|
|
||||||
PCPU_DV_MEM_STACK_SIZE, 1
|
|
||||||
|
|
|
@ -119,7 +119,7 @@ const unsigned int num_sec_irqs = sizeof(irq_sec_array) /
|
||||||
mmap_add(fvp_mmap); \
|
mmap_add(fvp_mmap); \
|
||||||
init_xlat_tables(); \
|
init_xlat_tables(); \
|
||||||
\
|
\
|
||||||
enable_mmu_el##_el(); \
|
enable_mmu_el##_el(0); \
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Define EL1 and EL3 variants of the function initialising the MMU */
|
/* Define EL1 and EL3 variants of the function initialising the MMU */
|
||||||
|
|
|
@ -120,11 +120,10 @@ exit:
|
||||||
* platform to decide whether the cluster is being turned off and take apt
|
* platform to decide whether the cluster is being turned off and take apt
|
||||||
* actions.
|
* actions.
|
||||||
*
|
*
|
||||||
* CAUTION: This function is called with coherent stacks so that caches can be
|
* CAUTION: There is no guarantee that caches will remain turned on across calls
|
||||||
* turned off, flushed and coherency disabled. There is no guarantee that caches
|
* to this function as each affinity level is dealt with. So do not write & read
|
||||||
* will remain turned on across calls to this function as each affinity level is
|
* global variables across calls. It will be wise to do flush a write to the
|
||||||
* dealt with. So do not write & read global variables across calls. It will be
|
* global to prevent unpredictable results.
|
||||||
* wise to do flush a write to the global to prevent unpredictable results.
|
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
int fvp_affinst_off(unsigned long mpidr,
|
int fvp_affinst_off(unsigned long mpidr,
|
||||||
unsigned int afflvl,
|
unsigned int afflvl,
|
||||||
|
@ -192,11 +191,10 @@ int fvp_affinst_off(unsigned long mpidr,
|
||||||
* platform to decide whether the cluster is being turned off and take apt
|
* platform to decide whether the cluster is being turned off and take apt
|
||||||
* actions.
|
* actions.
|
||||||
*
|
*
|
||||||
* CAUTION: This function is called with coherent stacks so that caches can be
|
* CAUTION: There is no guarantee that caches will remain turned on across calls
|
||||||
* turned off, flushed and coherency disabled. There is no guarantee that caches
|
* to this function as each affinity level is dealt with. So do not write & read
|
||||||
* will remain turned on across calls to this function as each affinity level is
|
* global variables across calls. It will be wise to do flush a write to the
|
||||||
* dealt with. So do not write & read global variables across calls. It will be
|
* global to prevent unpredictable results.
|
||||||
* wise to do flush a write to the global to prevent unpredictable results.
|
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
int fvp_affinst_suspend(unsigned long mpidr,
|
int fvp_affinst_suspend(unsigned long mpidr,
|
||||||
unsigned long sec_entrypoint,
|
unsigned long sec_entrypoint,
|
||||||
|
|
|
@ -47,13 +47,6 @@
|
||||||
/* Size of cacheable stacks */
|
/* Size of cacheable stacks */
|
||||||
#define PLATFORM_STACK_SIZE 0x800
|
#define PLATFORM_STACK_SIZE 0x800
|
||||||
|
|
||||||
/* Size of coherent stacks for debug and release builds */
|
|
||||||
#if DEBUG
|
|
||||||
#define PCPU_DV_MEM_STACK_SIZE 0x400
|
|
||||||
#else
|
|
||||||
#define PCPU_DV_MEM_STACK_SIZE 0x300
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define FIRMWARE_WELCOME_STR "Booting trusted firmware boot loader stage 1\n\r"
|
#define FIRMWARE_WELCOME_STR "Booting trusted firmware boot loader stage 1\n\r"
|
||||||
|
|
||||||
/* Trusted Boot Firmware BL2 */
|
/* Trusted Boot Firmware BL2 */
|
||||||
|
|
|
@ -44,7 +44,6 @@ static int psci_afflvl0_off(aff_map_node_t *cpu_node)
|
||||||
{
|
{
|
||||||
unsigned int plat_state;
|
unsigned int plat_state;
|
||||||
int rc;
|
int rc;
|
||||||
unsigned long sctlr;
|
|
||||||
|
|
||||||
assert(cpu_node->level == MPIDR_AFFLVL0);
|
assert(cpu_node->level == MPIDR_AFFLVL0);
|
||||||
|
|
||||||
|
@ -70,24 +69,8 @@ static int psci_afflvl0_off(aff_map_node_t *cpu_node)
|
||||||
/*
|
/*
|
||||||
* Arch. management. Perform the necessary steps to flush all
|
* Arch. management. Perform the necessary steps to flush all
|
||||||
* cpu caches.
|
* cpu caches.
|
||||||
*
|
|
||||||
* TODO: This power down sequence varies across cpus so it needs to be
|
|
||||||
* abstracted out on the basis of the MIDR like in cpu_reset_handler().
|
|
||||||
* Do the bare minimal for the time being. Fix this before porting to
|
|
||||||
* Cortex models.
|
|
||||||
*/
|
*/
|
||||||
sctlr = read_sctlr_el3();
|
psci_do_pwrdown_cache_maintenance(MPIDR_AFFLVL0);
|
||||||
sctlr &= ~SCTLR_C_BIT;
|
|
||||||
write_sctlr_el3(sctlr);
|
|
||||||
isb(); /* ensure MMU disable takes immediate effect */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* CAUTION: This flush to the level of unification makes an assumption
|
|
||||||
* about the cache hierarchy at affinity level 0 (cpu) in the platform.
|
|
||||||
* Ideally the platform should tell psci which levels to flush to exit
|
|
||||||
* coherency.
|
|
||||||
*/
|
|
||||||
dcsw_op_louis(DCCISW);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Plat. management: Perform platform specific actions to turn this
|
* Plat. management: Perform platform specific actions to turn this
|
||||||
|
@ -227,9 +210,6 @@ static int psci_call_off_handlers(mpidr_aff_map_nodes_t mpidr_nodes,
|
||||||
* the lowest to the highest affinity level implemented by the platform because
|
* the lowest to the highest affinity level implemented by the platform because
|
||||||
* to turn off affinity level X it is neccesary to turn off affinity level X - 1
|
* to turn off affinity level X it is neccesary to turn off affinity level X - 1
|
||||||
* first.
|
* first.
|
||||||
*
|
|
||||||
* CAUTION: This function is called with coherent stacks so that coherency can
|
|
||||||
* be turned off and caches can be flushed safely.
|
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
int psci_afflvl_off(int start_afflvl,
|
int psci_afflvl_off(int start_afflvl,
|
||||||
int end_afflvl)
|
int end_afflvl)
|
||||||
|
|
|
@ -359,9 +359,9 @@ static unsigned int psci_afflvl0_on_finish(aff_map_node_t *cpu_node)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Arch. management: Turn on mmu & restore architectural state
|
* Arch. management: Enable data cache and manage stack memory
|
||||||
*/
|
*/
|
||||||
bl31_plat_enable_mmu();
|
psci_do_pwrup_cache_maintenance();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* All the platform specific actions for turning this cpu
|
* All the platform specific actions for turning this cpu
|
||||||
|
|
|
@ -126,8 +126,7 @@ static int psci_afflvl0_suspend(aff_map_node_t *cpu_node,
|
||||||
unsigned int power_state)
|
unsigned int power_state)
|
||||||
{
|
{
|
||||||
unsigned int plat_state;
|
unsigned int plat_state;
|
||||||
unsigned long psci_entrypoint, sctlr;
|
unsigned long psci_entrypoint;
|
||||||
el3_state_t *saved_el3_state;
|
|
||||||
uint32_t ns_scr_el3 = read_scr_el3();
|
uint32_t ns_scr_el3 = read_scr_el3();
|
||||||
uint32_t ns_sctlr_el1 = read_sctlr_el1();
|
uint32_t ns_sctlr_el1 = read_sctlr_el1();
|
||||||
int rc;
|
int rc;
|
||||||
|
@ -170,37 +169,14 @@ static int psci_afflvl0_suspend(aff_map_node_t *cpu_node,
|
||||||
*/
|
*/
|
||||||
cm_el3_sysregs_context_save(NON_SECURE);
|
cm_el3_sysregs_context_save(NON_SECURE);
|
||||||
|
|
||||||
/*
|
|
||||||
* The EL3 state to PoC since it will be accessed after a
|
|
||||||
* reset with the caches turned off
|
|
||||||
*/
|
|
||||||
saved_el3_state = get_el3state_ctx(cm_get_context(NON_SECURE));
|
|
||||||
flush_dcache_range((uint64_t) saved_el3_state, sizeof(*saved_el3_state));
|
|
||||||
|
|
||||||
/* Set the secure world (EL3) re-entry point after BL1 */
|
/* Set the secure world (EL3) re-entry point after BL1 */
|
||||||
psci_entrypoint = (unsigned long) psci_aff_suspend_finish_entry;
|
psci_entrypoint = (unsigned long) psci_aff_suspend_finish_entry;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Arch. management. Perform the necessary steps to flush all
|
* Arch. management. Perform the necessary steps to flush all
|
||||||
* cpu caches.
|
* cpu caches.
|
||||||
*
|
|
||||||
* TODO: This power down sequence varies across cpus so it needs to be
|
|
||||||
* abstracted out on the basis of the MIDR like in cpu_reset_handler().
|
|
||||||
* Do the bare minimal for the time being. Fix this before porting to
|
|
||||||
* Cortex models.
|
|
||||||
*/
|
*/
|
||||||
sctlr = read_sctlr_el3();
|
psci_do_pwrdown_cache_maintenance(MPIDR_AFFLVL0);
|
||||||
sctlr &= ~SCTLR_C_BIT;
|
|
||||||
write_sctlr_el3(sctlr);
|
|
||||||
isb(); /* ensure MMU disable takes immediate effect */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* CAUTION: This flush to the level of unification makes an assumption
|
|
||||||
* about the cache hierarchy at affinity level 0 (cpu) in the platform.
|
|
||||||
* Ideally the platform should tell psci which levels to flush to exit
|
|
||||||
* coherency.
|
|
||||||
*/
|
|
||||||
dcsw_op_louis(DCCISW);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Plat. management: Allow the platform to perform the
|
* Plat. management: Allow the platform to perform the
|
||||||
|
@ -379,9 +355,6 @@ static int psci_call_suspend_handlers(mpidr_aff_map_nodes_t mpidr_nodes,
|
||||||
* the lowest to the highest affinity level implemented by the platform because
|
* the lowest to the highest affinity level implemented by the platform because
|
||||||
* to turn off affinity level X it is neccesary to turn off affinity level X - 1
|
* to turn off affinity level X it is neccesary to turn off affinity level X - 1
|
||||||
* first.
|
* first.
|
||||||
*
|
|
||||||
* CAUTION: This function is called with coherent stacks so that coherency can
|
|
||||||
* be turned off and caches can be flushed safely.
|
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
int psci_afflvl_suspend(unsigned long entrypoint,
|
int psci_afflvl_suspend(unsigned long entrypoint,
|
||||||
unsigned long context_id,
|
unsigned long context_id,
|
||||||
|
@ -467,9 +440,11 @@ static unsigned int psci_afflvl0_suspend_finish(aff_map_node_t *cpu_node)
|
||||||
|
|
||||||
/* Get the index for restoring the re-entry information */
|
/* Get the index for restoring the re-entry information */
|
||||||
/*
|
/*
|
||||||
* Arch. management: Restore the stashed EL3 architectural
|
* Arch. management: Enable the data cache, manage stack memory and
|
||||||
* context from the 'cpu_context' structure for this cpu.
|
* restore the stashed EL3 architectural context from the 'cpu_context'
|
||||||
|
* structure for this cpu.
|
||||||
*/
|
*/
|
||||||
|
psci_do_pwrup_cache_maintenance();
|
||||||
cm_el3_sysregs_context_restore(NON_SECURE);
|
cm_el3_sysregs_context_restore(NON_SECURE);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -575,4 +550,3 @@ const afflvl_power_on_finisher_t psci_afflvl_suspend_finishers[] = {
|
||||||
psci_afflvl1_suspend_finish,
|
psci_afflvl1_suspend_finish,
|
||||||
psci_afflvl2_suspend_finish,
|
psci_afflvl2_suspend_finish,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -390,9 +390,6 @@ static int psci_call_power_on_handlers(mpidr_aff_map_nodes_t mpidr_nodes,
|
||||||
* the highest to the lowest affinity level implemented by the platform because
|
* the highest to the lowest affinity level implemented by the platform because
|
||||||
* to turn on affinity level X it is neccesary to turn on affinity level X + 1
|
* to turn on affinity level X it is neccesary to turn on affinity level X + 1
|
||||||
* first.
|
* first.
|
||||||
*
|
|
||||||
* CAUTION: This function is called with coherent stacks so that coherency and
|
|
||||||
* the mmu can be turned on safely.
|
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
void psci_afflvl_power_on_finish(int start_afflvl,
|
void psci_afflvl_power_on_finish(int start_afflvl,
|
||||||
int end_afflvl,
|
int end_afflvl,
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include <arch.h>
|
#include <arch.h>
|
||||||
#include <asm_macros.S>
|
#include <asm_macros.S>
|
||||||
#include <psci.h>
|
#include <psci.h>
|
||||||
|
#include <xlat_tables.h>
|
||||||
|
|
||||||
.globl psci_aff_on_finish_entry
|
.globl psci_aff_on_finish_entry
|
||||||
.globl psci_aff_suspend_finish_entry
|
.globl psci_aff_suspend_finish_entry
|
||||||
|
@ -43,11 +44,6 @@
|
||||||
* upon whether it was resumed from suspend or simply
|
* upon whether it was resumed from suspend or simply
|
||||||
* turned on, call the common power on finisher with
|
* turned on, call the common power on finisher with
|
||||||
* the handlers (chosen depending upon original state).
|
* the handlers (chosen depending upon original state).
|
||||||
* For ease, the finisher is called with coherent
|
|
||||||
* stacks. This allows the cluster/cpu finishers to
|
|
||||||
* enter coherency and enable the mmu without running
|
|
||||||
* into issues. We switch back to normal stacks once
|
|
||||||
* all this is done.
|
|
||||||
* -----------------------------------------------------
|
* -----------------------------------------------------
|
||||||
*/
|
*/
|
||||||
func psci_aff_on_finish_entry
|
func psci_aff_on_finish_entry
|
||||||
|
@ -78,8 +74,34 @@ psci_aff_common_finish_entry:
|
||||||
*/
|
*/
|
||||||
msr spsel, #0
|
msr spsel, #0
|
||||||
|
|
||||||
|
/* --------------------------------------------
|
||||||
|
* Give ourselves a stack whose memory will be
|
||||||
|
* marked as Normal-IS-WBWA when the MMU is
|
||||||
|
* enabled.
|
||||||
|
* --------------------------------------------
|
||||||
|
*/
|
||||||
mrs x0, mpidr_el1
|
mrs x0, mpidr_el1
|
||||||
bl platform_set_coherent_stack
|
bl platform_set_stack
|
||||||
|
|
||||||
|
/* --------------------------------------------
|
||||||
|
* Enable the MMU with the DCache disabled. It
|
||||||
|
* is safe to use stacks allocated in normal
|
||||||
|
* memory as a result. All memory accesses are
|
||||||
|
* marked nGnRnE when the MMU is disabled. So
|
||||||
|
* all the stack writes will make it to memory.
|
||||||
|
* All memory accesses are marked Non-cacheable
|
||||||
|
* when the MMU is enabled but D$ is disabled.
|
||||||
|
* So used stack memory is guaranteed to be
|
||||||
|
* visible immediately after the MMU is enabled
|
||||||
|
* Enabling the DCache at the same time as the
|
||||||
|
* MMU can lead to speculatively fetched and
|
||||||
|
* possibly stale stack memory being read from
|
||||||
|
* other caches. This can lead to coherency
|
||||||
|
* issues.
|
||||||
|
* --------------------------------------------
|
||||||
|
*/
|
||||||
|
mov x0, #DISABLE_DCACHE
|
||||||
|
bl bl31_plat_enable_mmu
|
||||||
|
|
||||||
/* ---------------------------------------------
|
/* ---------------------------------------------
|
||||||
* Call the finishers starting from affinity
|
* Call the finishers starting from affinity
|
||||||
|
@ -95,60 +117,10 @@ psci_aff_common_finish_entry:
|
||||||
mov x0, #MPIDR_AFFLVL0
|
mov x0, #MPIDR_AFFLVL0
|
||||||
bl psci_afflvl_power_on_finish
|
bl psci_afflvl_power_on_finish
|
||||||
|
|
||||||
/* --------------------------------------------
|
|
||||||
* Give ourselves a stack allocated in Normal
|
|
||||||
* -IS-WBWA memory
|
|
||||||
* --------------------------------------------
|
|
||||||
*/
|
|
||||||
mrs x0, mpidr_el1
|
|
||||||
bl platform_set_stack
|
|
||||||
|
|
||||||
b el3_exit
|
b el3_exit
|
||||||
_panic:
|
_panic:
|
||||||
b _panic
|
b _panic
|
||||||
|
|
||||||
/* -----------------------------------------------------
|
|
||||||
* The following two stubs give the calling cpu a
|
|
||||||
* coherent stack to allow flushing of caches without
|
|
||||||
* suffering from stack coherency issues
|
|
||||||
* -----------------------------------------------------
|
|
||||||
*/
|
|
||||||
func __psci_cpu_off
|
|
||||||
func_prologue
|
|
||||||
sub sp, sp, #0x10
|
|
||||||
stp x19, x20, [sp, #0]
|
|
||||||
mov x19, sp
|
|
||||||
mrs x0, mpidr_el1
|
|
||||||
bl platform_set_coherent_stack
|
|
||||||
bl psci_cpu_off
|
|
||||||
mov sp, x19
|
|
||||||
ldp x19, x20, [sp,#0]
|
|
||||||
add sp, sp, #0x10
|
|
||||||
func_epilogue
|
|
||||||
ret
|
|
||||||
|
|
||||||
func __psci_cpu_suspend
|
|
||||||
func_prologue
|
|
||||||
sub sp, sp, #0x20
|
|
||||||
stp x19, x20, [sp, #0]
|
|
||||||
stp x21, x22, [sp, #0x10]
|
|
||||||
mov x19, sp
|
|
||||||
mov x20, x0
|
|
||||||
mov x21, x1
|
|
||||||
mov x22, x2
|
|
||||||
mrs x0, mpidr_el1
|
|
||||||
bl platform_set_coherent_stack
|
|
||||||
mov x0, x20
|
|
||||||
mov x1, x21
|
|
||||||
mov x2, x22
|
|
||||||
bl psci_cpu_suspend
|
|
||||||
mov sp, x19
|
|
||||||
ldp x21, x22, [sp,#0x10]
|
|
||||||
ldp x19, x20, [sp,#0]
|
|
||||||
add sp, sp, #0x20
|
|
||||||
func_epilogue
|
|
||||||
ret
|
|
||||||
|
|
||||||
/* --------------------------------------------
|
/* --------------------------------------------
|
||||||
* This function is called to indicate to the
|
* This function is called to indicate to the
|
||||||
* power controller that it is safe to power
|
* power controller that it is safe to power
|
||||||
|
|
|
@ -0,0 +1,176 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* Neither the name of ARM nor the names of its contributors may be used
|
||||||
|
* to endorse or promote products derived from this software without specific
|
||||||
|
* prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <arch.h>
|
||||||
|
#include <asm_macros.S>
|
||||||
|
#include <platform_def.h>
|
||||||
|
|
||||||
|
.globl psci_do_pwrdown_cache_maintenance
|
||||||
|
.globl psci_do_pwrup_cache_maintenance
|
||||||
|
|
||||||
|
/* -----------------------------------------------------------------------
|
||||||
|
* void psci_do_pwrdown_cache_maintenance(uint32_t affinity level);
|
||||||
|
*
|
||||||
|
* This function performs cache maintenance before this cpu is powered
|
||||||
|
* off. The levels of cache affected are determined by the affinity level
|
||||||
|
* which is passed as the argument. Additionally, this function also
|
||||||
|
* ensures that stack memory is correctly flushed out to avoid coherency
|
||||||
|
* issues due to a change in its memory attributes after the data cache
|
||||||
|
* is disabled.
|
||||||
|
* -----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
func psci_do_pwrdown_cache_maintenance
|
||||||
|
stp x29, x30, [sp,#-16]!
|
||||||
|
stp x19, x20, [sp,#-16]!
|
||||||
|
|
||||||
|
/* ---------------------------------------------
|
||||||
|
* Disable the Data Cache.
|
||||||
|
* ---------------------------------------------
|
||||||
|
*/
|
||||||
|
mrs x1, sctlr_el3
|
||||||
|
bic x1, x1, #SCTLR_C_BIT
|
||||||
|
msr sctlr_el3, x1
|
||||||
|
isb
|
||||||
|
|
||||||
|
/* ---------------------------------------------
|
||||||
|
* Determine to how many levels of cache will be
|
||||||
|
* subject to cache maintenance. Affinity level
|
||||||
|
* 0 implies that only the cpu is being powered
|
||||||
|
* down. Only the L1 data cache needs to be
|
||||||
|
* flushed to the PoU in this case. For a higher
|
||||||
|
* affinity level we are assuming that a flush
|
||||||
|
* of L1 data and L2 unified cache is enough.
|
||||||
|
* This information should be provided by the
|
||||||
|
* platform.
|
||||||
|
* ---------------------------------------------
|
||||||
|
*/
|
||||||
|
cmp x0, #MPIDR_AFFLVL0
|
||||||
|
mov x0, #DCCISW
|
||||||
|
b.ne flush_caches_to_poc
|
||||||
|
|
||||||
|
/* ---------------------------------------------
|
||||||
|
* Flush L1 cache to PoU.
|
||||||
|
* ---------------------------------------------
|
||||||
|
*/
|
||||||
|
bl dcsw_op_louis
|
||||||
|
b do_stack_maintenance
|
||||||
|
|
||||||
|
/* ---------------------------------------------
|
||||||
|
* Flush L1 and L2 caches to PoC.
|
||||||
|
* ---------------------------------------------
|
||||||
|
*/
|
||||||
|
flush_caches_to_poc:
|
||||||
|
bl dcsw_op_all
|
||||||
|
|
||||||
|
/* ---------------------------------------------
|
||||||
|
* TODO: Intra-cluster coherency should be
|
||||||
|
* turned off here once cpu-specific
|
||||||
|
* abstractions are in place.
|
||||||
|
* ---------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* ---------------------------------------------
|
||||||
|
* Do stack maintenance by flushing the used
|
||||||
|
* stack to the main memory and invalidating the
|
||||||
|
* remainder.
|
||||||
|
* ---------------------------------------------
|
||||||
|
*/
|
||||||
|
do_stack_maintenance:
|
||||||
|
mrs x0, mpidr_el1
|
||||||
|
bl platform_get_stack
|
||||||
|
|
||||||
|
/* ---------------------------------------------
|
||||||
|
* Calculate and store the size of the used
|
||||||
|
* stack memory in x1.
|
||||||
|
* ---------------------------------------------
|
||||||
|
*/
|
||||||
|
mov x19, x0
|
||||||
|
mov x1, sp
|
||||||
|
sub x1, x0, x1
|
||||||
|
mov x0, sp
|
||||||
|
bl flush_dcache_range
|
||||||
|
|
||||||
|
/* ---------------------------------------------
|
||||||
|
* Calculate and store the size of the unused
|
||||||
|
* stack memory in x1. Calculate and store the
|
||||||
|
* stack base address in x0.
|
||||||
|
* ---------------------------------------------
|
||||||
|
*/
|
||||||
|
sub x0, x19, #PLATFORM_STACK_SIZE
|
||||||
|
sub x1, sp, x0
|
||||||
|
bl inv_dcache_range
|
||||||
|
|
||||||
|
ldp x19, x20, [sp], #16
|
||||||
|
ldp x29, x30, [sp], #16
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
/* -----------------------------------------------------------------------
|
||||||
|
* void psci_do_pwrup_cache_maintenance(void);
|
||||||
|
*
|
||||||
|
* This function performs cache maintenance after this cpu is powered up.
|
||||||
|
* Currently, this involves managing the used stack memory before turning
|
||||||
|
* on the data cache.
|
||||||
|
* -----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
func psci_do_pwrup_cache_maintenance
|
||||||
|
stp x29, x30, [sp,#-16]!
|
||||||
|
|
||||||
|
/* ---------------------------------------------
|
||||||
|
* Ensure any inflight stack writes have made it
|
||||||
|
* to main memory.
|
||||||
|
* ---------------------------------------------
|
||||||
|
*/
|
||||||
|
dmb st
|
||||||
|
|
||||||
|
/* ---------------------------------------------
|
||||||
|
* Calculate and store the size of the used
|
||||||
|
* stack memory in x1. Calculate and store the
|
||||||
|
* stack base address in x0.
|
||||||
|
* ---------------------------------------------
|
||||||
|
*/
|
||||||
|
mrs x0, mpidr_el1
|
||||||
|
bl platform_get_stack
|
||||||
|
mov x1, sp
|
||||||
|
sub x1, x0, x1
|
||||||
|
mov x0, sp
|
||||||
|
bl inv_dcache_range
|
||||||
|
|
||||||
|
/* ---------------------------------------------
|
||||||
|
* Enable the data cache.
|
||||||
|
* ---------------------------------------------
|
||||||
|
*/
|
||||||
|
mrs x0, sctlr_el3
|
||||||
|
orr x0, x0, #SCTLR_C_BIT
|
||||||
|
msr sctlr_el3, x0
|
||||||
|
isb
|
||||||
|
|
||||||
|
ldp x29, x30, [sp], #16
|
||||||
|
ret
|
|
@ -230,10 +230,10 @@ uint64_t psci_smc_handler(uint32_t smc_fid,
|
||||||
SMC_RET1(handle, psci_version());
|
SMC_RET1(handle, psci_version());
|
||||||
|
|
||||||
case PSCI_CPU_OFF:
|
case PSCI_CPU_OFF:
|
||||||
SMC_RET1(handle, __psci_cpu_off());
|
SMC_RET1(handle, psci_cpu_off());
|
||||||
|
|
||||||
case PSCI_CPU_SUSPEND_AARCH32:
|
case PSCI_CPU_SUSPEND_AARCH32:
|
||||||
SMC_RET1(handle, __psci_cpu_suspend(x1, x2, x3));
|
SMC_RET1(handle, psci_cpu_suspend(x1, x2, x3));
|
||||||
|
|
||||||
case PSCI_CPU_ON_AARCH32:
|
case PSCI_CPU_ON_AARCH32:
|
||||||
SMC_RET1(handle, psci_cpu_on(x1, x2, x3));
|
SMC_RET1(handle, psci_cpu_on(x1, x2, x3));
|
||||||
|
@ -258,7 +258,7 @@ uint64_t psci_smc_handler(uint32_t smc_fid,
|
||||||
|
|
||||||
switch (smc_fid) {
|
switch (smc_fid) {
|
||||||
case PSCI_CPU_SUSPEND_AARCH64:
|
case PSCI_CPU_SUSPEND_AARCH64:
|
||||||
SMC_RET1(handle, __psci_cpu_suspend(x1, x2, x3));
|
SMC_RET1(handle, psci_cpu_suspend(x1, x2, x3));
|
||||||
|
|
||||||
case PSCI_CPU_ON_AARCH64:
|
case PSCI_CPU_ON_AARCH64:
|
||||||
SMC_RET1(handle, psci_cpu_on(x1, x2, x3));
|
SMC_RET1(handle, psci_cpu_on(x1, x2, x3));
|
||||||
|
|
|
@ -128,5 +128,8 @@ int psci_afflvl_suspend(unsigned long,
|
||||||
int);
|
int);
|
||||||
unsigned int psci_afflvl_suspend_finish(int, int);
|
unsigned int psci_afflvl_suspend_finish(int, int);
|
||||||
|
|
||||||
|
/* Private exported functions from psci_helpers.S */
|
||||||
|
void psci_do_pwrdown_cache_maintenance(uint32_t affinity_level);
|
||||||
|
void psci_do_pwrup_cache_maintenance(void);
|
||||||
|
|
||||||
#endif /* __PSCI_PRIVATE_H__ */
|
#endif /* __PSCI_PRIVATE_H__ */
|
||||||
|
|
Loading…
Reference in New Issue