]>
Commit | Line | Data |
---|---|---|
2363effb HS |
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 | */ | |
25 | efi_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; | |
731ab362 | 30 | struct efi_handler *handler; |
2363effb HS |
31 | efi_status_t ret; |
32 | ||
731ab362 | 33 | ret = efi_search_protocol(handle, &efi_guid_loaded_image, &handler); |
2363effb HS |
34 | if (ret != EFI_SUCCESS) |
35 | return EFI_INVALID_PARAMETER; | |
36 | ||
a7eb8aec | 37 | loaded_image_info = handler->protocol_interface; |
2363effb HS |
38 | loaded_image_info->load_options = load_options; |
39 | loaded_image_info->load_options_size = load_options_size; | |
40 | ||
731ab362 | 41 | return EFI_SUCCESS; |
2363effb HS |
42 | } |
43 | ||
44 | /** | |
45 | * efi_deserialize_load_option() - parse serialized data | |
46 | * | |
47 | * Parse serialized data describing a load option and transform it to the | |
48 | * efi_load_option structure. | |
49 | * | |
50 | * @lo: pointer to target | |
51 | * @data: serialized data | |
52 | * @size: size of the load option, on return size of the optional data | |
53 | * Return: status code | |
54 | */ | |
55 | efi_status_t efi_deserialize_load_option(struct efi_load_option *lo, u8 *data, | |
56 | efi_uintn_t *size) | |
57 | { | |
58 | efi_uintn_t len; | |
59 | ||
60 | len = sizeof(u32); | |
61 | if (*size < len + 2 * sizeof(u16)) | |
62 | return EFI_INVALID_PARAMETER; | |
63 | lo->attributes = get_unaligned_le32(data); | |
64 | data += len; | |
65 | *size -= len; | |
66 | ||
67 | len = sizeof(u16); | |
68 | lo->file_path_length = get_unaligned_le16(data); | |
69 | data += len; | |
70 | *size -= len; | |
71 | ||
72 | lo->label = (u16 *)data; | |
73 | len = u16_strnlen(lo->label, *size / sizeof(u16) - 1); | |
74 | if (lo->label[len]) | |
75 | return EFI_INVALID_PARAMETER; | |
76 | len = (len + 1) * sizeof(u16); | |
77 | if (*size < len) | |
78 | return EFI_INVALID_PARAMETER; | |
79 | data += len; | |
80 | *size -= len; | |
81 | ||
82 | len = lo->file_path_length; | |
83 | if (*size < len) | |
84 | return EFI_INVALID_PARAMETER; | |
85 | lo->file_path = (struct efi_device_path *)data; | |
86 | if (efi_dp_check_length(lo->file_path, len) < 0) | |
87 | return EFI_INVALID_PARAMETER; | |
88 | data += len; | |
89 | *size -= len; | |
90 | ||
91 | lo->optional_data = data; | |
92 | ||
93 | return EFI_SUCCESS; | |
94 | } | |
95 | ||
96 | /** | |
97 | * efi_serialize_load_option() - serialize load option | |
98 | * | |
99 | * Serialize efi_load_option structure into byte stream for BootXXXX. | |
100 | * | |
101 | * @data: buffer for serialized data | |
102 | * @lo: load option | |
103 | * Return: size of allocated buffer | |
104 | */ | |
105 | unsigned long efi_serialize_load_option(struct efi_load_option *lo, u8 **data) | |
106 | { | |
107 | unsigned long label_len; | |
108 | unsigned long size; | |
109 | u8 *p; | |
110 | ||
8bf5f9af | 111 | label_len = u16_strsize(lo->label); |
2363effb HS |
112 | |
113 | /* total size */ | |
114 | size = sizeof(lo->attributes); | |
115 | size += sizeof(lo->file_path_length); | |
116 | size += label_len; | |
117 | size += lo->file_path_length; | |
118 | if (lo->optional_data) | |
119 | size += (utf8_utf16_strlen((const char *)lo->optional_data) | |
120 | + 1) * sizeof(u16); | |
121 | p = malloc(size); | |
122 | if (!p) | |
123 | return 0; | |
124 | ||
125 | /* copy data */ | |
126 | *data = p; | |
127 | memcpy(p, &lo->attributes, sizeof(lo->attributes)); | |
128 | p += sizeof(lo->attributes); | |
129 | ||
130 | memcpy(p, &lo->file_path_length, sizeof(lo->file_path_length)); | |
131 | p += sizeof(lo->file_path_length); | |
132 | ||
133 | memcpy(p, lo->label, label_len); | |
134 | p += label_len; | |
135 | ||
136 | memcpy(p, lo->file_path, lo->file_path_length); | |
137 | p += lo->file_path_length; | |
138 | ||
139 | if (lo->optional_data) { | |
140 | utf8_utf16_strcpy((u16 **)&p, (const char *)lo->optional_data); | |
141 | p += sizeof(u16); /* size of trailing \0 */ | |
142 | } | |
143 | return size; | |
144 | } |