mc_amd.h revision 5667185bc023b9742cb2480659d7673fa9ac8050
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* 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
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*
* Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _MC_AMD_H
#define _MC_AMD_H
#include <sys/isa_defs.h>
#include <sys/x86_archext.h>
#ifdef __cplusplus
extern "C" {
#endif
/*
* Definitions, register offsets, register structure etc pertaining to
* the memory controller on AMD64 systems. These are used by both the
* AMD cpu module and the mc-amd driver.
*/
/*
* 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
* (and the contract should probably concern the topology, not this nvlist).
*
* 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
* -------------------- --------------- ---------------------------------------
* 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
* 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
/*
* among different AMD family 0xf processor revisions.
*/
/*
* Configuration constants
*/
/*
* Memory controller registers are read via PCI config space accesses on
* bus 0, device 0x18 + 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
*/
enum mc_funcnum {
MC_FUNC_HTCONFIG = 0,
MC_FUNC_ADDRMAP = 1,
MC_FUNC_DRAMCTL = 2,
MC_FUNC_MISCCTL = 3
};
/*
* For a given (bus, device, function) a particular offset selects the
* desired register. All registers are 32-bits wide.
*
* 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
* structures and macros defined below to be in those attach codepaths.
*/
/*
* Function 0 (HT Config) offsets
*/
#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
/*
* Function 1 (address map) offsets for DRAM base, DRAM limit, DRAM hole
* registers.
*/
/*
* Function 2 (dram controller) offsets for chip-select base, chip-select mask,
* DRAM bank address mapping, DRAM configuration registers.
*/
/*
* Function 3 (misc control) offset for NB MCA config, scrubber control,
* online spare control and NB capabilities.
*/
/*
* MC4_MISC MSR and MC4_MISCj MSRs
*/
#define MC_MSR_NB_MISC0 0x413
#define MC_MSR_NB_MISC1 0xc0000408
#define MC_MSR_NB_MISC2 0xc0000409
#define MC_MSR_NB_MISC3 0xc000040a
#define MC_MSR_NB_MISC(j) \
/*
* PCI 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
* 'f_preF' - applies to revisions E and earlier
* 'f_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_REV_UNKNOWN X86_CHIPREV_UNKNOWN
#define MC_F_REV_B X86_CHIPREV_AMD_F_REV_B
#define MC_F_REV_D X86_CHIPREV_AMD_F_REV_D
#define MC_F_REV_E X86_CHIPREV_AMD_F_REV_E
#define MC_F_REV_F X86_CHIPREV_AMD_F_REV_F
#define MC_F_REV_G X86_CHIPREV_AMD_F_REV_G
#define MC_10_REV_A X86_CHIPREV_AMD_10_REV_A
#define MC_10_REV_B X86_CHIPREV_AMD_10_REV_B
/*
* The most common groupings for memory controller features.
*/
/*
* Is 'rev' included in the 'revmask' bitmask?
*/
/*
* Is 'rev' at least revision 'revmin' or greater
*/
/*
* Access a field that has the same structure in all families and revisions
*/
/*
* Access a field as defined for family 0xf prior to revision F
*/
/*
* Access a field as defined for family 0xf revisions F and G
*/
/*
* Access a field as defined for family 0x10 revisions A and
*/
/*
* We will only define the register bitfields for little-endian order
*/
#ifdef _BIT_FIELDS_LTOH
/*
* Function 0 - HT Configuration: Routing Table Node Register
*/
union mcreg_htroute {
struct {
} _fmt_cmn;
};
/*
* Function 0 - HT Configuration: Node ID Register
*/
union mcreg_nodeid {
struct {
} _fmt_cmn;
};
/*
* Function 0 - HT Configuration: Unit ID Register
*/
union mcreg_unitid {
struct {
} _fmt_cmn;
};
/*
* Function 1 - DRAM Address Map: DRAM Base i Registers
*
*/
union mcreg_drambase {
struct {
} _fmt_cmn;
};
/*
* Function 1 - DRAM Address Map: DRAM Limit i Registers
*
*/
union mcreg_dramlimit {
struct {
} _fmt_cmn;
};
#define MC_DRAMLIM(up) \
/*
* Function 1 - DRAM Address Map: DRAM Hole Address Register
*/
union mcreg_dramhole {
struct {
} _fmt_cmn;
};
/*
* Function 2 - DRAM Controller: DRAM CS Base Address Registers
*/
union mcreg_csbase {
/*
* Register format in family 0xf revisions E and earlier
*/
struct {
} _fmt_f_preF;
/*
* Register format in family 0xf revisions F and G
*/
struct {
} _fmt_f_revFG;
};
/*
* Function 2 - DRAM Controller: DRAM CS Mask Registers
*/
union mcreg_csmask {
/*
* Register format in family 0xf revisions E and earlier
*/
struct {
} _fmt_f_preF;
/*
* Register format in family 0xf revisions F and G
*/
struct {
} _fmt_f_revFG;
};
/*
* Function 2 - DRAM Controller: DRAM Bank Address Mapping Registers
*/
union mcreg_bankaddrmap {
/*
* Register format in family 0xf revisions E and earlier
*/
struct {
} _fmt_f_preF;
/*
* Register format in family 0xf revisions F and G
*/
struct {
} _fmt_f_revFG;
/*
* Accessing all mode encodings as one uint16
*/
struct {
};
#define MC_DC_BAM_CSBANK_MASK 0x0000000f
#define MC_DC_BAM_CSBANK_SHIFT 4
/*
* Function 2 - DRAM Controller: DRAM Configuration Low and High
*/
union mcreg_dramcfg_lo {
/*
* Register format in family 0xf 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 {
} _fmt_f_preF;
/*
* Register format in family 0xf revisions F and G
*/
struct {
} _fmt_f_revFG;
};
/*
* Function 2 - DRAM Controller: DRAM Controller Miscellaneous Data
*/
union mcreg_drammisc {
/*
* Register format in family 0xf revisions F and G
*/
struct {
} _fmt_f_revFG;
};
union mcreg_dramcfg_hi {
/*
* Register format in family 0xf revisions E and earlier.
*/
struct {
} _fmt_f_preF;
/*
* Register format in family 0xf revisions F and G
*/
struct {
} _fmt_f_revFG;
};
/*
* Function 3 - Miscellaneous Control: Scrub Control Register
*/
union mcreg_scrubctl {
struct {
} _fmt_cmn;
};
union mcreg_dramscrublo {
struct {
} _fmt_cmn;
};
union mcreg_dramscrubhi {
struct {
} _fmt_cmn;
};
/*
* Function 3 - Miscellaneous Control: On-Line Spare Control Register
*/
union mcreg_nbcfg {
/*
* Register format in family 0xf revisions E and earlier.
*/
struct {
} _fmt_f_preF;
/*
* Register format in family 0xf revisions F and G
*/
struct {
} _fmt_f_revFG;
};
/*
* Function 3 - Miscellaneous Control: On-Line Spare Control Register
*/
union mcreg_sparectl {
/*
* Register format in family 0xf revisions F and G
*/
struct {
} _fmt_f_revFG;
/*
* Regiser format in family 0x10 revisions A and B
*/
struct {
};
/*
* 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
* kernels and so 64-bit bitfields cannot be used.
*/
/*
* The NB MISC registers. On family 0xf rev F this was introduced with
* a 12-bit ECC error count of all ECC errors observed on this memory-
* controller (regardless of channel or chip-select) and the ability to
* raise an interrupt or SMI on overflow. In family 0x10 it has a similar
* purpose, but the register is is split into 4 misc registers
* 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 {
/*
* MSR format in family 0xf revision F and later
*/
struct {
/*
* Lower 32 bits
*/
struct {
} _mcimisc_lo;
/*
* Upper 32 bits
*/
struct {
} _mcimisc_hi;
} _fmt_f_revFG;
/*
* MSR format in family 0x10 revisions A and B
*/
struct {
/*
* Lower 32 bits
*/
struct {
} _mcimisc_lo;
/*
* Upper 32 bits
*/
struct {
} _mcimisc_hi;
};
#endif /* _BIT_FIELDS_LTOH */
#ifdef __cplusplus
}
#endif
#endif /* _MC_AMD_H */