1 /* 2 * QEMU CXL PCI interfaces 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_PCI_H 11 #define CXL_PCI_H 12 13 #include "qemu/compiler.h" 14 #include "hw/pci/pci.h" 15 #include "hw/pci/pcie.h" 16 #include "hw/cxl/cxl_cdat.h" 17 18 #define CXL_VENDOR_ID 0x1e98 19 20 #define PCIE_DVSEC_HEADER1_OFFSET 0x4 /* Offset from start of extend cap */ 21 #define PCIE_DVSEC_ID_OFFSET 0x8 22 23 #define PCIE_CXL_DEVICE_DVSEC_LENGTH 0x38 24 #define PCIE_CXL1_DEVICE_DVSEC_REVID 0 25 #define PCIE_CXL2_DEVICE_DVSEC_REVID 1 26 27 #define EXTENSIONS_PORT_DVSEC_LENGTH 0x28 28 #define EXTENSIONS_PORT_DVSEC_REVID 0 29 30 #define GPF_PORT_DVSEC_LENGTH 0x10 31 #define GPF_PORT_DVSEC_REVID 0 32 33 #define GPF_DEVICE_DVSEC_LENGTH 0x10 34 #define GPF_DEVICE_DVSEC_REVID 0 35 36 #define PCIE_FLEXBUS_PORT_DVSEC_LENGTH_2_0 0x14 37 #define PCIE_FLEXBUS_PORT_DVSEC_REVID_2_0 1 38 39 #define REG_LOC_DVSEC_LENGTH 0x24 40 #define REG_LOC_DVSEC_REVID 0 41 42 enum { 43 PCIE_CXL_DEVICE_DVSEC = 0, 44 NON_CXL_FUNCTION_MAP_DVSEC = 2, 45 EXTENSIONS_PORT_DVSEC = 3, 46 GPF_PORT_DVSEC = 4, 47 GPF_DEVICE_DVSEC = 5, 48 PCIE_FLEXBUS_PORT_DVSEC = 7, 49 REG_LOC_DVSEC = 8, 50 MLD_DVSEC = 9, 51 CXL20_MAX_DVSEC 52 }; 53 54 typedef struct DVSECHeader { 55 uint32_t cap_hdr; 56 uint32_t dv_hdr1; 57 uint16_t dv_hdr2; 58 } QEMU_PACKED DVSECHeader; 59 QEMU_BUILD_BUG_ON(sizeof(DVSECHeader) != 10); 60 61 /* 62 * CXL 2.0 devices must implement certain DVSEC IDs, and can [optionally] 63 * implement others. 64 * 65 * CXL 2.0 Device: 0, [2], 5, 8 66 * CXL 2.0 RP: 3, 4, 7, 8 67 * CXL 2.0 Upstream Port: [2], 7, 8 68 * CXL 2.0 Downstream Port: 3, 4, 7, 8 69 */ 70 71 /* CXL 2.0 - 8.1.3 (ID 0001) */ 72 typedef struct CXLDVSECDevice { 73 DVSECHeader hdr; 74 uint16_t cap; 75 uint16_t ctrl; 76 uint16_t status; 77 uint16_t ctrl2; 78 uint16_t status2; 79 uint16_t lock; 80 uint16_t cap2; 81 uint32_t range1_size_hi; 82 uint32_t range1_size_lo; 83 uint32_t range1_base_hi; 84 uint32_t range1_base_lo; 85 uint32_t range2_size_hi; 86 uint32_t range2_size_lo; 87 uint32_t range2_base_hi; 88 uint32_t range2_base_lo; 89 } CXLDVSECDevice; 90 QEMU_BUILD_BUG_ON(sizeof(CXLDVSECDevice) != 0x38); 91 92 /* CXL 2.0 - 8.1.5 (ID 0003) */ 93 typedef struct CXLDVSECPortExtensions { 94 DVSECHeader hdr; 95 uint16_t status; 96 uint16_t control; 97 uint8_t alt_bus_base; 98 uint8_t alt_bus_limit; 99 uint16_t alt_memory_base; 100 uint16_t alt_memory_limit; 101 uint16_t alt_prefetch_base; 102 uint16_t alt_prefetch_limit; 103 uint32_t alt_prefetch_base_high; 104 uint32_t alt_prefetch_limit_high; 105 uint32_t rcrb_base; 106 uint32_t rcrb_base_high; 107 } CXLDVSECPortExtensions; 108 QEMU_BUILD_BUG_ON(sizeof(CXLDVSECPortExtensions) != 0x28); 109 110 #define PORT_CONTROL_OFFSET 0xc 111 #define PORT_CONTROL_UNMASK_SBR 1 112 #define PORT_CONTROL_ALT_MEMID_EN 4 113 114 /* CXL 2.0 - 8.1.6 GPF DVSEC (ID 0004) */ 115 typedef struct CXLDVSECPortGPF { 116 DVSECHeader hdr; 117 uint16_t rsvd; 118 uint16_t phase1_ctrl; 119 uint16_t phase2_ctrl; 120 } CXLDVSECPortGPF; 121 QEMU_BUILD_BUG_ON(sizeof(CXLDVSECPortGPF) != 0x10); 122 123 /* CXL 2.0 - 8.1.7 GPF DVSEC for CXL Device */ 124 typedef struct CXLDVSECDeviceGPF { 125 DVSECHeader hdr; 126 uint16_t phase2_duration; 127 uint32_t phase2_power; 128 } CXLDVSECDeviceGPF; 129 QEMU_BUILD_BUG_ON(sizeof(CXLDVSECDeviceGPF) != 0x10); 130 131 /* CXL 2.0 - 8.1.8/8.2.1.3 Flex Bus DVSEC (ID 0007) */ 132 typedef struct CXLDVSECPortFlexBus { 133 DVSECHeader hdr; 134 uint16_t cap; 135 uint16_t ctrl; 136 uint16_t status; 137 uint32_t rcvd_mod_ts_data_phase1; 138 } CXLDVSECPortFlexBus; 139 QEMU_BUILD_BUG_ON(sizeof(CXLDVSECPortFlexBus) != 0x14); 140 141 /* CXL 2.0 - 8.1.9 Register Locator DVSEC (ID 0008) */ 142 typedef struct CXLDVSECRegisterLocator { 143 DVSECHeader hdr; 144 uint16_t rsvd; 145 uint32_t reg0_base_lo; 146 uint32_t reg0_base_hi; 147 uint32_t reg1_base_lo; 148 uint32_t reg1_base_hi; 149 uint32_t reg2_base_lo; 150 uint32_t reg2_base_hi; 151 } CXLDVSECRegisterLocator; 152 QEMU_BUILD_BUG_ON(sizeof(CXLDVSECRegisterLocator) != 0x24); 153 154 /* BAR Equivalence Indicator */ 155 #define BEI_BAR_10H 0 156 #define BEI_BAR_14H 1 157 #define BEI_BAR_18H 2 158 #define BEI_BAR_1cH 3 159 #define BEI_BAR_20H 4 160 #define BEI_BAR_24H 5 161 162 /* Register Block Identifier */ 163 #define RBI_EMPTY 0 164 #define RBI_COMPONENT_REG (1 << 8) 165 #define RBI_BAR_VIRT_ACL (2 << 8) 166 #define RBI_CXL_DEVICE_REG (3 << 8) 167 168 #endif 169