1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * EFI watchdog 4 * 5 * Copyright (c) 2017 Heinrich Schuchardt 6 */ 7 8#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 15/** 16 * efi_watchdog_timer_notify() - resets system upon watchdog event 17 * 18 * 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"); 29 do_reset(NULL, 0, 0, NULL); 30 31 EFI_EXIT(EFI_UNSUPPORTED); 32} 33 34/** 35 * efi_set_watchdog() - resets the watchdog timer 36 * 37 * This function is used by the SetWatchdogTimer service. 38 * 39 * @timeout: seconds before reset by watchdog 40 * Return: status code 41 */ 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 56/** 57 * efi_watchdog_register() - initializes the EFI watchdog 58 * 59 * This function is called by efi_init_obj_list(). 60 * 61 * Return: status code 62 */ 63efi_status_t efi_watchdog_register(void) 64{ 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, 71 efi_watchdog_timer_notify, NULL, NULL, 72 &watchdog_timer_event); 73 if (r != EFI_SUCCESS) { 74 printf("ERROR: Failed to register watchdog event\n"); 75 return r; 76 } 77 78 return EFI_SUCCESS; 79} 80