|
81 | 81 | #define ECC_ERROR_LOG_UE BIT_ULL(63) |
82 | 82 | #define ECC_ERROR_LOG_ADDR_SHIFT 5 |
83 | 83 | #define ECC_ERROR_LOG_ADDR(v) GET_BITFIELD(v, 5, 38) |
| 84 | +#define ECC_ERROR_LOG_ADDR45(v) GET_BITFIELD(v, 5, 45) |
84 | 85 | #define ECC_ERROR_LOG_SYND(v) GET_BITFIELD(v, 46, 61) |
85 | 86 |
|
86 | 87 | /* Host MMIO base address */ |
@@ -134,6 +135,8 @@ static struct res_config { |
134 | 135 | u32 ibecc_base; |
135 | 136 | u32 ibecc_error_log_offset; |
136 | 137 | bool (*ibecc_available)(struct pci_dev *pdev); |
| 138 | + /* Extract error address logged in IBECC */ |
| 139 | + u64 (*err_addr)(u64 ecclog); |
137 | 140 | /* Convert error address logged in IBECC to system physical address */ |
138 | 141 | u64 (*err_addr_to_sys_addr)(u64 eaddr, int mc); |
139 | 142 | /* Convert error address logged in IBECC to integrated memory controller address */ |
@@ -236,6 +239,13 @@ static struct work_struct ecclog_work; |
236 | 239 | #define DID_ADL_N_SKU10 0x4679 |
237 | 240 | #define DID_ADL_N_SKU11 0x467c |
238 | 241 |
|
| 242 | +/* Compute die IDs for Raptor Lake-P with IBECC */ |
| 243 | +#define DID_RPL_P_SKU1 0xa706 |
| 244 | +#define DID_RPL_P_SKU2 0xa707 |
| 245 | +#define DID_RPL_P_SKU3 0xa708 |
| 246 | +#define DID_RPL_P_SKU4 0xa716 |
| 247 | +#define DID_RPL_P_SKU5 0xa718 |
| 248 | + |
239 | 249 | static bool ehl_ibecc_available(struct pci_dev *pdev) |
240 | 250 | { |
241 | 251 | u32 v; |
@@ -372,6 +382,11 @@ static u64 adl_err_addr_to_imc_addr(u64 eaddr, int mc) |
372 | 382 | return imc_addr; |
373 | 383 | } |
374 | 384 |
|
| 385 | +static u64 rpl_p_err_addr(u64 ecclog) |
| 386 | +{ |
| 387 | + return ECC_ERROR_LOG_ADDR45(ecclog); |
| 388 | +} |
| 389 | + |
375 | 390 | static struct res_config ehl_cfg = { |
376 | 391 | .num_imc = 1, |
377 | 392 | .imc_base = 0x5000, |
@@ -428,6 +443,18 @@ static struct res_config adl_n_cfg = { |
428 | 443 | .err_addr_to_imc_addr = adl_err_addr_to_imc_addr, |
429 | 444 | }; |
430 | 445 |
|
| 446 | +static struct res_config rpl_p_cfg = { |
| 447 | + .machine_check = true, |
| 448 | + .num_imc = 2, |
| 449 | + .imc_base = 0xd800, |
| 450 | + .ibecc_base = 0xd400, |
| 451 | + .ibecc_error_log_offset = 0x68, |
| 452 | + .ibecc_available = tgl_ibecc_available, |
| 453 | + .err_addr = rpl_p_err_addr, |
| 454 | + .err_addr_to_sys_addr = adl_err_addr_to_sys_addr, |
| 455 | + .err_addr_to_imc_addr = adl_err_addr_to_imc_addr, |
| 456 | +}; |
| 457 | + |
431 | 458 | static const struct pci_device_id igen6_pci_tbl[] = { |
432 | 459 | { PCI_VDEVICE(INTEL, DID_EHL_SKU5), (kernel_ulong_t)&ehl_cfg }, |
433 | 460 | { PCI_VDEVICE(INTEL, DID_EHL_SKU6), (kernel_ulong_t)&ehl_cfg }, |
@@ -460,6 +487,11 @@ static const struct pci_device_id igen6_pci_tbl[] = { |
460 | 487 | { PCI_VDEVICE(INTEL, DID_ADL_N_SKU9), (kernel_ulong_t)&adl_n_cfg }, |
461 | 488 | { PCI_VDEVICE(INTEL, DID_ADL_N_SKU10), (kernel_ulong_t)&adl_n_cfg }, |
462 | 489 | { PCI_VDEVICE(INTEL, DID_ADL_N_SKU11), (kernel_ulong_t)&adl_n_cfg }, |
| 490 | + { PCI_VDEVICE(INTEL, DID_RPL_P_SKU1), (kernel_ulong_t)&rpl_p_cfg }, |
| 491 | + { PCI_VDEVICE(INTEL, DID_RPL_P_SKU2), (kernel_ulong_t)&rpl_p_cfg }, |
| 492 | + { PCI_VDEVICE(INTEL, DID_RPL_P_SKU3), (kernel_ulong_t)&rpl_p_cfg }, |
| 493 | + { PCI_VDEVICE(INTEL, DID_RPL_P_SKU4), (kernel_ulong_t)&rpl_p_cfg }, |
| 494 | + { PCI_VDEVICE(INTEL, DID_RPL_P_SKU5), (kernel_ulong_t)&rpl_p_cfg }, |
463 | 495 | { }, |
464 | 496 | }; |
465 | 497 | MODULE_DEVICE_TABLE(pci, igen6_pci_tbl); |
@@ -737,8 +769,11 @@ static void ecclog_work_cb(struct work_struct *work) |
737 | 769 |
|
738 | 770 | llist_for_each_entry_safe(node, tmp, head, llnode) { |
739 | 771 | memset(&res, 0, sizeof(res)); |
740 | | - eaddr = ECC_ERROR_LOG_ADDR(node->ecclog) << |
741 | | - ECC_ERROR_LOG_ADDR_SHIFT; |
| 772 | + if (res_cfg->err_addr) |
| 773 | + eaddr = res_cfg->err_addr(node->ecclog); |
| 774 | + else |
| 775 | + eaddr = ECC_ERROR_LOG_ADDR(node->ecclog) << |
| 776 | + ECC_ERROR_LOG_ADDR_SHIFT; |
742 | 777 | res.mc = node->mc; |
743 | 778 | res.sys_addr = res_cfg->err_addr_to_sys_addr(eaddr, res.mc); |
744 | 779 | res.imc_addr = res_cfg->err_addr_to_imc_addr(eaddr, res.mc); |
|
0 commit comments