[PATCH] watchdog: Add driver to HPE ProLiant machines

3 views
Skip to first unread message

Jan Kiszka

unread,
Mar 4, 2022, 3:37:55 PM3/4/22
to efibootguard-dev, Lisicki, Raphael (MO MM R&D SYS SEC)
From: Jan Kiszka <jan.k...@siemens.com>

Tested on a ProLiant DL360 Gen10. Supported devices have been aligned to
Linux' hpwdt.c.

Signed-off-by: Jan Kiszka <jan.k...@siemens.com>
---
Makefile.am | 3 +-
drivers/watchdog/hpwdt.c | 90 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 92 insertions(+), 1 deletion(-)
create mode 100644 drivers/watchdog/hpwdt.c

diff --git a/Makefile.am b/Makefile.am
index 6d6a049..0018fd3 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -152,7 +152,8 @@ efi_sources_watchdogs = \
drivers/watchdog/i6300esb.c \
drivers/watchdog/atom-quark.c \
drivers/watchdog/ipc4x7e_wdt.c \
- drivers/watchdog/itco.c
+ drivers/watchdog/itco.c \
+ drivers/watchdog/hpwdt.c
endif

efi_sources = \
diff --git a/drivers/watchdog/hpwdt.c b/drivers/watchdog/hpwdt.c
new file mode 100644
index 0000000..30c8579
--- /dev/null
+++ b/drivers/watchdog/hpwdt.c
@@ -0,0 +1,90 @@
+/*
+ * EFI Boot Guard
+ *
+ * Copyright (c) Siemens AG, 2022
+ *
+ * Authors:
+ * Jan Kiszka <jan.k...@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 <pci/header.h>
+#include "utils.h"
+
+#define PCI_VENDOR_ID_HP 0x103c
+#define PCI_VENDOR_ID_HP_3PAR 0x1590
+#define PCI_DEVICE_ID_ILO3 0x3306
+#define PCI_DEVICE_ID_AUX_ILO 0x1979
+#define PCI_DEVICE_ID_CL 0x0289
+#define PCI_DEVICE_ID_PCTRL 0x0389
+
+#define HPWDT_TIMER_REG 0x70
+#define HPWDT_TIMER_CON 0x72
+
+#define SECS_TO_TICKS(secs) ((secs) * 1000 / 128)
+
+#define PCI_GET_SUBSYS_VENDOR_ID(id) (UINT16)(id)
+#define PCI_GET_SUBSYS_PRODUCT_ID(id) (UINT16)((id) >> 16)
+
+static EFI_STATUS __attribute__((constructor))
+init(EFI_PCI_IO *pci_io, UINT16 pci_vendor_id, UINT16 pci_device_id,
+ UINTN timeout)
+{
+ EFI_STATUS status;
+ UINT16 reload;
+ UINT8 control;
+
+ if (!pci_io ||
+ !((pci_vendor_id == PCI_VENDOR_ID_HP &&
+ pci_device_id == PCI_DEVICE_ID_ILO3) ||
+ (pci_vendor_id == PCI_VENDOR_ID_HP_3PAR &&
+ pci_device_id == PCI_DEVICE_ID_PCTRL))) {
+ return EFI_UNSUPPORTED;
+ }
+
+ if (pci_device_id == PCI_DEVICE_ID_ILO3) {
+ UINT16 vendor, product;
+ UINT32 value;
+
+ status = uefi_call_wrapper(pci_io->Pci.Read, 5, pci_io,
+ EfiPciIoWidthUint32,
+ PCI_SUBSYSTEM_VENDOR_ID, 1, &value);
+ if (EFI_ERROR(status)) {
+ return status;
+ }
+
+ vendor = PCI_GET_SUBSYS_VENDOR_ID(value);
+ product = PCI_GET_SUBSYS_PRODUCT_ID(value);
+ if ((vendor == PCI_VENDOR_ID_HP &&
+ product == PCI_DEVICE_ID_AUX_ILO) ||
+ (vendor == PCI_VENDOR_ID_HP_3PAR &&
+ product == PCI_DEVICE_ID_CL)) {
+ return EFI_UNSUPPORTED;
+ }
+ }
+
+ INFO(L"Detected HPE ProLiant watchdog\n");
+
+ reload = SECS_TO_TICKS(timeout);
+ status = uefi_call_wrapper(pci_io->Mem.Write, 6, pci_io,
+ EfiPciIoWidthUint16, 1, HPWDT_TIMER_REG,
+ 1, &reload);
+ if (EFI_ERROR(status)) {
+ return status;
+ }
+
+ control = 0x81;
+ status = uefi_call_wrapper(pci_io->Mem.Write, 6, pci_io,
+ EfiPciIoWidthUint8, 1, HPWDT_TIMER_CON,
+ 1, &control);
+ if (EFI_ERROR(status)) {
+ return status;
+ }
+
+ return EFI_SUCCESS;
+}
--
2.34.1
Reply all
Reply to author
Forward
0 new messages