efi_loader: validate load option
[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_old;
44 #ifdef CONFIG_EFI_SET_TIME
45         struct efi_time tm, tm_new = {
46                 .year = 2017,
47                 .month = 5,
48                 .day = 19,
49                 .hour = 13,
50                 .minute = 47,
51                 .second = 53,
52         };
53 #endif
54
55         /* Display current time */
56         ret = runtime->get_time(&tm_old, NULL);
57         if (ret != EFI_SUCCESS) {
58                 efi_st_error(EFI_ST_NO_RTC);
59                 return EFI_ST_FAILURE;
60         }
61         efi_st_printf("Time according to real time clock: "
62                       "%.4u-%.2u-%.2u %.2u:%.2u:%.2u\n",
63                       tm_old.year, tm_old.month, tm_old.day,
64                       tm_old.hour, tm_old.minute, tm_old.second);
65 #ifdef CONFIG_EFI_SET_TIME
66         ret = runtime->set_time(&tm_new);
67         if (ret != EFI_SUCCESS) {
68                 efi_st_error(EFI_ST_NO_RTC_SET);
69                 return EFI_ST_FAILURE;
70         }
71         ret = runtime->get_time(&tm, NULL);
72         if (ret != EFI_SUCCESS) {
73                 efi_st_error(EFI_ST_NO_RTC);
74                 return EFI_ST_FAILURE;
75         }
76         if (tm.year != tm_new.year ||
77             tm.month != tm_new.month ||
78             tm.day != tm_new.day ||
79             tm.hour !=  tm_new.hour ||
80             tm.minute != tm_new.minute ||
81             tm.second < tm_new.second ||
82             tm.second > tm_new.second + 2) {
83                 efi_st_error(EFI_ST_NO_RTC_SET);
84                 return EFI_ST_FAILURE;
85         }
86         /* Set time back to old value */
87         ret = runtime->set_time(&tm_old);
88         if (ret != EFI_SUCCESS) {
89                 efi_st_error(EFI_ST_NO_RTC_SET);
90                 return EFI_ST_FAILURE;
91         }
92 #endif
93
94         return EFI_ST_SUCCESS;
95 }
96
97 EFI_UNIT_TEST(rtc) = {
98         .name = "real time clock",
99         .phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT,
100         .setup = setup,
101         .execute = execute,
102 };