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 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 22 * Use is subject to license terms. 23 */ 24 25 #ifndef _SYS_MCA_X86_H 26 #define _SYS_MCA_X86_H 27 28 #pragma ident "%Z%%M% %I% %E% SMI" 29 30 /* 31 * Constants for the Memory Check Architecture as implemented on generic x86 32 * CPUs. 33 */ 34 35 #include <sys/types.h> 36 #include <sys/isa_defs.h> 37 38 #ifdef __cplusplus 39 extern "C" { 40 #endif 41 42 /* 43 * Architectural MSRs from the IA-32 Software Developer's Manual - IA32_MSR_* 44 */ 45 #define IA32_MSR_MCG_CAP 0x179 46 #define IA32_MSR_MCG_STATUS 0x17a 47 #define IA32_MSR_MCG_CTL 0x17b 48 49 #define MCG_CAP_CTL_P 0x00000100ULL 50 #define MCG_CAP_EXT_P 0x00000200ULL 51 #define MCG_CAP_TES_P 0x00000800ULL 52 53 #define MCG_CAP_COUNT_MASK 0x000000ffULL 54 #define MCG_CAP_COUNT(cap) ((cap) & MCG_CAP_COUNT_MASK) 55 56 #define MCG_CAP_EXT_CNT_MASK 0x00ff0000ULL 57 #define MCG_CAP_EXT_CNT_SHIFT 16 58 #define MCG_CAP_EXT_CNT(cap) \ 59 (((cap) & MCG_CAP_EXT_CNT_MASK) >> MCG_CAP_EXT_CNT_SHIFT) 60 61 #define MCG_STATUS_RIPV 0x01 62 #define MCG_STATUS_EIPV 0x02 63 #define MCG_STATUS_MCIP 0x04 64 65 /* 66 * There are as many error detector "banks" as indicated by 67 * IA32_MSR_MCG_CAP.COUNT. Each bank has a minimum of 3 associated 68 * registers (MCi_CTL, MCi_STATUS, and MCi_ADDR) and some banks 69 * may implement a fourth (MCi_MISC) which should only be read 70 * when MCi_STATUS.MISCV indicates that it exists and has valid data. 71 * 72 * The first bank features at MSR offsets 0x400 to 0x403, the next at 73 * 0x404 to 0x407, and so on. Current processors implement up to 6 74 * banks (sixth one at 0x414 to 0x417). 75 * 76 * It is, sadly, not the case that the i'th set of 4 registers starting 77 * at 0x400 corresponds to MCi_{CTL,STATUS,ADDR,MISC} - for some Intel 78 * processors, for example, the order is 0/1/2/4/3. Nonetheless, we can 79 * still iterate through the banks and read all telemetry - there'll just 80 * be some potential confusion as to which processor unit a bank is 81 * associated with. Error reports should seek to disambiguate. 82 * 83 * IA32_MSR_MC(i, which) calculates the MSR address for th i'th bank 84 * of registers (not for MCi_*, as above) and one of CTL, STATUS, ADDR, MISC 85 */ 86 87 #define _IA32_MSR_MC0_CTL 0x400ULL /* first/base reg */ 88 #define _IA32_MSR_OFFSET_CTL 0x0 /* offset within a bank */ 89 #define _IA32_MSR_OFFSET_STATUS 0x1 /* offset within a bank */ 90 #define _IA32_MSR_OFFSET_ADDR 0x2 /* offset within a bank */ 91 #define _IA32_MSR_OFFSET_MISC 0x3 /* offset within a bank */ 92 93 94 #define IA32_MSR_MC(i, which) \ 95 (_IA32_MSR_MC0_CTL + (i) * 4 + _IA32_MSR_OFFSET_##which) 96 97 /* 98 * IA32_MSR_MCG_CAP.MCG_EXT_P indicates that a processor implements 99 * a set of extended machine-check registers starting at MSR 0x180; 100 * when that is set, IA32_MSR_MCG_CAP.MCG_EXT_CNT indicates how 101 * many of these extended registers (addresses 0x180, 0x181, ...) 102 * are present. Which registers are present depends on whether support 103 * for 64-bit architecture is present. 104 */ 105 106 #define _IA32_MCG_RAX 0x180ULL /* first/base extended reg */ 107 108 #define IA32_MSR_EXT(i) (_IA32_MCG_RAX + (i)) 109 110 #ifdef _BIT_FIELDS_LTOH 111 typedef union mca_x86_mcistatus { 112 uint64_t _val64; 113 struct { 114 /* 115 * Lower 32 bits of MCi_STATUS 116 */ 117 struct { 118 uint32_t _errcode:16; /* <15:0> */ 119 uint32_t _ms_errcode:16; /* <31:16> */ 120 } _mcis_lo; 121 /* 122 * Upper 32 bits of MCi_STATUS 123 */ 124 union { 125 /* 126 * If IA32_MCG_CAP.MCG_TES_P is set then <54:53> 127 * and <56:55> are architectural. 128 */ 129 struct { 130 uint32_t _otherinfo:21; /* <52:32> */ 131 uint32_t _tbes:2; /* <54:53> */ 132 uint32_t _reserved:2; /* <56:55> */ 133 uint32_t _pcc:1; /* <57> */ 134 uint32_t _addrv:1; /* <58> */ 135 uint32_t _miscv:1; /* <59> */ 136 uint32_t _en:1; /* <60> */ 137 uint32_t _uc:1; /* <61> */ 138 uint32_t _over:1; /* <62> */ 139 uint32_t _val:1; /* <63> */ 140 } _mcis_hi_tes_p; 141 /* 142 * If IA32_MCG_CAP.MCG_TES_P is clear then <56:53> 143 * are model-specific. 144 */ 145 struct { 146 uint32_t _otherinfo:25; /* <56:32> */ 147 uint32_t _pcc:1; /* <57> */ 148 uint32_t _addrv:1; /* <58> */ 149 uint32_t _miscv:1; /* <59> */ 150 uint32_t _en:1; /* <60> */ 151 uint32_t _uc:1; /* <61> */ 152 uint32_t _over:1; /* <62> */ 153 uint32_t _val:1; /* <63> */ 154 } _mcis_hi_tes_np; 155 } _mcis_hi; 156 } _mcis_hilo; 157 } mca_x86_mcistatus_t; 158 159 #define mcistatus_errcode _mcis_hilo._mcis_lo._errcode 160 #define mcistatus_mserrcode _mcis_hilo._mcis_lo._ms_errcode 161 #define mcistatus_pcc _mcis_hilo._mcis_hi._mcis_hi_tes_np._pcc 162 #define mcistatus_addrv _mcis_hilo._mcis_hi._mcis_hi_tes_np._addrv 163 #define mcistatus_miscv _mcis_hilo._mcis_hi._mcis_hi_tes_np._miscv 164 #define mcistatus_en _mcis_hilo._mcis_hi._mcis_hi_tes_np._en 165 #define mcistatus_uc _mcis_hilo._mcis_hi._mcis_hi_tes_np._uc 166 #define mcistatus_over _mcis_hilo._mcis_hi._mcis_hi_tes_np._over 167 #define mcistatus_val _mcis_hilo._mcis_hi._mcis_hi_tes_np._val 168 169 /* 170 * The consumer must check for TES_P before using these. 171 */ 172 #define mcistatus_tbes _mcis_hilo._mcis_hi._mcis_hi_tes_p._tbes 173 #define mcistatus_reserved \ 174 _mcis_hilo._mcis_hi._mcis_hi_tes_p._reserved 175 #define mcistatus_otherinfo_tes_p \ 176 _mcis_hilo._mcis_hi._mcis_hi_tes_p._otherinfo 177 #define mcistatus_otherinfo_tes_np \ 178 _mcis_hilo._mcis_hi._mcis_hi_tes_np._otherinfo 179 180 #endif /* _BIT_FIELDS_LTOH */ 181 182 #define MSR_MC_STATUS_VAL 0x8000000000000000ULL 183 #define MSR_MC_STATUS_OVER 0x4000000000000000ULL 184 #define MSR_MC_STATUS_UC 0x2000000000000000ULL 185 #define MSR_MC_STATUS_EN 0x1000000000000000ULL 186 #define MSR_MC_STATUS_MISCV 0x0800000000000000ULL 187 #define MSR_MC_STATUS_ADDRV 0x0400000000000000ULL 188 #define MSR_MC_STATUS_PCC 0x0200000000000000ULL 189 #define MSR_MC_STATUS_RESERVED_MASK 0x0180000000000000ULL 190 #define MSR_MC_STATUS_TBES_MASK 0x0060000000000000ULL 191 #define MSR_MC_STATUS_TBES_SHIFT 53 192 #define MSR_MC_STATUS_MSERR_MASK 0x00000000ffff0000ULL 193 #define MSR_MC_STATUS_MSERR_SHIFT 16 194 #define MSR_MC_STATUS_MCAERR_MASK 0x000000000000ffffULL 195 196 /* 197 * Macros to extract error code and model-specific error code. 198 */ 199 #define MCAX86_ERRCODE(stat) ((stat) & MSR_MC_STATUS_MCAERR_MASK) 200 #define MCAX86_MSERRCODE(stat) \ 201 (((stat) & MSR_MC_STATUS_MSERR_MASK) >> MSR_MC_STATUS_MSERR_SHIFT) 202 203 /* 204 * Macro to extract threshold based error state (if MCG_CAP.TES_P) 205 */ 206 #define MCAX86_TBES_VALUE(stat) \ 207 (((stat) & MSR_MC_STATUS_TBES_MASK) >> MSR_MC_STATUS_TBES_SHIFT) 208 209 /* 210 * Bit definitions for the architectural error code. 211 */ 212 213 #define MCAX86_ERRCODE_TT_MASK 0x000c 214 #define MCAX86_ERRCODE_TT_SHIFT 2 215 #define MCAX86_ERRCODE_TT_INSTR 0x0 216 #define MCAX86_ERRCODE_TT_DATA 0x1 217 #define MCAX86_ERRCODE_TT_GEN 0x2 218 #define MCAX86_ERRCODE_TT(code) \ 219 (((code) & MCAX86_ERRCODE_TT_MASK) >> MCAX86_ERRCODE_TT_SHIFT) 220 221 #define MCAX86_ERRCODE_LL_MASK 0x0003 222 #define MCAX86_ERRCODE_LL_SHIFT 0 223 #define MCAX86_ERRCODE_LL_L0 0x0 224 #define MCAX86_ERRCODE_LL_L1 0x1 225 #define MCAX86_ERRCODE_LL_L2 0x2 226 #define MCAX86_ERRCODE_LL_LG 0x3 227 #define MCAX86_ERRCODE_LL(code) \ 228 ((code) & MCAX86_ERRCODE_LL_MASK) 229 230 #define MCAX86_ERRCODE_RRRR_MASK 0x00f0 231 #define MCAX86_ERRCODE_RRRR_SHIFT 4 232 #define MCAX86_ERRCODE_RRRR_ERR 0x0 233 #define MCAX86_ERRCODE_RRRR_RD 0x1 234 #define MCAX86_ERRCODE_RRRR_WR 0x2 235 #define MCAX86_ERRCODE_RRRR_DRD 0x3 236 #define MCAX86_ERRCODE_RRRR_DWR 0x4 237 #define MCAX86_ERRCODE_RRRR_IRD 0x5 238 #define MCAX86_ERRCODE_RRRR_PREFETCH 0x6 239 #define MCAX86_ERRCODE_RRRR_EVICT 0x7 240 #define MCAX86_ERRCODE_RRRR_SNOOP 0x8 241 #define MCAX86_ERRCODE_RRRR(code) \ 242 (((code) & MCAX86_ERRCODE_RRRR_MASK) >> MCAX86_ERRCODE_RRRR_SHIFT) 243 244 #define MCAX86_ERRCODE_PP_MASK 0x0600 245 #define MCAX86_ERRCODE_PP_SHIFT 9 246 #define MCAX86_ERRCODE_PP_SRC 0x0 247 #define MCAX86_ERRCODE_PP_RES 0x1 248 #define MCAX86_ERRCODE_PP_OBS 0x2 249 #define MCAX86_ERRCODE_PP_GEN 0x3 250 #define MCAX86_ERRCODE_PP(code) \ 251 (((code) & MCAX86_ERRCODE_PP_MASK) >> MCAX86_ERRCODE_PP_SHIFT) 252 253 #define MCAX86_ERRCODE_II_MASK 0x000c 254 #define MCAX86_ERRCODE_II_SHIFT 2 255 #define MCAX86_ERRCODE_II_MEM 0x0 256 #define MCAX86_ERRCODE_II_IO 0x2 257 #define MCAX86_ERRCODE_II_GEN 0x3 258 #define MCAX86_ERRCODE_II(code) \ 259 (((code) & MCAX86_ERRCODE_II_MASK) >> MCAX86_ERRCODE_II_SHIFT) 260 261 #define MCAX86_ERRCODE_T_MASK 0x0100 262 #define MCAX86_ERRCODE_T_SHIFT 8 263 #define MCAX86_ERRCODE_T_NONE 0x0 264 #define MCAX86_ERRCODE_T_TIMEOUT 0x1 265 #define MCAX86_ERRCODE_T(code) \ 266 (((code) & MCAX86_ERRCODE_T_MASK) >> MCAX86_ERRCODE_T_SHIFT) 267 268 /* 269 * Simple error encoding. MASKON are bits that must be set for a match 270 * at the same time bits indicated by MASKOFF are clear. 271 */ 272 #define MCAX86_SIMPLE_UNCLASSIFIED_MASKON 0x0001 273 #define MCAX86_SIMPLE_UNCLASSIFIED_MASKOFF 0xfffe 274 275 #define MCAX86_SIMPLE_MC_CODE_PARITY_MASKON 0x0002 276 #define MCAX86_SIMPLE_MC_CODE_PARITY_MASKOFF 0xfffd 277 278 #define MCAX86_SIMPLE_EXTERNAL_MASKON 0x0003 279 #define MCAX86_SIMPLE_EXTERNAL_MASKOFF 0xfffc 280 281 #define MCAX86_SIMPLE_FRC_MASKON 0x0004 282 #define MCAX86_SIMPLE_FRC_MASKOFF 0xfffb 283 284 #define MCAX86_SIMPLE_INTERNAL_TIMER_MASKON 0x0400 285 #define MCAX86_SIMPLE_INTERNAL_TIMER_MASKOFF 0xfbff 286 287 #define MCAX86_SIMPLE_INTERNAL_UNCLASS_MASK_MASKON 0x0400 288 #define MCAX86_SIMPLE_INTERNAL_UNCLASS_MASK_MASKOFF 0xf800 289 #define MCAX86_SIMPLE_INTERNAL_UNCLASS_VALUE_MASK 0x03ff 290 291 /* 292 * Macros to make an internal unclassified error code, and to test if 293 * a given code is internal unclassified. 294 */ 295 #define MCAX86_MKERRCODE_INTERNAL_UNCLASS(val) \ 296 (MCAX86_SIMPLE_INTERNAL_UNCLASS_MASK_MASKON | \ 297 ((val) & MCAX86_SIMPLE_INTERNAL_UNCLASS_VALUE_MASK)) 298 #define MCAX86_ERRCODE_ISSIMPLE_INTERNAL_UNCLASS(code) \ 299 (((code) & MCAX86_SIMPLE_INTERNAL_UNCLASS_MASK_MASKON) == \ 300 MCAX86_SIMPLE_INTERNAL_UNCLASS_MASK_MASKON && \ 301 ((code) & MCAX86_SIMPLE_INTERNAL_UNCLASS_MASK_MASKOFF) == 0 && \ 302 ((code) & MCAX86_SIMPLE_INTERNAL_UNCLASS_VALUE_MASK) != 0) 303 304 /* 305 * Is the given error code a simple error encoding? 306 */ 307 #define MCAX86_ERRCODE_ISSIMPLE(code) \ 308 ((code) >= MCAX86_SIMPLE_UNCLASSIFIED_MASKON && \ 309 (code) <= MCAX86_SIMPLE_FRC_MASKON || \ 310 (code) == MCAX86_SIMPLE_INTERNAL_TIMER_MASKON || \ 311 MCAX86_ERRCODE_ISSIMPLE_INTERNAL_UNCLASS(code)) 312 313 /* 314 * Compound error encoding. We always ignore the 'F' bit (which indicates 315 * "correction report filtering") in classifying the error type. 316 */ 317 #define MCAX86_COMPOUND_GENERIC_MEMHIER_MASKON 0x000c 318 #define MCAX86_COMPOUND_GENERIC_MEMHIER_MASKOFF 0xeff0 319 320 #define MCAX86_COMPOUND_TLB_MASKON 0x0010 321 #define MCAX86_COMPOUND_TLB_MASKOFF 0xefe0 322 323 #define MCAX86_COMPOUND_MEMHIER_MASKON 0x0100 324 #define MCAX86_COMPOUND_MEMHIER_MASKOFF 0xee00 325 326 #define MCAX86_COMPOUND_BUS_INTERCONNECT_MASKON 0x0800 327 #define MCAX86_COMPOUND_BUS_INTERCONNECT_MASKOFF 0xe000 328 329 /* 330 * Macros to make compound error codes and to test for each type. 331 */ 332 #define MCAX86_MKERRCODE_GENERIC_MEMHIER(ll) \ 333 (MCAX86_COMPOUND_GENERIC_MEMHIER_MASKON | \ 334 ((ll) & MCAX86_ERRCODE_LL_MASK)) 335 #define MCAX86_ERRCODE_ISGENERIC_MEMHIER(code) \ 336 (((code) & MCAX86_COMPOUND_GENERIC_MEMHIER_MASKON) == \ 337 MCAX86_COMPOUND_GENERIC_MEMHIER_MASKON && \ 338 ((code) & MCAX86_COMPOUND_GENERIC_MEMHIER_MASKOFF) == 0) 339 340 #define MCAX86_MKERRCODE_TLB(tt, ll) \ 341 (MCAX86_COMPOUND_TLB_MASKON | \ 342 ((tt) << MCAX86_ERRCODE_TT_SHIFT & MCAX86_ERRCODE_TT_MASK) | \ 343 ((ll) & MCAX86_ERRCODE_LL_MASK)) 344 #define MCAX86_ERRCODE_ISTLB(code) \ 345 (((code) & MCAX86_COMPOUND_TLB_MASKON) == \ 346 MCAX86_COMPOUND_TLB_MASKON && \ 347 ((code) & MCAX86_COMPOUND_TLB_MASKOFF) == 0) 348 349 #define MCAX86_MKERRCODE_MEMHIER(rrrr, tt, ll) \ 350 (MCAX86_COMPOUND_MEMHIER_MASKON | \ 351 ((rrrr) << MCAX86_ERRCODE_RRRR_SHIFT & MCAX86_ERRCODE_RRRR_MASK) | \ 352 ((tt) << MCAX86_ERRCODE_TT_SHIFT & MCAX86_ERRCODE_TT_MASK) | \ 353 ((ll) & MCAX86_ERRCODE_LL_MASK)) 354 #define MCAX86_ERRCODE_ISMEMHIER(code) \ 355 (((code) & MCAX86_COMPOUND_MEMHIER_MASKON) == \ 356 MCAX86_COMPOUND_MEMHIER_MASKON && \ 357 ((code) & MCAX86_COMPOUND_MEMHIER_MASKOFF) == 0) 358 359 #define MCAX86_MKERRCODE_BUS_INTERCONNECT(pp, t, rrrr, ii, ll) \ 360 (MCAX86_COMPOUND_BUS_INTERCONNECT_MASKON | \ 361 ((pp) << MCAX86_ERRCODE_PP_SHIFT & MCAX86_ERRCODE_PP_MASK) | \ 362 ((t) << MCAX86_ERRCODE_T_SHIFT & MCAX86_ERRCODE_T_MASK) | \ 363 ((rrrr) << MCAX86_ERRCODE_RRRR_SHIFT & MCAX86_ERRCODE_RRRR_MASK) | \ 364 ((ii) << MCAX86_ERRCODE_II_SHIFT & MCAX86_ERRCODE_II_MASK) | \ 365 ((ll) & MCAX86_ERRCODE_LL_MASK)) 366 #define MCAX86_ERRCODE_ISBUS_INTERCONNECT(code) \ 367 (((code) & MCAX86_COMPOUND_BUS_INTERCONNECT_MASKON) == \ 368 MCAX86_COMPOUND_BUS_INTERCONNECT_MASKON && \ 369 ((code) & MCAX86_COMPOUND_BUS_INTERCONNECT_MASKOFF) == 0) 370 371 #define MCAX86_ERRCODE_ISCOMPOUND(code) \ 372 (MCAX86_ERRCODE_ISGENERIC_MEMHIER(code) || \ 373 MCAX86_ERRCODE_ISTLB(code) || \ 374 MCAX86_ERRCODE_ISMEMHIER(code) \ 375 MCAX86_ERRCODE_ISBUS_INTERCONNECT(code)) 376 377 #define MCAX86_ERRCODE_UNKNOWN(code) \ 378 (!MCAX86_ERRCODE_ISSIMPLE(code) && !MCAX86_ERRCODE_ISCOMPOUND(code)) 379 380 #ifdef __cplusplus 381 } 382 #endif 383 384 #endif /* _SYS_MCA_X86_H */ 385