From 9a7da182fa936d28658daadef83e0b8f7104487b Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 23 Oct 2012 18:04:35 +0000 Subject: x86: Fill in the dram info using the e820 map on coreboot/x86 This way when that dram "banks" are displayed, there's some useful information there. The number of "banks" we claim to have needs to be adjusted so that it covers the number of RAM e820 regions we expect to have/care about. This needs to be done after "RAM" initialization even though we always run from RAM. The bd pointer in the global data structure doesn't automatically point to anything, and it isn't set up until "RAM" is available since, I assume, it would take too much space in the very constrained pre-RAM environment. Signed-off-by: Gabe Black Signed-off-by: Simon Glass --- arch/x86/cpu/coreboot/sdram.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'arch/x86/cpu/coreboot/sdram.c') diff --git a/arch/x86/cpu/coreboot/sdram.c b/arch/x86/cpu/coreboot/sdram.c index f8fdac6319e..93dccb83eff 100644 --- a/arch/x86/cpu/coreboot/sdram.c +++ b/arch/x86/cpu/coreboot/sdram.c @@ -71,5 +71,20 @@ int dram_init_f(void) int dram_init(void) { + int i, j; + + if (CONFIG_NR_DRAM_BANKS) { + for (i = 0, j = 0; i < lib_sysinfo.n_memranges; i++) { + struct memrange *memrange = &lib_sysinfo.memrange[i]; + + if (memrange->type == CB_MEM_RAM) { + gd->bd->bi_dram[j].start = memrange->base; + gd->bd->bi_dram[j].size = memrange->size; + j++; + if (j >= CONFIG_NR_DRAM_BANKS) + break; + } + } + } return 0; } -- cgit v1.2.3 From 984d8b09fb3c0ebe97931e6b36ac39bed106ce09 Mon Sep 17 00:00:00 2001 From: Duncan Laurie Date: Tue, 23 Oct 2012 18:04:42 +0000 Subject: x86: Ignore memory >4GB when parsing Coreboot tables U-boot is unable to actually use that memory and it can cause problems with relocation if it tries to. Signed-off-by: Duncan Laurie Signed-off-by: Simon Glass --- arch/x86/cpu/coreboot/sdram.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'arch/x86/cpu/coreboot/sdram.c') diff --git a/arch/x86/cpu/coreboot/sdram.c b/arch/x86/cpu/coreboot/sdram.c index 93dccb83eff..5d3da9977c8 100644 --- a/arch/x86/cpu/coreboot/sdram.c +++ b/arch/x86/cpu/coreboot/sdram.c @@ -60,6 +60,10 @@ int dram_init_f(void) struct memrange *memrange = &lib_sysinfo.memrange[i]; unsigned long long end = memrange->base + memrange->size; + /* Ignore memory over 4GB, we can't use it. */ + if (memrange->base > 0xffffffff) + continue; + if (memrange->type == CB_MEM_RAM && end > ram_size) ram_size = end; } -- cgit v1.2.3 From 112a575e498fe0c6bfbb4dbe3266d83f48d46a99 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Mon, 3 Dec 2012 14:26:08 +0000 Subject: x86: Override calculate_relocation_address to use the e820 map Because calculate_relocation_address now uses the e820 map, it will be able to avoid addresses over 32 bits and regions that are at high addresses but not big enough for U-Boot. It also means we can remove the hack which limitted U-Boot's idea of the size of memory to less than 4GB. Also take into account the space needed for the heap and stack, so we avoid picking a very small region those areas might overlap with something it shouldn't. Signed-off-by: Gabe Black Signed-off-by: Simon Glass --- arch/x86/cpu/coreboot/sdram.c | 61 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 55 insertions(+), 6 deletions(-) (limited to 'arch/x86/cpu/coreboot/sdram.c') diff --git a/arch/x86/cpu/coreboot/sdram.c b/arch/x86/cpu/coreboot/sdram.c index 5d3da9977c8..76274cb88e3 100644 --- a/arch/x86/cpu/coreboot/sdram.c +++ b/arch/x86/cpu/coreboot/sdram.c @@ -27,8 +27,9 @@ #include #include #include -#include -#include +#include +#include +#include DECLARE_GLOBAL_DATA_PTR; @@ -51,6 +52,58 @@ unsigned install_e820_map(unsigned max_entries, struct e820entry *entries) return num_entries; } +/* + * This function looks for the highest region of memory lower than 4GB which + * has enough space for U-Boot where U-Boot is aligned on a page boundary. It + * overrides the default implementation found elsewhere which simply picks the + * end of ram, wherever that may be. The location of the stack, the relocation + * address, and how far U-Boot is moved by relocation are set in the global + * data structure. + */ +int calculate_relocation_address(void) +{ + const uint64_t uboot_size = (uintptr_t)&__bss_end - + (uintptr_t)&__text_start; + const uint64_t total_size = uboot_size + CONFIG_SYS_MALLOC_LEN + + CONFIG_SYS_STACK_SIZE; + uintptr_t dest_addr = 0; + int i; + + for (i = 0; i < lib_sysinfo.n_memranges; i++) { + struct memrange *memrange = &lib_sysinfo.memrange[i]; + /* Force U-Boot to relocate to a page aligned address. */ + uint64_t start = roundup(memrange->base, 1 << 12); + uint64_t end = memrange->base + memrange->size; + + /* Ignore non-memory regions. */ + if (memrange->type != CB_MEM_RAM) + continue; + + /* Filter memory over 4GB. */ + if (end > 0xffffffffULL) + end = 0x100000000ULL; + /* Skip this region if it's too small. */ + if (end - start < total_size) + continue; + + /* Use this address if it's the largest so far. */ + if (end - uboot_size > dest_addr) + dest_addr = end; + } + + /* If no suitable area was found, return an error. */ + if (!dest_addr) + return 1; + + dest_addr -= uboot_size; + dest_addr &= ~((1 << 12) - 1); + gd->relocaddr = dest_addr; + gd->reloc_off = dest_addr - (uintptr_t)&__text_start; + gd->start_addr_sp = dest_addr - CONFIG_SYS_MALLOC_LEN; + + return 0; +} + int dram_init_f(void) { int i; @@ -60,10 +113,6 @@ int dram_init_f(void) struct memrange *memrange = &lib_sysinfo.memrange[i]; unsigned long long end = memrange->base + memrange->size; - /* Ignore memory over 4GB, we can't use it. */ - if (memrange->base > 0xffffffff) - continue; - if (memrange->type == CB_MEM_RAM && end > ram_size) ram_size = end; } -- cgit v1.2.3