@ -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 4 GB 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 ;
}