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

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

 ******************************************************************************
  File Name     : Robust_Peripherals_MPU.c
  Version       : Initial Draft
  Author        : Zhan
  Created       : 2012/9/10
  Last Modified :
  Description   : This file shows the peripheral memory protection example
  Function List :
  History       :
  1.Date        : 2012/9/10
    Author      : Zhan
    Modification: Created file

  2.Date        : 2012/12/15
    Author      : Brighton Feng
    Modification: change the method to configure MPU
******************************************************************************/
#include <stdio.h>
#include "KeyStone_common.h"
#include "Robust_Peripherals_MPU.h"
#include "Robust_MNav_Init.h"
#include "csl_cpintc.h"
/*----------------------------------------------*
 * external variables                           *
 *----------------------------------------------*/
/*----------------------------------------------*
 * external routine prototypes                  *
 *----------------------------------------------*/

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

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

/*----------------------------------------------*
 * module-wide global variables                 *
 *----------------------------------------------*/
/*MPU for QMSS VBUSM region*/
MPU_Range_Config MPU1_cfg_table[]=
{/*Due to the errata, MPU usage notes, the read permision must be enable for MPU1*/
	/*StartAddr  EndAddr     AccessPermisionMask*/
	{0x34000000, 0x3401FFFF, MPU_DENY_ALL},/*Reserved*/

	{0x34020000, 0x3403FFFF, MP_AID11|MP_NS|MP_EMU|MP_SR|MP_UR},/*Queue 0~8191, disable write from AID11*/
	{0x34020000, 0x34027FFF, MP_AID8_15|MP_NS|MP_EMU|MP_SR|MP_UR},/*Queue 0~2047, disable write from AID8~15*/
	{0x34038000, 0x3403FFFF, MP_AID0_7|MP_NS|MP_EMU|MP_SR|MP_UR},/*Queue 6144~8191, disable write from AID0~7*/

	{0x34040000, 0x340BFFFF, MPU_DENY_ALL} /*Reserved*/
};

/*MPU for QMSS VBUSP regions*/
MPU_Range_Config MPU2_cfg_table[]=
{
	/*StartAddr  EndAddr     AccessPermisionMask*/
	{0x02A00000, 0x02ABFFFF, MP_AID8_15|MP_NONE},/*disable access from AID8~15 for QMSS VBUSP regions*/
	{0x02A00000, 0x02A1FFFF, MP_AID0_7|MP_NS|MP_EMU|MP_SR|MP_SW|MP_UR},/*QMSS registers, disable UW from AID0~7*/

	{0x02A20000, 0x02A3FFFF, MP_AID0_7|MP_NS|MP_EMU|MP_SR|MP_SW|MP_UR|MP_UW},/*Queue0~8191, disable execute from AID0~7*/
	{0x02A20000, 0x02A23FFF, MP_AID7|MP_AID6|MP_AID5|MP_AID4|MP_NONE},/*Queue 0~1023, disable access from AID4~7*/
	{0x02A24000, 0x02A27FFF, MP_AID3|MP_AID2|MP_AID1|MP_AID0|MP_NONE},/*Queue 1024~2047, disable access from AID0~3*/
	{0x02A28000, 0x02A2FFFF, MP_AID0_7|MP_NS|MP_EMU|MP_SR|MP_UR},/*Queue2048~4095, disable write from AID0~7*/
	{0x02A38000, 0x02A3FFFF, MP_AID0_7|MP_NONE},/*Queue 6144~8191, disable access from AID0~7*/

	{0x02A40000, 0x02A5FFFF, MPU_DENY_ALL},/*Queue proxy region*                     */
	{0x02A60000, 0x02ABFFFF, MP_AID0_7|MP_NS|MP_EMU|MP_SR|MP_SW|MP_UR},/*QMSS registers, disable UW from AID0~7*/
	{0x02A62000, 0x02A67FFF, MP_AID0_7|MP_NS|MP_EMU|MP_SR|MP_UR},/*Queue threshold status, disable write from AID0~7*/
	{0x02A80000, 0x02A8FFFF, MPU_DENY_ALL} /*Queue manager internal linking RAM*/
};


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

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

/*----------------------------------------------*
 * routines' implementations                    *
 *----------------------------------------------*/
/*****************************************************************************
 Prototype    : Queue_MP_test
 Description  : Queue protection test with DSP core
 Input        : None
 Output       : None
 Return Value : 
 
  History        :
  1.Date         : 2012/10/20
    Author       : Zhan
    Modification : Created function

*****************************************************************************/
void Queue_MP_test()
{
    Uint32 uwDescAddr;

    KeyStone_MPU_setup(CSL_MPU_1, MPU1_cfg_table, 
        sizeof(MPU1_cfg_table)/sizeof(MPU_Range_Config));

    KeyStone_MPU_setup(CSL_MPU_2, MPU2_cfg_table, 
        sizeof(MPU2_cfg_table)/sizeof(MPU_Range_Config));

    printf("\nDSP core Pop descriptor from queue %d at 0x%x in a read-only range...\n",
    	SL2_HOST_SIZE0_FDQ, &gpQueueManageRegs[SL2_HOST_SIZE0_FDQ].REG_D_Descriptor);
    uwDescAddr = KeyStone_queuePop(SL2_HOST_SIZE0_FDQ);    

    if(uwDescAddr != 0)
    {
	    printf("\n!!!DSP core Push descriptor to queue %d at 0x%x in a read-only range...\n",
	    	SL2_HOST_SIZE0_FDQ, &gpQueueManageRegs[SL2_HOST_SIZE0_FDQ].REG_D_Descriptor);
        gpQueueManageRegs[SL2_HOST_SIZE0_FDQ].REG_D_Descriptor = uwDescAddr | FETCH_SIZE_32;

        /*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");
        asm(" nop 5");
        asm(" nop 5"); 	/*NRP should be around the address of this instruction*/
        asm(" nop 5");         

	    printf("\nDSP core Push descriptor to queue %d at 0x%x in a writeable range...\n",
	    	SL2_HOST_SIZE0_FDQ, &gpQueueManageVBUSM[SL2_HOST_SIZE0_FDQ].REG_D_Descriptor);
        KeyStone_queuePush(SL2_HOST_SIZE0_FDQ, uwDescAddr|FETCH_SIZE_32);                
    }
    else
    {
        printf("Core Test MPU:error. Pop NULL Descriptor!!!\n ");
        return;
    }

}

/*****************************************************************************
 Prototype    : peripheral_MP_test
 Description  : This function test the MPU function for peripherals
 Input        : None
 Output       : None
 Return Value : void
 
  History        :
  1.Date         : 2012/9/12
    Author       : Zhan
    Modification : Created function

  2.Date        : 2012/12/15
    Author      : Brighton Feng
    Modification: change the method to configure MPU
*****************************************************************************/
void peripheral_MP_test()
{
	puts("===================-peripherals protection test-=================");

	/*deny any access to PLL configuration registers*/
	KeyStone_MPU_MPPA_modify(CSL_MPU_0, CSL_PLL_CONTROLLER_REGS, MP_AID0_15);

	printf("!!!Write to PLL register at 0x%08x which is protected by MPU0...\n",
		&gpPLLC_regs->PLLM);

	gpPLLC_regs->PLLM= 0;
	
    /*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");
    asm(" nop 5");
    asm(" nop 5"); 	/*NRP should be around the address of this instruction*/
    asm(" nop 5");         

    Queue_MP_test();
}

