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 if (!gintel_ms_unconstrained) 67 gintel_error_action_return |= CMS_ERRSCOPE_POISONED; 68 break; 69 default: 70 break; 71 } 72 return (0); 73 } 74 75 /*ARGSUSED*/ 76 uint32_t 77 gintel_error_action(cmi_hdl_t hdl, int ismc, int bank, 78 uint64_t status, uint64_t addr, uint64_t misc, void *mslogout) 79 { 80 if ((status & MSR_MC_STATUS_PCC) == 0) 81 return (gintel_error_action_return); 82 else 83 return (gintel_error_action_return & ~CMS_ERRSCOPE_POISONED); 84 } 85 86 /*ARGSUSED*/ 87 void 88 gintel_ereport_class(cmi_hdl_t hdl, cms_cookie_t mscookie, 89 const char **cpuclsp, const char **leafclsp) 90 { 91 *cpuclsp = FM_EREPORT_CPU_INTEL; 92 } 93 94 cms_api_ver_t _cms_api_version = CMS_API_VERSION_0; 95 96 const cms_ops_t _cms_ops = { 97 gintel_init, /* cms_init */ 98 NULL, /* cms_post_startup */ 99 NULL, /* cms_post_mpstartup */ 100 NULL, /* cms_logout_size */ 101 NULL, /* cms_mcgctl_val */ 102 NULL, /* cms_bankctl_skipinit */ 103 NULL, /* cms_bankctl_val */ 104 NULL, /* cms_bankstatus_skipinit */ 105 NULL, /* cms_bankstatus_val */ 106 NULL, /* cms_mca_init */ 107 NULL, /* cms_poll_ownermask */ 108 NULL, /* cms_bank_logout */ 109 gintel_error_action, /* cms_error_action */ 110 NULL, /* cms_disp_match */ 111 gintel_ereport_class, /* cms_ereport_class */ 112 NULL, /* cms_ereport_detector */ 113 NULL, /* cms_ereport_includestack */ 114 NULL, /* cms_ereport_add_logout */ 115 NULL, /* cms_msrinject */ 116 NULL, /* cms_fini */ 117 }; 118 119 static struct modlcpu modlcpu = { 120 &mod_cpuops, 121 "Generic Intel model-specific MCA" 122 }; 123 124 static struct modlinkage modlinkage = { 125 MODREV_1, 126 (void *)&modlcpu, 127 NULL 128 }; 129 130 int 131 _init(void) 132 { 133 return (mod_install(&modlinkage)); 134 } 135 136 int 137 _info(struct modinfo *modinfop) 138 { 139 return (mod_info(&modlinkage, modinfop)); 140 } 141 142 int 143 _fini(void) 144 { 145 return (mod_remove(&modlinkage)); 146 } 147