diff options
author | Tom Rini | 2021-07-13 09:42:19 -0400 |
---|---|---|
committer | Tom Rini | 2021-07-13 09:42:19 -0400 |
commit | a7bdd2dd8e7685166767c5fecfdce7e5dc8a40be (patch) | |
tree | b4b167b47aa3e4934734d75f62c9a7e5b94a91d5 | |
parent | 490101a5e5df65238b900b21b81361bc4b13da2e (diff) | |
parent | b0b1449b3be9b93ecc57d91b0cb18ed81fc8a1ee (diff) |
Merge tag 'efi-2021-10-rc1' of https://source.denx.de/u-boot/custodians/u-boot-efi
Pull request for efi-2021-10-rc1
Documentation
* fix typo in signature.txt
UEFI
* provide file attributes in EFI_FILE_PROTOCOL.Read()
* various capsule update fixes
-rw-r--r-- | doc/uImage.FIT/signature.txt | 4 | ||||
-rw-r--r-- | fs/fat/fat.c | 32 | ||||
-rw-r--r-- | include/fs.h | 22 | ||||
-rw-r--r-- | lib/date.c | 6 | ||||
-rw-r--r-- | lib/efi_loader/efi_capsule.c | 66 | ||||
-rw-r--r-- | lib/efi_loader/efi_file.c | 15 |
6 files changed, 101 insertions, 44 deletions
diff --git a/doc/uImage.FIT/signature.txt b/doc/uImage.FIT/signature.txt index d9a91211903..7cb1c15e5e1 100644 --- a/doc/uImage.FIT/signature.txt +++ b/doc/uImage.FIT/signature.txt @@ -266,14 +266,14 @@ As an example, consider this FIT: data = <data for fdt1>; signature-1 { algo = "sha1,rsa2048"; - vaue = <...fdt signature 1...> + value = <...fdt signature 1...> }; }; fdt-2 { data = <data for fdt2>; signature-1 { algo = "sha1,rsa2048"; - vaue = <...fdt signature 2...> + value = <...fdt signature 2...> }; }; }; diff --git a/fs/fat/fat.c b/fs/fat/fat.c index c561d82b351..7021138b987 100644 --- a/fs/fat/fat.c +++ b/fs/fat/fat.c @@ -1187,6 +1187,28 @@ out: return ret == 0; } +/** + * fat2rtc() - convert FAT time stamp to RTC file stamp + * + * @date: FAT date + * @time: FAT time + * @tm: RTC time stamp + */ +static void __maybe_unused fat2rtc(u16 date, u16 time, struct rtc_time *tm) +{ + tm->tm_mday = date & 0x1f; + tm->tm_mon = (date & 0x1e0) >> 4; + tm->tm_year = (date >> 9) + 1980; + + tm->tm_sec = (time & 0x1f) << 1; + tm->tm_min = (time & 0x7e0) >> 5; + tm->tm_hour = time >> 11; + + rtc_calc_weekday(tm); + tm->tm_yday = 0; + tm->tm_isdst = 0; +} + int fat_size(const char *filename, loff_t *size) { fsdata fsdata; @@ -1325,7 +1347,15 @@ int fat_readdir(struct fs_dir_stream *dirs, struct fs_dirent **dentp) memset(dent, 0, sizeof(*dent)); strcpy(dent->name, dir->itr.name); - + if (CONFIG_IS_ENABLED(EFI_LOADER)) { + dent->attr = dir->itr.dent->attr; + fat2rtc(le16_to_cpu(dir->itr.dent->cdate), + le16_to_cpu(dir->itr.dent->ctime), &dent->create_time); + fat2rtc(le16_to_cpu(dir->itr.dent->date), + le16_to_cpu(dir->itr.dent->time), &dent->change_time); + fat2rtc(le16_to_cpu(dir->itr.dent->adate), + 0, &dent->access_time); + } if (fat_itr_isdir(&dir->itr)) { dent->type = FS_DT_DIR; } else { diff --git a/include/fs.h b/include/fs.h index 0794b50d102..1c79e299fdd 100644 --- a/include/fs.h +++ b/include/fs.h @@ -6,6 +6,7 @@ #define _FS_H #include <common.h> +#include <rtc.h> struct cmd_tbl; @@ -160,13 +161,26 @@ int fs_write(const char *filename, ulong addr, loff_t offset, loff_t len, #define FS_DT_REG 8 /* regular file */ #define FS_DT_LNK 10 /* symbolic link */ -/* - * A directory entry, returned by fs_readdir(). Returns information +/** + * struct fs_dirent - directory entry + * + * A directory entry, returned by fs_readdir(). Returns information * about the file/directory at the current directory entry position. */ struct fs_dirent { - unsigned type; /* one of FS_DT_x (not a mask) */ - loff_t size; /* size in bytes */ + /** @type: one of FS_DT_x (not a mask) */ + unsigned int type; + /** @size: file size */ + loff_t size; + /** @flags: attribute flags (FS_ATTR_*) */ + u32 attr; + /** create_time: time of creation */ + struct rtc_time create_time; + /** access_time: time of last access */ + struct rtc_time access_time; + /** change_time: time of last modification */ + struct rtc_time change_time; + /** name: file name */ char name[256]; }; diff --git a/lib/date.c b/lib/date.c index 0456de78ab1..c589d9ed3a2 100644 --- a/lib/date.c +++ b/lib/date.c @@ -10,8 +10,6 @@ #include <rtc.h> #include <linux/time.h> -#if defined(CONFIG_LIB_DATE) || defined(CONFIG_TIMESTAMP) - #define FEBRUARY 2 #define STARTOFTIME 1970 #define SECDAY 86400L @@ -97,9 +95,6 @@ unsigned long rtc_mktime(const struct rtc_time *tm) return (hours * 60 + tm->tm_min) * 60 + tm->tm_sec; } -#endif /* CONFIG_LIB_DATE || CONFIG_TIMESTAMP */ - -#ifdef CONFIG_LIB_DATE /* for compatibility with linux code */ time64_t mktime64(const unsigned int year, const unsigned int mon, const unsigned int day, const unsigned int hour, @@ -116,4 +111,3 @@ time64_t mktime64(const unsigned int year, const unsigned int mon, return (time64_t)rtc_mktime((const struct rtc_time *)&time); } -#endif diff --git a/lib/efi_loader/efi_capsule.c b/lib/efi_loader/efi_capsule.c index 50bed32bfb3..b878e71438b 100644 --- a/lib/efi_loader/efi_capsule.c +++ b/lib/efi_loader/efi_capsule.c @@ -6,6 +6,8 @@ * Author: AKASHI Takahiro */ +#define LOG_CATEGORY LOGC_EFI + #include <common.h> #include <efi_loader.h> #include <efi_variable.h> @@ -95,13 +97,25 @@ void set_capsule_result(int index, struct efi_capsule_header *capsule, else memset(&result.capsule_processed, 0, sizeof(time)); result.capsule_status = return_status; - ret = efi_set_variable(variable_name16, &efi_guid_capsule_report, - EFI_VARIABLE_NON_VOLATILE | - EFI_VARIABLE_BOOTSERVICE_ACCESS | - EFI_VARIABLE_RUNTIME_ACCESS, - sizeof(result), &result); - if (ret) - log_err("EFI: creating %ls failed\n", variable_name16); + ret = efi_set_variable_int(variable_name16, &efi_guid_capsule_report, + EFI_VARIABLE_NON_VOLATILE | + EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS, + sizeof(result), &result, false); + if (ret != EFI_SUCCESS) { + log_err("Setting %ls failed\n", variable_name16); + return; + } + + /* Variable CapsuleLast must not include terminating 0x0000 */ + ret = efi_set_variable_int(L"CapsuleLast", &efi_guid_capsule_report, + EFI_VARIABLE_READ_ONLY | + EFI_VARIABLE_NON_VOLATILE | + EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS, + 22, variable_name16, false); + if (ret != EFI_SUCCESS) + log_err("Setting %ls failed\n", L"CapsuleLast"); } #ifdef CONFIG_EFI_CAPSULE_FIRMWARE_MANAGEMENT @@ -361,7 +375,7 @@ static efi_status_t efi_capsule_update_firmware( /* sanity check */ if ((capsule->item_offset_list[item] + sizeof(*image) >= capsule_size)) { - log_err("EFI: A capsule has not enough data\n"); + log_err("Capsule does not have enough data\n"); ret = EFI_INVALID_PARAMETER; goto out; } @@ -379,7 +393,7 @@ static efi_status_t efi_capsule_update_firmware( image->update_hardware_instance, handles, no_handles); if (!fmp) { - log_err("EFI Capsule: driver not found for firmware type: %pUl, hardware instance: %lld\n", + log_err("FMP driver not found for firmware type %pUl, hardware instance %lld\n", &image->update_image_type_id, image->update_hardware_instance); ret = EFI_UNSUPPORTED; @@ -397,7 +411,7 @@ static efi_status_t efi_capsule_update_firmware( vendor_code, NULL, &abort_reason)); if (ret != EFI_SUCCESS) { - log_err("EFI Capsule: firmware update failed: %ls\n", + log_err("Firmware update failed: %ls\n", abort_reason); efi_free_pool(abort_reason); goto out; @@ -453,7 +467,7 @@ efi_status_t EFIAPI efi_update_capsule( /* sanity check */ if (capsule->header_size < sizeof(*capsule) || capsule->capsule_image_size < sizeof(*capsule)) { - log_err("EFI: A capsule has not enough data\n"); + log_err("Capsule does not have enough data\n"); continue; } @@ -463,7 +477,7 @@ efi_status_t EFIAPI efi_update_capsule( &efi_guid_firmware_management_capsule_id)) { ret = efi_capsule_update_firmware(capsule); } else { - log_err("EFI: not support capsule type: %pUl\n", + log_err("Unsupported capsule type: %pUl\n", &capsule->capsule_guid); ret = EFI_UNSUPPORTED; } @@ -476,7 +490,7 @@ efi_status_t EFIAPI efi_update_capsule( /* Rebuild the ESRT to reflect any updated FW images. */ ret = efi_esrt_populate(); if (ret != EFI_SUCCESS) - log_warning("EFI Capsule: failed to update ESRT\n"); + log_warning("ESRT update failed\n"); } out: @@ -632,7 +646,7 @@ static efi_status_t find_boot_device(void) ret = get_dp_device(boot_var16, &boot_dev); if (ret == EFI_SUCCESS) { if (device_is_present_and_system_part(boot_dev)) { - goto out; + goto found; } else { efi_free_pool(boot_dev); boot_dev = NULL; @@ -675,11 +689,12 @@ skip: efi_free_pool(boot_dev); boot_dev = NULL; } +found: if (boot_dev) { u16 *path_str; path_str = efi_dp_str(boot_dev); - log_debug("EFI Capsule: bootdev is %ls\n", path_str); + log_debug("Boot device %ls\n", path_str); efi_free_pool(path_str); volume = efi_fs_from_path(boot_dev); @@ -720,7 +735,7 @@ static efi_status_t efi_capsule_scan_dir(u16 ***files, unsigned int *num) ret = find_boot_device(); if (ret == EFI_NOT_FOUND) { - log_debug("EFI Capsule: bootdev is not set\n"); + log_debug("Boot device is not set\n"); *num = 0; return EFI_SUCCESS; } else if (ret != EFI_SUCCESS) { @@ -988,7 +1003,6 @@ efi_status_t efi_launch_capsules(void) struct efi_capsule_header *capsule = NULL; u16 **files; unsigned int nfiles, index, i; - u16 variable_name16[12]; efi_status_t ret; if (!check_run_capsules()) @@ -1011,19 +1025,19 @@ efi_status_t efi_launch_capsules(void) /* Launch capsules */ for (i = 0, ++index; i < nfiles; i++, index++) { - log_debug("capsule from %ls ...\n", files[i]); + log_debug("Applying %ls\n", files[i]); if (index > 0xffff) index = 0; ret = efi_capsule_read_file(files[i], &capsule); if (ret == EFI_SUCCESS) { ret = EFI_CALL(efi_update_capsule(&capsule, 1, 0)); if (ret != EFI_SUCCESS) - log_err("EFI Capsule update failed at %ls\n", + log_err("Applying capsule %ls failed\n", files[i]); free(capsule); } else { - log_err("EFI: reading capsule failed: %ls\n", files[i]); + log_err("Reading capsule %ls failed\n", files[i]); } /* create CapsuleXXXX */ set_capsule_result(index, capsule, ret); @@ -1031,7 +1045,7 @@ efi_status_t efi_launch_capsules(void) /* delete a capsule either in case of success or failure */ ret = efi_capsule_delete_file(files[i]); if (ret != EFI_SUCCESS) - log_err("EFI: deleting a capsule file failed: %ls\n", + log_err("Deleting capsule %ls failed\n", files[i]); } efi_capsule_scan_done(); @@ -1040,16 +1054,6 @@ efi_status_t efi_launch_capsules(void) free(files[i]); free(files); - /* CapsuleLast */ - efi_create_indexed_name(variable_name16, sizeof(variable_name16), - "Capsule", index - 1); - efi_set_variable_int(L"CapsuleLast", &efi_guid_capsule_report, - EFI_VARIABLE_READ_ONLY | - EFI_VARIABLE_NON_VOLATILE | - EFI_VARIABLE_BOOTSERVICE_ACCESS | - EFI_VARIABLE_RUNTIME_ACCESS, - 22, variable_name16, false); - return ret; } #endif /* CONFIG_EFI_CAPSULE_ON_DISK */ diff --git a/lib/efi_loader/efi_file.c b/lib/efi_loader/efi_file.c index 6b3f5962be2..6299fcbbf4e 100644 --- a/lib/efi_loader/efi_file.c +++ b/lib/efi_loader/efi_file.c @@ -480,6 +480,17 @@ static efi_status_t file_read(struct file_handle *fh, u64 *buffer_size, return EFI_SUCCESS; } +static void rtc2efi(struct efi_time *time, struct rtc_time *tm) +{ + memset(time, 0, sizeof(struct efi_time)); + time->year = tm->tm_year; + time->month = tm->tm_mon; + time->day = tm->tm_mday; + time->hour = tm->tm_hour; + time->minute = tm->tm_min; + time->second = tm->tm_sec; +} + static efi_status_t dir_read(struct file_handle *fh, u64 *buffer_size, void *buffer) { @@ -535,6 +546,10 @@ static efi_status_t dir_read(struct file_handle *fh, u64 *buffer_size, info->size = required_size; info->file_size = dent->size; info->physical_size = dent->size; + info->attribute = dent->attr; + rtc2efi(&info->create_time, &dent->create_time); + rtc2efi(&info->modification_time, &dent->change_time); + rtc2efi(&info->last_access_time, &dent->access_time); if (dent->type == FS_DT_DIR) info->attribute |= EFI_FILE_DIRECTORY; |