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