diff options
56 files changed, 303 insertions, 148 deletions
diff --git a/apps/netutils/thttpd/Makefile b/apps/netutils/thttpd/Makefile index ec0df4ba6..963ab514f 100644 --- a/apps/netutils/thttpd/Makefile +++ b/apps/netutils/thttpd/Makefile @@ -69,9 +69,15 @@ SUBDIR_BIN3 = ssi SUBDIR_BIN += cgi-bin/$(SUBDIR_BIN1) cgi-bin/$(SUBDIR_BIN2) cgi-bin/$(SUBDIR_BIN3) endif -all: $(SUBDIR_BIN) $(BIN) +all: $(SUBDIR_BIN) .built .PHONY: depend clean distclean +$(AOBJS): %$(OBJEXT): %.S + $(call ASSEMBLE, $<, $@) + +$(COBJS): %$(OBJEXT): %.c + $(call COMPILE, $<, $@) + ifeq ($(CONFIG_NXFLAT),y) cgi-bin: @mkdir cgi-bin @@ -97,12 +103,10 @@ endif .built: $(OBJS) @( for obj in $(OBJS) ; do \ - $(call ARCHIVE, $@, $${obj}); \ + $(call ARCHIVE, $(BIN), $${obj}); \ done ; ) @touch .built -.built: $(BIN) - context: .depend: Makefile $(SRCS) diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog index 2605cf699..5ad9eaaf0 100644 --- a/nuttx/ChangeLog +++ b/nuttx/ChangeLog @@ -1653,6 +1653,11 @@ an up_initialize() provide the same kind of capability. * arch/*/include/*/type.h: On some compilers, char defaults as unsigned. Explicitly add signed to integer types if signed is what is required. + * arch/*: For all architectures -- Global register state save structure + (usually called current_regs) should be marked volatile; Added general + capability to support nested interrupts (not fully realized for all + architectures). + diff --git a/nuttx/arch/8051/src/up_initialize.c b/nuttx/arch/8051/src/up_initialize.c index 3f0bc4027..4252dd617 100644 --- a/nuttx/arch/8051/src/up_initialize.c +++ b/nuttx/arch/8051/src/up_initialize.c @@ -1,7 +1,7 @@ /************************************************************************ * up_initialize.c * - * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved. + * Copyright (C) 2007, 2009, 2011 Gregory Nutt. All rights reserved. * Author: Gregory Nutt <spudmonkey@racsa.co.cr> * * Redistribution and use in source and binary forms, with or without @@ -61,7 +61,7 @@ * interrupt. */ -uint8_t g_irqtos; +volatile uint8_t g_irqtos; /* Registers are saved in the following global array during * interrupt processing. If a context switch is performed diff --git a/nuttx/arch/8051/src/up_internal.h b/nuttx/arch/8051/src/up_internal.h index d49c757a6..75fe58c40 100644 --- a/nuttx/arch/8051/src/up_internal.h +++ b/nuttx/arch/8051/src/up_internal.h @@ -1,7 +1,7 @@ /************************************************************************** * up_internal.h * - * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved. + * Copyright (C) 2007, 2009, 2011 Gregory Nutt. All rights reserved. * Author: Gregory Nutt <spudmonkey@racsa.co.cr> * * Redistribution and use in source and binary forms, with or without @@ -72,7 +72,7 @@ * interrupt. */ -extern uint8_t g_irqtos; +extern volatile uint8_t g_irqtos; /* Registers are saved in the following global array during * interrupt processing. If a context switch is performed diff --git a/nuttx/arch/8051/src/up_irqtest.c b/nuttx/arch/8051/src/up_irqtest.c index b0bdc8464..211f7e05f 100644 --- a/nuttx/arch/8051/src/up_irqtest.c +++ b/nuttx/arch/8051/src/up_irqtest.c @@ -1,7 +1,7 @@ /************************************************************************ * up_irqtest.c * - * Copyright (C) 2007 Gregory Nutt. All rights reserved. + * Copyright (C) 2007, 2011 Gregory Nutt. All rights reserved. * Author: Gregory Nutt <spudmonkey@racsa.co.cr> * * Redistribution and use in source and binary forms, with or without @@ -68,10 +68,10 @@ typedef void (*vector_t)(void); * Public Variables ************************************************************************/ -bool g_irqtest; -uint8_t g_irqtos; +bool g_irqtest; +volatile uint8_t g_irqtos; uint8_t g_irqregs[REGS_SIZE]; -int g_nirqs; +int g_nirqs; FAR struct xcptcontext *g_irqcontext; /************************************************************************ diff --git a/nuttx/arch/arm/include/cortexm3/irq.h b/nuttx/arch/arm/include/cortexm3/irq.h index 5c9ef04c0..063568655 100644 --- a/nuttx/arch/arm/include/cortexm3/irq.h +++ b/nuttx/arch/arm/include/cortexm3/irq.h @@ -156,6 +156,13 @@ struct xcptcontext #ifndef __ASSEMBLY__ +/* Disable IRQs */ + +static inline void irqdisable(void) +{ + __asm__ __volatile__ ("\tcpsid i\n"); +} + /* Save the current primask state & disable IRQs */ static inline irqstate_t irqsave(void) @@ -176,6 +183,13 @@ static inline irqstate_t irqsave(void) return primask; } +/* Enable IRQs */ + +static inline void irqenable(void) +{ + __asm__ __volatile__ ("\tcpsie i\n"); +} + /* Restore saved primask state */ static inline void irqrestore(irqstate_t primask) diff --git a/nuttx/arch/arm/src/arm/up_dataabort.c b/nuttx/arch/arm/src/arm/up_dataabort.c index 05886e384..c36970c1b 100644 --- a/nuttx/arch/arm/src/arm/up_dataabort.c +++ b/nuttx/arch/arm/src/arm/up_dataabort.c @@ -1,7 +1,7 @@ /**************************************************************************** * arch/arm/src/arm/up_dataabort.c * - * Copyright (C) 2007-2010 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2011 Gregory Nutt. All rights reserved. * Author: Gregory Nutt <spudmonkey@racsa.co.cr> * * Redistribution and use in source and binary forms, with or without @@ -103,13 +103,19 @@ void up_dataabort(uint32_t *regs, uint32_t far, uint32_t fsr) { FAR _TCB *tcb = (FAR _TCB *)g_readytorun.head; +#ifdef CONFIG_PAGING + uint32_t *savestate; /* Save the saved processor context in current_regs where it can be accessed * for register dumps and possibly context switching. */ + + savestate = (uint32_t*)current_regs; +#endif current_regs = regs; +#ifdef CONFIG_PAGING /* In the NuttX on-demand paging implementation, only the read-only, .text * section is paged. However, the ARM compiler generated PC-relative data * fetches from within the .text sections. Also, it is customary to locate @@ -162,12 +168,16 @@ void up_dataabort(uint32_t *regs, uint32_t far, uint32_t fsr) pg_miss(); - /* Indicate that we are no longer in an interrupt handler */ + /* Restore the previous value of current_regs. NULL would indicate that + * we are no longer in an interrupt handler. It will be non-NULL if we + * are returning from a nested interrupt. + */ - current_regs = NULL; + current_regs = savestate; return; segfault: +#endif lldbg("Data abort. PC: %08x FAR: %08x FSR: %08x\n", regs[REG_PC], far, fsr); PANIC(OSERR_ERREXCEPTION); } diff --git a/nuttx/arch/arm/src/arm/up_doirq.c b/nuttx/arch/arm/src/arm/up_doirq.c index 5c127b75c..1f1c77473 100644 --- a/nuttx/arch/arm/src/arm/up_doirq.c +++ b/nuttx/arch/arm/src/arm/up_doirq.c @@ -1,7 +1,7 @@ /**************************************************************************** * arch/arm/src/arm/up_doirq.c * - * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved. * Author: Gregory Nutt <spudmonkey@racsa.co.cr> * * Redistribution and use in source and binary forms, with or without @@ -76,6 +76,8 @@ void up_doirq(int irq, uint32_t *regs) #ifdef CONFIG_SUPPRESS_INTERRUPTS PANIC(OSERR_ERREXCEPTION); #else + uint32_t *savestate; + /* Nested interrupts are not supported in this implementation. If you want * implemented nested interrupts, you would have to (1) change the way that * current regs is handled and (2) the design associated with @@ -86,7 +88,7 @@ void up_doirq(int irq, uint32_t *regs) * current_regs is also used to manage interrupt level context switches. */ - DEBUGASSERT(current_regs == NULL); + savestate = (uint32_t*)current_regs; current_regs = regs; /* Mask and acknowledge the interrupt */ @@ -97,9 +99,12 @@ void up_doirq(int irq, uint32_t *regs) irq_dispatch(irq, regs); - /* Indicate that we are no long in an interrupt handler */ + /* Restore the previous value of current_regs. NULL would indicate that + * we are no longer in an interrupt handler. It will be non-NULL if we + * are returning from a nested interrupt. + */ - current_regs = NULL; + current_regs = savestate; /* Unmask the last interrupt (global interrupts are still disabled) */ diff --git a/nuttx/arch/arm/src/arm/up_prefetchabort.c b/nuttx/arch/arm/src/arm/up_prefetchabort.c index 2d184bad6..ed3dd91d3 100644 --- a/nuttx/arch/arm/src/arm/up_prefetchabort.c +++ b/nuttx/arch/arm/src/arm/up_prefetchabort.c @@ -1,7 +1,7 @@ /**************************************************************************** * arch/arm/src/src/up_prefetchabort.c * - * Copyright (C) 2007-2010 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2011 Gregory Nutt. All rights reserved. * Author: Gregory Nutt <spudmonkey@racsa.co.cr> * * Redistribution and use in source and binary forms, with or without @@ -89,10 +89,15 @@ void up_prefetchabort(uint32_t *regs) { +#ifdef CONFIG_PAGING + uint32_t *savestate; + /* Save the saved processor context in current_regs where it can be accessed * for register dumps and possibly context switching. */ + savestate = (uint32_t*)current_regs; +#endif current_regs = regs; #ifdef CONFIG_PAGING @@ -133,9 +138,12 @@ void up_prefetchabort(uint32_t *regs) pg_miss(); - /* Indicate that we are no longer in an interrupt handler */ + /* Restore the previous value of current_regs. NULL would indicate that + * we are no longer in an interrupt handler. It will be non-NULL if we + * are returning from a nested interrupt. + */ - current_regs = NULL; + current_regs = savestate; } else #endif diff --git a/nuttx/arch/arm/src/c5471/c5471_irq.c b/nuttx/arch/arm/src/c5471/c5471_irq.c index 6906e8f8d..fbeb2e720 100644 --- a/nuttx/arch/arm/src/c5471/c5471_irq.c +++ b/nuttx/arch/arm/src/c5471/c5471_irq.c @@ -1,7 +1,7 @@ /**************************************************************************** * arch/arm/src/c5471/c5471_irq.c * - * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved. + * Copyright (C) 2007, 2009, 2011 Gregory Nutt. All rights reserved. * Author: Gregory Nutt <spudmonkey@racsa.co.cr> * * Redistribution and use in source and binary forms, with or without @@ -59,7 +59,7 @@ * Public Data ****************************************************************************/ -uint32_t *current_regs; +volatile uint32_t *current_regs; /**************************************************************************** * Private Data diff --git a/nuttx/arch/arm/src/common/up_internal.h b/nuttx/arch/arm/src/common/up_internal.h index 9fe4464c7..803a6563d 100644 --- a/nuttx/arch/arm/src/common/up_internal.h +++ b/nuttx/arch/arm/src/common/up_internal.h @@ -82,11 +82,11 @@ */ #ifdef CONFIG_ARCH_CORTEXM3 -# define up_savestate(regs) up_copystate(regs, current_regs) +# define up_savestate(regs) up_copystate(regs, (uint32_t*)current_regs) # define up_restorestate(regs) (current_regs = regs) #else -# define up_savestate(regs) up_copystate(regs, current_regs) -# define up_restorestate(regs) up_copystate(current_regs, regs) +# define up_savestate(regs) up_copystate(regs, (uint32_t*)current_regs) +# define up_restorestate(regs) up_copystate((uint32_t*)current_regs, regs) #endif /**************************************************************************** @@ -107,7 +107,7 @@ typedef void (*up_vector_t)(void); * interrupt processing. */ -extern uint32_t *current_regs; +extern volatile uint32_t *current_regs; /* This is the beginning of heap as provided from up_head.S. * This is the first address in DRAM after the loaded diff --git a/nuttx/arch/arm/src/cortexm3/up_doirq.c b/nuttx/arch/arm/src/cortexm3/up_doirq.c index d5f3a6185..fc2f75c97 100644 --- a/nuttx/arch/arm/src/cortexm3/up_doirq.c +++ b/nuttx/arch/arm/src/cortexm3/up_doirq.c @@ -1,7 +1,7 @@ /**************************************************************************** * arch/arm/src/cortexm3/up_doirq.c * - * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved. * Author: Gregory Nutt <spudmonkey@racsa.co.cr> * * Redistribution and use in source and binary forms, with or without @@ -76,6 +76,8 @@ uint32_t *up_doirq(int irq, uint32_t *regs) #ifdef CONFIG_SUPPRESS_INTERRUPTS PANIC(OSERR_ERREXCEPTION); #else + uint32_t *savestate; + /* Nested interrupts are not supported in this implementation. If you want * implemented nested interrupts, you would have to (1) change the way that * current regs is handled and (2) the design associated with @@ -86,7 +88,7 @@ uint32_t *up_doirq(int irq, uint32_t *regs) * current_regs is also used to manage interrupt level context switches. */ - DEBUGASSERT(current_regs == NULL); + savestate = (uint32_t*)current_regs; current_regs = regs; /* Mask and acknowledge the interrupt */ @@ -103,11 +105,14 @@ uint32_t *up_doirq(int irq, uint32_t *regs) * switch occurred during interrupt processing. */ - regs = current_regs; + regs = (uint32_t*)current_regs; - /* Indicate that we are no long in an interrupt handler */ + /* Restore the previous value of current_regs. NULL would indicate that + * we are no longer in an interrupt handler. It will be non-NULL if we + * are returning from a nested interrupt. + */ - current_regs = NULL; + current_regs = savestate; /* Unmask the last interrupt (global interrupts are still disabled) */ diff --git a/nuttx/arch/arm/src/cortexm3/up_svcall.c b/nuttx/arch/arm/src/cortexm3/up_svcall.c index ec67617a7..f7e55a98b 100644 --- a/nuttx/arch/arm/src/cortexm3/up_svcall.c +++ b/nuttx/arch/arm/src/cortexm3/up_svcall.c @@ -57,7 +57,20 @@ /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ +/* Configuration ************************************************************/ + +#undef SYSCALL_INTERRUPTIBLE +#if defined(CONFIG_NUTTX_KERNEL) +# if CONFIG_ARCH_INTERRUPTSTACK > 3 +# warning "CONFIG_ARCH_INTERRUPTSTACK and CONFIG_NUTTX_KERNEL are incompatible" +# warning "options as currently implemented. Interrupts will have to be disabled" +# warning "during SYScall processing to avoid un-handled nested interrupts" +# else +# define SYSCALL_INTERRUPTIBLE 1 +# endif +#endif +/* Debug ********************************************************************/ /* Debug output from this file may interfere with context switching! To get * debug output you must enabled the following in your NuttX configuration: * @@ -116,6 +129,12 @@ static inline void dispatch_syscall(uint32_t *regs) int index = cmd - CONFIG_SYS_RESERVED; + /* Enable interrupts while the SYSCALL executes */ + +#ifdef SYSCALL_INTERRUPTIBLE + irqenable(); +#endif + /* Call the correct stub for each SYS call, based on the number of parameters */ svcdbg("Calling stub%d at %p\n", index, g_stubloopkup[index].stub0); @@ -177,6 +196,10 @@ static inline void dispatch_syscall(uint32_t *regs) cmd, g_stubnparms[index]); break; } + +#ifdef SYSCALL_INTERRUPTIBLE + irqdisable(); +#endif } /* Set up the return vaue. First, check if a context switch occurred. diff --git a/nuttx/arch/arm/src/dm320/dm320_decodeirq.c b/nuttx/arch/arm/src/dm320/dm320_decodeirq.c index a844fcae9..cb3efa5b9 100644 --- a/nuttx/arch/arm/src/dm320/dm320_decodeirq.c +++ b/nuttx/arch/arm/src/dm320/dm320_decodeirq.c @@ -2,7 +2,7 @@ * arch/arm/src/dm320/dm320_decodeirq.c * arch/arm/src/chip/dm320_decodeirq.c * - * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved. + * Copyright (C) 2007, 2009, 2011 Gregory Nutt. All rights reserved. * Author: Gregory Nutt <spudmonkey@racsa.co.cr> * * Redistribution and use in source and binary forms, with or without @@ -94,6 +94,8 @@ void up_decodeirq(uint32_t* regs) if ((unsigned)irq < NR_IRQS) { + uint32_t *savestate; + /* Mask and acknowledge the interrupt */ up_maskack_irq(irq); @@ -102,15 +104,19 @@ void up_decodeirq(uint32_t* regs) * current_regs is also used to manage interrupt level context switches. */ + savestate = (uint32_t*)current_regs; current_regs = regs; /* Deliver the IRQ */ irq_dispatch(irq, regs); - /* Indicate that we are no longer in an interrupt handler */ + /* Restore the previous value of current_regs. NULL would indicate that + * we are no longer in an interrupt handler. It will be non-NULL if we + * are returning from a nested interrupt. + */ - current_regs = NULL; + current_regs = savestate; /* Unmask the last interrupt (global interrupts are still * disabled). diff --git a/nuttx/arch/arm/src/dm320/dm320_irq.c b/nuttx/arch/arm/src/dm320/dm320_irq.c index f094bab1c..eb8201bb4 100644 --- a/nuttx/arch/arm/src/dm320/dm320_irq.c +++ b/nuttx/arch/arm/src/dm320/dm320_irq.c @@ -57,7 +57,7 @@ * Public Data ************************************************************************/ -uint32_t *current_regs; +volatile uint32_t *current_regs; /************************************************************************ * Private Data diff --git a/nuttx/arch/arm/src/imx/imx_decodeirq.c b/nuttx/arch/arm/src/imx/imx_decodeirq.c index 96a40fd4a..55c72ed76 100644 --- a/nuttx/arch/arm/src/imx/imx_decodeirq.c +++ b/nuttx/arch/arm/src/imx/imx_decodeirq.c @@ -2,7 +2,7 @@ * arch/arm/src/imx/imx_decodeirq.c * arch/arm/src/chip/imx_decodeirq.c * - * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved. * Author: Gregory Nutt <spudmonkey@racsa.co.cr> * * Redistribution and use in source and binary forms, with or without @@ -78,6 +78,7 @@ void up_decodeirq(uint32_t* regs) current_regs = regs; PANIC(OSERR_ERREXCEPTION); #else + uint32_t* savestate; uint32_t regval; int irq; @@ -85,6 +86,7 @@ void up_decodeirq(uint32_t* regs) * current_regs is also used to manage interrupt level context switches. */ + savestate = (uint32_t*)current_regs; current_regs = regs; /* Loop while there are pending interrupts to be processed */ @@ -124,8 +126,11 @@ void up_decodeirq(uint32_t* regs) } while (irq < NR_IRQS); - /* Indicate that we are no longer in an interrupt handler */ + /* Restore the previous value of current_regs. NULL would indicate that + * we are no longer in an interrupt handler. It will be non-NULL if we + * are returning from a nested interrupt. + */ - current_regs = NULL; + current_regs = savestate; #endif } diff --git a/nuttx/arch/arm/src/imx/imx_irq.c b/nuttx/arch/arm/src/imx/imx_irq.c index b346064c5..934a60f0b 100644 --- a/nuttx/arch/arm/src/imx/imx_irq.c +++ b/nuttx/arch/arm/src/imx/imx_irq.c @@ -2,7 +2,7 @@ * arch/arm/src/imc/imx_irq.c * arch/arm/src/chip/imx_irq.c * - * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved. * Author: Gregory Nutt <spudmonkey@racsa.co.cr> * * Redistribution and use in source and binary forms, with or without @@ -56,7 +56,7 @@ * Public Data ****************************************************************************/ -uint32_t *current_regs; +volatile uint32_t *current_regs; /**************************************************************************** * Private Data diff --git a/nuttx/arch/arm/src/lm3s/lm3s_irq.c b/nuttx/arch/arm/src/lm3s/lm3s_irq.c index da7f3d9c3..915ce3d13 100644 --- a/nuttx/arch/arm/src/lm3s/lm3s_irq.c +++ b/nuttx/arch/arm/src/lm3s/lm3s_irq.c @@ -75,7 +75,7 @@ * Public Data ****************************************************************************/ -uint32_t *current_regs; +volatile uint32_t *current_regs; /**************************************************************************** * Private Data diff --git a/nuttx/arch/arm/src/lpc17xx/lpc17_irq.c b/nuttx/arch/arm/src/lpc17xx/lpc17_irq.c index 967de45d7..cf3467833 100755 --- a/nuttx/arch/arm/src/lpc17xx/lpc17_irq.c +++ b/nuttx/arch/arm/src/lpc17xx/lpc17_irq.c @@ -75,7 +75,7 @@ * Public Data ****************************************************************************/ -uint32_t *current_regs; +volatile uint32_t *current_regs; /**************************************************************************** * Private Data diff --git a/nuttx/arch/arm/src/lpc214x/lpc214x_decodeirq.c b/nuttx/arch/arm/src/lpc214x/lpc214x_decodeirq.c index dc76509a9..6317066c3 100644 --- a/nuttx/arch/arm/src/lpc214x/lpc214x_decodeirq.c +++ b/nuttx/arch/arm/src/lpc214x/lpc214x_decodeirq.c @@ -1,7 +1,7 @@ /******************************************************************************** * arch/arm/src/lpc214x/lpc214x_decodeirq.c * - * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved. * Author: Gregory Nutt <spudmonkey@racsa.co.cr> * * Redistribution and use in source and binary forms, with or without @@ -145,19 +145,25 @@ static void lpc214x_decodeirq( uint32_t *regs) if (irq < NR_IRQS) { + uint32_t *savestate; + /* Current regs non-zero indicates that we are processing an interrupt; * current_regs is also used to manage interrupt level context switches. */ + savestate = (uint32_t*)current_regs; current_regs = regs; /* Deliver the IRQ */ irq_dispatch(irq, regs); - /* Indicate that we are no long in an interrupt handler */ + /* Restore the previous value of current_regs. NULL would indicate that + * we are no longer in an interrupt handler. It will be non-NULL if we + * are returning from a nested interrupt. + */ - current_regs = NULL; + current_regs = savestate; } #endif } diff --git a/nuttx/arch/arm/src/lpc214x/lpc214x_irq.c b/nuttx/arch/arm/src/lpc214x/lpc214x_irq.c index 9d8ed817b..a8b91037c 100644 --- a/nuttx/arch/arm/src/lpc214x/lpc214x_irq.c +++ b/nuttx/arch/arm/src/lpc214x/lpc214x_irq.c @@ -1,7 +1,7 @@ /**************************************************************************** * arch/arm/src/lpc214x/lpc214x_irq.c * - * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved. * Author: Gregory Nutt <spudmonkey@racsa.co.cr> * * Redistribution and use in source and binary forms, with or without @@ -59,7 +59,7 @@ * Public Data ****************************************************************************/ -uint32_t *current_regs; +volatile uint32_t *current_regs; /**************************************************************************** * Private Data diff --git a/nuttx/arch/arm/src/lpc2378/lpc23xx_decodeirq.c b/nuttx/arch/arm/src/lpc2378/lpc23xx_decodeirq.c index 42b678432..100502a22 100755 --- a/nuttx/arch/arm/src/lpc2378/lpc23xx_decodeirq.c +++ b/nuttx/arch/arm/src/lpc2378/lpc23xx_decodeirq.c @@ -6,7 +6,7 @@ * * This file is part of the NuttX RTOS and based on the lpc2148 port: * - * Copyright (C) 2010 Gregory Nutt. All rights reserved. + * Copyright (C) 2010, 2011 Gregory Nutt. All rights reserved. * Author: Gregory Nutt <spudmonkey@racsa.co.cr> * * Redistribution and use in source and binary forms, with or without @@ -131,11 +131,13 @@ static void lpc23xx_decodeirq(uint32_t *regs) if (irq < NR_IRQS) /* redundant check ?? */ { + uint32_t *savestate; + /* Current regs non-zero indicates that we are processing an interrupt; * current_regs is also used to manage interrupt level context switches. */ - DEBUGASSERT(current_regs == NULL); + savestate = (uint32_t*)current_regs; current_regs = regs; /* Mask and acknowledge the interrupt */ @@ -146,9 +148,12 @@ static void lpc23xx_decodeirq(uint32_t *regs) irq_dispatch(irq, regs); - /* Indicate that we are no longer in an interrupt handler */ + /* Restore the previous value of current_regs. NULL would indicate that + * we are no longer in an interrupt handler. It will be non-NULL if we + * are returning from a nested interrupt. + */ - current_regs = NULL; + current_regs = savestate; } #endif diff --git a/nuttx/arch/arm/src/lpc2378/lpc23xx_irq.c b/nuttx/arch/arm/src/lpc2378/lpc23xx_irq.c index 9a6268a2f..10f188cba 100755 --- a/nuttx/arch/arm/src/lpc2378/lpc23xx_irq.c +++ b/nuttx/arch/arm/src/lpc2378/lpc23xx_irq.c @@ -65,7 +65,7 @@ * Public Data ****************************************************************************/ -uint32_t *current_regs; +volatile uint32_t *current_regs; /**************************************************************************** * Private Data diff --git a/nuttx/arch/arm/src/lpc313x/lpc313x_decodeirq.c b/nuttx/arch/arm/src/lpc313x/lpc313x_decodeirq.c index 9abaff3c1..119e65c50 100755 --- a/nuttx/arch/arm/src/lpc313x/lpc313x_decodeirq.c +++ b/nuttx/arch/arm/src/lpc313x/lpc313x_decodeirq.c @@ -102,6 +102,8 @@ void up_decodeirq(uint32_t *regs) if ((unsigned)irq < NR_IRQS) { + uint32_t* savestate; + /* Mask and acknowledge the interrupt */ up_maskack_irq(irq); @@ -110,15 +112,19 @@ void up_decodeirq(uint32_t *regs) * current_regs is also used to manage interrupt level context switches. */ + savestate = (uint32_t*)current_regs; current_regs = regs; /* Deliver the IRQ */ irq_dispatch(irq, regs); - /* Indicate that we are no longer in an interrupt handler */ + /* Restore the previous value of current_regs. NULL would indicate that + * we are no longer in an interrupt handler. It will be non-NULL if we + * are returning from a nested interrupt. + */ - current_regs = NULL; + current_regs = savestate; /* Unmask the last interrupt (global interrupts are still * disabled). diff --git a/nuttx/arch/arm/src/lpc313x/lpc313x_irq.c b/nuttx/arch/arm/src/lpc313x/lpc313x_irq.c index 35ef3e89e..9b7f10e12 100755 --- a/nuttx/arch/arm/src/lpc313x/lpc313x_irq.c +++ b/nuttx/arch/arm/src/lpc313x/lpc313x_irq.c @@ -2,7 +2,7 @@ * arch/arm/src/lpc313x/lpc313x_irq.c * arch/arm/src/chip/lpc313x_irq.c * - * Copyright (C) 2009-2010 Gregory Nutt. All rights reserved. + * Copyright (C) 2009-2011 Gregory Nutt. All rights reserved. * Author: Gregory Nutt <spudmonkey@racsa.co.cr> * * Redistribution and use in source and binary forms, with or without @@ -64,7 +64,7 @@ * Public Data ****************************************************************************/ -uint32_t *current_regs; +volatile uint32_t *current_regs; /**************************************************************************** * Private Data diff --git a/nuttx/arch/arm/src/sam3u/sam3u_irq.c b/nuttx/arch/arm/src/sam3u/sam3u_irq.c index 1d19c126e..228be0f1f 100755 --- a/nuttx/arch/arm/src/sam3u/sam3u_irq.c +++ b/nuttx/arch/arm/src/sam3u/sam3u_irq.c @@ -75,7 +75,7 @@ * Public Data ****************************************************************************/ -uint32_t *current_regs; +volatile uint32_t *current_regs; /**************************************************************************** * Private Data diff --git a/nuttx/arch/arm/src/stm32/stm32_irq.c b/nuttx/arch/arm/src/stm32/stm32_irq.c index 7f963a117..b27f5448e 100644 --- a/nuttx/arch/arm/src/stm32/stm32_irq.c +++ b/nuttx/arch/arm/src/stm32/stm32_irq.c @@ -75,7 +75,7 @@ * Public Data ****************************************************************************/ -uint32_t *current_regs; +volatile uint32_t *current_regs; /**************************************************************************** * Private Data diff --git a/nuttx/arch/arm/src/str71x/str71x_decodeirq.c b/nuttx/arch/arm/src/str71x/str71x_decodeirq.c index 4182ab417..8a24ea44d 100644 --- a/nuttx/arch/arm/src/str71x/str71x_decodeirq.c +++ b/nuttx/arch/arm/src/str71x/str71x_decodeirq.c @@ -1,7 +1,7 @@ /******************************************************************************** * arch/arm/src/str71x/str71x_decodeirq.c * - * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Copyright (C) 2008-2009, 2011 Gregory Nutt. All rights reserved. * Author: Gregory Nutt <spudmonkey@racsa.co.cr> * * Redistribution and use in source and binary forms, with or without @@ -108,11 +108,13 @@ void up_decodeirq(uint32_t *regs) if (irq < NR_IRQS) { + uint32_t* savestate; + /* Current regs non-zero indicates that we are processing an interrupt; * current_regs is also used to manage interrupt level context switches. */ - DEBUGASSERT(current_regs == NULL); + savestate = (uint32_t*)current_regs; current_regs = regs; /* Mask and acknowledge the interrupt */ @@ -123,9 +125,12 @@ void up_decodeirq(uint32_t *regs) irq_dispatch(irq, regs); - /* Indicate that we are no long in an interrupt handler */ + /* Restore the previous value of current_regs. NULL would indicate that + * we are no longer in an interrupt handler. It will be non-NULL if we + * are returning from a nested interrupt. + */ - current_regs = NULL; + current_regs = savestate; /* Unmask the last interrupt (global interrupts are still disabled) */ diff --git a/nuttx/arch/arm/src/str71x/str71x_irq.c b/nuttx/arch/arm/src/str71x/str71x_irq.c index d27412e17..c5c359cdf 100644 --- a/nuttx/arch/arm/src/str71x/str71x_irq.c +++ b/nuttx/arch/arm/src/str71x/str71x_irq.c @@ -1,7 +1,7 @@ /**************************************************************************** * arch/arm/src/st71x/st71x_irq.c * - * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Copyright (C) 2008-2009, 2011 Gregory Nutt. All rights reserved. * Author: Gregory Nutt <spudmonkey@racsa.co.cr> * * Redistribution and use in source and binary forms, with or without @@ -58,7 +58,7 @@ * Public Data ****************************************************************************/ -uint32_t *current_regs; +volatile uint32_t *current_regs; /**************************************************************************** * Private Data diff --git a/nuttx/arch/avr/src/at32uc3/at32uc3_irq.c b/nuttx/arch/avr/src/at32uc3/at32uc3_irq.c index 1cdc7ed7d..ce42fd03d 100644 --- a/nuttx/arch/avr/src/at32uc3/at32uc3_irq.c +++ b/nuttx/arch/avr/src/at32uc3/at32uc3_irq.c @@ -2,7 +2,7 @@ * arch/avr/src/at32uc3_/at32uc3_irq.c * arch/avr/src/chip/at32uc3_irq.c * - * Copyright (C) 2010 Gregory Nutt. All rights reserved. + * Copyright (C) 2010-2011 Gregory Nutt. All rights reserved. * Author: Gregory Nutt <spudmonkey@racsa.co.cr> * * Redistribution and use in source and binary forms, with or without @@ -83,7 +83,7 @@ extern uint32_t avr32_int3; * Public Data ****************************************************************************/ -uint32_t *current_regs; +volatile uint32_t *current_regs; /**************************************************************************** * Private Types diff --git a/nuttx/arch/avr/src/avr32/up_doirq.c b/nuttx/arch/avr/src/avr32/up_doirq.c index abc0cf54d..061583393 100644 --- a/nuttx/arch/avr/src/avr32/up_doirq.c +++ b/nuttx/arch/avr/src/avr32/up_doirq.c @@ -1,7 +1,7 @@ /**************************************************************************** * arch/avr/src/avr32/up_doirq.c * - * Copyright (C) 2010 Gregory Nutt. All rights reserved. + * Copyright (C) 2010-2011 Gregory Nutt. All rights reserved. * Author: Gregory Nutt <spudmonkey@racsa.co.cr> * * Redistribution and use in source and binary forms, with or without @@ -76,6 +76,8 @@ uint32_t *up_doirq(int irq, uint32_t *regs) #ifdef CONFIG_SUPPRESS_INTERRUPTS PANIC(OSERR_ERREXCEPTION); #else + uint32_t *savestate; + /* Nested interrupts are not supported in this implementation. If you want * implemented nested interrupts, you would have to (1) change the way that * current regs is handled and (2) the design associated with @@ -86,7 +88,7 @@ uint32_t *up_doirq(int irq, uint32_t *regs) * current_regs is also used to manage interrupt level context switches. */ - DEBUGASSERT(current_regs == NULL); + savestate = (uint32_t*)current_regs; current_regs = regs; /* Deliver the IRQ */ @@ -101,9 +103,12 @@ uint32_t *up_doirq(int irq, uint32_t *regs) regs = current_regs; - /* Indicate that we are no long in an interrupt handler */ + /* Restore the previous value of current_regs. NULL would indicate that + * we are no longer in an interrupt handler. It will be non-NULL if we + * are returning from a nested interrupt. + */ - current_regs = NULL; + current_regs = savestate; #endif up_ledoff(LED_INIRQ); return regs; diff --git a/nuttx/arch/avr/src/common/up_internal.h b/nuttx/arch/avr/src/common/up_internal.h index ad5fc30f3..413e44078 100644 --- a/nuttx/arch/avr/src/common/up_internal.h +++ b/nuttx/arch/avr/src/common/up_internal.h @@ -1,7 +1,7 @@ /**************************************************************************** * arch/avr/src/common/up_internal.h * - * Copyright (C) 2010 Gregory Nutt. All rights reserved. + * Copyright (C) 2010-2011 Gregory Nutt. All rights reserved. * Author: Gregory Nutt <spudmonkey@racsa.co.cr> * * Redistribution and use in source and binary forms, with or without @@ -70,7 +70,7 @@ * state from the TCB. */ -#define up_savestate(regs) up_copystate(regs, current_regs) +#define up_savestate(regs) up_copystate(regs, (uint32_t*)current_regs) #define up_restorestate(regs) (current_regs = regs) /**************************************************************************** @@ -91,7 +91,7 @@ typedef void (*up_vector_t)(void); * interrupt processing. */ -extern uint32_t *current_regs; +extern volatile uint32_t *current_regs; /* This is the beginning of heap as provided from up_head.S. * This is the first address in DRAM after the loaded diff --git a/nuttx/arch/hc/src/common/up_doirq.c b/nuttx/arch/hc/src/common/up_doirq.c index 05dbaa2cf..adb3f81ce 100644 --- a/nuttx/arch/hc/src/common/up_doirq.c +++ b/nuttx/arch/hc/src/common/up_doirq.c @@ -76,6 +76,8 @@ uint8_t *up_doirq(int irq, uint8_t *regs) #ifdef CONFIG_SUPPRESS_INTERRUPTS PANIC(OSERR_ERREXCEPTION); #else + uint8_t *savestate; + /* Nested interrupts are not supported in this implementation. If you want * implemented nested interrupts, you would have to (1) change the way that * current regs is handled and (2) the design associated with @@ -86,7 +88,7 @@ uint8_t *up_doirq(int irq, uint8_t *regs) * current_regs is also used to manage interrupt level context switches. */ - DEBUGASSERT(current_regs == NULL); + savestate = (uint8_t*)current_regs; current_regs = regs; /* Deliver the IRQ */ @@ -101,9 +103,12 @@ uint8_t *up_doirq(int irq, uint8_t *regs) regs = current_regs; - /* Indicate that we are no long in an interrupt handler */ + /* Restore the previous value of current_regs. NULL would indicate that + * we are no longer in an interrupt handler. It will be non-NULL if we + * are returning from a nested interrupt. + */ - current_regs = NULL; + current_regs = savestate; #endif up_ledoff(LED_INIRQ); return regs; diff --git a/nuttx/arch/hc/src/common/up_internal.h b/nuttx/arch/hc/src/common/up_internal.h index 8879eee57..1a30f28e5 100755 --- a/nuttx/arch/hc/src/common/up_internal.h +++ b/nuttx/arch/hc/src/common/up_internal.h @@ -81,7 +81,7 @@ * a referenced is passed to get the state from the TCB. */ -#define up_savestate(regs) up_copystate(regs, current_regs) +#define up_savestate(regs) up_copystate(regs, (uint8_t*)current_regs) #define up_restorestate(regs) (current_regs = regs) /**************************************************************************** diff --git a/nuttx/arch/hc/src/m9s12/m9s12_irq.c b/nuttx/arch/hc/src/m9s12/m9s12_irq.c index 1e95c4e68..ab4758925 100755 --- a/nuttx/arch/hc/src/m9s12/m9s12_irq.c +++ b/nuttx/arch/hc/src/m9s12/m9s12_irq.c @@ -60,7 +60,7 @@ * Public Data ****************************************************************************/ -uint8_t *current_regs; +volatile uint8_t *current_regs; /**************************************************************************** * Private Data diff --git a/nuttx/arch/sh/src/common/up_doirq.c b/nuttx/arch/sh/src/common/up_doirq.c index 6e64a623c..0ec82b7d9 100644 --- a/nuttx/arch/sh/src/common/up_doirq.c +++ b/nuttx/arch/sh/src/common/up_doirq.c @@ -1,7 +1,7 @@ /**************************************************************************** * arch/sh/src/common/up_doirq.c * - * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Copyright (C) 2008-2009, 2011 Gregory Nutt. All rights reserved. * Author: Gregory Nutt <spudmonkey@racsa.co.cr> * * Redistribution and use in source and binary forms, with or without @@ -77,11 +77,14 @@ uint32_t *up_doirq(int irq, uint32_t* regs) #else if ((unsigned)irq < NR_IRQS) { + uint32_t *savestate; + /* Current regs non-zero indicates that we are processing * an interrupt; current_regs is also used to manage * interrupt level context switches. */ + savestate = (uint32_t*)current_regs; current_regs = regs; /* Mask and acknowledge the interrupt (if supported by the chip) */ @@ -100,9 +103,12 @@ uint32_t *up_doirq(int irq, uint32_t* regs) regs = current_regs; - /* Indicate that we are no longer in an interrupt handler */ + /* Restore the previous value of current_regs. NULL would indicate that + * we are no longer in an interrupt handler. It will be non-NULL if we + * are returning from a nested interrupt. + */ - current_regs = NULL; + current_regs = savestate; /* Unmask the last interrupt (global interrupts are still * disabled. diff --git a/nuttx/arch/sh/src/common/up_internal.h b/nuttx/arch/sh/src/common/up_internal.h index 7840caf66..7b1fb5f33 100644 --- a/nuttx/arch/sh/src/common/up_internal.h +++ b/nuttx/arch/sh/src/common/up_internal.h @@ -98,7 +98,7 @@ typedef void (*up_vector_t)(void); * interrupt processing. */ -extern uint32_t *current_regs; +extern volatile uint32_t *current_regs; /* This is the beginning of heap as provided from up_head.S. * This is the first address in DRAM after the loaded diff --git a/nuttx/arch/sh/src/common/up_reprioritizertr.c b/nuttx/arch/sh/src/common/up_reprioritizertr.c index cc9d0ff47..58a142563 100644 --- a/nuttx/arch/sh/src/common/up_reprioritizertr.c +++ b/nuttx/arch/sh/src/common/up_reprioritizertr.c @@ -1,7 +1,7 @@ /**************************************************************************** * arch/sh/src/common/up_reprioritizertr.c * - * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Copyright (C) 2008-2009, 2011 Gregory Nutt. All rights reserved. * Author: Gregory Nutt <spudmonkey@racsa.co.cr> * * Redistribution and use in source and binary forms, with or without diff --git a/nuttx/arch/sh/src/m16c/m16c_irq.c b/nuttx/arch/sh/src/m16c/m16c_irq.c index 10e129412..5cfb43e8d 100644 --- a/nuttx/arch/sh/src/m16c/m16c_irq.c +++ b/nuttx/arch/sh/src/m16c/m16c_irq.c @@ -1,7 +1,7 @@ /**************************************************************************** * arch/sh/src/m16c/m16c_irq.c * - * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved. * Author: Gregory Nutt <spudmonkey@racsa.co.cr> * * Redistribution and use in source and binary forms, with or without @@ -57,7 +57,7 @@ * structure. If is non-NULL only during interrupt processing. */ -uint32_t *current_regs; /* Actually a pointer to the beginning of a uint8_t array */ +volatile uint32_t *current_regs; /* Actually a pointer to the beginning of a uint8_t array */ /**************************************************************************** * Private Data diff --git a/nuttx/arch/sh/src/sh1/sh1_dumpstate.c b/nuttx/arch/sh/src/sh1/sh1_dumpstate.c index cf6a16cbe..ddfa5e455 100755 --- a/nuttx/arch/sh/src/sh1/sh1_dumpstate.c +++ b/nuttx/arch/sh/src/sh1/sh1_dumpstate.c @@ -1,7 +1,7 @@ /**************************************************************************** * arch/sh/src/sh1/sh1_assert.c * - * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Copyright (C) 2008-2009, 2011 Gregory Nutt. All rights reserved. * Author: Gregory Nutt <spudmonkey@racsa.co.cr> * * Redistribution and use in source and binary forms, with or without @@ -113,7 +113,7 @@ static void sh1_stackdump(uint32_t sp, uint32_t stack_base) static inline void sh1_registerdump(void) { - uint32_t *ptr = current_regs; + uint32_t *ptr = (uint32_t*)current_regs; /* Are user registers available from interrupt processing? */ diff --git a/nuttx/arch/sh/src/sh1/sh1_irq.c b/nuttx/arch/sh/src/sh1/sh1_irq.c index c5b33cc3e..d76d1d94c 100644 --- a/nuttx/arch/sh/src/sh1/sh1_irq.c +++ b/nuttx/arch/sh/src/sh1/sh1_irq.c @@ -1,7 +1,7 @@ /**************************************************************************** * arch/sh/src/sh1/sh1_irq.c * - * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Copyright (C) 2008-2009, 2011 Gregory Nutt. All rights reserved. * Author: Gregory Nutt <spudmonkey@racsa.co.cr> * * Redistribution and use in source and binary forms, with or without @@ -57,7 +57,7 @@ * Public Data ****************************************************************************/ -uint32_t *current_regs; +volatile uint32_t *current_regs; /**************************************************************************** * Private Data diff --git a/nuttx/arch/x86/src/common/up_assert.c b/nuttx/arch/x86/src/common/up_assert.c index 55ba376b4..776784656 100644 --- a/nuttx/arch/x86/src/common/up_assert.c +++ b/nuttx/arch/x86/src/common/up_assert.c @@ -198,7 +198,7 @@ static void up_dumpstate(void) if (current_regs != NULL) { - up_registerdump(current_regs); + up_registerdump((uint32_t*)current_regs); } } #else diff --git a/nuttx/arch/x86/src/common/up_internal.h b/nuttx/arch/x86/src/common/up_internal.h index 51f79beb3..185d0afc0 100644 --- a/nuttx/arch/x86/src/common/up_internal.h +++ b/nuttx/arch/x86/src/common/up_internal.h @@ -99,7 +99,7 @@ typedef void (*up_vector_t)(void); * structure. If is non-NULL only during interrupt processing. */ -extern uint32_t *current_regs; +extern volatile uint32_t *current_regs; /* This is the beginning of heap as provided from up_head.S. This is the first * address in DRAM after the loaded program+bss+idle stack. The end of the diff --git a/nuttx/arch/x86/src/i486/up_irq.c b/nuttx/arch/x86/src/i486/up_irq.c index 627c727de..01da4962e 100755 --- a/nuttx/arch/x86/src/i486/up_irq.c +++ b/nuttx/arch/x86/src/i486/up_irq.c @@ -72,7 +72,7 @@ static inline void up_idtinit(void); * Public Data ****************************************************************************/ -uint32_t *current_regs; +volatile uint32_t *current_regs; /**************************************************************************** * Private Data diff --git a/nuttx/arch/x86/src/i486/up_savestate.c b/nuttx/arch/x86/src/i486/up_savestate.c index d5f97fa85..1d35c62a9 100644 --- a/nuttx/arch/x86/src/i486/up_savestate.c +++ b/nuttx/arch/x86/src/i486/up_savestate.c @@ -80,7 +80,7 @@ void up_savestate(uint32_t *regs) /* First, just copy all of the registers */ - up_copystate(regs, current_regs); + up_copystate(regs, (uint32_t*)current_regs); /* The RES_SP and REG_SS values will not be saved by the interrupt handling * logic if there is no change in privilege level. In that case, we will diff --git a/nuttx/arch/x86/src/qemu/qemu_handlers.c b/nuttx/arch/x86/src/qemu/qemu_handlers.c index fbcb327aa..a85370f76 100644 --- a/nuttx/arch/x86/src/qemu/qemu_handlers.c +++ b/nuttx/arch/x86/src/qemu/qemu_handlers.c @@ -86,6 +86,8 @@ static void idt_outb(uint8_t val, uint16_t addr) #ifndef CONFIG_SUPPRESS_INTERRUPTS static uint32_t *common_handler(int irq, uint32_t *regs) { + uint32_t *savestate; + up_ledon(LED_INIRQ); /* Nested interrupts are not supported in this implementation. If you want @@ -98,7 +100,7 @@ static uint32_t *common_handler(int irq, uint32_t *regs) * current_regs is also used to manage interrupt level context switches. */ - DEBUGASSERT(current_regs == NULL); + savestate = (uint32_t*)current_regs; current_regs = regs; /* Deliver the IRQ */ @@ -111,11 +113,14 @@ static uint32_t *common_handler(int irq, uint32_t *regs) * switch occurred during interrupt processing. */ - regs = current_regs; + regs = (uint32_t*)current_regs; - /* Indicate that we are no long in an interrupt handler */ + /* Restore the previous value of current_regs. NULL would indicate that + * we are no longer in an interrupt handler. It will be non-NULL if we + * are returning from a nested interrupt. + */ - current_regs = NULL; + current_regs = savestate; return regs; } #endif diff --git a/nuttx/arch/z16/src/common/up_doirq.c b/nuttx/arch/z16/src/common/up_doirq.c index e7e43b24d..3adddf6db 100644 --- a/nuttx/arch/z16/src/common/up_doirq.c +++ b/nuttx/arch/z16/src/common/up_doirq.c @@ -1,7 +1,7 @@ /**************************************************************************** * common/up_doirq.c * - * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Copyright (C) 2008-2009, 2011 Gregory Nutt. All rights reserved. * Author: Gregory Nutt <spudmonkey@racsa.co.cr> * * Redistribution and use in source and binary forms, with or without @@ -88,31 +88,37 @@ FAR chipreg_t *up_doirq(int irq, FAR chipreg_t *regs) #else if ((unsigned)irq < NR_IRQS) { - /* Current regs non-zero indicates that we are processing - * an interrupt; current_regs is also used to manage - * interrupt level context switches. - */ + FAR chipreg_t *savestate; - current_regs = regs; + /* Current regs non-zero indicates that we are processing + * an interrupt; current_regs is also used to manage + * interrupt level context switches. + */ - /* Mask and acknowledge the interrupt */ + savestate = (uint32_t*)current_regs; + current_regs = regs; - up_maskack_irq(irq); + /* Mask and acknowledge the interrupt */ - /* Deliver the IRQ */ + up_maskack_irq(irq); - irq_dispatch(irq, regs); + /* Deliver the IRQ */ - /* Indicate that we are no long in an interrupt handler */ + irq_dispatch(irq, regs); - ret = current_regs; - current_regs = NULL; + /* Restore the previous value of current_regs. NULL would indicate that + * we are no longer in an interrupt handler. It will be non-NULL if we + * are returning from a nested interrupt. + */ - /* Unmask the last interrupt (global interrupts are still - * disabled. - */ + ret = current_regs; + current_regs = savestate; - up_enable_irq(irq); + /* Unmask the last interrupt (global interrupts are still + * disabled. + */ + + up_enable_irq(irq); } up_ledoff(LED_INIRQ); #endif diff --git a/nuttx/arch/z16/src/common/up_initialize.c b/nuttx/arch/z16/src/common/up_initialize.c index 2121f73d9..063ccdf71 100644 --- a/nuttx/arch/z16/src/common/up_initialize.c +++ b/nuttx/arch/z16/src/common/up_initialize.c @@ -1,7 +1,7 @@ /**************************************************************************** * common/up_initialize.c * - * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Copyright (C) 2008-2009, 2011 Gregory Nutt. All rights reserved. * Author: Gregory Nutt <spudmonkey@racsa.co.cr> * * Redistribution and use in source and binary forms, with or without @@ -68,7 +68,7 @@ * interrupt processing. */ -FAR chipreg_t *current_regs; +volatile FAR chipreg_t *current_regs; /**************************************************************************** * Private Types diff --git a/nuttx/arch/z16/src/common/up_internal.h b/nuttx/arch/z16/src/common/up_internal.h index fa527fd62..117d7f405 100644 --- a/nuttx/arch/z16/src/common/up_internal.h +++ b/nuttx/arch/z16/src/common/up_internal.h @@ -1,7 +1,7 @@ /**************************************************************************** * common/up_internal.h * - * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Copyright (C) 2008-2009, 2011 Gregory Nutt. All rights reserved. * Author: Gregory Nutt <spudmonkey@racsa.co.cr> * * Redistribution and use in source and binary forms, with or without @@ -74,7 +74,7 @@ /* Macros for portability */ #define IN_INTERRUPT (current_regs != NULL) -#define SAVE_IRQCONTEXT(tcb) up_copystate((tcb)->xcp.regs, current_regs) +#define SAVE_IRQCONTEXT(tcb) up_copystate((tcb)->xcp.regs, (FAR chipreg_t*)current_regs) #define SET_IRQCONTEXT(tcb) do { current_regs = (tcb)->xcp.regs; } while (0) #define SAVE_USERCONTEXT(tcb) up_saveusercontext((tcb)->xcp.regs) #define RESTORE_USERCONTEXT(tcb) up_restoreusercontext((tcb)->xcp.regs) @@ -98,7 +98,7 @@ typedef void (*up_vector_t)(void); * interrupt processing. */ -extern FAR chipreg_t *current_regs; +extern voltile FAR chipreg_t *current_regs; #endif /**************************************************************************** diff --git a/nuttx/arch/z80/src/common/up_doirq.c b/nuttx/arch/z80/src/common/up_doirq.c index 2c4c9e113..828806a49 100644 --- a/nuttx/arch/z80/src/common/up_doirq.c +++ b/nuttx/arch/z80/src/common/up_doirq.c @@ -84,6 +84,8 @@ FAR chipreg_t *up_doirq(uint8_t irq, FAR chipreg_t *regs) #else if (irq < NR_IRQS) { + FAR chipreg_t *savestate; + /* Indicate that we have entered IRQ processing logic */ IRQ_ENTER(irq, regs); diff --git a/nuttx/arch/z80/src/ez80/ez80_irq.c b/nuttx/arch/z80/src/ez80/ez80_irq.c index 38a51c9c4..d89bff859 100644 --- a/nuttx/arch/z80/src/ez80/ez80_irq.c +++ b/nuttx/arch/z80/src/ez80/ez80_irq.c @@ -57,7 +57,7 @@ * structure. If is non-NULL only during interrupt processing. */ -chipreg_t *current_regs; +volatile chipreg_t *current_regs; /**************************************************************************** * Private Data diff --git a/nuttx/arch/z80/src/ez80/switch.h b/nuttx/arch/z80/src/ez80/switch.h index b1d71669b..3b7f1bd95 100644 --- a/nuttx/arch/z80/src/ez80/switch.h +++ b/nuttx/arch/z80/src/ez80/switch.h @@ -2,7 +2,7 @@ * arch/z80/src/ez80/switch.h * arch/z80/src/chip/switch.h * - * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Copyright (C) 2008-2009, 2011 Gregory Nutt. All rights reserved. * Author: Gregory Nutt <spudmonkey@racsa.co.cr> * * Redistribution and use in source and binary forms, with or without @@ -61,7 +61,7 @@ #define INIT_IRQCONTEXT() current_regs = NULL -/* IN_INTERRUPT returns true if the system is current operating in the interrupt +/* IN_INTERRUPT returns true if the system is currently operating in the interrupt * context. IN_INTERRUPT is the inline equivalent of up_interrupt_context(). */ @@ -69,11 +69,15 @@ /* The following macro is used when the system enters interrupt handling logic */ -#define IRQ_ENTER(irq, regs) current_regs = (regs) +#define IRQ_ENTER(irq, regs) \ + do { \ + savestate = (FAR chipreg_t *)current_regs; \ + current_regs = (regs); \ + } while (0) /* The following macro is used when the system exits interrupt handling logic */ -#define IRQ_LEAVE(irq) current_regs = NULL +#define IRQ_LEAVE(irq) current_regs = savestate /* The following macro is used to sample the interrupt state (as a opaque handle) */ @@ -81,11 +85,11 @@ /* Save the current IRQ context in the specified TCB */ -#define SAVE_IRQCONTEXT(tcb) ez80_copystate((tcb)->xcp.regs, current_regs) +#define SAVE_IRQCONTEXT(tcb) ez80_copystate((tcb)->xcp.regs, (FAR chipreg_t*)current_regs) /* Set the current IRQ context to the state specified in the TCB */ -#define SET_IRQCONTEXT(tcb) ez80_copystate(current_regs, (tcb)->xcp.regs) +#define SET_IRQCONTEXT(tcb) ez80_copystate((FAR chipreg_t*)current_regs, (tcb)->xcp.regs) /* Save the user context in the specified TCB. User context saves can be simpler * because only those registers normally saved in a C called need be stored. @@ -116,7 +120,7 @@ * If is non-NULL only during interrupt processing. */ -extern chipreg_t *current_regs; +extern volatile chipreg_t *current_regs; #endif /************************************************************************************ @@ -133,19 +137,19 @@ extern "C" { /* Defined in ez80_copystate.c */ -EXTERN void ez80_copystate(chipreg_t *dest, const chipreg_t *src); +EXTERN void ez80_copystate(FAR chipreg_t *dest, FAR const chipreg_t *src); /* Defined in ez80_saveusercontext.asm */ -EXTERN int ez80_saveusercontext(chipreg_t *regs); +EXTERN int ez80_saveusercontext(FAR chipreg_t *regs); /* Defined in ez80_restorecontext.asm */ -EXTERN void ez80_restorecontext(chipreg_t *regs); +EXTERN void ez80_restorecontext(FAR chipreg_t *regs); /* Defined in ez80_sigsetup.c */ -EXTERN void ez80_sigsetup(_TCB *tcb, sig_deliver_t sigdeliver, chipreg_t *regs); +EXTERN void ez80_sigsetup(FAR _TCB *tcb, sig_deliver_t sigdeliver, chipreg_t *regs); /* Defined in ez80_registerdump.c */ diff --git a/nuttx/arch/z80/src/z8/switch.h b/nuttx/arch/z80/src/z8/switch.h index 69e766cf6..c37d7bcd0 100644 --- a/nuttx/arch/z80/src/z8/switch.h +++ b/nuttx/arch/z80/src/z8/switch.h @@ -2,7 +2,7 @@ * arch/z80/src/z8/switch.h * arch/z80/src/chip/switch.h * - * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Copyright (C) 2008-2009, 2011 Gregory Nutt. All rights reserved. * Author: Gregory Nutt <spudmonkey@racsa.co.cr> * * Redistribution and use in source and binary forms, with or without @@ -105,7 +105,7 @@ g_z8irqstate.state = Z8_IRQSTATE_NONE; \ } while (0) -/* IN_INTERRUPT returns true if the system is current operating in the interrupt +/* IN_INTERRUPT returns true if the system is currently operating in the interrupt * context. IN_INTERRUPT is the inline equivalent of up_interrupt_context(). */ @@ -114,8 +114,15 @@ /* The following macro is used when the system enters interrupt handling logic */ +#define IRQ_SAVE(irq, regs) savestate = (FAR chipreg_t *)current_regs; +#define IRQ_ENTER(irq, regs) current_regs = (regs) + +/* The following macro is used when the system exits interrupt handling logic */ + #define IRQ_ENTER(irq, regs) \ do { \ + savestate.state = g_z8irqstate.state; \ + savestate.regs = g_z8irqstate.regs; \ g_z8irqstate.state = Z8_IRQSTATE_ENTRY; \ g_z8irqstate.regs = (regs); \ up_maskack_irq(irq); \ @@ -125,7 +132,8 @@ #define IRQ_LEAVE(irq) \ do { \ - g_z8irqstate.state = Z8_IRQSTATE_NONE; \ + g_z8irqstate.state = savestate.state; \ + g_z8irqstate.regs = savestate.regs; \ up_enable_irq(irq); \ } while (0) diff --git a/nuttx/arch/z80/src/z80/switch.h b/nuttx/arch/z80/src/z80/switch.h index f30f41b9c..1b54ada5e 100644 --- a/nuttx/arch/z80/src/z80/switch.h +++ b/nuttx/arch/z80/src/z80/switch.h @@ -2,7 +2,7 @@ * arch/z80/src/z80/switch.h * arch/z80/src/chip/switch.h * - * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Copyright (C) 2008-2009, 2011 Gregory Nutt. All rights reserved. * Author: Gregory Nutt <spudmonkey@racsa.co.cr> * * Redistribution and use in source and binary forms, with or without @@ -68,11 +68,15 @@ /* The following macro is used when the system enters interrupt handling logic */ -#define IRQ_ENTER(irq, regs) current_regs = (regs) +#define IRQ_ENTER(irq, regs) \ + do { \ + savestate = (FAR chipreg_t *)current_regs; \ + current_regs = (regs); \ + } while (0) /* The following macro is used when the system exits interrupt handling logic */ -#define IRQ_LEAVE(irq) current_regs = NULL +#define IRQ_LEAVE(irq) current_regs = savestate /* The following macro is used to sample the interrupt state (as a opaque handle) */ @@ -80,11 +84,11 @@ /* Save the current IRQ context in the specified TCB */ -#define SAVE_IRQCONTEXT(tcb) z80_copystate((tcb)->xcp.regs, current_regs) +#define SAVE_IRQCONTEXT(tcb) z80_copystate((tcb)->xcp.regs, (FAR chipreg_t*)current_regs) /* Set the current IRQ context to the state specified in the TCB */ -#define SET_IRQCONTEXT(tcb) z80_copystate(current_regs, (tcb)->xcp.regs) +#define SET_IRQCONTEXT(tcb) z80_copystate((FAR chipreg_t*)current_regs, (tcb)->xcp.regs) /* Save the user context in the specified TCB. User context saves can be simpler * because only those registers normally saved in a C called need be stored. @@ -103,16 +107,19 @@ #define _REGISTER_DUMP() z80_registerdump() /************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ * Public Variables ************************************************************************************/ #ifndef __ASSEMBLY__ -/* This holds a references to the current interrupt level - * register storage structure. If is non-NULL only during - * interrupt processing. +/* This holds a references to the current interrupt level register storage structure. + * If is non-NULL only during interrupt processing. */ -extern chipreg_t *current_regs; +extern volatile chipreg_t *current_regs; #endif /************************************************************************************ diff --git a/nuttx/arch/z80/src/z80/z80_irq.c b/nuttx/arch/z80/src/z80/z80_irq.c index 8b46acc40..5efd36b9f 100644 --- a/nuttx/arch/z80/src/z80/z80_irq.c +++ b/nuttx/arch/z80/src/z80/z80_irq.c @@ -1,7 +1,7 @@ /**************************************************************************** * arch/z80/src/z80/z80_irq.c * - * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved. * Author: Gregory Nutt <spudmonkey@racsa.co.cr> * * Redistribution and use in source and binary forms, with or without @@ -56,7 +56,7 @@ * structure. If is non-NULL only during interrupt processing. */ -chipreg_t *current_regs; +volatile chipreg_t *current_regs; /**************************************************************************** * Private Data diff --git a/nuttx/configs/ntosd-dm320/thttpd/appconfig b/nuttx/configs/ntosd-dm320/thttpd/appconfig index 1a0b0718e..42bcab4d4 100644 --- a/nuttx/configs/ntosd-dm320/thttpd/appconfig +++ b/nuttx/configs/ntosd-dm320/thttpd/appconfig @@ -37,8 +37,8 @@ CONFIGURED_APPS += examples/thttpd - # Networking support CONFIGURED_APPS += netutils/uiplib CONFIGURED_APPS += netutils/thttpd + |