1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2025-07-22 06:28:13 +00:00
trezor-firmware/core/embed/trezorhal/systask.h

164 lines
4.7 KiB
C

/*
* This file is part of the Trezor project, https://trezor.io/
*
* Copyright (c) SatoshiLabs
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef TREZORHAL_SYSTASK_H
#define TREZORHAL_SYSTASK_H
#include <stddef.h>
#include <stdint.h>
#include "mpu.h"
// Termination reason for the task
typedef enum {
TASK_TERM_REASON_EXIT,
TASK_TERM_REASON_ERROR,
TASK_TERM_REASON_FATAL,
TASK_TERM_REASON_FAULT,
} systask_term_reason_t;
typedef struct {
// Fault/exception number (-15..-1)
int irqn;
// Configurable Fault Status Register
// (combined UFSR/BFSR/MMFSR)
uint32_t cfsr;
// Hard Fault Status Register
uint32_t hfsr;
// Address associated with MemManage fault
uint32_t mmfar;
// Address associated with the BusFault
uint32_t bfar;
} system_fault_t;
// Task post-mortem information
typedef struct {
systask_term_reason_t reason;
union {
// Argument passed to `systask_exit()`
struct {
int code;
} exit;
// Fault information catched in `systask_exit_fault()`
system_fault_t fault;
// Arguments passed to `systask_exit_fatal()`
struct {
uint32_t line;
char file[64];
char expr[64];
} fatal;
// Arguments passed to `systask_exit_error()`
struct {
char title[64];
char message[64];
char footer[64];
} error;
};
} systask_postmortem_t;
// Error handler callback invoke when kernel task terminates.
//
// The purpose of this callbacks display RSOD (Red Screen of Death).
//
// The callback may be called from any context, including interrupt context.
typedef void (*systask_error_handler_t)(const systask_postmortem_t* pminfo);
#ifdef KERNEL_MODE
// Task context used by the kernel to save the state of each task
// when switching between them
typedef struct {
// sp, sp_lim, exc_return should at the beginning
// and in this order to be compatible with the PendSV_Handler
// Stack pointer value
uint32_t sp;
// Stack pointer limit (ARMv8-M only)
uint32_t sp_lim;
// Exception return value
uint32_t exc_return;
// MPU mode the task is running in
mpu_mode_t mpu_mode;
// Task post-mortem information
systask_postmortem_t pminfo;
} systask_t;
// Initializes the scheduler for tasks
//
// No other task functions should be called before this function
void systask_scheduler_init(systask_error_handler_t error_handler);
// Returns the currently running task
systask_t* systask_active(void);
// Makes the given task the currently running task
void systask_yield_to(systask_t* task);
// Initializes a task with the given stack pointer, stack size
//
// The task must be not be running when the function is called
void systask_init(systask_t* task, uint32_t stack_ptr, uint32_t stack_size);
// Pushes data onto the stack of the task
//
// The task must be not be running when the function is called
uint32_t* systask_push_data(systask_t* task, const void* data, size_t size);
// Pops data from the stack of the task
//
// The task must be not be running when the function is called
void systask_pop_data(systask_t* task, size_t size);
// Runs the task with the given entrypoint and arguments
//
// The task must be not be running when the function is called
void systask_push_call(systask_t* task, void* fn, uint32_t arg1, uint32_t arg2,
uint32_t arg3);
// Terminates the current task with the given exit code
//
// If the terminated task is the currently running task, the kernel task
// will be scheduled next
void systask_exit(systask_t* task, int exit_code);
// Terminates the current task with an error message
//
// If the terminated task is the currently running task, the kernel task
// will be scheduled next
void systask_exit_error(systask_t* task, const char* title, const char* message,
const char* footer);
// Terminates the current task with a fatal error message
//
// If the terminated task is the currently running task, the kernel task
// will be scheduled next
void systask_exit_fatal(systask_t* task, const char* message, const char* file,
int line);
#endif // KERNEL_MODE
#endif // TREZORHAL_SYSTASK_H