On 26.12.15 19:33, Leif Lindholm wrote: > On Tue, Dec 22, 2015 at 02:57:53PM +0100, Alexander Graf wrote: >> After booting has finished, EFI allows firmware to still interact with the OS >> using the "runtime services". These callbacks live in a separate address >> space, >> since they are available long after U-Boot has been overwritten by the OS. >> >> However, since U-Boot has no notion of RTS, we just create an extremely >> minimal >> RTS stub that just declares all functions as unsupported. We could in the >> future >> map U-boot environment variables to EFI variables here. >> >> Signed-off-by: Alexander Graf <ag...@suse.de> >> --- >> arch/arm/cpu/armv8/u-boot.lds | 8 ++++++ >> arch/arm/cpu/u-boot.lds | 13 ++++++++++ >> arch/arm/lib/sections.c | 2 ++ >> include/efi_loader.h | 3 +++ >> lib/efi_loader/efi_runtime.c | 59 >> +++++++++++++++++++++++++++++++++++++++++++ >> 5 files changed, 85 insertions(+) >> create mode 100644 lib/efi_loader/efi_runtime.c >> >> diff --git a/arch/arm/cpu/armv8/u-boot.lds b/arch/arm/cpu/armv8/u-boot.lds >> index 4c12222..7c5b032 100644 >> --- a/arch/arm/cpu/armv8/u-boot.lds >> +++ b/arch/arm/cpu/armv8/u-boot.lds >> @@ -42,6 +42,14 @@ SECTIONS >> >> . = ALIGN(8); >> >> + .efi_runtime : { >> + __efi_runtime_start = .; >> + *(efi_runtime) >> + __efi_runtime_stop = .; >> + } >> + >> + . = ALIGN(8); >> + >> .image_copy_end : >> { >> *(.__image_copy_end) >> diff --git a/arch/arm/cpu/u-boot.lds b/arch/arm/cpu/u-boot.lds >> index d48a905..b5198d0 100644 >> --- a/arch/arm/cpu/u-boot.lds >> +++ b/arch/arm/cpu/u-boot.lds >> @@ -89,6 +89,19 @@ SECTIONS >> >> . = ALIGN(4); >> >> + .__efi_runtime_start : { >> + *(.__efi_runtime_start) >> + } >> + >> + .efi_runtime : { >> + *(efi_runtime) >> + } >> + >> + .__efi_runtime_stop : { >> + *(.__efi_runtime_stop) >> + } >> + . = ALIGN(4); >> + >> .image_copy_end : >> { >> *(.__image_copy_end) >> diff --git a/arch/arm/lib/sections.c b/arch/arm/lib/sections.c >> index a1205c3..21b3066 100644 >> --- a/arch/arm/lib/sections.c >> +++ b/arch/arm/lib/sections.c >> @@ -27,4 +27,6 @@ char __rel_dyn_start[0] >> __attribute__((section(".__rel_dyn_start"))); >> char __rel_dyn_end[0] __attribute__((section(".__rel_dyn_end"))); >> char __secure_start[0] __attribute__((section(".__secure_start"))); >> char __secure_end[0] __attribute__((section(".__secure_end"))); >> +char __efi_runtime_start[0] >> __attribute__((section(".__efi_runtime_start"))); >> +char __efi_runtime_stop[0] __attribute__((section(".__efi_runtime_stop"))); >> char _end[0] __attribute__((section(".__end"))); >> diff --git a/include/efi_loader.h b/include/efi_loader.h >> index 7fb2106..af1c88f 100644 >> --- a/include/efi_loader.h >> +++ b/include/efi_loader.h >> @@ -39,6 +39,7 @@ >> >> #define EFI_EXIT(ret) efi_exit_func(ret); >> >> +extern const struct efi_runtime_services efi_runtime_services; >> extern struct efi_system_table systab; >> >> extern const struct efi_simple_text_output_protocol efi_con_out; >> @@ -49,6 +50,8 @@ extern const efi_guid_t efi_guid_console_control; >> extern const efi_guid_t efi_guid_device_path; >> extern const efi_guid_t efi_guid_loaded_image; >> >> +extern unsigned int __efi_runtime_start, __efi_runtime_stop; >> + >> struct efi_class_map { >> const efi_guid_t *guid; >> const void *interface; >> diff --git a/lib/efi_loader/efi_runtime.c b/lib/efi_loader/efi_runtime.c >> new file mode 100644 >> index 0000000..214e1f5 >> --- /dev/null >> +++ b/lib/efi_loader/efi_runtime.c >> @@ -0,0 +1,59 @@ >> +/* >> + * EFI application runtime services >> + * >> + * Copyright (c) 2015 Alexander Graf >> + * >> + * This library is free software; you can redistribute it and/or >> + * modify it under the terms of the GNU Lesser General Public >> + * License as published by the Free Software Foundation; either >> + * version 2.1 of the License, or (at your option) any later version. >> + * >> + * This library is distributed in the hope that it will be useful, >> + * but WITHOUT ANY WARRANTY; without even the implied warranty of >> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU >> + * Lesser General Public License for more details. >> + * >> + * You should have received a copy of the GNU Lesser General Public >> + * License along with this library; if not, write to the Free Software >> + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, >> USA >> + * >> + * SPDX-License-Identifier: LGPL-2.1+ >> + */ >> + >> +#include <common.h> >> +#include <efi_loader.h> >> + >> +/* >> + * EFI Runtime code is still alive when U-Boot is long overwritten. To >> isolate >> + * this code from the rest, we put it into a special section. >> + * >> + * !!WARNING!! >> + * >> + * This means that we can not rely on any code outside of this file at >> runtime. >> + * Please keep it fully self-contained. >> + */ >> +asm(".section efi_runtime,\"a\""); >> + >> +static efi_status_t efi_unimplemented(void) >> +{ >> + return EFI_UNSUPPORTED; > > Again, EFI_UNSUPPORTED is not necessarily a valid return value for all > runtime services. > >> +} >> + >> +const struct efi_runtime_services efi_runtime_services = { >> + .hdr = { >> + .signature = EFI_RUNTIME_SERVICES_SIGNATURE, >> + .revision = EFI_RUNTIME_SERVICES_REVISION, >> + .headersize = sizeof(struct efi_table_hdr), >> + }, >> + .get_time = (void *)&efi_unimplemented, > > EFI_DEVICE_ERROR > >> + .set_time = (void *)&efi_unimplemented, > > EFI_DEVICE_ERROR > >> + .get_wakeup_time = (void *)&efi_unimplemented, >> + .set_wakeup_time = (void *)&efi_unimplemented, > > Both of these are fine, and correct, to return EFI_UNSUPPORTED. > >> + .set_virtual_address_map = (void *)&efi_unimplemented, >> + .convert_pointer = (void *)&efi_unimplemented, > > There really isn't a way to gracefully decline these two functions. > All valid error codes refer to invalid inputs.
Ok, changing to EFI_INVALID_PARAMETER then :). > >> + .get_variable = (void *)&efi_unimplemented, > > EFI_DEVICE_ERROR would probably be the closest thing to a correct > return code in this instance. > >> + .get_next_variable = (void *)&efi_unimplemented, > > (get_next_variable_name?) git blame says it's Simon's fault :). 867a6ac8 (Simon Glass 2015-07-31 09:31:36 -0600 170) efi_status_t (EFIAPI *get_next_variable)( 867a6ac8 (Simon Glass 2015-07-31 09:31:36 -0600 171) unsigned long *variable_name_size, 867a6ac8 (Simon Glass 2015-07-31 09:31:36 -0600 172) s16 *variable_name, efi_guid_t *vendor); > Again, EFI_DEVICE_ERROR, is probably the least wrong return value. > >> + .set_variable = (void *)&efi_unimplemented, > > EFI_DEVICE_ERROR > >> + .get_next_high_mono_count = (void *)&efi_unimplemented, > > EFI_DEVICE_ERROR > Ok, fixed all of the above. >> + .reset_system = (void *)&efi_unimplemented, > > "The ResetSystem() function does not return." Hrm, I think returning EFI_UNSUPPORTED is still better than while(1) { }. With the return an OS at least has the chance to fix things up itself. Alex _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot