Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

EDAC/{skx_comm,imh}: Detect 2-level memory configuration

Detect 2-level memory configurations and notify the 'skx_common' library
to enable ADXL 2-level memory error decoding.

Tested-by: Yi Lai <yi1.lai@intel.com>
Signed-off-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
Signed-off-by: Tony Luck <tony.luck@intel.com>
Link: https://patch.msgid.link/20251119134132.2389472-7-qiuxu.zhuo@intel.com

authored by

Qiuxu Zhuo and committed by
Tony Luck
f619613f 39abdcbd

+42
+38
drivers/edac/imh_base.c
··· 35 35 #define TOLM(reg) (((u64)GET_BITFIELD(reg, 16, 31)) << 16) 36 36 #define TOHM(reg) (((u64)GET_BITFIELD(reg, 16, 51)) << 16) 37 37 38 + /* Home Agent (HA) */ 39 + #define NMCACHING(reg) GET_BITFIELD(reg, 8, 8) 40 + 38 41 /** 39 42 * struct local_reg - A register as described in the local package view. 40 43 * ··· 349 346 return 0; 350 347 } 351 348 349 + static bool check_2lm_enabled(struct res_config *cfg, struct skx_dev *d, int ha_idx) 350 + { 351 + DEFINE_LOCAL_REG(reg, cfg, d->pkg, true, ha, ha_idx, mode); 352 + 353 + if (!read_local_reg(&reg)) 354 + return false; 355 + 356 + if (!NMCACHING(reg.val)) 357 + return false; 358 + 359 + edac_dbg(2, "2-level memory configuration (reg 0x%llx, ha idx %d)\n", reg.val, ha_idx); 360 + return true; 361 + } 362 + 363 + /* Check whether the system has a 2-level memory configuration. */ 364 + static bool imh_2lm_enabled(struct res_config *cfg, struct list_head *head) 365 + { 366 + struct skx_dev *d; 367 + int i; 368 + 369 + list_for_each_entry(d, head, list) { 370 + for (i = 0; i < cfg->ddr_imc_num; i++) 371 + if (check_2lm_enabled(cfg, d, i)) 372 + return true; 373 + } 374 + 375 + return false; 376 + } 377 + 352 378 /* Helpers to read memory controller registers */ 353 379 static u64 read_imc_reg(struct skx_imc *imc, int chan, u32 offset, u8 width) 354 380 { ··· 499 467 .sca_reg_tolm_width = 8, 500 468 .sca_reg_tohm_offset = 0x2108, 501 469 .sca_reg_tohm_width = 8, 470 + .ha_base = 0x3eb000, 471 + .ha_size = 0x1000, 472 + .ha_reg_mode_offset = 0x4a0, 473 + .ha_reg_mode_width = 4, 502 474 }; 503 475 504 476 static const struct x86_cpu_id imh_cpuids[] = { ··· 561 525 rc = imh_get_munits(cfg, edac_list); 562 526 if (rc) 563 527 goto fail; 528 + 529 + skx_set_mem_cfg(imh_2lm_enabled(cfg, edac_list)); 564 530 565 531 rc = imh_register_mci(cfg, edac_list); 566 532 if (rc)
+4
drivers/edac/skx_common.h
··· 313 313 u8 sca_reg_tolm_width; 314 314 u32 sca_reg_tohm_offset; 315 315 u8 sca_reg_tohm_width; 316 + u64 ha_base; 317 + u32 ha_size; 318 + u32 ha_reg_mode_offset; 319 + u8 ha_reg_mode_width; 316 320 }; 317 321 }; 318 322 };