📄 syscall.c
字号:
/*==========================================================================
//
// syscall.c
//
// Redboot syscall handling for GNUPro bsp support
//
//==========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Red Hat, Inc.
//
// eCos is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 or (at your option) any later version.
//
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with eCos; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
//
// As a special exception, if other files instantiate templates or use macros
// or inline functions from this file, or you compile this file and link it
// with other works to produce a work based on this file, this file does not
// by itself cause the resulting work to be covered by the GNU General Public
// License. However the source code for this file must still be made available
// in accordance with section (3) of the GNU General Public License.
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
//
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
// at http://sources.redhat.com/ecos/ecos-license/
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
//==========================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s): msalter
// Contributors: msalter
// Date: 1999-02-20
// Purpose: Temporary support for gnupro bsp
//
//####DESCRIPTIONEND####
//
//=========================================================================*/
#include <redboot.h>
#include <cyg/hal/hal_intr.h>
#include <cyg/hal/drv_api.h>
#include <cyg/hal/hal_stub.h>
#ifdef CYGSEM_REDBOOT_BSP_SYSCALLS
#define NEWLIB_EIO 5 /* I/O error */
#define NEWLIB_ENOSYS 88 /* Syscall not supported */
/*
* Clients of this BSP will need to have access to BSP functions and
* data structures. Because, the client and the BSP may not be linked
* together, a structure of vectors is used to gain this access. A
* pointer to this structure can be gotten via a syscall. This syscall
* is made automatically from within the crt0.o file.
*/
typedef struct {
int version; /* version number for future expansion */
const void **__ictrl_table;
void **__exc_table;
void *__dbg_vector;
void *__kill_vector;
void *__console_procs;
void *__debug_procs;
void (*__flush_dcache)(void *__p, int __nbytes);
void (*__flush_icache)(void *__p, int __nbytes);
void *__cpu_data;
void *__board_data;
void *__sysinfo;
int (*__set_debug_comm)(int __comm_id);
int (*__set_console_comm)(int __comm_id);
int (*__set_serial_baud)(int __comm_id, int baud);
void *__dbg_data;
void (*__reset)(void);
int __console_interrupt_flag;
} __shared_t;
static __shared_t __shared_data = { 2 };
// this is used by newlib's mode_t so we should match it
#ifdef __GNUC__
#define _ST_INT32 __attribute__ ((__mode__ (__SI__)))
#else
#define _ST_INT32
#endif
typedef unsigned int newlib_mode_t _ST_INT32;
typedef short newlib_dev_t;
typedef unsigned short newlib_ino_t;
typedef unsigned short newlib_nlink_t;
typedef long newlib_off_t;
typedef unsigned short newlib_uid_t;
typedef unsigned short newlib_gid_t;
typedef long newlib_time_t;
typedef long newlib_long_t;
struct newlib_stat
{
newlib_dev_t st_dev;
newlib_ino_t st_ino;
newlib_mode_t st_mode;
newlib_nlink_t st_nlink;
newlib_uid_t st_uid;
newlib_gid_t st_gid;
newlib_dev_t st_rdev;
newlib_off_t st_size;
// We assume we've been compiled with the same flags as newlib here
#if defined(__svr4__) && !defined(__PPC__) && !defined(__sun__)
newlib_time_t st_atime;
newlib_time_t st_mtime;
newlib_time_t st_ctime;
#else
newlib_time_t st_atime;
newlib_long_t st_spare1;
newlib_time_t st_mtime;
newlib_long_t st_spare2;
newlib_time_t st_ctime;
newlib_long_t st_spare3;
newlib_long_t st_blksize;
newlib_long_t st_blocks;
newlib_long_t st_spare4[2];
#endif
};
#define NEWLIB_S_IFCHR 0020000 // character special file
static inline char __getc(void)
{
char c;
hal_virtual_comm_table_t* __chan = CYGACC_CALL_IF_CONSOLE_PROCS();
if (__chan)
c = CYGACC_COMM_IF_GETC(*__chan);
else {
__chan = CYGACC_CALL_IF_DEBUG_PROCS();
c = CYGACC_COMM_IF_GETC(*__chan);
}
return c;
}
static inline void __putc(char c)
{
hal_virtual_comm_table_t* __chan = CYGACC_CALL_IF_CONSOLE_PROCS();
if (__chan)
CYGACC_COMM_IF_PUTC(*__chan, c);
else {
__chan = CYGACC_CALL_IF_DEBUG_PROCS();
CYGACC_COMM_IF_PUTC(*__chan, c);
}
}
static inline void __flush(void)
{
hal_virtual_comm_table_t* __chan = CYGACC_CALL_IF_CONSOLE_PROCS();
if (__chan == NULL)
__chan = CYGACC_CALL_IF_DEBUG_PROCS();
CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_FLUSH_OUTPUT);
}
// Timer support
static cyg_handle_t sys_timer_handle;
static cyg_interrupt sys_timer_interrupt;
static cyg_uint64 sys_timer_ticks = 0;
#ifdef CYGSEM_REDBOOT_BSP_SYSCALLS_GPROF
static unsigned int set_period = CYGNUM_HAL_RTC_PERIOD; // The default
typedef void *callback_func( char *pc, char *sp );
static callback_func *timer_callback = 0;
#endif // CYGSEM_REDBOOT_BSP_SYSCALLS_GPROF
static void
sys_timer_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
{
// do nothing
}
static cyg_uint32
sys_timer_isr(cyg_vector_t vector, cyg_addrword_t data)
{
++sys_timer_ticks;
#ifdef CYGSEM_REDBOOT_BSP_SYSCALLS_GPROF
HAL_CLOCK_RESET(CYGNUM_HAL_INTERRUPT_RTC, set_period);
#else
HAL_CLOCK_RESET(CYGNUM_HAL_INTERRUPT_RTC, CYGNUM_HAL_RTC_PERIOD);
#endif // CYGSEM_REDBOOT_BSP_SYSCALLS_GPROF
cyg_drv_interrupt_acknowledge(CYGNUM_HAL_INTERRUPT_RTC);
#ifdef CYGSEM_REDBOOT_BSP_SYSCALLS_GPROF
if ( timer_callback ) {
char *intrpc = (char *)0;
char *intrsp = (char *)0;
// There may be a number of ways to get the PC and (optional) SP
// information out of the HAL. Hence this is conditioned. In some
// configurations, a register-set pointer is available as
// (invisible) argument 3 to this ISR call.
#ifdef HAL_GET_PROFILE_INFO
HAL_GET_PROFILE_INFO( intrpc, intrsp );
#endif // HAL_GET_PROFILE_INFO available
CYGARC_HAL_SAVE_GP();
timer_callback( intrpc, intrsp );
CYGARC_HAL_RESTORE_GP();
}
#endif // CYGSEM_REDBOOT_BSP_SYSCALLS_GPROF
return CYG_ISR_HANDLED;
}
static void sys_timer_init(void)
{
#ifdef CYGSEM_REDBOOT_BSP_SYSCALLS_GPROF
HAL_CLOCK_INITIALIZE(set_period);
#else
HAL_CLOCK_INITIALIZE(CYGNUM_HAL_RTC_PERIOD);
#endif // CYGSEM_REDBOOT_BSP_SYSCALLS_GPROF
cyg_drv_interrupt_create(
CYGNUM_HAL_INTERRUPT_RTC,
0, // Priority - unused
(CYG_ADDRWORD)0, // Data item passed to ISR & DSR
sys_timer_isr, // ISR
sys_timer_dsr, // DSR
&sys_timer_handle, // handle to intr obj
&sys_timer_interrupt ); // space for int obj
cyg_drv_interrupt_attach(sys_timer_handle);
cyg_drv_interrupt_unmask(CYGNUM_HAL_INTERRUPT_RTC);
}
//
// read -- read bytes from the serial port. Ignore fd, since
// we only have stdin.
static int
sys_read(int fd, char *buf, int nbytes)
{
int i = 0;
for (i = 0; i < nbytes; i++) {
*(buf + i) = __getc();
if ((*(buf + i) == '\n') || (*(buf + i) == '\r')) {
(*(buf + i + 1)) = 0;
break;
}
}
return (i);
}
//
// write -- write bytes to the serial port. Ignore fd, since
// stdout and stderr are the same. Since we have no filesystem,
// open will only return an error.
//
static int
sys_write(int fd, char *buf, int nbytes)
{
#define WBUFSIZE 256
int tosend;
tosend = nbytes;
while (tosend > 0) {
if (*buf == '\n')
__putc('\r');
__putc(*buf++);
tosend--;
}
__flush();
return (nbytes);
}
//
// open -- open a file descriptor. We don't have a filesystem, so
// we return an error.
//
static int
sys_open (const char *buf, int flags, int mode)
{
return (-NEWLIB_EIO);
}
//
// close -- We don't need to do anything, but pretend we did.
//
static int
sys_close(int fd)
{
return (0);
}
//
// lseek -- Since a serial port is non-seekable, we return an error.
//
static int
sys_lseek(int fd, int offset, int whence)
{
return (-NEWLIB_EIO);
}
#define NS_PER_TICK (CYGNUM_HAL_RTC_NUMERATOR/CYGNUM_HAL_RTC_DENOMINATOR)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -