arch/risc-v: Merge duplicated logic by riscv_doirq
Signed-off-by: Huang Qi <huangqi3@xiaomi.com>
This commit is contained in:
parent
a6c22b722f
commit
32fe25278a
@ -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_releasepending.c riscv_reprioritizertr.c
|
||||||
CMN_CSRCS += riscv_releasestack.c riscv_stackframe.c riscv_schedulesigaction.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_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)
|
ifeq ($(CONFIG_SCHED_BACKTRACE),y)
|
||||||
CMN_CSRCS += riscv_backtrace.c
|
CMN_CSRCS += riscv_backtrace.c
|
||||||
|
@ -66,52 +66,9 @@ void *riscv_dispatch_irq(uintptr_t vector, uintptr_t *regs)
|
|||||||
|
|
||||||
riscv_ack_irq(irq);
|
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 */
|
/* Deliver the IRQ */
|
||||||
|
|
||||||
irq_dispatch(irq, regs);
|
regs = riscv_doirq(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;
|
|
||||||
|
|
||||||
return regs;
|
return regs;
|
||||||
}
|
}
|
||||||
|
@ -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_releasepending.c riscv_reprioritizertr.c
|
||||||
CMN_CSRCS += riscv_releasestack.c riscv_stackframe.c riscv_schedulesigaction.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_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
|
CMN_CSRCS += riscv_tcbinfo.c riscv_getnewintctx.c
|
||||||
|
|
||||||
ifeq ($(CONFIG_SCHED_BACKTRACE),y)
|
ifeq ($(CONFIG_SCHED_BACKTRACE),y)
|
||||||
|
@ -83,25 +83,13 @@ void *riscv_dispatch_irq(uintptr_t vector, uintptr_t *regs)
|
|||||||
|
|
||||||
riscv_ack_irq(irq);
|
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 */
|
/* MEXT means no interrupt */
|
||||||
|
|
||||||
if (RISCV_IRQ_MEXT != irq)
|
if (RISCV_IRQ_MEXT != irq)
|
||||||
{
|
{
|
||||||
/* Deliver the IRQ */
|
/* Deliver the IRQ */
|
||||||
|
|
||||||
irq_dispatch(irq, regs);
|
regs = riscv_doirq(irq, regs);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (C906_IRQ_PERI_START <= irq)
|
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);
|
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;
|
return regs;
|
||||||
}
|
}
|
||||||
|
@ -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_releasepending.c riscv_reprioritizertr.c
|
||||||
CMN_CSRCS += riscv_releasestack.c riscv_stackframe.c riscv_schedulesigaction.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_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)
|
ifeq ($(CONFIG_SCHED_BACKTRACE),y)
|
||||||
CMN_CSRCS += riscv_backtrace.c
|
CMN_CSRCS += riscv_backtrace.c
|
||||||
|
@ -384,12 +384,6 @@ IRAM_ATTR uintptr_t *esp32c3_dispatch_irq(uintptr_t mcause, uintptr_t *regs)
|
|||||||
|
|
||||||
irqinfo("INFO: mcause=%08" PRIXPTR "\n", mcause);
|
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)
|
if ((RISCV_IRQ_BIT & mcause) != 0)
|
||||||
{
|
{
|
||||||
uint8_t cpuint = mcause & RISCV_IRQ_MASK;
|
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);
|
putreg32(1 << cpuint, INTERRUPT_CPU_INT_CLEAR_REG);
|
||||||
|
|
||||||
irq = g_cpuint_map[cpuint] + ESP32C3_IRQ_FIRSTPERIPH;
|
irq = g_cpuint_map[cpuint] + ESP32C3_IRQ_FIRSTPERIPH;
|
||||||
irq_dispatch(irq, regs);
|
regs = riscv_doirq(irq, regs);
|
||||||
|
|
||||||
/* Toggle the bit back to zero. */
|
/* 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;
|
return regs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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_releasepending.c riscv_reprioritizertr.c
|
||||||
CMN_CSRCS += riscv_releasestack.c riscv_stackframe.c riscv_schedulesigaction.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_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)
|
ifeq ($(CONFIG_SCHED_BACKTRACE),y)
|
||||||
CMN_CSRCS += riscv_backtrace.c
|
CMN_CSRCS += riscv_backtrace.c
|
||||||
|
@ -77,21 +77,9 @@ void *riscv_dispatch_irq(uintptr_t vector, uintptr_t *regs)
|
|||||||
|
|
||||||
riscv_ack_irq(irq);
|
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 */
|
/* Deliver the IRQ */
|
||||||
|
|
||||||
irq_dispatch(irq, regs);
|
regs = riscv_doirq(irq, regs);
|
||||||
|
|
||||||
if (RISCV_IRQ_MEXT <= irq)
|
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);
|
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;
|
return regs;
|
||||||
}
|
}
|
||||||
|
@ -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_releasepending.c riscv_reprioritizertr.c
|
||||||
CMN_CSRCS += riscv_releasestack.c riscv_stackframe.c riscv_schedulesigaction.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_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
|
CMN_CSRCS += riscv_tcbinfo.c riscv_cpuidlestack.c riscv_getnewintctx.c
|
||||||
|
|
||||||
ifeq ($(CONFIG_SMP), y)
|
ifeq ($(CONFIG_SMP), y)
|
||||||
|
@ -83,25 +83,13 @@ void *riscv_dispatch_irq(uintptr_t vector, uintptr_t *regs)
|
|||||||
|
|
||||||
riscv_ack_irq(irq);
|
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 */
|
/* MEXT means no interrupt */
|
||||||
|
|
||||||
if (RISCV_IRQ_MEXT != irq)
|
if (RISCV_IRQ_MEXT != irq)
|
||||||
{
|
{
|
||||||
/* Deliver the IRQ */
|
/* Deliver the IRQ */
|
||||||
|
|
||||||
irq_dispatch(irq, regs);
|
regs = riscv_doirq(irq, regs);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (RISCV_IRQ_MEXT <= irq)
|
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);
|
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;
|
return regs;
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,7 @@ HEAD_ASRC = litex_head.S
|
|||||||
CMN_ASRCS += riscv_vectors.S riscv_testset.S riscv_exception_common.S
|
CMN_ASRCS += riscv_vectors.S riscv_testset.S riscv_exception_common.S
|
||||||
|
|
||||||
# Specify C code within the common directory to be included
|
# 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_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_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
|
CMN_CSRCS += riscv_interruptcontext.c riscv_modifyreg32.c riscv_puts.c riscv_mdelay.c
|
||||||
|
@ -93,32 +93,9 @@ void *riscv_dispatch_irq(uintptr_t vector, uintptr_t *regs)
|
|||||||
|
|
||||||
riscv_ack_irq(irq);
|
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 */
|
/* Deliver the IRQ */
|
||||||
|
|
||||||
irq_dispatch(irq, regs);
|
regs = riscv_doirq(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;
|
|
||||||
|
|
||||||
return regs;
|
return regs;
|
||||||
}
|
}
|
||||||
|
@ -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_sigdeliver.c riscv_unblocktask.c riscv_usestack.c
|
||||||
CMN_CSRCS += riscv_mdelay.c riscv_udelay.c
|
CMN_CSRCS += riscv_mdelay.c riscv_udelay.c
|
||||||
CMN_CSRCS += riscv_idle.c riscv_tcbinfo.c riscv_getnewintctx.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)
|
ifeq ($(CONFIG_SCHED_BACKTRACE),y)
|
||||||
CMN_CSRCS += riscv_backtrace.c
|
CMN_CSRCS += riscv_backtrace.c
|
||||||
|
@ -53,8 +53,6 @@ void *riscv_dispatch_irq(uintptr_t vector, uintptr_t *regs)
|
|||||||
int irq = (vector & 0x3f);
|
int irq = (vector & 0x3f);
|
||||||
uintptr_t *mepc = regs;
|
uintptr_t *mepc = regs;
|
||||||
|
|
||||||
board_autoled_on(LED_INIRQ);
|
|
||||||
|
|
||||||
/* Check if fault happened */
|
/* Check if fault happened */
|
||||||
|
|
||||||
if (vector < RISCV_IRQ_ECALLU ||
|
if (vector < RISCV_IRQ_ECALLU ||
|
||||||
@ -95,25 +93,13 @@ void *riscv_dispatch_irq(uintptr_t vector, uintptr_t *regs)
|
|||||||
|
|
||||||
riscv_ack_irq(irq);
|
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 */
|
/* MEXT means no interrupt */
|
||||||
|
|
||||||
if (irq != RISCV_IRQ_MEXT && irq != MPFS_IRQ_INVALID)
|
if (irq != RISCV_IRQ_MEXT && irq != MPFS_IRQ_INVALID)
|
||||||
{
|
{
|
||||||
/* Deliver the IRQ */
|
/* Deliver the IRQ */
|
||||||
|
|
||||||
irq_dispatch(irq, regs);
|
regs = riscv_doirq(irq, regs);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (irq > MPFS_IRQ_EXT_START)
|
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);
|
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;
|
return regs;
|
||||||
}
|
}
|
||||||
|
@ -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_releasestack.c riscv_stackframe.c riscv_schedulesigaction.c
|
||||||
CMN_CSRCS += riscv_sigdeliver.c riscv_unblocktask.c riscv_usestack.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_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)
|
ifeq ($(CONFIG_SMP), y)
|
||||||
CMN_CSRCS += riscv_cpuindex.c riscv_cpupause.c riscv_cpustart.c
|
CMN_CSRCS += riscv_cpuindex.c riscv_cpupause.c riscv_cpustart.c
|
||||||
|
@ -82,25 +82,13 @@ void *riscv_dispatch_irq(uintptr_t vector, uintptr_t *regs)
|
|||||||
*mepc += 4;
|
*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 */
|
/* MEXT means no interrupt */
|
||||||
|
|
||||||
if (RISCV_IRQ_MEXT != irq)
|
if (RISCV_IRQ_MEXT != irq)
|
||||||
{
|
{
|
||||||
/* Deliver the IRQ */
|
/* Deliver the IRQ */
|
||||||
|
|
||||||
irq_dispatch(irq, regs);
|
regs = riscv_doirq(irq, regs);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (RISCV_IRQ_MEXT <= irq)
|
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);
|
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;
|
return regs;
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,7 @@ HEAD_ASRC = rv32m1_head.S
|
|||||||
CMN_ASRCS = riscv_vectors.S
|
CMN_ASRCS = riscv_vectors.S
|
||||||
|
|
||||||
# Specify C code within the common directory to be included
|
# 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_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_assert.c riscv_blocktask.c riscv_copystate.c riscv_initialstate.c
|
||||||
CMN_CSRCS += riscv_interruptcontext.c riscv_modifyreg32.c riscv_puts.c
|
CMN_CSRCS += riscv_interruptcontext.c riscv_modifyreg32.c riscv_puts.c
|
||||||
|
@ -102,21 +102,9 @@ void *rv32m1_dispatch_irq(uintptr_t vector, uintptr_t *regs)
|
|||||||
|
|
||||||
riscv_ack_irq(irq);
|
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 */
|
/* Deliver the IRQ */
|
||||||
|
|
||||||
irq_dispatch(irq, regs);
|
regs = riscv_doirq(irq, regs);
|
||||||
|
|
||||||
if (RV32M1_IRQ_MEXT <= irq)
|
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);
|
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;
|
return regs;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user