--- onnv-129.orig/usr/src/common/mc/mc-amd/mcamd_api.h	Tue Dec  1 09:41:36 2009
+++ onnv-129/usr/src/common/mc/mc-amd/mcamd_api.h	Wed Mar 16 22:59:56 2011
@@ -96,8 +96,12 @@
 #define	MCAMD_PROPSTR_DRAMHOLE_SIZE	"dram-hole-size"
 	MCAMD_PROP_ACCESS_WIDTH,
 #define	MCAMD_PROPSTR_ACCESS_WIDTH	"access-width"
+	MCAMD_PROP_ACCESS_WIDTH1,
+#define	MCAMD_PROPSTR_ACCESS_WIDTH1	"access-width1"
 	MCAMD_PROP_CSBANKMAPREG,
 #define	MCAMD_PROPSTR_CSBANKMAPREG	"bank-mapping"
+	MCAMD_PROP_CSBANKMAPREG1,
+#define	MCAMD_PROPSTR_CSBANKMAPREG1	"bank-mapping1"
 	MCAMD_PROP_BANKSWZL,
 #define	MCAMD_PROPSTR_BANKSWZL		"bankswizzle"
 	MCAMD_PROP_MOD64MUX,
@@ -104,8 +108,16 @@
 #define	MCAMD_PROPSTR_MOD64MUX		"mismatched-dimm-support"
 	MCAMD_PROP_SPARECS,
 #define	MCAMD_PROPSTR_SPARECS		"spare-csnum"
+	MCAMD_PROP_SPARECS1,
+#define	MCAMD_PROPSTR_SPARECS1		"spare-csnum1"
 	MCAMD_PROP_BADCS,
 #define	MCAMD_PROPSTR_BADCS		"bad-csnum"
+	MCAMD_PROP_BADCS1,
+#define	MCAMD_PROPSTR_BADCS1		"bad-csnum1"
+	MCAMD_PROP_GANGED,
+#define MCAMD_PROPSTR_GANGED	"ganged-mode"
+	MCAMD_PROP_DDR3,
+#define MCAMD_PROPSTR_DDR3		"ddr3-mode"
 	/*
 	 * Chip-select properties
 	 */
@@ -132,7 +144,11 @@
 	MCAMD_REG_DRAMCFGLO,
 	MCAMD_REG_DRAMCFGHI,
 	MCAMD_REG_CSBASE,
-	MCAMD_REG_CSMASK
+	MCAMD_REG_CSMASK,
+	MCAMD_REG_DRAMCFGLO1, /* since 0x10 */
+	MCAMD_REG_DRAMCFGHI1, /* since 0x10 */
+	MCAMD_REG_SELECTLO, /* since 0x10 */
+	MCAMD_REG_SELECTHI /* since 0x10 */
 } mcamd_regcode_t;
 /*
  * Flags for mcamd_dprintf
--- onnv-129.orig/usr/src/uts/intel/sys/mca_amd.h	Tue Dec  1 09:42:08 2009
+++ onnv-129/usr/src/uts/intel/sys/mca_amd.h	Fri Mar  4 21:31:29 2011
@@ -88,7 +88,7 @@
 
 /*
  * Data Cache (DC) bank error-detection enabling bits and CTL register
- * initializer value.
+ * initializer value. (MC0_CTL)
  */
 
 #define	AMD_DC_EN_ECCI			0x00000001ULL
@@ -105,7 +105,7 @@
 
 /*
  * Instruction Cache (IC) bank error-detection enabling bits and CTL register
- * initializer value.
+ * initializer value. (MC1_CTL)
  *
  * The Northbridge will handle Read Data errors.  Our initializer will enable
  * all but the RDDE detector.
@@ -126,7 +126,7 @@
 
 /*
  * Bus Unit (BU) bank error-detection enabling bits and CTL register
- * initializer value.
+ * initializer value. (MC2_CTL)
  *
  * The Northbridge will handle Read Data errors.  Our initializer will enable
  * all but the S_RDE_* detectors.
@@ -135,6 +135,7 @@
 #define	AMD_BU_EN_S_RDE_HP		0x00000001ULL
 #define	AMD_BU_EN_S_RDE_TLB		0x00000002ULL
 #define	AMD_BU_EN_S_RDE_ALL		0x00000004ULL
+/* <= 0Fh, only */
 #define	AMD_BU_EN_S_ECC1_TLB		0x00000008ULL
 #define	AMD_BU_EN_S_ECC1_HP		0x00000010ULL
 #define	AMD_BU_EN_S_ECCM_TLB		0x00000020ULL
@@ -152,7 +153,19 @@
 #define	AMD_BU_EN_L2D_ECCM_CPB		0x00020000ULL
 #define	AMD_BU_EN_L2T_ECC1_SCR		0x00040000ULL
 #define	AMD_BU_EN_L2T_ECCM_SCR		0x00080000ULL
+/* since 10h */
+#define AMD_BU_EN_10_L2T_PAR	0x00000008ULL
+#define AMD_BU_EN_10_L2T_CECC	0x00000010ULL
+#define AMD_BU_EN_10_L2T_UECC	0x00000020ULL
+#define AMD_BU_EN_10_L2D_PAR	0x00000040ULL
+#define AMD_BU_EN_10_L2D_CECC	0x00000080ULL
+#define AMD_BU_EN_10_L2D_UECC	0x00000100ULL
+#define AMD_BU_EN_10_UNUSED		0x00000200ULL
+#define AMD_BU_EN_10_VB_PAR		0x00000400ULL
+#define AMD_BU_EN_10_PDC_PAR	0x00000800ULL
+#define AMD_BU_EN_10_UNUSED_RO	~(0xfffULL)
 
+/* covers all 10h, but also writes to RO bits ... */
 #define	AMD_BU_CTL_INIT_CMN \
 	(AMD_BU_EN_S_ECC1_TLB | AMD_BU_EN_S_ECC1_HP | \
 	AMD_BU_EN_S_ECCM_TLB | AMD_BU_EN_S_ECCM_HP | \
@@ -166,7 +179,7 @@
 
 /*
  * Load/Store (LS) bank error-detection enabling bits and CTL register
- * initializer value.
+ * initializer value. (MC3_CTL)
  *
  * The Northbridge will handle Read Data errors.  That's the only type of
  * error the LS unit can detect at present, so we won't be enabling any
@@ -179,11 +192,14 @@
 #define	AMD_LS_CTL_INIT_CMN			0ULL
 
 /*
- * NorthBridge (NB) MCi_MISC - DRAM Errors Threshold Register.
+ * NorthBridge (NB) MC4_MISC0 - DRAM Errors Threshold Register. 
+ * (MSR0000_0413[63:32] aka F3x160[31:0])
  */
 #define	AMD_NB_MISC_VALID		(0x1ULL << 63)
 #define	AMD_NB_MISC_CTRP		(0x1ULL << 62)
 #define	AMD_NB_MISC_LOCKED		(0x1ULL << 61)
+#define AMD_NB_MISC_LVTOFFSET	(0x1ULL << 52)
+#define AMD_NB_MISC_LVTOFFSET_MASK (0xfULL << 52) /* @since family 0x10 */
 #define	AMD_NB_MISC_CNTEN		(0x1ULL << 51)
 #define	AMD_NB_MISC_INTTYPE		(0x1ULL << 49)
 #define	AMD_NB_MISC_INTTYPE_MASK	(0x3ULL << 49)
@@ -199,8 +215,8 @@
  * The CTL register can be initialized statically, but portions of the NB CFG
  * register must be initialized based on the current machine's configuration.
  *
- * The MCA NB Control Register maps to MC4_CTL[31:0], but we initialize it
- * via and MSR write of 64 bits so define all as ULL.
+ * The MCA NB Control Register maps to MC4_CTL[31:0] aka F3x40[31:0], but we
+ * initialize it via and MSR write of 64 bits so define all as ULL.
  *
  */
 #define	AMD_NB_EN_CORRECC		0x00000001ULL
@@ -216,7 +232,21 @@
 #define	AMD_NB_EN_GARTTBLWK		0x00000400ULL
 #define	AMD_NB_EN_ATOMICRMW		0x00000800ULL
 #define	AMD_NB_EN_WCHDOGTMR		0x00001000ULL
+#define AMD_NB_EN_DEVERR		0x00002000ULL	/* since family 0x10 */
+#define AMD_NB_EN_L3ARRAYCOR	0x00004000ULL	/* since family 0x10 */
+#define AMD_NB_EN_L3ARRAYUC		0x00008000ULL	/* since family 0x10 */
+#define	AMD_NB_EN_PROT			0x00010000ULL	/* since family 0x10 */
+#define	AMD_NB_EN_HTDATA		0x00020000ULL	/* since family 0x10 */
 #define	AMD_NB_EN_DRAMPAR		0x00040000ULL	/* revs F and G */
+#define AMD_NB_EN_RTRYHT0		0x00080000ULL	/* since family 0x10 */
+#define AMD_NB_EN_RTRYHT1		0x00100000ULL	/* since family 0x10 */
+#define AMD_NB_EN_RTRYHT2		0x00200000ULL	/* since family 0x10 */
+#define AMD_NB_EN_RTRYHT3		0x00400000ULL	/* since family 0x10 */
+#define AMD_NB_EN_CRCERR3		0x00800000ULL	/* since family 0x10 */
+#define AMD_NB_EN_SYNCPKT3		0x01000000ULL	/* since family 0x10 */
+#define AMD_NB_EN_MCAUSPWDATERR	0x02000000ULL	/* since family 0x10 */
+#define AMD_NB_EN_NBARRAYPAR	0x04000000ULL	/* since family 0x10 */
+#define AMD_NB_EN_TBLWLKDATERR	0x08000000ULL	/* since family 0x10 */
 
 #define	AMD_NB_CTL_INIT_CMN /* Revs B to G; All but GARTTBLWK */ \
 	(AMD_NB_EN_CORRECC | AMD_NB_EN_UNCORRECC | \
@@ -229,9 +259,9 @@
 	AMD_NB_EN_DRAMPAR
 
 /*
- * NB MCA Configuration register
+ * NB MCA Configuration register (F3x44[31:0])
  */
-#define	AMD_NB_CFG_CPUECCERREN			0x00000001
+#define	AMD_NB_CFG_CPUECCERREN		0x00000001 /* reserved since family 0x10 */
 #define	AMD_NB_CFG_CPURDDATERREN		0x00000002
 #define	AMD_NB_CFG_SYNCONUCECCEN		0x00000004
 #define	AMD_NB_CFG_SYNCPKTGENDIS		0x00000008
@@ -246,10 +276,12 @@
 #define	AMD_NB_CFG_CHIPKILLECCEN		0x00800000
 #define	AMD_NB_CFG_IORDDATERREN			0x01000000
 #define	AMD_NB_CFG_DISPCICFGCPUERRRSP		0x02000000
+#define AMD_NB_CFG_CORRMCAEXC			0x04000000		/* since family 0x10 */
 #define	AMD_NB_CFG_NBMCATOMSTCPUEN		0x08000000
 #define	AMD_NB_CFG_DISTGTABTCPUERRRSP		0x10000000
 #define	AMD_NB_CFG_DISMSTABTCPUERRRSP		0x20000000
 #define	AMD_NB_CFG_SYNCONDRAMADRPARERREN	0x40000000 /* Revs F & G */
+#define AMD_NB_CFG_NBMCALOGEN			0x80000000	/* since family 0x10 */
 
 /*
  * We do not initialize the NB config with an absolute value; instead we
@@ -274,6 +306,7 @@
 
 #define	AMD_NB_CFG_REMOVE_REV_FG 0x0	/* Revs F and G */
 
+/* WDTCntSel[11:9] values */
 #define	AMD_NB_CFG_WDOGTMRCNTSEL_4095	0x00000000
 #define	AMD_NB_CFG_WDOGTMRCNTSEL_2047	0x00000200
 #define	AMD_NB_CFG_WDOGTMRCNTSEL_1023	0x00000400
@@ -285,6 +318,7 @@
 #define	AMD_NB_CFG_WDOGTMRCNTSEL_MASK	0x00000e00
 #define	AMD_NB_CFG_WDOGTMRCNTSEL_SHIFT	9
 
+/* WDTBaseSel[13:12] values */
 #define	AMD_NB_CFG_WDOGTMRBASESEL_1MS	0x00000000
 #define	AMD_NB_CFG_WDOGTMRBASESEL_1US	0x00001000
 #define	AMD_NB_CFG_WDOGTMRBASESEL_5NS	0x00002000
@@ -291,9 +325,11 @@
 #define	AMD_NB_CFG_WDOGTMRBASESEL_MASK	0x00003000
 #define	AMD_NB_CFG_WDOGTMRBASESEL_SHIFT	12
 
+/* LdtLinkSel[15:14] values */
 #define	AMD_NB_CFG_LDTLINKSEL_MASK	0x0000c000
 #define	AMD_NB_CFG_LDTLINKSEL_SHIFT	14
 
+/* GenCrcErrByte bits [17:16] */
 #define	AMD_NB_CFG_GENCRCERRBYTE0	0x00010000
 #define	AMD_NB_CFG_GENCRCERRBYTE1	0x00020000
 
@@ -301,7 +337,7 @@
  * The AMD extended error code is just one nibble of the upper 16 bits
  * of the bank status (the resy being used for syndrome etc).  So we use
  * AMD_EXT_ERRCODE to retrieve that extended error code, not the generic
- * MCAX86_MSERRCODE.
+ * MCAX86_MSERRCODE via MC4_STATUS. (F3x4C[22:13,9:0] F3x48[20:16])
  */
 #define	_AMD_ERREXT_MASK		0x00000000000f0000ULL
 #define	_AMD_ERREXT_SHIFT		16
@@ -344,6 +380,7 @@
 #define	AMD_ERREXT_MASK			0x00000000000f0000ULL
 #define	AMD_ERREXT_SHIFT		16
 
+/* see F3x48[15:0] */
 #define	AMD_ERRCODE_TLB_BIT		4
 #define	AMD_ERRCODE_MEM_BIT		8
 #define	AMD_ERRCODE_BUS_BIT		11
@@ -362,12 +399,17 @@
 	MCAX86_MKERRCODE_BUS_INTERCONNECT(pp, t, r4, ii, ll)
 #define	AMD_ERRCODE_ISBUS(code) MCAX86_ERRCODE_ISBUS_INTERCONNECT(code)
 
-#define	AMD_NB_ADDRLO_MASK		0xfffffff8
+/* F3x50, F3x54 */
+#define	AMD_NB_ADDRLO_MASK		0xfffffff8	/* all 0x0f */
 #define	AMD_NB_ADDRHI_MASK		0x000000ff
 
+#define	AMD_NB_10_ADDRLO_MASK		0xfffffffe /* all 0x10 */
+#define	AMD_NB_10_ADDRHI_MASK		0x0000ffff
+
 #define	AMD_SYNDTYPE_ECC		0
 #define	AMD_SYNDTYPE_CHIPKILL		1
 
+/* F3x58 */
 #define	AMD_NB_SCRUBCTL_DRAM_MASK	0x0000001f
 #define	AMD_NB_SCRUBCTL_DRAM_SHIFT	0
 #define	AMD_NB_SCRUBCTL_L2_MASK		0x00001f00
@@ -380,10 +422,11 @@
 #define	AMD_NB_SCRUBCTL_RATE_NONE	0
 #define	AMD_NB_SCRUBCTL_RATE_MAX	0x16
 
+/* F3x5C, F3x60 */
 #define	AMD_NB_SCRUBADDR_LO_MASK	0xffffffc0
 #define	AMD_NB_SCRUBADDR_LO_SHIFT	6
 #define	AMD_NB_SCRUBADDR_LO_SCRUBREDIREN 0x1
-#define	AMD_NB_SCRUBADDR_HI_MASK	0x000000ff
+#define	AMD_NB_SCRUBADDR_HI_MASK	0x0000ffff	/* since 0x10 16 instead of 8 */
 
 #define	AMD_NB_SCRUBADDR_MKLO(addr) \
 	(((addr) & AMD_NB_SCRUBADDR_LO_MASK) >> AMD_NB_SCRUBADDR_LO_SHIFT)
--- onnv-129.orig/usr/src/uts/intel/sys/mc_amd.h	Tue Dec  1 09:42:08 2009
+++ onnv-129/usr/src/uts/intel/sys/mc_amd.h	Mon Mar 14 20:43:19 2011
@@ -59,7 +59,8 @@
  * num			uint64		Chip id of this memory controller
  * revision		uint64		cpuid_getchiprev() result
  * revname		string		cpuid_getchiprevstr() result
- * socket		string		"Socket 755|939|940|AM2|F(1207)|S1g1"
+ * socket				string		"Socket 754|939|940, AM2|ASB1|F(1207)|S1g1,
+ * 										S1g2, S1g3|AM2r2|AM3|ABS2|C32|G34, FT1"
  * ecc-type		string		"ChipKill 128/16" or "Normal 64/8"
  * base-addr		uint64		Node base address
  * lim-addr		uint64		Node limit address
@@ -69,12 +70,16 @@
  * dram-hole-size	uint64		size in bytes from dram hole addr reg
  * access-width		uint64		MC mode, 64 or 128 bit
  * bank-mapping		uint64		Raw DRAM Bank Address Mapping Register
+ * bank-mapping1		uint64		Raw DRAM Bank Address Mapping Register DCT 1
  * bankswizzle		uint64		1 if bank swizzling enabled; else 0
  * mismatched-dimm-support uint64	1 if active; else 0
  * [spare-csnum]	uint64		Chip-select pair number of any spare
  * [bad-csnum]		uint64		Chip-select pair number of swapped cs
+ * [bad-csnum1]			uint64		Chip-select pair number of swapped cs DCT 1
  * cslist		nvlist array	See below; may have 0 members
  * dimmlist		nvlist array	See below; may have 0 members
+ * ganged-mode			uint64		1 if DCTs are in ganged mode, 0 otherwise.
+ * ddr3-mode			uint64		1 if DDR3, 0 if DDR2 DIMMs are in use.
  *
  * cslist is an array of nvlist, each as follows:
  *
@@ -164,8 +169,10 @@
  */
 #define	MC_HT_REG_RTBL_NODE_0	0x40
 #define	MC_HT_REG_RTBL_INCR	4
-#define	MC_HT_REG_NODEID	0x60
-#define	MC_HT_REG_UNITID	0x64
+#define	MC_HT_REG_NODEID	0x60	/* Node 0 */
+#define	MC_HT_REG_NODEID1	0x160	/* Node 1 */
+#define	MC_HT_REG_UNITID	0x64	/* Node 0 */
+#define	MC_HT_REG_UNITID1	0x164	/* Node 1 */
 
 /*
  * Function 1 (address map) offsets for DRAM base, DRAM limit, DRAM hole
@@ -172,8 +179,10 @@
  * registers.
  */
 #define	MC_AM_REG_DRAMBASE_0	0x40	/* Offset for DRAM Base 0 */
+#define	MC_AM_REG_DRAMBASE_HI_0	0x140	/* Offset for DRAM Base High 0 */
 #define	MC_AM_REG_DRAMLIM_0	0x44	/* Offset for DRAM Limit 0 */
-#define	MC_AM_REG_DRAM_INCR	8	/* incr between base/limit pairs */
+#define	MC_AM_REG_DRAMLIM_HI_0	0x144	/* Offset for DRAM Limit High 0 */
+#define	MC_AM_REG_DRAM_INCR		8	/* incr. between base/limit pairs rev BCDE */
 #define	MC_AM_REG_HOLEADDR	0xf0	/* DRAM Hole Address Register */
 
 /*
@@ -182,11 +191,20 @@
  */
 #define	MC_DC_REG_CS_INCR	4	/* incr for CS base and mask */
 #define	MC_DC_REG_CSBASE_0	0x40	/* 0x40 - 0x5c */
+#define	MC_DC_REG_CSBASE1_0		0x140	/* 0x140 - 0x15c */
 #define	MC_DC_REG_CSMASK_0	0x60	/* 0x60 - 0x7c */
-#define	MC_DC_REG_BANKADDRMAP	0x80	/* DRAM Bank Address Mapping */
-#define	MC_DC_REG_DRAMCFGLO	0x90	/* DRAM Configuration Low */
-#define	MC_DC_REG_DRAMCFGHI	0x94	/* DRAM Configuration High */
-#define	MC_DC_REG_DRAMMISC	0xa0	/* DRAM Miscellaneous */
+#define	MC_DC_REG_CSMASK1_0		0x160	/* 0x160 - 0x17c */
+#define	MC_DC_REG_BANKADDRMAP	0x80	/* DRAM Bank Address Mapping DCT 0 */
+#define	MC_DC_REG_BANKADDRMAP1	0x180	/* DRAM Bank Address Mapping DCT 1 */
+#define	MC_DC_REG_DRAMCFGLO		0x90	/* DRAM Configuration Low DCT 0 */
+#define	MC_DC_REG_DRAMCFGLO1	0x190	/* DRAM Configuration Low DCT 1 */
+#define	MC_DC_REG_DRAMCFGHI		0x94	/* DRAM Configuration High DCT 0 */
+#define	MC_DC_REG_DRAMCFGHI1	0x194	/* DRAM Configuration High DCT 1 */
+#define	MC_DC_REG_DRAMMISC		0xa0	/* DRAM Miscellaneous DCT 0 */
+#define	MC_DC_REG_DRAMMISC1		0x1a0	/* DRAM Miscellaneous DCT 1 */
+#define MC_DC_REG_SWAPINTLV		0x10c	/* Swap Interleave Region Base/Limit */
+#define MC_DC_REG_SELECT_LO 	0x110	/* DRAM Controller Select Low Register */
+#define MC_DC_REG_SELECT_HI 	0x114	/* DRAM Controller Select High Register */
 
 /*
  * Function 3 (misc control) offset for NB MCA config, scrubber control,
@@ -199,8 +217,8 @@
 #define	MC_CTL_REG_SPARECTL	0xb0	/* On-line spare control register */
 #define	MC_CTL_REG_NBCAP	0xe8	/* NB Capabilities */
 
-#define	MC_NBCAP_L3CAPABLE	(1U << 25)
-#define	MC_NBCAP_MULTINODECPU	(1U << 29)
+#define	MC_NBCAP_L3CAPABLE	(1U << 25)		/* 10h and later */
+#define	MC_NBCAP_MULTINODECPU	(1U << 29)	/* 10h rev. D and later */
 
 /*
  * MC4_MISC MSR and MC4_MISCj MSRs
@@ -224,9 +242,13 @@
  * The bitfield structs are all named _fmt_xxx where xxx identifies the
  * processor revision to which it applies.  At this point the only xxx
  * values in use are:
- *			'cmn' - applies to all revisions
  *			'f_preF' - applies to revisions E and earlier
  *			'f_revFG' - applies to revisions F and G
+ *			'f_ALL' - applies to all revisions of the 0Fh family
+ *			'10_ALL' - applies to all revisions of the 10h family
+ *			'pre_11' - applies to all revisions before the 11h family
+ *			'11_ALL' - applies to all revisions of the 11h family
+ *			'14_ALL' - applies to all revisions of the 14h family
  *
  * Variants such as 'preD', 'revDE', 'postCG' etc should be introduced
  * as requirements arise.  The MC_REV_* and MC_REV_MATCH etc macros
@@ -249,7 +271,16 @@
 
 #define	MC_10_REV_A	X86_CHIPREV_AMD_10_REV_A
 #define	MC_10_REV_B	X86_CHIPREV_AMD_10_REV_B
+#define	MC_10_REV_C2	X86_CHIPREV_AMD_10_REV_C2
+#define	MC_10_REV_C3	X86_CHIPREV_AMD_10_REV_C3
+#define	MC_10_REV_D0	X86_CHIPREV_AMD_10_REV_D0
+#define	MC_10_REV_D1	X86_CHIPREV_AMD_10_REV_D1
+#define	MC_10_REV_E	X86_CHIPREV_AMD_10_REV_E
 
+#define	MC_11_REV_B	X86_CHIPREV_AMD_11_REV_B
+
+#define	MC_14_REV_B	X86_CHIPREV_AMD_14_REV_B
+
 /*
  * The most common groupings for memory controller features.
  */
@@ -257,8 +288,12 @@
 #define	MC_F_REVS_DE	(MC_F_REV_D | MC_F_REV_E)
 #define	MC_F_REVS_BCDE	(MC_F_REVS_BC | MC_F_REVS_DE)
 #define	MC_F_REVS_FG	(MC_F_REV_F | MC_F_REV_G)
+#define MC_F_ALL (MC_F_REVS_BCDE | MC_F_REVS_FG )
 
-#define	MC_10_REVS_AB	(MC_10_REV_A | MC_10_REV_B)
+#define	MC_10_ALL (MC_10_REV_A | MC_10_REV_B | MC_10_REV_C2 | MC_10_REV_C3 \
+	| MC_10_REV_D0 | MC_10_REV_D1 | MC_10_REV_E)
+#define MC_11_ALL MC_11_REV_B
+#define MC_14_ALL MC_14_REV_B
 
 /*
  * Is 'rev' included in the 'revmask' bitmask?
@@ -275,11 +310,6 @@
 #define	MCREG_VAL32(up) ((up)->_val32)
 
 /*
- * Access a field that has the same structure in all families and revisions
- */
-#define	MCREG_FIELD_CMN(up, field)	_MCREG_FIELD(up, cmn, field)
-
-/*
  * Access a field as defined for family 0xf prior to revision F
  */
 #define	MCREG_FIELD_F_preF(up, field)	_MCREG_FIELD(up, f_preF, field)
@@ -290,11 +320,36 @@
 #define	MCREG_FIELD_F_revFG(up, field)	_MCREG_FIELD(up, f_revFG, field)
 
 /*
- * Access a field as defined for family 0x10 revisions A and
+ * Access a field as defined for family 0xf prior to revision F
  */
-#define	MCREG_FIELD_10_revAB(up, field)	_MCREG_FIELD(up, 10_revAB, field)
+#define	MCREG_FIELD_F_ALL(up, field)	_MCREG_FIELD(up, f_ALL, field)
 
 /*
+ * Access a field as defined for family 0x10
+ */
+#define	MCREG_FIELD_10_ALL(up, field)	_MCREG_FIELD(up, 10_ALL, field)
+
+/*
+ * Access a field as defined for family 0x10 after revision C2
+ */
+#define	MCREG_FIELD_10_postC2(up, field)	_MCREG_FIELD(up, 10_postC2, field)
+
+/*
+ * Access a field as defined for families < 0x11
+ */
+#define	MCREG_FIELD_PRE_11(up, field)	_MCREG_FIELD(up, pre_11, field)
+
+/*
+ * Access a field as defined for family 0x11
+ */
+#define	MCREG_FIELD_11_ALL(up, field)	_MCREG_FIELD(up, 11_ALL, field)
+
+/*
+ * Access a field as defined for family 0x14
+ */
+#define	MCREG_FIELD_14_ALL(up, field)	_MCREG_FIELD(up, 14_ALL, field)
+
+/*
  * We will only define the register bitfields for little-endian order
  */
 #ifdef	_BIT_FIELDS_LTOH
@@ -301,6 +356,7 @@
 
 /*
  * Function 0 - HT Configuration: Routing Table Node Register
+ * F0x[5C:40]
  */
 union mcreg_htroute {
 	uint32_t	_val32;
@@ -311,33 +367,66 @@
 		uint32_t	reserved2:4;	/* 15:12 */
 		uint32_t	BCRte:4;	/* 19:16 */
 		uint32_t	reserved3:12;	/* 31:20 */
-	} _fmt_cmn;
+	} _fmt_f_ALL;
+	struct {
+		uint32_t	RQRte:9;	/*  8:0 */
+		uint32_t	RPRte:9;	/* 17:9 */
+		uint32_t	BCRte:9;	/* 26:18 */
+		uint32_t	reserved1:5;	/* 31:27 */
+	} _fmt_10_ALL;
+	struct {
+		uint32_t	reserved;	/* n/a */
+	} _fmt_11_ALL;
+	struct {
+		uint32_t	reserved;	/* n/a */
+	} _fmt_14_ALL;
 };
 
 /*
  * Function 0 - HT Configuration: Node ID Register
+ * F0x60
  */
 union mcreg_nodeid {
 	uint32_t	_val32;
 	struct {
 		uint32_t	NodeId:3;	/*  2:0 */
-		uint32_t	reserved1:1;	/*  3:3 */
+		uint32_t	reserved1:1;	/*  3 */
 		uint32_t	NodeCnt:3;	/*  6:4 */
-		uint32_t	reserved2:1;	/*  7:7 */
+		uint32_t	reserved2:1;	/*  7 */
 		uint32_t	SbNode:3;	/* 10:8 */
-		uint32_t	reserved3:1;	/* 11:11 */
+		uint32_t	reserved3:1;	/* 11 */
 		uint32_t	LkNode:3;	/* 14:12 */
-		uint32_t	reserved4:1;	/* 15:15 */
-		uint32_t	CpuCnt:4;	/* 19:16 */
-		uint32_t	reserved:12;	/* 31:20 */
-	} _fmt_cmn;
+		uint32_t	reserved4:1;	/* 15 */
+		uint32_t	CpuCnt:5;	/* 20:16 */
+		uint32_t	reserved:11;	/* 31:21 */
+	} _fmt_pre_11;
+	struct {
+		uint32_t	NodeId:3;	/*  2:0 */
+		uint32_t	reserved1:1;	/*  3 */
+		uint32_t	NodeCnt:3;	/*  6:4 */
+		uint32_t	reserved2:25;	/* 31:7 */
+	} _fmt_11_ALL;
+	struct {
+		uint32_t	reserved;	/* n/a */
+	} _fmt_14_ALL;
 };
 
-#define	HT_COHERENTNODES(up)	(MCREG_FIELD_CMN(up, NodeCnt) + 1)
-#define	HT_SYSTEMCORECOUNT(up)	(MCREG_FIELD_CMN(up, CpuCnt) + 1)
+/*
+ * Function 0 - HT Configuration: Node1 ID Register
+ * F0x160
+ */
+union mcreg_nodeid1 {
+	uint32_t	_val32;
+	struct {
+		uint32_t	reserved1:16;	/* 15:0 */
+		uint32_t	CpuCount:3;		/* 18:16 */
+		uint32_t	reserved2:13;	/* 31:19 */
+	} _fmt_10_ALL;
+};
 
 /*
  * Function 0 - HT Configuration: Unit ID Register
+ * F0x64
  */
 union mcreg_unitid {
 	uint32_t	_val32;
@@ -347,70 +436,169 @@
 		uint32_t	McUnit:2;	/*  5:4 */
 		uint32_t	HbUnit:2;	/*  7:6 */
 		uint32_t	SbLink:2;	/*  9:8 */
-		uint32_t	reserved:22;	/* 31:10 */
-	} _fmt_cmn;
+		uint32_t	SubLink:1;	/*  10 */
+		uint32_t	reserved:22;	/* 31:11 */
+	} _fmt_f_ALL;
+	struct {
+		uint32_t	CpuUnit:2;	/*  1:0 */
+		uint32_t	reserved:2;	/*  3:2 */
+		uint32_t	McUnit:2;	/*  5:4 */
+		uint32_t	HbUnit:2;	/*  7:6 */
+		uint32_t	SbLink:2;	/*  9:8 */
+		uint32_t	SubLink:1;	/*  10 */
+		uint32_t	reserved:22;	/* 31:11 */
+	} _fmt_10_ALL;
+	struct {
+		uint32_t	reserved1:8;	/* 7:0 */
+		uint32_t	SbLink:3;		/* 10:8 */
+		uint32_t	reserved:21;	/* 31:11 */
+	} _fmt_11_ALL;
+	struct {
+		uint32_t	reserved;	/* n/a */
+	} _fmt_14_ALL;
 };
 
 /*
- * Function 1 - DRAM Address Map: DRAM Base i Registers
- *
+ * Function 1 - DRAM Address Map: DRAM Base Registers
+ * F1x[78, 70, 68, 60, 58, 50, 48, 40] - 0Fh, 10h
+ * F1x[40] - 11h, 14h
  */
-
 union mcreg_drambase {
 	uint32_t	_val32;
 	struct {
-		uint32_t	RE:1;		/*  0:0  - Read Enable */
-		uint32_t	WE:1;		/*  1:1  - Write Enable */
+		uint32_t	RE:1;			/* 0  - Read Enable */
+		uint32_t	WE:1;			/* 1  - Write Enable */
 		uint32_t	reserved1:6;	/*  7:2 */
-		uint32_t	IntlvEn:3;	/* 10:8  - Interleave Enable */
+		uint32_t	IntlvEn:3;		/* 10:8  - Node Interleave Enable */
 		uint32_t	reserved2:5;	/* 15:11 */
-		uint32_t	DRAMBasei:16;	/* 31:16 - Base Addr 39:24 */
-	} _fmt_cmn;
+		uint32_t	DRAMBase:16;	/* 31:16 - Base Addr 39:24 */
+	} _fmt_pre_11;
+	struct {
+		uint32_t	RE:1;			/* 0  - Read Enable */
+		uint32_t	WE:1;			/* 1  - Write Enable */
+		uint32_t	reserved1:14;	/* 15:2 */
+		uint32_t	DRAMBase:16;	/* 31:16 - Base Addr 39:24 */
+	} _fmt_11_ALL;
+	struct {
+		uint32_t	RE:1;			/* 0  - Read Enable */
+		uint32_t	WE:1;			/* 1  - Write Enable */
+		uint32_t	reserved1:14;	/* 15:2 */
+		uint32_t	DRAMBase:12;	/* 27:16 - Base Addr 35:24 */
+		uint32_t	reserved2:4;	/* 31:28 */
+	} _fmt_14_ALL;
 };
 
-#define	MC_DRAMBASE(up)	((uint64_t)MCREG_FIELD_CMN(up, DRAMBasei) << 24)
-
 /*
- * Function 1 - DRAM Address Map: DRAM Limit i Registers
- *
+ * Function 1 - DRAM Address Map: DRAM Base High Registers
+ * F1x1[78, 70, 68, 60, 58, 50, 48, 40] - 10h
  */
+union mcreg_drambase_hi {
+	uint32_t	_val32;
+	struct {
+		uint32_t	DRAMBase:8;	/* 7:0 - Limit Addr 47:40 */
+		uint32_t	reserved1:16;	/* 31:8 */
+	} _fmt_10_ALL;
+};
 
+#define	MC_DRAMBASE(up, upHi, rev)	(MC_REV_MATCH(rev, MC_14_ALL) \
+	? ((uint64_t)MCREG_FIELD_14_ALL((up), DRAMBase) << 24) \
+	: ((MC_REV_MATCH(rev, MC_10_ALL) \
+			? ((uint64_t)MCREG_FIELD_10_ALL((upHi), DRAMBase) << 40) : 0) \
+		| ((uint64_t)MCREG_FIELD_11_ALL((up), DRAMBase) << 24)) \
+	)
+
+/*
+ * Function 1 - DRAM Address Map: DRAM Limit Registers
+ * F1x[7C, 74, 6C, 64, 5C, 54, 4C, 44] - 0Fh, 10h
+ * F1x[44] - 11h, 14h
+ */
 union mcreg_dramlimit {
 	uint32_t	_val32;
 	struct {
 		uint32_t	DstNode:3;	/*  2:0  - Destination Node */
 		uint32_t	reserved1:5;	/*  7:3 */
-		uint32_t	IntlvSel:3;	/* 10:8  - Interleave Select */
+		uint32_t	IntlvSel:3;	/* 10:8  - Node Interleave Select */
 		uint32_t	reserved2:5;	/* 15:11 */
-		uint32_t	DRAMLimiti:16;	/* 31:16 - Limit Addr 39:24 */
-	} _fmt_cmn;
+		uint32_t	DRAMLimit:16;	/* 31:16 - Limit Addr 39:24 */
+	} _fmt_pre_11;
+	struct {
+		uint32_t	reserved1:16;	/*  0:15 */
+		uint32_t	DRAMLimit:16;	/* 31:16 - Limit Addr 39:24 */
+	} _fmt_11_ALL;
+	struct {
+		uint32_t	reserved1:16;	/*  0:15 */
+		uint32_t	DRAMLimit:12;	/* 27:16 - Limit Addr 35:24 */
+		uint32_t	reserved2:4;	/* 31:28 */
+	} _fmt_14_ALL;
 };
 
-#define	MC_DRAMLIM(up) \
-	((uint64_t)MCREG_FIELD_CMN(up, DRAMLimiti) << 24 |		\
-	(MCREG_FIELD_CMN(up, DRAMLimiti) ?  ((1 << 24) - 1) : 0))
+/*
+ * Function 1 - DRAM Address Map: DRAM Limit Address High Registers - 10h only
+ * F1x1[7C, 74, 6C, 64, 5C, 54, 4C, 44]
+ */
+union mcreg_dramlimit_hi {
+	uint32_t	_val32;
+	struct {
+		uint32_t	DRAMLimit:8;	/* 7:0 - Limit Addr 47:40 */
+		uint32_t	reserved1:16;	/* 31:8 */
+	} _fmt_10_ALL;
+};
 
+/* NOTE: BKDG says ... '| 0xff' but we '| 0xffffff' - which one is right ? */
+#define	MC_DRAMLIM(up, upHi, rev) (MC_REV_MATCH(rev, MC_14_ALL) \
+	? ((uint64_t)MCREG_FIELD_14_ALL(up, DRAMLimit) << 24 |		\
+		(MCREG_FIELD_14_ALL(up, DRAMLimit) ?  ((1 << 24) - 1) : 0)) \
+	: ((MC_REV_MATCH(rev, MC_10_ALL) \
+			? ((uint64_t)MCREG_FIELD_10_ALL((upHi), DRAMLimit) << 40) : 0) \
+		| ((uint64_t)MCREG_FIELD_11_ALL(up, DRAMLimit) << 24) \
+		| (MCREG_FIELD_11_ALL(up, DRAMLimit) ?  ((1 << 24) - 1) : 0)) \
+	)
+
 /*
  * Function 1 - DRAM Address Map: DRAM Hole Address Register
+ * F1xF0
  */
-
 union mcreg_dramhole {
 	uint32_t	_val32;
 	struct {
-		uint32_t	DramHoleValid:1;	/*  0:0 */
+		uint32_t	DramHoleValid:1;	/*  0 */
 		uint32_t	reserved1:7;		/*  7:1 */
 		uint32_t	DramHoleOffset:8;	/* 15:8 */
 		uint32_t	reserved2:8;		/* 23:16 */
 		uint32_t	DramHoleBase:8;		/* 31:24 */
-	} _fmt_cmn;
+	} _fmt_f_ALL;
+	struct {
+		uint32_t	DramHoleValid:1;	/*  0 */
+		uint32_t	DramMemHoistValid:1;	/*  1 */
+		uint32_t	reserved1:5;		/*  6:2 */
+		uint32_t	DramHoleOffset:9;	/* 15:7 */
+		uint32_t	reserved2:8;		/* 23:16 */
+		uint32_t	DramHoleBase:8;		/* 31:24 */
+	} _fmt_10_ALL;
+	struct {
+		uint32_t	DramHoleValid:1;	/*  0 */
+		uint32_t	reserved1:6;		/*  6:1 */
+		uint32_t	DramHoleOffset:9;	/* 15:7 */
+		uint32_t	reserved2:8;		/* 23:16 */
+		uint32_t	DramHoleBase:8;		/* 31:24 */
+	} _fmt_11_ALL;
+	struct {
+		uint32_t	DramHoleValid:1;	/*  0 */
+		uint32_t	reserved1:6;		/*  6:1 */
+		uint32_t	DramHoleOffset:9;	/* 15:7 */
+		uint32_t	reserved2:8;		/* 23:16 */
+		uint32_t	DramHoleBase:8;		/* 31:24 */
+	} _fmt_14_ALL;
 };
 
-#define	MC_DRAMHOLE_SIZE(up) (MCREG_FIELD_CMN(up, DramHoleOffset) << 24)
+#define	MC_DRAMHOLE_SIZE(up, rev) (MC_REV_MATCH(rev, MC_F_ALL) ? \
+	(MCREG_FIELD_F_ALL(up, DramHoleOffset) << 24) : \
+	(MCREG_FIELD_10_ALL(up, DramHoleOffset) << 24))
 
 /*
  * Function 2 - DRAM Controller: DRAM CS Base Address Registers
+ * F2x[1, 0][5C:40]
  */
-
 union mcreg_csbase {
 	uint32_t	_val32;
 	/*
@@ -417,7 +605,7 @@
 	 * Register format in family 0xf revisions E and earlier
 	 */
 	struct {
-		uint32_t	CSEnable:1;	/*  0:0  - CS Bank Enable */
+		uint32_t	CSEnable:1;	/*  0  - CS Bank Enable */
 		uint32_t	reserved1:8;	/*  8:1 */
 		uint32_t	BaseAddrLo:7;	/* 15:9  - Base Addr 19:13 */
 		uint32_t	reserved2:5;	/* 20:16 */
@@ -427,9 +615,9 @@
 	 * Register format in family 0xf revisions F and G
 	 */
 	struct {
-		uint32_t	CSEnable:1;	/*  0:0  - CS Bank Enable */
-		uint32_t	Spare:1;	/*  1:1  - Spare Rank */
-		uint32_t	TestFail:1;	/*  2:2  - Memory Test Failed */
+		uint32_t	CSEnable:1;	/*  0  - CS Bank Enable */
+		uint32_t	Spare:1;	/*  1  - Spare Rank */
+		uint32_t	TestFail:1;	/*  2  - Memory Test Failed */
 		uint32_t	reserved1:2;	/*  4:3 */
 		uint32_t	BaseAddrLo:9;	/* 13:5  - Base Addr 21:13 */
 		uint32_t	reserved2:5;	/* 18:14 */
@@ -436,18 +624,64 @@
 		uint32_t	BaseAddrHi:10;	/* 28:19 - Base Addr 36:27 */
 		uint32_t	reserved3:3;	/* 31:39 */
 	} _fmt_f_revFG;
+	/*
+	 * Register format in family 0x10
+	 */
+	struct {
+		uint32_t	CSEnable:1;	/*  0  - CS Bank Enable */
+		uint32_t	Spare:1;	/*  1  - Spare Rank */
+		uint32_t	TestFail:1;	/*  2  - Memory Test Failed */
+		uint32_t	OnDimmMirror:1;	/*  3 */
+		uint32_t	reserved1:1;	/*  4 */
+		uint32_t	BaseAddrLo:9;	/* 13:5  - Base Addr 21:13 */
+		uint32_t	reserved2:5;	/* 18:14 */
+		uint32_t	BaseAddrHi:10;	/* 28:19 - Base Addr 36:27 */
+		uint32_t	reserved3:3;	/* 31:29 */
+	} _fmt_10_ALL;
+	/*
+	 * Register format in family 0x11
+	 */
+	struct {
+		uint32_t	CSEnable:1;	/*  0  - CS Bank Enable */
+		uint32_t	reserved:1;	/*  1  */
+		uint32_t	TestFail:1;	/*  2  - Memory Test Failed */
+		uint32_t	reserved1:2;	/*  4:3 */
+		uint32_t	BaseAddrLo:9;	/* 13:5  - Base Addr 21:13 */
+		uint32_t	reserved2:5;	/* 18:14 */
+		uint32_t	BaseAddrHi:10;	/* 28:19 - Base Addr 36:27 */
+		uint32_t	reserved3:3;	/* 31:29 */
+	} _fmt_11_ALL;
+	/*
+	 * Register format in family 0x14
+	 */
+	struct {
+		uint32_t	CSEnable:1;	/*  0  - CS Bank Enable */
+		uint32_t	reserved:1;	/*  1  */
+		uint32_t	TestFail:1;	/*  2  - Memory Test Failed */
+		uint32_t	OnDimmMirror:1;	/*  3 */
+		uint32_t	reserved1:1;	/*  4 */
+		uint32_t	BaseAddrLo:9;	/* 13:5  - Base Addr 21:13 */
+		uint32_t	reserved2:5;	/* 18:14 */
+		uint32_t	BaseAddrHi:9;	/* 27:19 - Base Addr 35:27 */
+		uint32_t	reserved3:4;	/* 31:28 */
+	} _fmt_14_ALL;
 };
 
-#define	MC_CSBASE(up, rev) (MC_REV_MATCH(rev, MC_F_REVS_FG) ?	\
-	(uint64_t)MCREG_FIELD_F_revFG(up, BaseAddrHi) << 27 |		\
-	(uint64_t)MCREG_FIELD_F_revFG(up, BaseAddrLo) << 13 :		\
-	(uint64_t)MCREG_FIELD_F_preF(up, BaseAddrHi) << 25 |		\
-	(uint64_t)MCREG_FIELD_F_preF(up, BaseAddrLo) << 13)
+#define	MC_CSBASE(up, rev) (MC_REV_MATCH(rev, MC_F_REVS_BCDE) \
+	? ((uint64_t)MCREG_FIELD_F_preF(up, BaseAddrHi) << 25 \
+		| (uint64_t)MCREG_FIELD_F_preF(up, BaseAddrLo) << 13) \
+	: (MC_REV_MATCH(rev, MC_14_ALL) \
+		? ((uint64_t)MCREG_FIELD_14_ALL(up, BaseAddrHi) << 27 \
+			| (uint64_t)MCREG_FIELD_14_ALL(up, BaseAddrLo) << 13) \
+		: ((uint64_t)MCREG_FIELD_F_revFG(up, BaseAddrHi) << 27 \
+			| (uint64_t)MCREG_FIELD_F_revFG(up, BaseAddrLo) << 13 \
+		)) \
+	)
 
 /*
  * Function 2 - DRAM Controller: DRAM CS Mask Registers
+ * F2x[1, 0][6C:60]
  */
-
 union mcreg_csmask {
 	uint32_t	_val32;
 	/*
@@ -461,7 +695,7 @@
 		uint32_t	reserved3:2;	/* 31:30 */
 	} _fmt_f_preF;
 	/*
-	 * Register format in family 0xf revisions F and G
+	 * Register format in family 0xf revisions F and G, family 0x10, 0x11
 	 */
 	struct {
 		uint32_t	reserved1:5;	/*  4:0 */
@@ -470,26 +704,52 @@
 		uint32_t	AddrMaskHi:10;	/* 28:19 - Addr Mask 36:27 */
 		uint32_t	reserved3:3;	/* 31:29 */
 	} _fmt_f_revFG;
+	/*
+	 * Register format in family 0x14
+	 */
+	struct {
+		uint32_t	reserved1:5;	/*  4:0 */
+		uint32_t	AddrMaskLo:9;	/* 13:5  - Addr Mask 21:13 */
+		uint32_t	reserved2:5;	/* 18:14 */
+		uint32_t	AddrMaskHi:9;	/* 27:19 - Addr Mask 35:27 */
+		uint32_t	reserved3:4;	/* 31:28 */
+	} _fmt_14_ALL;
 };
 
-#define	MC_CSMASKLO_LOBIT(rev) (MC_REV_MATCH(rev, MC_F_REVS_FG) ? 13 : 13)
-#define	MC_CSMASKLO_HIBIT(rev) (MC_REV_MATCH(rev, MC_F_REVS_FG) ? 21 : 19)
+#define	MC_CSMASKLO_LOBIT(rev) 13
+#define	MC_CSMASKLO_HIBIT(rev) \
+	(MC_REV_MATCH(rev, MC_F_REVS_BCDE) ? 19 : 21)
 
-#define	MC_CSMASKHI_LOBIT(rev) (MC_REV_MATCH(rev, MC_F_REVS_FG) ? 27 : 25)
-#define	MC_CSMASKHI_HIBIT(rev) (MC_REV_MATCH(rev, MC_F_REVS_FG) ? 36 : 33)
+#define	MC_CSMASKHI_LOBIT(rev) \
+	(MC_REV_MATCH(rev, MC_F_REVS_BCDE) ? 25 : 27)
+#define	MC_CSMASKHI_HIBIT(rev) \
+	(MC_REV_MATCH(rev, MC_F_REVS_BCDE) \
+		? 33 \
+		: (MC_REV_MATCH(rev, MC_14_ALL) ? 35 : 36 ) \
+	)
 
-#define	MC_CSMASK_UNMASKABLE(rev) (MC_REV_MATCH(rev, MC_F_REVS_FG) ? 0 : 2)
+#define	MC_CSMASK_UNMASKABLE(rev) \
+	(MC_REV_MATCH(rev, MC_F_REVS_BCDE) \
+		? 2 \
+		: (MC_REV_MATCH(rev, MC_14_ALL) ? 1 : 0))
 
-#define	MC_CSMASK(up, rev) (MC_REV_MATCH(rev, MC_F_REVS_FG) ? \
-	(uint64_t)MCREG_FIELD_F_revFG(up, AddrMaskHi) << 27 | \
-	(uint64_t)MCREG_FIELD_F_revFG(up, AddrMaskLo) << 13 | 0x7c01fff : \
-	(uint64_t)MCREG_FIELD_F_preF(up, AddrMaskHi) << 25 | \
-	(uint64_t)MCREG_FIELD_F_preF(up, AddrMaskLo) << 13 | 0x1f01fff)
+#define	MC_CSMASK(up, rev) (MC_REV_MATCH(rev, MC_F_REVS_BCDE) \
+	? ((uint64_t)MCREG_FIELD_F_preF(up, AddrMaskHi) << 25 \
+		| (uint64_t)MCREG_FIELD_F_preF(up, AddrMaskLo) << 13 | 0x1f01fff) \
+	: (MC_REV_MATCH(rev, MC_14_ALL) \
+		? ((uint64_t)MCREG_FIELD_14_ALL(up, AddrMaskHi) << 27 \
+			| (uint64_t)MCREG_FIELD_14_ALL(up, AddrMaskLo) << 13 \
+			| 0x7c01fff) \
+		: ((uint64_t)MCREG_FIELD_F_revFG(up, AddrMaskHi) << 27 \
+			| (uint64_t)MCREG_FIELD_F_revFG(up, AddrMaskLo) << 13 \
+			| 0x7c01fff) \
+		) \
+	)
 
 /*
  * Function 2 - DRAM Controller: DRAM Bank Address Mapping Registers
+ * F2x[1, 0]80
  */
-
 union mcreg_bankaddrmap {
 	uint32_t	_val32;
 	/*
@@ -505,7 +765,7 @@
 		uint32_t	reserved2:1;		/* 31:31 */
 	} _fmt_f_preF;
 	/*
-	 * Register format in family 0xf revisions F and G
+	 * Register format in family 0xf revisions F and G and family 0x10
 	 */
 	struct {
 		uint32_t	cs10:4;			/*  3:0  - CS1/0 */
@@ -515,6 +775,22 @@
 		uint32_t	reserved1:16;		/* 31:16 */
 	} _fmt_f_revFG;
 	/*
+	 * Register format in family 0x11
+	 */
+	struct {
+		uint32_t	cs10:4;			/*  3:0  - CS1/0 */
+		uint32_t	cs32:4;			/*  7:4  - CS3/2 */
+		uint32_t	reserved1:24;		/* 31:8 */
+	} _fmt_11_ALL;
+	/*
+	 * Register format in family 0x14
+	 */
+	struct {
+		uint32_t	cs10:4;			/*  3:0  - CS1/0 */
+		uint32_t	cs32:4;			/*  7:4  - CS3/2 */
+		uint32_t	reserved1:24;		/* 31:8 */
+	} _fmt_14_ALL;
+	/*
 	 * Accessing all mode encodings as one uint16
 	 */
 	struct {
@@ -530,9 +806,9 @@
     MC_DC_BAM_CSBANK_SHIFT * MC_CHIP_DIMMPAIR(csnum) & MC_DC_BAM_CSBANK_MASK)
 
 /*
- * Function 2 - DRAM Controller: DRAM Configuration Low and High
+ * Function 2 - DRAM Controller: DRAM Configuration Low
+ * F2x[1, 0]90
  */
-
 union mcreg_dramcfg_lo {
 	uint32_t _val32;
 	/*
@@ -588,31 +864,75 @@
 		uint32_t	DimmEccEn:1;		/* 19 */
 		uint32_t	reserved4:12;		/* 31:20 */
 	} _fmt_f_revFG;
-};
-
-/*
- * Function 2 - DRAM Controller: DRAM Controller Miscellaneous Data
+	/*
+	 * Register format in family 0x10
  */
-
-union mcreg_drammisc {
-	uint32_t _val32;
+	struct {
+		uint32_t	InitDram:1;		/* 0 */
+		uint32_t	ExitSelfRef:1;		/* 1 */
+		uint32_t	PllLockTime:2;		/* 3:2 */
+		uint32_t	DramTerm:2;		/* 5:4 */
+		uint32_t	DisDqsBar:1;		/* 6 */
+		uint32_t	DramDrvWeak:1;		/* 7 */
+		uint32_t	ParEn:1;		/* 8 */
+		uint32_t	SelRefRateEn:1;		/* 9 */
+		uint32_t	BurstLength32:1;	/* 10 */
+		uint32_t	Width128:1;		/* 11 */
+		uint32_t	x4DIMMs:4;		/* 15:12 */
+		uint32_t	UnBuffDimm:1;		/* 16 */
+		uint32_t	EnterSelfRef:1;		/* 17 */
+		uint32_t	PendRefPayback:1;		/* 18 */
+		uint32_t	DimmEccEn:1;		/* 19 */
+		uint32_t	DynPageCloseEn:1;		/* 20 */
+		uint32_t	IdleCycleLowLimit:2;	/* 21:22 */
+		uint32_t	ForceAutoPchg:1;		/* 23 */
+		uint32_t	reserved1:3;		/* 26:24 */
+		uint32_t	DisDllShutdownSR:1;		/* 27 @since DA-C */
+		uint32_t	reserved2:4;		/* 31:28 */
+	} _fmt_10_ALL;
 	/*
-	 * Register format in family 0xf revisions F and G
+	 * Register format in family 0x11
 	 */
 	struct {
-		uint32_t	reserved2:1;		/* 0 */
-		uint32_t	DisableJitter:1;	/* 1 */
-		uint32_t	RdWrQByp:2;		/* 3:2 */
-		uint32_t	Mod64Mux:1;		/* 4 */
-		uint32_t	DCC_EN:1;		/* 5 */
-		uint32_t	ILD_lmt:3;		/* 8:6 */
-		uint32_t	DramEnabled:1;		/* 9 */
-		uint32_t	PwrSavingsEn:1;		/* 10 */
-		uint32_t	reserved1:13;		/* 23:11 */
-		uint32_t	MemClkDis:8;		/* 31:24 */
-	} _fmt_f_revFG;
+		uint32_t	InitDram:1;		/* 0 */
+		uint32_t	ExitSelfRef:1;		/* 1 */
+		uint32_t	reserved1:2;		/* 3:2 */
+		uint32_t	DramTerm:2;		/* 5:4 */
+		uint32_t	reserved2:1;		/* 6 */
+		uint32_t	DramDrvWeak:1;		/* 7 */
+		uint32_t	reserved3:1;		/* 8 */
+		uint32_t	SelRefRateEn:1;		/* 9 */
+		uint32_t	BurstLength32:1;	/* 10 */
+		uint32_t	reserved4:9;		/* 19:11 */
+		uint32_t	DynPageCloseEn:1;		/* 20 */
+		uint32_t	IdleCycleLowLimit:2;	/* 21:22 */
+		uint32_t	ForceAutoPchg:1;		/* 23 */
+		uint32_t	reserved5:8;		/* 31:24 */
+	} _fmt_11_ALL;
+	/*
+	 * Register format in family 0x14
+	 */
+	struct {
+		uint32_t	reserved1:1;		/* 0 */
+		uint32_t	ExitSelfRef:1;		/* 1 */
+		uint32_t	reserved2:15;		/* 16:2 */
+		uint32_t	EnterSelfRef:1;		/* 17 */
+		uint32_t	reserved3:2;		/* 19:18 */
+		uint32_t	DynPageCloseEn:1;		/* 20 */
+		uint32_t	IdleCycleLowLimit:2;	/* 21:22 */
+		uint32_t	ForceAutoPchg:1;		/* 23 */
+		uint32_t	reserved4:1;		/* 24 */
+		uint32_t	EnDispAutoPrecharge:1;		/* 25 */
+		uint32_t	DbeSkidBufDis:1;		/* 26 */
+		uint32_t	DisDllShutdownSR:1;		/* 27 */
+		uint32_t	reserved5:4;		/* 31:28 */
+	} _fmt_14_ALL;
 };
 
+/*
+ * Function 2 - DRAM Controller: DRAM Configuration High
+ * F2x[1, 0]94
+ */
 union mcreg_dramcfg_hi {
 	uint32_t _val32;
 	/*
@@ -660,45 +980,322 @@
 		uint32_t	DcqBypassMax:4;		/* 27:24 */
 		uint32_t	FourActWindow:4;	/* 31:28 */
 	} _fmt_f_revFG;
+	/*
+	 * Register format in family 0x10
+	 */
+	struct {
+		uint32_t	MemClkFreq:3;		/* 2:0 */
+		uint32_t	MemClkFreqVal:1;	/* 3 */
+		uint32_t	reserved1:4;		/* 7:4 */
+		uint32_t	Ddr3Mode:1;			/* 8 */
+		uint32_t	LegacyBiosMode:1;	/* 9 */
+		uint32_t	ZqcsInterval:2;		/* 11:10 */
+		uint32_t	RDqsEn:1;			/* 12 */
+		uint32_t	DisSimulRdWr:1;		/* 13 */
+		uint32_t	DisDramInterface:1;	/* 14 */
+		uint32_t	PowerDownEn:1;		/* 15 */
+		uint32_t	PowerDownMode:1;	/* 16 */
+		uint32_t	reserved2:1;		/* 17 */
+		uint32_t	FourRankRDimm:1;	/* 18 */
+		uint32_t	DcqArbBypassEn:1;	/* 19 */
+		uint32_t	SlowAccessMode:1;	/* 20 */
+		uint32_t	FreqChgInProg:1;	/* 21 */
+		uint32_t	BankSwizzleMode:1;	/* 22 */
+		uint32_t	ProcOdtDis:1;		/* 23 */
+		uint32_t	DcqBypassMax:4;		/* 27:24 */
+		uint32_t	FourActWindow:4;	/* 31:28 */
+	} _fmt_10_ALL;
+	/*
+	 * Register format in family 0x11
+	 */
+	struct {
+		uint32_t	MemClkFreq:3;		/* 2:0 */
+		uint32_t	MemClkFreqVal:1;	/* 3 */
+		uint32_t	MaxAsyncLat:4;		/* 7:4 */
+		uint32_t	reserved1:6;		/* 13:8 */
+		uint32_t	DisDramInterface:1;	/* 14 */
+		uint32_t	PowerDownEn:1;		/* 15 */
+		uint32_t	PowerDownMode:1;	/* 16 */
+		uint32_t	reserved2:2;		/* 18:17 */
+		uint32_t	DcqArbBypassEn:1;	/* 19 */
+		uint32_t	SlowAccessMode:1;	/* 20 */
+		uint32_t	reserved3:1;		/* 21 */
+		uint32_t	BankSwizzleMode:1;	/* 22 */
+		uint32_t	ProcOdtDis:1;		/* 23 */
+		uint32_t	DcqBypassMax:4;		/* 27:24 */
+		uint32_t	FourActWindow:4;	/* 31:28 */
+	} _fmt_11_ALL;
+	/*
+	 * Register format in family 0x14
+	 */
+	struct {
+		uint32_t	MemClkFreq:5;		/* 4:0 */
+		uint32_t	reserved1:2;		/* 6:5 */
+		uint32_t	MemClkFreqVal:1;	/* 7 */
+		uint32_t	reserved2:2;		/* 9:8 */
+		uint32_t	ZqcsInterval:2;		/* 11:10 */
+		uint32_t	reserved3:3;		/* 14:12 */
+		uint32_t	PowerDownEn:1;		/* 15 */
+		uint32_t	PowerDownMode:1;	/* 16 */
+		uint32_t	reserved4:3;		/* 19:17 */
+		uint32_t	SlowAccessMode:1;	/* 20 */
+		uint32_t	reserved5:1;		/* 21 */
+		uint32_t	BankSwizzleMode:1;	/* 22 */
+		uint32_t	ProcOdtDis:1;		/* 23 */
+		uint32_t	DcqBypassMax:4;		/* 27:24 */
+		uint32_t	FourActWindow:4;	/* 31:28 */
+	} _fmt_14_ALL;
 };
 
 /*
- * Function 3 - Miscellaneous Control: Scrub Control Register
+ * Function 2 - DRAM Controller: DRAM Controller Miscellaneous Data
+ * F2x[1, 0]A0
  */
+union mcreg_drammisc {
+	uint32_t _val32;
+	/*
+	 * Register format in family 0xf revisions F and G
+	 */
+	struct {
+		uint32_t	reserved2:1;		/* 0 */
+		uint32_t	DisableJitter:1;	/* 1 */
+		uint32_t	RdWrQByp:2;		/* 3:2 */
+		uint32_t	Mod64Mux:1;		/* 4 */
+		uint32_t	DCC_EN:1;		/* 5 */
+		uint32_t	ILD_lmt:3;		/* 8:6 */
+		uint32_t	DramEnabled:1;		/* 9 */
+		uint32_t	PwrSavingsEn:1;		/* 10 */
+		uint32_t	reserved1:13;		/* 23:11 */
+		uint32_t	MemClkDis:8;		/* 31:24 */
+	} _fmt_f_revFG;
+	/*
+	 * Register format in family 0x10
+	 */
+	struct {
+		uint32_t	reserved1:9;		/* 8:0 */
+		uint32_t	DramEnabled:1;		/* 9 */
+		uint32_t	reserved2:22;		/* 31:10 */
+	} _fmt_10_ALL;
+	/*
+	 * Register format in family 0x10
+	 */
+	struct {
+		uint32_t	reserved1:3;		/* 2:0 */
+		uint32_t	PhyClkDivInSR:1;	/* 3 */
+		uint32_t	DllVRegPwrDwn:2;	/* 5:4 */
+		uint32_t	DllPwrDwn:2;		/* 7:6 */
+		uint32_t	reserved1:24;		/* 31:8 */
+	} _fmt_11_ALL;
+	/*
+	 * Register format in family 0x10
+	 */
+	struct {
+		uint32_t	reserved;		/* 31:0 */
+	} _fmt_14_ALL;
+};
 
+
+/*
+ * Function 2 - Swap Interleaved Region Base/Limit Register
+ * F2x10C - 10h after rev. C2 (i.e. C3 and E for now)
+ */
+union mcreg_swap_intlv {
+	uint32_t _val32;
+	/* Register format in family 0x10 rev >= C3 */
+	struct {
+		uint32_t	IntLvRgnSwapEn:1;	/* 0 */
+		uint32_t	reserved1:2;		/* 2:1 */
+		uint32_t	IntLvRgnBaseAddr:7;	/* 9:3 - address bits[33:27] */
+		uint32_t	reserved2:1;		/* 10 */
+		uint32_t	IntLvRgnLmtAddr:7;	/* 17:11 - address bits[33:27] */
+		uint32_t	reserved3:2;		/* 19:18 */
+		uint32_t	IntLvRgnSize:7;		/* 26:20 - size bits[33:27] */
+		uint32_t	reserved4:5;		/* 31:27 */
+	} _fmt_10_postC2;
+};
+
+/*
+ * Function 2 - DRAM Controller: DRAM Controller Select Low Register
+ * F2x110 - 10h, 11h, 14h
+ */
+union mcreg_select_lo {
+	uint32_t _val32;
+	/*
+	 * Register format in family 0x10
+	 */
+	struct {
+		uint32_t	DctSelHiRngEn:1;	/* 0 */
+		uint32_t	DctSelHi:1;			/* 1 */
+		uint32_t	DctSelIntLvEn:1;	/* 2 */
+		uint32_t	MemClrInit:1;		/* 3 */
+		uint32_t	DctGangEn:1;		/* 4 */
+		uint32_t	DctDatIntLv:1;		/* 5 */
+		uint32_t	DctSelIntLvAddr:2;	/* 7:6 */
+		uint32_t	DramEnable:1;		/* 8 */
+		uint32_t	MemClrBusy:1;		/* 9 */
+		uint32_t	MemCleared:1;		/* 10 */
+		uint32_t	DctSelBaseAddr:21;	/* 31:11 - bits 47:27 */
+	} _fmt_10_ALL;
+	/*
+	 * Register format in family 0x11
+	 */
+	struct {
+		uint32_t	DctSelHiRngEn:1;	/* 0 */
+		uint32_t	DctSelHi:1;			/* 1 */
+		uint32_t	DctSelIntLvEn:1;	/* 2 */
+		uint32_t	MemClrInit:1;		/* 3 */
+		uint32_t	DctGangEn:1;		/* 4 */
+		uint32_t	reserved1:1;		/* 5 */
+		uint32_t	DctSelIntLvAddr:2;	/* 7:6 */
+		uint32_t	DramEnable:1;		/* 8 */
+		uint32_t	MemClrBusy:1;		/* 9 */
+		uint32_t	MemCleared:1;		/* 10 */
+		uint32_t	DctSelBaseAddr:13;	/* 23:11 - bits 39:27 */
+		uint32_t	reserved2:8;		/* 31:24 */
+	} _fmt_11_ALL;
+	/*
+	 * Register format in family 0x14
+	 */
+	struct {
+		uint32_t	reserved1:3;		/* 2:0 */
+		uint32_t	MemClrInit:1;		/* 3 */
+		uint32_t	reserved2:4;		/* 7:4 */
+		uint32_t	DramEnable:1;		/* 8 */
+		uint32_t	MemClrBusy:1;		/* 9 */
+		uint32_t	MemCleared:1;		/* 10 */
+		uint32_t	reserved3:21;		/* 31:11 */
+	} _fmt_14_ALL;
+};
+
+/*
+ * Function 2 - DRAM Controller: DRAM Controller Select High Register
+ * F2x114 - 10h, 11h, 14h
+ */
+union mcreg_select_hi {
+	uint32_t _val32;
+	/*
+	 * Register format in family 0x10
+	 */
+	struct {
+		uint32_t	reserved1:10;		/* 9:0 */
+		uint32_t	DctSelBaseOffset:22;	/* 31:10 - bits 47:26 */
+	} _fmt_10_ALL;
+	/*
+	 * Register format in family 0x11
+	 */
+	struct {
+		uint32_t	reserved1:10;		/* 9:0 */
+		uint32_t	DctSelBaseOffset:14;/* 23:10 - bits 39:26 */
+		uint32_t	reserved2:8;		/* 31:24 */
+	} _fmt_11_ALL;
+	/*
+	 * Register format in family 0x14
+	 */
+	struct {
+		uint32_t	reserved1:9;		/* 8:0 */
+		uint32_t	DctSelBankSwap:1;	/* 9 */
+		uint32_t	reserved2:22;		/* 31:10 */
+	} _fmt_14_ALL;
+};
+
+/*
+ * Function 3 - Miscellaneous Control: Scrub Rate Control Register
+ * F3x58
+ */
 union mcreg_scrubctl {
 	uint32_t _val32;
+	/*
+	 * Register format in family 0xf
+	 */
 	struct {
 		uint32_t	DramScrub:5;		/* 4:0 */
-		uint32_t	reserved3:3;		/* 7:5 */
+		uint32_t	reserved1:3;		/* 7:5 */
 		uint32_t	L2Scrub:5;		/* 12:8 */
 		uint32_t	reserved2:3;		/* 15:13 */
 		uint32_t	DcacheScrub:5;		/* 20:16 */
-		uint32_t	reserved1:11;		/* 31:21 */
-	} _fmt_cmn;
+		uint32_t	reserved3:11;		/* 31:21 */
+	} _fmt_f_ALL;
+	/*
+	 * Register format in family 0x10
+	 */
+	struct {
+		uint32_t	DramScrub:5;		/* 4:0 */
+		uint32_t	reserved1:3;		/* 7:5 */
+		uint32_t	L2Scrub:5;			/* 12:8 */
+		uint32_t	reserved2:3;		/* 15:13 */
+		uint32_t	DcacheScrub:5;		/* 20:16 */
+		uint32_t	reserved1:4;		/* 23:21 */
+		uint32_t	L3Scrub:5;			/* 28:24 */
+		uint32_t	reserved3:3;		/* 31:29 */
+	} _fmt_10_ALL;
+	/*
+	 * Register format in family 0x11
+	 */
+	struct {
+		uint32_t	reserved1:8;		/* 7:0 */
+		uint32_t	L2Scrub:5;			/* 12:8 */
+		uint32_t	reserved2:3;		/* 15:13 */
+		uint32_t	DcacheScrub:5;		/* 20:16 */
+		uint32_t	reserved3:11;		/* 31:21 */
+	} _fmt_11_ALL;
+	/*
+	 * Register format in family 0x14
+	 */
+	struct {
+		uint32_t	reserved:8;		/* n/a */
+	} _fmt_14_ALL;
 };
 
+/*
+ * Function 3 - Miscellaneous Control: Scrub Address Low
+ * F3x5C
+ */
 union mcreg_dramscrublo {
 	uint32_t _val32;
 	struct {
 		uint32_t	ScrubReDirEn:1;		/* 0 */
 		uint32_t	reserved:5;		/* 5:1 */
-		uint32_t	ScrubAddrLo:26;		/* 31:6 */
-	} _fmt_cmn;
+		uint32_t	ScrubAddrLo:26;		/* 31:6 - Addr 31:6 */
+	} _fmt_f_ALL;
+	struct {
+		uint32_t	ScrubReDirEn:1;		/* 0 */
+		uint32_t	reserved:5;		/* 5:1 */
+		uint32_t	ScrubAddrLo:26;		/* 31:6 - Addr 31:6 */
+	} _fmt_10_ALL;
+	struct {
+		uint32_t	reserved;	/* n/a */
+	} _fmt_11_ALL;
+	struct {
+		uint32_t	reserved;	/* n/a */
+	} _fmt_14_ALL;
 };
 
+/*
+ * Function 3 - Miscellaneous Control: Scrub Address Low
+ * F3x60
+ */
 union mcreg_dramscrubhi {
 	uint32_t _val32;
 	struct {
 		uint32_t	ScrubAddrHi:8;		/* 7:0 */
-		uint32_t	reserved:24;		/* 31:8 */
-	} _fmt_cmn;
+		uint32_t	reserved:24;		/* 31:8 - Addr 39:32 */
+	} _fmt_f_ALL;
+	struct {
+		uint32_t	ScrubAddrHi:16;		/* 15:0 - Addr 47:32 */
+		uint32_t	reserved:16;		/* 31:16 */
+	} _fmt_10_ALL;
+	struct {
+		uint32_t	reserved;	/* n/a */
+	} _fmt_11_ALL;
+	struct {
+		uint32_t	reserved;	/* n/a */
+	} _fmt_14_ALL;
 };
 
 /*
- * Function 3 - Miscellaneous Control: On-Line Spare Control Register
+ * Function 3 - Miscellaneous Control: MCA NB Configuration Register
+ * F3x44
  */
-
 union mcreg_nbcfg {
 	uint32_t _val32;
 	/*
@@ -761,14 +1358,102 @@
 		uint32_t	DisMstAbtCpuErrRsp:1;		/* 29 */
 		uint32_t	SyncOnDramAdrParErrEn:1;	/* 30 */
 		uint32_t	reserved3:1;			/* 31 */
-
 	} _fmt_f_revFG;
+	/*
+	 * Register format in family 0x10
+	 */
+	struct {
+		uint32_t	reserved1:1;			/* 0 */
+		uint32_t	CpuRdDatErrEn:1;		/* 1 */
+		uint32_t	SyncOnUcEccEn:1;		/* 2 */
+		uint32_t	SyncPktGenDis:1;		/* 3 */
+		uint32_t	SyncPktPropDis:1;		/* 4 */
+		uint32_t	IoMstAbortDis:1;		/* 5 */
+		uint32_t	CpuErrDis:1;			/* 6 */
+		uint32_t	IoErrDis:1;				/* 7 */
+		uint32_t	WdogTmrDis:1;			/* 8 */
+		uint32_t	WdogTmrCntSel:3;		/* 11:9 */
+		uint32_t	WdogTmrBaseSel:2;		/* 13:12 */
+		uint32_t	LdtLinkSel:2;			/* 15:14 */
+		uint32_t	GenCrcErrByte0:1;		/* 16 */
+		uint32_t	GenCrcErrByte1:1;		/* 17 */
+		uint32_t	SubLinkSel:2;			/* 19:18 */
+		uint32_t	SyncOnWdogEn:1;			/* 20 */
+		uint32_t	SyncOnAnyErrEn:1;		/* 21 */
+		uint32_t	EccEn:1;				/* 22 */
+		uint32_t	ChipKillEccEn:1;		/* 23 */
+		uint32_t	IoRdDatErrEn:1;			/* 24 */
+		uint32_t	DisPciCfgCpuErrRsp:1;	/* 25 */
+		uint32_t	CorrMcaExcEn:1;			/* 26 */
+		uint32_t	NbMcaToMstCpuEn:1;		/* 27 */
+		uint32_t	DisTgtAbtCpuErrRsp:1;	/* 28 */
+		uint32_t	DisMstAbtCpuErrRsp:1;	/* 29 */
+		uint32_t	SyncOnDramAdrParErrEn:1;/* 30 */
+		uint32_t	NbMcaLogEn:1;			/* 31 */
+	} _fmt_10_ALL;
+	/*
+	 * Register format in family 0x11
+	 */
+	struct {
+		uint32_t	reserved1:1;			/* 0 */
+		uint32_t	CpuRdDatErrEn:1;		/* 1 */
+		uint32_t	reserved2:1;			/* 2 */
+		uint32_t	SyncPktGenDis:1;		/* 3 */
+		uint32_t	SyncPktPropDis:1;		/* 4 */
+		uint32_t	IoMstAbortDis:1;		/* 5 */
+		uint32_t	CpuErrDis:1;			/* 6 */
+		uint32_t	IoErrDis:1;				/* 7 */
+		uint32_t	WdogTmrDis:1;			/* 8 */
+		uint32_t	WdogTmrCntSel:3;		/* 11:9 */
+		uint32_t	WdogTmrBaseSel:2;		/* 13:12 */
+		uint32_t	reserved3:2;			/* 15:14 */
+		uint32_t	GenCrcErrByte0:1;		/* 16 */
+		uint32_t	GenCrcErrByte1:1;		/* 17 */
+		uint32_t	reserved4:2;			/* 19:18 */
+		uint32_t	SyncOnWdogEn:1;			/* 20 */
+		uint32_t	SyncOnAnyErrEn:1;		/* 21 */
+		uint32_t	reserved5:2;			/* 23:22 */
+		uint32_t	IoRdDatErrEn:1;			/* 24 */
+		uint32_t	DisPciCfgCpuErrRsp:1;	/* 25 */
+		uint32_t	CorrMcaExcEn:1;			/* 26 */
+		uint32_t	NbMcaToMstCpuEn:1;		/* 27 */
+		uint32_t	DisTgtAbtCpuErrRsp:1;	/* 28 ??? */ 
+		uint32_t	DisMstAbtCpuErrRsp:1;	/* 29 */
+		uint32_t	reserved6:1;			/* 30 */
+		uint32_t	NbMcaLogEn:1;			/* 31 */
+	} _fmt_11_ALL;
+	/*
+	 * Register format in family 0x14
+	 */
+	struct {
+		uint32_t	reserved1:1;			/* 0 */
+		uint32_t	CpuRdDatErrEn:1;		/* 1 */
+		uint32_t	reserved2:3;			/* 4:2 */
+		uint32_t	IoMstAbortDis:1;		/* 5 */
+		uint32_t	CpuErrDis:1;			/* 6 */
+		uint32_t	IoErrDis:1;				/* 7 */
+		uint32_t	WdogTmrDis:1;			/* 8 */
+		uint32_t	WdogTmrCntSel:3;		/* 11:9 */
+		uint32_t	WdogTmrBaseSel:2;		/* 13:12 */
+		uint32_t	reserved3:6;			/* 19:14 */
+		uint32_t	SyncOnWdogEn:1;			/* 20 */
+		uint32_t	SyncOnAnyErrEn:1;		/* 21 */
+		uint32_t	reserved4:2;			/* 23:22 */
+		uint32_t	IoRdDatErrEn:1;			/* 24 */
+		uint32_t	DisPciCfgCpuErrRsp:1;	/* 25 */
+		uint32_t	CorrMcaExcEn:1;			/* 26 */
+		uint32_t	NbMcaToMstCpuEn:1;		/* 27 */
+		uint32_t	DisTgtAbtCpuErrRsp:1;	/* 28 */ 
+		uint32_t	DisMstAbtCpuErrRsp:1;	/* 29 */
+		uint32_t	reserved5:1;			/* 30 */
+		uint32_t	NbMcaLogEn:1;			/* 31 */
+	} _fmt_14_ALL;
 };
 
 /*
  * Function 3 - Miscellaneous Control: On-Line Spare Control Register
+ * F3xB0 - revFG, 10h
  */
-
 union mcreg_sparectl {
 	uint32_t _val32;
 	/*
@@ -791,7 +1476,7 @@
 		uint32_t	reserved5:4;		/* 31:28 */
 	} _fmt_f_revFG;
 	/*
-	 * Regiser format in family 0x10 revisions A and B
+	 * Register format in family 0x10
 	 */
 	struct {
 		uint32_t	SwapEn0:1;		/* 0 */
@@ -805,15 +1490,123 @@
 		uint32_t	SwapDoneInt:2;		/* 13:12 */
 		uint32_t	EccErrInt:2;		/* 15:14 */
 		uint32_t	EccErrCntDramCs:4;	/* 19:16 */
-		uint32_t	EccErrCntDramChan:2;	/* 21:20 */
-		uint32_t	reserved4:1;		/* 22 */
+		uint32_t	EccErrCntDramChan:1;	/* 20 */
+		uint32_t	reserved3:2;		/* 22:21 */
 		uint32_t	EccErrCntWrEn:1;	/* 23 */
 		uint32_t	EccErrCnt:4;		/* 27:24 */
 		uint32_t	LvtOffset:4;		/* 31:28 */
-	} _fmt_10_revAB;
+	} _fmt_10_ALL;
+	/*
+	 * Register format in family 0x11
+	 */
+	struct {
+		uint32_t	reserved;		/* n/a */
+	} _fmt_11_ALL;
+	/*
+	 * Register format in family 0x14
+	 */
+	struct {
+		uint32_t	reserved;		/* n/a */
+	} _fmt_14_ALL;
+
 };
 
 /*
+ * Function 3 - Northbridge Capabilities
+ * F3xE8 - all
+ */
+union mcreg_nbcap {
+	uint32_t _val32;
+	/*
+	 * Register format in family 0xf revisions E and earlier.
+	 */
+	struct {
+		uint32_t	Width128BitCap:1;	/* 0 */
+		uint32_t	MPCap:1;			/* 1 */
+		uint32_t	BigMPCap:1;			/* 2 */
+		uint32_t	EccCap:1;			/* 3 */
+		uint32_t	ChipKillEccCap: 1; 	/* 4 */
+		uint32_t	DdrMaxRate:2;		/* 6:5 */
+		uint32_t	reserved1:1;		/* 7 */
+		uint32_t	MctCap:1;			/* 8 */
+		uint32_t	reserved2:3;		/* 11:9 */
+		uint32_t	CmpCap:2;			/* 13:12 */
+		uint32_t	reserved4:18;		/* 31:14 */
+	} _fmt_f_preFG;
+	/*
+	 * Register format in family 0xf revisions F and G
+	 */
+	struct {
+		uint32_t	Width128BitCap:1;	/* 0 */
+		uint32_t	MPCap:1;			/* 1 */
+		uint32_t	BigMPCap:1;			/* 2 */
+		uint32_t	EccCap:1;			/* 3 */
+		uint32_t	ChipKillEccCap: 1; 	/* 4 */
+		uint32_t	DdrMaxRate:2;		/* 6:5 */
+		uint32_t	reserved1:1;		/* 7 */
+		uint32_t	MctCap:1;			/* 8 */
+		uint32_t	reserved2:1;		/* 9 */
+		uint32_t	HtcCap:1;			/* 10 */
+		uint32_t	reserved3:1;		/* 11 */
+		uint32_t	CmpCap:2;			/* 13:12 */
+		uint32_t	reserved4:18;		/* 31:14 */
+	} _fmt_f_revFG;
+	/*
+	 * Register format in family 0x10
+	 */
+	struct {
+		uint32_t	DctDualCap:1;		/* 0 */
+		uint32_t	DualNodeMPCap:1;	/* 1 */
+		uint32_t	EigthNodeMPCap:1;	/* 2 */
+		uint32_t	EccCap:1;			/* 3 */
+		uint32_t	ChipKillEccCap: 1; 	/* 4 */
+		uint32_t	DdrMaxRate:3;		/* 7:5 */
+		uint32_t	MctCap:1;			/* 8 */
+		uint32_t	SvmCap:1;			/* 9 */
+		uint32_t	HtcCap:1;			/* 10 */
+		uint32_t	LnkRtryCap:1;		/* 11 */
+		uint32_t	CmpCap:2;			/* 13:12 */
+		uint32_t	MultiVIDPlaneCap:1;	/* 14 */
+		uint32_t	CmpCap2:1;			/* 15 - since 0x10 Rev. D */
+		uint32_t	MpCap:3;			/* 18:16 */
+		uint32_t	reserved1:1;		/* 19 */
+		uint32_t	UnGangEn:4;			/* 23:20 */
+		uint32_t	reserved2:1;		/* 24 */
+		uint32_t	L3Cap:1;			/* 25 */
+		uint32_t	reserved3:3;		/* 28:26 */
+		uint32_t	MultiNodeCpu:1;		/* 29  - since 0x10 Rev. D */
+		uint32_t	IntNodeNum:2;		/* 31:30 - since 0x10 Rev. D */
+	} _fmt_10_ALL;
+	/*
+	 * Register format in family 0x11
+	 */
+	struct {
+		uint32_t	DctDualCap:1;		/* 0 */
+		uint32_t	reserved1:4;		/* 4:1 */
+		uint32_t	DdrMaxRate:3;		/* 7:5 */
+		uint32_t	MctCap:1;			/* 8 */
+		uint32_t	SvmCap:1;			/* 9 */
+		uint32_t	HtcCap:1;			/* 10 */
+		uint32_t	LnkRtryCap:1;		/* 11 */
+		uint32_t	CmpCap:2;			/* 13:12 */
+		uint32_t	reserved2:18;		/* 31:14 */
+	} _fmt_11_ALL;
+	/*
+	 * Register format in family 0x14
+	 */
+	struct {
+		uint32_t	reserved1:5;		/* 4:0 */
+		uint32_t	DdrMaxRate:3;		/* 7:5 */
+		uint32_t	MctCap:1;			/* 8 */
+		uint32_t	SvmCap:1;			/* 9 */
+		uint32_t	HtcCap:1;			/* 10 */
+		uint32_t	reserved2:1;		/* 11 */
+		uint32_t	CmpCap:1;			/* 12 */
+		uint32_t	reserved3:19;		/* 31:13 */
+	} _fmt_14_ALL;
+};
+
+/*
  * Since the NB is on-chip some registers are also accessible as MSRs.
  * We will represent such registers as bitfields as in the 32-bit PCI
  * registers above, with the restriction that we must compile for 32-bit
@@ -824,10 +1617,9 @@
 
 #define	MCMSR_VAL(up) ((up)->_val64)
 
-#define	MCMSR_FIELD_CMN(up, field)	_MCMSR_FIELD(up, cmn, field)
 #define	MCMSR_FIELD_F_preF(up, field)	_MCMSR_FIELD(up, f_preF, field)
 #define	MCMSR_FIELD_F_revFG(up, field)	_MCMSR_FIELD(up, f_revFG, field)
-#define	MCMSR_FIELD_10_revAB(up, field)	_MCMSR_FIELD(up, 10_revAB, field)
+#define	MCMSR_FIELD_10_ALL(up, field)	_MCMSR_FIELD(up, 10_ALL, field)
 
 /*
  * The NB MISC registers.  On family 0xf rev F this was introduced with
@@ -838,7 +1630,6 @@
  * MC4_MISC{0,1,2,3} accessible via both MSRs and PCI config space;
  * they perform thresholding for dram, l3, HT errors.
  */
-
 union mcmsr_nbmisc {
 	uint64_t _val64;
 	/*
@@ -868,11 +1659,11 @@
 		} _mcimisc_hi;
 	} _fmt_f_revFG;
 	/*
-	 * MSR format in family 0x10 revisions A and B
+	 * MSR format in family 0x10
 	 */
 	struct {
 		/*
-		 * Lower 32 bits
+		 * Lower 32 bits (MC4_MISC0[31:0])
 		 */
 		struct {
 			uint32_t _reserved:24;			/* 23:0 */
@@ -879,7 +1670,7 @@
 			uint32_t _BlkPtr:8;			/* 31:24 */
 		} _mcimisc_lo;
 		/*
-		 * Upper 32 bits
+		 * Upper 32 bits (MC4_MISC0[63:32] == F3x160[31:0])
 		 */
 		struct {
 			uint32_t _ErrCnt:12;			/* 43:32 */
@@ -894,7 +1685,29 @@
 			uint32_t _Valid:1;			/* 63 */
 
 		} _mcimisc_hi;
-	} _fmt_10_revAB;
+	} _fmt_10_ALL;
+	/*
+	 * MSR format in family 0x11
+	 */
+	struct {
+		struct {
+			uint32_t _reserved;		/* n/a */
+		} _mcimisc_lo;
+		struct {
+			uint32_t _reserved;		/* n/a */
+		} _mcimisc_hi;
+	} _fmt_11_ALL;
+	/*
+	 * MSR format in family 0x14
+	 */
+	struct {
+		struct {
+			uint32_t _reserved;		/* n/a */
+		} _mcimisc_lo;
+		struct {
+			uint32_t _reserved;		/* n/a */
+		} _mcimisc_hi;
+	} _fmt_14_ALL;
 };
 
 #define	mcmisc_BlkPtr	_mcimisc_lo._BlkPtr
--- onnv-129.orig/usr/src/uts/intel/io/mc-amd/mcamd_off.in	Tue Dec  1 09:42:07 2009
+++ onnv-129/usr/src/uts/intel/io/mc-amd/mcamd_off.in	Mon Mar 14 22:49:53 2011
@@ -36,16 +36,25 @@
 	mc_props.mcp_csintlvfctr	MCAMD_MC_OFF_CSINTLVFCTR
 	mc_props.mcp_dramhole_size	MCAMD_MC_OFF_DRAMHOLE_SIZE
 	mc_props.mcp_accwidth		MCAMD_MC_OFF_ACCWIDTH
+	mc_props.mcp_accwidth1		MCAMD_MC_OFF_ACCWIDTH1
 	mc_props.mcp_csbankmapreg	MCAMD_MC_OFF_CSBANKMAPREG
+	mc_props.mcp_csbankmapreg1	MCAMD_MC_OFF_CSBANKMAPREG1
 	mc_props.mcp_bnkswzl		MCAMD_MC_OFF_BNKSWZL
 	mc_props.mcp_mod64mux		MCAMD_MC_OFF_MOD64MUX
 	mc_props.mcp_sparecs		MCAMD_MC_OFF_SPARECS
 	mc_props.mcp_badcs		MCAMD_MC_OFF_BADCS
+	mc_props.mcp_badcs1		MCAMD_MC_OFF_BADCS1
+	mc_props.mcp_ganged		MCAMD_MC_OFF_GANGED
+	mc_props.mcp_ddr3		MCAMD_MC_OFF_DDR3
 	mc_cfgregs.mcr_drambase		MCAMD_MC_OFF_DRAMBASE_REG
 	mc_cfgregs.mcr_dramlimit	MCAMD_MC_OFF_DRAMLIMIT_REG
 	mc_cfgregs.mcr_dramhole		MCAMD_MC_OFF_DRAMHOLE_REG
 	mc_cfgregs.mcr_dramcfglo	MCAMD_MC_OFF_DRAMCFGLO_REG
+	mc_cfgregs.mcr_dramcfglo1	MCAMD_MC_OFF_DRAMCFGLO1_REG
 	mc_cfgregs.mcr_dramcfghi	MCAMD_MC_OFF_DRAMCFGHI_REG
+	mc_cfgregs.mcr_dramcfghi1	MCAMD_MC_OFF_DRAMCFGHI1_REG
+	mc_cfgregs.mcr_selectlo		MCAMD_MC_OFF_SELECTLO_REG
+	mc_cfgregs.mcr_selecthi		MCAMD_MC_OFF_SELECTLO_REG
 
 mc_cs_t
 	mccs_props.csp_num		MCAMD_CS_OFF_NUM
--- onnv-129.orig/usr/src/uts/intel/io/mc-amd/mcamd_dimmcfg_impl.h	Tue Dec  1 09:42:07 2009
+++ onnv-129/usr/src/uts/intel/io/mc-amd/mcamd_dimmcfg_impl.h	Tue Mar  8 04:14:49 2011
@@ -41,6 +41,8 @@
  */
 #define	CH_A	0
 #define	CH_B	1
+#define	CH_C	2
+#define	CH_D	3
 
 /*
  * Line structure for the tables.  We include up to 2 chip-selects per
@@ -74,6 +76,29 @@
 #define	AM2S1g1		(X86_SOCKET_AM2 | X86_SOCKET_S1g1)
 
 /*
+ * Defines for use with csm_pkg - 0x10 packages
+ */
+/* #define	F1207		X86_SOCKET_F1207 	* already defined */
+#define AM2r2	X86_SOCKET_AM2R2
+#define AM3		X86_SOCKET_AM3
+#define ASB2	X86_SOCKET_ASB2
+#define S1g3	X86_SOCKET_S1g3			/* includes S1g4 */
+#define C32		X86_SOCKET_C32
+#define G34		X86_SOCKET_G34
+#define SKT_0x10_DESKTOP	(AM2r2 | AM3 | ASB2 | S1g3)
+#define SKT_0x10_OPTERON	(F1207 | C32 | G34 )
+
+/*
+ * Defines for use with csm_pkg - 0x11 packages
+ */
+#define	S1g2		X86_SOCKET_S1g2
+
+/*
+ * Defines for use with csm_pkg - 0x14 packages
+ */
+#define	FT1		X86_SOCKET_FT1
+
+/*
  * Defines for use with csm_dimmcfg
  */
 #define	DCFG_N		0x1	/* Normal */
--- onnv-129.orig/usr/src/uts/intel/io/mc-amd/mcamd_subr.c	Tue Dec  1 09:42:07 2009
+++ onnv-129/usr/src/uts/intel/io/mc-amd/mcamd_subr.c	Mon Mar 14 22:47:56 2011
@@ -236,11 +236,14 @@
 	{ MCAMD_PROP_CSINTLVFCTR, MCAMD_MC_OFF_CSINTLVFCTR },
 	{ MCAMD_PROP_DRAMHOLE_SIZE, MCAMD_MC_OFF_DRAMHOLE_SIZE },
 	{ MCAMD_PROP_ACCESS_WIDTH, MCAMD_MC_OFF_ACCWIDTH },
+	{ MCAMD_PROP_ACCESS_WIDTH1, MCAMD_MC_OFF_ACCWIDTH1 },
 	{ MCAMD_PROP_CSBANKMAPREG, MCAMD_MC_OFF_CSBANKMAPREG },
 	{ MCAMD_PROP_BANKSWZL, MCAMD_MC_OFF_BNKSWZL },
 	{ MCAMD_PROP_MOD64MUX, MCAMD_MC_OFF_MOD64MUX },
 	{ MCAMD_PROP_SPARECS, MCAMD_MC_OFF_SPARECS },
 	{ MCAMD_PROP_BADCS, MCAMD_MC_OFF_BADCS },
+	{ MCAMD_PROP_GANGED, MCAMD_MC_OFF_GANGED },
+	{ MCAMD_PROP_DDR3, MCAMD_MC_OFF_DDR3 },
 };
 
 static const struct mc_offmap mcamd_cs_offmap[] = {
@@ -340,7 +343,11 @@
 	{ MCAMD_REG_DRAMLIMIT, MCAMD_MC_OFF_DRAMLIMIT_REG },
 	{ MCAMD_REG_DRAMHOLE, MCAMD_MC_OFF_DRAMHOLE_REG },
 	{ MCAMD_REG_DRAMCFGLO, MCAMD_MC_OFF_DRAMCFGLO_REG },
+	{ MCAMD_REG_DRAMCFGLO1, MCAMD_MC_OFF_DRAMCFGLO1_REG },
 	{ MCAMD_REG_DRAMCFGHI, MCAMD_MC_OFF_DRAMCFGHI_REG },
+	{ MCAMD_REG_DRAMCFGHI1, MCAMD_MC_OFF_DRAMCFGHI1_REG },
+	{ MCAMD_REG_SELECTLO, MCAMD_MC_OFF_SELECTLO_REG },
+	{ MCAMD_REG_SELECTHI, MCAMD_MC_OFF_SELECTHI_REG },
 };
 
 static const struct mc_offmap csreg_offmap[] = {
--- onnv-129.orig/usr/src/uts/intel/io/mc-amd/mcamd_drv.c	Tue Dec  1 09:42:07 2009
+++ onnv-129/usr/src/uts/intel/io/mc-amd/mcamd_drv.c	Wed Mar 16 22:59:15 2011
@@ -142,7 +142,7 @@
 	return (NULL);
 }
 
-/*
+/**
  * Read config register pairs into the two arrays provided on the given
  * handle and at offsets as follows:
  *
@@ -153,8 +153,15 @@
  *	...
  *	n - 1	r1addr + (n - 1) * incr		r2addr + (n - 1) * incr
  *
- * The number of registers to read into the r1 array is r1n; the number
- * for the r2 array is r2n.
+ * @param cfghdl	pcicfg handle
+ * @param r1		result storage 1
+ * @param r1addr	first register to read
+ * @param r1n		number of registers to read into r1
+ * @param r2		result storage 2
+ * @param r2addr	second register to read
+ * @param r2n		number of registers to read into r2
+ * @param incr		increment for r{1|2}addr to use to get the address of the
+ * 					next register to read.
  */
 static void
 mc_prop_read_pair(mc_pcicfg_hdl_t cfghdl, uint32_t *r1, off_t r1addr,
@@ -211,11 +218,12 @@
 	uint32_t rev = mc->mc_props.mcp_rev;
 	union mcreg_nbcfg nbcfg;
 
+	if (MC_REV_MATCH(rev, MC_11_ALL) || MC_REV_MATCH(rev, MC_14_ALL)) {
+		return 0;
+	}
 	MCREG_VAL32(&nbcfg) = mc->mc_cfgregs.mcr_nbcfg;
 
-	return (MC_REV_MATCH(rev, MC_F_REVS_BCDE) ?
-	    MCREG_FIELD_F_preF(&nbcfg, EccEn) :
-	    MCREG_FIELD_F_revFG(&nbcfg, EccEn));
+	return MCREG_FIELD_F_preF(&nbcfg, EccEn); /* same for all */
 }
 
 static uint32_t
@@ -224,11 +232,12 @@
 	uint32_t rev = mc->mc_props.mcp_rev;
 	union mcreg_nbcfg nbcfg;
 
+	if (MC_REV_MATCH(rev, MC_11_ALL) || MC_REV_MATCH(rev, MC_14_ALL)) {
+		return 0;
+	}
 	MCREG_VAL32(&nbcfg) = mc->mc_cfgregs.mcr_nbcfg;
 
-	return (MC_REV_MATCH(rev, MC_F_REVS_BCDE) ?
-	    MCREG_FIELD_F_preF(&nbcfg, ChipKillEccEn) :
-	    MCREG_FIELD_F_revFG(&nbcfg, ChipKillEccEn));
+	return MCREG_FIELD_F_preF(&nbcfg, ChipKillEccEn); /* same for all */
 }
 
 static void
@@ -338,39 +347,77 @@
 static void
 mc_nvl_add_htconfig(nvlist_t *mcnvl, mc_t *mc)
 {
+	uint32_t rev = mc->mc_props.mcp_rev;
+	boolean_t is_0x10 = MC_REV_MATCH(rev, MC_10_ALL);
+	boolean_t pre_0x11 = MC_REV_MATCH(rev, MC_F_ALL) || is_0x10;
+	boolean_t is_0x14 = MC_REV_MATCH(rev, MC_14_ALL);
+
 	mc_cfgregs_t *mcr = &mc->mc_cfgregs;
 	union mcreg_htroute *htrp = (union mcreg_htroute *)&mcr->mcr_htroute[0];
 	union mcreg_nodeid *nip = (union mcreg_nodeid *)&mcr->mcr_htnodeid;
+	union mcreg_nodeid1 *nip1 = (union mcreg_nodeid1 *)&mcr->mcr_htnodeid1;
 	union mcreg_unitid *uip = (union mcreg_unitid *)&mcr->mcr_htunitid;
-	int ndcnt = HT_COHERENTNODES(nip);
 	uint32_t BCRte[MC_CHIP_MAXNODES];
 	uint32_t RPRte[MC_CHIP_MAXNODES];
 	uint32_t RQRte[MC_CHIP_MAXNODES];
 	nvlist_t *nvl;
-	int i;
+	int i, ndcnt = is_0x14 ? 1 : (MCREG_FIELD_PRE_11(nip, NodeCnt)+1);
 
 	(void) nvlist_alloc(&nvl, NV_UNIQUE_NAME, KM_SLEEP);
 
-	(void) nvlist_add_uint32(nvl, "NodeId", MCREG_FIELD_CMN(nip, NodeId));
-	(void) nvlist_add_uint32(nvl, "CoherentNodes", HT_COHERENTNODES(nip));
-	(void) nvlist_add_uint32(nvl, "SbNode", MCREG_FIELD_CMN(nip, SbNode));
-	(void) nvlist_add_uint32(nvl, "LkNode", MCREG_FIELD_CMN(nip, LkNode));
+	(void) nvlist_add_uint32(nvl, "NodeId", MCREG_FIELD_PRE_11(nip, NodeId));
+	(void) nvlist_add_uint32(nvl, "CoherentNodes", ndcnt);
+	if (pre_0x11) {
+		(void) nvlist_add_uint32(nvl, "SbNode", MCREG_FIELD_PRE_11(nip, SbNode));
+		(void) nvlist_add_uint32(nvl, "LkNode", MCREG_FIELD_PRE_11(nip, LkNode));
+		int cores = MCREG_FIELD_PRE_11(nip, CpuCnt) + 1;
+		if (is_0x10) {
+			cores |= (MCREG_FIELD_10_ALL(nip1, CpuCount) << 3);
+		}
+		(void) nvlist_add_uint32(nvl, "SystemCoreCount", cores);
+	} else {
+		/* cores = Fn8000_0008_ECX[7:0] */
+		struct cpuid_regs cpuid = { 0, 0, 0, 0 };
+		cpuid.cp_eax = 0x80000008;
+		(void) __cpuid_insn(&cpuid);
 	(void) nvlist_add_uint32(nvl, "SystemCoreCount",
-	    HT_SYSTEMCORECOUNT(nip));
+			(cpuid.cp_ecx & 0xff) + 1);
+	}
 
-	(void) nvlist_add_uint32(nvl, "C0Unit", MCREG_FIELD_CMN(uip, C0Unit));
-	(void) nvlist_add_uint32(nvl, "C1Unit", MCREG_FIELD_CMN(uip, C1Unit));
-	(void) nvlist_add_uint32(nvl, "McUnit", MCREG_FIELD_CMN(uip, McUnit));
-	(void) nvlist_add_uint32(nvl, "HbUnit", MCREG_FIELD_CMN(uip, HbUnit));
-	(void) nvlist_add_uint32(nvl, "SbLink", MCREG_FIELD_CMN(uip, SbLink));
+	if (pre_0x10) {
+		(void) nvlist_add_uint32(nvl, "C0Unit", MCREG_FIELD_F_ALL(uip, C0Unit));
+		(void) nvlist_add_uint32(nvl, "C1Unit", MCREG_FIELD_F_ALL(uip, C1Unit));
+	} else if (is_0x10) {
+		(void) nvlist_add_uint32(nvl, "CpuUnit", MCREG_FIELD_10_ALL(uip, C0Unit));
+	} else {
+		/* 0x11, 0x14 have no Unit ID reg */
+		(void) nvlist_add_uint32(nvl, "CpuUnit", 0);
+	}
+	if (pre_0x11) {
+		(void) nvlist_add_uint32(nvl, "McUnit", MCREG_FIELD_10_ALL(uip, McUnit));
+		(void) nvlist_add_uint32(nvl, "HbUnit", MCREG_FIELD_10_ALL(uip, HbUnit));
+		(void) nvlist_add_uint32(nvl, "SbLink", MCREG_FIELD_10_ALL(uip, SbLink));
+	} else if (!is_0x14) {
+		(void) nvlist_add_uint32(nvl, "SbLink", MCREG_FIELD_11_ALL(uip, SbLink));
+	}
 
 	if (ndcnt <= MC_CHIP_MAXNODES) {
+		if (pre_0x10) {
 		for (i = 0; i < ndcnt; i++, htrp++) {
-			BCRte[i] = MCREG_FIELD_CMN(htrp, BCRte);
-			RPRte[i] = MCREG_FIELD_CMN(htrp, RPRte);
-			RQRte[i] = MCREG_FIELD_CMN(htrp, RQRte);
+				BCRte[i] = MCREG_FIELD_F_ALL(htrp, BCRte);
+				RPRte[i] = MCREG_FIELD_F_ALL(htrp, RPRte);
+				RQRte[i] = MCREG_FIELD_F_ALL(htrp, RQRte);
 		}
-
+		} else if (is_0x10) {
+				BCRte[i] = MCREG_FIELD_10_ALL(htrp, BCRte);
+				RPRte[i] = MCREG_FIELD_10_ALL(htrp, RPRte);
+				RQRte[i] = MCREG_FIELD_10_ALL(htrp, RQRte);
+		} else {
+			/* n/a in 0x11, 0x14 */
+			BCRte[0] = 0;
+			RPRte[0] = 0;
+			RQRte[0] = 0;
+		}
 		(void) nvlist_add_uint32_array(nvl, "BroadcastRoutes",
 		    &BCRte[0], ndcnt);
 		(void) nvlist_add_uint32_array(nvl, "ResponseRoutes",
@@ -411,11 +458,17 @@
 	mc_nvl_add_prop(mcnvl, mc, MCAMD_PROP_CSINTLVFCTR, 0);
 	mc_nvl_add_prop(mcnvl, mc, MCAMD_PROP_DRAMHOLE_SIZE, 0);
 	mc_nvl_add_prop(mcnvl, mc, MCAMD_PROP_ACCESS_WIDTH, 0);
+	mc_nvl_add_prop(mcnvl, mc, MCAMD_PROP_ACCESS_WIDTH1, 0);
 	mc_nvl_add_prop(mcnvl, mc, MCAMD_PROP_CSBANKMAPREG, 0);
+	mc_nvl_add_prop(mcnvl, mc, MCAMD_PROP_CSBANKMAPREG1, 0);
 	mc_nvl_add_prop(mcnvl, mc, MCAMD_PROP_BANKSWZL, 0);
 	mc_nvl_add_prop(mcnvl, mc, MCAMD_PROP_MOD64MUX, 0);
 	mc_nvl_add_prop(mcnvl, mc, MCAMD_PROP_SPARECS, 1);
+	mc_nvl_add_prop(mcnvl, mc, MCAMD_PROP_SPARECS1, 1);
 	mc_nvl_add_prop(mcnvl, mc, MCAMD_PROP_BADCS, 1);
+	mc_nvl_add_prop(mcnvl, mc, MCAMD_PROP_BADCS1, 1);
+	mc_nvl_add_prop(mcnvl, mc, MCAMD_PROP_GANGED, 0);
+	mc_nvl_add_prop(mcnvl, mc, MCAMD_PROP_DDR3, 0);
 
 	mc_nvl_add_cslist(mcnvl, mc);
 	mc_nvl_add_dimmlist(mcnvl, mc);
@@ -549,14 +602,19 @@
 	 * and 4 or fewer would indicate that if we see any of the upper
 	 * chip-selects enabled then a quadrank dimm is present.
 	 *
-	 * For socket F(1207) we can check a bit in the dram config high reg.
+	 * For socket F(1207), G34 we can check a bit in the dram config high reg.
 	 *
 	 * Other socket types do not support registered dimms.
+	 * AM2r2 and AM3 + S1g3 or S1g4 support unbuffered/SO QR-Dimms, only.
 	 */
-	if (mc->mc_socket == X86_SOCKET_940)
+	if (mc->mc_socket == X86_SOCKET_940) {
 		r4 = mc_quadranksupport != 0;
-	else if (mc->mc_socket == X86_SOCKET_F1207)
+	} else if (mc->mc_socket == X86_SOCKET_F1207
+			|| mc->mc_socket == X86_SOCKET_C32
+			|| mc->mc_socket == X86_SOCKET_G34)
+	{
 		r4 = MCREG_FIELD_F_revFG(drcfghip, FourRankRDimm);
+	}
 
 	/*
 	 * Are we dealing with quadrank SO-DIMMs?  These are supported
@@ -649,18 +707,33 @@
 mc_mkprops_htcfg(mc_pcicfg_hdl_t cfghdl, mc_t *mc)
 {
 	union mcreg_nodeid nodeid;
+	union mcreg_nodeid1 nodeid1;
 	off_t offset;
-	int i;
+	int i, nodes;
+	if (MC_REV_MATCH(rev, MC_14_ALL)) {
+		return;
+	}
 
 	mc->mc_cfgregs.mcr_htnodeid = MCREG_VAL32(&nodeid) =
 	    mc_pcicfg_get32(cfghdl, MC_HT_REG_NODEID);
+	if (MC_REV_MATCH(rev, MC_10_ALL)) {
+		/* required to determine number of cores */
+		mc->mc_cfgregs.mcr_htnodeid1 = MCREG_VAL32(&nodeid1) =
+		    mc_pcicfg_get32(cfghdl, MC_HT_REG_NODEID1);
+	}
+	nodes = MCREG_FIELD_11_ALL(&nodeid, NodeCnt) + 1; /* 0..8 */
 
 	mc->mc_cfgregs.mcr_htunitid = mc_pcicfg_get32(cfghdl, MC_HT_REG_UNITID);
 
-	for (i = 0, offset = MC_HT_REG_RTBL_NODE_0;
-	    i < HT_COHERENTNODES(&nodeid);
+	if (MC_REV_MATCH(rev, MC_11_ALL)) {
+		/* no routing info, no MPcap */
+		return;
+	}
+	for (i = 0, offset = MC_HT_REG_RTBL_NODE_0; i <  nodes;
 	    i++, offset += MC_HT_REG_RTBL_INCR)
+	{
 		mc->mc_cfgregs.mcr_htroute[i] = mc_pcicfg_get32(cfghdl, offset);
+	}
 }
 
 /*
@@ -679,30 +752,48 @@
 mc_mkprops_addrmap(mc_pcicfg_hdl_t cfghdl, mc_t *mc)
 {
 	union mcreg_drambase basereg;
+	union mcreg_drambase_hi basereg_hi;
 	union mcreg_dramlimit limreg;
+	union mcreg_dramlimit_hi limreg_hi;
+	union mcreg_dramhole hole;
+
 	mc_props_t *mcp = &mc->mc_props;
 	mc_cfgregs_t *mcr = &mc->mc_cfgregs;
-	union mcreg_dramhole hole;
 	int nodeid = mc->mc_props.mcp_num;
+	int incr = nodeid * MC_AM_REG_DRAM_INCR;
 
-	mcr->mcr_drambase = MCREG_VAL32(&basereg) = mc_pcicfg_get32(cfghdl,
-	    MC_AM_REG_DRAMBASE_0 + nodeid * MC_AM_REG_DRAM_INCR);
+	uint32_t rev = mc->mc_props.mcp_rev;
+	boolean_t is_0x14 = MC_REV_MATCH(rev, MC_14_ALL);
+	boolean_t post_0x10 = MC_REV_MATCH(rev, MC_11_ALL) || is_0x14;
+	boolean_t is_0x10 = MC_REV_MATCH(rev, MC_10_ALL);
 
-	mcr->mcr_dramlimit = MCREG_VAL32(&limreg) = mc_pcicfg_get32(cfghdl,
-	    MC_AM_REG_DRAMLIM_0 + nodeid * MC_AM_REG_DRAM_INCR);
+	mcr->mcr_drambase = MCREG_VAL32(&basereg)
+		= mc_pcicfg_get32(cfghdl, MC_AM_REG_DRAMBASE_0 + incr);
 
+	mcr->mcr_dramlimit = MCREG_VAL32(&limreg)
+		= mc_pcicfg_get32(cfghdl, MC_AM_REG_DRAMLIM_0 + incr);
+	if (is_0x10) {
+		mcr->mcr_drambase_hi = MCREG_VAL32(&basereg_hi)
+			= mc_pcicfg_get32(cfghdl, MC_AM_REG_DRAMBASE_HI_0 + incr);
+		mcr->mcr_dramlimit_hi = MCREG_VAL32(&limreg_hi)
+			= mc_pcicfg_get32(cfghdl, MC_AM_REG_DRAMLIM_HI_0 + incr);
+	}
+
 	/*
 	 * Derive some "cooked" properties for nodes that have a range of
 	 * physical addresses that are read or write enabled and for which
 	 * the DstNode matches the node we are attaching.
 	 */
-	if (MCREG_FIELD_CMN(&limreg, DRAMLimiti) != 0 &&
-	    MCREG_FIELD_CMN(&limreg, DstNode) == nodeid &&
-	    (MCREG_FIELD_CMN(&basereg, WE) || MCREG_FIELD_CMN(&basereg, RE))) {
-		mcp->mcp_base = MC_DRAMBASE(&basereg);
-		mcp->mcp_lim = MC_DRAMLIM(&limreg);
-		mcp->mcp_ilen = MCREG_FIELD_CMN(&basereg, IntlvEn);
-		mcp->mcp_ilsel = MCREG_FIELD_CMN(&limreg, IntlvSel);
+	mcp->mcp_lim = MC_DRAMLIM(&limreg, &limreg_hi, mc->mc_props.mcp_rev);
+	if (mcp->mcp_lim != 0 && !post_0x10 &&
+	    MCREG_FIELD_PRE_11(&limreg, DstNode) == nodeid &&
+	    (MCREG_FIELD_PRE_11(&basereg, WE) || MCREG_FIELD_PRE_11(&basereg, RE)))
+	{
+		mcp->mcp_base = MC_DRAMBASE(&basereg, &basereg_hi, rev);
+		mcp->mcp_ilen = MCREG_FIELD_PRE_11(&basereg, IntlvEn);
+		mcp->mcp_ilsel = MCREG_FIELD_PRE_11(&limreg, IntlvSel);
+	} else {
+		mcp->mcp_lim = 0;
 	}
 
 	/*
@@ -711,12 +802,14 @@
 	 * hole base and offset for this node.  This was introduced in
 	 * revision E.
 	 */
-	if (MC_REV_ATLEAST(mc->mc_props.mcp_rev, MC_F_REV_E)) {
+	if (MC_REV_ATLEAST(mc->mc_props.mcp_rev, MC_F_REV_E) || is_0x10
+		|| post_0x10)
+	{
 		mcr->mcr_dramhole = MCREG_VAL32(&hole) =
 		    mc_pcicfg_get32(cfghdl, MC_AM_REG_HOLEADDR);
 
-		if (MCREG_FIELD_CMN(&hole, DramHoleValid))
-			mcp->mcp_dramhole_size = MC_DRAMHOLE_SIZE(&hole);
+		if (MCREG_FIELD_F_ALL(&hole, DramHoleValid))
+			mcp->mcp_dramhole_size = MC_DRAMHOLE_SIZE(&hole, rev);
 	}
 }
 
@@ -729,21 +822,31 @@
 {
 	uint32_t rev = mc->mc_props.mcp_rev;
 	union mcreg_nbcfg nbcfg;
+	union mcreg_nbcap nbcap;
 	union mcreg_sparectl sparectl;
+	boolean_t is_0x10 = MC_REV_MATCH(rev, MC_10_ALL);
 
-	mc->mc_cfgregs.mcr_nbcfg = MCREG_VAL32(&nbcfg) =
-	    mc_pcicfg_get32_nohdl(mc, MC_FUNC_MISCCTL, MC_CTL_REG_NBCFG);
+	mc->mc_cfgregs.mcr_nbcfg = MCREG_VAL32(&nbcfg)
+		= mc_pcicfg_get32_nohdl(mc, MC_FUNC_MISCCTL, MC_CTL_REG_NBCFG);
+	mc->mc_cfgregs.mcr_nbcap = MCREG_VAL32(&nbcap)
+		= mc_pcicfg_get32_nohdl(mc, MC_FUNC_MISCCTL, MC_CTL_REG_NBCAP);
 
-	if (MC_REV_MATCH(rev, MC_F_REVS_FG)) {
-		mc->mc_cfgregs.mcr_sparectl = MCREG_VAL32(&sparectl) =
-		    mc_pcicfg_get32_nohdl(mc, MC_FUNC_MISCCTL,
-		    MC_CTL_REG_SPARECTL);
-
-		if (MCREG_FIELD_F_revFG(&sparectl, SwapDone)) {
+	if (MC_REV_MATCH(rev, MC_F_REVS_FG) || is_0x10) {
+		mc->mc_cfgregs.mcr_sparectl = MCREG_VAL32(&sparectl)
+			= mc_pcicfg_get32_nohdl(mc, MC_FUNC_MISCCTL, MC_CTL_REG_SPARECTL);
+		if (is_0x10) {
+			if (MCREG_FIELD_10_ALL(&sparectl, SwapDone0)) {
 			mc->mc_props.mcp_badcs =
-			    MCREG_FIELD_F_revFG(&sparectl, BadDramCs);
+					MCREG_FIELD_10_ALL(&sparectl, BadDramCs0);
 		}
+			if (MCREG_FIELD_10_ALL(&sparectl, SwapDone1)) {
+				mc->mc_props.mcp_badcs1 =
+					MCREG_FIELD_10_ALL(&sparectl, BadDramCs1);
 	}
+		} else if (MCREG_FIELD_F_revFG(&sparectl, SwapDone)) {
+			mc->mc_props.mcp_badcs = MCREG_FIELD_F_revFG(&sparectl, BadDramCs);
+		}
+	}
 }
 
 static int
@@ -780,17 +883,29 @@
 	union mcreg_csbase base[MC_CHIP_NCS];
 	union mcreg_csmask mask[MC_CHIP_NCS];
 	union mcreg_dramcfg_lo drcfg_lo;
+	union mcreg_dramcfg_lo drcfg_lo1;
 	union mcreg_dramcfg_hi drcfg_hi;
+	union mcreg_dramcfg_hi drcfg_hi1;
 	union mcreg_drammisc drmisc;
 	union mcreg_bankaddrmap baddrmap;
+	union mcreg_bankaddrmap baddrmap1;
+	union mcreg_select_lo select_lo;
+	union mcreg_select_hi select_hi;
 	mc_props_t *mcp = &mc->mc_props;
 	mc_cfgregs_t *mcr = &mc->mc_cfgregs;
 	int maskdivisor;
 	int wide = 0;
 	uint32_t rev = mc->mc_props.mcp_rev;
+	uint32_t ganged = 0;
 	int i;
 	mcamd_hdl_t hdl;
 
+	boolean_t is_0xf_bcde = MC_REV_MATCH(rev, MC_F_REVS_BCDE);
+	boolean_t is_0xf_fg = MC_REV_MATCH(rev, MC_F_REVS_FG);
+	boolean_t is_0x10 = MC_REV_MATCH(rev, MC_10_ALL);
+	boolean_t is_0x11 = MC_REV_MATCH(rev, MC_11_ALL);
+	boolean_t is_0x14 = MC_REV_MATCH(rev, MC_14_ALL);
+
 	mcamd_mkhdl(&hdl);	/* to call into common code */
 
 	/*
@@ -800,30 +915,52 @@
 	 * if we're in 64- or 128-bit MC mode, how the upper chip-selects
 	 * are mapped, which chip-select pairs are using x4 parts, etc.
 	 */
-	MCREG_VAL32(&drcfg_lo) = mc_pcicfg_get32(cfghdl, MC_DC_REG_DRAMCFGLO);
-	MCREG_VAL32(&drcfg_hi) = mc_pcicfg_get32(cfghdl, MC_DC_REG_DRAMCFGHI);
-	mcr->mcr_dramcfglo = MCREG_VAL32(&drcfg_lo);
-	mcr->mcr_dramcfghi = MCREG_VAL32(&drcfg_hi);
+	mcr->mcr_dramcfglo = MCREG_VAL32(&drcfg_lo)
+		= mc_pcicfg_get32(cfghdl, MC_DC_REG_DRAMCFGLO);
+	mcr->mcr_dramcfghi = MCREG_VAL32(&drcfg_hi)
+		= mc_pcicfg_get32(cfghdl, MC_DC_REG_DRAMCFGHI);
 
+	mcp->mcp_ddr3 = is_0x10 ? MCREG_FIELD_10_ALL(&drcfg_hi, Ddr3Mode) : is_0x14;
+	if (is_0x10 || is_0x11 || is_0x14) {
+		mcr->mcr_selectlo = MCREG_VAL32(&select_lo)
+			= mc_pcicfg_get32(cfghdl, MC_DC_REG_SELECT_LO);
+		mcr->mcr_selecthi = MCREG_VAL32(&select_hi)
+			= mc_pcicfg_get32(cfghdl, MC_DC_REG_SELECT_HI);
+		if (is_0x10 || is_0x11) {
+			mcp->mcp_ganged = ganged = MCREG_FIELD_10_ALL(&select_lo, DctGangEn);
+		}
+		if (!ganged) {
+			mcr->mcr_dramcfglo1 = MCREG_VAL32(&drcfg_lo1)
+				= mc_pcicfg_get32(cfghdl, MC_DC_REG_DRAMCFGLO1);
+			mcr->mcr_dramcfghi1 = MCREG_VAL32(&drcfg_hi1)
+				= mc_pcicfg_get32(cfghdl, MC_DC_REG_DRAMCFGHI1);
+		}
+	}
+
 	/*
 	 * Note the DRAM controller width.  The 64/128 bit is in a different
 	 * bit position for revision F and G.
 	 */
-	if (MC_REV_MATCH(rev, MC_F_REVS_FG)) {
+	if (is_0xf_fg || is_0x10) {
 		wide = MCREG_FIELD_F_revFG(&drcfg_lo, Width128);
-	} else {
+	} else if (!(is_0x11 || is_0x14)){
 		wide = MCREG_FIELD_F_preF(&drcfg_lo, Width128);
+	} else {
+		wide = 0;
 	}
 	mcp->mcp_accwidth = wide ? 128 : 64;
+	if (is_0x10 && !ganged) { /* 11h has DCT1, but no 128bit field */
+		mcp->mcp_accwidth1 = MCREG_FIELD_10_ALL(&drcfg_lo1, Width128) ? 128 : 64;
+	}
 
 	/*
-	 * Read Function 2 DRAM Controller Miscellaenous Regsiter for those
+	 * Read Function 2 DRAM Controller Miscellaneous Register for those
 	 * revs that support it.  This include the Mod64Mux indication on
 	 * these revs - for rev E it is in DRAM config low.
 	 */
-	if (MC_REV_MATCH(rev, MC_F_REVS_FG)) {
 		mcr->mcr_drammisc = MCREG_VAL32(&drmisc) =
 		    mc_pcicfg_get32(cfghdl, MC_DC_REG_DRAMMISC);
+	if (is_0xf_fg) {
 		mcp->mcp_mod64mux = MCREG_FIELD_F_revFG(&drmisc, Mod64Mux);
 	} else if (MC_REV_MATCH(rev, MC_F_REV_E)) {
 		mcp->mcp_mod64mux = MCREG_FIELD_F_preF(&drcfg_lo, Mod64BitMux);
@@ -835,28 +972,33 @@
 	 * Prior ro revision F it also tells us whether BankSwizzle mode
 	 * is enabled - in rev F that has moved to dram config hi register.
 	 */
-	mcp->mcp_csbankmapreg = MCREG_VAL32(&baddrmap) =
-	    mc_pcicfg_get32(cfghdl, MC_DC_REG_BANKADDRMAP);
+	mcp->mcp_csbankmapreg = MCREG_VAL32(&baddrmap)
+		= mc_pcicfg_get32(cfghdl, MC_DC_REG_BANKADDRMAP);
+	if ((is_0x10 || is_0x11) && !ganged) {
+		mcp->mcp_csbankmapreg1 = MCREG_VAL32(&baddrmap1)
+			= mc_pcicfg_get32(cfghdl, MC_DC_REG_BANKADDRMAP1);
+	}
 
 	/*
 	 * Determine whether bank swizzle mode is active.  Bank swizzling was
 	 * introduced as an option in rev E,  but the bit that indicates it
 	 * is enabled has moved in revs F/G.
+	 * 10h, 11h: BKDG says that the swizzle bit should be set for both DCTs, if
+	 * in unganged mode. If in ganged mode, a priori both regs need to have the
+	 * same value. So we do not need a mcp_bnkswzl1 or ask &drcfg_hi1.
 	 */
 	if (MC_REV_MATCH(rev, MC_F_REV_E)) {
-		mcp->mcp_bnkswzl =
-		    MCREG_FIELD_F_preF(&baddrmap, BankSwizzleMode);
-	} else if (MC_REV_MATCH(rev, MC_F_REVS_FG)) {
-		mcp->mcp_bnkswzl = MCREG_FIELD_F_revFG(&drcfg_hi,
-		    BankSwizzleMode);
+		mcp->mcp_bnkswzl = MCREG_FIELD_F_preF(&baddrmap, BankSwizzleMode);
+	} else {
+		mcp->mcp_bnkswzl = MCREG_FIELD_F_revFG(&drcfg_hi, BankSwizzleMode);
 	}
 
 	/*
 	 * Read the DRAM CS Base and DRAM CS Mask registers.  Revisions prior
-	 * to F have an equal number of base and mask registers; revision F
-	 * has twice as many base registers as masks.
+	 * to F have an equal number of base and mask registers; revision F and
+	 * later have twice as many base registers as masks.
 	 */
-	maskdivisor = MC_REV_MATCH(rev, MC_F_REVS_FG) ? 2 : 1;
+	maskdivisor = is_0xf_bcde ? 1 : 2;
 
 	mc_prop_read_pair(cfghdl,
 	    (uint32_t *)base, MC_DC_REG_CSBASE_0, MC_CHIP_NCS,
@@ -874,15 +1016,17 @@
 		size_t sz;
 		int csbe, spare, testfail;
 
-		if (MC_REV_MATCH(rev, MC_F_REVS_FG)) {
-			csbe = MCREG_FIELD_F_revFG(&base[i], CSEnable);
-			spare = MCREG_FIELD_F_revFG(&base[i], Spare);
-			testfail = MCREG_FIELD_F_revFG(&base[i], TestFail);
-		} else {
+		if (is_0xf_bcde) {
 			csbe = MCREG_FIELD_F_preF(&base[i], CSEnable);
 			spare = 0;
 			testfail = 0;
+		} else {
+			csbe = MCREG_FIELD_F_revFG(&base[i], CSEnable);
+			if (!(is_0x11 || is_0x14)) {
+				spare = MCREG_FIELD_F_revFG(&base[i], Spare);
 		}
+			testfail = MCREG_FIELD_F_revFG(&base[i], TestFail);
+		}
 
 		/* Testing hook */
 		if (testfail_mcnum != -1 && testfail_csnum != -1 &&
@@ -1004,13 +1148,34 @@
  */
 
 static const mc_bind_map_t mc_bind_map[] = {
-	{ MC_FUNC_HTCONFIG_BINDNM, MC_FUNC_HTCONFIG,
+	{ MC_FUNC_HTCONFIG_BINDNM_F, MC_FUNC_HTCONFIG,
 	    "AMD Memory Controller (HT Configuration)", mc_mkprops_htcfg },
-	{ MC_FUNC_ADDRMAP_BINDNM, MC_FUNC_ADDRMAP,
+	{ MC_FUNC_ADDRMAP_BINDNM_F, MC_FUNC_ADDRMAP,
 	    "AMD Memory Controller (Address Map)", mc_mkprops_addrmap },
-	{ MC_FUNC_DRAMCTL_BINDNM, MC_FUNC_DRAMCTL,
+	{ MC_FUNC_DRAMCTL_BINDNM_F, MC_FUNC_DRAMCTL,
 	    "AMD Memory Controller (DRAM Controller & HT Trace)",
 	    mc_mkprops_dramctl },
+	{ MC_FUNC_HTCONFIG_BINDNM_10, MC_FUNC_HTCONFIG,
+	    "AMD Memory Controller (HT Configuration)", mc_mkprops_htcfg },
+	{ MC_FUNC_ADDRMAP_BINDNM_10, MC_FUNC_ADDRMAP,
+	    "AMD Memory Controller (Address Map)", mc_mkprops_addrmap },
+	{ MC_FUNC_DRAMCTL_BINDNM_10, MC_FUNC_DRAMCTL,
+	    "AMD Memory Controller (DRAM Controller & HT Trace)",
+	    mc_mkprops_dramctl },
+	{ MC_FUNC_HTCONFIG_BINDNM_11, MC_FUNC_HTCONFIG,
+	    "AMD Memory Controller (HT Configuration)", mc_mkprops_htcfg },
+	{ MC_FUNC_ADDRMAP_BINDNM_11, MC_FUNC_ADDRMAP,
+	    "AMD Memory Controller (Address Map)", mc_mkprops_addrmap },
+	{ MC_FUNC_DRAMCTL_BINDNM_11, MC_FUNC_DRAMCTL,
+	    "AMD Memory Controller (DRAM Controller & HT Trace)",
+	    mc_mkprops_dramctl },
+	{ MC_FUNC_HTCONFIG_BINDNM_14, MC_FUNC_HTCONFIG,
+	    "AMD Memory Controller (HT Configuration)", mc_mkprops_htcfg },
+	{ MC_FUNC_ADDRMAP_BINDNM_14, MC_FUNC_ADDRMAP,
+	    "AMD Memory Controller (Address Map)", mc_mkprops_addrmap },
+	{ MC_FUNC_DRAMCTL_BINDNM_14, MC_FUNC_DRAMCTL,
+	    "AMD Memory Controller (DRAM Controller & HT Trace)",
+	    mc_mkprops_dramctl },
 	NULL
 };
 
@@ -1054,10 +1219,13 @@
 	mc_cs_t *mccs;
 	hrtime_t tmax;
 	int i = 0;
+	boolean_t is_0x10 = MC_REV_MATCH(mcp->mcp_rev, MC_10_ALL);
 
 	ASSERT(RW_WRITE_HELD(&mc_lock));
 
-	if (!MC_REV_MATCH(mcp->mcp_rev, MC_F_REVS_FG))
+	/* for family 0x10 ganged mode is similar to FG - TODO: unganged mode */
+	if (!(MC_REV_MATCH(mcp->mcp_rev, MC_F_REVS_FG) 
+			|| (is_0x10 && mcp->mcp_ganged)))
 		return (ENOTSUP);	/* MC rev does not offer online spare */
 	else if (mcp->mcp_sparecs == MC_INVALNUM)
 		return (ENODEV);	/* Supported, but no spare configured */
@@ -1082,12 +1250,18 @@
 		return (ENODEV);	/* DRAM scrubber not enabled */
 
 	/*
-	 * Read Online Spare Comtrol Register again, just in case our
+	 * Read Online Spare Control Register again, just in case our
 	 * state does not reflect reality.
 	 */
 	MCREG_VAL32(&sparectl) = mc_pcicfg_get32_nohdl(mc, MC_FUNC_MISCCTL,
 	    MC_CTL_REG_SPARECTL);
 
+	/* In 0x10 in _ganged mode_ $field0: is mirrored to $field1 and the same as
+	 * $field in FG (see BDKG 10h 2.8.1 DCT Configuration Registers).
+	 * If the check for "0x10 only if ganged" at the start of this function
+	 * gets changed, code below must check wrt. DCT0/DCT1 config and ganging,
+	 * to do the right thing.
+	 */
 	if (MCREG_FIELD_F_revFG(&sparectl, SwapDone))
 		return (EBUSY);
 
@@ -1350,6 +1524,7 @@
 	mc->mc_props.mcp_num = chipid;
 	mc->mc_props.mcp_sparecs = MC_INVALNUM;
 	mc->mc_props.mcp_badcs = MC_INVALNUM;
+	mc->mc_props.mcp_badcs1 = MC_INVALNUM;
 
 	mc->mc_props.mcp_rev = cmi_hdl_chiprev(hdl);
 	mc->mc_revname = cmi_hdl_chiprevstr(hdl);
@@ -1463,6 +1638,8 @@
 		break;
 	}
 
+	/* TODO: check for 0x10 - probably do not apply except erratum 388? */
+
 	/*
 	 * OPTERON_ERRATUM_99:
 	 * This erratum applies on revisions D and earlier.
@@ -1690,7 +1867,7 @@
 			 * registered ECC-capable DIMMs, if there is memory
 			 * present on a node but no ECC there then we'll assume
 			 * ECC is disabled for all nodes and we will not enable
-			 * the scrubber and wll also disable the software
+			 * the scrubber and will also disable the software
 			 * memscrub thread.
 			 */
 			rc = 1;
--- onnv-129.orig/usr/src/uts/intel/io/mc-amd/mcamd.h	Tue Dec  1 09:42:07 2009
+++ onnv-129/usr/src/uts/intel/io/mc-amd/mcamd.h	Sat Mar 12 01:26:06 2011
@@ -70,10 +70,24 @@
 #define	MC_FUNC_DEVIMAP		MC_FUNC_DRAMCTL
 #define	MC_FUNC_NUM		(MC_FUNC_MISCCTL + 1)
 
+/* deprecate */
 #define	MC_FUNC_HTCONFIG_BINDNM	"pci1022,1100"
 #define	MC_FUNC_ADDRMAP_BINDNM	"pci1022,1101"
 #define	MC_FUNC_DRAMCTL_BINDNM	"pci1022,1102"
 
+#define	MC_FUNC_HTCONFIG_BINDNM_F	"pci1022,1100"
+#define	MC_FUNC_ADDRMAP_BINDNM_F	"pci1022,1101"
+#define	MC_FUNC_DRAMCTL_BINDNM_F	"pci1022,1102"
+#define	MC_FUNC_HTCONFIG_BINDNM_10	"pci1022,1200"
+#define	MC_FUNC_ADDRMAP_BINDNM_10	"pci1022,1201"
+#define	MC_FUNC_DRAMCTL_BINDNM_10	"pci1022,1202"
+#define	MC_FUNC_HTCONFIG_BINDNM_11	"pci1022,1300"
+#define	MC_FUNC_ADDRMAP_BINDNM_11	"pci1022,1301"
+#define	MC_FUNC_DRAMCTL_BINDNM_11	"pci1022,1302"
+#define	MC_FUNC_HTCONFIG_BINDNM_14	"pci1022,1700"
+#define	MC_FUNC_ADDRMAP_BINDNM_14	"pci1022,1701"
+#define	MC_FUNC_DRAMCTL_BINDNM_14	"pci1022,1702"
+
 typedef struct mc_func {
 	uint_t mcf_instance;
 	dev_info_t *mcf_devi;
@@ -162,12 +176,17 @@
 	mcamd_prop_t mcp_ilsel;		/* interleave select */
 	mcamd_prop_t mcp_csintlvfctr;	/* cs bank interleave factor */
 	mcamd_prop_t mcp_dramhole_size;	/* DRAM Hole Size */
-	mcamd_prop_t mcp_accwidth;	/* dram access width (64 or 128) */
-	mcamd_prop_t mcp_csbankmapreg;	/* chip-select bank mapping reg */
+	mcamd_prop_t mcp_accwidth;	/* dram access width (64 or 128) DCT0 */
+	mcamd_prop_t mcp_accwidth1;	/* dram access width (64 or 128) DCT1 (10h, 11h) */
+	mcamd_prop_t mcp_csbankmapreg;	/* cs bank mapping reg  DCT0 */
+	mcamd_prop_t mcp_csbankmapreg1;	/* cs bank mapping reg  DCT1 (10h,11h) */
 	mcamd_prop_t mcp_bnkswzl;	/* BankSwizzle enabled */
-	mcamd_prop_t mcp_mod64mux;	/* Mismtached DIMMs support enabled */
+	mcamd_prop_t mcp_mod64mux;	/* Mismatched DIMMs support enabled */
 	mcamd_prop_t mcp_sparecs;	/* cs# replaced by online spare */
-	mcamd_prop_t mcp_badcs;		/* cs# replaced by online spare */
+	mcamd_prop_t mcp_badcs;		/* cs# replaced by online spare - DCT0 */
+	mcamd_prop_t mcp_badcs1;	/* cs# replaced by online spare - DCT1 (10h)*/
+	mcamd_prop_t mcp_ganged;	/* 1=Dimms are accessed in ganged mode */
+	mcamd_prop_t mcp_ddr3;		/* 1=DDR3 Dimms in use, 0=DDR2 */
 } mc_props_t;
 
 /*
@@ -175,19 +194,29 @@
  */
 typedef struct mc_cfgregs {
 	mcamd_cfgreg_t mcr_htroute[MC_CHIP_MAXNODES];
-	mcamd_cfgreg_t mcr_htnodeid;
-	mcamd_cfgreg_t mcr_htunitid;
-	mcamd_cfgreg_t mcr_drambase;
-	mcamd_cfgreg_t mcr_dramlimit;
-	mcamd_cfgreg_t mcr_dramhole;
-	mcamd_cfgreg_t mcr_dramcfglo;
-	mcamd_cfgreg_t mcr_dramcfghi;
-	mcamd_cfgreg_t mcr_drammisc;
-	mcamd_cfgreg_t mcr_nbcfg;
-	mcamd_cfgreg_t mcr_sparectl;
-	mcamd_cfgreg_t mcr_scrubctl;
-	mcamd_cfgreg_t mcr_scrubaddrlo;
-	mcamd_cfgreg_t mcr_scrubaddrhi;
+	mcamd_cfgreg_t mcr_htnodeid;	/* node 0 */
+	mcamd_cfgreg_t mcr_htnodeid1;	/* node 1 - 10h */
+	mcamd_cfgreg_t mcr_htunitid;	/* 0Fh, 10h, 11h */
+	mcamd_cfgreg_t mcr_drambase;		/* all */
+	mcamd_cfgreg_t mcr_drambase_hi;		/* 10h only */
+	mcamd_cfgreg_t mcr_dramlimit;		/* all */
+	mcamd_cfgreg_t mcr_dramlimit_hi;	/* 10h only */
+	mcamd_cfgreg_t mcr_dramhole;		/* all */
+	mcamd_cfgreg_t mcr_dramcfglo;		/* all */
+	mcamd_cfgreg_t mcr_dramcfglo1;		/* DCT1 - (10h, 11h) */
+	mcamd_cfgreg_t mcr_dramcfghi;		/* all */
+	mcamd_cfgreg_t mcr_dramcfghi1;		/* DCT1 - (10h,11h) */
+	mcamd_cfgreg_t mcr_drammisc;	/* DCT0. For 10h, 11h we do not have
+		* mcr_drammisc1 for DCT1, since it provides "DramEnabled" only, which
+		* is available via/has same value as F2x110. */
+	mcamd_cfgreg_t mcr_nbcfg;			/* all */
+	mcamd_cfgreg_t mcr_sparectl;		/* revFG, 10h */
+	mcamd_cfgreg_t mcr_scrubctl;		/* 0Fh, 10h, 11h */
+	mcamd_cfgreg_t mcr_scrubaddrlo;		/* 10h, 11h, 14h */
+	mcamd_cfgreg_t mcr_scrubaddrhi;		/* 10h, 11h, 14h */
+	mcamd_cfgreg_t mcr_selectlo;		/* 10h, 11h, 14h */
+	mcamd_cfgreg_t mcr_selecthi;		/* 10h, 11h, 14h */
+	mcamd_cfgreg_t mcr_nbcap;			/* all */
 } mc_cfgregs_t;
 
 struct mc {
--- onnv-129.orig/usr/src/uts/intel/io/mc-amd/mcamd_dimmcfg.c	Tue Dec  1 09:42:07 2009
+++ onnv-129/usr/src/uts/intel/io/mc-amd/mcamd_dimmcfg.c	Wed Mar  9 22:14:55 2011
@@ -212,9 +212,14 @@
  *
  *		Number of dimms of given type supported per dram channel
  * Package	Reg'd DIMM	4-rank reg'd	Unbuffered	SO-DIMMs
- * F(1207)	4		2		0		0
- * AM2		0		0		2		1
- * S1g1		0		0		0		1
+ * F(1207)		4		2		0		0		0x0f
+ * Fr2(1207)	4		2		0		0		0x10 
+ * G34,C32		2|3		1|2		0		0		0x10
+ * AM2			0		0		2		1		0x0f
+ * AM2r2,AM3	0		0		2		1		0x10
+ * S1g2			0		0		2		1		0x11	// max. 3 phys.
+ * S1g3,S1g4	0		0		2		1		0x10	// max. 3 phys.
+ * S1g1			0		0		0		1		0x0f
  */
 
 /*
@@ -323,9 +328,132 @@
     { S1g1,	7, DCFG_S4,		1, { { CH_B, 0, 3 } } }
 };
 
+/*
+ * Family 0x10 mapping.
+ * AM2r2/AM3/ASB2 and S1g3/S1g4 (Desktop CPUs) do not neither support
+ * registered nor QR, but unbuffered and SO-DIMMs. On the other side
+ * F1207, C32 and G34 do support registered and QR, but not unbuffered or
+ * SO-DIMMs.
+ * Ganged mode is not supported for S1g3, S1g4, ASB2, and G34 (unganged:
+ * a logical DIMM is equivalent to a 64-bit physical DIMM and each channel is
+ * controlled by a different DCT).
+ * Also they support max. 1 SO-DIMM per DCT, but there is no easy way on 0x10
+ * to determine, whether the used DIMM is SO or not. Thus this matrix is as 
+ * weak as the one for NPT, i.e. SR/DR (and on 0x10 QR) SO-DIMMs will be 
+ * covered by DCFG_N, which allows more than one phys DIMM per channel.
+ * For G34 internal node 1 the channel is the same of node 0 with an offset
+ * of 2, i.e. if CH_A for G34 is returned, this applies to internal node 0,
+ * the corresponding channel for internal node 1 would than be CH_C.
+ */
+static const struct mcdcfg_csmapline csmap_0x10[] = {
+    /*
+     * Pkgs   base dramconfig	     ldimm   cs A              cs B
+     *
+     * Base reg 0 (mask 0)
+     */
+    { SKT_0x10_OPTERON,	0, DCFG_N | DCFG_R4, 0, { { CH_A, 0, 0 }, { CH_B, 0, 0 } } },
+    { SKT_0x10_DESKTOP,	0, DCFG_N, 0, { { CH_A, 0, 0 }, { CH_B, 0, 0 } } },
+    /*
+     * Base reg 1 (mask 0)
+     */
+    { SKT_0x10_OPTERON,	1, DCFG_N | DCFG_R4, 0, { { CH_A, 0, 1 }, { CH_B, 0, 1 } } },
+    { SKT_0x10_DESKTOP,	1, DCFG_N, 0, { { CH_A, 0, 1 }, { CH_B, 0, 1 } } },
+    /*
+     * Base reg 2 (mask 1)
+     */
+    { SKT_0x10_OPTERON,	2, DCFG_N | DCFG_R4, 1, { { CH_A, 1, 0 }, { CH_B, 1, 0 } } },
+    { SKT_0x10_DESKTOP,	2, DCFG_N, 1, { { CH_A, 1, 0 }, { CH_B, 1, 0 } } },
+    /*
+     * Base reg 3 (mask 1)
+     */
+    { SKT_0x10_OPTERON,	3, DCFG_N | DCFG_R4, 1, { { CH_A, 1, 1 }, { CH_B, 1, 1 } } },
+    { (SKT_0x10_DESKTOP & ~(S1g3)), 3, DCFG_N, 1, { { CH_A, 1, 1 }, { CH_B, 1, 1 } } },
+    { S1g3, 3, DCFG_N, 1, { { CH_A, 1, 1 } } },
+    /*
+     * Base reg 4 (mask 2)
+     */
+    { SKT_0x10_OPTERON & ~(C32), 4, DCFG_N, 2, { { CH_A, 2, 0 }, { CH_B, 2, 0 } } },
+    { SKT_0x10_OPTERON & ~(C32), 4, DCFG_R4, 0, { { CH_A, 2, 0 }, { CH_B, 2, 0 } } },
+    { C32, 4, DCFG_N, 2, { { CH_A, 0, 2 }, { CH_B, 0, 2 } } },
+    { C32, 4, DCFG_R4, 0, { { CH_A, 0, 2 }, { CH_B, 0, 2 } } },
+    /*
+     * Base reg 5 (mask 2)
+     */
+    { SKT_0x10_OPTERON & ~(C32), 5, DCFG_N, 2, { { CH_A, 2, 1 }, { CH_B, 2, 1 } } },
+    { SKT_0x10_OPTERON & ~(C32), 5, DCFG_R4, 0, { { CH_A, 2, 1 }, { CH_B, 2, 1 } } },
+    { C32, 5, DCFG_N, 2, { { CH_A, 0, 3 }, { CH_B, 0, 3 } } },
+    { C32, 5, DCFG_R4, 0, { { CH_A, 0, 3 }, { CH_B, 0, 3 } } },
+    /*
+     * Base reg 6 (mask 3)
+     */
+    { SKT_0x10_OPTERON & ~(C32), 6, DCFG_N, 3, { { CH_A, 3, 0 }, { CH_B, 3, 0 } } },
+    { SKT_0x10_OPTERON & ~(C32), 6, DCFG_R4, 1, { { CH_A, 3, 0 }, { CH_B, 3, 0 } } },
+    { C32, 6, DCFG_N, 3, { { CH_A, 1, 2 }, { CH_B, 1, 2 } } },
+    { C32, 6, DCFG_R4, 1, { { CH_A, 1, 2 }, { CH_B, 1, 2 } } },
+    /*
+     * Base reg 7 (mask 3)
+     */
+    { SKT_0x10_OPTERON & ~(C32), 7, DCFG_N, 3, { { CH_A, 3, 1 }, { CH_B, 3, 1 } } },
+    { SKT_0x10_OPTERON & ~(C32), 7, DCFG_R4, 1, { { CH_A, 3, 1 }, { CH_B, 3, 1 } } },
+    { C32, 7, DCFG_N , 3, { { CH_A, 1, 3 }, { CH_B, 1, 3 } } },
+    { C32, 7, DCFG_R4, 1, { { CH_A, 1, 3 }, { CH_B, 1, 3 } } },
+};
+
+/*
+ * Family 0x11 mapping.
+ * S1g2 does neither support registered nor QR *DIMMs, max. 2 SO-DIMMS (one
+ * on each DCT) and max. 3 unbuffered DIMMs (2 on DCT0, 1 on DCT1).
+ * Same special note wrt. SO-DIMM as for 0x10 family.
+ */
+static const struct mcdcfg_csmapline csmap_0x11[] = {
+    /*
+     * Pkgs   base dramconfig	     ldimm   cs A              cs B
+     *
+     * Base reg 0 (mask 0)
+     */
+    { Sg1g2,	0, DCFG_N, 0, { { CH_A, 0, 0 }, { CH_B, 0, 0 } } },
+    /*
+     * Base reg 1 (mask 0)
+     */
+    { Sg1g2,	1, DCFG_N, 0, { { CH_A, 0, 1 }, { CH_B, 0, 1 } } },
+    /*
+     * Base reg 2 (mask 1)
+     */
+    { Sg1g2,	2, DCFG_N, 1, { { CH_A, 1, 0 }, { CH_B, 1, 0 } } },
+    /*
+     * Base reg 3 (mask 1)
+     */
+    { Sg1g2,	3, DCFG_N, 1, { { CH_A, 1, 1 } } },
+};
+
+/*
+ * Family 0x14 mapping.
+ * FT1 does not support neither registered nor x4 nor QR DIMMs.
+ */
+static const struct mcdcfg_csmapline csmap_0x14[] = {
+    /*
+     * Pkgs   base dramconfig	     ldimm   cs A              cs B
+     *
+     * Base reg 0 (mask 0)
+     */
+    { FT1,	0, DCFG_N, 0, { { CH_A, 0, 0 } } },
+    /*
+     * Base reg 1 (mask 0)
+     */
+    { FT1,	1, DCFG_N, 0, { { CH_A, 0, 1 } } },
+    /*
+     * Base reg 2 (mask 1)
+     */
+    { FT1,	2, DCFG_N, 1, { { CH_A, 1, 0 } } },
+    /*
+     * Base reg 3 (mask 1)
+     */
+    { FT1,	3, DCFG_N, 1, { { CH_A, 1, 1 } } },
+};
+
 /* END CSTYLED */
 
-#define	DCFG_NTBL	4
+#define	DCFG_NTBL	7
 
 static const struct {
 	uint32_t revmask;		/* applicable chip revs */
@@ -340,9 +468,143 @@
 	{ MC_F_REVS_FG, 0, &csmap_nomod64mux_fg[0],
 	    sizeof (csmap_nomod64mux_fg) / sizeof (struct mcdcfg_csmapline) },
 	{ MC_F_REVS_FG, 1, &csmap_mod64mux_fg[0],
-	    sizeof (csmap_mod64mux_fg) / sizeof (struct mcdcfg_csmapline) }
+	    sizeof (csmap_mod64mux_fg) / sizeof (struct mcdcfg_csmapline) },
+	{ MC_10_ALL, 0, &csmap_0x10[0],
+	    sizeof (csmap_0x10) / sizeof (struct mcdcfg_csmapline) },
+	{ MC_11_ALL, 0, &csmap_0x11[0],
+	    sizeof (csmap_0x11) / sizeof (struct mcdcfg_csmapline) },
+	{ MC_14_ALL, 0, &csmap_0x14[0],
+	    sizeof (csmap_0x14) / sizeof (struct mcdcfg_csmapline) }
 };
 
+#define GET_TOPONUM(a)	((a) >> 24)
+#define GET_NDIMMS(a)	(((a) >> 20) & 0xf)
+#define GET_LDIMM(a)	(((a) >> 16) & 0xf)
+#define GET_CHAN_0(a)	(((a) >> 12) & 0xf)
+#define GET_CHAN_1(a)	(((a) >>  8) & 0xf)
+#define GET_SLOT(a)		(((a) >> 4) & 0xf)
+#define GET_RANK(a)		((a) & 0xf)
+
+/**
+ * @return -1 if given parameter(s) doesn't make sense at all, otherwise:
+ *	   [31:24] toponum for the 1st channel - this implies toponum for the 
+ *	           2nd channel as well: value + 1
+ *	   [23:20] ndimms (current range: 1..2)
+ *	   [19:16] ldim (current range: 0..7)
+ *	   [15:12] 1st channel, 0 == 'A' ... , 0xf == n/a, (current range: A..D)
+ *	   [11:8 ] 2dn channel, 0 == 'A' ... , 0xf == n/a, (current range: A..D)
+ *	   [ 7:4 ] slot number (current range: 0..3)
+ *	   [ 3:0 ] rank number (current range: 0..3)
+ *   NOTE: Since the {slot,rank} is always the same on each channel for
+ *         basenum N, there is no need to store this pair twice.
+ */
+uint32_t
+mcdcfg_lookup2(uint32_t rev, int mod64mux, int accwidth, int basenum,
+	uint32_t pkg, int r4, int s4, int internalNode)
+{
+	if ((accwidth != 64 && accwidth != 128) || (r4 && s4) || (basenum > 7)) {
+		return -1;
+	}
+	ldimm = basenum >> (s4 ? 2 : 1); /* Fn2x94[17] QR SO-DIMM, rev FG only */
+	if (r4) { /* Fn2x94[18] QR-RDimm, rev FG and 0x10 only */
+		ldimm &= 0x1;
+	}
+	/* Pin the default AMD layout */
+	csm = (ldimm << 16) | (CH_A << 12) | (CH_B <<  8 )
+			| ((basenum >> 1) <<  4) | (basenum & 0x1);
+
+	/* sort out the obviously invalid stuff and adjust to special impls */
+	/* maxRanks = serverSocket ? 16 : 8; */
+	if (mod64mux) {
+		if (basenum < 4) {
+			csm |= 0x0f00; /* mask out 2nd channel */
+		} else {
+			csm |= 0xf000; /* mask out 1st channel */
+			csm &= 0xffffff00; /* reassign SLOT/RANK */
+			csm |= ((basenum & 0x2) << 3) | (basenum & 0x1);
+		}
+		switch (pkg) {
+			case SKT_939:
+				if (r4 || s4) return -1; /* no QRs */
+				break;
+			case AM2:
+			case S1g1:
+				if (r4) return -1; /* doesn't this imply !s4 as well ? */
+				break;
+			default:
+				return -1; /* mismatch mode unsupported */
+		}
+	} else {
+		if (s4 && (basenum > 3)) {
+			return -1;
+		}
+		switch (pkg) {
+			case SKT_754: /* phys: max. 3 unbuff || 4 reg. on lidded parts */
+				if (s4 || r4) return -1; /* no QRs */
+				if (basenum > 3) csm |= 0x0f00; /* mask out 2nd channel */
+				break;
+			case SKT_939: /* phys: max. 4 unbuff 128b || 2 unbuff 64b mode */
+				if (basenum > 3 || r4 || s4) return -1; /* no QRs */
+				break;
+			/* case 940: phys: max. 8 in 128b || 4 in 64b mode */
+			/* case F1207: ok */
+			case AM2:
+			case ASB1:
+				if (basenam > 3) return -1; 
+				break;
+			case S1g1:
+				if (basenum > 3) return -1;
+				csm &= 0xffffff00; /* reassign SLOT/RANK */
+				csm |= basenum;
+				break;
+			case S1g2:
+				if (basenme > 3) return -1;
+				/* maxRanks = 6 + 1; */
+				if (basename == 3) {
+					csm |= 0x0f00; /* mask out 2nd channel */
+					ndimm = 1;    /* just to be sure (onboard DIMM) */
+				}
+				break;
+			case S1g3:
+				if (basenum > 2 || s4) return -1;
+				/* maxRanks = 6; */
+				break;
+			case AM2r2:
+			case AM3:
+			case ASB2:
+				if (basenum > 3 || s4) return -1;
+				break;
+			case C32:
+				if (basenum > 3) {
+					csm &= 0xffffff00; /* reassign SLOT/RANK */
+					csm |= ((basenum >> 1)  << 4) | (basenum >> 1);
+				}
+				break;
+			case G34:
+				if (internalNode == 1) {
+					csm |= 0x2200;	/* add 2 for each CH: A -> C, B -> D */
+				}
+				break;
+			case FT1:
+				if (basenum > 3 || s4 || r4) return -1;
+				csm |= 0x0f00; /* mask out 2nd channel */
+				break;
+		}
+	}
+	csm |= ndimm << 20;
+	/* determine toponumber for the 1st channel - keep backward compat */
+	pkg = internalNode > 0 ? ((1 << (internalNode-1)) << 4) : 0;
+	pkg |= (r4 || s4 || !mux)
+		? ((ldimm & 0x7) < 1)		/* ldimm based - & 0x7 for paranoids ;-) */
+		: ((csm >> 4) & 0x7) < 1;	/* slot based - & 0x7 for paranoids ;-) */
+	csm |= (pkg << 24);
+	return csm;
+}
+
+/**
+ * NOTE: For socket G34 internal node 1 channel A the receiver needs to
+ *       substitute channel A with C and channel B with D!
+ */
 int
 mcdcfg_lookup(uint32_t rev, int mod64mux, int accwidth, int basenum,
     uint32_t pkg, int r4, int s4, mcdcfg_rslt_t *rsltp)
@@ -360,7 +622,7 @@
 	if ((accwidth != 64 && accwidth != 128) || (r4 != 0 && s4 != 0))
 		return (-1);
 
-	for (i = 0; i < DCFG_NTBL; i++) {
+	for (i = DCFG_NTBL - 1; i != 0; i--) {
 		if (MC_REV_MATCH(rev, csmap_tbls[i].revmask) &&
 		    ismux == csmap_tbls[i].mod64mux) {
 			csm = csmap_tbls[i].map;
@@ -407,7 +669,70 @@
 /*
  * Given a chip-select line and package type return the chip-select line
  * pin label for that package type.
+ *
+ * @param pkg  package type (determines the format of the result)
+ * @param csm the result of #mcdcfg_lookup2(). The first channel != 0xf
+ *            will be used. If all channels are 0xf, this function does nothing.
+ * @param buf where to store the result
+ * @param buflen storage size.
+ * @return 0 if nothing was written to the <var>buf</var>, 1 otherwise.
+ * @see snprintf()
  */
+int
+mcdcfg_csname2(uint32_t pkg, int csm, char *buf, int buflen)
+{
+	int csnum, chan;
+	
+	chan = GET_CHAN_0(csm);
+	if (chan == 0xf) {
+		chan = GET_CHAN_1(csm);
+	}
+	if (chan == 0xf) {
+		return 0;
+	}
+	switch (pkg) {
+		/* Format is: MEMCS_L[{0..7}].  There is only channel A.  */
+		case X86_SOCKET_754:
+			csnum = (GET_SLOT(csm) << 1) | GET_RANK(csm);
+			(void) snprintf(buf, buflen, "MEMCS_L%d",csnum);
+			break;
+		/* Format is: MEMCS_L[{0..7}] */
+		case X86_SOCKET_940:
+			csnum = (GET_SLOT(csm) << 1) | GET_RANK(csm);
+			(void) snprintf(buf, buflen, "MEMCS_L%d (channel %c)", csnum,
+				'A' + chan);
+			break;
+		/* Format is: MEMCS_{1,2}{L,H}_L[{1,0}] */
+		case X86_SOCKET_939:
+			(void) snprintf(buf, buflen, "MEMCS_%d%c_L[%d]",
+			    GET_SLOT(csm) + 1, 'A' + chan, GET_RANK(csm));
+			break;
+		/* Format is: M{D:A}{0,1,2,3}_CS_L[{0,1,2,3}] */
+		case X86_SOCKET_F1207:
+		case X86_SOCKET_AM2:
+		case X86_SOCKET_S1g1:
+		case X86_SOCKET_S1g2:
+		case X86_SOCKET_S1g3:
+		case X86_SOCKET_AM2R2:
+		case X86_SOCKET_AM3:
+		case X86_SOCKET_G34:
+		case X86_SOCKET_ASB2:
+		case X86_SOCKET_C32:
+		case X86_SOCKET_FT1:
+			(void) snprintf(buf, buflen, "M%c%d_CS_L[%d]",
+				'A' + chan, GET_SLOT(csm), GET_RANK(csm));
+			break;
+		default:
+			(void) snprintf(buf, buflen, "Unknown");
+			break;
+	}
+	return 1;
+}
+
+/*
+ * Given a chip-select line and package type return the chip-select line
+ * pin label for that package type.
+ */
 void
 mcdcfg_csname(uint32_t pkg, const mcdcfg_csl_t *cslp, char *buf, int buflen)
 {
@@ -451,14 +776,22 @@
 	case X86_SOCKET_F1207:
 	case X86_SOCKET_AM2:
 	case X86_SOCKET_S1g1:
+	case X86_SOCKET_S1g2:
+	case X86_SOCKET_S1g3:
+	case X86_SOCKET_AM2R2:
+	case X86_SOCKET_AM3:
+	case X86_SOCKET_G34:
+	case X86_SOCKET_ASB2:
+	case X86_SOCKET_C32:
+	case X86_SOCKET_FT1:
 		/*
-		 * Format is: M{B,A}{0,1,2,3}_CS_L[{0,1,2,3}]
+		 * Format is: M{D:A}{0,1,2,3}_CS_L[{0,1,2,3}]
 		 *		{B,A} - channel
 		 *		{0,1,2,3} - slot on channel
 		 *		{0,1,2,3} - rank
 		 */
-		(void) snprintf(buf, buflen, "M%s%d_CS_L[%d]",
-		    cslp->csl_chan == CH_A ? "A" : "B",
+		(void) snprintf(buf, buflen, "M%c%d_CS_L[%d]",
+		    cslp->csl_chan + 'A',
 		    cslp->csl_slot,
 		    cslp->csl_rank);
 		break;
