/* See COPYRIGHT for copyright information. */

#ifdef __SHARC__
#pragma nosharc
#endif


#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);
	sring = (syscall_sring_t*) (ppn2kva(PTE2PPN(*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 (p->state == PROC_DYING) {
				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()];
	struct proc *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;
}

