Intel and GFXUMA: fix MTRR and use uma_resource()
Commit 2d42b34003
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>
Reviewed-on: http://review.coreboot.org/1239
Reviewed-by: Anton Kochkov <anton.kochkov@gmail.com>
Tested-by: build bot (Jenkins)
This commit is contained in:
parent
26e441f5bc
commit
6ff1d36a47
|
@ -93,7 +93,7 @@ static void pci_domain_set_resources(device_t dev)
|
||||||
if (!mc_dev)
|
if (!mc_dev)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
unsigned long tomk;
|
unsigned long tomk, tomk_stolen;
|
||||||
int idx, drp_value;
|
int idx, drp_value;
|
||||||
u8 reg8;
|
u8 reg8;
|
||||||
|
|
||||||
|
@ -123,21 +123,22 @@ static void pci_domain_set_resources(device_t dev)
|
||||||
tomk += (unsigned long)(translate_i82810_to_mb[drp_value]);
|
tomk += (unsigned long)(translate_i82810_to_mb[drp_value]);
|
||||||
/* Convert tomk from MB to KB. */
|
/* Convert tomk from MB to KB. */
|
||||||
tomk = tomk << 10;
|
tomk = tomk << 10;
|
||||||
tomk -= igd_memory;
|
tomk_stolen = tomk - igd_memory;
|
||||||
|
|
||||||
/* For reserving UMA memory in the memory map */
|
/* 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;
|
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. */
|
/* Report the memory regions. */
|
||||||
idx = 10;
|
idx = 10;
|
||||||
ram_resource(dev, idx++, 0, 640);
|
ram_resource(dev, idx++, 0, 640);
|
||||||
ram_resource(dev, idx++, 768, tomk - 768);
|
ram_resource(dev, idx++, 768, tomk - 768);
|
||||||
|
uma_resource(dev, idx++, uma_memory_base >> 10, uma_memory_size >> 10);
|
||||||
|
|
||||||
#if CONFIG_WRITE_HIGH_TABLES
|
#if CONFIG_WRITE_HIGH_TABLES
|
||||||
/* Leave some space for ACPI, PIRQ and MP 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;
|
high_tables_size = HIGH_MEMORY_SIZE;
|
||||||
#endif
|
#endif
|
||||||
assign_resources(dev->link_list);
|
assign_resources(dev->link_list);
|
||||||
|
|
|
@ -73,7 +73,7 @@ static void pci_domain_set_resources(device_t dev)
|
||||||
if (!mc_dev)
|
if (!mc_dev)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
unsigned long tomk;
|
unsigned long tomk, tomk_stolen;
|
||||||
int idx;
|
int idx;
|
||||||
|
|
||||||
if (CONFIG_VIDEO_MB == 512) {
|
if (CONFIG_VIDEO_MB == 512) {
|
||||||
|
@ -89,24 +89,24 @@ static void pci_domain_set_resources(device_t dev)
|
||||||
* i.e. 1 means 32MB.
|
* i.e. 1 means 32MB.
|
||||||
*/
|
*/
|
||||||
tomk = ((unsigned long)pci_read_config8(mc_dev, DRB + 3)) << 15;
|
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 */
|
/* 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;
|
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. */
|
/* Report the memory regions. */
|
||||||
idx = 10;
|
idx = 10;
|
||||||
ram_resource(dev, idx++, 0, 640);
|
ram_resource(dev, idx++, 0, 640);
|
||||||
ram_resource(dev, idx++, 768, 256);
|
ram_resource(dev, idx++, 768, tomk - 768);
|
||||||
ram_resource(dev, idx++, 1024, tomk - 1024);
|
uma_resource(dev, idx++, uma_memory_base >> 10, uma_memory_size >> 10);
|
||||||
|
|
||||||
assign_resources(dev->link_list);
|
assign_resources(dev->link_list);
|
||||||
|
|
||||||
#if CONFIG_WRITE_HIGH_TABLES
|
#if CONFIG_WRITE_HIGH_TABLES
|
||||||
/* Leave some space for ACPI, PIRQ and MP 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;
|
high_tables_size = HIGH_MEMORY_SIZE;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,16 +73,9 @@ static void add_fixed_resources(struct device *dev, int index)
|
||||||
struct resource *resource;
|
struct resource *resource;
|
||||||
u32 pcie_config_base, pcie_config_size;
|
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)) {
|
if (get_pcie_bar(&pcie_config_base, &pcie_config_size)) {
|
||||||
printk(BIOS_DEBUG, "Adding PCIe config bar\n");
|
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->base = (resource_t) pcie_config_base;
|
||||||
resource->size = (resource_t) pcie_config_size;
|
resource->size = (resource_t) pcie_config_size;
|
||||||
resource->flags = IORESOURCE_MEM | IORESOURCE_RESERVE |
|
resource->flags = IORESOURCE_MEM | IORESOURCE_RESERVE |
|
||||||
|
@ -99,7 +92,8 @@ static void pci_domain_set_resources(device_t dev)
|
||||||
uint32_t pci_tolm;
|
uint32_t pci_tolm;
|
||||||
uint8_t tolud, reg8;
|
uint8_t tolud, reg8;
|
||||||
uint16_t reg16;
|
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
|
/* Can we find out how much memory we can use at most
|
||||||
* this way?
|
* 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);
|
printk(BIOS_SPEW, "Top of Low Used DRAM: 0x%08x\n", tolud << 24);
|
||||||
|
|
||||||
tomk = tolud << 14;
|
tomk = tolud << 14;
|
||||||
|
tomk_stolen = tomk;
|
||||||
|
|
||||||
/* Note: subtract IGD device and TSEG */
|
/* Note: subtract IGD device and TSEG */
|
||||||
reg8 = pci_read_config8(dev_find_slot(0, PCI_DEVFN(0, 0)), 0x9e);
|
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);
|
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);
|
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);
|
printk(BIOS_DEBUG, "%dM UMA\n", uma_size >> 10);
|
||||||
tomk -= uma_size;
|
tomk_stolen -= uma_size;
|
||||||
|
|
||||||
/* For reserving UMA memory in the memory map */
|
/* 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;
|
uma_memory_size = uma_size * 1024ULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The following needs to be 2 lines, otherwise the second
|
/* The following needs to be 2 lines, otherwise the second
|
||||||
* number is always 0
|
* number is always 0
|
||||||
*/
|
*/
|
||||||
printk(BIOS_INFO, "Available memory: %dK", (uint32_t)tomk);
|
printk(BIOS_INFO, "Available memory: %dK", (uint32_t)tomk_stolen);
|
||||||
printk(BIOS_INFO, " (%dM)\n", (uint32_t)(tomk >> 10));
|
printk(BIOS_INFO, " (%dM)\n", (uint32_t)(tomk_stolen >> 10));
|
||||||
|
|
||||||
/* Report the memory regions */
|
/* Report the memory regions */
|
||||||
ram_resource(dev, 3, 0, 640);
|
ram_resource(dev, 3, 0, 640);
|
||||||
ram_resource(dev, 4, 768, (tomk - 768));
|
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);
|
assign_resources(dev->link_list);
|
||||||
|
|
||||||
#if CONFIG_WRITE_HIGH_TABLES
|
#if CONFIG_WRITE_HIGH_TABLES
|
||||||
/* Leave some space for ACPI, PIRQ and MP 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;
|
high_tables_size = HIGH_MEMORY_SIZE;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,13 +78,6 @@ static void add_fixed_resources(struct device *dev, int index)
|
||||||
struct resource *resource;
|
struct resource *resource;
|
||||||
u32 pcie_config_base, pcie_config_size;
|
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)) {
|
if (get_pcie_bar(&pcie_config_base, &pcie_config_size)) {
|
||||||
printk(BIOS_DEBUG, "Adding PCIe config bar\n");
|
printk(BIOS_DEBUG, "Adding PCIe config bar\n");
|
||||||
resource = new_resource(dev, index++);
|
resource = new_resource(dev, index++);
|
||||||
|
@ -111,7 +104,8 @@ static void pci_domain_set_resources(device_t dev)
|
||||||
u32 pci_tolm;
|
u32 pci_tolm;
|
||||||
u8 reg8;
|
u8 reg8;
|
||||||
u16 reg16;
|
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? */
|
/* Can we find out how much memory we can use at most this way? */
|
||||||
pci_tolm = find_pci_tolm(dev->link_list);
|
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);
|
printk(BIOS_SPEW, "Top of Low Used DRAM: 0x%08llx\n", tolud << 24);
|
||||||
|
|
||||||
tomk = tolud << 14;
|
tomk = tolud << 14;
|
||||||
|
tomk_stolen = tomk;
|
||||||
|
|
||||||
/* Note: subtract IGD device and TSEG. */
|
/* Note: subtract IGD device and TSEG. */
|
||||||
reg8 = pci_read_config8(dev_find_slot(0, PCI_DEVFN(0, 0)), 0x9e);
|
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);
|
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);
|
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;
|
break;
|
||||||
}
|
}
|
||||||
printk(BIOS_DEBUG, "%dM UMA\n", uma_size >> 10);
|
printk(BIOS_DEBUG, "%dM UMA\n", uma_size >> 10);
|
||||||
tomk -= uma_size;
|
tomk_stolen -= uma_size;
|
||||||
|
|
||||||
/* For reserving UMA memory in the memory map. */
|
/* 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;
|
uma_memory_size = uma_size * 1024ULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -182,7 +181,10 @@ static void pci_domain_set_resources(device_t dev)
|
||||||
/* Report the memory regions. */
|
/* Report the memory regions. */
|
||||||
ram_resource(dev, 3, 0, 640);
|
ram_resource(dev, 3, 0, 640);
|
||||||
ram_resource(dev, 4, 768, (tomk - 768));
|
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);
|
assign_resources(dev->link_list);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue