| 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 | struct intel_iommu;
|
| 30 | #if defined(CONFIG_DMAR) || defined(CONFIG_INTR_REMAP)
|
| 31 | struct dmar_drhd_unit {
|
| 32 | struct list_head list;
|
| 33 | struct acpi_dmar_header *hdr;
|
| 34 | u64 reg_base_addr;
|
| 35 | struct pci_dev **devices;
|
| 36 | int devices_cnt;
|
| 37 | u16 segment;
|
| 38 | u8 ignored:1;
|
| 39 | u8 include_all:1;
|
| 40 | struct intel_iommu *iommu;
|
| 41 | };
|
| 42 |
|
| 43 | extern struct list_head dmar_drhd_units;
|
| 44 |
|
| 45 | #define for_each_drhd_unit(drhd) \
|
| 46 | list_for_each_entry(drhd, &dmar_drhd_units, list)
|
| 47 |
|
| 48 | #define for_each_active_iommu(i, drhd) \
|
| 49 | list_for_each_entry(drhd, &dmar_drhd_units, list) \
|
| 50 | if (i=drhd->iommu, drhd->ignored) {} else
|
| 51 |
|
| 52 | #define for_each_iommu(i, drhd) \
|
| 53 | list_for_each_entry(drhd, &dmar_drhd_units, list) \
|
| 54 | if (i=drhd->iommu, 0) {} else
|
| 55 |
|
| 56 | extern int dmar_table_init(void);
|
| 57 | extern int dmar_dev_scope_init(void);
|
| 58 |
|
| 59 |
|
| 60 | extern int detect_intel_iommu(void);
|
| 61 | extern int enable_drhd_fault_handling(void);
|
| 62 |
|
| 63 | extern int parse_ioapics_under_ir(void);
|
| 64 | extern int alloc_iommu(struct dmar_drhd_unit *);
|
| 65 | #else
|
| 66 | static inline int detect_intel_iommu(void)
|
| 67 | {
|
| 68 | return -ENODEV;
|
| 69 | }
|
| 70 |
|
| 71 | static inline int dmar_table_init(void)
|
| 72 | {
|
| 73 | return -ENODEV;
|
| 74 | }
|
| 75 | static inline int enable_drhd_fault_handling(void)
|
| 76 | {
|
| 77 | return -1;
|
| 78 | }
|
| 79 | #endif
|
| 80 |
|
| 81 | struct irte {
|
| 82 | union {
|
| 83 | struct {
|
| 84 | __u64 present : 1,
|
| 85 | fpd : 1,
|
| 86 | dst_mode : 1,
|
| 87 | redir_hint : 1,
|
| 88 | trigger_mode : 1,
|
| 89 | dlvry_mode : 3,
|
| 90 | avail : 4,
|
| 91 | __reserved_1 : 4,
|
| 92 | vector : 8,
|
| 93 | __reserved_2 : 8,
|
| 94 | dest_id : 32;
|
| 95 | };
|
| 96 | __u64 low;
|
| 97 | };
|
| 98 |
|
| 99 | union {
|
| 100 | struct {
|
| 101 | __u64 sid : 16,
|
| 102 | sq : 2,
|
| 103 | svt : 2,
|
| 104 | __reserved_3 : 44;
|
| 105 | };
|
| 106 | __u64 high;
|
| 107 | };
|
| 108 | };
|
| 109 |
|
| 110 | #ifdef CONFIG_INTR_REMAP
|
| 111 | extern int intr_remapping_enabled;
|
| 112 | extern int intr_remapping_supported(void);
|
| 113 | extern int enable_intr_remapping(int);
|
| 114 | extern void disable_intr_remapping(void);
|
| 115 | extern int reenable_intr_remapping(int);
|
| 116 |
|
| 117 | extern int get_irte(int irq, struct irte *entry);
|
| 118 | extern int modify_irte(int irq, struct irte *irte_modified);
|
| 119 | extern int alloc_irte(struct intel_iommu *iommu, int irq, u16 count);
|
| 120 | extern int set_irte_irq(int irq, struct intel_iommu *iommu, u16 index,
|
| 121 | u16 sub_handle);
|
| 122 | extern int map_irq_to_irte_handle(int irq, u16 *sub_handle);
|
| 123 | extern int free_irte(int irq);
|
| 124 |
|
| 125 | extern struct intel_iommu *map_dev_to_ir(struct pci_dev *dev);
|
| 126 | extern struct intel_iommu *map_ioapic_to_ir(int apic);
|
| 127 | extern struct intel_iommu *map_hpet_to_ir(u8 id);
|
| 128 | extern int set_ioapic_sid(struct irte *irte, int apic);
|
| 129 | extern int set_hpet_sid(struct irte *irte, u8 id);
|
| 130 | extern int set_msi_sid(struct irte *irte, struct pci_dev *dev);
|
| 131 | #else
|
| 132 | static inline int alloc_irte(struct intel_iommu *iommu, int irq, u16 count)
|
| 133 | {
|
| 134 | return -1;
|
| 135 | }
|
| 136 | static inline int modify_irte(int irq, struct irte *irte_modified)
|
| 137 | {
|
| 138 | return -1;
|
| 139 | }
|
| 140 | static inline int free_irte(int irq)
|
| 141 | {
|
| 142 | return -1;
|
| 143 | }
|
| 144 | static inline int map_irq_to_irte_handle(int irq, u16 *sub_handle)
|
| 145 | {
|
| 146 | return -1;
|
| 147 | }
|
| 148 | static inline int set_irte_irq(int irq, struct intel_iommu *iommu, u16 index,
|
| 149 | u16 sub_handle)
|
| 150 | {
|
| 151 | return -1;
|
| 152 | }
|
| 153 | static inline struct intel_iommu *map_dev_to_ir(struct pci_dev *dev)
|
| 154 | {
|
| 155 | return NULL;
|
| 156 | }
|
| 157 | static inline struct intel_iommu *map_ioapic_to_ir(int apic)
|
| 158 | {
|
| 159 | return NULL;
|
| 160 | }
|
| 161 | static inline struct intel_iommu *map_hpet_to_ir(unsigned int hpet_id)
|
| 162 | {
|
| 163 | return NULL;
|
| 164 | }
|
| 165 | static inline int set_ioapic_sid(struct irte *irte, int apic)
|
| 166 | {
|
| 167 | return 0;
|
| 168 | }
|
| 169 | static inline int set_hpet_sid(struct irte *irte, u8 id)
|
| 170 | {
|
| 171 | return -1;
|
| 172 | }
|
| 173 | static inline int set_msi_sid(struct irte *irte, struct pci_dev *dev)
|
| 174 | {
|
| 175 | return 0;
|
| 176 | }
|
| 177 |
|
| 178 | #define intr_remapping_enabled (0)
|
| 179 |
|
| 180 | static inline int enable_intr_remapping(int eim)
|
| 181 | {
|
| 182 | return -1;
|
| 183 | }
|
| 184 |
|
| 185 | static inline void disable_intr_remapping(void)
|
| 186 | {
|
| 187 | }
|
| 188 |
|
| 189 | static inline int reenable_intr_remapping(int eim)
|
| 190 | {
|
| 191 | return 0;
|
| 192 | }
|
| 193 | #endif
|
| 194 |
|
| 195 | |
| 196 | * since DMAR is not a pci device
|
| 197 |
|
| 198 | struct irq_data;
|
| 199 | extern void dmar_msi_unmask(struct irq_data *data);
|
| 200 | extern void dmar_msi_mask(struct irq_data *data);
|
| 201 | extern void dmar_msi_read(int irq, struct msi_msg *msg);
|
| 202 | extern void dmar_msi_write(int irq, struct msi_msg *msg);
|
| 203 | extern int dmar_set_interrupt(struct intel_iommu *iommu);
|
| 204 | extern irqreturn_t dmar_fault(int irq, void *dev_id);
|
| 205 | extern int arch_setup_dmar_msi(unsigned int irq);
|
| 206 |
|
| 207 | #ifdef CONFIG_DMAR
|
| 208 | extern int iommu_detected, no_iommu;
|
| 209 | extern struct list_head dmar_rmrr_units;
|
| 210 | struct dmar_rmrr_unit {
|
| 211 | struct list_head list;
|
| 212 | struct acpi_dmar_header *hdr;
|
| 213 | u64 base_address;
|
| 214 | u64 end_address;
|
| 215 | struct pci_dev **devices;
|
| 216 | int devices_cnt;
|
| 217 | };
|
| 218 |
|
| 219 | #define for_each_rmrr_units(rmrr) \
|
| 220 | list_for_each_entry(rmrr, &dmar_rmrr_units, list)
|
| 221 |
|
| 222 | struct dmar_atsr_unit {
|
| 223 | struct list_head list;
|
| 224 | struct acpi_dmar_header *hdr;
|
| 225 | struct pci_dev **devices;
|
| 226 | int devices_cnt;
|
| 227 | u8 include_all:1;
|
| 228 | };
|
| 229 |
|
| 230 | extern int intel_iommu_init(void);
|
| 231 | #else
|
| 232 | static inline int intel_iommu_init(void) { return -ENODEV; }
|
| 233 | #endif
|
| 234 |
|
| 235 | #endif
|