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.
10 #ifndef CXL_COMPONENT_H
11 #define CXL_COMPONENT_H
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/compiler.h"
19 #include "qemu/range.h"
20 #include "qemu/typedefs.h"
21 #include "hw/register.h"
22 #include "qapi/error.h"
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
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 REG32(CXL_RAS_UNC_ERR_MASK
, CXL_RAS_REGISTERS_OFFSET
+ 0x4)
70 REG32(CXL_RAS_UNC_ERR_SEVERITY
, CXL_RAS_REGISTERS_OFFSET
+ 0x8)
71 REG32(CXL_RAS_COR_ERR_STATUS
, CXL_RAS_REGISTERS_OFFSET
+ 0xc)
72 REG32(CXL_RAS_COR_ERR_MASK
, CXL_RAS_REGISTERS_OFFSET
+ 0x10)
73 REG32(CXL_RAS_ERR_CAP_CTRL
, CXL_RAS_REGISTERS_OFFSET
+ 0x14)
74 /* Offset 0x18 - 0x58 reserved for RAS logs */
76 /* 8.2.5.10 - CXL Security Capability Structure */
77 #define CXL_SEC_REGISTERS_OFFSET \
78 (CXL_RAS_REGISTERS_OFFSET + CXL_RAS_REGISTERS_SIZE)
79 #define CXL_SEC_REGISTERS_SIZE 0 /* We don't implement 1.1 downstream ports */
81 /* 8.2.5.11 - CXL Link Capability Structure */
82 #define CXL_LINK_REGISTERS_OFFSET \
83 (CXL_SEC_REGISTERS_OFFSET + CXL_SEC_REGISTERS_SIZE)
84 #define CXL_LINK_REGISTERS_SIZE 0x38
86 /* 8.2.5.12 - CXL HDM Decoder Capability Structure */
87 #define HDM_DECODE_MAX 10 /* 8.2.5.12.1 */
88 #define CXL_HDM_REGISTERS_OFFSET \
89 (CXL_LINK_REGISTERS_OFFSET + CXL_LINK_REGISTERS_SIZE)
90 #define CXL_HDM_REGISTERS_SIZE (0x10 + 0x20 * HDM_DECODE_MAX)
91 #define HDM_DECODER_INIT(n) \
92 REG32(CXL_HDM_DECODER##n##_BASE_LO, \
93 CXL_HDM_REGISTERS_OFFSET + (0x20 * n) + 0x10) \
94 FIELD(CXL_HDM_DECODER##n##_BASE_LO, L, 28, 4) \
95 REG32(CXL_HDM_DECODER##n##_BASE_HI, \
96 CXL_HDM_REGISTERS_OFFSET + (0x20 * n) + 0x14) \
97 REG32(CXL_HDM_DECODER##n##_SIZE_LO, \
98 CXL_HDM_REGISTERS_OFFSET + (0x20 * n) + 0x18) \
99 REG32(CXL_HDM_DECODER##n##_SIZE_HI, \
100 CXL_HDM_REGISTERS_OFFSET + (0x20 * n) + 0x1C) \
101 REG32(CXL_HDM_DECODER##n##_CTRL, \
102 CXL_HDM_REGISTERS_OFFSET + (0x20 * n) + 0x20) \
103 FIELD(CXL_HDM_DECODER##n##_CTRL, IG, 0, 4) \
104 FIELD(CXL_HDM_DECODER##n##_CTRL, IW, 4, 4) \
105 FIELD(CXL_HDM_DECODER##n##_CTRL, LOCK_ON_COMMIT, 8, 1) \
106 FIELD(CXL_HDM_DECODER##n##_CTRL, COMMIT, 9, 1) \
107 FIELD(CXL_HDM_DECODER##n##_CTRL, COMMITTED, 10, 1) \
108 FIELD(CXL_HDM_DECODER##n##_CTRL, ERR, 11, 1) \
109 FIELD(CXL_HDM_DECODER##n##_CTRL, TYPE, 12, 1) \
110 REG32(CXL_HDM_DECODER##n##_TARGET_LIST_LO, \
111 CXL_HDM_REGISTERS_OFFSET + (0x20 * n) + 0x24) \
112 REG32(CXL_HDM_DECODER##n##_TARGET_LIST_HI, \
113 CXL_HDM_REGISTERS_OFFSET + (0x20 * n) + 0x28)
115 REG32(CXL_HDM_DECODER_CAPABILITY
, CXL_HDM_REGISTERS_OFFSET
)
116 FIELD(CXL_HDM_DECODER_CAPABILITY
, DECODER_COUNT
, 0, 4)
117 FIELD(CXL_HDM_DECODER_CAPABILITY
, TARGET_COUNT
, 4, 4)
118 FIELD(CXL_HDM_DECODER_CAPABILITY
, INTERLEAVE_256B
, 8, 1)
119 FIELD(CXL_HDM_DECODER_CAPABILITY
, INTERLEAVE_4K
, 9, 1)
120 FIELD(CXL_HDM_DECODER_CAPABILITY
, POISON_ON_ERR_CAP
, 10, 1)
121 REG32(CXL_HDM_DECODER_GLOBAL_CONTROL
, CXL_HDM_REGISTERS_OFFSET
+ 4)
122 FIELD(CXL_HDM_DECODER_GLOBAL_CONTROL
, POISON_ON_ERR_EN
, 0, 1)
123 FIELD(CXL_HDM_DECODER_GLOBAL_CONTROL
, HDM_DECODER_ENABLE
, 1, 1)
127 /* 8.2.5.13 - CXL Extended Security Capability Structure (Root complex only) */
128 #define EXTSEC_ENTRY_MAX 256
129 #define CXL_EXTSEC_REGISTERS_OFFSET \
130 (CXL_HDM_REGISTERS_OFFSET + CXL_HDM_REGISTERS_SIZE)
131 #define CXL_EXTSEC_REGISTERS_SIZE (8 * EXTSEC_ENTRY_MAX + 4)
133 /* 8.2.5.14 - CXL IDE Capability Structure */
134 #define CXL_IDE_REGISTERS_OFFSET \
135 (CXL_EXTSEC_REGISTERS_OFFSET + CXL_EXTSEC_REGISTERS_SIZE)
136 #define CXL_IDE_REGISTERS_SIZE 0x20
138 /* 8.2.5.15 - CXL Snoop Filter Capability Structure */
139 #define CXL_SNOOP_REGISTERS_OFFSET \
140 (CXL_IDE_REGISTERS_OFFSET + CXL_IDE_REGISTERS_SIZE)
141 #define CXL_SNOOP_REGISTERS_SIZE 0x8
143 QEMU_BUILD_BUG_MSG((CXL_SNOOP_REGISTERS_OFFSET
+ CXL_SNOOP_REGISTERS_SIZE
) >= 0x1000,
144 "No space for registers");
146 typedef struct component_registers
{
148 * Main memory region to be registered with QEMU core.
150 MemoryRegion component_registers
;
154 * 0x0000 - 0x0fff CXL.io registers
155 * 0x1000 - 0x1fff CXL.cache and CXL.mem
156 * 0x2000 - 0xdfff Implementation specific
157 * 0xe000 - 0xe3ff CXL ARB/MUX registers
158 * 0xe400 - 0xffff RSVD
160 uint32_t io_registers
[CXL2_COMPONENT_IO_REGION_SIZE
>> 2];
163 uint32_t cache_mem_registers
[CXL2_COMPONENT_CM_REGION_SIZE
>> 2];
164 uint32_t cache_mem_regs_write_mask
[CXL2_COMPONENT_CM_REGION_SIZE
>> 2];
165 MemoryRegion cache_mem
;
167 MemoryRegion impl_specific
;
168 MemoryRegion arb_mux
;
171 /* special_ops is used for any component that needs any specific handling */
172 MemoryRegionOps
*special_ops
;
173 } ComponentRegisters
;
176 * A CXL component represents all entities in a CXL hierarchy. This includes,
177 * host bridges, root ports, upstream/downstream switch ports, and devices
179 typedef struct cxl_component
{
180 ComponentRegisters crb
;
183 Range dvsecs
[CXL20_MAX_DVSEC
];
184 uint16_t dvsec_offset
;
185 struct PCIDevice
*pdev
;
192 void cxl_component_register_block_init(Object
*obj
,
193 CXLComponentState
*cxl_cstate
,
195 void cxl_component_register_init_common(uint32_t *reg_state
,
199 void cxl_component_create_dvsec(CXLComponentState
*cxl_cstate
,
200 enum reg_type cxl_dev_type
, uint16_t length
,
201 uint16_t type
, uint8_t rev
, uint8_t *body
);
203 static inline int cxl_decoder_count_enc(int count
)
216 uint8_t cxl_interleave_ways_enc(int iw
, Error
**errp
);
217 uint8_t cxl_interleave_granularity_enc(uint64_t gran
, Error
**errp
);
219 static inline hwaddr
cxl_decode_ig(int ig
)
221 return 1ULL << (ig
+ 8);
224 CXLComponentState
*cxl_get_hb_cstate(PCIHostState
*hb
);
226 void cxl_doe_cdat_init(CXLComponentState
*cxl_cstate
, Error
**errp
);
227 void cxl_doe_cdat_release(CXLComponentState
*cxl_cstate
);
228 void cxl_doe_cdat_update(CXLComponentState
*cxl_cstate
, Error
**errp
);