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:
parent
7303584054
commit
197df27b7c
|
@ -69,7 +69,7 @@ typedef unsigned int uint32;
|
|||
* irqsave()
|
||||
*/
|
||||
|
||||
typedef unsigned int irqstate_t;
|
||||
typedef unsigned short irqstate_t;
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -141,21 +141,23 @@ void up_schedule_sigaction(FAR _TCB *tcb, sig_deliver_t sigdeliver)
|
|||
|
||||
else
|
||||
{
|
||||
uint32 *current_pc = (uint32*)¤t_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);
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
Loading…
Reference in New Issue