Exemplo n.º 1
0
/**
\brief Test case: TC_CoreFunc_GetCtrl
\details
- Check if __set_CONTROL and __get_CONTROL() sets/gets control register
*/
void TC_CoreFunc_Control (void) {
  // don't use stack for this variables
  static uint32_t orig;
  static uint32_t ctrl;
  static uint32_t result;

  orig = __get_CONTROL();
  ctrl = orig;
  result = UINT32_MAX;

#ifdef CONTROL_SPSEL_Msk
  // toggle SPSEL
  ctrl = (ctrl & ~CONTROL_SPSEL_Msk) | (~ctrl & CONTROL_SPSEL_Msk);
#endif

  __set_CONTROL(ctrl);
  __ISB();

  result = __get_CONTROL();

  __set_CONTROL(orig);
  __ISB();

  ASSERT_TRUE(result == ctrl);
  ASSERT_TRUE(__get_CONTROL() == orig);
}
/*******************************************************************************
* Function Name  : HardFault_Handler
* Description    : This function handles Hard Fault exception.
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void HardFault_Handler(void)
{
	unsigned int contr_reg;
	contr_reg = __get_CONTROL();
	if(contr_reg&2)
	{
#if defined ( __CMCARM__ )
		__ASM MRS R0, PSP;
#else
		__ASM("MRS R0, PSP");
#endif
	}
	else{
#if defined ( __CMCARM__ )
		__ASM MRS R0, MSP;
#else
		__ASM("MRS R0, MSP");
#endif
	}
	//top of stack is in R0. It is passed to C-function.
#if defined ( __CMCARM__ )
	__ASM BL (Hard_fault_handler_c);
#else
	__ASM("BL (Hard_fault_handler_c)");
#endif

	/* Go to infinite loop when Hard Fault exception occurs */
	while (1);
}
Exemplo n.º 3
0
/**
\brief Test case: TC_CoreFunc_MSPLIM
\details
- Check if __get_MSPLIM and __set_MSPLIM intrinsic can be used to manipulate main stack pointer limit.
*/
void TC_CoreFunc_MSPLIM (void) {
  // don't use stack for this variables
  static uint32_t orig;
  static uint32_t msplim;
  static uint32_t result;
  static uint32_t ctrl;

  ctrl = __get_CONTROL();
  __set_CONTROL(ctrl | CONTROL_SPSEL_Msk); // switch to PSP

  orig = __get_MSPLIM();

  msplim = orig + 0x12345678U;
  __set_MSPLIM(msplim);

  result = __get_MSPLIM();

  __set_MSPLIM(orig);
  
  __set_CONTROL(ctrl);

#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
     (!defined (__ARM_FEATURE_CMSE  ) || (__ARM_FEATURE_CMSE   < 3)))
  // without main extensions, the non-secure MSPLIM is RAZ/WI
  ASSERT_TRUE(result == 0U);
#else
  ASSERT_TRUE(result == msplim);
#endif
}
Exemplo n.º 4
0
 int main() {
	int * hello;
	int * hello2;
	int * hello3;
	volatile unsigned int ret_val = 1234; 
	 
	SystemInit();
	__disable_irq();
	uart0_init();
	init_memory();
	process_init();
	__enable_irq();
	
  //SET Control to user level
	__set_CONTROL(__get_CONTROL() | BIT(0));
	 
	hello = s_request_memory_block();
	hello2 = s_request_memory_block();
	s_release_memory_block(hello);
	s_release_memory_block(hello2);

	hello3 = s_request_memory_block();
	 
	*hello3 = 88; 
	 
	uart0_put_string("Hello World!\n\r");	
	
	ret_val = release_processor();
	 
	return 0;
}
Exemplo n.º 5
0
/**
 * @brief   Port-related initialization code.
 */
void _port_init(void) {

    /* Initialization of the vector table and priority related settings.*/
    SCB_VTOR = CORTEX_VTOR_INIT;
    SCB_AIRCR = AIRCR_VECTKEY | AIRCR_PRIGROUP(CORTEX_PRIGROUP_INIT);

#if CORTEX_USE_FPU
    {
        /* Initializing the FPU context save in lazy mode.*/
        SCB_FPCCR = FPCCR_ASPEN | FPCCR_LSPEN;

        /* CP10 and CP11 set to full access.*/
        SCB_CPACR |= 0x00F00000;

        /* Enables FPU context save/restore on exception entry/exit (FPCA bit).*/
        __set_CONTROL(__get_CONTROL() | 4);

        /* FPSCR and FPDSCR initially zero.*/
        __set_FPSCR(0);
        SCB_FPDSCR = 0;
    }
#endif

    /* Initialization of the system vectors used by the port.*/
    nvicSetSystemHandlerPriority(HANDLER_SVCALL,
                                 CORTEX_PRIORITY_MASK(CORTEX_PRIORITY_SVCALL));
    nvicSetSystemHandlerPriority(HANDLER_PENDSV,
                                 CORTEX_PRIORITY_MASK(CORTEX_PRIORITY_PENDSV));
    nvicSetSystemHandlerPriority(HANDLER_SYSTICK,
                                 CORTEX_PRIORITY_MASK(CORTEX_PRIORITY_SYSTICK));
}
Exemplo n.º 6
0
static inline void switch_sp_to_psp(void)
{
	__set_CONTROL(__get_CONTROL() | CONTROL_SPSEL_Msk);
	/*
	 * When changing the stack pointer, software must use an ISB instruction
	 * immediately after the MSR instruction. This ensures that instructions
	 * after the ISB instruction execute using the new stack pointer.
	 */
	__ISB();
}
os_error_t
os_arch_os_init(void)
{
    os_error_t err;
    int i;

    /* Cannot be called within an ISR */
    err = OS_ERR_IN_ISR;
    if (__get_IPSR() == 0) {
        err = OS_OK;

        /* Drop priority for all interrupts */
        for (i = 0; i < sizeof(NVIC->IP); i++) {
            NVIC->IP[i] = 0xff;
        }

        /*
         * Install default interrupt handler, which'll print out system
         * state at the time of the interrupt, and few other regs which
         * should help in trying to figure out what went wrong.
         */
        NVIC_SetVector(-13, (uint32_t)os_default_irq_asm); /* Hardfault */
        NVIC_SetVector(MemoryManagement_IRQn, (uint32_t)os_default_irq_asm);
        NVIC_SetVector(BusFault_IRQn, (uint32_t)os_default_irq_asm);
        NVIC_SetVector(UsageFault_IRQn, (uint32_t)os_default_irq_asm);
        for (i = 0; i < NVIC_NUM_VECTORS - NVIC_USER_IRQ_OFFSET; i++) {
            NVIC_SetVector(i, (uint32_t)os_default_irq_asm);
        }

        /* Call bsp related OS initializations */
        os_bsp_init();

        /* Set the PendSV interrupt exception priority to the lowest priority */
        NVIC_SetPriority(PendSV_IRQn, PEND_SV_PRIO);

        /* Set the SVC interrupt to priority 0 (highest configurable) */
        NVIC_SetPriority(SVCall_IRQn, SVC_PRIO);

        /*
         * Set the os environment. This will set stack pointers and, based
         * on the contents of os_flags, will determine if the tasks run in
         * priviliged or un-privileged mode.
         */
        os_set_env();

        /* Check if privileged or not */
        if ((__get_CONTROL() & 1) == 0) {
            os_arch_init();
        } else {
            svc_os_arch_init();
        }
    }

    return err;
}
Exemplo n.º 8
0
void enter_critical(void) {
  if ((__get_CONTROL() & 3) == 3) {
    // TODO PETER
    //print("enter critical from user!!\n");
  }
#ifndef CONFIG_ARCH_CRITICAL_DISABLE_IRQ
  __disable_irq();
#else
  CONFIG_ARCH_CRITICAL_DISABLE_IRQ;
#endif
  g_crit_entry++;
  TRACE_IRQ_OFF(g_crit_entry);
}
/**
 * Start the OS. First check to see if we are running with the correct stack 
 * pointer set (PSP) and privilege mode (PRIV). 
 * 
 * 
 * @return os_error_t 
 */
os_error_t
os_arch_os_start(void)
{
    os_error_t err;

    err = OS_ERR_IN_ISR;
    if (__get_IPSR() == 0) {
        /*
         * The following switch statement is really just a sanity check to
         * insure that the os initialization routine was called prior to the
         * os start routine.
         */
        err = OS_OK;
        switch (__get_CONTROL() & 0x03) {
        /*
         * These two cases are for completeness. Thread mode should be set
         * to use PSP already.
         *
         * Fall-through intentional!
         */
        case 0x00:
        case 0x01:
            err = OS_ERR_PRIV;
            break;
        case 0x02:
            /* 
             * We are running in Privileged Thread mode w/SP = PSP but we
             * are supposed to be un-privileged.
             */
            if ((os_flags & 1) == OS_RUN_UNPRIV) {
                err = OS_ERR_PRIV;
            }
            break;
        case 0x03:
            /* 
             * We are running in Unprivileged Thread mode w/SP = PSP but we
             * are supposed to be privileged.
             */
            if  ((os_flags & 1) == OS_RUN_PRIV) {
                err = OS_ERR_PRIV;
            }
            break;
        }
        if (err == OS_OK) {
            /* Always start OS through SVC call */
            svc_os_arch_start();
        }
    }

    return err;
}
Exemplo n.º 10
0
os_error_t
os_arch_os_init(void)
{
    os_error_t err;
    int i;

    /* Cannot be called within an ISR */
    err = OS_ERR_IN_ISR;
    if (__get_IPSR() == 0) {
        err = OS_OK;

        /* Drop priority for all interrupts */
        for (i = 0; i < sizeof(NVIC->IP); i++) {
            NVIC->IP[i] = -1;
        }

        NVIC_SetVector(SVCall_IRQn, (uint32_t)SVC_Handler);
        NVIC_SetVector(PendSV_IRQn, (uint32_t)PendSV_Handler);
        NVIC_SetVector(SysTick_IRQn, (uint32_t)SysTick_Handler);

        /*
         * Install default interrupt handler, which'll print out system
         * state at the time of the interrupt, and few other regs which
         * should help in trying to figure out what went wrong.
         */
        NVIC_SetVector(NonMaskableInt_IRQn, (uint32_t)os_default_irq_asm);
        NVIC_SetVector(HardFault_IRQn, (uint32_t)os_default_irq_asm);
        NVIC_SetVector(-13, (uint32_t)os_default_irq_asm); /* Hardfault */
        for (i = 0; i < NVIC_NUM_VECTORS - NVIC_USER_IRQ_OFFSET; i++) {
            NVIC_SetVector(i, (uint32_t)os_default_irq_asm);
        }

        /* Set the PendSV interrupt exception priority to the lowest priority */
        NVIC_SetPriority(PendSV_IRQn, PEND_SV_PRIO);

        /* Set the SVC interrupt to priority 0 (highest configurable) */
        NVIC_SetPriority(SVCall_IRQn, SVC_PRIO);

        /* Check if privileged or not */
        if ((__get_CONTROL() & 1) == 0) {
            os_arch_init();
        } else {
            svc_os_arch_init();
        }
    }

    return err;
}
Exemplo n.º 11
0
/* call scheduler so active_thread points to the next task */
void sched_task_return(void)
{
    /* switch to user mode use PSP insteat of MSP in ISR Mode*/
    CONTROL_Type mode;
    mode.w = __get_CONTROL();
    mode.b.SPSEL = 1; // select PSP
    mode.b.nPRIV = 0; // privilege
    __set_CONTROL(mode.w);
    /* load pdc->stackpointer in r0 */
    asm("ldr     r0, =active_thread"); /* r0 = &active_thread */
    asm("ldr     r0, [r0]"); /* r0 = *r0 = active_thread */
    asm("ldr     sp, [r0]"); /* sp = r0  restore stack pointer*/
    asm("pop		{r4}"); /* skip exception return */
    asm("pop		{r4-r11}");
    asm("pop		{r0-r3,r12,lr}"); /* simulate register restor from stack */
    asm("pop		{pc}");
}
Exemplo n.º 12
0
void jump_to_ns_code(void)
{
#if TFM_LVL != 1
    /* Initialization is done, set thread mode to unprivileged. */
    CONTROL_Type ctrl;

    ctrl.w = __get_CONTROL();
    ctrl.b.nPRIV = 1;
    __set_CONTROL(ctrl.w);
#endif
    /* All changes made to memory will be effective after this point */
    __DSB();
    __ISB();

    /* Calls the non-secure Reset_Handler to jump to the non-secure binary */
    ns_entry();
}
Exemplo n.º 13
0
void nOS_InitSpecific(void)
{
#if (NOS_CONFIG_DEBUG > 0)
    size_t i;

    for (i = 0; i < NOS_CONFIG_ISR_STACK_SIZE; i++) {
        _isrStack[i] = 0xFFFFFFFFUL;
    }
#endif

    /* Copy MSP to PSP */
    __set_PSP(__get_MSP());
    /* Set MSP to local ISR stack */
    __set_MSP((uint32_t)&_isrStack[NOS_CONFIG_ISR_STACK_SIZE] & 0xFFFFFFF8UL);
    /* Set current stack to PSP and privileged mode */
    __set_CONTROL(__get_CONTROL() | 0x00000002UL);
    /* Set PendSV exception to lowest priority */
    *(volatile uint32_t *)0xE000ED20UL |= 0x00FF0000UL;
}
Exemplo n.º 14
0
Arquivo: swap.c Projeto: kraj/zephyr
/**
 *
 * @brief Initiate a cooperative context switch
 *
 * The __swap() routine is invoked by various kernel services to effect
 * a cooperative context context switch.  Prior to invoking __swap(), the caller
 * disables interrupts via irq_lock() and the return 'key' is passed as a
 * parameter to __swap().  The 'key' actually represents the BASEPRI register
 * prior to disabling interrupts via the BASEPRI mechanism.
 *
 * __swap() itself does not do much.
 *
 * It simply stores the intlock key (the BASEPRI value) parameter into
 * current->basepri, and then triggers a PendSV exception, which does
 * the heavy lifting of context switching.

 * This is the only place we have to save BASEPRI since the other paths to
 * __pendsv all come from handling an interrupt, which means we know the
 * interrupts were not locked: in that case the BASEPRI value is 0.
 *
 * Given that __swap() is called to effect a cooperative context switch,
 * only the caller-saved integer registers need to be saved in the thread of the
 * outgoing thread. This is all performed by the hardware, which stores it in
 * its exception stack frame, created when handling the svc exception.
 *
 * On ARMv6-M, the intlock key is represented by the PRIMASK register,
 * as BASEPRI is not available.
 *
 * @return -EAGAIN, or a return value set by a call to
 * _set_thread_return_value()
 *
 */
int __swap(int key)
{
#ifdef CONFIG_USERSPACE
	/* Save off current privilege mode */
	_current->arch.mode = __get_CONTROL() & CONTROL_nPRIV_Msk;
#endif
#ifdef CONFIG_EXECUTION_BENCHMARKING
	read_timer_start_of_swap();
#endif

	/* store off key and return value */
	_current->arch.basepri = key;
	_current->arch.swap_return_value = _k_neg_eagain;

	/* set pending bit to make sure we will take a PendSV exception */
	SCB->ICSR |= SCB_ICSR_PENDSVSET_Msk;

	/* clear mask or enable all irqs to take a pendsv */
	irq_unlock(0);

	return _current->arch.swap_return_value;
}
Exemplo n.º 15
0
/**
\brief Test case: TC_CoreFunc_MSP
\details
- Check if __get_MSP and __set_MSP intrinsic can be used to manipulate main stack pointer.
*/
void TC_CoreFunc_MSP (void) {
  // don't use stack for this variables
  static uint32_t orig;
  static uint32_t msp;
  static uint32_t result;
  static uint32_t ctrl;

  ctrl = __get_CONTROL();
  __set_CONTROL(ctrl | CONTROL_SPSEL_Msk); // switch to PSP

  orig = __get_MSP();

  msp = orig + 0x12345678U;
  __set_MSP(msp);

  result = __get_MSP();

  __set_MSP(orig);

  __set_CONTROL(ctrl);

  ASSERT_TRUE(result == msp);
}
Exemplo n.º 16
0
Task* usr_task_create_dynamic(const char* name, TASK_FUNCTION func,
		unsigned char priority, unsigned int stack_words)
{
	Task* task;

	//Allocate task control block and stack
	stack_words = (stack_words * 4) + sizeof(TASK_STRU);
	if (__get_CONTROL() & 2)
	{
		task = (Task*)((unsigned int)usr_malloc(stack_words+4) +4);
	} else
	{
		task = (Task*)((unsigned int)svc_malloc(stack_words+4)+4);
	}

	if(task)
	{
		TASK_STACKED_CTX ctx;
		ctx = (TASK_STACKED_CTX) (((unsigned int)task) + stack_words);
		ctx--;
		ctx->psr.as_int = 0x01000000; //thumb mode
		ctx->pc.as_voidptr = (void*) func;
		ctx->lr.as_voidptr = (void*) sys_task_return;

		task->sp = ctx;

		task->priority = priority;
		task->time = main_task.time;
		task->prev = task->next = task->tprev = task->tnext = task;
		task->signals = 0;
		task->aloc_sig = 0;
		task->state = TSKSTATE_SUSPEND;
		strcpy(task->name, name);
	}

	return (task);
}
Exemplo n.º 17
0
os_error_t
os_arch_os_init(void)
{
    os_error_t err;

    /* Cannot be called within an ISR */
    err = OS_ERR_IN_ISR;
    if (__get_IPSR() == 0) {
        err = OS_OK;

        /* Call bsp related OS initializations */
        os_bsp_init();

        /* Set the PendSV interrupt exception priority to the lowest priority */
        NVIC_SetPriority(PendSV_IRQn, PEND_SV_PRIO);

        /* Set the SVC interrupt to priority 0 (highest configurable) */
        NVIC_SetPriority(SVCall_IRQn, SVC_PRIO);

        /*
         * Set the os environment. This will set stack pointers and, based
         * on the contents of os_flags, will determine if the tasks run in
         * priviliged or un-privileged mode.
         */
        os_set_env();

        /* Check if priviliged or not */
        if ((__get_CONTROL() & 1) == 0) {
            os_arch_init();
        } else {
            svc_os_arch_init();
        }
    }

    return err;
}
Exemplo n.º 18
0
/**
 * Task init
 * @param desc
 * @param bStart
 */
void usr_task_init_static(TASK_DESCRIPTION const * desc, int bStart)
{
	Task *task;
	TASK_STACKED_CTX ctx;

	ctx = (TASK_STACKED_CTX) desc->stack;
	ctx--;
	ctx->psr.as_int = 0x01000000; //thumb mode
	ctx->pc.as_voidptr = (void*) desc->func;
	ctx->lr.as_voidptr = (void*) sys_task_return;

	task = desc->tsk;
	task->sp = ctx;

	task->priority = desc->priority;
	task->time = main_task.time;
	task->prev = task->next = task->tprev = task->tnext = task;
	task->signals = 0;
	task->aloc_sig = 0;
	task->state = TSKSTATE_SUSPEND;
	for (int i = 0;; i++)
	{
		if (!(task->name[i] = desc->name[i]))
			break;
	}

	if (bStart)
	{
		if (__get_CONTROL() & 2)

			usr_task_schedule(task);

		else
			svc_task_schedule(task);
	}
}
Exemplo n.º 19
0
/**
  * @brief  Main program.
  * @param  None
  * @retval None
  */
int main(void)
{
  /* STM32F4xx HAL library initialization:
       - Configure the Flash prefetch
       - Systick timer is configured by default as source of time base, but user 
         can eventually implement his proper time base source (a general purpose 
         timer for example or other time source), keeping in mind that Time base 
         duration should be kept 1ms since PPP_TIMEOUT_VALUEs are defined and 
         handled in milliseconds basis.
       - Set NVIC Group Priority to 4
       - Low Level Initialization
     */
  HAL_Init();

  /* Configure the system clock to have a system clock = 180 MHz */
  SystemClock_Config();

  /* Configure LED1*/
  BSP_LED_Init(LED1);

  /* Switch Thread mode Stack from Main to Process -----------------------------*/
  /* Initialize memory reserved for Process Stack */
  for(Index = 0; Index < SP_PROCESS_SIZE; Index++)
  {
    PSPMemAlloc[Index] = 0x00;
  }

  /* Set Process stack value */
  __set_PSP((uint32_t)PSPMemAlloc + SP_PROCESS_SIZE);

  /* Select Process Stack as Thread mode Stack */
  __set_CONTROL(SP_PROCESS);

  /* Execute ISB instruction to flush pipeline as recommended by Arm */
  __ISB(); 

  /* Get the Thread mode stack used */
  if((__get_CONTROL() & 0x02) == SP_MAIN)
  {
    /* Main stack is used as the current stack */
    CurrentStack = SP_MAIN;
  }
  else
  {
    /* Process stack is used as the current stack */
    CurrentStack = SP_PROCESS;

    /* Get process stack pointer value */
    PSPValue = __get_PSP();
  }

  /* Switch Thread mode from privileged to unprivileged ------------------------*/
  /* Thread mode has unprivileged access */
  __set_CONTROL(THREAD_MODE_UNPRIVILEGED | SP_PROCESS);
  
  /* Execute ISB instruction to flush pipeline as recommended by Arm */
  __ISB(); 

  /* Unprivileged access mainly affect ability to:
      - Use or not use certain instructions such as MSR fields
      - Access System Control Space (SCS) registers such as NVIC and SysTick */

  /* Check Thread mode privilege status */
  if((__get_CONTROL() & 0x01) == THREAD_MODE_PRIVILEGED)
  {
    /* Thread mode has privileged access  */
    ThreadMode = THREAD_MODE_PRIVILEGED;
  }
  else
  {
    /* Thread mode has unprivileged access*/
    ThreadMode = THREAD_MODE_UNPRIVILEGED;
  }

  /* Switch back Thread mode from unprivileged to privileged -------------------*/
  /* Try to switch back Thread mode to privileged (Not possible, this can be
     done only in Handler mode) */
  __set_CONTROL(THREAD_MODE_PRIVILEGED | SP_PROCESS);

  /* Execute ISB instruction to flush pipeline as recommended by Arm */
  __ISB(); 

  /* Generate a system call exception, and in the ISR switch back Thread mode
    to privileged */
  __SVC();

  /* Check Thread mode privilege status */
  if((__get_CONTROL() & 0x01) == THREAD_MODE_PRIVILEGED)
  {
    /* Thread mode has privileged access  */
    ThreadMode = THREAD_MODE_PRIVILEGED;
  }
  else
  {
    /* Thread mode has unprivileged access*/
    ThreadMode = THREAD_MODE_UNPRIVILEGED;
  }

  /* Infinite loop */
  while (1)
  {
    /* Turn ON LED once test finished */
    BSP_LED_On(LED1);
  }
}
Exemplo n.º 20
0
/**
  * @brief  Main program
  * @param  None
  * @retval None
  */
int main(void)
{
    /* STM32F4xx HAL library initialization:
         - Configure the Flash prefetch, instruction and Data caches
         - Configure the Systick to generate an interrupt each 1 msec
         - Set NVIC Group Priority to 4
         - Global MSP (MCU Support Package) initialization
       */
    HAL_Init();

    /* Configure the system clock to 180 MHz */
    SystemClock_Config();

    /* Switch Thread mode Stack from Main to Process ###########################*/
    /* Initialize memory reserved for Process Stack */
    for(Index = 0; Index < SP_PROCESS_SIZE; Index++)
    {
        PSPMemAlloc[Index] = 0x00;
    }

    /* Set Process stack value */
    __set_PSP((uint32_t)PSPMemAlloc + SP_PROCESS_SIZE);

    /* Select Process Stack as Thread mode Stack */
    __set_CONTROL(SP_PROCESS);

    /* Execute ISB instruction to flush pipeline as recommended by Arm */
    __ISB();

    /* Get the Thread mode stack used */
    if((__get_CONTROL() & 0x02) == SP_MAIN)
    {
        /* Main stack is used as the current stack */
        CurrentStack = SP_MAIN;
    }
    else
    {
        /* Process stack is used as the current stack */
        CurrentStack = SP_PROCESS;

        /* Get process stack pointer value */
        PSPValue = __get_PSP();
    }

    /* Switch Thread mode from privileged to unprivileged ######################*/
    /* Thread mode has unprivileged access */
    __set_CONTROL(THREAD_MODE_UNPRIVILEGED | SP_PROCESS);

    /* Execute ISB instruction to flush pipeline as recommended by Arm */
    __ISB();

    /* Unprivileged access mainly affect ability to:
    - Use or not use certain instructions such as MSR fields
    - Access System Control Space (SCS) registers such as NVIC and SysTick */

    /* Check Thread mode privilege status */
    if((__get_CONTROL() & 0x01) == THREAD_MODE_PRIVILEGED)
    {
        /* Thread mode has privileged access  */
        ThreadMode = THREAD_MODE_PRIVILEGED;
    }
    else
    {
        /* Thread mode has unprivileged access*/
        ThreadMode = THREAD_MODE_UNPRIVILEGED;
    }

    /* Switch back Thread mode from unprivileged to privileged #################*/
    /* Try to switch back Thread mode to privileged (Not possible, this can be
    done only in Handler mode) */
    __set_CONTROL(THREAD_MODE_PRIVILEGED | SP_PROCESS);

    /* Execute ISB instruction to flush pipeline as recommended by Arm */
    __ISB();

    /* Generate a system call exception, and in the ISR switch back Thread mode
    to privileged */
    __SVC();

    /* Check Thread mode privilege status */
    if((__get_CONTROL() & 0x01) == THREAD_MODE_PRIVILEGED)
    {
        /* Thread mode has privileged access */
        ThreadMode = THREAD_MODE_PRIVILEGED;
    }
    else
    {
        /* Thread mode has unprivileged access */
        ThreadMode = THREAD_MODE_UNPRIVILEGED;
    }

    /* Infinite loop */
    while (1)
    {
    }
}
Exemplo n.º 21
0
/**
 * @brief This function check the privilege mode status
 * @return priviledge_status
 */
uint8_t BSP_Check_Priviledge_Status(void)
{
  priviledge_status = __get_CONTROL();
  return (uint8_t)(priviledge_status & ~(THREAD_PRIVILEDGED_MASK));
}
Exemplo n.º 22
0
/**
  * @brief  Main program.
  * @param  None
  * @retval None
  */
int main(void)
{
  /* STM32F0xx HAL library initialization:
       - Configure the Flash prefetch
       - Systick timer is configured by default as source of time base, but user 
         can eventually implement his proper time base source (a general purpose 
         timer for example or other time source), keeping in mind that Time base 
         duration should be kept 1ms since PPP_TIMEOUT_VALUEs are defined and 
         handled in milliseconds basis.
       - Low Level Initialization
     */
  HAL_Init();

  /* Configure LED2*/
  BSP_LED_Init(LED2);

  /* Configure the system clock to have a system clock = 48 MHz */
  SystemClock_Config();

  /* Switch Thread mode Stack from Main to Process -----------------------------*/
  /* Initialize memory reserved for Process Stack */
  for(Index = 0; Index < SP_PROCESS_SIZE; Index++)
  {
    PSPMemAlloc[Index] = 0x00;
  }

  /* Set Process stack value */
  __set_PSP((uint32_t)PSPMemAlloc + SP_PROCESS_SIZE);

  /* Select Process Stack as Thread mode Stack */
  __set_CONTROL(SP_PROCESS);

  /* Execute ISB instruction to flush pipeline as recommended by Arm */
  __ISB();

  /* Get the Thread mode stack used */
  CurrentStack = (__get_CONTROL() & 0x02);

    /* Get process stack pointer value */
    PSPValue = __get_PSP();
  
  /* Check is mode has been well applied */
  if(CurrentStack != SP_PROCESS)
  {
    Error_Handler();
  }

  /* Generate a system call exception: Main Stack pointer should be automaticcaly 
  when entering in ISR context */
  __SVC();

  /* Check is Main stack was used under ISR*/
  if(IsrStack != SP_MAIN)
  {
    Error_Handler();
  }

  /* Get the Thread mode stack used to verify we have switched back automatically 
  to Process Stack */
  
  CurrentStack = (__get_CONTROL() & 0x02);
  
  /* Check is mode has been well applied */
  if(CurrentStack != SP_PROCESS)
  {
    Error_Handler();
  }
  else
  {
    /* Turn LED2 On*/
    BSP_LED_On(LED2);
  }

  /* Infinite loop */
  while (1)
  {
  }
}
Exemplo n.º 23
0
static void disableFPU()
{
    static const uint32_t FPCA = 1 << 2;
    SCB->CPACR &= ~(0xF << 20);
    __set_CONTROL(__get_CONTROL() & ~FPCA);
}
Exemplo n.º 24
0
/**
 * Start the OS. First check to see if we are running with the correct stack
 * pointer set (PSP) and privilege mode (PRIV).
 *
 * @return os_error_t
 */
os_error_t
os_arch_os_start(void)
{
    os_error_t err;

    /*
     * Set the os environment. This will set stack pointers and, based
     * on the contents of os_flags, will determine if the tasks run in
     * priviliged or un-privileged mode.
     *
     * We switch to using "empty" part of idle task's stack until
     * the svc_os_arch_start() executes SVC, and we will never return.
     */
    os_set_env(g_idle_task.t_stackptr - 1);

    err = OS_ERR_IN_ISR;
    if (__get_IPSR() == 0) {
        /*
         * The following switch statement is really just a sanity check to
         * insure that the os initialization routine was called prior to the
         * os start routine.
         */
        err = OS_OK;
        switch (__get_CONTROL() & 0x03) {
        /*
         * These two cases are for completeness. Thread mode should be set
         * to use PSP already.
         *
         * Fall-through intentional!
         */
        case 0x00:
        case 0x01:
            err = OS_ERR_PRIV;
            break;
        case 0x02:
            /*
             * We are running in Privileged Thread mode w/SP = PSP but we
             * are supposed to be un-privileged.
             */
            if ((os_flags & 1) == OS_RUN_UNPRIV) {
                err = OS_ERR_PRIV;
            }
            break;
        case 0x03:
            /*
             * We are running in Unprivileged Thread mode w/SP = PSP but we
             * are supposed to be privileged.
             */
            if  ((os_flags & 1) == OS_RUN_PRIV) {
                err = OS_ERR_PRIV;
            }
            break;
        }
        if (err == OS_OK) {
            /* Always start OS through SVC call */
            svc_os_arch_start();
        }
    }

    return err;
}
Exemplo n.º 25
0
static int32_t tfm_start_partition(const struct tfm_sfn_req_s *desc_ptr,
                                                             uint32_t excReturn)
{
    uint32_t caller_partition_idx = desc_ptr->caller_part_idx;
    const struct spm_partition_runtime_data_t *curr_part_data;
    uint32_t caller_flags;
    register uint32_t partition_idx;
    uint32_t psp = __get_PSP();
    uint32_t partition_psp, partition_psplim;
    uint32_t partition_state;
    uint32_t partition_flags;
    struct tfm_exc_stack_t *svc_ctx = (struct tfm_exc_stack_t *)psp;
    uint32_t caller_partition_id;
    int32_t client_id;
    struct iovec_args_t *iovec_args;

    caller_flags = tfm_spm_partition_get_flags(caller_partition_idx);

    /* Check partition state consistency */
    if (((caller_flags & SPM_PART_FLAG_APP_ROT) != 0)
        != (!desc_ptr->ns_caller)) {
        /* Partition state inconsistency detected */
        return TFM_SECURE_LOCK_FAILED;
    }

    if((caller_flags & SPM_PART_FLAG_APP_ROT) == 0) {
        /* Disable NS exception handling while secure service is running.
         * FixMe:
         * This restriction is applied to limit the number of possible attack
         * vectors.
         * To be removed when pre-emption and context management issues have
         * been analysed and resolved.
         */
        TFM_NS_EXC_DISABLE();
    }

    partition_idx = get_partition_idx(desc_ptr->sp_id);

    curr_part_data = tfm_spm_partition_get_runtime_data(partition_idx);
    partition_state = curr_part_data->partition_state;
    partition_flags = tfm_spm_partition_get_flags(partition_idx);
    caller_partition_id = tfm_spm_partition_get_partition_id(
                                                          caller_partition_idx);

    if (tfm_secure_api_initializing) {
#if TFM_LVL != 1
        /* Make thread mode unprivileged while untrusted partition init is
         * executed
         */
        if ((partition_flags & SPM_PART_FLAG_PSA_ROT) == 0) {
            CONTROL_Type ctrl;

            ctrl.w = __get_CONTROL();
            ctrl.b.nPRIV = 1;
            __set_CONTROL(ctrl.w);
            __DSB();
            __ISB();
        }
#endif
    } else if (partition_state == SPM_PARTITION_STATE_RUNNING ||
        partition_state == SPM_PARTITION_STATE_SUSPENDED ||
        partition_state == SPM_PARTITION_STATE_BLOCKED) {
        /* Recursion is not permitted! */
        return TFM_ERROR_PARTITION_NON_REENTRANT;
    } else if (partition_state != SPM_PARTITION_STATE_IDLE) {
        /* The partition to be called is not in a proper state */
        return TFM_SECURE_LOCK_FAILED;
    }

#if TFM_LVL == 1
    /* Prepare switch to shared secure partition stack */
    /* In case the call is coming from the non-secure world, we save the iovecs
     * on the stop of the stack. So the memory area, that can actually be used
     * as stack by the partitions starts at a lower address
     */
    partition_psp =
        (uint32_t)&REGION_NAME(Image$$, TFM_SECURE_STACK, $$ZI$$Limit)-
        sizeof(struct iovec_args_t);
    partition_psplim =
        (uint32_t)&REGION_NAME(Image$$, TFM_SECURE_STACK, $$ZI$$Base);
#else
    partition_psp = curr_part_data->stack_ptr;
    partition_psplim = tfm_spm_partition_get_stack_bottom(partition_idx);
#endif
    /* Store the context for the partition call */
    tfm_spm_partition_set_caller_partition_idx(partition_idx,
                                               caller_partition_idx);
    tfm_spm_partition_store_context(caller_partition_idx, psp, excReturn);

    if ((caller_flags & SPM_PART_FLAG_APP_ROT)) {
        tfm_spm_partition_set_caller_client_id(partition_idx,
                                               caller_partition_id);
    } else {
        client_id = tfm_nspm_get_current_client_id();
        if (client_id >= 0)
        {
            return TFM_SECURE_LOCK_FAILED;
        }
        tfm_spm_partition_set_caller_client_id(partition_idx, client_id);
    }

#if (TFM_LVL != 1) && (TFM_LVL != 2)
    /* Dynamic partitioning is only done is TFM level 3 */
    tfm_spm_partition_sandbox_deconfig(caller_partition_idx);

    /* Configure partition execution environment */
    if (tfm_spm_partition_sandbox_config(partition_idx) != SPM_ERR_OK) {
        ERROR_MSG("Failed to configure sandbox for partition!");
        tfm_secure_api_error_handler();
    }
#endif

    /* Default share to scratch area in case of partition to partition calls
     * this way partitions always get default access to input buffers
     */
    /* FixMe: return value/error handling TBD */
    tfm_spm_partition_set_share(partition_idx, desc_ptr->ns_caller ?
        TFM_BUFFER_SHARE_NS_CODE : TFM_BUFFER_SHARE_SCRATCH);

#if TFM_LVL == 1
    /* In level one, only switch context and return from exception if in
     * handler mode
     */
    if ((desc_ptr->ns_caller) || (tfm_secure_api_initializing)) {
        if (desc_ptr->iovec_api == TFM_SFN_API_IOVEC) {
            /* Save the iovecs on the common stack. The vectors had been sanity
             * checked already, and since then the interrupts have been kept
             * disabled. So we can be sure that the vectors haven't been
             * tampered with since the check.
             */
            iovec_args = (struct iovec_args_t *)
                    ((uint32_t)&REGION_NAME(Image$$, TFM_SECURE_STACK, $$ZI$$Limit)-
                     sizeof(struct iovec_args_t));
            if (tfm_spm_partition_set_iovec(partition_idx, desc_ptr->args) !=
                SPM_ERR_OK) {
                return TFM_ERROR_GENERIC;
            }
            tfm_copy_iovec_parameters(iovec_args,
                                      &(curr_part_data->iovec_args));

            /* Prepare the partition context, update stack ptr */
            psp = (uint32_t)prepare_partition_iovec_ctx(svc_ctx, desc_ptr,
                                                        iovec_args,
                                                     (uint32_t *)partition_psp);
        } else {
            /* Prepare the partition context, update stack ptr */
            psp = (uint32_t)prepare_partition_ctx(svc_ctx, desc_ptr,
                                                  (uint32_t *)partition_psp);
        }
        __set_PSP(psp);
        __set_PSPLIM(partition_psplim);
    }
#else
    if (desc_ptr->iovec_api == TFM_SFN_API_IOVEC) {
        /* Save the iovecs on the stack of the partition. The vectors had been
         * sanity checked already, and since then the interrupts have been kept
         * disabled. So we can be sure that the vectors haven't been tampered
         * with since the check.
         */
        iovec_args =
        (struct iovec_args_t *)(tfm_spm_partition_get_stack_top(partition_idx) -
        sizeof(struct iovec_args_t));
        if (tfm_spm_partition_set_iovec(partition_idx, desc_ptr->args) !=
            SPM_ERR_OK) {
            return TFM_ERROR_GENERIC;
        }
        tfm_copy_iovec_parameters(iovec_args, &(curr_part_data->iovec_args));

        /* Prepare the partition context, update stack ptr */
        psp = (uint32_t)prepare_partition_iovec_ctx(svc_ctx, desc_ptr,
                                                    iovec_args,
                                                    (uint32_t *)partition_psp);
    } else {
        /* Prepare the partition context, update stack ptr */
        psp = (uint32_t)prepare_partition_ctx(svc_ctx, desc_ptr,
                                              (uint32_t *)partition_psp);
    }
    __set_PSP(psp);
    __set_PSPLIM(partition_psplim);
#endif

    tfm_spm_partition_set_state(caller_partition_idx,
                                SPM_PARTITION_STATE_BLOCKED);
    tfm_spm_partition_set_state(partition_idx, SPM_PARTITION_STATE_RUNNING);
    tfm_secure_lock++;

    return TFM_SUCCESS;
}
Exemplo n.º 26
0
void DAC_DCR(DAC_DRIVER_INFO* drv_info, unsigned int reason, HANDLE hnd)
{
	DAC_DRIVER_DATA *drv_data = drv_info->drv_data;
	DAC_DRIVER_MODE *dac_mode = (DAC_DRIVER_MODE *)(hnd->mode.as_voidptr);

	switch(reason)
	{
		case DCR_RESET:
			RCCPeripheralReset(drv_info->info.peripheral_indx);
			RCCPeripheralDisable(drv_info->info.peripheral_indx); // ??? turn off
#if USE_DAC_DMA_DRIVER
        	drv_data->dac_dma_hnd[0].client.drv_index = drv_info->info.drv_index;
        	drv_data->dac_dma_hnd[1].client.drv_index = drv_info->info.drv_index;
#endif
			break;

		case DCR_OPEN:
		{
			if(dac_mode && dac_mode->dac_ch <2 && drv_data->dac_mode[dac_mode->dac_ch] == NULL)
			{
				if(!drv_data->dac_mode[0] && !drv_data->dac_mode[1])
				{
					if(!ConfigureDac(drv_info))
						break;
				}
				ConfigureDacChannel(drv_info->hw_base, dac_mode);

				drv_data->dac_mode[dac_mode->dac_ch] = dac_mode;
				hnd->res = RES_OK;
			}
			break;
		}

		case DCR_CLOSE:
#if USE_DAC_DMA_DRIVER
			drv_data->dac_dma_hnd[dac_mode->dac_ch].close();
#endif
			drv_data->dac_mode[dac_mode->dac_ch] = NULL;
			if(!drv_data->dac_mode[0] && !drv_data->dac_mode[1])
			{
				//Disable ?
				NVIC_DisableIRQ(drv_info->info.drv_index);
				RCCPeripheralDisable(drv_info->info.peripheral_indx);

				PIO_Free_List(drv_info->dac_pins);
			}
			break;

		case DCR_CANCEL:
			// can only cancel dma transfers
#if USE_DAC_DMA_DRIVER
			if(drv_data->dac_dma_hnd[dac_mode->dac_ch].res & FLG_BUSY)
				drv_data->dac_dma_hnd[dac_mode->dac_ch].hcontrol(DCR_CANCEL);
#endif
			break;


		case DCR_SIGNAL:
#if USE_DAC_DMA_DRIVER
			TRACELN1("DAC sig");
			if(hnd == &drv_data->dac_dma_hnd[0])
			{

				hnd = drv_data->pending[0];
				if(hnd)
				{
					if(hnd->len > drv_data->dac_dma_hnd[0].len)
					{
						hnd->src.as_byteptr += hnd->len - drv_data->dac_dma_hnd[0].len;
						hnd->len = drv_data->dac_dma_hnd[0].len;
					}
					drv_data->pending[0] = NULL;
					if (__get_CONTROL() & 2)
						usr_HND_SET_STATUS(hnd, RES_SIG_OK);
					else
						svc_HND_SET_STATUS(hnd, RES_SIG_OK);
				}
			} else
			{
				if(hnd == &drv_data->dac_dma_hnd[1])
				{

					hnd = drv_data->pending[1];
					if(hnd)
					{
						if(hnd->len > drv_data->dac_dma_hnd[1].len)
						{
							hnd->src.as_byteptr += hnd->len - drv_data->dac_dma_hnd[1].len;
							hnd->len = drv_data->dac_dma_hnd[1].len;
						}
						drv_data->pending[1] = NULL;
						usr_HND_SET_STATUS(hnd, RES_SIG_OK);
					}
				}
			}
#endif
			break;

	}
}
Exemplo n.º 27
0
static int32_t tfm_return_from_partition(uint32_t *excReturn)
{
    uint32_t current_partition_idx =
            tfm_spm_partition_get_running_partition_idx();
    const struct spm_partition_runtime_data_t *curr_part_data, *ret_part_data;
    uint32_t current_partition_flags;
    uint32_t return_partition_idx;
    uint32_t return_partition_flags;
    uint32_t psp = __get_PSP();
    size_t i;
    struct tfm_exc_stack_t *svc_ctx = (struct tfm_exc_stack_t *)psp;
    struct iovec_args_t *iovec_args;

    if (current_partition_idx == SPM_INVALID_PARTITION_IDX) {
        return TFM_SECURE_UNLOCK_FAILED;
    }

    curr_part_data = tfm_spm_partition_get_runtime_data(current_partition_idx);
    return_partition_idx = curr_part_data->caller_partition_idx;

    if (return_partition_idx == SPM_INVALID_PARTITION_IDX) {
        return TFM_SECURE_UNLOCK_FAILED;
    }

    ret_part_data = tfm_spm_partition_get_runtime_data(return_partition_idx);

    return_partition_flags = tfm_spm_partition_get_flags(return_partition_idx);
    current_partition_flags = tfm_spm_partition_get_flags(
            current_partition_idx);

    tfm_secure_lock--;

    if((return_partition_flags & SPM_PART_FLAG_APP_ROT) == 0) {
        /* Re-enable NS exceptions when secure service returns to NS client.
         * FixMe:
         * To be removed when pre-emption and context management issues have
         * been analysed and resolved.
         */
        TFM_NS_EXC_ENABLE();
    }

#if (TFM_LVL != 1) && (TFM_LVL != 2)
    /* Deconfigure completed partition environment */
    tfm_spm_partition_sandbox_deconfig(current_partition_idx);
    if (tfm_secure_api_initializing) {
        /* Restore privilege for thread mode during TF-M init. This is only
         * have to be done if the partition is not trusted.
         */
        if ((current_partition_flags & SPM_PART_FLAG_PSA_ROT) == 0) {
            CONTROL_Type ctrl;

            ctrl.w = __get_CONTROL();
            ctrl.b.nPRIV = 0;
            __set_CONTROL(ctrl.w);
            __DSB();
            __ISB();
        }
    } else {
        /* Configure the caller partition environment in case this was a
         * partition to partition call and returning to untrusted partition
         */
        if (tfm_spm_partition_sandbox_config(return_partition_idx)
            != SPM_ERR_OK) {
            ERROR_MSG("Failed to configure sandbox for partition!");
            tfm_secure_api_error_handler();
        }
        if (return_partition_flags & SPM_PART_FLAG_APP_ROT) {
            /* Restore share status */
            tfm_spm_partition_set_share(
                return_partition_idx,
                tfm_spm_partition_get_runtime_data(
                    return_partition_idx)->share);
        }
    }
#endif

#if TFM_LVL == 1
    if (!(return_partition_flags & SPM_PART_FLAG_APP_ROT) ||
        (tfm_secure_api_initializing)) {
        /* In TFM level 1 context restore is only done when
         * returning to NS or after initialization
         */
        /* Restore caller context */
        restore_caller_ctx(svc_ctx,
            (struct tfm_exc_stack_t *)ret_part_data->stack_ptr);
        *excReturn = ret_part_data->lr;
        __set_PSP(ret_part_data->stack_ptr);
        extern uint32_t Image$$ARM_LIB_STACK$$ZI$$Base[];
        uint32_t psp_stack_bottom = (uint32_t)Image$$ARM_LIB_STACK$$ZI$$Base;
       __set_PSPLIM(psp_stack_bottom);

        /* FIXME: The condition should be removed once all the secure service
         *        calls are done via the iovec veneers */
        if (curr_part_data->iovec_api) {
            iovec_args = (struct iovec_args_t *)
                         ((uint32_t)&REGION_NAME(Image$$, TFM_SECURE_STACK, $$ZI$$Limit)-
                         sizeof(struct iovec_args_t));

            for (i = 0; i < curr_part_data->iovec_args.out_len; ++i) {
                curr_part_data->orig_outvec[i].len = iovec_args->out_vec[i].len;
            }
            tfm_clear_iovec_parameters(iovec_args);
        }
    }
#else
    /* Restore caller context */
    restore_caller_ctx(svc_ctx,
        (struct tfm_exc_stack_t *)ret_part_data->stack_ptr);
    *excReturn = ret_part_data->lr;
    __set_PSP(ret_part_data->stack_ptr);
    __set_PSPLIM(tfm_spm_partition_get_stack_bottom(return_partition_idx));
    /* Clear the context entry before returning */
    tfm_spm_partition_set_stack(
                current_partition_idx, psp + sizeof(struct tfm_exc_stack_t));

    /* FIXME: The condition should be removed once all the secure service
     *        calls are done via the iovec veneers */
    if (curr_part_data->iovec_api) {
        iovec_args = (struct iovec_args_t *)
                     (tfm_spm_partition_get_stack_top(current_partition_idx) -
                     sizeof(struct iovec_args_t));

        for (i = 0; i < curr_part_data->iovec_args.out_len; ++i) {
            curr_part_data->orig_outvec[i].len = iovec_args->out_vec[i].len;
        }
        tfm_clear_iovec_parameters(iovec_args);
    }
#endif

    tfm_spm_partition_cleanup_context(current_partition_idx);

    tfm_spm_partition_set_state(current_partition_idx,
                                SPM_PARTITION_STATE_IDLE);
    tfm_spm_partition_set_state(return_partition_idx,
                                SPM_PARTITION_STATE_RUNNING);

    return TFM_SUCCESS;
}
Exemplo n.º 28
0
/**
  * @brief   Main program.
  * @param  None
  * @retval None
  */
int main(void)
{   
  /* Clock configuration */
  RCC_Configuration();
    
/* Switch Thread mode Stack from Main to Process -----------------------------*/
  /* Initialize memory reserved for Process Stack */
  for(Index = 0; Index < SP_PROCESS_SIZE; Index++)
  {
    PSPMemAlloc[Index] = 0x00;
  }

  /* Set Process stack value */ 
  __set_PSP((uint32_t)PSPMemAlloc + SP_PROCESS_SIZE);
  
  /* Select Process Stack as Thread mode Stack */
  __set_CONTROL(SP_PROCESS);

  /* Get the Thread mode stack used */
  if((__get_CONTROL() & 0x02) == SP_MAIN)
  {
    /* Main stack is used as the current stack */
    CurrentStack = SP_MAIN;
  }
  else
  {
    /* Process stack is used as the current stack */
    CurrentStack = SP_PROCESS;

    /* Get process stack pointer value */
    PSPValue = __get_PSP();	
  }
  
/* Switch Thread mode from privileged to unprivileged ------------------------*/
  /* Thread mode has unprivileged access */
  __set_CONTROL(THREAD_MODE_UNPRIVILEGED | SP_PROCESS);
  /* Unprivileged access mainly affect ability to:
      - Use or not use certain instructions such as MSR fields
      - Access System Control Space (SCS) registers such as NVIC and SysTick */

  /* Check Thread mode privilege status */
  if((__get_CONTROL() & 0x01) == THREAD_MODE_PRIVILEGED)
  {
    /* Thread mode has privileged access  */
    ThreadMode = THREAD_MODE_PRIVILEGED;
  }
  else
  {
    /* Thread mode has unprivileged access*/
    ThreadMode = THREAD_MODE_UNPRIVILEGED;
  }

/* Switch back Thread mode from unprivileged to privileged -------------------*/  
  /* Try to switch back Thread mode to privileged (Not possible, this can be
     done only in Handler mode) */
  __set_CONTROL(THREAD_MODE_PRIVILEGED | SP_PROCESS);

  /* Generate a system call exception, and in the ISR switch back Thread mode
    to privileged */
  __SVC();

  /* Check Thread mode privilege status */
  if((__get_CONTROL() & 0x01) == THREAD_MODE_PRIVILEGED)
  {
    /* Thread mode has privileged access  */
    ThreadMode = THREAD_MODE_PRIVILEGED;
  }
  else
  {
    /* Thread mode has unprivileged access*/
    ThreadMode = THREAD_MODE_UNPRIVILEGED;
  }

  while (1)
  {
  }
}
Exemplo n.º 29
0
/**
  * @brief   Main program.
  * @param  None
  * @retval None
  */
int main(void)
{
  /*!< At this stage the microcontroller clock setting is already configured, 
       this is done through SystemInit() function which is called from startup
       file (startup_stm32f10x_xx.s) before to branch to application main.
       To reconfigure the default setting of SystemInit() function, refer to
       system_stm32f10x.c file
     */     
       
/* Switch Thread mode Stack from Main to Process -----------------------------*/
  /* Initialize memory reserved for Process Stack */
  for(Index = 0; Index < SP_PROCESS_SIZE; Index++)
  {
    PSPMemAlloc[Index] = 0x00;
  }

  /* Set Process stack value */ 
  __set_PSP((uint32_t)PSPMemAlloc + SP_PROCESS_SIZE);
  
  /* Select Process Stack as Thread mode Stack */
  __set_CONTROL(SP_PROCESS);

  /* Get the Thread mode stack used */
  if((__get_CONTROL() & 0x02) == SP_MAIN)
  {
    /* Main stack is used as the current stack */
    CurrentStack = SP_MAIN;
  }
  else
  {
    /* Process stack is used as the current stack */
    CurrentStack = SP_PROCESS;

    /* Get process stack pointer value */
    PSPValue = __get_PSP();	
  }
  
/* Switch Thread mode from privileged to unprivileged ------------------------*/
  /* Thread mode has unprivileged access */
  __set_CONTROL(THREAD_MODE_UNPRIVILEGED | SP_PROCESS);

  /* Unprivileged access mainly affect ability to:
      - Use or not use certain instructions such as MSR fields
      - Access System Control Space (SCS) registers such as NVIC and SysTick */

  /* Check Thread mode privilege status */
  if((__get_CONTROL() & 0x01) == THREAD_MODE_PRIVILEGED)
  {
    /* Thread mode has privileged access  */
    ThreadMode = THREAD_MODE_PRIVILEGED;
  }
  else
  {
    /* Thread mode has unprivileged access*/
    ThreadMode = THREAD_MODE_UNPRIVILEGED;
  }

/* Switch back Thread mode from unprivileged to privileged -------------------*/  
  /* Try to switch back Thread mode to privileged (Not possible, this can be
     done only in Handler mode) */
  __set_CONTROL(THREAD_MODE_PRIVILEGED | SP_PROCESS);

  /* Generate a system call exception, and in the ISR switch back Thread mode
    to privileged */
  __SVC();

  /* Check Thread mode privilege status */
  if((__get_CONTROL() & 0x01) == THREAD_MODE_PRIVILEGED)
  {
    /* Thread mode has privileged access  */
    ThreadMode = THREAD_MODE_PRIVILEGED;
  }
  else
  {
    /* Thread mode has unprivileged access*/
    ThreadMode = THREAD_MODE_UNPRIVILEGED;
  }

  while (1)
  {
  }
}
Exemplo n.º 30
0
/*********************************************************************//**
 * @brief		c_entry: main function
 * @param[in]	none
 * @return 		int
 **********************************************************************/
int c_entry(void)			/* Main Program */
{
	uint32_t priviledge_status;
	/* Initialize debug via UART0
	 * – 115200bps
	 * – 8 data bit
	 * – No parity
	 * – 1 stop bit
	 * – No flow control
	 */
	debug_frmwrk_init();
	LED_Init();
	//print menu
	_DBG(menu);
	_DBG_(menu2);

	/* Thread mode is privilege out of reset */
	/* First checking Thread mode is privilege or un-privilege */
	priviledge_status = __get_CONTROL();
	if((priviledge_status & (~THREAD_PRIVILEDGED_MASK))==THREAD_PRIVILEGED)
	{
		_DBG_("Thread mode is privileged!");
		Turn_on_LED(PRIVILEGE_LED);
	}
	else
	{
		_DBG_("Theard mode is unprivileged! It's not compliant with Cortex-M3 Technical");
		while(1); //Error loop
	}
	/* Wait user press '1' character to change to un-privilege mode */
	_DBG_("Press '1' to change to unprivilege mode ...\n\r");
	while(_DG !='1');

	/* Changing to un-privilege mode */
	__set_CONTROL((priviledge_status & THREAD_PRIVILEDGED_MASK)|THREAD_UNPRIVILEGED);
	_DBG_("Changed to unprivilege mode!");

	/* Check */
	priviledge_status = __get_CONTROL();
	if((priviledge_status & ~THREAD_PRIVILEDGED_MASK)==THREAD_UNPRIVILEGED)
	{
		_DBG_("Check: Thread mode change to unprivilege successful!");
		Turn_off_LED(PRIVILEGE_LED);
		Turn_on_LED(UNPRIVILEGE_LED);
	}
	else
	{
		_DBG_("Check: Thread mode is still privileged! ERROR...");
		while(1); //Error loop
	}
	/* Wait user press '1' character to change to un-privilege mode */
	_DBG_("Press '2' to change to privilege mode by calling system call exception...\n\r");
	while(_DG !='2');
	/* Call system call exception to re-change Thread mode into privilege */
	__SVC();
	_DBG_("Called system call exception!");

	/* Check */
	priviledge_status = __get_CONTROL();
	if((priviledge_status & ~THREAD_PRIVILEDGED_MASK)==THREAD_PRIVILEGED)
	{
		_DBG_("Check: Thread mode change to privilege successful!");
		Turn_off_LED(UNPRIVILEGE_LED);
		Turn_on_LED(PRIVILEGE_LED);
	}
	else
	{
		_DBG_("Check: Theard mode is still unprivileged! ERROR...");
		while(1); //Error loop
	}
	_DBG_("Demo terminate!");
	while (1);
	return 0;
}