/* SPDX-License-Identifier: GPL-2.0-only */

#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include <arch/cpu.h>
#include <bootstate.h>
#include <console/console.h>
#include <thread.h>
#include <timer.h>

static void idle_thread_init(void);

/* There needs to be at least one thread to run the ramstate state machine. */
#define TOTAL_NUM_THREADS (CONFIG_NUM_THREADS + 1)

/* Storage space for the thread structs .*/
static struct thread all_threads[TOTAL_NUM_THREADS];

/* All runnable (but not running) and free threads are kept on their
 * respective lists. */
static struct thread *runnable_threads;
static struct thread *free_threads;

static inline struct cpu_info *thread_cpu_info(const struct thread *t)
{
	return (void *)(t->stack_orig);
}

static inline int thread_can_yield(const struct thread *t)
{
	return (t != NULL && t->can_yield);
}

/* Assumes current CPU info can switch. */
static inline struct thread *cpu_info_to_thread(const struct cpu_info *ci)
{
	return ci->thread;
}

static inline struct thread *current_thread(void)
{
	return cpu_info_to_thread(cpu_info());
}

static inline int thread_list_empty(struct thread **list)
{
	return *list == NULL;
}

static inline struct thread *pop_thread(struct thread **list)
{
	struct thread *t;

	t = *list;
	*list = t->next;
	t->next = NULL;
	return t;
}

static inline void push_thread(struct thread **list, struct thread *t)
{
	t->next = *list;
	*list = t;
}

static inline void push_runnable(struct thread *t)
{
	push_thread(&runnable_threads, t);
}

static inline struct thread *pop_runnable(void)
{
	return pop_thread(&runnable_threads);
}

static inline struct thread *get_free_thread(void)
{
	struct thread *t;
	struct cpu_info *ci;
	struct cpu_info *new_ci;

	if (thread_list_empty(&free_threads))
		return NULL;

	t = pop_thread(&free_threads);

	ci = cpu_info();

	/* Initialize the cpu_info structure on the new stack. */
	new_ci = thread_cpu_info(t);
	*new_ci = *ci;
	new_ci->thread = t;

	/* Reset the current stack value to the original. */
	t->stack_current = t->stack_orig;

	return t;
}

static inline void free_thread(struct thread *t)
{
	push_thread(&free_threads, t);
}

/* The idle thread is ran whenever there isn't anything else that is runnable.
 * It's sole responsibility is to ensure progress is made by running the timer
 * callbacks. */
static void idle_thread(void *unused)
{
	/* This thread never voluntarily yields. */
	thread_prevent_coop();
	while (1)
		timers_run();
}

static void schedule(struct thread *t)
{
	struct thread *current = current_thread();

	/* If t is NULL need to find new runnable thread. */
	if (t == NULL) {
		if (thread_list_empty(&runnable_threads))
			die("Runnable thread list is empty!\n");
		t = pop_runnable();
	} else {
		/* current is still runnable. */
		push_runnable(current);
	}
	switch_to_thread(t->stack_current, &current->stack_current);
}

static void terminate_thread(struct thread *t)
{
	free_thread(t);
	schedule(NULL);
}

static void asmlinkage call_wrapper(void *unused)
{
	struct thread *current = current_thread();

	current->entry(current->entry_arg);
	terminate_thread(current);
}

/* Block the current state transitions until thread is complete. */
static void asmlinkage call_wrapper_block_current(void *unused)
{
	struct thread *current = current_thread();

	boot_state_current_block();
	current->entry(current->entry_arg);
	boot_state_current_unblock();
	terminate_thread(current);
}

struct block_boot_state {
	boot_state_t state;
	boot_state_sequence_t seq;
};

/* Block the provided state until thread is complete. */
static void asmlinkage call_wrapper_block_state(void *arg)
{
	struct block_boot_state *bbs = arg;
	struct thread *current = current_thread();

	boot_state_block(bbs->state, bbs->seq);
	current->entry(current->entry_arg);
	boot_state_unblock(bbs->state, bbs->seq);
	terminate_thread(current);
}

/* Prepare a thread so that it starts by executing thread_entry(thread_arg).
 * Within thread_entry() it will call func(arg). */
static void prepare_thread(struct thread *t, void *func, void *arg,
			   asmlinkage void (*thread_entry)(void *),
			   void *thread_arg)
{
	/* Stash the function and argument to run. */
	t->entry = func;
	t->entry_arg = arg;

	/* All new threads can yield by default. */
	t->can_yield = 1;

	arch_prepare_thread(t, thread_entry, thread_arg);
}

static void thread_resume_from_timeout(struct timeout_callback *tocb)
{
	struct thread *to;

	to = tocb->priv;
	schedule(to);
}

static void idle_thread_init(void)
{
	struct thread *t;

	t = get_free_thread();

	if (t == NULL)
		die("No threads available for idle thread!\n");

	/* Queue idle thread to run once all other threads have yielded. */
	prepare_thread(t, idle_thread, NULL, call_wrapper, NULL);
	push_runnable(t);
	/* Mark the currently executing thread to cooperate. */
	thread_cooperate();
}

/* Don't inline this function so the timeout_callback won't have its storage
 * space on the stack cleaned up before the call to schedule(). */
static int __attribute__((noinline))
thread_yield_timed_callback(struct timeout_callback *tocb,
	unsigned int microsecs)
{
	tocb->priv = current_thread();
	tocb->callback = thread_resume_from_timeout;

	if (timer_sched_callback(tocb, microsecs))
		return -1;

	/* The timer callback will wake up the current thread. */
	schedule(NULL);
	return 0;
}

static void *thread_alloc_space(struct thread *t, size_t bytes)
{
	/* Allocate the amount of space on the stack keeping the stack
	 * aligned to the pointer size. */
	t->stack_current -= ALIGN_UP(bytes, sizeof(uintptr_t));

	return (void *)t->stack_current;
}

void threads_initialize(void)
{
	int i;
	struct thread *t;
	u8 *stack_top;
	struct cpu_info *ci;
	u8 *thread_stacks;

	thread_stacks = arch_get_thread_stackbase();

	/* Initialize the BSP thread first. The cpu_info structure is assumed
	 * to be just under the top of the stack. */
	t = &all_threads[0];
	ci = cpu_info();
	ci->thread = t;
	t->stack_orig = (uintptr_t)ci;
	t->id = 0;

	stack_top = &thread_stacks[CONFIG_STACK_SIZE] - sizeof(struct cpu_info);
	for (i = 1; i < TOTAL_NUM_THREADS; i++) {
		t = &all_threads[i];
		t->stack_orig = (uintptr_t)stack_top;
		t->id = i;
		stack_top += CONFIG_STACK_SIZE;
		free_thread(t);
	}

	idle_thread_init();
}

int thread_run(void (*func)(void *), void *arg)
{
	struct thread *current;
	struct thread *t;

	current = current_thread();

	if (!thread_can_yield(current)) {
		printk(BIOS_ERR,
		       "thread_run() called from non-yielding context!\n");
		return -1;
	}

	t = get_free_thread();

	if (t == NULL) {
		printk(BIOS_ERR, "thread_run() No more threads!\n");
		return -1;
	}

	prepare_thread(t, func, arg, call_wrapper_block_current, NULL);
	schedule(t);

	return 0;
}

int thread_run_until(void (*func)(void *), void *arg,
		     boot_state_t state, boot_state_sequence_t seq)
{
	struct thread *current;
	struct thread *t;
	struct block_boot_state *bbs;

	current = current_thread();

	if (!thread_can_yield(current)) {
		printk(BIOS_ERR,
		       "thread_run() called from non-yielding context!\n");
		return -1;
	}

	t = get_free_thread();

	if (t == NULL) {
		printk(BIOS_ERR, "thread_run() No more threads!\n");
		return -1;
	}

	bbs = thread_alloc_space(t, sizeof(*bbs));
	bbs->state = state;
	bbs->seq = seq;
	prepare_thread(t, func, arg, call_wrapper_block_state, bbs);
	schedule(t);

	return 0;
}

int thread_yield_microseconds(unsigned int microsecs)
{
	struct thread *current;
	struct timeout_callback tocb;

	current = current_thread();

	if (!thread_can_yield(current))
		return -1;

	if (thread_yield_timed_callback(&tocb, microsecs))
		return -1;

	return 0;
}

void thread_cooperate(void)
{
	struct thread *current;

	current = current_thread();

	if (current != NULL)
		current->can_yield = 1;
}

void thread_prevent_coop(void)
{
	struct thread *current;

	current = current_thread();

	if (current != NULL)
		current->can_yield = 0;
}
