master
h 269 lines 7.41 KB
Raw
1 /*
2 * QEMU CXL Events
3 *
4 * Copyright (c) 2022 Intel
5 *
6 * This work is licensed under the terms of the GNU GPL, version 2. See the
7 * COPYING file in the top-level directory.
8 */
9
10 #ifndef CXL_EVENTS_H
11 #define CXL_EVENTS_H
12
13 #include "qemu/uuid.h"
14
15 /*
16 * CXL r3.1 section 8.2.9.2.2: Get Event Records (Opcode 0100h); Table 8-52
17 *
18 * Define these as the bit position for the event status register for ease of
19 * setting the status.
20 */
21 typedef enum CXLEventLogType {
22 CXL_EVENT_TYPE_INFO = 0,
23 CXL_EVENT_TYPE_WARN = 1,
24 CXL_EVENT_TYPE_FAIL = 2,
25 CXL_EVENT_TYPE_FATAL = 3,
26 CXL_EVENT_TYPE_DYNAMIC_CAP = 4,
27 CXL_EVENT_TYPE_MAX
28 } CXLEventLogType;
29
30 /*
31 * Common Event Record Format
32 * CXL r3.2 section 8.2.10.2.1: Event Records; Table 8-55
33 */
34 #define CXL_EVENT_REC_FLAGS_PERMANENT_COND BIT(2)
35 #define CXL_EVENT_REC_FLAGS_MAINT_NEEDED BIT(3)
36 #define CXL_EVENT_REC_FLAGS_PERF_DEGRADED BIT(4)
37 #define CXL_EVENT_REC_FLAGS_HW_REPLACEMENT_NEEDED BIT(5)
38 #define CXL_EVENT_REC_FLAGS_MAINT_OP_SUBCLASS_VALID BIT(6)
39 #define CXL_EVENT_REC_FLAGS_LD_ID_VALID BIT(7)
40 #define CXL_EVENT_REC_FLAGS_HEAD_ID_VALID BIT(8)
41 typedef struct CXLEventRecordHdr {
42 QemuUUID id;
43 uint8_t length;
44 uint8_t flags[3];
45 uint16_t handle;
46 uint16_t related_handle;
47 uint64_t timestamp;
48 uint8_t maint_op_class;
49 uint8_t maint_op_subclass;
50 uint16_t ld_id;
51 uint8_t head_id;
52 uint8_t reserved[0xb];
53 } QEMU_PACKED CXLEventRecordHdr;
54
55 #define CXL_EVENT_RECORD_DATA_LENGTH 0x50
56 typedef struct CXLEventRecordRaw {
57 CXLEventRecordHdr hdr;
58 uint8_t data[CXL_EVENT_RECORD_DATA_LENGTH];
59 } QEMU_PACKED CXLEventRecordRaw;
60 #define CXL_EVENT_RECORD_SIZE (sizeof(CXLEventRecordRaw))
61
62 /*
63 * Get Event Records output payload
64 * CXL r3.1 section 8.2.9.2.2; Table 8-53
65 */
66 #define CXL_GET_EVENT_FLAG_OVERFLOW BIT(0)
67 #define CXL_GET_EVENT_FLAG_MORE_RECORDS BIT(1)
68 typedef struct CXLGetEventPayload {
69 uint8_t flags;
70 uint8_t reserved1;
71 uint16_t overflow_err_count;
72 uint64_t first_overflow_timestamp;
73 uint64_t last_overflow_timestamp;
74 uint16_t record_count;
75 uint8_t reserved2[0xa];
76 CXLEventRecordRaw records[];
77 } QEMU_PACKED CXLGetEventPayload;
78 #define CXL_EVENT_PAYLOAD_HDR_SIZE (sizeof(CXLGetEventPayload))
79
80 /*
81 * Clear Event Records input payload
82 * CXL r3.1 section 8.2.9.2.3; Table 8-54
83 */
84 typedef struct CXLClearEventPayload {
85 uint8_t event_log; /* CXLEventLogType */
86 uint8_t clear_flags;
87 uint8_t nr_recs;
88 uint8_t reserved[3];
89 uint16_t handle[];
90 } CXLClearEventPayload;
91
92 /*
93 * Event Interrupt Policy
94 *
95 * CXL r3.1 section 8.2.9.2.4; Table 8-55
96 */
97 typedef enum CXLEventIntMode {
98 CXL_INT_NONE = 0x00,
99 CXL_INT_MSI_MSIX = 0x01,
100 CXL_INT_FW = 0x02,
101 CXL_INT_RES = 0x03,
102 } CXLEventIntMode;
103 #define CXL_EVENT_INT_MODE_MASK 0x3
104 #define CXL_EVENT_INT_SETTING(vector) \
105 ((((uint8_t)vector & 0xf) << 4) | CXL_INT_MSI_MSIX)
106 typedef struct CXLEventInterruptPolicy {
107 uint8_t info_settings;
108 uint8_t warn_settings;
109 uint8_t failure_settings;
110 uint8_t fatal_settings;
111 uint8_t dyn_cap_settings;
112 } QEMU_PACKED CXLEventInterruptPolicy;
113 /* DCD is optional but other fields are not */
114 #define CXL_EVENT_INT_SETTING_MIN_LEN 4
115
116 /*
117 * General Media Event Record
118 * CXL r3.2 Section 8.2.10.2.1.1; Table 8-57
119 */
120 #define CXL_EVENT_GEN_MED_COMP_ID_SIZE 0x10
121 #define CXL_EVENT_GEN_MED_RES_SIZE 0x29
122 typedef struct CXLEventGenMedia {
123 CXLEventRecordHdr hdr;
124 uint64_t phys_addr;
125 uint8_t descriptor;
126 uint8_t type;
127 uint8_t transaction_type;
128 uint16_t validity_flags;
129 uint8_t channel;
130 uint8_t rank;
131 uint8_t device[3];
132 uint8_t component_id[CXL_EVENT_GEN_MED_COMP_ID_SIZE];
133 uint8_t cme_ev_flags;
134 uint8_t cme_count[3];
135 uint8_t sub_type;
136 uint8_t reserved[CXL_EVENT_GEN_MED_RES_SIZE];
137 } QEMU_PACKED CXLEventGenMedia;
138
139 /*
140 * DRAM Event Record
141 * CXL r3.2 Section 8.2.10.2.1.2: Table 8-58
142 * All fields little endian.
143 */
144 typedef struct CXLEventDram {
145 CXLEventRecordHdr hdr;
146 uint64_t phys_addr;
147 uint8_t descriptor;
148 uint8_t type;
149 uint8_t transaction_type;
150 uint16_t validity_flags;
151 uint8_t channel;
152 uint8_t rank;
153 uint8_t nibble_mask[3];
154 uint8_t bank_group;
155 uint8_t bank;
156 uint8_t row[3];
157 uint16_t column;
158 uint64_t correction_mask[4];
159 uint8_t component_id[CXL_EVENT_GEN_MED_COMP_ID_SIZE];
160 uint8_t sub_channel;
161 uint8_t cme_ev_flags;
162 uint8_t cvme_count[3];
163 uint8_t sub_type;
164 uint8_t reserved;
165 } QEMU_PACKED CXLEventDram;
166
167 /*
168 * Memory Module Event Record
169 * CXL r3.2 Section 8.2.10.2.1.3: Table 8-59
170 * All fields little endian.
171 */
172 typedef struct CXLEventMemoryModule {
173 CXLEventRecordHdr hdr;
174 uint8_t type;
175 uint8_t health_status;
176 uint8_t media_status;
177 uint8_t additional_status;
178 uint8_t life_used;
179 int16_t temperature;
180 uint32_t dirty_shutdown_count;
181 uint32_t corrected_volatile_error_count;
182 uint32_t corrected_persistent_error_count;
183 uint16_t validity_flags;
184 uint8_t component_id[CXL_EVENT_GEN_MED_COMP_ID_SIZE];
185 uint8_t sub_type;
186 uint8_t reserved[0x2a];
187 } QEMU_PACKED CXLEventMemoryModule;
188
189 /*
190 * CXL r3.1 section Table 8-50: Dynamic Capacity Event Record
191 * All fields little endian.
192 */
193 typedef struct CXLEventDynamicCapacity {
194 CXLEventRecordHdr hdr;
195 uint8_t type;
196 uint8_t validity_flags;
197 uint16_t host_id;
198 uint8_t updated_region_id;
199 uint8_t flags;
200 uint8_t reserved2[2];
201 uint8_t dynamic_capacity_extent[0x28]; /* defined in cxl_device.h */
202 uint8_t reserved[0x18];
203 uint32_t extents_avail;
204 uint32_t tags_avail;
205 } QEMU_PACKED CXLEventDynamicCapacity;
206
207 /* CXL r3.1 Table 8-50: Dynamic Capacity Event Record */
208 static const QemuUUID dynamic_capacity_uuid = {
209 .data = UUID(0xca95afa7, 0xf183, 0x4018, 0x8c, 0x2f,
210 0x95, 0x26, 0x8e, 0x10, 0x1a, 0x2a),
211 };
212
213 typedef enum CXLDCEventType {
214 DC_EVENT_ADD_CAPACITY = 0x0,
215 DC_EVENT_RELEASE_CAPACITY = 0x1,
216 DC_EVENT_FORCED_RELEASE_CAPACITY = 0x2,
217 DC_EVENT_REGION_CONFIG_UPDATED = 0x3,
218 DC_EVENT_ADD_CAPACITY_RSP = 0x4,
219 DC_EVENT_CAPACITY_RELEASED = 0x5,
220 } CXLDCEventType;
221
222 /*
223 * CXL r3.2 section Table 8-60: Memory Sparing Event Record
224 * All fields little endian.
225 */
226
227 #define CXL_MSER_FLAGS_QUERY_RESOURCES BIT(0)
228 #define CXL_MSER_FLAGS_HARD_SPARING BIT(1)
229 #define CXL_MSER_FLAGS_DEV_INITIATED BIT(2)
230
231 #define CXL_MSER_VALID_CHANNEL BIT(0)
232 #define CXL_MSER_VALID_RANK BIT(1)
233 #define CXL_MSER_VALID_NIB_MASK BIT(2)
234 #define CXL_MSER_VALID_BANK_GROUP BIT(3)
235 #define CXL_MSER_VALID_BANK BIT(4)
236 #define CXL_MSER_VALID_ROW BIT(5)
237 #define CXL_MSER_VALID_COLUMN BIT(6)
238 #define CXL_MSER_VALID_COMP_ID BIT(7)
239 #define CXL_MSER_VALID_COMP_ID_FORMAT BIT(8)
240 #define CXL_MSER_VALID_SUB_CHANNEL BIT(9)
241
242 typedef struct CXLEventSparing {
243 CXLEventRecordHdr hdr;
244 uint8_t maint_op_class;
245 uint8_t maint_op_subclass;
246 uint8_t flags;
247 uint8_t result;
248 uint16_t validity_flags;
249 uint8_t reserved1[6];
250 uint16_t res_avail;
251 uint8_t channel;
252 uint8_t rank;
253 uint8_t nibble_mask[3];
254 uint8_t bank_group;
255 uint8_t bank;
256 uint8_t row[3];
257 uint16_t column;
258 uint8_t component_id[CXL_EVENT_GEN_MED_COMP_ID_SIZE];
259 uint8_t sub_channel;
260 uint8_t reserved2[0x25];
261 } QEMU_PACKED CXLEventSparing;
262
263 /* CXL r3.2 Table 8-60: Memory Sparing Event Record */
264 static const QemuUUID sparing_uuid = {
265 .data = UUID(0xe71f3a40, 0x2d29, 0x4092, 0x8a, 0x39,
266 0x4d, 0x1c, 0x96, 0x6c, 0x7c, 0x65),
267 };
268
269 #endif /* CXL_EVENTS_H */