summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2008-02-15 14:28:54 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2008-02-15 14:28:54 +0000
commitc0dbb0b79fd5f3a894d32e1c9621e65aba46b73c (patch)
treee857bfc8762505151d7547c0fda02ed6b303f682
parenteba1f80b6bf73a0006e43c89b4fc96362bb1a20b (diff)
downloadnuttx-c0dbb0b79fd5f3a894d32e1c9621e65aba46b73c.tar.gz
nuttx-c0dbb0b79fd5f3a894d32e1c9621e65aba46b73c.tar.bz2
nuttx-c0dbb0b79fd5f3a894d32e1c9621e65aba46b73c.zip
Flesh out Z8Encore\! interrupt context switches
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@685 42af7a65-404d-4744-a932-0658087f49c3
-rw-r--r--nuttx/arch/z80/include/z8/irq.h18
-rw-r--r--nuttx/arch/z80/src/common/up_sigdeliver.c2
-rw-r--r--nuttx/arch/z80/src/z8/z8_initialstate.c8
-rwxr-xr-xnuttx/arch/z80/src/z8/z8_restorecontext.S25
-rwxr-xr-xnuttx/arch/z80/src/z8/z8_vector.S172
-rw-r--r--nuttx/arch/z80/src/z80/z80_sigsetup.c2
6 files changed, 172 insertions, 55 deletions
diff --git a/nuttx/arch/z80/include/z8/irq.h b/nuttx/arch/z80/include/z8/irq.h
index 25d6d3ef4..962ed5662 100644
--- a/nuttx/arch/z80/include/z8/irq.h
+++ b/nuttx/arch/z80/include/z8/irq.h
@@ -245,7 +245,7 @@
/* Byte offsets: */
-#define XCPT_R0_OFFS (2*XCPT_RR0) /* Offset 0-15: R0-R15 */
+#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)
@@ -261,14 +261,14 @@
#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_UNUSED_OFFS (2*XCPT_IRQCTL) /* Offset 16: Unused (zero) */
-#define XCPT_IRQCTL_OFFS (2*XCPT_IRQCTL+1) /* offset 17: IRQCTL register */
-#define XCPT_SPH_OFFS (2*XCPT_SP) /* Offset 18: SP[8:15] */
-#define XCPT_SPL_OFFS (2*XCPT_SP+1) /* Offset 19: SP[0:7] */
-#define XCPT_RP_OFFS (2*XCPT_I) /* Offset 20: Register pointer */
-#define XCPT_FLAGS_OFFS (2*XCPT_I+1) /* Offset 21: FLAGS */
-#define XCPT_PCH_OFFS (2*XCPT_PC) /* Offset 22: PC[8:15] */
-#define XCPT_PCL_OFFS (2*XCPT_PC+1) /* Offset 23: PC[0:7] */
+#define XCPT_UNUSED_OFFS (2*XCPT_IRQCTL) /* Offset 16: Unused (zero) */
+#define XCPT_IRQCTL_OFFS (2*XCPT_IRQCTL+1) /* offset 17: IRQCTL register */
+#define XCPT_SPH_OFFS (2*XCPT_SP) /* Offset 18: SP[8:15] */
+#define XCPT_SPL_OFFS (2*XCPT_SP+1) /* Offset 19: SP[0:7] */
+#define XCPT_RP_OFFS (2*XCPT_RPFLAGS) /* Offset 20: Register pointer */
+#define XCPT_FLAGS_OFFS (2*XCPT_RPFLAGS+1) /* Offset 21: FLAGS */
+#define XCPT_PCH_OFFS (2*XCPT_PC) /* Offset 22: PC[8:15] */
+#define XCPT_PCL_OFFS (2*XCPT_PC+1) /* Offset 23: PC[0:7] */
#define XCPTCONTEXT_SIZE (2*XCPTCONTEXT_REGS)
diff --git a/nuttx/arch/z80/src/common/up_sigdeliver.c b/nuttx/arch/z80/src/common/up_sigdeliver.c
index 9ab8f8447..80fcb4e5c 100644
--- a/nuttx/arch/z80/src/common/up_sigdeliver.c
+++ b/nuttx/arch/z80/src/common/up_sigdeliver.c
@@ -83,7 +83,7 @@ void up_sigdeliver(void)
{
#ifndef CONFIG_DISABLE_SIGNALS
FAR _TCB *rtcb = (_TCB*)g_readytorun.head;
- uint16 regs[XCPTCONTEXT_REGS];
+ chipret_t regs[XCPTCONTEXT_REGS];
sig_deliver_t sigdeliver;
/* Save the errno. This must be preserved throughout the signal handling
diff --git a/nuttx/arch/z80/src/z8/z8_initialstate.c b/nuttx/arch/z80/src/z8/z8_initialstate.c
index 4d7ef4c17..57df5c735 100644
--- a/nuttx/arch/z80/src/z8/z8_initialstate.c
+++ b/nuttx/arch/z80/src/z8/z8_initialstate.c
@@ -41,7 +41,9 @@
#include <sys/types.h>
#include <string.h>
+
#include <nuttx/arch.h>
+#include <nuttx/sched.h>
#include "chip/chip.h"
#include "up_internal.h"
@@ -77,7 +79,7 @@
*
****************************************************************************/
-void up_initial_state(_TCB *tcb)
+void up_initial_state(FAR _TCB *tcb)
{
struct xcptcontext *xcp = &tcb->xcp;
@@ -85,9 +87,9 @@ void up_initial_state(_TCB *tcb)
memset(xcp, 0, sizeof(struct xcptcontext));
#ifndef CONFIG_SUPPRESS_INTERRUPTS
- xcp->regs[XCPT_IRQCTL] = %0080; /* IRQE bit will enable interrupts */
+ xcp->regs[XCPT_IRQCTL] = 0x0080; /* IRQE bit will enable interrupts */
#endif
- xcp->regs[XCPT_RPFLAGS] = %e000; /* RP=%e0 */
+ xcp->regs[XCPT_RPFLAGS] = 0xe000; /* RP=%e0 */
xcp->regs[XCPT_SP] = (chipreg_t)tcb->adj_stack_ptr;
xcp->regs[XCPT_PC] = (chipreg_t)tcb->start;
}
diff --git a/nuttx/arch/z80/src/z8/z8_restorecontext.S b/nuttx/arch/z80/src/z8/z8_restorecontext.S
index 2f614556e..ef22b10e4 100755
--- a/nuttx/arch/z80/src/z8/z8_restorecontext.S
+++ b/nuttx/arch/z80/src/z8/z8_restorecontext.S
@@ -101,23 +101,21 @@ _z8_restorecontext:
* address
*/
- ld r1, #%e0 /* r1 = destination address */
+ clr r0 /* rr0 = destination address */
+ ldx r1, XCPT_RP_OFFS(rr6)
ld r2, r6 /* rr2 = source address */
ld r3, r7
ld r4, #16 /* r4 = number of bytes to copy */
- cp r2, #0
- jr z, _z8_restore2
-_z8_restore1:
- ldx r0, @rr2
- ld @r1, r0
- inc r1
+_z8_restore:
+ ldx r5, @rr2
+ ldx @rr0, r5
+ incw rr0
incw rr2
- djnz r4, _z8_restore1
+ djnz r4, _z8_restore
/* Set the new stack pointer */
-_z8_restore2:
ldx r0, XCPT_SPH_OFFS(rr6)
ldx r1, XCPT_SPL_OFFS(rr6)
ldx sph, r0
@@ -130,9 +128,10 @@ _z8_restore2:
push r1
push r0
- /* Recover the flags settings.. but don't restore the flags yet */
+ /* Recover the flags and RP settings.. but don't restore them yet */
- ldx r1, XCPT_FLAGS_OFFS(rr6)
+ ldx r1, XCPT_FLAGS_OFFS(rr0)
+ ldx r2, XCPT_RP_OFFS(rr0)
/* Determine whether interrupts must be enabled on return. This
* would be nicer to do below, but later we will need to preserve
@@ -149,7 +148,7 @@ _z8_restore2:
/* Restore the user register page and return with interrupts disabled */
- srp #%e0 /* Does not effect flags */
+ ldx rp, r2 /* Does not effect flags */
ret /* Does not effect flags */
_z8_returnenabled:
@@ -159,7 +158,7 @@ _z8_returnenabled:
/* Restore the user register page, re-enable interrupts and return */
- srp #%e0 /* Does not effect flags */
+ ldx rp, r2 /* Does not effect flags */
ei /* Does not effect flags */
ret /* Does not effect flags */
diff --git a/nuttx/arch/z80/src/z8/z8_vector.S b/nuttx/arch/z80/src/z8/z8_vector.S
index aa25e5a89..186f59b59 100755
--- a/nuttx/arch/z80/src/z8/z8_vector.S
+++ b/nuttx/arch/z80/src/z8/z8_vector.S
@@ -52,50 +52,52 @@
* External References / External Definitions
**************************************************************************/
+ xref _up_doirq:ROM
+
#if defined(ENCORE_VECTORS)
- xdef _z8_wdt_handler
- xdef _z8_trap_handler
+ xdef _z8_wdt_handler
+ xdef _z8_trap_handler
if EZ8_TIMER3=1
- xdef _z8_timer2_handler
+ xdef _z8_timer2_handler
endif
- xdef _z8_timer1_handler
- xdef _z8_timer0_handler
+ xdef _z8_timer1_handler
+ xdef _z8_timer0_handler
if EZ8_UART0=1
- xdef _z8_uart0rx_handler
- xdef _z8_uart0tx_handler
+ xdef _z8_uart0rx_handler
+ xdef _z8_uart0tx_handler
endif
if EZ8_I2C=1
- xdef _z8_i2c_handler
+ xdef _z8_i2c_handler
endif
if EZ8_SPI=1
- xdef _z8_spi_handler
+ xdef _z8_spi_handler
endif
if EZ8_ADC=1
- xdef _z8_adc_handler
-endif
- xdef _z8_p7ad_handler
- xdef _z8_p6ad_handler
- xdef _z8_p5ad_handler
- xdef _z8_p4ad_handler
- xdef _z8_p3ad_handler
- xdef _z8_p2ad_handler
- xdef _z8_p1ad_handler
- xdef _z8_p0ad_handler
+ xdef _z8_adc_handler
+endif
+ xdef _z8_p7ad_handler
+ xdef _z8_p6ad_handler
+ xdef _z8_p5ad_handler
+ xdef _z8_p4ad_handler
+ xdef _z8_p3ad_handler
+ xdef _z8_p2ad_handler
+ xdef _z8_p1ad_handler
+ xdef _z8_p0ad_handler
if EZ8_TIMER4=1
- xdef _z8_timer3_handler
+ xdef _z8_timer3_handler
endif
if EZ8_UART1=1
- xdef _z8_uart1rx_handler
- xdef _z8_uart1tx_handler
+ xdef _z8_uart1rx_handler
+ xdef _z8_uart1tx_handler
endif
if EZ8_DMA=1
- xdef _z8_dma_handler
+ xdef _z8_dma_handler
endif
if EZ8_PORT1=0
- xdef _z8_c3_handler
- xdef _z8_c2_handler
- xdef _z8_c1_handler
- xdef _z8_c0_handler
+ xdef _z8_c3_handler
+ xdef _z8_c2_handler
+ xdef _z8_c1_handler
+ xdef _z8_c0_handler
endif
/**************************************************************************/
@@ -233,13 +235,14 @@ endif
**************************************************************************/
ENTER : MACRO val
+ pushx rp /* Save the current RP value in the stack */
srp #%f0 /* Load the interrupt register pointer */
ld r0, #val /* Pass the new value in r0
jr _z8_common_handler /* The rest of the handling is common */
ENDMAC ENTER
LEAVE : MACRO
- srp #%e0 /* Restore the user register pointer */
+ popx rp /* Restore the user register pointer */
iret /* And return from interrupt */
ENDMAC LEAVE
@@ -738,6 +741,119 @@ _z8_wotrap_handler:
**************************************************************************/
_z8_common_handler:
+ /* Pass the address of the IRQ stack frame */
+
+ ldx r2, sph /* rr2 = stack pointer */
+ ldx r3, spl
+ push r3 /* Pass as a parameter */
+ push r2
+
+ /* Pass the IRQ number */
+
+ push r0
+
+ /* Process the interrupt */
+
+ call _up_doirq /* Call the IRQ handler */
+
+ /* Release arguments from the stack */
+
+ pop r4 /* Discard the IRQ argument */
+ pop r2 /* Recover the stack pointer parameter */
+ pop r3
+
+ /* If a interrupt level context switch occurred, then the
+ * return value will be the same as the input value
+ */
+
+ cp r0, r2 /* Same as the return value? */
+ jr nz, _z8_switch
+ cp r1, r3
+ jr z, _z8_noswitch
+
+ /* A context switch occurs. Restore the use context.
+ * rr0 = pointer to context structgure.
+ */
+
+_z8_switch:
+
+ /* Destroy the interrupt return information on the stack */
+
+ pop r4 /* Destroy saved RP */
+ pop r4 /* Destroy saved flags */
+ pop r4 /* Destroy saved return address */
+ pop r4
+
+ /* Copy all registers into the user register area. */
+
+ clr r2 /* rr2 = destination address */
+ ldx r3, XCPT_RP_OFFS(rr0)
+ ld r4, r0 /* rr4 = source address */
+ ld r5, r1
+ ld r6, #16 /* r6 = number of bytes to copy */
+
+_z8_restore:
+ ldx r7, @rr4
+ ldx @rr2, r7
+ incw rr2
+ incw rr4
+ djnz r6, _z8_restore
+
+ /* Set the new stack pointer */
+
+ ldx r2, XCPT_SPH_OFFS(rr0)
+ ldx r3, XCPT_SPL_OFFS(rr0)
+ ldx sph, r2
+ ldx spl, r3
+
+ /* Push the return address onto the stack */
+
+ ldx r2, XCPT_PCH_OFFS(rr0)
+ ldx r3, XCPT_PCL_OFFS(rr0)
+ push r3
+ push r2
+
+ /* Recover the flags and RP settings.. but don't restore them yet */
+
+ ldx r3, XCPT_FLAGS_OFFS(rr0)
+ ldx r4, XCPT_RP_OFFS(rr0)
+
+ /* Determine whether interrupts must be enabled on return. This
+ * would be nicer to do below, but later we will need to preserve
+ * the condition codes in the flags.
+ */
+
+ ldx r2, XCPT_IRQCTL_OFFS(rr0)
+ tm r2, #%80
+ jr nz, _z8_returnenabled
+
+ /* Restore the flag settings */
+
+ ldx flags, r3
+
+ /* Restore the user register page and return with interrupts disabled.
+ * Note that we cannot use the iret instruction because it unconditionally
+ * re-enabled interrupts
+ */
+
+ ldx rp, r4 /* Does not effect flags */
+ ret /* Does not effect flags */
+
+_z8_returnenabled:
+ /* Restore the flag settings */
+
+ ldx flags, r1
+
+ /* Restore the user register page, re-enable interrupts and return.
+ * Note that we cannot use the iret instruction because it unconditionally
+ * re-enabled interrupts
+ */
+
+ ldx rp, r4 /* Does not effect flags */
+ ei /* Does not effect flags */
+ ret /* Does not effect flags */
+
+_z8_noswitch:
LEAVE
/**************************************************************************
diff --git a/nuttx/arch/z80/src/z80/z80_sigsetup.c b/nuttx/arch/z80/src/z80/z80_sigsetup.c
index 351745cd7..504f3ce19 100644
--- a/nuttx/arch/z80/src/z80/z80_sigsetup.c
+++ b/nuttx/arch/z80/src/z80/z80_sigsetup.c
@@ -79,7 +79,7 @@ void z80_sigsetup(FAR _TCB *tcb, sig_deliver_t sigdeliver, FAR chipreg_t *regs)
/* Then set up to vector to the trampoline with interrupts disabled */
- regs[XCPT_PC] = (uint16)up_sigdeliver;
+ regs[XCPT_PC] = (chipreg_t)up_sigdeliver;
regs[XCPT_I] = 0;
}