#include <ti\csl\csl_xmcAux.h>
#include <ti\csl\csl_cache.h>
#include <ti\csl\csl_cacheAux.h>

#include <ti/csl/csl_chip.h>
#include <ti/csl/src/intc/csl_intc.h>
#include <ti/csl/csl_cpintcAux.h>

#include <stdio.h>
#include "Interrupt.h"
#include "Exception.h"

typedef enum {
			  SEG_SZ_4KB = 0xB,
	      	  SEG_SZ_8KB = 0xC,	     
			  SEG_SZ_16KB = 0xD,
			  SEG_SZ_32KB = 0xE,
			  SEG_SZ_64KB = 0xF,
			  SEG_SZ_128KB = 0x10,
			  SEG_SZ_256KB = 0x11,
			  SEG_SZ_512KB = 0x12,  
			  SEG_SZ_1MB = 0x13,
			  SEG_SZ_2MB = 0x14,
			  SEG_SZ_4MB = 0x15,
			  SEG_SZ_8MB = 0x16,
			  SEG_SZ_16MB = 0x17,
			  SEG_SZ_32MB = 0x18,
			  SEG_SZ_64MB = 0x19,
			  SEG_SZ_128MB = 0x1A,
			  SEG_SZ_256MB = 0x1B,
			  SEG_SZ_512MB = 0x1C,
			  SEG_SZ_1GB = 0x1D,
			  SEG_SZ_2GB = 0x1E,
			  SEG_SZ_4GB = 0x1F
}SEG_SIZE;

#pragma DATA_SECTION(myVariable, ".mydata")
int myVariable;

#pragma DATA_SECTION(myVariable_Alias, ".mycachable")
int myVariable_Alias;

#pragma DATA_SECTION(myVariableMSMC_cacheable, ".mycachable")
int myVariableMSMC_cacheable;

#pragma DATA_SECTION(myVariableMSMC_noncacheable, ".mynoncachable")
int myVariableMSMC_noncacheable;

#pragma DATA_SECTION(myVariableDDR, ".ddrdata")
int myVariableDDR;

#pragma DATA_SECTION(myL2Var_Alias, ".myaliasL2data")
int myL2Var_Alias;

void main(void)
{
	int i;
	
	Uint32 index;
    CSL_XMC_XMPAXH mpaxh;
    CSL_XMC_XMPAXL mpaxl;

    /* set MPAX 3 to map 0x30000000->0x00c000000 */
	index = 3;
    mpaxh.segSize = SEG_SZ_1MB;
    mpaxh.bAddr = 0x30000;
    CSL_XMC_setXMPAXH (index, &mpaxh);
	
    mpaxl.ux = 1;
    mpaxl.uw = 1;
    mpaxl.ur = 1;
    mpaxl.sx = 1;
    mpaxl.sw = 1;
    mpaxl.sr = 1;
    mpaxl.rAddr= 0x00C000;    
	CSL_XMC_setXMPAXL (index, &mpaxl);
	
	CACHE_setL2Size(CACHE_32KCACHE); 
	/* set alias address range 0x30000000 as cachable  */
	CACHE_enableCaching(48);
	
	/* set MPAX 4 to map 0x31000000->0x00c100000 */
	index = 4;
	mpaxh.segSize = SEG_SZ_1MB;
    mpaxh.bAddr = 0x31000;
    CSL_XMC_setXMPAXH (index, &mpaxh);
	
    mpaxl.ux = 1;
    mpaxl.uw = 1;
    mpaxl.ur = 1;
    mpaxl.sx = 1;
    mpaxl.sw = 1;
    mpaxl.sr = 1;
    mpaxl.rAddr = 0x00C100;
	CSL_XMC_setXMPAXL (index, &mpaxl);
    /* set alias address range 0x30000000 as noncachable  */
	CACHE_disableCaching(49);

	/* set MPAX 5 to map 0x80000000->0x800000000 */
	index = 5;
	mpaxh.segSize = SEG_SZ_128KB;
    mpaxh.bAddr = 0x80000;
    CSL_XMC_setXMPAXH (index, &mpaxh);
	
    mpaxl.ux = 0;
    mpaxl.uw = 0;
    mpaxl.ur = 0;
    mpaxl.sx = 0;
    mpaxl.sw = 0;
    mpaxl.sr = 0;
    mpaxl.rAddr = 0x800000;
	CSL_XMC_setXMPAXL (index, &mpaxl);
	CACHE_disableCaching(128);

	/* set MPAX 6 to map 0x40000000->0x0,0080,0000 */
	index = 6;
	mpaxh.segSize = SEG_SZ_1MB;
    mpaxh.bAddr = 0x40000;
    CSL_XMC_setXMPAXH (index, &mpaxh);
	
    mpaxl.ux = 1;
    mpaxl.uw = 1;
    mpaxl.ur = 1;
    mpaxl.sx = 1;
    mpaxl.sw = 1;
    mpaxl.sr = 1;
    mpaxl.rAddr = 0x000800;
	CSL_XMC_setXMPAXL (index, &mpaxl);
		
	/* Init interrupt */	
	initCPINTC();
	
	intcInit();
	
	registerInterrupt();
	
	/* Init exception */
	Exception_cfg();
	
	CSL_intcHookIsr(CSL_INTC_VECTID_NMI, Exeception_ISR);
	
	
	for (i=0; i<1000; i++)
		asm (" NOP 5");
	
	
    /* example1: Show how to use alias address to revise memory */	
	/* Show use alias address to visit variable */
	printf("*****************************************************\n");
	printf("example1, show how to visit memory use alias address!\n");
	myVariable = 1000;
	printf("myVariable at addr 0x%8x, value = %d\n", &myVariable, myVariable);
	
	/* Show use alias address to visit variable */
	/* WB with alias address will replace the content of 0x0c000000 address with WB value */
	myVariable_Alias = 2000;	 
	printf("myVariable_Alias at addr 0x%8x value = %d\n", &myVariable_Alias, myVariable_Alias);
	CACHE_wbInvL2(&myVariable_Alias, 4, CACHE_WAIT);
	
	/* Show the value of "myVariable" is revised by the alias value */
	CACHE_invL2(&myVariable, 4, CACHE_WAIT);
	printf("myVariable at addr 0x%8x value = %d\n", &myVariable, myVariable);

    /* example2: Show use MPAX to map MSMC RAM to a non-cachable region */
    /* Set myVariableMSMC_cacheable to initial value 1000 */
    printf("*****************************************************\n");
    printf("example2, show use MPAX to map MSMC RAM to a non-cachable region!\n");
    myVariableMSMC_cacheable = 1000;
    printf("myVariableMSMC_cacheable at addr 0x%8x initial value = %d\n", &myVariableMSMC_cacheable, myVariableMSMC_cacheable);
    CACHE_wbL2(&myVariableMSMC_cacheable, 4, CACHE_WAIT);
      
    myVariableMSMC_cacheable = 2000;
    printf("myVariableMSMC_cacheable at add 0x%8x revised value in cache = %d\n", &myVariableMSMC_cacheable, myVariableMSMC_cacheable);
    
    CACHE_invL2(&myVariableMSMC_cacheable, 4, CACHE_WAIT);
    printf("myVariableMSMC_cacheable at addr 0x%8x value after cache Inv = %d\n", &myVariableMSMC_cacheable, myVariableMSMC_cacheable);
    
    myVariableMSMC_noncacheable = 1000;
    printf("myVariableMSMC_noncacheable at addr 0x%8x initial value = %d\n", &myVariableMSMC_noncacheable, myVariableMSMC_noncacheable);
    CACHE_wbL2(&myVariableMSMC_noncacheable, 4, CACHE_WAIT);
      
    myVariableMSMC_noncacheable = 2000;
    printf("myVariableMSMC_noncacheable at add 0x%8x revised value in cache = %d\n", &myVariableMSMC_noncacheable, myVariableMSMC_noncacheable);
    
    CACHE_invL2(&myVariableMSMC_noncacheable, 4, CACHE_WAIT);
    printf("myVariableMSMC_noncacheable at addr 0x%8x value after cache Inv = %d\n", &myVariableMSMC_noncacheable, myVariableMSMC_noncacheable);
    printf("From the log, You can see myVariableMSMC_cacheable is in Cacheable region!\n");
    printf("From the log, You can see myVariableMSMC_noncacheable is in nonCacheable region!\n");

    /* example3: Show use MPAX to map MSMC RAM to a non-cachable region */
    printf("myVariableDDR at addr 0x%8x value = %d\n", &myVariableDDR, myVariableDDR);    
    myVariableDDR = 1; 
    CACHE_wbL2(&myVariableDDR, 4, CACHE_WAIT);
    
    /* example4: */
}

void MEMORY_PROTECT_ISR()
{
	printf("Memory interrupt happen!");
}

