/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _SYS_MCA_X86_H
#define _SYS_MCA_X86_H
/*
* Constants for the Memory Check Architecture as implemented on generic x86
* CPUs.
*/
#include <sys/isa_defs.h>
#ifdef __cplusplus
extern "C" {
#endif
/*
* Architectural MSRs from the IA-32 Software Developer's Manual - IA32_MSR_*
*/
/*
* There are as many error detector "banks" as indicated by
* IA32_MSR_MCG_CAP.COUNT. Each bank has a minimum of 3 associated
* registers (MCi_CTL, MCi_STATUS, and MCi_ADDR) and some banks
* may implement a fourth (MCi_MISC) which should only be read
* when MCi_STATUS.MISCV indicates that it exists and has valid data.
*
* The first bank features at MSR offsets 0x400 to 0x403, the next at
* 0x404 to 0x407, and so on. Current processors implement up to 6
* banks (sixth one at 0x414 to 0x417).
*
* It is, sadly, not the case that the i'th set of 4 registers starting
* at 0x400 corresponds to MCi_{CTL,STATUS,ADDR,MISC} - for some Intel
* processors, for example, the order is 0/1/2/4/3. Nonetheless, we can
* still iterate through the banks and read all telemetry - there'll just
* be some potential confusion as to which processor unit a bank is
* associated with. Error reports should seek to disambiguate.
*
* IA32_MSR_MC(i, which) calculates the MSR address for th i'th bank
* of registers (not for MCi_*, as above) and one of CTL, STATUS, ADDR, MISC
*/
/*
* IA32_MSR_MCG_CAP.MCG_EXT_P indicates that a processor implements
* a set of extended machine-check registers starting at MSR 0x180;
* when that is set, IA32_MSR_MCG_CAP.MCG_EXT_CNT indicates how
* many of these extended registers (addresses 0x180, 0x181, ...)
* are present. Which registers are present depends on whether support
* for 64-bit architecture is present.
*/
#ifdef _BIT_FIELDS_LTOH
typedef union mca_x86_mcistatus {
struct {
/*
* Lower 32 bits of MCi_STATUS
*/
struct {
} _mcis_lo;
/*
* Upper 32 bits of MCi_STATUS
*/
union {
/*
* If IA32_MCG_CAP.MCG_TES_P is set then <54:53>
* and <56:55> are architectural.
*/
struct {
/*
* If IA32_MCG_CAP.MCG_TES_P is clear then <56:53>
* are model-specific.
*/
struct {
} _mcis_hi;
} _mcis_hilo;
/*
* The consumer must check for TES_P before using these.
*/
#define mcistatus_reserved \
#define mcistatus_otherinfo_tes_p \
#define mcistatus_otherinfo_tes_np \
#endif /* _BIT_FIELDS_LTOH */
/*
* Macros to extract error code and model-specific error code.
*/
/*
* Macro to extract threshold based error state (if MCG_CAP.TES_P)
*/
/*
* Bit definitions for the architectural error code.
*/
#define MCAX86_ERRCODE_LL_SHIFT 0
((code) & MCAX86_ERRCODE_LL_MASK)
#define MCAX86_ERRCODE_CCCC_SHIFT 0
/*
* Simple error encoding. MASKON are bits that must be set for a match
* at the same time bits indicated by MASKOFF are clear.
*/
/*
* Macros to make an internal unclassified error code, and to test if
* a given code is internal unclassified.
*/
(((code) & MCAX86_SIMPLE_INTERNAL_UNCLASS_MASK_MASKON) == \
((code) & MCAX86_SIMPLE_INTERNAL_UNCLASS_MASK_MASKOFF) == 0 && \
((code) & MCAX86_SIMPLE_INTERNAL_UNCLASS_VALUE_MASK) != 0)
/*
* Is the given error code a simple error encoding?
*/
((code) >= MCAX86_SIMPLE_UNCLASSIFIED_MASKON && \
(code) <= MCAX86_SIMPLE_INTERNAL_PARITY_MASKON || \
(code) == MCAX86_SIMPLE_INTERNAL_TIMER_MASKON || \
/*
* Compound error encoding. We always ignore the 'F' bit (which indicates
* "correction report filtering") in classifying the error type.
*/
/*
* Macros to make compound error codes and to test for each type.
*/
((ll) & MCAX86_ERRCODE_LL_MASK))
(((code) & MCAX86_COMPOUND_GENERIC_MEMHIER_MASKON) == \
((code) & MCAX86_COMPOUND_GENERIC_MEMHIER_MASKOFF) == 0)
((ll) & MCAX86_ERRCODE_LL_MASK))
(((code) & MCAX86_COMPOUND_TLB_MASKON) == \
((code) & MCAX86_COMPOUND_TLB_MASKOFF) == 0)
((ll) & MCAX86_ERRCODE_LL_MASK))
(((code) & MCAX86_COMPOUND_MEMHIER_MASKON) == \
((code) & MCAX86_COMPOUND_MEMHIER_MASKOFF) == 0)
((t) << MCAX86_ERRCODE_T_SHIFT & MCAX86_ERRCODE_T_MASK) | \
((ll) & MCAX86_ERRCODE_LL_MASK))
(((code) & MCAX86_COMPOUND_BUS_INTERCONNECT_MASKON) == \
((code) & MCAX86_COMPOUND_BUS_INTERCONNECT_MASKOFF) == 0)
(((code) & MCAX86_COMPOUND_MEMORY_CONTROLLER_MASKON) == \
((code) & MCAX86_COMPOUND_MEMORY_CONTROLLER_MASKOFF) == 0)
MCAX86_ERRCODE_ISTLB(code) || \
MCAX86_ERRCODE_ISMEMHIER(code) || \
#ifdef __cplusplus
}
#endif
#endif /* _SYS_MCA_X86_H */