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

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

 ******************************************************************************
  File Name     : Robust_SL2_EDC.c
  Version       : Initial Draft
  Author        : Jane
  Created       : 2012/10/12
  Last Modified :
  Description   : SL2 EDC test example
  Function List :
              funcTest1_SL2
              funcTest2_SL2
              funcTest3_SL2
              SL2_EDC_test
              SL2_data_bit_ERR_test
              SL2_code_bit_ERR_test
  History       :
  1.Date        : 2012/10/12
    Author      : Jane
    Modification: Created file

  2.Date        : 2012/12/12
    Author      : Brighton Feng
    Modification: add tests for data error on both original SL2 space and
                  remapped SL2 space.
******************************************************************************/

#include <stdio.h>
#include "KeyStone_common.h"
#include  "CSL_msmc.h"
#include  "CSL_msmcAux.h"

/*----------------------------------------------*
 * external variables                           *
 *----------------------------------------------*/

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

/*----------------------------------------------*
 * internal routine prototypes                  *
 *----------------------------------------------*/
extern void SL2_data_bit_ERR_test(Uint8 *dataPtr);
extern void SL2_code_bit_ERR_test();
/*----------------------------------------------*
 * project-wide global variables                *
 *----------------------------------------------*/

/*----------------------------------------------*
 * module-wide global variables                 *
 *----------------------------------------------*/
#pragma DATA_SECTION (EDCTestData, "Sl2EDCData")
#pragma DATA_ALIGN(EDCTestData,4*1024) //align to MPAX segment bouandary
Uint8 EDCTestData[4*1024];
/*----------------------------------------------*
 * constants                                    *
 *----------------------------------------------*/

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

/*----------------------------------------------*
 * routines' implementations                    *
 *----------------------------------------------*/


/*****************************************************************************
 Prototype    : funcTest1_SL2
 Description  : Test funtion 1 for SL2
 Input        : void  
 Output       : None
 Return Value : 
 
  History        :
  1.Date         : 2012/10/13
    Author       : Jane
    Modification : Created function

*****************************************************************************/
#pragma CODE_SECTION (funcTest1_SL2, "Sl2EDCCode")
void funcTest1_SL2(void)
{
	//first fetch packet
	asm(" nop	2");
	asm(" nop	2");
	asm(" nop   2");
	asm(" nop	2");
	asm(" nop	2");
	asm(" nop	2");
	asm(" nop	2");
	asm(" nop	2");
	asm(" nop	2");
	asm(" nop	2");
	asm(" nop   2");
	asm(" nop	2");
	asm(" nop	2");
	asm(" nop	2");
	//second fetch packet
	asm(" nop   1");
	asm(" nop	2");
	asm(" nop	2");
	asm(" nop	2");
	asm(" nop	2");
	asm(" nop	2");
	asm(" nop   2");
	asm(" nop	2");
	asm(" nop	2");
	asm(" nop	2");
	asm(" nop	2");
	asm(" nop	2");
	return;
}

/*****************************************************************************
 Prototype    : funcTest2_SL2
 Description  : Test function 3 for SL2
 Input        : void  
 Output       : None
 Return Value : 
 
  History        :
  1.Date         : 2012/10/13
    Author       : Jane
    Modification : Created function

*****************************************************************************/
#pragma CODE_SECTION (funcTest2_SL2, "Sl2EDCCode")
void funcTest2_SL2(void)
{
	//first fetch packet
	asm(" nop	2");
	asm(" nop	2");
	asm(" nop   2");
	asm(" nop	2");
	asm(" nop	2");
	asm(" nop	2");
	asm(" nop	2");
	asm(" nop	2");
	asm(" nop	2");
	asm(" nop	2");
	asm(" nop   2");
	asm(" nop	2");
	asm(" nop	2");
	asm(" nop	2");
	//second fetch packet
	asm(" nop	2");
	asm(" nop	2");
	asm(" nop	2");
	asm(" nop	2");
	asm(" nop	2");
	asm(" nop	2");
	asm(" nop   2");
	asm(" nop	2");
	asm(" nop	2");
	asm(" nop	2");
	asm(" nop	2");
	asm(" nop	2");
	return;
}

/*****************************************************************************
 Prototype    : funcTest3_SL2
 Description  : Test function 2 for SL2
 Input        : void  
 Output       : None
 Return Value : 
 
  History        :
  1.Date         : 2012/10/13
    Author       : Jane
    Modification : Created function

*****************************************************************************/
#pragma CODE_SECTION (funcTest3_SL2, "Sl2EDCCode")
void funcTest3_SL2(void)
{
	//first fetch packet
	asm(" nop	2");
	asm(" nop	2");
	asm(" nop   2");
	asm(" nop	2");
	asm(" nop	2");
	asm(" nop	2");
	asm(" nop	2");
	asm(" nop	2");
	asm(" nop	2");
	asm(" nop	2");
	asm(" nop   2");
	asm(" nop	2");
	asm(" nop	2");
	asm(" nop	2");
	//second fetch packet
	asm(" nop   4");
	asm(" nop	2");
	asm(" nop	2");
	asm(" nop	2");
	asm(" nop	2");
	asm(" nop	2");
	asm(" nop   2");
	asm(" nop	2");
	asm(" nop	2");
	asm(" nop	2");
	asm(" nop	2");
	asm(" nop	2");
	return;
}

/*****************************************************************************
 Prototype    : SL2_EDC_test
 Description  : SL2 EDC test example
 Input        : None
 Output       : None
 Return Value : 
 
  History        :
  1.Date         : 2012/10/13
    Author       : Jane
    Modification : Created function

*****************************************************************************/
void SL2_EDC_test()
{

	puts("===================-SL2 EDC test-================================");
	CACHE_invAllL1p(CACHE_WAIT);
	CACHE_wbInvAllL1d(CACHE_WAIT);
	CACHE_wbInvAllL2(CACHE_WAIT);

	/* disable scrubbing engine for below test */
	CSL_MSMC_unlockNonMPAX();
	CSL_MSMC_disableScrubbingEngine();

	/*  Run application and simulate the 1bit error */
	SL2_code_bit_ERR_test();

	SL2_data_bit_ERR_test(EDCTestData);

	//remap SL2 for test
	if(gpCGEM_regs->MPLKSTAT&CSL_CGEM_MPLKSTAT_LK_MASK)
		unlock_mem_prot_regs();
	KeyStone_MPAX_seg_setup((MPAX_Regs *)&gpXMC_regs->XMPAX[15], 
		0xE0000000, ((Uint32)EDCTestData)>>4, 4*1024, 
		MP_SR|MP_SW|MP_UR|MP_UW);
	lock_mem_prot_regs();

	gpCGEM_regs->MAR[0xE0000000/(16*1024*1024)] = 1;//cacheable

	//test EDC on the remapped SL2 space
	SL2_data_bit_ERR_test((Uint8 *)0xE0000000);

	/* enable scrubbing engine  */
	CSL_MSMC_unlockNonMPAX();
	CSL_MSMC_enableScrubbingEngine();

	CSL_MSMC_lockNonMPAX();
}


/*****************************************************************************
 Prototype    : SL2_code_bit_ERR_test
 Description  : SL2 EDC test in program memory
 Input        : None
 Output       : None
 Return Value : 
 
  History        :
  1.Date         : 2012/10/13
    Author       : Jane
    Modification : Created function

*****************************************************************************/
void SL2_code_bit_ERR_test()
{
	CACHE_invL1p((void *)((Uint32)funcTest1_SL2), 64, CACHE_WAIT);

    /*scrube the test function, make sure parity bit info are generated */
	EDMA_copy((Uint32)funcTest1_SL2, (Uint32)funcTest1_SL2, 64,
		EDMA_CC2_CH0, DMA_WAIT);
		
#if 0 	/*uncorrectable code bit error test may crush the program*/
	printf("!!!manually generate two bit error in a function at 0x%x, and then execute the function...\n",
		((Uint32)funcTest1_SL2)+32);

	CSL_MSMC_unlockNonMPAX();
	/* suspend SL2 EDC  */
	gpMSMC_regs->SMEDCTST |= 0xf;
	/* simulator one bit error  */
	EDMA_copy((Uint32)funcTest3_SL2, (Uint32)funcTest1_SL2,64,
		EDMA_CC0_CH0, DMA_WAIT);
	/* un_suspend SL2 EDC  */
	gpMSMC_regs->SMEDCTST &= ~0xf;

	/* trigger 1 bit error */
	funcTest1_SL2();

 	/*normally, exception is captured about 10~100 cycles after the
	access violation. Dummy operations added here to wait for it.*/
	asm(" nop 5");
	asm(" nop 5");
	asm(" nop 5");
	asm(" nop 5"); 	/*NRP should be around the address of this instruction*/
	asm(" nop 5");

	CACHE_invL1p((void *)((Uint32)funcTest1_SL2), 64, CACHE_WAIT);
#endif
	printf("!!!manually generate one bit error in a function at 0x%x, and then execute the function...\n",
		((Uint32)funcTest1_SL2)+32);

	CSL_MSMC_unlockNonMPAX();
	/* suspend SL2 EDC  */
	gpMSMC_regs->SMEDCTST |= 0xf;
	/* simulator one bit error  */
	EDMA_copy((Uint32)funcTest2_SL2, (Uint32)funcTest1_SL2,64,
		EDMA_CC2_CH0, DMA_WAIT);
	/* un_suspend SL2 EDC  */
	gpMSMC_regs->SMEDCTST &= ~0xf;

	/* trigger 1 bit error */
	funcTest1_SL2();

 	/*normally, exception is captured about 10~100 cycles after the
	access violation. Dummy operations added here to wait for it.*/
	asm(" nop 5");
	asm(" nop 5");
	asm(" nop 5");
	asm(" nop 5"); 	/*NRP should be around the address of this instruction*/
	asm(" nop 5");

	CACHE_invL1p((void *)((Uint32)funcTest1_SL2), 64, CACHE_WAIT);

	/* re-test 1 bit error, this time there's should no EDC error */
	puts("\none bit error was corrected with previous execution. Execute the function again...(no error happens again)");
	funcTest1_SL2();

}

/*****************************************************************************
 Prototype    : SL2_data_bit_ERR_test
 Description  : SL2 EDC generated on with logic address
 Input        : Uint8 *dataPtr: pointer to the test data buffer
 Output       : None
 Return Value : 
 
  History        :
  1.Date         : 2012/10/13
    Author       : Jane
    Modification : Created function

*****************************************************************************/
void SL2_data_bit_ERR_test(Uint8 *dataPtr)
{
    /*scrube the test data, make sure parity bit info are generated */
	memcpy((void *)dataPtr, (void *)dataPtr, 64);
	WritebackInvalidCache((void *)dataPtr, 128); /*writeback block size must >=128 !*/

	printf("\n!!!manually generate one bit error data at 0x%x, and then read it...\n",
		(Uint32)dataPtr);

	CSL_MSMC_unlockNonMPAX();

	 /* suspend SL2 EDC  */
	gpMSMC_regs->SMEDCTST |= 0xf;

	/* generate 1 bit error */
	dataPtr[1] ^= 1;
	WritebackInvalidCache((void *)dataPtr, 64);

	/* un_suspend SL2 EDC  */
	gpMSMC_regs->SMEDCTST &= ~0xf;

	/*read the data */
	memcpy((void *)dataPtr, (void *)dataPtr, 64);

 	/*normally, exception is captured about 10~100 cycles after the
	access violation. Dummy operations added here to wait for it.*/
	asm(" nop 5");
	asm(" nop 5");
	asm(" nop 5");
	asm(" nop 5"); 	/*NRP should be around the address of this instruction*/
	asm(" nop 5");

	CACHE_wbInvAllL1d(CACHE_WAIT);
	
}

