aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/edac
diff options
context:
space:
mode:
authorBorislav Petkov <borislav.petkov@amd.com>2010-09-17 13:22:34 -0400
committerBorislav Petkov <borislav.petkov@amd.com>2011-01-07 05:54:14 -0500
commit25a4f8b05917f8137bfff8a3f8c6c8c1ac561208 (patch)
tree8fc91785a6d142c9bf9f72c85df6b4abc234e152 /drivers/edac
parent2be64bfac71378e1aa8c20031a499bd55e391244 (diff)
EDAC, MCE: Add F15h DC MCE decoder
Add a decoder for F15h DC MCEs to support the new types of DC MCEs introduced by the BD microarchitecture. Signed-off-by: Borislav Petkov <borislav.petkov@amd.com>
Diffstat (limited to 'drivers/edac')
-rw-r--r--drivers/edac/mce_amd.c79
-rw-r--r--drivers/edac/mce_amd.h2
2 files changed, 62 insertions, 19 deletions
diff --git a/drivers/edac/mce_amd.c b/drivers/edac/mce_amd.c
index 01853eed2019..12bae3b18e3d 100644
--- a/drivers/edac/mce_amd.c
+++ b/drivers/edac/mce_amd.c
@@ -75,7 +75,7 @@ static const char *f10h_nb_mce_desc[] = {
75 "ECC Error in the Probe Filter directory" 75 "ECC Error in the Probe Filter directory"
76}; 76};
77 77
78static bool f12h_dc_mce(u16 ec) 78static bool f12h_dc_mce(u16 ec, u8 xec)
79{ 79{
80 bool ret = false; 80 bool ret = false;
81 81
@@ -93,7 +93,7 @@ static bool f12h_dc_mce(u16 ec)
93 return ret; 93 return ret;
94} 94}
95 95
96static bool f10h_dc_mce(u16 ec) 96static bool f10h_dc_mce(u16 ec, u8 xec)
97{ 97{
98 u8 r4 = (ec >> 4) & 0xf; 98 u8 r4 = (ec >> 4) & 0xf;
99 u8 ll = ec & 0x3; 99 u8 ll = ec & 0x3;
@@ -102,20 +102,20 @@ static bool f10h_dc_mce(u16 ec)
102 pr_cont("during data scrub.\n"); 102 pr_cont("during data scrub.\n");
103 return true; 103 return true;
104 } 104 }
105 return f12h_dc_mce(ec); 105 return f12h_dc_mce(ec, xec);
106} 106}
107 107
108static bool k8_dc_mce(u16 ec) 108static bool k8_dc_mce(u16 ec, u8 xec)
109{ 109{
110 if (BUS_ERROR(ec)) { 110 if (BUS_ERROR(ec)) {
111 pr_cont("during system linefill.\n"); 111 pr_cont("during system linefill.\n");
112 return true; 112 return true;
113 } 113 }
114 114
115 return f10h_dc_mce(ec); 115 return f10h_dc_mce(ec, xec);
116} 116}
117 117
118static bool f14h_dc_mce(u16 ec) 118static bool f14h_dc_mce(u16 ec, u8 xec)
119{ 119{
120 u8 r4 = (ec >> 4) & 0xf; 120 u8 r4 = (ec >> 4) & 0xf;
121 u8 ll = ec & 0x3; 121 u8 ll = ec & 0x3;
@@ -170,6 +170,54 @@ static bool f14h_dc_mce(u16 ec)
170 return ret; 170 return ret;
171} 171}
172 172
173static bool f15h_dc_mce(u16 ec, u8 xec)
174{
175 bool ret = true;
176
177 if (MEM_ERROR(ec)) {
178
179 switch (xec) {
180 case 0x0:
181 pr_cont("Data Array access error.\n");
182 break;
183
184 case 0x1:
185 pr_cont("UC error during a linefill from L2/NB.\n");
186 break;
187
188 case 0x2:
189 case 0x11:
190 pr_cont("STQ access error.\n");
191 break;
192
193 case 0x3:
194 pr_cont("SCB access error.\n");
195 break;
196
197 case 0x10:
198 pr_cont("Tag error.\n");
199 break;
200
201 case 0x12:
202 pr_cont("LDQ access error.\n");
203 break;
204
205 default:
206 ret = false;
207 }
208 } else if (BUS_ERROR(ec)) {
209
210 if (!xec)
211 pr_cont("during system linefill.\n");
212 else
213 pr_cont(" Internal %s condition.\n",
214 ((xec == 1) ? "livelock" : "deadlock"));
215 } else
216 ret = false;
217
218 return ret;
219}
220
173static void amd_decode_dc_mce(struct mce *m) 221static void amd_decode_dc_mce(struct mce *m)
174{ 222{
175 u16 ec = m->status & 0xffff; 223 u16 ec = m->status & 0xffff;
@@ -183,20 +231,14 @@ static void amd_decode_dc_mce(struct mce *m)
183 231
184 if (tt == TT_DATA) { 232 if (tt == TT_DATA) {
185 pr_cont("%s TLB %s.\n", LL_MSG(ec), 233 pr_cont("%s TLB %s.\n", LL_MSG(ec),
186 (xec ? "multimatch" : "parity error")); 234 ((xec == 2) ? "locked miss"
235 : (xec ? "multimatch" : "parity")));
187 return; 236 return;
188 } 237 }
189 else 238 } else if (fam_ops->dc_mce(ec, xec))
190 goto wrong_dc_mce; 239 ;
191 } 240 else
192 241 pr_emerg(HW_ERR "Corrupted DC MCE info?\n");
193 if (!fam_ops->dc_mce(ec))
194 goto wrong_dc_mce;
195
196 return;
197
198wrong_dc_mce:
199 pr_emerg(HW_ERR "Corrupted DC MCE info?\n");
200} 242}
201 243
202static bool k8_ic_mce(u16 ec) 244static bool k8_ic_mce(u16 ec)
@@ -654,6 +696,7 @@ static int __init mce_amd_init(void)
654 696
655 case 0x15: 697 case 0x15:
656 xec_mask = 0x1f; 698 xec_mask = 0x1f;
699 fam_ops->dc_mce = f15h_dc_mce;
657 break; 700 break;
658 701
659 default: 702 default:
diff --git a/drivers/edac/mce_amd.h b/drivers/edac/mce_amd.h
index 35f6e0e3b297..c12394db9bdf 100644
--- a/drivers/edac/mce_amd.h
+++ b/drivers/edac/mce_amd.h
@@ -100,7 +100,7 @@ struct err_regs {
100 * per-family decoder ops 100 * per-family decoder ops
101 */ 101 */
102struct amd_decoder_ops { 102struct amd_decoder_ops {
103 bool (*dc_mce)(u16); 103 bool (*dc_mce)(u16, u8);
104 bool (*ic_mce)(u16); 104 bool (*ic_mce)(u16);
105 bool (*nb_mce)(u16, u8); 105 bool (*nb_mce)(u16, u8);
106}; 106};