From 2fa8b9ba34d73bd0157c1d4f407a060fae796c2b Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Fri, 28 Oct 2016 13:03:25 -0600 Subject: [PATCH] Xtensa ESP32: Co-processor state is code complete but uncompiled and untested. --- arch/xtensa/src/common/xtensa.h | 5 +++++ arch/xtensa/src/common/xtensa_blocktask.c | 15 +++++++++++++++ arch/xtensa/src/common/xtensa_coproc.S | 1 + arch/xtensa/src/common/xtensa_exit.c | 13 +++++++++++++ arch/xtensa/src/common/xtensa_irqdispatch.c | 2 +- arch/xtensa/src/common/xtensa_releasepending.c | 15 +++++++++++++++ arch/xtensa/src/common/xtensa_reprioritizertr.c | 15 +++++++++++++++ arch/xtensa/src/common/xtensa_sigdeliver.c | 4 +++- arch/xtensa/src/common/xtensa_unblocktask.c | 16 ++++++++++++++++ arch/xtensa/src/esp32/esp32_cpustart.c | 2 ++ arch/xtensa/src/esp32/esp32_start.c | 2 ++ 11 files changed, 88 insertions(+), 2 deletions(-) diff --git a/arch/xtensa/src/common/xtensa.h b/arch/xtensa/src/common/xtensa.h index 1f06126b2a..c646ca4fca 100644 --- a/arch/xtensa/src/common/xtensa.h +++ b/arch/xtensa/src/common/xtensa.h @@ -236,8 +236,13 @@ void xtensa_dumpstate(void); /* Common XTENSA functions */ /* Initialization */ +#if XCHAL_CP_NUM > 0 void xtensa_coproc_init(void); +struct xtensa_cpstate_s; +void xtensa_coproc_release(struct xtensa_cpstate_s *cpstate); +#endif + /* IRQs */ uint32_t *xtensa_int_decode(uint32_t *regs); diff --git a/arch/xtensa/src/common/xtensa_blocktask.c b/arch/xtensa/src/common/xtensa_blocktask.c index 82eb5e30c9..d2fb62bf48 100644 --- a/arch/xtensa/src/common/xtensa_blocktask.c +++ b/arch/xtensa/src/common/xtensa_blocktask.c @@ -45,6 +45,7 @@ #include #include +#include #include "sched/sched.h" #include "group/group.h" @@ -148,12 +149,26 @@ void up_block_task(struct tcb_s *tcb, tstate_t task_state) else if (!xtensa_context_save(rtcb->xcp.regs)) { +#if XCHAL_CP_NUM > 0 + /* Save the co-processor state in in the suspended thread's co- + * processor save area. + */ + + xtensa_coproc_savestate(rtcb); +#endif + /* Restore the exception context of the rtcb at the (new) head * of the ready-to-run task list. */ rtcb = this_task(); +#if XCHAL_CP_NUM > 0 + /* Set up the co-processor state for the newly started thread. */ + + xtensa_coproc_restorestate(rtcb); +#endif + #ifdef CONFIG_ARCH_ADDRENV /* Make sure that the address environment for the previously * running task is closed down gracefully (data caches dump, diff --git a/arch/xtensa/src/common/xtensa_coproc.S b/arch/xtensa/src/common/xtensa_coproc.S index 62e88570c1..434f090684 100644 --- a/arch/xtensa/src/common/xtensa_coproc.S +++ b/arch/xtensa/src/common/xtensa_coproc.S @@ -167,6 +167,7 @@ xtensa_coproc_release: 1: l32i a7, a3, 0 /* a7 = owner at a3 */ bne a2, a7, 2f /* if (coproc_sa_base == owner) */ + s32i a5, a3, 0 /* owner = unowned */ 2: addi a3, a3, 1<<2 /* a3 = next entry in owner array */ bltu a3, a4, 1b /* repeat until end of array */ diff --git a/arch/xtensa/src/common/xtensa_exit.c b/arch/xtensa/src/common/xtensa_exit.c index e6c64aaecd..6eaba07c51 100644 --- a/arch/xtensa/src/common/xtensa_exit.c +++ b/arch/xtensa/src/common/xtensa_exit.c @@ -155,6 +155,13 @@ void _exit(int status) sched_foreach(_xtensa_dumponexit, NULL); #endif +#if XCHAL_CP_NUM > 0 + /* Disable preprocessor support fo the task that is exit-ing. */ + + tcb = this_task(); + xtensa_coproc_release(&tcb->xcp.cpstate); +#endif + /* Destroy the task at the head of the ready to run list. */ (void)task_exit(); @@ -165,6 +172,12 @@ void _exit(int status) tcb = this_task(); +#if XCHAL_CP_NUM > 0 + /* Set up the co-processor state for the newly started thread. */ + + xtensa_coproc_restorestate(tcb); +#endif + #ifdef CONFIG_ARCH_ADDRENV /* Make sure that the address environment for the previously running * task is closed down gracefully (data caches dump, MMU flushed) and diff --git a/arch/xtensa/src/common/xtensa_irqdispatch.c b/arch/xtensa/src/common/xtensa_irqdispatch.c index b7ba9a3982..d509f83e42 100644 --- a/arch/xtensa/src/common/xtensa_irqdispatch.c +++ b/arch/xtensa/src/common/xtensa_irqdispatch.c @@ -111,7 +111,7 @@ uint32_t *xtensa_irq_dispatch(int irq, uint32_t *regs) */ tcb = this_task(); - esp32_coproc_restorestate(tcb); + xtensa_coproc_restorestate(tcb); #endif #ifdef CONFIG_ARCH_ADDRENV diff --git a/arch/xtensa/src/common/xtensa_releasepending.c b/arch/xtensa/src/common/xtensa_releasepending.c index 99dc0c39b8..4328d78a7e 100644 --- a/arch/xtensa/src/common/xtensa_releasepending.c +++ b/arch/xtensa/src/common/xtensa_releasepending.c @@ -41,8 +41,10 @@ #include #include + #include #include +#include #include "sched/sched.h" #include "group/group.h" @@ -117,12 +119,25 @@ void up_release_pending(void) else if (!xtensa_context_save(rtcb->xcp.regs)) { +#if XCHAL_CP_NUM > 0 + /* Save the co-processor state in in the suspended thread's co- + * processor save area. + */ + + xtensa_coproc_savestate(rtcb); +#endif /* Restore the exception context of the rtcb at the (new) head * of the ready-to-run task list. */ rtcb = this_task(); +#if XCHAL_CP_NUM > 0 + /* Set up the co-processor state for the newly started thread. */ + + xtensa_coproc_restorestate(rtcb); +#endif + #ifdef CONFIG_ARCH_ADDRENV /* Make sure that the address environment for the previously * running task is closed down gracefully (data caches dump, diff --git a/arch/xtensa/src/common/xtensa_reprioritizertr.c b/arch/xtensa/src/common/xtensa_reprioritizertr.c index 3cc2978f47..eb5255ece8 100644 --- a/arch/xtensa/src/common/xtensa_reprioritizertr.c +++ b/arch/xtensa/src/common/xtensa_reprioritizertr.c @@ -43,8 +43,10 @@ #include #include #include + #include #include +#include #include "sched/sched.h" #include "group/group.h" @@ -170,12 +172,25 @@ void up_reprioritize_rtr(struct tcb_s *tcb, uint8_t priority) else if (!xtensa_context_save(rtcb->xcp.regs)) { +#if XCHAL_CP_NUM > 0 + /* Save the co-processor state in in the suspended thread's co- + * processor save area. + */ + + xtensa_coproc_savestate(rtcb); +#endif /* Restore the exception context of the rtcb at the (new) head * of the ready-to-run task list. */ rtcb = this_task(); +#if XCHAL_CP_NUM > 0 + /* Set up the co-processor state for the newly started thread. */ + + xtensa_coproc_restorestate(rtcb); +#endif + #ifdef CONFIG_ARCH_ADDRENV /* Make sure that the address environment for the previously * running task is closed down gracefully (data caches dump, diff --git a/arch/xtensa/src/common/xtensa_sigdeliver.c b/arch/xtensa/src/common/xtensa_sigdeliver.c index 5f54c4035c..ce43441928 100644 --- a/arch/xtensa/src/common/xtensa_sigdeliver.c +++ b/arch/xtensa/src/common/xtensa_sigdeliver.c @@ -117,7 +117,9 @@ void xtensa_sigdeliver(void) (void)up_irq_save(); rtcb->pterrno = saved_errno; - /* Then restore the correct state for this thread of execution. */ + /* Then restore the correct state for this thread of execution. + * NOTE: The co-processor state should already be correct. + */ board_autoled_off(LED_SIGNAL); xtensa_context_restore(regs); diff --git a/arch/xtensa/src/common/xtensa_unblocktask.c b/arch/xtensa/src/common/xtensa_unblocktask.c index e7a37ba410..c7788927c6 100644 --- a/arch/xtensa/src/common/xtensa_unblocktask.c +++ b/arch/xtensa/src/common/xtensa_unblocktask.c @@ -41,8 +41,10 @@ #include #include + #include #include +#include #include "sched/sched.h" #include "group/group.h" @@ -131,6 +133,14 @@ void up_unblock_task(struct tcb_s *tcb) else if (!xtensa_context_save(rtcb->xcp.regs)) { +#if XCHAL_CP_NUM > 0 + /* Save the co-processor state in in the suspended thread's co- + * processor save area. + */ + + xtensa_coproc_savestate(rtcb); +#endif + /* Restore the exception context of the new task that is ready to * run (probably tcb). This is the new rtcb at the head of the * ready-to-run task list. @@ -138,6 +148,12 @@ void up_unblock_task(struct tcb_s *tcb) rtcb = this_task(); +#if XCHAL_CP_NUM > 0 + /* Set up the co-processor state for the newly started thread. */ + + xtensa_coproc_restorestate(rtcb); +#endif + #ifdef CONFIG_ARCH_ADDRENV /* Make sure that the address environment for the previously * running task is closed down gracefully (data caches dump, diff --git a/arch/xtensa/src/esp32/esp32_cpustart.c b/arch/xtensa/src/esp32/esp32_cpustart.c index 5bf82dfd42..b3c2e90c9c 100644 --- a/arch/xtensa/src/esp32/esp32_cpustart.c +++ b/arch/xtensa/src/esp32/esp32_cpustart.c @@ -146,6 +146,8 @@ int xtensa_start_handler(int irq, FAR void *context) xtensa_disable_all(); +#warning REVISIT: Do we need to disable co-processors here? + /* Detach all peripheral sources APP CPU interrupts */ for (i = 0; i < ESP32_NPERIPHERALS; i++) diff --git a/arch/xtensa/src/esp32/esp32_start.c b/arch/xtensa/src/esp32/esp32_start.c index a468e83a9c..409bcf8813 100644 --- a/arch/xtensa/src/esp32/esp32_start.c +++ b/arch/xtensa/src/esp32/esp32_start.c @@ -85,6 +85,8 @@ void IRAM_ATTR __start(void) memset(&_sbss, 0, (&_ebss - &_sbss) * sizeof(_sbss)); +#warning REVISIT: Do we need to disable co-processors here? + /* Make sure that the APP_CPU is disabled for now */ regval = getreg32(DPORT_APPCPU_CTRL_B_REG);