mirror of
https://github.com/u-boot/u-boot.git
synced 2025-04-20 20:04:46 +00:00
Pull request for UEFI sub-system for v2019.07-rc4-2
Support for managing the non-volatile attribute of UEFI variables is added though we do not have a backend for persistence yet. Error messages for changes of UEFI variables are provided. UEFI boottime service implementations are corrected. -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEbcT5xx8ppvoGt20zxIHbvCwFGsQFAlz3mYcACgkQxIHbvCwF GsTNgw/8DSxiFXvOF6eTWd2POYfu9wjZXCcMtpsfuLA3b58AjF0VfYhoXgQoel1B BnP6wzaIajIM8yafvia38EBloa2ZkBPjqUD/dtvs/hYe9x9kMCqLpsbOgHmjKF4b X6w4j4OOvOaEuKnsi6faWmXfsOWA5laYz6/u1Ewau+0P5SMnt/0piVMqkLofFO1i TcUzzn8MyfuCOu6UH+nqMZMguPaLkiCZX+aS6Q6tDfd5wfVRDtGTMGrMO/X42tLB vqAgW6qRV8U4H08gBx8u2+xiO67soiH+7AVuhc+/6inMCPyAXBwVlr79YihNi75o FOftPJ3hcJ+YkLNSVpwayKzrPa9GCCB2PGVDPCWQMwejIgQMkLPq2xRbFCPmLC4N WM4E11lqLSDL4xUTqhn+bJfRofaIpV9t79VVNAOkwHD7Wj0mnOVWjnpY+bB3n3hN LAneXPiUoQXSy9d3F2dd6J3emQMSTK4TPchGwWyfFwTe8VszynvHbWU8AGyCjbop /XAlBHYfuTLjvB+j8WLfua7ocmMtvIAU3CLC8OJ6bvga/VIPtG17rGAiQ1RP9W0u JZ4QKOnU2M8NiOrq45GIQEUV/UocNDJ2g5fZshLIzNk1it90RFEQ7kR6WYZZg4Hq zHSVjKijqxUcqKfQbSukJInDYI8xS1F+jKgB3HdGCg49ZZb/y74= =mCc9 -----END PGP SIGNATURE----- Merge tag 'efi-2019-07-rc4-2' of git://git.denx.de/u-boot-efi Pull request for UEFI sub-system for v2019.07-rc4-2 Support for managing the non-volatile attribute of UEFI variables is added though we do not have a backend for persistence yet. Error messages for changes of UEFI variables are provided. UEFI boottime service implementations are corrected.
This commit is contained in:
commit
dbbb1c43f2
11 changed files with 100 additions and 21 deletions
|
@ -20,13 +20,6 @@ static uint64_t rockchip_get_ticks(void)
|
||||||
return timebase_h << 32 | timebase_l;
|
return timebase_h << 32 | timebase_l;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint64_t usec_to_tick(unsigned int usec)
|
|
||||||
{
|
|
||||||
uint64_t tick = usec;
|
|
||||||
tick *= CONFIG_SYS_TIMER_RATE / (1000 * 1000);
|
|
||||||
return tick;
|
|
||||||
}
|
|
||||||
|
|
||||||
void rockchip_udelay(unsigned int usec)
|
void rockchip_udelay(unsigned int usec)
|
||||||
{
|
{
|
||||||
uint64_t tmp;
|
uint64_t tmp;
|
||||||
|
|
|
@ -558,6 +558,7 @@ static int do_efi_boot_add(cmd_tbl_t *cmdtp, int flag,
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = EFI_CALL(RT->set_variable(var_name16, &guid,
|
ret = EFI_CALL(RT->set_variable(var_name16, &guid,
|
||||||
|
EFI_VARIABLE_NON_VOLATILE |
|
||||||
EFI_VARIABLE_BOOTSERVICE_ACCESS |
|
EFI_VARIABLE_BOOTSERVICE_ACCESS |
|
||||||
EFI_VARIABLE_RUNTIME_ACCESS,
|
EFI_VARIABLE_RUNTIME_ACCESS,
|
||||||
size, data));
|
size, data));
|
||||||
|
@ -909,6 +910,7 @@ static int do_efi_boot_next(cmd_tbl_t *cmdtp, int flag,
|
||||||
guid = efi_global_variable_guid;
|
guid = efi_global_variable_guid;
|
||||||
size = sizeof(u16);
|
size = sizeof(u16);
|
||||||
ret = EFI_CALL(RT->set_variable(L"BootNext", &guid,
|
ret = EFI_CALL(RT->set_variable(L"BootNext", &guid,
|
||||||
|
EFI_VARIABLE_NON_VOLATILE |
|
||||||
EFI_VARIABLE_BOOTSERVICE_ACCESS |
|
EFI_VARIABLE_BOOTSERVICE_ACCESS |
|
||||||
EFI_VARIABLE_RUNTIME_ACCESS,
|
EFI_VARIABLE_RUNTIME_ACCESS,
|
||||||
size, &bootnext));
|
size, &bootnext));
|
||||||
|
@ -964,6 +966,7 @@ static int do_efi_boot_order(cmd_tbl_t *cmdtp, int flag,
|
||||||
|
|
||||||
guid = efi_global_variable_guid;
|
guid = efi_global_variable_guid;
|
||||||
ret = EFI_CALL(RT->set_variable(L"BootOrder", &guid,
|
ret = EFI_CALL(RT->set_variable(L"BootOrder", &guid,
|
||||||
|
EFI_VARIABLE_NON_VOLATILE |
|
||||||
EFI_VARIABLE_BOOTSERVICE_ACCESS |
|
EFI_VARIABLE_BOOTSERVICE_ACCESS |
|
||||||
EFI_VARIABLE_RUNTIME_ACCESS,
|
EFI_VARIABLE_RUNTIME_ACCESS,
|
||||||
size, bootorder));
|
size, bootorder));
|
||||||
|
|
|
@ -1344,8 +1344,9 @@ U_BOOT_CMD_COMPLETE(
|
||||||
setenv, CONFIG_SYS_MAXARGS, 0, do_env_set,
|
setenv, CONFIG_SYS_MAXARGS, 0, do_env_set,
|
||||||
"set environment variables",
|
"set environment variables",
|
||||||
#if defined(CONFIG_CMD_NVEDIT_EFI)
|
#if defined(CONFIG_CMD_NVEDIT_EFI)
|
||||||
"-e name [value ...]\n"
|
"-e [-nv] name [value ...]\n"
|
||||||
" - set UEFI variable 'name' to 'value' ...'\n"
|
" - set UEFI variable 'name' to 'value' ...'\n"
|
||||||
|
" 'nv' option makes the variable non-volatile\n"
|
||||||
" - delete UEFI variable 'name' if 'value' not specified\n"
|
" - delete UEFI variable 'name' if 'value' not specified\n"
|
||||||
#endif
|
#endif
|
||||||
"setenv [-f] name value ...\n"
|
"setenv [-f] name value ...\n"
|
||||||
|
|
|
@ -349,6 +349,7 @@ int do_env_set_efi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||||
u16 *var_name16 = NULL, *p;
|
u16 *var_name16 = NULL, *p;
|
||||||
size_t len;
|
size_t len;
|
||||||
efi_guid_t guid;
|
efi_guid_t guid;
|
||||||
|
u32 attributes;
|
||||||
efi_status_t ret;
|
efi_status_t ret;
|
||||||
|
|
||||||
if (argc == 1)
|
if (argc == 1)
|
||||||
|
@ -362,6 +363,16 @@ int do_env_set_efi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||||
return CMD_RET_FAILURE;
|
return CMD_RET_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS |
|
||||||
|
EFI_VARIABLE_RUNTIME_ACCESS;
|
||||||
|
if (!strcmp(argv[1], "-nv")) {
|
||||||
|
attributes |= EFI_VARIABLE_NON_VOLATILE;
|
||||||
|
argc--;
|
||||||
|
argv++;
|
||||||
|
if (argc == 1)
|
||||||
|
return CMD_RET_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
var_name = argv[1];
|
var_name = argv[1];
|
||||||
if (argc == 2) {
|
if (argc == 2) {
|
||||||
/* delete */
|
/* delete */
|
||||||
|
@ -391,9 +402,7 @@ int do_env_set_efi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||||
utf8_utf16_strncpy(&p, var_name, len + 1);
|
utf8_utf16_strncpy(&p, var_name, len + 1);
|
||||||
|
|
||||||
guid = efi_global_variable_guid;
|
guid = efi_global_variable_guid;
|
||||||
ret = EFI_CALL(efi_set_variable(var_name16, &guid,
|
ret = EFI_CALL(efi_set_variable(var_name16, &guid, attributes,
|
||||||
EFI_VARIABLE_BOOTSERVICE_ACCESS |
|
|
||||||
EFI_VARIABLE_RUNTIME_ACCESS,
|
|
||||||
size, value));
|
size, value));
|
||||||
if (ret == EFI_SUCCESS) {
|
if (ret == EFI_SUCCESS) {
|
||||||
ret = CMD_RET_SUCCESS;
|
ret = CMD_RET_SUCCESS;
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#define _TIME_H
|
#define _TIME_H
|
||||||
|
|
||||||
#include <linux/typecheck.h>
|
#include <linux/typecheck.h>
|
||||||
|
#include <linux/types.h>
|
||||||
|
|
||||||
unsigned long get_timer(unsigned long base);
|
unsigned long get_timer(unsigned long base);
|
||||||
|
|
||||||
|
@ -21,6 +22,14 @@ unsigned long timer_get_us(void);
|
||||||
*/
|
*/
|
||||||
void timer_test_add_offset(unsigned long offset);
|
void timer_test_add_offset(unsigned long offset);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* usec_to_tick() - convert microseconds to clock ticks
|
||||||
|
*
|
||||||
|
* @usec: duration in microseconds
|
||||||
|
* Return: duration in clock ticks
|
||||||
|
*/
|
||||||
|
uint64_t usec_to_tick(unsigned long usec);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* These inlines deal with timer wrapping correctly. You are
|
* These inlines deal with timer wrapping correctly. You are
|
||||||
* strongly encouraged to use them
|
* strongly encouraged to use them
|
||||||
|
|
|
@ -210,7 +210,8 @@ efi_status_t efi_bootmgr_load(efi_handle_t *handle)
|
||||||
ret = EFI_CALL(efi_set_variable(
|
ret = EFI_CALL(efi_set_variable(
|
||||||
L"BootNext",
|
L"BootNext",
|
||||||
(efi_guid_t *)&efi_global_variable_guid,
|
(efi_guid_t *)&efi_global_variable_guid,
|
||||||
0, 0, &bootnext));
|
EFI_VARIABLE_NON_VOLATILE, 0,
|
||||||
|
&bootnext));
|
||||||
|
|
||||||
/* load BootNext */
|
/* load BootNext */
|
||||||
if (ret == EFI_SUCCESS) {
|
if (ret == EFI_SUCCESS) {
|
||||||
|
|
|
@ -1153,11 +1153,15 @@ static efi_status_t efi_get_drivers(efi_handle_t handle,
|
||||||
++count;
|
++count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*number_of_drivers = 0;
|
||||||
|
if (!count) {
|
||||||
|
*driver_handle_buffer = NULL;
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* Create buffer. In case of duplicate driver assignments the buffer
|
* Create buffer. In case of duplicate driver assignments the buffer
|
||||||
* will be too large. But that does not harm.
|
* will be too large. But that does not harm.
|
||||||
*/
|
*/
|
||||||
*number_of_drivers = 0;
|
|
||||||
*driver_handle_buffer = calloc(count, sizeof(efi_handle_t));
|
*driver_handle_buffer = calloc(count, sizeof(efi_handle_t));
|
||||||
if (!*driver_handle_buffer)
|
if (!*driver_handle_buffer)
|
||||||
return EFI_OUT_OF_RESOURCES;
|
return EFI_OUT_OF_RESOURCES;
|
||||||
|
@ -1213,7 +1217,8 @@ static efi_status_t efi_disconnect_all_drivers
|
||||||
&driver_handle_buffer);
|
&driver_handle_buffer);
|
||||||
if (ret != EFI_SUCCESS)
|
if (ret != EFI_SUCCESS)
|
||||||
return ret;
|
return ret;
|
||||||
|
if (!number_of_drivers)
|
||||||
|
return EFI_SUCCESS;
|
||||||
ret = EFI_NOT_FOUND;
|
ret = EFI_NOT_FOUND;
|
||||||
while (number_of_drivers) {
|
while (number_of_drivers) {
|
||||||
r = EFI_CALL(efi_disconnect_controller(
|
r = EFI_CALL(efi_disconnect_controller(
|
||||||
|
@ -1985,8 +1990,14 @@ out:
|
||||||
*/
|
*/
|
||||||
static efi_status_t EFIAPI efi_stall(unsigned long microseconds)
|
static efi_status_t EFIAPI efi_stall(unsigned long microseconds)
|
||||||
{
|
{
|
||||||
|
u64 end_tick;
|
||||||
|
|
||||||
EFI_ENTRY("%ld", microseconds);
|
EFI_ENTRY("%ld", microseconds);
|
||||||
udelay(microseconds);
|
|
||||||
|
end_tick = get_ticks() + usec_to_tick(microseconds);
|
||||||
|
while (get_ticks() < end_tick)
|
||||||
|
efi_timer_check();
|
||||||
|
|
||||||
return EFI_EXIT(EFI_SUCCESS);
|
return EFI_EXIT(EFI_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2868,12 +2879,46 @@ efi_status_t EFIAPI efi_start_image(efi_handle_t image_handle,
|
||||||
* @image_obj: handle of the loaded image
|
* @image_obj: handle of the loaded image
|
||||||
* @loaded_image_protocol: loaded image protocol
|
* @loaded_image_protocol: loaded image protocol
|
||||||
*/
|
*/
|
||||||
static void efi_delete_image(struct efi_loaded_image_obj *image_obj,
|
static efi_status_t efi_delete_image
|
||||||
struct efi_loaded_image *loaded_image_protocol)
|
(struct efi_loaded_image_obj *image_obj,
|
||||||
|
struct efi_loaded_image *loaded_image_protocol)
|
||||||
{
|
{
|
||||||
|
struct efi_object *efiobj;
|
||||||
|
efi_status_t r, ret = EFI_SUCCESS;
|
||||||
|
|
||||||
|
close_next:
|
||||||
|
list_for_each_entry(efiobj, &efi_obj_list, link) {
|
||||||
|
struct efi_handler *protocol;
|
||||||
|
|
||||||
|
list_for_each_entry(protocol, &efiobj->protocols, link) {
|
||||||
|
struct efi_open_protocol_info_item *info;
|
||||||
|
|
||||||
|
list_for_each_entry(info, &protocol->open_infos, link) {
|
||||||
|
if (info->info.agent_handle !=
|
||||||
|
(efi_handle_t)image_obj)
|
||||||
|
continue;
|
||||||
|
r = EFI_CALL(efi_close_protocol
|
||||||
|
(efiobj, protocol->guid,
|
||||||
|
info->info.agent_handle,
|
||||||
|
info->info.controller_handle
|
||||||
|
));
|
||||||
|
if (r != EFI_SUCCESS)
|
||||||
|
ret = r;
|
||||||
|
/*
|
||||||
|
* Closing protocols may results in further
|
||||||
|
* items being deleted. To play it safe loop
|
||||||
|
* over all elements again.
|
||||||
|
*/
|
||||||
|
goto close_next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
efi_free_pages((uintptr_t)loaded_image_protocol->image_base,
|
efi_free_pages((uintptr_t)loaded_image_protocol->image_base,
|
||||||
efi_size_in_pages(loaded_image_protocol->image_size));
|
efi_size_in_pages(loaded_image_protocol->image_size));
|
||||||
efi_delete_handle(&image_obj->header);
|
efi_delete_handle(&image_obj->header);
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -430,6 +430,7 @@ static efi_status_t EFIAPI efi_cout_enable_cursor(
|
||||||
EFI_ENTRY("%p, %d", this, enable);
|
EFI_ENTRY("%p, %d", this, enable);
|
||||||
|
|
||||||
printf(ESC"[?25%c", enable ? 'h' : 'l');
|
printf(ESC"[?25%c", enable ? 'h' : 'l');
|
||||||
|
efi_con_mode.cursor_visible = !!enable;
|
||||||
|
|
||||||
return EFI_EXIT(EFI_SUCCESS);
|
return EFI_EXIT(EFI_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
|
@ -230,6 +230,7 @@ uint64_t efi_add_memory_map(uint64_t start, uint64_t pages, int memory_type,
|
||||||
struct efi_mem_list *newlist;
|
struct efi_mem_list *newlist;
|
||||||
bool carve_again;
|
bool carve_again;
|
||||||
uint64_t carved_pages = 0;
|
uint64_t carved_pages = 0;
|
||||||
|
struct efi_event *evt;
|
||||||
|
|
||||||
EFI_PRINT("%s: 0x%llx 0x%llx %d %s\n", __func__,
|
EFI_PRINT("%s: 0x%llx 0x%llx %d %s\n", __func__,
|
||||||
start, pages, memory_type, overlap_only_ram ? "yes" : "no");
|
start, pages, memory_type, overlap_only_ram ? "yes" : "no");
|
||||||
|
@ -315,6 +316,16 @@ uint64_t efi_add_memory_map(uint64_t start, uint64_t pages, int memory_type,
|
||||||
/* And make sure memory is listed in descending order */
|
/* And make sure memory is listed in descending order */
|
||||||
efi_mem_sort();
|
efi_mem_sort();
|
||||||
|
|
||||||
|
/* Notify that the memory map was changed */
|
||||||
|
list_for_each_entry(evt, &efi_events, link) {
|
||||||
|
if (evt->group &&
|
||||||
|
!guidcmp(evt->group,
|
||||||
|
&efi_guid_event_group_memory_map_change)) {
|
||||||
|
efi_signal_event(evt, false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return start;
|
return start;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -125,6 +125,8 @@ static const char *parse_attr(const char *str, u32 *attrp)
|
||||||
|
|
||||||
if ((s = prefix(str, "ro"))) {
|
if ((s = prefix(str, "ro"))) {
|
||||||
attr |= READ_ONLY;
|
attr |= READ_ONLY;
|
||||||
|
} else if ((s = prefix(str, "nv"))) {
|
||||||
|
attr |= EFI_VARIABLE_NON_VOLATILE;
|
||||||
} else if ((s = prefix(str, "boot"))) {
|
} else if ((s = prefix(str, "boot"))) {
|
||||||
attr |= EFI_VARIABLE_BOOTSERVICE_ACCESS;
|
attr |= EFI_VARIABLE_BOOTSERVICE_ACCESS;
|
||||||
} else if ((s = prefix(str, "run"))) {
|
} else if ((s = prefix(str, "run"))) {
|
||||||
|
@ -468,7 +470,7 @@ efi_status_t EFIAPI efi_set_variable(u16 *variable_name,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val = malloc(2 * data_size + strlen("{ro,run,boot}(blob)") + 1);
|
val = malloc(2 * data_size + strlen("{ro,run,boot,nv}(blob)") + 1);
|
||||||
if (!val) {
|
if (!val) {
|
||||||
ret = EFI_OUT_OF_RESOURCES;
|
ret = EFI_OUT_OF_RESOURCES;
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -480,12 +482,16 @@ efi_status_t EFIAPI efi_set_variable(u16 *variable_name,
|
||||||
* store attributes
|
* store attributes
|
||||||
* TODO: several attributes are not supported
|
* TODO: several attributes are not supported
|
||||||
*/
|
*/
|
||||||
attributes &= (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS);
|
attributes &= (EFI_VARIABLE_NON_VOLATILE |
|
||||||
|
EFI_VARIABLE_BOOTSERVICE_ACCESS |
|
||||||
|
EFI_VARIABLE_RUNTIME_ACCESS);
|
||||||
s += sprintf(s, "{");
|
s += sprintf(s, "{");
|
||||||
while (attributes) {
|
while (attributes) {
|
||||||
u32 attr = 1 << (ffs(attributes) - 1);
|
u32 attr = 1 << (ffs(attributes) - 1);
|
||||||
|
|
||||||
if (attr == EFI_VARIABLE_BOOTSERVICE_ACCESS)
|
if (attr == EFI_VARIABLE_NON_VOLATILE)
|
||||||
|
s += sprintf(s, "nv");
|
||||||
|
else if (attr == EFI_VARIABLE_BOOTSERVICE_ACCESS)
|
||||||
s += sprintf(s, "boot");
|
s += sprintf(s, "boot");
|
||||||
else if (attr == EFI_VARIABLE_RUNTIME_ACCESS)
|
else if (attr == EFI_VARIABLE_RUNTIME_ACCESS)
|
||||||
s += sprintf(s, "run");
|
s += sprintf(s, "run");
|
||||||
|
|
|
@ -139,7 +139,7 @@ unsigned long __weak notrace timer_get_us(void)
|
||||||
return tick_to_time(get_ticks() * 1000);
|
return tick_to_time(get_ticks() * 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint64_t usec_to_tick(unsigned long usec)
|
uint64_t usec_to_tick(unsigned long usec)
|
||||||
{
|
{
|
||||||
uint64_t tick = usec;
|
uint64_t tick = usec;
|
||||||
tick *= get_tbclk();
|
tick *= get_tbclk();
|
||||||
|
|
Loading…
Add table
Reference in a new issue