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

Merge tag 'edac_updates_for_v6.11' of git://git.kernel.org/pub/scm/linux/kernel/git/ras/ras

Pull EDAC updates from Borislav Petkov:

- The AMD memory controllers data fabric version 4.5 supports
non-power-of-2 denormalization in the sense that certain bits of the
system physical address cannot be reconstructed from the normalized
address reported by the RAS hardware. Add support for handling such
addresses

- Switch the EDAC drivers to the new Intel CPU model defines

- The usual fixes and cleanups all over the place

* tag 'edac_updates_for_v6.11' of git://git.kernel.org/pub/scm/linux/kernel/git/ras/ras:
EDAC: Add missing MODULE_DESCRIPTION() macros
EDAC/dmc520: Use devm_platform_ioremap_resource()
EDAC/igen6: Add Intel Arrow Lake-U/H SoCs support
RAS/AMD/FMPM: Use atl internal.h for INVALID_SPA
RAS/AMD/ATL: Implement DF 4.5 NP2 denormalization
RAS/AMD/ATL: Validate address map when information is gathered
RAS/AMD/ATL: Expand helpers for adding and removing base and hole
RAS/AMD/ATL: Read DRAM hole base early
RAS/AMD/ATL: Add amd_atl pr_fmt() prefix
RAS/AMD/ATL: Add a missing module description
EDAC, i10nm: make skx_common.o a separate module
EDAC/skx: Switch to new Intel CPU model defines
EDAC/sb_edac: Switch to new Intel CPU model defines
EDAC, pnd2: Switch to new Intel CPU model defines
EDAC/i10nm: Switch to new Intel CPU model defines
EDAC/ghes: Add missing newline to pr_info() statement
RAS/AMD/ATL: Add missing newline to pr_info() statement
EDAC/thunderx: Remove unused struct error_syndrome

+819 -108
+6 -4
drivers/edac/Makefile
··· 54 54 layerscape_edac_mod-y := fsl_ddr_edac.o layerscape_edac.o 55 55 obj-$(CONFIG_EDAC_LAYERSCAPE) += layerscape_edac_mod.o 56 56 57 - skx_edac-y := skx_common.o skx_base.o 58 - obj-$(CONFIG_EDAC_SKX) += skx_edac.o 57 + skx_edac_common-y := skx_common.o 59 58 60 - i10nm_edac-y := skx_common.o i10nm_base.o 61 - obj-$(CONFIG_EDAC_I10NM) += i10nm_edac.o 59 + skx_edac-y := skx_base.o 60 + obj-$(CONFIG_EDAC_SKX) += skx_edac.o skx_edac_common.o 61 + 62 + i10nm_edac-y := i10nm_base.o 63 + obj-$(CONFIG_EDAC_I10NM) += i10nm_edac.o skx_edac_common.o 62 64 63 65 obj-$(CONFIG_EDAC_CELL) += cell_edac.o 64 66 obj-$(CONFIG_EDAC_PPC4XX) += ppc4xx_edac.o
+1 -3
drivers/edac/dmc520_edac.c
··· 480 480 struct mem_ctl_info *mci; 481 481 void __iomem *reg_base; 482 482 u32 irq_mask_all = 0; 483 - struct resource *res; 484 483 struct device *dev; 485 484 int ret, idx, irq; 486 485 u32 reg_val; ··· 504 505 } 505 506 506 507 /* Initialize dmc520 edac */ 507 - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 508 - reg_base = devm_ioremap_resource(dev, res); 508 + reg_base = devm_platform_ioremap_resource(pdev, 0); 509 509 if (IS_ERR(reg_base)) 510 510 return PTR_ERR(reg_base); 511 511
+1 -1
drivers/edac/ghes_edac.c
··· 547 547 return -ENODEV; 548 548 549 549 if (list_empty(ghes_devs)) { 550 - pr_info("GHES probing device list is empty"); 550 + pr_info("GHES probing device list is empty\n"); 551 551 return -ENODEV; 552 552 } 553 553
+10 -10
drivers/edac/i10nm_base.c
··· 942 942 }; 943 943 944 944 static const struct x86_cpu_id i10nm_cpuids[] = { 945 - X86_MATCH_INTEL_FAM6_MODEL_STEPPINGS(ATOM_TREMONT_D, X86_STEPPINGS(0x0, 0x3), &i10nm_cfg0), 946 - X86_MATCH_INTEL_FAM6_MODEL_STEPPINGS(ATOM_TREMONT_D, X86_STEPPINGS(0x4, 0xf), &i10nm_cfg1), 947 - X86_MATCH_INTEL_FAM6_MODEL_STEPPINGS(ICELAKE_X, X86_STEPPINGS(0x0, 0x3), &i10nm_cfg0), 948 - X86_MATCH_INTEL_FAM6_MODEL_STEPPINGS(ICELAKE_X, X86_STEPPINGS(0x4, 0xf), &i10nm_cfg1), 949 - X86_MATCH_INTEL_FAM6_MODEL_STEPPINGS(ICELAKE_D, X86_STEPPINGS(0x0, 0xf), &i10nm_cfg1), 950 - X86_MATCH_INTEL_FAM6_MODEL_STEPPINGS(SAPPHIRERAPIDS_X, X86_STEPPINGS(0x0, 0xf), &spr_cfg), 951 - X86_MATCH_INTEL_FAM6_MODEL_STEPPINGS(EMERALDRAPIDS_X, X86_STEPPINGS(0x0, 0xf), &spr_cfg), 952 - X86_MATCH_INTEL_FAM6_MODEL_STEPPINGS(GRANITERAPIDS_X, X86_STEPPINGS(0x0, 0xf), &gnr_cfg), 953 - X86_MATCH_INTEL_FAM6_MODEL_STEPPINGS(ATOM_CRESTMONT_X, X86_STEPPINGS(0x0, 0xf), &gnr_cfg), 954 - X86_MATCH_INTEL_FAM6_MODEL_STEPPINGS(ATOM_CRESTMONT, X86_STEPPINGS(0x0, 0xf), &gnr_cfg), 945 + X86_MATCH_VFM_STEPPINGS(INTEL_ATOM_TREMONT_D, X86_STEPPINGS(0x0, 0x3), &i10nm_cfg0), 946 + X86_MATCH_VFM_STEPPINGS(INTEL_ATOM_TREMONT_D, X86_STEPPINGS(0x4, 0xf), &i10nm_cfg1), 947 + X86_MATCH_VFM_STEPPINGS(INTEL_ICELAKE_X, X86_STEPPINGS(0x0, 0x3), &i10nm_cfg0), 948 + X86_MATCH_VFM_STEPPINGS(INTEL_ICELAKE_X, X86_STEPPINGS(0x4, 0xf), &i10nm_cfg1), 949 + X86_MATCH_VFM_STEPPINGS(INTEL_ICELAKE_D, X86_STEPPINGS(0x0, 0xf), &i10nm_cfg1), 950 + X86_MATCH_VFM_STEPPINGS(INTEL_SAPPHIRERAPIDS_X, X86_STEPPINGS(0x0, 0xf), &spr_cfg), 951 + X86_MATCH_VFM_STEPPINGS(INTEL_EMERALDRAPIDS_X, X86_STEPPINGS(0x0, 0xf), &spr_cfg), 952 + X86_MATCH_VFM_STEPPINGS(INTEL_GRANITERAPIDS_X, X86_STEPPINGS(0x0, 0xf), &gnr_cfg), 953 + X86_MATCH_VFM_STEPPINGS(INTEL_ATOM_CRESTMONT_X, X86_STEPPINGS(0x0, 0xf), &gnr_cfg), 954 + X86_MATCH_VFM_STEPPINGS(INTEL_ATOM_CRESTMONT, X86_STEPPINGS(0x0, 0xf), &gnr_cfg), 955 955 {} 956 956 }; 957 957 MODULE_DEVICE_TABLE(x86cpu, i10nm_cpuids);
+8
drivers/edac/igen6_edac.c
··· 258 258 #define DID_MTL_P_SKU2 0x7d02 259 259 #define DID_MTL_P_SKU3 0x7d14 260 260 261 + /* Compute die IDs for Arrow Lake-UH with IBECC */ 262 + #define DID_ARL_UH_SKU1 0x7d06 263 + #define DID_ARL_UH_SKU2 0x7d20 264 + #define DID_ARL_UH_SKU3 0x7d30 265 + 261 266 static int get_mchbar(struct pci_dev *pdev, u64 *mchbar) 262 267 { 263 268 union { ··· 602 597 { PCI_VDEVICE(INTEL, DID_MTL_P_SKU1), (kernel_ulong_t)&mtl_p_cfg }, 603 598 { PCI_VDEVICE(INTEL, DID_MTL_P_SKU2), (kernel_ulong_t)&mtl_p_cfg }, 604 599 { PCI_VDEVICE(INTEL, DID_MTL_P_SKU3), (kernel_ulong_t)&mtl_p_cfg }, 600 + { PCI_VDEVICE(INTEL, DID_ARL_UH_SKU1), (kernel_ulong_t)&mtl_p_cfg }, 601 + { PCI_VDEVICE(INTEL, DID_ARL_UH_SKU2), (kernel_ulong_t)&mtl_p_cfg }, 602 + { PCI_VDEVICE(INTEL, DID_ARL_UH_SKU3), (kernel_ulong_t)&mtl_p_cfg }, 605 603 { }, 606 604 }; 607 605 MODULE_DEVICE_TABLE(pci, igen6_pci_tbl);
+1
drivers/edac/layerscape_edac.c
··· 69 69 70 70 module_exit(fsl_ddr_mc_exit); 71 71 72 + MODULE_DESCRIPTION("Freescale Layerscape EDAC driver"); 72 73 MODULE_LICENSE("GPL"); 73 74 MODULE_AUTHOR("NXP Semiconductor"); 74 75 module_param(edac_op_state, int, 0444);
+1
drivers/edac/mpc85xx_edac.c
··· 704 704 705 705 module_exit(mpc85xx_mc_exit); 706 706 707 + MODULE_DESCRIPTION("Freescale MPC85xx Memory Controller EDAC driver"); 707 708 MODULE_LICENSE("GPL"); 708 709 MODULE_AUTHOR("Montavista Software, Inc."); 709 710 module_param(edac_op_state, int, 0444);
+1
drivers/edac/octeon_edac-l2c.c
··· 201 201 }; 202 202 module_platform_driver(octeon_l2c_driver); 203 203 204 + MODULE_DESCRIPTION("Cavium Octeon Secondary Caches (L2C) EDAC driver"); 204 205 MODULE_LICENSE("GPL"); 205 206 MODULE_AUTHOR("Ralf Baechle <ralf@linux-mips.org>");
+1
drivers/edac/octeon_edac-lmc.c
··· 319 319 }; 320 320 module_platform_driver(octeon_lmc_edac_driver); 321 321 322 + MODULE_DESCRIPTION("Cavium Octeon DRAM Memory Controller (LMC) EDAC driver"); 322 323 MODULE_LICENSE("GPL"); 323 324 MODULE_AUTHOR("Ralf Baechle <ralf@linux-mips.org>");
+1
drivers/edac/octeon_edac-pc.c
··· 137 137 }; 138 138 module_platform_driver(co_cache_error_driver); 139 139 140 + MODULE_DESCRIPTION("Cavium Octeon Primary Caches EDAC driver"); 140 141 MODULE_LICENSE("GPL"); 141 142 MODULE_AUTHOR("Ralf Baechle <ralf@linux-mips.org>");
+1
drivers/edac/octeon_edac-pci.c
··· 104 104 }; 105 105 module_platform_driver(octeon_pci_driver); 106 106 107 + MODULE_DESCRIPTION("Cavium Octeon PCI Controller EDAC driver"); 107 108 MODULE_LICENSE("GPL"); 108 109 MODULE_AUTHOR("Ralf Baechle <ralf@linux-mips.org>");
+2 -2
drivers/edac/pnd2_edac.c
··· 1511 1511 }; 1512 1512 1513 1513 static const struct x86_cpu_id pnd2_cpuids[] = { 1514 - X86_MATCH_INTEL_FAM6_MODEL(ATOM_GOLDMONT, &apl_ops), 1515 - X86_MATCH_INTEL_FAM6_MODEL(ATOM_GOLDMONT_D, &dnv_ops), 1514 + X86_MATCH_VFM(INTEL_ATOM_GOLDMONT, &apl_ops), 1515 + X86_MATCH_VFM(INTEL_ATOM_GOLDMONT_D, &dnv_ops), 1516 1516 { } 1517 1517 }; 1518 1518 MODULE_DEVICE_TABLE(x86cpu, pnd2_cpuids);
+7 -7
drivers/edac/sb_edac.c
··· 3546 3546 } 3547 3547 3548 3548 static const struct x86_cpu_id sbridge_cpuids[] = { 3549 - X86_MATCH_INTEL_FAM6_MODEL(SANDYBRIDGE_X, &pci_dev_descr_sbridge_table), 3550 - X86_MATCH_INTEL_FAM6_MODEL(IVYBRIDGE_X, &pci_dev_descr_ibridge_table), 3551 - X86_MATCH_INTEL_FAM6_MODEL(HASWELL_X, &pci_dev_descr_haswell_table), 3552 - X86_MATCH_INTEL_FAM6_MODEL(BROADWELL_X, &pci_dev_descr_broadwell_table), 3553 - X86_MATCH_INTEL_FAM6_MODEL(BROADWELL_D, &pci_dev_descr_broadwell_table), 3554 - X86_MATCH_INTEL_FAM6_MODEL(XEON_PHI_KNL, &pci_dev_descr_knl_table), 3555 - X86_MATCH_INTEL_FAM6_MODEL(XEON_PHI_KNM, &pci_dev_descr_knl_table), 3549 + X86_MATCH_VFM(INTEL_SANDYBRIDGE_X, &pci_dev_descr_sbridge_table), 3550 + X86_MATCH_VFM(INTEL_IVYBRIDGE_X, &pci_dev_descr_ibridge_table), 3551 + X86_MATCH_VFM(INTEL_HASWELL_X, &pci_dev_descr_haswell_table), 3552 + X86_MATCH_VFM(INTEL_BROADWELL_X, &pci_dev_descr_broadwell_table), 3553 + X86_MATCH_VFM(INTEL_BROADWELL_D, &pci_dev_descr_broadwell_table), 3554 + X86_MATCH_VFM(INTEL_XEON_PHI_KNL, &pci_dev_descr_knl_table), 3555 + X86_MATCH_VFM(INTEL_XEON_PHI_KNM, &pci_dev_descr_knl_table), 3556 3556 { } 3557 3557 }; 3558 3558 MODULE_DEVICE_TABLE(x86cpu, sbridge_cpuids);
+1 -1
drivers/edac/skx_base.c
··· 164 164 }; 165 165 166 166 static const struct x86_cpu_id skx_cpuids[] = { 167 - X86_MATCH_INTEL_FAM6_MODEL_STEPPINGS(SKYLAKE_X, X86_STEPPINGS(0x0, 0xf), &skx_cfg), 167 + X86_MATCH_VFM_STEPPINGS(INTEL_SKYLAKE_X, X86_STEPPINGS(0x0, 0xf), &skx_cfg), 168 168 { } 169 169 }; 170 170 MODULE_DEVICE_TABLE(x86cpu, skx_cpuids);
+19 -2
drivers/edac/skx_common.c
··· 48 48 static LIST_HEAD(dev_edac_list); 49 49 static bool skx_mem_cfg_2lm; 50 50 51 - int __init skx_adxl_get(void) 51 + int skx_adxl_get(void) 52 52 { 53 53 const char * const *names; 54 54 int i, j; ··· 110 110 111 111 return -ENODEV; 112 112 } 113 + EXPORT_SYMBOL_GPL(skx_adxl_get); 113 114 114 - void __exit skx_adxl_put(void) 115 + void skx_adxl_put(void) 115 116 { 116 117 kfree(adxl_values); 117 118 kfree(adxl_msg); 118 119 } 120 + EXPORT_SYMBOL_GPL(skx_adxl_put); 119 121 120 122 static bool skx_adxl_decode(struct decoded_addr *res, bool error_in_1st_level_mem) 121 123 { ··· 189 187 { 190 188 skx_mem_cfg_2lm = mem_cfg_2lm; 191 189 } 190 + EXPORT_SYMBOL_GPL(skx_set_mem_cfg); 192 191 193 192 void skx_set_decode(skx_decode_f decode, skx_show_retry_log_f show_retry_log) 194 193 { 195 194 driver_decode = decode; 196 195 skx_show_retry_rd_err_log = show_retry_log; 197 196 } 197 + EXPORT_SYMBOL_GPL(skx_set_decode); 198 198 199 199 int skx_get_src_id(struct skx_dev *d, int off, u8 *id) 200 200 { ··· 210 206 *id = GET_BITFIELD(reg, 12, 14); 211 207 return 0; 212 208 } 209 + EXPORT_SYMBOL_GPL(skx_get_src_id); 213 210 214 211 int skx_get_node_id(struct skx_dev *d, u8 *id) 215 212 { ··· 224 219 *id = GET_BITFIELD(reg, 0, 2); 225 220 return 0; 226 221 } 222 + EXPORT_SYMBOL_GPL(skx_get_node_id); 227 223 228 224 static int get_width(u32 mtr) 229 225 { ··· 290 284 *list = &dev_edac_list; 291 285 return ndev; 292 286 } 287 + EXPORT_SYMBOL_GPL(skx_get_all_bus_mappings); 293 288 294 289 int skx_get_hi_lo(unsigned int did, int off[], u64 *tolm, u64 *tohm) 295 290 { ··· 330 323 pci_dev_put(pdev); 331 324 return -ENODEV; 332 325 } 326 + EXPORT_SYMBOL_GPL(skx_get_hi_lo); 333 327 334 328 static int skx_get_dimm_attr(u32 reg, int lobit, int hibit, int add, 335 329 int minval, int maxval, const char *name) ··· 402 394 403 395 return 1; 404 396 } 397 + EXPORT_SYMBOL_GPL(skx_get_dimm_info); 405 398 406 399 int skx_get_nvdimm_info(struct dimm_info *dimm, struct skx_imc *imc, 407 400 int chan, int dimmno, const char *mod_str) ··· 451 442 452 443 return (size == 0 || size == ~0ull) ? 0 : 1; 453 444 } 445 + EXPORT_SYMBOL_GPL(skx_get_nvdimm_info); 454 446 455 447 int skx_register_mci(struct skx_imc *imc, struct pci_dev *pdev, 456 448 const char *ctl_name, const char *mod_str, ··· 522 512 imc->mci = NULL; 523 513 return rc; 524 514 } 515 + EXPORT_SYMBOL_GPL(skx_register_mci); 525 516 526 517 static void skx_unregister_mci(struct skx_imc *imc) 527 518 { ··· 699 688 mce->kflags |= MCE_HANDLED_EDAC; 700 689 return NOTIFY_DONE; 701 690 } 691 + EXPORT_SYMBOL_GPL(skx_mce_check_error); 702 692 703 693 void skx_remove(void) 704 694 { ··· 737 725 kfree(d); 738 726 } 739 727 } 728 + EXPORT_SYMBOL_GPL(skx_remove); 729 + 730 + MODULE_LICENSE("GPL v2"); 731 + MODULE_AUTHOR("Tony Luck"); 732 + MODULE_DESCRIPTION("MC Driver for Intel server processors");
+2 -2
drivers/edac/skx_common.h
··· 231 231 typedef bool (*skx_decode_f)(struct decoded_addr *res); 232 232 typedef void (*skx_show_retry_log_f)(struct decoded_addr *res, char *msg, int len, bool scrub_err); 233 233 234 - int __init skx_adxl_get(void); 235 - void __exit skx_adxl_put(void); 234 + int skx_adxl_get(void); 235 + void skx_adxl_put(void); 236 236 void skx_set_decode(skx_decode_f decode, skx_show_retry_log_f show_retry_log); 237 237 void skx_set_mem_cfg(bool mem_cfg_2lm); 238 238
-6
drivers/edac/thunderx_edac.c
··· 35 35 ERR_UNKNOWN = 3, 36 36 }; 37 37 38 - #define MAX_SYNDROME_REGS 4 39 - 40 - struct error_syndrome { 41 - u64 reg[MAX_SYNDROME_REGS]; 42 - }; 43 - 44 38 struct error_descr { 45 39 int type; 46 40 u64 mask;
+28 -24
drivers/ras/amd/atl/core.c
··· 49 49 return FIELD_GET(DF_LEGACY_MMIO_HOLE_EN, reg); 50 50 } 51 51 52 - static int add_legacy_hole(struct addr_ctx *ctx) 52 + static u64 add_legacy_hole(struct addr_ctx *ctx, u64 addr) 53 53 { 54 - u32 dram_hole_base; 55 - u8 func = 0; 56 - 57 54 if (!legacy_hole_en(ctx)) 58 - return 0; 55 + return addr; 59 56 60 - if (df_cfg.rev >= DF4) 61 - func = 7; 57 + if (addr >= df_cfg.dram_hole_base) 58 + addr += (BIT_ULL(32) - df_cfg.dram_hole_base); 62 59 63 - if (df_indirect_read_broadcast(ctx->node_id, func, 0x104, &dram_hole_base)) 64 - return -EINVAL; 60 + return addr; 61 + } 65 62 66 - dram_hole_base &= DF_DRAM_HOLE_BASE_MASK; 63 + static u64 remove_legacy_hole(struct addr_ctx *ctx, u64 addr) 64 + { 65 + if (!legacy_hole_en(ctx)) 66 + return addr; 67 67 68 - if (ctx->ret_addr >= dram_hole_base) 69 - ctx->ret_addr += (BIT_ULL(32) - dram_hole_base); 68 + if (addr >= df_cfg.dram_hole_base) 69 + addr -= (BIT_ULL(32) - df_cfg.dram_hole_base); 70 70 71 - return 0; 71 + return addr; 72 72 } 73 73 74 74 static u64 get_base_addr(struct addr_ctx *ctx) ··· 83 83 return base_addr << DF_DRAM_BASE_LIMIT_LSB; 84 84 } 85 85 86 - static int add_base_and_hole(struct addr_ctx *ctx) 86 + u64 add_base_and_hole(struct addr_ctx *ctx, u64 addr) 87 87 { 88 - ctx->ret_addr += get_base_addr(ctx); 88 + return add_legacy_hole(ctx, addr + get_base_addr(ctx)); 89 + } 89 90 90 - if (add_legacy_hole(ctx)) 91 - return -EINVAL; 92 - 93 - return 0; 91 + u64 remove_base_and_hole(struct addr_ctx *ctx, u64 addr) 92 + { 93 + return remove_legacy_hole(ctx, addr) - get_base_addr(ctx); 94 94 } 95 95 96 96 static bool late_hole_remove(struct addr_ctx *ctx) ··· 125 125 ctx.inputs.die_id = die_id; 126 126 ctx.inputs.coh_st_inst_id = coh_st_inst_id; 127 127 128 + if (legacy_hole_en(&ctx) && !df_cfg.dram_hole_base) 129 + return -EINVAL; 130 + 128 131 if (determine_node_id(&ctx, socket_id, die_id)) 129 132 return -EINVAL; 130 133 ··· 137 134 if (denormalize_address(&ctx)) 138 135 return -EINVAL; 139 136 140 - if (!late_hole_remove(&ctx) && add_base_and_hole(&ctx)) 141 - return -EINVAL; 137 + if (!late_hole_remove(&ctx)) 138 + ctx.ret_addr = add_base_and_hole(&ctx, ctx.ret_addr); 142 139 143 140 if (dehash_address(&ctx)) 144 141 return -EINVAL; 145 142 146 - if (late_hole_remove(&ctx) && add_base_and_hole(&ctx)) 147 - return -EINVAL; 143 + if (late_hole_remove(&ctx)) 144 + ctx.ret_addr = add_base_and_hole(&ctx, ctx.ret_addr); 148 145 149 146 if (addr_over_limit(&ctx)) 150 147 return -EINVAL; ··· 209 206 __module_get(THIS_MODULE); 210 207 amd_atl_register_decoder(convert_umc_mca_addr_to_sys_addr); 211 208 212 - pr_info("AMD Address Translation Library initialized"); 209 + pr_info("AMD Address Translation Library initialized\n"); 213 210 return 0; 214 211 } 215 212 ··· 225 222 module_init(amd_atl_init); 226 223 module_exit(amd_atl_exit); 227 224 225 + MODULE_DESCRIPTION("AMD Address Translation Library"); 228 226 MODULE_LICENSE("GPL");
-43
drivers/ras/amd/atl/dehash.c
··· 12 12 13 13 #include "internal.h" 14 14 15 - /* 16 - * Verify the interleave bits are correct in the different interleaving 17 - * settings. 18 - * 19 - * If @num_intlv_dies and/or @num_intlv_sockets are 1, it means the 20 - * respective interleaving is disabled. 21 - */ 22 - static inline bool map_bits_valid(struct addr_ctx *ctx, u8 bit1, u8 bit2, 23 - u8 num_intlv_dies, u8 num_intlv_sockets) 24 - { 25 - if (!(ctx->map.intlv_bit_pos == bit1 || ctx->map.intlv_bit_pos == bit2)) { 26 - pr_debug("Invalid interleave bit: %u", ctx->map.intlv_bit_pos); 27 - return false; 28 - } 29 - 30 - if (ctx->map.num_intlv_dies > num_intlv_dies) { 31 - pr_debug("Invalid number of interleave dies: %u", ctx->map.num_intlv_dies); 32 - return false; 33 - } 34 - 35 - if (ctx->map.num_intlv_sockets > num_intlv_sockets) { 36 - pr_debug("Invalid number of interleave sockets: %u", ctx->map.num_intlv_sockets); 37 - return false; 38 - } 39 - 40 - return true; 41 - } 42 - 43 15 static int df2_dehash_addr(struct addr_ctx *ctx) 44 16 { 45 17 u8 hashed_bit, intlv_bit, intlv_bit_pos; 46 - 47 - if (!map_bits_valid(ctx, 8, 9, 1, 1)) 48 - return -EINVAL; 49 18 50 19 intlv_bit_pos = ctx->map.intlv_bit_pos; 51 20 intlv_bit = !!(BIT_ULL(intlv_bit_pos) & ctx->ret_addr); ··· 35 66 { 36 67 bool hash_ctl_64k, hash_ctl_2M, hash_ctl_1G; 37 68 u8 hashed_bit, intlv_bit, intlv_bit_pos; 38 - 39 - if (!map_bits_valid(ctx, 8, 9, 1, 1)) 40 - return -EINVAL; 41 69 42 70 hash_ctl_64k = FIELD_GET(DF3_HASH_CTL_64K, ctx->map.ctl); 43 71 hash_ctl_2M = FIELD_GET(DF3_HASH_CTL_2M, ctx->map.ctl); ··· 137 171 bool hash_ctl_64k, hash_ctl_2M, hash_ctl_1G; 138 172 u8 hashed_bit, intlv_bit; 139 173 140 - if (!map_bits_valid(ctx, 8, 8, 1, 2)) 141 - return -EINVAL; 142 - 143 174 hash_ctl_64k = FIELD_GET(DF4_HASH_CTL_64K, ctx->map.ctl); 144 175 hash_ctl_2M = FIELD_GET(DF4_HASH_CTL_2M, ctx->map.ctl); 145 176 hash_ctl_1G = FIELD_GET(DF4_HASH_CTL_1G, ctx->map.ctl); ··· 209 246 bool hash_ctl_64k, hash_ctl_2M, hash_ctl_1G, hash_ctl_1T; 210 247 u8 hashed_bit, intlv_bit; 211 248 u64 rehash_vector; 212 - 213 - if (!map_bits_valid(ctx, 8, 8, 1, 2)) 214 - return -EINVAL; 215 249 216 250 hash_ctl_64k = FIELD_GET(DF4_HASH_CTL_64K, ctx->map.ctl); 217 251 hash_ctl_2M = FIELD_GET(DF4_HASH_CTL_2M, ctx->map.ctl); ··· 319 359 bool hash_ctl_4k, hash_ctl_64k, hash_ctl_2M, hash_ctl_1G, hash_ctl_1T; 320 360 bool hashed_bit, intlv_bit, test_bit; 321 361 u8 num_intlv_bits, base_bit, i; 322 - 323 - if (!map_bits_valid(ctx, 8, 8, 4, 1)) 324 - return -EINVAL; 325 362 326 363 hash_ctl_4k = FIELD_GET(DF4p5_HASH_CTL_4K, ctx->map.ctl); 327 364 hash_ctl_64k = FIELD_GET(DF4_HASH_CTL_64K, ctx->map.ctl);
+561
drivers/ras/amd/atl/denormalize.c
··· 448 448 return (phys_fabric_id & df_cfg.node_id_mask) | log_fabric_id; 449 449 } 450 450 451 + static u16 get_logical_coh_st_fabric_id_for_current_spa(struct addr_ctx *ctx, 452 + struct df4p5_denorm_ctx *denorm_ctx) 453 + { 454 + bool hash_ctl_64k, hash_ctl_2M, hash_ctl_1G, hash_ctl_1T; 455 + bool hash_pa8, hash_pa9, hash_pa12, hash_pa13; 456 + u64 cs_id = 0; 457 + 458 + hash_ctl_64k = FIELD_GET(DF4_HASH_CTL_64K, ctx->map.ctl); 459 + hash_ctl_2M = FIELD_GET(DF4_HASH_CTL_2M, ctx->map.ctl); 460 + hash_ctl_1G = FIELD_GET(DF4_HASH_CTL_1G, ctx->map.ctl); 461 + hash_ctl_1T = FIELD_GET(DF4p5_HASH_CTL_1T, ctx->map.ctl); 462 + 463 + hash_pa8 = FIELD_GET(BIT_ULL(8), denorm_ctx->current_spa); 464 + hash_pa8 ^= FIELD_GET(BIT_ULL(14), denorm_ctx->current_spa); 465 + hash_pa8 ^= FIELD_GET(BIT_ULL(16), denorm_ctx->current_spa) & hash_ctl_64k; 466 + hash_pa8 ^= FIELD_GET(BIT_ULL(21), denorm_ctx->current_spa) & hash_ctl_2M; 467 + hash_pa8 ^= FIELD_GET(BIT_ULL(30), denorm_ctx->current_spa) & hash_ctl_1G; 468 + hash_pa8 ^= FIELD_GET(BIT_ULL(40), denorm_ctx->current_spa) & hash_ctl_1T; 469 + 470 + hash_pa9 = FIELD_GET(BIT_ULL(9), denorm_ctx->current_spa); 471 + hash_pa9 ^= FIELD_GET(BIT_ULL(17), denorm_ctx->current_spa) & hash_ctl_64k; 472 + hash_pa9 ^= FIELD_GET(BIT_ULL(22), denorm_ctx->current_spa) & hash_ctl_2M; 473 + hash_pa9 ^= FIELD_GET(BIT_ULL(31), denorm_ctx->current_spa) & hash_ctl_1G; 474 + hash_pa9 ^= FIELD_GET(BIT_ULL(41), denorm_ctx->current_spa) & hash_ctl_1T; 475 + 476 + hash_pa12 = FIELD_GET(BIT_ULL(12), denorm_ctx->current_spa); 477 + hash_pa12 ^= FIELD_GET(BIT_ULL(18), denorm_ctx->current_spa) & hash_ctl_64k; 478 + hash_pa12 ^= FIELD_GET(BIT_ULL(23), denorm_ctx->current_spa) & hash_ctl_2M; 479 + hash_pa12 ^= FIELD_GET(BIT_ULL(32), denorm_ctx->current_spa) & hash_ctl_1G; 480 + hash_pa12 ^= FIELD_GET(BIT_ULL(42), denorm_ctx->current_spa) & hash_ctl_1T; 481 + 482 + hash_pa13 = FIELD_GET(BIT_ULL(13), denorm_ctx->current_spa); 483 + hash_pa13 ^= FIELD_GET(BIT_ULL(19), denorm_ctx->current_spa) & hash_ctl_64k; 484 + hash_pa13 ^= FIELD_GET(BIT_ULL(24), denorm_ctx->current_spa) & hash_ctl_2M; 485 + hash_pa13 ^= FIELD_GET(BIT_ULL(33), denorm_ctx->current_spa) & hash_ctl_1G; 486 + hash_pa13 ^= FIELD_GET(BIT_ULL(43), denorm_ctx->current_spa) & hash_ctl_1T; 487 + 488 + switch (ctx->map.intlv_mode) { 489 + case DF4p5_NPS0_24CHAN_1K_HASH: 490 + cs_id = FIELD_GET(GENMASK_ULL(63, 13), denorm_ctx->current_spa) << 3; 491 + cs_id %= denorm_ctx->mod_value; 492 + cs_id <<= 2; 493 + cs_id |= (hash_pa9 | (hash_pa12 << 1)); 494 + cs_id |= hash_pa8 << df_cfg.socket_id_shift; 495 + break; 496 + 497 + case DF4p5_NPS0_24CHAN_2K_HASH: 498 + cs_id = FIELD_GET(GENMASK_ULL(63, 14), denorm_ctx->current_spa) << 4; 499 + cs_id %= denorm_ctx->mod_value; 500 + cs_id <<= 2; 501 + cs_id |= (hash_pa12 | (hash_pa13 << 1)); 502 + cs_id |= hash_pa8 << df_cfg.socket_id_shift; 503 + break; 504 + 505 + case DF4p5_NPS1_12CHAN_1K_HASH: 506 + cs_id = FIELD_GET(GENMASK_ULL(63, 12), denorm_ctx->current_spa) << 2; 507 + cs_id %= denorm_ctx->mod_value; 508 + cs_id <<= 2; 509 + cs_id |= (hash_pa8 | (hash_pa9 << 1)); 510 + break; 511 + 512 + case DF4p5_NPS1_12CHAN_2K_HASH: 513 + cs_id = FIELD_GET(GENMASK_ULL(63, 13), denorm_ctx->current_spa) << 3; 514 + cs_id %= denorm_ctx->mod_value; 515 + cs_id <<= 2; 516 + cs_id |= (hash_pa8 | (hash_pa12 << 1)); 517 + break; 518 + 519 + case DF4p5_NPS2_6CHAN_1K_HASH: 520 + case DF4p5_NPS1_10CHAN_1K_HASH: 521 + cs_id = FIELD_GET(GENMASK_ULL(63, 12), denorm_ctx->current_spa) << 2; 522 + cs_id |= (FIELD_GET(BIT_ULL(9), denorm_ctx->current_spa) << 1); 523 + cs_id %= denorm_ctx->mod_value; 524 + cs_id <<= 1; 525 + cs_id |= hash_pa8; 526 + break; 527 + 528 + case DF4p5_NPS2_6CHAN_2K_HASH: 529 + case DF4p5_NPS1_10CHAN_2K_HASH: 530 + cs_id = FIELD_GET(GENMASK_ULL(63, 12), denorm_ctx->current_spa) << 2; 531 + cs_id %= denorm_ctx->mod_value; 532 + cs_id <<= 1; 533 + cs_id |= hash_pa8; 534 + break; 535 + 536 + case DF4p5_NPS4_3CHAN_1K_HASH: 537 + case DF4p5_NPS2_5CHAN_1K_HASH: 538 + cs_id = FIELD_GET(GENMASK_ULL(63, 12), denorm_ctx->current_spa) << 2; 539 + cs_id |= FIELD_GET(GENMASK_ULL(9, 8), denorm_ctx->current_spa); 540 + cs_id %= denorm_ctx->mod_value; 541 + break; 542 + 543 + case DF4p5_NPS4_3CHAN_2K_HASH: 544 + case DF4p5_NPS2_5CHAN_2K_HASH: 545 + cs_id = FIELD_GET(GENMASK_ULL(63, 12), denorm_ctx->current_spa) << 2; 546 + cs_id |= FIELD_GET(BIT_ULL(8), denorm_ctx->current_spa) << 1; 547 + cs_id %= denorm_ctx->mod_value; 548 + break; 549 + 550 + default: 551 + atl_debug_on_bad_intlv_mode(ctx); 552 + return 0; 553 + } 554 + 555 + if (cs_id > 0xffff) { 556 + atl_debug(ctx, "Translation error: Resulting cs_id larger than u16\n"); 557 + return 0; 558 + } 559 + 560 + return cs_id; 561 + } 562 + 451 563 static int denorm_addr_common(struct addr_ctx *ctx) 452 564 { 453 565 u64 denorm_addr; ··· 811 699 return 0; 812 700 } 813 701 702 + static u64 normalize_addr_df4p5_np2(struct addr_ctx *ctx, struct df4p5_denorm_ctx *denorm_ctx, 703 + u64 addr) 704 + { 705 + u64 temp_addr_a = 0, temp_addr_b = 0; 706 + 707 + switch (ctx->map.intlv_mode) { 708 + case DF4p5_NPS0_24CHAN_1K_HASH: 709 + case DF4p5_NPS1_12CHAN_1K_HASH: 710 + case DF4p5_NPS2_6CHAN_1K_HASH: 711 + case DF4p5_NPS4_3CHAN_1K_HASH: 712 + case DF4p5_NPS1_10CHAN_1K_HASH: 713 + case DF4p5_NPS2_5CHAN_1K_HASH: 714 + temp_addr_a = FIELD_GET(GENMASK_ULL(11, 10), addr) << 8; 715 + break; 716 + 717 + case DF4p5_NPS0_24CHAN_2K_HASH: 718 + case DF4p5_NPS1_12CHAN_2K_HASH: 719 + case DF4p5_NPS2_6CHAN_2K_HASH: 720 + case DF4p5_NPS4_3CHAN_2K_HASH: 721 + case DF4p5_NPS1_10CHAN_2K_HASH: 722 + case DF4p5_NPS2_5CHAN_2K_HASH: 723 + temp_addr_a = FIELD_GET(GENMASK_ULL(11, 9), addr) << 8; 724 + break; 725 + 726 + default: 727 + atl_debug_on_bad_intlv_mode(ctx); 728 + return 0; 729 + } 730 + 731 + switch (ctx->map.intlv_mode) { 732 + case DF4p5_NPS0_24CHAN_1K_HASH: 733 + temp_addr_b = FIELD_GET(GENMASK_ULL(63, 13), addr) / denorm_ctx->mod_value; 734 + temp_addr_b <<= 10; 735 + break; 736 + 737 + case DF4p5_NPS0_24CHAN_2K_HASH: 738 + temp_addr_b = FIELD_GET(GENMASK_ULL(63, 14), addr) / denorm_ctx->mod_value; 739 + temp_addr_b <<= 11; 740 + break; 741 + 742 + case DF4p5_NPS1_12CHAN_1K_HASH: 743 + temp_addr_b = FIELD_GET(GENMASK_ULL(63, 12), addr) / denorm_ctx->mod_value; 744 + temp_addr_b <<= 10; 745 + break; 746 + 747 + case DF4p5_NPS1_12CHAN_2K_HASH: 748 + temp_addr_b = FIELD_GET(GENMASK_ULL(63, 13), addr) / denorm_ctx->mod_value; 749 + temp_addr_b <<= 11; 750 + break; 751 + 752 + case DF4p5_NPS2_6CHAN_1K_HASH: 753 + case DF4p5_NPS1_10CHAN_1K_HASH: 754 + temp_addr_b = FIELD_GET(GENMASK_ULL(63, 12), addr) << 1; 755 + temp_addr_b |= FIELD_GET(BIT_ULL(9), addr); 756 + temp_addr_b /= denorm_ctx->mod_value; 757 + temp_addr_b <<= 10; 758 + break; 759 + 760 + case DF4p5_NPS2_6CHAN_2K_HASH: 761 + case DF4p5_NPS1_10CHAN_2K_HASH: 762 + temp_addr_b = FIELD_GET(GENMASK_ULL(63, 12), addr) / denorm_ctx->mod_value; 763 + temp_addr_b <<= 11; 764 + break; 765 + 766 + case DF4p5_NPS4_3CHAN_1K_HASH: 767 + case DF4p5_NPS2_5CHAN_1K_HASH: 768 + temp_addr_b = FIELD_GET(GENMASK_ULL(63, 12), addr) << 2; 769 + temp_addr_b |= FIELD_GET(GENMASK_ULL(9, 8), addr); 770 + temp_addr_b /= denorm_ctx->mod_value; 771 + temp_addr_b <<= 10; 772 + break; 773 + 774 + case DF4p5_NPS4_3CHAN_2K_HASH: 775 + case DF4p5_NPS2_5CHAN_2K_HASH: 776 + temp_addr_b = FIELD_GET(GENMASK_ULL(63, 12), addr) << 1; 777 + temp_addr_b |= FIELD_GET(BIT_ULL(8), addr); 778 + temp_addr_b /= denorm_ctx->mod_value; 779 + temp_addr_b <<= 11; 780 + break; 781 + 782 + default: 783 + atl_debug_on_bad_intlv_mode(ctx); 784 + return 0; 785 + } 786 + 787 + return denorm_ctx->base_denorm_addr | temp_addr_a | temp_addr_b; 788 + } 789 + 790 + static void recalculate_hashed_bits_df4p5_np2(struct addr_ctx *ctx, 791 + struct df4p5_denorm_ctx *denorm_ctx) 792 + { 793 + bool hash_ctl_64k, hash_ctl_2M, hash_ctl_1G, hash_ctl_1T, hashed_bit; 794 + 795 + if (!denorm_ctx->rehash_vector) 796 + return; 797 + 798 + hash_ctl_64k = FIELD_GET(DF4_HASH_CTL_64K, ctx->map.ctl); 799 + hash_ctl_2M = FIELD_GET(DF4_HASH_CTL_2M, ctx->map.ctl); 800 + hash_ctl_1G = FIELD_GET(DF4_HASH_CTL_1G, ctx->map.ctl); 801 + hash_ctl_1T = FIELD_GET(DF4p5_HASH_CTL_1T, ctx->map.ctl); 802 + 803 + if (denorm_ctx->rehash_vector & BIT_ULL(8)) { 804 + hashed_bit = FIELD_GET(BIT_ULL(8), denorm_ctx->current_spa); 805 + hashed_bit ^= FIELD_GET(BIT_ULL(14), denorm_ctx->current_spa); 806 + hashed_bit ^= FIELD_GET(BIT_ULL(16), denorm_ctx->current_spa) & hash_ctl_64k; 807 + hashed_bit ^= FIELD_GET(BIT_ULL(21), denorm_ctx->current_spa) & hash_ctl_2M; 808 + hashed_bit ^= FIELD_GET(BIT_ULL(30), denorm_ctx->current_spa) & hash_ctl_1G; 809 + hashed_bit ^= FIELD_GET(BIT_ULL(40), denorm_ctx->current_spa) & hash_ctl_1T; 810 + 811 + if (FIELD_GET(BIT_ULL(8), denorm_ctx->current_spa) != hashed_bit) 812 + denorm_ctx->current_spa ^= BIT_ULL(8); 813 + } 814 + 815 + if (denorm_ctx->rehash_vector & BIT_ULL(9)) { 816 + hashed_bit = FIELD_GET(BIT_ULL(9), denorm_ctx->current_spa); 817 + hashed_bit ^= FIELD_GET(BIT_ULL(17), denorm_ctx->current_spa) & hash_ctl_64k; 818 + hashed_bit ^= FIELD_GET(BIT_ULL(22), denorm_ctx->current_spa) & hash_ctl_2M; 819 + hashed_bit ^= FIELD_GET(BIT_ULL(31), denorm_ctx->current_spa) & hash_ctl_1G; 820 + hashed_bit ^= FIELD_GET(BIT_ULL(41), denorm_ctx->current_spa) & hash_ctl_1T; 821 + 822 + if (FIELD_GET(BIT_ULL(9), denorm_ctx->current_spa) != hashed_bit) 823 + denorm_ctx->current_spa ^= BIT_ULL(9); 824 + } 825 + 826 + if (denorm_ctx->rehash_vector & BIT_ULL(12)) { 827 + hashed_bit = FIELD_GET(BIT_ULL(12), denorm_ctx->current_spa); 828 + hashed_bit ^= FIELD_GET(BIT_ULL(18), denorm_ctx->current_spa) & hash_ctl_64k; 829 + hashed_bit ^= FIELD_GET(BIT_ULL(23), denorm_ctx->current_spa) & hash_ctl_2M; 830 + hashed_bit ^= FIELD_GET(BIT_ULL(32), denorm_ctx->current_spa) & hash_ctl_1G; 831 + hashed_bit ^= FIELD_GET(BIT_ULL(42), denorm_ctx->current_spa) & hash_ctl_1T; 832 + 833 + if (FIELD_GET(BIT_ULL(12), denorm_ctx->current_spa) != hashed_bit) 834 + denorm_ctx->current_spa ^= BIT_ULL(12); 835 + } 836 + 837 + if (denorm_ctx->rehash_vector & BIT_ULL(13)) { 838 + hashed_bit = FIELD_GET(BIT_ULL(13), denorm_ctx->current_spa); 839 + hashed_bit ^= FIELD_GET(BIT_ULL(19), denorm_ctx->current_spa) & hash_ctl_64k; 840 + hashed_bit ^= FIELD_GET(BIT_ULL(24), denorm_ctx->current_spa) & hash_ctl_2M; 841 + hashed_bit ^= FIELD_GET(BIT_ULL(33), denorm_ctx->current_spa) & hash_ctl_1G; 842 + hashed_bit ^= FIELD_GET(BIT_ULL(43), denorm_ctx->current_spa) & hash_ctl_1T; 843 + 844 + if (FIELD_GET(BIT_ULL(13), denorm_ctx->current_spa) != hashed_bit) 845 + denorm_ctx->current_spa ^= BIT_ULL(13); 846 + } 847 + } 848 + 849 + static bool match_logical_coh_st_fabric_id(struct addr_ctx *ctx, 850 + struct df4p5_denorm_ctx *denorm_ctx) 851 + { 852 + /* 853 + * The logical CS fabric ID of the permutation must be calculated from the 854 + * current SPA with the base and with the MMIO hole. 855 + */ 856 + u16 id = get_logical_coh_st_fabric_id_for_current_spa(ctx, denorm_ctx); 857 + 858 + atl_debug(ctx, "Checking calculated logical coherent station fabric id:\n"); 859 + atl_debug(ctx, " calculated fabric id = 0x%x\n", id); 860 + atl_debug(ctx, " expected fabric id = 0x%x\n", denorm_ctx->coh_st_fabric_id); 861 + 862 + return denorm_ctx->coh_st_fabric_id == id; 863 + } 864 + 865 + static bool match_norm_addr(struct addr_ctx *ctx, struct df4p5_denorm_ctx *denorm_ctx) 866 + { 867 + u64 addr = remove_base_and_hole(ctx, denorm_ctx->current_spa); 868 + 869 + /* 870 + * The normalized address must be calculated with the current SPA without 871 + * the base and without the MMIO hole. 872 + */ 873 + addr = normalize_addr_df4p5_np2(ctx, denorm_ctx, addr); 874 + 875 + atl_debug(ctx, "Checking calculated normalized address:\n"); 876 + atl_debug(ctx, " calculated normalized addr = 0x%016llx\n", addr); 877 + atl_debug(ctx, " expected normalized addr = 0x%016llx\n", ctx->ret_addr); 878 + 879 + return addr == ctx->ret_addr; 880 + } 881 + 882 + static int check_permutations(struct addr_ctx *ctx, struct df4p5_denorm_ctx *denorm_ctx) 883 + { 884 + u64 test_perm, temp_addr, denorm_addr, num_perms; 885 + unsigned int dropped_remainder; 886 + 887 + denorm_ctx->div_addr *= denorm_ctx->mod_value; 888 + 889 + /* 890 + * The high order bits of num_permutations represent the permutations 891 + * of the dropped remainder. This will be either 0-3 or 0-5 depending 892 + * on the interleave mode. The low order bits represent the 893 + * permutations of other "lost" bits which will be any combination of 894 + * 1, 2, or 3 bits depending on the interleave mode. 895 + */ 896 + num_perms = denorm_ctx->mod_value << denorm_ctx->perm_shift; 897 + 898 + for (test_perm = 0; test_perm < num_perms; test_perm++) { 899 + denorm_addr = denorm_ctx->base_denorm_addr; 900 + dropped_remainder = test_perm >> denorm_ctx->perm_shift; 901 + temp_addr = denorm_ctx->div_addr + dropped_remainder; 902 + 903 + switch (ctx->map.intlv_mode) { 904 + case DF4p5_NPS0_24CHAN_2K_HASH: 905 + denorm_addr |= temp_addr << 14; 906 + break; 907 + 908 + case DF4p5_NPS0_24CHAN_1K_HASH: 909 + case DF4p5_NPS1_12CHAN_2K_HASH: 910 + denorm_addr |= temp_addr << 13; 911 + break; 912 + 913 + case DF4p5_NPS1_12CHAN_1K_HASH: 914 + case DF4p5_NPS2_6CHAN_2K_HASH: 915 + case DF4p5_NPS1_10CHAN_2K_HASH: 916 + denorm_addr |= temp_addr << 12; 917 + break; 918 + 919 + case DF4p5_NPS2_6CHAN_1K_HASH: 920 + case DF4p5_NPS1_10CHAN_1K_HASH: 921 + denorm_addr |= FIELD_GET(BIT_ULL(0), temp_addr) << 9; 922 + denorm_addr |= FIELD_GET(GENMASK_ULL(63, 1), temp_addr) << 12; 923 + break; 924 + 925 + case DF4p5_NPS4_3CHAN_1K_HASH: 926 + case DF4p5_NPS2_5CHAN_1K_HASH: 927 + denorm_addr |= FIELD_GET(GENMASK_ULL(1, 0), temp_addr) << 8; 928 + denorm_addr |= FIELD_GET(GENMASK_ULL(63, 2), (temp_addr)) << 12; 929 + break; 930 + 931 + case DF4p5_NPS4_3CHAN_2K_HASH: 932 + case DF4p5_NPS2_5CHAN_2K_HASH: 933 + denorm_addr |= FIELD_GET(BIT_ULL(0), temp_addr) << 8; 934 + denorm_addr |= FIELD_GET(GENMASK_ULL(63, 1), temp_addr) << 12; 935 + break; 936 + 937 + default: 938 + atl_debug_on_bad_intlv_mode(ctx); 939 + return -EINVAL; 940 + } 941 + 942 + switch (ctx->map.intlv_mode) { 943 + case DF4p5_NPS0_24CHAN_1K_HASH: 944 + denorm_addr |= FIELD_GET(BIT_ULL(0), test_perm) << 8; 945 + denorm_addr |= FIELD_GET(BIT_ULL(1), test_perm) << 9; 946 + denorm_addr |= FIELD_GET(BIT_ULL(2), test_perm) << 12; 947 + break; 948 + 949 + case DF4p5_NPS0_24CHAN_2K_HASH: 950 + denorm_addr |= FIELD_GET(BIT_ULL(0), test_perm) << 8; 951 + denorm_addr |= FIELD_GET(BIT_ULL(1), test_perm) << 12; 952 + denorm_addr |= FIELD_GET(BIT_ULL(2), test_perm) << 13; 953 + break; 954 + 955 + case DF4p5_NPS1_12CHAN_2K_HASH: 956 + denorm_addr |= FIELD_GET(BIT_ULL(0), test_perm) << 8; 957 + denorm_addr |= FIELD_GET(BIT_ULL(1), test_perm) << 12; 958 + break; 959 + 960 + case DF4p5_NPS1_12CHAN_1K_HASH: 961 + case DF4p5_NPS4_3CHAN_1K_HASH: 962 + case DF4p5_NPS2_5CHAN_1K_HASH: 963 + denorm_addr |= FIELD_GET(BIT_ULL(0), test_perm) << 8; 964 + denorm_addr |= FIELD_GET(BIT_ULL(1), test_perm) << 9; 965 + break; 966 + 967 + case DF4p5_NPS2_6CHAN_1K_HASH: 968 + case DF4p5_NPS2_6CHAN_2K_HASH: 969 + case DF4p5_NPS4_3CHAN_2K_HASH: 970 + case DF4p5_NPS1_10CHAN_1K_HASH: 971 + case DF4p5_NPS1_10CHAN_2K_HASH: 972 + case DF4p5_NPS2_5CHAN_2K_HASH: 973 + denorm_addr |= FIELD_GET(BIT_ULL(0), test_perm) << 8; 974 + break; 975 + 976 + default: 977 + atl_debug_on_bad_intlv_mode(ctx); 978 + return -EINVAL; 979 + } 980 + 981 + denorm_ctx->current_spa = add_base_and_hole(ctx, denorm_addr); 982 + recalculate_hashed_bits_df4p5_np2(ctx, denorm_ctx); 983 + 984 + atl_debug(ctx, "Checking potential system physical address 0x%016llx\n", 985 + denorm_ctx->current_spa); 986 + 987 + if (!match_logical_coh_st_fabric_id(ctx, denorm_ctx)) 988 + continue; 989 + 990 + if (!match_norm_addr(ctx, denorm_ctx)) 991 + continue; 992 + 993 + if (denorm_ctx->resolved_spa == INVALID_SPA || 994 + denorm_ctx->current_spa > denorm_ctx->resolved_spa) 995 + denorm_ctx->resolved_spa = denorm_ctx->current_spa; 996 + } 997 + 998 + if (denorm_ctx->resolved_spa == INVALID_SPA) { 999 + atl_debug(ctx, "Failed to find valid SPA for normalized address 0x%016llx\n", 1000 + ctx->ret_addr); 1001 + return -EINVAL; 1002 + } 1003 + 1004 + /* Return the resolved SPA without the base, without the MMIO hole */ 1005 + ctx->ret_addr = remove_base_and_hole(ctx, denorm_ctx->resolved_spa); 1006 + 1007 + return 0; 1008 + } 1009 + 1010 + static int init_df4p5_denorm_ctx(struct addr_ctx *ctx, struct df4p5_denorm_ctx *denorm_ctx) 1011 + { 1012 + denorm_ctx->current_spa = INVALID_SPA; 1013 + denorm_ctx->resolved_spa = INVALID_SPA; 1014 + 1015 + switch (ctx->map.intlv_mode) { 1016 + case DF4p5_NPS0_24CHAN_1K_HASH: 1017 + denorm_ctx->perm_shift = 3; 1018 + denorm_ctx->rehash_vector = BIT(8) | BIT(9) | BIT(12); 1019 + break; 1020 + 1021 + case DF4p5_NPS0_24CHAN_2K_HASH: 1022 + denorm_ctx->perm_shift = 3; 1023 + denorm_ctx->rehash_vector = BIT(8) | BIT(12) | BIT(13); 1024 + break; 1025 + 1026 + case DF4p5_NPS1_12CHAN_1K_HASH: 1027 + denorm_ctx->perm_shift = 2; 1028 + denorm_ctx->rehash_vector = BIT(8); 1029 + break; 1030 + 1031 + case DF4p5_NPS1_12CHAN_2K_HASH: 1032 + denorm_ctx->perm_shift = 2; 1033 + denorm_ctx->rehash_vector = BIT(8) | BIT(12); 1034 + break; 1035 + 1036 + case DF4p5_NPS2_6CHAN_1K_HASH: 1037 + case DF4p5_NPS2_6CHAN_2K_HASH: 1038 + case DF4p5_NPS1_10CHAN_1K_HASH: 1039 + case DF4p5_NPS1_10CHAN_2K_HASH: 1040 + denorm_ctx->perm_shift = 1; 1041 + denorm_ctx->rehash_vector = BIT(8); 1042 + break; 1043 + 1044 + case DF4p5_NPS4_3CHAN_1K_HASH: 1045 + case DF4p5_NPS2_5CHAN_1K_HASH: 1046 + denorm_ctx->perm_shift = 2; 1047 + denorm_ctx->rehash_vector = 0; 1048 + break; 1049 + 1050 + case DF4p5_NPS4_3CHAN_2K_HASH: 1051 + case DF4p5_NPS2_5CHAN_2K_HASH: 1052 + denorm_ctx->perm_shift = 1; 1053 + denorm_ctx->rehash_vector = 0; 1054 + break; 1055 + 1056 + default: 1057 + atl_debug_on_bad_intlv_mode(ctx); 1058 + return -EINVAL; 1059 + } 1060 + 1061 + denorm_ctx->base_denorm_addr = FIELD_GET(GENMASK_ULL(7, 0), ctx->ret_addr); 1062 + 1063 + switch (ctx->map.intlv_mode) { 1064 + case DF4p5_NPS0_24CHAN_1K_HASH: 1065 + case DF4p5_NPS1_12CHAN_1K_HASH: 1066 + case DF4p5_NPS2_6CHAN_1K_HASH: 1067 + case DF4p5_NPS4_3CHAN_1K_HASH: 1068 + case DF4p5_NPS1_10CHAN_1K_HASH: 1069 + case DF4p5_NPS2_5CHAN_1K_HASH: 1070 + denorm_ctx->base_denorm_addr |= FIELD_GET(GENMASK_ULL(9, 8), ctx->ret_addr) << 10; 1071 + denorm_ctx->div_addr = FIELD_GET(GENMASK_ULL(63, 10), ctx->ret_addr); 1072 + break; 1073 + 1074 + case DF4p5_NPS0_24CHAN_2K_HASH: 1075 + case DF4p5_NPS1_12CHAN_2K_HASH: 1076 + case DF4p5_NPS2_6CHAN_2K_HASH: 1077 + case DF4p5_NPS4_3CHAN_2K_HASH: 1078 + case DF4p5_NPS1_10CHAN_2K_HASH: 1079 + case DF4p5_NPS2_5CHAN_2K_HASH: 1080 + denorm_ctx->base_denorm_addr |= FIELD_GET(GENMASK_ULL(10, 8), ctx->ret_addr) << 9; 1081 + denorm_ctx->div_addr = FIELD_GET(GENMASK_ULL(63, 11), ctx->ret_addr); 1082 + break; 1083 + 1084 + default: 1085 + atl_debug_on_bad_intlv_mode(ctx); 1086 + return -EINVAL; 1087 + } 1088 + 1089 + if (ctx->map.num_intlv_chan % 3 == 0) 1090 + denorm_ctx->mod_value = 3; 1091 + else 1092 + denorm_ctx->mod_value = 5; 1093 + 1094 + denorm_ctx->coh_st_fabric_id = get_logical_coh_st_fabric_id(ctx) - get_dst_fabric_id(ctx); 1095 + 1096 + atl_debug(ctx, "Initialized df4p5_denorm_ctx:"); 1097 + atl_debug(ctx, " mod_value = %d", denorm_ctx->mod_value); 1098 + atl_debug(ctx, " perm_shift = %d", denorm_ctx->perm_shift); 1099 + atl_debug(ctx, " rehash_vector = 0x%x", denorm_ctx->rehash_vector); 1100 + atl_debug(ctx, " base_denorm_addr = 0x%016llx", denorm_ctx->base_denorm_addr); 1101 + atl_debug(ctx, " div_addr = 0x%016llx", denorm_ctx->div_addr); 1102 + atl_debug(ctx, " coh_st_fabric_id = 0x%x", denorm_ctx->coh_st_fabric_id); 1103 + 1104 + return 0; 1105 + } 1106 + 1107 + /* 1108 + * For DF 4.5, parts of the physical address can be directly pulled from the 1109 + * normalized address. The exact bits will differ between interleave modes, but 1110 + * using NPS0_24CHAN_1K_HASH as an example, the normalized address consists of 1111 + * bits [63:13] (divided by 3), bits [11:10], and bits [7:0] of the system 1112 + * physical address. 1113 + * 1114 + * In this case, there is no way to reconstruct the missing bits (bits 8, 9, 1115 + * and 12) from the normalized address. Additionally, when bits [63:13] are 1116 + * divided by 3, the remainder is dropped. Determine the proper combination of 1117 + * "lost" bits and dropped remainder by iterating through each possible 1118 + * permutation of these bits and then normalizing the generated system physical 1119 + * addresses. If the normalized address matches the address we are trying to 1120 + * translate, then we have found the correct permutation of bits. 1121 + */ 1122 + static int denorm_addr_df4p5_np2(struct addr_ctx *ctx) 1123 + { 1124 + struct df4p5_denorm_ctx denorm_ctx; 1125 + int ret = 0; 1126 + 1127 + memset(&denorm_ctx, 0, sizeof(denorm_ctx)); 1128 + 1129 + atl_debug(ctx, "Denormalizing DF 4.5 normalized address 0x%016llx", ctx->ret_addr); 1130 + 1131 + ret = init_df4p5_denorm_ctx(ctx, &denorm_ctx); 1132 + if (ret) 1133 + return ret; 1134 + 1135 + return check_permutations(ctx, &denorm_ctx); 1136 + } 1137 + 814 1138 int denormalize_address(struct addr_ctx *ctx) 815 1139 { 816 1140 switch (ctx->map.intlv_mode) { ··· 1258 710 case DF4_NPS2_5CHAN_HASH: 1259 711 case DF4_NPS1_10CHAN_HASH: 1260 712 return denorm_addr_df4_np2(ctx); 713 + case DF4p5_NPS0_24CHAN_1K_HASH: 714 + case DF4p5_NPS4_3CHAN_1K_HASH: 715 + case DF4p5_NPS2_6CHAN_1K_HASH: 716 + case DF4p5_NPS1_12CHAN_1K_HASH: 717 + case DF4p5_NPS2_5CHAN_1K_HASH: 718 + case DF4p5_NPS1_10CHAN_1K_HASH: 719 + case DF4p5_NPS4_3CHAN_2K_HASH: 720 + case DF4p5_NPS2_6CHAN_2K_HASH: 721 + case DF4p5_NPS1_12CHAN_2K_HASH: 722 + case DF4p5_NPS0_24CHAN_2K_HASH: 723 + case DF4p5_NPS2_5CHAN_2K_HASH: 724 + case DF4p5_NPS1_10CHAN_2K_HASH: 725 + return denorm_addr_df4p5_np2(ctx); 1261 726 case DF3_6CHAN: 1262 727 return denorm_addr_df3_6chan(ctx); 1263 728 default:
+48
drivers/ras/amd/atl/internal.h
··· 21 21 22 22 #include "reg_fields.h" 23 23 24 + #undef pr_fmt 25 + #define pr_fmt(fmt) "amd_atl: " fmt 26 + 24 27 /* Maximum possible number of Coherent Stations within a single Data Fabric. */ 25 28 #define MAX_COH_ST_CHANNELS 32 26 29 ··· 36 33 /* Shift needed for adjusting register values to true values. */ 37 34 #define DF_DRAM_BASE_LIMIT_LSB 28 38 35 #define MI300_DRAM_LIMIT_LSB 20 36 + 37 + #define INVALID_SPA ~0ULL 39 38 40 39 enum df_revisions { 41 40 UNKNOWN, ··· 95 90 DF4p5_NPS1_10CHAN_2K_HASH = 0x49, 96 91 }; 97 92 93 + struct df4p5_denorm_ctx { 94 + /* Indicates the number of "lost" bits. This will be 1, 2, or 3. */ 95 + u8 perm_shift; 96 + 97 + /* A mask indicating the bits that need to be rehashed. */ 98 + u16 rehash_vector; 99 + 100 + /* 101 + * Represents the value that the high bits of the normalized address 102 + * are divided by during normalization. This value will be 3 for 103 + * interleave modes with a number of channels divisible by 3 or the 104 + * value will be 5 for interleave modes with a number of channels 105 + * divisible by 5. Power-of-two interleave modes are handled 106 + * separately. 107 + */ 108 + u8 mod_value; 109 + 110 + /* 111 + * Represents the bits that can be directly pulled from the normalized 112 + * address. In each case, pass through bits [7:0] of the normalized 113 + * address. The other bits depend on the interleave bit position which 114 + * will be bit 10 for 1K interleave stripe cases and bit 11 for 2K 115 + * interleave stripe cases. 116 + */ 117 + u64 base_denorm_addr; 118 + 119 + /* 120 + * Represents the high bits of the physical address that have been 121 + * divided by the mod_value. 122 + */ 123 + u64 div_addr; 124 + 125 + u64 current_spa; 126 + u64 resolved_spa; 127 + 128 + u16 coh_st_fabric_id; 129 + }; 130 + 98 131 struct df_flags { 99 132 __u8 legacy_ficaa : 1, 100 133 socket_id_shift_quirk : 1, ··· 174 131 175 132 /* Number of DRAM Address maps visible in a Coherent Station. */ 176 133 u8 num_coh_st_maps; 134 + 135 + u32 dram_hole_base; 177 136 178 137 /* Global flags to handle special cases. */ 179 138 struct df_flags flags; ··· 278 233 279 234 unsigned long norm_to_sys_addr(u8 socket_id, u8 die_id, u8 coh_st_inst_id, unsigned long addr); 280 235 unsigned long convert_umc_mca_addr_to_sys_addr(struct atl_err *err); 236 + 237 + u64 add_base_and_hole(struct addr_ctx *ctx, u64 addr); 238 + u64 remove_base_and_hole(struct addr_ctx *ctx, u64 addr); 281 239 282 240 /* 283 241 * Make a gap in @data that is @num_bits long starting at @bit_num.
+97
drivers/ras/amd/atl/map.c
··· 642 642 return 0; 643 643 } 644 644 645 + /* 646 + * Verify the interleave bits are correct in the different interleaving 647 + * settings. 648 + * 649 + * If @num_intlv_dies and/or @num_intlv_sockets are 1, it means the 650 + * respective interleaving is disabled. 651 + */ 652 + static inline bool map_bits_valid(struct addr_ctx *ctx, u8 bit1, u8 bit2, 653 + u8 num_intlv_dies, u8 num_intlv_sockets) 654 + { 655 + if (!(ctx->map.intlv_bit_pos == bit1 || ctx->map.intlv_bit_pos == bit2)) { 656 + pr_debug("Invalid interleave bit: %u", ctx->map.intlv_bit_pos); 657 + return false; 658 + } 659 + 660 + if (ctx->map.num_intlv_dies > num_intlv_dies) { 661 + pr_debug("Invalid number of interleave dies: %u", ctx->map.num_intlv_dies); 662 + return false; 663 + } 664 + 665 + if (ctx->map.num_intlv_sockets > num_intlv_sockets) { 666 + pr_debug("Invalid number of interleave sockets: %u", ctx->map.num_intlv_sockets); 667 + return false; 668 + } 669 + 670 + return true; 671 + } 672 + 673 + static int validate_address_map(struct addr_ctx *ctx) 674 + { 675 + switch (ctx->map.intlv_mode) { 676 + case DF2_2CHAN_HASH: 677 + case DF3_COD4_2CHAN_HASH: 678 + case DF3_COD2_4CHAN_HASH: 679 + case DF3_COD1_8CHAN_HASH: 680 + if (!map_bits_valid(ctx, 8, 9, 1, 1)) 681 + goto err; 682 + break; 683 + 684 + case DF4_NPS4_2CHAN_HASH: 685 + case DF4_NPS2_4CHAN_HASH: 686 + case DF4_NPS1_8CHAN_HASH: 687 + case DF4p5_NPS4_2CHAN_1K_HASH: 688 + case DF4p5_NPS4_2CHAN_2K_HASH: 689 + case DF4p5_NPS2_4CHAN_1K_HASH: 690 + case DF4p5_NPS2_4CHAN_2K_HASH: 691 + case DF4p5_NPS1_8CHAN_1K_HASH: 692 + case DF4p5_NPS1_8CHAN_2K_HASH: 693 + case DF4p5_NPS1_16CHAN_1K_HASH: 694 + case DF4p5_NPS1_16CHAN_2K_HASH: 695 + if (!map_bits_valid(ctx, 8, 8, 1, 2)) 696 + goto err; 697 + break; 698 + 699 + case DF4p5_NPS4_3CHAN_1K_HASH: 700 + case DF4p5_NPS4_3CHAN_2K_HASH: 701 + case DF4p5_NPS2_5CHAN_1K_HASH: 702 + case DF4p5_NPS2_5CHAN_2K_HASH: 703 + case DF4p5_NPS2_6CHAN_1K_HASH: 704 + case DF4p5_NPS2_6CHAN_2K_HASH: 705 + case DF4p5_NPS1_10CHAN_1K_HASH: 706 + case DF4p5_NPS1_10CHAN_2K_HASH: 707 + case DF4p5_NPS1_12CHAN_1K_HASH: 708 + case DF4p5_NPS1_12CHAN_2K_HASH: 709 + if (ctx->map.num_intlv_sockets != 1 || !map_bits_valid(ctx, 8, 0, 1, 1)) 710 + goto err; 711 + break; 712 + 713 + case DF4p5_NPS0_24CHAN_1K_HASH: 714 + case DF4p5_NPS0_24CHAN_2K_HASH: 715 + if (ctx->map.num_intlv_sockets < 2 || !map_bits_valid(ctx, 8, 0, 1, 2)) 716 + goto err; 717 + break; 718 + 719 + case MI3_HASH_8CHAN: 720 + case MI3_HASH_16CHAN: 721 + case MI3_HASH_32CHAN: 722 + if (!map_bits_valid(ctx, 8, 8, 4, 1)) 723 + goto err; 724 + break; 725 + 726 + /* Nothing to do for modes that don't need special validation checks. */ 727 + default: 728 + break; 729 + } 730 + 731 + return 0; 732 + 733 + err: 734 + atl_debug(ctx, "Inconsistent address map"); 735 + return -EINVAL; 736 + } 737 + 645 738 static void dump_address_map(struct dram_addr_map *map) 646 739 { 647 740 u8 i; ··· 770 677 return ret; 771 678 772 679 dump_address_map(&ctx->map); 680 + 681 + ret = validate_address_map(ctx); 682 + if (ret) 683 + return ret; 773 684 774 685 return ret; 775 686 }
+20 -1
drivers/ras/amd/atl/system.c
··· 223 223 return -EINVAL; 224 224 } 225 225 226 + static int get_dram_hole_base(void) 227 + { 228 + u8 func = 0; 229 + 230 + if (df_cfg.rev >= DF4) 231 + func = 7; 232 + 233 + if (df_indirect_read_broadcast(0, func, 0x104, &df_cfg.dram_hole_base)) 234 + return -EINVAL; 235 + 236 + df_cfg.dram_hole_base &= DF_DRAM_HOLE_BASE_MASK; 237 + 238 + return 0; 239 + } 240 + 226 241 static void get_num_maps(void) 227 242 { 228 243 switch (df_cfg.rev) { ··· 281 266 282 267 pr_debug("num_coh_st_maps=%u", df_cfg.num_coh_st_maps); 283 268 269 + pr_debug("dram_hole_base=0x%x", df_cfg.dram_hole_base); 284 270 pr_debug("flags.legacy_ficaa=%u", df_cfg.flags.legacy_ficaa); 285 271 pr_debug("flags.socket_id_shift_quirk=%u", df_cfg.flags.socket_id_shift_quirk); 286 272 } ··· 289 273 int get_df_system_info(void) 290 274 { 291 275 if (determine_df_rev()) { 292 - pr_warn("amd_atl: Failed to determine DF Revision"); 276 + pr_warn("Failed to determine DF Revision"); 293 277 df_cfg.rev = UNKNOWN; 294 278 return -EINVAL; 295 279 } ··· 297 281 apply_node_id_shift(); 298 282 299 283 get_num_maps(); 284 + 285 + if (get_dram_hole_base()) 286 + pr_warn("Failed to read DRAM hole base"); 300 287 301 288 dump_df_cfg(); 302 289
+2 -2
drivers/ras/amd/fmpm.c
··· 56 56 57 57 #include "../debugfs.h" 58 58 59 + #include "atl/internal.h" 60 + 59 61 #define INVALID_CPU UINT_MAX 60 62 61 63 /* Validation Bits */ ··· 117 115 118 116 /* system physical addresses array */ 119 117 static u64 *spa_entries; 120 - 121 - #define INVALID_SPA ~0ULL 122 118 123 119 static struct dentry *fmpm_dfs_dir; 124 120 static struct dentry *fmpm_dfs_entries;