Browse Source
This patch adds the essential AArch32 architecture helpers arch.h and arch_helpers.h and modifies `_types.h` to add AArch32 support. A new build option `ARCH` is defined in the top level makefile to enable the component makefiles to choose the right files based on the Architecture it is being build for. Depending on this flag, either `AARCH32` or `AARCH64` flag is defined by the Makefile. The default value of `ARCH` flag is `aarch64`. The AArch32 build support will be added in a later patch. Change-Id: I405e5fac02db828a55cd25989b572b64cb005241pull/678/head
Soby Mathew
9 years ago
4 changed files with 752 additions and 14 deletions
@ -0,0 +1,408 @@ |
|||
/*
|
|||
* Copyright (c) 2016, ARM Limited and Contributors. All rights reserved. |
|||
* |
|||
* Redistribution and use in source and binary forms, with or without |
|||
* modification, are permitted provided that the following conditions are met: |
|||
* |
|||
* Redistributions of source code must retain the above copyright notice, this |
|||
* list of conditions and the following disclaimer. |
|||
* |
|||
* Redistributions in binary form must reproduce the above copyright notice, |
|||
* this list of conditions and the following disclaimer in the documentation |
|||
* and/or other materials provided with the distribution. |
|||
* |
|||
* Neither the name of ARM nor the names of its contributors may be used |
|||
* to endorse or promote products derived from this software without specific |
|||
* prior written permission. |
|||
* |
|||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
|||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
|||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
|||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE |
|||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
|||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
|||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
|||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
|||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
|||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|||
* POSSIBILITY OF SUCH DAMAGE. |
|||
*/ |
|||
|
|||
#ifndef __ARCH_H__ |
|||
#define __ARCH_H__ |
|||
|
|||
/*******************************************************************************
|
|||
* MIDR bit definitions |
|||
******************************************************************************/ |
|||
#define MIDR_IMPL_MASK 0xff |
|||
#define MIDR_IMPL_SHIFT 24 |
|||
#define MIDR_VAR_SHIFT 20 |
|||
#define MIDR_VAR_BITS 4 |
|||
#define MIDR_REV_SHIFT 0 |
|||
#define MIDR_REV_BITS 4 |
|||
#define MIDR_PN_MASK 0xfff |
|||
#define MIDR_PN_SHIFT 4 |
|||
|
|||
/*******************************************************************************
|
|||
* MPIDR macros |
|||
******************************************************************************/ |
|||
#define MPIDR_CPU_MASK MPIDR_AFFLVL_MASK |
|||
#define MPIDR_CLUSTER_MASK (MPIDR_AFFLVL_MASK << MPIDR_AFFINITY_BITS) |
|||
#define MPIDR_AFFINITY_BITS 8 |
|||
#define MPIDR_AFFLVL_MASK 0xff |
|||
#define MPIDR_AFFLVL_SHIFT 3 |
|||
#define MPIDR_AFF0_SHIFT 0 |
|||
#define MPIDR_AFF1_SHIFT 8 |
|||
#define MPIDR_AFF2_SHIFT 16 |
|||
#define MPIDR_AFFINITY_MASK 0x00ffffff |
|||
#define MPIDR_AFFLVL0 0 |
|||
#define MPIDR_AFFLVL1 1 |
|||
#define MPIDR_AFFLVL2 2 |
|||
|
|||
#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) |
|||
|
|||
/*
|
|||
* 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 2 |
|||
|
|||
/* Data Cache set/way op type defines */ |
|||
#define DC_OP_ISW 0x0 |
|||
#define DC_OP_CISW 0x1 |
|||
#define DC_OP_CSW 0x2 |
|||
|
|||
/*******************************************************************************
|
|||
* Generic timer memory mapped registers & offsets |
|||
******************************************************************************/ |
|||
#define CNTCR_OFF 0x000 |
|||
#define CNTFID_OFF 0x020 |
|||
|
|||
#define CNTCR_EN (1 << 0) |
|||
#define CNTCR_HDBG (1 << 1) |
|||
#define CNTCR_FCREQ(x) ((x) << 8) |
|||
|
|||
/*******************************************************************************
|
|||
* System register bit definitions |
|||
******************************************************************************/ |
|||
/* CLIDR definitions */ |
|||
#define LOUIS_SHIFT 21 |
|||
#define LOC_SHIFT 24 |
|||
#define CLIDR_FIELD_WIDTH 3 |
|||
|
|||
/* CSSELR definitions */ |
|||
#define LEVEL_SHIFT 1 |
|||
|
|||
/* ID_PFR1 definitions */ |
|||
#define ID_PFR1_VIRTEXT_SHIFT 12 |
|||
#define ID_PFR1_VIRTEXT_MASK 0xf |
|||
#define GET_VIRT_EXT(id) (((id) >> ID_PFR1_VIRTEXT_SHIFT) \ |
|||
& ID_PFR1_VIRTEXT_MASK) |
|||
#define ID_PFR1_GIC_SHIFT 28 |
|||
#define ID_PFR1_GIC_MASK 0xf |
|||
|
|||
/* SCTLR definitions */ |
|||
#define SCTLR_RES1 ((1 << 23) | (1 << 22) | (1 << 11) | (1 << 4) | \ |
|||
(1 << 3) | SCTLR_CP15BEN_BIT | SCTLR_NTWI_BIT | SCTLR_NTWE_BIT) |
|||
#define SCTLR_M_BIT (1 << 0) |
|||
#define SCTLR_A_BIT (1 << 1) |
|||
#define SCTLR_C_BIT (1 << 2) |
|||
#define SCTLR_CP15BEN_BIT (1 << 5) |
|||
#define SCTLR_ITD_BIT (1 << 7) |
|||
#define SCTLR_I_BIT (1 << 12) |
|||
#define SCTLR_V_BIT (1 << 13) |
|||
#define SCTLR_NTWI_BIT (1 << 16) |
|||
#define SCTLR_NTWE_BIT (1 << 18) |
|||
#define SCTLR_WXN_BIT (1 << 19) |
|||
#define SCTLR_UWXN_BIT (1 << 20) |
|||
#define SCTLR_EE_BIT (1 << 25) |
|||
#define SCTLR_TRE_BIT (1 << 28) |
|||
#define SCTLR_AFE_BIT (1 << 29) |
|||
#define SCTLR_TE_BIT (1 << 30) |
|||
|
|||
/* HSCTLR definitions */ |
|||
#define HSCTLR_RES1 ((1 << 29) | (1 << 28) | (1 << 23) | (1 << 22) \ |
|||
| (1 << 18) | (1 << 16) | (1 << 11) | (1 << 4) \ |
|||
| (1 << 3) | HSCTLR_CP15BEN_BIT) |
|||
#define HSCTLR_M_BIT (1 << 0) |
|||
#define HSCTLR_A_BIT (1 << 1) |
|||
#define HSCTLR_C_BIT (1 << 2) |
|||
#define HSCTLR_CP15BEN_BIT (1 << 5) |
|||
#define HSCTLR_ITD_BIT (1 << 7) |
|||
#define HSCTLR_SED_BIT (1 << 8) |
|||
#define HSCTLR_I_BIT (1 << 12) |
|||
#define HSCTLR_WXN_BIT (1 << 19) |
|||
#define HSCTLR_EE_BIT (1 << 25) |
|||
#define HSCTLR_TE_BIT (1 << 30) |
|||
|
|||
/* CPACR definitions */ |
|||
#define CPACR_FPEN(x) ((x) << 20) |
|||
#define CPACR_FP_TRAP_PL0 0x1 |
|||
#define CPACR_FP_TRAP_ALL 0x2 |
|||
#define CPACR_FP_TRAP_NONE 0x3 |
|||
|
|||
/* SCR definitions */ |
|||
#define SCR_TWE_BIT (1 << 13) |
|||
#define SCR_TWI_BIT (1 << 12) |
|||
#define SCR_SIF_BIT (1 << 9) |
|||
#define SCR_HCE_BIT (1 << 8) |
|||
#define SCR_SCD_BIT (1 << 7) |
|||
#define SCR_NET_BIT (1 << 6) |
|||
#define SCR_AW_BIT (1 << 5) |
|||
#define SCR_FW_BIT (1 << 4) |
|||
#define SCR_EA_BIT (1 << 3) |
|||
#define SCR_FIQ_BIT (1 << 2) |
|||
#define SCR_IRQ_BIT (1 << 1) |
|||
#define SCR_NS_BIT (1 << 0) |
|||
#define SCR_VALID_BIT_MASK 0x33ff |
|||
|
|||
#define GET_NS_BIT(scr) ((scr) & SCR_NS_BIT) |
|||
|
|||
/* HCR definitions */ |
|||
#define HCR_AMO_BIT (1 << 5) |
|||
#define HCR_IMO_BIT (1 << 4) |
|||
#define HCR_FMO_BIT (1 << 3) |
|||
|
|||
/* CNTHCTL definitions */ |
|||
#define EVNTEN_BIT (1 << 2) |
|||
#define PL1PCEN_BIT (1 << 1) |
|||
#define PL1PCTEN_BIT (1 << 0) |
|||
|
|||
/* CNTKCTL definitions */ |
|||
#define PL0PTEN_BIT (1 << 9) |
|||
#define PL0VTEN_BIT (1 << 8) |
|||
#define PL0PCTEN_BIT (1 << 0) |
|||
#define PL0VCTEN_BIT (1 << 1) |
|||
#define EVNTEN_BIT (1 << 2) |
|||
#define EVNTDIR_BIT (1 << 3) |
|||
#define EVNTI_SHIFT 4 |
|||
#define EVNTI_MASK 0xf |
|||
|
|||
/* HCPTR definitions */ |
|||
#define TCPAC_BIT (1 << 31) |
|||
#define TTA_BIT (1 << 20) |
|||
#define TCP11_BIT (1 << 10) |
|||
#define TCP10_BIT (1 << 10) |
|||
|
|||
/* NASCR definitions */ |
|||
#define NSASEDIS_BIT (1 << 15) |
|||
#define NASCR_CP11_BIT (1 << 11) |
|||
#define NASCR_CP10_BIT (1 << 10) |
|||
|
|||
/* CPACR definitions */ |
|||
#define ASEDIS_BIT (1 << 31) |
|||
#define TRCDIS_BIT (1 << 28) |
|||
#define CPACR_CP11_SHIFT 22 |
|||
#define CPACR_CP10_SHIFT 20 |
|||
#define CPACR_ENABLE_FP_ACCESS (0x3 << CPACR_CP11_SHIFT |\ |
|||
0x3 << CPACR_CP10_SHIFT) |
|||
|
|||
/* FPEXC definitions */ |
|||
#define FPEXC_EN_BIT (1 << 30) |
|||
|
|||
/* SPSR/CPSR definitions */ |
|||
#define SPSR_FIQ_BIT (1 << 0) |
|||
#define SPSR_IRQ_BIT (1 << 1) |
|||
#define SPSR_ABT_BIT (1 << 2) |
|||
#define SPSR_AIF_SHIFT 6 |
|||
#define SPSR_AIF_MASK 0x7 |
|||
|
|||
#define SPSR_E_SHIFT 9 |
|||
#define SPSR_E_MASK 0x1 |
|||
#define SPSR_E_LITTLE 0 |
|||
#define SPSR_E_BIG 1 |
|||
|
|||
#define SPSR_T_SHIFT 5 |
|||
#define SPSR_T_MASK 0x1 |
|||
#define SPSR_T_ARM 0 |
|||
#define SPSR_T_THUMB 1 |
|||
|
|||
#define SPSR_MODE_SHIFT 0 |
|||
#define SPSR_MODE_MASK 0x7 |
|||
|
|||
|
|||
#define DISABLE_ALL_EXCEPTIONS \ |
|||
(SPSR_FIQ_BIT | SPSR_IRQ_BIT | SPSR_ABT_BIT) |
|||
|
|||
/*
|
|||
* TTBCR definitions |
|||
*/ |
|||
/* The ARM Trusted Firmware uses the long descriptor format */ |
|||
#define TTBCR_EAE_BIT (1 << 31) |
|||
|
|||
#define TTBCR_SH1_NON_SHAREABLE (0x0 << 28) |
|||
#define TTBCR_SH1_OUTER_SHAREABLE (0x2 << 28) |
|||
#define TTBCR_SH1_INNER_SHAREABLE (0x3 << 28) |
|||
|
|||
#define TTBCR_RGN1_OUTER_NC (0x0 << 26) |
|||
#define TTBCR_RGN1_OUTER_WBA (0x1 << 26) |
|||
#define TTBCR_RGN1_OUTER_WT (0x2 << 26) |
|||
#define TTBCR_RGN1_OUTER_WBNA (0x3 << 26) |
|||
|
|||
#define TTBCR_RGN1_INNER_NC (0x0 << 24) |
|||
#define TTBCR_RGN1_INNER_WBA (0x1 << 24) |
|||
#define TTBCR_RGN1_INNER_WT (0x2 << 24) |
|||
#define TTBCR_RGN1_INNER_WBNA (0x3 << 24) |
|||
|
|||
#define TTBCR_EPD1_BIT (1 << 23) |
|||
#define TTBCR_A1_BIT (1 << 22) |
|||
|
|||
#define TTBCR_T1SZ_SHIFT 16 |
|||
#define TTBCR_T1SZ_MASK (0x7) |
|||
|
|||
#define TTBCR_SH0_NON_SHAREABLE (0x0 << 12) |
|||
#define TTBCR_SH0_OUTER_SHAREABLE (0x2 << 12) |
|||
#define TTBCR_SH0_INNER_SHAREABLE (0x3 << 12) |
|||
|
|||
#define TTBCR_RGN0_OUTER_NC (0x0 << 10) |
|||
#define TTBCR_RGN0_OUTER_WBA (0x1 << 10) |
|||
#define TTBCR_RGN0_OUTER_WT (0x2 << 10) |
|||
#define TTBCR_RGN0_OUTER_WBNA (0x3 << 10) |
|||
|
|||
#define TTBCR_RGN0_INNER_NC (0x0 << 8) |
|||
#define TTBCR_RGN0_INNER_WBA (0x1 << 8) |
|||
#define TTBCR_RGN0_INNER_WT (0x2 << 8) |
|||
#define TTBCR_RGN0_INNER_WBNA (0x3 << 8) |
|||
|
|||
#define TTBCR_EPD0_BIT (1 << 7) |
|||
#define TTBCR_T0SZ_SHIFT 0 |
|||
#define TTBCR_T0SZ_MASK (0x7) |
|||
|
|||
#define MODE_RW_SHIFT 0x4 |
|||
#define MODE_RW_MASK 0x1 |
|||
#define MODE_RW_32 0x1 |
|||
|
|||
#define MODE32_SHIFT 0 |
|||
#define MODE32_MASK 0x1f |
|||
#define MODE32_usr 0x10 |
|||
#define MODE32_fiq 0x11 |
|||
#define MODE32_irq 0x12 |
|||
#define MODE32_svc 0x13 |
|||
#define MODE32_mon 0x16 |
|||
#define MODE32_abt 0x17 |
|||
#define MODE32_hyp 0x1a |
|||
#define MODE32_und 0x1b |
|||
#define MODE32_sys 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) |
|||
|
|||
/*
|
|||
* CTR definitions |
|||
*/ |
|||
#define CTR_CWG_SHIFT 24 |
|||
#define CTR_CWG_MASK 0xf |
|||
#define CTR_ERG_SHIFT 20 |
|||
#define CTR_ERG_MASK 0xf |
|||
#define CTR_DMINLINE_SHIFT 16 |
|||
#define CTR_DMINLINE_WIDTH 4 |
|||
#define CTR_DMINLINE_MASK ((1 << 4) - 1) |
|||
#define CTR_L1IP_SHIFT 14 |
|||
#define CTR_L1IP_MASK 0x3 |
|||
#define CTR_IMINLINE_SHIFT 0 |
|||
#define CTR_IMINLINE_MASK 0xf |
|||
|
|||
#define MAX_CACHE_LINE_SIZE 0x800 /* 2KB */ |
|||
|
|||
/*******************************************************************************
|
|||
* Definitions of register offsets and fields in the CNTCTLBase Frame of the |
|||
* system level implementation of the Generic Timer. |
|||
******************************************************************************/ |
|||
#define CNTNSAR 0x4 |
|||
#define CNTNSAR_NS_SHIFT(x) (x) |
|||
|
|||
#define CNTACR_BASE(x) (0x40 + ((x) << 2)) |
|||
#define CNTACR_RPCT_SHIFT 0x0 |
|||
#define CNTACR_RVCT_SHIFT 0x1 |
|||
#define CNTACR_RFRQ_SHIFT 0x2 |
|||
#define CNTACR_RVOFF_SHIFT 0x3 |
|||
#define CNTACR_RWVT_SHIFT 0x4 |
|||
#define CNTACR_RWPT_SHIFT 0x5 |
|||
|
|||
/* MAIR macros */ |
|||
#define MAIR0_ATTR_SET(attr, index) ((attr) << ((index) << 3)) |
|||
#define MAIR1_ATTR_SET(attr, index) ((attr) << (((index) - 3) << 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 MPIDR p15, 0, c0, c0, 5 |
|||
#define MIDR p15, 0, c0, 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_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 TLBIALLIS p15, 0, c8, c3, 0 |
|||
#define TLBIMVA p15, 0, c8, c7, 1 |
|||
#define TLBIMVAA p15, 0, c8, c7, 3 |
|||
#define HSCTLR p15, 4, c1, c0, 0 |
|||
#define HCR p15, 4, c1, c1, 0 |
|||
#define HCPTR p15, 4, c1, c1, 2 |
|||
#define CNTHCTL p15, 4, 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 |
|||
|
|||
/* 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 |
|||
|
|||
/* 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 |
|||
|
|||
#endif /* __ARCH_H__ */ |
@ -0,0 +1,292 @@ |
|||
/*
|
|||
* Copyright (c) 2016, ARM Limited and Contributors. All rights reserved. |
|||
* |
|||
* Redistribution and use in source and binary forms, with or without |
|||
* modification, are permitted provided that the following conditions are met: |
|||
* |
|||
* Redistributions of source code must retain the above copyright notice, this |
|||
* list of conditions and the following disclaimer. |
|||
* |
|||
* Redistributions in binary form must reproduce the above copyright notice, |
|||
* this list of conditions and the following disclaimer in the documentation |
|||
* and/or other materials provided with the distribution. |
|||
* |
|||
* Neither the name of ARM nor the names of its contributors may be used |
|||
* to endorse or promote products derived from this software without specific |
|||
* prior written permission. |
|||
* |
|||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
|||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
|||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
|||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE |
|||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
|||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
|||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
|||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
|||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
|||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|||
* POSSIBILITY OF SUCH DAMAGE. |
|||
*/ |
|||
|
|||
#ifndef __ARCH_HELPERS_H__ |
|||
#define __ARCH_HELPERS_H__ |
|||
|
|||
#include <arch.h> /* for additional register definitions */ |
|||
#include <stdint.h> |
|||
#include <types.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. It works only on Little Endian |
|||
* systems for GCC versions < 4.6. Above GCC 4.6, both Little Endian and |
|||
* Big Endian systems generate the right instruction encoding. |
|||
*/ |
|||
#if !(__GNUC__ > (4) || __GNUC__ == (4) && __GNUC_MINOR__ >= (6)) |
|||
#error "GCC 4.6 or above is required to build AArch32 Trusted Firmware" |
|||
#endif |
|||
|
|||
#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 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 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_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__) |
|||
|
|||
/**********************************************************************
|
|||
* 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); \ |
|||
} |
|||
|
|||
/* 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); |
|||
|
|||
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(dsb, ish) |
|||
DEFINE_SYSOP_TYPE_FUNC(dmb, ish) |
|||
DEFINE_SYSOP_FUNC(isb) |
|||
|
|||
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_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(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(ttbcr, TTBCR) |
|||
DEFINE_COPROCR_RW_FUNCS(ttbr0, TTBR0) |
|||
DEFINE_COPROCR_RW_FUNCS_64(ttbr0, TTBR0_64) |
|||
DEFINE_COPROCR_RW_FUNCS(ttbr1, TTBR1) |
|||
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(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_igrpen1_el3, ICC_MGRPEN1) |
|||
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) |
|||
|
|||
/*
|
|||
* 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) |
|||
|
|||
/*
|
|||
* DC operation prototypes |
|||
*/ |
|||
DEFINE_DCOP_PARAM_FUNC(civac, DCCIMVAC) |
|||
DEFINE_DCOP_PARAM_FUNC(ivac, DCIMVAC) |
|||
DEFINE_DCOP_PARAM_FUNC(cvac, DCCMVAC) |
|||
|
|||
/* Previously defined accessor functions with incomplete register names */ |
|||
#define dsb() dsbsy() |
|||
|
|||
#define IS_IN_SECURE() \ |
|||
(GET_NS_BIT(read_scr()) == 0) |
|||
|
|||
/*
|
|||
* 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))) |
|||
|
|||
/* 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() |
|||
|
|||
#endif /* __ARCH_HELPERS_H__ */ |
Loading…
Reference in new issue