1*91f16700Schasinglulu /* 2*91f16700Schasinglulu * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. 3*91f16700Schasinglulu * 4*91f16700Schasinglulu * SPDX-License-Identifier: BSD-3-Clause 5*91f16700Schasinglulu */ 6*91f16700Schasinglulu 7*91f16700Schasinglulu #ifndef EHF_H 8*91f16700Schasinglulu #define EHF_H 9*91f16700Schasinglulu 10*91f16700Schasinglulu #ifndef __ASSEMBLER__ 11*91f16700Schasinglulu 12*91f16700Schasinglulu #include <cdefs.h> 13*91f16700Schasinglulu #include <stdint.h> 14*91f16700Schasinglulu 15*91f16700Schasinglulu #include <lib/utils_def.h> 16*91f16700Schasinglulu 17*91f16700Schasinglulu /* Valid priorities set bit 0 of the priority handler. */ 18*91f16700Schasinglulu #define EHF_PRI_VALID_ BIT(0) 19*91f16700Schasinglulu 20*91f16700Schasinglulu /* Marker for no handler registered for a valid priority */ 21*91f16700Schasinglulu #define EHF_NO_HANDLER_ (0U | EHF_PRI_VALID_) 22*91f16700Schasinglulu 23*91f16700Schasinglulu /* Extract the specified number of top bits from 7 lower bits of priority */ 24*91f16700Schasinglulu #define EHF_PRI_TO_IDX(pri, plat_bits) \ 25*91f16700Schasinglulu ((((unsigned) (pri)) & 0x7fu) >> (7u - (plat_bits))) 26*91f16700Schasinglulu 27*91f16700Schasinglulu /* Install exception priority descriptor at a suitable index */ 28*91f16700Schasinglulu #define EHF_PRI_DESC(plat_bits, priority) \ 29*91f16700Schasinglulu [EHF_PRI_TO_IDX(priority, plat_bits)] = { \ 30*91f16700Schasinglulu .ehf_handler = EHF_NO_HANDLER_, \ 31*91f16700Schasinglulu } 32*91f16700Schasinglulu 33*91f16700Schasinglulu /* Macro for platforms to register its exception priorities */ 34*91f16700Schasinglulu #define EHF_REGISTER_PRIORITIES(priorities, num, bits) \ 35*91f16700Schasinglulu const ehf_priorities_t exception_data = { \ 36*91f16700Schasinglulu .num_priorities = (num), \ 37*91f16700Schasinglulu .ehf_priorities = (priorities), \ 38*91f16700Schasinglulu .pri_bits = (bits), \ 39*91f16700Schasinglulu } 40*91f16700Schasinglulu 41*91f16700Schasinglulu /* 42*91f16700Schasinglulu * Priority stack, managed as a bitmap. 43*91f16700Schasinglulu * 44*91f16700Schasinglulu * Currently only supports 32 priority levels, allowing platforms to use up to 5 45*91f16700Schasinglulu * top bits of priority. But the type can be changed to uint64_t should need 46*91f16700Schasinglulu * arise to support 64 priority levels, allowing platforms to use up to 6 top 47*91f16700Schasinglulu * bits of priority. 48*91f16700Schasinglulu */ 49*91f16700Schasinglulu typedef uint32_t ehf_pri_bits_t; 50*91f16700Schasinglulu 51*91f16700Schasinglulu /* 52*91f16700Schasinglulu * Per-PE exception data. The data for each PE is kept as a per-CPU data field. 53*91f16700Schasinglulu * See cpu_data.h. 54*91f16700Schasinglulu */ 55*91f16700Schasinglulu typedef struct { 56*91f16700Schasinglulu ehf_pri_bits_t active_pri_bits; 57*91f16700Schasinglulu 58*91f16700Schasinglulu /* Priority mask value before any priority levels were active */ 59*91f16700Schasinglulu uint8_t init_pri_mask; 60*91f16700Schasinglulu 61*91f16700Schasinglulu /* Non-secure priority mask value stashed during Secure execution */ 62*91f16700Schasinglulu uint8_t ns_pri_mask; 63*91f16700Schasinglulu } __aligned(sizeof(uint64_t)) pe_exc_data_t; 64*91f16700Schasinglulu 65*91f16700Schasinglulu typedef int (*ehf_handler_t)(uint32_t intr_raw, uint32_t flags, void *handle, 66*91f16700Schasinglulu void *cookie); 67*91f16700Schasinglulu 68*91f16700Schasinglulu typedef struct ehf_pri_desc { 69*91f16700Schasinglulu /* 70*91f16700Schasinglulu * 4-byte-aligned exception handler. Bit 0 indicates the corresponding 71*91f16700Schasinglulu * priority level is valid. This is effectively of ehf_handler_t type, 72*91f16700Schasinglulu * but left as uintptr_t in order to make pointer arithmetic convenient. 73*91f16700Schasinglulu */ 74*91f16700Schasinglulu uintptr_t ehf_handler; 75*91f16700Schasinglulu } ehf_pri_desc_t; 76*91f16700Schasinglulu 77*91f16700Schasinglulu typedef struct ehf_priority_type { 78*91f16700Schasinglulu ehf_pri_desc_t *ehf_priorities; 79*91f16700Schasinglulu unsigned int num_priorities; 80*91f16700Schasinglulu unsigned int pri_bits; 81*91f16700Schasinglulu } ehf_priorities_t; 82*91f16700Schasinglulu 83*91f16700Schasinglulu void ehf_init(void); 84*91f16700Schasinglulu void ehf_activate_priority(unsigned int priority); 85*91f16700Schasinglulu void ehf_deactivate_priority(unsigned int priority); 86*91f16700Schasinglulu void ehf_register_priority_handler(unsigned int pri, ehf_handler_t handler); 87*91f16700Schasinglulu void ehf_allow_ns_preemption(uint64_t preempt_ret_code); 88*91f16700Schasinglulu unsigned int ehf_is_ns_preemption_allowed(void); 89*91f16700Schasinglulu 90*91f16700Schasinglulu #endif /* __ASSEMBLER__ */ 91*91f16700Schasinglulu 92*91f16700Schasinglulu #endif /* EHF_H */ 93