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_TOPO_H 17 #define _AMDZEN_TOPO_H 18 19 #include "amdzen_client.h" 20 21 /* 22 * This contains the ioctl definitions for allowing and exploring access to the 23 * internal device topology of the Zen CPUs on the system. This ioctl interface 24 * is private and subject to change. 25 */ 26 27 #ifdef __cplusplus 28 extern "C" { 29 #endif 30 31 #define AMDZEN_TOPO_IOCTL (('z' << 24) | ('z' << 16) | ('t' << 8)) 32 33 /* 34 * Get base information about the system's present sockets and the DF 35 * configuration. Our current assumption is that even in a case where we have 36 * heterogeneous DF instances (like some of the DFv3.5 devices), then we'll need 37 * to revisit this structure and move the DF decomposition into the DF 38 * structure. 39 */ 40 #define AMDZEN_TOPO_IOCTL_BASE (AMDZEN_TOPO_IOCTL | 0x00) 41 typedef struct amdzen_topo_base { 42 uint32_t atb_ndf; 43 uint32_t atb_maxdfent; 44 df_rev_t atb_rev; 45 df_fabric_decomp_t atb_df_decomp; 46 amdzen_apic_decomp_t atb_apic_decomp; 47 } amdzen_topo_base_t; 48 49 /* 50 * Get information about a basic instance of the data fabric. If we're in a Zen 51 * 1 / DFv2 style environment, then this is a part of the underlying die. In a 52 * DFv3 (aka Zen 2+) then this represents a relatively coherent set of 53 * resources. Though there are some DFv3.5 parts that theoretically have two 54 * different types of DFs. 55 * 56 * We include all of the entities in the DF here as well. Note, that the types 57 * and subtypes are currently not normalized across DF generations and device 58 * families. 59 */ 60 #define AMDZEN_TOPO_IOCTL_DF (AMDZEN_TOPO_IOCTL | 0x01) 61 62 /* 63 * The current maximum number of peers is derived from the width of the bitfield 64 * in the data fabric. 65 */ 66 #define AMDZEN_TOPO_DF_MAX_PEERS 8 67 68 typedef struct amdzen_topo_ccm_data { 69 uint32_t atcd_nccds; 70 uint32_t atcd_ccd_en[DF_MAX_CCDS_PER_CCM]; 71 uint32_t atcd_ccd_ids[DF_MAX_CCDS_PER_CCM]; 72 } amdzen_topo_ccm_data_t; 73 74 typedef union amdzen_topo_df_data { 75 amdzen_topo_ccm_data_t atded_ccm; 76 } amdzen_topo_df_data_t; 77 78 typedef struct amdzen_topo_df_ent { 79 df_type_t atde_type; 80 uint8_t atde_subtype; 81 uint8_t atde_fabric_id; 82 uint8_t atde_inst_id; 83 uint8_t atde_npeers; 84 uint8_t atde_peers[AMDZEN_TOPO_DF_MAX_PEERS]; 85 amdzen_topo_df_data_t atde_data; 86 } amdzen_topo_df_ent_t; 87 88 typedef struct amdzen_topo_df { 89 /* 90 * Users specify the DF number which is in the range from 0 to the 91 * number of DFs specified in the amdzen_topo_base_t. The nodeid and its 92 * corresponding decomposed socket and die IDs will all be filled in. 93 */ 94 uint32_t atd_dfno; 95 uint32_t atd_nodeid; 96 uint32_t atd_sockid; 97 uint32_t atd_dieid; 98 df_rev_t atd_rev; 99 /* 100 * atd_ndf_buf_nents should be set to the size of the number of DF 101 * entries that are present in atd_df_ents. atd_ndf_buf_valid will 102 * determine the number of entries that are considered valid in the 103 * resulting array. atd_ndf_act_nents is the total number of entries 104 * that are present in the underlying DF. Setting atd_ndf_buf_nents to 105 * atb_maxdfent will ensure that we can obtain everything. 106 */ 107 uint32_t atd_df_buf_nents; 108 uint32_t atd_df_buf_nvalid; 109 uint32_t atd_df_act_nents; 110 amdzen_topo_df_ent_t *atd_df_ents; 111 } amdzen_topo_df_t; 112 113 #ifdef _KERNEL 114 typedef struct { 115 uint32_t atd_dfno; 116 uint32_t atd_nodeid; 117 uint32_t atd_sockid; 118 uint32_t atd_dieid; 119 df_rev_t atd_rev; 120 uint32_t atd_df_buf_nents; 121 uint32_t atd_df_buf_nvalid; 122 uint32_t atd_df_act_nents; 123 caddr32_t atd_df_ents; 124 } amdzen_topo_df32_t; 125 #endif /* _KERNEL */ 126 127 /* 128 * This describes information about what is physically enabled for a given 129 * compute based CCM. This is only known for Zen 3+. Input is the DF number and 130 * the CCM's fabric ID. Information about the resulting CCXs, cores, and their 131 * logical and physical numbers is then returned. All data is sized in terms of 132 * uint32_t's to try and keep the data independent of the model (i.e. ILP32 vs. 133 * LP64). 134 * 135 * Note, the maximum numbers defined below are subject to change and ABI 136 * compatibility is not guaranteed. 137 */ 138 #define AMDZEN_TOPO_IOCTL_CCD (AMDZEN_TOPO_IOCTL | 0x02) 139 140 #define AMDZEN_TOPO_CORE_MAX_THREADS 2 141 #define AMDZEN_TOPO_CCX_MAX_CORES 8 142 #define AMDZEN_TOPO_CCD_MAX_CCX 2 143 144 typedef struct amdzen_topo_core { 145 uint32_t atcore_log_no; 146 uint32_t atcore_phys_no; 147 uint32_t atcore_nthreads; 148 uint32_t atcore_thr_en[AMDZEN_TOPO_CORE_MAX_THREADS]; 149 uint32_t atcore_apicids[AMDZEN_TOPO_CORE_MAX_THREADS]; 150 } amdzen_topo_core_t; 151 152 typedef struct amdzen_topo_ccx { 153 uint32_t atccx_log_no; 154 uint32_t atccx_phys_no; 155 uint32_t atccx_nlog_cores; 156 uint32_t atccx_nphys_cores; 157 uint32_t atccx_core_en[AMDZEN_TOPO_CCX_MAX_CORES]; 158 amdzen_topo_core_t atccx_cores[AMDZEN_TOPO_CCX_MAX_CORES]; 159 } amdzen_topo_ccx_t; 160 161 typedef enum amdzen_topo_ccd_err { 162 AMDZEN_TOPO_CCD_E_OK = 0, 163 /* 164 * Indicates that the system was unable to determine the APIC 165 * decomposition and therefore we do not have mapping information 166 * available. 167 */ 168 AMDZEN_TOPO_CCD_E_NO_APIC_DECOMP, 169 /* 170 * Indicates that this DF number did not map to something that exists. 171 */ 172 AMDZEN_TOPO_CCD_E_BAD_DFNO, 173 /* 174 * Indicates that the current system is unsupported. Generally this is 175 * only the case for Zen 1 / DFv2. 176 */ 177 AMDZEN_TOPO_CCD_E_SOC_UNSUPPORTED, 178 /* 179 * Indicates that the instance ID in question doesn't map to a DF entity 180 * and is invalid. 181 */ 182 AMDZEN_TOPO_CCD_E_BAD_INSTID, 183 /* 184 * Indicates that the named DF element does not actually point to a CCD. 185 */ 186 AMDZEN_TOPO_CCD_E_NOT_A_CCD, 187 /* 188 * Indicates that the specified CCD ID is not known within the given 189 * instance. 190 */ 191 AMDZEN_TOPO_CCD_E_BAD_CCDID, 192 /* 193 * Indicates that the fabric ID does point to a CCD, but we don't 194 * believe it is actually present in the system. This often happens 195 * when a CCM is enabled but there is no CCD. This is the case in many 196 * DFv3 (Zen 2/3) systems. 197 */ 198 AMDZEN_TOPO_CCD_E_CCD_MISSING 199 } amdzen_topo_ccd_err_t; 200 201 /* 202 * The following flags are set to cover our understanding of the output. 203 */ 204 typedef enum amdzen_topo_ccd_flags { 205 /* 206 * Indicates that we don't actually know the mapping of physical to 207 * logical cores in the CCX and therefore we have assumed a 1:1 208 * relationship. 209 */ 210 AMDZEN_TOPO_CCD_F_CORE_PHYS_UNKNOWN = 1 << 0 211 } amdzen_topo_ccd_flags_t; 212 213 typedef struct amdzen_topo_ccd { 214 uint32_t atccd_dfno; 215 uint32_t atccd_instid; 216 uint32_t atccd_phys_no; 217 amdzen_topo_ccd_err_t atccd_err; 218 amdzen_topo_ccd_flags_t atccd_flags; 219 uint32_t atccd_log_no; 220 uint32_t atccd_nlog_ccx; 221 uint32_t atccd_nphys_ccx; 222 uint32_t atccd_ccx_en[AMDZEN_TOPO_CCD_MAX_CCX]; 223 amdzen_topo_ccx_t atccd_ccx[AMDZEN_TOPO_CCD_MAX_CCX]; 224 } amdzen_topo_ccd_t; 225 226 #ifdef __cplusplus 227 } 228 #endif 229 230 #endif /* _AMDZEN_TOPO_H */ 231