1 /*
2 * This program is free software; you can redistribute it and/or modify it
3 * under the terms and conditions of the GNU General Public License,
4 * version 2, as published by the Free Software Foundation.
5 *
6 * This program is distributed in the hope it will be useful, but WITHOUT
7 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
8 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
9 * more details.
10 *
11 * You should have received a copy of the GNU General Public License along with
12 * this program; If not, see <http://www.gnu.org/licenses/>.
13 */
14 #ifndef __ARCH_X86_IOMMU_H__
15 #define __ARCH_X86_IOMMU_H__
16
17 #include <xen/errno.h>
18 #include <xen/list.h>
19 #include <xen/spinlock.h>
20 #include <asm/processor.h>
21 #include <asm/hvm/vmx/vmcs.h>
22
23 #define DEFAULT_DOMAIN_ADDRESS_WIDTH 48
24 #define MAX_IOMMUS 32
25
26 struct g2m_ioport {
27 struct list_head list;
28 unsigned int gport;
29 unsigned int mport;
30 unsigned int np;
31 };
32
33 struct arch_iommu
34 {
35 u64 pgd_maddr; /* io page directory machine address */
36 spinlock_t mapping_lock; /* io page table lock */
37 int agaw; /* adjusted guest address width, 0 is level 2 30-bit */
38 u64 iommu_bitmap; /* bitmap of iommu(s) that the domain uses */
39 struct list_head mapped_rmrrs;
40
41 /* amd iommu support */
42 int paging_mode;
43 struct page_info *root_table;
44 struct guest_iommu *g_iommu;
45 };
46
47 extern const struct iommu_ops intel_iommu_ops;
48 extern const struct iommu_ops amd_iommu_ops;
49 int intel_vtd_setup(void);
50 int amd_iov_detect(void);
51
iommu_get_ops(void)52 static inline const struct iommu_ops *iommu_get_ops(void)
53 {
54 switch ( boot_cpu_data.x86_vendor )
55 {
56 case X86_VENDOR_INTEL:
57 return &intel_iommu_ops;
58 case X86_VENDOR_AMD:
59 return &amd_iommu_ops;
60 }
61
62 BUG();
63
64 return NULL;
65 }
66
iommu_hardware_setup(void)67 static inline int iommu_hardware_setup(void)
68 {
69 switch ( boot_cpu_data.x86_vendor )
70 {
71 case X86_VENDOR_INTEL:
72 return intel_vtd_setup();
73 case X86_VENDOR_AMD:
74 return amd_iov_detect();
75 }
76
77 return -ENODEV;
78 }
79
80 /* Does this domain have a P2M table we can use as its IOMMU pagetable? */
81 #define iommu_use_hap_pt(d) (hap_enabled(d) && iommu_hap_pt_share)
82
83 void iommu_update_ire_from_apic(unsigned int apic, unsigned int reg, unsigned int value);
84 unsigned int iommu_read_apic_from_ire(unsigned int apic, unsigned int reg);
85 int iommu_setup_hpet_msi(struct msi_desc *);
86
87 /* While VT-d specific, this must get declared in a generic header. */
88 int adjust_vtd_irq_affinities(void);
89 int __must_check iommu_pte_flush(struct domain *d, u64 gfn, u64 *pte,
90 int order, int present);
91 bool_t iommu_supports_eim(void);
92 int iommu_enable_x2apic_IR(void);
93 void iommu_disable_x2apic_IR(void);
94
95 extern bool untrusted_msi;
96
97 int pi_update_irte(const struct pi_desc *pi_desc, const struct pirq *pirq,
98 const uint8_t gvec);
99
100 #endif /* !__ARCH_X86_IOMMU_H__ */
101 /*
102 * Local variables:
103 * mode: C
104 * c-file-style: "BSD"
105 * c-basic-offset: 4
106 * indent-tabs-mode: nil
107 * End:
108 */
109