xref: /illumos-gate/usr/src/uts/intel/sys/mc_amd.h (revision 4156fc34b973159b0334e05ae5ec19344487bdc0)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  *
21  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
22  * Use is subject to license terms.
23  */
24 
25 #ifndef _MC_AMD_H
26 #define	_MC_AMD_H
27 
28 #pragma ident	"%Z%%M%	%I%	%E% SMI"
29 
30 #include <sys/mc.h>
31 #include <sys/x86_archext.h>
32 
33 /*
34  * The mc-amd driver exports an nvlist to userland, where the primary
35  * consumer is the "chip" topology enumerator for this platform type which
36  * builds a full topology subtree from this information.  Others can use
37  * it, too, but don't depend on it not changing without an ARC contract
38  * (and the contract should probably concern the topology, not this nvlist).
39  *
40  * In the initial mc-amd implementation this nvlist was not versioned;
41  * we'll think of that as version 0 and it may be recognised by the absence
42  * of a "mcamd-nvlist-version member.
43  *
44  * Version 1 is defined as follows.  A name in square brackets indicates
45  * that member is optional (only present if the actual value is valid).
46  *
47  * Name			Type		Description
48  * -------------------- --------------- ---------------------------------------
49  * mcamd-nvlist-version	uint8		Exported nvlist version number
50  * num			uint64		Chip id of this memory controller
51  * revision		uint64		cpuid_getchiprev() result
52  * revname		string		cpuid_getchiprevstr() result
53  * socket		string		"Socket 755|939|940|AM2|F(1207)|S1g1"
54  * ecc-type		string		"ChipKill 128/16" or "Normal 64/8"
55  * base-addr		uint64		Node base address
56  * lim-addr		uint64		Node limit address
57  * node-ilen		uint64		0|1|3|7 for 0/2/4/8 way node interleave
58  * node-ilsel		uint64		Node interleave position of this node
59  * cs-intlv-factor	uint64		chip-select interleave: 1/2/4/8
60  * dram-hole-size	uint64		size in bytes from dram hole addr reg
61  * access-width		uint64		MC mode, 64 or 128 bit
62  * bank-mapping		uint64		Raw DRAM Bank Address Mapping Register
63  * bankswizzle		uint64		1 if bank swizzling enabled; else 0
64  * mismatched-dimm-support uint64	1 if active; else 0
65  * [spare-csnum]	uint64		Chip-select pair number of any spare
66  * [bad-csnum]		uint64		Chip-select pair number of swapped cs
67  * cslist		nvlist array	See below; may have 0 members
68  * dimmlist		nvlist array	See below; may have 0 members
69  *
70  * cslist is an array of nvlist, each as follows:
71  *
72  * Name			Type		Description
73  * -------------------- --------------- ---------------------------------------
74  * num			uint64		Chip-select base/mask pair number
75  * base-addr		uint64		Chip-select base address (rel to node)
76  * mask			uint64		Chip-select mask
77  * size			uint64		Chip-select size in bytes
78  * dimm1-num		uint64		First dimm (lodimm if a pair)
79  * dimm1-csname		string		Socket cs# line name for 1st dimm rank
80  * [dimm2-num]		uint64		Second dimm if applicable (updimm)
81  * [dimm2-csname]	string		Socket cs# line name for 2nd dimm rank
82  *
83  * dimmlist is an array of nvlist, each as follows:
84  *
85  * Name			Type		Description
86  * -------------------- --------------- ---------------------------------------
87  * num			uint64		DIMM instance number
88  * size			uint64		DIMM size in bytes
89  * csnums		uint64 array	CS base/mask pair(s) on this DIMM
90  * csnames		string array	Socket cs# line name(s) on this DIMM
91  *
92  *	The n'th csnums entry corresponds to the n'th csnames entry
93  */
94 #define	MC_NVLIST_VERSTR	"mcamd-nvlist-version"
95 #define	MC_NVLIST_VERS0		0
96 #define	MC_NVLIST_VERS1		1
97 #define	MC_NVLIST_VERS		MC_NVLIST_VERS1
98 
99 /*
100  * Definitions describing various memory controller constant properties and
101  * the structure of configuration registers.
102  */
103 
104 #ifdef __cplusplus
105 extern "C" {
106 #endif
107 
108 /*
109  * Constants and feature/revision test macros that are not expected to vary
110  * among different AMD family 0xf processor revisions.
111  */
112 
113 /*
114  * Configuration constants
115  */
116 #define	MC_CHIP_MAXNODES	8	/* max number of MCs in system */
117 #define	MC_CHIP_NDIMM		8	/* max dimms per MC */
118 #define	MC_CHIP_NCS		8	/* number of chip-selects per MC */
119 #define	MC_CHIP_NDRAMCHAN	2	/* maximum number of dram channels */
120 #define	MC_CHIP_DIMMRANKMAX	4	/* largest number of ranks per dimm */
121 #define	MC_CHIP_DIMMPERCS	2	/* max number of dimms per cs */
122 #define	MC_CHIP_DIMMPAIR(csnum)	(csnum / MC_CHIP_DIMMPERCS)
123 
124 #if	MC_CHIP_DIMMPERCS > MC_UNUM_NDIMM
125 #error	"MC_CHIP_DIMMPERCS exceeds MC_UNUM_NDIMM"
126 #endif
127 
128 /*
129  * MC_REV_* are used a a convenient shorter form of the X86_CHIPREV
130  * counterparts; these must map directly as we fill mcp_rev from
131  * a cpuid_getchiprev call.
132  */
133 #define	MC_REV_UNKNOWN	X86_CHIPREV_UNKNOWN
134 #define	MC_REV_B	X86_CHIPREV_AMD_F_REV_B
135 #define	MC_REV_C	(X86_CHIPREV_AMD_F_REV_C0 | X86_CHIPREV_AMD_F_REV_CG)
136 #define	MC_REV_D	X86_CHIPREV_AMD_F_REV_D
137 #define	MC_REV_E	X86_CHIPREV_AMD_F_REV_E
138 #define	MC_REV_F	X86_CHIPREV_AMD_F_REV_F
139 #define	MC_REV_G	X86_CHIPREV_AMD_F_REV_G
140 
141 /*
142  * The most common groupings for memory controller features.
143  */
144 #define	MC_REVS_BC	(MC_REV_B | MC_REV_C)
145 #define	MC_REVS_DE	(MC_REV_D | MC_REV_E)
146 #define	MC_REVS_BCDE	(MC_REVS_BC | MC_REVS_DE)
147 #define	MC_REVS_FG	(MC_REV_F | MC_REV_G)
148 
149 /*
150  * Is 'rev' included in the 'revmask' bitmask?
151  */
152 #define	MC_REV_MATCH(rev, revmask)	X86_CHIPREV_MATCH(rev, revmask)
153 
154 /*
155  * Is 'rev' at least revision 'revmin' or greater
156  */
157 #define	MC_REV_ATLEAST(rev, minrev)	X86_CHIPREV_ATLEAST(rev, minrev)
158 
159 /*
160  * Chip socket types
161  */
162 #define	MC_SKT_UNKNOWN	0x0
163 #define	MC_SKT_754	0x1
164 #define	MC_SKT_939	0x2
165 #define	MC_SKT_940	0x3
166 #define	MC_SKT_S1g1	0x4
167 #define	MC_SKT_AM2	0x5
168 #define	MC_SKT_F1207	0x6
169 
170 /*
171  * Memory controller registers are read via PCI config space accesses on
172  * bus 0, device 24 + NodeId, and function as follows:
173  *
174  * Function 0: HyperTransport Technology Configuration
175  * Function 1: Address Map
176  * Function 2: DRAM Controller & HyperTransport Technology Trace Mode
177  * Function 3: Miscellaneous Control
178  *
179  * For a given (bus, device, function) a particular offset selects the
180  * desired register.  All registers are 32-bits wide.
181  *
182  * Different family 0xf processor revisions vary slightly in the content
183  * of these configuration registers.  The biggest change is with rev F
184  * where DDR2 support has been introduced along with some hardware-controlled
185  * correctable memory error thresholding.  Fortunately most of the config info
186  * required by the mc-amd driver is similar across revisions.
187  *
188  * We will try to insulate most of the driver code from config register
189  * details by reading all memory-controller PCI config registers that we
190  * will need at driver attach time for each of functions 0 through 3, and
191  * storing them in a "cooked" form as memory controller properties.
192  * These are to be accessed directly where we have an mc_t to hand, otherwise
193  * through mcamd_get_numprop.  As such we expect most/all use of the
194  * structures and macros defined below to be in those attach codepaths.
195  */
196 
197 /*
198  * Registers will be represented as unions, with one fixed-width unsigned
199  * integer member providing access to the raw register value and one or more
200  * structs breaking the register out into bitfields (more than one struct if
201  * the register definitions varies across processor revisions).
202  *
203  * The "raw" union member will always be '_val32'.  Use MCREG_VAL32 to
204  * access this member.
205  *
206  * The bitfield structs are all named _fmt_xxx where xxx identifies the
207  * processor revision to which it applies.  At this point the only xxx
208  * values in use are:
209  *			'cmn' - applies to all revisions
210  *			'preF' - applies to revisions E and earlier
211  *			'revFG' - applies to revisions F and G
212  * Variants such as 'preD', 'revDE', 'postCG' etc should be introduced
213  * as requirements arise.  The MC_REV_* and MC_REV_MATCH etc macros
214  * will also need to grow to match.  Use MCREG_FIELD_* to access the
215  * individual bitfields of a register, perhaps using MC_REV_* and MC_REV_MATCH
216  * to decide which revision suffix to provide.  Where a bitfield appears
217  * in different revisions but has the same use it should be named identically
218  * (even if the BKDG varies a little) so that the MC_REG_FIELD_* macros
219  * can lookup that member based on revision only.
220  */
221 
222 #define	_MCREG_FIELD(up, revsuffix, field) ((up)->_fmt_##revsuffix.field)
223 
224 #define	MCREG_VAL32(up) ((up)->_val32)
225 
226 #define	MCREG_FIELD_CMN(up, field)	_MCREG_FIELD(up, cmn, field)
227 #define	MCREG_FIELD_preF(up, field)	_MCREG_FIELD(up, preF, field)
228 #define	MCREG_FIELD_revFG(up, field)	_MCREG_FIELD(up, revFG, field)
229 
230 /*
231  * Function 1 - DRAM Address Map: DRAM Base i Registers
232  *
233  */
234 
235 union mcreg_drambase {
236 	uint32_t	_val32;
237 	struct {
238 		uint32_t	RE:1;		/*  0:0  - Read Enable */
239 		uint32_t	WE:1;		/*  1:1  - Write Enable */
240 		uint32_t	reserved1:6;	/*  7:2 */
241 		uint32_t	IntlvEn:3;	/* 10:8  - Interleave Enable */
242 		uint32_t	reserved2:5;	/* 15:11 */
243 		uint32_t	DRAMBasei:16;	/* 31:16 - Base Addr 39:24 */
244 	} _fmt_cmn;
245 };
246 
247 #define	MC_DRAMBASE(up)	((uint64_t)MCREG_FIELD_CMN(up, DRAMBasei) << 24)
248 
249 /*
250  * Function 1 - DRAM Address Map: DRAM Limit i Registers
251  *
252  */
253 
254 union mcreg_dramlimit {
255 	uint32_t	_val32;
256 	struct {
257 		uint32_t	DstNode:3;	/*  2:0  - Destination Node */
258 		uint32_t	reserved1:5;	/*  7:3 */
259 		uint32_t	IntlvSel:3;	/* 10:8  - Interleave Select */
260 		uint32_t	reserved2:5;	/* 15:11 */
261 		uint32_t	DRAMLimiti:16;	/* 31:16 - Limit Addr 39:24 */
262 	} _fmt_cmn;
263 };
264 
265 #define	MC_DRAMLIM(up) \
266 	((uint64_t)MCREG_FIELD_CMN(up, DRAMLimiti) << 24 |		\
267 	(MCREG_FIELD_CMN(up, DRAMLimiti) ?  ((1 << 24) - 1) : 0))
268 
269 /*
270  * Function 1 - DRAM Address Map: DRAM Hole Address Register
271  */
272 
273 union mcreg_dramhole {
274 	uint32_t	_val32;
275 	struct {
276 		uint32_t	DramHoleValid:1;	/*  0:0 */
277 		uint32_t	reserved1:7;		/*  7:1 */
278 		uint32_t	DramHoleOffset:8;	/* 15:8 */
279 		uint32_t	reserved2:8;		/* 23:16 */
280 		uint32_t	DramHoleBase:8;		/* 31:24 */
281 	} _fmt_cmn;
282 };
283 
284 #define	MC_DRAMHOLE_SIZE(up) (MCREG_FIELD_CMN(up, DramHoleOffset) << 24)
285 
286 /*
287  * Function 2 - DRAM Controller: DRAM CS Base Address Registers
288  */
289 
290 union mcreg_csbase {
291 	uint32_t	_val32;
292 	/*
293 	 * Register format in revisions E and earlier
294 	 */
295 	struct {
296 		uint32_t	CSEnable:1;	/*  0:0  - CS Bank Enable */
297 		uint32_t	reserved1:8;	/*  8:1 */
298 		uint32_t	BaseAddrLo:7;	/* 15:9  - Base Addr 19:13 */
299 		uint32_t	reserved2:5;	/* 20:16 */
300 		uint32_t	BaseAddrHi:11;	/* 31:21 - Base Addr 35:25 */
301 	} _fmt_preF;
302 	/*
303 	 * Register format in revisions F and G
304 	 */
305 	struct {
306 		uint32_t	CSEnable:1;	/*  0:0  - CS Bank Enable */
307 		uint32_t	Spare:1;	/*  1:1  - Spare Rank */
308 		uint32_t	TestFail:1;	/*  2:2  - Memory Test Failed */
309 		uint32_t	reserved1:2;	/*  4:3 */
310 		uint32_t	BaseAddrLo:9;	/* 13:5  - Base Addr 21:13 */
311 		uint32_t	reserved2:5;	/* 18:14 */
312 		uint32_t	BaseAddrHi:10;	/* 28:19 - Base Addr 36:27 */
313 		uint32_t	reserved3:3;	/* 31:39 */
314 	} _fmt_revFG;
315 };
316 
317 #define	MC_CSBASE(up, rev) (MC_REV_MATCH(rev, MC_REVS_FG) ?	\
318 	(uint64_t)MCREG_FIELD_revFG(up, BaseAddrHi) << 27 |		\
319 	(uint64_t)MCREG_FIELD_revFG(up, BaseAddrLo) << 13 :		\
320 	(uint64_t)MCREG_FIELD_preF(up, BaseAddrHi) << 25 |		\
321 	(uint64_t)MCREG_FIELD_preF(up, BaseAddrLo) << 13)
322 
323 /*
324  * Function 2 - DRAM Controller: DRAM CS Mask Registers
325  */
326 
327 union mcreg_csmask {
328 	uint32_t	_val32;
329 	/*
330 	 * Register format in revisions E and earlier
331 	 */
332 	struct {
333 		uint32_t	reserved1:9;	/*  8:0 */
334 		uint32_t	AddrMaskLo:7;	/* 15:9  - Addr Mask 19:13 */
335 		uint32_t	reserved2:5;	/* 20:16 */
336 		uint32_t	AddrMaskHi:9;	/* 29:21 - Addr Mask 33:25 */
337 		uint32_t	reserved3:2;	/* 31:30 */
338 	} _fmt_preF;
339 	/*
340 	 * Register format in revisions F and G
341 	 */
342 	struct {
343 		uint32_t	reserved1:5;	/*  4:0 */
344 		uint32_t	AddrMaskLo:9;	/* 13:5  - Addr Mask 21:13 */
345 		uint32_t	reserved2:5;	/* 18:14 */
346 		uint32_t	AddrMaskHi:10;	/* 28:19 - Addr Mask 36:27 */
347 		uint32_t	reserved3:3;	/* 31:29 */
348 	} _fmt_revFG;
349 };
350 
351 #define	MC_CSMASKLO_LOBIT(rev) (MC_REV_MATCH(rev, MC_REVS_FG) ? 13 : 13)
352 #define	MC_CSMASKLO_HIBIT(rev) (MC_REV_MATCH(rev, MC_REVS_FG) ? 21 : 19)
353 
354 #define	MC_CSMASKHI_LOBIT(rev) (MC_REV_MATCH(rev, MC_REVS_FG) ? 27 : 25)
355 #define	MC_CSMASKHI_HIBIT(rev) (MC_REV_MATCH(rev, MC_REVS_FG) ? 36 : 33)
356 
357 #define	MC_CSMASK_UNMASKABLE(rev) (MC_REV_MATCH(rev, MC_REVS_FG) ? 0 : 2)
358 
359 #define	MC_CSMASK(up, rev) (MC_REV_MATCH(rev, MC_REVS_FG) ?		\
360 	(uint64_t)MCREG_FIELD_revFG(up, AddrMaskHi) << 27 |		\
361 	(uint64_t)MCREG_FIELD_revFG(up, AddrMaskLo) << 13 | 0x7c01fff :	\
362 	(uint64_t)MCREG_FIELD_preF(up, AddrMaskHi) << 25 |		\
363 	(uint64_t)MCREG_FIELD_preF(up, AddrMaskLo) << 13 | 0x1f01fff)
364 
365 /*
366  * Function 2 - DRAM Controller: DRAM Bank Address Mapping Registers
367  */
368 
369 union mcreg_bankaddrmap {
370 	uint32_t	_val32;
371 	/*
372 	 * Register format in revisions E and earlier
373 	 */
374 	struct {
375 		uint32_t	cs10:4;			/*  3:0  - CS1/0 */
376 		uint32_t	cs32:4;			/*  7:4  - CS3/2 */
377 		uint32_t	cs54:4;			/* 11:8  - CS5/4 */
378 		uint32_t	cs76:4;			/* 15:12 - CS7/6 */
379 		uint32_t	reserved1:14;		/* 29:16 */
380 		uint32_t	BankSwizzleMode:1;	/* 30:30 */
381 		uint32_t	reserved2:1;		/* 31:31 */
382 	} _fmt_preF;
383 	/*
384 	 * Register format in revisions F and G
385 	 */
386 	struct {
387 		uint32_t	cs10:4;			/*  3:0  - CS1/0 */
388 		uint32_t	cs32:4;			/*  7:4  - CS3/2 */
389 		uint32_t	cs54:4;			/* 11:8  - CS5/4 */
390 		uint32_t	cs76:4;			/* 15:12 - CS7/6 */
391 		uint32_t	reserved1:16;		/* 31:16 */
392 	} _fmt_revFG;
393 	/*
394 	 * Accessing all mode encodings as one uint16
395 	 */
396 	struct {
397 		uint32_t	allcsmodes:16;		/* 15:0 */
398 		uint32_t	pad:16;			/* 31:16 */
399 	} _fmt_bankmodes;
400 };
401 
402 #define	MC_DC_BAM_CSBANK_MASK	0x0000000f
403 #define	MC_DC_BAM_CSBANK_SHIFT	4
404 
405 #define	MC_CSBANKMODE(up, csnum) ((up)->_fmt_bankmodes.allcsmodes >>	\
406     MC_DC_BAM_CSBANK_SHIFT * MC_CHIP_DIMMPAIR(csnum) & MC_DC_BAM_CSBANK_MASK)
407 
408 /*
409  * Function 2 - DRAM Controller: DRAM Configuration Low and High
410  */
411 
412 union mcreg_dramcfg_lo {
413 	uint32_t _val32;
414 	/*
415 	 * Register format in revisions E and earlier.
416 	 * Bit 7 is a BIOS ScratchBit in revs D and earlier,
417 	 * PwrDwnTriEn in revision E;  we don't use it so
418 	 * we'll call it ambig1.
419 	 */
420 	struct {
421 		uint32_t	DLL_Dis:1;	/* 0 */
422 		uint32_t	D_DRV:1;	/* 1 */
423 		uint32_t	QFC_EN:1;	/* 2 */
424 		uint32_t	DisDqsHys:1;	/* 3 */
425 		uint32_t	reserved1:1;	/* 4 */
426 		uint32_t	Burst2Opt:1;	/* 5 */
427 		uint32_t	Mod64BitMux:1;	/* 6 */
428 		uint32_t	ambig1:1;	/* 7 */
429 		uint32_t	DramInit:1;	/* 8 */
430 		uint32_t	DualDimmEn:1;	/* 9 */
431 		uint32_t	DramEnable:1;	/* 10 */
432 		uint32_t	MemClrStatus:1;	/* 11 */
433 		uint32_t	ESR:1;		/* 12 */
434 		uint32_t	SR_S:1;		/* 13 */
435 		uint32_t	RdWrQByp:2;	/* 15:14 */
436 		uint32_t	Width128:1;	/* 16 */
437 		uint32_t	DimmEcEn:1;	/* 17 */
438 		uint32_t	UnBufDimm:1;	/* 18 */
439 		uint32_t	ByteEn32:1;	/* 19 */
440 		uint32_t	x4DIMMs:4;	/* 23:20 */
441 		uint32_t	DisInRcvrs:1;	/* 24 */
442 		uint32_t	BypMax:3;	/* 27:25 */
443 		uint32_t	En2T:1;		/* 28 */
444 		uint32_t	UpperCSMap:1;	/* 29 */
445 		uint32_t	PwrDownCtl:2;	/* 31:30 */
446 	} _fmt_preF;
447 	/*
448 	 * Register format in revisions F and G
449 	 */
450 	struct {
451 		uint32_t	InitDram:1;		/* 0 */
452 		uint32_t	ExitSelfRef:1;		/* 1 */
453 		uint32_t	reserved1:2;		/* 3:2 */
454 		uint32_t	DramTerm:2;		/* 5:4 */
455 		uint32_t	reserved2:1;		/* 6 */
456 		uint32_t	DramDrvWeak:1;		/* 7 */
457 		uint32_t	ParEn:1;		/* 8 */
458 		uint32_t	SelRefRateEn:1;		/* 9 */
459 		uint32_t	BurstLength32:1;	/* 10 */
460 		uint32_t	Width128:1;		/* 11 */
461 		uint32_t	x4DIMMs:4;		/* 15:12 */
462 		uint32_t	UnBuffDimm:1;		/* 16 */
463 		uint32_t	reserved3:2;		/* 18:17 */
464 		uint32_t	DimmEccEn:1;		/* 19 */
465 		uint32_t	reserved4:12;		/* 31:20 */
466 	} _fmt_revFG;
467 };
468 
469 /*
470  * Function 2 - DRAM Controller: DRAM Controller Miscellaneous Data
471  */
472 
473 union mcreg_drammisc {
474 	uint32_t _val32;
475 	/*
476 	 * Register format in revisions F and G
477 	 */
478 	struct {
479 		uint32_t	reserved2:1;		/* 0 */
480 		uint32_t	DisableJitter:1;	/* 1 */
481 		uint32_t	RdWrQByp:2;		/* 3:2 */
482 		uint32_t	Mod64Mux:1;		/* 4 */
483 		uint32_t	DCC_EN:1;		/* 5 */
484 		uint32_t	ILD_lmt:3;		/* 8:6 */
485 		uint32_t	DramEnabled:1;		/* 9 */
486 		uint32_t	PwrSavingsEn:1;		/* 10 */
487 		uint32_t	reserved1:13;		/* 23:11 */
488 		uint32_t	MemClkDis:8;		/* 31:24 */
489 	} _fmt_revFG;
490 };
491 
492 union mcreg_dramcfg_hi {
493 	uint32_t _val32;
494 	/*
495 	 * Register format in revisions E and earlier.
496 	 */
497 	struct {
498 		uint32_t	AsyncLat:4;		/* 3:0 */
499 		uint32_t	reserved1:4;		/* 7:4 */
500 		uint32_t	RdPreamble:4;		/* 11:8 */
501 		uint32_t	reserved2:1;		/* 12 */
502 		uint32_t	MemDQDrvStren:2;	/* 14:13 */
503 		uint32_t	DisableJitter:1;	/* 15 */
504 		uint32_t	ILD_lmt:3;		/* 18:16 */
505 		uint32_t	DCC_EN:1;		/* 19 */
506 		uint32_t	MemClk:3;		/* 22:20 */
507 		uint32_t	reserved3:2;		/* 24:23 */
508 		uint32_t	MCR:1;			/* 25 */
509 		uint32_t	MC0_EN:1;		/* 26 */
510 		uint32_t	MC1_EN:1;		/* 27 */
511 		uint32_t	MC2_EN:1;		/* 28 */
512 		uint32_t	MC3_EN:1;		/* 29 */
513 		uint32_t	reserved4:1;		/* 30 */
514 		uint32_t	OddDivisorCorrect:1;	/* 31 */
515 	} _fmt_preF;
516 	/*
517 	 * Register format in revisions F and G
518 	 */
519 	struct {
520 		uint32_t	MemClkFreq:3;		/* 2:0 */
521 		uint32_t	MemClkFreqVal:1;	/* 3 */
522 		uint32_t	MaxAsyncLat:4;		/* 7:4 */
523 		uint32_t	reserved1:4;		/* 11:8 */
524 		uint32_t	RDqsEn:1;		/* 12 */
525 		uint32_t	reserved2:1;		/* 13 */
526 		uint32_t	DisDramInterface:1;	/* 14 */
527 		uint32_t	PowerDownEn:1;		/* 15 */
528 		uint32_t	PowerDownMode:1;	/* 16 */
529 		uint32_t	FourRankSODimm:1;	/* 17 */
530 		uint32_t	FourRankRDimm:1;	/* 18 */
531 		uint32_t	reserved3:1;		/* 19 */
532 		uint32_t	SlowAccessMode:1;	/* 20 */
533 		uint32_t	reserved4:1;		/* 21 */
534 		uint32_t	BankSwizzleMode:1;	/* 22 */
535 		uint32_t	undocumented1:1;	/* 23 */
536 		uint32_t	DcqBypassMax:4;		/* 27:24 */
537 		uint32_t	FourActWindow:4;	/* 31:28 */
538 	} _fmt_revFG;
539 };
540 
541 /*
542  * Function 3 - Miscellaneous Control: Scrub Control Register
543  */
544 
545 union mcreg_scrubctl {
546 	uint32_t _val32;
547 	struct {
548 		uint32_t	DramScrub:5;		/* 4:0 */
549 		uint32_t	reserved3:3;		/* 7:5 */
550 		uint32_t	L2Scrub:5;		/* 12:8 */
551 		uint32_t	reserved2:3;		/* 15:13 */
552 		uint32_t	DcacheScrub:5;		/* 20:16 */
553 		uint32_t	reserved1:11;		/* 31:21 */
554 	} _fmt_cmn;
555 };
556 
557 /*
558  * Function 3 - Miscellaneous Control: On-Line Spare Control Register
559  */
560 
561 union mcreg_nbcfg {
562 	uint32_t _val32;
563 	/*
564 	 * Register format in revisions E and earlier.
565 	 */
566 	struct {
567 		uint32_t	CpuEccErrEn:1;			/* 0 */
568 		uint32_t	CpuRdDatErrEn:1;		/* 1 */
569 		uint32_t	SyncOnUcEccEn:1;		/* 2 */
570 		uint32_t	SyncPktGenDis:1;		/* 3 */
571 		uint32_t	SyncPktPropDis:1;		/* 4 */
572 		uint32_t	IoMstAbortDis:1;		/* 5 */
573 		uint32_t	CpuErrDis:1;			/* 6 */
574 		uint32_t	IoErrDis:1;			/* 7 */
575 		uint32_t	WdogTmrDis:1;			/* 8 */
576 		uint32_t	WdogTmrCntSel:3;		/* 11:9 */
577 		uint32_t	WdogTmrBaseSel:2;		/* 13:12 */
578 		uint32_t	LdtLinkSel:2;			/* 15:14 */
579 		uint32_t	GenCrcErrByte0:1;		/* 16 */
580 		uint32_t	GenCrcErrByte1:1;		/* 17 */
581 		uint32_t	reserved1:2;			/* 19:18 */
582 		uint32_t	SyncOnWdogEn:1;			/* 20 */
583 		uint32_t	SyncOnAnyErrEn:1;		/* 21 */
584 		uint32_t	EccEn:1;			/* 22 */
585 		uint32_t	ChipKillEccEn:1;		/* 23 */
586 		uint32_t	IoRdDatErrEn:1;			/* 24 */
587 		uint32_t	DisPciCfgCpuErrRsp:1;		/* 25 */
588 		uint32_t	reserved2:1;			/* 26 */
589 		uint32_t	NbMcaToMstCpuEn:1;		/* 27 */
590 		uint32_t	reserved3:4;			/* 31:28 */
591 	} _fmt_preF;
592 	/*
593 	 * Register format in revisions F and G
594 	 */
595 	struct {
596 		uint32_t	CpuEccErrEn:1;			/* 0 */
597 		uint32_t	CpuRdDatErrEn:1;		/* 1 */
598 		uint32_t	SyncOnUcEccEn:1;		/* 2 */
599 		uint32_t	SyncPktGenDis:1;		/* 3 */
600 		uint32_t	SyncPktPropDis:1;		/* 4 */
601 		uint32_t	IoMstAbortDis:1;		/* 5 */
602 		uint32_t	CpuErrDis:1;			/* 6 */
603 		uint32_t	IoErrDis:1;			/* 7 */
604 		uint32_t	WdogTmrDis:1;			/* 8 */
605 		uint32_t	WdogTmrCntSel:3;		/* 11:9 */
606 		uint32_t	WdogTmrBaseSel:2;		/* 13:12 */
607 		uint32_t	LdtLinkSel:2;			/* 15:14 */
608 		uint32_t	GenCrcErrByte0:1;		/* 16 */
609 		uint32_t	GenCrcErrByte1:1;		/* 17 */
610 		uint32_t	reserved1:2;			/* 19:18 */
611 		uint32_t	SyncOnWdogEn:1;			/* 20 */
612 		uint32_t	SyncOnAnyErrEn:1;		/* 21 */
613 		uint32_t	EccEn:1;			/* 22 */
614 		uint32_t	ChipKillEccEn:1;		/* 23 */
615 		uint32_t	IoRdDatErrEn:1;			/* 24 */
616 		uint32_t	DisPciCfgCpuErrRsp:1;		/* 25 */
617 		uint32_t	reserved2:1;			/* 26 */
618 		uint32_t	NbMcaToMstCpuEn:1;		/* 27 */
619 		uint32_t	DisTgtAbtCpuErrRsp:1;		/* 28 */
620 		uint32_t	DisMstAbtCpuErrRsp:1;		/* 29 */
621 		uint32_t	SyncOnDramAdrParErrEn:1;	/* 30 */
622 		uint32_t	reserved3:1;			/* 31 */
623 
624 	} _fmt_revFG;
625 };
626 
627 /*
628  * Function 3 - Miscellaneous Control: On-Line Spare Control Register
629  */
630 
631 union mcreg_sparectl {
632 	uint32_t _val32;
633 	/*
634 	 * Register format in revisions F and G
635 	 */
636 	struct {
637 		uint32_t	SwapEn:1;		/* 0 */
638 		uint32_t	SwapDone:1;		/* 1 */
639 		uint32_t	reserved1:2;		/* 3:2 */
640 		uint32_t	BadDramCs:3;		/* 6:4 */
641 		uint32_t	reserved2:5;		/* 11:7 */
642 		uint32_t	SwapDoneInt:2;		/* 13:12 */
643 		uint32_t	EccErrInt:2;		/* 15:14 */
644 		uint32_t	EccErrCntDramCs:3;	/* 18:16 */
645 		uint32_t	reserved3:1;		/* 19 */
646 		uint32_t	EccErrCntDramChan:1;	/* 20 */
647 		uint32_t	reserved4:2;		/* 22:21 */
648 		uint32_t	EccErrCntWrEn:1;	/* 23 */
649 		uint32_t	EccErrCnt:4;		/* 27:24 */
650 		uint32_t	reserved5:4;		/* 31:28 */
651 	} _fmt_revFG;
652 };
653 
654 #ifdef __cplusplus
655 }
656 #endif
657 
658 #endif /* _MC_AMD_H */
659