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