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