exit(exit_code);
}
+unsigned int os_alarm(unsigned int seconds)
+{
+ return alarm(seconds);
+}
+
+void os_set_alarm_handler(void (*handler)(int))
+{
+ if (!handler)
+ handler = SIG_DFL;
+ signal(SIGALRM, handler);
+}
+
+void os_raise_sigalrm(void)
+{
+ raise(SIGALRM);
+}
+
int os_write_file(const char *fname, const void *buf, int size)
{
int fd;
can be probed and supports all of the methods of WDT, but does not
really do anything.
+config WDT_ALARM_SANDBOX
+ bool "Enable SIGALRM-based Watchdog Timer support for Sandbox"
+ depends on SANDBOX && WDT
+ help
+ Enable support for a SIGALRM-based watchdog timer in Sandbox. This is
+ a watchdog device based on the host OS' alarm() function, which will
+ kill the sandbox with SIGALRM unless properly maintained.
+
config WDT_SBSA
bool "SBSA watchdog timer support"
depends on WDT
obj-$(CONFIG_ULP_WATCHDOG) += ulp_wdog.o
obj-$(CONFIG_$(SPL_TPL_)WDT) += wdt-uclass.o
obj-$(CONFIG_WDT_SANDBOX) += sandbox_wdt.o
+obj-$(CONFIG_WDT_ALARM_SANDBOX) += sandbox_alarm-wdt.o
obj-$(CONFIG_WDT_APPLE) += apple_wdt.o
obj-$(CONFIG_WDT_ARMADA_37XX) += armada-37xx-wdt.o
obj-$(CONFIG_WDT_ASPEED) += ast_wdt.o
--- /dev/null
+#include <common.h>
+#include <dm.h>
+#include <os.h>
+#include <wdt.h>
+
+struct alarm_wdt_priv {
+ unsigned int timeout_sec;
+};
+
+static void alarm_handler(int sig)
+{
+ const char *msg = "!!! ALARM !!!\n";
+
+ os_write(2, msg, strlen(msg));
+ os_fd_restore();
+ os_set_alarm_handler(NULL);
+ os_raise_sigalrm();
+}
+
+static int alarm_wdt_start(struct udevice *dev, u64 timeout, ulong flags)
+{
+ struct alarm_wdt_priv *priv = dev_get_priv(dev);
+ unsigned int sec;
+
+ timeout = DIV_ROUND_UP(timeout, 1000);
+ sec = min_t(u64, UINT_MAX, timeout);
+ priv->timeout_sec = sec;
+
+ os_alarm(0);
+ os_set_alarm_handler(alarm_handler);
+ os_alarm(sec);
+
+ return 0;
+}
+
+static int alarm_wdt_stop(struct udevice *dev)
+{
+ os_alarm(0);
+ os_set_alarm_handler(NULL);
+
+ return 0;
+}
+
+static int alarm_wdt_reset(struct udevice *dev)
+{
+ struct alarm_wdt_priv *priv = dev_get_priv(dev);
+
+ os_alarm(priv->timeout_sec);
+
+ return 0;
+}
+
+static int alarm_wdt_expire_now(struct udevice *dev, ulong flags)
+{
+ alarm_handler(0);
+
+ return 0;
+}
+
+
+static const struct wdt_ops alarm_wdt_ops = {
+ .start = alarm_wdt_start,
+ .reset = alarm_wdt_reset,
+ .stop = alarm_wdt_stop,
+ .expire_now = alarm_wdt_expire_now,
+};
+
+static const struct udevice_id alarm_wdt_ids[] = {
+ { .compatible = "sandbox,alarm-wdt" },
+ {}
+};
+
+U_BOOT_DRIVER(alarm_wdt_sandbox) = {
+ .name = "alarm_wdt_sandbox",
+ .id = UCLASS_WDT,
+ .of_match = alarm_wdt_ids,
+ .ops = &alarm_wdt_ops,
+ .priv_auto = sizeof(struct alarm_wdt_priv),
+};
*/
void os_exit(int exit_code) __attribute__((noreturn));
+/**
+ * os_alarm() - access to the OS alarm() system call
+ */
+unsigned int os_alarm(unsigned int seconds);
+
+/**
+ * os_set_alarm_handler() - set handler for SIGALRM
+ *
+ * @handler: The handler function. Pass NULL for SIG_DFL.
+ */
+void os_set_alarm_handler(void (*handler)(int));
+
+/**
+ * os_raise_sigalrm() - do raise(SIGALRM)
+ */
+void os_raise_sigalrm(void);
+
/**
* os_tty_raw() - put tty into raw mode to mimic serial console better
*