diff options
author | Suresh Siddha <suresh.b.siddha@intel.com> | 2008-07-10 14:16:42 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-07-12 02:44:52 -0400 |
commit | fe962e90cb17a8426e144dee970e77ed789d98ee (patch) | |
tree | c7b3343df9bf58e047333758a89c78f6615fb97b /drivers/pci/intel-iommu.h | |
parent | cf1337f0447e5be8e66daa944f0ea3bcac2b6179 (diff) |
x64, x2apic/intr-remap: Queued invalidation infrastructure (part of VT-d)
Queued invalidation (part of Intel Virtualization Technology for
Directed I/O architecture) infrastructure.
This will be used for invalidating the interrupt entry cache in the
case of Interrupt-remapping and IOTLB invalidation in the case
of DMA-remapping.
Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com>
Cc: akpm@linux-foundation.org
Cc: arjan@linux.intel.com
Cc: andi@firstfloor.org
Cc: ebiederm@xmission.com
Cc: jbarnes@virtuousgeek.org
Cc: steiner@sgi.com
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'drivers/pci/intel-iommu.h')
-rw-r--r-- | drivers/pci/intel-iommu.h | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/drivers/pci/intel-iommu.h b/drivers/pci/intel-iommu.h index 3a650e8cba33..2983ce895353 100644 --- a/drivers/pci/intel-iommu.h +++ b/drivers/pci/intel-iommu.h | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/sysdev.h> | 27 | #include <linux/sysdev.h> |
28 | #include "iova.h" | 28 | #include "iova.h" |
29 | #include <linux/io.h> | 29 | #include <linux/io.h> |
30 | #include <asm/cacheflush.h> | ||
30 | #include "dma_remapping.h" | 31 | #include "dma_remapping.h" |
31 | 32 | ||
32 | /* | 33 | /* |
@@ -51,6 +52,10 @@ | |||
51 | #define DMAR_PLMLIMIT_REG 0x6c /* PMRR low limit */ | 52 | #define DMAR_PLMLIMIT_REG 0x6c /* PMRR low limit */ |
52 | #define DMAR_PHMBASE_REG 0x70 /* pmrr high base addr */ | 53 | #define DMAR_PHMBASE_REG 0x70 /* pmrr high base addr */ |
53 | #define DMAR_PHMLIMIT_REG 0x78 /* pmrr high limit */ | 54 | #define DMAR_PHMLIMIT_REG 0x78 /* pmrr high limit */ |
55 | #define DMAR_IQH_REG 0x80 /* Invalidation queue head register */ | ||
56 | #define DMAR_IQT_REG 0x88 /* Invalidation queue tail register */ | ||
57 | #define DMAR_IQA_REG 0x90 /* Invalidation queue addr register */ | ||
58 | #define DMAR_ICS_REG 0x98 /* Invalidation complete status register */ | ||
54 | 59 | ||
55 | #define OFFSET_STRIDE (9) | 60 | #define OFFSET_STRIDE (9) |
56 | /* | 61 | /* |
@@ -114,6 +119,7 @@ static inline void dmar_writeq(void __iomem *addr, u64 val) | |||
114 | #define ecap_max_iotlb_offset(e) \ | 119 | #define ecap_max_iotlb_offset(e) \ |
115 | (ecap_iotlb_offset(e) + ecap_niotlb_iunits(e) * 16) | 120 | (ecap_iotlb_offset(e) + ecap_niotlb_iunits(e) * 16) |
116 | #define ecap_coherent(e) ((e) & 0x1) | 121 | #define ecap_coherent(e) ((e) & 0x1) |
122 | #define ecap_qis(e) ((e) & 0x2) | ||
117 | #define ecap_eim_support(e) ((e >> 4) & 0x1) | 123 | #define ecap_eim_support(e) ((e >> 4) & 0x1) |
118 | #define ecap_ir_support(e) ((e >> 3) & 0x1) | 124 | #define ecap_ir_support(e) ((e >> 3) & 0x1) |
119 | 125 | ||
@@ -131,6 +137,17 @@ static inline void dmar_writeq(void __iomem *addr, u64 val) | |||
131 | #define DMA_TLB_IH_NONLEAF (((u64)1) << 6) | 137 | #define DMA_TLB_IH_NONLEAF (((u64)1) << 6) |
132 | #define DMA_TLB_MAX_SIZE (0x3f) | 138 | #define DMA_TLB_MAX_SIZE (0x3f) |
133 | 139 | ||
140 | /* INVALID_DESC */ | ||
141 | #define DMA_ID_TLB_GLOBAL_FLUSH (((u64)1) << 3) | ||
142 | #define DMA_ID_TLB_DSI_FLUSH (((u64)2) << 3) | ||
143 | #define DMA_ID_TLB_PSI_FLUSH (((u64)3) << 3) | ||
144 | #define DMA_ID_TLB_READ_DRAIN (((u64)1) << 7) | ||
145 | #define DMA_ID_TLB_WRITE_DRAIN (((u64)1) << 6) | ||
146 | #define DMA_ID_TLB_DID(id) (((u64)((id & 0xffff) << 16))) | ||
147 | #define DMA_ID_TLB_IH_NONLEAF (((u64)1) << 6) | ||
148 | #define DMA_ID_TLB_ADDR(addr) (addr) | ||
149 | #define DMA_ID_TLB_ADDR_MASK(mask) (mask) | ||
150 | |||
134 | /* PMEN_REG */ | 151 | /* PMEN_REG */ |
135 | #define DMA_PMEN_EPM (((u32)1)<<31) | 152 | #define DMA_PMEN_EPM (((u32)1)<<31) |
136 | #define DMA_PMEN_PRS (((u32)1)<<0) | 153 | #define DMA_PMEN_PRS (((u32)1)<<0) |
@@ -140,6 +157,7 @@ static inline void dmar_writeq(void __iomem *addr, u64 val) | |||
140 | #define DMA_GCMD_SRTP (((u32)1) << 30) | 157 | #define DMA_GCMD_SRTP (((u32)1) << 30) |
141 | #define DMA_GCMD_SFL (((u32)1) << 29) | 158 | #define DMA_GCMD_SFL (((u32)1) << 29) |
142 | #define DMA_GCMD_EAFL (((u32)1) << 28) | 159 | #define DMA_GCMD_EAFL (((u32)1) << 28) |
160 | #define DMA_GCMD_QIE (((u32)1) << 26) | ||
143 | #define DMA_GCMD_WBF (((u32)1) << 27) | 161 | #define DMA_GCMD_WBF (((u32)1) << 27) |
144 | 162 | ||
145 | /* GSTS_REG */ | 163 | /* GSTS_REG */ |
@@ -147,6 +165,7 @@ static inline void dmar_writeq(void __iomem *addr, u64 val) | |||
147 | #define DMA_GSTS_RTPS (((u32)1) << 30) | 165 | #define DMA_GSTS_RTPS (((u32)1) << 30) |
148 | #define DMA_GSTS_FLS (((u32)1) << 29) | 166 | #define DMA_GSTS_FLS (((u32)1) << 29) |
149 | #define DMA_GSTS_AFLS (((u32)1) << 28) | 167 | #define DMA_GSTS_AFLS (((u32)1) << 28) |
168 | #define DMA_GSTS_QIES (((u32)1) << 26) | ||
150 | #define DMA_GSTS_WBFS (((u32)1) << 27) | 169 | #define DMA_GSTS_WBFS (((u32)1) << 27) |
151 | 170 | ||
152 | /* CCMD_REG */ | 171 | /* CCMD_REG */ |
@@ -192,6 +211,40 @@ static inline void dmar_writeq(void __iomem *addr, u64 val) | |||
192 | }\ | 211 | }\ |
193 | } | 212 | } |
194 | 213 | ||
214 | #define QI_LENGTH 256 /* queue length */ | ||
215 | |||
216 | enum { | ||
217 | QI_FREE, | ||
218 | QI_IN_USE, | ||
219 | QI_DONE | ||
220 | }; | ||
221 | |||
222 | #define QI_CC_TYPE 0x1 | ||
223 | #define QI_IOTLB_TYPE 0x2 | ||
224 | #define QI_DIOTLB_TYPE 0x3 | ||
225 | #define QI_IEC_TYPE 0x4 | ||
226 | #define QI_IWD_TYPE 0x5 | ||
227 | |||
228 | #define QI_IEC_SELECTIVE (((u64)1) << 4) | ||
229 | #define QI_IEC_IIDEX(idx) (((u64)(idx & 0xffff) << 32)) | ||
230 | #define QI_IEC_IM(m) (((u64)(m & 0x1f) << 27)) | ||
231 | |||
232 | #define QI_IWD_STATUS_DATA(d) (((u64)d) << 32) | ||
233 | #define QI_IWD_STATUS_WRITE (((u64)1) << 5) | ||
234 | |||
235 | struct qi_desc { | ||
236 | u64 low, high; | ||
237 | }; | ||
238 | |||
239 | struct q_inval { | ||
240 | spinlock_t q_lock; | ||
241 | struct qi_desc *desc; /* invalidation queue */ | ||
242 | int *desc_status; /* desc status */ | ||
243 | int free_head; /* first free entry */ | ||
244 | int free_tail; /* last free entry */ | ||
245 | int free_cnt; | ||
246 | }; | ||
247 | |||
195 | struct intel_iommu { | 248 | struct intel_iommu { |
196 | void __iomem *reg; /* Pointer to hardware regs, virtual addr */ | 249 | void __iomem *reg; /* Pointer to hardware regs, virtual addr */ |
197 | u64 cap; | 250 | u64 cap; |
@@ -212,8 +265,16 @@ struct intel_iommu { | |||
212 | struct msi_msg saved_msg; | 265 | struct msi_msg saved_msg; |
213 | struct sys_device sysdev; | 266 | struct sys_device sysdev; |
214 | #endif | 267 | #endif |
268 | struct q_inval *qi; /* Queued invalidation info */ | ||
215 | }; | 269 | }; |
216 | 270 | ||
271 | static inline void __iommu_flush_cache( | ||
272 | struct intel_iommu *iommu, void *addr, int size) | ||
273 | { | ||
274 | if (!ecap_coherent(iommu->ecap)) | ||
275 | clflush_cache_range(addr, size); | ||
276 | } | ||
277 | |||
217 | extern struct dmar_drhd_unit * dmar_find_matched_drhd_unit(struct pci_dev *dev); | 278 | extern struct dmar_drhd_unit * dmar_find_matched_drhd_unit(struct pci_dev *dev); |
218 | 279 | ||
219 | extern int alloc_iommu(struct dmar_drhd_unit *drhd); | 280 | extern int alloc_iommu(struct dmar_drhd_unit *drhd); |