nb/intel/i945: Add a common function to compute TSEG size

This adds a common function to decode the TSEG size from the ESMRAM
register. This will come in handy when SMM in TSEG is implemented.

This function is used both in romstage and in ramstage.

Change-Id: I4e163598752fb6cd036aec229fce439ebad74def
Signed-off-by: Arthur Heymans <arthur@aheymans.xyz>
Reviewed-on: https://review.coreboot.org/23448
Reviewed-by: Patrick Georgi <pgeorgi@google.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
Arthur Heymans 2018-01-26 11:50:04 +01:00 committed by Patrick Georgi
parent 20c893e82c
commit f6d14773b2
3 changed files with 29 additions and 45 deletions

View File

@ -365,6 +365,7 @@ void dump_spd_registers(void);
void dump_mem(unsigned int start, unsigned int end); void dump_mem(unsigned int start, unsigned int end);
u32 decode_igd_memory_size(u32 gms); u32 decode_igd_memory_size(u32 gms);
u32 decode_tseg_size(const u8 esmramc);
#endif /* __ACPI__ */ #endif /* __ACPI__ */

View File

@ -59,8 +59,8 @@ static int get_pcie_bar(u32 *base)
static void pci_domain_set_resources(struct device *dev) static void pci_domain_set_resources(struct device *dev)
{ {
uint32_t pci_tolm; uint32_t pci_tolm, tseg_sizek;
uint8_t tolud, reg8; uint8_t tolud;
uint16_t reg16; uint16_t reg16;
unsigned long long tomk, tomk_stolen; unsigned long long tomk, tomk_stolen;
uint64_t uma_memory_base = 0, uma_memory_size = 0; uint64_t uma_memory_base = 0, uma_memory_size = 0;
@ -95,31 +95,12 @@ static void pci_domain_set_resources(struct device *dev)
uma_memory_size = uma_size * 1024ULL; uma_memory_size = uma_size * 1024ULL;
} }
reg8 = pci_read_config8(dev_find_slot(0, PCI_DEVFN(0, 0)), ESMRAMC); tseg_sizek = decode_tseg_size(pci_read_config8(dev_find_slot(0,
if (reg8 & 1) { PCI_DEVFN(0, 0)), ESMRAMC)) >> 10;
int tseg_size = 0; printk(BIOS_DEBUG, "TSEG decoded, subtracting %dM\n", tseg_sizek >> 10);
printk(BIOS_DEBUG, "TSEG decoded, subtracting "); tomk_stolen -= tseg_sizek;
reg8 >>= 1;
reg8 &= 3;
switch (reg8) {
case 0:
tseg_size = 1024;
break; /* TSEG = 1M */
case 1:
tseg_size = 2048;
break; /* TSEG = 2M */
case 2:
tseg_size = 8192;
break; /* TSEG = 8M */
}
printk(BIOS_DEBUG, "%dM\n", tseg_size >> 10);
tomk_stolen -= tseg_size;
/* For reserving TSEG memory in the memory map */
tseg_memory_base = tomk_stolen * 1024ULL; tseg_memory_base = tomk_stolen * 1024ULL;
tseg_memory_size = tseg_size * 1024ULL; tseg_memory_size = tseg_sizek * 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

View File

@ -25,6 +25,24 @@
#include <cpu/x86/mtrr.h> #include <cpu/x86/mtrr.h>
#include <program_loading.h> #include <program_loading.h>
/* Decodes TSEG region size to bytes. */
u32 decode_tseg_size(const u8 esmramc)
{
if (!(esmramc & 1))
return 0;
switch ((esmramc >> 1) & 3) {
case 0:
return 1 << 20;
case 1:
return 2 << 20;
case 2:
return 8 << 20;
case 3:
default:
die("Bad TSEG setting.\n");
}
}
static uintptr_t smm_region_start(void) static uintptr_t smm_region_start(void)
{ {
uintptr_t tom; uintptr_t tom;
@ -35,24 +53,8 @@ static uintptr_t smm_region_start(void)
else else
tom = (pci_read_config8(PCI_DEV(0, 0, 0), TOLUD) & 0xf7) << 24; tom = (pci_read_config8(PCI_DEV(0, 0, 0), TOLUD) & 0xf7) << 24;
/* if TSEG enabled subtract size */ /* subsctract TSEG size */
switch (pci_read_config8(PCI_DEV(0, 0, 0), ESMRAMC) & 0x07) { tom -= decode_tseg_size(pci_read_config8(PCI_DEV(0, 0, 0), ESMRAMC));
case 0x01:
/* 1MB TSEG */
tom -= 0x100000;
break;
case 0x03:
/* 2MB TSEG */
tom -= 0x200000;
break;
case 0x05:
/* 8MB TSEG */
tom -= 0x800000;
break;
default:
/* TSEG either disabled or invalid */
break;
}
return tom; return tom;
} }