/* 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, 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;
}

