xref: /illumos-gate/usr/src/uts/intel/sys/amdzen/df.h (revision de41ff85dfbbbd7520fbd23aaef504a9d9bd5138)
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 _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.
35  *
36  * To make things a little easier for clients, each register definition encodes
37  * enough information to also include which hardware generations it supports,
38  * the actual PCI function it appears upon, and the register offset. This is to
39  * make sure that consumers don't have to guess some of this information in the
40  * latter cases and we can try to guarantee we're not accessing an incorrect
41  * register for our platform (unfortunately at runtime).
42  *
43  * Register definitions have the following form:
44  *
45  * DF_<reg name>_<vers>
46  *
47  * Here <reg name> is something that describes the register. This may not be the
48  * exact same as the PPR (processor programming reference); however, the PPR
49  * name for the register will be included above it in a comment (though these
50  * have sometimes changed from time to time). For example, DF_DRAM_HOLE. If a
51  * given register is the same in all currently supported versions, then there is
52  * no version suffix appended. Otherwise, the first version it is supported in
53  * is appended. For example, DF_DRAM_BASE_V2, DF_DRAM_BASE_V3, DF_DRAM_BASE_V4,
54  * etc. or DF_FIDMASK0_V3P5, etc. If the register offset is the same in multiple
55  * versions, then there they share the earliest version.
56  *
57  * For fields there are currently macros to extract these or chain them together
58  * leveraging bitx32() and bitset32(). Fields have the forms:
59  *
60  * DF_<reg name>_<vers>_GET_<field>
61  * DF_<reg name>_<vers>_SET_<field>
62  *
63  * Like in the above, if there are cases where a single field is the same across
64  * all versions, then the <vers> portion will be elided. There are many cases
65  * where the register definition does not change, but the fields themselves do
66  * change with each version because each hardware rev opts to be slightly
67  * different.
68  *
69  * When adding support for a new chip, please look carefully through the
70  * requisite documentation to ensure that they match what we see here. There are
71  * often cases where there may be a subtle thing or you hit a case like V3P5
72  * that until you dig deeper just seem to be weird.
73  */
74 
75 #include <sys/bitext.h>
76 
77 #ifdef __cplusplus
78 extern "C" {
79 #endif
80 
81 typedef enum df_rev {
82 	DF_REV_UNKNOWN	= 0,
83 	DF_REV_2	= 1 << 0,
84 	DF_REV_3	= 1 << 1,
85 	DF_REV_3P5	= 1 << 2,
86 	DF_REV_4	= 1 << 3
87 } df_rev_t;
88 
89 #define	DF_REV_ALL_23	(DF_REV_2 | DF_REV_3 | DF_REV_3P5)
90 #define	DF_REV_ALL_3	(DF_REV_3 | DF_REV_3P5)
91 #define	DF_REV_ALL	(DF_REV_2 | DF_REV_3 | DF_REV_3P5 | DF_REV_4)
92 
93 typedef struct df_reg_def {
94 	df_rev_t	drd_gens;
95 	uint8_t		drd_func;
96 	uint16_t	drd_reg;
97 } df_reg_def_t;
98 
99 /*
100  * This set of registers provides us access to the count of instances in the
101  * data fabric and then a number of different pieces of information about them
102  * like their type. Note, these registers require indirect access because the
103  * information cannot be broadcast.
104  */
105 
106 /*
107  * DF::FabricBlockInstanceCount -- Describes the number of instances in the data
108  * fabric. With v4, also includes versioning information.
109  */
110 /*CSTYLED*/
111 #define	DF_FBICNT		(df_reg_def_t){ .drd_gens = DF_REV_ALL, \
112 				    .drd_func = 0, .drd_reg = 0x40 }
113 #define	DF_FBICNT_V4_GET_MAJOR(r)	bitx32(r, 27, 24)
114 #define	DF_FBICNT_V4_GET_MINOR(r)	bitx32(r, 23, 16)
115 #define	DF_FBICNT_GET_COUNT(r)		bitx32(r, 7, 0)
116 
117 /*
118  * DF::FabricBlockInstanceInformation0 -- get basic information about a fabric
119  * instance.
120  */
121 /*CSTYLED*/
122 #define	DF_FBIINFO0		(df_reg_def_t){ .drd_gens = DF_REV_ALL, \
123 				    .drd_func = 0, .drd_reg = 0x44 }
124 #define	DF_FBIINFO0_GET_SUBTYPE(r)	bitx32(r, 26, 24)
125 #define	DF_SUBTYPE_NONE	0
126 typedef enum {
127 	DF_CAKE_SUBTYPE_GMI = 1,
128 	DF_CAKE_SUBTYPE_xGMI = 2
129 } df_cake_subtype_t;
130 
131 typedef enum {
132 	DF_IOM_SUBTYPE_IOHUB = 1,
133 } df_iom_subtype_t;
134 
135 typedef enum {
136 	DF_CS_SUBTYPE_UMC = 1,
137 	/*
138 	 * The subtype changed beginning in DFv4. Prior to DFv4, the secondary
139 	 * type was CCIX. Starting with DFv4, this is now CMP. It is unclear if
140 	 * these are the same thing or not.
141 	 */
142 	DF_CS_SUBTYPE_CCIX = 2,
143 	DF_CS_SUBTYPE_CMP = 2
144 } df_cs_subtype_t;
145 
146 /*
147  * Note, this only exists in Genoa (maybe more generally Zen 4), otherwise it's
148  * always zero.
149  */
150 typedef enum {
151 	DF_CCM_SUBTYPE_CPU = 0,
152 	DF_CCM_SUBTYPE_ACM = 1
153 } df_ccm_subtype_v4_t;
154 #define	DF_FBIINFO0_GET_HAS_MCA(r)	bitx32(r, 23, 23)
155 #define	DF_FBIINFO0_GET_FTI_DCNT(r)	bitx32(r, 21, 20)
156 #define	DF_FBIINFO0_GET_FTI_PCNT(r)	bitx32(r, 18, 16)
157 #define	DF_FBIINFO0_GET_SDP_RESPCNT(r)	bitx32(r, 14, 14)
158 #define	DF_FBIINFO0_GET_SDP_PCNT(r)	bitx32(r, 13, 12)
159 #define	DF_FBIINFO0_GET_FTI_WIDTH(r)	bitx32(r, 9, 8)
160 typedef enum {
161 	DF_FTI_W_64 = 0,
162 	DF_FTI_W_128,
163 	DF_FTI_W_256,
164 	DF_FTI_W_512
165 } df_fti_width_t;
166 #define	DF_FBIINFO0_V3_GET_ENABLED(r)	bitx32(r, 6, 6)
167 #define	DF_FBIINFO0_GET_SDP_WIDTH(r)	bitx32(r, 5, 4)
168 typedef enum {
169 	DF_SDP_W_64 = 0,
170 	DF_SDP_W_128,
171 	DF_SDP_W_256,
172 	DF_SDP_W_512
173 } df_sdp_width_t;
174 #define	DF_FBIINFO0_GET_TYPE(r)		bitx32(r, 3, 0)
175 typedef enum {
176 	DF_TYPE_CCM = 0,
177 	DF_TYPE_GCM,
178 	DF_TYPE_NCM,
179 	DF_TYPE_IOMS,
180 	DF_TYPE_CS,
181 	DF_TYPE_NCS,
182 	DF_TYPE_TCDX,
183 	DF_TYPE_PIE,
184 	DF_TYPE_SPF,
185 	DF_TYPE_LLC,
186 	DF_TYPE_CAKE,
187 	DF_TYPE_CNLI = 0xd,
188 } df_type_t;
189 
190 /*
191  * DF::FabricBlockInstanceInformation1 -- get basic information about a fabric
192  * instance.
193  */
194 /*CSTYLED*/
195 #define	DF_FBIINFO1		(df_reg_def_t){ .drd_gens = DF_REV_ALL, \
196 				    .drd_func = 0, .drd_reg = 0x48 }
197 #define	DF_FBINFO1_GET_FTI3_NINSTID(r)		bitx32(r, 31, 24)
198 #define	DF_FBINFO1_GET_FTI2_NINSTID(r)		bitx32(r, 23, 16)
199 #define	DF_FBINFO1_GET_FTI1_NINSTID(r)		bitx32(r, 15, 8)
200 #define	DF_FBINFO1_GET_FTI0_NINSTID(r)		bitx32(r, 7, 0)
201 
202 /*
203  * DF::FabricBlockInstanceInformation2 -- get basic information about a fabric
204  * instance.
205  */
206 /*CSTYLED*/
207 #define	DF_FBIINFO2		(df_reg_def_t){ .drd_gens = DF_REV_ALL, \
208 				    .drd_func = 0, .drd_reg = 0x4c }
209 #define	DF_FBINFO2_GET_FTI5_NINSTID(r)		bitx32(r, 15, 8)
210 #define	DF_FBINFO2_GET_FTI4_NINSTID(r)		bitx32(r, 7, 0)
211 
212 /*
213  * DF::FabricBlockInstanceInformation3 -- obtain the basic IDs for a given
214  * instance.
215  */
216 /*CSTYLED*/
217 #define	DF_FBIINFO3		(df_reg_def_t){ .drd_gens = DF_REV_ALL, \
218 				    .drd_func = 0, .drd_reg = 0x50 }
219 #define	DF_FBIINFO3_V2_GET_BLOCKID(r)	bitx32(r, 15, 8)
220 #define	DF_FBIINFO3_V3_GET_BLOCKID(r)	bitx32(r, 13, 8)
221 #define	DF_FBIINFO3_V3P5_GET_BLOCKID(r)	bitx32(r, 11, 8)
222 #define	DF_FBIINFO3_V4_GET_BLOCKID(r)	bitx32(r, 19, 8)
223 #define	DF_FBIINFO3_GET_INSTID(r)	bitx32(r, 7, 0)
224 
225 /*
226  * DF::Skt0CsTargetRemap0, DF::Skt0CsTargetRemap1, DF::Skt1CsTargetRemap0,
227  * DF::Skt1CsTargetRemap1 -- The next set of registers provide access to
228  * chip-select remapping. Caution, while these have a documented DF generation
229  * that they are specific to, it seems they still aren't always implemented and
230  * are specific to Milan (v3) and Genoa (v4). The actual remap extraction is the
231  * same between both.
232  */
233 #define	DF_CS_REMAP_GET_CSX(r, x)	bitx32(r, (3 + (4 * (x))), (4 * ((x))))
234 /*CSTYLED*/
235 #define	DF_SKT0_CS_REMAP0_V3	(df_reg_def_t){ .drd_gens = DF_REV_3, \
236 				    .drd_func = 0, .drd_reg = 0x60 }
237 /*CSTYLED*/
238 #define	DF_SKT1_CS_REMAP0_V3	(df_reg_def_t){ .drd_gens = DF_REV_3, \
239 				    .drd_func = 0, .drd_reg = 0x68 }
240 /*CSTYLED*/
241 #define	DF_SKT0_CS_REMAP1_V3	(df_reg_def_t){ .drd_gens = DF_REV_3, \
242 				    .drd_func = 0, .drd_reg = 0x64 }
243 /*CSTYLED*/
244 #define	DF_SKT1_CS_REMAP1_V3	(df_reg_def_t){ .drd_gens = DF_REV_3, \
245 				    .drd_func = 0, .drd_reg = 0x6c }
246 /*
247  * DF::CsTargetRemap0A, DF::CsTargetRemap0B, etc. -- These registers contain the
248  * remap engines in DFv4. Note, that while v3 used 0/1 as REMAP[01], as
249  * referring to the same logical set of things, here [0-3] is used for different
250  * things and A/B distinguish the different actual CS values.
251  */
252 /*CSTYLED*/
253 #define	DF_CS_REMAP0A_V4	(df_reg_def_t){ .drd_gens = DF_REV_4, \
254 				    .drd_func = 7, .drd_reg = 0x180 }
255 /*CSTYLED*/
256 #define	DF_CS_REMAP0B_V4	(df_reg_def_t){ .drd_gens = DF_REV_4, \
257 				    .drd_func = 7, .drd_reg = 0x184 }
258 /*CSTYLED*/
259 #define	DF_CS_REMAP1A_V4	(df_reg_def_t){ .drd_gens = DF_REV_4, \
260 				    .drd_func = 7, .drd_reg = 0x188 }
261 /*CSTYLED*/
262 #define	DF_CS_REMAP1B_V4	(df_reg_def_t){ .drd_gens = DF_REV_4, \
263 				    .drd_func = 7, .drd_reg = 0x18c }
264 /*CSTYLED*/
265 #define	DF_CS_REMAP2A_V4	(df_reg_def_t){ .drd_gens = DF_REV_4, \
266 				    .drd_func = 7, .drd_reg = 0x190 }
267 /*CSTYLED*/
268 #define	DF_CS_REMAP2B_V4	(df_reg_def_t){ .drd_gens = DF_REV_4, \
269 				    .drd_func = 7, .drd_reg = 0x194 }
270 /*CSTYLED*/
271 #define	DF_CS_REMAP3A_V4	(df_reg_def_t){ .drd_gens = DF_REV_4, \
272 				    .drd_func = 7, .drd_reg = 0x198 }
273 /*CSTYLED*/
274 #define	DF_CS_REMAP3B_V4	(df_reg_def_t){ .drd_gens = DF_REV_4, \
275 				    .drd_func = 7, .drd_reg = 0x19c }
276 /*
277  * DF::CfgAddressCntl -- This register contains the information about the
278  * configuration of PCIe buses.  We care about finding which one has our BUS A,
279  * which is required to map it to the in-package northbridge instance.
280  */
281 /*CSTYLED*/
282 #define	DF_CFG_ADDR_CTL_V2	(df_reg_def_t){ .drd_gens = DF_REV_ALL_23, \
283 				.drd_func = 0, \
284 				.drd_reg = 0x84 }
285 /*CSTYLED*/
286 #define	DF_CFG_ADDR_CTL_V4	(df_reg_def_t){ .drd_gens = DF_REV_ALL_23, \
287 				.drd_func = 0, \
288 				.drd_reg = 0xc04 }
289 #define	DF_CFG_ADDR_CTL_GET_BUS_NUM(r)	bitx32(r, 7, 0)
290 
291 /*
292  * DF::CfgAddressMap -- This next set of registers covers PCI Bus configuration
293  * address maps. The layout here changes at v4. This routes a given PCI bus to a
294  * device.
295  */
296 /*CSTYLED*/
297 #define	DF_CFGMAP_V2(x)		(df_reg_def_t){ .drd_gens = DF_REV_ALL_23, \
298 				.drd_func = 0, \
299 				.drd_reg = 0xa0 + ((x) * 4) }
300 #define	DF_MAX_CFGMAP		8
301 #define	DF_CFGMAP_V2_GET_BUS_LIMIT(r)		bitx32(r, 31, 24)
302 #define	DF_CFGMAP_V2_GET_BUS_BASE(r)		bitx32(r, 23, 16)
303 #define	DF_CFGMAP_V2_GET_DEST_ID(r)		bitx32(r, 11, 4)
304 #define	DF_CFGMAP_V3_GET_DEST_ID(r)		bitx32(r, 13, 4)
305 #define	DF_CFGMAP_V3P5_GET_DEST_ID(r)		bitx32(r, 7, 4)
306 #define	DF_CFGMAP_V2_GET_WE(r)			bitx32(r, 1, 1)
307 #define	DF_CFGMAP_V2_GET_RE(r)			bitx32(r, 0, 0)
308 
309 /*
310  * DF::CfgBaseAddress, DF::CfgLimitAddress -- DFv4 variants of the above now in
311  * two registers and more possible entries!
312  */
313 /*CSTYLED*/
314 #define	DF_CFGMAP_BASE_V4(x)	(df_reg_def_t){ .drd_gens = DF_REV_4, \
315 				.drd_func = 0, \
316 				.drd_reg = 0xc80 + ((x) * 8) }
317 /*CSTYLED*/
318 #define	DF_CFGMAP_LIMIT_V4(x)	(df_reg_def_t){ .drd_gens = DF_REV_4, \
319 				.drd_func = 0, \
320 				.drd_reg = 0xc84 + ((x) * 8) }
321 #define	DF_CFGMAP_BASE_V4_GET_BASE(r)	bitx32(r, 23, 16)
322 #define	DF_CFGMAP_BASE_V4_GET_SEG(r)	bitx32(r, 15, 8)
323 #define	DF_CFGMAP_BASE_V4_GET_WE(r)	bitx32(r, 1, 1)
324 #define	DF_CFGMAP_BASE_V4_GET_RE(r)	bitx32(r, 0, 0)
325 #define	DF_CFGMAP_LIMIT_V4_GET_LIMIT(r)		bitx32(r, 23, 16)
326 #define	DF_CFGMAP_LIMIT_V4_GET_DEST_ID(r)	bitx32(r, 11, 0)
327 
328 /*
329  * DF::X86IOBaseAddress, DF::X86IOLimitAddress -- Base and limit registers for
330  * routing I/O space. These are fairly similar prior to DFv4.
331  */
332 /*CSTYLED*/
333 #define	DF_IO_BASE_V2(x)	(df_reg_def_t){ .drd_gens = DF_REV_ALL_23, \
334 				.drd_func = 0, \
335 				.drd_reg = 0xc0 + ((x) * 8) }
336 /*CSTYLED*/
337 #define	DF_IO_BASE_V4(x)	(df_reg_def_t){ .drd_gens = DF_REV_4, \
338 				.drd_func = 0, \
339 				.drd_reg = 0xd00 + ((x) * 8) }
340 #define	DF_MAX_IO_RULES		8
341 #define	DF_IO_BASE_SHIFT	12
342 #define	DF_IO_BASE_V2_GET_BASE(r)	bitx32(r, 24, 12)
343 #define	DF_IO_BASE_V2_GET_IE(r)		bitx32(r, 5, 5)
344 #define	DF_IO_BASE_V2_GET_WE(r)		bitx32(r, 1, 1)
345 #define	DF_IO_BASE_V2_GET_RE(r)		bitx32(r, 0, 0)
346 #define	DF_IO_BASE_V2_SET_BASE(r, v)	bitset32(r, 24, 12, v)
347 #define	DF_IO_BASE_V2_SET_IE(r, v)	bitset32(r, 5, 5, v)
348 #define	DF_IO_BASE_V2_SET_WE(r, v)	bitset32(r, 1, 1, v)
349 #define	DF_IO_BASE_V2_SET_RE(r, v)	bitset32(r, 0, 0, v)
350 
351 #define	DF_IO_BASE_V4_GET_BASE(r)	bitx32(r, 28, 16)
352 #define	DF_IO_BASE_V4_GET_IE(r)		bitx32(r, 5, 5)
353 #define	DF_IO_BASE_V4_GET_WE(r)		bitx32(r, 1, 1)
354 #define	DF_IO_BASE_V4_GET_RE(r)		bitx32(r, 0, 0)
355 #define	DF_IO_BASE_V4_SET_BASE(r, v)	bitset32(r, 28, 16, v)
356 #define	DF_IO_BASE_V4_SET_IE(r, v)	bitset32(r, 5, 5, v)
357 #define	DF_IO_BASE_V4_SET_WE(r, v)	bitset32(r, 1, 1, v)
358 #define	DF_IO_BASE_V4_SET_RE(r, v)	bitset32(r, 0, 0, v)
359 
360 /*CSTYLED*/
361 #define	DF_IO_LIMIT_V2(x)	(df_reg_def_t){ .drd_gens = DF_REV_ALL_23, \
362 				.drd_func = 0, \
363 				.drd_reg = 0xc4 + ((x) * 8) }
364 /*CSTYLED*/
365 #define	DF_IO_LIMIT_V4(x)	(df_reg_def_t){ .drd_gens = DF_REV_4, \
366 				.drd_func = 0, \
367 				.drd_reg = 0xd04 + ((x) * 8) }
368 #define	DF_MAX_IO_LIMIT		((1 << 24) - 1)
369 #define	DF_IO_LIMIT_SHIFT	12
370 #define	DF_IO_LIMIT_EXCL	(1 << DF_IO_LIMIT_SHIFT)
371 #define	DF_IO_LIMIT_V2_GET_LIMIT(r)	bitx32(r, 24, 12)
372 #define	DF_IO_LIMIT_V2_GET_DEST_ID(r)	bitx32(r, 7, 0)
373 #define	DF_IO_LIMIT_V3_GET_DEST_ID(r)	bitx32(r, 9, 0)
374 #define	DF_IO_LIMIT_V3P5_GET_DEST_ID(r)	bitx32(r, 3, 0)
375 #define	DF_IO_LIMIT_V2_SET_LIMIT(r, v)		bitset32(r, 24, 12, v)
376 #define	DF_IO_LIMIT_V2_SET_DEST_ID(r, v)	bitset32(r, 7, 0, v)
377 #define	DF_IO_LIMIT_V3_SET_DEST_ID(r, v)	bitset32(r, 9, 0, v)
378 #define	DF_IO_LIMIT_V3P5_SET_DEST_ID(r, v)	bitset32(r, 3, 0, v)
379 
380 #define	DF_IO_LIMIT_V4_GET_LIMIT(r)	bitx32(r, 28, 16)
381 #define	DF_IO_LIMIT_V4_GET_DEST_ID(r)	bitx32(r, 11, 0)
382 #define	DF_IO_LIMIT_V4_SET_LIMIT(r, v)		bitset32(r, 28, 16, v)
383 #define	DF_IO_LIMIT_V4_SET_DEST_ID(r, v)	bitset32(r, 11, 0, v)
384 
385 /*
386  * DF::DramHoleControl -- This controls MMIO below 4 GiB. Note, both this and
387  * the Top of Memory (TOM) need to be set consistently.
388  */
389 /*CSTYLED*/
390 #define	DF_DRAM_HOLE_V2		(df_reg_def_t){ .drd_gens = DF_REV_ALL_23, \
391 				.drd_func = 0, \
392 				.drd_reg = 0x104 }
393 /*CSTYLED*/
394 #define	DF_DRAM_HOLE_V4		(df_reg_def_t){ .drd_gens = DF_REV_4, \
395 				.drd_func = 7, \
396 				.drd_reg = 0x104 }
397 #define	DF_DRAM_HOLE_GET_BASE(r)	bitx32(r, 31, 24)
398 #define	DF_DRAM_HOLE_BASE_SHIFT		24
399 #define	DF_DRAM_HOLE_GET_VALID(r)	bitx32(r, 0, 0)
400 
401 /*
402  * DF::DramBaseAddress, DF::DramLimitAddress -- DRAM rules, these are split into
403  * a base and limit. While DFv2, 3, and 3.5 all have the same addresses, they
404  * have different bit patterns entirely. DFv4 is in a different location and
405  * further splits this into four registers. We do all of the pre-DFv4 stuff and
406  * follow with DFv4. In DFv2-3.5 the actual values of the bits (e.g. the meaning
407  * of the channel interleave value) are the same, even though where those bits
408  * are in the register changes.
409  *
410  * In DF v2, v3, and v3.5 the set of constants for interleave values are the
411  * same, so we define them once at the v2 version.
412  */
413 /*CSTYLED*/
414 #define	DF_DRAM_BASE_V2(r)	(df_reg_def_t){ .drd_gens = DF_REV_ALL_23, \
415 				.drd_func = 0, \
416 				.drd_reg = 0x110 + ((r) * 8) }
417 #define	DF_DRAM_BASE_V2_GET_BASE(r)		bitx32(r, 31, 12)
418 #define	DF_DRAM_BASE_V2_BASE_SHIFT		28
419 #define	DF_DRAM_BASE_V2_GET_ILV_ADDR(r)		bitx32(r, 10, 8)
420 #define	DF_DRAM_BASE_V2_GET_ILV_CHAN(r)		bitx32(r, 7, 4)
421 #define	DF_DRAM_BASE_V2_ILV_CHAN_1		0x0
422 #define	DF_DRAM_BASE_V2_ILV_CHAN_2		0x1
423 #define	DF_DRAM_BASE_V2_ILV_CHAN_4		0x3
424 #define	DF_DRAM_BASE_V2_ILV_CHAN_8		0x5
425 #define	DF_DRAM_BASE_V2_ILV_CHAN_6		0x6
426 #define	DF_DRAM_BASE_V2_ILV_CHAN_COD4_2		0xc
427 #define	DF_DRAM_BASE_V2_ILV_CHAN_COD2_4		0xd
428 #define	DF_DRAM_BASE_V2_ILV_CHAN_COD1_8		0xe
429 #define	DF_DRAM_BASE_V2_GET_HOLE_EN(r)		bitx32(r, 1, 1)
430 #define	DF_DRAM_BASE_V2_GET_VALID(r)		bitx32(r, 0, 0)
431 
432 #define	DF_DRAM_BASE_V3_GET_ILV_ADDR(r)		bitx32(r, 11, 9)
433 #define	DF_DRAM_BASE_V3_GET_ILV_SOCK(r)		bitx32(r, 8, 8)
434 #define	DF_DRAM_BASE_V3_GET_ILV_DIE(r)		bitx32(r, 7, 6)
435 #define	DF_DRAM_BASE_V3_GET_ILV_CHAN(r)		bitx32(r, 5, 2)
436 
437 #define	DF_DRAM_BASE_V3P5_GET_ILV_ADDR(r)	bitx32(r, 11, 9)
438 #define	DF_DRAM_BASE_V3P5_GET_ILV_SOCK(r)	bitx32(r, 8, 8)
439 #define	DF_DRAM_BASE_V3P5_GET_ILV_DIE(r)	bitx32(r, 7, 7)
440 #define	DF_DRAM_BASE_V3P5_GET_ILV_CHAN(r)	bitx32(r, 6, 2)
441 
442 /*
443  * Shared definitions for the DF DRAM interleaving address start bits. While the
444  * bitfield / register definition is different between DFv2/3/3.5 and DFv4, the
445  * actual contents of the base address register and the base are shared.
446  */
447 #define	DF_DRAM_ILV_ADDR_8		0
448 #define	DF_DRAM_ILV_ADDR_9		1
449 #define	DF_DRAM_ILV_ADDR_10		2
450 #define	DF_DRAM_ILV_ADDR_11		3
451 #define	DF_DRAM_ILV_ADDR_12		4
452 #define	DF_DRAM_ILV_ADDR_BASE		8
453 
454 /*CSTYLED*/
455 #define	DF_DRAM_LIMIT_V2(r)	(df_reg_def_t){ .drd_gens = DF_REV_ALL_23, \
456 				.drd_func = 0, \
457 				.drd_reg = 0x114 + ((r) * 8) }
458 #define	DF_DRAM_LIMIT_V2_GET_LIMIT(r)		bitx32(r, 31, 12)
459 #define	DF_DRAM_LIMIT_V2_LIMIT_SHIFT		28
460 #define	DF_DRAM_LIMIT_V2_LIMIT_EXCL		(1 << 28)
461 /* These are in the base register for v3, v3.5 */
462 #define	DF_DRAM_LIMIT_V2_GET_ILV_DIE(r)		bitx32(r, 11, 10)
463 #define	DF_DRAM_LIMIT_V2_GET_ILV_SOCK(r)	bitx32(r, 8, 8)
464 #define	DF_DRAM_LIMIT_V2_GET_DEST_ID(r)		bitx32(r, 7, 0)
465 
466 #define	DF_DRAM_LIMIT_V3_GET_BUS_BREAK(r)	bitx32(r, 10, 10)
467 #define	DF_DRAM_LIMIT_V3_GET_DEST_ID(r)		bitx32(r, 9, 0)
468 
469 #define	DF_DRAM_LIMIT_V3P5_GET_DEST_ID(r)	bitx32(r, 3, 0)
470 
471 /*
472  * DF::DramBaseAddress, DF::DramLimitAddress, DF::DramAddressCtl,
473  * DF::DramAddressIntlv  -- DFv4 edition. Here all the controls around the
474  * target, interleaving, hashing, and more is split out from the base and limit
475  * registers and put into dedicated control and interleave registers.
476  */
477 /*CSTYLED*/
478 #define	DF_DRAM_BASE_V4(x)	(df_reg_def_t){ .drd_gens = DF_REV_4, \
479 				.drd_func = 7, \
480 				.drd_reg = 0xe00 + ((x) * 0x10) }
481 #define	DF_DRAM_BASE_V4_GET_ADDR(r)		bitx32(r, 27, 0)
482 #define	DF_DRAM_BASE_V4_BASE_SHIFT		28
483 /*CSTYLED*/
484 #define	DF_DRAM_LIMIT_V4(x)	(df_reg_def_t){ .drd_gens = DF_REV_4, \
485 				.drd_func = 7, \
486 				.drd_reg = 0xe04 + ((x) * 0x10) }
487 #define	DF_DRAM_LIMIT_V4_GET_ADDR(r)		bitx32(r, 27, 0)
488 #define	DF_DRAM_LIMIT_V4_LIMIT_SHIFT		28
489 #define	DF_DRAM_LIMIT_V4_LIMIT_EXCL		(1 << 28)
490 
491 /*CSTYLED*/
492 #define	DF_DRAM_CTL_V4(x)	(df_reg_def_t){ .drd_gens = DF_REV_4, \
493 				.drd_func = 7, \
494 				.drd_reg = 0xe08 + ((x) * 0x10) }
495 #define	DF_DRAM_CTL_V4_GET_DEST_ID(r)		bitx32(r, 27, 16)
496 #define	DF_DRAM_CTL_V4_GET_HASH_1G(r)		bitx32(r, 10, 10)
497 #define	DF_DRAM_CTL_V4_GET_HASH_2M(r)		bitx32(r, 9, 9)
498 #define	DF_DRAM_CTL_V4_GET_HASH_64K(r)		bitx32(r, 8, 8)
499 #define	DF_DRAM_CTL_V4_GET_REMAP_SEL(r)		bitx32(r, 7, 5)
500 #define	DF_DRAM_CTL_V4_GET_REMAP_EN(r)		bitx32(r, 4, 4)
501 #define	DF_DRAM_CTL_V4_GET_SCM(r)		bitx32(r, 2, 2)
502 #define	DF_DRAM_CTL_V4_GET_HOLE_EN(r)		bitx32(r, 1, 1)
503 #define	DF_DRAM_CTL_V4_GET_VALID(r)		bitx32(r, 0, 0)
504 
505 /*CSTYLED*/
506 #define	DF_DRAM_ILV_V4(x)	(df_reg_def_t){ .drd_gens = DF_REV_4, \
507 				.drd_func = 7, \
508 				.drd_reg = 0xe0c + ((x) * 0x10) }
509 #define	DF_DRAM_ILV_V4_GET_SOCK(r)		bitx32(r, 18, 18)
510 #define	DF_DRAM_ILV_V4_GET_DIE(r)		bitx32(r, 13, 12)
511 #define	DF_DRAM_ILV_V4_GET_CHAN(r)		bitx32(r, 8, 4)
512 #define	DF_DRAM_ILV_V4_CHAN_1			0x0
513 #define	DF_DRAM_ILV_V4_CHAN_2			0x1
514 #define	DF_DRAM_ILV_V4_CHAN_4			0x3
515 #define	DF_DRAM_ILV_V4_CHAN_8			0x5
516 #define	DF_DRAM_ILV_V4_CHAN_16			0x7
517 #define	DF_DRAM_ILV_V4_CHAN_32			0x8
518 #define	DF_DRAM_ILV_V4_CHAN_NPS4_2CH		0x10
519 #define	DF_DRAM_ILV_V4_CHAN_NPS2_4CH		0x11
520 #define	DF_DRAM_ILV_V4_CHAN_NPS1_8CH		0x12
521 #define	DF_DRAM_ILV_V4_CHAN_NPS4_3CH		0x13
522 #define	DF_DRAM_ILV_V4_CHAN_NPS2_6CH		0x14
523 #define	DF_DRAM_ILV_V4_CHAN_NPS1_12CH		0x15
524 #define	DF_DRAM_ILV_V4_CHAN_NPS2_5CH		0x16
525 #define	DF_DRAM_ILV_V4_CHAN_NPS1_10CH		0x17
526 #define	DF_DRAM_ILV_V4_GET_ADDR(r)		bitx32(r, 2, 0)
527 
528 /*
529  * DF::DramOffset --  These exist only for CS entries, e.g. a UMC. There is
530  * generally only one of these in Zen 1-3. This register changes in Zen 4 and
531  * there are up to 3 instances there. This register corresponds to each DRAM
532  * rule that the UMC has starting at the second one. This is because the first
533  * DRAM rule in a channel always is defined to start at offset 0, so there is no
534  * entry here.
535  */
536 /*CSTYLED*/
537 #define	DF_DRAM_OFFSET_V2	(df_reg_def_t){ .drd_gens = DF_REV_ALL_23, \
538 				.drd_func = 0, \
539 				.drd_reg = 0x1b4 }
540 /*CSTYLED*/
541 #define	DF_DRAM_OFFSET_V4(r)	(df_reg_def_t){ .drd_gens = DF_REV_4, \
542 				.drd_func = 7, \
543 				.drd_reg = 0x404 + ((r) * 4) }
544 #define	DF_DRAM_OFFSET_V2_GET_OFFSET(r)		bitx32(r, 31, 20)
545 #define	DF_DRAM_OFFSET_V3_GET_OFFSET(r)		bitx32(r, 31, 12)
546 #define	DF_DRAM_OFFSET_V4_GET_OFFSET(r)		bitx32(r, 24, 1)
547 #define	DF_DRAM_OFFSET_SHIFT			28
548 #define	DF_DRAM_OFFSET_GET_EN(r)		bitx32(r, 0, 0)
549 
550 /*
551  * DF::MmioBaseAddress, DF::MmioLimitAddress, DF::MmioAddressControl -- These
552  * control the various MMIO rules for a given system.
553  */
554 /*CSTYLED*/
555 #define	DF_MMIO_BASE_V2(x)	(df_reg_def_t){ .drd_gens = DF_REV_ALL_23, \
556 				.drd_func = 0, \
557 				.drd_reg = 0x200 + ((x) * 0x10) }
558 /*CSTYLED*/
559 #define	DF_MMIO_LIMIT_V2(x)	(df_reg_def_t){ .drd_gens = DF_REV_ALL_23, \
560 				.drd_func = 0, \
561 				.drd_reg = 0x204 + ((x) * 0x10) }
562 /*CSTYLED*/
563 #define	DF_MMIO_BASE_V4(x)	(df_reg_def_t){ .drd_gens = DF_REV_4, \
564 				.drd_func = 0, \
565 				.drd_reg = 0xd80 + ((x) * 0x10) }
566 /*CSTYLED*/
567 #define	DF_MMIO_LIMIT_V4(x)	(df_reg_def_t){ .drd_gens = DF_REV_4, \
568 				.drd_func = 0, \
569 				.drd_reg = 0xd84 + ((x) * 0x10) }
570 #define	DF_MMIO_SHIFT		16
571 #define	DF_MMIO_LIMIT_EXCL	(1 << DF_MMIO_SHIFT)
572 #define	DF_MAX_MMIO_RULES	16
573 /*CSTYLED*/
574 #define	DF_MMIO_CTL_V2(x)	(df_reg_def_t){ .drd_gens = DF_REV_ALL_23, \
575 				.drd_func = 0, \
576 				.drd_reg = 0x208 + ((x) * 0x10) }
577 /*CSTYLED*/
578 #define	DF_MMIO_CTL_V4(x)	(df_reg_def_t){ .drd_gens = DF_REV_4, \
579 				.drd_func = 0, \
580 				.drd_reg = 0xd88 + ((x) * 0x10) }
581 #define	DF_MMIO_CTL_V2_GET_NP(r)	bitx32(r, 12, 12)
582 #define	DF_MMIO_CTL_V2_GET_DEST_ID(r)	bitx32(r, 11, 4)
583 #define	DF_MMIO_CTL_V2_SET_NP(r, v)		bitset32(r, 12, 12, v)
584 #define	DF_MMIO_CTL_V2_SET_DEST_ID(r, v)	bitset32(r, 11, 4, v)
585 
586 #define	DF_MMIO_CTL_V3_GET_NP(r)	bitx32(r, 16, 16)
587 #define	DF_MMIO_CTL_V3_GET_DEST_ID(r)	bitx32(r, 13, 4)
588 #define	DF_MMIO_CTL_V3P5_GET_DEST_ID(r)	bitx32(r, 7, 4)
589 #define	DF_MMIO_CTL_V3_SET_NP(r, v)		bitset32(r, 16, 16, v)
590 #define	DF_MMIO_CTL_V3_SET_DEST_ID(r, v)	bitset32(r, 13, 4, v)
591 #define	DF_MMIO_CTL_V3P5_SET_DEST_ID(r, v)	bitset32(r, 7, 4, v)
592 
593 #define	DF_MMIO_CTL_V4_GET_DEST_ID(r)	bitx32(r, 27, 16)
594 #define	DF_MMIO_CTL_V4_GET_NP(r)	bitx32(r, 3, 3)
595 #define	DF_MMIO_CTL_V4_SET_DEST_ID(r, v)	bitset32(r, 27, 16, v)
596 #define	DF_MMIO_CTL_V4_SET_NP(r, v)		bitset32(r, 3, 3, v)
597 
598 #define	DF_MMIO_CTL_GET_CPU_DIS(r)	bitx32(r, 2, 2)
599 #define	DF_MMIO_CTL_GET_WE(r)		bitx32(r, 1, 1)
600 #define	DF_MMIO_CTL_GET_RE(r)		bitx32(r, 0, 0)
601 #define	DF_MMIO_CTL_SET_CPU_DIS(r, v)		bitset32(r, 2, 2, v)
602 #define	DF_MMIO_CTL_SET_WE(r, v)		bitset32(r, 1, 1, v)
603 #define	DF_MMIO_CTL_SET_RE(r, v)		bitset32(r, 0, 0, v)
604 
605 /*
606  * DF::MmioExtAddress -- New in DFv4, this allows extending the number of bits
607  * used for MMIO.
608  */
609 /*CSTYLED*/
610 #define	DF_MMIO_EXT_V4(x)		(df_reg_def_t){ .drd_gens = DF_REV_4, \
611 				.drd_func = 0, \
612 				.drd_reg = 0xd8c + ((x) * 0x10) }
613 #define	DF_MMIO_EXT_V4_GET_LIMIT(r)	bitx32(r, 23, 16)
614 #define	DF_MMIO_EXT_V4_GET_BASE(r)	bitx32(r, 7, 0)
615 #define	DF_MMIO_EXT_V4_SET_LIMIT(r)	bitset32(r, 23, 16)
616 #define	DF_MMIO_EXT_V4_SET_BASE(r)	bitset32(r, 7, 0)
617 
618 /*
619  * DF::DfGlobalCtrl -- This register we generally only care about in the
620  * DFv3/3.5 timeframe when it has the actual hash controls, hence its current
621  * definition. It technically exists in DFv2/v4, but is not relevant.
622  */
623 /*CSTYLED*/
624 #define	DF_GLOB_CTL_V3		(df_reg_def_t){ .drd_gens = DF_REV_ALL_3, \
625 				.drd_func = 0, \
626 				.drd_reg = 0x3F8 }
627 #define	DF_GLOB_CTL_V3_GET_HASH_1G(r)	bitx32(r, 22, 22)
628 #define	DF_GLOB_CTL_V3_GET_HASH_2M(r)	bitx32(r, 21, 21)
629 #define	DF_GLOB_CTL_V3_GET_HASH_64K(r)	bitx32(r, 20, 20)
630 
631 /*
632  * DF::SystemCfg -- This register describes the basic information about the data
633  * fabric that we're talking to. Don't worry, this is different in every
634  * generation, even when the address is the same. Somehow despite all these
635  * differences the actual things like defined types are somehow the same.
636  */
637 typedef enum {
638 	DF_DIE_TYPE_CPU	= 0,
639 	DF_DIE_TYPE_APU,
640 	DF_DIE_TYPE_dGPU
641 } df_die_type_t;
642 
643 /*CSTYLED*/
644 #define	DF_SYSCFG_V2		(df_reg_def_t){ .drd_gens = DF_REV_2, \
645 				.drd_func = 1, \
646 				.drd_reg = 0x200 }
647 #define	DF_SYSCFG_V2_GET_SOCK_ID(r)	bitx32(r, 27, 27)
648 #define	DF_SYSCFG_V2_GET_DIE_ID(r)	bitx32(r, 25, 24)
649 #define	DF_SYSCFG_V2_GET_MY_TYPE(r)	bitx32(r, 22, 21)
650 #define	DF_SYSCFG_V2_GET_LOCAL_IS_ME(r)	bitx32(r, 19, 16)
651 #define	DF_SYSCFG_V2_GET_LOCAL_TYPE3(r)	bitx32(r, 13, 12)
652 #define	DF_SYSCFG_V2_GET_LOCAL_TYPE2(r)	bitx32(r, 11, 10)
653 #define	DF_SYSCFG_V2_GET_LOCAL_TYPE1(r)	bitx32(r, 9, 8)
654 #define	DF_SYSCFG_V2_GET_LOCAL_TYPE0(r)	bitx32(r, 7, 6)
655 #define	DF_SYSCFG_V2_GET_OTHER_SOCK(r)	bitx32(r, 5, 5)
656 #define	DF_SYSCFG_V2_GET_DIE_PRESENT(r)	bitx32(r, 4, 0)
657 #define	DF_SYSCFG_V2_DIE_PRESENT(x)	bitx32(r, 3, 0)
658 
659 /*CSTYLED*/
660 #define	DF_SYSCFG_V3		(df_reg_def_t){ .drd_gens = DF_REV_3, \
661 				.drd_func = 1, \
662 				.drd_reg = 0x200 }
663 #define	DF_SYSCFG_V3_GET_NODE_ID(r)	bitx32(r, 30, 28)
664 #define	DF_SYSCFG_V3_GET_OTHER_SOCK(r)	bitx32(r, 27, 27)
665 #define	DF_SYSCFG_V3_GET_OTHER_TYPE(r)	bitx32(r, 26, 25)
666 #define	DF_SYSCFG_V3_GET_MY_TYPE(r)	bitx32(r, 24, 23)
667 #define	DF_SYSCFG_V3_GET_DIE_TYPE(r)	bitx32(r, 18, 11)
668 #define	DF_SYSCFG_V3_GET_DIE_PRESENT(r)	bitx32(r, 7, 0)
669 
670 /*CSTYLED*/
671 #define	DF_SYSCFG_V3P5		(df_reg_def_t){ .drd_gens = DF_REV_3P5, \
672 				.drd_func = 1, \
673 				.drd_reg = 0x140 }
674 #define	DF_SYSCFG_V3P5_GET_NODE_ID(r)		bitx32(r, 19, 16)
675 #define	DF_SYSCFG_V3P5_GET_OTHER_SOCK(r)	bitx32(r, 8, 8)
676 #define	DF_SYSCFG_V3P5_GET_NODE_MAP(r)		bitx32(r, 4, 4)
677 #define	DF_SYSCFG_V3P5_GET_OTHER_TYPE(r)	bitx32(r, 3, 2)
678 #define	DF_SYSCFG_V3P5_GET_MY_TYPE(r)		bitx32(r, 1, 0)
679 
680 /*CSTYLED*/
681 #define	DF_SYSCFG_V4		(df_reg_def_t){ .drd_gens = DF_REV_4, \
682 				.drd_func = 4, \
683 				.drd_reg = 0x180 }
684 #define	DF_SYSCFG_V4_GET_NODE_ID(r)	bitx32(r, 27, 16)
685 #define	DF_SYSCFG_V4_GET_OTHER_SOCK(r)	bitx32(r, 8, 8)
686 #define	DF_SYSCFG_V4_GET_NODE_MAP(r)	bitx32(r, 4, 4)
687 #define	DF_SYSCFG_V4_GET_OTHER_TYPE(r)	bitx32(r, 3, 2)
688 #define	DF_SYSCFG_V4_GET_MY_TYPE(r)	bitx32(r, 1, 0)
689 
690 /*
691  * DF::SystemComponentCnt -- Has a count of how many things are here. However,
692  * this does not seem defined for DFv3.5
693  */
694 /*CSTYLED*/
695 #define	DF_COMPCNT_V2		(df_reg_def_t){ .drd_gens = DF_REV_2 | \
696 				    DF_REV_3, \
697 				.drd_func = 1, \
698 				.drd_reg = 0x204 }
699 #define	DF_COMPCNT_V2_GET_IOMS(r)	bitx32(r, 23, 16)
700 #define	DF_COMPCNT_V2_GET_GCM(r)	bitx32(r, 15, 8)
701 #define	DF_COMPCNT_V2_GET_PIE(r)	bitx32(r, 7, 0)
702 
703 /*CSTYLED*/
704 #define	DF_COMPCNT_V4		(df_reg_def_t){ .drd_gens = DF_REV_4 \
705 				.drd_func = 4, \
706 				.drd_reg = 0x184 }
707 #define	DF_COMPCNT_V4_GET_IOS(r)	bitx32(r, 31, 26)
708 #define	DF_COMPCNT_V4_GET_GCM(r)	bitx32(r, 25, 16)
709 #define	DF_COMPCNT_V4_GET_IOM(r)	bitx32(r, 15, 8)
710 #define	DF_COMPCNT_V4_GET_PIE(r)	bitx32(r, 7, 0)
711 
712 /*
713  * This next section contains a bunch of register definitions for how to take
714  * apart ID masks. The register names and sets have changed across every DF
715  * revision. This will be done in chunks that define all DFv2, then v3, etc.
716  */
717 
718 /*
719  * DF::SystemFabricIdMask -- DFv2 style breakdowns of IDs. Note, unlike others
720  * the socket and die shifts are not relative to a node mask, but are global.
721  */
722 /*CSTYLED*/
723 #define	DF_FIDMASK_V2		(df_reg_def_t){ .drd_gens = DF_REV_2, \
724 				.drd_func = 1, \
725 				.drd_reg = 0x208 }
726 #define	DF_FIDMASK_V2_GET_SOCK_SHIFT(r)		bitx32(r, 31, 28)
727 #define	DF_FIDMASK_V2_GET_DIE_SHIFT(r)		bitx32(r, 27, 24)
728 #define	DF_FIDMASK_V2_GET_SOCK_MASK(r)		bitx32(r, 23, 16)
729 #define	DF_FIDMASK_V2_GET_DIE_MASK(r)		bitx32(r, 15, 8)
730 
731 /*
732  * DF::SystemFabricIdMask0, DF::SystemFabricIdMask1 -- The DFv3 variant of
733  * breaking down an ID into bits and shifts. Unlike in DFv2, the socket and die
734  * are relative to a node ID. For more, see amdzen_determine_fabric_decomp() in
735  * uts/intel/io/amdzen/amdzen.c.
736  */
737 /*CSTYLED*/
738 #define	DF_FIDMASK0_V3		(df_reg_def_t){ .drd_gens = DF_REV_3, \
739 				.drd_func = 1, \
740 				.drd_reg = 0x208 }
741 #define	DF_FIDMASK0_V3_GET_NODE_MASK(r)		bitx32(r, 25, 16)
742 #define	DF_FIDMASK0_V3_GET_COMP_MASK(r)		bitx32(r, 9, 0)
743 /*CSTYLED*/
744 #define	DF_FIDMASK1_V3		(df_reg_def_t){ .drd_gens = DF_REV_3, \
745 				.drd_func = 1, \
746 				.drd_reg = 0x20c }
747 #define	DF_FIDMASK1_V3_GET_SOCK_MASK(r)		bitx32(r, 26, 24)
748 #define	DF_FIDMASK1_V3_GET_DIE_MASK(r)		bitx32(r, 18, 16)
749 #define	DF_FIDMASK1_V3_GET_SOCK_SHIFT(r)	bitx32(r, 9, 8)
750 #define	DF_FIDMASK1_V3_GET_NODE_SHIFT(r)	bitx32(r, 3, 0)
751 
752 /*
753  * DF::SystemFabricIdMask0, DF::SystemFabricIdMask1, DF::SystemFabricIdMask2 --
754  * DFv3.5 and DFv4 have the same format here, but in different registers.
755  */
756 /*CSTYLED*/
757 #define	DF_FIDMASK0_V3P5	(df_reg_def_t){ .drd_gens = DF_REV_3P5, \
758 				.drd_func = 1, \
759 				.drd_reg = 0x150 }
760 /*CSTYLED*/
761 #define	DF_FIDMASK0_V4		(df_reg_def_t){ .drd_gens = DF_REV_4, \
762 				.drd_func = 4, \
763 				.drd_reg = 0x1b0 }
764 #define	DF_FIDMASK0_V3P5_GET_NODE_MASK(r)	bitx32(r, 31, 16)
765 #define	DF_FIDMASK0_V3P5_GET_COMP_MASK(r)	bitx32(r, 15, 0)
766 /*CSTYLED*/
767 #define	DF_FIDMASK1_V3P5	(df_reg_def_t){ .drd_gens = DF_REV_3P5, \
768 				.drd_func = 1, \
769 				.drd_reg = 0x154 }
770 /*CSTYLED*/
771 #define	DF_FIDMASK1_V4		(df_reg_def_t){ .drd_gens = DF_REV_4, \
772 				.drd_func = 4, \
773 				.drd_reg = 0x1b4 }
774 #define	DF_FIDMASK1_V3P5_GET_SOCK_SHIFT(r)	bitx32(r, 11, 8)
775 #define	DF_FIDMASK1_V3P5_GET_NODE_SHIFT(r)	bitx32(r, 3, 0)
776 /*CSTYLED*/
777 #define	DF_FIDMASK2_V3P5	(df_reg_def_t){ .drd_gens = DF_REV_3P5, \
778 				.drd_func = 1, \
779 				.drd_reg = 0x158 }
780 /*CSTYLED*/
781 #define	DF_FIDMASK2_V4		(df_reg_def_t){ .drd_gens = DF_REV_4, \
782 				.drd_func = 4, \
783 				.drd_reg = 0x1b8 }
784 #define	DF_FIDMASK2_V3P5_GET_SOCK_MASK(r)	bitx32(r, 31, 16)
785 #define	DF_FIDMASK2_V3P5_GET_DIE_MASK(r)	bitx32(r, 15, 0)
786 
787 /*
788  * DF::DieFabricIdMask -- This is a Zeppelin, DFv2 special. There are a couple
789  * instances of this for different types of devices; however, this is where the
790  * component mask is actually stored. This is replicated for a CPU, APU, and
791  * dGPU, each with slightly different values. We need to look at DF_SYSCFG_V2 to
792  * determine which type of die we have and use the appropriate one when looking
793  * at this. This makes the Zen 1 CPUs and APUs have explicitly different set up
794  * here. Look, it got better in DFv3.
795  */
796 /*CSTYLED*/
797 #define	DF_DIEMASK_CPU_V2	(df_reg_def_t){ .drd_gens = DF_REV_2, \
798 				.drd_func = 1, \
799 				.drd_reg = 0x22c }
800 /*CSTYLED*/
801 #define	DF_DIEMASK_APU_V2	(df_reg_def_t){ .drd_gens = DF_REV_2, \
802 				.drd_func = 1, \
803 				.drd_reg = 0x24c }
804 #define	DF_DIEMASK_V2_GET_SOCK_SHIFT(r)		bitx32(r, 31, 28)
805 #define	DF_DIEMASK_V2_GET_DIE_SHIFT(r)		bitx32(r, 27, 24)
806 #define	DF_DIEMASK_V2_GET_SOCK_MASK(r)		bitx32(r, 23, 16)
807 #define	DF_DIEMASK_V2_GET_DIE_MASK(r)		bitx32(r, 15, 8)
808 #define	DF_DIEMASK_V2_GET_COMP_MASK(r)		bitx32(r, 7, 0)
809 
810 /*
811  * DF::CCDEnable -- This register is present for CCMs and ACMs. Despite its
812  * name, the interpretation is not quite straightforward. That is, it only
813  * indirectly tells us about whether or not there are two CCDs or not. A CCM
814  * port can be in wide mode where its two SDPs (Scalable Data Ports) are in fact
815  * instead connected to a single CCD. If wide mode is enabled in DF::CCMConfig4,
816  * then a value of 0x3 just indicates that both SDP ports are connected to a
817  * single CCD.
818  *
819  * The CCX related fields are only valid when the dense mode is enabled in the
820  * global DF controls. We don't generally recommend this as a way of determining
821  * if multiple CCX units are present on the CCD because it is tied to DFv4.
822  */
823 #define	DF_MAX_CCDS_PER_CCM	2
824 /*CSTYLED*/
825 #define	DF_CCD_EN_V4		(df_reg_def_t){ .drd_gens = DF_REV_4, \
826 				.drd_func = 1, \
827 				.drd_reg = 0x104 }
828 #define	DF_CCD_EN_V4_GET_CCX_EN(r)	bitx32(r, 17, 16)
829 #define	DF_CCD_EN_V4_GET_CCD_EN(r)	bitx32(r, 1, 0)
830 
831 
832 /*
833  * DF::PhysicalCoreEnable0, etc. -- These registers can be used to tell us which
834  * cores are actually enabled. This appears to have been introduced in DFv3.
835  * DFv4 expanded this from two registers to four.
836  */
837 /*CSTYLED*/
838 #define	DF_PHYS_CORE_EN0_V3	(df_reg_def_t){ .drd_gens = DF_REV_ALL_3, \
839 				.drd_func = 1, \
840 				.drd_reg = 0x300 }
841 /*CSTYLED*/
842 #define	DF_PHYS_CORE_EN1_V3	(df_reg_def_t){ .drd_gens = DF_REV_ALL_3, \
843 				.drd_func = 1, \
844 				.drd_reg = 0x304 }
845 /*CSTYLED*/
846 #define	DF_PHYS_CORE_EN0_V4	(df_reg_def_t){ .drd_gens = DF_REV_4, \
847 				.drd_func = 1, \
848 				.drd_reg = 0x140 }
849 /*CSTYLED*/
850 #define	DF_PHYS_CORE_EN1_V4	(df_reg_def_t){ .drd_gens = DF_REV_4, \
851 				.drd_func = 1, \
852 				.drd_reg = 0x144 }
853 /*CSTYLED*/
854 #define	DF_PHYS_CORE_EN2_V4	(df_reg_def_t){ .drd_gens = DF_REV_4, \
855 				.drd_func = 1, \
856 				.drd_reg = 0x148 }
857 /*CSTYLED*/
858 #define	DF_PHYS_CORE_EN3_V4	(df_reg_def_t){ .drd_gens = DF_REV_4, \
859 				.drd_func = 1, \
860 				.drd_reg = 0x14c }
861 
862 /*
863  * DF::Np2ChannelConfig -- This is used in Milan to contain information about
864  * how non-power of 2 based channel configuration works. Note, we only know that
865  * this exists in Milan (and its ThreadRipper equivalent). We don't believe it
866  * is in other DFv3 products like Rome, Matisse, Vermeer, or the APUs.
867  */
868 /*CSTYLED*/
869 #define	DF_NP2_CONFIG_V3	(df_reg_def_t){ .drd_gens = DF_REV_3, \
870 				.drd_func = 2, \
871 				.drd_reg = 0x90 }
872 #define	DF_NP2_CONFIG_V3_GET_SPACE1(r)		bitx32(r, 13, 8)
873 #define	DF_NP2_CONFIG_V3_GET_SPACE0(r)		bitx32(r, 5, 0)
874 
875 /*
876  * DF::CCMConfig4 -- This is one of several CCM configuration related registers.
877  * This varies in each DF revision. That is, while we've found it does exist in
878  * DFv3, it is at a different address and the bits have rather different
879  * meanings. A subset of the bits are defined below based upon our needs.
880  */
881 /*CSTYLED*/
882 #define	DF_CCMCFG4_V4		(df_reg_def_t){ .drd_gens = DF_REV_4, \
883 				.drd_func = 3, \
884 				.drd_reg = 0x510 }
885 #define	DF_CCMCFG4_V4_GET_WIDE_EN(r)		bitx32(r, 26, 26)
886 
887 /*
888  * DF::FabricIndirectConfigAccessAddress, DF::FabricIndirectConfigAccessDataLo,
889  * DF::FabricIndirectConfigAccessDataHi --  These registers are used to define
890  * Indirect Access, commonly known as FICAA and FICAD for the system. While
891  * there are multiple copies of the indirect access registers in device 4, we're
892  * only allowed access to one set of those (which are the ones present here).
893  * Specifically the OS is given access to set 3.
894  */
895 /*CSTYLED*/
896 #define	DF_FICAA_V2		(df_reg_def_t){ .drd_gens = DF_REV_ALL_23, \
897 				.drd_func = 4, \
898 				.drd_reg = 0x5c }
899 /*CSTYLED*/
900 #define	DF_FICAA_V4		(df_reg_def_t){ .drd_gens = DF_REV_4, \
901 				.drd_func = 4, \
902 				.drd_reg = 0x8c }
903 #define	DF_FICAA_V2_SET_INST(r, v)		bitset32(r, 23, 16, v)
904 #define	DF_FICAA_V2_SET_64B(r, v)		bitset32(r, 14, 14, v)
905 #define	DF_FICAA_V2_SET_FUNC(r, v)		bitset32(r, 13, 11, v)
906 #define	DF_FICAA_V2_SET_REG(r, v)		bitset32(r, 10, 2, v)
907 #define	DF_FICAA_V2_SET_TARG_INST(r, v)		bitset32(r, 0, 0, v)
908 
909 #define	DF_FICAA_V4_SET_REG(r, v)		bitset32(r, 10, 1, v)
910 
911 /*CSTYLED*/
912 #define	DF_FICAD_LO_V2		(df_reg_def_t){ .drd_gens = DF_REV_ALL_23, \
913 				.drd_func = 4, \
914 				.drd_reg = 0x98}
915 /*CSTYLED*/
916 #define	DF_FICAD_HI_V2		(df_reg_def_t){ .drd_gens = DF_REV_ALL_23, \
917 				.drd_func = 4, \
918 				.drd_reg = 0x9c}
919 /*CSTYLED*/
920 #define	DF_FICAD_LO_V4		(df_reg_def_t){ .drd_gens = DF_REV_4, \
921 				.drd_func = 4, \
922 				.drd_reg = 0xb8}
923 /*CSTYLED*/
924 #define	DF_FICAD_HI_V4		(df_reg_def_t){ .drd_gens = DF_REV_4, \
925 				.drd_func = 4, \
926 				.drd_reg = 0xbc}
927 
928 #ifdef __cplusplus
929 }
930 #endif
931 
932 #endif /* _SYS_AMDZEN_DF_H */
933