Michał Żygowski has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/61682 )
Change subject: nb/amd/common: Move RAM calcualtion to common code ......................................................................
nb/amd/common: Move RAM calcualtion to common code
This patch addresses post-merge comments from CB:52922. This change only unifies the code used by AMD northbirdges.
TEST=Boot PC Engines apu1 and see that RAM resources did not change.
Signed-off-by: Michał Żygowski michal.zygowski@3mdeb.com Change-Id: I3d222f6cbd26fe78d968d2883984f25e8b62ab5c --- M src/northbridge/amd/agesa/Makefile.inc M src/northbridge/amd/agesa/family14/northbridge.c M src/northbridge/amd/agesa/family15tn/northbridge.c M src/northbridge/amd/agesa/family16kb/northbridge.c A src/northbridge/amd/common/Makefile.inc A src/northbridge/amd/common/ram_calc.c M src/northbridge/amd/nb_common.h M src/northbridge/amd/pi/00730F01/northbridge.c M src/northbridge/amd/pi/Makefile.inc 9 files changed, 96 insertions(+), 137 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/82/61682/1
diff --git a/src/northbridge/amd/agesa/Makefile.inc b/src/northbridge/amd/agesa/Makefile.inc index ca9096c..11ec9a2 100644 --- a/src/northbridge/amd/agesa/Makefile.inc +++ b/src/northbridge/amd/agesa/Makefile.inc @@ -2,6 +2,7 @@
ifeq ($(CONFIG_NORTHBRIDGE_AMD_AGESA),y)
+subdirs-y += ../common subdirs-$(CONFIG_NORTHBRIDGE_AMD_AGESA_FAMILY14) += family14 subdirs-$(CONFIG_NORTHBRIDGE_AMD_AGESA_FAMILY15_TN) += family15tn subdirs-$(CONFIG_NORTHBRIDGE_AMD_AGESA_FAMILY16_KB) += family16kb diff --git a/src/northbridge/amd/agesa/family14/northbridge.c b/src/northbridge/amd/agesa/family14/northbridge.c index 4b4ab67..e4cd187 100644 --- a/src/northbridge/amd/agesa/family14/northbridge.c +++ b/src/northbridge/amd/agesa/family14/northbridge.c @@ -104,33 +104,6 @@ } }
-static int get_dram_base_limit(u32 nodeid, resource_t *basek, resource_t *limitk) -{ - u32 temp; - - if (fx_devs == 0) - get_fx_devs(); - - - temp = pci_read_config32(__f1_dev[nodeid], 0x40 + (nodeid << 3)); //[39:24] at [31:16] - if (!(temp & 1)) - return 0; // this memory range is not enabled - /* - * BKDG: {DramBase[35:24], 00_0000h} <= address[35:0] so shift left by 8 bits - * for physical address and the convert to KiB by shifting 10 bits left - */ - *basek = ((temp & 0x0fff0000)) >> (10 - 8); - /* - * BKDG address[35:0] <= {DramLimit[35:24], FF_FFFFh} converted as above but - * ORed with 0xffff to get real limit before shifting. - */ - temp = pci_read_config32(__f1_dev[nodeid], 0x44 + (nodeid << 3)); //[39:24] at [31:16] - *limitk = ((temp & 0x0fff0000) | 0xffff) >> (10 - 8); - *limitk += 1; // round up last byte - - return 1; -} - static u32 amdfam14_nodeid(struct device *dev) { return (dev->path.pci.devfn >> 3) - DEV_CDB; @@ -309,10 +282,10 @@ mem_hole.hole_startk = CONFIG_HW_MEM_HOLE_SIZEK; mem_hole.node_id = -1;
- resource_t basek, limitk; + u64 basek, limitk; u32 hole;
- if (get_dram_base_limit(0, &basek, &limitk)) { + if (get_dram_base_limit(__f1_dev[0], 0, &basek, &limitk)) { hole = pci_read_config32(__f1_dev[0], 0xf0); if (hole & 1) { // we find the hole mem_hole.hole_startk = (hole & (0xff << 24)) >> 10; @@ -513,6 +486,9 @@ u32 reset_memhole = 1; #endif
+ if (fx_devs == 0) + get_fx_devs(); + pci_tolm = 0xffffffffUL; for (link = dev->link_list; link; link = link->next) { pci_tolm = my_find_pci_tolm(link, pci_tolm); @@ -546,9 +522,9 @@ #endif
idx = 0x10; - resource_t basek, limitk, sizek; // 4 1T + u64 basek, limitk, sizek; // 4 1T
- if (get_dram_base_limit(0, &basek, &limitk)) { + if (get_dram_base_limit(__f1_dev[0], 0, &basek, &limitk)) { sizek = limitk - basek;
printk(BIOS_DEBUG, "adsr: basek = %llx, limitk = %llx, sizek = %llx.\n", diff --git a/src/northbridge/amd/agesa/family15tn/northbridge.c b/src/northbridge/amd/agesa/family15tn/northbridge.c index bd0a5c8..2d7e93b 100644 --- a/src/northbridge/amd/agesa/family15tn/northbridge.c +++ b/src/northbridge/amd/agesa/family15tn/northbridge.c @@ -102,39 +102,6 @@ } }
-static int get_dram_base_limit(u32 nodeid, resource_t *basek, resource_t *limitk) -{ - u32 temp; - - if (fx_devs == 0) - get_fx_devs(); - - - temp = pci_read_config32(__f1_dev[nodeid], 0x40 + (nodeid << 3)); //[39:24] at [31:16] - if (!(temp & 1)) - return 0; // this memory range is not enabled - /* - * BKDG: {DramBase[47:24], 00_0000h} <= address[47:0] so shift left by 8 bits - * for physical address and the convert to KiB by shifting 10 bits left - */ - *basek = ((temp & 0xffff0000)) >> (10 - 8); - /* Now high bits [47:40] */ - temp = pci_read_config32(__f1_dev[nodeid], 0x140 + (nodeid << 3)); //[47:40] at [7:0] - *basek = *basek | ((resource_t)temp << (40 - 10)); - /* - * BKDG address[39:0] <= {DramLimit[47:24], FF_FFFFh} converted as above but - * ORed with 0xffff to get real limit before shifting. - */ - temp = pci_read_config32(__f1_dev[nodeid], 0x44 + (nodeid << 3)); //[39:24] at [31:16] - *limitk = ((temp & 0xffff0000) | 0xffff) >> (10 - 8); - /* Now high bits [47:40] */ - temp = pci_read_config32(__f1_dev[nodeid], 0x144 + (nodeid << 3)); //[47:40] at [7:0] - *limitk = *limitk | ((resource_t)temp << (40 - 10)); - *limitk += 1; // round up last byte - - return 1; -} - static u32 amdfam15_nodeid(struct device *dev) { return (dev->path.pci.devfn >> 3) - DEV_CDB; @@ -626,9 +593,9 @@ mem_hole.hole_startk = CONFIG_HW_MEM_HOLE_SIZEK; mem_hole.node_id = -1; for (i = 0; i < node_nums; i++) { - resource_t basek, limitk; + u64 basek, limitk; u32 hole; - if (!get_dram_base_limit(i, &basek, &limitk)) + if (!get_dram_base_limit(__f1_dev[i], i, &basek, &limitk)) continue; // no memory on this node hole = pci_read_config32(__f1_dev[i], 0xf0); if (hole & 1) { // we find the hole @@ -644,8 +611,8 @@ if (mem_hole.node_id == -1) { resource_t limitk_pri = 0; for (i = 0; i < node_nums; i++) { - resource_t base_k, limit_k; - if (!get_dram_base_limit(i, &base_k, &limit_k)) + u64 base_k, limit_k; + if (!get_dram_base_limit(__f1_dev[i], i, &base_k, &limit_k)) continue; // no memory on this node if (base_k > 4 *1024 * 1024) break; // don't need to go to check if (limitk_pri != base_k) { // we find the hole @@ -671,6 +638,9 @@ u32 reset_memhole = 1; #endif
+ if (fx_devs == 0) + get_fx_devs(); + pci_tolm = 0xffffffffUL; for (link = dev->link_list; link; link = link->next) { pci_tolm = find_pci_tolm(link); @@ -705,9 +675,9 @@
idx = 0x10; for (i = 0; i < node_nums; i++) { - resource_t basek, limitk, sizek; // 4 1T + u64 basek, limitk, sizek; // 4 1T
- if (!get_dram_base_limit(i, &basek, &limitk)) + if (!get_dram_base_limit(__f1_dev[i], i, &basek, &limitk)) continue; // no memory on this node
sizek = limitk - basek; diff --git a/src/northbridge/amd/agesa/family16kb/northbridge.c b/src/northbridge/amd/agesa/family16kb/northbridge.c index 3d5313a..e754f99 100644 --- a/src/northbridge/amd/agesa/family16kb/northbridge.c +++ b/src/northbridge/amd/agesa/family16kb/northbridge.c @@ -102,33 +102,6 @@ } }
-static int get_dram_base_limit(u32 nodeid, resource_t *basek, resource_t *limitk) -{ - u32 temp; - - if (fx_devs == 0) - get_fx_devs(); - - - temp = pci_read_config32(__f1_dev[nodeid], 0x40 + (nodeid << 3)); //[39:24] at [31:16] - if (!(temp & 1)) - return 0; // this memory range is not enabled - /* - * BKDG: {DramBase[39:24], 00_0000h} <= address[39:0] so shift left by 8 bits - * for physical address and the convert to KiB by shifting 10 bits left - */ - *basek = ((temp & 0xffff0000)) >> (10 - 8); - /* - * BKDG address[39:0] <= {DramLimit[39:24], FF_FFFFh} converted as above but - * ORed with 0xffff to get real limit before shifting. - */ - temp = pci_read_config32(__f1_dev[nodeid], 0x44 + (nodeid << 3)); //[39:24] at [31:16] - *limitk = ((temp & 0xffff0000) | 0xffff) >> (10 - 8); - *limitk += 1; // round up last byte - - return 1; -} - static u32 amdfam16_nodeid(struct device *dev) { return (dev->path.pci.devfn >> 3) - DEV_CDB; @@ -638,9 +611,9 @@ mem_hole.hole_startk = CONFIG_HW_MEM_HOLE_SIZEK; mem_hole.node_id = -1; for (i = 0; i < node_nums; i++) { - resource_t basek, limitk; + u64 basek, limitk; u32 hole; - if (!get_dram_base_limit(i, &basek, &limitk)) + if (!get_dram_base_limit(__f1_dev[i], i, &basek, &limitk)) continue; // no memory on this node hole = pci_read_config32(__f1_dev[i], 0xf0); if (hole & 2) { // we find the hole @@ -656,8 +629,8 @@ if (mem_hole.node_id == -1) { resource_t limitk_pri = 0; for (i = 0; i < node_nums; i++) { - resource_t base_k, limit_k; - if (!get_dram_base_limit(i, &base_k, &limit_k)) + u64 base_k, limit_k; + if (!get_dram_base_limit(__f1_dev[i], i, &base_k, &limit_k)) continue; // no memory on this node if (base_k > 4 *1024 * 1024) break; // don't need to go to check if (limitk_pri != base_k) { // we find the hole @@ -683,6 +656,9 @@ u32 reset_memhole = 1; #endif
+ if (fx_devs == 0) + get_fx_devs(); + pci_tolm = 0xffffffffUL; for (link = dev->link_list; link; link = link->next) { pci_tolm = find_pci_tolm(link); @@ -719,7 +695,7 @@ for (i = 0; i < node_nums; i++) { resource_t basek, limitk, sizek; // 4 1T
- if (!get_dram_base_limit(i, &basek, &limitk)) + if (!get_dram_base_limit(__f1_dev[i], i, &basek, &limitk)) continue; // no memory on this node
sizek = limitk - basek; diff --git a/src/northbridge/amd/common/Makefile.inc b/src/northbridge/amd/common/Makefile.inc new file mode 100644 index 0000000..ee5d69d --- /dev/null +++ b/src/northbridge/amd/common/Makefile.inc @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0-only + +ramstage-y += ram_calc.c diff --git a/src/northbridge/amd/common/ram_calc.c b/src/northbridge/amd/common/ram_calc.c new file mode 100644 index 0000000..259554e --- /dev/null +++ b/src/northbridge/amd/common/ram_calc.c @@ -0,0 +1,54 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <console/console.h> +#include <cpu/cpu.h> +#include <commonlib/bsd/helpers.h> +#include <device/device.h> +#include <device/pci_ops.h> +#include <northbridge/amd/nb_common.h> + +int get_dram_base_limit(struct device *f1_dev, u32 nodeid, u64 *basek, u64 *limitk) +{ + u64 temp; + u32 address_bits = cpu_phys_address_size(); /* N bits of phys space */ + u64 address_mask = (1ULL << address_bits) - 1; + + if (!f1_dev) { + printk(BIOS_ERR, "Northbridge function 1 not found\n"); + return 0; + } + + /* BKDG: {DramBase[N-1:24], 00_0000h} <= address[N:0] */ + temp = pci_read_config32(f1_dev, 0x40 + (nodeid << 3)); + if (!(temp & 1)) + return 0; /* this memory range is not enabled */ + /* [N-1:24] at [N-1-8:16], if N < 40 addres_mask will clear unused high bits */ + *basek = ((temp & 0xffff0000) << 8) & address_mask; + + if (address_bits > 40) { + /* [N-1:40] at [N-1-40:0], addres_mask will clear unused high bits */ + temp = pci_read_config32(f1_dev, 0x140 + (nodeid << 3)); + *basek |= ((temp << 40) & address_mask); + } + + *basek /= KiB; /* Normalize to KiB */ + + /* + * BKDG address[N-1:0] <= {DramLimit[N-1:24], FF_FFFFh} converted as above but + * ORed with 0xffff to get real limit + */ + /* [N-1:24] at [N-1-8:16], if N < 40 addres_mask will clear unused high bits */ + temp = pci_read_config32(f1_dev, 0x44 + (nodeid << 3)); + *limitk = ((temp << 8) | 0xffffff) & address_mask; + + if (address_bits > 40) { + /* [N-1:40] at [N-1-40:0] addres_mask will clear unused high bits */ + temp = pci_read_config32(f1_dev, 0x144 + (nodeid << 3)); + *limitk |= ((temp << 40) & address_mask); + } + + *limitk += 1; /* round up last byte for northbridge resource calculation convenience */ + *limitk /= KiB; /* Normalize to KiB */ + + return 1; +} diff --git a/src/northbridge/amd/nb_common.h b/src/northbridge/amd/nb_common.h index bee75c7..c6515c8 100644 --- a/src/northbridge/amd/nb_common.h +++ b/src/northbridge/amd/nb_common.h @@ -9,4 +9,6 @@ #define DEV_CDB 0x18 #define IO_APIC2_ADDR 0xfec20000
+int get_dram_base_limit(struct device *f1_dev, u32 nodeid, u64 *basek, u64 *limitk); + #endif diff --git a/src/northbridge/amd/pi/00730F01/northbridge.c b/src/northbridge/amd/pi/00730F01/northbridge.c index 42505ab..6bc313d 100644 --- a/src/northbridge/amd/pi/00730F01/northbridge.c +++ b/src/northbridge/amd/pi/00730F01/northbridge.c @@ -88,33 +88,6 @@ } }
-static int get_dram_base_limit(u32 nodeid, resource_t *basek, resource_t *limitk) -{ - u32 temp; - - if (fx_devs == 0) - get_fx_devs(); - - - temp = pci_read_config32(__f1_dev[nodeid], 0x40 + (nodeid << 3)); //[39:24] at [31:16] - if (!(temp & 1)) - return 0; // this memory range is not enabled - /* - * BKDG: {DramBase[39:24], 00_0000h} <= address[39:0] so shift left by 8 bits - * for physical address and the convert to KiB by shifting 10 bits left - */ - *basek = ((temp & 0xffff0000)) >> (10 - 8); - /* - * BKDG address[39:0] <= {DramLimit[39:24], FF_FFFFh} converted as above but - * ORed with 0xffff to get real limit before shifting. - */ - temp = pci_read_config32(__f1_dev[nodeid], 0x44 + (nodeid << 3)); //[39:24] at [31:16] - *limitk = ((temp & 0xffff0000) | 0xffff) >> (10 - 8); - *limitk += 1; // round up last byte - - return 1; -} - static u32 amdfam16_nodeid(struct device *dev) { return (dev->path.pci.devfn >> 3) - DEV_CDB; @@ -149,8 +122,8 @@ /* Check if CC6 save area is enabled (bit 18 CC6SaveEn) */ if (pci_read_config32(__f2_dev[0], 0x118) & (1 << 18)) { /* Add CC6 DRAM UC resource residing at DRAM Limit of size 16MB as per BKDG */ - resource_t basek, limitk; - if (!get_dram_base_limit(0, &basek, &limitk)) + u64 basek, limitk; + if (!get_dram_base_limit(__f1_dev[0], 0, &basek, &limitk)) return; mmio_resource(dev, index++, limitk, 16*1024); } @@ -743,9 +716,9 @@ mem_hole.hole_startk = CONFIG_HW_MEM_HOLE_SIZEK; mem_hole.node_id = -1; for (i = 0; i < get_node_nums(); i++) { - resource_t basek, limitk; + u64 basek, limitk; u32 hole; - if (!get_dram_base_limit(i, &basek, &limitk)) + if (!get_dram_base_limit(__f1_dev[i], i, &basek, &limitk)) continue; // no memory on this node hole = pci_read_config32(__f1_dev[i], 0xf0); if (hole & 2) { // we find the hole @@ -761,8 +734,8 @@ if (mem_hole.node_id == -1) { resource_t limitk_pri = 0; for (i = 0; i < get_node_nums(); i++) { - resource_t base_k, limit_k; - if (!get_dram_base_limit(i, &base_k, &limit_k)) + u64 base_k, limit_k; + if (!get_dram_base_limit(__f1_dev[i], i, &base_k, &limit_k)) continue; // no memory on this node if (base_k > 4 *1024 * 1024) break; // don't need to go to check if (limitk_pri != base_k) { // we find the hole @@ -785,6 +758,9 @@ struct hw_mem_hole_info mem_hole; #endif
+ if (fx_devs == 0) + get_fx_devs(); + pci_domain_read_resources(dev);
/* TOP_MEM MSR is our boundary between DRAM and MMIO under 4G */ @@ -807,9 +783,9 @@
idx = 0x10; for (i = 0; i < get_node_nums(); i++) { - resource_t basek, limitk, sizek; // 4 1T + u64 basek, limitk, sizek; // 4 1T
- if (!get_dram_base_limit(i, &basek, &limitk)) + if (!get_dram_base_limit(__f1_dev[i], i, &basek, &limitk)) continue; // no memory on this node
sizek = limitk - basek; diff --git a/src/northbridge/amd/pi/Makefile.inc b/src/northbridge/amd/pi/Makefile.inc index f73b0d5..3a51bc7 100644 --- a/src/northbridge/amd/pi/Makefile.inc +++ b/src/northbridge/amd/pi/Makefile.inc @@ -2,6 +2,7 @@
ifeq ($(CONFIG_NORTHBRIDGE_AMD_PI),y)
+subdirs-y += ../common subdirs-$(CONFIG_NORTHBRIDGE_AMD_PI_00730F01) += 00730F01
endif