#pragma once
#include <rt/arch/control.h>
#include <rt/arch/dcb.h>
#include <rt/arch/dwt.h>
#include <rt/arch/scb.h>
#include "exc_return.h"
#define PSR_THUMB (UINT32_C(1) << 24)
struct context
{
#if !RT_ARM_V6M && RT_MPU_TASK_REGIONS_ENABLE
uint32_t control;
#endif
#if RT_ARM_V8M
uint32_t psplim;
#endif
uint32_t r4, r5, r6, r7, r8, r9, r10, r11;
#if RT_ARM_FP
uint32_t exc_return;
#endif
uint32_t r0, r1, r2, r3, r12, lr, pc, psr;
};
static void profile_context_init(struct context *ctx)
{
#if !RT_ARM_V6M && RT_MPU_TASK_REGIONS_ENABLE
ctx->control = 0;
#endif
#if RT_ARM_FP
ctx->exc_return = (uint32_t)EXC_RETURN_TASK_NOFP;
#endif
ctx->psr = PSR_THUMB;
}
void rt_task_drop_privilege(void)
{
#if !RT_ARM_V6M && RT_MPU_TASK_REGIONS_ENABLE
uint32_t control;
__asm__ __volatile__("mrs %0, control" : "=r"(control));
__asm__("dsb; msr control, %0; isb"
:
: "r"(control | CONTROL_NPRIV)
: "memory");
#endif }
bool rt_interrupt_is_active(void)
{
uint32_t ipsr;
__asm__ __volatile__("mrs %0, ipsr" : "=r"(ipsr));
return ipsr != 0;
}
void rt_syscall_0(enum rt_syscall syscall)
{
register enum rt_syscall r0 __asm__("r0") = syscall;
__asm__("svc 0" : : "r"(r0) : "memory");
}
void rt_syscall_1(enum rt_syscall syscall, uintptr_t arg0)
{
register enum rt_syscall r0 __asm__("r0") = syscall;
register uintptr_t r1 __asm__("r1") = arg0;
__asm__("svc 0" : : "r"(r0), "r"(r1) : "memory");
}
void rt_syscall_2(enum rt_syscall syscall, uintptr_t arg0, uintptr_t arg1)
{
register enum rt_syscall r0 __asm__("r0") = syscall;
register uintptr_t r1 __asm__("r1") = arg0;
register uintptr_t r2 __asm__("r2") = arg1;
__asm__("svc 0" : : "r"(r0), "r"(r1), "r"(r2) : "memory");
}
void rt_syscall_3(enum rt_syscall syscall, uintptr_t arg0, uintptr_t arg1,
uintptr_t arg2)
{
register enum rt_syscall r0 __asm__("r0") = syscall;
register uintptr_t r1 __asm__("r1") = arg0;
register uintptr_t r2 __asm__("r2") = arg1;
register uintptr_t r3 __asm__("r3") = arg2;
__asm__("svc 0" : : "r"(r0), "r"(r1), "r"(r2), "r"(r3) : "memory");
}
void rt_syscall_pend(void)
{
SCB->icsr = SCB_ICSR_PENDSVSET;
}
__attribute__((weak)) void rt_cycle_init(void)
{
#if !RT_ARM_V6M && RT_CYCLE_ENABLE
DCB->demcr |= DCB_DEMCR_TRCENA;
DWT->lar = DWT_LAR_UNLOCK;
DWT->ctrl |= DWT_CTRL_CYCCNTENA;
#endif }
__attribute__((weak)) uint32_t rt_cycle(void)
{
#if !RT_ARM_V6M && RT_CYCLE_ENABLE
return DWT->cyccnt;
#else
return 0;
#endif
}
void *rt_tp;
void rt_tls_set(void *tls)
{
rt_tp = tls;
}