summaryrefslogtreecommitdiff
path: root/usr/src/uts/intel/sys
diff options
context:
space:
mode:
authorgavinm <none@none>2006-10-05 17:39:16 -0700
committergavinm <none@none>2006-10-05 17:39:16 -0700
commit8a40a695ee676a322b094e9afe5375567bfb51e3 (patch)
treeb59160470b2412ad6a4afc8cf53da85376e7a18a /usr/src/uts/intel/sys
parent6fec36253a9fa8abfdf231fb3ea9fc656a2ff872 (diff)
downloadillumos-joyent-8a40a695ee676a322b094e9afe5375567bfb51e3.tar.gz
PSARC 2006/564 FMA for Athlon 64 and Opteron Rev F/G Processors
PSARC 2006/566 eversholt language enhancements: confprop_defined 6362846 eversholt doesn't allow dashes in pathname components 6391591 AMD NB config should not set NbMcaToMstCpuEn 6391605 AMD DRAM scrubber should be disabled when errata #99 applies 6398506 memory controller driver should not bother to attach at all on rev F 6424822 FMA needs to support AMD family 0xf revs F and G 6443847 FMA x64 multibit ChipKill rules need to follow MQSC guidelines 6443849 Accrue inf_sys and s_ecc ECC errors against memory 6443858 mc-amd can free unitsrtr before usage in subsequent error path 6443891 mc-amd does not recognise mismatched dimm support 6455363 x86 error injector should allow addr option for most errors 6455370 Opteron erratum 101 only applies on revs D and earlier 6455373 Identify chip-select lines used on a dimm 6455377 improve x64 quadrank dimm support 6455382 add generic interfaces for amd chip revision and package/socket type 6468723 mem scheme fmri containment test for hc scheme is busted 6473807 eversholt could use some mdb support 6473811 eversholt needs a confprop_defined function 6473819 eversholt should show version of rules active in DE 6475302 ::nvlist broken by some runtime link ordering changes
Diffstat (limited to 'usr/src/uts/intel/sys')
-rw-r--r--usr/src/uts/intel/sys/fm/cpu/AMD.h32
-rw-r--r--usr/src/uts/intel/sys/mc.h17
-rw-r--r--usr/src/uts/intel/sys/mc_amd.h694
-rw-r--r--usr/src/uts/intel/sys/mca_amd.h137
-rw-r--r--usr/src/uts/intel/sys/x86_archext.h87
5 files changed, 797 insertions, 170 deletions
diff --git a/usr/src/uts/intel/sys/fm/cpu/AMD.h b/usr/src/uts/intel/sys/fm/cpu/AMD.h
index bb7aa427e5..df66719ad3 100644
--- a/usr/src/uts/intel/sys/fm/cpu/AMD.h
+++ b/usr/src/uts/intel/sys/fm/cpu/AMD.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -44,6 +43,7 @@ extern "C" {
#define FM_EREPORT_PAYLOAD_NAME_BANK_NUM "bank-number"
#define FM_EREPORT_PAYLOAD_NAME_ADDR "addr"
#define FM_EREPORT_PAYLOAD_NAME_ADDR_VALID "addr-valid"
+#define FM_EREPORT_PAYLOAD_NAME_BANK_MISC "bank-misc"
#define FM_EREPORT_PAYLOAD_NAME_SYND "syndrome"
#define FM_EREPORT_PAYLOAD_NAME_SYND_TYPE "syndrome-type"
#define FM_EREPORT_PAYLOAD_NAME_IP "ip"
@@ -60,6 +60,7 @@ extern "C" {
#define FM_EREPORT_PAYLOAD_FLAG_PRIV 0x0000000000000080
#define FM_EREPORT_PAYLOAD_FLAG_RESOURCE 0x0000000000000100
#define FM_EREPORT_PAYLOAD_FLAG_STACK 0x0000000000000200
+#define FM_EREPORT_PAYLOAD_FLAG_BANK_MISC 0x0000000000000400
#define FM_EREPORT_PAYLOAD_FLAGS_BANK \
(FM_EREPORT_PAYLOAD_FLAG_BANK_STAT | FM_EREPORT_PAYLOAD_FLAG_BANK_NUM)
@@ -74,6 +75,8 @@ extern "C" {
FM_EREPORT_PAYLOAD_FLAG_PRIV)
#define FM_EREPORT_PAYLOAD_FLAGS_NB \
(FM_EREPORT_PAYLOAD_FLAG_STACK)
+#define FM_EREPORT_PAYLOAD_FLAGS_BANK_MISC \
+ (FM_EREPORT_PAYLOAD_FLAG_BANK_MISC)
#define FM_EREPORT_PAYLOAD_FLAGS_1(f1) \
(FM_EREPORT_PAYLOAD_FLAGS_COMMON | FM_EREPORT_PAYLOAD_FLAGS_##f1)
@@ -83,13 +86,17 @@ extern "C" {
#define FM_EREPORT_PAYLOAD_FLAGS_3(f1, f2, f3) \
(FM_EREPORT_PAYLOAD_FLAGS_COMMON | FM_EREPORT_PAYLOAD_FLAGS_##f1 | \
FM_EREPORT_PAYLOAD_FLAGS_##f2 | FM_EREPORT_PAYLOAD_FLAGS_##f3)
+#define FM_EREPORT_PAYLOAD_FLAGS_4(f1, f2, f3, f4) \
+ (FM_EREPORT_PAYLOAD_FLAGS_COMMON | FM_EREPORT_PAYLOAD_FLAGS_##f1 | \
+ FM_EREPORT_PAYLOAD_FLAGS_##f2 | FM_EREPORT_PAYLOAD_FLAGS_##f3 | \
+ FM_EREPORT_PAYLOAD_FLAGS_##f4)
#define FM_EREPORT_PAYLOAD_FLAGS_CPU_AMD_DC_INF_SYS_ECC1 \
- FM_EREPORT_PAYLOAD_FLAGS_2(ADDR, SYND)
+ FM_EREPORT_PAYLOAD_FLAGS_3(ADDR, SYND, RESOURCE)
#define FM_EREPORT_PAYLOAD_FLAGS_CPU_AMD_DC_INF_L2_ECC1 \
FM_EREPORT_PAYLOAD_FLAGS_2(ADDR, SYND)
#define FM_EREPORT_PAYLOAD_FLAGS_CPU_AMD_DC_INF_SYS_ECCM \
- FM_EREPORT_PAYLOAD_FLAGS_2(ADDR, SYND)
+ FM_EREPORT_PAYLOAD_FLAGS_3(ADDR, SYND, RESOURCE)
#define FM_EREPORT_PAYLOAD_FLAGS_CPU_AMD_DC_INF_L2_ECCM \
FM_EREPORT_PAYLOAD_FLAGS_2(ADDR, SYND)
#define FM_EREPORT_PAYLOAD_FLAGS_CPU_AMD_DC_DATA_ECC1 \
@@ -141,17 +148,17 @@ extern "C" {
#define FM_EREPORT_PAYLOAD_FLAGS_CPU_AMD_BU_S_RDE \
FM_EREPORT_PAYLOAD_FLAGS_1(ADDR)
#define FM_EREPORT_PAYLOAD_FLAGS_CPU_AMD_BU_S_ECC1 \
- FM_EREPORT_PAYLOAD_FLAGS_2(ADDR, SYND)
+ FM_EREPORT_PAYLOAD_FLAGS_3(ADDR, SYND, RESOURCE)
#define FM_EREPORT_PAYLOAD_FLAGS_CPU_AMD_BU_S_ECCM \
- FM_EREPORT_PAYLOAD_FLAGS_2(ADDR, SYND)
+ FM_EREPORT_PAYLOAD_FLAGS_3(ADDR, SYND, RESOURCE)
#define FM_EREPORT_PAYLOAD_FLAGS_CPU_AMD_LS_S_RDE \
FM_EREPORT_PAYLOAD_FLAGS_COMMON
#define FM_EREPORT_PAYLOAD_FLAGS_CPU_AMD_NB_MEM_CE \
- FM_EREPORT_PAYLOAD_FLAGS_3(ADDR, SYND, RESOURCE)
+ FM_EREPORT_PAYLOAD_FLAGS_4(ADDR, SYND, RESOURCE, BANK_MISC)
#define FM_EREPORT_PAYLOAD_FLAGS_CPU_AMD_NB_MEM_UE \
- FM_EREPORT_PAYLOAD_FLAGS_3(ADDR, SYND, RESOURCE)
+ FM_EREPORT_PAYLOAD_FLAGS_4(ADDR, SYND, RESOURCE, BANK_MISC)
#define FM_EREPORT_PAYLOAD_FLAGS_CPU_AMD_NB_HT_CRC \
FM_EREPORT_PAYLOAD_FLAGS_COMMON
#define FM_EREPORT_PAYLOAD_FLAGS_CPU_AMD_NB_HT_SYNC \
@@ -166,6 +173,10 @@ extern "C" {
FM_EREPORT_PAYLOAD_FLAGS_1(ADDR)
#define FM_EREPORT_PAYLOAD_FLAGS_CPU_AMD_NB_WDOG \
FM_EREPORT_PAYLOAD_FLAGS_1(ADDR)
+#define FM_EREPORT_PAYLOAD_FLAGS_CPU_AMD_NB_DRAMADDR_PAR \
+ FM_EREPORT_PAYLOAD_FLAGS_COMMON
+#define FM_EREPORT_PAYLOAD_FLAGS_CPU_AMD_MC_TESTFAIL \
+ FM_EREPORT_PAYLOAD_FLAG_RESOURCE
#define FM_EREPORT_PAYLOAD_FLAGS_CPU_AMD_UNKNOWN \
FM_EREPORT_PAYLOAD_FLAGS_1(ADDR)
@@ -213,6 +224,9 @@ extern "C" {
#define FM_EREPORT_CPU_AMD_NB_GART_WALK "nb.gart_walk"
#define FM_EREPORT_CPU_AMD_NB_RMW "nb.rmw"
#define FM_EREPORT_CPU_AMD_NB_WDOG "nb.wdog"
+#define FM_EREPORT_CPU_AMD_NB_DRAMADDR_PAR "nb.dramaddr_par"
+
+#define FM_EREPORT_CPU_AMD_MC_TESTFAIL "mc.cs_testfail"
#define FM_EREPORT_CPU_AMD_UNKNOWN "unknown"
diff --git a/usr/src/uts/intel/sys/mc.h b/usr/src/uts/intel/sys/mc.h
index 416f323c86..4e1ab003ee 100644
--- a/usr/src/uts/intel/sys/mc.h
+++ b/usr/src/uts/intel/sys/mc.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -39,22 +38,32 @@ extern "C" {
#endif
#define MC_UNUM_NAMLEN 192
-#define MC_UNUM_NDIMM 8
+#define MC_UNUM_NDIMM 2
typedef struct mc_unum {
int unum_board;
int unum_chip;
int unum_mc;
int unum_cs;
+ int unum_rank;
uint64_t unum_offset;
int unum_dimms[MC_UNUM_NDIMM];
} mc_unum_t;
+/*
+ * Invalid marker used in some numeric properties
+ */
+#define MC_INVALNUM ((uint32_t)-1)
+
#define MC_AMD_DEV_OFFSET 24 /* node ID + offset == PCI dev num */
+/*
+ * /dev/mc/mc* ioctl cmds
+ */
#define MC_IOC (0x4d43 << 16)
#define MC_IOC_SNAPSHOT_INFO (MC_IOC | 1)
#define MC_IOC_SNAPSHOT (MC_IOC | 2)
+#define MC_IOC_ONLINESPARE_EN (MC_IOC | 4)
/*
* Prior to requesting a copy of the snapshot, consumers are advised to request
diff --git a/usr/src/uts/intel/sys/mc_amd.h b/usr/src/uts/intel/sys/mc_amd.h
index fba266b14f..c1fc1f2513 100644
--- a/usr/src/uts/intel/sys/mc_amd.h
+++ b/usr/src/uts/intel/sys/mc_amd.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -28,6 +27,74 @@
#pragma ident "%Z%%M% %I% %E% SMI"
+#include <sys/mc.h>
+#include <sys/x86_archext.h>
+
+/*
+ * The mc-amd driver exports an nvlist to userland, where the primary
+ * consumer is the "chip" topology enumerator for this platform type which
+ * builds a full topology subtree from this information. Others can use
+ * it, too, but don't depend on it not changing without an ARC contract.
+ *
+ * In the initial mc-amd implementation this nvlist was not versioned;
+ * we'll think of that as version 0 and it may be recognised by the absence
+ * of a "mcamd-nvlist-version member.
+ *
+ * Version 1 is defined as follows. A name in square brackets indicates
+ * that member is optional (only present if the actual value is valid).
+ *
+ * Name Type Description
+ * -------------------- --------------- ---------------------------------------
+ * mcamd-nvlist-version uint8 Exported nvlist version number
+ * 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"
+ * ecc-type string "ChipKill 128/16" or "Normal 64/8"
+ * base-addr uint64 Node base address
+ * lim-addr uint64 Node limit address
+ * node-ilen uint64 0|1|3|7 for 0/2/4/8 way node interleave
+ * node-ilsel uint64 Node interleave position of this node
+ * cs-intlv-factor uint64 chip-select interleave: 1/2/4/8
+ * 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
+ * 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
+ * cslist nvlist array See below; may have 0 members
+ * dimmlist nvlist array See below; may have 0 members
+ *
+ * cslist is an array of nvlist, each as follows:
+ *
+ * Name Type Description
+ * -------------------- --------------- ---------------------------------------
+ * num uint64 Chip-select base/mask pair number
+ * base-addr uint64 Chip-select base address (rel to node)
+ * mask uint64 Chip-select mask
+ * size uint64 Chip-select size in bytes
+ * dimm1-num uint64 First dimm (lodimm if a pair)
+ * dimm1-csname string Socket cs# line name for 1st dimm rank
+ * [dimm2-num] uint64 Second dimm if applicable (updimm)
+ * [dimm2-csname] string Socket cs# line name for 2nd dimm rank
+ *
+ * dimmlist is an array of nvlist, each as follows:
+ *
+ * Name Type Description
+ * -------------------- --------------- ---------------------------------------
+ * num uint64 DIMM instance number
+ * size uint64 DIMM size in bytes
+ * csnums uint64 array CS base/mask pair(s) on this DIMM
+ * csnames string array Socket cs# line name(s) on this DIMM
+ *
+ * The n'th csnums entry corresponds to the n'th csnames entry
+ */
+#define MC_NVLIST_VERSTR "mcamd-nvlist-version"
+#define MC_NVLIST_VERS0 0
+#define MC_NVLIST_VERS1 1
+#define MC_NVLIST_VERS MC_NVLIST_VERS1
+
/*
* Definitions describing various memory controller constant properties and
* the structure of configuration registers.
@@ -38,155 +105,550 @@ extern "C" {
#endif
/*
+ * Constants and feature/revision test macros that are not expected to vary
+ * among different AMD family 0xf processor revisions.
+ */
+
+/*
* Configuration constants
*/
+#define MC_CHIP_MAXNODES 8 /* max number of MCs in system */
#define MC_CHIP_NDIMM 8 /* max dimms per MC */
#define MC_CHIP_NCS 8 /* number of chip-selects per MC */
+#define MC_CHIP_NDRAMCHAN 2 /* maximum number of dram channels */
#define MC_CHIP_DIMMRANKMAX 4 /* largest number of ranks per dimm */
#define MC_CHIP_DIMMPERCS 2 /* max number of dimms per cs */
#define MC_CHIP_DIMMPAIR(csnum) (csnum / MC_CHIP_DIMMPERCS)
+#if MC_CHIP_DIMMPERCS > MC_UNUM_NDIMM
+#error "MC_CHIP_DIMMPERCS exceeds MC_UNUM_NDIMM"
+#endif
+
+/*
+ * MC_REV_* are used a a convenient shorter form of the X86_CHIPREV
+ * counterparts; these must map directly as we fill mcp_rev from
+ * a cpuid_getchiprev call.
+ */
+#define MC_REV_UNKNOWN X86_CHIPREV_UNKNOWN
+#define MC_REV_B X86_CHIPREV_AMD_F_REV_B
+#define MC_REV_C (X86_CHIPREV_AMD_F_REV_C0 | X86_CHIPREV_AMD_F_REV_CG)
+#define MC_REV_D X86_CHIPREV_AMD_F_REV_D
+#define MC_REV_E X86_CHIPREV_AMD_F_REV_E
+#define MC_REV_F X86_CHIPREV_AMD_F_REV_F
+#define MC_REV_G X86_CHIPREV_AMD_F_REV_G
+
/*
- * Encoding of chip version variations that we need to distinguish
+ * The most common groupings for memory controller features.
*/
-#define MC_REV_UNKNOWN -1u /* unknown AMD revision */
-#define MC_REV_PRE_D 0 /* B/C/CG */
-#define MC_REV_D_E 1 /* D or E */
-#define MC_REV_F 2 /* F */
+#define MC_REVS_BC (MC_REV_B | MC_REV_C)
+#define MC_REVS_DE (MC_REV_D | MC_REV_E)
+#define MC_REVS_BCDE (MC_REVS_BC | MC_REVS_DE)
+#define MC_REVS_FG (MC_REV_F | MC_REV_G)
/*
- * BKDG 3.29 section 3.4.4.1 - DRAM base i registers
+ * Is 'rev' included in the 'revmask' bitmask?
*/
-#define MC_AM_DB_DRAMBASE_MASK 0xffff0000
-#define MC_AM_DB_DRAMBASE_LSHFT 8
-#define MC_AM_DB_DRAMBASE(regval) \
- (((uint64_t)(regval) & MC_AM_DB_DRAMBASE_MASK) << \
- MC_AM_DB_DRAMBASE_LSHFT)
-#define MC_AM_DB_INTLVEN_MASK 0x00000700
-#define MC_AM_DB_INTLVEN_SHIFT 8
-#define MC_AM_DB_WE 0x00000002
-#define MC_AM_DB_RE 0x00000001
+#define MC_REV_MATCH(rev, revmask) X86_CHIPREV_MATCH(rev, revmask)
/*
- * BKDG 3.29 section 3.4.4.2 - DRAM limit i registers
+ * Is 'rev' at least revision 'revmin' or greater
*/
-#define MC_AM_DL_DRAMLIM_MASK 0xffff0000
-#define MC_AM_DL_DRAMLIM_SHIFT 16
-#define MC_AM_DL_DRAMLIM_LSHFT 8
-#define MC_AM_DL_DRAMLIM(regval) \
- ((((uint64_t)(regval) & MC_AM_DL_DRAMLIM_MASK) << \
- MC_AM_DL_DRAMLIM_LSHFT) | ((regval) ? \
- ((1 << (MC_AM_DL_DRAMLIM_SHIFT + MC_AM_DL_DRAMLIM_LSHFT)) - 1) : 0))
-#define MC_AM_DL_INTLVSEL_MASK 0x00000700
-#define MC_AM_DL_INTLVSEL_SHIFT 8
-#define MC_AM_DL_DSTNODE_MASK 0x00000007
+#define MC_REV_ATLEAST(rev, minrev) X86_CHIPREV_ATLEAST(rev, minrev)
/*
- * BKDG 3.29 section 3.5.4 - DRAM CS Base Address Registers.
+ * Chip socket types
+ */
+#define MC_SKT_UNKNOWN 0x0
+#define MC_SKT_754 0x1
+#define MC_SKT_939 0x2
+#define MC_SKT_940 0x3
+#define MC_SKT_S1g1 0x4
+#define MC_SKT_AM2 0x5
+#define MC_SKT_F1207 0x6
+
+/*
+ * Memory controller registers are read via PCI config space accesses on
+ * bus 0, device 24 + NodeId, and function as follows:
+ *
+ * Function 0: HyperTransport Technology Configuration
+ * Function 1: Address Map
+ * Function 2: DRAM Controller & HyperTransport Technology Trace Mode
+ * Function 3: Miscellaneous Control
+ *
+ * For a given (bus, device, function) a particular offset selects the
+ * desired register. All registers are 32-bits wide.
*
- * MC_DC_CSB_CSBASE combines the BaseAddrHi and BaseAddrLo into a single
- * uint64_t, shifting them into the dram address bits they describe.
+ * Different family 0xf processor revisions vary slightly in the content
+ * of these configuration registers. The biggest change is with rev F
+ * where DDR2 support has been introduced along with some hardware-controlled
+ * correctable memory error thresholding. Fortunately most of the config info
+ * required by the mc-amd driver is similar across revisions.
+ *
+ * We will try to insulate most of the driver code from config register
+ * details by reading all memory-controller PCI config registers that we
+ * will need at driver attach time for each of functions 0 through 3, and
+ * storing them in a "cooked" form as memory controller properties.
+ * These are to be accessed directly where we have an mc_t to hand, otherwise
+ * through mcamd_get_numprop. As such we expect most/all use of the
+ * structures and macros defined below to be in those attach codepaths.
*/
-#define MC_DC_CSB_BASEHI_MASK 0xffe00000
-#define MC_DC_CSB_BASEHI_LSHFT 4
-#define MC_DC_CSB_BASELO_MASK 0x0000fe00
-#define MC_DC_CSB_BASELO_LSHFT 4
+/*
+ * Registers will be represented as unions, with one fixed-width unsigned
+ * integer member providing access to the raw register value and one or more
+ * structs breaking the register out into bitfields (more than one struct if
+ * the register definitions varies across processor revisions).
+ *
+ * The "raw" union member will always be '_val32'. Use MCREG_VAL32 to
+ * access this member.
+ *
+ * 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
+ * 'preF' - applies to revisions E and earlier
+ * 'revFG' - applies to revisions F and G
+ * Variants such as 'preD', 'revDE', 'postCG' etc should be introduced
+ * as requirements arise. The MC_REV_* and MC_REV_MATCH etc macros
+ * will also need to grow to match. Use MCREG_FIELD_* to access the
+ * individual bitfields of a register, perhaps using MC_REV_* and MC_REV_MATCH
+ * to decide which revision suffix to provide. Where a bitfield appears
+ * in different revisions but has the same use it should be named identically
+ * (even if the BKDG varies a little) so that the MC_REG_FIELD_* macros
+ * can lookup that member based on revision only.
+ */
-#define MC_DC_CSB_CSBASE(regval) \
- ((((uint64_t)(regval) & MC_DC_CSB_BASEHI_MASK) << \
- MC_DC_CSB_BASEHI_LSHFT) | (((uint64_t)(regval) & \
- MC_DC_CSB_BASELO_MASK) << MC_DC_CSB_BASELO_LSHFT))
+#define _MCREG_FIELD(up, revsuffix, field) ((up)->_fmt_##revsuffix.field)
-#define MC_DC_CSB_CSBE 0x00000001
+#define MCREG_VAL32(up) ((up)->_val32)
+
+#define MCREG_FIELD_CMN(up, field) _MCREG_FIELD(up, cmn, field)
+#define MCREG_FIELD_preF(up, field) _MCREG_FIELD(up, preF, field)
+#define MCREG_FIELD_revFG(up, field) _MCREG_FIELD(up, revFG, field)
/*
- * BKDG 3.29 section 3.5.5 - DRAM CS Mask Registers.
+ * Function 1 - DRAM Address Map: DRAM Base i Registers
*
- * MC_DC_CSM_CSMASK combines the AddrMaskHi and AddrMaskLo into a single
- * uint64_t, shifting them into the dram address bit positions they mask.
- * It also fills the gaps between high and low mask and below the low mask.
- * MC_DC_CSM_UNMASKED_BITS indicates the number of high dram address bits
- * above MC_DC_CSM_MASKHI_HIBIT that cannot be masked.
*/
-#define MC_DC_CSM_MASKHI_MASK 0x3fe00000
-#define MC_DC_CSM_MASKHI_LSHFT 4
-#define MC_DC_CSM_MASKHI_LOBIT 25
-#define MC_DC_CSM_MASKHI_HIBIT 33
-#define MC_DC_CSM_MASKLO_MASK 0x0000fe00
-#define MC_DC_CSM_MASKLO_LOBIT 13
-#define MC_DC_CSM_MASKLO_HIBIT 19
-#define MC_DC_CSM_MASKLO_LSHFT 4
+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 reserved1:6; /* 7:2 */
+ uint32_t IntlvEn:3; /* 10:8 - Interleave Enable */
+ uint32_t reserved2:5; /* 15:11 */
+ uint32_t DRAMBasei:16; /* 31:16 - Base Addr 39:24 */
+ } _fmt_cmn;
+};
+
+#define MC_DRAMBASE(up) ((uint64_t)MCREG_FIELD_CMN(up, DRAMBasei) << 24)
+
+/*
+ * Function 1 - DRAM Address Map: DRAM Limit i Registers
+ *
+ */
+
+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 reserved2:5; /* 15:11 */
+ uint32_t DRAMLimiti:16; /* 31:16 - Limit Addr 39:24 */
+ } _fmt_cmn;
+};
+
+#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 Hole Address Register
+ */
+
+union mcreg_dramhole {
+ uint32_t _val32;
+ struct {
+ uint32_t DramHoleValid:1; /* 0: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;
+};
+
+#define MC_DRAMHOLE_SIZE(up) (MCREG_FIELD_CMN(up, DramHoleOffset) << 24)
+
+/*
+ * Function 2 - DRAM Controller: DRAM CS Base Address Registers
+ */
+
+union mcreg_csbase {
+ uint32_t _val32;
+ /*
+ * Register format in revisions E and earlier
+ */
+ struct {
+ uint32_t CSEnable:1; /* 0: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 */
+ uint32_t BaseAddrHi:11; /* 31:21 - Base Addr 35:25 */
+ } _fmt_preF;
+ /*
+ * Register format in 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 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:39 */
+ } _fmt_revFG;
+};
+
+#define MC_CSBASE(up, rev) (MC_REV_MATCH(rev, MC_REV_F) ? \
+ (uint64_t)MCREG_FIELD_revFG(up, BaseAddrHi) << 27 | \
+ (uint64_t)MCREG_FIELD_revFG(up, BaseAddrLo) << 13 : \
+ (uint64_t)MCREG_FIELD_preF(up, BaseAddrHi) << 25 | \
+ (uint64_t)MCREG_FIELD_preF(up, BaseAddrLo) << 13)
+
+/*
+ * Function 2 - DRAM Controller: DRAM CS Mask Registers
+ */
+
+union mcreg_csmask {
+ uint32_t _val32;
+ /*
+ * Register format in revisions E and earlier
+ */
+ struct {
+ uint32_t reserved1:9; /* 8:0 */
+ uint32_t AddrMaskLo:7; /* 15:9 - Addr Mask 19:13 */
+ uint32_t reserved2:5; /* 20:16 */
+ uint32_t AddrMaskHi:9; /* 29:21 - Addr Mask 33:25 */
+ uint32_t reserved3:2; /* 31:30 */
+ } _fmt_preF;
+ /*
+ * Register format in revisions F and G
+ */
+ 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:10; /* 28:19 - Addr Mask 36:27 */
+ uint32_t reserved3:3; /* 31:29 */
+ } _fmt_revFG;
+};
-#define MC_DC_CSM_MASKFILL 0x1f01fff /* [24:20] and [12:0] */
+#define MC_CSMASKLO_LOBIT(rev) (MC_REV_MATCH(rev, MC_REV_F) ? 13 : 13)
+#define MC_CSMASKLO_HIBIT(rev) (MC_REV_MATCH(rev, MC_REV_F) ? 21 : 19)
-#define MC_DC_CSM_UNMASKED_BITS 2
+#define MC_CSMASKHI_LOBIT(rev) (MC_REV_MATCH(rev, MC_REV_F) ? 27 : 25)
+#define MC_CSMASKHI_HIBIT(rev) (MC_REV_MATCH(rev, MC_REV_F) ? 36 : 33)
-#define MC_DC_CSM_CSMASK(regval) \
- ((((uint64_t)(regval) & MC_DC_CSM_MASKHI_MASK) << \
- MC_DC_CSM_MASKHI_LSHFT) | (((uint64_t)(regval) & \
- MC_DC_CSM_MASKLO_MASK) << MC_DC_CSM_MASKLO_LSHFT) | \
- MC_DC_CSM_MASKFILL)
+#define MC_CSMASK_UNMASKABLE(rev) (MC_REV_MATCH(rev, MC_REV_F) ? 0 : 2)
+
+#define MC_CSMASK(up, rev) (MC_REV_MATCH(rev, MC_REV_F) ? \
+ (uint64_t)MCREG_FIELD_revFG(up, AddrMaskHi) << 27 | \
+ (uint64_t)MCREG_FIELD_revFG(up, AddrMaskLo) << 13 | 0x7c01fff : \
+ (uint64_t)MCREG_FIELD_preF(up, AddrMaskHi) << 25 | \
+ (uint64_t)MCREG_FIELD_preF(up, AddrMaskLo) << 13 | 0x1f01fff)
/*
- * BKDG 3.29 section 3.5.6 - DRAM Bank Address Mapping Register
+ * Function 2 - DRAM Controller: DRAM Bank Address Mapping Registers
*/
+
+union mcreg_bankaddrmap {
+ uint32_t _val32;
+ /*
+ * Register format in revisions E and earlier
+ */
+ struct {
+ uint32_t cs10:4; /* 3:0 - CS1/0 */
+ uint32_t cs32:4; /* 7:4 - CS3/2 */
+ uint32_t cs54:4; /* 11:8 - CS5/4 */
+ uint32_t cs76:4; /* 15:12 - CS7/6 */
+ uint32_t reserved1:14; /* 29:16 */
+ uint32_t BankSwizzleMode:1; /* 30:30 */
+ uint32_t reserved2:1; /* 31:31 */
+ } _fmt_preF;
+ /*
+ * Register format in revisions F and G
+ */
+ struct {
+ uint32_t cs10:4; /* 3:0 - CS1/0 */
+ uint32_t cs32:4; /* 7:4 - CS3/2 */
+ uint32_t cs54:4; /* 11:8 - CS5/4 */
+ uint32_t cs76:4; /* 15:12 - CS7/6 */
+ uint32_t reserved1:16; /* 31:16 */
+ } _fmt_revFG;
+ /*
+ * Accessing all mode encodings as one uint16
+ */
+ struct {
+ uint32_t allcsmodes:16; /* 15:0 */
+ uint32_t pad:16; /* 31:16 */
+ } _fmt_bankmodes;
+};
+
#define MC_DC_BAM_CSBANK_MASK 0x0000000f
#define MC_DC_BAM_CSBANK_SHIFT 4
-#define MC_DC_BAM_CSBANK_SWIZZLE 0x40000000
-
-/*
- * BKDG 3.29 section 3.4.8 - DRAM Hole register, revs E and later
- */
-#define MC_DC_HOLE_VALID 0x00000001
-#define MC_DC_HOLE_OFFSET_MASK 0x0000ff00
-#define MC_DC_HOLE_OFFSET_LSHIFT 16
-
-/*
- * BKDG 3.29 section 3.5.11 - DRAM configuration high and low registers.
- * The following defines may be applied to a uint64_t made by
- * concatenating those two 32-bit registers.
- */
-#define MC_DC_DCFG_DLL_DIS 0x0000000000000001
-#define MC_DC_DCFG_D_DRV 0x0000000000000002
-#define MC_DC_DCFG_QFC_EN 0x0000000000000004
-#define MC_DC_DCFG_DISDQSYS 0x0000000000000008
-#define MC_DC_DCFG_BURST2OPT 0x0000000000000020
-#define MC_DC_DCFG_MOD64BITMUX 0x0000000000000040
-#define MC_DC_DCFG_PWRDWNTRIEN 0x0000000000000080 /* >= rev E */
-#define MC_DC_DCFG_SCRATCHBIT 0x0000000000000080 /* <= rev D */
-#define MC_DC_DCFG_DRAMINIT 0x0000000000000100
-#define MC_DC_DCFG_DUALDIMMEN 0x0000000000000200
-#define MC_DC_DCFG_DRAMENABLE 0x0000000000000400
-#define MC_DC_DCFG_MEMCLRSTATUS 0x0000000000000800
-#define MC_DC_DCFG_ESR 0x0000000000001000
-#define MC_DC_DCFG_SR_S 0x0000000000002000
-#define MC_DC_DCFG_RDWRQBYP_MASK 0x000000000000c000
-#define MC_DC_DCFG_128 0x0000000000010000
-#define MC_DC_DCFG_DIMMECEN 0x0000000000020000
-#define MC_DC_DCFG_UNBUFFDIMM 0x0000000000040000
-#define MC_DC_DCFG_32BYTEEN 0x0000000000080000
-#define MC_DC_DCFG_X4DIMMS_MASK 0x0000000000f00000
-#define MC_DC_DCFG_X4DIMMS_SHIFT 20
-#define MC_DC_DCFG_DISINRCVRS 0x0000000001000000
-#define MC_DC_DCFG_BYPMAX_MASK 0x000000000e000000
-#define MC_DC_DCFG_EN2T 0x0000000010000000
-#define MC_DC_DCFG_UPPERCSMAP 0x0000000020000000
-#define MC_DC_DCFG_PWRDOWNCTL_MASK 0x00000000c0000000
-#define MC_DC_DCFG_ASYNCLAT_MASK 0x0000000f00000000
-#define MC_DC_DCFG_RDPREAMBLE_MASK 0x00000f0000000000
-#define MC_DC_DCFG_MEMDQDRVSTREN_MASK 0x0000600000000000
-#define MC_DC_DCFG_DISABLEJITTER 0x0000800000000000
-#define MC_DC_DCFG_ILD_LMT_MASK 0x0007000000000000
-#define MC_DC_DCFG_ECC_EN 0x0008000000000000
-#define MC_DC_DCFG_MEMCLK_MASK 0x0070000000000000
-#define MC_DC_DCFG_MCR 0x0200000000000000
-#define MC_DC_DCFG_MC0_EN 0x0400000000000000
-#define MC_DC_DCFG_MC1_EN 0x0800000000000000
-#define MC_DC_DCFG_MC2_EN 0x1000000000000000
-#define MC_DC_DCFG_MC3_EN 0x2000000000000000
-#define MC_DC_DCFG_ODDDIVISORCORRECT 0x8000000000000000
+
+#define MC_CSBANKMODE(up, csnum) ((up)->_fmt_bankmodes.allcsmodes >> \
+ MC_DC_BAM_CSBANK_SHIFT * MC_CHIP_DIMMPAIR(csnum) & MC_DC_BAM_CSBANK_MASK)
+
+/*
+ * Function 2 - DRAM Controller: DRAM Configuration Low and High
+ */
+
+union mcreg_dramcfg_lo {
+ uint32_t _val32;
+ /*
+ * Register format in revisions E and earlier.
+ * Bit 7 is a BIOS ScratchBit in revs D and earlier,
+ * PwrDwnTriEn in revision E; we don't use it so
+ * we'll call it ambig1.
+ */
+ struct {
+ uint32_t DLL_Dis:1; /* 0 */
+ uint32_t D_DRV:1; /* 1 */
+ uint32_t QFC_EN:1; /* 2 */
+ uint32_t DisDqsHys:1; /* 3 */
+ uint32_t reserved1:1; /* 4 */
+ uint32_t Burst2Opt:1; /* 5 */
+ uint32_t Mod64BitMux:1; /* 6 */
+ uint32_t ambig1:1; /* 7 */
+ uint32_t DramInit:1; /* 8 */
+ uint32_t DualDimmEn:1; /* 9 */
+ uint32_t DramEnable:1; /* 10 */
+ uint32_t MemClrStatus:1; /* 11 */
+ uint32_t ESR:1; /* 12 */
+ uint32_t SR_S:1; /* 13 */
+ uint32_t RdWrQByp:2; /* 15:14 */
+ uint32_t Width128:1; /* 16 */
+ uint32_t DimmEcEn:1; /* 17 */
+ uint32_t UnBufDimm:1; /* 18 */
+ uint32_t ByteEn32:1; /* 19 */
+ uint32_t x4DIMMs:4; /* 23:20 */
+ uint32_t DisInRcvrs:1; /* 24 */
+ uint32_t BypMax:3; /* 27:25 */
+ uint32_t En2T:1; /* 28 */
+ uint32_t UpperCSMap:1; /* 29 */
+ uint32_t PwrDownCtl:2; /* 31:30 */
+ } _fmt_preF;
+ /*
+ * Register format in revisions F and G
+ */
+ struct {
+ 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 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 reserved3:2; /* 18:17 */
+ uint32_t DimmEccEn:1; /* 19 */
+ uint32_t reserved4:12; /* 31:20 */
+ } _fmt_revFG;
+};
+
+/*
+ * Function 2 - DRAM Controller: DRAM Controller Miscellaneous Data
+ */
+
+union mcreg_drammisc {
+ uint32_t _val32;
+ /*
+ * Register format in 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_revFG;
+};
+
+union mcreg_dramcfg_hi {
+ uint32_t _val32;
+ /*
+ * Register format in revisions E and earlier.
+ */
+ struct {
+ uint32_t AsyncLat:4; /* 3:0 */
+ uint32_t reserved1:4; /* 7:4 */
+ uint32_t RdPreamble:4; /* 11:8 */
+ uint32_t reserved2:1; /* 12 */
+ uint32_t MemDQDrvStren:2; /* 14:13 */
+ uint32_t DisableJitter:1; /* 15 */
+ uint32_t ILD_lmt:3; /* 18:16 */
+ uint32_t DCC_EN:1; /* 19 */
+ uint32_t MemClk:3; /* 22:20 */
+ uint32_t reserved3:2; /* 24:23 */
+ uint32_t MCR:1; /* 25 */
+ uint32_t MC0_EN:1; /* 26 */
+ uint32_t MC1_EN:1; /* 27 */
+ uint32_t MC2_EN:1; /* 28 */
+ uint32_t MC3_EN:1; /* 29 */
+ uint32_t reserved4:1; /* 30 */
+ uint32_t OddDivisorCorrect:1; /* 31 */
+ } _fmt_preF;
+ /*
+ * Register format in revisions F and G
+ */
+ struct {
+ uint32_t MemClkFreq:3; /* 2:0 */
+ uint32_t MemClkFreqVal:1; /* 3 */
+ uint32_t MaxAsyncLat:4; /* 7:4 */
+ uint32_t reserved1:4; /* 11:8 */
+ uint32_t RDqsEn:1; /* 12 */
+ uint32_t reserved2:1; /* 13 */
+ uint32_t DisDramInterface:1; /* 14 */
+ uint32_t PowerDownEn:1; /* 15 */
+ uint32_t PowerDownMode:1; /* 16 */
+ uint32_t FourRankSODimm:1; /* 17 */
+ uint32_t FourRankRDimm:1; /* 18 */
+ uint32_t reserved3:1; /* 19 */
+ uint32_t SlowAccessMode:1; /* 20 */
+ uint32_t reserved4:1; /* 21 */
+ uint32_t BankSwizzleMode:1; /* 22 */
+ uint32_t undocumented1:1; /* 23 */
+ uint32_t DcqBypassMax:4; /* 27:24 */
+ uint32_t FourActWindow:4; /* 31:28 */
+ } _fmt_revFG;
+};
+
+/*
+ * Function 3 - Miscellaneous Control: Scrub Control Register
+ */
+
+union mcreg_scrubctl {
+ uint32_t _val32;
+ struct {
+ uint32_t DramScrub:5; /* 4:0 */
+ uint32_t reserved3: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;
+};
+
+/*
+ * Function 3 - Miscellaneous Control: On-Line Spare Control Register
+ */
+
+union mcreg_nbcfg {
+ uint32_t _val32;
+ /*
+ * Register format in revisions E and earlier.
+ */
+ struct {
+ uint32_t CpuEccErrEn: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 reserved1: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 reserved2:1; /* 26 */
+ uint32_t NbMcaToMstCpuEn:1; /* 27 */
+ uint32_t reserved3:4; /* 31:28 */
+ } _fmt_preF;
+ /*
+ * Register format in revisions F and G
+ */
+ struct {
+ uint32_t CpuEccErrEn: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 reserved1: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 reserved2:1; /* 26 */
+ uint32_t NbMcaToMstCpuEn:1; /* 27 */
+ uint32_t DisTgtAbtCpuErrRsp:1; /* 28 */
+ uint32_t DisMstAbtCpuErrRsp:1; /* 29 */
+ uint32_t SyncOnDramAdrParErrEn:1; /* 30 */
+ uint32_t reserved3:1; /* 31 */
+
+ } _fmt_revFG;
+};
+
+/*
+ * Function 3 - Miscellaneous Control: On-Line Spare Control Register
+ */
+
+union mcreg_sparectl {
+ uint32_t _val32;
+ /*
+ * Register format in revisions F and G
+ */
+ struct {
+ uint32_t SwapEn:1; /* 0 */
+ uint32_t SwapDone:1; /* 1 */
+ uint32_t reserved1:2; /* 3:2 */
+ uint32_t BadDramCs:3; /* 6:4 */
+ uint32_t reserved2:5; /* 11:7 */
+ uint32_t SwapDoneInt:2; /* 13:12 */
+ uint32_t EccErrInt:2; /* 15:14 */
+ uint32_t EccErrCntDramCs:3; /* 18:16 */
+ uint32_t reserved3:1; /* 19 */
+ uint32_t EccErrCntDramChan:1; /* 20 */
+ uint32_t reserved4:2; /* 22:21 */
+ uint32_t EccErrCntWrEn:1; /* 23 */
+ uint32_t EccErrCnt:4; /* 27:24 */
+ uint32_t reserved5:4; /* 31:28 */
+ } _fmt_revFG;
+};
#ifdef __cplusplus
}
diff --git a/usr/src/uts/intel/sys/mca_amd.h b/usr/src/uts/intel/sys/mca_amd.h
index 1b5b6b599f..6d45691c14 100644
--- a/usr/src/uts/intel/sys/mca_amd.h
+++ b/usr/src/uts/intel/sys/mca_amd.h
@@ -52,26 +52,31 @@ extern "C" {
#define AMD_MSR_DC_MASK 0xc0010044
#define AMD_MSR_DC_STATUS 0x401
#define AMD_MSR_DC_ADDR 0x402
+#define AMD_MSR_DC_MISC 0x403
#define AMD_MSR_IC_CTL 0x404
#define AMD_MSR_IC_MASK 0xc0010045
#define AMD_MSR_IC_STATUS 0x405
#define AMD_MSR_IC_ADDR 0x406
+#define AMD_MSR_IC_MISC 0x407
#define AMD_MSR_BU_CTL 0x408
#define AMD_MSR_BU_MASK 0xc0010046
#define AMD_MSR_BU_STATUS 0x409
#define AMD_MSR_BU_ADDR 0x40a
+#define AMD_MSR_BU_MISC 0x40b
#define AMD_MSR_LS_CTL 0x40c
#define AMD_MSR_LS_MASK 0xc0010047
#define AMD_MSR_LS_STATUS 0x40d
#define AMD_MSR_LS_ADDR 0x40e
+#define AMD_MSR_LS_MISC 0x40f
#define AMD_MSR_NB_CTL 0x410
#define AMD_MSR_NB_MASK 0xc0010048
#define AMD_MSR_NB_STATUS 0x411
#define AMD_MSR_NB_ADDR 0x412
+#define AMD_MSR_NB_MISC 0x413
#define AMD_MCG_EN_DC 0x01
#define AMD_MCG_EN_IC 0x02
@@ -95,7 +100,7 @@ extern "C" {
#define AMD_DC_EN_L1TP 0x00000020ULL
#define AMD_DC_EN_L2TP 0x00000040ULL
-#define AMD_DC_CTL_INIT \
+#define AMD_DC_CTL_INIT_CMN \
(AMD_DC_EN_ECCI | AMD_DC_EN_ECCM | AMD_DC_EN_DECC | AMD_DC_EN_DMTP | \
AMD_DC_EN_DSTP | AMD_DC_EN_L1TP | AMD_DC_EN_L2TP)
@@ -116,7 +121,7 @@ extern "C" {
#define AMD_IC_EN_L2TP 0x00000040ULL
#define AMD_IC_EN_RDDE 0x00000200ULL
-#define AMD_IC_CTL_INIT \
+#define AMD_IC_CTL_INIT_CMN \
(AMD_IC_EN_ECCI | AMD_IC_EN_ECCM | AMD_IC_EN_IDP | AMD_IC_EN_IMTP | \
AMD_IC_EN_ISTP | AMD_IC_EN_L1TP | AMD_IC_EN_L2TP)
@@ -149,7 +154,7 @@ extern "C" {
#define AMD_BU_EN_L2T_ECC1_SCR 0x00040000ULL
#define AMD_BU_EN_L2T_ECCM_SCR 0x00080000ULL
-#define AMD_BU_CTL_INIT \
+#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 | \
AMD_BU_EN_L2T_PAR_ICDC | AMD_BU_EN_L2T_PAR_TLB | \
@@ -172,7 +177,19 @@ extern "C" {
#define AMD_LS_EN_S_RDE_S 0x00000001ULL
#define AMD_LS_EN_S_RDE_L 0x00000002ULL
-#define AMD_LS_CTL_INIT 0ULL
+#define AMD_LS_CTL_INIT_CMN 0ULL
+
+/*
+ * NorthBridge (NB) MCi_MISC - DRAM Errors Threshold Register.
+ */
+#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_CNTEN (0x1ULL << 51)
+#define AMD_NB_MISC_INTTYPE (0x1ULL << 49)
+#define AMD_NB_MISC_INTTYPE_MASK (0x3ULL << 49)
+#define AMD_NB_MISC_OVRFLW (0x1ULL << 48)
+#define AMD_NB_MISC_ERRCOUNT_MASK (0xfffULL << 32)
/*
* The Northbridge (NB) is configured using both the standard MCA CTL register
@@ -183,46 +200,80 @@ extern "C" {
* 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].
+ * 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.
*
*/
-#define AMD_NB_EN_CORRECC 0x00000001
-#define AMD_NB_EN_UNCORRECC 0x00000002
-#define AMD_NB_EN_CRCERR0 0x00000004
-#define AMD_NB_EN_CRCERR1 0x00000008
-#define AMD_NB_EN_CRCERR2 0x00000010
-#define AMD_NB_EN_SYNCPKT0 0x00000020
-#define AMD_NB_EN_SYNCPKT1 0x00000040
-#define AMD_NB_EN_SYNCPKT2 0x00000080
-#define AMD_NB_EN_MSTRABRT 0x00000100
-#define AMD_NB_EN_TGTABRT 0x00000200
-#define AMD_NB_EN_GARTTBLWK 0x00000400
-#define AMD_NB_EN_ATOMICRMW 0x00000800
-#define AMD_NB_EN_WCHDOGTMR 0x00001000
-
-#define AMD_NB_CTL_INIT /* All but GARTTBLWK */ \
+#define AMD_NB_EN_CORRECC 0x00000001ULL
+#define AMD_NB_EN_UNCORRECC 0x00000002ULL
+#define AMD_NB_EN_CRCERR0 0x00000004ULL
+#define AMD_NB_EN_CRCERR1 0x00000008ULL
+#define AMD_NB_EN_CRCERR2 0x00000010ULL
+#define AMD_NB_EN_SYNCPKT0 0x00000020ULL
+#define AMD_NB_EN_SYNCPKT1 0x00000040ULL
+#define AMD_NB_EN_SYNCPKT2 0x00000080ULL
+#define AMD_NB_EN_MSTRABRT 0x00000100ULL
+#define AMD_NB_EN_TGTABRT 0x00000200ULL
+#define AMD_NB_EN_GARTTBLWK 0x00000400ULL
+#define AMD_NB_EN_ATOMICRMW 0x00000800ULL
+#define AMD_NB_EN_WCHDOGTMR 0x00001000ULL
+#define AMD_NB_EN_DRAMPAR 0x00040000ULL /* revs F and G */
+
+#define AMD_NB_CTL_INIT_CMN /* Revs B to G; All but GARTTBLWK */ \
(AMD_NB_EN_CORRECC | AMD_NB_EN_UNCORRECC | \
AMD_NB_EN_CRCERR0 | AMD_NB_EN_CRCERR1 | AMD_NB_EN_CRCERR2 | \
AMD_NB_EN_SYNCPKT0 | AMD_NB_EN_SYNCPKT1 | AMD_NB_EN_SYNCPKT2 | \
AMD_NB_EN_MSTRABRT | AMD_NB_EN_TGTABRT | \
AMD_NB_EN_ATOMICRMW | AMD_NB_EN_WCHDOGTMR)
-#define AMD_NB_CFG_CPUECCERREN 0x00000001
-#define AMD_NB_CFG_CPURDDATERREN 0x00000002
-#define AMD_NB_CFG_SYNCONUCECCEN 0x00000004
-#define AMD_NB_CFG_SYNCPKTGENDIS 0x00000008
-#define AMD_NB_CFG_SYNCPKTPROPDIS 0x00000010
-#define AMD_NB_CFG_IOMSTABORTDIS 0x00000020
-#define AMD_NB_CFG_CPUERRDIS 0x00000040
-#define AMD_NB_CFG_IOERRDIS 0x00000080
-#define AMD_NB_CFG_WDOGTMRDIS 0x00000100
-#define AMD_NB_CFG_SYNCONWDOGEN 0x00100000
-#define AMD_NB_CFG_SYNCONANYERREN 0x00200000
-#define AMD_NB_CFG_ECCEN 0x00400000
-#define AMD_NB_CFG_CHIPKILLECCEN 0x00800000
-#define AMD_NB_CFG_IORDDATERREN 0x01000000
-#define AMD_NB_CFG_DISPCICFGCPUERRRSP 0x02000000
-#define AMD_NB_CFG_NBMCATOMSTCPUEN 0x08000000
+#define AMD_NB_CTL_INIT_REV_FG /* Additional bits for revs F and G */ \
+ AMD_NB_EN_DRAMPAR
+
+/*
+ * NB MCA Configuration register
+ */
+#define AMD_NB_CFG_CPUECCERREN 0x00000001
+#define AMD_NB_CFG_CPURDDATERREN 0x00000002
+#define AMD_NB_CFG_SYNCONUCECCEN 0x00000004
+#define AMD_NB_CFG_SYNCPKTGENDIS 0x00000008
+#define AMD_NB_CFG_SYNCPKTPROPDIS 0x00000010
+#define AMD_NB_CFG_IOMSTABORTDIS 0x00000020
+#define AMD_NB_CFG_CPUERRDIS 0x00000040
+#define AMD_NB_CFG_IOERRDIS 0x00000080
+#define AMD_NB_CFG_WDOGTMRDIS 0x00000100
+#define AMD_NB_CFG_SYNCONWDOGEN 0x00100000
+#define AMD_NB_CFG_SYNCONANYERREN 0x00200000
+#define AMD_NB_CFG_ECCEN 0x00400000
+#define AMD_NB_CFG_CHIPKILLECCEN 0x00800000
+#define AMD_NB_CFG_IORDDATERREN 0x01000000
+#define AMD_NB_CFG_DISPCICFGCPUERRRSP 0x02000000
+#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 */
+
+/*
+ * We do not initialize the NB config with an absolute value; instead we
+ * selectively add some bits and remove others. Note that
+ * AMD_NB_CFG_{ADD,REMOVE}_{CMN,REV_FG} below are not the whole
+ * story here - additional config is performed regarding the watchdog (see
+ * ao_mca.c for details).
+ */
+#define AMD_NB_CFG_ADD_CMN /* Revs B to G */ \
+ (AMD_NB_CFG_DISPCICFGCPUERRRSP | AMD_NB_CFG_SYNCONUCECCEN | \
+ AMD_NB_CFG_CPUECCERREN)
+
+#define AMD_NB_CFG_REMOVE_CMN /* Revs B to G */ \
+ (AMD_NB_CFG_NBMCATOMSTCPUEN | \
+ AMD_NB_CFG_IORDDATERREN | AMD_NB_CFG_SYNCONANYERREN | \
+ AMD_NB_CFG_SYNCONWDOGEN | AMD_NB_CFG_IOERRDIS | \
+ AMD_NB_CFG_IOMSTABORTDIS | AMD_NB_CFG_SYNCPKTPROPDIS | \
+ AMD_NB_CFG_SYNCPKTGENDIS)
+
+#define AMD_NB_CFG_ADD_REV_FG /* Revs F and G */ \
+ AMD_NB_CFG_SYNCONDRAMADRPARERREN
+
+#define AMD_NB_CFG_REMOVE_REV_FG 0x0 /* Revs F and G */
#define AMD_NB_CFG_WDOGTMRCNTSEL_4095 0x00000000
#define AMD_NB_CFG_WDOGTMRCNTSEL_2047 0x00000200
@@ -283,10 +334,14 @@ extern "C" {
#define AMD_NB_REG_SCRUBADDR_LO 0x5c
#define AMD_NB_REG_SCRUBADDR_HI 0x60
-#define AMD_NB_STAT_LDTLINK_MASK 0x0000007000000000
+#define AMD_NB_REG_SPARECTL 0xb0
+
+#define AMD_NB_STAT_DRAMCHANNEL 0x0000020000000000ULL
+#define AMD_NB_STAT_LDTLINK_MASK 0x0000007000000000ULL
#define AMD_NB_STAT_LDTLINK_SHIFT 4
-#define AMD_NB_STAT_ERRCPU1 0x0000000200000000
-#define AMD_NB_STAT_ERRCPU0 0x0000000100000000
+#define AMD_NB_STAT_ERRCPU1 0x0000000200000000ULL
+#define AMD_NB_STAT_ERRCPU0 0x0000000100000000ULL
+
#define AMD_NB_STAT_CKSYND_MASK 0x00000000ff000000 /* syndrome[15:8] */
#define AMD_NB_STAT_CKSYND_SHIFT (24 - 8) /* shift [31:24] to [15:8] */
@@ -298,8 +353,8 @@ extern "C" {
((((uint64_t)(synd) << AMD_NB_STAT_CKSYND_SHIFT) & \
AMD_NB_STAT_CKSYND_MASK) | AMD_BANK_MKSYND(synd))
-#define AMD_ERRCODE_MASK 0x000000000000ffff
-#define AMD_ERREXT_MASK 0x00000000000f0000
+#define AMD_ERRCODE_MASK 0x000000000000ffffULL
+#define AMD_ERREXT_MASK 0x00000000000f0000ULL
#define AMD_ERREXT_SHIFT 16
#define AMD_ERRCODE_TT_MASK 0x000c
diff --git a/usr/src/uts/intel/sys/x86_archext.h b/usr/src/uts/intel/sys/x86_archext.h
index 1799e9e2ef..cf76d4f237 100644
--- a/usr/src/uts/intel/sys/x86_archext.h
+++ b/usr/src/uts/intel/sys/x86_archext.h
@@ -391,6 +391,89 @@ typedef struct mtrrvar {
#define X86_VENDOR_STRLEN 13 /* vendor string max len + \0 */
+/*
+ * Some vendor/family/model/stepping ranges are commonly grouped under
+ * a single identifying banner by the vendor. The following encode
+ * that "revision" in a uint32_t with the 8 most significant bits
+ * identifying the vendor with X86_VENDOR_*, the next 8 identifying the
+ * family, and the remaining 16 typically forming a bitmask of revisions
+ * within that family with more significant bits indicating "later" revisions.
+ */
+
+#define _X86_CHIPREV_VENDOR_MASK 0xff000000u
+#define _X86_CHIPREV_VENDOR_SHIFT 24
+#define _X86_CHIPREV_FAMILY_MASK 0x00ff0000u
+#define _X86_CHIPREV_FAMILY_SHIFT 16
+#define _X86_CHIPREV_REV_MASK 0x0000ffffu
+
+#define _X86_CHIPREV_VENDOR(x) \
+ (((x) & _X86_CHIPREV_VENDOR_MASK) >> _X86_CHIPREV_VENDOR_SHIFT)
+#define _X86_CHIPREV_FAMILY(x) \
+ (((x) & _X86_CHIPREV_FAMILY_MASK) >> _X86_CHIPREV_FAMILY_SHIFT)
+#define _X86_CHIPREV_REV(x) \
+ ((x) & _X86_CHIPREV_REV_MASK)
+
+/* True if x matches in vendor and family and if x matches the given rev mask */
+#define X86_CHIPREV_MATCH(x, mask) \
+ (_X86_CHIPREV_VENDOR(x) == _X86_CHIPREV_VENDOR(mask) && \
+ _X86_CHIPREV_FAMILY(x) == _X86_CHIPREV_FAMILY(mask) && \
+ ((_X86_CHIPREV_REV(x) & _X86_CHIPREV_REV(mask)) != 0))
+
+/* True if x matches in vendor and family and rev is at least minx */
+#define X86_CHIPREV_ATLEAST(x, minx) \
+ (_X86_CHIPREV_VENDOR(x) == _X86_CHIPREV_VENDOR(minx) && \
+ _X86_CHIPREV_FAMILY(x) == _X86_CHIPREV_FAMILY(minx) && \
+ _X86_CHIPREV_REV(x) >= _X86_CHIPREV_REV(minx))
+
+#define _X86_CHIPREV_MKREV(vendor, family, rev) \
+ ((uint32_t)(vendor) << _X86_CHIPREV_VENDOR_SHIFT | \
+ (family) << _X86_CHIPREV_FAMILY_SHIFT | (rev))
+
+/* Revision default */
+#define X86_CHIPREV_UNKNOWN 0x0
+
+/*
+ * Definitions for AMD Family 0xf. Minor revisions C0 and CG are
+ * sufficiently different that we will distinguish them; in all other
+ * case we will identify the major revision.
+ */
+#define X86_CHIPREV_AMD_F_REV_B _X86_CHIPREV_MKREV(X86_VENDOR_AMD, 0xf, 0x0001)
+#define X86_CHIPREV_AMD_F_REV_C0 _X86_CHIPREV_MKREV(X86_VENDOR_AMD, 0xf, 0x0002)
+#define X86_CHIPREV_AMD_F_REV_CG _X86_CHIPREV_MKREV(X86_VENDOR_AMD, 0xf, 0x0004)
+#define X86_CHIPREV_AMD_F_REV_D _X86_CHIPREV_MKREV(X86_VENDOR_AMD, 0xf, 0x0008)
+#define X86_CHIPREV_AMD_F_REV_E _X86_CHIPREV_MKREV(X86_VENDOR_AMD, 0xf, 0x0010)
+#define X86_CHIPREV_AMD_F_REV_F _X86_CHIPREV_MKREV(X86_VENDOR_AMD, 0xf, 0x0020)
+#define X86_CHIPREV_AMD_F_REV_G _X86_CHIPREV_MKREV(X86_VENDOR_AMD, 0xf, 0x0040)
+
+/*
+ * Various socket/package types, extended as the need to distinguish
+ * a new type arises. The top 8 byte identfies the vendor and the
+ * remaining 24 bits describe 24 socket types.
+ */
+
+#define _X86_SOCKET_VENDOR_SHIFT 24
+#define _X86_SOCKET_VENDOR(x) ((x) >> _X86_SOCKET_VENDOR_SHIFT)
+#define _X86_SOCKET_TYPE_MASK 0x00ffffff
+#define _X86_SOCKET_TYPE(x) ((x) & _X86_SOCKET_TYPE_MASK)
+
+#define _X86_SOCKET_MKVAL(vendor, bitval) \
+ ((uint32_t)(vendor) << _X86_SOCKET_VENDOR_SHIFT | (bitval))
+
+#define X86_SOCKET_MATCH(s, mask) \
+ (_X86_SOCKET_VENDOR(s) == _X86_SOCKET_VENDOR(mask) && \
+ (_X86_SOCKET_TYPE(s) & _X86_SOCKET_TYPE(mask)) != 0)
+
+#define X86_SOCKET_UNKNOWN 0x0
+ /*
+ * AMD socket types
+ */
+#define X86_SOCKET_754 _X86_SOCKET_MKVAL(X86_VENDOR_AMD, 0x000001)
+#define X86_SOCKET_939 _X86_SOCKET_MKVAL(X86_VENDOR_AMD, 0x000002)
+#define X86_SOCKET_940 _X86_SOCKET_MKVAL(X86_VENDOR_AMD, 0x000004)
+#define X86_SOCKET_S1g1 _X86_SOCKET_MKVAL(X86_VENDOR_AMD, 0x000008)
+#define X86_SOCKET_AM2 _X86_SOCKET_MKVAL(X86_VENDOR_AMD, 0x000010)
+#define X86_SOCKET_F1207 _X86_SOCKET_MKVAL(X86_VENDOR_AMD, 0x000020)
+
#if !defined(_ASM)
#if defined(_KERNEL) || defined(_KMEMUSER)
@@ -452,6 +535,10 @@ extern int cpuid_is_cmt(struct cpu *);
extern int cpuid_syscall32_insn(struct cpu *);
extern int getl2cacheinfo(struct cpu *, int *, int *, int *);
+extern uint32_t cpuid_getchiprev(struct cpu *);
+extern const char *cpuid_getchiprevstr(struct cpu *);
+extern uint32_t cpuid_getsockettype(struct cpu *);
+
extern int cpuid_opteron_erratum(struct cpu *, uint_t);
struct cpuid_info;