diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/bl31/cm_macros.S | 57 | ||||
-rw-r--r-- | include/bl31/context_mgmt.h | 7 | ||||
-rw-r--r-- | include/bl31/interrupt_mgmt.h | 128 | ||||
-rw-r--r-- | include/bl31/runtime_svc.h | 5 | ||||
-rw-r--r-- | include/bl32/payloads/tsp.h | 54 | ||||
-rw-r--r-- | include/drivers/arm/gic_v2.h | 13 | ||||
-rw-r--r-- | include/lib/aarch64/arch.h | 23 | ||||
-rw-r--r-- | include/lib/aarch64/arch_helpers.h | 7 |
8 files changed, 225 insertions, 69 deletions
diff --git a/include/bl31/cm_macros.S b/include/bl31/cm_macros.S deleted file mode 100644 index f12f8c30..00000000 --- a/include/bl31/cm_macros.S +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2013-2014, 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. - */ -#include <arch.h> -#include <context.h> - - /* ----------------------------------------------------- - * Handle SMC exceptions seperately from other sync. - * exceptions. - * ----------------------------------------------------- - */ - .macro handle_sync_exception - str x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR] - mrs x30, esr_el3 - ubfx x30, x30, #ESR_EC_SHIFT, #ESR_EC_LENGTH - - cmp x30, #EC_AARCH32_SMC - b.eq smc_handler32 - - cmp x30, #EC_AARCH64_SMC - b.eq smc_handler64 - - /* ----------------------------------------------------- - * The following code handles any synchronous exception - * that is not an SMC. - * ----------------------------------------------------- - */ - - bl dump_state_and_die - .endm - diff --git a/include/bl31/context_mgmt.h b/include/bl31/context_mgmt.h index d2598eef..ad9d7856 100644 --- a/include/bl31/context_mgmt.h +++ b/include/bl31/context_mgmt.h @@ -47,10 +47,13 @@ extern void cm_el1_sysregs_context_save(uint32_t security_state); extern void cm_el1_sysregs_context_restore(uint32_t security_state); extern void cm_set_el3_eret_context(uint32_t security_state, uint64_t entrypoint, uint32_t spsr, uint32_t scr); -extern void cm_set_el3_elr(uint32_t security_state, uint64_t entrypoint); +extern void cm_set_elr_el3(uint32_t security_state, uint64_t entrypoint); +extern void cm_write_scr_el3_bit(uint32_t security_state, + uint32_t bit_pos, + uint32_t value); extern void cm_set_next_eret_context(uint32_t security_state); extern void cm_init_pcpu_ptr_cache(); extern void cm_set_pcpu_ptr_cache(const void *pcpu_ptr); extern void *cm_get_pcpu_ptr_cache(void); - +extern uint32_t cm_get_scr_el3(uint32_t security_state); #endif /* __CM_H__ */ diff --git a/include/bl31/interrupt_mgmt.h b/include/bl31/interrupt_mgmt.h new file mode 100644 index 00000000..0b24f39a --- /dev/null +++ b/include/bl31/interrupt_mgmt.h @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2014, 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 __INTERRUPT_MGMT_H__ +#define __INTERRUPT_MGMT_H__ + +#include <arch.h> + +/******************************************************************************* + * Constants for the types of interrupts recognised by the IM framework + ******************************************************************************/ +#define INTR_TYPE_S_EL1 0 +#define INTR_TYPE_EL3 1 +#define INTR_TYPE_NS 2 +#define MAX_INTR_TYPES 3 +#define INTR_TYPE_INVAL MAX_INTR_TYPES +/* + * Constant passed to the interrupt handler in the 'id' field when the + * framework does not read the gic registers to determine the interrupt id. + */ +#define INTR_ID_UNAVAILABLE 0xFFFFFFFF + + +/******************************************************************************* + * Mask for _both_ the routing model bits in the 'flags' parameter and + * constants to define the valid routing models for each supported interrupt + * type + ******************************************************************************/ +#define INTR_RM_FLAGS_SHIFT 0x0 +#define INTR_RM_FLAGS_MASK 0x3 +/* Routed to EL3 from NS. Taken to S-EL1 from Secure */ +#define INTR_SEL1_VALID_RM0 0x2 +/* Routed to EL3 from NS and Secure */ +#define INTR_SEL1_VALID_RM1 0x3 +/* Routed to EL1/EL2 from NS and to S-EL1 from Secure */ +#define INTR_NS_VALID_RM0 0x0 +/* Routed to EL1/EL2 from NS and to EL3 from Secure */ +#define INTR_NS_VALID_RM1 0x1 + + +/******************************************************************************* + * Constants for the _individual_ routing model bits in the 'flags' field for + * each interrupt type and mask to validate the 'flags' parameter while + * registering an interrupt handler + ******************************************************************************/ +#define INTR_TYPE_FLAGS_MASK 0xFFFFFFFC + +#define INTR_RM_FROM_SEC_SHIFT SECURE /* BIT[0] */ +#define INTR_RM_FROM_NS_SHIFT NON_SECURE /* BIT[1] */ +#define INTR_RM_FROM_FLAG_MASK 1 +#define get_interrupt_rm_flag(flag, ss) (((flag >> INTR_RM_FLAGS_SHIFT) >> ss) \ + & INTR_RM_FROM_FLAG_MASK) +#define set_interrupt_rm_flag(flag, ss) (flag |= 1 << ss) +#define clr_interrupt_rm_flag(flag, ss) (flag &= ~(1 << ss)) + + +/******************************************************************************* + * Macros to validate the routing model bits in the 'flags' for a type + * of interrupt. If the model does not match one of the valid masks + * -EINVAL is returned. + ******************************************************************************/ +#define validate_sel1_interrupt_rm(x) (x == INTR_SEL1_VALID_RM0 ? 0 : \ + (x == INTR_SEL1_VALID_RM1 ? 0 :\ + -EINVAL)) + +#define validate_ns_interrupt_rm(x) (x == INTR_NS_VALID_RM0 ? 0 : \ + (x == INTR_NS_VALID_RM1 ? 0 :\ + -EINVAL)) + +/******************************************************************************* + * Macros to set the 'flags' parameter passed to an interrupt type handler. Only + * the flag to indicate the security state when the exception was generated is + * supported. + ******************************************************************************/ +#define INTR_SRC_SS_FLAG_SHIFT 0 /* BIT[0] */ +#define INTR_SRC_SS_FLAG_MASK 1 +#define set_interrupt_src_ss(flag, val) (flag |= val << INTR_SRC_SS_FLAG_SHIFT) +#define clr_interrupt_src_ss(flag) (flag &= ~(1 << INTR_SRC_SS_FLAG_SHIFT)) +#define get_interrupt_src_ss(flag) ((flag >> INTR_SRC_SS_FLAG_SHIFT) & \ + INTR_SRC_SS_FLAG_MASK) + +#ifndef __ASSEMBLY__ + +/* Prototype for defining a handler for an interrupt type */ +typedef uint64_t (*interrupt_type_handler_t)(uint32_t id, + uint32_t flags, + void *handle, + void *cookie); + +/******************************************************************************* + * Function & variable prototypes + ******************************************************************************/ +extern uint32_t get_scr_el3_from_routing_model(uint32_t security_state); +extern int32_t set_routing_model(uint32_t type, uint32_t flags); +extern int32_t register_interrupt_type_handler(uint32_t type, + interrupt_type_handler_t handler, + uint32_t flags); +extern interrupt_type_handler_t get_interrupt_type_handler(uint32_t interrupt_type); + +#endif /*__ASSEMBLY__*/ +#endif /* __INTERRUPT_MGMT_H__ */ diff --git a/include/bl31/runtime_svc.h b/include/bl31/runtime_svc.h index 6d708967..0f510f76 100644 --- a/include/bl31/runtime_svc.h +++ b/include/bl31/runtime_svc.h @@ -135,9 +135,12 @@ typedef int32_t (*rt_svc_init_t)(void); /* Convenience macros to return from SMC handler */ +#define SMC_RET0(_h) { \ + return (uint64_t) (_h); \ +} #define SMC_RET1(_h, _x0) { \ write_ctx_reg(get_gpregs_ctx(_h), CTX_GPREG_X0, (_x0)); \ - return _x0; \ + SMC_RET0(_h); \ } #define SMC_RET2(_h, _x0, _x1) { \ write_ctx_reg(get_gpregs_ctx(_h), CTX_GPREG_X1, (_x1)); \ diff --git a/include/bl32/payloads/tsp.h b/include/bl32/payloads/tsp.h index 1f542d53..3aa3e8c1 100644 --- a/include/bl32/payloads/tsp.h +++ b/include/bl32/payloads/tsp.h @@ -42,7 +42,16 @@ #define TSP_RESUME_DONE 0xf2000004 #define TSP_WORK_DONE 0xf2000005 -/* SMC function ID that TSP uses to request service from secure montior */ +/* + * Function identifiers to handle FIQs through the synchronous handling model. + * If the TSP was previously interrupted then control has to be returned to + * the TSPD after handling the interrupt else execution can remain in the TSP. + */ +#define TSP_HANDLED_S_EL1_FIQ 0xf2000006 +#define TSP_EL3_FIQ 0xf2000007 +#define TSP_HANDLE_FIQ_AND_RETURN 0x2004 + +/* SMC function ID that TSP uses to request service from secure monitor */ #define TSP_GET_ARGS 0xf2001000 /* Function IDs for various TSP services */ @@ -86,16 +95,17 @@ #include <cassert.h> #include <platform.h> /* For CACHE_WRITEBACK_GRANULE */ +#include <spinlock.h> #include <stdint.h> typedef void (*tsp_generic_fptr_t)(uint64_t arg0, - uint64_t arg1, - uint64_t arg2, - uint64_t arg3, - uint64_t arg4, - uint64_t arg5, - uint64_t arg6, - uint64_t arg7); + uint64_t arg1, + uint64_t arg2, + uint64_t arg3, + uint64_t arg4, + uint64_t arg5, + uint64_t arg6, + uint64_t arg7); typedef struct entry_info { tsp_generic_fptr_t fast_smc_entry; @@ -103,9 +113,13 @@ typedef struct entry_info { tsp_generic_fptr_t cpu_off_entry; tsp_generic_fptr_t cpu_resume_entry; tsp_generic_fptr_t cpu_suspend_entry; + tsp_generic_fptr_t fiq_entry; } entry_info_t; typedef struct work_statistics { + uint32_t fiq_count; /* Number of FIQs on this cpu */ + uint32_t sync_fiq_count; /* Number of sync. fiqs on this cpu */ + uint32_t sync_fiq_ret_count; /* Number of fiq returns on this cpu */ uint32_t smc_count; /* Number of returns on this cpu */ uint32_t eret_count; /* Number of entries on this cpu */ uint32_t cpu_on_count; /* Number of cpu on requests */ @@ -120,7 +134,7 @@ typedef struct tsp_args { /* Macros to access members of the above structure using their offsets */ #define read_sp_arg(args, offset) ((args)->_regs[offset >> 3]) -#define write_sp_arg(args, offset, val)(((args)->_regs[offset >> 3]) \ +#define write_sp_arg(args, offset, val) (((args)->_regs[offset >> 3]) \ = val) /* @@ -131,6 +145,14 @@ CASSERT(TSP_ARGS_SIZE == sizeof(tsp_args_t), assert_sp_args_size_mismatch); extern void tsp_get_magic(uint64_t args[4]); +extern void tsp_fiq_entry(uint64_t arg0, + uint64_t arg1, + uint64_t arg2, + uint64_t arg3, + uint64_t arg4, + uint64_t arg5, + uint64_t arg6, + uint64_t arg7); extern void tsp_fast_smc_entry(uint64_t arg0, uint64_t arg1, uint64_t arg2, @@ -196,6 +218,20 @@ extern tsp_args_t *tsp_cpu_off_main(uint64_t arg0, uint64_t arg5, uint64_t arg6, uint64_t arg7); + +/* Generic Timer functions */ +extern void tsp_generic_timer_start(void); +extern void tsp_generic_timer_handler(void); +extern void tsp_generic_timer_stop(void); +extern void tsp_generic_timer_save(void); +extern void tsp_generic_timer_restore(void); + +/* FIQ management functions */ +extern void tsp_update_sync_fiq_stats(uint32_t type, uint64_t elr_el3); + +/* Data structure to keep track of TSP statistics */ +extern spinlock_t console_lock; +extern work_statistics_t tsp_stats[PLATFORM_CORE_COUNT]; #endif /* __ASSEMBLY__ */ #endif /* __BL2_H__ */ diff --git a/include/drivers/arm/gic_v2.h b/include/drivers/arm/gic_v2.h index ccf3d32c..e8196763 100644 --- a/include/drivers/arm/gic_v2.h +++ b/include/drivers/arm/gic_v2.h @@ -43,6 +43,7 @@ #define GIC_LOWEST_SEC_PRIORITY 127 #define GIC_HIGHEST_NS_PRIORITY 128 #define GIC_LOWEST_NS_PRIORITY 254 /* 255 would disable an interrupt */ +#define GIC_SPURIOUS_INTERRUPT 1023 #define ENABLE_GRP0 (1 << 0) #define ENABLE_GRP1 (1 << 1) @@ -88,6 +89,7 @@ #define GICC_EOIR 0x10 #define GICC_RPR 0x14 #define GICC_HPPIR 0x18 +#define GICC_AHPPIR 0x28 #define GICC_IIDR 0xFC #define GICC_DIR 0x1000 #define GICC_PRIODROP GICC_EOIR @@ -247,6 +249,11 @@ static inline unsigned int gicc_read_hppir(unsigned int base) return mmio_read_32(base + GICC_HPPIR); } +static inline unsigned int gicc_read_ahppir(unsigned int base) +{ + return mmio_read_32(base + GICC_AHPPIR); +} + static inline unsigned int gicc_read_dir(unsigned int base) { return mmio_read_32(base + GICC_DIR); @@ -298,6 +305,12 @@ static inline void gicc_write_dir(unsigned int base, unsigned int val) mmio_write_32(base + GICC_DIR, val); } +/******************************************************************************* + * Prototype of function to map an interrupt type to the interrupt line used to + * signal it. + ******************************************************************************/ +uint32_t gicv2_interrupt_type_to_line(uint32_t cpuif_base, uint32_t type); + #endif /*__ASSEMBLY__*/ #endif /* __GIC_V2_H__ */ diff --git a/include/lib/aarch64/arch.h b/include/lib/aarch64/arch.h index 1c11af3f..920dfc9b 100644 --- a/include/lib/aarch64/arch.h +++ b/include/lib/aarch64/arch.h @@ -148,6 +148,7 @@ #define SCR_FIQ_BIT (1 << 2) #define SCR_IRQ_BIT (1 << 1) #define SCR_NS_BIT (1 << 0) +#define SCR_VALID_BIT_MASK 0x2f8f /* HCR definitions */ #define HCR_RW_BIT (1ull << 31) @@ -264,6 +265,28 @@ ((aif) & SPSR_AIF_MASK) << SPSR_AIF_SHIFT) +/* Physical timer control register bit fields shifts and masks */ +#define CNTP_CTL_ENABLE_SHIFT 0 +#define CNTP_CTL_IMASK_SHIFT 1 +#define CNTP_CTL_ISTATUS_SHIFT 2 + +#define CNTP_CTL_ENABLE_MASK 1 +#define CNTP_CTL_IMASK_MASK 1 +#define CNTP_CTL_ISTATUS_MASK 1 + +#define get_cntp_ctl_enable(x) ((x >> CNTP_CTL_ENABLE_SHIFT) & \ + CNTP_CTL_ENABLE_MASK) +#define get_cntp_ctl_imask(x) ((x >> CNTP_CTL_IMASK_SHIFT) & \ + CNTP_CTL_IMASK_MASK) +#define get_cntp_ctl_istatus(x) ((x >> CNTP_CTL_ISTATUS_SHIFT) & \ + CNTP_CTL_ISTATUS_MASK) + +#define set_cntp_ctl_enable(x) (x |= 1 << CNTP_CTL_ENABLE_SHIFT) +#define set_cntp_ctl_imask(x) (x |= 1 << CNTP_CTL_IMASK_SHIFT) + +#define clr_cntp_ctl_enable(x) (x &= ~(1 << CNTP_CTL_ENABLE_SHIFT)) +#define clr_cntp_ctl_imask(x) (x &= ~(1 << CNTP_CTL_IMASK_SHIFT)) + /* Miscellaneous MMU related constants */ #define NUM_2MB_IN_GB (1 << 9) #define NUM_4K_IN_2MB (1 << 9) diff --git a/include/lib/aarch64/arch_helpers.h b/include/lib/aarch64/arch_helpers.h index 0a398d08..f30301d1 100644 --- a/include/lib/aarch64/arch_helpers.h +++ b/include/lib/aarch64/arch_helpers.h @@ -202,6 +202,10 @@ extern unsigned long read_cptr_el3(void); extern unsigned long read_cpacr(void); extern unsigned long read_cpuectlr(void); extern unsigned int read_cntfrq_el0(void); +extern unsigned int read_cntps_ctl_el1(void); +extern unsigned int read_cntps_tval_el1(void); +extern unsigned long read_cntps_cval_el1(void); +extern unsigned long read_cntpct_el0(void); extern unsigned long read_cnthctl_el2(void); extern unsigned long read_tpidr_el3(void); @@ -210,6 +214,9 @@ extern void write_scr(unsigned long); extern void write_hcr(unsigned long); extern void write_cpacr(unsigned long); extern void write_cntfrq_el0(unsigned int); +extern void write_cntps_ctl_el1(unsigned int); +extern void write_cntps_tval_el1(unsigned int); +extern void write_cntps_cval_el1(unsigned long); extern void write_cnthctl_el2(unsigned long); extern void write_vbar_el1(unsigned long); |