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 7303584054
commit 197df27b7c
7 changed files with 76 additions and 43 deletions

View File

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

View File

@ -98,18 +98,30 @@
* in the TCB to many context switches.
*/
#define XCPT_I (0) /* Offset 0: Saved I w/interrupt state in carry */
#define XCPT_BC (1) /* Offset 1: Saved BC register */
#define XCPT_DE (2) /* Offset 2: Saved DE 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 REG_R0 ( 0) /* 32-bits: R0 */
#define REG_R1 ( 2) /* 32-bits: R0 */
#define REG_R2 ( 4) /* 32-bits: R0 */
#define REG_R3 ( 6) /* 32-bits: R0 */
#define REG_R4 ( 8) /* 32-bits: R0 */
#define REG_R5 (10) /* 32-bits: R0 */
#define REG_R6 (12) /* 32-bits: R0 */
#define REG_R7 (14) /* 32-bits: R0 */
#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_SIZE (2 * XCPTCONTEXT_REGS)
#define XCPTCONTEXT_REGS (35)
#define XCPTCONTEXT_SIZE (2 * XCPTCONTEXT_REGS)
#define REG_FP REG_R14
#define REG_SP REG_R15
/****************************************************************************
* Public Types
@ -138,12 +150,24 @@ struct xcptcontext
/* 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 */
#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
****************************************************************************/
@ -164,8 +188,10 @@ extern "C" {
#define EXTERN extern
#endif
#ifndef __ZILOG__
EXTERN irqstate_t irqsave(void);
EXTERN void irqrestore(irqstate_t flags);
#endif
#undef EXTERN
#ifdef __cplusplus

View File

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

View File

@ -78,14 +78,14 @@
void up_initial_state(_TCB *tcb)
{
struct xcptcontext *xcp = &tcb->xcp;
uint32 *reg32 = (uint32*)tcb->xcp.regs;
/* Initialize the initial exception register context structure */
memset(xcp, 0, sizeof(struct xcptcontext));
memset(&tcb->xcp, 0, sizeof(struct xcptcontext));
#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
xcp->regs[XCPT_SP] = (chipreg_t)tcb->adj_stack_ptr;
xcp->regs[XCPT_PC] = (chipreg_t)tcb->start;
reg32[REG_SP/2] = (uint32)tcb->adj_stack_ptr;
reg32[REG_PC/2] = (uint32)tcb->start;
}

View File

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

View File

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

View File

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