arch/risc-v: Merge duplicated logic by riscv_doirq

Signed-off-by: Huang Qi <huangqi3@xiaomi.com>
This commit is contained in:
Huang Qi 2022-03-31 12:53:47 +08:00 committed by Xiang Xiao
parent a6c22b722f
commit 32fe25278a
18 changed files with 18 additions and 299 deletions

View File

@ -33,7 +33,7 @@ CMN_CSRCS += riscv_interruptcontext.c riscv_modifyreg32.c riscv_puts.c riscv_mde
CMN_CSRCS += riscv_releasepending.c riscv_reprioritizertr.c
CMN_CSRCS += riscv_releasestack.c riscv_stackframe.c riscv_schedulesigaction.c
CMN_CSRCS += riscv_sigdeliver.c riscv_udelay.c riscv_unblocktask.c riscv_usestack.c
CMN_CSRCS += riscv_idle.c riscv_tcbinfo.c riscv_getnewintctx.c
CMN_CSRCS += riscv_idle.c riscv_tcbinfo.c riscv_getnewintctx.c riscv_doirq.c
ifeq ($(CONFIG_SCHED_BACKTRACE),y)
CMN_CSRCS += riscv_backtrace.c

View File

@ -66,52 +66,9 @@ void *riscv_dispatch_irq(uintptr_t vector, uintptr_t *regs)
riscv_ack_irq(irq);
#ifdef CONFIG_SUPPRESS_INTERRUPTS
PANIC();
#else
/* Current regs non-zero indicates that we are processing an interrupt;
* CURRENT_REGS is also used to manage interrupt level context switches.
*
* Nested interrupts are not supported
*/
DEBUGASSERT(CURRENT_REGS == NULL);
CURRENT_REGS = regs;
/* Deliver the IRQ */
irq_dispatch(irq, regs);
/* Check for a context switch. If a context switch occurred, then
* CURRENT_REGS will have a different value than it did on entry. If an
* interrupt level context switch has occurred, then restore the floating
* point state and the establish the correct address environment before
* returning from the interrupt.
*/
if (regs != CURRENT_REGS)
{
#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 set up the address environment for the new
* thread at the head of the ready-to-run list.
*/
group_addrenv(NULL);
#endif
}
#endif /* CONFIG_SUPPRESS_INTERRUPTS */
/* If a context switch occurred while processing the interrupt then
* CURRENT_REGS may have change value. If we return any value different
* from the input regs, then the lower level will know that a context
* switch occurred during interrupt processing.
*/
regs = (uintptr_t *)CURRENT_REGS;
CURRENT_REGS = NULL;
regs = riscv_doirq(irq, regs);
return regs;
}

View File

@ -33,7 +33,7 @@ CMN_CSRCS += riscv_interruptcontext.c riscv_modifyreg32.c riscv_puts.c
CMN_CSRCS += riscv_releasepending.c riscv_reprioritizertr.c
CMN_CSRCS += riscv_releasestack.c riscv_stackframe.c riscv_schedulesigaction.c
CMN_CSRCS += riscv_sigdeliver.c riscv_unblocktask.c riscv_usestack.c
CMN_CSRCS += riscv_mdelay.c riscv_idle.c
CMN_CSRCS += riscv_mdelay.c riscv_idle.c riscv_doirq.c
CMN_CSRCS += riscv_tcbinfo.c riscv_getnewintctx.c
ifeq ($(CONFIG_SCHED_BACKTRACE),y)

View File

@ -83,25 +83,13 @@ void *riscv_dispatch_irq(uintptr_t vector, uintptr_t *regs)
riscv_ack_irq(irq);
#ifdef CONFIG_SUPPRESS_INTERRUPTS
PANIC();
#else
/* Current regs non-zero indicates that we are processing an interrupt;
* CURRENT_REGS is also used to manage interrupt level context switches.
*
* Nested interrupts are not supported
*/
ASSERT(CURRENT_REGS == NULL);
CURRENT_REGS = regs;
/* MEXT means no interrupt */
if (RISCV_IRQ_MEXT != irq)
{
/* Deliver the IRQ */
irq_dispatch(irq, regs);
regs = riscv_doirq(irq, regs);
}
if (C906_IRQ_PERI_START <= irq)
@ -111,36 +99,5 @@ void *riscv_dispatch_irq(uintptr_t vector, uintptr_t *regs)
putreg32(irq - C906_IRQ_PERI_START, C906_PLIC_MCLAIM);
}
/* Check for a context switch. If a context switch occurred, then
* CURRENT_REGS will have a different value than it did on entry. If an
* interrupt level context switch has occurred, then restore the floating
* point state and the establish the correct address environment before
* returning from the interrupt.
*/
if (regs != CURRENT_REGS)
{
#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 set up the address environment for the new
* thread at the head of the ready-to-run list.
*/
group_addrenv(NULL);
#endif
}
#endif /* CONFIG_SUPPRESS_INTERRUPTS */
/* If a context switch occurred while processing the interrupt then
* CURRENT_REGS may have change value. If we return any value different
* from the input regs, then the lower level will know that a context
* switch occurred during interrupt processing.
*/
regs = (uintptr_t *)CURRENT_REGS;
CURRENT_REGS = NULL;
return regs;
}

View File

@ -36,7 +36,7 @@ CMN_CSRCS += riscv_interruptcontext.c riscv_modifyreg32.c riscv_puts.c riscv_mde
CMN_CSRCS += riscv_releasepending.c riscv_reprioritizertr.c
CMN_CSRCS += riscv_releasestack.c riscv_stackframe.c riscv_schedulesigaction.c
CMN_CSRCS += riscv_sigdeliver.c riscv_udelay.c riscv_unblocktask.c riscv_usestack.c
CMN_CSRCS += riscv_tcbinfo.c riscv_getnewintctx.c
CMN_CSRCS += riscv_tcbinfo.c riscv_getnewintctx.c riscv_doirq.c
ifeq ($(CONFIG_SCHED_BACKTRACE),y)
CMN_CSRCS += riscv_backtrace.c

View File

@ -384,12 +384,6 @@ IRAM_ATTR uintptr_t *esp32c3_dispatch_irq(uintptr_t mcause, uintptr_t *regs)
irqinfo("INFO: mcause=%08" PRIXPTR "\n", mcause);
/* If the board supports LEDs, turn on an LED now to indicate that we are
* processing an interrupt.
*/
board_autoled_on(LED_INIRQ);
if ((RISCV_IRQ_BIT & mcause) != 0)
{
uint8_t cpuint = mcause & RISCV_IRQ_MASK;
@ -403,7 +397,7 @@ IRAM_ATTR uintptr_t *esp32c3_dispatch_irq(uintptr_t mcause, uintptr_t *regs)
putreg32(1 << cpuint, INTERRUPT_CPU_INT_CLEAR_REG);
irq = g_cpuint_map[cpuint] + ESP32C3_IRQ_FIRSTPERIPH;
irq_dispatch(irq, regs);
regs = riscv_doirq(irq, regs);
/* Toggle the bit back to zero. */
@ -422,17 +416,6 @@ IRAM_ATTR uintptr_t *esp32c3_dispatch_irq(uintptr_t mcause, uintptr_t *regs)
}
}
/* If a context switch occurred while processing the interrupt then
* CURRENT_REGS may have change value. If we return any value different
* from the input regs, then the lower level will know that a context
* switch occurred during interrupt processing.
*/
regs = (uintptr_t *)CURRENT_REGS;
CURRENT_REGS = NULL;
board_autoled_off(LED_INIRQ);
return regs;
}

View File

@ -33,7 +33,7 @@ CMN_CSRCS += riscv_interruptcontext.c riscv_modifyreg32.c riscv_puts.c riscv_mde
CMN_CSRCS += riscv_releasepending.c riscv_reprioritizertr.c
CMN_CSRCS += riscv_releasestack.c riscv_stackframe.c riscv_schedulesigaction.c
CMN_CSRCS += riscv_sigdeliver.c riscv_udelay.c riscv_unblocktask.c riscv_usestack.c
CMN_CSRCS += riscv_idle.c riscv_tcbinfo.c riscv_getnewintctx.c
CMN_CSRCS += riscv_idle.c riscv_tcbinfo.c riscv_getnewintctx.c riscv_doirq.c
ifeq ($(CONFIG_SCHED_BACKTRACE),y)
CMN_CSRCS += riscv_backtrace.c

View File

@ -77,21 +77,9 @@ void *riscv_dispatch_irq(uintptr_t vector, uintptr_t *regs)
riscv_ack_irq(irq);
#ifdef CONFIG_SUPPRESS_INTERRUPTS
PANIC();
#else
/* Current regs non-zero indicates that we are processing an interrupt;
* CURRENT_REGS is also used to manage interrupt level context switches.
*
* Nested interrupts are not supported
*/
DEBUGASSERT(CURRENT_REGS == NULL);
CURRENT_REGS = regs;
/* Deliver the IRQ */
irq_dispatch(irq, regs);
regs = riscv_doirq(irq, regs);
if (RISCV_IRQ_MEXT <= irq)
{
@ -106,16 +94,6 @@ void *riscv_dispatch_irq(uintptr_t vector, uintptr_t *regs)
putreg32(irq - RISCV_IRQ_MEXT, FE310_PLIC_CLAIM);
}
#endif
/* If a context switch occurred while processing the interrupt then
* CURRENT_REGS may have change value. If we return any value different
* from the input regs, then the lower level will know that a context
* switch occurred during interrupt processing.
*/
regs = (uintptr_t *)CURRENT_REGS;
CURRENT_REGS = NULL;
return regs;
}

View File

@ -33,7 +33,7 @@ CMN_CSRCS += riscv_interruptcontext.c riscv_modifyreg32.c riscv_puts.c
CMN_CSRCS += riscv_releasepending.c riscv_reprioritizertr.c
CMN_CSRCS += riscv_releasestack.c riscv_stackframe.c riscv_schedulesigaction.c
CMN_CSRCS += riscv_sigdeliver.c riscv_unblocktask.c riscv_usestack.c
CMN_CSRCS += riscv_mdelay.c riscv_idle.c
CMN_CSRCS += riscv_mdelay.c riscv_idle.c riscv_doirq.c
CMN_CSRCS += riscv_tcbinfo.c riscv_cpuidlestack.c riscv_getnewintctx.c
ifeq ($(CONFIG_SMP), y)

View File

@ -83,25 +83,13 @@ void *riscv_dispatch_irq(uintptr_t vector, uintptr_t *regs)
riscv_ack_irq(irq);
#ifdef CONFIG_SUPPRESS_INTERRUPTS
PANIC();
#else
/* Current regs non-zero indicates that we are processing an interrupt;
* CURRENT_REGS is also used to manage interrupt level context switches.
*
* Nested interrupts are not supported
*/
ASSERT(CURRENT_REGS == NULL);
CURRENT_REGS = regs;
/* MEXT means no interrupt */
if (RISCV_IRQ_MEXT != irq)
{
/* Deliver the IRQ */
irq_dispatch(irq, regs);
regs = riscv_doirq(irq, regs);
}
if (RISCV_IRQ_MEXT <= irq)
@ -110,16 +98,6 @@ void *riscv_dispatch_irq(uintptr_t vector, uintptr_t *regs)
putreg32(irq - RISCV_IRQ_MEXT, K210_PLIC_CLAIM);
}
#endif
/* If a context switch occurred while processing the interrupt then
* CURRENT_REGS may have change value. If we return any value different
* from the input regs, then the lower level will know that a context
* switch occurred during interrupt processing.
*/
regs = (uintptr_t *)CURRENT_REGS;
CURRENT_REGS = NULL;
return regs;
}

View File

@ -26,7 +26,7 @@ HEAD_ASRC = litex_head.S
CMN_ASRCS += riscv_vectors.S riscv_testset.S riscv_exception_common.S
# Specify C code within the common directory to be included
CMN_CSRCS += riscv_initialize.c riscv_swint.c
CMN_CSRCS += riscv_initialize.c riscv_swint.c riscv_doirq.c
CMN_CSRCS += riscv_allocateheap.c riscv_createstack.c riscv_exit.c
CMN_CSRCS += riscv_assert.c riscv_blocktask.c riscv_copystate.c riscv_initialstate.c
CMN_CSRCS += riscv_interruptcontext.c riscv_modifyreg32.c riscv_puts.c riscv_mdelay.c

View File

@ -93,32 +93,9 @@ void *riscv_dispatch_irq(uintptr_t vector, uintptr_t *regs)
riscv_ack_irq(irq);
#ifdef CONFIG_SUPPRESS_INTERRUPTS
PANIC();
#else
/* Current regs non-zero indicates that we are processing an interrupt;
* CURRENT_REGS is also used to manage interrupt level context switches.
*
* Nested interrupts are not supported
*/
DEBUGASSERT(CURRENT_REGS == NULL);
CURRENT_REGS = regs;
/* Deliver the IRQ */
irq_dispatch(irq, regs);
#endif
/* If a context switch occurred while processing the interrupt then
* CURRENT_REGS may have change value. If we return any value different
* from the input regs, then the lower level will know that a context
* switch occurred during interrupt processing.
*/
regs = (uintptr_t *)CURRENT_REGS;
CURRENT_REGS = NULL;
regs = riscv_doirq(irq, regs);
return regs;
}

View File

@ -32,7 +32,7 @@ CMN_CSRCS += riscv_releasestack.c riscv_stackframe.c riscv_schedulesigaction.c
CMN_CSRCS += riscv_sigdeliver.c riscv_unblocktask.c riscv_usestack.c
CMN_CSRCS += riscv_mdelay.c riscv_udelay.c
CMN_CSRCS += riscv_idle.c riscv_tcbinfo.c riscv_getnewintctx.c
CMN_CSRCS += riscv_cpuindex.c
CMN_CSRCS += riscv_cpuindex.c riscv_doirq.c
ifeq ($(CONFIG_SCHED_BACKTRACE),y)
CMN_CSRCS += riscv_backtrace.c

View File

@ -53,8 +53,6 @@ void *riscv_dispatch_irq(uintptr_t vector, uintptr_t *regs)
int irq = (vector & 0x3f);
uintptr_t *mepc = regs;
board_autoled_on(LED_INIRQ);
/* Check if fault happened */
if (vector < RISCV_IRQ_ECALLU ||
@ -95,25 +93,13 @@ void *riscv_dispatch_irq(uintptr_t vector, uintptr_t *regs)
riscv_ack_irq(irq);
#ifdef CONFIG_SUPPRESS_INTERRUPTS
PANIC();
#else
/* Current regs non-zero indicates that we are processing an interrupt;
* CURRENT_REGS is also used to manage interrupt level context switches.
*
* Nested interrupts are not supported
*/
ASSERT(CURRENT_REGS == NULL);
CURRENT_REGS = regs;
/* MEXT means no interrupt */
if (irq != RISCV_IRQ_MEXT && irq != MPFS_IRQ_INVALID)
{
/* Deliver the IRQ */
irq_dispatch(irq, regs);
regs = riscv_doirq(irq, regs);
}
if (irq > MPFS_IRQ_EXT_START)
@ -123,37 +109,5 @@ void *riscv_dispatch_irq(uintptr_t vector, uintptr_t *regs)
putreg32(irq - MPFS_IRQ_EXT_START, claim_address);
}
/* Check for a context switch. If a context switch occurred, then
* CURRENT_REGS will have a different value than it did on entry. If an
* interrupt level context switch has occurred, then restore the floating
* point state and the establish the correct address environment before
* returning from the interrupt.
*/
if (regs != CURRENT_REGS)
{
#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 set up the address environment for the new
* thread at the head of the ready-to-run list.
*/
group_addrenv(NULL);
#endif
}
#endif
/* If a context switch occurred while processing the interrupt then
* CURRENT_REGS may have change value. If we return any value different
* from the input regs, then the lower level will know that a context
* switch occurred during interrupt processing.
*/
regs = (uintptr_t *)CURRENT_REGS;
CURRENT_REGS = NULL;
board_autoled_off(LED_INIRQ);
return regs;
}

View File

@ -34,7 +34,7 @@ CMN_CSRCS += riscv_releasepending.c riscv_reprioritizertr.c
CMN_CSRCS += riscv_releasestack.c riscv_stackframe.c riscv_schedulesigaction.c
CMN_CSRCS += riscv_sigdeliver.c riscv_unblocktask.c riscv_usestack.c
CMN_CSRCS += riscv_idle.c riscv_tcbinfo.c riscv_cpuidlestack.c
CMN_CSRCS += riscv_fault.c riscv_getnewintctx.c
CMN_CSRCS += riscv_fault.c riscv_getnewintctx.c riscv_doirq.c
ifeq ($(CONFIG_SMP), y)
CMN_CSRCS += riscv_cpuindex.c riscv_cpupause.c riscv_cpustart.c

View File

@ -82,25 +82,13 @@ void *riscv_dispatch_irq(uintptr_t vector, uintptr_t *regs)
*mepc += 4;
}
#ifdef CONFIG_SUPPRESS_INTERRUPTS
PANIC();
#else
/* Current regs non-zero indicates that we are processing an interrupt;
* CURRENT_REGS is also used to manage interrupt level context switches.
*
* Nested interrupts are not supported
*/
DEBUGASSERT(CURRENT_REGS == NULL);
CURRENT_REGS = regs;
/* MEXT means no interrupt */
if (RISCV_IRQ_MEXT != irq)
{
/* Deliver the IRQ */
irq_dispatch(irq, regs);
regs = riscv_doirq(irq, regs);
}
if (RISCV_IRQ_MEXT <= irq)
@ -109,36 +97,6 @@ void *riscv_dispatch_irq(uintptr_t vector, uintptr_t *regs)
putreg32(irq - RISCV_IRQ_MEXT, QEMU_RV_PLIC_CLAIM);
}
#endif
/* Check for a context switch. If a context switch occurred, then
* CURRENT_REGS will have a different value than it did on entry. If an
* interrupt level context switch has occurred, then restore the floating
* point state and the establish the correct address environment before
* returning from the interrupt.
*/
if (regs != CURRENT_REGS)
{
#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 set up the address environment for the new
* thread at the head of the ready-to-run list.
*/
group_addrenv(NULL);
#endif
}
/* If a context switch occurred while processing the interrupt then
* CURRENT_REGS may have change value. If we return any value different
* from the input regs, then the lower level will know that a context
* switch occurred during interrupt processing.
*/
regs = (uintptr_t *)CURRENT_REGS;
CURRENT_REGS = NULL;
return regs;
}

View File

@ -26,7 +26,7 @@ HEAD_ASRC = rv32m1_head.S
CMN_ASRCS = riscv_vectors.S
# Specify C code within the common directory to be included
CMN_CSRCS += riscv_initialize.c riscv_swint.c
CMN_CSRCS += riscv_initialize.c riscv_swint.c riscv_doirq.c
CMN_CSRCS += riscv_allocateheap.c riscv_createstack.c riscv_exit.c
CMN_CSRCS += riscv_assert.c riscv_blocktask.c riscv_copystate.c riscv_initialstate.c
CMN_CSRCS += riscv_interruptcontext.c riscv_modifyreg32.c riscv_puts.c

View File

@ -102,21 +102,9 @@ void *rv32m1_dispatch_irq(uintptr_t vector, uintptr_t *regs)
riscv_ack_irq(irq);
#ifdef CONFIG_SUPPRESS_INTERRUPTS
PANIC();
#else
/* Current regs non-zero indicates that we are processing an interrupt;
* CURRENT_REGS is also used to manage interrupt level context switches.
*
* Nested interrupts are not supported
*/
DEBUGASSERT(CURRENT_REGS == NULL);
CURRENT_REGS = regs;
/* Deliver the IRQ */
irq_dispatch(irq, regs);
regs = riscv_doirq(irq, regs);
if (RV32M1_IRQ_MEXT <= irq)
{
@ -127,16 +115,5 @@ void *rv32m1_dispatch_irq(uintptr_t vector, uintptr_t *regs)
putreg32(1 << vec, RV32M1_EU_INTPTPENDCLR);
}
#endif
/* If a context switch occurred while processing the interrupt then
* CURRENT_REGS may have change value. If we return any value different
* from the input regs, then the lower level will know that a context
* switch occurred during interrupt processing.
*/
regs = (uintptr_t *)CURRENT_REGS;
CURRENT_REGS = NULL;
return regs;
}