1 /*
2  * Copyright (C) 2018-2022 Intel Corporation.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #ifndef ARCH_X86_IRQ_H
8 #define ARCH_X86_IRQ_H
9 
10 #include <types.h>
11 
12 /**
13  * @file arch/x86/asm/irq.h
14  *
15  * @brief public APIs for x86 IRQ handling
16  */
17 
18 #define DBG_LEVEL_PTIRQ		6U
19 #define DBG_LEVEL_IRQ		6U
20 
21 #define NR_MAX_VECTOR		0xFFU
22 #define VECTOR_INVALID		(NR_MAX_VECTOR + 1U)
23 
24 /* # of NR_STATIC_MAPPINGS_1 entries for timer, vcpu notify, and PMI */
25 #define NR_STATIC_MAPPINGS_1	4U
26 
27 /*
28  * The static IRQ/Vector mapping table in irq.c consists of the following entries:
29  * # of NR_STATIC_MAPPINGS_1 entries for timer, vcpu notify, and PMI
30  *
31  * # of CONFIG_MAX_VM_NUM entries for posted interrupt notification, platform
32  * specific but known at build time:
33  * Allocate unique Activation Notification Vectors (ANV) for each vCPU that belongs
34  * to the same pCPU, the ANVs need only be unique within each pCPU, not across all
35  * vCPUs. The max numbers of vCPUs may be running on top of a pCPU is CONFIG_MAX_VM_NUM,
36  * since ACRN does not support 2 vCPUs of same VM running on top of same pCPU.
37  * This reduces # of pre-allocated ANVs for posted interrupts to CONFIG_MAX_VM_NUM,
38  * and enables ACRN to avoid switching between active and wake-up vector values
39  * in the posted interrupt descriptor on vCPU scheduling state changes.
40  */
41 #define NR_STATIC_MAPPINGS	(NR_STATIC_MAPPINGS_1 + CONFIG_MAX_VM_NUM)
42 
43 #define HYPERVISOR_CALLBACK_HSM_VECTOR	0xF3U
44 
45 /* vectors range for dynamic allocation, usually for devices */
46 #define VECTOR_DYNAMIC_START	0x20U
47 #define VECTOR_DYNAMIC_END	0xDFU
48 
49 /* vectors range for fixed vectors, usually for HV service */
50 #define VECTOR_FIXED_START	0xE0U
51 #define VECTOR_FIXED_END	0xFFU
52 
53 #define TIMER_VECTOR		(VECTOR_FIXED_START)
54 #define NOTIFY_VCPU_VECTOR	(VECTOR_FIXED_START + 1U)
55 #define PMI_VECTOR		(VECTOR_FIXED_START + 2U)
56 #define THERMAL_VECTOR		(VECTOR_FIXED_START + 3U)
57 /*
58  * Starting vector for posted interrupts
59  * # of CONFIG_MAX_VM_NUM (POSTED_INTR_VECTOR ~ (POSTED_INTR_VECTOR + CONFIG_MAX_VM_NUM - 1U))
60  * consecutive vectors reserved for posted interrupts
61  */
62 #define POSTED_INTR_VECTOR	(VECTOR_FIXED_START + NR_STATIC_MAPPINGS_1)
63 
64 #define TIMER_IRQ		(NR_IRQS - 1U)
65 #define NOTIFY_VCPU_IRQ		(NR_IRQS - 2U)
66 #define PMI_IRQ			(NR_IRQS - 3U)
67 #define THERMAL_IRQ		(NR_IRQS - 4U)
68 /*
69  * Starting IRQ for posted interrupts
70  * # of CONFIG_MAX_VM_NUM (POSTED_INTR_IRQ ~ (POSTED_INTR_IRQ + CONFIG_MAX_VM_NUM - 1U))
71  * consecutive IRQs reserved for posted interrupts
72  */
73 #define POSTED_INTR_IRQ	(NR_IRQS - NR_STATIC_MAPPINGS_1 - CONFIG_MAX_VM_NUM)
74 
75 /* the maximum number of msi entry is 2048 according to PCI
76  * local bus specification
77  */
78 #define MAX_MSI_ENTRY 0x800U
79 
80 #define INVALID_INTERRUPT_PIN	0xffffffffU
81 
82 /*
83  * x86 irq data
84  */
85 struct x86_irq_data {
86 	uint32_t vector;	/**< assigned vector */
87 #ifdef PROFILING_ON
88 	uint64_t ctx_rip;
89 	uint64_t ctx_rflags;
90 	uint64_t ctx_cs;
91 #endif
92 };
93 
94 struct intr_excp_ctx;
95 
96 /**
97  * @brief Allocate a vectror and bind it to irq
98  *
99  * For legacy irq (num < 16) and statically mapped ones, do nothing
100  * if mapping is correct.
101  *
102  * @param[in]	irq	The irq num to bind
103  *
104  * @return valid vector num on susccess, VECTOR_INVALID on failure
105  */
106 uint32_t alloc_irq_vector(uint32_t irq);
107 
108 /**
109  * @brief Get vector number of an interrupt from irq number
110  *
111  * @param[in]	irq	The irq_num to convert
112  *
113  * @return vector number
114  */
115 uint32_t irq_to_vector(uint32_t irq);
116 
117 /**
118  * @brief Dispatch interrupt
119  *
120  * To dispatch an interrupt, an action callback will be called if registered.
121  *
122  * @param ctx Pointer to interrupt exception context
123  */
124 void dispatch_interrupt(const struct intr_excp_ctx *ctx);
125 
126 /* Arch specific routines called from generic IRQ handling */
127 
128 struct irq_desc;
129 
130 void init_irq_descs_arch(struct irq_desc *descs);
131 void setup_irqs_arch(void);
132 void init_interrupt_arch(uint16_t pcpu_id);
133 void free_irq_arch(uint32_t irq);
134 bool request_irq_arch(uint32_t irq);
135 void pre_irq_arch(const struct irq_desc *desc);
136 void post_irq_arch(const struct irq_desc *desc);
137 
138 #endif /* ARCH_X86_IRQ_H */
139