From 456ca6ba04bc4ecb5d35d01dbc62573c4391fe38 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 20 Oct 2016 00:23:43 +0900 Subject: efi_loader: fix depends on line of EFI_LOADER This line is shown as depends on (ARM64 ||\302\240ARM) && OF_LIBFDT on my Emacs. Use ASCII characters only. Assuming it is (ARM64 || ARM), remove the redundancy. Unlike Linux, CONFIG_ARM includes CONFIG_ARM64 in U-Boot. Signed-off-by: Masahiro Yamada Signed-off-by: Alexander Graf diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig index 37a0dd6..7d4106e 100644 --- a/lib/efi_loader/Kconfig +++ b/lib/efi_loader/Kconfig @@ -1,6 +1,6 @@ config EFI_LOADER bool "Support running EFI Applications in U-Boot" - depends on (ARM64 || ARM) && OF_LIBFDT + depends on ARM && OF_LIBFDT default y help Select this option if you want to run EFI applications (like grub2) -- cgit v0.10.2 From d7608aba38d760be4c40cb8f4591057e5e40c2d4 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Mon, 24 Oct 2016 10:47:01 -0700 Subject: efi: Use device device path type Messaging for network interface node When adding network interface node use Messaging device path with subtype MAC Address and device's MAC address as a value instead of Media Device path type with subtype File Path and path "Net" Signed-off-by: Oleksandr Tymoshenko Signed-off-by: Alexander Graf diff --git a/include/efi_api.h b/include/efi_api.h index bdb600e..5c3836a 100644 --- a/include/efi_api.h +++ b/include/efi_api.h @@ -268,6 +268,19 @@ struct efi_device_path { u16 length; }; +struct efi_mac_addr { + u8 addr[32]; +}; + +#define DEVICE_PATH_TYPE_MESSAGING_DEVICE 0x03 +# define DEVICE_PATH_SUB_TYPE_MSG_MAC_ADDR 0x0b + +struct efi_device_path_mac_addr { + struct efi_device_path dp; + struct efi_mac_addr mac; + u8 if_type; +}; + #define DEVICE_PATH_TYPE_MEDIA_DEVICE 0x04 # define DEVICE_PATH_SUB_TYPE_FILE_PATH 0x04 diff --git a/lib/efi_loader/efi_net.c b/lib/efi_loader/efi_net.c index 3796496..604ac6e 100644 --- a/lib/efi_loader/efi_net.c +++ b/lib/efi_loader/efi_net.c @@ -27,7 +27,8 @@ struct efi_net_obj { struct efi_simple_network net; struct efi_simple_network_mode net_mode; /* Device path to the network adapter */ - struct efi_device_path_file_path dp[2]; + struct efi_device_path_mac_addr dp_mac; + struct efi_device_path_file_path dp_end; /* PXE struct to transmit dhcp data */ struct efi_pxe pxe; struct efi_pxe_mode pxe_mode; @@ -205,7 +206,7 @@ static efi_status_t EFIAPI efi_net_open_dp(void *handle, efi_guid_t *protocol, struct efi_simple_network *net = handle; struct efi_net_obj *netobj = container_of(net, struct efi_net_obj, net); - *protocol_interface = netobj->dp; + *protocol_interface = &netobj->dp_mac; return EFI_SUCCESS; } @@ -236,11 +237,10 @@ void efi_net_set_dhcp_ack(void *pkt, int len) int efi_net_register(void **handle) { struct efi_net_obj *netobj; - struct efi_device_path_file_path dp_net = { - .dp.type = DEVICE_PATH_TYPE_MEDIA_DEVICE, - .dp.sub_type = DEVICE_PATH_SUB_TYPE_FILE_PATH, + struct efi_device_path_mac_addr dp_net = { + .dp.type = DEVICE_PATH_TYPE_MESSAGING_DEVICE, + .dp.sub_type = DEVICE_PATH_SUB_TYPE_MSG_MAC_ADDR, .dp.length = sizeof(dp_net), - .str = { 'N', 'e', 't' }, }; struct efi_device_path_file_path dp_end = { .dp.type = DEVICE_PATH_TYPE_END, @@ -279,8 +279,9 @@ int efi_net_register(void **handle) netobj->net.receive = efi_net_receive; netobj->net.mode = &netobj->net_mode; netobj->net_mode.state = EFI_NETWORK_STARTED; - netobj->dp[0] = dp_net; - netobj->dp[1] = dp_end; + netobj->dp_mac = dp_net; + netobj->dp_end = dp_end; + memcpy(netobj->dp_mac.mac.addr, eth_get_ethaddr(), 6); memcpy(netobj->net_mode.current_address.mac_addr, eth_get_ethaddr(), 6); netobj->net_mode.max_packet_size = PKTSIZE; -- cgit v0.10.2 From 5be8b0a338c56c606d1e615c181b1cc0545b4747 Mon Sep 17 00:00:00 2001 From: Emmanuel Vadot Date: Tue, 8 Nov 2016 06:03:29 +0100 Subject: efi_loader: console: Correctly report modes Add support for EFI console modes. Mode 0 is always 80x25 and present by EFI specification. Mode 1 is always 80x50 and not mandatory. Mode 2 and above is freely usable. If the terminal can handle mode 1, we mark it as supported. If the terminal size is greater than mode 0 and different than mode 1, we install it as mode 2. Modes can be switch with cout_set_mode. Changes in V5: Correctly detect mode before enabling mode 2. Changes in V4: Reset cursor positon on mode switch Use local variables in console query code Changes in V3: Valid mode are 0 to EFIMode-1 Fix style Changes in V2: Add mode switch Report only the modes that we support Signed-off-by: Emmanuel Vadot Signed-off-by: Alexander Graf diff --git a/lib/efi_loader/efi_console.c b/lib/efi_loader/efi_console.c index 2e0228c..8ef7326 100644 --- a/lib/efi_loader/efi_console.c +++ b/lib/efi_loader/efi_console.c @@ -9,11 +9,38 @@ #include #include -/* If we can't determine the console size, default to 80x24 */ -static int console_columns = 80; -static int console_rows = 24; static bool console_size_queried; +#define EFI_COUT_MODE_2 2 +#define EFI_MAX_COUT_MODE 3 + +struct cout_mode { + unsigned long columns; + unsigned long rows; + int present; +}; + +static struct cout_mode efi_cout_modes[] = { + /* EFI Mode 0 is 80x25 and always present */ + { + .columns = 80, + .rows = 25, + .present = 1, + }, + /* EFI Mode 1 is always 80x50 */ + { + .columns = 80, + .rows = 50, + .present = 0, + }, + /* Value are unknown until we query the console */ + { + .columns = 0, + .rows = 0, + .present = 0, + }, +}; + const efi_guid_t efi_guid_console_control = CONSOLE_CONTROL_GUID; #define cESC '\x1b' @@ -56,8 +83,9 @@ const struct efi_console_control_protocol efi_console_control = { .lock_std_in = efi_cin_lock_std_in, }; +/* Default to mode 0 */ static struct simple_text_output_mode efi_con_mode = { - .max_mode = 0, + .max_mode = 1, .mode = 0, .attribute = 0, .cursor_column = 0, @@ -131,8 +159,10 @@ static efi_status_t EFIAPI efi_cout_output_string( struct efi_simple_text_output_protocol *this, const unsigned short *string) { + struct cout_mode *mode; u16 ch; + mode = &efi_cout_modes[efi_con_mode.mode]; EFI_ENTRY("%p, %p", this, string); for (;(ch = *string); string++) { print_unicode_in_utf8(ch); @@ -140,13 +170,12 @@ static efi_status_t EFIAPI efi_cout_output_string( if (ch == '\n') { efi_con_mode.cursor_column = 1; efi_con_mode.cursor_row++; - } else if (efi_con_mode.cursor_column > console_columns) { + } else if (efi_con_mode.cursor_column > mode->columns) { efi_con_mode.cursor_column = 1; efi_con_mode.cursor_row++; } - if (efi_con_mode.cursor_row > console_rows) { - efi_con_mode.cursor_row = console_rows; - } + if (efi_con_mode.cursor_row > mode->rows) + efi_con_mode.cursor_row = mode->rows; } return EFI_EXIT(EFI_SUCCESS); @@ -160,6 +189,14 @@ static efi_status_t EFIAPI efi_cout_test_string( return EFI_EXIT(EFI_SUCCESS); } +static bool cout_mode_matches(struct cout_mode *mode, int rows, int cols) +{ + if (!mode->present) + return false; + + return (mode->rows == rows) && (mode->columns == cols); +} + static efi_status_t EFIAPI efi_cout_query_mode( struct efi_simple_text_output_protocol *this, unsigned long mode_number, unsigned long *columns, @@ -170,6 +207,8 @@ static efi_status_t EFIAPI efi_cout_query_mode( if (!console_size_queried) { /* Ask the terminal about its size */ int n[3]; + int cols; + int rows; u64 timeout; console_size_queried = true; @@ -191,15 +230,40 @@ static efi_status_t EFIAPI efi_cout_query_mode( goto out; } - console_columns = n[2]; - console_rows = n[1]; + cols = n[2]; + rows = n[1]; + + /* Test if we can have Mode 1 */ + if (cols >= 80 && rows >= 50) { + efi_cout_modes[1].present = 1; + efi_con_mode.max_mode = 2; + } + + /* + * Install our mode as mode 2 if it is different + * than mode 0 or 1 and set it as the currently selected mode + */ + if (!cout_mode_matches(&efi_cout_modes[0], rows, cols) && + !cout_mode_matches(&efi_cout_modes[1], rows, cols)) { + efi_cout_modes[EFI_COUT_MODE_2].columns = cols; + efi_cout_modes[EFI_COUT_MODE_2].rows = rows; + efi_cout_modes[EFI_COUT_MODE_2].present = 1; + efi_con_mode.max_mode = EFI_MAX_COUT_MODE; + efi_con_mode.mode = EFI_COUT_MODE_2; + } } + if (mode_number >= efi_con_mode.max_mode) + return EFI_EXIT(EFI_UNSUPPORTED); + + if (efi_cout_modes[mode_number].present != 1) + return EFI_EXIT(EFI_UNSUPPORTED); + out: if (columns) - *columns = console_columns; + *columns = efi_cout_modes[mode_number].columns; if (rows) - *rows = console_rows; + *rows = efi_cout_modes[mode_number].rows; return EFI_EXIT(EFI_SUCCESS); } @@ -210,11 +274,15 @@ static efi_status_t EFIAPI efi_cout_set_mode( { EFI_ENTRY("%p, %ld", this, mode_number); - /* We only support text output for now */ - if (mode_number == EFI_CONSOLE_MODE_TEXT) - return EFI_EXIT(EFI_SUCCESS); - return EFI_EXIT(EFI_UNSUPPORTED); + if (mode_number > efi_con_mode.max_mode) + return EFI_EXIT(EFI_UNSUPPORTED); + + efi_con_mode.mode = mode_number; + efi_con_mode.cursor_column = 0; + efi_con_mode.cursor_row = 0; + + return EFI_EXIT(EFI_SUCCESS); } static efi_status_t EFIAPI efi_cout_set_attribute( -- cgit v0.10.2 From 1f3f0357aa79212e06fadf2149a85e0fa435a8eb Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 7 Nov 2016 08:47:03 -0700 Subject: x86: Correct a build warning in x86 tables There is a build warning for three x86 boards since write_smbios_table_wrapper() is not used. Fix it. Fixes: e824cf3f (smbios: Allow compilation on 64bit systems) Signed-off-by: Simon Glass Signed-off-by: Alexander Graf diff --git a/arch/x86/lib/tables.c b/arch/x86/lib/tables.c index 025b183..5966e58 100644 --- a/arch/x86/lib/tables.c +++ b/arch/x86/lib/tables.c @@ -12,10 +12,12 @@ #include #include +#ifdef CONFIG_GENERATE_SMBIOS_TABLE static u32 write_smbios_table_wrapper(u32 addr) { return write_smbios_table(addr); } +#endif /** * Function prototype to write a specific configuration table -- cgit v0.10.2 From d0d9099365f6658cfc89943b4e08d6436200845f Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 7 Nov 2016 08:47:04 -0700 Subject: efi: Correct cache flush alignment Make sure that the cache flushes correctly by ensuring that the end address is correctly aligned. Signed-off-by: Simon Glass Signed-off-by: Alexander Graf diff --git a/lib/efi_loader/efi_image_loader.c b/lib/efi_loader/efi_image_loader.c index 5165377..3262d76 100644 --- a/lib/efi_loader/efi_image_loader.c +++ b/lib/efi_loader/efi_image_loader.c @@ -174,7 +174,8 @@ void *efi_load_pe(void *efi, struct efi_loaded_image *loaded_image_info) efi_loader_relocate(rel, rel_size, efi_reloc); /* Flush cache */ - flush_cache((ulong)efi_reloc, virt_size); + flush_cache((ulong)efi_reloc, + ALIGN(virt_size, CONFIG_SYS_CACHELINE_SIZE)); invalidate_icache_all(); /* Populate the loaded image interface bits */ -- cgit v0.10.2 From 5ee31baf813123e2816e55cf2b5aaf604770da8b Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 7 Nov 2016 08:47:05 -0700 Subject: efi: Fix debug message address format This should use U-Boot's standard format for hex address. Fix it. Signed-off-by: Simon Glass Signed-off-by: Alexander Graf diff --git a/cmd/bootefi.c b/cmd/bootefi.c index c8079c4..3ab256e 100644 --- a/cmd/bootefi.c +++ b/cmd/bootefi.c @@ -248,7 +248,7 @@ static int do_bootefi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) fdt_addr = simple_strtoul(sfdt, NULL, 16); } - printf("## Starting EFI application at 0x%08lx ...\n", addr); + printf("## Starting EFI application at %08lx ...\n", addr); r = do_bootefi_exec((void *)addr, (void*)fdt_addr); printf("## Application terminated, r = %d\n", r); -- cgit v0.10.2 From 5abd9137d5329e84827c265bc950287043eac636 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 7 Nov 2016 08:47:06 -0700 Subject: x86: Tidy up selection of building the EFI stub At present we use a CONFIG option in efi.h to determine whether we are building the EFI stub or not. This means that the same header cannot be used for EFI_LOADER support. The CONFIG option will be enabled for the whole build, even when not building the stub. Use a different define instead, set up just for the files that make up the stub. Signed-off-by: Simon Glass Reviewed-by: Bin Meng Signed-off-by: Alexander Graf diff --git a/include/efi.h b/include/efi.h index d07187c..3d58780 100644 --- a/include/efi.h +++ b/include/efi.h @@ -30,8 +30,11 @@ struct efi_device_path; #define EFI_BITS_PER_LONG BITS_PER_LONG -/* With 64-bit EFI stub, EFI_BITS_PER_LONG has to be 64 */ -#ifdef CONFIG_EFI_STUB_64BIT +/* + * With 64-bit EFI stub, EFI_BITS_PER_LONG has to be 64. EFI_STUB is set + * in lib/efi/Makefile, when building the stub. + */ +#if defined(CONFIG_EFI_STUB_64BIT) && defined(EFI_STUB) #undef EFI_BITS_PER_LONG #define EFI_BITS_PER_LONG 64 #endif diff --git a/lib/efi/Makefile b/lib/efi/Makefile index e32dc14..9449600 100644 --- a/lib/efi/Makefile +++ b/lib/efi/Makefile @@ -9,9 +9,9 @@ obj-$(CONFIG_EFI_STUB) += efi_info.o CFLAGS_REMOVE_efi_stub.o := -mregparm=3 \ $(if $(CONFIG_EFI_STUB_64BIT),-march=i386 -m32) -CFLAGS_efi_stub.o := -fpic -fshort-wchar +CFLAGS_efi_stub.o := -fpic -fshort-wchar -DEFI_STUB CFLAGS_REMOVE_efi.o := -mregparm=3 \ $(if $(CONFIG_EFI_STUB_64BIT),-march=i386 -m32) -CFLAGS_efi.o := -fpic -fshort-wchar +CFLAGS_efi.o := -fpic -fshort-wchar -DEFI_STUB extra-$(CONFIG_EFI_STUB) += efi_stub.o efi.o -- cgit v0.10.2 From bb1ae55948377b6b75d2230fd8fea69106477d81 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 7 Nov 2016 08:47:07 -0700 Subject: efi: Makefile: Export variables for use with EFI When building an EFI app we need three things: - start-up code - relocation code - link script These are all different for each architecture. We also need special compiler flags in some cases. Add top-level Makefile variables for these along with documentation. Signed-off-by: Simon Glass Signed-off-by: Alexander Graf diff --git a/Makefile b/Makefile index 8ca1db5..bb108d4 100644 --- a/Makefile +++ b/Makefile @@ -527,6 +527,15 @@ endif endif endif +# These are set by the arch-specific config.mk. Make sure they are exported +# so they can be used when building an EFI application. +export EFI_LDS # Filename of EFI link script in arch/$(ARCH)/lib +export EFI_CRT0 # Filename of EFI CRT0 in arch/$(ARCH)/lib +export EFI_RELOC # Filename of EFU relocation code in arch/$(ARCH)/lib +export CFLAGS_EFI # Compiler flags to add when building EFI app +export CFLAGS_NON_EFI # Compiler flags to remove when building EFI app +export EFI_TARGET # binutils target if EFI is natively supported + # If board code explicitly specified LDSCRIPT or CONFIG_SYS_LDSCRIPT, use # that (or fail if absent). Otherwise, search for a linker script in a # standard location. -- cgit v0.10.2 From c7ae3dfdccc171543804d6577ee41ab03e7a09bc Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 7 Nov 2016 08:47:08 -0700 Subject: efi: Add support for a hello world test program It is useful to have a basic sanity check for EFI loader support. Add a 'bootefi hello' command which loads HelloWord.efi and runs it under U-Boot. Signed-off-by: Simon Glass [agraf: Fix documentation, add unfulfilled kconfig dep] Signed-off-by: Alexander Graf diff --git a/cmd/Kconfig b/cmd/Kconfig index e339d86..ebcfd6d 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -181,6 +181,15 @@ config CMD_BOOTEFI help Boot an EFI image from memory. +config CMD_BOOTEFI_HELLO + bool "Allow booting a standard EFI hello world for testing" + depends on CMD_BOOTEFI && NEED_CRT0_ENABLEMENT + help + This adds a standard EFI hello world application to U-Boot so that + it can be used with the 'bootefi hello' command. This is useful + for testing that EFI is working at a basic level, and for bringing + up EFI support on a new architecture. + config CMD_ELF bool "bootelf, bootvx" default y diff --git a/cmd/bootefi.c b/cmd/bootefi.c index 3ab256e..ae1b713 100644 --- a/cmd/bootefi.c +++ b/cmd/bootefi.c @@ -239,13 +239,23 @@ static int do_bootefi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) if (argc < 2) return CMD_RET_USAGE; - saddr = argv[1]; +#ifdef CONFIG_CMD_BOOTEFI_HELLO + if (!strcmp(argv[1], "hello")) { + ulong size = __efi_hello_world_end - __efi_hello_world_begin; - addr = simple_strtoul(saddr, NULL, 16); + addr = CONFIG_SYS_LOAD_ADDR; + memcpy((char *)addr, __efi_hello_world_begin, size); + } else +#endif + { + saddr = argv[1]; - if (argc > 2) { - sfdt = argv[2]; - fdt_addr = simple_strtoul(sfdt, NULL, 16); + addr = simple_strtoul(saddr, NULL, 16); + + if (argc > 2) { + sfdt = argv[2]; + fdt_addr = simple_strtoul(sfdt, NULL, 16); + } } printf("## Starting EFI application at %08lx ...\n", addr); @@ -263,7 +273,12 @@ static char bootefi_help_text[] = " [fdt address]\n" " - boot EFI payload stored at address .\n" " If specified, the device tree located at gets\n" - " exposed as EFI configuration table.\n"; + " exposed as EFI configuration table.\n" +#ifdef CONFIG_CMD_BOOTEFI_HELLO + "hello\n" + " - boot a sample Hello World application stored within U-Boot" +#endif + ; #endif U_BOOT_CMD( diff --git a/doc/README.efi b/doc/README.efi index 1fd3f00..66259f3 100644 --- a/doc/README.efi +++ b/doc/README.efi @@ -310,6 +310,20 @@ Removable media booting (search for /efi/boot/boota{a64,arm}.efi) is supported. Simple use cases like "Plug this SD card into my ARM device and it just boots into grub which boots into Linux", work very well. + +Running HelloWord.efi +--------------------- + +You can run a simple 'hello world' EFI program in U-Boot. +Enable the option CONFIG_CMD_BOOTEFI_HELLO. + +Then you can boot into U-Boot and type: + + > bootefi hello + +The 'hello world EFI' program will then run, print a message and exit. + + Future work ----------- diff --git a/include/asm-generic/sections.h b/include/asm-generic/sections.h index d69bc60..daf021b 100644 --- a/include/asm-generic/sections.h +++ b/include/asm-generic/sections.h @@ -22,6 +22,8 @@ extern char __kprobes_text_start[], __kprobes_text_end[]; extern char __entry_text_start[], __entry_text_end[]; extern char __initdata_begin[], __initdata_end[]; extern char __start_rodata[], __end_rodata[]; +extern char __efi_hello_world_begin[]; +extern char __efi_hello_world_end[]; /* Start and end of .ctors section - used for constructor calls. */ extern char __ctors_start[], __ctors_end[]; diff --git a/lib/efi_loader/Makefile b/lib/efi_loader/Makefile index 12159dd..f466408 100644 --- a/lib/efi_loader/Makefile +++ b/lib/efi_loader/Makefile @@ -7,6 +7,10 @@ # This file only gets included with CONFIG_EFI_LOADER set, so all # object inclusion implicitly depends on it +CFLAGS_helloworld.o := $(CFLAGS_EFI) +CFLAGS_REMOVE_helloworld.o := $(CFLAGS_NON_EFI) + +obj-$(CONFIG_CMD_BOOTEFI_HELLO) += helloworld_efi.o obj-y += efi_image_loader.o efi_boottime.o efi_runtime.o efi_console.o obj-y += efi_memory.o obj-$(CONFIG_LCD) += efi_gop.o diff --git a/lib/efi_loader/helloworld.c b/lib/efi_loader/helloworld.c new file mode 100644 index 0000000..03e65ab --- /dev/null +++ b/lib/efi_loader/helloworld.c @@ -0,0 +1,24 @@ +/* + * EFI hello world + * + * Copyright (c) 2016 Google, Inc + * Written by Simon Glass + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include + +efi_status_t EFIAPI efi_main(efi_handle_t handle, + struct efi_system_table *systable) +{ + struct efi_simple_text_output_protocol *con_out = systable->con_out; + struct efi_boot_services *boottime = systable->boottime; + + con_out->output_string(con_out, L"Hello, world!\n"); + boottime->exit(handle, 0, 0, NULL); + + return EFI_SUCCESS; +} diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 45a0e1d..956a8a9 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -321,6 +321,39 @@ cmd_S_ttf= \ $(obj)/%.S: $(src)/%.ttf $(call cmd,S_ttf) +# EFI Hello World application +# --------------------------------------------------------------------------- + +# Generate an assembly file to wrap the EFI app +cmd_S_efi= \ +( \ + echo '.section .rodata.efi.init,"a"'; \ + echo '.balign 16'; \ + echo '.global __efi_hello_world_begin'; \ + echo '__efi_hello_world_begin:'; \ + echo '.incbin "$<" '; \ + echo '__efi_hello_world_end:'; \ + echo '.global __efi_hello_world_end'; \ + echo '.balign 16'; \ +) > $@ + +$(obj)/%_efi.S: $(obj)/%.efi + $(call cmd,S_efi) + +$(obj)/%.efi: $(obj)/%.so + $(OBJCOPY) -j .header -j .text -j .sdata -j .data -j .dynamic \ + -j .dynsym -j .rel* -j .rela* -j .reloc \ + $(if $(EFI_TARGET),$(EFI_TARGET),-O binary) $^ $@ + +EFI_LDS_PATH = $(srctree)/arch/$(ARCH)/lib/$(EFI_LDS) + +$(obj)/helloworld.so: $(EFI_LDS_PATH) + +$(obj)/helloworld.so: $(obj)/helloworld.o arch/$(ARCH)/lib/$(EFI_CRT0) \ + arch/$(ARCH)/lib/$(EFI_RELOC) + $(LD) -nostdlib -znocombreloc -T $(EFI_LDS_PATH) -shared -Bsymbolic \ + $^ -o $@ + # ACPI # --------------------------------------------------------------------------- quiet_cmd_acpi_c_asl= ASL $< -- cgit v0.10.2 From c70f74a081c2005b0a4749cf8762fc14b7369ddb Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 7 Nov 2016 08:47:09 -0700 Subject: elf: arm: Add a few ARM relocation types Rather than hard-coding the relocation type, add it to the ELF header file and use it from there. Signed-off-by: Simon Glass Signed-off-by: Alexander Graf diff --git a/arch/arm/lib/relocate.S b/arch/arm/lib/relocate.S index 475d503..a6fb07c 100644 --- a/arch/arm/lib/relocate.S +++ b/arch/arm/lib/relocate.S @@ -8,6 +8,7 @@ #include #include +#include #include #ifdef CONFIG_CPU_V7M #include @@ -96,7 +97,7 @@ copy_loop: fixloop: ldmia r2!, {r0-r1} /* (r0,r1) <- (SRC location,fixup) */ and r1, r1, #0xff - cmp r1, #23 /* relative fixup? */ + cmp r1, #R_ARM_RELATIVE bne fixnext /* relative fix: increase location by offset */ diff --git a/arch/arm/lib/relocate_64.S b/arch/arm/lib/relocate_64.S index 5c51cae..242e56e 100644 --- a/arch/arm/lib/relocate_64.S +++ b/arch/arm/lib/relocate_64.S @@ -10,6 +10,7 @@ #include #include +#include #include #include @@ -47,7 +48,7 @@ fixloop: ldp x0, x1, [x2], #16 /* (x0,x1) <- (SRC location, fixup) */ ldr x4, [x2], #8 /* x4 <- addend */ and x1, x1, #0xffffffff - cmp x1, #1027 /* relative fixup? */ + cmp x1, #R_AARCH64_RELATIVE bne fixnext /* relative fix: store addend plus offset at dest location */ diff --git a/include/elf.h b/include/elf.h index bcc5eb7..aaecac7 100644 --- a/include/elf.h +++ b/include/elf.h @@ -13,6 +13,7 @@ #ifndef _ELF_H #define _ELF_H +#ifndef __ASSEMBLER__ #include "compiler.h" /* @@ -517,6 +518,8 @@ unsigned long elf_hash(const unsigned char *name); #define ELF_TARG_VER 1 /* The ver for which this code is intended */ +#endif /* __ASSEMBLER */ + /* * XXX - PowerPC defines really don't belong in here, * but we'll put them in for simplicity. @@ -602,6 +605,16 @@ unsigned long elf_hash(const unsigned char *name); that may still be in object files. */ #define R_PPC_TOC16 255 + /* ARM relocs */ +#define R_ARM_NONE 0 /* No reloc */ +#define R_ARM_RELATIVE 23 /* Adjust by program base */ + +/* AArch64 relocs */ +#define R_AARCH64_NONE 0 /* No relocation. */ +#define R_AARCH64_RELATIVE 1027 /* Adjust by program base. */ + +#ifndef __ASSEMBLER__ int valid_elf_image(unsigned long addr); +#endif #endif /* _ELF_H */ -- cgit v0.10.2 From dd46eef2f6e0b7dce2e6bcd85ed8caca5a6b606c Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 7 Nov 2016 08:47:10 -0700 Subject: efi: arm: Add EFI app support Add support for EFI apps on ARM. This includes start-up and relocation code, plus a link script and some compiler setting changes. Signed-off-by: Simon Glass [agraf: Remove whitespace change, add kconfig dep] Signed-off-by: Alexander Graf diff --git a/arch/arm/config.mk b/arch/arm/config.mk index 542b897..27914a9 100644 --- a/arch/arm/config.mk +++ b/arch/arm/config.mk @@ -13,6 +13,9 @@ CONFIG_STANDALONE_LOAD_ADDR = 0xc100000 endif endif +CFLAGS_NON_EFI := -fno-pic -ffixed-r9 -ffunction-sections -fdata-sections +CFLAGS_EFI := -fpic -fshort-wchar + LDFLAGS_FINAL += --gc-sections PLATFORM_RELFLAGS += -ffunction-sections -fdata-sections \ -fno-common -ffixed-r9 @@ -148,3 +151,7 @@ ifneq ($(CONFIG_VF610),) ALL-y += u-boot.vyb endif endif + +EFI_LDS := elf_arm_efi.lds +EFI_CRT0 := crt0_arm_efi.o +EFI_RELOC := reloc_arm_efi.o diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile index caa62c6..a812306 100644 --- a/arch/arm/lib/Makefile +++ b/arch/arm/lib/Makefile @@ -92,3 +92,13 @@ AFLAGS_memset.o := -DMEMSET_NO_THUMB_BUILD AFLAGS_memcpy.o := -DMEMCPY_NO_THUMB_BUILD endif endif + +# For building EFI apps +CFLAGS_$(EFI_CRT0) := $(CFLAGS_EFI) +CFLAGS_REMOVE_$(EFI_CRT0) := $(CFLAGS_NON_EFI) + +CFLAGS_$(EFI_RELOC) := $(CFLAGS_EFI) +CFLAGS_REMOVE_$(EFI_RELOC) := $(CFLAGS_NON_EFI) + +extra-$(CONFIG_CMD_BOOTEFI_HELLO) += $(EFI_CRT0) $(EFI_RELOC) +extra-$(CONFIG_EFI) += $(EFI_CRT0) $(EFI_RELOC) diff --git a/arch/arm/lib/crt0_arm_efi.S b/arch/arm/lib/crt0_arm_efi.S new file mode 100644 index 0000000..967c885 --- /dev/null +++ b/arch/arm/lib/crt0_arm_efi.S @@ -0,0 +1,138 @@ +/* + * crt0-efi-arm.S - PE/COFF header for ARM EFI applications + * + * Copright (C) 2014 Linaro Ltd. + * + * SPDX-License-Identifier: GPL-2.0+ BSD-2-Clause + * + * This file is taken and modified from the gnu-efi project. + */ + + .section .text.head + + /* + * Magic "MZ" signature for PE/COFF + */ + .globl image_base +image_base: + .ascii "MZ" + .skip 58 /* 'MZ' + pad + offset == 64 */ + .long pe_header - image_base /* Offset to the PE header */ +pe_header: + .ascii "PE" + .short 0 +coff_header: + .short 0x1c2 /* Mixed ARM/Thumb */ + .short 2 /* nr_sections */ + .long 0 /* TimeDateStamp */ + .long 0 /* PointerToSymbolTable */ + .long 1 /* NumberOfSymbols */ + .short section_table - optional_header /* SizeOfOptionalHeader */ + /* + * Characteristics: IMAGE_FILE_32BIT_MACHINE | + * IMAGE_FILE_DEBUG_STRIPPED | IMAGE_FILE_EXECUTABLE_IMAGE | + * IMAGE_FILE_LINE_NUMS_STRIPPED + */ + .short 0x306 +optional_header: + .short 0x10b /* PE32+ format */ + .byte 0x02 /* MajorLinkerVersion */ + .byte 0x14 /* MinorLinkerVersion */ + .long _edata - _start /* SizeOfCode */ + .long 0 /* SizeOfInitializedData */ + .long 0 /* SizeOfUninitializedData */ + .long _start - image_base /* AddressOfEntryPoint */ + .long _start - image_base /* BaseOfCode */ + .long 0 /* BaseOfData */ + +extra_header_fields: + .long 0 /* image_base */ + .long 0x20 /* SectionAlignment */ + .long 0x8 /* FileAlignment */ + .short 0 /* MajorOperatingSystemVersion */ + .short 0 /* MinorOperatingSystemVersion */ + .short 0 /* MajorImageVersion */ + .short 0 /* MinorImageVersion */ + .short 0 /* MajorSubsystemVersion */ + .short 0 /* MinorSubsystemVersion */ + .long 0 /* Win32VersionValue */ + + .long _edata - image_base /* SizeOfImage */ + + /* + * Everything before the kernel image is considered part of the header + */ + .long _start - image_base /* SizeOfHeaders */ + .long 0 /* CheckSum */ + .short EFI_SUBSYSTEM /* Subsystem */ + .short 0 /* DllCharacteristics */ + .long 0 /* SizeOfStackReserve */ + .long 0 /* SizeOfStackCommit */ + .long 0 /* SizeOfHeapReserve */ + .long 0 /* SizeOfHeapCommit */ + .long 0 /* LoaderFlags */ + .long 0x6 /* NumberOfRvaAndSizes */ + + .quad 0 /* ExportTable */ + .quad 0 /* ImportTable */ + .quad 0 /* ResourceTable */ + .quad 0 /* ExceptionTable */ + .quad 0 /* CertificationTable */ + .quad 0 /* BaseRelocationTable */ + +section_table: + + /* + * The EFI application loader requires a relocation section + * because EFI applications must be relocatable. This is a + * dummy section as far as we are concerned. + */ + .ascii ".reloc" + .byte 0 + .byte 0 /* end of 0 padding of section name */ + .long 0 + .long 0 + .long 0 /* SizeOfRawData */ + .long 0 /* PointerToRawData */ + .long 0 /* PointerToRelocations */ + .long 0 /* PointerToLineNumbers */ + .short 0 /* NumberOfRelocations */ + .short 0 /* NumberOfLineNumbers */ + .long 0x42100040 /* Characteristics (section flags) */ + + .ascii ".text" + .byte 0 + .byte 0 + .byte 0 /* end of 0 padding of section name */ + .long _edata - _start /* VirtualSize */ + .long _start - image_base /* VirtualAddress */ + .long _edata - _start /* SizeOfRawData */ + .long _start - image_base /* PointerToRawData */ + + .long 0 /* PointerToRelocations (0 for executables) */ + .long 0 /* PointerToLineNumbers (0 for executables) */ + .short 0 /* NumberOfRelocations (0 for executables) */ + .short 0 /* NumberOfLineNumbers (0 for executables) */ + .long 0xe0500020 /* Characteristics (section flags) */ + +_start: + stmfd sp!, {r0-r2, lr} + + mov r2, r0 + mov r3, r1 + adr r1, .L_DYNAMIC + ldr r0, [r1] + add r1, r0, r1 + adr r0, image_base + bl _relocate + teq r0, #0 + bne 0f + + ldmfd sp, {r0-r1} + bl efi_main + +0: add sp, sp, #12 + ldr pc, [sp], #4 + +.L_DYNAMIC: + .word _DYNAMIC - . diff --git a/arch/arm/lib/elf_arm_efi.lds b/arch/arm/lib/elf_arm_efi.lds new file mode 100644 index 0000000..59f66a1 --- /dev/null +++ b/arch/arm/lib/elf_arm_efi.lds @@ -0,0 +1,70 @@ +/* + * U-Boot ARM EFI linker script + * + * SPDX-License-Identifier: BSD-2-Clause + * + * Modified from elf_arm_efi.lds in gnu-efi + */ + +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +ENTRY(_start) +SECTIONS +{ + .text 0x0 : { + _text = .; + *(.text.head) + *(.text) + *(.text.*) + *(.gnu.linkonce.t.*) + *(.srodata) + *(.rodata*) + . = ALIGN(16); + } + _etext = .; + _text_size = . - _text; + .dynamic : { *(.dynamic) } + .data : { + _data = .; + *(.sdata) + *(.data) + *(.data1) + *(.data.*) + *(.got.plt) + *(.got) + + /* + * The EFI loader doesn't seem to like a .bss section, so we + * stick it all into .data: + */ + . = ALIGN(16); + _bss = .; + *(.sbss) + *(.scommon) + *(.dynbss) + *(.bss) + *(.bss.*) + *(COMMON) + . = ALIGN(16); + _bss_end = .; + _edata = .; + } + .rel.dyn : { *(.rel.dyn) } + .rel.plt : { *(.rel.plt) } + .rel.got : { *(.rel.got) } + .rel.data : { *(.rel.data) *(.rel.data*) } + _data_size = . - _etext; + + . = ALIGN(4096); + .dynsym : { *(.dynsym) } + . = ALIGN(4096); + .dynstr : { *(.dynstr) } + . = ALIGN(4096); + .note.gnu.build-id : { *(.note.gnu.build-id) } + /DISCARD/ : { + *(.rel.reloc) + *(.eh_frame) + *(.note.GNU-stack) + } + .comment 0 : { *(.comment) } +} diff --git a/arch/arm/lib/reloc_arm_efi.c b/arch/arm/lib/reloc_arm_efi.c new file mode 100644 index 0000000..d2f96ee --- /dev/null +++ b/arch/arm/lib/reloc_arm_efi.c @@ -0,0 +1,66 @@ +/* + * reloc_arm.c - position-independent ARM ELF shared object relocator + * + * Copyright (C) 2014 Linaro Ltd. + * Copyright (C) 1999 Hewlett-Packard Co. + * Contributed by David Mosberger . + * + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * This file is taken and modified from the gnu-efi project. + */ + +#include +#include + +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; + ulong *addr; + int i; + + for (i = 0; dyn[i].d_tag != DT_NULL; ++i) { + switch (dyn[i].d_tag) { + case DT_REL: + rel = (Elf32_Rel *)((ulong)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; + 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_ARM_NONE: + break; + case R_ARM_RELATIVE: + addr = (ulong *)(ldbase + rel->r_offset); + *addr += ldbase; + break; + default: + break; + } + rel = (Elf32_Rel *)((char *)rel + relent); + relsz -= relent; + } + + return EFI_SUCCESS; +} diff --git a/cmd/Kconfig b/cmd/Kconfig index ebcfd6d..a1ce4b7 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -183,7 +183,7 @@ config CMD_BOOTEFI config CMD_BOOTEFI_HELLO bool "Allow booting a standard EFI hello world for testing" - depends on CMD_BOOTEFI && NEED_CRT0_ENABLEMENT + depends on CMD_BOOTEFI && ARM && !ARM64 help This adds a standard EFI hello world application to U-Boot so that it can be used with the 'bootefi hello' command. This is useful -- cgit v0.10.2 From c65d76ed5f81e54d32f280116caaf45119e4670d Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 7 Nov 2016 08:47:11 -0700 Subject: efi: arm: Add aarch64 EFI app support Add support for EFI apps on aarch64. This includes start-up and relocation code plus a link script. Signed-off-by: Simon Glass [agraf: add kconfig dep] Signed-off-by: Alexander Graf diff --git a/arch/arm/cpu/armv8/config.mk b/arch/arm/cpu/armv8/config.mk index 6850258..27b66d4 100644 --- a/arch/arm/cpu/armv8/config.mk +++ b/arch/arm/cpu/armv8/config.mk @@ -8,3 +8,7 @@ PLATFORM_RELFLAGS += -fno-common -ffixed-x18 PF_NO_UNALIGNED := $(call cc-option, -mstrict-align) PLATFORM_CPPFLAGS += $(PF_NO_UNALIGNED) + +EFI_LDS := elf_aarch64_efi.lds +EFI_CRT0 := crt0_aarch64_efi.o +EFI_RELOC := reloc_aarch64_efi.o diff --git a/arch/arm/lib/crt0_aarch64_efi.S b/arch/arm/lib/crt0_aarch64_efi.S new file mode 100644 index 0000000..5205646 --- /dev/null +++ b/arch/arm/lib/crt0_aarch64_efi.S @@ -0,0 +1,135 @@ +/* + * crt0-efi-aarch64.S - PE/COFF header for aarch64 EFI applications + * + * Copright (C) 2014 Linaro Ltd. + * + * SPDX-License-Identifier: GPL-2.0+ BSD-2-Clause + * + * This file is taken and modified from the gnu-efi project. + */ + + .section .text.head + + /* + * Magic "MZ" signature for PE/COFF + */ + .globl ImageBase +ImageBase: + .ascii "MZ" + .skip 58 /* 'MZ' + pad + offset == 64 */ + .long pe_header - ImageBase /* Offset to the PE header */ +pe_header: + .ascii "PE" + .short 0 +coff_header: + .short 0xaa64 /* AArch64 */ + .short 2 /* nr_sections */ + .long 0 /* TimeDateStamp */ + .long 0 /* PointerToSymbolTable */ + .long 1 /* NumberOfSymbols */ + .short section_table - optional_header /* SizeOfOptionalHeader */ + /* + * Characteristics: IMAGE_FILE_DEBUG_STRIPPED | + * IMAGE_FILE_EXECUTABLE_IMAGE | IMAGE_FILE_LINE_NUMS_STRIPPED + */ + .short 0x206 +optional_header: + .short 0x20b /* PE32+ format */ + .byte 0x02 /* MajorLinkerVersion */ + .byte 0x14 /* MinorLinkerVersion */ + .long _edata - _start /* SizeOfCode */ + .long 0 /* SizeOfInitializedData */ + .long 0 /* SizeOfUninitializedData */ + .long _start - ImageBase /* AddressOfEntryPoint */ + .long _start - ImageBase /* BaseOfCode */ + +extra_header_fields: + .quad 0 /* ImageBase */ + .long 0x20 /* SectionAlignment */ + .long 0x8 /* FileAlignment */ + .short 0 /* MajorOperatingSystemVersion */ + .short 0 /* MinorOperatingSystemVersion */ + .short 0 /* MajorImageVersion */ + .short 0 /* MinorImageVersion */ + .short 0 /* MajorSubsystemVersion */ + .short 0 /* MinorSubsystemVersion */ + .long 0 /* Win32VersionValue */ + + .long _edata - ImageBase /* SizeOfImage */ + + /* + * Everything before the kernel image is considered part of the header + */ + .long _start - ImageBase /* SizeOfHeaders */ + .long 0 /* CheckSum */ + .short EFI_SUBSYSTEM /* Subsystem */ + .short 0 /* DllCharacteristics */ + .quad 0 /* SizeOfStackReserve */ + .quad 0 /* SizeOfStackCommit */ + .quad 0 /* SizeOfHeapReserve */ + .quad 0 /* SizeOfHeapCommit */ + .long 0 /* LoaderFlags */ + .long 0x6 /* NumberOfRvaAndSizes */ + + .quad 0 /* ExportTable */ + .quad 0 /* ImportTable */ + .quad 0 /* ResourceTable */ + .quad 0 /* ExceptionTable */ + .quad 0 /* CertificationTable */ + .quad 0 /* BaseRelocationTable */ + + /* Section table */ +section_table: + + /* + * The EFI application loader requires a relocation section + * because EFI applications must be relocatable. This is a + * dummy section as far as we are concerned. + */ + .ascii ".reloc" + .byte 0 + .byte 0 /* end of 0 padding of section name */ + .long 0 + .long 0 + .long 0 /* SizeOfRawData */ + .long 0 /* PointerToRawData */ + .long 0 /* PointerToRelocations */ + .long 0 /* PointerToLineNumbers */ + .short 0 /* NumberOfRelocations */ + .short 0 /* NumberOfLineNumbers */ + .long 0x42100040 /* Characteristics (section flags) */ + + + .ascii ".text" + .byte 0 + .byte 0 + .byte 0 /* end of 0 padding of section name */ + .long _edata - _start /* VirtualSize */ + .long _start - ImageBase /* VirtualAddress */ + .long _edata - _start /* SizeOfRawData */ + .long _start - ImageBase /* PointerToRawData */ + + .long 0 /* PointerToRelocations (0 for executables) */ + .long 0 /* PointerToLineNumbers (0 for executables) */ + .short 0 /* NumberOfRelocations (0 for executables) */ + .short 0 /* NumberOfLineNumbers (0 for executables) */ + .long 0xe0500020 /* Characteristics (section flags) */ + +_start: + stp x29, x30, [sp, #-32]! + mov x29, sp + + stp x0, x1, [sp, #16] + mov x2, x0 + mov x3, x1 + adr x0, ImageBase + adrp x1, _DYNAMIC + add x1, x1, #:lo12:_DYNAMIC + bl _relocate + cbnz x0, 0f + + ldp x0, x1, [sp, #16] + bl efi_main + +0: ldp x29, x30, [sp], #32 + ret diff --git a/arch/arm/lib/elf_aarch64_efi.lds b/arch/arm/lib/elf_aarch64_efi.lds new file mode 100644 index 0000000..47cce1d --- /dev/null +++ b/arch/arm/lib/elf_aarch64_efi.lds @@ -0,0 +1,70 @@ +/* + * U-Boot aarch64 EFI linker script + * + * SPDX-License-Identifier: BSD-2-Clause + * + * Modified from elf_aarch64_efi.lds in gnu-efi + */ + +OUTPUT_FORMAT("elf64-littleaarch64", "elf64-littleaarch64", "elf64-littleaarch64") +OUTPUT_ARCH(aarch64) +ENTRY(_start) +SECTIONS +{ + .text 0x0 : { + _text = .; + *(.text.head) + *(.text) + *(.text.*) + *(.gnu.linkonce.t.*) + *(.srodata) + *(.rodata*) + . = ALIGN(16); + } + _etext = .; + _text_size = . - _text; + .dynamic : { *(.dynamic) } + .data : { + _data = .; + *(.sdata) + *(.data) + *(.data1) + *(.data.*) + *(.got.plt) + *(.got) + + /* + * The EFI loader doesn't seem to like a .bss section, so we + * stick it all into .data: + */ + . = ALIGN(16); + _bss = .; + *(.sbss) + *(.scommon) + *(.dynbss) + *(.bss) + *(.bss.*) + *(COMMON) + . = ALIGN(16); + _bss_end = .; + _edata = .; + } + .rela.dyn : { *(.rela.dyn) } + .rela.plt : { *(.rela.plt) } + .rela.got : { *(.rela.got) } + .rela.data : { *(.rela.data) *(.rela.data*) } + _data_size = . - _etext; + + . = ALIGN(4096); + .dynsym : { *(.dynsym) } + . = ALIGN(4096); + .dynstr : { *(.dynstr) } + . = ALIGN(4096); + .note.gnu.build-id : { *(.note.gnu.build-id) } + /DISCARD/ : { + *(.rel.reloc) + *(.eh_frame) + *(.note.GNU-stack) + } + .comment 0 : { *(.comment) } +} diff --git a/arch/arm/lib/reloc_aarch64_efi.c b/arch/arm/lib/reloc_aarch64_efi.c new file mode 100644 index 0000000..38c13d3 --- /dev/null +++ b/arch/arm/lib/reloc_aarch64_efi.c @@ -0,0 +1,87 @@ +/* reloc_aarch64.c - position independent x86 ELF shared object relocator + Copyright (C) 2014 Linaro Ltd. + Copyright (C) 1999 Hewlett-Packard Co. + Contributed by David Mosberger . + + 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 + +#include + +efi_status_t _relocate(long ldbase, Elf64_Dyn *dyn, efi_handle_t image, + struct efi_system_table *systab) +{ + long relsz = 0, relent = 0; + Elf64_Rela *rel = 0; + unsigned long *addr; + int i; + + for (i = 0; dyn[i].d_tag != DT_NULL; ++i) { + switch (dyn[i].d_tag) { + case DT_RELA: + rel = (Elf64_Rela *)((ulong)dyn[i].d_un.d_ptr + ldbase); + break; + case DT_RELASZ: + relsz = dyn[i].d_un.d_val; + break; + case DT_RELAENT: + relent = dyn[i].d_un.d_val; + 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 (ELF64_R_TYPE(rel->r_info)) { + case R_AARCH64_NONE: + break; + case R_AARCH64_RELATIVE: + addr = (ulong *)(ldbase + rel->r_offset); + *addr = ldbase + rel->r_addend; + break; + default: + break; + } + rel = (Elf64_Rela *)((char *)rel + relent); + relsz -= relent; + } + return EFI_SUCCESS; +} diff --git a/cmd/Kconfig b/cmd/Kconfig index a1ce4b7..501ac17 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -183,7 +183,7 @@ config CMD_BOOTEFI config CMD_BOOTEFI_HELLO bool "Allow booting a standard EFI hello world for testing" - depends on CMD_BOOTEFI && ARM && !ARM64 + depends on CMD_BOOTEFI && ARM help This adds a standard EFI hello world application to U-Boot so that it can be used with the 'bootefi hello' command. This is useful -- cgit v0.10.2 From d36badfdc6a47ae1377dde809c9ea6f6249f5c15 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 7 Nov 2016 08:47:13 -0700 Subject: x86: Move efi .lds files into the 'lib' directory These files now need to be in a standard place so that they can be located by generic Makefile rules. Move them to the 'lib' directory. Signed-off-by: Simon Glass Signed-off-by: Alexander Graf diff --git a/arch/x86/config.mk b/arch/x86/config.mk index d7addd8..a17abbb 100644 --- a/arch/x86/config.mk +++ b/arch/x86/config.mk @@ -45,7 +45,7 @@ endif EFIPAYLOAD_BFDARCH = i386 -LDSCRIPT_EFI := $(srctree)/$(CPUDIR)/efi/elf_$(EFIARCH)_efi.lds +LDSCRIPT_EFI := $(srctree)/arch/x86/lib/elf_$(EFIARCH)_efi.lds EFISTUB := crt0-efi-$(EFIARCH).o reloc_$(EFIARCH).o OBJCOPYFLAGS_EFI += --target=efi-app-$(EFIARCH) diff --git a/arch/x86/cpu/efi/elf_ia32_efi.lds b/arch/x86/cpu/efi/elf_ia32_efi.lds deleted file mode 100644 index cd3b0a9..0000000 --- a/arch/x86/cpu/efi/elf_ia32_efi.lds +++ /dev/null @@ -1,94 +0,0 @@ -/* - * U-Boot EFI linker script - * - * SPDX-License-Identifier: BSD-2-Clause - * - * Modified from usr/lib32/elf_ia32_efi.lds in gnu-efi - */ - -#include - -OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") -OUTPUT_ARCH(i386) -ENTRY(_start) -SECTIONS -{ - image_base = .; - .hash : { *(.hash) } /* this MUST come first, EFI expects it */ - . = 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); - *(SORT(.u_boot_list*)); - . = ALIGN(8); - *(.dtb*); - } - - . = ALIGN(4096); - .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/elf_x86_64_efi.lds b/arch/x86/cpu/efi/elf_x86_64_efi.lds deleted file mode 100644 index 9d9f057..0000000 --- a/arch/x86/cpu/efi/elf_x86_64_efi.lds +++ /dev/null @@ -1,83 +0,0 @@ -/* - * U-Boot EFI linker script - * - * SPDX-License-Identifier: BSD-2-Clause - * - * Modified from usr/lib32/elf_x86_64_efi.lds in gnu-efi - */ - -#include - -OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64") -OUTPUT_ARCH(i386:x86-64) -ENTRY(_start) -SECTIONS -{ - image_base = .; - .hash : { *(.hash) } /* this MUST come first, EFI expects it */ - . = ALIGN(4096); - .eh_frame : { - *(.eh_frame) - } - - . = ALIGN(4096); - - .text : { - *(.text) - *(.text.*) - *(.gnu.linkonce.t.*) - } - - . = ALIGN(4096); - - .reloc : { - *(.reloc) - } - - . = ALIGN(4096); - - .data : { - *(.rodata*) - *(.got.plt) - *(.got) - *(.data*) - *(.sdata) - /* the EFI loader doesn't seem to like a .bss section, so we stick - * it all into .data: */ - *(.sbss) - *(.scommon) - *(.dynbss) - *(.bss) - *(COMMON) - *(.rel.local) - - /* U-Boot lists and device tree */ - . = ALIGN(8); - *(SORT(.u_boot_list*)); - . = ALIGN(8); - *(.dtb*); - } - - . = ALIGN(4096); - .dynamic : { *(.dynamic) } - . = ALIGN(4096); - - .rela : { - *(.rela.data*) - *(.rela.got) - *(.rela.stab) - } - - . = ALIGN(4096); - .dynsym : { *(.dynsym) } - . = ALIGN(4096); - .dynstr : { *(.dynstr) } - . = ALIGN(4096); - .ignored.reloc : { - *(.rela.reloc) - *(.eh_frame) - *(.note.GNU-stack) - } - - .comment 0 : { *(.comment) } -} diff --git a/arch/x86/lib/elf_ia32_efi.lds b/arch/x86/lib/elf_ia32_efi.lds new file mode 100644 index 0000000..cd3b0a9 --- /dev/null +++ b/arch/x86/lib/elf_ia32_efi.lds @@ -0,0 +1,94 @@ +/* + * U-Boot EFI linker script + * + * SPDX-License-Identifier: BSD-2-Clause + * + * Modified from usr/lib32/elf_ia32_efi.lds in gnu-efi + */ + +#include + +OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") +OUTPUT_ARCH(i386) +ENTRY(_start) +SECTIONS +{ + image_base = .; + .hash : { *(.hash) } /* this MUST come first, EFI expects it */ + . = 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); + *(SORT(.u_boot_list*)); + . = ALIGN(8); + *(.dtb*); + } + + . = ALIGN(4096); + .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/lib/elf_x86_64_efi.lds b/arch/x86/lib/elf_x86_64_efi.lds new file mode 100644 index 0000000..9d9f057 --- /dev/null +++ b/arch/x86/lib/elf_x86_64_efi.lds @@ -0,0 +1,83 @@ +/* + * U-Boot EFI linker script + * + * SPDX-License-Identifier: BSD-2-Clause + * + * Modified from usr/lib32/elf_x86_64_efi.lds in gnu-efi + */ + +#include + +OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64") +OUTPUT_ARCH(i386:x86-64) +ENTRY(_start) +SECTIONS +{ + image_base = .; + .hash : { *(.hash) } /* this MUST come first, EFI expects it */ + . = ALIGN(4096); + .eh_frame : { + *(.eh_frame) + } + + . = ALIGN(4096); + + .text : { + *(.text) + *(.text.*) + *(.gnu.linkonce.t.*) + } + + . = ALIGN(4096); + + .reloc : { + *(.reloc) + } + + . = ALIGN(4096); + + .data : { + *(.rodata*) + *(.got.plt) + *(.got) + *(.data*) + *(.sdata) + /* the EFI loader doesn't seem to like a .bss section, so we stick + * it all into .data: */ + *(.sbss) + *(.scommon) + *(.dynbss) + *(.bss) + *(COMMON) + *(.rel.local) + + /* U-Boot lists and device tree */ + . = ALIGN(8); + *(SORT(.u_boot_list*)); + . = ALIGN(8); + *(.dtb*); + } + + . = ALIGN(4096); + .dynamic : { *(.dynamic) } + . = ALIGN(4096); + + .rela : { + *(.rela.data*) + *(.rela.got) + *(.rela.stab) + } + + . = ALIGN(4096); + .dynsym : { *(.dynsym) } + . = ALIGN(4096); + .dynstr : { *(.dynstr) } + . = ALIGN(4096); + .ignored.reloc : { + *(.rela.reloc) + *(.eh_frame) + *(.note.GNU-stack) + } + + .comment 0 : { *(.comment) } +} -- cgit v0.10.2 From 2dcd4e9ee1b6dc0f0ba1d89a7af3987ea47dda23 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 7 Nov 2016 08:47:14 -0700 Subject: x86: Move efi .S files into the 'lib' directory These files now need to be in a standard place so that they can be located by generic Makefile rules. Move them to the 'lib' directory. Signed-off-by: Simon Glass Signed-off-by: Alexander Graf diff --git a/Makefile b/Makefile index bb108d4..96ddc59 100644 --- a/Makefile +++ b/Makefile @@ -1140,7 +1140,7 @@ quiet_cmd_u-boot_payload ?= LD $@ cmd_u-boot_payload ?= $(LD) $(LDFLAGS_EFI_PAYLOAD) -o $@ \ -T u-boot-payload.lds arch/x86/cpu/call32.o \ lib/efi/efi.o lib/efi/efi_stub.o u-boot.bin.o \ - $(addprefix arch/$(ARCH)/lib/efi/,$(EFISTUB)) + $(addprefix arch/$(ARCH)/lib/,$(EFISTUB)) u-boot-payload: u-boot.bin.o u-boot-payload.lds FORCE $(call if_changed,u-boot_payload) diff --git a/arch/x86/config.mk b/arch/x86/config.mk index a17abbb..12a8d73 100644 --- a/arch/x86/config.mk +++ b/arch/x86/config.mk @@ -46,7 +46,7 @@ endif EFIPAYLOAD_BFDARCH = i386 LDSCRIPT_EFI := $(srctree)/arch/x86/lib/elf_$(EFIARCH)_efi.lds -EFISTUB := crt0-efi-$(EFIARCH).o reloc_$(EFIARCH).o +EFISTUB := crt0_$(EFIARCH)_efi.o reloc_$(EFIARCH)_efi.o OBJCOPYFLAGS_EFI += --target=efi-app-$(EFIARCH) CPPFLAGS_REMOVE_crt0-efi-$(EFIARCH).o += $(CFLAGS_NON_EFI) diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile index b9c2922..aad6555 100644 --- a/arch/x86/lib/Makefile +++ b/arch/x86/lib/Makefile @@ -44,3 +44,21 @@ NORMAL_LIBGCC = $(shell $(CC) $(PLATFORM_CPPFLAGS) -print-libgcc-file-name) OBJCOPYFLAGS := --prefix-symbols=__normal_ $(obj)/lib.a: $(NORMAL_LIBGCC) FORCE $(call if_changed,objcopy) + +obj-$(CONFIG_EFI_APP) += crt0_ia32_efi.o reloc_ia32_efi.o + +ifneq ($(CONFIG_EFI_STUB),) + +CFLAGS_REMOVE_reloc_ia32_efi.o += -mregparm=3 +CFLAGS_reloc_ia32_efi.o += -fpic -fshort-wchar + +# When building for 64-bit we must remove the i386-specific flags +CFLAGS_REMOVE_reloc_x86_64_efi.o += -mregparm=3 -march=i386 -m32 +CFLAGS_reloc_x86_64_efi.o += -fpic -fshort-wchar + +AFLAGS_REMOVE_crt0_x86_64_efi.o += -mregparm=3 -march=i386 -m32 +AFLAGS_crt0_x86_64_efi.o += -fpic -fshort-wchar + +extra-$(CONFIG_EFI_STUB_32BIT) += crt0_ia32_efi.o reloc_ia32_efi.o +extra-$(CONFIG_EFI_STUB_64BIT) += crt0_x86_64_efi.o reloc_x86_64_efi.o +endif diff --git a/arch/x86/lib/crt0_ia32_efi.S b/arch/x86/lib/crt0_ia32_efi.S new file mode 100644 index 0000000..30e5eb0 --- /dev/null +++ b/arch/x86/lib/crt0_ia32_efi.S @@ -0,0 +1,52 @@ +/* + * crt0-efi-ia32.S - x86 EFI startup code. + * + * Copyright (C) 1999 Hewlett-Packard Co. + * Contributed by David Mosberger . + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + + .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 $image_base-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_x86_64_efi.S b/arch/x86/lib/crt0_x86_64_efi.S new file mode 100644 index 0000000..c5cbf41 --- /dev/null +++ b/arch/x86/lib/crt0_x86_64_efi.S @@ -0,0 +1,51 @@ +/* + * crt0-efi-x86_64.S - x86_64 EFI startup code. + * Copyright (C) 1999 Hewlett-Packard Co. + * Contributed by David Mosberger . + * Copyright (C) 2005 Intel Co. + * Contributed by Fenghua Yu . + * + * All rights reserved. + * SPDX-License-Identifier: BSD-3-Clause + */ + .text + .align 4 + + .globl _start +_start: + subq $8, %rsp + pushq %rcx + pushq %rdx + +0: + lea image_base(%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/efi/Makefile b/arch/x86/lib/efi/Makefile index af4503e..43aadfc 100644 --- a/arch/x86/lib/efi/Makefile +++ b/arch/x86/lib/efi/Makefile @@ -7,21 +7,3 @@ obj-$(CONFIG_EFI_STUB) += car.o obj-$(CONFIG_EFI_STUB) += efi.o - -obj-$(CONFIG_EFI_APP) += crt0-efi-ia32.o reloc_ia32.o - -ifneq ($(CONFIG_EFI_STUB),) - -CFLAGS_REMOVE_reloc_ia32.o += -mregparm=3 -CFLAGS_reloc_ia32.o += -fpic -fshort-wchar - -# When building for 64-bit we must remove the i386-specific flags -CFLAGS_REMOVE_reloc_x86_64.o += -mregparm=3 -march=i386 -m32 -CFLAGS_reloc_x86_64.o += -fpic -fshort-wchar - -AFLAGS_REMOVE_crt0-efi-x86_64.o += -mregparm=3 -march=i386 -m32 -AFLAGS_crt0-efi-x86_64.o += -fpic -fshort-wchar - -extra-$(CONFIG_EFI_STUB_32BIT) += crt0-efi-ia32.o reloc_ia32.o -extra-$(CONFIG_EFI_STUB_64BIT) += crt0-efi-x86_64.o reloc_x86_64.o -endif diff --git a/arch/x86/lib/efi/crt0-efi-ia32.S b/arch/x86/lib/efi/crt0-efi-ia32.S deleted file mode 100644 index 30e5eb0..0000000 --- a/arch/x86/lib/efi/crt0-efi-ia32.S +++ /dev/null @@ -1,52 +0,0 @@ -/* - * crt0-efi-ia32.S - x86 EFI startup code. - * - * Copyright (C) 1999 Hewlett-Packard Co. - * Contributed by David Mosberger . - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - - .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 $image_base-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/efi/crt0-efi-x86_64.S b/arch/x86/lib/efi/crt0-efi-x86_64.S deleted file mode 100644 index c5cbf41..0000000 --- a/arch/x86/lib/efi/crt0-efi-x86_64.S +++ /dev/null @@ -1,51 +0,0 @@ -/* - * crt0-efi-x86_64.S - x86_64 EFI startup code. - * Copyright (C) 1999 Hewlett-Packard Co. - * Contributed by David Mosberger . - * Copyright (C) 2005 Intel Co. - * Contributed by Fenghua Yu . - * - * All rights reserved. - * SPDX-License-Identifier: BSD-3-Clause - */ - .text - .align 4 - - .globl _start -_start: - subq $8, %rsp - pushq %rcx - pushq %rdx - -0: - lea image_base(%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/efi/reloc_ia32.c b/arch/x86/lib/efi/reloc_ia32.c deleted file mode 100644 index 4d68255..0000000 --- a/arch/x86/lib/efi/reloc_ia32.c +++ /dev/null @@ -1,72 +0,0 @@ -/* - * reloc_ia32.c - position independent x86 ELF shared object relocator - * Copyright (C) 1999 Hewlett-Packard Co. - * Contributed by David Mosberger . - * - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include -#include -#include - -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; -} diff --git a/arch/x86/lib/efi/reloc_x86_64.c b/arch/x86/lib/efi/reloc_x86_64.c deleted file mode 100644 index 5f71f2a..0000000 --- a/arch/x86/lib/efi/reloc_x86_64.c +++ /dev/null @@ -1,66 +0,0 @@ -/* - * reloc_x86_64.c - position independent x86_64 ELF shared object relocator - * Copyright (C) 1999 Hewlett-Packard Co. - * Contributed by David Mosberger . - * Copyright (C) 2005 Intel Co. - * Contributed by Fenghua Yu . - * - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include -#include -#include - -efi_status_t _relocate(long ldbase, Elf64_Dyn *dyn, efi_handle_t image, - struct efi_system_table *systab) -{ - long relsz = 0, relent = 0; - Elf64_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_RELA: - rel = (Elf64_Rel *) - ((unsigned long)dyn[i].d_un.d_ptr + ldbase); - break; - case DT_RELASZ: - relsz = dyn[i].d_un.d_val; - break; - case DT_RELAENT: - relent = dyn[i].d_un.d_val; - 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 (ELF64_R_TYPE(rel->r_info)) { - case R_X86_64_NONE: - break; - case R_X86_64_RELATIVE: - addr = (unsigned long *)(ldbase + rel->r_offset); - *addr += ldbase; - break; - default: - break; - } - rel = (Elf64_Rel *)((char *)rel + relent); - relsz -= relent; - } - - return EFI_SUCCESS; -} diff --git a/arch/x86/lib/reloc_ia32_efi.c b/arch/x86/lib/reloc_ia32_efi.c new file mode 100644 index 0000000..4d68255 --- /dev/null +++ b/arch/x86/lib/reloc_ia32_efi.c @@ -0,0 +1,72 @@ +/* + * reloc_ia32.c - position independent x86 ELF shared object relocator + * Copyright (C) 1999 Hewlett-Packard Co. + * Contributed by David Mosberger . + * + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include + +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; +} diff --git a/arch/x86/lib/reloc_x86_64_efi.c b/arch/x86/lib/reloc_x86_64_efi.c new file mode 100644 index 0000000..5f71f2a --- /dev/null +++ b/arch/x86/lib/reloc_x86_64_efi.c @@ -0,0 +1,66 @@ +/* + * reloc_x86_64.c - position independent x86_64 ELF shared object relocator + * Copyright (C) 1999 Hewlett-Packard Co. + * Contributed by David Mosberger . + * Copyright (C) 2005 Intel Co. + * Contributed by Fenghua Yu . + * + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include + +efi_status_t _relocate(long ldbase, Elf64_Dyn *dyn, efi_handle_t image, + struct efi_system_table *systab) +{ + long relsz = 0, relent = 0; + Elf64_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_RELA: + rel = (Elf64_Rel *) + ((unsigned long)dyn[i].d_un.d_ptr + ldbase); + break; + case DT_RELASZ: + relsz = dyn[i].d_un.d_val; + break; + case DT_RELAENT: + relent = dyn[i].d_un.d_val; + 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 (ELF64_R_TYPE(rel->r_info)) { + case R_X86_64_NONE: + break; + case R_X86_64_RELATIVE: + addr = (unsigned long *)(ldbase + rel->r_offset); + *addr += ldbase; + break; + default: + break; + } + rel = (Elf64_Rel *)((char *)rel + relent); + relsz -= relent; + } + + return EFI_SUCCESS; +} -- cgit v0.10.2 From 5bd828b5329ed9b7c85beae1e532daa710f22168 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 7 Nov 2016 08:47:15 -0700 Subject: efi: x86: Adjust EFI files support efi_loader Add compiler flags and make a few minor adjustments to support the efi loader. Signed-off-by: Simon Glass [agraf: Add Kconfig dep] Signed-off-by: Alexander Graf diff --git a/arch/x86/config.mk b/arch/x86/config.mk index 12a8d73..03c71f7 100644 --- a/arch/x86/config.mk +++ b/arch/x86/config.mk @@ -65,3 +65,19 @@ PLATFORM_LDFLAGS += --emit-relocs LDFLAGS_FINAL += --gc-sections -pie endif + +ifneq ($(CONFIG_EFI_STUB)$(CONFIG_CMD_BOOTEFI_HELLO),) + +ifneq ($(CONFIG_EFI_STUB_64BIT),) +EFI_LDS := elf_x86_64_efi.lds +EFI_CRT0 := crt0_x86_64_efi.o +EFI_RELOC := reloc_x86_64_efi.o +EFI_TARGET := --target=efi-app-ia32 +else +EFI_LDS := elf_ia32_efi.lds +EFI_CRT0 := crt0_ia32_efi.o +EFI_RELOC := reloc_ia32_efi.o +EFI_TARGET := --target=efi-app-x86_64 +endif + +endif diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile index aad6555..ff402dc 100644 --- a/arch/x86/lib/Makefile +++ b/arch/x86/lib/Makefile @@ -61,4 +61,9 @@ AFLAGS_crt0_x86_64_efi.o += -fpic -fshort-wchar extra-$(CONFIG_EFI_STUB_32BIT) += crt0_ia32_efi.o reloc_ia32_efi.o extra-$(CONFIG_EFI_STUB_64BIT) += crt0_x86_64_efi.o reloc_x86_64_efi.o + +endif + +ifneq ($(CONFIG_EFI_STUB)$(CONFIG_CMD_BOOTEFI_HELLO),) +extra-y += $(EFI_CRT0) $(EFI_RELOC) endif diff --git a/arch/x86/lib/elf_ia32_efi.lds b/arch/x86/lib/elf_ia32_efi.lds index cd3b0a9..174d36f 100644 --- a/arch/x86/lib/elf_ia32_efi.lds +++ b/arch/x86/lib/elf_ia32_efi.lds @@ -6,8 +6,6 @@ * Modified from usr/lib32/elf_ia32_efi.lds in gnu-efi */ -#include - OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") OUTPUT_ARCH(i386) ENTRY(_start) diff --git a/arch/x86/lib/elf_x86_64_efi.lds b/arch/x86/lib/elf_x86_64_efi.lds index 9d9f057..70c7c52 100644 --- a/arch/x86/lib/elf_x86_64_efi.lds +++ b/arch/x86/lib/elf_x86_64_efi.lds @@ -6,8 +6,6 @@ * Modified from usr/lib32/elf_x86_64_efi.lds in gnu-efi */ -#include - OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64") OUTPUT_ARCH(i386:x86-64) ENTRY(_start) diff --git a/cmd/Kconfig b/cmd/Kconfig index 501ac17..2a2f23e 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -183,7 +183,7 @@ config CMD_BOOTEFI config CMD_BOOTEFI_HELLO bool "Allow booting a standard EFI hello world for testing" - depends on CMD_BOOTEFI && ARM + depends on CMD_BOOTEFI && (ARM || X86) help This adds a standard EFI hello world application to U-Boot so that it can be used with the 'bootefi hello' command. This is useful -- cgit v0.10.2 From 58ad86288fd32f1f969ac654f2074c090f0abe32 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 7 Nov 2016 08:47:16 -0700 Subject: x86: Enable EFI loader support Enable this so that EFI applications (notably grub) can be run under U-Boot on x86 platforms. At present the 'hello world' EFI application is not supported for the qemu-x86_efi_payload64 board. That board builds a payload consisting of a 64-bit header and a 32-bit U-Boot, which is incompatible with the way the EFI loader builds its EFI application. The following error is obtained: x86_64-linux-ld.bfd: i386 architecture of input file `lib/efi_loader/helloworld.o' is incompatible with i386:x86-64 output This could be corrected with additional Makefile rules. For now, this feature is disabled for that board. Signed-off-by: Simon Glass Reviewed-by: Bin Meng [agraf: drop hello kconfig bits] Signed-off-by: Alexander Graf diff --git a/configs/efi-x86_defconfig b/configs/efi-x86_defconfig index b31c73b..1fe6142 100644 --- a/configs/efi-x86_defconfig +++ b/configs/efi-x86_defconfig @@ -34,3 +34,4 @@ CONFIG_USB=y CONFIG_USB_STORAGE=y CONFIG_USB_KEYBOARD=y CONFIG_EFI=y +# CONFIG_EFI_LOADER is not set diff --git a/doc/README.x86 b/doc/README.x86 index 6799559..a38cc1b 100644 --- a/doc/README.x86 +++ b/doc/README.x86 @@ -1077,7 +1077,6 @@ TODO List --------- - Audio - Chrome OS verified boot -- Support for CONFIG_EFI_LOADER - Building U-Boot to run in 64-bit mode References diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig index 7d4106e..d2b6327 100644 --- a/lib/efi_loader/Kconfig +++ b/lib/efi_loader/Kconfig @@ -1,6 +1,6 @@ config EFI_LOADER bool "Support running EFI Applications in U-Boot" - depends on ARM && OF_LIBFDT + depends on (ARM || X86) && OF_LIBFDT default y help Select this option if you want to run EFI applications (like grub2) -- cgit v0.10.2 From 69bd459d343fe1e5a68a6f187d8c99c78c6fc6ce Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Thu, 17 Nov 2016 01:02:58 +0100 Subject: efi_loader: AArch64: Run EFI payloads in EL2 if U-Boot runs in EL3 Some boards decided not to run ATF or other secure firmware in EL3, so they instead run U-Boot there. The uEFI spec doesn't know what EL3 is though - it only knows about EL2 and EL1. So if we see that we're running in EL3, let's get into EL2 to make payloads happy. Signed-off-by: Alexander Graf Reviewed-by: York Sun diff --git a/cmd/bootefi.c b/cmd/bootefi.c index ae1b713..ca41170 100644 --- a/cmd/bootefi.c +++ b/cmd/bootefi.c @@ -226,6 +226,17 @@ static unsigned long do_bootefi_exec(void *efi, void *fdt) return status == EFI_SUCCESS ? 0 : -EINVAL; } +#ifdef CONFIG_ARM64 + /* On AArch64 we need to make sure we call our payload in < EL3 */ + if (current_el() == 3) { + smp_kick_all_cpus(); + dcache_disable(); /* flush cache before switch to EL2 */ + armv8_switch_to_el2(); + /* Enable caches again */ + dcache_enable(); + } +#endif + return entry(&loaded_image_info, &systab); } -- cgit v0.10.2 From 441a2306ab748b63fa6790ce0d64bede9b0b82e4 Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Thu, 17 Nov 2016 01:02:55 +0100 Subject: efi_loader: Disable PSCI reset for ls1043 and ls1046 The NXP ls1043 and ls1046 systems do not (yet) have PSCI enablement for reset. Don't enable generic PSCI reset code on them. Signed-off-by: Alexander Graf diff --git a/arch/arm/cpu/armv8/Kconfig b/arch/arm/cpu/armv8/Kconfig index cd2d9bb..965a8d1 100644 --- a/arch/arm/cpu/armv8/Kconfig +++ b/arch/arm/cpu/armv8/Kconfig @@ -28,8 +28,9 @@ config PSCI_RESET !TARGET_LS2080A_SIMU && !TARGET_LS2080AQDS && \ !TARGET_LS2080ARDB && !TARGET_LS1012AQDS && \ !TARGET_LS1012ARDB && !TARGET_LS1012AFRDM && \ - !TARGET_LS1043ARDB && !ARCH_UNIPHIER && !ARCH_SNAPDRAGON && \ - !TARGET_S32V234EVB + !TARGET_LS1043ARDB && !TARGET_LS1043AQDS && \ + !TARGET_LS1046ARDB && !TARGET_LS1046AQDS && \ + !ARCH_UNIPHIER && !ARCH_SNAPDRAGON && !TARGET_S32V234EVB help Most armv8 systems have PSCI support enabled in EL3, either through ARM Trusted Firmware or other firmware. -- cgit v0.10.2 From 97d014446cec3ba98c7f3efe16c423dbcf769379 Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Thu, 17 Nov 2016 01:02:56 +0100 Subject: efi_loader: Fix efi_add_runtime_mmio definition The efi_add_runtime_mmio prototype for disabled CONFIG_EFI_LOADER was different from the enabled one. Sync them. Signed-off-by: Alexander Graf diff --git a/include/efi_loader.h b/include/efi_loader.h index 35b3fe2..99619f5 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -181,7 +181,7 @@ void efi_get_time_init(void); /* Without CONFIG_EFI_LOADER we don't have a runtime section, stub it out */ #define __efi_runtime_data #define __efi_runtime -static inline void efi_add_runtime_mmio(void **mmio_ptr, u64 len) { } +static inline void efi_add_runtime_mmio(void *mmio_ptr, u64 len) { } /* No loader configured, stub out EFI_ENTRY */ static inline void efi_restore_gd(void) { } -- cgit v0.10.2 From b7b8410a8fee9eda7b062a86a07dda0b97c49f8a Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Thu, 17 Nov 2016 01:02:57 +0100 Subject: ls2080: Exit dpaa only right before exiting U-Boot On ls2080 we have a separate network fabric component which we need to shut down before we enter Linux (or any other OS). Along with that also comes configuration of the fabric using a description file. Today we always stop and configure the fabric in the boot script and (again) exit it on device tree generation. This works ok for the normal booti case, but with bootefi the payload we're running may still want to access the network. So let's add a new fsl_mc command that defers configuration and stopping the hardware to when we actually exit U-Boot, so that we can still use the fabric from an EFI payload. For existing boot scripts, nothing should change with this patch. Signed-off-by: Alexander Graf Reviewed-by: York Sun [agraf: Fix x86 build] diff --git a/arch/arm/include/asm/u-boot-arm.h b/arch/arm/include/asm/u-boot-arm.h index 414042d..305a302 100644 --- a/arch/arm/include/asm/u-boot-arm.h +++ b/arch/arm/include/asm/u-boot-arm.h @@ -37,6 +37,7 @@ int arch_early_init_r(void); /* board/.../... */ int board_init(void); void dram_init_banksize (void); +void board_quiesce_devices(void); /* cpu/.../interrupt.c */ int arch_interrupt_init (void); diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c index 53c3141..dedcd1e 100644 --- a/arch/arm/lib/bootm.c +++ b/arch/arm/lib/bootm.c @@ -64,6 +64,10 @@ void arch_lmb_reserve(struct lmb *lmb) gd->bd->bi_dram[0].start + gd->bd->bi_dram[0].size - sp); } +__weak void board_quiesce_devices(void) +{ +} + /** * announce_and_cleanup() - Print message and prepare for kernel boot * @@ -84,6 +88,9 @@ static void announce_and_cleanup(int fake) #ifdef CONFIG_USB_DEVICE udc_disconnect(); #endif + + board_quiesce_devices(); + cleanup_before_linux(); } diff --git a/arch/x86/include/asm/u-boot-x86.h b/arch/x86/include/asm/u-boot-x86.h index 031740b..4f901f9 100644 --- a/arch/x86/include/asm/u-boot-x86.h +++ b/arch/x86/include/asm/u-boot-x86.h @@ -74,6 +74,7 @@ static inline __attribute__((no_instrument_function)) uint64_t rdtsc(void) /* board/... */ void timer_set_tsc_base(uint64_t new_base); uint64_t timer_get_tsc(void); +void board_quiesce_devices(void); void quick_ram_check(void); diff --git a/arch/x86/lib/bootm.c b/arch/x86/lib/bootm.c index 7cf9de4..80fadef 100644 --- a/arch/x86/lib/bootm.c +++ b/arch/x86/lib/bootm.c @@ -26,6 +26,10 @@ DECLARE_GLOBAL_DATA_PTR; #define COMMAND_LINE_OFFSET 0x9000 +__weak void board_quiesce_devices(void) +{ +} + void bootm_announce_and_cleanup(void) { printf("\nStarting kernel ...\n\n"); diff --git a/board/freescale/ls2080a/ls2080a.c b/board/freescale/ls2080a/ls2080a.c index d0a88d4..4f9b9c8 100644 --- a/board/freescale/ls2080a/ls2080a.c +++ b/board/freescale/ls2080a/ls2080a.c @@ -102,6 +102,11 @@ void fdt_fixup_board_enet(void *fdt) else fdt_status_fail(fdt, offset); } + +void board_quiesce_devices(void) +{ + fsl_mc_ldpaa_exit(gd->bd); +} #endif #ifdef CONFIG_OF_BOARD_SETUP @@ -122,7 +127,6 @@ int ft_board_setup(void *blob, bd_t *bd) #ifdef CONFIG_FSL_MC_ENET fdt_fixup_board_enet(blob); - fsl_mc_ldpaa_exit(bd); #endif return 0; diff --git a/board/freescale/ls2080aqds/ls2080aqds.c b/board/freescale/ls2080aqds/ls2080aqds.c index d07ca18..73a61fd 100644 --- a/board/freescale/ls2080aqds/ls2080aqds.c +++ b/board/freescale/ls2080aqds/ls2080aqds.c @@ -292,14 +292,16 @@ void fdt_fixup_board_enet(void *fdt) else fdt_status_fail(fdt, offset); } + +void board_quiesce_devices(void) +{ + fsl_mc_ldpaa_exit(gd->bd); +} #endif #ifdef CONFIG_OF_BOARD_SETUP int ft_board_setup(void *blob, bd_t *bd) { -#ifdef CONFIG_FSL_MC_ENET - int err; -#endif u64 base[CONFIG_NR_DRAM_BANKS]; u64 size[CONFIG_NR_DRAM_BANKS]; @@ -317,9 +319,6 @@ int ft_board_setup(void *blob, bd_t *bd) #ifdef CONFIG_FSL_MC_ENET fdt_fixup_board_enet(blob); - err = fsl_mc_ldpaa_exit(bd); - if (err) - return err; #endif return 0; diff --git a/board/freescale/ls2080ardb/ls2080ardb.c b/board/freescale/ls2080ardb/ls2080ardb.c index 83d9e7e..fab44b9 100644 --- a/board/freescale/ls2080ardb/ls2080ardb.c +++ b/board/freescale/ls2080ardb/ls2080ardb.c @@ -256,14 +256,16 @@ void fdt_fixup_board_enet(void *fdt) else fdt_status_fail(fdt, offset); } + +void board_quiesce_devices(void) +{ + fsl_mc_ldpaa_exit(gd->bd); +} #endif #ifdef CONFIG_OF_BOARD_SETUP int ft_board_setup(void *blob, bd_t *bd) { -#ifdef CONFIG_FSL_MC_ENET - int err; -#endif u64 base[CONFIG_NR_DRAM_BANKS]; u64 size[CONFIG_NR_DRAM_BANKS]; @@ -281,9 +283,6 @@ int ft_board_setup(void *blob, bd_t *bd) #ifdef CONFIG_FSL_MC_ENET fdt_fixup_board_enet(blob); - err = fsl_mc_ldpaa_exit(bd); - if (err) - return err; #endif return 0; diff --git a/drivers/net/fsl-mc/mc.c b/drivers/net/fsl-mc/mc.c index 1811b0f..46b8a6b 100644 --- a/drivers/net/fsl-mc/mc.c +++ b/drivers/net/fsl-mc/mc.c @@ -40,6 +40,7 @@ int child_dprc_id; struct fsl_dpbp_obj *dflt_dpbp = NULL; struct fsl_dpio_obj *dflt_dpio = NULL; struct fsl_dpni_obj *dflt_dpni = NULL; +static u64 mc_lazy_dpl_addr; #ifdef DEBUG void dump_ram_words(const char *title, void *addr) @@ -572,6 +573,9 @@ int mc_apply_dpl(u64 mc_dpl_addr) u64 mc_ram_addr = mc_get_dram_addr(); size_t mc_ram_size = mc_get_dram_block_size(); + if (!mc_dpl_addr) + return -1; + error = load_mc_dpl(mc_ram_addr, mc_ram_size, mc_dpl_addr); if (error != 0) return error; @@ -1156,6 +1160,11 @@ int fsl_mc_ldpaa_exit(bd_t *bd) { int err = 0; + if (bd && mc_lazy_dpl_addr && !fsl_mc_ldpaa_exit(NULL)) { + mc_apply_dpl(mc_lazy_dpl_addr); + mc_lazy_dpl_addr = 0; + } + /* MC is not loaded intentionally, So return success. */ if (bd && get_mc_boot_status() != 0) return 0; @@ -1259,6 +1268,7 @@ static int do_fsl_mc(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) } break; + case 'l': case 'a': { u64 mc_dpl_addr; @@ -1279,8 +1289,17 @@ static int do_fsl_mc(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) return -ENODEV; } - if (!fsl_mc_ldpaa_exit(NULL)) - err = mc_apply_dpl(mc_dpl_addr); + if (argv[1][0] == 'l') { + /* + * We will do the actual dpaa exit and dpl apply + * later from announce_and_cleanup(). + */ + mc_lazy_dpl_addr = mc_dpl_addr; + } else { + /* The user wants it applied now */ + if (!fsl_mc_ldpaa_exit(NULL)) + err = mc_apply_dpl(mc_dpl_addr); + } break; } default: @@ -1298,5 +1317,6 @@ U_BOOT_CMD( "DPAA2 command to manage Management Complex (MC)", "start mc [FW_addr] [DPC_addr] - Start Management Complex\n" "fsl_mc apply DPL [DPL_addr] - Apply DPL file\n" + "fsl_mc lazyapply DPL [DPL_addr] - Apply DPL file on exit\n" "fsl_mc start aiop [FW_addr] - Start AIOP\n" ); diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c index 1fdddf4..51080cb 100644 --- a/lib/efi_loader/efi_boottime.c +++ b/lib/efi_loader/efi_boottime.c @@ -538,6 +538,8 @@ static efi_status_t EFIAPI efi_exit_boot_services(void *image_handle, { EFI_ENTRY("%p, %ld", image_handle, map_key); + board_quiesce_devices(); + /* Fix up caches for EFI payloads if necessary */ efi_exit_caches(); -- cgit v0.10.2 From 215b1fb9fa43049aee34e824bfd994b335155750 Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Thu, 17 Nov 2016 01:02:59 +0100 Subject: ls2080ardb: Reserve DP-DDR RAM The DP-DDR shouldn't be exposed as conventional memory to an OS, so let's rather claim it's a reserved region in the EFI memory map Signed-off-by: Alexander Graf Reviewed-by: York Sun diff --git a/board/freescale/ls2080ardb/ls2080ardb.c b/board/freescale/ls2080ardb/ls2080ardb.c index fab44b9..02954ef 100644 --- a/board/freescale/ls2080ardb/ls2080ardb.c +++ b/board/freescale/ls2080ardb/ls2080ardb.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -201,6 +202,14 @@ int misc_init_r(void) if (adjust_vdd(0)) printf("Warning: Adjusting core voltage failed.\n"); +#if defined(CONFIG_EFI_LOADER) && !defined(CONFIG_SPL_BUILD) + if (soc_has_dp_ddr() && gd->bd->bi_dram[2].size) { + efi_add_memory_map(gd->bd->bi_dram[2].start, + gd->bd->bi_dram[2].size >> EFI_PAGE_SHIFT, + EFI_RESERVED_MEMORY_TYPE, false); + } +#endif + return 0; } -- cgit v0.10.2 From 5a37a2f0140c735ad6d8ca223a37fbfdc508622f Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Thu, 17 Nov 2016 01:03:00 +0100 Subject: armv8: ls2080a: Declare spin tables as reserved for efi loader The efi loader code has its own memory map, so it needs to be aware where the spin tables are located, to ensure that no code writes into those regions. Signed-off-by: Alexander Graf diff --git a/arch/arm/cpu/armv8/fsl-layerscape/fdt.c b/arch/arm/cpu/armv8/fsl-layerscape/fdt.c index 1a8321b..0dae5fa 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/fdt.c +++ b/arch/arm/cpu/armv8/fsl-layerscape/fdt.c @@ -5,6 +5,7 @@ */ #include +#include #include #include #include @@ -105,6 +106,11 @@ remove_psci_node: fdt_add_mem_rsv(blob, (uintptr_t)&secondary_boot_code, *boot_code_size); +#if defined(CONFIG_EFI_LOADER) && !defined(CONFIG_SPL_BUILD) + efi_add_memory_map((uintptr_t)&secondary_boot_code, + ALIGN(*boot_code_size, EFI_PAGE_SIZE) >> EFI_PAGE_SHIFT, + EFI_RESERVED_MEMORY_TYPE, false); +#endif } #endif -- cgit v0.10.2 From 78d578422abb9ba1a624e619ec62a0dcea7d3218 Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Thu, 17 Nov 2016 01:03:01 +0100 Subject: armv8: fsl-layerscape: Add support for efi_loader RTS reset When implementing efi loader support, we can expose runtime services for payloads. One such service is CPU reset. This patch implements RTS CPU reset support for layerscape systems. Signed-off-by: Alexander Graf Reviewed-by: York Sun diff --git a/arch/arm/cpu/armv8/fsl-layerscape/cpu.c b/arch/arm/cpu/armv8/fsl-layerscape/cpu.c index b7a2e0c..0b516e3 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/cpu.c +++ b/arch/arm/cpu/armv8/fsl-layerscape/cpu.c @@ -17,6 +17,7 @@ #ifdef CONFIG_MP #include #endif +#include #include #include #ifdef CONFIG_FSL_ESDHC @@ -462,9 +463,10 @@ int timer_init(void) return 0; } -void reset_cpu(ulong addr) +__efi_runtime_data u32 __iomem *rstcr = (u32 *)CONFIG_SYS_FSL_RST_ADDR; + +void __efi_runtime reset_cpu(ulong addr) { - u32 __iomem *rstcr = (u32 *)CONFIG_SYS_FSL_RST_ADDR; u32 val; /* Raise RESET_REQ_B */ @@ -473,6 +475,33 @@ void reset_cpu(ulong addr) scfg_out32(rstcr, val); } +#ifdef CONFIG_EFI_LOADER + +void __efi_runtime EFIAPI efi_reset_system( + enum efi_reset_type reset_type, + efi_status_t reset_status, + unsigned long data_size, void *reset_data) +{ + switch (reset_type) { + case EFI_RESET_COLD: + case EFI_RESET_WARM: + reset_cpu(0); + break; + case EFI_RESET_SHUTDOWN: + /* Nothing we can do */ + break; + } + + while (1) { } +} + +void efi_reset_system_init(void) +{ + efi_add_runtime_mmio(&rstcr, sizeof(*rstcr)); +} + +#endif + phys_size_t board_reserve_ram_top(phys_size_t ram_size) { phys_size_t ram_top = ram_size; -- cgit v0.10.2 From b99ebaf9f01ebe864061818e00beb70cb1ddc635 Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Thu, 17 Nov 2016 01:03:02 +0100 Subject: ls2080ardb: Convert to distro boot Most new systems in U-Boot these days make use of the generic "distro" framework which allows a user to have U-Boot scan for a bootable OS on all available media types. This patch extends the LS2080ARDB board to use that framework if the hard coded NOR flash location does not contain a bootable image. Signed-off-by: Alexander Graf diff --git a/Kconfig b/Kconfig index 1263d0b..f3a9f73 100644 --- a/Kconfig +++ b/Kconfig @@ -56,6 +56,7 @@ config CC_OPTIMIZE_FOR_SIZE config DISTRO_DEFAULTS bool "Select defaults suitable for booting general purpose Linux distributions" default y if ARCH_SUNXI + default y if ARCH_LS2080A default n select CMD_BOOTZ if ARM && !ARM64 select CMD_BOOTI if ARM64 diff --git a/include/configs/ls2080ardb.h b/include/configs/ls2080ardb.h index b9cb6d3..32fa0eb 100644 --- a/include/configs/ls2080ardb.h +++ b/include/configs/ls2080ardb.h @@ -316,10 +316,25 @@ unsigned long get_board_sys_clk(void); #define CONFIG_USB_MAX_CONTROLLER_COUNT 2 #define CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS 2 +#undef CONFIG_CMDLINE_EDITING +#include + +#define BOOT_TARGET_DEVICES(func) \ + func(USB, usb, 0) \ + func(MMC, mmc, 0) \ + func(SCSI, scsi, 0) \ + func(DHCP, dhcp, na) +#include + /* Initial environment variables */ #undef CONFIG_EXTRA_ENV_SETTINGS #define CONFIG_EXTRA_ENV_SETTINGS \ "hwconfig=fsl_ddr:bank_intlv=auto\0" \ + "scriptaddr=0x80800000\0" \ + "kernel_addr_r=0x81000000\0" \ + "pxefile_addr_r=0x81000000\0" \ + "fdt_addr_r=0x88000000\0" \ + "ramdisk_addr_r=0x89000000\0" \ "loadaddr=0x80100000\0" \ "kernel_addr=0x100000\0" \ "ramdisk_addr=0x800000\0" \ @@ -329,8 +344,10 @@ unsigned long get_board_sys_clk(void); "kernel_start=0x581100000\0" \ "kernel_load=0xa0000000\0" \ "kernel_size=0x2800000\0" \ + "fdtfile=fsl-ls2080a-rdb.dtb\0" \ "mcinitcmd=fsl_mc start mc 0x580300000" \ - " 0x580800000 \0" + " 0x580800000 \0" \ + BOOTENV #undef CONFIG_BOOTARGS #define CONFIG_BOOTARGS "console=ttyS1,115200 root=/dev/ram0 " \ @@ -338,6 +355,13 @@ unsigned long get_board_sys_clk(void); "ramdisk_size=0x2000000 default_hugepagesz=2m" \ " hugepagesz=2m hugepages=256" +#undef CONFIG_BOOTCOMMAND +/* Try to boot an on-NOR kernel first, then do normal distro boot */ +#define CONFIG_BOOTCOMMAND "run mcinitcmd && fsl_mc lazyapply dpl 0x580700000" \ + " && cp.b $kernel_start $kernel_load $kernel_size" \ + " && bootm $kernel_load" \ + " || run distro_bootcmd" + /* MAC/PHY configuration */ #ifdef CONFIG_FSL_MC_ENET #define CONFIG_PHYLIB_10G -- cgit v0.10.2