linux/drivers/edac/ie31200_edac.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 * Intel E3-1200
 * Copyright (C) 2014 Jason Baron <[email protected]>
 *
 * Support for the E3-1200 processor family. Heavily based on previous
 * Intel EDAC drivers.
 *
 * Since the DRAM controller is on the cpu chip, we can use its PCI device
 * id to identify these processors.
 *
 * PCI DRAM controller device ids (Taken from The PCI ID Repository - https://pci-ids.ucw.cz/)
 *
 * 0108: Xeon E3-1200 Processor Family DRAM Controller
 * 010c: Xeon E3-1200/2nd Generation Core Processor Family DRAM Controller
 * 0150: Xeon E3-1200 v2/3rd Gen Core processor DRAM Controller
 * 0158: Xeon E3-1200 v2/Ivy Bridge DRAM Controller
 * 015c: Xeon E3-1200 v2/3rd Gen Core processor DRAM Controller
 * 0c04: Xeon E3-1200 v3/4th Gen Core Processor DRAM Controller
 * 0c08: Xeon E3-1200 v3 Processor DRAM Controller
 * 1918: Xeon E3-1200 v5 Skylake Host Bridge/DRAM Registers
 * 5918: Xeon E3-1200 Xeon E3-1200 v6/7th Gen Core Processor Host Bridge/DRAM Registers
 * 190f: 6th Gen Core Dual-Core Processor Host Bridge/DRAM Registers
 * 191f: 6th Gen Core Quad-Core Processor Host Bridge/DRAM Registers
 * 3e..: 8th/9th Gen Core Processor Host Bridge/DRAM Registers
 *
 * Based on Intel specification:
 * https://www.intel.com/content/dam/www/public/us/en/documents/datasheets/xeon-e3-1200v3-vol-2-datasheet.pdf
 * http://www.intel.com/content/www/us/en/processors/xeon/xeon-e3-1200-family-vol-2-datasheet.html
 * https://www.intel.com/content/dam/www/public/us/en/documents/datasheets/desktop-6th-gen-core-family-datasheet-vol-2.pdf
 * https://www.intel.com/content/dam/www/public/us/en/documents/datasheets/xeon-e3-1200v6-vol-2-datasheet.pdf
 * https://www.intel.com/content/www/us/en/processors/core/7th-gen-core-family-mobile-h-processor-lines-datasheet-vol-2.html
 * https://www.intel.com/content/www/us/en/products/docs/processors/core/8th-gen-core-family-datasheet-vol-2.html
 *
 * According to the above datasheet (p.16):
 * "
 * 6. Software must not access B0/D0/F0 32-bit memory-mapped registers with
 * requests that cross a DW boundary.
 * "
 *
 * Thus, we make use of the explicit: lo_hi_readq(), which breaks the readq into
 * 2 readl() calls. This restriction may be lifted in subsequent chip releases,
 * but lo_hi_readq() ensures that we are safe across all e3-1200 processors.
 */

#include <linux/module.h>
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/pci_ids.h>
#include <linux/edac.h>

#include <linux/io-64-nonatomic-lo-hi.h>
#include "edac_module.h"

#define EDAC_MOD_STR

#define ie31200_printk(level, fmt, arg...)

#define PCI_DEVICE_ID_INTEL_IE31200_HB_1
#define PCI_DEVICE_ID_INTEL_IE31200_HB_2
#define PCI_DEVICE_ID_INTEL_IE31200_HB_3
#define PCI_DEVICE_ID_INTEL_IE31200_HB_4
#define PCI_DEVICE_ID_INTEL_IE31200_HB_5
#define PCI_DEVICE_ID_INTEL_IE31200_HB_6
#define PCI_DEVICE_ID_INTEL_IE31200_HB_7
#define PCI_DEVICE_ID_INTEL_IE31200_HB_8
#define PCI_DEVICE_ID_INTEL_IE31200_HB_9
#define PCI_DEVICE_ID_INTEL_IE31200_HB_10
#define PCI_DEVICE_ID_INTEL_IE31200_HB_11

/* Coffee Lake-S */
#define PCI_DEVICE_ID_INTEL_IE31200_HB_CFL_MASK
#define PCI_DEVICE_ID_INTEL_IE31200_HB_CFL_1
#define PCI_DEVICE_ID_INTEL_IE31200_HB_CFL_2
#define PCI_DEVICE_ID_INTEL_IE31200_HB_CFL_3
#define PCI_DEVICE_ID_INTEL_IE31200_HB_CFL_4
#define PCI_DEVICE_ID_INTEL_IE31200_HB_CFL_5
#define PCI_DEVICE_ID_INTEL_IE31200_HB_CFL_6
#define PCI_DEVICE_ID_INTEL_IE31200_HB_CFL_7
#define PCI_DEVICE_ID_INTEL_IE31200_HB_CFL_8
#define PCI_DEVICE_ID_INTEL_IE31200_HB_CFL_9
#define PCI_DEVICE_ID_INTEL_IE31200_HB_CFL_10

/* Test if HB is for Skylake or later. */
#define DEVICE_ID_SKYLAKE_OR_LATER(did)

#define IE31200_DIMMS
#define IE31200_RANKS
#define IE31200_RANKS_PER_CHANNEL
#define IE31200_DIMMS_PER_CHANNEL
#define IE31200_CHANNELS

/* Intel IE31200 register addresses - device 0 function 0 - DRAM Controller */
#define IE31200_MCHBAR_LOW
#define IE31200_MCHBAR_HIGH
#define IE31200_MCHBAR_MASK
#define IE31200_MMR_WINDOW_SIZE

/*
 * Error Status Register (16b)
 *
 * 15    reserved
 * 14    Isochronous TBWRR Run Behind FIFO Full
 *       (ITCV)
 * 13    Isochronous TBWRR Run Behind FIFO Put
 *       (ITSTV)
 * 12    reserved
 * 11    MCH Thermal Sensor Event
 *       for SMI/SCI/SERR (GTSE)
 * 10    reserved
 *  9    LOCK to non-DRAM Memory Flag (LCKF)
 *  8    reserved
 *  7    DRAM Throttle Flag (DTF)
 *  6:2  reserved
 *  1    Multi-bit DRAM ECC Error Flag (DMERR)
 *  0    Single-bit DRAM ECC Error Flag (DSERR)
 */
#define IE31200_ERRSTS
#define IE31200_ERRSTS_UE
#define IE31200_ERRSTS_CE
#define IE31200_ERRSTS_BITS

/*
 * Channel 0 ECC Error Log (64b)
 *
 * 63:48 Error Column Address (ERRCOL)
 * 47:32 Error Row Address (ERRROW)
 * 31:29 Error Bank Address (ERRBANK)
 * 28:27 Error Rank Address (ERRRANK)
 * 26:24 reserved
 * 23:16 Error Syndrome (ERRSYND)
 * 15: 2 reserved
 *    1  Multiple Bit Error Status (MERRSTS)
 *    0  Correctable Error Status (CERRSTS)
 */

#define IE31200_C0ECCERRLOG
#define IE31200_C1ECCERRLOG
#define IE31200_C0ECCERRLOG_SKL
#define IE31200_C1ECCERRLOG_SKL
#define IE31200_ECCERRLOG_CE
#define IE31200_ECCERRLOG_UE
#define IE31200_ECCERRLOG_RANK_BITS
#define IE31200_ECCERRLOG_RANK_SHIFT
#define IE31200_ECCERRLOG_SYNDROME_BITS
#define IE31200_ECCERRLOG_SYNDROME_SHIFT

#define IE31200_ECCERRLOG_SYNDROME(log)

#define IE31200_CAPID0
#define IE31200_CAPID0_PDCD
#define IE31200_CAPID0_DDPCD
#define IE31200_CAPID0_ECC

#define IE31200_MAD_DIMM_0_OFFSET
#define IE31200_MAD_DIMM_0_OFFSET_SKL
#define IE31200_MAD_DIMM_SIZE
#define IE31200_MAD_DIMM_A_RANK
#define IE31200_MAD_DIMM_A_RANK_SHIFT
#define IE31200_MAD_DIMM_A_RANK_SKL
#define IE31200_MAD_DIMM_A_RANK_SKL_SHIFT
#define IE31200_MAD_DIMM_A_WIDTH
#define IE31200_MAD_DIMM_A_WIDTH_SHIFT
#define IE31200_MAD_DIMM_A_WIDTH_SKL
#define IE31200_MAD_DIMM_A_WIDTH_SKL_SHIFT

/* Skylake reports 1GB increments, everything else is 256MB */
#define IE31200_PAGES(n, skl)

static int nr_channels;
static struct pci_dev *mci_pdev;
static int ie31200_registered =;

struct ie31200_priv {};

enum ie31200_chips {};

struct ie31200_dev_info {};

struct ie31200_error_info {};

static const struct ie31200_dev_info ie31200_devs[] =;

struct dimm_data {};

static int how_many_channels(struct pci_dev *pdev)
{}

static bool ecc_capable(struct pci_dev *pdev)
{}

static int eccerrlog_row(u64 log)
{}

static void ie31200_clear_error_info(struct mem_ctl_info *mci)
{}

static void ie31200_get_and_clear_error_info(struct mem_ctl_info *mci,
					     struct ie31200_error_info *info)
{}

static void ie31200_process_error_info(struct mem_ctl_info *mci,
				       struct ie31200_error_info *info)
{}

static void ie31200_check(struct mem_ctl_info *mci)
{}

static void __iomem *ie31200_map_mchbar(struct pci_dev *pdev)
{}

static void __skl_populate_dimm_info(struct dimm_data *dd, u32 addr_decode,
				     int chan)
{}

static void __populate_dimm_info(struct dimm_data *dd, u32 addr_decode,
				 int chan)
{}

static void populate_dimm_info(struct dimm_data *dd, u32 addr_decode, int chan,
			       bool skl)
{}


static int ie31200_probe1(struct pci_dev *pdev, int dev_idx)
{}

static int ie31200_init_one(struct pci_dev *pdev,
			    const struct pci_device_id *ent)
{}

static void ie31200_remove_one(struct pci_dev *pdev)
{}

static const struct pci_device_id ie31200_pci_tbl[] =;
MODULE_DEVICE_TABLE(pci, ie31200_pci_tbl);

static struct pci_driver ie31200_driver =;

static int __init ie31200_init(void)
{}

static void __exit ie31200_exit(void)
{}

module_init();
module_exit(ie31200_exit);

MODULE_LICENSE();
MODULE_AUTHOR();
MODULE_DESCRIPTION();