diff --git a/hal/armv7m/arch/exceptions.h b/hal/armv7m/arch/exceptions.h index 53b459c4c..d69cf1c76 100644 --- a/hal/armv7m/arch/exceptions.h +++ b/hal/armv7m/arch/exceptions.h @@ -11,21 +11,6 @@ #define SIZE_CTXDUMP 320 /* Size of dumped context */ -typedef struct _exc_context_t { - /* Saved by ISR */ - u32 psp; - u32 r4; - u32 r5; - u32 r6; - u32 r7; - u32 r8; - u32 r9; - u32 r10; - u32 r11; - u32 excret; - - /* Saved by hardware */ - cpu_hwContext_t mspctx; -} exc_context_t; +typedef cpu_context_t exc_context_t; #endif diff --git a/hal/armv7m/exceptions.c b/hal/armv7m/exceptions.c index 67672b2d4..c38710366 100644 --- a/hal/armv7m/exceptions.c +++ b/hal/armv7m/exceptions.c @@ -21,7 +21,7 @@ #include "hal/string.h" #include "config.h" -#define SIZE_FPUCTX (16 * sizeof(u32)) +#define SIZE_FPUCTX (18 * sizeof(u32)) static struct { void (*handler)(unsigned int, exc_context_t *); @@ -40,24 +40,19 @@ void hal_exceptionsDumpContext(char *buff, exc_context_t *ctx, int n) "12 #Debug", "13 #", "14 #PendSV", "15 #SysTick" }; size_t i = 0; - u32 msp = (u32)ctx + sizeof(*ctx); u32 psp = ctx->psp; cpu_hwContext_t *hwctx; /* If we came from userspace HW ctx in on psp stack */ - if (ctx->excret == RET_THREAD_PSP) { + if (ctx->irq_ret == RET_THREAD_PSP) { hwctx = (void *)ctx->psp; - msp -= sizeof(cpu_hwContext_t); psp += sizeof(cpu_hwContext_t); #ifdef CPU_IMXRT /* FIXME - check if FPU was enabled instead */ psp += SIZE_FPUCTX; #endif } else { - hwctx = &ctx->mspctx; -#ifdef CPU_IMXRT - msp += SIZE_FPUCTX; -#endif + hwctx = &ctx->hwctx; } n &= 0xf; @@ -88,8 +83,8 @@ void hal_exceptionsDumpContext(char *buff, exc_context_t *ctx, int n) i += hal_i2s(" pc=", &buff[i], hwctx->pc, 16, 1); i += hal_i2s("\npsp=", &buff[i], psp, 16, 1); - i += hal_i2s(" msp=", &buff[i], msp, 16, 1); - i += hal_i2s(" exr=", &buff[i], ctx->excret, 16, 1); + i += hal_i2s(" msp=", &buff[i], ctx->msp, 16, 1); + i += hal_i2s(" exr=", &buff[i], ctx->irq_ret, 16, 1); i += hal_i2s(" bfa=", &buff[i], *(u32 *)0xe000ed38, 16, 1); i += hal_i2s("\ncfs=", &buff[i], *(u32 *)0xe000ed28, 16, 1); @@ -123,7 +118,7 @@ __attribute__((noreturn)) static void exceptions_fatal(unsigned int n, exc_conte void exceptions_dispatch(unsigned int n, exc_context_t *ctx) { if ((hal_exception_common.handler != NULL) && - ((ctx->excret & (1 << 2)) != 0)) { + ((ctx->irq_ret & (1 << 2)) != 0)) { /* Need to enter the kernel by returning to the * thread mode. Otherwise we won't be able to @@ -142,11 +137,11 @@ ptr_t hal_exceptionsPC(exc_context_t *ctx) { cpu_hwContext_t *hwctx; - if (ctx->excret == RET_THREAD_PSP) { + if (ctx->irq_ret == RET_THREAD_PSP) { hwctx = (void *)ctx->psp; } else { - hwctx = &ctx->mspctx; + hwctx = &ctx->hwctx; } return hwctx->pc; diff --git a/hal/armv7m/imxrt/_init.S b/hal/armv7m/imxrt/_init.S index 2703d4d97..48491b80e 100644 --- a/hal/armv7m/imxrt/_init.S +++ b/hal/armv7m/imxrt/_init.S @@ -192,12 +192,23 @@ _syscallend: _exceptions_dispatch: cpsid if + isb - mrs r0, psp - stmdb sp!, {r0, r4-r11, lr} + mov r0, sp /* save MSP to be stored in cpu_context_t */ + tst lr, #(1 << 2) + ite ne + subne sp, sp, #((8 + 18) * 4) /* If coming from userspace, make room on the stack for hardware-stored context */ + addeq r0, r0, #((8 + 18) * 4) /* If coming from kernel, calculate msp as it was before the exception */ + + vstmdb sp!, {s16-s31} + str r0, [sp, #-8]! /* Store msp, skip over pad0 */ mrs r0, ipsr - mov r1, sp + mrs r3, psp + sub r1, sp, #48 + ldr r2, =0xe000ef38 + ldr r2, [r2] + stmdb sp!, {r1-r11, lr} b exceptions_dispatch .size _exceptions_dispatch, .-_exceptions_dispatch diff --git a/hal/armv7m/stm32/_init.S b/hal/armv7m/stm32/_init.S index 387a9c23b..8b1db4519 100644 --- a/hal/armv7m/stm32/_init.S +++ b/hal/armv7m/stm32/_init.S @@ -171,12 +171,20 @@ _syscallend: _exceptions_dispatch: cpsid if + isb - mrs r0, psp - stmdb sp!, {r0, r4-r11, lr} + mov r0, sp /* save MSP to be stored in cpu_context_t */ + tst lr, #(1 << 2) + ite ne + subne sp, sp, #(8 * 4) /* If coming from userspace, make room on the stack for hardware-stored context */ + addeq r0, r0, #(8 * 4) /* If coming from kernel, calculate msp as it was before the exception */ + + str r0, [sp, #-8]! /* Store msp, skip over pad0 */ mrs r0, ipsr - mov r1, sp + mrs r3, psp + sub r1, sp, #48 + stmdb sp!, {r1-r11, lr} b exceptions_dispatch .size _exceptions_dispatch, .-_exceptions_dispatch diff --git a/hal/armv8m/arch/exceptions.h b/hal/armv8m/arch/exceptions.h index 0494c03a8..a70dfef98 100644 --- a/hal/armv8m/arch/exceptions.h +++ b/hal/armv8m/arch/exceptions.h @@ -25,21 +25,6 @@ #define SIZE_CTXDUMP 512 /* Size of dumped context */ -typedef struct _exc_context_t { - /* Saved by ISR */ - u32 psp; - u32 r4; - u32 r5; - u32 r6; - u32 r7; - u32 r8; - u32 r9; - u32 r10; - u32 r11; - u32 excret; - - /* Saved by hardware */ - cpu_hwContext_t mspctx; -} exc_context_t; +typedef cpu_context_t exc_context_t; #endif diff --git a/hal/armv8m/exceptions.c b/hal/armv8m/exceptions.c index 19d763f12..38cfcda46 100644 --- a/hal/armv8m/exceptions.c +++ b/hal/armv8m/exceptions.c @@ -49,21 +49,18 @@ void hal_exceptionsDumpContext(char *buff, exc_context_t *ctx, int n) "12 #Debug", "13 #", "14 #PendSV", "15 #SysTick" }; size_t i = 0; - u32 msp = (u32)ctx + sizeof(*ctx); - const u32 fpu_hwctx_size = ((ctx->excret & EXC_RETURN_FTYPE) == 0) ? SIZE_FPUCTX : 0; + const u32 fpu_hwctx_size = ((ctx->irq_ret & EXC_RETURN_FTYPE) == 0) ? SIZE_FPUCTX : 0; u32 psp = ctx->psp; u32 cfsr, far; cpu_hwContext_t *hwctx; /* If we came from userspace HW ctx in on psp stack (according to EXC_RETURN) */ - if ((ctx->excret & EXC_RETURN_SPSEL) != 0) { + if ((ctx->irq_ret & EXC_RETURN_SPSEL) != 0) { hwctx = (void *)ctx->psp; - msp -= sizeof(cpu_hwContext_t); psp += sizeof(cpu_hwContext_t) + fpu_hwctx_size; } else { - hwctx = &ctx->mspctx; - msp += fpu_hwctx_size; + hwctx = &ctx->hwctx; } n &= 0xf; @@ -94,8 +91,8 @@ void hal_exceptionsDumpContext(char *buff, exc_context_t *ctx, int n) i += hal_i2s(" pc=", &buff[i], hwctx->pc, 16, 1); i += hal_i2s("\npsp=", &buff[i], psp, 16, 1); - i += hal_i2s(" msp=", &buff[i], msp, 16, 1); - i += hal_i2s(" exr=", &buff[i], ctx->excret, 16, 1); + i += hal_i2s(" msp=", &buff[i], ctx->msp, 16, 1); + i += hal_i2s(" exr=", &buff[i], ctx->irq_ret, 16, 1); if (n == exc_BusFault) { cfsr = (*CFSR >> 8) & 0xff; @@ -147,11 +144,11 @@ ptr_t hal_exceptionsPC(exc_context_t *ctx) { cpu_hwContext_t *hwctx; - if ((ctx->excret & EXC_RETURN_SPSEL) != 0) { + if ((ctx->irq_ret & EXC_RETURN_SPSEL) != 0) { hwctx = (void *)ctx->psp; } else { - hwctx = &ctx->mspctx; + hwctx = &ctx->hwctx; } return hwctx->pc; diff --git a/hal/armv8m/mcx/_init.S b/hal/armv8m/mcx/_init.S index 5faf78a15..e84e75a59 100644 --- a/hal/armv8m/mcx/_init.S +++ b/hal/armv8m/mcx/_init.S @@ -170,11 +170,18 @@ _exceptions_dispatch: cpsid if isb - mrs r0, psp - stmdb sp!, {r0, r4-r11, lr} + mov r0, sp /* save MSP to be stored in cpu_context_t */ + tst lr, #(1 << 2) + ite ne + subne sp, sp, #(8 * 4) /* If coming from userspace, make room on the stack for hardware-stored context */ + addeq r0, r0, #(8 * 4) /* If coming from kernel, calculate msp as it was before the exception */ + + str r0, [sp, #-8]! /* Store msp, skip over pad0 */ mrs r0, ipsr - mov r1, sp + mrs r3, psp + sub r1, sp, #48 + stmdb sp!, {r1-r11, lr} b exceptions_dispatch .size _exceptions_dispatch, .-_exceptions_dispatch diff --git a/hal/armv8m/nrf/_init.S b/hal/armv8m/nrf/_init.S index a247084ca..9f1bf010c 100644 --- a/hal/armv8m/nrf/_init.S +++ b/hal/armv8m/nrf/_init.S @@ -171,11 +171,18 @@ _exceptions_dispatch: cpsid if isb - mrs r0, psp - stmdb sp!, {r0, r4-r11, lr} + mov r0, sp /* save MSP to be stored in cpu_context_t */ + tst lr, #(1 << 2) + ite ne + subne sp, sp, #(8 * 4) /* If coming from userspace, make room on the stack for hardware-stored context */ + addeq r0, r0, #(8 * 4) /* If coming from kernel, calculate msp as it was before the exception */ + + str r0, [sp, #-8]! /* Store msp, skip over pad0 */ mrs r0, ipsr - mov r1, sp + mrs r3, psp + sub r1, sp, #48 + stmdb sp!, {r1-r11, lr} b exceptions_dispatch .size _exceptions_dispatch, .-_exceptions_dispatch @@ -357,4 +364,4 @@ hal_exceptionJump: bx lr .size hal_exceptionJump, .-hal_exceptionJump -.ltorg \ No newline at end of file +.ltorg diff --git a/hal/armv8m/stm32/_init.S b/hal/armv8m/stm32/_init.S index 817796424..870ae185d 100644 --- a/hal/armv8m/stm32/_init.S +++ b/hal/armv8m/stm32/_init.S @@ -252,12 +252,31 @@ _exceptions_dispatch: cpsid if isb - mrs r0, psp - /* push psp, r4~r11, excret */ - stmdb sp!, {r0, r4-r11, lr} + mov r0, sp /* save MSP to be stored in cpu_context_t */ + tst lr, #EXC_RETURN_SPSEL + itt ne + subne sp, sp, #(8 * 4) /* If coming from userspace, make room on the stack for hardware-stored context */ + bne 1f + + tst lr, #EXC_RETURN_FTYPE /* If coming from kernel, calculate msp as it was before the exception */ + ite ne + addne r0, r0, #(8 * 4) + addeq r0, r0, #((8 + 18) * 4) + +1: +#if KERNEL_FPU_SUPPORT + vpush {s16-s31} +#endif + str r0, [sp, #-8]! /* Store msp, skip over pad0 */ mrs r0, ipsr - mov r1, sp + sub r1, sp, #(12 * 4) /* pointer to cpu_context_t on stack */ +#if KERNEL_FPU_SUPPORT + ldr r2, =SCS_BASE + ldr r2, [r2, #SCS_FPCAR] +#endif + mrs r3, psp + push {r1-r11, lr} /* store savesp, fpuctx, psp, r4~r11, irq_ret */ /* void exceptions_dispatch(unsigned int n, exc_context_t *ctx) */ b exceptions_dispatch