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