// SPDX-License-Identifier: Apache-2.0
/*
 * Copyright 2013-2018 IBM Corp.
 * Copyright 2018 Google Corp.
 */

#include <stdlib.h>
#include <ipmi.h>
#include <lock.h>
#include <opal.h>
#include <device.h>
#include <timer.h>
#include <timebase.h>
#include <pool.h>
#include <skiboot.h>

#define TIMER_USE_DONT_LOG	0x80
#define TIMER_USE_DONT_STOP	0x40
#define TIMER_USE_POST		0x02

/* WDT expiration actions */
#define WDT_PRETIMEOUT_SMI	0x10
#define WDT_RESET_ACTION 	0x01
#define WDT_NO_ACTION		0x00

/* IPMI defined custom completion codes for the watchdog */
#define WDT_CC_OK		0x00
#define WDT_CC_NOT_INITIALIZED	0x80

/* Flags used for IPMI callbacks */
#define WDT_SET_DO_RESET	0x01
#define WDT_RESET_NO_REINIT	0x01

/* How long to set the overall watchdog timeout for. In units of
 * 100ms. If the timer is not reset within this time the watchdog
 * expiration action will occur. */
#define WDT_TIMEOUT		600

/* How often to reset the timer using schedule_timer(). Too short and
we risk accidentally resetting the system due to opal_run_pollers() not
being called in time, too short and we waste time resetting the wdt
more frequently than necessary. */
#define WDT_MARGIN		300

static struct timer wdt_timer;
static bool wdt_ticking;

/* Saved values from the last watchdog set action */
static uint8_t last_action;
static uint16_t last_count;
static uint8_t last_pretimeout;

static void reset_wdt(struct timer *t, void *data, uint64_t now);

static void set_wdt_complete(struct ipmi_msg *msg)
{
	const uintptr_t flags = (uintptr_t)msg->user_data;

	if (flags & WDT_SET_DO_RESET) {
		/* Make sure the reset action does not create a loop and
		 * perform a reset in the case where the BMC send an
		 * uninitialized error. */
		reset_wdt(NULL, (void *)WDT_RESET_NO_REINIT, 0);
	}

	ipmi_free_msg(msg);
}

static void set_wdt(uint8_t action, uint16_t count, uint8_t pretimeout,
		bool dont_stop, bool do_reset)
{
	struct ipmi_msg *ipmi_msg;
	uintptr_t completion_flags = 0;

	if (do_reset)
		completion_flags |= WDT_SET_DO_RESET;

	/* Save the values prior to issuing the set operation so that we can
	 * re-initialize the watchdog in error cases. */
	last_action = action;
	last_count = count;
	last_pretimeout = pretimeout;

	ipmi_msg = ipmi_mkmsg(IPMI_DEFAULT_INTERFACE, IPMI_SET_WDT,
			      set_wdt_complete, NULL, NULL, 6, 0);
	if (!ipmi_msg) {
		prerror("Unable to allocate set wdt message\n");
		return;
	}
	ipmi_msg->error = set_wdt_complete;
	ipmi_msg->user_data = (void *)completion_flags;
	ipmi_msg->data[0] = TIMER_USE_POST |
		TIMER_USE_DONT_LOG |
		(dont_stop ? TIMER_USE_DONT_STOP : 0);
	ipmi_msg->data[1] = action;			/* Timer Actions */
	ipmi_msg->data[2] = pretimeout;			/* Pre-timeout Interval */
	ipmi_msg->data[3] = 0;				/* Timer Use Flags */
	ipmi_msg->data[4] = count & 0xff;		/* Initial countdown (lsb) */
	ipmi_msg->data[5] = (count >> 8) & 0xff;	/* Initial countdown (msb) */
	ipmi_queue_msg(ipmi_msg);
}

static void reset_wdt_complete(struct ipmi_msg *msg)
{
	const uintptr_t flags = (uintptr_t)msg->user_data;
	uint64_t reset_delay_ms = (WDT_TIMEOUT - WDT_MARGIN) * 100;

	if (msg->cc == WDT_CC_NOT_INITIALIZED &&
			!(flags & WDT_RESET_NO_REINIT)) {
		/* If our timer was not initialized on the BMC side, we should
		 * perform a single attempt to set it up again. */
		set_wdt(last_action, last_count, last_pretimeout, true, true);
	} else if (msg->cc != WDT_CC_OK) {
		/* Use a short (10s) timeout before performing the next reset
		 * if we encounter an unknown error. This makes sure that we
		 * are able to reset and re-initialize the timer since it might
		 * expire. */
		reset_delay_ms = 10 * 1000;
	}

	/* If we are inside of skiboot we need to periodically restart the
	 * timer. Reschedule a reset so it happens before the timeout. */
	if (wdt_ticking)
		schedule_timer(&wdt_timer, msecs_to_tb(reset_delay_ms));

	ipmi_free_msg(msg);
}

static struct ipmi_msg *wdt_reset_mkmsg(void)
{
	struct ipmi_msg *ipmi_msg;

	ipmi_msg = ipmi_mkmsg(IPMI_DEFAULT_INTERFACE, IPMI_RESET_WDT,
			      reset_wdt_complete, NULL, NULL, 0, 0);
	if (!ipmi_msg) {
		prerror("Unable to allocate reset wdt message\n");
		return NULL;
	}
	ipmi_msg->error = reset_wdt_complete;

	return ipmi_msg;
}

static void sync_reset_wdt(void)
{
	struct ipmi_msg *ipmi_msg;

	if ((ipmi_msg = wdt_reset_mkmsg()))
		ipmi_queue_msg_sync(ipmi_msg);
}

static void reset_wdt(struct timer *t __unused, void *data,
		      uint64_t now __unused)
{
	struct ipmi_msg *ipmi_msg;

	if ((ipmi_msg = wdt_reset_mkmsg())) {
		ipmi_msg->user_data = data;
		ipmi_queue_msg_head(ipmi_msg);
	}
}

void ipmi_wdt_final_reset(void)
{
	/* We can safely stop the timer prior to setting up our final
	 * watchdog timeout since we have enough margin before the
	 * timeout. */
	wdt_ticking = false;
	cancel_timer(&wdt_timer);

	/*
	 * We're going to wait a little while before requiring
	 * BOOTKERNEL to have IPMI watchdog support so that people
	 * can catch up in their development environments.
	 * If you still read this after 2018, send a patch!
	 */
	set_wdt(WDT_NO_ACTION, 100, 0, false, false);
}

void ipmi_wdt_init(void)
{
	init_timer(&wdt_timer, reset_wdt, NULL);
	set_wdt(WDT_RESET_ACTION, WDT_TIMEOUT, 0, true, false);

	/* Start the WDT. We do it synchronously to make sure it has
	 * started before skiboot continues booting. Otherwise we
	 * could crash before the wdt has actually been started. */
	wdt_ticking = true;
	sync_reset_wdt();

	return;
}
