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

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

 ******************************************************************************
  File Name     : Robust_Peripherals_MPU.c
  Version       : Initial Draft
  Author        : Zhan Xiang
  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 Xiang
    Modification: Created file
  2.Date        : 2012/12/15
    Author      : Brighton Feng
    Modification: change the method to configure MPU
  3.Date        : July 24, 2013
    Author      : Andy Yin
    Modification: update for K2
  4.Date        : 2014/10/30
    Author      : Brighton Feng
    Modification: updated for ARM
******************************************************************************/
#include <stdio.h>
#include "K2_common.h"
#include "Robust_Peripherals_MPU.h"
#include "Robust_MNav_Init.h"
#include "csl_cpintc.h"

/*----------------------------------------------*
 * module-wide global variables                 *
 *----------------------------------------------*/
/*MPU for QMSS VBUSM region*/
MPU_Range_Config MPU1_cfg_table[]=
{
	/*StartAddr  EndAddr     AccessPermisionMask*/
	{0x23a00000, 0x23a7FFFF, MPU_DENY_ALL},/*Reserved*/

	{0x23a80000, 0x23a9FFFF, MP_AID11|MP_NS|MP_EMU|MP_SR|MP_UR},/*Queue 0~8191, disable write from AID11*/
	{0x23a80000, 0x23a87FFF, MP_AID9_15|MP_NS|MP_EMU|MP_SR|MP_UR},/*Queue 0~2047, disable write from AID9~15*/
	{0x23a98000, 0x23a9FFFF, MP_AID0_8|MP_NS|MP_EMU|MP_SR|MP_UR},/*Queue 6144~8191, disable write from AID0~8*/

	{0x23aa0000, 0x23BFFFFF, MPU_DENY_ALL} /*Reserved*/
};

/*MPU for QMSS VBUSP regions*/
MPU_Range_Config MPU2_cfg_table[]=
{
	/*StartAddr  EndAddr     AccessPermisionMask*/
	{0x02A00000, 0x02AFFFFF, MP_AID9_15|MP_NONE},/*disable access from AID9~15 for QMSS VBUSP regions*/
	{0x02A00000, 0x02A7FFFF, MP_AID0_8|MP_NS|MP_EMU|MP_SR|MP_SW|MP_UR},/*QMSS registers, disable UW from AID0~8*/

	{0x02A80000, 0x02A9FFFF, MP_AID0_8|MP_NS|MP_EMU|MP_SR|MP_SW|MP_UR|MP_UW},/*Queue0~8191, disable execute from AID0~8*/
	{0x02A80000, 0x02A83FFF, MP_AID8|MP_AID7|MP_AID6|MP_AID5|MP_AID4|MP_NONE},/*Queue 0~1023, disable access from AID4~8*/
	{0x02A84000, 0x02A87FFF, MP_AID3|MP_AID2|MP_AID1|MP_AID0|MP_NONE},/*Queue 1024~2047, disable access from AID0~3*/
	{0x02A88000, 0x02A8FFFF, MP_AID0_8|MP_NS|MP_EMU|MP_SR|MP_UR},/*Queue2048~4095, disable write from AID0~8*/
	{0x02A98000, 0x02A9FFFF, MP_AID0_8|MP_NONE},/*Queue 6144~8191, disable access from AID0~8*/

	{0x02AC0000, 0x02ADFFFF, MPU_DENY_ALL},/*Queue proxy region*                     */
	{0x02A00000, 0x02A7FFFF, MP_AID0_8|MP_NS|MP_EMU|MP_SR|MP_SW|MP_UR},/*QMSS registers, disable UW from AID0~8*/
	{0x02A06000, 0x02A063FF, MP_AID0_8|MP_NS|MP_EMU|MP_SR|MP_UR}/*Queue threshold status, disable write from AID0~8*/
};

/*----------------------------------------------*
 * routines' implementations                    *
 *----------------------------------------------*/
/*****************************************************************************
 Prototype    : Queue_MP_test
 Description  : Queue protection test with CPU
 Input        : None
 Output       : None
 Return Value : 
 
  History        :
  1.Date         : 2012/10/20
    Author       : Zhan Xiang
    Modification : Created function
  2.Date        : 2014/10/30
    Author      : Brighton Feng
    Modification: updated for ARM

*****************************************************************************/
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("\nCPU Pop descriptor from queue %d at 0x%x in a read-only range...\n",
    	MSMC_RAM_HOST_SIZE0_FDQ, (unsigned int)&gpQueueManageRegs[MSMC_RAM_HOST_SIZE0_FDQ].REG_D_Descriptor);
    uwDescAddr = KeyStone_queuePop(MSMC_RAM_HOST_SIZE0_FDQ);    

    if(uwDescAddr != 0)
    {
	    printf("\n!!!CPU Push descriptor to queue %d at 0x%x in a read-only range...\n",
	    	MSMC_RAM_HOST_SIZE0_FDQ, (unsigned int)&gpQueueManageRegs[MSMC_RAM_HOST_SIZE0_FDQ].REG_D_Descriptor);
	    gpQueueManageRegs[MSMC_RAM_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.*/
		dummy_wait(1000);	

	    printf("\nCPU Push descriptor to queue %d at 0x%x in a writeable range...\n",
	    	MSMC_RAM_HOST_SIZE0_FDQ, (unsigned int)&gpQueueManageVBUSM[MSMC_RAM_HOST_SIZE0_FDQ].REG_D_Descriptor);
        KeyStone_queuePush(MSMC_RAM_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 Xiang
    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_11, CSL_PLLC_REGS, MP_AID0_15);

	printf("!!!Write to PLL register at 0x%08x which is protected by MPU11...\n",
			(unsigned int)&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.*/
	dummy_wait(1000);	

    Queue_MP_test();
}

