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 2023 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 #include <sys/amdzen/df.h> 26 27 #include "amdzen_client.h" 28 29 /* 30 * This header describes properties of the data fabric and our internal state 31 * for the Zen Nexus driver. 32 */ 33 34 #ifdef __cplusplus 35 extern "C" { 36 #endif 37 38 /* 39 * The data fabric devices are always defined to be on PCI bus zero starting at 40 * device 0x18. 41 */ 42 #define AMDZEN_DF_BUSNO 0x00 43 #define AMDZEN_DF_FIRST_DEVICE 0x18 44 45 /* 46 * The maximum amount of Data Fabric node's we can see. In Zen 1 there were up 47 * to four per package. 48 */ 49 #define AMDZEN_MAX_DFS 0x8 50 51 /* 52 * The maximum number of PCI functions we expect to encounter on the data 53 * fabric. 54 */ 55 #define AMDZEN_MAX_DF_FUNCS 0x8 56 57 /* 58 * Northbridge registers that are relevant for the nexus, mostly for SMN. 59 */ 60 #define AMDZEN_NB_SMN_ADDR 0x60 61 #define AMDZEN_NB_SMN_DATA 0x64 62 63 /* 64 * AMD PCI ID for reference 65 */ 66 #define AMDZEN_PCI_VID_AMD 0x1022 67 68 /* 69 * Hygon PCI ID for reference 70 */ 71 #define AMDZEN_PCI_VID_HYGON 0x1d94 72 73 typedef enum { 74 AMDZEN_STUB_TYPE_DF, 75 AMDZEN_STUB_TYPE_NB 76 } amdzen_stub_type_t; 77 78 typedef struct { 79 list_node_t azns_link; 80 dev_info_t *azns_dip; 81 uint16_t azns_vid; 82 uint16_t azns_did; 83 uint16_t azns_bus; 84 uint16_t azns_dev; 85 uint16_t azns_func; 86 ddi_acc_handle_t azns_cfgspace; 87 } amdzen_stub_t; 88 89 typedef enum { 90 AMDZEN_DFE_F_MCA = 1 << 0, 91 AMDZEN_DFE_F_ENABLED = 1 << 1, 92 AMDZEN_DFE_F_DATA_VALID = 1 << 2 93 } amdzen_df_ent_flags_t; 94 95 /* 96 * Data specific to a CCM. 97 */ 98 typedef struct { 99 uint32_t acd_nccds; 100 uint8_t acd_ccd_en[DF_MAX_CCDS_PER_CCM]; 101 uint32_t acd_ccd_id[DF_MAX_CCDS_PER_CCM]; 102 void *acd_ccd_data[DF_MAX_CCDS_PER_CCM]; 103 } amdzen_ccm_data_t; 104 105 typedef union { 106 amdzen_ccm_data_t aded_ccm; 107 } amdzen_df_ent_data_t; 108 109 typedef struct { 110 uint8_t adfe_drvid; 111 amdzen_df_ent_flags_t adfe_flags; 112 df_type_t adfe_type; 113 uint8_t adfe_subtype; 114 uint8_t adfe_fabric_id; 115 uint8_t adfe_inst_id; 116 uint32_t adfe_info0; 117 uint32_t adfe_info1; 118 uint32_t adfe_info2; 119 uint32_t adfe_info3; 120 amdzen_df_ent_data_t adfe_data; 121 } amdzen_df_ent_t; 122 123 typedef enum { 124 AMDZEN_DF_F_VALID = 1 << 0, 125 AMDZEN_DF_F_FOUND_NB = 1 << 1, 126 } amdzen_df_flags_t; 127 128 typedef struct { 129 amdzen_df_flags_t adf_flags; 130 uint_t adf_nb_busno; 131 amdzen_stub_t *adf_funcs[AMDZEN_MAX_DF_FUNCS]; 132 amdzen_stub_t *adf_nb; 133 uint8_t adf_major; 134 uint8_t adf_minor; 135 uint_t adf_nents; 136 df_rev_t adf_rev; 137 amdzen_df_ent_t *adf_ents; 138 uint32_t adf_nodeid; 139 uint32_t adf_syscfg; 140 uint32_t adf_mask0; 141 uint32_t adf_mask1; 142 uint32_t adf_mask2; 143 uint32_t adf_nccm; 144 df_fabric_decomp_t adf_decomp; 145 } amdzen_df_t; 146 147 typedef enum { 148 AMDZEN_F_UNSUPPORTED = 1 << 0, 149 AMDZEN_F_DEVICE_ERROR = 1 << 1, 150 AMDZEN_F_MAP_ERROR = 1 << 2, 151 AMDZEN_F_SCAN_DISPATCHED = 1 << 3, 152 AMDZEN_F_SCAN_COMPLETE = 1 << 4, 153 AMDZEN_F_ATTACH_DISPATCHED = 1 << 5, 154 AMDZEN_F_ATTACH_COMPLETE = 1 << 6, 155 AMDZEN_F_APIC_DECOMP_VALID = 1 << 7 156 } amdzen_flags_t; 157 158 #define AMDZEN_F_TASKQ_MASK (AMDZEN_F_SCAN_DISPATCHED | \ 159 AMDZEN_F_SCAN_COMPLETE | AMDZEN_F_ATTACH_DISPATCHED | \ 160 AMDZEN_F_ATTACH_COMPLETE) 161 162 /* 163 * These are the set of flags we want to consider when determining whether or 164 * not we're OK for receiving topo ioctls. 165 */ 166 #define AMDZEN_F_IOCTL_MASK (AMDZEN_F_UNSUPPORTED | \ 167 AMDZEN_F_DEVICE_ERROR | AMDZEN_F_MAP_ERROR | AMDZEN_F_ATTACH_COMPLETE) 168 169 typedef struct amdzen { 170 kmutex_t azn_mutex; 171 kcondvar_t azn_cv; 172 amdzen_flags_t azn_flags; 173 dev_info_t *azn_dip; 174 taskqid_t azn_taskqid; 175 uint_t azn_nscanned; 176 uint_t azn_npresent; 177 list_t azn_df_stubs; 178 list_t azn_nb_stubs; 179 uint_t azn_ndfs; 180 amdzen_df_t azn_dfs[AMDZEN_MAX_DFS]; 181 uint32_t azn_ncore_per_ccx; 182 amdzen_apic_decomp_t azn_apic_decomp; 183 } amdzen_t; 184 185 typedef enum { 186 AMDZEN_C_SMNTEMP = 1, 187 AMDZEN_C_USMN, 188 AMDZEN_C_ZEN_UDF, 189 AMDZEN_C_ZEN_UMC 190 } amdzen_child_t; 191 192 /* 193 * Functions for stubs. 194 */ 195 extern int amdzen_attach_stub(dev_info_t *, ddi_attach_cmd_t); 196 extern int amdzen_detach_stub(dev_info_t *, ddi_detach_cmd_t); 197 198 #ifdef __cplusplus 199 } 200 #endif 201 202 #endif /* _AMDZEN_H */ 203