Xtensa: Adapt co-processor state save/restore functions so that they are call-able from C with Windows ABI.
This commit is contained in:
parent
c0da94fc3e
commit
261e0edc61
@ -260,9 +260,8 @@ int xtensa_context_save(uint32_t *regs);
|
||||
void xtensa_context_restore(uint32_t *regs) noreturn_function;
|
||||
|
||||
#if XCHAL_CP_NUM > 0
|
||||
struct tcb_s;
|
||||
void xtensa_coproc_savestate(struct tcb_s *tcb);
|
||||
void xtensa_coproc_restorestate(struct tcb_s *tcb);
|
||||
void xtensa_coproc_savestate(struct xtensa_cpstate_s *cpstate);
|
||||
void xtensa_coproc_restorestate(struct xtensa_cpstate_s *cpstate);
|
||||
#endif
|
||||
|
||||
/* Signals */
|
||||
|
@ -104,6 +104,8 @@
|
||||
*/
|
||||
|
||||
#ifdef __ASSEMBLY__
|
||||
/* Function prologues and epilogues */
|
||||
|
||||
#ifdef __XTENSA_CALL0_ABI__
|
||||
/* Call0 */
|
||||
|
||||
@ -130,7 +132,13 @@
|
||||
# define ENTRY0 entry sp, 0x10
|
||||
# define RET(sz) retw
|
||||
# define RET0 retw
|
||||
|
||||
#endif
|
||||
|
||||
/* Index into stack frame (skipping over saved A0) */
|
||||
|
||||
#define LOCAL_OFFSET(n) ((n) << 2) /* n = 1 .. ((size >> 2) - 1) */
|
||||
|
||||
#endif /* __ASSEMBLY_ */
|
||||
|
||||
#endif /* __ARCH_XTENSA_SRC_COMMON_XTENSA_ABI_H */
|
||||
|
@ -154,7 +154,7 @@ void up_block_task(struct tcb_s *tcb, tstate_t task_state)
|
||||
* processor save area.
|
||||
*/
|
||||
|
||||
xtensa_coproc_savestate(rtcb);
|
||||
xtensa_coproc_savestate(&rtcb->xcp.cpstate);
|
||||
#endif
|
||||
|
||||
/* Restore the exception context of the rtcb at the (new) head
|
||||
@ -166,7 +166,7 @@ void up_block_task(struct tcb_s *tcb, tstate_t task_state)
|
||||
#if XCHAL_CP_NUM > 0
|
||||
/* Set up the co-processor state for the newly started thread. */
|
||||
|
||||
xtensa_coproc_restorestate(rtcb);
|
||||
xtensa_coproc_restorestate(&rtcb->xcp.cpstate);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_ADDRENV
|
||||
|
@ -46,6 +46,8 @@
|
||||
#include <arch/chip/tie.h>
|
||||
#include <arch/chip/tie-asm.h>
|
||||
|
||||
#include "xtensa_abi.h"
|
||||
|
||||
#if XCHAL_CP_NUM > 0
|
||||
|
||||
/****************************************************************************
|
||||
@ -87,7 +89,7 @@ _xtensa_coproc_saoffsets:
|
||||
* around the assembly language call to _xtensa_coproc_savestate.
|
||||
*
|
||||
* Entry Conditions:
|
||||
* - A2 holds the address of the threads state save area
|
||||
* - A2 holds the address of the co-processor state save area
|
||||
* - The thread being switched out is still the current thread.
|
||||
* - CPENABLE state reflects which coprocessors are active.
|
||||
* - Registers have been saved/spilled already.
|
||||
@ -191,6 +193,79 @@ _xtensa_coproc_savestate:
|
||||
|
||||
.size _xtensa_coproc_savestate, . - _xtensa_coproc_savestate
|
||||
|
||||
/****************************************************************************
|
||||
* Name: xtensa_coproc_savestate
|
||||
*
|
||||
* Description:
|
||||
* If there is a current thread and it has a coprocessor state save area,
|
||||
* then save all callee-saved state into this area. xtensa_coproc_savestate()
|
||||
* is simply a C wrapper around the assembly language call to
|
||||
* _xtensa_coproc_savestate.
|
||||
*
|
||||
* Input Parameters:
|
||||
* A2 - Address of co-processor save area
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
* Called with interrupts disabled.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
.global xtensa_coproc_savestate
|
||||
.type xtensa_coproc_savestate, @function
|
||||
|
||||
.align 4
|
||||
.literal_position
|
||||
.align 4
|
||||
|
||||
xtensa_coproc_savestate:
|
||||
|
||||
#ifdef __XTENSA_CALL0_ABI__
|
||||
|
||||
/* Need to preserve a8-11. _xtensa_coproc_savestate modifies a2-a7,
|
||||
* a13-a15. So no registers need be saved.
|
||||
*/
|
||||
|
||||
ENTRY(16)
|
||||
|
||||
/* Call _xtensa_coproc_savestate() with A2=address of co-processor
|
||||
* save area.
|
||||
*/
|
||||
|
||||
call0 _xtensa_coproc_savestate
|
||||
RET(16)
|
||||
|
||||
#else
|
||||
|
||||
/* Need to preserve a8-15. _xtensa_coproc_savestate modifies a2-a7,
|
||||
* a13-a15. So only a13-a15 need be preserved.
|
||||
*/
|
||||
|
||||
ENTRY(16)
|
||||
s32i a13, sp, LOCAL_OFFSET(1)
|
||||
s32i a14, sp, LOCAL_OFFSET(2)
|
||||
s32i a15, sp, LOCAL_OFFSET(3)
|
||||
|
||||
/* Call _xtensa_coproc_savestate() with A2=address of co-processor
|
||||
* save area.
|
||||
*/
|
||||
|
||||
call0 _xtensa_coproc_savestate
|
||||
|
||||
/* Restore a13-15 and return */
|
||||
|
||||
132i a13, sp, LOCAL_OFFSET(1)
|
||||
132i a14, sp, LOCAL_OFFSET(2)
|
||||
132i a15, sp, LOCAL_OFFSET(3)
|
||||
|
||||
RET(16)
|
||||
|
||||
#endif
|
||||
|
||||
.size xtensa_coproc_savestate, . - xtensa_coproc_savestate
|
||||
|
||||
/****************************************************************************
|
||||
* Name: _xtensa_coproc_restorestate
|
||||
*
|
||||
@ -206,7 +281,7 @@ _xtensa_coproc_savestate:
|
||||
* around the assembly language call to _xtensa_coproc_restorestate.
|
||||
*
|
||||
* Entry Conditions:
|
||||
* - A2 holds the address of the threads state save area
|
||||
* - A2 holds the address of the co-processor state save area
|
||||
* - The incoming thread is set as the current thread.
|
||||
* - CPENABLE is set up correctly for all required coprocessors.
|
||||
*
|
||||
@ -306,4 +381,76 @@ _xtensa_coproc_restorestate:
|
||||
|
||||
.size _xtensa_coproc_restorestate, . - _xtensa_coproc_restorestate
|
||||
|
||||
/****************************************************************************
|
||||
* Name: xtensa_coproc_restorestate
|
||||
*
|
||||
* Description:
|
||||
* Restore any callee-saved coprocessor state for the incoming thread.
|
||||
* xtensa_coproc_restorestate() is simply a C wrapper around the assembly
|
||||
* language call to _xtensa_coproc_restorestate.
|
||||
*
|
||||
* Input Parameters:
|
||||
* - A2 holds the address of the threads state save area
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
* Called with interrupts disabled.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
.global xtensa_coproc_restorestate
|
||||
.type xtensa_coproc_restorestate, @function
|
||||
|
||||
.align 4
|
||||
.literal_position
|
||||
.align 4
|
||||
|
||||
xtensa_coproc_restorestate:
|
||||
|
||||
#ifdef __XTENSA_CALL0_ABI__
|
||||
|
||||
/* Need to preserve a8-11. _xtensa_coproc_restorestate modifies a2-a7,
|
||||
* a13-a15. So no registers need be saved.
|
||||
*/
|
||||
|
||||
ENTRY(16)
|
||||
|
||||
/* Call _xtensa_coproc_restorestate() with A2=address of co-processor
|
||||
* save area.
|
||||
*/
|
||||
|
||||
call0 _xtensa_coproc_restorestate
|
||||
RET(16)
|
||||
|
||||
#else
|
||||
|
||||
/* Need to preserve a8-15. _xtensa_coproc_savestate modifies a2-a7,
|
||||
* a13-a15. So only a13-a15 need be preserved.
|
||||
*/
|
||||
|
||||
ENTRY(16)
|
||||
s32i a13, sp, LOCAL_OFFSET(1)
|
||||
s32i a14, sp, LOCAL_OFFSET(2)
|
||||
s32i a15, sp, LOCAL_OFFSET(3)
|
||||
|
||||
/* Call _xtensa_coproc_restorestate() with A2=address of co-processor
|
||||
* save area.
|
||||
*/
|
||||
|
||||
call0 _xtensa_coproc_restorestate
|
||||
|
||||
/* Restore a13-15 and return */
|
||||
|
||||
132i a13, sp, LOCAL_OFFSET(1)
|
||||
132i a14, sp, LOCAL_OFFSET(2)
|
||||
132i a15, sp, LOCAL_OFFSET(3)
|
||||
|
||||
RET(16)
|
||||
|
||||
#endif
|
||||
|
||||
.size xtensa_coproc_restorestate, . - xtensa_coproc_restorestate
|
||||
|
||||
#endif /* XCHAL_CP_NUM > 0 */
|
||||
|
@ -1,5 +1,5 @@
|
||||
/****************************************************************************
|
||||
* arch/xtensa/src/common/xtensa_cpsave.c
|
||||
* arch/xtensa/src/common/xtensa_cpenable.c
|
||||
*
|
||||
* Copyright (C) 2016 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
@ -53,89 +53,6 @@
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: xtensa_coproc_savestate
|
||||
*
|
||||
* Description:
|
||||
* If there is a current thread and it has a coprocessor state save area,
|
||||
* then save all callee-saved state into this area. xtensa_coproc_savestate()
|
||||
* is simply a C wrapper around the assembly language call to
|
||||
* _xtensa_coproc_savestate.
|
||||
*
|
||||
* Entry Conditions:
|
||||
* - The thread being switched out is still the current thread.
|
||||
* - CPENABLE state reflects which coprocessors are active.
|
||||
*
|
||||
* Exit conditions:
|
||||
* - All necessary CP callee-saved state has been saved.
|
||||
*
|
||||
* Input Parameters:
|
||||
* tcb - A pointer to the TCB of thread whose co-processor state is to
|
||||
* be saved.
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
* Called with interrupts disabled.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void xtensa_coproc_savestate(struct tcb_s *tcb)
|
||||
{
|
||||
uint32_t cpstate = (uint32_t)((uintptr_t)&tcb->xcp.cpstate);
|
||||
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"mov a2, %0\n"
|
||||
"call0 _xtensa_coproc_savestate\n"
|
||||
:
|
||||
: "r" (cpstate)
|
||||
: "a0", "a2", "a3", "a4", "a5", "a6", "a7", "a13", "a14", "a15"
|
||||
);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: xtensa_coproc_restorestate
|
||||
*
|
||||
* Description:
|
||||
* Restore any callee-saved coprocessor state for the incoming thread.
|
||||
* xtensa_coproc_restorestate() is simply a C wrapper around the assembly
|
||||
* language call to _xtensa_coproc_restorestate.
|
||||
*
|
||||
* Entry Conditions:
|
||||
* - CPENABLE is set up correctly for all required coprocessors.
|
||||
*
|
||||
* Exit conditions:
|
||||
* - All necessary CP callee-saved state has been restored.
|
||||
* - CPENABLE - unchanged.
|
||||
*
|
||||
* Input Parameters:
|
||||
* tcb - A pointer to the TCB of thread whose co-processor state is to
|
||||
* be restored.
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
* Called with interrupts disabled.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void xtensa_coproc_restorestate(struct tcb_s *tcb)
|
||||
{
|
||||
uint32_t cpstate = (uint32_t)((uintptr_t)&tcb->xcp.cpstate);
|
||||
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"mov a2, %0\n"
|
||||
"call0 _xtensa_coproc_restorestate\n"
|
||||
:
|
||||
: "r" (cpstate)
|
||||
: "a0", "a2", "a3", "a4", "a5", "a6", "a7", "a13", "a14", "a15"
|
||||
);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: xtensa_coproc_enable
|
||||
*
|
||||
@ -238,5 +155,4 @@ void xtensa_coproc_disable(struct xtensa_cpstate_s *cpstate, int cpset)
|
||||
leave_critical_section(flags);
|
||||
}
|
||||
|
||||
|
||||
#endif /* XCHAL_CP_NUM */
|
@ -175,7 +175,7 @@ void _exit(int status)
|
||||
#if XCHAL_CP_NUM > 0
|
||||
/* Set up the co-processor state for the newly started thread. */
|
||||
|
||||
xtensa_coproc_restorestate(tcb);
|
||||
xtensa_coproc_restorestate(&tcb->xcp.cpstate);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_ADDRENV
|
||||
|
@ -103,7 +103,7 @@ uint32_t *xtensa_irq_dispatch(int irq, uint32_t *regs)
|
||||
* NOTE 2. We saved a reference TCB of the original thread on entry.
|
||||
*/
|
||||
|
||||
xtensa_coproc_savestate(tcb);
|
||||
xtensa_coproc_savestate(&tcb->xcp.cpstate);
|
||||
|
||||
/* Then set up the co-processor state for the to-be-started thread.
|
||||
*
|
||||
@ -112,7 +112,7 @@ uint32_t *xtensa_irq_dispatch(int irq, uint32_t *regs)
|
||||
*/
|
||||
|
||||
tcb = this_task();
|
||||
xtensa_coproc_restorestate(tcb);
|
||||
xtensa_coproc_restorestate(&tcb->xcp.cpstate);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_ADDRENV
|
||||
|
@ -124,7 +124,7 @@ void up_release_pending(void)
|
||||
* processor save area.
|
||||
*/
|
||||
|
||||
xtensa_coproc_savestate(rtcb);
|
||||
xtensa_coproc_savestate(&rtcb->xcp.cpstate);
|
||||
#endif
|
||||
/* Restore the exception context of the rtcb at the (new) head
|
||||
* of the ready-to-run task list.
|
||||
@ -135,7 +135,7 @@ void up_release_pending(void)
|
||||
#if XCHAL_CP_NUM > 0
|
||||
/* Set up the co-processor state for the newly started thread. */
|
||||
|
||||
xtensa_coproc_restorestate(rtcb);
|
||||
xtensa_coproc_restorestate(&rtcb->xcp.cpstate);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_ADDRENV
|
||||
|
@ -177,7 +177,7 @@ void up_reprioritize_rtr(struct tcb_s *tcb, uint8_t priority)
|
||||
* processor save area.
|
||||
*/
|
||||
|
||||
xtensa_coproc_savestate(rtcb);
|
||||
xtensa_coproc_savestate(&rtcb->xcp.cpstate);
|
||||
#endif
|
||||
/* Restore the exception context of the rtcb at the (new) head
|
||||
* of the ready-to-run task list.
|
||||
@ -188,7 +188,7 @@ void up_reprioritize_rtr(struct tcb_s *tcb, uint8_t priority)
|
||||
#if XCHAL_CP_NUM > 0
|
||||
/* Set up the co-processor state for the newly started thread. */
|
||||
|
||||
xtensa_coproc_restorestate(rtcb);
|
||||
xtensa_coproc_restorestate(&rtcb->xcp.cpstate);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_ADDRENV
|
||||
|
@ -152,9 +152,9 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
|
||||
|
||||
CURRENT_REGS[REG_PC] = (uint32_t)xtensa_sigdeliver;
|
||||
#ifdef __XTENSA_CALL0_ABI__
|
||||
CURRENT_REGS[REG_PS] = (uint32_t)(PS_INTLEVEL(0) | PS_UM);
|
||||
CURRENT_REGS[REG_PS] = (uint32_t)(PS_INTLEVEL(XCHAL_EXCM_LEVEL) | PS_UM);
|
||||
#else
|
||||
CURRENT_REGS[REG_PS] = (uint32_t)(PS_INTLEVEL(0) | PS_UM | PS_WOE);
|
||||
CURRENT_REGS[REG_PS] = (uint32_t)(PS_INTLEVEL(XCHAL_EXCM_LEVEL) | PS_UM | PS_WOE);
|
||||
#endif
|
||||
|
||||
/* And make sure that the saved context in the TCB is the same
|
||||
@ -187,9 +187,9 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
|
||||
|
||||
tcb->xcp.regs[REG_PC] = (uint32_t)xtensa_sigdeliver;
|
||||
#ifdef __XTENSA_CALL0_ABI__
|
||||
tcb->xcp.regs[REG_PS] = (uint32_t)(PS_INTLEVEL(0) | PS_UM);
|
||||
tcb->xcp.regs[REG_PS] = (uint32_t)(PS_INTLEVEL(XCHAL_EXCM_LEVEL) | PS_UM);
|
||||
#else
|
||||
tcb->xcp.regs[REG_PS] = (uint32_t)(PS_INTLEVEL(0) | PS_UM | PS_WOE);
|
||||
tcb->xcp.regs[REG_PS] = (uint32_t)(PS_INTLEVEL(XCHAL_EXCM_LEVEL) | PS_UM | PS_WOE);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -138,7 +138,7 @@ void up_unblock_task(struct tcb_s *tcb)
|
||||
* processor save area.
|
||||
*/
|
||||
|
||||
xtensa_coproc_savestate(rtcb);
|
||||
xtensa_coproc_savestate(&rtcb->xcp.cpstate);
|
||||
#endif
|
||||
|
||||
/* Restore the exception context of the new task that is ready to
|
||||
@ -151,7 +151,7 @@ void up_unblock_task(struct tcb_s *tcb)
|
||||
#if XCHAL_CP_NUM > 0
|
||||
/* Set up the co-processor state for the newly started thread. */
|
||||
|
||||
xtensa_coproc_restorestate(rtcb);
|
||||
xtensa_coproc_restorestate(&rtcb->xcp.cpstate);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_ADDRENV
|
||||
|
@ -44,7 +44,7 @@ CMN_ASRCS = xtensa_context.S xtensa_coproc.S xtensa_cpuint.S
|
||||
CMN_ASRCS += xtensa_int_handlers.S xtensa_nmi_handler.S xtensa_vectors.S
|
||||
|
||||
CMN_CSRCS = xtensa_assert.c xtensa_blocktask.c xtensa_copystate.c
|
||||
CMN_CSRCS += xtensa_cpsave.c xtensa_createstack.c xtensa_exit.c xtensa_idle.c
|
||||
CMN_CSRCS += xtensa_cpenable.c xtensa_createstack.c xtensa_exit.c xtensa_idle.c
|
||||
CMN_CSRCS += xtensa_initialize.c xtensa_initialstate.c xtensa_interruptcontext.c
|
||||
CMN_CSRCS += xtensa_irqdispatch.c xtensa_lowputs.c xtensa_mdelay.c
|
||||
CMN_CSRCS += xtensa_modifyreg8.c xtensa_modifyreg16.c xtensa_modifyreg32.c
|
||||
|
Loading…
x
Reference in New Issue
Block a user