Xtensa: Cleanup of co-processor logic; remove some unnecessary things.

This commit is contained in:
Gregory Nutt
2016-10-29 09:36:33 -06:00
parent 2fa8b9ba34
commit ccf5b4e357
10 changed files with 202 additions and 36 deletions
+11
View File
@@ -44,6 +44,17 @@ config XTENSA_USE_OVLY
---help---
Enable code overlay support. This option is currently unsupported.
config XTENSA_CP_INITSET
bool "Default co-processor enables"
default 1
range 0 65535
---help---
Co-processors may be enabled on a thread by calling xtensa_coproc_enable()
and disabled by calling xtensa_coproc_disable(). Some co-processors
should be enabled on all threads by default. That set of co-processors
is provided by CONFIG_XTENSA_CP_INITSET. Each bit corresponds to one
coprocessor with the same bit layout as for the CPENABLE register.
config ARCH_CHIP
string
default "esp32" if ARCH_CHIP_ESP32
+1 -1
View File
@@ -162,7 +162,7 @@ struct xcptcontext
#if XCHAL_CP_NUM > 0
/* Co-processor save area */
struct struct xtensa_cpstate_s cpstate;
struct xtensa_cpstate_s cpstate;
#endif
#ifdef CONFIG_LIB_SYSCALL
+37 -19
View File
@@ -52,6 +52,10 @@
#define _CP_ALIGNUP(n,val) (((val) + _CP_MASK(n)) & ~_CP_MASK(n))
#define _CP_ALIGNDOWN(n,val) ((val) & ~_CP_MASK(n))
/* A set of all co-processors */
#define XTENSA_CP_ALLSET ((1 << XCHAL_CP_NUM) - 1)
/* CO-PROCESSOR STATE SAVE AREA FOR A THREAD
*
* NuttX provides an area per thread to save the state of co-processors when
@@ -93,18 +97,11 @@
* XTENSA_CPSTORED
* A bitmask with the same layout as CPENABLE, a bit per co-processor.
* Indicates whether the state of each co-processor is saved in the state
* save area. When a thread enters the kernel, only the state of co-procs
* still enabled in CPENABLE is saved. When the co-processor exception
* handler assigns ownership of a co-processor to a thread, it restores
* the saved state only if this bit is set, and clears this bit.
*
* XTENSA_CPCSST
* A bitmask with the same layout as CPENABLE, a bit per co-processor.
* Indicates whether callee-saved state is saved in the state save area.
* Callee-saved state is saved by itself on a solicited context switch,
* and restored when needed by the coprocessor exception handler.
* Unsolicited switches will cause the entire coprocessor to be saved
* when necessary.
* save area. When the state of a thread is saved, only the state of co-procs
* still enabled in CPENABLE is saved. When the co-processor state is
* is restored, the state is only resotred for a co-processor if this bit
* is set. This bist set is cleared after after co-processor state has
* been restored.
*
* XTENSA_CPASA
* Pointer to the aligned save area. Allows it to be aligned more than
@@ -129,8 +126,7 @@
#define XTENSA_CPENABLE 0 /* (2 bytes) coprocessors active for this thread */
#define XTENSA_CPSTORED 2 /* (2 bytes) coprocessors saved for this thread */
#define XTENSA_CPCSST 4 /* (2 bytes) coprocessor callee-saved regs stored for this thread */
#define XTENSA_CPASA 8 /* (4 bytes) ptr to aligned save area */
#define XTENSA_CPASA 4 /* (4 bytes) ptr to aligned save area */
/****************************************************************************
* Public Types
@@ -140,11 +136,33 @@
struct xtensa_cpstate_s
{
uint16_t cpenable; /* (2 bytes) coprocessors active for this thread */
uint16_t cpstored; /* (2 bytes) coprocessors saved for this thread */
uint16_t cpcsst /* (2 bytes) coprocessor callee-saved regs stored for this thread */
uint16_t unused; /* (2 bytes) unused */
uint32_t *cpasa; /* (4 bytes) ptr to aligned save area */
uint16_t cpenable; /* (2 bytes) Co-processors active for this thread */
uint16_t cpstored; /* (2 bytes) Co-processors saved for this thread */
uint32_t *cpasa; /* (4 bytes) Pointer to aligned save area */
}
/* Return the current value of the CPENABLE register */
static inline uint32_t xtensa_get_cpenable(void)
{
uint32_t cpenable;
__asm__ __volatile__
(
"rsr %0, CPENABLE" : "=r"(cpenable)
);
return cpenable;
}
/* Set the value of the CPENABLE register */
static inline void xtensa_set_cpenable(uint32_t cpenable)
{
__asm__ __volatile__
(
"wsr %0, PS" : : "r"(cpenable)
);
}
#endif /* __ASSEMBLY__ */
+2
View File
@@ -241,6 +241,8 @@ void xtensa_coproc_init(void);
struct xtensa_cpstate_s;
void xtensa_coproc_release(struct xtensa_cpstate_s *cpstate);
void xtensa_coproc_enable(struct xtensa_cpstate_s *cpstate, int cpset);
void xtensa_coproc_disable(struct xtensa_cpstate_s *cpstate, int cpset);
#endif
/* IRQs */
+4 -3
View File
@@ -113,6 +113,7 @@ xtensa_coproc_init:
movi a2, _xt_coproc_owner_sa /* a2 = base of owner array */
addi a3, a2, (XTENSA_CP_MAX*portNUM_PROCESSORS) << 2 /* a3 = top+1 of owner array */
movi a4, 0 /* a4 = 0 (unowned) */
1: s32i a4, a2, 0
addi a2, a2, 4
bltu a2, a3, 1b
@@ -223,7 +224,7 @@ _xtensa_coproc_savestate:
rsr a2, CPENABLE /* a2 = which CPs are enabled */
beqz a2, .Ldone1 /* Quick exit if none */
s16i a2, a15, XTENSA_CPCSST /* Save mask of CPs being stored */
s16i a2, a15, XTENSA_CPSTORED /* Save mask of CPs being stored */
movi a13, _xtensa_coproc_saoffsets /* Array of CP save offsets */
l32i a15, a15, XTENSA_CPASA /* a15 = base of aligned save area */
@@ -336,9 +337,9 @@ _xtensa_coproc_restorestate:
/* Move the address of the thread state save area to R15 */
mov a15, a2 /* A15 is now the address of the save area */
l16ui a2, a15, XTENSA_CPCSST /* a3 = which CPs have been saved */
l16ui a2, a15, XTENSA_CPSTORED /* a2 = 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 */
s16i a3, a15, XTENSA_CPSTORED /* Clear saved CP mask */
movi a13, _xtensa_coproc_saoffsets /* Array of CP save offsets */
l32i a15, a15, XTENSA_CPASA /* a15 = base of aligned save area */
+135 -10
View File
@@ -39,6 +39,8 @@
#include <nuttx/config.h>
#include <nuttx/irq.h>
#include <arch/xtensa/xtensa_coproc.h>
#include <arch/chip/core-isa.h>
#include "xtensa.h"
@@ -58,12 +60,22 @@
* 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.
* 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.
* 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.
*
****************************************************************************/
@@ -89,12 +101,22 @@ void xtensa_coproc_savestate(struct tcb_s *tcb)
* 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.
* Entry Conditions:
* - CPENABLE is set up correctly for all required coprocessors.
*
* Exit conditions:
* - All necessary CP callee-saved state has been restored.
* - CPENABLE - unchanged.
* 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.
*
****************************************************************************/
@@ -113,4 +135,107 @@ void xtensa_coproc_restorestate(struct tcb_s *tcb)
)
}
/****************************************************************************
* Name: xtensa_coproc_enable
*
* Description:
* Enable a set of co-processors.
*
* Input Parameters:
* cpstate - A pointer to the Co-processor state save structure.
* cpset - A bit set of co-processors to be enabled. Matches bit layout
* of the CPENABLE register. Bit 0-XCHAL_CP_NUM: 0 = no change
* 1 = enable
*
* Returned Value:
* None
*
****************************************************************************/
void xtensa_coproc_enable(struct xtensa_cpstate_s *cpstate, int cpset)
{
irqstate_t flags;
uint32_t cpenable;
/* These operations must be atomic */
flags = enter_critical_section();
/* Don't enable co-processors that may already be enabled
*
* cpenable
* 0 1
* --- ---
* cpset 0 | 0 0
* 1 | 1 0
*/
cpset ^= (cpset & cpstate->cpenable);
if (cpset != 0)
{
/* Enable the co-processors */
cpenable = xtensa_get_cpenable();
cpenable |= cpset;
xtensa_put_cpenable(cpenable);
cpstate->cpenable = cpenable;
cpsates->cpstored &= ~cpset;
}
leave_critical_section();
}
/****************************************************************************
* Name: xtensa_coproc_disable
*
* Description:
* Enable a set of co-processors.
*
* Input Parameters:
* cpstate - A pointer to the Co-processor state save structure.
* cpset - A bit set of co-processors to be enabled. Matches bit layout
* of the CPENABLE register. Bit 0-XCHAL_CP_NUM: 0 = no change
* 1 = disable
*
* Returned Value:
* None
*
****************************************************************************/
void xtensa_coproc_disable(struct xtensa_cpstate_s *cpstate, int cpset)
{
irqstate_t flags;
uint32_t cpenable;
/* These operations must be atomic */
flags = enter_critical_section();
/* Don't disable co-processors that are already be disabled.
*
* cpenable
* 0 1
* --- ---
* cpset 0 | 0 0
* 1 | 0 1
*/
cpset &= cpstate->cpenable;
if (cpset != 0)
{
/* Disable the co-processors */
cpenable = xtensa_get_cpenable();
cpenable &= ~cpset;
xtensa_put_cpenable(cpenable);
cpstate->cpenable = cpenable;
cpsates->cpstored &= ~cpset;
}
leave_critical_section();
}
#endif /* XCHAL_CP_NUM */
@@ -215,8 +215,6 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
xcp->cpstate.cpenable = 0; /* No coprocessors active for this thread */
xcp->cpstate.cpstored = 0; /* No coprocessors saved for this thread */
xcp->cpstate.cpcsst = 0; /* No oprocessor callee-saved regs stored for this thread */
xcp->cpstate.unused = 0; /* unused */
xcp->cpstate.cpasa = (uint32_t *)cpstart; /* Start of aligned save area */
#endif
+2 -1
View File
@@ -156,10 +156,11 @@ void _exit(int status)
#endif
#if XCHAL_CP_NUM > 0
/* Disable preprocessor support fo the task that is exit-ing. */
/* Disable co-processor support for the task that is exit-ing. */
tcb = this_task();
xtensa_coproc_release(&tcb->xcp.cpstate);
xtensa_coproc_disable(&tcb->xcp.cpstate, XTENSA_CP_ALLSET);
#endif
/* Destroy the task at the head of the ready to run list. */
@@ -94,4 +94,13 @@ void up_initial_state(struct tcb_s *tcb)
xcp->regs[REG_PS] = PS_UM | PS_EXCM | PS_WOE | PS_CALLINC(1);
#endif
#if XCHAL_CP_NUM > 0
/* Set up the co-processors that will be enabled initially when the thread
* starts (see xtensa_coproc.h)
*/
xcp->cpstate.cpenable = CONFIG_XTENSA_CP_INITSET;
xcp->cpstate.cpstored = 0; /* No coprocessors haved statee saved for this thread */
#endif
}
+1
View File
@@ -174,6 +174,7 @@ _xtensa_level6_vector:
.align 4
_xtensa_nmi_vector:
wsr a0, EXCSAVE + XCHAL_NMILEVEL _ /* preserve a0 */
call0 _xt_nmi /* load interrupt handler */