diff options
| author | Borislav Petkov <borislav.petkov@amd.com> | 2010-08-26 13:05:49 -0400 |
|---|---|---|
| committer | Borislav Petkov <bp@amd64.org> | 2010-10-21 08:48:01 -0400 |
| commit | dd53bce4e8987f6848840d42bbeead5221eff308 (patch) | |
| tree | 0aa19cb96710be5c5f978b513a231e85590f6f60 | |
| parent | 888ab8e6eb2e41179cdc8edf5d0abd1cce0f0370 (diff) | |
EDAC, MCE: Adjust IC decoders to F14h
Add support for IC MCEs for F14h CPUs. K8 and F10h are almost identical
so use one function for both.
Signed-off-by: Borislav Petkov <borislav.petkov@amd.com>
| -rw-r--r-- | drivers/edac/mce_amd.c | 118 | ||||
| -rw-r--r-- | drivers/edac/mce_amd.h | 1 |
2 files changed, 71 insertions, 48 deletions
diff --git a/drivers/edac/mce_amd.c b/drivers/edac/mce_amd.c index 33985aa61356..60d5d9f4dfee 100644 --- a/drivers/edac/mce_amd.c +++ b/drivers/edac/mce_amd.c | |||
| @@ -219,61 +219,80 @@ wrong_dc_mce: | |||
| 219 | pr_emerg(HW_ERR "Corrupted DC MCE info?\n"); | 219 | pr_emerg(HW_ERR "Corrupted DC MCE info?\n"); |
| 220 | } | 220 | } |
| 221 | 221 | ||
| 222 | static void amd_decode_ic_mce(struct mce *m) | 222 | static bool k8_ic_mce(u16 ec) |
| 223 | { | 223 | { |
| 224 | u32 ec = m->status & 0xffff; | 224 | u8 ll = ec & 0x3; |
| 225 | u32 xec = (m->status >> 16) & 0xf; | 225 | u8 r4 = (ec >> 4) & 0xf; |
| 226 | bool ret = true; | ||
| 226 | 227 | ||
| 227 | pr_emerg(HW_ERR "Instruction Cache Error"); | 228 | if (!MEM_ERROR(ec)) |
| 229 | return false; | ||
| 228 | 230 | ||
| 229 | if (xec == 1 && TLB_ERROR(ec)) | 231 | if (ll == 0x2) |
| 230 | pr_cont(": %s TLB multimatch.\n", LL_MSG(ec)); | 232 | pr_cont("during a linefill from L2.\n"); |
| 231 | else if (xec == 0) { | 233 | else if (ll == 0x1) { |
| 232 | if (TLB_ERROR(ec)) | 234 | switch (r4) { |
| 233 | pr_cont(": %s TLB Parity error.\n", LL_MSG(ec)); | 235 | case R4_IRD: |
| 234 | else if (BUS_ERROR(ec)) { | 236 | pr_cont("Parity error during data load.\n"); |
| 235 | if (boot_cpu_data.x86 == 0xf && | 237 | break; |
| 236 | (m->status & BIT(58))) | ||
| 237 | pr_cont(" during system linefill.\n"); | ||
| 238 | else | ||
| 239 | pr_cont(" during attempted NB data read.\n"); | ||
| 240 | } else if (MEM_ERROR(ec)) { | ||
| 241 | u8 ll = ec & 0x3; | ||
| 242 | u8 rrrr = (ec >> 4) & 0xf; | ||
| 243 | 238 | ||
| 244 | if (ll == 0x2) | 239 | case R4_EVICT: |
| 245 | pr_cont(" during a linefill from L2.\n"); | 240 | pr_cont("Copyback Parity/Victim error.\n"); |
| 246 | else if (ll == 0x1) { | 241 | break; |
| 247 | 242 | ||
| 248 | switch (rrrr) { | 243 | case R4_SNOOP: |
| 249 | case 0x5: | 244 | pr_cont("Tag Snoop error.\n"); |
| 250 | pr_cont(": Parity error during " | 245 | break; |
| 251 | "data load.\n"); | 246 | |
| 252 | break; | 247 | default: |
| 253 | 248 | ret = false; | |
| 254 | case 0x7: | 249 | break; |
| 255 | pr_cont(": Copyback Parity/Victim" | 250 | } |
| 256 | " error.\n"); | ||
| 257 | break; | ||
| 258 | |||
| 259 | case 0x8: | ||
| 260 | pr_cont(": Tag Snoop error.\n"); | ||
| 261 | break; | ||
| 262 | |||
| 263 | default: | ||
| 264 | goto wrong_ic_mce; | ||
| 265 | break; | ||
| 266 | } | ||
| 267 | } | ||
| 268 | } else | ||
| 269 | goto wrong_ic_mce; | ||
| 270 | } else | 251 | } else |
| 271 | goto wrong_ic_mce; | 252 | ret = false; |
| 272 | 253 | ||
| 273 | return; | 254 | return ret; |
| 255 | } | ||
| 256 | |||
| 257 | static bool f14h_ic_mce(u16 ec) | ||
| 258 | { | ||
| 259 | u8 ll = ec & 0x3; | ||
| 260 | u8 tt = (ec >> 2) & 0x3; | ||
| 261 | u8 r4 = (ec >> 4) & 0xf; | ||
| 262 | bool ret = true; | ||
| 274 | 263 | ||
| 275 | wrong_ic_mce: | 264 | if (MEM_ERROR(ec)) { |
| 276 | pr_emerg(HW_ERR "Corrupted IC MCE info?\n"); | 265 | if (tt != 0 || ll != 1) |
| 266 | ret = false; | ||
| 267 | |||
| 268 | if (r4 == R4_IRD) | ||
| 269 | pr_cont("Data/tag array parity error for a tag hit.\n"); | ||
| 270 | else if (r4 == R4_SNOOP) | ||
| 271 | pr_cont("Tag error during snoop/victimization.\n"); | ||
| 272 | else | ||
| 273 | ret = false; | ||
| 274 | } | ||
| 275 | return ret; | ||
| 276 | } | ||
| 277 | |||
| 278 | static void amd_decode_ic_mce(struct mce *m) | ||
| 279 | { | ||
| 280 | u16 ec = m->status & 0xffff; | ||
| 281 | u8 xec = (m->status >> 16) & 0xf; | ||
| 282 | |||
| 283 | pr_emerg(HW_ERR "Instruction Cache Error: "); | ||
| 284 | |||
| 285 | if (TLB_ERROR(ec)) | ||
| 286 | pr_cont("%s TLB %s.\n", LL_MSG(ec), | ||
| 287 | (xec ? "multimatch" : "parity error")); | ||
| 288 | else if (BUS_ERROR(ec)) { | ||
| 289 | bool k8 = (boot_cpu_data.x86 == 0xf && (m->status & BIT(58))); | ||
| 290 | |||
| 291 | pr_cont("during %s.\n", (k8 ? "system linefill" : "NB data read")); | ||
| 292 | } else if (fam_ops->ic_mce(ec)) | ||
| 293 | ; | ||
| 294 | else | ||
| 295 | pr_emerg(HW_ERR "Corrupted IC MCE info?\n"); | ||
| 277 | } | 296 | } |
| 278 | 297 | ||
| 279 | static void amd_decode_bu_mce(struct mce *m) | 298 | static void amd_decode_bu_mce(struct mce *m) |
| @@ -481,14 +500,17 @@ static int __init mce_amd_init(void) | |||
| 481 | switch (boot_cpu_data.x86) { | 500 | switch (boot_cpu_data.x86) { |
| 482 | case 0xf: | 501 | case 0xf: |
| 483 | fam_ops->dc_mce = k8_dc_mce; | 502 | fam_ops->dc_mce = k8_dc_mce; |
| 503 | fam_ops->ic_mce = k8_ic_mce; | ||
| 484 | break; | 504 | break; |
| 485 | 505 | ||
| 486 | case 0x10: | 506 | case 0x10: |
| 487 | fam_ops->dc_mce = f10h_dc_mce; | 507 | fam_ops->dc_mce = f10h_dc_mce; |
| 508 | fam_ops->ic_mce = k8_ic_mce; | ||
| 488 | break; | 509 | break; |
| 489 | 510 | ||
| 490 | case 0x14: | 511 | case 0x14: |
| 491 | fam_ops->dc_mce = f14h_dc_mce; | 512 | fam_ops->dc_mce = f14h_dc_mce; |
| 513 | fam_ops->ic_mce = f14h_ic_mce; | ||
| 492 | break; | 514 | break; |
| 493 | 515 | ||
| 494 | default: | 516 | default: |
diff --git a/drivers/edac/mce_amd.h b/drivers/edac/mce_amd.h index 85985c225442..dc81dba9364b 100644 --- a/drivers/edac/mce_amd.h +++ b/drivers/edac/mce_amd.h | |||
| @@ -101,6 +101,7 @@ struct err_regs { | |||
| 101 | */ | 101 | */ |
| 102 | struct amd_decoder_ops { | 102 | struct amd_decoder_ops { |
| 103 | bool (*dc_mce)(u16); | 103 | bool (*dc_mce)(u16); |
| 104 | bool (*ic_mce)(u16); | ||
| 104 | }; | 105 | }; |
| 105 | 106 | ||
| 106 | void amd_report_gart_errors(bool); | 107 | void amd_report_gart_errors(bool); |
