cmd: env: add -nv option for UEFI non-volatile variable
[oweals/u-boot.git] / lib / efi_selftest / efi_selftest_rtc.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * efi_selftest_rtc
4  *
5  * Copyright (c) 2018 Heinrich Schuchardt <xypron.glpk@gmx.de>
6  *
7  * Test the real time clock runtime services.
8  */
9
10 #include <efi_selftest.h>
11
12 #define EFI_ST_NO_RTC "Could not read real time clock\n"
13 #define EFI_ST_NO_RTC_SET "Could not set real time clock\n"
14
15 static struct efi_runtime_services *runtime;
16
17 /*
18  * Setup unit test.
19  *
20  * @handle:     handle of the loaded image
21  * @systable:   system table
22  * @return:     EFI_ST_SUCCESS for success
23  */
24 static int setup(const efi_handle_t handle,
25                  const struct efi_system_table *systable)
26 {
27         runtime = systable->runtime;
28         return EFI_ST_SUCCESS;
29 }
30
31 /*
32  * Execute unit test.
33  *
34  * Read and display current time.
35  * Set a new value and read it back.
36  * Set the real time clock back the current time.
37  *
38  * @return:     EFI_ST_SUCCESS for success
39  */
40 static int execute(void)
41 {
42         efi_status_t ret;
43         struct efi_time tm, tm_old, tm_new = {
44                 .year = 2017,
45                 .month = 5,
46                 .day = 19,
47                 .hour = 13,
48                 .minute = 47,
49                 .second = 53,
50         };
51
52         /* Display current time */
53         ret = runtime->get_time(&tm_old, NULL);
54         if (ret != EFI_SUCCESS) {
55 #ifdef CONFIG_CMD_DATE
56                 efi_st_error(EFI_ST_NO_RTC);
57                 return EFI_ST_FAILURE;
58 #else
59                 efi_st_todo(EFI_ST_NO_RTC);
60                 return EFI_ST_SUCCESS;
61 #endif
62         }
63         efi_st_printf("Time according to real time clock: "
64                       "%.4u-%.2u-%.2u %.2u:%.2u:%.2u\n",
65                       tm_old.year, tm_old.month, tm_old.day,
66                       tm_old.hour, tm_old.minute, tm_old.second);
67         ret = runtime->set_time(&tm_new);
68         if (ret != EFI_SUCCESS) {
69 #ifdef CONFIG_CMD_DATE
70                 efi_st_error(EFI_ST_NO_RTC_SET);
71                 return EFI_ST_FAILURE;
72 #else
73                 efi_st_todo(EFI_ST_NO_RTC_SET);
74                 return EFI_ST_SUCCESS;
75 #endif
76         }
77         ret = runtime->get_time(&tm, NULL);
78         if (ret != EFI_SUCCESS) {
79                 efi_st_error(EFI_ST_NO_RTC);
80                 return EFI_ST_FAILURE;
81         }
82         if (tm.year != tm_new.year ||
83             tm.month != tm_new.month ||
84             tm.day != tm_new.day ||
85             tm.hour !=  tm_new.hour ||
86             tm.minute != tm_new.minute ||
87             tm.second < tm_new.second ||
88             tm.second > tm_new.second + 2) {
89                 efi_st_error(EFI_ST_NO_RTC_SET);
90                 return EFI_ST_FAILURE;
91         }
92         /* Set time back to old value */
93         ret = runtime->set_time(&tm_old);
94         if (ret != EFI_SUCCESS) {
95                 efi_st_error(EFI_ST_NO_RTC_SET);
96                 return EFI_ST_FAILURE;
97         }
98
99         return EFI_ST_SUCCESS;
100 }
101
102 EFI_UNIT_TEST(rtc) = {
103         .name = "real time clock",
104         .phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT,
105         .setup = setup,
106         .execute = execute,
107 };