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