diff --git a/arch/avr/include/avr32/irq.h b/arch/avr/include/avr32/irq.h index b63fb1925b..f5333e88d1 100644 --- a/arch/avr/include/avr32/irq.h +++ b/arch/avr/include/avr32/irq.h @@ -108,12 +108,17 @@ #ifndef __ASSEMBLY__ struct xcptcontext { - /* The following function pointer is non-zero if there - * are pending signals to be processed. + /* The following function pointer is non-zero if there are pending signals + * to be processed. */ #ifndef CONFIG_DISABLE_SIGNALS void *sigdeliver; /* Actual type is sig_deliver_t */ + + /* These are saved copies of PC and SR used during signal processing.*/ + + uint32_t saved_pc; + uint32_t saved_sr; #endif /* Register save area */ diff --git a/arch/avr/src/avr32/up_schedulesigaction.c b/arch/avr/src/avr32/up_schedulesigaction.c index c5e6a7af54..63bc9f1b9f 100644 --- a/arch/avr/src/avr32/up_schedulesigaction.c +++ b/arch/avr/src/avr32/up_schedulesigaction.c @@ -44,6 +44,7 @@ #include #include +#include #include "os_internal.h" #include "up_internal.h" @@ -152,14 +153,16 @@ void up_schedule_sigaction(_TCB *tcb, sig_deliver_t sigdeliver) * the signal(s) have been delivered. */ - tcb->xcp.sigdeliver = sigdeliver; -#warning "Not implemented" + tcb->xcp.sigdeliver = sigdeliver; + tcb->xcp.saved_pc = current_regs[REG_PC]; + tcb->xcp.saved_sr = current_regs[REG_SR]; /* Then set up to vector to the trampoline with interrupts * disabled */ -#warning "Not implemented" + current_regs[REG_PC] = (uint32_t)up_sigdeliver; + current_regs[REG_SR] |= AVR32_SR_GM_MASK; /* And make sure that the saved context in the TCB * is the same as the interrupt return context. @@ -183,13 +186,15 @@ void up_schedule_sigaction(_TCB *tcb, sig_deliver_t sigdeliver) */ tcb->xcp.sigdeliver = sigdeliver; -#warning "Not implemented" + tcb->xcp.saved_pc = current_regs[REG_PC]; + tcb->xcp.saved_sr = current_regs[REG_SR]; /* Then set up to vector to the trampoline with interrupts * disabled */ -#warning "Not implemented" + tcb->xcp.regs[REG_PC] = (uint32_t)up_sigdeliver; + tcb->xcp.regs[REG_SR] |= AVR32_SR_GM_MASK; } irqrestore(flags); diff --git a/arch/avr/src/avr32/up_sigdeliver.c b/arch/avr/src/avr32/up_sigdeliver.c index 1a8c2a7bcd..599b6f0d03 100644 --- a/arch/avr/src/avr32/up_sigdeliver.c +++ b/arch/avr/src/avr32/up_sigdeliver.c @@ -100,7 +100,8 @@ void up_sigdeliver(void) /* Save the real return state on the stack. */ up_copystate(regs, rtcb->xcp.regs); -#warning "Not Implemented" + regs[REG_PC] = rtcb->xcp.saved_pc; + regs[REG_SR] = rtcb->xcp.saved_sr; /* Get a local copy of the sigdeliver function pointer. We do this so tha * we can nullify the sigdeliver function point in the TCB and accept more @@ -112,7 +113,7 @@ void up_sigdeliver(void) /* Then restore the task interrupt state */ -#warning "Not Implemented" + irqrestore(regs[REG_SR]); /* Deliver the signals */