From 031dbb122472175ad6e888f3c6e0a70d1b2e9ac7 Mon Sep 17 00:00:00 2001 From: Soby Mathew Date: Mon, 9 May 2016 17:49:55 +0100 Subject: [PATCH] AArch32: Add essential Arch helpers 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: I405e5fac02db828a55cd25989b572b64cb005241 --- Makefile | 8 + include/lib/aarch32/arch.h | 408 ++++++++++++++++++++++++++++ include/lib/aarch32/arch_helpers.h | 292 ++++++++++++++++++++ include/lib/stdlib/machine/_types.h | 58 +++- 4 files changed, 752 insertions(+), 14 deletions(-) create mode 100644 include/lib/aarch32/arch.h create mode 100644 include/lib/aarch32/arch_helpers.h diff --git a/Makefile b/Makefile index a68335bdd6..eb593a7afe 100644 --- a/Makefile +++ b/Makefile @@ -45,6 +45,8 @@ include ${MAKE_HELPERS_DIRECTORY}build_env.mk # Default values for build configurations ################################################################################ +# The Target build architecture. +ARCH := aarch64 # Build verbosity V := 0 # Debug build @@ -468,6 +470,12 @@ else $(eval $(call add_define,PRELOADED_BL33_BASE)) endif endif +# Define the AARCH32/AARCH64 flag based on the ARCH flag +ifeq (${ARCH},aarch32) + $(eval $(call add_define,AARCH32)) +else + $(eval $(call add_define,AARCH64)) +endif ################################################################################ # Include BL specific makefiles diff --git a/include/lib/aarch32/arch.h b/include/lib/aarch32/arch.h new file mode 100644 index 0000000000..e571ddcb78 --- /dev/null +++ b/include/lib/aarch32/arch.h @@ -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__ */ diff --git a/include/lib/aarch32/arch_helpers.h b/include/lib/aarch32/arch_helpers.h new file mode 100644 index 0000000000..ddf660b11e --- /dev/null +++ b/include/lib/aarch32/arch_helpers.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 /* for additional register definitions */ +#include +#include + +/********************************************************************** + * 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__ */ diff --git a/include/lib/stdlib/machine/_types.h b/include/lib/stdlib/machine/_types.h index 7e993c4c37..fb1083b74f 100644 --- a/include/lib/stdlib/machine/_types.h +++ b/include/lib/stdlib/machine/_types.h @@ -31,6 +31,10 @@ * From: @(#)types.h 8.3 (Berkeley) 1/5/94 * $FreeBSD$ */ +/* + * Portions copyright (c) 2016, ARM Limited and Contributors. + * All rights reserved. + */ #ifndef _MACHINE__TYPES_H_ #define _MACHINE__TYPES_H_ @@ -48,19 +52,56 @@ typedef short __int16_t; typedef unsigned short __uint16_t; typedef int __int32_t; typedef unsigned int __uint32_t; + + +/* + * Standard type definitions which are different in AArch64 and AArch32 + */ +#ifdef AARCH32 +typedef long long __int64_t; +typedef unsigned long long __uint64_t; +typedef __int32_t __critical_t; +typedef __int32_t __intfptr_t; +typedef __int32_t __intptr_t; +typedef __int32_t __ptrdiff_t; /* ptr1 - ptr2 */ +typedef __int32_t __register_t; +typedef __int32_t __segsz_t; /* segment size (in pages) */ +typedef __uint32_t __size_t; /* sizeof() */ +typedef __int32_t __ssize_t; /* byte count or error */ +typedef __uint32_t __uintfptr_t; +typedef __uint32_t __uintptr_t; +typedef __uint32_t __u_register_t; +typedef __uint32_t __vm_offset_t; +typedef __uint32_t __vm_paddr_t; +typedef __uint32_t __vm_size_t; +#elif defined AARCH64 typedef long __int64_t; typedef unsigned long __uint64_t; +typedef __int64_t __critical_t; +typedef __int64_t __intfptr_t; +typedef __int64_t __intptr_t; +typedef __int64_t __ptrdiff_t; /* ptr1 - ptr2 */ +typedef __int64_t __register_t; +typedef __int64_t __segsz_t; /* segment size (in pages) */ +typedef __uint64_t __size_t; /* sizeof() */ +typedef __int64_t __ssize_t; /* byte count or error */ +typedef __uint64_t __uintfptr_t; +typedef __uint64_t __uintptr_t; +typedef __uint64_t __u_register_t; +typedef __uint64_t __vm_offset_t; +typedef __uint64_t __vm_paddr_t; +typedef __uint64_t __vm_size_t; +#else +#error "Only AArch32 or AArch64 supported" +#endif /* AARCH32 */ /* * Standard type definitions. */ typedef __int32_t __clock_t; /* clock()... */ -typedef __int64_t __critical_t; typedef double __double_t; typedef float __float_t; -typedef __int64_t __intfptr_t; typedef __int64_t __intmax_t; -typedef __int64_t __intptr_t; typedef __int32_t __int_fast8_t; typedef __int32_t __int_fast16_t; typedef __int32_t __int_fast32_t; @@ -69,15 +110,8 @@ typedef __int8_t __int_least8_t; typedef __int16_t __int_least16_t; typedef __int32_t __int_least32_t; typedef __int64_t __int_least64_t; -typedef __int64_t __ptrdiff_t; /* ptr1 - ptr2 */ -typedef __int64_t __register_t; -typedef __int64_t __segsz_t; /* segment size (in pages) */ -typedef __uint64_t __size_t; /* sizeof() */ -typedef __int64_t __ssize_t; /* byte count or error */ typedef __int64_t __time_t; /* time()... */ -typedef __uint64_t __uintfptr_t; typedef __uint64_t __uintmax_t; -typedef __uint64_t __uintptr_t; typedef __uint32_t __uint_fast8_t; typedef __uint32_t __uint_fast16_t; typedef __uint32_t __uint_fast32_t; @@ -86,12 +120,8 @@ typedef __uint8_t __uint_least8_t; typedef __uint16_t __uint_least16_t; typedef __uint32_t __uint_least32_t; typedef __uint64_t __uint_least64_t; -typedef __uint64_t __u_register_t; -typedef __uint64_t __vm_offset_t; typedef __int64_t __vm_ooffset_t; -typedef __uint64_t __vm_paddr_t; typedef __uint64_t __vm_pindex_t; -typedef __uint64_t __vm_size_t; /* * Unusual type definitions.