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/register.h" 14 15 /* 16 * The following is how a CXL device's Memory Device registers are laid out. 17 * The only requirement from the spec is that the capabilities array and the 18 * capability headers start at offset 0 and are contiguously packed. The headers 19 * themselves provide offsets to the register fields. For this emulation, the 20 * actual registers * will start at offset 0x80 (m == 0x80). No secondary 21 * mailbox is implemented which means that the offset of the start of the 22 * mailbox payload (n) is given by 23 * n = m + sizeof(mailbox registers) + sizeof(device registers). 24 * 25 * +---------------------------------+ 26 * | | 27 * | Memory Device Registers | 28 * | | 29 * n + PAYLOAD_SIZE_MAX ----------------------------------- 30 * ^ | | 31 * | | | 32 * | | | 33 * | | | 34 * | | | 35 * | | Mailbox Payload | 36 * | | | 37 * | | | 38 * | | | 39 * n ----------------------------------- 40 * ^ | Mailbox Registers | 41 * | | | 42 * | ----------------------------------- 43 * | | | 44 * | | Device Registers | 45 * | | | 46 * m ----------------------------------> 47 * ^ | Memory Device Capability Header| 48 * | ----------------------------------- 49 * | | Mailbox Capability Header | 50 * | ----------------------------------- 51 * | | Device Capability Header | 52 * | ----------------------------------- 53 * | | Device Cap Array Register | 54 * 0 +---------------------------------+ 55 * 56 */ 57 58 #define CXL_DEVICE_CAP_HDR1_OFFSET 0x10 /* Figure 138 */ 59 #define CXL_DEVICE_CAP_REG_SIZE 0x10 /* 8.2.8.2 */ 60 #define CXL_DEVICE_CAPS_MAX 4 /* 8.2.8.2.1 + 8.2.8.5 */ 61 #define CXL_CAPS_SIZE \ 62 (CXL_DEVICE_CAP_REG_SIZE * (CXL_DEVICE_CAPS_MAX + 1)) /* +1 for header */ 63 64 #define CXL_DEVICE_STATUS_REGISTERS_OFFSET 0x80 /* Read comment above */ 65 #define CXL_DEVICE_STATUS_REGISTERS_LENGTH 0x8 /* 8.2.8.3.1 */ 66 67 #define CXL_MAILBOX_REGISTERS_OFFSET \ 68 (CXL_DEVICE_STATUS_REGISTERS_OFFSET + CXL_DEVICE_STATUS_REGISTERS_LENGTH) 69 #define CXL_MAILBOX_REGISTERS_SIZE 0x20 /* 8.2.8.4, Figure 139 */ 70 #define CXL_MAILBOX_PAYLOAD_SHIFT 11 71 #define CXL_MAILBOX_MAX_PAYLOAD_SIZE (1 << CXL_MAILBOX_PAYLOAD_SHIFT) 72 #define CXL_MAILBOX_REGISTERS_LENGTH \ 73 (CXL_MAILBOX_REGISTERS_SIZE + CXL_MAILBOX_MAX_PAYLOAD_SIZE) 74 75 #define CXL_MEMORY_DEVICE_REGISTERS_OFFSET \ 76 (CXL_MAILBOX_REGISTERS_OFFSET + CXL_MAILBOX_REGISTERS_LENGTH) 77 #define CXL_MEMORY_DEVICE_REGISTERS_LENGTH 0x8 78 79 #define CXL_MMIO_SIZE \ 80 (CXL_DEVICE_CAP_REG_SIZE + CXL_DEVICE_STATUS_REGISTERS_LENGTH + \ 81 CXL_MAILBOX_REGISTERS_LENGTH + CXL_MEMORY_DEVICE_REGISTERS_LENGTH) 82 83 typedef struct cxl_device_state { 84 MemoryRegion device_registers; 85 86 /* mmio for device capabilities array - 8.2.8.2 */ 87 MemoryRegion device; 88 MemoryRegion memory_device; 89 struct { 90 MemoryRegion caps; 91 union { 92 uint32_t caps_reg_state32[CXL_CAPS_SIZE / 4]; 93 uint64_t caps_reg_state64[CXL_CAPS_SIZE / 8]; 94 }; 95 }; 96 97 /* mmio for the mailbox registers 8.2.8.4 */ 98 struct { 99 MemoryRegion mailbox; 100 uint16_t payload_size; 101 union { 102 uint8_t mbox_reg_state[CXL_MAILBOX_REGISTERS_LENGTH]; 103 uint16_t mbox_reg_state16[CXL_MAILBOX_REGISTERS_LENGTH / 2]; 104 uint32_t mbox_reg_state32[CXL_MAILBOX_REGISTERS_LENGTH / 4]; 105 uint64_t mbox_reg_state64[CXL_MAILBOX_REGISTERS_LENGTH / 8]; 106 }; 107 struct cel_log { 108 uint16_t opcode; 109 uint16_t effect; 110 } cel_log[1 << 16]; 111 size_t cel_size; 112 }; 113 114 struct { 115 bool set; 116 uint64_t last_set; 117 uint64_t host_set; 118 } timestamp; 119 120 /* memory region for persistent memory, HDM */ 121 uint64_t pmem_size; 122 } CXLDeviceState; 123 124 /* Initialize the register block for a device */ 125 void cxl_device_register_block_init(Object *obj, CXLDeviceState *dev); 126 127 /* Set up default values for the register block */ 128 void cxl_device_register_init_common(CXLDeviceState *dev); 129 130 /* 131 * CXL 2.0 - 8.2.8.1 including errata F4 132 * Documented as a 128 bit register, but 64 bit accesses and the second 133 * 64 bits are currently reserved. 134 */ 135 REG64(CXL_DEV_CAP_ARRAY, 0) /* Documented as 128 bit register but 64 byte accesses */ 136 FIELD(CXL_DEV_CAP_ARRAY, CAP_ID, 0, 16) 137 FIELD(CXL_DEV_CAP_ARRAY, CAP_VERSION, 16, 8) 138 FIELD(CXL_DEV_CAP_ARRAY, CAP_COUNT, 32, 16) 139 140 /* 141 * Helper macro to initialize capability headers for CXL devices. 142 * 143 * In the 8.2.8.2, this is listed as a 128b register, but in 8.2.8, it says: 144 * > No registers defined in Section 8.2.8 are larger than 64-bits wide so that 145 * > is the maximum access size allowed for these registers. If this rule is not 146 * > followed, the behavior is undefined 147 * 148 * CXL 2.0 Errata F4 states futher that the layouts in the specification are 149 * shown as greater than 128 bits, but implementations are expected to 150 * use any size of access up to 64 bits. 151 * 152 * Here we've chosen to make it 4 dwords. The spec allows any pow2 multiple 153 * access to be used for a register up to 64 bits. 154 */ 155 #define CXL_DEVICE_CAPABILITY_HEADER_REGISTER(n, offset) \ 156 REG32(CXL_DEV_##n##_CAP_HDR0, offset) \ 157 FIELD(CXL_DEV_##n##_CAP_HDR0, CAP_ID, 0, 16) \ 158 FIELD(CXL_DEV_##n##_CAP_HDR0, CAP_VERSION, 16, 8) \ 159 REG32(CXL_DEV_##n##_CAP_HDR1, offset + 4) \ 160 FIELD(CXL_DEV_##n##_CAP_HDR1, CAP_OFFSET, 0, 32) \ 161 REG32(CXL_DEV_##n##_CAP_HDR2, offset + 8) \ 162 FIELD(CXL_DEV_##n##_CAP_HDR2, CAP_LENGTH, 0, 32) 163 164 CXL_DEVICE_CAPABILITY_HEADER_REGISTER(DEVICE_STATUS, CXL_DEVICE_CAP_HDR1_OFFSET) 165 CXL_DEVICE_CAPABILITY_HEADER_REGISTER(MAILBOX, CXL_DEVICE_CAP_HDR1_OFFSET + \ 166 CXL_DEVICE_CAP_REG_SIZE) 167 CXL_DEVICE_CAPABILITY_HEADER_REGISTER(MEMORY_DEVICE, 168 CXL_DEVICE_CAP_HDR1_OFFSET + 169 CXL_DEVICE_CAP_REG_SIZE * 2) 170 171 int cxl_initialize_mailbox(CXLDeviceState *cxl_dstate); 172 void cxl_process_mailbox(CXLDeviceState *cxl_dstate); 173 174 #define cxl_device_cap_init(dstate, reg, cap_id) \ 175 do { \ 176 uint32_t *cap_hdrs = dstate->caps_reg_state32; \ 177 int which = R_CXL_DEV_##reg##_CAP_HDR0; \ 178 cap_hdrs[which] = \ 179 FIELD_DP32(cap_hdrs[which], CXL_DEV_##reg##_CAP_HDR0, \ 180 CAP_ID, cap_id); \ 181 cap_hdrs[which] = FIELD_DP32( \ 182 cap_hdrs[which], CXL_DEV_##reg##_CAP_HDR0, CAP_VERSION, 1); \ 183 cap_hdrs[which + 1] = \ 184 FIELD_DP32(cap_hdrs[which + 1], CXL_DEV_##reg##_CAP_HDR1, \ 185 CAP_OFFSET, CXL_##reg##_REGISTERS_OFFSET); \ 186 cap_hdrs[which + 2] = \ 187 FIELD_DP32(cap_hdrs[which + 2], CXL_DEV_##reg##_CAP_HDR2, \ 188 CAP_LENGTH, CXL_##reg##_REGISTERS_LENGTH); \ 189 } while (0) 190 191 /* CXL 2.0 8.2.8.4.3 Mailbox Capabilities Register */ 192 REG32(CXL_DEV_MAILBOX_CAP, 0) 193 FIELD(CXL_DEV_MAILBOX_CAP, PAYLOAD_SIZE, 0, 5) 194 FIELD(CXL_DEV_MAILBOX_CAP, INT_CAP, 5, 1) 195 FIELD(CXL_DEV_MAILBOX_CAP, BG_INT_CAP, 6, 1) 196 FIELD(CXL_DEV_MAILBOX_CAP, MSI_N, 7, 4) 197 198 /* CXL 2.0 8.2.8.4.4 Mailbox Control Register */ 199 REG32(CXL_DEV_MAILBOX_CTRL, 4) 200 FIELD(CXL_DEV_MAILBOX_CTRL, DOORBELL, 0, 1) 201 FIELD(CXL_DEV_MAILBOX_CTRL, INT_EN, 1, 1) 202 FIELD(CXL_DEV_MAILBOX_CTRL, BG_INT_EN, 2, 1) 203 204 /* CXL 2.0 8.2.8.4.5 Command Register */ 205 REG64(CXL_DEV_MAILBOX_CMD, 8) 206 FIELD(CXL_DEV_MAILBOX_CMD, COMMAND, 0, 8) 207 FIELD(CXL_DEV_MAILBOX_CMD, COMMAND_SET, 8, 8) 208 FIELD(CXL_DEV_MAILBOX_CMD, LENGTH, 16, 20) 209 210 /* CXL 2.0 8.2.8.4.6 Mailbox Status Register */ 211 REG64(CXL_DEV_MAILBOX_STS, 0x10) 212 FIELD(CXL_DEV_MAILBOX_STS, BG_OP, 0, 1) 213 FIELD(CXL_DEV_MAILBOX_STS, ERRNO, 32, 16) 214 FIELD(CXL_DEV_MAILBOX_STS, VENDOR_ERRNO, 48, 16) 215 216 /* CXL 2.0 8.2.8.4.7 Background Command Status Register */ 217 REG64(CXL_DEV_BG_CMD_STS, 0x18) 218 FIELD(CXL_DEV_BG_CMD_STS, OP, 0, 16) 219 FIELD(CXL_DEV_BG_CMD_STS, PERCENTAGE_COMP, 16, 7) 220 FIELD(CXL_DEV_BG_CMD_STS, RET_CODE, 32, 16) 221 FIELD(CXL_DEV_BG_CMD_STS, VENDOR_RET_CODE, 48, 16) 222 223 /* CXL 2.0 8.2.8.4.8 Command Payload Registers */ 224 REG32(CXL_DEV_CMD_PAYLOAD, 0x20) 225 226 REG64(CXL_MEM_DEV_STS, 0) 227 FIELD(CXL_MEM_DEV_STS, FATAL, 0, 1) 228 FIELD(CXL_MEM_DEV_STS, FW_HALT, 1, 1) 229 FIELD(CXL_MEM_DEV_STS, MEDIA_STATUS, 2, 2) 230 FIELD(CXL_MEM_DEV_STS, MBOX_READY, 4, 1) 231 FIELD(CXL_MEM_DEV_STS, RESET_NEEDED, 5, 3) 232 233 struct CXLType3Dev { 234 /* Private */ 235 PCIDevice parent_obj; 236 237 /* Properties */ 238 HostMemoryBackend *hostmem; 239 HostMemoryBackend *lsa; 240 241 /* State */ 242 AddressSpace hostmem_as; 243 CXLComponentState cxl_cstate; 244 CXLDeviceState cxl_dstate; 245 }; 246 247 #define TYPE_CXL_TYPE3 "cxl-type3" 248 OBJECT_DECLARE_TYPE(CXLType3Dev, CXLType3Class, CXL_TYPE3) 249 250 struct CXLType3Class { 251 /* Private */ 252 PCIDeviceClass parent_class; 253 254 /* public */ 255 uint64_t (*get_lsa_size)(CXLType3Dev *ct3d); 256 257 uint64_t (*get_lsa)(CXLType3Dev *ct3d, void *buf, uint64_t size, 258 uint64_t offset); 259 void (*set_lsa)(CXLType3Dev *ct3d, const void *buf, uint64_t size, 260 uint64_t offset); 261 }; 262 263 MemTxResult cxl_type3_read(PCIDevice *d, hwaddr host_addr, uint64_t *data, 264 unsigned size, MemTxAttrs attrs); 265 MemTxResult cxl_type3_write(PCIDevice *d, hwaddr host_addr, uint64_t data, 266 unsigned size, MemTxAttrs attrs); 267 268 #endif 269