summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>1995-08-11 14:27:23 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>1995-08-11 14:27:23 +0000
commitaa9f19454a6912a337752fee5e0f98414de3e8a5 (patch)
tree19f558b8763cda168b1ea2d047c0270297147c2f
parentclean up -- interrupt support is in place (diff)
downloadrtems-aa9f19454a6912a337752fee5e0f98414de3e8a5.tar.bz2
Initialization of semaphores was incorrect. It did not force
the count to "1" to indicate availability. Interrupt support was added. Problem where newlib's errno "overrides" that set by system calls was addressed. Fixed bug which resulted in all nodes using the same semaphore although an array of semaphores was allocated.
-rw-r--r--c/src/lib/libbsp/unix/posix/shmsupp/getcfg.c110
-rw-r--r--c/src/lib/libbsp/unix/posix/shmsupp/intr.c7
-rw-r--r--c/src/lib/libbsp/unix/posix/shmsupp/lock.c35
-rw-r--r--c/src/lib/libbsp/unix/posix/shmsupp/mpisr.c2
4 files changed, 98 insertions, 56 deletions
diff --git a/c/src/lib/libbsp/unix/posix/shmsupp/getcfg.c b/c/src/lib/libbsp/unix/posix/shmsupp/getcfg.c
index bd9c2e653d..b66e3c2287 100644
--- a/c/src/lib/libbsp/unix/posix/shmsupp/getcfg.c
+++ b/c/src/lib/libbsp/unix/posix/shmsupp/getcfg.c
@@ -11,17 +11,8 @@
* OUTPUT PARAMETERS:
* *shmcfg - pointer to SHM Config Table
*
- * NOTES: The MP interrupt used is the Runway bus' ability to directly
- * address the control registers of up to four CPUs and cause
- * interrupts on them.
- *
- * The following table illustrates the configuration limitations:
- *
- * BUS MAX
- * MODE ENDIAN NODES
- * ========= ====== =======
- * POLLED BIG 2+
- * INTERRUPT BIG 2..4
+ * NOTES: This driver is capable of supporting a practically unlimited
+ * number of nodes.
*
* COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
* On-Line Applications Research Corporation (OAR).
@@ -43,13 +34,11 @@
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
+#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
-#define INTERRUPT 0 /* can be interrupt or polling */
-#define POLLING 1
-
shm_config_table BSP_shm_cfgtbl;
int semid;
@@ -58,58 +47,103 @@ void Shm_Cause_interrupt_unix(
rtems_unsigned32 node
);
-void Shm_Get_configuration(
- rtems_unsigned32 localnode,
- shm_config_table **shmcfg
-)
+void fix_semaphores( void )
{
rtems_unsigned32 maximum_nodes;
int i;
+
int shmid;
char *shm_addr;
key_t shm_key;
key_t sem_key;
- struct sembuf sb;
int status;
+ int shm_size;
- shm_key = 0xa000;
+ 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 * KILOBYTE;
+#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, 16 * KILOBYTE, IPC_CREAT | 0660);
+ shmid = shmget(shm_key, shm_size, IPC_CREAT | 0660);
if ( shmid == -1 ) {
+ fix_syscall_errno(); /* in case of newlib */
perror( "shmget" );
- exit( 0 );
+ rtems_fatal_error_occurred(RTEMS_UNSATISFIED);
}
shm_addr = shmat(shmid, (char *)0, SHM_RND);
if ( shm_addr == (void *)-1 ) {
+ fix_syscall_errno(); /* in case of newlib */
perror( "shmat" );
- exit( 0 );
+ rtems_fatal_error_occurred(RTEMS_UNSATISFIED);
}
- sem_key = 0xa001;
-
maximum_nodes = Shm_RTEMS_MP_Configuration->maximum_nodes;
semid = semget(sem_key, maximum_nodes + 1, IPC_CREAT | 0660);
if ( semid == -1 ) {
+ fix_syscall_errno(); /* in case of newlib */
perror( "semget" );
- exit( 0 );
+ rtems_fatal_error_occurred(RTEMS_UNSATISFIED);
}
if ( Shm_Is_master_node() ) {
for ( i=0 ; i <= maximum_nodes ; i++ ) {
- sb.sem_op = 1;
- sb.sem_num = i;
- sb.sem_flg = 0;
- status = semop( semid, &sb, 1 );
+
+#if defined(solaris2)
+ union semun {
+ int val;
+ struct semid_ds *buf;
+ ushort *array;
+ } help;
+
+ help.val = 1;
+ semctl( semid, i, SETVAL, help );
+#endif
+#if defined(hpux)
+ semctl( semid, i, SETVAL, 1 );
+#endif
+
+ fix_syscall_errno(); /* in case of newlib */
if ( status == -1 ) {
fprintf( stderr, "Sem init failed %d\n", errno ); fflush( stderr );
- exit( 0 );
+ rtems_fatal_error_occurred(RTEMS_UNSATISFIED);
}
}
}
BSP_shm_cfgtbl.base = (vol_u32 *)shm_addr;
- BSP_shm_cfgtbl.length = 16 * KILOBYTE;
+ BSP_shm_cfgtbl.length = shm_size;
+}
+
+void Shm_Get_configuration(
+ rtems_unsigned32 localnode,
+ shm_config_table **shmcfg
+)
+{
+ fix_semaphores();
+
BSP_shm_cfgtbl.format = SHM_BIG;
BSP_shm_cfgtbl.cause_intr = Shm_Cause_interrupt_unix;
@@ -120,16 +154,16 @@ void Shm_Get_configuration(
BSP_shm_cfgtbl.convert = CPU_swap_u32;
#endif
-#if ( POLLING == 1 )
+#ifdef INTERRUPT_EXTERNAL_MPCI
+ BSP_shm_cfgtbl.poll_intr = INTR_MODE;
+ BSP_shm_cfgtbl.Intr.address = (vol_u32 *) getpid(); /* process id */
+ BSP_shm_cfgtbl.Intr.value = INTERRUPT_EXTERNAL_MPCI; /* signal to send */
+ BSP_shm_cfgtbl.Intr.length = LONG;
+#else
BSP_shm_cfgtbl.poll_intr = POLLED_MODE;
BSP_shm_cfgtbl.Intr.address = NO_INTERRUPT;
BSP_shm_cfgtbl.Intr.value = NO_INTERRUPT;
BSP_shm_cfgtbl.Intr.length = NO_INTERRUPT;
-#else
- BSP_shm_cfgtbl.poll_intr = INTR_MODE;
- BSP_shm_cfgtbl.Intr.address = 0; /* process id? */
- BSP_shm_cfgtbl.Intr.value = 0; /* signal to send? */
- BSP_shm_cfgtbl.Intr.length = LONG;
#endif
*shmcfg = &BSP_shm_cfgtbl;
diff --git a/c/src/lib/libbsp/unix/posix/shmsupp/intr.c b/c/src/lib/libbsp/unix/posix/shmsupp/intr.c
index 44259479db..2f8cd6db11 100644
--- a/c/src/lib/libbsp/unix/posix/shmsupp/intr.c
+++ b/c/src/lib/libbsp/unix/posix/shmsupp/intr.c
@@ -23,9 +23,14 @@
#include <shm.h>
#include <stdio.h>
-
+#include <signal.h>
+
void Shm_Cause_interrupt_unix(
rtems_unsigned32 node
)
{
+ Shm_Interrupt_information *intr;
+ intr = &Shm_Interrupt_table[node];
+
+ kill((pid_t) intr->address, intr->value);
}
diff --git a/c/src/lib/libbsp/unix/posix/shmsupp/lock.c b/c/src/lib/libbsp/unix/posix/shmsupp/lock.c
index 9376b6d5e8..0dd0cbd8b3 100644
--- a/c/src/lib/libbsp/unix/posix/shmsupp/lock.c
+++ b/c/src/lib/libbsp/unix/posix/shmsupp/lock.c
@@ -41,8 +41,7 @@ void Shm_Initialize_lock(
Shm_Locked_queue_Control *lq_cb
)
{
- lq_cb->lock =
- ( lq_cb - Shm_Locked_queues ) / sizeof( Shm_Locked_queue_Control );
+ lq_cb->lock = lq_cb - Shm_Locked_queues;
}
/* Shm_Lock( &lq_cb )
@@ -60,24 +59,25 @@ void Shm_Lock(
struct sembuf sb;
int status;
- isr_level = 0;
-
sb.sem_num = lq_cb->lock;
sb.sem_op = -1;
sb.sem_flg = 0;
+
rtems_interrupt_disable( isr_level );
Shm_isrstat = isr_level;
while (1) {
status = semop(semid, &sb, 1);
- if ( status == 0 )
+ if ( status >= 0 )
break;
- if ( status == -1 && errno == EINTR )
- continue;
-
- fprintf( stderr, "shm lock(%d %d)\n", status, errno );
- exit( 0 );
+ if ( status == -1 ) {
+ fix_syscall_errno(); /* in case of newlib */
+ if (errno == EINTR)
+ continue;
+ perror("shm lock");
+ rtems_fatal_error_occurred(RTEMS_UNSATISFIED);
+ }
}
}
@@ -95,21 +95,22 @@ void Shm_Unlock(
struct sembuf sb;
int status;
- isr_level = 0;
-
sb.sem_num = lq_cb->lock;
sb.sem_op = 1;
sb.sem_flg = 0;
while (1) {
status = semop(semid, &sb, 1);
- if ( status == 0 )
+ if ( status >= 0 )
break;
- if ( status == -1 && errno == EINTR )
- continue;
- fprintf( stderr, "shm unlock(%d %d)\n", status, errno );
- exit( 0 );
+ if ( status == -1 ) {
+ fix_syscall_errno(); /* in case of newlib */
+ if (errno == EINTR)
+ continue;
+ perror("shm unlock");
+ rtems_fatal_error_occurred(RTEMS_UNSATISFIED);
+ }
}
isr_level = Shm_isrstat;
diff --git a/c/src/lib/libbsp/unix/posix/shmsupp/mpisr.c b/c/src/lib/libbsp/unix/posix/shmsupp/mpisr.c
index 02bee168a6..ff24bfa31c 100644
--- a/c/src/lib/libbsp/unix/posix/shmsupp/mpisr.c
+++ b/c/src/lib/libbsp/unix/posix/shmsupp/mpisr.c
@@ -25,5 +25,7 @@
void Shm_setvec( void )
{
+#ifdef INTERRUPT_EXTERNAL_MPCI
set_vector( Shm_isr, INTERRUPT_EXTERNAL_MPCI, 1 );
+#endif
}