diff options
author | gavinm <none@none> | 2007-03-05 18:48:06 -0800 |
---|---|---|
committer | gavinm <none@none> | 2007-03-05 18:48:06 -0800 |
commit | bb86c3425be684b7eaa9e875ec2740b39d444ec8 (patch) | |
tree | 9d28ff5f088c5ce277e166de77db76fa8bd5eb59 | |
parent | 9919ad433c5e53424e91d92208eb38d7fdf622d7 (diff) | |
download | illumos-gate-bb86c3425be684b7eaa9e875ec2740b39d444ec8.tar.gz |
6504327 make with no target in i86pc failsonnv_60
6521185 Solaris trusts BIOS too much wrt AMD erratum 172
6528027 fallback to cpu.generic if number of mca banks not as expected
-rw-r--r-- | usr/src/uts/i86pc/Makefile.workarounds | 4 | ||||
-rw-r--r-- | usr/src/uts/i86pc/cpu/amd_opteron/ao.h | 8 | ||||
-rw-r--r-- | usr/src/uts/i86pc/cpu/amd_opteron/ao_cpu.c | 14 | ||||
-rw-r--r-- | usr/src/uts/i86pc/cpu/amd_opteron/ao_main.c | 13 | ||||
-rw-r--r-- | usr/src/uts/i86pc/cpu/amd_opteron/ao_mca.c | 68 | ||||
-rw-r--r-- | usr/src/uts/i86pc/cpu/scripts/Makefile | 4 | ||||
-rw-r--r-- | usr/src/uts/i86pc/io/mc/mcamd.h | 89 | ||||
-rw-r--r-- | usr/src/uts/intel/sys/mc_amd.h | 129 | ||||
-rw-r--r-- | usr/src/uts/intel/sys/mca_amd.h | 17 |
9 files changed, 182 insertions, 164 deletions
diff --git a/usr/src/uts/i86pc/Makefile.workarounds b/usr/src/uts/i86pc/Makefile.workarounds index cdc555b44b..46e3b6f15d 100644 --- a/usr/src/uts/i86pc/Makefile.workarounds +++ b/usr/src/uts/i86pc/Makefile.workarounds @@ -107,3 +107,7 @@ WORKAROUND_DEFS += -DOPTERON_WORKAROUND_6336786 # WORKAROUND_DEFS += -DOPTERON_WORKAROUND_6323525 +# +# Some Registered DIMMs incompatible with address parity feature +# +WORKAROUND_DEFS += -DOPTERON_ERRATUM_172 diff --git a/usr/src/uts/i86pc/cpu/amd_opteron/ao.h b/usr/src/uts/i86pc/cpu/amd_opteron/ao.h index 89cc07ab1d..e5d1b8edee 100644 --- a/usr/src/uts/i86pc/cpu/amd_opteron/ao.h +++ b/usr/src/uts/i86pc/cpu/amd_opteron/ao.h @@ -20,7 +20,7 @@ */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -213,14 +213,16 @@ struct ao_chipshared { uint64_t aos_bcfg_nb_misc; /* BIOS value of MC4_MISC */ uint32_t aos_bcfg_nb_cfg; /* BIOS value of NB MCA Config */ uint32_t aos_bcfg_nb_sparectl; /* BIOS value of Online Spare Control */ + uint32_t aos_bcfg_dcfg_lo; /* BIOS value of DRAM Config Low */ + uint32_t aos_bcfg_dcfg_hi; /* BIOS value of DRAM Config High */ }; /* Bit numbers for aos_cfgonce */ enum ao_cfgonce_bitnum { - AO_CFGONCE_NBMCA + AO_CFGONCE_NBMCA, + AO_CFGONCE_DRAMCFG }; - /* * Per-CPU state */ diff --git a/usr/src/uts/i86pc/cpu/amd_opteron/ao_cpu.c b/usr/src/uts/i86pc/cpu/amd_opteron/ao_cpu.c index 55084167b8..9d0fa32336 100644 --- a/usr/src/uts/i86pc/cpu/amd_opteron/ao_cpu.c +++ b/usr/src/uts/i86pc/cpu/amd_opteron/ao_cpu.c @@ -123,7 +123,7 @@ ao_scrubber_enable(void *data, uint64_t base, uint64_t ilen, int csdiscontig) * If ao_scrub_policy is DEFAULT, return immediately. Otherwise we * disable scrubbing activity while we fiddle with the configuration. */ - scrubctl = ao_pcicfg_read(chipid, AMD_NB_FUNC, AMD_NB_REG_SCRUBCTL); + scrubctl = ao_pcicfg_read(chipid, MC_FUNC_MISCCTL, MC_CTL_REG_SCRUBCTL); cas32(&ao_scrub_bios, 0, scrubctl); if (ao_scrub_policy == AO_SCRUB_BIOSDEFAULT) @@ -133,15 +133,15 @@ ao_scrubber_enable(void *data, uint64_t base, uint64_t ilen, int csdiscontig) scrubctl &= ~AMD_NB_SCRUBCTL_L2_MASK; scrubctl &= ~AMD_NB_SCRUBCTL_DC_MASK; - ao_pcicfg_write(chipid, AMD_NB_FUNC, AMD_NB_REG_SCRUBCTL, scrubctl); + ao_pcicfg_write(chipid, MC_FUNC_MISCCTL, MC_CTL_REG_SCRUBCTL, scrubctl); /* * Read the DRAM Scrub Address Low and High registers, clear their * address fields, enable sequential-redirect mode, and update the * address fields using the specified DRAM Base Address. */ - lo = ao_pcicfg_read(chipid, AMD_NB_FUNC, AMD_NB_REG_SCRUBADDR_LO); - hi = ao_pcicfg_read(chipid, AMD_NB_FUNC, AMD_NB_REG_SCRUBADDR_HI); + lo = ao_pcicfg_read(chipid, MC_FUNC_MISCCTL, MC_CTL_REG_SCRUBADDR_LO); + hi = ao_pcicfg_read(chipid, MC_FUNC_MISCCTL, MC_CTL_REG_SCRUBADDR_HI); lo &= ~AMD_NB_SCRUBADDR_LO_MASK; hi &= ~AMD_NB_SCRUBADDR_HI_MASK; @@ -152,8 +152,8 @@ ao_scrubber_enable(void *data, uint64_t base, uint64_t ilen, int csdiscontig) ao_scrub_lo = lo; ao_scrub_hi = hi; - ao_pcicfg_write(chipid, AMD_NB_FUNC, AMD_NB_REG_SCRUBADDR_LO, lo); - ao_pcicfg_write(chipid, AMD_NB_FUNC, AMD_NB_REG_SCRUBADDR_HI, hi); + ao_pcicfg_write(chipid, MC_FUNC_MISCCTL, MC_CTL_REG_SCRUBADDR_LO, lo); + ao_pcicfg_write(chipid, MC_FUNC_MISCCTL, MC_CTL_REG_SCRUBADDR_HI, hi); if (ao_scrub_rate_dcache > AMD_NB_SCRUBCTL_RATE_MAX) { cmn_err(CE_WARN, "ao_scrub_rate_dcache is too large; " @@ -235,7 +235,7 @@ ao_scrubber_enable(void *data, uint64_t base, uint64_t ilen, int csdiscontig) ao_scrub_rate_l2cache, ao_scrub_rate_dram); ao_scrub_system = scrubctl; - ao_pcicfg_write(chipid, AMD_NB_FUNC, AMD_NB_REG_SCRUBCTL, scrubctl); + ao_pcicfg_write(chipid, MC_FUNC_MISCCTL, MC_CTL_REG_SCRUBCTL, scrubctl); return (rv); } diff --git a/usr/src/uts/i86pc/cpu/amd_opteron/ao_main.c b/usr/src/uts/i86pc/cpu/amd_opteron/ao_main.c index 908786702d..6bef5143ee 100644 --- a/usr/src/uts/i86pc/cpu/amd_opteron/ao_main.c +++ b/usr/src/uts/i86pc/cpu/amd_opteron/ao_main.c @@ -71,6 +71,19 @@ ao_init(cpu_t *cp, void **datap) if (!(cap & MCG_CAP_CTL_P)) return (ENOTSUP); + /* + * Arrange to fallback to generic.cpu if the bank count is not + * as expected. We're not silent about this - if we have X86_MCA + * and MCG_CAP_CTL_P then we appear not to be virtualized. + */ + if ((cap & MCG_CAP_COUNT_MASK) != AMD_MCA_BANK_COUNT) { + cmn_err(CE_WARN, "CPU %d has %llu MCA banks; expected %u: " + "disabling AMD-specific MCA support on this CPU", + cp->cpu_id, (u_longlong_t)cap & MCG_CAP_COUNT_MASK, + AMD_MCA_BANK_COUNT); + return (ENOTSUP); + } + ao = *datap = kmem_zalloc(sizeof (ao_data_t), KM_SLEEP); ao->ao_cpu = cp; diff --git a/usr/src/uts/i86pc/cpu/amd_opteron/ao_mca.c b/usr/src/uts/i86pc/cpu/amd_opteron/ao_mca.c index c9adcde2cf..2de117b07d 100644 --- a/usr/src/uts/i86pc/cpu/amd_opteron/ao_mca.c +++ b/usr/src/uts/i86pc/cpu/amd_opteron/ao_mca.c @@ -408,7 +408,7 @@ nb_mcamisc_init(ao_data_t *ao, uint32_t rev) } /* - * NorthBridge (NB) Configuration. + * NorthBridge (NB) MCA Configuration. * * We add and remove bits from the BIOS-configured value, rather than * writing an absolute value. The variables ao_nb_cfg_{add,remove}_cmn and @@ -483,7 +483,7 @@ ao_nb_cfg(ao_data_t *ao, uint32_t rev) * modify the settings accordingly, and store the new value back. */ ao->ao_shared->aos_bcfg_nb_cfg = val = - ao_pcicfg_read(chipid, AMD_NB_FUNC, AMD_NB_REG_CFG); + ao_pcicfg_read(chipid, MC_FUNC_MISCCTL, MC_CTL_REG_NBCFG); switch (ao_nb_watchdog_policy) { case AO_NB_WDOG_LEAVEALONE: @@ -528,7 +528,28 @@ ao_nb_cfg(ao_data_t *ao, uint32_t rev) nbcp++; } - ao_pcicfg_write(chipid, AMD_NB_FUNC, AMD_NB_REG_CFG, val); + ao_pcicfg_write(chipid, MC_FUNC_MISCCTL, MC_CTL_REG_NBCFG, val); +} + +static void +ao_dram_cfg(ao_data_t *ao, uint32_t rev) +{ + uint_t chipid = pg_plat_hw_instance_id(CPU, PGHW_CHIP); + union mcreg_dramcfg_lo dcfglo; + + ao->ao_shared->aos_bcfg_dcfg_lo = MCREG_VAL32(&dcfglo) = + ao_pcicfg_read(chipid, MC_FUNC_DRAMCTL, MC_DC_REG_DRAMCFGLO); + ao->ao_shared->aos_bcfg_dcfg_hi = + ao_pcicfg_read(chipid, MC_FUNC_DRAMCTL, MC_DC_REG_DRAMCFGHI); + +#ifdef OPTERON_ERRATUM_172 + if (X86_CHIPREV_MATCH(rev, AO_REVS_FG) && + MCREG_FIELD_revFG(&dcfglo, ParEn)) { + MCREG_FIELD_revFG(&dcfglo, ParEn) = 0; + ao_pcicfg_write(chipid, MC_FUNC_DRAMCTL, MC_DC_REG_DRAMCFGLO, + MCREG_VAL32(&dcfglo)); + } +#endif } /* @@ -552,7 +573,7 @@ ao_sparectl_cfg(ao_data_t *ao) int chan, cs; ao->ao_shared->aos_bcfg_nb_sparectl = MCREG_VAL32(&sparectl) = - ao_pcicfg_read(chipid, AMD_NB_FUNC, AMD_NB_REG_SPARECTL); + ao_pcicfg_read(chipid, MC_FUNC_MISCCTL, MC_CTL_REG_SPARECTL); if (ao_nb_cfg_sparectl_noseize) return; /* stash BIOS value, but no changes */ @@ -568,7 +589,7 @@ ao_sparectl_cfg(ao_data_t *ao) MCREG_FIELD_revFG(&sparectl, EccErrCntWrEn) = 1; /* First write, preparing for writes to EccErrCnt */ - ao_pcicfg_write(chipid, AMD_NB_FUNC, AMD_NB_REG_SPARECTL, + ao_pcicfg_write(chipid, MC_FUNC_MISCCTL, MC_CTL_REG_SPARECTL, MCREG_VAL32(&sparectl)); /* @@ -580,8 +601,8 @@ ao_sparectl_cfg(ao_data_t *ao) for (cs = 0; cs < MC_CHIP_NCS; cs++) { MCREG_FIELD_revFG(&sparectl, EccErrCntDramCs) = cs; - ao_pcicfg_write(chipid, AMD_NB_FUNC, - AMD_NB_REG_SPARECTL, MCREG_VAL32(&sparectl)); + ao_pcicfg_write(chipid, MC_FUNC_MISCCTL, + MC_CTL_REG_SPARECTL, MCREG_VAL32(&sparectl)); } } } @@ -1052,25 +1073,21 @@ ao_mca_init(void *data) { ao_data_t *ao = data; ao_mca_t *mca = &ao->ao_mca; - uint64_t cap; + uint64_t cap = rdmsr(IA32_MSR_MCG_CAP); uint32_t rev; - int donb; + int donb, dodcfg; int i; - ASSERT(x86_feature & X86_MCA); - cap = rdmsr(IA32_MSR_MCG_CAP); - ASSERT(cap & MCG_CAP_CTL_P); - /* - * If the hardware's bank count is different than what we expect, then - * we're running on some Opteron variant that we don't understand yet. + * cmi_mca_init is only called during cpu startup if features include + * X86_MCA (defined as both MCA and MCE support indicated by CPUID). + * Furthermore, our ao_init function returns ENOTSUP if features + * lacked X86_MCA, IA32_MSR_MCG_CAP lacks MCG_CAP_CTL_P, or the + * cpu has an unexpected number of detector banks. */ - if ((cap & MCG_CAP_COUNT_MASK) != AMD_MCA_BANK_COUNT) { - cmn_err(CE_WARN, "CPU %d has %llu MCA banks; expected %u: " - "disabling MCA on this CPU", ao->ao_cpu->cpu_id, - (u_longlong_t)cap & MCG_CAP_COUNT_MASK, AMD_MCA_BANK_COUNT); - return; - } + ASSERT(x86_feature & X86_MCA); + ASSERT(cap & MCG_CAP_CTL_P); + ASSERT((cap & MCG_CAP_COUNT_MASK) == AMD_MCA_BANK_COUNT); /* * Configure the logout areas. We preset every logout area's acl_ao @@ -1086,10 +1103,11 @@ ao_mca_init(void *data) rev = ao->ao_shared->aos_chiprev = cpuid_getchiprev(ao->ao_cpu); /* - * Must this core perform NB MCA configuration? This must be done - * by just one core. + * Must this core perform NB MCA or DRAM configuration? This must be + * done by just one core. */ donb = ao_chip_once(ao, AO_CFGONCE_NBMCA); + dodcfg = ao_chip_once(ao, AO_CFGONCE_DRAMCFG); /* * Initialize poller data, but don't start polling yet. @@ -1107,10 +1125,12 @@ ao_mca_init(void *data) ao_bank_cfg(ao, rev, donb); /* - * Modify the MCA NB Configuration Register. + * Modify the MCA NB Configuration and Dram Configuration Registers. */ if (donb) ao_nb_cfg(ao, rev); + if (dodcfg) + ao_dram_cfg(ao, rev); /* * Setup the Online Spare Control Register diff --git a/usr/src/uts/i86pc/cpu/scripts/Makefile b/usr/src/uts/i86pc/cpu/scripts/Makefile index 4d40d76a64..1d06c1fe0c 100644 --- a/usr/src/uts/i86pc/cpu/scripts/Makefile +++ b/usr/src/uts/i86pc/cpu/scripts/Makefile @@ -20,7 +20,7 @@ # # -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # ident "%Z%%M% %I% %E% SMI" @@ -36,7 +36,7 @@ GROUP= bin .KEEP_STATE: -all install setup: $(PERLFILES) +def all install setup: $(PERLFILES) clean clobber: $(RM) $(PERLFILES) diff --git a/usr/src/uts/i86pc/io/mc/mcamd.h b/usr/src/uts/i86pc/io/mc/mcamd.h index 8ad790f1f8..08c5b918dd 100644 --- a/usr/src/uts/i86pc/io/mc/mcamd.h +++ b/usr/src/uts/i86pc/io/mc/mcamd.h @@ -29,6 +29,12 @@ #pragma ident "%Z%%M% %I% %E% SMI" +/* + * Header file for the mc-amd AMD memory-controller driver. This should be + * included from that driver source alone - any more-widely useful definitions + * belong in mc_amd.h. + */ + #include <sys/types.h> #include <sys/ddi.h> #include <sys/sunddi.h> @@ -41,77 +47,32 @@ extern "C" { #endif +#if MC_CHIP_DIMMPERCS > MC_UNUM_NDIMM +#error "MC_CHIP_DIMMPERCS exceeds MC_UNUM_NDIMM" +#endif + /* - * PCI configuration space functions for the memory controller. Note that - * the function numbers here also serve as the mc_func indices in the mc_t. - * We will not attach to function 3 "Miscellaneous Control" pci1022,1103 + * The memory controller configuration registers are accessed via PCI bus 0, + * device 0x18 + nodeid, functions 0 to 3. The function numbers are + * MC_FUNC_*, defined in mc_amd.h. + * + * We do not attach to function 3 "Miscellaneous Control" pci1022,1103 * since the agpgart driver already attaches to that function; instead we * retrieve what function 3 parameters we require via direct PCI Mechanism 1 - * accesses. - */ -enum mc_funcnum { - MC_FUNC_HTCONFIG = 0, -#define MC_FUNC_HTCONFIG_BINDNM "pci1022,1100" - MC_FUNC_ADDRMAP = 1, -#define MC_FUNC_ADDRMAP_BINDNM "pci1022,1101" - MC_FUNC_DRAMCTL = 2, -#define MC_FUNC_DRAMCTL_BINDNM "pci1022,1102" - MC_FUNC_MISCCTL = 3 -}; - -/* - * The memory controller driver attaches to several device nodes, but publishes + * accesses + * + * The memory controller driver attaches to these device nodes, but publishes * a single minor node. We need to ensure that the minor node can be - * consistently mapped back to a single (and the same) device node, so we need - * to pick one to be used. We'll use the misc control device node, as it'll - * be the last to be attached (since we do not attach function 3) + * consistently mapped back to a single (and the same) device node, so we + * need to pick one to be used. We'll use the dram address map device node, + * as it'll be the last to be attached. */ #define MC_FUNC_DEVIMAP MC_FUNC_DRAMCTL +#define MC_FUNC_NUM (MC_FUNC_MISCCTL + 1) -#define MC_FUNC_NUM 4 /* include MISCCTL, even if no attach */ - -/* - * The following define the offsets at which various MC registers are - * accessed in PCI config space. For defines describing the register - * structure see mc_amd.h. - */ - -/* - * 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 mask) offsets for DRAM base, DRAM limit, DRAM hole - * registers. - */ -#define MC_AM_REG_DRAMBASE_0 0x40 /* Offset for DRAM Base 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_HOLEADDR 0xf0 /* DRAM Hole Address Register */ - -/* - * Function 2 (dram controller) offsets for chip-select base, chip-select mask, - * DRAM bank address mapping, DRAM configuration registers. - */ -#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_CSMASK_0 0x60 /* 0x60 - 0x7c */ -#define MC_DC_REG_BANKADDRMAP 0x80 -#define MC_DC_REG_DRAMCFGLO 0x90 -#define MC_DC_REG_DRAMCFGHI 0x94 -#define MC_DC_REG_DRAMMISC 0xa0 - -/* - * Function 3 (misc control) offset for NB MCA config, scrubber control - * and online spare control. - */ -#define MC_CTL_REG_NBCFG 0x44 /* MCA NB configuration register */ -#define MC_CTL_REG_SCRUBCTL 0x58 /* Scrub control register */ -#define MC_CTL_REG_SPARECTL 0xb0 /* On-line spare control register */ +#define MC_FUNC_HTCONFIG_BINDNM "pci1022,1100" +#define MC_FUNC_ADDRMAP_BINDNM "pci1022,1101" +#define MC_FUNC_DRAMCTL_BINDNM "pci1022,1102" typedef struct mc_func { uint_t mcf_instance; diff --git a/usr/src/uts/intel/sys/mc_amd.h b/usr/src/uts/intel/sys/mc_amd.h index f879329150..6e799b2cf2 100644 --- a/usr/src/uts/intel/sys/mc_amd.h +++ b/usr/src/uts/intel/sys/mc_amd.h @@ -18,7 +18,7 @@ * * CDDL HEADER END * - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -35,6 +35,12 @@ 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 @@ -116,52 +122,6 @@ extern "C" { #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 - -/* - * The most common groupings for memory controller features. - */ -#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) - -/* - * Is 'rev' included in the 'revmask' bitmask? - */ -#define MC_REV_MATCH(rev, revmask) X86_CHIPREV_MATCH(rev, revmask) - -/* - * Is 'rev' at least revision 'revmin' or greater - */ -#define MC_REV_ATLEAST(rev, minrev) X86_CHIPREV_ATLEAST(rev, minrev) - -/* - * 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: @@ -170,7 +130,15 @@ extern "C" { * 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. * @@ -190,6 +158,45 @@ extern "C" { */ /* + * 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. + */ +#define MC_AM_REG_DRAMBASE_0 0x40 /* Offset for DRAM Base 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_HOLEADDR 0xf0 /* DRAM Hole Address Register */ + +/* + * Function 2 (dram controller) offsets for chip-select base, chip-select mask, + * DRAM bank address mapping, DRAM configuration registers. + */ +#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_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 */ + +/* + * Function 3 (misc control) offset for NB MCA config, scrubber control + * and online spare control. + */ +#define MC_CTL_REG_NBCFG 0x44 /* MCA NB configuration register */ +#define MC_CTL_REG_SCRUBCTL 0x58 /* Scrub control register */ +#define MC_CTL_REG_SCRUBADDR_LO 0x5c /* DRAM Scrub Address Low */ +#define MC_CTL_REG_SCRUBADDR_HI 0x60 /* DRAM Scrub Address High */ +#define MC_CTL_REG_SPARECTL 0xb0 /* On-line spare control register */ + +/* * 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 @@ -214,6 +221,32 @@ extern "C" { * can lookup that member based on revision only. */ +#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 + +/* + * The most common groupings for memory controller features. + */ +#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) + +/* + * Is 'rev' included in the 'revmask' bitmask? + */ +#define MC_REV_MATCH(rev, revmask) X86_CHIPREV_MATCH(rev, revmask) + +/* + * Is 'rev' at least revision 'revmin' or greater + */ +#define MC_REV_ATLEAST(rev, minrev) X86_CHIPREV_ATLEAST(rev, minrev) + #define _MCREG_FIELD(up, revsuffix, field) ((up)->_fmt_##revsuffix.field) #define MCREG_VAL32(up) ((up)->_val32) diff --git a/usr/src/uts/intel/sys/mca_amd.h b/usr/src/uts/intel/sys/mca_amd.h index 6d45691c14..5adbf02965 100644 --- a/usr/src/uts/intel/sys/mca_amd.h +++ b/usr/src/uts/intel/sys/mca_amd.h @@ -20,7 +20,7 @@ */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -321,21 +321,6 @@ extern "C" { (((uint64_t)(synd) << AMD_BANK_STAT_SYND_SHIFT) & \ AMD_BANK_STAT_SYND_MASK) -/* northbridge (NB) status registers */ - -#define AMD_NB_FUNC 3 -#define AMD_NB_REG_CFG 0x44 -#define AMD_NB_REG_STLO 0x48 /* alias: NB_STATUS[0:31] */ -#define AMD_NB_REG_STHI 0x4c /* alias: NB_STATUS[32:63] */ -#define AMD_NB_REG_ADDRLO 0x50 /* alias: NB_ADDR[0:31] */ -#define AMD_NB_REG_ADDRHI 0x54 /* alias: NB_ADDR[32:63] */ - -#define AMD_NB_REG_SCRUBCTL 0x58 -#define AMD_NB_REG_SCRUBADDR_LO 0x5c -#define AMD_NB_REG_SCRUBADDR_HI 0x60 - -#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 |