1 /* 2 * QEMU CXL Component 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_COMPONENT_H 11 #define CXL_COMPONENT_H 12 13 /* CXL 2.0 - 8.2.4 */ 14 #define CXL2_COMPONENT_IO_REGION_SIZE 0x1000 15 #define CXL2_COMPONENT_CM_REGION_SIZE 0x1000 16 #define CXL2_COMPONENT_BLOCK_SIZE 0x10000 17 18 #include "qemu/compiler.h" 19 #include "qemu/range.h" 20 #include "qemu/typedefs.h" 21 #include "hw/cxl/cxl_cdat.h" 22 #include "hw/register.h" 23 #include "qapi/error.h" 24 25 enum reg_type { 26 CXL2_DEVICE, 27 CXL2_TYPE3_DEVICE, 28 CXL2_LOGICAL_DEVICE, 29 CXL2_ROOT_PORT, 30 CXL2_UPSTREAM_PORT, 31 CXL2_DOWNSTREAM_PORT 32 }; 33 34 /* 35 * Capability registers are defined at the top of the CXL.cache/mem region and 36 * are packed. For our purposes we will always define the caps in the same 37 * order. 38 * CXL 2.0 - 8.2.5 Table 142 for details. 39 */ 40 41 /* CXL 2.0 - 8.2.5.1 */ 42 REG32(CXL_CAPABILITY_HEADER, 0) 43 FIELD(CXL_CAPABILITY_HEADER, ID, 0, 16) 44 FIELD(CXL_CAPABILITY_HEADER, VERSION, 16, 4) 45 FIELD(CXL_CAPABILITY_HEADER, CACHE_MEM_VERSION, 20, 4) 46 FIELD(CXL_CAPABILITY_HEADER, ARRAY_SIZE, 24, 8) 47 48 #define CXLx_CAPABILITY_HEADER(type, offset) \ 49 REG32(CXL_##type##_CAPABILITY_HEADER, offset) \ 50 FIELD(CXL_##type##_CAPABILITY_HEADER, ID, 0, 16) \ 51 FIELD(CXL_##type##_CAPABILITY_HEADER, VERSION, 16, 4) \ 52 FIELD(CXL_##type##_CAPABILITY_HEADER, PTR, 20, 12) 53 CXLx_CAPABILITY_HEADER(RAS, 0x4) 54 CXLx_CAPABILITY_HEADER(LINK, 0x8) 55 CXLx_CAPABILITY_HEADER(HDM, 0xc) 56 CXLx_CAPABILITY_HEADER(EXTSEC, 0x10) 57 CXLx_CAPABILITY_HEADER(SNOOP, 0x14) 58 59 /* 60 * Capability structures contain the actual registers that the CXL component 61 * implements. Some of these are specific to certain types of components, but 62 * this implementation leaves enough space regardless. 63 */ 64 /* 8.2.5.9 - CXL RAS Capability Structure */ 65 66 /* Give ample space for caps before this */ 67 #define CXL_RAS_REGISTERS_OFFSET 0x80 68 #define CXL_RAS_REGISTERS_SIZE 0x58 69 REG32(CXL_RAS_UNC_ERR_STATUS, CXL_RAS_REGISTERS_OFFSET) 70 REG32(CXL_RAS_UNC_ERR_MASK, CXL_RAS_REGISTERS_OFFSET + 0x4) 71 REG32(CXL_RAS_UNC_ERR_SEVERITY, CXL_RAS_REGISTERS_OFFSET + 0x8) 72 REG32(CXL_RAS_COR_ERR_STATUS, CXL_RAS_REGISTERS_OFFSET + 0xc) 73 REG32(CXL_RAS_COR_ERR_MASK, CXL_RAS_REGISTERS_OFFSET + 0x10) 74 REG32(CXL_RAS_ERR_CAP_CTRL, CXL_RAS_REGISTERS_OFFSET + 0x14) 75 /* Offset 0x18 - 0x58 reserved for RAS logs */ 76 77 /* 8.2.5.10 - CXL Security Capability Structure */ 78 #define CXL_SEC_REGISTERS_OFFSET \ 79 (CXL_RAS_REGISTERS_OFFSET + CXL_RAS_REGISTERS_SIZE) 80 #define CXL_SEC_REGISTERS_SIZE 0 /* We don't implement 1.1 downstream ports */ 81 82 /* 8.2.5.11 - CXL Link Capability Structure */ 83 #define CXL_LINK_REGISTERS_OFFSET \ 84 (CXL_SEC_REGISTERS_OFFSET + CXL_SEC_REGISTERS_SIZE) 85 #define CXL_LINK_REGISTERS_SIZE 0x38 86 87 /* 8.2.5.12 - CXL HDM Decoder Capability Structure */ 88 #define HDM_DECODE_MAX 10 /* 8.2.5.12.1 */ 89 #define CXL_HDM_REGISTERS_OFFSET \ 90 (CXL_LINK_REGISTERS_OFFSET + CXL_LINK_REGISTERS_SIZE) 91 #define CXL_HDM_REGISTERS_SIZE (0x10 + 0x20 * HDM_DECODE_MAX) 92 #define HDM_DECODER_INIT(n) \ 93 REG32(CXL_HDM_DECODER##n##_BASE_LO, \ 94 CXL_HDM_REGISTERS_OFFSET + (0x20 * n) + 0x10) \ 95 FIELD(CXL_HDM_DECODER##n##_BASE_LO, L, 28, 4) \ 96 REG32(CXL_HDM_DECODER##n##_BASE_HI, \ 97 CXL_HDM_REGISTERS_OFFSET + (0x20 * n) + 0x14) \ 98 REG32(CXL_HDM_DECODER##n##_SIZE_LO, \ 99 CXL_HDM_REGISTERS_OFFSET + (0x20 * n) + 0x18) \ 100 REG32(CXL_HDM_DECODER##n##_SIZE_HI, \ 101 CXL_HDM_REGISTERS_OFFSET + (0x20 * n) + 0x1C) \ 102 REG32(CXL_HDM_DECODER##n##_CTRL, \ 103 CXL_HDM_REGISTERS_OFFSET + (0x20 * n) + 0x20) \ 104 FIELD(CXL_HDM_DECODER##n##_CTRL, IG, 0, 4) \ 105 FIELD(CXL_HDM_DECODER##n##_CTRL, IW, 4, 4) \ 106 FIELD(CXL_HDM_DECODER##n##_CTRL, LOCK_ON_COMMIT, 8, 1) \ 107 FIELD(CXL_HDM_DECODER##n##_CTRL, COMMIT, 9, 1) \ 108 FIELD(CXL_HDM_DECODER##n##_CTRL, COMMITTED, 10, 1) \ 109 FIELD(CXL_HDM_DECODER##n##_CTRL, ERR, 11, 1) \ 110 FIELD(CXL_HDM_DECODER##n##_CTRL, TYPE, 12, 1) \ 111 REG32(CXL_HDM_DECODER##n##_TARGET_LIST_LO, \ 112 CXL_HDM_REGISTERS_OFFSET + (0x20 * n) + 0x24) \ 113 REG32(CXL_HDM_DECODER##n##_TARGET_LIST_HI, \ 114 CXL_HDM_REGISTERS_OFFSET + (0x20 * n) + 0x28) 115 116 REG32(CXL_HDM_DECODER_CAPABILITY, CXL_HDM_REGISTERS_OFFSET) 117 FIELD(CXL_HDM_DECODER_CAPABILITY, DECODER_COUNT, 0, 4) 118 FIELD(CXL_HDM_DECODER_CAPABILITY, TARGET_COUNT, 4, 4) 119 FIELD(CXL_HDM_DECODER_CAPABILITY, INTERLEAVE_256B, 8, 1) 120 FIELD(CXL_HDM_DECODER_CAPABILITY, INTERLEAVE_4K, 9, 1) 121 FIELD(CXL_HDM_DECODER_CAPABILITY, POISON_ON_ERR_CAP, 10, 1) 122 REG32(CXL_HDM_DECODER_GLOBAL_CONTROL, CXL_HDM_REGISTERS_OFFSET + 4) 123 FIELD(CXL_HDM_DECODER_GLOBAL_CONTROL, POISON_ON_ERR_EN, 0, 1) 124 FIELD(CXL_HDM_DECODER_GLOBAL_CONTROL, HDM_DECODER_ENABLE, 1, 1) 125 126 HDM_DECODER_INIT(0); 127 128 /* 8.2.5.13 - CXL Extended Security Capability Structure (Root complex only) */ 129 #define EXTSEC_ENTRY_MAX 256 130 #define CXL_EXTSEC_REGISTERS_OFFSET \ 131 (CXL_HDM_REGISTERS_OFFSET + CXL_HDM_REGISTERS_SIZE) 132 #define CXL_EXTSEC_REGISTERS_SIZE (8 * EXTSEC_ENTRY_MAX + 4) 133 134 /* 8.2.5.14 - CXL IDE Capability Structure */ 135 #define CXL_IDE_REGISTERS_OFFSET \ 136 (CXL_EXTSEC_REGISTERS_OFFSET + CXL_EXTSEC_REGISTERS_SIZE) 137 #define CXL_IDE_REGISTERS_SIZE 0x20 138 139 /* 8.2.5.15 - CXL Snoop Filter Capability Structure */ 140 #define CXL_SNOOP_REGISTERS_OFFSET \ 141 (CXL_IDE_REGISTERS_OFFSET + CXL_IDE_REGISTERS_SIZE) 142 #define CXL_SNOOP_REGISTERS_SIZE 0x8 143 144 QEMU_BUILD_BUG_MSG((CXL_SNOOP_REGISTERS_OFFSET + CXL_SNOOP_REGISTERS_SIZE) >= 0x1000, 145 "No space for registers"); 146 147 typedef struct component_registers { 148 /* 149 * Main memory region to be registered with QEMU core. 150 */ 151 MemoryRegion component_registers; 152 153 /* 154 * 8.2.4 Table 141: 155 * 0x0000 - 0x0fff CXL.io registers 156 * 0x1000 - 0x1fff CXL.cache and CXL.mem 157 * 0x2000 - 0xdfff Implementation specific 158 * 0xe000 - 0xe3ff CXL ARB/MUX registers 159 * 0xe400 - 0xffff RSVD 160 */ 161 uint32_t io_registers[CXL2_COMPONENT_IO_REGION_SIZE >> 2]; 162 MemoryRegion io; 163 164 uint32_t cache_mem_registers[CXL2_COMPONENT_CM_REGION_SIZE >> 2]; 165 uint32_t cache_mem_regs_write_mask[CXL2_COMPONENT_CM_REGION_SIZE >> 2]; 166 MemoryRegion cache_mem; 167 168 MemoryRegion impl_specific; 169 MemoryRegion arb_mux; 170 MemoryRegion rsvd; 171 172 /* special_ops is used for any component that needs any specific handling */ 173 MemoryRegionOps *special_ops; 174 } ComponentRegisters; 175 176 /* 177 * A CXL component represents all entities in a CXL hierarchy. This includes, 178 * host bridges, root ports, upstream/downstream switch ports, and devices 179 */ 180 typedef struct cxl_component { 181 ComponentRegisters crb; 182 union { 183 struct { 184 Range dvsecs[CXL20_MAX_DVSEC]; 185 uint16_t dvsec_offset; 186 struct PCIDevice *pdev; 187 }; 188 }; 189 190 CDATObject cdat; 191 } CXLComponentState; 192 193 void cxl_component_register_block_init(Object *obj, 194 CXLComponentState *cxl_cstate, 195 const char *type); 196 void cxl_component_register_init_common(uint32_t *reg_state, 197 uint32_t *write_msk, 198 enum reg_type type); 199 200 void cxl_component_create_dvsec(CXLComponentState *cxl_cstate, 201 enum reg_type cxl_dev_type, uint16_t length, 202 uint16_t type, uint8_t rev, uint8_t *body); 203 204 static inline int cxl_decoder_count_enc(int count) 205 { 206 switch (count) { 207 case 1: return 0; 208 case 2: return 1; 209 case 4: return 2; 210 case 6: return 3; 211 case 8: return 4; 212 case 10: return 5; 213 } 214 return 0; 215 } 216 217 uint8_t cxl_interleave_ways_enc(int iw, Error **errp); 218 uint8_t cxl_interleave_granularity_enc(uint64_t gran, Error **errp); 219 220 static inline hwaddr cxl_decode_ig(int ig) 221 { 222 return 1ULL << (ig + 8); 223 } 224 225 CXLComponentState *cxl_get_hb_cstate(PCIHostState *hb); 226 227 void cxl_doe_cdat_init(CXLComponentState *cxl_cstate, Error **errp); 228 void cxl_doe_cdat_release(CXLComponentState *cxl_cstate); 229 void cxl_doe_cdat_update(CXLComponentState *cxl_cstate, Error **errp); 230 231 #endif 232