1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 * 21 * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 22 * Use is subject to license terms. 23 */ 24 25 #ifndef _MC_AMD_H 26 #define _MC_AMD_H 27 28 #include <sys/mc.h> 29 #include <sys/isa_defs.h> 30 #include <sys/x86_archext.h> 31 32 #ifdef __cplusplus 33 extern "C" { 34 #endif 35 36 /* 37 * Definitions, register offsets, register structure etc pertaining to 38 * the memory controller on AMD64 systems. These are used by both the 39 * AMD cpu module and the mc-amd driver. 40 */ 41 42 /* 43 * The mc-amd driver exports an nvlist to userland, where the primary 44 * consumer is the "chip" topology enumerator for this platform type which 45 * builds a full topology subtree from this information. Others can use 46 * it, too, but don't depend on it not changing without an ARC contract 47 * (and the contract should probably concern the topology, not this nvlist). 48 * 49 * In the initial mc-amd implementation this nvlist was not versioned; 50 * we'll think of that as version 0 and it may be recognised by the absence 51 * of a "mcamd-nvlist-version member. 52 * 53 * Version 1 is defined as follows. A name in square brackets indicates 54 * that member is optional (only present if the actual value is valid). 55 * 56 * Name Type Description 57 * -------------------- --------------- --------------------------------------- 58 * mcamd-nvlist-version uint8 Exported nvlist version number 59 * num uint64 Chip id of this memory controller 60 * revision uint64 cpuid_getchiprev() result 61 * revname string cpuid_getchiprevstr() result 62 * socket string "Socket 755|939|940|AM2|F(1207)|S1g1" 63 * ecc-type string "ChipKill 128/16" or "Normal 64/8" 64 * base-addr uint64 Node base address 65 * lim-addr uint64 Node limit address 66 * node-ilen uint64 0|1|3|7 for 0/2/4/8 way node interleave 67 * node-ilsel uint64 Node interleave position of this node 68 * cs-intlv-factor uint64 chip-select interleave: 1/2/4/8 69 * dram-hole-size uint64 size in bytes from dram hole addr reg 70 * access-width uint64 MC mode, 64 or 128 bit 71 * bank-mapping uint64 Raw DRAM Bank Address Mapping Register 72 * bankswizzle uint64 1 if bank swizzling enabled; else 0 73 * mismatched-dimm-support uint64 1 if active; else 0 74 * [spare-csnum] uint64 Chip-select pair number of any spare 75 * [bad-csnum] uint64 Chip-select pair number of swapped cs 76 * cslist nvlist array See below; may have 0 members 77 * dimmlist nvlist array See below; may have 0 members 78 * 79 * cslist is an array of nvlist, each as follows: 80 * 81 * Name Type Description 82 * -------------------- --------------- --------------------------------------- 83 * num uint64 Chip-select base/mask pair number 84 * base-addr uint64 Chip-select base address (rel to node) 85 * mask uint64 Chip-select mask 86 * size uint64 Chip-select size in bytes 87 * dimm1-num uint64 First dimm (lodimm if a pair) 88 * dimm1-csname string Socket cs# line name for 1st dimm rank 89 * [dimm2-num] uint64 Second dimm if applicable (updimm) 90 * [dimm2-csname] string Socket cs# line name for 2nd dimm rank 91 * 92 * dimmlist is an array of nvlist, each as follows: 93 * 94 * Name Type Description 95 * -------------------- --------------- --------------------------------------- 96 * num uint64 DIMM instance number 97 * size uint64 DIMM size in bytes 98 * csnums uint64 array CS base/mask pair(s) on this DIMM 99 * csnames string array Socket cs# line name(s) on this DIMM 100 * 101 * The n'th csnums entry corresponds to the n'th csnames entry 102 */ 103 #define MC_NVLIST_VERSTR "mcamd-nvlist-version" 104 #define MC_NVLIST_VERS0 0 105 #define MC_NVLIST_VERS1 1 106 #define MC_NVLIST_VERS MC_NVLIST_VERS1 107 108 /* 109 * Constants and feature/revision test macros that are not expected to vary 110 * among different AMD family 0xf processor revisions. 111 */ 112 113 /* 114 * Configuration constants 115 */ 116 #define MC_CHIP_MAXNODES 8 /* max number of MCs in system */ 117 #define MC_CHIP_NDIMM 8 /* max dimms per MC */ 118 #define MC_CHIP_NCS 8 /* number of chip-selects per MC */ 119 #define MC_CHIP_NDRAMCHAN 2 /* maximum number of dram channels */ 120 #define MC_CHIP_DIMMRANKMAX 4 /* largest number of ranks per dimm */ 121 #define MC_CHIP_DIMMPERCS 2 /* max number of dimms per cs */ 122 #define MC_CHIP_DIMMPAIR(csnum) (csnum / MC_CHIP_DIMMPERCS) 123 124 /* 125 * Memory controller registers are read via PCI config space accesses on 126 * bus 0, device 0x18 + NodeId, and function as follows: 127 * 128 * Function 0: HyperTransport Technology Configuration 129 * Function 1: Address Map 130 * Function 2: DRAM Controller & HyperTransport Technology Trace Mode 131 * Function 3: Miscellaneous Control 132 */ 133 134 #define MC_AMD_DEV_OFFSET 0x18 /* node ID + offset == PCI dev num */ 135 136 enum mc_funcnum { 137 MC_FUNC_HTCONFIG = 0, 138 MC_FUNC_ADDRMAP = 1, 139 MC_FUNC_DRAMCTL = 2, 140 MC_FUNC_MISCCTL = 3 141 }; 142 143 /* 144 * For a given (bus, device, function) a particular offset selects the 145 * desired register. All registers are 32-bits wide. 146 * 147 * Different family 0xf processor revisions vary slightly in the content 148 * of these configuration registers. The biggest change is with rev F 149 * where DDR2 support has been introduced along with some hardware-controlled 150 * correctable memory error thresholding. Fortunately most of the config info 151 * required by the mc-amd driver is similar across revisions. 152 * 153 * We will try to insulate most of the driver code from config register 154 * details by reading all memory-controller PCI config registers that we 155 * will need at driver attach time for each of functions 0 through 3, and 156 * storing them in a "cooked" form as memory controller properties. 157 * These are to be accessed directly where we have an mc_t to hand, otherwise 158 * through mcamd_get_numprop. As such we expect most/all use of the 159 * structures and macros defined below to be in those attach codepaths. 160 */ 161 162 /* 163 * Function 0 (HT Config) offsets 164 */ 165 #define MC_HT_REG_RTBL_NODE_0 0x40 166 #define MC_HT_REG_RTBL_INCR 4 167 #define MC_HT_REG_NODEID 0x60 168 #define MC_HT_REG_UNITID 0x64 169 170 /* 171 * Function 1 (address map) offsets for DRAM base, DRAM limit, DRAM hole 172 * registers. 173 */ 174 #define MC_AM_REG_DRAMBASE_0 0x40 /* Offset for DRAM Base 0 */ 175 #define MC_AM_REG_DRAMLIM_0 0x44 /* Offset for DRAM Limit 0 */ 176 #define MC_AM_REG_DRAM_INCR 8 /* incr between base/limit pairs */ 177 #define MC_AM_REG_HOLEADDR 0xf0 /* DRAM Hole Address Register */ 178 179 /* 180 * Function 2 (dram controller) offsets for chip-select base, chip-select mask, 181 * DRAM bank address mapping, DRAM configuration registers. 182 */ 183 #define MC_DC_REG_CS_INCR 4 /* incr for CS base and mask */ 184 #define MC_DC_REG_CSBASE_0 0x40 /* 0x40 - 0x5c */ 185 #define MC_DC_REG_CSMASK_0 0x60 /* 0x60 - 0x7c */ 186 #define MC_DC_REG_BANKADDRMAP 0x80 /* DRAM Bank Address Mapping */ 187 #define MC_DC_REG_DRAMCFGLO 0x90 /* DRAM Configuration Low */ 188 #define MC_DC_REG_DRAMCFGHI 0x94 /* DRAM Configuration High */ 189 #define MC_DC_REG_DRAMMISC 0xa0 /* DRAM Miscellaneous */ 190 191 /* 192 * Function 3 (misc control) offset for NB MCA config, scrubber control, 193 * online spare control and NB capabilities. 194 */ 195 #define MC_CTL_REG_NBCFG 0x44 /* MCA NB configuration register */ 196 #define MC_CTL_REG_SCRUBCTL 0x58 /* Scrub control register */ 197 #define MC_CTL_REG_SCRUBADDR_LO 0x5c /* DRAM Scrub Address Low */ 198 #define MC_CTL_REG_SCRUBADDR_HI 0x60 /* DRAM Scrub Address High */ 199 #define MC_CTL_REG_SPARECTL 0xb0 /* On-line spare control register */ 200 #define MC_CTL_REG_NBCAP 0xe8 /* NB Capabilities */ 201 #define MC_CTL_REG_EXTNBCFG 0x180 /* Ext. MCA NB configuration register */ 202 203 #define MC_NBCAP_L3CAPABLE (1U << 25) 204 #define MC_NBCAP_MULTINODECPU (1U << 29) 205 #define MC_EXTNBCFG_ECCSYMSZ (1U << 25) 206 207 /* 208 * MC4_MISC MSR and MC4_MISCj MSRs 209 */ 210 #define MC_MSR_NB_MISC0 0x413 211 #define MC_MSR_NB_MISC1 0xc0000408 212 #define MC_MSR_NB_MISC2 0xc0000409 213 #define MC_MSR_NB_MISC3 0xc000040a 214 #define MC_MSR_NB_MISC(j) \ 215 ((j) == 0 ? MC_MSR_NB_MISC0 : MC_MSR_NB_MISC1 + (j) - 1) 216 217 /* 218 * PCI registers will be represented as unions, with one fixed-width unsigned 219 * integer member providing access to the raw register value and one or more 220 * structs breaking the register out into bitfields (more than one struct if 221 * the register definitions varies across processor revisions). 222 * 223 * The "raw" union member will always be '_val32'. Use MCREG_VAL32 to 224 * access this member. 225 * 226 * The bitfield structs are all named _fmt_xxx where xxx identifies the 227 * processor revision to which it applies. At this point the only xxx 228 * values in use are: 229 * 'cmn' - applies to all revisions 230 * 'f_preF' - applies to revisions E and earlier 231 * 'f_revFG' - applies to revisions F and G 232 * 233 * Variants such as 'preD', 'revDE', 'postCG' etc should be introduced 234 * as requirements arise. The MC_REV_* and MC_REV_MATCH etc macros 235 * will also need to grow to match. Use MCREG_FIELD_* to access the 236 * individual bitfields of a register, perhaps using MC_REV_* and MC_REV_MATCH 237 * to decide which revision suffix to provide. Where a bitfield appears 238 * in different revisions but has the same use it should be named identically 239 * (even if the BKDG varies a little) so that the MC_REG_FIELD_* macros 240 * can lookup that member based on revision only. 241 */ 242 243 #define MC_REV_UNKNOWN X86_CHIPREV_UNKNOWN 244 245 #define MC_F_REV_B X86_CHIPREV_AMD_F_REV_B 246 #define MC_F_REV_C (X86_CHIPREV_AMD_F_REV_C0 | X86_CHIPREV_AMD_F_REV_CG) 247 #define MC_F_REV_D X86_CHIPREV_AMD_F_REV_D 248 #define MC_F_REV_E X86_CHIPREV_AMD_F_REV_E 249 #define MC_F_REV_F X86_CHIPREV_AMD_F_REV_F 250 #define MC_F_REV_G X86_CHIPREV_AMD_F_REV_G 251 252 #define MC_10_REV_A X86_CHIPREV_AMD_10_REV_A 253 #define MC_10_REV_B X86_CHIPREV_AMD_10_REV_B 254 255 /* 256 * The most common groupings for memory controller features. 257 */ 258 #define MC_F_REVS_BC (MC_F_REV_B | MC_F_REV_C) 259 #define MC_F_REVS_DE (MC_F_REV_D | MC_F_REV_E) 260 #define MC_F_REVS_BCDE (MC_F_REVS_BC | MC_F_REVS_DE) 261 #define MC_F_REVS_FG (MC_F_REV_F | MC_F_REV_G) 262 263 #define MC_10_REVS_AB (MC_10_REV_A | MC_10_REV_B) 264 265 /* 266 * Is 'rev' included in the 'revmask' bitmask? 267 */ 268 #define MC_REV_MATCH(rev, revmask) X86_CHIPREV_MATCH(rev, revmask) 269 270 /* 271 * Is 'rev' at least revision 'revmin' or greater 272 */ 273 #define MC_REV_ATLEAST(rev, minrev) X86_CHIPREV_ATLEAST(rev, minrev) 274 275 #define _MCREG_FIELD(up, revsuffix, field) ((up)->_fmt_##revsuffix.field) 276 277 #define MCREG_VAL32(up) ((up)->_val32) 278 279 /* 280 * Access a field that has the same structure in all families and revisions 281 */ 282 #define MCREG_FIELD_CMN(up, field) _MCREG_FIELD(up, cmn, field) 283 284 /* 285 * Access a field as defined for family 0xf prior to revision F 286 */ 287 #define MCREG_FIELD_F_preF(up, field) _MCREG_FIELD(up, f_preF, field) 288 289 /* 290 * Access a field as defined for family 0xf revisions F and G 291 */ 292 #define MCREG_FIELD_F_revFG(up, field) _MCREG_FIELD(up, f_revFG, field) 293 294 /* 295 * Access a field as defined for family 0x10 revisions A and 296 */ 297 #define MCREG_FIELD_10_revAB(up, field) _MCREG_FIELD(up, 10_revAB, field) 298 299 /* 300 * We will only define the register bitfields for little-endian order 301 */ 302 #ifdef _BIT_FIELDS_LTOH 303 304 /* 305 * Function 0 - HT Configuration: Routing Table Node Register 306 */ 307 union mcreg_htroute { 308 uint32_t _val32; 309 struct { 310 uint32_t RQRte:4; /* 3:0 */ 311 uint32_t reserved1:4; /* 7:4 */ 312 uint32_t RPRte:4; /* 11:8 */ 313 uint32_t reserved2:4; /* 15:12 */ 314 uint32_t BCRte:4; /* 19:16 */ 315 uint32_t reserved3:12; /* 31:20 */ 316 } _fmt_cmn; 317 }; 318 319 /* 320 * Function 0 - HT Configuration: Node ID Register 321 */ 322 union mcreg_nodeid { 323 uint32_t _val32; 324 struct { 325 uint32_t NodeId:3; /* 2:0 */ 326 uint32_t reserved1:1; /* 3:3 */ 327 uint32_t NodeCnt:3; /* 6:4 */ 328 uint32_t reserved2:1; /* 7:7 */ 329 uint32_t SbNode:3; /* 10:8 */ 330 uint32_t reserved3:1; /* 11:11 */ 331 uint32_t LkNode:3; /* 14:12 */ 332 uint32_t reserved4:1; /* 15:15 */ 333 uint32_t CpuCnt:4; /* 19:16 */ 334 uint32_t reserved:12; /* 31:20 */ 335 } _fmt_cmn; 336 }; 337 338 #define HT_COHERENTNODES(up) (MCREG_FIELD_CMN(up, NodeCnt) + 1) 339 #define HT_SYSTEMCORECOUNT(up) (MCREG_FIELD_CMN(up, CpuCnt) + 1) 340 341 /* 342 * Function 0 - HT Configuration: Unit ID Register 343 */ 344 union mcreg_unitid { 345 uint32_t _val32; 346 struct { 347 uint32_t C0Unit:2; /* 1:0 */ 348 uint32_t C1Unit:2; /* 3:2 */ 349 uint32_t McUnit:2; /* 5:4 */ 350 uint32_t HbUnit:2; /* 7:6 */ 351 uint32_t SbLink:2; /* 9:8 */ 352 uint32_t reserved:22; /* 31:10 */ 353 } _fmt_cmn; 354 }; 355 356 /* 357 * Function 1 - DRAM Address Map: DRAM Base i Registers 358 * 359 */ 360 361 union mcreg_drambase { 362 uint32_t _val32; 363 struct { 364 uint32_t RE:1; /* 0:0 - Read Enable */ 365 uint32_t WE:1; /* 1:1 - Write Enable */ 366 uint32_t reserved1:6; /* 7:2 */ 367 uint32_t IntlvEn:3; /* 10:8 - Interleave Enable */ 368 uint32_t reserved2:5; /* 15:11 */ 369 uint32_t DRAMBasei:16; /* 31:16 - Base Addr 39:24 */ 370 } _fmt_cmn; 371 }; 372 373 #define MC_DRAMBASE(up) ((uint64_t)MCREG_FIELD_CMN(up, DRAMBasei) << 24) 374 375 /* 376 * Function 1 - DRAM Address Map: DRAM Limit i Registers 377 * 378 */ 379 380 union mcreg_dramlimit { 381 uint32_t _val32; 382 struct { 383 uint32_t DstNode:3; /* 2:0 - Destination Node */ 384 uint32_t reserved1:5; /* 7:3 */ 385 uint32_t IntlvSel:3; /* 10:8 - Interleave Select */ 386 uint32_t reserved2:5; /* 15:11 */ 387 uint32_t DRAMLimiti:16; /* 31:16 - Limit Addr 39:24 */ 388 } _fmt_cmn; 389 }; 390 391 #define MC_DRAMLIM(up) \ 392 ((uint64_t)MCREG_FIELD_CMN(up, DRAMLimiti) << 24 | \ 393 (MCREG_FIELD_CMN(up, DRAMLimiti) ? ((1 << 24) - 1) : 0)) 394 395 /* 396 * Function 1 - DRAM Address Map: DRAM Hole Address Register 397 */ 398 399 union mcreg_dramhole { 400 uint32_t _val32; 401 struct { 402 uint32_t DramHoleValid:1; /* 0:0 */ 403 uint32_t reserved1:7; /* 7:1 */ 404 uint32_t DramHoleOffset:8; /* 15:8 */ 405 uint32_t reserved2:8; /* 23:16 */ 406 uint32_t DramHoleBase:8; /* 31:24 */ 407 } _fmt_cmn; 408 }; 409 410 #define MC_DRAMHOLE_SIZE(up) (MCREG_FIELD_CMN(up, DramHoleOffset) << 24) 411 412 /* 413 * Function 2 - DRAM Controller: DRAM CS Base Address Registers 414 */ 415 416 union mcreg_csbase { 417 uint32_t _val32; 418 /* 419 * Register format in family 0xf revisions E and earlier 420 */ 421 struct { 422 uint32_t CSEnable:1; /* 0:0 - CS Bank Enable */ 423 uint32_t reserved1:8; /* 8:1 */ 424 uint32_t BaseAddrLo:7; /* 15:9 - Base Addr 19:13 */ 425 uint32_t reserved2:5; /* 20:16 */ 426 uint32_t BaseAddrHi:11; /* 31:21 - Base Addr 35:25 */ 427 } _fmt_f_preF; 428 /* 429 * Register format in family 0xf revisions F and G 430 */ 431 struct { 432 uint32_t CSEnable:1; /* 0:0 - CS Bank Enable */ 433 uint32_t Spare:1; /* 1:1 - Spare Rank */ 434 uint32_t TestFail:1; /* 2:2 - Memory Test Failed */ 435 uint32_t reserved1:2; /* 4:3 */ 436 uint32_t BaseAddrLo:9; /* 13:5 - Base Addr 21:13 */ 437 uint32_t reserved2:5; /* 18:14 */ 438 uint32_t BaseAddrHi:10; /* 28:19 - Base Addr 36:27 */ 439 uint32_t reserved3:3; /* 31:39 */ 440 } _fmt_f_revFG; 441 }; 442 443 #define MC_CSBASE(up, rev) (MC_REV_MATCH(rev, MC_F_REVS_FG) ? \ 444 (uint64_t)MCREG_FIELD_F_revFG(up, BaseAddrHi) << 27 | \ 445 (uint64_t)MCREG_FIELD_F_revFG(up, BaseAddrLo) << 13 : \ 446 (uint64_t)MCREG_FIELD_F_preF(up, BaseAddrHi) << 25 | \ 447 (uint64_t)MCREG_FIELD_F_preF(up, BaseAddrLo) << 13) 448 449 /* 450 * Function 2 - DRAM Controller: DRAM CS Mask Registers 451 */ 452 453 union mcreg_csmask { 454 uint32_t _val32; 455 /* 456 * Register format in family 0xf revisions E and earlier 457 */ 458 struct { 459 uint32_t reserved1:9; /* 8:0 */ 460 uint32_t AddrMaskLo:7; /* 15:9 - Addr Mask 19:13 */ 461 uint32_t reserved2:5; /* 20:16 */ 462 uint32_t AddrMaskHi:9; /* 29:21 - Addr Mask 33:25 */ 463 uint32_t reserved3:2; /* 31:30 */ 464 } _fmt_f_preF; 465 /* 466 * Register format in family 0xf revisions F and G 467 */ 468 struct { 469 uint32_t reserved1:5; /* 4:0 */ 470 uint32_t AddrMaskLo:9; /* 13:5 - Addr Mask 21:13 */ 471 uint32_t reserved2:5; /* 18:14 */ 472 uint32_t AddrMaskHi:10; /* 28:19 - Addr Mask 36:27 */ 473 uint32_t reserved3:3; /* 31:29 */ 474 } _fmt_f_revFG; 475 }; 476 477 #define MC_CSMASKLO_LOBIT(rev) (MC_REV_MATCH(rev, MC_F_REVS_FG) ? 13 : 13) 478 #define MC_CSMASKLO_HIBIT(rev) (MC_REV_MATCH(rev, MC_F_REVS_FG) ? 21 : 19) 479 480 #define MC_CSMASKHI_LOBIT(rev) (MC_REV_MATCH(rev, MC_F_REVS_FG) ? 27 : 25) 481 #define MC_CSMASKHI_HIBIT(rev) (MC_REV_MATCH(rev, MC_F_REVS_FG) ? 36 : 33) 482 483 #define MC_CSMASK_UNMASKABLE(rev) (MC_REV_MATCH(rev, MC_F_REVS_FG) ? 0 : 2) 484 485 #define MC_CSMASK(up, rev) (MC_REV_MATCH(rev, MC_F_REVS_FG) ? \ 486 (uint64_t)MCREG_FIELD_F_revFG(up, AddrMaskHi) << 27 | \ 487 (uint64_t)MCREG_FIELD_F_revFG(up, AddrMaskLo) << 13 | 0x7c01fff : \ 488 (uint64_t)MCREG_FIELD_F_preF(up, AddrMaskHi) << 25 | \ 489 (uint64_t)MCREG_FIELD_F_preF(up, AddrMaskLo) << 13 | 0x1f01fff) 490 491 /* 492 * Function 2 - DRAM Controller: DRAM Bank Address Mapping Registers 493 */ 494 495 union mcreg_bankaddrmap { 496 uint32_t _val32; 497 /* 498 * Register format in family 0xf revisions E and earlier 499 */ 500 struct { 501 uint32_t cs10:4; /* 3:0 - CS1/0 */ 502 uint32_t cs32:4; /* 7:4 - CS3/2 */ 503 uint32_t cs54:4; /* 11:8 - CS5/4 */ 504 uint32_t cs76:4; /* 15:12 - CS7/6 */ 505 uint32_t reserved1:14; /* 29:16 */ 506 uint32_t BankSwizzleMode:1; /* 30:30 */ 507 uint32_t reserved2:1; /* 31:31 */ 508 } _fmt_f_preF; 509 /* 510 * Register format in family 0xf revisions F and G 511 */ 512 struct { 513 uint32_t cs10:4; /* 3:0 - CS1/0 */ 514 uint32_t cs32:4; /* 7:4 - CS3/2 */ 515 uint32_t cs54:4; /* 11:8 - CS5/4 */ 516 uint32_t cs76:4; /* 15:12 - CS7/6 */ 517 uint32_t reserved1:16; /* 31:16 */ 518 } _fmt_f_revFG; 519 /* 520 * Accessing all mode encodings as one uint16 521 */ 522 struct { 523 uint32_t allcsmodes:16; /* 15:0 */ 524 uint32_t pad:16; /* 31:16 */ 525 } _fmt_bankmodes; 526 }; 527 528 #define MC_DC_BAM_CSBANK_MASK 0x0000000f 529 #define MC_DC_BAM_CSBANK_SHIFT 4 530 531 #define MC_CSBANKMODE(up, csnum) ((up)->_fmt_bankmodes.allcsmodes >> \ 532 MC_DC_BAM_CSBANK_SHIFT * MC_CHIP_DIMMPAIR(csnum) & MC_DC_BAM_CSBANK_MASK) 533 534 /* 535 * Function 2 - DRAM Controller: DRAM Configuration Low and High 536 */ 537 538 union mcreg_dramcfg_lo { 539 uint32_t _val32; 540 /* 541 * Register format in family 0xf revisions E and earlier. 542 * Bit 7 is a BIOS ScratchBit in revs D and earlier, 543 * PwrDwnTriEn in revision E; we don't use it so 544 * we'll call it ambig1. 545 */ 546 struct { 547 uint32_t DLL_Dis:1; /* 0 */ 548 uint32_t D_DRV:1; /* 1 */ 549 uint32_t QFC_EN:1; /* 2 */ 550 uint32_t DisDqsHys:1; /* 3 */ 551 uint32_t reserved1:1; /* 4 */ 552 uint32_t Burst2Opt:1; /* 5 */ 553 uint32_t Mod64BitMux:1; /* 6 */ 554 uint32_t ambig1:1; /* 7 */ 555 uint32_t DramInit:1; /* 8 */ 556 uint32_t DualDimmEn:1; /* 9 */ 557 uint32_t DramEnable:1; /* 10 */ 558 uint32_t MemClrStatus:1; /* 11 */ 559 uint32_t ESR:1; /* 12 */ 560 uint32_t SR_S:1; /* 13 */ 561 uint32_t RdWrQByp:2; /* 15:14 */ 562 uint32_t Width128:1; /* 16 */ 563 uint32_t DimmEcEn:1; /* 17 */ 564 uint32_t UnBufDimm:1; /* 18 */ 565 uint32_t ByteEn32:1; /* 19 */ 566 uint32_t x4DIMMs:4; /* 23:20 */ 567 uint32_t DisInRcvrs:1; /* 24 */ 568 uint32_t BypMax:3; /* 27:25 */ 569 uint32_t En2T:1; /* 28 */ 570 uint32_t UpperCSMap:1; /* 29 */ 571 uint32_t PwrDownCtl:2; /* 31:30 */ 572 } _fmt_f_preF; 573 /* 574 * Register format in family 0xf revisions F and G 575 */ 576 struct { 577 uint32_t InitDram:1; /* 0 */ 578 uint32_t ExitSelfRef:1; /* 1 */ 579 uint32_t reserved1:2; /* 3:2 */ 580 uint32_t DramTerm:2; /* 5:4 */ 581 uint32_t reserved2:1; /* 6 */ 582 uint32_t DramDrvWeak:1; /* 7 */ 583 uint32_t ParEn:1; /* 8 */ 584 uint32_t SelRefRateEn:1; /* 9 */ 585 uint32_t BurstLength32:1; /* 10 */ 586 uint32_t Width128:1; /* 11 */ 587 uint32_t x4DIMMs:4; /* 15:12 */ 588 uint32_t UnBuffDimm:1; /* 16 */ 589 uint32_t reserved3:2; /* 18:17 */ 590 uint32_t DimmEccEn:1; /* 19 */ 591 uint32_t reserved4:12; /* 31:20 */ 592 } _fmt_f_revFG; 593 }; 594 595 /* 596 * Function 2 - DRAM Controller: DRAM Controller Miscellaneous Data 597 */ 598 599 union mcreg_drammisc { 600 uint32_t _val32; 601 /* 602 * Register format in family 0xf revisions F and G 603 */ 604 struct { 605 uint32_t reserved2:1; /* 0 */ 606 uint32_t DisableJitter:1; /* 1 */ 607 uint32_t RdWrQByp:2; /* 3:2 */ 608 uint32_t Mod64Mux:1; /* 4 */ 609 uint32_t DCC_EN:1; /* 5 */ 610 uint32_t ILD_lmt:3; /* 8:6 */ 611 uint32_t DramEnabled:1; /* 9 */ 612 uint32_t PwrSavingsEn:1; /* 10 */ 613 uint32_t reserved1:13; /* 23:11 */ 614 uint32_t MemClkDis:8; /* 31:24 */ 615 } _fmt_f_revFG; 616 }; 617 618 union mcreg_dramcfg_hi { 619 uint32_t _val32; 620 /* 621 * Register format in family 0xf revisions E and earlier. 622 */ 623 struct { 624 uint32_t AsyncLat:4; /* 3:0 */ 625 uint32_t reserved1:4; /* 7:4 */ 626 uint32_t RdPreamble:4; /* 11:8 */ 627 uint32_t reserved2:1; /* 12 */ 628 uint32_t MemDQDrvStren:2; /* 14:13 */ 629 uint32_t DisableJitter:1; /* 15 */ 630 uint32_t ILD_lmt:3; /* 18:16 */ 631 uint32_t DCC_EN:1; /* 19 */ 632 uint32_t MemClk:3; /* 22:20 */ 633 uint32_t reserved3:2; /* 24:23 */ 634 uint32_t MCR:1; /* 25 */ 635 uint32_t MC0_EN:1; /* 26 */ 636 uint32_t MC1_EN:1; /* 27 */ 637 uint32_t MC2_EN:1; /* 28 */ 638 uint32_t MC3_EN:1; /* 29 */ 639 uint32_t reserved4:1; /* 30 */ 640 uint32_t OddDivisorCorrect:1; /* 31 */ 641 } _fmt_f_preF; 642 /* 643 * Register format in family 0xf revisions F and G 644 */ 645 struct { 646 uint32_t MemClkFreq:3; /* 2:0 */ 647 uint32_t MemClkFreqVal:1; /* 3 */ 648 uint32_t MaxAsyncLat:4; /* 7:4 */ 649 uint32_t reserved1:4; /* 11:8 */ 650 uint32_t RDqsEn:1; /* 12 */ 651 uint32_t reserved2:1; /* 13 */ 652 uint32_t DisDramInterface:1; /* 14 */ 653 uint32_t PowerDownEn:1; /* 15 */ 654 uint32_t PowerDownMode:1; /* 16 */ 655 uint32_t FourRankSODimm:1; /* 17 */ 656 uint32_t FourRankRDimm:1; /* 18 */ 657 uint32_t reserved3:1; /* 19 */ 658 uint32_t SlowAccessMode:1; /* 20 */ 659 uint32_t reserved4:1; /* 21 */ 660 uint32_t BankSwizzleMode:1; /* 22 */ 661 uint32_t undocumented1:1; /* 23 */ 662 uint32_t DcqBypassMax:4; /* 27:24 */ 663 uint32_t FourActWindow:4; /* 31:28 */ 664 } _fmt_f_revFG; 665 }; 666 667 /* 668 * Function 3 - Miscellaneous Control: Scrub Control Register 669 */ 670 671 union mcreg_scrubctl { 672 uint32_t _val32; 673 struct { 674 uint32_t DramScrub:5; /* 4:0 */ 675 uint32_t reserved3:3; /* 7:5 */ 676 uint32_t L2Scrub:5; /* 12:8 */ 677 uint32_t reserved2:3; /* 15:13 */ 678 uint32_t DcacheScrub:5; /* 20:16 */ 679 uint32_t reserved1:11; /* 31:21 */ 680 } _fmt_cmn; 681 }; 682 683 union mcreg_dramscrublo { 684 uint32_t _val32; 685 struct { 686 uint32_t ScrubReDirEn:1; /* 0 */ 687 uint32_t reserved:5; /* 5:1 */ 688 uint32_t ScrubAddrLo:26; /* 31:6 */ 689 } _fmt_cmn; 690 }; 691 692 union mcreg_dramscrubhi { 693 uint32_t _val32; 694 struct { 695 uint32_t ScrubAddrHi:8; /* 7:0 */ 696 uint32_t reserved:24; /* 31:8 */ 697 } _fmt_cmn; 698 }; 699 700 /* 701 * Function 3 - Miscellaneous Control: On-Line Spare Control Register 702 */ 703 704 union mcreg_nbcfg { 705 uint32_t _val32; 706 /* 707 * Register format in family 0xf revisions E and earlier. 708 */ 709 struct { 710 uint32_t CpuEccErrEn:1; /* 0 */ 711 uint32_t CpuRdDatErrEn:1; /* 1 */ 712 uint32_t SyncOnUcEccEn:1; /* 2 */ 713 uint32_t SyncPktGenDis:1; /* 3 */ 714 uint32_t SyncPktPropDis:1; /* 4 */ 715 uint32_t IoMstAbortDis:1; /* 5 */ 716 uint32_t CpuErrDis:1; /* 6 */ 717 uint32_t IoErrDis:1; /* 7 */ 718 uint32_t WdogTmrDis:1; /* 8 */ 719 uint32_t WdogTmrCntSel:3; /* 11:9 */ 720 uint32_t WdogTmrBaseSel:2; /* 13:12 */ 721 uint32_t LdtLinkSel:2; /* 15:14 */ 722 uint32_t GenCrcErrByte0:1; /* 16 */ 723 uint32_t GenCrcErrByte1:1; /* 17 */ 724 uint32_t reserved1:2; /* 19:18 */ 725 uint32_t SyncOnWdogEn:1; /* 20 */ 726 uint32_t SyncOnAnyErrEn:1; /* 21 */ 727 uint32_t EccEn:1; /* 22 */ 728 uint32_t ChipKillEccEn:1; /* 23 */ 729 uint32_t IoRdDatErrEn:1; /* 24 */ 730 uint32_t DisPciCfgCpuErrRsp:1; /* 25 */ 731 uint32_t reserved2:1; /* 26 */ 732 uint32_t NbMcaToMstCpuEn:1; /* 27 */ 733 uint32_t reserved3:4; /* 31:28 */ 734 } _fmt_f_preF; 735 /* 736 * Register format in family 0xf revisions F and G 737 */ 738 struct { 739 uint32_t CpuEccErrEn:1; /* 0 */ 740 uint32_t CpuRdDatErrEn:1; /* 1 */ 741 uint32_t SyncOnUcEccEn:1; /* 2 */ 742 uint32_t SyncPktGenDis:1; /* 3 */ 743 uint32_t SyncPktPropDis:1; /* 4 */ 744 uint32_t IoMstAbortDis:1; /* 5 */ 745 uint32_t CpuErrDis:1; /* 6 */ 746 uint32_t IoErrDis:1; /* 7 */ 747 uint32_t WdogTmrDis:1; /* 8 */ 748 uint32_t WdogTmrCntSel:3; /* 11:9 */ 749 uint32_t WdogTmrBaseSel:2; /* 13:12 */ 750 uint32_t LdtLinkSel:2; /* 15:14 */ 751 uint32_t GenCrcErrByte0:1; /* 16 */ 752 uint32_t GenCrcErrByte1:1; /* 17 */ 753 uint32_t reserved1:2; /* 19:18 */ 754 uint32_t SyncOnWdogEn:1; /* 20 */ 755 uint32_t SyncOnAnyErrEn:1; /* 21 */ 756 uint32_t EccEn:1; /* 22 */ 757 uint32_t ChipKillEccEn:1; /* 23 */ 758 uint32_t IoRdDatErrEn:1; /* 24 */ 759 uint32_t DisPciCfgCpuErrRsp:1; /* 25 */ 760 uint32_t reserved2:1; /* 26 */ 761 uint32_t NbMcaToMstCpuEn:1; /* 27 */ 762 uint32_t DisTgtAbtCpuErrRsp:1; /* 28 */ 763 uint32_t DisMstAbtCpuErrRsp:1; /* 29 */ 764 uint32_t SyncOnDramAdrParErrEn:1; /* 30 */ 765 uint32_t reserved3:1; /* 31 */ 766 767 } _fmt_f_revFG; 768 }; 769 770 /* 771 * Function 3 - Miscellaneous Control: On-Line Spare Control Register 772 */ 773 774 union mcreg_sparectl { 775 uint32_t _val32; 776 /* 777 * Register format in family 0xf revisions F and G 778 */ 779 struct { 780 uint32_t SwapEn:1; /* 0 */ 781 uint32_t SwapDone:1; /* 1 */ 782 uint32_t reserved1:2; /* 3:2 */ 783 uint32_t BadDramCs:3; /* 6:4 */ 784 uint32_t reserved2:5; /* 11:7 */ 785 uint32_t SwapDoneInt:2; /* 13:12 */ 786 uint32_t EccErrInt:2; /* 15:14 */ 787 uint32_t EccErrCntDramCs:3; /* 18:16 */ 788 uint32_t reserved3:1; /* 19 */ 789 uint32_t EccErrCntDramChan:1; /* 20 */ 790 uint32_t reserved4:2; /* 22:21 */ 791 uint32_t EccErrCntWrEn:1; /* 23 */ 792 uint32_t EccErrCnt:4; /* 27:24 */ 793 uint32_t reserved5:4; /* 31:28 */ 794 } _fmt_f_revFG; 795 /* 796 * Regiser format in family 0x10 revisions A and B 797 */ 798 struct { 799 uint32_t SwapEn0:1; /* 0 */ 800 uint32_t SwapDone0:1; /* 1 */ 801 uint32_t SwapEn1:1; /* 2 */ 802 uint32_t SwapDone1:1; /* 3 */ 803 uint32_t BadDramCs0:3; /* 6:4 */ 804 uint32_t reserved1:1; /* 7 */ 805 uint32_t BadDramCs1:3; /* 10:8 */ 806 uint32_t reserved2:1; /* 11 */ 807 uint32_t SwapDoneInt:2; /* 13:12 */ 808 uint32_t EccErrInt:2; /* 15:14 */ 809 uint32_t EccErrCntDramCs:4; /* 19:16 */ 810 uint32_t EccErrCntDramChan:2; /* 21:20 */ 811 uint32_t reserved4:1; /* 22 */ 812 uint32_t EccErrCntWrEn:1; /* 23 */ 813 uint32_t EccErrCnt:4; /* 27:24 */ 814 uint32_t LvtOffset:4; /* 31:28 */ 815 } _fmt_10_revAB; 816 }; 817 818 /* 819 * Since the NB is on-chip some registers are also accessible as MSRs. 820 * We will represent such registers as bitfields as in the 32-bit PCI 821 * registers above, with the restriction that we must compile for 32-bit 822 * kernels and so 64-bit bitfields cannot be used. 823 */ 824 825 #define _MCMSR_FIELD(up, revsuffix, field) ((up)->_fmt_##revsuffix.field) 826 827 #define MCMSR_VAL(up) ((up)->_val64) 828 829 #define MCMSR_FIELD_CMN(up, field) _MCMSR_FIELD(up, cmn, field) 830 #define MCMSR_FIELD_F_preF(up, field) _MCMSR_FIELD(up, f_preF, field) 831 #define MCMSR_FIELD_F_revFG(up, field) _MCMSR_FIELD(up, f_revFG, field) 832 #define MCMSR_FIELD_10_revAB(up, field) _MCMSR_FIELD(up, 10_revAB, field) 833 834 /* 835 * The NB MISC registers. On family 0xf rev F this was introduced with 836 * a 12-bit ECC error count of all ECC errors observed on this memory- 837 * controller (regardless of channel or chip-select) and the ability to 838 * raise an interrupt or SMI on overflow. In family 0x10 it has a similar 839 * purpose, but the register is is split into 4 misc registers 840 * MC4_MISC{0,1,2,3} accessible via both MSRs and PCI config space; 841 * they perform thresholding for dram, l3, HT errors. 842 */ 843 844 union mcmsr_nbmisc { 845 uint64_t _val64; 846 /* 847 * MSR format in family 0xf revision F and later 848 */ 849 struct { 850 /* 851 * Lower 32 bits 852 */ 853 struct { 854 uint32_t _reserved; /* 31:0 */ 855 } _mcimisc_lo; 856 /* 857 * Upper 32 bits 858 */ 859 struct { 860 uint32_t _ErrCount:12; /* 43:32 */ 861 uint32_t _reserved1:4; /* 47:44 */ 862 uint32_t _Ovrflw:1; /* 48 */ 863 uint32_t _IntType:2; /* 50:49 */ 864 uint32_t _CntEn:1; /* 51 */ 865 uint32_t _LvtOff:4; /* 55:52 */ 866 uint32_t _reserved2:5; /* 60:56 */ 867 uint32_t _Locked:1; /* 61 */ 868 uint32_t _CntP:1; /* 62 */ 869 uint32_t _Valid:1; /* 63 */ 870 } _mcimisc_hi; 871 } _fmt_f_revFG; 872 /* 873 * MSR format in family 0x10 revisions A and B 874 */ 875 struct { 876 /* 877 * Lower 32 bits 878 */ 879 struct { 880 uint32_t _reserved:24; /* 23:0 */ 881 uint32_t _BlkPtr:8; /* 31:24 */ 882 } _mcimisc_lo; 883 /* 884 * Upper 32 bits 885 */ 886 struct { 887 uint32_t _ErrCnt:12; /* 43:32 */ 888 uint32_t _reserved1:4; /* 47:44 */ 889 uint32_t _Ovrflw:1; /* 48 */ 890 uint32_t _IntType:2; /* 50:49 */ 891 uint32_t _CntEn:1; /* 51 */ 892 uint32_t _LvtOff:4; /* 55:52 */ 893 uint32_t _reserved2:5; /* 60:56 */ 894 uint32_t _Locked:1; /* 61 */ 895 uint32_t _CntP:1; /* 62 */ 896 uint32_t _Valid:1; /* 63 */ 897 898 } _mcimisc_hi; 899 } _fmt_10_revAB; 900 }; 901 902 #define mcmisc_BlkPtr _mcimisc_lo._BlkPtr 903 #define mcmisc_ErrCount _mcimisc_hi._ErrCount 904 #define mcmisc_Ovrflw _mcimisc_hi._Ovrflw 905 #define mcmisc_IntType _mcimisc_hi._IntType 906 #define mcmisc_CntEn _mcimisc_hi._CntEn 907 #define mcmisc_LvtOff _mcimisc_hi._LvtOff 908 #define mcmisc_Locked _mcimisc_hi._Locked 909 #define mcmisc_CntP _mcimisc_hi._CntP 910 #define mcmisc_Valid _mcimisc_hi._Valid 911 912 #endif /* _BIT_FIELDS_LTOH */ 913 914 #ifdef __cplusplus 915 } 916 #endif 917 918 #endif /* _MC_AMD_H */ 919