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