diff options
Diffstat (limited to 'drivers/edac/amd64_edac.h')
-rw-r--r-- | drivers/edac/amd64_edac.h | 447 |
1 files changed, 173 insertions, 274 deletions
diff --git a/drivers/edac/amd64_edac.h b/drivers/edac/amd64_edac.h index 613b9381e71a..9a666cb985b2 100644 --- a/drivers/edac/amd64_edac.h +++ b/drivers/edac/amd64_edac.h | |||
@@ -72,13 +72,28 @@ | |||
72 | #include <linux/edac.h> | 72 | #include <linux/edac.h> |
73 | #include <asm/msr.h> | 73 | #include <asm/msr.h> |
74 | #include "edac_core.h" | 74 | #include "edac_core.h" |
75 | #include "edac_mce_amd.h" | 75 | #include "mce_amd.h" |
76 | 76 | ||
77 | #define amd64_printk(level, fmt, arg...) \ | 77 | #define amd64_debug(fmt, arg...) \ |
78 | edac_printk(level, "amd64", fmt, ##arg) | 78 | edac_printk(KERN_DEBUG, "amd64", fmt, ##arg) |
79 | 79 | ||
80 | #define amd64_mc_printk(mci, level, fmt, arg...) \ | 80 | #define amd64_info(fmt, arg...) \ |
81 | edac_mc_chipset_printk(mci, level, "amd64", 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) | ||
82 | 97 | ||
83 | /* | 98 | /* |
84 | * Throughout the comments in this code, the following terms are used: | 99 | * Throughout the comments in this code, the following terms are used: |
@@ -129,96 +144,76 @@ | |||
129 | * sections 3.5.4 and 3.5.5 for more information. | 144 | * sections 3.5.4 and 3.5.5 for more information. |
130 | */ | 145 | */ |
131 | 146 | ||
132 | #define EDAC_AMD64_VERSION " Ver: 3.3.0 " __DATE__ | 147 | #define EDAC_AMD64_VERSION "3.4.0" |
133 | #define EDAC_MOD_STR "amd64_edac" | 148 | #define EDAC_MOD_STR "amd64_edac" |
134 | 149 | ||
135 | #define EDAC_MAX_NUMNODES 8 | ||
136 | |||
137 | /* Extended Model from CPUID, for CPU Revision numbers */ | 150 | /* Extended Model from CPUID, for CPU Revision numbers */ |
138 | #define K8_REV_D 1 | 151 | #define K8_REV_D 1 |
139 | #define K8_REV_E 2 | 152 | #define K8_REV_E 2 |
140 | #define K8_REV_F 4 | 153 | #define K8_REV_F 4 |
141 | 154 | ||
142 | /* Hardware limit on ChipSelect rows per MC and processors per system */ | 155 | /* Hardware limit on ChipSelect rows per MC and processors per system */ |
143 | #define MAX_CS_COUNT 8 | 156 | #define NUM_CHIPSELECTS 8 |
144 | #define DRAM_REG_COUNT 8 | 157 | #define DRAM_RANGES 8 |
145 | 158 | ||
146 | #define ON true | 159 | #define ON true |
147 | #define OFF false | 160 | #define OFF false |
148 | 161 | ||
149 | /* | 162 | /* |
163 | * Create a contiguous bitmask starting at bit position @lo and ending at | ||
164 | * position @hi. For example | ||
165 | * | ||
166 | * GENMASK(21, 39) gives us the 64bit vector 0x000000ffffe00000. | ||
167 | */ | ||
168 | #define GENMASK(lo, hi) (((1ULL << ((hi) - (lo) + 1)) - 1) << (lo)) | ||
169 | |||
170 | /* | ||
150 | * PCI-defined configuration space registers | 171 | * PCI-defined configuration space registers |
151 | */ | 172 | */ |
173 | #define PCI_DEVICE_ID_AMD_15H_NB_F1 0x1601 | ||
174 | #define PCI_DEVICE_ID_AMD_15H_NB_F2 0x1602 | ||
152 | 175 | ||
153 | 176 | ||
154 | /* | 177 | /* |
155 | * Function 1 - Address Map | 178 | * Function 1 - Address Map |
156 | */ | 179 | */ |
157 | #define K8_DRAM_BASE_LOW 0x40 | 180 | #define DRAM_BASE_LO 0x40 |
158 | #define K8_DRAM_LIMIT_LOW 0x44 | 181 | #define DRAM_LIMIT_LO 0x44 |
159 | #define K8_DHAR 0xf0 | ||
160 | |||
161 | #define DHAR_VALID BIT(0) | ||
162 | #define F10_DRAM_MEM_HOIST_VALID BIT(1) | ||
163 | 182 | ||
164 | #define DHAR_BASE_MASK 0xff000000 | 183 | #define dram_intlv_en(pvt, i) ((u8)((pvt->ranges[i].base.lo >> 8) & 0x7)) |
165 | #define dhar_base(dhar) (dhar & DHAR_BASE_MASK) | 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)) | ||
166 | 187 | ||
167 | #define K8_DHAR_OFFSET_MASK 0x0000ff00 | 188 | #define DHAR 0xf0 |
168 | #define k8_dhar_offset(dhar) ((dhar & K8_DHAR_OFFSET_MASK) << 16) | 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) | ||
169 | 193 | ||
170 | #define F10_DHAR_OFFSET_MASK 0x0000ff80 | ||
171 | /* NOTE: Extra mask bit vs K8 */ | 194 | /* NOTE: Extra mask bit vs K8 */ |
172 | #define f10_dhar_offset(dhar) ((dhar & F10_DHAR_OFFSET_MASK) << 16) | 195 | #define f10_dhar_offset(pvt) (((pvt)->dhar & 0x0000ff80) << 16) |
173 | 196 | ||
197 | #define DCT_CFG_SEL 0x10C | ||
174 | 198 | ||
175 | /* F10 High BASE/LIMIT registers */ | 199 | #define DRAM_LOCAL_NODE_BASE 0x120 |
176 | #define F10_DRAM_BASE_HIGH 0x140 | 200 | #define DRAM_LOCAL_NODE_LIM 0x124 |
177 | #define F10_DRAM_LIMIT_HIGH 0x144 | ||
178 | 201 | ||
202 | #define DRAM_BASE_HI 0x140 | ||
203 | #define DRAM_LIMIT_HI 0x144 | ||
179 | 204 | ||
180 | /* | ||
181 | * Function 2 - DRAM controller | ||
182 | */ | ||
183 | #define K8_DCSB0 0x40 | ||
184 | #define F10_DCSB1 0x140 | ||
185 | |||
186 | #define K8_DCSB_CS_ENABLE BIT(0) | ||
187 | #define K8_DCSB_NPT_SPARE BIT(1) | ||
188 | #define K8_DCSB_NPT_TESTFAIL BIT(2) | ||
189 | 205 | ||
190 | /* | 206 | /* |
191 | * REV E: select [31:21] and [15:9] from DCSB and the shift amount to form | 207 | * Function 2 - DRAM controller |
192 | * the address | ||
193 | */ | ||
194 | #define REV_E_DCSB_BASE_BITS (0xFFE0FE00ULL) | ||
195 | #define REV_E_DCS_SHIFT 4 | ||
196 | |||
197 | #define REV_F_F1Xh_DCSB_BASE_BITS (0x1FF83FE0ULL) | ||
198 | #define REV_F_F1Xh_DCS_SHIFT 8 | ||
199 | |||
200 | /* | ||
201 | * REV F and later: selects [28:19] and [13:5] from DCSB and the shift amount | ||
202 | * to form the address | ||
203 | */ | 208 | */ |
204 | #define REV_F_DCSB_BASE_BITS (0x1FF83FE0ULL) | 209 | #define DCSB0 0x40 |
205 | #define REV_F_DCS_SHIFT 8 | 210 | #define DCSB1 0x140 |
206 | 211 | #define DCSB_CS_ENABLE BIT(0) | |
207 | /* DRAM CS Mask Registers */ | ||
208 | #define K8_DCSM0 0x60 | ||
209 | #define F10_DCSM1 0x160 | ||
210 | |||
211 | /* REV E: select [29:21] and [15:9] from DCSM */ | ||
212 | #define REV_E_DCSM_MASK_BITS 0x3FE0FE00 | ||
213 | |||
214 | /* unused bits [24:20] and [12:0] */ | ||
215 | #define REV_E_DCS_NOTUSED_BITS 0x01F01FFF | ||
216 | 212 | ||
217 | /* REV F and later: select [28:19] and [13:5] from DCSM */ | 213 | #define DCSM0 0x60 |
218 | #define REV_F_F1Xh_DCSM_MASK_BITS 0x1FF83FE0 | 214 | #define DCSM1 0x160 |
219 | 215 | ||
220 | /* unused bits [26:22] and [12:0] */ | 216 | #define csrow_enabled(i, dct, pvt) ((pvt)->csels[(dct)].csbases[(i)] & DCSB_CS_ENABLE) |
221 | #define REV_F_F1Xh_DCS_NOTUSED_BITS 0x07C01FFF | ||
222 | 217 | ||
223 | #define DBAM0 0x80 | 218 | #define DBAM0 0x80 |
224 | #define DBAM1 0x180 | 219 | #define DBAM1 0x180 |
@@ -228,152 +223,84 @@ | |||
228 | 223 | ||
229 | #define DBAM_MAX_VALUE 11 | 224 | #define DBAM_MAX_VALUE 11 |
230 | 225 | ||
231 | 226 | #define DCLR0 0x90 | |
232 | #define F10_DCLR_0 0x90 | 227 | #define DCLR1 0x190 |
233 | #define F10_DCLR_1 0x190 | ||
234 | #define REVE_WIDTH_128 BIT(16) | 228 | #define REVE_WIDTH_128 BIT(16) |
235 | #define F10_WIDTH_128 BIT(11) | 229 | #define WIDTH_128 BIT(11) |
236 | 230 | ||
231 | #define DCHR0 0x94 | ||
232 | #define DCHR1 0x194 | ||
233 | #define DDR3_MODE BIT(8) | ||
237 | 234 | ||
238 | #define F10_DCHR_0 0x94 | 235 | #define DCT_SEL_LO 0x110 |
239 | #define F10_DCHR_1 0x194 | 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 | 240 | ||
241 | #define F10_DCHR_FOUR_RANK_DIMM BIT(18) | 241 | #define dct_ganging_enabled(pvt) ((boot_cpu_data.x86 == 0x10) && ((pvt)->dct_sel_lo & BIT(4))) |
242 | #define DDR3_MODE BIT(8) | ||
243 | #define F10_DCHR_MblMode BIT(6) | ||
244 | 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 | 245 | ||
246 | #define F10_DCTL_SEL_LOW 0x110 | 246 | #define SWAP_INTLV_REG 0x10c |
247 | #define dct_sel_baseaddr(pvt) ((pvt->dram_ctl_select_low) & 0xFFFFF800) | ||
248 | #define dct_sel_interleave_addr(pvt) (((pvt->dram_ctl_select_low) >> 6) & 0x3) | ||
249 | #define dct_high_range_enabled(pvt) (pvt->dram_ctl_select_low & BIT(0)) | ||
250 | #define dct_interleave_enabled(pvt) (pvt->dram_ctl_select_low & BIT(2)) | ||
251 | #define dct_ganging_enabled(pvt) (pvt->dram_ctl_select_low & BIT(4)) | ||
252 | #define dct_data_intlv_enabled(pvt) (pvt->dram_ctl_select_low & BIT(5)) | ||
253 | #define dct_dram_enabled(pvt) (pvt->dram_ctl_select_low & BIT(8)) | ||
254 | #define dct_memory_cleared(pvt) (pvt->dram_ctl_select_low & BIT(10)) | ||
255 | 247 | ||
256 | #define F10_DCTL_SEL_HIGH 0x114 | 248 | #define DCT_SEL_HI 0x114 |
257 | 249 | ||
258 | /* | 250 | /* |
259 | * Function 3 - Misc Control | 251 | * Function 3 - Misc Control |
260 | */ | 252 | */ |
261 | #define K8_NBCTL 0x40 | 253 | #define NBCTL 0x40 |
262 | |||
263 | /* Correctable ECC error reporting enable */ | ||
264 | #define K8_NBCTL_CECCEn BIT(0) | ||
265 | |||
266 | /* UnCorrectable ECC error reporting enable */ | ||
267 | #define K8_NBCTL_UECCEn BIT(1) | ||
268 | |||
269 | #define K8_NBCFG 0x44 | ||
270 | #define K8_NBCFG_CHIPKILL BIT(23) | ||
271 | #define K8_NBCFG_ECC_ENABLE BIT(22) | ||
272 | 254 | ||
273 | #define K8_NBSL 0x48 | 255 | #define NBCFG 0x44 |
256 | #define NBCFG_CHIPKILL BIT(23) | ||
257 | #define NBCFG_ECC_ENABLE BIT(22) | ||
274 | 258 | ||
275 | 259 | /* F3x48: NBSL */ | |
276 | /* Family F10h: Normalized Extended Error Codes */ | ||
277 | #define F10_NBSL_EXT_ERR_RES 0x0 | ||
278 | #define F10_NBSL_EXT_ERR_ECC 0x8 | 260 | #define F10_NBSL_EXT_ERR_ECC 0x8 |
261 | #define NBSL_PP_OBS 0x2 | ||
279 | 262 | ||
280 | /* Next two are overloaded values */ | 263 | #define SCRCTRL 0x58 |
281 | #define F10_NBSL_EXT_ERR_LINK_PROTO 0xB | ||
282 | #define F10_NBSL_EXT_ERR_L3_PROTO 0xB | ||
283 | |||
284 | #define F10_NBSL_EXT_ERR_NB_ARRAY 0xC | ||
285 | #define F10_NBSL_EXT_ERR_DRAM_PARITY 0xD | ||
286 | #define F10_NBSL_EXT_ERR_LINK_RETRY 0xE | ||
287 | |||
288 | /* Next two are overloaded values */ | ||
289 | #define F10_NBSL_EXT_ERR_GART_WALK 0xF | ||
290 | #define F10_NBSL_EXT_ERR_DEV_WALK 0xF | ||
291 | |||
292 | /* 0x10 to 0x1B: Reserved */ | ||
293 | #define F10_NBSL_EXT_ERR_L3_DATA 0x1C | ||
294 | #define F10_NBSL_EXT_ERR_L3_TAG 0x1D | ||
295 | #define F10_NBSL_EXT_ERR_L3_LRU 0x1E | ||
296 | |||
297 | /* K8: Normalized Extended Error Codes */ | ||
298 | #define K8_NBSL_EXT_ERR_ECC 0x0 | ||
299 | #define K8_NBSL_EXT_ERR_CRC 0x1 | ||
300 | #define K8_NBSL_EXT_ERR_SYNC 0x2 | ||
301 | #define K8_NBSL_EXT_ERR_MST 0x3 | ||
302 | #define K8_NBSL_EXT_ERR_TGT 0x4 | ||
303 | #define K8_NBSL_EXT_ERR_GART 0x5 | ||
304 | #define K8_NBSL_EXT_ERR_RMW 0x6 | ||
305 | #define K8_NBSL_EXT_ERR_WDT 0x7 | ||
306 | #define K8_NBSL_EXT_ERR_CHIPKILL_ECC 0x8 | ||
307 | #define K8_NBSL_EXT_ERR_DRAM_PARITY 0xD | ||
308 | |||
309 | /* | ||
310 | * The following are for BUS type errors AFTER values have been normalized by | ||
311 | * shifting right | ||
312 | */ | ||
313 | #define K8_NBSL_PP_SRC 0x0 | ||
314 | #define K8_NBSL_PP_RES 0x1 | ||
315 | #define K8_NBSL_PP_OBS 0x2 | ||
316 | #define K8_NBSL_PP_GENERIC 0x3 | ||
317 | |||
318 | #define EXTRACT_ERR_CPU_MAP(x) ((x) & 0xF) | ||
319 | |||
320 | #define K8_NBEAL 0x50 | ||
321 | #define K8_NBEAH 0x54 | ||
322 | #define K8_SCRCTRL 0x58 | ||
323 | |||
324 | #define F10_NB_CFG_LOW 0x88 | ||
325 | #define F10_NB_CFG_LOW_ENABLE_EXT_CFG BIT(14) | ||
326 | |||
327 | #define F10_NB_CFG_HIGH 0x8C | ||
328 | 264 | ||
329 | #define F10_ONLINE_SPARE 0xB0 | 265 | #define F10_ONLINE_SPARE 0xB0 |
330 | #define F10_ONLINE_SPARE_SWAPDONE0(x) ((x) & BIT(1)) | 266 | #define online_spare_swap_done(pvt, c) (((pvt)->online_spare >> (1 + 2 * (c))) & 0x1) |
331 | #define F10_ONLINE_SPARE_SWAPDONE1(x) ((x) & BIT(3)) | 267 | #define online_spare_bad_dramcs(pvt, c) (((pvt)->online_spare >> (4 + 4 * (c))) & 0x7) |
332 | #define F10_ONLINE_SPARE_BADDRAM_CS0(x) (((x) >> 4) & 0x00000007) | ||
333 | #define F10_ONLINE_SPARE_BADDRAM_CS1(x) (((x) >> 8) & 0x00000007) | ||
334 | 268 | ||
335 | #define F10_NB_ARRAY_ADDR 0xB8 | 269 | #define F10_NB_ARRAY_ADDR 0xB8 |
336 | 270 | #define F10_NB_ARRAY_DRAM_ECC BIT(31) | |
337 | #define F10_NB_ARRAY_DRAM_ECC 0x80000000 | ||
338 | 271 | ||
339 | /* Bits [2:1] are used to select 16-byte section within a 64-byte cacheline */ | 272 | /* Bits [2:1] are used to select 16-byte section within a 64-byte cacheline */ |
340 | #define SET_NB_ARRAY_ADDRESS(section) (((section) & 0x3) << 1) | 273 | #define SET_NB_ARRAY_ADDRESS(section) (((section) & 0x3) << 1) |
341 | 274 | ||
342 | #define F10_NB_ARRAY_DATA 0xBC | 275 | #define F10_NB_ARRAY_DATA 0xBC |
343 | |||
344 | #define SET_NB_DRAM_INJECTION_WRITE(word, bits) \ | 276 | #define SET_NB_DRAM_INJECTION_WRITE(word, bits) \ |
345 | (BIT(((word) & 0xF) + 20) | \ | 277 | (BIT(((word) & 0xF) + 20) | \ |
346 | BIT(17) | bits) | 278 | BIT(17) | bits) |
347 | |||
348 | #define SET_NB_DRAM_INJECTION_READ(word, bits) \ | 279 | #define SET_NB_DRAM_INJECTION_READ(word, bits) \ |
349 | (BIT(((word) & 0xF) + 20) | \ | 280 | (BIT(((word) & 0xF) + 20) | \ |
350 | BIT(16) | bits) | 281 | BIT(16) | bits) |
351 | 282 | ||
352 | #define K8_NBCAP 0xE8 | 283 | #define NBCAP 0xE8 |
353 | #define K8_NBCAP_CORES (BIT(12)|BIT(13)) | 284 | #define NBCAP_CHIPKILL BIT(4) |
354 | #define K8_NBCAP_CHIPKILL BIT(4) | 285 | #define NBCAP_SECDED BIT(3) |
355 | #define K8_NBCAP_SECDED BIT(3) | 286 | #define NBCAP_DCT_DUAL BIT(0) |
356 | #define K8_NBCAP_DCT_DUAL BIT(0) | ||
357 | 287 | ||
358 | #define EXT_NB_MCA_CFG 0x180 | 288 | #define EXT_NB_MCA_CFG 0x180 |
359 | 289 | ||
360 | /* MSRs */ | 290 | /* MSRs */ |
361 | #define K8_MSR_MCGCTL_NBE BIT(4) | 291 | #define MSR_MCGCTL_NBE BIT(4) |
362 | |||
363 | #define K8_MSR_MC4CTL 0x0410 | ||
364 | #define K8_MSR_MC4STAT 0x0411 | ||
365 | #define K8_MSR_MC4ADDR 0x0412 | ||
366 | 292 | ||
367 | /* AMD sets the first MC device at device ID 0x18. */ | 293 | /* AMD sets the first MC device at device ID 0x18. */ |
368 | static inline int get_node_id(struct pci_dev *pdev) | 294 | static inline u8 get_node_id(struct pci_dev *pdev) |
369 | { | 295 | { |
370 | return PCI_SLOT(pdev->devfn) - 0x18; | 296 | return PCI_SLOT(pdev->devfn) - 0x18; |
371 | } | 297 | } |
372 | 298 | ||
373 | enum amd64_chipset_families { | 299 | enum amd_families { |
374 | K8_CPUS = 0, | 300 | K8_CPUS = 0, |
375 | F10_CPUS, | 301 | F10_CPUS, |
376 | F11_CPUS, | 302 | F15_CPUS, |
303 | NUM_FAMILIES, | ||
377 | }; | 304 | }; |
378 | 305 | ||
379 | /* Error injection control structure */ | 306 | /* Error injection control structure */ |
@@ -383,17 +310,36 @@ struct error_injection { | |||
383 | u32 bit_map; | 310 | u32 bit_map; |
384 | }; | 311 | }; |
385 | 312 | ||
313 | /* low and high part of PCI config space regs */ | ||
314 | struct reg_pair { | ||
315 | u32 lo, hi; | ||
316 | }; | ||
317 | |||
318 | /* | ||
319 | * See F1x[1, 0][7C:40] DRAM Base/Limit Registers | ||
320 | */ | ||
321 | struct dram_range { | ||
322 | struct reg_pair base; | ||
323 | struct reg_pair lim; | ||
324 | }; | ||
325 | |||
326 | /* A DCT chip selects collection */ | ||
327 | struct chip_select { | ||
328 | u32 csbases[NUM_CHIPSELECTS]; | ||
329 | u8 b_cnt; | ||
330 | |||
331 | u32 csmasks[NUM_CHIPSELECTS]; | ||
332 | u8 m_cnt; | ||
333 | }; | ||
334 | |||
386 | struct amd64_pvt { | 335 | struct amd64_pvt { |
336 | struct low_ops *ops; | ||
337 | |||
387 | /* pci_device handles which we utilize */ | 338 | /* pci_device handles which we utilize */ |
388 | struct pci_dev *addr_f1_ctl; | 339 | struct pci_dev *F1, *F2, *F3; |
389 | struct pci_dev *dram_f2_ctl; | ||
390 | struct pci_dev *misc_f3_ctl; | ||
391 | 340 | ||
392 | int mc_node_id; /* MC index of this MC node */ | 341 | unsigned mc_node_id; /* MC index of this MC node */ |
393 | int ext_model; /* extended model value of this node */ | 342 | int ext_model; /* extended model value of this node */ |
394 | |||
395 | struct low_ops *ops; /* pointer to per PCI Device ID func table */ | ||
396 | |||
397 | int channel_count; | 343 | int channel_count; |
398 | 344 | ||
399 | /* Raw registers */ | 345 | /* Raw registers */ |
@@ -408,85 +354,66 @@ struct amd64_pvt { | |||
408 | u32 dbam0; /* DRAM Base Address Mapping reg for DCT0 */ | 354 | u32 dbam0; /* DRAM Base Address Mapping reg for DCT0 */ |
409 | u32 dbam1; /* DRAM Base Address Mapping reg for DCT1 */ | 355 | u32 dbam1; /* DRAM Base Address Mapping reg for DCT1 */ |
410 | 356 | ||
411 | /* DRAM CS Base Address Registers F2x[1,0][5C:40] */ | 357 | /* one for each DCT */ |
412 | u32 dcsb0[MAX_CS_COUNT]; | 358 | struct chip_select csels[2]; |
413 | u32 dcsb1[MAX_CS_COUNT]; | 359 | |
414 | 360 | /* DRAM base and limit pairs F1x[78,70,68,60,58,50,48,40] */ | |
415 | /* DRAM CS Mask Registers F2x[1,0][6C:60] */ | 361 | struct dram_range ranges[DRAM_RANGES]; |
416 | u32 dcsm0[MAX_CS_COUNT]; | ||
417 | u32 dcsm1[MAX_CS_COUNT]; | ||
418 | |||
419 | /* | ||
420 | * Decoded parts of DRAM BASE and LIMIT Registers | ||
421 | * F1x[78,70,68,60,58,50,48,40] | ||
422 | */ | ||
423 | u64 dram_base[DRAM_REG_COUNT]; | ||
424 | u64 dram_limit[DRAM_REG_COUNT]; | ||
425 | u8 dram_IntlvSel[DRAM_REG_COUNT]; | ||
426 | u8 dram_IntlvEn[DRAM_REG_COUNT]; | ||
427 | u8 dram_DstNode[DRAM_REG_COUNT]; | ||
428 | u8 dram_rw_en[DRAM_REG_COUNT]; | ||
429 | |||
430 | /* | ||
431 | * The following fields are set at (load) run time, after CPU revision | ||
432 | * has been determined, since the dct_base and dct_mask registers vary | ||
433 | * based on revision | ||
434 | */ | ||
435 | u32 dcsb_base; /* DCSB base bits */ | ||
436 | u32 dcsm_mask; /* DCSM mask bits */ | ||
437 | u32 cs_count; /* num chip selects (== num DCSB registers) */ | ||
438 | u32 num_dcsm; /* Number of DCSM registers */ | ||
439 | u32 dcs_mask_notused; /* DCSM notused mask bits */ | ||
440 | u32 dcs_shift; /* DCSB and DCSM shift value */ | ||
441 | 362 | ||
442 | u64 top_mem; /* top of memory below 4GB */ | 363 | u64 top_mem; /* top of memory below 4GB */ |
443 | u64 top_mem2; /* top of memory above 4GB */ | 364 | u64 top_mem2; /* top of memory above 4GB */ |
444 | 365 | ||
445 | u32 dram_ctl_select_low; /* DRAM Controller Select Low Reg */ | 366 | u32 dct_sel_lo; /* DRAM Controller Select Low */ |
446 | u32 dram_ctl_select_high; /* DRAM Controller Select High Reg */ | 367 | u32 dct_sel_hi; /* DRAM Controller Select High */ |
447 | u32 online_spare; /* On-Line spare Reg */ | 368 | u32 online_spare; /* On-Line spare Reg */ |
448 | 369 | ||
449 | /* x4 or x8 syndromes in use */ | 370 | /* x4 or x8 syndromes in use */ |
450 | u8 syn_type; | 371 | u8 ecc_sym_sz; |
451 | |||
452 | /* temp storage for when input is received from sysfs */ | ||
453 | struct err_regs ctl_error_info; | ||
454 | 372 | ||
455 | /* place to store error injection parameters prior to issue */ | 373 | /* place to store error injection parameters prior to issue */ |
456 | struct error_injection injection; | 374 | struct error_injection injection; |
375 | }; | ||
457 | 376 | ||
458 | /* Save old hw registers' values before we modified them */ | 377 | static inline u64 get_dram_base(struct amd64_pvt *pvt, unsigned i) |
459 | u32 nbctl_mcgctl_saved; /* When true, following 2 are valid */ | 378 | { |
460 | u32 old_nbctl; | 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 | |||
387 | static inline u64 get_dram_limit(struct amd64_pvt *pvt, unsigned i) | ||
388 | { | ||
389 | u64 lim = (((u64)pvt->ranges[i].lim.lo & 0xffff0000) << 8) | 0x00ffffff; | ||
461 | 390 | ||
462 | /* MC Type Index value: socket F vs Family 10h */ | 391 | if (boot_cpu_data.x86 == 0xf) |
463 | u32 mc_type_index; | 392 | return lim; |
393 | |||
394 | return (((u64)pvt->ranges[i].lim.hi & 0x000000ff) << 40) | lim; | ||
395 | } | ||
396 | |||
397 | static inline u16 extract_syndrome(u64 status) | ||
398 | { | ||
399 | return ((status >> 47) & 0xff) | ((status >> 16) & 0xff00); | ||
400 | } | ||
401 | |||
402 | /* | ||
403 | * per-node ECC settings descriptor | ||
404 | */ | ||
405 | struct ecc_settings { | ||
406 | u32 old_nbctl; | ||
407 | bool nbctl_valid; | ||
464 | 408 | ||
465 | /* misc settings */ | ||
466 | struct flags { | 409 | struct flags { |
467 | unsigned long cf8_extcfg:1; | ||
468 | unsigned long nb_mce_enable:1; | 410 | unsigned long nb_mce_enable:1; |
469 | unsigned long nb_ecc_prev:1; | 411 | unsigned long nb_ecc_prev:1; |
470 | } flags; | 412 | } flags; |
471 | }; | 413 | }; |
472 | 414 | ||
473 | struct scrubrate { | ||
474 | u32 scrubval; /* bit pattern for scrub rate */ | ||
475 | u32 bandwidth; /* bandwidth consumed (bytes/sec) */ | ||
476 | }; | ||
477 | |||
478 | extern struct scrubrate scrubrates[23]; | ||
479 | extern const char *tt_msgs[4]; | ||
480 | extern const char *ll_msgs[4]; | ||
481 | extern const char *rrrr_msgs[16]; | ||
482 | extern const char *to_msgs[2]; | ||
483 | extern const char *pp_msgs[4]; | ||
484 | extern const char *ii_msgs[4]; | ||
485 | extern const char *ext_msgs[32]; | ||
486 | extern const char *htlink_msgs[8]; | ||
487 | |||
488 | #ifdef CONFIG_EDAC_DEBUG | 415 | #ifdef CONFIG_EDAC_DEBUG |
489 | #define NUM_DBG_ATTRS 9 | 416 | #define NUM_DBG_ATTRS 5 |
490 | #else | 417 | #else |
491 | #define NUM_DBG_ATTRS 0 | 418 | #define NUM_DBG_ATTRS 0 |
492 | #endif | 419 | #endif |
@@ -506,58 +433,30 @@ extern struct mcidev_sysfs_attribute amd64_dbg_attrs[NUM_DBG_ATTRS], | |||
506 | */ | 433 | */ |
507 | struct low_ops { | 434 | struct low_ops { |
508 | int (*early_channel_count) (struct amd64_pvt *pvt); | 435 | int (*early_channel_count) (struct amd64_pvt *pvt); |
509 | 436 | void (*map_sysaddr_to_csrow) (struct mem_ctl_info *mci, u64 sys_addr, | |
510 | u64 (*get_error_address) (struct mem_ctl_info *mci, | 437 | u16 syndrome); |
511 | struct err_regs *info); | 438 | int (*dbam_to_cs) (struct amd64_pvt *pvt, u8 dct, unsigned cs_mode); |
512 | void (*read_dram_base_limit) (struct amd64_pvt *pvt, int dram); | 439 | int (*read_dct_pci_cfg) (struct amd64_pvt *pvt, int offset, |
513 | void (*read_dram_ctl_register) (struct amd64_pvt *pvt); | 440 | u32 *val, const char *func); |
514 | void (*map_sysaddr_to_csrow) (struct mem_ctl_info *mci, | ||
515 | struct err_regs *info, u64 SystemAddr); | ||
516 | int (*dbam_to_cs) (struct amd64_pvt *pvt, int cs_mode); | ||
517 | }; | 441 | }; |
518 | 442 | ||
519 | struct amd64_family_type { | 443 | struct amd64_family_type { |
520 | const char *ctl_name; | 444 | const char *ctl_name; |
521 | u16 addr_f1_ctl; | 445 | u16 f1_id, f3_id; |
522 | u16 misc_f3_ctl; | ||
523 | struct low_ops ops; | 446 | struct low_ops ops; |
524 | }; | 447 | }; |
525 | 448 | ||
526 | static struct amd64_family_type amd64_family_types[]; | 449 | int __amd64_write_pci_cfg_dword(struct pci_dev *pdev, int offset, |
527 | 450 | u32 val, const char *func); | |
528 | static inline const char *get_amd_family_name(int index) | ||
529 | { | ||
530 | return amd64_family_types[index].ctl_name; | ||
531 | } | ||
532 | |||
533 | static inline struct low_ops *family_ops(int index) | ||
534 | { | ||
535 | return &amd64_family_types[index].ops; | ||
536 | } | ||
537 | |||
538 | static inline int amd64_read_pci_cfg_dword(struct pci_dev *pdev, int offset, | ||
539 | u32 *val, const char *func) | ||
540 | { | ||
541 | int err = 0; | ||
542 | |||
543 | err = pci_read_config_dword(pdev, offset, val); | ||
544 | if (err) | ||
545 | amd64_printk(KERN_WARNING, "%s: error reading F%dx%x.\n", | ||
546 | func, PCI_FUNC(pdev->devfn), offset); | ||
547 | |||
548 | return err; | ||
549 | } | ||
550 | 451 | ||
551 | #define amd64_read_pci_cfg(pdev, offset, val) \ | 452 | #define amd64_read_pci_cfg(pdev, offset, val) \ |
552 | amd64_read_pci_cfg_dword(pdev, offset, val, __func__) | 453 | __amd64_read_pci_cfg_dword(pdev, offset, val, __func__) |
553 | 454 | ||
554 | /* | 455 | #define amd64_write_pci_cfg(pdev, offset, val) \ |
555 | * For future CPU versions, verify the following as new 'slow' rates appear and | 456 | __amd64_write_pci_cfg_dword(pdev, offset, val, __func__) |
556 | * modify the necessary skip values for the supported CPU. | 457 | |
557 | */ | 458 | #define amd64_read_dct_pci_cfg(pvt, offset, val) \ |
558 | #define K8_MIN_SCRUB_RATE_BITS 0x0 | 459 | pvt->ops->read_dct_pci_cfg(pvt, offset, val, __func__) |
559 | #define F10_MIN_SCRUB_RATE_BITS 0x5 | ||
560 | #define F11_MIN_SCRUB_RATE_BITS 0x6 | ||
561 | 460 | ||
562 | int amd64_get_dram_hole_info(struct mem_ctl_info *mci, u64 *hole_base, | 461 | int amd64_get_dram_hole_info(struct mem_ctl_info *mci, u64 *hole_base, |
563 | u64 *hole_offset, u64 *hole_size); | 462 | u64 *hole_offset, u64 *hole_size); |