/*
 *	linux/arch/cris/kernel/irq.c
 *
 *      Copyright (c) 2000-2002 Axis Communications AB
 *
 *      Authors: Bjorn Wesen (bjornw@axis.com)
 *
 *      This file contains the interrupt vectors and some
 *      helper functions
 *
 */

#include <asm/irq.h>
#include <asm/current.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/init.h>

#define crisv10_mask_irq(irq_nr) (*R_VECT_MASK_CLR = 1 << (irq_nr));
#define crisv10_unmask_irq(irq_nr) (*R_VECT_MASK_SET = 1 << (irq_nr));

extern void kgdb_init(void);
extern void breakpoint(void);

/* don't use set_int_vector, it bypasses the linux interrupt handlers. it is
 * global just so that the kernel gdb can use it.
 */

void
set_int_vector(int n, irqvectptr addr)
{
	etrax_irv->v[n + 0x20] = (irqvectptr)addr;
}

/* the breakpoint vector is obviously not made just like the normal irq handlers
 * but needs to contain _code_ to jump to addr.
 *
 * the BREAK n instruction jumps to IBR + n * 8
 */

void
set_break_vector(int n, irqvectptr addr)
{
	unsigned short *jinstr = (unsigned short *)&etrax_irv->v[n*2];
	unsigned long *jaddr = (unsigned long *)(jinstr + 1);

	/* if you don't know what this does, do not touch it! */
	
	*jinstr = 0x0d3f;
	*jaddr = (unsigned long)addr;

	/* 00000026 <clrlop+1a> 3f0d82000000     jump  0x82 */
}

/*
 * This builds up the IRQ handler stubs using some ugly macros in irq.h
 *
 * These macros create the low-level assembly IRQ routines that do all
 * the operations that are needed. They are also written to be fast - and to
 * disable interrupts as little as humanly possible.
 *
 */

/* IRQ0 and 1 are special traps */
void hwbreakpoint(void);
void IRQ1_interrupt(void);
BUILD_TIMER_IRQ(2, 0x04)       /* the timer interrupt is somewhat special */
BUILD_IRQ(3, 0x08)
BUILD_IRQ(4, 0x10)
BUILD_IRQ(5, 0x20)
BUILD_IRQ(6, 0x40)
BUILD_IRQ(7, 0x80)
BUILD_IRQ(8, 0x100)
BUILD_IRQ(9, 0x200)
BUILD_IRQ(10, 0x400)
BUILD_IRQ(11, 0x800)
BUILD_IRQ(12, 0x1000)
BUILD_IRQ(13, 0x2000)
void mmu_bus_fault(void);      /* IRQ 14 is the bus fault interrupt */
void multiple_interrupt(void); /* IRQ 15 is the multiple IRQ interrupt */
BUILD_IRQ(16, 0x10000 | 0x20000)  /* ethernet tx interrupt needs to block rx */
BUILD_IRQ(17, 0x20000 | 0x10000)  /* ...and vice versa */
BUILD_IRQ(18, 0x40000)
BUILD_IRQ(19, 0x80000)
BUILD_IRQ(20, 0x100000)
BUILD_IRQ(21, 0x200000)
BUILD_IRQ(22, 0x400000)
BUILD_IRQ(23, 0x800000)
BUILD_IRQ(24, 0x1000000)
BUILD_IRQ(25, 0x2000000)
/* IRQ 26-30 are reserved */
BUILD_IRQ(31, 0x80000000)
 
/*
 * Pointers to the low-level handlers 
 */

static void (*interrupt[NR_IRQS])(void) = {
	NULL, NULL, IRQ2_interrupt, IRQ3_interrupt,
	IRQ4_interrupt, IRQ5_interrupt, IRQ6_interrupt, IRQ7_interrupt,
	IRQ8_interrupt, IRQ9_interrupt, IRQ10_interrupt, IRQ11_interrupt,
	IRQ12_interrupt, IRQ13_interrupt, NULL, NULL,	
	IRQ16_interrupt, IRQ17_interrupt, IRQ18_interrupt, IRQ19_interrupt,	
	IRQ20_interrupt, IRQ21_interrupt, IRQ22_interrupt, IRQ23_interrupt,	
	IRQ24_interrupt, IRQ25_interrupt, NULL, NULL, NULL, NULL, NULL,
	IRQ31_interrupt
};

static void enable_crisv10_irq(struct irq_data *data)
{
	crisv10_unmask_irq(data->irq);
}

static void disable_crisv10_irq(struct irq_data *data)
{
	crisv10_mask_irq(data->irq);
}

static struct irq_chip crisv10_irq_type = {
	.name		= "CRISv10",
	.irq_shutdown	= disable_crisv10_irq,
	.irq_enable	= enable_crisv10_irq,
	.irq_disable	= disable_crisv10_irq,
};

void weird_irq(void);
void system_call(void);  /* from entry.S */
void do_sigtrap(void); /* from entry.S */
void gdb_handle_breakpoint(void); /* from entry.S */

extern void do_IRQ(int irq, struct pt_regs * regs);

/* Handle multiple IRQs */
void do_multiple_IRQ(struct pt_regs* regs)
{
	int bit;
	unsigned masked;
	unsigned mask;
	unsigned ethmask = 0;

	/* Get interrupts to mask and handle */
	mask = masked = *R_VECT_MASK_RD;

	/* Never mask timer IRQ */
	mask &= ~(IO_MASK(R_VECT_MASK_RD, timer0));

	/*
	 * If either ethernet interrupt (rx or tx) is active then block
	 * the other one too. Unblock afterwards also.
	 */
	if (mask &
	    (IO_STATE(R_VECT_MASK_RD, dma0, active) |
	     IO_STATE(R_VECT_MASK_RD, dma1, active))) {
		ethmask = (IO_MASK(R_VECT_MASK_RD, dma0) |
			   IO_MASK(R_VECT_MASK_RD, dma1));
	}

	/* Block them */
	*R_VECT_MASK_CLR = (mask | ethmask);

	/* An extra irq_enter here to prevent softIRQs to run after
	 * each do_IRQ. This will decrease the interrupt latency.
	 */
	irq_enter();

	/* Handle all IRQs */
	for (bit = 2; bit < 32; bit++) {
		if (masked & (1 << bit)) {
			do_IRQ(bit, regs);
		}
	}

	/* This irq_exit() will trigger the soft IRQs. */
	irq_exit();

	/* Unblock the IRQs again */
	*R_VECT_MASK_SET = (masked | ethmask);
}

/* init_IRQ() is called by start_kernel and is responsible for fixing IRQ masks and
   setting the irq vector table.
*/

void __init init_IRQ(void)
{
	int i;

	/* clear all interrupt masks */
	*R_IRQ_MASK0_CLR = 0xffffffff;
	*R_IRQ_MASK1_CLR = 0xffffffff;
	*R_IRQ_MASK2_CLR = 0xffffffff;
	*R_VECT_MASK_CLR = 0xffffffff;

        for (i = 0; i < 256; i++)
               etrax_irv->v[i] = weird_irq;

	/* Initialize IRQ handler descriptors. */
	for(i = 2; i < NR_IRQS; i++) {
		irq_set_chip_and_handler(i, &crisv10_irq_type,
					 handle_simple_irq);
		set_int_vector(i, interrupt[i]);
	}

        /* the entries in the break vector contain actual code to be
           executed by the associated break handler, rather than just a jump
           address. therefore we need to setup a default breakpoint handler
           for all breakpoints */
	for (i = 0; i < 16; i++)
                set_break_vector(i, do_sigtrap);

	/* except IRQ 15 which is the multiple-IRQ handler on Etrax100 */
	set_int_vector(15, multiple_interrupt);

	/* 0 and 1 which are special breakpoint/NMI traps */
	set_int_vector(0, hwbreakpoint);
	set_int_vector(1, IRQ1_interrupt);

	/* and irq 14 which is the mmu bus fault handler */
	set_int_vector(14, mmu_bus_fault);

	/* setup the system-call trap, which is reached by BREAK 13 */
	set_break_vector(13, system_call);

        /* setup a breakpoint handler for debugging used for both user and
           kernel mode debugging  (which is why it is not inside an ifdef
           CONFIG_ETRAX_KGDB) */
        set_break_vector(8, gdb_handle_breakpoint);

#ifdef CONFIG_ETRAX_KGDB
	/* setup kgdb if its enabled, and break into the debugger */
	kgdb_init();
	breakpoint();
#endif
}
