#include <sys/times.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <errno.h>
#include <stdlib.h>
#include "libsys.h"
#include "regdef.h"
#include "xcpt.h"
#include "irq.h"

static fp_t g_irq_handler[MAX_NUM_IRQ] = {NULL};

int _irq_dispatch(struct xcptcontext * xcp)
{
	int i, ip;

	ip =  (xcp->cr >> 8) & 0xFF;

	for (i=0; i < MAX_NUM_IRQ; i++)
	{
		if (ip & 1)
			if (g_irq_handler[i])
				(g_irq_handler[i])();

		ip >>= 1;
	}

	return 0;
}

void interrupt_register(int irq_num, fp_t fp)
{
	if ((irq_num >= 0) && (irq_num < MAX_NUM_IRQ))
		g_irq_handler[irq_num] = fp;

}

void interrupt_enable(int irq_num)
{
	reg_t reg, im;

	if ((irq_num >= 0) && (irq_num < MAX_NUM_IRQ))
	{
		im = 1 << irq_num;
		reg = CP0_SR_read();
		reg |= (SR_MASK_IM & (im << 8));
		CP0_SR_write(reg);
	}

}

void interrupt_disable(int irq_num)
{
	reg_t reg, im;

	if ((irq_num >= 0) && (irq_num < MAX_NUM_IRQ))
	{
		im = 1 << irq_num;
		reg = CP0_SR_read();
		reg &= ~(SR_MASK_IM & (im << 8));
		CP0_SR_write(reg);
	}
}

void interrupt_set(int irq_num)
{
	reg_t reg, ip;

	if ((irq_num >= 0) && (irq_num < MAX_NUM_IRQ))
	{
		ip = 1 << irq_num;
		reg = CP0_CR_read();
		reg |= (CR_MASK_IP & (ip << 8));
		CP0_CR_write(reg);
	}
}

void interrupt_clr(int irq_num)
{
	reg_t reg, ip;

	if ((irq_num >= 0) && (irq_num < MAX_NUM_IRQ))
	{
		ip = 1 << irq_num;
		reg = CP0_CR_read();
		reg &= ~(CR_MASK_IP & (ip << 8));
		CP0_CR_write(reg);
	}
}


