From db12f518edb05cbb4ea2b4f2d9771dda2341cbe7 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Fri, 1 Jan 2021 08:39:43 +0100 Subject: efi_loader: implement non-blocking file services Implement services OpenEx(), ReadEx(), WriteEx(), FlushEx() of the EFI_FILE_PROTOCOL. Signed-off-by: Heinrich Schuchardt --- include/efi_api.h | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'include') diff --git a/include/efi_api.h b/include/efi_api.h index ecb43a06070..2b54ee02a2d 100644 --- a/include/efi_api.h +++ b/include/efi_api.h @@ -1589,35 +1589,35 @@ struct efi_file_io_token { struct efi_file_handle { u64 rev; - efi_status_t (EFIAPI *open)(struct efi_file_handle *file, + efi_status_t (EFIAPI *open)(struct efi_file_handle *this, struct efi_file_handle **new_handle, u16 *file_name, u64 open_mode, u64 attributes); - efi_status_t (EFIAPI *close)(struct efi_file_handle *file); - efi_status_t (EFIAPI *delete)(struct efi_file_handle *file); - efi_status_t (EFIAPI *read)(struct efi_file_handle *file, + efi_status_t (EFIAPI *close)(struct efi_file_handle *this); + efi_status_t (EFIAPI *delete)(struct efi_file_handle *this); + efi_status_t (EFIAPI *read)(struct efi_file_handle *this, efi_uintn_t *buffer_size, void *buffer); - efi_status_t (EFIAPI *write)(struct efi_file_handle *file, + efi_status_t (EFIAPI *write)(struct efi_file_handle *this, efi_uintn_t *buffer_size, void *buffer); - efi_status_t (EFIAPI *getpos)(struct efi_file_handle *file, + efi_status_t (EFIAPI *getpos)(struct efi_file_handle *this, u64 *pos); - efi_status_t (EFIAPI *setpos)(struct efi_file_handle *file, + efi_status_t (EFIAPI *setpos)(struct efi_file_handle *this, u64 pos); - efi_status_t (EFIAPI *getinfo)(struct efi_file_handle *file, + efi_status_t (EFIAPI *getinfo)(struct efi_file_handle *this, const efi_guid_t *info_type, efi_uintn_t *buffer_size, void *buffer); - efi_status_t (EFIAPI *setinfo)(struct efi_file_handle *file, + efi_status_t (EFIAPI *setinfo)(struct efi_file_handle *this, const efi_guid_t *info_type, efi_uintn_t buffer_size, void *buffer); - efi_status_t (EFIAPI *flush)(struct efi_file_handle *file); - efi_status_t (EFIAPI *open_ex)(struct efi_file_handle *file, + efi_status_t (EFIAPI *flush)(struct efi_file_handle *this); + efi_status_t (EFIAPI *open_ex)(struct efi_file_handle *this, struct efi_file_handle **new_handle, u16 *file_name, u64 open_mode, u64 attributes, struct efi_file_io_token *token); - efi_status_t (EFIAPI *read_ex)(struct efi_file_handle *file, + efi_status_t (EFIAPI *read_ex)(struct efi_file_handle *this, struct efi_file_io_token *token); - efi_status_t (EFIAPI *write_ex)(struct efi_file_handle *file, + efi_status_t (EFIAPI *write_ex)(struct efi_file_handle *this, struct efi_file_io_token *token); - efi_status_t (EFIAPI *flush_ex)(struct efi_file_handle *file, + efi_status_t (EFIAPI *flush_ex)(struct efi_file_handle *this, struct efi_file_io_token *token); }; -- cgit v1.2.3 From 5dad05a0e61d759af2df8cf900d044a8485bd747 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Tue, 12 Jan 2021 12:40:32 +0100 Subject: efi_loader: carve out efi_check_pe() Carve out a function to check that a buffer contains a PE-COFF image. Signed-off-by: Heinrich Schuchardt --- include/efi_loader.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/efi_loader.h b/include/efi_loader.h index 4719fa93f06..df29d45a348 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -460,6 +460,8 @@ efi_status_t efi_set_watchdog(unsigned long timeout); /* Called from places to check whether a timer expired */ void efi_timer_check(void); +/* Check if a buffer contains a PE-COFF image */ +efi_status_t efi_check_pe(void *buffer, size_t size, void **nt_header); /* PE loader implementation */ efi_status_t efi_load_pe(struct efi_loaded_image_obj *handle, void *efi, size_t efi_size, -- cgit v1.2.3 From 5f59518a7b1aef9ad3a91defa06cff82dd01cdc5 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Tue, 12 Jan 2021 12:46:24 +0100 Subject: efi_loader: setting boot device Up to now the bootefi command used the last file loaded to determine the boot partition. This has led to errors when the fdt had been loaded from another partition after the EFI binary. Before setting the boot device from a loaded file check if it is a PE-COFF image or a FIT image. For a PE-COFF image remember address and size, boot device and path. For a FIT image remember boot device and path. If the PE-COFF image is overwritten by loading another file, forget it. Do not allow to start an image via bootefi which is not the last loaded PE-COFF image. Signed-off-by: Heinrich Schuchardt --- include/efi_loader.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/efi_loader.h b/include/efi_loader.h index df29d45a348..2a69ef844b6 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -474,7 +474,8 @@ void efi_restore_gd(void); /* Call this to relocate the runtime section to an address space */ void efi_runtime_relocate(ulong offset, struct efi_mem_desc *map); /* Call this to set the current device name */ -void efi_set_bootdev(const char *dev, const char *devnr, const char *path); +void efi_set_bootdev(const char *dev, const char *devnr, const char *path, + void *buffer, size_t buffer_size); /* Add a new object to the object list. */ void efi_add_handle(efi_handle_t obj); /* Create handle */ @@ -873,7 +874,8 @@ static inline efi_status_t efi_add_runtime_mmio(void *mmio_ptr, u64 len) /* No loader configured, stub out EFI_ENTRY */ static inline void efi_restore_gd(void) { } static inline void efi_set_bootdev(const char *dev, const char *devnr, - const char *path) { } + const char *path, void *buffer, + size_t buffer_size) { } static inline void efi_net_set_dhcp_ack(void *pkt, int len) { } static inline void efi_print_image_infos(void *pc) { } static inline efi_status_t efi_launch_capsules(void) -- cgit v1.2.3 From 85fc2ad4d13e1311652049c7322f5d36aacfc572 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Tue, 5 Jan 2021 07:52:48 +0100 Subject: efi_loader: move efi_(u)intn_t to efi.h Move efi_intn_t and efi_uintn_t to include/efi.h to allow usage without efi_api.h Signed-off-by: Heinrich Schuchardt --- include/efi.h | 5 +++++ include/efi_api.h | 2 -- 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/efi.h b/include/efi.h index 5695273ce9a..503fbf060bf 100644 --- a/include/efi.h +++ b/include/efi.h @@ -20,6 +20,11 @@ #include #include +/* Type INTN in UEFI specification */ +#define efi_intn_t ssize_t +/* Type UINTN in UEFI specification*/ +#define efi_uintn_t size_t + /* * EFI on x86_64 uses the Microsoft ABI which is not the default for GCC. * diff --git a/include/efi_api.h b/include/efi_api.h index 2b54ee02a2d..c635abe9a94 100644 --- a/include/efi_api.h +++ b/include/efi_api.h @@ -34,8 +34,6 @@ enum efi_timer_delay { EFI_TIMER_RELATIVE = 2 }; -#define efi_intn_t ssize_t -#define efi_uintn_t size_t typedef void *efi_hii_handle_t; typedef u16 *efi_string_t; typedef u16 efi_string_id_t; -- cgit v1.2.3 From 7913c7dc57eb1ce6a145c36fab7918a0c8c6860d Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Tue, 5 Jan 2021 07:50:09 +0100 Subject: efi_loader: typedef efi_string_t text output protocol We do not want to use typedefs in U-Boot. Do not use efi_string_t in the EFI_TEXT_OUTPUT_PROTOCOL. Signed-off-by: Heinrich Schuchardt --- include/efi_api.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/efi_api.h b/include/efi_api.h index c635abe9a94..df9bee2ae43 100644 --- a/include/efi_api.h +++ b/include/efi_api.h @@ -701,10 +701,10 @@ struct efi_simple_text_output_protocol { char extended_verification); efi_status_t (EFIAPI *output_string)( struct efi_simple_text_output_protocol *this, - const efi_string_t str); + const u16 *str); efi_status_t (EFIAPI *test_string)( struct efi_simple_text_output_protocol *this, - const efi_string_t str); + const u16 *str); efi_status_t(EFIAPI *query_mode)( struct efi_simple_text_output_protocol *this, unsigned long mode_number, unsigned long *columns, -- cgit v1.2.3 From 94686f60a2b9fd87842f473a5cdca316668765c3 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Sun, 13 Dec 2020 10:30:24 +0100 Subject: efi_loader: implement EFI_DT_FIXUP_PROTOCOL A boot manager like GRUB can use the protocol to * apply U-Boot's fix-ups to the a device-tree * let U-Boot make memory reservations according to the device-tree * install the device-tree as a configuration table Signed-off-by: Heinrich Schuchardt --- include/efi_dt_fixup.h | 39 +++++++++++++++++++++++++++++++++++++++ include/efi_loader.h | 2 ++ 2 files changed, 41 insertions(+) create mode 100644 include/efi_dt_fixup.h (limited to 'include') diff --git a/include/efi_dt_fixup.h b/include/efi_dt_fixup.h new file mode 100644 index 00000000000..9066e8dd8e1 --- /dev/null +++ b/include/efi_dt_fixup.h @@ -0,0 +1,39 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * EFI_DT_FIXUP_PROTOCOL + * + * Copyright (c) 2020 Heinrich Schuchardt + */ + +#include + +#define EFI_DT_FIXUP_PROTOCOL_GUID \ + EFI_GUID(0xe617d64c, 0xfe08, 0x46da, 0xf4, 0xdc, \ + 0xbb, 0xd5, 0x87, 0x0c, 0x73, 0x00) + +#define EFI_DT_FIXUP_PROTOCOL_REVISION 0x00010000 + +/* Add nodes and update properties */ +#define EFI_DT_APPLY_FIXUPS 0x00000001 +/* + * Reserve memory according to the /reserved-memory node + * and the memory reservation block + */ +#define EFI_DT_RESERVE_MEMORY 0x00000002 +/* Install the device-tree as configuration table */ +#define EFI_DT_INSTALL_TABLE 0x00000004 + +#define EFI_DT_ALL (EFI_DT_APPLY_FIXUPS | \ + EFI_DT_RESERVE_MEMORY | \ + EFI_DT_INSTALL_TABLE) + +struct efi_dt_fixup_protocol { + u64 revision; + efi_status_t (EFIAPI *fixup) (struct efi_dt_fixup_protocol *this, + void *dtb, + efi_uintn_t *buffer_size, + u32 flags); +}; + +extern struct efi_dt_fixup_protocol efi_dt_fixup_prot; +extern const efi_guid_t efi_guid_dt_fixup_protocol; diff --git a/include/efi_loader.h b/include/efi_loader.h index 2a69ef844b6..e53d286b9d1 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -411,6 +411,8 @@ void efi_runtime_detach(void); /* efi_convert_pointer() - convert pointer to virtual address */ efi_status_t EFIAPI efi_convert_pointer(efi_uintn_t debug_disposition, void **address); +/* Carve out DT reserved memory ranges */ +void efi_carve_out_dt_rsv(void *fdt); /* Called by bootefi to make console interface available */ efi_status_t efi_console_register(void); /* Called by bootefi to make all disk storage accessible as EFI objects */ -- cgit v1.2.3