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, see <http://www.gnu.org/licenses/>. 15 * 16 * Copyright (C) Ashok Raj <ashok.raj@intel.com> 17 * Copyright (C) Shaohua Li <shaohua.li@intel.com> 18 */ 19 20 #ifndef _DMAR_H_ 21 #define _DMAR_H_ 22 23 #include <xen/list.h> 24 #include <xen/iommu.h> 25 #include <xen/kexec.h> 26 27 /* This one is for interrupt remapping */ 28 struct acpi_ioapic_unit { 29 struct list_head list; 30 int apic_id; 31 union { 32 u16 info; 33 struct { 34 u16 func: 3, 35 dev: 5, 36 bus: 8; 37 }bdf; 38 }ioapic; 39 }; 40 41 struct acpi_hpet_unit { 42 struct list_head list; 43 unsigned int id; 44 union { 45 u16 bdf; 46 struct { 47 u16 func: 3, 48 dev: 5, 49 bus: 8; 50 }; 51 }; 52 }; 53 54 struct dmar_scope { 55 DECLARE_BITMAP(buses, 256); /* buses owned by this unit */ 56 u16 *devices; /* devices owned by this unit */ 57 int devices_cnt; 58 }; 59 60 struct acpi_drhd_unit { 61 struct dmar_scope scope; 62 struct list_head list; 63 u64 address; /* register base address of the unit */ 64 u16 segment; 65 u8 include_all:1; 66 struct iommu *iommu; 67 struct list_head ioapic_list; 68 struct list_head hpet_list; 69 }; 70 71 struct acpi_rmrr_unit { 72 struct dmar_scope scope; 73 struct list_head list; 74 u64 base_address; 75 u64 end_address; 76 u16 segment; 77 u8 allow_all:1; 78 }; 79 80 struct acpi_atsr_unit { 81 struct dmar_scope scope; 82 struct list_head list; 83 u16 segment; 84 u8 all_ports:1; 85 }; 86 87 struct acpi_rhsa_unit { 88 struct list_head list; 89 u64 address; 90 u32 proximity_domain; 91 }; 92 93 #define for_each_drhd_unit(drhd) \ 94 list_for_each_entry(drhd, &acpi_drhd_units, list) 95 96 #define for_each_rmrr_device(rmrr, bdf, idx) \ 97 list_for_each_entry(rmrr, &acpi_rmrr_units, list) \ 98 /* assume there never is a bdf == 0 */ \ 99 for (idx = 0; (bdf = rmrr->scope.devices[idx]) && \ 100 idx < rmrr->scope.devices_cnt; idx++) 101 102 struct acpi_drhd_unit *acpi_find_matched_drhd_unit(const struct pci_dev *); 103 struct acpi_atsr_unit *acpi_find_matched_atsr_unit(const struct pci_dev *); 104 105 #define DMAR_TYPE 1 106 #define RMRR_TYPE 2 107 #define ATSR_TYPE 3 108 109 #define DMAR_OPERATION_TIMEOUT MILLISECS(1000) 110 111 #define IOMMU_WAIT_OP(iommu, offset, op, cond, sts) \ 112 do { \ 113 s_time_t start_time = NOW(); \ 114 while (1) { \ 115 sts = op(iommu->reg, offset); \ 116 if ( cond ) \ 117 break; \ 118 if ( NOW() > start_time + DMAR_OPERATION_TIMEOUT ) { \ 119 if ( !kexecing ) \ 120 panic("%s:%d:%s: DMAR hardware is malfunctional",\ 121 __FILE__, __LINE__, __func__); \ 122 else \ 123 break; \ 124 } \ 125 cpu_relax(); \ 126 } \ 127 } while (0) 128 129 int vtd_hw_check(void); 130 void disable_pmr(struct iommu *iommu); 131 int is_igd_drhd(struct acpi_drhd_unit *drhd); 132 133 #endif /* _DMAR_H_ */ 134