xref: /rk3399_ARM-atf/include/bl31/ehf.h (revision af34cd72ca3b716d8a9800c83b1577e3a39cf41b)
121b818c0SJeenu Viswambharan /*
2*af34cd72SJeenu Viswambharan  * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
321b818c0SJeenu Viswambharan  *
421b818c0SJeenu Viswambharan  * SPDX-License-Identifier: BSD-3-Clause
521b818c0SJeenu Viswambharan  */
621b818c0SJeenu Viswambharan 
721b818c0SJeenu Viswambharan #ifndef __EHF_H__
821b818c0SJeenu Viswambharan #define __EHF_H__
921b818c0SJeenu Viswambharan 
1021b818c0SJeenu Viswambharan #ifndef __ASSEMBLY__
1121b818c0SJeenu Viswambharan 
1221b818c0SJeenu Viswambharan #include <stdint.h>
1321b818c0SJeenu Viswambharan #include <utils_def.h>
1421b818c0SJeenu Viswambharan 
1521b818c0SJeenu Viswambharan /* Valid priorities set bit 0 of the priority handler. */
1621b818c0SJeenu Viswambharan #define _EHF_PRI_VALID	(((uintptr_t) 1) << 0)
1721b818c0SJeenu Viswambharan 
1821b818c0SJeenu Viswambharan /* Marker for no handler registered for a valid priority */
1921b818c0SJeenu Viswambharan #define _EHF_NO_HANDLER	(0 | _EHF_PRI_VALID)
2021b818c0SJeenu Viswambharan 
2121b818c0SJeenu Viswambharan /* Extract the specified number of top bits from 7 lower bits of priority */
2221b818c0SJeenu Viswambharan #define EHF_PRI_TO_IDX(pri, plat_bits) \
2321b818c0SJeenu Viswambharan 	((pri & 0x7f) >> (7 - plat_bits))
2421b818c0SJeenu Viswambharan 
2521b818c0SJeenu Viswambharan /* Install exception priority descriptor at a suitable index */
2621b818c0SJeenu Viswambharan #define EHF_PRI_DESC(plat_bits, priority) \
2721b818c0SJeenu Viswambharan 	[EHF_PRI_TO_IDX(priority, plat_bits)] = { \
2821b818c0SJeenu Viswambharan 		.ehf_handler = _EHF_NO_HANDLER, \
2921b818c0SJeenu Viswambharan 	}
3021b818c0SJeenu Viswambharan 
3121b818c0SJeenu Viswambharan /* Macro for platforms to regiter its exception priorities */
3221b818c0SJeenu Viswambharan #define EHF_REGISTER_PRIORITIES(priorities, num, bits) \
3321b818c0SJeenu Viswambharan 	const ehf_priorities_t exception_data = { \
3421b818c0SJeenu Viswambharan 		.num_priorities = num, \
3521b818c0SJeenu Viswambharan 		.ehf_priorities = priorities, \
3621b818c0SJeenu Viswambharan 		.pri_bits = bits, \
3721b818c0SJeenu Viswambharan 	}
3821b818c0SJeenu Viswambharan 
3921b818c0SJeenu Viswambharan /*
4021b818c0SJeenu Viswambharan  * Priority stack, managed as a bitmap.
4121b818c0SJeenu Viswambharan  *
4221b818c0SJeenu Viswambharan  * Currently only supports 32 priority levels, allowing platforms to use up to 5
4321b818c0SJeenu Viswambharan  * top bits of priority. But the type can be changed to uint64_t should need
4421b818c0SJeenu Viswambharan  * arise to support 64 priority levels, allowing platforms to use up to 6 top
4521b818c0SJeenu Viswambharan  * bits of priority.
4621b818c0SJeenu Viswambharan  */
4721b818c0SJeenu Viswambharan typedef uint32_t ehf_pri_bits_t;
4821b818c0SJeenu Viswambharan 
4921b818c0SJeenu Viswambharan /*
5021b818c0SJeenu Viswambharan  * Per-PE exception data. The data for each PE is kept as a per-CPU data field.
5121b818c0SJeenu Viswambharan  * See cpu_data.h.
5221b818c0SJeenu Viswambharan  */
5321b818c0SJeenu Viswambharan typedef struct {
5421b818c0SJeenu Viswambharan 	ehf_pri_bits_t active_pri_bits;
5521b818c0SJeenu Viswambharan 
5621b818c0SJeenu Viswambharan 	/* Priority mask value before any priority levels were active */
5721b818c0SJeenu Viswambharan 	uint8_t init_pri_mask;
583d732e23SJeenu Viswambharan 
593d732e23SJeenu Viswambharan 	/* Non-secure priority mask value stashed during Secure execution */
603d732e23SJeenu Viswambharan 	uint8_t ns_pri_mask;
6121b818c0SJeenu Viswambharan } __aligned(sizeof(uint64_t)) pe_exc_data_t;
6221b818c0SJeenu Viswambharan 
6321b818c0SJeenu Viswambharan typedef int (*ehf_handler_t)(uint32_t intr_raw, uint32_t flags, void *handle,
6421b818c0SJeenu Viswambharan 		void *cookie);
6521b818c0SJeenu Viswambharan 
6621b818c0SJeenu Viswambharan typedef struct ehf_pri_desc {
6721b818c0SJeenu Viswambharan 	/*
6821b818c0SJeenu Viswambharan 	 * 4-byte-aligned exception handler. Bit 0 indicates the corresponding
6921b818c0SJeenu Viswambharan 	 * priority level is valid. This is effectively of ehf_handler_t type,
7021b818c0SJeenu Viswambharan 	 * but left as uintptr_t in order to make pointer arithmetic convenient.
7121b818c0SJeenu Viswambharan 	 */
7221b818c0SJeenu Viswambharan 	uintptr_t ehf_handler;
7321b818c0SJeenu Viswambharan } ehf_pri_desc_t;
7421b818c0SJeenu Viswambharan 
7521b818c0SJeenu Viswambharan typedef struct ehf_priorities {
7621b818c0SJeenu Viswambharan 	ehf_pri_desc_t *ehf_priorities;
7721b818c0SJeenu Viswambharan 	unsigned int num_priorities;
7821b818c0SJeenu Viswambharan 	int pri_bits;
7921b818c0SJeenu Viswambharan } ehf_priorities_t;
8021b818c0SJeenu Viswambharan 
8121b818c0SJeenu Viswambharan void ehf_init(void);
8221b818c0SJeenu Viswambharan void ehf_activate_priority(unsigned int priority);
8321b818c0SJeenu Viswambharan void ehf_deactivate_priority(unsigned int priority);
8421b818c0SJeenu Viswambharan void ehf_register_priority_handler(unsigned int pri, ehf_handler_t handler);
85*af34cd72SJeenu Viswambharan void ehf_allow_ns_preemption(uint64_t preempt_ret_code);
863d732e23SJeenu Viswambharan unsigned int ehf_is_ns_preemption_allowed(void);
8721b818c0SJeenu Viswambharan 
8821b818c0SJeenu Viswambharan #endif /* __ASSEMBLY__ */
8921b818c0SJeenu Viswambharan 
9021b818c0SJeenu Viswambharan #endif /* __EHF_H__ */
91