diff options
| author | Allen Martin <amartin@nvidia.com> | 2012-12-19 13:02:36 -0800 | 
|---|---|---|
| committer | Allen Martin <amartin@nvidia.com> | 2012-12-19 13:02:36 -0800 | 
| commit | a098cf41fdb2a6607c675f7fe4f3164617c9367e (patch) | |
| tree | b37acb36f65909e6f74cc537d73efd883a1485a6 /arch/x86/cpu/coreboot/sdram.c | |
| parent | b8a7c467960ffb4d5a5e1eef5f7783fb6f594542 (diff) | |
| parent | 095728803eedfce850a2f85828f79500cb09979e (diff) | |
| download | olio-uboot-2014.01-a098cf41fdb2a6607c675f7fe4f3164617c9367e.tar.xz olio-uboot-2014.01-a098cf41fdb2a6607c675f7fe4f3164617c9367e.zip | |
Merge remote-tracking branch 'u-boot/master' into u-boot-arm-merged
Conflicts:
	README
	arch/arm/cpu/armv7/exynos/clock.c
	board/samsung/universal_c210/universal.c
	drivers/misc/Makefile
	drivers/power/power_fsl.c
	include/configs/mx35pdk.h
	include/configs/mx53loco.h
	include/configs/seaboard.h
Diffstat (limited to 'arch/x86/cpu/coreboot/sdram.c')
| -rw-r--r-- | arch/x86/cpu/coreboot/sdram.c | 72 | 
1 files changed, 70 insertions, 2 deletions
| diff --git a/arch/x86/cpu/coreboot/sdram.c b/arch/x86/cpu/coreboot/sdram.c index f8fdac631..76274cb88 100644 --- a/arch/x86/cpu/coreboot/sdram.c +++ b/arch/x86/cpu/coreboot/sdram.c @@ -27,8 +27,9 @@  #include <asm/e820.h>  #include <asm/u-boot-x86.h>  #include <asm/global_data.h> -#include <asm/arch-coreboot/sysinfo.h> -#include <asm/arch-coreboot/tables.h> +#include <asm/processor.h> +#include <asm/arch/sysinfo.h> +#include <asm/arch/tables.h>  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; @@ -71,5 +124,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;  } |