1 #ifndef __ASM_MSI_H 2 #define __ASM_MSI_H 3 4 #include <xen/cpumask.h> 5 #include <xen/pci.h> 6 #include <asm/hvm/vmx/vmcs.h> 7 8 /* 9 * Constants for Intel APIC based MSI messages. 10 */ 11 12 /* 13 * Shifts for MSI data 14 */ 15 16 #define MSI_DATA_VECTOR_SHIFT 0 17 #define MSI_DATA_VECTOR_MASK 0x000000ff 18 #define MSI_DATA_VECTOR(v) (((v) << MSI_DATA_VECTOR_SHIFT) & MSI_DATA_VECTOR_MASK) 19 20 #define MSI_DATA_DELIVERY_MODE_SHIFT 8 21 #define MSI_DATA_DELIVERY_FIXED (0 << MSI_DATA_DELIVERY_MODE_SHIFT) 22 #define MSI_DATA_DELIVERY_LOWPRI (1 << MSI_DATA_DELIVERY_MODE_SHIFT) 23 #define MSI_DATA_DELIVERY_MODE_MASK 0x00000700 24 25 #define MSI_DATA_LEVEL_SHIFT 14 26 #define MSI_DATA_LEVEL_DEASSERT (0 << MSI_DATA_LEVEL_SHIFT) 27 #define MSI_DATA_LEVEL_ASSERT (1 << MSI_DATA_LEVEL_SHIFT) 28 29 #define MSI_DATA_TRIGGER_SHIFT 15 30 #define MSI_DATA_TRIGGER_EDGE (0 << MSI_DATA_TRIGGER_SHIFT) 31 #define MSI_DATA_TRIGGER_LEVEL (1 << MSI_DATA_TRIGGER_SHIFT) 32 #define MSI_DATA_TRIGGER_MASK 0x00008000 33 34 /* 35 * Shift/mask fields for msi address 36 */ 37 38 #define MSI_ADDR_BASE_HI 0 39 #define MSI_ADDR_BASE_LO 0xfee00000U 40 #define MSI_ADDR_BASE_MASK (~0xfffff) 41 #define MSI_ADDR_HEADER MSI_ADDR_BASE_LO 42 43 #define MSI_ADDR_DESTMODE_SHIFT 2 44 #define MSI_ADDR_DESTMODE_PHYS (0 << MSI_ADDR_DESTMODE_SHIFT) 45 #define MSI_ADDR_DESTMODE_LOGIC (1 << MSI_ADDR_DESTMODE_SHIFT) 46 #define MSI_ADDR_DESTMODE_MASK 0x4 47 48 #define MSI_ADDR_REDIRECTION_SHIFT 3 49 #define MSI_ADDR_REDIRECTION_CPU (0 << MSI_ADDR_REDIRECTION_SHIFT) 50 #define MSI_ADDR_REDIRECTION_LOWPRI (1 << MSI_ADDR_REDIRECTION_SHIFT) 51 #define MSI_ADDR_REDIRECTION_MASK (1 << MSI_ADDR_REDIRECTION_SHIFT) 52 53 #define MSI_ADDR_DEST_ID_SHIFT 12 54 #define MSI_ADDR_DEST_ID_MASK 0x00ff000 55 #define MSI_ADDR_DEST_ID(dest) (((dest) << MSI_ADDR_DEST_ID_SHIFT) & MSI_ADDR_DEST_ID_MASK) 56 57 /* MAX fixed pages reserved for mapping MSIX tables. */ 58 #define FIX_MSIX_MAX_PAGES 512 59 60 struct msi_info { 61 pci_sbdf_t sbdf; 62 int irq; 63 int entry_nr; 64 uint64_t table_base; 65 }; 66 67 struct msi_msg { 68 union { 69 uint64_t address; /* message address */ 70 struct { 71 uint32_t address_lo; /* message address low 32 bits */ 72 uint32_t address_hi; /* message address high 32 bits */ 73 }; 74 }; 75 uint32_t data; /* 16 bits of msi message data */ 76 uint32_t dest32; /* used when Interrupt Remapping is enabled */ 77 }; 78 79 struct irq_desc; 80 struct hw_interrupt_type; 81 struct msi_desc; 82 /* Helper functions */ 83 extern int pci_enable_msi(struct pci_dev *pdev, struct msi_info *msi, 84 struct msi_desc **desc); 85 extern void pci_disable_msi(struct msi_desc *msi_desc); 86 extern int pci_prepare_msix(u16 seg, u8 bus, u8 devfn, bool off); 87 extern void pci_cleanup_msi(struct pci_dev *pdev); 88 extern void pci_disable_msi_all(void); 89 extern int setup_msi_irq(struct irq_desc *desc, struct msi_desc *msidesc); 90 extern int __setup_msi_irq(struct irq_desc *desc, struct msi_desc *msidesc, 91 hw_irq_controller *handler); 92 extern void teardown_msi_irq(int irq); 93 extern int msi_free_vector(struct msi_desc *entry); 94 extern int pci_restore_msi_state(struct pci_dev *pdev); 95 extern int pci_reset_msix_state(struct pci_dev *pdev); 96 97 struct msi_desc { 98 struct msi_attrib { 99 uint8_t type; /* {0: unused, 5h:MSI, 11h:MSI-X} */ 100 uint8_t pos; /* Location of the MSI capability */ 101 bool maskbit : 1; /* mask/pending bit supported ? */ 102 bool is_64 : 1; /* Address size: 0=32bit 1=64bit */ 103 bool host_masked : 1; 104 bool guest_masked : 1; 105 uint16_t entry_nr; /* specific enabled entry */ 106 } msi_attrib; 107 108 bool irte_initialized; 109 uint8_t gvec; /* guest vector. valid when pi_desc isn't NULL */ 110 const struct pi_desc *pi_desc; /* pointer to posted descriptor */ 111 112 struct list_head list; 113 114 union { 115 void __iomem *mask_base; /* va for the entry in mask table */ 116 struct { 117 unsigned int nvec; /* number of vectors */ 118 unsigned int mpos; /* location of mask register */ 119 } msi; 120 unsigned int hpet_id; /* HPET (dev is NULL) */ 121 }; 122 struct pci_dev *dev; 123 int irq; 124 int remap_index; /* index in interrupt remapping table */ 125 126 struct msi_msg msg; /* Last set MSI message (untranslated) */ 127 }; 128 129 /* 130 * Values stored into msi_desc.msi_attrib.pos for non-PCI devices 131 * (msi_desc.msi_attrib.type is zero): 132 */ 133 #define MSI_TYPE_UNKNOWN 0 134 #define MSI_TYPE_HPET 1 135 #define MSI_TYPE_IOMMU 2 136 137 int msi_maskable_irq(const struct msi_desc *entry); 138 int msi_free_irq(struct msi_desc *entry); 139 140 /* 141 * Assume the maximum number of hot plug slots supported by the system is about 142 * ten. The worstcase is that each of these slots is hot-added with a device, 143 * which has two MSI/MSI-X capable functions. To avoid any MSI-X driver, which 144 * attempts to request all available vectors, NR_HP_RESERVED_VECTORS is defined 145 * as below to ensure at least one message is assigned to each detected MSI/ 146 * MSI-X device function. 147 */ 148 #define NR_HP_RESERVED_VECTORS 20 149 150 #define msi_control_reg(base) ((base) + PCI_MSI_FLAGS) 151 #define msi_lower_address_reg(base) ((base) + PCI_MSI_ADDRESS_LO) 152 #define msi_upper_address_reg(base) ((base) + PCI_MSI_ADDRESS_HI) 153 #define msi_data_reg(base, is64bit) \ 154 ((base) + ((is64bit) ? PCI_MSI_DATA_64 : PCI_MSI_DATA_32)) 155 #define msi_mask_bits_reg(base, is64bit) \ 156 ((base) + PCI_MSI_MASK_BIT - ((is64bit) ? 0 : 4)) 157 #define msi_pending_bits_reg(base, is64bit) \ 158 ((base) + PCI_MSI_MASK_BIT + ((is64bit) ? 4 : 0)) 159 #define multi_msi_capable(control) \ 160 (1U << MASK_EXTR(control, PCI_MSI_FLAGS_QMASK)) 161 #define multi_msi_enable(control, num) \ 162 ((control) |= MASK_INSR(fls(num) - 1, PCI_MSI_FLAGS_QSIZE)) 163 #define is_64bit_address(control) (!!((control) & PCI_MSI_FLAGS_64BIT)) 164 #define is_mask_bit_support(control) (!!((control) & PCI_MSI_FLAGS_MASKBIT)) 165 166 #define msix_control_reg(base) ((base) + PCI_MSIX_FLAGS) 167 #define msix_table_offset_reg(base) ((base) + PCI_MSIX_TABLE) 168 #define msix_pba_offset_reg(base) ((base) + PCI_MSIX_PBA) 169 #define msix_table_size(control) (((control) & PCI_MSIX_FLAGS_QSIZE) + 1) 170 171 /* 172 * MSI Defined Data Structures 173 */ 174 175 struct msg_data { 176 uint32_t vector : 8; 177 uint32_t delivery_mode : 3; /* 000b: FIXED | 001b: lowest prior */ 178 uint32_t : 3; 179 bool level : 1; /* 0: deassert | 1: assert */ 180 bool trigger : 1; /* 0: edge | 1: level */ 181 uint32_t : 16; 182 }; 183 184 struct msg_address { 185 union { 186 struct { 187 uint32_t : 2; 188 bool dest_mode : 1; /* 0:phys | 1:logic */ 189 bool redirection_hint : 1; /* 0: dedicated CPU 190 1: lowest priority */ 191 uint32_t : 4; 192 uint32_t dest_id : 24; /* Destination ID */ 193 } u; 194 uint32_t value; 195 } lo_address; 196 uint32_t hi_address; 197 }; 198 199 #define MAX_MSIX_TABLE_ENTRIES (PCI_MSIX_FLAGS_QSIZE + 1) 200 #define MAX_MSIX_TABLE_PAGES PFN_UP(MAX_MSIX_TABLE_ENTRIES * \ 201 PCI_MSIX_ENTRY_SIZE + \ 202 (~PCI_MSIX_BIRMASK & (PAGE_SIZE - 1))) 203 204 #define MSIX_CHECK_WARN(msix, domid, which) \ 205 ({ \ 206 if ( (msix)->warned_domid != (domid) ) \ 207 { \ 208 (msix)->warned_domid = (domid); \ 209 (msix)->warned_kind.all = 0; \ 210 } \ 211 (msix)->warned_kind.which ? false : ((msix)->warned_kind.which = true); \ 212 }) 213 214 struct arch_msix { 215 unsigned int nr_entries, used_entries; 216 struct { 217 unsigned long first, last; 218 } table, pba; 219 int table_refcnt[MAX_MSIX_TABLE_PAGES]; 220 int table_idx[MAX_MSIX_TABLE_PAGES]; 221 #define ADJ_IDX_FIRST 0 222 #define ADJ_IDX_LAST 1 223 unsigned int adj_access_idx[2]; 224 spinlock_t table_lock; 225 bool host_maskall, guest_maskall; 226 domid_t warned_domid; 227 union { 228 uint8_t all; 229 struct { 230 bool maskall : 1; 231 bool adjacent_not_initialized : 1; 232 bool adjacent_pba : 1; 233 }; 234 } warned_kind; 235 }; 236 237 void early_msi_init(void); 238 void msi_compose_msg(unsigned vector, const cpumask_t *cpu_mask, 239 struct msi_msg *msg); 240 void __msi_set_enable(pci_sbdf_t sbdf, int pos, int enable); 241 void cf_check mask_msi_irq(struct irq_desc *desc); 242 void cf_check unmask_msi_irq(struct irq_desc *desc); 243 void guest_mask_msi_irq(struct irq_desc *desc, bool mask); 244 void cf_check ack_nonmaskable_msi_irq(struct irq_desc *desc); 245 void cf_check set_msi_affinity(struct irq_desc *desc, const cpumask_t *mask); 246 247 #endif /* __ASM_MSI_H */ 248