source: rtems/cpukit/score/cpu/unix/cpu.c @ cc4c1fe4

4.104.114.84.95
Last change on this file since cc4c1fe4 was cc4c1fe4, checked in by Joel Sherrill <joel.sherrill@…>, on 04/22/96 at 16:44:54

added stack allocation fields to the cpu table

updates from Tony Bennett. Most were to insure all variables were properly
initialized and to correct the stray signal number reporting.

  • Property mode set to 100644
File size: 20.0 KB
Line 
1/*
2 *  UNIX Simulator Dependent Source
3 *
4 *
5 *  To anyone who acknowledges that this file is provided "AS IS"
6 *  without any express or implied warranty:
7 *      permission to use, copy, modify, and distribute this file
8 *      for any purpose is hereby granted without fee, provided that
9 *      the above copyright notice and this notice appears in all
10 *      copies, and that the name of Division Incorporated not be
11 *      used in advertising or publicity pertaining to distribution
12 *      of the software without specific, written prior permission.
13 *      Division Incorporated makes no representations about the
14 *      suitability of this software for any purpose.
15 *
16 *  $Id$
17 */
18
19#include <rtems/system.h>
20#include <rtems/score/isr.h>
21#include <rtems/score/interr.h>
22
23#if defined(solaris2)
24/*
25#undef  _POSIX_C_SOURCE
26#define _POSIX_C_SOURCE 3
27#undef  __STRICT_ANSI__
28#define __STRICT_ANSI__
29*/
30#define __EXTENSIONS__
31#endif
32 
33#if defined(linux)
34#define MALLOC_0_RETURNS_NULL
35#endif
36 
37#include <stdio.h>
38#include <stdlib.h>
39#include <setjmp.h>
40#include <signal.h>
41#include <time.h>
42#include <sys/time.h>
43#include <sys/types.h>
44#include <errno.h>
45#include <unistd.h>
46#include <sys/ipc.h>
47#include <sys/shm.h>
48#include <sys/sem.h>
49#include <string.h>   /* memset */
50
51#ifndef SA_RESTART
52#define SA_RESTART 0
53#endif
54
55typedef struct {
56  jmp_buf   regs;
57  sigset_t  isr_level;
58} Context_Control_overlay;
59
60void  _CPU_Signal_initialize(void);
61void  _CPU_Stray_signal(int);
62void  _CPU_ISR_Handler(int);
63
64sigset_t         _CPU_Signal_mask;
65Context_Control  _CPU_Context_Default_with_ISRs_enabled;
66Context_Control  _CPU_Context_Default_with_ISRs_disabled;
67
68/*
69 * Which cpu are we? Used by libcpu and libbsp.
70 */
71
72int cpu_number;
73
74/*PAGE
75 *
76 *  _CPU_ISR_From_CPU_Init
77 */
78
79sigset_t  posix_empty_mask;
80
81void _CPU_ISR_From_CPU_Init()
82{
83  unsigned32        i;
84  proc_ptr          old_handler;
85
86  /*
87   * Generate an empty mask to be used by disable_support
88   */
89
90  sigemptyset(&posix_empty_mask);
91
92  /*
93   * Block all the signals except SIGTRAP for the debugger
94   * and SIGABRT for fatal errors.
95   */
96
97  (void) sigfillset(&_CPU_Signal_mask);
98  (void) sigdelset(&_CPU_Signal_mask, SIGTRAP);
99  (void) sigdelset(&_CPU_Signal_mask, SIGABRT);
100  (void) sigdelset(&_CPU_Signal_mask, SIGIOT);
101  (void) sigdelset(&_CPU_Signal_mask, SIGCONT);
102
103  _CPU_ISR_Enable(1);
104
105  /*
106   * Set the handler for all signals to be signal_handler
107   * which will then vector out to the correct handler
108   * for whichever signal actually happened. Initially
109   * set the vectors to the stray signal handler.
110   */
111
112  for (i = 0; i < CPU_INTERRUPT_NUMBER_OF_VECTORS; i++)
113      (void)_CPU_ISR_install_vector(i, _CPU_Stray_signal, &old_handler);
114
115  _CPU_Signal_initialize();
116}
117
118void _CPU_Signal_initialize( void )
119{
120  struct sigaction  act;
121  sigset_t          mask;
122
123  /* mark them all active except for TraceTrap  and Abort */
124
125  sigfillset(&mask);
126  sigdelset(&mask, SIGTRAP);
127  sigdelset(&mask, SIGABRT);
128  sigdelset(&mask, SIGIOT);
129  sigdelset(&mask, SIGCONT);
130  sigprocmask(SIG_UNBLOCK, &mask, 0);
131
132  act.sa_handler = _CPU_ISR_Handler;
133  act.sa_mask = mask;
134  act.sa_flags = SA_RESTART;
135
136  sigaction(SIGHUP, &act, 0);
137  sigaction(SIGINT, &act, 0);
138  sigaction(SIGQUIT, &act, 0);
139  sigaction(SIGILL, &act, 0);
140#ifdef SIGEMT
141  sigaction(SIGEMT, &act, 0);
142#endif
143  sigaction(SIGFPE, &act, 0);
144  sigaction(SIGKILL, &act, 0);
145  sigaction(SIGBUS, &act, 0);
146  sigaction(SIGSEGV, &act, 0);
147#ifdef SIGSYS
148  sigaction(SIGSYS, &act, 0);
149#endif
150  sigaction(SIGPIPE, &act, 0);
151  sigaction(SIGALRM, &act, 0);
152  sigaction(SIGTERM, &act, 0);
153  sigaction(SIGUSR1, &act, 0);
154  sigaction(SIGUSR2, &act, 0);
155  sigaction(SIGCHLD, &act, 0);
156  sigaction(SIGCLD, &act, 0);
157  sigaction(SIGPWR, &act, 0);
158  sigaction(SIGVTALRM, &act, 0);
159  sigaction(SIGPROF, &act, 0);
160  sigaction(SIGIO, &act, 0);
161  sigaction(SIGWINCH, &act, 0);
162  sigaction(SIGSTOP, &act, 0);
163  sigaction(SIGTTIN, &act, 0);
164  sigaction(SIGTTOU, &act, 0);
165  sigaction(SIGURG, &act, 0);
166#ifdef SIGLOST
167    sigaction(SIGLOST, &act, 0);
168#endif
169
170}
171
172/*PAGE
173 *
174 *  _CPU_Context_From_CPU_Init
175 */
176
177void _CPU_Context_From_CPU_Init()
178{
179
180#if defined(hppa1_1) && defined(RTEMS_UNIXLIB_SETJMP)
181    /*
182     * HACK - set the _SYSTEM_ID to 0x20c so that setjmp/longjmp
183     * will handle the full 32 floating point registers.
184     */
185
186    {
187      extern unsigned32 _SYSTEM_ID;
188
189      _SYSTEM_ID = 0x20c;
190    }
191#endif
192
193  /*
194   *  get default values to use in _CPU_Context_Initialize()
195   */
196
197 
198  (void) memset(
199    &_CPU_Context_Default_with_ISRs_enabled,
200    0,
201    sizeof(Context_Control)
202  );
203  (void) memset(
204    &_CPU_Context_Default_with_ISRs_disabled,
205    0,
206    sizeof(Context_Control)
207  );
208
209  _CPU_ISR_Set_level( 0 );
210  _CPU_Context_switch(
211    &_CPU_Context_Default_with_ISRs_enabled,
212    &_CPU_Context_Default_with_ISRs_enabled
213  );
214
215  _CPU_ISR_Set_level( 1 );
216  _CPU_Context_switch(
217    &_CPU_Context_Default_with_ISRs_disabled,
218    &_CPU_Context_Default_with_ISRs_disabled
219  );
220}
221
222/*PAGE
223 *
224 *  _CPU_ISR_Get_level
225 */
226
227sigset_t GET_old_mask;
228
229unsigned32 _CPU_ISR_Get_level( void )
230{
231/*  sigset_t  old_mask; */
232   unsigned32 old_level;
233 
234  sigprocmask(0, 0, &GET_old_mask);
235 
236  if (memcmp((void *)&posix_empty_mask, (void *)&GET_old_mask, sizeof(sigset_t)))
237    old_level = 1;
238  else
239    old_level = 0;
240
241  return old_level;
242}
243
244/*  _CPU_Initialize
245 *
246 *  This routine performs processor dependent initialization.
247 *
248 *  INPUT PARAMETERS:
249 *    cpu_table       - CPU table to initialize
250 *    thread_dispatch - address of disptaching routine
251 */
252
253
254void _CPU_Initialize(
255  rtems_cpu_table  *cpu_table,
256  void            (*thread_dispatch)      /* ignored on this CPU */
257)
258{
259  /*
260   *  The thread_dispatch argument is the address of the entry point
261   *  for the routine called at the end of an ISR once it has been
262   *  decided a context switch is necessary.  On some compilation
263   *  systems it is difficult to call a high-level language routine
264   *  from assembly.  This allows us to trick these systems.
265   *
266   *  If you encounter this problem save the entry point in a CPU
267   *  dependent variable.
268   */
269
270  _CPU_Thread_dispatch_pointer = thread_dispatch;
271
272  /*
273   * XXX; If there is not an easy way to initialize the FP context
274   *      during Context_Initialize, then it is usually easier to
275   *      save an "uninitialized" FP context here and copy it to
276   *      the task's during Context_Initialize.
277   */
278
279  /* XXX: FP context initialization support */
280
281  _CPU_Table = *cpu_table;
282
283  _CPU_ISR_From_CPU_Init();
284
285  _CPU_Context_From_CPU_Init();
286
287}
288
289/*PAGE
290 *
291 *  _CPU_ISR_install_raw_handler
292 */
293
294void _CPU_ISR_install_raw_handler(
295  unsigned32  vector,
296  proc_ptr    new_handler,
297  proc_ptr   *old_handler
298)
299{
300  _CPU_Fatal_halt( 0xdeaddead );
301}
302
303/*PAGE
304 *
305 *  _CPU_ISR_install_vector
306 *
307 *  This kernel routine installs the RTEMS handler for the
308 *  specified vector.
309 *
310 *  Input parameters:
311 *    vector      - interrupt vector number
312 *    old_handler - former ISR for this vector number
313 *    new_handler - replacement ISR for this vector number
314 *
315 *  Output parameters:  NONE
316 *
317 */
318
319
320void _CPU_ISR_install_vector(
321  unsigned32  vector,
322  proc_ptr    new_handler,
323  proc_ptr   *old_handler
324)
325{
326   *old_handler = _ISR_Vector_table[ vector ];
327
328   /*
329    *  If the interrupt vector table is a table of pointer to isr entry
330    *  points, then we need to install the appropriate RTEMS interrupt
331    *  handler for this vector number.
332    */
333
334   /*
335    *  We put the actual user ISR address in '_ISR_vector_table'.  This will
336    *  be used by the _CPU_ISR_Handler so the user gets control.
337    */
338
339    _ISR_Vector_table[ vector ] = new_handler;
340}
341
342/*PAGE
343 *
344 *  _CPU_Install_interrupt_stack
345 */
346
347void _CPU_Install_interrupt_stack( void )
348{
349}
350
351/*PAGE
352 *
353 *  _CPU_Thread_Idle_body
354 *
355 *  Stop until we get a signal which is the logically the same thing
356 *  entering low-power or sleep mode on a real processor and waiting for
357 *  an interrupt.  This significantly reduces the consumption of host
358 *  CPU cycles which is again similar to low power mode.
359 */
360
361void _CPU_Thread_Idle_body( void )
362{
363  while (1)
364    pause();
365}
366
367/*PAGE
368 *
369 *  _CPU_Context_Initialize
370 */
371
372void _CPU_Context_Initialize(
373  Context_Control  *_the_context,
374  unsigned32       *_stack_base,
375  unsigned32        _size,
376  unsigned32        _new_level,
377  void             *_entry_point,
378  boolean           _is_fp
379)
380{
381  void        *source;
382  unsigned32  *addr;
383  unsigned32   jmp_addr;
384  unsigned32   _stack_low;   /* lowest "stack aligned" address */
385  unsigned32   _stack_high;  /* highest "stack aligned" address */
386  unsigned32   _the_size;
387
388  jmp_addr = (unsigned32) _entry_point;
389
390  /*
391   *  On CPUs with stacks which grow down, we build the stack
392   *  based on the _stack_high address.  On CPUs with stacks which
393   *  grow up, we build the stack based on the _stack_low address. 
394   */
395
396  _stack_low = (unsigned32)(_stack_base) + CPU_STACK_ALIGNMENT - 1;
397  _stack_low &= ~(CPU_STACK_ALIGNMENT - 1);
398
399  _stack_high = (unsigned32)(_stack_base) + _size;
400  _stack_high &= ~(CPU_STACK_ALIGNMENT - 1);
401
402  if (_stack_high > _stack_low)
403    _the_size = _stack_high - _stack_low;
404  else
405    _the_size = _stack_low - _stack_high;
406
407  /*
408   * Slam our jmp_buf template into the context we are creating
409   */
410
411  if ( _new_level == 0 )
412    source = &_CPU_Context_Default_with_ISRs_enabled;
413  else
414    source = &_CPU_Context_Default_with_ISRs_disabled;
415     
416  memcpy(
417    _the_context,
418    source,
419    sizeof(Context_Control)                /* sizeof(jmp_buf)); */
420  );
421
422  addr = (unsigned32 *)_the_context;
423
424#if defined(hppa1_1)
425  *(addr + RP_OFF) = jmp_addr;
426  *(addr + SP_OFF) = (unsigned32)(_stack_low + CPU_FRAME_SIZE);
427
428  /*
429   * See if we are using shared libraries by checking
430   * bit 30 in 24 off of newp. If bit 30 is set then
431   * we are using shared libraries and the jump address
432   * points to the pointer, so we put that into rp instead.
433   */
434
435  if (jmp_addr & 0x40000000) {
436    jmp_addr &= 0xfffffffc;
437     *(addr + RP_OFF) = *(unsigned32 *)jmp_addr;
438  }
439#elif defined(sparc)
440
441  /*
442   *  See /usr/include/sys/stack.h in Solaris 2.3 for a nice
443   *  diagram of the stack.
444   */
445
446  asm ("ta  0x03");            /* flush registers */
447
448  *(addr + RP_OFF) = jmp_addr + ADDR_ADJ_OFFSET;
449  *(addr + SP_OFF) = (unsigned32)(_stack_high - CPU_FRAME_SIZE);
450  *(addr + FP_OFF) = (unsigned32)(_stack_high);
451
452#elif defined(i386)
453 
454    /*
455     *  This information was gathered by disassembling setjmp().
456     */
457
458    {
459      unsigned32 stack_ptr;
460
461      stack_ptr = _stack_high - CPU_FRAME_SIZE;
462
463      *(addr + EBX_OFF) = 0xFEEDFEED;
464      *(addr + ESI_OFF) = 0xDEADDEAD;
465      *(addr + EDI_OFF) = 0xDEAFDEAF;
466      *(addr + EBP_OFF) = stack_ptr;
467      *(addr + ESP_OFF) = stack_ptr;
468      *(addr + RET_OFF) = jmp_addr;
469 
470      addr = (unsigned32 *) stack_ptr;
471 
472      addr[ 0 ] = jmp_addr;
473      addr[ 1 ] = (unsigned32) stack_ptr;
474      addr[ 2 ] = (unsigned32) stack_ptr;
475    }
476
477#else
478#error "UNKNOWN CPU!!!"
479#endif
480
481}
482
483/*PAGE
484 *
485 *  _CPU_Context_restore
486 */
487
488void _CPU_Context_restore(
489  Context_Control  *next
490)
491{
492  Context_Control_overlay *nextp = (Context_Control_overlay *)next;
493
494  sigprocmask( SIG_SETMASK, &nextp->isr_level, 0 );
495  longjmp( nextp->regs, 0 );
496}
497
498/*PAGE
499 *
500 *  _CPU_Context_switch
501 */
502
503void _CPU_Context_switch(
504  Context_Control  *current,
505  Context_Control  *next
506)
507{
508  Context_Control_overlay *currentp = (Context_Control_overlay *)current;
509  Context_Control_overlay *nextp = (Context_Control_overlay *)next;
510
511  int status;
512
513  /*
514   *  Switch levels in one operation
515   */
516
517  status = sigprocmask( SIG_SETMASK, &nextp->isr_level, &currentp->isr_level );
518  if ( status )
519    _Internal_error_Occurred(
520      INTERNAL_ERROR_CORE,
521      TRUE,
522      status
523    );
524
525  if (setjmp(currentp->regs) == 0) {    /* Save the current context */
526     longjmp(nextp->regs, 0);           /* Switch to the new context */
527     if ( status )
528       _Internal_error_Occurred(
529         INTERNAL_ERROR_CORE,
530         TRUE,
531         status
532       );
533  }
534
535}
536 
537/*PAGE
538 *
539 *  _CPU_Save_float_context
540 */
541
542void _CPU_Save_float_context(
543  Context_Control_fp *fp_context
544)
545{
546}
547
548/*PAGE
549 *
550 *  _CPU_Restore_float_context
551 */
552
553void _CPU_Restore_float_context(
554  Context_Control_fp *fp_context
555)
556{
557}
558
559/*PAGE
560 *
561 *  _CPU_ISR_Disable_support
562 */
563
564unsigned32 _CPU_ISR_Disable_support(void)
565{
566  int status;
567  sigset_t  old_mask;
568
569  status = sigprocmask(SIG_BLOCK, &_CPU_Signal_mask, &old_mask);
570  if ( status )
571    _Internal_error_Occurred(
572      INTERNAL_ERROR_CORE,
573      TRUE,
574      status
575    );
576
577  if (memcmp((void *)&posix_empty_mask, (void *)&old_mask, sizeof(sigset_t)))
578    return 1;
579
580  return 0;
581}
582
583/*PAGE
584 *
585 *  _CPU_ISR_Enable
586 */
587
588void _CPU_ISR_Enable(
589  unsigned32 level
590)
591{
592  int status;
593
594  if (level == 0)
595    status = sigprocmask(SIG_UNBLOCK, &_CPU_Signal_mask, 0);
596  else
597    status = sigprocmask(SIG_BLOCK, &_CPU_Signal_mask, 0);
598
599  if ( status )
600    _Internal_error_Occurred(
601      INTERNAL_ERROR_CORE,
602      TRUE,
603      status
604    );
605}
606
607/*PAGE
608 *
609 *  _CPU_ISR_Handler
610 *
611 *  External interrupt handler.
612 *  This is installed as a UNIX signal handler.
613 *  It vectors out to specific user interrupt handlers.
614 */
615
616void _CPU_ISR_Handler(int vector)
617{
618  extern void        _Thread_Dispatch(void);
619  extern unsigned32  _Thread_Dispatch_disable_level;
620  extern boolean     _Context_Switch_necessary;
621
622  if (_ISR_Nest_level++ == 0) {
623      /* switch to interrupt stack */
624  }
625
626  _Thread_Dispatch_disable_level++;
627
628  if (_ISR_Vector_table[vector]) {
629     _ISR_Vector_table[vector](vector);
630  } else {
631     _CPU_Stray_signal(vector);
632  }
633
634  if (_ISR_Nest_level-- == 0) {
635      /* switch back to original stack */
636  }
637
638  _Thread_Dispatch_disable_level--;
639
640  if (_Thread_Dispatch_disable_level == 0 &&
641      (_Context_Switch_necessary || _ISR_Signals_to_thread_executing)) {
642      _ISR_Signals_to_thread_executing = FALSE;
643      _CPU_ISR_Enable(0);
644      _Thread_Dispatch();
645  }
646}
647
648/*PAGE
649 *
650 *  _CPU_Stray_signal
651 */
652
653void _CPU_Stray_signal(int sig_num)
654{
655  char buffer[ 4 ];
656 
657  /*
658   * print "stray" msg about ones which that might mean something
659   * Avoid using the stdio section of the library.
660   * The following is generally safe.
661   */
662 
663  switch (sig_num)
664  {
665      case SIGCLD:
666          break;
667 
668      default:
669      {
670        /*
671         *  We avoid using the stdio section of the library.
672         *  The following is generally safe
673         */
674 
675        int digit;
676        int number = sig_num;
677        int len = 0;
678
679        digit = number / 100;
680        number %= 100;
681        if (digit) buffer[len++] = '0' + digit;
682
683        digit = number / 10;
684        number %= 10;
685        if (digit || len) buffer[len++] = '0' + digit;
686
687        digit = number;
688        buffer[len++] = '0' + digit;
689 
690        buffer[ len++ ] = '\n';
691 
692        write( 2, "Stray signal ", 13 );
693        write( 2, buffer, len );
694
695      }
696  }
697 
698  /*
699   * If it was a "fatal" signal, then exit here
700   * If app code has installed a hander for one of these, then
701   * we won't call _CPU_Stray_signal, so this is ok.
702   */
703 
704  switch (sig_num) {
705      case SIGINT:
706      case SIGHUP:
707      case SIGQUIT:
708      case SIGILL:
709#ifdef SIGEMT
710      case SIGEMT:
711#endif
712      case SIGKILL:
713      case SIGBUS:
714      case SIGSEGV:
715      case SIGTERM:
716        _CPU_Fatal_error(0x100 + sig_num);
717  }
718}
719
720/*PAGE
721 *
722 *  _CPU_Fatal_error
723 */
724
725void _CPU_Fatal_error(unsigned32 error)
726{
727  setitimer(ITIMER_REAL, 0, 0);
728
729  if ( error ) {
730#ifdef RTEMS_DEBUG
731    abort();
732#endif
733    if (getenv("RTEMS_DEBUG"))
734      abort();
735  }
736
737  _exit(error);
738}
739
740/*
741 *  Special Purpose Routines to hide the use of UNIX system calls.
742 */
743
744int _CPU_Get_clock_vector( void )
745{
746  return SIGALRM;
747}
748
749void _CPU_Start_clock(
750  int microseconds
751)
752{
753  struct itimerval  new;
754
755  new.it_value.tv_sec = 0;
756  new.it_value.tv_usec = microseconds;
757  new.it_interval.tv_sec = 0;
758  new.it_interval.tv_usec = microseconds;
759
760  setitimer(ITIMER_REAL, &new, 0);
761}
762
763void _CPU_Stop_clock( void )
764{
765  struct itimerval  new;
766  struct sigaction  act;
767 
768  /*
769   * Set the SIGALRM signal to ignore any last
770   * signals that might come in while we are
771   * disarming the timer and removing the interrupt
772   * vector.
773   */
774 
775  (void) memset(&act, 0, sizeof(act));
776  act.sa_handler = SIG_IGN;
777 
778  sigaction(SIGALRM, &act, 0);
779 
780  (void) memset(&new, 0, sizeof(new));
781  setitimer(ITIMER_REAL, &new, 0);
782}
783
784int  _CPU_SHM_Semid;
785extern       void fix_syscall_errno( void );
786
787void _CPU_SHM_Init(
788  unsigned32   maximum_nodes,
789  boolean      is_master_node,
790  void       **shm_address,
791  unsigned32  *shm_length
792)
793{
794  int          i;
795  int          shmid;
796  char        *shm_addr;
797  key_t        shm_key;
798  key_t        sem_key;
799  int          status;
800  int          shm_size;
801 
802  if (getenv("RTEMS_SHM_KEY"))
803    shm_key = strtol(getenv("RTEMS_SHM_KEY"), 0, 0);
804  else
805#ifdef RTEMS_SHM_KEY
806    shm_key = RTEMS_SHM_KEY;
807#else
808    shm_key = 0xa000;
809#endif
810 
811    if (getenv("RTEMS_SHM_SIZE"))
812      shm_size = strtol(getenv("RTEMS_SHM_SIZE"), 0, 0);
813    else
814#ifdef RTEMS_SHM_SIZE
815      shm_size = RTEMS_SHM_SIZE;
816#else
817      shm_size = 64 * 1024;
818#endif
819 
820    if (getenv("RTEMS_SHM_SEMAPHORE_KEY"))
821      sem_key = strtol(getenv("RTEMS_SHM_SEMAPHORE_KEY"), 0, 0);
822    else
823#ifdef RTEMS_SHM_SEMAPHORE_KEY
824      sem_key = RTEMS_SHM_SEMAPHORE_KEY;
825#else
826      sem_key = 0xa001;
827#endif
828 
829    shmid = shmget(shm_key, shm_size, IPC_CREAT | 0660);
830    if ( shmid == -1 ) {
831      fix_syscall_errno(); /* in case of newlib */
832      perror( "shmget" );
833      _CPU_Fatal_halt( 0xdead0001 );
834    }
835 
836    shm_addr = shmat(shmid, (char *)0, SHM_RND);
837    if ( shm_addr == (void *)-1 ) {
838      fix_syscall_errno(); /* in case of newlib */
839      perror( "shmat" );
840      _CPU_Fatal_halt( 0xdead0002 );
841    }
842 
843    _CPU_SHM_Semid = semget(sem_key, maximum_nodes + 1, IPC_CREAT | 0660);
844    if ( _CPU_SHM_Semid == -1 ) {
845      fix_syscall_errno(); /* in case of newlib */
846      perror( "semget" );
847      _CPU_Fatal_halt( 0xdead0003 );
848    }
849 
850    if ( is_master_node ) {
851      for ( i=0 ; i <= maximum_nodes ; i++ ) {
852#if defined(solaris2)
853        union semun {
854          int val;
855          struct semid_ds *buf;
856          ushort *array;
857        } help;
858 
859        help.val = 1;
860        status = semctl( _CPU_SHM_Semid, i, SETVAL, help );
861#endif
862#if defined(hpux)
863        status = semctl( _CPU_SHM_Semid, i, SETVAL, 1 );
864#endif
865 
866        fix_syscall_errno(); /* in case of newlib */
867        if ( status == -1 ) {
868          _CPU_Fatal_halt( 0xdead0004 );
869        }
870      }
871    }
872 
873  *shm_address = shm_addr;
874  *shm_length = shm_size;
875
876}
877
878int _CPU_Get_pid( void )
879{
880  return getpid();
881}
882
883/*
884 * Define this to use signals for MPCI shared memory driver.
885 * If undefined, the shared memory driver will poll from the
886 * clock interrupt.
887 * Ref: ../shmsupp/getcfg.c
888 *
889 * BEWARE:: many UN*X kernels and debuggers become severely confused when
890 *          debugging programs which use signals.  The problem is *much*
891 *          worse when using multiple signals, since ptrace(2) tends to
892 *          drop all signals except 1 in the case of multiples.
893 *          On hpux9, this problem was so bad, we couldn't use interrupts
894 *          with the shared memory driver if we ever hoped to debug
895 *          RTEMS programs.
896 *          Maybe systems that use /proc don't have this problem...
897 */
898 
899 
900int _CPU_SHM_Get_vector( void )
901{
902#ifdef CPU_USE_SHM_INTERRUPTS
903  return SIGUSR1;
904#else
905  return 0;
906#endif
907}
908
909void _CPU_SHM_Send_interrupt(
910  int pid,
911  int vector
912)
913{
914  kill((pid_t) pid, vector);
915}
916
917void _CPU_SHM_Lock(
918  int semaphore
919)
920{
921  struct sembuf      sb;
922  int                status;
923 
924  sb.sem_num = semaphore;
925  sb.sem_op  = -1;
926  sb.sem_flg = 0;
927 
928  while (1) {
929    status = semop(_CPU_SHM_Semid, &sb, 1);
930    if ( status >= 0 )
931      break;
932    if ( status == -1 ) {
933       fix_syscall_errno();    /* in case of newlib */
934        if (errno == EINTR)
935            continue;
936        perror("shm lock");
937        _CPU_Fatal_halt( 0xdead0005 );
938    }
939  }
940
941}
942
943void _CPU_SHM_Unlock(
944  int semaphore
945)
946{
947  struct sembuf  sb;
948  int            status;
949 
950  sb.sem_num = semaphore;
951  sb.sem_op  = 1;
952  sb.sem_flg = 0;
953 
954  while (1) {
955    status = semop(_CPU_SHM_Semid, &sb, 1);
956    if ( status >= 0 )
957      break;
958 
959    if ( status == -1 ) {
960      fix_syscall_errno();    /* in case of newlib */
961      if (errno == EINTR)
962          continue;
963      perror("shm unlock");
964      _CPU_Fatal_halt( 0xdead0006 );
965    }
966  }
967
968}
Note: See TracBrowser for help on using the repository browser.