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