1 /* 2 * This file and its contents are supplied under the terms of the 3 * Common Development and Distribution License ("CDDL"), version 1.0. 4 * You may only use this file in accordance with the terms of version 5 * 1.0 of the CDDL. 6 * 7 * A full copy of the text of the CDDL should have accompanied this 8 * source. A copy of the CDDL is also available via the Internet at 9 * http://www.illumos.org/license/CDDL. 10 */ 11 12 /* 13 * Copyright 2020 Oxide Computer Company 14 */ 15 16 #ifndef _AMDZEN_H 17 #define _AMDZEN_H 18 19 #include <sys/ddi.h> 20 #include <sys/sunddi.h> 21 #include <sys/list.h> 22 #include <sys/pci.h> 23 #include <sys/taskq.h> 24 #include <sys/bitmap.h> 25 26 /* 27 * This header describes properties of the data fabric and our internal state 28 * for the Zen Nexus driver. 29 */ 30 31 #ifdef __cplusplus 32 extern "C" { 33 #endif 34 35 /* 36 * The data fabric devices are always defined to be on PCI bus zero starting at 37 * device 0x18. 38 */ 39 #define AMDZEN_DF_BUSNO 0x00 40 #define AMDZEN_DF_FIRST_DEVICE 0x18 41 42 /* 43 * The maximum amount of Data Fabric node's we can see. In Zen 1 there were up 44 * to four per package. 45 */ 46 #define AMDZEN_MAX_DFS 0x8 47 48 /* 49 * The maximum number of PCI functions we expect to encounter on the data 50 * fabric. 51 */ 52 #define AMDZEN_MAX_DF_FUNCS 0x8 53 54 55 /* 56 * Registers in the data fabric space that we care about for the purposes of the 57 * nexus driver understanding itself. 58 */ 59 60 /* 61 * This set of registers provides us access to the count of instances in the 62 * data fabric and then a number of different pieces of information about them 63 * like their type. Note, these registers require indirect access because the 64 * information cannot be broadcast. 65 */ 66 #define AMDZEN_DF_F0_FBICNT 0x40 67 #define AMDZEN_DF_F0_FBICNT_COUNT(x) BITX(x, 7, 0) 68 #define AMDZEN_DF_F0_FBIINFO0 0x44 69 #define AMDZEN_DF_F0_FBIINFO0_TYPE(x) BITX(x, 3, 0) 70 typedef enum { 71 AMDZEN_DF_TYPE_CCM = 0, 72 AMDZEN_DF_TYPE_GCM, 73 AMDZEN_DF_TYPE_NCM, 74 AMDZEN_DF_TYPE_IOMS, 75 AMDZEN_DF_TYPE_CS, 76 AMDZEN_DF_TYPE_TCDX, 77 AMDZEN_DF_TYPE_PIE, 78 AMDZEN_DF_TYPE_SPF, 79 AMDZEN_DF_TYPE_LLC, 80 AMDZEN_DF_TYPE_CAKE 81 } amdzen_df_type_t; 82 #define AMDZEN_DF_F0_FBIINFO0_SDP_WIDTH(x) BITX(x, 5, 4) 83 typedef enum { 84 AMDZEN_DF_SDP_W_64 = 0, 85 AMDZEN_DF_SDP_W_128, 86 AMDZEN_DF_SDP_W_256, 87 AMDZEN_DF_SDP_W_512 88 } amdzen_df_sdp_width_t; 89 #define AMDZEN_DF_F0_FBIINFO0_ENABLED(x) BITX(x, 6, 6) 90 #define AMDZEN_DF_F0_FBIINFO0_FTI_WIDTH(x) BITX(x, 9, 8) 91 typedef enum { 92 AMDZEN_DF_FTI_W_64 = 0, 93 AMDZEN_DF_FTI_W_128, 94 AMDZEN_DF_FTI_W_256, 95 AMDZEN_DF_FTI_W_512 96 } amdzen_df_fti_width_t; 97 #define AMDZEN_DF_F0_FBIINFO0_SDP_PCOUNT(x) BITX(x, 13, 12) 98 #define AMDZEN_DF_F0_FBIINFO0_FTI_PCOUNT(x) BITX(x, 18, 16) 99 #define AMDZEN_DF_F0_FBIINFO0_HAS_MCA(x) BITX(x, 23, 23) 100 #define AMDZEN_DF_F0_FBIINFO0_SUBTYPE(x) BITX(x, 26, 24) 101 #define AMDZEN_DF_SUBTYPE_NONE 0 102 typedef enum { 103 AMDZEN_DF_CAKE_SUBTYPE_GMI = 1, 104 AMDZEN_DF_CAKE_SUBTYPE_xGMI = 2 105 } amdzen_df_cake_subtype_t; 106 107 typedef enum { 108 AMDZEN_DF_IOM_SUBTYPE_IOHUB = 1, 109 } amdzen_df_iom_subtype_t; 110 111 typedef enum { 112 AMDZEN_DF_CS_SUBTYPE_UMC = 1, 113 AMDZEN_DF_CS_SUBTYPE_CCIX = 2 114 } amdzen_df_cs_subtype_t; 115 116 #define AMDZEN_DF_F0_FBIINFO1 0x48 117 #define AMDZEN_DF_F0_FBIINFO1_FTI0_NINSTID(x) BITX(x, 7, 0) 118 #define AMDZEN_DF_F0_FBIINFO1_FTI1_NINSTID(x) BITX(x, 15, 8) 119 #define AMDZEN_DF_F0_FBIINFO1_FTI2_NINSTID(x) BITX(x, 23, 16) 120 #define AMDZEN_DF_F0_FBIINFO1_FTI3_NINSTID(x) BITX(x, 31, 24) 121 #define AMDZEN_DF_F0_FBIINFO2 0x4c 122 #define AMDZEN_DF_F0_FBIINFO2_FTI4_NINSTID(x) BITX(x, 7, 0) 123 #define AMDZEN_DF_F0_FBIINFO2_FTI5_NINSTID(x) BITX(x, 15, 8) 124 #define AMDZEN_DF_F0_FBIINFO3 0x50 125 #define AMDZEN_DF_F0_FBIINFO3_INSTID(x) BITX(x, 7, 0) 126 #define AMDZEN_DF_F0_FBIINFO3_FABID(x) BITX(x, 13, 8) 127 128 /* 129 * This register contains the information about the configuration of PCIe buses. 130 * We care about finding which one has our BUS A, which is required to map it to 131 * the northbridge. 132 */ 133 #define AMDZEN_DF_F0_CFG_ADDR_CTL 0x84 134 #define AMDZEN_DF_F0_CFG_ADDR_CTL_BUS_NUM(x) BITX(x, 7, 0) 135 136 /* 137 * Registers that describe how the system is actually put together. 138 */ 139 #define AMDZEN_DF_F1_SYSCFG 0x200 140 #define AMDZEN_DF_F1_SYSCFG_DIE_PRESENT(X) BITX(x, 7, 0) 141 #define AMDZEN_DF_F1_SYSCFG_DIE_TYPE(x) BITX(x, 18, 11) 142 #define AMDZEN_DF_F1_SYSCFG_MYDIE_TYPE(x) BITX(x, 24, 23) 143 typedef enum { 144 AMDZEN_DF_DIE_TYPE_CPU = 0, 145 AMDZEN_DF_DIE_TYPE_APU, 146 AMDZEN_DF_DIE_TYPE_dGPU 147 } amdzen_df_die_type_t; 148 #define AMDZEN_DF_F1_SYSCFG_OTHERDIE_TYPE(x) BITX(x, 26, 25) 149 #define AMDZEN_DF_F1_SYSCFG_OTHERSOCK(x) BITX(x, 27, 27) 150 #define AMDZEN_DF_F1_SYSCFG_NODEID(x) BITX(x, 30, 28) 151 152 #define AMDZEN_DF_F1_FIDMASK0 0x208 153 #define AMDZEN_DF_F1_FIDMASK0_COMP_MASK(x) BITX(x, 9, 0) 154 #define AMDZEN_DF_F1_FIDMASK0_NODE_MASK(x) BITX(x, 25, 16) 155 #define AMDZEN_DF_F1_FIDMASK1 0x20C 156 #define AMDZEN_DF_F1_FIDMASK1_NODE_SHIFT(x) BITX(x, 3, 0) 157 #define AMDZEN_DF_F1_FIDMASK1_SKT_SHIFT(x) BITX(x, 9, 8) 158 #define AMDZEN_DF_F1_FIDMASK1_DIE_MASK(x) BITX(x, 18, 16) 159 #define AMDZEN_DF_F1_FIDMASK1_SKT_MASK(x) BITX(x, 26, 24) 160 161 /* 162 * These two registers define information about the PSP and SMU on local and 163 * remote dies (from the context of the DF instance). The bits are the same. 164 */ 165 #define AMDZEN_DF_F1_PSPSMU_LOCAL 0x268 166 #define AMDZEN_DF_F1_PSPSMU_REMOTE 0x268 167 #define AMDZEN_DF_F1_PSPSMU_SMU_VALID(x) BITX(x, 0, 0) 168 #define AMDZEN_DF_F1_PSPSMU_SMU_UNITID(x) BITX(x, 6, 1) 169 #define AMDZEN_DF_F1_PSPSMU_SMU_COMPID(x) BITX(x, 15, 8) 170 #define AMDZEN_DF_F1_PSPSMU_PSP_VALID(x) BITX(x, 16, 16) 171 #define AMDZEN_DF_F1_PSPSMU_PSP_UNITID(x) BITX(x, 22, 17) 172 #define AMDZEN_DF_F1_PSPSMU_PSP_COMPID(x) BITX(x, 31, 24) 173 174 #define AMDZEN_DF_F1_CAKE_ENCR 0x2cc 175 176 /* 177 * These registers are used to define Indirect Access, commonly known as FICAA 178 * and FICAD for the system. While there are multiple copies of the indirect 179 * access registers in device 4, we're only allowed access to one set of those 180 * (which are the ones present here). Specifically the OS is given access to set 181 * 3. 182 */ 183 #define AMDZEN_DF_F4_FICAA 0x5c 184 #define AMDZEN_DF_F4_FICAA_TARG_INST (1 << 0) 185 #define AMDZEN_DF_F4_FICAA_SET_REG(x) ((x) & 0x3fc) 186 #define AMDZEN_DF_F4_FICAA_SET_FUNC(x) (((x) & 0x7) << 11) 187 #define AMDZEN_DF_F4_FICAA_SET_64B (1 << 14) 188 #define AMDZEN_DF_F4_FICAA_SET_INST(x) (((x) & 0xff) << 16) 189 #define AMDZEN_DF_F4_FICAD_LO 0x98 190 #define AMDZEN_DF_F4_FICAD_HI 0x9c 191 192 /* 193 * Northbridge registers that are relevant for the nexus, mostly for SMN. 194 */ 195 #define AMDZEN_NB_SMN_ADDR 0x60 196 #define AMDZEN_NB_SMN_DATA 0x64 197 198 /* 199 * AMD PCI ID for reference 200 */ 201 #define AMDZEN_PCI_VID_AMD 0x1022 202 203 /* 204 * Hygon PCI ID for reference 205 */ 206 #define AMDZEN_PCI_VID_HYGON 0x1d94 207 208 typedef enum { 209 AMDZEN_STUB_TYPE_DF, 210 AMDZEN_STUB_TYPE_NB 211 } amdzen_stub_type_t; 212 213 typedef struct { 214 list_node_t azns_link; 215 dev_info_t *azns_dip; 216 uint16_t azns_vid; 217 uint16_t azns_did; 218 uint16_t azns_bus; 219 uint16_t azns_dev; 220 uint16_t azns_func; 221 ddi_acc_handle_t azns_cfgspace; 222 } amdzen_stub_t; 223 224 typedef enum { 225 AMDZEN_DFE_F_MCA = 1 << 0, 226 AMDZEN_DFE_F_ENABLED = 1 << 1 227 } amdzen_df_ent_flags_t; 228 229 typedef struct { 230 uint8_t adfe_drvid; 231 amdzen_df_ent_flags_t adfe_flags; 232 amdzen_df_type_t adfe_type; 233 uint8_t adfe_subtype; 234 uint8_t adfe_fabric_id; 235 uint8_t adfe_inst_id; 236 amdzen_df_sdp_width_t adfe_sdp_width; 237 amdzen_df_fti_width_t adfe_fti_width; 238 uint8_t adfe_sdp_count; 239 uint8_t adfe_fti_count; 240 uint32_t adfe_info0; 241 uint32_t adfe_info1; 242 uint32_t adfe_info2; 243 uint32_t adfe_info3; 244 uint32_t adfe_syscfg; 245 uint32_t adfe_mask0; 246 uint32_t adfe_mask1; 247 } amdzen_df_ent_t; 248 249 typedef enum { 250 AMDZEN_DF_F_VALID = 1 << 0, 251 AMDZEN_DF_F_FOUND_NB = 1 << 1 252 } amdzen_df_flags_t; 253 254 typedef struct { 255 amdzen_df_flags_t adf_flags; 256 uint_t adf_nb_busno; 257 amdzen_stub_t *adf_funcs[AMDZEN_MAX_DF_FUNCS]; 258 amdzen_stub_t *adf_nb; 259 uint_t adf_nents; 260 amdzen_df_ent_t *adf_ents; 261 uint32_t adf_nodeid; 262 uint32_t adf_syscfg; 263 uint32_t adf_mask0; 264 uint32_t adf_mask1; 265 } amdzen_df_t; 266 267 typedef enum { 268 AMDZEN_F_UNSUPPORTED = 1 << 0, 269 AMDZEN_F_DEVICE_ERROR = 1 << 1, 270 AMDZEN_F_MAP_ERROR = 1 << 2, 271 AMDZEN_F_SCAN_DISPATCHED = 1 << 3, 272 AMDZEN_F_SCAN_COMPLETE = 1 << 4, 273 AMDZEN_F_ATTACH_DISPATCHED = 1 << 5, 274 AMDZEN_F_ATTACH_COMPLETE = 1 << 6 275 } amdzen_flags_t; 276 277 #define AMDZEN_F_TASKQ_MASK (AMDZEN_F_SCAN_DISPATCHED | \ 278 AMDZEN_F_SCAN_COMPLETE | AMDZEN_F_ATTACH_DISPATCHED | \ 279 AMDZEN_F_ATTACH_COMPLETE) 280 281 typedef struct amdzen { 282 kmutex_t azn_mutex; 283 kcondvar_t azn_cv; 284 amdzen_flags_t azn_flags; 285 dev_info_t *azn_dip; 286 taskqid_t azn_taskqid; 287 uint_t azn_nscanned; 288 uint_t azn_npresent; 289 list_t azn_df_stubs; 290 list_t azn_nb_stubs; 291 uint_t azn_ndfs; 292 amdzen_df_t azn_dfs[AMDZEN_MAX_DFS]; 293 } amdzen_t; 294 295 typedef enum { 296 AMDZEN_C_SMNTEMP = 1, 297 AMDZEN_C_USMN, 298 AMDZEN_C_ZEN_UDF 299 } amdzen_child_t; 300 301 /* 302 * Functions for stubs. 303 */ 304 extern int amdzen_attach_stub(dev_info_t *, ddi_attach_cmd_t); 305 extern int amdzen_detach_stub(dev_info_t *, ddi_detach_cmd_t); 306 307 #ifdef __cplusplus 308 } 309 #endif 310 311 #endif /* _AMDZEN_H */ 312