diff mbox

[U-Boot,25/48] x86: Add support for U-Boot as an EFI application

Message ID 1437580180-6405-26-git-send-email-sjg@chromium.org
State Superseded
Delegated to: Simon Glass
Headers show

Commit Message

Simon Glass July 22, 2015, 3:49 p.m. UTC
From: Ben Stoltz <stoltz@google.com>

Add the required x86 glue code. This includes the initial start-up,
relocation and jumping to efi_main(). We also need to avoid fiddling with
interrupts.

Signed-off-by: Ben Stoltz <stoltz@google.com>
Signed-off-by: Simon Glass <sjg@chromium.org>
---

 arch/x86/Kconfig                     |  3 ++
 arch/x86/Makefile                    |  2 +
 arch/x86/cpu/Makefile                |  1 +
 arch/x86/cpu/efi/Makefile            |  8 +++
 arch/x86/cpu/efi/efi.c               | 49 ++++++++++++++++++
 arch/x86/cpu/efi/elf_ia32_efi.lds    | 92 ++++++++++++++++++++++++++++++++++
 arch/x86/cpu/efi/sdram.c             | 29 +++++++++++
 arch/x86/cpu/interrupts.c            |  2 +
 arch/x86/include/asm/arch-efi/gpio.h | 10 ++++
 arch/x86/lib/Makefile                |  6 +++
 arch/x86/lib/crt0-efi-ia32.S         | 77 +++++++++++++++++++++++++++++
 arch/x86/lib/crt0-efi-x86_64.S       | 77 +++++++++++++++++++++++++++++
 arch/x86/lib/reloc_ia32.c            | 96 ++++++++++++++++++++++++++++++++++++
 13 files changed, 452 insertions(+)
 create mode 100644 arch/x86/cpu/efi/Makefile
 create mode 100644 arch/x86/cpu/efi/efi.c
 create mode 100644 arch/x86/cpu/efi/elf_ia32_efi.lds
 create mode 100644 arch/x86/cpu/efi/sdram.c
 create mode 100644 arch/x86/include/asm/arch-efi/gpio.h
 create mode 100644 arch/x86/lib/crt0-efi-ia32.S
 create mode 100644 arch/x86/lib/crt0-efi-x86_64.S
 create mode 100644 arch/x86/lib/reloc_ia32.c

Comments

Bin Meng July 23, 2015, 9:43 a.m. UTC | #1
Hi Simon,

On Wed, Jul 22, 2015 at 11:49 PM, Simon Glass <sjg@chromium.org> wrote:
> From: Ben Stoltz <stoltz@google.com>
>
> Add the required x86 glue code. This includes the initial start-up,
> relocation and jumping to efi_main(). We also need to avoid fiddling with
> interrupts.
>
> Signed-off-by: Ben Stoltz <stoltz@google.com>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
>  arch/x86/Kconfig                     |  3 ++
>  arch/x86/Makefile                    |  2 +
>  arch/x86/cpu/Makefile                |  1 +
>  arch/x86/cpu/efi/Makefile            |  8 +++
>  arch/x86/cpu/efi/efi.c               | 49 ++++++++++++++++++
>  arch/x86/cpu/efi/elf_ia32_efi.lds    | 92 ++++++++++++++++++++++++++++++++++
>  arch/x86/cpu/efi/sdram.c             | 29 +++++++++++
>  arch/x86/cpu/interrupts.c            |  2 +
>  arch/x86/include/asm/arch-efi/gpio.h | 10 ++++
>  arch/x86/lib/Makefile                |  6 +++
>  arch/x86/lib/crt0-efi-ia32.S         | 77 +++++++++++++++++++++++++++++
>  arch/x86/lib/crt0-efi-x86_64.S       | 77 +++++++++++++++++++++++++++++
>  arch/x86/lib/reloc_ia32.c            | 96 ++++++++++++++++++++++++++++++++++++
>  13 files changed, 452 insertions(+)
>  create mode 100644 arch/x86/cpu/efi/Makefile
>  create mode 100644 arch/x86/cpu/efi/efi.c
>  create mode 100644 arch/x86/cpu/efi/elf_ia32_efi.lds
>  create mode 100644 arch/x86/cpu/efi/sdram.c
>  create mode 100644 arch/x86/include/asm/arch-efi/gpio.h
>  create mode 100644 arch/x86/lib/crt0-efi-ia32.S
>  create mode 100644 arch/x86/lib/crt0-efi-x86_64.S
>  create mode 100644 arch/x86/lib/reloc_ia32.c
>
> diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
> index e8968a7..7e6e89c 100644
> --- a/arch/x86/Kconfig
> +++ b/arch/x86/Kconfig
> @@ -11,6 +11,9 @@ choice
>  config VENDOR_COREBOOT
>         bool "coreboot"
>
> +config VENDOR_EFI
> +       bool "efi"
> +
>  config VENDOR_EMULATION
>         bool "emulation"
>
> diff --git a/arch/x86/Makefile b/arch/x86/Makefile
> index 36a6018..e842015 100644
> --- a/arch/x86/Makefile
> +++ b/arch/x86/Makefile
> @@ -2,7 +2,9 @@
>  # SPDX-License-Identifier:     GPL-2.0+
>  #
>
> +ifeq ($(CONFIG_ARCH_EFI),)
>  head-y := arch/x86/cpu/start.o
> +endif
>  ifeq ($(CONFIG_SPL_BUILD),y)
>  head-y += arch/x86/cpu/start16.o
>  head-y += arch/x86/cpu/resetvec.o
> diff --git a/arch/x86/cpu/Makefile b/arch/x86/cpu/Makefile
> index 8a8e63e..9678976 100644
> --- a/arch/x86/cpu/Makefile
> +++ b/arch/x86/cpu/Makefile
> @@ -14,6 +14,7 @@ obj-y += interrupts.o cpu.o cpu_x86.o call64.o
>
>  obj-$(CONFIG_INTEL_BAYTRAIL) += baytrail/
>  obj-$(CONFIG_SYS_COREBOOT) += coreboot/
> +obj-$(CONFIG_ARCH_EFI) += efi/
>  obj-$(CONFIG_QEMU) += qemu/
>  obj-$(CONFIG_NORTHBRIDGE_INTEL_SANDYBRIDGE) += ivybridge/
>  obj-$(CONFIG_NORTHBRIDGE_INTEL_IVYBRIDGE) += ivybridge/
> diff --git a/arch/x86/cpu/efi/Makefile b/arch/x86/cpu/efi/Makefile
> new file mode 100644
> index 0000000..e091637
> --- /dev/null
> +++ b/arch/x86/cpu/efi/Makefile
> @@ -0,0 +1,8 @@
> +#
> +# Copyright (c) 2015 Google, Inc
> +#
> +# SPDX-License-Identifier:     GPL-2.0+
> +#
> +
> +obj-y += efi.o
> +obj-y += sdram.o
> diff --git a/arch/x86/cpu/efi/efi.c b/arch/x86/cpu/efi/efi.c
> new file mode 100644
> index 0000000..0b1c54e
> --- /dev/null
> +++ b/arch/x86/cpu/efi/efi.c
> @@ -0,0 +1,49 @@
> +/*
> + * Copyright (c) 2015 Google, Inc
> + *
> + * SPDX-License-Identifier:    GPL-2.0+
> + */
> +
> +#include <common.h>
> +#include <fdtdec.h>
> +#include <netdev.h>
> +
> +DECLARE_GLOBAL_DATA_PTR;

This is not needed.

> +
> +int arch_cpu_init(void)
> +{
> +#ifdef CONFIG_SYS_X86_TSC_TIMER
> +       timer_set_base(rdtsc());
> +#endif
> +
> +       return 0;
> +}
> +
> +int board_early_init_f(void)
> +{
> +       return 0;
> +}
> +
> +int print_cpuinfo(void)
> +{
> +       return default_print_cpuinfo();
> +}
> +
> +int board_eth_init(bd_t *bis)
> +{
> +       return pci_eth_init(bis);

I don't think this works. Remove?

> +}
> +
> +void board_final_cleanup(void)
> +{
> +}
> +
> +int misc_init_r(void)
> +{
> +       return 0;
> +}
> +
> +int arch_misc_init(void)
> +{
> +       return 0;
> +}
> diff --git a/arch/x86/cpu/efi/elf_ia32_efi.lds b/arch/x86/cpu/efi/elf_ia32_efi.lds
> new file mode 100644
> index 0000000..fca008b
> --- /dev/null
> +++ b/arch/x86/cpu/efi/elf_ia32_efi.lds
> @@ -0,0 +1,92 @@
> +/*
> + * U-Boot EFI link script

Nits: linker script

> + *
> + * SPDX-License-Identifier:    bsd-2-clause
> + *
> + * Modified from usr/lib32/elf_ia32_efi.lds in gnu-efi
> + */
> +
> +#include <config.h>
> +
> +OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
> +OUTPUT_ARCH(i386)
> +ENTRY(_start)
> +SECTIONS
> +{
> +       ImageBase = .;

CamelCase

> +       .hash : { *(.hash) }    /* this MUST come first! */

Why? Please add a comment on this.

> +       . = ALIGN(4096);
> +       .text :
> +       {
> +               *(.text)
> +               *(.text.*)
> +               *(.gnu.linkonce.t.*)
> +       }
> +       . = ALIGN(4096);
> +       .sdata :
> +       {
> +               *(.got.plt)
> +               *(.got)
> +               *(.srodata)
> +               *(.sdata)
> +               *(.sbss)
> +               *(.scommon)
> +       }
> +       . = ALIGN(4096);
> +       .data :
> +       {
> +               *(.rodata*)
> +               *(.data)
> +               *(.data1)
> +               *(.data.*)
> +               *(.sdata)
> +               *(.got.plt)
> +               *(.got)
> +               /*
> +                * the EFI loader doesn't seem to like a .bss section, so we
> +                * stick it all into .data:
> +                */
> +               *(.sbss)
> +               *(.scommon)
> +               *(.dynbss)
> +               *(.bss)
> +               *(COMMON)
> +
> +               /* U-Boot lists and device tree */
> +               . = ALIGN(8);
> +               KEEP(*(SORT(.u_boot_list*)));

I doubt KEEP is needed as this is in the .data section anyway.

> +               . = ALIGN(8);
> +               KEEP(*(.dtb*));
> +       }

The original gnuefi codes have a ". = ALIGN(4096)" here. Is it
intended to drop this?

> +       .dynamic  : { *(.dynamic) }
> +       . = ALIGN(4096);
> +       .rel :
> +       {
> +               *(.rel.data)
> +               *(.rel.data.*)
> +               *(.rel.got)
> +               *(.rel.stab)
> +               *(.data.rel.ro.local)
> +               *(.data.rel.local)
> +               *(.data.rel.ro)
> +               *(.data.rel*)
> +               *(.rel.u_boot_list*)
> +       }
> +       . = ALIGN(4096);
> +               .reloc :        /* This is the PECOFF .reloc section! */
> +       {
> +       *(.reloc)
> +       }
> +       . = ALIGN(4096);
> +       .dynsym   : { *(.dynsym) }
> +       . = ALIGN(4096);
> +       .dynstr   : { *(.dynstr) }
> +       . = ALIGN(4096);
> +       /DISCARD/ :
> +       {
> +               *(.rel.reloc)
> +               *(.eh_frame)
> +               *(.note.GNU-stack)
> +       }
> +       .comment 0 : { *(.comment) }
> +}
> diff --git a/arch/x86/cpu/efi/sdram.c b/arch/x86/cpu/efi/sdram.c
> new file mode 100644
> index 0000000..5159944
> --- /dev/null
> +++ b/arch/x86/cpu/efi/sdram.c
> @@ -0,0 +1,29 @@
> +/*
> + * Copyright (c) 2015 Google, Inc
> + *
> + * SPDX-License-Identifier:    GPL-2.0+
> + */
> +
> +#include <common.h>
> +#include <efi.h>
> +#include <asm/u-boot-x86.h>
> +
> +DECLARE_GLOBAL_DATA_PTR;
> +
> +ulong board_get_usable_ram_top(ulong total_size)
> +{
> +       return (ulong)efi_get_ram_base() + gd->ram_size;
> +}
> +
> +int dram_init(void)
> +{
> +       /* gd->ram_size is set as part of EFI init */
> +
> +       return 0;
> +}
> +
> +void dram_init_banksize(void)
> +{
> +       gd->bd->bi_dram[0].start = efi_get_ram_base();
> +       gd->bd->bi_dram[0].size = CONFIG_EFI_RAM_SIZE;
> +}
> diff --git a/arch/x86/cpu/interrupts.c b/arch/x86/cpu/interrupts.c
> index 3a9c2d4..a86c673 100644
> --- a/arch/x86/cpu/interrupts.c
> +++ b/arch/x86/cpu/interrupts.c
> @@ -242,6 +242,7 @@ int disable_interrupts(void)
>
>  int interrupt_init(void)
>  {
> +#ifndef CONFIG_ARCH_EFI

Can we add a comment block above to explain why EFI APP cannot call
interrupt_init()?

>         /* Just in case... */
>         disable_interrupts();
>
> @@ -255,6 +256,7 @@ int interrupt_init(void)
>
>         /* It is now safe to enable interrupts */
>         enable_interrupts();
> +#endif
>
>         return 0;
>  }
> diff --git a/arch/x86/include/asm/arch-efi/gpio.h b/arch/x86/include/asm/arch-efi/gpio.h
> new file mode 100644
> index 0000000..f044f07
> --- /dev/null
> +++ b/arch/x86/include/asm/arch-efi/gpio.h
> @@ -0,0 +1,10 @@
> +/*
> + * Copyright (c) 2015 Google, Inc.
> + *
> + * SPDX-License-Identifier:    GPL-2.0+
> + */
> +
> +#ifndef _X86_ARCH_GPIO_H_
> +#define _X86_ARCH_GPIO_H_
> +
> +#endif /* _X86_ARCH_GPIO_H_ */
> diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile
> index 43489fd..77bba16 100644
> --- a/arch/x86/lib/Makefile
> +++ b/arch/x86/lib/Makefile
> @@ -5,6 +5,12 @@
>  # SPDX-License-Identifier:     GPL-2.0+
>  #
>
> +ifeq ($(CONFIG_X86_64),)

Where is CONFIG_X86_64 introduced?

> +obj-$(CONFIG_ARCH_EFI) += crt0-efi-ia32.o reloc_ia32.o
> +else
> +obj-$(CONFIG_ARCH_EFI) += crt0-efi-ia64.o reloc_ia64.o
> +endif
> +
>  obj-y += bios.o
>  obj-y += bios_asm.o
>  obj-y += bios_interrupts.o
> diff --git a/arch/x86/lib/crt0-efi-ia32.S b/arch/x86/lib/crt0-efi-ia32.S

Can we put this file to arch/x86/lib/efi instead given it is only used for efi?

> new file mode 100644
> index 0000000..a5aebda
> --- /dev/null
> +++ b/arch/x86/lib/crt0-efi-ia32.S
> @@ -0,0 +1,77 @@
> +/* crt0-efi-ia32.S - x86 EFI startup code.
> +   Copyright (C) 1999 Hewlett-Packard Co.
> +       Contributed by David Mosberger <davidm@hpl.hp.com>.
> +
> +    All rights reserved.
> +
> +    Redistribution and use in source and binary forms, with or without
> +    modification, are permitted provided that the following conditions
> +    are met:
> +
> +    * Redistributions of source code must retain the above copyright
> +      notice, this list of conditions and the following disclaimer.
> +    * Redistributions in binary form must reproduce the above
> +      copyright notice, this list of conditions and the following
> +      disclaimer in the documentation and/or other materials
> +      provided with the distribution.
> +    * Neither the name of Hewlett-Packard Co. nor the names of its
> +      contributors may be used to endorse or promote products derived
> +      from this software without specific prior written permission.
> +
> +    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
> +    CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
> +    INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
> +    MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
> +    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
> +    BE LIABLE FOR ANYDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
> +    OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
> +    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
> +    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> +    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
> +    TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
> +    THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
> +    SUCH DAMAGE.

Can we replace the above license with simplified SPDX version?

> +*/
> +
> +       .text
> +       .align 4
> +
> +       .globl _start
> +_start:
> +       pushl %ebp
> +       movl %esp,%ebp
> +
> +       pushl 12(%ebp)                  # copy "image" argument
> +       pushl  8(%ebp)                  # copy "systab" argument
> +
> +       call 0f
> +0:     popl %eax
> +       movl %eax,%ebx
> +
> +       addl $ImageBase-0b,%eax         # %eax = ldbase
> +       addl $_DYNAMIC-0b,%ebx          # %ebx = _DYNAMIC
> +
> +       pushl %ebx                      # pass _DYNAMIC as second argument
> +       pushl %eax                      # pass ldbase as first argument
> +       call _relocate
> +       popl %ebx
> +       popl %ebx
> +       testl %eax,%eax
> +       jne .exit
> +       call efi_main           # call app with "image" and "systab" argument
> +
> +.exit: leave
> +       ret
> +
> +       /*
> +        * hand-craft a dummy .reloc section so EFI knows it's a relocatable
> +        * executable:
> +        */
> +       .data
> +dummy: .long   0
> +
> +#define IMAGE_REL_ABSOLUTE     0
> +       .section .reloc
> +       .long   dummy                                   /* Page RVA */
> +       .long   10                                      /* Block Size (2*4+2) */
> +       .word   (IMAGE_REL_ABSOLUTE<<12) +  0           /* reloc for dummy */

Nits: space around <<

> diff --git a/arch/x86/lib/crt0-efi-x86_64.S b/arch/x86/lib/crt0-efi-x86_64.S

I believe this file needs to be introduced in later patches, as we
only handle 32-bit so far.

> new file mode 100644
> index 0000000..65a2795
> --- /dev/null
> +++ b/arch/x86/lib/crt0-efi-x86_64.S
> @@ -0,0 +1,77 @@
> +/* crt0-efi-x86_64.S - x86_64 EFI startup code.
> +   Copyright (C) 1999 Hewlett-Packard Co.
> +       Contributed by David Mosberger <davidm@hpl.hp.com>.
> +   Copyright (C) 2005 Intel Co.
> +       Contributed by Fenghua Yu <fenghua.yu@intel.com>.
> +
> +    All rights reserved.
> +
> +    Redistribution and use in source and binary forms, with or without
> +    modification, are permitted provided that the following conditions
> +    are met:
> +
> +    * Redistributions of source code must retain the above copyright
> +      notice, this list of conditions and the following disclaimer.
> +    * Redistributions in binary form must reproduce the above
> +      copyright notice, this list of conditions and the following
> +      disclaimer in the documentation and/or other materials
> +      provided with the distribution.
> +    * Neither the name of Hewlett-Packard Co. nor the names of its
> +      contributors may be used to endorse or promote products derived
> +      from this software without specific prior written permission.
> +
> +    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
> +    CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
> +    INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
> +    MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
> +    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
> +    BE LIABLE FOR ANYDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
> +    OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
> +    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
> +    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> +    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
> +    TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
> +    THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
> +    SUCH DAMAGE.

Can we replace the above license with simplified SPDX version?

> +*/
> +       .text
> +       .align 4
> +
> +       .globl _start
> +_start:
> +       subq $8, %rsp
> +       pushq %rcx
> +       pushq %rdx
> +
> +0:
> +       lea ImageBase(%rip), %rdi
> +       lea _DYNAMIC(%rip), %rsi
> +
> +       popq %rcx
> +       popq %rdx
> +       pushq %rcx
> +       pushq %rdx
> +       call _relocate
> +
> +       popq %rdi
> +       popq %rsi
> +
> +       call efi_main
> +       addq $8, %rsp
> +
> +.exit:
> +       ret
> +
> +       /*
> +        * hand-craft a dummy .reloc section so EFI knows it's a relocatable
> +        * executable:
> +        */
> +       .data
> +dummy: .long   0
> +
> +#define IMAGE_REL_ABSOLUTE     0
> +       .section .reloc, "a"
> +label1:
> +       .long   dummy-label1                            /* Page RVA */
> +       .long   10                                      /* Block Size (2*4+2) */
> +       .word   (IMAGE_REL_ABSOLUTE<<12) +  0           /* reloc for dummy */

Nits: space around <<

> diff --git a/arch/x86/lib/reloc_ia32.c b/arch/x86/lib/reloc_ia32.c
> new file mode 100644
> index 0000000..45c6654
> --- /dev/null
> +++ b/arch/x86/lib/reloc_ia32.c
> @@ -0,0 +1,96 @@
> +/* reloc_ia32.c - position independent x86 ELF shared object relocator
> +   Copyright (C) 1999 Hewlett-Packard Co.
> +       Contributed by David Mosberger <davidm@hpl.hp.com>.
> +
> +    All rights reserved.
> +
> +    Redistribution and use in source and binary forms, with or without
> +    modification, are permitted provided that the following conditions
> +    are met:
> +
> +    * Redistributions of source code must retain the above copyright
> +      notice, this list of conditions and the following disclaimer.
> +    * Redistributions in binary form must reproduce the above
> +      copyright notice, this list of conditions and the following
> +      disclaimer in the documentation and/or other materials
> +      provided with the distribution.
> +    * Neither the name of Hewlett-Packard Co. nor the names of its
> +      contributors may be used to endorse or promote products derived
> +      from this software without specific prior written permission.
> +
> +    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
> +    CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
> +    INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
> +    MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
> +    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
> +    BE LIABLE FOR ANYDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
> +    OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
> +    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
> +    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> +    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
> +    TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
> +    THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
> +    SUCH DAMAGE.

Can we replace the above license with simplified SPDX version?

> +*/
> +
> +#include <common.h>
> +#include <efi.h>
> +#include <elf.h>
> +#include <asm/elf.h>
> +
> +efi_status_t _relocate(long ldbase, Elf32_Dyn *dyn, efi_handle_t image,
> +                      struct efi_system_table *systab)
> +{
> +       long relsz = 0, relent = 0;
> +       Elf32_Rel *rel = 0;
> +       unsigned long *addr;
> +       int i;
> +
> +       for (i = 0; dyn[i].d_tag != DT_NULL; ++i) {
> +               switch (dyn[i].d_tag) {
> +               case DT_REL:
> +                       rel = (Elf32_Rel *)((unsigned long)dyn[i].d_un.d_ptr +
> +                                                               ldbase);
> +                       break;
> +
> +               case DT_RELSZ:
> +                       relsz = dyn[i].d_un.d_val;
> +                       break;
> +
> +               case DT_RELENT:
> +                       relent = dyn[i].d_un.d_val;
> +                       break;
> +
> +               case DT_RELA:
> +                       break;
> +
> +               default:
> +                       break;
> +               }
> +       }
> +
> +       if (!rel && relent == 0)
> +               return EFI_SUCCESS;
> +
> +       if (!rel || relent == 0)
> +               return EFI_LOAD_ERROR;
> +
> +       while (relsz > 0) {
> +               /* apply the relocs */
> +               switch (ELF32_R_TYPE(rel->r_info)) {
> +               case R_386_NONE:
> +                       break;
> +
> +               case R_386_RELATIVE:
> +                       addr = (unsigned long *)(ldbase + rel->r_offset);
> +                       *addr += ldbase;
> +                       break;
> +
> +               default:
> +                       break;
> +               }
> +               rel = (Elf32_Rel *)((char *)rel + relent);
> +               relsz -= relent;
> +       }

Nits: need a blank line

> +       return EFI_SUCCESS;
> +}
> --

Regards,
Bin
diff mbox

Patch

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index e8968a7..7e6e89c 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -11,6 +11,9 @@  choice
 config VENDOR_COREBOOT
 	bool "coreboot"
 
+config VENDOR_EFI
+	bool "efi"
+
 config VENDOR_EMULATION
 	bool "emulation"
 
diff --git a/arch/x86/Makefile b/arch/x86/Makefile
index 36a6018..e842015 100644
--- a/arch/x86/Makefile
+++ b/arch/x86/Makefile
@@ -2,7 +2,9 @@ 
 # SPDX-License-Identifier:	GPL-2.0+
 #
 
+ifeq ($(CONFIG_ARCH_EFI),)
 head-y := arch/x86/cpu/start.o
+endif
 ifeq ($(CONFIG_SPL_BUILD),y)
 head-y += arch/x86/cpu/start16.o
 head-y += arch/x86/cpu/resetvec.o
diff --git a/arch/x86/cpu/Makefile b/arch/x86/cpu/Makefile
index 8a8e63e..9678976 100644
--- a/arch/x86/cpu/Makefile
+++ b/arch/x86/cpu/Makefile
@@ -14,6 +14,7 @@  obj-y	+= interrupts.o cpu.o cpu_x86.o call64.o
 
 obj-$(CONFIG_INTEL_BAYTRAIL) += baytrail/
 obj-$(CONFIG_SYS_COREBOOT) += coreboot/
+obj-$(CONFIG_ARCH_EFI) += efi/
 obj-$(CONFIG_QEMU) += qemu/
 obj-$(CONFIG_NORTHBRIDGE_INTEL_SANDYBRIDGE) += ivybridge/
 obj-$(CONFIG_NORTHBRIDGE_INTEL_IVYBRIDGE) += ivybridge/
diff --git a/arch/x86/cpu/efi/Makefile b/arch/x86/cpu/efi/Makefile
new file mode 100644
index 0000000..e091637
--- /dev/null
+++ b/arch/x86/cpu/efi/Makefile
@@ -0,0 +1,8 @@ 
+#
+# Copyright (c) 2015 Google, Inc
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+
+obj-y += efi.o
+obj-y += sdram.o
diff --git a/arch/x86/cpu/efi/efi.c b/arch/x86/cpu/efi/efi.c
new file mode 100644
index 0000000..0b1c54e
--- /dev/null
+++ b/arch/x86/cpu/efi/efi.c
@@ -0,0 +1,49 @@ 
+/*
+ * Copyright (c) 2015 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <fdtdec.h>
+#include <netdev.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int arch_cpu_init(void)
+{
+#ifdef CONFIG_SYS_X86_TSC_TIMER
+	timer_set_base(rdtsc());
+#endif
+
+	return 0;
+}
+
+int board_early_init_f(void)
+{
+	return 0;
+}
+
+int print_cpuinfo(void)
+{
+	return default_print_cpuinfo();
+}
+
+int board_eth_init(bd_t *bis)
+{
+	return pci_eth_init(bis);
+}
+
+void board_final_cleanup(void)
+{
+}
+
+int misc_init_r(void)
+{
+	return 0;
+}
+
+int arch_misc_init(void)
+{
+	return 0;
+}
diff --git a/arch/x86/cpu/efi/elf_ia32_efi.lds b/arch/x86/cpu/efi/elf_ia32_efi.lds
new file mode 100644
index 0000000..fca008b
--- /dev/null
+++ b/arch/x86/cpu/efi/elf_ia32_efi.lds
@@ -0,0 +1,92 @@ 
+/*
+ * U-Boot EFI link script
+ *
+ * SPDX-License-Identifier:	bsd-2-clause
+ *
+ * Modified from usr/lib32/elf_ia32_efi.lds in gnu-efi
+ */
+
+#include <config.h>
+
+OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
+OUTPUT_ARCH(i386)
+ENTRY(_start)
+SECTIONS
+{
+	ImageBase = .;
+	.hash : { *(.hash) }	/* this MUST come first! */
+	. = ALIGN(4096);
+	.text :
+	{
+		*(.text)
+		*(.text.*)
+		*(.gnu.linkonce.t.*)
+	}
+	. = ALIGN(4096);
+	.sdata :
+	{
+		*(.got.plt)
+		*(.got)
+		*(.srodata)
+		*(.sdata)
+		*(.sbss)
+		*(.scommon)
+	}
+	. = ALIGN(4096);
+	.data :
+	{
+		*(.rodata*)
+		*(.data)
+		*(.data1)
+		*(.data.*)
+		*(.sdata)
+		*(.got.plt)
+		*(.got)
+		/*
+		 * the EFI loader doesn't seem to like a .bss section, so we
+		 * stick it all into .data:
+		 */
+		*(.sbss)
+		*(.scommon)
+		*(.dynbss)
+		*(.bss)
+		*(COMMON)
+
+		/* U-Boot lists and device tree */
+		. = ALIGN(8);
+		KEEP(*(SORT(.u_boot_list*)));
+		. = ALIGN(8);
+		KEEP(*(.dtb*));
+	}
+	.dynamic  : { *(.dynamic) }
+	. = ALIGN(4096);
+	.rel :
+	{
+		*(.rel.data)
+		*(.rel.data.*)
+		*(.rel.got)
+		*(.rel.stab)
+		*(.data.rel.ro.local)
+		*(.data.rel.local)
+		*(.data.rel.ro)
+		*(.data.rel*)
+		*(.rel.u_boot_list*)
+	}
+	. = ALIGN(4096);
+		.reloc :	/* This is the PECOFF .reloc section! */
+	{
+	*(.reloc)
+	}
+	. = ALIGN(4096);
+	.dynsym   : { *(.dynsym) }
+	. = ALIGN(4096);
+	.dynstr   : { *(.dynstr) }
+	. = ALIGN(4096);
+	/DISCARD/ :
+	{
+		*(.rel.reloc)
+		*(.eh_frame)
+		*(.note.GNU-stack)
+	}
+	.comment 0 : { *(.comment) }
+}
diff --git a/arch/x86/cpu/efi/sdram.c b/arch/x86/cpu/efi/sdram.c
new file mode 100644
index 0000000..5159944
--- /dev/null
+++ b/arch/x86/cpu/efi/sdram.c
@@ -0,0 +1,29 @@ 
+/*
+ * Copyright (c) 2015 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <efi.h>
+#include <asm/u-boot-x86.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+ulong board_get_usable_ram_top(ulong total_size)
+{
+	return (ulong)efi_get_ram_base() + gd->ram_size;
+}
+
+int dram_init(void)
+{
+	/* gd->ram_size is set as part of EFI init */
+
+	return 0;
+}
+
+void dram_init_banksize(void)
+{
+	gd->bd->bi_dram[0].start = efi_get_ram_base();
+	gd->bd->bi_dram[0].size = CONFIG_EFI_RAM_SIZE;
+}
diff --git a/arch/x86/cpu/interrupts.c b/arch/x86/cpu/interrupts.c
index 3a9c2d4..a86c673 100644
--- a/arch/x86/cpu/interrupts.c
+++ b/arch/x86/cpu/interrupts.c
@@ -242,6 +242,7 @@  int disable_interrupts(void)
 
 int interrupt_init(void)
 {
+#ifndef CONFIG_ARCH_EFI
 	/* Just in case... */
 	disable_interrupts();
 
@@ -255,6 +256,7 @@  int interrupt_init(void)
 
 	/* It is now safe to enable interrupts */
 	enable_interrupts();
+#endif
 
 	return 0;
 }
diff --git a/arch/x86/include/asm/arch-efi/gpio.h b/arch/x86/include/asm/arch-efi/gpio.h
new file mode 100644
index 0000000..f044f07
--- /dev/null
+++ b/arch/x86/include/asm/arch-efi/gpio.h
@@ -0,0 +1,10 @@ 
+/*
+ * Copyright (c) 2015 Google, Inc.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef _X86_ARCH_GPIO_H_
+#define _X86_ARCH_GPIO_H_
+
+#endif /* _X86_ARCH_GPIO_H_ */
diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile
index 43489fd..77bba16 100644
--- a/arch/x86/lib/Makefile
+++ b/arch/x86/lib/Makefile
@@ -5,6 +5,12 @@ 
 # SPDX-License-Identifier:	GPL-2.0+
 #
 
+ifeq ($(CONFIG_X86_64),)
+obj-$(CONFIG_ARCH_EFI) += crt0-efi-ia32.o reloc_ia32.o
+else
+obj-$(CONFIG_ARCH_EFI) += crt0-efi-ia64.o reloc_ia64.o
+endif
+
 obj-y += bios.o
 obj-y += bios_asm.o
 obj-y += bios_interrupts.o
diff --git a/arch/x86/lib/crt0-efi-ia32.S b/arch/x86/lib/crt0-efi-ia32.S
new file mode 100644
index 0000000..a5aebda
--- /dev/null
+++ b/arch/x86/lib/crt0-efi-ia32.S
@@ -0,0 +1,77 @@ 
+/* crt0-efi-ia32.S - x86 EFI startup code.
+   Copyright (C) 1999 Hewlett-Packard Co.
+	Contributed by David Mosberger <davidm@hpl.hp.com>.
+
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials
+      provided with the distribution.
+    * Neither the name of Hewlett-Packard Co. nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+    CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+    INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+    MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+    BE LIABLE FOR ANYDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+    OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+    TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+    THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+    SUCH DAMAGE.
+*/
+
+	.text
+	.align 4
+
+	.globl _start
+_start:
+	pushl %ebp
+	movl %esp,%ebp
+
+	pushl 12(%ebp)			# copy "image" argument
+	pushl  8(%ebp)			# copy "systab" argument
+
+	call 0f
+0:	popl %eax
+	movl %eax,%ebx
+
+	addl $ImageBase-0b,%eax		# %eax = ldbase
+	addl $_DYNAMIC-0b,%ebx		# %ebx = _DYNAMIC
+
+	pushl %ebx			# pass _DYNAMIC as second argument
+	pushl %eax			# pass ldbase as first argument
+	call _relocate
+	popl %ebx
+	popl %ebx
+	testl %eax,%eax
+	jne .exit
+	call efi_main		# call app with "image" and "systab" argument
+
+.exit:	leave
+	ret
+
+	/*
+	 * hand-craft a dummy .reloc section so EFI knows it's a relocatable
+	 * executable:
+	 */
+	.data
+dummy:	.long	0
+
+#define IMAGE_REL_ABSOLUTE	0
+	.section .reloc
+	.long	dummy					/* Page RVA */
+	.long	10					/* Block Size (2*4+2) */
+	.word	(IMAGE_REL_ABSOLUTE<<12) +  0		/* reloc for dummy */
diff --git a/arch/x86/lib/crt0-efi-x86_64.S b/arch/x86/lib/crt0-efi-x86_64.S
new file mode 100644
index 0000000..65a2795
--- /dev/null
+++ b/arch/x86/lib/crt0-efi-x86_64.S
@@ -0,0 +1,77 @@ 
+/* crt0-efi-x86_64.S - x86_64 EFI startup code.
+   Copyright (C) 1999 Hewlett-Packard Co.
+	Contributed by David Mosberger <davidm@hpl.hp.com>.
+   Copyright (C) 2005 Intel Co.
+	Contributed by Fenghua Yu <fenghua.yu@intel.com>.
+
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials
+      provided with the distribution.
+    * Neither the name of Hewlett-Packard Co. nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+    CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+    INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+    MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+    BE LIABLE FOR ANYDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+    OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+    TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+    THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+    SUCH DAMAGE.
+*/
+	.text
+	.align 4
+
+	.globl _start
+_start:
+	subq $8, %rsp
+	pushq %rcx
+	pushq %rdx
+
+0:
+	lea ImageBase(%rip), %rdi
+	lea _DYNAMIC(%rip), %rsi
+
+	popq %rcx
+	popq %rdx
+	pushq %rcx
+	pushq %rdx
+	call _relocate
+
+	popq %rdi
+	popq %rsi
+
+	call efi_main
+	addq $8, %rsp
+
+.exit:
+	ret
+
+	/*
+	 * hand-craft a dummy .reloc section so EFI knows it's a relocatable
+	 * executable:
+	 */
+	.data
+dummy:	.long	0
+
+#define IMAGE_REL_ABSOLUTE	0
+	.section .reloc, "a"
+label1:
+	.long	dummy-label1				/* Page RVA */
+	.long	10					/* Block Size (2*4+2) */
+	.word	(IMAGE_REL_ABSOLUTE<<12) +  0		/* reloc for dummy */
diff --git a/arch/x86/lib/reloc_ia32.c b/arch/x86/lib/reloc_ia32.c
new file mode 100644
index 0000000..45c6654
--- /dev/null
+++ b/arch/x86/lib/reloc_ia32.c
@@ -0,0 +1,96 @@ 
+/* reloc_ia32.c - position independent x86 ELF shared object relocator
+   Copyright (C) 1999 Hewlett-Packard Co.
+	Contributed by David Mosberger <davidm@hpl.hp.com>.
+
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials
+      provided with the distribution.
+    * Neither the name of Hewlett-Packard Co. nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+    CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+    INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+    MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+    BE LIABLE FOR ANYDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+    OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+    TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+    THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+    SUCH DAMAGE.
+*/
+
+#include <common.h>
+#include <efi.h>
+#include <elf.h>
+#include <asm/elf.h>
+
+efi_status_t _relocate(long ldbase, Elf32_Dyn *dyn, efi_handle_t image,
+		       struct efi_system_table *systab)
+{
+	long relsz = 0, relent = 0;
+	Elf32_Rel *rel = 0;
+	unsigned long *addr;
+	int i;
+
+	for (i = 0; dyn[i].d_tag != DT_NULL; ++i) {
+		switch (dyn[i].d_tag) {
+		case DT_REL:
+			rel = (Elf32_Rel *)((unsigned long)dyn[i].d_un.d_ptr +
+								ldbase);
+			break;
+
+		case DT_RELSZ:
+			relsz = dyn[i].d_un.d_val;
+			break;
+
+		case DT_RELENT:
+			relent = dyn[i].d_un.d_val;
+			break;
+
+		case DT_RELA:
+			break;
+
+		default:
+			break;
+		}
+	}
+
+	if (!rel && relent == 0)
+		return EFI_SUCCESS;
+
+	if (!rel || relent == 0)
+		return EFI_LOAD_ERROR;
+
+	while (relsz > 0) {
+		/* apply the relocs */
+		switch (ELF32_R_TYPE(rel->r_info)) {
+		case R_386_NONE:
+			break;
+
+		case R_386_RELATIVE:
+			addr = (unsigned long *)(ldbase + rel->r_offset);
+			*addr += ldbase;
+			break;
+
+		default:
+			break;
+		}
+		rel = (Elf32_Rel *)((char *)rel + relent);
+		relsz -= relent;
+	}
+	return EFI_SUCCESS;
+}