From 4b65c894f640faf51b67bbc771c520494f82d3af Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Thu, 28 Aug 2014 07:38:05 -0600 Subject: [PATCH] Z80: Move address environment switch from the task switchers to the interrupt handler. That may save doing the action multiple times per interrupt --- arch/z80/src/common/up_blocktask.c | 13 ++------ arch/z80/src/common/up_doirq.c | 48 +++++++++++++++++++++------- arch/z80/src/common/up_unblocktask.c | 13 ++------ 3 files changed, 41 insertions(+), 33 deletions(-) diff --git a/arch/z80/src/common/up_blocktask.c b/arch/z80/src/common/up_blocktask.c index d8bed13188..1527e06989 100644 --- a/arch/z80/src/common/up_blocktask.c +++ b/arch/z80/src/common/up_blocktask.c @@ -142,20 +142,11 @@ void up_block_task(FAR struct tcb_s *tcb, tstate_t task_state) /* dbg("New Active Task TCB=%p\n", rtcb); */ /* Then setup so that the context will be performed on exit - * from the interrupt. + * from the interrupt. Any necessary address environment + * changes will be made when the interrupt returns. */ SET_IRQCONTEXT(rtcb); - -#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. - */ - - (void)group_addrenv(rtcb); -#endif } /* Copy the user C context into the TCB at the (old) head of the diff --git a/arch/z80/src/common/up_doirq.c b/arch/z80/src/common/up_doirq.c index a92d3d7744..ab974c88a1 100644 --- a/arch/z80/src/common/up_doirq.c +++ b/arch/z80/src/common/up_doirq.c @@ -1,7 +1,7 @@ /**************************************************************************** * arch/z80/src/common/up_doirq.c * - * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2014 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -49,8 +49,10 @@ #include "chip/switch.h" #include "up_internal.h" +#include "group/group.h" + /**************************************************************************** - * Definitions + * Pre-processor Definitions ****************************************************************************/ /**************************************************************************** @@ -81,25 +83,49 @@ FAR chipreg_t *up_doirq(uint8_t irq, FAR chipreg_t *regs) return NULL; /* Won't get here */ #else +#ifdef CONFIG_ARCH_ADDRENV + FAR chipreg_t *newregs; +#endif + if (irq < NR_IRQS) { - DECL_SAVESTATE(); + DECL_SAVESTATE(); - /* Indicate that we have entered IRQ processing logic */ + /* Indicate that we have entered IRQ processing logic */ - IRQ_ENTER(irq, regs); + IRQ_ENTER(irq, regs); - /* Deliver the IRQ */ + /* Deliver the IRQ */ - irq_dispatch(irq, regs); + irq_dispatch(irq, regs); - /* If a context switch occurred, 'regs' will hold the new context */ +#ifdef CONFIG_ARCH_ADDRENV + /* If a context switch occurred, 'newregs' will hold the new context */ - regs = IRQ_STATE(); + newregs = IRQ_STATE(); - /* Indicate that we are no longer in interrupt processing logic */ + if (newregs != regs) + { + /* Make sure that the address environment for the previously + * running task is closed down gracefully and set up the + * address environment for the new thread at the head of the + * ready-to-run list. + */ - IRQ_LEAVE(irq); + (void)group_addrenv(rtcb); + } + + regs = newregs; + +#else + /* If a context switch occurred, 'regs' will hold the new context */ + + regs = IRQ_STATE(); +#endif + + /* Indicate that we are no longer in interrupt processing logic */ + + IRQ_LEAVE(irq); } board_led_off(LED_INIRQ); diff --git a/arch/z80/src/common/up_unblocktask.c b/arch/z80/src/common/up_unblocktask.c index 257b19c6fc..12dcc4d51f 100644 --- a/arch/z80/src/common/up_unblocktask.c +++ b/arch/z80/src/common/up_unblocktask.c @@ -133,20 +133,11 @@ void up_unblock_task(FAR struct tcb_s *tcb) rtcb = (FAR struct tcb_s*)g_readytorun.head; /* Then setup so that the context will be performed on exit - * from the interrupt. + * from the interrupt. Any necessary address environment + * changes will be made when the interrupt returns. */ SET_IRQCONTEXT(rtcb); - -#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. - */ - - (void)group_addrenv(rtcb); -#endif } /* We are not in an interrupt handler. Copy the user C context