diff options
Diffstat (limited to 'include')
24 files changed, 583 insertions, 115 deletions
diff --git a/include/bl31/interrupt_mgmt.h b/include/bl31/interrupt_mgmt.h index 9a6a7faa7..cccad3add 100644 --- a/include/bl31/interrupt_mgmt.h +++ b/include/bl31/interrupt_mgmt.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2017, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -17,6 +17,11 @@ #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. @@ -93,6 +98,8 @@ #ifndef __ASSEMBLY__ +#include <stdint.h> + /* Prototype for defining a handler for an interrupt type */ typedef uint64_t (*interrupt_type_handler_t)(uint32_t id, uint32_t flags, diff --git a/include/common/interrupt_props.h b/include/common/interrupt_props.h new file mode 100644 index 000000000..9786b40c8 --- /dev/null +++ b/include/common/interrupt_props.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 __ASSEMBLY__ + +/* 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 /* __ASSEMBLY__ */ +#endif /* __INTERRUPT_PROPS_H__ */ diff --git a/include/drivers/arm/gic_common.h b/include/drivers/arm/gic_common.h index b9cae802f..9e126a854 100644 --- a/include/drivers/arm/gic_common.h +++ b/include/drivers/arm/gic_common.h @@ -12,6 +12,7 @@ ******************************************************************************/ /* Constants to categorise interrupts */ #define MIN_SGI_ID 0 +#define MIN_SEC_SGI_ID 8 #define MIN_PPI_ID 16 #define MIN_SPI_ID 32 #define MAX_SPI_ID 1019 @@ -22,9 +23,16 @@ /* Mask for the priority field common to all GIC interfaces */ #define GIC_PRI_MASK 0xff +/* Mask for the configuration field common to all GIC interfaces */ +#define GIC_CFG_MASK 0x3 + /* Constant to indicate a spurious interrupt in all GIC versions */ #define GIC_SPURIOUS_INTERRUPT 1023 +/* Interrupt configurations */ +#define GIC_INTR_CFG_LEVEL 0 +#define GIC_INTR_CFG_EDGE 1 + /* Constants to categorise priorities */ #define GIC_HIGHEST_SEC_PRIORITY 0 #define GIC_LOWEST_SEC_PRIORITY 127 @@ -73,6 +81,7 @@ #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 diff --git a/include/drivers/arm/gic_v2.h b/include/drivers/arm/gic_v2.h index 3a3d7aaa3..258b89812 100644 --- a/include/drivers/arm/gic_v2.h +++ b/include/drivers/arm/gic_v2.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -7,6 +7,9 @@ #ifndef __GIC_V2_H__ #define __GIC_V2_H__ +/* The macros required here are additional to those in gic_common.h. */ +#include <gic_common.h> + /****************************************************************************** * THIS DRIVER IS DEPRECATED. For GICv2 systems, use the driver in gicv2.h * and for GICv3 systems, use the driver in gicv3.h. @@ -19,50 +22,20 @@ #define MAX_PPIS U(14) #define MAX_SGIS U(16) -#define MIN_SGI_ID U(0) -#define MIN_PPI_ID U(16) -#define MIN_SPI_ID U(32) #define GRP0 U(0) #define GRP1 U(1) -#define GIC_PRI_MASK U(0xff) -#define GIC_HIGHEST_SEC_PRIORITY U(0) -#define GIC_LOWEST_SEC_PRIORITY U(127) -#define GIC_HIGHEST_NS_PRIORITY U(128) -#define GIC_LOWEST_NS_PRIORITY U(254) /* 255 would disable an interrupt */ -#define GIC_SPURIOUS_INTERRUPT U(1023) #define GIC_TARGET_CPU_MASK U(0xff) #define ENABLE_GRP0 (U(1) << 0) #define ENABLE_GRP1 (U(1) << 1) /* Distributor interface definitions */ -#define GICD_CTLR U(0x0) -#define GICD_TYPER U(0x4) -#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_ITARGETSR U(0x800) -#define GICD_ICFGR U(0xC00) #define GICD_SGIR U(0xF00) #define GICD_CPENDSGIR U(0xF10) #define GICD_SPENDSGIR U(0xF20) -#define IGROUPR_SHIFT U(5) -#define ISENABLER_SHIFT U(5) -#define ICENABLER_SHIFT ISENABLER_SHIFT -#define ISPENDR_SHIFT U(5) -#define ICPENDR_SHIFT ISPENDR_SHIFT -#define ISACTIVER_SHIFT U(5) -#define ICACTIVER_SHIFT ISACTIVER_SHIFT -#define IPRIORITYR_SHIFT U(2) -#define ITARGETSR_SHIFT U(2) -#define ICFGR_SHIFT U(4) #define CPENDSGIR_SHIFT U(2) #define SPENDSGIR_SHIFT CPENDSGIR_SHIFT diff --git a/include/drivers/arm/gicv2.h b/include/drivers/arm/gicv2.h index a78802545..6e8322e1b 100644 --- a/include/drivers/arm/gicv2.h +++ b/include/drivers/arm/gicv2.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -10,9 +10,17 @@ /******************************************************************************* * GICv2 miscellaneous definitions ******************************************************************************/ + +/* Interrupt group definitions */ +#define GICV2_INTR_GROUP0 0 +#define GICV2_INTR_GROUP1 1 + /* Interrupt IDs reported by the HPPIR and IAR registers */ #define PENDING_G1_INTID 1022 +/* GICv2 can only target up to 8 PEs */ +#define GICV2_MAX_TARGET_PE 8 + /******************************************************************************* * GICv2 specific Distributor interface register offsets and constants. ******************************************************************************/ @@ -28,6 +36,19 @@ #define CPENDSGIR_SHIFT 2 #define SPENDSGIR_SHIFT CPENDSGIR_SHIFT +#define SGIR_TGTLSTFLT_SHIFT 24 +#define SGIR_TGTLSTFLT_MASK 0x3 +#define SGIR_TGTLST_SHIFT 16 +#define SGIR_TGTLST_MASK 0xff +#define SGIR_INTID_MASK 0xf + +#define SGIR_TGT_SPECIFIC 0 + +#define GICV2_SGIR_VALUE(tgt_lst_flt, tgt, intid) \ + ((((tgt_lst_flt) & SGIR_TGTLSTFLT_MASK) << SGIR_TGTLSTFLT_SHIFT) | \ + (((tgt) & SGIR_TGTLST_MASK) << SGIR_TGTLST_SHIFT) | \ + ((intid) & SGIR_INTID_MASK)) + /******************************************************************************* * GICv2 specific CPU interface register offsets and constants. ******************************************************************************/ @@ -95,6 +116,7 @@ #ifndef __ASSEMBLY__ +#include <interrupt_props.h> #include <stdint.h> /******************************************************************************* @@ -103,23 +125,43 @@ * in order to initialize the GICv2 driver. The attributes are described * below. * - * 1. The 'gicd_base' field contains the base address of the Distributor - * interface programmer's view. + * 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 'g0_interrupt_array' field is a pointer to an array in which each entry + * corresponds to an ID of a Group 0 interrupt. This field is ignored when + * 'interrupt_props' field is used. This field is deprecated. + * + * The 'g0_interrupt_num' field contains the number of entries in the + * 'g0_interrupt_array'. This field is ignored when 'interrupt_props' field is + * used. This field is deprecated. * - * 2. 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. * - * 3. The 'g0_interrupt_array' field is a pointer to an array in which each - * entry corresponds to an ID of a Group 0 interrupt. + * 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. * - * 4. The 'g0_interrupt_num' field contains the number of entries in the - * 'g0_interrupt_array'. + * 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; +#if !ERROR_DEPRECATED unsigned int g0_interrupt_num; const unsigned int *g0_interrupt_array; +#endif + unsigned int *target_masks; + unsigned int target_masks_num; + const interrupt_prop_t *interrupt_props; + unsigned int interrupt_props_num; } gicv2_driver_data_t; /******************************************************************************* @@ -136,6 +178,18 @@ 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, 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); #endif /* __ASSEMBLY__ */ #endif /* __GICV2_H__ */ diff --git a/include/drivers/arm/gicv3.h b/include/drivers/arm/gicv3.h index c52fe4833..b2e4d4c5e 100644 --- a/include/drivers/arm/gicv3.h +++ b/include/drivers/arm/gicv3.h @@ -7,8 +7,6 @@ #ifndef __GICV3_H__ #define __GICV3_H__ -#include "utils_def.h" - /******************************************************************************* * GICv3 miscellaneous definitions ******************************************************************************/ @@ -24,6 +22,9 @@ /* Constant to categorize LPI interrupt */ #define MIN_LPI_ID 8192 +/* GICv3 can only target up to 16 PEs with SGI */ +#define GICV3_MAX_SGI_TARGETS 16 + /******************************************************************************* * GICv3 specific Distributor interface register offsets and constants. ******************************************************************************/ @@ -72,6 +73,9 @@ #define IROUTER_IRM_SHIFT 31 #define IROUTER_IRM_MASK 0x1 +#define GICV3_IRM_PE 0 +#define GICV3_IRM_ANY 1 + #define NUM_OF_DIST_REGS 30 /******************************************************************************* @@ -165,6 +169,27 @@ #define IAR1_EL1_INTID_SHIFT 0 #define IAR1_EL1_INTID_MASK 0xffffff +/* ICC SGI macros */ +#define SGIR_TGT_MASK 0xffff +#define SGIR_AFF1_SHIFT 16 +#define SGIR_INTID_SHIFT 24 +#define SGIR_INTID_MASK 0xf +#define SGIR_AFF2_SHIFT 32 +#define SGIR_IRM_SHIFT 40 +#define SGIR_IRM_MASK 0x1 +#define SGIR_AFF3_SHIFT 48 +#define SGIR_AFF_MASK 0xf + +#define SGIR_IRM_TO_AFF 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 ITS registers and constants *****************************************************************************/ @@ -185,6 +210,7 @@ #ifndef __ASSEMBLY__ #include <gic_common.h> +#include <interrupt_props.h> #include <stdint.h> #include <types.h> #include <utils_def.h> @@ -224,53 +250,70 @@ * 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. * - * 1. The 'gicd_base' field contains the base address of the Distributor - * interface programmer's view. + * The 'gicd_base' field contains the base address of the Distributor interface + * programmer's view. * - * 2. The 'gicr_base' field contains the base address of the Re-distributor - * interface programmer's view. + * The 'gicr_base' field contains the base address of the Re-distributor + * interface programmer's view. * - * 3. The 'g0_interrupt_array' field is a ponter to an array in which each - * entry corresponds to an ID of a Group 0 interrupt. + * The 'g0_interrupt_array' field is a pointer to an array in which each entry + * corresponds to an ID of a Group 0 interrupt. This field is ignored when + * 'interrupt_props' field is used. This field is deprecated. * - * 4. The 'g0_interrupt_num' field contains the number of entries in the - * 'g0_interrupt_array'. + * The 'g0_interrupt_num' field contains the number of entries in the + * 'g0_interrupt_array'. This field is ignored when 'interrupt_props' field is + * used. This field is deprecated. * - * 5. The 'g1s_interrupt_array' field is a ponter to an array in which each - * entry corresponds to an ID of a Group 1 interrupt. + * The 'g1s_interrupt_array' field is a pointer to an array in which each entry + * corresponds to an ID of a Group 1 interrupt. This field is ignored when + * 'interrupt_props' field is used. This field is deprecated. * - * 6. The 'g1s_interrupt_num' field contains the number of entries in the - * 'g1s_interrupt_array'. + * The 'g1s_interrupt_num' field contains the number of entries in the + * 'g1s_interrupt_array'. This field must be 0 if 'interrupt_props' field is + * used. This field is ignored when 'interrupt_props' field is used. This field + * is deprecated. * - * 7. 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 '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. * - * 8. 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 '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. * - * 9. 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. + * 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; +#if !ERROR_DEPRECATED unsigned int g0_interrupt_num; unsigned int g1s_interrupt_num; const unsigned int *g0_interrupt_array; const unsigned int *g1s_interrupt_array; +#endif + 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; @@ -349,5 +392,20 @@ void gicv3_rdistif_save(unsigned int proc_num, gicv3_redist_ctx_t * const rdist_ 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 group); +void gicv3_raise_secure_g0_sgi(int sgi_num, 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); + #endif /* __ASSEMBLY__ */ #endif /* __GICV3_H__ */ diff --git a/include/drivers/auth/mbedtls/mbedtls_config.h b/include/drivers/auth/mbedtls/mbedtls_config.h index ca2d9fad8..96587acae 100644 --- a/include/drivers/auth/mbedtls/mbedtls_config.h +++ b/include/drivers/auth/mbedtls/mbedtls_config.h @@ -76,12 +76,13 @@ #define MBEDTLS_MPI_WINDOW_SIZE 2 #define MBEDTLS_MPI_MAX_SIZE 256 -/* System headers required to build mbed TLS with the current configuration */ -#include <stdlib.h> - /* Memory buffer allocator options */ #define MBEDTLS_MEMORY_ALIGN_MULTIPLE 8 +#ifndef __ASSEMBLY__ +/* System headers required to build mbed TLS with the current configuration */ +#include <stdlib.h> #include "mbedtls/check_config.h" +#endif #endif /* __MBEDTLS_CONFIG_H__ */ diff --git a/include/lib/aarch32/arch.h b/include/lib/aarch32/arch.h index 5fbb83a6c..3846bec4d 100644 --- a/include/lib/aarch32/arch.h +++ b/include/lib/aarch32/arch.h @@ -44,6 +44,7 @@ (((mpidr) >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK) #define MPIDR_AFFLVL2_VAL(mpidr) \ (((mpidr) >> MPIDR_AFF2_SHIFT) & MPIDR_AFFLVL_MASK) +#define MPIDR_AFFLVL3_VAL(mpidr) 0 /* * The MPIDR_MAX_AFFLVL count starts from 0. Take care to @@ -350,6 +351,8 @@ #define PMCR_N_SHIFT 11 #define PMCR_N_MASK 0x1f #define PMCR_N_BITS (PMCR_N_MASK << PMCR_N_SHIFT) +#define PMCR_LC_BIT (1 << 6) +#define PMCR_DP_BIT (1 << 5) /******************************************************************************* * Definitions of register offsets, fields and macros for CPU system diff --git a/include/lib/aarch32/arch_helpers.h b/include/lib/aarch32/arch_helpers.h index 5d3183603..469e9b0d0 100644 --- a/include/lib/aarch32/arch_helpers.h +++ b/include/lib/aarch32/arch_helpers.h @@ -213,6 +213,7 @@ DEFINE_SYSOP_TYPE_FUNC(dmb, ld) 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, @@ -257,6 +258,7 @@ 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_igrpen0_el1, ICC_IGRPEN0) DEFINE_COPROCR_RW_FUNCS(icc_hppir0_el1, ICC_HPPIR0) @@ -265,6 +267,7 @@ 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_RW_FUNCS(hdcr, HDCR) DEFINE_COPROCR_RW_FUNCS(cnthp_ctl, CNTHP_CTL) @@ -324,4 +327,7 @@ DEFINE_DCOP_PARAM_FUNC(cvac, DCCMVAC) #define read_ctr_el0() read_ctr() +#define write_icc_sgi0r_el1(_v) \ + write64_icc_sgi0r_el1(_v) + #endif /* __ARCH_HELPERS_H__ */ diff --git a/include/lib/aarch32/smcc_helpers.h b/include/lib/aarch32/smcc_helpers.h index 1bc843810..53f1aa4ab 100644 --- a/include/lib/aarch32/smcc_helpers.h +++ b/include/lib/aarch32/smcc_helpers.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -21,7 +21,8 @@ #define SMC_CTX_SP_MON 0x7C #define SMC_CTX_LR_MON 0x80 #define SMC_CTX_SCR 0x84 -#define SMC_CTX_SIZE 0x88 +#define SMC_CTX_PMCR 0x88 +#define SMC_CTX_SIZE 0x8C #ifndef __ASSEMBLY__ #include <cassert.h> @@ -73,6 +74,7 @@ typedef struct smc_ctx { u_register_t sp_mon; u_register_t lr_mon; u_register_t scr; + u_register_t pmcr; } smc_ctx_t; /* diff --git a/include/lib/aarch32/smcc_macros.S b/include/lib/aarch32/smcc_macros.S index 7edf41061..cf26175d6 100644 --- a/include/lib/aarch32/smcc_macros.S +++ b/include/lib/aarch32/smcc_macros.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -13,6 +13,8 @@ * 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 smcc_save_gp_mode_regs /* Save r0 - r12 in the SMC context */ @@ -46,6 +48,8 @@ /* lr_mon is already saved by caller */ ldcopr r4, SCR str r4, [sp, #SMC_CTX_SCR] + ldcopr r4, PMCR + str r4, [sp, #SMC_CTX_PMCR] .endm /* @@ -70,6 +74,12 @@ stcopr r1, SCR isb + /* + * Restore the PMCR register. + */ + ldr r1, [r0, #SMC_CTX_PMCR] + stcopr r1, PMCR + /* Restore the banked registers including the current SPSR */ add r1, r0, #SMC_CTX_SP_USR ldm r1!, {r4-r12} diff --git a/include/lib/aarch64/arch.h b/include/lib/aarch64/arch.h index f85e78971..997e3a229 100644 --- a/include/lib/aarch64/arch.h +++ b/include/lib/aarch64/arch.h @@ -68,6 +68,7 @@ #define ICC_CTLR_EL1 S3_0_C12_C12_4 #define ICC_CTLR_EL3 S3_6_C12_C12_4 #define ICC_PMR_EL1 S3_0_C4_C6_0 +#define ICC_RPR_EL1 S3_0_C12_C11_3 #define ICC_IGRPEN1_EL3 S3_6_c12_c12_7 #define ICC_IGRPEN0_EL1 S3_0_c12_c12_6 #define ICC_HPPIR0_EL1 S3_0_c12_c8_2 @@ -76,6 +77,7 @@ #define ICC_IAR1_EL1 S3_0_c12_c12_0 #define ICC_EOIR0_EL1 S3_0_c12_c8_1 #define ICC_EOIR1_EL1 S3_0_c12_c12_1 +#define ICC_SGI0R_EL1 S3_0_c12_c11_7 /******************************************************************************* * Generic timer memory mapped registers & offsets @@ -502,9 +504,14 @@ #define CNTACR_RWPT_SHIFT U(0x5) /* PMCR_EL0 definitions */ +#define PMCR_EL0_RESET_VAL U(0x0) #define PMCR_EL0_N_SHIFT U(11) #define PMCR_EL0_N_MASK U(0x1f) #define PMCR_EL0_N_BITS (PMCR_EL0_N_MASK << PMCR_EL0_N_SHIFT) +#define PMCR_EL0_LC_BIT (U(1) << 6) +#define PMCR_EL0_DP_BIT (U(1) << 5) +#define PMCR_EL0_X_BIT (U(1) << 4) +#define PMCR_EL0_D_BIT (U(1) << 3) /******************************************************************************* * Definitions of MAIR encodings for device and normal memory diff --git a/include/lib/aarch64/arch_helpers.h b/include/lib/aarch64/arch_helpers.h index 0d0d7d335..9c022ab5e 100644 --- a/include/lib/aarch64/arch_helpers.h +++ b/include/lib/aarch64/arch_helpers.h @@ -31,11 +31,8 @@ static inline void write_ ## _name(uint64_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 uint64_t v) \ -{ \ - __asm__ volatile ("msr " #_reg_name ", %0" : : "i" (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) \ @@ -59,11 +56,6 @@ static inline void write_ ## _name(const uint64_t v) \ #define DEFINE_RENAME_SYSREG_WRITE_FUNC(_name, _reg_name) \ _DEFINE_SYSREG_WRITE_FUNC(_name, _reg_name) -/* Define write function for special system registers */ -#define DEFINE_SYSREG_WRITE_CONST_FUNC(_name) \ - _DEFINE_SYSREG_WRITE_CONST_FUNC(_name, _name) - - /********************************************************************** * Macros to create inline functions for system instructions *********************************************************************/ @@ -171,15 +163,17 @@ void inv_dcache_range(uintptr_t addr, size_t size); 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_mmu_icache_el1(void); void disable_mmu_icache_el3(void); /******************************************************************************* * Misc. accessor prototypes ******************************************************************************/ -DEFINE_SYSREG_WRITE_CONST_FUNC(daifset) -DEFINE_SYSREG_WRITE_CONST_FUNC(daifclr) +#define write_daifclr(val) SYSREG_WRITE_CONST(daifclr, val) +#define write_daifset(val) SYSREG_WRITE_CONST(daifset, val) DEFINE_SYSREG_READ_FUNC(par_el1) DEFINE_SYSREG_READ_FUNC(id_pfr1_el1) @@ -204,6 +198,7 @@ DEFINE_SYSOP_TYPE_FUNC(dmb, ld) 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) uint32_t get_afflvl_shift(uint32_t); @@ -307,12 +302,13 @@ DEFINE_SYSREG_READ_FUNC(ctr_el0) DEFINE_SYSREG_RW_FUNCS(mdcr_el2) DEFINE_SYSREG_RW_FUNCS(hstr_el2) DEFINE_SYSREG_RW_FUNCS(cnthp_ctl_el2) -DEFINE_SYSREG_READ_FUNC(pmcr_el0) +DEFINE_SYSREG_RW_FUNCS(pmcr_el0) 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_igrpen0_el1, ICC_IGRPEN0_EL1) DEFINE_RENAME_SYSREG_READ_FUNC(icc_hppir0_el1, ICC_HPPIR0_EL1) @@ -321,6 +317,7 @@ 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 IS_IN_EL(x) \ diff --git a/include/lib/el3_runtime/aarch64/context.h b/include/lib/el3_runtime/aarch64/context.h index dcbf1c9d4..a89468d49 100644 --- a/include/lib/el3_runtime/aarch64/context.h +++ b/include/lib/el3_runtime/aarch64/context.h @@ -87,22 +87,23 @@ #define CTX_AFSR1_EL1 U(0x98) #define CTX_CONTEXTIDR_EL1 U(0xa0) #define CTX_VBAR_EL1 U(0xa8) +#define CTX_PMCR_EL0 U(0xb0) /* * If the platform is AArch64-only, there is no need to save and restore these * AArch32 registers. */ #if CTX_INCLUDE_AARCH32_REGS -#define CTX_SPSR_ABT U(0xb0) -#define CTX_SPSR_UND U(0xb8) -#define CTX_SPSR_IRQ U(0xc0) -#define CTX_SPSR_FIQ U(0xc8) -#define CTX_DACR32_EL2 U(0xd0) -#define CTX_IFSR32_EL2 U(0xd8) -#define CTX_FP_FPEXC32_EL2 U(0xe0) -#define CTX_TIMER_SYSREGS_OFF U(0xf0) /* Align to the next 16 byte boundary */ +#define CTX_SPSR_ABT U(0xc0) /* Align to the next 16 byte boundary */ +#define CTX_SPSR_UND U(0xc8) +#define CTX_SPSR_IRQ U(0xd0) +#define CTX_SPSR_FIQ U(0xd8) +#define CTX_DACR32_EL2 U(0xe0) +#define CTX_IFSR32_EL2 U(0xe8) +#define CTX_FP_FPEXC32_EL2 U(0xf0) +#define CTX_TIMER_SYSREGS_OFF U(0x100) /* Align to the next 16 byte boundary */ #else -#define CTX_TIMER_SYSREGS_OFF U(0xb0) +#define CTX_TIMER_SYSREGS_OFF U(0xc0) /* Align to the next 16 byte boundary */ #endif /* __CTX_INCLUDE_AARCH32_REGS__ */ /* diff --git a/include/lib/el3_runtime/pubsub.h b/include/lib/el3_runtime/pubsub.h new file mode 100644 index 000000000..9a854808f --- /dev/null +++ b/include/lib/el3_runtime/pubsub.h @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __PUBSUB_H__ +#define __PUBSUB_H__ + +#define __pubsub_start_sym(event) __pubsub_##event##_start +#define __pubsub_end_sym(event) __pubsub_##event##_end + +#ifdef __LINKER__ + +/* For the linker ... */ + +#define __pubsub_section(event) __pubsub_##event + +/* + * REGISTER_PUBSUB_EVENT has a different definition between linker and compiler + * contexts. In linker context, this collects pubsub sections for each event, + * placing guard symbols around each. + */ +#define REGISTER_PUBSUB_EVENT(event) \ + __pubsub_start_sym(event) = .; \ + KEEP(*(__pubsub_section(event))); \ + __pubsub_end_sym(event) = . + +#else /* __LINKER__ */ + +/* For the compiler ... */ + +#include <arch_helpers.h> +#include <assert.h> +#include <cdefs.h> +#include <stddef.h> + +#define __pubsub_section(event) __section("__pubsub_" #event) + +/* + * In compiler context, REGISTER_PUBSUB_EVENT declares the per-event symbols + * exported by the linker required for the other pubsub macros to work. + */ +#define REGISTER_PUBSUB_EVENT(event) \ + extern pubsub_cb_t __pubsub_start_sym(event)[]; \ + extern pubsub_cb_t __pubsub_end_sym(event)[] + +/* + * Have the function func called back when the specified event happens. This + * macro places the function address into the pubsub section, which is picked up + * and invoked by the invoke_pubsubs() function via. the PUBLISH_EVENT* macros. + */ +#define SUBSCRIBE_TO_EVENT(event, func) \ + pubsub_cb_t __cb_func_##func##event __pubsub_section(event) = func + +/* + * Iterate over subscribed handlers for a defined event. 'event' is the name of + * the event, and 'subscriber' a local variable of type 'pubsub_cb_t *'. + */ +#define for_each_subscriber(event, subscriber) \ + for (subscriber = __pubsub_start_sym(event); \ + subscriber < __pubsub_end_sym(event); \ + subscriber++) + +/* + * Publish a defined event supplying an argument. All subscribed handlers are + * invoked, but the return value of handlers are ignored for now. + */ +#define PUBLISH_EVENT_ARG(event, arg) \ + do { \ + pubsub_cb_t *subscriber; \ + for_each_subscriber(event, subscriber) { \ + (*subscriber)(arg); \ + } \ + } while (0) + +/* Publish a defined event with NULL argument */ +#define PUBLISH_EVENT(event) PUBLISH_EVENT_ARG(event, NULL) + +/* Subscriber callback type */ +typedef void* (*pubsub_cb_t)(const void *arg); + +#endif /* __LINKER__ */ +#endif /* __PUBSUB_H__ */ diff --git a/include/lib/el3_runtime/pubsub_events.h b/include/lib/el3_runtime/pubsub_events.h new file mode 100644 index 000000000..9cfedb4de --- /dev/null +++ b/include/lib/el3_runtime/pubsub_events.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <pubsub.h> + +/* + * This file defines a list of pubsub events, declared using + * REGISTER_PUBSUB_EVENT() macro. + */ + +/* + * Event published after a CPU has been powered up and finished its + * initialization. + */ +REGISTER_PUBSUB_EVENT(psci_cpu_on_finish); + +#ifdef AARCH64 +/* + * These events are published by the AArch64 context management framework + * after the secure context is restored/saved via + * cm_el1_sysregs_context_{restore,save}() API. + */ +REGISTER_PUBSUB_EVENT(cm_entering_secure_world); +REGISTER_PUBSUB_EVENT(cm_exited_secure_world); + +/* + * These events are published by the AArch64 context management framework + * after the normal context is restored/saved via + * cm_el1_sysregs_context_{restore,save}() API. + */ +REGISTER_PUBSUB_EVENT(cm_entering_normal_world); +REGISTER_PUBSUB_EVENT(cm_exited_normal_world); +#endif /* AARCH64 */ diff --git a/include/lib/psci/psci.h b/include/lib/psci/psci.h index 0b44ab2e0..06434f9e5 100644 --- a/include/lib/psci/psci.h +++ b/include/lib/psci/psci.h @@ -65,6 +65,8 @@ #define PSCI_STAT_RESIDENCY_AARCH64 U(0xc4000010) #define PSCI_STAT_COUNT_AARCH32 U(0x84000011) #define PSCI_STAT_COUNT_AARCH64 U(0xc4000011) +#define PSCI_SYSTEM_RESET2_AARCH32 U(0x84000012) +#define PSCI_SYSTEM_RESET2_AARCH64 U(0xc4000012) #define PSCI_MEM_PROTECT U(0x84000013) #define PSCI_MEM_CHK_RANGE_AARCH32 U(0x84000014) #define PSCI_MEM_CHK_RANGE_AARCH64 U(0xc4000014) @@ -149,7 +151,7 @@ * PSCI version ******************************************************************************/ #define PSCI_MAJOR_VER (U(1) << 16) -#define PSCI_MINOR_VER U(0x0) +#define PSCI_MINOR_VER U(0x1) /******************************************************************************* * PSCI error codes @@ -167,6 +169,14 @@ #define PSCI_INVALID_MPIDR ~((u_register_t)0) +/* + * SYSTEM_RESET2 macros + */ +#define PSCI_RESET2_TYPE_VENDOR_SHIFT 31 +#define PSCI_RESET2_TYPE_VENDOR (1U << PSCI_RESET2_TYPE_VENDOR_SHIFT) +#define PSCI_RESET2_TYPE_ARCH (0U << PSCI_RESET2_TYPE_VENDOR_SHIFT) +#define PSCI_RESET2_SYSTEM_WARM_RESET (PSCI_RESET2_TYPE_ARCH | 0) + #ifndef __ASSEMBLY__ #include <stdint.h> @@ -294,6 +304,8 @@ typedef struct plat_psci_ops { int (*mem_protect_chk)(uintptr_t base, u_register_t length); int (*read_mem_protect)(int *val); int (*write_mem_protect)(int val); + int (*system_reset2)(int is_vendor, + int reset_type, u_register_t cookie); } plat_psci_ops_t; /******************************************************************************* diff --git a/include/lib/xlat_tables/xlat_tables_defs.h b/include/lib/xlat_tables/xlat_tables_defs.h index 7cb9d37f1..3a7f2456b 100644 --- a/include/lib/xlat_tables/xlat_tables_defs.h +++ b/include/lib/xlat_tables/xlat_tables_defs.h @@ -24,9 +24,19 @@ #define FOUR_KB_INDEX(x) ((x) >> FOUR_KB_SHIFT) #define INVALID_DESC U(0x0) +/* + * A block descriptor points to a region of memory bigger than the granule size + * (e.g. a 2MB region when the granule size is 4KB). + */ #define BLOCK_DESC U(0x1) /* Table levels 0-2 */ +/* A table descriptor points to the next level of translation table. */ #define TABLE_DESC U(0x3) /* Table levels 0-2 */ +/* + * A page descriptor points to a page, i.e. a memory region whose size is the + * translation granule size (e.g. 4KB). + */ #define PAGE_DESC U(0x3) /* Table level 3 */ + #define DESC_MASK U(0x3) #define FIRST_LEVEL_DESC_N ONE_GB_SHIFT @@ -84,10 +94,22 @@ #define XLAT_BLOCK_MASK(level) (XLAT_BLOCK_SIZE(level) - 1) /* Mask to get the address bits common to a block of a certain table level*/ #define XLAT_ADDR_MASK(level) (~XLAT_BLOCK_MASK(level)) +/* + * Extract from the given virtual address the index into the given lookup level. + * This macro assumes the system is using the 4KB translation granule. + */ +#define XLAT_TABLE_IDX(virtual_addr, level) \ + (((virtual_addr) >> XLAT_ADDR_SHIFT(level)) & ULL(0x1FF)) /* - * AP[1] bit is ignored by hardware and is - * treated as if it is One in EL2/EL3 + * The ARMv8 translation table descriptor format defines AP[2:1] as the Access + * Permissions bits, and does not define an AP[0] bit. + * + * AP[1] is valid only for a stage 1 translation that supports two VA ranges + * (i.e. in the ARMv8A.0 architecture, that is the S-EL1&0 regime). + * + * AP[1] is RES0 for stage 1 translations that support only one VA range + * (e.g. EL3). */ #define AP2_SHIFT U(0x7) #define AP2_RO U(0x1) @@ -122,6 +144,28 @@ #define ATTR_INDEX_GET(attr) (((attr) >> 2) & ATTR_INDEX_MASK) /* + * Shift values for the attributes fields in a block or page descriptor. + * See section D4.3.3 in the ARMv8-A ARM (issue B.a). + */ + +/* Memory attributes index field, AttrIndx[2:0]. */ +#define ATTR_INDEX_SHIFT 2 +/* Non-secure bit, NS. */ +#define NS_SHIFT 5 +/* Shareability field, SH[1:0] */ +#define SHAREABILITY_SHIFT 8 +/* The Access Flag, AF. */ +#define ACCESS_FLAG_SHIFT 10 +/* The not global bit, nG. */ +#define NOT_GLOBAL_SHIFT 11 +/* Contiguous hint bit. */ +#define CONT_HINT_SHIFT 52 +/* Execute-never bits, XN. */ +#define PXN_SHIFT 53 +#define XN_SHIFT 54 +#define UXN_SHIFT XN_SHIFT + +/* * Flags to override default values used to program system registers while * enabling the MMU. */ diff --git a/include/lib/xlat_tables/xlat_tables_v2.h b/include/lib/xlat_tables/xlat_tables_v2.h index 1a55fba77..73a9c5334 100644 --- a/include/lib/xlat_tables/xlat_tables_v2.h +++ b/include/lib/xlat_tables/xlat_tables_v2.h @@ -251,5 +251,66 @@ int mmap_remove_dynamic_region_ctx(xlat_ctx_t *ctx, #endif /* PLAT_XLAT_TABLES_DYNAMIC */ +/* + * Change the memory attributes of the memory region starting from a given + * virtual address in a set of translation tables. + * + * This function can only be used after the translation tables have been + * initialized. + * + * The base address of the memory region must be aligned on a page boundary. + * The size of this memory region must be a multiple of a page size. + * The memory region must be already mapped by the given translation tables + * and it must be mapped at the granularity of a page. + * + * Return 0 on success, a negative value on error. + * + * In case of error, the memory attributes remain unchanged and this function + * has no effect. + * + * ctx + * Translation context to work on. + * base_va: + * Virtual address of the 1st page to change the attributes of. + * size: + * Size in bytes of the memory region. + * attr: + * New attributes of the page tables. The attributes that can be changed are + * data access (MT_RO/MT_RW), instruction access (MT_EXECUTE_NEVER/MT_EXECUTE) + * and user/privileged access (MT_USER/MT_PRIVILEGED) in the case of contexts + * that are used in the EL1&0 translation regime. Also, note that this + * function doesn't allow to remap a region as RW and executable, or to remap + * device memory as executable. + * + * NOTE: The caller of this function must be able to write to the translation + * tables, i.e. the memory where they are stored must be mapped with read-write + * access permissions. This function assumes it is the case. If this is not + * the case then this function might trigger a data abort exception. + * + * NOTE2: The caller is responsible for making sure that the targeted + * translation tables are not modified by any other code while this function is + * executing. + */ +int change_mem_attributes(xlat_ctx_t *ctx, uintptr_t base_va, size_t size, + mmap_attr_t attr); + +/* + * Query the memory attributes of a memory page in a set of translation tables. + * + * Return 0 on success, a negative error code on error. + * On success, the attributes are stored into *attributes. + * + * ctx + * Translation context to work on. + * base_va + * Virtual address of the page to get the attributes of. + * There are no alignment restrictions on this address. The attributes of the + * memory page it lies within are returned. + * attributes + * Output parameter where to store the attributes of the targeted memory page. + */ +int get_mem_attributes(const xlat_ctx_t *ctx, uintptr_t base_va, + mmap_attr_t *attributes); + #endif /*__ASSEMBLY__*/ #endif /* __XLAT_TABLES_V2_H__ */ diff --git a/include/lib/xlat_tables/xlat_tables_v2_helpers.h b/include/lib/xlat_tables/xlat_tables_v2_helpers.h index 0ebdc9307..28228c4c6 100644 --- a/include/lib/xlat_tables/xlat_tables_v2_helpers.h +++ b/include/lib/xlat_tables/xlat_tables_v2_helpers.h @@ -162,8 +162,12 @@ struct xlat_ctx { .initialized = 0, \ } +#if AARCH64 -/* This IMAGE_EL macro must not to be used outside the library */ +/* + * This IMAGE_EL macro must not to be used outside the library, and it is only + * used in AArch64. + */ #if IMAGE_BL1 || IMAGE_BL31 # define IMAGE_EL 3 # define IMAGE_XLAT_DEFAULT_REGIME EL3_REGIME @@ -172,6 +176,17 @@ struct xlat_ctx { # define IMAGE_XLAT_DEFAULT_REGIME EL1_EL0_REGIME #endif +#else /* if AARCH32 */ + +/* + * The PL1&0 translation regime in AArch32 behaves like the EL1&0 regime in + * AArch64 except for the XN bits, but we set and unset them at the same time, + * so there's no difference in practice. + */ +#define IMAGE_XLAT_DEFAULT_REGIME EL1_EL0_REGIME + +#endif /* AARCH64 */ + #endif /*__ASSEMBLY__*/ #endif /* __XLAT_TABLES_V2_HELPERS_H__ */ diff --git a/include/plat/arm/board/common/board_arm_def.h b/include/plat/arm/board/common/board_arm_def.h index 64ca3808b..7a4594cc5 100644 --- a/include/plat/arm/board/common/board_arm_def.h +++ b/include/plat/arm/board/common/board_arm_def.h @@ -71,7 +71,7 @@ * little space for growth. */ #if TRUSTED_BOARD_BOOT -# define PLAT_ARM_MAX_BL2_SIZE 0x1D000 +# define PLAT_ARM_MAX_BL2_SIZE 0x1E000 #else # define PLAT_ARM_MAX_BL2_SIZE 0xF000 #endif diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h index 8ae820a92..6cab91fef 100644 --- a/include/plat/arm/common/arm_def.h +++ b/include/plat/arm/common/arm_def.h @@ -8,6 +8,8 @@ #include <arch.h> #include <common_def.h> +#include <gic_common.h> +#include <interrupt_props.h> #include <platform_def.h> #include <tbbr_img_def.h> #include <utils_def.h> @@ -164,9 +166,8 @@ #define ARM_IRQ_SEC_SGI_7 15 /* - * Define a list of Group 1 Secure and Group 0 interrupts as per GICv3 - * terminology. On a GICv2 system or mode, the lists will be merged and treated - * as Group 0 interrupts. + * List of secure interrupts are deprecated, but are retained only to support + * legacy configurations. */ #define ARM_G1S_IRQS ARM_IRQ_SEC_PHY_TIMER, \ ARM_IRQ_SEC_SGI_1, \ @@ -179,6 +180,33 @@ #define ARM_G0_IRQS ARM_IRQ_SEC_SGI_0, \ ARM_IRQ_SEC_SGI_6 +/* + * Define a list of Group 1 Secure and Group 0 interrupt properties as per GICv3 + * terminology. On a GICv2 system or mode, the lists will be merged and treated + * as Group 0 interrupts. + */ +#define ARM_G1S_IRQ_PROPS(grp) \ + INTR_PROP_DESC(ARM_IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY, grp, \ + GIC_INTR_CFG_LEVEL), \ + INTR_PROP_DESC(ARM_IRQ_SEC_SGI_1, GIC_HIGHEST_SEC_PRIORITY, grp, \ + GIC_INTR_CFG_EDGE), \ + INTR_PROP_DESC(ARM_IRQ_SEC_SGI_2, GIC_HIGHEST_SEC_PRIORITY, grp, \ + GIC_INTR_CFG_EDGE), \ + INTR_PROP_DESC(ARM_IRQ_SEC_SGI_3, GIC_HIGHEST_SEC_PRIORITY, grp, \ + GIC_INTR_CFG_EDGE), \ + INTR_PROP_DESC(ARM_IRQ_SEC_SGI_4, GIC_HIGHEST_SEC_PRIORITY, grp, \ + GIC_INTR_CFG_EDGE), \ + INTR_PROP_DESC(ARM_IRQ_SEC_SGI_5, GIC_HIGHEST_SEC_PRIORITY, grp, \ + GIC_INTR_CFG_EDGE), \ + INTR_PROP_DESC(ARM_IRQ_SEC_SGI_7, GIC_HIGHEST_SEC_PRIORITY, grp, \ + GIC_INTR_CFG_EDGE) + +#define ARM_G0_IRQ_PROPS(grp) \ + INTR_PROP_DESC(ARM_IRQ_SEC_SGI_0, GIC_HIGHEST_SEC_PRIORITY, grp, \ + GIC_INTR_CFG_EDGE), \ + INTR_PROP_DESC(ARM_IRQ_SEC_SGI_6, GIC_HIGHEST_SEC_PRIORITY, grp, \ + GIC_INTR_CFG_EDGE) + #define ARM_MAP_SHARED_RAM MAP_REGION_FLAT( \ ARM_SHARED_RAM_BASE, \ ARM_SHARED_RAM_SIZE, \ diff --git a/include/plat/arm/css/common/css_def.h b/include/plat/arm/css/common/css_def.h index ac0769c37..a2c0b4e80 100644 --- a/include/plat/arm/css/common/css_def.h +++ b/include/plat/arm/css/common/css_def.h @@ -8,6 +8,8 @@ #define __CSS_DEF_H__ #include <arm_def.h> +#include <gic_common.h> +#include <interrupt_props.h> #include <tzc400.h> /************************************************************************* @@ -41,14 +43,21 @@ #define MHU_CPU_INTR_S_SET_OFFSET 0x308 /* - * Define a list of Group 1 Secure interrupts as per GICv3 terminology. On a - * GICv2 system or mode, the interrupts will be treated as Group 0 interrupts. + * Define a list of Group 1 Secure interrupt properties as per GICv3 + * terminology. On a GICv2 system or mode, the interrupts will be treated as + * Group 0 interrupts. */ -#define CSS_G1S_IRQS CSS_IRQ_MHU, \ - CSS_IRQ_GPU_SMMU_0, \ - CSS_IRQ_TZC, \ - CSS_IRQ_TZ_WDOG, \ - CSS_IRQ_SEC_SYS_TIMER +#define CSS_G1S_IRQ_PROPS(grp) \ + INTR_PROP_DESC(CSS_IRQ_MHU, GIC_HIGHEST_SEC_PRIORITY, grp, \ + GIC_INTR_CFG_LEVEL), \ + INTR_PROP_DESC(CSS_IRQ_GPU_SMMU_0, GIC_HIGHEST_SEC_PRIORITY, grp, \ + GIC_INTR_CFG_LEVEL), \ + INTR_PROP_DESC(CSS_IRQ_TZC, GIC_HIGHEST_SEC_PRIORITY, grp, \ + GIC_INTR_CFG_LEVEL), \ + INTR_PROP_DESC(CSS_IRQ_TZ_WDOG, GIC_HIGHEST_SEC_PRIORITY, grp, \ + GIC_INTR_CFG_LEVEL), \ + INTR_PROP_DESC(CSS_IRQ_SEC_SYS_TIMER, GIC_HIGHEST_SEC_PRIORITY, grp, \ + GIC_INTR_CFG_LEVEL) #if CSS_USE_SCMI_SDS_DRIVER /* Memory region for shared data storage */ diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h index e189f648a..e2bfa5050 100644 --- a/include/plat/common/platform.h +++ b/include/plat/common/platform.h @@ -70,6 +70,26 @@ uint32_t plat_interrupt_type_to_line(uint32_t type, uint32_t security_state); /******************************************************************************* + * Optional interrupt management functions, depending on chosen EL3 components. + ******************************************************************************/ +unsigned int plat_ic_get_running_priority(void); +int plat_ic_is_spi(unsigned int id); +int plat_ic_is_ppi(unsigned int id); +int plat_ic_is_sgi(unsigned int id); +unsigned int plat_ic_get_interrupt_active(unsigned int id); +void plat_ic_disable_interrupt(unsigned int id); +void plat_ic_enable_interrupt(unsigned int id); +int plat_ic_has_interrupt_type(unsigned int type); +void plat_ic_set_interrupt_type(unsigned int id, unsigned int type); +void plat_ic_set_interrupt_priority(unsigned int id, unsigned int priority); +void plat_ic_raise_el3_sgi(int sgi_num, u_register_t target); +void plat_ic_set_spi_routing(unsigned int id, unsigned int routing_mode, + u_register_t mpidr); +void plat_ic_set_interrupt_pending(unsigned int id); +void plat_ic_clear_interrupt_pending(unsigned int id); +unsigned int plat_ic_set_priority_mask(unsigned int mask); + +/******************************************************************************* * Optional common functions (may be overridden) ******************************************************************************/ uintptr_t plat_get_my_stack(void); @@ -80,6 +100,8 @@ int plat_crash_console_flush(void); void plat_error_handler(int err) __dead2; void plat_panic_handler(void) __dead2; const char *plat_log_get_prefix(unsigned int log_level); +void bl2_plat_preload_setup(void); +int plat_try_next_boot_source(void); /******************************************************************************* * Mandatory BL1 functions |