diff options
author | Tom Rini | 2020-10-28 08:35:28 -0400 |
---|---|---|
committer | Tom Rini | 2020-10-28 08:35:28 -0400 |
commit | 39dd7c1d6bc94e6381ef7418edd8206cae24377f (patch) | |
tree | e594bcca477d1c87c2ba97f46b70314bf87cdea1 | |
parent | a45da8f51eeb22f3c44928b0beabee819469e309 (diff) | |
parent | 0eae552d18690a19cc714046fb1665138f5701f6 (diff) |
Merge tag 'efi-2021-01-rc2' of https://gitlab.denx.de/u-boot/custodians/u-boot-efi
Pull request for UEFI sub-system for efi-2021-01-rc2
A software RTC driver is supplied for UEFI SCT testing.
The following UEFI related bugs are fixed:
* correct handling of daylight saving time in GetTime() and SetTime()
* handling of the gd register in function tracing on RISC-V
* disable U-Boot devices in ExitBootServices()
-rw-r--r-- | MAINTAINERS | 1 | ||||
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | drivers/rtc/Kconfig | 11 | ||||
-rw-r--r-- | drivers/rtc/Makefile | 1 | ||||
-rw-r--r-- | drivers/rtc/emul_rtc.c | 80 | ||||
-rw-r--r-- | lib/efi_loader/efi_boottime.c | 13 | ||||
-rw-r--r-- | lib/efi_loader/efi_runtime.c | 19 | ||||
-rw-r--r-- | lib/trace.c | 2 |
8 files changed, 121 insertions, 8 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index 69a5bc37689..d9f80325f57 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -678,6 +678,7 @@ S: Maintained T: git https://gitlab.denx.de/u-boot/custodians/u-boot-efi.git F: doc/api/efi.rst F: doc/uefi/* +F: drivers/rtc/emul_rtc.c F: include/capitalization.h F: include/charset.h F: include/cp1250.h @@ -1870,6 +1870,7 @@ define filechk_timestamp.h LC_ALL=C $${DATE} -u -d "$${SOURCE_DATE}" +'#define U_BOOT_TZ "%z"'; \ LC_ALL=C $${DATE} -u -d "$${SOURCE_DATE}" +'#define U_BOOT_DMI_DATE "%m/%d/%Y"'; \ LC_ALL=C $${DATE} -u -d "$${SOURCE_DATE}" +'#define U_BOOT_BUILD_DATE 0x%Y%m%d'; \ + LC_ALL=C $${DATE} -u -d "$${SOURCE_DATE}" +'#define U_BOOT_EPOCH %s'; \ else \ return 42; \ fi; \ @@ -1879,6 +1880,7 @@ define filechk_timestamp.h LC_ALL=C date +'#define U_BOOT_TZ "%z"'; \ LC_ALL=C date +'#define U_BOOT_DMI_DATE "%m/%d/%Y"'; \ LC_ALL=C date +'#define U_BOOT_BUILD_DATE 0x%Y%m%d'; \ + LC_ALL=C date +'#define U_BOOT_EPOCH %s'; \ fi) endef diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 63662001c26..d06d272e14b 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -63,6 +63,17 @@ config RTC_DS3232 Support for Dallas Semiconductor (now Maxim) DS3232 compatible Real Time Clock devices. +config RTC_EMULATION + bool "Enable emulated RTC" + depends on DM_RTC + help + On a board without hardware clock this software real time clock can be + used. The build time is used to initialize the RTC. So you will have + to adjust the time either manually using the 'date' command or use + the 'sntp' to update the RTC with the time from a network time server. + See CONFIG_CMD_SNTP and CONFIG_BOOTP_NTPSERVER. The RTC time is + advanced according to CPU ticks. + config RTC_ISL1208 bool "Enable ISL1208 driver" depends on DM_RTC diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 12eb449583a..ef66dc4bf02 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile @@ -22,6 +22,7 @@ obj-$(CONFIG_RTC_DS164x) += ds164x.o obj-$(CONFIG_RTC_DS174x) += ds174x.o obj-$(CONFIG_RTC_DS3231) += ds3231.o obj-$(CONFIG_RTC_DS3232) += ds3232.o +obj-$(CONFIG_RTC_EMULATION) += emul_rtc.o obj-$(CONFIG_RTC_FTRTC010) += ftrtc010.o obj-$(CONFIG_SANDBOX) += i2c_rtc_emul.o obj-$(CONFIG_RTC_IMXDI) += imxdi.o diff --git a/drivers/rtc/emul_rtc.c b/drivers/rtc/emul_rtc.c new file mode 100644 index 00000000000..c98c24bbb3d --- /dev/null +++ b/drivers/rtc/emul_rtc.c @@ -0,0 +1,80 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2020, Heinrich Schuchardt <xypron.glpk@gmx.de> + * + * This driver emulates a real time clock based on timer ticks. + */ + +#include <common.h> +#include <div64.h> +#include <dm.h> +#include <generated/timestamp_autogenerated.h> +#include <rtc.h> + +/** + * struct emul_rtc - private data for emulated RTC driver + */ +struct emul_rtc { + /** + * @offset_us: microseconds from 1970-01-01 to timer_get_us() base + */ + u64 offset_us; + /** + * @isdst: daylight saving time + */ + int isdst; +}; + +static int emul_rtc_get(struct udevice *dev, struct rtc_time *time) +{ + struct emul_rtc *priv = dev_get_priv(dev); + u64 now; + + if (!priv->offset_us) { + /* Use the build date as initial time */ + priv->offset_us = U_BOOT_EPOCH * 1000000ULL - timer_get_us(); + priv->isdst = -1; + } + + now = timer_get_us() + priv->offset_us; + do_div(now, 1000000); + rtc_to_tm(now, time); + time->tm_isdst = priv->isdst; + + return 0; +} + +static int emul_rtc_set(struct udevice *dev, const struct rtc_time *time) +{ + struct emul_rtc *priv = dev_get_priv(dev); + + if (time->tm_year < 1970) + return -EINVAL; + + priv->offset_us = rtc_mktime(time) * 1000000ULL - timer_get_us(); + + if (time->tm_isdst > 0) + priv->isdst = 1; + else if (time->tm_isdst < 0) + priv->isdst = -1; + else + priv->isdst = 0; + + return 0; +} + +static const struct rtc_ops emul_rtc_ops = { + .get = emul_rtc_get, + .set = emul_rtc_set, +}; + +U_BOOT_DRIVER(rtc_emul) = { + .name = "rtc_emul", + .id = UCLASS_RTC, + .ops = &emul_rtc_ops, + .priv_auto_alloc_size = sizeof(struct emul_rtc), +}; + +U_BOOT_DEVICE(rtc_emul) = { + .name = "rtc_emul", +}; diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c index bf78176217c..b26ac9fbfc7 100644 --- a/lib/efi_loader/efi_boottime.c +++ b/lib/efi_loader/efi_boottime.c @@ -6,18 +6,20 @@ */ #include <common.h> +#include <bootm.h> #include <div64.h> +#include <dm/device.h> +#include <dm/root.h> #include <efi_loader.h> #include <irq_func.h> #include <log.h> #include <malloc.h> -#include <time.h> -#include <linux/libfdt_env.h> -#include <u-boot/crc.h> -#include <bootm.h> #include <pe.h> +#include <time.h> #include <u-boot/crc.h> +#include <usb.h> #include <watchdog.h> +#include <linux/libfdt_env.h> DECLARE_GLOBAL_DATA_PTR; @@ -1994,7 +1996,10 @@ static efi_status_t EFIAPI efi_exit_boot_services(efi_handle_t image_handle, list_del(&evt->link); } + if IS_ENABLED(CONFIG_USB_DEVICE) + udc_disconnect(); board_quiesce_devices(); + dm_remove_devices_flags(DM_REMOVE_ACTIVE_ALL); /* Patch out unsupported runtime function */ efi_runtime_detach(); diff --git a/lib/efi_loader/efi_runtime.c b/lib/efi_loader/efi_runtime.c index dea2b4e5eea..1fa1595e402 100644 --- a/lib/efi_loader/efi_runtime.c +++ b/lib/efi_loader/efi_runtime.c @@ -266,9 +266,13 @@ static efi_status_t EFIAPI efi_get_time_boottime( time->hour = tm.tm_hour; time->minute = tm.tm_min; time->second = tm.tm_sec; - if (tm.tm_isdst) + if (tm.tm_isdst > 0) time->daylight = EFI_TIME_ADJUST_DAYLIGHT | EFI_TIME_IN_DAYLIGHT; + else if (!tm.tm_isdst) + time->daylight = EFI_TIME_ADJUST_DAYLIGHT; + else + time->daylight = 0; time->timezone = EFI_UNSPECIFIED_TIMEZONE; if (capabilities) { @@ -347,8 +351,17 @@ static efi_status_t EFIAPI efi_set_time_boottime(struct efi_time *time) tm.tm_hour = time->hour; tm.tm_min = time->minute; tm.tm_sec = time->second; - tm.tm_isdst = time->daylight == - (EFI_TIME_ADJUST_DAYLIGHT | EFI_TIME_IN_DAYLIGHT); + switch (time->daylight) { + case EFI_TIME_ADJUST_DAYLIGHT: + tm.tm_isdst = 0; + break; + case EFI_TIME_ADJUST_DAYLIGHT | EFI_TIME_IN_DAYLIGHT: + tm.tm_isdst = 1; + break; + default: + tm.tm_isdst = -1; + break; + } /* Calculate day of week */ rtc_calc_weekday(&tm); diff --git a/lib/trace.c b/lib/trace.c index 831283c283d..defc9716d80 100644 --- a/lib/trace.c +++ b/lib/trace.c @@ -57,7 +57,7 @@ static inline uintptr_t __attribute__((no_instrument_function)) return offset / FUNC_SITE_SIZE; } -#if defined(CONFIG_EFI_LOADER) && defined(CONFIG_ARM) +#if defined(CONFIG_EFI_LOADER) && (defined(CONFIG_ARM) || defined(CONFIG_RISCV)) /** * trace_gd - the value of the gd register |