Blame view

cmd/nvedit_efi.c 13.6 KB
49d81fdfb   AKASHI Takahiro   cmd: env: add "-e...
1
2
3
4
5
6
7
8
9
10
11
  // SPDX-License-Identifier: GPL-2.0+
  /*
   *  Integrate UEFI variables to u-boot env interface
   *
   *  Copyright (c) 2018 AKASHI Takahiro, Linaro Limited
   */
  
  #include <charset.h>
  #include <common.h>
  #include <command.h>
  #include <efi_loader.h>
9fb625ce0   Simon Glass   env: Move env_set...
12
  #include <env.h>
49d81fdfb   AKASHI Takahiro   cmd: env: add "-e...
13
14
15
  #include <exports.h>
  #include <hexdump.h>
  #include <malloc.h>
051aa89f4   AKASHI Takahiro   cmd: env: extend ...
16
  #include <mapmem.h>
49d81fdfb   AKASHI Takahiro   cmd: env: add "-e...
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
  #include <linux/kernel.h>
  
  /*
   * From efi_variable.c,
   *
   * Mapping between UEFI variables and u-boot variables:
   *
   *   efi_$guid_$varname = {attributes}(type)value
   */
  
  static const struct {
  	u32 mask;
  	char *text;
  } efi_var_attrs[] = {
  	{EFI_VARIABLE_NON_VOLATILE, "NV"},
  	{EFI_VARIABLE_BOOTSERVICE_ACCESS, "BS"},
  	{EFI_VARIABLE_RUNTIME_ACCESS, "RT"},
  	{EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS, "AW"},
  	{EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS, "AT"},
  };
051aa89f4   AKASHI Takahiro   cmd: env: extend ...
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
  static const struct {
  	efi_guid_t guid;
  	char *text;
  } efi_guid_text[] = {
  	/* signature database */
  	{EFI_GLOBAL_VARIABLE_GUID, "EFI_GLOBAL_VARIABLE_GUID"},
  };
  
  /* "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" */
  static char unknown_guid[37];
  
  /**
   * efi_guid_to_str() - convert guid to readable name
   *
   * @guid:	GUID
   * Return:	string for GUID
   *
   * convert guid to readable name
   */
  static const char *efi_guid_to_str(const efi_guid_t *guid)
  {
  	int i;
  
  	for (i = 0; i < ARRAY_SIZE(efi_guid_text); i++)
  		if (!guidcmp(guid, &efi_guid_text[i].guid))
  			return efi_guid_text[i].text;
  
  	uuid_bin_to_str((unsigned char *)guid->b, unknown_guid,
  			UUID_STR_FORMAT_GUID);
  
  	return unknown_guid;
  }
49d81fdfb   AKASHI Takahiro   cmd: env: add "-e...
69
70
71
72
73
  /**
   * efi_dump_single_var() - show information about a UEFI variable
   *
   * @name:	Name of the variable
   * @guid:	Vendor GUID
051aa89f4   AKASHI Takahiro   cmd: env: extend ...
74
   * @verbose:	if true, dump data
49d81fdfb   AKASHI Takahiro   cmd: env: add "-e...
75
76
77
   *
   * Show information encoded in one UEFI variable
   */
051aa89f4   AKASHI Takahiro   cmd: env: extend ...
78
  static void efi_dump_single_var(u16 *name, const efi_guid_t *guid, bool verbose)
49d81fdfb   AKASHI Takahiro   cmd: env: add "-e...
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
  {
  	u32 attributes;
  	u8 *data;
  	efi_uintn_t size;
  	int count, i;
  	efi_status_t ret;
  
  	data = NULL;
  	size = 0;
  	ret = EFI_CALL(efi_get_variable(name, guid, &attributes, &size, data));
  	if (ret == EFI_BUFFER_TOO_SMALL) {
  		data = malloc(size);
  		if (!data)
  			goto out;
  
  		ret = EFI_CALL(efi_get_variable(name, guid, &attributes, &size,
  						data));
  	}
  	if (ret == EFI_NOT_FOUND) {
  		printf("Error: \"%ls\" not defined
  ", name);
  		goto out;
  	}
  	if (ret != EFI_SUCCESS)
  		goto out;
051aa89f4   AKASHI Takahiro   cmd: env: extend ...
104
105
  	printf("%ls:
      %s:", name, efi_guid_to_str(guid));
49d81fdfb   AKASHI Takahiro   cmd: env: add "-e...
106
107
108
109
110
111
112
113
114
115
116
  	for (count = 0, i = 0; i < ARRAY_SIZE(efi_var_attrs); i++)
  		if (attributes & efi_var_attrs[i].mask) {
  			if (count)
  				putc('|');
  			else
  				putc(' ');
  			count++;
  			puts(efi_var_attrs[i].text);
  		}
  	printf(", DataSize = 0x%zx
  ", size);
051aa89f4   AKASHI Takahiro   cmd: env: extend ...
117
118
119
  	if (verbose)
  		print_hex_dump("    ", DUMP_PREFIX_OFFSET, 16, 1,
  			       data, size, true);
49d81fdfb   AKASHI Takahiro   cmd: env: add "-e...
120

49d81fdfb   AKASHI Takahiro   cmd: env: add "-e...
121
122
123
124
125
126
127
128
129
  out:
  	free(data);
  }
  
  /**
   * efi_dump_vars() - show information about named UEFI variables
   *
   * @argc:	Number of arguments (variables)
   * @argv:	Argument (variable name) array
051aa89f4   AKASHI Takahiro   cmd: env: extend ...
130
   * @verbose:	if true, dump data
49d81fdfb   AKASHI Takahiro   cmd: env: add "-e...
131
132
133
134
   * Return:	CMD_RET_SUCCESS on success, or CMD_RET_RET_FAILURE
   *
   * Show information encoded in named UEFI variables
   */
051aa89f4   AKASHI Takahiro   cmd: env: extend ...
135
136
  static int efi_dump_vars(int argc,  char * const argv[],
  			 const efi_guid_t *guid, bool verbose)
49d81fdfb   AKASHI Takahiro   cmd: env: add "-e...
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
  {
  	u16 *var_name16, *p;
  	efi_uintn_t buf_size, size;
  
  	buf_size = 128;
  	var_name16 = malloc(buf_size);
  	if (!var_name16)
  		return CMD_RET_FAILURE;
  
  	for (; argc > 0; argc--, argv++) {
  		size = (utf8_utf16_strlen(argv[0]) + 1) * sizeof(u16);
  		if (buf_size < size) {
  			buf_size = size;
  			p = realloc(var_name16, buf_size);
  			if (!p) {
  				free(var_name16);
  				return CMD_RET_FAILURE;
  			}
  			var_name16 = p;
  		}
  
  		p = var_name16;
  		utf8_utf16_strcpy(&p, argv[0]);
051aa89f4   AKASHI Takahiro   cmd: env: extend ...
160
  		efi_dump_single_var(var_name16, guid, verbose);
49d81fdfb   AKASHI Takahiro   cmd: env: add "-e...
161
162
163
164
165
166
  	}
  
  	free(var_name16);
  
  	return CMD_RET_SUCCESS;
  }
051aa89f4   AKASHI Takahiro   cmd: env: extend ...
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
  static bool match_name(int argc, char * const argv[], u16 *var_name16)
  {
  	char *buf, *p;
  	size_t buflen;
  	int i;
  	bool result = false;
  
  	buflen = utf16_utf8_strlen(var_name16) + 1;
  	buf = calloc(1, buflen);
  	if (!buf)
  		return result;
  
  	p = buf;
  	utf16_utf8_strcpy(&p, var_name16);
  
  	for (i = 0; i < argc; argc--, argv++) {
  		if (!strcmp(buf, argv[i])) {
  			result = true;
  			goto out;
  		}
  	}
  
  out:
  	free(buf);
  
  	return result;
  }
49d81fdfb   AKASHI Takahiro   cmd: env: add "-e...
194
  /**
051aa89f4   AKASHI Takahiro   cmd: env: extend ...
195
   * efi_dump_var_all() - show information about all the UEFI variables
49d81fdfb   AKASHI Takahiro   cmd: env: add "-e...
196
   *
051aa89f4   AKASHI Takahiro   cmd: env: extend ...
197
198
199
   * @argc:	Number of arguments (variables)
   * @argv:	Argument (variable name) array
   * @verbose:	if true, dump data
49d81fdfb   AKASHI Takahiro   cmd: env: add "-e...
200
201
202
203
   * Return:	CMD_RET_SUCCESS on success, or CMD_RET_RET_FAILURE
   *
   * Show information encoded in all the UEFI variables
   */
051aa89f4   AKASHI Takahiro   cmd: env: extend ...
204
205
  static int efi_dump_var_all(int argc,  char * const argv[],
  			    const efi_guid_t *guid_p, bool verbose)
49d81fdfb   AKASHI Takahiro   cmd: env: add "-e...
206
207
208
209
210
  {
  	u16 *var_name16, *p;
  	efi_uintn_t buf_size, size;
  	efi_guid_t guid;
  	efi_status_t ret;
051aa89f4   AKASHI Takahiro   cmd: env: extend ...
211
212
213
  	if (argc && guid_p)
  		/* simplified case */
  		return efi_dump_vars(argc, argv, guid_p, verbose);
49d81fdfb   AKASHI Takahiro   cmd: env: add "-e...
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
  	buf_size = 128;
  	var_name16 = malloc(buf_size);
  	if (!var_name16)
  		return CMD_RET_FAILURE;
  
  	var_name16[0] = 0;
  	for (;;) {
  		size = buf_size;
  		ret = EFI_CALL(efi_get_next_variable_name(&size, var_name16,
  							  &guid));
  		if (ret == EFI_NOT_FOUND)
  			break;
  		if (ret == EFI_BUFFER_TOO_SMALL) {
  			buf_size = size;
  			p = realloc(var_name16, buf_size);
  			if (!p) {
  				free(var_name16);
  				return CMD_RET_FAILURE;
  			}
  			var_name16 = p;
  			ret = EFI_CALL(efi_get_next_variable_name(&size,
  								  var_name16,
  								  &guid));
  		}
  		if (ret != EFI_SUCCESS) {
  			free(var_name16);
  			return CMD_RET_FAILURE;
  		}
051aa89f4   AKASHI Takahiro   cmd: env: extend ...
242
243
244
  		if ((!guid_p || !guidcmp(guid_p, &guid)) &&
  		    (!argc || match_name(argc, argv, var_name16)))
  			efi_dump_single_var(var_name16, &guid, verbose);
49d81fdfb   AKASHI Takahiro   cmd: env: add "-e...
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
  	}
  
  	free(var_name16);
  
  	return CMD_RET_SUCCESS;
  }
  
  /**
   * do_env_print_efi() - show information about UEFI variables
   *
   * @cmdtp:	Command table
   * @flag:	Command flag
   * @argc:	Number of arguments
   * @argv:	Argument array
   * Return:	CMD_RET_SUCCESS on success, or CMD_RET_RET_FAILURE
   *
   * This function is for "env print -e" or "printenv -e" command:
051aa89f4   AKASHI Takahiro   cmd: env: extend ...
262
   *   => env print -e [-n] [-guid <guid> | -all] [var [...]]
49d81fdfb   AKASHI Takahiro   cmd: env: add "-e...
263
264
265
266
267
   * If one or more variable names are specified, show information
   * named UEFI variables, otherwise show all the UEFI variables.
   */
  int do_env_print_efi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
  {
051aa89f4   AKASHI Takahiro   cmd: env: extend ...
268
269
270
  	efi_guid_t guid;
  	const efi_guid_t *guid_p;
  	bool default_guid, guid_any, verbose;
49d81fdfb   AKASHI Takahiro   cmd: env: add "-e...
271
272
273
274
275
276
277
278
279
280
  	efi_status_t ret;
  
  	/* Initialize EFI drivers */
  	ret = efi_init_obj_list();
  	if (ret != EFI_SUCCESS) {
  		printf("Error: Cannot initialize UEFI sub-system, r = %lu
  ",
  		       ret & ~EFI_ERROR_MASK);
  		return CMD_RET_FAILURE;
  	}
051aa89f4   AKASHI Takahiro   cmd: env: extend ...
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
  	default_guid = true;
  	guid_any = false;
  	verbose = true;
  	for (argc--, argv++; argc > 0 && argv[0][0] == '-'; argc--, argv++) {
  		if (!strcmp(argv[0], "-guid")) {
  			if (argc == 1)
  				return CMD_RET_USAGE;
  
  			/* -a already specified */
  			if (!default_guid & guid_any)
  				return CMD_RET_USAGE;
  
  			argc--;
  			argv++;
  			if (uuid_str_to_bin(argv[0], guid.b,
  					    UUID_STR_FORMAT_GUID))
  				return CMD_RET_USAGE;
  			default_guid = false;
  		} else if (!strcmp(argv[0], "-all")) {
  			/* -guid already specified */
  			if (!default_guid && !guid_any)
  				return CMD_RET_USAGE;
  
  			guid_any = true;
  			default_guid = false;
  		} else if (!strcmp(argv[0], "-n")) {
  			verbose = false;
  		} else {
  			return CMD_RET_USAGE;
  		}
  	}
  
  	if (guid_any)
  		guid_p = NULL;
  	else if (default_guid)
  		guid_p = &efi_global_variable_guid;
  	else
  		guid_p = (const efi_guid_t *)guid.b;
49d81fdfb   AKASHI Takahiro   cmd: env: add "-e...
319
320
  
  	/* enumerate and show all UEFI variables */
051aa89f4   AKASHI Takahiro   cmd: env: extend ...
321
  	return efi_dump_var_all(argc, argv, guid_p, verbose);
49d81fdfb   AKASHI Takahiro   cmd: env: add "-e...
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
  }
  
  /**
   * append_value() - encode UEFI variable's value
   * @bufp:	Buffer of encoded UEFI variable's value
   * @sizep:	Size of buffer
   * @data:	data to be encoded into the value
   * Return:	0 on success, -1 otherwise
   *
   * Interpret a given data string and append it to buffer.
   * Buffer will be realloc'ed if necessary.
   *
   * Currently supported formats are:
   *   =0x0123...:		Hexadecimal number
   *   =H0123...:			Hexadecimal-byte array
   *   ="...", =S"..." or <string>:
   *				String
   */
  static int append_value(char **bufp, size_t *sizep, char *data)
  {
  	char *tmp_buf = NULL, *new_buf = NULL, *value;
  	unsigned long len = 0;
  
  	if (!strncmp(data, "=0x", 2)) { /* hexadecimal number */
  		union {
  			u8 u8;
  			u16 u16;
  			u32 u32;
  			u64 u64;
  		} tmp_data;
  		unsigned long hex_value;
  		void *hex_ptr;
  
  		data += 3;
  		len = strlen(data);
  		if ((len & 0x1)) /* not multiple of two */
  			return -1;
  
  		len /= 2;
  		if (len > 8)
  			return -1;
  		else if (len > 4)
  			len = 8;
  		else if (len > 2)
  			len = 4;
  
  		/* convert hex hexadecimal number */
  		if (strict_strtoul(data, 16, &hex_value) < 0)
  			return -1;
  
  		tmp_buf = malloc(len);
  		if (!tmp_buf)
  			return -1;
  
  		if (len == 1) {
  			tmp_data.u8 = hex_value;
  			hex_ptr = &tmp_data.u8;
  		} else if (len == 2) {
  			tmp_data.u16 = hex_value;
  			hex_ptr = &tmp_data.u16;
  		} else if (len == 4) {
  			tmp_data.u32 = hex_value;
  			hex_ptr = &tmp_data.u32;
  		} else {
  			tmp_data.u64 = hex_value;
  			hex_ptr = &tmp_data.u64;
  		}
  		memcpy(tmp_buf, hex_ptr, len);
  		value = tmp_buf;
  
  	} else if (!strncmp(data, "=H", 2)) { /* hexadecimal-byte array */
  		data += 2;
  		len = strlen(data);
  		if (len & 0x1) /* not multiple of two */
  			return -1;
  
  		len /= 2;
  		tmp_buf = malloc(len);
  		if (!tmp_buf)
  			return -1;
45203e0cc   Heinrich Schuchardt   efi_loader: memor...
402
403
404
405
  		if (hex2bin((u8 *)tmp_buf, data, len) < 0) {
  			printf("Error: illegal hexadecimal string
  ");
  			free(tmp_buf);
49d81fdfb   AKASHI Takahiro   cmd: env: add "-e...
406
  			return -1;
45203e0cc   Heinrich Schuchardt   efi_loader: memor...
407
  		}
49d81fdfb   AKASHI Takahiro   cmd: env: add "-e...
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
  
  		value = tmp_buf;
  	} else { /* string */
  		if (!strncmp(data, "=\"", 2) || !strncmp(data, "=S\"", 3)) {
  			if (data[1] == '"')
  				data += 2;
  			else
  				data += 3;
  			value = data;
  			len = strlen(data) - 1;
  			if (data[len] != '"')
  				return -1;
  		} else {
  			value = data;
  			len = strlen(data);
  		}
  	}
  
  	new_buf = realloc(*bufp, *sizep + len);
  	if (!new_buf)
  		goto out;
  
  	memcpy(new_buf + *sizep, value, len);
  	*bufp = new_buf;
  	*sizep += len;
  
  out:
  	free(tmp_buf);
  
  	return 0;
  }
  
  /**
6810caf85   AKASHI Takahiro   cmd: env: fix a t...
441
   * do_env_set_efi() - set UEFI variable
49d81fdfb   AKASHI Takahiro   cmd: env: add "-e...
442
443
444
445
446
447
448
449
   *
   * @cmdtp:	Command table
   * @flag:	Command flag
   * @argc:	Number of arguments
   * @argv:	Argument array
   * Return:	CMD_RET_SUCCESS on success, or CMD_RET_RET_FAILURE
   *
   * This function is for "env set -e" or "setenv -e" command:
051aa89f4   AKASHI Takahiro   cmd: env: extend ...
450
451
452
   *   => env set -e [-guid guid][-nv][-bs][-rt][-a][-v]
   *		   [-i address,size] var, or
   *                 var [value ...]
49d81fdfb   AKASHI Takahiro   cmd: env: add "-e...
453
454
455
456
457
   * Encode values specified and set given UEFI variable.
   * If no value is specified, delete the variable.
   */
  int do_env_set_efi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
  {
051aa89f4   AKASHI Takahiro   cmd: env: extend ...
458
459
460
  	char *var_name, *value, *ep;
  	ulong addr;
  	efi_uintn_t size;
49d81fdfb   AKASHI Takahiro   cmd: env: add "-e...
461
  	efi_guid_t guid;
4b27a7613   AKASHI Takahiro   cmd: env: add -nv...
462
  	u32 attributes;
051aa89f4   AKASHI Takahiro   cmd: env: extend ...
463
464
465
  	bool default_guid, verbose, value_on_memory;
  	u16 *var_name16 = NULL, *p;
  	size_t len;
49d81fdfb   AKASHI Takahiro   cmd: env: add "-e...
466
467
468
469
470
471
472
473
474
475
476
477
478
  	efi_status_t ret;
  
  	if (argc == 1)
  		return CMD_RET_USAGE;
  
  	/* Initialize EFI drivers */
  	ret = efi_init_obj_list();
  	if (ret != EFI_SUCCESS) {
  		printf("Error: Cannot initialize UEFI sub-system, r = %lu
  ",
  		       ret & ~EFI_ERROR_MASK);
  		return CMD_RET_FAILURE;
  	}
051aa89f4   AKASHI Takahiro   cmd: env: extend ...
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
  	/*
  	 * attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS |
  	 *	     EFI_VARIABLE_RUNTIME_ACCESS;
  	 */
  	value = NULL;
  	size = 0;
  	attributes = 0;
  	guid = efi_global_variable_guid;
  	default_guid = true;
  	verbose = false;
  	value_on_memory = false;
  	for (argc--, argv++; argc > 0 && argv[0][0] == '-'; argc--, argv++) {
  		if (!strcmp(argv[0], "-guid")) {
  			if (argc == 1)
  				return CMD_RET_USAGE;
  
  			argc--;
  			argv++;
  			if (uuid_str_to_bin(argv[0], guid.b,
  					    UUID_STR_FORMAT_GUID)) {
  				printf("## Guid not specified or in XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX format
  ");
  				return CMD_RET_FAILURE;
  			}
  			default_guid = false;
  		} else if (!strcmp(argv[0], "-bs")) {
  			attributes |= EFI_VARIABLE_BOOTSERVICE_ACCESS;
  		} else if (!strcmp(argv[0], "-rt")) {
  			attributes |= EFI_VARIABLE_RUNTIME_ACCESS;
  		} else if (!strcmp(argv[0], "-nv")) {
  			attributes |= EFI_VARIABLE_NON_VOLATILE;
  		} else if (!strcmp(argv[0], "-a")) {
  			attributes |= EFI_VARIABLE_APPEND_WRITE;
  		} else if (!strcmp(argv[0], "-i")) {
  			/* data comes from memory */
  			if (argc == 1)
  				return CMD_RET_USAGE;
  
  			argc--;
  			argv++;
  			addr = simple_strtoul(argv[0], &ep, 16);
  			if (*ep != ',')
  				return CMD_RET_USAGE;
  
  			size = simple_strtoul(++ep, NULL, 16);
  			if (!size)
  				return CMD_RET_FAILURE;
  			value_on_memory = true;
  		} else if (!strcmp(argv[0], "-v")) {
  			verbose = true;
  		} else {
  			return CMD_RET_USAGE;
  		}
4b27a7613   AKASHI Takahiro   cmd: env: add -nv...
532
  	}
051aa89f4   AKASHI Takahiro   cmd: env: extend ...
533
534
  	if (!argc)
  		return CMD_RET_USAGE;
4b27a7613   AKASHI Takahiro   cmd: env: add -nv...
535

051aa89f4   AKASHI Takahiro   cmd: env: extend ...
536
537
538
539
540
541
542
543
544
545
546
  	var_name = argv[0];
  	if (default_guid)
  		guid = efi_global_variable_guid;
  
  	if (verbose) {
  		printf("GUID: %s
  ", efi_guid_to_str((const efi_guid_t *)
  						     &guid));
  		printf("Attributes: 0x%x
  ", attributes);
  	}
49d81fdfb   AKASHI Takahiro   cmd: env: add "-e...
547

051aa89f4   AKASHI Takahiro   cmd: env: extend ...
548
549
550
551
552
  	/* for value */
  	if (value_on_memory)
  		value = map_sysmem(addr, 0);
  	else if (argc > 1)
  		for (argc--, argv++; argc > 0; argc--, argv++)
49d81fdfb   AKASHI Takahiro   cmd: env: add "-e...
553
  			if (append_value(&value, &size, argv[0]) < 0) {
8190b4a3e   AKASHI Takahiro   cmd: env: print a...
554
555
556
  				printf("## Failed to process an argument, %s
  ",
  				       argv[0]);
49d81fdfb   AKASHI Takahiro   cmd: env: add "-e...
557
558
559
  				ret = CMD_RET_FAILURE;
  				goto out;
  			}
051aa89f4   AKASHI Takahiro   cmd: env: extend ...
560
561
562
563
564
565
  
  	if (size && verbose) {
  		printf("Value:
  ");
  		print_hex_dump("    ", DUMP_PREFIX_OFFSET,
  			       16, 1, value, size, true);
49d81fdfb   AKASHI Takahiro   cmd: env: add "-e...
566
567
568
569
570
  	}
  
  	len = utf8_utf16_strnlen(var_name, strlen(var_name));
  	var_name16 = malloc((len + 1) * 2);
  	if (!var_name16) {
8190b4a3e   AKASHI Takahiro   cmd: env: print a...
571
572
  		printf("## Out of memory
  ");
49d81fdfb   AKASHI Takahiro   cmd: env: add "-e...
573
574
575
576
577
  		ret = CMD_RET_FAILURE;
  		goto out;
  	}
  	p = var_name16;
  	utf8_utf16_strncpy(&p, var_name, len + 1);
4b27a7613   AKASHI Takahiro   cmd: env: add -nv...
578
  	ret = EFI_CALL(efi_set_variable(var_name16, &guid, attributes,
49d81fdfb   AKASHI Takahiro   cmd: env: add "-e...
579
  					size, value));
051aa89f4   AKASHI Takahiro   cmd: env: extend ...
580
  	unmap_sysmem(value);
8190b4a3e   AKASHI Takahiro   cmd: env: print a...
581
582
583
  	if (ret == EFI_SUCCESS) {
  		ret = CMD_RET_SUCCESS;
  	} else {
051aa89f4   AKASHI Takahiro   cmd: env: extend ...
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
  		const char *msg;
  
  		switch (ret) {
  		case EFI_NOT_FOUND:
  			msg = " (not found)";
  			break;
  		case EFI_WRITE_PROTECTED:
  			msg = " (read only)";
  			break;
  		case EFI_INVALID_PARAMETER:
  			msg = " (invalid parameter)";
  			break;
  		case EFI_SECURITY_VIOLATION:
  			msg = " (validation failed)";
  			break;
  		case EFI_OUT_OF_RESOURCES:
  			msg = " (out of memory)";
  			break;
  		default:
  			msg = "";
  			break;
  		}
  		printf("## Failed to set EFI variable%s
  ", msg);
8190b4a3e   AKASHI Takahiro   cmd: env: print a...
608
609
  		ret = CMD_RET_FAILURE;
  	}
49d81fdfb   AKASHI Takahiro   cmd: env: add "-e...
610
  out:
051aa89f4   AKASHI Takahiro   cmd: env: extend ...
611
612
613
614
  	if (value_on_memory)
  		unmap_sysmem(value);
  	else
  		free(value);
49d81fdfb   AKASHI Takahiro   cmd: env: add "-e...
615
616
617
618
  	free(var_name16);
  
  	return ret;
  }