1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65#include <linux/module.h>
66#include <linux/ctype.h>
67#include <linux/init.h>
68#include <linux/pci.h>
69#include <linux/pci_ids.h>
70#include <linux/slab.h>
71#include <linux/mmzone.h>
72#include <linux/edac.h>
73#include <asm/msr.h>
74#include "edac_core.h"
75#include "mce_amd.h"
76
77#define amd64_debug(fmt, arg...) \
78 edac_printk(KERN_DEBUG, "amd64", fmt, ##arg)
79
80#define amd64_info(fmt, arg...) \
81 edac_printk(KERN_INFO, "amd64", fmt, ##arg)
82
83#define amd64_notice(fmt, arg...) \
84 edac_printk(KERN_NOTICE, "amd64", fmt, ##arg)
85
86#define amd64_warn(fmt, arg...) \
87 edac_printk(KERN_WARNING, "amd64", fmt, ##arg)
88
89#define amd64_err(fmt, arg...) \
90 edac_printk(KERN_ERR, "amd64", fmt, ##arg)
91
92#define amd64_mc_warn(mci, fmt, arg...) \
93 edac_mc_chipset_printk(mci, KERN_WARNING, "amd64", fmt, ##arg)
94
95#define amd64_mc_err(mci, fmt, arg...) \
96 edac_mc_chipset_printk(mci, KERN_ERR, "amd64", fmt, ##arg)
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147#define EDAC_AMD64_VERSION "3.4.0"
148#define EDAC_MOD_STR "amd64_edac"
149
150
151#define K8_REV_D 1
152#define K8_REV_E 2
153#define K8_REV_F 4
154
155
156#define NUM_CHIPSELECTS 8
157#define DRAM_RANGES 8
158
159#define ON true
160#define OFF false
161
162
163
164
165
166
167
168#define GENMASK(lo, hi) (((1ULL << ((hi) - (lo) + 1)) - 1) << (lo))
169
170
171
172
173#define PCI_DEVICE_ID_AMD_15H_NB_F1 0x1601
174#define PCI_DEVICE_ID_AMD_15H_NB_F2 0x1602
175
176
177
178
179
180#define DRAM_BASE_LO 0x40
181#define DRAM_LIMIT_LO 0x44
182
183#define dram_intlv_en(pvt, i) ((u8)((pvt->ranges[i].base.lo >> 8) & 0x7))
184#define dram_rw(pvt, i) ((u8)(pvt->ranges[i].base.lo & 0x3))
185#define dram_intlv_sel(pvt, i) ((u8)((pvt->ranges[i].lim.lo >> 8) & 0x7))
186#define dram_dst_node(pvt, i) ((u8)(pvt->ranges[i].lim.lo & 0x7))
187
188#define DHAR 0xf0
189#define dhar_valid(pvt) ((pvt)->dhar & BIT(0))
190#define dhar_mem_hoist_valid(pvt) ((pvt)->dhar & BIT(1))
191#define dhar_base(pvt) ((pvt)->dhar & 0xff000000)
192#define k8_dhar_offset(pvt) (((pvt)->dhar & 0x0000ff00) << 16)
193
194
195#define f10_dhar_offset(pvt) (((pvt)->dhar & 0x0000ff80) << 16)
196
197#define DCT_CFG_SEL 0x10C
198
199#define DRAM_LOCAL_NODE_BASE 0x120
200#define DRAM_LOCAL_NODE_LIM 0x124
201
202#define DRAM_BASE_HI 0x140
203#define DRAM_LIMIT_HI 0x144
204
205
206
207
208
209#define DCSB0 0x40
210#define DCSB1 0x140
211#define DCSB_CS_ENABLE BIT(0)
212
213#define DCSM0 0x60
214#define DCSM1 0x160
215
216#define csrow_enabled(i, dct, pvt) ((pvt)->csels[(dct)].csbases[(i)] & DCSB_CS_ENABLE)
217
218#define DBAM0 0x80
219#define DBAM1 0x180
220
221
222#define DBAM_DIMM(i, reg) ((((reg) >> (4*i))) & 0xF)
223
224#define DBAM_MAX_VALUE 11
225
226#define DCLR0 0x90
227#define DCLR1 0x190
228#define REVE_WIDTH_128 BIT(16)
229#define WIDTH_128 BIT(11)
230
231#define DCHR0 0x94
232#define DCHR1 0x194
233#define DDR3_MODE BIT(8)
234
235#define DCT_SEL_LO 0x110
236#define dct_sel_baseaddr(pvt) ((pvt)->dct_sel_lo & 0xFFFFF800)
237#define dct_sel_interleave_addr(pvt) (((pvt)->dct_sel_lo >> 6) & 0x3)
238#define dct_high_range_enabled(pvt) ((pvt)->dct_sel_lo & BIT(0))
239#define dct_interleave_enabled(pvt) ((pvt)->dct_sel_lo & BIT(2))
240
241#define dct_ganging_enabled(pvt) ((boot_cpu_data.x86 == 0x10) && ((pvt)->dct_sel_lo & BIT(4)))
242
243#define dct_data_intlv_enabled(pvt) ((pvt)->dct_sel_lo & BIT(5))
244#define dct_memory_cleared(pvt) ((pvt)->dct_sel_lo & BIT(10))
245
246#define SWAP_INTLV_REG 0x10c
247
248#define DCT_SEL_HI 0x114
249
250
251
252
253#define NBCTL 0x40
254
255#define NBCFG 0x44
256#define NBCFG_CHIPKILL BIT(23)
257#define NBCFG_ECC_ENABLE BIT(22)
258
259
260#define F10_NBSL_EXT_ERR_ECC 0x8
261#define NBSL_PP_OBS 0x2
262
263#define SCRCTRL 0x58
264
265#define F10_ONLINE_SPARE 0xB0
266#define online_spare_swap_done(pvt, c) (((pvt)->online_spare >> (1 + 2 * (c))) & 0x1)
267#define online_spare_bad_dramcs(pvt, c) (((pvt)->online_spare >> (4 + 4 * (c))) & 0x7)
268
269#define F10_NB_ARRAY_ADDR 0xB8
270#define F10_NB_ARRAY_DRAM_ECC BIT(31)
271
272
273#define SET_NB_ARRAY_ADDRESS(section) (((section) & 0x3) << 1)
274
275#define F10_NB_ARRAY_DATA 0xBC
276#define SET_NB_DRAM_INJECTION_WRITE(word, bits) \
277 (BIT(((word) & 0xF) + 20) | \
278 BIT(17) | bits)
279#define SET_NB_DRAM_INJECTION_READ(word, bits) \
280 (BIT(((word) & 0xF) + 20) | \
281 BIT(16) | bits)
282
283#define NBCAP 0xE8
284#define NBCAP_CHIPKILL BIT(4)
285#define NBCAP_SECDED BIT(3)
286#define NBCAP_DCT_DUAL BIT(0)
287
288#define EXT_NB_MCA_CFG 0x180
289
290
291#define MSR_MCGCTL_NBE BIT(4)
292
293
294static inline u8 get_node_id(struct pci_dev *pdev)
295{
296 return PCI_SLOT(pdev->devfn) - 0x18;
297}
298
299enum amd_families {
300 K8_CPUS = 0,
301 F10_CPUS,
302 F15_CPUS,
303 NUM_FAMILIES,
304};
305
306
307struct error_injection {
308 u32 section;
309 u32 word;
310 u32 bit_map;
311};
312
313
314struct reg_pair {
315 u32 lo, hi;
316};
317
318
319
320
321struct dram_range {
322 struct reg_pair base;
323 struct reg_pair lim;
324};
325
326
327struct chip_select {
328 u32 csbases[NUM_CHIPSELECTS];
329 u8 b_cnt;
330
331 u32 csmasks[NUM_CHIPSELECTS];
332 u8 m_cnt;
333};
334
335struct amd64_pvt {
336 struct low_ops *ops;
337
338
339 struct pci_dev *F1, *F2, *F3;
340
341 unsigned mc_node_id;
342 int ext_model;
343 int channel_count;
344
345
346 u32 dclr0;
347 u32 dclr1;
348 u32 dchr0;
349 u32 dchr1;
350 u32 nbcap;
351 u32 nbcfg;
352 u32 ext_nbcfg;
353 u32 dhar;
354 u32 dbam0;
355 u32 dbam1;
356
357
358 struct chip_select csels[2];
359
360
361 struct dram_range ranges[DRAM_RANGES];
362
363 u64 top_mem;
364 u64 top_mem2;
365
366 u32 dct_sel_lo;
367 u32 dct_sel_hi;
368 u32 online_spare;
369
370
371 u8 ecc_sym_sz;
372
373
374 struct error_injection injection;
375};
376
377static inline u64 get_dram_base(struct amd64_pvt *pvt, unsigned i)
378{
379 u64 addr = ((u64)pvt->ranges[i].base.lo & 0xffff0000) << 8;
380
381 if (boot_cpu_data.x86 == 0xf)
382 return addr;
383
384 return (((u64)pvt->ranges[i].base.hi & 0x000000ff) << 40) | addr;
385}
386
387static inline u64 get_dram_limit(struct amd64_pvt *pvt, unsigned i)
388{
389 u64 lim = (((u64)pvt->ranges[i].lim.lo & 0xffff0000) << 8) | 0x00ffffff;
390
391 if (boot_cpu_data.x86 == 0xf)
392 return lim;
393
394 return (((u64)pvt->ranges[i].lim.hi & 0x000000ff) << 40) | lim;
395}
396
397static inline u16 extract_syndrome(u64 status)
398{
399 return ((status >> 47) & 0xff) | ((status >> 16) & 0xff00);
400}
401
402
403
404
405struct ecc_settings {
406 u32 old_nbctl;
407 bool nbctl_valid;
408
409 struct flags {
410 unsigned long nb_mce_enable:1;
411 unsigned long nb_ecc_prev:1;
412 } flags;
413};
414
415#ifdef CONFIG_EDAC_DEBUG
416#define NUM_DBG_ATTRS 5
417#else
418#define NUM_DBG_ATTRS 0
419#endif
420
421#ifdef CONFIG_EDAC_AMD64_ERROR_INJECTION
422#define NUM_INJ_ATTRS 5
423#else
424#define NUM_INJ_ATTRS 0
425#endif
426
427extern struct mcidev_sysfs_attribute amd64_dbg_attrs[NUM_DBG_ATTRS],
428 amd64_inj_attrs[NUM_INJ_ATTRS];
429
430
431
432
433
434struct low_ops {
435 int (*early_channel_count) (struct amd64_pvt *pvt);
436 void (*map_sysaddr_to_csrow) (struct mem_ctl_info *mci, u64 sys_addr,
437 u16 syndrome);
438 int (*dbam_to_cs) (struct amd64_pvt *pvt, u8 dct, unsigned cs_mode);
439 int (*read_dct_pci_cfg) (struct amd64_pvt *pvt, int offset,
440 u32 *val, const char *func);
441};
442
443struct amd64_family_type {
444 const char *ctl_name;
445 u16 f1_id, f3_id;
446 struct low_ops ops;
447};
448
449int __amd64_write_pci_cfg_dword(struct pci_dev *pdev, int offset,
450 u32 val, const char *func);
451
452#define amd64_read_pci_cfg(pdev, offset, val) \
453 __amd64_read_pci_cfg_dword(pdev, offset, val, __func__)
454
455#define amd64_write_pci_cfg(pdev, offset, val) \
456 __amd64_write_pci_cfg_dword(pdev, offset, val, __func__)
457
458#define amd64_read_dct_pci_cfg(pvt, offset, val) \
459 pvt->ops->read_dct_pci_cfg(pvt, offset, val, __func__)
460
461int amd64_get_dram_hole_info(struct mem_ctl_info *mci, u64 *hole_base,
462 u64 *hole_offset, u64 *hole_size);
463