From e4fb6116495eafbeee5ea8ff7ea245eb5e96d012 Mon Sep 17 00:00:00 2001 From: Graeme Russ Date: Tue, 27 Nov 2012 15:38:35 +0000 Subject: x86: Forward declare gd_t So it can be used as a type in struct global_data and remove an ugly typecast Signed-off-by: Graeme Russ Signed-off-by: Simon Glass Acked-by: Marek Vasut --- arch/x86/lib/init_helpers.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/x86/lib/init_helpers.c') diff --git a/arch/x86/lib/init_helpers.c b/arch/x86/lib/init_helpers.c index 9ec34ff992..2f718d7c4a 100644 --- a/arch/x86/lib/init_helpers.c +++ b/arch/x86/lib/init_helpers.c @@ -126,7 +126,7 @@ int copy_gd_to_ram_f_r(void) * in-RAM copy of Global Data (calculate_relocation_address() * has already calculated the in-RAM location of the GDT) */ - ram_gd->gd_addr = (ulong)ram_gd; + ram_gd->gd_addr = ram_gd; init_gd(ram_gd, (u64 *)gd->gdt_addr); return 0; -- cgit v1.2.3 From 8d61625d6a73307857f80002949583105545dbbc Mon Sep 17 00:00:00 2001 From: Graeme Russ Date: Tue, 27 Nov 2012 15:38:36 +0000 Subject: x86: Put global data on the stack Putting global data on the stack simplifies the init process (and makes it slightly quicker). During the 'flash' stage of the init sequence, global data is in the CAR stack. After SDRAM is initialised, global data is copied from CAR to the SDRAM stack Signed-off-by: Graeme Russ Signed-off-by: Simon Glass --- arch/x86/cpu/cpu.c | 6 ---- arch/x86/cpu/start.S | 67 +++++++++++++++++++++++++++++++++---- arch/x86/include/asm/global_data.h | 1 - arch/x86/include/asm/init_helpers.h | 1 - arch/x86/include/asm/processor.h | 1 + arch/x86/lib/board.c | 2 +- arch/x86/lib/init_helpers.c | 37 +------------------- include/configs/coreboot.h | 5 ++- include/configs/eNET.h | 6 ---- 9 files changed, 65 insertions(+), 61 deletions(-) (limited to 'arch/x86/lib/init_helpers.c') diff --git a/arch/x86/cpu/cpu.c b/arch/x86/cpu/cpu.c index 67de6bcb38..9c2db9f21e 100644 --- a/arch/x86/cpu/cpu.c +++ b/arch/x86/cpu/cpu.c @@ -90,12 +90,6 @@ static void load_gdt(const u64 *boot_gdt, u16 num_entries) asm volatile("lgdtl %0\n" : : "m" (gdt)); } -void init_gd(gd_t *id, u64 *gdt_addr) -{ - id->gd_addr = id; - setup_gdt(id, gdt_addr); -} - void setup_gdt(gd_t *id, u64 *gdt_addr) { /* CS: code, read/execute, 4 GB, base 0 */ diff --git a/arch/x86/cpu/start.S b/arch/x86/cpu/start.S index ee0dabe4bc..ec12e8044f 100644 --- a/arch/x86/cpu/start.S +++ b/arch/x86/cpu/start.S @@ -83,13 +83,33 @@ car_init_ret: * or fully initialised SDRAM - we really don't care which) * starting at CONFIG_SYS_CAR_ADDR to be used as a temporary stack */ - movl $CONFIG_SYS_INIT_SP_ADDR, %esp - /* Initialise the Global Data Pointer */ - movl $CONFIG_SYS_INIT_GD_ADDR, %eax - movl %eax, %edx - addl $GENERATED_GBL_DATA_SIZE, %edx - call init_gd; + /* Stack grows down from top of CAR */ + movl $(CONFIG_SYS_CAR_ADDR + CONFIG_SYS_CAR_SIZE), %esp + + /* Reserve space on stack for global data */ + subl $GENERATED_GBL_DATA_SIZE, %esp + + /* Align global data to 16-byte boundary */ + andl $0xfffffff0, %esp + + /* Setup first parameter to setup_gdt */ + movl %esp, %eax + + /* Reserve space for global descriptor table */ + subl $X86_GDT_SIZE, %esp + + /* Align temporary global descriptor table to 16-byte boundary */ + andl $0xfffffff0, %esp + + /* Set second parameter to setup_gdt */ + movl %esp, %edx + + /* gd->gd_addr = gd (Required to allow gd->xyz to work) */ + movl %eax, (%eax) + + /* Setup global descriptor table so gd->xyz works */ + call setup_gdt /* Set parameter to board_init_f() to boot flags */ xorl %eax, %eax @@ -113,9 +133,42 @@ board_init_f_r_trampoline: * %eax = Address of top of new stack */ - /* Setup stack in RAM */ + /* Stack grows down from top of SDRAM */ movl %eax, %esp + /* Reserve space on stack for global data */ + subl $GENERATED_GBL_DATA_SIZE, %esp + + /* Align global data to 16-byte boundary */ + andl $0xfffffff0, %esp + + /* Setup first parameter to memcpy (and setup_gdt) */ + movl %esp, %eax + + /* Setup second parameter to memcpy */ + fs movl 0, %edx + + /* Set third parameter to memcpy */ + movl $GENERATED_GBL_DATA_SIZE, %ecx + + /* Copy global data from CAR to SDRAM stack */ + call memcpy + + /* Reserve space for global descriptor table */ + subl $X86_GDT_SIZE, %esp + + /* Align global descriptor table to 16-byte boundary */ + andl $0xfffffff0, %esp + + /* Set second parameter to setup_gdt */ + movl %esp, %edx + + /* gd->gd_addr = gd (Required to allow gd->xyz to work) */ + movl %eax, (%eax) + + /* Setup global descriptor table so gd->xyz works */ + call setup_gdt + /* Re-enter U-Boot by calling board_init_f_r */ call board_init_f_r diff --git a/arch/x86/include/asm/global_data.h b/arch/x86/include/asm/global_data.h index 13a3ce8fbf..59c2a9095b 100644 --- a/arch/x86/include/asm/global_data.h +++ b/arch/x86/include/asm/global_data.h @@ -54,7 +54,6 @@ struct global_data { unsigned long relocaddr; /* Start address of U-Boot in RAM */ unsigned long start_addr_sp; /* start_addr_stackpointer */ unsigned long gdt_addr; /* Location of GDT */ - unsigned long new_gd_addr; /* New location of Global Data */ phys_size_t ram_size; /* RAM size */ unsigned long reset_status; /* reset status register at boot */ void **jt; /* jump table */ diff --git a/arch/x86/include/asm/init_helpers.h b/arch/x86/include/asm/init_helpers.h index 8afb443290..ade694fba3 100644 --- a/arch/x86/include/asm/init_helpers.h +++ b/arch/x86/include/asm/init_helpers.h @@ -29,7 +29,6 @@ int display_dram_config(void); int init_baudrate_f(void); int calculate_relocation_address(void); -int copy_gd_to_ram_f_r(void); int init_cache_f_r(void); int set_reloc_flag_r(void); diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index 6eb518063b..17f27cbb68 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h @@ -41,6 +41,7 @@ enum { #else /* NOTE: If the above enum is modified, this define must be checked */ #define X86_GDT_ENTRY_32BIT_DS 3 +#define X86_GDT_NUM_ENTRIES 7 #endif #define X86_GDT_SIZE (X86_GDT_NUM_ENTRIES * X86_GDT_ENTRY_SIZE) diff --git a/arch/x86/lib/board.c b/arch/x86/lib/board.c index e5caf13561..a13f5c0e10 100644 --- a/arch/x86/lib/board.c +++ b/arch/x86/lib/board.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include @@ -121,7 +122,6 @@ init_fnc_t *init_sequence_f[] = { * initialise the CPU caches (to speed up the relocation process) */ init_fnc_t *init_sequence_f_r[] = { - copy_gd_to_ram_f_r, init_cache_f_r, copy_uboot_to_ram, clear_bss, diff --git a/arch/x86/lib/init_helpers.c b/arch/x86/lib/init_helpers.c index 2f718d7c4a..87c7263fcb 100644 --- a/arch/x86/lib/init_helpers.c +++ b/arch/x86/lib/init_helpers.c @@ -83,18 +83,8 @@ int calculate_relocation_address(void) * requirements */ - /* Global Data is at top of available memory */ + /* Stack is at top of available memory */ dest_addr = gd->ram_size; - dest_addr -= GENERATED_GBL_DATA_SIZE; - dest_addr &= ~15; - gd->new_gd_addr = dest_addr; - - /* GDT is below Global Data */ - dest_addr -= X86_GDT_SIZE; - dest_addr &= ~15; - gd->gdt_addr = dest_addr; - - /* Stack is below GDT */ gd->start_addr_sp = dest_addr; /* U-Boot is below the stack */ @@ -107,31 +97,6 @@ int calculate_relocation_address(void) return 0; } -int copy_gd_to_ram_f_r(void) -{ - gd_t *ram_gd; - - /* - * Global data is still in temporary memory (the CPU cache). - * calculate_relocation_address() has set gd->new_gd_addr to - * where the global data lives in RAM but getting it there - * safely is a bit tricky due to the 'F-Segment Hack' that - * we need to use for x86 - */ - ram_gd = (gd_t *)gd->new_gd_addr; - memcpy((void *)ram_gd, gd, sizeof(gd_t)); - - /* - * Reload the Global Descriptor Table so FS points to the - * in-RAM copy of Global Data (calculate_relocation_address() - * has already calculated the in-RAM location of the GDT) - */ - ram_gd->gd_addr = ram_gd; - init_gd(ram_gd, (u64 *)gd->gdt_addr); - - return 0; -} - int init_cache_f_r(void) { /* Initialise the CPU cache(s) */ diff --git a/include/configs/coreboot.h b/include/configs/coreboot.h index cc95e2be98..8d3c21f05d 100644 --- a/include/configs/coreboot.h +++ b/include/configs/coreboot.h @@ -210,12 +210,11 @@ * (128kB + Environment Sector Size) malloc pool */ #define CONFIG_SYS_STACK_SIZE (32 * 1024) -#define CONFIG_SYS_INIT_SP_ADDR (256 * 1024 + 16 * 1024) +#define CONFIG_SYS_CAR_ADDR 0x19200000 +#define CONFIG_SYS_CAR_SIZE (16 * 1024) #define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE #define CONFIG_SYS_MONITOR_LEN (256 * 1024) #define CONFIG_SYS_MALLOC_LEN (0x20000 + 128 * 1024) -/* Address of temporary Global Data */ -#define CONFIG_SYS_INIT_GD_ADDR (256 * 1024) /* allow to overwrite serial and ethaddr */ diff --git a/include/configs/eNET.h b/include/configs/eNET.h index 4b1c21904c..28cf95b778 100644 --- a/include/configs/eNET.h +++ b/include/configs/eNET.h @@ -168,16 +168,10 @@ #define CONFIG_SYS_STACK_SIZE (32 * 1024) #define CONFIG_SYS_CAR_ADDR 0x19200000 #define CONFIG_SYS_CAR_SIZE (16 * 1024) -#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_CAR_ADDR + \ - CONFIG_SYS_CAR_SIZE) #define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE #define CONFIG_SYS_MONITOR_LEN (256 * 1024) #define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SECT_SIZE + \ 128*1024) -/* Address of temporary Global Data */ -#define CONFIG_SYS_INIT_GD_ADDR CONFIG_SYS_CAR_ADDR - - /* allow to overwrite serial and ethaddr */ #define CONFIG_ENV_OVERWRITE -- cgit v1.2.3 From 8313315b9ab3a130784a2a7d0c4f329808690c0b Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sat, 3 Nov 2012 11:41:23 +0000 Subject: x86: Initialise SPI if enabled If we have SPI support, make sure that we init it. Signed-off-by: Gabe Black Signed-off-by: Simon Glass Signed-off-by: Vic Yang --- arch/x86/include/asm/init_helpers.h | 1 + arch/x86/lib/board.c | 3 +++ arch/x86/lib/init_helpers.c | 9 +++++++++ 3 files changed, 13 insertions(+) (limited to 'arch/x86/lib/init_helpers.c') diff --git a/arch/x86/include/asm/init_helpers.h b/arch/x86/include/asm/init_helpers.h index ade694fba3..2f437e0343 100644 --- a/arch/x86/include/asm/init_helpers.h +++ b/arch/x86/include/asm/init_helpers.h @@ -37,5 +37,6 @@ int init_bd_struct_r(void); int flash_init_r(void); int status_led_set_r(void); int set_load_addr_r(void); +int init_func_spi(void); #endif /* !_INIT_HELPERS_H_ */ diff --git a/arch/x86/lib/board.c b/arch/x86/lib/board.c index c7d89604ca..2ffe0614dc 100644 --- a/arch/x86/lib/board.c +++ b/arch/x86/lib/board.c @@ -153,6 +153,9 @@ init_fnc_t *init_sequence_r[] = { serial_initialize_r, #ifndef CONFIG_SYS_NO_FLASH flash_init_r, +#endif +#ifdef CONFIG_SPI + init_func_spi; #endif env_relocate_r, #ifdef CONFIG_PCI diff --git a/arch/x86/lib/init_helpers.c b/arch/x86/lib/init_helpers.c index 87c7263fcb..d10a846cfd 100644 --- a/arch/x86/lib/init_helpers.c +++ b/arch/x86/lib/init_helpers.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -160,3 +161,11 @@ int set_load_addr_r(void) return 0; } + +int init_func_spi(void) +{ + puts("SPI: "); + spi_init(); + puts("ready\n"); + return 0; +} -- cgit v1.2.3 From 32f98735f9ada2bcfb114088f6226be8a22943fa Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sat, 3 Nov 2012 11:41:24 +0000 Subject: x86: Reorder x86's post relocation memory layout This changes the layout in decreasing addresses from: 1. Stack 2. Sections in the image 3. Heap to 1. Sections in the image 2. Heap 3. Stack This allows the stack to grow significantly more since it isn't constrained by the other u-boot areas. More importantly, the generic memory wipe code assumes that the stack is the lowest addressed area used by the main part of u-boot. In the original layout, that means that u-boot tramples all over itself. In the new layout, it works. Signed-off-by: Gabe Black Signed-off-by: Simon Glass --- arch/x86/lib/init_helpers.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'arch/x86/lib/init_helpers.c') diff --git a/arch/x86/lib/init_helpers.c b/arch/x86/lib/init_helpers.c index d10a846cfd..9fd87dfd2e 100644 --- a/arch/x86/lib/init_helpers.c +++ b/arch/x86/lib/init_helpers.c @@ -86,15 +86,16 @@ int calculate_relocation_address(void) /* Stack is at top of available memory */ dest_addr = gd->ram_size; - gd->start_addr_sp = dest_addr; - /* U-Boot is below the stack */ - dest_addr -= CONFIG_SYS_STACK_SIZE; + /* U-Boot is at the top */ dest_addr -= (bss_end - text_start); dest_addr &= ~15; gd->relocaddr = dest_addr; gd->reloc_off = (dest_addr - text_start); + /* Stack is at the bottom, so it can grow down */ + gd->start_addr_sp = dest_addr - CONFIG_SYS_MALLOC_LEN; + return 0; } -- cgit v1.2.3 From d65297b64d743105b18d912fa62627d6bf468c2f Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sat, 3 Nov 2012 11:41:26 +0000 Subject: x86: Make calculate_relocation_address an overridable function Different systems may have different mechanisms for picking a suitable place to relocate U-Boot to. Signed-off-by: Gabe Black Signed-off-by: Simon Glass --- arch/x86/lib/init_helpers.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch/x86/lib/init_helpers.c') diff --git a/arch/x86/lib/init_helpers.c b/arch/x86/lib/init_helpers.c index 9fd87dfd2e..3a62b2ea06 100644 --- a/arch/x86/lib/init_helpers.c +++ b/arch/x86/lib/init_helpers.c @@ -32,6 +32,7 @@ #include #include #include +#include #include @@ -72,7 +73,7 @@ int init_baudrate_f(void) return 0; } -int calculate_relocation_address(void) +__weak int calculate_relocation_address(void) { ulong text_start = (ulong)&__text_start; ulong bss_end = (ulong)&__bss_end; -- cgit v1.2.3 From b208c7f1d05c304e0dd27b7278ffb00e4af8e26e Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sat, 3 Nov 2012 11:41:30 +0000 Subject: x86: Add support for CONFIG_OF_CONTROL Allow a device tree to be provided through the standard mechanisms. Signed-off-by: Gabe Black Signed-off-by: Simon Glass --- arch/x86/lib/board.c | 7 +++++++ arch/x86/lib/init_helpers.c | 29 +++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) (limited to 'arch/x86/lib/init_helpers.c') diff --git a/arch/x86/lib/board.c b/arch/x86/lib/board.c index 2ffe0614dc..22bc26dde9 100644 --- a/arch/x86/lib/board.c +++ b/arch/x86/lib/board.c @@ -99,10 +99,17 @@ typedef int (init_fnc_t) (void); init_fnc_t *init_sequence_f[] = { cpu_init_f, board_early_init_f, +#ifdef CONFIG_OF_CONTROL + find_fdt, + fdtdec_check_fdt, +#endif env_init, init_baudrate_f, serial_init, console_init_f, +#ifdef CONFIG_OF_CONTROL + prepare_fdt, +#endif dram_init_f, calculate_relocation_address, diff --git a/arch/x86/lib/init_helpers.c b/arch/x86/lib/init_helpers.c index 3a62b2ea06..3eec9a61d6 100644 --- a/arch/x86/lib/init_helpers.c +++ b/arch/x86/lib/init_helpers.c @@ -171,3 +171,32 @@ int init_func_spi(void) puts("ready\n"); return 0; } + +#ifdef CONFIG_OF_CONTROL +int find_fdt(void) +{ +#ifdef CONFIG_OF_EMBED + /* Get a pointer to the FDT */ + gd->fdt_blob = _binary_dt_dtb_start; +#elif defined CONFIG_OF_SEPARATE + /* FDT is at end of image */ + gd->fdt_blob = (void *)(_end_ofs + _TEXT_BASE); +#endif + /* Allow the early environment to override the fdt address */ + gd->fdt_blob = (void *)getenv_ulong("fdtcontroladdr", 16, + (uintptr_t)gd->fdt_blob); + + return 0; +} + +int prepare_fdt(void) +{ + /* For now, put this check after the console is ready */ + if (fdtdec_prepare_fdt()) { + panic("** CONFIG_OF_CONTROL defined but no FDT - please see " + "doc/README.fdt-control"); + } + + return 0; +} +#endif -- cgit v1.2.3