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
37extern "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
113typedef 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