From patchwork Tue Oct 10 12:23:04 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rob Clark X-Patchwork-Id: 823815 X-Patchwork-Delegate: agraf@suse.de Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="ckV9kroF"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 3yBGfn2pztz9tY3 for ; Tue, 10 Oct 2017 23:30:41 +1100 (AEDT) Received: by lists.denx.de (Postfix, from userid 105) id 2279FC21DD9; Tue, 10 Oct 2017 12:27:07 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=-0.0 required=5.0 tests=FREEMAIL_FROM, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, T_DKIM_INVALID autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id 8251BC21E0F; Tue, 10 Oct 2017 12:24:47 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id A151AC21DF1; Tue, 10 Oct 2017 12:23:53 +0000 (UTC) Received: from mail-qt0-f196.google.com (mail-qt0-f196.google.com [209.85.216.196]) by lists.denx.de (Postfix) with ESMTPS id 00D63C21DA3 for ; Tue, 10 Oct 2017 12:23:49 +0000 (UTC) Received: by mail-qt0-f196.google.com with SMTP id 24so4848432qts.3 for ; Tue, 10 Oct 2017 05:23:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=lue4HotMp115CHyOhWpabjbgw+CVMtoUkkCod2foFIA=; b=ckV9kroF9i0yBUwAae/FEyovHX7GsNMuquPXhhW0MhvolP5+gzF0sciVcDpbbwe/tj Zh/MMfO/1xwWqHffnpPnbNrpprQjSl0g2hwNNdGgZUVcC6ddTD9iUfXPbJOvWULmb1E4 bPdn23kCx5wCOLaiSzzXfFT6eEQKq8qRKSYTlxxyApfgzPlT5owQQjzibVW9MQ7/M5UW OV4F61DADbJpRMC9a51lRQ2u4z+NwDFJWygUguGNp9JYFxXl1u5+OPxYljQyBS1PWqnZ 4jtPAO0DGE1JgfRgtu1UjNKjb7hLEU3ehOq4IVMDnNvgPnENyXTXNRR6tYVE4jGoQrvW h5MA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=lue4HotMp115CHyOhWpabjbgw+CVMtoUkkCod2foFIA=; b=ml2PZ+dWjVlNWofUpa8zNLQFmZ0XTEt9a1S3hfkM2+B7fAHeqMtwAGcDxbytlC3UEo b4QPLo4hGuWSfMdkxPIbvFym6XWcXMEoXtI1/shFIA3bOhH+9L3UfdWB6udes5SlE2hW ZqqAzBobKl/xaI0LQo0YpzqhwB61uDaajZnw3xNribx0I31+esHbMYO5ayC87/CAhyqh kLn9mYU9F0MQ3Ot/IvN14wWZ0dJnwHnmLYyxwOK7JftH8eDQkNC6/9k3gZDkiLzzT0YE bQMPL7NutX+BxbzA2ONm0vM/skQme8HmGQdLB3nt+5+l8WcI+Rg1w2B4/WhJdxM4IN3l JshA== X-Gm-Message-State: AMCzsaWV+OXZ5DjCzzZf2VHkqpCD6CJ/XTXyrC7y1acwuRhZWujLCSaX kn4+tddCnkfCvu/e330EekE1qyIL X-Google-Smtp-Source: AOwi7QCNsp4U35iOWyuRXZV2QeIylzXLMm8tMzuWmt7Myqz+x+dsFA2wwJuWZ0FqoXfGxbWly2L1lw== X-Received: by 10.55.95.67 with SMTP id t64mr1489512qkb.249.1507638227622; Tue, 10 Oct 2017 05:23:47 -0700 (PDT) Received: from localhost ([144.121.20.162]) by smtp.gmail.com with ESMTPSA id b194sm3008956qkc.31.2017.10.10.05.23.46 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 10 Oct 2017 05:23:46 -0700 (PDT) From: Rob Clark To: U-Boot Mailing List Date: Tue, 10 Oct 2017 08:23:04 -0400 Message-Id: <20171010122309.25313-9-robdclark@gmail.com> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20171010122309.25313-1-robdclark@gmail.com> References: <20171010122309.25313-1-robdclark@gmail.com> Cc: Heinrich Schuchardt , Leif Lindholm Subject: [U-Boot] [PATCH 08/11] efi_loader: implement SetWatchdogTimer X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" From: Heinrich Schuchardt The watchdog is initialized with a 5 minute timeout period. It can be reset by SetWatchdogTimer. It is stopped by ExitBoottimeServices. Signed-off-by: Heinrich Schuchardt Reviewed-by: Alexander Graf --- cmd/bootefi.c | 1 + include/efi_loader.h | 4 ++ lib/efi_loader/Makefile | 2 +- lib/efi_loader/efi_boottime.c | 17 ++------- lib/efi_loader/efi_watchdog.c | 86 +++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 95 insertions(+), 15 deletions(-) create mode 100644 lib/efi_loader/efi_watchdog.c diff --git a/cmd/bootefi.c b/cmd/bootefi.c index b7087e3da8..24958ada46 100644 --- a/cmd/bootefi.c +++ b/cmd/bootefi.c @@ -43,6 +43,7 @@ static void efi_init_obj_list(void) #ifdef CONFIG_GENERATE_SMBIOS_TABLE efi_smbios_register(); #endif + efi_watchdog_register(); /* Initialize EFI runtime services */ efi_reset_system_init(); diff --git a/include/efi_loader.h b/include/efi_loader.h index 2232caca44..fa4e1cdb1c 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -169,6 +169,8 @@ int efi_disk_register(void); int efi_gop_register(void); /* Called by bootefi to make the network interface available */ int efi_net_register(void); +/* Called by bootefi to make the watchdog available */ +int efi_watchdog_register(void); /* Called by bootefi to make SMBIOS tables available */ void efi_smbios_register(void); @@ -177,6 +179,8 @@ efi_fs_from_path(struct efi_device_path *fp); /* Called by networking code to memorize the dhcp ack package */ void efi_net_set_dhcp_ack(void *pkt, int len); +/* Called by efi_set_watchdog_timer to reset the timer */ +efi_status_t efi_set_watchdog(unsigned long timeout); /* Called from places to check whether a timer expired */ void efi_timer_check(void); diff --git a/lib/efi_loader/Makefile b/lib/efi_loader/Makefile index 7ea96a4f1c..4238cf9f9b 100644 --- a/lib/efi_loader/Makefile +++ b/lib/efi_loader/Makefile @@ -18,7 +18,7 @@ obj-$(CONFIG_CMD_BOOTEFI_HELLO) += helloworld_efi.o obj-y += efi_image_loader.o efi_boottime.o efi_runtime.o efi_console.o obj-y += efi_memory.o efi_device_path_to_text.o efi_device_path.o obj-y += efi_device_path_utilities.o efi_hii.o efi_unicode.o -obj-y += efi_file.o efi_variable.o efi_bootmgr.o +obj-y += efi_file.o efi_variable.o efi_bootmgr.o efi_watchdog.o obj-$(CONFIG_LCD) += efi_gop.o obj-$(CONFIG_DM_VIDEO) += efi_gop.o obj-$(CONFIG_PARTITIONS) += efi_disk.o diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c index 19fafe546c..310f0a3b62 100644 --- a/lib/efi_loader/efi_boottime.c +++ b/lib/efi_loader/efi_boottime.c @@ -156,18 +156,6 @@ void efi_signal_event(struct efi_event *event) } /* - * Write a debug message for an EPI API service that is not implemented yet. - * - * @funcname function that is not yet implemented - * @return EFI_UNSUPPORTED - */ -static efi_status_t efi_unsupported(const char *funcname) -{ - debug("EFI: App called into unimplemented function %s\n", funcname); - return EFI_EXIT(EFI_UNSUPPORTED); -} - -/* * Raise the task priority level. * * This function implements the RaiseTpl service. @@ -1470,6 +1458,7 @@ static efi_status_t EFIAPI efi_exit_boot_services(void *image_handle, bootm_disable_interrupts(); /* Give the payload some time to boot */ + efi_set_watchdog(0); WATCHDOG_RESET(); return EFI_EXIT(EFI_SUCCESS); @@ -1513,7 +1502,7 @@ static efi_status_t EFIAPI efi_stall(unsigned long microseconds) /* * Reset the watchdog timer. * - * This function implements the WatchdogTimer service. + * This function implements the SetWatchdogTimer service. * See the Unified Extensible Firmware Interface (UEFI) specification * for details. * @@ -1529,7 +1518,7 @@ static efi_status_t EFIAPI efi_set_watchdog_timer(unsigned long timeout, { EFI_ENTRY("%ld, 0x%"PRIx64", %ld, %p", timeout, watchdog_code, data_size, watchdog_data); - return efi_unsupported(__func__); + return EFI_EXIT(efi_set_watchdog(timeout)); } /* diff --git a/lib/efi_loader/efi_watchdog.c b/lib/efi_loader/efi_watchdog.c new file mode 100644 index 0000000000..eb437faf4b --- /dev/null +++ b/lib/efi_loader/efi_watchdog.c @@ -0,0 +1,86 @@ +/* + * EFI watchdog + * + * Copyright (c) 2017 Heinrich Schuchardt + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include + +static struct efi_event *watchdog_timer_event; + +/* + * Reset the system when the watchdog event is notified. + * + * @event: the watchdog event + * @context: not used + */ +static void EFIAPI efi_watchdog_timer_notify(struct efi_event *event, + void *context) +{ + EFI_ENTRY("%p, %p", event, context); + + printf("\nEFI: Watchdog timeout\n"); + EFI_CALL_VOID(efi_runtime_services.reset_system(EFI_RESET_COLD, + EFI_SUCCESS, 0, NULL)); + + EFI_EXIT(EFI_UNSUPPORTED); +} + +/* + * Reset the watchdog timer. + * + * This function is used by the SetWatchdogTimer service. + * + * @timeout: seconds before reset by watchdog + * @return: status code + */ +efi_status_t efi_set_watchdog(unsigned long timeout) +{ + efi_status_t r; + + if (timeout) + /* Reset watchdog */ + r = efi_set_timer(watchdog_timer_event, EFI_TIMER_RELATIVE, + 10000000 * timeout); + else + /* Deactivate watchdog */ + r = efi_set_timer(watchdog_timer_event, EFI_TIMER_STOP, 0); + return r; +} + +/* + * Initialize the EFI watchdog. + * + * This function is called by efi_init_obj_list() + */ +int efi_watchdog_register(void) +{ + efi_status_t r; + + /* + * Create a timer event. + */ + r = efi_create_event(EVT_TIMER | EVT_NOTIFY_SIGNAL, TPL_CALLBACK, + efi_watchdog_timer_notify, NULL, + &watchdog_timer_event); + if (r != EFI_SUCCESS) { + printf("ERROR: Failed to register watchdog event\n"); + return r; + } + /* + * The UEFI standard requires that the watchdog timer is set to five + * minutes when invoking an EFI boot option. + * + * Unified Extensible Firmware Interface (UEFI), version 2.7 Errata A + * 7.5. Miscellaneous Boot Services - EFI_BOOT_SERVICES.SetWatchdogTimer + */ + r = efi_set_watchdog(300); + if (r != EFI_SUCCESS) { + printf("ERROR: Failed to set watchdog timer\n"); + return r; + } + return 0; +}