1 /*
2 * MCA implementation for AMD CPUs
3 * Copyright (c) 2007-2012 Advanced Micro Devices, Inc.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 #ifndef X86_MCA_H
20 #define X86_MCA_H
21
22 #include <public/arch-x86/xen-mca.h>
23
24 /* The MCA/MCE MSRs should not be used anywhere else.
25 * They are cpu family/model specific and are only for use
26 * in terms of machine check handling.
27 * So we define them here rather in <asm/msr.h>.
28 */
29
30
31 /* Bitfield of the MSR_IA32_MCG_CAP register */
32 #define MCG_CAP_COUNT 0x00000000000000ffULL
33 #define MCG_CTL_P (1ULL<<8)
34 #define MCG_EXT_P (1ULL<<9) /* Intel specific */
35 #define MCG_CMCI_P (1ULL<<10) /* Intel specific */
36 #define MCG_TES_P (1ULL<<11) /* Intel specific */
37 #define MCG_EXT_CNT 16 /* Intel specific */
38 #define MCG_SER_P (1ULL<<24) /* Intel specific */
39 #define MCG_LMCE_P (1ULL<<27) /* Intel specific */
40 /* Other bits are reserved */
41
42 /* Bitfield of the MSR_IA32_MCG_STATUS register */
43 #define MCG_STATUS_RIPV 0x0000000000000001ULL
44 #define MCG_STATUS_EIPV 0x0000000000000002ULL
45 #define MCG_STATUS_MCIP 0x0000000000000004ULL
46 #define MCG_STATUS_LMCE 0x0000000000000008ULL /* Intel specific */
47 /* Bits 3-63 are reserved on CPU not supporting LMCE */
48 /* Bits 4-63 are reserved on CPU supporting LMCE */
49
50 /* Bitfield of MSR_IA32_MCG_EXT_CTL register (Intel Specific) */
51 #define MCG_EXT_CTL_LMCE_EN (1ULL<<0)
52 /* Other bits are reserved */
53
54 /* Bitfield of MSR_K8_MCi_STATUS registers */
55 /* MCA error code */
56 #define MCi_STATUS_MCA 0x000000000000ffffULL
57 /* model-specific error code */
58 #define MCi_STATUS_MSEC 0x00000000ffff0000ULL
59 /* Other information */
60 #define MCi_STATUS_OTHER 0x01ffffff00000000ULL
61 /* Action Required flag */
62 #define MCi_STATUS_AR 0x0080000000000000ULL /* Intel specific */
63 /* Signaling flag */
64 #define MCi_STATUS_S 0x0100000000000000ULL /* Intel specific */
65 /* processor context corrupt */
66 #define MCi_STATUS_PCC 0x0200000000000000ULL
67 /* MSR_K8_MCi_ADDR register valid */
68 #define MCi_STATUS_ADDRV 0x0400000000000000ULL
69 /* MSR_K8_MCi_MISC register valid */
70 #define MCi_STATUS_MISCV 0x0800000000000000ULL
71 /* error condition enabled */
72 #define MCi_STATUS_EN 0x1000000000000000ULL
73 /* uncorrected error */
74 #define MCi_STATUS_UC 0x2000000000000000ULL
75 /* status register overflow */
76 #define MCi_STATUS_OVER 0x4000000000000000ULL
77 /* valid */
78 #define MCi_STATUS_VAL 0x8000000000000000ULL
79
80 /* Bitfield of MSi_STATUS_OTHER field */
81 /* reserved bits */
82 #define MCi_STATUS_OTHER_RESERVED1 0x00001fff00000000ULL
83 /* uncorrectable ECC error */
84 #define MCi_STATUS_OTEHR_UC_ECC 0x0000200000000000ULL
85 /* correctable ECC error */
86 #define MCi_STATUS_OTHER_C_ECC 0x0000400000000000ULL
87 /* ECC syndrome of an ECC error */
88 #define MCi_STATUS_OTHER_ECC_SYNDROME 0x007f800000000000ULL
89 /* reserved bits */
90 #define MCi_STATUS_OTHER_RESERVED2 0x0180000000000000ULL
91
92 /* Bitfield of MSR_K8_HWCR register */
93 #define K8_HWCR_MCi_STATUS_WREN (1ULL << 18)
94
95 /*Intel Specific bitfield*/
96 #define MCi_MISC_ADDRMOD_MASK (0x7UL << 6)
97 #define MCi_MISC_PHYSMOD (0x2UL << 6)
98
99 #include <asm/domain.h>
100
101 struct mca_banks
102 {
103 int num;
104 unsigned long *bank_map;
105 };
106
mcabanks_clear(int bit,struct mca_banks * banks)107 static inline void mcabanks_clear(int bit, struct mca_banks *banks)
108 {
109 if (!banks || !banks->bank_map || bit >= banks->num)
110 return ;
111 clear_bit(bit, banks->bank_map);
112 }
113
mcabanks_set(int bit,struct mca_banks * banks)114 static inline void mcabanks_set(int bit, struct mca_banks* banks)
115 {
116 if (!banks || !banks->bank_map || bit >= banks->num)
117 return;
118 set_bit(bit, banks->bank_map);
119 }
120
mcabanks_test(int bit,struct mca_banks * banks)121 static inline int mcabanks_test(int bit, struct mca_banks* banks)
122 {
123 if (!banks || !banks->bank_map || bit >= banks->num)
124 return 0;
125 return test_bit(bit, banks->bank_map);
126 }
127
128 struct mca_banks *mcabanks_alloc(unsigned int nr);
129 void mcabanks_free(struct mca_banks *banks);
130 extern struct mca_banks *mca_allbanks;
131
132 /* Keep bank so that we can get status even if mib is NULL */
133 struct mca_binfo {
134 int bank;
135 struct mcinfo_global *mig;
136 struct mcinfo_bank *mib;
137 struct mc_info *mi;
138 struct cpu_user_regs *regs;
139 };
140
141 enum mce_result
142 {
143 MCER_NOERROR,
144 MCER_RECOVERED,
145 /* Not recovered, but can continue */
146 MCER_CONTINUE,
147 MCER_RESET,
148 };
149
150 struct mca_error_handler
151 {
152 /* Assume corresponding recovery action could be uniquely
153 * identified by mca_code. Otherwise, we might need to have
154 * a seperate function to decode the corresponding actions
155 * for the particular mca error later.
156 */
157 bool (*owned_error)(uint64_t status);
158 void (*recovery_handler)(struct mca_binfo *binfo,
159 enum mce_result *result, const struct cpu_user_regs *regs);
160 };
161
162 /* Global variables */
163 extern bool opt_mce;
164
165 #endif /* X86_MCA_H */
166