/*
 * 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 = *pDCPLB_FAULT_ADDR;
		} else {
			addr = *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);
	}

trap_c_return:
	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);

}
