1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright (C) 2015 Intel Corporation. 3 * All rights reserved. 4 */ 5 6 /** 7 * \file 8 * I/OAT specification definitions 9 */ 10 11 #ifndef SPDK_IOAT_SPEC_H 12 #define SPDK_IOAT_SPEC_H 13 14 #include "spdk/stdinc.h" 15 16 #ifdef __cplusplus 17 extern "C" { 18 #endif 19 20 #include "spdk/assert.h" 21 22 #define SPDK_IOAT_PCI_CHANERR_INT_OFFSET 0x180 23 24 #define SPDK_IOAT_INTRCTRL_MASTER_INT_EN 0x01 25 26 #define SPDK_IOAT_VER_3_0 0x30 27 #define SPDK_IOAT_VER_3_3 0x33 28 29 /* DMA Channel Registers */ 30 #define SPDK_IOAT_CHANCTRL_CHANNEL_PRIORITY_MASK 0xF000 31 #define SPDK_IOAT_CHANCTRL_COMPL_DCA_EN 0x0200 32 #define SPDK_IOAT_CHANCTRL_CHANNEL_IN_USE 0x0100 33 #define SPDK_IOAT_CHANCTRL_DESCRIPTOR_ADDR_SNOOP_CONTROL 0x0020 34 #define SPDK_IOAT_CHANCTRL_ERR_INT_EN 0x0010 35 #define SPDK_IOAT_CHANCTRL_ANY_ERR_ABORT_EN 0x0008 36 #define SPDK_IOAT_CHANCTRL_ERR_COMPLETION_EN 0x0004 37 #define SPDK_IOAT_CHANCTRL_INT_REARM 0x0001 38 39 /* DMA Channel Capabilities */ 40 #define SPDK_IOAT_DMACAP_PB (1 << 0) 41 #define SPDK_IOAT_DMACAP_DCA (1 << 4) 42 #define SPDK_IOAT_DMACAP_BFILL (1 << 6) 43 #define SPDK_IOAT_DMACAP_XOR (1 << 8) 44 #define SPDK_IOAT_DMACAP_PQ (1 << 9) 45 #define SPDK_IOAT_DMACAP_DMA_DIF (1 << 10) 46 47 struct spdk_ioat_registers { 48 uint8_t chancnt; 49 uint8_t xfercap; 50 uint8_t genctrl; 51 uint8_t intrctrl; 52 uint32_t attnstatus; 53 uint8_t cbver; /* 0x08 */ 54 uint8_t reserved4[0x3]; /* 0x09 */ 55 uint16_t intrdelay; /* 0x0C */ 56 uint16_t cs_status; /* 0x0E */ 57 uint32_t dmacapability; /* 0x10 */ 58 uint8_t reserved5[0x6C]; /* 0x14 */ 59 uint16_t chanctrl; /* 0x80 */ 60 uint8_t reserved6[0x2]; /* 0x82 */ 61 uint8_t chancmd; /* 0x84 */ 62 uint8_t reserved3[1]; /* 0x85 */ 63 uint16_t dmacount; /* 0x86 */ 64 uint64_t chansts; /* 0x88 */ 65 uint64_t chainaddr; /* 0x90 */ 66 uint64_t chancmp; /* 0x98 */ 67 uint8_t reserved2[0x8]; /* 0xA0 */ 68 uint32_t chanerr; /* 0xA8 */ 69 uint32_t chanerrmask; /* 0xAC */ 70 } __attribute__((packed)) __attribute__((aligned)); 71 72 #define SPDK_IOAT_CHANCMD_RESET 0x20 73 #define SPDK_IOAT_CHANCMD_SUSPEND 0x04 74 75 #define SPDK_IOAT_CHANSTS_STATUS 0x7ULL 76 #define SPDK_IOAT_CHANSTS_ACTIVE 0x0 77 #define SPDK_IOAT_CHANSTS_IDLE 0x1 78 #define SPDK_IOAT_CHANSTS_SUSPENDED 0x2 79 #define SPDK_IOAT_CHANSTS_HALTED 0x3 80 #define SPDK_IOAT_CHANSTS_ARMED 0x4 81 82 #define SPDK_IOAT_CHANSTS_UNAFFILIATED_ERROR 0x8ULL 83 #define SPDK_IOAT_CHANSTS_SOFT_ERROR 0x10ULL 84 85 #define SPDK_IOAT_CHANSTS_COMPLETED_DESCRIPTOR_MASK (~0x3FULL) 86 87 #define SPDK_IOAT_CHANCMP_ALIGN 8 /* CHANCMP address must be 64-bit aligned */ 88 89 struct spdk_ioat_generic_hw_desc { 90 uint32_t size; 91 union { 92 uint32_t control_raw; 93 struct { 94 uint32_t int_enable: 1; 95 uint32_t src_snoop_disable: 1; 96 uint32_t dest_snoop_disable: 1; 97 uint32_t completion_update: 1; 98 uint32_t fence: 1; 99 uint32_t reserved2: 1; 100 uint32_t src_page_break: 1; 101 uint32_t dest_page_break: 1; 102 uint32_t bundle: 1; 103 uint32_t dest_dca: 1; 104 uint32_t hint: 1; 105 uint32_t reserved: 13; 106 uint32_t op: 8; 107 } control; 108 } u; 109 uint64_t src_addr; 110 uint64_t dest_addr; 111 uint64_t next; 112 uint64_t op_specific[4]; 113 }; 114 115 struct spdk_ioat_dma_hw_desc { 116 uint32_t size; 117 union { 118 uint32_t control_raw; 119 struct { 120 uint32_t int_enable: 1; 121 uint32_t src_snoop_disable: 1; 122 uint32_t dest_snoop_disable: 1; 123 uint32_t completion_update: 1; 124 uint32_t fence: 1; 125 uint32_t null: 1; 126 uint32_t src_page_break: 1; 127 uint32_t dest_page_break: 1; 128 uint32_t bundle: 1; 129 uint32_t dest_dca: 1; 130 uint32_t hint: 1; 131 uint32_t reserved: 13; 132 #define SPDK_IOAT_OP_COPY 0x00 133 uint32_t op: 8; 134 } control; 135 } u; 136 uint64_t src_addr; 137 uint64_t dest_addr; 138 uint64_t next; 139 uint64_t reserved; 140 uint64_t reserved2; 141 uint64_t user1; 142 uint64_t user2; 143 }; 144 145 struct spdk_ioat_fill_hw_desc { 146 uint32_t size; 147 union { 148 uint32_t control_raw; 149 struct { 150 uint32_t int_enable: 1; 151 uint32_t reserved: 1; 152 uint32_t dest_snoop_disable: 1; 153 uint32_t completion_update: 1; 154 uint32_t fence: 1; 155 uint32_t reserved2: 2; 156 uint32_t dest_page_break: 1; 157 uint32_t bundle: 1; 158 uint32_t reserved3: 15; 159 #define SPDK_IOAT_OP_FILL 0x01 160 uint32_t op: 8; 161 } control; 162 } u; 163 uint64_t src_data; 164 uint64_t dest_addr; 165 uint64_t next; 166 uint64_t reserved; 167 uint64_t next_dest_addr; 168 uint64_t user1; 169 uint64_t user2; 170 }; 171 172 struct spdk_ioat_xor_hw_desc { 173 uint32_t size; 174 union { 175 uint32_t control_raw; 176 struct { 177 uint32_t int_enable: 1; 178 uint32_t src_snoop_disable: 1; 179 uint32_t dest_snoop_disable: 1; 180 uint32_t completion_update: 1; 181 uint32_t fence: 1; 182 uint32_t src_count: 3; 183 uint32_t bundle: 1; 184 uint32_t dest_dca: 1; 185 uint32_t hint: 1; 186 uint32_t reserved: 13; 187 #define SPDK_IOAT_OP_XOR 0x87 188 #define SPDK_IOAT_OP_XOR_VAL 0x88 189 uint32_t op: 8; 190 } control; 191 } u; 192 uint64_t src_addr; 193 uint64_t dest_addr; 194 uint64_t next; 195 uint64_t src_addr2; 196 uint64_t src_addr3; 197 uint64_t src_addr4; 198 uint64_t src_addr5; 199 }; 200 201 struct spdk_ioat_xor_ext_hw_desc { 202 uint64_t src_addr6; 203 uint64_t src_addr7; 204 uint64_t src_addr8; 205 uint64_t next; 206 uint64_t reserved[4]; 207 }; 208 209 struct spdk_ioat_pq_hw_desc { 210 uint32_t size; 211 union { 212 uint32_t control_raw; 213 struct { 214 uint32_t int_enable: 1; 215 uint32_t src_snoop_disable: 1; 216 uint32_t dest_snoop_disable: 1; 217 uint32_t completion_update: 1; 218 uint32_t fence: 1; 219 uint32_t src_count: 3; 220 uint32_t bundle: 1; 221 uint32_t dest_dca: 1; 222 uint32_t hint: 1; 223 uint32_t p_disable: 1; 224 uint32_t q_disable: 1; 225 uint32_t reserved: 11; 226 #define SPDK_IOAT_OP_PQ 0x89 227 #define SPDK_IOAT_OP_PQ_VAL 0x8a 228 uint32_t op: 8; 229 } control; 230 } u; 231 uint64_t src_addr; 232 uint64_t p_addr; 233 uint64_t next; 234 uint64_t src_addr2; 235 uint64_t src_addr3; 236 uint8_t coef[8]; 237 uint64_t q_addr; 238 }; 239 240 struct spdk_ioat_pq_ext_hw_desc { 241 uint64_t src_addr4; 242 uint64_t src_addr5; 243 uint64_t src_addr6; 244 uint64_t next; 245 uint64_t src_addr7; 246 uint64_t src_addr8; 247 uint64_t reserved[2]; 248 }; 249 250 struct spdk_ioat_pq_update_hw_desc { 251 uint32_t size; 252 union { 253 uint32_t control_raw; 254 struct { 255 uint32_t int_enable: 1; 256 uint32_t src_snoop_disable: 1; 257 uint32_t dest_snoop_disable: 1; 258 uint32_t completion_update: 1; 259 uint32_t fence: 1; 260 uint32_t src_cnt: 3; 261 uint32_t bundle: 1; 262 uint32_t dest_dca: 1; 263 uint32_t hint: 1; 264 uint32_t p_disable: 1; 265 uint32_t q_disable: 1; 266 uint32_t reserved: 3; 267 uint32_t coef: 8; 268 #define SPDK_IOAT_OP_PQ_UP 0x8b 269 uint32_t op: 8; 270 } control; 271 } u; 272 uint64_t src_addr; 273 uint64_t p_addr; 274 uint64_t next; 275 uint64_t src_addr2; 276 uint64_t p_src; 277 uint64_t q_src; 278 uint64_t q_addr; 279 }; 280 281 struct spdk_ioat_raw_hw_desc { 282 uint64_t field[8]; 283 }; 284 285 union spdk_ioat_hw_desc { 286 struct spdk_ioat_raw_hw_desc raw; 287 struct spdk_ioat_generic_hw_desc generic; 288 struct spdk_ioat_dma_hw_desc dma; 289 struct spdk_ioat_fill_hw_desc fill; 290 struct spdk_ioat_xor_hw_desc xor_desc; 291 struct spdk_ioat_xor_ext_hw_desc xor_ext; 292 struct spdk_ioat_pq_hw_desc pq; 293 struct spdk_ioat_pq_ext_hw_desc pq_ext; 294 struct spdk_ioat_pq_update_hw_desc pq_update; 295 }; 296 SPDK_STATIC_ASSERT(sizeof(union spdk_ioat_hw_desc) == 64, "incorrect spdk_ioat_hw_desc layout"); 297 298 #ifdef __cplusplus 299 } 300 #endif 301 302 #endif /* SPDK_IOAT_SPEC_H */ 303