xref: /illumos-gate/usr/src/uts/intel/sys/amdzen/df.h (revision e8d3efa1c56e5f2b5368600a2baeb7b1d54a07f8)
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 2026 Oxide Computer Company
14  */
15 
16 #ifndef _SYS_AMDZEN_DF_H
17 #define	_SYS_AMDZEN_DF_H
18 
19 /*
20  * This file contains definitions for the registers that appears in the AMD Zen
21  * Data Fabric. The data fabric is the main component which routes transactions
22  * between entities (e.g. CPUS, DRAM, PCIe, etc.) in the system. The data fabric
23  * itself is made up of up to 8 PCI functions. There can be multiple instances
24  * of the data fabric. There is one instance per die. In most AMD processors
25  * after Zen 1, there is only a single die per socket, for more background see
26  * the uts/i86pc/os/cpuid.c big theory statement. All data fabric instances
27  * appear on PCI bus 0. The first instance shows up on device 0x18. Subsequent
28  * instances simply increment that number by one.
29  *
30  * There are currently four major revisions of the data fabric that are
31  * supported here, which are v2 (Zen 1), v3 (Zen 2/3), v3.5 (Zen 2/3 with DDR5),
32  * and v4 (Zen 4). In many cases, while the same logical thing exists in
33  * different generations, they often have different shapes and sometimes things
34  * with the same shape show up in different locations. As DFv4 has been extended
35  * across several different lines, things haven't been quite as smooth as we'd
36  * like in terms of DF representation. Certain things end up moving around much
37  * more liberally while revving the minor version of the DF, though at least we
38  * can still identify it as such.
39  *
40  * The major (relevant to us) distinction that we have found so far is that
41  * starting in DF 4v2 and greater, the way that DRAM was structured and the
42  * corresponding DRAM channel remap settings were moved. Because the DRAM base
43  * address registers were moved to 0x200, we call this DF_REV_4D2. If this
44  * gets much more nuanced, we should likely figure out if we want to encode
45  * minor versions in these constants and offer function pointers to get common
46  * things rather than forcing it onto clients. Note that this is very much a
47  * rough approximation and not really great. There are many places where the
48  * width of fields has changed slightly between minor revs, but are eating up
49  * more reserved bits, or not using quite as many.
50  *
51  * To make things a little easier for clients, each register definition encodes
52  * enough information to also include which hardware generations it supports,
53  * the actual PCI function it appears upon, and the register offset. This is to
54  * make sure that consumers don't have to guess some of this information in the
55  * latter cases and we can try to guarantee we're not accessing an incorrect
56  * register for our platform (unfortunately at runtime).
57  *
58  * Register definitions have the following form:
59  *
60  * DF_<reg name>_<vers>
61  *
62  * Here <reg name> is something that describes the register. This may not be the
63  * exact same as the PPR (processor programming reference); however, the PPR
64  * name for the register will be included above it in a comment (though these
65  * have sometimes changed from time to time). For example, DF_DRAM_HOLE. If a
66  * given register is the same in all currently supported versions, then there is
67  * no version suffix appended. Otherwise, the first version it is supported in
68  * is appended. For example, DF_DRAM_BASE_V2, DF_DRAM_BASE_V3, DF_DRAM_BASE_V4,
69  * etc. or DF_FIDMASK0_V3P5, etc. If the register offset is the same in multiple
70  * versions, then there they share the earliest version.
71  *
72  * For fields there are currently macros to extract these or chain them together
73  * leveraging bitx32() and bitset32(). Fields have the forms:
74  *
75  * DF_<reg name>_<vers>_GET_<field>
76  * DF_<reg name>_<vers>_SET_<field>
77  *
78  * Like in the above, if there are cases where a single field is the same across
79  * all versions, then the <vers> portion will be elided. There are many cases
80  * where the register definition does not change, but the fields themselves do
81  * change with each version because each hardware rev opts to be slightly
82  * different.
83  *
84  * When adding support for a new chip, please look carefully through the
85  * requisite documentation to ensure that they match what we see here. There are
86  * often cases where there may be a subtle thing or you hit a case like V3P5
87  * that until you dig deeper just seem to be weird.
88  */
89 
90 #include <sys/bitext.h>
91 
92 #ifdef __cplusplus
93 extern "C" {
94 #endif
95 
96 typedef enum df_rev {
97 	DF_REV_UNKNOWN	= 0,
98 	DF_REV_2	= 1 << 0,
99 	DF_REV_3	= 1 << 1,
100 	DF_REV_3P5	= 1 << 2,
101 	DF_REV_4	= 1 << 3,
102 	/*
103 	 * This is a synthetic revision we make up per the theory statement that
104 	 * covers devices that have an updated DRAM layout.
105 	 */
106 	DF_REV_4D2	= 1 << 4
107 } df_rev_t;
108 
109 #define	DF_REV_ALL_3	(DF_REV_3 | DF_REV_3P5)
110 #define	DF_REV_ALL_23	(DF_REV_2 | DF_REV_ALL_3)
111 #define	DF_REV_ALL_4	(DF_REV_4 | DF_REV_4D2)
112 #define	DF_REV_ALL	(DF_REV_ALL_23 | DF_REV_ALL_4)
113 
114 typedef struct df_reg_def {
115 	df_rev_t	drd_gens;
116 	uint8_t		drd_func;
117 	uint16_t	drd_reg;
118 } df_reg_def_t;
119 
120 /*
121  * This set of registers provides us access to the count of instances in the
122  * data fabric and then a number of different pieces of information about them
123  * like their type. Note, these registers require indirect access because the
124  * information cannot be broadcast.
125  */
126 
127 /*
128  * DF::FabricBlockInstanceCount -- Describes the number of instances in the data
129  * fabric. With v4, also includes versioning information.
130  */
131 /*CSTYLED*/
132 #define	DF_FBICNT		(df_reg_def_t){ .drd_gens = DF_REV_ALL, \
133 				    .drd_func = 0, .drd_reg = 0x40 }
134 #define	DF_FBICNT_V4_GET_MAJOR(r)	bitx32(r, 27, 24)
135 #define	DF_FBICNT_V4_GET_MINOR(r)	bitx32(r, 23, 16)
136 #define	DF_FBICNT_GET_COUNT(r)		bitx32(r, 7, 0)
137 
138 /*
139  * DF::FabricBlockInstanceInformation0 -- get basic information about a fabric
140  * instance.
141  */
142 /*CSTYLED*/
143 #define	DF_FBIINFO0		(df_reg_def_t){ .drd_gens = DF_REV_ALL, \
144 				    .drd_func = 0, .drd_reg = 0x44 }
145 #define	DF_FBIINFO0_GET_SUBTYPE(r)	bitx32(r, 26, 24)
146 #define	DF_SUBTYPE_NONE	0
147 typedef enum {
148 	DF_CAKE_SUBTYPE_GMI = 1,
149 	DF_CAKE_SUBTYPE_xGMI = 2
150 } df_cake_subtype_t;
151 
152 typedef enum {
153 	DF_IOM_SUBTYPE_IOHUB = 1,
154 } df_iom_subtype_t;
155 
156 typedef enum {
157 	DF_CS_SUBTYPE_UMC = 1,
158 	/*
159 	 * The subtype changed beginning in DFv4. Prior to DFv4, the secondary
160 	 * type was CCIX. Starting with DFv4, this is now CMP. It is unclear if
161 	 * these are the same thing or not.
162 	 */
163 	DF_CS_SUBTYPE_CCIX = 2,
164 	DF_CS_SUBTYPE_CMP = 2
165 } df_cs_subtype_t;
166 
167 /*
168  * Starting in DFv4 they introduced a CCM subtype; however, kept the CPU
169  * compatible with prior DF revisions in v4.0. Starting with v4.1, they moved
170  * this to a value of one and the less asked about the ACM the better.
171  * Unfortunately this doesn't fit nicely with the major DF revisions which we
172  * use for register access.
173  */
174 typedef enum {
175 	DF_CCM_SUBTYPE_CPU_V2 = 0,
176 	DF_CCM_SUBTYPE_ACM_V4 = 1,
177 	DF_CCM_SUBTYPE_CPU_V4P1 = 1
178 } df_ccm_subtype_v4_t;
179 
180 typedef enum {
181 	DF_NCM_SUBTYPE_MMHUB = 1,
182 	DF_NCM_SUBTYPE_DCE = 2,
183 	DF_NCM_SUBTYPE_IOMMU = 4
184 } df_ncm_subtype_t;
185 
186 
187 #define	DF_FBIINFO0_GET_HAS_MCA(r)	bitx32(r, 23, 23)
188 #define	DF_FBIINFO0_GET_FTI_DCNT(r)	bitx32(r, 21, 20)
189 #define	DF_FBIINFO0_GET_FTI_PCNT(r)	bitx32(r, 18, 16)
190 #define	DF_FBIINFO0_GET_SDP_RESPCNT(r)	bitx32(r, 14, 14)
191 #define	DF_FBIINFO0_GET_SDP_PCNT(r)	bitx32(r, 13, 12)
192 #define	DF_FBIINFO0_GET_FTI_WIDTH(r)	bitx32(r, 9, 8)
193 typedef enum {
194 	DF_FTI_W_64 = 0,
195 	DF_FTI_W_128,
196 	DF_FTI_W_256,
197 	DF_FTI_W_512
198 } df_fti_width_t;
199 #define	DF_FBIINFO0_V3_GET_ENABLED(r)	bitx32(r, 6, 6)
200 #define	DF_FBIINFO0_GET_SDP_WIDTH(r)	bitx32(r, 5, 4)
201 typedef enum {
202 	DF_SDP_W_64 = 0,
203 	DF_SDP_W_128,
204 	DF_SDP_W_256,
205 	DF_SDP_W_512
206 } df_sdp_width_t;
207 #define	DF_FBIINFO0_GET_TYPE(r)		bitx32(r, 3, 0)
208 typedef enum {
209 	DF_TYPE_CCM = 0,
210 	DF_TYPE_GCM,
211 	DF_TYPE_NCM,
212 	DF_TYPE_IOMS,
213 	DF_TYPE_CS,
214 	DF_TYPE_NCS,
215 	DF_TYPE_TCDX,
216 	DF_TYPE_PIE,
217 	DF_TYPE_SPF,
218 	DF_TYPE_LLC,
219 	DF_TYPE_CAKE,
220 	DF_TYPE_ICNG,
221 	DF_TYPE_PFX,
222 	DF_TYPE_CNLI
223 } df_type_t;
224 
225 /*
226  * DF::FabricBlockInstanceInformation1 -- get basic information about a fabric
227  * instance. This appears to have been dropped starting in DF 4D2.
228  */
229 /*CSTYLED*/
230 #define	DF_FBIINFO1		(df_reg_def_t){ .drd_gens = DF_REV_ALL_23 | \
231 				    DF_REV_4, .drd_func = 0, .drd_reg = 0x48 }
232 #define	DF_FBINFO1_GET_FTI3_NINSTID(r)		bitx32(r, 31, 24)
233 #define	DF_FBINFO1_GET_FTI2_NINSTID(r)		bitx32(r, 23, 16)
234 #define	DF_FBINFO1_GET_FTI1_NINSTID(r)		bitx32(r, 15, 8)
235 #define	DF_FBINFO1_GET_FTI0_NINSTID(r)		bitx32(r, 7, 0)
236 
237 /*
238  * DF::FabricBlockInstanceInformation2 -- get basic information about a fabric
239  * instance. This appears to have been dropped starting in DF 4D2.
240  */
241 /*CSTYLED*/
242 #define	DF_FBIINFO2		(df_reg_def_t){ .drd_gens = DF_REV_ALL_23 | \
243 				    DF_REV_4, .drd_func = 0, .drd_reg = 0x4c }
244 #define	DF_FBINFO2_GET_FTI5_NINSTID(r)		bitx32(r, 15, 8)
245 #define	DF_FBINFO2_GET_FTI4_NINSTID(r)		bitx32(r, 7, 0)
246 
247 /*
248  * DF::FabricBlockInstanceInformation3 -- obtain the basic IDs for a given
249  * instance.
250  */
251 /*CSTYLED*/
252 #define	DF_FBIINFO3		(df_reg_def_t){ .drd_gens = DF_REV_ALL, \
253 				    .drd_func = 0, .drd_reg = 0x50 }
254 #define	DF_FBIINFO3_V2_GET_BLOCKID(r)	bitx32(r, 15, 8)
255 #define	DF_FBIINFO3_V3_GET_BLOCKID(r)	bitx32(r, 13, 8)
256 #define	DF_FBIINFO3_V3P5_GET_BLOCKID(r)	bitx32(r, 11, 8)
257 #define	DF_FBIINFO3_V4_GET_BLOCKID(r)	bitx32(r, 19, 8)
258 #define	DF_FBIINFO3_V4D2_GET_BLOCKID(r)	bitx32(r, 15, 8)
259 #define	DF_FBIINFO3_GET_INSTID(r)	bitx32(r, 7, 0)
260 
261 /*
262  * DF::DfCapability -- Describes the capabilities that the DF has. Note that one
263  * must generally check the DF version prior to considering various bits here.
264  * For example, the extended CS remaper is only valid starting in the 4D2
265  * variant.
266  */
267 /*CSTYLED*/
268 #define	DF_CAPAB		(df_reg_def_t){ .drd_gens = DF_REV_ALL, \
269 				    .drd_func = 0, .drd_reg = 0x90 }
270 #define	DF_CAPAB_GET_EXTCSREMAP(r)	bitx32(r, 2, 2)
271 #define	DF_CAPAB_GET_SPF(r)		bitx32(r, 1, 1)
272 #define	DF_CAPAB_GET_POISON(r)		bitx32(r, 0, 0)
273 
274 /*
275  * DF::Skt0CsTargetRemap0, DF::Skt0CsTargetRemap1, DF::Skt1CsTargetRemap0,
276  * DF::Skt1CsTargetRemap1 -- The next set of registers provide access to
277  * chip-select remapping. Caution, while these have a documented DF generation
278  * that they are specific to, it seems they still aren't always implemented and
279  * are specific to Milan (v3) and Genoa (v4). The actual remap extraction is the
280  * same between both.
281  */
282 #define	DF_CS_REMAP_GET_CSX(r, x)	bitx32(r, (3 + (4 * (x))), (4 * ((x))))
283 /*CSTYLED*/
284 #define	DF_SKT0_CS_REMAP0_V3	(df_reg_def_t){ .drd_gens = DF_REV_3, \
285 				    .drd_func = 0, .drd_reg = 0x60 }
286 /*CSTYLED*/
287 #define	DF_SKT1_CS_REMAP0_V3	(df_reg_def_t){ .drd_gens = DF_REV_3, \
288 				    .drd_func = 0, .drd_reg = 0x68 }
289 /*CSTYLED*/
290 #define	DF_SKT0_CS_REMAP1_V3	(df_reg_def_t){ .drd_gens = DF_REV_3, \
291 				    .drd_func = 0, .drd_reg = 0x64 }
292 /*CSTYLED*/
293 #define	DF_SKT1_CS_REMAP1_V3	(df_reg_def_t){ .drd_gens = DF_REV_3, \
294 				    .drd_func = 0, .drd_reg = 0x6c }
295 /*
296  * DF::CsTargetRemap0A, DF::CsTargetRemap0B, etc. -- These registers contain the
297  * remap engines in DFv4. Note, that while v3 used 0/1 as REMAP[01], as
298  * referring to the same logical set of things, here [0-3] is used for different
299  * things and A/B distinguish the different actual CS values. This was redone to
300  * allow for a wider channel selection in the 4D2 parts, see the subsequent
301  * section.
302  */
303 /*CSTYLED*/
304 #define	DF_CS_REMAP0A_V4	(df_reg_def_t){ .drd_gens = DF_REV_4, \
305 				    .drd_func = 7, .drd_reg = 0x180 }
306 /*CSTYLED*/
307 #define	DF_CS_REMAP0B_V4	(df_reg_def_t){ .drd_gens = DF_REV_4, \
308 				    .drd_func = 7, .drd_reg = 0x184 }
309 /*CSTYLED*/
310 #define	DF_CS_REMAP1A_V4	(df_reg_def_t){ .drd_gens = DF_REV_4, \
311 				    .drd_func = 7, .drd_reg = 0x188 }
312 /*CSTYLED*/
313 #define	DF_CS_REMAP1B_V4	(df_reg_def_t){ .drd_gens = DF_REV_4, \
314 				    .drd_func = 7, .drd_reg = 0x18c }
315 /*CSTYLED*/
316 #define	DF_CS_REMAP2A_V4	(df_reg_def_t){ .drd_gens = DF_REV_4, \
317 				    .drd_func = 7, .drd_reg = 0x190 }
318 /*CSTYLED*/
319 #define	DF_CS_REMAP2B_V4	(df_reg_def_t){ .drd_gens = DF_REV_4, \
320 				    .drd_func = 7, .drd_reg = 0x194 }
321 /*CSTYLED*/
322 #define	DF_CS_REMAP3A_V4	(df_reg_def_t){ .drd_gens = DF_REV_4, \
323 				    .drd_func = 7, .drd_reg = 0x198 }
324 /*CSTYLED*/
325 #define	DF_CS_REMAP3B_V4	(df_reg_def_t){ .drd_gens = DF_REV_4, \
326 				    .drd_func = 7, .drd_reg = 0x19c }
327 
328 /*
329  * DF::CsTargetRemap0A, DF::CsTargetRemap0B, etc. -- D42 edition. This has
330  * changed the actual size of the remap values so that they are now 5 bits wide,
331  * allowing for up to 32 channels. This is indicated by bit 2 (EXTCSREMAP) in
332  * DF::DfCapability. As a result, there are now only 6 remaps per register, so
333  * there are now 3 registers [ABC] per remap target [0123].
334  * changing around where the registers actually are.
335  */
336 #define	DF_CS_REMAP_GET_CSX_V4B(r, x)	bitx32(r, (4 + (5 * (x))), (5 * ((x))))
337 /*CSTYLED*/
338 #define	DF_CS_REMAP0A_V4D2	(df_reg_def_t){ .drd_gens = DF_REV_4D2, \
339 				    .drd_func = 7, .drd_reg = 0x180 }
340 /*CSTYLED*/
341 #define	DF_CS_REMAP0B_V4D2	(df_reg_def_t){ .drd_gens = DF_REV_4D2, \
342 				    .drd_func = 7, .drd_reg = 0x184 }
343 /*CSTYLED*/
344 #define	DF_CS_REMAP0C_V4D2	(df_reg_def_t){ .drd_gens = DF_REV_4D2, \
345 				    .drd_func = 7, .drd_reg = 0x188 }
346 /*CSTYLED*/
347 #define	DF_CS_REMAP1A_V4D2	(df_reg_def_t){ .drd_gens = DF_REV_4D2, \
348 				    .drd_func = 7, .drd_reg = 0x198 }
349 /*CSTYLED*/
350 #define	DF_CS_REMAP1B_V4D2	(df_reg_def_t){ .drd_gens = DF_REV_4D2, \
351 				    .drd_func = 7, .drd_reg = 0x19c }
352 /*CSTYLED*/
353 #define	DF_CS_REMAP1C_V4D2	(df_reg_def_t){ .drd_gens = DF_REV_4D2, \
354 				    .drd_func = 7, .drd_reg = 0x1a0 }
355 /*CSTYLED*/
356 #define	DF_CS_REMAP2A_V4D2	(df_reg_def_t){ .drd_gens = DF_REV_4D2, \
357 				    .drd_func = 7, .drd_reg = 0x1b0 }
358 /*CSTYLED*/
359 #define	DF_CS_REMAP2B_V4D2	(df_reg_def_t){ .drd_gens = DF_REV_4D2, \
360 				    .drd_func = 7, .drd_reg = 0x1b4 }
361 /*CSTYLED*/
362 #define	DF_CS_REMAP2C_V4D2	(df_reg_def_t){ .drd_gens = DF_REV_4D2, \
363 				    .drd_func = 7, .drd_reg = 0x1b8 }
364 /*CSTYLED*/
365 #define	DF_CS_REMAP3A_V4D2	(df_reg_def_t){ .drd_gens = DF_REV_4D2, \
366 				    .drd_func = 7, .drd_reg = 0x1c8 }
367 /*CSTYLED*/
368 #define	DF_CS_REMAP3B_V4D2	(df_reg_def_t){ .drd_gens = DF_REV_4D2, \
369 				    .drd_func = 7, .drd_reg = 0x1cc }
370 /*CSTYLED*/
371 #define	DF_CS_REMAP3C_V4D2	(df_reg_def_t){ .drd_gens = DF_REV_4D2, \
372 				    .drd_func = 7, .drd_reg = 0x1d0 }
373 
374 /*
375  * DF::CfgAddressCntl -- This register contains the information about the
376  * configuration of PCIe buses.  We care about finding which one has our BUS A,
377  * which is required to map it to the in-package northbridge instance.
378  */
379 /*CSTYLED*/
380 #define	DF_CFG_ADDR_CTL_V2	(df_reg_def_t){ .drd_gens = DF_REV_ALL_23, \
381 				.drd_func = 0, \
382 				.drd_reg = 0x84 }
383 /*CSTYLED*/
384 #define	DF_CFG_ADDR_CTL_V4	(df_reg_def_t){ .drd_gens = DF_REV_ALL_4, \
385 				.drd_func = 0, \
386 				.drd_reg = 0xc04 }
387 #define	DF_CFG_ADDR_CTL_GET_BUS_NUM(r)	bitx32(r, 7, 0)
388 
389 /*
390  * DF::CfgAddressMap -- This next set of registers covers PCI Bus configuration
391  * address maps. The layout here changes at v4. This routes a given PCI bus to a
392  * device.
393  */
394 /*CSTYLED*/
395 #define	DF_CFGMAP_V2(x)		(df_reg_def_t){ .drd_gens = DF_REV_ALL_23, \
396 				.drd_func = 0, \
397 				.drd_reg = 0xa0 + ((x) * 4) }
398 #define	DF_MAX_CFGMAP		8
399 #define	DF_MAX_CFGMAP_TURIN	16
400 #define	DF_CFGMAP_V2_GET_BUS_LIMIT(r)		bitx32(r, 31, 24)
401 #define	DF_CFGMAP_V2_GET_BUS_BASE(r)		bitx32(r, 23, 16)
402 #define	DF_CFGMAP_V2_GET_DEST_ID(r)		bitx32(r, 11, 4)
403 #define	DF_CFGMAP_V3_GET_DEST_ID(r)		bitx32(r, 13, 4)
404 #define	DF_CFGMAP_V3P5_GET_DEST_ID(r)		bitx32(r, 7, 4)
405 #define	DF_CFGMAP_V2_GET_WE(r)			bitx32(r, 1, 1)
406 #define	DF_CFGMAP_V2_GET_RE(r)			bitx32(r, 0, 0)
407 
408 /*
409  * DF::CfgBaseAddress, DF::CfgLimitAddress -- DFv4 variants of the above now in
410  * two registers and more possible entries!
411  */
412 /*CSTYLED*/
413 #define	DF_CFGMAP_BASE_V4(x)	(df_reg_def_t){ .drd_gens = DF_REV_ALL_4, \
414 				.drd_func = 0, \
415 				.drd_reg = 0xc80 + ((x) * 8) }
416 /*CSTYLED*/
417 #define	DF_CFGMAP_LIMIT_V4(x)	(df_reg_def_t){ .drd_gens = DF_REV_ALL_4, \
418 				.drd_func = 0, \
419 				.drd_reg = 0xc84 + ((x) * 8) }
420 #define	DF_CFGMAP_BASE_V4_GET_BASE(r)	bitx32(r, 23, 16)
421 #define	DF_CFGMAP_BASE_V4_GET_SEG(r)	bitx32(r, 15, 8)
422 #define	DF_CFGMAP_BASE_V4_GET_WE(r)	bitx32(r, 1, 1)
423 #define	DF_CFGMAP_BASE_V4_GET_RE(r)	bitx32(r, 0, 0)
424 #define	DF_CFGMAP_LIMIT_V4_GET_LIMIT(r)		bitx32(r, 23, 16)
425 #define	DF_CFGMAP_LIMIT_V4_GET_DEST_ID(r)	bitx32(r, 11, 0)
426 #define	DF_CFGMAP_LIMIT_V4D2_GET_DEST_ID(r)	bitx32(r, 7, 0)
427 
428 /*
429  * DF::X86IOBaseAddress, DF::X86IOLimitAddress -- Base and limit registers for
430  * routing I/O space. These are fairly similar prior to DFv4. The number of
431  * these was increased in Turin. We expect this'll hold true for future server
432  * parts.
433  */
434 /*CSTYLED*/
435 #define	DF_IO_BASE_V2(x)	(df_reg_def_t){ .drd_gens = DF_REV_ALL_23, \
436 				.drd_func = 0, \
437 				.drd_reg = 0xc0 + ((x) * 8) }
438 /*CSTYLED*/
439 #define	DF_IO_BASE_V4(x)	(df_reg_def_t){ .drd_gens = DF_REV_ALL_4, \
440 				.drd_func = 0, \
441 				.drd_reg = 0xd00 + ((x) * 8) }
442 #define	DF_MAX_IO_RULES		8
443 #define	DF_MAX_IO_RULES_TURIN	16
444 #define	DF_IO_BASE_SHIFT	12
445 #define	DF_IO_BASE_V2_GET_BASE(r)	bitx32(r, 24, 12)
446 #define	DF_IO_BASE_V2_GET_IE(r)		bitx32(r, 5, 5)
447 #define	DF_IO_BASE_V2_GET_WE(r)		bitx32(r, 1, 1)
448 #define	DF_IO_BASE_V2_GET_RE(r)		bitx32(r, 0, 0)
449 #define	DF_IO_BASE_V2_SET_BASE(r, v)	bitset32(r, 24, 12, v)
450 #define	DF_IO_BASE_V2_SET_IE(r, v)	bitset32(r, 5, 5, v)
451 #define	DF_IO_BASE_V2_SET_WE(r, v)	bitset32(r, 1, 1, v)
452 #define	DF_IO_BASE_V2_SET_RE(r, v)	bitset32(r, 0, 0, v)
453 
454 #define	DF_IO_BASE_V4_GET_BASE(r)	bitx32(r, 28, 16)
455 #define	DF_IO_BASE_V4_GET_IE(r)		bitx32(r, 5, 5)
456 #define	DF_IO_BASE_V4_GET_WE(r)		bitx32(r, 1, 1)
457 #define	DF_IO_BASE_V4_GET_RE(r)		bitx32(r, 0, 0)
458 #define	DF_IO_BASE_V4_SET_BASE(r, v)	bitset32(r, 28, 16, v)
459 #define	DF_IO_BASE_V4_SET_IE(r, v)	bitset32(r, 5, 5, v)
460 #define	DF_IO_BASE_V4_SET_WE(r, v)	bitset32(r, 1, 1, v)
461 #define	DF_IO_BASE_V4_SET_RE(r, v)	bitset32(r, 0, 0, v)
462 
463 /*CSTYLED*/
464 #define	DF_IO_LIMIT_V2(x)	(df_reg_def_t){ .drd_gens = DF_REV_ALL_23, \
465 				.drd_func = 0, \
466 				.drd_reg = 0xc4 + ((x) * 8) }
467 /*CSTYLED*/
468 #define	DF_IO_LIMIT_V4(x)	(df_reg_def_t){ .drd_gens = DF_REV_ALL_4, \
469 				.drd_func = 0, \
470 				.drd_reg = 0xd04 + ((x) * 8) }
471 #define	DF_MAX_IO_LIMIT		((1 << 24) - 1)
472 #define	DF_IO_LIMIT_SHIFT	12
473 #define	DF_IO_LIMIT_EXCL	(1 << DF_IO_LIMIT_SHIFT)
474 #define	DF_IO_LIMIT_V2_GET_LIMIT(r)	bitx32(r, 24, 12)
475 #define	DF_IO_LIMIT_V2_GET_DEST_ID(r)	bitx32(r, 7, 0)
476 #define	DF_IO_LIMIT_V3_GET_DEST_ID(r)	bitx32(r, 9, 0)
477 #define	DF_IO_LIMIT_V3P5_GET_DEST_ID(r)	bitx32(r, 3, 0)
478 #define	DF_IO_LIMIT_V2_SET_LIMIT(r, v)		bitset32(r, 24, 12, v)
479 #define	DF_IO_LIMIT_V2_SET_DEST_ID(r, v)	bitset32(r, 7, 0, v)
480 #define	DF_IO_LIMIT_V3_SET_DEST_ID(r, v)	bitset32(r, 9, 0, v)
481 #define	DF_IO_LIMIT_V3P5_SET_DEST_ID(r, v)	bitset32(r, 3, 0, v)
482 
483 #define	DF_IO_LIMIT_V4_GET_LIMIT(r)	bitx32(r, 28, 16)
484 #define	DF_IO_LIMIT_V4_GET_DEST_ID(r)	bitx32(r, 11, 0)
485 #define	DF_IO_LIMIT_V4D2_GET_DEST_ID(r)	bitx32(r, 7, 0)
486 #define	DF_IO_LIMIT_V4_SET_LIMIT(r, v)		bitset32(r, 28, 16, v)
487 #define	DF_IO_LIMIT_V4_SET_DEST_ID(r, v)	bitset32(r, 11, 0, v)
488 #define	DF_IO_LIMIT_V4D2_SET_DEST_ID(r, v)	bitset32(r, 7, 0, v)
489 
490 /*
491  * DF::DramHoleControl -- This controls MMIO below 4 GiB. Note, both this and
492  * the Top of Memory (TOM) need to be set consistently.
493  */
494 /*CSTYLED*/
495 #define	DF_DRAM_HOLE_V2		(df_reg_def_t){ .drd_gens = DF_REV_ALL_23, \
496 				.drd_func = 0, \
497 				.drd_reg = 0x104 }
498 /*CSTYLED*/
499 #define	DF_DRAM_HOLE_V4		(df_reg_def_t){ .drd_gens = DF_REV_ALL_4, \
500 				.drd_func = 7, \
501 				.drd_reg = 0x104 }
502 #define	DF_DRAM_HOLE_GET_BASE(r)	bitx32(r, 31, 24)
503 #define	DF_DRAM_HOLE_BASE_SHIFT		24
504 #define	DF_DRAM_HOLE_GET_VALID(r)	bitx32(r, 0, 0)
505 
506 /*
507  * DF::DramBaseAddress, DF::DramLimitAddress -- DRAM rules, these are split into
508  * a base and limit. While DFv2, 3, and 3.5 all have the same addresses, they
509  * have different bit patterns entirely. DFv4 is in a different location and
510  * further splits this into four registers. We do all of the pre-DFv4 stuff and
511  * follow with DFv4. In DFv2-3.5 the actual values of the bits (e.g. the meaning
512  * of the channel interleave value) are the same, even though where those bits
513  * are in the register changes.
514  *
515  * In DF v2, v3, and v3.5 the set of constants for interleave values are the
516  * same, so we define them once at the v2 version.
517  */
518 /*CSTYLED*/
519 #define	DF_DRAM_BASE_V2(r)	(df_reg_def_t){ .drd_gens = DF_REV_ALL_23, \
520 				.drd_func = 0, \
521 				.drd_reg = 0x110 + ((r) * 8) }
522 #define	DF_DRAM_BASE_V2_GET_BASE(r)		bitx32(r, 31, 12)
523 #define	DF_DRAM_BASE_V2_BASE_SHIFT		28
524 #define	DF_DRAM_BASE_V2_GET_ILV_ADDR(r)		bitx32(r, 10, 8)
525 #define	DF_DRAM_BASE_V2_GET_ILV_CHAN(r)		bitx32(r, 7, 4)
526 #define	DF_DRAM_BASE_V2_ILV_CHAN_1		0x0
527 #define	DF_DRAM_BASE_V2_ILV_CHAN_2		0x1
528 #define	DF_DRAM_BASE_V2_ILV_CHAN_4		0x3
529 #define	DF_DRAM_BASE_V2_ILV_CHAN_8		0x5
530 #define	DF_DRAM_BASE_V2_ILV_CHAN_6		0x6
531 #define	DF_DRAM_BASE_V2_ILV_CHAN_COD4_2		0xc
532 #define	DF_DRAM_BASE_V2_ILV_CHAN_COD2_4		0xd
533 #define	DF_DRAM_BASE_V2_ILV_CHAN_COD1_8		0xe
534 #define	DF_DRAM_BASE_V2_GET_HOLE_EN(r)		bitx32(r, 1, 1)
535 #define	DF_DRAM_BASE_V2_GET_VALID(r)		bitx32(r, 0, 0)
536 
537 #define	DF_DRAM_BASE_V3_GET_ILV_ADDR(r)		bitx32(r, 11, 9)
538 #define	DF_DRAM_BASE_V3_GET_ILV_SOCK(r)		bitx32(r, 8, 8)
539 #define	DF_DRAM_BASE_V3_GET_ILV_DIE(r)		bitx32(r, 7, 6)
540 #define	DF_DRAM_BASE_V3_GET_ILV_CHAN(r)		bitx32(r, 5, 2)
541 
542 #define	DF_DRAM_BASE_V3P5_GET_ILV_ADDR(r)	bitx32(r, 11, 9)
543 #define	DF_DRAM_BASE_V3P5_GET_ILV_SOCK(r)	bitx32(r, 8, 8)
544 #define	DF_DRAM_BASE_V3P5_GET_ILV_DIE(r)	bitx32(r, 7, 7)
545 #define	DF_DRAM_BASE_V3P5_GET_ILV_CHAN(r)	bitx32(r, 6, 2)
546 
547 /*
548  * Shared definitions for the DF DRAM interleaving address start bits. While the
549  * bitfield / register definition is different between DFv2/3/3.5 and DFv4, the
550  * actual contents of the base address register and the base are shared.
551  */
552 #define	DF_DRAM_ILV_ADDR_8		0
553 #define	DF_DRAM_ILV_ADDR_9		1
554 #define	DF_DRAM_ILV_ADDR_10		2
555 #define	DF_DRAM_ILV_ADDR_11		3
556 #define	DF_DRAM_ILV_ADDR_12		4
557 #define	DF_DRAM_ILV_ADDR_BASE		8
558 
559 /*CSTYLED*/
560 #define	DF_DRAM_LIMIT_V2(r)	(df_reg_def_t){ .drd_gens = DF_REV_ALL_23, \
561 				.drd_func = 0, \
562 				.drd_reg = 0x114 + ((r) * 8) }
563 #define	DF_DRAM_LIMIT_V2_GET_LIMIT(r)		bitx32(r, 31, 12)
564 #define	DF_DRAM_LIMIT_V2_LIMIT_SHIFT		28
565 #define	DF_DRAM_LIMIT_V2_LIMIT_EXCL		(1 << 28)
566 /* These are in the base register for v3, v3.5 */
567 #define	DF_DRAM_LIMIT_V2_GET_ILV_DIE(r)		bitx32(r, 11, 10)
568 #define	DF_DRAM_LIMIT_V2_GET_ILV_SOCK(r)	bitx32(r, 8, 8)
569 #define	DF_DRAM_LIMIT_V2_GET_DEST_ID(r)		bitx32(r, 7, 0)
570 
571 #define	DF_DRAM_LIMIT_V3_GET_BUS_BREAK(r)	bitx32(r, 10, 10)
572 #define	DF_DRAM_LIMIT_V3_GET_DEST_ID(r)		bitx32(r, 9, 0)
573 
574 #define	DF_DRAM_LIMIT_V3P5_GET_DEST_ID(r)	bitx32(r, 3, 0)
575 
576 /*
577  * DF::DramBaseAddress, DF::DramLimitAddress, DF::DramAddressCtl,
578  * DF::DramAddressIntlv  -- DFv4 edition. Here all the controls around the
579  * target, interleaving, hashing, and more is split out from the base and limit
580  * registers and put into dedicated control and interleave registers.
581  *
582  * In the 4D2 variant, the base and limit are the same, just at different
583  * addresses. The control register is subtly different with additional
584  * interleave options.
585  */
586 /*CSTYLED*/
587 #define	DF_DRAM_BASE_V4(x)	(df_reg_def_t){ .drd_gens = DF_REV_4, \
588 				.drd_func = 7, \
589 				.drd_reg = 0xe00 + ((x) * 0x10) }
590 /*CSTYLED*/
591 #define	DF_DRAM_BASE_V4D2(x)	(df_reg_def_t){ .drd_gens = DF_REV_4D2, \
592 				.drd_func = 7, \
593 				.drd_reg = 0x200 + ((x) * 0x10) }
594 #define	DF_DRAM_BASE_V4_GET_ADDR(r)		bitx32(r, 27, 0)
595 #define	DF_DRAM_BASE_V4_BASE_SHIFT		28
596 /*CSTYLED*/
597 #define	DF_DRAM_LIMIT_V4(x)	(df_reg_def_t){ .drd_gens = DF_REV_4, \
598 				.drd_func = 7, \
599 				.drd_reg = 0xe04 + ((x) * 0x10) }
600 /*CSTYLED*/
601 #define	DF_DRAM_LIMIT_V4D2(x)	(df_reg_def_t){ .drd_gens = DF_REV_4D2, \
602 				.drd_func = 7, \
603 				.drd_reg = 0x204 + ((x) * 0x10) }
604 #define	DF_DRAM_LIMIT_V4_GET_ADDR(r)		bitx32(r, 27, 0)
605 #define	DF_DRAM_LIMIT_V4_LIMIT_SHIFT		28
606 #define	DF_DRAM_LIMIT_V4_LIMIT_EXCL		(1 << 28)
607 
608 /*CSTYLED*/
609 #define	DF_DRAM_CTL_V4(x)	(df_reg_def_t){ .drd_gens = DF_REV_4, \
610 				.drd_func = 7, \
611 				.drd_reg = 0xe08 + ((x) * 0x10) }
612 /*CSTYLED*/
613 #define	DF_DRAM_CTL_V4D2(x)	(df_reg_def_t){ .drd_gens = DF_REV_4D2, \
614 				.drd_func = 7, \
615 				.drd_reg = 0x208 + ((x) * 0x10) }
616 #define	DF_DRAM_CTL_V4_GET_DEST_ID(r)		bitx32(r, 27, 16)
617 #define	DF_DRAM_CTL_V4D2_GET_DEST_ID(r)		bitx32(r, 23, 16)
618 #define	DF_DRAM_CTL_V4D2_GET_HASH_1T(r)		bitx32(r, 15, 15)
619 /*
620  * It seems that this was added in DF V4.1 (no relation to 4D2). It was reserved
621  * prior to this, so we leave it without a version suffix for now.
622  */
623 #define	DF_DRAM_CTL_V4_GET_COL_SWIZ(r)		bitx32(r, 11, 11)
624 #define	DF_DRAM_CTL_V4_GET_HASH_1G(r)		bitx32(r, 10, 10)
625 #define	DF_DRAM_CTL_V4_GET_HASH_2M(r)		bitx32(r, 9, 9)
626 #define	DF_DRAM_CTL_V4_GET_HASH_64K(r)		bitx32(r, 8, 8)
627 #define	DF_DRAM_CTL_V4D2_GET_HASH_4K(r)		bitx32(r, 7, 7)
628 #define	DF_DRAM_CTL_V4_GET_REMAP_SEL(r)		bitx32(r, 7, 5)
629 #define	DF_DRAM_CTL_V4D2_GET_REMAP_SEL(r)	bitx32(r, 6, 5)
630 #define	DF_DRAM_CTL_V4_GET_REMAP_EN(r)		bitx32(r, 4, 4)
631 #define	DF_DRAM_CTL_V4_GET_SCM(r)		bitx32(r, 2, 2)
632 #define	DF_DRAM_CTL_V4_GET_HOLE_EN(r)		bitx32(r, 1, 1)
633 #define	DF_DRAM_CTL_V4_GET_VALID(r)		bitx32(r, 0, 0)
634 
635 /*CSTYLED*/
636 #define	DF_DRAM_ILV_V4(x)	(df_reg_def_t){ .drd_gens = DF_REV_4, \
637 				.drd_func = 7, \
638 				.drd_reg = 0xe0c + ((x) * 0x10) }
639 /*CSTYLED*/
640 #define	DF_DRAM_ILV_V4D2(x)	(df_reg_def_t){ .drd_gens = DF_REV_4D2, \
641 				.drd_func = 7, \
642 				.drd_reg = 0x20c + ((x) * 0x10) }
643 #define	DF_DRAM_ILV_V4_GET_SOCK(r)		bitx32(r, 18, 18)
644 #define	DF_DRAM_ILV_V4_GET_DIE(r)		bitx32(r, 13, 12)
645 /*
646  * We're cheating a bit here. We combine the various different non-overlapping
647  * values in the 4D2 variants. In particular, most client parts stick to the
648  * first few values while the rest are sometimes used in the moniker "DF 4.5".
649  * The MI300 has a few non-overlapping gaps.
650  */
651 #define	DF_DRAM_ILV_V4D2_GET_CHAN(r)		bitx32(r, 9, 4)
652 #define	DF_DRAM_ILV_V4D2_CHAN_1			0x0
653 #define	DF_DRAM_ILV_V4D2_CHAN_2			0x1
654 #define	DF_DRAM_ILV_V4D2_CHAN_4			0x3
655 #define	DF_DRAM_ILV_V4D2_CHAN_8			0x5
656 #define	DF_DRAM_ILV_V4D2_CHAN_16		0x7
657 #define	DF_DRAM_ILV_V4D2_CHAN_32		0x8
658 #define	DF_DRAM_ILV_V4D2_CHAN_NPS1_16S8CH_1K	0xc
659 #define	DF_DRAM_ILV_V4D2_CHAN_NPS0_24CH_1K	0xe
660 #define	DF_DRAM_ILV_V4D2_CHAN_NPS4_2CH_1K	0x10
661 #define	DF_DRAM_ILV_V4D2_CHAN_NPS2_4CH_1K	0x11
662 #define	DF_DRAM_ILV_V4D2_CHAN_NPS1_8S4CH_1K	0x12
663 #define	DF_DRAM_ILV_V4D2_CHAN_NPS4_3CH_1K	0x13
664 #define	DF_DRAM_ILV_V4D2_CHAN_NPS2_6CH_1K	0x14
665 #define	DF_DRAM_ILV_V4D2_CHAN_NPS1_12CH_1K	0x15
666 #define	DF_DRAM_ILV_V4D2_CHAN_NPS2_5CH_1K	0x16
667 #define	DF_DRAM_ILV_V4D2_CHAN_NPS1_10CH_1K	0x17
668 #define	DF_DRAM_ILV_V4D2_CHAN_MI3H_8CH		0x18
669 #define	DF_DRAM_ILV_V4D2_CHAN_MI3H_16CH		0x19
670 #define	DF_DRAM_ILV_V4D2_CHAN_MI3H_32CH		0x1a
671 #define	DF_DRAM_ILV_V4D2_CHAN_NPS4_2CH_2K	0x20
672 #define	DF_DRAM_ILV_V4D2_CHAN_NPS2_4CH_2K	0x21
673 #define	DF_DRAM_ILV_V4D2_CHAN_NPS1_8S4CH_2K	0x22
674 #define	DF_DRAM_ILV_V4D2_CHAN_NPS1_16S8CH_2K	0x23
675 #define	DF_DRAM_ILV_V4D2_CHAN_NPS4_3CH_2K	0x24
676 #define	DF_DRAM_ILV_V4D2_CHAN_NPS2_6CH_2K	0x25
677 #define	DF_DRAM_ILV_V4D2_CHAN_NPS1_12CH_2K	0x26
678 #define	DF_DRAM_ILV_V4D2_CHAN_NPS0_24CH_2K	0x27
679 #define	DF_DRAM_ILV_V4D2_CHAN_NPS2_5CH_2K	0x28
680 #define	DF_DRAM_ILV_V4D2_CHAN_NPS2_10CH_2K	0x29
681 #define	DF_DRAM_ILV_V4_GET_CHAN(r)		bitx32(r, 8, 4)
682 #define	DF_DRAM_ILV_V4_CHAN_1			0x0
683 #define	DF_DRAM_ILV_V4_CHAN_2			0x1
684 #define	DF_DRAM_ILV_V4_CHAN_4			0x3
685 #define	DF_DRAM_ILV_V4_CHAN_8			0x5
686 #define	DF_DRAM_ILV_V4_CHAN_16			0x7
687 #define	DF_DRAM_ILV_V4_CHAN_32			0x8
688 #define	DF_DRAM_ILV_V4_CHAN_NPS4_2CH		0x10
689 #define	DF_DRAM_ILV_V4_CHAN_NPS2_4CH		0x11
690 #define	DF_DRAM_ILV_V4_CHAN_NPS1_8CH		0x12
691 #define	DF_DRAM_ILV_V4_CHAN_NPS4_3CH		0x13
692 #define	DF_DRAM_ILV_V4_CHAN_NPS2_6CH		0x14
693 #define	DF_DRAM_ILV_V4_CHAN_NPS1_12CH		0x15
694 #define	DF_DRAM_ILV_V4_CHAN_NPS2_5CH		0x16
695 #define	DF_DRAM_ILV_V4_CHAN_NPS1_10CH		0x17
696 #define	DF_DRAM_ILV_V4_GET_ADDR(r)		bitx32(r, 2, 0)
697 
698 /*
699  * DF::DramOffset --  These exist only for CS entries, e.g. a UMC. There is
700  * generally only one of these in Zen 1-3. This register changes in Zen 4 and
701  * there are up to 3 instances there. This register corresponds to each DRAM
702  * rule that the UMC has starting at the second one. This is because the first
703  * DRAM rule in a channel always is defined to start at offset 0, so there is no
704  * entry here.
705  */
706 /*CSTYLED*/
707 #define	DF_DRAM_OFFSET_V2	(df_reg_def_t){ .drd_gens = DF_REV_ALL_23, \
708 				.drd_func = 0, \
709 				.drd_reg = 0x1b4 }
710 /*CSTYLED*/
711 #define	DF_DRAM_OFFSET_V4(r)	(df_reg_def_t){ .drd_gens = DF_REV_ALL_4, \
712 				.drd_func = 7, \
713 				.drd_reg = 0x140 + ((r) * 4) }
714 #define	DF_DRAM_OFFSET_V2_GET_OFFSET(r)		bitx32(r, 31, 20)
715 #define	DF_DRAM_OFFSET_V3_GET_OFFSET(r)		bitx32(r, 31, 12)
716 #define	DF_DRAM_OFFSET_V4_GET_OFFSET(r)		bitx32(r, 24, 1)
717 #define	DF_DRAM_OFFSET_SHIFT			28
718 #define	DF_DRAM_OFFSET_GET_EN(r)		bitx32(r, 0, 0)
719 
720 /*
721  * DF::VGAEn -- This controls whether or not the historical x86 VGA
722  * compatibility region is enabled or not.
723  */
724 /*CSTYLED*/
725 #define	DF_VGA_EN_V2		(df_reg_def_t){ .drd_gens = DF_REV_ALL_23, \
726 				.drd_func = 0, \
727 				.drd_reg = 0x80 }
728 /*CSTYLED*/
729 #define	DF_VGA_EN_V4		(df_reg_def_t){ .drd_gens = DF_REV_ALL_4, \
730 				.drd_func = 0, \
731 				.drd_reg = 0xc08 }
732 
733 #define	DF_VGA_EN_GET_FABID(r)		bitx32(r, 15, 4)
734 #define	DF_VGA_EN_GET_CPUDIS(r)		bitx32(r, 2, 2)
735 #define	DF_VGA_EN_GET_NP(r)		bitx32(r, 1, 1)
736 #define	DF_VGA_EN_GET_EN(r)		bitx32(r, 0, 0)
737 
738 /*
739  * DF::MmioPciCfgBaseAddr, DF::MmioPciCfgBaseAddrExt, DF::MmioPciCfgLimitAddr,
740  * DF::MmioPciCfgLimitAddrExt -- These are DFv4 additions that control where PCI
741  * extended configuration space is and whether or not the DF honors this. This
742  * must match the values programmed into the CPU. Prior to DFv4, there was not a
743  * DF setting for this. The encoded values of the base and limit are the same.
744  */
745 /*CSTYLED*/
746 #define	DF_ECAM_BASE_V4		(df_reg_def_t){ .drd_gens = DF_REV_ALL_4, \
747 				.drd_func = 0, \
748 				.drd_reg = 0xc10 }
749 /*CSTYLED*/
750 #define	DF_ECAM_BASE_EXT_V4	(df_reg_def_t){ .drd_gens = DF_REV_ALL_4, \
751 				.drd_func = 0, \
752 				.drd_reg = 0xc14 }
753 /*CSTYLED*/
754 #define	DF_ECAM_LIMIT_V4		(df_reg_def_t){ .drd_gens = DF_REV_ALL_4, \
755 				.drd_func = 0, \
756 				.drd_reg = 0xc18 }
757 /*CSTYLED*/
758 #define	DF_ECAM_LIMIT_EXT_V4	(df_reg_def_t){ .drd_gens = DF_REV_ALL_4, \
759 				.drd_func = 0, \
760 				.drd_reg = 0xc1c }
761 #define	DF_ECAM_V4_GET_ADDR(r)		bitx32(r, 31, 20)
762 #define	DF_ECAM_V4_SET_ADDR(r, v)	bitset32(r, 31, 20, v)
763 #define	DF_ECAM_V4_ADDR_SHIFT		20
764 #define	DF_ECAM_LIMIT_EXCL		(1 << DF_ECAM_V4_ADDR_SHIFT)
765 #define	DF_ECAM_BASE_V4_GET_EN(r)	bitx32(r, 0, 0)
766 #define	DF_ECAM_BASE_V4_SET_EN(r, v)	bitset32(r, 0, 0, v)
767 #define	DF_ECAM_EXT_V4_GET_ADDR(r)	bitx32(r, 23, 0)
768 #define	DF_ECAM_EXT_V4_SET_ADDR(r, v)	bitset32(r, 23, 0, v)
769 #define	DF_ECAM_EXT_V4_ADDR_SHIFT	32
770 
771 /*
772  * DF::MmioBaseAddress, DF::MmioLimitAddress, DF::MmioAddressControl -- These
773  * control the various MMIO rules for a given system.
774  */
775 /*CSTYLED*/
776 #define	DF_MMIO_BASE_V2(x)	(df_reg_def_t){ .drd_gens = DF_REV_ALL_23, \
777 				.drd_func = 0, \
778 				.drd_reg = 0x200 + ((x) * 0x10) }
779 /*CSTYLED*/
780 #define	DF_MMIO_LIMIT_V2(x)	(df_reg_def_t){ .drd_gens = DF_REV_ALL_23, \
781 				.drd_func = 0, \
782 				.drd_reg = 0x204 + ((x) * 0x10) }
783 /*CSTYLED*/
784 #define	DF_MMIO_BASE_V4(x)	(df_reg_def_t){ .drd_gens = DF_REV_ALL_4, \
785 				.drd_func = 0, \
786 				.drd_reg = 0xd80 + ((x) * 0x10) }
787 /*CSTYLED*/
788 #define	DF_MMIO_LIMIT_V4(x)	(df_reg_def_t){ .drd_gens = DF_REV_ALL_4, \
789 				.drd_func = 0, \
790 				.drd_reg = 0xd84 + ((x) * 0x10) }
791 #define	DF_MMIO_SHIFT		16
792 #define	DF_MMIO_LIMIT_EXCL	(1 << DF_MMIO_SHIFT)
793 #define	DF_MAX_MMIO_RULES	16
794 #define	DF_MAX_MMIO_RULES_TURIN	32
795 /*CSTYLED*/
796 #define	DF_MMIO_CTL_V2(x)	(df_reg_def_t){ .drd_gens = DF_REV_ALL_23, \
797 				.drd_func = 0, \
798 				.drd_reg = 0x208 + ((x) * 0x10) }
799 /*CSTYLED*/
800 #define	DF_MMIO_CTL_V4(x)	(df_reg_def_t){ .drd_gens = DF_REV_ALL_4, \
801 				.drd_func = 0, \
802 				.drd_reg = 0xd88 + ((x) * 0x10) }
803 #define	DF_MMIO_CTL_V2_GET_NP(r)	bitx32(r, 12, 12)
804 #define	DF_MMIO_CTL_V2_GET_DEST_ID(r)	bitx32(r, 11, 4)
805 #define	DF_MMIO_CTL_V2_SET_NP(r, v)		bitset32(r, 12, 12, v)
806 #define	DF_MMIO_CTL_V2_SET_DEST_ID(r, v)	bitset32(r, 11, 4, v)
807 
808 #define	DF_MMIO_CTL_V3_GET_NP(r)	bitx32(r, 16, 16)
809 #define	DF_MMIO_CTL_V3_GET_DEST_ID(r)	bitx32(r, 13, 4)
810 #define	DF_MMIO_CTL_V3P5_GET_DEST_ID(r)	bitx32(r, 7, 4)
811 #define	DF_MMIO_CTL_V3_SET_NP(r, v)		bitset32(r, 16, 16, v)
812 #define	DF_MMIO_CTL_V3_SET_DEST_ID(r, v)	bitset32(r, 13, 4, v)
813 #define	DF_MMIO_CTL_V3P5_SET_DEST_ID(r, v)	bitset32(r, 7, 4, v)
814 
815 #define	DF_MMIO_CTL_V4_GET_DEST_ID(r)	bitx32(r, 27, 16)
816 #define	DF_MMIO_CTL_V4D2_GET_DEST_ID(r)	bitx32(r, 23, 16)
817 #define	DF_MMIO_CTL_V4_GET_NP(r)	bitx32(r, 3, 3)
818 #define	DF_MMIO_CTL_V4_SET_DEST_ID(r, v)	bitset32(r, 27, 16, v)
819 #define	DF_MMIO_CTL_V4D2_SET_DEST_ID(r, v)	bitset32(r, 23, 16, v)
820 #define	DF_MMIO_CTL_V4_SET_NP(r, v)		bitset32(r, 3, 3, v)
821 
822 #define	DF_MMIO_CTL_GET_CPU_DIS(r)	bitx32(r, 2, 2)
823 #define	DF_MMIO_CTL_GET_WE(r)		bitx32(r, 1, 1)
824 #define	DF_MMIO_CTL_GET_RE(r)		bitx32(r, 0, 0)
825 #define	DF_MMIO_CTL_SET_CPU_DIS(r, v)		bitset32(r, 2, 2, v)
826 #define	DF_MMIO_CTL_SET_WE(r, v)		bitset32(r, 1, 1, v)
827 #define	DF_MMIO_CTL_SET_RE(r, v)		bitset32(r, 0, 0, v)
828 
829 /*
830  * DF::MmioExtAddress -- New in DFv4, this allows extending the number of bits
831  * used for MMIO.
832  */
833 /*CSTYLED*/
834 #define	DF_MMIO_EXT_V4(x)	(df_reg_def_t){ .drd_gens = DF_REV_ALL_4, \
835 				.drd_func = 0, \
836 				.drd_reg = 0xd8c + ((x) * 0x10) }
837 #define	DF_MMIO_EXT_V4_GET_LIMIT(r)	bitx32(r, 23, 16)
838 #define	DF_MMIO_EXT_V4_GET_BASE(r)	bitx32(r, 7, 0)
839 #define	DF_MMIO_EXT_V4_SET_LIMIT(r, v)	bitset32(r, 23, 16, v)
840 #define	DF_MMIO_EXT_V4_SET_BASE(r, v)	bitset32(r, 7, 0, v)
841 #define	DF_MMIO_EXT_SHIFT		48
842 
843 /*
844  * DF::DfGlobalCtrl -- This register we generally only care about in the
845  * DFv3/3.5 timeframe when it has the actual hash controls, hence its current
846  * definition. It technically exists in DFv2/v4, but is not relevant.
847  */
848 /*CSTYLED*/
849 #define	DF_GLOB_CTL_V3		(df_reg_def_t){ .drd_gens = DF_REV_ALL_3, \
850 				.drd_func = 0, \
851 				.drd_reg = 0x3F8 }
852 #define	DF_GLOB_CTL_V3_GET_HASH_1G(r)	bitx32(r, 22, 22)
853 #define	DF_GLOB_CTL_V3_GET_HASH_2M(r)	bitx32(r, 21, 21)
854 #define	DF_GLOB_CTL_V3_GET_HASH_64K(r)	bitx32(r, 20, 20)
855 
856 /*
857  * DF::SystemCfg -- This register describes the basic information about the data
858  * fabric that we're talking to. Don't worry, this is different in every
859  * generation, even when the address is the same. Somehow despite all these
860  * differences the actual things like defined types are somehow the same.
861  */
862 typedef enum {
863 	DF_DIE_TYPE_CPU	= 0,
864 	DF_DIE_TYPE_APU,
865 	DF_DIE_TYPE_dGPU
866 } df_die_type_t;
867 
868 /*CSTYLED*/
869 #define	DF_SYSCFG_V2		(df_reg_def_t){ .drd_gens = DF_REV_2, \
870 				.drd_func = 1, \
871 				.drd_reg = 0x200 }
872 #define	DF_SYSCFG_V2_GET_SOCK_ID(r)	bitx32(r, 27, 27)
873 #define	DF_SYSCFG_V2_GET_DIE_ID(r)	bitx32(r, 25, 24)
874 #define	DF_SYSCFG_V2_GET_MY_TYPE(r)	bitx32(r, 22, 21)
875 #define	DF_SYSCFG_V2_GET_LOCAL_IS_ME(r)	bitx32(r, 19, 16)
876 #define	DF_SYSCFG_V2_GET_LOCAL_TYPE3(r)	bitx32(r, 13, 12)
877 #define	DF_SYSCFG_V2_GET_LOCAL_TYPE2(r)	bitx32(r, 11, 10)
878 #define	DF_SYSCFG_V2_GET_LOCAL_TYPE1(r)	bitx32(r, 9, 8)
879 #define	DF_SYSCFG_V2_GET_LOCAL_TYPE0(r)	bitx32(r, 7, 6)
880 #define	DF_SYSCFG_V2_GET_OTHER_SOCK(r)	bitx32(r, 5, 5)
881 #define	DF_SYSCFG_V2_GET_DIE_PRESENT(r)	bitx32(r, 4, 0)
882 #define	DF_SYSCFG_V2_DIE_PRESENT(x)	bitx32(r, 3, 0)
883 
884 /*CSTYLED*/
885 #define	DF_SYSCFG_V3		(df_reg_def_t){ .drd_gens = DF_REV_3, \
886 				.drd_func = 1, \
887 				.drd_reg = 0x200 }
888 #define	DF_SYSCFG_V3_GET_NODE_ID(r)	bitx32(r, 30, 28)
889 #define	DF_SYSCFG_V3_GET_OTHER_SOCK(r)	bitx32(r, 27, 27)
890 #define	DF_SYSCFG_V3_GET_OTHER_TYPE(r)	bitx32(r, 26, 25)
891 #define	DF_SYSCFG_V3_GET_MY_TYPE(r)	bitx32(r, 24, 23)
892 #define	DF_SYSCFG_V3_GET_DIE_TYPE(r)	bitx32(r, 18, 11)
893 #define	DF_SYSCFG_V3_GET_DIE_PRESENT(r)	bitx32(r, 7, 0)
894 
895 /*CSTYLED*/
896 #define	DF_SYSCFG_V3P5		(df_reg_def_t){ .drd_gens = DF_REV_3P5, \
897 				.drd_func = 1, \
898 				.drd_reg = 0x140 }
899 #define	DF_SYSCFG_V3P5_GET_NODE_ID(r)		bitx32(r, 19, 16)
900 #define	DF_SYSCFG_V3P5_GET_OTHER_SOCK(r)	bitx32(r, 8, 8)
901 #define	DF_SYSCFG_V3P5_GET_NODE_MAP(r)		bitx32(r, 4, 4)
902 #define	DF_SYSCFG_V3P5_GET_OTHER_TYPE(r)	bitx32(r, 3, 2)
903 #define	DF_SYSCFG_V3P5_GET_MY_TYPE(r)		bitx32(r, 1, 0)
904 
905 /*CSTYLED*/
906 #define	DF_SYSCFG_V4		(df_reg_def_t){ .drd_gens = DF_REV_ALL_4, \
907 				.drd_func = 4, \
908 				.drd_reg = 0x180 }
909 #define	DF_SYSCFG_V4_GET_NODE_ID(r)	bitx32(r, 27, 16)
910 #define	DF_SYSCFG_V4D2_GET_NODE_ID(r)	bitx32(r, 23, 16)
911 #define	DF_SYSCFG_V4_GET_OTHER_SOCK(r)	bitx32(r, 8, 8)
912 #define	DF_SYSCFG_V4_GET_NODE_MAP(r)	bitx32(r, 4, 4)
913 #define	DF_SYSCFG_V4_GET_OTHER_TYPE(r)	bitx32(r, 3, 2)
914 #define	DF_SYSCFG_V4_GET_MY_TYPE(r)	bitx32(r, 1, 0)
915 
916 /*
917  * DF::SystemComponentCnt -- Has a count of how many things are here. However,
918  * this does not seem defined for DFv3.5
919  */
920 /*CSTYLED*/
921 #define	DF_COMPCNT_V2		(df_reg_def_t){ .drd_gens = DF_REV_ALL_23, \
922 				.drd_func = 1, \
923 				.drd_reg = 0x204 }
924 #define	DF_COMPCNT_V2_GET_IOMS(r)	bitx32(r, 23, 16)
925 #define	DF_COMPCNT_V2_GET_GCM(r)	bitx32(r, 15, 8)
926 #define	DF_COMPCNT_V2_GET_PIE(r)	bitx32(r, 7, 0)
927 
928 /*CSTYLED*/
929 #define	DF_COMPCNT_V4		(df_reg_def_t){ .drd_gens = DF_REV_ALL_4, \
930 				.drd_func = 4, \
931 				.drd_reg = 0x184 }
932 #define	DF_COMPCNT_V4_GET_IOS(r)	bitx32(r, 31, 26)
933 #define	DF_COMPCNT_V4_GET_GCM(r)	bitx32(r, 25, 16)
934 #define	DF_COMPCNT_V4_GET_IOM(r)	bitx32(r, 15, 8)
935 #define	DF_COMPCNT_V4_GET_PIE(r)	bitx32(r, 7, 0)
936 
937 /*
938  * This next section contains a bunch of register definitions for how to take
939  * apart ID masks. The register names and sets have changed across every DF
940  * revision. This will be done in chunks that define all DFv2, then v3, etc.
941  */
942 
943 /*
944  * DF::SystemFabricIdMask -- DFv2 style breakdowns of IDs. Note, unlike others
945  * the socket and die shifts are not relative to a node mask, but are global.
946  */
947 /*CSTYLED*/
948 #define	DF_FIDMASK_V2		(df_reg_def_t){ .drd_gens = DF_REV_2, \
949 				.drd_func = 1, \
950 				.drd_reg = 0x208 }
951 #define	DF_FIDMASK_V2_GET_SOCK_SHIFT(r)		bitx32(r, 31, 28)
952 #define	DF_FIDMASK_V2_GET_DIE_SHIFT(r)		bitx32(r, 27, 24)
953 #define	DF_FIDMASK_V2_GET_SOCK_MASK(r)		bitx32(r, 23, 16)
954 #define	DF_FIDMASK_V2_GET_DIE_MASK(r)		bitx32(r, 15, 8)
955 
956 /*
957  * DF::SystemFabricIdMask0, DF::SystemFabricIdMask1 -- The DFv3 variant of
958  * breaking down an ID into bits and shifts. Unlike in DFv2, the socket and die
959  * are relative to a node ID. For more, see amdzen_determine_fabric_decomp() in
960  * uts/intel/io/amdzen/amdzen.c.
961  */
962 /*CSTYLED*/
963 #define	DF_FIDMASK0_V3		(df_reg_def_t){ .drd_gens = DF_REV_3, \
964 				.drd_func = 1, \
965 				.drd_reg = 0x208 }
966 #define	DF_FIDMASK0_V3_GET_NODE_MASK(r)		bitx32(r, 25, 16)
967 #define	DF_FIDMASK0_V3_GET_COMP_MASK(r)		bitx32(r, 9, 0)
968 /*CSTYLED*/
969 #define	DF_FIDMASK1_V3		(df_reg_def_t){ .drd_gens = DF_REV_3, \
970 				.drd_func = 1, \
971 				.drd_reg = 0x20c }
972 #define	DF_FIDMASK1_V3_GET_SOCK_MASK(r)		bitx32(r, 26, 24)
973 #define	DF_FIDMASK1_V3_GET_DIE_MASK(r)		bitx32(r, 18, 16)
974 #define	DF_FIDMASK1_V3_GET_SOCK_SHIFT(r)	bitx32(r, 9, 8)
975 #define	DF_FIDMASK1_V3_GET_NODE_SHIFT(r)	bitx32(r, 3, 0)
976 
977 /*
978  * DF::SystemFabricIdMask0, DF::SystemFabricIdMask1, DF::SystemFabricIdMask2 --
979  * DFv3.5 and DFv4 have the same format here, but in different registers.
980  */
981 /*CSTYLED*/
982 #define	DF_FIDMASK0_V3P5	(df_reg_def_t){ .drd_gens = DF_REV_3P5, \
983 				.drd_func = 1, \
984 				.drd_reg = 0x150 }
985 /*CSTYLED*/
986 #define	DF_FIDMASK0_V4		(df_reg_def_t){ .drd_gens = DF_REV_ALL_4, \
987 				.drd_func = 4, \
988 				.drd_reg = 0x1b0 }
989 #define	DF_FIDMASK0_V3P5_GET_NODE_MASK(r)	bitx32(r, 31, 16)
990 #define	DF_FIDMASK0_V3P5_GET_COMP_MASK(r)	bitx32(r, 15, 0)
991 /*CSTYLED*/
992 #define	DF_FIDMASK1_V3P5	(df_reg_def_t){ .drd_gens = DF_REV_3P5, \
993 				.drd_func = 1, \
994 				.drd_reg = 0x154 }
995 /*CSTYLED*/
996 #define	DF_FIDMASK1_V4		(df_reg_def_t){ .drd_gens = DF_REV_ALL_4, \
997 				.drd_func = 4, \
998 				.drd_reg = 0x1b4 }
999 #define	DF_FIDMASK1_V3P5_GET_SOCK_SHIFT(r)	bitx32(r, 11, 8)
1000 #define	DF_FIDMASK1_V3P5_GET_NODE_SHIFT(r)	bitx32(r, 3, 0)
1001 /*CSTYLED*/
1002 #define	DF_FIDMASK2_V3P5	(df_reg_def_t){ .drd_gens = DF_REV_3P5, \
1003 				.drd_func = 1, \
1004 				.drd_reg = 0x158 }
1005 /*CSTYLED*/
1006 #define	DF_FIDMASK2_V4		(df_reg_def_t){ .drd_gens = DF_REV_ALL_4, \
1007 				.drd_func = 4, \
1008 				.drd_reg = 0x1b8 }
1009 #define	DF_FIDMASK2_V3P5_GET_SOCK_MASK(r)	bitx32(r, 31, 16)
1010 #define	DF_FIDMASK2_V3P5_GET_DIE_MASK(r)	bitx32(r, 15, 0)
1011 
1012 /*
1013  * DF::DieFabricIdMask -- This is a Zeppelin, DFv2 special. There are a couple
1014  * instances of this for different types of devices; however, this is where the
1015  * component mask is actually stored. This is replicated for a CPU, APU, and
1016  * dGPU, each with slightly different values. We need to look at DF_SYSCFG_V2 to
1017  * determine which type of die we have and use the appropriate one when looking
1018  * at this. This makes the Zen 1 CPUs and APUs have explicitly different set up
1019  * here. Look, it got better in DFv3.
1020  */
1021 /*CSTYLED*/
1022 #define	DF_DIEMASK_CPU_V2	(df_reg_def_t){ .drd_gens = DF_REV_2, \
1023 				.drd_func = 1, \
1024 				.drd_reg = 0x22c }
1025 /*CSTYLED*/
1026 #define	DF_DIEMASK_APU_V2	(df_reg_def_t){ .drd_gens = DF_REV_2, \
1027 				.drd_func = 1, \
1028 				.drd_reg = 0x24c }
1029 #define	DF_DIEMASK_V2_GET_SOCK_SHIFT(r)		bitx32(r, 31, 28)
1030 #define	DF_DIEMASK_V2_GET_DIE_SHIFT(r)		bitx32(r, 27, 24)
1031 #define	DF_DIEMASK_V2_GET_SOCK_MASK(r)		bitx32(r, 23, 16)
1032 #define	DF_DIEMASK_V2_GET_DIE_MASK(r)		bitx32(r, 15, 8)
1033 #define	DF_DIEMASK_V2_GET_COMP_MASK(r)		bitx32(r, 7, 0)
1034 
1035 /*
1036  * DF::CCDEnable -- This register is present for CCMs and ACMs. Despite its
1037  * name, the interpretation is not quite straightforward. That is, it only
1038  * indirectly tells us about whether or not there are two CCDs or not. A CCM
1039  * port can be in wide mode where its two SDPs (Scalable Data Ports) are in fact
1040  * instead connected to a single CCD. If wide mode is enabled in DF::CCMConfig4,
1041  * then a value of 0x3 just indicates that both SDP ports are connected to a
1042  * single CCD. For DFv4D2, the wide mode bit is moved from DF::CCMConfig4 to
1043  * this register itself.
1044  *
1045  * The CCX related fields are only valid when the dense mode is enabled in the
1046  * global DF controls. If a CPU doesn't support that, then that field is
1047  * reserved. We don't generally recommend this as a way of determining if
1048  * multiple CCX units are present on the CCD because it is tied to DFv4.
1049  */
1050 #define	DF_MAX_CCDS_PER_CCM	2
1051 /*CSTYLED*/
1052 #define	DF_CCD_EN_V4		(df_reg_def_t){ .drd_gens = DF_REV_ALL_4, \
1053 				.drd_func = 1, \
1054 				.drd_reg = 0x104 }
1055 #define	DF_CCD_EN_V4D2_GET_WIDE_EN(r)	bitx32(r, 31, 31)
1056 #define	DF_CCD_EN_V4_GET_CCX_EN(r)	bitx32(r, 17, 16)
1057 #define	DF_CCD_EN_V4_GET_CCD_EN(r)	bitx32(r, 1, 0)
1058 
1059 
1060 /*
1061  * DF::PhysicalCoreEnable0, etc. -- These registers can be used to tell us which
1062  * cores are actually enabled. This appears to have been introduced in DFv3.
1063  * DFv4 expanded this from two registers to several more. The number that are
1064  * valid vary based upon the CPU family.
1065  */
1066 /*CSTYLED*/
1067 #define	DF_PHYS_CORE_EN0_V3	(df_reg_def_t){ .drd_gens = DF_REV_ALL_3, \
1068 				.drd_func = 1, \
1069 				.drd_reg = 0x300 }
1070 /*CSTYLED*/
1071 #define	DF_PHYS_CORE_EN1_V3	(df_reg_def_t){ .drd_gens = DF_REV_ALL_3, \
1072 				.drd_func = 1, \
1073 				.drd_reg = 0x304 }
1074 /*CSTYLED*/
1075 #define	DF_PHYS_CORE_EN0_V4	(df_reg_def_t){ .drd_gens = DF_REV_ALL_4, \
1076 				.drd_func = 1, \
1077 				.drd_reg = 0x140 }
1078 /*CSTYLED*/
1079 #define	DF_PHYS_CORE_EN1_V4	(df_reg_def_t){ .drd_gens = DF_REV_ALL_4, \
1080 				.drd_func = 1, \
1081 				.drd_reg = 0x144 }
1082 /*CSTYLED*/
1083 #define	DF_PHYS_CORE_EN2_V4	(df_reg_def_t){ .drd_gens = DF_REV_ALL_4, \
1084 				.drd_func = 1, \
1085 				.drd_reg = 0x148 }
1086 /*CSTYLED*/
1087 #define	DF_PHYS_CORE_EN3_V4	(df_reg_def_t){ .drd_gens = DF_REV_ALL_4, \
1088 				.drd_func = 1, \
1089 				.drd_reg = 0x14c }
1090 /*CSTYLED*/
1091 #define	DF_PHYS_CORE_EN4_V4	(df_reg_def_t){ .drd_gens = DF_REV_ALL_4, \
1092 				.drd_func = 1, \
1093 				.drd_reg = 0x150 }
1094 /*CSTYLED*/
1095 #define	DF_PHYS_CORE_EN5_V4	(df_reg_def_t){ .drd_gens = DF_REV_ALL_4, \
1096 				.drd_func = 1, \
1097 				.drd_reg = 0x154 }
1098 
1099 /*
1100  * DF::Np2ChannelConfig -- This is used in Milan to contain information about
1101  * how non-power of 2 based channel configuration works. Note, we only know that
1102  * this exists in Milan (and its ThreadRipper equivalent). We don't believe it
1103  * is in other DFv3 products like Rome, Matisse, Vermeer, or the APUs.
1104  */
1105 /*CSTYLED*/
1106 #define	DF_NP2_CONFIG_V3	(df_reg_def_t){ .drd_gens = DF_REV_3, \
1107 				.drd_func = 2, \
1108 				.drd_reg = 0x90 }
1109 #define	DF_NP2_CONFIG_V3_GET_SPACE1(r)		bitx32(r, 13, 8)
1110 #define	DF_NP2_CONFIG_V3_GET_SPACE0(r)		bitx32(r, 5, 0)
1111 
1112 /*
1113  * DF::CCMConfig4 -- This is one of several CCM configuration related registers.
1114  * This varies in each DF revision. That is, while we've found it does exist in
1115  * DFv3, it is at a different address and the bits have rather different
1116  * meanings. A subset of the bits are defined below based upon our needs.
1117  * The wide mode bit is moved to DF::CCDEnable in DFv4D2.
1118  */
1119 /*CSTYLED*/
1120 #define	DF_CCMCFG4_V4		(df_reg_def_t){ .drd_gens = DF_REV_4, \
1121 				.drd_func = 3, \
1122 				.drd_reg = 0x510 }
1123 #define	DF_CCMCFG4_V4_GET_WIDE_EN(r)		bitx32(r, 26, 26)
1124 
1125 /*
1126  * DF::FabricIndirectConfigAccessAddress, DF::FabricIndirectConfigAccessDataLo,
1127  * DF::FabricIndirectConfigAccessDataHi --  These registers are used to define
1128  * Indirect Access, commonly known as FICAA and FICAD for the system. While
1129  * there are multiple copies of the indirect access registers in device 4, we're
1130  * only allowed access to one set of those (which are the ones present here).
1131  * Specifically the OS is given access to set 3.
1132  */
1133 /*CSTYLED*/
1134 #define	DF_FICAA_V2		(df_reg_def_t){ .drd_gens = DF_REV_ALL_23, \
1135 				.drd_func = 4, \
1136 				.drd_reg = 0x5c }
1137 #define	DF_FICAA_V2_REG_MASK	0x7fc
1138 /*CSTYLED*/
1139 #define	DF_FICAA_V4		(df_reg_def_t){ .drd_gens = DF_REV_ALL_4, \
1140 				.drd_func = 4, \
1141 				.drd_reg = 0x8c }
1142 #define	DF_FICAA_V4_REG_MASK	0xffc
1143 /*
1144  * Across all current versions, the register ignores the lower 2 bits.
1145  * That is we can only address and encode things in units of 4 bytes.
1146  */
1147 #define	DF_FICAA_REG_SHIFT	2
1148 
1149 #define	DF_FICAA_V2_SET_INST(r, v)		bitset32(r, 23, 16, v)
1150 #define	DF_FICAA_V2_SET_64B(r, v)		bitset32(r, 14, 14, v)
1151 #define	DF_FICAA_V2_SET_FUNC(r, v)		bitset32(r, 13, 11, v)
1152 #define	DF_FICAA_V2_SET_REG(r, v)		bitset32(r, 10, 2, v)
1153 #define	DF_FICAA_V2_SET_TARG_INST(r, v)		bitset32(r, 0, 0, v)
1154 
1155 #define	DF_FICAA_V4_SET_REG(r, v)		bitset32(r, 10, 1, v)
1156 
1157 /*CSTYLED*/
1158 #define	DF_FICAD_LO_V2		(df_reg_def_t){ .drd_gens = DF_REV_ALL_23, \
1159 				.drd_func = 4, \
1160 				.drd_reg = 0x98}
1161 /*CSTYLED*/
1162 #define	DF_FICAD_HI_V2		(df_reg_def_t){ .drd_gens = DF_REV_ALL_23, \
1163 				.drd_func = 4, \
1164 				.drd_reg = 0x9c}
1165 /*CSTYLED*/
1166 #define	DF_FICAD_LO_V4		(df_reg_def_t){ .drd_gens = DF_REV_ALL_4, \
1167 				.drd_func = 4, \
1168 				.drd_reg = 0xb8}
1169 /*CSTYLED*/
1170 #define	DF_FICAD_HI_V4		(df_reg_def_t){ .drd_gens = DF_REV_ALL_4, \
1171 				.drd_func = 4, \
1172 				.drd_reg = 0xbc}
1173 
1174 /*
1175  * Check whether a given register definition is valid for the given DF revision.
1176  */
1177 static inline boolean_t
1178 df_reg_valid(const df_rev_t rev, const df_reg_def_t def)
1179 {
1180 	uint16_t mask;
1181 
1182 	switch (rev) {
1183 	case DF_REV_2:
1184 	case DF_REV_3:
1185 	case DF_REV_3P5:
1186 		mask = DF_FICAA_V2_REG_MASK;
1187 		break;
1188 	case DF_REV_4:
1189 	case DF_REV_4D2:
1190 		mask = DF_FICAA_V4_REG_MASK;
1191 		break;
1192 	default:
1193 		return (B_FALSE);
1194 	}
1195 
1196 	return ((def.drd_gens & rev) == rev && (def.drd_reg & ~mask) == 0);
1197 }
1198 
1199 /*
1200  * DF::SpecialSysFunctionFabricID1, DF::SpecialSysFunctionFabricID2 -- These
1201  * registers are used to look up the FabricID of various functional groups.
1202  * These exist in DFv3 and DFv4 at different addresses with slightly different
1203  * field widths.
1204  */
1205 /*CSTYLED*/
1206 #define	DF_SYS_FUN_FID1_V3	(df_reg_def_t){ .drd_gens = DF_REV_ALL_3, \
1207 				.drd_func = 1, \
1208 				.drd_reg = 0x60 }
1209 #define	DF_SYS_FUN_FID1_V3_GET_MSTR_PIE_FID(r)		bitx32(r, 21, 16)
1210 #define	DF_SYS_FUN_FID1_V3_GET_LCL_PIE_FID(r)		bitx32(r, 5, 0)
1211 
1212 /*CSTYLED*/
1213 #define	DF_SYS_FUN_FID1_V4	(df_reg_def_t){ .drd_gens = DF_REV_ALL_4, \
1214 				.drd_func = 4, \
1215 				.drd_reg = 0x190 }
1216 #define	DF_SYS_FUN_FID1_V4_GET_MSTR_PIE_FID(r)		bitx32(r, 27, 16)
1217 #define	DF_SYS_FUN_FID1_V4D2_GET_MSTR_PIE_FID(r)	bitx32(r, 23, 16)
1218 #define	DF_SYS_FUN_FID1_V4_GET_LCL_PIE_FID(r)		bitx32(r, 11, 0)
1219 #define	DF_SYS_FUN_FID1_V4D2_GET_LCL_PIE_FID(r)		bitx32(r, 7, 0)
1220 
1221 /*CSTYLED*/
1222 #define	DF_SYS_FUN_FID2_V3	(df_reg_def_t){ .drd_gens = DF_REV_ALL_3, \
1223 				.drd_func = 1, \
1224 				.drd_reg = 0x64 }
1225 #define	DF_SYS_FUN_FID2_V3_GET_FCH_IOMS_FID(r)		bitx32(r, 21, 16)
1226 #define	DF_SYS_FUN_FID2_V3_GET_LCL_IOMS_FID(r)		bitx32(r, 5, 0)
1227 
1228 /*CSTYLED*/
1229 #define	DF_SYS_FUN_FID2_V4	(df_reg_def_t){ .drd_gens = DF_REV_ALL_4, \
1230 				.drd_func = 4, \
1231 				.drd_reg = 0x194 }
1232 #define	DF_SYS_FUN_FID2_V4_GET_FCH_IOS_FID(r)		bitx32(r, 27, 16)
1233 #define	DF_SYS_FUN_FID2_V4D2_GET_FCH_IOS_FID(r)		bitx32(r, 23, 16)
1234 
1235 #ifdef __cplusplus
1236 }
1237 #endif
1238 
1239 #endif /* _SYS_AMDZEN_DF_H */
1240