/*
 * Copyright 2018 NXP
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include "fsl_device_registers.h"
#include "fsl_debug_console.h"
#include "veneer_table.h"
#include "pin_mux.h"
#include "board.h"
#include "clock_config.h"

#include "fsl_inputmux.h"
/*******************************************************************************
 * Definitions
 ******************************************************************************/
#define PRINTF_NSE DbgConsole_Printf_NSE
#define DEMO_SW1_GPIO GPIO
#define DEMO_SW1_GPIO_PORT 0U
#define DEMO_SW1_GPIO_PIN 10U
#define DEMO_SW2_GPIO GPIO
#define DEMO_SW2_GPIO_PORT 1U
#define DEMO_SW2_GPIO_PIN 1U
typedef void (*funcptr_t)(char const * s);
/*******************************************************************************
 * Prototypes
 ******************************************************************************/
void ForceSecureFault(uint32_t testCase);

/*******************************************************************************
 * Global variables
 ******************************************************************************/
uint32_t testCaseNumber;

/*******************************************************************************
 * Code
 ******************************************************************************/

void SystemInit(void)
{
}
/*!
 * @brief Main function
 */
int main(void)
{

	PRINTF_NSE("Welcome in NS normal world!\r\n");

    /** Secure Faults Test Examples */
    testCaseNumber = GetTestCaseNumber_NSE();
    ForceSecureFault(testCaseNumber);

    while (1)
    {
        /** Poll SW1 GPIO from NS World **/
    	/** If SW1 (Switch 2 in EVK) can be read and is not pressed --> Blue LED is ON                     **/
    	/** If SW1 (Switch 2 in EVK) can be read and is pressed -> Blue LED is OFF                         **/
    	/** If SW1 (Switch 2 in EVK) can't be read due SEC_GPIO_0_10 and is not pressed -> Blue LED is OFF **/
    	if (GPIO_PinRead(DEMO_SW1_GPIO, DEMO_SW1_GPIO_PORT, DEMO_SW1_GPIO_PIN))
        {
            LED_BLUE_ON();
        }
        else
        {
        	LED_BLUE_OFF();
        }

    	/* GPIO Mask is controlled by pressing SW2 (Switch 1 in EVK)                          */
    	/* If GPIO Mask is enabled turn Green LED ON                                          */
    	/* When SecureGPIO_Mask is cleared, NS World can't read SW1 GPIO (Switch 2 in EVK) pin*/
    	/* Description: PIOn_PIN10_SEC_MASK RW:
    	 * 0: GPIO can't read PIOn_PIN10
    	 * 1: GPIO can read PIO0_PIN10       */
    	if(SecureGPIO_Mask_NSE())
    	{
    		LED_GREEN_OFF();
    	}
    	else
    	{
    		LED_GREEN_ON();
    	}

    }
}

void ForceSecureFault(uint32_t testCase)
{
	uint32_t *test_ptr;
	funcptr_t func_ptr;
	uint32_t test_value=0;

	switch (testCase)
	{
 	 /* Test 2 NS->S invalid entry point
 	  * The function pointer is intentionally incremented by 4,
 	  * which causes skipping the SG instruction.  */
	 case FAULT_INV_S_ENTRY:
 	 {
  		PRINTF_NSE("The right way to jump NS -> S \r\n");

 		func_ptr = (funcptr_t)((uint32_t)&PRINTF_NSE + 4);
  		func_ptr("Invalid Test Case\r\n");
  		break;
 	 }

 	 /* Test 3 NS->S illegal data access
 	  * Try to read data from secure RAM0 address 0x30000000U */
 	 case FAULT_INV_NS_DATA_ACCESS:
 	 {
  		test_ptr = (uint32_t *)(0x30000000U);
  		test_value = *test_ptr;
  		test_value ++;
  		break;
 	 }

 	 /* Test 4 NS->S invalid data access
 	  * Try to read data from RAM1 address 0x00130000U
 	  * SAU attribute = NS
 	  * AHB Secure Controller = S */
 	 case FAULT_INV_NS_DATA2_ACCESS:
 	 {
         test_ptr = (uint32_t *)(0x00130000U);
         test_value = *test_ptr;
 	 }

 	 /*Test 5 NS->NSC invalid input parameter
 	  * This function call uses secure RAM0 address 0x30000000U,
 	  * but will not generate a secure fault, since the input is used by a S function
 	  * NSC uses TT instruction to detect this type of error */
 	 case FAULT_INV_INPUT_PARAMS:
 	 {
 		PRINTF_NSE((char *)(0x30000000U));
 		break;
 	 }

 	 default:
 		 break;
	}
}
