xref: /illumos-gate/usr/src/uts/intel/sys/mca_x86.h (revision 728f047c)
17aec1d6eScindi /*
27aec1d6eScindi  * CDDL HEADER START
37aec1d6eScindi  *
47aec1d6eScindi  * The contents of this file are subject to the terms of the
520c794b3Sgavinm  * Common Development and Distribution License (the "License").
620c794b3Sgavinm  * You may not use this file except in compliance with the License.
77aec1d6eScindi  *
87aec1d6eScindi  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97aec1d6eScindi  * or http://www.opensolaris.org/os/licensing.
107aec1d6eScindi  * See the License for the specific language governing permissions
117aec1d6eScindi  * and limitations under the License.
127aec1d6eScindi  *
137aec1d6eScindi  * When distributing Covered Code, include this CDDL HEADER in each
147aec1d6eScindi  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157aec1d6eScindi  * If applicable, add the following below this CDDL HEADER, with the
167aec1d6eScindi  * fields enclosed by brackets "[]" replaced with your own identifying
177aec1d6eScindi  * information: Portions Copyright [yyyy] [name of copyright owner]
187aec1d6eScindi  *
197aec1d6eScindi  * CDDL HEADER END
207aec1d6eScindi  *
21e3d60c9bSAdrian Frost  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
227aec1d6eScindi  * Use is subject to license terms.
237aec1d6eScindi  */
247aec1d6eScindi 
257aec1d6eScindi #ifndef _SYS_MCA_X86_H
267aec1d6eScindi #define	_SYS_MCA_X86_H
277aec1d6eScindi 
287aec1d6eScindi /*
297aec1d6eScindi  * Constants for the Memory Check Architecture as implemented on generic x86
307aec1d6eScindi  * CPUs.
317aec1d6eScindi  */
327aec1d6eScindi 
3320c794b3Sgavinm #include <sys/types.h>
3420c794b3Sgavinm #include <sys/isa_defs.h>
3520c794b3Sgavinm 
367aec1d6eScindi #ifdef __cplusplus
377aec1d6eScindi extern "C" {
387aec1d6eScindi #endif
397aec1d6eScindi 
407aec1d6eScindi /*
4120c794b3Sgavinm  * Architectural MSRs from the IA-32 Software Developer's Manual - IA32_MSR_*
427aec1d6eScindi  */
437aec1d6eScindi #define	IA32_MSR_MCG_CAP		0x179
447aec1d6eScindi #define	IA32_MSR_MCG_STATUS		0x17a
457aec1d6eScindi #define	IA32_MSR_MCG_CTL		0x17b
467aec1d6eScindi 
477aec1d6eScindi #define	MCG_CAP_CTL_P			0x00000100ULL
487aec1d6eScindi #define	MCG_CAP_EXT_P			0x00000200ULL
4920c794b3Sgavinm #define	MCG_CAP_TES_P			0x00000800ULL
50*728f047cSAdrian Frost #define	MCG_CAP_CTL2_P			0x00000400ULL
5120c794b3Sgavinm 
5220c794b3Sgavinm #define	MCG_CAP_COUNT_MASK		0x000000ffULL
5320c794b3Sgavinm #define	MCG_CAP_COUNT(cap) ((cap) & MCG_CAP_COUNT_MASK)
5420c794b3Sgavinm 
557aec1d6eScindi #define	MCG_CAP_EXT_CNT_MASK		0x00ff0000ULL
567aec1d6eScindi #define	MCG_CAP_EXT_CNT_SHIFT		16
5720c794b3Sgavinm #define	MCG_CAP_EXT_CNT(cap) \
5820c794b3Sgavinm 	(((cap) & MCG_CAP_EXT_CNT_MASK) >> MCG_CAP_EXT_CNT_SHIFT)
597aec1d6eScindi 
607aec1d6eScindi #define	MCG_STATUS_RIPV			0x01
617aec1d6eScindi #define	MCG_STATUS_EIPV			0x02
627aec1d6eScindi #define	MCG_STATUS_MCIP			0x04
637aec1d6eScindi 
6420c794b3Sgavinm /*
6520c794b3Sgavinm  * There are as many error detector "banks" as indicated by
6620c794b3Sgavinm  * IA32_MSR_MCG_CAP.COUNT.  Each bank has a minimum of 3 associated
6720c794b3Sgavinm  * registers (MCi_CTL, MCi_STATUS, and MCi_ADDR) and some banks
6820c794b3Sgavinm  * may implement a fourth (MCi_MISC) which should only be read
6920c794b3Sgavinm  * when MCi_STATUS.MISCV indicates that it exists and has valid data.
7020c794b3Sgavinm  *
7120c794b3Sgavinm  * The first bank features at MSR offsets 0x400 to 0x403, the next at
7220c794b3Sgavinm  * 0x404 to 0x407, and so on.  Current processors implement up to 6
7320c794b3Sgavinm  * banks (sixth one at 0x414 to 0x417).
7420c794b3Sgavinm  *
7520c794b3Sgavinm  * It is, sadly, not the case that the i'th set of 4 registers starting
7620c794b3Sgavinm  * at 0x400 corresponds to MCi_{CTL,STATUS,ADDR,MISC} - for some Intel
7720c794b3Sgavinm  * processors, for example, the order is 0/1/2/4/3.  Nonetheless, we can
7820c794b3Sgavinm  * still iterate through the banks and read all telemetry - there'll just
7920c794b3Sgavinm  * be some potential confusion as to which processor unit a bank is
8020c794b3Sgavinm  * associated with.  Error reports should seek to disambiguate.
8120c794b3Sgavinm  *
8220c794b3Sgavinm  * IA32_MSR_MC(i, which) calculates the MSR address for th i'th bank
8320c794b3Sgavinm  * of registers (not for MCi_*, as above) and one of CTL, STATUS, ADDR, MISC
8420c794b3Sgavinm  */
8520c794b3Sgavinm 
8620c794b3Sgavinm #define	_IA32_MSR_MC0_CTL		0x400ULL /* first/base reg */
8720c794b3Sgavinm #define	_IA32_MSR_OFFSET_CTL		0x0	/* offset within a bank */
8820c794b3Sgavinm #define	_IA32_MSR_OFFSET_STATUS		0x1	/* offset within a bank */
8920c794b3Sgavinm #define	_IA32_MSR_OFFSET_ADDR		0x2	/* offset within a bank */
9020c794b3Sgavinm #define	_IA32_MSR_OFFSET_MISC		0x3	/* offset within a bank */
9120c794b3Sgavinm 
92*728f047cSAdrian Frost #define	_IA32_MSR_MC0_CTL2		0x280ULL /* first MCi_CTL2 reg */
9320c794b3Sgavinm 
9420c794b3Sgavinm #define	IA32_MSR_MC(i, which) \
9520c794b3Sgavinm 	(_IA32_MSR_MC0_CTL + (i) * 4 + _IA32_MSR_OFFSET_##which)
9620c794b3Sgavinm 
97*728f047cSAdrian Frost #define	IA32_MSR_MC_CTL2(i)	(_IA32_MSR_MC0_CTL2 + (i))
98e3d60c9bSAdrian Frost 
9920c794b3Sgavinm /*
10020c794b3Sgavinm  * IA32_MSR_MCG_CAP.MCG_EXT_P indicates that a processor implements
10120c794b3Sgavinm  * a set of extended machine-check registers starting at MSR 0x180;
10220c794b3Sgavinm  * when that is set, IA32_MSR_MCG_CAP.MCG_EXT_CNT indicates how
10320c794b3Sgavinm  * many of these extended registers (addresses 0x180, 0x181, ...)
10420c794b3Sgavinm  * are present.  Which registers are present depends on whether support
10520c794b3Sgavinm  * for 64-bit architecture is present.
10620c794b3Sgavinm  */
1077aec1d6eScindi 
10820c794b3Sgavinm #define	_IA32_MCG_RAX			0x180ULL /* first/base extended reg */
1097aec1d6eScindi 
11020c794b3Sgavinm #define	IA32_MSR_EXT(i)	(_IA32_MCG_RAX + (i))
1117aec1d6eScindi 
11220c794b3Sgavinm #ifdef _BIT_FIELDS_LTOH
11320c794b3Sgavinm typedef union mca_x86_mcistatus {
11420c794b3Sgavinm 	uint64_t _val64;
11520c794b3Sgavinm 	struct {
11620c794b3Sgavinm 		/*
11720c794b3Sgavinm 		 * Lower 32 bits of MCi_STATUS
11820c794b3Sgavinm 		 */
11920c794b3Sgavinm 		struct {
12020c794b3Sgavinm 			uint32_t _errcode:16;		/* <15:0> */
12120c794b3Sgavinm 			uint32_t _ms_errcode:16;	/* <31:16> */
12220c794b3Sgavinm 		} _mcis_lo;
12320c794b3Sgavinm 		/*
12420c794b3Sgavinm 		 * Upper 32 bits of MCi_STATUS
12520c794b3Sgavinm 		 */
12620c794b3Sgavinm 		union {
12720c794b3Sgavinm 			/*
12820c794b3Sgavinm 			 * If IA32_MCG_CAP.MCG_TES_P is set then <54:53>
12920c794b3Sgavinm 			 * and <56:55> are architectural.
13020c794b3Sgavinm 			 */
13120c794b3Sgavinm 			struct {
13220c794b3Sgavinm 				uint32_t _otherinfo:21;		/* <52:32> */
13320c794b3Sgavinm 				uint32_t _tbes:2;		/* <54:53> */
13420c794b3Sgavinm 				uint32_t _reserved:2;		/* <56:55> */
13520c794b3Sgavinm 				uint32_t _pcc:1;		/* <57> */
13620c794b3Sgavinm 				uint32_t _addrv:1;		/* <58> */
13720c794b3Sgavinm 				uint32_t _miscv:1;		/* <59> */
13820c794b3Sgavinm 				uint32_t _en:1;			/* <60> */
13920c794b3Sgavinm 				uint32_t _uc:1;			/* <61> */
14020c794b3Sgavinm 				uint32_t _over:1;		/* <62> */
14120c794b3Sgavinm 				uint32_t _val:1;		/* <63> */
14220c794b3Sgavinm 			} _mcis_hi_tes_p;
14320c794b3Sgavinm 			/*
14420c794b3Sgavinm 			 * If IA32_MCG_CAP.MCG_TES_P is clear then <56:53>
14520c794b3Sgavinm 			 * are model-specific.
14620c794b3Sgavinm 			 */
14720c794b3Sgavinm 			struct {
14820c794b3Sgavinm 				uint32_t _otherinfo:25;		/* <56:32> */
14920c794b3Sgavinm 				uint32_t _pcc:1;		/* <57> */
15020c794b3Sgavinm 				uint32_t _addrv:1;		/* <58> */
15120c794b3Sgavinm 				uint32_t _miscv:1;		/* <59> */
15220c794b3Sgavinm 				uint32_t _en:1;			/* <60> */
15320c794b3Sgavinm 				uint32_t _uc:1;			/* <61> */
15420c794b3Sgavinm 				uint32_t _over:1;		/* <62> */
15520c794b3Sgavinm 				uint32_t _val:1;		/* <63> */
15620c794b3Sgavinm 			} _mcis_hi_tes_np;
15720c794b3Sgavinm 		} _mcis_hi;
15820c794b3Sgavinm 	} _mcis_hilo;
15920c794b3Sgavinm } mca_x86_mcistatus_t;
16020c794b3Sgavinm 
16120c794b3Sgavinm #define	mcistatus_errcode	_mcis_hilo._mcis_lo._errcode
16220c794b3Sgavinm #define	mcistatus_mserrcode	_mcis_hilo._mcis_lo._ms_errcode
16320c794b3Sgavinm #define	mcistatus_pcc	_mcis_hilo._mcis_hi._mcis_hi_tes_np._pcc
16420c794b3Sgavinm #define	mcistatus_addrv	_mcis_hilo._mcis_hi._mcis_hi_tes_np._addrv
16520c794b3Sgavinm #define	mcistatus_miscv	_mcis_hilo._mcis_hi._mcis_hi_tes_np._miscv
16620c794b3Sgavinm #define	mcistatus_en	_mcis_hilo._mcis_hi._mcis_hi_tes_np._en
16720c794b3Sgavinm #define	mcistatus_uc	_mcis_hilo._mcis_hi._mcis_hi_tes_np._uc
16820c794b3Sgavinm #define	mcistatus_over	_mcis_hilo._mcis_hi._mcis_hi_tes_np._over
16920c794b3Sgavinm #define	mcistatus_val	_mcis_hilo._mcis_hi._mcis_hi_tes_np._val
17020c794b3Sgavinm 
17120c794b3Sgavinm /*
17220c794b3Sgavinm  * The consumer must check for TES_P before using these.
17320c794b3Sgavinm  */
17420c794b3Sgavinm #define	mcistatus_tbes	_mcis_hilo._mcis_hi._mcis_hi_tes_p._tbes
17520c794b3Sgavinm #define	mcistatus_reserved \
17620c794b3Sgavinm 	_mcis_hilo._mcis_hi._mcis_hi_tes_p._reserved
17720c794b3Sgavinm #define	mcistatus_otherinfo_tes_p \
17820c794b3Sgavinm 	_mcis_hilo._mcis_hi._mcis_hi_tes_p._otherinfo
17920c794b3Sgavinm #define	mcistatus_otherinfo_tes_np \
18020c794b3Sgavinm 	_mcis_hilo._mcis_hi._mcis_hi_tes_np._otherinfo
18120c794b3Sgavinm 
18220c794b3Sgavinm #endif /* _BIT_FIELDS_LTOH */
1837aec1d6eScindi 
1847aec1d6eScindi #define	MSR_MC_STATUS_VAL		0x8000000000000000ULL
18520c794b3Sgavinm #define	MSR_MC_STATUS_OVER		0x4000000000000000ULL
1867aec1d6eScindi #define	MSR_MC_STATUS_UC		0x2000000000000000ULL
1877aec1d6eScindi #define	MSR_MC_STATUS_EN		0x1000000000000000ULL
1887aec1d6eScindi #define	MSR_MC_STATUS_MISCV		0x0800000000000000ULL
1897aec1d6eScindi #define	MSR_MC_STATUS_ADDRV		0x0400000000000000ULL
1907aec1d6eScindi #define	MSR_MC_STATUS_PCC		0x0200000000000000ULL
19120c794b3Sgavinm #define	MSR_MC_STATUS_RESERVED_MASK	0x0180000000000000ULL
19220c794b3Sgavinm #define	MSR_MC_STATUS_TBES_MASK		0x0060000000000000ULL
19320c794b3Sgavinm #define	MSR_MC_STATUS_TBES_SHIFT	53
194e3d60c9bSAdrian Frost #define	MSR_MC_STATUS_CEC_MASK		0x001fffc000000000ULL
195e3d60c9bSAdrian Frost #define	MSR_MC_STATUS_CEC_SHIFT	38
1967aec1d6eScindi #define	MSR_MC_STATUS_MSERR_MASK	0x00000000ffff0000ULL
1977aec1d6eScindi #define	MSR_MC_STATUS_MSERR_SHIFT	16
1987aec1d6eScindi #define	MSR_MC_STATUS_MCAERR_MASK	0x000000000000ffffULL
1997aec1d6eScindi 
200*728f047cSAdrian Frost #define	MSR_MC_CTL2_EN			0x0000000040000000ULL
201*728f047cSAdrian Frost #define	MSR_MC_CTL2_THRESHOLD_MASK	0x0000000000007fffULL
202*728f047cSAdrian Frost #define	MSR_MC_CTL2_THRESHOLD_OVERFLOW	0x0000000000004000ULL
203e3d60c9bSAdrian Frost 
2047aec1d6eScindi /*
20520c794b3Sgavinm  * Macros to extract error code and model-specific error code.
20620c794b3Sgavinm  */
20720c794b3Sgavinm #define	MCAX86_ERRCODE(stat)		((stat) & MSR_MC_STATUS_MCAERR_MASK)
20820c794b3Sgavinm #define	MCAX86_MSERRCODE(stat) \
20920c794b3Sgavinm 	(((stat) & MSR_MC_STATUS_MSERR_MASK) >> MSR_MC_STATUS_MSERR_SHIFT)
21020c794b3Sgavinm 
21120c794b3Sgavinm /*
21220c794b3Sgavinm  * Macro to extract threshold based error state (if MCG_CAP.TES_P)
2137aec1d6eScindi  */
21420c794b3Sgavinm #define	MCAX86_TBES_VALUE(stat) \
21520c794b3Sgavinm 	(((stat) & MSR_MC_STATUS_TBES_MASK) >> MSR_MC_STATUS_TBES_SHIFT)
21620c794b3Sgavinm 
21720c794b3Sgavinm /*
21820c794b3Sgavinm  * Bit definitions for the architectural error code.
21920c794b3Sgavinm  */
22020c794b3Sgavinm 
22120c794b3Sgavinm #define	MCAX86_ERRCODE_TT_MASK		0x000c
22220c794b3Sgavinm #define	MCAX86_ERRCODE_TT_SHIFT		2
22320c794b3Sgavinm #define	MCAX86_ERRCODE_TT_INSTR		0x0
22420c794b3Sgavinm #define	MCAX86_ERRCODE_TT_DATA		0x1
22520c794b3Sgavinm #define	MCAX86_ERRCODE_TT_GEN		0x2
22620c794b3Sgavinm #define	MCAX86_ERRCODE_TT(code) \
22720c794b3Sgavinm 	(((code) & MCAX86_ERRCODE_TT_MASK) >> MCAX86_ERRCODE_TT_SHIFT)
22820c794b3Sgavinm 
22920c794b3Sgavinm #define	MCAX86_ERRCODE_LL_MASK		0x0003
23020c794b3Sgavinm #define	MCAX86_ERRCODE_LL_SHIFT		0
23120c794b3Sgavinm #define	MCAX86_ERRCODE_LL_L0		0x0
23220c794b3Sgavinm #define	MCAX86_ERRCODE_LL_L1		0x1
23320c794b3Sgavinm #define	MCAX86_ERRCODE_LL_L2		0x2
23420c794b3Sgavinm #define	MCAX86_ERRCODE_LL_LG		0x3
23520c794b3Sgavinm #define	MCAX86_ERRCODE_LL(code) \
23620c794b3Sgavinm 	((code) & MCAX86_ERRCODE_LL_MASK)
23720c794b3Sgavinm 
23820c794b3Sgavinm #define	MCAX86_ERRCODE_RRRR_MASK	0x00f0
23920c794b3Sgavinm #define	MCAX86_ERRCODE_RRRR_SHIFT	4
24020c794b3Sgavinm #define	MCAX86_ERRCODE_RRRR_ERR		0x0
24120c794b3Sgavinm #define	MCAX86_ERRCODE_RRRR_RD		0x1
24220c794b3Sgavinm #define	MCAX86_ERRCODE_RRRR_WR		0x2
24320c794b3Sgavinm #define	MCAX86_ERRCODE_RRRR_DRD		0x3
24420c794b3Sgavinm #define	MCAX86_ERRCODE_RRRR_DWR		0x4
24520c794b3Sgavinm #define	MCAX86_ERRCODE_RRRR_IRD		0x5
24620c794b3Sgavinm #define	MCAX86_ERRCODE_RRRR_PREFETCH	0x6
24720c794b3Sgavinm #define	MCAX86_ERRCODE_RRRR_EVICT	0x7
24820c794b3Sgavinm #define	MCAX86_ERRCODE_RRRR_SNOOP	0x8
24920c794b3Sgavinm #define	MCAX86_ERRCODE_RRRR(code) \
25020c794b3Sgavinm 	(((code) & MCAX86_ERRCODE_RRRR_MASK) >> MCAX86_ERRCODE_RRRR_SHIFT)
25120c794b3Sgavinm 
25220c794b3Sgavinm #define	MCAX86_ERRCODE_PP_MASK		0x0600
25320c794b3Sgavinm #define	MCAX86_ERRCODE_PP_SHIFT		9
25420c794b3Sgavinm #define	MCAX86_ERRCODE_PP_SRC		0x0
25520c794b3Sgavinm #define	MCAX86_ERRCODE_PP_RES		0x1
25620c794b3Sgavinm #define	MCAX86_ERRCODE_PP_OBS		0x2
25720c794b3Sgavinm #define	MCAX86_ERRCODE_PP_GEN		0x3
25820c794b3Sgavinm #define	MCAX86_ERRCODE_PP(code) \
25920c794b3Sgavinm 	(((code) & MCAX86_ERRCODE_PP_MASK) >> MCAX86_ERRCODE_PP_SHIFT)
26020c794b3Sgavinm 
26120c794b3Sgavinm #define	MCAX86_ERRCODE_II_MASK		0x000c
26220c794b3Sgavinm #define	MCAX86_ERRCODE_II_SHIFT		2
26320c794b3Sgavinm #define	MCAX86_ERRCODE_II_MEM		0x0
26420c794b3Sgavinm #define	MCAX86_ERRCODE_II_IO		0x2
26520c794b3Sgavinm #define	MCAX86_ERRCODE_II_GEN		0x3
26620c794b3Sgavinm #define	MCAX86_ERRCODE_II(code) \
26720c794b3Sgavinm 	(((code) & MCAX86_ERRCODE_II_MASK) >> MCAX86_ERRCODE_II_SHIFT)
26820c794b3Sgavinm 
26920c794b3Sgavinm #define	MCAX86_ERRCODE_T_MASK		0x0100
27020c794b3Sgavinm #define	MCAX86_ERRCODE_T_SHIFT		8
27120c794b3Sgavinm #define	MCAX86_ERRCODE_T_NONE		0x0
27220c794b3Sgavinm #define	MCAX86_ERRCODE_T_TIMEOUT	0x1
27320c794b3Sgavinm #define	MCAX86_ERRCODE_T(code) \
27420c794b3Sgavinm 	(((code) & MCAX86_ERRCODE_T_MASK) >> MCAX86_ERRCODE_T_SHIFT)
27520c794b3Sgavinm 
276e3d60c9bSAdrian Frost #define	MCAX86_ERRCODE_MMM_MASK		0x0070
277e3d60c9bSAdrian Frost #define	MCAX86_ERRCODE_MMM_SHIFT	4
278e3d60c9bSAdrian Frost #define	MCAX86_ERRCODE_MMM_GEN		0x0
279e3d60c9bSAdrian Frost #define	MCAX86_ERRCODE_MMM_RD		0x1
280e3d60c9bSAdrian Frost #define	MCAX86_ERRCODE_MMM_WR		0x2
281e3d60c9bSAdrian Frost #define	MCAX86_ERRCODE_MMM_ADRCMD	0x3
282e3d60c9bSAdrian Frost #define	MCAX86_ERRCODE_MMM(code) \
283e3d60c9bSAdrian Frost 	(((code) & MCAX86_ERRCODE_MMM_MASK) >> MCAX86_ERRCODE_MMM_SHIFT)
284e3d60c9bSAdrian Frost 
285e3d60c9bSAdrian Frost #define	MCAX86_ERRCODE_CCCC_MASK	0x000f
286e3d60c9bSAdrian Frost #define	MCAX86_ERRCODE_CCCC_SHIFT	0
287e3d60c9bSAdrian Frost #define	MCAX86_ERRCODE_CCCC_CH0		0x0
288e3d60c9bSAdrian Frost #define	MCAX86_ERRCODE_CCCC_CH1		0x1
289e3d60c9bSAdrian Frost #define	MCAX86_ERRCODE_CCCC_CH2		0x2
290e3d60c9bSAdrian Frost #define	MCAX86_ERRCODE_CCCC_CH3		0x3
291e3d60c9bSAdrian Frost #define	MCAX86_ERRCODE_CCCC_CH4		0x4
292e3d60c9bSAdrian Frost #define	MCAX86_ERRCODE_CCCC_CH5		0x5
293e3d60c9bSAdrian Frost #define	MCAX86_ERRCODE_CCCC_CH6		0x6
294e3d60c9bSAdrian Frost #define	MCAX86_ERRCODE_CCCC_CH7		0x7
295e3d60c9bSAdrian Frost #define	MCAX86_ERRCODE_CCCC_CH8		0x8
296e3d60c9bSAdrian Frost #define	MCAX86_ERRCODE_CCCC_CH9		0x9
297e3d60c9bSAdrian Frost #define	MCAX86_ERRCODE_CCCC_CH10	0xa
298e3d60c9bSAdrian Frost #define	MCAX86_ERRCODE_CCCC_CH11	0xb
299e3d60c9bSAdrian Frost #define	MCAX86_ERRCODE_CCCC_CH12	0xc
300e3d60c9bSAdrian Frost #define	MCAX86_ERRCODE_CCCC_CH13	0xd
301e3d60c9bSAdrian Frost #define	MCAX86_ERRCODE_CCCC_CH14	0xe
302e3d60c9bSAdrian Frost #define	MCAX86_ERRCODE_CCCC_GEN		0xf
303e3d60c9bSAdrian Frost #define	MCAX86_ERRCODE_CCCC(code) \
304e3d60c9bSAdrian Frost 	(((code) & MCAX86_ERRCODE_CCCC_MASK) >> MCAX86_ERRCODE_CCCC_SHIFT)
305e3d60c9bSAdrian Frost 
30620c794b3Sgavinm /*
30720c794b3Sgavinm  * Simple error encoding.  MASKON are bits that must be set for a match
30820c794b3Sgavinm  * at the same time bits indicated by MASKOFF are clear.
30920c794b3Sgavinm  */
31020c794b3Sgavinm #define	MCAX86_SIMPLE_UNCLASSIFIED_MASKON		0x0001
31120c794b3Sgavinm #define	MCAX86_SIMPLE_UNCLASSIFIED_MASKOFF		0xfffe
31220c794b3Sgavinm 
31320c794b3Sgavinm #define	MCAX86_SIMPLE_MC_CODE_PARITY_MASKON		0x0002
31420c794b3Sgavinm #define	MCAX86_SIMPLE_MC_CODE_PARITY_MASKOFF		0xfffd
31520c794b3Sgavinm 
31620c794b3Sgavinm #define	MCAX86_SIMPLE_EXTERNAL_MASKON			0x0003
31720c794b3Sgavinm #define	MCAX86_SIMPLE_EXTERNAL_MASKOFF			0xfffc
31820c794b3Sgavinm 
31920c794b3Sgavinm #define	MCAX86_SIMPLE_FRC_MASKON			0x0004
32020c794b3Sgavinm #define	MCAX86_SIMPLE_FRC_MASKOFF			0xfffb
32120c794b3Sgavinm 
322e3d60c9bSAdrian Frost #define	MCAX86_SIMPLE_INTERNAL_PARITY_MASKON		0x0005
323e3d60c9bSAdrian Frost #define	MCAX86_SIMPLE_INTERNAL_PARITY_MASKOFF		0xfffa
324e3d60c9bSAdrian Frost 
32520c794b3Sgavinm #define	MCAX86_SIMPLE_INTERNAL_TIMER_MASKON		0x0400
32620c794b3Sgavinm #define	MCAX86_SIMPLE_INTERNAL_TIMER_MASKOFF		0xfbff
32720c794b3Sgavinm 
32820c794b3Sgavinm #define	MCAX86_SIMPLE_INTERNAL_UNCLASS_MASK_MASKON	0x0400
32920c794b3Sgavinm #define	MCAX86_SIMPLE_INTERNAL_UNCLASS_MASK_MASKOFF	0xf800
33020c794b3Sgavinm #define	MCAX86_SIMPLE_INTERNAL_UNCLASS_VALUE_MASK	0x03ff
33120c794b3Sgavinm 
33220c794b3Sgavinm /*
33320c794b3Sgavinm  * Macros to make an internal unclassified error code, and to test if
33420c794b3Sgavinm  * a given code is internal unclassified.
33520c794b3Sgavinm  */
33620c794b3Sgavinm #define	MCAX86_MKERRCODE_INTERNAL_UNCLASS(val) \
33720c794b3Sgavinm 	(MCAX86_SIMPLE_INTERNAL_UNCLASS_MASK_MASKON | \
33820c794b3Sgavinm 	((val) & MCAX86_SIMPLE_INTERNAL_UNCLASS_VALUE_MASK))
33920c794b3Sgavinm #define	MCAX86_ERRCODE_ISSIMPLE_INTERNAL_UNCLASS(code) \
34020c794b3Sgavinm 	(((code) & MCAX86_SIMPLE_INTERNAL_UNCLASS_MASK_MASKON) == \
34120c794b3Sgavinm 	MCAX86_SIMPLE_INTERNAL_UNCLASS_MASK_MASKON && \
34220c794b3Sgavinm 	((code) & MCAX86_SIMPLE_INTERNAL_UNCLASS_MASK_MASKOFF) == 0 && \
34320c794b3Sgavinm 	((code) & MCAX86_SIMPLE_INTERNAL_UNCLASS_VALUE_MASK) != 0)
34420c794b3Sgavinm 
34520c794b3Sgavinm /*
34620c794b3Sgavinm  * Is the given error code a simple error encoding?
34720c794b3Sgavinm  */
34820c794b3Sgavinm #define	MCAX86_ERRCODE_ISSIMPLE(code) \
34920c794b3Sgavinm 	((code) >= MCAX86_SIMPLE_UNCLASSIFIED_MASKON && \
350e3d60c9bSAdrian Frost 	(code) <= MCAX86_SIMPLE_INTERNAL_PARITY_MASKON || \
35120c794b3Sgavinm 	(code) == MCAX86_SIMPLE_INTERNAL_TIMER_MASKON || \
35220c794b3Sgavinm 	MCAX86_ERRCODE_ISSIMPLE_INTERNAL_UNCLASS(code))
35320c794b3Sgavinm 
35420c794b3Sgavinm /*
35520c794b3Sgavinm  * Compound error encoding.  We always ignore the 'F' bit (which indicates
35620c794b3Sgavinm  * "correction report filtering") in classifying the error type.
35720c794b3Sgavinm  */
35820c794b3Sgavinm #define	MCAX86_COMPOUND_GENERIC_MEMHIER_MASKON		0x000c
35920c794b3Sgavinm #define	MCAX86_COMPOUND_GENERIC_MEMHIER_MASKOFF		0xeff0
36020c794b3Sgavinm 
36120c794b3Sgavinm #define	MCAX86_COMPOUND_TLB_MASKON			0x0010
36220c794b3Sgavinm #define	MCAX86_COMPOUND_TLB_MASKOFF			0xefe0
36320c794b3Sgavinm 
36420c794b3Sgavinm #define	MCAX86_COMPOUND_MEMHIER_MASKON			0x0100
36520c794b3Sgavinm #define	MCAX86_COMPOUND_MEMHIER_MASKOFF			0xee00
36620c794b3Sgavinm 
36720c794b3Sgavinm #define	MCAX86_COMPOUND_BUS_INTERCONNECT_MASKON		0x0800
36820c794b3Sgavinm #define	MCAX86_COMPOUND_BUS_INTERCONNECT_MASKOFF	0xe000
36920c794b3Sgavinm 
370e3d60c9bSAdrian Frost #define	MCAX86_COMPOUND_MEMORY_CONTROLLER_MASKON	0x0080
371e3d60c9bSAdrian Frost #define	MCAX86_COMPOUND_MEMORY_CONTROLLER_MASKOFF	0xff00
372e3d60c9bSAdrian Frost 
37320c794b3Sgavinm /*
37420c794b3Sgavinm  * Macros to make compound error codes and to test for each type.
37520c794b3Sgavinm  */
37620c794b3Sgavinm #define	MCAX86_MKERRCODE_GENERIC_MEMHIER(ll) \
37720c794b3Sgavinm 	(MCAX86_COMPOUND_GENERIC_MEMHIER_MASKON | \
37820c794b3Sgavinm 	((ll) & MCAX86_ERRCODE_LL_MASK))
37920c794b3Sgavinm #define	MCAX86_ERRCODE_ISGENERIC_MEMHIER(code) \
38020c794b3Sgavinm 	(((code) & MCAX86_COMPOUND_GENERIC_MEMHIER_MASKON) == \
38120c794b3Sgavinm 	MCAX86_COMPOUND_GENERIC_MEMHIER_MASKON && \
38220c794b3Sgavinm 	((code) & MCAX86_COMPOUND_GENERIC_MEMHIER_MASKOFF) == 0)
38320c794b3Sgavinm 
38420c794b3Sgavinm #define	MCAX86_MKERRCODE_TLB(tt, ll) \
38520c794b3Sgavinm 	(MCAX86_COMPOUND_TLB_MASKON | \
38620c794b3Sgavinm 	((tt) << MCAX86_ERRCODE_TT_SHIFT & MCAX86_ERRCODE_TT_MASK) | \
38720c794b3Sgavinm 	((ll) & MCAX86_ERRCODE_LL_MASK))
38820c794b3Sgavinm #define	MCAX86_ERRCODE_ISTLB(code) \
38920c794b3Sgavinm 	(((code) & MCAX86_COMPOUND_TLB_MASKON) == \
39020c794b3Sgavinm 	MCAX86_COMPOUND_TLB_MASKON && \
39120c794b3Sgavinm 	((code) & MCAX86_COMPOUND_TLB_MASKOFF) == 0)
39220c794b3Sgavinm 
39320c794b3Sgavinm #define	MCAX86_MKERRCODE_MEMHIER(rrrr, tt, ll) \
39420c794b3Sgavinm 	(MCAX86_COMPOUND_MEMHIER_MASKON | \
39520c794b3Sgavinm 	((rrrr) << MCAX86_ERRCODE_RRRR_SHIFT & MCAX86_ERRCODE_RRRR_MASK) | \
39620c794b3Sgavinm 	((tt) << MCAX86_ERRCODE_TT_SHIFT & MCAX86_ERRCODE_TT_MASK) | \
39720c794b3Sgavinm 	((ll) & MCAX86_ERRCODE_LL_MASK))
39820c794b3Sgavinm #define	MCAX86_ERRCODE_ISMEMHIER(code) \
39920c794b3Sgavinm 	(((code) & MCAX86_COMPOUND_MEMHIER_MASKON) == \
40020c794b3Sgavinm 	MCAX86_COMPOUND_MEMHIER_MASKON && \
40120c794b3Sgavinm 	((code) & MCAX86_COMPOUND_MEMHIER_MASKOFF) == 0)
40220c794b3Sgavinm 
40320c794b3Sgavinm #define	MCAX86_MKERRCODE_BUS_INTERCONNECT(pp, t, rrrr, ii, ll) \
40420c794b3Sgavinm 	(MCAX86_COMPOUND_BUS_INTERCONNECT_MASKON | \
40520c794b3Sgavinm 	((pp) << MCAX86_ERRCODE_PP_SHIFT & MCAX86_ERRCODE_PP_MASK) | \
40620c794b3Sgavinm 	((t) << MCAX86_ERRCODE_T_SHIFT & MCAX86_ERRCODE_T_MASK) | \
40720c794b3Sgavinm 	((rrrr) << MCAX86_ERRCODE_RRRR_SHIFT & MCAX86_ERRCODE_RRRR_MASK) | \
40820c794b3Sgavinm 	((ii) << MCAX86_ERRCODE_II_SHIFT & MCAX86_ERRCODE_II_MASK) | \
40920c794b3Sgavinm 	((ll) & MCAX86_ERRCODE_LL_MASK))
41020c794b3Sgavinm #define	MCAX86_ERRCODE_ISBUS_INTERCONNECT(code) \
41120c794b3Sgavinm 	(((code) & MCAX86_COMPOUND_BUS_INTERCONNECT_MASKON) == \
41220c794b3Sgavinm 	MCAX86_COMPOUND_BUS_INTERCONNECT_MASKON && \
41320c794b3Sgavinm 	((code) & MCAX86_COMPOUND_BUS_INTERCONNECT_MASKOFF) == 0)
41420c794b3Sgavinm 
415e3d60c9bSAdrian Frost #define	MCAX86_MKERRCODE_MEMORY_CONTROLLER (mmm, cccc) \
416e3d60c9bSAdrian Frost 	(MCAX86_COMPOUNT_MEMORY_CONTROLLER_MASKON | \
417e3d60c9bSAdrian Frost 	((mmm) << MCAX86_ERRCODE_MMM_SHIFT & MCAX86_ERRCODE_MMM_MASK) | \
418e3d60c9bSAdrian Frost 	((cccc) << MCAX86_ERRCODE_CCCC_SHIFT & MCAX86_ERRCODE_CCCC_MASK))
419e3d60c9bSAdrian Frost #define	MCAX86_ERRCODE_ISMEMORY_CONTROLLER(code) \
420e3d60c9bSAdrian Frost 	(((code) & MCAX86_COMPOUND_MEMORY_CONTROLLER_MASKON) == \
421e3d60c9bSAdrian Frost 	MCAX86_COMPOUND_MEMORY_CONTROLLER_MASKON && \
422e3d60c9bSAdrian Frost 	((code) & MCAX86_COMPOUND_MEMORY_CONTROLLER_MASKOFF) == 0)
423e3d60c9bSAdrian Frost 
42420c794b3Sgavinm #define	MCAX86_ERRCODE_ISCOMPOUND(code) \
42520c794b3Sgavinm 	(MCAX86_ERRCODE_ISGENERIC_MEMHIER(code) || \
42620c794b3Sgavinm 	MCAX86_ERRCODE_ISTLB(code) || \
427e3d60c9bSAdrian Frost 	MCAX86_ERRCODE_ISMEMHIER(code) || \
428e3d60c9bSAdrian Frost 	MCAX86_ERRCODE_ISBUS_INTERCONNECT(code) || \
429e3d60c9bSAdrian Frost 	MCAX86_ERRCODE_ISMEMORY_CONTROLLER(code))
43020c794b3Sgavinm 
43120c794b3Sgavinm #define	MCAX86_ERRCODE_UNKNOWN(code) \
43220c794b3Sgavinm 	(!MCAX86_ERRCODE_ISSIMPLE(code) && !MCAX86_ERRCODE_ISCOMPOUND(code))
4337aec1d6eScindi 
4347aec1d6eScindi #ifdef __cplusplus
4357aec1d6eScindi }
4367aec1d6eScindi #endif
4377aec1d6eScindi 
4387aec1d6eScindi #endif /* _SYS_MCA_X86_H */
439