^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Shared code by both skx_edac and i10nm_edac. Originally split out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * from the skx_edac driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * This file is linked into both skx_edac and i10nm_edac drivers. In
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * order to avoid link errors, this file must be like a pure library
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * without including symbols and defines which would otherwise conflict,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * when linked once into a module and into a built-in object, at the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * same time. For example, __this_module symbol references when that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * file is being linked into a built-in object.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * Copyright (c) 2018, Intel Corporation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/acpi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/dmi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/adxl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <acpi/nfit.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <asm/mce.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include "edac_module.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include "skx_common.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) static const char * const component_names[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) [INDEX_SOCKET] = "ProcessorSocketId",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) [INDEX_MEMCTRL] = "MemoryControllerId",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) [INDEX_CHANNEL] = "ChannelId",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) [INDEX_DIMM] = "DimmSlotId",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) static int component_indices[ARRAY_SIZE(component_names)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) static int adxl_component_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) static const char * const *adxl_component_names;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) static u64 *adxl_values;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) static char *adxl_msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) static char skx_msg[MSG_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) static skx_decode_f skx_decode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) static skx_show_retry_log_f skx_show_retry_rd_err_log;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) static u64 skx_tolm, skx_tohm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) static LIST_HEAD(dev_edac_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) int __init skx_adxl_get(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) const char * const *names;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) names = adxl_get_component_names();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) if (!names) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) skx_printk(KERN_NOTICE, "No firmware support for address translation.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) for (i = 0; i < INDEX_MAX; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) for (j = 0; names[j]; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) if (!strcmp(component_names[i], names[j])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) component_indices[i] = j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) if (!names[j])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) adxl_component_names = names;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) while (*names++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) adxl_component_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) adxl_values = kcalloc(adxl_component_count, sizeof(*adxl_values),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) if (!adxl_values) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) adxl_component_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) adxl_msg = kzalloc(MSG_SIZE, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) if (!adxl_msg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) adxl_component_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) kfree(adxl_values);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) skx_printk(KERN_ERR, "'%s' is not matched from DSM parameters: ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) component_names[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) for (j = 0; names[j]; j++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) skx_printk(KERN_CONT, "%s ", names[j]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) skx_printk(KERN_CONT, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) void __exit skx_adxl_put(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) kfree(adxl_values);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) kfree(adxl_msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) static bool skx_adxl_decode(struct decoded_addr *res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) struct skx_dev *d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) int i, len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) if (res->addr >= skx_tohm || (res->addr >= skx_tolm &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) res->addr < BIT_ULL(32))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) edac_dbg(0, "Address 0x%llx out of range\n", res->addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) if (adxl_decode(res->addr, adxl_values)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) edac_dbg(0, "Failed to decode 0x%llx\n", res->addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) res->socket = (int)adxl_values[component_indices[INDEX_SOCKET]];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) res->imc = (int)adxl_values[component_indices[INDEX_MEMCTRL]];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) res->channel = (int)adxl_values[component_indices[INDEX_CHANNEL]];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) res->dimm = (int)adxl_values[component_indices[INDEX_DIMM]];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) if (res->imc > NUM_IMC - 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) skx_printk(KERN_ERR, "Bad imc %d\n", res->imc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) list_for_each_entry(d, &dev_edac_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) if (d->imc[0].src_id == res->socket) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) res->dev = d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) if (!res->dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) skx_printk(KERN_ERR, "No device for src_id %d imc %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) res->socket, res->imc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) for (i = 0; i < adxl_component_count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) if (adxl_values[i] == ~0x0ull)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) len += snprintf(adxl_msg + len, MSG_SIZE - len, " %s:0x%llx",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) adxl_component_names[i], adxl_values[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) if (MSG_SIZE - len <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) void skx_set_decode(skx_decode_f decode, skx_show_retry_log_f show_retry_log)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) skx_decode = decode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) skx_show_retry_rd_err_log = show_retry_log;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) int skx_get_src_id(struct skx_dev *d, int off, u8 *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) if (pci_read_config_dword(d->util_all, off, ®)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) skx_printk(KERN_ERR, "Failed to read src id\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) *id = GET_BITFIELD(reg, 12, 14);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) int skx_get_node_id(struct skx_dev *d, u8 *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) if (pci_read_config_dword(d->util_all, 0xf4, ®)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) skx_printk(KERN_ERR, "Failed to read node id\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) *id = GET_BITFIELD(reg, 0, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) static int get_width(u32 mtr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) switch (GET_BITFIELD(mtr, 8, 9)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) return DEV_X4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) return DEV_X8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) return DEV_X16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) return DEV_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) * We use the per-socket device @cfg->did to count how many sockets are present,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) * and to detemine which PCI buses are associated with each socket. Allocate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) * and build the full list of all the skx_dev structures that we need here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) int skx_get_all_bus_mappings(struct res_config *cfg, struct list_head **list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) struct pci_dev *pdev, *prev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) struct skx_dev *d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) int ndev = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) prev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) pdev = pci_get_device(PCI_VENDOR_ID_INTEL, cfg->decs_did, prev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) if (!pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) ndev++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) d = kzalloc(sizeof(*d), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) if (!d) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) pci_dev_put(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) if (pci_read_config_dword(pdev, cfg->busno_cfg_offset, ®)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) kfree(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) pci_dev_put(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) skx_printk(KERN_ERR, "Failed to read bus idx\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) d->bus[0] = GET_BITFIELD(reg, 0, 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) d->bus[1] = GET_BITFIELD(reg, 8, 15);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) if (cfg->type == SKX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) d->seg = pci_domain_nr(pdev->bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) d->bus[2] = GET_BITFIELD(reg, 16, 23);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) d->bus[3] = GET_BITFIELD(reg, 24, 31);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) d->seg = GET_BITFIELD(reg, 16, 23);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) edac_dbg(2, "busses: 0x%x, 0x%x, 0x%x, 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) d->bus[0], d->bus[1], d->bus[2], d->bus[3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) list_add_tail(&d->list, &dev_edac_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) prev = pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) if (list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) *list = &dev_edac_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) return ndev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) int skx_get_hi_lo(unsigned int did, int off[], u64 *tolm, u64 *tohm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) struct pci_dev *pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) pdev = pci_get_device(PCI_VENDOR_ID_INTEL, did, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) if (!pdev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) edac_dbg(2, "Can't get tolm/tohm\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) if (pci_read_config_dword(pdev, off[0], ®)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) skx_printk(KERN_ERR, "Failed to read tolm\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) skx_tolm = reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) if (pci_read_config_dword(pdev, off[1], ®)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) skx_printk(KERN_ERR, "Failed to read lower tohm\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) skx_tohm = reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) if (pci_read_config_dword(pdev, off[2], ®)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) skx_printk(KERN_ERR, "Failed to read upper tohm\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) skx_tohm |= (u64)reg << 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) pci_dev_put(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) *tolm = skx_tolm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) *tohm = skx_tohm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) edac_dbg(2, "tolm = 0x%llx tohm = 0x%llx\n", skx_tolm, skx_tohm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) pci_dev_put(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) static int skx_get_dimm_attr(u32 reg, int lobit, int hibit, int add,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) int minval, int maxval, const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) u32 val = GET_BITFIELD(reg, lobit, hibit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) if (val < minval || val > maxval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) edac_dbg(2, "bad %s = %d (raw=0x%x)\n", name, val, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) return val + add;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) #define numrank(reg) skx_get_dimm_attr(reg, 12, 13, 0, 0, 2, "ranks")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) #define numrow(reg) skx_get_dimm_attr(reg, 2, 4, 12, 1, 6, "rows")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) #define numcol(reg) skx_get_dimm_attr(reg, 0, 1, 10, 0, 2, "cols")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) int skx_get_dimm_info(u32 mtr, u32 mcmtr, u32 amap, struct dimm_info *dimm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) struct skx_imc *imc, int chan, int dimmno)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) int banks = 16, ranks, rows, cols, npages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) u64 size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) ranks = numrank(mtr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) rows = numrow(mtr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) cols = numcol(mtr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) * Compute size in 8-byte (2^3) words, then shift to MiB (2^20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) size = ((1ull << (rows + cols + ranks)) * banks) >> (20 - 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) npages = MiB_TO_PAGES(size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) edac_dbg(0, "mc#%d: channel %d, dimm %d, %lld MiB (%d pages) bank: %d, rank: %d, row: 0x%x, col: 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) imc->mc, chan, dimmno, size, npages,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) banks, 1 << ranks, rows, cols);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) imc->chan[chan].dimms[dimmno].close_pg = GET_BITFIELD(mcmtr, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) imc->chan[chan].dimms[dimmno].bank_xor_enable = GET_BITFIELD(mcmtr, 9, 9);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) imc->chan[chan].dimms[dimmno].fine_grain_bank = GET_BITFIELD(amap, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) imc->chan[chan].dimms[dimmno].rowbits = rows;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) imc->chan[chan].dimms[dimmno].colbits = cols;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) dimm->nr_pages = npages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) dimm->grain = 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) dimm->dtype = get_width(mtr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) dimm->mtype = MEM_DDR4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) dimm->edac_mode = EDAC_SECDED; /* likely better than this */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) snprintf(dimm->label, sizeof(dimm->label), "CPU_SrcID#%u_MC#%u_Chan#%u_DIMM#%u",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) imc->src_id, imc->lmc, chan, dimmno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) int skx_get_nvdimm_info(struct dimm_info *dimm, struct skx_imc *imc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) int chan, int dimmno, const char *mod_str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) int smbios_handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) u32 dev_handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) u16 flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) u64 size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) dev_handle = ACPI_NFIT_BUILD_DEVICE_HANDLE(dimmno, chan, imc->lmc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) imc->src_id, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) smbios_handle = nfit_get_smbios_id(dev_handle, &flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) if (smbios_handle == -EOPNOTSUPP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) pr_warn_once("%s: Can't find size of NVDIMM. Try enabling CONFIG_ACPI_NFIT\n", mod_str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) goto unknown_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) if (smbios_handle < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) skx_printk(KERN_ERR, "Can't find handle for NVDIMM ADR=0x%x\n", dev_handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) goto unknown_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) if (flags & ACPI_NFIT_MEM_MAP_FAILED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) skx_printk(KERN_ERR, "NVDIMM ADR=0x%x is not mapped\n", dev_handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) goto unknown_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) size = dmi_memdev_size(smbios_handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) if (size == ~0ull)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) skx_printk(KERN_ERR, "Can't find size for NVDIMM ADR=0x%x/SMBIOS=0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) dev_handle, smbios_handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) unknown_size:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) dimm->nr_pages = size >> PAGE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) dimm->grain = 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) dimm->dtype = DEV_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) dimm->mtype = MEM_NVDIMM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) dimm->edac_mode = EDAC_SECDED; /* likely better than this */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) edac_dbg(0, "mc#%d: channel %d, dimm %d, %llu MiB (%u pages)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) imc->mc, chan, dimmno, size >> 20, dimm->nr_pages);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) snprintf(dimm->label, sizeof(dimm->label), "CPU_SrcID#%u_MC#%u_Chan#%u_DIMM#%u",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) imc->src_id, imc->lmc, chan, dimmno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) return (size == 0 || size == ~0ull) ? 0 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) int skx_register_mci(struct skx_imc *imc, struct pci_dev *pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) const char *ctl_name, const char *mod_str,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) get_dimm_config_f get_dimm_config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) struct mem_ctl_info *mci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) struct edac_mc_layer layers[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) struct skx_pvt *pvt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) /* Allocate a new MC control structure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) layers[0].type = EDAC_MC_LAYER_CHANNEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) layers[0].size = NUM_CHANNELS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) layers[0].is_virt_csrow = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) layers[1].type = EDAC_MC_LAYER_SLOT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) layers[1].size = NUM_DIMMS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) layers[1].is_virt_csrow = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) mci = edac_mc_alloc(imc->mc, ARRAY_SIZE(layers), layers,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) sizeof(struct skx_pvt));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) if (unlikely(!mci))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) edac_dbg(0, "MC#%d: mci = %p\n", imc->mc, mci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) /* Associate skx_dev and mci for future usage */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) imc->mci = mci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) pvt = mci->pvt_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) pvt->imc = imc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) mci->ctl_name = kasprintf(GFP_KERNEL, "%s#%d IMC#%d", ctl_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) imc->node_id, imc->lmc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) if (!mci->ctl_name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) goto fail0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) mci->mtype_cap = MEM_FLAG_DDR4 | MEM_FLAG_NVDIMM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) mci->edac_ctl_cap = EDAC_FLAG_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) mci->edac_cap = EDAC_FLAG_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) mci->mod_name = mod_str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) mci->dev_name = pci_name(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) mci->ctl_page_to_phys = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) rc = get_dimm_config(mci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) /* Record ptr to the generic device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) mci->pdev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) /* Add this new MC control structure to EDAC's list of MCs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) if (unlikely(edac_mc_add_mc(mci))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) edac_dbg(0, "MC: failed edac_mc_add_mc()\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) kfree(mci->ctl_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) fail0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) edac_mc_free(mci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) imc->mci = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) static void skx_unregister_mci(struct skx_imc *imc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) struct mem_ctl_info *mci = imc->mci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) if (!mci)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) edac_dbg(0, "MC%d: mci = %p\n", imc->mc, mci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) /* Remove MC sysfs nodes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) edac_mc_del_mc(mci->pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) edac_dbg(1, "%s: free mci struct\n", mci->ctl_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) kfree(mci->ctl_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) edac_mc_free(mci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) static void skx_mce_output_error(struct mem_ctl_info *mci,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) const struct mce *m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) struct decoded_addr *res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) enum hw_event_mc_err_type tp_event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) char *optype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) bool ripv = GET_BITFIELD(m->mcgstatus, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) bool overflow = GET_BITFIELD(m->status, 62, 62);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) bool uncorrected_error = GET_BITFIELD(m->status, 61, 61);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) bool recoverable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) u32 core_err_cnt = GET_BITFIELD(m->status, 38, 52);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) u32 mscod = GET_BITFIELD(m->status, 16, 31);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) u32 errcode = GET_BITFIELD(m->status, 0, 15);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) u32 optypenum = GET_BITFIELD(m->status, 4, 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) recoverable = GET_BITFIELD(m->status, 56, 56);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) if (uncorrected_error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) core_err_cnt = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) if (ripv) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) tp_event = HW_EVENT_ERR_UNCORRECTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) tp_event = HW_EVENT_ERR_FATAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) tp_event = HW_EVENT_ERR_CORRECTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) * According to Intel Architecture spec vol 3B,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) * Table 15-10 "IA32_MCi_Status [15:0] Compound Error Code Encoding"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) * memory errors should fit one of these masks:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) * 000f 0000 1mmm cccc (binary)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) * 000f 0010 1mmm cccc (binary) [RAM used as cache]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) * where:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) * f = Correction Report Filtering Bit. If 1, subsequent errors
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) * won't be shown
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) * mmm = error type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) * cccc = channel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) * If the mask doesn't match, report an error to the parsing logic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) if (!((errcode & 0xef80) == 0x80 || (errcode & 0xef80) == 0x280)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) optype = "Can't parse: it is not a mem";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) switch (optypenum) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) optype = "generic undef request error";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) optype = "memory read error";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) optype = "memory write error";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) optype = "addr/cmd error";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) optype = "memory scrubbing error";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) optype = "reserved";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) if (adxl_component_count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) len = snprintf(skx_msg, MSG_SIZE, "%s%s err_code:0x%04x:0x%04x %s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) overflow ? " OVERFLOW" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) (uncorrected_error && recoverable) ? " recoverable" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) mscod, errcode, adxl_msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) len = snprintf(skx_msg, MSG_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) "%s%s err_code:0x%04x:0x%04x socket:%d imc:%d rank:%d bg:%d ba:%d row:0x%x col:0x%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) overflow ? " OVERFLOW" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) (uncorrected_error && recoverable) ? " recoverable" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) mscod, errcode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) res->socket, res->imc, res->rank,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) res->bank_group, res->bank_address, res->row, res->column);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) if (skx_show_retry_rd_err_log)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) skx_show_retry_rd_err_log(res, skx_msg + len, MSG_SIZE - len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) edac_dbg(0, "%s\n", skx_msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) /* Call the helper to output message */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) edac_mc_handle_error(tp_event, mci, core_err_cnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) m->addr >> PAGE_SHIFT, m->addr & ~PAGE_MASK, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) res->channel, res->dimm, -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) optype, skx_msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) int skx_mce_check_error(struct notifier_block *nb, unsigned long val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) struct mce *mce = (struct mce *)data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) struct decoded_addr res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) struct mem_ctl_info *mci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) char *type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) if (mce->kflags & MCE_HANDLED_CEC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) return NOTIFY_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) /* ignore unless this is memory related with an address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) if ((mce->status & 0xefff) >> 7 != 1 || !(mce->status & MCI_STATUS_ADDRV))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) return NOTIFY_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) memset(&res, 0, sizeof(res));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) res.addr = mce->addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) if (adxl_component_count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) if (!skx_adxl_decode(&res))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) return NOTIFY_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) } else if (!skx_decode || !skx_decode(&res)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) return NOTIFY_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) mci = res.dev->imc[res.imc].mci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) if (!mci)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) return NOTIFY_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) if (mce->mcgstatus & MCG_STATUS_MCIP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) type = "Exception";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) type = "Event";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) skx_mc_printk(mci, KERN_DEBUG, "HANDLING MCE MEMORY ERROR\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) skx_mc_printk(mci, KERN_DEBUG, "CPU %d: Machine Check %s: 0x%llx "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) "Bank %d: 0x%llx\n", mce->extcpu, type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) mce->mcgstatus, mce->bank, mce->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) skx_mc_printk(mci, KERN_DEBUG, "TSC 0x%llx ", mce->tsc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) skx_mc_printk(mci, KERN_DEBUG, "ADDR 0x%llx ", mce->addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) skx_mc_printk(mci, KERN_DEBUG, "MISC 0x%llx ", mce->misc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) skx_mc_printk(mci, KERN_DEBUG, "PROCESSOR %u:0x%x TIME %llu SOCKET "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) "%u APIC 0x%x\n", mce->cpuvendor, mce->cpuid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) mce->time, mce->socketid, mce->apicid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) skx_mce_output_error(mci, mce, &res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) mce->kflags |= MCE_HANDLED_EDAC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) return NOTIFY_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) void skx_remove(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) struct skx_dev *d, *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) edac_dbg(0, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) list_for_each_entry_safe(d, tmp, &dev_edac_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) list_del(&d->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) for (i = 0; i < NUM_IMC; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) if (d->imc[i].mci)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) skx_unregister_mci(&d->imc[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) if (d->imc[i].mdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) pci_dev_put(d->imc[i].mdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) if (d->imc[i].mbase)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) iounmap(d->imc[i].mbase);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) for (j = 0; j < NUM_CHANNELS; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) if (d->imc[i].chan[j].cdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) pci_dev_put(d->imc[i].chan[j].cdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) if (d->util_all)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) pci_dev_put(d->util_all);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) if (d->sad_all)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) pci_dev_put(d->sad_all);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) if (d->uracu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) pci_dev_put(d->uracu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) kfree(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) }