mirror of
https://github.com/apache/nuttx.git
synced 2026-05-22 22:20:01 +08:00
arch/tricore: Full implementation of setjmp and longjmp.
1. The original method of restoring the register context relies on the ret instruction, which does not conform to the semantics of longjmp not returning. 2. There are csa leak during longjmp and need recycle. Signed-off-by: zhangyu117 <zhangyu117@xiaomi.com>
This commit is contained in:
@@ -30,36 +30,28 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
#define JB_LPCXI 0
|
||||
#define JB_LA11 1
|
||||
#define JB_A2 2
|
||||
#define JB_A3 3
|
||||
#define JB_D0 4
|
||||
#define JB_D1 5
|
||||
#define JB_D2 6
|
||||
#define JB_D3 7
|
||||
#define JB_A4 8
|
||||
#define JB_A5 9
|
||||
#define JB_A6 10
|
||||
#define JB_A7 11
|
||||
#define JB_D4 12
|
||||
#define JB_D5 13
|
||||
#define JB_D6 14
|
||||
#define JB_D7 15
|
||||
#define JB_UA11 16
|
||||
#define JB_REG_NUM 17
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
|
||||
struct setjmp_buf_s
|
||||
{
|
||||
uintptr_t regs[JB_REG_NUM];
|
||||
uintptr_t pcxi;
|
||||
uintptr_t psw;
|
||||
uintptr_t sp;
|
||||
uintptr_t a11;
|
||||
uintptr_t d8;
|
||||
uintptr_t d9;
|
||||
uintptr_t d10;
|
||||
uintptr_t d11;
|
||||
uintptr_t a12;
|
||||
uintptr_t a13;
|
||||
uintptr_t a14;
|
||||
uintptr_t a15;
|
||||
uintptr_t d12;
|
||||
uintptr_t d13;
|
||||
uintptr_t d14;
|
||||
uintptr_t d15;
|
||||
};
|
||||
|
||||
/* Traditional typedef for setjmp_buf */
|
||||
@@ -79,7 +71,7 @@ extern "C"
|
||||
#endif
|
||||
|
||||
int setjmp(jmp_buf env);
|
||||
void longjmp(jmp_buf env, int val);
|
||||
void longjmp(jmp_buf env, int val) noreturn_function;
|
||||
|
||||
#undef EXTERN
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -24,13 +24,10 @@
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <string.h>
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <nuttx/compiler.h>
|
||||
#include <arch/setjmp.h>
|
||||
#include <nuttx/arch.h>
|
||||
|
||||
#include <IfxCpu_reg.h>
|
||||
#include <IfxCpu_Intrinsics.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
@@ -38,32 +35,141 @@
|
||||
|
||||
int setjmp(jmp_buf env)
|
||||
{
|
||||
uintptr_t *regs;
|
||||
uintptr_t pcxi;
|
||||
|
||||
env->regs[JB_UA11] = (uintptr_t)__getA11();
|
||||
|
||||
pcxi = __mfcr(CPU_PCXI);
|
||||
regs = tricore_csa2addr(pcxi);
|
||||
memcpy(env, regs, TC_CONTEXT_SIZE);
|
||||
__asm__ __volatile__ (
|
||||
#ifdef CONFIG_TRICORE_TOOLCHAIN_TASKING
|
||||
"st.a [a4]12, a11\n\t"
|
||||
"movh.a a11, #@HIS(.Lsaveregs)\n\t"
|
||||
"lea a11, [a11]@LOS(.Lsaveregs)\n\t"
|
||||
"ret\n\t"
|
||||
".Lsaveregs:\n\t"
|
||||
"st.a [a4]8, sp\n\t"
|
||||
"st.a [a4]32, a12\n\t"
|
||||
"st.a [a4]36, a13\n\t"
|
||||
"st.a [a4]40, a14\n\t"
|
||||
"st.a [a4]44, a15\n\t"
|
||||
"st.w [a4]16, d8\n\t"
|
||||
"st.w [a4]20, d9\n\t"
|
||||
"st.w [a4]24, d10\n\t"
|
||||
"st.w [a4]28, d11\n\t"
|
||||
"st.w [a4]48, d12\n\t"
|
||||
"st.w [a4]52, d13\n\t"
|
||||
"st.w [a4]56, d14\n\t"
|
||||
"st.w [a4]60, d15\n\t"
|
||||
"mfcr d2, #0xfe00\n\t"
|
||||
"st.w [a4]0, d2\n\t"
|
||||
"mfcr d2, #0xfe04\n\t"
|
||||
"st.w [a4]4, d2\n\t"
|
||||
"ld.a a2, [a4]12\n\t"
|
||||
"mov d2, #0\n\t"
|
||||
"ji a2\n\t"
|
||||
#else
|
||||
"st.a [%%a4]12, %%a11\n\t"
|
||||
"movh.a %%a11, hi:.Lsaveregs\n\t"
|
||||
"lea %%a11, [%%a11] lo:.Lsaveregs\n\t"
|
||||
"ret\n\t"
|
||||
".Lsaveregs:\n\t"
|
||||
"st.a [%%a4]8, %%sp\n\t"
|
||||
"st.a [%%a4]32, %%a12\n\t"
|
||||
"st.a [%%a4]36, %%a13\n\t"
|
||||
"st.a [%%a4]40, %%a14\n\t"
|
||||
"st.a [%%a4]44, %%a15\n\t"
|
||||
"st.w [%%a4]16, %%d8\n\t"
|
||||
"st.w [%%a4]20, %%d9\n\t"
|
||||
"st.w [%%a4]24, %%d10\n\t"
|
||||
"st.w [%%a4]28, %%d11\n\t"
|
||||
"st.w [%%a4]48, %%d12\n\t"
|
||||
"st.w [%%a4]52, %%d13\n\t"
|
||||
"st.w [%%a4]56, %%d14\n\t"
|
||||
"st.w [%%a4]60, %%d15\n\t"
|
||||
"mfcr %%d2, 0xfe00\n\t"
|
||||
"st.w [%%a4]0, %%d2\n\t"
|
||||
"mfcr %%d2, 0xfe04\n\t"
|
||||
"st.w [%%a4]4, %%d2\n\t"
|
||||
"ld.a %%a2, [%%a4]12\n\t"
|
||||
"mov %%d2, 0\n\t"
|
||||
"ji %%a2\n\t"
|
||||
#endif
|
||||
::: "memory"
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void longjmp(jmp_buf env, int val)
|
||||
{
|
||||
void *func = (void *)env->regs[JB_UA11];
|
||||
uintptr_t *regs;
|
||||
uintptr_t pcxi;
|
||||
__asm__ __volatile__ (
|
||||
#ifdef CONFIG_TRICORE_TOOLCHAIN_TASKING
|
||||
"ld.w d5, [a4]0\n\t"
|
||||
".Lloop:\n\t"
|
||||
"mfcr d2, #0xfe00\n\t"
|
||||
"jne d2, d5, .Lrelease\n\t"
|
||||
"max.u d2, d4, #1\n\t"
|
||||
"ld.a a2, [a4]12\n\t"
|
||||
"ld.a sp, [a4]8\n\t"
|
||||
"ld.a a12, [a4]32\n\t"
|
||||
"ld.a a13, [a4]36\n\t"
|
||||
"ld.a a14, [a4]40\n\t"
|
||||
"ld.a a15, [a4]44\n\t"
|
||||
"ld.w d8, [a4]16\n\t"
|
||||
"ld.w d9, [a4]20\n\t"
|
||||
"ld.w d10, [a4]24\n\t"
|
||||
"ld.w d11, [a4]28\n\t"
|
||||
"ld.w d12, [a4]48\n\t"
|
||||
"ld.w d13, [a4]52\n\t"
|
||||
"ld.w d14, [a4]56\n\t"
|
||||
"ld.w d15, [a4]60\n\t"
|
||||
"ji a2\n\t"
|
||||
".Lrelease:\n\t"
|
||||
"jnz.t d2, #20, .Lupper\n\t"
|
||||
"mov.aa a15, a4\n\t"
|
||||
"mov d15, d4\n\t"
|
||||
"mov d14, d5\n\t"
|
||||
"rslcx\n\t"
|
||||
"mov d4, d15\n\t"
|
||||
"mov d5, d14\n\t"
|
||||
"mov.aa a4, a15\n\t"
|
||||
"j .Lloop\n\t"
|
||||
".Lupper:\n\t"
|
||||
"movh.a a11, #@HIS(.Lloop)\n\t"
|
||||
"lea a11, [a11]@LOS(.Lloop)\n\t"
|
||||
"ret\n\t"
|
||||
#else
|
||||
"ld.w %%d5, [%%a4]0\n\t"
|
||||
".Lloop:\n\t"
|
||||
"mfcr %%d2, 0xfe00\n\t"
|
||||
"jne %%d2, %%d5, .Lrelease\n\t"
|
||||
"max.u %%d2, %%d4, 1\n\t"
|
||||
"ld.a %%a2, [%%a4]12\n\t"
|
||||
"ld.a %%sp, [%%a4]8\n\t"
|
||||
"ld.a %%a12, [%%a4]32\n\t"
|
||||
"ld.a %%a13, [%%a4]36\n\t"
|
||||
"ld.a %%a14, [%%a4]40\n\t"
|
||||
"ld.a %%a15, [%%a4]44\n\t"
|
||||
"ld.w %%d8, [%%a4]16\n\t"
|
||||
"ld.w %%d9, [%%a4]20\n\t"
|
||||
"ld.w %%d10, [%%a4]24\n\t"
|
||||
"ld.w %%d11, [%%a4]28\n\t"
|
||||
"ld.w %%d12, [%%a4]48\n\t"
|
||||
"ld.w %%d13, [%%a4]52\n\t"
|
||||
"ld.w %%d14, [%%a4]56\n\t"
|
||||
"ld.w %%d15, [%%a4]60\n\t"
|
||||
"ji %%a2\n\t"
|
||||
".Lrelease:\n\t"
|
||||
"jnz.t %%d2, 20, .Lupper\n\t"
|
||||
"mov.aa %%a15, %%a4\n\t"
|
||||
"mov %%d15, %%d4\n\t"
|
||||
"mov %%d14, %%d5\n\t"
|
||||
"rslcx\n\t"
|
||||
"mov %%d4, %%d15\n\t"
|
||||
"mov %%d5, %%d14\n\t"
|
||||
"mov.aa %%a4, %%a15\n\t"
|
||||
"j .Lloop\n\t"
|
||||
".Lupper:\n\t"
|
||||
"movh.a %%a11, hi:.Lloop\n\t"
|
||||
"lea %%a11, [%%a11] lo:.Lloop\n\t"
|
||||
"ret\n\t"
|
||||
#endif
|
||||
::: "memory"
|
||||
);
|
||||
|
||||
pcxi = __mfcr(CPU_PCXI);
|
||||
regs = tricore_csa2addr(pcxi);
|
||||
memcpy(regs, env, TC_CONTEXT_SIZE);
|
||||
|
||||
if (val == 0)
|
||||
{
|
||||
val = 1;
|
||||
}
|
||||
|
||||
__moveToDataParamRet(val);
|
||||
__jumpToFunctionWithLink(func);
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user