All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH v2 1/1] efi_loader: implement SetTime
@ 2019-05-21 15:40 Heinrich Schuchardt
  0 siblings, 0 replies; only message in thread
From: Heinrich Schuchardt @ 2019-05-21 15:40 UTC (permalink / raw)
  To: u-boot

Implement the SetTime() runtime service.

Extend the real time clock selftest to check setting the clock.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
---
v2
	fix reference to unknown parameter for CONFIG_DM_RTC=n
---
 lib/efi_loader/efi_runtime.c        | 73 ++++++++++++++++++++++++++++-
 lib/efi_selftest/efi_selftest_rtc.c | 56 ++++++++++++++++++----
 2 files changed, 120 insertions(+), 9 deletions(-)

diff --git a/lib/efi_loader/efi_runtime.c b/lib/efi_loader/efi_runtime.c
index 636dfdab39..5f40659ee7 100644
--- a/lib/efi_loader/efi_runtime.c
+++ b/lib/efi_loader/efi_runtime.c
@@ -214,7 +214,57 @@ out:
 #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;
@@ -289,6 +357,9 @@ static const struct efi_runtime_detach_list_struct efi_runtime_detach_list[] = {
 		/* RTC accessors are gone */
 		.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,
@@ -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_selftest/efi_selftest_rtc.c b/lib/efi_selftest/efi_selftest_rtc.c
index 8d440dc0b3..9eb29add3b 100644
--- a/lib/efi_selftest/efi_selftest_rtc.c
+++ b/lib/efi_selftest/efi_selftest_rtc.c
@@ -10,6 +10,7 @@
 #include <efi_selftest.h>

 #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;

@@ -30,17 +31,26 @@ static int setup(const efi_handle_t handle,
 /*
  * 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
  */
 static int execute(void)
 {
 	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 */
-	ret = runtime->get_time(&tm, NULL);
+	ret = runtime->get_time(&tm_old, NULL);
 	if (ret != EFI_SUCCESS) {
 #ifdef CONFIG_CMD_DATE
 		efi_st_error(EFI_ST_NO_RTC);
@@ -49,11 +59,41 @@ static int execute(void)
 		efi_st_todo(EFI_ST_NO_RTC);
 		return EFI_ST_SUCCESS;
 #endif
-	} else {
-		efi_st_printf("Time according to real time clock: "
-			      "%.4u-%.2u-%.2u %.2u:%.2u:%.2u\n",
-			      tm.year, tm.month, tm.day,
-			      tm.hour, tm.minute, tm.second);
+	}
+	efi_st_printf("Time according to real time clock: "
+		      "%.4u-%.2u-%.2u %.2u:%.2u:%.2u\n",
+		      tm_old.year, tm_old.month, tm_old.day,
+		      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;
--
2.20.1

^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2019-05-21 15:40 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-05-21 15:40 [U-Boot] [PATCH v2 1/1] efi_loader: implement SetTime Heinrich Schuchardt

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.