2
* Copyright (c) 2006, Intel Corporation.
4
* This program is free software; you can redistribute it and/or modify it
5
* under the terms and conditions of the GNU General Public License,
6
* version 2, as published by the Free Software Foundation.
8
* This program is distributed in the hope it will be useful, but WITHOUT
9
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13
* You should have received a copy of the GNU General Public License along with
14
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
15
* Place - Suite 330, Boston, MA 02111-1307 USA.
17
* Copyright (C) Allen Kay <allen.m.kay@intel.com>
18
* Copyright (C) Xiaohui Xin <xiaohui.xin@intel.com>
22
#include <xen/sched.h>
23
#include <xen/iommu.h>
26
#include <xen/pci_regs.h>
32
static void print_qi_regs(struct iommu *iommu)
36
val = dmar_readq(iommu->reg, DMAR_IQA_REG);
37
printk("DMAR_IQA_REG = %"PRIx64"\n", val);
39
val = dmar_readq(iommu->reg, DMAR_IQH_REG);
40
printk("DMAR_IQH_REG = %"PRIx64"\n", val);
42
val = dmar_readq(iommu->reg, DMAR_IQT_REG);
43
printk("DMAR_IQT_REG = %"PRIx64"\n", val);
46
static int qinval_next_index(struct iommu *iommu)
50
tail = dmar_readq(iommu->reg, DMAR_IQT_REG);
51
tail >>= QINVAL_INDEX_SHIFT;
53
/* (tail+1 == head) indicates a full queue, wait for HW */
54
while ( ( tail + 1 ) % QINVAL_ENTRY_NR ==
55
( dmar_readq(iommu->reg, DMAR_IQH_REG) >> QINVAL_INDEX_SHIFT ) )
61
static int qinval_update_qtail(struct iommu *iommu, int index)
65
/* Need hold register lock when update tail */
66
ASSERT( spin_is_locked(&iommu->register_lock) );
67
val = (index + 1) % QINVAL_ENTRY_NR;
68
dmar_writeq(iommu->reg, DMAR_IQT_REG, (val << QINVAL_INDEX_SHIFT));
72
static int gen_cc_inv_dsc(struct iommu *iommu, int index,
73
u16 did, u16 source_id, u8 function_mask, u8 granu)
76
struct qinval_entry *qinval_entry = NULL, *qinval_entries;
77
struct qi_ctrl *qi_ctrl = iommu_qi_ctrl(iommu);
78
u64 entry_base = qi_ctrl->qinval_maddr +
79
(( index >> QINVAL_ENTRY_ORDER ) << PAGE_SHIFT );
81
spin_lock_irqsave(&qi_ctrl->qinval_lock, flags);
83
(struct qinval_entry *)map_vtd_domain_page(entry_base);
84
qinval_entry = &qinval_entries[index % (1 << QINVAL_ENTRY_ORDER)];
85
qinval_entry->q.cc_inv_dsc.lo.type = TYPE_INVAL_CONTEXT;
86
qinval_entry->q.cc_inv_dsc.lo.granu = granu;
87
qinval_entry->q.cc_inv_dsc.lo.res_1 = 0;
88
qinval_entry->q.cc_inv_dsc.lo.did = did;
89
qinval_entry->q.cc_inv_dsc.lo.sid = source_id;
90
qinval_entry->q.cc_inv_dsc.lo.fm = function_mask;
91
qinval_entry->q.cc_inv_dsc.lo.res_2 = 0;
92
qinval_entry->q.cc_inv_dsc.hi.res = 0;
94
unmap_vtd_domain_page(qinval_entries);
95
spin_unlock_irqrestore(&qi_ctrl->qinval_lock, flags);
100
int queue_invalidate_context(struct iommu *iommu,
101
u16 did, u16 source_id, u8 function_mask, u8 granu)
107
spin_lock_irqsave(&iommu->register_lock, flags);
108
index = qinval_next_index(iommu);
111
ret = gen_cc_inv_dsc(iommu, index, did, source_id,
112
function_mask, granu);
113
ret |= qinval_update_qtail(iommu, index);
114
spin_unlock_irqrestore(&iommu->register_lock, flags);
118
static int gen_iotlb_inv_dsc(struct iommu *iommu, int index,
119
u8 granu, u8 dr, u8 dw, u16 did, u8 am, u8 ih, u64 addr)
122
struct qinval_entry *qinval_entry = NULL, *qinval_entries;
123
struct qi_ctrl *qi_ctrl = iommu_qi_ctrl(iommu);
124
u64 entry_base = qi_ctrl->qinval_maddr +
125
(( index >> QINVAL_ENTRY_ORDER ) << PAGE_SHIFT );
127
spin_lock_irqsave(&qi_ctrl->qinval_lock, flags);
130
(struct qinval_entry *)map_vtd_domain_page(entry_base);
131
qinval_entry = &qinval_entries[index % (1 << QINVAL_ENTRY_ORDER)];
132
qinval_entry->q.iotlb_inv_dsc.lo.type = TYPE_INVAL_IOTLB;
133
qinval_entry->q.iotlb_inv_dsc.lo.granu = granu;
134
qinval_entry->q.iotlb_inv_dsc.lo.dr = dr;
135
qinval_entry->q.iotlb_inv_dsc.lo.dw = dw;
136
qinval_entry->q.iotlb_inv_dsc.lo.res_1 = 0;
137
qinval_entry->q.iotlb_inv_dsc.lo.did = did;
138
qinval_entry->q.iotlb_inv_dsc.lo.res_2 = 0;
140
qinval_entry->q.iotlb_inv_dsc.hi.am = am;
141
qinval_entry->q.iotlb_inv_dsc.hi.ih = ih;
142
qinval_entry->q.iotlb_inv_dsc.hi.res_1 = 0;
143
qinval_entry->q.iotlb_inv_dsc.hi.addr = addr;
145
unmap_vtd_domain_page(qinval_entries);
146
spin_unlock_irqrestore(&qi_ctrl->qinval_lock, flags);
150
int queue_invalidate_iotlb(struct iommu *iommu,
151
u8 granu, u8 dr, u8 dw, u16 did, u8 am, u8 ih, u64 addr)
157
spin_lock_irqsave(&iommu->register_lock, flags);
159
index = qinval_next_index(iommu);
162
ret = gen_iotlb_inv_dsc(iommu, index, granu, dr, dw, did,
164
ret |= qinval_update_qtail(iommu, index);
165
spin_unlock_irqrestore(&iommu->register_lock, flags);
169
static int gen_wait_dsc(struct iommu *iommu, int index,
170
u8 iflag, u8 sw, u8 fn, u32 sdata, volatile u32 *saddr)
173
struct qinval_entry *qinval_entry = NULL, *qinval_entries;
174
struct qi_ctrl *qi_ctrl = iommu_qi_ctrl(iommu);
175
u64 entry_base = qi_ctrl->qinval_maddr +
176
(( index >> QINVAL_ENTRY_ORDER ) << PAGE_SHIFT );
178
spin_lock_irqsave(&qi_ctrl->qinval_lock, flags);
180
(struct qinval_entry *)map_vtd_domain_page(entry_base);
181
qinval_entry = &qinval_entries[index % (1 << QINVAL_ENTRY_ORDER)];
182
qinval_entry->q.inv_wait_dsc.lo.type = TYPE_INVAL_WAIT;
183
qinval_entry->q.inv_wait_dsc.lo.iflag = iflag;
184
qinval_entry->q.inv_wait_dsc.lo.sw = sw;
185
qinval_entry->q.inv_wait_dsc.lo.fn = fn;
186
qinval_entry->q.inv_wait_dsc.lo.res_1 = 0;
187
qinval_entry->q.inv_wait_dsc.lo.sdata = sdata;
188
qinval_entry->q.inv_wait_dsc.hi.res_1 = 0;
189
qinval_entry->q.inv_wait_dsc.hi.saddr = virt_to_maddr(saddr) >> 2;
190
unmap_vtd_domain_page(qinval_entries);
191
spin_unlock_irqrestore(&qi_ctrl->qinval_lock, flags);
195
static int queue_invalidate_wait(struct iommu *iommu,
196
u8 iflag, u8 sw, u8 fn)
199
u32 poll_slot = QINVAL_STAT_INIT;
204
spin_lock_irqsave(&iommu->register_lock, flags);
205
index = qinval_next_index(iommu);
209
ret = gen_wait_dsc(iommu, index, iflag, sw, fn, QINVAL_STAT_DONE, &poll_slot);
210
ret |= qinval_update_qtail(iommu, index);
211
spin_unlock_irqrestore(&iommu->register_lock, flags);
213
/* Now we don't support interrupt method */
216
/* In case all wait descriptor writes to same addr with same data */
218
while ( poll_slot != QINVAL_STAT_DONE )
220
if ( NOW() > (start_time + DMAR_OPERATION_TIMEOUT) )
222
print_qi_regs(iommu);
223
panic("queue invalidate wait descriptor was not executed\n");
231
int invalidate_sync(struct iommu *iommu)
234
struct qi_ctrl *qi_ctrl = iommu_qi_ctrl(iommu);
236
if ( qi_ctrl->qinval_maddr != 0 )
238
ret = queue_invalidate_wait(iommu, 0, 1, 1);
244
static int gen_dev_iotlb_inv_dsc(struct iommu *iommu, int index,
245
u32 max_invs_pend, u16 sid, u16 size, u64 addr)
248
struct qinval_entry *qinval_entry = NULL, *qinval_entries;
249
struct qi_ctrl *qi_ctrl = iommu_qi_ctrl(iommu);
250
u64 entry_base = qi_ctrl->qinval_maddr +
251
(( index >> QINVAL_ENTRY_ORDER ) << PAGE_SHIFT );
253
spin_lock_irqsave(&qi_ctrl->qinval_lock, flags);
256
(struct qinval_entry *)map_vtd_domain_page(entry_base);
257
qinval_entry = &qinval_entries[index % (1 << QINVAL_ENTRY_ORDER)];
258
qinval_entry->q.dev_iotlb_inv_dsc.lo.type = TYPE_INVAL_DEVICE_IOTLB;
259
qinval_entry->q.dev_iotlb_inv_dsc.lo.res_1 = 0;
260
qinval_entry->q.dev_iotlb_inv_dsc.lo.max_invs_pend = max_invs_pend;
261
qinval_entry->q.dev_iotlb_inv_dsc.lo.res_2 = 0;
262
qinval_entry->q.dev_iotlb_inv_dsc.lo.sid = sid;
263
qinval_entry->q.dev_iotlb_inv_dsc.lo.res_3 = 0;
265
qinval_entry->q.dev_iotlb_inv_dsc.hi.size = size;
266
qinval_entry->q.dev_iotlb_inv_dsc.hi.res_1 = 0;
267
qinval_entry->q.dev_iotlb_inv_dsc.hi.addr = addr >> PAGE_SHIFT_4K;
269
unmap_vtd_domain_page(qinval_entries);
270
spin_unlock_irqrestore(&qi_ctrl->qinval_lock, flags);
274
int qinval_device_iotlb(struct iommu *iommu,
275
u32 max_invs_pend, u16 sid, u16 size, u64 addr)
281
spin_lock_irqsave(&iommu->register_lock, flags);
282
index = qinval_next_index(iommu);
285
ret = gen_dev_iotlb_inv_dsc(iommu, index, max_invs_pend,
287
ret |= qinval_update_qtail(iommu, index);
288
spin_unlock_irqrestore(&iommu->register_lock, flags);
292
static int gen_iec_inv_dsc(struct iommu *iommu, int index,
293
u8 granu, u8 im, u16 iidx)
296
struct qinval_entry *qinval_entry = NULL, *qinval_entries;
297
struct qi_ctrl *qi_ctrl = iommu_qi_ctrl(iommu);
298
u64 entry_base = qi_ctrl->qinval_maddr +
299
(( index >> QINVAL_ENTRY_ORDER ) << PAGE_SHIFT );
301
spin_lock_irqsave(&qi_ctrl->qinval_lock, flags);
304
(struct qinval_entry *)map_vtd_domain_page(entry_base);
305
qinval_entry = &qinval_entries[index % (1 << QINVAL_ENTRY_ORDER)];
306
qinval_entry->q.iec_inv_dsc.lo.type = TYPE_INVAL_IEC;
307
qinval_entry->q.iec_inv_dsc.lo.granu = granu;
308
qinval_entry->q.iec_inv_dsc.lo.res_1 = 0;
309
qinval_entry->q.iec_inv_dsc.lo.im = im;
310
qinval_entry->q.iec_inv_dsc.lo.iidx = iidx;
311
qinval_entry->q.iec_inv_dsc.lo.res_2 = 0;
312
qinval_entry->q.iec_inv_dsc.hi.res = 0;
314
unmap_vtd_domain_page(qinval_entries);
315
spin_unlock_irqrestore(&qi_ctrl->qinval_lock, flags);
319
int queue_invalidate_iec(struct iommu *iommu, u8 granu, u8 im, u16 iidx)
325
spin_lock_irqsave(&iommu->register_lock, flags);
326
index = qinval_next_index(iommu);
329
ret = gen_iec_inv_dsc(iommu, index, granu, im, iidx);
330
ret |= qinval_update_qtail(iommu, index);
331
spin_unlock_irqrestore(&iommu->register_lock, flags);
335
static int __iommu_flush_iec(struct iommu *iommu, u8 granu, u8 im, u16 iidx)
338
ret = queue_invalidate_iec(iommu, granu, im, iidx);
339
ret |= invalidate_sync(iommu);
342
* reading vt-d architecture register will ensure
343
* draining happens in implementation independent way.
345
(void)dmar_readq(iommu->reg, DMAR_CAP_REG);
349
int iommu_flush_iec_global(struct iommu *iommu)
351
return __iommu_flush_iec(iommu, IEC_GLOBAL_INVL, 0, 0);
354
int iommu_flush_iec_index(struct iommu *iommu, u8 im, u16 iidx)
356
return __iommu_flush_iec(iommu, IEC_INDEX_INVL, im, iidx);
359
static int flush_context_qi(
360
void *_iommu, u16 did, u16 sid, u8 fm, u64 type,
361
int flush_non_present_entry)
364
struct iommu *iommu = (struct iommu *)_iommu;
365
struct qi_ctrl *qi_ctrl = iommu_qi_ctrl(iommu);
368
* In the non-present entry flush case, if hardware doesn't cache
369
* non-present entry we do nothing and if hardware cache non-present
370
* entry, we flush entries of domain 0 (the domain id is used to cache
371
* any non-present entries)
373
if ( flush_non_present_entry )
375
if ( !cap_caching_mode(iommu->cap) )
381
if ( qi_ctrl->qinval_maddr != 0 )
383
ret = queue_invalidate_context(iommu, did, sid, fm,
384
type >> DMA_CCMD_INVL_GRANU_OFFSET);
385
ret |= invalidate_sync(iommu);
390
static int flush_iotlb_qi(
391
void *_iommu, u16 did,
392
u64 addr, unsigned int size_order, u64 type,
393
int flush_non_present_entry, int flush_dev_iotlb)
397
struct iommu *iommu = (struct iommu *)_iommu;
398
struct qi_ctrl *qi_ctrl = iommu_qi_ctrl(iommu);
401
* In the non-present entry flush case, if hardware doesn't cache
402
* non-present entry we do nothing and if hardware cache non-present
403
* entry, we flush entries of domain 0 (the domain id is used to cache
404
* any non-present entries)
406
if ( flush_non_present_entry )
408
if ( !cap_caching_mode(iommu->cap) )
414
if ( qi_ctrl->qinval_maddr != 0 )
416
/* use queued invalidation */
417
if (cap_write_drain(iommu->cap))
419
if (cap_read_drain(iommu->cap))
421
/* Need to conside the ih bit later */
422
ret = queue_invalidate_iotlb(iommu,
423
(type >> DMA_TLB_FLUSH_GRANU_OFFSET), dr,
424
dw, did, (u8)size_order, 0, addr);
425
if ( flush_dev_iotlb )
426
ret |= dev_invalidate_iotlb(iommu, did, addr, size_order, type);
427
ret |= invalidate_sync(iommu);
432
int enable_qinval(struct iommu *iommu)
434
struct acpi_drhd_unit *drhd;
435
struct qi_ctrl *qi_ctrl;
436
struct iommu_flush *flush;
440
qi_ctrl = iommu_qi_ctrl(iommu);
441
flush = iommu_get_flush(iommu);
443
ASSERT(ecap_queued_inval(iommu->ecap) && iommu_qinval);
445
if ( qi_ctrl->qinval_maddr == 0 )
447
drhd = iommu_to_drhd(iommu);
448
qi_ctrl->qinval_maddr = alloc_pgtable_maddr(drhd, QINVAL_ARCH_PAGE_NR);
449
if ( qi_ctrl->qinval_maddr == 0 )
451
dprintk(XENLOG_WARNING VTDPREFIX,
452
"Cannot allocate memory for qi_ctrl->qinval_maddr\n");
457
flush->context = flush_context_qi;
458
flush->iotlb = flush_iotlb_qi;
460
/* Setup Invalidation Queue Address(IQA) register with the
461
* address of the page we just allocated. QS field at
462
* bits[2:0] to indicate size of queue is one 4KB page.
463
* That's 256 entries. Queued Head (IQH) and Queue Tail (IQT)
464
* registers are automatically reset to 0 with write
467
qi_ctrl->qinval_maddr |= QINVAL_PAGE_ORDER;
469
spin_lock_irqsave(&iommu->register_lock, flags);
470
dmar_writeq(iommu->reg, DMAR_IQA_REG, qi_ctrl->qinval_maddr);
472
dmar_writeq(iommu->reg, DMAR_IQT_REG, 0);
474
/* enable queued invalidation hardware */
475
sts = dmar_readl(iommu->reg, DMAR_GSTS_REG);
476
dmar_writel(iommu->reg, DMAR_GCMD_REG, sts | DMA_GCMD_QIE);
478
/* Make sure hardware complete it */
479
IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG, dmar_readl,
480
(sts & DMA_GSTS_QIES), sts);
481
spin_unlock_irqrestore(&iommu->register_lock, flags);
486
void disable_qinval(struct iommu *iommu)
491
ASSERT(ecap_queued_inval(iommu->ecap) && iommu_qinval);
493
spin_lock_irqsave(&iommu->register_lock, flags);
494
sts = dmar_readl(iommu->reg, DMAR_GSTS_REG);
495
dmar_writel(iommu->reg, DMAR_GCMD_REG, sts & (~DMA_GCMD_QIE));
497
/* Make sure hardware complete it */
498
IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG, dmar_readl,
499
!(sts & DMA_GSTS_QIES), sts);
500
spin_unlock_irqrestore(&iommu->register_lock, flags);