summaryrefslogtreecommitdiffstats
path: root/cpukit
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>1995-09-27 20:53:58 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>1995-09-27 20:53:58 +0000
commit37f4c2d99fbf09142aeafe3a9908a81e283f8186 (patch)
tree04dc487b28113dc17f1c3c9ab2241390b4ed95ea /cpukit
parentFixed typo (diff)
downloadrtems-37f4c2d99fbf09142aeafe3a9908a81e283f8186.tar.bz2
Modified UNIX simulator port so all references to native unix
stuff is in the executive source proper in the file cpu.c. This should help avoid conflicts between RTEMS POSIX files and UNIX files.
Diffstat (limited to '')
-rw-r--r--cpukit/score/cpu/unix/cpu.c304
1 files changed, 291 insertions, 13 deletions
diff --git a/cpukit/score/cpu/unix/cpu.c b/cpukit/score/cpu/unix/cpu.c
index daff56a1de..54d4104ac7 100644
--- a/cpukit/score/cpu/unix/cpu.c
+++ b/cpukit/score/cpu/unix/cpu.c
@@ -20,16 +20,39 @@
#include <rtems/score/isr.h>
#include <rtems/score/interr.h>
+#if defined(solaris2)
+#undef _POSIX_C_SOURCE
+#define _POSIX_C_SOURCE 3
+#undef __STRICT_ANSI__
+#define __STRICT_ANSI__
+#endif
+
+#if defined(linux)
+#define MALLOC_0_RETURNS_NULL
+#endif
+
#include <stdio.h>
#include <stdlib.h>
+#include <setjmp.h>
#include <signal.h>
#include <time.h>
#include <sys/time.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include <sys/sem.h>
#ifndef SA_RESTART
#define SA_RESTART 0
#endif
+typedef struct {
+ jmp_buf regs;
+ sigset_t isr_level;
+} Context_Control_overlay;
+
void _CPU_Signal_initialize(void);
void _CPU_Stray_signal(int);
void _CPU_ISR_Handler(int);
@@ -375,9 +398,9 @@ void _CPU_Context_Initialize(
*/
if ( _new_level == 0 )
- source = _CPU_Context_Default_with_ISRs_enabled.regs;
+ source = &_CPU_Context_Default_with_ISRs_enabled;
else
- source = _CPU_Context_Default_with_ISRs_disabled.regs;
+ source = &_CPU_Context_Default_with_ISRs_disabled;
memcpy(_the_context, source, sizeof(Context_Control) ); /* sizeof(jmp_buf)); */
@@ -452,8 +475,10 @@ void _CPU_Context_restore(
Context_Control *next
)
{
- sigprocmask( SIG_SETMASK, &next->isr_level, 0 );
- longjmp( next->regs, 0 );
+ Context_Control_overlay *nextp = (Context_Control_overlay *)next;
+
+ sigprocmask( SIG_SETMASK, &nextp->isr_level, 0 );
+ longjmp( nextp->regs, 0 );
}
/*PAGE
@@ -466,13 +491,16 @@ void _CPU_Context_switch(
Context_Control *next
)
{
+ Context_Control_overlay *currentp = (Context_Control_overlay *)current;
+ Context_Control_overlay *nextp = (Context_Control_overlay *)next;
+
int status;
/*
* Switch levels in one operation
*/
- status = sigprocmask( SIG_SETMASK, &next->isr_level, &current->isr_level );
+ status = sigprocmask( SIG_SETMASK, &nextp->isr_level, &currentp->isr_level );
if ( status )
_Internal_error_Occurred(
INTERNAL_ERROR_CORE,
@@ -480,8 +508,8 @@ void _CPU_Context_switch(
status
);
- if (setjmp(current->regs) == 0) { /* Save the current context */
- longjmp(next->regs, 0); /* Switch to the new context */
+ 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_CORE,
@@ -610,18 +638,19 @@ void _CPU_ISR_Handler(int vector)
void _CPU_Stray_signal(int sig_num)
{
- char buffer[ 80 ];
+ char buffer[ 4 ];
/*
* We avoid using the stdio section of the library.
* The following is generally safe.
*/
- write(
- 2,
- buffer,
- sprintf( buffer, "Stray signal %d\n", sig_num )
- );
+ buffer[ 0 ] = (sig_num >> 4) + 0x30;
+ buffer[ 1 ] = (sig_num & 0xf) + 0x30;
+ buffer[ 2 ] = '\n';
+
+ write( 2, "Stray signal 0x", 12 );
+ write( 2, buffer, 3 );
/*
* If it was a "fatal" signal, then exit here
@@ -680,3 +709,252 @@ int _CPU_ffs(unsigned32 value)
return output;
}
+
+
+/*
+ * Special Purpose Routines to hide the use of UNIX system calls.
+ */
+
+#if 0
+/* XXX clock had this set of #define's */
+
+/*
+ * In order to get the types and prototypes used in this file under
+ * Solaris 2.3, it is necessary to pull the following magic.
+ */
+
+#if defined(solaris)
+#warning "Ignore the undefining __STDC__ warning"
+#undef __STDC__
+#define __STDC__ 0
+#undef _POSIX_C_SOURCE
+#endif
+#endif
+
+int _CPU_Get_clock_vector( void )
+{
+ return SIGALRM;
+}
+
+
+void _CPU_Start_clock(
+ int microseconds
+)
+{
+ struct itimerval new;
+
+ new.it_value.tv_sec = 0;
+ new.it_value.tv_usec = microseconds;
+ new.it_interval.tv_sec = 0;
+ new.it_interval.tv_usec = microseconds;
+
+ setitimer(ITIMER_REAL, &new, 0);
+}
+
+void _CPU_Stop_clock( void )
+{
+ struct itimerval new;
+ struct sigaction act;
+
+ /*
+ * Set the SIGALRM signal to ignore any last
+ * signals that might come in while we are
+ * disarming the timer and removing the interrupt
+ * vector.
+ */
+
+ act.sa_handler = SIG_IGN;
+
+ sigaction(SIGALRM, &act, 0);
+
+ new.it_value.tv_sec = 0;
+ new.it_value.tv_usec = 0;
+
+ setitimer(ITIMER_REAL, &new, 0);
+}
+
+int _CPU_SHM_Semid;
+extern void fix_syscall_errno( void );
+
+void _CPU_SHM_Init(
+ unsigned32 maximum_nodes,
+ boolean is_master_node,
+ void **shm_address,
+ unsigned32 *shm_length
+)
+{
+ int i;
+ int shmid;
+ char *shm_addr;
+ key_t shm_key;
+ key_t sem_key;
+ int status;
+ int shm_size;
+
+ if (getenv("RTEMS_SHM_KEY"))
+ shm_key = strtol(getenv("RTEMS_SHM_KEY"), 0, 0);
+ else
+#ifdef RTEMS_SHM_KEY
+ shm_key = RTEMS_SHM_KEY;
+#else
+ shm_key = 0xa000;
+#endif
+
+ if (getenv("RTEMS_SHM_SIZE"))
+ shm_size = strtol(getenv("RTEMS_SHM_SIZE"), 0, 0);
+ else
+#ifdef RTEMS_SHM_SIZE
+ shm_size = RTEMS_SHM_SIZE;
+#else
+ shm_size = 64 * 1024;
+#endif
+
+ if (getenv("RTEMS_SHM_SEMAPHORE_KEY"))
+ sem_key = strtol(getenv("RTEMS_SHM_SEMAPHORE_KEY"), 0, 0);
+ else
+#ifdef RTEMS_SHM_SEMAPHORE_KEY
+ sem_key = RTEMS_SHM_SEMAPHORE_KEY;
+#else
+ sem_key = 0xa001;
+#endif
+
+ shmid = shmget(shm_key, shm_size, IPC_CREAT | 0660);
+ if ( shmid == -1 ) {
+ fix_syscall_errno(); /* in case of newlib */
+ perror( "shmget" );
+ _CPU_Fatal_halt( 0xdead0001 );
+ }
+
+ shm_addr = shmat(shmid, (char *)0, SHM_RND);
+ if ( shm_addr == (void *)-1 ) {
+ fix_syscall_errno(); /* in case of newlib */
+ perror( "shmat" );
+ _CPU_Fatal_halt( 0xdead0002 );
+ }
+
+ _CPU_SHM_Semid = semget(sem_key, maximum_nodes + 1, IPC_CREAT | 0660);
+ if ( _CPU_SHM_Semid == -1 ) {
+ fix_syscall_errno(); /* in case of newlib */
+ perror( "semget" );
+ _CPU_Fatal_halt( 0xdead0003 );
+ }
+
+ if ( is_master_node ) {
+ for ( i=0 ; i <= maximum_nodes ; i++ ) {
+#if defined(solaris2)
+ union semun {
+ int val;
+ struct semid_ds *buf;
+ ushort *array;
+ } help;
+
+ help.val = 1;
+ status = semctl( _CPU_SHM_Semid, i, SETVAL, help );
+#endif
+#if defined(hpux)
+ status = semctl( _CPU_SHM_Semid, i, SETVAL, 1 );
+#endif
+
+ fix_syscall_errno(); /* in case of newlib */
+ if ( status == -1 ) {
+ _CPU_Fatal_halt( 0xdead0004 );
+ }
+ }
+ }
+
+ *shm_address = shm_addr;
+ *shm_length = shm_size;
+
+}
+
+int _CPU_Get_pid( void )
+{
+ return getpid();
+}
+
+/*
+ * Define this to use signals for MPCI shared memory driver.
+ * If undefined, the shared memory driver will poll from the
+ * clock interrupt.
+ * Ref: ../shmsupp/getcfg.c
+ *
+ * BEWARE:: many UN*X kernels and debuggers become severely confused when
+ * debugging programs which use signals. The problem is *much*
+ * worse when using multiple signals, since ptrace(2) tends to
+ * drop all signals except 1 in the case of multiples.
+ * On hpux9, this problem was so bad, we couldn't use interrupts
+ * with the shared memory driver if we ever hoped to debug
+ * RTEMS programs.
+ * Maybe systems that use /proc don't have this problem...
+ */
+
+
+int _CPU_SHM_Get_vector( void )
+{
+#ifdef CPU_USE_SHM_INTERRUPTS
+ return SIGUSR1;
+#else
+ return 0;
+#endif
+}
+
+void _CPU_SHM_Send_interrupt(
+ int pid,
+ int vector
+)
+{
+ kill((pid_t) pid, vector);
+}
+
+void _CPU_SHM_Lock(
+ int semaphore
+)
+{
+ struct sembuf sb;
+ int status;
+
+ sb.sem_num = semaphore;
+ sb.sem_op = -1;
+ sb.sem_flg = 0;
+
+ while (1) {
+ status = semop(_CPU_SHM_Semid, &sb, 1);
+ if ( status >= 0 )
+ break;
+ if ( status == -1 ) {
+ fix_syscall_errno(); /* in case of newlib */
+ if (errno == EINTR)
+ continue;
+ perror("shm lock");
+ _CPU_Fatal_halt( 0xdead0005 );
+ }
+ }
+
+}
+
+void _CPU_SHM_Unlock(
+ int semaphore
+)
+{
+ struct sembuf sb;
+ int status;
+
+ sb.sem_num = semaphore;
+ sb.sem_op = 1;
+ sb.sem_flg = 0;
+
+ while (1) {
+ status = semop(_CPU_SHM_Semid, &sb, 1);
+ if ( status >= 0 )
+ break;
+
+ if ( status == -1 ) {
+ fix_syscall_errno(); /* in case of newlib */
+ if (errno == EINTR)
+ continue;
+ perror("shm unlock");
+ _CPU_Fatal_halt( 0xdead0006 );
+ }
+ }
+
+}