aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/edac/amd64_edac.c
diff options
context:
space:
mode:
authorBorislav Petkov <borislav.petkov@amd.com>2011-03-21 15:45:06 -0400
committerBorislav Petkov <borislav.petkov@amd.com>2011-04-26 10:18:44 -0400
commitf08e457cecece7fbbdad3add9defac3373a59b5a (patch)
tree10fc4421d4277cb24ec2019ce4965f5a3dcf02a1 /drivers/edac/amd64_edac.c
parentf030ddfb3752df36bb73285353374fc04feabb80 (diff)
amd64_edac: Factor in CC6 save area
F15h and later use a portion of DRAM as a CC6 storage area. BIOS programs D18F1x[17C:140,7C:40] DRAM Base/Limit accordingly by subtracting the storage area from the DRAM limit setting. However, in order for edac to consider that part of DRAM too, we need to include it into the per-node range. Signed-off-by: Borislav Petkov <borislav.petkov@amd.com>
Diffstat (limited to 'drivers/edac/amd64_edac.c')
-rw-r--r--drivers/edac/amd64_edac.c28
1 files changed, 27 insertions, 1 deletions
diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c
index 601142a0738a..e17de90ba6c6 100644
--- a/drivers/edac/amd64_edac.c
+++ b/drivers/edac/amd64_edac.c
@@ -944,12 +944,13 @@ static u64 get_error_address(struct mce *m)
944 944
945static void read_dram_base_limit_regs(struct amd64_pvt *pvt, unsigned range) 945static void read_dram_base_limit_regs(struct amd64_pvt *pvt, unsigned range)
946{ 946{
947 struct cpuinfo_x86 *c = &boot_cpu_data;
947 int off = range << 3; 948 int off = range << 3;
948 949
949 amd64_read_pci_cfg(pvt->F1, DRAM_BASE_LO + off, &pvt->ranges[range].base.lo); 950 amd64_read_pci_cfg(pvt->F1, DRAM_BASE_LO + off, &pvt->ranges[range].base.lo);
950 amd64_read_pci_cfg(pvt->F1, DRAM_LIMIT_LO + off, &pvt->ranges[range].lim.lo); 951 amd64_read_pci_cfg(pvt->F1, DRAM_LIMIT_LO + off, &pvt->ranges[range].lim.lo);
951 952
952 if (boot_cpu_data.x86 == 0xf) 953 if (c->x86 == 0xf)
953 return; 954 return;
954 955
955 if (!dram_rw(pvt, range)) 956 if (!dram_rw(pvt, range))
@@ -957,6 +958,31 @@ static void read_dram_base_limit_regs(struct amd64_pvt *pvt, unsigned range)
957 958
958 amd64_read_pci_cfg(pvt->F1, DRAM_BASE_HI + off, &pvt->ranges[range].base.hi); 959 amd64_read_pci_cfg(pvt->F1, DRAM_BASE_HI + off, &pvt->ranges[range].base.hi);
959 amd64_read_pci_cfg(pvt->F1, DRAM_LIMIT_HI + off, &pvt->ranges[range].lim.hi); 960 amd64_read_pci_cfg(pvt->F1, DRAM_LIMIT_HI + off, &pvt->ranges[range].lim.hi);
961
962 /* Factor in CC6 save area by reading dst node's limit reg */
963 if (c->x86 == 0x15) {
964 struct pci_dev *f1 = NULL;
965 u8 nid = dram_dst_node(pvt, range);
966 u32 llim;
967
968 f1 = pci_get_domain_bus_and_slot(0, 0, PCI_DEVFN(0x18 + nid, 1));
969 if (WARN_ON(!f1))
970 return;
971
972 amd64_read_pci_cfg(f1, DRAM_LOCAL_NODE_LIM, &llim);
973
974 pvt->ranges[range].lim.lo &= GENMASK(0, 15);
975
976 /* {[39:27],111b} */
977 pvt->ranges[range].lim.lo |= ((llim & 0x1fff) << 3 | 0x7) << 16;
978
979 pvt->ranges[range].lim.hi &= GENMASK(0, 7);
980
981 /* [47:40] */
982 pvt->ranges[range].lim.hi |= llim >> 13;
983
984 pci_dev_put(f1);
985 }
960} 986}
961 987
962static void k8_map_sysaddr_to_csrow(struct mem_ctl_info *mci, u64 sys_addr, 988static void k8_map_sysaddr_to_csrow(struct mem_ctl_info *mci, u64 sys_addr,