[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] Generic and VT-d specific Xen header changes for PCI passthru.
# HG changeset patch # User kfraser@xxxxxxxxxxxxxxxxxxxxx # Date 1189608159 -3600 # Node ID ca495837a7223259ecbdc9f8b1ab69d08ed11002 # Parent 9dd580b8b056860fe7634bb964e2bcf201e87bd6 Generic and VT-d specific Xen header changes for PCI passthru. Signed-off-by: Allen Kay <allen.m.kay@xxxxxxxxx> Signed-off-by: Guy Zana <guy@xxxxxxxxxxxx> --- xen/include/asm-x86/acpi.h | 2 xen/include/asm-x86/fixmap.h | 3 xen/include/asm-x86/hvm/domain.h | 5 xen/include/asm-x86/hvm/io.h | 1 xen/include/asm-x86/hvm/iommu.h | 40 ++ xen/include/asm-x86/hvm/irq.h | 16 + xen/include/asm-x86/hvm/vmx/intel-iommu.h | 401 ++++++++++++++++++++++++++++++ xen/include/asm-x86/iommu.h | 79 +++++ xen/include/asm-x86/system.h | 3 xen/include/public/domctl.h | 68 +++++ xen/include/xen/acpi.h | 70 +++++ xen/include/xen/irq.h | 3 12 files changed, 690 insertions(+), 1 deletion(-) diff -r 9dd580b8b056 -r ca495837a722 xen/include/asm-x86/acpi.h --- a/xen/include/asm-x86/acpi.h Wed Sep 12 15:32:58 2007 +0100 +++ b/xen/include/asm-x86/acpi.h Wed Sep 12 15:42:39 2007 +0100 @@ -196,4 +196,6 @@ extern u8 x86_acpiid_to_apicid[]; extern u8 x86_acpiid_to_apicid[]; #define MAX_LOCAL_APIC 256 +extern int acpi_dmar_init(void); + #endif /*_ASM_ACPI_H*/ diff -r 9dd580b8b056 -r ca495837a722 xen/include/asm-x86/fixmap.h --- a/xen/include/asm-x86/fixmap.h Wed Sep 12 15:32:58 2007 +0100 +++ b/xen/include/asm-x86/fixmap.h Wed Sep 12 15:42:39 2007 +0100 @@ -17,6 +17,7 @@ #include <asm/acpi.h> #include <asm/page.h> #include <xen/kexec.h> +#include <asm/iommu.h> /* * Here we define all the compile-time 'special' virtual @@ -40,6 +41,8 @@ enum fixed_addresses { FIX_KEXEC_BASE_0, FIX_KEXEC_BASE_END = FIX_KEXEC_BASE_0 \ + ((KEXEC_XEN_NO_PAGES >> 1) * KEXEC_IMAGE_NR) - 1, + FIX_IOMMU_REGS_BASE_0, + FIX_IOMMU_REGS_END = FIX_IOMMU_REGS_BASE_0 + MAX_IOMMUS-1, __end_of_fixed_addresses }; diff -r 9dd580b8b056 -r ca495837a722 xen/include/asm-x86/hvm/domain.h --- a/xen/include/asm-x86/hvm/domain.h Wed Sep 12 15:32:58 2007 +0100 +++ b/xen/include/asm-x86/hvm/domain.h Wed Sep 12 15:42:39 2007 +0100 @@ -21,10 +21,12 @@ #ifndef __ASM_X86_HVM_DOMAIN_H__ #define __ASM_X86_HVM_DOMAIN_H__ +#include <asm/iommu.h> #include <asm/hvm/irq.h> #include <asm/hvm/vpt.h> #include <asm/hvm/vlapic.h> #include <asm/hvm/io.h> +#include <asm/hvm/iommu.h> #include <public/hvm/params.h> #include <public/hvm/save.h> @@ -57,6 +59,9 @@ struct hvm_domain { uint64_t params[HVM_NR_PARAMS]; unsigned long vmx_apic_access_mfn; + + /* Pass-through */ + struct hvm_iommu hvm_iommu; }; #endif /* __ASM_X86_HVM_DOMAIN_H__ */ diff -r 9dd580b8b056 -r ca495837a722 xen/include/asm-x86/hvm/io.h --- a/xen/include/asm-x86/hvm/io.h Wed Sep 12 15:32:58 2007 +0100 +++ b/xen/include/asm-x86/hvm/io.h Wed Sep 12 15:42:39 2007 +0100 @@ -151,6 +151,7 @@ extern void handle_mmio(unsigned long gp extern void handle_mmio(unsigned long gpa); extern void hvm_interrupt_post(struct vcpu *v, int vector, int type); extern void hvm_io_assist(void); +extern void hvm_dpci_eoi(unsigned int guest_irq, union vioapic_redir_entry *ent); #endif /* __ASM_X86_HVM_IO_H__ */ diff -r 9dd580b8b056 -r ca495837a722 xen/include/asm-x86/hvm/iommu.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/xen/include/asm-x86/hvm/iommu.h Wed Sep 12 15:42:39 2007 +0100 @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2006, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place - Suite 330, Boston, MA 02111-1307 USA. + * + * Copyright (C) Allen Kay <allen.m.kay@xxxxxxxxx> + */ + +#ifndef __ASM_X86_HVM_IOMMU_H__ +#define __ASM_X86_HVM_IOMMU_H__ + +#include <asm/iommu.h> +#include <asm/hvm/irq.h> +#include <asm/hvm/vpt.h> +#include <asm/hvm/vlapic.h> +#include <asm/hvm/io.h> +#include <public/hvm/params.h> +#include <public/hvm/save.h> + +struct hvm_iommu { + spinlock_t iommu_list_lock; /* protect iommu specific lists */ + struct list_head pdev_list; /* direct accessed pci devices */ + struct dma_pte *pgd; /* io page directory root */ + spinlock_t mapping_lock; /* io page table lock */ + int agaw; /* adjusted guest address width, 0 is level 2 30-bit */ + struct list_head g2m_ioport_list; /* guest to machine ioport mapping */ +}; + +#endif // __ASM_X86_HVM_IOMMU_H__ diff -r 9dd580b8b056 -r ca495837a722 xen/include/asm-x86/hvm/irq.h --- a/xen/include/asm-x86/hvm/irq.h Wed Sep 12 15:32:58 2007 +0100 +++ b/xen/include/asm-x86/hvm/irq.h Wed Sep 12 15:42:39 2007 +0100 @@ -28,6 +28,16 @@ #include <asm/hvm/vpic.h> #include <asm/hvm/vioapic.h> #include <public/hvm/save.h> + +struct hvm_irq_mapping { + uint8_t valid; + uint8_t device; + uint8_t intx; + union { + uint8_t guest_gsi; + uint8_t machine_gsi; + }; +}; struct hvm_irq { /* @@ -88,6 +98,12 @@ struct hvm_irq { /* Last VCPU that was delivered a LowestPrio interrupt. */ u8 round_robin_prev_vcpu; + + /* machine irq to guest device/intx mapping */ + struct hvm_irq_mapping mirq[NR_IRQS]; + /* guest irq to guest device/intx mapping */ + struct hvm_irq_mapping girq[NR_IRQS]; + DECLARE_BITMAP(dirq_mask, NR_IRQS); }; #define hvm_pci_intx_gsi(dev, intx) \ diff -r 9dd580b8b056 -r ca495837a722 xen/include/asm-x86/hvm/vmx/intel-iommu.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/xen/include/asm-x86/hvm/vmx/intel-iommu.h Wed Sep 12 15:42:39 2007 +0100 @@ -0,0 +1,401 @@ +/* + * Copyright (c) 2006, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place - Suite 330, Boston, MA 02111-1307 USA. + * + * Copyright (C) Ashok Raj <ashok.raj@xxxxxxxxx> + */ + +#ifndef _INTEL_IOMMU_H_ +#define _INTEL_IOMMU_H_ + +#include <xen/types.h> + +/* + * Intel IOMMU register specification per version 1.0 public spec. + */ + +#define DMAR_VER_REG 0x0 /* Arch version supported by this IOMMU */ +#define DMAR_CAP_REG 0x8 /* Hardware supported capabilities */ +#define DMAR_ECAP_REG 0x10 /* Extended capabilities supported */ +#define DMAR_GCMD_REG 0x18 /* Global command register */ +#define DMAR_GSTS_REG 0x1c /* Global status register */ +#define DMAR_RTADDR_REG 0x20 /* Root entry table */ +#define DMAR_CCMD_REG 0x28 /* Context command reg */ +#define DMAR_FSTS_REG 0x34 /* Fault Status register */ +#define DMAR_FECTL_REG 0x38 /* Fault control register */ +#define DMAR_FEDATA_REG 0x3c /* Fault event interrupt data register */ +#define DMAR_FEADDR_REG 0x40 /* Fault event interrupt addr register */ +#define DMAR_FEUADDR_REG 0x44 /* Upper address register */ +#define DMAR_AFLOG_REG 0x58 /* Advanced Fault control */ +#define DMAR_PMEN_REG 0x64 /* Enable Protected Memory Region */ +#define DMAR_PLMBASE_REG 0x68 /* PMRR Low addr */ +#define DMAR_PLMLIMIT_REG 0x6c /* PMRR low limit */ +#define DMAR_PHMBASE_REG 0x70 /* pmrr high base addr */ +#define DMAR_PHMLIMIT_REG 0x78 /* pmrr high limit */ +#define DMAR_IQH_REG 0x80 /* invalidation queue head */ +#define DMAR_IQT_REG 0x88 /* invalidation queue tail */ +#define DMAR_IQA_REG 0x90 /* invalidation queue addr */ +#define DMAR_IRTA_REG 0xB8 /* intr remap */ + +#define OFFSET_STRIDE (9) +#define dmar_readl(dmar, reg) readl(dmar + reg) +#define dmar_writel(dmar, reg, val) writel(val, dmar + reg) +#define dmar_readq(dmar, reg) ({ \ + u32 lo, hi; \ + lo = dmar_readl(dmar, reg); \ + hi = dmar_readl(dmar, reg + 4); \ + (((u64) hi) << 32) + lo; }) +#define dmar_writeq(dmar, reg, val) do {\ + dmar_writel(dmar, reg, (u32)val); \ + dmar_writel(dmar, reg + 4, (u32)((u64) val >> 32)); \ + } while (0) + +#define VER_MAJOR(v) (((v) & 0xf0) >> 4) +#define VER_MINOR(v) ((v) & 0x0f) + +/* + * Decoding Capability Register + */ +#define cap_read_drain(c) (((c) >> 55) & 1) +#define cap_write_drain(c) (((c) >> 54) & 1) +#define cap_max_amask_val(c) (((c) >> 48) & 0x3f) +#define cap_num_fault_regs(c) ((((c) >> 40) & 0xff) + 1) +#define cap_pgsel_inv(c) (((c) >> 39) & 1) + +#define cap_super_page_val(c) (((c) >> 34) & 0xf) +#define cap_super_offset(c) (((find_first_bit(&cap_super_page_val(c), 4)) \ + * OFFSET_STRIDE) + 21) + +#define cap_fault_reg_offset(c) ((((c) >> 24) & 0x3ff) * 16) + +#define cap_isoch(c) (((c) >> 23) & 1) +#define cap_qos(c) (((c) >> 22) & 1) +#define cap_mgaw(c) ((((c) >> 16) & 0x3f) + 1) +#define cap_sagaw(c) (((c) >> 8) & 0x1f) +#define cap_caching_mode(c) (((c) >> 7) & 1) +#define cap_phmr(c) (((c) >> 6) & 1) +#define cap_plmr(c) (((c) >> 5) & 1) +#define cap_rwbf(c) (((c) >> 4) & 1) +#define cap_afl(c) (((c) >> 3) & 1) +#define cap_ndoms(c) (2 ^ (4 + 2 * ((c) & 0x7))) +/* + * Extended Capability Register + */ + +#define ecap_niotlb_iunits(e) ((((e) >> 24) & 0xff) + 1) +#define ecap_iotlb_offset(e) ((((e) >> 8) & 0x3ff) * 16) +#define ecap_coherent(e) ((e >> 0) & 0x1) +#define ecap_queued_inval(e) ((e >> 1) & 0x1) +#define ecap_dev_iotlb(e) ((e >> 2) & 0x1) +#define ecap_intr_remap(e) ((e >> 3) & 0x1) +#define ecap_ext_intr(e) ((e >> 4) & 0x1) +#define ecap_cache_hints(e) ((e >> 5) & 0x1) +#define ecap_pass_thru(e) ((e >> 6) & 0x1) + +#define PAGE_SHIFT_4K (12) +#define PAGE_SIZE_4K (1UL << PAGE_SHIFT_4K) +#define PAGE_MASK_4K (((u64)-1) << PAGE_SHIFT_4K) +#define PAGE_ALIGN_4K(addr) (((addr) + PAGE_SIZE_4K - 1) & PAGE_MASK_4K) + +/* IOTLB_REG */ +#define DMA_TLB_FLUSH_GRANU_OFFSET 60 +#define DMA_TLB_GLOBAL_FLUSH (((u64)1) << 60) +#define DMA_TLB_DSI_FLUSH (((u64)2) << 60) +#define DMA_TLB_PSI_FLUSH (((u64)3) << 60) +#define DMA_TLB_IIRG(x) (((x) >> 60) & 7) +#define DMA_TLB_IAIG(val) (((val) >> 57) & 7) +#define DMA_TLB_DID(x) (((u64)(x & 0xffff)) << 32) + +#define DMA_TLB_READ_DRAIN (((u64)1) << 49) +#define DMA_TLB_WRITE_DRAIN (((u64)1) << 48) +#define DMA_TLB_IVT (((u64)1) << 63) + +#define DMA_TLB_IVA_ADDR(x) ((((u64)x) >> 12) << 12) +#define DMA_TLB_IVA_HINT(x) ((((u64)x) & 1) << 6) + +/* GCMD_REG */ +#define DMA_GCMD_TE (((u64)1) << 31) +#define DMA_GCMD_SRTP (((u64)1) << 30) +#define DMA_GCMD_SFL (((u64)1) << 29) +#define DMA_GCMD_EAFL (((u64)1) << 28) +#define DMA_GCMD_WBF (((u64)1) << 27) +#define DMA_GCMD_QIE (((u64)1) << 26) +#define DMA_GCMD_IRE (((u64)1) << 25) +#define DMA_GCMD_SIRTP (((u64)1) << 24) + +/* GSTS_REG */ +#define DMA_GSTS_TES (((u64)1) << 31) +#define DMA_GSTS_RTPS (((u64)1) << 30) +#define DMA_GSTS_FLS (((u64)1) << 29) +#define DMA_GSTS_AFLS (((u64)1) << 28) +#define DMA_GSTS_WBFS (((u64)1) << 27) +#define DMA_GSTS_IRTPS (((u64)1) << 24) +#define DMA_GSTS_QIES (((u64)1) <<26) +#define DMA_GSTS_IRES (((u64)1) <<25) + +/* CCMD_REG */ +#define DMA_CCMD_INVL_GRANU_OFFSET 61 +#define DMA_CCMD_ICC (((u64)1) << 63) +#define DMA_CCMD_GLOBAL_INVL (((u64)1) << 61) +#define DMA_CCMD_DOMAIN_INVL (((u64)2) << 61) +#define DMA_CCMD_DEVICE_INVL (((u64)3) << 61) +#define DMA_CCMD_FM(m) (((u64)((m) & 0x3)) << 32) +#define DMA_CCMD_CIRG(x) ((((u64)3) << 61) & x) +#define DMA_CCMD_MASK_NOBIT 0 +#define DMA_CCMD_MASK_1BIT 1 +#define DMA_CCMD_MASK_2BIT 2 +#define DMA_CCMD_MASK_3BIT 3 +#define DMA_CCMD_SID(s) (((u64)((s) & 0xffff)) << 16) +#define DMA_CCMD_DID(d) ((u64)((d) & 0xffff)) + +#define DMA_CCMD_CAIG_MASK(x) (((u64)x) & ((u64) 0x3 << 59)) + +/* FECTL_REG */ +#define DMA_FECTL_IM (((u64)1) << 31) + +/* FSTS_REG */ +#define DMA_FSTS_PPF ((u64)2) +#define DMA_FSTS_PFO ((u64)1) +#define dma_fsts_fault_record_index(s) (((s) >> 8) & 0xff) + +/* FRCD_REG, 32 bits access */ +#define DMA_FRCD_F (((u64)1) << 31) +#define dma_frcd_type(d) ((d >> 30) & 1) +#define dma_frcd_fault_reason(c) (c & 0xff) +#define dma_frcd_source_id(c) (c & 0xffff) +#define dma_frcd_page_addr(d) (d & (((u64)-1) << 12)) /* low 64 bit */ + +/* + * 0: Present + * 1-11: Reserved + * 12-63: Context Ptr (12 - (haw-1)) + * 64-127: Reserved + */ +struct root_entry { + u64 val; + u64 rsvd1; +}; +#define root_present(root) ((root).val & 1) +#define set_root_present(root) do {(root).val |= 1;} while(0) +#define get_context_addr(root) ((root).val & PAGE_MASK_4K) +#define set_root_value(root, value) \ + do {(root).val |= ((value) & PAGE_MASK_4K);} while(0) + +struct context_entry { + u64 lo; + u64 hi; +}; +#define ROOT_ENTRY_NR (PAGE_SIZE_4K/sizeof(struct root_entry)) +#define context_present(c) ((c).lo & 1) +#define context_fault_disable(c) (((c).lo >> 1) & 1) +#define context_translation_type(c) (((c).lo >> 2) & 3) +#define context_address_root(c) ((c).lo & PAGE_MASK_4K) +#define context_address_width(c) ((c).hi & 7) +#define context_domain_id(c) (((c).hi >> 8) & ((1 << 16) - 1)) + +#define context_set_present(c) do {(c).lo |= 1;} while(0) +#define context_clear_present(c) do {(c).lo &= ~1;} while(0) +#define context_set_fault_enable(c) \ + do {(c).lo &= (((u64)-1) << 2) | 1;} while(0) + +#define context_set_translation_type(c, val) do { \ + (c).lo &= (((u64)-1) << 4) | 3; \ + (c).lo |= (val & 3) << 2; \ + } while(0) +#define CONTEXT_TT_MULTI_LEVEL 0 +#define CONTEXT_TT_DEV_IOTLB 1 +#define CONTEXT_TT_PASS_THRU 2 + +#define context_set_address_root(c, val) \ + do {(c).lo &= 0xfff; (c).lo |= (val) & PAGE_MASK_4K ;} while(0) +#define context_set_address_width(c, val) \ + do {(c).hi &= 0xfffffff8; (c).hi |= (val) & 7;} while(0) +#define context_set_domain_id(c, val) \ + do {(c).hi &= 0xff; (c).hi |= ((val + 1) & ((1 << 16) - 1)) << 8;} while(0) +#define context_clear_entry(c) do {(c).lo = 0; (c).hi = 0;} while(0) + +/* + * 0: readable + * 1: writable + * 2-6: reserved + * 7: super page + * 8-11: available + * 12-63: Host physcial address + */ +struct dma_pte { + u64 val; +}; +#define dma_clear_pte(p) do {(p).val = 0;} while(0) +#define dma_set_pte_readable(p) do {(p).val |= 1;} while(0) +#define dma_set_pte_writable(p) do {(p).val |= 2;} while(0) +#define dma_set_pte_superpage(p) do {(p).val |= 8;} while(0) +#define dma_set_pte_prot(p, prot) do { (p).val = (((p).val >> 2) << 2) | ((prot) & 3);} while (0) +#define dma_pte_addr(p) ((p).val & PAGE_MASK_4K) +#define dma_set_pte_addr(p, addr) do {(p).val |= ((addr) >> PAGE_SHIFT_4K) << PAGE_SHIFT_4K;} while(0) +#define DMA_PTE_READ (1) +#define DMA_PTE_WRITE (2) +#define dma_pte_present(p) (((p).val & 3) != 0) + +/* interrupt remap entry */ +struct iremap_entry { + struct { + u64 present : 1, + fpd : 1, + dm : 1, + rh : 1, + tm : 1, + dlm : 3, + avail : 4, + res_1 : 4, + vector : 8, + res_2 : 8, + dst : 32; + }lo; + struct { + u64 sid : 16, + sq : 2, + svt : 2, + res_1 : 44; + }hi; +}; +#define IREMAP_ENTRY_NR (PAGE_SIZE_4K/sizeof(struct iremap_entry)) +#define iremap_present(v) ((v).lo & 1) +#define iremap_fault_disable(v) (((v).lo >> 1) & 1) + +#define iremap_set_present(v) do {(v).lo |= 1;} while(0) +#define iremap_clear_present(v) do {(v).lo &= ~1;} while(0) + +/* queue invalidation entry */ +struct qinval_entry { + union { + struct { + struct { + u64 type : 4, + granu : 2, + res_1 : 10, + did : 16, + sid : 16, + fm : 2, + res_2 : 14; + }lo; + struct { + u64 res; + }hi; + }cc_inv_dsc; + struct { + struct { + u64 type : 4, + granu : 2, + dw : 1, + dr : 1, + res_1 : 8, + did : 16, + res_2 : 32; + }lo; + struct { + u64 am : 6, + ih : 1, + res_1 : 5, + addr : 52; + }hi; + }iotlb_inv_dsc; + struct { + struct { + u64 type : 4, + res_1 : 12, + max_invs_pend: 5, + res_2 : 11, + sid : 16, + res_3 : 16; + }lo; + struct { + u64 size : 1, + res_1 : 11, + addr : 52; + }hi; + }dev_iotlb_inv_dsc; + struct { + struct { + u64 type : 4, + granu : 1, + res_1 : 22, + im : 5, + iidx : 16, + res_2 : 16; + }lo; + struct { + u64 res; + }hi; + }iec_inv_dsc; + struct { + struct { + u64 type : 4, + iflag : 1, + sw : 1, + fn : 1, + res_1 : 25, + sdata : 32; + }lo; + struct { + u64 res_1 : 2, + saddr : 62; + }hi; + }inv_wait_dsc; + }q; +}; + +struct poll_info { + u64 saddr; + u32 udata; +}; + +#define QINVAL_ENTRY_NR (PAGE_SIZE_4K/sizeof(struct qinval_entry)) +#define qinval_present(v) ((v).lo & 1) +#define qinval_fault_disable(v) (((v).lo >> 1) & 1) + +#define qinval_set_present(v) do {(v).lo |= 1;} while(0) +#define qinval_clear_present(v) do {(v).lo &= ~1;} while(0) + +#define RESERVED_VAL 0 + +#define TYPE_INVAL_CONTEXT 1 +#define TYPE_INVAL_IOTLB 2 +#define TYPE_INVAL_DEVICE_IOTLB 3 +#define TYPE_INVAL_IEC 4 +#define TYPE_INVAL_WAIT 5 + +#define NOTIFY_TYPE_POLL 1 +#define NOTIFY_TYPE_INTR 1 +#define INTERRUTP_FLAG 1 +#define STATUS_WRITE 1 +#define FENCE_FLAG 1 + +#define IEC_GLOBAL_INVL 0 +#define IEC_INDEX_INVL 1 + +#define VTD_PAGE_TABLE_LEVEL_3 3 +#define VTD_PAGE_TABLE_LEVEL_4 4 + +typedef paddr_t dma_addr_t; + +#define DEFAULT_DOMAIN_ADDRESS_WIDTH 48 +#define MAX_IOMMUS 32 +#define MAX_IOMMU_REGS 0xc0 + +extern struct list_head acpi_drhd_units; +extern struct list_head acpi_rmrr_units; +extern struct list_head acpi_ioapic_units; + +#endif diff -r 9dd580b8b056 -r ca495837a722 xen/include/asm-x86/iommu.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/xen/include/asm-x86/iommu.h Wed Sep 12 15:42:39 2007 +0100 @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2006, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place - Suite 330, Boston, MA 02111-1307 USA. + * + * Copyright (C) Allen Kay <allen.m.kay@xxxxxxxxx> + */ + +#ifndef _IOMMU_H_ +#define _IOMMU_H_ + +#include <xen/init.h> +#include <xen/bitmap.h> +#include <xen/irq.h> +#include <xen/spinlock.h> +#include <xen/mm.h> +#include <xen/xmalloc.h> +#include <asm/hvm/vmx/intel-iommu.h> +#include <public/hvm/ioreq.h> + +extern int vtd_enabled; + +#define domain_hvm_iommu(d) (&d->arch.hvm_domain.hvm_iommu) +#define domain_vmx_iommu(d) (&d->arch.hvm_domain.hvm_iommu.vmx_iommu) + +/* + * The PCI interface treats multi-function devices as independent + * devices. The slot/function address of each device is encoded + * in a single byte as follows: + * + * 15:8 = bus + * 7:3 = slot + * 2:0 = function + */ +#define PCI_DEVFN(slot,func) (((slot & 0x1f) << 3) | (func & 0x07)) +#define PCI_SLOT(devfn) (((devfn) >> 3) & 0x1f) +#define PCI_FUNC(devfn) ((devfn) & 0x07) + +struct pci_dev { + struct list_head list; + u8 bus; + u8 devfn; +}; + +struct iommu { + struct list_head list; + void __iomem *reg; /* Pointer to hardware regs, virtual addr */ + u32 gcmd; /* Holds TE, EAFL. Don't need SRTP, SFL, WBF */ + u64 cap; + u64 ecap; + spinlock_t lock; /* protect context, domain ids */ + spinlock_t register_lock; /* protect iommu register handling */ + struct root_entry *root_entry; /* virtual address */ + unsigned int vector; +}; + +int iommu_setup(void); +int iommu_domain_init(struct domain *d); +int assign_device(struct domain *d, u8 bus, u8 devfn); +int release_devices(struct domain *d); +int iommu_map_page(struct domain *d, dma_addr_t gfn, dma_addr_t mfn); +int iommu_unmap_page(struct domain *d, dma_addr_t gfn); +void iommu_flush(struct domain *d, dma_addr_t gfn, u64 *p2m_entry); +void iommu_set_pgd(struct domain *d); +void iommu_domain_teardown(struct domain *d); +int hvm_do_IRQ_dpci(struct domain *d, unsigned int irq); + +#endif // _IOMMU_H_ diff -r 9dd580b8b056 -r ca495837a722 xen/include/asm-x86/system.h --- a/xen/include/asm-x86/system.h Wed Sep 12 15:32:58 2007 +0100 +++ b/xen/include/asm-x86/system.h Wed Sep 12 15:42:39 2007 +0100 @@ -13,6 +13,9 @@ #define wbinvd() \ __asm__ __volatile__ ("wbinvd": : :"memory"); + +#define clflush(a) \ + __asm__ __volatile__ ("clflush (%0)": :"r"(a)); #define nop() __asm__ __volatile__ ("nop") diff -r 9dd580b8b056 -r ca495837a722 xen/include/public/domctl.h --- a/xen/include/public/domctl.h Wed Sep 12 15:32:58 2007 +0100 +++ b/xen/include/public/domctl.h Wed Sep 12 15:42:39 2007 +0100 @@ -432,7 +432,69 @@ typedef struct xen_domctl_sendtrigger xe typedef struct xen_domctl_sendtrigger xen_domctl_sendtrigger_t; DEFINE_XEN_GUEST_HANDLE(xen_domctl_sendtrigger_t); - + +/* Assign PCI device to HVM guest. Sets up IOMMU structures. */ +#define XEN_DOMCTL_assign_device 37 +#define DPCI_ADD_MAPPING 1 +#define DPCI_REMOVE_MAPPING 0 +struct xen_domctl_assign_device { + uint32_t machine_bdf; /* machine PCI ID of assigned device */ +}; +typedef struct xen_domctl_assign_device xen_domctl_assign_device_t; +DEFINE_XEN_GUEST_HANDLE(xen_domctl_assign_device_t); + + +/* Pass-through interrupts: bind real irq -> hvm devfn. */ +#define XEN_DOMCTL_bind_pt_irq 38 +typedef enum pt_irq_type_e { + PT_IRQ_TYPE_PCI, + PT_IRQ_TYPE_ISA +} pt_irq_type_t; +struct xen_domctl_bind_pt_irq { + uint32_t machine_irq; + pt_irq_type_t irq_type; + uint32_t hvm_domid; + + union { + struct { + uint8_t isa_irq; + } isa; + struct { + uint8_t bus; + uint8_t device; + uint8_t intx; + } pci; + } u; +}; +typedef struct xen_domctl_bind_pt_irq xen_domctl_bind_pt_irq_t; +DEFINE_XEN_GUEST_HANDLE(xen_domctl_bind_pt_irq_t); + + +/* Bind machine I/O address range -> HVM address range. */ +#define XEN_DOMCTL_memory_mapping 39 +struct xen_domctl_memory_mapping { + uint64_t first_gfn; /* first page (hvm guest phys page) in range */ + uint64_t first_mfn; /* first page (machine page) in range */ + uint64_t nr_mfns; /* number of pages in range (>0) */ + uint32_t add_mapping; /* add or remove mapping */ + uint32_t padding; /* padding for 64-bit aligned structure */ +}; +typedef struct xen_domctl_memory_mapping xen_domctl_memory_mapping_t; +DEFINE_XEN_GUEST_HANDLE(xen_domctl_memory_mapping_t); + + +/* Bind machine I/O port range -> HVM I/O port range. */ +#define XEN_DOMCTL_ioport_mapping 40 +struct xen_domctl_ioport_mapping { + uint32_t first_gport; /* first guest IO port*/ + uint32_t first_mport; /* first machine IO port */ + uint32_t nr_ports; /* size of port range */ + uint32_t add_mapping; /* add or remove mapping */ +}; +typedef struct xen_domctl_ioport_mapping xen_domctl_ioport_mapping_t; +DEFINE_XEN_GUEST_HANDLE(xen_domctl_ioport_mapping_t); + + struct xen_domctl { uint32_t cmd; uint32_t interface_version; /* XEN_DOMCTL_INTERFACE_VERSION */ @@ -462,6 +524,10 @@ struct xen_domctl { struct xen_domctl_hvmcontext hvmcontext; struct xen_domctl_address_size address_size; struct xen_domctl_sendtrigger sendtrigger; + struct xen_domctl_assign_device assign_device; + struct xen_domctl_bind_pt_irq bind_pt_irq; + struct xen_domctl_memory_mapping memory_mapping; + struct xen_domctl_ioport_mapping ioport_mapping; uint8_t pad[128]; } u; }; diff -r 9dd580b8b056 -r ca495837a722 xen/include/xen/acpi.h --- a/xen/include/xen/acpi.h Wed Sep 12 15:32:58 2007 +0100 +++ b/xen/include/xen/acpi.h Wed Sep 12 15:42:39 2007 +0100 @@ -367,8 +367,78 @@ enum acpi_table_id { ACPI_SPMI, ACPI_HPET, ACPI_MCFG, + ACPI_DMAR, ACPI_TABLE_COUNT }; + +/* DMA Remapping Reporting Table (DMAR) */ + +#define DMAR_FLAGS_INTR_REMAP 0x1 /* intr remap supported */ +struct acpi_table_dmar { + struct acpi_table_header header; + u8 haw; /* Host address Width */ + u8 flags; + u8 reserved[10]; +} __attribute__ ((packed)); + +struct acpi_dmar_entry_header { + u16 type; + u16 length; +} __attribute__((packed)); + +enum acpi_dmar_entry_type { + ACPI_DMAR_DRHD = 0, + ACPI_DMAR_RMRR, + ACPI_DMAR_ATSR, + ACPI_DMAR_ENTRY_COUNT +}; + +#define DRHD_FLAGS_INCLUDE_ALL 0x1 /* drhd remaps remaining devices */ +struct acpi_table_drhd { + struct acpi_dmar_entry_header header; + u8 flags; + u8 reserved; + u16 segment; + u64 address; /* register base address for this drhd */ +} __attribute__ ((packed)); + +struct acpi_table_rmrr { + struct acpi_dmar_entry_header header; + u16 reserved; + u16 segment; + u64 base_address; + u64 end_address; +} __attribute__ ((packed)); + +struct acpi_table_atsr { + struct acpi_dmar_entry_header header; + u8 flags; + u8 reserved; + u16 segment; +} __attribute__ ((packed)); + +enum acpi_dev_scope_type { + ACPI_DEV_ENDPOINT=0x01, /* PCI Endpoing device */ + ACPI_DEV_P2PBRIDGE, /* PCI-PCI Bridge */ + ACPI_DEV_IOAPIC, /* IOAPIC device*/ + ACPI_DEV_MSI_HPET, /* MSI capable HPET*/ + ACPI_DEV_ENTRY_COUNT +}; + +struct acpi_dev_scope { + u8 dev_type; + u8 length; + u8 reserved[2]; + u8 enum_id; + u8 start_bus; +} __attribute__((packed)); + +struct acpi_pci_path { + u8 dev; + u8 fn; +} __attribute__((packed)); + +typedef int (*acpi_dmar_entry_handler) (struct acpi_dmar_entry_header *header, const unsigned long end); typedef int (*acpi_table_handler) (unsigned long phys_addr, unsigned long size); diff -r 9dd580b8b056 -r ca495837a722 xen/include/xen/irq.h --- a/xen/include/xen/irq.h Wed Sep 12 15:32:58 2007 +0100 +++ b/xen/include/xen/irq.h Wed Sep 12 15:42:39 2007 +0100 @@ -64,6 +64,9 @@ extern irq_desc_t irq_desc[NR_IRQS]; extern int setup_irq(unsigned int, struct irqaction *); extern void free_irq(unsigned int); +extern int request_irq(unsigned int irq, + void (*handler)(int, void *, struct cpu_user_regs *), + unsigned long irqflags, const char * devname, void *dev_id); extern hw_irq_controller no_irq_type; extern void no_action(int cpl, void *dev_id, struct cpu_user_regs *regs); _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |