📄 syscall.c
字号:
#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 + -