xref: /spdk/include/spdk/idxd_spec.h (revision ee32a82bfd3ff5b1a10ed775ee06f0eaffce60eb)
1 /*   SPDX-License-Identifier: BSD-3-Clause
2  *   Copyright (C) 2020 Intel Corporation.
3  *   All rights reserved.
4  */
5 
6 /**
7  * \file
8  * IDXD specification definitions
9  */
10 
11 #ifndef SPDK_IDXD_SPEC_H
12 #define SPDK_IDXD_SPEC_H
13 
14 #include "spdk/stdinc.h"
15 #include "spdk/assert.h"
16 
17 #ifdef __cplusplus
18 extern "C" {
19 #endif
20 
21 #define IDXD_MMIO_BAR			0
22 #define IDXD_WQ_BAR			2
23 #define PORTAL_SIZE			0x1000
24 #define WQ_TOTAL_PORTAL_SIZE		(PORTAL_SIZE * 4)
25 #define PORTAL_STRIDE			0x40
26 #define PORTAL_MASK			(PORTAL_SIZE - 1)
27 #define WQCFG_SHIFT			5
28 
29 #define IDXD_TABLE_OFFSET_MULT		0x100
30 
31 #define IDXD_CLEAR_CRC_FLAGS		0xFFFFu
32 
33 #define IDXD_FLAG_FENCE			(1 << 0)
34 #define IDXD_FLAG_COMPLETION_ADDR_VALID	(1 << 2)
35 #define IDXD_FLAG_REQUEST_COMPLETION	(1 << 3)
36 #define IDXD_FLAG_CACHE_CONTROL		(1 << 8)
37 #define IDXD_FLAG_DEST_READBACK		(1 << 14)
38 #define IDXD_FLAG_DEST_STEERING_TAG	(1 << 15)
39 #define IDXD_FLAG_CRC_READ_CRC_SEED	(1 << 16)
40 
41 #define IDXD_DSA_STATUS_DIF_ERROR	0x9
42 
43 #define IDXD_DIF_FLAG_INVERT_CRC_RESULT		(1 << 3)
44 #define IDXD_DIF_FLAG_INVERT_CRC_SEED		(1 << 2)
45 #define IDXD_DIF_FLAG_DIF_BLOCK_SIZE_512	0x0
46 #define IDXD_DIF_FLAG_DIF_BLOCK_SIZE_520	0x1
47 #define IDXD_DIF_FLAG_DIF_BLOCK_SIZE_4096	0x2
48 #define IDXD_DIF_FLAG_DIF_BLOCK_SIZE_4104	0x3
49 
50 #define IDXD_DIF_SOURCE_FLAG_SOURCE_REF_TAG_TYPE	(1 << 7)
51 #define IDXD_DIF_SOURCE_FLAG_REF_TAG_CHECK_DISABLE	(1 << 6)
52 #define IDXD_DIF_SOURCE_FLAG_GUARD_CHECK_DISABLE	(1 << 5)
53 #define IDXD_DIF_SOURCE_FLAG_SOURCE_APP_TAG_TYPE	(1 << 4)
54 #define IDXD_DIF_SOURCE_FLAG_APP_AND_REF_TAG_F_DETECT	(1 << 3)
55 #define IDXD_DIF_SOURCE_FLAG_APP_TAG_F_DETECT		(1 << 2)
56 #define IDXD_DIF_SOURCE_FLAG_ALL_F_DETECT		(1 << 1)
57 #define IDXD_DIF_SOURCE_FLAG_ENABLE_ALL_F_DETECT_ERR	(1)
58 
59 #define IAA_FLAG_RD_SRC2_AECS		(1 << 16)
60 #define IAA_COMP_FLUSH_OUTPUT		(1 << 1)
61 #define IAA_COMP_APPEND_EOB		(1 << 2)
62 #define IAA_COMP_FLAGS			(IAA_COMP_FLUSH_OUTPUT | IAA_COMP_APPEND_EOB)
63 #define IAA_DECOMP_ENABLE		(1 << 0)
64 #define IAA_DECOMP_FLUSH_OUTPUT		(1 << 1)
65 #define IAA_DECOMP_CHECK_FOR_EOB	(1 << 2)
66 #define IAA_DECOMP_STOP_ON_EOB		(1 << 3)
67 #define IAA_DECOMP_FLAGS		(IAA_DECOMP_ENABLE | \
68 					IAA_DECOMP_FLUSH_OUTPUT | \
69 					IAA_DECOMP_CHECK_FOR_EOB | \
70 					IAA_DECOMP_STOP_ON_EOB)
71 
72 /*
73  * IDXD is a family of devices, DSA and IAA.
74  */
75 enum dsa_completion_status {
76 	DSA_COMP_NONE			= 0,
77 	DSA_COMP_SUCCESS		= 1,
78 	DSA_COMP_SUCCESS_PRED		= 2,
79 	DSA_COMP_PAGE_FAULT_NOBOF	= 3,
80 	DSA_COMP_PAGE_FAULT_IR		= 4,
81 	DSA_COMP_BATCH_FAIL		= 5,
82 	DSA_COMP_BATCH_PAGE_FAULT	= 6,
83 	DSA_COMP_DR_OFFSET_NOINC	= 7,
84 	DSA_COMP_DR_OFFSET_ERANGE	= 8,
85 	DSA_COMP_DIF_ERR		= 9,
86 	DSA_COMP_BAD_OPCODE		= 16,
87 	DSA_COMP_INVALID_FLAGS		= 17,
88 	DSA_COMP_NOZERO_RESERVE		= 18,
89 	DSA_COMP_XFER_ERANGE		= 19,
90 	DSA_COMP_DESC_CNT_ERANGE	= 20,
91 	DSA_COMP_DR_ERANGE		= 21,
92 	DSA_COMP_OVERLAP_BUFFERS	= 22,
93 	DSA_COMP_DCAST_ERR		= 23,
94 	DSA_COMP_DESCLIST_ALIGN		= 24,
95 	DSA_COMP_INT_HANDLE_INVAL	= 25,
96 	DSA_COMP_CRA_XLAT		= 26,
97 	DSA_COMP_CRA_ALIGN		= 27,
98 	DSA_COMP_ADDR_ALIGN		= 28,
99 	DSA_COMP_PRIV_BAD		= 29,
100 	DSA_COMP_TRAFFIC_CLASS_CONF	= 30,
101 	DSA_COMP_PFAULT_RDBA		= 31,
102 	DSA_COMP_HW_ERR1		= 32,
103 	DSA_COMP_HW_ERR_DRB		= 33,
104 	DSA_COMP_TRANSLATION_FAIL	= 34,
105 };
106 
107 enum iaa_completion_status {
108 	IAA_COMP_NONE			= 0,
109 	IAA_COMP_SUCCESS		= 1,
110 	IAA_COMP_PAGE_FAULT_IR		= 4,
111 	IAA_COMP_OUTBUF_OVERFLOW	= 5,
112 	IAA_COMP_BAD_OPCODE		= 16,
113 	IAA_COMP_INVALID_FLAGS		= 17,
114 	IAA_COMP_NOZERO_RESERVE		= 18,
115 	IAA_COMP_INVALID_SIZE		= 19,
116 	IAA_COMP_OVERLAP_BUFFERS	= 22,
117 	IAA_COMP_INT_HANDLE_INVAL	= 25,
118 	IAA_COMP_CRA_XLAT		= 32,
119 	IAA_COMP_CRA_ALIGN		= 33,
120 	IAA_COMP_ADDR_ALIGN		= 34,
121 	IAA_COMP_PRIV_BAD		= 35,
122 	IAA_COMP_TRAFFIC_CLASS_CONF	= 36,
123 	IAA_COMP_PFAULT_RDBA		= 37,
124 	IAA_COMP_HW_ERR1		= 38,
125 	IAA_COMP_TRANSLATION_FAIL	= 39,
126 	IAA_COMP_PRS_TIMEOUT		= 40,
127 	IAA_COMP_WATCHDOG		= 41,
128 	IAA_COMP_INVALID_COMP_FLAG	= 48,
129 	IAA_COMP_INVALID_FILTER_FLAG	= 49,
130 	IAA_COMP_INVALID_NUM_ELEMS	= 50,
131 };
132 
133 enum idxd_wq_state {
134 	WQ_DISABLED	= 0,
135 	WQ_ENABLED	= 1,
136 };
137 
138 enum idxd_wq_flag {
139 	WQ_FLAG_DEDICATED	= 0,
140 	WQ_FLAG_BOF		= 1,
141 };
142 
143 enum idxd_wq_type {
144 	WQT_NONE	= 0,
145 	WQT_KERNEL	= 1,
146 	WQT_USER	= 2,
147 	WQT_MDEV	= 3,
148 };
149 
150 enum idxd_dev_state {
151 	IDXD_DEVICE_STATE_DISABLED	= 0,
152 	IDXD_DEVICE_STATE_ENABLED	= 1,
153 	IDXD_DEVICE_STATE_DRAIN		= 2,
154 	IDXD_DEVICE_STATE_HALT		= 3,
155 };
156 
157 enum idxd_device_reset_type {
158 	IDXD_DEVICE_RESET_SOFTWARE	= 0,
159 	IDXD_DEVICE_RESET_FLR		= 1,
160 	IDXD_DEVICE_RESET_WARM		= 2,
161 	IDXD_DEVICE_RESET_COLD		= 3,
162 };
163 
164 enum idxd_cmds {
165 	IDXD_ENABLE_DEV		= 1,
166 	IDXD_DISABLE_DEV	= 2,
167 	IDXD_DRAIN_ALL		= 3,
168 	IDXD_ABORT_ALL		= 4,
169 	IDXD_RESET_DEVICE	= 5,
170 	IDXD_ENABLE_WQ		= 6,
171 	IDXD_DISABLE_WQ		= 7,
172 	IDXD_DRAIN_WQ		= 8,
173 	IDXD_ABORT_WQ		= 9,
174 	IDXD_RESET_WQ		= 10,
175 };
176 
177 enum idxd_cmdsts_err {
178 	IDXD_CMDSTS_SUCCESS		= 0,
179 	IDXD_CMDSTS_INVAL_CMD		= 1,
180 	IDXD_CMDSTS_INVAL_WQIDX		= 2,
181 	IDXD_CMDSTS_HW_ERR		= 3,
182 	IDXD_CMDSTS_ERR_DEV_ENABLED	= 16,
183 	IDXD_CMDSTS_ERR_CONFIG		= 17,
184 	IDXD_CMDSTS_ERR_BUSMASTER_EN	= 18,
185 	IDXD_CMDSTS_ERR_PASID_INVAL	= 19,
186 	IDXD_CMDSTS_ERR_WQ_SIZE_ERANGE	= 20,
187 	IDXD_CMDSTS_ERR_GRP_CONFIG	= 21,
188 	IDXD_CMDSTS_ERR_GRP_CONFIG2	= 22,
189 	IDXD_CMDSTS_ERR_GRP_CONFIG3	= 23,
190 	IDXD_CMDSTS_ERR_GRP_CONFIG4	= 24,
191 	IDXD_CMDSTS_ERR_DEV_NOTEN	= 32,
192 	IDXD_CMDSTS_ERR_WQ_ENABLED	= 33,
193 	IDXD_CMDSTS_ERR_WQ_SIZE		= 34,
194 	IDXD_CMDSTS_ERR_WQ_PRIOR	= 35,
195 	IDXD_CMDSTS_ERR_WQ_MODE		= 36,
196 	IDXD_CMDSTS_ERR_BOF_EN		= 37,
197 	IDXD_CMDSTS_ERR_PASID_EN	= 38,
198 	IDXD_CMDSTS_ERR_MAX_BATCH_SIZE	= 39,
199 	IDXD_CMDSTS_ERR_MAX_XFER_SIZE	= 40,
200 	IDXD_CMDSTS_ERR_DIS_DEV_EN	= 49,
201 	IDXD_CMDSTS_ERR_DEV_NOT_EN	= 50,
202 	IDXD_CMDSTS_ERR_INVAL_INT_IDX	= 65,
203 	IDXD_CMDSTS_ERR_NO_HANDLE	= 66,
204 };
205 
206 enum idxd_wq_hw_state {
207 	IDXD_WQ_DEV_DISABLED	= 0,
208 	IDXD_WQ_DEV_ENABLED	= 1,
209 	IDXD_WQ_DEV_BUSY	= 2,
210 };
211 
212 struct idxd_hw_desc {
213 	uint32_t	pasid: 20;
214 	uint32_t	rsvd: 11;
215 	uint32_t	priv: 1;
216 	uint32_t	flags: 24;
217 	uint32_t	opcode: 8;
218 	uint64_t	completion_addr;
219 	union {
220 		uint64_t	src_addr;
221 		uint64_t	src1_addr;
222 		uint64_t	readback_addr;
223 		uint64_t	pattern;
224 		uint64_t	desc_list_addr;
225 	};
226 	union {
227 		uint64_t	dst_addr;
228 		uint64_t	readback_addr2;
229 		uint64_t	src2_addr;
230 		uint64_t	comp_pattern;
231 	};
232 	union {
233 		uint32_t	src1_size;
234 		uint32_t	xfer_size;
235 		uint32_t	desc_count;
236 	};
237 	uint16_t	int_handle;
238 	union {
239 		uint16_t	rsvd1;
240 		uint16_t	compr_flags;
241 		uint16_t	decompr_flags;
242 	};
243 	union {
244 		struct {
245 			uint64_t	src2_addr;
246 			uint32_t	max_dst_size;
247 			uint32_t	src2_size;
248 			uint32_t	filter_flags;
249 			uint32_t	num_inputs;
250 		} iaa;
251 		uint8_t		expected_res;
252 		struct {
253 			uint64_t	addr;
254 			uint32_t	max_size;
255 		} delta;
256 		uint32_t	delta_rec_size;
257 		uint64_t	dest2;
258 		struct {
259 			uint32_t	seed;
260 			uint32_t	rsvd;
261 			uint64_t	addr;
262 		} crc32c;
263 		struct {
264 			uint8_t		src_flags;
265 			uint8_t		rsvd1;
266 			uint8_t		flags;
267 			uint8_t		rsvd2[5];
268 			uint32_t	ref_tag_seed;
269 			uint16_t	app_tag_mask;
270 			uint16_t	app_tag_seed;
271 		} dif_chk;
272 		struct {
273 			uint8_t		rsvd1;
274 			uint8_t		dest_flag;
275 			uint8_t		flags;
276 			uint8_t		rsvd2[13];
277 			uint32_t	ref_tag_seed;
278 			uint16_t	app_tag_mask;
279 			uint16_t	app_tag_seed;
280 		} dif_ins;
281 		struct {
282 			uint8_t		src_flags;
283 			uint8_t		dest_flags;
284 			uint8_t		flags;
285 			uint8_t		rsvd[5];
286 			uint32_t	src_ref_tag_seed;
287 			uint16_t	src_app_tag_mask;
288 			uint16_t	src_app_tag_seed;
289 			uint32_t	dest_ref_tag_seed;
290 			uint16_t	dest_app_tag_mask;
291 			uint16_t	dest_app_tag_seed;
292 		} dif_upd;
293 		struct {
294 			uint8_t		src_flags;
295 			uint8_t		rsvd1;
296 			uint8_t		flags;
297 			uint8_t		rsvd2[5];
298 			uint32_t	ref_tag_seed;
299 			uint16_t	app_tag_mask;
300 			uint16_t	app_tag_seed;
301 		} dif_strip;
302 		struct {
303 			uint8_t		rsvd1;
304 			uint8_t		dest_flags;
305 			uint8_t		flags;
306 			uint8_t		rsvd2[13];
307 			uint32_t	ref_tag_seed;
308 			uint16_t	app_tag_mask;
309 			uint16_t	app_tag_seed;
310 		} dix_gen;
311 		uint8_t		op_specific[24];
312 	};
313 } __attribute((aligned(64)));
314 SPDK_STATIC_ASSERT(sizeof(struct idxd_hw_desc) == 64, "size mismatch");
315 
316 struct dsa_hw_comp_record {
317 	volatile uint8_t	status;
318 	union {
319 		uint8_t		result;
320 		uint8_t		dif_status;
321 	};
322 	uint16_t		rsvd;
323 	uint32_t		bytes_completed;
324 	uint64_t		fault_addr;
325 	union {
326 		uint32_t	delta_rec_size;
327 		uint32_t	crc32c_val;
328 		struct {
329 			uint32_t	dif_chk_ref_tag;
330 			uint16_t	dif_chk_app_tag_mask;
331 			uint16_t	dif_chk_app_tag;
332 		};
333 		struct {
334 			uint64_t	rsvd;
335 			uint32_t	ref_tag;
336 			uint16_t	app_tag_mask;
337 			uint16_t	app_tag;
338 		} dif_ins_comp;
339 		struct {
340 			uint32_t	src_ref_tag;
341 			uint16_t	src_app_tag_mask;
342 			uint16_t	src_app_tag;
343 			uint32_t	dest_ref_tag;
344 			uint16_t	dest_app_tag_mask;
345 			uint16_t	dest_app_tag;
346 		} dif_upd_comp;
347 		struct {
348 			uint64_t	rsvd;
349 			uint32_t	dix_gen_ref_tag;
350 			uint16_t	dix_gen_app_tag_mask;
351 			uint16_t	dix_gen_app_tag;
352 		} dix_gen_comp;
353 		uint8_t		op_specific[16];
354 	};
355 };
356 SPDK_STATIC_ASSERT(sizeof(struct dsa_hw_comp_record) == 32, "size mismatch");
357 
358 struct iaa_hw_comp_record {
359 	volatile uint8_t	status;
360 	uint8_t			error_code;
361 	uint16_t		rsvd;
362 	uint32_t		bytes_completed;
363 	uint64_t		fault_addr;
364 	uint32_t		invalid_flags;
365 	uint32_t		rsvd2;
366 	uint32_t		output_size;
367 	uint8_t			output_bits;
368 	uint8_t			rsvd3;
369 	uint16_t		rsvd4;
370 	uint64_t		rsvd5[4];
371 };
372 SPDK_STATIC_ASSERT(sizeof(struct iaa_hw_comp_record) == 64, "size mismatch");
373 
374 struct iaa_aecs {
375 	uint32_t crc;
376 	uint32_t xor_checksum;
377 	uint32_t rsvd[5];
378 	uint32_t num_output_accum_bits;
379 	uint8_t output_accum[256];
380 	uint32_t ll_sym[286];
381 	uint32_t rsvd1;
382 	uint32_t rsvd3;
383 	uint32_t d_sym[30];
384 	uint32_t pad[2];
385 };
386 SPDK_STATIC_ASSERT(sizeof(struct iaa_aecs) == 1568, "size mismatch");
387 
388 union idxd_gencap_register {
389 	struct {
390 		uint64_t block_on_fault: 1;
391 		uint64_t overlap_copy: 1;
392 		uint64_t cache_control_mem: 1;
393 		uint64_t cache_control_cache: 1;
394 		uint64_t command_cap: 1;
395 		uint64_t rsvd: 3;
396 		uint64_t dest_readback: 1;
397 		uint64_t drain_readback: 1;
398 		uint64_t rsvd2: 6;
399 		uint64_t max_xfer_shift: 5;
400 		uint64_t max_batch_shift: 4;
401 		uint64_t max_ims_mult: 6;
402 		uint64_t config_support: 1;
403 		uint64_t rsvd3: 32;
404 	};
405 	uint64_t raw;
406 };
407 SPDK_STATIC_ASSERT(sizeof(union idxd_gencap_register) == 8, "size mismatch");
408 
409 union idxd_wqcap_register {
410 	struct {
411 		uint64_t total_wq_size: 16;
412 		uint64_t num_wqs: 8;
413 		uint64_t wqcfg_size: 4;
414 		uint64_t rsvd: 20;
415 		uint64_t shared_mode: 1;
416 		uint64_t dedicated_mode: 1;
417 		uint64_t ats_support: 1;
418 		uint64_t priority: 1;
419 		uint64_t occupancy: 1;
420 		uint64_t occupancy_int: 1;
421 		uint64_t rsvd1: 10;
422 	};
423 	uint64_t raw;
424 };
425 SPDK_STATIC_ASSERT(sizeof(union idxd_wqcap_register) == 8, "size mismatch");
426 
427 union idxd_groupcap_register {
428 	struct {
429 		uint64_t num_groups: 8;
430 		uint64_t read_bufs: 8;
431 		uint64_t read_bufs_ctrl: 1;
432 		uint64_t read_bus_limit: 1;
433 		uint64_t rsvd: 46;
434 	};
435 	uint64_t raw;
436 };
437 SPDK_STATIC_ASSERT(sizeof(union idxd_groupcap_register) == 8, "size mismatch");
438 
439 union idxd_enginecap_register {
440 	struct {
441 		uint64_t num_engines: 8;
442 		uint64_t rsvd: 56;
443 	};
444 	uint64_t raw;
445 };
446 SPDK_STATIC_ASSERT(sizeof(union idxd_enginecap_register) == 8, "size mismatch");
447 
448 struct idxd_opcap_register {
449 	uint64_t raw[4];
450 };
451 SPDK_STATIC_ASSERT(sizeof(struct idxd_opcap_register) == 32, "size mismatch");
452 
453 union idxd_offsets_register {
454 	struct {
455 		uint64_t grpcfg: 16;
456 		uint64_t wqcfg: 16;
457 		uint64_t msix_perm: 16;
458 		uint64_t ims: 16;
459 		uint64_t perfmon: 16;
460 		uint64_t rsvd: 48;
461 	};
462 	uint64_t raw[2];
463 };
464 SPDK_STATIC_ASSERT(sizeof(union idxd_offsets_register) == 16, "size mismatch");
465 
466 union idxd_gencfg_register {
467 	struct {
468 		uint8_t		global_read_buf_limit;
469 		uint8_t		reserved0 : 4;
470 		uint8_t		user_mode_int_enabled : 1;
471 		uint8_t		reserved1 : 3;
472 		uint16_t	reserved2;
473 	};
474 	uint32_t raw;
475 };
476 SPDK_STATIC_ASSERT(sizeof(union idxd_gencfg_register) == 4, "size mismatch");
477 
478 union idxd_genctrl_register {
479 	struct {
480 		uint32_t	sw_err_int_enable : 1;
481 		uint32_t	halt_state_int_enable : 1;
482 		uint32_t	reserved : 30;
483 	};
484 	uint32_t raw;
485 };
486 SPDK_STATIC_ASSERT(sizeof(union idxd_genctrl_register) == 4, "size mismatch");
487 
488 union idxd_gensts_register {
489 	struct {
490 		uint32_t state: 2;
491 		uint32_t reset_type: 2;
492 		uint32_t rsvd: 28;
493 	};
494 	uint32_t raw;
495 };
496 SPDK_STATIC_ASSERT(sizeof(union idxd_gensts_register) == 4, "size mismatch");
497 
498 union idxd_intcause_register {
499 	struct {
500 		uint32_t	software_err : 1;
501 		uint32_t	command_completion : 1;
502 		uint32_t	wq_occupancy_below_limit : 1;
503 		uint32_t	perfmon_counter_overflow : 1;
504 		uint32_t	halt_state : 1;
505 		uint32_t	reserved : 26;
506 		uint32_t	int_handles_revoked : 1;
507 	};
508 	uint32_t raw;
509 };
510 SPDK_STATIC_ASSERT(sizeof(union idxd_intcause_register) == 4, "size mismatch");
511 
512 union idxd_cmd_register {
513 	struct {
514 		uint32_t	operand : 20;
515 		uint32_t	command_code : 5;
516 		uint32_t	reserved : 6;
517 		uint32_t	request_completion_interrupt : 1;
518 	};
519 	uint32_t raw;
520 };
521 SPDK_STATIC_ASSERT(sizeof(union idxd_cmd_register) == 4, "size mismatch");
522 
523 union idxd_cmdsts_register {
524 	struct {
525 		uint32_t err : 8;
526 		uint32_t result : 16;
527 		uint32_t rsvd: 7;
528 		uint32_t active: 1;
529 	};
530 	uint32_t raw;
531 };
532 SPDK_STATIC_ASSERT(sizeof(union idxd_cmdsts_register) == 4, "size mismatch");
533 
534 union idxd_cmdcap_register {
535 	struct {
536 		uint32_t	reserved0 : 1;
537 		uint32_t	enable_device : 1;
538 		uint32_t	disable_device : 1;
539 		uint32_t	drain_all : 1;
540 		uint32_t	abort_all : 1;
541 		uint32_t	reset_device : 1;
542 		uint32_t	enable_wq : 1;
543 		uint32_t	disable_wq : 1;
544 		uint32_t	drain_wq : 1;
545 		uint32_t	abort_wq : 1;
546 		uint32_t	reset_wq : 1;
547 		uint32_t	drain_pasid : 1;
548 		uint32_t	abort_pasid : 1;
549 		uint32_t	request_int_handle : 1;
550 		uint32_t	release_int_handle : 1;
551 		uint32_t	reserved1 : 17;
552 	};
553 	uint32_t raw;
554 };
555 SPDK_STATIC_ASSERT(sizeof(union idxd_cmdcap_register) == 4, "size mismatch");
556 
557 union idxd_swerr_register {
558 	struct {
559 		uint64_t valid: 1;
560 		uint64_t overflow: 1;
561 		uint64_t desc_valid: 1;
562 		uint64_t wq_idx_valid: 1;
563 		uint64_t batch: 1;
564 		uint64_t fault_rw: 1;
565 		uint64_t priv: 1;
566 		uint64_t rsvd: 1;
567 		uint64_t error: 8;
568 		uint64_t wq_idx: 8;
569 		uint64_t rsvd2: 8;
570 		uint64_t operation: 8;
571 		uint64_t pasid: 20;
572 		uint64_t rsvd3: 4;
573 		uint64_t batch_idx: 16;
574 		uint64_t rsvd4: 16;
575 		uint64_t invalid_flags: 32;
576 		uint64_t fault_addr;
577 		uint64_t rsvd5;
578 	};
579 	uint64_t raw[4];
580 };
581 SPDK_STATIC_ASSERT(sizeof(union idxd_swerr_register) == 32, "size mismatch");
582 
583 struct idxd_registers {
584 	uint32_t			version;
585 	uint32_t			reserved0;
586 	uint64_t			reserved1;
587 	union idxd_gencap_register	gencap;
588 	uint64_t			reserved2;
589 	union idxd_wqcap_register	wqcap;
590 	uint64_t			reserved3;
591 	union idxd_groupcap_register	groupcap;
592 	union idxd_enginecap_register	enginecap;
593 	struct idxd_opcap_register	opcap;
594 	union idxd_offsets_register	offsets;
595 	uint64_t			reserved4[2];
596 	union idxd_gencfg_register	gencfg;
597 	uint32_t			reserved5;
598 	union idxd_genctrl_register	genctrl;
599 	uint32_t			reserved6;
600 	union idxd_gensts_register	gensts;
601 	uint32_t			reserved7;
602 	union idxd_intcause_register	intcause;
603 	uint32_t			reserved8;
604 	union idxd_cmd_register		cmd;
605 	uint32_t			reserved9;
606 	union idxd_cmdsts_register	cmdsts;
607 	uint32_t			reserved10;
608 	union idxd_cmdcap_register	cmdcap;
609 	uint32_t			reserved11;
610 	uint64_t			reserved12;
611 	union idxd_swerr_register	sw_err;
612 };
613 SPDK_STATIC_ASSERT(sizeof(struct idxd_registers) == 0xE0, "size mismatch");
614 
615 union idxd_group_flags {
616 	struct {
617 		uint32_t tc_a : 3;
618 		uint32_t tc_b : 3;
619 		uint32_t reserved0 : 1;
620 		uint32_t global_read_buffer_limit: 1;
621 		uint32_t read_buffers_reserved : 8;
622 		uint32_t reserved1: 4;
623 		uint32_t read_buffers_allowed : 8;
624 		uint32_t reserved2 : 4;
625 	};
626 	uint32_t raw;
627 };
628 SPDK_STATIC_ASSERT(sizeof(union idxd_group_flags) == 4, "size mismatch");
629 
630 struct idxd_grpcfg {
631 	uint64_t wqs[4];
632 	uint64_t engines;
633 	union idxd_group_flags flags;
634 
635 	/* This is not part of the definition, but in practice the stride in the table
636 	 * is 64 bytes. */
637 	uint32_t reserved0;
638 	uint64_t reserved1[2];
639 };
640 SPDK_STATIC_ASSERT(sizeof(struct idxd_grpcfg) == 64, "size mismatch");
641 
642 struct idxd_grptbl {
643 	struct idxd_grpcfg group[1];
644 };
645 
646 union idxd_wqcfg {
647 	struct {
648 		uint16_t wq_size;
649 		uint16_t rsvd;
650 		uint16_t wq_thresh;
651 		uint16_t rsvd1;
652 		uint32_t mode: 1;
653 		uint32_t bof: 1;
654 		uint32_t wq_ats_disable: 1;
655 		uint32_t rsvd2: 1;
656 		uint32_t priority: 4;
657 		uint32_t pasid: 20;
658 		uint32_t pasid_en: 1;
659 		uint32_t priv: 1;
660 		uint32_t rsvd3: 2;
661 		uint32_t max_xfer_shift: 5;
662 		uint32_t max_batch_shift: 4;
663 		uint32_t rsvd4: 23;
664 		uint16_t occupancy_inth;
665 		uint16_t occupancy_table_sel: 1;
666 		uint16_t rsvd5: 15;
667 		uint16_t occupancy_limit;
668 		uint16_t occupancy_int_en: 1;
669 		uint16_t rsvd6: 15;
670 		uint16_t occupancy;
671 		uint16_t occupancy_int: 1;
672 		uint16_t rsvd7: 12;
673 		uint16_t mode_support: 1;
674 		uint16_t wq_state: 2;
675 		uint32_t rsvd8;
676 	};
677 	uint32_t raw[8];
678 };
679 SPDK_STATIC_ASSERT(sizeof(union idxd_wqcfg) == 32, "size mismatch");
680 
681 #ifdef __cplusplus
682 }
683 #endif
684 
685 #endif /* SPDK_IDXD_SPEC_H */
686