mirror of
https://xff.cz/git/u-boot/
synced 2025-09-02 09:12:08 +02:00
Merge tag 'efi-2019-07-rc4' of git://git.denx.de/u-boot-efi
Pull request for UEFI sub-system for v2019.07-rc4 Corrections for boottime services for protocols and for the SetTime() service are provided. Error messages for the 'setenv -e' and 'bootefi bootmgr' commands are added.
This commit is contained in:
@@ -373,6 +373,8 @@ int do_env_set_efi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
|||||||
|
|
||||||
for ( ; argc > 0; argc--, argv++)
|
for ( ; argc > 0; argc--, argv++)
|
||||||
if (append_value(&value, &size, argv[0]) < 0) {
|
if (append_value(&value, &size, argv[0]) < 0) {
|
||||||
|
printf("## Failed to process an argument, %s\n",
|
||||||
|
argv[0]);
|
||||||
ret = CMD_RET_FAILURE;
|
ret = CMD_RET_FAILURE;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@@ -381,6 +383,7 @@ int do_env_set_efi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
|||||||
len = utf8_utf16_strnlen(var_name, strlen(var_name));
|
len = utf8_utf16_strnlen(var_name, strlen(var_name));
|
||||||
var_name16 = malloc((len + 1) * 2);
|
var_name16 = malloc((len + 1) * 2);
|
||||||
if (!var_name16) {
|
if (!var_name16) {
|
||||||
|
printf("## Out of memory\n");
|
||||||
ret = CMD_RET_FAILURE;
|
ret = CMD_RET_FAILURE;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@@ -392,7 +395,12 @@ int do_env_set_efi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
|||||||
EFI_VARIABLE_BOOTSERVICE_ACCESS |
|
EFI_VARIABLE_BOOTSERVICE_ACCESS |
|
||||||
EFI_VARIABLE_RUNTIME_ACCESS,
|
EFI_VARIABLE_RUNTIME_ACCESS,
|
||||||
size, value));
|
size, value));
|
||||||
ret = (ret == EFI_SUCCESS ? CMD_RET_SUCCESS : CMD_RET_FAILURE);
|
if (ret == EFI_SUCCESS) {
|
||||||
|
ret = CMD_RET_SUCCESS;
|
||||||
|
} else {
|
||||||
|
printf("## Failed to set EFI variable\n");
|
||||||
|
ret = CMD_RET_FAILURE;
|
||||||
|
}
|
||||||
out:
|
out:
|
||||||
free(value);
|
free(value);
|
||||||
free(var_name16);
|
free(var_name16);
|
||||||
|
@@ -23,7 +23,7 @@ static const unsigned char rtc_days_in_month[] = {
|
|||||||
/*
|
/*
|
||||||
* The number of days in the month.
|
* The number of days in the month.
|
||||||
*/
|
*/
|
||||||
static int rtc_month_days(unsigned int month, unsigned int year)
|
int rtc_month_days(unsigned int month, unsigned int year)
|
||||||
{
|
{
|
||||||
return rtc_days_in_month[month] + (is_leap_year(year) && month == 1);
|
return rtc_days_in_month[month] + (is_leap_year(year) && month == 1);
|
||||||
}
|
}
|
||||||
|
@@ -286,20 +286,38 @@ extern struct list_head efi_obj_list;
|
|||||||
/* List of all events */
|
/* List of all events */
|
||||||
extern struct list_head efi_events;
|
extern struct list_head efi_events;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct efi_protocol_notification - handle for notified protocol
|
||||||
|
*
|
||||||
|
* When a protocol interface is installed for which an event was registered with
|
||||||
|
* the RegisterProtocolNotify() service this structure is used to hold the
|
||||||
|
* handle on which the protocol interface was installed.
|
||||||
|
*
|
||||||
|
* @link: link to list of all handles notified for this event
|
||||||
|
* @handle: handle on which the notified protocol interface was installed
|
||||||
|
*/
|
||||||
|
struct efi_protocol_notification {
|
||||||
|
struct list_head link;
|
||||||
|
efi_handle_t handle;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* efi_register_notify_event - event registered by RegisterProtocolNotify()
|
* efi_register_notify_event - event registered by RegisterProtocolNotify()
|
||||||
*
|
*
|
||||||
* The address of this structure serves as registration value.
|
* The address of this structure serves as registration value.
|
||||||
*
|
*
|
||||||
* @link: link to list of all registered events
|
* @link: link to list of all registered events
|
||||||
* @event: registered event. The same event may registered for
|
* @event: registered event. The same event may registered for multiple
|
||||||
* multiple GUIDs.
|
* GUIDs.
|
||||||
* @protocol: protocol for which the event is registered
|
* @protocol: protocol for which the event is registered
|
||||||
|
* @handles: linked list of all handles on which the notified protocol was
|
||||||
|
* installed
|
||||||
*/
|
*/
|
||||||
struct efi_register_notify_event {
|
struct efi_register_notify_event {
|
||||||
struct list_head link;
|
struct list_head link;
|
||||||
struct efi_event *event;
|
struct efi_event *event;
|
||||||
efi_guid_t protocol;
|
efi_guid_t protocol;
|
||||||
|
struct list_head handles;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* List of all events registered by RegisterProtocolNotify() */
|
/* List of all events registered by RegisterProtocolNotify() */
|
||||||
@@ -576,6 +594,8 @@ efi_status_t __efi_runtime EFIAPI efi_get_time(
|
|||||||
struct efi_time *time,
|
struct efi_time *time,
|
||||||
struct efi_time_cap *capabilities);
|
struct efi_time_cap *capabilities);
|
||||||
|
|
||||||
|
efi_status_t __efi_runtime EFIAPI efi_set_time(struct efi_time *time);
|
||||||
|
|
||||||
#ifdef CONFIG_CMD_BOOTEFI_SELFTEST
|
#ifdef CONFIG_CMD_BOOTEFI_SELFTEST
|
||||||
/*
|
/*
|
||||||
* Entry point for the tests of the EFI API.
|
* Entry point for the tests of the EFI API.
|
||||||
|
@@ -258,4 +258,12 @@ void rtc_to_tm(u64 time_t, struct rtc_time *time);
|
|||||||
*/
|
*/
|
||||||
unsigned long rtc_mktime(const struct rtc_time *time);
|
unsigned long rtc_mktime(const struct rtc_time *time);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* rtc_month_days() - The number of days in the month
|
||||||
|
*
|
||||||
|
* @month: month (January = 0)
|
||||||
|
* @year: year (4 digits)
|
||||||
|
*/
|
||||||
|
int rtc_month_days(unsigned int month, unsigned int year);
|
||||||
|
|
||||||
#endif /* _RTC_H_ */
|
#endif /* _RTC_H_ */
|
||||||
|
@@ -18,6 +18,22 @@ config EFI_LOADER
|
|||||||
|
|
||||||
if EFI_LOADER
|
if EFI_LOADER
|
||||||
|
|
||||||
|
config EFI_GET_TIME
|
||||||
|
bool "GetTime() runtime service"
|
||||||
|
depends on DM_RTC
|
||||||
|
default y
|
||||||
|
help
|
||||||
|
Provide the GetTime() runtime service at boottime. This service
|
||||||
|
can be used by an EFI application to read the real time clock.
|
||||||
|
|
||||||
|
config EFI_SET_TIME
|
||||||
|
bool "SetTime() runtime service"
|
||||||
|
depends on EFI_GET_TIME
|
||||||
|
default n
|
||||||
|
help
|
||||||
|
Provide the SetTime() runtime service at boottime. This service
|
||||||
|
can be used by an EFI application to adjust the real time clock.
|
||||||
|
|
||||||
config EFI_DEVICE_PATH_TO_TEXT
|
config EFI_DEVICE_PATH_TO_TEXT
|
||||||
bool "Device path to text protocol"
|
bool "Device path to text protocol"
|
||||||
default y
|
default y
|
||||||
|
@@ -149,8 +149,11 @@ static efi_status_t try_load_entry(u16 n, efi_handle_t *handle)
|
|||||||
|
|
||||||
ret = EFI_CALL(efi_load_image(true, efi_root, lo.file_path,
|
ret = EFI_CALL(efi_load_image(true, efi_root, lo.file_path,
|
||||||
NULL, 0, handle));
|
NULL, 0, handle));
|
||||||
if (ret != EFI_SUCCESS)
|
if (ret != EFI_SUCCESS) {
|
||||||
|
printf("Loading from Boot%04X '%ls' failed\n", n,
|
||||||
|
lo.label);
|
||||||
goto error;
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS |
|
attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS |
|
||||||
EFI_VARIABLE_RUNTIME_ACCESS;
|
EFI_VARIABLE_RUNTIME_ACCESS;
|
||||||
@@ -215,6 +218,7 @@ efi_status_t efi_bootmgr_load(efi_handle_t *handle)
|
|||||||
ret = try_load_entry(bootnext, handle);
|
ret = try_load_entry(bootnext, handle);
|
||||||
if (ret == EFI_SUCCESS)
|
if (ret == EFI_SUCCESS)
|
||||||
return ret;
|
return ret;
|
||||||
|
printf("Loading from BootNext failed, falling back to BootOrder\n");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
printf("Deleting BootNext failed\n");
|
printf("Deleting BootNext failed\n");
|
||||||
|
@@ -921,6 +921,14 @@ static efi_status_t EFIAPI efi_close_event(struct efi_event *event)
|
|||||||
list_for_each_entry_safe(item, next, &efi_register_notify_events,
|
list_for_each_entry_safe(item, next, &efi_register_notify_events,
|
||||||
link) {
|
link) {
|
||||||
if (event == item->event) {
|
if (event == item->event) {
|
||||||
|
struct efi_protocol_notification *hitem, *hnext;
|
||||||
|
|
||||||
|
/* Remove signaled handles */
|
||||||
|
list_for_each_entry_safe(hitem, hnext, &item->handles,
|
||||||
|
link) {
|
||||||
|
list_del(&hitem->link);
|
||||||
|
free(hitem);
|
||||||
|
}
|
||||||
list_del(&item->link);
|
list_del(&item->link);
|
||||||
free(item);
|
free(item);
|
||||||
}
|
}
|
||||||
@@ -1049,9 +1057,20 @@ efi_status_t efi_add_protocol(const efi_handle_t handle,
|
|||||||
|
|
||||||
/* Notify registered events */
|
/* Notify registered events */
|
||||||
list_for_each_entry(event, &efi_register_notify_events, link) {
|
list_for_each_entry(event, &efi_register_notify_events, link) {
|
||||||
if (!guidcmp(protocol, &event->protocol))
|
if (!guidcmp(protocol, &event->protocol)) {
|
||||||
|
struct efi_protocol_notification *notif;
|
||||||
|
|
||||||
|
notif = calloc(1, sizeof(*notif));
|
||||||
|
if (!notif) {
|
||||||
|
list_del(&handler->link);
|
||||||
|
free(handler);
|
||||||
|
return EFI_OUT_OF_RESOURCES;
|
||||||
|
}
|
||||||
|
notif->handle = handle;
|
||||||
|
list_add_tail(¬if->link, &event->handles);
|
||||||
efi_signal_event(event->event, true);
|
efi_signal_event(event->event, true);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!guidcmp(&efi_guid_device_path, protocol))
|
if (!guidcmp(&efi_guid_device_path, protocol))
|
||||||
EFI_PRINT("installed device path '%pD'\n", protocol_interface);
|
EFI_PRINT("installed device path '%pD'\n", protocol_interface);
|
||||||
@@ -1241,10 +1260,6 @@ static efi_status_t efi_uninstall_protocol
|
|||||||
goto out;
|
goto out;
|
||||||
/* Disconnect controllers */
|
/* Disconnect controllers */
|
||||||
efi_disconnect_all_drivers(efiobj, protocol, NULL);
|
efi_disconnect_all_drivers(efiobj, protocol, NULL);
|
||||||
if (!list_empty(&handler->open_infos)) {
|
|
||||||
r = EFI_ACCESS_DENIED;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
/* Close protocol */
|
/* Close protocol */
|
||||||
list_for_each_entry_safe(item, pos, &handler->open_infos, link) {
|
list_for_each_entry_safe(item, pos, &handler->open_infos, link) {
|
||||||
if (item->info.attributes ==
|
if (item->info.attributes ==
|
||||||
@@ -1332,6 +1347,7 @@ static efi_status_t EFIAPI efi_register_protocol_notify(
|
|||||||
|
|
||||||
item->event = event;
|
item->event = event;
|
||||||
memcpy(&item->protocol, protocol, sizeof(efi_guid_t));
|
memcpy(&item->protocol, protocol, sizeof(efi_guid_t));
|
||||||
|
INIT_LIST_HEAD(&item->handles);
|
||||||
|
|
||||||
list_add_tail(&item->link, &efi_register_notify_events);
|
list_add_tail(&item->link, &efi_register_notify_events);
|
||||||
|
|
||||||
@@ -1359,7 +1375,6 @@ static int efi_search(enum efi_locate_search_type search_type,
|
|||||||
switch (search_type) {
|
switch (search_type) {
|
||||||
case ALL_HANDLES:
|
case ALL_HANDLES:
|
||||||
return 0;
|
return 0;
|
||||||
case BY_REGISTER_NOTIFY:
|
|
||||||
case BY_PROTOCOL:
|
case BY_PROTOCOL:
|
||||||
ret = efi_search_protocol(handle, protocol, NULL);
|
ret = efi_search_protocol(handle, protocol, NULL);
|
||||||
return (ret != EFI_SUCCESS);
|
return (ret != EFI_SUCCESS);
|
||||||
@@ -1369,6 +1384,27 @@ static int efi_search(enum efi_locate_search_type search_type,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* efi_check_register_notify_event() - check if registration key is valid
|
||||||
|
*
|
||||||
|
* Check that a pointer is a valid registration key as returned by
|
||||||
|
* RegisterProtocolNotify().
|
||||||
|
*
|
||||||
|
* @key: registration key
|
||||||
|
* Return: valid registration key or NULL
|
||||||
|
*/
|
||||||
|
static struct efi_register_notify_event *efi_check_register_notify_event
|
||||||
|
(void *key)
|
||||||
|
{
|
||||||
|
struct efi_register_notify_event *event;
|
||||||
|
|
||||||
|
list_for_each_entry(event, &efi_register_notify_events, link) {
|
||||||
|
if (event == (struct efi_register_notify_event *)key)
|
||||||
|
return event;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* efi_locate_handle() - locate handles implementing a protocol
|
* efi_locate_handle() - locate handles implementing a protocol
|
||||||
*
|
*
|
||||||
@@ -1390,7 +1426,8 @@ static efi_status_t efi_locate_handle(
|
|||||||
{
|
{
|
||||||
struct efi_object *efiobj;
|
struct efi_object *efiobj;
|
||||||
efi_uintn_t size = 0;
|
efi_uintn_t size = 0;
|
||||||
struct efi_register_notify_event *item, *event = NULL;
|
struct efi_register_notify_event *event;
|
||||||
|
struct efi_protocol_notification *handle = NULL;
|
||||||
|
|
||||||
/* Check parameters */
|
/* Check parameters */
|
||||||
switch (search_type) {
|
switch (search_type) {
|
||||||
@@ -1400,17 +1437,9 @@ static efi_status_t efi_locate_handle(
|
|||||||
if (!search_key)
|
if (!search_key)
|
||||||
return EFI_INVALID_PARAMETER;
|
return EFI_INVALID_PARAMETER;
|
||||||
/* Check that the registration key is valid */
|
/* Check that the registration key is valid */
|
||||||
list_for_each_entry(item, &efi_register_notify_events, link) {
|
event = efi_check_register_notify_event(search_key);
|
||||||
if (item ==
|
|
||||||
(struct efi_register_notify_event *)search_key) {
|
|
||||||
event = item;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!event)
|
if (!event)
|
||||||
return EFI_INVALID_PARAMETER;
|
return EFI_INVALID_PARAMETER;
|
||||||
|
|
||||||
protocol = &event->protocol;
|
|
||||||
break;
|
break;
|
||||||
case BY_PROTOCOL:
|
case BY_PROTOCOL:
|
||||||
if (!protocol)
|
if (!protocol)
|
||||||
@@ -1421,13 +1450,22 @@ static efi_status_t efi_locate_handle(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Count how much space we need */
|
/* Count how much space we need */
|
||||||
|
if (search_type == BY_REGISTER_NOTIFY) {
|
||||||
|
if (list_empty(&event->handles))
|
||||||
|
return EFI_NOT_FOUND;
|
||||||
|
handle = list_first_entry(&event->handles,
|
||||||
|
struct efi_protocol_notification,
|
||||||
|
link);
|
||||||
|
efiobj = handle->handle;
|
||||||
|
size += sizeof(void *);
|
||||||
|
} else {
|
||||||
list_for_each_entry(efiobj, &efi_obj_list, link) {
|
list_for_each_entry(efiobj, &efi_obj_list, link) {
|
||||||
if (!efi_search(search_type, protocol, efiobj))
|
if (!efi_search(search_type, protocol, efiobj))
|
||||||
size += sizeof(void *);
|
size += sizeof(void *);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
return EFI_NOT_FOUND;
|
return EFI_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
if (!buffer_size)
|
if (!buffer_size)
|
||||||
return EFI_INVALID_PARAMETER;
|
return EFI_INVALID_PARAMETER;
|
||||||
@@ -1444,10 +1482,15 @@ static efi_status_t efi_locate_handle(
|
|||||||
return EFI_INVALID_PARAMETER;
|
return EFI_INVALID_PARAMETER;
|
||||||
|
|
||||||
/* Then fill the array */
|
/* Then fill the array */
|
||||||
|
if (search_type == BY_REGISTER_NOTIFY) {
|
||||||
|
*buffer = efiobj;
|
||||||
|
list_del(&handle->link);
|
||||||
|
} else {
|
||||||
list_for_each_entry(efiobj, &efi_obj_list, link) {
|
list_for_each_entry(efiobj, &efi_obj_list, link) {
|
||||||
if (!efi_search(search_type, protocol, efiobj))
|
if (!efi_search(search_type, protocol, efiobj))
|
||||||
*buffer++ = efiobj;
|
*buffer++ = efiobj;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
@@ -2013,7 +2056,6 @@ static efi_status_t EFIAPI efi_close_protocol(efi_handle_t handle,
|
|||||||
item->info.controller_handle == controller_handle) {
|
item->info.controller_handle == controller_handle) {
|
||||||
efi_delete_open_info(item);
|
efi_delete_open_info(item);
|
||||||
r = EFI_SUCCESS;
|
r = EFI_SUCCESS;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
@@ -2212,30 +2254,59 @@ static efi_status_t EFIAPI efi_locate_protocol(const efi_guid_t *protocol,
|
|||||||
void *registration,
|
void *registration,
|
||||||
void **protocol_interface)
|
void **protocol_interface)
|
||||||
{
|
{
|
||||||
struct list_head *lhandle;
|
struct efi_handler *handler;
|
||||||
efi_status_t ret;
|
efi_status_t ret;
|
||||||
|
struct efi_object *efiobj;
|
||||||
|
|
||||||
EFI_ENTRY("%pUl, %p, %p", protocol, registration, protocol_interface);
|
EFI_ENTRY("%pUl, %p, %p", protocol, registration, protocol_interface);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The UEFI spec explicitly requires a protocol even if a registration
|
||||||
|
* key is provided. This differs from the logic in LocateHandle().
|
||||||
|
*/
|
||||||
if (!protocol || !protocol_interface)
|
if (!protocol || !protocol_interface)
|
||||||
return EFI_EXIT(EFI_INVALID_PARAMETER);
|
return EFI_EXIT(EFI_INVALID_PARAMETER);
|
||||||
|
|
||||||
list_for_each(lhandle, &efi_obj_list) {
|
if (registration) {
|
||||||
struct efi_object *efiobj;
|
struct efi_register_notify_event *event;
|
||||||
struct efi_handler *handler;
|
struct efi_protocol_notification *handle;
|
||||||
|
|
||||||
efiobj = list_entry(lhandle, struct efi_object, link);
|
|
||||||
|
|
||||||
|
event = efi_check_register_notify_event(registration);
|
||||||
|
if (!event)
|
||||||
|
return EFI_EXIT(EFI_INVALID_PARAMETER);
|
||||||
|
/*
|
||||||
|
* The UEFI spec requires to return EFI_NOT_FOUND if no
|
||||||
|
* protocol instance matches protocol and registration.
|
||||||
|
* So let's do the same for a mismatch between protocol and
|
||||||
|
* registration.
|
||||||
|
*/
|
||||||
|
if (guidcmp(&event->protocol, protocol))
|
||||||
|
goto not_found;
|
||||||
|
if (list_empty(&event->handles))
|
||||||
|
goto not_found;
|
||||||
|
handle = list_first_entry(&event->handles,
|
||||||
|
struct efi_protocol_notification,
|
||||||
|
link);
|
||||||
|
efiobj = handle->handle;
|
||||||
|
list_del(&handle->link);
|
||||||
|
free(handle);
|
||||||
ret = efi_search_protocol(efiobj, protocol, &handler);
|
ret = efi_search_protocol(efiobj, protocol, &handler);
|
||||||
if (ret == EFI_SUCCESS) {
|
if (ret == EFI_SUCCESS)
|
||||||
|
goto found;
|
||||||
|
} else {
|
||||||
|
list_for_each_entry(efiobj, &efi_obj_list, link) {
|
||||||
|
ret = efi_search_protocol(efiobj, protocol, &handler);
|
||||||
|
if (ret == EFI_SUCCESS)
|
||||||
|
goto found;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
not_found:
|
||||||
|
*protocol_interface = NULL;
|
||||||
|
return EFI_EXIT(EFI_NOT_FOUND);
|
||||||
|
found:
|
||||||
*protocol_interface = handler->protocol_interface;
|
*protocol_interface = handler->protocol_interface;
|
||||||
return EFI_EXIT(EFI_SUCCESS);
|
return EFI_EXIT(EFI_SUCCESS);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
*protocol_interface = NULL;
|
|
||||||
|
|
||||||
return EFI_EXIT(EFI_NOT_FOUND);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* efi_locate_device_path() - Get the device path and handle of an device
|
* efi_locate_device_path() - Get the device path and handle of an device
|
||||||
@@ -2561,34 +2632,50 @@ static efi_status_t efi_protocol_open(
|
|||||||
if ((attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) &&
|
if ((attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) &&
|
||||||
(item->info.attributes == attributes))
|
(item->info.attributes == attributes))
|
||||||
return EFI_ALREADY_STARTED;
|
return EFI_ALREADY_STARTED;
|
||||||
|
} else {
|
||||||
|
if (item->info.attributes &
|
||||||
|
EFI_OPEN_PROTOCOL_BY_DRIVER)
|
||||||
|
opened_by_driver = true;
|
||||||
}
|
}
|
||||||
if (item->info.attributes & EFI_OPEN_PROTOCOL_EXCLUSIVE)
|
if (item->info.attributes & EFI_OPEN_PROTOCOL_EXCLUSIVE)
|
||||||
opened_exclusive = true;
|
opened_exclusive = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Only one controller can open the protocol exclusively */
|
/* Only one controller can open the protocol exclusively */
|
||||||
if (opened_exclusive && attributes &
|
if (attributes & EFI_OPEN_PROTOCOL_EXCLUSIVE) {
|
||||||
(EFI_OPEN_PROTOCOL_EXCLUSIVE | EFI_OPEN_PROTOCOL_BY_DRIVER))
|
if (opened_exclusive)
|
||||||
return EFI_ACCESS_DENIED;
|
return EFI_ACCESS_DENIED;
|
||||||
|
} else if (attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) {
|
||||||
|
if (opened_exclusive || opened_by_driver)
|
||||||
|
return EFI_ACCESS_DENIED;
|
||||||
|
}
|
||||||
|
|
||||||
/* Prepare exclusive opening */
|
/* Prepare exclusive opening */
|
||||||
if (attributes & EFI_OPEN_PROTOCOL_EXCLUSIVE) {
|
if (attributes & EFI_OPEN_PROTOCOL_EXCLUSIVE) {
|
||||||
/* Try to disconnect controllers */
|
/* Try to disconnect controllers */
|
||||||
|
disconnect_next:
|
||||||
|
opened_by_driver = false;
|
||||||
list_for_each_entry(item, &handler->open_infos, link) {
|
list_for_each_entry(item, &handler->open_infos, link) {
|
||||||
|
efi_status_t ret;
|
||||||
|
|
||||||
if (item->info.attributes ==
|
if (item->info.attributes ==
|
||||||
EFI_OPEN_PROTOCOL_BY_DRIVER)
|
EFI_OPEN_PROTOCOL_BY_DRIVER) {
|
||||||
EFI_CALL(efi_disconnect_controller(
|
ret = EFI_CALL(efi_disconnect_controller(
|
||||||
item->info.controller_handle,
|
item->info.controller_handle,
|
||||||
item->info.agent_handle,
|
item->info.agent_handle,
|
||||||
NULL));
|
NULL));
|
||||||
}
|
if (ret == EFI_SUCCESS)
|
||||||
opened_by_driver = false;
|
/*
|
||||||
/* Check if all controllers are disconnected */
|
* Child controllers may have been
|
||||||
list_for_each_entry(item, &handler->open_infos, link) {
|
* removed from the open_infos list. So
|
||||||
if (item->info.attributes & EFI_OPEN_PROTOCOL_BY_DRIVER)
|
* let's restart the loop.
|
||||||
|
*/
|
||||||
|
goto disconnect_next;
|
||||||
|
else
|
||||||
opened_by_driver = true;
|
opened_by_driver = true;
|
||||||
}
|
}
|
||||||
/* Only one controller can be connected */
|
}
|
||||||
|
/* Only one driver can be connected */
|
||||||
if (opened_by_driver)
|
if (opened_by_driver)
|
||||||
return EFI_ACCESS_DENIED;
|
return EFI_ACCESS_DENIED;
|
||||||
}
|
}
|
||||||
@@ -2596,7 +2683,8 @@ static efi_status_t efi_protocol_open(
|
|||||||
/* Find existing entry */
|
/* Find existing entry */
|
||||||
list_for_each_entry(item, &handler->open_infos, link) {
|
list_for_each_entry(item, &handler->open_infos, link) {
|
||||||
if (item->info.agent_handle == agent_handle &&
|
if (item->info.agent_handle == agent_handle &&
|
||||||
item->info.controller_handle == controller_handle)
|
item->info.controller_handle == controller_handle &&
|
||||||
|
item->info.attributes == attributes)
|
||||||
match = &item->info;
|
match = &item->info;
|
||||||
}
|
}
|
||||||
/* None found, create one */
|
/* None found, create one */
|
||||||
@@ -2985,7 +3073,7 @@ static efi_status_t EFIAPI efi_handle_protocol(efi_handle_t handle,
|
|||||||
const efi_guid_t *protocol,
|
const efi_guid_t *protocol,
|
||||||
void **protocol_interface)
|
void **protocol_interface)
|
||||||
{
|
{
|
||||||
return efi_open_protocol(handle, protocol, protocol_interface, NULL,
|
return efi_open_protocol(handle, protocol, protocol_interface, efi_root,
|
||||||
NULL, EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL);
|
NULL, EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -167,7 +167,7 @@ static efi_status_t EFIAPI efi_get_time_boottime(
|
|||||||
struct efi_time *time,
|
struct efi_time *time,
|
||||||
struct efi_time_cap *capabilities)
|
struct efi_time_cap *capabilities)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_DM_RTC
|
#ifdef CONFIG_EFI_GET_TIME
|
||||||
efi_status_t ret = EFI_SUCCESS;
|
efi_status_t ret = EFI_SUCCESS;
|
||||||
struct rtc_time tm;
|
struct rtc_time tm;
|
||||||
struct udevice *dev;
|
struct udevice *dev;
|
||||||
@@ -195,9 +195,9 @@ static efi_status_t EFIAPI efi_get_time_boottime(
|
|||||||
time->hour = tm.tm_hour;
|
time->hour = tm.tm_hour;
|
||||||
time->minute = tm.tm_min;
|
time->minute = tm.tm_min;
|
||||||
time->second = tm.tm_sec;
|
time->second = tm.tm_sec;
|
||||||
time->daylight = EFI_TIME_ADJUST_DAYLIGHT;
|
if (tm.tm_isdst)
|
||||||
if (tm.tm_isdst > 0)
|
time->daylight =
|
||||||
time->daylight |= EFI_TIME_IN_DAYLIGHT;
|
EFI_TIME_ADJUST_DAYLIGHT | EFI_TIME_IN_DAYLIGHT;
|
||||||
time->timezone = EFI_UNSPECIFIED_TIMEZONE;
|
time->timezone = EFI_UNSPECIFIED_TIMEZONE;
|
||||||
|
|
||||||
if (capabilities) {
|
if (capabilities) {
|
||||||
@@ -214,6 +214,30 @@ out:
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_EFI_SET_TIME
|
||||||
|
|
||||||
|
/**
|
||||||
|
* efi_validate_time() - checks if timestamp is valid
|
||||||
|
*
|
||||||
|
* @time: timestamp to validate
|
||||||
|
* Returns: 0 if timestamp is valid, 1 otherwise
|
||||||
|
*/
|
||||||
|
static int efi_validate_time(struct efi_time *time)
|
||||||
|
{
|
||||||
|
return (!time ||
|
||||||
|
time->year < 1900 || time->year > 9999 ||
|
||||||
|
!time->month || time->month > 12 || !time->day ||
|
||||||
|
time->day > rtc_month_days(time->month - 1, time->year) ||
|
||||||
|
time->hour > 23 || time->minute > 59 || time->second > 59 ||
|
||||||
|
time->nanosecond > 999999999 ||
|
||||||
|
time->daylight &
|
||||||
|
~(EFI_TIME_IN_DAYLIGHT | EFI_TIME_ADJUST_DAYLIGHT) ||
|
||||||
|
((time->timezone < -1440 || time->timezone > 1440) &&
|
||||||
|
time->timezone != EFI_UNSPECIFIED_TIMEZONE));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* efi_set_time_boottime() - set current time
|
* efi_set_time_boottime() - set current time
|
||||||
*
|
*
|
||||||
@@ -228,14 +252,14 @@ out:
|
|||||||
*/
|
*/
|
||||||
static efi_status_t EFIAPI efi_set_time_boottime(struct efi_time *time)
|
static efi_status_t EFIAPI efi_set_time_boottime(struct efi_time *time)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_DM_RTC
|
#ifdef CONFIG_EFI_SET_TIME
|
||||||
efi_status_t ret = EFI_SUCCESS;
|
efi_status_t ret = EFI_SUCCESS;
|
||||||
struct rtc_time tm;
|
struct rtc_time tm;
|
||||||
struct udevice *dev;
|
struct udevice *dev;
|
||||||
|
|
||||||
EFI_ENTRY("%p", time);
|
EFI_ENTRY("%p", time);
|
||||||
|
|
||||||
if (!time) {
|
if (efi_validate_time(time)) {
|
||||||
ret = EFI_INVALID_PARAMETER;
|
ret = EFI_INVALID_PARAMETER;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@@ -252,7 +276,8 @@ static efi_status_t EFIAPI efi_set_time_boottime(struct efi_time *time)
|
|||||||
tm.tm_hour = time->hour;
|
tm.tm_hour = time->hour;
|
||||||
tm.tm_min = time->minute;
|
tm.tm_min = time->minute;
|
||||||
tm.tm_sec = time->second;
|
tm.tm_sec = time->second;
|
||||||
tm.tm_isdst = time->daylight == EFI_TIME_IN_DAYLIGHT;
|
tm.tm_isdst = time->daylight ==
|
||||||
|
(EFI_TIME_ADJUST_DAYLIGHT | EFI_TIME_IN_DAYLIGHT);
|
||||||
/* Calculate day of week */
|
/* Calculate day of week */
|
||||||
rtc_calc_weekday(&tm);
|
rtc_calc_weekday(&tm);
|
||||||
|
|
||||||
|
@@ -26,8 +26,8 @@ efi_selftest_gop.o \
|
|||||||
efi_selftest_loaded_image.o \
|
efi_selftest_loaded_image.o \
|
||||||
efi_selftest_manageprotocols.o \
|
efi_selftest_manageprotocols.o \
|
||||||
efi_selftest_memory.o \
|
efi_selftest_memory.o \
|
||||||
|
efi_selftest_open_protocol.o \
|
||||||
efi_selftest_register_notify.o \
|
efi_selftest_register_notify.o \
|
||||||
efi_selftest_rtc.o \
|
|
||||||
efi_selftest_snp.o \
|
efi_selftest_snp.o \
|
||||||
efi_selftest_textinput.o \
|
efi_selftest_textinput.o \
|
||||||
efi_selftest_textinputex.o \
|
efi_selftest_textinputex.o \
|
||||||
@@ -43,6 +43,7 @@ efi_selftest_unicode_collation.o
|
|||||||
|
|
||||||
obj-$(CONFIG_CPU_V7) += efi_selftest_unaligned.o
|
obj-$(CONFIG_CPU_V7) += efi_selftest_unaligned.o
|
||||||
obj-$(CONFIG_EFI_LOADER_HII) += efi_selftest_hii.o
|
obj-$(CONFIG_EFI_LOADER_HII) += efi_selftest_hii.o
|
||||||
|
obj-$(CONFIG_EFI_GET_TIME) += efi_selftest_rtc.o
|
||||||
|
|
||||||
ifeq ($(CONFIG_GENERATE_ACPI_TABLE),)
|
ifeq ($(CONFIG_GENERATE_ACPI_TABLE),)
|
||||||
obj-y += efi_selftest_fdt.o
|
obj-y += efi_selftest_fdt.o
|
||||||
|
205
lib/efi_selftest/efi_selftest_open_protocol.c
Normal file
205
lib/efi_selftest/efi_selftest_open_protocol.c
Normal file
@@ -0,0 +1,205 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0+
|
||||||
|
/*
|
||||||
|
* efi_selftest_open_protocol
|
||||||
|
*
|
||||||
|
* Copyright (c) 2019 Heinrich Schuchardt <xypron.glpk@gmx.de>
|
||||||
|
*
|
||||||
|
* This unit test checks that open protocol information is correctly updated
|
||||||
|
* when calling:
|
||||||
|
* HandleProtocol, OpenProtocol, OpenProtocolInformation, CloseProtocol.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <efi_selftest.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The test currently does not actually call the interface function.
|
||||||
|
* So this is just a dummy structure.
|
||||||
|
*/
|
||||||
|
struct interface {
|
||||||
|
void (EFIAPI *inc)(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct efi_boot_services *boottime;
|
||||||
|
static efi_guid_t guid1 =
|
||||||
|
EFI_GUID(0x492a0e38, 0x1442, 0xf819,
|
||||||
|
0x14, 0xaa, 0x4b, 0x8d, 0x09, 0xfe, 0x5a, 0xb9);
|
||||||
|
static efi_handle_t handle1;
|
||||||
|
static struct interface interface1;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Setup unit test.
|
||||||
|
*
|
||||||
|
* Create a handle and install a protocol interface on it.
|
||||||
|
*
|
||||||
|
* @handle: handle of the loaded image
|
||||||
|
* @systable: system table
|
||||||
|
*/
|
||||||
|
static int setup(const efi_handle_t img_handle,
|
||||||
|
const struct efi_system_table *systable)
|
||||||
|
{
|
||||||
|
efi_status_t ret;
|
||||||
|
|
||||||
|
boottime = systable->boottime;
|
||||||
|
|
||||||
|
ret = boottime->install_protocol_interface(&handle1, &guid1,
|
||||||
|
EFI_NATIVE_INTERFACE,
|
||||||
|
&interface1);
|
||||||
|
if (ret != EFI_SUCCESS) {
|
||||||
|
efi_st_error("InstallProtocolInterface failed\n");
|
||||||
|
return EFI_ST_FAILURE;
|
||||||
|
}
|
||||||
|
if (!handle1) {
|
||||||
|
efi_st_error
|
||||||
|
("InstallProtocolInterface failed to create handle\n");
|
||||||
|
return EFI_ST_FAILURE;
|
||||||
|
}
|
||||||
|
return EFI_ST_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tear down unit test.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static int teardown(void)
|
||||||
|
{
|
||||||
|
efi_status_t ret;
|
||||||
|
|
||||||
|
if (handle1) {
|
||||||
|
ret = boottime->uninstall_protocol_interface(handle1, &guid1,
|
||||||
|
&interface1);
|
||||||
|
if (ret != EFI_SUCCESS) {
|
||||||
|
efi_st_error("UninstallProtocolInterface failed\n");
|
||||||
|
return EFI_ST_FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return EFI_ST_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Execute unit test.
|
||||||
|
*
|
||||||
|
* Open the installed protocol twice via HandleProtocol() and once via
|
||||||
|
* OpenProtocol(EFI_OPEN_PROTOCOL_GET_PROTOCOL). Read the open protocol
|
||||||
|
* information and check the open counts. Finally close the protocol and
|
||||||
|
* check again.
|
||||||
|
*/
|
||||||
|
static int execute(void)
|
||||||
|
{
|
||||||
|
void *interface;
|
||||||
|
struct efi_open_protocol_info_entry *entry_buffer;
|
||||||
|
efi_uintn_t entry_count;
|
||||||
|
efi_handle_t firmware_handle;
|
||||||
|
efi_status_t ret;
|
||||||
|
|
||||||
|
ret = boottime->handle_protocol(handle1, &guid1, &interface);
|
||||||
|
if (ret != EFI_SUCCESS) {
|
||||||
|
efi_st_error("HandleProtocol failed\n");
|
||||||
|
return EFI_ST_FAILURE;
|
||||||
|
}
|
||||||
|
if (interface != &interface1) {
|
||||||
|
efi_st_error("HandleProtocol returned wrong interface\n");
|
||||||
|
return EFI_ST_FAILURE;
|
||||||
|
}
|
||||||
|
ret = boottime->open_protocol_information(handle1, &guid1,
|
||||||
|
&entry_buffer, &entry_count);
|
||||||
|
if (ret != EFI_SUCCESS) {
|
||||||
|
efi_st_error("OpenProtocolInformation failed\n");
|
||||||
|
return EFI_ST_FAILURE;
|
||||||
|
}
|
||||||
|
if (entry_count != 1) {
|
||||||
|
efi_st_error("Incorrect OpenProtocolInformation count\n");
|
||||||
|
efi_st_printf("Expected 1, got %u\n",
|
||||||
|
(unsigned int)entry_count);
|
||||||
|
return EFI_ST_FAILURE;
|
||||||
|
}
|
||||||
|
ret = boottime->free_pool(entry_buffer);
|
||||||
|
if (ret != EFI_SUCCESS) {
|
||||||
|
efi_st_error("FreePool failed\n");
|
||||||
|
return EFI_ST_FAILURE;
|
||||||
|
}
|
||||||
|
ret = boottime->handle_protocol(handle1, &guid1, &interface);
|
||||||
|
if (ret != EFI_SUCCESS) {
|
||||||
|
efi_st_error("HandleProtocol failed\n");
|
||||||
|
return EFI_ST_FAILURE;
|
||||||
|
}
|
||||||
|
ret = boottime->open_protocol_information(handle1, &guid1,
|
||||||
|
&entry_buffer, &entry_count);
|
||||||
|
if (ret != EFI_SUCCESS) {
|
||||||
|
efi_st_error("OpenProtocolInformation failed\n");
|
||||||
|
return EFI_ST_FAILURE;
|
||||||
|
}
|
||||||
|
if (entry_count != 1) {
|
||||||
|
efi_st_error("Incorrect OpenProtocolInformation count\n");
|
||||||
|
efi_st_printf("Expected 1, got %u\n",
|
||||||
|
(unsigned int)entry_count);
|
||||||
|
return EFI_ST_FAILURE;
|
||||||
|
}
|
||||||
|
if (entry_buffer[0].open_count != 2) {
|
||||||
|
efi_st_error("Incorrect open count: expected 2 got %u\n",
|
||||||
|
entry_buffer[0].open_count);
|
||||||
|
return EFI_ST_FAILURE;
|
||||||
|
}
|
||||||
|
firmware_handle = entry_buffer[0].agent_handle;
|
||||||
|
ret = boottime->free_pool(entry_buffer);
|
||||||
|
if (ret != EFI_SUCCESS) {
|
||||||
|
efi_st_error("FreePool failed\n");
|
||||||
|
return EFI_ST_FAILURE;
|
||||||
|
}
|
||||||
|
ret = boottime->open_protocol(handle1, &guid1, &interface,
|
||||||
|
firmware_handle, NULL,
|
||||||
|
EFI_OPEN_PROTOCOL_GET_PROTOCOL);
|
||||||
|
if (ret != EFI_SUCCESS) {
|
||||||
|
efi_st_error("OpenProtocol failed\n");
|
||||||
|
return EFI_ST_FAILURE;
|
||||||
|
}
|
||||||
|
ret = boottime->open_protocol_information(handle1, &guid1,
|
||||||
|
&entry_buffer, &entry_count);
|
||||||
|
if (ret != EFI_SUCCESS) {
|
||||||
|
efi_st_error("OpenProtocolInformation failed\n");
|
||||||
|
return EFI_ST_FAILURE;
|
||||||
|
}
|
||||||
|
if (entry_count != 2) {
|
||||||
|
efi_st_error("Incorrect OpenProtocolInformation count\n");
|
||||||
|
efi_st_printf("Expected 2, got %u\n",
|
||||||
|
(unsigned int)entry_count);
|
||||||
|
return EFI_ST_FAILURE;
|
||||||
|
}
|
||||||
|
if (entry_buffer[0].open_count + entry_buffer[1].open_count != 3) {
|
||||||
|
efi_st_error("Incorrect open count: expected 3 got %u\n",
|
||||||
|
entry_buffer[0].open_count +
|
||||||
|
entry_buffer[1].open_count);
|
||||||
|
return EFI_ST_FAILURE;
|
||||||
|
}
|
||||||
|
ret = boottime->free_pool(entry_buffer);
|
||||||
|
if (ret != EFI_SUCCESS) {
|
||||||
|
efi_st_error("FreePool failed\n");
|
||||||
|
return EFI_ST_FAILURE;
|
||||||
|
}
|
||||||
|
ret = boottime->close_protocol(handle1, &guid1, firmware_handle, NULL);
|
||||||
|
if (ret != EFI_SUCCESS) {
|
||||||
|
efi_st_error("CloseProtocol failed\n");
|
||||||
|
return EFI_ST_FAILURE;
|
||||||
|
}
|
||||||
|
ret = boottime->open_protocol_information(handle1, &guid1,
|
||||||
|
&entry_buffer, &entry_count);
|
||||||
|
if (ret != EFI_SUCCESS) {
|
||||||
|
efi_st_error("OpenProtocolInformation failed\n");
|
||||||
|
return EFI_ST_FAILURE;
|
||||||
|
}
|
||||||
|
if (entry_count) {
|
||||||
|
efi_st_error("Incorrect OpenProtocolInformation count\n");
|
||||||
|
efi_st_printf("Expected 0, got %u\n",
|
||||||
|
(unsigned int)entry_count);
|
||||||
|
return EFI_ST_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return EFI_ST_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_UNIT_TEST(openprot) = {
|
||||||
|
.name = "open protocol",
|
||||||
|
.phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT,
|
||||||
|
.setup = setup,
|
||||||
|
.execute = execute,
|
||||||
|
.teardown = teardown,
|
||||||
|
};
|
@@ -47,15 +47,20 @@ static void EFIAPI notify(struct efi_event *event, void *context)
|
|||||||
{
|
{
|
||||||
struct context *cp = context;
|
struct context *cp = context;
|
||||||
efi_status_t ret;
|
efi_status_t ret;
|
||||||
|
efi_uintn_t handle_count;
|
||||||
|
efi_handle_t *handles;
|
||||||
|
|
||||||
cp->notify_count++;
|
cp->notify_count++;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
ret = boottime->locate_handle_buffer(BY_REGISTER_NOTIFY, NULL,
|
ret = boottime->locate_handle_buffer(BY_REGISTER_NOTIFY, NULL,
|
||||||
cp->registration_key,
|
cp->registration_key,
|
||||||
&cp->handle_count,
|
&handle_count, &handles);
|
||||||
&cp->handles);
|
|
||||||
if (ret != EFI_SUCCESS)
|
if (ret != EFI_SUCCESS)
|
||||||
cp->handle_count = 0;
|
break;
|
||||||
|
cp->handle_count += handle_count;
|
||||||
|
cp->handles = handles;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -170,7 +175,7 @@ static int execute(void)
|
|||||||
efi_st_error("reinstall was notified too often\n");
|
efi_st_error("reinstall was notified too often\n");
|
||||||
return EFI_ST_FAILURE;
|
return EFI_ST_FAILURE;
|
||||||
}
|
}
|
||||||
if (context.handle_count != 1) {
|
if (context.handle_count != 2) {
|
||||||
efi_st_error("LocateHandle failed\n");
|
efi_st_error("LocateHandle failed\n");
|
||||||
return EFI_ST_FAILURE;
|
return EFI_ST_FAILURE;
|
||||||
}
|
}
|
||||||
@@ -195,7 +200,7 @@ static int execute(void)
|
|||||||
efi_st_error("install was notified too often\n");
|
efi_st_error("install was notified too often\n");
|
||||||
return EFI_ST_FAILURE;
|
return EFI_ST_FAILURE;
|
||||||
}
|
}
|
||||||
if (context.handle_count != 2) {
|
if (context.handle_count != 3) {
|
||||||
efi_st_error("LocateHandle failed\n");
|
efi_st_error("LocateHandle failed\n");
|
||||||
return EFI_ST_FAILURE;
|
return EFI_ST_FAILURE;
|
||||||
}
|
}
|
||||||
|
@@ -40,7 +40,9 @@ static int setup(const efi_handle_t handle,
|
|||||||
static int execute(void)
|
static int execute(void)
|
||||||
{
|
{
|
||||||
efi_status_t ret;
|
efi_status_t ret;
|
||||||
struct efi_time tm, tm_old, tm_new = {
|
struct efi_time tm_old;
|
||||||
|
#ifdef CONFIG_EFI_SET_TIME
|
||||||
|
struct efi_time tm, tm_new = {
|
||||||
.year = 2017,
|
.year = 2017,
|
||||||
.month = 5,
|
.month = 5,
|
||||||
.day = 19,
|
.day = 19,
|
||||||
@@ -48,31 +50,23 @@ static int execute(void)
|
|||||||
.minute = 47,
|
.minute = 47,
|
||||||
.second = 53,
|
.second = 53,
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Display current time */
|
/* Display current time */
|
||||||
ret = runtime->get_time(&tm_old, NULL);
|
ret = runtime->get_time(&tm_old, NULL);
|
||||||
if (ret != EFI_SUCCESS) {
|
if (ret != EFI_SUCCESS) {
|
||||||
#ifdef CONFIG_CMD_DATE
|
|
||||||
efi_st_error(EFI_ST_NO_RTC);
|
efi_st_error(EFI_ST_NO_RTC);
|
||||||
return EFI_ST_FAILURE;
|
return EFI_ST_FAILURE;
|
||||||
#else
|
|
||||||
efi_st_todo(EFI_ST_NO_RTC);
|
|
||||||
return EFI_ST_SUCCESS;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
efi_st_printf("Time according to real time clock: "
|
efi_st_printf("Time according to real time clock: "
|
||||||
"%.4u-%.2u-%.2u %.2u:%.2u:%.2u\n",
|
"%.4u-%.2u-%.2u %.2u:%.2u:%.2u\n",
|
||||||
tm_old.year, tm_old.month, tm_old.day,
|
tm_old.year, tm_old.month, tm_old.day,
|
||||||
tm_old.hour, tm_old.minute, tm_old.second);
|
tm_old.hour, tm_old.minute, tm_old.second);
|
||||||
|
#ifdef CONFIG_EFI_SET_TIME
|
||||||
ret = runtime->set_time(&tm_new);
|
ret = runtime->set_time(&tm_new);
|
||||||
if (ret != EFI_SUCCESS) {
|
if (ret != EFI_SUCCESS) {
|
||||||
#ifdef CONFIG_CMD_DATE
|
|
||||||
efi_st_error(EFI_ST_NO_RTC_SET);
|
efi_st_error(EFI_ST_NO_RTC_SET);
|
||||||
return EFI_ST_FAILURE;
|
return EFI_ST_FAILURE;
|
||||||
#else
|
|
||||||
efi_st_todo(EFI_ST_NO_RTC_SET);
|
|
||||||
return EFI_ST_SUCCESS;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
ret = runtime->get_time(&tm, NULL);
|
ret = runtime->get_time(&tm, NULL);
|
||||||
if (ret != EFI_SUCCESS) {
|
if (ret != EFI_SUCCESS) {
|
||||||
@@ -95,6 +89,7 @@ static int execute(void)
|
|||||||
efi_st_error(EFI_ST_NO_RTC_SET);
|
efi_st_error(EFI_ST_NO_RTC_SET);
|
||||||
return EFI_ST_FAILURE;
|
return EFI_ST_FAILURE;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return EFI_ST_SUCCESS;
|
return EFI_ST_SUCCESS;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user