1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
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
69
70
71
72
73
74
75
76
77
78
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
104
105
106
107
108
109
110
111
|
// SPDX-License-Identifier: GPL-2.0+
/*
* SPI Flash interface for UEFI variables
*
* Copyright (c) 2023, Shantur Rathore
* Copyright (C) 2026, Advanced Micro Devices, Inc.
*/
#define LOG_CATEGORY LOGC_EFI
#include <efi_loader.h>
#include <efi_variable.h>
#include <spi_flash.h>
#include <dm.h>
efi_status_t efi_var_to_storage(void)
{
struct efi_var_file *buf;
struct spi_flash *flash;
struct udevice *sfdev;
efi_status_t ret;
size_t erase_len;
loff_t len;
int r;
ret = efi_var_collect(&buf, &len, EFI_VARIABLE_NON_VOLATILE);
if (ret != EFI_SUCCESS)
goto error;
if (len > EFI_VAR_BUF_SIZE) {
log_debug("EFI var buffer length more than target SPI Flash size\n");
ret = EFI_OUT_OF_RESOURCES;
goto error;
}
log_debug("Got buffer to write buf->len: %d\n", buf->length);
r = uclass_get_device(UCLASS_SPI_FLASH,
CONFIG_EFI_VARIABLE_SF_DEVICE_INDEX, &sfdev);
if (r) {
ret = EFI_DEVICE_ERROR;
goto error;
}
flash = dev_get_uclass_priv(sfdev);
if (!flash) {
log_debug("Failed to get SPI Flash priv data\n");
ret = EFI_DEVICE_ERROR;
goto error;
}
erase_len = ALIGN(len, flash->sector_size);
r = spi_flash_erase_dm(sfdev, CONFIG_EFI_VARIABLE_SF_OFFSET,
erase_len);
if (r) {
log_debug("Failed to erase SPI Flash\n");
ret = EFI_DEVICE_ERROR;
goto error;
}
r = spi_flash_write_dm(sfdev, CONFIG_EFI_VARIABLE_SF_OFFSET, len, buf);
if (r) {
log_debug("Failed to write to SPI Flash: %d\n", r);
ret = EFI_DEVICE_ERROR;
}
error:
free(buf);
return ret;
}
efi_status_t efi_var_from_storage(void)
{
struct efi_var_file *buf;
struct udevice *sfdev;
efi_status_t ret;
int r;
buf = calloc(1, EFI_VAR_BUF_SIZE);
if (!buf) {
log_err("Unable to allocate buffer\n");
return EFI_OUT_OF_RESOURCES;
}
r = uclass_get_device(UCLASS_SPI_FLASH,
CONFIG_EFI_VARIABLE_SF_DEVICE_INDEX, &sfdev);
if (r) {
log_err("Failed to get SPI Flash device: %d\n", r);
ret = EFI_DEVICE_ERROR;
goto error;
}
r = spi_flash_read_dm(sfdev, CONFIG_EFI_VARIABLE_SF_OFFSET,
EFI_VAR_BUF_SIZE, buf);
if (r) {
log_err("Failed to read from SPI Flash: %d\n", r);
ret = EFI_DEVICE_ERROR;
goto error;
}
if (efi_var_restore(buf, false) != EFI_SUCCESS) {
log_err("No valid EFI variables in SPI Flash\n");
ret = EFI_DEVICE_ERROR;
goto error;
}
ret = EFI_SUCCESS;
error:
free(buf);
return ret;
}
|