📄 cpu.c
字号:
*/void _CPU_Context_restore( Context_Control *next){ Context_Control_overlay *nextp = (Context_Control_overlay *)next; _CPU_ISR_Enable(nextp->isr_level); longjmp( nextp->regs, 0 );}/*PAGE * * _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){ 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 );#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 */ _Internal_error_Occurred( INTERNAL_ERROR_CORE, TRUE, status ); }}/*PAGE * * _CPU_Save_float_context */void _CPU_Save_float_context( Context_Control_fp *fp_context){}/*PAGE * * _CPU_Restore_float_context */void _CPU_Restore_float_context( Context_Control_fp *fp_context){}/*PAGE * * _CPU_ISR_Disable_support */unsigned32 _CPU_ISR_Disable_support(void){ int status; sigset_t old_mask; sigemptyset( &old_mask ); status = sigprocmask(SIG_BLOCK, &_CPU_Signal_mask, &old_mask); if ( status ) _Internal_error_Occurred( INTERNAL_ERROR_CORE, TRUE, status ); if (memcmp((void *)&posix_empty_mask, (void *)&old_mask, sizeof(sigset_t))) return 1; return 0;}/*PAGE * * _CPU_ISR_Enable */void _CPU_ISR_Enable( unsigned32 level){ int status; if (level == 0) status = sigprocmask(SIG_UNBLOCK, &_CPU_Signal_mask, 0); else status = sigprocmask(SIG_BLOCK, &_CPU_Signal_mask, 0); if ( status ) _Internal_error_Occurred( INTERNAL_ERROR_CORE, TRUE, status );}/*PAGE * * _CPU_ISR_Handler * * External interrupt handler. * This is installed as a UNIX signal handler. * It vectors out to specific user interrupt handlers. */void _CPU_ISR_Handler(int vector){ extern void _Thread_Dispatch(void); extern unsigned32 _Thread_Dispatch_disable_level; extern boolean _Context_Switch_necessary; if (_ISR_Nest_level++ == 0) { /* switch to interrupt stack */ } _Thread_Dispatch_disable_level++; if (_ISR_Vector_table[vector]) { _ISR_Vector_table[vector](vector); } else { _CPU_Stray_signal(vector); } if (_ISR_Nest_level-- == 0) { /* switch back to original stack */ } _Thread_Dispatch_disable_level--; if (_Thread_Dispatch_disable_level == 0 && (_Context_Switch_necessary || _ISR_Signals_to_thread_executing)) { _ISR_Signals_to_thread_executing = FALSE; _CPU_ISR_Enable(0); _Thread_Dispatch(); }}/*PAGE * * _CPU_Stray_signal */void _CPU_Stray_signal(int sig_num){ char buffer[ 4 ]; /* * print "stray" msg about ones which that might mean something * Avoid using the stdio section of the library. * The following is generally safe. */ switch (sig_num) {#ifdef SIGCLD case SIGCLD: break;#endif default: { /* * We avoid using the stdio section of the library. * The following is generally safe */ int digit; int number = sig_num; int len = 0; digit = number / 100; number %= 100; if (digit) buffer[len++] = '0' + digit; digit = number / 10; number %= 10; if (digit || len) buffer[len++] = '0' + digit; digit = number; buffer[len++] = '0' + digit; buffer[ len++ ] = '\n'; write( 2, "Stray signal ", 13 ); write( 2, buffer, len ); } } /* * If it was a "fatal" signal, then exit here * If app code has installed a hander for one of these, then * we won't call _CPU_Stray_signal, so this is ok. */ switch (sig_num) { case SIGINT: case SIGHUP: case SIGQUIT: case SIGILL:#ifdef SIGEMT case SIGEMT:#endif case SIGKILL: case SIGBUS: case SIGSEGV: case SIGTERM:#if !defined(__CYGWIN__) case SIGIOT:#endif _CPU_Fatal_error(0x100 + sig_num); }}/*PAGE * * _CPU_Fatal_error */void _CPU_Fatal_error(unsigned32 error){ setitimer(ITIMER_REAL, 0, 0); if ( error ) {#ifdef RTEMS_DEBUG abort();#endif if (getenv("RTEMS_DEBUG")) abort(); } _exit(error);}/* * Special Purpose Routines to hide the use of UNIX system calls. */int _CPU_Set_sync_io_handler( int fd, boolean read, boolean write, boolean except, rtems_sync_io_handler handler){ if ((fd < FD_SETSIZE) && (_CPU_Sync_io_handlers[fd] == NULL)) { if (read) FD_SET(fd, &sync_io_readfds); else FD_CLR(fd, &sync_io_readfds); if (write) FD_SET(fd, &sync_io_writefds); else FD_CLR(fd, &sync_io_writefds); if (except) FD_SET(fd, &sync_io_exceptfds); else FD_CLR(fd, &sync_io_exceptfds); _CPU_Sync_io_handlers[fd] = handler; if ((fd + 1) > sync_io_nfds) sync_io_nfds = fd + 1; return 0; } return -1;}int _CPU_Clear_sync_io_handler( int fd){ if ((fd < FD_SETSIZE) && _CPU_Sync_io_handlers[fd]) { FD_CLR(fd, &sync_io_readfds); FD_CLR(fd, &sync_io_writefds); FD_CLR(fd, &sync_io_exceptfds); _CPU_Sync_io_handlers[fd] = NULL; sync_io_nfds = 0; for (fd = 0; fd < FD_SETSIZE; fd++) if (FD_ISSET(fd, &sync_io_readfds) || FD_ISSET(fd, &sync_io_writefds) || FD_ISSET(fd, &sync_io_exceptfds)) sync_io_nfds = fd + 1; return 0; } return -1;}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. */ (void) memset(&act, 0, sizeof(act)); act.sa_handler = SIG_IGN; sigaction(SIGALRM, &act, 0); (void) memset(&new, 0, sizeof(new)); setitimer(ITIMER_REAL, &new, 0);}#if 0extern void fix_syscall_errno( void );#endif#define fix_syscall_errno() #if defined(RTEMS_MULTIPROCESSING)int _CPU_SHM_Semid;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 = 0; /* to avoid unitialized warnings */ 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 !HAS_UNION_SEMUN union semun { int val; struct semid_ds *buf; unsigned short int *array;#if defined(__linux__) struct seminfo *__buf;#endif } ;#endif union semun help ; help.val = 1; status = semctl( _CPU_SHM_Semid, i, SETVAL, help ); fix_syscall_errno(); /* in case of newlib */ if ( status == -1 ) { _CPU_Fatal_halt( 0xdead0004 ); } } } *shm_address = shm_addr; *shm_length = shm_size;}#endifint _CPU_Get_pid( void ){ return getpid();}#if defined(RTEMS_MULTIPROCESSING)/* * 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; sb.sem_num = semaphore; sb.sem_op = -1; sb.sem_flg = 0; while (1) { int status = -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 ); } }}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -