|
80 | 80 | #define ECC_ERROR_LOG_UE BIT_ULL(63) |
81 | 81 | #define ECC_ERROR_LOG_ADDR_SHIFT 5 |
82 | 82 | #define ECC_ERROR_LOG_ADDR(v) GET_BITFIELD(v, 5, 38) |
| 83 | +#define ECC_ERROR_LOG_ADDR45(v) GET_BITFIELD(v, 5, 45) |
83 | 84 | #define ECC_ERROR_LOG_SYND(v) GET_BITFIELD(v, 46, 61) |
84 | 85 |
|
85 | 86 | /* Host MMIO base address */ |
@@ -133,6 +134,8 @@ static struct res_config { |
133 | 134 | u32 ibecc_base; |
134 | 135 | u32 ibecc_error_log_offset; |
135 | 136 | bool (*ibecc_available)(struct pci_dev *pdev); |
| 137 | + /* Extract error address logged in IBECC */ |
| 138 | + u64 (*err_addr)(u64 ecclog); |
136 | 139 | /* Convert error address logged in IBECC to system physical address */ |
137 | 140 | u64 (*err_addr_to_sys_addr)(u64 eaddr, int mc); |
138 | 141 | /* Convert error address logged in IBECC to integrated memory controller address */ |
@@ -235,6 +238,13 @@ static struct work_struct ecclog_work; |
235 | 238 | #define DID_ADL_N_SKU10 0x4679 |
236 | 239 | #define DID_ADL_N_SKU11 0x467c |
237 | 240 |
|
| 241 | +/* Compute die IDs for Raptor Lake-P with IBECC */ |
| 242 | +#define DID_RPL_P_SKU1 0xa706 |
| 243 | +#define DID_RPL_P_SKU2 0xa707 |
| 244 | +#define DID_RPL_P_SKU3 0xa708 |
| 245 | +#define DID_RPL_P_SKU4 0xa716 |
| 246 | +#define DID_RPL_P_SKU5 0xa718 |
| 247 | + |
238 | 248 | static int get_mchbar(struct pci_dev *pdev, u64 *mchbar) |
239 | 249 | { |
240 | 250 | union { |
@@ -401,6 +411,11 @@ static u64 adl_err_addr_to_imc_addr(u64 eaddr, int mc) |
401 | 411 | return imc_addr; |
402 | 412 | } |
403 | 413 |
|
| 414 | +static u64 rpl_p_err_addr(u64 ecclog) |
| 415 | +{ |
| 416 | + return ECC_ERROR_LOG_ADDR45(ecclog); |
| 417 | +} |
| 418 | + |
404 | 419 | static struct res_config ehl_cfg = { |
405 | 420 | .num_imc = 1, |
406 | 421 | .imc_base = 0x5000, |
@@ -457,6 +472,18 @@ static struct res_config adl_n_cfg = { |
457 | 472 | .err_addr_to_imc_addr = adl_err_addr_to_imc_addr, |
458 | 473 | }; |
459 | 474 |
|
| 475 | +static struct res_config rpl_p_cfg = { |
| 476 | + .machine_check = true, |
| 477 | + .num_imc = 2, |
| 478 | + .imc_base = 0xd800, |
| 479 | + .ibecc_base = 0xd400, |
| 480 | + .ibecc_error_log_offset = 0x68, |
| 481 | + .ibecc_available = tgl_ibecc_available, |
| 482 | + .err_addr = rpl_p_err_addr, |
| 483 | + .err_addr_to_sys_addr = adl_err_addr_to_sys_addr, |
| 484 | + .err_addr_to_imc_addr = adl_err_addr_to_imc_addr, |
| 485 | +}; |
| 486 | + |
460 | 487 | static const struct pci_device_id igen6_pci_tbl[] = { |
461 | 488 | { PCI_VDEVICE(INTEL, DID_EHL_SKU5), (kernel_ulong_t)&ehl_cfg }, |
462 | 489 | { PCI_VDEVICE(INTEL, DID_EHL_SKU6), (kernel_ulong_t)&ehl_cfg }, |
@@ -489,6 +516,11 @@ static const struct pci_device_id igen6_pci_tbl[] = { |
489 | 516 | { PCI_VDEVICE(INTEL, DID_ADL_N_SKU9), (kernel_ulong_t)&adl_n_cfg }, |
490 | 517 | { PCI_VDEVICE(INTEL, DID_ADL_N_SKU10), (kernel_ulong_t)&adl_n_cfg }, |
491 | 518 | { PCI_VDEVICE(INTEL, DID_ADL_N_SKU11), (kernel_ulong_t)&adl_n_cfg }, |
| 519 | + { PCI_VDEVICE(INTEL, DID_RPL_P_SKU1), (kernel_ulong_t)&rpl_p_cfg }, |
| 520 | + { PCI_VDEVICE(INTEL, DID_RPL_P_SKU2), (kernel_ulong_t)&rpl_p_cfg }, |
| 521 | + { PCI_VDEVICE(INTEL, DID_RPL_P_SKU3), (kernel_ulong_t)&rpl_p_cfg }, |
| 522 | + { PCI_VDEVICE(INTEL, DID_RPL_P_SKU4), (kernel_ulong_t)&rpl_p_cfg }, |
| 523 | + { PCI_VDEVICE(INTEL, DID_RPL_P_SKU5), (kernel_ulong_t)&rpl_p_cfg }, |
492 | 524 | { }, |
493 | 525 | }; |
494 | 526 | MODULE_DEVICE_TABLE(pci, igen6_pci_tbl); |
@@ -744,8 +776,11 @@ static void ecclog_work_cb(struct work_struct *work) |
744 | 776 |
|
745 | 777 | llist_for_each_entry_safe(node, tmp, head, llnode) { |
746 | 778 | memset(&res, 0, sizeof(res)); |
747 | | - eaddr = ECC_ERROR_LOG_ADDR(node->ecclog) << |
748 | | - ECC_ERROR_LOG_ADDR_SHIFT; |
| 779 | + if (res_cfg->err_addr) |
| 780 | + eaddr = res_cfg->err_addr(node->ecclog); |
| 781 | + else |
| 782 | + eaddr = ECC_ERROR_LOG_ADDR(node->ecclog) << |
| 783 | + ECC_ERROR_LOG_ADDR_SHIFT; |
749 | 784 | res.mc = node->mc; |
750 | 785 | res.sys_addr = res_cfg->err_addr_to_sys_addr(eaddr, res.mc); |
751 | 786 | res.imc_addr = res_cfg->err_addr_to_imc_addr(eaddr, res.mc); |
|
0 commit comments