[U-Boot] [PATCH 43/48] x86: Handle running as EFI payload
Simon Glass
sjg at chromium.org
Fri Jul 31 17:45:48 CEST 2015
Hi Bin,
On 24 July 2015 at 02:58, Bin Meng <bmeng.cn at gmail.com> wrote:
> Hi Simon,
>
> On Wed, Jul 22, 2015 at 11:49 PM, Simon Glass <sjg at chromium.org> wrote:
>> When U-Boot runs as an EFI payload it needs to avoid setting up the CPU
>> again. Also U-Boot currently does not handle interrupts for many devices, so
>> run with interrupts disabled.
>>
>> Signed-off-by: Simon Glass <sjg at chromium.org>
>> ---
>>
>> arch/x86/Kconfig | 16 ++++++++++++++++
>> arch/x86/cpu/cpu.c | 21 +++++++++++++--------
>> arch/x86/cpu/interrupts.c | 10 ++++++++--
>> arch/x86/lib/bootm.c | 2 ++
>> 4 files changed, 39 insertions(+), 10 deletions(-)
>>
>> diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
>> index f124d58..c64c626 100644
>> --- a/arch/x86/Kconfig
>> +++ b/arch/x86/Kconfig
>> @@ -194,6 +194,7 @@ config X86_RAMTEST
>>
>> config HAVE_FSP
>> bool "Add an Firmware Support Package binary"
>> + depends on !EFI
>> help
>> Select this option to add an Firmware Support Package binary to
>> the resulting U-Boot image. It is a binary blob which U-Boot uses
>> @@ -309,6 +310,7 @@ menu "System tables"
>>
>> config GENERATE_PIRQ_TABLE
>> bool "Generate a PIRQ table"
>> + depends on !EFI
>> default n
>> help
>> Generate a PIRQ routing table for this board. The PIRQ routing table
>> @@ -319,6 +321,7 @@ config GENERATE_PIRQ_TABLE
>>
>> config GENERATE_SFI_TABLE
>> bool "Generate a SFI (Simple Firmware Interface) table"
>> + depends on !EFI
>> help
>> The Simple Firmware Interface (SFI) provides a lightweight method
>> for platform firmware to pass information to the operating system
>> @@ -333,6 +336,7 @@ config GENERATE_SFI_TABLE
>>
>> config GENERATE_MP_TABLE
>> bool "Generate an MP (Multi-Processor) table"
>> + depends on !EFI
>> default n
>> help
>> Generate an MP (Multi-Processor) table for this board. The MP table
>> @@ -383,4 +387,16 @@ config PCIE_ECAM_SIZE
>> so a default 0x10000000 size covers all of the 256 buses which is the
>> maximum number of PCI buses as defined by the PCI specification.
>>
>> +if EFI
>> +
>> +config SYS_CAR_ADDR
>> + hex
>> + default 0x100000
>> +
>> +config SYS_CAR_SIZE
>> + hex
>> + default 0x20000
>> +
>> +endif
>
> Can we move this to arch/x86/cpu/efi/Kconfig?
That's for the application (i.e. the 'cpu' is EFI). These options are
actually needed for the payload. I'll move them to
arch/x86/lib/efi/Kconfig since it is reasonable to include that for
all x86 boards.
>
>> +
>> endmenu
>> diff --git a/arch/x86/cpu/cpu.c b/arch/x86/cpu/cpu.c
>> index d233a45..129777c 100644
>> --- a/arch/x86/cpu/cpu.c
>> +++ b/arch/x86/cpu/cpu.c
>> @@ -330,13 +330,15 @@ int x86_cpu_init_f(void)
>> const u32 em_rst = ~X86_CR0_EM;
>> const u32 mp_ne_set = X86_CR0_MP | X86_CR0_NE;
>>
>> - /* initialize FPU, reset EM, set MP and NE */
>> - asm ("fninit\n" \
>> - "movl %%cr0, %%eax\n" \
>> - "andl %0, %%eax\n" \
>> - "orl %1, %%eax\n" \
>> - "movl %%eax, %%cr0\n" \
>> - : : "i" (em_rst), "i" (mp_ne_set) : "eax");
>> + if (ll_boot_init()) {
>> + /* initialize FPU, reset EM, set MP and NE */
>> + asm ("fninit\n" \
>> + "movl %%cr0, %%eax\n" \
>> + "andl %0, %%eax\n" \
>> + "orl %1, %%eax\n" \
>> + "movl %%eax, %%cr0\n" \
>> + : : "i" (em_rst), "i" (mp_ne_set) : "eax");
>> + }
>>
>> /* identify CPU via cpuid and store the decoded info into gd->arch */
>> if (has_cpuid()) {
>> @@ -712,5 +714,8 @@ __weak int x86_init_cpus(void)
>>
>> int cpu_init_r(void)
>> {
>> - return x86_init_cpus();
>> + if (ll_boot_init())
>> + return x86_init_cpus();
>> +
>> + return 0;
>> }
>> diff --git a/arch/x86/cpu/interrupts.c b/arch/x86/cpu/interrupts.c
>> index a86c673..7df50bd 100644
>> --- a/arch/x86/cpu/interrupts.c
>> +++ b/arch/x86/cpu/interrupts.c
>> @@ -254,8 +254,14 @@ int interrupt_init(void)
>> /* Initialize core interrupt and exception functionality of CPU */
>> cpu_init_interrupts();
>>
>> - /* It is now safe to enable interrupts */
>> - enable_interrupts();
>> + /*
>> + * It is now safe to enable interrupts.
>> + *
>> + * TODO(sjg at chromium.org): But we don't handle these correctly when
>> + * booted from EFI.
>> + */
>> + if (ll_boot_init())
>> + enable_interrupts();
>> #endif
>>
>> return 0;
>> diff --git a/arch/x86/lib/bootm.c b/arch/x86/lib/bootm.c
>> index 445ee6e..3ad941f 100644
>> --- a/arch/x86/lib/bootm.c
>> +++ b/arch/x86/lib/bootm.c
>> @@ -165,6 +165,7 @@ int boot_linux_kernel(ulong setup_base, ulong load_address, bool image_64bit)
>> * U-boot is setting them up that way for itself in
>> * arch/i386/cpu/cpu.c.
>> */
>> +#ifndef CONFIG_ARCH_EFI
>
> Does this mean EFI application cannot load a Linux kernel?
Yes. I'll add a comment. It would actually be possible to implement
this, but it is not done yet.
>
>> __asm__ __volatile__ (
>> "movl $0, %%ebp\n"
>> "cli\n"
>> @@ -173,6 +174,7 @@ int boot_linux_kernel(ulong setup_base, ulong load_address, bool image_64bit)
>> [boot_params] "S"(setup_base),
>> "b"(0), "D"(0)
>> );
>> +#endif
>> }
>>
>> /* We can't get to here */
>> --
>
> Regards,
> Bin
Regards,
Simon
More information about the U-Boot
mailing list