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); |
