2
0

cxl_component.h 12 KB

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