20c794b39650d115e17a15983b6b82e46238cf45gavinm/*
20c794b39650d115e17a15983b6b82e46238cf45gavinm * CDDL HEADER START
20c794b39650d115e17a15983b6b82e46238cf45gavinm *
20c794b39650d115e17a15983b6b82e46238cf45gavinm * The contents of this file are subject to the terms of the
20c794b39650d115e17a15983b6b82e46238cf45gavinm * Common Development and Distribution License (the "License").
20c794b39650d115e17a15983b6b82e46238cf45gavinm * You may not use this file except in compliance with the License.
20c794b39650d115e17a15983b6b82e46238cf45gavinm *
20c794b39650d115e17a15983b6b82e46238cf45gavinm * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
20c794b39650d115e17a15983b6b82e46238cf45gavinm * or http://www.opensolaris.org/os/licensing.
20c794b39650d115e17a15983b6b82e46238cf45gavinm * See the License for the specific language governing permissions
20c794b39650d115e17a15983b6b82e46238cf45gavinm * and limitations under the License.
20c794b39650d115e17a15983b6b82e46238cf45gavinm *
20c794b39650d115e17a15983b6b82e46238cf45gavinm * When distributing Covered Code, include this CDDL HEADER in each
20c794b39650d115e17a15983b6b82e46238cf45gavinm * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
20c794b39650d115e17a15983b6b82e46238cf45gavinm * If applicable, add the following below this CDDL HEADER, with the
20c794b39650d115e17a15983b6b82e46238cf45gavinm * fields enclosed by brackets "[]" replaced with your own identifying
20c794b39650d115e17a15983b6b82e46238cf45gavinm * information: Portions Copyright [yyyy] [name of copyright owner]
20c794b39650d115e17a15983b6b82e46238cf45gavinm *
20c794b39650d115e17a15983b6b82e46238cf45gavinm * CDDL HEADER END
20c794b39650d115e17a15983b6b82e46238cf45gavinm */
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm/*
c84b7bbef5ecc2a27799422588073deefd9db715Adrian Frost * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
20c794b39650d115e17a15983b6b82e46238cf45gavinm */
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm/*
20c794b39650d115e17a15983b6b82e46238cf45gavinm * "Generic AMD" model-specific support. If no more-specific support can
20c794b39650d115e17a15983b6b82e46238cf45gavinm * be found, or such modules declines to initialize, then for AuthenticAMD
20c794b39650d115e17a15983b6b82e46238cf45gavinm * cpus this module can have a crack at providing some AMD model-specific
20c794b39650d115e17a15983b6b82e46238cf45gavinm * support that at least goes beyond common MCA architectural features
20c794b39650d115e17a15983b6b82e46238cf45gavinm * if not down to the nitty-gritty level for a particular model. We
20c794b39650d115e17a15983b6b82e46238cf45gavinm * are layered on top of a cpu module, likely cpu.generic, so there is no
20c794b39650d115e17a15983b6b82e46238cf45gavinm * need for us to perform common architecturally-accessible functions.
20c794b39650d115e17a15983b6b82e46238cf45gavinm */
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm#include <sys/types.h>
20c794b39650d115e17a15983b6b82e46238cf45gavinm#include <sys/cmn_err.h>
20c794b39650d115e17a15983b6b82e46238cf45gavinm#include <sys/modctl.h>
20c794b39650d115e17a15983b6b82e46238cf45gavinm#include <sys/cpu_module.h>
20c794b39650d115e17a15983b6b82e46238cf45gavinm#include <sys/mca_x86.h>
20c794b39650d115e17a15983b6b82e46238cf45gavinm#include <sys/pci_cfgspace.h>
20c794b39650d115e17a15983b6b82e46238cf45gavinm#include <sys/x86_archext.h>
20c794b39650d115e17a15983b6b82e46238cf45gavinm#include <sys/mc_amd.h>
20c794b39650d115e17a15983b6b82e46238cf45gavinm#include <sys/fm/protocol.h>
20c794b39650d115e17a15983b6b82e46238cf45gavinm#include <sys/fm/cpu/GENAMD.h>
074bb90d80fdbeb2d04a8450a55ecbc96de28785Tom Pothier#include <sys/fm/smb/fmsmb.h>
074bb90d80fdbeb2d04a8450a55ecbc96de28785Tom Pothier#include <sys/fm/util.h>
20c794b39650d115e17a15983b6b82e46238cf45gavinm#include <sys/nvpair.h>
20c794b39650d115e17a15983b6b82e46238cf45gavinm#include <sys/controlregs.h>
20c794b39650d115e17a15983b6b82e46238cf45gavinm#include <sys/pghw.h>
20c794b39650d115e17a15983b6b82e46238cf45gavinm#include <sys/sunddi.h>
25f476773dea2a0ee593dcf662a38d5f02487196gavinm#include <sys/sysmacros.h>
20c794b39650d115e17a15983b6b82e46238cf45gavinm#include <sys/cpu_module_ms_impl.h>
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm#include "authamd.h"
20c794b39650d115e17a15983b6b82e46238cf45gavinm
074bb90d80fdbeb2d04a8450a55ecbc96de28785Tom Pothierextern int x86gentopo_legacy; /* x86 generic topo support */
074bb90d80fdbeb2d04a8450a55ecbc96de28785Tom Pothier
20c794b39650d115e17a15983b6b82e46238cf45gavinmint authamd_ms_support_disable = 0;
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm#define AUTHAMD_F_REVS_BCDE \
20c794b39650d115e17a15983b6b82e46238cf45gavinm (X86_CHIPREV_AMD_F_REV_B | X86_CHIPREV_AMD_F_REV_C0 | \
20c794b39650d115e17a15983b6b82e46238cf45gavinm X86_CHIPREV_AMD_F_REV_CG | X86_CHIPREV_AMD_F_REV_D | \
20c794b39650d115e17a15983b6b82e46238cf45gavinm X86_CHIPREV_AMD_F_REV_E)
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm#define AUTHAMD_F_REVS_FG \
20c794b39650d115e17a15983b6b82e46238cf45gavinm (X86_CHIPREV_AMD_F_REV_F | X86_CHIPREV_AMD_F_REV_G)
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm#define AUTHAMD_10_REVS_AB \
20c794b39650d115e17a15983b6b82e46238cf45gavinm (X86_CHIPREV_AMD_10_REV_A | X86_CHIPREV_AMD_10_REV_B)
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm/*
20c794b39650d115e17a15983b6b82e46238cf45gavinm * Bitmasks of support for various features. Try to enable features
20c794b39650d115e17a15983b6b82e46238cf45gavinm * via inclusion in one of these bitmasks and check that at the
20c794b39650d115e17a15983b6b82e46238cf45gavinm * feature imlementation - that way new family support may often simply
20c794b39650d115e17a15983b6b82e46238cf45gavinm * simply need to update these bitmasks.
20c794b39650d115e17a15983b6b82e46238cf45gavinm */
20c794b39650d115e17a15983b6b82e46238cf45gavinm
a4e4e13f4001644f2f960e3be0056c22b3a40fd1gavinm/*
a4e4e13f4001644f2f960e3be0056c22b3a40fd1gavinm * Models that include an on-chip NorthBridge.
a4e4e13f4001644f2f960e3be0056c22b3a40fd1gavinm */
a4e4e13f4001644f2f960e3be0056c22b3a40fd1gavinm#define AUTHAMD_NBONCHIP(rev) \
a4e4e13f4001644f2f960e3be0056c22b3a40fd1gavinm (X86_CHIPREV_ATLEAST(rev, X86_CHIPREV_AMD_F_REV_B) || \
a4e4e13f4001644f2f960e3be0056c22b3a40fd1gavinm X86_CHIPREV_ATLEAST(rev, X86_CHIPREV_AMD_10_REV_A))
a4e4e13f4001644f2f960e3be0056c22b3a40fd1gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm/*
20c794b39650d115e17a15983b6b82e46238cf45gavinm * Families/revisions for which we can recognise main memory ECC errors.
20c794b39650d115e17a15983b6b82e46238cf45gavinm */
20c794b39650d115e17a15983b6b82e46238cf45gavinm#define AUTHAMD_MEMECC_RECOGNISED(rev) \
20c794b39650d115e17a15983b6b82e46238cf45gavinm (X86_CHIPREV_ATLEAST(rev, X86_CHIPREV_AMD_F_REV_B) || \
20c794b39650d115e17a15983b6b82e46238cf45gavinm X86_CHIPREV_ATLEAST(rev, X86_CHIPREV_AMD_10_REV_A))
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm/*
20c794b39650d115e17a15983b6b82e46238cf45gavinm * Families/revisions that have an Online Spare Control Register
20c794b39650d115e17a15983b6b82e46238cf45gavinm */
20c794b39650d115e17a15983b6b82e46238cf45gavinm#define AUTHAMD_HAS_ONLINESPARECTL(rev) \
20c794b39650d115e17a15983b6b82e46238cf45gavinm (X86_CHIPREV_ATLEAST(rev, X86_CHIPREV_AMD_F_REV_F) || \
20c794b39650d115e17a15983b6b82e46238cf45gavinm X86_CHIPREV_ATLEAST(rev, X86_CHIPREV_AMD_10_REV_A))
20c794b39650d115e17a15983b6b82e46238cf45gavinm
25f476773dea2a0ee593dcf662a38d5f02487196gavinm/*
25f476773dea2a0ee593dcf662a38d5f02487196gavinm * Families/revisions for which we will perform NB MCA Config changes
25f476773dea2a0ee593dcf662a38d5f02487196gavinm */
25f476773dea2a0ee593dcf662a38d5f02487196gavinm#define AUTHAMD_DO_NBMCACFG(rev) \
a4e4e13f4001644f2f960e3be0056c22b3a40fd1gavinm (X86_CHIPREV_ATLEAST(rev, X86_CHIPREV_AMD_F_REV_B) || \
25f476773dea2a0ee593dcf662a38d5f02487196gavinm X86_CHIPREV_ATLEAST(rev, X86_CHIPREV_AMD_10_REV_A))
25f476773dea2a0ee593dcf662a38d5f02487196gavinm
25f476773dea2a0ee593dcf662a38d5f02487196gavinm/*
25f476773dea2a0ee593dcf662a38d5f02487196gavinm * Families/revisions that have chip cache scrubbers.
25f476773dea2a0ee593dcf662a38d5f02487196gavinm */
25f476773dea2a0ee593dcf662a38d5f02487196gavinm#define AUTHAMD_HAS_CHIPSCRUB(rev) \
a4e4e13f4001644f2f960e3be0056c22b3a40fd1gavinm (X86_CHIPREV_ATLEAST(rev, X86_CHIPREV_AMD_F_REV_B) || \
25f476773dea2a0ee593dcf662a38d5f02487196gavinm X86_CHIPREV_ATLEAST(rev, X86_CHIPREV_AMD_10_REV_A))
25f476773dea2a0ee593dcf662a38d5f02487196gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm/*
20c794b39650d115e17a15983b6b82e46238cf45gavinm * Families/revisions that have a NB misc register or registers -
20c794b39650d115e17a15983b6b82e46238cf45gavinm * evaluates to 0 if no support, otherwise the number of MC4_MISCj.
20c794b39650d115e17a15983b6b82e46238cf45gavinm */
20c794b39650d115e17a15983b6b82e46238cf45gavinm#define AUTHAMD_NBMISC_NUM(rev) \
20c794b39650d115e17a15983b6b82e46238cf45gavinm (X86_CHIPREV_ATLEAST(rev, X86_CHIPREV_AMD_F_REV_F)? 1 : \
20c794b39650d115e17a15983b6b82e46238cf45gavinm (X86_CHIPREV_ATLEAST(rev, X86_CHIPREV_AMD_10_REV_A) ? 3 : 0))
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm/*
20c794b39650d115e17a15983b6b82e46238cf45gavinm * Families/revision for which we wish not to machine check for GART
20c794b39650d115e17a15983b6b82e46238cf45gavinm * table walk errors - bit 10 of NB CTL.
20c794b39650d115e17a15983b6b82e46238cf45gavinm */
20c794b39650d115e17a15983b6b82e46238cf45gavinm#define AUTHAMD_NOGARTTBLWLK_MC(rev) \
20c794b39650d115e17a15983b6b82e46238cf45gavinm (X86_CHIPREV_ATLEAST(rev, X86_CHIPREV_AMD_F_REV_B) || \
20c794b39650d115e17a15983b6b82e46238cf45gavinm X86_CHIPREV_ATLEAST(rev, X86_CHIPREV_AMD_10_REV_A))
20c794b39650d115e17a15983b6b82e46238cf45gavinm
25f476773dea2a0ee593dcf662a38d5f02487196gavinm/*
25f476773dea2a0ee593dcf662a38d5f02487196gavinm * Families/revisions that are potentially L3 capable
25f476773dea2a0ee593dcf662a38d5f02487196gavinm */
25f476773dea2a0ee593dcf662a38d5f02487196gavinm#define AUTHAMD_L3CAPABLE(rev) \
25f476773dea2a0ee593dcf662a38d5f02487196gavinm (X86_CHIPREV_ATLEAST(rev, X86_CHIPREV_AMD_10_REV_A))
25f476773dea2a0ee593dcf662a38d5f02487196gavinm
5667185bc023b9742cb2480659d7673fa9ac8050Srihari Venkatesan/*
5667185bc023b9742cb2480659d7673fa9ac8050Srihari Venkatesan * Families/revisions that support x8 ChipKill ECC
5667185bc023b9742cb2480659d7673fa9ac8050Srihari Venkatesan */
5667185bc023b9742cb2480659d7673fa9ac8050Srihari Venkatesan#define AUTHAMD_SUPPORTS_X8ECC(rev) \
7932179448259e425d93162dedd251930575d83eJens Elkner (X86_CHIPREV_ATLEAST(rev, X86_CHIPREV_AMD_10_REV_D0))
5667185bc023b9742cb2480659d7673fa9ac8050Srihari Venkatesan
20c794b39650d115e17a15983b6b82e46238cf45gavinm/*
20c794b39650d115e17a15983b6b82e46238cf45gavinm * We recognise main memory ECC errors for AUTHAMD_MEMECC_RECOGNISED
20c794b39650d115e17a15983b6b82e46238cf45gavinm * revisions as:
20c794b39650d115e17a15983b6b82e46238cf45gavinm *
20c794b39650d115e17a15983b6b82e46238cf45gavinm * - being reported by the NB
20c794b39650d115e17a15983b6b82e46238cf45gavinm * - being a compound bus/interconnect error (external to chip)
20c794b39650d115e17a15983b6b82e46238cf45gavinm * - having LL of LG
20c794b39650d115e17a15983b6b82e46238cf45gavinm * - having II of MEM (but could still be a master/target abort)
20c794b39650d115e17a15983b6b82e46238cf45gavinm * - having CECC or UECC set
20c794b39650d115e17a15983b6b82e46238cf45gavinm *
20c794b39650d115e17a15983b6b82e46238cf45gavinm * We do not check the extended error code (first nibble of the
20c794b39650d115e17a15983b6b82e46238cf45gavinm * model-specific error code on AMD) since this has changed from
20c794b39650d115e17a15983b6b82e46238cf45gavinm * family 0xf to family 0x10 (ext code 0 now reserved on family 0x10).
20c794b39650d115e17a15983b6b82e46238cf45gavinm * Instead we use CECC/UECC to separate off the master/target
20c794b39650d115e17a15983b6b82e46238cf45gavinm * abort cases.
20c794b39650d115e17a15983b6b82e46238cf45gavinm *
20c794b39650d115e17a15983b6b82e46238cf45gavinm * We insist that the detector be the NorthBridge bank; although
20c794b39650d115e17a15983b6b82e46238cf45gavinm * IC/DC can report some main memory errors, they do not capture
20c794b39650d115e17a15983b6b82e46238cf45gavinm * an address at sufficient resolution to be useful and the NB will
20c794b39650d115e17a15983b6b82e46238cf45gavinm * report most errors.
20c794b39650d115e17a15983b6b82e46238cf45gavinm */
20c794b39650d115e17a15983b6b82e46238cf45gavinm#define AUTHAMD_IS_MEMECCERR(bank, status) \
20c794b39650d115e17a15983b6b82e46238cf45gavinm ((bank) == AMD_MCA_BANK_NB && \
20c794b39650d115e17a15983b6b82e46238cf45gavinm MCAX86_ERRCODE_ISBUS_INTERCONNECT(MCAX86_ERRCODE(status)) && \
20c794b39650d115e17a15983b6b82e46238cf45gavinm MCAX86_ERRCODE_LL(MCAX86_ERRCODE(status)) == MCAX86_ERRCODE_LL_LG && \
20c794b39650d115e17a15983b6b82e46238cf45gavinm MCAX86_ERRCODE_II(MCAX86_ERRCODE(status)) == MCAX86_ERRCODE_II_MEM && \
20c794b39650d115e17a15983b6b82e46238cf45gavinm ((status) & (AMD_BANK_STAT_CECC | AMD_BANK_STAT_UECC)))
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinmstatic authamd_error_disp_t authamd_memce_disp = {
20c794b39650d115e17a15983b6b82e46238cf45gavinm FM_EREPORT_CPU_GENAMD,
20c794b39650d115e17a15983b6b82e46238cf45gavinm FM_EREPORT_CPU_GENAMD_MEM_CE,
20c794b39650d115e17a15983b6b82e46238cf45gavinm FM_EREPORT_GENAMD_PAYLOAD_FLAGS_MEM_CE
20c794b39650d115e17a15983b6b82e46238cf45gavinm};
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinmstatic authamd_error_disp_t authamd_memue_disp = {
20c794b39650d115e17a15983b6b82e46238cf45gavinm FM_EREPORT_CPU_GENAMD,
20c794b39650d115e17a15983b6b82e46238cf45gavinm FM_EREPORT_CPU_GENAMD_MEM_UE,
20c794b39650d115e17a15983b6b82e46238cf45gavinm FM_EREPORT_GENAMD_PAYLOAD_FLAGS_MEM_UE
20c794b39650d115e17a15983b6b82e46238cf45gavinm};
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinmstatic authamd_error_disp_t authamd_ckmemce_disp = {
20c794b39650d115e17a15983b6b82e46238cf45gavinm FM_EREPORT_CPU_GENAMD,
20c794b39650d115e17a15983b6b82e46238cf45gavinm FM_EREPORT_CPU_GENAMD_CKMEM_CE,
20c794b39650d115e17a15983b6b82e46238cf45gavinm FM_EREPORT_GENAMD_PAYLOAD_FLAGS_CKMEM_CE
20c794b39650d115e17a15983b6b82e46238cf45gavinm};
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinmstatic authamd_error_disp_t authamd_ckmemue_disp = {
20c794b39650d115e17a15983b6b82e46238cf45gavinm FM_EREPORT_CPU_GENAMD,
20c794b39650d115e17a15983b6b82e46238cf45gavinm FM_EREPORT_CPU_GENAMD_CKMEM_UE,
20c794b39650d115e17a15983b6b82e46238cf45gavinm FM_EREPORT_GENAMD_PAYLOAD_FLAGS_CKMEM_UE
20c794b39650d115e17a15983b6b82e46238cf45gavinm};
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm/*
20c794b39650d115e17a15983b6b82e46238cf45gavinm * We recognise GART walk errors as:
20c794b39650d115e17a15983b6b82e46238cf45gavinm *
20c794b39650d115e17a15983b6b82e46238cf45gavinm * - being reported by the NB
20c794b39650d115e17a15983b6b82e46238cf45gavinm * - being a compound TLB error
20c794b39650d115e17a15983b6b82e46238cf45gavinm * - having LL of LG and TT of GEN
20c794b39650d115e17a15983b6b82e46238cf45gavinm * - having UC set
20c794b39650d115e17a15983b6b82e46238cf45gavinm * - possibly having PCC set (if source CPU)
20c794b39650d115e17a15983b6b82e46238cf45gavinm */
20c794b39650d115e17a15983b6b82e46238cf45gavinm#define AUTHAMD_IS_GARTERR(bank, status) \
20c794b39650d115e17a15983b6b82e46238cf45gavinm ((bank) == AMD_MCA_BANK_NB && \
20c794b39650d115e17a15983b6b82e46238cf45gavinm MCAX86_ERRCODE_ISTLB(MCAX86_ERRCODE(status)) && \
20c794b39650d115e17a15983b6b82e46238cf45gavinm MCAX86_ERRCODE_LL(MCAX86_ERRCODE(status)) == MCAX86_ERRCODE_LL_LG && \
20c794b39650d115e17a15983b6b82e46238cf45gavinm MCAX86_ERRCODE_TT(MCAX86_ERRCODE(status)) == MCAX86_ERRCODE_TT_GEN && \
20c794b39650d115e17a15983b6b82e46238cf45gavinm (status) & MSR_MC_STATUS_UC)
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinmstatic authamd_error_disp_t authamd_gart_disp = {
20c794b39650d115e17a15983b6b82e46238cf45gavinm FM_EREPORT_CPU_GENAMD, /* use generic subclass */
20c794b39650d115e17a15983b6b82e46238cf45gavinm FM_EREPORT_CPU_GENADM_GARTTBLWLK, /* use generic leafclass */
20c794b39650d115e17a15983b6b82e46238cf45gavinm 0 /* no additional payload */
20c794b39650d115e17a15983b6b82e46238cf45gavinm};
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm
8031591d3cc3c82e97f4b60ea22d671525077b15Srihari Venkatesanstatic struct authamd_nodeshared *authamd_shared[AUTHAMD_MAX_NODES];
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinmstatic int
20c794b39650d115e17a15983b6b82e46238cf45gavinmauthamd_chip_once(authamd_data_t *authamd, enum authamd_cfgonce_bitnum what)
20c794b39650d115e17a15983b6b82e46238cf45gavinm{
5667185bc023b9742cb2480659d7673fa9ac8050Srihari Venkatesan return (atomic_set_long_excl(&authamd->amd_shared->ans_cfgonce,
20c794b39650d115e17a15983b6b82e46238cf45gavinm what) == 0 ? B_TRUE : B_FALSE);
20c794b39650d115e17a15983b6b82e46238cf45gavinm}
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinmstatic void
8031591d3cc3c82e97f4b60ea22d671525077b15Srihari Venkatesanauthamd_pcicfg_write(uint_t procnodeid, uint_t func, uint_t reg, uint32_t val)
20c794b39650d115e17a15983b6b82e46238cf45gavinm{
8031591d3cc3c82e97f4b60ea22d671525077b15Srihari Venkatesan ASSERT(procnodeid + 24 <= 31);
20c794b39650d115e17a15983b6b82e46238cf45gavinm ASSERT((func & 7) == func);
5667185bc023b9742cb2480659d7673fa9ac8050Srihari Venkatesan ASSERT((reg & 3) == 0 && reg < 4096);
20c794b39650d115e17a15983b6b82e46238cf45gavinm
8031591d3cc3c82e97f4b60ea22d671525077b15Srihari Venkatesan cmi_pci_putl(0, procnodeid + 24, func, reg, 0, val);
20c794b39650d115e17a15983b6b82e46238cf45gavinm}
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinmstatic uint32_t
8031591d3cc3c82e97f4b60ea22d671525077b15Srihari Venkatesanauthamd_pcicfg_read(uint_t procnodeid, uint_t func, uint_t reg)
20c794b39650d115e17a15983b6b82e46238cf45gavinm{
8031591d3cc3c82e97f4b60ea22d671525077b15Srihari Venkatesan ASSERT(procnodeid + 24 <= 31);
20c794b39650d115e17a15983b6b82e46238cf45gavinm ASSERT((func & 7) == func);
5667185bc023b9742cb2480659d7673fa9ac8050Srihari Venkatesan ASSERT((reg & 3) == 0 && reg < 4096);
20c794b39650d115e17a15983b6b82e46238cf45gavinm
8031591d3cc3c82e97f4b60ea22d671525077b15Srihari Venkatesan return (cmi_pci_getl(0, procnodeid + 24, func, reg, 0, 0));
20c794b39650d115e17a15983b6b82e46238cf45gavinm}
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinmvoid
20c794b39650d115e17a15983b6b82e46238cf45gavinmauthamd_bankstatus_prewrite(cmi_hdl_t hdl, authamd_data_t *authamd)
20c794b39650d115e17a15983b6b82e46238cf45gavinm{
20c794b39650d115e17a15983b6b82e46238cf45gavinm uint64_t hwcr;
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm if (cmi_hdl_rdmsr(hdl, MSR_AMD_HWCR, &hwcr) != CMI_SUCCESS)
20c794b39650d115e17a15983b6b82e46238cf45gavinm return;
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm authamd->amd_hwcr = hwcr;
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm if (!(hwcr & AMD_HWCR_MCI_STATUS_WREN)) {
20c794b39650d115e17a15983b6b82e46238cf45gavinm hwcr |= AMD_HWCR_MCI_STATUS_WREN;
20c794b39650d115e17a15983b6b82e46238cf45gavinm (void) cmi_hdl_wrmsr(hdl, MSR_AMD_HWCR, hwcr);
20c794b39650d115e17a15983b6b82e46238cf45gavinm }
20c794b39650d115e17a15983b6b82e46238cf45gavinm}
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinmvoid
20c794b39650d115e17a15983b6b82e46238cf45gavinmauthamd_bankstatus_postwrite(cmi_hdl_t hdl, authamd_data_t *authamd)
20c794b39650d115e17a15983b6b82e46238cf45gavinm{
20c794b39650d115e17a15983b6b82e46238cf45gavinm uint64_t hwcr = authamd->amd_hwcr;
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm if (!(hwcr & AMD_HWCR_MCI_STATUS_WREN)) {
20c794b39650d115e17a15983b6b82e46238cf45gavinm hwcr &= ~AMD_HWCR_MCI_STATUS_WREN;
20c794b39650d115e17a15983b6b82e46238cf45gavinm (void) cmi_hdl_wrmsr(hdl, MSR_AMD_HWCR, hwcr);
20c794b39650d115e17a15983b6b82e46238cf45gavinm }
20c794b39650d115e17a15983b6b82e46238cf45gavinm}
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm/*
20c794b39650d115e17a15983b6b82e46238cf45gavinm * Read EccCnt repeatedly for all possible channel/chip-select combos:
20c794b39650d115e17a15983b6b82e46238cf45gavinm *
20c794b39650d115e17a15983b6b82e46238cf45gavinm * - read sparectl register
20c794b39650d115e17a15983b6b82e46238cf45gavinm * - if EccErrCntWrEn is set, clear that bit in the just-read value
20c794b39650d115e17a15983b6b82e46238cf45gavinm * and write it back to sparectl; this *may* clobber the EccCnt
20c794b39650d115e17a15983b6b82e46238cf45gavinm * for the channel/chip-select combination currently selected, so
20c794b39650d115e17a15983b6b82e46238cf45gavinm * we leave this bit clear if we had to clear it
20c794b39650d115e17a15983b6b82e46238cf45gavinm * - cycle through all channel/chip-select combinations writing each
20c794b39650d115e17a15983b6b82e46238cf45gavinm * combination to sparectl before reading the register back for
20c794b39650d115e17a15983b6b82e46238cf45gavinm * EccCnt for that combination; since EccErrCntWrEn is clear
20c794b39650d115e17a15983b6b82e46238cf45gavinm * the writes to select what count to read will not themselves
20c794b39650d115e17a15983b6b82e46238cf45gavinm * zero any counts
20c794b39650d115e17a15983b6b82e46238cf45gavinm */
20c794b39650d115e17a15983b6b82e46238cf45gavinmstatic int
20c794b39650d115e17a15983b6b82e46238cf45gavinmauthamd_read_ecccnt(authamd_data_t *authamd, struct authamd_logout *msl)
20c794b39650d115e17a15983b6b82e46238cf45gavinm{
20c794b39650d115e17a15983b6b82e46238cf45gavinm union mcreg_sparectl sparectl;
5667185bc023b9742cb2480659d7673fa9ac8050Srihari Venkatesan uint_t procnodeid = authamd->amd_shared->ans_procnodeid;
5667185bc023b9742cb2480659d7673fa9ac8050Srihari Venkatesan uint_t family = authamd->amd_shared->ans_family;
5667185bc023b9742cb2480659d7673fa9ac8050Srihari Venkatesan uint32_t rev = authamd->amd_shared->ans_rev;
20c794b39650d115e17a15983b6b82e46238cf45gavinm int chan, cs;
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm /*
20c794b39650d115e17a15983b6b82e46238cf45gavinm * Check for feature support; this macro will test down to the
20c794b39650d115e17a15983b6b82e46238cf45gavinm * family revision number, whereafter we'll switch on family
20c794b39650d115e17a15983b6b82e46238cf45gavinm * assuming that future revisions will use the same register
20c794b39650d115e17a15983b6b82e46238cf45gavinm * format.
20c794b39650d115e17a15983b6b82e46238cf45gavinm */
20c794b39650d115e17a15983b6b82e46238cf45gavinm if (!AUTHAMD_HAS_ONLINESPARECTL(rev)) {
20c794b39650d115e17a15983b6b82e46238cf45gavinm bzero(&msl->aal_eccerrcnt, sizeof (msl->aal_eccerrcnt));
20c794b39650d115e17a15983b6b82e46238cf45gavinm return (0);
20c794b39650d115e17a15983b6b82e46238cf45gavinm }
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm MCREG_VAL32(&sparectl) =
8031591d3cc3c82e97f4b60ea22d671525077b15Srihari Venkatesan authamd_pcicfg_read(procnodeid, MC_FUNC_MISCCTL,
8031591d3cc3c82e97f4b60ea22d671525077b15Srihari Venkatesan MC_CTL_REG_SPARECTL);
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm switch (family) {
20c794b39650d115e17a15983b6b82e46238cf45gavinm case AUTHAMD_FAMILY_F:
20c794b39650d115e17a15983b6b82e46238cf45gavinm MCREG_FIELD_F_revFG(&sparectl, EccErrCntWrEn) = 0;
20c794b39650d115e17a15983b6b82e46238cf45gavinm break;
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm case AUTHAMD_FAMILY_10:
20c794b39650d115e17a15983b6b82e46238cf45gavinm MCREG_FIELD_10_revAB(&sparectl, EccErrCntWrEn) = 0;
20c794b39650d115e17a15983b6b82e46238cf45gavinm break;
20c794b39650d115e17a15983b6b82e46238cf45gavinm }
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm for (chan = 0; chan < AUTHAMD_DRAM_NCHANNEL; chan++) {
20c794b39650d115e17a15983b6b82e46238cf45gavinm switch (family) {
20c794b39650d115e17a15983b6b82e46238cf45gavinm case AUTHAMD_FAMILY_F:
20c794b39650d115e17a15983b6b82e46238cf45gavinm MCREG_FIELD_F_revFG(&sparectl, EccErrCntDramChan) =
20c794b39650d115e17a15983b6b82e46238cf45gavinm chan;
20c794b39650d115e17a15983b6b82e46238cf45gavinm break;
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm case AUTHAMD_FAMILY_10:
20c794b39650d115e17a15983b6b82e46238cf45gavinm MCREG_FIELD_10_revAB(&sparectl, EccErrCntDramChan) =
20c794b39650d115e17a15983b6b82e46238cf45gavinm chan;
20c794b39650d115e17a15983b6b82e46238cf45gavinm break;
20c794b39650d115e17a15983b6b82e46238cf45gavinm }
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm for (cs = 0; cs < AUTHAMD_DRAM_NCS; cs++) {
20c794b39650d115e17a15983b6b82e46238cf45gavinm switch (family) {
20c794b39650d115e17a15983b6b82e46238cf45gavinm case AUTHAMD_FAMILY_F:
20c794b39650d115e17a15983b6b82e46238cf45gavinm MCREG_FIELD_F_revFG(&sparectl,
20c794b39650d115e17a15983b6b82e46238cf45gavinm EccErrCntDramCs) = cs;
20c794b39650d115e17a15983b6b82e46238cf45gavinm break;
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm case AUTHAMD_FAMILY_10:
20c794b39650d115e17a15983b6b82e46238cf45gavinm MCREG_FIELD_10_revAB(&sparectl,
20c794b39650d115e17a15983b6b82e46238cf45gavinm EccErrCntDramCs) = cs;
20c794b39650d115e17a15983b6b82e46238cf45gavinm break;
20c794b39650d115e17a15983b6b82e46238cf45gavinm }
20c794b39650d115e17a15983b6b82e46238cf45gavinm
8031591d3cc3c82e97f4b60ea22d671525077b15Srihari Venkatesan authamd_pcicfg_write(procnodeid, MC_FUNC_MISCCTL,
20c794b39650d115e17a15983b6b82e46238cf45gavinm MC_CTL_REG_SPARECTL, MCREG_VAL32(&sparectl));
20c794b39650d115e17a15983b6b82e46238cf45gavinm
8031591d3cc3c82e97f4b60ea22d671525077b15Srihari Venkatesan MCREG_VAL32(&sparectl) = authamd_pcicfg_read(procnodeid,
20c794b39650d115e17a15983b6b82e46238cf45gavinm MC_FUNC_MISCCTL, MC_CTL_REG_SPARECTL);
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm switch (family) {
20c794b39650d115e17a15983b6b82e46238cf45gavinm case AUTHAMD_FAMILY_F:
20c794b39650d115e17a15983b6b82e46238cf45gavinm msl->aal_eccerrcnt[chan][cs] =
20c794b39650d115e17a15983b6b82e46238cf45gavinm MCREG_FIELD_F_revFG(&sparectl, EccErrCnt);
20c794b39650d115e17a15983b6b82e46238cf45gavinm break;
20c794b39650d115e17a15983b6b82e46238cf45gavinm case AUTHAMD_FAMILY_10:
20c794b39650d115e17a15983b6b82e46238cf45gavinm msl->aal_eccerrcnt[chan][cs] =
20c794b39650d115e17a15983b6b82e46238cf45gavinm MCREG_FIELD_10_revAB(&sparectl, EccErrCnt);
20c794b39650d115e17a15983b6b82e46238cf45gavinm break;
20c794b39650d115e17a15983b6b82e46238cf45gavinm }
20c794b39650d115e17a15983b6b82e46238cf45gavinm }
20c794b39650d115e17a15983b6b82e46238cf45gavinm }
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm return (1);
20c794b39650d115e17a15983b6b82e46238cf45gavinm}
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm/*
20c794b39650d115e17a15983b6b82e46238cf45gavinm * Clear EccCnt for all possible channel/chip-select combos:
20c794b39650d115e17a15983b6b82e46238cf45gavinm *
20c794b39650d115e17a15983b6b82e46238cf45gavinm * - set EccErrCntWrEn in sparectl, if necessary
20c794b39650d115e17a15983b6b82e46238cf45gavinm * - write 0 to EccCnt for all channel/chip-select combinations
20c794b39650d115e17a15983b6b82e46238cf45gavinm * - clear EccErrCntWrEn
20c794b39650d115e17a15983b6b82e46238cf45gavinm *
20c794b39650d115e17a15983b6b82e46238cf45gavinm * If requested also disable the interrupts taken on counter overflow
20c794b39650d115e17a15983b6b82e46238cf45gavinm * and on swap done.
20c794b39650d115e17a15983b6b82e46238cf45gavinm */
20c794b39650d115e17a15983b6b82e46238cf45gavinmstatic void
20c794b39650d115e17a15983b6b82e46238cf45gavinmauthamd_clear_ecccnt(authamd_data_t *authamd, boolean_t clrint)
20c794b39650d115e17a15983b6b82e46238cf45gavinm{
20c794b39650d115e17a15983b6b82e46238cf45gavinm union mcreg_sparectl sparectl;
5667185bc023b9742cb2480659d7673fa9ac8050Srihari Venkatesan uint_t procnodeid = authamd->amd_shared->ans_procnodeid;
5667185bc023b9742cb2480659d7673fa9ac8050Srihari Venkatesan uint_t family = authamd->amd_shared->ans_family;
5667185bc023b9742cb2480659d7673fa9ac8050Srihari Venkatesan uint32_t rev = authamd->amd_shared->ans_rev;
20c794b39650d115e17a15983b6b82e46238cf45gavinm int chan, cs;
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm if (!AUTHAMD_HAS_ONLINESPARECTL(rev))
20c794b39650d115e17a15983b6b82e46238cf45gavinm return;
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm MCREG_VAL32(&sparectl) =
8031591d3cc3c82e97f4b60ea22d671525077b15Srihari Venkatesan authamd_pcicfg_read(procnodeid, MC_FUNC_MISCCTL,
8031591d3cc3c82e97f4b60ea22d671525077b15Srihari Venkatesan MC_CTL_REG_SPARECTL);
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm switch (family) {
20c794b39650d115e17a15983b6b82e46238cf45gavinm case AUTHAMD_FAMILY_F:
20c794b39650d115e17a15983b6b82e46238cf45gavinm MCREG_FIELD_F_revFG(&sparectl, EccErrCntWrEn) = 1;
20c794b39650d115e17a15983b6b82e46238cf45gavinm if (clrint) {
20c794b39650d115e17a15983b6b82e46238cf45gavinm MCREG_FIELD_F_revFG(&sparectl, EccErrInt) = 0;
20c794b39650d115e17a15983b6b82e46238cf45gavinm MCREG_FIELD_F_revFG(&sparectl, SwapDoneInt) = 0;
20c794b39650d115e17a15983b6b82e46238cf45gavinm }
20c794b39650d115e17a15983b6b82e46238cf45gavinm break;
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm case AUTHAMD_FAMILY_10:
20c794b39650d115e17a15983b6b82e46238cf45gavinm MCREG_FIELD_10_revAB(&sparectl, EccErrCntWrEn) = 1;
20c794b39650d115e17a15983b6b82e46238cf45gavinm if (clrint) {
20c794b39650d115e17a15983b6b82e46238cf45gavinm MCREG_FIELD_10_revAB(&sparectl, EccErrInt) = 0;
20c794b39650d115e17a15983b6b82e46238cf45gavinm MCREG_FIELD_10_revAB(&sparectl, SwapDoneInt) = 0;
20c794b39650d115e17a15983b6b82e46238cf45gavinm }
20c794b39650d115e17a15983b6b82e46238cf45gavinm break;
20c794b39650d115e17a15983b6b82e46238cf45gavinm }
20c794b39650d115e17a15983b6b82e46238cf45gavinm
8031591d3cc3c82e97f4b60ea22d671525077b15Srihari Venkatesan authamd_pcicfg_write(procnodeid, MC_FUNC_MISCCTL,
20c794b39650d115e17a15983b6b82e46238cf45gavinm MC_CTL_REG_SPARECTL, MCREG_VAL32(&sparectl));
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm for (chan = 0; chan < AUTHAMD_DRAM_NCHANNEL; chan++) {
20c794b39650d115e17a15983b6b82e46238cf45gavinm switch (family) {
20c794b39650d115e17a15983b6b82e46238cf45gavinm case AUTHAMD_FAMILY_F:
20c794b39650d115e17a15983b6b82e46238cf45gavinm MCREG_FIELD_F_revFG(&sparectl, EccErrCntDramChan) =
20c794b39650d115e17a15983b6b82e46238cf45gavinm chan;
20c794b39650d115e17a15983b6b82e46238cf45gavinm break;
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm case AUTHAMD_FAMILY_10:
20c794b39650d115e17a15983b6b82e46238cf45gavinm MCREG_FIELD_10_revAB(&sparectl, EccErrCntDramChan) =
20c794b39650d115e17a15983b6b82e46238cf45gavinm chan;
20c794b39650d115e17a15983b6b82e46238cf45gavinm break;
20c794b39650d115e17a15983b6b82e46238cf45gavinm }
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm for (cs = 0; cs < AUTHAMD_DRAM_NCS; cs++) {
20c794b39650d115e17a15983b6b82e46238cf45gavinm switch (family) {
20c794b39650d115e17a15983b6b82e46238cf45gavinm case AUTHAMD_FAMILY_F:
20c794b39650d115e17a15983b6b82e46238cf45gavinm MCREG_FIELD_F_revFG(&sparectl,
20c794b39650d115e17a15983b6b82e46238cf45gavinm EccErrCntDramCs) = cs;
20c794b39650d115e17a15983b6b82e46238cf45gavinm MCREG_FIELD_F_revFG(&sparectl,
20c794b39650d115e17a15983b6b82e46238cf45gavinm EccErrCnt) = 0;
20c794b39650d115e17a15983b6b82e46238cf45gavinm break;
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm case AUTHAMD_FAMILY_10:
20c794b39650d115e17a15983b6b82e46238cf45gavinm MCREG_FIELD_10_revAB(&sparectl,
20c794b39650d115e17a15983b6b82e46238cf45gavinm EccErrCntDramCs) = cs;
20c794b39650d115e17a15983b6b82e46238cf45gavinm MCREG_FIELD_10_revAB(&sparectl,
20c794b39650d115e17a15983b6b82e46238cf45gavinm EccErrCnt) = 0;
20c794b39650d115e17a15983b6b82e46238cf45gavinm break;
20c794b39650d115e17a15983b6b82e46238cf45gavinm }
20c794b39650d115e17a15983b6b82e46238cf45gavinm
8031591d3cc3c82e97f4b60ea22d671525077b15Srihari Venkatesan authamd_pcicfg_write(procnodeid, MC_FUNC_MISCCTL,
20c794b39650d115e17a15983b6b82e46238cf45gavinm MC_CTL_REG_SPARECTL, MCREG_VAL32(&sparectl));
20c794b39650d115e17a15983b6b82e46238cf45gavinm }
20c794b39650d115e17a15983b6b82e46238cf45gavinm }
20c794b39650d115e17a15983b6b82e46238cf45gavinm}
20c794b39650d115e17a15983b6b82e46238cf45gavinm
a24e89c4a1eec8361718d94a6275e6720643284eKuriakose Kuruvilla
a24e89c4a1eec8361718d94a6275e6720643284eKuriakose Kuruvilla/*
a24e89c4a1eec8361718d94a6275e6720643284eKuriakose Kuruvilla * Return
a24e89c4a1eec8361718d94a6275e6720643284eKuriakose Kuruvilla * 1: supported
a24e89c4a1eec8361718d94a6275e6720643284eKuriakose Kuruvilla * 0: unsupported
a24e89c4a1eec8361718d94a6275e6720643284eKuriakose Kuruvilla */
a24e89c4a1eec8361718d94a6275e6720643284eKuriakose Kuruvillastatic int
8031591d3cc3c82e97f4b60ea22d671525077b15Srihari Venkatesanauthamd_supported(cmi_hdl_t hdl)
a24e89c4a1eec8361718d94a6275e6720643284eKuriakose Kuruvilla{
8031591d3cc3c82e97f4b60ea22d671525077b15Srihari Venkatesan uint_t family = cmi_hdl_family(hdl);
a24e89c4a1eec8361718d94a6275e6720643284eKuriakose Kuruvilla
8031591d3cc3c82e97f4b60ea22d671525077b15Srihari Venkatesan switch (family) {
8031591d3cc3c82e97f4b60ea22d671525077b15Srihari Venkatesan case AUTHAMD_FAMILY_6:
8031591d3cc3c82e97f4b60ea22d671525077b15Srihari Venkatesan case AUTHAMD_FAMILY_F:
8031591d3cc3c82e97f4b60ea22d671525077b15Srihari Venkatesan case AUTHAMD_FAMILY_10:
a24e89c4a1eec8361718d94a6275e6720643284eKuriakose Kuruvilla return (1);
8031591d3cc3c82e97f4b60ea22d671525077b15Srihari Venkatesan default:
8031591d3cc3c82e97f4b60ea22d671525077b15Srihari Venkatesan return (0);
a24e89c4a1eec8361718d94a6275e6720643284eKuriakose Kuruvilla }
a24e89c4a1eec8361718d94a6275e6720643284eKuriakose Kuruvilla}
a24e89c4a1eec8361718d94a6275e6720643284eKuriakose Kuruvilla
20c794b39650d115e17a15983b6b82e46238cf45gavinm/*
20c794b39650d115e17a15983b6b82e46238cf45gavinm * cms_init entry point.
20c794b39650d115e17a15983b6b82e46238cf45gavinm *
20c794b39650d115e17a15983b6b82e46238cf45gavinm * This module provides broad model-specific support for AMD families
20c794b39650d115e17a15983b6b82e46238cf45gavinm * 0x6, 0xf and 0x10. Future families will have to be evaluated once their
20c794b39650d115e17a15983b6b82e46238cf45gavinm * documentation is available.
20c794b39650d115e17a15983b6b82e46238cf45gavinm */
20c794b39650d115e17a15983b6b82e46238cf45gavinmint
20c794b39650d115e17a15983b6b82e46238cf45gavinmauthamd_init(cmi_hdl_t hdl, void **datap)
20c794b39650d115e17a15983b6b82e46238cf45gavinm{
20c794b39650d115e17a15983b6b82e46238cf45gavinm uint_t chipid = cmi_hdl_chipid(hdl);
8031591d3cc3c82e97f4b60ea22d671525077b15Srihari Venkatesan uint_t procnodeid = cmi_hdl_procnodeid(hdl);
8031591d3cc3c82e97f4b60ea22d671525077b15Srihari Venkatesan struct authamd_nodeshared *sp, *osp;
20c794b39650d115e17a15983b6b82e46238cf45gavinm uint_t family = cmi_hdl_family(hdl);
a24e89c4a1eec8361718d94a6275e6720643284eKuriakose Kuruvilla uint32_t rev = cmi_hdl_chiprev(hdl);
20c794b39650d115e17a15983b6b82e46238cf45gavinm authamd_data_t *authamd;
20c794b39650d115e17a15983b6b82e46238cf45gavinm uint64_t cap;
20c794b39650d115e17a15983b6b82e46238cf45gavinm
a24e89c4a1eec8361718d94a6275e6720643284eKuriakose Kuruvilla if (authamd_ms_support_disable ||
8031591d3cc3c82e97f4b60ea22d671525077b15Srihari Venkatesan !authamd_supported(hdl))
20c794b39650d115e17a15983b6b82e46238cf45gavinm return (ENOTSUP);
20c794b39650d115e17a15983b6b82e46238cf45gavinm
7417cfdecea1902cef03c0d61a72df97d945925dKuriakose Kuruvilla if (!is_x86_feature(x86_featureset, X86FSET_MCA))
20c794b39650d115e17a15983b6b82e46238cf45gavinm return (ENOTSUP);
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm if (cmi_hdl_rdmsr(hdl, IA32_MSR_MCG_CAP, &cap) != CMI_SUCCESS)
20c794b39650d115e17a15983b6b82e46238cf45gavinm return (ENOTSUP);
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm if (!(cap & MCG_CAP_CTL_P))
20c794b39650d115e17a15983b6b82e46238cf45gavinm return (ENOTSUP);
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm authamd = *datap = kmem_zalloc(sizeof (authamd_data_t), KM_SLEEP);
20c794b39650d115e17a15983b6b82e46238cf45gavinm cmi_hdl_hold(hdl); /* release in fini */
20c794b39650d115e17a15983b6b82e46238cf45gavinm authamd->amd_hdl = hdl;
20c794b39650d115e17a15983b6b82e46238cf45gavinm
8031591d3cc3c82e97f4b60ea22d671525077b15Srihari Venkatesan if ((sp = authamd_shared[procnodeid]) == NULL) {
8031591d3cc3c82e97f4b60ea22d671525077b15Srihari Venkatesan sp = kmem_zalloc(sizeof (struct authamd_nodeshared), KM_SLEEP);
5667185bc023b9742cb2480659d7673fa9ac8050Srihari Venkatesan sp->ans_chipid = chipid;
5667185bc023b9742cb2480659d7673fa9ac8050Srihari Venkatesan sp->ans_procnodeid = procnodeid;
5667185bc023b9742cb2480659d7673fa9ac8050Srihari Venkatesan sp->ans_family = family;
5667185bc023b9742cb2480659d7673fa9ac8050Srihari Venkatesan sp->ans_rev = rev;
a3c4695861e3f0a8d3706f77ccd53683cca48d67gavinm membar_producer();
a3c4695861e3f0a8d3706f77ccd53683cca48d67gavinm
8031591d3cc3c82e97f4b60ea22d671525077b15Srihari Venkatesan osp = atomic_cas_ptr(&authamd_shared[procnodeid], NULL, sp);
20c794b39650d115e17a15983b6b82e46238cf45gavinm if (osp != NULL) {
8031591d3cc3c82e97f4b60ea22d671525077b15Srihari Venkatesan kmem_free(sp, sizeof (struct authamd_nodeshared));
20c794b39650d115e17a15983b6b82e46238cf45gavinm sp = osp;
20c794b39650d115e17a15983b6b82e46238cf45gavinm }
20c794b39650d115e17a15983b6b82e46238cf45gavinm }
20c794b39650d115e17a15983b6b82e46238cf45gavinm authamd->amd_shared = sp;
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm return (0);
20c794b39650d115e17a15983b6b82e46238cf45gavinm}
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm/*
20c794b39650d115e17a15983b6b82e46238cf45gavinm * cms_logout_size entry point.
20c794b39650d115e17a15983b6b82e46238cf45gavinm */
20c794b39650d115e17a15983b6b82e46238cf45gavinm/*ARGSUSED*/
20c794b39650d115e17a15983b6b82e46238cf45gavinmsize_t
20c794b39650d115e17a15983b6b82e46238cf45gavinmauthamd_logout_size(cmi_hdl_t hdl)
20c794b39650d115e17a15983b6b82e46238cf45gavinm{
20c794b39650d115e17a15983b6b82e46238cf45gavinm return (sizeof (struct authamd_logout));
20c794b39650d115e17a15983b6b82e46238cf45gavinm}
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm/*
20c794b39650d115e17a15983b6b82e46238cf45gavinm * cms_mcgctl_val entry point
20c794b39650d115e17a15983b6b82e46238cf45gavinm *
20c794b39650d115e17a15983b6b82e46238cf45gavinm * Instead of setting all bits to 1 we can set just those for the
20c794b39650d115e17a15983b6b82e46238cf45gavinm * error detector banks known to exist.
20c794b39650d115e17a15983b6b82e46238cf45gavinm */
20c794b39650d115e17a15983b6b82e46238cf45gavinm/*ARGSUSED*/
20c794b39650d115e17a15983b6b82e46238cf45gavinmuint64_t
20c794b39650d115e17a15983b6b82e46238cf45gavinmauthamd_mcgctl_val(cmi_hdl_t hdl, int nbanks, uint64_t proposed)
20c794b39650d115e17a15983b6b82e46238cf45gavinm{
20c794b39650d115e17a15983b6b82e46238cf45gavinm return (nbanks < 64 ? (1ULL << nbanks) - 1 : proposed);
20c794b39650d115e17a15983b6b82e46238cf45gavinm}
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm/*
20c794b39650d115e17a15983b6b82e46238cf45gavinm * cms_bankctl_skipinit entry point
20c794b39650d115e17a15983b6b82e46238cf45gavinm *
20c794b39650d115e17a15983b6b82e46238cf45gavinm * On K6 we do not initialize MC0_CTL since, reportedly, this bank (for DC)
20c794b39650d115e17a15983b6b82e46238cf45gavinm * may produce spurious machine checks.
a4e4e13f4001644f2f960e3be0056c22b3a40fd1gavinm *
a4e4e13f4001644f2f960e3be0056c22b3a40fd1gavinm * Only allow a single core to setup the NorthBridge MCi_CTL register.
20c794b39650d115e17a15983b6b82e46238cf45gavinm */
20c794b39650d115e17a15983b6b82e46238cf45gavinm/*ARGSUSED*/
20c794b39650d115e17a15983b6b82e46238cf45gavinmboolean_t
20c794b39650d115e17a15983b6b82e46238cf45gavinmauthamd_bankctl_skipinit(cmi_hdl_t hdl, int bank)
20c794b39650d115e17a15983b6b82e46238cf45gavinm{
20c794b39650d115e17a15983b6b82e46238cf45gavinm authamd_data_t *authamd = cms_hdl_getcmsdata(hdl);
5667185bc023b9742cb2480659d7673fa9ac8050Srihari Venkatesan uint32_t rev = authamd->amd_shared->ans_rev;
a4e4e13f4001644f2f960e3be0056c22b3a40fd1gavinm
5667185bc023b9742cb2480659d7673fa9ac8050Srihari Venkatesan if (authamd->amd_shared->ans_family == AUTHAMD_FAMILY_6)
a4e4e13f4001644f2f960e3be0056c22b3a40fd1gavinm return (bank == 0 ? B_TRUE : B_FALSE);
a4e4e13f4001644f2f960e3be0056c22b3a40fd1gavinm
a4e4e13f4001644f2f960e3be0056c22b3a40fd1gavinm if (AUTHAMD_NBONCHIP(rev) && bank == AMD_MCA_BANK_NB) {
a4e4e13f4001644f2f960e3be0056c22b3a40fd1gavinm return (authamd_chip_once(authamd, AUTHAMD_CFGONCE_NBMCA) ==
a4e4e13f4001644f2f960e3be0056c22b3a40fd1gavinm B_TRUE ? B_FALSE : B_TRUE);
a4e4e13f4001644f2f960e3be0056c22b3a40fd1gavinm }
20c794b39650d115e17a15983b6b82e46238cf45gavinm
a4e4e13f4001644f2f960e3be0056c22b3a40fd1gavinm return (B_FALSE);
20c794b39650d115e17a15983b6b82e46238cf45gavinm}
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm/*
20c794b39650d115e17a15983b6b82e46238cf45gavinm * cms_bankctl_val entry point
20c794b39650d115e17a15983b6b82e46238cf45gavinm */
20c794b39650d115e17a15983b6b82e46238cf45gavinmuint64_t
20c794b39650d115e17a15983b6b82e46238cf45gavinmauthamd_bankctl_val(cmi_hdl_t hdl, int bank, uint64_t proposed)
20c794b39650d115e17a15983b6b82e46238cf45gavinm{
20c794b39650d115e17a15983b6b82e46238cf45gavinm authamd_data_t *authamd = cms_hdl_getcmsdata(hdl);
5667185bc023b9742cb2480659d7673fa9ac8050Srihari Venkatesan uint32_t rev = authamd->amd_shared->ans_rev;
20c794b39650d115e17a15983b6b82e46238cf45gavinm uint64_t val = proposed;
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm /*
20c794b39650d115e17a15983b6b82e46238cf45gavinm * The Intel MCA says we can write all 1's to enable #MC for
20c794b39650d115e17a15983b6b82e46238cf45gavinm * all errors, and AMD docs say much the same. But, depending
20c794b39650d115e17a15983b6b82e46238cf45gavinm * perhaps on other config registers, taking machine checks
20c794b39650d115e17a15983b6b82e46238cf45gavinm * for some errors such as GART TLB errors and master/target
20c794b39650d115e17a15983b6b82e46238cf45gavinm * aborts may be bad - they set UC and sometime also PCC, but
20c794b39650d115e17a15983b6b82e46238cf45gavinm * we should not always panic for these error types.
20c794b39650d115e17a15983b6b82e46238cf45gavinm *
20c794b39650d115e17a15983b6b82e46238cf45gavinm * Our cms_error_action entry point can suppress such panics,
20c794b39650d115e17a15983b6b82e46238cf45gavinm * however we can also use the cms_bankctl_val entry point to
20c794b39650d115e17a15983b6b82e46238cf45gavinm * veto enabling of some of the known villains in the first place.
20c794b39650d115e17a15983b6b82e46238cf45gavinm */
20c794b39650d115e17a15983b6b82e46238cf45gavinm if (bank == AMD_MCA_BANK_NB && AUTHAMD_NOGARTTBLWLK_MC(rev))
20c794b39650d115e17a15983b6b82e46238cf45gavinm val &= ~AMD_NB_EN_GARTTBLWK;
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm return (val);
20c794b39650d115e17a15983b6b82e46238cf45gavinm}
20c794b39650d115e17a15983b6b82e46238cf45gavinm
25f476773dea2a0ee593dcf662a38d5f02487196gavinm/*
25f476773dea2a0ee593dcf662a38d5f02487196gavinm * Bits to add to NB MCA config (after watchdog config).
25f476773dea2a0ee593dcf662a38d5f02487196gavinm */
25f476773dea2a0ee593dcf662a38d5f02487196gavinmuint32_t authamd_nb_mcacfg_add = AMD_NB_CFG_ADD_CMN;
25f476773dea2a0ee593dcf662a38d5f02487196gavinm
25f476773dea2a0ee593dcf662a38d5f02487196gavinm/*
25f476773dea2a0ee593dcf662a38d5f02487196gavinm * Bits to remove from NB MCA config (after watchdog config)
25f476773dea2a0ee593dcf662a38d5f02487196gavinm */
25f476773dea2a0ee593dcf662a38d5f02487196gavinmuint32_t authamd_nb_mcacfg_remove = AMD_NB_CFG_REMOVE_CMN;
25f476773dea2a0ee593dcf662a38d5f02487196gavinm
25f476773dea2a0ee593dcf662a38d5f02487196gavinm/*
25f476773dea2a0ee593dcf662a38d5f02487196gavinm * NB Watchdog policy, and rate we use if enabling.
25f476773dea2a0ee593dcf662a38d5f02487196gavinm */
25f476773dea2a0ee593dcf662a38d5f02487196gavinmenum {
25f476773dea2a0ee593dcf662a38d5f02487196gavinm AUTHAMD_NB_WDOG_LEAVEALONE,
25f476773dea2a0ee593dcf662a38d5f02487196gavinm AUTHAMD_NB_WDOG_DISABLE,
25f476773dea2a0ee593dcf662a38d5f02487196gavinm AUTHAMD_NB_WDOG_ENABLE_IF_DISABLED,
25f476773dea2a0ee593dcf662a38d5f02487196gavinm AUTHAMD_NB_WDOG_ENABLE_FORCE_RATE
25f476773dea2a0ee593dcf662a38d5f02487196gavinm} authamd_nb_watchdog_policy = AUTHAMD_NB_WDOG_ENABLE_IF_DISABLED;
25f476773dea2a0ee593dcf662a38d5f02487196gavinm
25f476773dea2a0ee593dcf662a38d5f02487196gavinmuint32_t authamd_nb_mcacfg_wdog = AMD_NB_CFG_WDOGTMRCNTSEL_4095 |
25f476773dea2a0ee593dcf662a38d5f02487196gavinm AMD_NB_CFG_WDOGTMRBASESEL_1MS;
25f476773dea2a0ee593dcf662a38d5f02487196gavinm
25f476773dea2a0ee593dcf662a38d5f02487196gavinm/*
25f476773dea2a0ee593dcf662a38d5f02487196gavinm * Per-core cache scrubbing policy and rates.
25f476773dea2a0ee593dcf662a38d5f02487196gavinm */
25f476773dea2a0ee593dcf662a38d5f02487196gavinmenum {
25f476773dea2a0ee593dcf662a38d5f02487196gavinm AUTHAMD_SCRUB_BIOSDEFAULT, /* leave as BIOS configured */
25f476773dea2a0ee593dcf662a38d5f02487196gavinm AUTHAMD_SCRUB_FIXED, /* assign our chosen rate */
25f476773dea2a0ee593dcf662a38d5f02487196gavinm AUTHAMD_SCRUB_MAX /* use higher of ours and BIOS rate */
25f476773dea2a0ee593dcf662a38d5f02487196gavinm} authamd_scrub_policy = AUTHAMD_SCRUB_MAX;
25f476773dea2a0ee593dcf662a38d5f02487196gavinm
25f476773dea2a0ee593dcf662a38d5f02487196gavinmuint32_t authamd_scrub_rate_dcache = 0xf; /* 64K per 0.67 seconds */
25f476773dea2a0ee593dcf662a38d5f02487196gavinmuint32_t authamd_scrub_rate_l2cache = 0xe; /* 1MB per 5.3 seconds */
25f476773dea2a0ee593dcf662a38d5f02487196gavinmuint32_t authamd_scrub_rate_l3cache = 0xd; /* 1MB per 2.7 seconds */
25f476773dea2a0ee593dcf662a38d5f02487196gavinm
25f476773dea2a0ee593dcf662a38d5f02487196gavinmstatic uint32_t
25f476773dea2a0ee593dcf662a38d5f02487196gavinmauthamd_scrubrate(uint32_t osrate, uint32_t biosrate, const char *varnm)
25f476773dea2a0ee593dcf662a38d5f02487196gavinm{
25f476773dea2a0ee593dcf662a38d5f02487196gavinm uint32_t rate;
25f476773dea2a0ee593dcf662a38d5f02487196gavinm
25f476773dea2a0ee593dcf662a38d5f02487196gavinm if (osrate > AMD_NB_SCRUBCTL_RATE_MAX) {
25f476773dea2a0ee593dcf662a38d5f02487196gavinm cmn_err(CE_WARN, "%s is too large, resetting to 0x%x\n",
25f476773dea2a0ee593dcf662a38d5f02487196gavinm varnm, AMD_NB_SCRUBCTL_RATE_MAX);
25f476773dea2a0ee593dcf662a38d5f02487196gavinm osrate = AMD_NB_SCRUBCTL_RATE_MAX;
25f476773dea2a0ee593dcf662a38d5f02487196gavinm }
25f476773dea2a0ee593dcf662a38d5f02487196gavinm
25f476773dea2a0ee593dcf662a38d5f02487196gavinm switch (authamd_scrub_policy) {
25f476773dea2a0ee593dcf662a38d5f02487196gavinm case AUTHAMD_SCRUB_FIXED:
25f476773dea2a0ee593dcf662a38d5f02487196gavinm rate = osrate;
25f476773dea2a0ee593dcf662a38d5f02487196gavinm break;
25f476773dea2a0ee593dcf662a38d5f02487196gavinm
25f476773dea2a0ee593dcf662a38d5f02487196gavinm default:
25f476773dea2a0ee593dcf662a38d5f02487196gavinm cmn_err(CE_WARN, "Unknown authamd_scrub_policy %d - "
25f476773dea2a0ee593dcf662a38d5f02487196gavinm "using default policy of AUTHAMD_SCRUB_MAX",
25f476773dea2a0ee593dcf662a38d5f02487196gavinm authamd_scrub_policy);
25f476773dea2a0ee593dcf662a38d5f02487196gavinm /*FALLTHRU*/
25f476773dea2a0ee593dcf662a38d5f02487196gavinm
25f476773dea2a0ee593dcf662a38d5f02487196gavinm case AUTHAMD_SCRUB_MAX:
25f476773dea2a0ee593dcf662a38d5f02487196gavinm if (osrate != 0 && biosrate != 0)
25f476773dea2a0ee593dcf662a38d5f02487196gavinm rate = MIN(osrate, biosrate); /* small is fast */
25f476773dea2a0ee593dcf662a38d5f02487196gavinm else
25f476773dea2a0ee593dcf662a38d5f02487196gavinm rate = osrate ? osrate : biosrate;
25f476773dea2a0ee593dcf662a38d5f02487196gavinm }
25f476773dea2a0ee593dcf662a38d5f02487196gavinm
25f476773dea2a0ee593dcf662a38d5f02487196gavinm return (rate);
25f476773dea2a0ee593dcf662a38d5f02487196gavinm}
25f476773dea2a0ee593dcf662a38d5f02487196gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm/*
20c794b39650d115e17a15983b6b82e46238cf45gavinm * cms_mca_init entry point.
20c794b39650d115e17a15983b6b82e46238cf45gavinm */
20c794b39650d115e17a15983b6b82e46238cf45gavinm/*ARGSUSED*/
20c794b39650d115e17a15983b6b82e46238cf45gavinmvoid
20c794b39650d115e17a15983b6b82e46238cf45gavinmauthamd_mca_init(cmi_hdl_t hdl, int nbanks)
20c794b39650d115e17a15983b6b82e46238cf45gavinm{
20c794b39650d115e17a15983b6b82e46238cf45gavinm authamd_data_t *authamd = cms_hdl_getcmsdata(hdl);
5667185bc023b9742cb2480659d7673fa9ac8050Srihari Venkatesan uint32_t rev = authamd->amd_shared->ans_rev;
5667185bc023b9742cb2480659d7673fa9ac8050Srihari Venkatesan uint_t procnodeid = authamd->amd_shared->ans_procnodeid;
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm /*
20c794b39650d115e17a15983b6b82e46238cf45gavinm * On chips with a NB online spare control register take control
20c794b39650d115e17a15983b6b82e46238cf45gavinm * and clear ECC counts.
20c794b39650d115e17a15983b6b82e46238cf45gavinm */
20c794b39650d115e17a15983b6b82e46238cf45gavinm if (AUTHAMD_HAS_ONLINESPARECTL(rev) &&
20c794b39650d115e17a15983b6b82e46238cf45gavinm authamd_chip_once(authamd, AUTHAMD_CFGONCE_ONLNSPRCFG)) {
20c794b39650d115e17a15983b6b82e46238cf45gavinm authamd_clear_ecccnt(authamd, B_TRUE);
20c794b39650d115e17a15983b6b82e46238cf45gavinm }
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm /*
20c794b39650d115e17a15983b6b82e46238cf45gavinm * And since we are claiming the telemetry stop the BIOS receiving
20c794b39650d115e17a15983b6b82e46238cf45gavinm * an SMI on NB threshold overflow.
20c794b39650d115e17a15983b6b82e46238cf45gavinm */
20c794b39650d115e17a15983b6b82e46238cf45gavinm if (AUTHAMD_NBMISC_NUM(rev) &&
20c794b39650d115e17a15983b6b82e46238cf45gavinm authamd_chip_once(authamd, AUTHAMD_CFGONCE_NBTHRESH)) {
20c794b39650d115e17a15983b6b82e46238cf45gavinm union mcmsr_nbmisc nbm;
20c794b39650d115e17a15983b6b82e46238cf45gavinm int i;
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm authamd_bankstatus_prewrite(hdl, authamd);
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm for (i = 0; i < AUTHAMD_NBMISC_NUM(rev); i++) {
20c794b39650d115e17a15983b6b82e46238cf45gavinm if (cmi_hdl_rdmsr(hdl, MC_MSR_NB_MISC(i),
20c794b39650d115e17a15983b6b82e46238cf45gavinm (uint64_t *)&nbm) != CMI_SUCCESS)
20c794b39650d115e17a15983b6b82e46238cf45gavinm continue;
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm if (X86_CHIPREV_ATLEAST(rev, X86_CHIPREV_AMD_F_REV_F) &&
20c794b39650d115e17a15983b6b82e46238cf45gavinm MCMSR_FIELD_F_revFG(&nbm, mcmisc_Valid) &&
20c794b39650d115e17a15983b6b82e46238cf45gavinm MCMSR_FIELD_F_revFG(&nbm, mcmisc_CntP)) {
20c794b39650d115e17a15983b6b82e46238cf45gavinm MCMSR_FIELD_F_revFG(&nbm, mcmisc_IntType) = 0;
20c794b39650d115e17a15983b6b82e46238cf45gavinm } else if (X86_CHIPREV_ATLEAST(rev,
20c794b39650d115e17a15983b6b82e46238cf45gavinm X86_CHIPREV_AMD_10_REV_A) &&
20c794b39650d115e17a15983b6b82e46238cf45gavinm MCMSR_FIELD_10_revAB(&nbm, mcmisc_Valid) &&
20c794b39650d115e17a15983b6b82e46238cf45gavinm MCMSR_FIELD_10_revAB(&nbm, mcmisc_CntP)) {
20c794b39650d115e17a15983b6b82e46238cf45gavinm MCMSR_FIELD_10_revAB(&nbm, mcmisc_IntType) = 0;
20c794b39650d115e17a15983b6b82e46238cf45gavinm }
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm (void) cmi_hdl_wrmsr(hdl, MC_MSR_NB_MISC(i),
20c794b39650d115e17a15983b6b82e46238cf45gavinm MCMSR_VAL(&nbm));
20c794b39650d115e17a15983b6b82e46238cf45gavinm }
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm authamd_bankstatus_postwrite(hdl, authamd);
20c794b39650d115e17a15983b6b82e46238cf45gavinm }
25f476773dea2a0ee593dcf662a38d5f02487196gavinm
25f476773dea2a0ee593dcf662a38d5f02487196gavinm /*
25f476773dea2a0ee593dcf662a38d5f02487196gavinm * NB MCA Configuration Register.
25f476773dea2a0ee593dcf662a38d5f02487196gavinm */
25f476773dea2a0ee593dcf662a38d5f02487196gavinm if (AUTHAMD_DO_NBMCACFG(rev) &&
25f476773dea2a0ee593dcf662a38d5f02487196gavinm authamd_chip_once(authamd, AUTHAMD_CFGONCE_NBMCACFG)) {
8031591d3cc3c82e97f4b60ea22d671525077b15Srihari Venkatesan uint32_t val = authamd_pcicfg_read(procnodeid, MC_FUNC_MISCCTL,
25f476773dea2a0ee593dcf662a38d5f02487196gavinm MC_CTL_REG_NBCFG);
25f476773dea2a0ee593dcf662a38d5f02487196gavinm
25f476773dea2a0ee593dcf662a38d5f02487196gavinm switch (authamd_nb_watchdog_policy) {
25f476773dea2a0ee593dcf662a38d5f02487196gavinm case AUTHAMD_NB_WDOG_LEAVEALONE:
25f476773dea2a0ee593dcf662a38d5f02487196gavinm break;
25f476773dea2a0ee593dcf662a38d5f02487196gavinm
25f476773dea2a0ee593dcf662a38d5f02487196gavinm case AUTHAMD_NB_WDOG_DISABLE:
25f476773dea2a0ee593dcf662a38d5f02487196gavinm val &= ~(AMD_NB_CFG_WDOGTMRBASESEL_MASK |
25f476773dea2a0ee593dcf662a38d5f02487196gavinm AMD_NB_CFG_WDOGTMRCNTSEL_MASK);
25f476773dea2a0ee593dcf662a38d5f02487196gavinm val |= AMD_NB_CFG_WDOGTMRDIS;
25f476773dea2a0ee593dcf662a38d5f02487196gavinm break;
25f476773dea2a0ee593dcf662a38d5f02487196gavinm
25f476773dea2a0ee593dcf662a38d5f02487196gavinm default:
25f476773dea2a0ee593dcf662a38d5f02487196gavinm cmn_err(CE_NOTE, "authamd_nb_watchdog_policy=%d "
25f476773dea2a0ee593dcf662a38d5f02487196gavinm "unrecognised, using default policy",
25f476773dea2a0ee593dcf662a38d5f02487196gavinm authamd_nb_watchdog_policy);
25f476773dea2a0ee593dcf662a38d5f02487196gavinm /*FALLTHRU*/
25f476773dea2a0ee593dcf662a38d5f02487196gavinm
25f476773dea2a0ee593dcf662a38d5f02487196gavinm case AUTHAMD_NB_WDOG_ENABLE_IF_DISABLED:
25f476773dea2a0ee593dcf662a38d5f02487196gavinm if (!(val & AMD_NB_CFG_WDOGTMRDIS))
25f476773dea2a0ee593dcf662a38d5f02487196gavinm break; /* if enabled leave rate intact */
25f476773dea2a0ee593dcf662a38d5f02487196gavinm /*FALLTHRU*/
25f476773dea2a0ee593dcf662a38d5f02487196gavinm
25f476773dea2a0ee593dcf662a38d5f02487196gavinm case AUTHAMD_NB_WDOG_ENABLE_FORCE_RATE:
25f476773dea2a0ee593dcf662a38d5f02487196gavinm val &= ~(AMD_NB_CFG_WDOGTMRBASESEL_MASK |
25f476773dea2a0ee593dcf662a38d5f02487196gavinm AMD_NB_CFG_WDOGTMRCNTSEL_MASK |
25f476773dea2a0ee593dcf662a38d5f02487196gavinm AMD_NB_CFG_WDOGTMRDIS);
25f476773dea2a0ee593dcf662a38d5f02487196gavinm val |= authamd_nb_mcacfg_wdog;
25f476773dea2a0ee593dcf662a38d5f02487196gavinm break;
25f476773dea2a0ee593dcf662a38d5f02487196gavinm }
25f476773dea2a0ee593dcf662a38d5f02487196gavinm
25f476773dea2a0ee593dcf662a38d5f02487196gavinm /*
25f476773dea2a0ee593dcf662a38d5f02487196gavinm * Bit 0 of the NB MCA Config register is reserved on family
25f476773dea2a0ee593dcf662a38d5f02487196gavinm * 0x10.
25f476773dea2a0ee593dcf662a38d5f02487196gavinm */
25f476773dea2a0ee593dcf662a38d5f02487196gavinm if (X86_CHIPREV_ATLEAST(rev, X86_CHIPREV_AMD_10_REV_A))
25f476773dea2a0ee593dcf662a38d5f02487196gavinm authamd_nb_mcacfg_add &= ~AMD_NB_CFG_CPUECCERREN;
25f476773dea2a0ee593dcf662a38d5f02487196gavinm
25f476773dea2a0ee593dcf662a38d5f02487196gavinm val &= ~authamd_nb_mcacfg_remove;
25f476773dea2a0ee593dcf662a38d5f02487196gavinm val |= authamd_nb_mcacfg_add;
25f476773dea2a0ee593dcf662a38d5f02487196gavinm
8031591d3cc3c82e97f4b60ea22d671525077b15Srihari Venkatesan authamd_pcicfg_write(procnodeid, MC_FUNC_MISCCTL,
8031591d3cc3c82e97f4b60ea22d671525077b15Srihari Venkatesan MC_CTL_REG_NBCFG, val);
25f476773dea2a0ee593dcf662a38d5f02487196gavinm }
25f476773dea2a0ee593dcf662a38d5f02487196gavinm
25f476773dea2a0ee593dcf662a38d5f02487196gavinm /*
25f476773dea2a0ee593dcf662a38d5f02487196gavinm * Cache scrubbing. We can't enable DRAM scrubbing since
25f476773dea2a0ee593dcf662a38d5f02487196gavinm * we don't know the DRAM base for this node.
25f476773dea2a0ee593dcf662a38d5f02487196gavinm */
25f476773dea2a0ee593dcf662a38d5f02487196gavinm if (AUTHAMD_HAS_CHIPSCRUB(rev) &&
25f476773dea2a0ee593dcf662a38d5f02487196gavinm authamd_scrub_policy != AUTHAMD_SCRUB_BIOSDEFAULT &&
25f476773dea2a0ee593dcf662a38d5f02487196gavinm authamd_chip_once(authamd, AUTHAMD_CFGONCE_CACHESCRUB)) {
8031591d3cc3c82e97f4b60ea22d671525077b15Srihari Venkatesan uint32_t val = authamd_pcicfg_read(procnodeid, MC_FUNC_MISCCTL,
25f476773dea2a0ee593dcf662a38d5f02487196gavinm MC_CTL_REG_SCRUBCTL);
25f476773dea2a0ee593dcf662a38d5f02487196gavinm int l3cap = 0;
25f476773dea2a0ee593dcf662a38d5f02487196gavinm
25f476773dea2a0ee593dcf662a38d5f02487196gavinm if (AUTHAMD_L3CAPABLE(rev)) {
8031591d3cc3c82e97f4b60ea22d671525077b15Srihari Venkatesan l3cap = (authamd_pcicfg_read(procnodeid,
8031591d3cc3c82e97f4b60ea22d671525077b15Srihari Venkatesan MC_FUNC_MISCCTL, MC_CTL_REG_NBCAP) &
8031591d3cc3c82e97f4b60ea22d671525077b15Srihari Venkatesan MC_NBCAP_L3CAPABLE) != 0;
25f476773dea2a0ee593dcf662a38d5f02487196gavinm }
25f476773dea2a0ee593dcf662a38d5f02487196gavinm
25f476773dea2a0ee593dcf662a38d5f02487196gavinm authamd_scrub_rate_dcache =
25f476773dea2a0ee593dcf662a38d5f02487196gavinm authamd_scrubrate(authamd_scrub_rate_dcache,
25f476773dea2a0ee593dcf662a38d5f02487196gavinm (val & AMD_NB_SCRUBCTL_DC_MASK) >> AMD_NB_SCRUBCTL_DC_SHIFT,
25f476773dea2a0ee593dcf662a38d5f02487196gavinm "authamd_scrub_rate_dcache");
25f476773dea2a0ee593dcf662a38d5f02487196gavinm
25f476773dea2a0ee593dcf662a38d5f02487196gavinm authamd_scrub_rate_l2cache =
25f476773dea2a0ee593dcf662a38d5f02487196gavinm authamd_scrubrate(authamd_scrub_rate_l2cache,
25f476773dea2a0ee593dcf662a38d5f02487196gavinm (val & AMD_NB_SCRUBCTL_L2_MASK) >> AMD_NB_SCRUBCTL_L2_SHIFT,
25f476773dea2a0ee593dcf662a38d5f02487196gavinm "authamd_scrub_rate_l2cache");
25f476773dea2a0ee593dcf662a38d5f02487196gavinm
25f476773dea2a0ee593dcf662a38d5f02487196gavinm authamd_scrub_rate_l3cache = l3cap ?
25f476773dea2a0ee593dcf662a38d5f02487196gavinm authamd_scrubrate(authamd_scrub_rate_l3cache,
25f476773dea2a0ee593dcf662a38d5f02487196gavinm (val & AMD_NB_SCRUBCTL_L3_MASK) >> AMD_NB_SCRUBCTL_L3_SHIFT,
25f476773dea2a0ee593dcf662a38d5f02487196gavinm "authamd_scrub_rate_l3cache") : 0;
25f476773dea2a0ee593dcf662a38d5f02487196gavinm
25f476773dea2a0ee593dcf662a38d5f02487196gavinm val = AMD_NB_MKSCRUBCTL(authamd_scrub_rate_l3cache,
25f476773dea2a0ee593dcf662a38d5f02487196gavinm authamd_scrub_rate_dcache, authamd_scrub_rate_l2cache,
25f476773dea2a0ee593dcf662a38d5f02487196gavinm val & AMD_NB_SCRUBCTL_DRAM_MASK);
25f476773dea2a0ee593dcf662a38d5f02487196gavinm
8031591d3cc3c82e97f4b60ea22d671525077b15Srihari Venkatesan authamd_pcicfg_write(procnodeid, MC_FUNC_MISCCTL,
25f476773dea2a0ee593dcf662a38d5f02487196gavinm MC_CTL_REG_SCRUBCTL, val);
25f476773dea2a0ee593dcf662a38d5f02487196gavinm }
25f476773dea2a0ee593dcf662a38d5f02487196gavinm
5667185bc023b9742cb2480659d7673fa9ac8050Srihari Venkatesan /*
5667185bc023b9742cb2480659d7673fa9ac8050Srihari Venkatesan * ECC symbol size. Defaults to 4.
5667185bc023b9742cb2480659d7673fa9ac8050Srihari Venkatesan * Set to 8 on systems that support x8 ECC and have it enabled.
5667185bc023b9742cb2480659d7673fa9ac8050Srihari Venkatesan */
5667185bc023b9742cb2480659d7673fa9ac8050Srihari Venkatesan if (authamd_chip_once(authamd, AUTHAMD_CFGONCE_ECCSYMSZ)) {
5667185bc023b9742cb2480659d7673fa9ac8050Srihari Venkatesan authamd->amd_shared->ans_eccsymsz = "C4";
5667185bc023b9742cb2480659d7673fa9ac8050Srihari Venkatesan if (AUTHAMD_SUPPORTS_X8ECC(rev) &&
5667185bc023b9742cb2480659d7673fa9ac8050Srihari Venkatesan (authamd_pcicfg_read(procnodeid, MC_FUNC_MISCCTL,
5667185bc023b9742cb2480659d7673fa9ac8050Srihari Venkatesan MC_CTL_REG_EXTNBCFG) & MC_EXTNBCFG_ECCSYMSZ))
5667185bc023b9742cb2480659d7673fa9ac8050Srihari Venkatesan authamd->amd_shared->ans_eccsymsz = "C8";
5667185bc023b9742cb2480659d7673fa9ac8050Srihari Venkatesan }
25f476773dea2a0ee593dcf662a38d5f02487196gavinm}
25f476773dea2a0ee593dcf662a38d5f02487196gavinm
25f476773dea2a0ee593dcf662a38d5f02487196gavinm/*
25f476773dea2a0ee593dcf662a38d5f02487196gavinm * cms_poll_ownermask entry point.
25f476773dea2a0ee593dcf662a38d5f02487196gavinm */
25f476773dea2a0ee593dcf662a38d5f02487196gavinmuint64_t
25f476773dea2a0ee593dcf662a38d5f02487196gavinmauthamd_poll_ownermask(cmi_hdl_t hdl, hrtime_t pintvl)
25f476773dea2a0ee593dcf662a38d5f02487196gavinm{
25f476773dea2a0ee593dcf662a38d5f02487196gavinm authamd_data_t *authamd = cms_hdl_getcmsdata(hdl);
5667185bc023b9742cb2480659d7673fa9ac8050Srihari Venkatesan struct authamd_nodeshared *ansp = authamd->amd_shared;
25f476773dea2a0ee593dcf662a38d5f02487196gavinm hrtime_t now = gethrtime_waitfree();
5667185bc023b9742cb2480659d7673fa9ac8050Srihari Venkatesan hrtime_t last = ansp->ans_poll_timestamp;
25f476773dea2a0ee593dcf662a38d5f02487196gavinm int dopoll = 0;
25f476773dea2a0ee593dcf662a38d5f02487196gavinm
25f476773dea2a0ee593dcf662a38d5f02487196gavinm if (now - last > 2 * pintvl || last == 0) {
5667185bc023b9742cb2480659d7673fa9ac8050Srihari Venkatesan ansp->ans_pollowner = hdl;
25f476773dea2a0ee593dcf662a38d5f02487196gavinm dopoll = 1;
5667185bc023b9742cb2480659d7673fa9ac8050Srihari Venkatesan } else if (ansp->ans_pollowner == hdl) {
25f476773dea2a0ee593dcf662a38d5f02487196gavinm dopoll = 1;
25f476773dea2a0ee593dcf662a38d5f02487196gavinm }
25f476773dea2a0ee593dcf662a38d5f02487196gavinm
25f476773dea2a0ee593dcf662a38d5f02487196gavinm if (dopoll)
5667185bc023b9742cb2480659d7673fa9ac8050Srihari Venkatesan ansp->ans_poll_timestamp = now;
25f476773dea2a0ee593dcf662a38d5f02487196gavinm
25f476773dea2a0ee593dcf662a38d5f02487196gavinm return (dopoll ? -1ULL : ~(1 << AMD_MCA_BANK_NB));
25f476773dea2a0ee593dcf662a38d5f02487196gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm}
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm/*
20c794b39650d115e17a15983b6b82e46238cf45gavinm * cms_bank_logout entry point.
20c794b39650d115e17a15983b6b82e46238cf45gavinm */
20c794b39650d115e17a15983b6b82e46238cf45gavinm/*ARGSUSED*/
20c794b39650d115e17a15983b6b82e46238cf45gavinmvoid
20c794b39650d115e17a15983b6b82e46238cf45gavinmauthamd_bank_logout(cmi_hdl_t hdl, int bank, uint64_t status,
20c794b39650d115e17a15983b6b82e46238cf45gavinm uint64_t addr, uint64_t misc, void *mslogout)
20c794b39650d115e17a15983b6b82e46238cf45gavinm{
20c794b39650d115e17a15983b6b82e46238cf45gavinm authamd_data_t *authamd = cms_hdl_getcmsdata(hdl);
20c794b39650d115e17a15983b6b82e46238cf45gavinm struct authamd_logout *msl = mslogout;
5667185bc023b9742cb2480659d7673fa9ac8050Srihari Venkatesan uint32_t rev = authamd->amd_shared->ans_rev;
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm if (msl == NULL)
20c794b39650d115e17a15983b6b82e46238cf45gavinm return;
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm /*
20c794b39650d115e17a15983b6b82e46238cf45gavinm * For main memory ECC errors on revisions with an Online Spare
20c794b39650d115e17a15983b6b82e46238cf45gavinm * Control Register grab the ECC counts by channel and chip-select
20c794b39650d115e17a15983b6b82e46238cf45gavinm * and reset them to 0.
20c794b39650d115e17a15983b6b82e46238cf45gavinm */
20c794b39650d115e17a15983b6b82e46238cf45gavinm if (AUTHAMD_MEMECC_RECOGNISED(rev) &&
20c794b39650d115e17a15983b6b82e46238cf45gavinm AUTHAMD_IS_MEMECCERR(bank, status) &&
20c794b39650d115e17a15983b6b82e46238cf45gavinm AUTHAMD_HAS_ONLINESPARECTL(rev)) {
20c794b39650d115e17a15983b6b82e46238cf45gavinm if (authamd_read_ecccnt(authamd, msl))
20c794b39650d115e17a15983b6b82e46238cf45gavinm authamd_clear_ecccnt(authamd, B_FALSE);
20c794b39650d115e17a15983b6b82e46238cf45gavinm }
20c794b39650d115e17a15983b6b82e46238cf45gavinm}
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm/*
20c794b39650d115e17a15983b6b82e46238cf45gavinm * cms_error_action entry point
20c794b39650d115e17a15983b6b82e46238cf45gavinm */
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinmint authamd_forgive_uc = 0; /* For test/debug only */
20c794b39650d115e17a15983b6b82e46238cf45gavinmint authamd_forgive_pcc = 0; /* For test/debug only */
20c794b39650d115e17a15983b6b82e46238cf45gavinmint authamd_fake_poison = 0; /* For test/debug only */
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm/*ARGSUSED*/
20c794b39650d115e17a15983b6b82e46238cf45gavinmuint32_t
20c794b39650d115e17a15983b6b82e46238cf45gavinmauthamd_error_action(cmi_hdl_t hdl, int ismc, int bank,
20c794b39650d115e17a15983b6b82e46238cf45gavinm uint64_t status, uint64_t addr, uint64_t misc, void *mslogout)
20c794b39650d115e17a15983b6b82e46238cf45gavinm{
20c794b39650d115e17a15983b6b82e46238cf45gavinm authamd_error_disp_t *disp;
20c794b39650d115e17a15983b6b82e46238cf45gavinm uint32_t rv = 0;
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm if (authamd_forgive_uc)
20c794b39650d115e17a15983b6b82e46238cf45gavinm rv |= CMS_ERRSCOPE_CLEARED_UC;
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm if (authamd_forgive_pcc)
20c794b39650d115e17a15983b6b82e46238cf45gavinm rv |= CMS_ERRSCOPE_CURCONTEXT_OK;
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm if (authamd_fake_poison && status & MSR_MC_STATUS_UC)
20c794b39650d115e17a15983b6b82e46238cf45gavinm rv |= CMS_ERRSCOPE_POISONED;
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm if (rv)
20c794b39650d115e17a15983b6b82e46238cf45gavinm return (rv);
20c794b39650d115e17a15983b6b82e46238cf45gavinm
c84b7bbef5ecc2a27799422588073deefd9db715Adrian Frost disp = authamd_disp_match(hdl, ismc, bank, status, addr, misc,
c84b7bbef5ecc2a27799422588073deefd9db715Adrian Frost mslogout);
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm if (disp == &authamd_gart_disp) {
20c794b39650d115e17a15983b6b82e46238cf45gavinm /*
20c794b39650d115e17a15983b6b82e46238cf45gavinm * GART walk errors set UC and possibly PCC (if source CPU)
20c794b39650d115e17a15983b6b82e46238cf45gavinm * but should not be regarded as terminal.
20c794b39650d115e17a15983b6b82e46238cf45gavinm */
20c794b39650d115e17a15983b6b82e46238cf45gavinm return (CMS_ERRSCOPE_IGNORE_ERR);
20c794b39650d115e17a15983b6b82e46238cf45gavinm }
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm /*
20c794b39650d115e17a15983b6b82e46238cf45gavinm * May also want to consider master abort and target abort. These
20c794b39650d115e17a15983b6b82e46238cf45gavinm * also set UC and PCC (if src CPU) but the requester gets -1
20c794b39650d115e17a15983b6b82e46238cf45gavinm * and I believe the IO stuff in Solaris will handle that.
20c794b39650d115e17a15983b6b82e46238cf45gavinm */
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm return (rv);
20c794b39650d115e17a15983b6b82e46238cf45gavinm}
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm/*
20c794b39650d115e17a15983b6b82e46238cf45gavinm * cms_disp_match entry point
20c794b39650d115e17a15983b6b82e46238cf45gavinm */
20c794b39650d115e17a15983b6b82e46238cf45gavinm/*ARGSUSED*/
20c794b39650d115e17a15983b6b82e46238cf45gavinmcms_cookie_t
c84b7bbef5ecc2a27799422588073deefd9db715Adrian Frostauthamd_disp_match(cmi_hdl_t hdl, int ismc, int bank, uint64_t status,
20c794b39650d115e17a15983b6b82e46238cf45gavinm uint64_t addr, uint64_t misc, void *mslogout)
20c794b39650d115e17a15983b6b82e46238cf45gavinm{
20c794b39650d115e17a15983b6b82e46238cf45gavinm authamd_data_t *authamd = cms_hdl_getcmsdata(hdl);
20c794b39650d115e17a15983b6b82e46238cf45gavinm /* uint16_t errcode = MCAX86_ERRCODE(status); */
20c794b39650d115e17a15983b6b82e46238cf45gavinm uint16_t exterrcode = AMD_EXT_ERRCODE(status);
5667185bc023b9742cb2480659d7673fa9ac8050Srihari Venkatesan uint32_t rev = authamd->amd_shared->ans_rev;
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm /*
20c794b39650d115e17a15983b6b82e46238cf45gavinm * Recognise main memory ECC errors
20c794b39650d115e17a15983b6b82e46238cf45gavinm */
20c794b39650d115e17a15983b6b82e46238cf45gavinm if (AUTHAMD_MEMECC_RECOGNISED(rev) &&
20c794b39650d115e17a15983b6b82e46238cf45gavinm AUTHAMD_IS_MEMECCERR(bank, status)) {
20c794b39650d115e17a15983b6b82e46238cf45gavinm if (status & AMD_BANK_STAT_CECC) {
20c794b39650d115e17a15983b6b82e46238cf45gavinm return (exterrcode == 0 ? &authamd_memce_disp :
20c794b39650d115e17a15983b6b82e46238cf45gavinm &authamd_ckmemce_disp);
20c794b39650d115e17a15983b6b82e46238cf45gavinm } else if (status & AMD_BANK_STAT_UECC) {
20c794b39650d115e17a15983b6b82e46238cf45gavinm return (exterrcode == 0 ? &authamd_memue_disp :
20c794b39650d115e17a15983b6b82e46238cf45gavinm &authamd_ckmemue_disp);
20c794b39650d115e17a15983b6b82e46238cf45gavinm }
20c794b39650d115e17a15983b6b82e46238cf45gavinm }
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm /*
20c794b39650d115e17a15983b6b82e46238cf45gavinm * Recognise GART walk errors
20c794b39650d115e17a15983b6b82e46238cf45gavinm */
20c794b39650d115e17a15983b6b82e46238cf45gavinm if (AUTHAMD_NOGARTTBLWLK_MC(rev) && AUTHAMD_IS_GARTERR(bank, status))
20c794b39650d115e17a15983b6b82e46238cf45gavinm return (&authamd_gart_disp);
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm return (NULL);
20c794b39650d115e17a15983b6b82e46238cf45gavinm}
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm/*
20c794b39650d115e17a15983b6b82e46238cf45gavinm * cms_ereport_class entry point
20c794b39650d115e17a15983b6b82e46238cf45gavinm */
20c794b39650d115e17a15983b6b82e46238cf45gavinm/*ARGSUSED*/
20c794b39650d115e17a15983b6b82e46238cf45gavinmvoid
20c794b39650d115e17a15983b6b82e46238cf45gavinmauthamd_ereport_class(cmi_hdl_t hdl, cms_cookie_t mscookie,
20c794b39650d115e17a15983b6b82e46238cf45gavinm const char **cpuclsp, const char **leafclsp)
20c794b39650d115e17a15983b6b82e46238cf45gavinm{
20c794b39650d115e17a15983b6b82e46238cf45gavinm const authamd_error_disp_t *aed = mscookie;
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm if (aed == NULL)
20c794b39650d115e17a15983b6b82e46238cf45gavinm return;
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm if (aed->aad_subclass != NULL)
20c794b39650d115e17a15983b6b82e46238cf45gavinm *cpuclsp = aed->aad_subclass;
20c794b39650d115e17a15983b6b82e46238cf45gavinm if (aed->aad_leafclass != NULL)
20c794b39650d115e17a15983b6b82e46238cf45gavinm *leafclsp = aed->aad_leafclass;
20c794b39650d115e17a15983b6b82e46238cf45gavinm}
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm/*ARGSUSED*/
20c794b39650d115e17a15983b6b82e46238cf45gavinmstatic void
20c794b39650d115e17a15983b6b82e46238cf45gavinmauthamd_ereport_add_resource(cmi_hdl_t hdl, authamd_data_t *authamd,
20c794b39650d115e17a15983b6b82e46238cf45gavinm nvlist_t *ereport, nv_alloc_t *nva, void *mslogout)
20c794b39650d115e17a15983b6b82e46238cf45gavinm{
20c794b39650d115e17a15983b6b82e46238cf45gavinm nvlist_t *elems[AUTHAMD_DRAM_NCHANNEL * AUTHAMD_DRAM_NCS];
20c794b39650d115e17a15983b6b82e46238cf45gavinm uint8_t counts[AUTHAMD_DRAM_NCHANNEL * AUTHAMD_DRAM_NCS];
20c794b39650d115e17a15983b6b82e46238cf45gavinm authamd_logout_t *msl;
20c794b39650d115e17a15983b6b82e46238cf45gavinm nvlist_t *nvl;
20c794b39650d115e17a15983b6b82e46238cf45gavinm int nelems = 0;
8031591d3cc3c82e97f4b60ea22d671525077b15Srihari Venkatesan int i, chan, cs, mc;
074bb90d80fdbeb2d04a8450a55ecbc96de28785Tom Pothier nvlist_t *board_list = NULL;
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm if ((msl = mslogout) == NULL)
20c794b39650d115e17a15983b6b82e46238cf45gavinm return;
20c794b39650d115e17a15983b6b82e46238cf45gavinm
8031591d3cc3c82e97f4b60ea22d671525077b15Srihari Venkatesan /* Assume all processors have the same number of nodes */
5667185bc023b9742cb2480659d7673fa9ac8050Srihari Venkatesan mc = authamd->amd_shared->ans_procnodeid %
8031591d3cc3c82e97f4b60ea22d671525077b15Srihari Venkatesan cpuid_get_procnodes_per_pkg(CPU);
8031591d3cc3c82e97f4b60ea22d671525077b15Srihari Venkatesan
20c794b39650d115e17a15983b6b82e46238cf45gavinm for (chan = 0; chan < AUTHAMD_DRAM_NCHANNEL; chan++) {
20c794b39650d115e17a15983b6b82e46238cf45gavinm for (cs = 0; cs < AUTHAMD_DRAM_NCS; cs++) {
20c794b39650d115e17a15983b6b82e46238cf45gavinm if (msl->aal_eccerrcnt[chan][cs] == 0)
20c794b39650d115e17a15983b6b82e46238cf45gavinm continue;
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm if ((nvl = fm_nvlist_create(nva)) == NULL)
20c794b39650d115e17a15983b6b82e46238cf45gavinm continue;
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm elems[nelems] = nvl;
20c794b39650d115e17a15983b6b82e46238cf45gavinm counts[nelems++] = msl->aal_eccerrcnt[chan][cs];
20c794b39650d115e17a15983b6b82e46238cf45gavinm
074bb90d80fdbeb2d04a8450a55ecbc96de28785Tom Pothier if (!x86gentopo_legacy) {
074bb90d80fdbeb2d04a8450a55ecbc96de28785Tom Pothier board_list = cmi_hdl_smb_bboard(hdl);
074bb90d80fdbeb2d04a8450a55ecbc96de28785Tom Pothier if (board_list == NULL)
074bb90d80fdbeb2d04a8450a55ecbc96de28785Tom Pothier continue;
074bb90d80fdbeb2d04a8450a55ecbc96de28785Tom Pothier fm_fmri_hc_create(nvl, FM_HC_SCHEME_VERSION,
074bb90d80fdbeb2d04a8450a55ecbc96de28785Tom Pothier NULL, NULL, board_list, 4,
074bb90d80fdbeb2d04a8450a55ecbc96de28785Tom Pothier "chip", cmi_hdl_smb_chipid(hdl),
074bb90d80fdbeb2d04a8450a55ecbc96de28785Tom Pothier "memory-controller", 0,
074bb90d80fdbeb2d04a8450a55ecbc96de28785Tom Pothier "dram-channel", chan,
074bb90d80fdbeb2d04a8450a55ecbc96de28785Tom Pothier "chip-select", cs);
074bb90d80fdbeb2d04a8450a55ecbc96de28785Tom Pothier } else {
074bb90d80fdbeb2d04a8450a55ecbc96de28785Tom Pothier fm_fmri_hc_set(nvl, FM_HC_SCHEME_VERSION,
074bb90d80fdbeb2d04a8450a55ecbc96de28785Tom Pothier NULL, NULL, 5,
074bb90d80fdbeb2d04a8450a55ecbc96de28785Tom Pothier "motherboard", 0,
5667185bc023b9742cb2480659d7673fa9ac8050Srihari Venkatesan "chip", authamd->amd_shared->ans_chipid,
8031591d3cc3c82e97f4b60ea22d671525077b15Srihari Venkatesan "memory-controller", mc,
074bb90d80fdbeb2d04a8450a55ecbc96de28785Tom Pothier "dram-channel", chan,
074bb90d80fdbeb2d04a8450a55ecbc96de28785Tom Pothier "chip-select", cs);
074bb90d80fdbeb2d04a8450a55ecbc96de28785Tom Pothier }
20c794b39650d115e17a15983b6b82e46238cf45gavinm }
20c794b39650d115e17a15983b6b82e46238cf45gavinm }
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm if (nelems == 0)
20c794b39650d115e17a15983b6b82e46238cf45gavinm return;
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm fm_payload_set(ereport, FM_EREPORT_GENAMD_PAYLOAD_NAME_RESOURCE,
20c794b39650d115e17a15983b6b82e46238cf45gavinm DATA_TYPE_NVLIST_ARRAY, nelems, elems,
20c794b39650d115e17a15983b6b82e46238cf45gavinm NULL);
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm fm_payload_set(ereport, FM_EREPORT_GENAMD_PAYLOAD_NAME_RESOURCECNT,
20c794b39650d115e17a15983b6b82e46238cf45gavinm DATA_TYPE_UINT8_ARRAY, nelems, &counts[0],
20c794b39650d115e17a15983b6b82e46238cf45gavinm NULL);
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm for (i = 0; i < nelems; i++)
20c794b39650d115e17a15983b6b82e46238cf45gavinm fm_nvlist_destroy(elems[i], nva ? FM_NVA_RETAIN : FM_NVA_FREE);
20c794b39650d115e17a15983b6b82e46238cf45gavinm}
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm/*
20c794b39650d115e17a15983b6b82e46238cf45gavinm * cms_ereport_add_logout entry point
20c794b39650d115e17a15983b6b82e46238cf45gavinm */
20c794b39650d115e17a15983b6b82e46238cf45gavinm/*ARGSUSED*/
20c794b39650d115e17a15983b6b82e46238cf45gavinmvoid
20c794b39650d115e17a15983b6b82e46238cf45gavinmauthamd_ereport_add_logout(cmi_hdl_t hdl, nvlist_t *ereport, nv_alloc_t *nva,
20c794b39650d115e17a15983b6b82e46238cf45gavinm int bank, uint64_t status, uint64_t addr, uint64_t misc,
20c794b39650d115e17a15983b6b82e46238cf45gavinm void *mslogout, cms_cookie_t mscookie)
20c794b39650d115e17a15983b6b82e46238cf45gavinm{
20c794b39650d115e17a15983b6b82e46238cf45gavinm authamd_data_t *authamd = cms_hdl_getcmsdata(hdl);
20c794b39650d115e17a15983b6b82e46238cf45gavinm const authamd_error_disp_t *aed = mscookie;
20c794b39650d115e17a15983b6b82e46238cf45gavinm uint64_t members;
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm if (aed == NULL)
20c794b39650d115e17a15983b6b82e46238cf45gavinm return;
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm members = aed->aad_ereport_members;
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm if (members & FM_EREPORT_GENAMD_PAYLOAD_FLAG_SYND) {
20c794b39650d115e17a15983b6b82e46238cf45gavinm fm_payload_set(ereport, FM_EREPORT_GENAMD_PAYLOAD_NAME_SYND,
20c794b39650d115e17a15983b6b82e46238cf45gavinm DATA_TYPE_UINT16, (uint16_t)AMD_BANK_SYND(status),
20c794b39650d115e17a15983b6b82e46238cf45gavinm NULL);
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm if (members & FM_EREPORT_GENAMD_PAYLOAD_FLAG_SYNDTYPE) {
20c794b39650d115e17a15983b6b82e46238cf45gavinm fm_payload_set(ereport,
20c794b39650d115e17a15983b6b82e46238cf45gavinm FM_EREPORT_GENAMD_PAYLOAD_NAME_SYNDTYPE,
20c794b39650d115e17a15983b6b82e46238cf45gavinm DATA_TYPE_STRING, "E",
20c794b39650d115e17a15983b6b82e46238cf45gavinm NULL);
20c794b39650d115e17a15983b6b82e46238cf45gavinm }
20c794b39650d115e17a15983b6b82e46238cf45gavinm }
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm if (members & FM_EREPORT_GENAMD_PAYLOAD_FLAG_CKSYND) {
20c794b39650d115e17a15983b6b82e46238cf45gavinm fm_payload_set(ereport, FM_EREPORT_GENAMD_PAYLOAD_NAME_CKSYND,
20c794b39650d115e17a15983b6b82e46238cf45gavinm DATA_TYPE_UINT16, (uint16_t)AMD_NB_STAT_CKSYND(status),
20c794b39650d115e17a15983b6b82e46238cf45gavinm NULL);
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm if (members & FM_EREPORT_GENAMD_PAYLOAD_FLAG_SYNDTYPE) {
20c794b39650d115e17a15983b6b82e46238cf45gavinm fm_payload_set(ereport,
20c794b39650d115e17a15983b6b82e46238cf45gavinm FM_EREPORT_GENAMD_PAYLOAD_NAME_SYNDTYPE,
5667185bc023b9742cb2480659d7673fa9ac8050Srihari Venkatesan DATA_TYPE_STRING, authamd->amd_shared->ans_eccsymsz,
20c794b39650d115e17a15983b6b82e46238cf45gavinm NULL);
20c794b39650d115e17a15983b6b82e46238cf45gavinm }
20c794b39650d115e17a15983b6b82e46238cf45gavinm }
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm if (members & FM_EREPORT_GENAMD_PAYLOAD_FLAG_RESOURCE &&
20c794b39650d115e17a15983b6b82e46238cf45gavinm status & MSR_MC_STATUS_ADDRV) {
20c794b39650d115e17a15983b6b82e46238cf45gavinm authamd_ereport_add_resource(hdl, authamd, ereport, nva,
20c794b39650d115e17a15983b6b82e46238cf45gavinm mslogout);
20c794b39650d115e17a15983b6b82e46238cf45gavinm }
20c794b39650d115e17a15983b6b82e46238cf45gavinm}
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm/*
20c794b39650d115e17a15983b6b82e46238cf45gavinm * cms_msrinject entry point
20c794b39650d115e17a15983b6b82e46238cf45gavinm */
20c794b39650d115e17a15983b6b82e46238cf45gavinmcms_errno_t
20c794b39650d115e17a15983b6b82e46238cf45gavinmauthamd_msrinject(cmi_hdl_t hdl, uint_t msr, uint64_t val)
20c794b39650d115e17a15983b6b82e46238cf45gavinm{
20c794b39650d115e17a15983b6b82e46238cf45gavinm authamd_data_t *authamd = cms_hdl_getcmsdata(hdl);
20c794b39650d115e17a15983b6b82e46238cf45gavinm cms_errno_t rv = CMSERR_BADMSRWRITE;
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm authamd_bankstatus_prewrite(hdl, authamd);
20c794b39650d115e17a15983b6b82e46238cf45gavinm if (cmi_hdl_wrmsr(hdl, msr, val) == CMI_SUCCESS)
20c794b39650d115e17a15983b6b82e46238cf45gavinm rv = CMS_SUCCESS;
20c794b39650d115e17a15983b6b82e46238cf45gavinm authamd_bankstatus_postwrite(hdl, authamd);
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm return (rv);
20c794b39650d115e17a15983b6b82e46238cf45gavinm}
20c794b39650d115e17a15983b6b82e46238cf45gavinm
c84b7bbef5ecc2a27799422588073deefd9db715Adrian Frostcms_api_ver_t _cms_api_version = CMS_API_VERSION_2;
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinmconst cms_ops_t _cms_ops = {
20c794b39650d115e17a15983b6b82e46238cf45gavinm authamd_init, /* cms_init */
20c794b39650d115e17a15983b6b82e46238cf45gavinm NULL, /* cms_post_startup */
20c794b39650d115e17a15983b6b82e46238cf45gavinm NULL, /* cms_post_mpstartup */
20c794b39650d115e17a15983b6b82e46238cf45gavinm authamd_logout_size, /* cms_logout_size */
20c794b39650d115e17a15983b6b82e46238cf45gavinm authamd_mcgctl_val, /* cms_mcgctl_val */
20c794b39650d115e17a15983b6b82e46238cf45gavinm authamd_bankctl_skipinit, /* cms_bankctl_skipinit */
20c794b39650d115e17a15983b6b82e46238cf45gavinm authamd_bankctl_val, /* cms_bankctl_val */
20c794b39650d115e17a15983b6b82e46238cf45gavinm NULL, /* cms_bankstatus_skipinit */
20c794b39650d115e17a15983b6b82e46238cf45gavinm NULL, /* cms_bankstatus_val */
20c794b39650d115e17a15983b6b82e46238cf45gavinm authamd_mca_init, /* cms_mca_init */
25f476773dea2a0ee593dcf662a38d5f02487196gavinm authamd_poll_ownermask, /* cms_poll_ownermask */
20c794b39650d115e17a15983b6b82e46238cf45gavinm authamd_bank_logout, /* cms_bank_logout */
20c794b39650d115e17a15983b6b82e46238cf45gavinm authamd_error_action, /* cms_error_action */
20c794b39650d115e17a15983b6b82e46238cf45gavinm authamd_disp_match, /* cms_disp_match */
20c794b39650d115e17a15983b6b82e46238cf45gavinm authamd_ereport_class, /* cms_ereport_class */
20c794b39650d115e17a15983b6b82e46238cf45gavinm NULL, /* cms_ereport_detector */
20c794b39650d115e17a15983b6b82e46238cf45gavinm NULL, /* cms_ereport_includestack */
20c794b39650d115e17a15983b6b82e46238cf45gavinm authamd_ereport_add_logout, /* cms_ereport_add_logout */
20c794b39650d115e17a15983b6b82e46238cf45gavinm authamd_msrinject, /* cms_msrinject */
20c794b39650d115e17a15983b6b82e46238cf45gavinm NULL, /* cms_fini */
20c794b39650d115e17a15983b6b82e46238cf45gavinm};
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinmstatic struct modlcpu modlcpu = {
20c794b39650d115e17a15983b6b82e46238cf45gavinm &mod_cpuops,
20c794b39650d115e17a15983b6b82e46238cf45gavinm "Generic AMD model-specific MCA"
20c794b39650d115e17a15983b6b82e46238cf45gavinm};
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinmstatic struct modlinkage modlinkage = {
20c794b39650d115e17a15983b6b82e46238cf45gavinm MODREV_1,
20c794b39650d115e17a15983b6b82e46238cf45gavinm (void *)&modlcpu,
20c794b39650d115e17a15983b6b82e46238cf45gavinm NULL
20c794b39650d115e17a15983b6b82e46238cf45gavinm};
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinmint
20c794b39650d115e17a15983b6b82e46238cf45gavinm_init(void)
20c794b39650d115e17a15983b6b82e46238cf45gavinm{
20c794b39650d115e17a15983b6b82e46238cf45gavinm return (mod_install(&modlinkage));
20c794b39650d115e17a15983b6b82e46238cf45gavinm}
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinmint
20c794b39650d115e17a15983b6b82e46238cf45gavinm_info(struct modinfo *modinfop)
20c794b39650d115e17a15983b6b82e46238cf45gavinm{
20c794b39650d115e17a15983b6b82e46238cf45gavinm return (mod_info(&modlinkage, modinfop));
20c794b39650d115e17a15983b6b82e46238cf45gavinm}
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinmint
20c794b39650d115e17a15983b6b82e46238cf45gavinm_fini(void)
20c794b39650d115e17a15983b6b82e46238cf45gavinm{
20c794b39650d115e17a15983b6b82e46238cf45gavinm return (mod_remove(&modlinkage));
20c794b39650d115e17a15983b6b82e46238cf45gavinm}