/*
 * This file is part of the coreboot project.
 *
 * Copyright (C) 2013 Google, Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 2 of the License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */
#ifndef BOOTSTATE_H
#define BOOTSTATE_H

#include <rules.h>
#include <string.h>
#include <stdlib.h>
#include <stddef.h>
#include <stdint.h>
/* Only declare main() when in ramstage. */
#if ENV_RAMSTAGE
#include <main_decl.h>
#endif

/*
 * The boot state machine provides a mechanism for calls to be made through-
 * out the main boot process. The boot process is separated into discrete
 * states. Upon a state's entry and exit and callbacks can be made. For
 * example:
 *
 *      Enter State
 *           +
 *           |
 *           V
 *   +-----------------+
 *   | Entry callbacks |
 *   +-----------------+
 *   | State Actions   |
 *   +-----------------+
 *   | Exit callbacks  |
 *   +-------+---------+
 *           |
 *           V
 *       Next State
 *
 * Below is the current flow from top to bottom:
 *
 *        start
 *          |
 *    BS_PRE_DEVICE
 *          |
 *    BS_DEV_INIT_CHIPS
 *          |
 *    BS_DEV_ENUMERATE
 *          |
 *    BS_DEV_RESOURCES
 *          |
 *    BS_DEV_ENABLE
 *          |
 *    BS_DEV_INIT
 *          |
 *    BS_POST_DEVICE
 *          |
 *    BS_OS_RESUME_CHECK -------- BS_OS_RESUME
 *          |                          |
 *    BS_WRITE_TABLES              os handoff
 *          |
 *    BS_PAYLOAD_LOAD
 *          |
 *    BS_PAYLOAD_BOOT
 *          |
 *      payload run
 *
 * Brief description of states:
 *   BS_PRE_DEVICE - before any device tree actions take place
 *   BS_DEV_INIT_CHIPS - init all chips in device tree
 *   BS_DEV_ENUMERATE - device tree probing
 *   BS_DEV_RESOURCES - device tree resource allocation and assignment
 *   BS_DEV_ENABLE - device tree enabling/disabling of devices
 *   BS_DEV_INIT - device tree device initialization
 *   BS_POST_DEVICE - all device tree actions performed
 *   BS_OS_RESUME_CHECK - check for OS resume
 *   BS_OS_RESUME - resume to OS
 *   BS_WRITE_TABLES - write coreboot tables
 *   BS_PAYLOAD_LOAD - Load payload into memory
 *   BS_PAYLOAD_BOOT - Boot to payload
 */

typedef enum {
	BS_PRE_DEVICE,
	BS_DEV_INIT_CHIPS,
	BS_DEV_ENUMERATE,
	BS_DEV_RESOURCES,
	BS_DEV_ENABLE,
	BS_DEV_INIT,
	BS_POST_DEVICE,
	BS_OS_RESUME_CHECK,
	BS_OS_RESUME,
	BS_WRITE_TABLES,
	BS_PAYLOAD_LOAD,
	BS_PAYLOAD_BOOT,
} boot_state_t;

/* The boot_state_sequence_t describes when a callback is to be made. It is
 * called either before a state is entered or when a state is exited. */
typedef enum {
	BS_ON_ENTRY,
	BS_ON_EXIT
} boot_state_sequence_t;

struct boot_state_callback {
	void *arg;
	void (*callback)(void *arg);
	/* For use internal to the boot state machine. */
	struct boot_state_callback *next;
#if IS_ENABLED(CONFIG_DEBUG_BOOT_STATE)
	const char *location;
#endif
};

#if IS_ENABLED(CONFIG_DEBUG_BOOT_STATE)
#define BOOT_STATE_CALLBACK_LOC __FILE__ ":" STRINGIFY(__LINE__)
#define BOOT_STATE_CALLBACK_INIT_DEBUG .location = BOOT_STATE_CALLBACK_LOC,
#define INIT_BOOT_STATE_CALLBACK_DEBUG(bscb_)			\
	do {							\
		bscb_->location = BOOT_STATE_CALLBACK_LOC;	\
	} while (0)
#else
#define BOOT_STATE_CALLBACK_INIT_DEBUG
#define INIT_BOOT_STATE_CALLBACK_DEBUG(bscb_)
#endif

#define BOOT_STATE_CALLBACK_INIT(func_, arg_)		\
	{						\
		.arg = arg_,				\
		.callback = func_,			\
		.next = NULL,				\
		BOOT_STATE_CALLBACK_INIT_DEBUG		\
	}

#define BOOT_STATE_CALLBACK(name_, func_, arg_)	\
	struct boot_state_callback name_ = BOOT_STATE_CALLBACK_INIT(func_, arg_)

/* Initialize an allocated boot_state_callback. */
#define INIT_BOOT_STATE_CALLBACK(bscb_, func_, arg_)	\
	do {						\
		INIT_BOOT_STATE_CALLBACK_DEBUG(bscb_)	\
		bscb_->callback = func_;		\
		bscb_->arg = arg_			\
	} while (0)

/* The following 2 functions schedule a callback to be called on entry/exit
 * to a given state. Note that there are no ordering guarantees between the
 * individual callbacks on a given state. 0 is returned on success < 0 on
 * error. */
int boot_state_sched_on_entry(struct boot_state_callback *bscb,
				boot_state_t state);
int boot_state_sched_on_exit(struct boot_state_callback *bscb,
				boot_state_t state);
/* Schedule an array of entries of size num. */
struct boot_state_init_entry;
void boot_state_sched_entries(struct boot_state_init_entry *entries,
				size_t num);

/* Block/Unblock the (state, seq) pair from transitioning. Returns 0 on
 * success < 0  when the phase of the (state,seq) has already ran. */
int boot_state_block(boot_state_t state, boot_state_sequence_t seq);
int boot_state_unblock(boot_state_t state, boot_state_sequence_t seq);
/* Block/Unblock current state phase from transitioning. */
void boot_state_current_block(void);
void boot_state_current_unblock(void);

/* In order to schedule boot state callbacks at compile-time specify the
 * entries in an array using the BOOT_STATE_INIT_ENTRIES and
 * BOOT_STATE_INIT_ENTRY macros below. */
struct boot_state_init_entry {
	boot_state_t state;
	boot_state_sequence_t when;
	struct boot_state_callback bscb;
};

#if ENV_RAMSTAGE
#define BOOT_STATE_INIT_ATTR  __attribute__((used, section(".bs_init")))
#else
#define BOOT_STATE_INIT_ATTR  __attribute__((unused))
#endif

#define BOOT_STATE_INIT_ENTRY(state_, when_, func_, arg_)		\
	static struct boot_state_init_entry func_ ##_## state_ ##_## when_ = \
	{								\
		.state = state_,					\
		.when = when_,						\
		.bscb = BOOT_STATE_CALLBACK_INIT(func_, arg_),		\
	};								\
	static struct boot_state_init_entry *				\
		bsie_ ## func_ ##_## state_ ##_## when_ BOOT_STATE_INIT_ATTR = \
		&func_ ##_## state_ ##_## when_;

/* Hook per arch when coreboot is exiting to payload or ACPI OS resume. It's
 * the very last thing done before the transition. */
void arch_bootstate_coreboot_exit(void);

#endif /* BOOTSTATE_H */
