
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