blob: f5fb9117717cb9d4a1952a97d5ac11b6875db87c [file] [log] [blame]
Tom Rini70df9d62018-05-07 17:02:21 -04001// SPDX-License-Identifier: GPL-2.0+
Heinrich Schuchardt18081d42017-10-18 18:13:04 +02002/*
3 * EFI watchdog
4 *
5 * Copyright (c) 2017 Heinrich Schuchardt
Heinrich Schuchardt18081d42017-10-18 18:13:04 +02006 */
7
Heinrich Schuchardt18081d42017-10-18 18:13:04 +02008#include <efi_loader.h>
9
10/* Conversion factor from seconds to multiples of 100ns */
11#define EFI_SECONDS_TO_100NS 10000000ULL
12
13static struct efi_event *watchdog_timer_event;
14
Heinrich Schuchardtf011aa42020-04-10 17:51:56 +020015/**
16 * efi_watchdog_timer_notify() - resets system upon watchdog event
17 *
Heinrich Schuchardt18081d42017-10-18 18:13:04 +020018 * Reset the system when the watchdog event is notified.
19 *
20 * @event: the watchdog event
21 * @context: not used
22 */
23static void EFIAPI efi_watchdog_timer_notify(struct efi_event *event,
24 void *context)
25{
26 EFI_ENTRY("%p, %p", event, context);
27
28 printf("\nEFI: Watchdog timeout\n");
Heinrich Schuchardte2345182021-09-09 07:47:05 +020029 do_reset(NULL, 0, 0, NULL);
Heinrich Schuchardt18081d42017-10-18 18:13:04 +020030
31 EFI_EXIT(EFI_UNSUPPORTED);
32}
33
Heinrich Schuchardtf011aa42020-04-10 17:51:56 +020034/**
35 * efi_set_watchdog() - resets the watchdog timer
Heinrich Schuchardt18081d42017-10-18 18:13:04 +020036 *
37 * This function is used by the SetWatchdogTimer service.
38 *
39 * @timeout: seconds before reset by watchdog
Heinrich Schuchardtf011aa42020-04-10 17:51:56 +020040 * Return: status code
Heinrich Schuchardt18081d42017-10-18 18:13:04 +020041 */
42efi_status_t efi_set_watchdog(unsigned long timeout)
43{
44 efi_status_t r;
45
46 if (timeout)
47 /* Reset watchdog */
48 r = efi_set_timer(watchdog_timer_event, EFI_TIMER_RELATIVE,
49 EFI_SECONDS_TO_100NS * timeout);
50 else
51 /* Deactivate watchdog */
52 r = efi_set_timer(watchdog_timer_event, EFI_TIMER_STOP, 0);
53 return r;
54}
55
Heinrich Schuchardtf011aa42020-04-10 17:51:56 +020056/**
57 * efi_watchdog_register() - initializes the EFI watchdog
58 *
59 * This function is called by efi_init_obj_list().
Heinrich Schuchardt18081d42017-10-18 18:13:04 +020060 *
Heinrich Schuchardtf011aa42020-04-10 17:51:56 +020061 * Return: status code
Heinrich Schuchardt18081d42017-10-18 18:13:04 +020062 */
Heinrich Schuchardtf2704cc2018-03-03 15:28:57 +010063efi_status_t efi_watchdog_register(void)
Heinrich Schuchardt18081d42017-10-18 18:13:04 +020064{
65 efi_status_t r;
66
67 /*
68 * Create a timer event.
69 */
70 r = efi_create_event(EVT_TIMER | EVT_NOTIFY_SIGNAL, TPL_CALLBACK,
Heinrich Schuchardtbf7f1692018-02-18 15:17:52 +010071 efi_watchdog_timer_notify, NULL, NULL,
Heinrich Schuchardt18081d42017-10-18 18:13:04 +020072 &watchdog_timer_event);
73 if (r != EFI_SUCCESS) {
74 printf("ERROR: Failed to register watchdog event\n");
75 return r;
76 }
Masahisa Kojimad250a8f2022-02-22 09:58:30 +090077
Heinrich Schuchardtf2704cc2018-03-03 15:28:57 +010078 return EFI_SUCCESS;
Heinrich Schuchardt18081d42017-10-18 18:13:04 +020079}