#include <rt/abort.h>
#include <rt/context.h>
#include <rt/idle.h>
#include <rt/syscall.h>
#include <rt/task.h>
#include <rt/tick.h>
#include <rt/trap.h>
#include <stdbool.h>
#include <stdint.h>
#define ST1_VMAP (UINT16_C(1) << 3)
#define ST1_OBJMODE (UINT16_C(1) << 9)
#define ST1_M0M1MAP (UINT16_C(1) << 11)
struct context
{
uint16_t st0, t;
uint32_t acc;
uint32_t p;
uint16_t ar0, ar1;
uint16_t st1, dp;
uint16_t ier, dbgstat;
uint32_t pc;
uint16_t ar0h, ar1h;
uint32_t xar4;
uint32_t xar5;
uint32_t xar6;
uint32_t xar7;
uint32_t xt;
#ifdef __TMS320C28XX_FPU32__
uint32_t rb;
float r0h, r1h, r2h, r3h;
#ifdef __TMS320C28XX_FPU64__
float r0l, r1l, r2l, r3l;
#endif #endif
uint32_t xar2;
uint32_t xar3;
uint32_t rpc;
#ifdef __TMS320C28XX_FPU32__
float r4h, r5h, r6h, r7h;
#ifdef __TMS320C28XX_FPU64__
float r4l, r5l, r6l, r7l;
#endif
uint32_t stf;
#endif };
#define ST0_PM(pm) ((uint16_t)((pm) + 1) << 7)
void *rt_context_init(uintptr_t fn, uintptr_t arg, void *stack,
size_t stack_size)
{
struct context *ctx = stack;
ctx->st0 = ST0_PM(0);
ctx->acc = arg;
ctx->st1 = ST1_VMAP | ST1_M0M1MAP | ST1_OBJMODE;
ctx->ier = UINT16_C(0xFFFF);
ctx->pc = (uint32_t)rt_task_entry;
ctx->xar4 = fn;
ctx->rpc = 0;
#ifdef __TMS320C28XX_FPU32__
ctx->rb = 0;
ctx->stf = 0;
#endif
return (char *)(ctx + 1) + 1;
}
extern __cregister volatile uint16_t IER;
extern __cregister volatile uint16_t IFR;
#define IFR_DLOGINT (UINT16_C(1) << 14)
#define IFR_TIMER2 (UINT16_C(1) << 13)
__attribute__((noreturn, weak)) void rt_idle(void)
{
for (;;)
{
__asm__(" idle");
}
}
__attribute__((noreturn, weak)) void rt_abort(void)
{
for (;;)
{
__asm__(" itrap0");
}
}
__attribute__((noreturn, weak)) void rt_trap(void)
{
for (;;)
{
__asm__(" estop0");
__asm__(" itrap0");
}
}
bool rt_interrupt_is_active(void)
{
return IER != 0xFFFFU;
}
void rt_syscall_pend(void)
{
IFR |= IFR_DLOGINT;
}
__attribute__((weak)) void rt_cycle_init(void)
{
}
#define IPCCOUNTERL (*(volatile uint32_t *)0x5000CUL)
__attribute__((weak)) uint32_t rt_cycle(void)
{
return IPCCOUNTERL;
}
void rt_task_drop_privilege(void)
{
}