2 * Xeon 7500 series specific machine check support code.
3 * Copyright 2009, 2010 Intel Corporation
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; version 2
11 * Implement Xeon 7500 series specific code to retrieve the physical address
12 * and DIMM information for corrected memory errors.
14 * Interface: mce->aux0/aux1 is mapped to a struct pfa_dimm with pad
15 * redefined to DIMM valid bits. Consumers check CPUID and bank and
16 * then interpret aux0/aux1
19 /* #define DEBUG 1 */ /* disable for production */
20 #define pr_fmt(x) "MCE: " x
22 #include <linux/moduleparam.h>
23 #include <linux/pci_ids.h>
24 #include <linux/hrtimer.h>
25 #include <linux/string.h>
26 #include <linux/module.h>
27 #include <linux/kernel.h>
28 #include <linux/ktime.h>
29 #include <linux/init.h>
30 #include <linux/pci.h>
31 #include <asm/processor.h>
36 #include "mce-internal.h"
38 #define PFA_SIG "$PFA"
41 /* DIMM description */
49 u8 ddr_dimm_column_id;
51 } __attribute__((packed));
60 u32 ddr_dimm_column_id;
61 } __attribute__((packed));
63 /* Memory translation table in memory. */
65 u8 sig[PFA_SIG_LEN]; /* Signature: '$PFA' */
66 u16 len; /* total length */
67 u16 revision; /* 0x11 */
68 u8 checksum; /* 8bit sum to zero */
69 u8 db_value; /* mailbox port command value */
70 u8 db_port; /* mailbox port */
71 /* end of header; end of checksum */
72 u8 command; /* input command */
73 u32 valid; /* valid input/output bits */
74 u16 status; /* output status */
75 u8 socket_id; /* input socket id*/
76 u8 bank_id; /* input MCE bank id */
79 u64 physical_addr; /* physical address */
80 struct pfa_dimm dimm[2];
82 * topology information follows: not used for now.
84 } __attribute__((packed));
86 /* DIMM valid bits in valid: DIMM0: 8..12; DIMM1 16..20 */
87 #define DIMM_VALID_BITS(val, num) (((val) >> (4 + (num) * 8)) & DIMM_VALID_ALL)
88 #define DIMM_SET_VALID(val, num) ((val) << (4 + (num) * 8))
94 PFA_REVISION = 0x11, /* v1.1 */
96 /* Status bits for valid field */
97 PFA_VALID_MA = (1 << 0),
98 PFA_VALID_SOCKETID = (1 << 1),
99 PFA_VALID_BANKID = (1 << 2),
100 PFA_VALID_PA = (1 << 3),
102 /* DIMM valid bits in valid */
103 /* use with DIMM_VALID_BITS/DIMM_SET_VALID for pfa->valid */
104 DIMM_VALID_FBD_CHAN = (1 << 0),
105 DIMM_VALID_DDR_CHAN = (1 << 1),
106 DIMM_VALID_DDR_DIMM = (1 << 2),
107 DIMM_VALID_DDR_RANK = (1 << 3),
108 DIMM_VALID_DIMM_BANK = (1 << 4),
109 DIMM_VALID_DIMM_ROW = (1 << 5),
110 DIMM_VALID_DIMM_COLUMN = (1 << 6),
111 DIMM_VALID_ALL = 0x7f,
113 PFA_DIMM_VALID_MASK = DIMM_SET_VALID(DIMM_VALID_ALL, 0)
114 | DIMM_SET_VALID(DIMM_VALID_ALL, 1),
116 /* Values for status field */
117 PFA_STATUS_SUCCESS = 0,
118 PFA_STATUS_SOCKET_INVALID = (1 << 1),
119 PFA_STATUS_MBOX_INVALID = (1 << 2),
120 PFA_STATUS_MA_INVALID = (1 << 3),
121 PFA_STATUS_PA_INVALID = (1 << 4),
123 /* Values for command field */
124 PFA_CMD_GET_MEM_CORR_ERR_PA = 0,
125 PFA_CMD_PA_TO_DIMM_ADDR = 1,
126 PFA_CMD_DIMM_TO_PA = 2,
127 PFA_CMD_GET_TOPOLOGY = 3,
129 /* PCI device IDs and the base register */
130 ICH_PFA_CFG = 0x8c, /* SCRATCH4 */
131 PCI_DEVICE_ID_BXB_ICH_LEGACY0 = 0x3422,
134 static struct pfa_table *pfa_table __read_mostly;
135 static int memerr_max_conv_rate __read_mostly = 100;
136 static int memerr_min_interval __read_mostly = 500;
137 static int pfa_lost; /* for diagnosis */
140 RATE_LIMIT_PERIOD = USEC_PER_SEC, /* in us; period of rate limit */
143 module_param(memerr_max_conv_rate, int, 0644);
144 MODULE_PARM_DESC(memerr_max_conv_rate,
145 "Maximum number of memory error conversions each second; 0 to disable");
146 module_param(memerr_min_interval, int, 0644);
147 MODULE_PARM_DESC(memerr_min_interval,
148 "Minimum time delta between two memory conversions; in us; default 500");
152 module_param(notest, int, 0);
153 module_param(nocsum, int, 0);
155 static u64 encode_dimm(struct pfa_dimm *d, u8 valid)
158 struct aux_pfa_dimm d;
162 BUILD_BUG_ON(sizeof(struct aux_pfa_dimm) != sizeof(u64));
163 p.d.fbd_channel_id = d->fbd_channel_id;
164 p.d.ddr_channel_id = d->ddr_channel_id;
165 p.d.ddr_dimm_id = d->ddr_dimm_id;
166 p.d.ddr_rank_id = d->ddr_rank_id;
167 p.d.ddr_dimm_bank_id = d->ddr_dimm_bank_id;
168 p.d.ddr_dimm_row_id = d->ddr_dimm_row_id;
169 if (p.d.ddr_dimm_row_id != d->ddr_dimm_row_id) /* truncated? */
170 valid &= ~DIMM_VALID_DIMM_ROW;
171 p.d.ddr_dimm_column_id = d->ddr_dimm_column_id;
172 if (p.d.ddr_dimm_column_id != d->ddr_dimm_column_id)
173 valid &= ~DIMM_VALID_DIMM_COLUMN;
175 pr_debug("PFA fbd_ch %u ddr_ch %u dimm %u rank %u bank %u valid %x\n",
185 static u8 csum(u8 *table, u16 len)
189 for (i = 0; i < len; i++)
195 * Execute a command through the mailbox interface.
198 pfa_command(unsigned bank, unsigned socketid, unsigned command, unsigned valid)
200 pfa_table->bank_id = bank;
201 pfa_table->socket_id = socketid;
202 pfa_table->valid = valid | PFA_VALID_SOCKETID;
203 pfa_table->command = command;
205 outb(pfa_table->db_value, pfa_table->db_port);
207 mb(); /* Reread fields after they got changed */
209 if (pfa_table->status != PFA_STATUS_SUCCESS) {
210 pr_debug("Memory PFA command %d failed: socket:%d bank:%d status:%x\n",
211 command, socketid, bank, pfa_table->status);
212 return -pfa_table->status;
218 * Retrieve physical address and DIMMs.
220 static int translate_memory_error(struct mce *m)
222 struct pfa_table *pfa = pfa_table;
226 int cpu = smp_processor_id();
228 /* Make sure our structures match the specification */
229 BUILD_BUG_ON(offsetof(struct pfa_table, physical_addr) != 0x20);
230 BUILD_BUG_ON(offsetof(struct pfa_table, status) != 0x10);
231 BUILD_BUG_ON(offsetof(struct pfa_table, physical_addr) != 0x20);
232 BUILD_BUG_ON(offsetof(struct pfa_table, dimm[1].ddr_dimm_column_id) !=
235 /* Ask for PA/DIMMs of last error */
236 if (pfa_command(m->bank, m->socketid,
237 PFA_CMD_GET_MEM_CORR_ERR_PA, PFA_VALID_BANKID) < 0)
241 * Recheck machine check bank. If the overflow bit was set
242 * there was a race. Don't use the information in this case.
244 rdmsrl(MSR_IA32_MCx_STATUS(m->bank), status);
245 if (status & MCI_STATUS_OVER) {
246 pr_debug("%d: overflow race on bank %d\n", cpu, m->bank);
252 if (valid & PFA_VALID_PA) {
253 m->status |= MCI_STATUS_ADDRV;
254 m->addr = pfa_table->physical_addr;
255 pr_debug("%d: got physical address %llx valid %x\n",
256 cpu, m->addr, valid);
260 /* When DIMM information was supplied pass it out */
261 if (valid & PFA_DIMM_VALID_MASK) {
262 m->aux0 = encode_dimm(&pfa->dimm[0], DIMM_VALID_BITS(valid, 0));
263 m->aux1 = encode_dimm(&pfa->dimm[1], DIMM_VALID_BITS(valid, 1));
271 * Xeon 75xx specific mce poll method to retrieve the physical address
272 * and DIMM information.
274 static void xeon75xx_mce_poll(struct mce *m)
276 static DEFINE_SPINLOCK(convert_lock); /* Protect table and static */
277 static unsigned long cperm;
278 static ktime_t last, last_int;
284 if (m->bank != MCE_BANK_MBOX0 && m->bank != MCE_BANK_MBOX1)
286 if (m->status & MCI_STATUS_OVER)
288 if (memerr_max_conv_rate == 0)
291 spin_lock_irqsave(&convert_lock, flags);
293 * Rate limit conversions. The conversion takes some time,
294 * but it's not good to use all the CPU time during a error
296 * Enforce maximum number per second and minimum interval.
297 * The ktime call should use TSC on this machine and be fast.
300 delta = ktime_us_delta(now, last);
301 if (delta >= RATE_LIMIT_PERIOD) {
305 if (ktime_us_delta(now, last_int) >= memerr_min_interval &&
306 ++cperm <= memerr_max_conv_rate) {
307 if (translate_memory_error(m) < 0) {
308 /* On error stop converting for the next second */
309 cperm = memerr_max_conv_rate;
310 pr_debug("PFA translation failed\n");
315 spin_unlock_irqrestore(&convert_lock, flags);
318 static struct pci_device_id bxb_mce_pciids[] = {
319 { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_BXB_ICH_LEGACY0) },
323 static int __init xeon75xx_mce_init(void)
328 if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL ||
329 boot_cpu_data.x86 != 6 ||
330 boot_cpu_data.x86_model != 0x2e)
334 * Get table address from register in IOH.
335 * This just looks up the device, because we don't want to "own" it.
338 while ((dev = pci_get_device(PCI_VENDOR_ID_INTEL, PCI_ANY_ID, dev))
340 if (!pci_match_id(bxb_mce_pciids, dev))
342 pci_read_config_dword(dev, ICH_PFA_CFG, &addr);
350 if (!e820_all_mapped(addr, addr + PAGE_SIZE, E820_RESERVED)) {
351 pr_info("PFA table at %x not e820 reserved\n", addr);
355 pfa_table = (__force struct pfa_table *)ioremap_cache(addr, PAGE_SIZE);
357 pr_err("Cannot map PFA table at %x\n", addr);
361 if (memcmp(&pfa_table->sig, PFA_SIG, PFA_SIG_LEN) ||
362 pfa_table->len < sizeof(struct pfa_table) ||
363 /* assume newer versions are compatible */
364 pfa_table->revision < PFA_REVISION) {
365 pr_info("PFA table at %x invalid\n", addr);
369 if (!nocsum && csum((u8 *)pfa_table,
370 offsetof(struct pfa_table, command))) {
371 pr_info("PFA table at %x length %u has invalid checksum\n",
372 addr, pfa_table->len);
376 /* Not strictly needed today */
377 if (pfa_table->len > PAGE_SIZE) {
378 unsigned len = roundup(pfa_table->len, PAGE_SIZE);
380 pfa_table = (__force void *)ioremap_cache(addr, len);
382 pr_err("Cannot remap %u bytes PFA table at %x\n",
389 int status = pfa_command(0, 0, PFA_CMD_GET_TOPOLOGY, 0);
391 pr_err("Test of PFA table failed: %x\n", -status);
396 pr_info("Found Xeon75xx PFA memory error translation table at %x\n",
399 cpu_specific_poll = xeon75xx_mce_poll;
407 MODULE_DEVICE_TABLE(pci, bxb_mce_pciids);
408 MODULE_LICENSE("GPL v2");
409 MODULE_AUTHOR("Andi Kleen");
410 MODULE_DESCRIPTION("Intel Xeon 75xx specific DIMM error reporting");
413 static void __exit xeon75xx_mce_exit(void)
415 cpu_specific_poll = NULL;
417 /* Wait for all machine checks to finish before really unloading */
422 module_init(xeon75xx_mce_init);
423 module_exit(xeon75xx_mce_exit);
425 /* When built-in run as soon as the PCI subsystem is up */
426 fs_initcall(xeon75xx_mce_init);