1919#include <linux/genalloc.h>
2020#include <linux/edac.h>
2121#include <linux/bits.h>
22+ #include <linux/bitfield.h>
2223#include <linux/io.h>
2324#include <asm/mach_traps.h>
2425#include <asm/nmi.h>
7980#define ECC_ERROR_LOG_OFFSET (IBECC_BASE + res_cfg->ibecc_error_log_offset)
8081#define ECC_ERROR_LOG_CE BIT_ULL(62)
8182#define ECC_ERROR_LOG_UE BIT_ULL(63)
82- #define ECC_ERROR_LOG_ADDR_SHIFT 5
83- #define ECC_ERROR_LOG_ADDR (v ) GET_BITFIELD(v, 5, 38)
84- #define ECC_ERROR_LOG_ADDR45 (v ) GET_BITFIELD(v, 5, 45)
8583#define ECC_ERROR_LOG_SYND (v ) GET_BITFIELD(v, 46, 61)
8684
8785/* Host MMIO base address */
8886#define MCHBAR_OFFSET 0x48
8987#define MCHBAR_EN BIT_ULL(0)
90- #define MCHBAR_BASE (v ) (GET_BITFIELD(v, 16, 38) << 16)
9188#define MCHBAR_SIZE 0x10000
9289
9390/* Parameters for the channel decode stage */
@@ -129,6 +126,14 @@ static struct res_config {
129126 bool machine_check ;
130127 /* The number of present memory controllers. */
131128 int num_imc ;
129+ /* Host MMIO configuration */
130+ u64 reg_mchbar_mask ;
131+ /* Top of memory */
132+ u64 reg_tom_mask ;
133+ /* Top of upper usable DRAM */
134+ u64 reg_touud_mask ;
135+ /* IBECC error log */
136+ u64 reg_eccerrlog_addr_mask ;
132137 u32 imc_base ;
133138 u32 cmf_base ;
134139 u32 cmf_size ;
@@ -305,7 +310,8 @@ static int get_mchbar(struct pci_dev *pdev, u64 *mchbar)
305310 return - ENODEV ;
306311 }
307312
308- * mchbar = MCHBAR_BASE (u .v );
313+ * mchbar = u .v & res_cfg -> reg_mchbar_mask ;
314+ edac_dbg (2 , "MCHBAR 0x%llx (reg 0x%llx)\n" , * mchbar , u .v );
309315
310316 return 0 ;
311317}
@@ -481,11 +487,15 @@ static u64 adl_err_addr_to_imc_addr(u64 eaddr, int mc)
481487
482488static u64 rpl_p_err_addr (u64 ecclog )
483489{
484- return ECC_ERROR_LOG_ADDR45 ( ecclog );
490+ return field_get ( res_cfg -> reg_eccerrlog_addr_mask , ecclog );
485491}
486492
487493static struct res_config ehl_cfg = {
488494 .num_imc = 1 ,
495+ .reg_mchbar_mask = GENMASK_ULL (38 , 16 ),
496+ .reg_tom_mask = GENMASK_ULL (38 , 20 ),
497+ .reg_touud_mask = GENMASK_ULL (38 , 20 ),
498+ .reg_eccerrlog_addr_mask = GENMASK_ULL (38 , 5 ),
489499 .imc_base = 0x5000 ,
490500 .ibecc_base = 0xdc00 ,
491501 .ibecc_available = ehl_ibecc_available ,
@@ -496,6 +506,10 @@ static struct res_config ehl_cfg = {
496506
497507static struct res_config icl_cfg = {
498508 .num_imc = 1 ,
509+ .reg_mchbar_mask = GENMASK_ULL (38 , 16 ),
510+ .reg_tom_mask = GENMASK_ULL (38 , 20 ),
511+ .reg_touud_mask = GENMASK_ULL (38 , 20 ),
512+ .reg_eccerrlog_addr_mask = GENMASK_ULL (38 , 5 ),
499513 .imc_base = 0x5000 ,
500514 .ibecc_base = 0xd800 ,
501515 .ibecc_error_log_offset = 0x170 ,
@@ -507,6 +521,10 @@ static struct res_config icl_cfg = {
507521static struct res_config tgl_cfg = {
508522 .machine_check = true,
509523 .num_imc = 2 ,
524+ .reg_mchbar_mask = GENMASK_ULL (38 , 17 ),
525+ .reg_tom_mask = GENMASK_ULL (38 , 20 ),
526+ .reg_touud_mask = GENMASK_ULL (38 , 20 ),
527+ .reg_eccerrlog_addr_mask = GENMASK_ULL (38 , 5 ),
510528 .imc_base = 0x5000 ,
511529 .cmf_base = 0x11000 ,
512530 .cmf_size = 0x800 ,
@@ -521,6 +539,10 @@ static struct res_config tgl_cfg = {
521539static struct res_config adl_cfg = {
522540 .machine_check = true,
523541 .num_imc = 2 ,
542+ .reg_mchbar_mask = GENMASK_ULL (41 , 17 ),
543+ .reg_tom_mask = GENMASK_ULL (41 , 20 ),
544+ .reg_touud_mask = GENMASK_ULL (41 , 20 ),
545+ .reg_eccerrlog_addr_mask = GENMASK_ULL (45 , 5 ),
524546 .imc_base = 0xd800 ,
525547 .ibecc_base = 0xd400 ,
526548 .ibecc_error_log_offset = 0x68 ,
@@ -532,6 +554,10 @@ static struct res_config adl_cfg = {
532554static struct res_config adl_n_cfg = {
533555 .machine_check = true,
534556 .num_imc = 1 ,
557+ .reg_mchbar_mask = GENMASK_ULL (41 , 17 ),
558+ .reg_tom_mask = GENMASK_ULL (41 , 20 ),
559+ .reg_touud_mask = GENMASK_ULL (41 , 20 ),
560+ .reg_eccerrlog_addr_mask = GENMASK_ULL (45 , 5 ),
535561 .imc_base = 0xd800 ,
536562 .ibecc_base = 0xd400 ,
537563 .ibecc_error_log_offset = 0x68 ,
@@ -543,6 +569,10 @@ static struct res_config adl_n_cfg = {
543569static struct res_config rpl_p_cfg = {
544570 .machine_check = true,
545571 .num_imc = 2 ,
572+ .reg_mchbar_mask = GENMASK_ULL (41 , 17 ),
573+ .reg_tom_mask = GENMASK_ULL (41 , 20 ),
574+ .reg_touud_mask = GENMASK_ULL (41 , 20 ),
575+ .reg_eccerrlog_addr_mask = GENMASK_ULL (45 , 5 ),
546576 .imc_base = 0xd800 ,
547577 .ibecc_base = 0xd400 ,
548578 .ibecc_error_log_offset = 0x68 ,
@@ -555,6 +585,10 @@ static struct res_config rpl_p_cfg = {
555585static struct res_config mtl_ps_cfg = {
556586 .machine_check = true,
557587 .num_imc = 2 ,
588+ .reg_mchbar_mask = GENMASK_ULL (41 , 17 ),
589+ .reg_tom_mask = GENMASK_ULL (41 , 20 ),
590+ .reg_touud_mask = GENMASK_ULL (41 , 20 ),
591+ .reg_eccerrlog_addr_mask = GENMASK_ULL (38 , 5 ),
558592 .imc_base = 0xd800 ,
559593 .ibecc_base = 0xd400 ,
560594 .ibecc_error_log_offset = 0x170 ,
@@ -566,6 +600,10 @@ static struct res_config mtl_ps_cfg = {
566600static struct res_config mtl_p_cfg = {
567601 .machine_check = true,
568602 .num_imc = 2 ,
603+ .reg_mchbar_mask = GENMASK_ULL (41 , 17 ),
604+ .reg_tom_mask = GENMASK_ULL (41 , 20 ),
605+ .reg_touud_mask = GENMASK_ULL (41 , 20 ),
606+ .reg_eccerrlog_addr_mask = GENMASK_ULL (38 , 5 ),
569607 .imc_base = 0xd800 ,
570608 .ibecc_base = 0xd400 ,
571609 .ibecc_error_log_offset = 0x170 ,
@@ -577,6 +615,10 @@ static struct res_config mtl_p_cfg = {
577615static struct res_config wcl_cfg = {
578616 .machine_check = true,
579617 .num_imc = 1 ,
618+ .reg_mchbar_mask = GENMASK_ULL (41 , 17 ),
619+ .reg_tom_mask = GENMASK_ULL (41 , 20 ),
620+ .reg_touud_mask = GENMASK_ULL (41 , 20 ),
621+ .reg_eccerrlog_addr_mask = GENMASK_ULL (38 , 5 ),
580622 .imc_base = 0xd800 ,
581623 .ibecc_base = 0xd400 ,
582624 .ibecc_error_log_offset = 0x170 ,
@@ -908,8 +950,8 @@ static void ecclog_work_cb(struct work_struct *work)
908950 if (res_cfg -> err_addr )
909951 eaddr = res_cfg -> err_addr (node -> ecclog );
910952 else
911- eaddr = ECC_ERROR_LOG_ADDR ( node -> ecclog ) <<
912- ECC_ERROR_LOG_ADDR_SHIFT ;
953+ eaddr = node -> ecclog & res_cfg -> reg_eccerrlog_addr_mask ;
954+
913955 res .mc = node -> mc ;
914956 res .sys_addr = res_cfg -> err_addr_to_sys_addr (eaddr , res .mc );
915957 res .imc_addr = res_cfg -> err_addr_to_imc_addr (eaddr , res .mc );
@@ -1129,8 +1171,7 @@ static int debugfs_u64_set(void *data, u64 val)
11291171
11301172 pr_warn_once ("Fake error to 0x%llx injected via debugfs\n" , val );
11311173
1132- val >>= ECC_ERROR_LOG_ADDR_SHIFT ;
1133- ecclog = (val << ECC_ERROR_LOG_ADDR_SHIFT ) | ECC_ERROR_LOG_CE ;
1174+ ecclog = (val & res_cfg -> reg_eccerrlog_addr_mask ) | ECC_ERROR_LOG_CE ;
11341175
11351176 if (!ecclog_gen_pool_add (0 , ecclog ))
11361177 irq_work_queue (& ecclog_irq_work );
@@ -1196,7 +1237,7 @@ static int igen6_pci_setup(struct pci_dev *pdev, u64 *mchbar)
11961237 goto fail ;
11971238 }
11981239
1199- igen6_tom = u .v & GENMASK_ULL ( 38 , 20 ) ;
1240+ igen6_tom = u .v & res_cfg -> reg_tom_mask ;
12001241
12011242 if (get_mchbar (pdev , mchbar ))
12021243 goto fail ;
@@ -1207,7 +1248,7 @@ static int igen6_pci_setup(struct pci_dev *pdev, u64 *mchbar)
12071248 else if (pci_read_config_dword (pdev , TOUUD_OFFSET + 4 , & u .v_hi ))
12081249 edac_dbg (2 , "Failed to read upper TOUUD\n" );
12091250 else
1210- igen6_touud = u .v & GENMASK_ULL ( 38 , 20 ) ;
1251+ igen6_touud = u .v & res_cfg -> reg_touud_mask ;
12111252#endif
12121253
12131254 return 0 ;
0 commit comments