summaryrefslogtreecommitdiff
path: root/nuttx/arch/z80/src/ez80/switch.h
diff options
context:
space:
mode:
Diffstat (limited to 'nuttx/arch/z80/src/ez80/switch.h')
-rw-r--r--nuttx/arch/z80/src/ez80/switch.h249
1 files changed, 249 insertions, 0 deletions
diff --git a/nuttx/arch/z80/src/ez80/switch.h b/nuttx/arch/z80/src/ez80/switch.h
new file mode 100644
index 000000000..8aec784f2
--- /dev/null
+++ b/nuttx/arch/z80/src/ez80/switch.h
@@ -0,0 +1,249 @@
+/************************************************************************************
+ * arch/z80/src/ez80/switch.h
+ * arch/z80/src/chip/switch.h
+ *
+ * Copyright (C) 2008 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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 __EZ80_SWITCH_H
+#define __EZ80_SWITCH_H
+
+/************************************************************************************
+ * Included Files
+ ************************************************************************************/
+
+#include <sys/types.h>
+#ifndef __ASSEMBLY__
+# include <nuttx/sched.h>
+# include <nuttx/arch.h>
+#endif
+#include "common/up_internal.h"
+
+/************************************************************************************
+ * Definitions
+ ************************************************************************************/
+
+/* EZ80_IRQSTATE_* definitions ********************************************************
+ * These are used in the state field of 'struct z8_irqstate_s' structure to define
+ * the current state of the interrupt handling. These definition support "lazy"
+ * interrupt context saving. See comments below associated with s'truct z8_irqstate_s'.
+ */
+
+#define EZ80_IRQSTATE_NONE 0 /* Not handling an interrupt */
+#define EZ80_IRQSTATE_ENTRY 1 /* In interrupt, context has not been saved */
+#define EZ80_IRQSTATE_SAVED 2 /* In interrupt, context has been saved */
+
+/* The information saved on interrupt entry can be retained in a array of two
+ * uint16 values. These are
+ *
+ * value[0] = RP (MS byte) and Flags (LS) byte
+ * value[1] = PC
+ *
+ * The pointer to the save structure is a stack pointer at the time that up_doirq()
+ * was called:
+ *
+ * PC[7:0]
+ * PC[15:8]
+ * Flags Register
+ * SP -> RP
+ *
+ * The stack pointer on return from interrupt can be obtained by adding 4 to the
+ * pointer to the save structure.
+ */
+
+#define EZ80_IRQSAVE_RPFLAGS (0) /* Index 10: RP (MS) and FLAGS (LS) */
+#define EZ80_IRQSAVE_PC (1) /* Index 2: PC[8:15] */
+#define EZ80_IRQSAVE_REGS (2) /* Number 16-bit values saved */
+
+/* Byte offsets */
+
+#define EZ80_IRQSAVE_RP_OFFS (2*EZ80_IRQSAVE_RPFLAGS) /* Offset 0: RP */
+#define EZ80_IRQSAVE_FLAGS_OFFS (2*EZ80_IRQSAVE_RPFLAGS+1) /* Offset 1: FLAGS */
+#define EZ80_IRQSAVE_PCH_OFFS (2*EZ80_IRQSAVE_PC) /* Offset 2: PC[8:15] */
+#define EZ80_IRQSAVE_PCL_OFFS (2*EZ80_IRQSAVE_PC+1) /* Offset 3: PC[0:7] */
+#define EZ80_IRQSAVE_SIZE (2*EZ80_IRQSAVE_REGS) /* Number 8-bit values saved */
+
+/* Macros for portability ***********************************************************
+ *
+ * Common logic in arch/z80/src/common is customized for the z8 context switching
+ * logic via the following macros.
+ */
+
+/* Initialize the IRQ state */
+
+#define INIT_IRQCONTEXT() \
+ do { \
+ g_z8irqstate.state = EZ80_IRQSTATE_NONE; \
+ } while (0)
+
+/* 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() \
+ (g_z8irqstate.state != EZ80_IRQSTATE_NONE)
+
+/* The following macro is used when the system enters interrupt handling logic */
+
+#define IRQ_ENTER(irq, regs) \
+ do { \
+ g_z8irqstate.state = EZ80_IRQSTATE_ENTRY; \
+ g_z8irqstate.regs = (regs); \
+ up_maskack_irq(irq); \
+ } while (0)
+
+/* The following macro is used when the system exits interrupt handling logic */
+
+#define IRQ_LEAVE(irq) \
+ do { \
+ g_z8irqstate.state = EZ80_IRQSTATE_NONE; \
+ up_enable_irq(irq); \
+ } while (0)
+
+/* The following macro is used to sample the interrupt state (as a opaque handle) */
+
+#define IRQ_STATE() \
+ (g_z8irqstate.regs)
+
+/* Save the current IRQ context in the specified TCB */
+
+#define SAVE_IRQCONTEXT(tcb) \
+ z8_saveirqcontext((tcb)->xcp.regs)
+
+/* Set the current IRQ context to the state specified in the TCB */
+
+#define SET_IRQCONTEXT(tcb) \
+ do { \
+ g_z8irqstate.state = EZ80_IRQSTATE_SAVED; \
+ g_z8irqstate.regs = (tcb)->xcp.regs; \
+ } while (0)
+
+/* 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) \
+ z8_saveusercontext((tcb)->xcp.regs)
+
+/* Restore the full context -- either a simple user state save or the full,
+ * IRQ state save.
+ */
+
+#define RESTORE_USERCONTEXT(tcb) \
+ z8_restorecontext((tcb)->xcp.regs)
+
+/* Dump the current machine registers */
+
+#define _REGISTER_DUMP() \
+ z8_registerdump()
+
+/************************************************************************************
+ * Public Types
+ ************************************************************************************/
+
+/* In order to provide faster interrupt handling, the interrupt logic does "lazy"
+ * context saving as described below:
+ *
+ * (1) At the time of the interrupt, minimum information is saved and the register
+ * pointer is changed so that the interrupt logic does not alter the state of
+ * the interrupted task's registers.
+ * (2) If no context switch occurs during the interrupt processing, then the return
+ * from interrupt is also simple.
+ * (3) If a context switch occurs during interrupt processing, then
+ * (a) The full context of the interrupt task is saved, and
+ * (b) A full context switch is performed when the interrupt exits (see
+ * z8_vector.S).
+ *
+ * The following structure is used to manage this "lazy" context saving.
+ */
+
+#ifndef __ASSEMBLY__
+struct z8_irqstate_s
+{
+ ubyte state; /* See EZ80_IRQSTATE_* definitions above */
+ chipreg_t *regs; /* Saved register information */
+};
+#endif
+
+/************************************************************************************
+ * Public Variables
+ ************************************************************************************/
+
+#ifndef __ASSEMBLY__
+/* This structure holds information about the current interrupt processing state */
+
+extern struct z8_irqstate_s g_z8irqstate;
+#endif
+
+/************************************************************************************
+ * Public Function Prototypes
+ ************************************************************************************/
+
+#ifndef __ASSEMBLY__
+#ifdef __cplusplus
+#define EXTERN extern "C"
+extern "C" {
+#else
+#define EXTERN extern
+#endif
+
+/* Defined in z8_irq.c */
+
+EXTERN void up_maskack_irq(int irq);
+
+/* Defined in z8_saveusercontext.asm */
+
+EXTERN int z8_saveusercontext(FAR chipreg_t *regs);
+
+/* Defined in z8_saveirqcontext.c */
+
+EXTERN void z8_saveirqcontext(FAR chipreg_t *regs);
+
+/* Defined in z8_restorecontext.asm */
+
+EXTERN void z8_restorecontext(FAR chipreg_t *regs);
+
+/* Defined in z8_sigsetup.c */
+
+EXTERN void z8_sigsetup(FAR _TCB *tcb, sig_deliver_t sigdeliver, FAR chipreg_t *regs);
+
+/* Defined in z8_registerdump.c */
+
+EXTERN void z8_registerdump(void);
+
+#undef EXTERN
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+#endif /* __EZ80_SWITCH_H */