Message ID | 1437580180-6405-26-git-send-email-sjg@chromium.org |
---|---|
State | Superseded |
Delegated to: | Simon Glass |
Headers | show |
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 --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; +}