Kyösti Mälkki (kyosti.malkki@gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/1239
-gerrit
commit 2863e55ffa17b8f822f1bbd1b6b3a7cb46f3f5a2 Author: Kyösti Mälkki kyosti.malkki@gmail.com Date: Fri Jul 27 08:42:20 2012 +0300
Intel and GFXUMA: fix MTRR and use uma_resource()
Commit 2d42b340034ff005693482ef9ca34ce3e0f08371 changed the variable MTRR setup and removed compensation of uma_memory_size in the cacheable memory resources.
Since the cacheable region size was no longer divisible by a large power of 2, like 256 MB, this caused excessive use of MTRRs. As first symptoms, slow boot with grub and poor user response.
As a solution, register the actual top of low ram with ram_resource(), and do not subtract the UMA/TSEG regions from it.
TSEG may require further work as the original did not appear exactly right to begin with. To have UMA as un-cacheable, use uma_resource().
Change-Id: I4ca99b5c2ca4e474296590b3d0c6ef5d09550d80 Signed-off-by: Kyösti Mälkki kyosti.malkki@gmail.com --- src/northbridge/intel/i82810/northbridge.c | 11 +++++---- src/northbridge/intel/i82830/northbridge.c | 14 +++++----- src/northbridge/intel/i945/northbridge.c | 34 ++++++++++++++------------- src/northbridge/intel/sch/northbridge.c | 26 +++++++++++---------- 4 files changed, 45 insertions(+), 40 deletions(-)
diff --git a/src/northbridge/intel/i82810/northbridge.c b/src/northbridge/intel/i82810/northbridge.c index 892fc28..f6d14e0 100644 --- a/src/northbridge/intel/i82810/northbridge.c +++ b/src/northbridge/intel/i82810/northbridge.c @@ -93,7 +93,7 @@ static void pci_domain_set_resources(device_t dev) if (!mc_dev) return;
- unsigned long tomk; + unsigned long tomk, tomk_stolen; int idx, drp_value; u8 reg8;
@@ -123,21 +123,22 @@ static void pci_domain_set_resources(device_t dev) tomk += (unsigned long)(translate_i82810_to_mb[drp_value]); /* Convert tomk from MB to KB. */ tomk = tomk << 10; - tomk -= igd_memory; + tomk_stolen = tomk - igd_memory;
/* For reserving UMA memory in the memory map */ - uma_memory_base = tomk * 1024ULL; + uma_memory_base = tomk_stolen * 1024ULL; uma_memory_size = igd_memory * 1024ULL; - printk(BIOS_DEBUG, "Available memory: %ldKB\n", tomk); + printk(BIOS_DEBUG, "Available memory: %ldKB\n", tomk_stolen);
/* Report the memory regions. */ idx = 10; ram_resource(dev, idx++, 0, 640); ram_resource(dev, idx++, 768, tomk - 768); + uma_resource(dev, idx++, uma_memory_base >> 10, uma_memory_size >> 10);
#if CONFIG_WRITE_HIGH_TABLES /* Leave some space for ACPI, PIRQ and MP tables */ - high_tables_base = (tomk * 1024) - HIGH_MEMORY_SIZE; + high_tables_base = (tomk_stolen * 1024) - HIGH_MEMORY_SIZE; high_tables_size = HIGH_MEMORY_SIZE; #endif assign_resources(dev->link_list); diff --git a/src/northbridge/intel/i82830/northbridge.c b/src/northbridge/intel/i82830/northbridge.c index 4ada4d7..649a203 100644 --- a/src/northbridge/intel/i82830/northbridge.c +++ b/src/northbridge/intel/i82830/northbridge.c @@ -73,7 +73,7 @@ static void pci_domain_set_resources(device_t dev) if (!mc_dev) return;
- unsigned long tomk; + unsigned long tomk, tomk_stolen; int idx;
if (CONFIG_VIDEO_MB == 512) { @@ -89,24 +89,24 @@ static void pci_domain_set_resources(device_t dev) * i.e. 1 means 32MB. */ tomk = ((unsigned long)pci_read_config8(mc_dev, DRB + 3)) << 15; - tomk -= igd_memory; + tomk_stolen = tomk - igd_memory;
/* For reserving UMA memory in the memory map */ - uma_memory_base = tomk * 1024ULL; + uma_memory_base = tomk_stolen * 1024ULL; uma_memory_size = igd_memory * 1024ULL; - printk(BIOS_DEBUG, "Available memory: %ldKB\n", tomk); + printk(BIOS_DEBUG, "Available memory: %ldKB\n", tomk_stolen);
/* Report the memory regions. */ idx = 10; ram_resource(dev, idx++, 0, 640); - ram_resource(dev, idx++, 768, 256); - ram_resource(dev, idx++, 1024, tomk - 1024); + ram_resource(dev, idx++, 768, tomk - 768); + uma_resource(dev, idx++, uma_memory_base >> 10, uma_memory_size >> 10);
assign_resources(dev->link_list);
#if CONFIG_WRITE_HIGH_TABLES /* Leave some space for ACPI, PIRQ and MP tables */ - high_tables_base = (tomk * 1024) - HIGH_MEMORY_SIZE; + high_tables_base = (tomk_stolen * 1024) - HIGH_MEMORY_SIZE; high_tables_size = HIGH_MEMORY_SIZE; #endif } diff --git a/src/northbridge/intel/i945/northbridge.c b/src/northbridge/intel/i945/northbridge.c index 9a69823..9d6d0df 100644 --- a/src/northbridge/intel/i945/northbridge.c +++ b/src/northbridge/intel/i945/northbridge.c @@ -73,16 +73,9 @@ static void add_fixed_resources(struct device *dev, int index) struct resource *resource; u32 pcie_config_base, pcie_config_size;
- printk(BIOS_DEBUG, "Adding UMA memory area\n"); - resource = new_resource(dev, index); - resource->base = (resource_t) uma_memory_base; - resource->size = (resource_t) uma_memory_size; - resource->flags = IORESOURCE_MEM | IORESOURCE_RESERVE | - IORESOURCE_FIXED | IORESOURCE_STORED | IORESOURCE_ASSIGNED; - if (get_pcie_bar(&pcie_config_base, &pcie_config_size)) { printk(BIOS_DEBUG, "Adding PCIe config bar\n"); - resource = new_resource(dev, index+1); + resource = new_resource(dev, index++); resource->base = (resource_t) pcie_config_base; resource->size = (resource_t) pcie_config_size; resource->flags = IORESOURCE_MEM | IORESOURCE_RESERVE | @@ -99,7 +92,8 @@ static void pci_domain_set_resources(device_t dev) uint32_t pci_tolm; uint8_t tolud, reg8; uint16_t reg16; - unsigned long long tomk; + unsigned long long tomk, tomk_stolen; + uint64_t tseg_memory_base = 0, tseg_memory_size = 0;
/* Can we find out how much memory we can use at most * this way? @@ -114,6 +108,7 @@ static void pci_domain_set_resources(device_t dev) printk(BIOS_SPEW, "Top of Low Used DRAM: 0x%08x\n", tolud << 24);
tomk = tolud << 14; + tomk_stolen = tomk;
/* Note: subtract IGD device and TSEG */ reg8 = pci_read_config8(dev_find_slot(0, PCI_DEVFN(0, 0)), 0x9e); @@ -135,7 +130,11 @@ static void pci_domain_set_resources(device_t dev) }
printk(BIOS_DEBUG, "%dM\n", tseg_size >> 10); - tomk -= tseg_size; + tomk_stolen -= tseg_size; + + /* For reserving TSEG memory in the memory map */ + tseg_memory_base = tomk_stolen * 1024ULL; + tseg_memory_size = tseg_size * 1024ULL; }
reg16 = pci_read_config16(dev_find_slot(0, PCI_DEVFN(0, 0)), GGC); @@ -154,29 +153,32 @@ static void pci_domain_set_resources(device_t dev) }
printk(BIOS_DEBUG, "%dM UMA\n", uma_size >> 10); - tomk -= uma_size; + tomk_stolen -= uma_size;
/* For reserving UMA memory in the memory map */ - uma_memory_base = tomk * 1024ULL; + uma_memory_base = tomk_stolen * 1024ULL; uma_memory_size = uma_size * 1024ULL; }
/* The following needs to be 2 lines, otherwise the second * number is always 0 */ - printk(BIOS_INFO, "Available memory: %dK", (uint32_t)tomk); - printk(BIOS_INFO, " (%dM)\n", (uint32_t)(tomk >> 10)); + printk(BIOS_INFO, "Available memory: %dK", (uint32_t)tomk_stolen); + printk(BIOS_INFO, " (%dM)\n", (uint32_t)(tomk_stolen >> 10));
/* Report the memory regions */ ram_resource(dev, 3, 0, 640); ram_resource(dev, 4, 768, (tomk - 768)); - add_fixed_resources(dev, 6); + uma_resource(dev, 5, uma_memory_base >> 10, uma_memory_size >> 10); + mmio_resource(dev, 6, tseg_memory_base >> 10, tseg_memory_size >> 10); + + add_fixed_resources(dev, 7);
assign_resources(dev->link_list);
#if CONFIG_WRITE_HIGH_TABLES /* Leave some space for ACPI, PIRQ and MP tables */ - high_tables_base = (tomk * 1024) - HIGH_MEMORY_SIZE; + high_tables_base = (tomk_stolen * 1024) - HIGH_MEMORY_SIZE; high_tables_size = HIGH_MEMORY_SIZE; #endif } diff --git a/src/northbridge/intel/sch/northbridge.c b/src/northbridge/intel/sch/northbridge.c index 52b688a..419a82c 100644 --- a/src/northbridge/intel/sch/northbridge.c +++ b/src/northbridge/intel/sch/northbridge.c @@ -78,13 +78,6 @@ static void add_fixed_resources(struct device *dev, int index) struct resource *resource; u32 pcie_config_base, pcie_config_size;
- printk(BIOS_DEBUG, "Adding UMA memory area\n"); - resource = new_resource(dev, index++); - resource->base = (resource_t) uma_memory_base; - resource->size = (resource_t) uma_memory_size; - resource->flags = IORESOURCE_MEM | IORESOURCE_RESERVE | - IORESOURCE_FIXED | IORESOURCE_STORED | IORESOURCE_ASSIGNED; - if (get_pcie_bar(&pcie_config_base, &pcie_config_size)) { printk(BIOS_DEBUG, "Adding PCIe config bar\n"); resource = new_resource(dev, index++); @@ -111,7 +104,8 @@ static void pci_domain_set_resources(device_t dev) u32 pci_tolm; u8 reg8; u16 reg16; - unsigned long long tomk, tolud; + unsigned long long tomk, tolud, tomk_stolen; + uint64_t tseg_memory_base = 0, tseg_memory_size = 0;
/* Can we find out how much memory we can use at most this way? */ pci_tolm = find_pci_tolm(dev->link_list); @@ -123,6 +117,7 @@ static void pci_domain_set_resources(device_t dev) printk(BIOS_SPEW, "Top of Low Used DRAM: 0x%08llx\n", tolud << 24);
tomk = tolud << 14; + tomk_stolen = tomk;
/* Note: subtract IGD device and TSEG. */ reg8 = pci_read_config8(dev_find_slot(0, PCI_DEVFN(0, 0)), 0x9e); @@ -144,7 +139,11 @@ static void pci_domain_set_resources(device_t dev) }
printk(BIOS_DEBUG, "%dM\n", tseg_size >> 10); - tomk -= tseg_size; + tomk_stolen -= tseg_size; + + /* For reserving TSEG memory in the memory map */ + tseg_memory_base = tomk_stolen * 1024ULL; + tseg_memory_size = tseg_size * 1024ULL; }
reg16 = pci_read_config16(dev_find_slot(0, PCI_DEVFN(0, 0)), GGC); @@ -165,10 +164,10 @@ static void pci_domain_set_resources(device_t dev) break; } printk(BIOS_DEBUG, "%dM UMA\n", uma_size >> 10); - tomk -= uma_size; + tomk_stolen -= uma_size;
/* For reserving UMA memory in the memory map. */ - uma_memory_base = tomk * 1024ULL; + uma_memory_base = tomk_stolen * 1024ULL; uma_memory_size = uma_size * 1024ULL; }
@@ -182,7 +181,10 @@ static void pci_domain_set_resources(device_t dev) /* Report the memory regions. */ ram_resource(dev, 3, 0, 640); ram_resource(dev, 4, 768, (tomk - 768)); - add_fixed_resources(dev, 6); + uma_resource(dev, 5, uma_memory_base >> 10, uma_memory_size >> 10); + mmio_resource(dev, 6, tseg_memory_base >> 10, tseg_memory_size >> 10); + + add_fixed_resources(dev, 7);
assign_resources(dev->link_list);