Fix Z16F context structure

git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@556 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
patacongo 2008-01-13 15:31:26 +00:00
parent 9108a01f1d
commit 1f115108e6
9 changed files with 86 additions and 48 deletions

View File

@ -69,7 +69,7 @@ typedef unsigned int uint32;
* irqsave() * irqsave()
*/ */
typedef unsigned int irqstate_t; typedef unsigned short irqstate_t;
#endif /* __ASSEMBLY__ */ #endif /* __ASSEMBLY__ */

View File

@ -98,19 +98,31 @@
* in the TCB to many context switches. * in the TCB to many context switches.
*/ */
#define XCPT_I (0) /* Offset 0: Saved I w/interrupt state in carry */ #define REG_R0 ( 0) /* 32-bits: R0 */
#define XCPT_BC (1) /* Offset 1: Saved BC register */ #define REG_R1 ( 2) /* 32-bits: R0 */
#define XCPT_DE (2) /* Offset 2: Saved DE register */ #define REG_R2 ( 4) /* 32-bits: R0 */
#define XCPT_IX (3) /* Offset 3: Saved IX register */ #define REG_R3 ( 6) /* 32-bits: R0 */
#define XCPT_IY (4) /* Offset 4: Saved IY register */ #define REG_R4 ( 8) /* 32-bits: R0 */
#define XCPT_SP (5) /* Offset 5: Offset to SP at time of interrupt */ #define REG_R5 (10) /* 32-bits: R0 */
#define XCPT_HL (6) /* Offset 6: Saved HL register */ #define REG_R6 (12) /* 32-bits: R0 */
#define XCPT_AF (7) /* Offset 7: Saved AF register */ #define REG_R7 (14) /* 32-bits: R0 */
#define XCPT_PC (8) /* Offset 8: Offset to PC at time of interrupt */ #define REG_R8 (16) /* 32-bits: R0 */
#define REG_R9 (18) /* 32-bits: R0 */
#define REG_R10 (20) /* 32-bits: R0 */
#define REG_R11 (22) /* 32-bits: R0 */
#define REG_R12 (24) /* 32-bits: R0 */
#define REG_R13 (26) /* 32-bits: R0 */
#define REG_R14 (28) /* 32-bits: R0 */
#define REG_R15 (30) /* 32-bits: R0 */
#define REG_PC (32) /* 32-bits: Return PC */
#define REG_FLAGS (34) /* 16-bits: Flags register (with 0x00 padding)
#define XCPTCONTEXT_REGS (9) #define XCPTCONTEXT_REGS (35)
#define XCPTCONTEXT_SIZE (2 * XCPTCONTEXT_REGS) #define XCPTCONTEXT_SIZE (2 * XCPTCONTEXT_REGS)
#define REG_FP REG_R14
#define REG_SP REG_R15
/**************************************************************************** /****************************************************************************
* Public Types * Public Types
****************************************************************************/ ****************************************************************************/
@ -138,12 +150,24 @@ struct xcptcontext
/* The following retains that state during signal execution */ /* The following retains that state during signal execution */
uint16 saved_pc; /* Saved return address */ uint32 saved_pc; /* Saved return address */
uint16 saved_i; /* Saved interrupt state */ uint16 saved_i; /* Saved interrupt state */
#endif #endif
}; };
#endif #endif
/* 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);
*/
#ifdef __ZILOG__
# define irqsave() TDI()
# define irqrestore(f) RI(f)
#endif
/**************************************************************************** /****************************************************************************
* Inline functions * Inline functions
****************************************************************************/ ****************************************************************************/
@ -164,8 +188,10 @@ extern "C" {
#define EXTERN extern #define EXTERN extern
#endif #endif
#ifndef __ZILOG__
EXTERN irqstate_t irqsave(void); EXTERN irqstate_t irqsave(void);
EXTERN void irqrestore(irqstate_t flags); EXTERN void irqrestore(irqstate_t flags);
#endif
#undef EXTERN #undef EXTERN
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -81,7 +81,7 @@ $(AOBJS) $(HEAD_AOBJ): %$(OBJEXT): %$(ASMEXT)
$(call ASSEMBLE, $<, $@) $(call ASSEMBLE, $<, $@)
else else
$(OBJS) $(HEAD_AOBJ): %$(OBJEXT): %.S $(OBJS) $(HEAD_AOBJ): %$(OBJEXT): %.S
$(call ASSEMBLE, $<, $@)endif $(call ASSEMBLE, $<, $@)
endif endif
$(COBJS): %$(OBJEXT): %.c $(COBJS): %$(OBJEXT): %.c

View File

@ -78,14 +78,14 @@
void up_initial_state(_TCB *tcb) void up_initial_state(_TCB *tcb)
{ {
struct xcptcontext *xcp = &tcb->xcp; uint32 *reg32 = (uint32*)tcb->xcp.regs;
/* Initialize the initial exception register context structure */ /* Initialize the initial exception register context structure */
memset(xcp, 0, sizeof(struct xcptcontext)); memset(&tcb->xcp, 0, sizeof(struct xcptcontext));
#ifndef CONFIG_SUPPRESS_INTERRUPTS #ifndef CONFIG_SUPPRESS_INTERRUPTS
xcp->regs[XCPT_I] = Z80_C_FLAG; /* Carry flag will enable interrupts */ xcp->regs[REG_FLAGS] = Z16F_CNTRL_FLAGS_IRQE << 8; /* IRQE flag will enable interrupts */
#endif #endif
xcp->regs[XCPT_SP] = (chipreg_t)tcb->adj_stack_ptr; reg32[REG_SP/2] = (uint32)tcb->adj_stack_ptr;
xcp->regs[XCPT_PC] = (chipreg_t)tcb->start; reg32[REG_PC/2] = (uint32)tcb->start;
} }

View File

@ -76,16 +76,15 @@
#ifdef CONFIG_ARCH_STACKDUMP #ifdef CONFIG_ARCH_STACKDUMP
static void up_registerdump(void) static void up_registerdump(void)
{ {
if (current_regs) uint32 *regs32 = (uint32*)current_regs;
{ lldbg("R0 :%08x R1 :%08x R2 :%08x R3 :%08x "
lldbg("AF: %04x I: %04x\n", "R4 :%08x R5 :%08x R6 :%08x R7 :%08x\n"
current_regs[XCPT_AF], current_regs[XCPT_I]); regs32[REG_R0/2], regs32[REG_R1/2], regs32[REG_R2/2], regs32[REG_R3/2],
lldbg("BC: %04x DE: %04x HL: %04x\n", regs32[REG_R4/2], regs32[REG_R5/2], regs32[REG_R6/2], regs32[REG_R7/2]);
current_regs[XCPT_BC], current_regs[XCPT_DE], current_regs[XCPT_HL]); lldbg("R8 :%08x R9 :%08x R10:%08x R11:%08x R12:%08x R13:%08x\n"
lldbg("IX: %04x IY: %04x\n", regs32[REG_R8/2], regs32[REG_R9/2], regs32[REG_R10/2], regs3[REG_R11/2],
current_regs[XCPT_IX], current_regs[XCPT_IY]); regs32[REG_R12/2], regs32[REG_R13/2]);
lldbg("SP: %04x PC: $04x\n" lldbg("FP :%08x SP :%08x FLG:%04x\n"
current_regs[XCPT_SP], current_regs[XCPT_PC]); regs32[REG_R14/2], regs32[REG_R15/2], current_regs[REG_FLAGS]);
}
} }
#endif #endif

View File

@ -141,21 +141,23 @@ void up_schedule_sigaction(FAR _TCB *tcb, sig_deliver_t sigdeliver)
else else
{ {
uint32 *current_pc = (uint32*)&current_regs[REG_PC];
/* Save the return address and interrupt state. /* Save the return address and interrupt state.
* These will be restored by the signal trampoline after * These will be restored by the signal trampoline after
* the signals have been delivered. * the signals have been delivered.
*/ */
tcb->xcp.sigdeliver = sigdeliver; tcb->xcp.sigdeliver = sigdeliver;
tcb->xcp.saved_pc = current_regs[XCPT_PC]; tcb->xcp.saved_pc = *current_pc;
tcb->xcp.saved_i = current_regs[XCPT_I]; tcb->xcp.saved_i = current_regs[REG_FLAGS];
/* Then set up to vector to the trampoline with interrupts /* Then set up to vector to the trampoline with interrupts
* disabled * disabled
*/ */
current_regs[XCPT_PC] = (chipreg_t)up_sigdeliver; *current_pc = (uint32)up_sigdeliver;
current_regs[XCPT_I] = 0; current_regs[REG_FLAGS] = 0;
/* And make sure that the saved context in the TCB /* And make sure that the saved context in the TCB
* is the same as the interrupt return context. * is the same as the interrupt return context.
@ -173,21 +175,23 @@ void up_schedule_sigaction(FAR _TCB *tcb, sig_deliver_t sigdeliver)
else else
{ {
uint32 *saved_pc = (uint32*)&tcb->xcp.regs[REG_PC];
/* Save the return lr and cpsr and one scratch register /* Save the return lr and cpsr and one scratch register
* These will be restored by the signal trampoline after * These will be restored by the signal trampoline after
* the signals have been delivered. * the signals have been delivered.
*/ */
tcb->xcp.sigdeliver = sigdeliver; tcb->xcp.sigdeliver = sigdeliver;
tcb->xcp.saved_pc = tcb->xcp.regs[XCPT_PC]; tcb->xcp.saved_pc = *saved_pc;
tcb->xcp.saved_i = tcb->xcp.regs[XCPT_I]; tcb->xcp.saved_i = tcb->xcp.regs[REG_FLAGS];
/* Then set up to vector to the trampoline with interrupts /* Then set up to vector to the trampoline with interrupts
* disabled * disabled
*/ */
tcb->xcp.regs[XCPT_PC] = (chipreg_t)up_sigdeliver; *saved_pc = (uint32)up_sigdeliver;
tcb->xcp.regs[XCPT_I] = 0; tcb->xcp.regs[REG_FLAGS] = 0;
} }
irqrestore(flags); irqrestore(flags);

View File

@ -83,6 +83,7 @@ void up_sigdeliver(void)
#ifndef CONFIG_DISABLE_SIGNALS #ifndef CONFIG_DISABLE_SIGNALS
_TCB *rtcb = (_TCB*)g_readytorun.head; _TCB *rtcb = (_TCB*)g_readytorun.head;
chipreg_t regs[XCPTCONTEXT_REGS]; chipreg_t regs[XCPTCONTEXT_REGS];
uint32 *regs32 = (uint32*)regs;
sig_deliver_t sigdeliver; sig_deliver_t sigdeliver;
/* Save the errno. This must be preserved throughout the signal handling /* Save the errno. This must be preserved throughout the signal handling
@ -101,8 +102,8 @@ void up_sigdeliver(void)
/* Save the real return state on the stack. */ /* Save the real return state on the stack. */
up_copystate(regs, rtcb->xcp.regs); up_copystate(regs, rtcb->xcp.regs);
regs[XCPT_PC] = rtcb->xcp.saved_pc; regs32[REG_PC/2] = rtcb->xcp.saved_pc;
regs[XCPT_I] = rtcb->xcp.saved_i; regs[REG_FLAGS] = rtcb->xcp.saved_i;
/* Get a local copy of the sigdeliver function pointer. /* Get a local copy of the sigdeliver function pointer.
* we do this so that we can nullify the sigdeliver * we do this so that we can nullify the sigdeliver
@ -116,7 +117,10 @@ void up_sigdeliver(void)
/* Then restore the task interrupt state. */ /* Then restore the task interrupt state. */
irqrestore(regs[XCPT_I]); if ((reg[REG_FLAGS] & (Z16F_CNTRL_FLAGS_IRQE << 8)) != 0)
{
EI();
}
/* Deliver the signals */ /* Deliver the signals */

View File

@ -125,12 +125,12 @@ EXEEXT = .hex
# object files into an archive # object files into an archive
define COMPILE define COMPILE
@echo "CC: $1" @#echo "CC: $1"
@$(CC) $(CFLAGS) $1 1>/dev/null @$(CC) $(CFLAGS) $1
endef endef
define ASSEMBLE define ASSEMBLE
@echo "AS: $1" @#echo "AS: $1"
@$(AS) -c $(AFLAGS) $1 @$(AS) -c $(AFLAGS) $1
endef endef

View File

@ -52,11 +52,16 @@ OBJS = $(AOBJS) $(COBJS)
all: libboard$(LIBEXT) all: libboard$(LIBEXT)
$(AOBJS): %$(OBJEXT): %.S $(ASRCS) $(HEAD_ASRC): %$(ASMEXT): %.S
@$(CPP) $(CPPFLAGS) $< -o $@.tmp
@cat $@.tmp | sed -e "s/^#/;/g" > $@
@rm $@.tmp
$(AOBJS): %$(OBJEXT): %$(ASMEXT)
$(call ASSEMBLE, $<, $@) $(call ASSEMBLE, $<, $@)
$(COBJS) $(LINKOBJS): %$(OBJEXT): %.c $(COBJS) $(LINKOBJS): %$(OBJEXT): %.c
$(call COMPILE, $<, $@) $(call COMPILE, `cygpath -w $<`, $@)
libboard$(LIBEXT): $(OBJS) libboard$(LIBEXT): $(OBJS)
@( for obj in $(OBJS) ; do \ @( for obj in $(OBJS) ; do \