diff --git a/ChangeLog b/ChangeLog index 1636806862..f08c0ac1a3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -339,4 +339,7 @@ * Began adding support for the ZiLOG Z8Encore! microcontroller for the Z8Encore000ZCO development board and the Z8F642 part. * Fix broken 'clean' target on z80sim configurations + * Re-structure arch/z80 to provide support for all ZiLOG 8-bit microcontrollers (ez8 + in particular for now). + diff --git a/Documentation/NuttX.html b/Documentation/NuttX.html index f1c8b3c592..a3762e77e1 100644 --- a/Documentation/NuttX.html +++ b/Documentation/NuttX.html @@ -8,7 +8,7 @@

NuttX RTOS

-

Last Updated: February 11, 2008

+

Last Updated: February 14, 2008

@@ -993,6 +993,8 @@ nuttx-0.3.9 2008-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr> * Began adding support for the ZiLOG Z8Encore! microcontroller for the Z8Encore000ZCO development board and the Z8F642 part. * Fix broken 'clean' target on z80sim configurations + * Re-structure arch/z80 to provide support for all ZiLOG 8-bit microcontrollers (ez8 + in particular for now). pascal-0.1.3 2008-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr> diff --git a/TODO b/TODO index 788bab57b0..9afd2d112b 100644 --- a/TODO +++ b/TODO @@ -1,5 +1,5 @@ -NuttX TODO List (Last updated January 6, 2008) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +NuttX TODO List (Last updated February 13, 2008) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ (6) Task/Scheduler (sched/) (1) Dynamic loader (N/A) diff --git a/arch/z80/include/z8/irq.h b/arch/z80/include/z8/irq.h index 4aaa8752f7..15979c0a6d 100644 --- a/arch/z80/include/z8/irq.h +++ b/arch/z80/include/z8/irq.h @@ -196,30 +196,78 @@ #define Z8_IRQ_SYSTIMER Z8_TIMER0_IRQ -/* IRQ Stack Frame Format +/* IRQ State Save Formatt * - * This stack frame is created on each interrupt. These registers are stored - * in the TCB to many context switches. + * These indices describe how the ez8 context is save in the state save array + * + * Byte offsets: */ -#define XCPT_I (0) /* Offset 0: Saved I w/interrupt state in carry */ -#define XCPT_BC (1) /* Offset 1: Saved BC register */ -#define XCPT_IX (3) /* Offset 3: Saved IX register */ -#define XCPT_IY (4) /* Offset 4: Saved IY register */ -#define XCPT_SP (5) /* Offset 5: Offset to SP at time of interrupt */ -#define XCPT_HL (6) /* Offset 6: Saved HL register */ -#define XCPT_AF (7) /* Offset 7: Saved AF register */ -#define XCPT_PC (8) /* Offset 8: Offset to PC at time of interrupt */ +#define XCPT8_R0 (0) /* Offset 0-15: R0-R15 */ +#define XCPT8_R1 (1) +#define XCPT8_R2 (2) +#define XCPT8_R3 (3) +#define XCPT8_R4 (4) +#define XCPT8_R5 (5) +#define XCPT8_R6 (6) +#define XCPT8_R7 (7) +#define XCPT8_R8 (8) +#define XCPT8_R9 (9) +#define XCPT8_R10 (10) +#define XCPT8_R11 (11) +#define XCPT8_R12 (12) +#define XCPT8_R13 (13) +#define XCPT8_R14 (14) +#define XCPT8_R15 (15) +#define XCPT8_SPH (16) /* Offset 16: SP[8:15] */ +#define XCPT8_SPL (17) /* Offset 17: SP[0:7] */ +#define XCPT8_RP (18) /* Offset 18: Register pointer */ +#define XCPT8_FLAGS (19) /* Offset 19: FLAGS */ +#define XCPT8_PCH (20) /* Offset 20: PC[8:15] */ +#define XCPT8_PCL (21) /* Offset 21: PC[0:7] */ -#define XCPTCONTEXT_REGS (9) -#define XCPTCONTEXT_SIZE (2 * XCPTCONTEXT_REGS) +/* 16-bit "word" offsets */ -/* The ZDS-II provides built-in operations to test & disable and to restore - * the interrupt state. - * - * irqstate_t irqsave(void); - * void irqrestore(irqstate_t flags); - */ +#define XCPT_RR0 (0) /* Indices 0-7: RR0-RR14 */ +#define XCPT_RR2 (1) +#define XCPT_RR4 (2) +#define XCPT_RR6 (3) +#define XCPT_RR8 (4) +#define XCPT_RR10 (5) +#define XCPT_RR12 (6) +#define XCPT_R1R4 (7) +#define XCPT_SP (8) /* Index 8: SP[8:15] */ +#define XCPT_I (9) /* Index 9: FLAGS */ +#define XCPT_PC (10) /* Index 10: PC[8:15] */ + +#define XCPTCONTEXT_REGS (11) + +/* Byte offsets: */ + +#define XCPT_R0_OFFS (2*XCPT_RR0) /* Offset 0-15: R0-R15 */ +#define XCPT_R1_OFFS (2*XCPT_RR0+1) +#define XCPT_R2_OFFS (2*XCPT_RR2) +#define XCPT_R3_OFFS (2*XCPT_RR2+1) +#define XCPT_R4_OFFS (2*XCPT_RR4) +#define XCPT_R5_OFFS (2*XCPT_RR4+1) +#define XCPT_R6_OFFS (2*XCPT_RR6) +#define XCPT_R7_OFFS (2*XCPT_RR6+1) +#define XCPT_R8_OFFS (2*XCPT_RR8) +#define XCPT_R9_OFFS (2*XCPT_RR8+1) +#define XCPT_R10_OFFS (2*XCPT_RR10) +#define XCPT_R11_OFFS (2*XCPT_RR10+1) +#define XCPT_R12_OFFS (2*XCPT_RR12) +#define XCPT_R13_OFFS (2*XCPT_RR12+1) +#define XCPT_R14_OFFS (2*XCPT_R1R4) +#define XCPT_R15_OFFS (2*XCPT_R1R4+1) +#define XCPT_SPH_OFFS (2*XCPT_SP) /* Offset 16: SP[8:15] */ +#define XCPT_SPL_OFFS (2*XCPT_SP+1) /* Offset 17: SP[0:7] */ +#define XCPT_RP_OFFS (2*XCPT_I) /* Offset 18: Register pointer */ +#define XCPT_FLAGS_OFFS (2*XCPT_I+1) /* Offset 19: FLAGS */ +#define XCPT_PCH_OFFS (2*XCPT_PC) /* Offset 20: PC[8:15] */ +#define XCPT_PCL_OFFS (2*XCPT_PC+1) /* Offset 21: PC[0:7] */ + +#define XCPTCONTEXT_SIZE (2*XCPTCONTEXT_REGS) /**************************************************************************** * Public Types @@ -237,7 +285,7 @@ struct xcptcontext { /* Register save area */ - uint16 regs[XCPTCONTEXT_REGS]; + chipreg_t regs[XCPTCONTEXT_REGS]; /* The following function pointer is non-zero if there * are pending signals to be processed. diff --git a/arch/z80/include/z80/irq.h b/arch/z80/include/z80/irq.h index f71ed208e4..25d43e3637 100644 --- a/arch/z80/include/z80/irq.h +++ b/arch/z80/include/z80/irq.h @@ -98,14 +98,14 @@ struct xcptcontext { /* Register save area */ - uint16 regs[XCPTCONTEXT_REGS]; + chipreg_t regs[XCPTCONTEXT_REGS]; /* The following function pointer is non-zero if there * are pending signals to be processed. */ #ifndef CONFIG_DISABLE_SIGNALS - void *sigdeliver; /* Actual type is sig_deliver_t */ + CODE void *sigdeliver; /* Actual type is sig_deliver_t */ /* The following retains that state during signal execution */ diff --git a/arch/z80/src/common/up_assert.c b/arch/z80/src/common/up_assert.c index d7243e7162..1d8fd6a5a0 100644 --- a/arch/z80/src/common/up_assert.c +++ b/arch/z80/src/common/up_assert.c @@ -137,7 +137,7 @@ void up_assert(void) #endif up_stackdump(); - up_registerdump(); + REGISTER_DUMP(); _up_assert(EXIT_FAILURE); } @@ -174,6 +174,6 @@ void up_assert_code(int errorcode) #endif up_stackdump(); - up_registerdump(); + REGISTER_DUMP(); _up_assert(errorcode); } diff --git a/arch/z80/src/common/up_blocktask.c b/arch/z80/src/common/up_blocktask.c index e2d405b366..d0e7922031 100644 --- a/arch/z80/src/common/up_blocktask.c +++ b/arch/z80/src/common/up_blocktask.c @@ -1,5 +1,5 @@ /**************************************************************************** - * common/up_blocktask.c + * arch/z80/src/common/up_blocktask.c * * Copyright (C) 2007, 2008 Gregory Nutt. All rights reserved. * Author: Gregory Nutt @@ -45,6 +45,7 @@ #include +#include "chip/switch.h" #include "os_internal.h" #include "up_internal.h" @@ -128,7 +129,7 @@ void up_block_task(FAR _TCB *tcb, tstate_t task_state) { /* Are we in an interrupt handler? */ - if (IN_INTERRUPT) + if (IN_INTERRUPT()) { /* Yes, then we have to do things differently. * Just copy the current registers into the OLD rtcb. diff --git a/arch/z80/src/common/up_doirq.c b/arch/z80/src/common/up_doirq.c index 9e91054268..f9c9f72bba 100644 --- a/arch/z80/src/common/up_doirq.c +++ b/arch/z80/src/common/up_doirq.c @@ -1,5 +1,5 @@ /**************************************************************************** - * common/up_doirq.c + * arch/z80/src/common/up_doirq.c * * Copyright (C) 2007, 2008 Gregory Nutt. All rights reserved. * Author: Gregory Nutt @@ -38,11 +38,15 @@ ****************************************************************************/ #include + #include -#include -#include #include #include "up_arch.h" + +#include +#include + +#include "chip/switch.h" #include "os_internal.h" #include "up_internal.h" @@ -66,39 +70,37 @@ * Public Functions ****************************************************************************/ -void up_doirq(int irq, chipreg_t *regs) +FAR chipreg_t *up_doirq(ubyte irq, FAR chipreg_t *regs) { up_ledon(LED_INIRQ); + #ifdef CONFIG_SUPPRESS_INTERRUPTS + + lib_lowprintf("Unexpected IRQ\n"); + IRQ_ENTER(regs); PANIC(OSERR_ERREXCEPTION); + return NULL; /* Won't get here */ + #else - if ((unsigned)irq < NR_IRQS) + if (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. - */ + /* Indicate that we have enter IRQ processing logic */ - current_regs = regs; - - /* Mask and acknowledge the interrupt */ - - up_maskack_irq(irq); + IRQ_ENTER(irq, regs); /* Deliver the IRQ */ irq_dispatch(irq, regs); - /* Indicate that we are no long in an interrupt handler */ + /* If a context switch occurred, 'regs' will hold the new context */ - current_regs = NULL; + regs = IRQ_STATE(); - /* Unmask the last interrupt (global interrupts are still - * disabled. - */ + /* Indicate that we are no long in interrupt processing logic */ - up_enable_irq(irq); + IRQ_LEAVE(irq); } up_ledoff(LED_INIRQ); + return regs; #endif } diff --git a/arch/z80/src/common/up_initialize.c b/arch/z80/src/common/up_initialize.c index 40205133b2..036e4618a0 100644 --- a/arch/z80/src/common/up_initialize.c +++ b/arch/z80/src/common/up_initialize.c @@ -1,5 +1,5 @@ /**************************************************************************** - * common/up_initialize.c + * arch/z80/src/common/up_initialize.c * * Copyright (C) 2007, 2008 Gregory Nutt. All rights reserved. * Author: Gregory Nutt @@ -47,6 +47,7 @@ #include #include +#include "chip/switch.h" #include "up_internal.h" /**************************************************************************** @@ -61,13 +62,6 @@ * Public Data ****************************************************************************/ -/* This holds a references to the current interrupt level - * register storage structure. If is non-NULL only during - * interrupt processing. - */ - -uint16 *current_regs; - /**************************************************************************** * Private Types ****************************************************************************/ @@ -130,7 +124,7 @@ void up_initialize(void) { /* Initialize global variables */ - current_regs = NULL; + INIT_IRQCONTEXT(); /* Calibrate the timing loop */ diff --git a/arch/z80/src/common/up_internal.h b/arch/z80/src/common/up_internal.h index e90bec766d..838b4cf369 100644 --- a/arch/z80/src/common/up_internal.h +++ b/arch/z80/src/common/up_internal.h @@ -1,5 +1,5 @@ /**************************************************************************** - * common/up_internal.h + * arch/z80/src/common/up_internal.h * * Copyright (C) 2007, 2008 Gregory Nutt. All rights reserved. * Author: Gregory Nutt @@ -37,14 +37,7 @@ #define __UP_INTERNAL_H /**************************************************************************** - * Included Files - ****************************************************************************/ - -#include -#include "chip/chip.h" - -/**************************************************************************** - * Definitions + * Conditional Compilation ****************************************************************************/ /* Bring-up debug configurations. These are here (vs defconfig) @@ -58,69 +51,52 @@ #undef CONFIG_SUPPRESS_UART_CONFIG /* Do not reconfig UART */ #undef CONFIG_DUMP_ON_EXIT /* Dump task state on exit */ -/* Macros for portability */ +/**************************************************************************** + * Included Files + ****************************************************************************/ -#define IN_INTERRUPT (current_regs != NULL) -#define SAVE_IRQCONTEXT(tcb) up_copystate((tcb)->xcp.regs, current_regs) -#define SET_IRQCONTEXT(tcb) up_copystate(current_regs, (tcb)->xcp.regs) -#define SAVE_USERCONTEXT(tcb) up_saveusercontext((tcb)->xcp.regs) -#define RESTORE_USERCONTEXT(tcb) up_restoreusercontext((tcb)->xcp.regs) -#define SIGNAL_RETURN(regs) up_restoreusercontext(regs) +#include +#include "chip/chip.h" +#include "chip/switch.h" + +/**************************************************************************** + * Definitions + ****************************************************************************/ /**************************************************************************** * Public Types ****************************************************************************/ -#ifndef __ASSEMBLY__ -typedef void (*up_vector_t)(void); -#endif - /**************************************************************************** * Public Variables ****************************************************************************/ -#ifndef __ASSEMBLY__ -/* This holds a references to the current interrupt level - * register storage structure. If is non-NULL only during - * interrupt processing. - */ - -extern uint16 *current_regs; -#endif - /**************************************************************************** * Public Functions ****************************************************************************/ #ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" { +#else +#define EXTERN extern +#endif -/* Defined in up_copystate.c */ +/* Supplied by chip- or board-specific logic */ -extern void up_copystate(FAR chipreg_t *dest, FAR const chipreg_t *src); - -/* Defined in up_saveusercontext.asm */ - -extern int up_saveusercontext(chipreg_t *regs); - -/* Defined in up_restoreusercontext.asm */ - -extern int up_restoreusercontext(chipreg_t *regs); - -/* Supplied by board-specific logic */ - -extern FAR chipreg_t *up_decodeirq(uint8 rstno, FAR chipreg_t *regs); -extern void up_irqinitialize(void); -extern int up_timerisr(int irq, FAR chipreg_t *regs); -extern void up_lowputc(char ch) naked_function; -extern char up_lowgetc(void) naked_function; +EXTERN void up_irqinitialize(void); +EXTERN int up_timerisr(int irq, FAR chipreg_t *regs); +EXTERN void up_lowputc(char ch) naked_function; +EXTERN char up_lowgetc(void) naked_function; /* Defined in up_doirq.c */ -extern void up_doirq(int irq, FAR chipreg_t *regs); +EXTERN FAR chipreg_t *up_doirq(ubyte irq, FAR chipreg_t *regs); /* Define in up_sigdeliver */ -extern void up_sigdeliver(void); +EXTERN void up_sigdeliver(void); /* Defined in up_allocateheap.c */ @@ -131,8 +107,8 @@ void up_addregion(void); /* Defined in up_serial.c */ #if CONFIG_NFILE_DESCRIPTORS > 0 -extern void up_earlyserialinit(void); -extern void up_serialinit(void); +EXTERN void up_earlyserialinit(void); +EXTERN void up_serialinit(void); #else # define up_earlyserialinit() # define up_serialinit() @@ -140,14 +116,14 @@ extern void up_serialinit(void); /* Defined in up_timerisr.c */ -extern void up_timerinit(void); +EXTERN void up_timerinit(void); /* Defined in board/up_leds.c */ #ifdef CONFIG_ARCH_LEDS -extern void up_ledinit(void); -extern void up_ledon(int led); -extern void up_ledoff(int led); +EXTERN void up_ledinit(void); +EXTERN void up_ledon(int led); +EXTERN void up_ledoff(int led); #else # define up_ledinit() # define up_ledon(led) @@ -157,25 +133,29 @@ extern void up_ledoff(int led); /* Defined in board/up_network.c */ #ifdef CONFIG_NET -extern void up_netinitialize(void); +EXTERN void up_netinitialize(void); #else # define up_netinitialize() #endif /* Return the current value of the stack pointer (used in stack dump logic) */ -extern uint16 up_getsp(void); +EXTERN uint16 up_getsp(void); /* Dump stack and registers */ #ifdef CONFIG_ARCH_STACKDUMP -extern void up_stackdump(void); -extern void up_registerdump(void); +EXTERN void up_stackdump(void); +# define REGISTER_DUMP() _REGISTER_DUMP() #else # define up_stackdump() -# define up_registerdump() +# define REGISTER_DUMP() #endif -#endif /* __ASSEMBLY__ */ +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif #endif /* __UP_INTERNAL_H */ diff --git a/arch/z80/src/common/up_interruptcontext.c b/arch/z80/src/common/up_interruptcontext.c index 6e9e752c9a..354227cc28 100644 --- a/arch/z80/src/common/up_interruptcontext.c +++ b/arch/z80/src/common/up_interruptcontext.c @@ -1,5 +1,5 @@ /**************************************************************************** - * common/up_interruptcontext.c + * arch/z80/src/common/up_interruptcontext.c * * Copyright (C) 2007, 2008 Gregory Nutt. All rights reserved. * Author: Gregory Nutt @@ -38,9 +38,13 @@ ****************************************************************************/ #include + #include + #include #include + +#include "chip/switch.h" #include "up_internal.h" /**************************************************************************** @@ -64,5 +68,5 @@ boolean up_interrupt_context(void) { - return current_regs != NULL; + return IN_INTERRUPT(); } diff --git a/arch/z80/src/common/up_releasepending.c b/arch/z80/src/common/up_releasepending.c index 853cc73507..e4048152f4 100644 --- a/arch/z80/src/common/up_releasepending.c +++ b/arch/z80/src/common/up_releasepending.c @@ -1,5 +1,5 @@ /**************************************************************************** - * common/up_releasepending.c + * arch/z80/src/common/up_releasepending.c * * Copyright (C) 2007, 2008 Gregory Nutt. All rights reserved. * Author: Gregory Nutt @@ -46,6 +46,7 @@ #include #include "chip/chip.h" +#include "chip/switch.h" #include "os_internal.h" #include "up_internal.h" @@ -92,7 +93,7 @@ void up_release_pending(void) * interrupt context: */ - if (IN_INTERRUPT) + if (IN_INTERRUPT()) { /* Yes, then we have to do things differently. * Just copy the current context into the OLD rtcb. diff --git a/arch/z80/src/common/up_reprioritizertr.c b/arch/z80/src/common/up_reprioritizertr.c index 3adf33735c..4576852acb 100644 --- a/arch/z80/src/common/up_reprioritizertr.c +++ b/arch/z80/src/common/up_reprioritizertr.c @@ -1,5 +1,5 @@ /**************************************************************************** - * common/up_reprioritizertr.c + * arch/z80/src/common/up_reprioritizertr.c * * Copyright (C) 2007, 2008 Gregory Nutt. All rights reserved. * Author: Gregory Nutt @@ -46,6 +46,7 @@ #include #include "chip/chip.h" +#include "chip/switch.h" #include "os_internal.h" #include "up_internal.h" @@ -140,7 +141,7 @@ void up_reprioritize_rtr(FAR _TCB *tcb, ubyte priority) /* Are we in an interrupt handler? */ - if (IN_INTERRUPT) + if (IN_INTERRUPT()) { /* Yes, then we have to do things differently. * Just copy the current context into the OLD rtcb. diff --git a/arch/z80/src/common/up_schedulesigaction.c b/arch/z80/src/common/up_schedulesigaction.c index 946ba859b8..bad83e5516 100644 --- a/arch/z80/src/common/up_schedulesigaction.c +++ b/arch/z80/src/common/up_schedulesigaction.c @@ -1,5 +1,5 @@ /**************************************************************************** - * common/up_schedulesigaction.c + * arch/z80/src/common/up_schedulesigaction.c * * Copyright (C) 2007,2008 Gregory Nutt. All rights reserved. * Author: Gregory Nutt @@ -46,6 +46,7 @@ #include #include +#include "chip/switch.h" #include "os_internal.h" #include "up_internal.h" @@ -102,11 +103,11 @@ void up_schedule_sigaction(FAR _TCB *tcb, sig_deliver_t sigdeliver) { - /* Refuse to handle nested signal actions */ - dbg("tcb=0x%p sigdeliver=0x%04x\n", tcb, (uint16)sigdeliver); - if (!tcb->xcp.sigdeliver) + /* Refuse to handle nested signal actions */ + + if (!SIGNAL_DELIVERING(tcb)) { irqstate_t flags; @@ -114,80 +115,53 @@ void up_schedule_sigaction(FAR _TCB *tcb, sig_deliver_t sigdeliver) flags = irqsave(); - /* First, handle some special cases when the signal is - * being delivered to the currently executing task. + /* First, handle some special cases when the signal is being delivered + * to the currently executing task. */ - dbg("rtcb=0x%p current_regs=0x%p\n", g_readytorun.head, current_regs); - if (tcb == (FAR _TCB*)g_readytorun.head) { - /* CASE 1: We are not in an interrupt handler and - * a task is signalling itself for some reason. + /* CASE 1: We are not in an interrupt handler and a task is + * signalling itself for some reason. */ - if (!current_regs) + if (!IN_INTERRUPT()) { /* In this case just deliver the signal now. */ sigdeliver(tcb); } - /* CASE 2: We are in an interrupt handler AND the - * interrupted task is the same as the one that - * must receive the signal, then we will have to modify - * the return state as well as the state in the TCB. + /* CASE 2: We are in an interrupt handler AND the interrupted task + * is the same as the one that must receive the signal, then we + * will have to modify the return state as well as the state in + * the TCB. */ else { - /* Save the return address and interrupt state. - * These will be restored by the signal trampoline after - * the signals have been delivered. - */ + /* Set up to vector to the trampoline with interrupts disabled. */ - tcb->xcp.sigdeliver = sigdeliver; - tcb->xcp.saved_pc = current_regs[XCPT_PC]; - tcb->xcp.saved_i = current_regs[XCPT_I]; - - /* Then set up to vector to the trampoline with interrupts - * disabled - */ - - current_regs[XCPT_PC] = (uint16)up_sigdeliver; - current_regs[XCPT_I] = 0; + SIGNAL_SETUP(tcb, sigdeliver, IRQ_STATE()); /* And make sure that the saved context in the TCB * is the same as the interrupt return context. */ - up_copystate(tcb->xcp.regs, current_regs); + SAVE_IRQCONTEXT(tcb); } } - /* Otherwise, we are (1) signaling a task is not running - * from an interrupt handler or (2) we are not in an - * interrupt handler and the running task is signalling - * some non-running task. + /* Otherwise, we are (1) signaling a task is not running from an interrupt + * handler or (2) we are not in an interrupt handler and the running task + * is signalling some non-running task. */ else { - /* Save the return lr and cpsr and one scratch register - * These will be restored by the signal trampoline after - * the signals have been delivered. - */ + /* Set up to vector to the trampoline with interrupts disabled. */ - tcb->xcp.sigdeliver = sigdeliver; - tcb->xcp.saved_pc = tcb->xcp.regs[XCPT_PC]; - tcb->xcp.saved_i = tcb->xcp.regs[XCPT_I]; - - /* Then set up to vector to the trampoline with interrupts - * disabled - */ - - tcb->xcp.regs[XCPT_PC] = (uint16)up_sigdeliver; - tcb->xcp.regs[XCPT_I] = 0; + SIGNAL_SETUP(tcb, sigdeliver, tcb->xcp.regs) } irqrestore(flags); diff --git a/arch/z80/src/common/up_sigdeliver.c b/arch/z80/src/common/up_sigdeliver.c index 757e5020bc..9ab8f84470 100644 --- a/arch/z80/src/common/up_sigdeliver.c +++ b/arch/z80/src/common/up_sigdeliver.c @@ -1,5 +1,5 @@ /**************************************************************************** - * common/up_sigdeliver.c + * arch/z80/src/common/up_sigdeliver.c * * Copyright (C) 2007, 2008 Gregory Nutt. All rights reserved. * Author: Gregory Nutt @@ -46,6 +46,7 @@ #include #include +#include "chip/switch.h" #include "os_internal.h" #include "up_internal.h" @@ -100,7 +101,7 @@ void up_sigdeliver(void) /* Save the real return state on the stack. */ - up_copystate(regs, rtcb->xcp.regs); + COPYSTATE(regs, rtcb->xcp.regs); regs[XCPT_PC] = rtcb->xcp.saved_pc; regs[XCPT_I] = rtcb->xcp.saved_i; diff --git a/arch/z80/src/common/up_unblocktask.c b/arch/z80/src/common/up_unblocktask.c index 1ce672a5da..aa09342c67 100644 --- a/arch/z80/src/common/up_unblocktask.c +++ b/arch/z80/src/common/up_unblocktask.c @@ -1,5 +1,5 @@ /**************************************************************************** - * common/up_unblocktask.c + * arch/z80/src/common/up_unblocktask.c * * Copyright (C) 2007, 2008 Gregory Nutt. All rights reserved. * Author: Gregory Nutt @@ -46,6 +46,7 @@ #include #include "chip/chip.h" +#include "chip/switch.h" #include "os_internal.h" #include "clock_internal.h" #include "up_internal.h" @@ -121,7 +122,7 @@ void up_unblock_task(FAR _TCB *tcb) * Are we in an interrupt handler? */ - if (IN_INTERRUPT) + if (IN_INTERRUPT()) { /* Yes, then we have to do things differently. * Just copy the current context into the OLD rtcb. diff --git a/arch/z80/src/z8/Make.defs b/arch/z80/src/z8/Make.defs index 389d6bb81a..da6d78a9e0 100644 --- a/arch/z80/src/z8/Make.defs +++ b/arch/z80/src/z8/Make.defs @@ -39,11 +39,10 @@ CMN_SSRCS = CMN_CSRCS = up_initialize.c up_allocateheap.c up_createstack.c \ up_releasestack.c up_interruptcontext.c up_blocktask.c \ up_unblocktask.c up_exit.c up_releasepending.c \ - up_reprioritizertr.c up_copystate.c up_idle.c \ - up_assert.c up_mdelay.c up_udelay.c \ - up_schedulesigaction.c up_sigdeliver.c \ - up_registerdump.c up_usestack.c + up_reprioritizertr.c up_idle.c up_assert.c up_doirq.c \ + up_mdelay.c up_udelay.c up_schedulesigaction.c \ + up_sigdeliver.c up_usestack.c CHIP_SSRCS = z8_vector.S #z8_saveusercontext.S z8_restoreusercontext.S -CHIP_CSRCS = #z8_initialstate.c z8_irq.c +CHIP_CSRCS = #z8_initialstate.c z8_irq.c z8_copystate.c z8_registerdump.c diff --git a/arch/z80/src/z8/z8_copystate.c b/arch/z80/src/z8/z8_copystate.c new file mode 100644 index 0000000000..d4d4601a8a --- /dev/null +++ b/arch/z80/src/z8/z8_copystate.c @@ -0,0 +1,79 @@ +/**************************************************************************** + * arch/z80/src/z8/z8_copystate.c + * + * Copyright (C) 2008 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include "chip/switch.h" +#include "os_internal.h" +#include "up_internal.h" + +/**************************************************************************** + * Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: z80_copystate + ****************************************************************************/ + +/* Maybe a little faster than most memcpy's */ + +void z8_copystate(FAR chipreg_t *dest, FAR const chipreg_t *src) +{ + int i; + for (i = 0; i < XCPTCONTEXT_REGS; i++) + { + *dest++ = *src++; + } +} + diff --git a/arch/z80/src/z80/Make.defs b/arch/z80/src/z80/Make.defs index 11b0312f9e..18c6bca72e 100644 --- a/arch/z80/src/z80/Make.defs +++ b/arch/z80/src/z80/Make.defs @@ -39,10 +39,10 @@ CMN_ASRCS = CMN_CSRCS = up_initialize.c up_allocateheap.c up_createstack.c \ up_releasestack.c up_interruptcontext.c up_blocktask.c \ up_unblocktask.c up_exit.c up_releasepending.c \ - up_reprioritizertr.c up_copystate.c up_idle.c \ - up_assert.c up_mdelay.c up_udelay.c up_schedulesigaction.c \ - up_sigdeliver.c up_registerdump.c up_usestack.c + up_reprioritizertr.c up_idle.c up_assert.c up_doirq.c \ + up_mdelay.c up_udelay.c up_schedulesigaction.c \ + up_sigdeliver.c up_usestack.c CHIP_ASRCS = z80_saveusercontext.asm z80_restoreusercontext.asm -CHIP_CSRCS = z80_initialstate.c z80_irq.c +CHIP_CSRCS = z80_initialstate.c z80_irq.c z80_copystate.c z80_registerdump.c diff --git a/arch/z80/src/z80/switch.h b/arch/z80/src/z80/switch.h new file mode 100644 index 0000000000..c0c689dbfd --- /dev/null +++ b/arch/z80/src/z80/switch.h @@ -0,0 +1,168 @@ +/************************************************************************************ + * arch/z80/src/z80/switch.h + * arch/z80/src/chip/switch.h + * + * Copyright (C) 2008 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __Z80_SWITCH_H +#define __Z80_SWITCH_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include +#include +#include "up_internal.h" + +/************************************************************************************ + * Definitions + ************************************************************************************/ + +/* Macros for portability */ + +/* Initialize the IRQ state */ + +#define INIT_IRQCONTEXT() current_regs = NULL + +/* IN_INTERRUPT returns TRUE if the system is current operating in the interrupt + * context. IN_INTERRUPT is the inline equivalent of up_interrupt_context(). + */ + +#define IN_INTERRUPT() (current_regs != NULL) + +/* The following macro is used when the system enters interrupt handling logic */ + +#define IRQ_ENTER(irq, regs) current_regs = (regs) + +/* The following macro is used when the system exits interrupt handling logic */ + +#define IRQ_LEAVE(irq) current_regs = NULL + +/* The following macro is used to sample the interrupt state (as a opaque handle) */ + +#define IRQ_STATE() (current_regs) + +/* Copy a register state save structure to another location */ + +#define COPYSTATE(r1,r2) z80_copystate(r1,r2) + +/* Save the current IRQ context in the specified TCB */ + +#define SAVE_IRQCONTEXT(tcb) COPYSTATE((tcb)->xcp.regs, current_regs) + +/* Set the current IRQ context to the state specified in the TCB */ + +#define SET_IRQCONTEXT(tcb) COPYSTATE(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. + */ + +#define SAVE_USERCONTEXT(tcb) z80_saveusercontext((tcb)->xcp.regs) + +/* Restore the full context -- either a simple user state save or the full, + * IRQ state save. + */ + +#define RESTORE_USERCONTEXT(tcb) z80_restoreusercontext((tcb)->xcp.regs) + +/* Verify that we have a signal handler */ + +#define SIGNAL_DELIVERING(tcb) (tcb->xcp.sigdeliver != NULL) + +/* Setup the signal handler trampoline */ + +#define SIGNAL_SETUP(tcb, sigdeliver, regs) z80_sigsetup(tcb, sigdeliver, regs) + +/* Return from a signal handler using the provided register context */ + +#define SIGNAL_RETURN(regs) z80_restoreusercontext(regs) + +/* Dump the current machine registers */ + +#define _REGISTER_DUMP() z80_registerdump() + +/************************************************************************************ + * Public Variables + ************************************************************************************/ + +#ifndef __ASSEMBLY__ +/* 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; +#endif + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" { +#else +#define EXTERN extern +#endif + +/* Defined in z80_copystate.c */ + +EXTERN void z80_copystate(FAR chipreg_t *dest, FAR const chipreg_t *src); + +/* Defined in z80_saveusercontext.asm */ + +EXTERN int z80_saveusercontext(FAR chipreg_t *regs); + +/* Defined in z80_restoreusercontext.asm */ + +EXTERN int z80_restoreusercontext(FAR chipreg_t *regs); + +/* Defined in z80_sigsetup.c */ + +EXTERN void z80_sigsetup(FAR _TCB *tcb, sig_deliver_t sigdeliver, FAR chipreg_t *regs); + +/* Defined in z80_registerdump.c */ + +EXTERN void z80_registerdump(void); + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __Z80_SWITCH_H */ diff --git a/arch/z80/src/common/up_copystate.c b/arch/z80/src/z80/z80_copystate.c similarity index 95% rename from arch/z80/src/common/up_copystate.c rename to arch/z80/src/z80/z80_copystate.c index b05ab82c31..02dd4841c6 100644 --- a/arch/z80/src/common/up_copystate.c +++ b/arch/z80/src/z80/z80_copystate.c @@ -1,5 +1,5 @@ /**************************************************************************** - * common/up_copystate.c + * arch/z80/src/z80/z80_copystate.c * * Copyright (C) 2007, 2008 Gregory Nutt. All rights reserved. * Author: Gregory Nutt @@ -42,6 +42,7 @@ #include #include +#include "chip/switch.h" #include "os_internal.h" #include "up_internal.h" @@ -62,12 +63,12 @@ ****************************************************************************/ /**************************************************************************** - * Name: up_undefinedinsn + * Name: z80_copystate ****************************************************************************/ /* Maybe a little faster than most memcpy's */ -void up_copystate(FAR chipreg_t *dest, FAR const chipreg_t *src) +void z80_copystate(FAR chipreg_t *dest, FAR const chipreg_t *src) { int i; for (i = 0; i < XCPTCONTEXT_REGS; i++) diff --git a/arch/z80/src/z80/z80_head.asm b/arch/z80/src/z80/z80_head.asm index 2a02cdf1c1..eb246b588e 100644 --- a/arch/z80/src/z80/z80_head.asm +++ b/arch/z80/src/z80/z80_head.asm @@ -61,7 +61,7 @@ ;************************************************************************** .globl _os_start ; OS entry point - .globl _up_decodeirq ; Interrupt decoding logic + .globl _up_doirq ; Interrupt decoding logic ;************************************************************************** ; Reset entry point @@ -216,7 +216,7 @@ _up_rstcommon:: push hl ; Place argument #2 at the top of stack push bc ; Argument #1 is the Reset number inc sp ; (make byte sized) - call _up_decodeirq ; Decode the IRQ + call _up_doirq ; Decode the IRQ ; On return, HL points to the beginning of the reg structure to restore ; Note that (1) the arguments pushed on the stack are not popped, and (2) the diff --git a/arch/z80/src/z80/z80_irq.c b/arch/z80/src/z80/z80_irq.c index 5d4e92fe01..d9aee3994e 100644 --- a/arch/z80/src/z80/z80_irq.c +++ b/arch/z80/src/z80/z80_irq.c @@ -50,6 +50,16 @@ * Private Definitions ****************************************************************************/ +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* This holds a references to the current interrupt level register storage +* structure. If is non-NULL only during interrupt processing. + */ + +chipreg_t *current_regs; + /**************************************************************************** * Private Data ****************************************************************************/ diff --git a/arch/z80/src/common/up_registerdump.c b/arch/z80/src/z80/z80_registerdump.c similarity index 96% rename from arch/z80/src/common/up_registerdump.c rename to arch/z80/src/z80/z80_registerdump.c index 05761bf859..8646fcb843 100644 --- a/arch/z80/src/common/up_registerdump.c +++ b/arch/z80/src/z80/z80_registerdump.c @@ -1,5 +1,5 @@ /**************************************************************************** - * common/up_registerdump.c + * arch/z80/src/z80/z80_registerdump.c * * Copyright (C) 2007, 2008 Gregory Nutt. All rights reserved. * Author: Gregory Nutt @@ -45,6 +45,7 @@ #include #include +#include "chip/switch.h" #include "os_internal.h" #include "up_internal.h" @@ -70,11 +71,11 @@ ****************************************************************************/ /**************************************************************************** - * Name: up_registerdump + * Name: z80_registerdump ****************************************************************************/ #ifdef CONFIG_ARCH_STACKDUMP -static void up_registerdump(void) +static void z80_registerdump(void) { if (current_regs) { diff --git a/arch/z80/src/z80/z80_restoreusercontext.asm b/arch/z80/src/z80/z80_restoreusercontext.asm index 5807fa811e..27dbdf433e 100644 --- a/arch/z80/src/z80/z80_restoreusercontext.asm +++ b/arch/z80/src/z80/z80_restoreusercontext.asm @@ -46,11 +46,11 @@ .globl XCPT_PC ; Offset 8: Offset to PC at time of interrupt ;************************************************************************** -; up_restoreusercontext +; z80_restoreusercontext ;************************************************************************** .area _CODE -_up_restoreusercontext: +_z80_restoreusercontext: ; On entry, stack contains return address (not used), then address ; of the register save structure diff --git a/arch/z80/src/z80/z80_saveusercontext.asm b/arch/z80/src/z80/z80_saveusercontext.asm index 886872f37a..807b3fce1f 100644 --- a/arch/z80/src/z80/z80_saveusercontext.asm +++ b/arch/z80/src/z80/z80_saveusercontext.asm @@ -59,11 +59,11 @@ SP_OFFSET == 6 ;************************************************************************* -; Name: up_saveusercontext +; Name: z80_saveusercontext ;************************************************************************* .area _CODE -_up_saveusercontext: +_z80_saveusercontext: ; Set up a stack frame push ix ; Save IX and IY diff --git a/configs/z80sim/src/z80_decodeirq.c b/arch/z80/src/z80/z80_sigsetup.c similarity index 67% rename from configs/z80sim/src/z80_decodeirq.c rename to arch/z80/src/z80/z80_sigsetup.c index 0b52bc7a6d..351745cd7f 100644 --- a/configs/z80sim/src/z80_decodeirq.c +++ b/arch/z80/src/z80/z80_sigsetup.c @@ -1,7 +1,7 @@ -/******************************************************************************** - * board/z80_decodeirq.c +/**************************************************************************** + * arch/z80/src/z80/z80_sigsetup.c * - * Copyright (C) 2007, 2008 Gregory Nutt. All rights reserved. + * Copyright (C) 2008 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -31,74 +31,57 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ********************************************************************************/ + ****************************************************************************/ -/******************************************************************************** +/**************************************************************************** * Included Files - ********************************************************************************/ + ****************************************************************************/ #include #include -#include -#include -#include -#include +#include +#include "chip/switch.h" #include "os_internal.h" #include "up_internal.h" -/******************************************************************************** +/**************************************************************************** * Definitions - ********************************************************************************/ + ****************************************************************************/ -/******************************************************************************** - * Public Data - ********************************************************************************/ - -/******************************************************************************** +/**************************************************************************** * Private Data - ********************************************************************************/ + ****************************************************************************/ -/******************************************************************************** +/**************************************************************************** * Private Functions - ********************************************************************************/ + ****************************************************************************/ -/******************************************************************************** +/**************************************************************************** * Public Functions - ********************************************************************************/ + ****************************************************************************/ -FAR chipreg_t *up_decodeirq(uint8 rstno, FAR chipreg_t *regs) +/**************************************************************************** + * Name: z80_copystate + ****************************************************************************/ + +void z80_sigsetup(FAR _TCB *tcb, sig_deliver_t sigdeliver, FAR chipreg_t *regs) { -#ifdef CONFIG_SUPPRESS_INTERRUPTS - - lib_lowprintf("Unexpected IRQ\n"); - current_regs = regs; - PANIC(OSERR_ERREXCEPTION); - return NULL; /* Won't get here */ - -#else - - /* Current regs non-zero indicates that we are processing an interrupt; - * current_regs is also used to manage interrupt level context switches. + /* Save the return address and interrupt state. These will be restored by + * the signal trampoline after the signals have been delivered (via + * SIGNAL_RETURN). */ - current_regs = regs; + tcb->xcp.sigdeliver = sigdeliver; + tcb->xcp.saved_pc = regs[XCPT_PC]; + tcb->xcp.saved_i = regs[XCPT_I]; - /* Deliver the IRQ -- the simulation supports only timer interrupts and - * the IRQ maps to the reset number (real hardware probably needs an - * additional level of interrupt decoding. - */ + /* Then set up to vector to the trampoline with interrupts disabled */ - irq_dispatch((int)rstno, regs); - - /* If a context switch occurred, current_regs will hold the new context */ - - regs = current_regs; - - /* Indicate that we are no long in an interrupt handler */ - - current_regs = NULL; - return regs; -#endif + regs[XCPT_PC] = (uint16)up_sigdeliver; + regs[XCPT_I] = 0; } + + + diff --git a/configs/z80sim/src/Makefile b/configs/z80sim/src/Makefile index be685f18c8..46767d1395 100644 --- a/configs/z80sim/src/Makefile +++ b/configs/z80sim/src/Makefile @@ -39,7 +39,7 @@ CFLAGS += -I$(TOPDIR)/sched -I$(TOPDIR)/arch/z80/src/common -I$(TOPDIR)/arch/z8 ASRCS = AOBJS = $(ASRCS:$(ASMEXT)=$(OBJEXT)) -CSRCS = z80_decodeirq.c z80_irq.c z80_serial.c z80_timerisr.c z80_lowputc.c +CSRCS = z80_irq.c z80_serial.c z80_timerisr.c z80_lowputc.c COBJS = $(CSRCS:.c=$(OBJEXT)) SRCS = $(ASRCS) $(CSRCS) diff --git a/configs/z80sim/src/z80_irq.c b/configs/z80sim/src/z80_irq.c index 5fd1503598..c2b64a1d59 100644 --- a/configs/z80sim/src/z80_irq.c +++ b/configs/z80sim/src/z80_irq.c @@ -72,10 +72,6 @@ void up_irqinitialize(void) { - /* currents_regs is non-NULL only while processing an interrupt */ - - current_regs = NULL; - /* Attach the timer interrupt -- There is not special timer interrupt * enable in the simulation so it must be enabled here before interrupts * are enabled.