u-boot/arch/x86/lib/fsp/fsp_car.S
Simon Glass 7b02bf3c7d x86: Make CAR and DRAM FSP code common
For now this code seems to be the same for all FSP platforms. Make it
common until we see what differences are required.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Tested-by: Bin Meng <bmeng.cn@gmail.com>
2015-02-05 22:16:44 -07:00

124 lines
3.2 KiB
ArmAsm

/*
* Copyright (C) 2014, Bin Meng <bmeng.cn@gmail.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <config.h>
#include <asm/post.h>
.globl car_init
car_init:
/*
* Note: ebp holds the BIST value (built-in self test) so far, but ebp
* will be destroyed through the FSP call, thus we have to test the
* BIST value here before we call into FSP.
*/
test %ebp, %ebp
jz car_init_start
post_code(POST_BIST_FAILURE)
jmp die
car_init_start:
post_code(POST_CAR_START)
lea find_fsp_header_romstack, %esp
jmp find_fsp_header
find_fsp_header_ret:
/* EAX points to FSP_INFO_HEADER */
mov %eax, %ebp
/* sanity test */
cmp $CONFIG_FSP_ADDR, %eax
jb die
/* calculate TempRamInitEntry address */
mov 0x30(%ebp), %eax
add 0x1c(%ebp), %eax
/* call FSP TempRamInitEntry to setup temporary stack */
lea temp_ram_init_romstack, %esp
jmp *%eax
temp_ram_init_ret:
addl $4, %esp
cmp $0, %eax
jnz car_init_fail
post_code(POST_CAR_CPU_CACHE)
/*
* The FSP TempRamInit initializes the ecx and edx registers to
* point to a temporary but writable memory range (Cache-As-RAM).
* ecx: the start of this temporary memory range,
* edx: the end of this range.
*/
/* stack grows down from top of CAR */
movl %edx, %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
.global fsp_init_done
fsp_init_done:
/*
* We come here from FspInit with eax pointing to the HOB list.
* Save eax to esi temporarily.
*/
movl %eax, %esi
/*
* Re-initialize the ebp (BIST) to zero, as we already reach here
* which means we passed BIST testing before.
*/
xorl %ebp, %ebp
jmp car_init_ret
car_init_fail:
post_code(POST_CAR_FAILURE)
die:
hlt
jmp die
hlt
/*
* The function call before CAR initialization is tricky. It cannot
* be called using the 'call' instruction but only the 'jmp' with
* the help of a handcrafted stack in the ROM. The stack needs to
* contain the function return address as well as the parameters.
*/
.balign 4
find_fsp_header_romstack:
.long find_fsp_header_ret
.balign 4
temp_ram_init_romstack:
.long temp_ram_init_ret
.long temp_ram_init_params
temp_ram_init_params:
_dt_ucode_base_size:
/* These next two fields are filled in by ifdtool */
.long 0 /* microcode base */
.long 0 /* microcode size */
.long CONFIG_SYS_MONITOR_BASE /* code region base */
.long CONFIG_SYS_MONITOR_LEN /* code region size */