1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20#ifndef HW_I386_X86_IOMMU_H
21#define HW_I386_X86_IOMMU_H
22
23#include "hw/sysbus.h"
24#include "hw/pci/pci.h"
25#include "hw/pci/msi.h"
26
27#define TYPE_X86_IOMMU_DEVICE ("x86-iommu")
28#define X86_IOMMU_DEVICE(obj) \
29 OBJECT_CHECK(X86IOMMUState, (obj), TYPE_X86_IOMMU_DEVICE)
30#define X86_IOMMU_CLASS(klass) \
31 OBJECT_CLASS_CHECK(X86IOMMUClass, (klass), TYPE_X86_IOMMU_DEVICE)
32#define X86_IOMMU_GET_CLASS(obj) \
33 OBJECT_GET_CLASS(X86IOMMUClass, obj, TYPE_X86_IOMMU_DEVICE)
34
35#define X86_IOMMU_SID_INVALID (0xffff)
36
37typedef struct X86IOMMUState X86IOMMUState;
38typedef struct X86IOMMUClass X86IOMMUClass;
39typedef struct X86IOMMUIrq X86IOMMUIrq;
40typedef struct X86IOMMU_MSIMessage X86IOMMU_MSIMessage;
41
42typedef enum IommuType {
43 TYPE_INTEL,
44 TYPE_AMD,
45 TYPE_NONE
46} IommuType;
47
48struct X86IOMMUClass {
49 SysBusDeviceClass parent;
50
51 DeviceRealize realize;
52
53 int (*int_remap)(X86IOMMUState *iommu, MSIMessage *src,
54 MSIMessage *dst, uint16_t sid);
55};
56
57
58
59
60
61
62
63
64
65typedef void (*iec_notify_fn)(void *private, bool global,
66 uint32_t index, uint32_t mask);
67
68struct IEC_Notifier {
69 iec_notify_fn iec_notify;
70 void *private;
71 QLIST_ENTRY(IEC_Notifier) list;
72};
73typedef struct IEC_Notifier IEC_Notifier;
74
75struct X86IOMMUState {
76 SysBusDevice busdev;
77 OnOffAuto intr_supported;
78 bool dt_supported;
79 bool pt_supported;
80 IommuType type;
81 QLIST_HEAD(, IEC_Notifier) iec_notifiers;
82};
83
84bool x86_iommu_ir_supported(X86IOMMUState *s);
85
86
87struct X86IOMMUIrq {
88
89 uint8_t trigger_mode;
90 uint8_t vector;
91 uint8_t delivery_mode;
92 uint32_t dest;
93 uint8_t dest_mode;
94
95
96 uint8_t redir_hint;
97 uint8_t msi_addr_last_bits;
98};
99
100struct X86IOMMU_MSIMessage {
101 union {
102 struct {
103#ifdef HOST_WORDS_BIGENDIAN
104 uint32_t __addr_head:12;
105 uint32_t dest:8;
106 uint32_t __reserved:8;
107 uint32_t redir_hint:1;
108 uint32_t dest_mode:1;
109 uint32_t __not_used:2;
110#else
111 uint32_t __not_used:2;
112 uint32_t dest_mode:1;
113 uint32_t redir_hint:1;
114 uint32_t __reserved:8;
115 uint32_t dest:8;
116 uint32_t __addr_head:12;
117#endif
118 uint32_t __addr_hi;
119 } QEMU_PACKED;
120 uint64_t msi_addr;
121 };
122 union {
123 struct {
124#ifdef HOST_WORDS_BIGENDIAN
125 uint16_t trigger_mode:1;
126 uint16_t level:1;
127 uint16_t __resved:3;
128 uint16_t delivery_mode:3;
129 uint16_t vector:8;
130#else
131 uint16_t vector:8;
132 uint16_t delivery_mode:3;
133 uint16_t __resved:3;
134 uint16_t level:1;
135 uint16_t trigger_mode:1;
136#endif
137 uint16_t __resved1;
138 } QEMU_PACKED;
139 uint32_t msi_data;
140 };
141};
142
143
144
145
146
147X86IOMMUState *x86_iommu_get_default(void);
148
149
150
151
152IommuType x86_iommu_get_type(void);
153
154
155
156
157
158
159
160
161void x86_iommu_iec_register_notifier(X86IOMMUState *iommu,
162 iec_notify_fn fn, void *data);
163
164
165
166
167
168
169
170
171
172void x86_iommu_iec_notify_all(X86IOMMUState *iommu, bool global,
173 uint32_t index, uint32_t mask);
174
175
176
177
178
179
180void x86_iommu_irq_to_msi_message(X86IOMMUIrq *irq, MSIMessage *out);
181#endif
182