/* Copyright (c) 2015 Google, Inc.
 * Barret Rhoden <brho@cs.berkeley.edu>
 * See LICENSE for details.
 *
 * thread0_sched: a basic scheduler for thread0, used by SCPs without a
 * multithreaded 2LS linked in.
 *
 * This is closely coupled with uthread.c */

#include <ros/arch/membar.h>
#include <parlib/arch/atomic.h>
#include <parlib/parlib.h>
#include <parlib/vcore.h>
#include <parlib/uthread.h>
#include <parlib/event.h>
#include <parlib/arch/trap.h>
#include <parlib/ros_debug.h>
#include <stdlib.h>

static void thread0_sched_init(void);
static void thread0_sched_entry(void);
static void thread0_thread_blockon_sysc(struct uthread *uthread, void *sysc);
static void thread0_thread_refl_fault(struct uthread *uth,
                                      struct user_context *ctx);
static void thread0_thread_runnable(struct uthread *uth);
static void thread0_thread_has_blocked(struct uthread *uth, int flags);
static void thread0_thread_exited(struct uthread *uth);
static struct uthread *thread0_thread_create(void *(*func)(void *), void *arg);
static void thread0_sync_init(uth_sync_t *s);
static void thread0_sync_destroy(uth_sync_t *s);
static void thread0_sync_enqueue(struct uthread *uth, uth_sync_t *s);
static struct uthread *thread0_sync_get_next(uth_sync_t *s);
static bool thread0_sync_get_uth(uth_sync_t *s, struct uthread *uth);
static void thread0_sync_swap(uth_sync_t *a, uth_sync_t *b);
static bool thread0_sync_is_empty(uth_sync_t *s);

/* externed into uthread.c */
struct schedule_ops thread0_2ls_ops = {
	.sched_init = thread0_sched_init,
	.sched_entry = thread0_sched_entry,
	.thread_blockon_sysc = thread0_thread_blockon_sysc,
	.thread_refl_fault = thread0_thread_refl_fault,
	.thread_runnable = thread0_thread_runnable,
	.thread_paused = thread0_thread_runnable,
	.thread_has_blocked = thread0_thread_has_blocked,
	.thread_exited = thread0_thread_exited,
	.thread_create = thread0_thread_create,
	.sync_init = thread0_sync_init,
	.sync_destroy = thread0_sync_destroy,
	.sync_enqueue = thread0_sync_enqueue,
	.sync_get_next = thread0_sync_get_next,
	.sync_get_uth = thread0_sync_get_uth,
	.sync_swap = thread0_sync_swap,
	.sync_is_empty = thread0_sync_is_empty,
};

struct schedule_ops *sched_ops __attribute__((weak)) = &thread0_2ls_ops;

/* externed into uthread.c */
struct uthread *thread0_uth;

/* Our thread0 is actually allocated in uthread as just a struct uthread, so we
 * don't actually attach this mgmt info to it.  But since we just have one
 * thread, it doesn't matter. */
struct thread0_info {
	bool						is_blocked;
};
static struct thread0_info thread0_info;
static struct event_queue *sysc_evq;

void thread0_handle_syscall(struct event_msg *ev_msg,
                            unsigned int ev_type, void *data)
{
	thread0_info.is_blocked = FALSE;
}

void thread0_sched_init(void)
{
	int ret;

	ret = posix_memalign((void**)&thread0_uth, __alignof__(struct uthread),
	                     sizeof(struct uthread));
	assert(!ret);
	memset(thread0_uth, 0, sizeof(struct uthread));	/* aggressively 0 for bugs*/
	memset(&thread0_info, 0, sizeof(thread0_info));
	/* we don't care about the message, so don't bother with a UCQ */
	sysc_evq = get_eventq(EV_MBOX_BITMAP);
	sysc_evq->ev_flags = EVENT_INDIR | EVENT_WAKEUP;
	uthread_2ls_init(thread0_uth, thread0_handle_syscall, NULL);
}

/* Thread0 scheduler ops (for processes that haven't linked in a full 2LS) */
static void thread0_sched_entry(void)
{
	/* TODO: support signal handling whenever we run a uthread */
	if (current_uthread) {
		uthread_prep_pending_signals(current_uthread);
		run_current_uthread();
		assert(0);
	}
	while (1) {
		if (!thread0_info.is_blocked) {
			uthread_prep_pending_signals(thread0_uth);
			run_uthread(thread0_uth);
			assert(0);
		}
		sys_yield(FALSE);
		handle_events(0);
	}
}

static void thread0_thread_blockon_sysc(struct uthread *uthread, void *arg)
{
	struct syscall *sysc = (struct syscall*)arg;
	thread0_thread_has_blocked(uthread, 0);
	if (!register_evq(sysc, sysc_evq))
		thread0_thread_runnable(uthread);
}

static void refl_error(struct uthread *uth, unsigned int trap_nr,
                       unsigned int err, unsigned long aux)
{
	printf("Thread has unhandled fault: %d, err: %d, aux: %p\n",
	       trap_nr, err, aux);
	/* Note that uthread.c already copied out our ctx into the uth
	 * struct */
	print_user_context(&uth->u_ctx);
	printf("Turn on printx to spew unhandled, malignant trap info\n");
	exit(-1);
}

static bool handle_page_fault(struct uthread *uth, unsigned int err,
                              unsigned long aux)
{
	if (!(err & PF_VMR_BACKED))
		return FALSE;
	syscall_async(&uth->local_sysc, SYS_populate_va, aux, 1);
	__block_uthread_on_async_sysc(uth);
	return TRUE;
}

static void thread0_thread_refl_fault(struct uthread *uth,
                                      struct user_context *ctx)
{
	unsigned int trap_nr = __arch_refl_get_nr(ctx);
	unsigned int err = __arch_refl_get_err(ctx);
	unsigned long aux = __arch_refl_get_aux(ctx);

	assert(ctx->type == ROS_HW_CTX);
	switch (trap_nr) {
	case HW_TRAP_PAGE_FAULT:
		if (!handle_page_fault(uth, err, aux))
			refl_error(uth, trap_nr, err, aux);
		break;
	default:
		refl_error(uth, trap_nr, err, aux);
	}
}

static void thread0_thread_runnable(struct uthread *uth)
{
	thread0_info.is_blocked = FALSE;
}

static void thread0_thread_has_blocked(struct uthread *uth, int flags)
{
	assert(!thread0_info.is_blocked);
	thread0_info.is_blocked = TRUE;
}

/* Actually, a 2LS only needs to implement this if it calls
 * uth_2ls_thread_exit().  Keep it here to catch bugs. */
static void thread0_thread_exited(struct uthread *uth)
{
	assert(0);
}

static struct uthread *thread0_thread_create(void *(*func)(void *), void *arg)
{
	panic("Thread0 sched asked to create more threads!");
}

static void thread0_sync_init(uth_sync_t *s)
{
	memset(s, 0x5a, sizeof(uth_sync_t));
}

static void thread0_sync_destroy(uth_sync_t *s)
{
}

static void thread0_sync_enqueue(struct uthread *uth, uth_sync_t *s)
{
}

static struct uthread *thread0_sync_get_next(uth_sync_t *s)
{
	if (thread0_info.is_blocked) {
		/* Note we don't clear is_blocked.  Runnable does that, which should be
		 * called before the next get_next (since we have only one thread). */
		return thread0_uth;
	} else {
		return NULL;
	}
}

static bool thread0_sync_get_uth(uth_sync_t *s, struct uthread *uth)
{
	assert(uth == thread0_uth);
	if (thread0_info.is_blocked) {
		/* Note we don't clear is_blocked.  Runnable does that. */
		return TRUE;
	}
	return FALSE;
}

static void thread0_sync_swap(uth_sync_t *a, uth_sync_t *b)
{
}

static bool thread0_sync_is_empty(uth_sync_t *s)
{
	return !thread0_info.is_blocked;
}
