xref: /illumos-gate/usr/src/uts/intel/sys/mc_amd.h (revision 22e4c3ac)
17aec1d6eScindi /*
27aec1d6eScindi  * CDDL HEADER START
37aec1d6eScindi  *
47aec1d6eScindi  * The contents of this file are subject to the terms of the
58a40a695Sgavinm  * Common Development and Distribution License (the "License").
68a40a695Sgavinm  * You may not use this file except in compliance with the License.
77aec1d6eScindi  *
87aec1d6eScindi  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97aec1d6eScindi  * or http://www.opensolaris.org/os/licensing.
107aec1d6eScindi  * See the License for the specific language governing permissions
117aec1d6eScindi  * and limitations under the License.
127aec1d6eScindi  *
137aec1d6eScindi  * When distributing Covered Code, include this CDDL HEADER in each
147aec1d6eScindi  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157aec1d6eScindi  * If applicable, add the following below this CDDL HEADER, with the
167aec1d6eScindi  * fields enclosed by brackets "[]" replaced with your own identifying
177aec1d6eScindi  * information: Portions Copyright [yyyy] [name of copyright owner]
187aec1d6eScindi  *
197aec1d6eScindi  * CDDL HEADER END
207aec1d6eScindi  *
215667185bSSrihari Venkatesan  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
227aec1d6eScindi  * Use is subject to license terms.
237aec1d6eScindi  */
24*22e4c3acSKeith M Wesolowski /*
25*22e4c3acSKeith M Wesolowski  * Copyright 2022 Oxide Computer Co.
26*22e4c3acSKeith M Wesolowski  */
277aec1d6eScindi 
287aec1d6eScindi #ifndef _MC_AMD_H
297aec1d6eScindi #define	_MC_AMD_H
307aec1d6eScindi 
318a40a695Sgavinm #include <sys/mc.h>
3220c794b3Sgavinm #include <sys/isa_defs.h>
338a40a695Sgavinm #include <sys/x86_archext.h>
348a40a695Sgavinm 
359dd0f810Scindi #ifdef __cplusplus
369dd0f810Scindi extern "C" {
379dd0f810Scindi #endif
389dd0f810Scindi 
39bb86c342Sgavinm /*
40bb86c342Sgavinm  * Definitions, register offsets, register structure etc pertaining to
41bb86c342Sgavinm  * the memory controller on AMD64 systems.  These are used by both the
42bb86c342Sgavinm  * AMD cpu module and the mc-amd driver.
43bb86c342Sgavinm  */
44bb86c342Sgavinm 
458a40a695Sgavinm /*
468a40a695Sgavinm  * The mc-amd driver exports an nvlist to userland, where the primary
478a40a695Sgavinm  * consumer is the "chip" topology enumerator for this platform type which
488a40a695Sgavinm  * builds a full topology subtree from this information.  Others can use
494156fc34Sgavinm  * it, too, but don't depend on it not changing without an ARC contract
504156fc34Sgavinm  * (and the contract should probably concern the topology, not this nvlist).
518a40a695Sgavinm  *
528a40a695Sgavinm  * In the initial mc-amd implementation this nvlist was not versioned;
538a40a695Sgavinm  * we'll think of that as version 0 and it may be recognised by the absence
548a40a695Sgavinm  * of a "mcamd-nvlist-version member.
558a40a695Sgavinm  *
568a40a695Sgavinm  * Version 1 is defined as follows.  A name in square brackets indicates
578a40a695Sgavinm  * that member is optional (only present if the actual value is valid).
588a40a695Sgavinm  *
598a40a695Sgavinm  * Name			Type		Description
608a40a695Sgavinm  * -------------------- --------------- ---------------------------------------
618a40a695Sgavinm  * mcamd-nvlist-version	uint8		Exported nvlist version number
628a40a695Sgavinm  * num			uint64		Chip id of this memory controller
638a40a695Sgavinm  * revision		uint64		cpuid_getchiprev() result
648a40a695Sgavinm  * revname		string		cpuid_getchiprevstr() result
658a40a695Sgavinm  * socket		string		"Socket 755|939|940|AM2|F(1207)|S1g1"
668a40a695Sgavinm  * ecc-type		string		"ChipKill 128/16" or "Normal 64/8"
678a40a695Sgavinm  * base-addr		uint64		Node base address
688a40a695Sgavinm  * lim-addr		uint64		Node limit address
698a40a695Sgavinm  * node-ilen		uint64		0|1|3|7 for 0/2/4/8 way node interleave
708a40a695Sgavinm  * node-ilsel		uint64		Node interleave position of this node
718a40a695Sgavinm  * cs-intlv-factor	uint64		chip-select interleave: 1/2/4/8
728a40a695Sgavinm  * dram-hole-size	uint64		size in bytes from dram hole addr reg
738a40a695Sgavinm  * access-width		uint64		MC mode, 64 or 128 bit
748a40a695Sgavinm  * bank-mapping		uint64		Raw DRAM Bank Address Mapping Register
758a40a695Sgavinm  * bankswizzle		uint64		1 if bank swizzling enabled; else 0
768a40a695Sgavinm  * mismatched-dimm-support uint64	1 if active; else 0
778a40a695Sgavinm  * [spare-csnum]	uint64		Chip-select pair number of any spare
788a40a695Sgavinm  * [bad-csnum]		uint64		Chip-select pair number of swapped cs
798a40a695Sgavinm  * cslist		nvlist array	See below; may have 0 members
808a40a695Sgavinm  * dimmlist		nvlist array	See below; may have 0 members
818a40a695Sgavinm  *
828a40a695Sgavinm  * cslist is an array of nvlist, each as follows:
838a40a695Sgavinm  *
848a40a695Sgavinm  * Name			Type		Description
858a40a695Sgavinm  * -------------------- --------------- ---------------------------------------
868a40a695Sgavinm  * num			uint64		Chip-select base/mask pair number
878a40a695Sgavinm  * base-addr		uint64		Chip-select base address (rel to node)
888a40a695Sgavinm  * mask			uint64		Chip-select mask
898a40a695Sgavinm  * size			uint64		Chip-select size in bytes
908a40a695Sgavinm  * dimm1-num		uint64		First dimm (lodimm if a pair)
918a40a695Sgavinm  * dimm1-csname		string		Socket cs# line name for 1st dimm rank
928a40a695Sgavinm  * [dimm2-num]		uint64		Second dimm if applicable (updimm)
938a40a695Sgavinm  * [dimm2-csname]	string		Socket cs# line name for 2nd dimm rank
948a40a695Sgavinm  *
958a40a695Sgavinm  * dimmlist is an array of nvlist, each as follows:
968a40a695Sgavinm  *
978a40a695Sgavinm  * Name			Type		Description
988a40a695Sgavinm  * -------------------- --------------- ---------------------------------------
998a40a695Sgavinm  * num			uint64		DIMM instance number
1008a40a695Sgavinm  * size			uint64		DIMM size in bytes
1018a40a695Sgavinm  * csnums		uint64 array	CS base/mask pair(s) on this DIMM
1028a40a695Sgavinm  * csnames		string array	Socket cs# line name(s) on this DIMM
1038a40a695Sgavinm  *
1048a40a695Sgavinm  *	The n'th csnums entry corresponds to the n'th csnames entry
1058a40a695Sgavinm  */
1068a40a695Sgavinm #define	MC_NVLIST_VERSTR	"mcamd-nvlist-version"
1078a40a695Sgavinm #define	MC_NVLIST_VERS0		0
1088a40a695Sgavinm #define	MC_NVLIST_VERS1		1
1098a40a695Sgavinm #define	MC_NVLIST_VERS		MC_NVLIST_VERS1
1108a40a695Sgavinm 
1118a40a695Sgavinm /*
1128a40a695Sgavinm  * Constants and feature/revision test macros that are not expected to vary
1138a40a695Sgavinm  * among different AMD family 0xf processor revisions.
1148a40a695Sgavinm  */
1158a40a695Sgavinm 
1167aec1d6eScindi /*
1177aec1d6eScindi  * Configuration constants
1187aec1d6eScindi  */
1198a40a695Sgavinm #define	MC_CHIP_MAXNODES	8	/* max number of MCs in system */
1207aec1d6eScindi #define	MC_CHIP_NDIMM		8	/* max dimms per MC */
1217aec1d6eScindi #define	MC_CHIP_NCS		8	/* number of chip-selects per MC */
1228a40a695Sgavinm #define	MC_CHIP_NDRAMCHAN	2	/* maximum number of dram channels */
1237aec1d6eScindi #define	MC_CHIP_DIMMRANKMAX	4	/* largest number of ranks per dimm */
1247aec1d6eScindi #define	MC_CHIP_DIMMPERCS	2	/* max number of dimms per cs */
1257aec1d6eScindi #define	MC_CHIP_DIMMPAIR(csnum)	(csnum / MC_CHIP_DIMMPERCS)
1267aec1d6eScindi 
1278a40a695Sgavinm /*
1288a40a695Sgavinm  * Memory controller registers are read via PCI config space accesses on
12920c794b3Sgavinm  * bus 0, device 0x18 + NodeId, and function as follows:
1308a40a695Sgavinm  *
1318a40a695Sgavinm  * Function 0: HyperTransport Technology Configuration
1328a40a695Sgavinm  * Function 1: Address Map
1338a40a695Sgavinm  * Function 2: DRAM Controller & HyperTransport Technology Trace Mode
1348a40a695Sgavinm  * Function 3: Miscellaneous Control
135bb86c342Sgavinm  */
13620c794b3Sgavinm 
13720c794b3Sgavinm #define	MC_AMD_DEV_OFFSET	0x18	/* node ID + offset == PCI dev num */
13820c794b3Sgavinm 
139bb86c342Sgavinm enum mc_funcnum {
140bb86c342Sgavinm 	MC_FUNC_HTCONFIG = 0,
141bb86c342Sgavinm 	MC_FUNC_ADDRMAP	= 1,
142bb86c342Sgavinm 	MC_FUNC_DRAMCTL = 2,
143bb86c342Sgavinm 	MC_FUNC_MISCCTL = 3
144bb86c342Sgavinm };
145bb86c342Sgavinm 
146bb86c342Sgavinm /*
1478a40a695Sgavinm  * For a given (bus, device, function) a particular offset selects the
1488a40a695Sgavinm  * desired register.  All registers are 32-bits wide.
1497aec1d6eScindi  *
1508a40a695Sgavinm  * Different family 0xf processor revisions vary slightly in the content
1518a40a695Sgavinm  * of these configuration registers.  The biggest change is with rev F
1528a40a695Sgavinm  * where DDR2 support has been introduced along with some hardware-controlled
1538a40a695Sgavinm  * correctable memory error thresholding.  Fortunately most of the config info
1548a40a695Sgavinm  * required by the mc-amd driver is similar across revisions.
1558a40a695Sgavinm  *
1568a40a695Sgavinm  * We will try to insulate most of the driver code from config register
1578a40a695Sgavinm  * details by reading all memory-controller PCI config registers that we
1588a40a695Sgavinm  * will need at driver attach time for each of functions 0 through 3, and
1598a40a695Sgavinm  * storing them in a "cooked" form as memory controller properties.
1608a40a695Sgavinm  * These are to be accessed directly where we have an mc_t to hand, otherwise
1618a40a695Sgavinm  * through mcamd_get_numprop.  As such we expect most/all use of the
1628a40a695Sgavinm  * structures and macros defined below to be in those attach codepaths.
1637aec1d6eScindi  */
1647aec1d6eScindi 
165bb86c342Sgavinm /*
166bb86c342Sgavinm  * Function 0 (HT Config) offsets
167bb86c342Sgavinm  */
168bb86c342Sgavinm #define	MC_HT_REG_RTBL_NODE_0	0x40
169bb86c342Sgavinm #define	MC_HT_REG_RTBL_INCR	4
170bb86c342Sgavinm #define	MC_HT_REG_NODEID	0x60
171bb86c342Sgavinm #define	MC_HT_REG_UNITID	0x64
172bb86c342Sgavinm 
173bb86c342Sgavinm /*
174bb86c342Sgavinm  * Function 1 (address map) offsets for DRAM base, DRAM limit, DRAM hole
175bb86c342Sgavinm  * registers.
176bb86c342Sgavinm  */
177bb86c342Sgavinm #define	MC_AM_REG_DRAMBASE_0	0x40	/* Offset for DRAM Base 0 */
178bb86c342Sgavinm #define	MC_AM_REG_DRAMLIM_0	0x44	/* Offset for DRAM Limit 0 */
179bb86c342Sgavinm #define	MC_AM_REG_DRAM_INCR	8	/* incr between base/limit pairs */
180bb86c342Sgavinm #define	MC_AM_REG_HOLEADDR	0xf0	/* DRAM Hole Address Register */
181bb86c342Sgavinm 
182bb86c342Sgavinm /*
183bb86c342Sgavinm  * Function 2 (dram controller) offsets for chip-select base, chip-select mask,
184bb86c342Sgavinm  * DRAM bank address mapping, DRAM configuration registers.
185bb86c342Sgavinm  */
186bb86c342Sgavinm #define	MC_DC_REG_CS_INCR	4	/* incr for CS base and mask */
187bb86c342Sgavinm #define	MC_DC_REG_CSBASE_0	0x40	/* 0x40 - 0x5c */
188bb86c342Sgavinm #define	MC_DC_REG_CSMASK_0	0x60	/* 0x60 - 0x7c */
189bb86c342Sgavinm #define	MC_DC_REG_BANKADDRMAP	0x80	/* DRAM Bank Address Mapping */
190bb86c342Sgavinm #define	MC_DC_REG_DRAMCFGLO	0x90	/* DRAM Configuration Low */
191bb86c342Sgavinm #define	MC_DC_REG_DRAMCFGHI	0x94	/* DRAM Configuration High */
192bb86c342Sgavinm #define	MC_DC_REG_DRAMMISC	0xa0	/* DRAM Miscellaneous */
193bb86c342Sgavinm 
194bb86c342Sgavinm /*
19525f47677Sgavinm  * Function 3 (misc control) offset for NB MCA config, scrubber control,
19625f47677Sgavinm  * online spare control and NB capabilities.
197bb86c342Sgavinm  */
198bb86c342Sgavinm #define	MC_CTL_REG_NBCFG	0x44	/* MCA NB configuration register */
199bb86c342Sgavinm #define	MC_CTL_REG_SCRUBCTL	0x58	/* Scrub control register */
200bb86c342Sgavinm #define	MC_CTL_REG_SCRUBADDR_LO	0x5c	/* DRAM Scrub Address Low */
201bb86c342Sgavinm #define	MC_CTL_REG_SCRUBADDR_HI	0x60	/* DRAM Scrub Address High */
202bb86c342Sgavinm #define	MC_CTL_REG_SPARECTL	0xb0	/* On-line spare control register */
20325f47677Sgavinm #define	MC_CTL_REG_NBCAP	0xe8	/* NB Capabilities */
2045667185bSSrihari Venkatesan #define	MC_CTL_REG_EXTNBCFG	0x180	/* Ext. MCA NB configuration register */
20525f47677Sgavinm 
206a24e89c4SKuriakose Kuruvilla #define	MC_NBCAP_L3CAPABLE	(1U << 25)
207a24e89c4SKuriakose Kuruvilla #define	MC_NBCAP_MULTINODECPU	(1U << 29)
2085667185bSSrihari Venkatesan #define	MC_EXTNBCFG_ECCSYMSZ	(1U << 25)
209bb86c342Sgavinm 
2108a40a695Sgavinm /*
21120c794b3Sgavinm  * MC4_MISC MSR and MC4_MISCj MSRs
21220c794b3Sgavinm  */
21320c794b3Sgavinm #define	MC_MSR_NB_MISC0		0x413
21420c794b3Sgavinm #define	MC_MSR_NB_MISC1		0xc0000408
21520c794b3Sgavinm #define	MC_MSR_NB_MISC2		0xc0000409
21620c794b3Sgavinm #define	MC_MSR_NB_MISC3		0xc000040a
21720c794b3Sgavinm #define	MC_MSR_NB_MISC(j) \
21820c794b3Sgavinm 	((j) == 0 ? MC_MSR_NB_MISC0 : MC_MSR_NB_MISC1 + (j) - 1)
21920c794b3Sgavinm 
22020c794b3Sgavinm /*
22120c794b3Sgavinm  * PCI registers will be represented as unions, with one fixed-width unsigned
2228a40a695Sgavinm  * integer member providing access to the raw register value and one or more
2238a40a695Sgavinm  * structs breaking the register out into bitfields (more than one struct if
2248a40a695Sgavinm  * the register definitions varies across processor revisions).
2258a40a695Sgavinm  *
2268a40a695Sgavinm  * The "raw" union member will always be '_val32'.  Use MCREG_VAL32 to
2278a40a695Sgavinm  * access this member.
2288a40a695Sgavinm  *
2298a40a695Sgavinm  * The bitfield structs are all named _fmt_xxx where xxx identifies the
2308a40a695Sgavinm  * processor revision to which it applies.  At this point the only xxx
2318a40a695Sgavinm  * values in use are:
2328a40a695Sgavinm  *			'cmn' - applies to all revisions
23320c794b3Sgavinm  *			'f_preF' - applies to revisions E and earlier
23420c794b3Sgavinm  *			'f_revFG' - applies to revisions F and G
23520c794b3Sgavinm  *
2368a40a695Sgavinm  * Variants such as 'preD', 'revDE', 'postCG' etc should be introduced
2378a40a695Sgavinm  * as requirements arise.  The MC_REV_* and MC_REV_MATCH etc macros
2388a40a695Sgavinm  * will also need to grow to match.  Use MCREG_FIELD_* to access the
2398a40a695Sgavinm  * individual bitfields of a register, perhaps using MC_REV_* and MC_REV_MATCH
2408a40a695Sgavinm  * to decide which revision suffix to provide.  Where a bitfield appears
2418a40a695Sgavinm  * in different revisions but has the same use it should be named identically
2428a40a695Sgavinm  * (even if the BKDG varies a little) so that the MC_REG_FIELD_* macros
2438a40a695Sgavinm  * can lookup that member based on revision only.
2448a40a695Sgavinm  */
2457aec1d6eScindi 
246bb86c342Sgavinm #define	MC_REV_UNKNOWN	X86_CHIPREV_UNKNOWN
24720c794b3Sgavinm 
248*22e4c3acSKeith M Wesolowski #define	MC_F_REV_B	X86_CHIPREV_AMD_LEGACY_F_REV_B
249*22e4c3acSKeith M Wesolowski #define	MC_F_REV_C	(X86_CHIPREV_AMD_LEGACY_F_REV_C0 | \
250*22e4c3acSKeith M Wesolowski 	X86_CHIPREV_AMD_LEGACY_F_REV_CG)
251*22e4c3acSKeith M Wesolowski #define	MC_F_REV_D	X86_CHIPREV_AMD_LEGACY_F_REV_D
252*22e4c3acSKeith M Wesolowski #define	MC_F_REV_E	X86_CHIPREV_AMD_LEGACY_F_REV_E
253*22e4c3acSKeith M Wesolowski #define	MC_F_REV_F	X86_CHIPREV_AMD_LEGACY_F_REV_F
254*22e4c3acSKeith M Wesolowski #define	MC_F_REV_G	X86_CHIPREV_AMD_LEGACY_F_REV_G
25520c794b3Sgavinm 
256*22e4c3acSKeith M Wesolowski #define	MC_10_REV_A	X86_CHIPREV_AMD_LEGACY_10_REV_A
257*22e4c3acSKeith M Wesolowski #define	MC_10_REV_B	X86_CHIPREV_AMD_LEGACY_10_REV_B
258bb86c342Sgavinm 
259bb86c342Sgavinm /*
260bb86c342Sgavinm  * The most common groupings for memory controller features.
261bb86c342Sgavinm  */
26220c794b3Sgavinm #define	MC_F_REVS_BC	(MC_F_REV_B | MC_F_REV_C)
26320c794b3Sgavinm #define	MC_F_REVS_DE	(MC_F_REV_D | MC_F_REV_E)
26420c794b3Sgavinm #define	MC_F_REVS_BCDE	(MC_F_REVS_BC | MC_F_REVS_DE)
26520c794b3Sgavinm #define	MC_F_REVS_FG	(MC_F_REV_F | MC_F_REV_G)
26620c794b3Sgavinm 
26720c794b3Sgavinm #define	MC_10_REVS_AB	(MC_10_REV_A | MC_10_REV_B)
268bb86c342Sgavinm 
269bb86c342Sgavinm /*
270bb86c342Sgavinm  * Is 'rev' included in the 'revmask' bitmask?
271bb86c342Sgavinm  */
272*22e4c3acSKeith M Wesolowski #define	MC_REV_MATCH(rev, revmask)	chiprev_matches(rev, revmask)
273bb86c342Sgavinm 
274bb86c342Sgavinm /*
275bb86c342Sgavinm  * Is 'rev' at least revision 'revmin' or greater
276bb86c342Sgavinm  */
277*22e4c3acSKeith M Wesolowski #define	MC_REV_ATLEAST(rev, minrev)	chiprev_at_least(rev, minrev)
278bb86c342Sgavinm 
2798a40a695Sgavinm #define	_MCREG_FIELD(up, revsuffix, field) ((up)->_fmt_##revsuffix.field)
2807aec1d6eScindi 
2818a40a695Sgavinm #define	MCREG_VAL32(up) ((up)->_val32)
2828a40a695Sgavinm 
28320c794b3Sgavinm /*
28420c794b3Sgavinm  * Access a field that has the same structure in all families and revisions
28520c794b3Sgavinm  */
2868a40a695Sgavinm #define	MCREG_FIELD_CMN(up, field)	_MCREG_FIELD(up, cmn, field)
28720c794b3Sgavinm 
28820c794b3Sgavinm /*
28920c794b3Sgavinm  * Access a field as defined for family 0xf prior to revision F
29020c794b3Sgavinm  */
29120c794b3Sgavinm #define	MCREG_FIELD_F_preF(up, field)	_MCREG_FIELD(up, f_preF, field)
29220c794b3Sgavinm 
29320c794b3Sgavinm /*
29420c794b3Sgavinm  * Access a field as defined for family 0xf revisions F and G
29520c794b3Sgavinm  */
29620c794b3Sgavinm #define	MCREG_FIELD_F_revFG(up, field)	_MCREG_FIELD(up, f_revFG, field)
29720c794b3Sgavinm 
29820c794b3Sgavinm /*
29920c794b3Sgavinm  * Access a field as defined for family 0x10 revisions A and
30020c794b3Sgavinm  */
30120c794b3Sgavinm #define	MCREG_FIELD_10_revAB(up, field)	_MCREG_FIELD(up, 10_revAB, field)
30220c794b3Sgavinm 
30320c794b3Sgavinm /*
30420c794b3Sgavinm  * We will only define the register bitfields for little-endian order
30520c794b3Sgavinm  */
30620c794b3Sgavinm #ifdef	_BIT_FIELDS_LTOH
3077aec1d6eScindi 
3089dd0f810Scindi /*
3099dd0f810Scindi  * Function 0 - HT Configuration: Routing Table Node Register
3109dd0f810Scindi  */
3119dd0f810Scindi union mcreg_htroute {
3129dd0f810Scindi 	uint32_t	_val32;
3139dd0f810Scindi 	struct {
3149dd0f810Scindi 		uint32_t	RQRte:4;	/*  3:0 */
3159dd0f810Scindi 		uint32_t	reserved1:4;	/*  7:4 */
3169dd0f810Scindi 		uint32_t	RPRte:4;	/* 11:8 */
3179dd0f810Scindi 		uint32_t	reserved2:4;	/* 15:12 */
3189dd0f810Scindi 		uint32_t	BCRte:4;	/* 19:16 */
3199dd0f810Scindi 		uint32_t	reserved3:12;	/* 31:20 */
3209dd0f810Scindi 	} _fmt_cmn;
3219dd0f810Scindi };
3229dd0f810Scindi 
3239dd0f810Scindi /*
3249dd0f810Scindi  * Function 0 - HT Configuration: Node ID Register
3259dd0f810Scindi  */
3269dd0f810Scindi union mcreg_nodeid {
3279dd0f810Scindi 	uint32_t	_val32;
3289dd0f810Scindi 	struct {
3299dd0f810Scindi 		uint32_t	NodeId:3;	/*  2:0 */
3309dd0f810Scindi 		uint32_t	reserved1:1;	/*  3:3 */
3319dd0f810Scindi 		uint32_t	NodeCnt:3;	/*  6:4 */
3329dd0f810Scindi 		uint32_t	reserved2:1;	/*  7:7 */
3339dd0f810Scindi 		uint32_t	SbNode:3;	/* 10:8 */
3349dd0f810Scindi 		uint32_t	reserved3:1;	/* 11:11 */
3359dd0f810Scindi 		uint32_t	LkNode:3;	/* 14:12 */
3369dd0f810Scindi 		uint32_t	reserved4:1;	/* 15:15 */
3379dd0f810Scindi 		uint32_t	CpuCnt:4;	/* 19:16 */
3389dd0f810Scindi 		uint32_t	reserved:12;	/* 31:20 */
3399dd0f810Scindi 	} _fmt_cmn;
3409dd0f810Scindi };
3419dd0f810Scindi 
3429dd0f810Scindi #define	HT_COHERENTNODES(up)	(MCREG_FIELD_CMN(up, NodeCnt) + 1)
3439dd0f810Scindi #define	HT_SYSTEMCORECOUNT(up)	(MCREG_FIELD_CMN(up, CpuCnt) + 1)
3449dd0f810Scindi 
3459dd0f810Scindi /*
3469dd0f810Scindi  * Function 0 - HT Configuration: Unit ID Register
3479dd0f810Scindi  */
3489dd0f810Scindi union mcreg_unitid {
3499dd0f810Scindi 	uint32_t	_val32;
3509dd0f810Scindi 	struct {
3519dd0f810Scindi 		uint32_t	C0Unit:2;	/*  1:0 */
3529dd0f810Scindi 		uint32_t	C1Unit:2;	/*  3:2 */
3539dd0f810Scindi 		uint32_t	McUnit:2;	/*  5:4 */
3549dd0f810Scindi 		uint32_t	HbUnit:2;	/*  7:6 */
3559dd0f810Scindi 		uint32_t	SbLink:2;	/*  9:8 */
3569dd0f810Scindi 		uint32_t	reserved:22;	/* 31:10 */
3579dd0f810Scindi 	} _fmt_cmn;
3589dd0f810Scindi };
3599dd0f810Scindi 
3607aec1d6eScindi /*
3618a40a695Sgavinm  * Function 1 - DRAM Address Map: DRAM Base i Registers
3627aec1d6eScindi  *
3637aec1d6eScindi  */
3647aec1d6eScindi 
3658a40a695Sgavinm union mcreg_drambase {
3668a40a695Sgavinm 	uint32_t	_val32;
3678a40a695Sgavinm 	struct {
3688a40a695Sgavinm 		uint32_t	RE:1;		/*  0:0  - Read Enable */
3698a40a695Sgavinm 		uint32_t	WE:1;		/*  1:1  - Write Enable */
3708a40a695Sgavinm 		uint32_t	reserved1:6;	/*  7:2 */
3718a40a695Sgavinm 		uint32_t	IntlvEn:3;	/* 10:8  - Interleave Enable */
3728a40a695Sgavinm 		uint32_t	reserved2:5;	/* 15:11 */
3738a40a695Sgavinm 		uint32_t	DRAMBasei:16;	/* 31:16 - Base Addr 39:24 */
3748a40a695Sgavinm 	} _fmt_cmn;
3758a40a695Sgavinm };
3768a40a695Sgavinm 
3778a40a695Sgavinm #define	MC_DRAMBASE(up)	((uint64_t)MCREG_FIELD_CMN(up, DRAMBasei) << 24)
3788a40a695Sgavinm 
3798a40a695Sgavinm /*
3808a40a695Sgavinm  * Function 1 - DRAM Address Map: DRAM Limit i Registers
3818a40a695Sgavinm  *
3828a40a695Sgavinm  */
3838a40a695Sgavinm 
3848a40a695Sgavinm union mcreg_dramlimit {
3858a40a695Sgavinm 	uint32_t	_val32;
3868a40a695Sgavinm 	struct {
3878a40a695Sgavinm 		uint32_t	DstNode:3;	/*  2:0  - Destination Node */
3888a40a695Sgavinm 		uint32_t	reserved1:5;	/*  7:3 */
3898a40a695Sgavinm 		uint32_t	IntlvSel:3;	/* 10:8  - Interleave Select */
3908a40a695Sgavinm 		uint32_t	reserved2:5;	/* 15:11 */
3918a40a695Sgavinm 		uint32_t	DRAMLimiti:16;	/* 31:16 - Limit Addr 39:24 */
3928a40a695Sgavinm 	} _fmt_cmn;
3938a40a695Sgavinm };
3948a40a695Sgavinm 
3958a40a695Sgavinm #define	MC_DRAMLIM(up) \
3968a40a695Sgavinm 	((uint64_t)MCREG_FIELD_CMN(up, DRAMLimiti) << 24 |		\
3978a40a695Sgavinm 	(MCREG_FIELD_CMN(up, DRAMLimiti) ?  ((1 << 24) - 1) : 0))
3988a40a695Sgavinm 
3998a40a695Sgavinm /*
4008a40a695Sgavinm  * Function 1 - DRAM Address Map: DRAM Hole Address Register
4018a40a695Sgavinm  */
4028a40a695Sgavinm 
4038a40a695Sgavinm union mcreg_dramhole {
4048a40a695Sgavinm 	uint32_t	_val32;
4058a40a695Sgavinm 	struct {
4068a40a695Sgavinm 		uint32_t	DramHoleValid:1;	/*  0:0 */
4078a40a695Sgavinm 		uint32_t	reserved1:7;		/*  7:1 */
4088a40a695Sgavinm 		uint32_t	DramHoleOffset:8;	/* 15:8 */
4098a40a695Sgavinm 		uint32_t	reserved2:8;		/* 23:16 */
4108a40a695Sgavinm 		uint32_t	DramHoleBase:8;		/* 31:24 */
4118a40a695Sgavinm 	} _fmt_cmn;
4128a40a695Sgavinm };
4138a40a695Sgavinm 
4148a40a695Sgavinm #define	MC_DRAMHOLE_SIZE(up) (MCREG_FIELD_CMN(up, DramHoleOffset) << 24)
4158a40a695Sgavinm 
4168a40a695Sgavinm /*
4178a40a695Sgavinm  * Function 2 - DRAM Controller: DRAM CS Base Address Registers
4188a40a695Sgavinm  */
4198a40a695Sgavinm 
4208a40a695Sgavinm union mcreg_csbase {
4218a40a695Sgavinm 	uint32_t	_val32;
4228a40a695Sgavinm 	/*
42320c794b3Sgavinm 	 * Register format in family 0xf revisions E and earlier
4248a40a695Sgavinm 	 */
4258a40a695Sgavinm 	struct {
4268a40a695Sgavinm 		uint32_t	CSEnable:1;	/*  0:0  - CS Bank Enable */
4278a40a695Sgavinm 		uint32_t	reserved1:8;	/*  8:1 */
4288a40a695Sgavinm 		uint32_t	BaseAddrLo:7;	/* 15:9  - Base Addr 19:13 */
4298a40a695Sgavinm 		uint32_t	reserved2:5;	/* 20:16 */
4308a40a695Sgavinm 		uint32_t	BaseAddrHi:11;	/* 31:21 - Base Addr 35:25 */
43120c794b3Sgavinm 	} _fmt_f_preF;
4328a40a695Sgavinm 	/*
43320c794b3Sgavinm 	 * Register format in family 0xf revisions F and G
4348a40a695Sgavinm 	 */
4358a40a695Sgavinm 	struct {
4368a40a695Sgavinm 		uint32_t	CSEnable:1;	/*  0:0  - CS Bank Enable */
4378a40a695Sgavinm 		uint32_t	Spare:1;	/*  1:1  - Spare Rank */
4388a40a695Sgavinm 		uint32_t	TestFail:1;	/*  2:2  - Memory Test Failed */
4398a40a695Sgavinm 		uint32_t	reserved1:2;	/*  4:3 */
4408a40a695Sgavinm 		uint32_t	BaseAddrLo:9;	/* 13:5  - Base Addr 21:13 */
4418a40a695Sgavinm 		uint32_t	reserved2:5;	/* 18:14 */
4428a40a695Sgavinm 		uint32_t	BaseAddrHi:10;	/* 28:19 - Base Addr 36:27 */
4438a40a695Sgavinm 		uint32_t	reserved3:3;	/* 31:39 */
44420c794b3Sgavinm 	} _fmt_f_revFG;
4458a40a695Sgavinm };
4468a40a695Sgavinm 
44720c794b3Sgavinm #define	MC_CSBASE(up, rev) (MC_REV_MATCH(rev, MC_F_REVS_FG) ?	\
44820c794b3Sgavinm 	(uint64_t)MCREG_FIELD_F_revFG(up, BaseAddrHi) << 27 |		\
44920c794b3Sgavinm 	(uint64_t)MCREG_FIELD_F_revFG(up, BaseAddrLo) << 13 :		\
45020c794b3Sgavinm 	(uint64_t)MCREG_FIELD_F_preF(up, BaseAddrHi) << 25 |		\
45120c794b3Sgavinm 	(uint64_t)MCREG_FIELD_F_preF(up, BaseAddrLo) << 13)
4528a40a695Sgavinm 
4538a40a695Sgavinm /*
4548a40a695Sgavinm  * Function 2 - DRAM Controller: DRAM CS Mask Registers
4558a40a695Sgavinm  */
4568a40a695Sgavinm 
4578a40a695Sgavinm union mcreg_csmask {
4588a40a695Sgavinm 	uint32_t	_val32;
4598a40a695Sgavinm 	/*
46020c794b3Sgavinm 	 * Register format in family 0xf revisions E and earlier
4618a40a695Sgavinm 	 */
4628a40a695Sgavinm 	struct {
4638a40a695Sgavinm 		uint32_t	reserved1:9;	/*  8:0 */
4648a40a695Sgavinm 		uint32_t	AddrMaskLo:7;	/* 15:9  - Addr Mask 19:13 */
4658a40a695Sgavinm 		uint32_t	reserved2:5;	/* 20:16 */
4668a40a695Sgavinm 		uint32_t	AddrMaskHi:9;	/* 29:21 - Addr Mask 33:25 */
4678a40a695Sgavinm 		uint32_t	reserved3:2;	/* 31:30 */
46820c794b3Sgavinm 	} _fmt_f_preF;
4698a40a695Sgavinm 	/*
47020c794b3Sgavinm 	 * Register format in family 0xf revisions F and G
4718a40a695Sgavinm 	 */
4728a40a695Sgavinm 	struct {
4738a40a695Sgavinm 		uint32_t	reserved1:5;	/*  4:0 */
4748a40a695Sgavinm 		uint32_t	AddrMaskLo:9;	/* 13:5  - Addr Mask 21:13 */
4758a40a695Sgavinm 		uint32_t	reserved2:5;	/* 18:14 */
4768a40a695Sgavinm 		uint32_t	AddrMaskHi:10;	/* 28:19 - Addr Mask 36:27 */
4778a40a695Sgavinm 		uint32_t	reserved3:3;	/* 31:29 */
47820c794b3Sgavinm 	} _fmt_f_revFG;
4798a40a695Sgavinm };
4807aec1d6eScindi 
48120c794b3Sgavinm #define	MC_CSMASKLO_LOBIT(rev) (MC_REV_MATCH(rev, MC_F_REVS_FG) ? 13 : 13)
48220c794b3Sgavinm #define	MC_CSMASKLO_HIBIT(rev) (MC_REV_MATCH(rev, MC_F_REVS_FG) ? 21 : 19)
4837aec1d6eScindi 
48420c794b3Sgavinm #define	MC_CSMASKHI_LOBIT(rev) (MC_REV_MATCH(rev, MC_F_REVS_FG) ? 27 : 25)
48520c794b3Sgavinm #define	MC_CSMASKHI_HIBIT(rev) (MC_REV_MATCH(rev, MC_F_REVS_FG) ? 36 : 33)
4867aec1d6eScindi 
48720c794b3Sgavinm #define	MC_CSMASK_UNMASKABLE(rev) (MC_REV_MATCH(rev, MC_F_REVS_FG) ? 0 : 2)
4888a40a695Sgavinm 
48920c794b3Sgavinm #define	MC_CSMASK(up, rev) (MC_REV_MATCH(rev, MC_F_REVS_FG) ? \
49020c794b3Sgavinm 	(uint64_t)MCREG_FIELD_F_revFG(up, AddrMaskHi) << 27 | \
49120c794b3Sgavinm 	(uint64_t)MCREG_FIELD_F_revFG(up, AddrMaskLo) << 13 | 0x7c01fff : \
49220c794b3Sgavinm 	(uint64_t)MCREG_FIELD_F_preF(up, AddrMaskHi) << 25 | \
49320c794b3Sgavinm 	(uint64_t)MCREG_FIELD_F_preF(up, AddrMaskLo) << 13 | 0x1f01fff)
4947aec1d6eScindi 
4957aec1d6eScindi /*
4968a40a695Sgavinm  * Function 2 - DRAM Controller: DRAM Bank Address Mapping Registers
4977aec1d6eScindi  */
4988a40a695Sgavinm 
4998a40a695Sgavinm union mcreg_bankaddrmap {
5008a40a695Sgavinm 	uint32_t	_val32;
5018a40a695Sgavinm 	/*
50220c794b3Sgavinm 	 * Register format in family 0xf revisions E and earlier
5038a40a695Sgavinm 	 */
5048a40a695Sgavinm 	struct {
5058a40a695Sgavinm 		uint32_t	cs10:4;			/*  3:0  - CS1/0 */
5068a40a695Sgavinm 		uint32_t	cs32:4;			/*  7:4  - CS3/2 */
5078a40a695Sgavinm 		uint32_t	cs54:4;			/* 11:8  - CS5/4 */
5088a40a695Sgavinm 		uint32_t	cs76:4;			/* 15:12 - CS7/6 */
5098a40a695Sgavinm 		uint32_t	reserved1:14;		/* 29:16 */
5108a40a695Sgavinm 		uint32_t	BankSwizzleMode:1;	/* 30:30 */
5118a40a695Sgavinm 		uint32_t	reserved2:1;		/* 31:31 */
51220c794b3Sgavinm 	} _fmt_f_preF;
5138a40a695Sgavinm 	/*
51420c794b3Sgavinm 	 * Register format in family 0xf revisions F and G
5158a40a695Sgavinm 	 */
5168a40a695Sgavinm 	struct {
5178a40a695Sgavinm 		uint32_t	cs10:4;			/*  3:0  - CS1/0 */
5188a40a695Sgavinm 		uint32_t	cs32:4;			/*  7:4  - CS3/2 */
5198a40a695Sgavinm 		uint32_t	cs54:4;			/* 11:8  - CS5/4 */
5208a40a695Sgavinm 		uint32_t	cs76:4;			/* 15:12 - CS7/6 */
5218a40a695Sgavinm 		uint32_t	reserved1:16;		/* 31:16 */
52220c794b3Sgavinm 	} _fmt_f_revFG;
5238a40a695Sgavinm 	/*
5248a40a695Sgavinm 	 * Accessing all mode encodings as one uint16
5258a40a695Sgavinm 	 */
5268a40a695Sgavinm 	struct {
5278a40a695Sgavinm 		uint32_t	allcsmodes:16;		/* 15:0 */
5288a40a695Sgavinm 		uint32_t	pad:16;			/* 31:16 */
5298a40a695Sgavinm 	} _fmt_bankmodes;
5308a40a695Sgavinm };
5318a40a695Sgavinm 
5327aec1d6eScindi #define	MC_DC_BAM_CSBANK_MASK	0x0000000f
5337aec1d6eScindi #define	MC_DC_BAM_CSBANK_SHIFT	4
5348a40a695Sgavinm 
5358a40a695Sgavinm #define	MC_CSBANKMODE(up, csnum) ((up)->_fmt_bankmodes.allcsmodes >>	\
5368a40a695Sgavinm     MC_DC_BAM_CSBANK_SHIFT * MC_CHIP_DIMMPAIR(csnum) & MC_DC_BAM_CSBANK_MASK)
5378a40a695Sgavinm 
5388a40a695Sgavinm /*
5398a40a695Sgavinm  * Function 2 - DRAM Controller: DRAM Configuration Low and High
5408a40a695Sgavinm  */
5418a40a695Sgavinm 
5428a40a695Sgavinm union mcreg_dramcfg_lo {
5438a40a695Sgavinm 	uint32_t _val32;
5448a40a695Sgavinm 	/*
54520c794b3Sgavinm 	 * Register format in family 0xf revisions E and earlier.
5468a40a695Sgavinm 	 * Bit 7 is a BIOS ScratchBit in revs D and earlier,
5478a40a695Sgavinm 	 * PwrDwnTriEn in revision E;  we don't use it so
5488a40a695Sgavinm 	 * we'll call it ambig1.
5498a40a695Sgavinm 	 */
5508a40a695Sgavinm 	struct {
5518a40a695Sgavinm 		uint32_t	DLL_Dis:1;	/* 0 */
5528a40a695Sgavinm 		uint32_t	D_DRV:1;	/* 1 */
5538a40a695Sgavinm 		uint32_t	QFC_EN:1;	/* 2 */
5548a40a695Sgavinm 		uint32_t	DisDqsHys:1;	/* 3 */
5558a40a695Sgavinm 		uint32_t	reserved1:1;	/* 4 */
5568a40a695Sgavinm 		uint32_t	Burst2Opt:1;	/* 5 */
5578a40a695Sgavinm 		uint32_t	Mod64BitMux:1;	/* 6 */
5588a40a695Sgavinm 		uint32_t	ambig1:1;	/* 7 */
5598a40a695Sgavinm 		uint32_t	DramInit:1;	/* 8 */
5608a40a695Sgavinm 		uint32_t	DualDimmEn:1;	/* 9 */
5618a40a695Sgavinm 		uint32_t	DramEnable:1;	/* 10 */
5628a40a695Sgavinm 		uint32_t	MemClrStatus:1;	/* 11 */
5638a40a695Sgavinm 		uint32_t	ESR:1;		/* 12 */
5648a40a695Sgavinm 		uint32_t	SR_S:1;		/* 13 */
5658a40a695Sgavinm 		uint32_t	RdWrQByp:2;	/* 15:14 */
5668a40a695Sgavinm 		uint32_t	Width128:1;	/* 16 */
5678a40a695Sgavinm 		uint32_t	DimmEcEn:1;	/* 17 */
5688a40a695Sgavinm 		uint32_t	UnBufDimm:1;	/* 18 */
5698a40a695Sgavinm 		uint32_t	ByteEn32:1;	/* 19 */
5708a40a695Sgavinm 		uint32_t	x4DIMMs:4;	/* 23:20 */
5718a40a695Sgavinm 		uint32_t	DisInRcvrs:1;	/* 24 */
5728a40a695Sgavinm 		uint32_t	BypMax:3;	/* 27:25 */
5738a40a695Sgavinm 		uint32_t	En2T:1;		/* 28 */
5748a40a695Sgavinm 		uint32_t	UpperCSMap:1;	/* 29 */
5758a40a695Sgavinm 		uint32_t	PwrDownCtl:2;	/* 31:30 */
57620c794b3Sgavinm 	} _fmt_f_preF;
5778a40a695Sgavinm 	/*
57820c794b3Sgavinm 	 * Register format in family 0xf revisions F and G
5798a40a695Sgavinm 	 */
5808a40a695Sgavinm 	struct {
5818a40a695Sgavinm 		uint32_t	InitDram:1;		/* 0 */
5828a40a695Sgavinm 		uint32_t	ExitSelfRef:1;		/* 1 */
5838a40a695Sgavinm 		uint32_t	reserved1:2;		/* 3:2 */
5848a40a695Sgavinm 		uint32_t	DramTerm:2;		/* 5:4 */
5858a40a695Sgavinm 		uint32_t	reserved2:1;		/* 6 */
5868a40a695Sgavinm 		uint32_t	DramDrvWeak:1;		/* 7 */
5878a40a695Sgavinm 		uint32_t	ParEn:1;		/* 8 */
5888a40a695Sgavinm 		uint32_t	SelRefRateEn:1;		/* 9 */
5898a40a695Sgavinm 		uint32_t	BurstLength32:1;	/* 10 */
5908a40a695Sgavinm 		uint32_t	Width128:1;		/* 11 */
5918a40a695Sgavinm 		uint32_t	x4DIMMs:4;		/* 15:12 */
5928a40a695Sgavinm 		uint32_t	UnBuffDimm:1;		/* 16 */
5938a40a695Sgavinm 		uint32_t	reserved3:2;		/* 18:17 */
5948a40a695Sgavinm 		uint32_t	DimmEccEn:1;		/* 19 */
5958a40a695Sgavinm 		uint32_t	reserved4:12;		/* 31:20 */
59620c794b3Sgavinm 	} _fmt_f_revFG;
5978a40a695Sgavinm };
5988a40a695Sgavinm 
5998a40a695Sgavinm /*
6008a40a695Sgavinm  * Function 2 - DRAM Controller: DRAM Controller Miscellaneous Data
6018a40a695Sgavinm  */
6028a40a695Sgavinm 
6038a40a695Sgavinm union mcreg_drammisc {
6048a40a695Sgavinm 	uint32_t _val32;
6058a40a695Sgavinm 	/*
60620c794b3Sgavinm 	 * Register format in family 0xf revisions F and G
6078a40a695Sgavinm 	 */
6088a40a695Sgavinm 	struct {
6098a40a695Sgavinm 		uint32_t	reserved2:1;		/* 0 */
6108a40a695Sgavinm 		uint32_t	DisableJitter:1;	/* 1 */
6118a40a695Sgavinm 		uint32_t	RdWrQByp:2;		/* 3:2 */
6128a40a695Sgavinm 		uint32_t	Mod64Mux:1;		/* 4 */
6138a40a695Sgavinm 		uint32_t	DCC_EN:1;		/* 5 */
6148a40a695Sgavinm 		uint32_t	ILD_lmt:3;		/* 8:6 */
6158a40a695Sgavinm 		uint32_t	DramEnabled:1;		/* 9 */
6168a40a695Sgavinm 		uint32_t	PwrSavingsEn:1;		/* 10 */
6178a40a695Sgavinm 		uint32_t	reserved1:13;		/* 23:11 */
6188a40a695Sgavinm 		uint32_t	MemClkDis:8;		/* 31:24 */
61920c794b3Sgavinm 	} _fmt_f_revFG;
6208a40a695Sgavinm };
6218a40a695Sgavinm 
6228a40a695Sgavinm union mcreg_dramcfg_hi {
6238a40a695Sgavinm 	uint32_t _val32;
6248a40a695Sgavinm 	/*
62520c794b3Sgavinm 	 * Register format in family 0xf revisions E and earlier.
6268a40a695Sgavinm 	 */
6278a40a695Sgavinm 	struct {
6288a40a695Sgavinm 		uint32_t	AsyncLat:4;		/* 3:0 */
6298a40a695Sgavinm 		uint32_t	reserved1:4;		/* 7:4 */
6308a40a695Sgavinm 		uint32_t	RdPreamble:4;		/* 11:8 */
6318a40a695Sgavinm 		uint32_t	reserved2:1;		/* 12 */
6328a40a695Sgavinm 		uint32_t	MemDQDrvStren:2;	/* 14:13 */
6338a40a695Sgavinm 		uint32_t	DisableJitter:1;	/* 15 */
6348a40a695Sgavinm 		uint32_t	ILD_lmt:3;		/* 18:16 */
6358a40a695Sgavinm 		uint32_t	DCC_EN:1;		/* 19 */
6368a40a695Sgavinm 		uint32_t	MemClk:3;		/* 22:20 */
6378a40a695Sgavinm 		uint32_t	reserved3:2;		/* 24:23 */
6388a40a695Sgavinm 		uint32_t	MCR:1;			/* 25 */
6398a40a695Sgavinm 		uint32_t	MC0_EN:1;		/* 26 */
6408a40a695Sgavinm 		uint32_t	MC1_EN:1;		/* 27 */
6418a40a695Sgavinm 		uint32_t	MC2_EN:1;		/* 28 */
6428a40a695Sgavinm 		uint32_t	MC3_EN:1;		/* 29 */
6438a40a695Sgavinm 		uint32_t	reserved4:1;		/* 30 */
6448a40a695Sgavinm 		uint32_t	OddDivisorCorrect:1;	/* 31 */
64520c794b3Sgavinm 	} _fmt_f_preF;
6468a40a695Sgavinm 	/*
64720c794b3Sgavinm 	 * Register format in family 0xf revisions F and G
6488a40a695Sgavinm 	 */
6498a40a695Sgavinm 	struct {
6508a40a695Sgavinm 		uint32_t	MemClkFreq:3;		/* 2:0 */
6518a40a695Sgavinm 		uint32_t	MemClkFreqVal:1;	/* 3 */
6528a40a695Sgavinm 		uint32_t	MaxAsyncLat:4;		/* 7:4 */
6538a40a695Sgavinm 		uint32_t	reserved1:4;		/* 11:8 */
6548a40a695Sgavinm 		uint32_t	RDqsEn:1;		/* 12 */
6558a40a695Sgavinm 		uint32_t	reserved2:1;		/* 13 */
6568a40a695Sgavinm 		uint32_t	DisDramInterface:1;	/* 14 */
6578a40a695Sgavinm 		uint32_t	PowerDownEn:1;		/* 15 */
6588a40a695Sgavinm 		uint32_t	PowerDownMode:1;	/* 16 */
6598a40a695Sgavinm 		uint32_t	FourRankSODimm:1;	/* 17 */
6608a40a695Sgavinm 		uint32_t	FourRankRDimm:1;	/* 18 */
6618a40a695Sgavinm 		uint32_t	reserved3:1;		/* 19 */
6628a40a695Sgavinm 		uint32_t	SlowAccessMode:1;	/* 20 */
6638a40a695Sgavinm 		uint32_t	reserved4:1;		/* 21 */
6648a40a695Sgavinm 		uint32_t	BankSwizzleMode:1;	/* 22 */
6658a40a695Sgavinm 		uint32_t	undocumented1:1;	/* 23 */
6668a40a695Sgavinm 		uint32_t	DcqBypassMax:4;		/* 27:24 */
6678a40a695Sgavinm 		uint32_t	FourActWindow:4;	/* 31:28 */
66820c794b3Sgavinm 	} _fmt_f_revFG;
6698a40a695Sgavinm };
6708a40a695Sgavinm 
6718a40a695Sgavinm /*
6728a40a695Sgavinm  * Function 3 - Miscellaneous Control: Scrub Control Register
6738a40a695Sgavinm  */
6748a40a695Sgavinm 
6758a40a695Sgavinm union mcreg_scrubctl {
6768a40a695Sgavinm 	uint32_t _val32;
6778a40a695Sgavinm 	struct {
6788a40a695Sgavinm 		uint32_t	DramScrub:5;		/* 4:0 */
6798a40a695Sgavinm 		uint32_t	reserved3:3;		/* 7:5 */
6808a40a695Sgavinm 		uint32_t	L2Scrub:5;		/* 12:8 */
6818a40a695Sgavinm 		uint32_t	reserved2:3;		/* 15:13 */
6828a40a695Sgavinm 		uint32_t	DcacheScrub:5;		/* 20:16 */
6838a40a695Sgavinm 		uint32_t	reserved1:11;		/* 31:21 */
6848a40a695Sgavinm 	} _fmt_cmn;
6858a40a695Sgavinm };
6868a40a695Sgavinm 
68720c794b3Sgavinm union mcreg_dramscrublo {
68820c794b3Sgavinm 	uint32_t _val32;
68920c794b3Sgavinm 	struct {
69020c794b3Sgavinm 		uint32_t	ScrubReDirEn:1;		/* 0 */
69120c794b3Sgavinm 		uint32_t	reserved:5;		/* 5:1 */
69220c794b3Sgavinm 		uint32_t	ScrubAddrLo:26;		/* 31:6 */
69320c794b3Sgavinm 	} _fmt_cmn;
69420c794b3Sgavinm };
69520c794b3Sgavinm 
69620c794b3Sgavinm union mcreg_dramscrubhi {
69720c794b3Sgavinm 	uint32_t _val32;
69820c794b3Sgavinm 	struct {
69920c794b3Sgavinm 		uint32_t	ScrubAddrHi:8;		/* 7:0 */
70020c794b3Sgavinm 		uint32_t	reserved:24;		/* 31:8 */
70120c794b3Sgavinm 	} _fmt_cmn;
70220c794b3Sgavinm };
70320c794b3Sgavinm 
7048a40a695Sgavinm /*
7058a40a695Sgavinm  * Function 3 - Miscellaneous Control: On-Line Spare Control Register
7068a40a695Sgavinm  */
7078a40a695Sgavinm 
7088a40a695Sgavinm union mcreg_nbcfg {
7098a40a695Sgavinm 	uint32_t _val32;
7108a40a695Sgavinm 	/*
71120c794b3Sgavinm 	 * Register format in family 0xf revisions E and earlier.
7128a40a695Sgavinm 	 */
7138a40a695Sgavinm 	struct {
7148a40a695Sgavinm 		uint32_t	CpuEccErrEn:1;			/* 0 */
7158a40a695Sgavinm 		uint32_t	CpuRdDatErrEn:1;		/* 1 */
7168a40a695Sgavinm 		uint32_t	SyncOnUcEccEn:1;		/* 2 */
7178a40a695Sgavinm 		uint32_t	SyncPktGenDis:1;		/* 3 */
7188a40a695Sgavinm 		uint32_t	SyncPktPropDis:1;		/* 4 */
7198a40a695Sgavinm 		uint32_t	IoMstAbortDis:1;		/* 5 */
7208a40a695Sgavinm 		uint32_t	CpuErrDis:1;			/* 6 */
7218a40a695Sgavinm 		uint32_t	IoErrDis:1;			/* 7 */
7228a40a695Sgavinm 		uint32_t	WdogTmrDis:1;			/* 8 */
7238a40a695Sgavinm 		uint32_t	WdogTmrCntSel:3;		/* 11:9 */
7248a40a695Sgavinm 		uint32_t	WdogTmrBaseSel:2;		/* 13:12 */
7258a40a695Sgavinm 		uint32_t	LdtLinkSel:2;			/* 15:14 */
7268a40a695Sgavinm 		uint32_t	GenCrcErrByte0:1;		/* 16 */
7278a40a695Sgavinm 		uint32_t	GenCrcErrByte1:1;		/* 17 */
7288a40a695Sgavinm 		uint32_t	reserved1:2;			/* 19:18 */
7298a40a695Sgavinm 		uint32_t	SyncOnWdogEn:1;			/* 20 */
7308a40a695Sgavinm 		uint32_t	SyncOnAnyErrEn:1;		/* 21 */
7318a40a695Sgavinm 		uint32_t	EccEn:1;			/* 22 */
7328a40a695Sgavinm 		uint32_t	ChipKillEccEn:1;		/* 23 */
7338a40a695Sgavinm 		uint32_t	IoRdDatErrEn:1;			/* 24 */
7348a40a695Sgavinm 		uint32_t	DisPciCfgCpuErrRsp:1;		/* 25 */
7358a40a695Sgavinm 		uint32_t	reserved2:1;			/* 26 */
7368a40a695Sgavinm 		uint32_t	NbMcaToMstCpuEn:1;		/* 27 */
7378a40a695Sgavinm 		uint32_t	reserved3:4;			/* 31:28 */
73820c794b3Sgavinm 	} _fmt_f_preF;
7398a40a695Sgavinm 	/*
74020c794b3Sgavinm 	 * Register format in family 0xf revisions F and G
7418a40a695Sgavinm 	 */
7428a40a695Sgavinm 	struct {
7438a40a695Sgavinm 		uint32_t	CpuEccErrEn:1;			/* 0 */
7448a40a695Sgavinm 		uint32_t	CpuRdDatErrEn:1;		/* 1 */
7458a40a695Sgavinm 		uint32_t	SyncOnUcEccEn:1;		/* 2 */
7468a40a695Sgavinm 		uint32_t	SyncPktGenDis:1;		/* 3 */
7478a40a695Sgavinm 		uint32_t	SyncPktPropDis:1;		/* 4 */
7488a40a695Sgavinm 		uint32_t	IoMstAbortDis:1;		/* 5 */
7498a40a695Sgavinm 		uint32_t	CpuErrDis:1;			/* 6 */
7508a40a695Sgavinm 		uint32_t	IoErrDis:1;			/* 7 */
7518a40a695Sgavinm 		uint32_t	WdogTmrDis:1;			/* 8 */
7528a40a695Sgavinm 		uint32_t	WdogTmrCntSel:3;		/* 11:9 */
7538a40a695Sgavinm 		uint32_t	WdogTmrBaseSel:2;		/* 13:12 */
7548a40a695Sgavinm 		uint32_t	LdtLinkSel:2;			/* 15:14 */
7558a40a695Sgavinm 		uint32_t	GenCrcErrByte0:1;		/* 16 */
7568a40a695Sgavinm 		uint32_t	GenCrcErrByte1:1;		/* 17 */
7578a40a695Sgavinm 		uint32_t	reserved1:2;			/* 19:18 */
7588a40a695Sgavinm 		uint32_t	SyncOnWdogEn:1;			/* 20 */
7598a40a695Sgavinm 		uint32_t	SyncOnAnyErrEn:1;		/* 21 */
7608a40a695Sgavinm 		uint32_t	EccEn:1;			/* 22 */
7618a40a695Sgavinm 		uint32_t	ChipKillEccEn:1;		/* 23 */
7628a40a695Sgavinm 		uint32_t	IoRdDatErrEn:1;			/* 24 */
7638a40a695Sgavinm 		uint32_t	DisPciCfgCpuErrRsp:1;		/* 25 */
7648a40a695Sgavinm 		uint32_t	reserved2:1;			/* 26 */
7658a40a695Sgavinm 		uint32_t	NbMcaToMstCpuEn:1;		/* 27 */
7668a40a695Sgavinm 		uint32_t	DisTgtAbtCpuErrRsp:1;		/* 28 */
7678a40a695Sgavinm 		uint32_t	DisMstAbtCpuErrRsp:1;		/* 29 */
7688a40a695Sgavinm 		uint32_t	SyncOnDramAdrParErrEn:1;	/* 30 */
7698a40a695Sgavinm 		uint32_t	reserved3:1;			/* 31 */
7708a40a695Sgavinm 
77120c794b3Sgavinm 	} _fmt_f_revFG;
7728a40a695Sgavinm };
7738a40a695Sgavinm 
7748a40a695Sgavinm /*
7758a40a695Sgavinm  * Function 3 - Miscellaneous Control: On-Line Spare Control Register
7768a40a695Sgavinm  */
7778a40a695Sgavinm 
7788a40a695Sgavinm union mcreg_sparectl {
7798a40a695Sgavinm 	uint32_t _val32;
7808a40a695Sgavinm 	/*
78120c794b3Sgavinm 	 * Register format in family 0xf revisions F and G
7828a40a695Sgavinm 	 */
7838a40a695Sgavinm 	struct {
7848a40a695Sgavinm 		uint32_t	SwapEn:1;		/* 0 */
7858a40a695Sgavinm 		uint32_t	SwapDone:1;		/* 1 */
7868a40a695Sgavinm 		uint32_t	reserved1:2;		/* 3:2 */
7878a40a695Sgavinm 		uint32_t	BadDramCs:3;		/* 6:4 */
7888a40a695Sgavinm 		uint32_t	reserved2:5;		/* 11:7 */
7898a40a695Sgavinm 		uint32_t	SwapDoneInt:2;		/* 13:12 */
7908a40a695Sgavinm 		uint32_t	EccErrInt:2;		/* 15:14 */
7918a40a695Sgavinm 		uint32_t	EccErrCntDramCs:3;	/* 18:16 */
7928a40a695Sgavinm 		uint32_t	reserved3:1;		/* 19 */
7938a40a695Sgavinm 		uint32_t	EccErrCntDramChan:1;	/* 20 */
7948a40a695Sgavinm 		uint32_t	reserved4:2;		/* 22:21 */
7958a40a695Sgavinm 		uint32_t	EccErrCntWrEn:1;	/* 23 */
7968a40a695Sgavinm 		uint32_t	EccErrCnt:4;		/* 27:24 */
7978a40a695Sgavinm 		uint32_t	reserved5:4;		/* 31:28 */
79820c794b3Sgavinm 	} _fmt_f_revFG;
79920c794b3Sgavinm 	/*
80020c794b3Sgavinm 	 * Regiser format in family 0x10 revisions A and B
80120c794b3Sgavinm 	 */
80220c794b3Sgavinm 	struct {
80320c794b3Sgavinm 		uint32_t	SwapEn0:1;		/* 0 */
80420c794b3Sgavinm 		uint32_t	SwapDone0:1;		/* 1 */
80520c794b3Sgavinm 		uint32_t	SwapEn1:1;		/* 2 */
80620c794b3Sgavinm 		uint32_t	SwapDone1:1;		/* 3 */
80720c794b3Sgavinm 		uint32_t	BadDramCs0:3;		/* 6:4 */
80820c794b3Sgavinm 		uint32_t	reserved1:1;		/* 7 */
80920c794b3Sgavinm 		uint32_t	BadDramCs1:3;		/* 10:8 */
81020c794b3Sgavinm 		uint32_t	reserved2:1;		/* 11 */
81120c794b3Sgavinm 		uint32_t	SwapDoneInt:2;		/* 13:12 */
81220c794b3Sgavinm 		uint32_t	EccErrInt:2;		/* 15:14 */
81320c794b3Sgavinm 		uint32_t	EccErrCntDramCs:4;	/* 19:16 */
81420c794b3Sgavinm 		uint32_t	EccErrCntDramChan:2;	/* 21:20 */
81520c794b3Sgavinm 		uint32_t	reserved4:1;		/* 22 */
81620c794b3Sgavinm 		uint32_t	EccErrCntWrEn:1;	/* 23 */
81720c794b3Sgavinm 		uint32_t	EccErrCnt:4;		/* 27:24 */
81820c794b3Sgavinm 		uint32_t	LvtOffset:4;		/* 31:28 */
81920c794b3Sgavinm 	} _fmt_10_revAB;
8208a40a695Sgavinm };
8217aec1d6eScindi 
82220c794b3Sgavinm /*
82320c794b3Sgavinm  * Since the NB is on-chip some registers are also accessible as MSRs.
82420c794b3Sgavinm  * We will represent such registers as bitfields as in the 32-bit PCI
82520c794b3Sgavinm  * registers above, with the restriction that we must compile for 32-bit
82620c794b3Sgavinm  * kernels and so 64-bit bitfields cannot be used.
82720c794b3Sgavinm  */
82820c794b3Sgavinm 
82920c794b3Sgavinm #define	_MCMSR_FIELD(up, revsuffix, field) ((up)->_fmt_##revsuffix.field)
83020c794b3Sgavinm 
83120c794b3Sgavinm #define	MCMSR_VAL(up) ((up)->_val64)
83220c794b3Sgavinm 
83320c794b3Sgavinm #define	MCMSR_FIELD_CMN(up, field)	_MCMSR_FIELD(up, cmn, field)
83420c794b3Sgavinm #define	MCMSR_FIELD_F_preF(up, field)	_MCMSR_FIELD(up, f_preF, field)
83520c794b3Sgavinm #define	MCMSR_FIELD_F_revFG(up, field)	_MCMSR_FIELD(up, f_revFG, field)
83620c794b3Sgavinm #define	MCMSR_FIELD_10_revAB(up, field)	_MCMSR_FIELD(up, 10_revAB, field)
83720c794b3Sgavinm 
83820c794b3Sgavinm /*
83920c794b3Sgavinm  * The NB MISC registers.  On family 0xf rev F this was introduced with
84020c794b3Sgavinm  * a 12-bit ECC error count of all ECC errors observed on this memory-
84120c794b3Sgavinm  * controller (regardless of channel or chip-select) and the ability to
84220c794b3Sgavinm  * raise an interrupt or SMI on overflow.  In family 0x10 it has a similar
84320c794b3Sgavinm  * purpose, but the register is is split into 4 misc registers
84420c794b3Sgavinm  * MC4_MISC{0,1,2,3} accessible via both MSRs and PCI config space;
84520c794b3Sgavinm  * they perform thresholding for dram, l3, HT errors.
84620c794b3Sgavinm  */
84720c794b3Sgavinm 
84820c794b3Sgavinm union mcmsr_nbmisc {
84920c794b3Sgavinm 	uint64_t _val64;
85020c794b3Sgavinm 	/*
85120c794b3Sgavinm 	 * MSR format in family 0xf revision F and later
85220c794b3Sgavinm 	 */
85320c794b3Sgavinm 	struct {
85420c794b3Sgavinm 		/*
85520c794b3Sgavinm 		 * Lower 32 bits
85620c794b3Sgavinm 		 */
85720c794b3Sgavinm 		struct {
85820c794b3Sgavinm 			uint32_t _reserved;			/* 31:0 */
85920c794b3Sgavinm 		} _mcimisc_lo;
86020c794b3Sgavinm 		/*
86120c794b3Sgavinm 		 * Upper 32 bits
86220c794b3Sgavinm 		 */
86320c794b3Sgavinm 		struct {
86420c794b3Sgavinm 			uint32_t _ErrCount:12;			/* 43:32 */
86520c794b3Sgavinm 			uint32_t _reserved1:4;			/* 47:44 */
86620c794b3Sgavinm 			uint32_t _Ovrflw:1;			/* 48 */
86720c794b3Sgavinm 			uint32_t _IntType:2;			/* 50:49 */
86820c794b3Sgavinm 			uint32_t _CntEn:1;			/* 51 */
86920c794b3Sgavinm 			uint32_t _LvtOff:4;			/* 55:52 */
87020c794b3Sgavinm 			uint32_t _reserved2:5;			/* 60:56 */
87120c794b3Sgavinm 			uint32_t _Locked:1;			/* 61 */
87220c794b3Sgavinm 			uint32_t _CntP:1;			/* 62 */
87320c794b3Sgavinm 			uint32_t _Valid:1;			/* 63 */
87420c794b3Sgavinm 		} _mcimisc_hi;
87520c794b3Sgavinm 	} _fmt_f_revFG;
87620c794b3Sgavinm 	/*
87720c794b3Sgavinm 	 * MSR format in family 0x10 revisions A and B
87820c794b3Sgavinm 	 */
87920c794b3Sgavinm 	struct {
88020c794b3Sgavinm 		/*
88120c794b3Sgavinm 		 * Lower 32 bits
88220c794b3Sgavinm 		 */
88320c794b3Sgavinm 		struct {
88420c794b3Sgavinm 			uint32_t _reserved:24;			/* 23:0 */
88520c794b3Sgavinm 			uint32_t _BlkPtr:8;			/* 31:24 */
88620c794b3Sgavinm 		} _mcimisc_lo;
88720c794b3Sgavinm 		/*
88820c794b3Sgavinm 		 * Upper 32 bits
88920c794b3Sgavinm 		 */
89020c794b3Sgavinm 		struct {
89120c794b3Sgavinm 			uint32_t _ErrCnt:12;			/* 43:32 */
89220c794b3Sgavinm 			uint32_t _reserved1:4;			/* 47:44 */
89320c794b3Sgavinm 			uint32_t _Ovrflw:1;			/* 48 */
89420c794b3Sgavinm 			uint32_t _IntType:2;			/* 50:49 */
89520c794b3Sgavinm 			uint32_t _CntEn:1;			/* 51 */
89620c794b3Sgavinm 			uint32_t _LvtOff:4;			/* 55:52 */
89720c794b3Sgavinm 			uint32_t _reserved2:5;			/* 60:56 */
89820c794b3Sgavinm 			uint32_t _Locked:1;			/* 61 */
89920c794b3Sgavinm 			uint32_t _CntP:1;			/* 62 */
90020c794b3Sgavinm 			uint32_t _Valid:1;			/* 63 */
90120c794b3Sgavinm 
90220c794b3Sgavinm 		} _mcimisc_hi;
90320c794b3Sgavinm 	} _fmt_10_revAB;
90420c794b3Sgavinm };
90520c794b3Sgavinm 
90620c794b3Sgavinm #define	mcmisc_BlkPtr	_mcimisc_lo._BlkPtr
90720c794b3Sgavinm #define	mcmisc_ErrCount	_mcimisc_hi._ErrCount
90820c794b3Sgavinm #define	mcmisc_Ovrflw	_mcimisc_hi._Ovrflw
90920c794b3Sgavinm #define	mcmisc_IntType	_mcimisc_hi._IntType
91020c794b3Sgavinm #define	mcmisc_CntEn	_mcimisc_hi._CntEn
91120c794b3Sgavinm #define	mcmisc_LvtOff	_mcimisc_hi._LvtOff
91220c794b3Sgavinm #define	mcmisc_Locked	_mcimisc_hi._Locked
91320c794b3Sgavinm #define	mcmisc_CntP	_mcimisc_hi._CntP
91420c794b3Sgavinm #define	mcmisc_Valid	_mcimisc_hi._Valid
91520c794b3Sgavinm 
91620c794b3Sgavinm #endif /* _BIT_FIELDS_LTOH */
91720c794b3Sgavinm 
9187aec1d6eScindi #ifdef __cplusplus
9197aec1d6eScindi }
9207aec1d6eScindi #endif
9217aec1d6eScindi 
9227aec1d6eScindi #endif /* _MC_AMD_H */
923