blob: 76a274f2e22da132bd77fe9e3fbaf6f1a1c1cb4e [file] [log] [blame]
/*
* Copyright (c) 2018-2021, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
#ifndef __TFM_THREAD_H__
#define __TFM_THREAD_H__
#include <stdint.h>
#include <stddef.h>
#include "tfm_arch.h"
#include "cmsis_compiler.h"
/* State code */
#define THRD_STATE_CREATING 0
#define THRD_STATE_RUNNABLE 1
#define THRD_STATE_BLOCK 2
#define THRD_STATE_DETACH 3
#define THRD_STATE_INVALID 4
/* Security attribute - default as security */
#define THRD_ATTR_SECURE_OFFSET 16
#define THRD_ATTR_SECURE (0)
#define THRD_ATTR_NON_SECURE (1 << THRD_ATTR_SECURE_OFFSET)
/* Lower value has higher priority */
#define THRD_PRIOR_MASK 0xFF
#define THRD_PRIOR_HIGHEST 0x0
#define THRD_PRIOR_HIGH 0xF
#define THRD_PRIOR_MEDIUM 0x1F
#define THRD_PRIOR_LOW 0x7F
#define THRD_PRIOR_LOWEST 0xFF
/* Error code */
#define THRD_SUCCESS 0
#define THRD_ERR_INVALID_PARAM 1
/* Thread entry function type */
typedef void *(*tfm_core_thrd_entry_t)(void *);
/* Thread context */
struct tfm_core_thread_t {
tfm_core_thrd_entry_t pfn; /* entry function */
void *param; /* entry parameter */
uintptr_t stk_btm; /* stack bottom (lower address) */
uintptr_t stk_top; /* stack top (higher address)*/
uintptr_t flih_ctx; /* FLIH context pointer */
uint32_t prior; /* priority */
uint32_t state; /* state */
struct tfm_arch_ctx_t arch_ctx; /* State context */
struct tfm_core_thread_t *next; /* next thread in list */
};
/*
* Initialize a thread context with the necessary info.
*
* Parameters :
* pth - pointer of caller provided thread context
* pfn - thread entry function
* param - thread entry function parameter
* stk_top - stack pointer top (higher address)
* stk_btm - stack pointer bottom (lower address)
*
* Notes :
* Thread contex rely on caller allocated memory; initialize members in
* context. This function does not insert thread into schedulable list.
*/
void tfm_core_thrd_init(struct tfm_core_thread_t *pth,
tfm_core_thrd_entry_t pfn, void *param,
uintptr_t stk_top, uintptr_t stk_btm);
/*
* Set thread priority.
*
* Parameters :
* pth - pointer of thread context
* prior - priority value (0~255)
*
* Notes :
* Set thread priority. Priority is set to THRD_PRIOR_MEDIUM in
* tfm_core_thrd_init().
*/
void __STATIC_INLINE tfm_core_thrd_set_priority(struct tfm_core_thread_t *pth,
uint32_t prior)
{
pth->prior &= ~THRD_PRIOR_MASK;
pth->prior |= prior & THRD_PRIOR_MASK;
}
/*
* Set thread security attribute.
*
* Parameters :
* pth - pointer of thread context
* attr_secure - THRD_ATTR_SECURE or THRD_ATTR_NON_SECURE
*
* Notes
* Reuse prior of thread context to shift down non-secure thread priority.
*/
void __STATIC_INLINE tfm_core_thrd_set_secure(struct tfm_core_thread_t *pth,
uint32_t attr_secure)
{
pth->prior &= ~THRD_ATTR_NON_SECURE;
pth->prior |= attr_secure;
}
/*
* Set thread state.
*
* Parameters :
* pth - pointer of thread context
* new_state - new state of thread
*
* Return :
* None
*
* Notes :
* Thread state is not changed if invalid state value inputed.
*/
void tfm_core_thrd_set_state(struct tfm_core_thread_t *pth, uint32_t new_state);
/*
* Get thread state.
*
* Parameters :
* pth - pointer of thread context
*
* Return :
* State of thread
*/
uint32_t __STATIC_INLINE tfm_core_thrd_get_state(struct tfm_core_thread_t *pth)
{
return pth->state;
}
/*
* Set thread state return value.
*
* Parameters :
* pth - pointer of thread context
* retval - return value to be set for thread state
*
* Notes :
* This API is useful for blocked syscall blocking thread. Syscall
* could set its return value to the caller before caller goes.
*/
void __STATIC_INLINE tfm_core_thrd_set_retval(struct tfm_core_thread_t *pth,
uint32_t retval)
{
TFM_STATE_RET_VAL(&pth->arch_ctx) = retval;
}
/*
* Validate thread context and insert it into schedulable list.
*
* Parameters :
* pth - pointer of thread context
*
* Return :
* THRD_SUCCESS for success. Or an error is returned.
*
* Notes :
* This function validates thread info. It returns error if thread info
* is not correct. Thread is available after successful tfm_core_thrd_start().
*/
uint32_t tfm_core_thrd_start(struct tfm_core_thread_t *pth);
/*
* Get current running thread.
*
* Return :
* Current running thread context pointer.
*/
struct tfm_core_thread_t *tfm_core_thrd_get_curr(void);
/*
* Set the current running thread
* Note:
* This API is intended to update the current thread in FLIH handling.
* So that in nested FLIH interrupts, the handler knows which isolation
* boundary was preempted.
* Although the CURR_THRD is updated, it does not mean the running Partition
* thread is changed. It could also be the FLIH function which runs with the
* same isolation boundary of the CURR_THRD.
*/
void tfm_core_thrd_set_curr(struct tfm_core_thread_t *pth);
/*
* Get next thread to run in list.
*
* Return :
* Pointer of next thread to run.
*/
struct tfm_core_thread_t *tfm_core_thrd_get_next(void);
/*
* Start scheduler for existing threads
*
* Parameters:
* pth - pointer of the caller context collecting thread
*
* Notes :
* This function should be called only ONCE to start the scheduler.
* Caller needs to provide a thread object to collect current context.
* The usage of the collected context is caller defined.
*/
void tfm_core_thrd_start_scheduler(struct tfm_core_thread_t *pth);
/*
* Activate a scheduling action after exception.
*
* Notes :
* This function could be called multiple times before scheduling.
*/
void tfm_core_thrd_activate_schedule(void);
/*
* Save current architecture context into 'prev' thread and switch to 'next'.
*
* Parameters :
* p_actx - latest caller context
* prev - previous thread to be switched out
* next - thread to be run
*
* Notes :
* This function could be called multiple times before scheduling.
*/
void tfm_core_thrd_switch_context(struct tfm_arch_ctx_t *p_actx,
struct tfm_core_thread_t *prev,
struct tfm_core_thread_t *next);
#endif