ia64/xen-unstable
changeset 15907:ca495837a722
Generic and VT-d specific Xen header changes for PCI passthru.
Signed-off-by: Allen Kay <allen.m.kay@intel.com>
Signed-off-by: Guy Zana <guy@neocleus.com>
Signed-off-by: Allen Kay <allen.m.kay@intel.com>
Signed-off-by: Guy Zana <guy@neocleus.com>
author | kfraser@localhost.localdomain |
---|---|
date | Wed Sep 12 15:42:39 2007 +0100 (2007-09-12) |
parents | 9dd580b8b056 |
children | a79d2c043643 |
files | xen/include/asm-x86/acpi.h xen/include/asm-x86/fixmap.h xen/include/asm-x86/hvm/domain.h xen/include/asm-x86/hvm/io.h xen/include/asm-x86/hvm/iommu.h xen/include/asm-x86/hvm/irq.h xen/include/asm-x86/hvm/vmx/intel-iommu.h xen/include/asm-x86/iommu.h xen/include/asm-x86/system.h xen/include/public/domctl.h xen/include/xen/acpi.h xen/include/xen/irq.h |
line diff
1.1 --- a/xen/include/asm-x86/acpi.h Wed Sep 12 15:32:58 2007 +0100 1.2 +++ b/xen/include/asm-x86/acpi.h Wed Sep 12 15:42:39 2007 +0100 1.3 @@ -196,4 +196,6 @@ struct acpi_sleep_info { 1.4 extern u8 x86_acpiid_to_apicid[]; 1.5 #define MAX_LOCAL_APIC 256 1.6 1.7 +extern int acpi_dmar_init(void); 1.8 + 1.9 #endif /*_ASM_ACPI_H*/
2.1 --- a/xen/include/asm-x86/fixmap.h Wed Sep 12 15:32:58 2007 +0100 2.2 +++ b/xen/include/asm-x86/fixmap.h Wed Sep 12 15:42:39 2007 +0100 2.3 @@ -17,6 +17,7 @@ 2.4 #include <asm/acpi.h> 2.5 #include <asm/page.h> 2.6 #include <xen/kexec.h> 2.7 +#include <asm/iommu.h> 2.8 2.9 /* 2.10 * Here we define all the compile-time 'special' virtual 2.11 @@ -40,6 +41,8 @@ enum fixed_addresses { 2.12 FIX_KEXEC_BASE_0, 2.13 FIX_KEXEC_BASE_END = FIX_KEXEC_BASE_0 \ 2.14 + ((KEXEC_XEN_NO_PAGES >> 1) * KEXEC_IMAGE_NR) - 1, 2.15 + FIX_IOMMU_REGS_BASE_0, 2.16 + FIX_IOMMU_REGS_END = FIX_IOMMU_REGS_BASE_0 + MAX_IOMMUS-1, 2.17 __end_of_fixed_addresses 2.18 }; 2.19
3.1 --- a/xen/include/asm-x86/hvm/domain.h Wed Sep 12 15:32:58 2007 +0100 3.2 +++ b/xen/include/asm-x86/hvm/domain.h Wed Sep 12 15:42:39 2007 +0100 3.3 @@ -21,10 +21,12 @@ 3.4 #ifndef __ASM_X86_HVM_DOMAIN_H__ 3.5 #define __ASM_X86_HVM_DOMAIN_H__ 3.6 3.7 +#include <asm/iommu.h> 3.8 #include <asm/hvm/irq.h> 3.9 #include <asm/hvm/vpt.h> 3.10 #include <asm/hvm/vlapic.h> 3.11 #include <asm/hvm/io.h> 3.12 +#include <asm/hvm/iommu.h> 3.13 #include <public/hvm/params.h> 3.14 #include <public/hvm/save.h> 3.15 3.16 @@ -57,6 +59,9 @@ struct hvm_domain { 3.17 uint64_t params[HVM_NR_PARAMS]; 3.18 3.19 unsigned long vmx_apic_access_mfn; 3.20 + 3.21 + /* Pass-through */ 3.22 + struct hvm_iommu hvm_iommu; 3.23 }; 3.24 3.25 #endif /* __ASM_X86_HVM_DOMAIN_H__ */
4.1 --- a/xen/include/asm-x86/hvm/io.h Wed Sep 12 15:32:58 2007 +0100 4.2 +++ b/xen/include/asm-x86/hvm/io.h Wed Sep 12 15:42:39 2007 +0100 4.3 @@ -151,6 +151,7 @@ void send_invalidate_req(void); 4.4 extern void handle_mmio(unsigned long gpa); 4.5 extern void hvm_interrupt_post(struct vcpu *v, int vector, int type); 4.6 extern void hvm_io_assist(void); 4.7 +extern void hvm_dpci_eoi(unsigned int guest_irq, union vioapic_redir_entry *ent); 4.8 4.9 #endif /* __ASM_X86_HVM_IO_H__ */ 4.10
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 5.2 +++ b/xen/include/asm-x86/hvm/iommu.h Wed Sep 12 15:42:39 2007 +0100 5.3 @@ -0,0 +1,40 @@ 5.4 +/* 5.5 + * Copyright (c) 2006, Intel Corporation. 5.6 + * 5.7 + * This program is free software; you can redistribute it and/or modify it 5.8 + * under the terms and conditions of the GNU General Public License, 5.9 + * version 2, as published by the Free Software Foundation. 5.10 + * 5.11 + * This program is distributed in the hope it will be useful, but WITHOUT 5.12 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 5.13 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 5.14 + * more details. 5.15 + * 5.16 + * You should have received a copy of the GNU General Public License along with 5.17 + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple 5.18 + * Place - Suite 330, Boston, MA 02111-1307 USA. 5.19 + * 5.20 + * Copyright (C) Allen Kay <allen.m.kay@intel.com> 5.21 + */ 5.22 + 5.23 +#ifndef __ASM_X86_HVM_IOMMU_H__ 5.24 +#define __ASM_X86_HVM_IOMMU_H__ 5.25 + 5.26 +#include <asm/iommu.h> 5.27 +#include <asm/hvm/irq.h> 5.28 +#include <asm/hvm/vpt.h> 5.29 +#include <asm/hvm/vlapic.h> 5.30 +#include <asm/hvm/io.h> 5.31 +#include <public/hvm/params.h> 5.32 +#include <public/hvm/save.h> 5.33 + 5.34 +struct hvm_iommu { 5.35 + spinlock_t iommu_list_lock; /* protect iommu specific lists */ 5.36 + struct list_head pdev_list; /* direct accessed pci devices */ 5.37 + struct dma_pte *pgd; /* io page directory root */ 5.38 + spinlock_t mapping_lock; /* io page table lock */ 5.39 + int agaw; /* adjusted guest address width, 0 is level 2 30-bit */ 5.40 + struct list_head g2m_ioport_list; /* guest to machine ioport mapping */ 5.41 +}; 5.42 + 5.43 +#endif // __ASM_X86_HVM_IOMMU_H__
6.1 --- a/xen/include/asm-x86/hvm/irq.h Wed Sep 12 15:32:58 2007 +0100 6.2 +++ b/xen/include/asm-x86/hvm/irq.h Wed Sep 12 15:42:39 2007 +0100 6.3 @@ -29,6 +29,16 @@ 6.4 #include <asm/hvm/vioapic.h> 6.5 #include <public/hvm/save.h> 6.6 6.7 +struct hvm_irq_mapping { 6.8 + uint8_t valid; 6.9 + uint8_t device; 6.10 + uint8_t intx; 6.11 + union { 6.12 + uint8_t guest_gsi; 6.13 + uint8_t machine_gsi; 6.14 + }; 6.15 +}; 6.16 + 6.17 struct hvm_irq { 6.18 /* 6.19 * Virtual interrupt wires for a single PCI bus. 6.20 @@ -88,6 +98,12 @@ struct hvm_irq { 6.21 6.22 /* Last VCPU that was delivered a LowestPrio interrupt. */ 6.23 u8 round_robin_prev_vcpu; 6.24 + 6.25 + /* machine irq to guest device/intx mapping */ 6.26 + struct hvm_irq_mapping mirq[NR_IRQS]; 6.27 + /* guest irq to guest device/intx mapping */ 6.28 + struct hvm_irq_mapping girq[NR_IRQS]; 6.29 + DECLARE_BITMAP(dirq_mask, NR_IRQS); 6.30 }; 6.31 6.32 #define hvm_pci_intx_gsi(dev, intx) \
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 7.2 +++ b/xen/include/asm-x86/hvm/vmx/intel-iommu.h Wed Sep 12 15:42:39 2007 +0100 7.3 @@ -0,0 +1,401 @@ 7.4 +/* 7.5 + * Copyright (c) 2006, Intel Corporation. 7.6 + * 7.7 + * This program is free software; you can redistribute it and/or modify it 7.8 + * under the terms and conditions of the GNU General Public License, 7.9 + * version 2, as published by the Free Software Foundation. 7.10 + * 7.11 + * This program is distributed in the hope it will be useful, but WITHOUT 7.12 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 7.13 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 7.14 + * more details. 7.15 + * 7.16 + * You should have received a copy of the GNU General Public License along with 7.17 + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple 7.18 + * Place - Suite 330, Boston, MA 02111-1307 USA. 7.19 + * 7.20 + * Copyright (C) Ashok Raj <ashok.raj@intel.com> 7.21 + */ 7.22 + 7.23 +#ifndef _INTEL_IOMMU_H_ 7.24 +#define _INTEL_IOMMU_H_ 7.25 + 7.26 +#include <xen/types.h> 7.27 + 7.28 +/* 7.29 + * Intel IOMMU register specification per version 1.0 public spec. 7.30 + */ 7.31 + 7.32 +#define DMAR_VER_REG 0x0 /* Arch version supported by this IOMMU */ 7.33 +#define DMAR_CAP_REG 0x8 /* Hardware supported capabilities */ 7.34 +#define DMAR_ECAP_REG 0x10 /* Extended capabilities supported */ 7.35 +#define DMAR_GCMD_REG 0x18 /* Global command register */ 7.36 +#define DMAR_GSTS_REG 0x1c /* Global status register */ 7.37 +#define DMAR_RTADDR_REG 0x20 /* Root entry table */ 7.38 +#define DMAR_CCMD_REG 0x28 /* Context command reg */ 7.39 +#define DMAR_FSTS_REG 0x34 /* Fault Status register */ 7.40 +#define DMAR_FECTL_REG 0x38 /* Fault control register */ 7.41 +#define DMAR_FEDATA_REG 0x3c /* Fault event interrupt data register */ 7.42 +#define DMAR_FEADDR_REG 0x40 /* Fault event interrupt addr register */ 7.43 +#define DMAR_FEUADDR_REG 0x44 /* Upper address register */ 7.44 +#define DMAR_AFLOG_REG 0x58 /* Advanced Fault control */ 7.45 +#define DMAR_PMEN_REG 0x64 /* Enable Protected Memory Region */ 7.46 +#define DMAR_PLMBASE_REG 0x68 /* PMRR Low addr */ 7.47 +#define DMAR_PLMLIMIT_REG 0x6c /* PMRR low limit */ 7.48 +#define DMAR_PHMBASE_REG 0x70 /* pmrr high base addr */ 7.49 +#define DMAR_PHMLIMIT_REG 0x78 /* pmrr high limit */ 7.50 +#define DMAR_IQH_REG 0x80 /* invalidation queue head */ 7.51 +#define DMAR_IQT_REG 0x88 /* invalidation queue tail */ 7.52 +#define DMAR_IQA_REG 0x90 /* invalidation queue addr */ 7.53 +#define DMAR_IRTA_REG 0xB8 /* intr remap */ 7.54 + 7.55 +#define OFFSET_STRIDE (9) 7.56 +#define dmar_readl(dmar, reg) readl(dmar + reg) 7.57 +#define dmar_writel(dmar, reg, val) writel(val, dmar + reg) 7.58 +#define dmar_readq(dmar, reg) ({ \ 7.59 + u32 lo, hi; \ 7.60 + lo = dmar_readl(dmar, reg); \ 7.61 + hi = dmar_readl(dmar, reg + 4); \ 7.62 + (((u64) hi) << 32) + lo; }) 7.63 +#define dmar_writeq(dmar, reg, val) do {\ 7.64 + dmar_writel(dmar, reg, (u32)val); \ 7.65 + dmar_writel(dmar, reg + 4, (u32)((u64) val >> 32)); \ 7.66 + } while (0) 7.67 + 7.68 +#define VER_MAJOR(v) (((v) & 0xf0) >> 4) 7.69 +#define VER_MINOR(v) ((v) & 0x0f) 7.70 + 7.71 +/* 7.72 + * Decoding Capability Register 7.73 + */ 7.74 +#define cap_read_drain(c) (((c) >> 55) & 1) 7.75 +#define cap_write_drain(c) (((c) >> 54) & 1) 7.76 +#define cap_max_amask_val(c) (((c) >> 48) & 0x3f) 7.77 +#define cap_num_fault_regs(c) ((((c) >> 40) & 0xff) + 1) 7.78 +#define cap_pgsel_inv(c) (((c) >> 39) & 1) 7.79 + 7.80 +#define cap_super_page_val(c) (((c) >> 34) & 0xf) 7.81 +#define cap_super_offset(c) (((find_first_bit(&cap_super_page_val(c), 4)) \ 7.82 + * OFFSET_STRIDE) + 21) 7.83 + 7.84 +#define cap_fault_reg_offset(c) ((((c) >> 24) & 0x3ff) * 16) 7.85 + 7.86 +#define cap_isoch(c) (((c) >> 23) & 1) 7.87 +#define cap_qos(c) (((c) >> 22) & 1) 7.88 +#define cap_mgaw(c) ((((c) >> 16) & 0x3f) + 1) 7.89 +#define cap_sagaw(c) (((c) >> 8) & 0x1f) 7.90 +#define cap_caching_mode(c) (((c) >> 7) & 1) 7.91 +#define cap_phmr(c) (((c) >> 6) & 1) 7.92 +#define cap_plmr(c) (((c) >> 5) & 1) 7.93 +#define cap_rwbf(c) (((c) >> 4) & 1) 7.94 +#define cap_afl(c) (((c) >> 3) & 1) 7.95 +#define cap_ndoms(c) (2 ^ (4 + 2 * ((c) & 0x7))) 7.96 +/* 7.97 + * Extended Capability Register 7.98 + */ 7.99 + 7.100 +#define ecap_niotlb_iunits(e) ((((e) >> 24) & 0xff) + 1) 7.101 +#define ecap_iotlb_offset(e) ((((e) >> 8) & 0x3ff) * 16) 7.102 +#define ecap_coherent(e) ((e >> 0) & 0x1) 7.103 +#define ecap_queued_inval(e) ((e >> 1) & 0x1) 7.104 +#define ecap_dev_iotlb(e) ((e >> 2) & 0x1) 7.105 +#define ecap_intr_remap(e) ((e >> 3) & 0x1) 7.106 +#define ecap_ext_intr(e) ((e >> 4) & 0x1) 7.107 +#define ecap_cache_hints(e) ((e >> 5) & 0x1) 7.108 +#define ecap_pass_thru(e) ((e >> 6) & 0x1) 7.109 + 7.110 +#define PAGE_SHIFT_4K (12) 7.111 +#define PAGE_SIZE_4K (1UL << PAGE_SHIFT_4K) 7.112 +#define PAGE_MASK_4K (((u64)-1) << PAGE_SHIFT_4K) 7.113 +#define PAGE_ALIGN_4K(addr) (((addr) + PAGE_SIZE_4K - 1) & PAGE_MASK_4K) 7.114 + 7.115 +/* IOTLB_REG */ 7.116 +#define DMA_TLB_FLUSH_GRANU_OFFSET 60 7.117 +#define DMA_TLB_GLOBAL_FLUSH (((u64)1) << 60) 7.118 +#define DMA_TLB_DSI_FLUSH (((u64)2) << 60) 7.119 +#define DMA_TLB_PSI_FLUSH (((u64)3) << 60) 7.120 +#define DMA_TLB_IIRG(x) (((x) >> 60) & 7) 7.121 +#define DMA_TLB_IAIG(val) (((val) >> 57) & 7) 7.122 +#define DMA_TLB_DID(x) (((u64)(x & 0xffff)) << 32) 7.123 + 7.124 +#define DMA_TLB_READ_DRAIN (((u64)1) << 49) 7.125 +#define DMA_TLB_WRITE_DRAIN (((u64)1) << 48) 7.126 +#define DMA_TLB_IVT (((u64)1) << 63) 7.127 + 7.128 +#define DMA_TLB_IVA_ADDR(x) ((((u64)x) >> 12) << 12) 7.129 +#define DMA_TLB_IVA_HINT(x) ((((u64)x) & 1) << 6) 7.130 + 7.131 +/* GCMD_REG */ 7.132 +#define DMA_GCMD_TE (((u64)1) << 31) 7.133 +#define DMA_GCMD_SRTP (((u64)1) << 30) 7.134 +#define DMA_GCMD_SFL (((u64)1) << 29) 7.135 +#define DMA_GCMD_EAFL (((u64)1) << 28) 7.136 +#define DMA_GCMD_WBF (((u64)1) << 27) 7.137 +#define DMA_GCMD_QIE (((u64)1) << 26) 7.138 +#define DMA_GCMD_IRE (((u64)1) << 25) 7.139 +#define DMA_GCMD_SIRTP (((u64)1) << 24) 7.140 + 7.141 +/* GSTS_REG */ 7.142 +#define DMA_GSTS_TES (((u64)1) << 31) 7.143 +#define DMA_GSTS_RTPS (((u64)1) << 30) 7.144 +#define DMA_GSTS_FLS (((u64)1) << 29) 7.145 +#define DMA_GSTS_AFLS (((u64)1) << 28) 7.146 +#define DMA_GSTS_WBFS (((u64)1) << 27) 7.147 +#define DMA_GSTS_IRTPS (((u64)1) << 24) 7.148 +#define DMA_GSTS_QIES (((u64)1) <<26) 7.149 +#define DMA_GSTS_IRES (((u64)1) <<25) 7.150 + 7.151 +/* CCMD_REG */ 7.152 +#define DMA_CCMD_INVL_GRANU_OFFSET 61 7.153 +#define DMA_CCMD_ICC (((u64)1) << 63) 7.154 +#define DMA_CCMD_GLOBAL_INVL (((u64)1) << 61) 7.155 +#define DMA_CCMD_DOMAIN_INVL (((u64)2) << 61) 7.156 +#define DMA_CCMD_DEVICE_INVL (((u64)3) << 61) 7.157 +#define DMA_CCMD_FM(m) (((u64)((m) & 0x3)) << 32) 7.158 +#define DMA_CCMD_CIRG(x) ((((u64)3) << 61) & x) 7.159 +#define DMA_CCMD_MASK_NOBIT 0 7.160 +#define DMA_CCMD_MASK_1BIT 1 7.161 +#define DMA_CCMD_MASK_2BIT 2 7.162 +#define DMA_CCMD_MASK_3BIT 3 7.163 +#define DMA_CCMD_SID(s) (((u64)((s) & 0xffff)) << 16) 7.164 +#define DMA_CCMD_DID(d) ((u64)((d) & 0xffff)) 7.165 + 7.166 +#define DMA_CCMD_CAIG_MASK(x) (((u64)x) & ((u64) 0x3 << 59)) 7.167 + 7.168 +/* FECTL_REG */ 7.169 +#define DMA_FECTL_IM (((u64)1) << 31) 7.170 + 7.171 +/* FSTS_REG */ 7.172 +#define DMA_FSTS_PPF ((u64)2) 7.173 +#define DMA_FSTS_PFO ((u64)1) 7.174 +#define dma_fsts_fault_record_index(s) (((s) >> 8) & 0xff) 7.175 + 7.176 +/* FRCD_REG, 32 bits access */ 7.177 +#define DMA_FRCD_F (((u64)1) << 31) 7.178 +#define dma_frcd_type(d) ((d >> 30) & 1) 7.179 +#define dma_frcd_fault_reason(c) (c & 0xff) 7.180 +#define dma_frcd_source_id(c) (c & 0xffff) 7.181 +#define dma_frcd_page_addr(d) (d & (((u64)-1) << 12)) /* low 64 bit */ 7.182 + 7.183 +/* 7.184 + * 0: Present 7.185 + * 1-11: Reserved 7.186 + * 12-63: Context Ptr (12 - (haw-1)) 7.187 + * 64-127: Reserved 7.188 + */ 7.189 +struct root_entry { 7.190 + u64 val; 7.191 + u64 rsvd1; 7.192 +}; 7.193 +#define root_present(root) ((root).val & 1) 7.194 +#define set_root_present(root) do {(root).val |= 1;} while(0) 7.195 +#define get_context_addr(root) ((root).val & PAGE_MASK_4K) 7.196 +#define set_root_value(root, value) \ 7.197 + do {(root).val |= ((value) & PAGE_MASK_4K);} while(0) 7.198 + 7.199 +struct context_entry { 7.200 + u64 lo; 7.201 + u64 hi; 7.202 +}; 7.203 +#define ROOT_ENTRY_NR (PAGE_SIZE_4K/sizeof(struct root_entry)) 7.204 +#define context_present(c) ((c).lo & 1) 7.205 +#define context_fault_disable(c) (((c).lo >> 1) & 1) 7.206 +#define context_translation_type(c) (((c).lo >> 2) & 3) 7.207 +#define context_address_root(c) ((c).lo & PAGE_MASK_4K) 7.208 +#define context_address_width(c) ((c).hi & 7) 7.209 +#define context_domain_id(c) (((c).hi >> 8) & ((1 << 16) - 1)) 7.210 + 7.211 +#define context_set_present(c) do {(c).lo |= 1;} while(0) 7.212 +#define context_clear_present(c) do {(c).lo &= ~1;} while(0) 7.213 +#define context_set_fault_enable(c) \ 7.214 + do {(c).lo &= (((u64)-1) << 2) | 1;} while(0) 7.215 + 7.216 +#define context_set_translation_type(c, val) do { \ 7.217 + (c).lo &= (((u64)-1) << 4) | 3; \ 7.218 + (c).lo |= (val & 3) << 2; \ 7.219 + } while(0) 7.220 +#define CONTEXT_TT_MULTI_LEVEL 0 7.221 +#define CONTEXT_TT_DEV_IOTLB 1 7.222 +#define CONTEXT_TT_PASS_THRU 2 7.223 + 7.224 +#define context_set_address_root(c, val) \ 7.225 + do {(c).lo &= 0xfff; (c).lo |= (val) & PAGE_MASK_4K ;} while(0) 7.226 +#define context_set_address_width(c, val) \ 7.227 + do {(c).hi &= 0xfffffff8; (c).hi |= (val) & 7;} while(0) 7.228 +#define context_set_domain_id(c, val) \ 7.229 + do {(c).hi &= 0xff; (c).hi |= ((val + 1) & ((1 << 16) - 1)) << 8;} while(0) 7.230 +#define context_clear_entry(c) do {(c).lo = 0; (c).hi = 0;} while(0) 7.231 + 7.232 +/* 7.233 + * 0: readable 7.234 + * 1: writable 7.235 + * 2-6: reserved 7.236 + * 7: super page 7.237 + * 8-11: available 7.238 + * 12-63: Host physcial address 7.239 + */ 7.240 +struct dma_pte { 7.241 + u64 val; 7.242 +}; 7.243 +#define dma_clear_pte(p) do {(p).val = 0;} while(0) 7.244 +#define dma_set_pte_readable(p) do {(p).val |= 1;} while(0) 7.245 +#define dma_set_pte_writable(p) do {(p).val |= 2;} while(0) 7.246 +#define dma_set_pte_superpage(p) do {(p).val |= 8;} while(0) 7.247 +#define dma_set_pte_prot(p, prot) do { (p).val = (((p).val >> 2) << 2) | ((prot) & 3);} while (0) 7.248 +#define dma_pte_addr(p) ((p).val & PAGE_MASK_4K) 7.249 +#define dma_set_pte_addr(p, addr) do {(p).val |= ((addr) >> PAGE_SHIFT_4K) << PAGE_SHIFT_4K;} while(0) 7.250 +#define DMA_PTE_READ (1) 7.251 +#define DMA_PTE_WRITE (2) 7.252 +#define dma_pte_present(p) (((p).val & 3) != 0) 7.253 + 7.254 +/* interrupt remap entry */ 7.255 +struct iremap_entry { 7.256 + struct { 7.257 + u64 present : 1, 7.258 + fpd : 1, 7.259 + dm : 1, 7.260 + rh : 1, 7.261 + tm : 1, 7.262 + dlm : 3, 7.263 + avail : 4, 7.264 + res_1 : 4, 7.265 + vector : 8, 7.266 + res_2 : 8, 7.267 + dst : 32; 7.268 + }lo; 7.269 + struct { 7.270 + u64 sid : 16, 7.271 + sq : 2, 7.272 + svt : 2, 7.273 + res_1 : 44; 7.274 + }hi; 7.275 +}; 7.276 +#define IREMAP_ENTRY_NR (PAGE_SIZE_4K/sizeof(struct iremap_entry)) 7.277 +#define iremap_present(v) ((v).lo & 1) 7.278 +#define iremap_fault_disable(v) (((v).lo >> 1) & 1) 7.279 + 7.280 +#define iremap_set_present(v) do {(v).lo |= 1;} while(0) 7.281 +#define iremap_clear_present(v) do {(v).lo &= ~1;} while(0) 7.282 + 7.283 +/* queue invalidation entry */ 7.284 +struct qinval_entry { 7.285 + union { 7.286 + struct { 7.287 + struct { 7.288 + u64 type : 4, 7.289 + granu : 2, 7.290 + res_1 : 10, 7.291 + did : 16, 7.292 + sid : 16, 7.293 + fm : 2, 7.294 + res_2 : 14; 7.295 + }lo; 7.296 + struct { 7.297 + u64 res; 7.298 + }hi; 7.299 + }cc_inv_dsc; 7.300 + struct { 7.301 + struct { 7.302 + u64 type : 4, 7.303 + granu : 2, 7.304 + dw : 1, 7.305 + dr : 1, 7.306 + res_1 : 8, 7.307 + did : 16, 7.308 + res_2 : 32; 7.309 + }lo; 7.310 + struct { 7.311 + u64 am : 6, 7.312 + ih : 1, 7.313 + res_1 : 5, 7.314 + addr : 52; 7.315 + }hi; 7.316 + }iotlb_inv_dsc; 7.317 + struct { 7.318 + struct { 7.319 + u64 type : 4, 7.320 + res_1 : 12, 7.321 + max_invs_pend: 5, 7.322 + res_2 : 11, 7.323 + sid : 16, 7.324 + res_3 : 16; 7.325 + }lo; 7.326 + struct { 7.327 + u64 size : 1, 7.328 + res_1 : 11, 7.329 + addr : 52; 7.330 + }hi; 7.331 + }dev_iotlb_inv_dsc; 7.332 + struct { 7.333 + struct { 7.334 + u64 type : 4, 7.335 + granu : 1, 7.336 + res_1 : 22, 7.337 + im : 5, 7.338 + iidx : 16, 7.339 + res_2 : 16; 7.340 + }lo; 7.341 + struct { 7.342 + u64 res; 7.343 + }hi; 7.344 + }iec_inv_dsc; 7.345 + struct { 7.346 + struct { 7.347 + u64 type : 4, 7.348 + iflag : 1, 7.349 + sw : 1, 7.350 + fn : 1, 7.351 + res_1 : 25, 7.352 + sdata : 32; 7.353 + }lo; 7.354 + struct { 7.355 + u64 res_1 : 2, 7.356 + saddr : 62; 7.357 + }hi; 7.358 + }inv_wait_dsc; 7.359 + }q; 7.360 +}; 7.361 + 7.362 +struct poll_info { 7.363 + u64 saddr; 7.364 + u32 udata; 7.365 +}; 7.366 + 7.367 +#define QINVAL_ENTRY_NR (PAGE_SIZE_4K/sizeof(struct qinval_entry)) 7.368 +#define qinval_present(v) ((v).lo & 1) 7.369 +#define qinval_fault_disable(v) (((v).lo >> 1) & 1) 7.370 + 7.371 +#define qinval_set_present(v) do {(v).lo |= 1;} while(0) 7.372 +#define qinval_clear_present(v) do {(v).lo &= ~1;} while(0) 7.373 + 7.374 +#define RESERVED_VAL 0 7.375 + 7.376 +#define TYPE_INVAL_CONTEXT 1 7.377 +#define TYPE_INVAL_IOTLB 2 7.378 +#define TYPE_INVAL_DEVICE_IOTLB 3 7.379 +#define TYPE_INVAL_IEC 4 7.380 +#define TYPE_INVAL_WAIT 5 7.381 + 7.382 +#define NOTIFY_TYPE_POLL 1 7.383 +#define NOTIFY_TYPE_INTR 1 7.384 +#define INTERRUTP_FLAG 1 7.385 +#define STATUS_WRITE 1 7.386 +#define FENCE_FLAG 1 7.387 + 7.388 +#define IEC_GLOBAL_INVL 0 7.389 +#define IEC_INDEX_INVL 1 7.390 + 7.391 +#define VTD_PAGE_TABLE_LEVEL_3 3 7.392 +#define VTD_PAGE_TABLE_LEVEL_4 4 7.393 + 7.394 +typedef paddr_t dma_addr_t; 7.395 + 7.396 +#define DEFAULT_DOMAIN_ADDRESS_WIDTH 48 7.397 +#define MAX_IOMMUS 32 7.398 +#define MAX_IOMMU_REGS 0xc0 7.399 + 7.400 +extern struct list_head acpi_drhd_units; 7.401 +extern struct list_head acpi_rmrr_units; 7.402 +extern struct list_head acpi_ioapic_units; 7.403 + 7.404 +#endif
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 8.2 +++ b/xen/include/asm-x86/iommu.h Wed Sep 12 15:42:39 2007 +0100 8.3 @@ -0,0 +1,79 @@ 8.4 +/* 8.5 + * Copyright (c) 2006, Intel Corporation. 8.6 + * 8.7 + * This program is free software; you can redistribute it and/or modify it 8.8 + * under the terms and conditions of the GNU General Public License, 8.9 + * version 2, as published by the Free Software Foundation. 8.10 + * 8.11 + * This program is distributed in the hope it will be useful, but WITHOUT 8.12 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 8.13 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 8.14 + * more details. 8.15 + * 8.16 + * You should have received a copy of the GNU General Public License along with 8.17 + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple 8.18 + * Place - Suite 330, Boston, MA 02111-1307 USA. 8.19 + * 8.20 + * Copyright (C) Allen Kay <allen.m.kay@intel.com> 8.21 + */ 8.22 + 8.23 +#ifndef _IOMMU_H_ 8.24 +#define _IOMMU_H_ 8.25 + 8.26 +#include <xen/init.h> 8.27 +#include <xen/bitmap.h> 8.28 +#include <xen/irq.h> 8.29 +#include <xen/spinlock.h> 8.30 +#include <xen/mm.h> 8.31 +#include <xen/xmalloc.h> 8.32 +#include <asm/hvm/vmx/intel-iommu.h> 8.33 +#include <public/hvm/ioreq.h> 8.34 + 8.35 +extern int vtd_enabled; 8.36 + 8.37 +#define domain_hvm_iommu(d) (&d->arch.hvm_domain.hvm_iommu) 8.38 +#define domain_vmx_iommu(d) (&d->arch.hvm_domain.hvm_iommu.vmx_iommu) 8.39 + 8.40 +/* 8.41 + * The PCI interface treats multi-function devices as independent 8.42 + * devices. The slot/function address of each device is encoded 8.43 + * in a single byte as follows: 8.44 + * 8.45 + * 15:8 = bus 8.46 + * 7:3 = slot 8.47 + * 2:0 = function 8.48 + */ 8.49 +#define PCI_DEVFN(slot,func) (((slot & 0x1f) << 3) | (func & 0x07)) 8.50 +#define PCI_SLOT(devfn) (((devfn) >> 3) & 0x1f) 8.51 +#define PCI_FUNC(devfn) ((devfn) & 0x07) 8.52 + 8.53 +struct pci_dev { 8.54 + struct list_head list; 8.55 + u8 bus; 8.56 + u8 devfn; 8.57 +}; 8.58 + 8.59 +struct iommu { 8.60 + struct list_head list; 8.61 + void __iomem *reg; /* Pointer to hardware regs, virtual addr */ 8.62 + u32 gcmd; /* Holds TE, EAFL. Don't need SRTP, SFL, WBF */ 8.63 + u64 cap; 8.64 + u64 ecap; 8.65 + spinlock_t lock; /* protect context, domain ids */ 8.66 + spinlock_t register_lock; /* protect iommu register handling */ 8.67 + struct root_entry *root_entry; /* virtual address */ 8.68 + unsigned int vector; 8.69 +}; 8.70 + 8.71 +int iommu_setup(void); 8.72 +int iommu_domain_init(struct domain *d); 8.73 +int assign_device(struct domain *d, u8 bus, u8 devfn); 8.74 +int release_devices(struct domain *d); 8.75 +int iommu_map_page(struct domain *d, dma_addr_t gfn, dma_addr_t mfn); 8.76 +int iommu_unmap_page(struct domain *d, dma_addr_t gfn); 8.77 +void iommu_flush(struct domain *d, dma_addr_t gfn, u64 *p2m_entry); 8.78 +void iommu_set_pgd(struct domain *d); 8.79 +void iommu_domain_teardown(struct domain *d); 8.80 +int hvm_do_IRQ_dpci(struct domain *d, unsigned int irq); 8.81 + 8.82 +#endif // _IOMMU_H_
9.1 --- a/xen/include/asm-x86/system.h Wed Sep 12 15:32:58 2007 +0100 9.2 +++ b/xen/include/asm-x86/system.h Wed Sep 12 15:42:39 2007 +0100 9.3 @@ -14,6 +14,9 @@ 9.4 #define wbinvd() \ 9.5 __asm__ __volatile__ ("wbinvd": : :"memory"); 9.6 9.7 +#define clflush(a) \ 9.8 + __asm__ __volatile__ ("clflush (%0)": :"r"(a)); 9.9 + 9.10 #define nop() __asm__ __volatile__ ("nop") 9.11 9.12 #define xchg(ptr,v) ((__typeof__(*(ptr)))__xchg((unsigned long)(v),(ptr),sizeof(*(ptr))))
10.1 --- a/xen/include/public/domctl.h Wed Sep 12 15:32:58 2007 +0100 10.2 +++ b/xen/include/public/domctl.h Wed Sep 12 15:42:39 2007 +0100 10.3 @@ -432,7 +432,69 @@ struct xen_domctl_sendtrigger { 10.4 typedef struct xen_domctl_sendtrigger xen_domctl_sendtrigger_t; 10.5 DEFINE_XEN_GUEST_HANDLE(xen_domctl_sendtrigger_t); 10.6 10.7 - 10.8 + 10.9 +/* Assign PCI device to HVM guest. Sets up IOMMU structures. */ 10.10 +#define XEN_DOMCTL_assign_device 37 10.11 +#define DPCI_ADD_MAPPING 1 10.12 +#define DPCI_REMOVE_MAPPING 0 10.13 +struct xen_domctl_assign_device { 10.14 + uint32_t machine_bdf; /* machine PCI ID of assigned device */ 10.15 +}; 10.16 +typedef struct xen_domctl_assign_device xen_domctl_assign_device_t; 10.17 +DEFINE_XEN_GUEST_HANDLE(xen_domctl_assign_device_t); 10.18 + 10.19 + 10.20 +/* Pass-through interrupts: bind real irq -> hvm devfn. */ 10.21 +#define XEN_DOMCTL_bind_pt_irq 38 10.22 +typedef enum pt_irq_type_e { 10.23 + PT_IRQ_TYPE_PCI, 10.24 + PT_IRQ_TYPE_ISA 10.25 +} pt_irq_type_t; 10.26 +struct xen_domctl_bind_pt_irq { 10.27 + uint32_t machine_irq; 10.28 + pt_irq_type_t irq_type; 10.29 + uint32_t hvm_domid; 10.30 + 10.31 + union { 10.32 + struct { 10.33 + uint8_t isa_irq; 10.34 + } isa; 10.35 + struct { 10.36 + uint8_t bus; 10.37 + uint8_t device; 10.38 + uint8_t intx; 10.39 + } pci; 10.40 + } u; 10.41 +}; 10.42 +typedef struct xen_domctl_bind_pt_irq xen_domctl_bind_pt_irq_t; 10.43 +DEFINE_XEN_GUEST_HANDLE(xen_domctl_bind_pt_irq_t); 10.44 + 10.45 + 10.46 +/* Bind machine I/O address range -> HVM address range. */ 10.47 +#define XEN_DOMCTL_memory_mapping 39 10.48 +struct xen_domctl_memory_mapping { 10.49 + uint64_t first_gfn; /* first page (hvm guest phys page) in range */ 10.50 + uint64_t first_mfn; /* first page (machine page) in range */ 10.51 + uint64_t nr_mfns; /* number of pages in range (>0) */ 10.52 + uint32_t add_mapping; /* add or remove mapping */ 10.53 + uint32_t padding; /* padding for 64-bit aligned structure */ 10.54 +}; 10.55 +typedef struct xen_domctl_memory_mapping xen_domctl_memory_mapping_t; 10.56 +DEFINE_XEN_GUEST_HANDLE(xen_domctl_memory_mapping_t); 10.57 + 10.58 + 10.59 +/* Bind machine I/O port range -> HVM I/O port range. */ 10.60 +#define XEN_DOMCTL_ioport_mapping 40 10.61 +struct xen_domctl_ioport_mapping { 10.62 + uint32_t first_gport; /* first guest IO port*/ 10.63 + uint32_t first_mport; /* first machine IO port */ 10.64 + uint32_t nr_ports; /* size of port range */ 10.65 + uint32_t add_mapping; /* add or remove mapping */ 10.66 +}; 10.67 +typedef struct xen_domctl_ioport_mapping xen_domctl_ioport_mapping_t; 10.68 +DEFINE_XEN_GUEST_HANDLE(xen_domctl_ioport_mapping_t); 10.69 + 10.70 + 10.71 struct xen_domctl { 10.72 uint32_t cmd; 10.73 uint32_t interface_version; /* XEN_DOMCTL_INTERFACE_VERSION */ 10.74 @@ -462,6 +524,10 @@ struct xen_domctl { 10.75 struct xen_domctl_hvmcontext hvmcontext; 10.76 struct xen_domctl_address_size address_size; 10.77 struct xen_domctl_sendtrigger sendtrigger; 10.78 + struct xen_domctl_assign_device assign_device; 10.79 + struct xen_domctl_bind_pt_irq bind_pt_irq; 10.80 + struct xen_domctl_memory_mapping memory_mapping; 10.81 + struct xen_domctl_ioport_mapping ioport_mapping; 10.82 uint8_t pad[128]; 10.83 } u; 10.84 };
11.1 --- a/xen/include/xen/acpi.h Wed Sep 12 15:32:58 2007 +0100 11.2 +++ b/xen/include/xen/acpi.h Wed Sep 12 15:42:39 2007 +0100 11.3 @@ -367,9 +367,79 @@ enum acpi_table_id { 11.4 ACPI_SPMI, 11.5 ACPI_HPET, 11.6 ACPI_MCFG, 11.7 + ACPI_DMAR, 11.8 ACPI_TABLE_COUNT 11.9 }; 11.10 11.11 +/* DMA Remapping Reporting Table (DMAR) */ 11.12 + 11.13 +#define DMAR_FLAGS_INTR_REMAP 0x1 /* intr remap supported */ 11.14 +struct acpi_table_dmar { 11.15 + struct acpi_table_header header; 11.16 + u8 haw; /* Host address Width */ 11.17 + u8 flags; 11.18 + u8 reserved[10]; 11.19 +} __attribute__ ((packed)); 11.20 + 11.21 +struct acpi_dmar_entry_header { 11.22 + u16 type; 11.23 + u16 length; 11.24 +} __attribute__((packed)); 11.25 + 11.26 +enum acpi_dmar_entry_type { 11.27 + ACPI_DMAR_DRHD = 0, 11.28 + ACPI_DMAR_RMRR, 11.29 + ACPI_DMAR_ATSR, 11.30 + ACPI_DMAR_ENTRY_COUNT 11.31 +}; 11.32 + 11.33 +#define DRHD_FLAGS_INCLUDE_ALL 0x1 /* drhd remaps remaining devices */ 11.34 +struct acpi_table_drhd { 11.35 + struct acpi_dmar_entry_header header; 11.36 + u8 flags; 11.37 + u8 reserved; 11.38 + u16 segment; 11.39 + u64 address; /* register base address for this drhd */ 11.40 +} __attribute__ ((packed)); 11.41 + 11.42 +struct acpi_table_rmrr { 11.43 + struct acpi_dmar_entry_header header; 11.44 + u16 reserved; 11.45 + u16 segment; 11.46 + u64 base_address; 11.47 + u64 end_address; 11.48 +} __attribute__ ((packed)); 11.49 + 11.50 +struct acpi_table_atsr { 11.51 + struct acpi_dmar_entry_header header; 11.52 + u8 flags; 11.53 + u8 reserved; 11.54 + u16 segment; 11.55 +} __attribute__ ((packed)); 11.56 + 11.57 +enum acpi_dev_scope_type { 11.58 + ACPI_DEV_ENDPOINT=0x01, /* PCI Endpoing device */ 11.59 + ACPI_DEV_P2PBRIDGE, /* PCI-PCI Bridge */ 11.60 + ACPI_DEV_IOAPIC, /* IOAPIC device*/ 11.61 + ACPI_DEV_MSI_HPET, /* MSI capable HPET*/ 11.62 + ACPI_DEV_ENTRY_COUNT 11.63 +}; 11.64 + 11.65 +struct acpi_dev_scope { 11.66 + u8 dev_type; 11.67 + u8 length; 11.68 + u8 reserved[2]; 11.69 + u8 enum_id; 11.70 + u8 start_bus; 11.71 +} __attribute__((packed)); 11.72 + 11.73 +struct acpi_pci_path { 11.74 + u8 dev; 11.75 + u8 fn; 11.76 +} __attribute__((packed)); 11.77 + 11.78 +typedef int (*acpi_dmar_entry_handler) (struct acpi_dmar_entry_header *header, const unsigned long end); 11.79 + 11.80 typedef int (*acpi_table_handler) (unsigned long phys_addr, unsigned long size); 11.81 11.82 extern acpi_table_handler acpi_table_ops[ACPI_TABLE_COUNT];
12.1 --- a/xen/include/xen/irq.h Wed Sep 12 15:32:58 2007 +0100 12.2 +++ b/xen/include/xen/irq.h Wed Sep 12 15:42:39 2007 +0100 12.3 @@ -64,6 +64,9 @@ extern irq_desc_t irq_desc[NR_IRQS]; 12.4 12.5 extern int setup_irq(unsigned int, struct irqaction *); 12.6 extern void free_irq(unsigned int); 12.7 +extern int request_irq(unsigned int irq, 12.8 + void (*handler)(int, void *, struct cpu_user_regs *), 12.9 + unsigned long irqflags, const char * devname, void *dev_id); 12.10 12.11 extern hw_irq_controller no_irq_type; 12.12 extern void no_action(int cpl, void *dev_id, struct cpu_user_regs *regs);