1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20#ifndef IOMMU_COMMON_H
21#define IOMMU_COMMON_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 bool intr_supported;
78 bool dt_supported;
79 bool pt_supported;
80 IommuType type;
81 QLIST_HEAD(, IEC_Notifier) iec_notifiers;
82};
83
84
85struct X86IOMMUIrq {
86
87 uint8_t trigger_mode;
88 uint8_t vector;
89 uint8_t delivery_mode;
90 uint32_t dest;
91 uint8_t dest_mode;
92
93
94 uint8_t redir_hint;
95 uint8_t msi_addr_last_bits;
96};
97
98struct X86IOMMU_MSIMessage {
99 union {
100 struct {
101#ifdef HOST_WORDS_BIGENDIAN
102 uint32_t __addr_head:12;
103 uint32_t dest:8;
104 uint32_t __reserved:8;
105 uint32_t redir_hint:1;
106 uint32_t dest_mode:1;
107 uint32_t __not_used:2;
108#else
109 uint32_t __not_used:2;
110 uint32_t dest_mode:1;
111 uint32_t redir_hint:1;
112 uint32_t __reserved:8;
113 uint32_t dest:8;
114 uint32_t __addr_head:12;
115#endif
116 uint32_t __addr_hi;
117 } QEMU_PACKED;
118 uint64_t msi_addr;
119 };
120 union {
121 struct {
122#ifdef HOST_WORDS_BIGENDIAN
123 uint16_t trigger_mode:1;
124 uint16_t level:1;
125 uint16_t __resved:3;
126 uint16_t delivery_mode:3;
127 uint16_t vector:8;
128#else
129 uint16_t vector:8;
130 uint16_t delivery_mode:3;
131 uint16_t __resved:3;
132 uint16_t level:1;
133 uint16_t trigger_mode:1;
134#endif
135 uint16_t __resved1;
136 } QEMU_PACKED;
137 uint32_t msi_data;
138 };
139};
140
141
142
143
144
145X86IOMMUState *x86_iommu_get_default(void);
146
147
148
149
150IommuType x86_iommu_get_type(void);
151
152
153
154
155
156
157
158
159void x86_iommu_iec_register_notifier(X86IOMMUState *iommu,
160 iec_notify_fn fn, void *data);
161
162
163
164
165
166
167
168
169
170void x86_iommu_iec_notify_all(X86IOMMUState *iommu, bool global,
171 uint32_t index, uint32_t mask);
172
173
174
175
176
177
178void x86_iommu_irq_to_msi_message(X86IOMMUIrq *irq, MSIMessage *out);
179#endif
180