mirror of
https://xff.cz/git/u-boot/
synced 2025-09-29 22:41:17 +02:00
Merge tag 'efi-2019-07-rc3-3' of git://git.denx.de/u-boot-efi
Pull request for UEFI sub-system for v2019.07-rc3 (3) Several bug fixes for the UEFI sub-system are provided. The SetTime() boottime service is implemented.
This commit is contained in:
@@ -160,27 +160,36 @@ extern const efi_guid_t efi_guid_hii_string_protocol;
|
|||||||
extern unsigned int __efi_runtime_start, __efi_runtime_stop;
|
extern unsigned int __efi_runtime_start, __efi_runtime_stop;
|
||||||
extern unsigned int __efi_runtime_rel_start, __efi_runtime_rel_stop;
|
extern unsigned int __efi_runtime_rel_start, __efi_runtime_rel_stop;
|
||||||
|
|
||||||
/*
|
/**
|
||||||
|
* struct efi_open_protocol_info_item - open protocol info item
|
||||||
|
*
|
||||||
* When a protocol is opened a open protocol info entry is created.
|
* When a protocol is opened a open protocol info entry is created.
|
||||||
* These are maintained in a list.
|
* These are maintained in a list.
|
||||||
|
*
|
||||||
|
* @link: link to the list of open protocol info entries of a protocol
|
||||||
|
* @info: information about the opening of a protocol
|
||||||
*/
|
*/
|
||||||
struct efi_open_protocol_info_item {
|
struct efi_open_protocol_info_item {
|
||||||
/* Link to the list of open protocol info entries of a protocol */
|
|
||||||
struct list_head link;
|
struct list_head link;
|
||||||
struct efi_open_protocol_info_entry info;
|
struct efi_open_protocol_info_entry info;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/**
|
||||||
|
* struct efi_handler - single protocol interface of a handle
|
||||||
|
*
|
||||||
* When the UEFI payload wants to open a protocol on an object to get its
|
* When the UEFI payload wants to open a protocol on an object to get its
|
||||||
* interface (usually a struct with callback functions), this struct maps the
|
* interface (usually a struct with callback functions), this struct maps the
|
||||||
* protocol GUID to the respective protocol interface
|
* protocol GUID to the respective protocol interface
|
||||||
|
*
|
||||||
|
* @link: link to the list of protocols of a handle
|
||||||
|
* @guid: GUID of the protocol
|
||||||
|
* @protocol_interface: protocol interface
|
||||||
|
* @open_infos link to the list of open protocol info items
|
||||||
*/
|
*/
|
||||||
struct efi_handler {
|
struct efi_handler {
|
||||||
/* Link to the list of protocols of a handle */
|
|
||||||
struct list_head link;
|
struct list_head link;
|
||||||
const efi_guid_t *guid;
|
const efi_guid_t *guid;
|
||||||
void *protocol_interface;
|
void *protocol_interface;
|
||||||
/* Link to the list of open protocol info items */
|
|
||||||
struct list_head open_infos;
|
struct list_head open_infos;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -2360,7 +2360,10 @@ efi_status_t EFIAPI efi_install_multiple_protocol_interfaces
|
|||||||
|
|
||||||
r = EFI_CALL(efi_locate_device_path(protocol, &dp,
|
r = EFI_CALL(efi_locate_device_path(protocol, &dp,
|
||||||
&old_handle));
|
&old_handle));
|
||||||
if (r == EFI_SUCCESS) {
|
if (r == EFI_SUCCESS &&
|
||||||
|
dp->type == DEVICE_PATH_TYPE_END) {
|
||||||
|
EFI_PRINT("Path %pD already installed\n",
|
||||||
|
protocol_interface);
|
||||||
r = EFI_ALREADY_STARTED;
|
r = EFI_ALREADY_STARTED;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@@ -169,7 +169,6 @@ static efi_status_t EFIAPI efi_get_time_boottime(
|
|||||||
{
|
{
|
||||||
#ifdef CONFIG_DM_RTC
|
#ifdef CONFIG_DM_RTC
|
||||||
efi_status_t ret = EFI_SUCCESS;
|
efi_status_t ret = EFI_SUCCESS;
|
||||||
int r;
|
|
||||||
struct rtc_time tm;
|
struct rtc_time tm;
|
||||||
struct udevice *dev;
|
struct udevice *dev;
|
||||||
|
|
||||||
@@ -179,11 +178,12 @@ static efi_status_t EFIAPI efi_get_time_boottime(
|
|||||||
ret = EFI_INVALID_PARAMETER;
|
ret = EFI_INVALID_PARAMETER;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
if (uclass_get_device(UCLASS_RTC, 0, &dev) ||
|
||||||
r = uclass_get_device(UCLASS_RTC, 0, &dev);
|
dm_rtc_get(dev, &tm)) {
|
||||||
if (!r)
|
ret = EFI_UNSUPPORTED;
|
||||||
r = dm_rtc_get(dev, &tm);
|
goto out;
|
||||||
if (r) {
|
}
|
||||||
|
if (dm_rtc_get(dev, &tm)) {
|
||||||
ret = EFI_DEVICE_ERROR;
|
ret = EFI_DEVICE_ERROR;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@@ -210,11 +210,61 @@ out:
|
|||||||
return EFI_EXIT(ret);
|
return EFI_EXIT(ret);
|
||||||
#else
|
#else
|
||||||
EFI_ENTRY("%p %p", time, capabilities);
|
EFI_ENTRY("%p %p", time, capabilities);
|
||||||
return EFI_EXIT(EFI_DEVICE_ERROR);
|
return EFI_EXIT(EFI_UNSUPPORTED);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* efi_set_time_boottime() - set current time
|
||||||
|
*
|
||||||
|
* This function implements the SetTime() runtime service before
|
||||||
|
* SetVirtualAddressMap() is called.
|
||||||
|
*
|
||||||
|
* See the Unified Extensible Firmware Interface (UEFI) specification
|
||||||
|
* for details.
|
||||||
|
*
|
||||||
|
* @time: pointer to structure to with current time
|
||||||
|
* Returns: status code
|
||||||
|
*/
|
||||||
|
static efi_status_t EFIAPI efi_set_time_boottime(struct efi_time *time)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_DM_RTC
|
||||||
|
efi_status_t ret = EFI_SUCCESS;
|
||||||
|
struct rtc_time tm;
|
||||||
|
struct udevice *dev;
|
||||||
|
|
||||||
|
EFI_ENTRY("%p", time);
|
||||||
|
|
||||||
|
if (!time) {
|
||||||
|
ret = EFI_INVALID_PARAMETER;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (uclass_get_device(UCLASS_RTC, 0, &dev)) {
|
||||||
|
ret = EFI_UNSUPPORTED;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&tm, 0, sizeof(tm));
|
||||||
|
tm.tm_year = time->year;
|
||||||
|
tm.tm_mon = time->month;
|
||||||
|
tm.tm_mday = time->day;
|
||||||
|
tm.tm_hour = time->hour;
|
||||||
|
tm.tm_min = time->minute;
|
||||||
|
tm.tm_sec = time->second;
|
||||||
|
tm.tm_isdst = time->daylight == EFI_TIME_IN_DAYLIGHT;
|
||||||
|
/* Calculate day of week */
|
||||||
|
rtc_calc_weekday(&tm);
|
||||||
|
|
||||||
|
if (dm_rtc_set(dev, &tm))
|
||||||
|
ret = EFI_DEVICE_ERROR;
|
||||||
|
out:
|
||||||
|
return EFI_EXIT(ret);
|
||||||
|
#else
|
||||||
|
EFI_ENTRY("%p", time);
|
||||||
|
return EFI_EXIT(EFI_UNSUPPORTED);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* efi_reset_system() - reset system
|
* efi_reset_system() - reset system
|
||||||
*
|
*
|
||||||
@@ -271,6 +321,24 @@ efi_status_t __weak __efi_runtime EFIAPI efi_get_time(
|
|||||||
return EFI_DEVICE_ERROR;
|
return EFI_DEVICE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* efi_set_time() - set current time
|
||||||
|
*
|
||||||
|
* This function implements the SetTime runtime service after
|
||||||
|
* SetVirtualAddressMap() is called. As the U-Boot driver are not available
|
||||||
|
* anymore only an error code is returned.
|
||||||
|
*
|
||||||
|
* See the Unified Extensible Firmware Interface (UEFI) specification
|
||||||
|
* for details.
|
||||||
|
*
|
||||||
|
* @time: pointer to structure to with current time
|
||||||
|
* Returns: status code
|
||||||
|
*/
|
||||||
|
efi_status_t __weak __efi_runtime EFIAPI efi_set_time(struct efi_time *time)
|
||||||
|
{
|
||||||
|
return EFI_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
struct efi_runtime_detach_list_struct {
|
struct efi_runtime_detach_list_struct {
|
||||||
void *ptr;
|
void *ptr;
|
||||||
void *patchto;
|
void *patchto;
|
||||||
@@ -289,6 +357,9 @@ static const struct efi_runtime_detach_list_struct efi_runtime_detach_list[] = {
|
|||||||
/* RTC accessors are gone */
|
/* RTC accessors are gone */
|
||||||
.ptr = &efi_runtime_services.get_time,
|
.ptr = &efi_runtime_services.get_time,
|
||||||
.patchto = &efi_get_time,
|
.patchto = &efi_get_time,
|
||||||
|
}, {
|
||||||
|
.ptr = &efi_runtime_services.set_time,
|
||||||
|
.patchto = &efi_set_time,
|
||||||
}, {
|
}, {
|
||||||
/* Clean up system table */
|
/* Clean up system table */
|
||||||
.ptr = &systab.con_in,
|
.ptr = &systab.con_in,
|
||||||
@@ -697,7 +768,7 @@ struct efi_runtime_services __efi_runtime_data efi_runtime_services = {
|
|||||||
.headersize = sizeof(struct efi_runtime_services),
|
.headersize = sizeof(struct efi_runtime_services),
|
||||||
},
|
},
|
||||||
.get_time = &efi_get_time_boottime,
|
.get_time = &efi_get_time_boottime,
|
||||||
.set_time = (void *)&efi_device_error,
|
.set_time = &efi_set_time_boottime,
|
||||||
.get_wakeup_time = (void *)&efi_unimplemented,
|
.get_wakeup_time = (void *)&efi_unimplemented,
|
||||||
.set_wakeup_time = (void *)&efi_unimplemented,
|
.set_wakeup_time = (void *)&efi_unimplemented,
|
||||||
.set_virtual_address_map = &efi_set_virtual_address_map,
|
.set_virtual_address_map = &efi_set_virtual_address_map,
|
||||||
|
@@ -12,7 +12,7 @@
|
|||||||
#include <efi_loader.h>
|
#include <efi_loader.h>
|
||||||
|
|
||||||
/* Characters that may not be used in file names */
|
/* Characters that may not be used in file names */
|
||||||
static const char illegal[] = "<>:\"/\\|?*";
|
static const char illegal[] = "<>:\"/\\|?*\x7f";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* EDK2 assumes codepage 1250 when creating FAT 8.3 file names.
|
* EDK2 assumes codepage 1250 when creating FAT 8.3 file names.
|
||||||
|
@@ -427,7 +427,9 @@ efi_status_t EFIAPI efi_set_variable(u16 *variable_name,
|
|||||||
EFI_ENTRY("\"%ls\" %pUl %x %zu %p", variable_name, vendor, attributes,
|
EFI_ENTRY("\"%ls\" %pUl %x %zu %p", variable_name, vendor, attributes,
|
||||||
data_size, data);
|
data_size, data);
|
||||||
|
|
||||||
if (!variable_name || !vendor) {
|
/* TODO: implement APPEND_WRITE */
|
||||||
|
if (!variable_name || !vendor ||
|
||||||
|
(attributes & EFI_VARIABLE_APPEND_WRITE)) {
|
||||||
ret = EFI_INVALID_PARAMETER;
|
ret = EFI_INVALID_PARAMETER;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@@ -449,12 +451,21 @@ efi_status_t EFIAPI efi_set_variable(u16 *variable_name,
|
|||||||
if (val) {
|
if (val) {
|
||||||
parse_attr(val, &attr);
|
parse_attr(val, &attr);
|
||||||
|
|
||||||
if (attr & READ_ONLY) {
|
|
||||||
/* We should not free val */
|
/* We should not free val */
|
||||||
val = NULL;
|
val = NULL;
|
||||||
|
if (attr & READ_ONLY) {
|
||||||
ret = EFI_WRITE_PROTECTED;
|
ret = EFI_WRITE_PROTECTED;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* attributes won't be changed
|
||||||
|
* TODO: take care of APPEND_WRITE once supported
|
||||||
|
*/
|
||||||
|
if (attr != attributes) {
|
||||||
|
ret = EFI_INVALID_PARAMETER;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val = malloc(2 * data_size + strlen("{ro,run,boot}(blob)") + 1);
|
val = malloc(2 * data_size + strlen("{ro,run,boot}(blob)") + 1);
|
||||||
|
@@ -10,6 +10,7 @@
|
|||||||
#include <efi_selftest.h>
|
#include <efi_selftest.h>
|
||||||
|
|
||||||
#define EFI_ST_NO_RTC "Could not read real time clock\n"
|
#define EFI_ST_NO_RTC "Could not read real time clock\n"
|
||||||
|
#define EFI_ST_NO_RTC_SET "Could not set real time clock\n"
|
||||||
|
|
||||||
static struct efi_runtime_services *runtime;
|
static struct efi_runtime_services *runtime;
|
||||||
|
|
||||||
@@ -30,17 +31,26 @@ static int setup(const efi_handle_t handle,
|
|||||||
/*
|
/*
|
||||||
* Execute unit test.
|
* Execute unit test.
|
||||||
*
|
*
|
||||||
* Display current time.
|
* Read and display current time.
|
||||||
|
* Set a new value and read it back.
|
||||||
|
* Set the real time clock back the current time.
|
||||||
*
|
*
|
||||||
* @return: EFI_ST_SUCCESS for success
|
* @return: EFI_ST_SUCCESS for success
|
||||||
*/
|
*/
|
||||||
static int execute(void)
|
static int execute(void)
|
||||||
{
|
{
|
||||||
efi_status_t ret;
|
efi_status_t ret;
|
||||||
struct efi_time tm;
|
struct efi_time tm, tm_old, tm_new = {
|
||||||
|
.year = 2017,
|
||||||
|
.month = 5,
|
||||||
|
.day = 19,
|
||||||
|
.hour = 13,
|
||||||
|
.minute = 47,
|
||||||
|
.second = 53,
|
||||||
|
};
|
||||||
|
|
||||||
/* Display current time */
|
/* Display current time */
|
||||||
ret = runtime->get_time(&tm, NULL);
|
ret = runtime->get_time(&tm_old, NULL);
|
||||||
if (ret != EFI_SUCCESS) {
|
if (ret != EFI_SUCCESS) {
|
||||||
#ifdef CONFIG_CMD_DATE
|
#ifdef CONFIG_CMD_DATE
|
||||||
efi_st_error(EFI_ST_NO_RTC);
|
efi_st_error(EFI_ST_NO_RTC);
|
||||||
@@ -49,11 +59,41 @@ static int execute(void)
|
|||||||
efi_st_todo(EFI_ST_NO_RTC);
|
efi_st_todo(EFI_ST_NO_RTC);
|
||||||
return EFI_ST_SUCCESS;
|
return EFI_ST_SUCCESS;
|
||||||
#endif
|
#endif
|
||||||
} else {
|
}
|
||||||
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.year, tm.month, tm.day,
|
tm_old.year, tm_old.month, tm_old.day,
|
||||||
tm.hour, tm.minute, tm.second);
|
tm_old.hour, tm_old.minute, tm_old.second);
|
||||||
|
ret = runtime->set_time(&tm_new);
|
||||||
|
if (ret != EFI_SUCCESS) {
|
||||||
|
#ifdef CONFIG_CMD_DATE
|
||||||
|
efi_st_error(EFI_ST_NO_RTC_SET);
|
||||||
|
return EFI_ST_FAILURE;
|
||||||
|
#else
|
||||||
|
efi_st_todo(EFI_ST_NO_RTC_SET);
|
||||||
|
return EFI_ST_SUCCESS;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
ret = runtime->get_time(&tm, NULL);
|
||||||
|
if (ret != EFI_SUCCESS) {
|
||||||
|
efi_st_error(EFI_ST_NO_RTC);
|
||||||
|
return EFI_ST_FAILURE;
|
||||||
|
}
|
||||||
|
if (tm.year != tm_new.year ||
|
||||||
|
tm.month != tm_new.month ||
|
||||||
|
tm.day != tm_new.day ||
|
||||||
|
tm.hour != tm_new.hour ||
|
||||||
|
tm.minute != tm_new.minute ||
|
||||||
|
tm.second < tm_new.second ||
|
||||||
|
tm.second > tm_new.second + 2) {
|
||||||
|
efi_st_error(EFI_ST_NO_RTC_SET);
|
||||||
|
return EFI_ST_FAILURE;
|
||||||
|
}
|
||||||
|
/* Set time back to old value */
|
||||||
|
ret = runtime->set_time(&tm_old);
|
||||||
|
if (ret != EFI_SUCCESS) {
|
||||||
|
efi_st_error(EFI_ST_NO_RTC_SET);
|
||||||
|
return EFI_ST_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return EFI_ST_SUCCESS;
|
return EFI_ST_SUCCESS;
|
||||||
|
@@ -116,9 +116,8 @@ static int execute(void)
|
|||||||
EFI_VARIABLE_APPEND_WRITE,
|
EFI_VARIABLE_APPEND_WRITE,
|
||||||
7, v + 8);
|
7, v + 8);
|
||||||
if (ret != EFI_SUCCESS) {
|
if (ret != EFI_SUCCESS) {
|
||||||
efi_st_error("SetVariable failed\n");
|
efi_st_todo("SetVariable(APPEND_WRITE) failed\n");
|
||||||
return EFI_ST_FAILURE;
|
} else {
|
||||||
}
|
|
||||||
len = EFI_ST_MAX_DATA_SIZE;
|
len = EFI_ST_MAX_DATA_SIZE;
|
||||||
ret = runtime->get_variable(L"efi_st_var1", &guid_vendor1,
|
ret = runtime->get_variable(L"efi_st_var1", &guid_vendor1,
|
||||||
&attr, &len, data);
|
&attr, &len, data);
|
||||||
@@ -131,6 +130,7 @@ static int execute(void)
|
|||||||
(unsigned int)len);
|
(unsigned int)len);
|
||||||
if (memcmp(data, v, len))
|
if (memcmp(data, v, len))
|
||||||
efi_st_todo("GetVariable returned wrong value\n");
|
efi_st_todo("GetVariable returned wrong value\n");
|
||||||
|
}
|
||||||
/* Enumerate variables */
|
/* Enumerate variables */
|
||||||
boottime->set_mem(&guid, 16, 0);
|
boottime->set_mem(&guid, 16, 0);
|
||||||
*varname = 0;
|
*varname = 0;
|
||||||
|
Reference in New Issue
Block a user