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