/* See COPYRIGHT for copyright information. */

#include <ros/common.h>
#include <ros/ring_syscall.h>
#include <arch/types.h>
#include <arch/arch.h>
#include <arch/mmu.h>
#include <error.h>

#include <syscall.h>
#include <kmalloc.h>
#include <pmap.h>
#include <stdio.h>
#include <hashtable.h>
#include <smp.h>
#include <arsc_server.h>
#include <kref.h>



struct proc_list arsc_proc_list = TAILQ_HEAD_INITIALIZER(arsc_proc_list);
spinlock_t arsc_proc_lock = SPINLOCK_INITIALIZER_IRQSAVE;

intreg_t inline syscall_async(struct proc *p, syscall_req_t *call)
{
	struct syscall* sc = call->sc;
	return syscall(p, sc->num, sc->arg0, sc->arg1,
	               sc->arg2, sc->arg3, sc->arg4, sc->arg5);
}

syscall_sring_t* sys_init_arsc(struct proc *p)
{
	kref_get(&p->p_kref, 1);		/* we're storing an external ref here */
	syscall_sring_t* sring;
	void * va;
	// TODO: need to pin this page in the future when swapping happens
	va = do_mmap(p,MMAP_LOWEST_VA, SYSCALLRINGSIZE, PROT_READ | PROT_WRITE,
	             MAP_ANONYMOUS | MAP_POPULATE | MAP_PRIVATE, NULL, 0);
	pte_t pte = pgdir_walk(p->env_pgdir, (void*)va, 0);
	assert(pte_walk_okay(pte));
	sring = (syscall_sring_t*) KADDR(pte_get_paddr(pte));
	/*make sure we are able to allocate the shared ring */
	assert(sring != NULL);
 	p->procdata->syscallring = sring;
	/* Initialize the generic syscall ring buffer */
	SHARED_RING_INIT(sring);

	BACK_RING_INIT(&p->syscallbackring,
	               sring,
	               SYSCALLRINGSIZE);

	spin_lock_irqsave(&arsc_proc_lock);
	TAILQ_INSERT_TAIL(&arsc_proc_list, p, proc_arsc_link);
	spin_unlock_irqsave(&arsc_proc_lock);
	return (syscall_sring_t*)va;
}

void arsc_server(uint32_t srcid, long a0, long a1, long a2)
{
	struct proc *p = NULL;
	TAILQ_INIT(&arsc_proc_list);
	while (1) {
		while (TAILQ_EMPTY(&arsc_proc_list))
			cpu_relax();

		TAILQ_FOREACH(p, &arsc_proc_list, proc_arsc_link) {
			/* Probably want to try to process a dying process's syscalls.  If
			 * not, just move it to an else case */
			process_generic_syscalls (p, MAX_ASRC_BATCH);
			if (proc_is_dying(p)) {
				TAILQ_REMOVE(&arsc_proc_list, p, proc_arsc_link);
				proc_decref(p);
				/* Need to break out, so the TAILQ_FOREACH doesn't flip out.
				 * It's not fair, but we're not dealing with that yet anyway */
				break;
			}
		}
	}
}

static intreg_t process_generic_syscalls(struct proc *p, size_t max)
{
	size_t count = 0;
	syscall_back_ring_t* sysbr = &p->syscallbackring;
	struct per_cpu_info* pcpui = &per_cpu_info[core_id()];
	uintptr_t old_proc;
	// looking at a process not initialized to perform arsc.
	if (sysbr == NULL)
		return count;
	/* Bail out if there is nothing to do */
	if (!RING_HAS_UNCONSUMED_REQUESTS(sysbr))
		return 0;
	/* Switch to the address space of the process, so we can handle their
	 * pointers, etc. */
	old_proc = switch_to(p);
	// max is the most we'll process.  max = 0 means do as many as possible
	// TODO: check for initialization of the ring.
	while (RING_HAS_UNCONSUMED_REQUESTS(sysbr) && ((!max)||(count < max)) ) {
		// ASSUME: one queue per process
		count++;
		//printk("DEBUG PRE: sring->req_prod: %d, sring->rsp_prod: %d\n",
		//	   sysbr->sring->req_prod, sysbr->sring->rsp_prod);
		// might want to think about 0-ing this out, if we aren't
		// going to explicitly fill in all fields
		syscall_rsp_t rsp;
		// this assumes we get our answer immediately for the syscall.
		syscall_req_t* req = RING_GET_REQUEST(sysbr, ++sysbr->req_cons);

		pcpui->cur_kthread->sysc = req->sc;
		run_local_syscall(req->sc); // TODO: blocking call will block arcs as well.

		// need to keep the slot in the ring buffer if it is blocked
		(sysbr->rsp_prod_pvt)++;
		req->status = RES_ready;
		RING_PUSH_RESPONSES(sysbr);

		//printk("DEBUG POST: sring->req_prod: %d, sring->rsp_prod: %d\n",
		//	   sysbr->sring->req_prod, sysbr->sring->rsp_prod);
	}
	/* switch back to whatever context we were in before */
	switch_back(p, old_proc);
	return (intreg_t)count;
}

