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