diff options
Diffstat (limited to 'lib/efi_loader')
-rw-r--r-- | lib/efi_loader/efi_boottime.c | 5 | ||||
-rw-r--r-- | lib/efi_loader/efi_runtime.c | 87 | ||||
-rw-r--r-- | lib/efi_loader/efi_unicode_collation.c | 2 | ||||
-rw-r--r-- | lib/efi_loader/efi_variable.c | 17 |
4 files changed, 98 insertions, 13 deletions
diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c index 971bd5ffa3..54fff85e64 100644 --- a/lib/efi_loader/efi_boottime.c +++ b/lib/efi_loader/efi_boottime.c @@ -2360,7 +2360,10 @@ efi_status_t EFIAPI efi_install_multiple_protocol_interfaces r = EFI_CALL(efi_locate_device_path(protocol, &dp, &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; break; } diff --git a/lib/efi_loader/efi_runtime.c b/lib/efi_loader/efi_runtime.c index 636dfdab39..058b40a887 100644 --- a/lib/efi_loader/efi_runtime.c +++ b/lib/efi_loader/efi_runtime.c @@ -169,7 +169,6 @@ static efi_status_t EFIAPI efi_get_time_boottime( { #ifdef CONFIG_DM_RTC efi_status_t ret = EFI_SUCCESS; - int r; struct rtc_time tm; struct udevice *dev; @@ -179,11 +178,12 @@ static efi_status_t EFIAPI efi_get_time_boottime( ret = EFI_INVALID_PARAMETER; goto out; } - - r = uclass_get_device(UCLASS_RTC, 0, &dev); - if (!r) - r = dm_rtc_get(dev, &tm); - if (r) { + if (uclass_get_device(UCLASS_RTC, 0, &dev) || + dm_rtc_get(dev, &tm)) { + ret = EFI_UNSUPPORTED; + goto out; + } + if (dm_rtc_get(dev, &tm)) { ret = EFI_DEVICE_ERROR; goto out; } @@ -210,11 +210,61 @@ out: return EFI_EXIT(ret); #else EFI_ENTRY("%p %p", time, capabilities); - return EFI_EXIT(EFI_DEVICE_ERROR); + return EFI_EXIT(EFI_UNSUPPORTED); #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 * @@ -271,6 +321,24 @@ efi_status_t __weak __efi_runtime EFIAPI efi_get_time( 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 { void *ptr; void *patchto; @@ -290,6 +358,9 @@ static const struct efi_runtime_detach_list_struct efi_runtime_detach_list[] = { .ptr = &efi_runtime_services.get_time, .patchto = &efi_get_time, }, { + .ptr = &efi_runtime_services.set_time, + .patchto = &efi_set_time, + }, { /* Clean up system table */ .ptr = &systab.con_in, .patchto = NULL, @@ -697,7 +768,7 @@ struct efi_runtime_services __efi_runtime_data efi_runtime_services = { .headersize = sizeof(struct efi_runtime_services), }, .get_time = &efi_get_time_boottime, - .set_time = (void *)&efi_device_error, + .set_time = &efi_set_time_boottime, .get_wakeup_time = (void *)&efi_unimplemented, .set_wakeup_time = (void *)&efi_unimplemented, .set_virtual_address_map = &efi_set_virtual_address_map, diff --git a/lib/efi_loader/efi_unicode_collation.c b/lib/efi_loader/efi_unicode_collation.c index 06fddca1c4..f293b42397 100644 --- a/lib/efi_loader/efi_unicode_collation.c +++ b/lib/efi_loader/efi_unicode_collation.c @@ -12,7 +12,7 @@ #include <efi_loader.h> /* 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. diff --git a/lib/efi_loader/efi_variable.c b/lib/efi_loader/efi_variable.c index 28b1aa7505..50bc10537f 100644 --- a/lib/efi_loader/efi_variable.c +++ b/lib/efi_loader/efi_variable.c @@ -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, data_size, data); - if (!variable_name || !vendor) { + /* TODO: implement APPEND_WRITE */ + if (!variable_name || !vendor || + (attributes & EFI_VARIABLE_APPEND_WRITE)) { ret = EFI_INVALID_PARAMETER; goto out; } @@ -449,12 +451,21 @@ efi_status_t EFIAPI efi_set_variable(u16 *variable_name, if (val) { parse_attr(val, &attr); + /* We should not free val */ + val = NULL; if (attr & READ_ONLY) { - /* We should not free val */ - val = NULL; ret = EFI_WRITE_PROTECTED; 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); |