#include <linux/ras.h>
#include "amd64_edac.h"
#include <asm/amd_nb.h>
static struct edac_pci_ctl_info *pci_ctl;
static int ecc_enable_override;
module_param(ecc_enable_override, int, 0644);
static struct msr __percpu *msrs;
static inline u32 get_umc_reg(struct amd64_pvt *pvt, u32 reg)
{ … }
static struct ecc_settings **ecc_stngs;
static struct device *pci_ctl_dev;
static const struct scrubrate { … } scrubrates[] = …;
int __amd64_read_pci_cfg_dword(struct pci_dev *pdev, int offset,
u32 *val, const char *func)
{ … }
int __amd64_write_pci_cfg_dword(struct pci_dev *pdev, int offset,
u32 val, const char *func)
{ … }
static void f15h_select_dct(struct amd64_pvt *pvt, u8 dct)
{ … }
static inline int amd64_read_dct_pci_cfg(struct amd64_pvt *pvt, u8 dct,
int offset, u32 *val)
{ … }
static int __set_scrub_rate(struct amd64_pvt *pvt, u32 new_bw, u32 min_rate)
{ … }
static int set_scrub_rate(struct mem_ctl_info *mci, u32 bw)
{ … }
static int get_scrub_rate(struct mem_ctl_info *mci)
{ … }
static bool base_limit_match(struct amd64_pvt *pvt, u64 sys_addr, u8 nid)
{ … }
static struct mem_ctl_info *find_mc_by_sys_addr(struct mem_ctl_info *mci,
u64 sys_addr)
{ … }
static void get_cs_base_and_mask(struct amd64_pvt *pvt, int csrow, u8 dct,
u64 *base, u64 *mask)
{ … }
#define for_each_chip_select(i, dct, pvt) …
#define chip_select_base(i, dct, pvt) …
#define for_each_chip_select_mask(i, dct, pvt) …
#define for_each_umc(i) …
static int input_addr_to_csrow(struct mem_ctl_info *mci, u64 input_addr)
{ … }
static int get_dram_hole_info(struct mem_ctl_info *mci, u64 *hole_base,
u64 *hole_offset, u64 *hole_size)
{ … }
#ifdef CONFIG_EDAC_DEBUG
#define EDAC_DCT_ATTR_SHOW(reg) …
EDAC_DCT_ATTR_SHOW(dhar);
EDAC_DCT_ATTR_SHOW(dbam0);
EDAC_DCT_ATTR_SHOW(top_mem);
EDAC_DCT_ATTR_SHOW(top_mem2);
static ssize_t dram_hole_show(struct device *dev, struct device_attribute *mattr,
char *data)
{ … }
static DEVICE_ATTR(dhar, S_IRUGO, dhar_show, NULL);
static DEVICE_ATTR(dbam, S_IRUGO, dbam0_show, NULL);
static DEVICE_ATTR(topmem, S_IRUGO, top_mem_show, NULL);
static DEVICE_ATTR(topmem2, S_IRUGO, top_mem2_show, NULL);
static DEVICE_ATTR_RO(dram_hole);
static struct attribute *dbg_attrs[] = …;
static const struct attribute_group dbg_group = …;
static ssize_t inject_section_show(struct device *dev,
struct device_attribute *mattr, char *buf)
{ … }
static ssize_t inject_section_store(struct device *dev,
struct device_attribute *mattr,
const char *data, size_t count)
{ … }
static ssize_t inject_word_show(struct device *dev,
struct device_attribute *mattr, char *buf)
{ … }
static ssize_t inject_word_store(struct device *dev,
struct device_attribute *mattr,
const char *data, size_t count)
{ … }
static ssize_t inject_ecc_vector_show(struct device *dev,
struct device_attribute *mattr,
char *buf)
{ … }
static ssize_t inject_ecc_vector_store(struct device *dev,
struct device_attribute *mattr,
const char *data, size_t count)
{ … }
static ssize_t inject_read_store(struct device *dev,
struct device_attribute *mattr,
const char *data, size_t count)
{ … }
static ssize_t inject_write_store(struct device *dev,
struct device_attribute *mattr,
const char *data, size_t count)
{ … }
static DEVICE_ATTR_RW(inject_section);
static DEVICE_ATTR_RW(inject_word);
static DEVICE_ATTR_RW(inject_ecc_vector);
static DEVICE_ATTR_WO(inject_write);
static DEVICE_ATTR_WO(inject_read);
static struct attribute *inj_attrs[] = …;
static umode_t inj_is_visible(struct kobject *kobj, struct attribute *attr, int idx)
{ … }
static const struct attribute_group inj_group = …;
#endif
static u64 sys_addr_to_dram_addr(struct mem_ctl_info *mci, u64 sys_addr)
{ … }
static int num_node_interleave_bits(unsigned intlv_en)
{ … }
static u64 dram_addr_to_input_addr(struct mem_ctl_info *mci, u64 dram_addr)
{ … }
static u64 sys_addr_to_input_addr(struct mem_ctl_info *mci, u64 sys_addr)
{ … }
static inline void error_address_to_page_and_offset(u64 error_address,
struct err_info *err)
{ … }
static int sys_addr_to_csrow(struct mem_ctl_info *mci, u64 sys_addr)
{ … }
static struct local_node_map { … } gpu_node_map;
#define PCI_DEVICE_ID_AMD_MI200_DF_F1 …
#define REG_LOCAL_NODE_TYPE_MAP …
#define LNTM_NODE_COUNT …
#define LNTM_BASE_NODE_ID …
static int gpu_get_node_map(struct amd64_pvt *pvt)
{ … }
static int fixup_node_id(int node_id, struct mce *m)
{ … }
static int get_channel_from_ecc_syndrome(struct mem_ctl_info *, u16);
static unsigned long dct_determine_edac_cap(struct amd64_pvt *pvt)
{ … }
static unsigned long umc_determine_edac_cap(struct amd64_pvt *pvt)
{ … }
static void dct_debug_display_dimm_sizes(struct amd64_pvt *pvt, u8 ctrl)
{ … }
static void debug_dump_dramcfg_low(struct amd64_pvt *pvt, u32 dclr, int chan)
{ … }
#define CS_EVEN_PRIMARY …
#define CS_ODD_PRIMARY …
#define CS_EVEN_SECONDARY …
#define CS_ODD_SECONDARY …
#define CS_3R_INTERLEAVE …
#define CS_EVEN …
#define CS_ODD …
static int umc_get_cs_mode(int dimm, u8 ctrl, struct amd64_pvt *pvt)
{ … }
static int __addr_mask_to_cs_size(u32 addr_mask_orig, unsigned int cs_mode,
int csrow_nr, int dimm)
{ … }
static int umc_addr_mask_to_cs_size(struct amd64_pvt *pvt, u8 umc,
unsigned int cs_mode, int csrow_nr)
{ … }
static void umc_debug_display_dimm_sizes(struct amd64_pvt *pvt, u8 ctrl)
{ … }
static void umc_dump_misc_regs(struct amd64_pvt *pvt)
{ … }
static void dct_dump_misc_regs(struct amd64_pvt *pvt)
{ … }
static void dct_prep_chip_selects(struct amd64_pvt *pvt)
{ … }
static void umc_prep_chip_selects(struct amd64_pvt *pvt)
{ … }
static void umc_read_base_mask(struct amd64_pvt *pvt)
{ … }
static void dct_read_base_mask(struct amd64_pvt *pvt)
{ … }
static void umc_determine_memory_type(struct amd64_pvt *pvt)
{ … }
static void dct_determine_memory_type(struct amd64_pvt *pvt)
{ … }
static u64 get_error_address(struct amd64_pvt *pvt, struct mce *m)
{ … }
static struct pci_dev *pci_get_related_function(unsigned int vendor,
unsigned int device,
struct pci_dev *related)
{ … }
static void read_dram_base_limit_regs(struct amd64_pvt *pvt, unsigned range)
{ … }
static void k8_map_sysaddr_to_csrow(struct mem_ctl_info *mci, u64 sys_addr,
struct err_info *err)
{ … }
static int ddr2_cs_size(unsigned i, bool dct_width)
{ … }
static int k8_dbam_to_chip_select(struct amd64_pvt *pvt, u8 dct,
unsigned cs_mode, int cs_mask_nr)
{ … }
static int ddr3_cs_size(unsigned i, bool dct_width)
{ … }
static int ddr3_lrdimm_cs_size(unsigned i, unsigned rank_multiply)
{ … }
static int ddr4_cs_size(unsigned i)
{ … }
static int f10_dbam_to_chip_select(struct amd64_pvt *pvt, u8 dct,
unsigned cs_mode, int cs_mask_nr)
{ … }
static int f15_dbam_to_chip_select(struct amd64_pvt *pvt, u8 dct,
unsigned cs_mode, int cs_mask_nr)
{ … }
static int f15_m60h_dbam_to_chip_select(struct amd64_pvt *pvt, u8 dct,
unsigned cs_mode, int cs_mask_nr)
{ … }
static int f16_dbam_to_chip_select(struct amd64_pvt *pvt, u8 dct,
unsigned cs_mode, int cs_mask_nr)
{ … }
static void read_dram_ctl_register(struct amd64_pvt *pvt)
{ … }
static u8 f15_m30h_determine_channel(struct amd64_pvt *pvt, u64 sys_addr,
u8 intlv_en, int num_dcts_intlv,
u32 dct_sel)
{ … }
static u8 f1x_determine_channel(struct amd64_pvt *pvt, u64 sys_addr,
bool hi_range_sel, u8 intlv_en)
{ … }
static u64 f1x_get_norm_dct_addr(struct amd64_pvt *pvt, u8 range,
u64 sys_addr, bool hi_rng,
u32 dct_sel_base_addr)
{ … }
static int f10_process_possible_spare(struct amd64_pvt *pvt, u8 dct, int csrow)
{ … }
static int f1x_lookup_addr_in_dct(u64 in_addr, u8 nid, u8 dct)
{ … }
static u64 f1x_swap_interleaved_region(struct amd64_pvt *pvt, u64 sys_addr)
{ … }
static int f1x_match_to_this_node(struct amd64_pvt *pvt, unsigned range,
u64 sys_addr, int *chan_sel)
{ … }
static int f15_m30h_match_to_this_node(struct amd64_pvt *pvt, unsigned range,
u64 sys_addr, int *chan_sel)
{ … }
static int f1x_translate_sysaddr_to_cs(struct amd64_pvt *pvt,
u64 sys_addr,
int *chan_sel)
{ … }
static void f1x_map_sysaddr_to_csrow(struct mem_ctl_info *mci, u64 sys_addr,
struct err_info *err)
{ … }
static const u16 x4_vectors[] = …;
static const u16 x8_vectors[] = …;
static int decode_syndrome(u16 syndrome, const u16 *vectors, unsigned num_vecs,
unsigned v_dim)
{ … }
static int map_err_sym_to_channel(int err_sym, int sym_size)
{ … }
static int get_channel_from_ecc_syndrome(struct mem_ctl_info *mci, u16 syndrome)
{ … }
static void __log_ecc_error(struct mem_ctl_info *mci, struct err_info *err,
u8 ecc_type)
{ … }
static inline void decode_bus_error(int node_id, struct mce *m)
{ … }
static void umc_get_err_info(struct mce *m, struct err_info *err)
{ … }
static void decode_umc_error(int node_id, struct mce *m)
{ … }
static int
reserve_mc_sibling_devs(struct amd64_pvt *pvt, u16 pci_id1, u16 pci_id2)
{ … }
static void determine_ecc_sym_sz(struct amd64_pvt *pvt)
{ … }
static void umc_read_mc_regs(struct amd64_pvt *pvt)
{ … }
static void dct_read_mc_regs(struct amd64_pvt *pvt)
{ … }
static u32 dct_get_csrow_nr_pages(struct amd64_pvt *pvt, u8 dct, int csrow_nr)
{ … }
static u32 umc_get_csrow_nr_pages(struct amd64_pvt *pvt, u8 dct, int csrow_nr_orig)
{ … }
static void umc_init_csrows(struct mem_ctl_info *mci)
{ … }
static void dct_init_csrows(struct mem_ctl_info *mci)
{ … }
static void get_cpus_on_this_dct_cpumask(struct cpumask *mask, u16 nid)
{ … }
static bool nb_mce_bank_enabled_on_node(u16 nid)
{ … }
static int toggle_ecc_err_reporting(struct ecc_settings *s, u16 nid, bool on)
{ … }
static bool enable_ecc_error_reporting(struct ecc_settings *s, u16 nid,
struct pci_dev *F3)
{ … }
static void restore_ecc_error_reporting(struct ecc_settings *s, u16 nid,
struct pci_dev *F3)
{ … }
static bool dct_ecc_enabled(struct amd64_pvt *pvt)
{ … }
static bool umc_ecc_enabled(struct amd64_pvt *pvt)
{ … }
static inline void
umc_determine_edac_ctl_cap(struct mem_ctl_info *mci, struct amd64_pvt *pvt)
{ … }
static void dct_setup_mci_misc_attrs(struct mem_ctl_info *mci)
{ … }
static void umc_setup_mci_misc_attrs(struct mem_ctl_info *mci)
{ … }
static int dct_hw_info_get(struct amd64_pvt *pvt)
{ … }
static int umc_hw_info_get(struct amd64_pvt *pvt)
{ … }
static void gpu_get_err_info(struct mce *m, struct err_info *err)
{ … }
static int gpu_addr_mask_to_cs_size(struct amd64_pvt *pvt, u8 umc,
unsigned int cs_mode, int csrow_nr)
{ … }
static void gpu_debug_display_dimm_sizes(struct amd64_pvt *pvt, u8 ctrl)
{ … }
static void gpu_dump_misc_regs(struct amd64_pvt *pvt)
{ … }
static u32 gpu_get_csrow_nr_pages(struct amd64_pvt *pvt, u8 dct, int csrow_nr)
{ … }
static void gpu_init_csrows(struct mem_ctl_info *mci)
{ … }
static void gpu_setup_mci_misc_attrs(struct mem_ctl_info *mci)
{ … }
static bool gpu_ecc_enabled(struct amd64_pvt *pvt)
{ … }
static inline u32 gpu_get_umc_base(struct amd64_pvt *pvt, u8 umc, u8 channel)
{ … }
static void gpu_read_mc_regs(struct amd64_pvt *pvt)
{ … }
static void gpu_read_base_mask(struct amd64_pvt *pvt)
{ … }
static void gpu_prep_chip_selects(struct amd64_pvt *pvt)
{ … }
static int gpu_hw_info_get(struct amd64_pvt *pvt)
{ … }
static void hw_info_put(struct amd64_pvt *pvt)
{ … }
static struct low_ops umc_ops = …;
static struct low_ops gpu_ops = …;
static struct low_ops dct_ops = …;
static int per_family_init(struct amd64_pvt *pvt)
{ … }
static const struct attribute_group *amd64_edac_attr_groups[] = …;
static unsigned int get_layer_size(struct amd64_pvt *pvt, u8 layer)
{ … }
static int init_one_instance(struct amd64_pvt *pvt)
{ … }
static bool instance_has_memory(struct amd64_pvt *pvt)
{ … }
static int probe_one_instance(unsigned int nid)
{ … }
static void remove_one_instance(unsigned int nid)
{ … }
static void setup_pci_device(void)
{ … }
static const struct x86_cpu_id amd64_cpuids[] = …;
MODULE_DEVICE_TABLE(x86cpu, amd64_cpuids);
static int __init amd64_edac_init(void)
{ … }
static void __exit amd64_edac_exit(void)
{ … }
module_init(…) …;
module_exit(amd64_edac_exit);
MODULE_LICENSE(…) …;
MODULE_AUTHOR(…) …;
MODULE_DESCRIPTION(…) …;
module_param(edac_op_state, int, 0444);
MODULE_PARM_DESC(…) …;