Skip to content

Commit 221aa03

Browse files
youquan-songaegl
authored andcommitted
EDAC/i10nm: Add driver decoder for Sapphire Rapids server
Intel SDM (December 2022) vol3B 17.13.2 contains IMC MC error codes for Sapphire Rapids. Current i10nm_edac only supports firmware decoder (ACPI DSM methods) for Sapphire Rapids. So add the driver decoder (decoding DDR memory errors via extracting error information from the IMC MC error codes) for Sapphire Rapids for better decoding performance. Co-developed-by: Qiuxu Zhuo <[email protected]> Signed-off-by: Qiuxu Zhuo <[email protected]> Signed-off-by: Youquan Song <[email protected]> Signed-off-by: Tony Luck <[email protected]>
1 parent ba987ea commit 221aa03

File tree

1 file changed

+69
-33
lines changed

1 file changed

+69
-33
lines changed

drivers/edac/i10nm_base.c

Lines changed: 69 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -434,27 +434,47 @@ static bool i10nm_check_2lm(struct res_config *cfg)
434434
}
435435

436436
/*
437-
* Check whether the error comes from DDRT by ICX/Tremont model specific error code.
438-
* Refer to SDM vol3B 16.11.3 Intel IMC MC error codes for IA32_MCi_STATUS.
437+
* Check whether the error comes from DDRT by ICX/Tremont/SPR model specific error code.
438+
* Refer to SDM vol3B 17.11.3/17.13.2 Intel IMC MC error codes for IA32_MCi_STATUS.
439439
*/
440440
static bool i10nm_mscod_is_ddrt(u32 mscod)
441441
{
442-
switch (mscod) {
443-
case 0x0106: case 0x0107:
444-
case 0x0800: case 0x0804:
445-
case 0x0806 ... 0x0808:
446-
case 0x080a ... 0x080e:
447-
case 0x0810: case 0x0811:
448-
case 0x0816: case 0x081e:
449-
case 0x081f:
450-
return true;
442+
switch (res_cfg->type) {
443+
case I10NM:
444+
switch (mscod) {
445+
case 0x0106: case 0x0107:
446+
case 0x0800: case 0x0804:
447+
case 0x0806 ... 0x0808:
448+
case 0x080a ... 0x080e:
449+
case 0x0810: case 0x0811:
450+
case 0x0816: case 0x081e:
451+
case 0x081f:
452+
return true;
453+
}
454+
455+
break;
456+
case SPR:
457+
switch (mscod) {
458+
case 0x0800: case 0x0804:
459+
case 0x0806 ... 0x0808:
460+
case 0x080a ... 0x080e:
461+
case 0x0810: case 0x0811:
462+
case 0x0816: case 0x081e:
463+
case 0x081f:
464+
return true;
465+
}
466+
467+
break;
468+
default:
469+
return false;
451470
}
452471

453472
return false;
454473
}
455474

456475
static bool i10nm_mc_decode_available(struct mce *mce)
457476
{
477+
#define ICX_IMCx_CHy 0x06666000
458478
u8 bank;
459479

460480
if (!decoding_via_mca || mem_cfg_2lm)
@@ -468,21 +488,26 @@ static bool i10nm_mc_decode_available(struct mce *mce)
468488

469489
switch (res_cfg->type) {
470490
case I10NM:
471-
if (bank < 13 || bank > 26)
472-
return false;
473-
474-
/* DDRT errors can't be decoded from MCA bank registers */
475-
if (MCI_MISC_ECC_MODE(mce->misc) == MCI_MISC_ECC_DDRT)
491+
/* Check whether the bank is one of {13,14,17,18,21,22,25,26} */
492+
if (!(ICX_IMCx_CHy & (1 << bank)))
476493
return false;
477-
478-
if (i10nm_mscod_is_ddrt(MCI_STATUS_MSCOD(mce->status)))
494+
break;
495+
case SPR:
496+
if (bank < 13 || bank > 20)
479497
return false;
480-
481-
/* Check whether one of {13,14,17,18,21,22,25,26} */
482-
return ((bank - 13) & BIT(1)) == 0;
498+
break;
483499
default:
484500
return false;
485501
}
502+
503+
/* DDRT errors can't be decoded from MCA bank registers */
504+
if (MCI_MISC_ECC_MODE(mce->misc) == MCI_MISC_ECC_DDRT)
505+
return false;
506+
507+
if (i10nm_mscod_is_ddrt(MCI_STATUS_MSCOD(mce->status)))
508+
return false;
509+
510+
return true;
486511
}
487512

488513
static bool i10nm_mc_decode(struct decoded_addr *res)
@@ -504,9 +529,29 @@ static bool i10nm_mc_decode(struct decoded_addr *res)
504529

505530
switch (res_cfg->type) {
506531
case I10NM:
507-
bank = m->bank - 13;
508-
res->imc = bank / 4;
509-
res->channel = bank % 2;
532+
bank = m->bank - 13;
533+
res->imc = bank / 4;
534+
res->channel = bank % 2;
535+
res->column = GET_BITFIELD(m->misc, 9, 18) << 2;
536+
res->row = GET_BITFIELD(m->misc, 19, 39);
537+
res->bank_group = GET_BITFIELD(m->misc, 40, 41);
538+
res->bank_address = GET_BITFIELD(m->misc, 42, 43);
539+
res->bank_group |= GET_BITFIELD(m->misc, 44, 44) << 2;
540+
res->rank = GET_BITFIELD(m->misc, 56, 58);
541+
res->dimm = res->rank >> 2;
542+
res->rank = res->rank % 4;
543+
break;
544+
case SPR:
545+
bank = m->bank - 13;
546+
res->imc = bank / 2;
547+
res->channel = bank % 2;
548+
res->column = GET_BITFIELD(m->misc, 9, 18) << 2;
549+
res->row = GET_BITFIELD(m->misc, 19, 36);
550+
res->bank_group = GET_BITFIELD(m->misc, 37, 38);
551+
res->bank_address = GET_BITFIELD(m->misc, 39, 40);
552+
res->bank_group |= GET_BITFIELD(m->misc, 41, 41) << 2;
553+
res->rank = GET_BITFIELD(m->misc, 57, 57);
554+
res->dimm = GET_BITFIELD(m->misc, 58, 58);
510555
break;
511556
default:
512557
return false;
@@ -518,15 +563,6 @@ static bool i10nm_mc_decode(struct decoded_addr *res)
518563
return false;
519564
}
520565

521-
res->column = GET_BITFIELD(m->misc, 9, 18) << 2;
522-
res->row = GET_BITFIELD(m->misc, 19, 39);
523-
res->bank_group = GET_BITFIELD(m->misc, 40, 41);
524-
res->bank_address = GET_BITFIELD(m->misc, 42, 43);
525-
res->bank_group |= GET_BITFIELD(m->misc, 44, 44) << 2;
526-
res->rank = GET_BITFIELD(m->misc, 56, 58);
527-
res->dimm = res->rank >> 2;
528-
res->rank = res->rank % 4;
529-
530566
return true;
531567
}
532568

0 commit comments

Comments
 (0)