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

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

 ******************************************************************************
  File Name     : Robust_SL2_SMS_MP.c
  Version       : Initial Draft
  Author        : Zhan
  Created       : 2012/3/11
  Last Modified :
  Description   : SL2 SMS memory protection example
  Function List :
              MSMCSmsMemoryBufInit
              SMS_SL2_MP_test
  History       :
  1.Date        : 2012/3/11
    Author      : Zhan
    Modification: Created file

  2.Date         : 2012/10/28
    Author       : Zhan
    Modification : Add SRIO access test
******************************************************************************/
#include <stdio.h>
#include "KeyStone_common.h"
#include "KeyStone_SRIO_init_drv.h"
#include "Robust_SRIO_Init.h"
/*----------------------------------------------*
 * external variables                           *
 *----------------------------------------------*/
extern CSL_MsmcRegs * gpMSMC_regs;

/*----------------------------------------------*
 * external routine prototypes                  *
 *----------------------------------------------*/
extern void InitLsuTransfer(SRIO_LSU_Transfer * lsuTransfer,
	SRIO_Transfer_Param * transferParam, Uint32 uiLsuNum,
	Uint32 uiDstID, Uint32 uiSrcIDMap);
/*----------------------------------------------*
 * internal routine prototypes                  *
 *----------------------------------------------*/

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

/*----------------------------------------------*
 * module-wide global variables                 *
 *----------------------------------------------*/
/*total 64K data for MSMC SMS*/
#pragma DATA_SECTION(msmcSmsMPDataDst, "msmcSmsMPData_w")
#pragma DATA_ALIGN(msmcSmsMPDataDst,64*1024) //align to MPAX segment bouandary
volatile char msmcSmsMPDataDst[2][32768];

/* 16K data */
#pragma DATA_SECTION(msmcSmsMPDataSrc, "msmcSmsMPData_r")
#pragma DATA_ALIGN(msmcSmsMPDataSrc,16*1024) //align to MPAX segment bouandary
volatile char msmcSmsMPDataSrc[4][4096];

/*memory protection and address extension configuration table*/
MPAX_Config SMS_MPAX_cfg_table[]=
{
    /*BADDR                  RADDR           SegementSize            AccessPermisionMask
    32-bit virtual           36-bit physical in byte, must           Access types allowed
    base address             address right   be power of 2           in this address range
                             shift by 4                                                    */
    {(Uint32)msmcSmsMPDataDst, 0,          sizeof(msmcSmsMPDataDst), MP_SW|MP_UW},/*write only data*/
    {(Uint32)msmcSmsMPDataSrc, 0,          sizeof(msmcSmsMPDataSrc), MP_SR|MP_UR}/*read only data*/
};

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

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

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




/*****************************************************************************
 Prototype    : MSMCSmsMemoryBufInit
 Description  : SMS test buffer initialization
 Input        : None
 Output       : None
 Return Value : 
 
  History        :
  1.Date         : 2012/3/11
    Author       : Zhan
    Modification : Created function

*****************************************************************************/
void MSMCSmsMemoryBufInit()
{
	int i;
	for(i=0; i<4096; i++)
	{
		msmcSmsMPDataSrc[0][i] = 0xCC;
		msmcSmsMPDataSrc[1][i] = 0xDD;
		msmcSmsMPDataSrc[2][i] = 0xEE;
		msmcSmsMPDataSrc[3][i] = 0xFF;

	}

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

/*****************************************************************************
 Prototype    : SMS_SL2_MP_test
 Description  : This test shows the MSMC memory protection among different
                master 
 Input        : None
 Output       : None
 Return Value : 
 
  History        :
  1.Date         : 2012/3/11
    Author       : Zhan
    Modification : Created function

  2.Date         : 2012/10/28
    Author       : Zhan
    Modification : Add SRIO access
*****************************************************************************/
void SMS_SL2_MP_test()
{
	int i;
    Uint32 uwSrioPriVid;
	SRIO_Transfer_Param transferParam;
	SRIO_LSU_Transfer lsuTransfer;    
	TDSP_Board_Type DSP_Board_Type;

	puts("===================-SMS SL2 memory protection test-==============");

	MSMCSmsMemoryBufInit();

	SMS_MPAX_cfg_table[0].RADDR= SMS_MPAX_cfg_table[0].BADDR>>4;
	SMS_MPAX_cfg_table[1].RADDR= SMS_MPAX_cfg_table[1].BADDR>>4;
	KeyStone_SMS_MPAX_setup(SMS_MPAX_cfg_table, 1,
		sizeof(SMS_MPAX_cfg_table)/sizeof(MPAX_Config), DNUM);

	/* EDMA copy data from msmcMPDataSrc to msmcMPDataDst is allowed */
	/* The first EDMA write is allowed */
	printf("EDMA copy from 0x%x (read-only) to 0x%x (write-only)...\n",
		GLOBAL_ADDR((Uint32)&msmcSmsMPDataSrc[0][0]),
		GLOBAL_ADDR((Uint32)&msmcSmsMPDataDst[0][0]));
	EDMA_copy(GLOBAL_ADDR((Uint32)&msmcSmsMPDataSrc[0][0]),
			  GLOBAL_ADDR((Uint32)&msmcSmsMPDataDst[0][0]),
			  640, EDMA_CC2_CH0, DMA_WAIT);

	/*EDMA copy data from msmcMPDataDst to msmcMPDataSrc is not allowed */
	printf("\n!!!EDMA copy from 0x%x (write-only) to 0x%x (read-only)...\n",
		GLOBAL_ADDR((Uint32)&msmcSmsMPDataDst[1][0]),
		GLOBAL_ADDR((Uint32)&msmcSmsMPDataSrc[1][0]));
	EDMA_copy(GLOBAL_ADDR((Uint32)&msmcSmsMPDataDst[1][0]),
			  GLOBAL_ADDR((Uint32)&msmcSmsMPDataSrc[1][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");/*NRP should be around the address of this instruction*/
	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");
	EDMA_wait(EDMA_CC2_CH0);

	printf("\n!!!DSP core write to gpMSMC_regs->SMS_MPAX_PER_PRIVID[%d].SMS[0].MPAXL register at 0x%x without unlocking...\n",
		DNUM, &gpMSMC_regs->SMS_MPAX_PER_PRIVID[DNUM].SMS[0].MPAXL);
	gpMSMC_regs->SMS_MPAX_PER_PRIVID[DNUM].SMS[0].MPAXL= 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");
	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");
	asm(" nop 5");
	asm(" nop 5");
	asm(" nop 5");

	puts("--------------------SRIO SMS SL2 memory protection test---------------");

	DSP_Board_Type = KeyStone_Get_dsp_board_type();
	if((C6670_EVM == DSP_Board_Type))
	{	
		uwSrioPriVid = PRIVID_SRIO_C6670;
	}
	else if(C6678_EVM == DSP_Board_Type)
	{
		uwSrioPriVid = PRIVID_SRIO_C6678;
	}
	else if(TCI6614_EVM == DSP_Board_Type)
	{
		uwSrioPriVid = PRIVID_SRIODIO_TCI6614;
	}    
	else if(C6657_EVM == DSP_Board_Type)
	{
		uwSrioPriVid = PRIVID_SRIO_C6657;
	}
	else
	{
		puts("Unknown DSP type!");
		return;
	}    

    KeyStone_MSMC_MP_interrupt_en(1<<uwSrioPriVid);

	SMS_MPAX_cfg_table[0].RADDR= SMS_MPAX_cfg_table[0].BADDR>>4;
	SMS_MPAX_cfg_table[1].RADDR= SMS_MPAX_cfg_table[1].BADDR>>4;
	KeyStone_SMS_MPAX_setup(SMS_MPAX_cfg_table, 1,
		sizeof(SMS_MPAX_cfg_table)/sizeof(MPAX_Config), uwSrioPriVid);    
    
	/* The first SRIO write is allowed */
	printf("SRIO copy from 0x%x (read-only) to 0x%x (write-only)...\n",
		GLOBAL_ADDR((Uint32)&msmcSmsMPDataSrc[2][0]),
		GLOBAL_ADDR((Uint32)&msmcSmsMPDataDst[1][0]));

	transferParam.byteCount = 32;
	transferParam.packet_type = SRIO_PKT_TYPE_NWRITE_R;
	transferParam.source = GLOBAL_ADDR((Uint32)&msmcSmsMPDataSrc[2][0]);
	transferParam.dest = GLOBAL_ADDR((Uint32)&msmcSmsMPDataDst[1][0]);

	InitLsuTransfer(&lsuTransfer, &transferParam, 0, 
		DSP0_SRIO_BASE_ID, 0);
	
	KeyStone_SRIO_LSU_transfer(&lsuTransfer);

	/*wait for transfer complete*/
	KeyStone_SRIO_wait_LSU_completion(0,
		lsuTransfer.transactionID, lsuTransfer.contextBit);

	/* SRIO copy data from msmcMPDataSrc to msmcMPDataSrc is not allowed */
	printf("\n!!!SRIO copy from 0x%x (read-only) to 0x%x (read-only)...\n",
		GLOBAL_ADDR((Uint32)&msmcSmsMPDataSrc[2][0]),
		GLOBAL_ADDR((Uint32)&msmcSmsMPDataSrc[1][0]));

	transferParam.byteCount = 32;
	transferParam.packet_type = SRIO_PKT_TYPE_NWRITE_R;
	transferParam.source = GLOBAL_ADDR((Uint32)&msmcSmsMPDataSrc[2][0]);
	transferParam.dest = GLOBAL_ADDR((Uint32)&msmcSmsMPDataSrc[1][0]);

	InitLsuTransfer(&lsuTransfer, &transferParam, 0, 
		DSP0_SRIO_BASE_ID, 0);
	
	KeyStone_SRIO_LSU_transfer(&lsuTransfer);

	/*add dummy nop here to wait for the exception happens*/
	for(i=0; i<10; i++)
	{
		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");
	}
	
	/*wait for transfer complete*/
	KeyStone_SRIO_wait_LSU_completion(0,
		lsuTransfer.transactionID, lsuTransfer.contextBit);

}


