mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-17 01:54:22 +00:00
Add helper library for cpu context management
This patch introduces functions for saving and restoring shared system registers between secure and non-secure EL1 exception levels, VFP registers and essential EL3 system register and other state. It also defines the 'cpu_context' data structure which will used for saving and restoring execution context for a given security state. These functions will allow runtime services like PSCI and Secure payload dispatcher to implement logic for switching between the secure and non-secure states. The save and restore functions follow AArch64 PCS and only use caller-saved temporary registers. Change-Id: I8ee3aaa061d3caaedb28ae2c5becb9a206b6fd74
This commit is contained in:
parent
b739f22a99
commit
9ac63c59c4
3 changed files with 598 additions and 1 deletions
360
bl31/aarch64/context.S
Normal file
360
bl31/aarch64/context.S
Normal file
|
@ -0,0 +1,360 @@
|
|||
/*
|
||||
* Copyright (c) 2013-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 <context.h>
|
||||
|
||||
/* -----------------------------------------------------
|
||||
* The following function strictly follows the AArch64
|
||||
* PCS to use x9-x17 (temporary caller-saved registers)
|
||||
* to save essential EL3 system register context. It
|
||||
* assumes that 'x0' is pointing to a 'el1_sys_regs'
|
||||
* structure where the register context will be saved.
|
||||
* -----------------------------------------------------
|
||||
*/
|
||||
.global el3_sysregs_context_save
|
||||
el3_sysregs_context_save:
|
||||
|
||||
mrs x9, scr_el3
|
||||
mrs x10, sctlr_el3
|
||||
stp x9, x10, [x0, #CTX_SCR_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
|
||||
|
||||
/* -----------------------------------------------------
|
||||
* The following function strictly follows the AArch64
|
||||
* PCS to use x9-x17 (temporary caller-saved registers)
|
||||
* to restore essential EL3 system register context. It
|
||||
* assumes that 'x0' is pointing to a 'el1_sys_regs'
|
||||
* structure from where the register context will be
|
||||
* restored.
|
||||
*
|
||||
* Note that the sequence differs from that of the save
|
||||
* function as we want the MMU to be enabled last
|
||||
* -----------------------------------------------------
|
||||
*/
|
||||
.global el3_sysregs_context_restore
|
||||
el3_sysregs_context_restore:
|
||||
|
||||
ldp x11, xzr, [x0, #CTX_CPTR_EL3]
|
||||
msr cptr_el3, x11
|
||||
|
||||
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
|
||||
|
||||
ldp x9, x10, [x0, #CTX_SCR_EL3]
|
||||
msr scr_el3, x9
|
||||
msr sctlr_el3, x10
|
||||
isb
|
||||
|
||||
ret
|
||||
|
||||
/* -----------------------------------------------------
|
||||
* The following function strictly follows the AArch64
|
||||
* PCS to use x9-x17 (temporary caller-saved registers)
|
||||
* to save EL1 system register context. It assumes that
|
||||
* 'x0' is pointing to a 'el1_sys_regs' structure where
|
||||
* the register context will be saved.
|
||||
* -----------------------------------------------------
|
||||
*/
|
||||
.global el1_sysregs_context_save
|
||||
el1_sysregs_context_save:
|
||||
|
||||
mrs x9, spsr_el1
|
||||
mrs x10, elr_el1
|
||||
stp x9, x10, [x0, #CTX_SPSR_EL1]
|
||||
|
||||
mrs x11, spsr_abt
|
||||
mrs x12, spsr_und
|
||||
stp x11, x12, [x0, #CTX_SPSR_ABT]
|
||||
|
||||
mrs x13, spsr_irq
|
||||
mrs x14, spsr_fiq
|
||||
stp x13, x14, [x0, #CTX_SPSR_IRQ]
|
||||
|
||||
mrs x15, sctlr_el1
|
||||
mrs x16, actlr_el1
|
||||
stp x15, x16, [x0, #CTX_SCTLR_EL1]
|
||||
|
||||
mrs x17, cpacr_el1
|
||||
mrs x9, csselr_el1
|
||||
stp x17, x9, [x0, #CTX_CPACR_EL1]
|
||||
|
||||
mrs x10, sp_el1
|
||||
mrs x11, esr_el1
|
||||
stp x10, x11, [x0, #CTX_SP_EL1]
|
||||
|
||||
mrs x12, ttbr0_el1
|
||||
mrs x13, ttbr1_el1
|
||||
stp x12, x13, [x0, #CTX_TTBR0_EL1]
|
||||
|
||||
mrs x14, mair_el1
|
||||
mrs x15, amair_el1
|
||||
stp x14, x15, [x0, #CTX_MAIR_EL1]
|
||||
|
||||
mrs x16, tcr_el1
|
||||
mrs x17, tpidr_el1
|
||||
stp x16, x17, [x0, #CTX_TCR_EL1]
|
||||
|
||||
mrs x9, tpidr_el0
|
||||
mrs x10, tpidrro_el0
|
||||
stp x9, x10, [x0, #CTX_TPIDR_EL0]
|
||||
|
||||
mrs x11, dacr32_el2
|
||||
mrs x12, ifsr32_el2
|
||||
stp x11, x12, [x0, #CTX_DACR32_EL2]
|
||||
|
||||
mrs x13, par_el1
|
||||
mrs x14, far_el1
|
||||
stp x13, x14, [x0, #CTX_PAR_EL1]
|
||||
|
||||
mrs x15, afsr0_el1
|
||||
mrs x16, afsr1_el1
|
||||
stp x15, x16, [x0, #CTX_AFSR0_EL1]
|
||||
|
||||
mrs x17, contextidr_el1
|
||||
mrs x9, vbar_el1
|
||||
stp x17, x9, [x0, #CTX_CONTEXTIDR_EL1]
|
||||
|
||||
mrs x10, cntp_ctl_el0
|
||||
mrs x11, cntp_cval_el0
|
||||
stp x10, x11, [x0, #CTX_CNTP_CTL_EL0]
|
||||
|
||||
mrs x12, cntv_ctl_el0
|
||||
mrs x13, cntv_cval_el0
|
||||
stp x12, x13, [x0, #CTX_CNTV_CTL_EL0]
|
||||
|
||||
mrs x14, cntkctl_el1
|
||||
mrs x15, fpexc32_el2
|
||||
stp x14, x15, [x0, #CTX_CNTKCTL_EL1]
|
||||
|
||||
ret
|
||||
|
||||
/* -----------------------------------------------------
|
||||
* The following function strictly follows the AArch64
|
||||
* PCS to use x9-x17 (temporary caller-saved registers)
|
||||
* to restore EL1 system register context. It assumes
|
||||
* that 'x0' is pointing to a 'el1_sys_regs' structure
|
||||
* from where the register context will be restored
|
||||
* -----------------------------------------------------
|
||||
*/
|
||||
.global el1_sysregs_context_restore
|
||||
el1_sysregs_context_restore:
|
||||
|
||||
ldp x9, x10, [x0, #CTX_SPSR_EL1]
|
||||
msr spsr_el1, x9
|
||||
msr elr_el1, x10
|
||||
|
||||
ldp x11, x12, [x0, #CTX_SPSR_ABT]
|
||||
msr spsr_abt, x11
|
||||
msr spsr_und, x12
|
||||
|
||||
ldp x13, x14, [x0, #CTX_SPSR_IRQ]
|
||||
msr spsr_irq, x13
|
||||
msr spsr_fiq, x14
|
||||
|
||||
ldp x15, x16, [x0, #CTX_SCTLR_EL1]
|
||||
msr sctlr_el1, x15
|
||||
msr actlr_el1, x16
|
||||
|
||||
ldp x17, x9, [x0, #CTX_CPACR_EL1]
|
||||
msr cpacr_el1, x17
|
||||
msr csselr_el1, x9
|
||||
|
||||
ldp x10, x11, [x0, #CTX_SP_EL1]
|
||||
msr sp_el1, x10
|
||||
msr esr_el1, x11
|
||||
|
||||
ldp x12, x13, [x0, #CTX_TTBR0_EL1]
|
||||
msr ttbr0_el1, x12
|
||||
msr ttbr1_el1, x13
|
||||
|
||||
ldp x14, x15, [x0, #CTX_MAIR_EL1]
|
||||
msr mair_el1, x14
|
||||
msr amair_el1, x15
|
||||
|
||||
ldp x16, x17, [x0, #CTX_TCR_EL1]
|
||||
msr tcr_el1, x16
|
||||
msr tpidr_el1, x17
|
||||
|
||||
ldp x9, x10, [x0, #CTX_TPIDR_EL0]
|
||||
msr tpidr_el0, x9
|
||||
msr tpidrro_el0, x10
|
||||
|
||||
ldp x11, x12, [x0, #CTX_DACR32_EL2]
|
||||
msr dacr32_el2, x11
|
||||
msr ifsr32_el2, x12
|
||||
|
||||
ldp x13, x14, [x0, #CTX_PAR_EL1]
|
||||
msr par_el1, x13
|
||||
msr far_el1, x14
|
||||
|
||||
ldp x15, x16, [x0, #CTX_AFSR0_EL1]
|
||||
msr afsr0_el1, x15
|
||||
msr afsr1_el1, x16
|
||||
|
||||
ldp x17, x9, [x0, #CTX_CONTEXTIDR_EL1]
|
||||
msr contextidr_el1, x17
|
||||
msr vbar_el1, x9
|
||||
|
||||
ldp x10, x11, [x0, #CTX_CNTP_CTL_EL0]
|
||||
msr cntp_ctl_el0, x10
|
||||
msr cntp_cval_el0, x11
|
||||
|
||||
ldp x12, x13, [x0, #CTX_CNTV_CTL_EL0]
|
||||
msr cntv_ctl_el0, x12
|
||||
msr cntv_cval_el0, x13
|
||||
|
||||
ldp x14, x15, [x0, #CTX_CNTKCTL_EL1]
|
||||
msr cntkctl_el1, x14
|
||||
msr fpexc32_el2, x15
|
||||
|
||||
/* No explict ISB required here as ERET covers it */
|
||||
|
||||
ret
|
||||
|
||||
/* -----------------------------------------------------
|
||||
* The followsing function follows the aapcs_64 strictly
|
||||
* to use x9-x17 (temporary caller-saved registers
|
||||
* according to AArch64 PCS) to save floating point
|
||||
* register context. It assumes that 'x0' is pointing to
|
||||
* a 'fp_regs' structure where the register context will
|
||||
* be saved.
|
||||
*
|
||||
* Access to VFP registers will trap if CPTR_EL3.TFP is
|
||||
* set. However currently we don't use VFP registers
|
||||
* nor set traps in Trusted Firmware, and assume it's
|
||||
* cleared
|
||||
*
|
||||
* TODO: Revisit when VFP is used in secure world
|
||||
* -----------------------------------------------------
|
||||
*/
|
||||
.global fpregs_context_save
|
||||
fpregs_context_save:
|
||||
stp q0, q1, [x0, #CTX_FP_Q0]
|
||||
stp q2, q3, [x0, #CTX_FP_Q2]
|
||||
stp q4, q5, [x0, #CTX_FP_Q4]
|
||||
stp q6, q7, [x0, #CTX_FP_Q6]
|
||||
stp q8, q9, [x0, #CTX_FP_Q8]
|
||||
stp q10, q11, [x0, #CTX_FP_Q10]
|
||||
stp q12, q13, [x0, #CTX_FP_Q12]
|
||||
stp q14, q15, [x0, #CTX_FP_Q14]
|
||||
stp q16, q17, [x0, #CTX_FP_Q16]
|
||||
stp q18, q19, [x0, #CTX_FP_Q18]
|
||||
stp q20, q21, [x0, #CTX_FP_Q20]
|
||||
stp q22, q23, [x0, #CTX_FP_Q22]
|
||||
stp q24, q25, [x0, #CTX_FP_Q24]
|
||||
stp q26, q27, [x0, #CTX_FP_Q26]
|
||||
stp q28, q29, [x0, #CTX_FP_Q28]
|
||||
stp q30, q31, [x0, #CTX_FP_Q30]
|
||||
|
||||
mrs x9, fpsr
|
||||
str x9, [x0, #CTX_FP_FPSR]
|
||||
|
||||
mrs x10, fpcr
|
||||
str x10, [x0, #CTX_FP_FPCR]
|
||||
|
||||
ret
|
||||
|
||||
/* -----------------------------------------------------
|
||||
* The following function follows the aapcs_64 strictly
|
||||
* to use x9-x17 (temporary caller-saved registers
|
||||
* according to AArch64 PCS) to restore floating point
|
||||
* register context. It assumes that 'x0' is pointing to
|
||||
* a 'fp_regs' structure from where the register context
|
||||
* will be restored.
|
||||
*
|
||||
* Access to VFP registers will trap if CPTR_EL3.TFP is
|
||||
* set. However currently we don't use VFP registers
|
||||
* nor set traps in Trusted Firmware, and assume it's
|
||||
* cleared
|
||||
*
|
||||
* TODO: Revisit when VFP is used in secure world
|
||||
* -----------------------------------------------------
|
||||
*/
|
||||
.global fpregs_context_restore
|
||||
fpregs_context_restore:
|
||||
ldp q0, q1, [x0, #CTX_FP_Q0]
|
||||
ldp q2, q3, [x0, #CTX_FP_Q2]
|
||||
ldp q4, q5, [x0, #CTX_FP_Q4]
|
||||
ldp q6, q7, [x0, #CTX_FP_Q6]
|
||||
ldp q8, q9, [x0, #CTX_FP_Q8]
|
||||
ldp q10, q11, [x0, #CTX_FP_Q10]
|
||||
ldp q12, q13, [x0, #CTX_FP_Q12]
|
||||
ldp q14, q15, [x0, #CTX_FP_Q14]
|
||||
ldp q16, q17, [x0, #CTX_FP_Q16]
|
||||
ldp q18, q19, [x0, #CTX_FP_Q18]
|
||||
ldp q20, q21, [x0, #CTX_FP_Q20]
|
||||
ldp q22, q23, [x0, #CTX_FP_Q22]
|
||||
ldp q24, q25, [x0, #CTX_FP_Q24]
|
||||
ldp q26, q27, [x0, #CTX_FP_Q26]
|
||||
ldp q28, q29, [x0, #CTX_FP_Q28]
|
||||
ldp q30, q31, [x0, #CTX_FP_Q30]
|
||||
|
||||
ldr x9, [x0, #CTX_FP_FPSR]
|
||||
msr fpsr, x9
|
||||
|
||||
str x10, [x0, #CTX_FP_FPCR]
|
||||
msr fpcr, x10
|
||||
|
||||
/*
|
||||
* No explict ISB required here as ERET to
|
||||
* swtich to secure EL1 or non-secure world
|
||||
* covers it
|
||||
*/
|
||||
|
||||
ret
|
|
@ -63,7 +63,8 @@ BL31_OBJS += bl31_arch_setup.o \
|
|||
gic_v3_sysregs.o \
|
||||
bakery_lock.o \
|
||||
runtime_svc.o \
|
||||
early_exceptions.o
|
||||
early_exceptions.o \
|
||||
context.o
|
||||
|
||||
BL31_ENTRY_POINT := bl31_entrypoint
|
||||
BL31_MAPFILE := bl31.map
|
||||
|
|
236
include/context.h
Normal file
236
include/context.h
Normal file
|
@ -0,0 +1,236 @@
|
|||
/*
|
||||
* Copyright (c) 2013-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.
|
||||
*/
|
||||
|
||||
#ifndef __CONTEXT_H__
|
||||
#define __CONTEXT_H__
|
||||
|
||||
#include <bl_common.h>
|
||||
#include <arch.h>
|
||||
|
||||
/*******************************************************************************
|
||||
* Constants that allow assembler code to access members of and the 'el3_state'
|
||||
* structure at their correct offsets. Note that some of the registers are only
|
||||
* 32-bits wide but are stored as 64-bit values for convenience
|
||||
******************************************************************************/
|
||||
#define CTX_EL3STATE_OFFSET 0x0
|
||||
#define CTX_SAVED_SP_EL3 0x0
|
||||
#define CTX_SAVED_SP_EL0 0x8
|
||||
#define CTX_SPSR_EL3 0x10
|
||||
#define CTX_ELR_EL3 0x18
|
||||
#define CTX_SCR_EL3 0x20
|
||||
#define CTX_SCTLR_EL3 0x28
|
||||
#define CTX_CPTR_EL3 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
|
||||
#define CTX_VBAR_EL3 0x68 /* Currently unused */
|
||||
#define CTX_EL3STATE_END 0x70
|
||||
|
||||
/*******************************************************************************
|
||||
* Constants that allow assembler code to access members of and the
|
||||
* 'el1_sys_regs' structure at their correct offsets. Note that some of the
|
||||
* registers are only 32-bits wide but are stored as 64-bit values for
|
||||
* convenience
|
||||
******************************************************************************/
|
||||
#define CTX_SYSREGS_OFFSET (CTX_EL3STATE_OFFSET + CTX_EL3STATE_END)
|
||||
#define CTX_SPSR_EL1 0x0
|
||||
#define CTX_ELR_EL1 0x8
|
||||
#define CTX_SPSR_ABT 0x10
|
||||
#define CTX_SPSR_UND 0x18
|
||||
#define CTX_SPSR_IRQ 0x20
|
||||
#define CTX_SPSR_FIQ 0x28
|
||||
#define CTX_SCTLR_EL1 0x30
|
||||
#define CTX_ACTLR_EL1 0x38
|
||||
#define CTX_CPACR_EL1 0x40
|
||||
#define CTX_CSSELR_EL1 0x48
|
||||
#define CTX_SP_EL1 0x50
|
||||
#define CTX_ESR_EL1 0x58
|
||||
#define CTX_TTBR0_EL1 0x60
|
||||
#define CTX_TTBR1_EL1 0x68
|
||||
#define CTX_MAIR_EL1 0x70
|
||||
#define CTX_AMAIR_EL1 0x78
|
||||
#define CTX_TCR_EL1 0x80
|
||||
#define CTX_TPIDR_EL1 0x88
|
||||
#define CTX_TPIDR_EL0 0x90
|
||||
#define CTX_TPIDRRO_EL0 0x98
|
||||
#define CTX_DACR32_EL2 0xa0
|
||||
#define CTX_IFSR32_EL2 0xa8
|
||||
#define CTX_PAR_EL1 0xb0
|
||||
#define CTX_FAR_EL1 0xb8
|
||||
#define CTX_AFSR0_EL1 0xc0
|
||||
#define CTX_AFSR1_EL1 0xc8
|
||||
#define CTX_CONTEXTIDR_EL1 0xd0
|
||||
#define CTX_VBAR_EL1 0xd8
|
||||
#define CTX_CNTP_CTL_EL0 0xe0
|
||||
#define CTX_CNTP_CVAL_EL0 0xe8
|
||||
#define CTX_CNTV_CTL_EL0 0xf0
|
||||
#define CTX_CNTV_CVAL_EL0 0xf8
|
||||
#define CTX_CNTKCTL_EL1 0x100
|
||||
#define CTX_FP_FPEXC32_EL2 0x108
|
||||
#define CTX_SYSREGS_END 0x110
|
||||
|
||||
/*******************************************************************************
|
||||
* Constants that allow assembler code to access members of and the 'fp_regs'
|
||||
* structure at their correct offsets.
|
||||
******************************************************************************/
|
||||
#define CTX_FPREGS_OFFSET (CTX_SYSREGS_OFFSET + CTX_SYSREGS_END)
|
||||
#define CTX_FP_Q0 0x0
|
||||
#define CTX_FP_Q1 0x10
|
||||
#define CTX_FP_Q2 0x20
|
||||
#define CTX_FP_Q3 0x30
|
||||
#define CTX_FP_Q4 0x40
|
||||
#define CTX_FP_Q5 0x50
|
||||
#define CTX_FP_Q6 0x60
|
||||
#define CTX_FP_Q7 0x70
|
||||
#define CTX_FP_Q8 0x80
|
||||
#define CTX_FP_Q9 0x90
|
||||
#define CTX_FP_Q10 0xa0
|
||||
#define CTX_FP_Q11 0xb0
|
||||
#define CTX_FP_Q12 0xc0
|
||||
#define CTX_FP_Q13 0xd0
|
||||
#define CTX_FP_Q14 0xe0
|
||||
#define CTX_FP_Q15 0xf0
|
||||
#define CTX_FP_Q16 0x100
|
||||
#define CTX_FP_Q17 0x110
|
||||
#define CTX_FP_Q18 0x120
|
||||
#define CTX_FP_Q19 0x130
|
||||
#define CTX_FP_Q20 0x140
|
||||
#define CTX_FP_Q21 0x150
|
||||
#define CTX_FP_Q22 0x160
|
||||
#define CTX_FP_Q23 0x170
|
||||
#define CTX_FP_Q24 0x180
|
||||
#define CTX_FP_Q25 0x190
|
||||
#define CTX_FP_Q26 0x1a0
|
||||
#define CTX_FP_Q27 0x1b0
|
||||
#define CTX_FP_Q28 0x1c0
|
||||
#define CTX_FP_Q29 0x1d0
|
||||
#define CTX_FP_Q30 0x1e0
|
||||
#define CTX_FP_Q31 0x1f0
|
||||
#define CTX_FP_FPSR 0x200
|
||||
#define CTX_FP_FPCR 0x208
|
||||
#define CTX_FPREGS_END 0x210
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
/*
|
||||
* Common constants to help define the 'cpu_context' structure and its
|
||||
* members below.
|
||||
*/
|
||||
#define DWORD_SHIFT 3
|
||||
#define DEFINE_REG_STRUCT(name, num_regs) \
|
||||
typedef struct { \
|
||||
uint64_t _regs[num_regs]; \
|
||||
} __aligned(16) name
|
||||
|
||||
/* Constants to determine the size of individual context structures */
|
||||
#define CTX_SYSREG_ALL (CTX_SYSREGS_END >> DWORD_SHIFT)
|
||||
#define CTX_FPREG_ALL (CTX_FPREGS_END >> DWORD_SHIFT)
|
||||
#define CTX_EL3STATE_ALL (CTX_EL3STATE_END >> DWORD_SHIFT)
|
||||
|
||||
/*
|
||||
* AArch64 EL1 system register context structure for preserving the
|
||||
* architectural state during switches from one security state to
|
||||
* another in EL1.
|
||||
*/
|
||||
DEFINE_REG_STRUCT(el1_sys_regs, CTX_SYSREG_ALL);
|
||||
|
||||
/*
|
||||
* AArch64 floating point register context structure for preserving
|
||||
* the floating point state during switches from one security state to
|
||||
* another.
|
||||
*/
|
||||
DEFINE_REG_STRUCT(fp_regs, CTX_FPREG_ALL);
|
||||
|
||||
/*
|
||||
* Miscellaneous registers used by EL3 firmware to maintain its state
|
||||
* across exception entries and exits
|
||||
*/
|
||||
DEFINE_REG_STRUCT(el3_state, CTX_EL3STATE_ALL);
|
||||
|
||||
/*
|
||||
* Macros to access members of any of the above structures using their
|
||||
* offsets
|
||||
*/
|
||||
#define read_ctx_reg(ctx, offset) ((ctx)->_regs[offset >> DWORD_SHIFT])
|
||||
#define write_ctx_reg(ctx, offset, val) (((ctx)->_regs[offset >> DWORD_SHIFT]) \
|
||||
= val)
|
||||
|
||||
/*
|
||||
* Top-level context structure which is used by EL3 firmware to
|
||||
* preserve the state of a core at EL1 in one of the two security
|
||||
* states and save enough EL3 meta data to be able to return to that
|
||||
* EL and security state. The context management library will be used
|
||||
* to ensure that SP_EL3 always points to an instance of this
|
||||
* structure at exception entry and exit. Each instance will
|
||||
* correspond to either the secure or the non-secure state.
|
||||
*/
|
||||
typedef struct {
|
||||
el3_state el3state_ctx;
|
||||
el1_sys_regs sysregs_ctx;
|
||||
fp_regs fpregs_ctx;
|
||||
} cpu_context;
|
||||
|
||||
/* Macros to access members of the 'cpu_context' structure */
|
||||
#define get_el3state_ctx(h) (&((cpu_context *) h)->el3state_ctx)
|
||||
#define get_fpregs_ctx(h) (&((cpu_context *) h)->fpregs_ctx)
|
||||
#define get_sysregs_ctx(h) (&((cpu_context *) h)->sysregs_ctx)
|
||||
|
||||
/*
|
||||
* Compile time assertions related to the 'cpu_context' structure to
|
||||
* ensure that the assembler and the compiler view of the offsets of
|
||||
* the structure members is the same.
|
||||
*/
|
||||
CASSERT(CTX_SYSREGS_OFFSET == __builtin_offsetof(cpu_context, sysregs_ctx), \
|
||||
assert_core_context_sys_offset_mismatch);
|
||||
CASSERT(CTX_FPREGS_OFFSET == __builtin_offsetof(cpu_context, fpregs_ctx), \
|
||||
assert_core_context_fp_offset_mismatch);
|
||||
CASSERT(CTX_EL3STATE_OFFSET == __builtin_offsetof(cpu_context, el3state_ctx), \
|
||||
assert_core_context_el3state_offset_mismatch);
|
||||
|
||||
/*******************************************************************************
|
||||
* Function prototypes
|
||||
******************************************************************************/
|
||||
void el3_sysregs_context_save(el3_state *regs);
|
||||
void el3_sysregs_context_restore(el3_state *regs);
|
||||
void el1_sysregs_context_save(el1_sys_regs *regs);
|
||||
void el1_sysregs_context_restore(el1_sys_regs *regs);
|
||||
void fpregs_context_save(fp_regs *regs);
|
||||
void fpregs_context_restore(fp_regs *regs);
|
||||
|
||||
#undef CTX_SYSREG_ALL
|
||||
#undef CTX_FP_ALL
|
||||
#undef CTX_EL3STATE_ALL
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
#endif /* __CONTEXT_H__ */
|
Loading…
Add table
Reference in a new issue