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

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

 ******************************************************************************
  File Name     : Robust_LL2_MP.c
  Version       : Initial Draft
  Author        : Zhan
  Created       : 2012/3/11
  Last Modified :
  Description   : LL2 Memory protection example
  Function List :
              LL2MemoryBufInit
              LL2_MP_test
  History       :
  1.Date        : 2012/3/11
    Author      : Zhan
    Modification: Created file

******************************************************************************/
#include <stdio.h>
#include "KeyStone_common.h"
/*----------------------------------------------*
 * external variables                           *
 *----------------------------------------------*/

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

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

/*----------------------------------------------*
 * project-wide global variables                *
 *----------------------------------------------*/

/*----------------------------------------------*
 * module-wide global variables                 *
 *----------------------------------------------*/
/*total 64K data (at least two pages) for LL2 MP test*/
#pragma DATA_SECTION(ll2MPDataDst, "ll2MPData")
#pragma DATA_ALIGN(ll2MPDataDst,32*1024) //align to LL2 page bouandary
char ll2MPDataDst[2][32768];

char ll2MPDataSrc[1024];

int LL2_MP_testISRFlag = 0;
/*----------------------------------------------*
 * constants                                    *
 *----------------------------------------------*/

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

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




/*****************************************************************************
 Prototype    : LL2MemoryBufInit
 Description  : LL2 Memory protection initialization
 Input        : None
 Output       : None
 Return Value : 
 
  History        :
  1.Date         : 2012/3/11
    Author       : Zhan
    Modification : Created function

*****************************************************************************/
void LL2MemoryBufInit()
{
	int i;
	for(i=0; i<1024; i++)
	{
		ll2MPDataSrc[i] = i;
	}

	for(i=0; i<32768; i++)
	{
		ll2MPDataDst[0][i] = 0xFF;
		ll2MPDataDst[1][i] = 0xFF;
	}
	return;
}

/*****************************************************************************
 Prototype    : LL2_MP_test
 Description  : L2 memory protection test, the 64K data was used for
                test,
                 The core can write and read the 64K,
                 The EDMA can write the second 32K
                 The EDMA privilege will be mapping to the AID0
                
 Input        : None
 Output       : None
 Return Value : 
 
  History        :
  1.Date         : 2012/3/11
    Author       : Zhan
    Modification : Created function

*****************************************************************************/
void LL2_MP_test()
{
	//int privID = DNUM;

	puts("===================-LL2 memory protection test-==================");

	//KeyStone_PrivID_Remap(privID, 1);

	LL2MemoryBufInit();

	/*first half of the test data for local access only*/
	LL2_Memory_Protection_cfg((Uint32)&ll2MPDataDst[0][0],
		sizeof(ll2MPDataDst)/2, MP_LOCAL|MP_SR|MP_SW);

	/*second half of the test data for all AIDs access*/
	LL2_Memory_Protection_cfg((Uint32)&ll2MPDataDst[1][0],
		sizeof(ll2MPDataDst)/2, 
		MP_AID0_5|MP_AIDX|MP_LOCAL|MP_SR|MP_SW);

	/* The first EDMA write is allowed */
	printf("EDMA write to 0x%x, which is allowed for external access...\n",
		GLOBAL_ADDR((Uint32)&ll2MPDataDst[1][0]));
	EDMA_copy(GLOBAL_ADDR((Uint32)&ll2MPDataSrc[0]),
			  GLOBAL_ADDR((Uint32)&ll2MPDataDst[1][0]),
			  32, EDMA_CC2_CH0, DMA_WAIT);

	/* The second EDMA write is not allowed */
	printf("\n!!!EDMA write to 0x%x, which is protected against external access...\n",
		GLOBAL_ADDR((Uint32)&ll2MPDataDst[0][0]));
	EDMA_copy(GLOBAL_ADDR((Uint32)&ll2MPDataSrc[0]),
			  GLOBAL_ADDR((Uint32)&ll2MPDataDst[0][0]),
			  32, EDMA_CC2_CH0, DMA_NO_WAIT);

	/*DMA access has some latency, and normally, exception is 
	captured about 15~45 cycles after the access violation.
	Dummy operations added here to wait for DMA access and excpetion*/
	asm(" nop 5");	asm(" nop 5");
	asm(" nop 5");	asm(" nop 5");
	asm(" nop 5");	asm(" nop 5");
	asm(" nop 5");	asm(" nop 5");
	asm(" nop 5");	asm(" nop 5");
	asm(" nop 5");	asm(" nop 5");
	asm(" nop 5");	asm(" nop 5");
	asm(" nop 5");	asm(" nop 5");
	asm(" nop 5");	asm(" nop 5");
	asm(" nop 5");	asm(" nop 5");
	asm(" nop 5");	asm(" nop 5");
	asm(" nop 5");	asm(" nop 5");
	asm(" nop 5");	asm(" nop 5");
	asm(" nop 5");	asm(" nop 5");
	asm(" nop 5");	asm(" nop 5");
	asm(" nop 5");	asm(" nop 5");
	asm(" nop 5");	asm(" nop 5");
	asm(" nop 5");	asm(" nop 5");
	asm(" nop 5");	asm(" nop 5");/*NRP should be around the address of this instruction*/
	asm(" nop 5");	asm(" nop 5");
	EDMA_wait(EDMA_CC2_CH0);

	printf("\n!!!DSP core write to gpCGEM_regs->L2MPPA[0] register at 0x%x without unlocking...\n",
		&gpCGEM_regs->L2MPPA[0]);
	gpCGEM_regs->L2MPPA[0] = 0xFFFFFFFF;

	/*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"); 	
}

