Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause 2 : : * Copyright (C) 2020 Intel Corporation. 3 : : * All rights reserved. 4 : : */ 5 : : 6 : : #ifndef __IDXD_H__ 7 : : #define __IDXD_H__ 8 : : 9 : : #include "spdk/stdinc.h" 10 : : 11 : : #include "spdk/idxd.h" 12 : : #include "spdk/queue.h" 13 : : #include "spdk/mmio.h" 14 : : #include "spdk/idxd_spec.h" 15 : : 16 : : #ifdef __cplusplus 17 : : extern "C" { 18 : : #endif 19 : : 20 : : /* TODO: get the gcc intrinsic to work. */ 21 : : #define nop() asm volatile ("nop") 22 : 0 : static inline void movdir64b(void *dst, const void *src) 23 : : { 24 : 0 : asm volatile(".byte 0x66, 0x0f, 0x38, 0xf8, 0x02" 25 : : : "=m"(*(char *)dst) 26 : : : "d"(src), "a"(dst)); 27 : 0 : } 28 : : 29 : : #define IDXD_REGISTER_TIMEOUT_US 50 30 : : #define IDXD_DRAIN_TIMEOUT_US 500000 31 : : 32 : : #define WQ_MODE_DEDICATED 1 33 : : 34 : : /* TODO: consider setting the max per batch limit via RPC. */ 35 : : 36 : : #define LOG2_WQ_MAX_XFER 30 /* 2^30 = 1073741824 */ 37 : : #define WQ_PRIORITY_1 1 38 : : #define IDXD_MAX_QUEUES 64 39 : : 40 : : enum idxd_dev { 41 : : IDXD_DEV_TYPE_DSA = 0, 42 : : IDXD_DEV_TYPE_IAA = 1, 43 : : }; 44 : : 45 : : /* Each pre-allocated batch structure goes on a per channel list and 46 : : * contains the memory for both user descriptors. 47 : : */ 48 : : struct idxd_batch { 49 : : struct idxd_hw_desc *user_desc; 50 : : struct idxd_ops *user_ops; 51 : : uint64_t user_desc_addr; 52 : : uint16_t index; 53 : : uint16_t refcnt; 54 : : uint16_t size; 55 : : struct spdk_idxd_io_channel *chan; 56 : : TAILQ_ENTRY(idxd_batch) link; 57 : : }; 58 : : 59 : : struct device_config { 60 : : uint8_t config_num; 61 : : uint8_t num_groups; 62 : : uint16_t total_wqs; 63 : : uint16_t total_engines; 64 : : }; 65 : : 66 : : struct idxd_ops; 67 : : 68 : : struct spdk_idxd_io_channel { 69 : : struct spdk_idxd_device *idxd; 70 : : /* The portal is the address that we write descriptors to for submission. */ 71 : : void *portal; 72 : : uint32_t portal_offset; 73 : : 74 : : bool pasid_enabled; 75 : : 76 : : /* The currently open batch */ 77 : : struct idxd_batch *batch; 78 : : 79 : : /* 80 : : * User descriptors (those included in a batch) are managed independently from 81 : : * data descriptors and are located in the batch structure. 82 : : */ 83 : : void *desc_base; 84 : : STAILQ_HEAD(, idxd_ops) ops_pool; 85 : : /* Current list of outstanding operations to poll. */ 86 : : STAILQ_HEAD(op_head, idxd_ops) ops_outstanding; 87 : : void *ops_base; 88 : : 89 : : TAILQ_HEAD(, idxd_batch) batch_pool; 90 : : void *batch_base; 91 : : }; 92 : : 93 : : struct pci_dev_id { 94 : : int vendor_id; 95 : : int device_id; 96 : : }; 97 : : 98 : : /* 99 : : * This struct wraps the hardware completion record which is 32 bytes in 100 : : * size and must be 32 byte aligned. 101 : : */ 102 : : struct idxd_ops { 103 : : union { 104 : : struct dsa_hw_comp_record hw; 105 : : struct iaa_hw_comp_record iaa_hw; 106 : : }; 107 : : void *cb_arg; 108 : : spdk_idxd_req_cb cb_fn; 109 : : struct idxd_batch *batch; 110 : : struct idxd_hw_desc *desc; 111 : : union { 112 : : uint32_t *crc_dst; 113 : : uint32_t *output_size; 114 : : }; 115 : : struct idxd_ops *parent; 116 : : uint32_t count; 117 : : STAILQ_ENTRY(idxd_ops) link; 118 : : }; 119 : : SPDK_STATIC_ASSERT(sizeof(struct idxd_ops) == 128, "size mismatch"); 120 : : 121 : : struct spdk_idxd_impl { 122 : : const char *name; 123 : : int (*probe)(void *cb_ctx, spdk_idxd_attach_cb attach_cb, 124 : : spdk_idxd_probe_cb probe_cb); 125 : : void (*destruct)(struct spdk_idxd_device *idxd); 126 : : void (*dump_sw_error)(struct spdk_idxd_device *idxd, void *portal); 127 : : char *(*portal_get_addr)(struct spdk_idxd_device *idxd); 128 : : 129 : : STAILQ_ENTRY(spdk_idxd_impl) link; 130 : : }; 131 : : 132 : : struct spdk_idxd_device { 133 : : struct spdk_idxd_impl *impl; 134 : : void *portal; 135 : : uint32_t socket_id; 136 : : uint32_t num_channels; 137 : : uint32_t total_wq_size; 138 : : uint32_t chan_per_device; 139 : : uint16_t batch_size; 140 : : pthread_mutex_t num_channels_lock; 141 : : bool pasid_enabled; 142 : : enum idxd_dev type; 143 : : struct iaa_aecs *aecs; 144 : : uint64_t aecs_addr; 145 : : uint32_t version; 146 : : }; 147 : : 148 : : void idxd_impl_register(struct spdk_idxd_impl *impl); 149 : : 150 : : #define SPDK_IDXD_IMPL_REGISTER(name, impl) \ 151 : : static void __attribute__((constructor)) idxd_impl_register_##name(void) \ 152 : : { \ 153 : : idxd_impl_register(impl); \ 154 : : } 155 : : 156 : : #ifdef __cplusplus 157 : : } 158 : : #endif 159 : : 160 : : #endif /* __IDXD_H__ */