string: factorize skip_spaces and export it to be generally available
[safe/jmp/linux-2.6] / include / linux / intel-iommu.h
index afb0d2a..4f0a72a 100644 (file)
 #define _INTEL_IOMMU_H_
 
 #include <linux/types.h>
-#include <linux/msi.h>
-#include <linux/sysdev.h>
 #include <linux/iova.h>
 #include <linux/io.h>
 #include <linux/dma_remapping.h>
 #include <asm/cacheflush.h>
+#include <asm/iommu.h>
 
 /*
  * Intel IOMMU register specification per version 1.0 public spec.
@@ -54,6 +53,7 @@
 #define        DMAR_PHMLIMIT_REG 0x78  /* pmrr high limit */
 #define DMAR_IQH_REG   0x80    /* Invalidation queue head register */
 #define DMAR_IQT_REG   0x88    /* Invalidation queue tail register */
+#define DMAR_IQ_SHIFT  4       /* Invalidation queue head/tail shift */
 #define DMAR_IQA_REG   0x90    /* Invalidation queue addr register */
 #define DMAR_ICS_REG   0x98    /* Invalidation complete status register */
 #define DMAR_IRTA_REG  0xb8    /* Interrupt remapping table addr register */
@@ -121,10 +121,12 @@ static inline void dmar_writeq(void __iomem *addr, u64 val)
        (ecap_iotlb_offset(e) + ecap_niotlb_iunits(e) * 16)
 #define ecap_coherent(e)       ((e) & 0x1)
 #define ecap_qis(e)            ((e) & 0x2)
+#define ecap_pass_through(e)   ((e >> 6) & 0x1)
 #define ecap_eim_support(e)    ((e >> 4) & 0x1)
 #define ecap_ir_support(e)     ((e >> 3) & 0x1)
+#define ecap_dev_iotlb_support(e)      (((e) >> 2) & 0x1)
 #define ecap_max_handle_mask(e) ((e >> 20) & 0xf)
-
+#define ecap_sc_support(e)     ((e >> 7) & 0x1) /* Snooping Control */
 
 /* IOTLB_REG */
 #define DMA_TLB_FLUSH_GRANU_OFFSET  60
@@ -165,6 +167,7 @@ static inline void dmar_writeq(void __iomem *addr, u64 val)
 #define DMA_GCMD_QIE (((u32)1) << 26)
 #define DMA_GCMD_SIRTP (((u32)1) << 24)
 #define DMA_GCMD_IRE (((u32) 1) << 25)
+#define DMA_GCMD_CFI (((u32) 1) << 23)
 
 /* GSTS_REG */
 #define DMA_GSTS_TES (((u32)1) << 31)
@@ -175,6 +178,7 @@ static inline void dmar_writeq(void __iomem *addr, u64 val)
 #define DMA_GSTS_QIES (((u32)1) << 26)
 #define DMA_GSTS_IRTPS (((u32)1) << 24)
 #define DMA_GSTS_IRES (((u32)1) << 25)
+#define DMA_GSTS_CFIS (((u32)1) << 23)
 
 /* CCMD_REG */
 #define DMA_CCMD_ICC (((u64)1) << 63)
@@ -195,6 +199,9 @@ static inline void dmar_writeq(void __iomem *addr, u64 val)
 /* FSTS_REG */
 #define DMA_FSTS_PPF ((u32)2)
 #define DMA_FSTS_PFO ((u32)1)
+#define DMA_FSTS_IQE (1 << 4)
+#define DMA_FSTS_ICE (1 << 5)
+#define DMA_FSTS_ITE (1 << 6)
 #define dma_fsts_fault_record_index(s) (((s) >> 8) & 0xff)
 
 /* FRCD_REG, 32 bits access */
@@ -202,29 +209,29 @@ static inline void dmar_writeq(void __iomem *addr, u64 val)
 #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 */
-
-#define DMAR_OPERATION_TIMEOUT ((cycles_t) tsc_khz*10*1000) /* 10sec */
-
-#define IOMMU_WAIT_OP(iommu, offset, op, cond, sts) \
-{\
-       cycles_t start_time = get_cycles();\
-       while (1) {\
-               sts = op (iommu->reg + offset);\
-               if (cond)\
-                       break;\
+/* low 64 bit */
+#define dma_frcd_page_addr(d) (d & (((u64)-1) << PAGE_SHIFT))
+
+#define IOMMU_WAIT_OP(iommu, offset, op, cond, sts)                    \
+do {                                                                   \
+       cycles_t start_time = get_cycles();                             \
+       while (1) {                                                     \
+               sts = op(iommu->reg + offset);                          \
+               if (cond)                                               \
+                       break;                                          \
                if (DMAR_OPERATION_TIMEOUT < (get_cycles() - start_time))\
-                       panic("DMAR hardware is malfunctioning\n");\
-               cpu_relax();\
-       }\
-}
+                       panic("DMAR hardware is malfunctioning\n");     \
+               cpu_relax();                                            \
+       }                                                               \
+} while (0)
 
 #define QI_LENGTH      256     /* queue length */
 
 enum {
        QI_FREE,
        QI_IN_USE,
-       QI_DONE
+       QI_DONE,
+       QI_ABORT
 };
 
 #define QI_CC_TYPE             0x1
@@ -244,7 +251,7 @@ enum {
 #define QI_IOTLB_DR(dr)        (((u64)dr) << 7)
 #define QI_IOTLB_DW(dw)        (((u64)dw) << 6)
 #define QI_IOTLB_GRAN(gran)    (((u64)gran) >> (DMA_TLB_FLUSH_GRANU_OFFSET-4))
-#define QI_IOTLB_ADDR(addr)    (((u64)addr) & PAGE_MASK_4K)
+#define QI_IOTLB_ADDR(addr)    (((u64)addr) & VTD_PAGE_MASK)
 #define QI_IOTLB_IH(ih)                (((u64)ih) << 6)
 #define QI_IOTLB_AM(am)                (((u8)am))
 
@@ -253,6 +260,12 @@ enum {
 #define QI_CC_DID(did)         (((u64)did) << 16)
 #define QI_CC_GRAN(gran)       (((u64)gran) >> (DMA_CCMD_INVL_GRANU_OFFSET-4))
 
+#define QI_DEV_IOTLB_SID(sid)  ((u64)((sid) & 0xffff) << 32)
+#define QI_DEV_IOTLB_QDEP(qdep)        (((qdep) & 0x1f) << 16)
+#define QI_DEV_IOTLB_ADDR(addr)        ((u64)(addr) & VTD_PAGE_MASK)
+#define QI_DEV_IOTLB_SIZE      1
+#define QI_DEV_IOTLB_MAX_INVS  32
+
 struct qi_desc {
        u64 low, high;
 };
@@ -279,20 +292,31 @@ struct ir_table {
 #endif
 
 struct iommu_flush {
-       int (*flush_context)(struct intel_iommu *iommu, u16 did, u16 sid, u8 fm,
-               u64 type, int non_present_entry_flush);
-       int (*flush_iotlb)(struct intel_iommu *iommu, u16 did, u64 addr,
-               unsigned int size_order, u64 type, int non_present_entry_flush);
+       void (*flush_context)(struct intel_iommu *iommu, u16 did, u16 sid,
+                             u8 fm, u64 type);
+       void (*flush_iotlb)(struct intel_iommu *iommu, u16 did, u64 addr,
+                           unsigned int size_order, u64 type);
+};
+
+enum {
+       SR_DMAR_FECTL_REG,
+       SR_DMAR_FEDATA_REG,
+       SR_DMAR_FEADDR_REG,
+       SR_DMAR_FEUADDR_REG,
+       MAX_SR_DMAR_REGS
 };
 
 struct intel_iommu {
        void __iomem    *reg; /* Pointer to hardware regs, virtual addr */
        u64             cap;
        u64             ecap;
-       int             seg;
        u32             gcmd; /* Holds TE, EAFL. Don't need SRTP, SFL, WBF */
        spinlock_t      register_lock; /* protect register handling */
        int             seq_id; /* sequence id of the iommu */
+       int             agaw; /* agaw of this iommu */
+       int             msagaw; /* max sagaw of this iommu */
+       unsigned int    irq;
+       unsigned char   name[13];    /* Device Name */
 
 #ifdef CONFIG_DMAR
        unsigned long   *domain_ids; /* bitmap of domains */
@@ -300,13 +324,11 @@ struct intel_iommu {
        spinlock_t      lock; /* protect context, domain ids */
        struct root_entry *root_entry; /* virtual address */
 
-       unsigned int irq;
-       unsigned char name[7];    /* Device Name */
-       struct msi_msg saved_msg;
-       struct sys_device sysdev;
        struct iommu_flush flush;
 #endif
        struct q_inval  *qi;            /* Queued invalidation info */
+       u32 *iommu_state; /* Store iommu states between suspend and resume.*/
+
 #ifdef CONFIG_INTR_REMAP
        struct ir_table *ir_table;      /* Interrupt remapping info */
 #endif
@@ -320,37 +342,24 @@ static inline void __iommu_flush_cache(
 }
 
 extern struct dmar_drhd_unit * dmar_find_matched_drhd_unit(struct pci_dev *dev);
+extern int dmar_find_matched_atsr_unit(struct pci_dev *dev);
 
 extern int alloc_iommu(struct dmar_drhd_unit *drhd);
 extern void free_iommu(struct intel_iommu *iommu);
 extern int dmar_enable_qi(struct intel_iommu *iommu);
+extern void dmar_disable_qi(struct intel_iommu *iommu);
+extern int dmar_reenable_qi(struct intel_iommu *iommu);
 extern void qi_global_iec(struct intel_iommu *iommu);
 
-extern int qi_flush_context(struct intel_iommu *iommu, u16 did, u16 sid,
-                               u8 fm, u64 type, int non_present_entry_flush);
-extern int qi_flush_iotlb(struct intel_iommu *iommu, u16 did, u64 addr,
-                         unsigned int size_order, u64 type,
-                         int non_present_entry_flush);
-
-extern void qi_submit_sync(struct qi_desc *desc, struct intel_iommu *iommu);
+extern void qi_flush_context(struct intel_iommu *iommu, u16 did, u16 sid,
+                            u8 fm, u64 type);
+extern void qi_flush_iotlb(struct intel_iommu *iommu, u16 did, u64 addr,
+                         unsigned int size_order, u64 type);
+extern void qi_flush_dev_iotlb(struct intel_iommu *iommu, u16 sid, u16 qdep,
+                              u64 addr, unsigned mask);
 
-void intel_iommu_domain_exit(struct dmar_domain *domain);
-struct dmar_domain *intel_iommu_domain_alloc(struct pci_dev *pdev);
-int intel_iommu_context_mapping(struct dmar_domain *domain,
-                               struct pci_dev *pdev);
-int intel_iommu_page_mapping(struct dmar_domain *domain, dma_addr_t iova,
-                            u64 hpa, size_t size, int prot);
-void intel_iommu_detach_dev(struct dmar_domain *domain, u8 bus, u8 devfn);
-struct dmar_domain *intel_iommu_find_domain(struct pci_dev *pdev);
-u64 intel_iommu_iova_to_pfn(struct dmar_domain *domain, u64 iova);
+extern int qi_submit_sync(struct qi_desc *desc, struct intel_iommu *iommu);
 
-#ifdef CONFIG_DMAR
-int intel_iommu_found(void);
-#else /* CONFIG_DMAR */
-static inline int intel_iommu_found(void)
-{
-       return 0;
-}
-#endif /* CONFIG_DMAR */
+extern int dmar_ir_support(void);
 
 #endif