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
> 

Reply via email to