aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/edac
diff options
context:
space:
mode:
authorBorislav Petkov <borislav.petkov@amd.com>2010-10-21 12:52:53 -0400
committerBorislav Petkov <borislav.petkov@amd.com>2011-03-17 09:46:11 -0400
commit7f19bf755ced6fa16dbf118c0eff60586760496b (patch)
tree93b050e1a30efe33aaa1ffdf26473bd9ab55a585 /drivers/edac
parentb2b0c605436e343a9a24f00e7fc8fb89a8316e20 (diff)
amd64_edac: Remove DRAM base/limit subfields caching
Add a struct representing the DRAM base/limit range pairs and remove all cached subfields. Replace them with accessor functions, which actually saves us some space: text data bss dec hex filename 14712 1577 336 16625 40f1 drivers/edac/amd64_edac_mod.o.after 14831 1609 336 16776 4188 drivers/edac/amd64_edac_mod.o.before Also, it simplifies the code a lot allowing to merge the K8 and F10h routines. No functional change. Signed-off-by: Borislav Petkov <borislav.petkov@amd.com>
Diffstat (limited to 'drivers/edac')
-rw-r--r--drivers/edac/amd64_edac.c230
-rw-r--r--drivers/edac/amd64_edac.h73
2 files changed, 115 insertions, 188 deletions
diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c
index ae5adac3733f..683fd3c716a0 100644
--- a/drivers/edac/amd64_edac.c
+++ b/drivers/edac/amd64_edac.c
@@ -296,32 +296,13 @@ static u32 amd64_get_dct_mask(struct amd64_pvt *pvt, int dct, int csrow)
296 return pvt->dcsm1[amd64_map_to_dcs_mask(pvt, csrow)]; 296 return pvt->dcsm1[amd64_map_to_dcs_mask(pvt, csrow)];
297} 297}
298 298
299
300/* 299/*
301 * In *base and *limit, pass back the full 40-bit base and limit physical 300 * returns true if the SysAddr given by sys_addr matches the
302 * addresses for the node given by node_id. This information is obtained from 301 * DRAM base/limit associated with node_id
303 * DRAM Base (section 3.4.4.1) and DRAM Limit (section 3.4.4.2) registers. The
304 * base and limit addresses are of type SysAddr, as defined at the start of
305 * section 3.4.4 (p. 70). They are the lowest and highest physical addresses
306 * in the address range they represent.
307 */ 302 */
308static void amd64_get_base_and_limit(struct amd64_pvt *pvt, int node_id, 303static bool amd64_base_limit_match(struct amd64_pvt *pvt, u64 sys_addr, int nid)
309 u64 *base, u64 *limit)
310{ 304{
311 *base = pvt->dram_base[node_id]; 305 u64 addr;
312 *limit = pvt->dram_limit[node_id];
313}
314
315/*
316 * Return 1 if the SysAddr given by sys_addr matches the base/limit associated
317 * with node_id
318 */
319static int amd64_base_limit_match(struct amd64_pvt *pvt,
320 u64 sys_addr, int node_id)
321{
322 u64 base, limit, addr;
323
324 amd64_get_base_and_limit(pvt, node_id, &base, &limit);
325 306
326 /* The K8 treats this as a 40-bit value. However, bits 63-40 will be 307 /* The K8 treats this as a 40-bit value. However, bits 63-40 will be
327 * all ones if the most significant implemented address bit is 1. 308 * all ones if the most significant implemented address bit is 1.
@@ -331,7 +312,8 @@ static int amd64_base_limit_match(struct amd64_pvt *pvt,
331 */ 312 */
332 addr = sys_addr & 0x000000ffffffffffull; 313 addr = sys_addr & 0x000000ffffffffffull;
333 314
334 return (addr >= base) && (addr <= limit); 315 return ((addr >= get_dram_base(pvt, nid)) &&
316 (addr <= get_dram_limit(pvt, nid)));
335} 317}
336 318
337/* 319/*
@@ -358,10 +340,10 @@ static struct mem_ctl_info *find_mc_by_sys_addr(struct mem_ctl_info *mci,
358 * registers. Therefore we arbitrarily choose to read it from the 340 * registers. Therefore we arbitrarily choose to read it from the
359 * register for node 0. 341 * register for node 0.
360 */ 342 */
361 intlv_en = pvt->dram_IntlvEn[0]; 343 intlv_en = dram_intlv_en(pvt, 0);
362 344
363 if (intlv_en == 0) { 345 if (intlv_en == 0) {
364 for (node_id = 0; node_id < DRAM_REG_COUNT; node_id++) { 346 for (node_id = 0; node_id < DRAM_RANGES; node_id++) {
365 if (amd64_base_limit_match(pvt, sys_addr, node_id)) 347 if (amd64_base_limit_match(pvt, sys_addr, node_id))
366 goto found; 348 goto found;
367 } 349 }
@@ -378,10 +360,10 @@ static struct mem_ctl_info *find_mc_by_sys_addr(struct mem_ctl_info *mci,
378 bits = (((u32) sys_addr) >> 12) & intlv_en; 360 bits = (((u32) sys_addr) >> 12) & intlv_en;
379 361
380 for (node_id = 0; ; ) { 362 for (node_id = 0; ; ) {
381 if ((pvt->dram_IntlvSel[node_id] & intlv_en) == bits) 363 if ((dram_intlv_sel(pvt, node_id) & intlv_en) == bits)
382 break; /* intlv_sel field matches */ 364 break; /* intlv_sel field matches */
383 365
384 if (++node_id >= DRAM_REG_COUNT) 366 if (++node_id >= DRAM_RANGES)
385 goto err_no_match; 367 goto err_no_match;
386 } 368 }
387 369
@@ -477,19 +459,6 @@ static int input_addr_to_csrow(struct mem_ctl_info *mci, u64 input_addr)
477} 459}
478 460
479/* 461/*
480 * Return the base value defined by the DRAM Base register for the node
481 * represented by mci. This function returns the full 40-bit value despite the
482 * fact that the register only stores bits 39-24 of the value. See section
483 * 3.4.4.1 (BKDG #26094, K8, revA-E)
484 */
485static inline u64 get_dram_base(struct mem_ctl_info *mci)
486{
487 struct amd64_pvt *pvt = mci->pvt_info;
488
489 return pvt->dram_base[pvt->mc_node_id];
490}
491
492/*
493 * Obtain info from the DRAM Hole Address Register (section 3.4.8, pub #26094) 462 * Obtain info from the DRAM Hole Address Register (section 3.4.8, pub #26094)
494 * for the node represented by mci. Info is passed back in *hole_base, 463 * for the node represented by mci. Info is passed back in *hole_base,
495 * *hole_offset, and *hole_size. Function returns 0 if info is valid or 1 if 464 * *hole_offset, and *hole_size. Function returns 0 if info is valid or 1 if
@@ -598,10 +567,11 @@ EXPORT_SYMBOL_GPL(amd64_get_dram_hole_info);
598 */ 567 */
599static u64 sys_addr_to_dram_addr(struct mem_ctl_info *mci, u64 sys_addr) 568static u64 sys_addr_to_dram_addr(struct mem_ctl_info *mci, u64 sys_addr)
600{ 569{
570 struct amd64_pvt *pvt = mci->pvt_info;
601 u64 dram_base, hole_base, hole_offset, hole_size, dram_addr; 571 u64 dram_base, hole_base, hole_offset, hole_size, dram_addr;
602 int ret = 0; 572 int ret = 0;
603 573
604 dram_base = get_dram_base(mci); 574 dram_base = get_dram_base(pvt, pvt->mc_node_id);
605 575
606 ret = amd64_get_dram_hole_info(mci, &hole_base, &hole_offset, 576 ret = amd64_get_dram_hole_info(mci, &hole_base, &hole_offset,
607 &hole_size); 577 &hole_size);
@@ -665,7 +635,7 @@ static u64 dram_addr_to_input_addr(struct mem_ctl_info *mci, u64 dram_addr)
665 * See the start of section 3.4.4 (p. 70, BKDG #26094, K8, revA-E) 635 * See the start of section 3.4.4 (p. 70, BKDG #26094, K8, revA-E)
666 * concerning translating a DramAddr to an InputAddr. 636 * concerning translating a DramAddr to an InputAddr.
667 */ 637 */
668 intlv_shift = num_node_interleave_bits(pvt->dram_IntlvEn[0]); 638 intlv_shift = num_node_interleave_bits(dram_intlv_en(pvt, 0));
669 input_addr = ((dram_addr >> intlv_shift) & 0xffffff000ull) + 639 input_addr = ((dram_addr >> intlv_shift) & 0xffffff000ull) +
670 (dram_addr & 0xfff); 640 (dram_addr & 0xfff);
671 641
@@ -717,7 +687,7 @@ static u64 input_addr_to_dram_addr(struct mem_ctl_info *mci, u64 input_addr)
717 node_id = pvt->mc_node_id; 687 node_id = pvt->mc_node_id;
718 BUG_ON((node_id < 0) || (node_id > 7)); 688 BUG_ON((node_id < 0) || (node_id > 7));
719 689
720 intlv_shift = num_node_interleave_bits(pvt->dram_IntlvEn[0]); 690 intlv_shift = num_node_interleave_bits(dram_intlv_en(pvt, 0));
721 691
722 if (intlv_shift == 0) { 692 if (intlv_shift == 0) {
723 debugf1(" InputAddr 0x%lx translates to DramAddr of " 693 debugf1(" InputAddr 0x%lx translates to DramAddr of "
@@ -729,7 +699,7 @@ static u64 input_addr_to_dram_addr(struct mem_ctl_info *mci, u64 input_addr)
729 bits = ((input_addr & 0xffffff000ull) << intlv_shift) + 699 bits = ((input_addr & 0xffffff000ull) << intlv_shift) +
730 (input_addr & 0xfff); 700 (input_addr & 0xfff);
731 701
732 intlv_sel = pvt->dram_IntlvSel[node_id] & ((1 << intlv_shift) - 1); 702 intlv_sel = dram_intlv_sel(pvt, node_id) & ((1 << intlv_shift) - 1);
733 dram_addr = bits + (intlv_sel << 12); 703 dram_addr = bits + (intlv_sel << 12);
734 704
735 debugf1("InputAddr 0x%lx translates to DramAddr 0x%lx " 705 debugf1("InputAddr 0x%lx translates to DramAddr 0x%lx "
@@ -746,7 +716,7 @@ static u64 input_addr_to_dram_addr(struct mem_ctl_info *mci, u64 input_addr)
746static u64 dram_addr_to_sys_addr(struct mem_ctl_info *mci, u64 dram_addr) 716static u64 dram_addr_to_sys_addr(struct mem_ctl_info *mci, u64 dram_addr)
747{ 717{
748 struct amd64_pvt *pvt = mci->pvt_info; 718 struct amd64_pvt *pvt = mci->pvt_info;
749 u64 hole_base, hole_offset, hole_size, base, limit, sys_addr; 719 u64 hole_base, hole_offset, hole_size, base, sys_addr;
750 int ret = 0; 720 int ret = 0;
751 721
752 ret = amd64_get_dram_hole_info(mci, &hole_base, &hole_offset, 722 ret = amd64_get_dram_hole_info(mci, &hole_base, &hole_offset,
@@ -764,7 +734,7 @@ static u64 dram_addr_to_sys_addr(struct mem_ctl_info *mci, u64 dram_addr)
764 } 734 }
765 } 735 }
766 736
767 amd64_get_base_and_limit(pvt, pvt->mc_node_id, &base, &limit); 737 base = get_dram_base(pvt, pvt->mc_node_id);
768 sys_addr = dram_addr + base; 738 sys_addr = dram_addr + base;
769 739
770 /* 740 /*
@@ -1090,33 +1060,21 @@ static u64 k8_get_error_address(struct mem_ctl_info *mci,
1090 (info->nbeal & ~0x03); 1060 (info->nbeal & ~0x03);
1091} 1061}
1092 1062
1093/* 1063static void read_dram_base_limit_regs(struct amd64_pvt *pvt, unsigned range)
1094 * Read the Base and Limit registers for K8 based Memory controllers; extract
1095 * fields from the 'raw' reg into separate data fields
1096 *
1097 * Isolates: BASE, LIMIT, IntlvEn, IntlvSel, RW_EN
1098 */
1099static void k8_read_dram_base_limit(struct amd64_pvt *pvt, int dram)
1100{ 1064{
1101 u32 low; 1065 u32 off = range << 3;
1102 u32 off = dram << 3; /* 8 bytes between DRAM entries */
1103 1066
1104 amd64_read_pci_cfg(pvt->F1, K8_DRAM_BASE_LOW + off, &low); 1067 amd64_read_pci_cfg(pvt->F1, DRAM_BASE_LO + off, &pvt->ranges[range].base.lo);
1068 amd64_read_pci_cfg(pvt->F1, DRAM_LIMIT_LO + off, &pvt->ranges[range].lim.lo);
1105 1069
1106 /* Extract parts into separate data entries */ 1070 if (boot_cpu_data.x86 == 0xf)
1107 pvt->dram_base[dram] = ((u64) low & 0xFFFF0000) << 8; 1071 return;
1108 pvt->dram_IntlvEn[dram] = (low >> 8) & 0x7;
1109 pvt->dram_rw_en[dram] = (low & 0x3);
1110 1072
1111 amd64_read_pci_cfg(pvt->F1, K8_DRAM_LIMIT_LOW + off, &low); 1073 if (!dram_rw(pvt, range))
1074 return;
1112 1075
1113 /* 1076 amd64_read_pci_cfg(pvt->F1, DRAM_BASE_HI + off, &pvt->ranges[range].base.hi);
1114 * Extract parts into separate data entries. Limit is the HIGHEST memory 1077 amd64_read_pci_cfg(pvt->F1, DRAM_LIMIT_HI + off, &pvt->ranges[range].lim.hi);
1115 * location of the region, so lower 24 bits need to be all ones
1116 */
1117 pvt->dram_limit[dram] = (((u64) low & 0xFFFF0000) << 8) | 0x00FFFFFF;
1118 pvt->dram_IntlvSel[dram] = (low >> 8) & 0x7;
1119 pvt->dram_DstNode[dram] = (low & 0x7);
1120} 1078}
1121 1079
1122static void k8_map_sysaddr_to_csrow(struct mem_ctl_info *mci, 1080static void k8_map_sysaddr_to_csrow(struct mem_ctl_info *mci,
@@ -1271,53 +1229,6 @@ static u64 f10_get_error_address(struct mem_ctl_info *mci,
1271 (info->nbeal & ~0x01); 1229 (info->nbeal & ~0x01);
1272} 1230}
1273 1231
1274/*
1275 * Read the Base and Limit registers for F10 based Memory controllers. Extract
1276 * fields from the 'raw' reg into separate data fields.
1277 *
1278 * Isolates: BASE, LIMIT, IntlvEn, IntlvSel, RW_EN.
1279 */
1280static void f10_read_dram_base_limit(struct amd64_pvt *pvt, int dram)
1281{
1282 u32 high_offset, low_offset, high_base, low_base, high_limit, low_limit;
1283
1284 low_offset = K8_DRAM_BASE_LOW + (dram << 3);
1285 high_offset = F10_DRAM_BASE_HIGH + (dram << 3);
1286
1287 /* read the 'raw' DRAM BASE Address register */
1288 amd64_read_pci_cfg(pvt->F1, low_offset, &low_base);
1289 amd64_read_pci_cfg(pvt->F1, high_offset, &high_base);
1290
1291 /* Extract parts into separate data entries */
1292 pvt->dram_rw_en[dram] = (low_base & 0x3);
1293
1294 if (pvt->dram_rw_en[dram] == 0)
1295 return;
1296
1297 pvt->dram_IntlvEn[dram] = (low_base >> 8) & 0x7;
1298
1299 pvt->dram_base[dram] = (((u64)high_base & 0x000000FF) << 40) |
1300 (((u64)low_base & 0xFFFF0000) << 8);
1301
1302 low_offset = K8_DRAM_LIMIT_LOW + (dram << 3);
1303 high_offset = F10_DRAM_LIMIT_HIGH + (dram << 3);
1304
1305 /* read the 'raw' LIMIT registers */
1306 amd64_read_pci_cfg(pvt->F1, low_offset, &low_limit);
1307 amd64_read_pci_cfg(pvt->F1, high_offset, &high_limit);
1308
1309 pvt->dram_DstNode[dram] = (low_limit & 0x7);
1310 pvt->dram_IntlvSel[dram] = (low_limit >> 8) & 0x7;
1311
1312 /*
1313 * Extract address values and form a LIMIT address. Limit is the HIGHEST
1314 * memory location of the region, so low 24 bits need to be all ones.
1315 */
1316 pvt->dram_limit[dram] = (((u64)high_limit & 0x000000FF) << 40) |
1317 (((u64) low_limit & 0xFFFF0000) << 8) |
1318 0x00FFFFFF;
1319}
1320
1321static void f10_read_dram_ctl_register(struct amd64_pvt *pvt) 1232static void f10_read_dram_ctl_register(struct amd64_pvt *pvt)
1322{ 1233{
1323 1234
@@ -1520,22 +1431,21 @@ static int f10_lookup_addr_in_dct(u32 in_addr, u32 nid, u32 cs)
1520} 1431}
1521 1432
1522/* For a given @dram_range, check if @sys_addr falls within it. */ 1433/* For a given @dram_range, check if @sys_addr falls within it. */
1523static int f10_match_to_this_node(struct amd64_pvt *pvt, int dram_range, 1434static int f10_match_to_this_node(struct amd64_pvt *pvt, int range,
1524 u64 sys_addr, int *nid, int *chan_sel) 1435 u64 sys_addr, int *nid, int *chan_sel)
1525{ 1436{
1526 int node_id, cs_found = -EINVAL, high_range = 0; 1437 int cs_found = -EINVAL, high_range = 0;
1527 u32 intlv_en, intlv_sel, intlv_shift, hole_off; 1438 u32 intlv_shift, hole_off;
1528 u32 hole_valid, tmp, dct_sel_base, channel; 1439 u32 hole_valid, tmp, dct_sel_base, channel;
1529 u64 dram_base, chan_addr, dct_sel_base_off; 1440 u64 chan_addr, dct_sel_base_off;
1530
1531 dram_base = pvt->dram_base[dram_range];
1532 intlv_en = pvt->dram_IntlvEn[dram_range];
1533 1441
1534 node_id = pvt->dram_DstNode[dram_range]; 1442 u8 node_id = dram_dst_node(pvt, range);
1535 intlv_sel = pvt->dram_IntlvSel[dram_range]; 1443 u32 intlv_en = dram_intlv_en(pvt, range);
1444 u32 intlv_sel = dram_intlv_sel(pvt, range);
1445 u64 dram_base = get_dram_base(pvt, range);
1536 1446
1537 debugf1("(dram=%d) Base=0x%llx SystemAddr= 0x%llx Limit=0x%llx\n", 1447 debugf1("(range %d) Base=0x%llx SystemAddr= 0x%llx Limit=0x%llx\n",
1538 dram_range, dram_base, sys_addr, pvt->dram_limit[dram_range]); 1448 range, dram_base, sys_addr, get_dram_limit(pvt, range));
1539 1449
1540 /* 1450 /*
1541 * This assumes that one node's DHAR is the same as all the other 1451 * This assumes that one node's DHAR is the same as all the other
@@ -1604,20 +1514,17 @@ static int f10_match_to_this_node(struct amd64_pvt *pvt, int dram_range,
1604static int f10_translate_sysaddr_to_cs(struct amd64_pvt *pvt, u64 sys_addr, 1514static int f10_translate_sysaddr_to_cs(struct amd64_pvt *pvt, u64 sys_addr,
1605 int *node, int *chan_sel) 1515 int *node, int *chan_sel)
1606{ 1516{
1607 int dram_range, cs_found = -EINVAL; 1517 int range, cs_found = -EINVAL;
1608 u64 dram_base, dram_limit;
1609 1518
1610 for (dram_range = 0; dram_range < DRAM_REG_COUNT; dram_range++) { 1519 for (range = 0; range < DRAM_RANGES; range++) {
1611 1520
1612 if (!pvt->dram_rw_en[dram_range]) 1521 if (!dram_rw(pvt, range))
1613 continue; 1522 continue;
1614 1523
1615 dram_base = pvt->dram_base[dram_range]; 1524 if ((get_dram_base(pvt, range) <= sys_addr) &&
1616 dram_limit = pvt->dram_limit[dram_range]; 1525 (get_dram_limit(pvt, range) >= sys_addr)) {
1617 1526
1618 if ((dram_base <= sys_addr) && (sys_addr <= dram_limit)) { 1527 cs_found = f10_match_to_this_node(pvt, range,
1619
1620 cs_found = f10_match_to_this_node(pvt, dram_range,
1621 sys_addr, node, 1528 sys_addr, node,
1622 chan_sel); 1529 chan_sel);
1623 if (cs_found >= 0) 1530 if (cs_found >= 0)
@@ -1727,7 +1634,6 @@ static struct amd64_family_type amd64_family_types[] = {
1727 .ops = { 1634 .ops = {
1728 .early_channel_count = k8_early_channel_count, 1635 .early_channel_count = k8_early_channel_count,
1729 .get_error_address = k8_get_error_address, 1636 .get_error_address = k8_get_error_address,
1730 .read_dram_base_limit = k8_read_dram_base_limit,
1731 .map_sysaddr_to_csrow = k8_map_sysaddr_to_csrow, 1637 .map_sysaddr_to_csrow = k8_map_sysaddr_to_csrow,
1732 .dbam_to_cs = k8_dbam_to_chip_select, 1638 .dbam_to_cs = k8_dbam_to_chip_select,
1733 .read_dct_pci_cfg = k8_read_dct_pci_cfg, 1639 .read_dct_pci_cfg = k8_read_dct_pci_cfg,
@@ -1740,7 +1646,6 @@ static struct amd64_family_type amd64_family_types[] = {
1740 .ops = { 1646 .ops = {
1741 .early_channel_count = f10_early_channel_count, 1647 .early_channel_count = f10_early_channel_count,
1742 .get_error_address = f10_get_error_address, 1648 .get_error_address = f10_get_error_address,
1743 .read_dram_base_limit = f10_read_dram_base_limit,
1744 .read_dram_ctl_register = f10_read_dram_ctl_register, 1649 .read_dram_ctl_register = f10_read_dram_ctl_register,
1745 .map_sysaddr_to_csrow = f10_map_sysaddr_to_csrow, 1650 .map_sysaddr_to_csrow = f10_map_sysaddr_to_csrow,
1746 .dbam_to_cs = f10_dbam_to_chip_select, 1651 .dbam_to_cs = f10_dbam_to_chip_select,
@@ -2099,7 +2004,7 @@ static void read_mc_regs(struct amd64_pvt *pvt)
2099{ 2004{
2100 u64 msr_val; 2005 u64 msr_val;
2101 u32 tmp; 2006 u32 tmp;
2102 int dram; 2007 int range;
2103 2008
2104 /* 2009 /*
2105 * Retrieve TOP_MEM and TOP_MEM2; no masking off of reserved bits since 2010 * Retrieve TOP_MEM and TOP_MEM2; no masking off of reserved bits since
@@ -2121,34 +2026,27 @@ static void read_mc_regs(struct amd64_pvt *pvt)
2121 if (pvt->ops->read_dram_ctl_register) 2026 if (pvt->ops->read_dram_ctl_register)
2122 pvt->ops->read_dram_ctl_register(pvt); 2027 pvt->ops->read_dram_ctl_register(pvt);
2123 2028
2124 for (dram = 0; dram < DRAM_REG_COUNT; dram++) { 2029 for (range = 0; range < DRAM_RANGES; range++) {
2125 /* 2030 u8 rw;
2126 * Call CPU specific READ function to get the DRAM Base and
2127 * Limit values from the DCT.
2128 */
2129 pvt->ops->read_dram_base_limit(pvt, dram);
2130 2031
2131 /* 2032 /* read settings for this DRAM range */
2132 * Only print out debug info on rows with both R and W Enabled. 2033 read_dram_base_limit_regs(pvt, range);
2133 * Normal processing, compiler should optimize this whole 'if' 2034
2134 * debug output block away. 2035 rw = dram_rw(pvt, range);
2135 */ 2036 if (!rw)
2136 if (pvt->dram_rw_en[dram] != 0) { 2037 continue;
2137 debugf1(" DRAM-BASE[%d]: 0x%016llx " 2038
2138 "DRAM-LIMIT: 0x%016llx\n", 2039 debugf1(" DRAM range[%d], base: 0x%016llx; limit: 0x%016llx\n",
2139 dram, 2040 range,
2140 pvt->dram_base[dram], 2041 get_dram_base(pvt, range),
2141 pvt->dram_limit[dram]); 2042 get_dram_limit(pvt, range));
2142 2043
2143 debugf1(" IntlvEn=%s %s %s " 2044 debugf1(" IntlvEn=%s; Range access: %s%s IntlvSel=%d DstNode=%d\n",
2144 "IntlvSel=%d DstNode=%d\n", 2045 dram_intlv_en(pvt, range) ? "Enabled" : "Disabled",
2145 pvt->dram_IntlvEn[dram] ? 2046 (rw & 0x1) ? "R" : "-",
2146 "Enabled" : "Disabled", 2047 (rw & 0x2) ? "W" : "-",
2147 (pvt->dram_rw_en[dram] & 0x2) ? "W" : "!W", 2048 dram_intlv_sel(pvt, range),
2148 (pvt->dram_rw_en[dram] & 0x1) ? "R" : "!R", 2049 dram_dst_node(pvt, range));
2149 pvt->dram_IntlvSel[dram],
2150 pvt->dram_DstNode[dram]);
2151 }
2152 } 2050 }
2153 2051
2154 read_dct_base_mask(pvt); 2052 read_dct_base_mask(pvt);
diff --git a/drivers/edac/amd64_edac.h b/drivers/edac/amd64_edac.h
index 91c266b9f6cf..93af3575e427 100644
--- a/drivers/edac/amd64_edac.h
+++ b/drivers/edac/amd64_edac.h
@@ -153,8 +153,8 @@
153#define K8_REV_F 4 153#define K8_REV_F 4
154 154
155/* Hardware limit on ChipSelect rows per MC and processors per system */ 155/* Hardware limit on ChipSelect rows per MC and processors per system */
156#define MAX_CS_COUNT 8 156#define NUM_CHIPSELECTS 8
157#define DRAM_REG_COUNT 8 157#define DRAM_RANGES 8
158 158
159#define ON true 159#define ON true
160#define OFF false 160#define OFF false
@@ -167,8 +167,14 @@
167/* 167/*
168 * Function 1 - Address Map 168 * Function 1 - Address Map
169 */ 169 */
170#define K8_DRAM_BASE_LOW 0x40 170#define DRAM_BASE_LO 0x40
171#define K8_DRAM_LIMIT_LOW 0x44 171#define DRAM_LIMIT_LO 0x44
172
173#define dram_intlv_en(pvt, i) ((pvt->ranges[i].base.lo >> 8) & 0x7)
174#define dram_rw(pvt, i) (pvt->ranges[i].base.lo & 0x3)
175#define dram_intlv_sel(pvt, i) ((pvt->ranges[i].lim.lo >> 8) & 0x7)
176#define dram_dst_node(pvt, i) (pvt->ranges[i].lim.lo & 0x7)
177
172#define K8_DHAR 0xf0 178#define K8_DHAR 0xf0
173 179
174#define DHAR_VALID BIT(0) 180#define DHAR_VALID BIT(0)
@@ -186,9 +192,8 @@
186 192
187#define DCT_CFG_SEL 0x10C 193#define DCT_CFG_SEL 0x10C
188 194
189/* F10 High BASE/LIMIT registers */ 195#define DRAM_BASE_HI 0x140
190#define F10_DRAM_BASE_HIGH 0x140 196#define DRAM_LIMIT_HI 0x144
191#define F10_DRAM_LIMIT_HIGH 0x144
192 197
193 198
194/* 199/*
@@ -395,6 +400,19 @@ struct error_injection {
395 u32 bit_map; 400 u32 bit_map;
396}; 401};
397 402
403/* low and high part of PCI config space regs */
404struct reg_pair {
405 u32 lo, hi;
406};
407
408/*
409 * See F1x[1, 0][7C:40] DRAM Base/Limit Registers
410 */
411struct dram_range {
412 struct reg_pair base;
413 struct reg_pair lim;
414};
415
398struct amd64_pvt { 416struct amd64_pvt {
399 struct low_ops *ops; 417 struct low_ops *ops;
400 418
@@ -418,23 +436,15 @@ struct amd64_pvt {
418 u32 dbam1; /* DRAM Base Address Mapping reg for DCT1 */ 436 u32 dbam1; /* DRAM Base Address Mapping reg for DCT1 */
419 437
420 /* DRAM CS Base Address Registers F2x[1,0][5C:40] */ 438 /* DRAM CS Base Address Registers F2x[1,0][5C:40] */
421 u32 dcsb0[MAX_CS_COUNT]; 439 u32 dcsb0[NUM_CHIPSELECTS];
422 u32 dcsb1[MAX_CS_COUNT]; 440 u32 dcsb1[NUM_CHIPSELECTS];
423 441
424 /* DRAM CS Mask Registers F2x[1,0][6C:60] */ 442 /* DRAM CS Mask Registers F2x[1,0][6C:60] */
425 u32 dcsm0[MAX_CS_COUNT]; 443 u32 dcsm0[NUM_CHIPSELECTS];
426 u32 dcsm1[MAX_CS_COUNT]; 444 u32 dcsm1[NUM_CHIPSELECTS];
427 445
428 /* 446 /* DRAM base and limit pairs F1x[78,70,68,60,58,50,48,40] */
429 * Decoded parts of DRAM BASE and LIMIT Registers 447 struct dram_range ranges[DRAM_RANGES];
430 * F1x[78,70,68,60,58,50,48,40]
431 */
432 u64 dram_base[DRAM_REG_COUNT];
433 u64 dram_limit[DRAM_REG_COUNT];
434 u8 dram_IntlvSel[DRAM_REG_COUNT];
435 u8 dram_IntlvEn[DRAM_REG_COUNT];
436 u8 dram_DstNode[DRAM_REG_COUNT];
437 u8 dram_rw_en[DRAM_REG_COUNT];
438 448
439 /* 449 /*
440 * The following fields are set at (load) run time, after CPU revision 450 * The following fields are set at (load) run time, after CPU revision
@@ -472,6 +482,26 @@ struct amd64_pvt {
472 482
473}; 483};
474 484
485static inline u64 get_dram_base(struct amd64_pvt *pvt, unsigned i)
486{
487 u64 addr = ((u64)pvt->ranges[i].base.lo & 0xffff0000) << 8;
488
489 if (boot_cpu_data.x86 == 0xf)
490 return addr;
491
492 return (((u64)pvt->ranges[i].base.hi & 0x000000ff) << 40) | addr;
493}
494
495static inline u64 get_dram_limit(struct amd64_pvt *pvt, unsigned i)
496{
497 u64 lim = (((u64)pvt->ranges[i].lim.lo & 0xffff0000) << 8) | 0x00ffffff;
498
499 if (boot_cpu_data.x86 == 0xf)
500 return lim;
501
502 return (((u64)pvt->ranges[i].lim.hi & 0x000000ff) << 40) | lim;
503}
504
475/* 505/*
476 * per-node ECC settings descriptor 506 * per-node ECC settings descriptor
477 */ 507 */
@@ -517,7 +547,6 @@ struct low_ops {
517 547
518 u64 (*get_error_address) (struct mem_ctl_info *mci, 548 u64 (*get_error_address) (struct mem_ctl_info *mci,
519 struct err_regs *info); 549 struct err_regs *info);
520 void (*read_dram_base_limit) (struct amd64_pvt *pvt, int dram);
521 void (*read_dram_ctl_register) (struct amd64_pvt *pvt); 550 void (*read_dram_ctl_register) (struct amd64_pvt *pvt);
522 void (*map_sysaddr_to_csrow) (struct mem_ctl_info *mci, 551 void (*map_sysaddr_to_csrow) (struct mem_ctl_info *mci,
523 struct err_regs *info, u64 SystemAddr); 552 struct err_regs *info, u64 SystemAddr);