mirror of
https://github.com/apache/nuttx.git
synced 2026-08-01 20:28:58 +00: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:
parent
e087d0f79d
commit
02833038fd
2 changed files with 150 additions and 52 deletions
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue