⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 syscall.c

📁 eCos/RedBoot for勤研ARM AnywhereII(4510) 含全部源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
#define TICKS_PER_SEC  (1000000000ULL / NS_PER_TICK)

// This needs to match newlib HZ which is normally 60.
#define HZ (60ULL)

#ifdef CYGSEM_REDBOOT_BSP_SYSCALLS_GPROF
static unsigned int set_freq   = TICKS_PER_SEC; // The default
#endif // CYGSEM_REDBOOT_BSP_SYSCALLS_GPROF
static int
sys_times(unsigned long *p)
{
    static int inited = 0;

    if (!inited) {
        inited = 1;
        sys_timer_init();
    }

    /* target clock runs at CLOCKS_PER_SEC. Convert to HZ */
    if (p)
#ifdef CYGSEM_REDBOOT_BSP_SYSCALLS_GPROF
        *p = (sys_timer_ticks * HZ) / (cyg_uint64)set_freq;
#else
        *p = (sys_timer_ticks * HZ) / TICKS_PER_SEC;
#endif // CYGSEM_REDBOOT_BSP_SYSCALLS_GPROF

    return 0;
}

#ifdef CYGSEM_REDBOOT_BSP_SYSCALLS_GPROF

static void sys_profile_call_back( char *func, char **previous_call_back )
{
    if ( previous_call_back )
        *previous_call_back = (char *)timer_callback;

    timer_callback = (callback_func *)func;

    // Ensure the timer is started
    (void)sys_times( (unsigned long *)0 );
} 

static void sys_profile_frequency( int freq, int *previous_freq )
{
// Requested HZ:
// 0         => tell me the current value (no change, IMPLEMENTED HERE)
// - 1       => tell me the slowest (no change)
// - 2       => tell me the default (no change, IMPLEMENTED HERE)
// -nnn      => tell me what you would choose for nnn (no change)
// MIN_INT   => tell me the fastest (no change)
//        
// 1         => tell me the slowest (sets the clock)
// MAX_INT   => tell me the fastest (sets the clock)

    // Ensure the timer is started
    (void)sys_times( (unsigned long *)0 );

    if ( -2 == freq )
        freq = TICKS_PER_SEC; // default value
    else if ( 0 == freq )
        freq = set_freq; // collect current value
    else {
        int do_set_freq = (freq > 0);
        unsigned int period = CYGNUM_HAL_RTC_PERIOD;

        if ( 0 == (freq ^ -freq) ) // Then it's MIN_INT in local size
            freq++; // just so that it will negate correctly

        // Then set the timer to that fast - or pass on the enquiry
#ifdef HAL_CLOCK_REINITIALIZE
        // Give the HAL enough info to do the division sum relative to
        // the default setup, in period and TICKS_PER_SEC.
        HAL_CLOCK_REINITIALIZE( freq, period, TICKS_PER_SEC );
#else
        freq = TICKS_PER_SEC; // the only choice
#endif
        if ( do_set_freq ) { // update the global variables
            unsigned int orig = set_freq;
            set_freq = freq;
            set_period = period;
            // We must "correct" sys_timer_ticks for the new scale factor.
            sys_timer_ticks = sys_timer_ticks * set_freq / orig;
        }
    }

    if ( previous_freq ) // Return the current value (new value)
        *previous_freq = freq;
}

void sys_profile_reset( void )
{
    timer_callback = NULL;
// Want to preserve the frequency between runs, for clever GDB users!
//    sys_profile_frequency( TICKS_PER_SEC, NULL );
}

#endif // CYGSEM_REDBOOT_BSP_SYSCALLS_GPROF

//
//  Generic syscall handler.
//
//  Returns 0 if syscall number is not handled by this
//  module, 1 otherwise. This allows applications to
//  extend the syscall handler by using exception chaining.
//
CYG_ADDRWORD
__do_syscall(CYG_ADDRWORD func,                 // syscall function number
             CYG_ADDRWORD arg1, CYG_ADDRWORD arg2,      // up to four args.
             CYG_ADDRWORD arg3, CYG_ADDRWORD arg4,
             CYG_ADDRWORD *retval, CYG_ADDRWORD *sig)   // syscall return value
{
    int err = 0;
    *sig = 0;

    switch (func) {

      case SYS_open:
      {
#ifdef CYGPKG_HAL_GDB_FILEIO // File I/O over the GDB remote protocol
          __externC int cyg_hal_gdbfileio_open( const char *name, int flags, 
                                                int mode, int *sig );
	  if (gdb_active)
	      err = cyg_hal_gdbfileio_open((const char *)arg1, (int)arg2, (int)arg3,
					   (int *)sig);
	  else
#endif
	      err = sys_open((const char *)arg1, (int)arg2, (int)arg3);
          break;
      }
      case SYS_read:
      {
#ifdef CYGPKG_HAL_GDB_FILEIO // File I/O over the GDB remote protocol
          __externC int cyg_hal_gdbfileio_read( int fd, void *buf, size_t count,
                                                int *sig );
	  if (gdb_active)
	      err = cyg_hal_gdbfileio_read((int)arg1, (void *)arg2, (size_t)arg3,
					   (int *)sig);
	  else
#endif
	      err = sys_read((int)arg1, (char *)arg2, (int)arg3);
          break;
      }
      case SYS_write:
      {
#ifdef CYGPKG_HAL_GDB_FILEIO // File I/O over the GDB remote protocol
          __externC int cyg_hal_gdbfileio_write( int fd, const void *buf,
                                                 size_t count, int *sig );
	  if (gdb_active)
	      err = cyg_hal_gdbfileio_write((int)arg1, (const void *)arg2,
					    (size_t)arg3, (int *)sig);
	  else
#endif
	      err = sys_write((int)arg1, (char *)arg2, (int)arg3);
          break;
      }
      case SYS_close:
      {
#ifdef CYGPKG_HAL_GDB_FILEIO // File I/O over the GDB remote protocol
          __externC int cyg_hal_gdbfileio_close( int fd, int *sig );
	  if (gdb_active)
	      err = cyg_hal_gdbfileio_close((int)arg1, (int *)sig);
	  else
#endif
	      err = sys_close((int)arg1);
          break;
      }
      case SYS_lseek:
      {
#ifdef CYGPKG_HAL_GDB_FILEIO // File I/O over the GDB remote protocol
          __externC int cyg_hal_gdbfileio_lseek( int fd, long offset,
                                                 int whence, int *sig );
	  if (gdb_active)
	      err = cyg_hal_gdbfileio_lseek((int)arg1, (long)arg2, (int)arg3,
					    (int *)sig);
	  else
#endif
	      err = sys_lseek((int)arg1, (int)arg2, (int)arg3);
          break;
      }
      case SYS_stat:
      {
#ifdef CYGPKG_HAL_GDB_FILEIO // File I/O over the GDB remote protocol
          __externC int cyg_hal_gdbfileio_stat( const char *pathname,
                                                void *statbuf, int *sig );
	  if (gdb_active)
	      err = cyg_hal_gdbfileio_stat((const char *)arg1, (void *)arg2,
					   (int *)sig);
	  else
#endif
	      err = -NEWLIB_ENOSYS;
          break;
      }
      case SYS_fstat:
      {
#ifdef CYGPKG_HAL_GDB_FILEIO // File I/O over the GDB remote protocol
          __externC int cyg_hal_gdbfileio_fstat( int fd, void *statbuf,
                                                 int *sig );
	  if (gdb_active)
	      err = cyg_hal_gdbfileio_fstat((int)arg1, (void *)arg2,
					    (int *)sig);
	  else
#endif
	  {
	      struct newlib_stat *st = (struct newlib_stat *)arg2;
	      st->st_mode = NEWLIB_S_IFCHR;
	      st->st_blksize = 4096;
	      err = 0;
	  }
          break;
      }
      case SYS_rename:
      {
#ifdef CYGPKG_HAL_GDB_FILEIO // File I/O over the GDB remote protocol
          __externC int cyg_hal_gdbfileio_rename( const char *oldpath,
                                                  const char *newpath,
                                                  int *sig );
	  if (gdb_active)
	      err = cyg_hal_gdbfileio_rename((const char *)arg1, (const char *)arg2,
					     (int *)sig);
	  else
#endif
	      err = -NEWLIB_ENOSYS;
          break;
      }
      case SYS_unlink:
      {
#ifdef CYGPKG_HAL_GDB_FILEIO // File I/O over the GDB remote protocol
          __externC int cyg_hal_gdbfileio_unlink( const char *pathname,
                                                  int *sig );
	  if (gdb_active)
	      err = cyg_hal_gdbfileio_unlink((const char *)arg1, (int *)sig);
	  else
#endif
	      err = -NEWLIB_ENOSYS;
          break;
      }
      case SYS_isatty:
      {
#ifdef CYGPKG_HAL_GDB_FILEIO // File I/O over the GDB remote protocol
          __externC int cyg_hal_gdbfileio_isatty( int fd, int *sig );
	  if (gdb_active)
	      err = cyg_hal_gdbfileio_isatty((int)arg1, (int *)sig);
	  else
#endif
	      err = 1;
          break;
      }
      case SYS_system:
      {
#ifdef CYGPKG_HAL_GDB_FILEIO // File I/O over the GDB remote protocol
          __externC int cyg_hal_gdbfileio_system( const char *command,
                                                  int *sig );
	  if (gdb_active)
	      err = cyg_hal_gdbfileio_system((const char *)arg1, (int *)sig);
	  else
#endif
	      err = -1;
          break;
      }
      case SYS_gettimeofday:
      {
#ifdef CYGPKG_HAL_GDB_FILEIO // File I/O over the GDB remote protocol
          __externC int cyg_hal_gdbfileio_gettimeofday( void *tv, void *tz,
                                                        int *sig );
	  if (gdb_active)
	      err = cyg_hal_gdbfileio_gettimeofday((void *)arg1, (void *)arg2,
						   (int *)sig);
	  else
#endif
	      err = 0;
          break;
      }
      case SYS_utime:
        // FIXME. Some libglosses depend on this behavior.
        err = sys_times((unsigned long *)arg1);
        break;

      case SYS_times:
        err = sys_times((unsigned long *)arg1);
        break;

      case SYS_meminfo:
        err = 1;
        *(unsigned long *)arg1 = (unsigned long)(ram_end-ram_start);
        *(unsigned long *)arg2 = (unsigned long)ram_end;
        break;
#ifdef CYGSEM_REDBOOT_BSP_SYSCALLS_GPROF
    case SYS_timer_call_back:
        sys_profile_call_back( (char *)arg1, (char **)arg2 );
        break;

    case SYS_timer_frequency:
        sys_profile_frequency( (int)arg1, (unsigned int *)arg2 );
        break;

    case SYS_timer_reset:
        sys_profile_reset();
        break;

#endif // CYGSEM_REDBOOT_BSP_SYSCALLS_GPROF
      case __GET_SHARED:
        *(__shared_t **)arg1 = &__shared_data;
        break;

      case SYS_exit:
	*sig = -1;    // signal exit
	err = arg1;

	if (gdb_active) {
#ifdef CYGOPT_REDBOOT_BSP_SYSCALLS_EXIT_WITHOUT_TRAP
	    __send_exit_status((int)arg1);
#else
	    *sig = SIGTRAP;
	    err = func;
#endif // CYGOPT_REDBOOT_BSP_SYSCALLS_EXIT_WITHOUT_TRAP
	}
	break;

      default:
        return 0;
    }    

    *retval = err;
    return 1;
}

#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -