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>
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);