Xtensa: More co-processor save logic. Still not complete.
This commit is contained in:
parent
a90d0bbf2e
commit
9345c6f4db
@ -45,6 +45,8 @@
|
||||
# include <stdbool.h>
|
||||
#endif
|
||||
|
||||
#include <arch/chip/core-isa.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
@ -252,6 +254,11 @@ int xtensa_swint(int irq, FAR void *context);
|
||||
int xtensa_context_save(uint32_t *regs);
|
||||
void xtensa_context_restore(uint32_t *regs) noreturn_function;
|
||||
|
||||
#if XCHAL_CP_NUM > 0
|
||||
void xtensa_coproc_savestate(struct tcb_s *tcb);
|
||||
void xtensa_coproc_restorestate(struct tcb_s *tcb);
|
||||
#endif
|
||||
|
||||
/* Signals */
|
||||
|
||||
void xtensa_sigdeliver(void);
|
||||
|
@ -146,7 +146,6 @@ xtensa_coproc_init:
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#if 0 /* Not used in current design */
|
||||
.global xtensa_coproc_release
|
||||
.type xtensa_coproc_release, @function
|
||||
|
||||
@ -177,7 +176,6 @@ xtensa_coproc_release:
|
||||
ret
|
||||
|
||||
.size xtensa_coproc_release, . - xtensa_coproc_release
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: _xtensa_coproc_savestate
|
||||
@ -188,7 +186,12 @@ xtensa_coproc_release:
|
||||
* called from the solicited context switch handler. It calls a system-
|
||||
* specific function to get the coprocessor save area base address.
|
||||
*
|
||||
* It is also called from xtensa_coproc_savestate() for synchronous
|
||||
* context switches. xtensa_coproc_savestate() is simply a C wrapper
|
||||
* around the assembly language call to _xtensa_coproc_savestate.
|
||||
*
|
||||
* Entry Conditions:
|
||||
* - A2 holds the address of the threads 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.
|
||||
@ -210,18 +213,17 @@ xtensa_coproc_release:
|
||||
|
||||
_xtensa_coproc_savestate:
|
||||
|
||||
/* At entry, CPENABLE should be showing which CPs are enabled. */
|
||||
/* Move the address of the thread state save area to R15 */
|
||||
|
||||
mov a15, a2 /* A15 is now the address of the save area */
|
||||
|
||||
/* CPENABLE should show which CPs are enabled. */
|
||||
|
||||
rsr a2, CPENABLE /* a2 = which CPs are enabled */
|
||||
beqz a2, .Ldone /* Quick exit if none */
|
||||
|
||||
mov a14, a0 /* Save return address */
|
||||
call0 XT_RTOS_CP_STATE /* Get address of CP save area */
|
||||
mov a0, a14 /* Restore return address */
|
||||
beqz a15, .Ldone /* if none then nothing to do */
|
||||
beqz a2, .Ldone1 /* Quick exit if none */
|
||||
|
||||
s16i a2, a15, XTENSA_CPCSST /* Save mask of CPs being stored */
|
||||
movi a13, _xtensa_coproc_saoffsets /* Array of CP save offsets */
|
||||
movi a13, _xtensa_coproc_saoffsets /* Array of CP save offsets */
|
||||
l32i a15, a15, XTENSA_CPASA /* a15 = base of aligned save area */
|
||||
|
||||
#if XTENSA_CP0_SA_SIZE > 0
|
||||
@ -288,7 +290,7 @@ _xtensa_coproc_savestate:
|
||||
2:
|
||||
#endif
|
||||
|
||||
.Ldone:
|
||||
.Ldone1:
|
||||
ret
|
||||
|
||||
.size _xtensa_coproc_savestate, . - _xtensa_coproc_savestate
|
||||
@ -300,12 +302,17 @@ _xtensa_coproc_savestate:
|
||||
* Restore any callee-saved coprocessor state for the incoming thread.
|
||||
* This function is called from coprocessor exception handling, when
|
||||
* giving ownership to a thread that solicited a context switch earlier.
|
||||
* It calls a system-specific function to get the coprocessor save area base address.
|
||||
* It calls a system-specific function to get the coprocessor save area
|
||||
* base address.
|
||||
*
|
||||
* It is also called from xtensa_coproc_restorestate() for synchronous
|
||||
* context switches. xtensa_coproc_restorestate() is simply a C wrapper
|
||||
* around the assembly language call to _xtensa_coproc_restorestate.
|
||||
*
|
||||
* Entry Conditions:
|
||||
* - A2 holds the address of the threads state save area
|
||||
* - The incoming thread is set as the current thread.
|
||||
* - CPENABLE is set up correctly for all required coprocessors.
|
||||
* - a2 = mask of coprocessors to be restored.
|
||||
*
|
||||
* Exit conditions:
|
||||
* - All necessary CP callee-saved state has been restored.
|
||||
@ -325,16 +332,14 @@ _xtensa_coproc_savestate:
|
||||
|
||||
_xtensa_coproc_restorestate:
|
||||
|
||||
mov a14, a0 /* Save return address */
|
||||
call0 XT_RTOS_CP_STATE /* Get address of CP save area */
|
||||
mov a0, a14 /* Restore return address */
|
||||
beqz a15, .Ldone2 /* if none then nothing to do */
|
||||
/* Move the address of the thread state save area to R15 */
|
||||
|
||||
l16ui a3, a15, XTENSA_CPCSST /* a3 = which CPs have been saved */
|
||||
xor a3, a3, a2 /* Clear the ones being restored */
|
||||
mov a15, a2 /* A15 is now the address of the save area */
|
||||
l16ui a2, a15, XTENSA_CPCSST /* a3 = which CPs have been saved */
|
||||
movi a3, 0 /* Clear the ones being restored (all of them) */
|
||||
s32i a3, a15, XTENSA_CPCSST /* Update saved CP mask */
|
||||
|
||||
movi a13, _xtensa_coproc_saoffsets /* Array of CP save offsets */
|
||||
movi a13, _xtensa_coproc_saoffsets /* Array of CP save offsets */
|
||||
l32i a15, a15, XTENSA_CPASA /* a15 = base of aligned save area */
|
||||
|
||||
#if XTENSA_CP0_SA_SIZE
|
||||
@ -401,7 +406,6 @@ _xtensa_coproc_restorestate:
|
||||
2:
|
||||
#endif
|
||||
|
||||
.Ldone2:
|
||||
ret
|
||||
|
||||
.size _xtensa_coproc_restorestate, . - _xtensa_coproc_restorestate
|
||||
|
@ -39,8 +39,78 @@
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <arch/chip/core-isa.h>
|
||||
|
||||
#include "xtensa.h"
|
||||
|
||||
#if XCHAL_CP_NUM > 0
|
||||
|
||||
/****************************************************************************
|
||||
* 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void xtensa_coproc_savestate(struct tcb_s *tcb)
|
||||
{
|
||||
uint32_t cpsave = (uint32_t)((uintptr_t)&tcp->xcp.cpsave);
|
||||
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"mov a2, %0\n"
|
||||
"call0 _xtensa_coproc_savestate\n"
|
||||
:
|
||||
: "r" (cpsave)
|
||||
: "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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void xtensa_coproc_restorestate(struct tcb_s *tcb)
|
||||
{
|
||||
uint32_t cpsave = (uint32_t)((uintptr_t)&tcp->xcp.cpsave);
|
||||
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"mov a2, %0\n"
|
||||
"mov a3, %1\n"
|
||||
"call0 _xtensa_coproc_restorestate\n"
|
||||
:
|
||||
: "r" (cpmask) "r" (cpsave)
|
||||
: "a0", "a2", "a3", "a4", "a5", "a6", "a7", "a13", "a14", "a15"
|
||||
)
|
||||
}
|
||||
|
||||
#endif /* XCHAL_CP_NUM */
|
||||
|
@ -102,7 +102,7 @@ uint32_t *xtensa_irq_dispatch(int irq, uint32_t *regs)
|
||||
* NOTE 2. We saved a reference TCB of the original thread on entry.
|
||||
*/
|
||||
|
||||
esp32_coproc_savestate(tcb->xcp.cpstate);
|
||||
xtensa_coproc_savestate(tcb);
|
||||
|
||||
/* Then set up the co-processor state for the to-be-started thread.
|
||||
*
|
||||
@ -111,7 +111,7 @@ uint32_t *xtensa_irq_dispatch(int irq, uint32_t *regs)
|
||||
*/
|
||||
|
||||
tcb = this_task();
|
||||
esp32_coproc_restorestate(tcb->xcp.cpstate);
|
||||
esp32_coproc_restorestate(tcb);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_ADDRENV
|
||||
|
Loading…
Reference in New Issue
Block a user