xref: /illumos-gate/usr/src/uts/intel/io/amdzen/zen_umc.h (revision ddb365bfc9e868ad24ccdcb0dc91af18b10df082)
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 _ZEN_UMC_H
17 #define	_ZEN_UMC_H
18 
19 /*
20  * This file contains definitions that are used to manage and decode the Zen UMC
21  * state.
22  */
23 
24 #ifdef __cplusplus
25 extern "C" {
26 #endif
27 
28 #include <sys/stdint.h>
29 #include <sys/sunddi.h>
30 #include <sys/nvpair.h>
31 #include <sys/x86_archext.h>
32 #include <amdzen_client.h>
33 
34 /*
35  * This is the maximum number of DRAM rules that we expect any supported device
36  * to have here. The actual number may be less. These are rules that come from a
37  * DF CCM.
38  */
39 #define	ZEN_UMC_MAX_DRAM_RULES	20
40 
41 /*
42  * This is the maximum number of rules that we expect any system to actually
43  * have for each UMC.
44  */
45 #define	ZEN_UMC_MAX_CS_RULES	4
46 
47 /*
48  * This is the maximum number of DFs that we expect to encounter in a given
49  * platform. This number comes from the Naples generation, where there were up
50  * to 4 per socket, 2 sockets per machine, so 8 total. In subsequent generations
51  * there is only a single 1 per socket.
52  */
53 #define	ZEN_UMC_MAX_DFS	8
54 
55 /*
56  * This indicates the maximum number of UMC DF nodes that we expect to
57  * encounter.
58  */
59 #define	ZEN_UMC_MAX_UMCS	12
60 
61 /*
62  * This indicates the maximum number of DRAM offset rules that can exist in a
63  * platform. Note, this is directly tied to the maximum number of CS rules.
64  */
65 #define	ZEN_UMC_MAX_DRAM_OFFSET	(ZEN_UMC_MAX_CS_RULES - 1)
66 
67 /*
68  * This indicates the maximum number of remap rule sets and corresponding
69  * entries that can exist. Milan's max is smaller than the current overall DFv4
70  * maximum.
71  */
72 #define	ZEN_UMC_MAX_CS_REMAPS		4
73 #define	ZEN_UMC_MAX_REMAP_ENTS		16
74 #define	ZEN_UMC_MILAN_CS_NREMAPS	2
75 #define	ZEN_UMC_MILAN_REMAP_ENTS	12
76 #define	ZEN_UMC_REMAP_PER_REG		8
77 
78 /*
79  * DRAM Channel related maximums.
80  */
81 #define	ZEN_UMC_MAX_DIMMS		2
82 #define	ZEN_UMC_MAX_CS_PER_DIMM		2
83 #define	ZEN_UMC_MAX_CS_BITS		2
84 #define	ZEN_UMC_MAX_CHAN_BASE		2
85 #define	ZEN_UMC_MAX_CHAN_MASK		2
86 #define	ZEN_UMC_MAX_BANK_BITS		5
87 #define	ZEN_UMC_MAX_COL_BITS		16
88 #define	ZEN_UMC_MAX_RM_BITS		4
89 #define	ZEN_UMC_MAX_COLSEL_PER_REG	8
90 
91 #define	ZEN_UMC_DDR4_CHAN_NMASKS	1
92 
93 /*
94  * DRAM Channel hash maximums. Surprisingly enough, the DDR4 and DDR5 maximums
95  * are the same; however, in exchange what hashes are actually implemented
96  * varies.
97  */
98 #define	ZEN_UMC_MAX_CHAN_BANK_HASH	5
99 #define	ZEN_UMC_MAX_CHAN_RM_HASH	3
100 #define	ZEN_UMC_MAX_CHAN_CS_HASH	2
101 
102 /*
103  * A sentinel to indicate we were unable to determine a frequency or transfer
104  * rate.
105  */
106 #define	ZEN_UMC_UNKNOWN_FREQ	0
107 
108 /*
109  * This is the number of memory P-states that the UMC supports. This appears to
110  * be the same across all Zen Family processors. While there are ways to see the
111  * current P-state, it is hard to really know when these transitions occur. We
112  * simply grab all of the speed and configuration information with them when we
113  * discover it.
114  */
115 #define	ZEN_UMC_NMEM_PSTATES	4
116 
117 /*
118  * This is the logical set of different channel interleaving rules that we
119  * support today in the driver. The actual values of the enumeration do not
120  * overlap at all with hardware. Do not use these to try and marry up against
121  * values from the DF itself.
122  *
123  * Note, these values are also encoded in the private mc decoder dumps that we
124  * can produce. If these values change, please take care of ensuring
125  * compatibility for others who may be consuming this. Appending to this list
126  * should be OK.
127  */
128 typedef enum df_chan_ileave {
129 	DF_CHAN_ILEAVE_1CH	= 0,
130 	DF_CHAN_ILEAVE_2CH,
131 	DF_CHAN_ILEAVE_4CH,
132 	DF_CHAN_ILEAVE_6CH,
133 	DF_CHAN_ILEAVE_8CH,
134 	DF_CHAN_ILEAVE_16CH,
135 	DF_CHAN_ILEAVE_32CH,
136 	DF_CHAN_ILEAVE_COD4_2CH,
137 	DF_CHAN_ILEAVE_COD2_4CH,
138 	DF_CHAN_ILEAVE_COD1_8CH,
139 	DF_CHAN_ILEAVE_NPS4_2CH,
140 	DF_CHAN_ILEAVE_NPS2_4CH,
141 	DF_CHAN_ILEAVE_NPS1_8CH,
142 	DF_CHAN_ILEAVE_NPS4_3CH,
143 	DF_CHAN_ILEAVE_NPS2_6CH,
144 	DF_CHAN_ILEAVE_NPS1_12CH,
145 	DF_CHAN_ILEAVE_NPS2_5CH,
146 	DF_CHAN_ILEAVE_NPS1_10CH
147 } df_chan_ileave_t;
148 
149 /*
150  * This is a collection of logical flags that we use to cover attributes of a
151  * DRAM rule.
152  */
153 typedef enum df_dram_flags {
154 	/*
155 	 * Used to indicate that the contents of the rule are actually valid and
156 	 * should be considered. Many rules can be unused in hardware.
157 	 */
158 	DF_DRAM_F_VALID		= 1 << 0,
159 	/*
160 	 * Indicates that the DRAM hole is active for this particular rule. If
161 	 * this flag is set and the hole is valid in the DF, then we need to
162 	 * take the actual DRAM hole into account.
163 	 */
164 	DF_DRAM_F_HOLE		= 1 << 1,
165 	/*
166 	 * These next three are used to indicate when hashing is going on, which
167 	 * bits to use. These are for 64K, 2M, and 1G parts of addresses
168 	 * respectively.
169 	 */
170 	DF_DRAM_F_HASH_16_18	= 1 << 2,
171 	DF_DRAM_F_HASH_21_23	= 1 << 3,
172 	DF_DRAM_F_HASH_30_32	= 1 << 4,
173 	/*
174 	 * Indicates that this rule should have remap processing and the remap
175 	 * target is valid. If the DF_DRAM_F_REMAP_SOCK flag is set, this
176 	 * indicates that the processing is based on socket versus a particular
177 	 * entry.
178 	 */
179 	DF_DRAM_F_REMAP_EN	= 1 << 5,
180 	DF_DRAM_F_REMAP_SOCK	= 1 << 6
181 } df_dram_flags_t;
182 
183 /*
184  * This represents a single offset value for a channel. This is used when
185  * applying normalization.
186  */
187 typedef struct chan_offset {
188 	uint32_t	cho_raw;
189 	boolean_t	cho_valid;
190 	uint64_t	cho_offset;
191 } chan_offset_t;
192 
193 /*
194  * This structure represents a single DRAM rule, no matter where it shows up.
195  * This smooths over the differences between generations.
196  */
197 typedef struct df_dram_rule {
198 	uint32_t		ddr_raw_base;
199 	uint32_t		ddr_raw_limit;
200 	uint32_t		ddr_raw_ctrl;
201 	uint32_t		ddr_raw_ileave;
202 	df_dram_flags_t		ddr_flags;
203 	uint64_t		ddr_base;
204 	uint64_t		ddr_limit;
205 	uint16_t		ddr_dest_fabid;
206 	uint8_t			ddr_sock_ileave_bits;
207 	uint8_t			ddr_die_ileave_bits;
208 	uint8_t			ddr_addr_start;
209 	uint8_t			ddr_remap_ent;
210 	df_chan_ileave_t	ddr_chan_ileave;
211 } df_dram_rule_t;
212 
213 typedef struct umc_dimm_base {
214 	uint64_t	udb_base;
215 	boolean_t	udb_valid;
216 } umc_dimm_base_t;
217 
218 typedef enum umc_dimm_type {
219 	UMC_DIMM_T_UNKNOWN,
220 	UMC_DIMM_T_DDR4,
221 	UMC_DIMM_T_LPDDR4,
222 	UMC_DIMM_T_DDR5,
223 	UMC_DIMM_T_LPDDR5
224 } umc_dimm_type_t;
225 
226 typedef enum umc_dimm_width {
227 	UMC_DIMM_W_X4,
228 	UMC_DIMM_W_X8,
229 	UMC_DIMM_W_X16,
230 } umc_dimm_width_t;
231 
232 typedef enum umc_dimm_kind {
233 	UMC_DIMM_K_UDIMM,
234 	UMC_DIMM_K_RDIMM,
235 	UMC_DIMM_K_LRDIMM,
236 	UMC_DIMM_K_3DS_RDIMM
237 } umc_dimm_kind_t;
238 
239 typedef enum umc_dimm_flags {
240 	/*
241 	 * This flag indicates that this DIMM should be used for decoding
242 	 * purposes. It basically means that there is at least one chip-select
243 	 * decoding register that has been enabled. Unfortunately, we don't have
244 	 * a good way right now of distinguishing between a DIMM being present
245 	 * and being usable. This likely needs to be re-evaluated when we
246 	 * consider how we present things to topo. We may be able to pull this
247 	 * out of the clock disable logic.
248 	 */
249 	UMC_DIMM_F_VALID	= 1 << 0,
250 } umc_dimm_flags_t;
251 
252 /*
253  * A DIMM may have one or more ranks, which is an independent logical item that
254  * is activated by a 'chip-select' signal on a DIMM (e.g. CS_L[1:0]). In a given
255  * channel, AMD always has two instances of a 'chip-select' data structure.
256  * While these have a 1:1 correspondence in the case of single and dual rank
257  * DIMMs, in the case where there are more, then rank multiplication rules are
258  * used to determine which of the additional chip and chip-select signals to
259  * actually drive on the bus. But still, there are only up to two of these
260  * structures. To match AMD terminology we call these a 'chip-select' or
261  * 'umc_cs_t'.
262  *
263  * The amount of information that exists on a per-chip-select and per-DIMM basis
264  * varies between the different memory controller generations. As such, we
265  * normalize things such that a given chip-select always has all of the
266  * information related to it, duplicating it in the DDR4 case.
267  *
268  * While DDR5 adds the notion of sub-channels, a single chip-select is used to
269  * cover both sub-channels and instead a bit in the normalized address (and
270  * hashing) is used to determine which sub-channel to active. So while hardware
271  * actually has different chip-select lines for each sub-channel they are not
272  * represented that way in the UMC.
273  */
274 typedef struct umc_cs {
275 	umc_dimm_base_t		ucs_base;
276 	umc_dimm_base_t		ucs_sec;
277 	uint64_t		ucs_base_mask;
278 	uint64_t		ucs_sec_mask;
279 	uint8_t			ucs_nbanks;
280 	uint8_t			ucs_ncol;
281 	uint8_t			ucs_nrow_lo;
282 	uint8_t			ucs_nrow_hi;
283 	uint8_t			ucs_nrm;
284 	uint8_t			ucs_nbank_groups;
285 	uint8_t			ucs_cs_xor;
286 	uint8_t			ucs_row_hi_bit;
287 	uint8_t			ucs_row_low_bit;
288 	uint8_t			ucs_bank_bits[ZEN_UMC_MAX_BANK_BITS];
289 	uint8_t			ucs_col_bits[ZEN_UMC_MAX_COL_BITS];
290 	uint8_t			ucs_inv_msbs;
291 	uint8_t			ucs_rm_bits[ZEN_UMC_MAX_RM_BITS];
292 	uint8_t			ucs_inv_msbs_sec;
293 	uint8_t			ucs_rm_bits_sec[ZEN_UMC_MAX_RM_BITS];
294 	uint8_t			ucs_subchan;
295 } umc_cs_t;
296 
297 /*
298  * This structure represents information about a DIMM. Most of the interesting
299  * stuff is on the umc_cs_t up above, which is the logical 'chip-select' that
300  * AMD implements in the UMC.
301  *
302  * When we come back and add topo glue for the driver, we should consider adding
303  * the following information here and in the channel:
304  *
305  *  o Channel capable speed
306  *  o A way to map this DIMM to an SMBIOS / SPD style entry
307  */
308 typedef struct umc_dimm {
309 	umc_dimm_flags_t	ud_flags;
310 	umc_dimm_width_t	ud_width;
311 	umc_dimm_kind_t		ud_kind;
312 	uint32_t		ud_dimmno;
313 	uint32_t		ud_dimmcfg_raw;
314 	uint64_t		ud_dimm_size;
315 	umc_cs_t		ud_cs[ZEN_UMC_MAX_CS_PER_DIMM];
316 } umc_dimm_t;
317 
318 typedef enum umc_chan_flags {
319 	/*
320 	 * Indicates that the channel has enabled ECC logic.
321 	 */
322 	UMC_CHAN_F_ECC_EN	= 1 << 0,
323 	/*
324 	 * We believe that this indicates some amount of the AMD SEV encryption
325 	 * is ongoing, leveraging some of the page-table control.
326 	 */
327 	UMC_CHAN_F_ENCR_EN	= 1 << 1,
328 	/*
329 	 * Indicates that the channel is employing data scrambling. This is
330 	 * basically what folks have called Transparent Shared Memory
331 	 * Encryption.
332 	 */
333 	UMC_CHAN_F_SCRAMBLE_EN	= 1 << 2
334 } umc_chan_flags_t;
335 
336 typedef struct umc_bank_hash {
337 	uint32_t	ubh_row_xor;
338 	uint32_t	ubh_col_xor;
339 	boolean_t	ubh_en;
340 } umc_bank_hash_t;
341 
342 typedef struct umc_addr_hash {
343 	uint64_t	uah_addr_xor;
344 	boolean_t	uah_en;
345 } umc_addr_hash_t;
346 
347 typedef struct umc_pc_hash {
348 	uint32_t	uph_row_xor;
349 	uint32_t	uph_col_xor;
350 	uint8_t		uph_bank_xor;
351 	boolean_t	uph_en;
352 } umc_pc_hash_t;
353 
354 typedef enum umc_chan_hash_flags {
355 	UMC_CHAN_HASH_F_BANK	= 1 << 0,
356 	UMC_CHAN_HASH_F_RM	= 1 << 1,
357 	UMC_CHAN_HASH_F_PC	= 1 << 2,
358 	UMC_CHAN_HASH_F_CS	= 1 << 3,
359 } umc_chan_hash_flags_t;
360 
361 typedef struct umc_chan_hash {
362 	umc_chan_hash_flags_t	uch_flags;
363 	umc_bank_hash_t		uch_bank_hashes[ZEN_UMC_MAX_CHAN_BANK_HASH];
364 	umc_addr_hash_t		uch_rm_hashes[ZEN_UMC_MAX_CHAN_RM_HASH];
365 	umc_addr_hash_t		uch_cs_hashes[ZEN_UMC_MAX_CHAN_CS_HASH];
366 	umc_pc_hash_t		uch_pc_hash;
367 } umc_chan_hash_t;
368 
369 /*
370  * This structure represents the overall memory channel. There is a 1:1
371  * relationship between these structures and discover UMC hardware entities on
372  * the data fabric. Note, these always exist regardless of whether the channels
373  * are actually implemented on a PCB or not.
374  */
375 typedef struct zen_umc_chan {
376 	umc_chan_flags_t	chan_flags;
377 	uint32_t		chan_fabid;
378 	uint32_t		chan_instid;
379 	uint32_t		chan_logid;
380 	uint32_t		chan_nrules;
381 	uint32_t		chan_umccfg_raw;
382 	uint32_t		chan_datactl_raw;
383 	uint32_t		chan_eccctl_raw;
384 	uint32_t		chan_umccap_raw;
385 	uint32_t		chan_umccap_hi_raw;
386 	uint32_t		chan_np2_raw;
387 	uint32_t		chan_np2_space0;
388 	/*
389 	 * These have the clock and speed of the channel in MHz and MT/s
390 	 * respectively. These are not always a 1:2 ratio. See the definition
391 	 * and discussion around D_UMC_DRAMCFG. Note, the channel's speed may
392 	 * not be the maximum supported speed of a DIMM itself. That requires
393 	 * going into the SPD data on Zen, the UMC doesn't track it because it
394 	 * doesn't matter to it. There is one of these for each memory P-state.
395 	 */
396 	uint32_t		chan_dramcfg_raw[ZEN_UMC_NMEM_PSTATES];
397 	uint32_t		chan_clock[ZEN_UMC_NMEM_PSTATES];
398 	uint32_t		chan_speed[ZEN_UMC_NMEM_PSTATES];
399 	umc_dimm_type_t		chan_type;
400 	df_dram_rule_t		chan_rules[ZEN_UMC_MAX_CS_RULES];
401 	chan_offset_t		chan_offsets[ZEN_UMC_MAX_DRAM_OFFSET];
402 	umc_dimm_t		chan_dimms[ZEN_UMC_MAX_DIMMS];
403 	umc_chan_hash_t		chan_hash;
404 } zen_umc_chan_t;
405 
406 typedef struct zen_umc_cs_remap {
407 	uint_t		csr_nremaps;
408 	uint16_t	csr_remaps[ZEN_UMC_MAX_REMAP_ENTS];
409 } zen_umc_cs_remap_t;
410 
411 typedef enum zen_umc_df_flags {
412 	/*
413 	 * Indicates that the DRAM Hole is valid and in use.
414 	 */
415 	ZEN_UMC_DF_F_HOLE_VALID	= 1 << 0,
416 	/*
417 	 * These next three are used to indicate when hashing is going on, which
418 	 * bits to use. These are for 64K, 2M, and 1G parts of addresses
419 	 * respectively.
420 	 */
421 	ZEN_UMC_DF_F_HASH_16_18	= 1 << 1,
422 	ZEN_UMC_DF_F_HASH_21_23	= 1 << 2,
423 	ZEN_UMC_DF_F_HASH_30_32	= 1 << 3
424 } zen_umc_df_flags_t;
425 
426 typedef struct zen_umc_df {
427 	zen_umc_df_flags_t	zud_flags;
428 	uint_t			zud_dfno;
429 	uint_t			zud_ccm_inst;
430 	uint_t			zud_dram_nrules;
431 	uint_t			zud_nchan;
432 	uint_t			zud_cs_nremap;
433 	uint32_t		zud_hole_raw;
434 	uint32_t		zud_glob_ctl_raw;
435 	uint64_t		zud_hole_base;
436 	df_dram_rule_t		zud_rules[ZEN_UMC_MAX_DRAM_RULES];
437 	zen_umc_cs_remap_t	zud_remap[ZEN_UMC_MAX_CS_REMAPS];
438 	zen_umc_chan_t		zud_chan[ZEN_UMC_MAX_UMCS];
439 } zen_umc_df_t;
440 
441 typedef enum zen_umc_umc_style {
442 	/*
443 	 * These are UMCs that generally implement the basic DDR4 UMC found in
444 	 * Zen 1-3 systems. The APU variant does not support multiple banks.
445 	 */
446 	ZEN_UMC_UMC_S_DDR4,
447 	ZEN_UMC_UMC_S_DDR4_APU,
448 	/*
449 	 * This represents a slightly different UMC design that exists in Van
450 	 * Gogh and Mendocino. In particular, it primarily supports LPDDR5 but
451 	 * is an extension of the DDR4 UMC in some respects such as the
452 	 * DramConfiguration register, but otherwise looks more like the DDR5
453 	 * case.
454 	 */
455 	ZEN_UMC_UMC_S_HYBRID_LPDDR5,
456 	/*
457 	 * These are UMCs that generally implement the basic DDR5 UMC found in
458 	 * Zen 4+ (and other) systems. The APU variant does not support multiple
459 	 * banks.
460 	 */
461 	ZEN_UMC_UMC_S_DDR5,
462 	ZEN_UMC_UMC_S_DDR5_APU
463 } zen_umc_umc_style_t;
464 
465 typedef enum zen_umc_fam_flags {
466 	/*
467 	 * Indicates that there's an indirection table for the destinations of
468 	 * target rules.
469 	 */
470 	ZEN_UMC_FAM_F_TARG_REMAP	= 1 << 0,
471 	/*
472 	 * Indicates that non-power of two interleave rules are supported and
473 	 * that we need additional register configuration.
474 	 */
475 	ZEN_UMC_FAM_F_NP2		= 1 << 1,
476 	/*
477 	 * Indicates that the DF hashing rules to configure COD hashes need to
478 	 * be checked.
479 	 */
480 	ZEN_UMC_FAM_F_NORM_HASH		= 1 << 2,
481 	/*
482 	 * In DDR4 this indicates presence of the HashRM and in DDR5 the
483 	 * AddrHash.
484 	 */
485 	ZEN_UMC_FAM_F_UMC_HASH		= 1 << 3,
486 	/*
487 	 * Indicates support for extended UMC registers for larger addresses.
488 	 * Generally on Server parts.
489 	 */
490 	ZEN_UMC_FAM_F_UMC_EADDR		= 1 << 4,
491 	/*
492 	 * Indicates that CS decoder supports an XOR function.
493 	 */
494 	ZEN_UMC_FAM_F_CS_XOR		= 1 << 5
495 } zen_umc_fam_flags_t;
496 
497 /*
498  * This structure is meant to contain per SoC family (not CPUID family)
499  * information. This is stuff that we basically need to encode about the
500  * processor itself and relates to its limits, the style it operates in, the
501  * way it works, etc.
502  */
503 typedef struct zen_umc_fam_data {
504 	x86_processor_family_t	zufd_family;
505 	zen_umc_fam_flags_t	zufd_flags;
506 	uint8_t			zufd_dram_nrules;
507 	uint8_t			zufd_cs_nrules;
508 	zen_umc_umc_style_t	zufd_umc_style;
509 	umc_chan_hash_flags_t	zufd_chan_hash;
510 } zen_umc_fam_data_t;
511 
512 /*
513  * The top-level data structure for the system. This is a single structure that
514  * represents everything that could possibly exist and is filled in with what we
515  * actually discover.
516  */
517 typedef struct zen_umc {
518 	uint64_t umc_tom;
519 	uint64_t umc_tom2;
520 	dev_info_t *umc_dip;
521 	x86_processor_family_t umc_family;
522 	df_rev_t umc_df_rev;
523 	const zen_umc_fam_data_t *umc_fdata;
524 	df_fabric_decomp_t umc_decomp;
525 	uint_t umc_ndfs;
526 	zen_umc_df_t umc_dfs[ZEN_UMC_MAX_DFS];
527 	/*
528 	 * This lock protects the data underneath here.
529 	 */
530 	kmutex_t umc_nvl_lock;
531 	nvlist_t *umc_decoder_nvl;
532 	char *umc_decoder_buf;
533 	size_t umc_decoder_len;
534 } zen_umc_t;
535 
536 typedef enum zen_umc_decode_failure {
537 	ZEN_UMC_DECODE_F_NONE = 0,
538 	/*
539 	 * Indicates that the address was not contained within the TOM and TOM2
540 	 * regions that indicate DRAM (or was in a reserved hole).
541 	 */
542 	ZEN_UMC_DECODE_F_OUTSIDE_DRAM,
543 	/*
544 	 * Indicates that we could not find a DF rule in the CCM rule that
545 	 * claims to honor this address.
546 	 */
547 	ZEN_UMC_DECODE_F_NO_DF_RULE,
548 	/*
549 	 * Indicates that trying to construct the interleave address to use
550 	 * would have led to an underflow somehow.
551 	 */
552 	ZEN_UMC_DECODE_F_ILEAVE_UNDERFLOW,
553 	/*
554 	 * Indicates that we do not currently support decoding the indicated
555 	 * channel interleave type.
556 	 */
557 	ZEN_UMC_DECODE_F_CHAN_ILEAVE_NOTSUP,
558 	/*
559 	 * Indicates that we found a COD hash rule that had a non-zero socket or
560 	 * die interleave, which isn't supported and we don't know how to
561 	 * decode.
562 	 */
563 	ZEN_UMC_DECODE_F_COD_BAD_ILEAVE,
564 	/*
565 	 * This is similar to the above, but indicates that we hit a bad NPS
566 	 * interleave rule instead of a COD.
567 	 */
568 	ZEN_UMC_DECODE_F_NPS_BAD_ILEAVE,
569 	/*
570 	 * Indicates that somehow we thought we should use a remap rule set that
571 	 * was beyond our capabilities.
572 	 */
573 	ZEN_UMC_DECODE_F_BAD_REMAP_SET,
574 	/*
575 	 * Indicates that we tried to find an index for the remap rules;
576 	 * however, the logical component ID was outside the range of the number
577 	 * of entries that we have.
578 	 */
579 	ZEN_UMC_DECODE_F_BAD_REMAP_ENTRY,
580 	/*
581 	 * Indicates that the remap rule had an invalid component bit set in its
582 	 * mask.
583 	 */
584 	ZEN_UMC_DECODE_F_REMAP_HAS_BAD_COMP,
585 	/*
586 	 * Indicates that we could not find a UMC with the fabric ID we thought
587 	 * we should have.
588 	 */
589 	ZEN_UMC_DECODE_F_CANNOT_MAP_FABID,
590 	/*
591 	 * Indicates that somehow the UMC we found did not actually contain a
592 	 * DRAM rule that covered our original PA.
593 	 */
594 	ZEN_UMC_DECODE_F_UMC_DOESNT_HAVE_PA,
595 	/*
596 	 * Indicates that we would have somehow underflowed the address
597 	 * calculations normalizing the system address.
598 	 */
599 	ZEN_UMC_DECODE_F_CALC_NORM_UNDERFLOW,
600 	/*
601 	 * Indicates that none of the UMC's chip-selects actually matched a base
602 	 * or secondary.
603 	 */
604 	ZEN_UMC_DECODE_F_NO_CS_BASE_MATCH
605 } zen_umc_decode_failure_t;
606 
607 /*
608  * This struct accumulates all of our decoding logic and states and we use it so
609  * it's easier for us to look at what's going on and the decisions that we made
610  * along the way.
611  */
612 typedef struct zen_umc_decoder {
613 	zen_umc_decode_failure_t	dec_fail;
614 	uint64_t			dec_fail_data;
615 	uint64_t			dec_pa;
616 	const zen_umc_df_t		*dec_df_rulesrc;
617 	uint32_t			dec_df_ruleno;
618 	const df_dram_rule_t		*dec_df_rule;
619 	uint64_t			dec_ilv_pa;
620 	/*
621 	 * These three values represent the IDs that we extract from the
622 	 * interleave address.
623 	 */
624 	uint32_t			dec_ilv_sock;
625 	uint32_t			dec_ilv_die;
626 	uint32_t			dec_ilv_chan;
627 	uint32_t			dec_ilv_fabid;
628 	uint32_t			dec_log_fabid;
629 	uint32_t			dec_remap_comp;
630 	uint32_t			dec_targ_fabid;
631 	const zen_umc_chan_t		*dec_umc_chan;
632 	uint32_t			dec_umc_ruleno;
633 	uint64_t			dec_norm_addr;
634 	const umc_dimm_t		*dec_dimm;
635 	const umc_cs_t			*dec_cs;
636 	boolean_t			dec_cs_sec;
637 	uint32_t			dec_dimm_col;
638 	uint32_t			dec_dimm_row;
639 	uint8_t				dec_log_csno;
640 	uint8_t				dec_dimm_bank;
641 	uint8_t				dec_dimm_bank_group;
642 	uint8_t				dec_dimm_subchan;
643 	uint8_t				dec_dimm_rm;
644 	uint8_t				dec_chan_csno;
645 	uint8_t				dec_dimm_no;
646 	uint8_t				dec_dimm_csno;
647 } zen_umc_decoder_t;
648 
649 /*
650  * Decoding and normalization routines.
651  */
652 extern boolean_t zen_umc_decode_pa(const zen_umc_t *, const uint64_t,
653     zen_umc_decoder_t *);
654 
655 /*
656  * Fabric ID utilities
657  */
658 extern boolean_t zen_fabric_id_valid_fabid(const df_fabric_decomp_t *,
659     const uint32_t);
660 extern boolean_t zen_fabric_id_valid_parts(const df_fabric_decomp_t *,
661     const uint32_t, const uint32_t, const uint32_t);
662 extern void zen_fabric_id_decompose(const df_fabric_decomp_t *, const uint32_t,
663     uint32_t *, uint32_t *, uint32_t *);
664 extern void zen_fabric_id_compose(const df_fabric_decomp_t *, const uint32_t,
665     const uint32_t, const uint32_t, uint32_t *);
666 
667 /*
668  * Encoding and decoding
669  */
670 extern nvlist_t *zen_umc_dump_decoder(zen_umc_t *);
671 extern boolean_t zen_umc_restore_decoder(nvlist_t *, zen_umc_t *);
672 
673 #ifdef __cplusplus
674 }
675 #endif
676 
677 #endif /* _ZEN_UMC_H */
678