GK SDK 源码库: XMIPCLinuxV100R005C00SPC030 (kernel/tools/open_source excluded)

This commit is contained in:
lai
2026-09-06 03:52:57 +08:00
commit b1928b41c0
21813 changed files with 4413081 additions and 0 deletions
@@ -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 */
@@ -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 */
@@ -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 */
@@ -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 */
@@ -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
@@ -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 */
@@ -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
@@ -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
@@ -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
@@ -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*/
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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 */
/**
@}
*/
@@ -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
/**
@}
*/
@@ -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
/**
@}
*/
@@ -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
/**
@}
*/
@@ -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
/**
@}
*/
@@ -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
/**
@}
*/
@@ -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 */
/**
@}
*/
@@ -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
/**
@}
*/
@@ -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*/
@@ -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
/**
@}
*/
@@ -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
/**
@}
*/
@@ -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 */
@@ -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