]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
x86: fsp: Move FspInitEntry call to board_init_f()
authorBin Meng <bmeng.cn@gmail.com>
Sun, 7 Jun 2015 03:33:14 +0000 (11:33 +0800)
committerSimon Glass <sjg@chromium.org>
Wed, 15 Jul 2015 00:03:15 +0000 (18:03 -0600)
The call to FspInitEntry is done in arch/x86/lib/fsp/fsp_car.S so far.
It worked pretty well but looks not that good. Apart from doing too
much work than just enabling CAR, it cannot read the configuration
data from device tree at that time. Now we want to move it a little
bit later as part of init_sequence_f[] being called by board_init_f().
This way it looks and works better in the U-Boot initialization path.

Due to FSP's design, after calling FspInitEntry it will not return to
its caller, instead it jumps to a continuation function which is given
by bootloader with a new stack in system memory. The original stack in
the CAR is gone, but its content is perserved by FSP and described by
a bootloader temporary memory HOB. Technically we can recover anything
we had before in the previous stack, but that is way too complicated.
To make life much easier, in the FSP continuation routine we just
simply call fsp_init_done() and jump back to car_init_ret() to redo
the whole board_init_f() initialization, but this time with a non-zero
HOB list pointer saved in U-Boot's global data so that we can bypass
the FspInitEntry for the second time.

Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
Acked-by: Simon Glass <sjg@chromium.org>
Tested-by: Andrew Bradford <andrew.bradford@kodakalaris.com>
Tested-by: Simon Glass <sjg@chromium.org>
arch/x86/cpu/start.S
arch/x86/include/asm/u-boot-x86.h
arch/x86/lib/fsp/fsp_car.S
arch/x86/lib/fsp/fsp_common.c
common/board_f.c

index 2e5f9da75673c55397d58ec18d858f5fa1c34a4a..00e585e19bfccdd4e0465c9575b98d137fc811b4 100644 (file)
@@ -116,12 +116,16 @@ car_init_ret:
        rep     stosb
 
 #ifdef CONFIG_HAVE_FSP
+       test    %esi, %esi
+       jz      skip_hob
+
        /* Store HOB list */
        movl    %esp, %edx
        addl    $GD_HOB_LIST, %edx
        movl    %esi, (%edx)
-#endif
 
+skip_hob:
+#endif
        /* Setup first parameter to setup_gdt, pointer to global_data */
        movl    %esp, %eax
 
index 3c6ee2914bc337a0355257144028f6233c6249e0..4dae365a1233bcf2cb3804ba3f8cedcf05b26f36 100644 (file)
@@ -56,6 +56,9 @@ u32 isa_map_rom(u32 bus_addr, int size);
 /* arch/x86/lib/... */
 int video_bios_init(void);
 
+/* arch/x86/lib/fsp/... */
+int x86_fsp_init(void);
+
 void   board_init_f_r_trampoline(ulong) __attribute__ ((noreturn));
 void   board_init_f_r(void) __attribute__ ((noreturn));
 
index 5e09568b85be46bbf5d3b534397e19012b9f4cf2..afbf3f9baae19f059f06b5338ead3209b730b850 100644 (file)
@@ -56,28 +56,10 @@ temp_ram_init_ret:
 
        /* stack grows down from top of CAR */
        movl    %edx, %esp
+       subl    $4, %esp
 
-       /*
-        * TODO:
-        *
-        * According to FSP architecture spec, the fsp_init() will not return
-        * to its caller, instead it requires the bootloader to provide a
-        * so-called continuation function to pass into the FSP as a parameter
-        * of fsp_init, and fsp_init() will call that continuation function
-        * directly.
-        *
-        * The call to fsp_init() may need to be moved out of the car_init()
-        * to cpu_init_f() with the help of some inline assembly codes.
-        * Note there is another issue that fsp_init() will setup another stack
-        * using the fsp_init parameter stack_top after DRAM is initialized,
-        * which means any data on the previous stack (on the CAR) gets lost
-        * (ie: U-Boot global_data). FSP is supposed to support such scenario,
-        * however it does not work. This should be revisited in the future.
-        */
-       movl    $CONFIG_FSP_TEMP_RAM_ADDR, %eax
-       xorl    %edx, %edx
-       xorl    %ecx, %ecx
-       call    fsp_init
+       xor     %esi, %esi
+       jmp     car_init_done
 
 .global fsp_init_done
 fsp_init_done:
@@ -86,6 +68,8 @@ fsp_init_done:
         * Save eax to esi temporarily.
         */
        movl    %eax, %esi
+
+car_init_done:
        /*
         * Re-initialize the ebp (BIST) to zero, as we already reach here
         * which means we passed BIST testing before.
index 001494d97dce65e241b2f6266b1c0ffe736e9ab0..5b256324e1721c546ca058eb83468060274feaae 100644 (file)
@@ -46,3 +46,11 @@ void board_final_cleanup(void)
 
        return;
 }
+
+int x86_fsp_init(void)
+{
+       if (!gd->arch.hob_list)
+               fsp_init(CONFIG_FSP_TEMP_RAM_ADDR, BOOT_FULL_CONFIG, NULL);
+
+       return 0;
+}
index fbbad1bcb99c53e4626847e23d137262b43e1586..21be26f8e4051289b78de72933688ecd8d39135e 100644 (file)
@@ -753,6 +753,9 @@ static init_fnc_t init_sequence_f[] = {
 #ifdef CONFIG_OF_CONTROL
        fdtdec_setup,
 #endif
+#if defined(CONFIG_X86) && defined(CONFIG_HAVE_FSP)
+       x86_fsp_init,
+#endif
 #ifdef CONFIG_TRACE
        trace_early_init,
 #endif