i7300_edac.c (8199d8cc65787bfd83abbfb69d9de1b51e027c41) i7300_edac.c (32f9472613b30791d8cb5a953791cf4647166744)
1/*
2 * Intel 7300 class Memory Controllers kernel module (Clarksboro)
3 *
4 * This file may be distributed under the terms of the
5 * GNU General Public License version 2 only.
6 *
7 * Copyright (c) 2010 by:
8 * Mauro Carvalho Chehab <mchehab@redhat.com>

--- 263 unchanged lines hidden (view full) ---

272 #define NRECMEMA_BANK(v) (((v) >> 12) & 7)
273 #define NRECMEMA_RANK(v) (((v) >> 8) & 15)
274
275#define NRECMEMB 0xc0
276 #define NRECMEMB_IS_WR(v) ((v) & (1 << 31))
277 #define NRECMEMB_CAS(v) (((v) >> 16) & 0x1fff)
278 #define NRECMEMB_RAS(v) ((v) & 0xffff)
279
1/*
2 * Intel 7300 class Memory Controllers kernel module (Clarksboro)
3 *
4 * This file may be distributed under the terms of the
5 * GNU General Public License version 2 only.
6 *
7 * Copyright (c) 2010 by:
8 * Mauro Carvalho Chehab <mchehab@redhat.com>

--- 263 unchanged lines hidden (view full) ---

272 #define NRECMEMA_BANK(v) (((v) >> 12) & 7)
273 #define NRECMEMA_RANK(v) (((v) >> 8) & 15)
274
275#define NRECMEMB 0xc0
276 #define NRECMEMB_IS_WR(v) ((v) & (1 << 31))
277 #define NRECMEMB_CAS(v) (((v) >> 16) & 0x1fff)
278 #define NRECMEMB_RAS(v) ((v) & 0xffff)
279
280#define REDMEMA 0xdc
280
281
282#define RECMEMA 0xe0
283 #define RECMEMA_BANK(v) (((v) >> 12) & 7)
284 #define RECMEMA_RANK(v) (((v) >> 8) & 15)
285
286#define RECMEMB 0xe4
287 #define RECMEMB_IS_WR(v) ((v) & (1 << 31))
288 #define RECMEMB_CAS(v) (((v) >> 16) & 0x1fff)
289 #define RECMEMB_RAS(v) ((v) & 0xffff)
290
291
281/* Device name and register DID (Device ID) */
282struct i7300_dev_info {
283 const char *ctl_name; /* name for this device */
284 u16 fsb_mapping_errors; /* DID for the branchmap,control */
285};
286
287/* Table of devices attributes supported by this driver */
288static const struct i7300_dev_info i7300_devs[] = {

--- 109 unchanged lines hidden (view full) ---

398 * the hardware and cache it in the 'info'
399 * structure
400 */
401static void i7300_process_fbd_error(struct mem_ctl_info *mci)
402{
403 struct i7300_pvt *pvt;
404 u32 errnum, value;
405 u16 val16;
292/* Device name and register DID (Device ID) */
293struct i7300_dev_info {
294 const char *ctl_name; /* name for this device */
295 u16 fsb_mapping_errors; /* DID for the branchmap,control */
296};
297
298/* Table of devices attributes supported by this driver */
299static const struct i7300_dev_info i7300_devs[] = {

--- 109 unchanged lines hidden (view full) ---

409 * the hardware and cache it in the 'info'
410 * structure
411 */
412static void i7300_process_fbd_error(struct mem_ctl_info *mci)
413{
414 struct i7300_pvt *pvt;
415 u32 errnum, value;
416 u16 val16;
406 int branch, bank, rank, cas, ras;
417 unsigned branch, bank, rank, cas, ras;
418 u32 syndrome;
419
407 unsigned long errors;
408 const char *specific;
420 unsigned long errors;
421 const char *specific;
409 bool is_fatal, is_wr;
422 bool is_wr;
410
411 pvt = mci->pvt_info;
412
413 /* read in the 1st FATAL error register */
414 pci_read_config_dword(pvt->pci_dev_16_1_fsb_addr_map,
415 FERR_FAT_FBD, &value);
416 if (unlikely(value & FERR_FAT_FBD_ERR_MASK)) {
417 errors = value & FERR_FAT_FBD_ERR_MASK ;
418 errnum = find_first_bit(&errors,
419 ARRAY_SIZE(ferr_fat_fbd_name));
420 specific = GET_ERR_FROM_TABLE(ferr_fat_fbd_name, errnum);
423
424 pvt = mci->pvt_info;
425
426 /* read in the 1st FATAL error register */
427 pci_read_config_dword(pvt->pci_dev_16_1_fsb_addr_map,
428 FERR_FAT_FBD, &value);
429 if (unlikely(value & FERR_FAT_FBD_ERR_MASK)) {
430 errors = value & FERR_FAT_FBD_ERR_MASK ;
431 errnum = find_first_bit(&errors,
432 ARRAY_SIZE(ferr_fat_fbd_name));
433 specific = GET_ERR_FROM_TABLE(ferr_fat_fbd_name, errnum);
421 is_fatal = 1;
422
423 branch = (GET_FBD_FAT_IDX(value) == 2) ? 1 : 0;
424 pci_read_config_word(pvt->pci_dev_16_1_fsb_addr_map,
425 NRECMEMA, &val16);
426 bank = NRECMEMA_BANK(val16);
427 rank = NRECMEMA_RANK(val16);
428
429 pci_read_config_dword(pvt->pci_dev_16_1_fsb_addr_map,
430 NRECMEMB, &value);
431
432 is_wr = NRECMEMB_IS_WR(value);
433 cas = NRECMEMB_CAS(value);
434 ras = NRECMEMB_RAS(value);
435
436 snprintf(pvt->tmp_prt_buffer, PAGE_SIZE,
437 "FATAL (Branch=%d DRAM-Bank=%d %s "
438 "RAS=%d CAS=%d Err=0x%lx (%s))",
434
435 branch = (GET_FBD_FAT_IDX(value) == 2) ? 1 : 0;
436 pci_read_config_word(pvt->pci_dev_16_1_fsb_addr_map,
437 NRECMEMA, &val16);
438 bank = NRECMEMA_BANK(val16);
439 rank = NRECMEMA_RANK(val16);
440
441 pci_read_config_dword(pvt->pci_dev_16_1_fsb_addr_map,
442 NRECMEMB, &value);
443
444 is_wr = NRECMEMB_IS_WR(value);
445 cas = NRECMEMB_CAS(value);
446 ras = NRECMEMB_RAS(value);
447
448 snprintf(pvt->tmp_prt_buffer, PAGE_SIZE,
449 "FATAL (Branch=%d DRAM-Bank=%d %s "
450 "RAS=%d CAS=%d Err=0x%lx (%s))",
439 branch >> 1, bank,
451 branch, bank,
440 is_wr ? "RDWR" : "RD",
441 ras, cas,
442 errors, specific);
443
444 /* Call the helper to output message */
445 edac_mc_handle_fbd_ue(mci, rank, branch << 1,
446 (branch << 1) + 1,
447 pvt->tmp_prt_buffer);
452 is_wr ? "RDWR" : "RD",
453 ras, cas,
454 errors, specific);
455
456 /* Call the helper to output message */
457 edac_mc_handle_fbd_ue(mci, rank, branch << 1,
458 (branch << 1) + 1,
459 pvt->tmp_prt_buffer);
448 return;
449 }
450
451 /* read in the 1st NON-FATAL error register */
452 pci_read_config_dword(pvt->pci_dev_16_1_fsb_addr_map,
453 FERR_NF_FBD, &value);
454 if (unlikely(value & FERR_NF_FBD_ERR_MASK)) {
455 errors = value & FERR_NF_FBD_ERR_MASK;
456 errnum = find_first_bit(&errors,
457 ARRAY_SIZE(ferr_nf_fbd_name));
458 specific = GET_ERR_FROM_TABLE(ferr_nf_fbd_name, errnum);
460 }
461
462 /* read in the 1st NON-FATAL error register */
463 pci_read_config_dword(pvt->pci_dev_16_1_fsb_addr_map,
464 FERR_NF_FBD, &value);
465 if (unlikely(value & FERR_NF_FBD_ERR_MASK)) {
466 errors = value & FERR_NF_FBD_ERR_MASK;
467 errnum = find_first_bit(&errors,
468 ARRAY_SIZE(ferr_nf_fbd_name));
469 specific = GET_ERR_FROM_TABLE(ferr_nf_fbd_name, errnum);
459 is_fatal = 0;
460
461 /* Clear the error bit */
462 pci_write_config_dword(pvt->pci_dev_16_2_fsb_err_regs,
463 FERR_GLOBAL_LO, value);
464
470
471 /* Clear the error bit */
472 pci_write_config_dword(pvt->pci_dev_16_2_fsb_err_regs,
473 FERR_GLOBAL_LO, value);
474
465 goto error_fbd;
466 }
467 return;
475 pci_read_config_dword(pvt->pci_dev_16_1_fsb_addr_map,
476 REDMEMA, &syndrome);
468
477
469error_fbd:
478 branch = (GET_FBD_FAT_IDX(value) == 2) ? 1 : 0;
479 pci_read_config_word(pvt->pci_dev_16_1_fsb_addr_map,
480 RECMEMA, &val16);
481 bank = RECMEMA_BANK(val16);
482 rank = RECMEMA_RANK(val16);
470
483
471 i7300_mc_printk(mci, KERN_EMERG, "%s FBD error on branch %d: %s\n",
472 is_fatal ? "Fatal" : "NOT fatal", branch, specific);
484 pci_read_config_dword(pvt->pci_dev_16_1_fsb_addr_map,
485 RECMEMB, &value);
486
487 is_wr = RECMEMB_IS_WR(value);
488 cas = RECMEMB_CAS(value);
489 ras = RECMEMB_RAS(value);
490
491 /* Form out message */
492 snprintf(pvt->tmp_prt_buffer, PAGE_SIZE,
493 "Corrected error (Branch=%d (channel %d or %d), "
494 " DRAM-Bank=%d %s "
495 "RAS=%d CAS=%d, CE Err=0x%lx, Syndrome=0x%08x(%s))",
496 branch, branch << 1, (branch << 1) + 1,
497 bank,
498 is_wr ? "RDWR" : "RD",
499 ras, cas,
500 errors, syndrome, specific);
501
502 /*
503 * Call the helper to output message
504 * NOTE: Errors are reported per-branch, and not per-channel
505 * Currently, we don't know how to identify the right
506 * channel.
507 */
508 edac_mc_handle_fbd_ce(mci, rank, branch << 1,
509 pvt->tmp_prt_buffer);
510 }
511 return;
473}
474
475/*
476 * i7300_check_error Retrieve the hardware error information from
477 * the hardware and cache it in the 'info'
478 * structure
479 */
480static void i7300_check_error(struct mem_ctl_info *mci)

--- 714 unchanged lines hidden ---
512}
513
514/*
515 * i7300_check_error Retrieve the hardware error information from
516 * the hardware and cache it in the 'info'
517 * structure
518 */
519static void i7300_check_error(struct mem_ctl_info *mci)

--- 714 unchanged lines hidden ---