xref: /illumos-gate/usr/src/uts/intel/io/amdzen/amdzen_topo.h (revision c43efa7f6b109f90d7f4962df8c0e1a94008d2d1)
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