1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 /* 30 * Intel model-specific support. Right now all this conists of is 31 * to modify the ereport subclass to produce different ereport classes 32 * so that we can have different diagnosis rules and corresponding faults. 33 */ 34 35 #include <sys/types.h> 36 #include <sys/cmn_err.h> 37 #include <sys/modctl.h> 38 #include <sys/mca_x86.h> 39 #include <sys/cpu_module_ms_impl.h> 40 #include <sys/mc_intel.h> 41 #include <sys/pci_cfgspace.h> 42 43 int gintel_ms_support_disable = 0; 44 int gintel_error_action_return = 0; 45 int gintel_ms_unconstrained = 0; 46 47 /*ARGSUSED*/ 48 int 49 gintel_init(cmi_hdl_t hdl, void **datap) 50 { 51 uint32_t nb_chipset; 52 53 if (gintel_ms_support_disable) 54 return (ENOTSUP); 55 56 if (!(x86_feature & X86_MCA)) 57 return (ENOTSUP); 58 59 nb_chipset = (*pci_getl_func)(0, 0, 0, 0x0); 60 switch (nb_chipset) { 61 case INTEL_NB_7300: 62 case INTEL_NB_5000P: 63 case INTEL_NB_5000X: 64 case INTEL_NB_5000V: 65 case INTEL_NB_5000Z: 66 case INTEL_NB_5400: 67 case INTEL_NB_5400A: 68 case INTEL_NB_5400B: 69 if (!gintel_ms_unconstrained) 70 gintel_error_action_return |= CMS_ERRSCOPE_POISONED; 71 break; 72 default: 73 break; 74 } 75 return (0); 76 } 77 78 /*ARGSUSED*/ 79 uint32_t 80 gintel_error_action(cmi_hdl_t hdl, int ismc, int bank, 81 uint64_t status, uint64_t addr, uint64_t misc, void *mslogout) 82 { 83 if ((status & MSR_MC_STATUS_PCC) == 0) 84 return (gintel_error_action_return); 85 else 86 return (gintel_error_action_return & ~CMS_ERRSCOPE_POISONED); 87 } 88 89 /*ARGSUSED*/ 90 void 91 gintel_ereport_class(cmi_hdl_t hdl, cms_cookie_t mscookie, 92 const char **cpuclsp, const char **leafclsp) 93 { 94 *cpuclsp = FM_EREPORT_CPU_INTEL; 95 } 96 97 cms_api_ver_t _cms_api_version = CMS_API_VERSION_0; 98 99 const cms_ops_t _cms_ops = { 100 gintel_init, /* cms_init */ 101 NULL, /* cms_post_startup */ 102 NULL, /* cms_post_mpstartup */ 103 NULL, /* cms_logout_size */ 104 NULL, /* cms_mcgctl_val */ 105 NULL, /* cms_bankctl_skipinit */ 106 NULL, /* cms_bankctl_val */ 107 NULL, /* cms_bankstatus_skipinit */ 108 NULL, /* cms_bankstatus_val */ 109 NULL, /* cms_mca_init */ 110 NULL, /* cms_poll_ownermask */ 111 NULL, /* cms_bank_logout */ 112 gintel_error_action, /* cms_error_action */ 113 NULL, /* cms_disp_match */ 114 gintel_ereport_class, /* cms_ereport_class */ 115 NULL, /* cms_ereport_detector */ 116 NULL, /* cms_ereport_includestack */ 117 NULL, /* cms_ereport_add_logout */ 118 NULL, /* cms_msrinject */ 119 NULL, /* cms_fini */ 120 }; 121 122 static struct modlcpu modlcpu = { 123 &mod_cpuops, 124 "Generic Intel model-specific MCA" 125 }; 126 127 static struct modlinkage modlinkage = { 128 MODREV_1, 129 (void *)&modlcpu, 130 NULL 131 }; 132 133 int 134 _init(void) 135 { 136 return (mod_install(&modlinkage)); 137 } 138 139 int 140 _info(struct modinfo *modinfop) 141 { 142 return (mod_info(&modlinkage, modinfop)); 143 } 144 145 int 146 _fini(void) 147 { 148 return (mod_remove(&modlinkage)); 149 } 150