1 /* 2 * QEMU CXL Devices 3 * 4 * Copyright (c) 2020 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_DEVICE_H 11 #define CXL_DEVICE_H 12 13 #include "hw/cxl/cxl_component.h" 14 #include "hw/pci/pci_device.h" 15 #include "hw/register.h" 16 #include "hw/cxl/cxl_events.h" 17 18 /* 19 * The following is how a CXL device's Memory Device registers are laid out. 20 * The only requirement from the spec is that the capabilities array and the 21 * capability headers start at offset 0 and are contiguously packed. The headers 22 * themselves provide offsets to the register fields. For this emulation, the 23 * actual registers * will start at offset 0x80 (m == 0x80). No secondary 24 * mailbox is implemented which means that the offset of the start of the 25 * mailbox payload (n) is given by 26 * n = m + sizeof(mailbox registers) + sizeof(device registers). 27 * 28 * +---------------------------------+ 29 * | | 30 * | Memory Device Registers | 31 * | | 32 * n + PAYLOAD_SIZE_MAX ----------------------------------- 33 * ^ | | 34 * | | | 35 * | | | 36 * | | | 37 * | | | 38 * | | Mailbox Payload | 39 * | | | 40 * | | | 41 * | | | 42 * n ----------------------------------- 43 * ^ | Mailbox Registers | 44 * | | | 45 * | ----------------------------------- 46 * | | | 47 * | | Device Registers | 48 * | | | 49 * m ----------------------------------> 50 * ^ | Memory Device Capability Header| 51 * | ----------------------------------- 52 * | | Mailbox Capability Header | 53 * | ----------------------------------- 54 * | | Device Capability Header | 55 * | ----------------------------------- 56 * | | Device Cap Array Register | 57 * 0 +---------------------------------+ 58 * 59 */ 60 61 #define CXL_DEVICE_CAP_HDR1_OFFSET 0x10 /* Figure 138 */ 62 #define CXL_DEVICE_CAP_REG_SIZE 0x10 /* 8.2.8.2 */ 63 #define CXL_DEVICE_CAPS_MAX 4 /* 8.2.8.2.1 + 8.2.8.5 */ 64 #define CXL_CAPS_SIZE \ 65 (CXL_DEVICE_CAP_REG_SIZE * (CXL_DEVICE_CAPS_MAX + 1)) /* +1 for header */ 66 67 #define CXL_DEVICE_STATUS_REGISTERS_OFFSET 0x80 /* Read comment above */ 68 #define CXL_DEVICE_STATUS_REGISTERS_LENGTH 0x8 /* 8.2.8.3.1 */ 69 70 #define CXL_MAILBOX_REGISTERS_OFFSET \ 71 (CXL_DEVICE_STATUS_REGISTERS_OFFSET + CXL_DEVICE_STATUS_REGISTERS_LENGTH) 72 #define CXL_MAILBOX_REGISTERS_SIZE 0x20 /* 8.2.8.4, Figure 139 */ 73 #define CXL_MAILBOX_PAYLOAD_SHIFT 11 74 #define CXL_MAILBOX_MAX_PAYLOAD_SIZE (1 << CXL_MAILBOX_PAYLOAD_SHIFT) 75 #define CXL_MAILBOX_REGISTERS_LENGTH \ 76 (CXL_MAILBOX_REGISTERS_SIZE + CXL_MAILBOX_MAX_PAYLOAD_SIZE) 77 78 #define CXL_MEMORY_DEVICE_REGISTERS_OFFSET \ 79 (CXL_MAILBOX_REGISTERS_OFFSET + CXL_MAILBOX_REGISTERS_LENGTH) 80 #define CXL_MEMORY_DEVICE_REGISTERS_LENGTH 0x8 81 82 #define CXL_MMIO_SIZE \ 83 (CXL_DEVICE_CAP_REG_SIZE + CXL_DEVICE_STATUS_REGISTERS_LENGTH + \ 84 CXL_MAILBOX_REGISTERS_LENGTH + CXL_MEMORY_DEVICE_REGISTERS_LENGTH) 85 86 /* 8.2.8.4.5.1 Command Return Codes */ 87 typedef enum { 88 CXL_MBOX_SUCCESS = 0x0, 89 CXL_MBOX_BG_STARTED = 0x1, 90 CXL_MBOX_INVALID_INPUT = 0x2, 91 CXL_MBOX_UNSUPPORTED = 0x3, 92 CXL_MBOX_INTERNAL_ERROR = 0x4, 93 CXL_MBOX_RETRY_REQUIRED = 0x5, 94 CXL_MBOX_BUSY = 0x6, 95 CXL_MBOX_MEDIA_DISABLED = 0x7, 96 CXL_MBOX_FW_XFER_IN_PROGRESS = 0x8, 97 CXL_MBOX_FW_XFER_OUT_OF_ORDER = 0x9, 98 CXL_MBOX_FW_AUTH_FAILED = 0xa, 99 CXL_MBOX_FW_INVALID_SLOT = 0xb, 100 CXL_MBOX_FW_ROLLEDBACK = 0xc, 101 CXL_MBOX_FW_REST_REQD = 0xd, 102 CXL_MBOX_INVALID_HANDLE = 0xe, 103 CXL_MBOX_INVALID_PA = 0xf, 104 CXL_MBOX_INJECT_POISON_LIMIT = 0x10, 105 CXL_MBOX_PERMANENT_MEDIA_FAILURE = 0x11, 106 CXL_MBOX_ABORTED = 0x12, 107 CXL_MBOX_INVALID_SECURITY_STATE = 0x13, 108 CXL_MBOX_INCORRECT_PASSPHRASE = 0x14, 109 CXL_MBOX_UNSUPPORTED_MAILBOX = 0x15, 110 CXL_MBOX_INVALID_PAYLOAD_LENGTH = 0x16, 111 CXL_MBOX_MAX = 0x17 112 } CXLRetCode; 113 114 typedef struct CXLEvent { 115 CXLEventRecordRaw data; 116 QSIMPLEQ_ENTRY(CXLEvent) node; 117 } CXLEvent; 118 119 typedef struct CXLEventLog { 120 uint16_t next_handle; 121 uint16_t overflow_err_count; 122 uint64_t first_overflow_timestamp; 123 uint64_t last_overflow_timestamp; 124 bool irq_enabled; 125 int irq_vec; 126 QemuMutex lock; 127 QSIMPLEQ_HEAD(, CXLEvent) events; 128 } CXLEventLog; 129 130 typedef struct cxl_device_state { 131 MemoryRegion device_registers; 132 133 /* mmio for device capabilities array - 8.2.8.2 */ 134 struct { 135 MemoryRegion device; 136 union { 137 uint8_t dev_reg_state[CXL_DEVICE_STATUS_REGISTERS_LENGTH]; 138 uint16_t dev_reg_state16[CXL_DEVICE_STATUS_REGISTERS_LENGTH / 2]; 139 uint32_t dev_reg_state32[CXL_DEVICE_STATUS_REGISTERS_LENGTH / 4]; 140 uint64_t dev_reg_state64[CXL_DEVICE_STATUS_REGISTERS_LENGTH / 8]; 141 }; 142 uint64_t event_status; 143 }; 144 MemoryRegion memory_device; 145 struct { 146 MemoryRegion caps; 147 union { 148 uint32_t caps_reg_state32[CXL_CAPS_SIZE / 4]; 149 uint64_t caps_reg_state64[CXL_CAPS_SIZE / 8]; 150 }; 151 }; 152 153 /* mmio for the mailbox registers 8.2.8.4 */ 154 struct { 155 MemoryRegion mailbox; 156 uint16_t payload_size; 157 union { 158 uint8_t mbox_reg_state[CXL_MAILBOX_REGISTERS_LENGTH]; 159 uint16_t mbox_reg_state16[CXL_MAILBOX_REGISTERS_LENGTH / 2]; 160 uint32_t mbox_reg_state32[CXL_MAILBOX_REGISTERS_LENGTH / 4]; 161 uint64_t mbox_reg_state64[CXL_MAILBOX_REGISTERS_LENGTH / 8]; 162 }; 163 struct cel_log { 164 uint16_t opcode; 165 uint16_t effect; 166 } cel_log[1 << 16]; 167 size_t cel_size; 168 }; 169 170 struct { 171 bool set; 172 uint64_t last_set; 173 uint64_t host_set; 174 } timestamp; 175 176 /* memory region size, HDM */ 177 uint64_t mem_size; 178 uint64_t pmem_size; 179 uint64_t vmem_size; 180 181 CXLEventLog event_logs[CXL_EVENT_TYPE_MAX]; 182 } CXLDeviceState; 183 184 /* Initialize the register block for a device */ 185 void cxl_device_register_block_init(Object *obj, CXLDeviceState *dev); 186 187 /* Set up default values for the register block */ 188 void cxl_device_register_init_common(CXLDeviceState *dev); 189 190 /* 191 * CXL 2.0 - 8.2.8.1 including errata F4 192 * Documented as a 128 bit register, but 64 bit accesses and the second 193 * 64 bits are currently reserved. 194 */ 195 REG64(CXL_DEV_CAP_ARRAY, 0) /* Documented as 128 bit register but 64 byte accesses */ 196 FIELD(CXL_DEV_CAP_ARRAY, CAP_ID, 0, 16) 197 FIELD(CXL_DEV_CAP_ARRAY, CAP_VERSION, 16, 8) 198 FIELD(CXL_DEV_CAP_ARRAY, CAP_COUNT, 32, 16) 199 200 void cxl_event_set_status(CXLDeviceState *cxl_dstate, CXLEventLogType log_type, 201 bool available); 202 203 /* 204 * Helper macro to initialize capability headers for CXL devices. 205 * 206 * In the 8.2.8.2, this is listed as a 128b register, but in 8.2.8, it says: 207 * > No registers defined in Section 8.2.8 are larger than 64-bits wide so that 208 * > is the maximum access size allowed for these registers. If this rule is not 209 * > followed, the behavior is undefined 210 * 211 * CXL 2.0 Errata F4 states further that the layouts in the specification are 212 * shown as greater than 128 bits, but implementations are expected to 213 * use any size of access up to 64 bits. 214 * 215 * Here we've chosen to make it 4 dwords. The spec allows any pow2 multiple 216 * access to be used for a register up to 64 bits. 217 */ 218 #define CXL_DEVICE_CAPABILITY_HEADER_REGISTER(n, offset) \ 219 REG32(CXL_DEV_##n##_CAP_HDR0, offset) \ 220 FIELD(CXL_DEV_##n##_CAP_HDR0, CAP_ID, 0, 16) \ 221 FIELD(CXL_DEV_##n##_CAP_HDR0, CAP_VERSION, 16, 8) \ 222 REG32(CXL_DEV_##n##_CAP_HDR1, offset + 4) \ 223 FIELD(CXL_DEV_##n##_CAP_HDR1, CAP_OFFSET, 0, 32) \ 224 REG32(CXL_DEV_##n##_CAP_HDR2, offset + 8) \ 225 FIELD(CXL_DEV_##n##_CAP_HDR2, CAP_LENGTH, 0, 32) 226 227 CXL_DEVICE_CAPABILITY_HEADER_REGISTER(DEVICE_STATUS, CXL_DEVICE_CAP_HDR1_OFFSET) 228 CXL_DEVICE_CAPABILITY_HEADER_REGISTER(MAILBOX, CXL_DEVICE_CAP_HDR1_OFFSET + \ 229 CXL_DEVICE_CAP_REG_SIZE) 230 CXL_DEVICE_CAPABILITY_HEADER_REGISTER(MEMORY_DEVICE, 231 CXL_DEVICE_CAP_HDR1_OFFSET + 232 CXL_DEVICE_CAP_REG_SIZE * 2) 233 234 void cxl_initialize_mailbox(CXLDeviceState *cxl_dstate); 235 void cxl_process_mailbox(CXLDeviceState *cxl_dstate); 236 237 #define cxl_device_cap_init(dstate, reg, cap_id, ver) \ 238 do { \ 239 uint32_t *cap_hdrs = dstate->caps_reg_state32; \ 240 int which = R_CXL_DEV_##reg##_CAP_HDR0; \ 241 cap_hdrs[which] = \ 242 FIELD_DP32(cap_hdrs[which], CXL_DEV_##reg##_CAP_HDR0, \ 243 CAP_ID, cap_id); \ 244 cap_hdrs[which] = FIELD_DP32( \ 245 cap_hdrs[which], CXL_DEV_##reg##_CAP_HDR0, CAP_VERSION, ver); \ 246 cap_hdrs[which + 1] = \ 247 FIELD_DP32(cap_hdrs[which + 1], CXL_DEV_##reg##_CAP_HDR1, \ 248 CAP_OFFSET, CXL_##reg##_REGISTERS_OFFSET); \ 249 cap_hdrs[which + 2] = \ 250 FIELD_DP32(cap_hdrs[which + 2], CXL_DEV_##reg##_CAP_HDR2, \ 251 CAP_LENGTH, CXL_##reg##_REGISTERS_LENGTH); \ 252 } while (0) 253 254 /* CXL 3.0 8.2.8.3.1 Event Status Register */ 255 REG64(CXL_DEV_EVENT_STATUS, 0) 256 FIELD(CXL_DEV_EVENT_STATUS, EVENT_STATUS, 0, 32) 257 258 /* CXL 2.0 8.2.8.4.3 Mailbox Capabilities Register */ 259 REG32(CXL_DEV_MAILBOX_CAP, 0) 260 FIELD(CXL_DEV_MAILBOX_CAP, PAYLOAD_SIZE, 0, 5) 261 FIELD(CXL_DEV_MAILBOX_CAP, INT_CAP, 5, 1) 262 FIELD(CXL_DEV_MAILBOX_CAP, BG_INT_CAP, 6, 1) 263 FIELD(CXL_DEV_MAILBOX_CAP, MSI_N, 7, 4) 264 265 /* CXL 2.0 8.2.8.4.4 Mailbox Control Register */ 266 REG32(CXL_DEV_MAILBOX_CTRL, 4) 267 FIELD(CXL_DEV_MAILBOX_CTRL, DOORBELL, 0, 1) 268 FIELD(CXL_DEV_MAILBOX_CTRL, INT_EN, 1, 1) 269 FIELD(CXL_DEV_MAILBOX_CTRL, BG_INT_EN, 2, 1) 270 271 /* CXL 2.0 8.2.8.4.5 Command Register */ 272 REG64(CXL_DEV_MAILBOX_CMD, 8) 273 FIELD(CXL_DEV_MAILBOX_CMD, COMMAND, 0, 8) 274 FIELD(CXL_DEV_MAILBOX_CMD, COMMAND_SET, 8, 8) 275 FIELD(CXL_DEV_MAILBOX_CMD, LENGTH, 16, 20) 276 277 /* CXL 2.0 8.2.8.4.6 Mailbox Status Register */ 278 REG64(CXL_DEV_MAILBOX_STS, 0x10) 279 FIELD(CXL_DEV_MAILBOX_STS, BG_OP, 0, 1) 280 FIELD(CXL_DEV_MAILBOX_STS, ERRNO, 32, 16) 281 FIELD(CXL_DEV_MAILBOX_STS, VENDOR_ERRNO, 48, 16) 282 283 /* CXL 2.0 8.2.8.4.7 Background Command Status Register */ 284 REG64(CXL_DEV_BG_CMD_STS, 0x18) 285 FIELD(CXL_DEV_BG_CMD_STS, OP, 0, 16) 286 FIELD(CXL_DEV_BG_CMD_STS, PERCENTAGE_COMP, 16, 7) 287 FIELD(CXL_DEV_BG_CMD_STS, RET_CODE, 32, 16) 288 FIELD(CXL_DEV_BG_CMD_STS, VENDOR_RET_CODE, 48, 16) 289 290 /* CXL 2.0 8.2.8.4.8 Command Payload Registers */ 291 REG32(CXL_DEV_CMD_PAYLOAD, 0x20) 292 293 REG64(CXL_MEM_DEV_STS, 0) 294 FIELD(CXL_MEM_DEV_STS, FATAL, 0, 1) 295 FIELD(CXL_MEM_DEV_STS, FW_HALT, 1, 1) 296 FIELD(CXL_MEM_DEV_STS, MEDIA_STATUS, 2, 2) 297 FIELD(CXL_MEM_DEV_STS, MBOX_READY, 4, 1) 298 FIELD(CXL_MEM_DEV_STS, RESET_NEEDED, 5, 3) 299 300 typedef struct CXLError { 301 QTAILQ_ENTRY(CXLError) node; 302 int type; /* Error code as per FE definition */ 303 uint32_t header[32]; 304 } CXLError; 305 306 typedef QTAILQ_HEAD(, CXLError) CXLErrorList; 307 308 typedef struct CXLPoison { 309 uint64_t start, length; 310 uint8_t type; 311 #define CXL_POISON_TYPE_EXTERNAL 0x1 312 #define CXL_POISON_TYPE_INTERNAL 0x2 313 #define CXL_POISON_TYPE_INJECTED 0x3 314 QLIST_ENTRY(CXLPoison) node; 315 } CXLPoison; 316 317 typedef QLIST_HEAD(, CXLPoison) CXLPoisonList; 318 #define CXL_POISON_LIST_LIMIT 256 319 320 struct CXLType3Dev { 321 /* Private */ 322 PCIDevice parent_obj; 323 324 /* Properties */ 325 HostMemoryBackend *hostmem; /* deprecated */ 326 HostMemoryBackend *hostvmem; 327 HostMemoryBackend *hostpmem; 328 HostMemoryBackend *lsa; 329 uint64_t sn; 330 331 /* State */ 332 AddressSpace hostvmem_as; 333 AddressSpace hostpmem_as; 334 CXLComponentState cxl_cstate; 335 CXLDeviceState cxl_dstate; 336 337 /* DOE */ 338 DOECap doe_cdat; 339 340 /* Error injection */ 341 CXLErrorList error_list; 342 343 /* Poison Injection - cache */ 344 CXLPoisonList poison_list; 345 unsigned int poison_list_cnt; 346 bool poison_list_overflowed; 347 uint64_t poison_list_overflow_ts; 348 }; 349 350 #define TYPE_CXL_TYPE3 "cxl-type3" 351 OBJECT_DECLARE_TYPE(CXLType3Dev, CXLType3Class, CXL_TYPE3) 352 353 struct CXLType3Class { 354 /* Private */ 355 PCIDeviceClass parent_class; 356 357 /* public */ 358 uint64_t (*get_lsa_size)(CXLType3Dev *ct3d); 359 360 uint64_t (*get_lsa)(CXLType3Dev *ct3d, void *buf, uint64_t size, 361 uint64_t offset); 362 void (*set_lsa)(CXLType3Dev *ct3d, const void *buf, uint64_t size, 363 uint64_t offset); 364 bool (*set_cacheline)(CXLType3Dev *ct3d, uint64_t dpa_offset, uint8_t *data); 365 }; 366 367 MemTxResult cxl_type3_read(PCIDevice *d, hwaddr host_addr, uint64_t *data, 368 unsigned size, MemTxAttrs attrs); 369 MemTxResult cxl_type3_write(PCIDevice *d, hwaddr host_addr, uint64_t data, 370 unsigned size, MemTxAttrs attrs); 371 372 uint64_t cxl_device_get_timestamp(CXLDeviceState *cxlds); 373 374 void cxl_event_init(CXLDeviceState *cxlds, int start_msg_num); 375 bool cxl_event_insert(CXLDeviceState *cxlds, CXLEventLogType log_type, 376 CXLEventRecordRaw *event); 377 CXLRetCode cxl_event_get_records(CXLDeviceState *cxlds, CXLGetEventPayload *pl, 378 uint8_t log_type, int max_recs, 379 uint16_t *len); 380 CXLRetCode cxl_event_clear_records(CXLDeviceState *cxlds, 381 CXLClearEventPayload *pl); 382 383 void cxl_event_irq_assert(CXLType3Dev *ct3d); 384 385 void cxl_set_poison_list_overflowed(CXLType3Dev *ct3d); 386 387 #endif 388