diff packages/redboot/current/src/syscall.c @ 136:a9ac27ec7abc ecos-sw-2000-11-17

Merge from eCos master repository on 2000-11-17-18:24:25-GMT
author jlarmour
date Fri, 17 Nov 2000 23:16:43 +0000
parents
children 25e238959bae
line wrap: on
line diff
new file mode 100644
--- /dev/null
+++ b/packages/redboot/current/src/syscall.c
@@ -0,0 +1,279 @@
+/*==========================================================================
+//
+//      syscall.c
+//
+//      Redboot syscall handling for GNUPro bsp support
+//
+//==========================================================================
+//####COPYRIGHTBEGIN####
+//                                                                          
+// -------------------------------------------                              
+// The contents of this file are subject to the Red Hat eCos Public License 
+// Version 1.1 (the "License"); you may not use this file except in         
+// compliance with the License.  You may obtain a copy of the License at    
+// http://www.redhat.com/                                                   
+//                                                                          
+// Software distributed under the License is distributed on an "AS IS"      
+// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the 
+// License for the specific language governing rights and limitations under 
+// the License.                                                             
+//                                                                          
+// The Original Code is eCos - Embedded Configurable Operating System,      
+// released September 30, 1998.                                             
+//                                                                          
+// The Initial Developer of the Original Code is Red Hat.                   
+// Portions created by Red Hat are                                          
+// Copyright (C) 2000 Red Hat, Inc.                             
+// All Rights Reserved.                                                     
+// -------------------------------------------                              
+//                                                                          
+//####COPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    msalter
+// Contributors: msalter
+// Date:         1999-02-20
+// Purpose:      Temporary support for gnupro bsp
+//
+//####DESCRIPTIONEND####
+//
+//=========================================================================*/
+
+#include <redboot.h>
+
+#ifdef CYGSEM_REDBOOT_BSP_SYSCALLS
+
+#define	EIO 5		/* I/O error */
+
+// These are required by the ANSI C part of newlib (excluding system() of
+// course).
+#define	SYS_exit	1
+#define	SYS_open	2
+#define	SYS_close	3
+#define	SYS_read	4
+#define	SYS_write	5
+#define	SYS_lseek	6
+#define	SYS_unlink	7
+#define	SYS_getpid	8
+#define	SYS_kill	9
+#define SYS_fstat       10
+//#define SYS_sbrk	11 - not currently a system call, but reserved.
+
+// ARGV support.
+#define SYS_argvlen	12
+#define SYS_argv	13
+
+// These are extras added for one reason or another.
+#define SYS_chdir	14
+#define SYS_stat	15
+#define SYS_chmod 	16
+#define SYS_utime 	17
+#define SYS_time 	18
+
+#define SYS_interrupt   1000
+
+#define __GET_SHARED  0xbaad
+
+
+/*
+ * 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 };
+
+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);
+    }
+}
+
+
+//
+// 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--;
+    }
+
+    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 (-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 (-EIO);
+}
+
+
+static int
+sys_utime(unsigned long *p)
+{
+#ifdef HAVE_SYS_CLOCK
+    extern unsigned long __clock;
+
+    /* target clock runs at CLOCKS_PER_SEC. Convert to HZ */
+    if (p)
+	*p = (__clock * HZ) / CLOCKS_PER_SEC;
+#else
+    if (p)
+	*p = 0;
+#endif
+    return 0;
+}
+
+
+//
+//  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.
+//
+int
+__do_syscall(int func,			// syscall function number
+	     long arg1, long arg2,	// up to four args.
+	     long arg3, long arg4,
+	     int *retval)		// syscall return value
+{
+    int err = 0;
+
+    switch (func) {
+
+      case SYS_read:
+	err = sys_read((int)arg1, (char *)arg2, (int)arg3);
+	break;
+
+      case SYS_write:
+	err = sys_write((int)arg1, (char *)arg2, (int)arg3);
+	break;
+
+      case SYS_open:
+	err = sys_open((const char *)arg1, (int)arg2, (int)arg3);
+	break;
+
+      case SYS_close:
+	err = sys_close((int)arg1);
+	break;
+
+      case SYS_lseek:
+	err = sys_lseek((int)arg1, (int)arg2, (int)arg3);
+	break;
+
+      case SYS_utime:
+	err = sys_utime((unsigned long *)arg1);
+	break;
+
+      case __GET_SHARED:
+	*(__shared_t **)arg1 = &__shared_data;
+	break;
+
+      default:
+	return 0;
+    }    
+
+    *retval = err;
+    return 1;
+}
+
+#endif