Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rework signal handling #428

Merged
merged 2 commits into from
Sep 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 11 additions & 17 deletions hal/armv7a/_interrupts.S
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ _exception_abort:
stmfd sp, {r0-r4}
mov r0, #4
sub r2, lr, #8
b _exceptions_dispatch
.size _exception_abort, .-_exception_abort


Expand All @@ -68,6 +69,12 @@ _exceptions_dispatch:
mov sp, r4
ldmfd r1, {r4-r8}
push {r3-r8}
vpush {d16-d31}
vpush {d0-d15}
vmrs r4,fpscr
push {r4}
sub sp, sp, #8
str sp, [sp]
mrc p15, 0, r1, c6, c0, 2
push {r1}
mrc p15, 0, r1, c5, c0, 1
Expand All @@ -76,27 +83,14 @@ _exceptions_dispatch:
push {r1}
mrc p15, 0, r1, c5, c0, 0
push {r1}
sub r1, sp, #4
push {r1}
mov r1, sp

ldr lr, =exceptions_dispatch
blx lr

ldr sp, [sp]
add sp, sp, #20

pop {r11}
pop {r0-r10}
mov r12, sp
ldr sp, [r12, #0x8]
ldr lr, [r12, #0xc]
cps #IRQ_MODE
push {r11}
ldr r11, [r12, #0x0]
ldr lr, [r12, #0x10]
push {lr}
ldr r12, [r12, #0x4]
rfefd sp!
ldr sp, [sp, #0x10]
add sp, sp, #8
lukileczo marked this conversation as resolved.
Show resolved Hide resolved
b _hal_cpuRestoreCtx
.size _exceptions_dispatch, .-_exceptions_dispatch


Expand Down
4 changes: 2 additions & 2 deletions hal/armv7a/arch/cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -161,9 +161,9 @@ static inline void hal_cpuRestore(cpu_context_t *curr, cpu_context_t *next)
}


static inline void hal_cpuSetReturnValue(cpu_context_t *ctx, int retval)
static inline void hal_cpuSetReturnValue(cpu_context_t *ctx, void *retval)
{
ctx->r0 = retval;
ctx->r0 = (u32)retval;
}


Expand Down
24 changes: 2 additions & 22 deletions hal/armv7a/arch/exceptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#define _HAL_ARMV7A_EXCEPTIONS_H_

#include "types.h"
#include "cpu.h"

#define EXC_DEFAULT 128

Expand All @@ -27,33 +28,12 @@


typedef struct _exc_context_t {
u32 savesp;

u32 dfsr;
u32 dfar;
u32 ifsr;
u32 ifar;

u32 psr;

u32 r0;
u32 r1;
u32 r2;
u32 r3;
u32 r4;
u32 r5;
u32 r6;
u32 r7;
u32 r8;
u32 r9;
u32 r10;

u32 fp;
u32 ip;
u32 sp;
u32 lr;

u32 pc;
cpu_context_t cpuCtx;
} exc_context_t;

#endif
38 changes: 27 additions & 11 deletions hal/armv7a/cpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,28 +93,44 @@ int hal_cpuCreateContext(cpu_context_t **nctx, void *start, void *kstack, size_t
}


int hal_cpuPushSignal(void *kstack, void (*handler)(void), int n)
int hal_cpuPushSignal(void *kstack, void (*handler)(void), cpu_context_t *signalCtx, int n, const int src)
{
cpu_context_t *ctx = (void *)((char *)kstack - sizeof(cpu_context_t));

/* No signal handling inside IT block */
if (ctx->psr & 0x600fc00)
return -1;
(void)src;

PUTONSTACK(ctx->sp, u32, ctx->pc | !!(ctx->psr & THUMB_STATE));
PUTONSTACK(ctx->sp, int, n);
hal_memcpy(signalCtx, ctx, sizeof(cpu_context_t));

ctx->pc = (u32)handler & ~1;
signalCtx->pc = (u32)handler & ~1;
signalCtx->sp -= sizeof(cpu_context_t);

if ((u32)handler & 1)
ctx->psr |= THUMB_STATE;
else
ctx->psr &= ~THUMB_STATE;
if (((u32)handler & 1) != 0) {
signalCtx->psr |= THUMB_STATE;
}
else {
signalCtx->psr &= ~THUMB_STATE;
}

PUTONSTACK(signalCtx->sp, u32, 0); /* alignment */
PUTONSTACK(signalCtx->sp, u32, ctx->psr);
PUTONSTACK(signalCtx->sp, u32, ctx->sp);
PUTONSTACK(signalCtx->sp, u32, ctx->pc);
PUTONSTACK(signalCtx->sp, cpu_context_t *, signalCtx);
PUTONSTACK(signalCtx->sp, int, n);
lukileczo marked this conversation as resolved.
Show resolved Hide resolved

return 0;
}


void hal_cpuSigreturn(void *kstack, void *ustack, cpu_context_t **ctx)
{
(void)kstack;
GETFROMSTACK(ustack, u32, (*ctx)->pc, 2);
GETFROMSTACK(ustack, u32, (*ctx)->sp, 3);
GETFROMSTACK(ustack, u32, (*ctx)->psr, 4);
}


char *hal_cpuInfo(char *info)
{
size_t n = 0;
Expand Down
48 changes: 28 additions & 20 deletions hal/armv7a/exceptions.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,27 +64,27 @@ void hal_exceptionsDumpContext(char *buff, exc_context_t *ctx, int n)
hal_strcpy(buff += hal_strlen(buff), "\n");
buff += hal_strlen(buff);

i += hal_i2s(" r0=", &buff[i], ctx->r0, 16, 1);
i += hal_i2s(" r1=", &buff[i], ctx->r1, 16, 1);
i += hal_i2s(" r2=", &buff[i], ctx->r2, 16, 1);
i += hal_i2s(" r3=", &buff[i], ctx->r3, 16, 1);

i += hal_i2s("\n r4=", &buff[i], ctx->r4, 16, 1);
i += hal_i2s(" r5=", &buff[i], ctx->r5, 16, 1);
i += hal_i2s(" r6=", &buff[i], ctx->r6, 16, 1);
i += hal_i2s(" r7=", &buff[i], ctx->r7, 16, 1);

i += hal_i2s("\n r8=", &buff[i], ctx->r8, 16, 1);
i += hal_i2s(" r9=", &buff[i], ctx->r9, 16, 1);
i += hal_i2s(" r10=", &buff[i], ctx->r10, 16, 1);
i += hal_i2s(" fp=", &buff[i], ctx->fp, 16, 1);

i += hal_i2s("\n ip=", &buff[i], ctx->ip, 16, 1);
i += hal_i2s(" r0=", &buff[i], ctx->cpuCtx.r0, 16, 1);
i += hal_i2s(" r1=", &buff[i], ctx->cpuCtx.r1, 16, 1);
i += hal_i2s(" r2=", &buff[i], ctx->cpuCtx.r2, 16, 1);
i += hal_i2s(" r3=", &buff[i], ctx->cpuCtx.r3, 16, 1);

i += hal_i2s("\n r4=", &buff[i], ctx->cpuCtx.r4, 16, 1);
i += hal_i2s(" r5=", &buff[i], ctx->cpuCtx.r5, 16, 1);
i += hal_i2s(" r6=", &buff[i], ctx->cpuCtx.r6, 16, 1);
i += hal_i2s(" r7=", &buff[i], ctx->cpuCtx.r7, 16, 1);

i += hal_i2s("\n r8=", &buff[i], ctx->cpuCtx.r8, 16, 1);
i += hal_i2s(" r9=", &buff[i], ctx->cpuCtx.r9, 16, 1);
i += hal_i2s(" r10=", &buff[i], ctx->cpuCtx.r10, 16, 1);
i += hal_i2s(" fp=", &buff[i], ctx->cpuCtx.fp, 16, 1);

i += hal_i2s("\n ip=", &buff[i], ctx->cpuCtx.ip, 16, 1);
i += hal_i2s(" sp=", &buff[i], (u32)ctx + 21 * 4, 16, 1);
i += hal_i2s(" lr=", &buff[i], ctx->lr, 16, 1);
i += hal_i2s(" pc=", &buff[i], ctx->pc, 16, 1);
i += hal_i2s(" lr=", &buff[i], ctx->cpuCtx.lr, 16, 1);
i += hal_i2s(" pc=", &buff[i], ctx->cpuCtx.pc, 16, 1);

i += hal_i2s("\npsr=", &buff[i], ctx->psr, 16, 1);
i += hal_i2s("\npsr=", &buff[i], ctx->cpuCtx.psr, 16, 1);
i += hal_i2s(" dfs=", &buff[i], ctx->dfsr, 16, 1);
i += hal_i2s(" dfa=", &buff[i], ctx->dfar, 16, 1);
i += hal_i2s(" ifs=", &buff[i], ctx->ifsr, 16, 1);
Expand Down Expand Up @@ -116,6 +116,9 @@ static void exceptions_defaultHandler(unsigned int n, exc_context_t *ctx)
}


extern void threads_setupUserReturn(void *retval);


void exceptions_dispatch(unsigned int n, exc_context_t *ctx)
{
if (n == exc_prefetch || n == exc_abort)
Expand All @@ -124,6 +127,11 @@ void exceptions_dispatch(unsigned int n, exc_context_t *ctx)
exceptions.undefHandler(n, ctx);
else
exceptions.defaultHandler(n, ctx);

/* Handle signals if necessary */
if (hal_cpuSupervisorMode(&ctx->cpuCtx) == 0) {
threads_setupUserReturn((void *)ctx->cpuCtx.r0);
}
}


Expand Down Expand Up @@ -155,7 +163,7 @@ int hal_exceptionsFaultType(unsigned int n, exc_context_t *ctx)

ptr_t hal_exceptionsPC(exc_context_t *ctx)
{
return ctx->pc;
return ctx->cpuCtx.pc;
}


Expand Down
13 changes: 5 additions & 8 deletions hal/armv7m/arch/cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,9 @@ typedef struct _cpu_context_t {
u32 r11;
u32 irq_ret;

u32 msp;
u32 pad0;

#ifdef CPU_IMXRT
u32 s16;
u32 s17;
Expand Down Expand Up @@ -222,9 +225,9 @@ static inline void hal_cpuRestore(cpu_context_t *curr, cpu_context_t *next)
}


static inline void hal_cpuSetReturnValue(cpu_context_t *ctx, int retval)
static inline void hal_cpuSetReturnValue(cpu_context_t *ctx, void *retval)
{
ctx->hwctx.r0 = retval;
ctx->hwctx.r0 = (u32)retval;
}


Expand Down Expand Up @@ -261,12 +264,6 @@ static inline int hal_cpuSupervisorMode(cpu_context_t *ctx)
}


static inline int hal_cpuPushSignal(void *kstack, void (*handler)(void), int sig)
{
return 0;
}


/* core management */


Expand Down
69 changes: 52 additions & 17 deletions hal/armv7m/cpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ int hal_cpuCreateContext(cpu_context_t **nctx, void *start, void *kstack, size_t

ctx->savesp = (u32)ctx;
ctx->psp = (ustack != NULL) ? (u32)ustack - (HWCTXSIZE * sizeof(int)) : NULL;
ctx->msp = (ustack != NULL) ? (u32)kstack + kstacksz : (u32)&ctx->hwctx;
ctx->r4 = 0x44444444;
ctx->r5 = 0x55555555;
ctx->r6 = 0x66666666;
Expand All @@ -116,30 +117,22 @@ int hal_cpuCreateContext(cpu_context_t **nctx, void *start, void *kstack, size_t
ctx->r10 = 0xaaaaaaaa;
ctx->r11 = 0xbbbbbbbb;

ctx->hwctx.r0 = (u32)arg;
ctx->hwctx.r1 = 0x11111111;
ctx->hwctx.r2 = 0x22222222;
ctx->hwctx.r3 = 0x33333333;
ctx->hwctx.r12 = 0xcccccccc;
ctx->hwctx.lr = 0xeeeeeeee;
ctx->hwctx.pc = (u32)start;
ctx->hwctx.psr = 0x01000000;
if (ustack != NULL) {
((cpu_hwContext_t *)ctx->psp)->r0 = (u32)arg;
((cpu_hwContext_t *)ctx->psp)->r1 = 0x11111111;
((cpu_hwContext_t *)ctx->psp)->r2 = 0x22222222;
((cpu_hwContext_t *)ctx->psp)->r3 = 0x33333333;
((cpu_hwContext_t *)ctx->psp)->r12 = 0xcccccccc;
((cpu_hwContext_t *)ctx->psp)->lr = 0xeeeeeeee;
((cpu_hwContext_t *)ctx->psp)->pc = (u32)start;
((cpu_hwContext_t *)ctx->psp)->psr = 0x01000000;
#ifdef CPU_IMXRT
ctx->fpuctx = ctx->psp + 8 * sizeof(int);
((u32 *)ctx->psp)[24] = 0; /* fpscr */
ctx->fpscr = 0;
#endif
ctx->irq_ret = RET_THREAD_PSP;
}
else {
ctx->hwctx.r0 = (u32)arg;
ctx->hwctx.r1 = 0x11111111;
ctx->hwctx.r2 = 0x22222222;
ctx->hwctx.r3 = 0x33333333;
ctx->hwctx.r12 = 0xcccccccc;
ctx->hwctx.lr = 0xeeeeeeee;
ctx->hwctx.pc = (u32)start;
ctx->hwctx.psr = 0x01000000;
ctx->fpuctx = (u32)(&ctx->hwctx.psr + 1);
#ifdef CPU_IMXRT
ctx->fpscr = 0;
Expand All @@ -152,6 +145,48 @@ int hal_cpuCreateContext(cpu_context_t **nctx, void *start, void *kstack, size_t
}


int hal_cpuPushSignal(void *kstack, void (*handler)(void), cpu_context_t *signalCtx, int n, const int src)
{
cpu_context_t *ctx = (void *)((char *)kstack - sizeof(cpu_context_t));

hal_memcpy(signalCtx, ctx, sizeof(cpu_context_t));

signalCtx->psp -= sizeof(cpu_context_t);
signalCtx->hwctx.pc = (u32)handler;

PUTONSTACK(signalCtx->psp, u32, 0); /* alignment */
PUTONSTACK(signalCtx->psp, u32, ctx->hwctx.psr);
PUTONSTACK(signalCtx->psp, u32, ctx->psp);
PUTONSTACK(signalCtx->psp, u32, ctx->hwctx.pc);
PUTONSTACK(signalCtx->psp, cpu_context_t *, signalCtx);
PUTONSTACK(signalCtx->psp, int, n);
lukileczo marked this conversation as resolved.
Show resolved Hide resolved

if (src == SIG_SRC_SCHED) {
/* We'll be returning through interrupt dispatcher,
* need to prepare context on ustack to be restored
*/
signalCtx->psp -= HWCTXSIZE * sizeof(int);
hal_memcpy((void *)signalCtx->psp, &signalCtx->hwctx, HWCTXSIZE * sizeof(int));
}
return 0;
}


void hal_cpuSigreturn(void *kstack, void *ustack, cpu_context_t **ctx)
{
cpu_context_t *kCtx = (void *)((char *)kstack - sizeof(cpu_context_t));

GETFROMSTACK(ustack, u32, (*ctx)->hwctx.pc, 2);
GETFROMSTACK(ustack, u32, (*ctx)->psp, 3);
GETFROMSTACK(ustack, u32, (*ctx)->hwctx.psr, 4);
(*ctx)->irq_ret = RET_THREAD_PSP;

hal_memcpy(kCtx, *ctx, sizeof(cpu_context_t));

*ctx = kCtx;
}


void hal_longjmp(cpu_context_t *ctx)
{
__asm__ volatile
Expand Down
Loading
Loading