uboot/lib/efi_selftest/efi_selftest_rtc.c
<<
>>
Prefs
   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
  15static 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 */
  24static 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 */
  40static 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
  97EFI_UNIT_TEST(rtc) = {
  98        .name = "real time clock",
  99        .phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT,
 100        .setup = setup,
 101        .execute = execute,
 102};
 103