Hi Heinrich, Overall the patch and idea seem fine. Would it make sense to name the file differently? Something similar to what I did on my initrd patches, i.e efi_helper.c, so we can start adding helper functions that have a wider usage?
Thanks /Ilias On Fri, Jan 15, 2021 at 07:02:49PM +0100, Heinrich Schuchardt wrote: > Move all load options related functions to a new module. So that they can > be compiled independently. > > Signed-off-by: Heinrich Schuchardt <xypron.g...@gmx.de> > --- > lib/efi_loader/efi_load_options.c | 151 ++++++++++++++++++++++++++++++ > 1 file changed, 151 insertions(+) > create mode 100644 lib/efi_loader/efi_load_options.c > > diff --git a/lib/efi_loader/efi_load_options.c > b/lib/efi_loader/efi_load_options.c > new file mode 100644 > index 0000000000..9f0e25b6e9 > --- /dev/null > +++ b/lib/efi_loader/efi_load_options.c > @@ -0,0 +1,151 @@ > +// SPDX-License-Identifier: GPL-2.0+ > +/* > + * EFI boot manager > + * > + * Copyright (c) 2017 Rob Clark > + */ > + > +#define LOG_CATEGORY LOGC_EFI > + > +#include <common.h> > +#include <charset.h> > +#include <log.h> > +#include <malloc.h> > +#include <efi_loader.h> > +//#include <efi_variable.h> > +#include <asm/unaligned.h> > + > +/** > + * efi_set_load_options() - set the load options of a loaded image > + * > + * @handle: the image handle > + * @load_options_size: size of load options > + * @load_options: pointer to load options > + * Return: status code > + */ > +efi_status_t efi_set_load_options(efi_handle_t handle, > + efi_uintn_t load_options_size, > + void *load_options) > +{ > + struct efi_loaded_image *loaded_image_info; > + efi_status_t ret; > + > + ret = EFI_CALL(systab.boottime->open_protocol( > + handle, > + &efi_guid_loaded_image, > + (void **)&loaded_image_info, > + efi_root, NULL, > + EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL)); > + if (ret != EFI_SUCCESS) > + return EFI_INVALID_PARAMETER; > + > + loaded_image_info->load_options = load_options; > + loaded_image_info->load_options_size = load_options_size; > + > + return EFI_CALL(systab.boottime->close_protocol(handle, > + &efi_guid_loaded_image, > + efi_root, NULL)); > +} > + > +/** > + * efi_deserialize_load_option() - parse serialized data > + * > + * Parse serialized data describing a load option and transform it to the > + * efi_load_option structure. > + * > + * @lo: pointer to target > + * @data: serialized data > + * @size: size of the load option, on return size of the optional data > + * Return: status code > + */ > +efi_status_t efi_deserialize_load_option(struct efi_load_option *lo, u8 > *data, > + efi_uintn_t *size) > +{ > + efi_uintn_t len; > + > + len = sizeof(u32); > + if (*size < len + 2 * sizeof(u16)) > + return EFI_INVALID_PARAMETER; > + lo->attributes = get_unaligned_le32(data); > + data += len; > + *size -= len; > + > + len = sizeof(u16); > + lo->file_path_length = get_unaligned_le16(data); > + data += len; > + *size -= len; > + > + lo->label = (u16 *)data; > + len = u16_strnlen(lo->label, *size / sizeof(u16) - 1); > + if (lo->label[len]) > + return EFI_INVALID_PARAMETER; > + len = (len + 1) * sizeof(u16); > + if (*size < len) > + return EFI_INVALID_PARAMETER; > + data += len; > + *size -= len; > + > + len = lo->file_path_length; > + if (*size < len) > + return EFI_INVALID_PARAMETER; > + lo->file_path = (struct efi_device_path *)data; > + if (efi_dp_check_length(lo->file_path, len) < 0) > + return EFI_INVALID_PARAMETER; > + data += len; > + *size -= len; > + > + lo->optional_data = data; > + > + return EFI_SUCCESS; > +} > + > +/** > + * efi_serialize_load_option() - serialize load option > + * > + * Serialize efi_load_option structure into byte stream for BootXXXX. > + * > + * @data: buffer for serialized data > + * @lo: load option > + * Return: size of allocated buffer > + */ > +unsigned long efi_serialize_load_option(struct efi_load_option *lo, u8 > **data) > +{ > + unsigned long label_len; > + unsigned long size; > + u8 *p; > + > + label_len = (u16_strlen(lo->label) + 1) * sizeof(u16); > + > + /* total size */ > + size = sizeof(lo->attributes); > + size += sizeof(lo->file_path_length); > + size += label_len; > + size += lo->file_path_length; > + if (lo->optional_data) > + size += (utf8_utf16_strlen((const char *)lo->optional_data) > + + 1) * sizeof(u16); > + p = malloc(size); > + if (!p) > + return 0; > + > + /* copy data */ > + *data = p; > + memcpy(p, &lo->attributes, sizeof(lo->attributes)); > + p += sizeof(lo->attributes); > + > + memcpy(p, &lo->file_path_length, sizeof(lo->file_path_length)); > + p += sizeof(lo->file_path_length); > + > + memcpy(p, lo->label, label_len); > + p += label_len; > + > + memcpy(p, lo->file_path, lo->file_path_length); > + p += lo->file_path_length; > + > + if (lo->optional_data) { > + utf8_utf16_strcpy((u16 **)&p, (const char *)lo->optional_data); > + p += sizeof(u16); /* size of trailing \0 */ > + } > + return size; > +} > + > -- > 2.29.2 >