[U-Boot] [PATCH v2 16/27] x86: Add basic support to queensbay platform and crownbay board
Simon Glass
sjg at chromium.org
Fri Dec 12 05:54:17 CET 2014
Hi Bin,
On 11 December 2014 at 21:49, Bin Meng <bmeng.cn at gmail.com> wrote:
> Hi Simon,
>
> On Fri, Dec 12, 2014 at 11:53 AM, Simon Glass <sjg at chromium.org> wrote:
>> Hi Bin,
>>
>
> [snip]
>
>>>>> diff --git a/arch/x86/cpu/queensbay/tnc_car.S b/arch/x86/cpu/queensbay/tnc_car.S
>>>>> new file mode 100644
>>>>> index 0000000..4f39e42
>>>>> --- /dev/null
>>>>> +++ b/arch/x86/cpu/queensbay/tnc_car.S
>>>>> @@ -0,0 +1,103 @@
>>>>> +/*
>>>>> + * Copyright (C) 2014, Bin Meng <bmeng.cn at 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_stack, %esp
>>>>> + jmp find_fsp_header
>>>>> +
>>>>> +find_fsp_header_ret:
>>>>> + /* EAX points to FSP_INFO_HEADER */
>>>>> + mov %eax, %ebp
>>>>> +
>>>>> + /* sanity test */
>>>>> + cmp $CONFIG_FSP_LOCATION, %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_stack, %esp
>>>>> + jmp *%eax
>>>>> +
>>>>> +temp_ram_init_ret:
>>>>> + addl $4, %esp
>>>>> + cmp $0, %eax
>>>>> + jz continue
>>>>
>>>> Can we make this jnz put the error code below instead of it being in
>>>> the normal path flow?
>>>
>>> Sure.
>>>
>>>>> + post_code(POST_CAR_FAILURE)
>>>>> +
>>>>> +die:
>>>>> + hlt
>>>>> + jmp die
>>>>> + hlt
>>>>> +
>>>>> +continue:
>>>>> + 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
>>>>> +
>>>>> + movl $CONFIG_FSP_TEMP_RAM_ADDR, %eax
>>>>> + xorl %edx, %edx
>>>>> + xorl %ecx, %ecx
>>>>> + call fsp_init
>>>>
>>>> Do we have to call fsp_init so early? Could we not call it from
>>>> cpu_init_f() or even later?
>>>
>>> Unfortunately yes. 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.
>>
>> But couldn't it be called from C with an assembler shim?
>>
>> My objective is to make the assembler code as short as possible and
>> call board_init_f() as soon as possible. So can we no call this later
>> in the init sequence?
>
> It may work from cpu_init_f() with an some inline assembly, but I am
> not sure and need do some experiments. Besides this, there is another
> issue that fsp_init() will setup another stack after the call using
> the fsp_init parameter stack_top, which means any data on the previous
> stack (on the CAR) gets lost (ie: global_data). I mentioned in one of
> the discussion thread before, that supposed FSP should support such
> scenario, however it does not work. I planned to look into this in the
> future. Perhaps we need leave this issue for now for this series. I
> will investigate it later. How do you think?
OK. Can you please add a TODO in the code and mention it in the commit
message also?
>
>>>
>>>>> +
>>>>> +.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
>>>>> +
>>>>> + .balign 4
>>>>> +find_fsp_header_stack:
>>>>> + .long find_fsp_header_ret
>>>>> +
>>>>> + .balign 4
>>>>> +temp_ram_init_stack:
>>>>
>>>> Can we use temp_ram_init_vars or similar? This name makes it look like
>>>> it is a temporary stack.
>>>
>>> Yes, it is indeed a temporary ROM stack.
>>
>> It's not writeable though, right? So in what sense it is a stack?
>
> It is the ROM stack of the fsp_tempram_init call. See the codes below:
>
> /* calculate TempRamInitEntry address */
> mov 0x30(%ebp), %eax
> add 0x1c(%ebp), %eax
>
> /* call FSP TempRamInitEntry to setup temporary stack */
> lea temp_ram_init_stack, %esp
> jmp *%eax
>
> It needs to have the return address and fsp_tempram_init parameters on
> the stack.
OK, so really it is just parameters to the function, but in a strange
way. One wonders why they didn't just use registers.
Anyway, I think the name should not be 'stack' as it is in ROM and so
cannot be written. To me that is confusing.
Regards,
Simon
More information about the U-Boot
mailing list