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

  Copyright (C), 2010-2013, Texas Instrument.

 ******************************************************************************
  File Name     : Robust_MSMC_RAM_EDC.c
  Version       : Initial Draft
  Author        : Jane Lu
  Created       : 2012/10/12
  Last Modified :
  Description   : MSMC_RAM EDC test example
  Function List :
              funcTest1_MSMC_RAM
              funcTest2_MSMC_RAM
              funcTest3_MSMC_RAM
              MSMC_RAM_EDC_test
              MSMC_RAM_data_bit_ERR_test
              MSMC_RAM_code_bit_ERR_test
  History       :
  1.Date        : 2012/10/12
    Author      : Jane Lu
    Modification: Created file

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

#include <stdio.h>
#include <string.h>
#include "K2_common.h"
#include  "CSL_msmc.h"
#include  "CSL_msmcAux.h"

/*----------------------------------------------*
 * internal routine prototypes                  *
 *----------------------------------------------*/
extern void MSMC_RAM_data_bit_ERR_test(Uint8 *dataPtr);

/*----------------------------------------------*
 * module-wide global variables                 *
 *----------------------------------------------*/
//align to MPAX segment bouandary
Uint8 EDCTestData[4*1024] __attribute__ ((aligned (4*1024), section ("MSRAM_EDC_Data")));

/*****************************************************************************
 Prototype    : MSMC_RAM_EDC_test
 Description  : MSMC_RAM EDC test example
 Input        : None
 Output       : None
 Return Value : 
 
  History        :
  1.Date         : 2012/10/13
    Author       : Jane Lu
    Modification : Created function
  2.Date        : 2014/10/30
    Author      : Brighton Feng
    Modification: updated for ARM

*****************************************************************************/
void MSMC_RAM_EDC_test()
{

	puts("===================-MSMC_RAM EDC test-================================");
	CP15_ICacheInvalidate();
	CP15_DCacheCleanInvalidate();

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

	MSMC_RAM_data_bit_ERR_test(EDCTestData);
	__asm__(" ISB");

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

	CSL_MSMC_lockNonMPAX();
}

/*****************************************************************************
 Prototype    : MSMC_RAM_data_bit_ERR_test
 Description  : MSMC_RAM 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 Lu
    Modification : Created function
  2.Date        : 2014/10/30
    Author      : Brighton Feng
    Modification: updated for ARM

*****************************************************************************/
void MSMC_RAM_data_bit_ERR_test(Uint8 *dataPtr)
{
	CP15_DCacheCleanInvalidateBuff((unsigned int)dataPtr, 128); /*writeback block size must >=128 !*/
	__asm__(" DSB");
	__asm__(" ISB");
    /*fill the test data, make sure parity bit info are generated */
	EDMA_fill((unsigned int)dataPtr, 0, 64, EDMA_CC0_CH0);
	__asm__(" DSB");
	__asm__(" ISB");

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

	CSL_MSMC_unlockNonMPAX();

	 /* suspend MSMC_RAM EDC  */
	gpMSMC_regs->SMEDCTST |= 0xf;
	__asm__(" DSB");
	__asm__(" ISB");

	/* generate 1 bit error */
	dataPtr[1] ^= 1;
	CP15_DCacheCleanInvalidateBuff((unsigned int)dataPtr, 64);

	/* un_suspend MSMC_RAM EDC  */
	gpMSMC_regs->SMEDCTST &= ~0xf;
	__asm__(" DSB");
	__asm__(" ISB");

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

 	/*normally, exception is captured about 10~100 cycles after the
	access violation. Dummy operations added here to wait for it.*/
	dummy_wait(1000);	

	CP15_DCacheCleanInvalidate();
}

