ao_mca.c revision 25f476773dea2a0ee593dcf662a38d5f02487196
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi/*
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * CDDL HEADER START
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi *
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * The contents of this file are subject to the terms of the
a307a2550e1618a7971751ee83c22441ced27bbegavinm * Common Development and Distribution License (the "License").
a307a2550e1618a7971751ee83c22441ced27bbegavinm * You may not use this file except in compliance with the License.
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi *
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * or http://www.opensolaris.org/os/licensing.
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * See the License for the specific language governing permissions
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * and limitations under the License.
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi *
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * When distributing Covered Code, include this CDDL HEADER in each
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * If applicable, add the following below this CDDL HEADER, with the
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * fields enclosed by brackets "[]" replaced with your own identifying
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * information: Portions Copyright [yyyy] [name of copyright owner]
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi *
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * CDDL HEADER END
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi */
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi/*
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * Use is subject to license terms.
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi */
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi#pragma ident "%Z%%M% %I% %E% SMI"
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi#include <sys/types.h>
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi#include <sys/regset.h>
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi#include <sys/privregs.h>
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi#include <sys/pci_impl.h>
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi#include <sys/cpuvar.h>
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi#include <sys/x86_archext.h>
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi#include <sys/cmn_err.h>
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi#include <sys/systm.h>
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi#include <sys/sysmacros.h>
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe#include <sys/pghw.h>
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi#include <sys/cyclic.h>
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi#include <sys/sysevent.h>
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi#include <sys/smbios.h>
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi#include <sys/mca_x86.h>
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi#include <sys/mca_amd.h>
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi#include <sys/mc.h>
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm#include <sys/mc_amd.h>
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi#include <sys/psw.h>
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi#include <sys/ddi.h>
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi#include <sys/sunddi.h>
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi#include <sys/sdt.h>
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi#include <sys/fm/util.h>
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi#include <sys/fm/protocol.h>
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi#include <sys/fm/cpu/AMD.h>
bc946ef3d51a883d2aa15b39f2d8b03a119e26casethg#include <sys/acpi/acpi.h>
bc946ef3d51a883d2aa15b39f2d8b03a119e26casethg#include <sys/acpi/acpi_pci.h>
bc946ef3d51a883d2aa15b39f2d8b03a119e26casethg#include <sys/acpica.h>
20c794b39650d115e17a15983b6b82e46238cf45gavinm#include <sys/cpu_module.h>
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi#include "ao.h"
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi#include "ao_mca_disp.h"
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
20c794b39650d115e17a15983b6b82e46238cf45gavinm#define AO_F_REVS_FG (X86_CHIPREV_AMD_F_REV_F | X86_CHIPREV_AMD_F_REV_G)
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindiint ao_mca_smi_disable = 1; /* attempt to disable SMI polling */
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
8a40a695ee676a322b094e9afe5375567bfb51e3gavinmstruct ao_ctl_init {
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm uint32_t ctl_revmask; /* rev(s) to which this applies */
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm uint64_t ctl_bits; /* mca ctl reg bitmask to set */
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm};
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm/*
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm * Additional NB MCA ctl initialization for revs F and G
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm */
8a40a695ee676a322b094e9afe5375567bfb51e3gavinmstatic const struct ao_ctl_init ao_nb_ctl_init[] = {
20c794b39650d115e17a15983b6b82e46238cf45gavinm { AO_F_REVS_FG, AMD_NB_CTL_INIT_REV_FG },
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm { X86_CHIPREV_UNKNOWN, 0 }
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi};
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecinditypedef struct ao_bank_cfg {
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm uint64_t bank_ctl_init_cmn; /* Common init value */
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm const struct ao_ctl_init *bank_ctl_init_extra; /* Extra for each rev */
20c794b39650d115e17a15983b6b82e46238cf45gavinm void (*bank_misc_initfunc)(cmi_hdl_t, ao_ms_data_t *, uint32_t);
20c794b39650d115e17a15983b6b82e46238cf45gavinm uint_t bank_ctl_mask;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi} ao_bank_cfg_t;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
20c794b39650d115e17a15983b6b82e46238cf45gavinmstatic void nb_mcamisc_init(cmi_hdl_t, ao_ms_data_t *, uint32_t);
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindistatic const ao_bank_cfg_t ao_bank_cfgs[] = {
20c794b39650d115e17a15983b6b82e46238cf45gavinm { AMD_DC_CTL_INIT_CMN, NULL, NULL, AMD_MSR_DC_MASK },
20c794b39650d115e17a15983b6b82e46238cf45gavinm { AMD_IC_CTL_INIT_CMN, NULL, NULL, AMD_MSR_IC_MASK },
20c794b39650d115e17a15983b6b82e46238cf45gavinm { AMD_BU_CTL_INIT_CMN, NULL, NULL, AMD_MSR_BU_MASK },
20c794b39650d115e17a15983b6b82e46238cf45gavinm { AMD_LS_CTL_INIT_CMN, NULL, NULL, AMD_MSR_LS_MASK },
20c794b39650d115e17a15983b6b82e46238cf45gavinm { AMD_NB_CTL_INIT_CMN, &ao_nb_ctl_init[0], nb_mcamisc_init,
20c794b39650d115e17a15983b6b82e46238cf45gavinm AMD_MSR_NB_MASK },
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi};
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
20c794b39650d115e17a15983b6b82e46238cf45gavinmstatic int ao_nbanks = sizeof (ao_bank_cfgs) / sizeof (ao_bank_cfgs[0]);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi/*
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * This is quite awful but necessary to work around x86 system vendor's view of
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * the world. Other operating systems (you know who you are) don't understand
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * Opteron-specific error handling, so BIOS and system vendors often hide these
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * conditions from them by using SMI polling to copy out any errors from the
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * machine-check registers. When Solaris runs on a system with this feature,
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * we want to disable the SMI polling so we can use FMA instead. Sadly, there
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * isn't even a standard self-describing way to express the whole situation,
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * so we have to resort to hard-coded values. This should all be changed to
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * be a self-describing vendor-specific SMBIOS structure in the future.
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi */
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindistatic const struct ao_smi_disable {
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi const char *asd_sys_vendor; /* SMB_TYPE_SYSTEM vendor prefix */
4156fc34b973159b0334e05ae5ec19344487bdc0gavinm const char *asd_sys_product; /* SMB_TYPE_SYSTEM product prefix */
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi const char *asd_bios_vendor; /* SMB_TYPE_BIOS vendor prefix */
a6d65bf44b30c41c72de38d957e1d635f62f8314sethg uint8_t asd_code; /* output code for SMI disable */
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi} ao_smi_disable[] = {
4156fc34b973159b0334e05ae5ec19344487bdc0gavinm { "Sun Microsystems", "Galaxy12",
4156fc34b973159b0334e05ae5ec19344487bdc0gavinm "American Megatrends", 0x59 },
4156fc34b973159b0334e05ae5ec19344487bdc0gavinm { "Sun Microsystems", "Sun Fire X4100 Server",
4156fc34b973159b0334e05ae5ec19344487bdc0gavinm "American Megatrends", 0x59 },
4156fc34b973159b0334e05ae5ec19344487bdc0gavinm { "Sun Microsystems", "Sun Fire X4200 Server",
4156fc34b973159b0334e05ae5ec19344487bdc0gavinm "American Megatrends", 0x59 },
4156fc34b973159b0334e05ae5ec19344487bdc0gavinm { NULL, NULL, NULL, 0 }
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi};
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindistatic int
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindiao_disp_match_r4(uint16_t ref, uint8_t r4)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi{
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi static const uint16_t ao_r4_map[] = {
20c794b39650d115e17a15983b6b82e46238cf45gavinm AO_MCA_R4_BIT_ERR, /* MCAX86_ERRCODE_RRRR_ERR */
20c794b39650d115e17a15983b6b82e46238cf45gavinm AO_MCA_R4_BIT_RD, /* MCAX86_ERRCODE_RRRR_RD */
20c794b39650d115e17a15983b6b82e46238cf45gavinm AO_MCA_R4_BIT_WR, /* MCAX86_ERRCODE_RRRR_WR */
20c794b39650d115e17a15983b6b82e46238cf45gavinm AO_MCA_R4_BIT_DRD, /* MCAX86_ERRCODE_RRRR_DRD */
20c794b39650d115e17a15983b6b82e46238cf45gavinm AO_MCA_R4_BIT_DWR, /* MCAX86_ERRCODE_RRRR_DWR */
20c794b39650d115e17a15983b6b82e46238cf45gavinm AO_MCA_R4_BIT_IRD, /* MCAX86_ERRCODE_RRRR_IRD */
20c794b39650d115e17a15983b6b82e46238cf45gavinm AO_MCA_R4_BIT_PREFETCH, /* MCAX86_ERRCODE_RRRR_PREFETCH */
20c794b39650d115e17a15983b6b82e46238cf45gavinm AO_MCA_R4_BIT_EVICT, /* MCAX86_ERRCODE_RRRR_EVICT */
20c794b39650d115e17a15983b6b82e46238cf45gavinm AO_MCA_R4_BIT_SNOOP /* MCAX86_ERRCODE_RRRR_SNOOP */
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi };
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi ASSERT(r4 < sizeof (ao_r4_map) / sizeof (uint16_t));
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return ((ref & ao_r4_map[r4]) != 0);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi}
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindistatic int
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindiao_disp_match_pp(uint8_t ref, uint8_t pp)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi{
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi static const uint8_t ao_pp_map[] = {
20c794b39650d115e17a15983b6b82e46238cf45gavinm AO_MCA_PP_BIT_SRC, /* MCAX86_ERRCODE_PP_SRC */
20c794b39650d115e17a15983b6b82e46238cf45gavinm AO_MCA_PP_BIT_RES, /* MCAX86_ERRCODE_PP_RES */
20c794b39650d115e17a15983b6b82e46238cf45gavinm AO_MCA_PP_BIT_OBS, /* MCAX86_ERRCODE_PP_OBS */
20c794b39650d115e17a15983b6b82e46238cf45gavinm AO_MCA_PP_BIT_GEN /* MCAX86_ERRCODE_PP_GEN */
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi };
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi ASSERT(pp < sizeof (ao_pp_map) / sizeof (uint8_t));
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return ((ref & ao_pp_map[pp]) != 0);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi}
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindistatic int
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindiao_disp_match_ii(uint8_t ref, uint8_t ii)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi{
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi static const uint8_t ao_ii_map[] = {
20c794b39650d115e17a15983b6b82e46238cf45gavinm AO_MCA_II_BIT_MEM, /* MCAX86_ERRCODE_II_MEM */
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi 0,
20c794b39650d115e17a15983b6b82e46238cf45gavinm AO_MCA_II_BIT_IO, /* MCAX86_ERRCODE_II_IO */
20c794b39650d115e17a15983b6b82e46238cf45gavinm AO_MCA_II_BIT_GEN /* MCAX86_ERRCODE_II_GEN */
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi };
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi ASSERT(ii < sizeof (ao_ii_map) / sizeof (uint8_t));
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return ((ref & ao_ii_map[ii]) != 0);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi}
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindistatic uint8_t
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindibit_strip(uint16_t *codep, uint16_t mask, uint16_t shift)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi{
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi uint8_t val = (*codep & mask) >> shift;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi *codep &= ~mask;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (val);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi}
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi#define BIT_STRIP(codep, name) \
20c794b39650d115e17a15983b6b82e46238cf45gavinm bit_strip(codep, MCAX86_ERRCODE_##name##_MASK, \
20c794b39650d115e17a15983b6b82e46238cf45gavinm MCAX86_ERRCODE_##name##_SHIFT)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
20c794b39650d115e17a15983b6b82e46238cf45gavinm/*ARGSUSED*/
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindistatic int
8a40a695ee676a322b094e9afe5375567bfb51e3gavinmao_disp_match_one(const ao_error_disp_t *aed, uint64_t status, uint32_t rev,
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm int bankno)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi{
20c794b39650d115e17a15983b6b82e46238cf45gavinm uint16_t code = MCAX86_ERRCODE(status);
20c794b39650d115e17a15983b6b82e46238cf45gavinm uint8_t extcode = AMD_EXT_ERRCODE(status);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi uint64_t stat_mask = aed->aed_stat_mask;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi uint64_t stat_mask_res = aed->aed_stat_mask_res;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi /*
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * If the bank's status register indicates overflow, then we can no
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * longer rely on the value of CECC: our experience with actual fault
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * injection has shown that multiple CE's overwriting each other shows
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * AMD_BANK_STAT_CECC and AMD_BANK_STAT_UECC both set to zero. This
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * should be clarified in a future BKDG or by the Revision Guide.
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm * This behaviour is fixed in revision F.
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi */
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm if (bankno == AMD_MCA_BANK_NB &&
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm !X86_CHIPREV_ATLEAST(rev, X86_CHIPREV_AMD_F_REV_F) &&
20c794b39650d115e17a15983b6b82e46238cf45gavinm status & MSR_MC_STATUS_OVER) {
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi stat_mask &= ~AMD_BANK_STAT_CECC;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi stat_mask_res &= ~AMD_BANK_STAT_CECC;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi }
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if ((status & stat_mask) != stat_mask_res)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (0);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi /*
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * r4 and pp bits are stored separately, so we mask off and compare them
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * for the code types that use them. Once we've taken the r4 and pp
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * bits out of the equation, we can directly compare the resulting code
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * with the one stored in the ao_error_disp_t.
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi */
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if (AMD_ERRCODE_ISMEM(code)) {
20c794b39650d115e17a15983b6b82e46238cf45gavinm uint8_t r4 = BIT_STRIP(&code, RRRR);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if (!ao_disp_match_r4(aed->aed_stat_r4_bits, r4))
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (0);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi } else if (AMD_ERRCODE_ISBUS(code)) {
20c794b39650d115e17a15983b6b82e46238cf45gavinm uint8_t r4 = BIT_STRIP(&code, RRRR);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi uint8_t pp = BIT_STRIP(&code, PP);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi uint8_t ii = BIT_STRIP(&code, II);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if (!ao_disp_match_r4(aed->aed_stat_r4_bits, r4) ||
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi !ao_disp_match_pp(aed->aed_stat_pp_bits, pp) ||
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi !ao_disp_match_ii(aed->aed_stat_ii_bits, ii))
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (0);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi }
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (code == aed->aed_stat_code && extcode == aed->aed_stat_extcode);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi}
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
20c794b39650d115e17a15983b6b82e46238cf45gavinm/*ARGSUSED*/
20c794b39650d115e17a15983b6b82e46238cf45gavinmcms_cookie_t
20c794b39650d115e17a15983b6b82e46238cf45gavinmao_ms_disp_match(cmi_hdl_t hdl, int banknum, uint64_t status,
20c794b39650d115e17a15983b6b82e46238cf45gavinm uint64_t addr, uint64_t misc, void *mslogout)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi{
20c794b39650d115e17a15983b6b82e46238cf45gavinm ao_ms_data_t *ao = cms_hdl_getcmsdata(hdl);
20c794b39650d115e17a15983b6b82e46238cf45gavinm uint32_t rev = ao->ao_ms_shared->aos_chiprev;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi const ao_error_disp_t *aed;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
20c794b39650d115e17a15983b6b82e46238cf45gavinm for (aed = ao_error_disp[banknum]; aed->aed_stat_mask != 0; aed++) {
20c794b39650d115e17a15983b6b82e46238cf45gavinm if (ao_disp_match_one(aed, status, rev, banknum))
20c794b39650d115e17a15983b6b82e46238cf45gavinm return ((cms_cookie_t)aed);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi }
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
20c794b39650d115e17a15983b6b82e46238cf45gavinm return (NULL);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi}
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
20c794b39650d115e17a15983b6b82e46238cf45gavinm/*ARGSUSED*/
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindivoid
20c794b39650d115e17a15983b6b82e46238cf45gavinmao_ms_ereport_class(cmi_hdl_t hdl, cms_cookie_t mscookie,
20c794b39650d115e17a15983b6b82e46238cf45gavinm const char **cpuclsp, const char **leafclsp)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi{
20c794b39650d115e17a15983b6b82e46238cf45gavinm const ao_error_disp_t *aed = mscookie;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
20c794b39650d115e17a15983b6b82e46238cf45gavinm if (aed != NULL) {
20c794b39650d115e17a15983b6b82e46238cf45gavinm *cpuclsp = FM_EREPORT_CPU_AMD;
20c794b39650d115e17a15983b6b82e46238cf45gavinm *leafclsp = aed->aed_class;
20c794b39650d115e17a15983b6b82e46238cf45gavinm }
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi}
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
20c794b39650d115e17a15983b6b82e46238cf45gavinmstatic int
20c794b39650d115e17a15983b6b82e46238cf45gavinmao_chip_once(ao_ms_data_t *ao, enum ao_cfgonce_bitnum what)
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm{
20c794b39650d115e17a15983b6b82e46238cf45gavinm return (atomic_set_long_excl(&ao->ao_ms_shared->aos_cfgonce,
20c794b39650d115e17a15983b6b82e46238cf45gavinm what) == 0 ? B_TRUE : B_FALSE);
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm}
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm/*
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm * This knob exists in case any platform has a problem with our default
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm * policy of disabling any interrupt registered in the NB MC4_MISC
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm * register. Setting this may cause Solaris and external entities
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm * who also have an interest in this register to argue over available
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm * telemetry (so setting it is generally not recommended).
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm */
8a40a695ee676a322b094e9afe5375567bfb51e3gavinmint ao_nb_cfg_mc4misc_noseize = 0;
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm/*
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm * The BIOS may have setup to receive SMI on counter overflow. It may also
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm * have locked various fields or made them read-only. We will clear any
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm * SMI request and leave the register locked. We will also clear the
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm * counter and enable counting - while we don't use the counter it is nice
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm * to have it enabled for verification and debug work.
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm */
8a40a695ee676a322b094e9afe5375567bfb51e3gavinmstatic void
20c794b39650d115e17a15983b6b82e46238cf45gavinmnb_mcamisc_init(cmi_hdl_t hdl, ao_ms_data_t *ao, uint32_t rev)
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm{
20c794b39650d115e17a15983b6b82e46238cf45gavinm uint64_t val, nval;
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm if (!X86_CHIPREV_MATCH(rev, AO_F_REVS_FG))
20c794b39650d115e17a15983b6b82e46238cf45gavinm return;
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm if (cmi_hdl_rdmsr(hdl, AMD_MSR_NB_MISC, &val) != CMI_SUCCESS)
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm return;
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm ao->ao_ms_shared->aos_bcfg_nb_misc = val;
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm if (ao_nb_cfg_mc4misc_noseize)
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm return; /* stash BIOS value, but no changes */
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm /*
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm * The Valid bit tells us whether the CtrP bit is defined; if it
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm * is the CtrP bit tells us whether an ErrCount field is present.
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm * If not then there is nothing for us to do.
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm */
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm if (!(val & AMD_NB_MISC_VALID) || !(val & AMD_NB_MISC_CTRP))
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm return;
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm nval = val;
20c794b39650d115e17a15983b6b82e46238cf45gavinm nval |= AMD_NB_MISC_CNTEN; /* enable ECC error counting */
20c794b39650d115e17a15983b6b82e46238cf45gavinm nval &= ~AMD_NB_MISC_ERRCOUNT_MASK; /* clear ErrCount */
20c794b39650d115e17a15983b6b82e46238cf45gavinm nval &= ~AMD_NB_MISC_OVRFLW; /* clear Ovrflw */
20c794b39650d115e17a15983b6b82e46238cf45gavinm nval &= ~AMD_NB_MISC_INTTYPE_MASK; /* no interrupt on overflow */
20c794b39650d115e17a15983b6b82e46238cf45gavinm nval |= AMD_NB_MISC_LOCKED;
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm if (nval != val) {
20c794b39650d115e17a15983b6b82e46238cf45gavinm uint64_t locked = val & AMD_NB_MISC_LOCKED;
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm if (locked)
20c794b39650d115e17a15983b6b82e46238cf45gavinm ao_bankstatus_prewrite(hdl, ao);
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm (void) cmi_hdl_wrmsr(hdl, AMD_MSR_NB_MISC, nval);
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm if (locked)
20c794b39650d115e17a15983b6b82e46238cf45gavinm ao_bankstatus_postwrite(hdl, ao);
20c794b39650d115e17a15983b6b82e46238cf45gavinm }
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi}
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi/*
bb86c3425be684b7eaa9e875ec2740b39d444ec8gavinm * NorthBridge (NB) MCA Configuration.
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm *
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm * We add and remove bits from the BIOS-configured value, rather than
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm * writing an absolute value. The variables ao_nb_cfg_{add,remove}_cmn and
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm * ap_nb_cfg_{add,remove}_revFG are available for modification via kmdb
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm * and /etc/system. The revision-specific adds and removes are applied
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm * after the common changes, and one write is made to the config register.
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm * These are not intended for watchdog configuration via these variables -
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm * use the watchdog policy below.
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm */
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm/*
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm * Bits to be added to the NB configuration register - all revs.
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm */
8a40a695ee676a322b094e9afe5375567bfb51e3gavinmuint32_t ao_nb_cfg_add_cmn = AMD_NB_CFG_ADD_CMN;
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm/*
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm * Bits to be cleared from the NB configuration register - all revs.
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm */
8a40a695ee676a322b094e9afe5375567bfb51e3gavinmuint32_t ao_nb_cfg_remove_cmn = AMD_NB_CFG_REMOVE_CMN;
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm/*
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm * Bits to be added to the NB configuration register - revs F and G.
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi */
8a40a695ee676a322b094e9afe5375567bfb51e3gavinmuint32_t ao_nb_cfg_add_revFG = AMD_NB_CFG_ADD_REV_FG;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi/*
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm * Bits to be cleared from the NB configuration register - revs F and G.
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi */
8a40a695ee676a322b094e9afe5375567bfb51e3gavinmuint32_t ao_nb_cfg_remove_revFG = AMD_NB_CFG_REMOVE_REV_FG;
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm
8a40a695ee676a322b094e9afe5375567bfb51e3gavinmstruct ao_nb_cfg {
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm uint32_t cfg_revmask;
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm uint32_t *cfg_add_p;
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm uint32_t *cfg_remove_p;
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm};
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm
8a40a695ee676a322b094e9afe5375567bfb51e3gavinmstatic const struct ao_nb_cfg ao_cfg_extra[] = {
20c794b39650d115e17a15983b6b82e46238cf45gavinm { AO_F_REVS_FG, &ao_nb_cfg_add_revFG, &ao_nb_cfg_remove_revFG },
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm { X86_CHIPREV_UNKNOWN, NULL, NULL }
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm};
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi/*
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * Bits to be used if we configure the NorthBridge (NB) Watchdog. The watchdog
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * triggers a machine check exception when no response to an NB system access
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm * occurs within a specified time interval.
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi */
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindiuint32_t ao_nb_cfg_wdog =
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi AMD_NB_CFG_WDOGTMRCNTSEL_4095 |
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi AMD_NB_CFG_WDOGTMRBASESEL_1MS;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm/*
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm * The default watchdog policy is to enable it (at the above rate) if it
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm * is disabled; if it is enabled then we leave it enabled at the rate
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm * chosen by the BIOS.
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm */
8a40a695ee676a322b094e9afe5375567bfb51e3gavinmenum {
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm AO_NB_WDOG_LEAVEALONE, /* Don't touch watchdog config */
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm AO_NB_WDOG_DISABLE, /* Always disable watchdog */
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm AO_NB_WDOG_ENABLE_IF_DISABLED, /* If disabled, enable at our rate */
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm AO_NB_WDOG_ENABLE_FORCE_RATE /* Enable and set our rate */
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm} ao_nb_watchdog_policy = AO_NB_WDOG_ENABLE_IF_DISABLED;
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindistatic void
20c794b39650d115e17a15983b6b82e46238cf45gavinmao_nb_cfg(ao_ms_data_t *ao, uint32_t rev)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi{
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm const struct ao_nb_cfg *nbcp = &ao_cfg_extra[0];
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe uint_t chipid = pg_plat_hw_instance_id(CPU, PGHW_CHIP);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi uint32_t val;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi /*
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * Read the NorthBridge (NB) configuration register in PCI space,
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * modify the settings accordingly, and store the new value back.
20c794b39650d115e17a15983b6b82e46238cf45gavinm * Note that the stashed BIOS config value aos_bcfg_nb_cfg is used
20c794b39650d115e17a15983b6b82e46238cf45gavinm * in ereport payload population to determine ECC syndrome type for
20c794b39650d115e17a15983b6b82e46238cf45gavinm * memory errors.
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi */
20c794b39650d115e17a15983b6b82e46238cf45gavinm ao->ao_ms_shared->aos_bcfg_nb_cfg = val =
bb86c3425be684b7eaa9e875ec2740b39d444ec8gavinm ao_pcicfg_read(chipid, MC_FUNC_MISCCTL, MC_CTL_REG_NBCFG);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm switch (ao_nb_watchdog_policy) {
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm case AO_NB_WDOG_LEAVEALONE:
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm break;
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm case AO_NB_WDOG_DISABLE:
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm val &= ~AMD_NB_CFG_WDOGTMRBASESEL_MASK;
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm val &= ~AMD_NB_CFG_WDOGTMRCNTSEL_MASK;
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm val |= AMD_NB_CFG_WDOGTMRDIS;
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm break;
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm default:
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm cmn_err(CE_NOTE, "ao_nb_watchdog_policy=%d unrecognised, "
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm "using default policy", ao_nb_watchdog_policy);
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm /*FALLTHRU*/
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm case AO_NB_WDOG_ENABLE_IF_DISABLED:
25f476773dea2a0ee593dcf662a38d5f02487196gavinm if (!(val & AMD_NB_CFG_WDOGTMRDIS))
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm break; /* if enabled leave rate intact */
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm /*FALLTHRU*/
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm case AO_NB_WDOG_ENABLE_FORCE_RATE:
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi val &= ~AMD_NB_CFG_WDOGTMRBASESEL_MASK;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi val &= ~AMD_NB_CFG_WDOGTMRCNTSEL_MASK;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi val &= ~AMD_NB_CFG_WDOGTMRDIS;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi val |= ao_nb_cfg_wdog;
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm break;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi }
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm /*
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm * Now apply bit adds and removes, first those common to all revs
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm * and then the revision-specific ones.
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm */
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm val &= ~ao_nb_cfg_remove_cmn;
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm val |= ao_nb_cfg_add_cmn;
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm while (nbcp->cfg_revmask != X86_CHIPREV_UNKNOWN) {
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm if (X86_CHIPREV_MATCH(rev, nbcp->cfg_revmask)) {
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm val &= ~(*nbcp->cfg_remove_p);
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm val |= *nbcp->cfg_add_p;
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm }
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm nbcp++;
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm }
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
bb86c3425be684b7eaa9e875ec2740b39d444ec8gavinm ao_pcicfg_write(chipid, MC_FUNC_MISCCTL, MC_CTL_REG_NBCFG, val);
bb86c3425be684b7eaa9e875ec2740b39d444ec8gavinm}
bb86c3425be684b7eaa9e875ec2740b39d444ec8gavinm
bb86c3425be684b7eaa9e875ec2740b39d444ec8gavinmstatic void
20c794b39650d115e17a15983b6b82e46238cf45gavinmao_dram_cfg(ao_ms_data_t *ao, uint32_t rev)
bb86c3425be684b7eaa9e875ec2740b39d444ec8gavinm{
bb86c3425be684b7eaa9e875ec2740b39d444ec8gavinm uint_t chipid = pg_plat_hw_instance_id(CPU, PGHW_CHIP);
bb86c3425be684b7eaa9e875ec2740b39d444ec8gavinm union mcreg_dramcfg_lo dcfglo;
bb86c3425be684b7eaa9e875ec2740b39d444ec8gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm ao->ao_ms_shared->aos_bcfg_dcfg_lo = MCREG_VAL32(&dcfglo) =
bb86c3425be684b7eaa9e875ec2740b39d444ec8gavinm ao_pcicfg_read(chipid, MC_FUNC_DRAMCTL, MC_DC_REG_DRAMCFGLO);
20c794b39650d115e17a15983b6b82e46238cf45gavinm ao->ao_ms_shared->aos_bcfg_dcfg_hi =
bb86c3425be684b7eaa9e875ec2740b39d444ec8gavinm ao_pcicfg_read(chipid, MC_FUNC_DRAMCTL, MC_DC_REG_DRAMCFGHI);
bb86c3425be684b7eaa9e875ec2740b39d444ec8gavinm
bb86c3425be684b7eaa9e875ec2740b39d444ec8gavinm#ifdef OPTERON_ERRATUM_172
20c794b39650d115e17a15983b6b82e46238cf45gavinm if (X86_CHIPREV_MATCH(rev, AO_F_REVS_FG) &&
20c794b39650d115e17a15983b6b82e46238cf45gavinm MCREG_FIELD_F_revFG(&dcfglo, ParEn)) {
20c794b39650d115e17a15983b6b82e46238cf45gavinm MCREG_FIELD_F_revFG(&dcfglo, ParEn) = 0;
bb86c3425be684b7eaa9e875ec2740b39d444ec8gavinm ao_pcicfg_write(chipid, MC_FUNC_DRAMCTL, MC_DC_REG_DRAMCFGLO,
bb86c3425be684b7eaa9e875ec2740b39d444ec8gavinm MCREG_VAL32(&dcfglo));
bb86c3425be684b7eaa9e875ec2740b39d444ec8gavinm }
bb86c3425be684b7eaa9e875ec2740b39d444ec8gavinm#endif
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi}
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm/*
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm * This knob exists in case any platform has a problem with our default
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm * policy of disabling any interrupt registered in the online spare
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm * control register. Setting this may cause Solaris and external entities
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm * who also have an interest in this register to argue over available
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm * telemetry (so setting it is generally not recommended).
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm */
8a40a695ee676a322b094e9afe5375567bfb51e3gavinmint ao_nb_cfg_sparectl_noseize = 0;
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm/*
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm * Setup the online spare control register (revs F and G). We disable
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm * any interrupt registered by the BIOS and zero all error counts.
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm */
8a40a695ee676a322b094e9afe5375567bfb51e3gavinmstatic void
20c794b39650d115e17a15983b6b82e46238cf45gavinmao_sparectl_cfg(ao_ms_data_t *ao)
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm{
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe uint_t chipid = pg_plat_hw_instance_id(CPU, PGHW_CHIP);
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm union mcreg_sparectl sparectl;
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm int chan, cs;
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm ao->ao_ms_shared->aos_bcfg_nb_sparectl = MCREG_VAL32(&sparectl) =
bb86c3425be684b7eaa9e875ec2740b39d444ec8gavinm ao_pcicfg_read(chipid, MC_FUNC_MISCCTL, MC_CTL_REG_SPARECTL);
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm if (ao_nb_cfg_sparectl_noseize)
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm return; /* stash BIOS value, but no changes */
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm /*
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm * If the BIOS has requested SMI interrupt type for ECC count
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm * overflow for a chip-select or channel force those off.
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm */
20c794b39650d115e17a15983b6b82e46238cf45gavinm MCREG_FIELD_F_revFG(&sparectl, EccErrInt) = 0;
20c794b39650d115e17a15983b6b82e46238cf45gavinm MCREG_FIELD_F_revFG(&sparectl, SwapDoneInt) = 0;
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm /*
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm * Zero EccErrCnt and write this back to all chan/cs combinations.
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm */
20c794b39650d115e17a15983b6b82e46238cf45gavinm MCREG_FIELD_F_revFG(&sparectl, EccErrCntWrEn) = 1;
20c794b39650d115e17a15983b6b82e46238cf45gavinm MCREG_FIELD_F_revFG(&sparectl, EccErrCnt) = 0;
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm for (chan = 0; chan < MC_CHIP_NDRAMCHAN; chan++) {
20c794b39650d115e17a15983b6b82e46238cf45gavinm MCREG_FIELD_F_revFG(&sparectl, EccErrCntDramChan) = chan;
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm for (cs = 0; cs < MC_CHIP_NCS; cs++) {
20c794b39650d115e17a15983b6b82e46238cf45gavinm MCREG_FIELD_F_revFG(&sparectl, EccErrCntDramCs) = cs;
bb86c3425be684b7eaa9e875ec2740b39d444ec8gavinm ao_pcicfg_write(chipid, MC_FUNC_MISCCTL,
bb86c3425be684b7eaa9e875ec2740b39d444ec8gavinm MC_CTL_REG_SPARECTL, MCREG_VAL32(&sparectl));
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm }
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm }
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm}
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinmint ao_forgive_uc = 0; /* For test/debug only */
20c794b39650d115e17a15983b6b82e46238cf45gavinmint ao_forgive_pcc = 0; /* For test/debug only */
20c794b39650d115e17a15983b6b82e46238cf45gavinmint ao_fake_poison = 0; /* For test/debug only */
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinmuint32_t
20c794b39650d115e17a15983b6b82e46238cf45gavinmao_ms_error_action(cmi_hdl_t hdl, int ismc, int banknum,
20c794b39650d115e17a15983b6b82e46238cf45gavinm uint64_t status, uint64_t addr, uint64_t misc, void *mslogout)
20c794b39650d115e17a15983b6b82e46238cf45gavinm{
20c794b39650d115e17a15983b6b82e46238cf45gavinm const ao_error_disp_t *aed;
20c794b39650d115e17a15983b6b82e46238cf45gavinm uint32_t retval = 0;
20c794b39650d115e17a15983b6b82e46238cf45gavinm uint8_t when;
20c794b39650d115e17a15983b6b82e46238cf45gavinm int en;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
20c794b39650d115e17a15983b6b82e46238cf45gavinm if (ao_forgive_uc)
20c794b39650d115e17a15983b6b82e46238cf45gavinm retval |= CMS_ERRSCOPE_CLEARED_UC;
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm if (ao_forgive_pcc)
20c794b39650d115e17a15983b6b82e46238cf45gavinm retval |= CMS_ERRSCOPE_CURCONTEXT_OK;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
20c794b39650d115e17a15983b6b82e46238cf45gavinm if (ao_fake_poison && status & MSR_MC_STATUS_UC)
20c794b39650d115e17a15983b6b82e46238cf45gavinm retval |= CMS_ERRSCOPE_POISONED;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
20c794b39650d115e17a15983b6b82e46238cf45gavinm if (retval)
20c794b39650d115e17a15983b6b82e46238cf45gavinm return (retval);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
20c794b39650d115e17a15983b6b82e46238cf45gavinm aed = ao_ms_disp_match(hdl, banknum, status, addr, misc, mslogout);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi /*
20c794b39650d115e17a15983b6b82e46238cf45gavinm * If we do not recognise the error let the cpu module apply
20c794b39650d115e17a15983b6b82e46238cf45gavinm * the generic criteria to decide how to react.
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi */
20c794b39650d115e17a15983b6b82e46238cf45gavinm if (aed == NULL)
20c794b39650d115e17a15983b6b82e46238cf45gavinm return (0);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
20c794b39650d115e17a15983b6b82e46238cf45gavinm en = (status & MSR_MC_STATUS_EN) != 0;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
20c794b39650d115e17a15983b6b82e46238cf45gavinm if ((when = aed->aed_panic_when) == AO_AED_PANIC_NEVER)
20c794b39650d115e17a15983b6b82e46238cf45gavinm retval |= CMS_ERRSCOPE_IGNORE_ERR;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
20c794b39650d115e17a15983b6b82e46238cf45gavinm if ((when & AO_AED_PANIC_ALWAYS) ||
20c794b39650d115e17a15983b6b82e46238cf45gavinm ((when & AO_AED_PANIC_IFMCE) && (en || ismc)))
20c794b39650d115e17a15983b6b82e46238cf45gavinm retval |= CMS_ERRSCOPE_FORCE_FATAL;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
20c794b39650d115e17a15983b6b82e46238cf45gavinm /*
20c794b39650d115e17a15983b6b82e46238cf45gavinm * The original AMD implementation would panic on a machine check
20c794b39650d115e17a15983b6b82e46238cf45gavinm * (not a poll) if the status overflow bit was set, with an
20c794b39650d115e17a15983b6b82e46238cf45gavinm * exception for the case of rev F or later with an NB error
20c794b39650d115e17a15983b6b82e46238cf45gavinm * indicating CECC. This came from the perception that the
20c794b39650d115e17a15983b6b82e46238cf45gavinm * overflow bit was not correctly managed on rev E and earlier, for
20c794b39650d115e17a15983b6b82e46238cf45gavinm * example that repeated correctable memeory errors did not set
20c794b39650d115e17a15983b6b82e46238cf45gavinm * OVER but somehow clear CECC.
20c794b39650d115e17a15983b6b82e46238cf45gavinm *
20c794b39650d115e17a15983b6b82e46238cf45gavinm * We will leave the generic support to evaluate overflow errors
20c794b39650d115e17a15983b6b82e46238cf45gavinm * and decide to panic on their individual merits, e.g., if PCC
20c794b39650d115e17a15983b6b82e46238cf45gavinm * is set and so on. The AMD docs do say (as Intel does) that
20c794b39650d115e17a15983b6b82e46238cf45gavinm * the status information is *all* from the higher-priority
20c794b39650d115e17a15983b6b82e46238cf45gavinm * error in the case of an overflow, so it is at least as serious
20c794b39650d115e17a15983b6b82e46238cf45gavinm * as the original and we can decide panic etc based on it.
20c794b39650d115e17a15983b6b82e46238cf45gavinm */
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
20c794b39650d115e17a15983b6b82e46238cf45gavinm return (retval);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi}
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
20c794b39650d115e17a15983b6b82e46238cf45gavinm/*
20c794b39650d115e17a15983b6b82e46238cf45gavinm * Will need to change for family 0x10
20c794b39650d115e17a15983b6b82e46238cf45gavinm */
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindistatic uint_t
20c794b39650d115e17a15983b6b82e46238cf45gavinmao_ereport_synd(ao_ms_data_t *ao, uint64_t status, uint_t *typep,
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm int is_nb)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi{
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if (is_nb) {
20c794b39650d115e17a15983b6b82e46238cf45gavinm if (ao->ao_ms_shared->aos_bcfg_nb_cfg &
20c794b39650d115e17a15983b6b82e46238cf45gavinm AMD_NB_CFG_CHIPKILLECCEN) {
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi *typep = AMD_SYNDTYPE_CHIPKILL;
20c794b39650d115e17a15983b6b82e46238cf45gavinm return (AMD_NB_STAT_CKSYND(status));
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi } else {
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi *typep = AMD_SYNDTYPE_ECC;
20c794b39650d115e17a15983b6b82e46238cf45gavinm return (AMD_BANK_SYND(status));
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi }
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi } else {
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi *typep = AMD_SYNDTYPE_ECC;
20c794b39650d115e17a15983b6b82e46238cf45gavinm return (AMD_BANK_SYND(status));
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi }
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi}
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
20c794b39650d115e17a15983b6b82e46238cf45gavinmstatic nvlist_t *
20c794b39650d115e17a15983b6b82e46238cf45gavinmao_ereport_create_resource_elem(nv_alloc_t *nva, mc_unum_t *unump, int dimmnum)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi{
20c794b39650d115e17a15983b6b82e46238cf45gavinm nvlist_t *nvl, *snvl;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
20c794b39650d115e17a15983b6b82e46238cf45gavinm if ((nvl = fm_nvlist_create(nva)) == NULL) /* freed by caller */
20c794b39650d115e17a15983b6b82e46238cf45gavinm return (NULL);
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm if ((snvl = fm_nvlist_create(nva)) == NULL) {
20c794b39650d115e17a15983b6b82e46238cf45gavinm fm_nvlist_destroy(nvl, nva ? FM_NVA_RETAIN : FM_NVA_FREE);
20c794b39650d115e17a15983b6b82e46238cf45gavinm return (NULL);
20c794b39650d115e17a15983b6b82e46238cf45gavinm }
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi (void) nvlist_add_uint64(snvl, FM_FMRI_HC_SPECIFIC_OFFSET,
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi unump->unum_offset);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
20c794b39650d115e17a15983b6b82e46238cf45gavinm fm_fmri_hc_set(nvl, FM_HC_SCHEME_VERSION, NULL, snvl, 5,
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi "motherboard", unump->unum_board,
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi "chip", unump->unum_chip,
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi "memory-controller", unump->unum_mc,
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm "dimm", unump->unum_dimms[dimmnum],
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm "rank", unump->unum_rank);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
52d60c845b4569ed1f136c204372e7e5a3535239gavinm fm_nvlist_destroy(snvl, nva ? FM_NVA_RETAIN : FM_NVA_FREE);
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm return (nvl);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi}
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindistatic void
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindiao_ereport_add_resource(nvlist_t *payload, nv_alloc_t *nva, mc_unum_t *unump)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi{
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi nvlist_t *elems[MC_UNUM_NDIMM];
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi int nelems = 0;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi int i;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi for (i = 0; i < MC_UNUM_NDIMM; i++) {
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm if (unump->unum_dimms[i] == MC_INVALNUM)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi break;
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm if ((elems[nelems] = ao_ereport_create_resource_elem(nva,
20c794b39650d115e17a15983b6b82e46238cf45gavinm unump, i)) == NULL)
20c794b39650d115e17a15983b6b82e46238cf45gavinm break;
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm nelems++;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi }
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
20c794b39650d115e17a15983b6b82e46238cf45gavinm if (nelems == 0)
20c794b39650d115e17a15983b6b82e46238cf45gavinm return;
20c794b39650d115e17a15983b6b82e46238cf45gavinm
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RESOURCE,
fab5495c079caeadf22a46365446644b7b077f5bgavinm DATA_TYPE_NVLIST_ARRAY, nelems, elems, NULL);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi for (i = 0; i < nelems; i++)
52d60c845b4569ed1f136c204372e7e5a3535239gavinm fm_nvlist_destroy(elems[i], nva ? FM_NVA_RETAIN : FM_NVA_FREE);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi}
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
20c794b39650d115e17a15983b6b82e46238cf45gavinm/*ARGSUSED*/
20c794b39650d115e17a15983b6b82e46238cf45gavinmvoid
20c794b39650d115e17a15983b6b82e46238cf45gavinmao_ms_ereport_add_logout(cmi_hdl_t hdl, nvlist_t *ereport,
20c794b39650d115e17a15983b6b82e46238cf45gavinm nv_alloc_t *nva, int banknum, uint64_t status, uint64_t addr,
20c794b39650d115e17a15983b6b82e46238cf45gavinm uint64_t misc, void *mslogout, cms_cookie_t mscookie)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi{
20c794b39650d115e17a15983b6b82e46238cf45gavinm ao_ms_data_t *ao = cms_hdl_getcmsdata(hdl);
20c794b39650d115e17a15983b6b82e46238cf45gavinm const ao_error_disp_t *aed = mscookie;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi uint_t synd, syndtype;
20c794b39650d115e17a15983b6b82e46238cf45gavinm uint64_t members;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
20c794b39650d115e17a15983b6b82e46238cf45gavinm if (aed == NULL)
20c794b39650d115e17a15983b6b82e46238cf45gavinm return;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
20c794b39650d115e17a15983b6b82e46238cf45gavinm members = aed->aed_ereport_members;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
20c794b39650d115e17a15983b6b82e46238cf45gavinm synd = ao_ereport_synd(ao, status, &syndtype,
20c794b39650d115e17a15983b6b82e46238cf45gavinm banknum == AMD_MCA_BANK_NB);
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if (members & FM_EREPORT_PAYLOAD_FLAG_SYND) {
20c794b39650d115e17a15983b6b82e46238cf45gavinm fm_payload_set(ereport, FM_EREPORT_PAYLOAD_NAME_SYND,
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi DATA_TYPE_UINT16, synd, NULL);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi }
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if (members & FM_EREPORT_PAYLOAD_FLAG_SYND_TYPE) {
20c794b39650d115e17a15983b6b82e46238cf45gavinm fm_payload_set(ereport, FM_EREPORT_PAYLOAD_NAME_SYND_TYPE,
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi DATA_TYPE_STRING, (syndtype == AMD_SYNDTYPE_CHIPKILL ?
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi "C" : "E"), NULL);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi }
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if (members & FM_EREPORT_PAYLOAD_FLAG_RESOURCE) {
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi mc_unum_t unum;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
20c794b39650d115e17a15983b6b82e46238cf45gavinm if (((aed->aed_flags & AO_AED_FLAGS_ADDRTYPE) ==
20c794b39650d115e17a15983b6b82e46238cf45gavinm AO_AED_F_PHYSICAL) && (status & MSR_MC_STATUS_ADDRV) &&
20c794b39650d115e17a15983b6b82e46238cf45gavinm cmi_mc_patounum(addr, aed->aed_addrvalid_hi,
20c794b39650d115e17a15983b6b82e46238cf45gavinm aed->aed_addrvalid_lo, synd, syndtype, &unum) ==
20c794b39650d115e17a15983b6b82e46238cf45gavinm CMI_SUCCESS)
20c794b39650d115e17a15983b6b82e46238cf45gavinm ao_ereport_add_resource(ereport, nva, &unum);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi }
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi}
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
20c794b39650d115e17a15983b6b82e46238cf45gavinm/*ARGSUSED*/
20c794b39650d115e17a15983b6b82e46238cf45gavinmboolean_t
20c794b39650d115e17a15983b6b82e46238cf45gavinmao_ms_ereport_includestack(cmi_hdl_t hdl, cms_cookie_t mscookie)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi{
20c794b39650d115e17a15983b6b82e46238cf45gavinm const ao_error_disp_t *aed = mscookie;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
20c794b39650d115e17a15983b6b82e46238cf45gavinm if (aed == NULL)
20c794b39650d115e17a15983b6b82e46238cf45gavinm return (0);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
20c794b39650d115e17a15983b6b82e46238cf45gavinm return ((aed->aed_ereport_members &
20c794b39650d115e17a15983b6b82e46238cf45gavinm FM_EREPORT_PAYLOAD_FLAG_STACK) != 0);
20c794b39650d115e17a15983b6b82e46238cf45gavinm}
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
20c794b39650d115e17a15983b6b82e46238cf45gavinmcms_errno_t
20c794b39650d115e17a15983b6b82e46238cf45gavinmao_ms_msrinject(cmi_hdl_t hdl, uint_t msr, uint64_t val)
20c794b39650d115e17a15983b6b82e46238cf45gavinm{
20c794b39650d115e17a15983b6b82e46238cf45gavinm ao_ms_data_t *ao = cms_hdl_getcmsdata(hdl);
20c794b39650d115e17a15983b6b82e46238cf45gavinm cms_errno_t rv = CMSERR_BADMSRWRITE;
52d60c845b4569ed1f136c204372e7e5a3535239gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm ao_bankstatus_prewrite(hdl, ao);
20c794b39650d115e17a15983b6b82e46238cf45gavinm if (cmi_hdl_wrmsr(hdl, msr, val) == CMI_SUCCESS)
20c794b39650d115e17a15983b6b82e46238cf45gavinm rv = CMS_SUCCESS;
20c794b39650d115e17a15983b6b82e46238cf45gavinm ao_bankstatus_postwrite(hdl, ao);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
20c794b39650d115e17a15983b6b82e46238cf45gavinm return (rv);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi}
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi/*ARGSUSED*/
20c794b39650d115e17a15983b6b82e46238cf45gavinmuint64_t
20c794b39650d115e17a15983b6b82e46238cf45gavinmao_ms_mcgctl_val(cmi_hdl_t hdl, int nbanks, uint64_t def)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi{
20c794b39650d115e17a15983b6b82e46238cf45gavinm return ((1ULL << nbanks) - 1);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi}
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
20c794b39650d115e17a15983b6b82e46238cf45gavinmboolean_t
20c794b39650d115e17a15983b6b82e46238cf45gavinmao_ms_bankctl_skipinit(cmi_hdl_t hdl, int banknum)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi{
20c794b39650d115e17a15983b6b82e46238cf45gavinm ao_ms_data_t *ao = cms_hdl_getcmsdata(hdl);
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm if (banknum != AMD_MCA_BANK_NB)
20c794b39650d115e17a15983b6b82e46238cf45gavinm return (B_FALSE);
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm return (ao_chip_once(ao, AO_CFGONCE_NBMCA));
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi}
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
20c794b39650d115e17a15983b6b82e46238cf45gavinmuint64_t
20c794b39650d115e17a15983b6b82e46238cf45gavinmao_ms_bankctl_val(cmi_hdl_t hdl, int banknum, uint64_t def)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi{
20c794b39650d115e17a15983b6b82e46238cf45gavinm ao_ms_data_t *ao = cms_hdl_getcmsdata(hdl);
20c794b39650d115e17a15983b6b82e46238cf45gavinm const struct ao_ctl_init *extrap;
20c794b39650d115e17a15983b6b82e46238cf45gavinm const ao_bank_cfg_t *bankcfg;
20c794b39650d115e17a15983b6b82e46238cf45gavinm uint64_t mcictl;
20c794b39650d115e17a15983b6b82e46238cf45gavinm uint32_t rev = ao->ao_ms_shared->aos_chiprev;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
20c794b39650d115e17a15983b6b82e46238cf45gavinm if (banknum >= sizeof (ao_bank_cfgs) / sizeof (ao_bank_cfgs[0]))
20c794b39650d115e17a15983b6b82e46238cf45gavinm return (def);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
20c794b39650d115e17a15983b6b82e46238cf45gavinm bankcfg = &ao_bank_cfgs[banknum];
20c794b39650d115e17a15983b6b82e46238cf45gavinm extrap = bankcfg->bank_ctl_init_extra;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
20c794b39650d115e17a15983b6b82e46238cf45gavinm mcictl = bankcfg->bank_ctl_init_cmn;
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm while (extrap != NULL && extrap->ctl_revmask != X86_CHIPREV_UNKNOWN) {
20c794b39650d115e17a15983b6b82e46238cf45gavinm if (X86_CHIPREV_MATCH(rev, extrap->ctl_revmask))
20c794b39650d115e17a15983b6b82e46238cf45gavinm mcictl |= extrap->ctl_bits;
20c794b39650d115e17a15983b6b82e46238cf45gavinm extrap++;
20c794b39650d115e17a15983b6b82e46238cf45gavinm }
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm return (mcictl);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi}
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindivoid
20c794b39650d115e17a15983b6b82e46238cf45gavinmao_bankstatus_prewrite(cmi_hdl_t hdl, ao_ms_data_t *ao)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi{
20c794b39650d115e17a15983b6b82e46238cf45gavinm uint64_t hwcr;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
20c794b39650d115e17a15983b6b82e46238cf45gavinm if (cmi_hdl_rdmsr(hdl, MSR_AMD_HWCR, &hwcr) != CMI_SUCCESS)
20c794b39650d115e17a15983b6b82e46238cf45gavinm return;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
20c794b39650d115e17a15983b6b82e46238cf45gavinm ao->ao_ms_hwcr_val = hwcr;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
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}
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinmvoid
20c794b39650d115e17a15983b6b82e46238cf45gavinmao_bankstatus_postwrite(cmi_hdl_t hdl, ao_ms_data_t *ao)
20c794b39650d115e17a15983b6b82e46238cf45gavinm{
20c794b39650d115e17a15983b6b82e46238cf45gavinm uint64_t hwcr = ao->ao_ms_hwcr_val;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
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}
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinmvoid
20c794b39650d115e17a15983b6b82e46238cf45gavinmao_ms_mca_init(cmi_hdl_t hdl, int nbanks)
20c794b39650d115e17a15983b6b82e46238cf45gavinm{
20c794b39650d115e17a15983b6b82e46238cf45gavinm ao_ms_data_t *ao = cms_hdl_getcmsdata(hdl);
20c794b39650d115e17a15983b6b82e46238cf45gavinm uint32_t rev = ao->ao_ms_shared->aos_chiprev;
20c794b39650d115e17a15983b6b82e46238cf45gavinm ao_ms_mca_t *mca = &ao->ao_ms_mca;
20c794b39650d115e17a15983b6b82e46238cf45gavinm uint64_t *maskp;
20c794b39650d115e17a15983b6b82e46238cf45gavinm int i;
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm maskp = mca->ao_mca_bios_cfg.bcfg_bank_mask = kmem_zalloc(nbanks *
20c794b39650d115e17a15983b6b82e46238cf45gavinm sizeof (uint64_t), KM_SLEEP);
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm /*
20c794b39650d115e17a15983b6b82e46238cf45gavinm * Read the bank ctl mask MSRs, but only as many as we know
20c794b39650d115e17a15983b6b82e46238cf45gavinm * certainly exist - don't calculate the register address.
20c794b39650d115e17a15983b6b82e46238cf45gavinm * Also initialize the MCi_MISC register where required.
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm */
20c794b39650d115e17a15983b6b82e46238cf45gavinm for (i = 0; i < MIN(nbanks, ao_nbanks); i++) {
20c794b39650d115e17a15983b6b82e46238cf45gavinm (void) cmi_hdl_rdmsr(hdl, ao_bank_cfgs[i].bank_ctl_mask,
20c794b39650d115e17a15983b6b82e46238cf45gavinm maskp++);
20c794b39650d115e17a15983b6b82e46238cf45gavinm if (ao_bank_cfgs[i].bank_misc_initfunc != NULL)
20c794b39650d115e17a15983b6b82e46238cf45gavinm ao_bank_cfgs[i].bank_misc_initfunc(hdl, ao, rev);
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm }
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm if (ao_chip_once(ao, AO_CFGONCE_NBCFG) == B_TRUE) {
20c794b39650d115e17a15983b6b82e46238cf45gavinm ao_nb_cfg(ao, rev);
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm if (X86_CHIPREV_MATCH(rev, AO_F_REVS_FG))
20c794b39650d115e17a15983b6b82e46238cf45gavinm ao_sparectl_cfg(ao);
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm }
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
20c794b39650d115e17a15983b6b82e46238cf45gavinm if (ao_chip_once(ao, AO_CFGONCE_DRAMCFG) == B_TRUE)
20c794b39650d115e17a15983b6b82e46238cf45gavinm ao_dram_cfg(ao, rev);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
20c794b39650d115e17a15983b6b82e46238cf45gavinm ao_chip_scrubber_enable(hdl, ao);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi}
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
bc946ef3d51a883d2aa15b39f2d8b03a119e26casethg/*
bc946ef3d51a883d2aa15b39f2d8b03a119e26casethg * Note that although this cpu module is loaded before the PSMs are
bc946ef3d51a883d2aa15b39f2d8b03a119e26casethg * loaded (and hence before acpica is loaded), this function is
bc946ef3d51a883d2aa15b39f2d8b03a119e26casethg * called from post_startup(), after PSMs are initialized and acpica
bc946ef3d51a883d2aa15b39f2d8b03a119e26casethg * is loaded.
bc946ef3d51a883d2aa15b39f2d8b03a119e26casethg */
bc946ef3d51a883d2aa15b39f2d8b03a119e26casethgstatic int
bc946ef3d51a883d2aa15b39f2d8b03a119e26casethgao_acpi_find_smicmd(int *asd_port)
bc946ef3d51a883d2aa15b39f2d8b03a119e26casethg{
bc946ef3d51a883d2aa15b39f2d8b03a119e26casethg FADT_DESCRIPTOR *fadt = NULL;
bc946ef3d51a883d2aa15b39f2d8b03a119e26casethg
bc946ef3d51a883d2aa15b39f2d8b03a119e26casethg /*
bc946ef3d51a883d2aa15b39f2d8b03a119e26casethg * AcpiGetFirmwareTable works even if ACPI is disabled, so a failure
bc946ef3d51a883d2aa15b39f2d8b03a119e26casethg * here means we weren't able to retreive a pointer to the FADT.
bc946ef3d51a883d2aa15b39f2d8b03a119e26casethg */
bc946ef3d51a883d2aa15b39f2d8b03a119e26casethg if (AcpiGetFirmwareTable(FADT_SIG, 1, ACPI_LOGICAL_ADDRESSING,
bc946ef3d51a883d2aa15b39f2d8b03a119e26casethg (ACPI_TABLE_HEADER **)&fadt) != AE_OK)
bc946ef3d51a883d2aa15b39f2d8b03a119e26casethg return (-1);
bc946ef3d51a883d2aa15b39f2d8b03a119e26casethg
bc946ef3d51a883d2aa15b39f2d8b03a119e26casethg ASSERT(fadt != NULL);
bc946ef3d51a883d2aa15b39f2d8b03a119e26casethg
bc946ef3d51a883d2aa15b39f2d8b03a119e26casethg *asd_port = fadt->SmiCmd;
bc946ef3d51a883d2aa15b39f2d8b03a119e26casethg return (0);
bc946ef3d51a883d2aa15b39f2d8b03a119e26casethg}
bc946ef3d51a883d2aa15b39f2d8b03a119e26casethg
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi/*ARGSUSED*/
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindivoid
20c794b39650d115e17a15983b6b82e46238cf45gavinmao_ms_post_startup(cmi_hdl_t hdl)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi{
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi const struct ao_smi_disable *asd;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi id_t id;
bc946ef3d51a883d2aa15b39f2d8b03a119e26casethg int rv = -1, asd_port;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi smbios_system_t sy;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi smbios_bios_t sb;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi smbios_info_t si;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi /*
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * Fetch the System and BIOS vendor strings from SMBIOS and see if they
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * match a value in our table. If so, disable SMI error polling. This
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * is grotesque and should be replaced by self-describing vendor-
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * specific SMBIOS data or a specification enhancement instead.
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi */
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if (ao_mca_smi_disable && ksmbios != NULL &&
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi smbios_info_bios(ksmbios, &sb) != SMB_ERR &&
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi (id = smbios_info_system(ksmbios, &sy)) != SMB_ERR &&
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi smbios_info_common(ksmbios, id, &si) != SMB_ERR) {
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi for (asd = ao_smi_disable; asd->asd_sys_vendor != NULL; asd++) {
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if (strncmp(asd->asd_sys_vendor, si.smbi_manufacturer,
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi strlen(asd->asd_sys_vendor)) != 0 ||
4156fc34b973159b0334e05ae5ec19344487bdc0gavinm strncmp(asd->asd_sys_product, si.smbi_product,
4156fc34b973159b0334e05ae5ec19344487bdc0gavinm strlen(asd->asd_sys_product)) != 0 ||
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi strncmp(asd->asd_bios_vendor, sb.smbb_vendor,
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi strlen(asd->asd_bios_vendor)) != 0)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi continue;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
bc946ef3d51a883d2aa15b39f2d8b03a119e26casethg /*
bc946ef3d51a883d2aa15b39f2d8b03a119e26casethg * Look for the SMI_CMD port in the ACPI FADT,
bc946ef3d51a883d2aa15b39f2d8b03a119e26casethg * if the port is 0, this platform doesn't support
bc946ef3d51a883d2aa15b39f2d8b03a119e26casethg * SMM, so there is no SMI error polling to disable.
bc946ef3d51a883d2aa15b39f2d8b03a119e26casethg */
bc946ef3d51a883d2aa15b39f2d8b03a119e26casethg if ((rv = ao_acpi_find_smicmd(&asd_port)) == 0 &&
bc946ef3d51a883d2aa15b39f2d8b03a119e26casethg asd_port != 0) {
bc946ef3d51a883d2aa15b39f2d8b03a119e26casethg cmn_err(CE_CONT, "?SMI polling disabled in "
bc946ef3d51a883d2aa15b39f2d8b03a119e26casethg "favor of Solaris Fault Management for "
bc946ef3d51a883d2aa15b39f2d8b03a119e26casethg "AMD Processors\n");
bc946ef3d51a883d2aa15b39f2d8b03a119e26casethg
a6d65bf44b30c41c72de38d957e1d635f62f8314sethg outb(asd_port, asd->asd_code);
bc946ef3d51a883d2aa15b39f2d8b03a119e26casethg
bc946ef3d51a883d2aa15b39f2d8b03a119e26casethg } else if (rv < 0) {
bc946ef3d51a883d2aa15b39f2d8b03a119e26casethg cmn_err(CE_CONT, "?Solaris Fault Management "
bc946ef3d51a883d2aa15b39f2d8b03a119e26casethg "for AMD Processors could not disable SMI "
bc946ef3d51a883d2aa15b39f2d8b03a119e26casethg "polling because an error occurred while "
bc946ef3d51a883d2aa15b39f2d8b03a119e26casethg "trying to determine the SMI command port "
bc946ef3d51a883d2aa15b39f2d8b03a119e26casethg "from the ACPI FADT table\n");
bc946ef3d51a883d2aa15b39f2d8b03a119e26casethg }
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi break;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi }
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi }
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi}