GK SDK 源码库: XMIPCLinuxV100R005C00SPC030 (kernel/tools/open_source excluded)
This commit is contained in:
@@ -0,0 +1,786 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2023, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef ARCH_H
|
||||
#define ARCH_H
|
||||
|
||||
#include <lib/utils_def.h>
|
||||
|
||||
/*******************************************************************************
|
||||
* MIDR bit definitions
|
||||
******************************************************************************/
|
||||
#define MIDR_IMPL_MASK U(0xff)
|
||||
#define MIDR_IMPL_SHIFT U(24)
|
||||
#define MIDR_VAR_SHIFT U(20)
|
||||
#define MIDR_VAR_BITS U(4)
|
||||
#define MIDR_VAR_MASK U(0xf)
|
||||
#define MIDR_REV_SHIFT U(0)
|
||||
#define MIDR_REV_BITS U(4)
|
||||
#define MIDR_REV_MASK U(0xf)
|
||||
#define MIDR_PN_MASK U(0xfff)
|
||||
#define MIDR_PN_SHIFT U(4)
|
||||
|
||||
/*******************************************************************************
|
||||
* MPIDR macros
|
||||
******************************************************************************/
|
||||
#define MPIDR_MT_MASK (U(1) << 24)
|
||||
#define MPIDR_CPU_MASK MPIDR_AFFLVL_MASK
|
||||
#define MPIDR_CLUSTER_MASK (MPIDR_AFFLVL_MASK << MPIDR_AFFINITY_BITS)
|
||||
#define MPIDR_AFFINITY_BITS U(8)
|
||||
#define MPIDR_AFFLVL_MASK U(0xff)
|
||||
#define MPIDR_AFFLVL_SHIFT U(3)
|
||||
#define MPIDR_AFF0_SHIFT U(0)
|
||||
#define MPIDR_AFF1_SHIFT U(8)
|
||||
#define MPIDR_AFF2_SHIFT U(16)
|
||||
#define MPIDR_AFF_SHIFT(_n) MPIDR_AFF##_n##_SHIFT
|
||||
#define MPIDR_AFFINITY_MASK U(0x00ffffff)
|
||||
#define MPIDR_AFFLVL0 U(0)
|
||||
#define MPIDR_AFFLVL1 U(1)
|
||||
#define MPIDR_AFFLVL2 U(2)
|
||||
#define MPIDR_AFFLVL(_n) MPIDR_AFFLVL##_n
|
||||
|
||||
#define MPIDR_AFFLVL0_VAL(mpidr) \
|
||||
(((mpidr) >> MPIDR_AFF0_SHIFT) & MPIDR_AFFLVL_MASK)
|
||||
#define MPIDR_AFFLVL1_VAL(mpidr) \
|
||||
(((mpidr) >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK)
|
||||
#define MPIDR_AFFLVL2_VAL(mpidr) \
|
||||
(((mpidr) >> MPIDR_AFF2_SHIFT) & MPIDR_AFFLVL_MASK)
|
||||
#define MPIDR_AFFLVL3_VAL(mpidr) U(0)
|
||||
|
||||
#define MPIDR_AFF_ID(mpid, n) \
|
||||
(((mpid) >> MPIDR_AFF_SHIFT(n)) & MPIDR_AFFLVL_MASK)
|
||||
|
||||
#define MPID_MASK (MPIDR_MT_MASK |\
|
||||
(MPIDR_AFFLVL_MASK << MPIDR_AFF2_SHIFT)|\
|
||||
(MPIDR_AFFLVL_MASK << MPIDR_AFF1_SHIFT)|\
|
||||
(MPIDR_AFFLVL_MASK << MPIDR_AFF0_SHIFT))
|
||||
|
||||
/*
|
||||
* An invalid MPID. This value can be used by functions that return an MPID to
|
||||
* indicate an error.
|
||||
*/
|
||||
#define INVALID_MPID U(0xFFFFFFFF)
|
||||
|
||||
/*
|
||||
* The MPIDR_MAX_AFFLVL count starts from 0. Take care to
|
||||
* add one while using this macro to define array sizes.
|
||||
*/
|
||||
#define MPIDR_MAX_AFFLVL U(2)
|
||||
|
||||
/* Data Cache set/way op type defines */
|
||||
#define DC_OP_ISW U(0x0)
|
||||
#define DC_OP_CISW U(0x1)
|
||||
#if ERRATA_A53_827319
|
||||
#define DC_OP_CSW DC_OP_CISW
|
||||
#else
|
||||
#define DC_OP_CSW U(0x2)
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
* Generic timer memory mapped registers & offsets
|
||||
******************************************************************************/
|
||||
#define CNTCR_OFF U(0x000)
|
||||
/* Counter Count Value Lower register */
|
||||
#define CNTCVL_OFF U(0x008)
|
||||
/* Counter Count Value Upper register */
|
||||
#define CNTCVU_OFF U(0x00C)
|
||||
#define CNTFID_OFF U(0x020)
|
||||
|
||||
#define CNTCR_EN (U(1) << 0)
|
||||
#define CNTCR_HDBG (U(1) << 1)
|
||||
#define CNTCR_FCREQ(x) ((x) << 8)
|
||||
|
||||
/*******************************************************************************
|
||||
* System register bit definitions
|
||||
******************************************************************************/
|
||||
/* CLIDR definitions */
|
||||
#define LOUIS_SHIFT U(21)
|
||||
#define LOC_SHIFT U(24)
|
||||
#define CLIDR_FIELD_WIDTH U(3)
|
||||
|
||||
/* CSSELR definitions */
|
||||
#define LEVEL_SHIFT U(1)
|
||||
|
||||
/* ID_DFR0_EL1 definitions */
|
||||
#define ID_DFR0_COPTRC_SHIFT U(12)
|
||||
#define ID_DFR0_COPTRC_MASK U(0xf)
|
||||
#define ID_DFR0_COPTRC_SUPPORTED U(1)
|
||||
#define ID_DFR0_COPTRC_LENGTH U(4)
|
||||
#define ID_DFR0_TRACEFILT_SHIFT U(28)
|
||||
#define ID_DFR0_TRACEFILT_MASK U(0xf)
|
||||
#define ID_DFR0_TRACEFILT_SUPPORTED U(1)
|
||||
#define ID_DFR0_TRACEFILT_LENGTH U(4)
|
||||
|
||||
/* ID_DFR1_EL1 definitions */
|
||||
#define ID_DFR1_MTPMU_SHIFT U(0)
|
||||
#define ID_DFR1_MTPMU_MASK U(0xf)
|
||||
#define ID_DFR1_MTPMU_SUPPORTED U(1)
|
||||
|
||||
/* ID_MMFR4 definitions */
|
||||
#define ID_MMFR4_CNP_SHIFT U(12)
|
||||
#define ID_MMFR4_CNP_LENGTH U(4)
|
||||
#define ID_MMFR4_CNP_MASK U(0xf)
|
||||
|
||||
#define ID_MMFR4_CCIDX_SHIFT U(24)
|
||||
#define ID_MMFR4_CCIDX_LENGTH U(4)
|
||||
#define ID_MMFR4_CCIDX_MASK U(0xf)
|
||||
|
||||
/* ID_PFR0 definitions */
|
||||
#define ID_PFR0_AMU_SHIFT U(20)
|
||||
#define ID_PFR0_AMU_LENGTH U(4)
|
||||
#define ID_PFR0_AMU_MASK U(0xf)
|
||||
#define ID_PFR0_AMU_NOT_SUPPORTED U(0x0)
|
||||
#define ID_PFR0_AMU_V1 U(0x1)
|
||||
#define ID_PFR0_AMU_V1P1 U(0x2)
|
||||
|
||||
#define ID_PFR0_DIT_SHIFT U(24)
|
||||
#define ID_PFR0_DIT_LENGTH U(4)
|
||||
#define ID_PFR0_DIT_MASK U(0xf)
|
||||
#define ID_PFR0_DIT_SUPPORTED (U(1) << ID_PFR0_DIT_SHIFT)
|
||||
|
||||
/* ID_PFR1 definitions */
|
||||
#define ID_PFR1_VIRTEXT_SHIFT U(12)
|
||||
#define ID_PFR1_VIRTEXT_MASK U(0xf)
|
||||
#define GET_VIRT_EXT(id) (((id) >> ID_PFR1_VIRTEXT_SHIFT) \
|
||||
& ID_PFR1_VIRTEXT_MASK)
|
||||
#define ID_PFR1_GENTIMER_SHIFT U(16)
|
||||
#define ID_PFR1_GENTIMER_MASK U(0xf)
|
||||
#define ID_PFR1_GIC_SHIFT U(28)
|
||||
#define ID_PFR1_GIC_MASK U(0xf)
|
||||
#define ID_PFR1_SEC_SHIFT U(4)
|
||||
#define ID_PFR1_SEC_MASK U(0xf)
|
||||
#define ID_PFR1_ELx_ENABLED U(1)
|
||||
|
||||
/* SCTLR definitions */
|
||||
#define SCTLR_RES1_DEF ((U(1) << 23) | (U(1) << 22) | (U(1) << 4) | \
|
||||
(U(1) << 3))
|
||||
#if ARM_ARCH_MAJOR == 7
|
||||
#define SCTLR_RES1 SCTLR_RES1_DEF
|
||||
#else
|
||||
#define SCTLR_RES1 (SCTLR_RES1_DEF | (U(1) << 11))
|
||||
#endif
|
||||
#define SCTLR_M_BIT (U(1) << 0)
|
||||
#define SCTLR_A_BIT (U(1) << 1)
|
||||
#define SCTLR_C_BIT (U(1) << 2)
|
||||
#define SCTLR_CP15BEN_BIT (U(1) << 5)
|
||||
#define SCTLR_ITD_BIT (U(1) << 7)
|
||||
#define SCTLR_Z_BIT (U(1) << 11)
|
||||
#define SCTLR_I_BIT (U(1) << 12)
|
||||
#define SCTLR_V_BIT (U(1) << 13)
|
||||
#define SCTLR_RR_BIT (U(1) << 14)
|
||||
#define SCTLR_NTWI_BIT (U(1) << 16)
|
||||
#define SCTLR_NTWE_BIT (U(1) << 18)
|
||||
#define SCTLR_WXN_BIT (U(1) << 19)
|
||||
#define SCTLR_UWXN_BIT (U(1) << 20)
|
||||
#define SCTLR_EE_BIT (U(1) << 25)
|
||||
#define SCTLR_TRE_BIT (U(1) << 28)
|
||||
#define SCTLR_AFE_BIT (U(1) << 29)
|
||||
#define SCTLR_TE_BIT (U(1) << 30)
|
||||
#define SCTLR_DSSBS_BIT (U(1) << 31)
|
||||
#define SCTLR_RESET_VAL (SCTLR_RES1 | SCTLR_NTWE_BIT | \
|
||||
SCTLR_NTWI_BIT | SCTLR_CP15BEN_BIT)
|
||||
|
||||
/* SDCR definitions */
|
||||
#define SDCR_SPD(x) ((x) << 14)
|
||||
#define SDCR_SPD_LEGACY U(0x0)
|
||||
#define SDCR_SPD_DISABLE U(0x2)
|
||||
#define SDCR_SPD_ENABLE U(0x3)
|
||||
#define SDCR_SCCD_BIT (U(1) << 23)
|
||||
#define SDCR_TTRF_BIT (U(1) << 19)
|
||||
#define SDCR_SPME_BIT (U(1) << 17)
|
||||
#define SDCR_RESET_VAL U(0x0)
|
||||
#define SDCR_MTPME_BIT (U(1) << 28)
|
||||
|
||||
/* HSCTLR definitions */
|
||||
#define HSCTLR_RES1 ((U(1) << 29) | (U(1) << 28) | (U(1) << 23) | \
|
||||
(U(1) << 22) | (U(1) << 18) | (U(1) << 16) | \
|
||||
(U(1) << 11) | (U(1) << 4) | (U(1) << 3))
|
||||
|
||||
#define HSCTLR_M_BIT (U(1) << 0)
|
||||
#define HSCTLR_A_BIT (U(1) << 1)
|
||||
#define HSCTLR_C_BIT (U(1) << 2)
|
||||
#define HSCTLR_CP15BEN_BIT (U(1) << 5)
|
||||
#define HSCTLR_ITD_BIT (U(1) << 7)
|
||||
#define HSCTLR_SED_BIT (U(1) << 8)
|
||||
#define HSCTLR_I_BIT (U(1) << 12)
|
||||
#define HSCTLR_WXN_BIT (U(1) << 19)
|
||||
#define HSCTLR_EE_BIT (U(1) << 25)
|
||||
#define HSCTLR_TE_BIT (U(1) << 30)
|
||||
|
||||
/* CPACR definitions */
|
||||
#define CPACR_FPEN(x) ((x) << 20)
|
||||
#define CPACR_FP_TRAP_PL0 UL(0x1)
|
||||
#define CPACR_FP_TRAP_ALL UL(0x2)
|
||||
#define CPACR_FP_TRAP_NONE UL(0x3)
|
||||
|
||||
/* SCR definitions */
|
||||
#define SCR_TWE_BIT (UL(1) << 13)
|
||||
#define SCR_TWI_BIT (UL(1) << 12)
|
||||
#define SCR_SIF_BIT (UL(1) << 9)
|
||||
#define SCR_HCE_BIT (UL(1) << 8)
|
||||
#define SCR_SCD_BIT (UL(1) << 7)
|
||||
#define SCR_NET_BIT (UL(1) << 6)
|
||||
#define SCR_AW_BIT (UL(1) << 5)
|
||||
#define SCR_FW_BIT (UL(1) << 4)
|
||||
#define SCR_EA_BIT (UL(1) << 3)
|
||||
#define SCR_FIQ_BIT (UL(1) << 2)
|
||||
#define SCR_IRQ_BIT (UL(1) << 1)
|
||||
#define SCR_NS_BIT (UL(1) << 0)
|
||||
#define SCR_VALID_BIT_MASK U(0x33ff)
|
||||
#define SCR_RESET_VAL U(0x0)
|
||||
|
||||
#define GET_NS_BIT(scr) ((scr) & SCR_NS_BIT)
|
||||
|
||||
/* HCR definitions */
|
||||
#define HCR_TGE_BIT (U(1) << 27)
|
||||
#define HCR_AMO_BIT (U(1) << 5)
|
||||
#define HCR_IMO_BIT (U(1) << 4)
|
||||
#define HCR_FMO_BIT (U(1) << 3)
|
||||
#define HCR_RESET_VAL U(0x0)
|
||||
|
||||
/* CNTHCTL definitions */
|
||||
#define CNTHCTL_RESET_VAL U(0x0)
|
||||
#define PL1PCEN_BIT (U(1) << 1)
|
||||
#define PL1PCTEN_BIT (U(1) << 0)
|
||||
|
||||
/* CNTKCTL definitions */
|
||||
#define PL0PTEN_BIT (U(1) << 9)
|
||||
#define PL0VTEN_BIT (U(1) << 8)
|
||||
#define PL0PCTEN_BIT (U(1) << 0)
|
||||
#define PL0VCTEN_BIT (U(1) << 1)
|
||||
#define EVNTEN_BIT (U(1) << 2)
|
||||
#define EVNTDIR_BIT (U(1) << 3)
|
||||
#define EVNTI_SHIFT U(4)
|
||||
#define EVNTI_MASK U(0xf)
|
||||
|
||||
/* HCPTR definitions */
|
||||
#define HCPTR_RES1 ((U(1) << 13) | (U(1) << 12) | U(0x3ff))
|
||||
#define TCPAC_BIT (U(1) << 31)
|
||||
#define TAM_SHIFT U(30)
|
||||
#define TAM_BIT (U(1) << TAM_SHIFT)
|
||||
#define TTA_BIT (U(1) << 20)
|
||||
#define TCP11_BIT (U(1) << 11)
|
||||
#define TCP10_BIT (U(1) << 10)
|
||||
#define HCPTR_RESET_VAL HCPTR_RES1
|
||||
|
||||
/* VTTBR defintions */
|
||||
#define VTTBR_RESET_VAL ULL(0x0)
|
||||
#define VTTBR_VMID_MASK ULL(0xff)
|
||||
#define VTTBR_VMID_SHIFT U(48)
|
||||
#define VTTBR_BADDR_MASK ULL(0xffffffffffff)
|
||||
#define VTTBR_BADDR_SHIFT U(0)
|
||||
|
||||
/* HDCR definitions */
|
||||
#define HDCR_MTPME_BIT (U(1) << 28)
|
||||
#define HDCR_HLP_BIT (U(1) << 26)
|
||||
#define HDCR_HPME_BIT (U(1) << 7)
|
||||
#define HDCR_RESET_VAL U(0x0)
|
||||
|
||||
/* HSTR definitions */
|
||||
#define HSTR_RESET_VAL U(0x0)
|
||||
|
||||
/* CNTHP_CTL definitions */
|
||||
#define CNTHP_CTL_RESET_VAL U(0x0)
|
||||
|
||||
/* NSACR definitions */
|
||||
#define NSASEDIS_BIT (U(1) << 15)
|
||||
#define NSTRCDIS_BIT (U(1) << 20)
|
||||
#define NSACR_CP11_BIT (U(1) << 11)
|
||||
#define NSACR_CP10_BIT (U(1) << 10)
|
||||
#define NSACR_IMP_DEF_MASK (U(0x7) << 16)
|
||||
#define NSACR_ENABLE_FP_ACCESS (NSACR_CP11_BIT | NSACR_CP10_BIT)
|
||||
#define NSACR_RESET_VAL U(0x0)
|
||||
|
||||
/* CPACR definitions */
|
||||
#define ASEDIS_BIT (U(1) << 31)
|
||||
#define TRCDIS_BIT (U(1) << 28)
|
||||
#define CPACR_CP11_SHIFT U(22)
|
||||
#define CPACR_CP10_SHIFT U(20)
|
||||
#define CPACR_ENABLE_FP_ACCESS ((U(0x3) << CPACR_CP11_SHIFT) |\
|
||||
(U(0x3) << CPACR_CP10_SHIFT))
|
||||
#define CPACR_RESET_VAL U(0x0)
|
||||
|
||||
/* FPEXC definitions */
|
||||
#define FPEXC_RES1 ((U(1) << 10) | (U(1) << 9) | (U(1) << 8))
|
||||
#define FPEXC_EN_BIT (U(1) << 30)
|
||||
#define FPEXC_RESET_VAL FPEXC_RES1
|
||||
|
||||
/* SPSR/CPSR definitions */
|
||||
#define SPSR_FIQ_BIT (U(1) << 0)
|
||||
#define SPSR_IRQ_BIT (U(1) << 1)
|
||||
#define SPSR_ABT_BIT (U(1) << 2)
|
||||
#define SPSR_AIF_SHIFT U(6)
|
||||
#define SPSR_AIF_MASK U(0x7)
|
||||
|
||||
#define SPSR_E_SHIFT U(9)
|
||||
#define SPSR_E_MASK U(0x1)
|
||||
#define SPSR_E_LITTLE U(0)
|
||||
#define SPSR_E_BIG U(1)
|
||||
|
||||
#define SPSR_T_SHIFT U(5)
|
||||
#define SPSR_T_MASK U(0x1)
|
||||
#define SPSR_T_ARM U(0)
|
||||
#define SPSR_T_THUMB U(1)
|
||||
|
||||
#define SPSR_MODE_SHIFT U(0)
|
||||
#define SPSR_MODE_MASK U(0x7)
|
||||
|
||||
#define SPSR_SSBS_BIT BIT_32(23)
|
||||
|
||||
#define DISABLE_ALL_EXCEPTIONS \
|
||||
(SPSR_FIQ_BIT | SPSR_IRQ_BIT | SPSR_ABT_BIT)
|
||||
|
||||
#define CPSR_DIT_BIT (U(1) << 21)
|
||||
/*
|
||||
* TTBCR definitions
|
||||
*/
|
||||
#define TTBCR_EAE_BIT (U(1) << 31)
|
||||
|
||||
#define TTBCR_SH1_NON_SHAREABLE (U(0x0) << 28)
|
||||
#define TTBCR_SH1_OUTER_SHAREABLE (U(0x2) << 28)
|
||||
#define TTBCR_SH1_INNER_SHAREABLE (U(0x3) << 28)
|
||||
|
||||
#define TTBCR_RGN1_OUTER_NC (U(0x0) << 26)
|
||||
#define TTBCR_RGN1_OUTER_WBA (U(0x1) << 26)
|
||||
#define TTBCR_RGN1_OUTER_WT (U(0x2) << 26)
|
||||
#define TTBCR_RGN1_OUTER_WBNA (U(0x3) << 26)
|
||||
|
||||
#define TTBCR_RGN1_INNER_NC (U(0x0) << 24)
|
||||
#define TTBCR_RGN1_INNER_WBA (U(0x1) << 24)
|
||||
#define TTBCR_RGN1_INNER_WT (U(0x2) << 24)
|
||||
#define TTBCR_RGN1_INNER_WBNA (U(0x3) << 24)
|
||||
|
||||
#define TTBCR_EPD1_BIT (U(1) << 23)
|
||||
#define TTBCR_A1_BIT (U(1) << 22)
|
||||
|
||||
#define TTBCR_T1SZ_SHIFT U(16)
|
||||
#define TTBCR_T1SZ_MASK U(0x7)
|
||||
#define TTBCR_TxSZ_MIN U(0)
|
||||
#define TTBCR_TxSZ_MAX U(7)
|
||||
|
||||
#define TTBCR_SH0_NON_SHAREABLE (U(0x0) << 12)
|
||||
#define TTBCR_SH0_OUTER_SHAREABLE (U(0x2) << 12)
|
||||
#define TTBCR_SH0_INNER_SHAREABLE (U(0x3) << 12)
|
||||
|
||||
#define TTBCR_RGN0_OUTER_NC (U(0x0) << 10)
|
||||
#define TTBCR_RGN0_OUTER_WBA (U(0x1) << 10)
|
||||
#define TTBCR_RGN0_OUTER_WT (U(0x2) << 10)
|
||||
#define TTBCR_RGN0_OUTER_WBNA (U(0x3) << 10)
|
||||
|
||||
#define TTBCR_RGN0_INNER_NC (U(0x0) << 8)
|
||||
#define TTBCR_RGN0_INNER_WBA (U(0x1) << 8)
|
||||
#define TTBCR_RGN0_INNER_WT (U(0x2) << 8)
|
||||
#define TTBCR_RGN0_INNER_WBNA (U(0x3) << 8)
|
||||
|
||||
#define TTBCR_EPD0_BIT (U(1) << 7)
|
||||
#define TTBCR_T0SZ_SHIFT U(0)
|
||||
#define TTBCR_T0SZ_MASK U(0x7)
|
||||
|
||||
/*
|
||||
* HTCR definitions
|
||||
*/
|
||||
#define HTCR_RES1 ((U(1) << 31) | (U(1) << 23))
|
||||
|
||||
#define HTCR_SH0_NON_SHAREABLE (U(0x0) << 12)
|
||||
#define HTCR_SH0_OUTER_SHAREABLE (U(0x2) << 12)
|
||||
#define HTCR_SH0_INNER_SHAREABLE (U(0x3) << 12)
|
||||
|
||||
#define HTCR_RGN0_OUTER_NC (U(0x0) << 10)
|
||||
#define HTCR_RGN0_OUTER_WBA (U(0x1) << 10)
|
||||
#define HTCR_RGN0_OUTER_WT (U(0x2) << 10)
|
||||
#define HTCR_RGN0_OUTER_WBNA (U(0x3) << 10)
|
||||
|
||||
#define HTCR_RGN0_INNER_NC (U(0x0) << 8)
|
||||
#define HTCR_RGN0_INNER_WBA (U(0x1) << 8)
|
||||
#define HTCR_RGN0_INNER_WT (U(0x2) << 8)
|
||||
#define HTCR_RGN0_INNER_WBNA (U(0x3) << 8)
|
||||
|
||||
#define HTCR_T0SZ_SHIFT U(0)
|
||||
#define HTCR_T0SZ_MASK U(0x7)
|
||||
|
||||
#define MODE_RW_SHIFT U(0x4)
|
||||
#define MODE_RW_MASK U(0x1)
|
||||
#define MODE_RW_32 U(0x1)
|
||||
|
||||
#define MODE32_SHIFT U(0)
|
||||
#define MODE32_MASK U(0x1f)
|
||||
#define MODE32_usr U(0x10)
|
||||
#define MODE32_fiq U(0x11)
|
||||
#define MODE32_irq U(0x12)
|
||||
#define MODE32_svc U(0x13)
|
||||
#define MODE32_mon U(0x16)
|
||||
#define MODE32_abt U(0x17)
|
||||
#define MODE32_hyp U(0x1a)
|
||||
#define MODE32_und U(0x1b)
|
||||
#define MODE32_sys U(0x1f)
|
||||
|
||||
#define GET_M32(mode) (((mode) >> MODE32_SHIFT) & MODE32_MASK)
|
||||
|
||||
#define SPSR_MODE32(mode, isa, endian, aif) \
|
||||
( \
|
||||
( \
|
||||
(MODE_RW_32 << MODE_RW_SHIFT) | \
|
||||
(((mode) & MODE32_MASK) << MODE32_SHIFT) | \
|
||||
(((isa) & SPSR_T_MASK) << SPSR_T_SHIFT) | \
|
||||
(((endian) & SPSR_E_MASK) << SPSR_E_SHIFT) | \
|
||||
(((aif) & SPSR_AIF_MASK) << SPSR_AIF_SHIFT) \
|
||||
) & \
|
||||
(~(SPSR_SSBS_BIT)) \
|
||||
)
|
||||
|
||||
/*
|
||||
* TTBR definitions
|
||||
*/
|
||||
#define TTBR_CNP_BIT ULL(0x1)
|
||||
|
||||
/*
|
||||
* CTR definitions
|
||||
*/
|
||||
#define CTR_CWG_SHIFT U(24)
|
||||
#define CTR_CWG_MASK U(0xf)
|
||||
#define CTR_ERG_SHIFT U(20)
|
||||
#define CTR_ERG_MASK U(0xf)
|
||||
#define CTR_DMINLINE_SHIFT U(16)
|
||||
#define CTR_DMINLINE_WIDTH U(4)
|
||||
#define CTR_DMINLINE_MASK ((U(1) << 4) - U(1))
|
||||
#define CTR_L1IP_SHIFT U(14)
|
||||
#define CTR_L1IP_MASK U(0x3)
|
||||
#define CTR_IMINLINE_SHIFT U(0)
|
||||
#define CTR_IMINLINE_MASK U(0xf)
|
||||
|
||||
#define MAX_CACHE_LINE_SIZE U(0x800) /* 2KB */
|
||||
|
||||
/* PMCR definitions */
|
||||
#define PMCR_N_SHIFT U(11)
|
||||
#define PMCR_N_MASK U(0x1f)
|
||||
#define PMCR_N_BITS (PMCR_N_MASK << PMCR_N_SHIFT)
|
||||
#define PMCR_LP_BIT (U(1) << 7)
|
||||
#define PMCR_LC_BIT (U(1) << 6)
|
||||
#define PMCR_DP_BIT (U(1) << 5)
|
||||
#define PMCR_RESET_VAL U(0x0)
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions of register offsets, fields and macros for CPU system
|
||||
* instructions.
|
||||
******************************************************************************/
|
||||
|
||||
#define TLBI_ADDR_SHIFT U(0)
|
||||
#define TLBI_ADDR_MASK U(0xFFFFF000)
|
||||
#define TLBI_ADDR(x) (((x) >> TLBI_ADDR_SHIFT) & TLBI_ADDR_MASK)
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions of register offsets and fields in the CNTCTLBase Frame of the
|
||||
* system level implementation of the Generic Timer.
|
||||
******************************************************************************/
|
||||
#define CNTCTLBASE_CNTFRQ U(0x0)
|
||||
#define CNTNSAR U(0x4)
|
||||
#define CNTNSAR_NS_SHIFT(x) (x)
|
||||
|
||||
#define CNTACR_BASE(x) (U(0x40) + ((x) << 2))
|
||||
#define CNTACR_RPCT_SHIFT U(0x0)
|
||||
#define CNTACR_RVCT_SHIFT U(0x1)
|
||||
#define CNTACR_RFRQ_SHIFT U(0x2)
|
||||
#define CNTACR_RVOFF_SHIFT U(0x3)
|
||||
#define CNTACR_RWVT_SHIFT U(0x4)
|
||||
#define CNTACR_RWPT_SHIFT U(0x5)
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions of register offsets and fields in the CNTBaseN Frame of the
|
||||
* system level implementation of the Generic Timer.
|
||||
******************************************************************************/
|
||||
/* Physical Count register. */
|
||||
#define CNTPCT_LO U(0x0)
|
||||
/* Counter Frequency register. */
|
||||
#define CNTBASEN_CNTFRQ U(0x10)
|
||||
/* Physical Timer CompareValue register. */
|
||||
#define CNTP_CVAL_LO U(0x20)
|
||||
/* Physical Timer Control register. */
|
||||
#define CNTP_CTL U(0x2c)
|
||||
|
||||
/* Physical timer control register bit fields shifts and masks */
|
||||
#define CNTP_CTL_ENABLE_SHIFT 0
|
||||
#define CNTP_CTL_IMASK_SHIFT 1
|
||||
#define CNTP_CTL_ISTATUS_SHIFT 2
|
||||
|
||||
#define CNTP_CTL_ENABLE_MASK U(1)
|
||||
#define CNTP_CTL_IMASK_MASK U(1)
|
||||
#define CNTP_CTL_ISTATUS_MASK U(1)
|
||||
|
||||
/* MAIR macros */
|
||||
#define MAIR0_ATTR_SET(attr, index) ((attr) << ((index) << U(3)))
|
||||
#define MAIR1_ATTR_SET(attr, index) ((attr) << (((index) - U(3)) << U(3)))
|
||||
|
||||
/* System register defines The format is: coproc, opt1, CRn, CRm, opt2 */
|
||||
#define SCR p15, 0, c1, c1, 0
|
||||
#define SCTLR p15, 0, c1, c0, 0
|
||||
#define ACTLR p15, 0, c1, c0, 1
|
||||
#define SDCR p15, 0, c1, c3, 1
|
||||
#define MPIDR p15, 0, c0, c0, 5
|
||||
#define MIDR p15, 0, c0, c0, 0
|
||||
#define HVBAR p15, 4, c12, c0, 0
|
||||
#define VBAR p15, 0, c12, c0, 0
|
||||
#define MVBAR p15, 0, c12, c0, 1
|
||||
#define NSACR p15, 0, c1, c1, 2
|
||||
#define CPACR p15, 0, c1, c0, 2
|
||||
#define DCCIMVAC p15, 0, c7, c14, 1
|
||||
#define DCCMVAC p15, 0, c7, c10, 1
|
||||
#define DCIMVAC p15, 0, c7, c6, 1
|
||||
#define DCCISW p15, 0, c7, c14, 2
|
||||
#define DCCSW p15, 0, c7, c10, 2
|
||||
#define DCISW p15, 0, c7, c6, 2
|
||||
#define CTR p15, 0, c0, c0, 1
|
||||
#define CNTFRQ p15, 0, c14, c0, 0
|
||||
#define ID_MMFR4 p15, 0, c0, c2, 6
|
||||
#define ID_DFR0 p15, 0, c0, c1, 2
|
||||
#define ID_DFR1 p15, 0, c0, c3, 5
|
||||
#define ID_PFR0 p15, 0, c0, c1, 0
|
||||
#define ID_PFR1 p15, 0, c0, c1, 1
|
||||
#define MAIR0 p15, 0, c10, c2, 0
|
||||
#define MAIR1 p15, 0, c10, c2, 1
|
||||
#define TTBCR p15, 0, c2, c0, 2
|
||||
#define TTBR0 p15, 0, c2, c0, 0
|
||||
#define TTBR1 p15, 0, c2, c0, 1
|
||||
#define TLBIALL p15, 0, c8, c7, 0
|
||||
#define TLBIALLH p15, 4, c8, c7, 0
|
||||
#define TLBIALLIS p15, 0, c8, c3, 0
|
||||
#define TLBIMVA p15, 0, c8, c7, 1
|
||||
#define TLBIMVAA p15, 0, c8, c7, 3
|
||||
#define TLBIMVAAIS p15, 0, c8, c3, 3
|
||||
#define TLBIMVAHIS p15, 4, c8, c3, 1
|
||||
#define BPIALLIS p15, 0, c7, c1, 6
|
||||
#define BPIALL p15, 0, c7, c5, 6
|
||||
#define ICIALLU p15, 0, c7, c5, 0
|
||||
#define HSCTLR p15, 4, c1, c0, 0
|
||||
#define HCR p15, 4, c1, c1, 0
|
||||
#define HCPTR p15, 4, c1, c1, 2
|
||||
#define HSTR p15, 4, c1, c1, 3
|
||||
#define CNTHCTL p15, 4, c14, c1, 0
|
||||
#define CNTKCTL p15, 0, c14, c1, 0
|
||||
#define VPIDR p15, 4, c0, c0, 0
|
||||
#define VMPIDR p15, 4, c0, c0, 5
|
||||
#define ISR p15, 0, c12, c1, 0
|
||||
#define CLIDR p15, 1, c0, c0, 1
|
||||
#define CSSELR p15, 2, c0, c0, 0
|
||||
#define CCSIDR p15, 1, c0, c0, 0
|
||||
#define CCSIDR2 p15, 1, c0, c0, 2
|
||||
#define HTCR p15, 4, c2, c0, 2
|
||||
#define HMAIR0 p15, 4, c10, c2, 0
|
||||
#define ATS1CPR p15, 0, c7, c8, 0
|
||||
#define ATS1HR p15, 4, c7, c8, 0
|
||||
#define DBGOSDLR p14, 0, c1, c3, 4
|
||||
|
||||
/* Debug register defines. The format is: coproc, opt1, CRn, CRm, opt2 */
|
||||
#define HDCR p15, 4, c1, c1, 1
|
||||
#define PMCR p15, 0, c9, c12, 0
|
||||
#define CNTHP_TVAL p15, 4, c14, c2, 0
|
||||
#define CNTHP_CTL p15, 4, c14, c2, 1
|
||||
|
||||
/* AArch32 coproc registers for 32bit MMU descriptor support */
|
||||
#define PRRR p15, 0, c10, c2, 0
|
||||
#define NMRR p15, 0, c10, c2, 1
|
||||
#define DACR p15, 0, c3, c0, 0
|
||||
|
||||
/* GICv3 CPU Interface system register defines. The format is: coproc, opt1, CRn, CRm, opt2 */
|
||||
#define ICC_IAR1 p15, 0, c12, c12, 0
|
||||
#define ICC_IAR0 p15, 0, c12, c8, 0
|
||||
#define ICC_EOIR1 p15, 0, c12, c12, 1
|
||||
#define ICC_EOIR0 p15, 0, c12, c8, 1
|
||||
#define ICC_HPPIR1 p15, 0, c12, c12, 2
|
||||
#define ICC_HPPIR0 p15, 0, c12, c8, 2
|
||||
#define ICC_BPR1 p15, 0, c12, c12, 3
|
||||
#define ICC_BPR0 p15, 0, c12, c8, 3
|
||||
#define ICC_DIR p15, 0, c12, c11, 1
|
||||
#define ICC_PMR p15, 0, c4, c6, 0
|
||||
#define ICC_RPR p15, 0, c12, c11, 3
|
||||
#define ICC_CTLR p15, 0, c12, c12, 4
|
||||
#define ICC_MCTLR p15, 6, c12, c12, 4
|
||||
#define ICC_SRE p15, 0, c12, c12, 5
|
||||
#define ICC_HSRE p15, 4, c12, c9, 5
|
||||
#define ICC_MSRE p15, 6, c12, c12, 5
|
||||
#define ICC_IGRPEN0 p15, 0, c12, c12, 6
|
||||
#define ICC_IGRPEN1 p15, 0, c12, c12, 7
|
||||
#define ICC_MGRPEN1 p15, 6, c12, c12, 7
|
||||
|
||||
/* 64 bit system register defines The format is: coproc, opt1, CRm */
|
||||
#define TTBR0_64 p15, 0, c2
|
||||
#define TTBR1_64 p15, 1, c2
|
||||
#define CNTVOFF_64 p15, 4, c14
|
||||
#define VTTBR_64 p15, 6, c2
|
||||
#define CNTPCT_64 p15, 0, c14
|
||||
#define HTTBR_64 p15, 4, c2
|
||||
#define CNTHP_CVAL_64 p15, 6, c14
|
||||
#define PAR_64 p15, 0, c7
|
||||
|
||||
/* 64 bit GICv3 CPU Interface system register defines. The format is: coproc, opt1, CRm */
|
||||
#define ICC_SGI1R_EL1_64 p15, 0, c12
|
||||
#define ICC_ASGI1R_EL1_64 p15, 1, c12
|
||||
#define ICC_SGI0R_EL1_64 p15, 2, c12
|
||||
|
||||
/* Fault registers. The format is: coproc, opt1, CRn, CRm, opt2 */
|
||||
#define DFSR p15, 0, c5, c0, 0
|
||||
#define IFSR p15, 0, c5, c0, 1
|
||||
#define DFAR p15, 0, c6, c0, 0
|
||||
#define IFAR p15, 0, c6, c0, 2
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions of MAIR encodings for device and normal memory
|
||||
******************************************************************************/
|
||||
/*
|
||||
* MAIR encodings for device memory attributes.
|
||||
*/
|
||||
#define MAIR_DEV_nGnRnE U(0x0)
|
||||
#define MAIR_DEV_nGnRE U(0x4)
|
||||
#define MAIR_DEV_nGRE U(0x8)
|
||||
#define MAIR_DEV_GRE U(0xc)
|
||||
|
||||
/*
|
||||
* MAIR encodings for normal memory attributes.
|
||||
*
|
||||
* Cache Policy
|
||||
* WT: Write Through
|
||||
* WB: Write Back
|
||||
* NC: Non-Cacheable
|
||||
*
|
||||
* Transient Hint
|
||||
* NTR: Non-Transient
|
||||
* TR: Transient
|
||||
*
|
||||
* Allocation Policy
|
||||
* RA: Read Allocate
|
||||
* WA: Write Allocate
|
||||
* RWA: Read and Write Allocate
|
||||
* NA: No Allocation
|
||||
*/
|
||||
#define MAIR_NORM_WT_TR_WA U(0x1)
|
||||
#define MAIR_NORM_WT_TR_RA U(0x2)
|
||||
#define MAIR_NORM_WT_TR_RWA U(0x3)
|
||||
#define MAIR_NORM_NC U(0x4)
|
||||
#define MAIR_NORM_WB_TR_WA U(0x5)
|
||||
#define MAIR_NORM_WB_TR_RA U(0x6)
|
||||
#define MAIR_NORM_WB_TR_RWA U(0x7)
|
||||
#define MAIR_NORM_WT_NTR_NA U(0x8)
|
||||
#define MAIR_NORM_WT_NTR_WA U(0x9)
|
||||
#define MAIR_NORM_WT_NTR_RA U(0xa)
|
||||
#define MAIR_NORM_WT_NTR_RWA U(0xb)
|
||||
#define MAIR_NORM_WB_NTR_NA U(0xc)
|
||||
#define MAIR_NORM_WB_NTR_WA U(0xd)
|
||||
#define MAIR_NORM_WB_NTR_RA U(0xe)
|
||||
#define MAIR_NORM_WB_NTR_RWA U(0xf)
|
||||
|
||||
#define MAIR_NORM_OUTER_SHIFT U(4)
|
||||
|
||||
#define MAKE_MAIR_NORMAL_MEMORY(inner, outer) \
|
||||
((inner) | ((outer) << MAIR_NORM_OUTER_SHIFT))
|
||||
|
||||
/* PAR fields */
|
||||
#define PAR_F_SHIFT U(0)
|
||||
#define PAR_F_MASK ULL(0x1)
|
||||
#define PAR_ADDR_SHIFT U(12)
|
||||
#define PAR_ADDR_MASK (BIT_64(40) - ULL(1)) /* 40-bits-wide page address */
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions for system register interface to AMU for FEAT_AMUv1
|
||||
******************************************************************************/
|
||||
#define AMCR p15, 0, c13, c2, 0
|
||||
#define AMCFGR p15, 0, c13, c2, 1
|
||||
#define AMCGCR p15, 0, c13, c2, 2
|
||||
#define AMUSERENR p15, 0, c13, c2, 3
|
||||
#define AMCNTENCLR0 p15, 0, c13, c2, 4
|
||||
#define AMCNTENSET0 p15, 0, c13, c2, 5
|
||||
#define AMCNTENCLR1 p15, 0, c13, c3, 0
|
||||
#define AMCNTENSET1 p15, 0, c13, c3, 1
|
||||
|
||||
/* Activity Monitor Group 0 Event Counter Registers */
|
||||
#define AMEVCNTR00 p15, 0, c0
|
||||
#define AMEVCNTR01 p15, 1, c0
|
||||
#define AMEVCNTR02 p15, 2, c0
|
||||
#define AMEVCNTR03 p15, 3, c0
|
||||
|
||||
/* Activity Monitor Group 0 Event Type Registers */
|
||||
#define AMEVTYPER00 p15, 0, c13, c6, 0
|
||||
#define AMEVTYPER01 p15, 0, c13, c6, 1
|
||||
#define AMEVTYPER02 p15, 0, c13, c6, 2
|
||||
#define AMEVTYPER03 p15, 0, c13, c6, 3
|
||||
|
||||
/* Activity Monitor Group 1 Event Counter Registers */
|
||||
#define AMEVCNTR10 p15, 0, c4
|
||||
#define AMEVCNTR11 p15, 1, c4
|
||||
#define AMEVCNTR12 p15, 2, c4
|
||||
#define AMEVCNTR13 p15, 3, c4
|
||||
#define AMEVCNTR14 p15, 4, c4
|
||||
#define AMEVCNTR15 p15, 5, c4
|
||||
#define AMEVCNTR16 p15, 6, c4
|
||||
#define AMEVCNTR17 p15, 7, c4
|
||||
#define AMEVCNTR18 p15, 0, c5
|
||||
#define AMEVCNTR19 p15, 1, c5
|
||||
#define AMEVCNTR1A p15, 2, c5
|
||||
#define AMEVCNTR1B p15, 3, c5
|
||||
#define AMEVCNTR1C p15, 4, c5
|
||||
#define AMEVCNTR1D p15, 5, c5
|
||||
#define AMEVCNTR1E p15, 6, c5
|
||||
#define AMEVCNTR1F p15, 7, c5
|
||||
|
||||
/* Activity Monitor Group 1 Event Type Registers */
|
||||
#define AMEVTYPER10 p15, 0, c13, c14, 0
|
||||
#define AMEVTYPER11 p15, 0, c13, c14, 1
|
||||
#define AMEVTYPER12 p15, 0, c13, c14, 2
|
||||
#define AMEVTYPER13 p15, 0, c13, c14, 3
|
||||
#define AMEVTYPER14 p15, 0, c13, c14, 4
|
||||
#define AMEVTYPER15 p15, 0, c13, c14, 5
|
||||
#define AMEVTYPER16 p15, 0, c13, c14, 6
|
||||
#define AMEVTYPER17 p15, 0, c13, c14, 7
|
||||
#define AMEVTYPER18 p15, 0, c13, c15, 0
|
||||
#define AMEVTYPER19 p15, 0, c13, c15, 1
|
||||
#define AMEVTYPER1A p15, 0, c13, c15, 2
|
||||
#define AMEVTYPER1B p15, 0, c13, c15, 3
|
||||
#define AMEVTYPER1C p15, 0, c13, c15, 4
|
||||
#define AMEVTYPER1D p15, 0, c13, c15, 5
|
||||
#define AMEVTYPER1E p15, 0, c13, c15, 6
|
||||
#define AMEVTYPER1F p15, 0, c13, c15, 7
|
||||
|
||||
/* AMCNTENSET0 definitions */
|
||||
#define AMCNTENSET0_Pn_SHIFT U(0)
|
||||
#define AMCNTENSET0_Pn_MASK U(0xffff)
|
||||
|
||||
/* AMCNTENSET1 definitions */
|
||||
#define AMCNTENSET1_Pn_SHIFT U(0)
|
||||
#define AMCNTENSET1_Pn_MASK U(0xffff)
|
||||
|
||||
/* AMCNTENCLR0 definitions */
|
||||
#define AMCNTENCLR0_Pn_SHIFT U(0)
|
||||
#define AMCNTENCLR0_Pn_MASK U(0xffff)
|
||||
|
||||
/* AMCNTENCLR1 definitions */
|
||||
#define AMCNTENCLR1_Pn_SHIFT U(0)
|
||||
#define AMCNTENCLR1_Pn_MASK U(0xffff)
|
||||
|
||||
/* AMCR definitions */
|
||||
#define AMCR_CG1RZ_SHIFT U(17)
|
||||
#define AMCR_CG1RZ_BIT (ULL(1) << AMCR_CG1RZ_SHIFT)
|
||||
|
||||
/* AMCFGR definitions */
|
||||
#define AMCFGR_NCG_SHIFT U(28)
|
||||
#define AMCFGR_NCG_MASK U(0xf)
|
||||
#define AMCFGR_N_SHIFT U(0)
|
||||
#define AMCFGR_N_MASK U(0xff)
|
||||
|
||||
/* AMCGCR definitions */
|
||||
#define AMCGCR_CG0NC_SHIFT U(0)
|
||||
#define AMCGCR_CG0NC_MASK U(0xff)
|
||||
#define AMCGCR_CG1NC_SHIFT U(8)
|
||||
#define AMCGCR_CG1NC_MASK U(0xff)
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions for DynamicIQ Shared Unit registers
|
||||
******************************************************************************/
|
||||
#define CLUSTERPWRDN p15, 0, c15, c3, 6
|
||||
|
||||
/* CLUSTERPWRDN register definitions */
|
||||
#define DSU_CLUSTER_PWR_OFF 0
|
||||
#define DSU_CLUSTER_PWR_ON 1
|
||||
#define DSU_CLUSTER_PWR_MASK U(1)
|
||||
|
||||
#endif /* ARCH_H */
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Arm Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef ARCH_FEATURES_H
|
||||
#define ARCH_FEATURES_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <arch_helpers.h>
|
||||
|
||||
static inline bool is_armv7_gentimer_present(void)
|
||||
{
|
||||
return ((read_id_pfr1() >> ID_PFR1_GENTIMER_SHIFT) &
|
||||
ID_PFR1_GENTIMER_MASK) != 0U;
|
||||
}
|
||||
|
||||
static inline bool is_armv8_2_ttcnp_present(void)
|
||||
{
|
||||
return ((read_id_mmfr4() >> ID_MMFR4_CNP_SHIFT) &
|
||||
ID_MMFR4_CNP_MASK) != 0U;
|
||||
}
|
||||
|
||||
#endif /* ARCH_FEATURES_H */
|
||||
@@ -0,0 +1,474 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2021, ARM Limited and Contributors. All rights reserved.
|
||||
* Portions copyright (c) 2021-2022, ProvenRun S.A.S. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef ARCH_HELPERS_H
|
||||
#define ARCH_HELPERS_H
|
||||
|
||||
#include <cdefs.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <arch.h>
|
||||
|
||||
/**********************************************************************
|
||||
* Macros which create inline functions to read or write CPU system
|
||||
* registers
|
||||
*********************************************************************/
|
||||
|
||||
#define _DEFINE_COPROCR_WRITE_FUNC(_name, coproc, opc1, CRn, CRm, opc2) \
|
||||
static inline void write_## _name(u_register_t v) \
|
||||
{ \
|
||||
__asm__ volatile ("mcr "#coproc","#opc1",%0,"#CRn","#CRm","#opc2 : : "r" (v));\
|
||||
}
|
||||
|
||||
#define _DEFINE_COPROCR_READ_FUNC(_name, coproc, opc1, CRn, CRm, opc2) \
|
||||
static inline u_register_t read_ ## _name(void) \
|
||||
{ \
|
||||
u_register_t v; \
|
||||
__asm__ volatile ("mrc "#coproc","#opc1",%0,"#CRn","#CRm","#opc2 : "=r" (v));\
|
||||
return v; \
|
||||
}
|
||||
|
||||
/*
|
||||
* The undocumented %Q and %R extended asm are used to implemented the below
|
||||
* 64 bit `mrrc` and `mcrr` instructions.
|
||||
*/
|
||||
|
||||
#define _DEFINE_COPROCR_WRITE_FUNC_64(_name, coproc, opc1, CRm) \
|
||||
static inline void write64_## _name(uint64_t v) \
|
||||
{ \
|
||||
__asm__ volatile ("mcrr "#coproc","#opc1", %Q0, %R0,"#CRm : : "r" (v));\
|
||||
}
|
||||
|
||||
#define _DEFINE_COPROCR_READ_FUNC_64(_name, coproc, opc1, CRm) \
|
||||
static inline uint64_t read64_## _name(void) \
|
||||
{ uint64_t v; \
|
||||
__asm__ volatile ("mrrc "#coproc","#opc1", %Q0, %R0,"#CRm : "=r" (v));\
|
||||
return v; \
|
||||
}
|
||||
|
||||
#define _DEFINE_SYSREG_READ_FUNC(_name, _reg_name) \
|
||||
static inline u_register_t read_ ## _name(void) \
|
||||
{ \
|
||||
u_register_t v; \
|
||||
__asm__ volatile ("mrs %0, " #_reg_name : "=r" (v)); \
|
||||
return v; \
|
||||
}
|
||||
|
||||
#define _DEFINE_SYSREG_WRITE_FUNC(_name, _reg_name) \
|
||||
static inline void write_ ## _name(u_register_t v) \
|
||||
{ \
|
||||
__asm__ volatile ("msr " #_reg_name ", %0" : : "r" (v)); \
|
||||
}
|
||||
|
||||
#define _DEFINE_SYSREG_WRITE_CONST_FUNC(_name, _reg_name) \
|
||||
static inline void write_ ## _name(const u_register_t v) \
|
||||
{ \
|
||||
__asm__ volatile ("msr " #_reg_name ", %0" : : "i" (v)); \
|
||||
}
|
||||
|
||||
/* Define read function for coproc register */
|
||||
#define DEFINE_COPROCR_READ_FUNC(_name, ...) \
|
||||
_DEFINE_COPROCR_READ_FUNC(_name, __VA_ARGS__)
|
||||
|
||||
/* Define write function for coproc register */
|
||||
#define DEFINE_COPROCR_WRITE_FUNC(_name, ...) \
|
||||
_DEFINE_COPROCR_WRITE_FUNC(_name, __VA_ARGS__)
|
||||
|
||||
/* Define read & write function for coproc register */
|
||||
#define DEFINE_COPROCR_RW_FUNCS(_name, ...) \
|
||||
_DEFINE_COPROCR_READ_FUNC(_name, __VA_ARGS__) \
|
||||
_DEFINE_COPROCR_WRITE_FUNC(_name, __VA_ARGS__)
|
||||
|
||||
/* Define 64 bit read function for coproc register */
|
||||
#define DEFINE_COPROCR_READ_FUNC_64(_name, ...) \
|
||||
_DEFINE_COPROCR_READ_FUNC_64(_name, __VA_ARGS__)
|
||||
|
||||
/* Define 64 bit write function for coproc register */
|
||||
#define DEFINE_COPROCR_WRITE_FUNC_64(_name, ...) \
|
||||
_DEFINE_COPROCR_WRITE_FUNC_64(_name, __VA_ARGS__)
|
||||
|
||||
/* Define 64 bit read & write function for coproc register */
|
||||
#define DEFINE_COPROCR_RW_FUNCS_64(_name, ...) \
|
||||
_DEFINE_COPROCR_READ_FUNC_64(_name, __VA_ARGS__) \
|
||||
_DEFINE_COPROCR_WRITE_FUNC_64(_name, __VA_ARGS__)
|
||||
|
||||
/* Define read & write function for system register */
|
||||
#define DEFINE_SYSREG_RW_FUNCS(_name) \
|
||||
_DEFINE_SYSREG_READ_FUNC(_name, _name) \
|
||||
_DEFINE_SYSREG_WRITE_FUNC(_name, _name)
|
||||
|
||||
/**********************************************************************
|
||||
* Macros to create inline functions for tlbi operations
|
||||
*********************************************************************/
|
||||
|
||||
#define _DEFINE_TLBIOP_FUNC(_op, coproc, opc1, CRn, CRm, opc2) \
|
||||
static inline void tlbi##_op(void) \
|
||||
{ \
|
||||
u_register_t v = 0; \
|
||||
__asm__ volatile ("mcr "#coproc","#opc1",%0,"#CRn","#CRm","#opc2 : : "r" (v));\
|
||||
}
|
||||
|
||||
#define _DEFINE_BPIOP_FUNC(_op, coproc, opc1, CRn, CRm, opc2) \
|
||||
static inline void bpi##_op(void) \
|
||||
{ \
|
||||
u_register_t v = 0; \
|
||||
__asm__ volatile ("mcr "#coproc","#opc1",%0,"#CRn","#CRm","#opc2 : : "r" (v));\
|
||||
}
|
||||
|
||||
#define _DEFINE_TLBIOP_PARAM_FUNC(_op, coproc, opc1, CRn, CRm, opc2) \
|
||||
static inline void tlbi##_op(u_register_t v) \
|
||||
{ \
|
||||
__asm__ volatile ("mcr "#coproc","#opc1",%0,"#CRn","#CRm","#opc2 : : "r" (v));\
|
||||
}
|
||||
|
||||
/* Define function for simple TLBI operation */
|
||||
#define DEFINE_TLBIOP_FUNC(_op, ...) \
|
||||
_DEFINE_TLBIOP_FUNC(_op, __VA_ARGS__)
|
||||
|
||||
/* Define function for TLBI operation with register parameter */
|
||||
#define DEFINE_TLBIOP_PARAM_FUNC(_op, ...) \
|
||||
_DEFINE_TLBIOP_PARAM_FUNC(_op, __VA_ARGS__)
|
||||
|
||||
/* Define function for simple BPI operation */
|
||||
#define DEFINE_BPIOP_FUNC(_op, ...) \
|
||||
_DEFINE_BPIOP_FUNC(_op, __VA_ARGS__)
|
||||
|
||||
/**********************************************************************
|
||||
* Macros to create inline functions for DC operations
|
||||
*********************************************************************/
|
||||
#define _DEFINE_DCOP_PARAM_FUNC(_op, coproc, opc1, CRn, CRm, opc2) \
|
||||
static inline void dc##_op(u_register_t v) \
|
||||
{ \
|
||||
__asm__ volatile ("mcr "#coproc","#opc1",%0,"#CRn","#CRm","#opc2 : : "r" (v));\
|
||||
}
|
||||
|
||||
/* Define function for DC operation with register parameter */
|
||||
#define DEFINE_DCOP_PARAM_FUNC(_op, ...) \
|
||||
_DEFINE_DCOP_PARAM_FUNC(_op, __VA_ARGS__)
|
||||
|
||||
/**********************************************************************
|
||||
* Macros to create inline functions for system instructions
|
||||
*********************************************************************/
|
||||
/* Define function for simple system instruction */
|
||||
#define DEFINE_SYSOP_FUNC(_op) \
|
||||
static inline void _op(void) \
|
||||
{ \
|
||||
__asm__ (#_op); \
|
||||
}
|
||||
|
||||
|
||||
/* Define function for system instruction with type specifier */
|
||||
#define DEFINE_SYSOP_TYPE_FUNC(_op, _type) \
|
||||
static inline void _op ## _type(void) \
|
||||
{ \
|
||||
__asm__ (#_op " " #_type : : : "memory"); \
|
||||
}
|
||||
|
||||
/* Define function for system instruction with register parameter */
|
||||
#define DEFINE_SYSOP_TYPE_PARAM_FUNC(_op, _type) \
|
||||
static inline void _op ## _type(u_register_t v) \
|
||||
{ \
|
||||
__asm__ (#_op " " #_type ", %0" : : "r" (v)); \
|
||||
}
|
||||
|
||||
void flush_dcache_range(uintptr_t addr, size_t size);
|
||||
void clean_dcache_range(uintptr_t addr, size_t size);
|
||||
void inv_dcache_range(uintptr_t addr, size_t size);
|
||||
bool is_dcache_enabled(void);
|
||||
|
||||
void dcsw_op_louis(u_register_t op_type);
|
||||
void dcsw_op_all(u_register_t op_type);
|
||||
|
||||
void disable_mmu_secure(void);
|
||||
void disable_mmu_icache_secure(void);
|
||||
|
||||
DEFINE_SYSOP_FUNC(wfi)
|
||||
DEFINE_SYSOP_FUNC(wfe)
|
||||
DEFINE_SYSOP_FUNC(sev)
|
||||
DEFINE_SYSOP_TYPE_FUNC(dsb, sy)
|
||||
DEFINE_SYSOP_TYPE_FUNC(dmb, sy)
|
||||
DEFINE_SYSOP_TYPE_FUNC(dmb, st)
|
||||
|
||||
/* dmb ld is not valid for armv7/thumb machines */
|
||||
#if ARM_ARCH_MAJOR != 7
|
||||
DEFINE_SYSOP_TYPE_FUNC(dmb, ld)
|
||||
#endif
|
||||
|
||||
DEFINE_SYSOP_TYPE_FUNC(dsb, ish)
|
||||
DEFINE_SYSOP_TYPE_FUNC(dsb, ishst)
|
||||
DEFINE_SYSOP_TYPE_FUNC(dmb, ish)
|
||||
DEFINE_SYSOP_TYPE_FUNC(dmb, ishst)
|
||||
DEFINE_SYSOP_FUNC(isb)
|
||||
|
||||
void __dead2 smc(uint32_t r0, uint32_t r1, uint32_t r2, uint32_t r3,
|
||||
uint32_t r4, uint32_t r5, uint32_t r6, uint32_t r7);
|
||||
|
||||
DEFINE_SYSREG_RW_FUNCS(spsr)
|
||||
DEFINE_SYSREG_RW_FUNCS(cpsr)
|
||||
|
||||
/*******************************************************************************
|
||||
* System register accessor prototypes
|
||||
******************************************************************************/
|
||||
DEFINE_COPROCR_READ_FUNC(mpidr, MPIDR)
|
||||
DEFINE_COPROCR_READ_FUNC(midr, MIDR)
|
||||
DEFINE_COPROCR_READ_FUNC(id_mmfr4, ID_MMFR4)
|
||||
DEFINE_COPROCR_READ_FUNC(id_dfr0, ID_DFR0)
|
||||
DEFINE_COPROCR_READ_FUNC(id_pfr0, ID_PFR0)
|
||||
DEFINE_COPROCR_READ_FUNC(id_pfr1, ID_PFR1)
|
||||
DEFINE_COPROCR_READ_FUNC(isr, ISR)
|
||||
DEFINE_COPROCR_READ_FUNC(clidr, CLIDR)
|
||||
DEFINE_COPROCR_READ_FUNC_64(cntpct, CNTPCT_64)
|
||||
|
||||
DEFINE_COPROCR_RW_FUNCS(scr, SCR)
|
||||
DEFINE_COPROCR_RW_FUNCS(ctr, CTR)
|
||||
DEFINE_COPROCR_RW_FUNCS(sctlr, SCTLR)
|
||||
DEFINE_COPROCR_RW_FUNCS(actlr, ACTLR)
|
||||
DEFINE_COPROCR_RW_FUNCS(hsctlr, HSCTLR)
|
||||
DEFINE_COPROCR_RW_FUNCS(hcr, HCR)
|
||||
DEFINE_COPROCR_RW_FUNCS(hcptr, HCPTR)
|
||||
DEFINE_COPROCR_RW_FUNCS(cntfrq, CNTFRQ)
|
||||
DEFINE_COPROCR_RW_FUNCS(cnthctl, CNTHCTL)
|
||||
DEFINE_COPROCR_RW_FUNCS(mair0, MAIR0)
|
||||
DEFINE_COPROCR_RW_FUNCS(mair1, MAIR1)
|
||||
DEFINE_COPROCR_RW_FUNCS(hmair0, HMAIR0)
|
||||
DEFINE_COPROCR_RW_FUNCS(ttbcr, TTBCR)
|
||||
DEFINE_COPROCR_RW_FUNCS(htcr, HTCR)
|
||||
DEFINE_COPROCR_RW_FUNCS(ttbr0, TTBR0)
|
||||
DEFINE_COPROCR_RW_FUNCS_64(ttbr0, TTBR0_64)
|
||||
DEFINE_COPROCR_RW_FUNCS(ttbr1, TTBR1)
|
||||
DEFINE_COPROCR_RW_FUNCS_64(httbr, HTTBR_64)
|
||||
DEFINE_COPROCR_RW_FUNCS(vpidr, VPIDR)
|
||||
DEFINE_COPROCR_RW_FUNCS(vmpidr, VMPIDR)
|
||||
DEFINE_COPROCR_RW_FUNCS_64(vttbr, VTTBR_64)
|
||||
DEFINE_COPROCR_RW_FUNCS_64(ttbr1, TTBR1_64)
|
||||
DEFINE_COPROCR_RW_FUNCS_64(cntvoff, CNTVOFF_64)
|
||||
DEFINE_COPROCR_RW_FUNCS(csselr, CSSELR)
|
||||
DEFINE_COPROCR_RW_FUNCS(hstr, HSTR)
|
||||
DEFINE_COPROCR_RW_FUNCS(cnthp_ctl_el2, CNTHP_CTL)
|
||||
DEFINE_COPROCR_RW_FUNCS(cnthp_tval_el2, CNTHP_TVAL)
|
||||
DEFINE_COPROCR_RW_FUNCS_64(cnthp_cval_el2, CNTHP_CVAL_64)
|
||||
|
||||
#define get_cntp_ctl_enable(x) (((x) >> CNTP_CTL_ENABLE_SHIFT) & \
|
||||
CNTP_CTL_ENABLE_MASK)
|
||||
#define get_cntp_ctl_imask(x) (((x) >> CNTP_CTL_IMASK_SHIFT) & \
|
||||
CNTP_CTL_IMASK_MASK)
|
||||
#define get_cntp_ctl_istatus(x) (((x) >> CNTP_CTL_ISTATUS_SHIFT) & \
|
||||
CNTP_CTL_ISTATUS_MASK)
|
||||
|
||||
#define set_cntp_ctl_enable(x) ((x) |= U(1) << CNTP_CTL_ENABLE_SHIFT)
|
||||
#define set_cntp_ctl_imask(x) ((x) |= U(1) << CNTP_CTL_IMASK_SHIFT)
|
||||
|
||||
#define clr_cntp_ctl_enable(x) ((x) &= ~(U(1) << CNTP_CTL_ENABLE_SHIFT))
|
||||
#define clr_cntp_ctl_imask(x) ((x) &= ~(U(1) << CNTP_CTL_IMASK_SHIFT))
|
||||
|
||||
DEFINE_COPROCR_RW_FUNCS(icc_sre_el1, ICC_SRE)
|
||||
DEFINE_COPROCR_RW_FUNCS(icc_sre_el2, ICC_HSRE)
|
||||
DEFINE_COPROCR_RW_FUNCS(icc_sre_el3, ICC_MSRE)
|
||||
DEFINE_COPROCR_RW_FUNCS(icc_pmr_el1, ICC_PMR)
|
||||
DEFINE_COPROCR_RW_FUNCS(icc_rpr_el1, ICC_RPR)
|
||||
DEFINE_COPROCR_RW_FUNCS(icc_igrpen1_el3, ICC_MGRPEN1)
|
||||
DEFINE_COPROCR_RW_FUNCS(icc_igrpen1_el1, ICC_IGRPEN1)
|
||||
DEFINE_COPROCR_RW_FUNCS(icc_igrpen0_el1, ICC_IGRPEN0)
|
||||
DEFINE_COPROCR_RW_FUNCS(icc_hppir0_el1, ICC_HPPIR0)
|
||||
DEFINE_COPROCR_RW_FUNCS(icc_hppir1_el1, ICC_HPPIR1)
|
||||
DEFINE_COPROCR_RW_FUNCS(icc_iar0_el1, ICC_IAR0)
|
||||
DEFINE_COPROCR_RW_FUNCS(icc_iar1_el1, ICC_IAR1)
|
||||
DEFINE_COPROCR_RW_FUNCS(icc_eoir0_el1, ICC_EOIR0)
|
||||
DEFINE_COPROCR_RW_FUNCS(icc_eoir1_el1, ICC_EOIR1)
|
||||
DEFINE_COPROCR_RW_FUNCS_64(icc_sgi0r_el1, ICC_SGI0R_EL1_64)
|
||||
DEFINE_COPROCR_WRITE_FUNC_64(icc_sgi1r, ICC_SGI1R_EL1_64)
|
||||
DEFINE_COPROCR_WRITE_FUNC_64(icc_asgi1r, ICC_ASGI1R_EL1_64)
|
||||
|
||||
DEFINE_COPROCR_RW_FUNCS(sdcr, SDCR)
|
||||
DEFINE_COPROCR_RW_FUNCS(hdcr, HDCR)
|
||||
DEFINE_COPROCR_RW_FUNCS(cnthp_ctl, CNTHP_CTL)
|
||||
DEFINE_COPROCR_READ_FUNC(pmcr, PMCR)
|
||||
|
||||
/*
|
||||
* Address translation
|
||||
*/
|
||||
DEFINE_COPROCR_WRITE_FUNC(ats1cpr, ATS1CPR)
|
||||
DEFINE_COPROCR_WRITE_FUNC(ats1hr, ATS1HR)
|
||||
DEFINE_COPROCR_RW_FUNCS_64(par, PAR_64)
|
||||
|
||||
DEFINE_COPROCR_RW_FUNCS(nsacr, NSACR)
|
||||
|
||||
/* AArch32 coproc registers for 32bit MMU descriptor support */
|
||||
DEFINE_COPROCR_RW_FUNCS(prrr, PRRR)
|
||||
DEFINE_COPROCR_RW_FUNCS(nmrr, NMRR)
|
||||
DEFINE_COPROCR_RW_FUNCS(dacr, DACR)
|
||||
|
||||
/* Coproc registers for 32bit AMU support */
|
||||
DEFINE_COPROCR_READ_FUNC(amcfgr, AMCFGR)
|
||||
DEFINE_COPROCR_READ_FUNC(amcgcr, AMCGCR)
|
||||
DEFINE_COPROCR_RW_FUNCS(amcr, AMCR)
|
||||
|
||||
DEFINE_COPROCR_RW_FUNCS(amcntenset0, AMCNTENSET0)
|
||||
DEFINE_COPROCR_RW_FUNCS(amcntenset1, AMCNTENSET1)
|
||||
DEFINE_COPROCR_RW_FUNCS(amcntenclr0, AMCNTENCLR0)
|
||||
DEFINE_COPROCR_RW_FUNCS(amcntenclr1, AMCNTENCLR1)
|
||||
|
||||
/* Coproc registers for 64bit AMU support */
|
||||
DEFINE_COPROCR_RW_FUNCS_64(amevcntr00, AMEVCNTR00)
|
||||
DEFINE_COPROCR_RW_FUNCS_64(amevcntr01, AMEVCNTR01)
|
||||
DEFINE_COPROCR_RW_FUNCS_64(amevcntr02, AMEVCNTR02)
|
||||
DEFINE_COPROCR_RW_FUNCS_64(amevcntr03, AMEVCNTR03)
|
||||
|
||||
/*
|
||||
* TLBI operation prototypes
|
||||
*/
|
||||
DEFINE_TLBIOP_FUNC(all, TLBIALL)
|
||||
DEFINE_TLBIOP_FUNC(allis, TLBIALLIS)
|
||||
DEFINE_TLBIOP_PARAM_FUNC(mva, TLBIMVA)
|
||||
DEFINE_TLBIOP_PARAM_FUNC(mvaa, TLBIMVAA)
|
||||
DEFINE_TLBIOP_PARAM_FUNC(mvaais, TLBIMVAAIS)
|
||||
DEFINE_TLBIOP_PARAM_FUNC(mvahis, TLBIMVAHIS)
|
||||
|
||||
/*
|
||||
* BPI operation prototypes.
|
||||
*/
|
||||
DEFINE_BPIOP_FUNC(allis, BPIALLIS)
|
||||
|
||||
/*
|
||||
* DC operation prototypes
|
||||
*/
|
||||
DEFINE_DCOP_PARAM_FUNC(civac, DCCIMVAC)
|
||||
DEFINE_DCOP_PARAM_FUNC(ivac, DCIMVAC)
|
||||
#if ERRATA_A53_819472 || ERRATA_A53_824069 || ERRATA_A53_827319
|
||||
DEFINE_DCOP_PARAM_FUNC(cvac, DCCIMVAC)
|
||||
#else
|
||||
DEFINE_DCOP_PARAM_FUNC(cvac, DCCMVAC)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* DynamIQ Shared Unit power management
|
||||
*/
|
||||
DEFINE_COPROCR_RW_FUNCS(clusterpwrdn, CLUSTERPWRDN)
|
||||
|
||||
/* Previously defined accessor functions with incomplete register names */
|
||||
#define dsb() dsbsy()
|
||||
#define dmb() dmbsy()
|
||||
|
||||
/* dmb ld is not valid for armv7/thumb machines, so alias it to dmb */
|
||||
#if ARM_ARCH_MAJOR == 7
|
||||
#define dmbld() dmb()
|
||||
#endif
|
||||
|
||||
#define IS_IN_SECURE() \
|
||||
(GET_NS_BIT(read_scr()) == 0)
|
||||
|
||||
#define IS_IN_HYP() (GET_M32(read_cpsr()) == MODE32_hyp)
|
||||
#define IS_IN_SVC() (GET_M32(read_cpsr()) == MODE32_svc)
|
||||
#define IS_IN_MON() (GET_M32(read_cpsr()) == MODE32_mon)
|
||||
#define IS_IN_EL2() IS_IN_HYP()
|
||||
/* If EL3 is AArch32, then secure PL1 and monitor mode correspond to EL3 */
|
||||
#define IS_IN_EL3() \
|
||||
((GET_M32(read_cpsr()) == MODE32_mon) || \
|
||||
(IS_IN_SECURE() && (GET_M32(read_cpsr()) != MODE32_usr)))
|
||||
|
||||
static inline unsigned int get_current_el(void)
|
||||
{
|
||||
if (IS_IN_EL3()) {
|
||||
return 3U;
|
||||
} else if (IS_IN_EL2()) {
|
||||
return 2U;
|
||||
} else {
|
||||
return 1U;
|
||||
}
|
||||
}
|
||||
|
||||
/* Macros for compatibility with AArch64 system registers */
|
||||
#define read_mpidr_el1() read_mpidr()
|
||||
|
||||
#define read_scr_el3() read_scr()
|
||||
#define write_scr_el3(_v) write_scr(_v)
|
||||
|
||||
#define read_hcr_el2() read_hcr()
|
||||
#define write_hcr_el2(_v) write_hcr(_v)
|
||||
|
||||
#define read_cpacr_el1() read_cpacr()
|
||||
#define write_cpacr_el1(_v) write_cpacr(_v)
|
||||
|
||||
#define read_cntfrq_el0() read_cntfrq()
|
||||
#define write_cntfrq_el0(_v) write_cntfrq(_v)
|
||||
#define read_isr_el1() read_isr()
|
||||
|
||||
#define read_cntpct_el0() read64_cntpct()
|
||||
|
||||
#define read_ctr_el0() read_ctr()
|
||||
|
||||
#define write_icc_sgi0r_el1(_v) write64_icc_sgi0r_el1(_v)
|
||||
#define write_icc_sgi1r(_v) write64_icc_sgi1r(_v)
|
||||
#define write_icc_asgi1r(_v) write64_icc_asgi1r(_v)
|
||||
|
||||
#define read_daif() read_cpsr()
|
||||
#define write_daif(flags) write_cpsr(flags)
|
||||
|
||||
#define read_cnthp_cval_el2() read64_cnthp_cval_el2()
|
||||
#define write_cnthp_cval_el2(v) write64_cnthp_cval_el2(v)
|
||||
|
||||
#define read_amcntenset0_el0() read_amcntenset0()
|
||||
#define read_amcntenset1_el0() read_amcntenset1()
|
||||
|
||||
/* Helper functions to manipulate CPSR */
|
||||
static inline void enable_irq(void)
|
||||
{
|
||||
/*
|
||||
* The compiler memory barrier will prevent the compiler from
|
||||
* scheduling non-volatile memory access after the write to the
|
||||
* register.
|
||||
*
|
||||
* This could happen if some initialization code issues non-volatile
|
||||
* accesses to an area used by an interrupt handler, in the assumption
|
||||
* that it is safe as the interrupts are disabled at the time it does
|
||||
* that (according to program order). However, non-volatile accesses
|
||||
* are not necessarily in program order relatively with volatile inline
|
||||
* assembly statements (and volatile accesses).
|
||||
*/
|
||||
COMPILER_BARRIER();
|
||||
__asm__ volatile ("cpsie i");
|
||||
isb();
|
||||
}
|
||||
|
||||
static inline void enable_serror(void)
|
||||
{
|
||||
COMPILER_BARRIER();
|
||||
__asm__ volatile ("cpsie a");
|
||||
isb();
|
||||
}
|
||||
|
||||
static inline void enable_fiq(void)
|
||||
{
|
||||
COMPILER_BARRIER();
|
||||
__asm__ volatile ("cpsie f");
|
||||
isb();
|
||||
}
|
||||
|
||||
static inline void disable_irq(void)
|
||||
{
|
||||
COMPILER_BARRIER();
|
||||
__asm__ volatile ("cpsid i");
|
||||
isb();
|
||||
}
|
||||
|
||||
static inline void disable_serror(void)
|
||||
{
|
||||
COMPILER_BARRIER();
|
||||
__asm__ volatile ("cpsid a");
|
||||
isb();
|
||||
}
|
||||
|
||||
static inline void disable_fiq(void)
|
||||
{
|
||||
COMPILER_BARRIER();
|
||||
__asm__ volatile ("cpsid f");
|
||||
isb();
|
||||
}
|
||||
|
||||
#endif /* ARCH_HELPERS_H */
|
||||
@@ -0,0 +1,237 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
#ifndef ASM_MACROS_S
|
||||
#define ASM_MACROS_S
|
||||
|
||||
#include <arch.h>
|
||||
#include <common/asm_macros_common.S>
|
||||
#include <lib/spinlock.h>
|
||||
|
||||
/*
|
||||
* TLBI instruction with type specifier that implements the workaround for
|
||||
* errata 813419 of Cortex-A57.
|
||||
*/
|
||||
#if ERRATA_A57_813419
|
||||
#define TLB_INVALIDATE(_reg, _coproc) \
|
||||
stcopr _reg, _coproc; \
|
||||
dsb ish; \
|
||||
stcopr _reg, _coproc
|
||||
#else
|
||||
#define TLB_INVALIDATE(_reg, _coproc) \
|
||||
stcopr _reg, _coproc
|
||||
#endif
|
||||
|
||||
#define WORD_SIZE 4
|
||||
|
||||
/*
|
||||
* Co processor register accessors
|
||||
*/
|
||||
.macro ldcopr reg, coproc, opc1, CRn, CRm, opc2
|
||||
mrc \coproc, \opc1, \reg, \CRn, \CRm, \opc2
|
||||
.endm
|
||||
|
||||
.macro ldcopr16 reg1, reg2, coproc, opc1, CRm
|
||||
mrrc \coproc, \opc1, \reg1, \reg2, \CRm
|
||||
.endm
|
||||
|
||||
.macro stcopr reg, coproc, opc1, CRn, CRm, opc2
|
||||
mcr \coproc, \opc1, \reg, \CRn, \CRm, \opc2
|
||||
.endm
|
||||
|
||||
.macro stcopr16 reg1, reg2, coproc, opc1, CRm
|
||||
mcrr \coproc, \opc1, \reg1, \reg2, \CRm
|
||||
.endm
|
||||
|
||||
/* Cache line size helpers */
|
||||
.macro dcache_line_size reg, tmp
|
||||
ldcopr \tmp, CTR
|
||||
ubfx \tmp, \tmp, #CTR_DMINLINE_SHIFT, #CTR_DMINLINE_WIDTH
|
||||
mov \reg, #WORD_SIZE
|
||||
lsl \reg, \reg, \tmp
|
||||
.endm
|
||||
|
||||
.macro icache_line_size reg, tmp
|
||||
ldcopr \tmp, CTR
|
||||
and \tmp, \tmp, #CTR_IMINLINE_MASK
|
||||
mov \reg, #WORD_SIZE
|
||||
lsl \reg, \reg, \tmp
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Declare the exception vector table, enforcing it is aligned on a
|
||||
* 32 byte boundary.
|
||||
*/
|
||||
.macro vector_base label
|
||||
.section .vectors, "ax"
|
||||
.align 5
|
||||
\label:
|
||||
.endm
|
||||
|
||||
/*
|
||||
* This macro calculates the base address of the current CPU's multi
|
||||
* processor(MP) stack using the plat_my_core_pos() index, the name of
|
||||
* the stack storage and the size of each stack.
|
||||
* Out: r0 = physical address of stack base
|
||||
* Clobber: r14, r1, r2
|
||||
*/
|
||||
.macro get_my_mp_stack _name, _size
|
||||
bl plat_my_core_pos
|
||||
ldr r2, =(\_name + \_size)
|
||||
mov r1, #\_size
|
||||
mla r0, r0, r1, r2
|
||||
.endm
|
||||
|
||||
/*
|
||||
* This macro calculates the base address of a uniprocessor(UP) stack
|
||||
* using the name of the stack storage and the size of the stack
|
||||
* Out: r0 = physical address of stack base
|
||||
*/
|
||||
.macro get_up_stack _name, _size
|
||||
ldr r0, =(\_name + \_size)
|
||||
.endm
|
||||
|
||||
#if ARM_ARCH_MAJOR == 7 && !defined(ARMV7_SUPPORTS_VIRTUALIZATION)
|
||||
/*
|
||||
* Macro for mitigating against speculative execution.
|
||||
* ARMv7 cores without Virtualization extension do not support the
|
||||
* eret instruction.
|
||||
*/
|
||||
.macro exception_return
|
||||
movs pc, lr
|
||||
dsb nsh
|
||||
isb
|
||||
.endm
|
||||
|
||||
#else
|
||||
/*
|
||||
* Macro for mitigating against speculative execution beyond ERET. Uses the
|
||||
* speculation barrier instruction introduced by FEAT_SB, if it's enabled.
|
||||
*/
|
||||
.macro exception_return
|
||||
eret
|
||||
#if ENABLE_FEAT_SB
|
||||
sb
|
||||
#else
|
||||
dsb nsh
|
||||
isb
|
||||
#endif
|
||||
.endm
|
||||
#endif
|
||||
|
||||
#if (ARM_ARCH_MAJOR == 7)
|
||||
/* ARMv7 does not support stl instruction */
|
||||
.macro stl _reg, _write_lock
|
||||
dmb
|
||||
str \_reg, \_write_lock
|
||||
dsb
|
||||
.endm
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Helper macro to generate the best mov/movw/movt combinations
|
||||
* according to the value to be moved.
|
||||
*/
|
||||
.macro mov_imm _reg, _val
|
||||
.if ((\_val) & 0xffff0000) == 0
|
||||
mov \_reg, #(\_val)
|
||||
.else
|
||||
movw \_reg, #((\_val) & 0xffff)
|
||||
movt \_reg, #((\_val) >> 16)
|
||||
.endif
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Macro to mark instances where we're jumping to a function and don't
|
||||
* expect a return. To provide the function being jumped to with
|
||||
* additional information, we use 'bl' instruction to jump rather than
|
||||
* 'b'.
|
||||
*
|
||||
* Debuggers infer the location of a call from where LR points to, which
|
||||
* is usually the instruction after 'bl'. If this macro expansion
|
||||
* happens to be the last location in a function, that'll cause the LR
|
||||
* to point a location beyond the function, thereby misleading debugger
|
||||
* back trace. We therefore insert a 'nop' after the function call for
|
||||
* debug builds, unless 'skip_nop' parameter is non-zero.
|
||||
*/
|
||||
.macro no_ret _func:req, skip_nop=0
|
||||
bl \_func
|
||||
#if DEBUG
|
||||
.ifeq \skip_nop
|
||||
nop
|
||||
.endif
|
||||
#endif
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Reserve space for a spin lock in assembly file.
|
||||
*/
|
||||
.macro define_asm_spinlock _name:req
|
||||
.align SPINLOCK_ASM_ALIGN
|
||||
\_name:
|
||||
.space SPINLOCK_ASM_SIZE
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Helper macro to OR the bottom 32 bits of `_val` into `_reg_l`
|
||||
* and the top 32 bits of `_val` into `_reg_h`. If either the bottom
|
||||
* or top word of `_val` is zero, the corresponding OR operation
|
||||
* is skipped.
|
||||
*/
|
||||
.macro orr64_imm _reg_l, _reg_h, _val
|
||||
.if (\_val >> 32)
|
||||
orr \_reg_h, \_reg_h, #(\_val >> 32)
|
||||
.endif
|
||||
.if (\_val & 0xffffffff)
|
||||
orr \_reg_l, \_reg_l, #(\_val & 0xffffffff)
|
||||
.endif
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Helper macro to bitwise-clear bits in `_reg_l` and
|
||||
* `_reg_h` given a 64 bit immediate `_val`. The set bits
|
||||
* in the bottom word of `_val` dictate which bits from
|
||||
* `_reg_l` should be cleared. Similarly, the set bits in
|
||||
* the top word of `_val` dictate which bits from `_reg_h`
|
||||
* should be cleared. If either the bottom or top word of
|
||||
* `_val` is zero, the corresponding BIC operation is skipped.
|
||||
*/
|
||||
.macro bic64_imm _reg_l, _reg_h, _val
|
||||
.if (\_val >> 32)
|
||||
bic \_reg_h, \_reg_h, #(\_val >> 32)
|
||||
.endif
|
||||
.if (\_val & 0xffffffff)
|
||||
bic \_reg_l, \_reg_l, #(\_val & 0xffffffff)
|
||||
.endif
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Helper macro for carrying out division in software when
|
||||
* hardware division is not suported. \top holds the dividend
|
||||
* in the function call and the remainder after
|
||||
* the function is executed. \bot holds the divisor. \div holds
|
||||
* the quotient and \temp is a temporary registed used in calcualtion.
|
||||
* The division algorithm has been obtained from:
|
||||
* http://www.keil.com/support/man/docs/armasm/armasm_dom1359731155623.htm
|
||||
*/
|
||||
.macro softudiv div:req,top:req,bot:req,temp:req
|
||||
|
||||
mov \temp, \bot
|
||||
cmp \temp, \top, lsr #1
|
||||
div1:
|
||||
movls \temp, \temp, lsl #1
|
||||
cmp \temp, \top, lsr #1
|
||||
bls div1
|
||||
mov \div, #0
|
||||
|
||||
div2:
|
||||
cmp \top, \temp
|
||||
subcs \top, \top,\temp
|
||||
ADC \div, \div, \div
|
||||
mov \temp, \temp, lsr #1
|
||||
cmp \temp, \bot
|
||||
bhs div2
|
||||
.endm
|
||||
#endif /* ASM_MACROS_S */
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
#ifndef ASSERT_MACROS_S
|
||||
#define ASSERT_MACROS_S
|
||||
|
||||
/*
|
||||
* Assembler macro to enable asm_assert. We assume that the stack is
|
||||
* initialized prior to invoking this macro.
|
||||
*/
|
||||
#define ASM_ASSERT(_cc) \
|
||||
.ifndef .L_assert_filename ;\
|
||||
.pushsection .rodata.str1.1, "aS" ;\
|
||||
.L_assert_filename: ;\
|
||||
.string __FILE__ ;\
|
||||
.popsection ;\
|
||||
.endif ;\
|
||||
b##_cc 300f ;\
|
||||
ldr r0, =.L_assert_filename ;\
|
||||
ldr r1, =__LINE__ ;\
|
||||
b asm_assert;\
|
||||
300:
|
||||
|
||||
#endif /* ASSERT_MACROS_S */
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
#ifndef CONSOLE_MACROS_S
|
||||
#define CONSOLE_MACROS_S
|
||||
|
||||
#include <drivers/console.h>
|
||||
|
||||
/*
|
||||
* This macro encapsulates the common setup that has to be done at the end of
|
||||
* a console driver's register function. It will register all of the driver's
|
||||
* callbacks in the console_t structure and initialize the flags field (by
|
||||
* default consoles are enabled for the "boot" and "crash" states, this can be
|
||||
* changed after registration with the console_set_scope() function). It ends
|
||||
* with a tail call that will include return to the caller.
|
||||
* REQUIRES console_t pointer in r0 and a valid return address in lr.
|
||||
*/
|
||||
.macro finish_console_register _driver, putc=0, getc=0, flush=0
|
||||
/*
|
||||
* If any of the callback is not specified or set as 0, then the
|
||||
* corresponding callback entry in console_t is set to 0.
|
||||
*/
|
||||
.ifne \putc
|
||||
ldr r1, =console_\_driver\()_putc
|
||||
.else
|
||||
mov r1, #0
|
||||
.endif
|
||||
str r1, [r0, #CONSOLE_T_PUTC]
|
||||
|
||||
.ifne \getc
|
||||
ldr r1, =console_\_driver\()_getc
|
||||
.else
|
||||
mov r1, #0
|
||||
.endif
|
||||
str r1, [r0, #CONSOLE_T_GETC]
|
||||
|
||||
.ifne \flush
|
||||
ldr r1, =console_\_driver\()_flush
|
||||
.else
|
||||
mov r1, #0
|
||||
.endif
|
||||
str r1, [r0, #CONSOLE_T_FLUSH]
|
||||
|
||||
mov r1, #(CONSOLE_FLAG_BOOT | CONSOLE_FLAG_CRASH)
|
||||
str r1, [r0, #CONSOLE_T_FLAGS]
|
||||
b console_register
|
||||
.endm
|
||||
|
||||
#endif /* CONSOLE_MACROS_S */
|
||||
+458
@@ -0,0 +1,458 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2022, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef EL3_COMMON_MACROS_S
|
||||
#define EL3_COMMON_MACROS_S
|
||||
|
||||
#include <arch.h>
|
||||
#include <asm_macros.S>
|
||||
#include <assert_macros.S>
|
||||
#include <lib/xlat_tables/xlat_tables_defs.h>
|
||||
|
||||
#define PAGE_START_MASK ~(PAGE_SIZE_MASK)
|
||||
|
||||
/*
|
||||
* Helper macro to initialise EL3 registers we care about.
|
||||
*/
|
||||
.macro el3_arch_init_common
|
||||
/* ---------------------------------------------------------------------
|
||||
* SCTLR has already been initialised - read current value before
|
||||
* modifying.
|
||||
*
|
||||
* SCTLR.I: Enable the instruction cache.
|
||||
*
|
||||
* SCTLR.A: Enable Alignment fault checking. All instructions that load
|
||||
* or store one or more registers have an alignment check that the
|
||||
* address being accessed is aligned to the size of the data element(s)
|
||||
* being accessed.
|
||||
* ---------------------------------------------------------------------
|
||||
*/
|
||||
ldr r1, =(SCTLR_I_BIT | SCTLR_A_BIT)
|
||||
ldcopr r0, SCTLR
|
||||
orr r0, r0, r1
|
||||
stcopr r0, SCTLR
|
||||
isb
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
* Initialise SCR, setting all fields rather than relying on the hw.
|
||||
*
|
||||
* SCR.SIF: Enabled so that Secure state instruction fetches from
|
||||
* Non-secure memory are not permitted.
|
||||
* ---------------------------------------------------------------------
|
||||
*/
|
||||
ldr r0, =(SCR_RESET_VAL | SCR_SIF_BIT)
|
||||
stcopr r0, SCR
|
||||
|
||||
/* -----------------------------------------------------
|
||||
* Enable the Asynchronous data abort now that the
|
||||
* exception vectors have been setup.
|
||||
* -----------------------------------------------------
|
||||
*/
|
||||
cpsie a
|
||||
isb
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
* Initialise NSACR, setting all the fields, except for the
|
||||
* IMPLEMENTATION DEFINED field, rather than relying on the hw. Some
|
||||
* fields are architecturally UNKNOWN on reset.
|
||||
*
|
||||
* NSACR_ENABLE_FP_ACCESS: Represents NSACR.cp11 and NSACR.cp10. The
|
||||
* cp11 field is ignored, but is set to same value as cp10. The cp10
|
||||
* field is set to allow access to Advanced SIMD and floating point
|
||||
* features from both Security states.
|
||||
*
|
||||
* NSACR.NSTRCDIS: When system register trace implemented, Set to one
|
||||
* so that NS System register accesses to all implemented trace
|
||||
* registers are disabled.
|
||||
* When system register trace is not implemented, this bit is RES0 and
|
||||
* hence set to zero.
|
||||
* ---------------------------------------------------------------------
|
||||
*/
|
||||
ldcopr r0, NSACR
|
||||
and r0, r0, #NSACR_IMP_DEF_MASK
|
||||
orr r0, r0, #(NSACR_RESET_VAL | NSACR_ENABLE_FP_ACCESS)
|
||||
ldcopr r1, ID_DFR0
|
||||
ubfx r1, r1, #ID_DFR0_COPTRC_SHIFT, #ID_DFR0_COPTRC_LENGTH
|
||||
cmp r1, #ID_DFR0_COPTRC_SUPPORTED
|
||||
bne 1f
|
||||
orr r0, r0, #NSTRCDIS_BIT
|
||||
1:
|
||||
stcopr r0, NSACR
|
||||
isb
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
* Initialise CPACR, setting all fields rather than relying on hw. Some
|
||||
* fields are architecturally UNKNOWN on reset.
|
||||
*
|
||||
* CPACR.TRCDIS: Trap control for PL0 and PL1 System register accesses
|
||||
* to trace registers. Set to zero to allow access.
|
||||
*
|
||||
* CPACR_ENABLE_FP_ACCESS: Represents CPACR.cp11 and CPACR.cp10. The
|
||||
* cp11 field is ignored, but is set to same value as cp10. The cp10
|
||||
* field is set to allow full access from PL0 and PL1 to floating-point
|
||||
* and Advanced SIMD features.
|
||||
* ---------------------------------------------------------------------
|
||||
*/
|
||||
ldr r0, =((CPACR_RESET_VAL | CPACR_ENABLE_FP_ACCESS) & ~(TRCDIS_BIT))
|
||||
stcopr r0, CPACR
|
||||
isb
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
* Initialise FPEXC, setting all fields rather than relying on hw. Some
|
||||
* fields are architecturally UNKNOWN on reset and are set to zero
|
||||
* except for field(s) listed below.
|
||||
*
|
||||
* FPEXC.EN: Enable access to Advanced SIMD and floating point features
|
||||
* from all exception levels.
|
||||
*
|
||||
* __SOFTFP__: Predefined macro exposed by soft-float toolchain.
|
||||
* ARMv7 and Cortex-A32(ARMv8/aarch32) has both soft-float and
|
||||
* hard-float variants of toolchain, avoid compiling below code with
|
||||
* soft-float toolchain as "vmsr" instruction will not be recognized.
|
||||
* ---------------------------------------------------------------------
|
||||
*/
|
||||
#if ((ARM_ARCH_MAJOR > 7) || defined(ARMV7_SUPPORTS_VFP)) && !(__SOFTFP__)
|
||||
ldr r0, =(FPEXC_RESET_VAL | FPEXC_EN_BIT)
|
||||
vmsr FPEXC, r0
|
||||
isb
|
||||
#endif
|
||||
|
||||
#if (ARM_ARCH_MAJOR > 7)
|
||||
/* ---------------------------------------------------------------------
|
||||
* Initialise SDCR, setting all the fields rather than relying on hw.
|
||||
*
|
||||
* SDCR.SPD: Disable AArch32 privileged debug. Debug exceptions from
|
||||
* Secure EL1 are disabled.
|
||||
*
|
||||
* SDCR.SCCD: Set to one so that cycle counting by PMCCNTR is prohibited
|
||||
* in Secure state. This bit is RES0 in versions of the architecture
|
||||
* earlier than ARMv8.5, setting it to 1 doesn't have any effect on
|
||||
* them.
|
||||
*
|
||||
* SDCR.TTRF: Set to one so that access to trace filter control
|
||||
* registers in non-monitor mode generate Monitor trap exception,
|
||||
* unless the access generates a higher priority exception when
|
||||
* trace filter control(FEAT_TRF) is implemented.
|
||||
* When FEAT_TRF is not implemented, this bit is RES0.
|
||||
* ---------------------------------------------------------------------
|
||||
*/
|
||||
ldr r0, =((SDCR_RESET_VAL | SDCR_SPD(SDCR_SPD_DISABLE) | \
|
||||
SDCR_SCCD_BIT) & ~SDCR_TTRF_BIT)
|
||||
ldcopr r1, ID_DFR0
|
||||
ubfx r1, r1, #ID_DFR0_TRACEFILT_SHIFT, #ID_DFR0_TRACEFILT_LENGTH
|
||||
cmp r1, #ID_DFR0_TRACEFILT_SUPPORTED
|
||||
bne 1f
|
||||
orr r0, r0, #SDCR_TTRF_BIT
|
||||
1:
|
||||
stcopr r0, SDCR
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
* Initialise PMCR, setting all fields rather than relying
|
||||
* on hw. Some fields are architecturally UNKNOWN on reset.
|
||||
*
|
||||
* PMCR.LP: Set to one so that event counter overflow, that
|
||||
* is recorded in PMOVSCLR[0-30], occurs on the increment
|
||||
* that changes PMEVCNTR<n>[63] from 1 to 0, when ARMv8.5-PMU
|
||||
* is implemented. This bit is RES0 in versions of the architecture
|
||||
* earlier than ARMv8.5, setting it to 1 doesn't have any effect
|
||||
* on them.
|
||||
* This bit is Reserved, UNK/SBZP in ARMv7.
|
||||
*
|
||||
* PMCR.LC: Set to one so that cycle counter overflow, that
|
||||
* is recorded in PMOVSCLR[31], occurs on the increment
|
||||
* that changes PMCCNTR[63] from 1 to 0.
|
||||
* This bit is Reserved, UNK/SBZP in ARMv7.
|
||||
*
|
||||
* PMCR.DP: Set to one to prohibit cycle counting whilst in Secure mode.
|
||||
* ---------------------------------------------------------------------
|
||||
*/
|
||||
ldr r0, =(PMCR_RESET_VAL | PMCR_DP_BIT | PMCR_LC_BIT | \
|
||||
PMCR_LP_BIT)
|
||||
#else
|
||||
ldr r0, =(PMCR_RESET_VAL | PMCR_DP_BIT)
|
||||
#endif
|
||||
stcopr r0, PMCR
|
||||
|
||||
/*
|
||||
* If Data Independent Timing (DIT) functionality is implemented,
|
||||
* always enable DIT in EL3
|
||||
*/
|
||||
ldcopr r0, ID_PFR0
|
||||
and r0, r0, #(ID_PFR0_DIT_MASK << ID_PFR0_DIT_SHIFT)
|
||||
cmp r0, #ID_PFR0_DIT_SUPPORTED
|
||||
bne 1f
|
||||
mrs r0, cpsr
|
||||
orr r0, r0, #CPSR_DIT_BIT
|
||||
msr cpsr_cxsf, r0
|
||||
1:
|
||||
.endm
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* This is the super set of actions that need to be performed during a cold boot
|
||||
* or a warm boot in EL3. This code is shared by BL1 and BL32 (SP_MIN).
|
||||
*
|
||||
* This macro will always perform reset handling, architectural initialisations
|
||||
* and stack setup. The rest of the actions are optional because they might not
|
||||
* be needed, depending on the context in which this macro is called. This is
|
||||
* why this macro is parameterised ; each parameter allows to enable/disable
|
||||
* some actions.
|
||||
*
|
||||
* _init_sctlr:
|
||||
* Whether the macro needs to initialise the SCTLR register including
|
||||
* configuring the endianness of data accesses.
|
||||
*
|
||||
* _warm_boot_mailbox:
|
||||
* Whether the macro needs to detect the type of boot (cold/warm). The
|
||||
* detection is based on the platform entrypoint address : if it is zero
|
||||
* then it is a cold boot, otherwise it is a warm boot. In the latter case,
|
||||
* this macro jumps on the platform entrypoint address.
|
||||
*
|
||||
* _secondary_cold_boot:
|
||||
* Whether the macro needs to identify the CPU that is calling it: primary
|
||||
* CPU or secondary CPU. The primary CPU will be allowed to carry on with
|
||||
* the platform initialisations, while the secondaries will be put in a
|
||||
* platform-specific state in the meantime.
|
||||
*
|
||||
* If the caller knows this macro will only be called by the primary CPU
|
||||
* then this parameter can be defined to 0 to skip this step.
|
||||
*
|
||||
* _init_memory:
|
||||
* Whether the macro needs to initialise the memory.
|
||||
*
|
||||
* _init_c_runtime:
|
||||
* Whether the macro needs to initialise the C runtime environment.
|
||||
*
|
||||
* _exception_vectors:
|
||||
* Address of the exception vectors to program in the VBAR_EL3 register.
|
||||
*
|
||||
* _pie_fixup_size:
|
||||
* Size of memory region to fixup Global Descriptor Table (GDT).
|
||||
*
|
||||
* A non-zero value is expected when firmware needs GDT to be fixed-up.
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
*/
|
||||
.macro el3_entrypoint_common \
|
||||
_init_sctlr, _warm_boot_mailbox, _secondary_cold_boot, \
|
||||
_init_memory, _init_c_runtime, _exception_vectors, \
|
||||
_pie_fixup_size
|
||||
|
||||
/* Make sure we are in Secure Mode */
|
||||
#if ENABLE_ASSERTIONS
|
||||
ldcopr r0, SCR
|
||||
tst r0, #SCR_NS_BIT
|
||||
ASM_ASSERT(eq)
|
||||
#endif
|
||||
|
||||
.if \_init_sctlr
|
||||
/* -------------------------------------------------------------
|
||||
* This is the initialisation of SCTLR and so must ensure that
|
||||
* all fields are explicitly set rather than relying on hw. Some
|
||||
* fields reset to an IMPLEMENTATION DEFINED value.
|
||||
*
|
||||
* SCTLR.TE: Set to zero so that exceptions to an Exception
|
||||
* Level executing at PL1 are taken to A32 state.
|
||||
*
|
||||
* SCTLR.EE: Set the CPU endianness before doing anything that
|
||||
* might involve memory reads or writes. Set to zero to select
|
||||
* Little Endian.
|
||||
*
|
||||
* SCTLR.V: Set to zero to select the normal exception vectors
|
||||
* with base address held in VBAR.
|
||||
*
|
||||
* SCTLR.DSSBS: Set to zero to disable speculation store bypass
|
||||
* safe behaviour upon exception entry to EL3.
|
||||
* -------------------------------------------------------------
|
||||
*/
|
||||
ldr r0, =(SCTLR_RESET_VAL & ~(SCTLR_TE_BIT | SCTLR_EE_BIT | \
|
||||
SCTLR_V_BIT | SCTLR_DSSBS_BIT))
|
||||
stcopr r0, SCTLR
|
||||
isb
|
||||
.endif /* _init_sctlr */
|
||||
|
||||
/* Switch to monitor mode */
|
||||
cps #MODE32_mon
|
||||
isb
|
||||
|
||||
#if DISABLE_MTPMU
|
||||
bl mtpmu_disable
|
||||
#endif
|
||||
|
||||
.if \_warm_boot_mailbox
|
||||
/* -------------------------------------------------------------
|
||||
* This code will be executed for both warm and cold resets.
|
||||
* Now is the time to distinguish between the two.
|
||||
* Query the platform entrypoint address and if it is not zero
|
||||
* then it means it is a warm boot so jump to this address.
|
||||
* -------------------------------------------------------------
|
||||
*/
|
||||
bl plat_get_my_entrypoint
|
||||
cmp r0, #0
|
||||
bxne r0
|
||||
.endif /* _warm_boot_mailbox */
|
||||
|
||||
.if \_pie_fixup_size
|
||||
#if ENABLE_PIE
|
||||
/*
|
||||
* ------------------------------------------------------------
|
||||
* If PIE is enabled fixup the Global descriptor Table only
|
||||
* once during primary core cold boot path.
|
||||
*
|
||||
* Compile time base address, required for fixup, is calculated
|
||||
* using "pie_fixup" label present within first page.
|
||||
* ------------------------------------------------------------
|
||||
*/
|
||||
pie_fixup:
|
||||
ldr r0, =pie_fixup
|
||||
ldr r1, =PAGE_START_MASK
|
||||
and r0, r0, r1
|
||||
mov_imm r1, \_pie_fixup_size
|
||||
add r1, r1, r0
|
||||
bl fixup_gdt_reloc
|
||||
#endif /* ENABLE_PIE */
|
||||
.endif /* _pie_fixup_size */
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
* Set the exception vectors (VBAR/MVBAR).
|
||||
* ---------------------------------------------------------------------
|
||||
*/
|
||||
ldr r0, =\_exception_vectors
|
||||
stcopr r0, VBAR
|
||||
stcopr r0, MVBAR
|
||||
isb
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
* It is a cold boot.
|
||||
* Perform any processor specific actions upon reset e.g. cache, TLB
|
||||
* invalidations etc.
|
||||
* ---------------------------------------------------------------------
|
||||
*/
|
||||
bl reset_handler
|
||||
|
||||
el3_arch_init_common
|
||||
|
||||
.if \_secondary_cold_boot
|
||||
/* -------------------------------------------------------------
|
||||
* Check if this is a primary or secondary CPU cold boot.
|
||||
* The primary CPU will set up the platform while the
|
||||
* secondaries are placed in a platform-specific state until the
|
||||
* primary CPU performs the necessary actions to bring them out
|
||||
* of that state and allows entry into the OS.
|
||||
* -------------------------------------------------------------
|
||||
*/
|
||||
bl plat_is_my_cpu_primary
|
||||
cmp r0, #0
|
||||
bne do_primary_cold_boot
|
||||
|
||||
/* This is a cold boot on a secondary CPU */
|
||||
bl plat_secondary_cold_boot_setup
|
||||
/* plat_secondary_cold_boot_setup() is not supposed to return */
|
||||
no_ret plat_panic_handler
|
||||
|
||||
do_primary_cold_boot:
|
||||
.endif /* _secondary_cold_boot */
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
* Initialize memory now. Secondary CPU initialization won't get to this
|
||||
* point.
|
||||
* ---------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
.if \_init_memory
|
||||
bl platform_mem_init
|
||||
.endif /* _init_memory */
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
* Init C runtime environment:
|
||||
* - Zero-initialise the NOBITS sections. There are 2 of them:
|
||||
* - the .bss section;
|
||||
* - the coherent memory section (if any).
|
||||
* - Relocate the data section from ROM to RAM, if required.
|
||||
* ---------------------------------------------------------------------
|
||||
*/
|
||||
.if \_init_c_runtime
|
||||
#if defined(IMAGE_BL32) || (defined(IMAGE_BL2) && BL2_AT_EL3)
|
||||
/* -----------------------------------------------------------------
|
||||
* Invalidate the RW memory used by the image. This
|
||||
* includes the data and NOBITS sections. This is done to
|
||||
* safeguard against possible corruption of this memory by
|
||||
* dirty cache lines in a system cache as a result of use by
|
||||
* an earlier boot loader stage. If PIE is enabled however,
|
||||
* RO sections including the GOT may be modified during
|
||||
* pie fixup. Therefore, to be on the safe side, invalidate
|
||||
* the entire image region if PIE is enabled.
|
||||
* -----------------------------------------------------------------
|
||||
*/
|
||||
#if ENABLE_PIE
|
||||
#if SEPARATE_CODE_AND_RODATA
|
||||
ldr r0, =__TEXT_START__
|
||||
#else
|
||||
ldr r0, =__RO_START__
|
||||
#endif /* SEPARATE_CODE_AND_RODATA */
|
||||
#else
|
||||
ldr r0, =__RW_START__
|
||||
#endif /* ENABLE_PIE */
|
||||
ldr r1, =__RW_END__
|
||||
sub r1, r1, r0
|
||||
bl inv_dcache_range
|
||||
#if defined(IMAGE_BL2) && SEPARATE_BL2_NOLOAD_REGION
|
||||
ldr r0, =__BL2_NOLOAD_START__
|
||||
ldr r1, =__BL2_NOLOAD_END__
|
||||
sub r1, r1, r0
|
||||
bl inv_dcache_range
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* zeromem uses r12 whereas it is used to save previous BL arg3,
|
||||
* save it in r7
|
||||
*/
|
||||
mov r7, r12
|
||||
ldr r0, =__BSS_START__
|
||||
ldr r1, =__BSS_END__
|
||||
sub r1, r1, r0
|
||||
bl zeromem
|
||||
|
||||
#if USE_COHERENT_MEM
|
||||
ldr r0, =__COHERENT_RAM_START__
|
||||
ldr r1, =__COHERENT_RAM_END_UNALIGNED__
|
||||
sub r1, r1, r0
|
||||
bl zeromem
|
||||
#endif
|
||||
|
||||
/* Restore r12 */
|
||||
mov r12, r7
|
||||
|
||||
#if defined(IMAGE_BL1) || (defined(IMAGE_BL2) && BL2_AT_EL3 && BL2_IN_XIP_MEM)
|
||||
/* -----------------------------------------------------
|
||||
* Copy data from ROM to RAM.
|
||||
* -----------------------------------------------------
|
||||
*/
|
||||
ldr r0, =__DATA_RAM_START__
|
||||
ldr r1, =__DATA_ROM_START__
|
||||
ldr r2, =__DATA_RAM_END__
|
||||
sub r2, r2, r0
|
||||
bl memcpy4
|
||||
#endif
|
||||
.endif /* _init_c_runtime */
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
* Allocate a stack whose memory will be marked 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.
|
||||
* ---------------------------------------------------------------------
|
||||
*/
|
||||
bl plat_set_my_stack
|
||||
|
||||
#if STACK_PROTECTOR_ENABLED
|
||||
.if \_init_c_runtime
|
||||
bl update_stack_protector_canary
|
||||
.endif /* _init_c_runtime */
|
||||
#endif
|
||||
.endm
|
||||
|
||||
#endif /* EL3_COMMON_MACROS_S */
|
||||
@@ -0,0 +1,177 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef SMCCC_HELPERS_H
|
||||
#define SMCCC_HELPERS_H
|
||||
|
||||
#include <lib/smccc.h>
|
||||
|
||||
/* These are offsets to registers in smc_ctx_t */
|
||||
#define SMC_CTX_GPREG_R0 U(0x0)
|
||||
#define SMC_CTX_GPREG_R1 U(0x4)
|
||||
#define SMC_CTX_GPREG_R2 U(0x8)
|
||||
#define SMC_CTX_GPREG_R3 U(0xC)
|
||||
#define SMC_CTX_GPREG_R4 U(0x10)
|
||||
#define SMC_CTX_GPREG_R5 U(0x14)
|
||||
#define SMC_CTX_SP_USR U(0x34)
|
||||
#define SMC_CTX_SPSR_MON U(0x78)
|
||||
#define SMC_CTX_SP_MON U(0x7C)
|
||||
#define SMC_CTX_LR_MON U(0x80)
|
||||
#define SMC_CTX_SCR U(0x84)
|
||||
#define SMC_CTX_PMCR U(0x88)
|
||||
#define SMC_CTX_SIZE U(0x90)
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <lib/cassert.h>
|
||||
|
||||
/*
|
||||
* The generic structure to save arguments and callee saved registers during
|
||||
* an SMC. Also this structure is used to store the result return values after
|
||||
* the completion of SMC service.
|
||||
*/
|
||||
typedef struct smc_ctx {
|
||||
u_register_t r0;
|
||||
u_register_t r1;
|
||||
u_register_t r2;
|
||||
u_register_t r3;
|
||||
u_register_t r4;
|
||||
u_register_t r5;
|
||||
u_register_t r6;
|
||||
u_register_t r7;
|
||||
u_register_t r8;
|
||||
u_register_t r9;
|
||||
u_register_t r10;
|
||||
u_register_t r11;
|
||||
u_register_t r12;
|
||||
/* spsr_usr doesn't exist */
|
||||
u_register_t sp_usr;
|
||||
u_register_t lr_usr;
|
||||
u_register_t spsr_irq;
|
||||
u_register_t sp_irq;
|
||||
u_register_t lr_irq;
|
||||
u_register_t spsr_fiq;
|
||||
u_register_t sp_fiq;
|
||||
u_register_t lr_fiq;
|
||||
u_register_t spsr_svc;
|
||||
u_register_t sp_svc;
|
||||
u_register_t lr_svc;
|
||||
u_register_t spsr_abt;
|
||||
u_register_t sp_abt;
|
||||
u_register_t lr_abt;
|
||||
u_register_t spsr_und;
|
||||
u_register_t sp_und;
|
||||
u_register_t lr_und;
|
||||
u_register_t spsr_mon;
|
||||
/*
|
||||
* `sp_mon` will point to the C runtime stack in monitor mode. But prior
|
||||
* to exit from SMC, this will point to the `smc_ctx_t` so that
|
||||
* on next entry due to SMC, the `smc_ctx_t` can be easily accessed.
|
||||
*/
|
||||
u_register_t sp_mon;
|
||||
u_register_t lr_mon;
|
||||
u_register_t scr;
|
||||
u_register_t pmcr;
|
||||
/*
|
||||
* The workaround for CVE-2017-5715 requires storing information in
|
||||
* the bottom 3 bits of the stack pointer. Add a padding field to
|
||||
* force the size of the struct to be a multiple of 8.
|
||||
*/
|
||||
u_register_t pad;
|
||||
} smc_ctx_t __aligned(8);
|
||||
|
||||
/*
|
||||
* Compile time assertions related to the 'smc_context' structure to
|
||||
* ensure that the assembler and the compiler view of the offsets of
|
||||
* the structure members is the same.
|
||||
*/
|
||||
CASSERT(SMC_CTX_GPREG_R0 == __builtin_offsetof(smc_ctx_t, r0), \
|
||||
assert_smc_ctx_greg_r0_offset_mismatch);
|
||||
CASSERT(SMC_CTX_GPREG_R1 == __builtin_offsetof(smc_ctx_t, r1), \
|
||||
assert_smc_ctx_greg_r1_offset_mismatch);
|
||||
CASSERT(SMC_CTX_GPREG_R2 == __builtin_offsetof(smc_ctx_t, r2), \
|
||||
assert_smc_ctx_greg_r2_offset_mismatch);
|
||||
CASSERT(SMC_CTX_GPREG_R3 == __builtin_offsetof(smc_ctx_t, r3), \
|
||||
assert_smc_ctx_greg_r3_offset_mismatch);
|
||||
CASSERT(SMC_CTX_GPREG_R4 == __builtin_offsetof(smc_ctx_t, r4), \
|
||||
assert_smc_ctx_greg_r4_offset_mismatch);
|
||||
CASSERT(SMC_CTX_SP_USR == __builtin_offsetof(smc_ctx_t, sp_usr), \
|
||||
assert_smc_ctx_sp_usr_offset_mismatch);
|
||||
CASSERT(SMC_CTX_LR_MON == __builtin_offsetof(smc_ctx_t, lr_mon), \
|
||||
assert_smc_ctx_lr_mon_offset_mismatch);
|
||||
CASSERT(SMC_CTX_SPSR_MON == __builtin_offsetof(smc_ctx_t, spsr_mon), \
|
||||
assert_smc_ctx_spsr_mon_offset_mismatch);
|
||||
|
||||
CASSERT((sizeof(smc_ctx_t) & 0x7U) == 0U, assert_smc_ctx_not_aligned);
|
||||
CASSERT(SMC_CTX_SIZE == sizeof(smc_ctx_t), assert_smc_ctx_size_mismatch);
|
||||
|
||||
/* Convenience macros to return from SMC handler */
|
||||
#define SMC_RET0(_h) { \
|
||||
return (uintptr_t)(_h); \
|
||||
}
|
||||
#define SMC_RET1(_h, _r0) { \
|
||||
((smc_ctx_t *)(_h))->r0 = (_r0); \
|
||||
SMC_RET0(_h); \
|
||||
}
|
||||
#define SMC_RET2(_h, _r0, _r1) { \
|
||||
((smc_ctx_t *)(_h))->r1 = (_r1); \
|
||||
SMC_RET1(_h, (_r0)); \
|
||||
}
|
||||
#define SMC_RET3(_h, _r0, _r1, _r2) { \
|
||||
((smc_ctx_t *)(_h))->r2 = (_r2); \
|
||||
SMC_RET2(_h, (_r0), (_r1)); \
|
||||
}
|
||||
#define SMC_RET4(_h, _r0, _r1, _r2, _r3) { \
|
||||
((smc_ctx_t *)(_h))->r3 = (_r3); \
|
||||
SMC_RET3(_h, (_r0), (_r1), (_r2)); \
|
||||
}
|
||||
#define SMC_RET5(_h, _r0, _r1, _r2, _r3, _r4) { \
|
||||
((smc_ctx_t *)(_h))->r4 = (_r4); \
|
||||
SMC_RET4(_h, (_r0), (_r1), (_r2), (_r3)); \
|
||||
}
|
||||
#define SMC_RET6(_h, _r0, _r1, _r2, _r3, _r4, _r5) { \
|
||||
((smc_ctx_t *)(_h))->r5 = (_r5); \
|
||||
SMC_RET5(_h, (_r0), (_r1), (_r2), (_r3), (_r4)); \
|
||||
}
|
||||
#define SMC_RET7(_h, _r0, _r1, _r2, _r3, _r4, _r5, _r6) { \
|
||||
((smc_ctx_t *)(_h))->r6 = (_r6); \
|
||||
SMC_RET6(_h, (_r0), (_r1), (_r2), (_r3), (_r4), (_r5)); \
|
||||
}
|
||||
#define SMC_RET8(_h, _r0, _r1, _r2, _r3, _r4, _r5, _r6, _r7) { \
|
||||
((smc_ctx_t *)(_h))->r7 = (_r7); \
|
||||
SMC_RET7(_h, (_r0), (_r1), (_r2), (_r3), (_r4), (_r5), (_r6)); \
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper macro to retrieve the SMC parameters from smc_ctx_t.
|
||||
*/
|
||||
#define get_smc_params_from_ctx(_hdl, _r1, _r2, _r3, _r4) { \
|
||||
_r1 = ((smc_ctx_t *)_hdl)->r1; \
|
||||
_r2 = ((smc_ctx_t *)_hdl)->r2; \
|
||||
_r3 = ((smc_ctx_t *)_hdl)->r3; \
|
||||
_r4 = ((smc_ctx_t *)_hdl)->r4; \
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------
|
||||
* Helper APIs for setting and retrieving appropriate `smc_ctx_t`.
|
||||
* These functions need to implemented by the BL including this library.
|
||||
* ------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/* Get the pointer to `smc_ctx_t` corresponding to the security state. */
|
||||
void *smc_get_ctx(unsigned int security_state);
|
||||
|
||||
/* Set the next `smc_ctx_t` corresponding to the security state. */
|
||||
void smc_set_next_ctx(unsigned int security_state);
|
||||
|
||||
/* Get the pointer to next `smc_ctx_t` already set by `smc_set_next_ctx()`. */
|
||||
void *smc_get_next_ctx(void);
|
||||
|
||||
#endif /*__ASSEMBLER__*/
|
||||
|
||||
#endif /* SMCCC_HELPERS_H */
|
||||
@@ -0,0 +1,241 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
#ifndef SMCCC_MACROS_S
|
||||
#define SMCCC_MACROS_S
|
||||
|
||||
#include <arch.h>
|
||||
|
||||
/*
|
||||
* Macro to save the General purpose registers (r0 - r12), the banked
|
||||
* spsr, lr, sp registers and the `scr` register to the SMC context on entry
|
||||
* due a SMC call. The `lr` of the current mode (monitor) is expected to be
|
||||
* already saved. The `sp` must point to the `smc_ctx_t` to save to.
|
||||
* Additionally, also save the 'pmcr' register as this is updated whilst
|
||||
* executing in the secure world.
|
||||
*/
|
||||
.macro smccc_save_gp_mode_regs
|
||||
/* Save r0 - r12 in the SMC context */
|
||||
stm sp, {r0-r12}
|
||||
mov r0, sp
|
||||
add r0, r0, #SMC_CTX_SP_USR
|
||||
|
||||
#if ARM_ARCH_MAJOR == 7 && !defined(ARMV7_SUPPORTS_VIRTUALIZATION)
|
||||
/* Must be in secure state to restore Monitor mode */
|
||||
ldcopr r4, SCR
|
||||
bic r2, r4, #SCR_NS_BIT
|
||||
stcopr r2, SCR
|
||||
isb
|
||||
|
||||
cps #MODE32_sys
|
||||
stm r0!, {sp, lr}
|
||||
|
||||
cps #MODE32_irq
|
||||
mrs r2, spsr
|
||||
stm r0!, {r2, sp, lr}
|
||||
|
||||
cps #MODE32_fiq
|
||||
mrs r2, spsr
|
||||
stm r0!, {r2, sp, lr}
|
||||
|
||||
cps #MODE32_svc
|
||||
mrs r2, spsr
|
||||
stm r0!, {r2, sp, lr}
|
||||
|
||||
cps #MODE32_abt
|
||||
mrs r2, spsr
|
||||
stm r0!, {r2, sp, lr}
|
||||
|
||||
cps #MODE32_und
|
||||
mrs r2, spsr
|
||||
stm r0!, {r2, sp, lr}
|
||||
|
||||
/* lr_mon is already saved by caller */
|
||||
cps #MODE32_mon
|
||||
mrs r2, spsr
|
||||
stm r0!, {r2}
|
||||
|
||||
stcopr r4, SCR
|
||||
#else
|
||||
/* Save the banked registers including the current SPSR and LR */
|
||||
mrs r4, sp_usr
|
||||
mrs r5, lr_usr
|
||||
mrs r6, spsr_irq
|
||||
mrs r7, sp_irq
|
||||
mrs r8, lr_irq
|
||||
mrs r9, spsr_fiq
|
||||
mrs r10, sp_fiq
|
||||
mrs r11, lr_fiq
|
||||
mrs r12, spsr_svc
|
||||
stm r0!, {r4-r12}
|
||||
|
||||
mrs r4, sp_svc
|
||||
mrs r5, lr_svc
|
||||
mrs r6, spsr_abt
|
||||
mrs r7, sp_abt
|
||||
mrs r8, lr_abt
|
||||
mrs r9, spsr_und
|
||||
mrs r10, sp_und
|
||||
mrs r11, lr_und
|
||||
mrs r12, spsr
|
||||
stm r0!, {r4-r12}
|
||||
/* lr_mon is already saved by caller */
|
||||
|
||||
ldcopr r4, SCR
|
||||
|
||||
#if ARM_ARCH_MAJOR > 7
|
||||
/*
|
||||
* Check if earlier initialization of SDCR.SCCD to 1
|
||||
* failed, meaning that ARMv8-PMU is not implemented,
|
||||
* cycle counting is not disabled and PMCR should be
|
||||
* saved in Non-secure context.
|
||||
*/
|
||||
ldcopr r5, SDCR
|
||||
tst r5, #SDCR_SCCD_BIT
|
||||
bne 1f
|
||||
#endif
|
||||
/* Secure Cycle Counter is not disabled */
|
||||
#endif
|
||||
ldcopr r5, PMCR
|
||||
|
||||
/* Check caller's security state */
|
||||
tst r4, #SCR_NS_BIT
|
||||
beq 2f
|
||||
|
||||
/* Save PMCR if called from Non-secure state */
|
||||
str r5, [sp, #SMC_CTX_PMCR]
|
||||
|
||||
/* Disable cycle counter when event counting is prohibited */
|
||||
2: orr r5, r5, #PMCR_DP_BIT
|
||||
stcopr r5, PMCR
|
||||
isb
|
||||
1: str r4, [sp, #SMC_CTX_SCR]
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Macro to restore the `smc_ctx_t`, which includes the General purpose
|
||||
* registers and banked mode registers, and exit from the monitor mode.
|
||||
* r0 must point to the `smc_ctx_t` to restore from.
|
||||
*/
|
||||
.macro monitor_exit
|
||||
/*
|
||||
* Save the current sp and restore the smc context
|
||||
* pointer to sp which will be used for handling the
|
||||
* next SMC.
|
||||
*/
|
||||
str sp, [r0, #SMC_CTX_SP_MON]
|
||||
mov sp, r0
|
||||
|
||||
/*
|
||||
* Restore SCR first so that we access the right banked register
|
||||
* when the other mode registers are restored.
|
||||
*/
|
||||
ldr r1, [r0, #SMC_CTX_SCR]
|
||||
stcopr r1, SCR
|
||||
isb
|
||||
|
||||
/*
|
||||
* Restore PMCR when returning to Non-secure state
|
||||
*/
|
||||
tst r1, #SCR_NS_BIT
|
||||
beq 2f
|
||||
|
||||
/*
|
||||
* Back to Non-secure state
|
||||
*/
|
||||
#if ARM_ARCH_MAJOR > 7
|
||||
/*
|
||||
* Check if earlier initialization SDCR.SCCD to 1
|
||||
* failed, meaning that ARMv8-PMU is not implemented and
|
||||
* PMCR should be restored from Non-secure context.
|
||||
*/
|
||||
ldcopr r1, SDCR
|
||||
tst r1, #SDCR_SCCD_BIT
|
||||
bne 2f
|
||||
#endif
|
||||
/*
|
||||
* Restore the PMCR register.
|
||||
*/
|
||||
ldr r1, [r0, #SMC_CTX_PMCR]
|
||||
stcopr r1, PMCR
|
||||
2:
|
||||
/* Restore the banked registers including the current SPSR */
|
||||
add r1, r0, #SMC_CTX_SP_USR
|
||||
|
||||
#if ARM_ARCH_MAJOR == 7 && !defined(ARMV7_SUPPORTS_VIRTUALIZATION)
|
||||
/* Must be in secure state to restore Monitor mode */
|
||||
ldcopr r4, SCR
|
||||
bic r2, r4, #SCR_NS_BIT
|
||||
stcopr r2, SCR
|
||||
isb
|
||||
|
||||
cps #MODE32_sys
|
||||
ldm r1!, {sp, lr}
|
||||
|
||||
cps #MODE32_irq
|
||||
ldm r1!, {r2, sp, lr}
|
||||
msr spsr_fsxc, r2
|
||||
|
||||
cps #MODE32_fiq
|
||||
ldm r1!, {r2, sp, lr}
|
||||
msr spsr_fsxc, r2
|
||||
|
||||
cps #MODE32_svc
|
||||
ldm r1!, {r2, sp, lr}
|
||||
msr spsr_fsxc, r2
|
||||
|
||||
cps #MODE32_abt
|
||||
ldm r1!, {r2, sp, lr}
|
||||
msr spsr_fsxc, r2
|
||||
|
||||
cps #MODE32_und
|
||||
ldm r1!, {r2, sp, lr}
|
||||
msr spsr_fsxc, r2
|
||||
|
||||
cps #MODE32_mon
|
||||
ldm r1!, {r2}
|
||||
msr spsr_fsxc, r2
|
||||
|
||||
stcopr r4, SCR
|
||||
isb
|
||||
#else
|
||||
ldm r1!, {r4-r12}
|
||||
msr sp_usr, r4
|
||||
msr lr_usr, r5
|
||||
msr spsr_irq, r6
|
||||
msr sp_irq, r7
|
||||
msr lr_irq, r8
|
||||
msr spsr_fiq, r9
|
||||
msr sp_fiq, r10
|
||||
msr lr_fiq, r11
|
||||
msr spsr_svc, r12
|
||||
|
||||
ldm r1!, {r4-r12}
|
||||
msr sp_svc, r4
|
||||
msr lr_svc, r5
|
||||
msr spsr_abt, r6
|
||||
msr sp_abt, r7
|
||||
msr lr_abt, r8
|
||||
msr spsr_und, r9
|
||||
msr sp_und, r10
|
||||
msr lr_und, r11
|
||||
/*
|
||||
* Use the `_fsxc` suffix explicitly to instruct the assembler
|
||||
* to update all the 32 bits of SPSR. Else, by default, the
|
||||
* assembler assumes `_fc` suffix which only modifies
|
||||
* f->[31:24] and c->[7:0] bits of SPSR.
|
||||
*/
|
||||
msr spsr_fsxc, r12
|
||||
#endif
|
||||
|
||||
/* Restore the LR */
|
||||
ldr lr, [r0, #SMC_CTX_LR_MON]
|
||||
|
||||
/* Restore the rest of the general purpose registers */
|
||||
ldm r0, {r0-r12}
|
||||
exception_return
|
||||
.endm
|
||||
|
||||
#endif /* SMCCC_MACROS_S */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,268 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2022, Arm Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef ARCH_FEATURES_H
|
||||
#define ARCH_FEATURES_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <arch_helpers.h>
|
||||
|
||||
static inline bool is_armv7_gentimer_present(void)
|
||||
{
|
||||
/* The Generic Timer is always present in an ARMv8-A implementation */
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool is_armv8_1_pan_present(void)
|
||||
{
|
||||
return ((read_id_aa64mmfr1_el1() >> ID_AA64MMFR1_EL1_PAN_SHIFT) &
|
||||
ID_AA64MMFR1_EL1_PAN_MASK) != 0U;
|
||||
}
|
||||
|
||||
static inline bool is_armv8_1_vhe_present(void)
|
||||
{
|
||||
return ((read_id_aa64mmfr1_el1() >> ID_AA64MMFR1_EL1_VHE_SHIFT) &
|
||||
ID_AA64MMFR1_EL1_VHE_MASK) != 0U;
|
||||
}
|
||||
|
||||
static inline bool is_armv8_2_ttcnp_present(void)
|
||||
{
|
||||
return ((read_id_aa64mmfr2_el1() >> ID_AA64MMFR2_EL1_CNP_SHIFT) &
|
||||
ID_AA64MMFR2_EL1_CNP_MASK) != 0U;
|
||||
}
|
||||
|
||||
static inline bool is_feat_pacqarma3_present(void)
|
||||
{
|
||||
uint64_t mask_id_aa64isar2 =
|
||||
(ID_AA64ISAR2_GPA3_MASK << ID_AA64ISAR2_GPA3_SHIFT) |
|
||||
(ID_AA64ISAR2_APA3_MASK << ID_AA64ISAR2_APA3_SHIFT);
|
||||
|
||||
/* If any of the fields is not zero, QARMA3 algorithm is present */
|
||||
return (read_id_aa64isar2_el1() & mask_id_aa64isar2) != 0U;
|
||||
}
|
||||
|
||||
static inline bool is_armv8_3_pauth_present(void)
|
||||
{
|
||||
uint64_t mask_id_aa64isar1 =
|
||||
(ID_AA64ISAR1_GPI_MASK << ID_AA64ISAR1_GPI_SHIFT) |
|
||||
(ID_AA64ISAR1_GPA_MASK << ID_AA64ISAR1_GPA_SHIFT) |
|
||||
(ID_AA64ISAR1_API_MASK << ID_AA64ISAR1_API_SHIFT) |
|
||||
(ID_AA64ISAR1_APA_MASK << ID_AA64ISAR1_APA_SHIFT);
|
||||
|
||||
/*
|
||||
* If any of the fields is not zero or QARMA3 is present,
|
||||
* PAuth is present
|
||||
*/
|
||||
return ((read_id_aa64isar1_el1() & mask_id_aa64isar1) != 0U ||
|
||||
is_feat_pacqarma3_present());
|
||||
}
|
||||
|
||||
static inline bool is_armv8_4_dit_present(void)
|
||||
{
|
||||
return ((read_id_aa64pfr0_el1() >> ID_AA64PFR0_DIT_SHIFT) &
|
||||
ID_AA64PFR0_DIT_MASK) == 1U;
|
||||
}
|
||||
|
||||
static inline bool is_armv8_4_ttst_present(void)
|
||||
{
|
||||
return ((read_id_aa64mmfr2_el1() >> ID_AA64MMFR2_EL1_ST_SHIFT) &
|
||||
ID_AA64MMFR2_EL1_ST_MASK) == 1U;
|
||||
}
|
||||
|
||||
static inline bool is_armv8_5_bti_present(void)
|
||||
{
|
||||
return ((read_id_aa64pfr1_el1() >> ID_AA64PFR1_EL1_BT_SHIFT) &
|
||||
ID_AA64PFR1_EL1_BT_MASK) == BTI_IMPLEMENTED;
|
||||
}
|
||||
|
||||
static inline unsigned int get_armv8_5_mte_support(void)
|
||||
{
|
||||
return ((read_id_aa64pfr1_el1() >> ID_AA64PFR1_EL1_MTE_SHIFT) &
|
||||
ID_AA64PFR1_EL1_MTE_MASK);
|
||||
}
|
||||
|
||||
static inline bool is_armv8_4_sel2_present(void)
|
||||
{
|
||||
return ((read_id_aa64pfr0_el1() >> ID_AA64PFR0_SEL2_SHIFT) &
|
||||
ID_AA64PFR0_SEL2_MASK) == 1ULL;
|
||||
}
|
||||
|
||||
static inline bool is_armv8_6_twed_present(void)
|
||||
{
|
||||
return (((read_id_aa64mmfr1_el1() >> ID_AA64MMFR1_EL1_TWED_SHIFT) &
|
||||
ID_AA64MMFR1_EL1_TWED_MASK) == ID_AA64MMFR1_EL1_TWED_SUPPORTED);
|
||||
}
|
||||
|
||||
static inline bool is_armv8_6_fgt_present(void)
|
||||
{
|
||||
return ((read_id_aa64mmfr0_el1() >> ID_AA64MMFR0_EL1_FGT_SHIFT) &
|
||||
ID_AA64MMFR0_EL1_FGT_MASK) != 0U;
|
||||
}
|
||||
|
||||
static inline unsigned long int get_armv8_6_ecv_support(void)
|
||||
{
|
||||
return ((read_id_aa64mmfr0_el1() >> ID_AA64MMFR0_EL1_ECV_SHIFT) &
|
||||
ID_AA64MMFR0_EL1_ECV_MASK);
|
||||
}
|
||||
|
||||
static inline bool is_armv8_5_rng_present(void)
|
||||
{
|
||||
return ((read_id_aa64isar0_el1() >> ID_AA64ISAR0_RNDR_SHIFT) &
|
||||
ID_AA64ISAR0_RNDR_MASK);
|
||||
}
|
||||
|
||||
static inline bool is_armv8_6_feat_amuv1p1_present(void)
|
||||
{
|
||||
return (((read_id_aa64pfr0_el1() >> ID_AA64PFR0_AMU_SHIFT) &
|
||||
ID_AA64PFR0_AMU_MASK) >= ID_AA64PFR0_AMU_V1P1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return MPAM version:
|
||||
*
|
||||
* 0x00: None Armv8.0 or later
|
||||
* 0x01: v0.1 Armv8.4 or later
|
||||
* 0x10: v1.0 Armv8.2 or later
|
||||
* 0x11: v1.1 Armv8.4 or later
|
||||
*
|
||||
*/
|
||||
static inline unsigned int get_mpam_version(void)
|
||||
{
|
||||
return (unsigned int)((((read_id_aa64pfr0_el1() >>
|
||||
ID_AA64PFR0_MPAM_SHIFT) & ID_AA64PFR0_MPAM_MASK) << 4) |
|
||||
((read_id_aa64pfr1_el1() >>
|
||||
ID_AA64PFR1_MPAM_FRAC_SHIFT) & ID_AA64PFR1_MPAM_FRAC_MASK));
|
||||
}
|
||||
|
||||
static inline bool is_feat_hcx_present(void)
|
||||
{
|
||||
return (((read_id_aa64mmfr1_el1() >> ID_AA64MMFR1_EL1_HCX_SHIFT) &
|
||||
ID_AA64MMFR1_EL1_HCX_MASK) == ID_AA64MMFR1_EL1_HCX_SUPPORTED);
|
||||
}
|
||||
|
||||
static inline bool is_feat_rng_trap_present(void)
|
||||
{
|
||||
return (((read_id_aa64pfr1_el1() >> ID_AA64PFR1_EL1_RNDR_TRAP_SHIFT) &
|
||||
ID_AA64PFR1_EL1_RNDR_TRAP_MASK)
|
||||
== ID_AA64PFR1_EL1_RNG_TRAP_SUPPORTED);
|
||||
}
|
||||
|
||||
static inline unsigned int get_armv9_2_feat_rme_support(void)
|
||||
{
|
||||
/*
|
||||
* Return the RME version, zero if not supported. This function can be
|
||||
* used as both an integer value for the RME version or compared to zero
|
||||
* to detect RME presence.
|
||||
*/
|
||||
return (unsigned int)(read_id_aa64pfr0_el1() >>
|
||||
ID_AA64PFR0_FEAT_RME_SHIFT) & ID_AA64PFR0_FEAT_RME_MASK;
|
||||
}
|
||||
|
||||
/*********************************************************************************
|
||||
* Function to identify the presence of FEAT_SB (Speculation Barrier Instruction)
|
||||
********************************************************************************/
|
||||
static inline bool is_armv8_0_feat_sb_present(void)
|
||||
{
|
||||
return (((read_id_aa64isar1_el1() >> ID_AA64ISAR1_SB_SHIFT) &
|
||||
ID_AA64ISAR1_SB_MASK) == ID_AA64ISAR1_SB_SUPPORTED);
|
||||
}
|
||||
|
||||
/*********************************************************************************
|
||||
* Function to identify the presence of FEAT_CSV2_2 (Cache Speculation Variant 2)
|
||||
********************************************************************************/
|
||||
static inline bool is_armv8_0_feat_csv2_2_present(void)
|
||||
{
|
||||
return (((read_id_aa64pfr0_el1() >> ID_AA64PFR0_CSV2_SHIFT) &
|
||||
ID_AA64PFR0_CSV2_MASK) == ID_AA64PFR0_CSV2_2_SUPPORTED);
|
||||
}
|
||||
|
||||
/**********************************************************************************
|
||||
* Function to identify the presence of FEAT_SPE (Statistical Profiling Extension)
|
||||
*********************************************************************************/
|
||||
static inline bool is_armv8_2_feat_spe_present(void)
|
||||
{
|
||||
return (((read_id_aa64dfr0_el1() >> ID_AA64DFR0_PMS_SHIFT) &
|
||||
ID_AA64DFR0_PMS_MASK) != ID_AA64DFR0_SPE_NOT_SUPPORTED);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Function to identify the presence of FEAT_SVE (Scalable Vector Extension)
|
||||
******************************************************************************/
|
||||
static inline bool is_armv8_2_feat_sve_present(void)
|
||||
{
|
||||
return (((read_id_aa64pfr0_el1() >> ID_AA64PFR0_SVE_SHIFT) &
|
||||
ID_AA64PFR0_SVE_MASK) == ID_AA64PFR0_SVE_SUPPORTED);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Function to identify the presence of FEAT_RAS (Reliability,Availability,
|
||||
* and Serviceability Extension)
|
||||
******************************************************************************/
|
||||
static inline bool is_armv8_2_feat_ras_present(void)
|
||||
{
|
||||
return (((read_id_aa64pfr0_el1() >> ID_AA64PFR0_RAS_SHIFT) &
|
||||
ID_AA64PFR0_RAS_MASK) != ID_AA64PFR0_RAS_NOT_SUPPORTED);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* Function to identify the presence of FEAT_DIT (Data Independent Timing)
|
||||
*************************************************************************/
|
||||
static inline bool is_armv8_4_feat_dit_present(void)
|
||||
{
|
||||
return (((read_id_aa64pfr0_el1() >> ID_AA64PFR0_DIT_SHIFT) &
|
||||
ID_AA64PFR0_DIT_MASK) == ID_AA64PFR0_DIT_SUPPORTED);
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* Function to identify the presence of FEAT_TRF (TraceLift)
|
||||
************************************************************************/
|
||||
static inline bool is_arm8_4_feat_trf_present(void)
|
||||
{
|
||||
return (((read_id_aa64dfr0_el1() >> ID_AA64DFR0_TRACEFILT_SHIFT) &
|
||||
ID_AA64DFR0_TRACEFILT_MASK) == ID_AA64DFR0_TRACEFILT_SUPPORTED);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Function to identify the presence of FEAT_AMUv1 (Activity Monitors-
|
||||
* Extension v1)
|
||||
******************************************************************************/
|
||||
static inline bool is_armv8_4_feat_amuv1_present(void)
|
||||
{
|
||||
return (((read_id_aa64pfr0_el1() >> ID_AA64PFR0_AMU_SHIFT) &
|
||||
ID_AA64PFR0_AMU_MASK) >= ID_AA64PFR0_AMU_V1);
|
||||
}
|
||||
|
||||
/********************************************************************************
|
||||
* Function to identify the presence of FEAT_NV2 (Enhanced Nested Virtualization
|
||||
* Support)
|
||||
*******************************************************************************/
|
||||
static inline unsigned int get_armv8_4_feat_nv_support(void)
|
||||
{
|
||||
return (((read_id_aa64mmfr2_el1() >> ID_AA64MMFR2_EL1_NV_SHIFT) &
|
||||
ID_AA64MMFR2_EL1_NV_MASK));
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Function to identify the presence of FEAT_BRBE (Branch Record Buffer
|
||||
* Extension)
|
||||
******************************************************************************/
|
||||
static inline bool is_feat_brbe_present(void)
|
||||
{
|
||||
return (((read_id_aa64dfr0_el1() >> ID_AA64DFR0_BRBE_SHIFT) &
|
||||
ID_AA64DFR0_BRBE_MASK) == ID_AA64DFR0_BRBE_SUPPORTED);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Function to identify the presence of FEAT_TRBE (Trace Buffer Extension)
|
||||
******************************************************************************/
|
||||
static inline bool is_feat_trbe_present(void)
|
||||
{
|
||||
return (((read_id_aa64dfr0_el1() >> ID_AA64DFR0_TRACEBUFFER_SHIFT) &
|
||||
ID_AA64DFR0_TRACEBUFFER_MASK) == ID_AA64DFR0_TRACEBUFFER_SUPPORTED);
|
||||
}
|
||||
|
||||
#endif /* ARCH_FEATURES_H */
|
||||
@@ -0,0 +1,671 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2022, Arm Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef ARCH_HELPERS_H
|
||||
#define ARCH_HELPERS_H
|
||||
|
||||
#include <cdefs.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <arch.h>
|
||||
|
||||
/**********************************************************************
|
||||
* Macros which create inline functions to read or write CPU system
|
||||
* registers
|
||||
*********************************************************************/
|
||||
|
||||
#define _DEFINE_SYSREG_READ_FUNC(_name, _reg_name) \
|
||||
static inline u_register_t read_ ## _name(void) \
|
||||
{ \
|
||||
u_register_t v; \
|
||||
__asm__ volatile ("mrs %0, " #_reg_name : "=r" (v)); \
|
||||
return v; \
|
||||
}
|
||||
|
||||
#define _DEFINE_SYSREG_WRITE_FUNC(_name, _reg_name) \
|
||||
static inline void write_ ## _name(u_register_t v) \
|
||||
{ \
|
||||
__asm__ volatile ("msr " #_reg_name ", %0" : : "r" (v)); \
|
||||
}
|
||||
|
||||
#define SYSREG_WRITE_CONST(reg_name, v) \
|
||||
__asm__ volatile ("msr " #reg_name ", %0" : : "i" (v))
|
||||
|
||||
/* Define read function for system register */
|
||||
#define DEFINE_SYSREG_READ_FUNC(_name) \
|
||||
_DEFINE_SYSREG_READ_FUNC(_name, _name)
|
||||
|
||||
/* Define read & write function for system register */
|
||||
#define DEFINE_SYSREG_RW_FUNCS(_name) \
|
||||
_DEFINE_SYSREG_READ_FUNC(_name, _name) \
|
||||
_DEFINE_SYSREG_WRITE_FUNC(_name, _name)
|
||||
|
||||
/* Define read & write function for renamed system register */
|
||||
#define DEFINE_RENAME_SYSREG_RW_FUNCS(_name, _reg_name) \
|
||||
_DEFINE_SYSREG_READ_FUNC(_name, _reg_name) \
|
||||
_DEFINE_SYSREG_WRITE_FUNC(_name, _reg_name)
|
||||
|
||||
/* Define read function for renamed system register */
|
||||
#define DEFINE_RENAME_SYSREG_READ_FUNC(_name, _reg_name) \
|
||||
_DEFINE_SYSREG_READ_FUNC(_name, _reg_name)
|
||||
|
||||
/* Define write function for renamed system register */
|
||||
#define DEFINE_RENAME_SYSREG_WRITE_FUNC(_name, _reg_name) \
|
||||
_DEFINE_SYSREG_WRITE_FUNC(_name, _reg_name)
|
||||
|
||||
/**********************************************************************
|
||||
* Macros to create inline functions for system instructions
|
||||
*********************************************************************/
|
||||
|
||||
/* Define function for simple system instruction */
|
||||
#define DEFINE_SYSOP_FUNC(_op) \
|
||||
static inline void _op(void) \
|
||||
{ \
|
||||
__asm__ (#_op); \
|
||||
}
|
||||
|
||||
/* Define function for system instruction with register parameter */
|
||||
#define DEFINE_SYSOP_PARAM_FUNC(_op) \
|
||||
static inline void _op(uint64_t v) \
|
||||
{ \
|
||||
__asm__ (#_op " %0" : : "r" (v)); \
|
||||
}
|
||||
|
||||
/* Define function for system instruction with type specifier */
|
||||
#define DEFINE_SYSOP_TYPE_FUNC(_op, _type) \
|
||||
static inline void _op ## _type(void) \
|
||||
{ \
|
||||
__asm__ (#_op " " #_type : : : "memory"); \
|
||||
}
|
||||
|
||||
/* Define function for system instruction with register parameter */
|
||||
#define DEFINE_SYSOP_TYPE_PARAM_FUNC(_op, _type) \
|
||||
static inline void _op ## _type(uint64_t v) \
|
||||
{ \
|
||||
__asm__ (#_op " " #_type ", %0" : : "r" (v)); \
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* TLB maintenance accessor prototypes
|
||||
******************************************************************************/
|
||||
|
||||
#if ERRATA_A57_813419 || ERRATA_A76_1286807
|
||||
/*
|
||||
* Define function for TLBI instruction with type specifier that implements
|
||||
* the workaround for errata 813419 of Cortex-A57 or errata 1286807 of
|
||||
* Cortex-A76.
|
||||
*/
|
||||
#define DEFINE_TLBIOP_ERRATA_TYPE_FUNC(_type)\
|
||||
static inline void tlbi ## _type(void) \
|
||||
{ \
|
||||
__asm__("tlbi " #_type "\n" \
|
||||
"dsb ish\n" \
|
||||
"tlbi " #_type); \
|
||||
}
|
||||
|
||||
/*
|
||||
* Define function for TLBI instruction with register parameter that implements
|
||||
* the workaround for errata 813419 of Cortex-A57 or errata 1286807 of
|
||||
* Cortex-A76.
|
||||
*/
|
||||
#define DEFINE_TLBIOP_ERRATA_TYPE_PARAM_FUNC(_type) \
|
||||
static inline void tlbi ## _type(uint64_t v) \
|
||||
{ \
|
||||
__asm__("tlbi " #_type ", %0\n" \
|
||||
"dsb ish\n" \
|
||||
"tlbi " #_type ", %0" : : "r" (v)); \
|
||||
}
|
||||
#endif /* ERRATA_A57_813419 */
|
||||
|
||||
#if ERRATA_A53_819472 || ERRATA_A53_824069 || ERRATA_A53_827319
|
||||
/*
|
||||
* Define function for DC instruction with register parameter that enables
|
||||
* the workaround for errata 819472, 824069 and 827319 of Cortex-A53.
|
||||
*/
|
||||
#define DEFINE_DCOP_ERRATA_A53_TYPE_PARAM_FUNC(_name, _type) \
|
||||
static inline void dc ## _name(uint64_t v) \
|
||||
{ \
|
||||
__asm__("dc " #_type ", %0" : : "r" (v)); \
|
||||
}
|
||||
#endif /* ERRATA_A53_819472 || ERRATA_A53_824069 || ERRATA_A53_827319 */
|
||||
|
||||
#if ERRATA_A57_813419
|
||||
DEFINE_SYSOP_TYPE_FUNC(tlbi, alle1)
|
||||
DEFINE_SYSOP_TYPE_FUNC(tlbi, alle1is)
|
||||
DEFINE_SYSOP_TYPE_FUNC(tlbi, alle2)
|
||||
DEFINE_SYSOP_TYPE_FUNC(tlbi, alle2is)
|
||||
DEFINE_TLBIOP_ERRATA_TYPE_FUNC(alle3)
|
||||
DEFINE_TLBIOP_ERRATA_TYPE_FUNC(alle3is)
|
||||
DEFINE_SYSOP_TYPE_FUNC(tlbi, vmalle1)
|
||||
#elif ERRATA_A76_1286807
|
||||
DEFINE_TLBIOP_ERRATA_TYPE_FUNC(alle1)
|
||||
DEFINE_TLBIOP_ERRATA_TYPE_FUNC(alle1is)
|
||||
DEFINE_TLBIOP_ERRATA_TYPE_FUNC(alle2)
|
||||
DEFINE_TLBIOP_ERRATA_TYPE_FUNC(alle2is)
|
||||
DEFINE_TLBIOP_ERRATA_TYPE_FUNC(alle3)
|
||||
DEFINE_TLBIOP_ERRATA_TYPE_FUNC(alle3is)
|
||||
DEFINE_TLBIOP_ERRATA_TYPE_FUNC(vmalle1)
|
||||
#else
|
||||
DEFINE_SYSOP_TYPE_FUNC(tlbi, alle1)
|
||||
DEFINE_SYSOP_TYPE_FUNC(tlbi, alle1is)
|
||||
DEFINE_SYSOP_TYPE_FUNC(tlbi, alle2)
|
||||
DEFINE_SYSOP_TYPE_FUNC(tlbi, alle2is)
|
||||
DEFINE_SYSOP_TYPE_FUNC(tlbi, alle3)
|
||||
DEFINE_SYSOP_TYPE_FUNC(tlbi, alle3is)
|
||||
DEFINE_SYSOP_TYPE_FUNC(tlbi, vmalle1)
|
||||
#endif
|
||||
|
||||
#if ERRATA_A57_813419
|
||||
DEFINE_SYSOP_TYPE_PARAM_FUNC(tlbi, vaae1is)
|
||||
DEFINE_SYSOP_TYPE_PARAM_FUNC(tlbi, vaale1is)
|
||||
DEFINE_SYSOP_TYPE_PARAM_FUNC(tlbi, vae2is)
|
||||
DEFINE_SYSOP_TYPE_PARAM_FUNC(tlbi, vale2is)
|
||||
DEFINE_TLBIOP_ERRATA_TYPE_PARAM_FUNC(vae3is)
|
||||
DEFINE_TLBIOP_ERRATA_TYPE_PARAM_FUNC(vale3is)
|
||||
#elif ERRATA_A76_1286807
|
||||
DEFINE_TLBIOP_ERRATA_TYPE_PARAM_FUNC(vaae1is)
|
||||
DEFINE_TLBIOP_ERRATA_TYPE_PARAM_FUNC(vaale1is)
|
||||
DEFINE_TLBIOP_ERRATA_TYPE_PARAM_FUNC(vae2is)
|
||||
DEFINE_TLBIOP_ERRATA_TYPE_PARAM_FUNC(vale2is)
|
||||
DEFINE_TLBIOP_ERRATA_TYPE_PARAM_FUNC(vae3is)
|
||||
DEFINE_TLBIOP_ERRATA_TYPE_PARAM_FUNC(vale3is)
|
||||
#else
|
||||
DEFINE_SYSOP_TYPE_PARAM_FUNC(tlbi, vaae1is)
|
||||
DEFINE_SYSOP_TYPE_PARAM_FUNC(tlbi, vaale1is)
|
||||
DEFINE_SYSOP_TYPE_PARAM_FUNC(tlbi, vae2is)
|
||||
DEFINE_SYSOP_TYPE_PARAM_FUNC(tlbi, vale2is)
|
||||
DEFINE_SYSOP_TYPE_PARAM_FUNC(tlbi, vae3is)
|
||||
DEFINE_SYSOP_TYPE_PARAM_FUNC(tlbi, vale3is)
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
* Cache maintenance accessor prototypes
|
||||
******************************************************************************/
|
||||
DEFINE_SYSOP_TYPE_PARAM_FUNC(dc, isw)
|
||||
DEFINE_SYSOP_TYPE_PARAM_FUNC(dc, cisw)
|
||||
#if ERRATA_A53_827319
|
||||
DEFINE_DCOP_ERRATA_A53_TYPE_PARAM_FUNC(csw, cisw)
|
||||
#else
|
||||
DEFINE_SYSOP_TYPE_PARAM_FUNC(dc, csw)
|
||||
#endif
|
||||
#if ERRATA_A53_819472 || ERRATA_A53_824069 || ERRATA_A53_827319
|
||||
DEFINE_DCOP_ERRATA_A53_TYPE_PARAM_FUNC(cvac, civac)
|
||||
#else
|
||||
DEFINE_SYSOP_TYPE_PARAM_FUNC(dc, cvac)
|
||||
#endif
|
||||
DEFINE_SYSOP_TYPE_PARAM_FUNC(dc, ivac)
|
||||
DEFINE_SYSOP_TYPE_PARAM_FUNC(dc, civac)
|
||||
#if ERRATA_A53_819472 || ERRATA_A53_824069 || ERRATA_A53_827319
|
||||
DEFINE_DCOP_ERRATA_A53_TYPE_PARAM_FUNC(cvau, civac)
|
||||
#else
|
||||
DEFINE_SYSOP_TYPE_PARAM_FUNC(dc, cvau)
|
||||
#endif
|
||||
DEFINE_SYSOP_TYPE_PARAM_FUNC(dc, zva)
|
||||
|
||||
/*******************************************************************************
|
||||
* Address translation accessor prototypes
|
||||
******************************************************************************/
|
||||
DEFINE_SYSOP_TYPE_PARAM_FUNC(at, s12e1r)
|
||||
DEFINE_SYSOP_TYPE_PARAM_FUNC(at, s12e1w)
|
||||
DEFINE_SYSOP_TYPE_PARAM_FUNC(at, s12e0r)
|
||||
DEFINE_SYSOP_TYPE_PARAM_FUNC(at, s12e0w)
|
||||
DEFINE_SYSOP_TYPE_PARAM_FUNC(at, s1e1r)
|
||||
DEFINE_SYSOP_TYPE_PARAM_FUNC(at, s1e2r)
|
||||
DEFINE_SYSOP_TYPE_PARAM_FUNC(at, s1e3r)
|
||||
|
||||
/*******************************************************************************
|
||||
* Strip Pointer Authentication Code
|
||||
******************************************************************************/
|
||||
DEFINE_SYSOP_PARAM_FUNC(xpaci)
|
||||
|
||||
void flush_dcache_range(uintptr_t addr, size_t size);
|
||||
void flush_dcache_to_popa_range(uintptr_t addr, size_t size);
|
||||
void clean_dcache_range(uintptr_t addr, size_t size);
|
||||
void inv_dcache_range(uintptr_t addr, size_t size);
|
||||
bool is_dcache_enabled(void);
|
||||
|
||||
void dcsw_op_louis(u_register_t op_type);
|
||||
void dcsw_op_all(u_register_t op_type);
|
||||
|
||||
void disable_mmu_el1(void);
|
||||
void disable_mmu_el3(void);
|
||||
void disable_mpu_el2(void);
|
||||
void disable_mmu_icache_el1(void);
|
||||
void disable_mmu_icache_el3(void);
|
||||
void disable_mpu_icache_el2(void);
|
||||
|
||||
/*******************************************************************************
|
||||
* Misc. accessor prototypes
|
||||
******************************************************************************/
|
||||
|
||||
#define write_daifclr(val) SYSREG_WRITE_CONST(daifclr, val)
|
||||
#define write_daifset(val) SYSREG_WRITE_CONST(daifset, val)
|
||||
|
||||
DEFINE_SYSREG_RW_FUNCS(par_el1)
|
||||
DEFINE_SYSREG_READ_FUNC(id_pfr1_el1)
|
||||
DEFINE_SYSREG_READ_FUNC(id_aa64isar0_el1)
|
||||
DEFINE_SYSREG_READ_FUNC(id_aa64isar1_el1)
|
||||
DEFINE_RENAME_SYSREG_READ_FUNC(id_aa64isar2_el1, ID_AA64ISAR2_EL1)
|
||||
DEFINE_SYSREG_READ_FUNC(id_aa64pfr0_el1)
|
||||
DEFINE_SYSREG_READ_FUNC(id_aa64pfr1_el1)
|
||||
DEFINE_SYSREG_READ_FUNC(id_aa64dfr0_el1)
|
||||
DEFINE_SYSREG_READ_FUNC(id_afr0_el1)
|
||||
DEFINE_SYSREG_READ_FUNC(CurrentEl)
|
||||
DEFINE_SYSREG_READ_FUNC(ctr_el0)
|
||||
DEFINE_SYSREG_RW_FUNCS(daif)
|
||||
DEFINE_SYSREG_RW_FUNCS(spsr_el1)
|
||||
DEFINE_SYSREG_RW_FUNCS(spsr_el2)
|
||||
DEFINE_SYSREG_RW_FUNCS(spsr_el3)
|
||||
DEFINE_SYSREG_RW_FUNCS(elr_el1)
|
||||
DEFINE_SYSREG_RW_FUNCS(elr_el2)
|
||||
DEFINE_SYSREG_RW_FUNCS(elr_el3)
|
||||
DEFINE_SYSREG_RW_FUNCS(mdccsr_el0)
|
||||
DEFINE_SYSREG_RW_FUNCS(dbgdtrrx_el0)
|
||||
DEFINE_SYSREG_RW_FUNCS(dbgdtrtx_el0)
|
||||
DEFINE_SYSREG_RW_FUNCS(sp_el1)
|
||||
DEFINE_SYSREG_RW_FUNCS(sp_el2)
|
||||
|
||||
DEFINE_SYSOP_FUNC(wfi)
|
||||
DEFINE_SYSOP_FUNC(wfe)
|
||||
DEFINE_SYSOP_FUNC(sev)
|
||||
DEFINE_SYSOP_TYPE_FUNC(dsb, sy)
|
||||
DEFINE_SYSOP_TYPE_FUNC(dmb, sy)
|
||||
DEFINE_SYSOP_TYPE_FUNC(dmb, st)
|
||||
DEFINE_SYSOP_TYPE_FUNC(dmb, ld)
|
||||
DEFINE_SYSOP_TYPE_FUNC(dsb, ish)
|
||||
DEFINE_SYSOP_TYPE_FUNC(dsb, osh)
|
||||
DEFINE_SYSOP_TYPE_FUNC(dsb, nsh)
|
||||
DEFINE_SYSOP_TYPE_FUNC(dsb, ishst)
|
||||
DEFINE_SYSOP_TYPE_FUNC(dsb, oshst)
|
||||
DEFINE_SYSOP_TYPE_FUNC(dmb, oshld)
|
||||
DEFINE_SYSOP_TYPE_FUNC(dmb, oshst)
|
||||
DEFINE_SYSOP_TYPE_FUNC(dmb, osh)
|
||||
DEFINE_SYSOP_TYPE_FUNC(dmb, nshld)
|
||||
DEFINE_SYSOP_TYPE_FUNC(dmb, nshst)
|
||||
DEFINE_SYSOP_TYPE_FUNC(dmb, nsh)
|
||||
DEFINE_SYSOP_TYPE_FUNC(dmb, ishld)
|
||||
DEFINE_SYSOP_TYPE_FUNC(dmb, ishst)
|
||||
DEFINE_SYSOP_TYPE_FUNC(dmb, ish)
|
||||
DEFINE_SYSOP_FUNC(isb)
|
||||
|
||||
static inline void enable_irq(void)
|
||||
{
|
||||
/*
|
||||
* The compiler memory barrier will prevent the compiler from
|
||||
* scheduling non-volatile memory access after the write to the
|
||||
* register.
|
||||
*
|
||||
* This could happen if some initialization code issues non-volatile
|
||||
* accesses to an area used by an interrupt handler, in the assumption
|
||||
* that it is safe as the interrupts are disabled at the time it does
|
||||
* that (according to program order). However, non-volatile accesses
|
||||
* are not necessarily in program order relatively with volatile inline
|
||||
* assembly statements (and volatile accesses).
|
||||
*/
|
||||
COMPILER_BARRIER();
|
||||
write_daifclr(DAIF_IRQ_BIT);
|
||||
isb();
|
||||
}
|
||||
|
||||
static inline void enable_fiq(void)
|
||||
{
|
||||
COMPILER_BARRIER();
|
||||
write_daifclr(DAIF_FIQ_BIT);
|
||||
isb();
|
||||
}
|
||||
|
||||
static inline void enable_serror(void)
|
||||
{
|
||||
COMPILER_BARRIER();
|
||||
write_daifclr(DAIF_ABT_BIT);
|
||||
isb();
|
||||
}
|
||||
|
||||
static inline void enable_debug_exceptions(void)
|
||||
{
|
||||
COMPILER_BARRIER();
|
||||
write_daifclr(DAIF_DBG_BIT);
|
||||
isb();
|
||||
}
|
||||
|
||||
static inline void disable_irq(void)
|
||||
{
|
||||
COMPILER_BARRIER();
|
||||
write_daifset(DAIF_IRQ_BIT);
|
||||
isb();
|
||||
}
|
||||
|
||||
static inline void disable_fiq(void)
|
||||
{
|
||||
COMPILER_BARRIER();
|
||||
write_daifset(DAIF_FIQ_BIT);
|
||||
isb();
|
||||
}
|
||||
|
||||
static inline void disable_serror(void)
|
||||
{
|
||||
COMPILER_BARRIER();
|
||||
write_daifset(DAIF_ABT_BIT);
|
||||
isb();
|
||||
}
|
||||
|
||||
static inline void disable_debug_exceptions(void)
|
||||
{
|
||||
COMPILER_BARRIER();
|
||||
write_daifset(DAIF_DBG_BIT);
|
||||
isb();
|
||||
}
|
||||
|
||||
void __dead2 smc(uint64_t x0, uint64_t x1, uint64_t x2, uint64_t x3,
|
||||
uint64_t x4, uint64_t x5, uint64_t x6, uint64_t x7);
|
||||
|
||||
/*******************************************************************************
|
||||
* System register accessor prototypes
|
||||
******************************************************************************/
|
||||
DEFINE_SYSREG_READ_FUNC(midr_el1)
|
||||
DEFINE_SYSREG_READ_FUNC(mpidr_el1)
|
||||
DEFINE_SYSREG_READ_FUNC(id_aa64mmfr0_el1)
|
||||
DEFINE_SYSREG_READ_FUNC(id_aa64mmfr1_el1)
|
||||
|
||||
DEFINE_SYSREG_RW_FUNCS(scr_el3)
|
||||
DEFINE_SYSREG_RW_FUNCS(hcr_el2)
|
||||
|
||||
DEFINE_SYSREG_RW_FUNCS(vbar_el1)
|
||||
DEFINE_SYSREG_RW_FUNCS(vbar_el2)
|
||||
DEFINE_SYSREG_RW_FUNCS(vbar_el3)
|
||||
|
||||
DEFINE_SYSREG_RW_FUNCS(sctlr_el1)
|
||||
DEFINE_SYSREG_RW_FUNCS(sctlr_el2)
|
||||
DEFINE_SYSREG_RW_FUNCS(sctlr_el3)
|
||||
|
||||
DEFINE_SYSREG_RW_FUNCS(actlr_el1)
|
||||
DEFINE_SYSREG_RW_FUNCS(actlr_el2)
|
||||
DEFINE_SYSREG_RW_FUNCS(actlr_el3)
|
||||
|
||||
DEFINE_SYSREG_RW_FUNCS(esr_el1)
|
||||
DEFINE_SYSREG_RW_FUNCS(esr_el2)
|
||||
DEFINE_SYSREG_RW_FUNCS(esr_el3)
|
||||
|
||||
DEFINE_SYSREG_RW_FUNCS(afsr0_el1)
|
||||
DEFINE_SYSREG_RW_FUNCS(afsr0_el2)
|
||||
DEFINE_SYSREG_RW_FUNCS(afsr0_el3)
|
||||
|
||||
DEFINE_SYSREG_RW_FUNCS(afsr1_el1)
|
||||
DEFINE_SYSREG_RW_FUNCS(afsr1_el2)
|
||||
DEFINE_SYSREG_RW_FUNCS(afsr1_el3)
|
||||
|
||||
DEFINE_SYSREG_RW_FUNCS(far_el1)
|
||||
DEFINE_SYSREG_RW_FUNCS(far_el2)
|
||||
DEFINE_SYSREG_RW_FUNCS(far_el3)
|
||||
|
||||
DEFINE_SYSREG_RW_FUNCS(mair_el1)
|
||||
DEFINE_SYSREG_RW_FUNCS(mair_el2)
|
||||
DEFINE_SYSREG_RW_FUNCS(mair_el3)
|
||||
|
||||
DEFINE_SYSREG_RW_FUNCS(amair_el1)
|
||||
DEFINE_SYSREG_RW_FUNCS(amair_el2)
|
||||
DEFINE_SYSREG_RW_FUNCS(amair_el3)
|
||||
|
||||
DEFINE_SYSREG_READ_FUNC(rvbar_el1)
|
||||
DEFINE_SYSREG_READ_FUNC(rvbar_el2)
|
||||
DEFINE_SYSREG_READ_FUNC(rvbar_el3)
|
||||
|
||||
DEFINE_SYSREG_RW_FUNCS(rmr_el1)
|
||||
DEFINE_SYSREG_RW_FUNCS(rmr_el2)
|
||||
DEFINE_SYSREG_RW_FUNCS(rmr_el3)
|
||||
|
||||
DEFINE_SYSREG_RW_FUNCS(tcr_el1)
|
||||
DEFINE_SYSREG_RW_FUNCS(tcr_el2)
|
||||
DEFINE_SYSREG_RW_FUNCS(tcr_el3)
|
||||
|
||||
DEFINE_SYSREG_RW_FUNCS(ttbr0_el1)
|
||||
DEFINE_SYSREG_RW_FUNCS(ttbr0_el2)
|
||||
DEFINE_SYSREG_RW_FUNCS(ttbr0_el3)
|
||||
|
||||
DEFINE_SYSREG_RW_FUNCS(ttbr1_el1)
|
||||
|
||||
DEFINE_SYSREG_RW_FUNCS(vttbr_el2)
|
||||
|
||||
DEFINE_SYSREG_RW_FUNCS(cptr_el2)
|
||||
DEFINE_SYSREG_RW_FUNCS(cptr_el3)
|
||||
|
||||
DEFINE_SYSREG_RW_FUNCS(cpacr_el1)
|
||||
DEFINE_SYSREG_RW_FUNCS(cntfrq_el0)
|
||||
DEFINE_SYSREG_RW_FUNCS(cnthp_ctl_el2)
|
||||
DEFINE_SYSREG_RW_FUNCS(cnthp_tval_el2)
|
||||
DEFINE_SYSREG_RW_FUNCS(cnthp_cval_el2)
|
||||
DEFINE_SYSREG_RW_FUNCS(cntps_ctl_el1)
|
||||
DEFINE_SYSREG_RW_FUNCS(cntps_tval_el1)
|
||||
DEFINE_SYSREG_RW_FUNCS(cntps_cval_el1)
|
||||
DEFINE_SYSREG_RW_FUNCS(cntp_ctl_el0)
|
||||
DEFINE_SYSREG_RW_FUNCS(cntp_tval_el0)
|
||||
DEFINE_SYSREG_RW_FUNCS(cntp_cval_el0)
|
||||
DEFINE_SYSREG_READ_FUNC(cntpct_el0)
|
||||
DEFINE_SYSREG_RW_FUNCS(cnthctl_el2)
|
||||
|
||||
DEFINE_SYSREG_RW_FUNCS(vtcr_el2)
|
||||
|
||||
#define get_cntp_ctl_enable(x) (((x) >> CNTP_CTL_ENABLE_SHIFT) & \
|
||||
CNTP_CTL_ENABLE_MASK)
|
||||
#define get_cntp_ctl_imask(x) (((x) >> CNTP_CTL_IMASK_SHIFT) & \
|
||||
CNTP_CTL_IMASK_MASK)
|
||||
#define get_cntp_ctl_istatus(x) (((x) >> CNTP_CTL_ISTATUS_SHIFT) & \
|
||||
CNTP_CTL_ISTATUS_MASK)
|
||||
|
||||
#define set_cntp_ctl_enable(x) ((x) |= (U(1) << CNTP_CTL_ENABLE_SHIFT))
|
||||
#define set_cntp_ctl_imask(x) ((x) |= (U(1) << CNTP_CTL_IMASK_SHIFT))
|
||||
|
||||
#define clr_cntp_ctl_enable(x) ((x) &= ~(U(1) << CNTP_CTL_ENABLE_SHIFT))
|
||||
#define clr_cntp_ctl_imask(x) ((x) &= ~(U(1) << CNTP_CTL_IMASK_SHIFT))
|
||||
|
||||
DEFINE_SYSREG_RW_FUNCS(tpidr_el3)
|
||||
|
||||
DEFINE_SYSREG_RW_FUNCS(cntvoff_el2)
|
||||
|
||||
DEFINE_SYSREG_RW_FUNCS(vpidr_el2)
|
||||
DEFINE_SYSREG_RW_FUNCS(vmpidr_el2)
|
||||
|
||||
DEFINE_SYSREG_READ_FUNC(isr_el1)
|
||||
|
||||
DEFINE_SYSREG_RW_FUNCS(mdcr_el2)
|
||||
DEFINE_SYSREG_RW_FUNCS(mdcr_el3)
|
||||
DEFINE_SYSREG_RW_FUNCS(hstr_el2)
|
||||
DEFINE_SYSREG_RW_FUNCS(pmcr_el0)
|
||||
|
||||
/* GICv3 System Registers */
|
||||
|
||||
DEFINE_RENAME_SYSREG_RW_FUNCS(icc_sre_el1, ICC_SRE_EL1)
|
||||
DEFINE_RENAME_SYSREG_RW_FUNCS(icc_sre_el2, ICC_SRE_EL2)
|
||||
DEFINE_RENAME_SYSREG_RW_FUNCS(icc_sre_el3, ICC_SRE_EL3)
|
||||
DEFINE_RENAME_SYSREG_RW_FUNCS(icc_pmr_el1, ICC_PMR_EL1)
|
||||
DEFINE_RENAME_SYSREG_READ_FUNC(icc_rpr_el1, ICC_RPR_EL1)
|
||||
DEFINE_RENAME_SYSREG_RW_FUNCS(icc_igrpen1_el3, ICC_IGRPEN1_EL3)
|
||||
DEFINE_RENAME_SYSREG_RW_FUNCS(icc_igrpen1_el1, ICC_IGRPEN1_EL1)
|
||||
DEFINE_RENAME_SYSREG_RW_FUNCS(icc_igrpen0_el1, ICC_IGRPEN0_EL1)
|
||||
DEFINE_RENAME_SYSREG_READ_FUNC(icc_hppir0_el1, ICC_HPPIR0_EL1)
|
||||
DEFINE_RENAME_SYSREG_READ_FUNC(icc_hppir1_el1, ICC_HPPIR1_EL1)
|
||||
DEFINE_RENAME_SYSREG_READ_FUNC(icc_iar0_el1, ICC_IAR0_EL1)
|
||||
DEFINE_RENAME_SYSREG_READ_FUNC(icc_iar1_el1, ICC_IAR1_EL1)
|
||||
DEFINE_RENAME_SYSREG_WRITE_FUNC(icc_eoir0_el1, ICC_EOIR0_EL1)
|
||||
DEFINE_RENAME_SYSREG_WRITE_FUNC(icc_eoir1_el1, ICC_EOIR1_EL1)
|
||||
DEFINE_RENAME_SYSREG_WRITE_FUNC(icc_sgi0r_el1, ICC_SGI0R_EL1)
|
||||
DEFINE_RENAME_SYSREG_RW_FUNCS(icc_sgi1r, ICC_SGI1R)
|
||||
DEFINE_RENAME_SYSREG_RW_FUNCS(icc_asgi1r, ICC_ASGI1R)
|
||||
|
||||
DEFINE_RENAME_SYSREG_READ_FUNC(amcfgr_el0, AMCFGR_EL0)
|
||||
DEFINE_RENAME_SYSREG_READ_FUNC(amcgcr_el0, AMCGCR_EL0)
|
||||
DEFINE_RENAME_SYSREG_READ_FUNC(amcg1idr_el0, AMCG1IDR_EL0)
|
||||
DEFINE_RENAME_SYSREG_RW_FUNCS(amcr_el0, AMCR_EL0)
|
||||
DEFINE_RENAME_SYSREG_RW_FUNCS(amcntenclr0_el0, AMCNTENCLR0_EL0)
|
||||
DEFINE_RENAME_SYSREG_RW_FUNCS(amcntenset0_el0, AMCNTENSET0_EL0)
|
||||
DEFINE_RENAME_SYSREG_RW_FUNCS(amcntenclr1_el0, AMCNTENCLR1_EL0)
|
||||
DEFINE_RENAME_SYSREG_RW_FUNCS(amcntenset1_el0, AMCNTENSET1_EL0)
|
||||
|
||||
DEFINE_RENAME_SYSREG_READ_FUNC(mpamidr_el1, MPAMIDR_EL1)
|
||||
DEFINE_RENAME_SYSREG_RW_FUNCS(mpam3_el3, MPAM3_EL3)
|
||||
DEFINE_RENAME_SYSREG_RW_FUNCS(mpam2_el2, MPAM2_EL2)
|
||||
DEFINE_RENAME_SYSREG_RW_FUNCS(mpamhcr_el2, MPAMHCR_EL2)
|
||||
|
||||
DEFINE_RENAME_SYSREG_RW_FUNCS(pmblimitr_el1, PMBLIMITR_EL1)
|
||||
|
||||
DEFINE_RENAME_SYSREG_WRITE_FUNC(zcr_el3, ZCR_EL3)
|
||||
DEFINE_RENAME_SYSREG_WRITE_FUNC(zcr_el2, ZCR_EL2)
|
||||
|
||||
DEFINE_RENAME_SYSREG_READ_FUNC(id_aa64smfr0_el1, ID_AA64SMFR0_EL1)
|
||||
DEFINE_RENAME_SYSREG_RW_FUNCS(smcr_el3, SMCR_EL3)
|
||||
|
||||
DEFINE_RENAME_SYSREG_READ_FUNC(erridr_el1, ERRIDR_EL1)
|
||||
DEFINE_RENAME_SYSREG_WRITE_FUNC(errselr_el1, ERRSELR_EL1)
|
||||
|
||||
DEFINE_RENAME_SYSREG_READ_FUNC(erxfr_el1, ERXFR_EL1)
|
||||
DEFINE_RENAME_SYSREG_RW_FUNCS(erxctlr_el1, ERXCTLR_EL1)
|
||||
DEFINE_RENAME_SYSREG_RW_FUNCS(erxstatus_el1, ERXSTATUS_EL1)
|
||||
DEFINE_RENAME_SYSREG_READ_FUNC(erxaddr_el1, ERXADDR_EL1)
|
||||
DEFINE_RENAME_SYSREG_READ_FUNC(erxmisc0_el1, ERXMISC0_EL1)
|
||||
DEFINE_RENAME_SYSREG_READ_FUNC(erxmisc1_el1, ERXMISC1_EL1)
|
||||
|
||||
/* Armv8.2 Registers */
|
||||
DEFINE_RENAME_SYSREG_READ_FUNC(id_aa64mmfr2_el1, ID_AA64MMFR2_EL1)
|
||||
|
||||
/* Armv8.3 Pointer Authentication Registers */
|
||||
DEFINE_RENAME_SYSREG_RW_FUNCS(apiakeyhi_el1, APIAKeyHi_EL1)
|
||||
DEFINE_RENAME_SYSREG_RW_FUNCS(apiakeylo_el1, APIAKeyLo_EL1)
|
||||
|
||||
/* Armv8.4 Data Independent Timing Register */
|
||||
DEFINE_RENAME_SYSREG_RW_FUNCS(dit, DIT)
|
||||
|
||||
/* Armv8.5 MTE Registers */
|
||||
DEFINE_RENAME_SYSREG_RW_FUNCS(tfsre0_el1, TFSRE0_EL1)
|
||||
DEFINE_RENAME_SYSREG_RW_FUNCS(tfsr_el1, TFSR_EL1)
|
||||
DEFINE_RENAME_SYSREG_RW_FUNCS(rgsr_el1, RGSR_EL1)
|
||||
DEFINE_RENAME_SYSREG_RW_FUNCS(gcr_el1, GCR_EL1)
|
||||
|
||||
/* Armv8.5 FEAT_RNG Registers */
|
||||
DEFINE_SYSREG_READ_FUNC(rndr)
|
||||
DEFINE_SYSREG_READ_FUNC(rndrrs)
|
||||
|
||||
/* FEAT_HCX Register */
|
||||
DEFINE_RENAME_SYSREG_RW_FUNCS(hcrx_el2, HCRX_EL2)
|
||||
|
||||
/* DynamIQ Shared Unit power management */
|
||||
DEFINE_RENAME_SYSREG_RW_FUNCS(clusterpwrdn_el1, CLUSTERPWRDN_EL1)
|
||||
|
||||
/* CPU Power/Performance Management registers */
|
||||
DEFINE_RENAME_SYSREG_RW_FUNCS(cpuppmcr_el3, CPUPPMCR_EL3)
|
||||
DEFINE_RENAME_SYSREG_RW_FUNCS(cpumpmmcr_el3, CPUMPMMCR_EL3)
|
||||
|
||||
/* Armv9.2 RME Registers */
|
||||
DEFINE_RENAME_SYSREG_RW_FUNCS(gptbr_el3, GPTBR_EL3)
|
||||
DEFINE_RENAME_SYSREG_RW_FUNCS(gpccr_el3, GPCCR_EL3)
|
||||
|
||||
#define IS_IN_EL(x) \
|
||||
(GET_EL(read_CurrentEl()) == MODE_EL##x)
|
||||
|
||||
#define IS_IN_EL1() IS_IN_EL(1)
|
||||
#define IS_IN_EL2() IS_IN_EL(2)
|
||||
#define IS_IN_EL3() IS_IN_EL(3)
|
||||
|
||||
static inline unsigned int get_current_el(void)
|
||||
{
|
||||
return GET_EL(read_CurrentEl());
|
||||
}
|
||||
|
||||
static inline unsigned int get_current_el_maybe_constant(void)
|
||||
{
|
||||
#if defined(IMAGE_AT_EL1)
|
||||
return 1;
|
||||
#elif defined(IMAGE_AT_EL2)
|
||||
return 2; /* no use-case in TF-A */
|
||||
#elif defined(IMAGE_AT_EL3)
|
||||
return 3;
|
||||
#else
|
||||
/*
|
||||
* If we do not know which exception level this is being built for
|
||||
* (e.g. built for library), fall back to run-time detection.
|
||||
*/
|
||||
return get_current_el();
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if an EL is implemented from AA64PFR0 register fields.
|
||||
*/
|
||||
static inline uint64_t el_implemented(unsigned int el)
|
||||
{
|
||||
if (el > 3U) {
|
||||
return EL_IMPL_NONE;
|
||||
} else {
|
||||
unsigned int shift = ID_AA64PFR0_EL1_SHIFT * el;
|
||||
|
||||
return (read_id_aa64pfr0_el1() >> shift) & ID_AA64PFR0_ELX_MASK;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* TLBIPAALLOS instruction
|
||||
* (TLB Inivalidate GPT Information by PA,
|
||||
* All Entries, Outer Shareable)
|
||||
*/
|
||||
static inline void tlbipaallos(void)
|
||||
{
|
||||
__asm__("SYS #6,c8,c1,#4");
|
||||
}
|
||||
|
||||
/*
|
||||
* Invalidate TLBs of GPT entries by Physical address, last level.
|
||||
*
|
||||
* @pa: the starting address for the range
|
||||
* of invalidation
|
||||
* @size: size of the range of invalidation
|
||||
*/
|
||||
void gpt_tlbi_by_pa_ll(uint64_t pa, size_t size);
|
||||
|
||||
|
||||
/* Previously defined accessor functions with incomplete register names */
|
||||
|
||||
#define read_current_el() read_CurrentEl()
|
||||
|
||||
#define dsb() dsbsy()
|
||||
|
||||
#define read_midr() read_midr_el1()
|
||||
|
||||
#define read_mpidr() read_mpidr_el1()
|
||||
|
||||
#define read_scr() read_scr_el3()
|
||||
#define write_scr(_v) write_scr_el3(_v)
|
||||
|
||||
#define read_hcr() read_hcr_el2()
|
||||
#define write_hcr(_v) write_hcr_el2(_v)
|
||||
|
||||
#define read_cpacr() read_cpacr_el1()
|
||||
#define write_cpacr(_v) write_cpacr_el1(_v)
|
||||
|
||||
#define read_clusterpwrdn() read_clusterpwrdn_el1()
|
||||
#define write_clusterpwrdn(_v) write_clusterpwrdn_el1(_v)
|
||||
|
||||
#if ERRATA_SPECULATIVE_AT
|
||||
/*
|
||||
* Assuming SCTLR.M bit is already enabled
|
||||
* 1. Enable page table walk by clearing TCR_EL1.EPDx bits
|
||||
* 2. Execute AT instruction for lower EL1/0
|
||||
* 3. Disable page table walk by setting TCR_EL1.EPDx bits
|
||||
*/
|
||||
#define AT(_at_inst, _va) \
|
||||
{ \
|
||||
assert((read_sctlr_el1() & SCTLR_M_BIT) != 0ULL); \
|
||||
write_tcr_el1(read_tcr_el1() & ~(TCR_EPD0_BIT | TCR_EPD1_BIT)); \
|
||||
isb(); \
|
||||
_at_inst(_va); \
|
||||
write_tcr_el1(read_tcr_el1() | (TCR_EPD0_BIT | TCR_EPD1_BIT)); \
|
||||
isb(); \
|
||||
}
|
||||
#else
|
||||
#define AT(_at_inst, _va) _at_inst(_va);
|
||||
#endif
|
||||
|
||||
#endif /* ARCH_HELPERS_H */
|
||||
@@ -0,0 +1,244 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
#ifndef ASM_MACROS_S
|
||||
#define ASM_MACROS_S
|
||||
|
||||
#include <arch.h>
|
||||
#include <common/asm_macros_common.S>
|
||||
#include <lib/spinlock.h>
|
||||
|
||||
/*
|
||||
* TLBI instruction with type specifier that implements the workaround for
|
||||
* errata 813419 of Cortex-A57 or errata 1286807 of Cortex-A76.
|
||||
*/
|
||||
#if ERRATA_A57_813419 || ERRATA_A76_1286807
|
||||
#define TLB_INVALIDATE(_type) \
|
||||
tlbi _type; \
|
||||
dsb ish; \
|
||||
tlbi _type
|
||||
#else
|
||||
#define TLB_INVALIDATE(_type) \
|
||||
tlbi _type
|
||||
#endif
|
||||
|
||||
|
||||
.macro func_prologue
|
||||
stp x29, x30, [sp, #-0x10]!
|
||||
mov x29,sp
|
||||
.endm
|
||||
|
||||
.macro func_epilogue
|
||||
ldp x29, x30, [sp], #0x10
|
||||
.endm
|
||||
|
||||
|
||||
.macro dcache_line_size reg, tmp
|
||||
mrs \tmp, ctr_el0
|
||||
ubfx \tmp, \tmp, #16, #4
|
||||
mov \reg, #4
|
||||
lsl \reg, \reg, \tmp
|
||||
.endm
|
||||
|
||||
|
||||
.macro icache_line_size reg, tmp
|
||||
mrs \tmp, ctr_el0
|
||||
and \tmp, \tmp, #0xf
|
||||
mov \reg, #4
|
||||
lsl \reg, \reg, \tmp
|
||||
.endm
|
||||
|
||||
|
||||
.macro smc_check label
|
||||
mrs x0, esr_el3
|
||||
ubfx x0, x0, #ESR_EC_SHIFT, #ESR_EC_LENGTH
|
||||
cmp x0, #EC_AARCH64_SMC
|
||||
b.ne $label
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Declare the exception vector table, enforcing it is aligned on a
|
||||
* 2KB boundary, as required by the ARMv8 architecture.
|
||||
* Use zero bytes as the fill value to be stored in the padding bytes
|
||||
* so that it inserts illegal AArch64 instructions. This increases
|
||||
* security, robustness and potentially facilitates debugging.
|
||||
*/
|
||||
.macro vector_base label, section_name=.vectors
|
||||
.section \section_name, "ax"
|
||||
.align 11, 0
|
||||
\label:
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Create an entry in the exception vector table, enforcing it is
|
||||
* aligned on a 128-byte boundary, as required by the ARMv8 architecture.
|
||||
* Use zero bytes as the fill value to be stored in the padding bytes
|
||||
* so that it inserts illegal AArch64 instructions. This increases
|
||||
* security, robustness and potentially facilitates debugging.
|
||||
*/
|
||||
.macro vector_entry label, section_name=.vectors
|
||||
.cfi_sections .debug_frame
|
||||
.section \section_name, "ax"
|
||||
.align 7, 0
|
||||
.type \label, %function
|
||||
.cfi_startproc
|
||||
\label:
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Add the bytes until fill the full exception vector, whose size is always
|
||||
* 32 instructions. If there are more than 32 instructions in the
|
||||
* exception vector then an error is emitted.
|
||||
*/
|
||||
.macro end_vector_entry label
|
||||
.cfi_endproc
|
||||
.fill \label + (32 * 4) - .
|
||||
.endm
|
||||
|
||||
/*
|
||||
* This macro calculates the base address of the current CPU's MP stack
|
||||
* using the plat_my_core_pos() index, the name of the stack storage
|
||||
* and the size of each stack
|
||||
* Out: X0 = physical address of stack base
|
||||
* Clobber: X30, X1, X2
|
||||
*/
|
||||
.macro get_my_mp_stack _name, _size
|
||||
bl plat_my_core_pos
|
||||
adrp x2, (\_name + \_size)
|
||||
add x2, x2, :lo12:(\_name + \_size)
|
||||
mov x1, #\_size
|
||||
madd x0, x0, x1, x2
|
||||
.endm
|
||||
|
||||
/*
|
||||
* This macro calculates the base address of a UP stack using the
|
||||
* name of the stack storage and the size of the stack
|
||||
* Out: X0 = physical address of stack base
|
||||
*/
|
||||
.macro get_up_stack _name, _size
|
||||
adrp x0, (\_name + \_size)
|
||||
add x0, x0, :lo12:(\_name + \_size)
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Helper macro to generate the best mov/movk combinations according
|
||||
* the value to be moved. The 16 bits from '_shift' are tested and
|
||||
* if not zero, they are moved into '_reg' without affecting
|
||||
* other bits.
|
||||
*/
|
||||
.macro _mov_imm16 _reg, _val, _shift
|
||||
.if (\_val >> \_shift) & 0xffff
|
||||
.if (\_val & (1 << \_shift - 1))
|
||||
movk \_reg, (\_val >> \_shift) & 0xffff, LSL \_shift
|
||||
.else
|
||||
mov \_reg, \_val & (0xffff << \_shift)
|
||||
.endif
|
||||
.endif
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Helper macro to load arbitrary values into 32 or 64-bit registers
|
||||
* which generates the best mov/movk combinations. Many base addresses
|
||||
* are 64KB aligned the macro will eliminate updating bits 15:0 in
|
||||
* that case
|
||||
*/
|
||||
.macro mov_imm _reg, _val
|
||||
.if (\_val) == 0
|
||||
mov \_reg, #0
|
||||
.else
|
||||
_mov_imm16 \_reg, (\_val), 0
|
||||
_mov_imm16 \_reg, (\_val), 16
|
||||
_mov_imm16 \_reg, (\_val), 32
|
||||
_mov_imm16 \_reg, (\_val), 48
|
||||
.endif
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Macro to mark instances where we're jumping to a function and don't
|
||||
* expect a return. To provide the function being jumped to with
|
||||
* additional information, we use 'bl' instruction to jump rather than
|
||||
* 'b'.
|
||||
*
|
||||
* Debuggers infer the location of a call from where LR points to, which
|
||||
* is usually the instruction after 'bl'. If this macro expansion
|
||||
* happens to be the last location in a function, that'll cause the LR
|
||||
* to point a location beyond the function, thereby misleading debugger
|
||||
* back trace. We therefore insert a 'nop' after the function call for
|
||||
* debug builds, unless 'skip_nop' parameter is non-zero.
|
||||
*/
|
||||
.macro no_ret _func:req, skip_nop=0
|
||||
bl \_func
|
||||
#if DEBUG
|
||||
.ifeq \skip_nop
|
||||
nop
|
||||
.endif
|
||||
#endif
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Reserve space for a spin lock in assembly file.
|
||||
*/
|
||||
.macro define_asm_spinlock _name:req
|
||||
.align SPINLOCK_ASM_ALIGN
|
||||
\_name:
|
||||
.space SPINLOCK_ASM_SIZE
|
||||
.endm
|
||||
|
||||
#if RAS_EXTENSION
|
||||
.macro esb
|
||||
.inst 0xd503221f
|
||||
.endm
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Helper macro to read system register value into x0
|
||||
*/
|
||||
.macro read reg:req
|
||||
#if ENABLE_BTI
|
||||
bti j
|
||||
#endif
|
||||
mrs x0, \reg
|
||||
ret
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Helper macro to write value from x1 to system register
|
||||
*/
|
||||
.macro write reg:req
|
||||
#if ENABLE_BTI
|
||||
bti j
|
||||
#endif
|
||||
msr \reg, x1
|
||||
ret
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Macro for using speculation barrier instruction introduced by
|
||||
* FEAT_SB, if it's enabled.
|
||||
*/
|
||||
.macro speculation_barrier
|
||||
#if ENABLE_FEAT_SB
|
||||
sb
|
||||
#else
|
||||
dsb sy
|
||||
isb
|
||||
#endif
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Macro for mitigating against speculative execution beyond ERET. Uses the
|
||||
* speculation barrier instruction introduced by FEAT_SB, if it's enabled.
|
||||
*/
|
||||
.macro exception_return
|
||||
eret
|
||||
#if ENABLE_FEAT_SB
|
||||
sb
|
||||
#else
|
||||
dsb nsh
|
||||
isb
|
||||
#endif
|
||||
.endm
|
||||
|
||||
#endif /* ASM_MACROS_S */
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
#ifndef ASSERT_MACROS_S
|
||||
#define ASSERT_MACROS_S
|
||||
|
||||
/*
|
||||
* Assembler macro to enable asm_assert. Use this macro wherever
|
||||
* assert is required in assembly. Please note that the macro makes
|
||||
* use of label '300' to provide the logic and the caller
|
||||
* should make sure that this label is not used to branch prior
|
||||
* to calling this macro.
|
||||
*/
|
||||
#define ASM_ASSERT(_cc) \
|
||||
.ifndef .L_assert_filename ;\
|
||||
.pushsection .rodata.str1.1, "aS" ;\
|
||||
.L_assert_filename: ;\
|
||||
.string __FILE__ ;\
|
||||
.popsection ;\
|
||||
.endif ;\
|
||||
b._cc 300f ;\
|
||||
adr x0, .L_assert_filename ;\
|
||||
mov x1, __LINE__ ;\
|
||||
b asm_assert ;\
|
||||
300:
|
||||
|
||||
#endif /* ASSERT_MACROS_S */
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
#ifndef CONSOLE_MACROS_S
|
||||
#define CONSOLE_MACROS_S
|
||||
|
||||
#include <drivers/console.h>
|
||||
|
||||
/*
|
||||
* This macro encapsulates the common setup that has to be done at the end of
|
||||
* a console driver's register function. It will register all of the driver's
|
||||
* callbacks in the console_t structure and initialize the flags field (by
|
||||
* default consoles are enabled for the "boot" and "crash" states, this can be
|
||||
* changed after registration with the console_set_scope() function). It ends
|
||||
* with a tail call that will include return to the caller.
|
||||
* REQUIRES console_t pointer in x0 and a valid return address in x30.
|
||||
*/
|
||||
.macro finish_console_register _driver, putc=0, getc=0, flush=0
|
||||
/*
|
||||
* If any of the callback is not specified or set as 0, then the
|
||||
* corresponding callback entry in console_t is set to 0.
|
||||
*/
|
||||
.ifne \putc
|
||||
adrp x1, console_\_driver\()_putc
|
||||
add x1, x1, :lo12:console_\_driver\()_putc
|
||||
str x1, [x0, #CONSOLE_T_PUTC]
|
||||
.else
|
||||
str xzr, [x0, #CONSOLE_T_PUTC]
|
||||
.endif
|
||||
|
||||
.ifne \getc
|
||||
adrp x1, console_\_driver\()_getc
|
||||
add x1, x1, :lo12:console_\_driver\()_getc
|
||||
str x1, [x0, #CONSOLE_T_GETC]
|
||||
.else
|
||||
str xzr, [x0, #CONSOLE_T_GETC]
|
||||
.endif
|
||||
|
||||
.ifne \flush
|
||||
adrp x1, console_\_driver\()_flush
|
||||
add x1, x1, :lo12:console_\_driver\()_flush
|
||||
str x1, [x0, #CONSOLE_T_FLUSH]
|
||||
.else
|
||||
str xzr, [x0, #CONSOLE_T_FLUSH]
|
||||
.endif
|
||||
|
||||
mov x1, #(CONSOLE_FLAG_BOOT | CONSOLE_FLAG_CRASH)
|
||||
str x1, [x0, #CONSOLE_T_FLAGS]
|
||||
b console_register
|
||||
.endm
|
||||
|
||||
#endif /* CONSOLE_MACROS_S */
|
||||
+422
@@ -0,0 +1,422 @@
|
||||
/*
|
||||
* Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef EL2_COMMON_MACROS_S
|
||||
#define EL2_COMMON_MACROS_S
|
||||
|
||||
#include <arch.h>
|
||||
#include <asm_macros.S>
|
||||
#include <context.h>
|
||||
#include <lib/xlat_tables/xlat_tables_defs.h>
|
||||
|
||||
#include <platform_def.h>
|
||||
|
||||
/*
|
||||
* Helper macro to initialise system registers at EL2.
|
||||
*/
|
||||
.macro el2_arch_init_common
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
* SCTLR_EL2 has already been initialised - read current value before
|
||||
* modifying.
|
||||
*
|
||||
* SCTLR_EL2.I: Enable the instruction cache.
|
||||
*
|
||||
* SCTLR_EL2.SA: Enable Stack Alignment check. A SP alignment fault
|
||||
* exception is generated if a load or store instruction executed at
|
||||
* EL2 uses the SP as the base address and the SP is not aligned to a
|
||||
* 16-byte boundary.
|
||||
*
|
||||
* SCTLR_EL2.A: Enable Alignment fault checking. All instructions that
|
||||
* load or store one or more registers have an alignment check that the
|
||||
* address being accessed is aligned to the size of the data element(s)
|
||||
* being accessed.
|
||||
* ---------------------------------------------------------------------
|
||||
*/
|
||||
mov x1, #(SCTLR_I_BIT | SCTLR_A_BIT | SCTLR_SA_BIT)
|
||||
mrs x0, sctlr_el2
|
||||
orr x0, x0, x1
|
||||
msr sctlr_el2, x0
|
||||
isb
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
* Initialise HCR_EL2, setting all fields rather than relying on HW.
|
||||
* All fields are architecturally UNKNOWN on reset. The following fields
|
||||
* do not change during the TF lifetime. The remaining fields are set to
|
||||
* zero here but are updated ahead of transitioning to a lower EL in the
|
||||
* function cm_init_context_common().
|
||||
*
|
||||
* HCR_EL2.TWE: Set to zero so that execution of WFE instructions at
|
||||
* EL2, EL1 and EL0 are not trapped to EL2.
|
||||
*
|
||||
* HCR_EL2.TWI: Set to zero so that execution of WFI instructions at
|
||||
* EL2, EL1 and EL0 are not trapped to EL2.
|
||||
*
|
||||
* HCR_EL2.HCD: Set to zero to enable HVC calls at EL1 and above,
|
||||
* from both Security states and both Execution states.
|
||||
*
|
||||
* HCR_EL2.TEA: Set to one to route External Aborts and SError
|
||||
* Interrupts to EL2 when executing at any EL.
|
||||
*
|
||||
* HCR_EL2.{API,APK}: For Armv8.3 pointer authentication feature,
|
||||
* disable traps to EL2 when accessing key registers or using
|
||||
* pointer authentication instructions from lower ELs.
|
||||
* ---------------------------------------------------------------------
|
||||
*/
|
||||
mov_imm x0, ((HCR_RESET_VAL | HCR_TEA_BIT) \
|
||||
& ~(HCR_TWE_BIT | HCR_TWI_BIT | HCR_HCD_BIT))
|
||||
#if CTX_INCLUDE_PAUTH_REGS
|
||||
/*
|
||||
* If the pointer authentication registers are saved during world
|
||||
* switches, enable pointer authentication everywhere, as it is safe to
|
||||
* do so.
|
||||
*/
|
||||
orr x0, x0, #(HCR_API_BIT | HCR_APK_BIT)
|
||||
#endif /* CTX_INCLUDE_PAUTH_REGS */
|
||||
msr hcr_el2, x0
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
* Initialise MDCR_EL2, setting all fields rather than relying on
|
||||
* hw. Some fields are architecturally UNKNOWN on reset.
|
||||
*
|
||||
* MDCR_EL2.TDOSA: Set to zero so that EL2 and EL2 System register
|
||||
* access to the powerdown debug registers do not trap to EL2.
|
||||
*
|
||||
* MDCR_EL2.TDA: Set to zero to allow EL0, EL1 and EL2 access to the
|
||||
* debug registers, other than those registers that are controlled by
|
||||
* MDCR_EL2.TDOSA.
|
||||
*
|
||||
* MDCR_EL2.TPM: Set to zero so that EL0, EL1, and EL2 System
|
||||
* register accesses to all Performance Monitors registers do not trap
|
||||
* to EL2.
|
||||
*
|
||||
* MDCR_EL2.HPMD: Set to zero so that event counting by the program-
|
||||
* mable counters PMEVCNTR<n>_EL0 is prohibited in Secure state. If
|
||||
* ARMv8.2 Debug is not implemented this bit does not have any effect
|
||||
* on the counters unless there is support for the implementation
|
||||
* defined authentication interface
|
||||
* ExternalSecureNoninvasiveDebugEnabled().
|
||||
* ---------------------------------------------------------------------
|
||||
*/
|
||||
mov_imm x0, ((MDCR_EL2_RESET_VAL | \
|
||||
MDCR_SPD32(MDCR_SPD32_DISABLE)) \
|
||||
& ~(MDCR_EL2_HPMD | MDCR_TDOSA_BIT | \
|
||||
MDCR_TDA_BIT | MDCR_TPM_BIT))
|
||||
|
||||
msr mdcr_el2, x0
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
* Initialise PMCR_EL0 setting all fields rather than relying
|
||||
* on hw. Some fields are architecturally UNKNOWN on reset.
|
||||
*
|
||||
* PMCR_EL0.DP: Set to one so that the cycle counter,
|
||||
* PMCCNTR_EL0 does not count when event counting is prohibited.
|
||||
*
|
||||
* PMCR_EL0.X: Set to zero to disable export of events.
|
||||
*
|
||||
* PMCR_EL0.D: Set to zero so that, when enabled, PMCCNTR_EL0
|
||||
* counts on every clock cycle.
|
||||
* ---------------------------------------------------------------------
|
||||
*/
|
||||
mov_imm x0, ((PMCR_EL0_RESET_VAL | PMCR_EL0_DP_BIT) & \
|
||||
~(PMCR_EL0_X_BIT | PMCR_EL0_D_BIT))
|
||||
|
||||
msr pmcr_el0, x0
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
* Enable External Aborts and SError Interrupts now that the exception
|
||||
* vectors have been setup.
|
||||
* ---------------------------------------------------------------------
|
||||
*/
|
||||
msr daifclr, #DAIF_ABT_BIT
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
* Initialise CPTR_EL2, setting all fields rather than relying on hw.
|
||||
* All fields are architecturally UNKNOWN on reset.
|
||||
*
|
||||
* CPTR_EL2.TCPAC: Set to zero so that any accesses to CPACR_EL1 do
|
||||
* not trap to EL2.
|
||||
*
|
||||
* CPTR_EL2.TTA: Set to zero so that System register accesses to the
|
||||
* trace registers do not trap to EL2.
|
||||
*
|
||||
* CPTR_EL2.TFP: Set to zero so that accesses to the V- or Z- registers
|
||||
* by Advanced SIMD, floating-point or SVE instructions (if implemented)
|
||||
* do not trap to EL2.
|
||||
*/
|
||||
|
||||
mov_imm x0, (CPTR_EL2_RESET_VAL & ~(TCPAC_BIT | TTA_BIT | TFP_BIT))
|
||||
msr cptr_el2, x0
|
||||
|
||||
/*
|
||||
* If Data Independent Timing (DIT) functionality is implemented,
|
||||
* always enable DIT in EL2
|
||||
*/
|
||||
mrs x0, id_aa64pfr0_el1
|
||||
ubfx x0, x0, #ID_AA64PFR0_DIT_SHIFT, #ID_AA64PFR0_DIT_LENGTH
|
||||
cmp x0, #ID_AA64PFR0_DIT_SUPPORTED
|
||||
bne 1f
|
||||
mov x0, #DIT_BIT
|
||||
msr DIT, x0
|
||||
1:
|
||||
.endm
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* This is the super set of actions that need to be performed during a cold boot
|
||||
* or a warm boot in EL2. This code is shared by BL1 and BL31.
|
||||
*
|
||||
* This macro will always perform reset handling, architectural initialisations
|
||||
* and stack setup. The rest of the actions are optional because they might not
|
||||
* be needed, depending on the context in which this macro is called. This is
|
||||
* why this macro is parameterised ; each parameter allows to enable/disable
|
||||
* some actions.
|
||||
*
|
||||
* _init_sctlr:
|
||||
* Whether the macro needs to initialise SCTLR_EL2, including configuring
|
||||
* the endianness of data accesses.
|
||||
*
|
||||
* _warm_boot_mailbox:
|
||||
* Whether the macro needs to detect the type of boot (cold/warm). The
|
||||
* detection is based on the platform entrypoint address : if it is zero
|
||||
* then it is a cold boot, otherwise it is a warm boot. In the latter case,
|
||||
* this macro jumps on the platform entrypoint address.
|
||||
*
|
||||
* _secondary_cold_boot:
|
||||
* Whether the macro needs to identify the CPU that is calling it: primary
|
||||
* CPU or secondary CPU. The primary CPU will be allowed to carry on with
|
||||
* the platform initialisations, while the secondaries will be put in a
|
||||
* platform-specific state in the meantime.
|
||||
*
|
||||
* If the caller knows this macro will only be called by the primary CPU
|
||||
* then this parameter can be defined to 0 to skip this step.
|
||||
*
|
||||
* _init_memory:
|
||||
* Whether the macro needs to initialise the memory.
|
||||
*
|
||||
* _init_c_runtime:
|
||||
* Whether the macro needs to initialise the C runtime environment.
|
||||
*
|
||||
* _exception_vectors:
|
||||
* Address of the exception vectors to program in the VBAR_EL2 register.
|
||||
*
|
||||
* _pie_fixup_size:
|
||||
* Size of memory region to fixup Global Descriptor Table (GDT).
|
||||
*
|
||||
* A non-zero value is expected when firmware needs GDT to be fixed-up.
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
*/
|
||||
.macro el2_entrypoint_common \
|
||||
_init_sctlr, _warm_boot_mailbox, _secondary_cold_boot, \
|
||||
_init_memory, _init_c_runtime, _exception_vectors, \
|
||||
_pie_fixup_size
|
||||
|
||||
.if \_init_sctlr
|
||||
/* -------------------------------------------------------------
|
||||
* This is the initialisation of SCTLR_EL2 and so must ensure
|
||||
* that all fields are explicitly set rather than relying on hw.
|
||||
* Some fields reset to an IMPLEMENTATION DEFINED value and
|
||||
* others are architecturally UNKNOWN on reset.
|
||||
*
|
||||
* SCTLR.EE: Set the CPU endianness before doing anything that
|
||||
* might involve memory reads or writes. Set to zero to select
|
||||
* Little Endian.
|
||||
*
|
||||
* SCTLR_EL2.WXN: For the EL2 translation regime, this field can
|
||||
* force all memory regions that are writeable to be treated as
|
||||
* XN (Execute-never). Set to zero so that this control has no
|
||||
* effect on memory access permissions.
|
||||
*
|
||||
* SCTLR_EL2.SA: Set to zero to disable Stack Alignment check.
|
||||
*
|
||||
* SCTLR_EL2.A: Set to zero to disable Alignment fault checking.
|
||||
*
|
||||
* SCTLR.DSSBS: Set to zero to disable speculation store bypass
|
||||
* safe behaviour upon exception entry to EL2.
|
||||
* -------------------------------------------------------------
|
||||
*/
|
||||
mov_imm x0, (SCTLR_RESET_VAL & ~(SCTLR_EE_BIT | SCTLR_WXN_BIT \
|
||||
| SCTLR_SA_BIT | SCTLR_A_BIT | SCTLR_DSSBS_BIT))
|
||||
msr sctlr_el2, x0
|
||||
isb
|
||||
.endif /* _init_sctlr */
|
||||
|
||||
#if DISABLE_MTPMU
|
||||
bl mtpmu_disable
|
||||
#endif
|
||||
|
||||
.if \_warm_boot_mailbox
|
||||
/* -------------------------------------------------------------
|
||||
* This code will be executed for both warm and cold resets.
|
||||
* Now is the time to distinguish between the two.
|
||||
* Query the platform entrypoint address and if it is not zero
|
||||
* then it means it is a warm boot so jump to this address.
|
||||
* -------------------------------------------------------------
|
||||
*/
|
||||
bl plat_get_my_entrypoint
|
||||
cbz x0, do_cold_boot
|
||||
br x0
|
||||
|
||||
do_cold_boot:
|
||||
.endif /* _warm_boot_mailbox */
|
||||
|
||||
.if \_pie_fixup_size
|
||||
#if ENABLE_PIE
|
||||
/*
|
||||
* ------------------------------------------------------------
|
||||
* If PIE is enabled fixup the Global descriptor Table only
|
||||
* once during primary core cold boot path.
|
||||
*
|
||||
* Compile time base address, required for fixup, is calculated
|
||||
* using "pie_fixup" label present within first page.
|
||||
* ------------------------------------------------------------
|
||||
*/
|
||||
pie_fixup:
|
||||
ldr x0, =pie_fixup
|
||||
and x0, x0, #~(PAGE_SIZE_MASK)
|
||||
mov_imm x1, \_pie_fixup_size
|
||||
add x1, x1, x0
|
||||
bl fixup_gdt_reloc
|
||||
#endif /* ENABLE_PIE */
|
||||
.endif /* _pie_fixup_size */
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
* Set the exception vectors.
|
||||
* ---------------------------------------------------------------------
|
||||
*/
|
||||
adr x0, \_exception_vectors
|
||||
msr vbar_el2, x0
|
||||
isb
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
* It is a cold boot.
|
||||
* Perform any processor specific actions upon reset e.g. cache, TLB
|
||||
* invalidations etc.
|
||||
* ---------------------------------------------------------------------
|
||||
*/
|
||||
bl reset_handler
|
||||
|
||||
el2_arch_init_common
|
||||
|
||||
.if \_secondary_cold_boot
|
||||
/* -------------------------------------------------------------
|
||||
* Check if this is a primary or secondary CPU cold boot.
|
||||
* The primary CPU will set up the platform while the
|
||||
* secondaries are placed in a platform-specific state until the
|
||||
* primary CPU performs the necessary actions to bring them out
|
||||
* of that state and allows entry into the OS.
|
||||
* -------------------------------------------------------------
|
||||
*/
|
||||
bl plat_is_my_cpu_primary
|
||||
cbnz w0, do_primary_cold_boot
|
||||
|
||||
/* This is a cold boot on a secondary CPU */
|
||||
bl plat_secondary_cold_boot_setup
|
||||
/* plat_secondary_cold_boot_setup() is not supposed to return */
|
||||
bl el2_panic
|
||||
do_primary_cold_boot:
|
||||
.endif /* _secondary_cold_boot */
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
* Initialize memory now. Secondary CPU initialization won't get to this
|
||||
* point.
|
||||
* ---------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
.if \_init_memory
|
||||
bl platform_mem_init
|
||||
.endif /* _init_memory */
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
* Init C runtime environment:
|
||||
* - Zero-initialise the NOBITS sections. There are 2 of them:
|
||||
* - the .bss section;
|
||||
* - the coherent memory section (if any).
|
||||
* - Relocate the data section from ROM to RAM, if required.
|
||||
* ---------------------------------------------------------------------
|
||||
*/
|
||||
.if \_init_c_runtime
|
||||
adrp x0, __BSS_START__
|
||||
add x0, x0, :lo12:__BSS_START__
|
||||
|
||||
adrp x1, __BSS_END__
|
||||
add x1, x1, :lo12:__BSS_END__
|
||||
sub x1, x1, x0
|
||||
bl zeromem
|
||||
|
||||
#if defined(IMAGE_BL1) || (defined(IMAGE_BL2) && BL2_AT_EL3 && BL2_IN_XIP_MEM)
|
||||
adrp x0, __DATA_RAM_START__
|
||||
add x0, x0, :lo12:__DATA_RAM_START__
|
||||
adrp x1, __DATA_ROM_START__
|
||||
add x1, x1, :lo12:__DATA_ROM_START__
|
||||
adrp x2, __DATA_RAM_END__
|
||||
add x2, x2, :lo12:__DATA_RAM_END__
|
||||
sub x2, x2, x0
|
||||
bl memcpy16
|
||||
#endif
|
||||
.endif /* _init_c_runtime */
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
* Use SP_EL0 for the C runtime stack.
|
||||
* ---------------------------------------------------------------------
|
||||
*/
|
||||
msr spsel, #0
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
* Allocate a stack whose memory will be marked 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.
|
||||
* ---------------------------------------------------------------------
|
||||
*/
|
||||
bl plat_set_my_stack
|
||||
|
||||
#if STACK_PROTECTOR_ENABLED
|
||||
.if \_init_c_runtime
|
||||
bl update_stack_protector_canary
|
||||
.endif /* _init_c_runtime */
|
||||
#endif
|
||||
.endm
|
||||
|
||||
.macro apply_at_speculative_wa
|
||||
#if ERRATA_SPECULATIVE_AT
|
||||
/*
|
||||
* Explicitly save x30 so as to free up a register and to enable
|
||||
* branching and also, save x29 which will be used in the called
|
||||
* function
|
||||
*/
|
||||
stp x29, x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X29]
|
||||
bl save_and_update_ptw_el1_sys_regs
|
||||
ldp x29, x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X29]
|
||||
#endif
|
||||
.endm
|
||||
|
||||
.macro restore_ptw_el1_sys_regs
|
||||
#if ERRATA_SPECULATIVE_AT
|
||||
/* -----------------------------------------------------------
|
||||
* In case of ERRATA_SPECULATIVE_AT, must follow below order
|
||||
* to ensure that page table walk is not enabled until
|
||||
* restoration of all EL1 system registers. TCR_EL1 register
|
||||
* should be updated at the end which restores previous page
|
||||
* table walk setting of stage1 i.e.(TCR_EL1.EPDx) bits. ISB
|
||||
* ensures that CPU does below steps in order.
|
||||
*
|
||||
* 1. Ensure all other system registers are written before
|
||||
* updating SCTLR_EL1 using ISB.
|
||||
* 2. Restore SCTLR_EL1 register.
|
||||
* 3. Ensure SCTLR_EL1 written successfully using ISB.
|
||||
* 4. Restore TCR_EL1 register.
|
||||
* -----------------------------------------------------------
|
||||
*/
|
||||
isb
|
||||
ldp x28, x29, [sp, #CTX_EL1_SYSREGS_OFFSET + CTX_SCTLR_EL1]
|
||||
msr sctlr_el1, x28
|
||||
isb
|
||||
msr tcr_el1, x29
|
||||
#endif
|
||||
.endm
|
||||
|
||||
#endif /* EL2_COMMON_MACROS_S */
|
||||
+570
@@ -0,0 +1,570 @@
|
||||
/*
|
||||
* Copyright (c) 2015-2022, Arm Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef EL3_COMMON_MACROS_S
|
||||
#define EL3_COMMON_MACROS_S
|
||||
|
||||
#include <arch.h>
|
||||
#include <asm_macros.S>
|
||||
#include <assert_macros.S>
|
||||
#include <context.h>
|
||||
#include <lib/xlat_tables/xlat_tables_defs.h>
|
||||
|
||||
/*
|
||||
* Helper macro to initialise EL3 registers we care about.
|
||||
*/
|
||||
.macro el3_arch_init_common
|
||||
/* ---------------------------------------------------------------------
|
||||
* SCTLR_EL3 has already been initialised - read current value before
|
||||
* modifying.
|
||||
*
|
||||
* SCTLR_EL3.I: Enable the instruction cache.
|
||||
*
|
||||
* SCTLR_EL3.SA: Enable Stack Alignment check. A SP alignment fault
|
||||
* exception is generated if a load or store instruction executed at
|
||||
* EL3 uses the SP as the base address and the SP is not aligned to a
|
||||
* 16-byte boundary.
|
||||
*
|
||||
* SCTLR_EL3.A: Enable Alignment fault checking. All instructions that
|
||||
* load or store one or more registers have an alignment check that the
|
||||
* address being accessed is aligned to the size of the data element(s)
|
||||
* being accessed.
|
||||
* ---------------------------------------------------------------------
|
||||
*/
|
||||
mov x1, #(SCTLR_I_BIT | SCTLR_A_BIT | SCTLR_SA_BIT)
|
||||
mrs x0, sctlr_el3
|
||||
orr x0, x0, x1
|
||||
msr sctlr_el3, x0
|
||||
isb
|
||||
|
||||
#ifdef IMAGE_BL31
|
||||
/* ---------------------------------------------------------------------
|
||||
* Initialise the per-cpu cache pointer to the CPU.
|
||||
* This is done early to enable crash reporting to have access to crash
|
||||
* stack. Since crash reporting depends on cpu_data to report the
|
||||
* unhandled exception, not doing so can lead to recursive exceptions
|
||||
* due to a NULL TPIDR_EL3.
|
||||
* ---------------------------------------------------------------------
|
||||
*/
|
||||
bl init_cpu_data_ptr
|
||||
#endif /* IMAGE_BL31 */
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
* Initialise SCR_EL3, setting all fields rather than relying on hw.
|
||||
* All fields are architecturally UNKNOWN on reset. The following fields
|
||||
* do not change during the TF lifetime. The remaining fields are set to
|
||||
* zero here but are updated ahead of transitioning to a lower EL in the
|
||||
* function cm_init_context_common().
|
||||
*
|
||||
* SCR_EL3.TWE: Set to zero so that execution of WFE instructions at
|
||||
* EL2, EL1 and EL0 are not trapped to EL3.
|
||||
*
|
||||
* SCR_EL3.TWI: Set to zero so that execution of WFI instructions at
|
||||
* EL2, EL1 and EL0 are not trapped to EL3.
|
||||
*
|
||||
* SCR_EL3.SIF: Set to one to disable instruction fetches from
|
||||
* Non-secure memory.
|
||||
*
|
||||
* SCR_EL3.SMD: Set to zero to enable SMC calls at EL1 and above, from
|
||||
* both Security states and both Execution states.
|
||||
*
|
||||
* SCR_EL3.EA: Set to one to route External Aborts and SError Interrupts
|
||||
* to EL3 when executing at any EL.
|
||||
*
|
||||
* SCR_EL3.{API,APK}: For Armv8.3 pointer authentication feature,
|
||||
* disable traps to EL3 when accessing key registers or using pointer
|
||||
* authentication instructions from lower ELs.
|
||||
* ---------------------------------------------------------------------
|
||||
*/
|
||||
mov_imm x0, ((SCR_RESET_VAL | SCR_EA_BIT | SCR_SIF_BIT) \
|
||||
& ~(SCR_TWE_BIT | SCR_TWI_BIT | SCR_SMD_BIT))
|
||||
#if CTX_INCLUDE_PAUTH_REGS
|
||||
/*
|
||||
* If the pointer authentication registers are saved during world
|
||||
* switches, enable pointer authentication everywhere, as it is safe to
|
||||
* do so.
|
||||
*/
|
||||
orr x0, x0, #(SCR_API_BIT | SCR_APK_BIT)
|
||||
#endif
|
||||
#if ENABLE_RME
|
||||
/*
|
||||
* TODO: Settting the EEL2 bit to allow EL3 access to secure only registers
|
||||
* in context management. This will need to be refactored.
|
||||
*/
|
||||
orr x0, x0, #SCR_EEL2_BIT
|
||||
#endif
|
||||
msr scr_el3, x0
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
* Initialise MDCR_EL3, setting all fields rather than relying on hw.
|
||||
* Some fields are architecturally UNKNOWN on reset.
|
||||
*
|
||||
* MDCR_EL3.SDD: Set to one to disable AArch64 Secure self-hosted debug.
|
||||
* Debug exceptions, other than Breakpoint Instruction exceptions, are
|
||||
* disabled from all ELs in Secure state.
|
||||
*
|
||||
* MDCR_EL3.SPD32: Set to 0b10 to disable AArch32 Secure self-hosted
|
||||
* privileged debug from S-EL1.
|
||||
*
|
||||
* MDCR_EL3.TDOSA: Set to zero so that EL2 and EL2 System register
|
||||
* access to the powerdown debug registers do not trap to EL3.
|
||||
*
|
||||
* MDCR_EL3.TDA: Set to zero to allow EL0, EL1 and EL2 access to the
|
||||
* debug registers, other than those registers that are controlled by
|
||||
* MDCR_EL3.TDOSA.
|
||||
*
|
||||
* MDCR_EL3.TPM: Set to zero so that EL0, EL1, and EL2 System register
|
||||
* accesses to all Performance Monitors registers do not trap to EL3.
|
||||
*
|
||||
* MDCR_EL3.SCCD: Set to one so that cycle counting by PMCCNTR_EL0 is
|
||||
* prohibited in Secure state. This bit is RES0 in versions of the
|
||||
* architecture with FEAT_PMUv3p5 not implemented, setting it to 1
|
||||
* doesn't have any effect on them.
|
||||
*
|
||||
* MDCR_EL3.MCCD: Set to one so that cycle counting by PMCCNTR_EL0 is
|
||||
* prohibited in EL3. This bit is RES0 in versions of the
|
||||
* architecture with FEAT_PMUv3p7 not implemented, setting it to 1
|
||||
* doesn't have any effect on them.
|
||||
*
|
||||
* MDCR_EL3.SPME: Set to zero so that event counting by the programmable
|
||||
* counters PMEVCNTR<n>_EL0 is prohibited in Secure state. If ARMv8.2
|
||||
* Debug is not implemented this bit does not have any effect on the
|
||||
* counters unless there is support for the implementation defined
|
||||
* authentication interface ExternalSecureNoninvasiveDebugEnabled().
|
||||
*
|
||||
* MDCR_EL3.NSTB, MDCR_EL3.NSTBE: Set to zero so that Trace Buffer
|
||||
* owning security state is Secure state. If FEAT_TRBE is implemented,
|
||||
* accesses to Trace Buffer control registers at EL2 and EL1 in any
|
||||
* security state generates trap exceptions to EL3.
|
||||
* If FEAT_TRBE is not implemented, these bits are RES0.
|
||||
*
|
||||
* MDCR_EL3.TTRF: Set to one so that access to trace filter control
|
||||
* registers in non-monitor mode generate EL3 trap exception,
|
||||
* unless the access generates a higher priority exception when trace
|
||||
* filter control(FEAT_TRF) is implemented.
|
||||
* When FEAT_TRF is not implemented, this bit is RES0.
|
||||
* ---------------------------------------------------------------------
|
||||
*/
|
||||
mov_imm x0, ((MDCR_EL3_RESET_VAL | MDCR_SDD_BIT | \
|
||||
MDCR_SPD32(MDCR_SPD32_DISABLE) | MDCR_SCCD_BIT | \
|
||||
MDCR_MCCD_BIT) & ~(MDCR_SPME_BIT | MDCR_TDOSA_BIT | \
|
||||
MDCR_TDA_BIT | MDCR_TPM_BIT | MDCR_NSTB(MDCR_NSTB_EL1) | \
|
||||
MDCR_NSTBE | MDCR_TTRF_BIT))
|
||||
|
||||
mrs x1, id_aa64dfr0_el1
|
||||
ubfx x1, x1, #ID_AA64DFR0_TRACEFILT_SHIFT, #ID_AA64DFR0_TRACEFILT_LENGTH
|
||||
cbz x1, 1f
|
||||
orr x0, x0, #MDCR_TTRF_BIT
|
||||
1:
|
||||
msr mdcr_el3, x0
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
* Initialise PMCR_EL0 setting all fields rather than relying
|
||||
* on hw. Some fields are architecturally UNKNOWN on reset.
|
||||
*
|
||||
* PMCR_EL0.LP: Set to one so that event counter overflow, that
|
||||
* is recorded in PMOVSCLR_EL0[0-30], occurs on the increment
|
||||
* that changes PMEVCNTR<n>_EL0[63] from 1 to 0, when ARMv8.5-PMU
|
||||
* is implemented. This bit is RES0 in versions of the architecture
|
||||
* earlier than ARMv8.5, setting it to 1 doesn't have any effect
|
||||
* on them.
|
||||
*
|
||||
* PMCR_EL0.LC: Set to one so that cycle counter overflow, that
|
||||
* is recorded in PMOVSCLR_EL0[31], occurs on the increment
|
||||
* that changes PMCCNTR_EL0[63] from 1 to 0.
|
||||
*
|
||||
* PMCR_EL0.DP: Set to one so that the cycle counter,
|
||||
* PMCCNTR_EL0 does not count when event counting is prohibited.
|
||||
*
|
||||
* PMCR_EL0.X: Set to zero to disable export of events.
|
||||
*
|
||||
* PMCR_EL0.D: Set to zero so that, when enabled, PMCCNTR_EL0
|
||||
* counts on every clock cycle.
|
||||
* ---------------------------------------------------------------------
|
||||
*/
|
||||
mov_imm x0, ((PMCR_EL0_RESET_VAL | PMCR_EL0_LP_BIT | \
|
||||
PMCR_EL0_LC_BIT | PMCR_EL0_DP_BIT) & \
|
||||
~(PMCR_EL0_X_BIT | PMCR_EL0_D_BIT))
|
||||
|
||||
msr pmcr_el0, x0
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
* Enable External Aborts and SError Interrupts now that the exception
|
||||
* vectors have been setup.
|
||||
* ---------------------------------------------------------------------
|
||||
*/
|
||||
msr daifclr, #DAIF_ABT_BIT
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
* Initialise CPTR_EL3, setting all fields rather than relying on hw.
|
||||
* All fields are architecturally UNKNOWN on reset.
|
||||
*
|
||||
* CPTR_EL3.TCPAC: Set to zero so that any accesses to CPACR_EL1,
|
||||
* CPTR_EL2, CPACR, or HCPTR do not trap to EL3.
|
||||
*
|
||||
* CPTR_EL3.TTA: Set to one so that accesses to the trace system
|
||||
* registers trap to EL3 from all exception levels and security
|
||||
* states when system register trace is implemented.
|
||||
* When system register trace is not implemented, this bit is RES0 and
|
||||
* hence set to zero.
|
||||
*
|
||||
* CPTR_EL3.TTA: Set to zero so that System register accesses to the
|
||||
* trace registers do not trap to EL3.
|
||||
*
|
||||
* CPTR_EL3.TFP: Set to zero so that accesses to the V- or Z- registers
|
||||
* by Advanced SIMD, floating-point or SVE instructions (if implemented)
|
||||
* do not trap to EL3.
|
||||
*
|
||||
* CPTR_EL3.TAM: Set to one so that Activity Monitor access is
|
||||
* trapped to EL3 by default.
|
||||
*
|
||||
* CPTR_EL3.EZ: Set to zero so that all SVE functionality is trapped
|
||||
* to EL3 by default.
|
||||
*
|
||||
* CPTR_EL3.ESM: Set to zero so that all SME functionality is trapped
|
||||
* to EL3 by default.
|
||||
*/
|
||||
|
||||
mov_imm x0, (CPTR_EL3_RESET_VAL & ~(TCPAC_BIT | TTA_BIT | TFP_BIT))
|
||||
mrs x1, id_aa64dfr0_el1
|
||||
ubfx x1, x1, #ID_AA64DFR0_TRACEVER_SHIFT, #ID_AA64DFR0_TRACEVER_LENGTH
|
||||
cbz x1, 1f
|
||||
orr x0, x0, #TTA_BIT
|
||||
1:
|
||||
msr cptr_el3, x0
|
||||
|
||||
/*
|
||||
* If Data Independent Timing (DIT) functionality is implemented,
|
||||
* always enable DIT in EL3.
|
||||
* First assert that the FEAT_DIT build flag matches the feature id
|
||||
* register value for DIT.
|
||||
*/
|
||||
#if ENABLE_FEAT_DIT
|
||||
#if ENABLE_ASSERTIONS
|
||||
mrs x0, id_aa64pfr0_el1
|
||||
ubfx x0, x0, #ID_AA64PFR0_DIT_SHIFT, #ID_AA64PFR0_DIT_LENGTH
|
||||
cmp x0, #ID_AA64PFR0_DIT_SUPPORTED
|
||||
ASM_ASSERT(eq)
|
||||
#endif /* ENABLE_ASSERTIONS */
|
||||
mov x0, #DIT_BIT
|
||||
msr DIT, x0
|
||||
#endif
|
||||
.endm
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* This is the super set of actions that need to be performed during a cold boot
|
||||
* or a warm boot in EL3. This code is shared by BL1 and BL31.
|
||||
*
|
||||
* This macro will always perform reset handling, architectural initialisations
|
||||
* and stack setup. The rest of the actions are optional because they might not
|
||||
* be needed, depending on the context in which this macro is called. This is
|
||||
* why this macro is parameterised ; each parameter allows to enable/disable
|
||||
* some actions.
|
||||
*
|
||||
* _init_sctlr:
|
||||
* Whether the macro needs to initialise SCTLR_EL3, including configuring
|
||||
* the endianness of data accesses.
|
||||
*
|
||||
* _warm_boot_mailbox:
|
||||
* Whether the macro needs to detect the type of boot (cold/warm). The
|
||||
* detection is based on the platform entrypoint address : if it is zero
|
||||
* then it is a cold boot, otherwise it is a warm boot. In the latter case,
|
||||
* this macro jumps on the platform entrypoint address.
|
||||
*
|
||||
* _secondary_cold_boot:
|
||||
* Whether the macro needs to identify the CPU that is calling it: primary
|
||||
* CPU or secondary CPU. The primary CPU will be allowed to carry on with
|
||||
* the platform initialisations, while the secondaries will be put in a
|
||||
* platform-specific state in the meantime.
|
||||
*
|
||||
* If the caller knows this macro will only be called by the primary CPU
|
||||
* then this parameter can be defined to 0 to skip this step.
|
||||
*
|
||||
* _init_memory:
|
||||
* Whether the macro needs to initialise the memory.
|
||||
*
|
||||
* _init_c_runtime:
|
||||
* Whether the macro needs to initialise the C runtime environment.
|
||||
*
|
||||
* _exception_vectors:
|
||||
* Address of the exception vectors to program in the VBAR_EL3 register.
|
||||
*
|
||||
* _pie_fixup_size:
|
||||
* Size of memory region to fixup Global Descriptor Table (GDT).
|
||||
*
|
||||
* A non-zero value is expected when firmware needs GDT to be fixed-up.
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
*/
|
||||
.macro el3_entrypoint_common \
|
||||
_init_sctlr, _warm_boot_mailbox, _secondary_cold_boot, \
|
||||
_init_memory, _init_c_runtime, _exception_vectors, \
|
||||
_pie_fixup_size
|
||||
|
||||
.if \_init_sctlr
|
||||
/* -------------------------------------------------------------
|
||||
* This is the initialisation of SCTLR_EL3 and so must ensure
|
||||
* that all fields are explicitly set rather than relying on hw.
|
||||
* Some fields reset to an IMPLEMENTATION DEFINED value and
|
||||
* others are architecturally UNKNOWN on reset.
|
||||
*
|
||||
* SCTLR.EE: Set the CPU endianness before doing anything that
|
||||
* might involve memory reads or writes. Set to zero to select
|
||||
* Little Endian.
|
||||
*
|
||||
* SCTLR_EL3.WXN: For the EL3 translation regime, this field can
|
||||
* force all memory regions that are writeable to be treated as
|
||||
* XN (Execute-never). Set to zero so that this control has no
|
||||
* effect on memory access permissions.
|
||||
*
|
||||
* SCTLR_EL3.SA: Set to zero to disable Stack Alignment check.
|
||||
*
|
||||
* SCTLR_EL3.A: Set to zero to disable Alignment fault checking.
|
||||
*
|
||||
* SCTLR.DSSBS: Set to zero to disable speculation store bypass
|
||||
* safe behaviour upon exception entry to EL3.
|
||||
* -------------------------------------------------------------
|
||||
*/
|
||||
mov_imm x0, (SCTLR_RESET_VAL & ~(SCTLR_EE_BIT | SCTLR_WXN_BIT \
|
||||
| SCTLR_SA_BIT | SCTLR_A_BIT | SCTLR_DSSBS_BIT))
|
||||
msr sctlr_el3, x0
|
||||
isb
|
||||
.endif /* _init_sctlr */
|
||||
|
||||
#if DISABLE_MTPMU
|
||||
bl mtpmu_disable
|
||||
#endif
|
||||
|
||||
.if \_warm_boot_mailbox
|
||||
/* -------------------------------------------------------------
|
||||
* This code will be executed for both warm and cold resets.
|
||||
* Now is the time to distinguish between the two.
|
||||
* Query the platform entrypoint address and if it is not zero
|
||||
* then it means it is a warm boot so jump to this address.
|
||||
* -------------------------------------------------------------
|
||||
*/
|
||||
bl plat_get_my_entrypoint
|
||||
cbz x0, do_cold_boot
|
||||
br x0
|
||||
|
||||
do_cold_boot:
|
||||
.endif /* _warm_boot_mailbox */
|
||||
|
||||
.if \_pie_fixup_size
|
||||
#if ENABLE_PIE
|
||||
/*
|
||||
* ------------------------------------------------------------
|
||||
* If PIE is enabled fixup the Global descriptor Table only
|
||||
* once during primary core cold boot path.
|
||||
*
|
||||
* Compile time base address, required for fixup, is calculated
|
||||
* using "pie_fixup" label present within first page.
|
||||
* ------------------------------------------------------------
|
||||
*/
|
||||
pie_fixup:
|
||||
ldr x0, =pie_fixup
|
||||
and x0, x0, #~(PAGE_SIZE_MASK)
|
||||
mov_imm x1, \_pie_fixup_size
|
||||
add x1, x1, x0
|
||||
bl fixup_gdt_reloc
|
||||
#endif /* ENABLE_PIE */
|
||||
.endif /* _pie_fixup_size */
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
* Set the exception vectors.
|
||||
* ---------------------------------------------------------------------
|
||||
*/
|
||||
adr x0, \_exception_vectors
|
||||
msr vbar_el3, x0
|
||||
isb
|
||||
|
||||
#if !(defined(IMAGE_BL2) && ENABLE_RME)
|
||||
/* ---------------------------------------------------------------------
|
||||
* It is a cold boot.
|
||||
* Perform any processor specific actions upon reset e.g. cache, TLB
|
||||
* invalidations etc.
|
||||
* ---------------------------------------------------------------------
|
||||
*/
|
||||
bl reset_handler
|
||||
#endif
|
||||
|
||||
el3_arch_init_common
|
||||
|
||||
.if \_secondary_cold_boot
|
||||
/* -------------------------------------------------------------
|
||||
* Check if this is a primary or secondary CPU cold boot.
|
||||
* The primary CPU will set up the platform while the
|
||||
* secondaries are placed in a platform-specific state until the
|
||||
* primary CPU performs the necessary actions to bring them out
|
||||
* of that state and allows entry into the OS.
|
||||
* -------------------------------------------------------------
|
||||
*/
|
||||
bl plat_is_my_cpu_primary
|
||||
cbnz w0, do_primary_cold_boot
|
||||
|
||||
/* This is a cold boot on a secondary CPU */
|
||||
bl plat_secondary_cold_boot_setup
|
||||
/* plat_secondary_cold_boot_setup() is not supposed to return */
|
||||
bl el3_panic
|
||||
|
||||
do_primary_cold_boot:
|
||||
.endif /* _secondary_cold_boot */
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
* Initialize memory now. Secondary CPU initialization won't get to this
|
||||
* point.
|
||||
* ---------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
.if \_init_memory
|
||||
bl platform_mem_init
|
||||
.endif /* _init_memory */
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
* Init C runtime environment:
|
||||
* - Zero-initialise the NOBITS sections. There are 2 of them:
|
||||
* - the .bss section;
|
||||
* - the coherent memory section (if any).
|
||||
* - Relocate the data section from ROM to RAM, if required.
|
||||
* ---------------------------------------------------------------------
|
||||
*/
|
||||
.if \_init_c_runtime
|
||||
#if defined(IMAGE_BL31) || (defined(IMAGE_BL2) && \
|
||||
((BL2_AT_EL3 && BL2_INV_DCACHE) || ENABLE_RME))
|
||||
/* -------------------------------------------------------------
|
||||
* Invalidate the RW memory used by the BL31 image. This
|
||||
* includes the data and NOBITS sections. This is done to
|
||||
* safeguard against possible corruption of this memory by
|
||||
* dirty cache lines in a system cache as a result of use by
|
||||
* an earlier boot loader stage. If PIE is enabled however,
|
||||
* RO sections including the GOT may be modified during
|
||||
* pie fixup. Therefore, to be on the safe side, invalidate
|
||||
* the entire image region if PIE is enabled.
|
||||
* -------------------------------------------------------------
|
||||
*/
|
||||
#if ENABLE_PIE
|
||||
#if SEPARATE_CODE_AND_RODATA
|
||||
adrp x0, __TEXT_START__
|
||||
add x0, x0, :lo12:__TEXT_START__
|
||||
#else
|
||||
adrp x0, __RO_START__
|
||||
add x0, x0, :lo12:__RO_START__
|
||||
#endif /* SEPARATE_CODE_AND_RODATA */
|
||||
#else
|
||||
adrp x0, __RW_START__
|
||||
add x0, x0, :lo12:__RW_START__
|
||||
#endif /* ENABLE_PIE */
|
||||
adrp x1, __RW_END__
|
||||
add x1, x1, :lo12:__RW_END__
|
||||
sub x1, x1, x0
|
||||
bl inv_dcache_range
|
||||
#if defined(IMAGE_BL31) && SEPARATE_NOBITS_REGION
|
||||
adrp x0, __NOBITS_START__
|
||||
add x0, x0, :lo12:__NOBITS_START__
|
||||
adrp x1, __NOBITS_END__
|
||||
add x1, x1, :lo12:__NOBITS_END__
|
||||
sub x1, x1, x0
|
||||
bl inv_dcache_range
|
||||
#endif
|
||||
#if defined(IMAGE_BL2) && SEPARATE_BL2_NOLOAD_REGION
|
||||
adrp x0, __BL2_NOLOAD_START__
|
||||
add x0, x0, :lo12:__BL2_NOLOAD_START__
|
||||
adrp x1, __BL2_NOLOAD_END__
|
||||
add x1, x1, :lo12:__BL2_NOLOAD_END__
|
||||
sub x1, x1, x0
|
||||
bl inv_dcache_range
|
||||
#endif
|
||||
#endif
|
||||
adrp x0, __BSS_START__
|
||||
add x0, x0, :lo12:__BSS_START__
|
||||
|
||||
adrp x1, __BSS_END__
|
||||
add x1, x1, :lo12:__BSS_END__
|
||||
sub x1, x1, x0
|
||||
bl zeromem
|
||||
|
||||
#if USE_COHERENT_MEM
|
||||
adrp x0, __COHERENT_RAM_START__
|
||||
add x0, x0, :lo12:__COHERENT_RAM_START__
|
||||
adrp x1, __COHERENT_RAM_END_UNALIGNED__
|
||||
add x1, x1, :lo12: __COHERENT_RAM_END_UNALIGNED__
|
||||
sub x1, x1, x0
|
||||
bl zeromem
|
||||
#endif
|
||||
|
||||
#if defined(IMAGE_BL1) || (defined(IMAGE_BL2) && BL2_AT_EL3 && BL2_IN_XIP_MEM)
|
||||
adrp x0, __DATA_RAM_START__
|
||||
add x0, x0, :lo12:__DATA_RAM_START__
|
||||
adrp x1, __DATA_ROM_START__
|
||||
add x1, x1, :lo12:__DATA_ROM_START__
|
||||
adrp x2, __DATA_RAM_END__
|
||||
add x2, x2, :lo12:__DATA_RAM_END__
|
||||
sub x2, x2, x0
|
||||
bl memcpy16
|
||||
#endif
|
||||
.endif /* _init_c_runtime */
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
* Use SP_EL0 for the C runtime stack.
|
||||
* ---------------------------------------------------------------------
|
||||
*/
|
||||
msr spsel, #0
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
* Allocate a stack whose memory will be marked 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.
|
||||
* ---------------------------------------------------------------------
|
||||
*/
|
||||
bl plat_set_my_stack
|
||||
|
||||
#if STACK_PROTECTOR_ENABLED
|
||||
.if \_init_c_runtime
|
||||
bl update_stack_protector_canary
|
||||
.endif /* _init_c_runtime */
|
||||
#endif
|
||||
.endm
|
||||
|
||||
.macro apply_at_speculative_wa
|
||||
#if ERRATA_SPECULATIVE_AT
|
||||
/*
|
||||
* Explicitly save x30 so as to free up a register and to enable
|
||||
* branching and also, save x29 which will be used in the called
|
||||
* function
|
||||
*/
|
||||
stp x29, x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X29]
|
||||
bl save_and_update_ptw_el1_sys_regs
|
||||
ldp x29, x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X29]
|
||||
#endif
|
||||
.endm
|
||||
|
||||
.macro restore_ptw_el1_sys_regs
|
||||
#if ERRATA_SPECULATIVE_AT
|
||||
/* -----------------------------------------------------------
|
||||
* In case of ERRATA_SPECULATIVE_AT, must follow below order
|
||||
* to ensure that page table walk is not enabled until
|
||||
* restoration of all EL1 system registers. TCR_EL1 register
|
||||
* should be updated at the end which restores previous page
|
||||
* table walk setting of stage1 i.e.(TCR_EL1.EPDx) bits. ISB
|
||||
* ensures that CPU does below steps in order.
|
||||
*
|
||||
* 1. Ensure all other system registers are written before
|
||||
* updating SCTLR_EL1 using ISB.
|
||||
* 2. Restore SCTLR_EL1 register.
|
||||
* 3. Ensure SCTLR_EL1 written successfully using ISB.
|
||||
* 4. Restore TCR_EL1 register.
|
||||
* -----------------------------------------------------------
|
||||
*/
|
||||
isb
|
||||
ldp x28, x29, [sp, #CTX_EL1_SYSREGS_OFFSET + CTX_SCTLR_EL1]
|
||||
msr sctlr_el1, x28
|
||||
isb
|
||||
msr tcr_el1, x29
|
||||
#endif
|
||||
.endm
|
||||
|
||||
#endif /* EL3_COMMON_MACROS_S */
|
||||
@@ -0,0 +1,144 @@
|
||||
/*
|
||||
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef SMCCC_HELPERS_H
|
||||
#define SMCCC_HELPERS_H
|
||||
|
||||
#include <lib/smccc.h>
|
||||
|
||||
/* Definitions to help the assembler access the SMC/ERET args structure */
|
||||
#define SMC_ARGS_SIZE 0x40
|
||||
#define SMC_ARG0 0x0
|
||||
#define SMC_ARG1 0x8
|
||||
#define SMC_ARG2 0x10
|
||||
#define SMC_ARG3 0x18
|
||||
#define SMC_ARG4 0x20
|
||||
#define SMC_ARG5 0x28
|
||||
#define SMC_ARG6 0x30
|
||||
#define SMC_ARG7 0x38
|
||||
#define SMC_ARGS_END 0x40
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <context.h>
|
||||
|
||||
#include <platform_def.h> /* For CACHE_WRITEBACK_GRANULE */
|
||||
|
||||
/* Convenience macros to return from SMC handler */
|
||||
#define SMC_RET0(_h) { \
|
||||
return (uint64_t) (_h); \
|
||||
}
|
||||
#define SMC_RET1(_h, _x0) { \
|
||||
write_ctx_reg((get_gpregs_ctx(_h)), (CTX_GPREG_X0), (_x0)); \
|
||||
SMC_RET0(_h); \
|
||||
}
|
||||
#define SMC_RET2(_h, _x0, _x1) { \
|
||||
write_ctx_reg((get_gpregs_ctx(_h)), (CTX_GPREG_X1), (_x1)); \
|
||||
SMC_RET1(_h, (_x0)); \
|
||||
}
|
||||
#define SMC_RET3(_h, _x0, _x1, _x2) { \
|
||||
write_ctx_reg((get_gpregs_ctx(_h)), (CTX_GPREG_X2), (_x2)); \
|
||||
SMC_RET2(_h, (_x0), (_x1)); \
|
||||
}
|
||||
#define SMC_RET4(_h, _x0, _x1, _x2, _x3) { \
|
||||
write_ctx_reg((get_gpregs_ctx(_h)), (CTX_GPREG_X3), (_x3)); \
|
||||
SMC_RET3(_h, (_x0), (_x1), (_x2)); \
|
||||
}
|
||||
#define SMC_RET5(_h, _x0, _x1, _x2, _x3, _x4) { \
|
||||
write_ctx_reg((get_gpregs_ctx(_h)), (CTX_GPREG_X4), (_x4)); \
|
||||
SMC_RET4(_h, (_x0), (_x1), (_x2), (_x3)); \
|
||||
}
|
||||
#define SMC_RET6(_h, _x0, _x1, _x2, _x3, _x4, _x5) { \
|
||||
write_ctx_reg((get_gpregs_ctx(_h)), (CTX_GPREG_X5), (_x5)); \
|
||||
SMC_RET5(_h, (_x0), (_x1), (_x2), (_x3), (_x4)); \
|
||||
}
|
||||
#define SMC_RET7(_h, _x0, _x1, _x2, _x3, _x4, _x5, _x6) { \
|
||||
write_ctx_reg((get_gpregs_ctx(_h)), (CTX_GPREG_X6), (_x6)); \
|
||||
SMC_RET6(_h, (_x0), (_x1), (_x2), (_x3), (_x4), (_x5)); \
|
||||
}
|
||||
#define SMC_RET8(_h, _x0, _x1, _x2, _x3, _x4, _x5, _x6, _x7) { \
|
||||
write_ctx_reg((get_gpregs_ctx(_h)), (CTX_GPREG_X7), (_x7)); \
|
||||
SMC_RET7(_h, (_x0), (_x1), (_x2), (_x3), (_x4), (_x5), (_x6)); \
|
||||
}
|
||||
|
||||
/*
|
||||
* Convenience macros to access general purpose registers using handle provided
|
||||
* to SMC handler. These take the offset values defined in context.h
|
||||
*/
|
||||
#define SMC_GET_GP(_h, _g) \
|
||||
read_ctx_reg((get_gpregs_ctx(_h)), (_g))
|
||||
#define SMC_SET_GP(_h, _g, _v) \
|
||||
write_ctx_reg((get_gpregs_ctx(_h)), (_g), (_v))
|
||||
|
||||
/*
|
||||
* Convenience macros to access EL3 context registers using handle provided to
|
||||
* SMC handler. These take the offset values defined in context.h
|
||||
*/
|
||||
#define SMC_GET_EL3(_h, _e) \
|
||||
read_ctx_reg((get_el3state_ctx(_h)), (_e))
|
||||
#define SMC_SET_EL3(_h, _e, _v) \
|
||||
write_ctx_reg((get_el3state_ctx(_h)), (_e), (_v))
|
||||
|
||||
/*
|
||||
* Helper macro to retrieve the SMC parameters from cpu_context_t.
|
||||
*/
|
||||
#define get_smc_params_from_ctx(_hdl, _x1, _x2, _x3, _x4) \
|
||||
do { \
|
||||
const gp_regs_t *regs = get_gpregs_ctx(_hdl); \
|
||||
_x1 = read_ctx_reg(regs, CTX_GPREG_X1); \
|
||||
_x2 = read_ctx_reg(regs, CTX_GPREG_X2); \
|
||||
_x3 = read_ctx_reg(regs, CTX_GPREG_X3); \
|
||||
_x4 = read_ctx_reg(regs, CTX_GPREG_X4); \
|
||||
} while (false)
|
||||
|
||||
typedef struct {
|
||||
uint64_t _regs[SMC_ARGS_END >> 3];
|
||||
} __aligned(CACHE_WRITEBACK_GRANULE) smc_args_t;
|
||||
|
||||
/*
|
||||
* Ensure that the assembler's view of the size of the tsp_args is the
|
||||
* same as the compilers.
|
||||
*/
|
||||
CASSERT(sizeof(smc_args_t) == SMC_ARGS_SIZE, assert_sp_args_size_mismatch);
|
||||
|
||||
static inline smc_args_t smc_helper(uint32_t func, uint64_t arg0,
|
||||
uint64_t arg1, uint64_t arg2,
|
||||
uint64_t arg3, uint64_t arg4,
|
||||
uint64_t arg5, uint64_t arg6)
|
||||
{
|
||||
smc_args_t ret_args = {0};
|
||||
|
||||
register uint64_t r0 __asm__("x0") = func;
|
||||
register uint64_t r1 __asm__("x1") = arg0;
|
||||
register uint64_t r2 __asm__("x2") = arg1;
|
||||
register uint64_t r3 __asm__("x3") = arg2;
|
||||
register uint64_t r4 __asm__("x4") = arg3;
|
||||
register uint64_t r5 __asm__("x5") = arg4;
|
||||
register uint64_t r6 __asm__("x6") = arg5;
|
||||
register uint64_t r7 __asm__("x7") = arg6;
|
||||
|
||||
/* Output registers, also used as inputs ('+' constraint). */
|
||||
__asm__ volatile("smc #0"
|
||||
: "+r"(r0), "+r"(r1), "+r"(r2), "+r"(r3), "+r"(r4),
|
||||
"+r"(r5), "+r"(r6), "+r"(r7));
|
||||
|
||||
ret_args._regs[0] = r0;
|
||||
ret_args._regs[1] = r1;
|
||||
ret_args._regs[2] = r2;
|
||||
ret_args._regs[3] = r3;
|
||||
ret_args._regs[4] = r4;
|
||||
ret_args._regs[5] = r5;
|
||||
ret_args._regs[6] = r6;
|
||||
ret_args._regs[7] = r7;
|
||||
|
||||
return ret_args;
|
||||
}
|
||||
|
||||
#endif /*__ASSEMBLER__*/
|
||||
|
||||
#endif /* SMCCC_HELPERS_H */
|
||||
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef BL1_H
|
||||
#define BL1_H
|
||||
|
||||
#include <common/bl_common.h>
|
||||
|
||||
/*
|
||||
* Defines for BL1 SMC function ids.
|
||||
*/
|
||||
#define BL1_SMC_CALL_COUNT 0x0
|
||||
#define BL1_SMC_UID 0x1
|
||||
/* SMC #0x2 reserved */
|
||||
#define BL1_SMC_VERSION 0x3
|
||||
|
||||
/*
|
||||
* Corresponds to the function ID of the SMC that
|
||||
* the BL1 exception handler service to execute BL31.
|
||||
*/
|
||||
#define BL1_SMC_RUN_IMAGE 0x4
|
||||
|
||||
/*
|
||||
* BL1 SMC version
|
||||
*/
|
||||
#define BL1_SMC_MAJOR_VER UL(0x0)
|
||||
#define BL1_SMC_MINOR_VER UL(0x1)
|
||||
|
||||
/*
|
||||
* Defines for FWU SMC function ids.
|
||||
*/
|
||||
|
||||
#define FWU_SMC_IMAGE_COPY 0x10
|
||||
#define FWU_SMC_IMAGE_AUTH 0x11
|
||||
#define FWU_SMC_IMAGE_EXECUTE 0x12
|
||||
#define FWU_SMC_IMAGE_RESUME 0x13
|
||||
#define FWU_SMC_SEC_IMAGE_DONE 0x14
|
||||
#define FWU_SMC_UPDATE_DONE 0x15
|
||||
#define FWU_SMC_IMAGE_RESET 0x16
|
||||
|
||||
/*
|
||||
* Number of FWU calls (above) implemented
|
||||
*/
|
||||
#define FWU_NUM_SMC_CALLS 7
|
||||
|
||||
#if TRUSTED_BOARD_BOOT
|
||||
# define BL1_NUM_SMC_CALLS (FWU_NUM_SMC_CALLS + 4)
|
||||
#else
|
||||
# define BL1_NUM_SMC_CALLS 4
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The macros below are used to identify FWU
|
||||
* calls from the SMC function ID
|
||||
*/
|
||||
#define FWU_SMC_FID_START FWU_SMC_IMAGE_COPY
|
||||
#define FWU_SMC_FID_END FWU_SMC_IMAGE_RESET
|
||||
#define is_fwu_fid(_fid) \
|
||||
((_fid >= FWU_SMC_FID_START) && (_fid <= FWU_SMC_FID_END))
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
|
||||
#include <lib/cassert.h>
|
||||
|
||||
struct entry_point_info;
|
||||
|
||||
u_register_t bl1_smc_wrapper(uint32_t smc_fid,
|
||||
void *cookie,
|
||||
void *handle,
|
||||
unsigned int flags);
|
||||
|
||||
u_register_t bl1_smc_handler(unsigned int smc_fid,
|
||||
u_register_t x1,
|
||||
u_register_t x2,
|
||||
u_register_t x3,
|
||||
u_register_t x4,
|
||||
void *cookie,
|
||||
void *handle,
|
||||
unsigned int flags);
|
||||
|
||||
void bl1_print_next_bl_ep_info(const struct entry_point_info *bl_ep_info);
|
||||
|
||||
void bl1_setup(void);
|
||||
void bl1_main(void);
|
||||
void bl1_plat_prepare_exit(entry_point_info_t *ep_info);
|
||||
|
||||
/*
|
||||
* Check if the total number of FWU SMC calls are as expected.
|
||||
*/
|
||||
CASSERT(FWU_NUM_SMC_CALLS == \
|
||||
(FWU_SMC_FID_END - FWU_SMC_FID_START + 1),\
|
||||
assert_FWU_NUM_SMC_CALLS_mismatch);
|
||||
|
||||
/* Utility functions */
|
||||
void bl1_calc_bl2_mem_layout(const meminfo_t *bl1_mem_layout,
|
||||
meminfo_t *bl2_mem_layout);
|
||||
|
||||
#endif /* __ASSEMBLER__ */
|
||||
#endif /* BL1_H */
|
||||
@@ -0,0 +1,14 @@
|
||||
/*
|
||||
* Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef TBBR_IMG_DESC_H
|
||||
#define TBBR_IMG_DESC_H
|
||||
|
||||
#include <common/bl_common.h>
|
||||
|
||||
extern image_desc_t bl1_tbbr_image_descs[];
|
||||
|
||||
#endif /* TBBR_IMG_DESC_H */
|
||||
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef BL2_H
|
||||
#define BL2_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
void bl2_setup(u_register_t arg0, u_register_t arg1, u_register_t arg2,
|
||||
u_register_t arg3);
|
||||
void bl2_el3_setup(u_register_t arg0, u_register_t arg1, u_register_t arg2,
|
||||
u_register_t arg3);
|
||||
void bl2_main(void);
|
||||
|
||||
#endif /* BL2_H */
|
||||
@@ -0,0 +1,12 @@
|
||||
/*
|
||||
* Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef BL2U_H
|
||||
#define BL2U_H
|
||||
|
||||
void bl2u_main(void);
|
||||
|
||||
#endif /* BL2U_H */
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2021, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef BL31_H
|
||||
#define BL31_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/*******************************************************************************
|
||||
* Function prototypes
|
||||
******************************************************************************/
|
||||
void bl31_setup(u_register_t arg0, u_register_t arg1, u_register_t arg2,
|
||||
u_register_t arg3);
|
||||
void bl31_next_el_arch_setup(uint32_t security_state);
|
||||
void bl31_set_next_image_type(uint32_t security_state);
|
||||
uint32_t bl31_get_next_image_type(void);
|
||||
void bl31_prepare_next_image_entry(void);
|
||||
void bl31_register_bl32_init(int32_t (*func)(void));
|
||||
void bl31_register_rmm_init(int32_t (*func)(void));
|
||||
void bl31_warm_entrypoint(void);
|
||||
void bl31_main(void);
|
||||
void bl31_lib_init(void);
|
||||
|
||||
#endif /* BL31_H */
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef EA_HANDLE_H
|
||||
#define EA_HANDLE_H
|
||||
|
||||
/* Constants indicating the reason for an External Abort */
|
||||
|
||||
/* External Abort received at SError vector */
|
||||
#define ERROR_EA_ASYNC 0
|
||||
|
||||
/* Synchronous External Abort received at Synchronous exception vector */
|
||||
#define ERROR_EA_SYNC 1
|
||||
|
||||
/* External Abort synchronized by ESB instruction */
|
||||
#define ERROR_EA_ESB 2
|
||||
|
||||
/* RAS event signalled as peripheral interrupt */
|
||||
#define ERROR_INTERRUPT 3
|
||||
|
||||
#endif /* EA_HANDLE_H */
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef EHF_H
|
||||
#define EHF_H
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
|
||||
#include <cdefs.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <lib/utils_def.h>
|
||||
|
||||
/* Valid priorities set bit 0 of the priority handler. */
|
||||
#define EHF_PRI_VALID_ BIT(0)
|
||||
|
||||
/* Marker for no handler registered for a valid priority */
|
||||
#define EHF_NO_HANDLER_ (0U | EHF_PRI_VALID_)
|
||||
|
||||
/* Extract the specified number of top bits from 7 lower bits of priority */
|
||||
#define EHF_PRI_TO_IDX(pri, plat_bits) \
|
||||
((((unsigned) (pri)) & 0x7fu) >> (7u - (plat_bits)))
|
||||
|
||||
/* Install exception priority descriptor at a suitable index */
|
||||
#define EHF_PRI_DESC(plat_bits, priority) \
|
||||
[EHF_PRI_TO_IDX(priority, plat_bits)] = { \
|
||||
.ehf_handler = EHF_NO_HANDLER_, \
|
||||
}
|
||||
|
||||
/* Macro for platforms to regiter its exception priorities */
|
||||
#define EHF_REGISTER_PRIORITIES(priorities, num, bits) \
|
||||
const ehf_priorities_t exception_data = { \
|
||||
.num_priorities = (num), \
|
||||
.ehf_priorities = (priorities), \
|
||||
.pri_bits = (bits), \
|
||||
}
|
||||
|
||||
/*
|
||||
* Priority stack, managed as a bitmap.
|
||||
*
|
||||
* Currently only supports 32 priority levels, allowing platforms to use up to 5
|
||||
* top bits of priority. But the type can be changed to uint64_t should need
|
||||
* arise to support 64 priority levels, allowing platforms to use up to 6 top
|
||||
* bits of priority.
|
||||
*/
|
||||
typedef uint32_t ehf_pri_bits_t;
|
||||
|
||||
/*
|
||||
* Per-PE exception data. The data for each PE is kept as a per-CPU data field.
|
||||
* See cpu_data.h.
|
||||
*/
|
||||
typedef struct {
|
||||
ehf_pri_bits_t active_pri_bits;
|
||||
|
||||
/* Priority mask value before any priority levels were active */
|
||||
uint8_t init_pri_mask;
|
||||
|
||||
/* Non-secure priority mask value stashed during Secure execution */
|
||||
uint8_t ns_pri_mask;
|
||||
} __aligned(sizeof(uint64_t)) pe_exc_data_t;
|
||||
|
||||
typedef int (*ehf_handler_t)(uint32_t intr_raw, uint32_t flags, void *handle,
|
||||
void *cookie);
|
||||
|
||||
typedef struct ehf_pri_desc {
|
||||
/*
|
||||
* 4-byte-aligned exception handler. Bit 0 indicates the corresponding
|
||||
* priority level is valid. This is effectively of ehf_handler_t type,
|
||||
* but left as uintptr_t in order to make pointer arithmetic convenient.
|
||||
*/
|
||||
uintptr_t ehf_handler;
|
||||
} ehf_pri_desc_t;
|
||||
|
||||
typedef struct ehf_priority_type {
|
||||
ehf_pri_desc_t *ehf_priorities;
|
||||
unsigned int num_priorities;
|
||||
unsigned int pri_bits;
|
||||
} ehf_priorities_t;
|
||||
|
||||
void ehf_init(void);
|
||||
void ehf_activate_priority(unsigned int priority);
|
||||
void ehf_deactivate_priority(unsigned int priority);
|
||||
void ehf_register_priority_handler(unsigned int pri, ehf_handler_t handler);
|
||||
void ehf_allow_ns_preemption(uint64_t preempt_ret_code);
|
||||
unsigned int ehf_is_ns_preemption_allowed(void);
|
||||
|
||||
#endif /* __ASSEMBLER__ */
|
||||
|
||||
#endif /* EHF_H */
|
||||
@@ -0,0 +1,155 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2022, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef INTERRUPT_MGMT_H
|
||||
#define INTERRUPT_MGMT_H
|
||||
|
||||
#include <arch.h>
|
||||
#include <lib/utils_def.h>
|
||||
|
||||
/*******************************************************************************
|
||||
* Constants for the types of interrupts recognised by the IM framework
|
||||
******************************************************************************/
|
||||
#define INTR_TYPE_S_EL1 U(0)
|
||||
#define INTR_TYPE_EL3 U(1)
|
||||
#define INTR_TYPE_NS U(2)
|
||||
#define MAX_INTR_TYPES U(3)
|
||||
#define INTR_TYPE_INVAL MAX_INTR_TYPES
|
||||
|
||||
/* Interrupt routing modes */
|
||||
#define INTR_ROUTING_MODE_PE 0
|
||||
#define INTR_ROUTING_MODE_ANY 1
|
||||
|
||||
/*
|
||||
* Constant passed to the interrupt handler in the 'id' field when the
|
||||
* framework does not read the gic registers to determine the interrupt id.
|
||||
*/
|
||||
#define INTR_ID_UNAVAILABLE U(0xFFFFFFFF)
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Mask for _both_ the routing model bits in the 'flags' parameter and
|
||||
* constants to define the valid routing models for each supported interrupt
|
||||
* type
|
||||
******************************************************************************/
|
||||
#define INTR_RM_FLAGS_SHIFT U(0x0)
|
||||
#define INTR_RM_FLAGS_MASK U(0x3)
|
||||
/* Routed to EL3 from NS. Taken to S-EL1 from Secure */
|
||||
#define INTR_SEL1_VALID_RM0 U(0x2)
|
||||
/* Routed to EL3 from NS and Secure */
|
||||
#define INTR_SEL1_VALID_RM1 U(0x3)
|
||||
/* Routed to EL1/EL2 from NS and to S-EL1 from Secure */
|
||||
#define INTR_NS_VALID_RM0 U(0x0)
|
||||
/* Routed to EL1/EL2 from NS and to EL3 from Secure */
|
||||
#define INTR_NS_VALID_RM1 U(0x1)
|
||||
/* Routed to EL3 from NS. Taken to S-EL1 from Secure and handed over to EL3 */
|
||||
#define INTR_EL3_VALID_RM0 U(0x2)
|
||||
/* Routed to EL3 from NS and Secure */
|
||||
#define INTR_EL3_VALID_RM1 U(0x3)
|
||||
/* This is the default routing model */
|
||||
#define INTR_DEFAULT_RM U(0x0)
|
||||
|
||||
/*******************************************************************************
|
||||
* Constants for the _individual_ routing model bits in the 'flags' field for
|
||||
* each interrupt type and mask to validate the 'flags' parameter while
|
||||
* registering an interrupt handler
|
||||
******************************************************************************/
|
||||
#define INTR_TYPE_FLAGS_MASK U(0xFFFFFFFC)
|
||||
|
||||
#define INTR_RM_FROM_SEC_SHIFT SECURE /* BIT[0] */
|
||||
#define INTR_RM_FROM_NS_SHIFT NON_SECURE /* BIT[1] */
|
||||
#define INTR_RM_FROM_FLAG_MASK U(1)
|
||||
#define get_interrupt_rm_flag(flag, ss) \
|
||||
((((flag) >> INTR_RM_FLAGS_SHIFT) >> (ss)) & INTR_RM_FROM_FLAG_MASK)
|
||||
#define set_interrupt_rm_flag(flag, ss) ((flag) |= U(1) << (ss))
|
||||
#define clr_interrupt_rm_flag(flag, ss) ((flag) &= ~(U(1) << (ss)))
|
||||
|
||||
/*******************************************************************************
|
||||
* Macros to set the 'flags' parameter passed to an interrupt type handler. Only
|
||||
* the flag to indicate the security state when the exception was generated is
|
||||
* supported.
|
||||
******************************************************************************/
|
||||
#define INTR_SRC_SS_FLAG_SHIFT U(0) /* BIT[0] */
|
||||
#define INTR_SRC_SS_FLAG_MASK U(1)
|
||||
#define set_interrupt_src_ss(flag, val) ((flag) |= (val) << INTR_SRC_SS_FLAG_SHIFT)
|
||||
#define clr_interrupt_src_ss(flag) ((flag) &= ~(U(1) << INTR_SRC_SS_FLAG_SHIFT))
|
||||
#define get_interrupt_src_ss(flag) (((flag) >> INTR_SRC_SS_FLAG_SHIFT) & \
|
||||
INTR_SRC_SS_FLAG_MASK)
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/*******************************************************************************
|
||||
* Helpers to validate the routing model bits in the 'flags' for a type
|
||||
* of interrupt. If the model does not match one of the valid masks
|
||||
* -EINVAL is returned.
|
||||
******************************************************************************/
|
||||
static inline int32_t validate_sel1_interrupt_rm(uint32_t x)
|
||||
{
|
||||
if ((x == INTR_SEL1_VALID_RM0) || (x == INTR_SEL1_VALID_RM1))
|
||||
return 0;
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static inline int32_t validate_ns_interrupt_rm(uint32_t x)
|
||||
{
|
||||
if ((x == INTR_NS_VALID_RM0) || (x == INTR_NS_VALID_RM1))
|
||||
return 0;
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static inline int32_t validate_el3_interrupt_rm(uint32_t x)
|
||||
{
|
||||
#if EL3_EXCEPTION_HANDLING && !(defined(SPD_spmd) && (SPMD_SPM_AT_SEL2 == 1))
|
||||
/*
|
||||
* With EL3 exception handling, EL3 interrupts are always routed to EL3
|
||||
* from both Secure and Non-secure, when the SPMC does not live in S-EL2.
|
||||
* Therefore INTR_EL3_VALID_RM1 is the only valid routing model.
|
||||
*/
|
||||
if (x == INTR_EL3_VALID_RM1)
|
||||
return 0;
|
||||
#else
|
||||
/*
|
||||
* When EL3_EXCEPTION_HANDLING is not defined both routing modes are
|
||||
* valid. This is the most common case. The exception to this rule is
|
||||
* when EL3_EXCEPTION_HANDLING is defined but also when the SPMC lives
|
||||
* at S-EL2. In this case, Group0 Interrupts are trapped to the SPMC
|
||||
* when running in S-EL0 and S-EL1. The SPMC may handle the interrupt
|
||||
* itself, delegate it to an SP or forward to EL3 for handling.
|
||||
*/
|
||||
if ((x == INTR_EL3_VALID_RM0) || (x == INTR_EL3_VALID_RM1))
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Prototype for defining a handler for an interrupt type
|
||||
******************************************************************************/
|
||||
typedef uint64_t (*interrupt_type_handler_t)(uint32_t id,
|
||||
uint32_t flags,
|
||||
void *handle,
|
||||
void *cookie);
|
||||
|
||||
/*******************************************************************************
|
||||
* Function & variable prototypes
|
||||
******************************************************************************/
|
||||
u_register_t get_scr_el3_from_routing_model(uint32_t security_state);
|
||||
int32_t set_routing_model(uint32_t type, uint32_t flags);
|
||||
int32_t register_interrupt_type_handler(uint32_t type,
|
||||
interrupt_type_handler_t handler,
|
||||
uint32_t flags);
|
||||
interrupt_type_handler_t get_interrupt_type_handler(uint32_t type);
|
||||
int disable_intr_rm_local(uint32_t type, uint32_t security_state);
|
||||
int enable_intr_rm_local(uint32_t type, uint32_t security_state);
|
||||
|
||||
#endif /*__ASSEMBLER__*/
|
||||
#endif /* INTERRUPT_MGMT_H */
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
|
||||
* Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef TLK_H
|
||||
#define TLK_H
|
||||
|
||||
#include <lib/utils_def.h>
|
||||
|
||||
/*
|
||||
* Generate function IDs for the Trusted OS/Apps
|
||||
*/
|
||||
#define TLK_TOS_YIELD_FID(fid) ((fid) | 0x72000000 | (0 << 31))
|
||||
#define TLK_TA_YIELD_FID(fid) ((fid) | 0x70000000 | (0 << 31))
|
||||
|
||||
/*
|
||||
* Trusted OS specific function IDs
|
||||
*/
|
||||
#define TLK_REGISTER_LOGBUF TLK_TOS_YIELD_FID(0x1)
|
||||
#define TLK_REGISTER_REQBUF TLK_TOS_YIELD_FID(0x2)
|
||||
#define TLK_SS_REGISTER_HANDLER TLK_TOS_YIELD_FID(0x3)
|
||||
#define TLK_REGISTER_NS_DRAM_RANGES TLK_TOS_YIELD_FID(0x4)
|
||||
#define TLK_SET_ROOT_OF_TRUST TLK_TOS_YIELD_FID(0x5)
|
||||
#define TLK_SET_BL_VERSION TLK_TOS_YIELD_FID(0x6)
|
||||
#define TLK_LOCK_BL_INTERFACE TLK_TOS_YIELD_FID(0x7)
|
||||
#define TLK_BL_RPMB_SERVICE TLK_TOS_YIELD_FID(0x8)
|
||||
#define TLK_RESUME_FID TLK_TOS_YIELD_FID(0x100)
|
||||
#define TLK_SYSTEM_SUSPEND TLK_TOS_YIELD_FID(0xE001)
|
||||
#define TLK_SYSTEM_RESUME TLK_TOS_YIELD_FID(0xE002)
|
||||
#define TLK_IRQ_FIRED TLK_TOS_YIELD_FID(0xE004)
|
||||
|
||||
/*
|
||||
* SMC function IDs that TLK uses to signal various forms of completions
|
||||
* to the secure payload dispatcher.
|
||||
*/
|
||||
#define TLK_REQUEST_DONE (0x32000001 | (ULL(1) << 31))
|
||||
#define TLK_PREEMPTED (0x32000002 | (ULL(1) << 31))
|
||||
#define TLK_ENTRY_DONE (0x32000003 | (ULL(1) << 31))
|
||||
#define TLK_VA_TRANSLATE (0x32000004 | (ULL(1) << 31))
|
||||
#define TLK_SUSPEND_DONE (0x32000005 | (ULL(1) << 31))
|
||||
#define TLK_RESUME_DONE (0x32000006 | (ULL(1) << 31))
|
||||
#define TLK_IRQ_DONE (0x32000008 | (ULL(1) << 31))
|
||||
|
||||
/*
|
||||
* Trusted Application specific function IDs
|
||||
*/
|
||||
#define TLK_OPEN_TA_SESSION TLK_TA_YIELD_FID(0x1)
|
||||
#define TLK_CLOSE_TA_SESSION TLK_TA_YIELD_FID(0x2)
|
||||
#define TLK_TA_LAUNCH_OP TLK_TA_YIELD_FID(0x3)
|
||||
#define TLK_TA_SEND_EVENT TLK_TA_YIELD_FID(0x4)
|
||||
|
||||
/*
|
||||
* Total number of function IDs implemented for services offered to NS clients.
|
||||
*/
|
||||
#define TLK_NUM_FID 7
|
||||
|
||||
/* TLK implementation version numbers */
|
||||
#define TLK_VERSION_MAJOR 0x0 /* Major version */
|
||||
#define TLK_VERSION_MINOR 0x1 /* Minor version */
|
||||
|
||||
/*
|
||||
* Standard Trusted OS Function IDs that fall under Trusted OS call range
|
||||
* according to SMC calling convention
|
||||
*/
|
||||
#define TOS_CALL_COUNT 0xbf00ff00 /* Number of calls implemented */
|
||||
#define TOS_UID 0xbf00ff01 /* Implementation UID */
|
||||
#define TOS_CALL_VERSION 0xbf00ff03 /* Trusted OS Call Version */
|
||||
|
||||
#endif /* TLK_H */
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (c) 2021-2022, ProvenRun S.A.S. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef __PNC_H__
|
||||
#define __PNC_H__
|
||||
|
||||
#define SMC_YIELD 0xbf000000
|
||||
#define SMC_ACTION_FROM_S 0xbf000001
|
||||
#define SMC_GET_SHAREDMEM 0xbf000002
|
||||
#define SMC_CONFIG_SHAREDMEM 0xbf000003
|
||||
#define SMC_ACTION_FROM_NS 0xbf000004
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
void *pncd_context_switch_to(unsigned long security_state);
|
||||
int plat_pncd_setup(void);
|
||||
uintptr_t plat_pncd_smc_handler(uint32_t smc_fid, u_register_t x1,
|
||||
u_register_t x2, u_register_t x3,
|
||||
u_register_t x4, void *cookie, void *handle,
|
||||
u_register_t flags);
|
||||
|
||||
#endif /* __ASSEMBLER__ */
|
||||
|
||||
#endif /* __PNC_H__ */
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef PLATFORM_SP_MIN_H
|
||||
#define PLATFORM_SP_MIN_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <common/bl_common.h>
|
||||
|
||||
/*******************************************************************************
|
||||
* Mandatory SP_MIN functions
|
||||
******************************************************************************/
|
||||
void sp_min_early_platform_setup2(u_register_t arg0, u_register_t arg1,
|
||||
u_register_t arg2, u_register_t arg3);
|
||||
void sp_min_platform_setup(void);
|
||||
void sp_min_plat_runtime_setup(void);
|
||||
void sp_min_plat_arch_setup(void);
|
||||
entry_point_info_t *sp_min_plat_get_bl33_ep_info(void);
|
||||
void sp_min_warm_entrypoint(void);
|
||||
|
||||
/* Platforms that enable SP_MIN_WITH_SECURE_FIQ shall implement this api */
|
||||
void sp_min_plat_fiq_handler(uint32_t id);
|
||||
|
||||
#endif /* PLATFORM_SP_MIN_H */
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef PLATFORM_TSP_H
|
||||
#define PLATFORM_TSP_H
|
||||
|
||||
/*******************************************************************************
|
||||
* Mandatory TSP functions (only if platform contains a TSP)
|
||||
******************************************************************************/
|
||||
void tsp_early_platform_setup(void);
|
||||
void tsp_plat_arch_setup(void);
|
||||
void tsp_platform_setup(void);
|
||||
|
||||
#endif /* PLATFORM_TSP_H */
|
||||
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2022, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef TSP_H
|
||||
#define TSP_H
|
||||
|
||||
/*
|
||||
* SMC function IDs that TSP uses to signal various forms of completions
|
||||
* to the secure payload dispatcher.
|
||||
*/
|
||||
#define TSP_ENTRY_DONE 0xf2000000
|
||||
#define TSP_ON_DONE 0xf2000001
|
||||
#define TSP_OFF_DONE 0xf2000002
|
||||
#define TSP_SUSPEND_DONE 0xf2000003
|
||||
#define TSP_RESUME_DONE 0xf2000004
|
||||
#define TSP_PREEMPTED 0xf2000005
|
||||
#define TSP_ABORT_DONE 0xf2000007
|
||||
#define TSP_SYSTEM_OFF_DONE 0xf2000008
|
||||
#define TSP_SYSTEM_RESET_DONE 0xf2000009
|
||||
|
||||
/*
|
||||
* Function identifiers to handle S-EL1 interrupt through the synchronous
|
||||
* handling model. If the TSP was previously interrupted then control has to
|
||||
* be returned to the TSPD after handling the interrupt else execution can
|
||||
* remain in the TSP.
|
||||
*/
|
||||
#define TSP_HANDLED_S_EL1_INTR 0xf2000006
|
||||
|
||||
/* SMC function ID that TSP uses to request service from secure monitor */
|
||||
#define TSP_GET_ARGS 0xf2001000
|
||||
|
||||
/*
|
||||
* Identifiers for various TSP services. Corresponding function IDs (whether
|
||||
* fast or yielding) are generated by macros defined below
|
||||
*/
|
||||
#define TSP_ADD 0x2000
|
||||
#define TSP_SUB 0x2001
|
||||
#define TSP_MUL 0x2002
|
||||
#define TSP_DIV 0x2003
|
||||
#define TSP_HANDLE_SEL1_INTR_AND_RETURN 0x2004
|
||||
#define TSP_CHECK_DIT 0x2005
|
||||
|
||||
/*
|
||||
* Identify a TSP service from function ID filtering the last 16 bits from the
|
||||
* SMC function ID
|
||||
*/
|
||||
#define TSP_BARE_FID(fid) ((fid) & 0xffff)
|
||||
|
||||
/*
|
||||
* Generate function IDs for TSP services to be used in SMC calls, by
|
||||
* appropriately setting bit 31 to differentiate yielding and fast SMC calls
|
||||
*/
|
||||
#define TSP_YIELD_FID(fid) ((TSP_BARE_FID(fid) | 0x72000000))
|
||||
#define TSP_FAST_FID(fid) ((TSP_BARE_FID(fid) | 0x72000000) | (1u << 31))
|
||||
|
||||
/* SMC function ID to request a previously preempted yielding smc */
|
||||
#define TSP_FID_RESUME TSP_YIELD_FID(0x3000)
|
||||
/*
|
||||
* SMC function ID to request abortion of a previously preempted yielding SMC. A
|
||||
* fast SMC is used so that the TSP abort handler does not have to be
|
||||
* reentrant.
|
||||
*/
|
||||
#define TSP_FID_ABORT TSP_FAST_FID(0x3001)
|
||||
|
||||
/*
|
||||
* Total number of function IDs implemented for services offered to NS clients.
|
||||
* The function IDs are defined above
|
||||
*/
|
||||
#define TSP_NUM_FID 0x5
|
||||
|
||||
/* TSP implementation version numbers */
|
||||
#define TSP_VERSION_MAJOR 0x0 /* Major version */
|
||||
#define TSP_VERSION_MINOR 0x1 /* Minor version */
|
||||
|
||||
/*
|
||||
* Standard Trusted OS Function IDs that fall under Trusted OS call range
|
||||
* according to SMC calling convention
|
||||
*/
|
||||
#define TOS_CALL_COUNT 0xbf00ff00 /* Number of calls implemented */
|
||||
#define TOS_UID 0xbf00ff01 /* Implementation UID */
|
||||
/* 0xbf00ff02 is reserved */
|
||||
#define TOS_CALL_VERSION 0xbf00ff03 /* Trusted OS Call Version */
|
||||
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
typedef uint32_t tsp_vector_isn_t;
|
||||
|
||||
typedef struct tsp_vectors {
|
||||
tsp_vector_isn_t yield_smc_entry;
|
||||
tsp_vector_isn_t fast_smc_entry;
|
||||
tsp_vector_isn_t cpu_on_entry;
|
||||
tsp_vector_isn_t cpu_off_entry;
|
||||
tsp_vector_isn_t cpu_resume_entry;
|
||||
tsp_vector_isn_t cpu_suspend_entry;
|
||||
tsp_vector_isn_t sel1_intr_entry;
|
||||
tsp_vector_isn_t system_off_entry;
|
||||
tsp_vector_isn_t system_reset_entry;
|
||||
tsp_vector_isn_t abort_yield_smc_entry;
|
||||
} tsp_vectors_t;
|
||||
|
||||
void tsp_setup(void);
|
||||
|
||||
#endif /* __ASSEMBLER__ */
|
||||
|
||||
#endif /* TSP_H */
|
||||
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
#ifndef ASM_MACROS_COMMON_S
|
||||
#define ASM_MACROS_COMMON_S
|
||||
|
||||
/*
|
||||
* This macro is used to create a function label and place the
|
||||
* code into a separate text section based on the function name
|
||||
* to enable elimination of unused code during linking. It also adds
|
||||
* basic debug information to enable call stack printing most of the
|
||||
* time. The optional _align parameter can be used to force a
|
||||
* non-standard alignment (indicated in powers of 2). The default is
|
||||
* _align=2 because both Aarch32 and Aarch64 instructions must be
|
||||
* word aligned. Do *not* try to use a raw .align directive. Since func
|
||||
* switches to a new section, this would not have the desired effect.
|
||||
*/
|
||||
.macro func _name, _align=2
|
||||
/*
|
||||
* Add Call Frame Information entry in the .debug_frame section for
|
||||
* debugger consumption. This enables callstack printing in debuggers.
|
||||
* This does not use any space in the final loaded binary, only in the
|
||||
* ELF file.
|
||||
* Note that a function manipulating the CFA pointer location (i.e. the
|
||||
* x29 frame pointer on AArch64) should declare it using the
|
||||
* appropriate .cfi* directives, or be prepared to have a degraded
|
||||
* debugging experience.
|
||||
*/
|
||||
.cfi_sections .debug_frame
|
||||
.section .text.asm.\_name, "ax"
|
||||
.type \_name, %function
|
||||
/*
|
||||
* .cfi_startproc and .cfi_endproc are needed to output entries in
|
||||
* .debug_frame
|
||||
*/
|
||||
.cfi_startproc
|
||||
.align \_align
|
||||
\_name:
|
||||
#if ENABLE_BTI
|
||||
/* When Branch Target Identification is enabled, insert "bti jc"
|
||||
* instruction to enable indirect calls and branches
|
||||
*/
|
||||
bti jc
|
||||
#endif
|
||||
.endm
|
||||
|
||||
/*
|
||||
* This macro is used to mark the end of a function.
|
||||
*/
|
||||
.macro endfunc _name
|
||||
.cfi_endproc
|
||||
.size \_name, . - \_name
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Theses macros are used to create function labels for deprecated
|
||||
* APIs. If ERROR_DEPRECATED is non zero, the callers of these APIs
|
||||
* will fail to link and cause build failure.
|
||||
*/
|
||||
#if ERROR_DEPRECATED
|
||||
.macro func_deprecated _name
|
||||
func deprecated\_name
|
||||
.endm
|
||||
|
||||
.macro endfunc_deprecated _name
|
||||
endfunc deprecated\_name
|
||||
.endm
|
||||
#else
|
||||
.macro func_deprecated _name
|
||||
func \_name
|
||||
.endm
|
||||
|
||||
.macro endfunc_deprecated _name
|
||||
endfunc \_name
|
||||
.endm
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Helper assembler macro to count trailing zeros. The output is
|
||||
* populated in the `TZ_COUNT` symbol.
|
||||
*/
|
||||
.macro count_tz _value, _tz_count
|
||||
.if \_value
|
||||
count_tz "(\_value >> 1)", "(\_tz_count + 1)"
|
||||
.else
|
||||
.equ TZ_COUNT, (\_tz_count - 1)
|
||||
.endif
|
||||
.endm
|
||||
|
||||
/*
|
||||
* This macro declares an array of 1 or more stacks, properly
|
||||
* aligned and in the requested section
|
||||
*/
|
||||
#define DEFAULT_STACK_ALIGN (1 << 6) /* In case the caller doesnt provide alignment */
|
||||
|
||||
.macro declare_stack _name, _section, _size, _count, _align=DEFAULT_STACK_ALIGN
|
||||
count_tz \_align, 0
|
||||
.if (\_align - (1 << TZ_COUNT))
|
||||
.error "Incorrect stack alignment specified (Must be a power of 2)."
|
||||
.endif
|
||||
.if ((\_size & ((1 << TZ_COUNT) - 1)) <> 0)
|
||||
.error "Stack size not correctly aligned"
|
||||
.endif
|
||||
.section \_section, "aw", %nobits
|
||||
.align TZ_COUNT
|
||||
\_name:
|
||||
.space ((\_count) * (\_size)), 0
|
||||
.endm
|
||||
|
||||
|
||||
#endif /* ASM_MACROS_COMMON_S */
|
||||
@@ -0,0 +1,195 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2022, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef BL_COMMON_H
|
||||
#define BL_COMMON_H
|
||||
|
||||
#include <common/ep_info.h>
|
||||
#include <common/param_header.h>
|
||||
#include <lib/utils_def.h>
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <lib/cassert.h>
|
||||
#endif /* __ASSEMBLER__ */
|
||||
|
||||
#include <export/common/bl_common_exp.h>
|
||||
|
||||
#define UP U(1)
|
||||
#define DOWN U(0)
|
||||
|
||||
/*******************************************************************************
|
||||
* Constants to identify the location of a memory region in a given memory
|
||||
* layout.
|
||||
******************************************************************************/
|
||||
#define TOP U(0x1)
|
||||
#define BOTTOM U(0x0)
|
||||
|
||||
/*******************************************************************************
|
||||
* Constants to indicate type of exception to the common exception handler.
|
||||
******************************************************************************/
|
||||
#define SYNC_EXCEPTION_SP_EL0 U(0x0)
|
||||
#define IRQ_SP_EL0 U(0x1)
|
||||
#define FIQ_SP_EL0 U(0x2)
|
||||
#define SERROR_SP_EL0 U(0x3)
|
||||
#define SYNC_EXCEPTION_SP_ELX U(0x4)
|
||||
#define IRQ_SP_ELX U(0x5)
|
||||
#define FIQ_SP_ELX U(0x6)
|
||||
#define SERROR_SP_ELX U(0x7)
|
||||
#define SYNC_EXCEPTION_AARCH64 U(0x8)
|
||||
#define IRQ_AARCH64 U(0x9)
|
||||
#define FIQ_AARCH64 U(0xa)
|
||||
#define SERROR_AARCH64 U(0xb)
|
||||
#define SYNC_EXCEPTION_AARCH32 U(0xc)
|
||||
#define IRQ_AARCH32 U(0xd)
|
||||
#define FIQ_AARCH32 U(0xe)
|
||||
#define SERROR_AARCH32 U(0xf)
|
||||
|
||||
/*
|
||||
* Mapping to connect linker symbols from .ld.S with their counterparts
|
||||
* from .scat for the BL31 image
|
||||
*/
|
||||
#if defined(USE_ARM_LINK)
|
||||
#define __BL31_END__ Load$$LR$$LR_END$$Base
|
||||
#define __BSS_START__ Load$$LR$$LR_BSS$$Base
|
||||
#define __BSS_END__ Load$$LR$$LR_BSS$$Limit
|
||||
#define __BSS_SIZE__ Load$$LR$$LR_BSS$$Length
|
||||
#define __COHERENT_RAM_START__ Load$$LR$$LR_COHERENT_RAM$$Base
|
||||
#define __COHERENT_RAM_END_UNALIGNED__ Load$$__COHERENT_RAM_EPILOGUE_UNALIGNED__$$Base
|
||||
#define __COHERENT_RAM_END__ Load$$LR$$LR_COHERENT_RAM$$Limit
|
||||
#define __COHERENT_RAM_UNALIGNED_SIZE__ Load$$__COHERENT_RAM__$$Length
|
||||
#define __CPU_OPS_START__ Load$$__CPU_OPS__$$Base
|
||||
#define __CPU_OPS_END__ Load$$__CPU_OPS__$$Limit
|
||||
#define __DATA_START__ Load$$__DATA__$$Base
|
||||
#define __DATA_END__ Load$$__DATA__$$Limit
|
||||
#define __GOT_START__ Load$$__GOT__$$Base
|
||||
#define __GOT_END__ Load$$__GOT__$$Limit
|
||||
#define __PERCPU_BAKERY_LOCK_START__ Load$$__BAKERY_LOCKS__$$Base
|
||||
#define __PERCPU_BAKERY_LOCK_END__ Load$$__BAKERY_LOCKS_EPILOGUE__$$Base
|
||||
#define __PMF_SVC_DESCS_START__ Load$$__PMF_SVC_DESCS__$$Base
|
||||
#define __PMF_SVC_DESCS_END__ Load$$__PMF_SVC_DESCS__$$Limit
|
||||
#define __PMF_TIMESTAMP_START__ Load$$__PMF_TIMESTAMP__$$Base
|
||||
#define __PMF_TIMESTAMP_END__ Load$$__PER_CPU_TIMESTAMPS__$$Limit
|
||||
#define __PMF_PERCPU_TIMESTAMP_END__ Load$$__PMF_TIMESTAMP_EPILOGUE__$$Base
|
||||
#define __RELA_END__ Load$$__RELA__$$Limit
|
||||
#define __RELA_START__ Load$$__RELA__$$Base
|
||||
#define __RODATA_START__ Load$$__RODATA__$$Base
|
||||
#define __RODATA_END__ Load$$__RODATA_EPILOGUE__$$Base
|
||||
#define __RT_SVC_DESCS_START__ Load$$__RT_SVC_DESCS__$$Base
|
||||
#define __RT_SVC_DESCS_END__ Load$$__RT_SVC_DESCS__$$Limit
|
||||
#if SPMC_AT_EL3
|
||||
#define __EL3_LP_DESCS_START__ Load$$__EL3_LP_DESCS__$$Base
|
||||
#define __EL3_LP_DESCS_END__ Load$$__EL3_LP_DESCS__$$Limit
|
||||
#endif
|
||||
#define __RW_START__ Load$$LR$$LR_RW_DATA$$Base
|
||||
#define __RW_END__ Load$$LR$$LR_END$$Base
|
||||
#define __SPM_SHIM_EXCEPTIONS_START__ Load$$__SPM_SHIM_EXCEPTIONS__$$Base
|
||||
#define __SPM_SHIM_EXCEPTIONS_END__ Load$$__SPM_SHIM_EXCEPTIONS_EPILOGUE__$$Base
|
||||
#define __STACKS_START__ Load$$__STACKS__$$Base
|
||||
#define __STACKS_END__ Load$$__STACKS__$$Limit
|
||||
#define __TEXT_START__ Load$$__TEXT__$$Base
|
||||
#define __TEXT_END__ Load$$__TEXT_EPILOGUE__$$Base
|
||||
#endif /* USE_ARM_LINK */
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
|
||||
/*
|
||||
* Declarations of linker defined symbols to help determine memory layout of
|
||||
* BL images
|
||||
*/
|
||||
#if SEPARATE_CODE_AND_RODATA
|
||||
IMPORT_SYM(uintptr_t, __TEXT_START__, BL_CODE_BASE);
|
||||
IMPORT_SYM(uintptr_t, __TEXT_END__, BL_CODE_END);
|
||||
IMPORT_SYM(uintptr_t, __RODATA_START__, BL_RO_DATA_BASE);
|
||||
IMPORT_SYM(uintptr_t, __RODATA_END__, BL_RO_DATA_END);
|
||||
#else
|
||||
IMPORT_SYM(uintptr_t, __RO_START__, BL_CODE_BASE);
|
||||
IMPORT_SYM(uintptr_t, __RO_END__, BL_CODE_END);
|
||||
#endif
|
||||
#if SEPARATE_NOBITS_REGION
|
||||
IMPORT_SYM(uintptr_t, __NOBITS_START__, BL_NOBITS_BASE);
|
||||
IMPORT_SYM(uintptr_t, __NOBITS_END__, BL_NOBITS_END);
|
||||
#endif
|
||||
IMPORT_SYM(uintptr_t, __RW_END__, BL_END);
|
||||
|
||||
#if defined(IMAGE_BL1)
|
||||
IMPORT_SYM(uintptr_t, __BL1_ROM_END__, BL1_ROM_END);
|
||||
|
||||
IMPORT_SYM(uintptr_t, __BL1_RAM_START__, BL1_RAM_BASE);
|
||||
IMPORT_SYM(uintptr_t, __BL1_RAM_END__, BL1_RAM_LIMIT);
|
||||
#elif defined(IMAGE_BL2)
|
||||
IMPORT_SYM(uintptr_t, __BL2_END__, BL2_END);
|
||||
#elif defined(IMAGE_BL2U)
|
||||
IMPORT_SYM(uintptr_t, __BL2U_END__, BL2U_END);
|
||||
#elif defined(IMAGE_BL31)
|
||||
IMPORT_SYM(uintptr_t, __BL31_START__, BL31_START);
|
||||
IMPORT_SYM(uintptr_t, __BL31_END__, BL31_END);
|
||||
#elif defined(IMAGE_BL32)
|
||||
IMPORT_SYM(uintptr_t, __BL32_END__, BL32_END);
|
||||
#elif defined(IMAGE_RMM)
|
||||
IMPORT_SYM(uintptr_t, __RMM_END__, RMM_END);
|
||||
#endif /* IMAGE_BLX */
|
||||
|
||||
/* The following symbols are only exported from the BL2 at EL3 linker script. */
|
||||
#if BL2_IN_XIP_MEM && defined(IMAGE_BL2)
|
||||
IMPORT_SYM(uintptr_t, __BL2_ROM_END__, BL2_ROM_END);
|
||||
|
||||
IMPORT_SYM(uintptr_t, __BL2_RAM_START__, BL2_RAM_BASE);
|
||||
IMPORT_SYM(uintptr_t, __BL2_RAM_END__, BL2_RAM_END);
|
||||
#endif /* BL2_IN_XIP_MEM */
|
||||
|
||||
/*
|
||||
* The next 2 constants identify the extents of the coherent memory region.
|
||||
* These addresses are used by the MMU setup code and therefore they must be
|
||||
* page-aligned. It is the responsibility of the linker script to ensure that
|
||||
* __COHERENT_RAM_START__ and __COHERENT_RAM_END__ linker symbols refer to
|
||||
* page-aligned addresses.
|
||||
*/
|
||||
#if USE_COHERENT_MEM
|
||||
IMPORT_SYM(uintptr_t, __COHERENT_RAM_START__, BL_COHERENT_RAM_BASE);
|
||||
IMPORT_SYM(uintptr_t, __COHERENT_RAM_END__, BL_COHERENT_RAM_END);
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
* Structure used for telling the next BL how much of a particular type of
|
||||
* memory is available for its use and how much is already used.
|
||||
******************************************************************************/
|
||||
typedef struct meminfo {
|
||||
uintptr_t total_base;
|
||||
size_t total_size;
|
||||
} meminfo_t;
|
||||
|
||||
/*******************************************************************************
|
||||
* Function & variable prototypes
|
||||
******************************************************************************/
|
||||
int load_auth_image(unsigned int image_id, image_info_t *image_data);
|
||||
|
||||
#if TRUSTED_BOARD_BOOT && defined(DYN_DISABLE_AUTH)
|
||||
/*
|
||||
* API to dynamically disable authentication. Only meant for development
|
||||
* systems.
|
||||
*/
|
||||
void dyn_disable_auth(void);
|
||||
#endif
|
||||
|
||||
extern const char build_message[];
|
||||
extern const char version_string[];
|
||||
const char *get_version(void);
|
||||
|
||||
void print_entry_point_info(const entry_point_info_t *ep_info);
|
||||
uintptr_t page_align(uintptr_t value, unsigned dir);
|
||||
|
||||
struct mmap_region;
|
||||
|
||||
void setup_page_tables(const struct mmap_region *bl_regions,
|
||||
const struct mmap_region *plat_regions);
|
||||
|
||||
void bl_handle_pauth(void);
|
||||
|
||||
#endif /*__ASSEMBLER__*/
|
||||
|
||||
#endif /* BL_COMMON_H */
|
||||
@@ -0,0 +1,231 @@
|
||||
/*
|
||||
* Copyright (c) 2020-2022, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef BL_COMMON_LD_H
|
||||
#define BL_COMMON_LD_H
|
||||
|
||||
#include <platform_def.h>
|
||||
|
||||
#ifdef __aarch64__
|
||||
#define STRUCT_ALIGN 8
|
||||
#define BSS_ALIGN 16
|
||||
#else
|
||||
#define STRUCT_ALIGN 4
|
||||
#define BSS_ALIGN 8
|
||||
#endif
|
||||
|
||||
#ifndef DATA_ALIGN
|
||||
#define DATA_ALIGN 1
|
||||
#endif
|
||||
|
||||
#define CPU_OPS \
|
||||
. = ALIGN(STRUCT_ALIGN); \
|
||||
__CPU_OPS_START__ = .; \
|
||||
KEEP(*(cpu_ops)) \
|
||||
__CPU_OPS_END__ = .;
|
||||
|
||||
#define PARSER_LIB_DESCS \
|
||||
. = ALIGN(STRUCT_ALIGN); \
|
||||
__PARSER_LIB_DESCS_START__ = .; \
|
||||
KEEP(*(.img_parser_lib_descs)) \
|
||||
__PARSER_LIB_DESCS_END__ = .;
|
||||
|
||||
#define RT_SVC_DESCS \
|
||||
. = ALIGN(STRUCT_ALIGN); \
|
||||
__RT_SVC_DESCS_START__ = .; \
|
||||
KEEP(*(rt_svc_descs)) \
|
||||
__RT_SVC_DESCS_END__ = .;
|
||||
|
||||
#if SPMC_AT_EL3
|
||||
#define EL3_LP_DESCS \
|
||||
. = ALIGN(STRUCT_ALIGN); \
|
||||
__EL3_LP_DESCS_START__ = .; \
|
||||
KEEP(*(el3_lp_descs)) \
|
||||
__EL3_LP_DESCS_END__ = .;
|
||||
#else
|
||||
#define EL3_LP_DESCS
|
||||
#endif
|
||||
|
||||
#define PMF_SVC_DESCS \
|
||||
. = ALIGN(STRUCT_ALIGN); \
|
||||
__PMF_SVC_DESCS_START__ = .; \
|
||||
KEEP(*(pmf_svc_descs)) \
|
||||
__PMF_SVC_DESCS_END__ = .;
|
||||
|
||||
#define FCONF_POPULATOR \
|
||||
. = ALIGN(STRUCT_ALIGN); \
|
||||
__FCONF_POPULATOR_START__ = .; \
|
||||
KEEP(*(.fconf_populator)) \
|
||||
__FCONF_POPULATOR_END__ = .;
|
||||
|
||||
/*
|
||||
* Keep the .got section in the RO section as it is patched prior to enabling
|
||||
* the MMU and having the .got in RO is better for security. GOT is a table of
|
||||
* addresses so ensure pointer size alignment.
|
||||
*/
|
||||
#define GOT \
|
||||
. = ALIGN(STRUCT_ALIGN); \
|
||||
__GOT_START__ = .; \
|
||||
*(.got) \
|
||||
__GOT_END__ = .;
|
||||
|
||||
/*
|
||||
* The base xlat table
|
||||
*
|
||||
* It is put into the rodata section if PLAT_RO_XLAT_TABLES=1,
|
||||
* or into the bss section otherwise.
|
||||
*/
|
||||
#define BASE_XLAT_TABLE \
|
||||
. = ALIGN(16); \
|
||||
__BASE_XLAT_TABLE_START__ = .; \
|
||||
*(base_xlat_table) \
|
||||
__BASE_XLAT_TABLE_END__ = .;
|
||||
|
||||
#if PLAT_RO_XLAT_TABLES
|
||||
#define BASE_XLAT_TABLE_RO BASE_XLAT_TABLE
|
||||
#define BASE_XLAT_TABLE_BSS
|
||||
#else
|
||||
#define BASE_XLAT_TABLE_RO
|
||||
#define BASE_XLAT_TABLE_BSS BASE_XLAT_TABLE
|
||||
#endif
|
||||
|
||||
#define RODATA_COMMON \
|
||||
RT_SVC_DESCS \
|
||||
FCONF_POPULATOR \
|
||||
PMF_SVC_DESCS \
|
||||
PARSER_LIB_DESCS \
|
||||
CPU_OPS \
|
||||
GOT \
|
||||
BASE_XLAT_TABLE_RO \
|
||||
EL3_LP_DESCS
|
||||
|
||||
/*
|
||||
* .data must be placed at a lower address than the stacks if the stack
|
||||
* protector is enabled. Alternatively, the .data.stack_protector_canary
|
||||
* section can be placed independently of the main .data section.
|
||||
*/
|
||||
#define DATA_SECTION \
|
||||
.data . : ALIGN(DATA_ALIGN) { \
|
||||
__DATA_START__ = .; \
|
||||
*(SORT_BY_ALIGNMENT(.data*)) \
|
||||
__DATA_END__ = .; \
|
||||
}
|
||||
|
||||
/*
|
||||
* .rela.dyn needs to come after .data for the read-elf utility to parse
|
||||
* this section correctly.
|
||||
*/
|
||||
#if __aarch64__
|
||||
#define RELA_DYN_NAME .rela.dyn
|
||||
#define RELOC_SECTIONS_PATTERN *(.rela*)
|
||||
#else
|
||||
#define RELA_DYN_NAME .rel.dyn
|
||||
#define RELOC_SECTIONS_PATTERN *(.rel*)
|
||||
#endif
|
||||
|
||||
#define RELA_SECTION \
|
||||
RELA_DYN_NAME : ALIGN(STRUCT_ALIGN) { \
|
||||
__RELA_START__ = .; \
|
||||
RELOC_SECTIONS_PATTERN \
|
||||
__RELA_END__ = .; \
|
||||
}
|
||||
|
||||
#if !(defined(IMAGE_BL31) && RECLAIM_INIT_CODE)
|
||||
#define STACK_SECTION \
|
||||
stacks (NOLOAD) : { \
|
||||
__STACKS_START__ = .; \
|
||||
*(tzfw_normal_stacks) \
|
||||
__STACKS_END__ = .; \
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* If BL doesn't use any bakery lock then __PERCPU_BAKERY_LOCK_SIZE__
|
||||
* will be zero. For this reason, the only two valid values for
|
||||
* __PERCPU_BAKERY_LOCK_SIZE__ are 0 or the platform defined value
|
||||
* PLAT_PERCPU_BAKERY_LOCK_SIZE.
|
||||
*/
|
||||
#ifdef PLAT_PERCPU_BAKERY_LOCK_SIZE
|
||||
#define BAKERY_LOCK_SIZE_CHECK \
|
||||
ASSERT((__PERCPU_BAKERY_LOCK_SIZE__ == 0) || \
|
||||
(__PERCPU_BAKERY_LOCK_SIZE__ == PLAT_PERCPU_BAKERY_LOCK_SIZE), \
|
||||
"PLAT_PERCPU_BAKERY_LOCK_SIZE does not match bakery lock requirements");
|
||||
#else
|
||||
#define BAKERY_LOCK_SIZE_CHECK
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Bakery locks are stored in normal .bss memory
|
||||
*
|
||||
* Each lock's data is spread across multiple cache lines, one per CPU,
|
||||
* but multiple locks can share the same cache line.
|
||||
* The compiler will allocate enough memory for one CPU's bakery locks,
|
||||
* the remaining cache lines are allocated by the linker script
|
||||
*/
|
||||
#if !USE_COHERENT_MEM
|
||||
#define BAKERY_LOCK_NORMAL \
|
||||
. = ALIGN(CACHE_WRITEBACK_GRANULE); \
|
||||
__BAKERY_LOCK_START__ = .; \
|
||||
__PERCPU_BAKERY_LOCK_START__ = .; \
|
||||
*(bakery_lock) \
|
||||
. = ALIGN(CACHE_WRITEBACK_GRANULE); \
|
||||
__PERCPU_BAKERY_LOCK_END__ = .; \
|
||||
__PERCPU_BAKERY_LOCK_SIZE__ = ABSOLUTE(__PERCPU_BAKERY_LOCK_END__ - __PERCPU_BAKERY_LOCK_START__); \
|
||||
. = . + (__PERCPU_BAKERY_LOCK_SIZE__ * (PLATFORM_CORE_COUNT - 1)); \
|
||||
__BAKERY_LOCK_END__ = .; \
|
||||
BAKERY_LOCK_SIZE_CHECK
|
||||
#else
|
||||
#define BAKERY_LOCK_NORMAL
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Time-stamps are stored in normal .bss memory
|
||||
*
|
||||
* The compiler will allocate enough memory for one CPU's time-stamps,
|
||||
* the remaining memory for other CPUs is allocated by the
|
||||
* linker script
|
||||
*/
|
||||
#define PMF_TIMESTAMP \
|
||||
. = ALIGN(CACHE_WRITEBACK_GRANULE); \
|
||||
__PMF_TIMESTAMP_START__ = .; \
|
||||
KEEP(*(pmf_timestamp_array)) \
|
||||
. = ALIGN(CACHE_WRITEBACK_GRANULE); \
|
||||
__PMF_PERCPU_TIMESTAMP_END__ = .; \
|
||||
__PERCPU_TIMESTAMP_SIZE__ = ABSOLUTE(. - __PMF_TIMESTAMP_START__); \
|
||||
. = . + (__PERCPU_TIMESTAMP_SIZE__ * (PLATFORM_CORE_COUNT - 1)); \
|
||||
__PMF_TIMESTAMP_END__ = .;
|
||||
|
||||
|
||||
/*
|
||||
* The .bss section gets initialised to 0 at runtime.
|
||||
* Its base address has bigger alignment for better performance of the
|
||||
* zero-initialization code.
|
||||
*/
|
||||
#define BSS_SECTION \
|
||||
.bss (NOLOAD) : ALIGN(BSS_ALIGN) { \
|
||||
__BSS_START__ = .; \
|
||||
*(SORT_BY_ALIGNMENT(.bss*)) \
|
||||
*(COMMON) \
|
||||
BAKERY_LOCK_NORMAL \
|
||||
PMF_TIMESTAMP \
|
||||
BASE_XLAT_TABLE_BSS \
|
||||
__BSS_END__ = .; \
|
||||
}
|
||||
|
||||
/*
|
||||
* The xlat_table section is for full, aligned page tables (4K).
|
||||
* Removing them from .bss avoids forcing 4K alignment on
|
||||
* the .bss section. The tables are initialized to zero by the translation
|
||||
* tables library.
|
||||
*/
|
||||
#define XLAT_TABLE_SECTION \
|
||||
xlat_table (NOLOAD) : { \
|
||||
__XLAT_TABLE_START__ = .; \
|
||||
*(xlat_table) \
|
||||
__XLAT_TABLE_END__ = .; \
|
||||
}
|
||||
|
||||
#endif /* BL_COMMON_LD_H */
|
||||
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef DEBUG_H
|
||||
#define DEBUG_H
|
||||
|
||||
#include <lib/utils_def.h>
|
||||
|
||||
/*
|
||||
* The log output macros print output to the console. These macros produce
|
||||
* compiled log output only if the LOG_LEVEL defined in the makefile (or the
|
||||
* make command line) is greater or equal than the level required for that
|
||||
* type of log output.
|
||||
*
|
||||
* The format expected is the same as for printf(). For example:
|
||||
* INFO("Info %s.\n", "message") -> INFO: Info message.
|
||||
* WARN("Warning %s.\n", "message") -> WARNING: Warning message.
|
||||
*/
|
||||
|
||||
#define LOG_LEVEL_NONE U(0)
|
||||
#define LOG_LEVEL_ERROR U(10)
|
||||
#define LOG_LEVEL_NOTICE U(20)
|
||||
#define LOG_LEVEL_WARNING U(30)
|
||||
#define LOG_LEVEL_INFO U(40)
|
||||
#define LOG_LEVEL_VERBOSE U(50)
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
|
||||
#include <cdefs.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <drivers/console.h>
|
||||
|
||||
/*
|
||||
* Define Log Markers corresponding to each log level which will
|
||||
* be embedded in the format string and is expected by tf_log() to determine
|
||||
* the log level.
|
||||
*/
|
||||
#define LOG_MARKER_ERROR "\xa" /* 10 */
|
||||
#define LOG_MARKER_NOTICE "\x14" /* 20 */
|
||||
#define LOG_MARKER_WARNING "\x1e" /* 30 */
|
||||
#define LOG_MARKER_INFO "\x28" /* 40 */
|
||||
#define LOG_MARKER_VERBOSE "\x32" /* 50 */
|
||||
|
||||
/*
|
||||
* If the log output is too low then this macro is used in place of tf_log()
|
||||
* below. The intent is to get the compiler to evaluate the function call for
|
||||
* type checking and format specifier correctness but let it optimize it out.
|
||||
*/
|
||||
#define no_tf_log(fmt, ...) \
|
||||
do { \
|
||||
if (false) { \
|
||||
tf_log(fmt, ##__VA_ARGS__); \
|
||||
} \
|
||||
} while (false)
|
||||
|
||||
#if LOG_LEVEL >= LOG_LEVEL_ERROR
|
||||
# define ERROR(...) tf_log(LOG_MARKER_ERROR __VA_ARGS__)
|
||||
# define ERROR_NL() tf_log_newline(LOG_MARKER_ERROR)
|
||||
#else
|
||||
# define ERROR(...) no_tf_log(LOG_MARKER_ERROR __VA_ARGS__)
|
||||
# define ERROR_NL()
|
||||
#endif
|
||||
|
||||
#if LOG_LEVEL >= LOG_LEVEL_NOTICE
|
||||
# define NOTICE(...) tf_log(LOG_MARKER_NOTICE __VA_ARGS__)
|
||||
#else
|
||||
# define NOTICE(...) no_tf_log(LOG_MARKER_NOTICE __VA_ARGS__)
|
||||
#endif
|
||||
|
||||
#if LOG_LEVEL >= LOG_LEVEL_WARNING
|
||||
# define WARN(...) tf_log(LOG_MARKER_WARNING __VA_ARGS__)
|
||||
#else
|
||||
# define WARN(...) no_tf_log(LOG_MARKER_WARNING __VA_ARGS__)
|
||||
#endif
|
||||
|
||||
#if LOG_LEVEL >= LOG_LEVEL_INFO
|
||||
# define INFO(...) tf_log(LOG_MARKER_INFO __VA_ARGS__)
|
||||
#else
|
||||
# define INFO(...) no_tf_log(LOG_MARKER_INFO __VA_ARGS__)
|
||||
#endif
|
||||
|
||||
#if LOG_LEVEL >= LOG_LEVEL_VERBOSE
|
||||
# define VERBOSE(...) tf_log(LOG_MARKER_VERBOSE __VA_ARGS__)
|
||||
#else
|
||||
# define VERBOSE(...) no_tf_log(LOG_MARKER_VERBOSE __VA_ARGS__)
|
||||
#endif
|
||||
|
||||
const char *get_el_str(unsigned int el);
|
||||
|
||||
#if ENABLE_BACKTRACE
|
||||
void backtrace(const char *cookie);
|
||||
#else
|
||||
#define backtrace(x)
|
||||
#endif
|
||||
|
||||
void __dead2 do_panic(void);
|
||||
|
||||
#define panic() \
|
||||
do { \
|
||||
backtrace(__func__); \
|
||||
console_flush(); \
|
||||
do_panic(); \
|
||||
} while (false)
|
||||
|
||||
/* Function called when stack protection check code detects a corrupted stack */
|
||||
void __dead2 __stack_chk_fail(void);
|
||||
|
||||
void tf_log(const char *fmt, ...) __printflike(1, 2);
|
||||
void tf_log_newline(const char log_fmt[2]);
|
||||
void tf_log_set_max_level(unsigned int log_level);
|
||||
|
||||
#endif /* __ASSEMBLER__ */
|
||||
#endif /* DEBUG_H */
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
#ifndef DESC_IMAGE_LOAD_H
|
||||
#define DESC_IMAGE_LOAD_H
|
||||
|
||||
#include <common/bl_common.h>
|
||||
|
||||
/* Following structure is used to store BL ep/image info. */
|
||||
typedef struct bl_mem_params_node {
|
||||
unsigned int image_id;
|
||||
image_info_t image_info;
|
||||
entry_point_info_t ep_info;
|
||||
unsigned int next_handoff_image_id;
|
||||
bl_load_info_node_t load_node_mem;
|
||||
bl_params_node_t params_node_mem;
|
||||
} bl_mem_params_node_t;
|
||||
|
||||
extern bl_mem_params_node_t *bl_mem_params_desc_ptr;
|
||||
extern unsigned int bl_mem_params_desc_num;
|
||||
|
||||
/*
|
||||
* Macro to register list of BL image descriptors,
|
||||
* defined as an array of bl_mem_params_node_t.
|
||||
*/
|
||||
#define REGISTER_BL_IMAGE_DESCS(_img_desc) \
|
||||
bl_mem_params_node_t *bl_mem_params_desc_ptr = &_img_desc[0]; \
|
||||
unsigned int bl_mem_params_desc_num = ARRAY_SIZE(_img_desc);
|
||||
|
||||
/* BL image loading utility functions */
|
||||
void flush_bl_params_desc(void);
|
||||
void flush_bl_params_desc_args(bl_mem_params_node_t *mem_params_desc_ptr,
|
||||
unsigned int mem_params_desc_num,
|
||||
bl_params_t *next_bl_params_ptr);
|
||||
int get_bl_params_node_index(unsigned int image_id);
|
||||
bl_mem_params_node_t *get_bl_mem_params_node(unsigned int image_id);
|
||||
bl_load_info_t *get_bl_load_info_from_mem_params_desc(void);
|
||||
bl_params_t *get_next_bl_params_from_mem_params_desc(void);
|
||||
void populate_next_bl_params_config(bl_params_t *bl2_to_next_bl_params);
|
||||
|
||||
/* Helper to extract BL32/BL33 entry point info from arg0 passed to BL31. */
|
||||
void bl31_params_parse_helper(u_register_t param,
|
||||
entry_point_info_t *bl32_ep_info_out,
|
||||
entry_point_info_t *bl33_ep_info_out);
|
||||
|
||||
#endif /* DESC_IMAGE_LOAD_H */
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (c) 2017-2021, Arm Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef EP_INFO_H
|
||||
#define EP_INFO_H
|
||||
|
||||
#include <common/param_header.h>
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
#include <stdint.h>
|
||||
#include <lib/cassert.h>
|
||||
#endif /* __ASSEMBLER__ */
|
||||
|
||||
#include <export/common/ep_info_exp.h>
|
||||
|
||||
#define SECURE EP_SECURE
|
||||
#define NON_SECURE EP_NON_SECURE
|
||||
#define REALM EP_REALM
|
||||
#if ENABLE_RME
|
||||
#define sec_state_is_valid(s) (((s) == SECURE) || \
|
||||
((s) == NON_SECURE) || \
|
||||
((s) == REALM))
|
||||
#else
|
||||
#define sec_state_is_valid(s) (((s) == SECURE) || ((s) == NON_SECURE))
|
||||
#endif
|
||||
|
||||
#define PARAM_EP_SECURITY_MASK EP_SECURITY_MASK
|
||||
|
||||
#define NON_EXECUTABLE EP_NON_EXECUTABLE
|
||||
#define EXECUTABLE EP_EXECUTABLE
|
||||
|
||||
/* Get/set security state of an image */
|
||||
#define GET_SECURITY_STATE(x) ((x) & EP_SECURITY_MASK)
|
||||
#define SET_SECURITY_STATE(x, security) \
|
||||
((x) = ((x) & ~EP_SECURITY_MASK) | (security))
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
|
||||
/*
|
||||
* Compile time assertions related to the 'entry_point_info' structure to
|
||||
* ensure that the assembler and the compiler view of the offsets of
|
||||
* the structure members is the same.
|
||||
*/
|
||||
CASSERT(ENTRY_POINT_INFO_PC_OFFSET ==
|
||||
__builtin_offsetof(entry_point_info_t, pc), \
|
||||
assert_BL31_pc_offset_mismatch);
|
||||
|
||||
#ifndef __aarch64__
|
||||
CASSERT(ENTRY_POINT_INFO_LR_SVC_OFFSET ==
|
||||
__builtin_offsetof(entry_point_info_t, lr_svc),
|
||||
assert_entrypoint_lr_offset_error);
|
||||
#endif
|
||||
|
||||
CASSERT(ENTRY_POINT_INFO_ARGS_OFFSET == \
|
||||
__builtin_offsetof(entry_point_info_t, args), \
|
||||
assert_BL31_args_offset_mismatch);
|
||||
|
||||
CASSERT(sizeof(uintptr_t) ==
|
||||
__builtin_offsetof(entry_point_info_t, spsr) - \
|
||||
__builtin_offsetof(entry_point_info_t, pc), \
|
||||
assert_entrypoint_and_spsr_should_be_adjacent);
|
||||
|
||||
#endif /*__ASSEMBLER__*/
|
||||
|
||||
#endif /* EP_INFO_H */
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef FDT_FIXUP_H
|
||||
#define FDT_FIXUP_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define INVALID_BASE_ADDR ((uintptr_t)~0UL)
|
||||
|
||||
struct psci_cpu_idle_state {
|
||||
const char *name;
|
||||
uint32_t power_state;
|
||||
bool local_timer_stop;
|
||||
uint32_t entry_latency_us;
|
||||
uint32_t exit_latency_us;
|
||||
uint32_t min_residency_us;
|
||||
uint32_t wakeup_latency_us;
|
||||
};
|
||||
|
||||
int dt_add_psci_node(void *fdt);
|
||||
int dt_add_psci_cpu_enable_methods(void *fdt);
|
||||
int fdt_add_reserved_memory(void *dtb, const char *node_name,
|
||||
uintptr_t base, size_t size);
|
||||
int fdt_add_cpus_node(void *dtb, unsigned int afflv0,
|
||||
unsigned int afflv1, unsigned int afflv2);
|
||||
int fdt_add_cpu_idle_states(void *dtb, const struct psci_cpu_idle_state *state);
|
||||
int fdt_adjust_gic_redist(void *dtb, unsigned int nr_cores, uintptr_t gicr_base,
|
||||
unsigned int gicr_frame_size);
|
||||
int fdt_set_mac_address(void *dtb, unsigned int ethernet_idx,
|
||||
const uint8_t *mac_addr);
|
||||
|
||||
#endif /* FDT_FIXUP_H */
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/* Helper functions to offer easier navigation of Device Tree Blob */
|
||||
|
||||
#ifndef FDT_WRAPPERS_H
|
||||
#define FDT_WRAPPERS_H
|
||||
|
||||
#include <libfdt_env.h>
|
||||
|
||||
/* Number of cells, given total length in bytes. Each cell is 4 bytes long */
|
||||
#define NCELLS(len) ((len) / 4U)
|
||||
|
||||
int fdt_read_uint32(const void *dtb, int node, const char *prop_name,
|
||||
uint32_t *value);
|
||||
uint32_t fdt_read_uint32_default(const void *dtb, int node,
|
||||
const char *prop_name, uint32_t dflt_value);
|
||||
int fdt_read_uint64(const void *dtb, int node, const char *prop_name,
|
||||
uint64_t *value);
|
||||
int fdt_read_uint32_array(const void *dtb, int node, const char *prop_name,
|
||||
unsigned int cells, uint32_t *value);
|
||||
int fdtw_read_string(const void *dtb, int node, const char *prop,
|
||||
char *str, size_t size);
|
||||
int fdtw_read_uuid(const void *dtb, int node, const char *prop,
|
||||
unsigned int length, uint8_t *uuid);
|
||||
int fdtw_write_inplace_cells(void *dtb, int node, const char *prop,
|
||||
unsigned int cells, void *value);
|
||||
int fdtw_read_bytes(const void *dtb, int node, const char *prop,
|
||||
unsigned int length, void *value);
|
||||
int fdtw_write_inplace_bytes(void *dtb, int node, const char *prop,
|
||||
unsigned int length, const void *data);
|
||||
int fdt_get_reg_props_by_index(const void *dtb, int node, int index,
|
||||
uintptr_t *base, size_t *size);
|
||||
int fdt_get_reg_props_by_name(const void *dtb, int node, const char *name,
|
||||
uintptr_t *base, size_t *size);
|
||||
int fdt_get_stdout_node_offset(const void *dtb);
|
||||
|
||||
uint64_t fdtw_translate_address(const void *dtb, int bus_node,
|
||||
uint64_t base_address);
|
||||
|
||||
int fdtw_for_each_cpu(const void *fdt,
|
||||
int (*callback)(const void *dtb, int node, uintptr_t mpidr));
|
||||
|
||||
int fdtw_find_or_add_subnode(void *fdt, int parentoffset, const char *name);
|
||||
|
||||
static inline uint32_t fdt_blob_size(const void *dtb)
|
||||
{
|
||||
const uint32_t *dtb_header = dtb;
|
||||
|
||||
return fdt32_to_cpu(dtb_header[1]);
|
||||
}
|
||||
|
||||
#define fdt_for_each_compatible_node(dtb, node, compatible_str) \
|
||||
for (node = fdt_node_offset_by_compatible(dtb, -1, compatible_str); \
|
||||
node >= 0; \
|
||||
node = fdt_node_offset_by_compatible(dtb, node, compatible_str))
|
||||
|
||||
#endif /* FDT_WRAPPERS_H */
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef FEAT_DETECT_H
|
||||
#define FEAT_DETECT_H
|
||||
|
||||
#include <arch_features.h>
|
||||
#include <common/debug.h>
|
||||
|
||||
/* Function Prototypes */
|
||||
void detect_arch_features(void);
|
||||
|
||||
/* Macro Definitions */
|
||||
#define FEAT_STATE_1 1
|
||||
#define FEAT_STATE_2 2
|
||||
#define feat_detect_panic(a, b) ((a) ? (void)0 : feature_panic(b))
|
||||
|
||||
/*******************************************************************************
|
||||
* Function : feature_panic
|
||||
* Customised panic module with error logging mechanism to list the feature
|
||||
* not supported by the PE.
|
||||
******************************************************************************/
|
||||
static inline void feature_panic(char *feat_name)
|
||||
{
|
||||
ERROR("FEAT_%s not supported by the PE\n", feat_name);
|
||||
panic();
|
||||
}
|
||||
|
||||
#endif /* FEAT_DETECT_H */
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef IMAGE_DECOMPRESS_H
|
||||
#define IMAGE_DECOMPRESS_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
struct image_info;
|
||||
|
||||
typedef int (decompressor_t)(uintptr_t *in_buf, size_t in_len,
|
||||
uintptr_t *out_buf, size_t out_len,
|
||||
uintptr_t work_buf, size_t work_len);
|
||||
|
||||
void image_decompress_init(uintptr_t buf_base, uint32_t buf_size,
|
||||
decompressor_t *decompressor);
|
||||
void image_decompress_prepare(struct image_info *info);
|
||||
int image_decompress(struct image_info *info);
|
||||
|
||||
#endif /* IMAGE_DECOMPRESS_H */
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef INTERRUPT_PROPS_H
|
||||
#define INTERRUPT_PROPS_H
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
|
||||
/* Create an interrupt property descriptor from various interrupt properties */
|
||||
#define INTR_PROP_DESC(num, pri, grp, cfg) \
|
||||
{ \
|
||||
.intr_num = (num), \
|
||||
.intr_pri = (pri), \
|
||||
.intr_grp = (grp), \
|
||||
.intr_cfg = (cfg), \
|
||||
}
|
||||
|
||||
typedef struct interrupt_prop {
|
||||
unsigned int intr_num:10;
|
||||
unsigned int intr_pri:8;
|
||||
unsigned int intr_grp:2;
|
||||
unsigned int intr_cfg:2;
|
||||
} interrupt_prop_t;
|
||||
|
||||
#endif /* __ASSEMBLER__ */
|
||||
#endif /* INTERRUPT_PROPS_H */
|
||||
@@ -0,0 +1,9 @@
|
||||
/*
|
||||
* Copyright (c) 2020, Arm Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#define TRUSTED_NV_CTR_ID U(0)
|
||||
#define NON_TRUSTED_NV_CTR_ID U(1)
|
||||
#define MAX_NV_CTR_IDS U(2)
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef PARAM_HEADER_H
|
||||
#define PARAM_HEADER_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
#include <stdint.h>
|
||||
#endif /*__ASSEMBLER__*/
|
||||
|
||||
#include <export/common/param_header_exp.h>
|
||||
|
||||
#define VERSION_1 PARAM_VERSION_1
|
||||
#define VERSION_2 PARAM_VERSION_2
|
||||
|
||||
#define SET_PARAM_HEAD(_p, _type, _ver, _attr) do { \
|
||||
(_p)->h.type = (uint8_t)(_type); \
|
||||
(_p)->h.version = (uint8_t)(_ver); \
|
||||
(_p)->h.size = (uint16_t)sizeof(*(_p)); \
|
||||
(_p)->h.attr = (uint32_t)(_attr) ; \
|
||||
} while (false)
|
||||
|
||||
/* Following is used for populating structure members statically. */
|
||||
#define SET_STATIC_PARAM_HEAD(_p, _type, _ver, _p_type, _attr) \
|
||||
._p.h.type = (uint8_t)(_type), \
|
||||
._p.h.version = (uint8_t)(_ver), \
|
||||
._p.h.size = (uint16_t)sizeof(_p_type), \
|
||||
._p.h.attr = (uint32_t)(_attr)
|
||||
|
||||
#endif /* PARAM_HEADER_H */
|
||||
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef ROMLIB_H
|
||||
#define ROMLIB_H
|
||||
|
||||
#define ROMLIB_MAJOR 0
|
||||
#define ROMLIB_MINOR 1
|
||||
#define ROMLIB_VERSION ((ROMLIB_MAJOR << 8) | ROMLIB_MINOR)
|
||||
|
||||
int rom_lib_init(int version);
|
||||
|
||||
#endif /* ROMLIB_H */
|
||||
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef RUNTIME_SVC_H
|
||||
#define RUNTIME_SVC_H
|
||||
|
||||
#include <common/bl_common.h> /* to include exception types */
|
||||
#include <lib/cassert.h>
|
||||
#include <lib/utils_def.h>
|
||||
#include <smccc_helpers.h> /* to include SMCCC definitions */
|
||||
|
||||
/*******************************************************************************
|
||||
* Structure definition, typedefs & constants for the runtime service framework
|
||||
******************************************************************************/
|
||||
|
||||
/*
|
||||
* Constants to allow the assembler access a runtime service
|
||||
* descriptor
|
||||
*/
|
||||
#ifdef __aarch64__
|
||||
#define RT_SVC_SIZE_LOG2 U(5)
|
||||
#define RT_SVC_DESC_INIT U(16)
|
||||
#define RT_SVC_DESC_HANDLE U(24)
|
||||
#else
|
||||
#define RT_SVC_SIZE_LOG2 U(4)
|
||||
#define RT_SVC_DESC_INIT U(8)
|
||||
#define RT_SVC_DESC_HANDLE U(12)
|
||||
#endif /* __aarch64__ */
|
||||
#define SIZEOF_RT_SVC_DESC (U(1) << RT_SVC_SIZE_LOG2)
|
||||
|
||||
|
||||
/*
|
||||
* In SMCCC 1.X, the function identifier has 6 bits for the owning entity number
|
||||
* and a single bit for the type of smc call. When taken together, those values
|
||||
* limit the maximum number of runtime services to 128.
|
||||
*/
|
||||
#define MAX_RT_SVCS U(128)
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
|
||||
/* Prototype for runtime service initializing function */
|
||||
typedef int32_t (*rt_svc_init_t)(void);
|
||||
|
||||
/*
|
||||
* Prototype for runtime service SMC handler function. x0 (SMC Function ID) to
|
||||
* x4 are as passed by the caller. Rest of the arguments to SMC and the context
|
||||
* can be accessed using the handle pointer. The cookie parameter is reserved
|
||||
* for future use
|
||||
*/
|
||||
typedef uintptr_t (*rt_svc_handle_t)(uint32_t smc_fid,
|
||||
u_register_t x1,
|
||||
u_register_t x2,
|
||||
u_register_t x3,
|
||||
u_register_t x4,
|
||||
void *cookie,
|
||||
void *handle,
|
||||
u_register_t flags);
|
||||
typedef struct rt_svc_desc {
|
||||
uint8_t start_oen;
|
||||
uint8_t end_oen;
|
||||
uint8_t call_type;
|
||||
const char *name;
|
||||
rt_svc_init_t init;
|
||||
rt_svc_handle_t handle;
|
||||
} rt_svc_desc_t;
|
||||
|
||||
/*
|
||||
* Convenience macros to declare a service descriptor
|
||||
*/
|
||||
#define DECLARE_RT_SVC(_name, _start, _end, _type, _setup, _smch) \
|
||||
static const rt_svc_desc_t __svc_desc_ ## _name \
|
||||
__section("rt_svc_descs") __used = { \
|
||||
.start_oen = (_start), \
|
||||
.end_oen = (_end), \
|
||||
.call_type = (_type), \
|
||||
.name = #_name, \
|
||||
.init = (_setup), \
|
||||
.handle = (_smch) \
|
||||
}
|
||||
|
||||
/*
|
||||
* Compile time assertions related to the 'rt_svc_desc' structure to:
|
||||
* 1. ensure that the assembler and the compiler view of the size
|
||||
* of the structure are the same.
|
||||
* 2. ensure that the assembler and the compiler see the initialisation
|
||||
* routine at the same offset.
|
||||
* 3. ensure that the assembler and the compiler see the handler
|
||||
* routine at the same offset.
|
||||
*/
|
||||
CASSERT((sizeof(rt_svc_desc_t) == SIZEOF_RT_SVC_DESC), \
|
||||
assert_sizeof_rt_svc_desc_mismatch);
|
||||
CASSERT(RT_SVC_DESC_INIT == __builtin_offsetof(rt_svc_desc_t, init), \
|
||||
assert_rt_svc_desc_init_offset_mismatch);
|
||||
CASSERT(RT_SVC_DESC_HANDLE == __builtin_offsetof(rt_svc_desc_t, handle), \
|
||||
assert_rt_svc_desc_handle_offset_mismatch);
|
||||
|
||||
|
||||
/*
|
||||
* This function combines the call type and the owning entity number
|
||||
* corresponding to a runtime service to generate a unique owning entity number.
|
||||
* This unique oen is used to access an entry in the 'rt_svc_descs_indices'
|
||||
* array. The entry contains the index of the service descriptor in the
|
||||
* 'rt_svc_descs' array.
|
||||
*/
|
||||
static inline uint32_t get_unique_oen(uint32_t oen, uint32_t call_type)
|
||||
{
|
||||
return ((call_type & FUNCID_TYPE_MASK) << FUNCID_OEN_WIDTH) |
|
||||
(oen & FUNCID_OEN_MASK);
|
||||
}
|
||||
|
||||
/*
|
||||
* This function generates the unique owning entity number from the SMC Function
|
||||
* ID. This unique oen is used to access an entry in the 'rt_svc_descs_indices'
|
||||
* array to invoke the corresponding runtime service handler during SMC
|
||||
* handling.
|
||||
*/
|
||||
static inline uint32_t get_unique_oen_from_smc_fid(uint32_t fid)
|
||||
{
|
||||
return get_unique_oen(GET_SMC_OEN(fid), GET_SMC_TYPE(fid));
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Function & variable prototypes
|
||||
******************************************************************************/
|
||||
void runtime_svc_init(void);
|
||||
uintptr_t handle_runtime_svc(uint32_t smc_fid, void *cookie, void *handle,
|
||||
unsigned int flags);
|
||||
IMPORT_SYM(uintptr_t, __RT_SVC_DESCS_START__, RT_SVC_DESCS_START);
|
||||
IMPORT_SYM(uintptr_t, __RT_SVC_DESCS_END__, RT_SVC_DESCS_END);
|
||||
void init_crash_reporting(void);
|
||||
|
||||
extern uint8_t rt_svc_descs_indices[MAX_RT_SVCS];
|
||||
|
||||
#endif /*__ASSEMBLER__*/
|
||||
#endif /* RUNTIME_SVC_H */
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef COT_DEF_H
|
||||
#define COT_DEF_H
|
||||
|
||||
#ifdef MBEDTLS_CONFIG_FILE
|
||||
#include MBEDTLS_CONFIG_FILE
|
||||
#endif
|
||||
|
||||
/* TBBR CoT definitions */
|
||||
#if defined(SPD_spmd)
|
||||
#define COT_MAX_VERIFIED_PARAMS 8
|
||||
#elif defined(ARM_COT_cca)
|
||||
#define COT_MAX_VERIFIED_PARAMS 8
|
||||
#else
|
||||
#define COT_MAX_VERIFIED_PARAMS 4
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Maximum key and hash sizes (in DER format).
|
||||
*
|
||||
* Both RSA and ECDSA keys may be used at the same time. In this case, the key
|
||||
* buffers must be big enough to hold either. As RSA keys are bigger than ECDSA
|
||||
* ones for all key sizes we support, they impose the minimum size of these
|
||||
* buffers.
|
||||
*/
|
||||
#if TF_MBEDTLS_USE_RSA
|
||||
#if TF_MBEDTLS_KEY_SIZE == 1024
|
||||
#define PK_DER_LEN 162
|
||||
#elif TF_MBEDTLS_KEY_SIZE == 2048
|
||||
#define PK_DER_LEN 294
|
||||
#elif TF_MBEDTLS_KEY_SIZE == 3072
|
||||
#define PK_DER_LEN 422
|
||||
#elif TF_MBEDTLS_KEY_SIZE == 4096
|
||||
#define PK_DER_LEN 550
|
||||
#else
|
||||
#error "Invalid value for TF_MBEDTLS_KEY_SIZE"
|
||||
#endif
|
||||
#else /* Only using ECDSA keys. */
|
||||
#define PK_DER_LEN 92
|
||||
#endif
|
||||
|
||||
#if TF_MBEDTLS_HASH_ALG_ID == TF_MBEDTLS_SHA256
|
||||
#define HASH_DER_LEN 51
|
||||
#elif TF_MBEDTLS_HASH_ALG_ID == TF_MBEDTLS_SHA384
|
||||
#define HASH_DER_LEN 67
|
||||
#elif TF_MBEDTLS_HASH_ALG_ID == TF_MBEDTLS_SHA512
|
||||
#define HASH_DER_LEN 83
|
||||
#else
|
||||
#error "Invalid value for TF_MBEDTLS_HASH_ALG_ID"
|
||||
#endif
|
||||
|
||||
#endif /* COT_DEF_H */
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef TBBR_IMG_DEF_H
|
||||
#define TBBR_IMG_DEF_H
|
||||
|
||||
#include <export/common/tbbr/tbbr_img_def_exp.h>
|
||||
|
||||
#if defined(SPD_spmd)
|
||||
#define SIP_SP_CONTENT_CERT_ID MAX_IMAGE_IDS
|
||||
#define PLAT_SP_CONTENT_CERT_ID (MAX_IMAGE_IDS + 1)
|
||||
#define SP_PKG1_ID (MAX_IMAGE_IDS + 2)
|
||||
#define SP_PKG2_ID (MAX_IMAGE_IDS + 3)
|
||||
#define SP_PKG3_ID (MAX_IMAGE_IDS + 4)
|
||||
#define SP_PKG4_ID (MAX_IMAGE_IDS + 5)
|
||||
#define SP_PKG5_ID (MAX_IMAGE_IDS + 6)
|
||||
#define SP_PKG6_ID (MAX_IMAGE_IDS + 7)
|
||||
#define SP_PKG7_ID (MAX_IMAGE_IDS + 8)
|
||||
#define SP_PKG8_ID (MAX_IMAGE_IDS + 9)
|
||||
#define MAX_SP_IDS U(8)
|
||||
#define MAX_IMG_IDS_WITH_SPMDS (MAX_IMAGE_IDS + MAX_SP_IDS + U(2))
|
||||
#else
|
||||
#define MAX_IMG_IDS_WITH_SPMDS MAX_IMAGE_IDS
|
||||
#endif
|
||||
|
||||
#ifdef PLAT_TBBR_IMG_DEF
|
||||
#include <plat_tbbr_img_def.h>
|
||||
#endif
|
||||
|
||||
#ifndef MAX_NUMBER_IDS
|
||||
#define MAX_NUMBER_IDS MAX_IMG_IDS_WITH_SPMDS
|
||||
#endif
|
||||
|
||||
#endif /* TBBR_IMG_DEF_H */
|
||||
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Arm Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef TF_CRC32_H
|
||||
#define TF_CRC32_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/* compute CRC using Arm intrinsic function */
|
||||
uint32_t tf_crc32(uint32_t crc, const unsigned char *buf, size_t size);
|
||||
|
||||
#endif /* TF_CRC32_H */
|
||||
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef UUID_COMMON_H
|
||||
#define UUID_COMMON_H
|
||||
|
||||
#define UUID_BYTES_LENGTH 16
|
||||
#define UUID_STRING_LENGTH 36
|
||||
|
||||
int read_uuid(uint8_t *dest, char *uuid);
|
||||
bool uuid_match(uint32_t *uuid1, uint32_t *uuid2);
|
||||
void copy_uuid(uint32_t *to_uuid, uint32_t *from_uuid);
|
||||
bool is_null_uuid(uint32_t *uuid);
|
||||
|
||||
#endif /* UUID_COMMON_H */
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef AXP_H
|
||||
#define AXP_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define AXP20X_MODE_REG 0x3e
|
||||
#define AXP20X_MODE_I2C 0x00
|
||||
#define AXP20X_MODE_RSB 0x7c
|
||||
|
||||
#define NA 0xff
|
||||
|
||||
enum {
|
||||
AXP803_CHIP_ID = 0x41,
|
||||
AXP805_CHIP_ID = 0x40,
|
||||
};
|
||||
|
||||
struct axp_regulator {
|
||||
const char *dt_name;
|
||||
uint16_t min_volt;
|
||||
uint16_t max_volt;
|
||||
uint16_t step;
|
||||
unsigned char split;
|
||||
unsigned char volt_reg;
|
||||
unsigned char switch_reg;
|
||||
unsigned char switch_bit;
|
||||
};
|
||||
|
||||
extern const uint8_t axp_chip_id;
|
||||
extern const char *const axp_compatible;
|
||||
extern const struct axp_regulator axp_regulators[];
|
||||
|
||||
/*
|
||||
* Since the PMIC can be connected to multiple bus types,
|
||||
* low-level read/write functions must be provided by the platform
|
||||
*/
|
||||
int axp_read(uint8_t reg);
|
||||
int axp_write(uint8_t reg, uint8_t val);
|
||||
int axp_clrsetbits(uint8_t reg, uint8_t clr_mask, uint8_t set_mask);
|
||||
#define axp_clrbits(reg, clr_mask) axp_clrsetbits(reg, clr_mask, 0)
|
||||
#define axp_setbits(reg, set_mask) axp_clrsetbits(reg, 0, set_mask)
|
||||
|
||||
int axp_check_id(void);
|
||||
void axp_power_off(void);
|
||||
|
||||
#if SUNXI_SETUP_REGULATORS == 1
|
||||
void axp_setup_regulators(const void *fdt);
|
||||
#else
|
||||
static inline void axp_setup_regulators(const void *fdt)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* AXP_H */
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright (c) 2017-2018 ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef SUNXI_RSB_H
|
||||
#define SUNXI_RSB_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
int rsb_init_controller(void);
|
||||
int rsb_set_bus_speed(uint32_t source_freq, uint32_t bus_freq);
|
||||
int rsb_set_device_mode(uint32_t device_mode);
|
||||
int rsb_assign_runtime_address(uint16_t hw_addr, uint8_t rt_addr);
|
||||
|
||||
int rsb_read(uint8_t rt_addr, uint8_t reg_addr);
|
||||
int rsb_write(uint8_t rt_addr, uint8_t reg_addr, uint8_t value);
|
||||
|
||||
#endif /* SUNXI_RSB_H */
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Remi Pommarel <repk@triplefau.lt>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
#ifndef SHA_DMA_H
|
||||
#define SHA_DMA_H
|
||||
|
||||
#define SHA256_HASHSZ 32
|
||||
#define SHA256_BLOCKSZ 0x40
|
||||
|
||||
enum ASD_MODE {
|
||||
ASM_INVAL,
|
||||
ASM_SHA256,
|
||||
ASM_SHA224,
|
||||
};
|
||||
|
||||
struct asd_ctx {
|
||||
uint8_t digest[SHA256_HASHSZ];
|
||||
uint8_t block[SHA256_BLOCKSZ];
|
||||
size_t blocksz;
|
||||
enum ASD_MODE mode;
|
||||
uint8_t started;
|
||||
};
|
||||
|
||||
static inline void asd_sha_init(struct asd_ctx *ctx, enum ASD_MODE mode)
|
||||
{
|
||||
ctx->started = 0;
|
||||
ctx->mode = mode;
|
||||
ctx->blocksz = 0;
|
||||
}
|
||||
|
||||
void asd_sha_update(struct asd_ctx *ctx, void *data, size_t len);
|
||||
void asd_sha_finalize(struct asd_ctx *ctx);
|
||||
|
||||
#endif
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef MESON_CONSOLE_H
|
||||
#define MESON_CONSOLE_H
|
||||
|
||||
#include <drivers/console.h>
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/*
|
||||
* Initialize a new meson console instance and register it with the console
|
||||
* framework. The |console| pointer must point to storage that will be valid
|
||||
* for the lifetime of the console, such as a global or static local variable.
|
||||
* Its contents will be reinitialized from scratch.
|
||||
*
|
||||
* NOTE: The clock is actually fixed to 24 MHz. The argument is only there in
|
||||
* order to make this function future-proof.
|
||||
*/
|
||||
int console_meson_register(uintptr_t baseaddr, uint32_t clock, uint32_t baud,
|
||||
console_t *console);
|
||||
|
||||
#endif /*__ASSEMBLER__*/
|
||||
|
||||
#endif /* MESON_CONSOLE_H */
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
#ifndef ARM_GICV3_COMMON_H
|
||||
#define ARM_GICV3_COMMON_H
|
||||
|
||||
/*******************************************************************************
|
||||
* GIC500/GIC600 Re-distributor interface registers & constants
|
||||
******************************************************************************/
|
||||
|
||||
/* GICR_WAKER implementation-defined bit definitions */
|
||||
#define WAKER_SL_SHIFT 0
|
||||
#define WAKER_QSC_SHIFT 31
|
||||
|
||||
#define WAKER_SL_BIT (1U << WAKER_SL_SHIFT)
|
||||
#define WAKER_QSC_BIT (1U << WAKER_QSC_SHIFT)
|
||||
|
||||
#define IIDR_MODEL_ARM_GIC_600 U(0x0200043b)
|
||||
#define IIDR_MODEL_ARM_GIC_600AE U(0x0300043b)
|
||||
#define IIDR_MODEL_ARM_GIC_700 U(0x0400043b)
|
||||
|
||||
#define PIDR_COMPONENT_ARM_DIST U(0x492)
|
||||
#define PIDR_COMPONENT_ARM_REDIST U(0x493)
|
||||
#define PIDR_COMPONENT_ARM_ITS U(0x494)
|
||||
|
||||
#endif /* ARM_GICV3_COMMON_H */
|
||||
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef CCI_H
|
||||
#define CCI_H
|
||||
|
||||
#include <lib/utils_def.h>
|
||||
|
||||
/* Slave interface offsets from PERIPHBASE */
|
||||
#define SLAVE_IFACE6_OFFSET UL(0x7000)
|
||||
#define SLAVE_IFACE5_OFFSET UL(0x6000)
|
||||
#define SLAVE_IFACE4_OFFSET UL(0x5000)
|
||||
#define SLAVE_IFACE3_OFFSET UL(0x4000)
|
||||
#define SLAVE_IFACE2_OFFSET UL(0x3000)
|
||||
#define SLAVE_IFACE1_OFFSET UL(0x2000)
|
||||
#define SLAVE_IFACE0_OFFSET UL(0x1000)
|
||||
#define SLAVE_IFACE_OFFSET(index) (SLAVE_IFACE0_OFFSET + \
|
||||
(UL(0x1000) * (index)))
|
||||
|
||||
/* Slave interface event and count register offsets from PERIPHBASE */
|
||||
#define EVENT_SELECT7_OFFSET UL(0x80000)
|
||||
#define EVENT_SELECT6_OFFSET UL(0x70000)
|
||||
#define EVENT_SELECT5_OFFSET UL(0x60000)
|
||||
#define EVENT_SELECT4_OFFSET UL(0x50000)
|
||||
#define EVENT_SELECT3_OFFSET UL(0x40000)
|
||||
#define EVENT_SELECT2_OFFSET UL(0x30000)
|
||||
#define EVENT_SELECT1_OFFSET UL(0x20000)
|
||||
#define EVENT_SELECT0_OFFSET UL(0x10000)
|
||||
#define EVENT_OFFSET(index) (EVENT_SELECT0_OFFSET + \
|
||||
(UL(0x10000) * (index)))
|
||||
|
||||
/* Control and ID register offsets */
|
||||
#define CTRL_OVERRIDE_REG U(0x0)
|
||||
#define SECURE_ACCESS_REG U(0x8)
|
||||
#define STATUS_REG U(0xc)
|
||||
#define IMPRECISE_ERR_REG U(0x10)
|
||||
#define PERFMON_CTRL_REG U(0x100)
|
||||
#define IFACE_MON_CTRL_REG U(0x104)
|
||||
|
||||
/* Component and peripheral ID registers */
|
||||
#define PERIPHERAL_ID0 U(0xFE0)
|
||||
#define PERIPHERAL_ID1 U(0xFE4)
|
||||
#define PERIPHERAL_ID2 U(0xFE8)
|
||||
#define PERIPHERAL_ID3 U(0xFEC)
|
||||
#define PERIPHERAL_ID4 U(0xFD0)
|
||||
#define PERIPHERAL_ID5 U(0xFD4)
|
||||
#define PERIPHERAL_ID6 U(0xFD8)
|
||||
#define PERIPHERAL_ID7 U(0xFDC)
|
||||
|
||||
#define COMPONENT_ID0 U(0xFF0)
|
||||
#define COMPONENT_ID1 U(0xFF4)
|
||||
#define COMPONENT_ID2 U(0xFF8)
|
||||
#define COMPONENT_ID3 U(0xFFC)
|
||||
#define COMPONENT_ID4 U(0x1000)
|
||||
#define COMPONENT_ID5 U(0x1004)
|
||||
#define COMPONENT_ID6 U(0x1008)
|
||||
#define COMPONENT_ID7 U(0x100C)
|
||||
|
||||
/* Slave interface register offsets */
|
||||
#define SNOOP_CTRL_REG U(0x0)
|
||||
#define SH_OVERRIDE_REG U(0x4)
|
||||
#define READ_CHNL_QOS_VAL_OVERRIDE_REG U(0x100)
|
||||
#define WRITE_CHNL_QOS_VAL_OVERRIDE_REG U(0x104)
|
||||
#define MAX_OT_REG U(0x110)
|
||||
|
||||
/* Snoop Control register bit definitions */
|
||||
#define DVM_EN_BIT BIT_32(1)
|
||||
#define SNOOP_EN_BIT BIT_32(0)
|
||||
#define SUPPORT_SNOOPS BIT_32(30)
|
||||
#define SUPPORT_DVM BIT_32(31)
|
||||
|
||||
/* Status register bit definitions */
|
||||
#define CHANGE_PENDING_BIT BIT_32(0)
|
||||
|
||||
/* Event and count register offsets */
|
||||
#define EVENT_SELECT_REG U(0x0)
|
||||
#define EVENT_COUNT_REG U(0x4)
|
||||
#define COUNT_CNTRL_REG U(0x8)
|
||||
#define COUNT_OVERFLOW_REG U(0xC)
|
||||
|
||||
/* Slave interface monitor registers */
|
||||
#define INT_MON_REG_SI0 U(0x90000)
|
||||
#define INT_MON_REG_SI1 U(0x90004)
|
||||
#define INT_MON_REG_SI2 U(0x90008)
|
||||
#define INT_MON_REG_SI3 U(0x9000C)
|
||||
#define INT_MON_REG_SI4 U(0x90010)
|
||||
#define INT_MON_REG_SI5 U(0x90014)
|
||||
#define INT_MON_REG_SI6 U(0x90018)
|
||||
|
||||
/* Master interface monitor registers */
|
||||
#define INT_MON_REG_MI0 U(0x90100)
|
||||
#define INT_MON_REG_MI1 U(0x90104)
|
||||
#define INT_MON_REG_MI2 U(0x90108)
|
||||
#define INT_MON_REG_MI3 U(0x9010c)
|
||||
#define INT_MON_REG_MI4 U(0x90110)
|
||||
#define INT_MON_REG_MI5 U(0x90114)
|
||||
|
||||
#define SLAVE_IF_UNUSED -1
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/* Function declarations */
|
||||
|
||||
/*
|
||||
* The ARM CCI driver needs the following:
|
||||
* 1. Base address of the CCI product
|
||||
* 2. An array of map between AMBA 4 master ids and ACE/ACE lite slave
|
||||
* interfaces.
|
||||
* 3. Size of the array.
|
||||
*
|
||||
* SLAVE_IF_UNUSED should be used in the map to represent no AMBA 4 master exists
|
||||
* for that interface.
|
||||
*/
|
||||
void cci_init(uintptr_t base, const int *map, unsigned int num_cci_masters);
|
||||
|
||||
void cci_enable_snoop_dvm_reqs(unsigned int master_id);
|
||||
void cci_disable_snoop_dvm_reqs(unsigned int master_id);
|
||||
|
||||
#endif /* __ASSEMBLER__ */
|
||||
#endif /* CCI_H */
|
||||
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef CCN_H
|
||||
#define CCN_H
|
||||
|
||||
/*
|
||||
* This macro defines the maximum number of master interfaces that reside on
|
||||
* Request nodes which the CCN driver can accommodate. The driver APIs to add
|
||||
* and remove Request nodes from snoop/dvm domains take a bit map of master
|
||||
* interfaces as inputs. The largest C data type that can be used is a 64-bit
|
||||
* unsigned integer. Hence the value of 64. The platform will have to ensure
|
||||
* that the master interfaces are numbered from 0-63.
|
||||
*/
|
||||
#define CCN_MAX_RN_MASTERS 64
|
||||
|
||||
/*
|
||||
* The following constants define the various run modes that the platform can
|
||||
* request the CCN driver to place the L3 cache in. These map to the
|
||||
* programmable P-State values in a HN-F P-state register.
|
||||
*/
|
||||
#define CCN_L3_RUN_MODE_NOL3 0x0 /* HNF_PM_NOL3 */
|
||||
#define CCN_L3_RUN_MODE_SFONLY 0x1 /* HNF_PM_SFONLY */
|
||||
#define CCN_L3_RUN_MODE_HAM 0x2 /* HNF_PM_HALF */
|
||||
#define CCN_L3_RUN_MODE_FAM 0x3 /* HNF_PM_FULL */
|
||||
|
||||
/* part 0 IDs for various CCN variants */
|
||||
#define CCN_502_PART0_ID 0x30
|
||||
#define CCN_504_PART0_ID 0x26
|
||||
#define CCN_505_PART0_ID 0x27
|
||||
#define CCN_508_PART0_ID 0x28
|
||||
#define CCN_512_PART0_ID 0x29
|
||||
|
||||
/*
|
||||
* The following macro takes the value returned from a read of a HN-F P-state
|
||||
* status register and returns the retention state value.
|
||||
*/
|
||||
#define CCN_GET_RETENTION_STATE(pstate) ((pstate >> 4) & 0x3)
|
||||
|
||||
/*
|
||||
* The following macro takes the value returned from a read of a HN-F P-state
|
||||
* status register and returns the run state value.
|
||||
*/
|
||||
#define CCN_GET_RUN_STATE(pstate) (pstate & 0xf)
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
#include <stdint.h>
|
||||
|
||||
/*
|
||||
* This structure describes some of the implementation defined attributes of the
|
||||
* CCN IP. It is used by the platform port to specify these attributes in order
|
||||
* to initialise the CCN driver. The attributes are described below.
|
||||
*
|
||||
* 1. The 'num_masters' field specifies the total number of master interfaces
|
||||
* resident on Request nodes.
|
||||
*
|
||||
* 2. The 'master_to_rn_id_map' field is a ponter to an array in which each
|
||||
* index corresponds to a master interface and its value corresponds to the
|
||||
* Request node on which the master interface resides.
|
||||
* This field is not simply defined as an array of size CCN_MAX_RN_MASTERS.
|
||||
* In reality, a platform will have much fewer master * interfaces than
|
||||
* CCN_MAX_RN_MASTERS. With an array of this size, it would also have to
|
||||
* set the unused entries to a suitable value. Zeroing the array would not
|
||||
* be enough since 0 is also a valid node id. Hence, such an array is not
|
||||
* used.
|
||||
*
|
||||
* 3. The 'periphbase' field is the base address of the programmer's view of the
|
||||
* CCN IP.
|
||||
*/
|
||||
typedef struct ccn_desc {
|
||||
unsigned int num_masters;
|
||||
const unsigned char *master_to_rn_id_map;
|
||||
uintptr_t periphbase;
|
||||
} ccn_desc_t;
|
||||
|
||||
/* Enum used to loop through all types of nodes in CCN*/
|
||||
typedef enum node_types {
|
||||
NODE_TYPE_RNF = 0,
|
||||
NODE_TYPE_RNI,
|
||||
NODE_TYPE_RND,
|
||||
NODE_TYPE_HNF,
|
||||
NODE_TYPE_HNI,
|
||||
NODE_TYPE_SN,
|
||||
NUM_NODE_TYPES
|
||||
} node_types_t;
|
||||
|
||||
void ccn_init(const ccn_desc_t *plat_ccn_desc);
|
||||
void ccn_enter_snoop_dvm_domain(unsigned long long master_iface_map);
|
||||
void ccn_exit_snoop_dvm_domain(unsigned long long master_iface_map);
|
||||
void ccn_enter_dvm_domain(unsigned long long master_iface_map);
|
||||
void ccn_exit_dvm_domain(unsigned long long master_iface_map);
|
||||
void ccn_set_l3_run_mode(unsigned int mode);
|
||||
void ccn_program_sys_addrmap(unsigned int sn0_id,
|
||||
unsigned int sn1_id,
|
||||
unsigned int sn2_id,
|
||||
unsigned int top_addr_bit0,
|
||||
unsigned int top_addr_bit1,
|
||||
unsigned char three_sn_en);
|
||||
unsigned int ccn_get_l3_run_mode(void);
|
||||
int ccn_get_part0_id(uintptr_t periphbase);
|
||||
|
||||
void ccn_write_node_reg(node_types_t node_type, unsigned int node_id,
|
||||
unsigned int reg_offset,
|
||||
unsigned long long val);
|
||||
unsigned long long ccn_read_node_reg(node_types_t node_type,
|
||||
unsigned int node_id,
|
||||
unsigned int reg_offset);
|
||||
|
||||
#endif /* __ASSEMBLER__ */
|
||||
#endif /* CCN_H */
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef _CC_CRYPTO_BOOT_DEFS_H
|
||||
#define _CC_CRYPTO_BOOT_DEFS_H
|
||||
|
||||
/*! @file
|
||||
@brief This file contains SBROM definitions
|
||||
*/
|
||||
|
||||
/*! Version counters value. */
|
||||
typedef enum {
|
||||
|
||||
CC_SW_VERSION_COUNTER1 = 1, /*!< Counter 1 - trusted version. */
|
||||
CC_SW_VERSION_COUNTER2, /*!< Counter 2 - non trusted version. */
|
||||
|
||||
CC_SW_VERSION_MAX = 0x7FFFFFFF
|
||||
|
||||
} CCSbSwVersionId_t;
|
||||
|
||||
/* HASH boot key definition */
|
||||
typedef enum {
|
||||
CC_SB_HASH_BOOT_KEY_0_128B = 0, /*!< 128-bit truncated SHA256 digest of public key 0. */
|
||||
CC_SB_HASH_BOOT_KEY_1_128B = 1, /*!< 128-bit truncated SHA256 digest of public key 1. */
|
||||
CC_SB_HASH_BOOT_KEY_256B = 2, /*!< 256-bit SHA256 digest of public key. */
|
||||
CC_SB_HASH_BOOT_NOT_USED = 0xFF,
|
||||
CC_SB_HASH_MAX_NUM = 0x7FFFFFFF, /*!\internal use external 128-bit truncated SHA256 digest */
|
||||
} CCSbPubKeyIndexType_t;
|
||||
|
||||
|
||||
#endif
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*!
|
||||
@file
|
||||
@brief This file contains the platform-dependent definitions that are used in the SBROM code.
|
||||
*/
|
||||
|
||||
#ifndef _CC_PAL_SB_PLAT_H
|
||||
#define _CC_PAL_SB_PLAT_H
|
||||
|
||||
#include "cc_pal_types.h"
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/*! Definition of DMA address type, can be 32 bits or 64 bits according to CryptoCell's HW. */
|
||||
typedef uint64_t CCDmaAddr_t;
|
||||
/*! Definition of CryptoCell address type, can be 32 bits or 64 bits according to platform. */
|
||||
typedef uintptr_t CCAddr_t;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef CC_PAL_TYPES_H
|
||||
#define CC_PAL_TYPES_H
|
||||
|
||||
/*!
|
||||
@file
|
||||
@brief This file contains platform-dependent definitions and types.
|
||||
*/
|
||||
|
||||
#include "cc_pal_types_plat.h"
|
||||
|
||||
typedef enum {
|
||||
CC_FALSE = 0,
|
||||
CC_TRUE = 1
|
||||
} CCBool;
|
||||
|
||||
#define CC_SUCCESS 0UL
|
||||
#define CC_FAIL 1UL
|
||||
|
||||
#define CC_1K_SIZE_IN_BYTES 1024
|
||||
#define CC_BITS_IN_BYTE 8
|
||||
#define CC_BITS_IN_32BIT_WORD 32
|
||||
#define CC_32BIT_WORD_SIZE (sizeof(uint32_t))
|
||||
|
||||
#define CC_OK CC_SUCCESS
|
||||
|
||||
#define CC_UNUSED_PARAM(prm) ((void)prm)
|
||||
|
||||
#define CC_MAX_UINT32_VAL (0xFFFFFFFF)
|
||||
|
||||
#define CALC_FULL_BYTES(numBits) (((numBits) + (CC_BITS_IN_BYTE - 1))/CC_BITS_IN_BYTE)
|
||||
#define CALC_FULL_32BIT_WORDS(numBits) (((numBits) + (CC_BITS_IN_32BIT_WORD - 1))/CC_BITS_IN_32BIT_WRD)
|
||||
#define CALC_32BIT_WORDS_FROM_BYTES(sizeBytes) (((sizeBytes) + CC_32BIT_WORD_SIZE - 1)/CC_32BIT_WORD_SIZE)
|
||||
|
||||
#endif
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*! @file
|
||||
@brief This file contains basic type definitions that are platform-dependent.
|
||||
*/
|
||||
#ifndef _CC_PAL_TYPES_PLAT_H
|
||||
#define _CC_PAL_TYPES_PLAT_H
|
||||
/* Host specific types for standard (ISO-C99) compilant platforms */
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
typedef uint32_t CCStatus;
|
||||
|
||||
#define CCError_t CCStatus
|
||||
#define CC_INFINITE 0xFFFFFFFF
|
||||
|
||||
#define CEXPORT_C
|
||||
#define CIMPORT_C
|
||||
|
||||
#endif /*_CC_PAL_TYPES_PLAT_H*/
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef _CC_SEC_DEFS_H
|
||||
#define _CC_SEC_DEFS_H
|
||||
|
||||
/*!
|
||||
@file
|
||||
@brief This file contains general hash definitions and types.
|
||||
*/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/*! The hashblock size in words. */
|
||||
#define HASH_BLOCK_SIZE_IN_WORDS 16
|
||||
/*! The hash - SHA2 results in words. */
|
||||
#define HASH_RESULT_SIZE_IN_WORDS 8
|
||||
#define HASH_RESULT_SIZE_IN_BYTES 32
|
||||
|
||||
/*! Definition for hash result array. */
|
||||
typedef uint32_t CCHashResult_t[HASH_RESULT_SIZE_IN_WORDS];
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef _CRYPTO_DRIVER_H
|
||||
#define _CRYPTO_DRIVER_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include "cc_pal_sb_plat.h"
|
||||
#include "cc_sec_defs.h"
|
||||
|
||||
/*----------------------------
|
||||
PUBLIC FUNCTIONS
|
||||
-----------------------------------*/
|
||||
/*!
|
||||
* @brief This function gives the functionality of integrated hash
|
||||
*
|
||||
* @param[in] hwBaseAddress - CryptoCell base address
|
||||
* @param[out] hashResult - the HASH result.
|
||||
*
|
||||
*/
|
||||
CCError_t SBROM_CryptoHash(unsigned long hwBaseAddress, CCDmaAddr_t inputDataAddr, uint32_t BlockSize,
|
||||
CCHashResult_t hashResult);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef _NVM__H
|
||||
#define _NVM__H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include "cc_crypto_boot_defs.h"
|
||||
#include "cc_pal_types.h"
|
||||
#include "cc_sec_defs.h"
|
||||
|
||||
/*------------------------------------
|
||||
DEFINES
|
||||
-------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief This function reads the LCS from the SRAM/NVM
|
||||
*
|
||||
* @param[in] hwBaseAddress - CryptoCell base address
|
||||
*
|
||||
* @param[in/out] lcs_ptr - pointer to memory to store the LCS
|
||||
*
|
||||
* @return CCError_t - On success the value CC_OK is returned, and on failure -a value from NVM_error.h
|
||||
*/
|
||||
CCError_t NVM_GetLCS(unsigned long hwBaseAddress, uint32_t *lcs_ptr);
|
||||
|
||||
/**
|
||||
* @brief The NVM_ReadHASHPubKey function is a NVM interface function -
|
||||
* The function retrieves the HASH of the device Public key from the SRAM/NVM
|
||||
*
|
||||
* @param[in] hwBaseAddress - CryptoCell base address
|
||||
*
|
||||
* @param[in] pubKeyIndex - Index of HASH in the OTP
|
||||
*
|
||||
* @param[out] PubKeyHASH - the public key HASH.
|
||||
*
|
||||
* @param[in] hashSizeInWords - hash size (valid values: 4W, 8W)
|
||||
*
|
||||
* @return CCError_t - On success the value CC_OK is returned, and on failure -a value from NVM_error.h
|
||||
*/
|
||||
|
||||
CCError_t NVM_ReadHASHPubKey(unsigned long hwBaseAddress, CCSbPubKeyIndexType_t pubKeyIndex, CCHashResult_t PubKeyHASH, uint32_t hashSizeInWords);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef _NVM_OTP_H
|
||||
#define _NVM_OTP_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include "cc_crypto_boot_defs.h"
|
||||
#include "cc_pal_types.h"
|
||||
|
||||
/*------------------------------------
|
||||
DEFINES
|
||||
-------------------------------------*/
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief The NVM_GetSwVersion function is a NVM interface function -
|
||||
* The function retrieves the SW version from the SRAM/NVM.
|
||||
* In case of OTP, we support up to 16 anti-rollback counters (taken from the certificate)
|
||||
*
|
||||
* @param[in] hwBaseAddress - CryptoCell base address
|
||||
*
|
||||
* @param[in] counterId - relevant only for OTP (valid values: 1,2)
|
||||
*
|
||||
* @param[out] swVersion - the minimum SW version
|
||||
*
|
||||
* @return CCError_t - On success the value CC_OK is returned, and on failure -a value from NVM_error.h
|
||||
*/
|
||||
CCError_t NVM_GetSwVersion(unsigned long hwBaseAddress, CCSbSwVersionId_t counterId, uint32_t *swVersion);
|
||||
|
||||
|
||||
/**
|
||||
* @brief The NVM_SetSwVersion function is a NVM interface function -
|
||||
* The function writes the SW version into the SRAM/NVM.
|
||||
* In case of OTP, we support up to 16 anti-rollback counters (taken from the certificate)
|
||||
*
|
||||
* @param[in] hwBaseAddress - CryptoCell base address
|
||||
*
|
||||
* @param[in] counterId - relevant only for OTP (valid values: 1,2)
|
||||
*
|
||||
* @param[in] swVersion - the minimum SW version
|
||||
*
|
||||
* @return CCError_t - On success the value CC_OK is returned, and on failure -a value from NVM_error.h
|
||||
*/
|
||||
CCError_t NVM_SetSwVersion(unsigned long hwBaseAddress, CCSbSwVersionId_t counterId, uint32_t swVersion);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef RSA_H
|
||||
#define RSA_H
|
||||
|
||||
/*
|
||||
* All the includes that are needed for code using this module to
|
||||
* compile correctly should be #included here.
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include "cc_pal_types.h"
|
||||
|
||||
/************************ Defines ******************************/
|
||||
|
||||
/* the modulus size in bits */
|
||||
#if (KEY_SIZE == 2048)
|
||||
#define RSA_MOD_SIZE_IN_BITS 2048UL
|
||||
#elif (KEY_SIZE == 3072)
|
||||
#define RSA_MOD_SIZE_IN_BITS 3072UL
|
||||
#else
|
||||
#error Unsupported CryptoCell key size requested
|
||||
#endif
|
||||
|
||||
#define RSA_MOD_SIZE_IN_BYTES (CALC_FULL_BYTES(RSA_MOD_SIZE_IN_BITS))
|
||||
#define RSA_MOD_SIZE_IN_WORDS (CALC_FULL_32BIT_WORDS(RSA_MOD_SIZE_IN_BITS))
|
||||
#define RSA_MOD_SIZE_IN_256BITS (RSA_MOD_SIZE_IN_WORDS/8)
|
||||
#define RSA_EXP_SIZE_IN_BITS 17UL
|
||||
#define RSA_EXP_SIZE_IN_BYTES (CALC_FULL_BYTES(RSA_EXP_SIZE_IN_BITS))
|
||||
|
||||
/*
|
||||
* @brief The RSA_CalcNp calculates Np value and saves it into Np_ptr:
|
||||
*
|
||||
*
|
||||
|
||||
* @param[in] hwBaseAddress - HW base address. Relevant for HW
|
||||
* implementation, for SW it is ignored.
|
||||
* @N_ptr[in] - The pointer to the modulus buffer.
|
||||
* @Np_ptr[out] - pointer to Np vector buffer. Its size must be >= 160.
|
||||
*/
|
||||
void RSA_CalcNp(unsigned long hwBaseAddress,
|
||||
uint32_t *N_ptr,
|
||||
uint32_t *Np_ptr);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef _SBROM_BSV_API_H
|
||||
#define _SBROM_BSV_API_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/*! @file
|
||||
@brief This file contains all SBROM library APIs and definitions.
|
||||
*/
|
||||
#include "cc_pal_types.h"
|
||||
|
||||
/* Life cycle state definitions */
|
||||
#define CC_BSV_CHIP_MANUFACTURE_LCS 0x0 /*!< CM lifecycle value. */
|
||||
#define CC_BSV_DEVICE_MANUFACTURE_LCS 0x1 /*!< DM lifecycle value. */
|
||||
#define CC_BSV_SECURITY_DISABLED_LCS 0x3 /*!< SD lifecycle value. */
|
||||
#define CC_BSV_SECURE_LCS 0x5 /*!< Secure lifecycle value. */
|
||||
#define CC_BSV_RMA_LCS 0x7 /*!< RMA lifecycle value. */
|
||||
|
||||
/*----------------------------
|
||||
PUBLIC FUNCTIONS
|
||||
-----------------------------------*/
|
||||
|
||||
/*!
|
||||
@brief This function should be the first ARM TrustZone CryptoCell TEE SBROM library API called.
|
||||
It verifies the HW product and version numbers.
|
||||
|
||||
@return CC_OK On success.
|
||||
@return A non-zero value from sbrom_bsv_error.h on failure.
|
||||
*/
|
||||
CCError_t CC_BsvSbromInit(
|
||||
unsigned long hwBaseAddress /*!< [in] HW registers base address. */
|
||||
);
|
||||
|
||||
|
||||
/*!
|
||||
@brief This function can be used for checking the LCS value, after CC_BsvLcsGetAndInit was called by the Boot ROM.
|
||||
|
||||
@return CC_OK On success.
|
||||
@return A non-zero value from sbrom_bsv_error.h on failure.
|
||||
*/
|
||||
CCError_t CC_BsvLcsGet(
|
||||
unsigned long hwBaseAddress, /*!< [in] HW registers base address. */
|
||||
uint32_t *pLcs /*!< [out] Returned lifecycle state. */
|
||||
);
|
||||
|
||||
/*!
|
||||
@brief This function retrieves the HW security lifecycle state, performs validity checks,
|
||||
and additional initializations in case the LCS is RMA (sets the Kce to fixed value).
|
||||
\note Invalid LCS results in an error returned.
|
||||
In this case, the customer's code must completely disable the device.
|
||||
|
||||
@return CC_OK On success.
|
||||
@return A non-zero value from sbrom_bsv_error.h on failure.
|
||||
*/
|
||||
CCError_t CC_BsvLcsGetAndInit(
|
||||
unsigned long hwBaseAddress, /*!< [in] HW registers base address. */
|
||||
uint32_t *pLcs /*!< [out] Returned lifecycle state. */
|
||||
);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef _SECURE_BOOT_BASE_FUNC_H
|
||||
#define _SECURE_BOOT_BASE_FUNC_H
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include "cc_pal_types.h"
|
||||
#include "secureboot_gen_defs.h"
|
||||
|
||||
|
||||
/*----------------------------
|
||||
PUBLIC FUNCTIONS
|
||||
-----------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief This function calculates the HASH over the given data and than verify
|
||||
* RSA signature on that hashed data
|
||||
*
|
||||
* @param[in] hwBaseAddr - CryptoCell base address
|
||||
* @param[in] pData - pointer to the data to be verified
|
||||
* @param[in] pNParams - a pointer to the public key parameters
|
||||
* @param[in] pSignature - a pointer to the signature structure
|
||||
* @param[in] sizeOfData - size of the data to calculate the HASH on (in bytes)
|
||||
* @param[in] RSAAlg - RSA algorithm to use
|
||||
*
|
||||
* @return CCError_t - On success the value CC_OK is returned,
|
||||
* on failure - a value from BootImagesVerifier_error.h
|
||||
*/
|
||||
CCError_t CCSbVerifySignature(unsigned long hwBaseAddress,
|
||||
uint32_t *pData,
|
||||
CCSbNParams_t *pNParams,
|
||||
CCSbSignature_t *pSignature,
|
||||
uint32_t sizeOfData,
|
||||
CCSbRsaAlg_t RSAAlg);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef _SECURE_BOOT_GEN_DEFS_H
|
||||
#define _SECURE_BOOT_GEN_DEFS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/*! @file
|
||||
@brief This file contains all of the definitions and structures that are used for the secure boot.
|
||||
*/
|
||||
|
||||
#include "cc_pal_sb_plat.h"
|
||||
#include "cc_sec_defs.h"
|
||||
|
||||
|
||||
/* General definitions */
|
||||
/***********************/
|
||||
|
||||
/*RSA definitions*/
|
||||
#if (KEY_SIZE == 2048)
|
||||
#define SB_RSA_MOD_SIZE_IN_WORDS 64
|
||||
#elif (KEY_SIZE == 3072)
|
||||
#define SB_RSA_MOD_SIZE_IN_WORDS 96
|
||||
#else
|
||||
#error Unsupported CryptoCell key size requested
|
||||
#endif
|
||||
|
||||
#define SB_RSA_HW_PKI_PKA_BARRETT_MOD_TAG_SIZE_IN_WORDS 5
|
||||
|
||||
|
||||
/*! Public key data structure. */
|
||||
typedef struct {
|
||||
uint32_t N[SB_RSA_MOD_SIZE_IN_WORDS]; /*!< N public key, big endian representation. */
|
||||
uint32_t Np[SB_RSA_HW_PKI_PKA_BARRETT_MOD_TAG_SIZE_IN_WORDS]; /*!< Np (Barrett n' value). */
|
||||
} CCSbNParams_t;
|
||||
|
||||
/*! Signature structure. */
|
||||
typedef struct {
|
||||
uint32_t sig[SB_RSA_MOD_SIZE_IN_WORDS]; /*!< RSA PSS signature. */
|
||||
} CCSbSignature_t;
|
||||
|
||||
|
||||
/********* Supported algorithms definitions ***********/
|
||||
|
||||
/*! RSA supported algorithms */
|
||||
/* Note: this applies to either 2k or 3k based on CryptoCell SBROM library
|
||||
* version - it means 2k in version 1 and 3k in version 2 (yes, really).
|
||||
*/
|
||||
typedef enum {
|
||||
RSA_PSS = 0x01, /*!< RSA PSS after hash SHA 256 */
|
||||
RSA_PKCS15 = 0x02, /*!< RSA PKX15 */
|
||||
RSA_Last = 0x7FFFFFFF
|
||||
} CCSbRsaAlg_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef UTIL_H
|
||||
#define UTIL_H
|
||||
|
||||
/*
|
||||
* All the includes that are needed for code using this module to
|
||||
* compile correctly should be #included here.
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/************************ Defines ******************************/
|
||||
|
||||
/* invers the bytes on a word- used for output from HASH */
|
||||
#ifdef BIG__ENDIAN
|
||||
#define UTIL_INVERSE_UINT32_BYTES(val) (val)
|
||||
#else
|
||||
#define UTIL_INVERSE_UINT32_BYTES(val) \
|
||||
(((val) >> 24) | (((val) & 0x00FF0000) >> 8) | (((val) & 0x0000FF00) << 8) | (((val) & 0x000000FF) << 24))
|
||||
#endif
|
||||
|
||||
/* invers the bytes on a word - used for input data for HASH */
|
||||
#ifdef BIG__ENDIAN
|
||||
#define UTIL_REVERT_UINT32_BYTES(val) \
|
||||
(((val) >> 24) | (((val) & 0x00FF0000) >> 8) | (((val) & 0x0000FF00) << 8) | (((val) & 0x000000FF) << 24))
|
||||
#else
|
||||
#define UTIL_REVERT_UINT32_BYTES(val) (val)
|
||||
#endif
|
||||
|
||||
/* ------------------------------------------------------------
|
||||
**
|
||||
* @brief This function executes a reverse bytes copying from one buffer to another buffer.
|
||||
*
|
||||
* @param[in] dst_ptr - The pointer to destination buffer.
|
||||
* @param[in] src_ptr - The pointer to source buffer.
|
||||
* @param[in] size - The size in bytes.
|
||||
*
|
||||
*/
|
||||
|
||||
void UTIL_ReverseMemCopy(uint8_t *dst_ptr, uint8_t *src_ptr, uint32_t size);
|
||||
|
||||
|
||||
/* ------------------------------------------------------------
|
||||
**
|
||||
* @brief This function executes a reversed byte copy on a specified buffer.
|
||||
*
|
||||
* on a 6 byte byffer:
|
||||
*
|
||||
* buff[5] <---> buff[0]
|
||||
* buff[4] <---> buff[1]
|
||||
* buff[3] <---> buff[2]
|
||||
*
|
||||
* @param[in] dst_ptr - The counter buffer.
|
||||
* @param[in] src_ptr - The counter size in bytes.
|
||||
*
|
||||
*/
|
||||
void UTIL_ReverseBuff(uint8_t *buff_ptr, uint32_t size);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+221
@@ -0,0 +1,221 @@
|
||||
/*
|
||||
* Copyright (c) 2017-2020 ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef _BSV_API_H
|
||||
#define _BSV_API_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/*!
|
||||
@file
|
||||
@brief This file contains the Boot Services APIs and definitions.
|
||||
|
||||
@defgroup cc_bsv_api CryptoCell Boot Services APIs and definitions
|
||||
@{
|
||||
@ingroup cc_bsv
|
||||
*/
|
||||
|
||||
#include "cc_pal_types.h"
|
||||
#include "cc_sec_defs.h"
|
||||
#include "cc_boot_defs.h"
|
||||
|
||||
/* Life cycle state definitions. */
|
||||
#define CC_BSV_CHIP_MANUFACTURE_LCS 0x0 /*!< The CM life-cycle state (LCS) value. */
|
||||
#define CC_BSV_DEVICE_MANUFACTURE_LCS 0x1 /*!< The DM life-cycle state (LCS) value. */
|
||||
#define CC_BSV_SECURE_LCS 0x5 /*!< The Secure life-cycle state (LCS) value. */
|
||||
#define CC_BSV_RMA_LCS 0x7 /*!< The RMA life-cycle state (LCS) value. */
|
||||
#define CC_BSV_INVALID_LCS 0xff /*!< The invalid life-cycle state (LCS) value. */
|
||||
|
||||
/*----------------------------
|
||||
TYPES
|
||||
-----------------------------------*/
|
||||
|
||||
/*----------------------------
|
||||
PUBLIC FUNCTIONS
|
||||
-----------------------------------*/
|
||||
|
||||
|
||||
/*!
|
||||
@brief This function verifies the product and version numbers of the HW, and initializes it.
|
||||
|
||||
\warning This function must be the first CryptoCell-7xx SBROM library API called.
|
||||
|
||||
@return \c CC_OK on success.
|
||||
@return A non-zero value from bsv_error.h on failure.
|
||||
*/
|
||||
CCError_t CC_BsvInit(
|
||||
unsigned long hwBaseAddress /*!< [in] The base address of the CryptoCell HW registers. */
|
||||
);
|
||||
|
||||
/*!
|
||||
@brief This function retrieves the HW LCS and performs validity checks.
|
||||
|
||||
If the LCS is RMA, it also sets the OTP secret keys to a fixed value.
|
||||
|
||||
@note An error is returned if there is an invalid LCS. If this happens, your code must
|
||||
completely disable the device.
|
||||
|
||||
@return \c CC_OK on success.
|
||||
@return A non-zero value from bsv_error.h on failure.
|
||||
*/
|
||||
CCError_t CC_BsvGetAndInitLcs(
|
||||
unsigned long hwBaseAddress, /*!< [in] The base address of the CryptoCell HW registers. */
|
||||
uint32_t *pLcs /*!< [out] The value of the current LCS. */
|
||||
);
|
||||
|
||||
/*!
|
||||
@brief This function retrieves the LCS from the NVM manager.
|
||||
|
||||
@return \c CC_OK on success.
|
||||
@return A non-zero value from bsv_error.h on failure.
|
||||
*/
|
||||
CCError_t CC_BsvLcsGet(
|
||||
unsigned long hwBaseAddress, /*!< [in] The base address of the CryptoCell HW registers. */
|
||||
uint32_t *pLcs /*!< [out] The value of the current LCS. */
|
||||
);
|
||||
|
||||
/*!
|
||||
@brief This function reads software revocation counter from OTP memory, according to the provided sw version index.
|
||||
SW version is stored in NVM counter and represented by ones. Meaning seVersion=5 would be stored as binary 0b11111;
|
||||
hence:
|
||||
the maximal of trusted is 32
|
||||
the maximal of non-trusted is 224
|
||||
|
||||
@return \c CC_OK on success.
|
||||
@return A non-zero value from bsv_error.h on failure.
|
||||
*/
|
||||
CCError_t CC_BsvSwVersionGet(
|
||||
unsigned long hwBaseAddress, /*!< [in] HW registers base address. */
|
||||
CCSbSwVersionId_t id, /*!< [in] Enumeration defining the trusted/non-trusted counter to read. */
|
||||
uint32_t *swVersion /*!< [out] The value of the requested counter as read from OTP memory. */
|
||||
);
|
||||
|
||||
/*!
|
||||
@brief This function sets the NVM counter according to swVersionID (trusted/non-trusted).
|
||||
|
||||
@return \c CC_OK on success.
|
||||
@return A non-zero value from bsv_error.h on failure.
|
||||
*/
|
||||
CCError_t CC_BsvSwVersionSet(
|
||||
unsigned long hwBaseAddress, /*!< [in] HW registers base address. */
|
||||
CCSbSwVersionId_t id, /*!< [in] Enumeration defining the trusted/non-trusted counter to read. */
|
||||
uint32_t swVersion /*!< [in] New value of the counter to be programmed in OTP memory. */
|
||||
);
|
||||
|
||||
/*!
|
||||
@brief This function sets the "fatal error" flag in the NVM manager, to disable the use of
|
||||
any HW keys or security services.
|
||||
|
||||
@return \c CC_OK on success.
|
||||
@return A non-zero value from bsv_error.h on failure.
|
||||
*/
|
||||
CCError_t CC_BsvFatalErrorSet(
|
||||
unsigned long hwBaseAddress /*!< [in] The base address of the CryptoCell HW registers. */
|
||||
);
|
||||
|
||||
/*!
|
||||
@brief This function retrieves the public key hash from OTP memory, according to the provided index.
|
||||
|
||||
@return \c CC_OK on success.
|
||||
@return A non-zero value from bsv_error.h on failure.
|
||||
*/
|
||||
CCError_t CC_BsvPubKeyHashGet(
|
||||
unsigned long hwBaseAddress, /*!< [in] HW registers base address. */
|
||||
CCSbPubKeyIndexType_t keyIndex, /*!< [in] Enumeration defining the key hash to retrieve: 128-bit HBK0, 128-bit HBK1, or 256-bit HBK. */
|
||||
uint32_t *hashedPubKey, /*!< [out] A buffer to contain the public key HASH. */
|
||||
uint32_t hashResultSizeWords /*!< [in] The size of the hash in 32-bit words:
|
||||
- Must be 4 for 128-bit hash.
|
||||
- Must be 8 for 256bit hash. */
|
||||
);
|
||||
|
||||
/*!
|
||||
@brief This function permanently sets the RMA LCS for the ICV and the OEM.
|
||||
|
||||
@return \c CC_OK on success.
|
||||
@return A non-zero value from bsv_error.h on failure.
|
||||
*/
|
||||
CCError_t CC_BsvRMAModeEnable(
|
||||
unsigned long hwBaseAddress /*!< [in] The base address of the CryptoCell HW registers. */
|
||||
);
|
||||
|
||||
/*!
|
||||
@brief This function is called by the ICV code, to disable the OEM code from changing the ICV RMA bit flag.
|
||||
|
||||
@return \c CC_OK on success.
|
||||
@return A non-zero value from bsv_error.h on failure.
|
||||
*/
|
||||
CCError_t CC_BsvICVRMAFlagBitLock(
|
||||
unsigned long hwBaseAddress /*!< [in] The base address of the CryptoCell HW registers. */
|
||||
);
|
||||
|
||||
/*!
|
||||
@brief This function locks the defined ICV class keys from further usage.
|
||||
|
||||
@return \c CC_OK on success.
|
||||
@return A non-zero value from bsv_error.h on failure.
|
||||
*/
|
||||
CCError_t CC_BsvICVKeyLock(
|
||||
unsigned long hwBaseAddress, /*!< [in] HW registers base address. */
|
||||
CCBool_t isICVProvisioningKeyLock, /*!< [in] Should the provisioning key be locked. */
|
||||
CCBool_t isICVCodeEncKeyLock /*!< [in] Should the encryption key be locked. */
|
||||
);
|
||||
|
||||
|
||||
/*!
|
||||
@brief This function retrieves the value of "secure disable" bit.
|
||||
|
||||
@return \c CC_OK on success.
|
||||
@return A non-zero value from bsv_error.h on failure.
|
||||
*/
|
||||
CCError_t CC_BsvSecureDisableGet(
|
||||
unsigned long hwBaseAddress, /*!< [in] HW registers base address. */
|
||||
CCBool_t *isSDEnabled /*!< [out] The value of the SD Enable bit. */
|
||||
);
|
||||
|
||||
|
||||
/*!
|
||||
@brief This function derives the platform key (Kplt) from the Kpicv, and then decrypts the customer key (Kcst)
|
||||
from the EKcst (burned in the OTP). The decryption is done only in Secure and RMA LCS mode using AES-ECB.
|
||||
The customer ROM should invoke this function during early boot, prior to running any non-ROM code, only if Kcst exists.
|
||||
The resulting Kcst is saved in a HW register.
|
||||
|
||||
@return \c CC_OK on success.
|
||||
@return A non-zero value from bsv_error.h on failure.
|
||||
*/
|
||||
CCError_t CC_BsvCustomerKeyDecrypt(
|
||||
unsigned long hwBaseAddress /*!< [in] The base address of the CryptoCell HW registers. */
|
||||
);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/*!
|
||||
@brief This function derives the unique SoC_ID for the device, as hashed (Hbk || AES_CMAC (HUK)).
|
||||
|
||||
@note SoC_ID is required to create debug certificates.
|
||||
|
||||
The OEM or ICV must provide a method for a developer to discover the SoC_ID of a target
|
||||
device without having to first enable debugging.
|
||||
One suggested implementation is to have the device ROM code compute the SoC_ID and place
|
||||
it in a specific location in the flash memory, from where it can be accessed by the developer.
|
||||
|
||||
@return \c CC_OK on success.
|
||||
@return A non-zero value from bsv_error.h on failure.
|
||||
*/
|
||||
CCError_t CC_BsvSocIDCompute(
|
||||
unsigned long hwBaseAddress, /*!< [in] The base address of the CryptoCell HW registers. */
|
||||
CCHashResult_t hashResult /*!< [out] The derived SoC_ID. */
|
||||
);
|
||||
|
||||
#endif /* _BSV_API_H */
|
||||
|
||||
/**
|
||||
@}
|
||||
*/
|
||||
|
||||
+76
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright (c) 2017-2020 ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef _BSV_CRYPTO_API_H
|
||||
#define _BSV_CRYPTO_API_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/*!
|
||||
@file
|
||||
@brief This file contains the cryptographic ROM APIs of the Boot Services.
|
||||
|
||||
@defgroup cc_bsv_crypto_api CryptoCell Boot Services cryptographic ROM APIs
|
||||
@{
|
||||
@ingroup cc_bsv
|
||||
*/
|
||||
|
||||
#include "cc_pal_types.h"
|
||||
#include "cc_sec_defs.h"
|
||||
#include "cc_address_defs.h"
|
||||
#include "bsv_crypto_defs.h"
|
||||
|
||||
/*----------------------------
|
||||
PUBLIC FUNCTIONS
|
||||
-----------------------------------*/
|
||||
|
||||
/*!
|
||||
@brief This function calculates the SHA-256 digest over contiguous memory
|
||||
in an integrated operation.
|
||||
|
||||
@return \c CC_OK on success.
|
||||
@return A non-zero value from bsv_error.h on failure.
|
||||
*/
|
||||
CCError_t CC_BsvSha256(
|
||||
unsigned long hwBaseAddress, /*!< [in] The base address of the CryptoCell HW registers. */
|
||||
uint8_t *pDataIn, /*!< [in] A pointer to the input buffer to be hashed. The buffer must be contiguous. */
|
||||
size_t dataSize, /*!< [in] The size of the data to be hashed, in bytes. */
|
||||
CCHashResult_t hashBuff /*!< [out] A pointer to a word-aligned 32-byte buffer. */
|
||||
);
|
||||
|
||||
|
||||
/*!
|
||||
@brief This function allows you to calculate SHA256 digest of an image with decryption base on AES-CTR,
|
||||
with HW or user key.
|
||||
|
||||
@return \c CC_OK on success.
|
||||
@return A non-zero value from bsv_error.h on failure. (in this case, hashBuff will be returned clean, while the output data should be cleaned by the user).
|
||||
*/
|
||||
CCError_t CC_BsvCryptoImageDecrypt( unsigned long hwBaseAddress, /*!< [in] The base address of the CryptoCell HW registers. */
|
||||
CCBsvflowMode_t flow, /*!< [in] The supported operations are: HASH, AES to HASH, AES and HASH. */
|
||||
CCBsvKeyType_t keyType, /*!< [in] The key type to use: Kce, Kceicv, or user key. */
|
||||
uint8_t *pUserKey, /*!< [in] A pointer to the user key buffer in case keyType is CC_BSV_USER_KEY. */
|
||||
size_t userKeySize, /*!< [in] The user key size in bytes (128bits) in case keyType is CC_BSV_USER_KEY. */
|
||||
uint8_t *pIvBuf, /*!< [in] A pointer to the IV / counter buffer. */
|
||||
uint8_t *pInputData, /*!< [in] A pointer to the input data. */
|
||||
uint8_t *pOutputData, /*!< [out] A pointer to the output buffer. (optional – should be null in case of hash only). */
|
||||
size_t dataSize, /*!< [in] The size of the input data in bytes. MUST be multiple of AES block size. */
|
||||
CCHashResult_t hashBuff /*!< [out] A pointer to a word-aligned 32-byte digest output buffer. */
|
||||
);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
@}
|
||||
*/
|
||||
|
||||
+100
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright (c) 2017-2020 ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef _BSV_CRYPTO_ASYM_API_H
|
||||
#define _BSV_CRYPTO_ASYM_API_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/*!
|
||||
@file
|
||||
@brief This file contains the cryptographic Asymmetric ROM APIs of the Boot Services.
|
||||
|
||||
@defgroup cc_bsv_crypto_asym_api CryptoCell Boot Services cryptographic Asymmetric ROM APIs
|
||||
@{
|
||||
@ingroup cc_bsv
|
||||
*/
|
||||
|
||||
#include "cc_pal_types.h"
|
||||
#include "cc_pka_hw_plat_defs.h"
|
||||
#include "cc_sec_defs.h"
|
||||
#include "bsv_crypto_api.h"
|
||||
|
||||
/*! Defines the workspace size in bytes needed for internal Asymmetric operations. */
|
||||
#define BSV_RSA_WORKSPACE_MIN_SIZE (4*BSV_CERT_RSA_KEY_SIZE_IN_BYTES +\
|
||||
2*RSA_PKA_BARRETT_MOD_TAG_BUFF_SIZE_IN_BYTES)
|
||||
|
||||
/*! Definition for the RSA public modulus array. */
|
||||
typedef uint32_t CCBsvNBuff_t[BSV_CERT_RSA_KEY_SIZE_IN_WORDS];
|
||||
|
||||
/*! Definition for the RSA Barrett mod tag array. */
|
||||
typedef uint32_t CCBsvNpBuff_t[RSA_PKA_BARRETT_MOD_TAG_BUFF_SIZE_IN_BYTES];
|
||||
|
||||
/*! Definition for the RSA signature array. */
|
||||
typedef uint32_t CCBsvSignature_t[BSV_CERT_RSA_KEY_SIZE_IN_WORDS];
|
||||
|
||||
|
||||
/*----------------------------
|
||||
PUBLIC FUNCTIONS
|
||||
-----------------------------------*/
|
||||
|
||||
/*!
|
||||
@brief This function performs the primitive operation of RSA, meaning exponent and modulus.
|
||||
outBuff = (pInBuff ^ Exp) mod NBuff. ( Exp = 0x10001 )
|
||||
|
||||
The function supports 2k and 3K bit size of modulus, based on compile time define.
|
||||
There are no restriction on pInBuff location, however its size must be equal to BSV_RSA_KEY_SIZE_IN_BYTES and its
|
||||
value must be smaller than the modulus.
|
||||
|
||||
|
||||
@return \c CC_OK on success.
|
||||
@return A non-zero value from bsv_error.h on failure.
|
||||
*/
|
||||
CCError_t CC_BsvRsaPrimVerify (unsigned long hwBaseAddress, /*!< [in] The base address of the CryptoCell HW registers. */
|
||||
CCBsvNBuff_t NBuff, /*!< [in] The modulus buffer big endian format. */
|
||||
CCBsvNpBuff_t NpBuff, /*!< [in] The barret tag buffer big endian format - optional. */
|
||||
uint32_t *pInBuff, /*!< [in] The DataIn buffer to be encrypted. */
|
||||
size_t inBuffSize, /*!< [in] The DataIn buffer size in bytes, must be BSV_RSA_KEY_SIZE_IN_BYTES. */
|
||||
CCBsvSignature_t pOutBuff, /*!< [out] The encrypted buffer in big endian format. */
|
||||
uint32_t *pWorkSpace, /*!< [in] The pointer to user allocated buffer for internal use. */
|
||||
size_t workBufferSize /*!< [in] The size in bytes of pWorkSpace, must be at-least BSV_RSA_WORKSPACE_MIN_SIZE. */
|
||||
);
|
||||
|
||||
|
||||
/*!
|
||||
@brief This function performs RSA PSS verify.
|
||||
|
||||
The function should support 2k and 3K bit size of modulus, based on compile time define.
|
||||
|
||||
@return \c CC_OK on success.
|
||||
@return A non-zero value from bsv_error.h on failure.
|
||||
*/
|
||||
CCError_t CC_BsvRsaPssVerify (unsigned long hwBaseAddress, /*!< [in] The base address of the CryptoCell HW registers. */
|
||||
CCBsvNBuff_t NBuff, /*!< [in] The modulus buffer big endian format. */
|
||||
CCBsvNpBuff_t NpBuff, /*!< [in] The barret tag buffer big endian format - optional. */
|
||||
CCBsvSignature_t signature, /*!< [in] The signature buffer to verify - big endian format. */
|
||||
CCHashResult_t hashedData, /*!< [in] The data-in buffer to be verified as sha256 digest. */
|
||||
uint32_t *pWorkSpace, /*!< [in] The pointer to user allocated buffer for internal use. */
|
||||
size_t workBufferSize, /*!< [in] The size in bytes of pWorkSpace, must be at-least BSV_RSA_WORKSPACE_MIN_SIZE. */
|
||||
CCBool_t *pIsVerified /*!< [out] The flag indicates whether the signature is verified or not.
|
||||
If verified value will be CC_TRUE, otherwise CC_FALSE */
|
||||
);
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
@}
|
||||
*/
|
||||
|
||||
+94
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright (c) 2017-2020 ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef _BSV_CRYPTO_DEFS_H
|
||||
#define _BSV_CRYPTO_DEFS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/*!
|
||||
@file
|
||||
@brief This file contains the definitions of the cryptographic ROM APIs.
|
||||
|
||||
@defgroup cc_bsv_crypto_defs CryptoCell Boot Services cryptographic ROM API definitions
|
||||
@{
|
||||
@ingroup cc_bsv
|
||||
*/
|
||||
|
||||
/*! AES supported HW key code table. */
|
||||
typedef enum {
|
||||
|
||||
CC_BSV_USER_KEY = 0, /*!< Definition for a user key. */
|
||||
CC_BSV_HUK_KEY = 1, /*!< Definition for the HW unique key. */
|
||||
CC_BSV_RTL_KEY = 2, /*!< Definition for the RTL key. */
|
||||
CC_BSV_SESSION_KEY = 3, /*!< Definition for the Session key. */
|
||||
CC_BSV_CE_KEY = 4, /*!< Definition for the Kce. */
|
||||
CC_BSV_PLT_KEY = 5, /*!< Definition for the Platform key. */
|
||||
CC_BSV_KCST_KEY = 6, /*!< Definition for Kcst. */
|
||||
CC_BSV_ICV_PROV_KEY = 0xd, /*!< Definition for the Kpicv. */
|
||||
CC_BSV_ICV_CE_KEY = 0xe, /*!< Definition for the Kceicv. */
|
||||
CC_BSV_PROV_KEY = 0xf, /*!< Definition for the Kcp. */
|
||||
CC_BSV_END_OF_KEY_TYPE = INT32_MAX, /*!< Reserved. */
|
||||
}CCBsvKeyType_t;
|
||||
|
||||
/*! AES directions. */
|
||||
typedef enum bsvAesDirection {
|
||||
BSV_AES_DIRECTION_ENCRYPT = 0, /*!< Encrypt.*/
|
||||
BSV_AES_DIRECTION_DECRYPT = 1, /*!< Decrypt.*/
|
||||
BSV_AES_NUM_OF_ENCRYPT_MODES, /*!< The maximal number of operations. */
|
||||
BSV_AES_DIRECTION_RESERVE32B = INT32_MAX /*!< Reserved.*/
|
||||
}bsvAesDirection_t;
|
||||
|
||||
/*! Definitions of the cryptographic flow supported as part of the Secure Boot. */
|
||||
typedef enum {
|
||||
CC_BSV_CRYPTO_HASH_MODE = 0, /*!< Hash mode only. */
|
||||
CC_BSV_CRYPTO_AES_CTR_AND_HASH_MODE = 1, /*!< Data goes into the AES and Hash engines. */
|
||||
CC_BSV_CRYPTO_AES_CTR_TO_HASH_MODE = 2 /*!< Data goes into the AES and from the AES to the Hash engine. */
|
||||
}CCBsvflowMode_t;
|
||||
|
||||
/*! CryptoImage HW completion sequence mode */
|
||||
typedef enum
|
||||
{
|
||||
BSV_CRYPTO_COMPLETION_NO_WAIT = 0, /*!< The driver waits only before reading the output. */
|
||||
BSV_CRYPTO_COMPLETION_WAIT_UPON_END = 1 /*!< The driver waits after each chunk of data. */
|
||||
}bsvCryptoCompletionMode_t;
|
||||
|
||||
|
||||
/*! AES-CMAC result size, in words. */
|
||||
#define CC_BSV_CMAC_RESULT_SIZE_IN_WORDS 4 /* 128b */
|
||||
/*! AES-CMAC result size, in bytes. */
|
||||
#define CC_BSV_CMAC_RESULT_SIZE_IN_BYTES 16 /* 128b */
|
||||
/*! AES-CCM 128bit key size, in bytes. */
|
||||
#define CC_BSV_CCM_KEY_SIZE_BYTES 16
|
||||
/*! AES-CCM 128bit key size, in words. */
|
||||
#define CC_BSV_CCM_KEY_SIZE_WORDS 4
|
||||
/*! AES-CCM NONCE size, in bytes. */
|
||||
#define CC_BSV_CCM_NONCE_SIZE_BYTES 12
|
||||
|
||||
|
||||
/*! AES-CMAC result buffer. */
|
||||
typedef uint32_t CCBsvCmacResult_t[CC_BSV_CMAC_RESULT_SIZE_IN_WORDS];
|
||||
/*! AES-CCM key buffer.*/
|
||||
typedef uint32_t CCBsvCcmKey_t[CC_BSV_CCM_KEY_SIZE_WORDS];
|
||||
/*! AES-CCM nonce buffer.*/
|
||||
typedef uint8_t CCBsvCcmNonce_t[CC_BSV_CCM_NONCE_SIZE_BYTES];
|
||||
/*! AES-CCM MAC buffer.*/
|
||||
typedef uint8_t CCBsvCcmMacRes_t[CC_BSV_CMAC_RESULT_SIZE_IN_BYTES];
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
@}
|
||||
*/
|
||||
|
||||
+161
@@ -0,0 +1,161 @@
|
||||
/*
|
||||
* Copyright (c) 2017-2020 ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef _BSV_ERROR_H
|
||||
#define _BSV_ERROR_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/*!
|
||||
@file
|
||||
@brief This file defines the error code types that are returned from the Boot Services APIs.
|
||||
|
||||
@defgroup cc_bsv_error CryptoCell Boot Services error codes
|
||||
@{
|
||||
@ingroup cc_bsv
|
||||
*/
|
||||
|
||||
/*! Defines the base address for Boot Services errors. */
|
||||
#define CC_BSV_BASE_ERROR 0x0B000000
|
||||
/*! Defines the base address for Boot Services cryptographic errors. */
|
||||
#define CC_BSV_CRYPTO_ERROR 0x0C000000
|
||||
|
||||
/*! Illegal input parameter. */
|
||||
#define CC_BSV_ILLEGAL_INPUT_PARAM_ERR (CC_BSV_BASE_ERROR + 0x00000001)
|
||||
/*! Illegal HUK value. */
|
||||
#define CC_BSV_ILLEGAL_HUK_VALUE_ERR (CC_BSV_BASE_ERROR + 0x00000002)
|
||||
/*! Illegal Kcp value. */
|
||||
#define CC_BSV_ILLEGAL_KCP_VALUE_ERR (CC_BSV_BASE_ERROR + 0x00000003)
|
||||
/*! Illegal Kce value. */
|
||||
#define CC_BSV_ILLEGAL_KCE_VALUE_ERR (CC_BSV_BASE_ERROR + 0x00000004)
|
||||
/*! Illegal Kpicv value. */
|
||||
#define CC_BSV_ILLEGAL_KPICV_VALUE_ERR (CC_BSV_BASE_ERROR + 0x00000005)
|
||||
/*! Illegal Kceicv value. */
|
||||
#define CC_BSV_ILLEGAL_KCEICV_VALUE_ERR (CC_BSV_BASE_ERROR + 0x00000006)
|
||||
/*! Illegal EKcst value. */
|
||||
#define CC_BSV_ILLEGAL_EKCST_VALUE_ERR (CC_BSV_BASE_ERROR + 0x00000007)
|
||||
/*! Hash boot key not programmed in the OTP. */
|
||||
#define CC_BSV_HASH_NOT_PROGRAMMED_ERR (CC_BSV_BASE_ERROR + 0x00000008)
|
||||
/*! Illegal Hash boot key zero count in the OTP. */
|
||||
#define CC_BSV_HBK_ZERO_COUNT_ERR (CC_BSV_BASE_ERROR + 0x00000009)
|
||||
/*! Illegal LCS. */
|
||||
#define CC_BSV_ILLEGAL_LCS_ERR (CC_BSV_BASE_ERROR + 0x0000000A)
|
||||
/*! OTP write compare failure. */
|
||||
#define CC_BSV_OTP_WRITE_CMP_FAIL_ERR (CC_BSV_BASE_ERROR + 0x0000000B)
|
||||
/*! OTP access error */
|
||||
#define CC_BSV_OTP_ACCESS_ERR (CC_BSV_BASE_ERROR + 0x0000000C)
|
||||
/*! Erase key in OTP failed. */
|
||||
#define CC_BSV_ERASE_KEY_FAILED_ERR (CC_BSV_BASE_ERROR + 0x0000000D)
|
||||
/*! Illegal PIDR. */
|
||||
#define CC_BSV_ILLEGAL_PIDR_ERR (CC_BSV_BASE_ERROR + 0x0000000E)
|
||||
/*! Illegal CIDR. */
|
||||
#define CC_BSV_ILLEGAL_CIDR_ERR (CC_BSV_BASE_ERROR + 0x0000000F)
|
||||
/*! Device failed to move to fatal error state. */
|
||||
#define CC_BSV_FAILED_TO_SET_FATAL_ERR (CC_BSV_BASE_ERROR + 0x00000010)
|
||||
/*! Failed to set RMA LCS. */
|
||||
#define CC_BSV_FAILED_TO_SET_RMA_ERR (CC_BSV_BASE_ERROR + 0x00000011)
|
||||
/*! Illegal RMA indication. */
|
||||
#define CC_BSV_ILLEGAL_RMA_INDICATION_ERR (CC_BSV_BASE_ERROR + 0x00000012)
|
||||
/*! Boot Services version is not initialized. */
|
||||
#define CC_BSV_VER_IS_NOT_INITIALIZED_ERR (CC_BSV_BASE_ERROR + 0x00000013)
|
||||
/*! APB secure mode is locked. */
|
||||
#define CC_BSV_APB_SECURE_IS_LOCKED_ERR (CC_BSV_BASE_ERROR + 0x00000014)
|
||||
/*! APB privilege mode is locked. */
|
||||
#define CC_BSV_APB_PRIVILEG_IS_LOCKED_ERR (CC_BSV_BASE_ERROR + 0x00000015)
|
||||
/*! Illegal operation. */
|
||||
#define CC_BSV_ILLEGAL_OPERATION_ERR (CC_BSV_BASE_ERROR + 0x00000016)
|
||||
/*! Illegal asset size. */
|
||||
#define CC_BSV_ILLEGAL_ASSET_SIZE_ERR (CC_BSV_BASE_ERROR + 0x00000017)
|
||||
/*! Illegal asset value. */
|
||||
#define CC_BSV_ILLEGAL_ASSET_VAL_ERR (CC_BSV_BASE_ERROR + 0x00000018)
|
||||
/*! Kpicv is locked. */
|
||||
#define CC_BSV_KPICV_IS_LOCKED_ERR (CC_BSV_BASE_ERROR + 0x00000019)
|
||||
/*! Illegal SW version. */
|
||||
#define CC_BSV_ILLEGAL_SW_VERSION_ERR (CC_BSV_BASE_ERROR + 0x0000001A)
|
||||
/*! AO write operation. */
|
||||
#define CC_BSV_AO_WRITE_FAILED_ERR (CC_BSV_BASE_ERROR + 0x0000001B)
|
||||
/*! Chip state is already initialized. */
|
||||
#define CC_BSV_CHIP_INITIALIZED_ERR (CC_BSV_BASE_ERROR + 0x0000001C)
|
||||
/*! SP is not enabled. */
|
||||
#define CC_BSV_SP_NOT_ENABLED_ERR (CC_BSV_BASE_ERROR + 0x0000001D)
|
||||
/*! Production secure provisioning - header fields. */
|
||||
#define CC_BSV_PROD_PKG_HEADER_ERR (CC_BSV_BASE_ERROR + 0x0000001E)
|
||||
/*! Production secure provisioning - header MAC. */
|
||||
#define CC_BSV_PROD_PKG_HEADER_MAC_ERR (CC_BSV_BASE_ERROR + 0x0000001F)
|
||||
/*! Overrun buffer or size. */
|
||||
#define CC_BSV_OVERRUN_ERR (CC_BSV_BASE_ERROR + 0x00000020)
|
||||
/*! Kceicv is locked. */
|
||||
#define CC_BSV_KCEICV_IS_LOCKED_ERR (CC_BSV_BASE_ERROR + 0x00000021)
|
||||
/*! Chip indication is CHIP_STATE_ERROR. */
|
||||
#define CC_BSV_CHIP_INDICATION_ERR (CC_BSV_BASE_ERROR + 0x00000022)
|
||||
/*! Device is locked in fatal error state. */
|
||||
#define CC_BSV_FATAL_ERR_IS_LOCKED_ERR (CC_BSV_BASE_ERROR + 0x00000023)
|
||||
/*! Device has security disable feature enabled. */
|
||||
#define CC_BSV_SECURE_DISABLE_ERROR (CC_BSV_BASE_ERROR + 0x00000024)
|
||||
/*! Device has Kcst in disabled state */
|
||||
#define CC_BSV_KCST_DISABLE_ERROR (CC_BSV_BASE_ERROR + 0x00000025)
|
||||
|
||||
|
||||
/*! Illegal data-in pointer. */
|
||||
#define CC_BSV_CRYPTO_INVALID_DATA_IN_POINTER_ERROR (CC_BSV_CRYPTO_ERROR + 0x00000001)
|
||||
/*! Illegal data-out pointer. */
|
||||
#define CC_BSV_CRYPTO_INVALID_DATA_OUT_POINTER_ERROR (CC_BSV_CRYPTO_ERROR + 0x00000002)
|
||||
/*! Illegal data size. */
|
||||
#define CC_BSV_CRYPTO_INVALID_DATA_SIZE_ERROR (CC_BSV_CRYPTO_ERROR + 0x00000003)
|
||||
/*! Illegal key type. */
|
||||
#define CC_BSV_CRYPTO_INVALID_KEY_TYPE_ERROR (CC_BSV_CRYPTO_ERROR + 0x00000004)
|
||||
/*! Illegal key size. */
|
||||
#define CC_BSV_CRYPTO_INVALID_KEY_SIZE_ERROR (CC_BSV_CRYPTO_ERROR + 0x00000005)
|
||||
/*! Invalid key pointer. */
|
||||
#define CC_BSV_CRYPTO_INVALID_KEY_POINTER_ERROR (CC_BSV_CRYPTO_ERROR + 0x00000006)
|
||||
/*! Illegal key DMA type. */
|
||||
#define CC_BSV_CRYPTO_INVALID_KEY_DMA_TYPE_ERROR (CC_BSV_CRYPTO_ERROR + 0x00000007)
|
||||
/*! Illegal IV pointer. */
|
||||
#define CC_BSV_CRYPTO_INVALID_IV_POINTER_ERROR (CC_BSV_CRYPTO_ERROR + 0x00000008)
|
||||
/*! Illegal cipher mode. */
|
||||
#define CC_BSV_CRYPTO_INVALID_CIPHER_MODE_ERROR (CC_BSV_CRYPTO_ERROR + 0x00000009)
|
||||
/*! Illegal result buffer pointer. */
|
||||
#define CC_BSV_CRYPTO_INVALID_RESULT_BUFFER_POINTER_ERROR (CC_BSV_CRYPTO_ERROR + 0x0000000A)
|
||||
/*! Invalid DMA type. */
|
||||
#define CC_BSV_CRYPTO_INVALID_DMA_TYPE_ERROR (CC_BSV_CRYPTO_ERROR + 0x0000000B)
|
||||
/*! Invalid in/out buffers overlapping. */
|
||||
#define CC_BSV_CRYPTO_DATA_OUT_DATA_IN_OVERLAP_ERROR (CC_BSV_CRYPTO_ERROR + 0x0000000C)
|
||||
/*! Invalid KDF label size. */
|
||||
#define CC_BSV_CRYPTO_ILLEGAL_KDF_LABEL_ERROR (CC_BSV_CRYPTO_ERROR + 0x0000000D)
|
||||
/*! Invalid KDF Context size. */
|
||||
#define CC_BSV_CRYPTO_ILLEGAL_KDF_CONTEXT_ERROR (CC_BSV_CRYPTO_ERROR + 0x0000000E)
|
||||
/*! Invalid CCM key. */
|
||||
#define CC_BSV_CCM_INVALID_KEY_ERROR (CC_BSV_CRYPTO_ERROR + 0x0000000f)
|
||||
/*! Invalid CCM Nonce. */
|
||||
#define CC_BSV_CCM_INVALID_NONCE_ERROR (CC_BSV_CRYPTO_ERROR + 0x00000010)
|
||||
/*! Invalid CCM associated data. */
|
||||
#define CC_BSV_CCM_INVALID_ASSOC_DATA_ERROR (CC_BSV_CRYPTO_ERROR + 0x00000011)
|
||||
/*! Invalid CCM text data. */
|
||||
#define CC_BSV_CCM_INVALID_TEXT_DATA_ERROR (CC_BSV_CRYPTO_ERROR + 0x00000012)
|
||||
/*! Invalid CCM-MAC buffer. */
|
||||
#define CC_BSV_CCM_INVALID_MAC_BUF_ERROR (CC_BSV_CRYPTO_ERROR + 0x00000013)
|
||||
/*! CCM-MAC comparison failed. */
|
||||
#define CC_BSV_CCM_TAG_LENGTH_ERROR (CC_BSV_CRYPTO_ERROR + 0x00000014)
|
||||
/*! CCM-MAC comparison failed. */
|
||||
#define CC_BSV_CCM_MAC_INVALID_ERROR (CC_BSV_CRYPTO_ERROR + 0x00000015)
|
||||
/*! Illegal flow mode. */
|
||||
#define CC_BSV_CRYPTO_INVALID_FLOW_MODE_ERROR (CC_BSV_CRYPTO_ERROR + 0x00000016)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
@}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (c) 2017-2020 ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef _CC_ADDRESS_DEFS_H
|
||||
#define _CC_ADDRESS_DEFS_H
|
||||
|
||||
/*!
|
||||
@file
|
||||
@brief This file contains general definitions.
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include "cc_pal_types.h"
|
||||
|
||||
/************************ Defines ******************************/
|
||||
|
||||
/**
|
||||
* Address types within CC
|
||||
*/
|
||||
/*! Definition of DMA address type, can be 32 bits or 64 bits according to CryptoCell's HW. */
|
||||
typedef uint64_t CCDmaAddr_t;
|
||||
/*! Definition of CryptoCell address type, can be 32 bits or 64 bits according to platform. */
|
||||
typedef uint64_t CCAddr_t;
|
||||
/*! Definition of CC SRAM address type, can be 32 bits according to CryptoCell's HW. */
|
||||
typedef uint32_t CCSramAddr_t;
|
||||
|
||||
/*
|
||||
* CCSramAddr_t is being cast into pointer type which can be 64 bit.
|
||||
*/
|
||||
/*! Definition of MACRO that casts SRAM addresses to pointer types. */
|
||||
#define CCSramAddr2Ptr(sramAddr) ((uintptr_t)sramAddr)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
@}
|
||||
*/
|
||||
|
||||
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (c) 2017-2020 ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef _CC_BOOT_DEFS_H
|
||||
#define _CC_BOOT_DEFS_H
|
||||
|
||||
/*!
|
||||
@file
|
||||
@brief This file contains general definitions of types and enums of Boot APIs.
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/*! Version counters value. */
|
||||
typedef enum {
|
||||
|
||||
CC_SW_VERSION_TRUSTED = 0, /*!< Trusted counter. */
|
||||
CC_SW_VERSION_NON_TRUSTED, /*!< Non trusted counter. */
|
||||
CC_SW_VERSION_MAX = 0x7FFFFFFF /*!< Reserved */
|
||||
} CCSbSwVersionId_t;
|
||||
|
||||
/*! The hash boot key definition. */
|
||||
typedef enum {
|
||||
CC_SB_HASH_BOOT_KEY_0_128B = 0, /*!< Hbk0: 128-bit truncated SHA-256 digest of PubKB0. Used by ICV */
|
||||
CC_SB_HASH_BOOT_KEY_1_128B = 1, /*!< Hbk1: 128-bit truncated SHA-256 digest of PubKB1. Used by OEM */
|
||||
CC_SB_HASH_BOOT_KEY_256B = 2, /*!< Hbk: 256-bit SHA-256 digest of public key. */
|
||||
CC_SB_HASH_BOOT_NOT_USED = 0xF, /*!< Hbk is not used. */
|
||||
CC_SB_HASH_MAX_NUM = 0x7FFFFFFF, /*!< Reserved. */
|
||||
} CCSbPubKeyIndexType_t;
|
||||
|
||||
/*! Chip state. */
|
||||
typedef enum {
|
||||
CHIP_STATE_NOT_INITIALIZED = 0, /*! Chip is not initialized. */
|
||||
CHIP_STATE_TEST = 1, /*! Chip is in Production state. */
|
||||
CHIP_STATE_PRODUCTION = 2, /*! Chip is in Production state. */
|
||||
CHIP_STATE_ERROR = 3, /*! Chip is in Error state. */
|
||||
} CCBsvChipState_t;
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*_CC_BOOT_DEFS_H */
|
||||
|
||||
/**
|
||||
@}
|
||||
*/
|
||||
+100
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright (c) 2017-2020 ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef CC_PAL_TYPES_H
|
||||
#define CC_PAL_TYPES_H
|
||||
|
||||
/*!
|
||||
@file
|
||||
@brief This file contains platform-dependent definitions and types of the PAL layer.
|
||||
|
||||
@defgroup cc_pal_types CryptoCell platform-dependent PAL layer definitions and types
|
||||
@{
|
||||
@ingroup cc_pal
|
||||
|
||||
@{
|
||||
@ingroup cc_pal
|
||||
@}
|
||||
*/
|
||||
|
||||
#include "cc_pal_types_plat.h"
|
||||
|
||||
/*! Definition of Boolean type.*/
|
||||
typedef enum {
|
||||
/*! Boolean false.*/
|
||||
CC_FALSE = 0,
|
||||
/*! Boolean true.*/
|
||||
CC_TRUE = 1
|
||||
} CCBool_t;
|
||||
|
||||
/*! Success. */
|
||||
#define CC_SUCCESS 0UL
|
||||
/*! Failure. */
|
||||
#define CC_FAIL 1UL
|
||||
|
||||
/*! Success (OK). */
|
||||
#define CC_OK 0
|
||||
|
||||
/*! This macro handles unused parameters in the code, to avoid compilation warnings. */
|
||||
#define CC_UNUSED_PARAM(prm) ((void)prm)
|
||||
|
||||
/*! The maximal uint32 value.*/
|
||||
#define CC_MAX_UINT32_VAL (0xFFFFFFFF)
|
||||
|
||||
|
||||
/* Minimal and Maximal macros */
|
||||
#ifdef min
|
||||
/*! Definition for minimal calculation. */
|
||||
#define CC_MIN(a,b) min( a , b )
|
||||
#else
|
||||
/*! Definition for minimal calculation. */
|
||||
#define CC_MIN( a , b ) ( ( (a) < (b) ) ? (a) : (b) )
|
||||
#endif
|
||||
|
||||
#ifdef max
|
||||
/*! Definition for maximal calculation. */
|
||||
#define CC_MAX(a,b) max( a , b )
|
||||
#else
|
||||
/*! Definition for maximal calculation.. */
|
||||
#define CC_MAX( a , b ) ( ( (a) > (b) ) ? (a) : (b) )
|
||||
#endif
|
||||
|
||||
/*! This macro calculates the number of full Bytes from bits, where seven bits are one Byte. */
|
||||
#define CALC_FULL_BYTES(numBits) ((numBits)/CC_BITS_IN_BYTE + (((numBits) & (CC_BITS_IN_BYTE-1)) > 0))
|
||||
/*! This macro calculates the number of full 32-bit words from bits where 31 bits are one word. */
|
||||
#define CALC_FULL_32BIT_WORDS(numBits) ((numBits)/CC_BITS_IN_32BIT_WORD + (((numBits) & (CC_BITS_IN_32BIT_WORD-1)) > 0))
|
||||
/*! This macro calculates the number of full 32-bit words from Bytes where three Bytes are one word. */
|
||||
#define CALC_32BIT_WORDS_FROM_BYTES(sizeBytes) ((sizeBytes)/CC_32BIT_WORD_SIZE + (((sizeBytes) & (CC_32BIT_WORD_SIZE-1)) > 0))
|
||||
/*! This macro calculates the number of full 32-bit words from 64-bits dwords. */
|
||||
#define CALC_32BIT_WORDS_FROM_64BIT_DWORD(sizeWords) (sizeWords * CC_32BIT_WORD_IN_64BIT_DWORD)
|
||||
/*! This macro rounds up bits to 32-bit words. */
|
||||
#define ROUNDUP_BITS_TO_32BIT_WORD(numBits) (CALC_FULL_32BIT_WORDS(numBits) * CC_BITS_IN_32BIT_WORD)
|
||||
/*! This macro rounds up bits to Bytes. */
|
||||
#define ROUNDUP_BITS_TO_BYTES(numBits) (CALC_FULL_BYTES(numBits) * CC_BITS_IN_BYTE)
|
||||
/*! This macro rounds up bytes to 32-bit words. */
|
||||
#define ROUNDUP_BYTES_TO_32BIT_WORD(sizeBytes) (CALC_32BIT_WORDS_FROM_BYTES(sizeBytes) * CC_32BIT_WORD_SIZE)
|
||||
/*! This macro calculates the number Bytes from words. */
|
||||
#define CALC_WORDS_TO_BYTES(numwords) ((numwords)*CC_32BIT_WORD_SIZE)
|
||||
/*! Definition of 1 KB in Bytes. */
|
||||
#define CC_1K_SIZE_IN_BYTES 1024
|
||||
/*! Definition of number of bits in a Byte. */
|
||||
#define CC_BITS_IN_BYTE 8
|
||||
/*! Definition of number of bits in a 32-bits word. */
|
||||
#define CC_BITS_IN_32BIT_WORD 32
|
||||
/*! Definition of number of Bytes in a 32-bits word. */
|
||||
#define CC_32BIT_WORD_SIZE 4
|
||||
/*! Definition of number of 32-bits words in a 64-bits dword. */
|
||||
#define CC_32BIT_WORD_IN_64BIT_DWORD 2
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
@}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*! @file
|
||||
@brief This file contains basic type definitions that are platform-dependent.
|
||||
*/
|
||||
#ifndef _CC_PAL_TYPES_PLAT_H
|
||||
#define _CC_PAL_TYPES_PLAT_H
|
||||
/* Host specific types for standard (ISO-C99) compilant platforms */
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
typedef uint32_t CCStatus;
|
||||
|
||||
#define CCError_t CCStatus
|
||||
#define CC_INFINITE 0xFFFFFFFF
|
||||
|
||||
#define CEXPORT_C
|
||||
#define CIMPORT_C
|
||||
|
||||
#endif /*_CC_PAL_TYPES_PLAT_H*/
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (c) 2017-2020 ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef _CC_PKA_HW_PLAT_DEFS_H
|
||||
#define _CC_PKA_HW_PLAT_DEFS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
|
||||
#include "cc_pal_types.h"
|
||||
/*!
|
||||
@file
|
||||
@brief Contains the enums and definitions that are used in the PKA code (definitions that are platform dependent).
|
||||
*/
|
||||
|
||||
/*! The size of the PKA engine word. */
|
||||
#define CC_PKA_WORD_SIZE_IN_BITS 128
|
||||
|
||||
/*! The maximal supported size of modulus in RSA in bits. */
|
||||
#define CC_RSA_MAX_VALID_KEY_SIZE_VALUE_IN_BITS 4096
|
||||
/*! The maximal supported size of key-generation in RSA in bits. */
|
||||
#define CC_RSA_MAX_KEY_GENERATION_HW_SIZE_BITS 4096
|
||||
|
||||
/*! Secure boot/debug certificate RSA public modulus key size in bits. */
|
||||
#if (KEY_SIZE == 3072)
|
||||
#define BSV_CERT_RSA_KEY_SIZE_IN_BITS 3072
|
||||
#else
|
||||
#define BSV_CERT_RSA_KEY_SIZE_IN_BITS 2048
|
||||
#endif
|
||||
/*! Secure boot/debug certificate RSA public modulus key size in bytes. */
|
||||
#define BSV_CERT_RSA_KEY_SIZE_IN_BYTES (BSV_CERT_RSA_KEY_SIZE_IN_BITS/CC_BITS_IN_BYTE)
|
||||
/*! Secure boot/debug certificate RSA public modulus key size in words. */
|
||||
#define BSV_CERT_RSA_KEY_SIZE_IN_WORDS (BSV_CERT_RSA_KEY_SIZE_IN_BITS/CC_BITS_IN_32BIT_WORD)
|
||||
|
||||
/*! The maximal count of extra bits in PKA operations. */
|
||||
#define PKA_EXTRA_BITS 8
|
||||
/*! The number of memory registers in PKA operations. */
|
||||
#define PKA_MAX_COUNT_OF_PHYS_MEM_REGS 32
|
||||
|
||||
/*! Size of buffer for Barrett modulus tag in words. */
|
||||
#define RSA_PKA_BARRETT_MOD_TAG_BUFF_SIZE_IN_WORDS 5
|
||||
/*! Size of buffer for Barrett modulus tag in bytes. */
|
||||
#define RSA_PKA_BARRETT_MOD_TAG_BUFF_SIZE_IN_BYTES (RSA_PKA_BARRETT_MOD_TAG_BUFF_SIZE_IN_WORDS*CC_32BIT_WORD_SIZE)
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //_CC_PKA_HW_PLAT_DEFS_H
|
||||
|
||||
/**
|
||||
@}
|
||||
*/
|
||||
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (c) 2017-2020 ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef _CC_SEC_DEFS_H
|
||||
#define _CC_SEC_DEFS_H
|
||||
|
||||
/*!
|
||||
@file
|
||||
@brief This file contains general definitions and types.
|
||||
*/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include "cc_pal_types.h"
|
||||
|
||||
/*! Hashblock size in words. */
|
||||
#define HASH_BLOCK_SIZE_IN_WORDS 16
|
||||
/*! Hash - SHA2 results in words. */
|
||||
#define HASH_RESULT_SIZE_IN_WORDS 8
|
||||
/*! Hash - SHA2 results in bytes. */
|
||||
#define HASH_RESULT_SIZE_IN_BYTES 32
|
||||
|
||||
/*! Definition for hash result array. */
|
||||
typedef uint32_t CCHashResult_t[HASH_RESULT_SIZE_IN_WORDS];
|
||||
|
||||
/*! Definition for converting pointer to Host address. */
|
||||
#define CONVERT_TO_ADDR(ptr) (unsigned long)ptr
|
||||
|
||||
/*! Definition for converting pointer to SRAM address. */
|
||||
#define CONVERT_TO_SRAM_ADDR(ptr) (0xFFFFFFFF & ptr)
|
||||
|
||||
/*! The data size of the signed SW image, in bytes. */
|
||||
/*!\internal ContentCertImageRecord_t includes: HS(8W) + 64-b dstAddr(2W) + imgSize(1W) + isCodeEncUsed(1W) */
|
||||
#define SW_REC_SIGNED_DATA_SIZE_IN_BYTES 48
|
||||
|
||||
/*! The data size of the unsigned SW image, in bytes. */
|
||||
/*!\internal CCSbSwImgAddData_t includes: 64-b srcAddr(2W)*/
|
||||
#define SW_REC_NONE_SIGNED_DATA_SIZE_IN_BYTES 8
|
||||
|
||||
/*! The additional data size - storage address and length of the unsigned SW image, in words. */
|
||||
#define SW_REC_NONE_SIGNED_DATA_SIZE_IN_WORDS SW_REC_NONE_SIGNED_DATA_SIZE_IN_BYTES/CC_32BIT_WORD_SIZE
|
||||
|
||||
/*! The additional data section size, in bytes. */
|
||||
#define CC_SB_MAX_SIZE_ADDITIONAL_DATA_BYTES 128
|
||||
|
||||
/*! Indication of whether or not to load the SW image to memory. */
|
||||
#define CC_SW_COMP_NO_MEM_LOAD_INDICATION 0xFFFFFFFFFFFFFFFFUL
|
||||
|
||||
/*! Indication of product version, stored in certificate version field. */
|
||||
#define CC_SB_CERT_VERSION_PROJ_PRD 0x713
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
@}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
/*
|
||||
* Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef _CC_ROTPK_H
|
||||
#define _CC_ROTPK_H
|
||||
|
||||
int cc_get_rotpk_hash(unsigned char *dst, unsigned int len,
|
||||
unsigned int *flags);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef CSS_MHU_H
|
||||
#define CSS_MHU_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
void mhu_secure_message_start(unsigned int slot_id);
|
||||
void mhu_secure_message_send(unsigned int slot_id);
|
||||
uint32_t mhu_secure_message_wait(void);
|
||||
void mhu_secure_message_end(unsigned int slot_id);
|
||||
|
||||
void mhu_secure_init(void);
|
||||
|
||||
#endif /* CSS_MHU_H */
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef CSS_MHU_DOORBELL_H
|
||||
#define CSS_MHU_DOORBELL_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <lib/mmio.h>
|
||||
|
||||
/* MHUv2 Frame Base Mask */
|
||||
#define MHU_V2_FRAME_BASE_MASK UL(~0xFFF)
|
||||
|
||||
/* MHUv2 Control Registers Offsets */
|
||||
#define MHU_V2_MSG_NO_CAP_OFFSET UL(0xF80)
|
||||
#define MHU_V2_ACCESS_REQ_OFFSET UL(0xF88)
|
||||
#define MHU_V2_ACCESS_READY_OFFSET UL(0xF8C)
|
||||
|
||||
#define SENDER_REG_STAT(_channel) (0x20 * (_channel))
|
||||
#define SENDER_REG_SET(_channel) ((0x20 * (_channel)) + 0xC)
|
||||
|
||||
/* Helper macro to ring doorbell */
|
||||
#define MHU_RING_DOORBELL(addr, modify_mask, preserve_mask) do { \
|
||||
uint32_t db = mmio_read_32(addr) & (preserve_mask); \
|
||||
mmio_write_32(addr, db | (modify_mask)); \
|
||||
} while (0)
|
||||
|
||||
#define MHU_V2_ACCESS_REQUEST(addr) \
|
||||
mmio_write_32((addr) + MHU_V2_ACCESS_REQ_OFFSET, 0x1)
|
||||
|
||||
#define MHU_V2_CLEAR_REQUEST(addr) \
|
||||
mmio_write_32((addr) + MHU_V2_ACCESS_REQ_OFFSET, 0x0)
|
||||
|
||||
#define MHU_V2_IS_ACCESS_READY(addr) \
|
||||
(mmio_read_32((addr) + MHU_V2_ACCESS_READY_OFFSET) & 0x1)
|
||||
|
||||
struct scmi_channel_plat_info;
|
||||
void mhu_ring_doorbell(struct scmi_channel_plat_info *plat_info);
|
||||
void mhuv2_ring_doorbell(struct scmi_channel_plat_info *plat_info);
|
||||
|
||||
#endif /* CSS_MHU_DOORBELL_H */
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef CSS_SCP_H
|
||||
#define CSS_SCP_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <platform_def.h>
|
||||
|
||||
#include <lib/cassert.h>
|
||||
|
||||
/* Forward declarations */
|
||||
struct psci_power_state;
|
||||
|
||||
/* API for power management by SCP */
|
||||
int css_system_reset2(int is_vendor, int reset_type, u_register_t cookie);
|
||||
void css_scp_suspend(const struct psci_power_state *target_state);
|
||||
void css_scp_off(const struct psci_power_state *target_state);
|
||||
void css_scp_on(u_register_t mpidr);
|
||||
int css_scp_get_power_state(u_register_t mpidr, unsigned int power_level);
|
||||
void __dead2 css_scp_sys_shutdown(void);
|
||||
void __dead2 css_scp_sys_reboot(void);
|
||||
void __dead2 css_scp_system_off(int state);
|
||||
|
||||
/* API for SCP Boot Image transfer. Return 0 on success, -1 on error */
|
||||
int css_scp_boot_image_xfer(void *image, unsigned int image_size);
|
||||
|
||||
/*
|
||||
* API to wait for SCP to signal till it's ready after booting the transferred
|
||||
* image.
|
||||
*/
|
||||
int css_scp_boot_ready(void);
|
||||
|
||||
#if CSS_LOAD_SCP_IMAGES
|
||||
|
||||
/*
|
||||
* All CSS platforms load SCP_BL2/SCP_BL2U just below BL2 (this is where BL31
|
||||
* usually resides except when ARM_BL31_IN_DRAM is
|
||||
* set). Ensure that SCP_BL2/SCP_BL2U do not overflow into fw_config.
|
||||
*/
|
||||
CASSERT(SCP_BL2_LIMIT <= BL2_BASE, assert_scp_bl2_overwrite_bl2);
|
||||
CASSERT(SCP_BL2U_LIMIT <= BL2_BASE, assert_scp_bl2u_overwrite_bl2);
|
||||
|
||||
CASSERT(SCP_BL2_BASE >= ARM_FW_CONFIG_LIMIT, assert_scp_bl2_overflow);
|
||||
CASSERT(SCP_BL2U_BASE >= ARM_FW_CONFIG_LIMIT, assert_scp_bl2u_overflow);
|
||||
#endif
|
||||
|
||||
#endif /* CSS_SCP_H */
|
||||
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2017, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef CSS_SCPI_H
|
||||
#define CSS_SCPI_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/*
|
||||
* An SCPI command consists of a header and a payload.
|
||||
* The following structure describes the header. It is 64-bit long.
|
||||
*/
|
||||
typedef struct {
|
||||
/* Command ID */
|
||||
uint32_t id : 7;
|
||||
/* Set ID. Identifies whether this is a standard or extended command. */
|
||||
uint32_t set : 1;
|
||||
/* Sender ID to match a reply. The value is sender specific. */
|
||||
uint32_t sender : 8;
|
||||
/* Size of the payload in bytes (0 - 511) */
|
||||
uint32_t size : 9;
|
||||
uint32_t reserved : 7;
|
||||
/*
|
||||
* Status indicating the success of a command.
|
||||
* See the enum below.
|
||||
*/
|
||||
uint32_t status;
|
||||
} scpi_cmd_t;
|
||||
|
||||
typedef enum {
|
||||
SCPI_SET_NORMAL = 0, /* Normal SCPI commands */
|
||||
SCPI_SET_EXTENDED /* Extended SCPI commands */
|
||||
} scpi_set_t;
|
||||
|
||||
enum {
|
||||
SCP_OK = 0, /* Success */
|
||||
SCP_E_PARAM, /* Invalid parameter(s) */
|
||||
SCP_E_ALIGN, /* Invalid alignment */
|
||||
SCP_E_SIZE, /* Invalid size */
|
||||
SCP_E_HANDLER, /* Invalid handler or callback */
|
||||
SCP_E_ACCESS, /* Invalid access or permission denied */
|
||||
SCP_E_RANGE, /* Value out of range */
|
||||
SCP_E_TIMEOUT, /* Time out has ocurred */
|
||||
SCP_E_NOMEM, /* Invalid memory area or pointer */
|
||||
SCP_E_PWRSTATE, /* Invalid power state */
|
||||
SCP_E_SUPPORT, /* Feature not supported or disabled */
|
||||
SCPI_E_DEVICE, /* Device error */
|
||||
SCPI_E_BUSY, /* Device is busy */
|
||||
};
|
||||
|
||||
typedef uint32_t scpi_status_t;
|
||||
|
||||
typedef enum {
|
||||
SCPI_CMD_SCP_READY = 0x01,
|
||||
SCPI_CMD_SET_CSS_POWER_STATE = 0x03,
|
||||
SCPI_CMD_GET_CSS_POWER_STATE = 0x04,
|
||||
SCPI_CMD_SYS_POWER_STATE = 0x05
|
||||
} scpi_command_t;
|
||||
|
||||
/*
|
||||
* Macros to parse SCP response to GET_CSS_POWER_STATE command
|
||||
*
|
||||
* [3:0] : cluster ID
|
||||
* [7:4] : cluster state: 0 = on; 3 = off; rest are reserved
|
||||
* [15:8]: on/off state for individual CPUs in the cluster
|
||||
*
|
||||
* Payload is in little-endian
|
||||
*/
|
||||
#define CLUSTER_ID(_resp) ((_resp) & 0xf)
|
||||
#define CLUSTER_POWER_STATE(_resp) (((_resp) >> 4) & 0xf)
|
||||
|
||||
/* Result is a bit mask of CPU on/off states in the cluster */
|
||||
#define CPU_POWER_STATE(_resp) (((_resp) >> 8) & 0xff)
|
||||
|
||||
/*
|
||||
* For GET_CSS_POWER_STATE, SCP returns the power states of every cluster. The
|
||||
* size of response depends on the number of clusters in the system. The
|
||||
* SCP-to-AP payload contains 2 bytes per cluster. Make sure the response is
|
||||
* large enough to contain power states of a given cluster
|
||||
*/
|
||||
#define CHECK_RESPONSE(_resp, _clus) \
|
||||
(_resp.size >= (((_clus) + 1) * 2))
|
||||
|
||||
typedef enum {
|
||||
scpi_power_on = 0,
|
||||
scpi_power_retention = 1,
|
||||
scpi_power_off = 3,
|
||||
} scpi_power_state_t;
|
||||
|
||||
typedef enum {
|
||||
scpi_system_shutdown = 0,
|
||||
scpi_system_reboot = 1,
|
||||
scpi_system_reset = 2
|
||||
} scpi_system_state_t;
|
||||
|
||||
int scpi_wait_ready(void);
|
||||
void scpi_set_css_power_state(unsigned int mpidr,
|
||||
scpi_power_state_t cpu_state,
|
||||
scpi_power_state_t cluster_state,
|
||||
scpi_power_state_t css_state);
|
||||
int scpi_get_css_power_state(unsigned int mpidr, unsigned int *cpu_state_p,
|
||||
unsigned int *cluster_state_p);
|
||||
uint32_t scpi_sys_power_state(scpi_system_state_t system_state);
|
||||
|
||||
#endif /* CSS_SCPI_H */
|
||||
@@ -0,0 +1,176 @@
|
||||
/*
|
||||
* Copyright (c) 2017-2021, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef SCMI_H
|
||||
#define SCMI_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <lib/bakery_lock.h>
|
||||
#include <lib/psci/psci.h>
|
||||
#include <lib/spinlock.h>
|
||||
|
||||
/* Supported SCMI Protocol Versions */
|
||||
#define SCMI_AP_CORE_PROTO_VER MAKE_SCMI_VERSION(1, 0)
|
||||
#define SCMI_PWR_DMN_PROTO_VER MAKE_SCMI_VERSION(2, 0)
|
||||
#define SCMI_SYS_PWR_PROTO_VER MAKE_SCMI_VERSION(1, 0)
|
||||
|
||||
#define GET_SCMI_MAJOR_VER(ver) (((ver) >> 16) & 0xffff)
|
||||
#define GET_SCMI_MINOR_VER(ver) ((ver) & 0xffff)
|
||||
|
||||
#define MAKE_SCMI_VERSION(maj, min) \
|
||||
((((maj) & 0xffff) << 16) | ((min) & 0xffff))
|
||||
|
||||
/*
|
||||
* Check that the driver's version is same or higher than the reported SCMI
|
||||
* version. We accept lower major version numbers, as all affected protocols
|
||||
* so far stay backwards compatible. This might need to be revisited in the
|
||||
* future.
|
||||
*/
|
||||
#define is_scmi_version_compatible(drv, scmi) \
|
||||
((GET_SCMI_MAJOR_VER(drv) > GET_SCMI_MAJOR_VER(scmi)) || \
|
||||
((GET_SCMI_MAJOR_VER(drv) == GET_SCMI_MAJOR_VER(scmi)) && \
|
||||
(GET_SCMI_MINOR_VER(drv) <= GET_SCMI_MINOR_VER(scmi))))
|
||||
|
||||
/* SCMI Protocol identifiers */
|
||||
#define SCMI_PWR_DMN_PROTO_ID 0x11
|
||||
#define SCMI_SYS_PWR_PROTO_ID 0x12
|
||||
/* The AP core protocol is a CSS platform-specific extension */
|
||||
#define SCMI_AP_CORE_PROTO_ID 0x90
|
||||
|
||||
/* Mandatory messages IDs for all SCMI protocols */
|
||||
#define SCMI_PROTO_VERSION_MSG 0x0
|
||||
#define SCMI_PROTO_ATTR_MSG 0x1
|
||||
#define SCMI_PROTO_MSG_ATTR_MSG 0x2
|
||||
|
||||
/* SCMI power domain management protocol message IDs */
|
||||
#define SCMI_PWR_STATE_SET_MSG 0x4
|
||||
#define SCMI_PWR_STATE_GET_MSG 0x5
|
||||
|
||||
/* SCMI system power management protocol message IDs */
|
||||
#define SCMI_SYS_PWR_STATE_SET_MSG 0x3
|
||||
#define SCMI_SYS_PWR_STATE_GET_MSG 0x4
|
||||
|
||||
/* SCMI AP core protocol message IDs */
|
||||
#define SCMI_AP_CORE_RESET_ADDR_SET_MSG 0x3
|
||||
#define SCMI_AP_CORE_RESET_ADDR_GET_MSG 0x4
|
||||
|
||||
/* Helper macros for system power management protocol commands */
|
||||
|
||||
/*
|
||||
* Macros to describe the bit-fields of the `attribute` of system power domain
|
||||
* protocol PROTOCOL_MSG_ATTRIBUTE message.
|
||||
*/
|
||||
#define SYS_PWR_ATTR_WARM_RESET_SHIFT 31
|
||||
#define SCMI_SYS_PWR_WARM_RESET_SUPPORTED (1U << SYS_PWR_ATTR_WARM_RESET_SHIFT)
|
||||
|
||||
#define SYS_PWR_ATTR_SUSPEND_SHIFT 30
|
||||
#define SCMI_SYS_PWR_SUSPEND_SUPPORTED (1 << SYS_PWR_ATTR_SUSPEND_SHIFT)
|
||||
|
||||
/*
|
||||
* Macros to describe the bit-fields of the `flags` parameter of system power
|
||||
* domain protocol SYSTEM_POWER_STATE_SET message.
|
||||
*/
|
||||
#define SYS_PWR_SET_GRACEFUL_REQ_SHIFT 0
|
||||
#define SCMI_SYS_PWR_GRACEFUL_REQ (1 << SYS_PWR_SET_GRACEFUL_REQ_SHIFT)
|
||||
#define SCMI_SYS_PWR_FORCEFUL_REQ (0 << SYS_PWR_SET_GRACEFUL_REQ_SHIFT)
|
||||
|
||||
/*
|
||||
* Macros to describe the `system_state` parameter of system power
|
||||
* domain protocol SYSTEM_POWER_STATE_SET message.
|
||||
*/
|
||||
#define SCMI_SYS_PWR_SHUTDOWN 0x0
|
||||
#define SCMI_SYS_PWR_COLD_RESET 0x1
|
||||
#define SCMI_SYS_PWR_WARM_RESET 0x2
|
||||
#define SCMI_SYS_PWR_POWER_UP 0x3
|
||||
#define SCMI_SYS_PWR_SUSPEND 0x4
|
||||
|
||||
/*
|
||||
* Macros to describe the bit-fields of the `attribute` of AP core protocol
|
||||
* AP_CORE_RESET_ADDR set/get messages.
|
||||
*/
|
||||
#define SCMI_AP_CORE_LOCK_ATTR_SHIFT 0x0
|
||||
#define SCMI_AP_CORE_LOCK_ATTR (1U << SCMI_AP_CORE_LOCK_ATTR_SHIFT)
|
||||
|
||||
/* SCMI Error code definitions */
|
||||
#define SCMI_E_QUEUED 1
|
||||
#define SCMI_E_SUCCESS 0
|
||||
#define SCMI_E_NOT_SUPPORTED -1
|
||||
#define SCMI_E_INVALID_PARAM -2
|
||||
#define SCMI_E_DENIED -3
|
||||
#define SCMI_E_NOT_FOUND -4
|
||||
#define SCMI_E_OUT_OF_RANGE -5
|
||||
#define SCMI_E_BUSY -6
|
||||
|
||||
/*
|
||||
* SCMI driver platform information. The details of the doorbell mechanism
|
||||
* can be found in the SCMI specification.
|
||||
*/
|
||||
typedef struct scmi_channel_plat_info {
|
||||
/* SCMI mailbox memory */
|
||||
uintptr_t scmi_mbx_mem;
|
||||
/* The door bell register address */
|
||||
uintptr_t db_reg_addr;
|
||||
/* The bit mask that need to be preserved when ringing doorbell */
|
||||
uint32_t db_preserve_mask;
|
||||
/* The bit mask that need to be set to ring doorbell */
|
||||
uint32_t db_modify_mask;
|
||||
/* The handler for ringing doorbell */
|
||||
void (*ring_doorbell)(struct scmi_channel_plat_info *plat_info);
|
||||
/* cookie is unused now. But added for future enhancements. */
|
||||
void *cookie;
|
||||
} scmi_channel_plat_info_t;
|
||||
|
||||
|
||||
#if HW_ASSISTED_COHERENCY
|
||||
typedef spinlock_t scmi_lock_t;
|
||||
#else
|
||||
typedef bakery_lock_t scmi_lock_t;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Structure to represent an SCMI channel.
|
||||
*/
|
||||
typedef struct scmi_channel {
|
||||
scmi_channel_plat_info_t *info;
|
||||
/* The lock for channel access */
|
||||
scmi_lock_t *lock;
|
||||
/* Indicate whether the channel is initialized */
|
||||
int is_initialized;
|
||||
} scmi_channel_t;
|
||||
|
||||
/* External Common API */
|
||||
void *scmi_init(scmi_channel_t *ch);
|
||||
int scmi_proto_msg_attr(void *p, uint32_t proto_id, uint32_t command_id,
|
||||
uint32_t *attr);
|
||||
int scmi_proto_version(void *p, uint32_t proto_id, uint32_t *version);
|
||||
|
||||
/*
|
||||
* Power domain protocol commands. Refer to the SCMI specification for more
|
||||
* details on these commands.
|
||||
*/
|
||||
int scmi_pwr_state_set(void *p, uint32_t domain_id, uint32_t scmi_pwr_state);
|
||||
int scmi_pwr_state_get(void *p, uint32_t domain_id, uint32_t *scmi_pwr_state);
|
||||
|
||||
/*
|
||||
* System power management protocol commands. Refer SCMI specification for more
|
||||
* details on these commands.
|
||||
*/
|
||||
int scmi_sys_pwr_state_set(void *p, uint32_t flags, uint32_t system_state);
|
||||
int scmi_sys_pwr_state_get(void *p, uint32_t *system_state);
|
||||
|
||||
/* SCMI AP core configuration protocol commands. */
|
||||
int scmi_ap_core_set_reset_addr(void *p, uint64_t reset_addr, uint32_t attr);
|
||||
int scmi_ap_core_get_reset_addr(void *p, uint64_t *reset_addr, uint32_t *attr);
|
||||
|
||||
/* API to get the platform specific SCMI channel information. */
|
||||
scmi_channel_plat_info_t *plat_css_get_scmi_info(int channel_id);
|
||||
|
||||
/* API to override default PSCI callbacks for platforms that support SCMI. */
|
||||
const plat_psci_ops_t *css_scmi_override_pm_ops(plat_psci_ops_t *ops);
|
||||
|
||||
#endif /* SCMI_H */
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef SDS_H
|
||||
#define SDS_H
|
||||
|
||||
/* SDS Structure Identifier defines */
|
||||
/* AP CPU INFO defines */
|
||||
#define SDS_AP_CPU_INFO_STRUCT_ID 1
|
||||
#define SDS_AP_CPU_INFO_PRIMARY_CPUID_OFFSET 0x0
|
||||
#define SDS_AP_CPU_INFO_PRIMARY_CPUID_SIZE 0x4
|
||||
|
||||
/* ROM Firmware Version defines */
|
||||
#define SDS_ROM_VERSION_STRUCT_ID 2
|
||||
#define SDS_ROM_VERSION_OFFSET 0x0
|
||||
#define SDS_ROM_VERSION_SIZE 0x4
|
||||
|
||||
/* RAM Firmware version defines */
|
||||
#define SDS_RAM_VERSION_STRUCT_ID 3
|
||||
#define SDS_RAM_VERSION_OFFSET 0x0
|
||||
#define SDS_RAM_VERSION_SIZE 0x4
|
||||
|
||||
/* Platform Identity defines */
|
||||
#define SDS_PLATFORM_IDENTITY_STRUCT_ID 4
|
||||
#define SDS_PLATFORM_IDENTITY_ID_OFFSET 0x0
|
||||
#define SDS_PLATFORM_IDENTITY_ID_SIZE 0x4
|
||||
#define SDS_PLATFORM_IDENTITY_ID_CONFIG_SHIFT 28
|
||||
#define SDS_PLATFORM_IDENTITY_ID_CONFIG_WIDTH 4
|
||||
#define SDS_PLATFORM_IDENTITY_ID_CONFIG_MASK \
|
||||
((1 << SDS_PLATFORM_IDENTITY_ID_CONFIG_WIDTH) - 1)
|
||||
|
||||
#define SDS_PLATFORM_IDENTITY_PLAT_TYPE_OFFSET 0x4
|
||||
#define SDS_PLATFORM_IDENTITY_PLAT_TYPE_SIZE 0x4
|
||||
|
||||
/* Reset Syndrome defines */
|
||||
#define SDS_RESET_SYNDROME_STRUCT_ID 5
|
||||
#define SDS_RESET_SYNDROME_OFFSET 0
|
||||
#define SDS_RESET_SYNDROME_SIZE 4
|
||||
#define SDS_RESET_SYNDROME_POW_ON_RESET_BIT (1 << 0)
|
||||
#define SDS_RESET_SYNDROME_SCP_WD_RESET_BIT (1 << 1)
|
||||
#define SDS_RESET_SYNDROME_AP_WD_RESET_BIT (1 << 2)
|
||||
#define SDS_RESET_SYNDROME_SYS_RESET_REQ_BIT (1 << 3)
|
||||
#define SDS_RESET_SYNDROME_M3_LOCKUP_BIT (1 << 4)
|
||||
|
||||
/* SCP Firmware Feature Availability defines */
|
||||
#define SDS_FEATURE_AVAIL_STRUCT_ID 6
|
||||
#define SDS_FEATURE_AVAIL_OFFSET 0
|
||||
#define SDS_FEATURE_AVAIL_SIZE 4
|
||||
#define SDS_FEATURE_AVAIL_SCP_RAM_READY_BIT (1 << 0)
|
||||
#define SDS_FEATURE_AVAIL_DMC_READY_BIT (1 << 1)
|
||||
#define SDS_FEATURE_AVAIL_MSG_IF_READY_BIT (1 << 2)
|
||||
|
||||
/* SCP BL2 Image Metadata defines */
|
||||
#define SDS_SCP_IMG_STRUCT_ID 9
|
||||
#define SDS_SCP_IMG_FLAG_OFFSET 0
|
||||
#define SDS_SCP_IMG_FLAG_SIZE 4
|
||||
#define SDS_SCP_IMG_VALID_FLAG_BIT (1 << 0)
|
||||
#define SDS_SCP_IMG_ADDR_OFFSET 4
|
||||
#define SDS_SCP_IMG_ADDR_SIZE 4
|
||||
#define SDS_SCP_IMG_SIZE_OFFSET 8
|
||||
#define SDS_SCP_IMG_SIZE_SIZE 4
|
||||
|
||||
/* SDS Driver Error Codes */
|
||||
#define SDS_OK 0
|
||||
#define SDS_ERR_FAIL -1
|
||||
#define SDS_ERR_INVALID_PARAMS -2
|
||||
#define SDS_ERR_STRUCT_NOT_FOUND -3
|
||||
#define SDS_ERR_STRUCT_NOT_FINALIZED -4
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
typedef enum {
|
||||
SDS_ACCESS_MODE_NON_CACHED,
|
||||
SDS_ACCESS_MODE_CACHED,
|
||||
} sds_access_mode_t;
|
||||
|
||||
int sds_init(void);
|
||||
int sds_struct_exists(unsigned int structure_id);
|
||||
int sds_struct_read(uint32_t structure_id, unsigned int fld_off, void *data,
|
||||
size_t size, sds_access_mode_t mode);
|
||||
int sds_struct_write(uint32_t structure_id, unsigned int fld_off, void *data,
|
||||
size_t size, sds_access_mode_t mode);
|
||||
#endif /*__ASSEMBLER__ */
|
||||
|
||||
#endif /* SDS_H */
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Xilinx Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef DCC_H
|
||||
#define DCC_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <drivers/console.h>
|
||||
|
||||
/*
|
||||
* Initialize a new dcc console instance and register it with the console
|
||||
* framework.
|
||||
*/
|
||||
int console_dcc_register(void);
|
||||
|
||||
#endif /* DCC */
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (c) 2021-2022, Arm Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef ETHOSN_H
|
||||
#define ETHOSN_H
|
||||
|
||||
#include <lib/smccc.h>
|
||||
|
||||
/* Function numbers */
|
||||
#define ETHOSN_FNUM_VERSION U(0x50)
|
||||
#define ETHOSN_FNUM_IS_SEC U(0x51)
|
||||
#define ETHOSN_FNUM_HARD_RESET U(0x52)
|
||||
#define ETHOSN_FNUM_SOFT_RESET U(0x53)
|
||||
/* 0x54-0x5F reserved for future use */
|
||||
|
||||
/* SMC64 function IDs */
|
||||
#define ETHOSN_FID_64(func_num) U(0xC2000000 | func_num)
|
||||
#define ETHOSN_FID_VERSION_64 ETHOSN_FID_64(ETHOSN_FNUM_VERSION)
|
||||
#define ETHOSN_FID_IS_SEC_64 ETHOSN_FID_64(ETHOSN_FNUM_IS_SEC)
|
||||
#define ETHOSN_FID_HARD_RESET_64 ETHOSN_FID_64(ETHOSN_FNUM_HARD_RESET)
|
||||
#define ETHOSN_FID_SOFT_RESET_64 ETHOSN_FID_64(ETHOSN_FNUM_SOFT_RESET)
|
||||
|
||||
/* SMC32 function IDs */
|
||||
#define ETHOSN_FID_32(func_num) U(0x82000000 | func_num)
|
||||
#define ETHOSN_FID_VERSION_32 ETHOSN_FID_32(ETHOSN_FNUM_VERSION)
|
||||
#define ETHOSN_FID_IS_SEC_32 ETHOSN_FID_32(ETHOSN_FNUM_IS_SEC)
|
||||
#define ETHOSN_FID_HARD_RESET_32 ETHOSN_FID_32(ETHOSN_FNUM_HARD_RESET)
|
||||
#define ETHOSN_FID_SOFT_RESET_32 ETHOSN_FID_32(ETHOSN_FNUM_SOFT_RESET)
|
||||
|
||||
#define ETHOSN_NUM_SMC_CALLS 8
|
||||
|
||||
/* Macro to identify function calls */
|
||||
#define ETHOSN_FID_MASK U(0xFFF0)
|
||||
#define ETHOSN_FID_VALUE U(0x50)
|
||||
#define is_ethosn_fid(_fid) (((_fid) & ETHOSN_FID_MASK) == ETHOSN_FID_VALUE)
|
||||
|
||||
/* Service version */
|
||||
#define ETHOSN_VERSION_MAJOR U(2)
|
||||
#define ETHOSN_VERSION_MINOR U(0)
|
||||
|
||||
/* Return codes for function calls */
|
||||
#define ETHOSN_SUCCESS 0
|
||||
#define ETHOSN_NOT_SUPPORTED -1
|
||||
/* -2 Reserved for NOT_REQUIRED */
|
||||
/* -3 Reserved for INVALID_PARAMETER */
|
||||
#define ETHOSN_FAILURE -4
|
||||
#define ETHOSN_UNKNOWN_CORE_ADDRESS -5
|
||||
#define ETHOSN_UNKNOWN_ALLOCATOR_IDX -6
|
||||
|
||||
uintptr_t ethosn_smc_handler(uint32_t smc_fid,
|
||||
u_register_t core_addr,
|
||||
u_register_t asset_alloc_idx,
|
||||
u_register_t x3,
|
||||
u_register_t x4,
|
||||
void *cookie,
|
||||
void *handle,
|
||||
u_register_t flags);
|
||||
|
||||
#endif /* ETHOSN_H */
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef FVP_PWRC_H
|
||||
#define FVP_PWRC_H
|
||||
|
||||
/* FVP Power controller register offset etc */
|
||||
#define PPOFFR_OFF U(0x0)
|
||||
#define PPONR_OFF U(0x4)
|
||||
#define PCOFFR_OFF U(0x8)
|
||||
#define PWKUPR_OFF U(0xc)
|
||||
#define PSYSR_OFF U(0x10)
|
||||
|
||||
#define PWKUPR_WEN BIT_32(31)
|
||||
|
||||
#define PSYSR_AFF_L2 BIT_32(31)
|
||||
#define PSYSR_AFF_L1 BIT_32(30)
|
||||
#define PSYSR_AFF_L0 BIT_32(29)
|
||||
#define PSYSR_WEN BIT_32(28)
|
||||
#define PSYSR_PC BIT_32(27)
|
||||
#define PSYSR_PP BIT_32(26)
|
||||
|
||||
#define PSYSR_WK_SHIFT 24
|
||||
#define PSYSR_WK_WIDTH 0x2
|
||||
#define PSYSR_WK_MASK ((1U << PSYSR_WK_WIDTH) - 1U)
|
||||
#define PSYSR_WK(x) ((x) >> PSYSR_WK_SHIFT) & PSYSR_WK_MASK
|
||||
|
||||
#define WKUP_COLD U(0x0)
|
||||
#define WKUP_RESET U(0x1)
|
||||
#define WKUP_PPONR U(0x2)
|
||||
#define WKUP_GICREQ U(0x3)
|
||||
|
||||
#define PSYSR_INVALID U(0xffffffff)
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/*******************************************************************************
|
||||
* Function & variable prototypes
|
||||
******************************************************************************/
|
||||
void fvp_pwrc_write_pcoffr(u_register_t mpidr);
|
||||
void fvp_pwrc_write_ppoffr(u_register_t mpidr);
|
||||
void fvp_pwrc_write_pponr(u_register_t mpidr);
|
||||
void fvp_pwrc_set_wen(u_register_t mpidr);
|
||||
void fvp_pwrc_clr_wen(u_register_t mpidr);
|
||||
unsigned int fvp_pwrc_read_psysr(u_register_t mpidr);
|
||||
unsigned int fvp_pwrc_get_cpu_wkr(u_register_t mpidr);
|
||||
|
||||
#endif /*__ASSEMBLER__*/
|
||||
|
||||
#endif /* FVP_PWRC_H */
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (c) 2019, ARM Limited. All rights reserved.
|
||||
* Copyright (c) 2023, NVIDIA Corporation. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef GIC600_MULTICHIP_H
|
||||
#define GIC600_MULTICHIP_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/*
|
||||
* GIC-600 microarchitecture supports coherent multichip environments containing
|
||||
* up to 16 chips.
|
||||
*/
|
||||
#define GIC600_MAX_MULTICHIP 16
|
||||
|
||||
typedef struct multichip_spi_ids_desc {
|
||||
uintptr_t gicd_base;
|
||||
uint32_t spi_id_min;
|
||||
uint32_t spi_id_max;
|
||||
} multichip_spi_ids_desc_t;
|
||||
|
||||
/*******************************************************************************
|
||||
* GIC-600 multichip data structure describes platform specific attributes
|
||||
* related to GIC-600 multichip. Platform port is expected to define these
|
||||
* attributes to initialize the multichip related registers and create
|
||||
* successful connections between the GIC-600s in a multichip system.
|
||||
*
|
||||
* The 'rt_owner_base' field contains the base address of the GIC Distributor
|
||||
* which owns the routing table.
|
||||
*
|
||||
* The 'rt_owner' field contains the chip number which owns the routing table.
|
||||
* Chip number or chip_id starts from 0.
|
||||
*
|
||||
* The 'chip_count' field contains the total number of chips in a multichip
|
||||
* system. This should match the number of entries in 'chip_addrs' and 'spi_ids'
|
||||
* fields.
|
||||
*
|
||||
* The 'chip_addrs' field contains array of chip addresses. These addresses are
|
||||
* implementation specific values.
|
||||
*
|
||||
* The 'multichip_spi_ids_desc_t' field contains array of descriptors used to
|
||||
* provide minimum and maximum SPI interrupt ids that each chip owns and the
|
||||
* corresponding chip base address. Note that SPI interrupt ids can range from
|
||||
* 32 to 960 and it should be group of 32 (i.e., SPI minimum and (SPI maximum +
|
||||
* 1) should be a multiple of 32). If a chip doesn't own any SPI interrupts a
|
||||
* value of {0, 0, 0} should be passed.
|
||||
******************************************************************************/
|
||||
struct gic600_multichip_data {
|
||||
uintptr_t rt_owner_base;
|
||||
unsigned int rt_owner;
|
||||
unsigned int chip_count;
|
||||
uint64_t chip_addrs[GIC600_MAX_MULTICHIP];
|
||||
multichip_spi_ids_desc_t spi_ids[GIC600_MAX_MULTICHIP];
|
||||
};
|
||||
|
||||
uintptr_t gic600_multichip_gicd_base_for_spi(uint32_t spi_id);
|
||||
void gic600_multichip_init(struct gic600_multichip_data *multichip_data);
|
||||
bool gic600_multichip_is_initialized(void);
|
||||
|
||||
#endif /* GIC600_MULTICHIP_H */
|
||||
@@ -0,0 +1,157 @@
|
||||
/*
|
||||
* Copyright (c) 2021-2022, NVIDIA Corporation. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef GIC600AE_FMU_H
|
||||
#define GIC600AE_FMU_H
|
||||
|
||||
/*******************************************************************************
|
||||
* GIC600-AE FMU register offsets and constants
|
||||
******************************************************************************/
|
||||
#define GICFMU_ERRFR_LO U(0x000)
|
||||
#define GICFMU_ERRFR_HI U(0x004)
|
||||
#define GICFMU_ERRCTLR_LO U(0x008)
|
||||
#define GICFMU_ERRCTLR_HI U(0x00C)
|
||||
#define GICFMU_ERRSTATUS_LO U(0x010)
|
||||
#define GICFMU_ERRSTATUS_HI U(0x014)
|
||||
#define GICFMU_ERRGSR_LO U(0xE00)
|
||||
#define GICFMU_ERRGSR_HI U(0xE04)
|
||||
#define GICFMU_KEY U(0xEA0)
|
||||
#define GICFMU_PINGCTLR U(0xEA4)
|
||||
#define GICFMU_PINGNOW U(0xEA8)
|
||||
#define GICFMU_SMEN U(0xEB0)
|
||||
#define GICFMU_SMINJERR U(0xEB4)
|
||||
#define GICFMU_PINGMASK_LO U(0xEC0)
|
||||
#define GICFMU_PINGMASK_HI U(0xEC4)
|
||||
#define GICFMU_STATUS U(0xF00)
|
||||
#define GICFMU_ERRIDR U(0xFC8)
|
||||
|
||||
/* ERRCTLR bits */
|
||||
#define FMU_ERRCTLR_ED_BIT BIT(0)
|
||||
#define FMU_ERRCTLR_CE_EN_BIT BIT(1)
|
||||
#define FMU_ERRCTLR_UI_BIT BIT(2)
|
||||
#define FMU_ERRCTLR_CI_BIT BIT(3)
|
||||
|
||||
/* SMEN constants */
|
||||
#define FMU_SMEN_BLK_SHIFT U(8)
|
||||
#define FMU_SMEN_SMID_SHIFT U(24)
|
||||
#define FMU_SMEN_EN_BIT BIT(0)
|
||||
|
||||
/* Error record IDs */
|
||||
#define FMU_BLK_GICD U(0)
|
||||
#define FMU_BLK_SPICOL U(1)
|
||||
#define FMU_BLK_WAKERQ U(2)
|
||||
#define FMU_BLK_ITS0 U(4)
|
||||
#define FMU_BLK_ITS1 U(5)
|
||||
#define FMU_BLK_ITS2 U(6)
|
||||
#define FMU_BLK_ITS3 U(7)
|
||||
#define FMU_BLK_ITS4 U(8)
|
||||
#define FMU_BLK_ITS5 U(9)
|
||||
#define FMU_BLK_ITS6 U(10)
|
||||
#define FMU_BLK_ITS7 U(11)
|
||||
#define FMU_BLK_PPI0 U(12)
|
||||
#define FMU_BLK_PPI1 U(13)
|
||||
#define FMU_BLK_PPI2 U(14)
|
||||
#define FMU_BLK_PPI3 U(15)
|
||||
#define FMU_BLK_PPI4 U(16)
|
||||
#define FMU_BLK_PPI5 U(17)
|
||||
#define FMU_BLK_PPI6 U(18)
|
||||
#define FMU_BLK_PPI7 U(19)
|
||||
#define FMU_BLK_PPI8 U(20)
|
||||
#define FMU_BLK_PPI9 U(21)
|
||||
#define FMU_BLK_PPI10 U(22)
|
||||
#define FMU_BLK_PPI11 U(23)
|
||||
#define FMU_BLK_PPI12 U(24)
|
||||
#define FMU_BLK_PPI13 U(25)
|
||||
#define FMU_BLK_PPI14 U(26)
|
||||
#define FMU_BLK_PPI15 U(27)
|
||||
#define FMU_BLK_PPI16 U(28)
|
||||
#define FMU_BLK_PPI17 U(29)
|
||||
#define FMU_BLK_PPI18 U(30)
|
||||
#define FMU_BLK_PPI19 U(31)
|
||||
#define FMU_BLK_PPI20 U(32)
|
||||
#define FMU_BLK_PPI21 U(33)
|
||||
#define FMU_BLK_PPI22 U(34)
|
||||
#define FMU_BLK_PPI23 U(35)
|
||||
#define FMU_BLK_PPI24 U(36)
|
||||
#define FMU_BLK_PPI25 U(37)
|
||||
#define FMU_BLK_PPI26 U(38)
|
||||
#define FMU_BLK_PPI27 U(39)
|
||||
#define FMU_BLK_PPI28 U(40)
|
||||
#define FMU_BLK_PPI29 U(41)
|
||||
#define FMU_BLK_PPI30 U(42)
|
||||
#define FMU_BLK_PPI31 U(43)
|
||||
#define FMU_BLK_PRESENT_MASK U(0xFFFFFFFFFFF)
|
||||
|
||||
/* Safety Mechamism limit */
|
||||
#define FMU_SMID_GICD_MAX U(33)
|
||||
#define FMU_SMID_PPI_MAX U(12)
|
||||
#define FMU_SMID_ITS_MAX U(14)
|
||||
#define FMU_SMID_SPICOL_MAX U(5)
|
||||
#define FMU_SMID_WAKERQ_MAX U(2)
|
||||
|
||||
/* MBIST Safety Mechanism ID */
|
||||
#define GICD_MBIST_REQ_ERROR U(23)
|
||||
#define GICD_FMU_CLKGATE_ERROR U(33)
|
||||
#define PPI_MBIST_REQ_ERROR U(10)
|
||||
#define PPI_FMU_CLKGATE_ERROR U(12)
|
||||
#define ITS_MBIST_REQ_ERROR U(13)
|
||||
#define ITS_FMU_CLKGATE_ERROR U(14)
|
||||
|
||||
/* ERRSTATUS bits */
|
||||
#define FMU_ERRSTATUS_BLKID_SHIFT U(32)
|
||||
#define FMU_ERRSTATUS_BLKID_MASK U(0xFF)
|
||||
#define FMU_ERRSTATUS_V_BIT BIT(30)
|
||||
#define FMU_ERRSTATUS_UE_BIT BIT(29)
|
||||
#define FMU_ERRSTATUS_OV_BIT BIT(27)
|
||||
#define FMU_ERRSTATUS_CE_BITS (BIT(25) | BIT(24))
|
||||
#define FMU_ERRSTATUS_CLEAR (FMU_ERRSTATUS_V_BIT | FMU_ERRSTATUS_UE_BIT | \
|
||||
FMU_ERRSTATUS_OV_BIT | FMU_ERRSTATUS_CE_BITS)
|
||||
#define FMU_ERRSTATUS_IERR_MASK U(0xFF)
|
||||
#define FMU_ERRSTATUS_IERR_SHIFT U(8)
|
||||
#define FMU_ERRSTATUS_SERR_MASK U(0xFF)
|
||||
|
||||
/* PINGCTLR constants */
|
||||
#define FMU_PINGCTLR_INTDIFF_SHIFT U(16)
|
||||
#define FMU_PINGCTLR_TIMEOUTVAL_SHIFT U(4)
|
||||
#define FMU_PINGCTLR_EN_BIT BIT(0)
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <arch_helpers.h>
|
||||
|
||||
/*******************************************************************************
|
||||
* GIC600 FMU EL3 driver API
|
||||
******************************************************************************/
|
||||
uint64_t gic_fmu_read_errfr(uintptr_t base, unsigned int n);
|
||||
uint64_t gic_fmu_read_errctlr(uintptr_t base, unsigned int n);
|
||||
uint64_t gic_fmu_read_errstatus(uintptr_t base, unsigned int n);
|
||||
uint64_t gic_fmu_read_errgsr(uintptr_t base);
|
||||
uint32_t gic_fmu_read_pingctlr(uintptr_t base);
|
||||
uint32_t gic_fmu_read_pingnow(uintptr_t base);
|
||||
uint64_t gic_fmu_read_pingmask(uintptr_t base);
|
||||
uint32_t gic_fmu_read_status(uintptr_t base);
|
||||
uint32_t gic_fmu_read_erridr(uintptr_t base);
|
||||
void gic_fmu_write_errctlr(uintptr_t base, unsigned int n, uint64_t val);
|
||||
void gic_fmu_write_errstatus(uintptr_t base, unsigned int n, uint64_t val);
|
||||
void gic_fmu_write_pingctlr(uintptr_t base, uint32_t val);
|
||||
void gic_fmu_write_pingnow(uintptr_t base, uint32_t val);
|
||||
void gic_fmu_write_smen(uintptr_t base, uint32_t val);
|
||||
void gic_fmu_write_sminjerr(uintptr_t base, uint32_t val);
|
||||
void gic_fmu_write_pingmask(uintptr_t base, uint64_t val);
|
||||
void gic_fmu_disable_all_sm_blkid(uintptr_t base, unsigned int blkid);
|
||||
|
||||
void gic600_fmu_init(uint64_t base, uint64_t blk_present_mask, bool errctlr_ce_en, bool errctlr_ue_en);
|
||||
void gic600_fmu_enable_ping(uint64_t base, uint64_t blk_present_mask,
|
||||
unsigned int timeout_val, unsigned int interval_diff);
|
||||
void gic600_fmu_print_sm_info(uint64_t base, unsigned int blk, unsigned int smid);
|
||||
int gic600_fmu_probe(uint64_t base, int *probe_data);
|
||||
int gic600_fmu_ras_handler(uint64_t base, int probe_data);
|
||||
|
||||
#endif /* __ASSEMBLER__ */
|
||||
|
||||
#endif /* GIC600AE_FMU_H */
|
||||
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef GIC_COMMON_H
|
||||
#define GIC_COMMON_H
|
||||
|
||||
#include <lib/utils_def.h>
|
||||
|
||||
/*******************************************************************************
|
||||
* GIC Distributor interface general definitions
|
||||
******************************************************************************/
|
||||
/* Constants to categorise interrupts */
|
||||
#define MIN_SGI_ID U(0)
|
||||
#define MIN_SEC_SGI_ID U(8)
|
||||
#define MIN_PPI_ID U(16)
|
||||
#define MIN_SPI_ID U(32)
|
||||
#define MAX_SPI_ID U(1019)
|
||||
|
||||
#define TOTAL_SPI_INTR_NUM (MAX_SPI_ID - MIN_SPI_ID + U(1))
|
||||
#define TOTAL_PCPU_INTR_NUM (MIN_SPI_ID - MIN_SGI_ID)
|
||||
|
||||
/* Mask for the priority field common to all GIC interfaces */
|
||||
#define GIC_PRI_MASK U(0xff)
|
||||
|
||||
/* Mask for the configuration field common to all GIC interfaces */
|
||||
#define GIC_CFG_MASK U(0x3)
|
||||
|
||||
/* Constant to indicate a spurious interrupt in all GIC versions */
|
||||
#define GIC_SPURIOUS_INTERRUPT U(1023)
|
||||
|
||||
/* Interrupt configurations: 2-bit fields with LSB reserved */
|
||||
#define GIC_INTR_CFG_LEVEL (0 << 1)
|
||||
#define GIC_INTR_CFG_EDGE (1 << 1)
|
||||
|
||||
/* Highest possible interrupt priorities */
|
||||
#define GIC_HIGHEST_SEC_PRIORITY U(0x00)
|
||||
#define GIC_HIGHEST_NS_PRIORITY U(0x80)
|
||||
|
||||
/*******************************************************************************
|
||||
* Common GIC Distributor interface register offsets
|
||||
******************************************************************************/
|
||||
#define GICD_CTLR U(0x0)
|
||||
#define GICD_TYPER U(0x4)
|
||||
#define GICD_IIDR U(0x8)
|
||||
#define GICD_IGROUPR U(0x80)
|
||||
#define GICD_ISENABLER U(0x100)
|
||||
#define GICD_ICENABLER U(0x180)
|
||||
#define GICD_ISPENDR U(0x200)
|
||||
#define GICD_ICPENDR U(0x280)
|
||||
#define GICD_ISACTIVER U(0x300)
|
||||
#define GICD_ICACTIVER U(0x380)
|
||||
#define GICD_IPRIORITYR U(0x400)
|
||||
#define GICD_ICFGR U(0xc00)
|
||||
#define GICD_NSACR U(0xe00)
|
||||
|
||||
/* GICD_CTLR bit definitions */
|
||||
#define CTLR_ENABLE_G0_SHIFT 0
|
||||
#define CTLR_ENABLE_G0_MASK U(0x1)
|
||||
#define CTLR_ENABLE_G0_BIT BIT_32(CTLR_ENABLE_G0_SHIFT)
|
||||
|
||||
/*******************************************************************************
|
||||
* Common GIC Distributor interface register constants
|
||||
******************************************************************************/
|
||||
#define PIDR2_ARCH_REV_SHIFT 4
|
||||
#define PIDR2_ARCH_REV_MASK U(0xf)
|
||||
|
||||
/* GIC revision as reported by PIDR2.ArchRev register field */
|
||||
#define ARCH_REV_GICV1 U(0x1)
|
||||
#define ARCH_REV_GICV2 U(0x2)
|
||||
#define ARCH_REV_GICV3 U(0x3)
|
||||
#define ARCH_REV_GICV4 U(0x4)
|
||||
|
||||
#define IGROUPR_SHIFT 5
|
||||
#define ISENABLER_SHIFT 5
|
||||
#define ICENABLER_SHIFT ISENABLER_SHIFT
|
||||
#define ISPENDR_SHIFT 5
|
||||
#define ICPENDR_SHIFT ISPENDR_SHIFT
|
||||
#define ISACTIVER_SHIFT 5
|
||||
#define ICACTIVER_SHIFT ISACTIVER_SHIFT
|
||||
#define IPRIORITYR_SHIFT 2
|
||||
#define ITARGETSR_SHIFT 2
|
||||
#define ICFGR_SHIFT 4
|
||||
#define NSACR_SHIFT 4
|
||||
|
||||
/* GICD_TYPER shifts and masks */
|
||||
#define TYPER_IT_LINES_NO_SHIFT U(0)
|
||||
#define TYPER_IT_LINES_NO_MASK U(0x1f)
|
||||
|
||||
/* Value used to initialize Normal world interrupt priorities four at a time */
|
||||
#define GICD_IPRIORITYR_DEF_VAL \
|
||||
(GIC_HIGHEST_NS_PRIORITY | \
|
||||
(GIC_HIGHEST_NS_PRIORITY << 8) | \
|
||||
(GIC_HIGHEST_NS_PRIORITY << 16) | \
|
||||
(GIC_HIGHEST_NS_PRIORITY << 24))
|
||||
|
||||
#endif /* GIC_COMMON_H */
|
||||
@@ -0,0 +1,200 @@
|
||||
/*
|
||||
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
|
||||
* Portions copyright (c) 2021-2022, ProvenRun S.A.S. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef GICV2_H
|
||||
#define GICV2_H
|
||||
|
||||
#include <drivers/arm/gic_common.h>
|
||||
#include <platform_def.h>
|
||||
|
||||
/*******************************************************************************
|
||||
* GICv2 miscellaneous definitions
|
||||
******************************************************************************/
|
||||
|
||||
/* Interrupt group definitions */
|
||||
#define GICV2_INTR_GROUP0 U(0)
|
||||
#define GICV2_INTR_GROUP1 U(1)
|
||||
|
||||
/* Interrupt IDs reported by the HPPIR and IAR registers */
|
||||
#define PENDING_G1_INTID U(1022)
|
||||
|
||||
/* GICv2 can only target up to 8 PEs */
|
||||
#define GICV2_MAX_TARGET_PE U(8)
|
||||
|
||||
/*******************************************************************************
|
||||
* GICv2 specific Distributor interface register offsets and constants.
|
||||
******************************************************************************/
|
||||
#define GICD_ITARGETSR U(0x800)
|
||||
#define GICD_SGIR U(0xF00)
|
||||
#define GICD_CPENDSGIR U(0xF10)
|
||||
#define GICD_SPENDSGIR U(0xF20)
|
||||
|
||||
/*
|
||||
* Some GICv2 implementations violate the specification and have this register
|
||||
* at a different address. Allow overriding it in platform_def.h as workaround.
|
||||
*/
|
||||
#ifndef GICD_PIDR2_GICV2
|
||||
#define GICD_PIDR2_GICV2 U(0xFE8)
|
||||
#endif
|
||||
|
||||
#define ITARGETSR_SHIFT 2
|
||||
#define GIC_TARGET_CPU_MASK U(0xff)
|
||||
|
||||
#define CPENDSGIR_SHIFT 2
|
||||
#define SPENDSGIR_SHIFT CPENDSGIR_SHIFT
|
||||
|
||||
#define SGIR_TGTLSTFLT_SHIFT 24
|
||||
#define SGIR_TGTLSTFLT_MASK U(0x3)
|
||||
#define SGIR_TGTLST_SHIFT 16
|
||||
#define SGIR_TGTLST_MASK U(0xff)
|
||||
#define SGIR_NSATT (U(0x1) << 16)
|
||||
#define SGIR_INTID_MASK ULL(0xf)
|
||||
|
||||
#define SGIR_TGT_SPECIFIC U(0)
|
||||
|
||||
#define GICV2_SGIR_VALUE(tgt_lst_flt, tgt, nsatt, intid) \
|
||||
((((tgt_lst_flt) & SGIR_TGTLSTFLT_MASK) << SGIR_TGTLSTFLT_SHIFT) | \
|
||||
(((tgt) & SGIR_TGTLST_MASK) << SGIR_TGTLST_SHIFT) | \
|
||||
((nsatt) ? SGIR_NSATT : U(0)) | \
|
||||
((intid) & SGIR_INTID_MASK))
|
||||
|
||||
/*******************************************************************************
|
||||
* GICv2 specific CPU interface register offsets and constants.
|
||||
******************************************************************************/
|
||||
/* Physical CPU Interface registers */
|
||||
#define GICC_CTLR U(0x0)
|
||||
#define GICC_PMR U(0x4)
|
||||
#define GICC_BPR U(0x8)
|
||||
#define GICC_IAR U(0xC)
|
||||
#define GICC_EOIR U(0x10)
|
||||
#define GICC_RPR U(0x14)
|
||||
#define GICC_HPPIR U(0x18)
|
||||
#define GICC_AHPPIR U(0x28)
|
||||
#define GICC_IIDR U(0xFC)
|
||||
#define GICC_DIR U(0x1000)
|
||||
#define GICC_PRIODROP GICC_EOIR
|
||||
|
||||
/* GICC_CTLR bit definitions */
|
||||
#define EOI_MODE_NS BIT_32(10)
|
||||
#define EOI_MODE_S BIT_32(9)
|
||||
#define IRQ_BYP_DIS_GRP1 BIT_32(8)
|
||||
#define FIQ_BYP_DIS_GRP1 BIT_32(7)
|
||||
#define IRQ_BYP_DIS_GRP0 BIT_32(6)
|
||||
#define FIQ_BYP_DIS_GRP0 BIT_32(5)
|
||||
#define CBPR BIT_32(4)
|
||||
#define FIQ_EN_SHIFT 3
|
||||
#define FIQ_EN_BIT BIT_32(FIQ_EN_SHIFT)
|
||||
#define ACK_CTL BIT_32(2)
|
||||
|
||||
/* GICC_IIDR bit masks and shifts */
|
||||
#define GICC_IIDR_PID_SHIFT 20
|
||||
#define GICC_IIDR_ARCH_SHIFT 16
|
||||
#define GICC_IIDR_REV_SHIFT 12
|
||||
#define GICC_IIDR_IMP_SHIFT 0
|
||||
|
||||
#define GICC_IIDR_PID_MASK U(0xfff)
|
||||
#define GICC_IIDR_ARCH_MASK U(0xf)
|
||||
#define GICC_IIDR_REV_MASK U(0xf)
|
||||
#define GICC_IIDR_IMP_MASK U(0xfff)
|
||||
|
||||
/* HYP view virtual CPU Interface registers */
|
||||
#define GICH_CTL U(0x0)
|
||||
#define GICH_VTR U(0x4)
|
||||
#define GICH_ELRSR0 U(0x30)
|
||||
#define GICH_ELRSR1 U(0x34)
|
||||
#define GICH_APR0 U(0xF0)
|
||||
#define GICH_LR_BASE U(0x100)
|
||||
|
||||
/* Virtual CPU Interface registers */
|
||||
#define GICV_CTL U(0x0)
|
||||
#define GICV_PRIMASK U(0x4)
|
||||
#define GICV_BP U(0x8)
|
||||
#define GICV_INTACK U(0xC)
|
||||
#define GICV_EOI U(0x10)
|
||||
#define GICV_RUNNINGPRI U(0x14)
|
||||
#define GICV_HIGHESTPEND U(0x18)
|
||||
#define GICV_DEACTIVATE U(0x1000)
|
||||
|
||||
/* GICD_CTLR bit definitions */
|
||||
#define CTLR_ENABLE_G1_SHIFT 1
|
||||
#define CTLR_ENABLE_G1_MASK U(0x1)
|
||||
#define CTLR_ENABLE_G1_BIT BIT_32(CTLR_ENABLE_G1_SHIFT)
|
||||
|
||||
/* Interrupt ID mask for HPPIR, AHPPIR, IAR and AIAR CPU Interface registers */
|
||||
#define INT_ID_MASK U(0x3ff)
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
|
||||
#include <cdefs.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <common/interrupt_props.h>
|
||||
|
||||
/*******************************************************************************
|
||||
* This structure describes some of the implementation defined attributes of
|
||||
* the GICv2 IP. It is used by the platform port to specify these attributes
|
||||
* in order to initialize the GICv2 driver. The attributes are described
|
||||
* below.
|
||||
*
|
||||
* The 'gicd_base' field contains the base address of the Distributor interface
|
||||
* programmer's view.
|
||||
*
|
||||
* The 'gicc_base' field contains the base address of the CPU Interface
|
||||
* programmer's view.
|
||||
*
|
||||
* The 'target_masks' is a pointer to an array containing 'target_masks_num'
|
||||
* elements. The GIC driver will populate the array with per-PE target mask to
|
||||
* use to when targeting interrupts.
|
||||
*
|
||||
* The 'interrupt_props' field is a pointer to an array that enumerates secure
|
||||
* interrupts and their properties. If this field is not NULL, both
|
||||
* 'g0_interrupt_array' and 'g1s_interrupt_array' fields are ignored.
|
||||
*
|
||||
* The 'interrupt_props_num' field contains the number of entries in the
|
||||
* 'interrupt_props' array. If this field is non-zero, 'g0_interrupt_num' is
|
||||
* ignored.
|
||||
******************************************************************************/
|
||||
typedef struct gicv2_driver_data {
|
||||
uintptr_t gicd_base;
|
||||
uintptr_t gicc_base;
|
||||
unsigned int *target_masks;
|
||||
unsigned int target_masks_num;
|
||||
const interrupt_prop_t *interrupt_props;
|
||||
unsigned int interrupt_props_num;
|
||||
} gicv2_driver_data_t;
|
||||
|
||||
/*******************************************************************************
|
||||
* Function prototypes
|
||||
******************************************************************************/
|
||||
void gicv2_driver_init(const gicv2_driver_data_t *plat_driver_data);
|
||||
void gicv2_distif_init(void);
|
||||
void gicv2_pcpu_distif_init(void);
|
||||
void gicv2_cpuif_enable(void);
|
||||
void gicv2_cpuif_disable(void);
|
||||
unsigned int gicv2_is_fiq_enabled(void);
|
||||
unsigned int gicv2_get_pending_interrupt_type(void);
|
||||
unsigned int gicv2_get_pending_interrupt_id(void);
|
||||
unsigned int gicv2_acknowledge_interrupt(void);
|
||||
void gicv2_end_of_interrupt(unsigned int id);
|
||||
unsigned int gicv2_get_interrupt_group(unsigned int id);
|
||||
unsigned int gicv2_get_running_priority(void);
|
||||
void gicv2_set_pe_target_mask(unsigned int proc_num);
|
||||
unsigned int gicv2_get_interrupt_active(unsigned int id);
|
||||
void gicv2_enable_interrupt(unsigned int id);
|
||||
void gicv2_disable_interrupt(unsigned int id);
|
||||
void gicv2_set_interrupt_priority(unsigned int id, unsigned int priority);
|
||||
void gicv2_set_interrupt_type(unsigned int id, unsigned int type);
|
||||
void gicv2_raise_sgi(int sgi_num, bool ns, int proc_num);
|
||||
void gicv2_set_spi_routing(unsigned int id, int proc_num);
|
||||
void gicv2_set_interrupt_pending(unsigned int id);
|
||||
void gicv2_clear_interrupt_pending(unsigned int id);
|
||||
unsigned int gicv2_set_pmr(unsigned int mask);
|
||||
void gicv2_interrupt_set_cfg(unsigned int id, unsigned int cfg);
|
||||
|
||||
#endif /* __ASSEMBLER__ */
|
||||
#endif /* GICV2_H */
|
||||
@@ -0,0 +1,605 @@
|
||||
/*
|
||||
* Copyright (c) 2015-2022, Arm Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef GICV3_H
|
||||
#define GICV3_H
|
||||
|
||||
/*******************************************************************************
|
||||
* GICv3 and 3.1 miscellaneous definitions
|
||||
******************************************************************************/
|
||||
/* Interrupt group definitions */
|
||||
#define INTR_GROUP1S U(0)
|
||||
#define INTR_GROUP0 U(1)
|
||||
#define INTR_GROUP1NS U(2)
|
||||
|
||||
/* Interrupt IDs reported by the HPPIR and IAR registers */
|
||||
#define PENDING_G1S_INTID U(1020)
|
||||
#define PENDING_G1NS_INTID U(1021)
|
||||
|
||||
/* Constant to categorize LPI interrupt */
|
||||
#define MIN_LPI_ID U(8192)
|
||||
|
||||
/* GICv3 can only target up to 16 PEs with SGI */
|
||||
#define GICV3_MAX_SGI_TARGETS U(16)
|
||||
|
||||
/* PPIs INTIDs 16-31 */
|
||||
#define MAX_PPI_ID U(31)
|
||||
|
||||
#if GIC_EXT_INTID
|
||||
|
||||
/* GICv3.1 extended PPIs INTIDs 1056-1119 */
|
||||
#define MIN_EPPI_ID U(1056)
|
||||
#define MAX_EPPI_ID U(1119)
|
||||
|
||||
/* Total number of GICv3.1 EPPIs */
|
||||
#define TOTAL_EPPI_INTR_NUM (MAX_EPPI_ID - MIN_EPPI_ID + U(1))
|
||||
|
||||
/* Total number of GICv3.1 PPIs and EPPIs */
|
||||
#define TOTAL_PRIVATE_INTR_NUM (TOTAL_PCPU_INTR_NUM + TOTAL_EPPI_INTR_NUM)
|
||||
|
||||
/* GICv3.1 extended SPIs INTIDs 4096 - 5119 */
|
||||
#define MIN_ESPI_ID U(4096)
|
||||
#define MAX_ESPI_ID U(5119)
|
||||
|
||||
/* Total number of GICv3.1 ESPIs */
|
||||
#define TOTAL_ESPI_INTR_NUM (MAX_ESPI_ID - MIN_ESPI_ID + U(1))
|
||||
|
||||
/* Total number of GICv3.1 SPIs and ESPIs */
|
||||
#define TOTAL_SHARED_INTR_NUM (TOTAL_SPI_INTR_NUM + TOTAL_ESPI_INTR_NUM)
|
||||
|
||||
/* SGIs: 0-15, PPIs: 16-31, EPPIs: 1056-1119 */
|
||||
#define IS_SGI_PPI(id) (((id) <= MAX_PPI_ID) || \
|
||||
(((id) >= MIN_EPPI_ID) && \
|
||||
((id) <= MAX_EPPI_ID)))
|
||||
|
||||
/* SPIs: 32-1019, ESPIs: 4096-5119 */
|
||||
#define IS_SPI(id) ((((id) >= MIN_SPI_ID) && \
|
||||
((id) <= MAX_SPI_ID)) || \
|
||||
(((id) >= MIN_ESPI_ID) && \
|
||||
((id) <= MAX_ESPI_ID)))
|
||||
#else /* GICv3 */
|
||||
|
||||
/* Total number of GICv3 PPIs */
|
||||
#define TOTAL_PRIVATE_INTR_NUM TOTAL_PCPU_INTR_NUM
|
||||
|
||||
/* Total number of GICv3 SPIs */
|
||||
#define TOTAL_SHARED_INTR_NUM TOTAL_SPI_INTR_NUM
|
||||
|
||||
/* SGIs: 0-15, PPIs: 16-31 */
|
||||
#define IS_SGI_PPI(id) ((id) <= MAX_PPI_ID)
|
||||
|
||||
/* SPIs: 32-1019 */
|
||||
#define IS_SPI(id) (((id) >= MIN_SPI_ID) && ((id) <= MAX_SPI_ID))
|
||||
|
||||
#endif /* GIC_EXT_INTID */
|
||||
|
||||
#define GIC_REV(r, p) ((r << 4) | p)
|
||||
|
||||
/*******************************************************************************
|
||||
* GICv3 and 3.1 specific Distributor interface register offsets and constants
|
||||
******************************************************************************/
|
||||
#define GICD_TYPER2 U(0x0c)
|
||||
#define GICD_STATUSR U(0x10)
|
||||
#define GICD_SETSPI_NSR U(0x40)
|
||||
#define GICD_CLRSPI_NSR U(0x48)
|
||||
#define GICD_SETSPI_SR U(0x50)
|
||||
#define GICD_CLRSPI_SR U(0x58)
|
||||
#define GICD_IGRPMODR U(0xd00)
|
||||
#define GICD_IGROUPRE U(0x1000)
|
||||
#define GICD_ISENABLERE U(0x1200)
|
||||
#define GICD_ICENABLERE U(0x1400)
|
||||
#define GICD_ISPENDRE U(0x1600)
|
||||
#define GICD_ICPENDRE U(0x1800)
|
||||
#define GICD_ISACTIVERE U(0x1a00)
|
||||
#define GICD_ICACTIVERE U(0x1c00)
|
||||
#define GICD_IPRIORITYRE U(0x2000)
|
||||
#define GICD_ICFGRE U(0x3000)
|
||||
#define GICD_IGRPMODRE U(0x3400)
|
||||
#define GICD_NSACRE U(0x3600)
|
||||
/*
|
||||
* GICD_IROUTER<n> register is at 0x6000 + 8n, where n is the interrupt ID
|
||||
* and n >= 32, making the effective offset as 0x6100
|
||||
*/
|
||||
#define GICD_IROUTER U(0x6000)
|
||||
#define GICD_IROUTERE U(0x8000)
|
||||
|
||||
#define GICD_PIDR0_GICV3 U(0xffe0)
|
||||
#define GICD_PIDR1_GICV3 U(0xffe4)
|
||||
#define GICD_PIDR2_GICV3 U(0xffe8)
|
||||
|
||||
#define IGRPMODR_SHIFT 5
|
||||
|
||||
/* GICD_CTLR bit definitions */
|
||||
#define CTLR_ENABLE_G1NS_SHIFT 1
|
||||
#define CTLR_ENABLE_G1S_SHIFT 2
|
||||
#define CTLR_ARE_S_SHIFT 4
|
||||
#define CTLR_ARE_NS_SHIFT 5
|
||||
#define CTLR_DS_SHIFT 6
|
||||
#define CTLR_E1NWF_SHIFT 7
|
||||
#define GICD_CTLR_RWP_SHIFT 31
|
||||
|
||||
#define CTLR_ENABLE_G1NS_MASK U(0x1)
|
||||
#define CTLR_ENABLE_G1S_MASK U(0x1)
|
||||
#define CTLR_ARE_S_MASK U(0x1)
|
||||
#define CTLR_ARE_NS_MASK U(0x1)
|
||||
#define CTLR_DS_MASK U(0x1)
|
||||
#define CTLR_E1NWF_MASK U(0x1)
|
||||
#define GICD_CTLR_RWP_MASK U(0x1)
|
||||
|
||||
#define CTLR_ENABLE_G1NS_BIT BIT_32(CTLR_ENABLE_G1NS_SHIFT)
|
||||
#define CTLR_ENABLE_G1S_BIT BIT_32(CTLR_ENABLE_G1S_SHIFT)
|
||||
#define CTLR_ARE_S_BIT BIT_32(CTLR_ARE_S_SHIFT)
|
||||
#define CTLR_ARE_NS_BIT BIT_32(CTLR_ARE_NS_SHIFT)
|
||||
#define CTLR_DS_BIT BIT_32(CTLR_DS_SHIFT)
|
||||
#define CTLR_E1NWF_BIT BIT_32(CTLR_E1NWF_SHIFT)
|
||||
#define GICD_CTLR_RWP_BIT BIT_32(GICD_CTLR_RWP_SHIFT)
|
||||
|
||||
/* GICD_IROUTER shifts and masks */
|
||||
#define IROUTER_SHIFT 0
|
||||
#define IROUTER_IRM_SHIFT 31
|
||||
#define IROUTER_IRM_MASK U(0x1)
|
||||
|
||||
#define GICV3_IRM_PE U(0)
|
||||
#define GICV3_IRM_ANY U(1)
|
||||
|
||||
#define NUM_OF_DIST_REGS 30
|
||||
|
||||
/* GICD_TYPER shifts and masks */
|
||||
#define TYPER_ESPI U(1 << 8)
|
||||
#define TYPER_DVIS U(1 << 18)
|
||||
#define TYPER_ESPI_RANGE_MASK U(0x1f)
|
||||
#define TYPER_ESPI_RANGE_SHIFT U(27)
|
||||
#define TYPER_ESPI_RANGE U(TYPER_ESPI_MASK << TYPER_ESPI_SHIFT)
|
||||
|
||||
/*******************************************************************************
|
||||
* Common GIC Redistributor interface registers & constants
|
||||
******************************************************************************/
|
||||
#define GICR_V4_PCPUBASE_SHIFT 0x12
|
||||
#define GICR_V3_PCPUBASE_SHIFT 0x11
|
||||
#define GICR_SGIBASE_OFFSET U(65536) /* 64 KB */
|
||||
#define GICR_CTLR U(0x0)
|
||||
#define GICR_IIDR U(0x04)
|
||||
#define GICR_TYPER U(0x08)
|
||||
#define GICR_STATUSR U(0x10)
|
||||
#define GICR_WAKER U(0x14)
|
||||
#define GICR_PROPBASER U(0x70)
|
||||
#define GICR_PENDBASER U(0x78)
|
||||
#define GICR_IGROUPR0 (GICR_SGIBASE_OFFSET + U(0x80))
|
||||
#define GICR_ISENABLER0 (GICR_SGIBASE_OFFSET + U(0x100))
|
||||
#define GICR_ICENABLER0 (GICR_SGIBASE_OFFSET + U(0x180))
|
||||
#define GICR_ISPENDR0 (GICR_SGIBASE_OFFSET + U(0x200))
|
||||
#define GICR_ICPENDR0 (GICR_SGIBASE_OFFSET + U(0x280))
|
||||
#define GICR_ISACTIVER0 (GICR_SGIBASE_OFFSET + U(0x300))
|
||||
#define GICR_ICACTIVER0 (GICR_SGIBASE_OFFSET + U(0x380))
|
||||
#define GICR_IPRIORITYR (GICR_SGIBASE_OFFSET + U(0x400))
|
||||
#define GICR_ICFGR0 (GICR_SGIBASE_OFFSET + U(0xc00))
|
||||
#define GICR_ICFGR1 (GICR_SGIBASE_OFFSET + U(0xc04))
|
||||
#define GICR_IGRPMODR0 (GICR_SGIBASE_OFFSET + U(0xd00))
|
||||
#define GICR_NSACR (GICR_SGIBASE_OFFSET + U(0xe00))
|
||||
|
||||
#define GICR_IGROUPR GICR_IGROUPR0
|
||||
#define GICR_ISENABLER GICR_ISENABLER0
|
||||
#define GICR_ICENABLER GICR_ICENABLER0
|
||||
#define GICR_ISPENDR GICR_ISPENDR0
|
||||
#define GICR_ICPENDR GICR_ICPENDR0
|
||||
#define GICR_ISACTIVER GICR_ISACTIVER0
|
||||
#define GICR_ICACTIVER GICR_ICACTIVER0
|
||||
#define GICR_ICFGR GICR_ICFGR0
|
||||
#define GICR_IGRPMODR GICR_IGRPMODR0
|
||||
|
||||
/* GICR_CTLR bit definitions */
|
||||
#define GICR_CTLR_UWP_SHIFT 31
|
||||
#define GICR_CTLR_UWP_MASK U(0x1)
|
||||
#define GICR_CTLR_UWP_BIT BIT_32(GICR_CTLR_UWP_SHIFT)
|
||||
#define GICR_CTLR_DPG1S_SHIFT 26
|
||||
#define GICR_CTLR_DPG1S_MASK U(0x1)
|
||||
#define GICR_CTLR_DPG1S_BIT BIT_32(GICR_CTLR_DPG1S_SHIFT)
|
||||
#define GICR_CTLR_DPG1NS_SHIFT 25
|
||||
#define GICR_CTLR_DPG1NS_MASK U(0x1)
|
||||
#define GICR_CTLR_DPG1NS_BIT BIT_32(GICR_CTLR_DPG1NS_SHIFT)
|
||||
#define GICR_CTLR_DPG0_SHIFT 24
|
||||
#define GICR_CTLR_DPG0_MASK U(0x1)
|
||||
#define GICR_CTLR_DPG0_BIT BIT_32(GICR_CTLR_DPG0_SHIFT)
|
||||
#define GICR_CTLR_RWP_SHIFT 3
|
||||
#define GICR_CTLR_RWP_MASK U(0x1)
|
||||
#define GICR_CTLR_RWP_BIT BIT_32(GICR_CTLR_RWP_SHIFT)
|
||||
#define GICR_CTLR_EN_LPIS_BIT BIT_32(0)
|
||||
|
||||
/* GICR_WAKER bit definitions */
|
||||
#define WAKER_CA_SHIFT 2
|
||||
#define WAKER_PS_SHIFT 1
|
||||
|
||||
#define WAKER_CA_MASK U(0x1)
|
||||
#define WAKER_PS_MASK U(0x1)
|
||||
|
||||
#define WAKER_CA_BIT BIT_32(WAKER_CA_SHIFT)
|
||||
#define WAKER_PS_BIT BIT_32(WAKER_PS_SHIFT)
|
||||
|
||||
/* GICR_TYPER bit definitions */
|
||||
#define TYPER_AFF_VAL_SHIFT 32
|
||||
#define TYPER_PROC_NUM_SHIFT 8
|
||||
#define TYPER_LAST_SHIFT 4
|
||||
#define TYPER_VLPI_SHIFT 1
|
||||
|
||||
#define TYPER_AFF_VAL_MASK U(0xffffffff)
|
||||
#define TYPER_PROC_NUM_MASK U(0xffff)
|
||||
#define TYPER_LAST_MASK U(0x1)
|
||||
|
||||
#define TYPER_LAST_BIT BIT_32(TYPER_LAST_SHIFT)
|
||||
#define TYPER_VLPI_BIT BIT_32(TYPER_VLPI_SHIFT)
|
||||
|
||||
#define TYPER_PPI_NUM_SHIFT U(27)
|
||||
#define TYPER_PPI_NUM_MASK U(0x1f)
|
||||
|
||||
/* GICR_IIDR bit definitions */
|
||||
#define IIDR_PRODUCT_ID_MASK U(0xff)
|
||||
#define IIDR_VARIANT_MASK U(0xf)
|
||||
#define IIDR_REV_MASK U(0xf)
|
||||
#define IIDR_IMPLEMENTER_MASK U(0xfff)
|
||||
#define IIDR_PRODUCT_ID_SHIFT 24
|
||||
#define IIDR_VARIANT_SHIFT 16
|
||||
#define IIDR_REV_SHIFT 12
|
||||
#define IIDR_IMPLEMENTER_SHIFT 0
|
||||
#define IIDR_PRODUCT_ID_BIT BIT_32(IIDR_PRODUCT_ID_SHIFT)
|
||||
#define IIDR_VARIANT_BIT BIT_32(IIDR_VARIANT_SHIFT)
|
||||
#define IIDR_REV_BIT BIT_32(IIDR_REVISION_SHIFT)
|
||||
#define IIDR_IMPLEMENTER_BIT BIT_32(IIDR_IMPLEMENTER_SHIFT)
|
||||
|
||||
#define IIDR_MODEL_MASK (IIDR_PRODUCT_ID_MASK << IIDR_PRODUCT_ID_SHIFT | \
|
||||
IIDR_IMPLEMENTER_MASK << IIDR_IMPLEMENTER_SHIFT)
|
||||
|
||||
#define GIC_PRODUCT_ID_GIC600 U(0x2)
|
||||
#define GIC_PRODUCT_ID_GIC600AE U(0x3)
|
||||
#define GIC_PRODUCT_ID_GIC700 U(0x4)
|
||||
|
||||
/*
|
||||
* Note that below revisions and variants definations are as per GIC600/GIC600AE
|
||||
* specification.
|
||||
*/
|
||||
#define GIC_REV_P0 U(0x1)
|
||||
#define GIC_REV_P1 U(0x3)
|
||||
#define GIC_REV_P2 U(0x4)
|
||||
#define GIC_REV_P3 U(0x5)
|
||||
#define GIC_REV_P4 U(0x6)
|
||||
#define GIC_REV_P6 U(0x7)
|
||||
|
||||
#define GIC_VARIANT_R0 U(0x0)
|
||||
#define GIC_VARIANT_R1 U(0x1)
|
||||
#define GIC_VARIANT_R2 U(0x2)
|
||||
|
||||
/*******************************************************************************
|
||||
* GICv3 and 3.1 CPU interface registers & constants
|
||||
******************************************************************************/
|
||||
/* ICC_SRE bit definitions */
|
||||
#define ICC_SRE_EN_BIT BIT_32(3)
|
||||
#define ICC_SRE_DIB_BIT BIT_32(2)
|
||||
#define ICC_SRE_DFB_BIT BIT_32(1)
|
||||
#define ICC_SRE_SRE_BIT BIT_32(0)
|
||||
|
||||
/* ICC_IGRPEN1_EL3 bit definitions */
|
||||
#define IGRPEN1_EL3_ENABLE_G1NS_SHIFT 0
|
||||
#define IGRPEN1_EL3_ENABLE_G1S_SHIFT 1
|
||||
|
||||
#define IGRPEN1_EL3_ENABLE_G1NS_BIT BIT_32(IGRPEN1_EL3_ENABLE_G1NS_SHIFT)
|
||||
#define IGRPEN1_EL3_ENABLE_G1S_BIT BIT_32(IGRPEN1_EL3_ENABLE_G1S_SHIFT)
|
||||
|
||||
/* ICC_IGRPEN0_EL1 bit definitions */
|
||||
#define IGRPEN1_EL1_ENABLE_G0_SHIFT 0
|
||||
#define IGRPEN1_EL1_ENABLE_G0_BIT BIT_32(IGRPEN1_EL1_ENABLE_G0_SHIFT)
|
||||
|
||||
/* ICC_HPPIR0_EL1 bit definitions */
|
||||
#define HPPIR0_EL1_INTID_SHIFT 0
|
||||
#define HPPIR0_EL1_INTID_MASK U(0xffffff)
|
||||
|
||||
/* ICC_HPPIR1_EL1 bit definitions */
|
||||
#define HPPIR1_EL1_INTID_SHIFT 0
|
||||
#define HPPIR1_EL1_INTID_MASK U(0xffffff)
|
||||
|
||||
/* ICC_IAR0_EL1 bit definitions */
|
||||
#define IAR0_EL1_INTID_SHIFT 0
|
||||
#define IAR0_EL1_INTID_MASK U(0xffffff)
|
||||
|
||||
/* ICC_IAR1_EL1 bit definitions */
|
||||
#define IAR1_EL1_INTID_SHIFT 0
|
||||
#define IAR1_EL1_INTID_MASK U(0xffffff)
|
||||
|
||||
/* ICC SGI macros */
|
||||
#define SGIR_TGT_MASK ULL(0xffff)
|
||||
#define SGIR_AFF1_SHIFT 16
|
||||
#define SGIR_INTID_SHIFT 24
|
||||
#define SGIR_INTID_MASK ULL(0xf)
|
||||
#define SGIR_AFF2_SHIFT 32
|
||||
#define SGIR_IRM_SHIFT 40
|
||||
#define SGIR_IRM_MASK ULL(0x1)
|
||||
#define SGIR_AFF3_SHIFT 48
|
||||
#define SGIR_AFF_MASK ULL(0xff)
|
||||
|
||||
#define SGIR_IRM_TO_AFF U(0)
|
||||
|
||||
#define GICV3_SGIR_VALUE(_aff3, _aff2, _aff1, _intid, _irm, _tgt) \
|
||||
((((uint64_t) (_aff3) & SGIR_AFF_MASK) << SGIR_AFF3_SHIFT) | \
|
||||
(((uint64_t) (_irm) & SGIR_IRM_MASK) << SGIR_IRM_SHIFT) | \
|
||||
(((uint64_t) (_aff2) & SGIR_AFF_MASK) << SGIR_AFF2_SHIFT) | \
|
||||
(((_intid) & SGIR_INTID_MASK) << SGIR_INTID_SHIFT) | \
|
||||
(((_aff1) & SGIR_AFF_MASK) << SGIR_AFF1_SHIFT) | \
|
||||
((_tgt) & SGIR_TGT_MASK))
|
||||
|
||||
/*****************************************************************************
|
||||
* GICv3 and 3.1 ITS registers and constants
|
||||
*****************************************************************************/
|
||||
#define GITS_CTLR U(0x0)
|
||||
#define GITS_IIDR U(0x4)
|
||||
#define GITS_TYPER U(0x8)
|
||||
#define GITS_CBASER U(0x80)
|
||||
#define GITS_CWRITER U(0x88)
|
||||
#define GITS_CREADR U(0x90)
|
||||
#define GITS_BASER U(0x100)
|
||||
|
||||
/* GITS_CTLR bit definitions */
|
||||
#define GITS_CTLR_ENABLED_BIT BIT_32(0)
|
||||
#define GITS_CTLR_QUIESCENT_BIT BIT_32(1)
|
||||
|
||||
#define GITS_TYPER_VSGI BIT_64(39)
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <arch_helpers.h>
|
||||
#include <common/interrupt_props.h>
|
||||
#include <drivers/arm/gic_common.h>
|
||||
#include <lib/utils_def.h>
|
||||
|
||||
typedef enum {
|
||||
GICV3_G1S,
|
||||
GICV3_G1NS,
|
||||
GICV3_G0
|
||||
} gicv3_irq_group_t;
|
||||
|
||||
static inline uintptr_t gicv3_redist_size(uint64_t typer_val)
|
||||
{
|
||||
#if GIC_ENABLE_V4_EXTN
|
||||
if ((typer_val & TYPER_VLPI_BIT) != 0U) {
|
||||
return 1U << GICR_V4_PCPUBASE_SHIFT;
|
||||
} else {
|
||||
return 1U << GICR_V3_PCPUBASE_SHIFT;
|
||||
}
|
||||
#else
|
||||
return 1U << GICR_V3_PCPUBASE_SHIFT;
|
||||
#endif
|
||||
}
|
||||
|
||||
unsigned int gicv3_get_component_partnum(const uintptr_t gic_frame);
|
||||
|
||||
static inline bool gicv3_is_intr_id_special_identifier(unsigned int id)
|
||||
{
|
||||
return (id >= PENDING_G1S_INTID) && (id <= GIC_SPURIOUS_INTERRUPT);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Helper GICv3 and 3.1 macros for SEL1
|
||||
******************************************************************************/
|
||||
static inline uint32_t gicv3_acknowledge_interrupt_sel1(void)
|
||||
{
|
||||
return (uint32_t)read_icc_iar1_el1() & IAR1_EL1_INTID_MASK;
|
||||
}
|
||||
|
||||
static inline uint32_t gicv3_get_pending_interrupt_id_sel1(void)
|
||||
{
|
||||
return (uint32_t)read_icc_hppir1_el1() & HPPIR1_EL1_INTID_MASK;
|
||||
}
|
||||
|
||||
static inline void gicv3_end_of_interrupt_sel1(unsigned int id)
|
||||
{
|
||||
/*
|
||||
* Interrupt request deassertion from peripheral to GIC happens
|
||||
* by clearing interrupt condition by a write to the peripheral
|
||||
* register. It is desired that the write transfer is complete
|
||||
* before the core tries to change GIC state from 'AP/Active' to
|
||||
* a new state on seeing 'EOI write'.
|
||||
* Since ICC interface writes are not ordered against Device
|
||||
* memory writes, a barrier is required to ensure the ordering.
|
||||
* The dsb will also ensure *completion* of previous writes with
|
||||
* DEVICE nGnRnE attribute.
|
||||
*/
|
||||
dsbishst();
|
||||
write_icc_eoir1_el1(id);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Helper GICv3 macros for EL3
|
||||
******************************************************************************/
|
||||
static inline uint32_t gicv3_acknowledge_interrupt(void)
|
||||
{
|
||||
return (uint32_t)read_icc_iar0_el1() & IAR0_EL1_INTID_MASK;
|
||||
}
|
||||
|
||||
static inline void gicv3_end_of_interrupt(unsigned int id)
|
||||
{
|
||||
/*
|
||||
* Interrupt request deassertion from peripheral to GIC happens
|
||||
* by clearing interrupt condition by a write to the peripheral
|
||||
* register. It is desired that the write transfer is complete
|
||||
* before the core tries to change GIC state from 'AP/Active' to
|
||||
* a new state on seeing 'EOI write'.
|
||||
* Since ICC interface writes are not ordered against Device
|
||||
* memory writes, a barrier is required to ensure the ordering.
|
||||
* The dsb will also ensure *completion* of previous writes with
|
||||
* DEVICE nGnRnE attribute.
|
||||
*/
|
||||
dsbishst();
|
||||
return write_icc_eoir0_el1(id);
|
||||
}
|
||||
|
||||
/*
|
||||
* This macro returns the total number of GICD/GICR registers corresponding to
|
||||
* the register name
|
||||
*/
|
||||
#define GICD_NUM_REGS(reg_name) \
|
||||
DIV_ROUND_UP_2EVAL(TOTAL_SHARED_INTR_NUM, (1 << reg_name##_SHIFT))
|
||||
|
||||
#define GICR_NUM_REGS(reg_name) \
|
||||
DIV_ROUND_UP_2EVAL(TOTAL_PRIVATE_INTR_NUM, (1 << reg_name##_SHIFT))
|
||||
|
||||
/* Interrupt ID mask for HPPIR, AHPPIR, IAR and AIAR CPU Interface registers */
|
||||
#define INT_ID_MASK U(0xffffff)
|
||||
|
||||
/*******************************************************************************
|
||||
* This structure describes some of the implementation defined attributes of the
|
||||
* GICv3 IP. It is used by the platform port to specify these attributes in order
|
||||
* to initialise the GICV3 driver. The attributes are described below.
|
||||
*
|
||||
* The 'gicd_base' field contains the base address of the Distributor interface
|
||||
* programmer's view.
|
||||
*
|
||||
* The 'gicr_base' field contains the base address of the Re-distributor
|
||||
* interface programmer's view.
|
||||
*
|
||||
* The 'interrupt_props' field is a pointer to an array that enumerates secure
|
||||
* interrupts and their properties. If this field is not NULL, both
|
||||
* 'g0_interrupt_array' and 'g1s_interrupt_array' fields are ignored.
|
||||
*
|
||||
* The 'interrupt_props_num' field contains the number of entries in the
|
||||
* 'interrupt_props' array. If this field is non-zero, both 'g0_interrupt_num'
|
||||
* and 'g1s_interrupt_num' are ignored.
|
||||
*
|
||||
* The 'rdistif_num' field contains the number of Redistributor interfaces the
|
||||
* GIC implements. This is equal to the number of CPUs or CPU interfaces
|
||||
* instantiated in the GIC.
|
||||
*
|
||||
* The 'rdistif_base_addrs' field is a pointer to an array that has an entry for
|
||||
* storing the base address of the Redistributor interface frame of each CPU in
|
||||
* the system. The size of the array = 'rdistif_num'. The base addresses are
|
||||
* detected during driver initialisation.
|
||||
*
|
||||
* The 'mpidr_to_core_pos' field is a pointer to a hash function which the
|
||||
* driver will use to convert an MPIDR value to a linear core index. This index
|
||||
* will be used for accessing the 'rdistif_base_addrs' array. This is an
|
||||
* optional field. A GICv3 implementation maps each MPIDR to a linear core index
|
||||
* as well. This mapping can be found by reading the "Affinity Value" and
|
||||
* "Processor Number" fields in the GICR_TYPER. It is IMP. DEF. if the
|
||||
* "Processor Numbers" are suitable to index into an array to access core
|
||||
* specific information. If this not the case, the platform port must provide a
|
||||
* hash function. Otherwise, the "Processor Number" field will be used to access
|
||||
* the array elements.
|
||||
******************************************************************************/
|
||||
typedef unsigned int (*mpidr_hash_fn)(u_register_t mpidr);
|
||||
|
||||
typedef struct gicv3_driver_data {
|
||||
uintptr_t gicd_base;
|
||||
uintptr_t gicr_base;
|
||||
const interrupt_prop_t *interrupt_props;
|
||||
unsigned int interrupt_props_num;
|
||||
unsigned int rdistif_num;
|
||||
uintptr_t *rdistif_base_addrs;
|
||||
mpidr_hash_fn mpidr_to_core_pos;
|
||||
} gicv3_driver_data_t;
|
||||
|
||||
typedef struct gicv3_redist_ctx {
|
||||
/* 64 bits registers */
|
||||
uint64_t gicr_propbaser;
|
||||
uint64_t gicr_pendbaser;
|
||||
|
||||
/* 32 bits registers */
|
||||
uint32_t gicr_ctlr;
|
||||
uint32_t gicr_igroupr[GICR_NUM_REGS(IGROUPR)];
|
||||
uint32_t gicr_isenabler[GICR_NUM_REGS(ISENABLER)];
|
||||
uint32_t gicr_ispendr[GICR_NUM_REGS(ISPENDR)];
|
||||
uint32_t gicr_isactiver[GICR_NUM_REGS(ISACTIVER)];
|
||||
uint32_t gicr_ipriorityr[GICR_NUM_REGS(IPRIORITYR)];
|
||||
uint32_t gicr_icfgr[GICR_NUM_REGS(ICFGR)];
|
||||
uint32_t gicr_igrpmodr[GICR_NUM_REGS(IGRPMODR)];
|
||||
uint32_t gicr_nsacr;
|
||||
} gicv3_redist_ctx_t;
|
||||
|
||||
typedef struct gicv3_dist_ctx {
|
||||
/* 64 bits registers */
|
||||
uint64_t gicd_irouter[TOTAL_SHARED_INTR_NUM];
|
||||
|
||||
/* 32 bits registers */
|
||||
uint32_t gicd_ctlr;
|
||||
uint32_t gicd_igroupr[GICD_NUM_REGS(IGROUPR)];
|
||||
uint32_t gicd_isenabler[GICD_NUM_REGS(ISENABLER)];
|
||||
uint32_t gicd_ispendr[GICD_NUM_REGS(ISPENDR)];
|
||||
uint32_t gicd_isactiver[GICD_NUM_REGS(ISACTIVER)];
|
||||
uint32_t gicd_ipriorityr[GICD_NUM_REGS(IPRIORITYR)];
|
||||
uint32_t gicd_icfgr[GICD_NUM_REGS(ICFGR)];
|
||||
uint32_t gicd_igrpmodr[GICD_NUM_REGS(IGRPMODR)];
|
||||
uint32_t gicd_nsacr[GICD_NUM_REGS(NSACR)];
|
||||
} gicv3_dist_ctx_t;
|
||||
|
||||
typedef struct gicv3_its_ctx {
|
||||
/* 64 bits registers */
|
||||
uint64_t gits_cbaser;
|
||||
uint64_t gits_cwriter;
|
||||
uint64_t gits_baser[8];
|
||||
|
||||
/* 32 bits registers */
|
||||
uint32_t gits_ctlr;
|
||||
} gicv3_its_ctx_t;
|
||||
|
||||
/*******************************************************************************
|
||||
* GICv3 EL3 driver API
|
||||
******************************************************************************/
|
||||
void gicv3_driver_init(const gicv3_driver_data_t *plat_driver_data);
|
||||
int gicv3_rdistif_probe(const uintptr_t gicr_frame);
|
||||
void gicv3_distif_init(void);
|
||||
void gicv3_rdistif_init(unsigned int proc_num);
|
||||
void gicv3_rdistif_on(unsigned int proc_num);
|
||||
void gicv3_rdistif_off(unsigned int proc_num);
|
||||
unsigned int gicv3_rdistif_get_number_frames(const uintptr_t gicr_frame);
|
||||
void gicv3_cpuif_enable(unsigned int proc_num);
|
||||
void gicv3_cpuif_disable(unsigned int proc_num);
|
||||
unsigned int gicv3_get_pending_interrupt_type(void);
|
||||
unsigned int gicv3_get_pending_interrupt_id(void);
|
||||
unsigned int gicv3_get_interrupt_type(unsigned int id,
|
||||
unsigned int proc_num);
|
||||
void gicv3_distif_init_restore(const gicv3_dist_ctx_t * const dist_ctx);
|
||||
void gicv3_distif_save(gicv3_dist_ctx_t * const dist_ctx);
|
||||
/*
|
||||
* gicv3_distif_post_restore and gicv3_distif_pre_save must be implemented if
|
||||
* gicv3_distif_save and gicv3_rdistif_init_restore are used. If no
|
||||
* implementation-defined sequence is needed at these steps, an empty function
|
||||
* can be provided.
|
||||
*/
|
||||
void gicv3_distif_post_restore(unsigned int proc_num);
|
||||
void gicv3_distif_pre_save(unsigned int proc_num);
|
||||
void gicv3_rdistif_init_restore(unsigned int proc_num, const gicv3_redist_ctx_t * const rdist_ctx);
|
||||
void gicv3_rdistif_save(unsigned int proc_num, gicv3_redist_ctx_t * const rdist_ctx);
|
||||
void gicv3_its_save_disable(uintptr_t gits_base, gicv3_its_ctx_t * const its_ctx);
|
||||
void gicv3_its_restore(uintptr_t gits_base, const gicv3_its_ctx_t * const its_ctx);
|
||||
|
||||
unsigned int gicv3_get_running_priority(void);
|
||||
unsigned int gicv3_get_interrupt_active(unsigned int id, unsigned int proc_num);
|
||||
void gicv3_enable_interrupt(unsigned int id, unsigned int proc_num);
|
||||
void gicv3_disable_interrupt(unsigned int id, unsigned int proc_num);
|
||||
void gicv3_set_interrupt_priority(unsigned int id, unsigned int proc_num,
|
||||
unsigned int priority);
|
||||
void gicv3_set_interrupt_type(unsigned int id, unsigned int proc_num,
|
||||
unsigned int type);
|
||||
void gicv3_raise_sgi(unsigned int sgi_num, gicv3_irq_group_t group,
|
||||
u_register_t target);
|
||||
void gicv3_set_spi_routing(unsigned int id, unsigned int irm,
|
||||
u_register_t mpidr);
|
||||
void gicv3_set_interrupt_pending(unsigned int id, unsigned int proc_num);
|
||||
void gicv3_clear_interrupt_pending(unsigned int id, unsigned int proc_num);
|
||||
unsigned int gicv3_set_pmr(unsigned int mask);
|
||||
|
||||
void gicv3_get_component_prodid_rev(const uintptr_t gicd_base,
|
||||
unsigned int *gic_prod_id,
|
||||
uint8_t *gic_rev);
|
||||
void gicv3_check_erratas_applies(const uintptr_t gicd_base);
|
||||
#if GIC600_ERRATA_WA_2384374
|
||||
void gicv3_apply_errata_wa_2384374(const uintptr_t gicr_base);
|
||||
#else
|
||||
static inline void gicv3_apply_errata_wa_2384374(const uintptr_t gicr_base)
|
||||
{
|
||||
}
|
||||
#endif /* GIC600_ERRATA_WA_2384374 */
|
||||
|
||||
#endif /* __ASSEMBLER__ */
|
||||
#endif /* GICV3_H */
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Arm Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef MHU_H
|
||||
#define MHU_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/**
|
||||
* Generic MHU error enumeration types.
|
||||
*/
|
||||
enum mhu_error_t {
|
||||
MHU_ERR_NONE = 0,
|
||||
MHU_ERR_NOT_INIT = -1,
|
||||
MHU_ERR_ALREADY_INIT = -2,
|
||||
MHU_ERR_UNSUPPORTED_VERSION = -3,
|
||||
MHU_ERR_UNSUPPORTED = -4,
|
||||
MHU_ERR_INVALID_ARG = -5,
|
||||
MHU_ERR_BUFFER_TOO_SMALL = -6,
|
||||
MHU_ERR_GENERAL = -7,
|
||||
};
|
||||
|
||||
/**
|
||||
* Initializes sender MHU.
|
||||
*
|
||||
* mhu_sender_base Base address of sender MHU.
|
||||
*
|
||||
* Returns mhu_error_t error code.
|
||||
*
|
||||
* This function must be called before mhu_send_data().
|
||||
*/
|
||||
enum mhu_error_t mhu_init_sender(uintptr_t mhu_sender_base);
|
||||
|
||||
|
||||
/**
|
||||
* Initializes receiver MHU.
|
||||
*
|
||||
* mhu_receiver_base Base address of receiver MHU.
|
||||
*
|
||||
* Returns mhu_error_t error code.
|
||||
*
|
||||
* This function must be called before mhu_receive_data().
|
||||
*/
|
||||
enum mhu_error_t mhu_init_receiver(uintptr_t mhu_receiver_base);
|
||||
|
||||
/**
|
||||
* Sends data over MHU.
|
||||
*
|
||||
* send_buffer Pointer to buffer containing the data to be transmitted.
|
||||
* size Size of the data to be transmitted in bytes.
|
||||
*
|
||||
* Returns mhu_error_t error code.
|
||||
*
|
||||
* The send_buffer must be 4-byte aligned and its length must be at least
|
||||
* (4 - (size % 4)) bytes bigger than the data size to prevent buffer
|
||||
* over-reading.
|
||||
*/
|
||||
enum mhu_error_t mhu_send_data(const uint8_t *send_buffer, size_t size);
|
||||
|
||||
/**
|
||||
* Receives data from MHU.
|
||||
*
|
||||
* receive_buffer Pointer the buffer where to store the received data.
|
||||
* size As input the size of the receive_buffer, as output the
|
||||
* number of bytes received. As a limitation,
|
||||
* the size of the buffer must be a multiple of 4.
|
||||
*
|
||||
* Returns mhu_error_t error code.
|
||||
*
|
||||
* The receive_buffer must be 4-byte aligned and its length must be a
|
||||
* multiple of 4.
|
||||
*/
|
||||
enum mhu_error_t mhu_receive_data(uint8_t *receive_buffer, size_t *size);
|
||||
|
||||
/**
|
||||
* Gets the maximum amount of bytes that can be transmitted in a single send by MHU.
|
||||
*
|
||||
* Returns The amount of bytes that can be sent or received in a single message.
|
||||
*/
|
||||
size_t mhu_get_max_message_size(void);
|
||||
|
||||
#endif /* MHU_H */
|
||||
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef NIC_400_H
|
||||
#define NIC_400_H
|
||||
|
||||
/*
|
||||
* Address of slave 'n' security setting in the NIC-400 address region
|
||||
* control
|
||||
*/
|
||||
#define NIC400_ADDR_CTRL_SECURITY_REG(n) (0x8 + (n) * 4)
|
||||
|
||||
#endif /* NIC_400_H */
|
||||
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef PL011_H
|
||||
#define PL011_H
|
||||
|
||||
#include <drivers/console.h>
|
||||
|
||||
/* PL011 Registers */
|
||||
#define UARTDR 0x000
|
||||
#define UARTRSR 0x004
|
||||
#define UARTECR 0x004
|
||||
#define UARTFR 0x018
|
||||
#define UARTIMSC 0x038
|
||||
#define UARTRIS 0x03C
|
||||
#define UARTICR 0x044
|
||||
|
||||
/* PL011 registers (out of the SBSA specification) */
|
||||
#if !PL011_GENERIC_UART
|
||||
#define UARTILPR 0x020
|
||||
#define UARTIBRD 0x024
|
||||
#define UARTFBRD 0x028
|
||||
#define UARTLCR_H 0x02C
|
||||
#define UARTCR 0x030
|
||||
#define UARTIFLS 0x034
|
||||
#define UARTMIS 0x040
|
||||
#define UARTDMACR 0x048
|
||||
#endif /* !PL011_GENERIC_UART */
|
||||
|
||||
/* Data status bits */
|
||||
#define UART_DATA_ERROR_MASK 0x0F00
|
||||
|
||||
/* Status reg bits */
|
||||
#define UART_STATUS_ERROR_MASK 0x0F
|
||||
|
||||
/* Flag reg bits */
|
||||
#define PL011_UARTFR_RI (1 << 8) /* Ring indicator */
|
||||
#define PL011_UARTFR_TXFE (1 << 7) /* Transmit FIFO empty */
|
||||
#define PL011_UARTFR_RXFF (1 << 6) /* Receive FIFO full */
|
||||
#define PL011_UARTFR_TXFF (1 << 5) /* Transmit FIFO full */
|
||||
#define PL011_UARTFR_RXFE (1 << 4) /* Receive FIFO empty */
|
||||
#define PL011_UARTFR_BUSY (1 << 3) /* UART busy */
|
||||
#define PL011_UARTFR_DCD (1 << 2) /* Data carrier detect */
|
||||
#define PL011_UARTFR_DSR (1 << 1) /* Data set ready */
|
||||
#define PL011_UARTFR_CTS (1 << 0) /* Clear to send */
|
||||
|
||||
#define PL011_UARTFR_TXFF_BIT 5 /* Transmit FIFO full bit in UARTFR register */
|
||||
#define PL011_UARTFR_RXFE_BIT 4 /* Receive FIFO empty bit in UARTFR register */
|
||||
#define PL011_UARTFR_BUSY_BIT 3 /* UART busy bit in UARTFR register */
|
||||
|
||||
/* Control reg bits */
|
||||
#if !PL011_GENERIC_UART
|
||||
#define PL011_UARTCR_CTSEN (1 << 15) /* CTS hardware flow control enable */
|
||||
#define PL011_UARTCR_RTSEN (1 << 14) /* RTS hardware flow control enable */
|
||||
#define PL011_UARTCR_RTS (1 << 11) /* Request to send */
|
||||
#define PL011_UARTCR_DTR (1 << 10) /* Data transmit ready. */
|
||||
#define PL011_UARTCR_RXE (1 << 9) /* Receive enable */
|
||||
#define PL011_UARTCR_TXE (1 << 8) /* Transmit enable */
|
||||
#define PL011_UARTCR_LBE (1 << 7) /* Loopback enable */
|
||||
#define PL011_UARTCR_UARTEN (1 << 0) /* UART Enable */
|
||||
|
||||
#if !defined(PL011_LINE_CONTROL)
|
||||
/* FIFO Enabled / No Parity / 8 Data bit / One Stop Bit */
|
||||
#define PL011_LINE_CONTROL (PL011_UARTLCR_H_FEN | PL011_UARTLCR_H_WLEN_8)
|
||||
#endif
|
||||
|
||||
/* Line Control Register Bits */
|
||||
#define PL011_UARTLCR_H_SPS (1 << 7) /* Stick parity select */
|
||||
#define PL011_UARTLCR_H_WLEN_8 (3 << 5)
|
||||
#define PL011_UARTLCR_H_WLEN_7 (2 << 5)
|
||||
#define PL011_UARTLCR_H_WLEN_6 (1 << 5)
|
||||
#define PL011_UARTLCR_H_WLEN_5 (0 << 5)
|
||||
#define PL011_UARTLCR_H_FEN (1 << 4) /* FIFOs Enable */
|
||||
#define PL011_UARTLCR_H_STP2 (1 << 3) /* Two stop bits select */
|
||||
#define PL011_UARTLCR_H_EPS (1 << 2) /* Even parity select */
|
||||
#define PL011_UARTLCR_H_PEN (1 << 1) /* Parity Enable */
|
||||
#define PL011_UARTLCR_H_BRK (1 << 0) /* Send break */
|
||||
|
||||
#endif /* !PL011_GENERIC_UART */
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/*
|
||||
* Initialize a new PL011 console instance and register it with the console
|
||||
* framework. The |console| pointer must point to storage that will be valid
|
||||
* for the lifetime of the console, such as a global or static local variable.
|
||||
* Its contents will be reinitialized from scratch.
|
||||
*/
|
||||
int console_pl011_register(uintptr_t baseaddr, uint32_t clock, uint32_t baud,
|
||||
console_t *console);
|
||||
|
||||
#endif /*__ASSEMBLER__*/
|
||||
|
||||
#endif /* PL011_H */
|
||||
@@ -0,0 +1,15 @@
|
||||
/*
|
||||
* Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef PL061_GPIO_H
|
||||
#define PL061_GPIO_H
|
||||
|
||||
#include <drivers/gpio.h>
|
||||
|
||||
void pl061_gpio_register(uintptr_t base_addr, int gpio_dev);
|
||||
void pl061_gpio_init(void);
|
||||
|
||||
#endif /* PL061_GPIO_H */
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user