1 /*- 2 * Copyright (c) 2014 Tycho Nightingale <tycho.nightingale@pluribusnetworks.com> 3 * Copyright (c) 2017-2022 Intel Corporation. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * $FreeBSD$ 27 */ 28 29 #ifndef VPIC_H 30 #define VPIC_H 31 32 /** 33 * @file vpic.h 34 * 35 * @brief public APIs for virtual PIC 36 */ 37 38 39 #define ICU_IMR_OFFSET 1U 40 41 /* Initialization control word 1. Written to even address. */ 42 #define ICW1_IC4 0x01U /* ICW4 present */ 43 #define ICW1_SNGL 0x02U /* 1 = single, 0 = cascaded */ 44 #define ICW1_ADI 0x04U /* 1 = 4, 0 = 8 byte vectors */ 45 #define ICW1_LTIM 0x08U /* 1 = level trigger, 0 = edge */ 46 #define ICW1_RESET 0x10U /* must be 1 */ 47 /* 0x20 - 0x80 - in 8080/8085 mode only */ 48 49 /* Initialization control word 2. Written to the odd address. */ 50 /* No definitions, it is the base vector of the IDT for 8086 mode */ 51 52 /* Initialization control word 3. Written to the odd address. */ 53 /* For a primary PIC, bitfield indicating a secondary PIC on given input */ 54 /* For a secondary PIC, lower 3 bits are the PIC's ID binary id on primary PIC */ 55 56 /* Initialization control word 4. Written to the odd address. */ 57 #define ICW4_8086 0x01U /* 1 = 8086, 0 = 8080 */ 58 #define ICW4_AEOI 0x02U /* 1 = Auto EOI */ 59 #define ICW4_MS 0x04U /* 1 = buffered primary PIC, 0 = secondary PIC*/ 60 #define ICW4_BUF 0x08U /* 1 = enable buffer mode */ 61 #define ICW4_SFNM 0x10U /* 1 = special fully nested mode */ 62 63 /* Operation control words. Written after initialization. */ 64 65 /* Operation control word type 1 */ 66 /* 67 * No definitions. Written to the odd address. Bitmask for interrupts. 68 * 1 = disabled. 69 */ 70 71 /* Operation control word type 2. Bit 3 (0x08) must be zero. Even address. */ 72 #define OCW2_L0 0x01U /* Level */ 73 #define OCW2_L1 0x02U 74 #define OCW2_L2 0x04U 75 /* 0x08 must be 0 to select OCW2 vs OCW3 */ 76 /* 0x10 must be 0 to select OCW2 vs ICW1 */ 77 #define OCW2_EOI 0x20U /* 1 = EOI */ 78 #define OCW2_SL 0x40U /* EOI mode */ 79 #define OCW2_R 0x80U /* EOI mode */ 80 81 /* Operation control word type 3. Bit 3 (0x08) must be set. Even address. */ 82 #define OCW3_RIS 0x01U /* 1 = read IS, 0 = read IR */ 83 #define OCW3_RR 0x02U /* register read */ 84 #define OCW3_P 0x04U /* poll mode command */ 85 /* 0x08 must be 1 to select OCW3 vs OCW2 */ 86 #define OCW3_SEL 0x08U /* must be 1 */ 87 /* 0x10 must be 0 to select OCW3 vs ICW1 */ 88 #define OCW3_SMM 0x20U /* special mode mask */ 89 #define OCW3_ESMM 0x40U /* enable SMM */ 90 91 #define IO_ELCR1 0x4d0U 92 #define IO_ELCR2 0x4d1U 93 94 #define NR_VPIC_PINS_PER_CHIP 8U 95 #define NR_VPIC_PINS_TOTAL 16U 96 97 enum vpic_wire_mode { 98 VPIC_WIRE_INTR = 0, 99 VPIC_WIRE_LAPIC, 100 VPIC_WIRE_IOAPIC, 101 VPIC_WIRE_NULL 102 }; 103 104 enum vpic_trigger { 105 EDGE_TRIGGER, 106 LEVEL_TRIGGER 107 }; 108 109 struct i8259_reg_state { 110 bool ready; 111 uint8_t icw_num; 112 uint8_t rd_cmd_reg; 113 114 bool aeoi; 115 bool poll; 116 bool rotate; 117 bool sfn; /* special fully-nested mode */ 118 119 uint32_t irq_base; 120 uint8_t request; /* Interrupt Request Register (IIR) */ 121 uint8_t service; /* Interrupt Service (ISR) */ 122 uint8_t mask; /* Interrupt Mask Register (IMR) */ 123 uint8_t smm; /* special mask mode */ 124 125 uint8_t pin_state[8]; /* pin state for level */ 126 uint32_t lowprio; /* lowest priority irq */ 127 128 bool intr_raised; 129 uint8_t elc; 130 }; 131 132 struct acrn_vpic { 133 spinlock_t lock; 134 struct i8259_reg_state i8259[2]; 135 }; 136 137 struct acrn_vm; 138 void vpic_init(struct acrn_vm *vm); 139 140 /** 141 * @brief virtual PIC 142 * 143 * @addtogroup acrn_vpic ACRN vPIC 144 * @{ 145 */ 146 147 /** 148 * @brief Set vPIC IRQ line status. 149 * 150 * @param[in] vpic Pointer to target VM's vpic table 151 * @param[in] vgsi GSI for the virtual interrupt 152 * @param[in] operation action options:GSI_SET_HIGH/GSI_SET_LOW/ 153 * GSI_RAISING_PULSE/GSI_FALLING_PULSE 154 */ 155 void vpic_set_irqline(struct acrn_vpic *vpic, uint32_t vgsi, uint32_t operation); 156 157 /** 158 * @brief Get pending virtual interrupts for vPIC. 159 * 160 * @param[in] vpic Pointer to target VM's vpic table 161 * @param[inout] vecptr Pointer to vector buffer and will be filled 162 * with eligible vector if any. 163 */ 164 void vpic_pending_intr(struct acrn_vpic *vpic, uint32_t *vecptr); 165 166 /** 167 * @brief Accept virtual interrupt for vPIC. 168 * 169 * @param[in] vpic Pointer to target VM's vpic table 170 * @param[in] vector Target virtual interrupt vector 171 * 172 * @pre vm != NULL 173 */ 174 void vpic_intr_accepted(struct acrn_vpic *vpic, uint32_t vector); 175 void vpic_get_irqline_trigger_mode(const struct acrn_vpic *vpic, uint32_t vgsi, enum vpic_trigger *trigger); 176 uint32_t vpic_pincount(void); 177 struct acrn_vpic *vm_pic(const struct acrn_vm *vm); 178 179 /** 180 * @} 181 */ 182 /* End of acrn_vpic */ 183 184 #endif /* VPIC_H */ 185