xref: /qemu/hw/cxl/cxl-component-utils.c (revision 9e58f52d3f809712762bef735a02290fd4436b0c)
1 /*
2  * CXL Utility library for components
3  *
4  * Copyright(C) 2020 Intel Corporation.
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 #include "qemu/osdep.h"
11 #include "qemu/log.h"
12 #include "hw/pci/pci.h"
13 #include "hw/cxl/cxl.h"
14 
15 static uint64_t cxl_cache_mem_read_reg(void *opaque, hwaddr offset,
16                                        unsigned size)
17 {
18     CXLComponentState *cxl_cstate = opaque;
19     ComponentRegisters *cregs = &cxl_cstate->crb;
20 
21     if (size == 8) {
22         qemu_log_mask(LOG_UNIMP,
23                       "CXL 8 byte cache mem registers not implemented\n");
24         return 0;
25     }
26 
27     if (cregs->special_ops && cregs->special_ops->read) {
28         return cregs->special_ops->read(cxl_cstate, offset, size);
29     } else {
30         return cregs->cache_mem_registers[offset / sizeof(*cregs->cache_mem_registers)];
31     }
32 }
33 
34 static void cxl_cache_mem_write_reg(void *opaque, hwaddr offset, uint64_t value,
35                                     unsigned size)
36 {
37     CXLComponentState *cxl_cstate = opaque;
38     ComponentRegisters *cregs = &cxl_cstate->crb;
39     uint32_t mask;
40 
41     if (size == 8) {
42         qemu_log_mask(LOG_UNIMP,
43                       "CXL 8 byte cache mem registers not implemented\n");
44         return;
45     }
46     mask = cregs->cache_mem_regs_write_mask[offset / sizeof(*cregs->cache_mem_regs_write_mask)];
47     value &= mask;
48     /* RO bits should remain constant. Done by reading existing value */
49     value |= ~mask & cregs->cache_mem_registers[offset / sizeof(*cregs->cache_mem_registers)];
50     if (cregs->special_ops && cregs->special_ops->write) {
51         cregs->special_ops->write(cxl_cstate, offset, value, size);
52     } else {
53         cregs->cache_mem_registers[offset / sizeof(*cregs->cache_mem_registers)] = value;
54     }
55 }
56 
57 /*
58  * 8.2.3
59  *   The access restrictions specified in Section 8.2.2 also apply to CXL 2.0
60  *   Component Registers.
61  *
62  * 8.2.2
63  *   • A 32 bit register shall be accessed as a 4 Bytes quantity. Partial
64  *   reads are not permitted.
65  *   • A 64 bit register shall be accessed as a 8 Bytes quantity. Partial
66  *   reads are not permitted.
67  *
68  * As of the spec defined today, only 4 byte registers exist.
69  */
70 static const MemoryRegionOps cache_mem_ops = {
71     .read = cxl_cache_mem_read_reg,
72     .write = cxl_cache_mem_write_reg,
73     .endianness = DEVICE_LITTLE_ENDIAN,
74     .valid = {
75         .min_access_size = 4,
76         .max_access_size = 8,
77         .unaligned = false,
78     },
79     .impl = {
80         .min_access_size = 4,
81         .max_access_size = 8,
82     },
83 };
84 
85 void cxl_component_register_block_init(Object *obj,
86                                        CXLComponentState *cxl_cstate,
87                                        const char *type)
88 {
89     ComponentRegisters *cregs = &cxl_cstate->crb;
90 
91     memory_region_init(&cregs->component_registers, obj, type,
92                        CXL2_COMPONENT_BLOCK_SIZE);
93 
94     /* io registers controls link which we don't care about in QEMU */
95     memory_region_init_io(&cregs->io, obj, NULL, cregs, ".io",
96                           CXL2_COMPONENT_IO_REGION_SIZE);
97     memory_region_init_io(&cregs->cache_mem, obj, &cache_mem_ops, cregs,
98                           ".cache_mem", CXL2_COMPONENT_CM_REGION_SIZE);
99 
100     memory_region_add_subregion(&cregs->component_registers, 0, &cregs->io);
101     memory_region_add_subregion(&cregs->component_registers,
102                                 CXL2_COMPONENT_IO_REGION_SIZE,
103                                 &cregs->cache_mem);
104 }
105 
106 static void ras_init_common(uint32_t *reg_state, uint32_t *write_msk)
107 {
108     /*
109      * Error status is RW1C but given bits are not yet set, it can
110      * be handled as RO.
111      */
112     reg_state[R_CXL_RAS_UNC_ERR_STATUS] = 0;
113     /* Bits 12-13 and 17-31 reserved in CXL 2.0 */
114     reg_state[R_CXL_RAS_UNC_ERR_MASK] = 0x1cfff;
115     write_msk[R_CXL_RAS_UNC_ERR_MASK] = 0x1cfff;
116     reg_state[R_CXL_RAS_UNC_ERR_SEVERITY] = 0x1cfff;
117     write_msk[R_CXL_RAS_UNC_ERR_SEVERITY] = 0x1cfff;
118     reg_state[R_CXL_RAS_COR_ERR_STATUS] = 0;
119     reg_state[R_CXL_RAS_COR_ERR_MASK] = 0x7f;
120     write_msk[R_CXL_RAS_COR_ERR_MASK] = 0x7f;
121     /* CXL switches and devices must set */
122     reg_state[R_CXL_RAS_ERR_CAP_CTRL] = 0x00;
123 }
124 
125 static void hdm_init_common(uint32_t *reg_state, uint32_t *write_msk)
126 {
127     int decoder_count = 1;
128     int i;
129 
130     ARRAY_FIELD_DP32(reg_state, CXL_HDM_DECODER_CAPABILITY, DECODER_COUNT,
131                      cxl_decoder_count_enc(decoder_count));
132     ARRAY_FIELD_DP32(reg_state, CXL_HDM_DECODER_CAPABILITY, TARGET_COUNT, 1);
133     ARRAY_FIELD_DP32(reg_state, CXL_HDM_DECODER_CAPABILITY, INTERLEAVE_256B, 1);
134     ARRAY_FIELD_DP32(reg_state, CXL_HDM_DECODER_CAPABILITY, INTERLEAVE_4K, 1);
135     ARRAY_FIELD_DP32(reg_state, CXL_HDM_DECODER_CAPABILITY, POISON_ON_ERR_CAP, 0);
136     ARRAY_FIELD_DP32(reg_state, CXL_HDM_DECODER_GLOBAL_CONTROL,
137                      HDM_DECODER_ENABLE, 0);
138     write_msk[R_CXL_HDM_DECODER_GLOBAL_CONTROL] = 0x3;
139     for (i = 0; i < decoder_count; i++) {
140         write_msk[R_CXL_HDM_DECODER0_BASE_LO + i * 0x20] = 0xf0000000;
141         write_msk[R_CXL_HDM_DECODER0_BASE_HI + i * 0x20] = 0xffffffff;
142         write_msk[R_CXL_HDM_DECODER0_SIZE_LO + i * 0x20] = 0xf0000000;
143         write_msk[R_CXL_HDM_DECODER0_SIZE_HI + i * 0x20] = 0xffffffff;
144         write_msk[R_CXL_HDM_DECODER0_CTRL + i * 0x20] = 0x13ff;
145     }
146 }
147 
148 void cxl_component_register_init_common(uint32_t *reg_state, uint32_t *write_msk,
149                                         enum reg_type type)
150 {
151     int caps = 0;
152 
153     /*
154      * In CXL 2.0 the capabilities required for each CXL component are such that,
155      * with the ordering chosen here, a single number can be used to define
156      * which capabilities should be provided.
157      */
158     switch (type) {
159     case CXL2_DOWNSTREAM_PORT:
160     case CXL2_DEVICE:
161         /* RAS, Link */
162         caps = 2;
163         break;
164     case CXL2_UPSTREAM_PORT:
165     case CXL2_TYPE3_DEVICE:
166     case CXL2_LOGICAL_DEVICE:
167         /* + HDM */
168         caps = 3;
169         break;
170     case CXL2_ROOT_PORT:
171         /* + Extended Security, + Snoop */
172         caps = 5;
173         break;
174     default:
175         abort();
176     }
177 
178     memset(reg_state, 0, CXL2_COMPONENT_CM_REGION_SIZE);
179 
180     /* CXL Capability Header Register */
181     ARRAY_FIELD_DP32(reg_state, CXL_CAPABILITY_HEADER, ID, 1);
182     ARRAY_FIELD_DP32(reg_state, CXL_CAPABILITY_HEADER, VERSION, 1);
183     ARRAY_FIELD_DP32(reg_state, CXL_CAPABILITY_HEADER, CACHE_MEM_VERSION, 1);
184     ARRAY_FIELD_DP32(reg_state, CXL_CAPABILITY_HEADER, ARRAY_SIZE, caps);
185 
186 #define init_cap_reg(reg, id, version)                                        \
187     QEMU_BUILD_BUG_ON(CXL_##reg##_REGISTERS_OFFSET == 0);                     \
188     do {                                                                      \
189         int which = R_CXL_##reg##_CAPABILITY_HEADER;                          \
190         reg_state[which] = FIELD_DP32(reg_state[which],                       \
191                                       CXL_##reg##_CAPABILITY_HEADER, ID, id); \
192         reg_state[which] =                                                    \
193             FIELD_DP32(reg_state[which], CXL_##reg##_CAPABILITY_HEADER,       \
194                        VERSION, version);                                     \
195         reg_state[which] =                                                    \
196             FIELD_DP32(reg_state[which], CXL_##reg##_CAPABILITY_HEADER, PTR,  \
197                        CXL_##reg##_REGISTERS_OFFSET);                         \
198     } while (0)
199 
200     init_cap_reg(RAS, 2, 2);
201     ras_init_common(reg_state, write_msk);
202 
203     init_cap_reg(LINK, 4, 2);
204 
205     if (caps < 3) {
206         return;
207     }
208 
209     init_cap_reg(HDM, 5, 1);
210     hdm_init_common(reg_state, write_msk);
211 
212     if (caps < 5) {
213         return;
214     }
215 
216     init_cap_reg(EXTSEC, 6, 1);
217     init_cap_reg(SNOOP, 8, 1);
218 
219 #undef init_cap_reg
220 }
221 
222 /*
223  * Helper to creates a DVSEC header for a CXL entity. The caller is responsible
224  * for tracking the valid offset.
225  *
226  * This function will build the DVSEC header on behalf of the caller and then
227  * copy in the remaining data for the vendor specific bits.
228  * It will also set up appropriate write masks.
229  */
230 void cxl_component_create_dvsec(CXLComponentState *cxl,
231                                 enum reg_type cxl_dev_type, uint16_t length,
232                                 uint16_t type, uint8_t rev, uint8_t *body)
233 {
234     PCIDevice *pdev = cxl->pdev;
235     uint16_t offset = cxl->dvsec_offset;
236     uint8_t *wmask = pdev->wmask;
237 
238     assert(offset >= PCI_CFG_SPACE_SIZE &&
239            ((offset + length) < PCI_CFG_SPACE_EXP_SIZE));
240     assert((length & 0xf000) == 0);
241     assert((rev & ~0xf) == 0);
242 
243     /* Create the DVSEC in the MCFG space */
244     pcie_add_capability(pdev, PCI_EXT_CAP_ID_DVSEC, 1, offset, length);
245     pci_set_long(pdev->config + offset + PCIE_DVSEC_HEADER1_OFFSET,
246                  (length << 20) | (rev << 16) | CXL_VENDOR_ID);
247     pci_set_word(pdev->config + offset + PCIE_DVSEC_ID_OFFSET, type);
248     memcpy(pdev->config + offset + sizeof(DVSECHeader),
249            body + sizeof(DVSECHeader),
250            length - sizeof(DVSECHeader));
251 
252     /* Configure write masks */
253     switch (type) {
254     case PCIE_CXL_DEVICE_DVSEC:
255         break;
256     case NON_CXL_FUNCTION_MAP_DVSEC:
257         break; /* Not yet implemented */
258     case EXTENSIONS_PORT_DVSEC:
259         wmask[offset + offsetof(CXLDVSECPortExtensions, control)] = 0x0F;
260         wmask[offset + offsetof(CXLDVSECPortExtensions, control) + 1] = 0x40;
261         wmask[offset + offsetof(CXLDVSECPortExtensions, alt_bus_base)] = 0xFF;
262         wmask[offset + offsetof(CXLDVSECPortExtensions, alt_bus_limit)] = 0xFF;
263         wmask[offset + offsetof(CXLDVSECPortExtensions, alt_memory_base)] = 0xF0;
264         wmask[offset + offsetof(CXLDVSECPortExtensions, alt_memory_base) + 1] = 0xFF;
265         wmask[offset + offsetof(CXLDVSECPortExtensions, alt_memory_limit)] = 0xF0;
266         wmask[offset + offsetof(CXLDVSECPortExtensions, alt_memory_limit) + 1] = 0xFF;
267         wmask[offset + offsetof(CXLDVSECPortExtensions, alt_prefetch_base)] = 0xF0;
268         wmask[offset + offsetof(CXLDVSECPortExtensions, alt_prefetch_base) + 1] = 0xFF;
269         wmask[offset + offsetof(CXLDVSECPortExtensions, alt_prefetch_limit)] = 0xF0;
270         wmask[offset + offsetof(CXLDVSECPortExtensions, alt_prefetch_limit) + 1] = 0xFF;
271         wmask[offset + offsetof(CXLDVSECPortExtensions, alt_prefetch_base_high)] = 0xFF;
272         wmask[offset + offsetof(CXLDVSECPortExtensions, alt_prefetch_base_high) + 1] = 0xFF;
273         wmask[offset + offsetof(CXLDVSECPortExtensions, alt_prefetch_base_high) + 2] = 0xFF;
274         wmask[offset + offsetof(CXLDVSECPortExtensions, alt_prefetch_base_high) + 3] = 0xFF;
275         wmask[offset + offsetof(CXLDVSECPortExtensions, alt_prefetch_limit_high)] = 0xFF;
276         wmask[offset + offsetof(CXLDVSECPortExtensions, alt_prefetch_limit_high) + 1] = 0xFF;
277         wmask[offset + offsetof(CXLDVSECPortExtensions, alt_prefetch_limit_high) + 2] = 0xFF;
278         wmask[offset + offsetof(CXLDVSECPortExtensions, alt_prefetch_limit_high) + 3] = 0xFF;
279         break;
280     case GPF_PORT_DVSEC:
281         wmask[offset + offsetof(CXLDVSECPortGPF, phase1_ctrl)] = 0x0F;
282         wmask[offset + offsetof(CXLDVSECPortGPF, phase1_ctrl) + 1] = 0x0F;
283         wmask[offset + offsetof(CXLDVSECPortGPF, phase2_ctrl)] = 0x0F;
284         wmask[offset + offsetof(CXLDVSECPortGPF, phase2_ctrl) + 1] = 0x0F;
285         break;
286     case GPF_DEVICE_DVSEC:
287         wmask[offset + offsetof(CXLDVSECDeviceGPF, phase2_duration)] = 0x0F;
288         wmask[offset + offsetof(CXLDVSECDeviceGPF, phase2_duration) + 1] = 0x0F;
289         wmask[offset + offsetof(CXLDVSECDeviceGPF, phase2_power)] = 0xFF;
290         wmask[offset + offsetof(CXLDVSECDeviceGPF, phase2_power) + 1] = 0xFF;
291         wmask[offset + offsetof(CXLDVSECDeviceGPF, phase2_power) + 2] = 0xFF;
292         wmask[offset + offsetof(CXLDVSECDeviceGPF, phase2_power) + 3] = 0xFF;
293         break;
294     case PCIE_FLEXBUS_PORT_DVSEC:
295         switch (cxl_dev_type) {
296         case CXL2_ROOT_PORT:
297             /* No MLD */
298             wmask[offset + offsetof(CXLDVSECPortFlexBus, ctrl)] = 0xbd;
299             break;
300         case CXL2_DOWNSTREAM_PORT:
301             wmask[offset + offsetof(CXLDVSECPortFlexBus, ctrl)] = 0xfd;
302             break;
303         default: /* Registers are RO for other component types */
304             break;
305         }
306         /* There are rw1cs bits in the status register but never set currently */
307         break;
308     }
309 
310     /* Update state for future DVSEC additions */
311     range_init_nofail(&cxl->dvsecs[type], cxl->dvsec_offset, length);
312     cxl->dvsec_offset += length;
313 }
314