1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright © 2018 Intel Corporation.
5 * Authors: Gayatri Kammela <gayatri.kammela@intel.com>
6 * Sohil Mehta <sohil.mehta@intel.com>
7 * Jacob Pan <jacob.jun.pan@linux.intel.com>
10 #include <linux/debugfs.h>
11 #include <linux/dmar.h>
12 #include <linux/intel-iommu.h>
13 #include <linux/pci.h>
15 #include <asm/irq_remapping.h>
22 #define IOMMU_REGSET_ENTRY(_reg_) \
23 { DMAR_##_reg_##_REG, __stringify(_reg_) }
24 static const struct iommu_regset iommu_regs[] = {
25 IOMMU_REGSET_ENTRY(VER),
26 IOMMU_REGSET_ENTRY(CAP),
27 IOMMU_REGSET_ENTRY(ECAP),
28 IOMMU_REGSET_ENTRY(GCMD),
29 IOMMU_REGSET_ENTRY(GSTS),
30 IOMMU_REGSET_ENTRY(RTADDR),
31 IOMMU_REGSET_ENTRY(CCMD),
32 IOMMU_REGSET_ENTRY(FSTS),
33 IOMMU_REGSET_ENTRY(FECTL),
34 IOMMU_REGSET_ENTRY(FEDATA),
35 IOMMU_REGSET_ENTRY(FEADDR),
36 IOMMU_REGSET_ENTRY(FEUADDR),
37 IOMMU_REGSET_ENTRY(AFLOG),
38 IOMMU_REGSET_ENTRY(PMEN),
39 IOMMU_REGSET_ENTRY(PLMBASE),
40 IOMMU_REGSET_ENTRY(PLMLIMIT),
41 IOMMU_REGSET_ENTRY(PHMBASE),
42 IOMMU_REGSET_ENTRY(PHMLIMIT),
43 IOMMU_REGSET_ENTRY(IQH),
44 IOMMU_REGSET_ENTRY(IQT),
45 IOMMU_REGSET_ENTRY(IQA),
46 IOMMU_REGSET_ENTRY(ICS),
47 IOMMU_REGSET_ENTRY(IRTA),
48 IOMMU_REGSET_ENTRY(PQH),
49 IOMMU_REGSET_ENTRY(PQT),
50 IOMMU_REGSET_ENTRY(PQA),
51 IOMMU_REGSET_ENTRY(PRS),
52 IOMMU_REGSET_ENTRY(PECTL),
53 IOMMU_REGSET_ENTRY(PEDATA),
54 IOMMU_REGSET_ENTRY(PEADDR),
55 IOMMU_REGSET_ENTRY(PEUADDR),
56 IOMMU_REGSET_ENTRY(MTRRCAP),
57 IOMMU_REGSET_ENTRY(MTRRDEF),
58 IOMMU_REGSET_ENTRY(MTRR_FIX64K_00000),
59 IOMMU_REGSET_ENTRY(MTRR_FIX16K_80000),
60 IOMMU_REGSET_ENTRY(MTRR_FIX16K_A0000),
61 IOMMU_REGSET_ENTRY(MTRR_FIX4K_C0000),
62 IOMMU_REGSET_ENTRY(MTRR_FIX4K_C8000),
63 IOMMU_REGSET_ENTRY(MTRR_FIX4K_D0000),
64 IOMMU_REGSET_ENTRY(MTRR_FIX4K_D8000),
65 IOMMU_REGSET_ENTRY(MTRR_FIX4K_E0000),
66 IOMMU_REGSET_ENTRY(MTRR_FIX4K_E8000),
67 IOMMU_REGSET_ENTRY(MTRR_FIX4K_F0000),
68 IOMMU_REGSET_ENTRY(MTRR_FIX4K_F8000),
69 IOMMU_REGSET_ENTRY(MTRR_PHYSBASE0),
70 IOMMU_REGSET_ENTRY(MTRR_PHYSMASK0),
71 IOMMU_REGSET_ENTRY(MTRR_PHYSBASE1),
72 IOMMU_REGSET_ENTRY(MTRR_PHYSMASK1),
73 IOMMU_REGSET_ENTRY(MTRR_PHYSBASE2),
74 IOMMU_REGSET_ENTRY(MTRR_PHYSMASK2),
75 IOMMU_REGSET_ENTRY(MTRR_PHYSBASE3),
76 IOMMU_REGSET_ENTRY(MTRR_PHYSMASK3),
77 IOMMU_REGSET_ENTRY(MTRR_PHYSBASE4),
78 IOMMU_REGSET_ENTRY(MTRR_PHYSMASK4),
79 IOMMU_REGSET_ENTRY(MTRR_PHYSBASE5),
80 IOMMU_REGSET_ENTRY(MTRR_PHYSMASK5),
81 IOMMU_REGSET_ENTRY(MTRR_PHYSBASE6),
82 IOMMU_REGSET_ENTRY(MTRR_PHYSMASK6),
83 IOMMU_REGSET_ENTRY(MTRR_PHYSBASE7),
84 IOMMU_REGSET_ENTRY(MTRR_PHYSMASK7),
85 IOMMU_REGSET_ENTRY(MTRR_PHYSBASE8),
86 IOMMU_REGSET_ENTRY(MTRR_PHYSMASK8),
87 IOMMU_REGSET_ENTRY(MTRR_PHYSBASE9),
88 IOMMU_REGSET_ENTRY(MTRR_PHYSMASK9),
89 IOMMU_REGSET_ENTRY(VCCAP),
90 IOMMU_REGSET_ENTRY(VCMD),
91 IOMMU_REGSET_ENTRY(VCRSP),
94 static int iommu_regset_show(struct seq_file *m, void *unused)
96 struct dmar_drhd_unit *drhd;
97 struct intel_iommu *iommu;
103 for_each_active_iommu(iommu, drhd) {
104 if (!drhd->reg_base_addr) {
105 seq_puts(m, "IOMMU: Invalid base address\n");
110 seq_printf(m, "IOMMU: %s Register Base Address: %llx\n",
111 iommu->name, drhd->reg_base_addr);
112 seq_puts(m, "Name\t\t\tOffset\t\tContents\n");
114 * Publish the contents of the 64-bit hardware registers
115 * by adding the offset to the pointer (virtual address).
117 raw_spin_lock_irqsave(&iommu->register_lock, flag);
118 for (i = 0 ; i < ARRAY_SIZE(iommu_regs); i++) {
119 value = dmar_readq(iommu->reg + iommu_regs[i].offset);
120 seq_printf(m, "%-16s\t0x%02x\t\t0x%016llx\n",
121 iommu_regs[i].regs, iommu_regs[i].offset,
124 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
132 DEFINE_SHOW_ATTRIBUTE(iommu_regset);
134 void __init intel_iommu_debugfs_init(void)
136 struct dentry *intel_iommu_debug = debugfs_create_dir("intel",
139 debugfs_create_file("iommu_regset", 0444, intel_iommu_debug, NULL,