1 /* 2 * Copyright (c) 2006, Intel Corporation. 3 * 4 * This program is free software; you can redistribute it and/or modify it 5 * under the terms and conditions of the GNU General Public License, 6 * version 2, as published by the Free Software Foundation. 7 * 8 * This program is distributed in the hope it will be useful, but WITHOUT 9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 11 * more details. 12 * 13 * You should have received a copy of the GNU General Public License along with 14 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple 15 * Place - Suite 330, Boston, MA 02111-1307 USA. 16 * 17 * Copyright (C) Ashok Raj <[email protected]> 18 * Copyright (C) Shaohua Li <[email protected]> 19 */ 20 21 #ifndef __DMAR_H__ 22 #define __DMAR_H__ 23 24 #include <linux/acpi.h> 25 #include <linux/types.h> 26 #include <linux/msi.h> 27 #include <linux/irqreturn.h> 28 29 /* DMAR Flags */ 30 #define DMAR_INTR_REMAP 0x1 31 #define DMAR_X2APIC_OPT_OUT 0x2 32 33 struct intel_iommu; 34 #ifdef CONFIG_DMAR_TABLE 35 extern struct acpi_table_header *dmar_tbl; 36 struct dmar_drhd_unit { 37 struct list_head list; /* list of drhd units */ 38 struct acpi_dmar_header *hdr; /* ACPI header */ 39 u64 reg_base_addr; /* register base address*/ 40 struct pci_dev **devices; /* target device array */ 41 int devices_cnt; /* target device count */ 42 u16 segment; /* PCI domain */ 43 u8 ignored:1; /* ignore drhd */ 44 u8 include_all:1; 45 struct intel_iommu *iommu; 46 }; 47 48 extern struct list_head dmar_drhd_units; 49 50 #define for_each_drhd_unit(drhd) \ 51 list_for_each_entry(drhd, &dmar_drhd_units, list) 52 53 #define for_each_active_iommu(i, drhd) \ 54 list_for_each_entry(drhd, &dmar_drhd_units, list) \ 55 if (i=drhd->iommu, drhd->ignored) {} else 56 57 #define for_each_iommu(i, drhd) \ 58 list_for_each_entry(drhd, &dmar_drhd_units, list) \ 59 if (i=drhd->iommu, 0) {} else 60 61 extern int dmar_table_init(void); 62 extern int dmar_dev_scope_init(void); 63 64 /* Intel IOMMU detection */ 65 extern int detect_intel_iommu(void); 66 extern int enable_drhd_fault_handling(void); 67 68 extern int parse_ioapics_under_ir(void); 69 extern int alloc_iommu(struct dmar_drhd_unit *); 70 #else 71 static inline int detect_intel_iommu(void) 72 { 73 return -ENODEV; 74 } 75 76 static inline int dmar_table_init(void) 77 { 78 return -ENODEV; 79 } 80 static inline int enable_drhd_fault_handling(void) 81 { 82 return -1; 83 } 84 #endif /* !CONFIG_DMAR_TABLE */ 85 86 struct irte { 87 union { 88 struct { 89 __u64 present : 1, 90 fpd : 1, 91 dst_mode : 1, 92 redir_hint : 1, 93 trigger_mode : 1, 94 dlvry_mode : 3, 95 avail : 4, 96 __reserved_1 : 4, 97 vector : 8, 98 __reserved_2 : 8, 99 dest_id : 32; 100 }; 101 __u64 low; 102 }; 103 104 union { 105 struct { 106 __u64 sid : 16, 107 sq : 2, 108 svt : 2, 109 __reserved_3 : 44; 110 }; 111 __u64 high; 112 }; 113 }; 114 115 #ifdef CONFIG_IRQ_REMAP 116 extern int intr_remapping_enabled; 117 extern int intr_remapping_supported(void); 118 extern int enable_intr_remapping(void); 119 extern void disable_intr_remapping(void); 120 extern int reenable_intr_remapping(int); 121 122 extern int get_irte(int irq, struct irte *entry); 123 extern int modify_irte(int irq, struct irte *irte_modified); 124 extern int alloc_irte(struct intel_iommu *iommu, int irq, u16 count); 125 extern int set_irte_irq(int irq, struct intel_iommu *iommu, u16 index, 126 u16 sub_handle); 127 extern int map_irq_to_irte_handle(int irq, u16 *sub_handle); 128 extern int free_irte(int irq); 129 130 extern struct intel_iommu *map_dev_to_ir(struct pci_dev *dev); 131 extern struct intel_iommu *map_ioapic_to_ir(int apic); 132 extern struct intel_iommu *map_hpet_to_ir(u8 id); 133 extern int set_ioapic_sid(struct irte *irte, int apic); 134 extern int set_hpet_sid(struct irte *irte, u8 id); 135 extern int set_msi_sid(struct irte *irte, struct pci_dev *dev); 136 #else 137 static inline int alloc_irte(struct intel_iommu *iommu, int irq, u16 count) 138 { 139 return -1; 140 } 141 static inline int modify_irte(int irq, struct irte *irte_modified) 142 { 143 return -1; 144 } 145 static inline int free_irte(int irq) 146 { 147 return -1; 148 } 149 static inline int map_irq_to_irte_handle(int irq, u16 *sub_handle) 150 { 151 return -1; 152 } 153 static inline int set_irte_irq(int irq, struct intel_iommu *iommu, u16 index, 154 u16 sub_handle) 155 { 156 return -1; 157 } 158 static inline struct intel_iommu *map_dev_to_ir(struct pci_dev *dev) 159 { 160 return NULL; 161 } 162 static inline struct intel_iommu *map_ioapic_to_ir(int apic) 163 { 164 return NULL; 165 } 166 static inline struct intel_iommu *map_hpet_to_ir(unsigned int hpet_id) 167 { 168 return NULL; 169 } 170 static inline int set_ioapic_sid(struct irte *irte, int apic) 171 { 172 return 0; 173 } 174 static inline int set_hpet_sid(struct irte *irte, u8 id) 175 { 176 return -1; 177 } 178 static inline int set_msi_sid(struct irte *irte, struct pci_dev *dev) 179 { 180 return 0; 181 } 182 183 #define intr_remapping_enabled (0) 184 185 static inline int enable_intr_remapping(void) 186 { 187 return -1; 188 } 189 190 static inline void disable_intr_remapping(void) 191 { 192 } 193 194 static inline int reenable_intr_remapping(int eim) 195 { 196 return 0; 197 } 198 #endif 199 200 enum { 201 IRQ_REMAP_XAPIC_MODE, 202 IRQ_REMAP_X2APIC_MODE, 203 }; 204 205 /* Can't use the common MSI interrupt functions 206 * since DMAR is not a pci device 207 */ 208 struct irq_data; 209 extern void dmar_msi_unmask(struct irq_data *data); 210 extern void dmar_msi_mask(struct irq_data *data); 211 extern void dmar_msi_read(int irq, struct msi_msg *msg); 212 extern void dmar_msi_write(int irq, struct msi_msg *msg); 213 extern int dmar_set_interrupt(struct intel_iommu *iommu); 214 extern irqreturn_t dmar_fault(int irq, void *dev_id); 215 extern int arch_setup_dmar_msi(unsigned int irq); 216 217 #ifdef CONFIG_INTEL_IOMMU 218 extern int iommu_detected, no_iommu; 219 extern struct list_head dmar_rmrr_units; 220 struct dmar_rmrr_unit { 221 struct list_head list; /* list of rmrr units */ 222 struct acpi_dmar_header *hdr; /* ACPI header */ 223 u64 base_address; /* reserved base address*/ 224 u64 end_address; /* reserved end address */ 225 struct pci_dev **devices; /* target devices */ 226 int devices_cnt; /* target device count */ 227 }; 228 229 #define for_each_rmrr_units(rmrr) \ 230 list_for_each_entry(rmrr, &dmar_rmrr_units, list) 231 232 struct dmar_atsr_unit { 233 struct list_head list; /* list of ATSR units */ 234 struct acpi_dmar_header *hdr; /* ACPI header */ 235 struct pci_dev **devices; /* target devices */ 236 int devices_cnt; /* target device count */ 237 u8 include_all:1; /* include all ports */ 238 }; 239 240 int dmar_parse_rmrr_atsr_dev(void); 241 extern int dmar_parse_one_rmrr(struct acpi_dmar_header *header); 242 extern int dmar_parse_one_atsr(struct acpi_dmar_header *header); 243 extern int dmar_parse_dev_scope(void *start, void *end, int *cnt, 244 struct pci_dev ***devices, u16 segment); 245 extern int intel_iommu_init(void); 246 #else /* !CONFIG_INTEL_IOMMU: */ 247 static inline int intel_iommu_init(void) { return -ENODEV; } 248 static inline int dmar_parse_one_rmrr(struct acpi_dmar_header *header) 249 { 250 return 0; 251 } 252 static inline int dmar_parse_one_atsr(struct acpi_dmar_header *header) 253 { 254 return 0; 255 } 256 static inline int dmar_parse_rmrr_atsr_dev(void) 257 { 258 return 0; 259 } 260 #endif /* CONFIG_INTEL_IOMMU */ 261 262 #endif /* __DMAR_H__ */ 263