/******************************************************************************

  Copyright (C), 2001-2012, Texas Instrument.

 ******************************************************************************
  File Name     : Robust_INTC.c
  Version       : Initial Draft
  Author        : Brighton Feng
  Created       : 2012/10/7
  Last Modified :
  Description   : This file setup interrupt controller, and includes:
                  1, ISR for memory protection and EDC/ECC.
                  2, function to manually tigger two interrupts to show
                  the interrup drop monitor
  Function List :
              INT_drop_test
              LL2_EDC_ISR
              Robust_Interrupts_Init
              SL2_EDC_ISR
              Timer_ISR
  History       :
  1.Date        : 2012/10/7
    Author      : Brighton Feng
    Modification: Created file

******************************************************************************/
#include <stdio.h>
#include <c6x.h>
#include <tistdtypes.h>
#include <csl_cpintc.h>
#include "KeyStone_common.h"
#include "CSL_msmc.h"
#include "CSL_msmcAux.h"
#include <cslr_chip.h>

/*----------------------------------------------*
 * external variables                           *
 *----------------------------------------------*/
/*----------------------------------------------*
 * external routine prototypes                  *
 *----------------------------------------------*/

/*----------------------------------------------*
 * internal routine prototypes                  *
 *----------------------------------------------*/

/*----------------------------------------------*
 * project-wide global variables                *
 *----------------------------------------------*/
Uint32 gCIC_out_num = 0;

/*----------------------------------------------*
 * module-wide global variables                 *
 *----------------------------------------------*/

/*----------------------------------------------*
 * constants                                    *
 *----------------------------------------------*/

/*----------------------------------------------*
 * macros                                       *
 *----------------------------------------------*/

/*----------------------------------------------*
 * routines' implementations                    *
 *----------------------------------------------*/
/*****************************************************************************
 Prototype    : Robust_Interrupts_Init
 Description  : Interrupt initilization for robust system test
 Input        : void  
 Output       : None
 Return Value : 
 
  History        :
  1.Date         : 2012/10/7
    Author       : Brighton Feng
    Modification : Created function

*****************************************************************************/
void Robust_Interrupts_Init(void)
{
	TDSP_Board_Type DSP_Board_Type= KeyStone_Get_dsp_board_type();

	if(C6670_EVM==DSP_Board_Type
		||DUAL_NYQUIST_EVM==DSP_Board_Type
		||TCI6614_EVM==DSP_Board_Type)
	{	
		gCIC_out_num= 64+10*DNUM;
	}
	else if(C6678_EVM==DSP_Board_Type)
	{	
		if(DNUM<4)
			gCIC_out_num= 33+11*DNUM;
		else
		{
			gCIC_out_num= 33+11*(DNUM-4);
			gpCIC_regs= gpCIC1_regs;
		}
	}
	else if(C6657_EVM==DSP_Board_Type)
	{
		gCIC_out_num= 0+20*DNUM;
	}
	else
	{
		puts("Unknown DSP board type!");
		return;
	}	
    
	/*-----------------------CP_INTC configuration---------------------*/
	/* Disable Global host interrupts. */
	gpCIC_regs->GLOBAL_ENABLE_HINT_REG= 0;

	/* route following system events to CIC out (event 22 of INTC), and then to Core interrupt
	CIC: 87 MSMC_scrub_cerror Correctable (1-bit) soft error detected during scrub cycle
	CIC: 98 MSMC_dedc_cerror Correctable (1-bit) soft error detected on SRAM read
	*/
	KeyStone_CIC_event_map(gpCIC_regs, 87, gCIC_out_num);
	KeyStone_CIC_event_map(gpCIC_regs, 98, gCIC_out_num);

	/* Enable Global host interrupts. */
	gpCIC_regs->GLOBAL_ENABLE_HINT_REG= 1;

	/*-----------------------Core INTC configuration---------------------*/
	/*map LL2 correctable soft error to DSP core interrupt 4,
	map MSMC correctable soft error (from CIC) to DSP core interrupt 5*/
	gpCGEM_regs->INTMUX1 = 
		(CSL_GEM_UMC_ED1<<CSL_CGEM_INTMUX1_INTSEL4_SHIFT)|
		(22<<CSL_CGEM_INTMUX1_INTSEL5_SHIFT);

	//map timer 4 on Appleton/Nyquist or timer 8 on Shannon interrupt to INT14, timer 2 on Gauss
	gpCGEM_regs->INTMUX3 = 66<<CSL_CGEM_INTMUX3_INTSEL14_SHIFT;

	/* disable event combine */
	gpCGEM_regs->EVTMASK[0] = 0xffffffff;
	gpCGEM_regs->EVTMASK[1] = 0xffffffff;
	gpCGEM_regs->EVTMASK[2] = 0xffffffff;
	gpCGEM_regs->EVTMASK[3] = 0xffffffff;

	 /*Clear all DSP core events*/
	gpCGEM_regs->EVTCLR[0]= 	0xFFFFFFFF;
	gpCGEM_regs->EVTCLR[1]= 	0xFFFFFFFF;
	gpCGEM_regs->EVTCLR[2]= 	0xFFFFFFFF;
	gpCGEM_regs->EVTCLR[3]= 	0xFFFFFFFF;

	//clear DSP core interrupt flag
	ICR= IFR;

	//enable interrupts
	IER |= (1<<4)|(1<<5)|(1<<14);
	gpCGEM_regs->INTDMASK= ~IER; /*only monitor drop of enabled interrupts*/

	/*Interrupt Service Table Pointer to begining of LL2 memory*/
	ISTP= 0x800000;

	//enable GIE
	TSR |= 1;

}

/*****************************************************************************
 Prototype    : INT_drop_test
 Description  : Interrupt dorp test 
 Input        : None
 Output       : None
 Return Value : 
 
  History        :
  1.Date         : 2012/10/29
    Author       : Brighton Feng
    Modification : Created function

*****************************************************************************/
void INT_drop_test()
{
	unsigned int uiOldGIE;
	Timer64_Config tmrCfg;
	TDSP_Board_Type DSP_Board_Type= KeyStone_Get_dsp_board_type();

	puts("===================-interrupt drop test-=========================");

	//disable global interrupt to block interrupt response
	uiOldGIE= _disable_interrupts(); 	

	puts("!!!Quickly generate multiple timer interrupts (#14) before the DSP core can response...");

	if(C6678_EVM == DSP_Board_Type)
		tmrCfg.timer_num= 8;
	else if(C6657_EVM == DSP_Board_Type)
		tmrCfg.timer_num= 2;
	else
		tmrCfg.timer_num= 4;
	tmrCfg.timerMode= TIMER_PERIODIC_PULSE;

	/*set the timer period to be very short*/
	/*timer period is in the unit of DSP core clock/6*/	
	tmrCfg.period= 100; 	
	tmrCfg.pulseWidth= 3;
	Timer64_Init(&tmrCfg);

	TSC_delay_ms(10);

	_restore_interrupts(uiOldGIE); 	//restore global interrupt
}

/*****************************************************************************
 Prototype    : Timer_ISR
 Description  : Interrupt service routine for timer
 Input        : void  
 Output       : None
 Return Value : interrupt
 
  History        :
  1.Date         : 2012/10/29
    Author       : Brighton Feng
    Modification : Created function

*****************************************************************************/
interrupt void Timer_ISR(void)
{
	/*scrub 1024 bytes in LL2 for EDC*/
	LL2_EDC_scrub(1024);
}


/*****************************************************************************
 Prototype    : LL2_EDC_ISR
 Description  : LL2 correctable EDC interrupt
 Input        : None
 Output       : None
 Return Value : void
 
  History        :
  1.Date         : 2012/10/29
    Author       : Brighton Feng
    Modification : Created function

*****************************************************************************/
interrupt void LL2_EDC_ISR()
{
	unsigned int tscl, tsch, irp, itsr;

	/*record timestamp*/
	tscl = TSCL;
	tsch = TSCH;
	irp = IRP;
	itsr= ITSR;

	LL2_EDC_handler(TRUE);

	printf("IRP= 0x%x, ITSR= 0x%x. TSCH= 0x%x, TSCL= 0x%x\n",
		irp, itsr, tsch, tscl);
}

/*****************************************************************************
 Prototype    : SL2_EDC_ISR
 Description  : SL2 correctable EDC interrupt
 Input        : None
 Output       : None
 Return Value : interrupt
 
  History        :
  1.Date         : 2012/10/29
    Author       : Brighton Feng
    Modification : Created function

*****************************************************************************/
interrupt void SL2_EDC_ISR()
{
	unsigned int tscl, tsch, irp, itsr;
	unsigned int status2, status3;

	/*record timestamp*/
	tscl = TSCL;
	tsch = TSCH;
	irp = IRP;
	itsr= ITSR;

	/* processing folloiwng events from CIC
	CIC: 87 MSMC_scrub_cerror Correctable (1-bit) soft error detected during scrub cycle
	CIC: 98 MSMC_dedc_cerror Correctable (1-bit) soft error detected on SRAM read
 	*/
    /*Step1: Disable CIC host interrupt*/
    KeyStone_CIC_disable_host_int(gpCIC_regs, gCIC_out_num);

	/*Step2: clear system events*/
	status2= gpCIC_regs->ENA_STATUS_REG[2]&(1<<(87-64));
	status3= gpCIC_regs->ENA_STATUS_REG[3]&(1<<(98-96));
	gpCIC_regs->ENA_STATUS_REG[2]= status2;
	gpCIC_regs->ENA_STATUS_REG[3]= status3;

	if(status2|status3)
	{
		KeyStone_SL2_EDC_handler();
	}
	else
		puts("Enter SL2 EDC ISR, but no interrupt flag was set!");
		
	printf("IRP= 0x%x, ITSR= 0x%x. TSCH= 0x%x, TSCL= 0x%x\n",
		irp, itsr, tsch, tscl);

    /*Step3: Enable the CIC host interrupt */
    KeyStone_CIC_enable_host_int(gpCIC_regs, gCIC_out_num);    

}

