uboot/lib/efi_loader/efi_load_options.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 *  EFI boot manager
   4 *
   5 *  Copyright (c) 2018 AKASHI Takahiro, et.al.
   6 */
   7
   8#define LOG_CATEGORY LOGC_EFI
   9
  10#include <common.h>
  11#include <charset.h>
  12#include <log.h>
  13#include <malloc.h>
  14#include <efi_loader.h>
  15#include <asm/unaligned.h>
  16
  17/**
  18 * efi_set_load_options() - set the load options of a loaded image
  19 *
  20 * @handle:             the image handle
  21 * @load_options_size:  size of load options
  22 * @load_options:       pointer to load options
  23 * Return:              status code
  24 */
  25efi_status_t efi_set_load_options(efi_handle_t handle,
  26                                  efi_uintn_t load_options_size,
  27                                  void *load_options)
  28{
  29        struct efi_loaded_image *loaded_image_info;
  30        efi_status_t ret;
  31
  32        ret = EFI_CALL(systab.boottime->open_protocol(
  33                                        handle,
  34                                        &efi_guid_loaded_image,
  35                                        (void **)&loaded_image_info,
  36                                        efi_root, NULL,
  37                                        EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL));
  38        if (ret != EFI_SUCCESS)
  39                return EFI_INVALID_PARAMETER;
  40
  41        loaded_image_info->load_options = load_options;
  42        loaded_image_info->load_options_size = load_options_size;
  43
  44        return EFI_CALL(systab.boottime->close_protocol(handle,
  45                                                        &efi_guid_loaded_image,
  46                                                        efi_root, NULL));
  47}
  48
  49/**
  50 * efi_deserialize_load_option() - parse serialized data
  51 *
  52 * Parse serialized data describing a load option and transform it to the
  53 * efi_load_option structure.
  54 *
  55 * @lo:         pointer to target
  56 * @data:       serialized data
  57 * @size:       size of the load option, on return size of the optional data
  58 * Return:      status code
  59 */
  60efi_status_t efi_deserialize_load_option(struct efi_load_option *lo, u8 *data,
  61                                         efi_uintn_t *size)
  62{
  63        efi_uintn_t len;
  64
  65        len = sizeof(u32);
  66        if (*size < len + 2 * sizeof(u16))
  67                return EFI_INVALID_PARAMETER;
  68        lo->attributes = get_unaligned_le32(data);
  69        data += len;
  70        *size -= len;
  71
  72        len = sizeof(u16);
  73        lo->file_path_length = get_unaligned_le16(data);
  74        data += len;
  75        *size -= len;
  76
  77        lo->label = (u16 *)data;
  78        len = u16_strnlen(lo->label, *size / sizeof(u16) - 1);
  79        if (lo->label[len])
  80                return EFI_INVALID_PARAMETER;
  81        len = (len + 1) * sizeof(u16);
  82        if (*size < len)
  83                return EFI_INVALID_PARAMETER;
  84        data += len;
  85        *size -= len;
  86
  87        len = lo->file_path_length;
  88        if (*size < len)
  89                return EFI_INVALID_PARAMETER;
  90        lo->file_path = (struct efi_device_path *)data;
  91        if (efi_dp_check_length(lo->file_path, len) < 0)
  92                return EFI_INVALID_PARAMETER;
  93        data += len;
  94        *size -= len;
  95
  96        lo->optional_data = data;
  97
  98        return EFI_SUCCESS;
  99}
 100
 101/**
 102 * efi_serialize_load_option() - serialize load option
 103 *
 104 * Serialize efi_load_option structure into byte stream for BootXXXX.
 105 *
 106 * @data:       buffer for serialized data
 107 * @lo:         load option
 108 * Return:      size of allocated buffer
 109 */
 110unsigned long efi_serialize_load_option(struct efi_load_option *lo, u8 **data)
 111{
 112        unsigned long label_len;
 113        unsigned long size;
 114        u8 *p;
 115
 116        label_len = u16_strsize(lo->label);
 117
 118        /* total size */
 119        size = sizeof(lo->attributes);
 120        size += sizeof(lo->file_path_length);
 121        size += label_len;
 122        size += lo->file_path_length;
 123        if (lo->optional_data)
 124                size += (utf8_utf16_strlen((const char *)lo->optional_data)
 125                                           + 1) * sizeof(u16);
 126        p = malloc(size);
 127        if (!p)
 128                return 0;
 129
 130        /* copy data */
 131        *data = p;
 132        memcpy(p, &lo->attributes, sizeof(lo->attributes));
 133        p += sizeof(lo->attributes);
 134
 135        memcpy(p, &lo->file_path_length, sizeof(lo->file_path_length));
 136        p += sizeof(lo->file_path_length);
 137
 138        memcpy(p, lo->label, label_len);
 139        p += label_len;
 140
 141        memcpy(p, lo->file_path, lo->file_path_length);
 142        p += lo->file_path_length;
 143
 144        if (lo->optional_data) {
 145                utf8_utf16_strcpy((u16 **)&p, (const char *)lo->optional_data);
 146                p += sizeof(u16); /* size of trailing \0 */
 147        }
 148        return size;
 149}
 150