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>
20
#include <xen/sched.h>
21
#include <xen/delay.h>
22
#include <xen/iommu.h>
25
#include <xen/pci_regs.h>
31
int is_usb_device(u8 bus, u8 devfn)
33
u16 class = pci_conf_read16(bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
35
return (class == 0xc03);
38
/* Disable vt-d protected memory registers. */
39
void disable_pmr(struct iommu *iommu)
44
val = dmar_readl(iommu->reg, DMAR_PMEN_REG);
45
if ( !(val & DMA_PMEN_PRS) )
48
spin_lock_irqsave(&iommu->register_lock, flags);
49
dmar_writel(iommu->reg, DMAR_PMEN_REG, val & ~DMA_PMEN_EPM);
51
IOMMU_WAIT_OP(iommu, DMAR_PMEN_REG, dmar_readl,
52
!(val & DMA_PMEN_PRS), val);
53
spin_unlock_irqrestore(&iommu->register_lock, flags);
55
dprintk(XENLOG_INFO VTDPREFIX,
56
"Disabled protected memory registers\n");
59
void print_iommu_regs(struct acpi_drhd_unit *drhd)
61
struct iommu *iommu = drhd->iommu;
64
printk("---- print_iommu_regs ----\n");
65
printk(" drhd->address = %"PRIx64"\n", drhd->address);
66
printk(" VER = %x\n", dmar_readl(iommu->reg, DMAR_VER_REG));
67
printk(" CAP = %"PRIx64"\n", cap = dmar_readq(iommu->reg, DMAR_CAP_REG));
68
printk(" n_fault_reg = %"PRIx64"\n", cap_num_fault_regs(cap));
69
printk(" fault_recording_offset = %"PRIx64"\n", cap_fault_reg_offset(cap));
70
if ( cap_fault_reg_offset(cap) < PAGE_SIZE )
72
printk(" fault_recording_reg_l = %"PRIx64"\n",
73
dmar_readq(iommu->reg, cap_fault_reg_offset(cap)));
74
printk(" fault_recording_reg_h = %"PRIx64"\n",
75
dmar_readq(iommu->reg, cap_fault_reg_offset(cap) + 8));
77
printk(" ECAP = %"PRIx64"\n", dmar_readq(iommu->reg, DMAR_ECAP_REG));
78
printk(" GCMD = %x\n", dmar_readl(iommu->reg, DMAR_GCMD_REG));
79
printk(" GSTS = %x\n", dmar_readl(iommu->reg, DMAR_GSTS_REG));
80
printk(" RTADDR = %"PRIx64"\n", dmar_readq(iommu->reg,DMAR_RTADDR_REG));
81
printk(" CCMD = %"PRIx64"\n", dmar_readq(iommu->reg, DMAR_CCMD_REG));
82
printk(" FSTS = %x\n", dmar_readl(iommu->reg, DMAR_FSTS_REG));
83
printk(" FECTL = %x\n", dmar_readl(iommu->reg, DMAR_FECTL_REG));
84
printk(" FEDATA = %x\n", dmar_readl(iommu->reg, DMAR_FEDATA_REG));
85
printk(" FEADDR = %x\n", dmar_readl(iommu->reg, DMAR_FEADDR_REG));
86
printk(" FEUADDR = %x\n", dmar_readl(iommu->reg, DMAR_FEUADDR_REG));
89
static u32 get_level_index(unsigned long gmfn, int level)
92
gmfn = gmfn >> LEVEL_STRIDE;
94
return gmfn & LEVEL_MASK;
97
void print_vtd_entries(struct iommu *iommu, int bus, int devfn, u64 gmfn)
99
struct context_entry *ctxt_entry;
100
struct root_entry *root_entry;
105
printk("print_vtd_entries: iommu = %p bdf = %x:%x.%x gmfn = %"PRIx64"\n",
106
iommu, bus, PCI_SLOT(devfn), PCI_FUNC(devfn), gmfn);
108
if ( iommu->root_maddr == 0 )
110
printk(" iommu->root_maddr = 0\n");
114
root_entry = (struct root_entry *)map_vtd_domain_page(iommu->root_maddr);
116
printk(" root_entry = %p\n", root_entry);
117
printk(" root_entry[%x] = %"PRIx64"\n", bus, root_entry[bus].val);
118
if ( !root_present(root_entry[bus]) )
120
unmap_vtd_domain_page(root_entry);
121
printk(" root_entry[%x] not present\n", bus);
126
(struct context_entry *)map_vtd_domain_page(root_entry[bus].val);
127
if ( ctxt_entry == NULL )
129
unmap_vtd_domain_page(root_entry);
130
printk(" ctxt_entry == NULL\n");
134
printk(" context = %p\n", ctxt_entry);
135
printk(" context[%x] = %"PRIx64"_%"PRIx64"\n",
136
devfn, ctxt_entry[devfn].hi, ctxt_entry[devfn].lo);
137
if ( !context_present(ctxt_entry[devfn]) )
139
unmap_vtd_domain_page(ctxt_entry);
140
unmap_vtd_domain_page(root_entry);
141
printk(" ctxt_entry[%x] not present\n", devfn);
145
level = agaw_to_level(context_address_width(ctxt_entry[devfn]));
146
if ( level != VTD_PAGE_TABLE_LEVEL_3 &&
147
level != VTD_PAGE_TABLE_LEVEL_4)
149
unmap_vtd_domain_page(ctxt_entry);
150
unmap_vtd_domain_page(root_entry);
151
printk("Unsupported VTD page table level (%d)!\n", level);
154
l = maddr_to_virt(ctxt_entry[devfn].lo);
157
l = (u64*)(((unsigned long)l >> PAGE_SHIFT_4K) << PAGE_SHIFT_4K);
158
printk(" l%d = %p\n", level, l);
161
unmap_vtd_domain_page(ctxt_entry);
162
unmap_vtd_domain_page(root_entry);
163
printk(" l%d == NULL\n", level);
166
l_index = get_level_index(gmfn, level);
167
printk(" l%d_index = %x\n", level, l_index);
168
printk(" l%d[%x] = %"PRIx64"\n", level, l_index, l[l_index]);
170
pte.val = l[l_index];
171
if ( !dma_pte_present(pte) )
173
unmap_vtd_domain_page(ctxt_entry);
174
unmap_vtd_domain_page(root_entry);
175
printk(" l%d[%x] not present\n", level, l_index);
179
l = maddr_to_virt(l[l_index]);
183
static void dump_iommu_info(unsigned char key)
185
#if defined(__i386__) || defined(__x86_64__)
186
struct acpi_drhd_unit *drhd;
190
for_each_drhd_unit ( drhd )
195
printk("\niommu %x: nr_pt_levels = %x.\n", iommu->index,
196
iommu->nr_pt_levels);
198
if ( ecap_queued_inval(iommu->ecap) || ecap_intr_remap(iommu->ecap) )
199
status = dmar_readl(iommu->reg, DMAR_GSTS_REG);
201
printk(" Queued Invalidation: %ssupported%s.\n",
202
ecap_queued_inval(iommu->ecap) ? "" : "not ",
203
(status & DMA_GSTS_QIES) ? " and enabled" : "" );
206
printk(" Interrupt Remapping: %ssupported%s.\n",
207
ecap_intr_remap(iommu->ecap) ? "" : "not ",
208
(status & DMA_GSTS_IRES) ? " and enabled" : "" );
210
if ( status & DMA_GSTS_IRES )
212
/* Dump interrupt remapping table. */
213
u64 iremap_maddr = dmar_readq(iommu->reg, DMAR_IRTA_REG);
214
int nr_entry = 1 << ((iremap_maddr & 0xF) + 1);
215
struct iremap_entry *iremap_entries = NULL;
218
printk(" Interrupt remapping table (nr_entry=0x%x. "
219
"Only dump P=1 entries here):\n", nr_entry);
220
printk(" SVT SQ SID DST V AVL DLM TM RH DM "
222
for ( i = 0; i < nr_entry; i++ )
224
struct iremap_entry *p;
225
if ( i % (1 << IREMAP_ENTRY_ORDER) == 0 )
227
/* This entry across page boundry */
228
if ( iremap_entries )
229
unmap_vtd_domain_page(iremap_entries);
231
GET_IREMAP_ENTRY(iremap_maddr, i,
235
p = &iremap_entries[i % (1 << IREMAP_ENTRY_ORDER)];
239
printk(" %04x: %x %x %04x %08x %02x %x %x %x %x %x"
241
(u32)p->hi.svt, (u32)p->hi.sq, (u32)p->hi.sid,
242
(u32)p->lo.dst, (u32)p->lo.vector, (u32)p->lo.avail,
243
(u32)p->lo.dlm, (u32)p->lo.tm, (u32)p->lo.rh,
244
(u32)p->lo.dm, (u32)p->lo.fpd, (u32)p->lo.p);
247
if ( iremap_entries )
248
unmap_vtd_domain_page(iremap_entries);
249
if ( iommu_ir_ctrl(iommu)->iremap_num != print_cnt )
250
printk("Warning: Print %d IRTE (actually have %d)!\n",
251
print_cnt, iommu_ir_ctrl(iommu)->iremap_num);
256
/* Dump the I/O xAPIC redirection table(s). */
260
union IO_APIC_reg_01 reg_01;
261
struct IO_APIC_route_entry rte = { 0 };
262
struct IO_APIC_route_remap_entry *remap;
263
struct ir_ctrl *ir_ctrl;
265
for ( apic = 0; apic < nr_ioapics; apic++ )
267
iommu = ioapic_to_iommu(mp_ioapics[apic].mpc_apicid);
268
ir_ctrl = iommu_ir_ctrl(iommu);
269
if ( !iommu || !ir_ctrl || ir_ctrl->iremap_maddr == 0 ||
270
ir_ctrl->iremap_num == 0 )
273
printk( "\nRedirection table of IOAPIC %x:\n", apic);
275
reg = 1; /* IO xAPIC Version Register. */
276
*IO_APIC_BASE(apic) = reg;
277
reg_01.raw = *(IO_APIC_BASE(apic)+4);
279
printk(" #entry IDX FMT MASK TRIG IRR POL STAT DELI VECTOR\n");
280
for ( i = 0; i <= reg_01.bits.entries; i++ )
283
*IO_APIC_BASE(apic) = reg;
284
*(((u32 *)&rte) + 0) = *(IO_APIC_BASE(apic)+4);
286
*IO_APIC_BASE(apic) = reg + 1;
287
*(((u32 *)&rte) + 1) = *(IO_APIC_BASE(apic)+4);
289
remap = (struct IO_APIC_route_remap_entry *) &rte;
290
if ( !remap->format )
293
printk(" %02x: %04x %x %x %x %x %x %x"
295
(u32)remap->index_0_14 | ((u32)remap->index_15 << 15),
296
(u32)remap->format, (u32)remap->mask, (u32)remap->trigger,
297
(u32)remap->irr, (u32)remap->polarity,
298
(u32)remap->delivery_status, (u32)remap->delivery_mode,
304
printk("%s: not implemnted on IA64 for now.\n", __func__);
309
struct keyhandler dump_iommu_info_keyhandler = {
311
.u.fn = dump_iommu_info,
312
.desc = "dump iommu info"
320
* indent-tabs-mode: nil