xref: /openbmc/qemu/include/hw/cxl/cxl_component.h (revision 21c06f57)
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 r3.1 Section 8.2.4: CXL.cache and CXL.mem Registers  */
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/range.h"
19 #include "hw/cxl/cxl_cdat.h"
20 #include "hw/register.h"
21 #include "qapi/error.h"
22 
23 enum reg_type {
24     CXL2_DEVICE,
25     CXL2_TYPE3_DEVICE,
26     CXL2_LOGICAL_DEVICE,
27     CXL2_ROOT_PORT,
28     CXL2_RC,
29     CXL2_UPSTREAM_PORT,
30     CXL2_DOWNSTREAM_PORT,
31     CXL3_SWITCH_MAILBOX_CCI,
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 r3.1 Table 8-22: CXL_CAPABILITY_ID Assignment for details.
39  */
40 
41 /* CXL r3.1 Section 8.2.4.1: CXL Capability Header Register */
42 #define CXL_CAPABILITY_VERSION 1
43 REG32(CXL_CAPABILITY_HEADER, 0)
44     FIELD(CXL_CAPABILITY_HEADER, ID, 0, 16)
45     FIELD(CXL_CAPABILITY_HEADER, VERSION, 16, 4)
46     FIELD(CXL_CAPABILITY_HEADER, CACHE_MEM_VERSION, 20, 4)
47     FIELD(CXL_CAPABILITY_HEADER, ARRAY_SIZE, 24, 8)
48 
49 #define CXLx_CAPABILITY_HEADER(type, offset)                  \
50     REG32(CXL_##type##_CAPABILITY_HEADER, offset)             \
51         FIELD(CXL_##type##_CAPABILITY_HEADER, ID, 0, 16)      \
52         FIELD(CXL_##type##_CAPABILITY_HEADER, VERSION, 16, 4) \
53         FIELD(CXL_##type##_CAPABILITY_HEADER, PTR, 20, 12)
54 CXLx_CAPABILITY_HEADER(RAS, 0x4)
55 CXLx_CAPABILITY_HEADER(LINK, 0x8)
56 CXLx_CAPABILITY_HEADER(HDM, 0xc)
57 CXLx_CAPABILITY_HEADER(EXTSEC, 0x10)
58 CXLx_CAPABILITY_HEADER(SNOOP, 0x14)
59 
60 /*
61  * Capability structures contain the actual registers that the CXL component
62  * implements. Some of these are specific to certain types of components, but
63  * this implementation leaves enough space regardless.
64  */
65 
66 /* CXL r3.1 Section 8.2.4.17: CXL RAS Capability Structure */
67 #define CXL_RAS_CAPABILITY_VERSION 3
68 /* Give ample space for caps before this */
69 #define CXL_RAS_REGISTERS_OFFSET 0x80
70 #define CXL_RAS_REGISTERS_SIZE   0x58
71 REG32(CXL_RAS_UNC_ERR_STATUS, CXL_RAS_REGISTERS_OFFSET)
72 #define CXL_RAS_UNC_ERR_CACHE_DATA_PARITY 0
73 #define CXL_RAS_UNC_ERR_CACHE_ADDRESS_PARITY 1
74 #define CXL_RAS_UNC_ERR_CACHE_BE_PARITY 2
75 #define CXL_RAS_UNC_ERR_CACHE_DATA_ECC 3
76 #define CXL_RAS_UNC_ERR_MEM_DATA_PARITY 4
77 #define CXL_RAS_UNC_ERR_MEM_ADDRESS_PARITY 5
78 #define CXL_RAS_UNC_ERR_MEM_BE_PARITY 6
79 #define CXL_RAS_UNC_ERR_MEM_DATA_ECC 7
80 #define CXL_RAS_UNC_ERR_REINIT_THRESHOLD 8
81 #define CXL_RAS_UNC_ERR_RSVD_ENCODING 9
82 #define CXL_RAS_UNC_ERR_POISON_RECEIVED 10
83 #define CXL_RAS_UNC_ERR_RECEIVER_OVERFLOW 11
84 #define CXL_RAS_UNC_ERR_INTERNAL 14
85 #define CXL_RAS_UNC_ERR_CXL_IDE_TX 15
86 #define CXL_RAS_UNC_ERR_CXL_IDE_RX 16
87 #define CXL_RAS_UNC_ERR_CXL_UNUSED 63 /* Magic value */
88 REG32(CXL_RAS_UNC_ERR_MASK, CXL_RAS_REGISTERS_OFFSET + 0x4)
89 REG32(CXL_RAS_UNC_ERR_SEVERITY, CXL_RAS_REGISTERS_OFFSET + 0x8)
90 REG32(CXL_RAS_COR_ERR_STATUS, CXL_RAS_REGISTERS_OFFSET + 0xc)
91 #define CXL_RAS_COR_ERR_CACHE_DATA_ECC 0
92 #define CXL_RAS_COR_ERR_MEM_DATA_ECC 1
93 #define CXL_RAS_COR_ERR_CRC_THRESHOLD 2
94 #define CXL_RAS_COR_ERR_RETRY_THRESHOLD 3
95 #define CXL_RAS_COR_ERR_CACHE_POISON_RECEIVED 4
96 #define CXL_RAS_COR_ERR_MEM_POISON_RECEIVED 5
97 #define CXL_RAS_COR_ERR_PHYSICAL 6
98 REG32(CXL_RAS_COR_ERR_MASK, CXL_RAS_REGISTERS_OFFSET + 0x10)
99 REG32(CXL_RAS_ERR_CAP_CTRL, CXL_RAS_REGISTERS_OFFSET + 0x14)
100     FIELD(CXL_RAS_ERR_CAP_CTRL, FIRST_ERROR_POINTER, 0, 6)
101     FIELD(CXL_RAS_ERR_CAP_CTRL, MULTIPLE_HEADER_RECORDING_CAP, 9, 1)
102     FIELD(CXL_RAS_ERR_POISON_ENABLED, POISON_ENABLED, 13, 1)
103 REG32(CXL_RAS_ERR_HEADER0, CXL_RAS_REGISTERS_OFFSET + 0x18)
104 #define CXL_RAS_ERR_HEADER_NUM 32
105 /* Offset 0x18 - 0x58 reserved for RAS logs */
106 
107 /* CXL r3.1 Section 8.2.4.18: CXL Security Capability Structure */
108 #define CXL_SEC_REGISTERS_OFFSET \
109     (CXL_RAS_REGISTERS_OFFSET + CXL_RAS_REGISTERS_SIZE)
110 #define CXL_SEC_REGISTERS_SIZE   0 /* We don't implement 1.1 downstream ports */
111 
112 /* CXL r3.1 Section 8.2.4.19: CXL Link Capability Structure */
113 #define CXL_LINK_CAPABILITY_VERSION 2
114 #define CXL_LINK_REGISTERS_OFFSET \
115     (CXL_SEC_REGISTERS_OFFSET + CXL_SEC_REGISTERS_SIZE)
116 #define CXL_LINK_REGISTERS_SIZE   0x50
117 
118 /* CXL r3.1 Section 8.2.4.20: CXL HDM Decoder Capability Structure */
119 #define HDM_DECODE_MAX 10 /* Maximum decoders for Devices */
120 #define CXL_HDM_CAPABILITY_VERSION 3
121 #define CXL_HDM_REGISTERS_OFFSET \
122     (CXL_LINK_REGISTERS_OFFSET + CXL_LINK_REGISTERS_SIZE)
123 #define CXL_HDM_REGISTERS_SIZE (0x10 + 0x20 * HDM_DECODE_MAX)
124 #define HDM_DECODER_INIT(n)                                                    \
125   REG32(CXL_HDM_DECODER##n##_BASE_LO,                                          \
126         CXL_HDM_REGISTERS_OFFSET + (0x20 * n) + 0x10)                          \
127             FIELD(CXL_HDM_DECODER##n##_BASE_LO, L, 28, 4)                      \
128   REG32(CXL_HDM_DECODER##n##_BASE_HI,                                          \
129         CXL_HDM_REGISTERS_OFFSET + (0x20 * n) + 0x14)                          \
130   REG32(CXL_HDM_DECODER##n##_SIZE_LO,                                          \
131         CXL_HDM_REGISTERS_OFFSET + (0x20 * n) + 0x18)                          \
132   REG32(CXL_HDM_DECODER##n##_SIZE_HI,                                          \
133         CXL_HDM_REGISTERS_OFFSET + (0x20 * n) + 0x1C)                          \
134   REG32(CXL_HDM_DECODER##n##_CTRL,                                             \
135         CXL_HDM_REGISTERS_OFFSET + (0x20 * n) + 0x20)                          \
136             FIELD(CXL_HDM_DECODER##n##_CTRL, IG, 0, 4)                         \
137             FIELD(CXL_HDM_DECODER##n##_CTRL, IW, 4, 4)                         \
138             FIELD(CXL_HDM_DECODER##n##_CTRL, LOCK_ON_COMMIT, 8, 1)             \
139             FIELD(CXL_HDM_DECODER##n##_CTRL, COMMIT, 9, 1)                     \
140             FIELD(CXL_HDM_DECODER##n##_CTRL, COMMITTED, 10, 1)                 \
141             FIELD(CXL_HDM_DECODER##n##_CTRL, ERR, 11, 1)                       \
142             FIELD(CXL_HDM_DECODER##n##_CTRL, TYPE, 12, 1)                      \
143             FIELD(CXL_HDM_DECODER##n##_CTRL, BI, 13, 1)                        \
144             FIELD(CXL_HDM_DECODER##n##_CTRL, UIO, 14, 1)                       \
145             FIELD(CXL_HDM_DECODER##n##_CTRL, UIG, 16, 4)                       \
146             FIELD(CXL_HDM_DECODER##n##_CTRL, UIW, 20, 4)                       \
147             FIELD(CXL_HDM_DECODER##n##_CTRL, ISP, 24, 4)                       \
148   REG32(CXL_HDM_DECODER##n##_TARGET_LIST_LO,                                   \
149         CXL_HDM_REGISTERS_OFFSET + (0x20 * n) + 0x24)                          \
150   REG32(CXL_HDM_DECODER##n##_TARGET_LIST_HI,                                   \
151         CXL_HDM_REGISTERS_OFFSET + (0x20 * n) + 0x28)                          \
152   REG32(CXL_HDM_DECODER##n##_DPA_SKIP_LO,                                      \
153         CXL_HDM_REGISTERS_OFFSET + (0x20 * n) + 0x24)                          \
154   REG32(CXL_HDM_DECODER##n##_DPA_SKIP_HI,                                      \
155         CXL_HDM_REGISTERS_OFFSET + (0x20 * n) + 0x28)
156 
157 REG32(CXL_HDM_DECODER_CAPABILITY, CXL_HDM_REGISTERS_OFFSET)
158     FIELD(CXL_HDM_DECODER_CAPABILITY, DECODER_COUNT, 0, 4)
159     FIELD(CXL_HDM_DECODER_CAPABILITY, TARGET_COUNT, 4, 4)
160     FIELD(CXL_HDM_DECODER_CAPABILITY, INTERLEAVE_256B, 8, 1)
161     FIELD(CXL_HDM_DECODER_CAPABILITY, INTERLEAVE_4K, 9, 1)
162     FIELD(CXL_HDM_DECODER_CAPABILITY, POISON_ON_ERR_CAP, 10, 1)
163     FIELD(CXL_HDM_DECODER_CAPABILITY, 3_6_12_WAY, 11, 1)
164     FIELD(CXL_HDM_DECODER_CAPABILITY, 16_WAY, 12, 1)
165     FIELD(CXL_HDM_DECODER_CAPABILITY, UIO, 13, 1)
166     FIELD(CXL_HDM_DECODER_CAPABILITY, UIO_DECODER_COUNT, 16, 4)
167     FIELD(CXL_HDM_DECODER_CAPABILITY, MEMDATA_NXM_CAP, 20, 1)
168     FIELD(CXL_HDM_DECODER_CAPABILITY, SUPPORTED_COHERENCY_MODEL, 21, 2)
169 REG32(CXL_HDM_DECODER_GLOBAL_CONTROL, CXL_HDM_REGISTERS_OFFSET + 4)
170     FIELD(CXL_HDM_DECODER_GLOBAL_CONTROL, POISON_ON_ERR_EN, 0, 1)
171     FIELD(CXL_HDM_DECODER_GLOBAL_CONTROL, HDM_DECODER_ENABLE, 1, 1)
172 
173 /* Support 4 decoders at all levels of topology */
174 #define CXL_HDM_DECODER_COUNT 4
175 
176 HDM_DECODER_INIT(0);
177 HDM_DECODER_INIT(1);
178 HDM_DECODER_INIT(2);
179 HDM_DECODER_INIT(3);
180 
181 /*
182  * CXL r3.1 Section 8.2.4.21: CXL Extended Security Capability Structure
183  * (Root complex only)
184  */
185 #define EXTSEC_ENTRY_MAX        256
186 #define CXL_EXTSEC_CAP_VERSION 2
187 #define CXL_EXTSEC_REGISTERS_OFFSET \
188     (CXL_HDM_REGISTERS_OFFSET + CXL_HDM_REGISTERS_SIZE)
189 #define CXL_EXTSEC_REGISTERS_SIZE   (8 * EXTSEC_ENTRY_MAX + 4)
190 
191 /* CXL r3.1 Section 8.2.4.22: CXL IDE Capability Structure */
192 #define CXL_IDE_CAP_VERSION 2
193 #define CXL_IDE_REGISTERS_OFFSET \
194     (CXL_EXTSEC_REGISTERS_OFFSET + CXL_EXTSEC_REGISTERS_SIZE)
195 #define CXL_IDE_REGISTERS_SIZE   0x24
196 
197 /* CXL r3.1 Section 8.2.4.23 - CXL Snoop Filter Capability Structure */
198 #define CXL_SNOOP_CAP_VERSION 1
199 #define CXL_SNOOP_REGISTERS_OFFSET \
200     (CXL_IDE_REGISTERS_OFFSET + CXL_IDE_REGISTERS_SIZE)
201 #define CXL_SNOOP_REGISTERS_SIZE   0x8
202 
203 QEMU_BUILD_BUG_MSG((CXL_SNOOP_REGISTERS_OFFSET +
204                     CXL_SNOOP_REGISTERS_SIZE) >= 0x1000,
205                    "No space for registers");
206 
207 typedef struct component_registers {
208     /*
209      * Main memory region to be registered with QEMU core.
210      */
211     MemoryRegion component_registers;
212 
213     /*
214      * CXL r3.1 Table 8-21: CXL Subsystem Component Register Ranges
215      *   0x0000 - 0x0fff CXL.io registers
216      *   0x1000 - 0x1fff CXL.cache and CXL.mem
217      *   0x2000 - 0xdfff Implementation specific
218      *   0xe000 - 0xe3ff CXL ARB/MUX registers
219      *   0xe400 - 0xffff RSVD
220      */
221     uint32_t io_registers[CXL2_COMPONENT_IO_REGION_SIZE >> 2];
222     MemoryRegion io;
223 
224     uint32_t cache_mem_registers[CXL2_COMPONENT_CM_REGION_SIZE >> 2];
225     uint32_t cache_mem_regs_write_mask[CXL2_COMPONENT_CM_REGION_SIZE >> 2];
226     MemoryRegion cache_mem;
227 
228     MemoryRegion impl_specific;
229     MemoryRegion arb_mux;
230     MemoryRegion rsvd;
231 
232     /* special_ops is used for any component that needs any specific handling */
233     MemoryRegionOps *special_ops;
234 } ComponentRegisters;
235 
236 /*
237  * A CXL component represents all entities in a CXL hierarchy. This includes,
238  * host bridges, root ports, upstream/downstream switch ports, and devices
239  */
240 typedef struct cxl_component {
241     ComponentRegisters crb;
242     union {
243         struct {
244             Range dvsecs[CXL20_MAX_DVSEC];
245             uint16_t dvsec_offset;
246             struct PCIDevice *pdev;
247         };
248     };
249 
250     CDATObject cdat;
251 } CXLComponentState;
252 
253 void cxl_component_register_block_init(Object *obj,
254                                        CXLComponentState *cxl_cstate,
255                                        const char *type);
256 void cxl_component_register_init_common(uint32_t *reg_state,
257                                         uint32_t *write_msk,
258                                         enum reg_type type);
259 
260 void cxl_component_create_dvsec(CXLComponentState *cxl_cstate,
261                                 enum reg_type cxl_dev_type, uint16_t length,
262                                 uint16_t type, uint8_t rev, uint8_t *body);
263 
264 int cxl_decoder_count_enc(int count);
265 int cxl_decoder_count_dec(int enc_cnt);
266 
267 uint8_t cxl_interleave_ways_enc(int iw, Error **errp);
268 int cxl_interleave_ways_dec(uint8_t iw_enc, Error **errp);
269 uint8_t cxl_interleave_granularity_enc(uint64_t gran, Error **errp);
270 
271 hwaddr cxl_decode_ig(int ig);
272 
273 CXLComponentState *cxl_get_hb_cstate(PCIHostState *hb);
274 bool cxl_get_hb_passthrough(PCIHostState *hb);
275 
276 bool cxl_doe_cdat_init(CXLComponentState *cxl_cstate, Error **errp);
277 void cxl_doe_cdat_release(CXLComponentState *cxl_cstate);
278 void cxl_doe_cdat_update(CXLComponentState *cxl_cstate, Error **errp);
279 
280 #endif
281