/*
 * U-boot - traps.c Routines related to interrupts and exceptions
 *
 * Copyright (c) 2005-2007 Analog Devices Inc.
 *
 * This file is based on
 * No original Copyright holder listed,
 * Probabily original (C) Roman Zippel (assigned DJD, 1999)
 *
 * Copyright 2003 Metrowerks - for Blackfin
 * Copyright 2000-2001 Lineo, Inc. D. Jeff Dionne <jeff@lineo.ca>
 * Copyright 1999-2000 D. Jeff Dionne, <jeff@uclinux.org>
 *
 * (C) Copyright 2000-2004
 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 *
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
 * MA 02110-1301 USA
 */

#include <common.h>
#include <linux/types.h>
#include <asm/errno.h>
#include <asm/system.h>
#include <asm/traps.h>
#include "cpu.h"
#include <asm/cplb.h>
#include <asm/io.h>
#include <asm/mach-common/bits/core.h>
#include <asm/mach-common/bits/mpu.h>

void init_IRQ(void)
{
	blackfin_init_IRQ();
	return;
}

void process_int(unsigned long vec, struct pt_regs *fp)
{
	printf("interrupt\n");
	return;
}

extern unsigned int icplb_table[page_descriptor_table_size][2];
extern unsigned int dcplb_table[page_descriptor_table_size][2];

unsigned long last_cplb_fault_retx;

static unsigned int cplb_sizes[4] =
    { 1024, 4 * 1024, 1024 * 1024, 4 * 1024 * 1024 };

void trap_c(struct pt_regs *regs)
{
	unsigned int addr;
	unsigned long trapnr = (regs->seqstat) & EXCAUSE;
	unsigned int i, j, size, *I0, *I1;
	unsigned short data = 0;

	switch (trapnr) {
	/* 0x26 - Data CPLB Miss */
	case VEC_CPLB_M:

#if ANOMALY_05000261
		/*
		 * Work around an anomaly: if we see a new DCPLB fault,
		 * return without doing anything. Then,
		 * if we get the same fault again, handle it.
		 */
		addr = last_cplb_fault_retx;
		last_cplb_fault_retx = regs->retx;
		printf("this time, curr = 0x%08x last = 0x%08x\n",
		       addr, last_cplb_fault_retx);
		if (addr != last_cplb_fault_retx)
			goto trap_c_return;
#endif
		data = 1;

	case VEC_CPLB_I_M:

		if (data) {
			addr = *(unsigned int *)pDCPLB_FAULT_ADDR;
		} else {
			addr = *(unsigned int *)pICPLB_FAULT_ADDR;
		}
		for (i = 0; i < page_descriptor_table_size; i++) {
			if (data) {
				size = cplb_sizes[dcplb_table[i][1] >> 16];
				j = dcplb_table[i][0];
			} else {
				size = cplb_sizes[icplb_table[i][1] >> 16];
				j = icplb_table[i][0];
			}
			if ((j <= addr) && ((j + size) > addr)) {
				debug("found %i 0x%08x\n", i, j);
				break;
			}
		}
		if (i == page_descriptor_table_size) {
			printf("something is really wrong\n");
			do_reset(NULL, 0, 0, NULL);
		}

		/* Turn the cache off */
		if (data) {
			SSYNC();
			asm(" .align 8; ");
			*(unsigned int *)DMEM_CONTROL &=
			    ~(ACACHE_BCACHE | ENDCPLB | PORT_PREF0);
			SSYNC();
		} else {
			SSYNC();
			asm(" .align 8; ");
			*(unsigned int *)IMEM_CONTROL &= ~(IMC | ENICPLB);
			SSYNC();
		}

		if (data) {
			I0 = (unsigned int *)DCPLB_ADDR0;
			I1 = (unsigned int *)DCPLB_DATA0;
		} else {
			I0 = (unsigned int *)ICPLB_ADDR0;
			I1 = (unsigned int *)ICPLB_DATA0;
		}

		j = 0;
		while (*I1 & CPLB_LOCK) {
			debug("skipping %i %08p - %08x\n", j, I1, *I1);
			*I0++;
			*I1++;
			j++;
		}

		debug("remove %i 0x%08x  0x%08x\n", j, *I0, *I1);

		for (; j < 15; j++) {
			debug("replace %i 0x%08x  0x%08x\n", j, I0, I0 + 1);
			*I0++ = *(I0 + 1);
			*I1++ = *(I1 + 1);
		}

		if (data) {
			*I0 = dcplb_table[i][0];
			*I1 = dcplb_table[i][1];
			I0 = (unsigned int *)DCPLB_ADDR0;
			I1 = (unsigned int *)DCPLB_DATA0;
		} else {
			*I0 = icplb_table[i][0];
			*I1 = icplb_table[i][1];
			I0 = (unsigned int *)ICPLB_ADDR0;
			I1 = (unsigned int *)ICPLB_DATA0;
		}

		for (j = 0; j < 16; j++) {
			debug("%i 0x%08x  0x%08x\n", j, *I0++, *I1++);
		}

		/* Turn the cache back on */
		if (data) {
			j = *(unsigned int *)DMEM_CONTROL;
			SSYNC();
			asm(" .align 8; ");
			*(unsigned int *)DMEM_CONTROL =
			    ACACHE_BCACHE | ENDCPLB | PORT_PREF0 | j;
			SSYNC();
		} else {
			SSYNC();
			asm(" .align 8; ");
			*(unsigned int *)IMEM_CONTROL = IMC | ENICPLB;
			SSYNC();
		}

		break;
	default:
		/* All traps come here */
		printf("code=[0x%x], ", (unsigned int)(regs->seqstat & 0x3f));
		printf("stack frame=0x%x, ", (unsigned int)regs);
		printf("bad PC=0x%04x\n", (unsigned int)regs->pc);
		dump(regs);
		printf("\n\n");

		printf("Unhandled IRQ or exceptions!\n");
		printf("Please reset the board \n");
		do_reset(NULL, 0, 0, NULL);
	}

	return;

}

void dump(struct pt_regs *fp)
{
	debug("RETE:  %08lx  RETN: %08lx  RETX: %08lx  RETS: %08lx\n",
		 fp->rete, fp->retn, fp->retx, fp->rets);
	debug("IPEND: %04lx  SYSCFG: %04lx\n", fp->ipend, fp->syscfg);
	debug("SEQSTAT: %08lx    SP: %08lx\n", (long)fp->seqstat, (long)fp);
	debug("R0: %08lx    R1: %08lx    R2: %08lx    R3: %08lx\n",
		 fp->r0, fp->r1, fp->r2, fp->r3);
	debug("R4: %08lx    R5: %08lx    R6: %08lx    R7: %08lx\n",
		 fp->r4, fp->r5, fp->r6, fp->r7);
	debug("P0: %08lx    P1: %08lx    P2: %08lx    P3: %08lx\n",
		 fp->p0, fp->p1, fp->p2, fp->p3);
	debug("P4: %08lx    P5: %08lx    FP: %08lx\n",
		 fp->p4, fp->p5, fp->fp);
	debug("A0.w: %08lx    A0.x: %08lx    A1.w: %08lx    A1.x: %08lx\n",
		 fp->a0w, fp->a0x, fp->a1w, fp->a1x);

	debug("LB0: %08lx  LT0: %08lx  LC0: %08lx\n",
		 fp->lb0, fp->lt0, fp->lc0);
	debug("LB1: %08lx  LT1: %08lx  LC1: %08lx\n",
		 fp->lb1, fp->lt1, fp->lc1);
	debug("B0: %08lx  L0: %08lx  M0: %08lx  I0: %08lx\n",
		 fp->b0, fp->l0, fp->m0, fp->i0);
	debug("B1: %08lx  L1: %08lx  M1: %08lx  I1: %08lx\n",
		 fp->b1, fp->l1, fp->m1, fp->i1);
	debug("B2: %08lx  L2: %08lx  M2: %08lx  I2: %08lx\n",
		 fp->b2, fp->l2, fp->m2, fp->i2);
	debug("B3: %08lx  L3: %08lx  M3: %08lx  I3: %08lx\n",
		 fp->b3, fp->l3, fp->m3, fp->i3);

	debug("DCPLB_FAULT_ADDR=%p\n", *pDCPLB_FAULT_ADDR);
	debug("ICPLB_FAULT_ADDR=%p\n", *pICPLB_FAULT_ADDR);

}
