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