summaryrefslogtreecommitdiffstats
path: root/c/src/exec/score/cpu/unix/cpu.c
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>1996-05-23 15:34:54 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>1996-05-23 15:34:54 +0000
commitd196e48590af1f3cacd193f9034f963468410796 (patch)
tree8572bcba5c8754096f31de494d00bf78597dac49 /c/src/exec/score/cpu/unix/cpu.c
parent2328475ccd111f1c3a0dea032c5f1dee401995af (diff)
downloadrtems-d196e48590af1f3cacd193f9034f963468410796.tar.bz2
updates from Tony Bennett.
Broke the setjmp/longjmp pair in the context switch into a separate routine so no code depended on local variables surviving the jump.
Diffstat (limited to 'c/src/exec/score/cpu/unix/cpu.c')
-rw-r--r--c/src/exec/score/cpu/unix/cpu.c134
1 files changed, 76 insertions, 58 deletions
diff --git a/c/src/exec/score/cpu/unix/cpu.c b/c/src/exec/score/cpu/unix/cpu.c
index 4c1604465f..4c0beea43c 100644
--- a/c/src/exec/score/cpu/unix/cpu.c
+++ b/c/src/exec/score/cpu/unix/cpu.c
@@ -55,16 +55,16 @@
typedef struct {
jmp_buf regs;
- sigset_t isr_level;
+ unsigned32 isr_level;
} Context_Control_overlay;
void _CPU_Signal_initialize(void);
void _CPU_Stray_signal(int);
void _CPU_ISR_Handler(int);
-sigset_t _CPU_Signal_mask;
-Context_Control _CPU_Context_Default_with_ISRs_enabled;
-Context_Control _CPU_Context_Default_with_ISRs_disabled;
+static sigset_t _CPU_Signal_mask;
+static Context_Control_overlay _CPU_Context_Default_with_ISRs_enabled;
+static Context_Control_overlay _CPU_Context_Default_with_ISRs_disabled;
/*
* Which cpu are we? Used by libcpu and libbsp.
@@ -92,7 +92,7 @@ void _CPU_ISR_From_CPU_Init()
/*
* Block all the signals except SIGTRAP for the debugger
- * and SIGABRT for fatal errors.
+ * and fatal error signals.
*/
(void) sigfillset(&_CPU_Signal_mask);
@@ -100,6 +100,9 @@ void _CPU_ISR_From_CPU_Init()
(void) sigdelset(&_CPU_Signal_mask, SIGABRT);
(void) sigdelset(&_CPU_Signal_mask, SIGIOT);
(void) sigdelset(&_CPU_Signal_mask, SIGCONT);
+ (void) sigdelset(&_CPU_Signal_mask, SIGSEGV);
+ (void) sigdelset(&_CPU_Signal_mask, SIGBUS);
+ (void) sigdelset(&_CPU_Signal_mask, SIGFPE);
_CPU_ISR_Enable(1);
@@ -120,20 +123,16 @@ void _CPU_Signal_initialize( void )
{
struct sigaction act;
sigset_t mask;
-
+
/* mark them all active except for TraceTrap and Abort */
-
- sigfillset(&mask);
- sigdelset(&mask, SIGTRAP);
- sigdelset(&mask, SIGABRT);
- sigdelset(&mask, SIGIOT);
- sigdelset(&mask, SIGCONT);
+
+ mask = _CPU_Signal_mask;
sigprocmask(SIG_UNBLOCK, &mask, 0);
-
+
act.sa_handler = _CPU_ISR_Handler;
act.sa_mask = mask;
act.sa_flags = SA_RESTART;
-
+
sigaction(SIGHUP, &act, 0);
sigaction(SIGINT, &act, 0);
sigaction(SIGQUIT, &act, 0);
@@ -167,7 +166,6 @@ void _CPU_Signal_initialize( void )
#ifdef SIGLOST
sigaction(SIGLOST, &act, 0);
#endif
-
}
/*PAGE
@@ -209,14 +207,14 @@ void _CPU_Context_From_CPU_Init()
_CPU_ISR_Set_level( 0 );
_CPU_Context_switch(
- &_CPU_Context_Default_with_ISRs_enabled,
- &_CPU_Context_Default_with_ISRs_enabled
+ (Context_Control *) &_CPU_Context_Default_with_ISRs_enabled,
+ (Context_Control *) &_CPU_Context_Default_with_ISRs_enabled
);
-
+
_CPU_ISR_Set_level( 1 );
_CPU_Context_switch(
- &_CPU_Context_Default_with_ISRs_disabled,
- &_CPU_Context_Default_with_ISRs_disabled
+ (Context_Control *) &_CPU_Context_Default_with_ISRs_disabled,
+ (Context_Control *) &_CPU_Context_Default_with_ISRs_disabled
);
}
@@ -225,21 +223,16 @@ void _CPU_Context_From_CPU_Init()
* _CPU_ISR_Get_level
*/
-sigset_t GET_old_mask;
-
unsigned32 _CPU_ISR_Get_level( void )
{
-/* sigset_t old_mask; */
- unsigned32 old_level;
+ sigset_t old_mask;
- sigprocmask(0, 0, &GET_old_mask);
+ sigprocmask(SIG_BLOCK, 0, &old_mask);
- if (memcmp((void *)&posix_empty_mask, (void *)&GET_old_mask, sizeof(sigset_t)))
- old_level = 1;
- else
- old_level = 0;
-
- return old_level;
+ if (memcmp((void *)&posix_empty_mask, (void *)&old_mask, sizeof(sigset_t)))
+ return 1;
+
+ return 0;
}
/* _CPU_Initialize
@@ -361,8 +354,15 @@ void _CPU_Install_interrupt_stack( void )
void _CPU_Thread_Idle_body( void )
{
- while (1)
+ while (1) {
+#ifdef RTEMS_DEBUG
+ /* interrupts had better be enabled at this point! */
+ if (_CPU_ISR_Get_level() != 0)
+ abort();
+#endif
pause();
+ }
+
}
/*PAGE
@@ -379,7 +379,6 @@ void _CPU_Context_Initialize(
boolean _is_fp
)
{
- void *source;
unsigned32 *addr;
unsigned32 jmp_addr;
unsigned32 _stack_low; /* lowest "stack aligned" address */
@@ -410,16 +409,12 @@ void _CPU_Context_Initialize(
*/
if ( _new_level == 0 )
- source = &_CPU_Context_Default_with_ISRs_enabled;
+ *_the_context = *(Context_Control *)
+ &_CPU_Context_Default_with_ISRs_enabled;
else
- source = &_CPU_Context_Default_with_ISRs_disabled;
+ *_the_context = *(Context_Control *)
+ &_CPU_Context_Default_with_ISRs_disabled;
- memcpy(
- _the_context,
- source,
- sizeof(Context_Control) /* sizeof(jmp_buf)); */
- );
-
addr = (unsigned32 *)_the_context;
#if defined(hppa1_1)
@@ -492,7 +487,7 @@ void _CPU_Context_restore(
{
Context_Control_overlay *nextp = (Context_Control_overlay *)next;
- sigprocmask( SIG_SETMASK, &nextp->isr_level, 0 );
+ _CPU_ISR_Enable(nextp->isr_level);
longjmp( nextp->regs, 0 );
}
@@ -501,6 +496,11 @@ void _CPU_Context_restore(
* _CPU_Context_switch
*/
+static void do_jump(
+ Context_Control_overlay *currentp,
+ Context_Control_overlay *nextp
+);
+
void _CPU_Context_switch(
Context_Control *current,
Context_Control *next
@@ -508,33 +508,50 @@ void _CPU_Context_switch(
{
Context_Control_overlay *currentp = (Context_Control_overlay *)current;
Context_Control_overlay *nextp = (Context_Control_overlay *)next;
-
+#if 0
int status;
+#endif
+
+ currentp->isr_level = _CPU_ISR_Disable_support();
+
+ do_jump( currentp, nextp );
- /*
- * Switch levels in one operation
- */
-
- status = sigprocmask( SIG_SETMASK, &nextp->isr_level, &currentp->isr_level );
- if ( status )
- _Internal_error_Occurred(
- INTERNAL_ERROR_CORE,
- TRUE,
- status
- );
+#if 0
+ if (sigsetjmp(currentp->regs, 1) == 0) { /* Save the current context */
+ siglongjmp(nextp->regs, 0); /* Switch to the new context */
+ _Internal_error_Occurred(
+ INTERNAL_ERROR_CORE,
+ TRUE,
+ status
+ );
+ }
+#endif
+
+#ifdef RTEMS_DEBUG
+ if (_CPU_ISR_Get_level() == 0)
+ abort();
+#endif
+
+ _CPU_ISR_Enable(currentp->isr_level);
+}
+
+static void do_jump(
+ Context_Control_overlay *currentp,
+ Context_Control_overlay *nextp
+)
+{
+ int status;
if (setjmp(currentp->regs) == 0) { /* Save the current context */
longjmp(nextp->regs, 0); /* Switch to the new context */
- if ( status )
- _Internal_error_Occurred(
+ _Internal_error_Occurred(
INTERNAL_ERROR_CORE,
TRUE,
status
);
}
-
}
-
+
/*PAGE
*
* _CPU_Save_float_context
@@ -714,6 +731,7 @@ void _CPU_Stray_signal(int sig_num)
case SIGBUS:
case SIGSEGV:
case SIGTERM:
+ case SIGIOT:
_CPU_Fatal_error(0x100 + sig_num);
}
}