From: Christian Storm <
christi...@siemens.com>
Carve out EFI Boot Guard's watchdog arming part in preparation to
enable aarch64 support -- which is then naturally restricted to
the switching logics only -- as the watchdog drivers are specific
to x86. For x86, there's no change in behavior.
Signed-off-by: Christian Storm <
christi...@siemens.com>
---
Makefile.am | 2 +
include/watchdog.h | 27 +++++++++++++
main.c | 73 +---------------------------------
watchdog.c | 97 ++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 127 insertions(+), 72 deletions(-)
create mode 100644 include/watchdog.h
create mode 100644 watchdog.c
diff --git a/Makefile.am b/Makefile.am
index 8347749..91bcf46 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -133,6 +133,7 @@ efi_sources = \
drivers/watchdog/ipc4x7e_wdt.c \
drivers/watchdog/itco.c \
drivers/watchdog/init_array_end.S \
+ watchdog.c \
env/syspart.c \
env/fatvars.c \
utils.c \
@@ -166,6 +167,7 @@ efi_cflags = \
if ARCH_X86_64
efi_cflags += \
-DEFI_FUNCTION_WRAPPER \
+ -DWATCHDOG_DRIVERS \
-mno-red-zone
endif
diff --git a/include/watchdog.h b/include/watchdog.h
new file mode 100644
index 0000000..0f4cc56
--- /dev/null
+++ b/include/watchdog.h
@@ -0,0 +1,27 @@
+/*
+ * EFI Boot Guard
+ *
+ * Copyright (c) Siemens AG, 2021
+ *
+ * Authors:
+ * Christian Storm <
christi...@siemens.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2. See
+ * the COPYING file in the top-level directory.
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#pragma once
+
+#include <efi.h>
+
+#if defined(WATCHDOG_DRIVERS)
+EFI_STATUS scan_devices(EFI_LOADED_IMAGE *loaded_image, UINTN timeout);
+#else
+EFI_STATUS scan_devices(EFI_LOADED_IMAGE __attribute__((__unused__)) *loaded_image,
+ UINTN __attribute__((__unused__)) timeout)
+{
+ return EFI_SUCCESS;
+}
+#endif
diff --git a/main.c b/main.c
index 0bec838..8e03186 100644
--- a/main.c
+++ b/main.c
@@ -20,83 +20,12 @@
#include <pci/header.h>
#include <bootguard.h>
#include <configuration.h>
+#include <watchdog.h>
#include "version.h"
#include "utils.h"
-extern const unsigned long init_array_start[];
-extern const unsigned long init_array_end[];
extern CHAR16 *boot_medium_path;
-static EFI_STATUS probe_watchdog(EFI_LOADED_IMAGE *loaded_image,
- EFI_PCI_IO *pci_io, UINT16 pci_vendor_id,
- UINT16 pci_device_id, UINTN timeout)
-{
- const unsigned long *entry;
-
- for (entry = init_array_start; entry < init_array_end; entry++) {
- EFI_STATUS (*probe)(EFI_PCI_IO *, UINT16, UINT16, UINTN);
-
- probe = loaded_image->ImageBase + *entry;
- if (probe(pci_io, pci_vendor_id, pci_device_id, timeout) ==
- EFI_SUCCESS) {
- return EFI_SUCCESS;
- }
- }
-
- return EFI_UNSUPPORTED;
-}
-
-static EFI_STATUS scan_devices(EFI_LOADED_IMAGE *loaded_image, UINTN timeout)
-{
- EFI_HANDLE devices[1000];
- UINTN count, size = sizeof(devices);
- EFI_PCI_IO *pci_io;
- EFI_STATUS status;
- UINT32 value;
-
- status = uefi_call_wrapper(BS->LocateHandle, 5, ByProtocol,
- &PciIoProtocol, NULL, &size, devices);
- if (EFI_ERROR(status)) {
- return status;
- }
-
- count = size / sizeof(EFI_HANDLE);
- if (count == 0) {
- return probe_watchdog(loaded_image, NULL, 0, 0, timeout);
- }
-
- do {
- EFI_HANDLE device = devices[count - 1];
-
- count--;
-
- status = uefi_call_wrapper(BS->OpenProtocol, 6, device,
- &PciIoProtocol, (VOID **)&pci_io,
- this_image, NULL,
- EFI_OPEN_PROTOCOL_GET_PROTOCOL);
- if (EFI_ERROR(status)) {
- error_exit(L"Cannot open PciIoProtocol while probing watchdogs",
- status);
- }
-
- status = uefi_call_wrapper(pci_io->Pci.Read, 5, pci_io,
- EfiPciIoWidthUint32, PCI_VENDOR_ID,
- 1, &value);
- if (EFI_ERROR(status)) {
- error_exit(L"Cannot read from PCI device while probing watchdogs",
- status);
- }
-
- status = probe_watchdog(loaded_image, pci_io, (UINT16)value,
- value >> 16, timeout);
-
- uefi_call_wrapper(BS->CloseProtocol, 4, device, &PciIoProtocol,
- this_image, NULL);
- } while (status != EFI_SUCCESS && count > 0);
-
- return status;
-}
-
EFI_STATUS efi_main(EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *system_table)
{
EFI_DEVICE_PATH *payload_dev_path;
diff --git a/watchdog.c b/watchdog.c
new file mode 100644
index 0000000..60fba03
--- /dev/null
+++ b/watchdog.c
@@ -0,0 +1,97 @@
+/*
+ * EFI Boot Guard
+ *
+ * Copyright (c) Siemens AG, 2017
+ *
+ * Authors:
+ * Jan Kiszka <
jan.k...@siemens.com>
+ * Andreas Reichel <
andreas.r...@siemens.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2. See
+ * the COPYING file in the top-level directory.
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include <efi.h>
+#include <efilib.h>
+#include <efiprot.h>
+#include <efipciio.h>
+#include <pci/header.h>
+#include <bootguard.h>
+#include <watchdog.h>
+#include "utils.h"
+
+extern const unsigned long init_array_start[];
+extern const unsigned long init_array_end[];
+
+static EFI_STATUS probe_watchdog(EFI_LOADED_IMAGE *loaded_image,
+ EFI_PCI_IO *pci_io, UINT16 pci_vendor_id,
+ UINT16 pci_device_id, UINTN timeout)
+{
+ const unsigned long *entry;
+
+ for (entry = init_array_start; entry < init_array_end; entry++) {
+ EFI_STATUS (*probe)(EFI_PCI_IO *, UINT16, UINT16, UINTN);
+
+ probe = loaded_image->ImageBase + *entry;
+ if (probe(pci_io, pci_vendor_id, pci_device_id, timeout) ==
+ EFI_SUCCESS) {
+ return EFI_SUCCESS;
+ }
+ }
+
+ return EFI_UNSUPPORTED;
+}
+
+EFI_STATUS scan_devices(EFI_LOADED_IMAGE *loaded_image, UINTN timeout)
+{
+ EFI_HANDLE devices[1000];
+ UINTN count, size = sizeof(devices);
+ EFI_PCI_IO *pci_io;
+ EFI_STATUS status;
+ UINT32 value;
+
+ status = uefi_call_wrapper(BS->LocateHandle, 5, ByProtocol,
+ &PciIoProtocol, NULL, &size, devices);
+ if (EFI_ERROR(status)) {
+ return status;
+ }
+
+ count = size / sizeof(EFI_HANDLE);
+ if (count == 0) {
+ return probe_watchdog(loaded_image, NULL, 0, 0, timeout);
+ }
+
+ do {
+ EFI_HANDLE device = devices[count - 1];
+
+ count--;
+
+ status = uefi_call_wrapper(BS->OpenProtocol, 6, device,
+ &PciIoProtocol, (VOID **)&pci_io,
+ this_image, NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+ if (EFI_ERROR(status)) {
+ error_exit(L"Cannot open PciIoProtocol while probing watchdogs",
+ status);
+ }
+
+ status = uefi_call_wrapper(pci_io->Pci.Read, 5, pci_io,
+ EfiPciIoWidthUint32, PCI_VENDOR_ID,
+ 1, &value);
+ if (EFI_ERROR(status)) {
+ error_exit(L"Cannot read from PCI device while probing watchdogs",
+ status);
+ }
+
+ status = probe_watchdog(loaded_image, pci_io, (UINT16)value,
+ value >> 16, timeout);
+
+ uefi_call_wrapper(BS->CloseProtocol, 4, device, &PciIoProtocol,
+ this_image, NULL);
+ } while (status != EFI_SUCCESS && count > 0);
+
+ return status;
+}
+
--
2.32.0