[U-Boot] [PATCH v2 2/3] x86: fsp: Load GDT before calling FspInitEntry
Simon Glass
sjg at chromium.org
Fri Jun 5 17:34:14 CEST 2015
Hi Bin,
On 4 June 2015 at 04:28, Bin Meng <bmeng.cn at gmail.com> wrote:
> Currently the FSP execution environment GDT is setup by U-Boot in
> arch/x86/cpu/start16.S, which works pretty well. But if we try to
> move the FspInitEntry call a little bit later to better fit into
> U-Boot's initialization sequence, FSP will fail to bring up the AP
> due to #GP fault as AP's GDT is duplicated from BSP whose GDT is
> now moved into CAR, and unfortunately FSP calls AP initialization
> after it disables the CAR. So basically the BSP's GDT still refers
> to the one in the CAR, whose content is no longer available, so
> when AP starts up and loads its segment register, it blows up.
>
> To resolve this, we load GDT before calling into FspInitEntry.
> The GDT is the same one used in arch/x86/cpu/start16.S, which is
> in the ROM and exists forever.
>
> Signed-off-by: Bin Meng <bmeng.cn at gmail.com>
Tested on Minnowboard MAX:
Tested-by: Simon Glass <sjg at chromium.org>
>
> ---
>
> Changes in v2:
> - Use CONFIG_RESET_SEG_START to avoid duplication
>
> arch/x86/cpu/cpu.c | 20 ++++++++++++++++++++
> arch/x86/cpu/start16.S | 1 +
> arch/x86/include/asm/u-boot-x86.h | 3 +++
> arch/x86/lib/fsp/fsp_support.c | 3 +++
> 4 files changed, 27 insertions(+)
>
> diff --git a/arch/x86/cpu/cpu.c b/arch/x86/cpu/cpu.c
> index bb4a110..f4ebc97 100644
> --- a/arch/x86/cpu/cpu.c
> +++ b/arch/x86/cpu/cpu.c
> @@ -164,6 +164,26 @@ void setup_gdt(gd_t *id, u64 *gdt_addr)
> load_fs(X86_GDT_ENTRY_32BIT_FS);
> }
>
> +#ifdef CONFIG_HAVE_FSP
> +/*
> + * Setup FSP execution environment GDT
> + *
> + * Per Intel FSP external architecture specification, before calling any FSP
> + * APIs, we need make sure the system is in flat 32-bit mode and both the code
> + * and data selectors should have full 4GB access range. Here we reuse the one
> + * we used in arch/x86/cpu/start16.S, and reload the segement registers.
> + */
> +void setup_fsp_gdt(void)
> +{
> + load_gdt((const u64 *)((u32)&gdt + CONFIG_RESET_SEG_START), 4);
> + load_ds(X86_GDT_ENTRY_32BIT_DS);
> + load_ss(X86_GDT_ENTRY_32BIT_DS);
> + load_es(X86_GDT_ENTRY_32BIT_DS);
> + load_fs(X86_GDT_ENTRY_32BIT_DS);
> + load_gs(X86_GDT_ENTRY_32BIT_DS);
> +}
> +#endif
> +
> int __weak x86_cleanup_before_linux(void)
> {
> #ifdef CONFIG_BOOTSTAGE_STASH
> diff --git a/arch/x86/cpu/start16.S b/arch/x86/cpu/start16.S
> index 826e2b4..a3e7ab4 100644
> --- a/arch/x86/cpu/start16.S
> +++ b/arch/x86/cpu/start16.S
> @@ -75,6 +75,7 @@ gdt_ptr:
>
> /* Some CPUs are picky about GDT alignment... */
> .align 16
> +.globl gdt
> gdt:
Could we rename this to gdt_initial or something like that? To me, gdt
is a bit vague for an exported symbol. We need to use a name that
indicates it is only used at the start.
> /*
> * The GDT table ...
> diff --git a/arch/x86/include/asm/u-boot-x86.h b/arch/x86/include/asm/u-boot-x86.h
> index d1d21ed..67c0098 100644
> --- a/arch/x86/include/asm/u-boot-x86.h
> +++ b/arch/x86/include/asm/u-boot-x86.h
> @@ -8,12 +8,15 @@
> #ifndef _U_BOOT_I386_H_
> #define _U_BOOT_I386_H_ 1
>
> +extern u32 gdt;
Perhaps this should be declared as char gdt[] so you don't need to
take its address later? See asm/linkage.h for how they do it.
> +
> /* cpu/.../cpu.c */
> int arch_cpu_init(void);
> int x86_cpu_init_f(void);
> int cpu_init_f(void);
> void init_gd(gd_t *id, u64 *gdt_addr);
> void setup_gdt(gd_t *id, u64 *gdt_addr);
> +void setup_fsp_gdt(void);
Please add function comment.
> int init_cache(void);
> int cleanup_before_linux(void);
>
> diff --git a/arch/x86/lib/fsp/fsp_support.c b/arch/x86/lib/fsp/fsp_support.c
> index 5809235..4585166 100644
> --- a/arch/x86/lib/fsp/fsp_support.c
> +++ b/arch/x86/lib/fsp/fsp_support.c
> @@ -173,6 +173,9 @@ void fsp_init(u32 stack_top, u32 boot_mode, void *nvs_buf)
>
> post_code(POST_PRE_MRC);
>
> + /* Load GDT for FSP */
> + setup_fsp_gdt();
> +
> /*
> * Use ASM code to ensure the register value in EAX & ECX
> * will be passed into BlContinuationFunc
> --
> 1.8.2.1
>
Regards,
Simon
More information about the U-Boot
mailing list