summaryrefslogtreecommitdiffstats
path: root/bsps/arm/csb337
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2018-04-03 16:24:31 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2018-04-09 07:09:46 +0200
commit671c31fc5d20a82bf39cdcd2a105daa65e0eb555 (patch)
tree503811ce9bb9e8597c55602773a9b8e350a81c34 /bsps/arm/csb337
parentAllow rtems-bsps to be run from any path. (diff)
downloadrtems-671c31fc5d20a82bf39cdcd2a105daa65e0eb555.tar.bz2
bsp: Move umon support to bsps
The umon support is only used by the csb337 BSP. This patch is a part of the BSP source reorganization. Update #3285.
Diffstat (limited to 'bsps/arm/csb337')
-rw-r--r--bsps/arm/csb337/umon/README50
-rw-r--r--bsps/arm/csb337/umon/doxygen.h7
-rw-r--r--bsps/arm/csb337/umon/monlib.c1166
-rw-r--r--bsps/arm/csb337/umon/tfsDriver.c683
-rw-r--r--bsps/arm/csb337/umon/umoncons.c131
-rw-r--r--bsps/arm/csb337/umon/umonrtemsglue.c34
6 files changed, 2071 insertions, 0 deletions
diff --git a/bsps/arm/csb337/umon/README b/bsps/arm/csb337/umon/README
new file mode 100644
index 0000000000..aa8b0b972c
--- /dev/null
+++ b/bsps/arm/csb337/umon/README
@@ -0,0 +1,50 @@
+# Fernando Nicodemos <fgnicodemos@terra.com.br>
+# from NCB - Sistemas Embarcados Ltda. (Brazil)
+#
+# Joel Sherill
+# from OAR Corporation
+#
+
+This directory contains support for utilitizing MicroMonitor
+(http://www.umonfw.com/) capabilities from within an RTEMS
+application. This directory contiains:
+
++ "MonLib" functionality as documented in the MicroMonitor
+ User's Manual.
++ TFS filesystem which makes the MicroMonitor TFS filesystem
+ available under RTEMS as a regular filesystem.
+
+Usage
+=====
+
+For any of this functionality to work, the application is
+responsible for connecting the library to the monitor.
+This is done by calling rtems_umon_connect() early in the
+application. This routine assumes that the BSP has provided
+the routine rtems_bsp_get_umon_monptr() which returns the
+value referred to as MONCOMPTR by MicroMonitor.
+
+To use the TFS filesystem, it is necessary to mount it
+by calling the rtems_initialize_tfs_filesystem() routine
+and providing it the name of the mount point directory.
+
+CONFIGURATION
+=============
+The TFS filesystem uses a single Classic API Semaphore.
+
+The monlib functionality will eventually also use a single
+Classic API Semaphore.
+
+STATUS
+======
+
++ Limited testing -- especially of TFS RTEMS filesystem.
++ monlib is NOT currently protected by a mutex.
+
+SOURCE ORIGIN
+=============
+Some of the files in this directory are included in the
+MicroMonitor distribution and may need to be updated
+in the future.
+
+12 June 2009: Source is from umon 1.17
diff --git a/bsps/arm/csb337/umon/doxygen.h b/bsps/arm/csb337/umon/doxygen.h
new file mode 100644
index 0000000000..a74d3c3e8b
--- /dev/null
+++ b/bsps/arm/csb337/umon/doxygen.h
@@ -0,0 +1,7 @@
+/**
+ * @defgroup shared_umon SHARED UMON Modules
+ *
+ * @ingroup bsp_shared
+ *
+ * @brief SHARED UMON Modules
+ */ \ No newline at end of file
diff --git a/bsps/arm/csb337/umon/monlib.c b/bsps/arm/csb337/umon/monlib.c
new file mode 100644
index 0000000000..36f9158a36
--- /dev/null
+++ b/bsps/arm/csb337/umon/monlib.c
@@ -0,0 +1,1166 @@
+/*
+ * monlib.c -
+ * This file is part of the monitor code, but it is actually linked into
+ * the application. It is built with (but not linked with) the monitor,
+ * then the monlib.o file is linked with the application.
+ * The only requirement on the application is that it know where the address
+ * of the monCom function is in the monitor's space.
+ * The monCom function will be accessible in some "well-known" way (processor
+ * and platform dependent) so that this will not be a problem.
+ *
+ * This monlib.c file is a replacement for the older mechanism that was
+ * a bit more error-prone... A table of function pointers existed at some
+ * well-known location in the monitor, and the content of that table was
+ * assumed to also be "well-known". This new version only assumes that the
+ * pointer to monCom is well-known; everything else will work based on the
+ * fact that the monitor and application will share the monlib.h header
+ * file.
+ *
+ **************************************************************************
+ * General notice:
+ * This code is part of a boot-monitor package developed as a generic base
+ * platform for embedded system designs. As such, it is likely to be
+ * distributed to various projects beyond the control of the original
+ * author. Please notify the author of any enhancements made or bugs found
+ * so that all may benefit from the changes. In addition, notification back
+ * to the author will allow the new user to pick up changes that may have
+ * been made by other users after this version of the code was distributed.
+ *
+ * Note1: the majority of this code was edited with 4-space tabs.
+ * Note2: as more and more contributions are accepted, the term "author"
+ * is becoming a mis-representation of credit.
+ *
+ * Original author: Ed Sutter
+ * Email: esutter@alcatel-lucent.com
+ * Phone: 908-582-2351
+ **************************************************************************
+ *
+ * Ed Sutter has been informed that this code is being used in RTEMS.
+ *
+ * This code was reformatted by Joel Sherrill from OAR Corporation and
+ * Fernando Nicodemos <fgnicodemos@terra.com.br> from NCB - Sistemas
+ * Embarcados Ltda. (Brazil) to be more compliant with RTEMS coding
+ * standards and to eliminate C++ style comments.
+ */
+
+#include <umon/monlib.h>
+
+static int (*_tfsseek)(int,int,int);
+static int (*_tfsgetline)(int,char *,int);
+static int (*_tfsipmod)(char *,char *,int,int);
+static int (*_tfsinit)(void);
+static int (*_tfsadd)(char *,char *,char *,unsigned char *,int);
+static int (*_tfsunlink)(char *);
+static int (*_tfsrun)(char **,int);
+static int (*_tfsread)(int,char *,int);
+static int (*_tfswrite)(int,char *,int);
+static int (*_tfsopen)(char *,long,char *);
+static int (*_tfsclose)(int,char *);
+static int (*_printf)(
+ char *, int,int,int,int,int,int,int,int,int,int,int,int);
+static int (*_cprintf)(
+ char *, int,int,int,int,int,int,int,int,int,int,int,int);
+static int (*_sprintf)(
+ char *, char *, int,int,int,int,int,int,int,int,int,int,int,int);
+static int (*_monrestart)(int);
+static int (*_rputchar)(unsigned char c);
+static int (*_getchar)(void);
+static int (*_gotachar)(void);
+static int (*_getbytes)(char *,int,int);
+static int (*_addcommand)(struct monCommand *,char *);
+static int (*_docommand)(char *,int);
+static int (*_getline)(char *,int,int);
+static int (*_tfsfstat)(char *,struct tfshdr *);
+static int (*_tfseof)(int);
+static int (*_decompress)(char *,int,char *);
+static int (*_tfstruncate)(int,long);
+static int (*_heapextend)(char *,int);
+static int (*_tfslink)(char *,char *);
+static int (*_pcicfgwrite)(int,int,int,int,int,unsigned long);
+static int (*_i2cwrite)(int,int,unsigned char *,int);
+static int (*_i2cread)(int,int,unsigned char *,int);
+static int (*_flashwrite)(char *,char *,int);
+static int (*_flasherase)(int);
+static int (*_flashinfo)(int,int *,char **);
+static int (*_flashoverride)(void *,int,int);
+static int (*_sendenet)(char *,int);
+static int (*_recvenet)(char *,int);
+static int (*_printpkt)(char *,int,int);
+static int (*_setenv)(char *,char *);
+static int (*_watchdog)(void);
+static int (*_timeofday)(int,void *);
+static int (*_montimer)(int cmd, void *arg);
+
+static char *(*_getenv)(char *);
+static char *(*_version)(void);
+static char *(*_getenvp)(void);
+#ifdef MALLOC_DEBUG
+static char *(*_malloc)(int,char *,int);
+static char *(*_realloc)(char *buf,int,char *,int);
+#else
+static char *(*_malloc)(int);
+static char *(*_realloc)(char *,int);
+#endif
+static char *(*_getsym)(char *,char *,int);
+
+static void (*_intsrestore)(unsigned long);
+static void (*_appexit)(int);
+static void (*_free)(char *);
+static void (*_getargv)(int *,char ***);
+static void (*_profiler)(void *);
+static void (*_bbc)(char *,int);
+static void (*_memtrace)(
+ char *, int,int,int,int,int,int,int,int,int,int,int,int);
+static void (*_appwarmstart)(unsigned long);
+static void (*_mondelay)(long);
+static void (*_printmem)(char *,int,int);
+
+static long (*_tfsctrl)(int,long,long);
+static long (*_tfstell)(int);
+static long (*_portcmd)(int,void *);
+
+static struct tfshdr *(*_tfsnext)(struct tfshdr *);
+static struct tfshdr *(*_tfsstat)(char *);
+
+static unsigned long (*_i2cctrl)(int,int,unsigned long,unsigned long);
+static unsigned long (*_pcicfgread)(int,int,int,int,int);
+static unsigned long (*_pcictrl)(int,int,unsigned long,unsigned long);
+static unsigned long (*_crc32)(unsigned char *,unsigned long);
+static unsigned long (*_intsoff)(void);
+static unsigned long (*_assign_handler)(long,unsigned long,unsigned long);
+
+static unsigned short (*_xcrc16)(unsigned char *,unsigned long);
+
+
+static void (*_monlock)(void);
+static void (*_monunlock)(void);
+static int (*_moncom)(int,void *,void *, void *);
+
+/**************************************************************************
+ *
+ * The following macros support the default monitor lock/unlock mechanism when
+ * they point to monLock and monUnlock. If something other than the default
+ * is to be used, then simply redefine them here. Refer to the monitor
+ * app note that discusses multi-tasking access to the monitor API for more
+ * information.
+ *
+ * TFS_MONLOCK/UNLOCK:
+ * Lock/unlock for functions that access TFS flash space:
+ */
+#define TFS_MONLOCK monLock
+#define TFS_MONUNLOCK monUnlock
+
+/* ENV_MONLOCK/UNLOCK:
+ * Lock/unlock for functions that access monitor shell variables:
+ */
+#define ENV_MONLOCK monLock
+#define ENV_MONUNLOCK monUnlock
+
+/* CONSOLE_MONLOCK/UNLOCK:
+ * Lock/unlock for functions in the monitor that deal with console output.
+ */
+#define CONSOLE_MONLOCK monLock
+#define CONSOLE_MONUNLOCK monUnlock
+
+/* HEAP_MONLOCK/UNLOCK:
+ * Lock/unlock for functions in the monitor that deal with the heap.
+ */
+#define HEAP_MONLOCK monLock
+#define HEAP_MONUNLOCK monUnlock
+
+/* BLOCKING_MONLOCK/UNLOCK:
+ * Lock/unlock for functions in the monitor that block waiting for
+ * console input.
+ */
+#define BLOCKING_MONLOCK monLock
+#define BLOCKING_MONUNLOCK monUnlock
+
+/* GENERIC_MONLOCK/UNLOCK:
+ * Lock/unlock for all functions not covered by the above macros.
+ */
+#define GENERIC_MONLOCK monLock
+#define GENERIC_MONUNLOCK monUnlock
+
+/*
+ * Prototype these to avoid warnings but let them appear varargs to user.
+ */
+extern void mon_memtrace(
+ char *fmt,
+ int a1, int a2, int a3, int a4, int a5, int a6,
+ int a7, int a8, int a9, int a10, int a11, int a12
+);
+extern int mon_printf(
+ char *fmt,
+ int a1, int a2, int a3, int a4, int a5, int a6,
+ int a7, int a8, int a9, int a10, int a11, int a12
+);
+extern int mon_cprintf(
+ char *fmt,
+ int a1, int a2, int a3, int a4, int a5, int a6,
+ int a7, int a8, int a9, int a10, int a11, int a12
+);
+extern int mon_sprintf(
+ char *buf,
+ char *fmt,
+ int a1, int a2, int a3, int a4, int a5, int a6,
+ int a7, int a8, int a9, int a10, int a11, int a12
+);
+
+/**************************************************************************
+ *
+ * monConnect():
+ * This must be the first call by the application code to talk to the
+ * monitor. It is expecting three incoming function pointers:
+ *
+ * mon: Points to the monitor's _moncom function;
+ * This is a "well-known" address because the monitor and
+ * application code (two separately linked binaries) must
+ * know it.
+ * lock: Points to a function in the application code that will be
+ * used by the monitor as a lock-out function (some kind of
+ * semaphore in the application).
+ * unlock: Points to a function in the application code that will be
+ * used by the monitor as an un-lock-out function (undo whatever
+ * lock-out mechanism was done by lock).
+ */
+int
+monConnect(int (*mon)(int,void *,void *,void *),
+ void (*lock)(void), void (*unlock)(void))
+{
+ int rc = 0;
+
+ /* Assign incoming lock and unlock functions... */
+ _monlock = lock;
+ _monunlock = unlock;
+
+ /* If the mon pointer is non-zero, then make the mon_ connections... */
+ if (mon) {
+
+ _moncom = mon;
+
+ /* Make the connections between "mon_" functions that are */
+ /* symbolically accessible by the application and the corresponding */
+ /* functions that exists in the monitor. */
+ rc += _moncom(GETMONFUNC_PUTCHAR,&_rputchar,0,0);
+ rc += _moncom(GETMONFUNC_GETCHAR,&_getchar,0,0);
+ rc += _moncom(GETMONFUNC_GOTACHAR,&_gotachar,0,0);
+ rc += _moncom(GETMONFUNC_GETBYTES,&_getbytes,0,0);
+ rc += _moncom(GETMONFUNC_PRINTF,&_printf,0,0);
+ rc += _moncom(GETMONFUNC_CPRINTF,&_cprintf,0,0);
+ rc += _moncom(GETMONFUNC_SPRINTF,&_sprintf,0,0);
+ rc += _moncom(GETMONFUNC_RESTART,&_monrestart,0,0);
+ rc += _moncom(GETMONFUNC_GETENV,&_getenv,0,0);
+ rc += _moncom(GETMONFUNC_SETENV,&_setenv,0,0);
+ rc += _moncom(GETMONFUNC_TFSINIT,&_tfsinit,0,0);
+ rc += _moncom(GETMONFUNC_TFSADD,&_tfsadd,0,0);
+ rc += _moncom(GETMONFUNC_TFSUNLINK,&_tfsunlink,0,0);
+ rc += _moncom(GETMONFUNC_TFSRUN,&_tfsrun,0,0);
+ rc += _moncom(GETMONFUNC_TFSNEXT,&_tfsnext,0,0);
+ rc += _moncom(GETMONFUNC_TFSSTAT,&_tfsstat,0,0);
+ rc += _moncom(GETMONFUNC_TFSREAD,&_tfsread,0,0);
+ rc += _moncom(GETMONFUNC_TFSWRITE,&_tfswrite,0,0);
+ rc += _moncom(GETMONFUNC_TFSOPEN,&_tfsopen,0,0);
+ rc += _moncom(GETMONFUNC_TFSCLOSE,&_tfsclose,0,0);
+ rc += _moncom(GETMONFUNC_TFSSEEK,&_tfsseek,0,0);
+ rc += _moncom(GETMONFUNC_TFSGETLINE,&_tfsgetline,0,0);
+ rc += _moncom(GETMONFUNC_TFSIPMOD,&_tfsipmod,0,0);
+ rc += _moncom(GETMONFUNC_TFSCTRL,&_tfsctrl,0,0);
+ rc += _moncom(GETMONFUNC_ADDCOMMAND,&_addcommand,0,0);
+ rc += _moncom(GETMONFUNC_DOCOMMAND,&_docommand,0,0);
+ rc += _moncom(GETMONFUNC_GETARGV,&_getargv,0,0);
+ rc += _moncom(GETMONFUNC_CRC16,&_xcrc16,0,0);
+ rc += _moncom(GETMONFUNC_CRC32,&_crc32,0,0);
+ rc += _moncom(GETMONFUNC_INTSOFF,&_intsoff,0,0);
+ rc += _moncom(GETMONFUNC_INTSRESTORE,&_intsrestore,0,0);
+ rc += _moncom(GETMONFUNC_APPEXIT,&_appexit,0,0);
+ rc += _moncom(GETMONFUNC_MALLOC,&_malloc,0,0);
+ rc += _moncom(GETMONFUNC_FREE,&_free,0,0);
+ rc += _moncom(GETMONFUNC_GETLINE,&_getline,0,0);
+ rc += _moncom(GETMONFUNC_TFSFSTAT,&_tfsfstat,0,0);
+ rc += _moncom(GETMONFUNC_TFSEOF,&_tfseof,0,0);
+ rc += _moncom(GETMONFUNC_DECOMPRESS,&_decompress,0,0);
+ rc += _moncom(GETMONFUNC_TFSTRUNCATE,&_tfstruncate,0,0);
+ rc += _moncom(GETMONFUNC_HEAPXTEND,&_heapextend,0,0);
+ rc += _moncom(GETMONFUNC_PROFILER,&_profiler,0,0);
+ rc += _moncom(GETMONFUNC_TFSLINK,&_tfslink,0,0);
+ rc += _moncom(GETMONFUNC_BBC,&_bbc,0,0);
+ rc += _moncom(GETMONFUNC_MEMTRACE,&_memtrace,0,0);
+ rc += _moncom(GETMONFUNC_TFSTELL,&_tfstell,0,0);
+ rc += _moncom(GETMONFUNC_VERSION,&_version,0,0);
+ rc += _moncom(GETMONFUNC_WARMSTART,&_appwarmstart,0,0);
+ rc += _moncom(GETMONFUNC_PCICFGREAD,&_pcicfgread,0,0);
+ rc += _moncom(GETMONFUNC_PCICFGWRITE,&_pcicfgwrite,0,0);
+ rc += _moncom(GETMONFUNC_PCICONTROL,&_pcictrl,0,0);
+ rc += _moncom(GETMONFUNC_I2CREAD,&_i2cread,0,0);
+ rc += _moncom(GETMONFUNC_I2CWRITE,&_i2cwrite,0,0);
+ rc += _moncom(GETMONFUNC_I2CCONTROL,&_i2cctrl,0,0);
+ rc += _moncom(GETMONFUNC_MONDELAY,&_mondelay,0,0);
+ rc += _moncom(GETMONFUNC_GETENVP,&_getenvp,0,0);
+ rc += _moncom(GETMONFUNC_REALLOC,&_realloc,0,0);
+ rc += _moncom(GETMONFUNC_SENDENETPKT,&_sendenet,0,0);
+ rc += _moncom(GETMONFUNC_RECVENETPKT,&_recvenet,0,0);
+ rc += _moncom(GETMONFUNC_GETSYM,&_getsym,0,0);
+ rc += _moncom(GETMONFUNC_PRINTPKT,&_printpkt,0,0);
+ rc += _moncom(GETMONFUNC_FLASHWRITE,&_flashwrite,0,0);
+ rc += _moncom(GETMONFUNC_FLASHERASE,&_flasherase,0,0);
+ rc += _moncom(GETMONFUNC_FLASHINFO,&_flashinfo,0,0);
+ rc += _moncom(GETMONFUNC_ASSIGNHDLR,&_assign_handler,0,0);
+ rc += _moncom(GETMONFUNC_WATCHDOG,&_watchdog,0,0);
+ rc += _moncom(GETMONFUNC_PRINTMEM,&_printmem,0,0);
+ rc += _moncom(GETMONFUNC_PORTCMD,&_portcmd,0,0);
+ rc += _moncom(GETMONFUNC_TIMEOFDAY,&_timeofday,0,0);
+ rc += _moncom(GETMONFUNC_TIMER,&_montimer,0,0);
+ rc += _moncom(GETMONFUNC_FLASHOVRRD,&_flashoverride,0,0);
+ }
+ return(rc);
+}
+
+/* ignorelock:
+ * Used as a back-door to disable the monLock()/monUnlock() stuff.
+ * This is useful if the application CLI falls through to the monitor's
+ * CLI and you are using the "call" command in the monitor to execute some
+ * function that has a mon_xxx function in it. In this case, the fact that
+ * the application has fallen through to the monitor means that the lock
+ * is already active, so when the function tries to call some other mon_xxx
+ * function it won't be able to because of the lock already being set.
+ *
+ * With these functions in the application space, the user can do the
+ * following:
+ * call %DisableLock
+ * call %Func_with_monXXX_in_it
+ * call %EnableLock
+ *
+ * Note that this is NOT to be used by application code, it is simply a
+ * back-door mechanism to allow "call" from the CLI to invoke functions
+ * that have mon_XXX functionality in them.
+ */
+static int ignorelock = 0;
+
+#if KEEP_TO_STAY_IN_SYNC_WITH_UPSTREAM_BUT_UNUSED
+static void
+DisableMonLock(void)
+{
+ ignorelock = 2;
+}
+
+static void
+EnableMonLock(void)
+{
+ ignorelock = 0;
+}
+#endif
+
+/* monLock() & monUnlock():
+ * Used by all of the wrapper functions below this point to call
+ * the function pointed to by _monlock & _monunlock function pointers
+ * (if set).
+ * These functions must test both the function pointer and the state
+ * of the ignorelock variable. The function DisableMonLock() sets the
+ * ignorelock variable to 2 because it is being executed through "call"
+ * which means that the lock is active.
+ */
+static void
+monLock(void)
+{
+ if (_monlock) {
+ switch(ignorelock) {
+ case 1:
+ break;
+ case 2:
+ ignorelock--;
+ break;
+ default:
+ _monlock();
+ break;
+ }
+ }
+}
+
+static void
+monUnlock(void)
+{
+ if (_monunlock) {
+ switch(ignorelock) {
+ case 1:
+ break;
+ case 2:
+ ignorelock--;
+ default:
+ _monunlock();
+ break;
+ }
+ }
+}
+
+int
+mon_com(int cmd, void *arg1, void *arg2, void *arg3)
+{
+ int ret;
+
+ GENERIC_MONLOCK();
+ ret = _moncom(cmd,arg1,arg2,arg3);
+ GENERIC_MONUNLOCK();
+ return(ret);
+}
+
+int
+mon_putchar(char c)
+{
+ int ret;
+
+ CONSOLE_MONLOCK();
+ ret = _rputchar(c);
+ CONSOLE_MONUNLOCK();
+ return(ret);
+}
+
+int
+mon_getchar(void)
+{
+ int ret;
+
+ BLOCKING_MONLOCK();
+ ret = _getchar();
+ BLOCKING_MONUNLOCK();
+ return(ret);
+}
+
+int
+mon_gotachar(void)
+{
+ int ret;
+
+ GENERIC_MONLOCK();
+ ret = _gotachar();
+ GENERIC_MONUNLOCK();
+ return(ret);
+}
+
+int
+mon_getbytes(char *buf,int cnt,int block)
+{
+ int ret;
+
+ BLOCKING_MONLOCK();
+ ret = _getbytes(buf,cnt,block);
+ BLOCKING_MONUNLOCK();
+ return(ret);
+}
+
+int
+mon_printf(
+ char *fmt,
+ int a1, int a2, int a3, int a4, int a5, int a6,
+ int a7, int a8, int a9, int a10, int a11, int a12
+)
+{
+ int ret;
+
+ CONSOLE_MONLOCK();
+ ret = _printf(fmt,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12);
+ CONSOLE_MONUNLOCK();
+ return(ret);
+}
+
+int
+mon_cprintf(
+ char *fmt,
+ int a1, int a2, int a3, int a4, int a5, int a6,
+ int a7, int a8, int a9, int a10, int a11, int a12
+)
+{
+ int ret;
+
+ CONSOLE_MONLOCK();
+ ret = _cprintf(fmt,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12);
+ CONSOLE_MONUNLOCK();
+ return(ret);
+}
+
+int
+mon_sprintf(
+ char *buf,
+ char *fmt,
+ int a1, int a2, int a3, int a4, int a5, int a6,
+ int a7, int a8, int a9, int a10, int a11, int a12
+)
+{
+ int ret;
+
+ GENERIC_MONLOCK();
+ ret = _sprintf(buf,fmt,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12);
+ GENERIC_MONUNLOCK();
+ return(ret);
+}
+
+int
+mon_restart(int val)
+{
+ int ret;
+
+ GENERIC_MONLOCK();
+ ret = _monrestart(val);
+ GENERIC_MONUNLOCK();
+ return(ret);
+}
+
+char *
+mon_getenvp(void)
+{
+ char *ret;
+
+ ENV_MONLOCK();
+ ret = _getenvp();
+ ENV_MONUNLOCK();
+ return(ret);
+}
+
+char *
+mon_getenv(char *name)
+{
+ char *ret;
+
+ ENV_MONLOCK();
+ ret = _getenv(name);
+ ENV_MONUNLOCK();
+ return(ret);
+}
+
+int
+mon_setenv(char *name,char *val)
+{
+ int ret;
+
+ ENV_MONLOCK();
+ ret = _setenv(name,val);
+ ENV_MONUNLOCK();
+ return(ret);
+}
+
+char *
+mon_getsym(char *name,char *buf, int bufsize)
+{
+ char *ret;
+
+ ENV_MONLOCK();
+ ret = _getsym(name,buf,bufsize);
+ ENV_MONUNLOCK();
+ return(ret);
+}
+
+int
+mon_tfsinit(void)
+{
+ int ret;
+
+ TFS_MONLOCK();
+ ret = _tfsinit();
+ TFS_MONUNLOCK();
+ return(ret);
+}
+
+int
+mon_tfsadd(char *name, char *info, char *flags, unsigned char *src, int size)
+{
+ int ret;
+
+ TFS_MONLOCK();
+ ret = _tfsadd(name,info,flags,src,size);
+ TFS_MONUNLOCK();
+ return(ret);
+}
+
+int
+mon_tfslink(char *src, char *target)
+{
+ int ret;
+
+ TFS_MONLOCK();
+ ret = _tfslink(src,target);
+ TFS_MONUNLOCK();
+ return(ret);
+}
+
+int
+mon_tfsunlink(char *name)
+{
+ int ret;
+
+ TFS_MONLOCK();
+ ret = _tfsunlink(name);
+ TFS_MONUNLOCK();
+ return(ret);
+}
+
+int
+mon_tfsrun(char **name,int verbose)
+{
+ int ret;
+
+ TFS_MONLOCK();
+ ret = _tfsrun(name,verbose);
+ TFS_MONUNLOCK();
+ return(ret);
+}
+
+struct tfshdr *
+mon_tfsnext(struct tfshdr *fp)
+{
+ struct tfshdr *ret;
+
+ TFS_MONLOCK();
+ ret = _tfsnext(fp);
+ TFS_MONUNLOCK();
+ return(ret);
+}
+
+int
+mon_tfstruncate(int tfd, long len)
+{
+ int ret;
+
+ TFS_MONLOCK();
+ ret = _tfstruncate(tfd,len);
+ TFS_MONUNLOCK();
+ return(ret);
+}
+
+int
+mon_tfseof(int tfd)
+{
+ int ret;
+
+ TFS_MONLOCK();
+ ret = _tfseof(tfd);
+ TFS_MONUNLOCK();
+ return(ret);
+}
+
+int
+mon_tfsfstat(char *name, struct tfshdr *fp)
+{
+ int ret;
+
+ TFS_MONLOCK();
+ ret = _tfsfstat(name,fp);
+ TFS_MONUNLOCK();
+ return(ret);
+}
+
+struct tfshdr *
+mon_tfsstat(char *name)
+{
+ struct tfshdr *ret;
+
+ TFS_MONLOCK();
+ ret = _tfsstat(name);
+ TFS_MONUNLOCK();
+ return(ret);
+}
+
+int
+mon_tfsread(int fd, char *buf, int cnt)
+{
+ int ret;
+
+ TFS_MONLOCK();
+ ret = _tfsread(fd,buf,cnt);
+ TFS_MONUNLOCK();
+ return(ret);
+}
+
+int
+mon_tfswrite(int fd, char *buf, int cnt)
+{
+ int ret;
+
+ TFS_MONLOCK();
+ ret = _tfswrite(fd,buf,cnt);
+ TFS_MONUNLOCK();
+ return(ret);
+}
+
+int
+mon_tfsopen(char *file,long flagmode,char *buf)
+{
+ int ret;
+
+ TFS_MONLOCK();
+ ret = _tfsopen(file,flagmode,buf);
+ TFS_MONUNLOCK();
+ return(ret);
+}
+
+int
+mon_tfsclose(int fd,char *info)
+{
+ int ret;
+
+ TFS_MONLOCK();
+ ret = _tfsclose(fd,info);
+ TFS_MONUNLOCK();
+ return(ret);
+}
+
+int
+mon_tfsseek(int fd, int offset, int whence)
+{
+ int ret;
+
+ TFS_MONLOCK();
+ ret = _tfsseek(fd,offset,whence);
+ TFS_MONUNLOCK();
+ return(ret);
+}
+
+int
+mon_tfsgetline(int fd,char *bp,int max)
+{
+ int ret;
+
+ TFS_MONLOCK();
+ ret = _tfsgetline(fd,bp,max);
+ TFS_MONUNLOCK();
+ return(ret);
+}
+
+int
+mon_tfsipmod(char *name,char *buf,int offset,int size)
+{
+ int ret;
+
+ TFS_MONLOCK();
+ ret = _tfsipmod(name,buf,offset,size);
+ TFS_MONUNLOCK();
+ return(ret);
+}
+
+long
+mon_tfsctrl(int rqst,long arg1,long arg2)
+{
+ long ret;
+
+ TFS_MONLOCK();
+ ret = _tfsctrl(rqst,arg1,arg2);
+ TFS_MONUNLOCK();
+ return(ret);
+}
+
+long
+mon_tfstell(int fd)
+{
+ long ret;
+
+ TFS_MONLOCK();
+ ret = _tfstell(fd);
+ TFS_MONUNLOCK();
+ return(ret);
+}
+
+int
+mon_addcommand(struct monCommand *cmdlist, char *cmdlvl)
+{
+ int ret;
+
+ GENERIC_MONLOCK();
+ ret = _addcommand(cmdlist,cmdlvl);
+ GENERIC_MONUNLOCK();
+ return(ret);
+}
+
+int
+mon_docommand(char *cmdline,int verbose)
+{
+ int ret;
+
+ GENERIC_MONLOCK();
+ ret = _docommand(cmdline,verbose);
+ GENERIC_MONUNLOCK();
+ return(ret);
+}
+
+void
+mon_getargv(int *argc,char ***argv)
+{
+ GENERIC_MONLOCK();
+ _getargv(argc,argv);
+ GENERIC_MONUNLOCK();
+}
+
+unsigned short
+mon_xcrc16(char *buf,long nbytes)
+{
+ unsigned short ret;
+
+ GENERIC_MONLOCK();
+ ret = _xcrc16((unsigned char *)buf,nbytes);
+ GENERIC_MONUNLOCK();
+ return(ret);
+}
+
+unsigned long
+mon_intsoff(void)
+{
+ unsigned long ret;
+
+ GENERIC_MONLOCK();
+ ret = _intsoff();
+ GENERIC_MONUNLOCK();
+ return(ret);
+}
+
+void
+mon_intsrestore(unsigned long msr)
+{
+ GENERIC_MONLOCK();
+ _intsrestore(msr);
+ GENERIC_MONUNLOCK();
+}
+
+void
+mon_appexit(int val)
+{
+ GENERIC_MONLOCK();
+ _appexit(val);
+ GENERIC_MONUNLOCK();
+}
+
+#ifdef MALLOC_DEBUG
+char *
+mon_malloc(int size,char *fname,int fline)
+{
+ char *ret;
+
+ HEAP_MONLOCK();
+ ret = _malloc(size,fname,fline);
+ HEAP_MONUNLOCK();
+ return(ret);
+}
+
+char *
+mon_realloc(char *buf, int size, char *fname, int fline)
+{
+ char *ret;
+
+ HEAP_MONLOCK();
+ ret = _realloc(buf,size, fname, fline);
+ HEAP_MONUNLOCK();
+ return(ret);
+}
+#else
+char *
+mon_malloc(int size)
+{
+ char *ret;
+
+ HEAP_MONLOCK();
+ ret = _malloc(size);
+ HEAP_MONUNLOCK();
+ return(ret);
+}
+
+char *
+mon_realloc(char *buf, int size)
+{
+ char *ret;
+
+ HEAP_MONLOCK();
+ ret = _realloc(buf,size);
+ HEAP_MONUNLOCK();
+ return(ret);
+}
+#endif
+
+void
+mon_free(char *cp)
+{
+ HEAP_MONLOCK();
+ _free(cp);
+ HEAP_MONUNLOCK();
+}
+
+int
+mon_getline(char *buf,int max,int ledit)
+{
+ int ret;
+
+ BLOCKING_MONLOCK();
+ ret = _getline(buf,max,ledit);
+ BLOCKING_MONUNLOCK();
+ return(ret);
+}
+
+int
+mon_decompress(char *src,int srcsize,char *dest)
+{
+ int ret;
+
+ GENERIC_MONLOCK();
+ ret = _decompress(src,srcsize,dest);
+ GENERIC_MONUNLOCK();
+ return(ret);
+}
+
+int
+mon_heapextend(char *base,int size)
+{
+ int ret;
+
+ GENERIC_MONLOCK();
+ ret = _heapextend(base,size);
+ GENERIC_MONUNLOCK();
+ return(ret);
+}
+
+void
+mon_bbc(char *filename, int lineno)
+{
+ _bbc(filename, lineno);
+}
+
+void
+mon_profiler(void *pdata)
+{
+ _profiler(pdata);
+}
+
+void
+mon_memtrace(
+ char *fmt,
+ int a1, int a2, int a3, int a4, int a5, int a6,
+ int a7, int a8, int a9, int a10, int a11, int a12
+)
+{
+ _memtrace(fmt,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12);
+}
+
+char *
+mon_version(void)
+{
+ char *ret;
+
+ GENERIC_MONLOCK();
+ ret = _version();
+ GENERIC_MONUNLOCK();
+ return(ret);
+}
+
+void
+mon_warmstart(unsigned long mask)
+{
+ GENERIC_MONLOCK();
+ _appwarmstart(mask);
+ GENERIC_MONUNLOCK();
+}
+
+int
+mon_pcicfgwrite(int interface,int bus,int dev,int func,int reg,
+ unsigned long val)
+{
+ int retval;
+
+ GENERIC_MONLOCK();
+ retval = _pcicfgwrite(interface,bus,dev,func,reg,val);
+ GENERIC_MONUNLOCK();
+ return(retval);
+}
+
+unsigned long
+mon_pcicfgread(int interface,int bus,int dev, int func,int reg)
+{
+ unsigned long retval;
+
+ GENERIC_MONLOCK();
+ retval = _pcicfgread(interface,bus,dev,func,reg);
+ GENERIC_MONUNLOCK();
+ return(retval);
+}
+
+unsigned long
+mon_pcictrl(int interface, int cmd, unsigned long arg1, unsigned long arg2)
+{
+ unsigned long val;
+
+ GENERIC_MONLOCK();
+ val = _pcictrl(interface,cmd,arg1,arg2);
+ GENERIC_MONUNLOCK();
+ return(val);
+}
+
+unsigned long
+mon_i2cctrl(int interface, int cmd, unsigned long arg1, unsigned long arg2)
+{
+ unsigned long val;
+
+ GENERIC_MONLOCK();
+ val = _i2cctrl(interface,cmd,arg1,arg2);
+ GENERIC_MONUNLOCK();
+ return(val);
+}
+
+int
+mon_i2cwrite(int interface, int bigaddr, unsigned char *data, int len)
+{
+ int val;
+
+ GENERIC_MONLOCK();
+ val = _i2cwrite(interface,bigaddr,data,len);
+ GENERIC_MONUNLOCK();
+ return(val);
+}
+
+int
+mon_i2cread(int interface, int bigaddr, unsigned char *data, int len)
+{
+ int val;
+
+ GENERIC_MONLOCK();
+ val = _i2cread(interface,bigaddr,data,len);
+ GENERIC_MONUNLOCK();
+ return(val);
+}
+
+void
+mon_delay(long msec)
+{
+ GENERIC_MONLOCK();
+ _mondelay(msec);
+ GENERIC_MONUNLOCK();
+}
+
+int
+mon_timer(int cmd, void *arg)
+{
+ int ret;
+
+ GENERIC_MONLOCK();
+ ret = _montimer(cmd, arg);
+ GENERIC_MONUNLOCK();
+ return(ret);
+}
+
+int
+mon_sendenetpkt(char *pkt,int size)
+{
+ int ret;
+
+ GENERIC_MONLOCK();
+ ret = _sendenet(pkt,size);
+ GENERIC_MONUNLOCK();
+ return(ret);
+}
+
+int
+mon_recvenetpkt(char *pkt,int size)
+{
+ int ret;
+
+ GENERIC_MONLOCK();
+ ret = _recvenet(pkt,size);
+ GENERIC_MONUNLOCK();
+ return(ret);
+}
+
+void
+mon_printpkt(char *buf,int size, int incoming)
+{
+ GENERIC_MONLOCK();
+ _printpkt(buf,size,incoming);
+ GENERIC_MONUNLOCK();
+}
+
+int
+mon_flashoverride(void *flashinfo,int get,int bank)
+{
+ int ret;
+
+ TFS_MONLOCK();
+ ret = _flashoverride(flashinfo,get,bank);
+ TFS_MONUNLOCK();
+ return(ret);
+}
+
+int
+mon_flashwrite(char *dest,char *src,int bytecnt)
+{
+ int ret;
+
+ TFS_MONLOCK();
+ ret = _flashwrite(dest,src,bytecnt);
+ TFS_MONUNLOCK();
+ return(ret);
+}
+
+int
+mon_flasherase(int snum)
+{
+ int ret;
+
+ TFS_MONLOCK();
+ ret = _flasherase(snum);
+ TFS_MONUNLOCK();
+ return(ret);
+}
+
+int
+mon_flashinfo(int snum, int *size, char **base)
+{
+ int ret;
+
+ TFS_MONLOCK();
+ ret = _flashinfo(snum,size,base);
+ TFS_MONUNLOCK();
+ return(ret);
+}
+
+unsigned long
+mon_assignhandler(long hnum, unsigned long arg1, unsigned long arg2)
+{
+ int ret;
+
+ GENERIC_MONLOCK();
+ ret = _assign_handler(hnum,arg1,arg2);
+ GENERIC_MONUNLOCK();
+ return(ret);
+}
+
+int
+mon_watchdog(void)
+{
+ int ret;
+
+ GENERIC_MONLOCK();
+ ret = _watchdog();
+ GENERIC_MONUNLOCK();
+ return(ret);
+}
+
+void
+mon_printmem(char *mem, int size, int ascii)
+{
+ GENERIC_MONLOCK();
+ _printmem(mem,size,ascii);
+ GENERIC_MONUNLOCK();
+}
+
+long
+mon_portcmd(int cmd, void *arg)
+{
+ long ret;
+
+ GENERIC_MONLOCK();
+ ret = _portcmd(cmd,arg);
+ GENERIC_MONUNLOCK();
+ return(ret);
+}
+
+int
+mon_timeofday(int cmd, void *arg)
+{
+ int ret;
+
+ GENERIC_MONLOCK();
+ ret = _timeofday(cmd,arg);
+ GENERIC_MONUNLOCK();
+ return(ret);
+}
diff --git a/bsps/arm/csb337/umon/tfsDriver.c b/bsps/arm/csb337/umon/tfsDriver.c
new file mode 100644
index 0000000000..01953469bb
--- /dev/null
+++ b/bsps/arm/csb337/umon/tfsDriver.c
@@ -0,0 +1,683 @@
+/*
+ * tfsDriver.c - MicroMonitor TFS Hookup to RTEMS FS
+ *
+ * Initial release: Oct 1, 2004 by Ed Sutter
+ *
+ * Modifications to support reference counting in the file system are
+ * Copyright (c) 2012 embedded brains GmbH.
+ *
+ * This code was derived from the tftpDriver.c code written by
+ * W. Eric Norum, which was apparently derived from the IMFS driver.
+ *
+ * This code was reformatted by Joel Sherrill from OAR Corporation and
+ * Fernando Nicodemos <fgnicodemos@terra.com.br> from NCB - Sistemas
+ * Embarcados Ltda. (Brazil) to be more compliant with RTEMS coding
+ * standards and to eliminate C++ style comments.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <rtems.h>
+#include <rtems/libio.h>
+#include <rtems/libio_.h>
+#include <rtems/seterr.h>
+#include <rtems/bspIo.h>
+#include <rtems/umon.h>
+
+#include <umon/tfs.h>
+#include <umon/monlib.h>
+
+#ifdef RTEMS_TFS_DRIVER_DEBUG
+#define RTEMS_TFS_DEBUG 1
+#else
+#define RTEMS_TFS_DEBUG 0
+#endif
+
+#define MAXFILESIZE 0x4000
+#define MAXTFDS 15
+
+/* Define these for thread safety...
+ */
+#ifndef newlib_tfdlock
+#define newlib_tfdlock()
+#endif
+
+#ifndef newlib_tfdunlock
+#define newlib_tfdunlock()
+#endif
+
+/* TFS file descriptor info:
+ */
+struct tfdinfo {
+ int inuse;
+ int tfd;
+ char *buf;
+ char name[TFSNAMESIZE+1];
+ char info[TFSNAMESIZE+1];
+} tfdtable[MAXTFDS];
+
+/*
+ * Pathname prefix
+ */
+char TFS_PATHNAME_PREFIX[128];
+
+static const rtems_filesystem_operations_table rtems_tfs_ops;
+static const rtems_filesystem_file_handlers_r rtems_tfs_handlers;
+
+static bool rtems_tfs_is_directory(
+ const char *path,
+ size_t pathlen
+)
+{
+ return path [pathlen - 1] == '/';
+}
+
+static int rtems_tfs_mount_me(
+ rtems_filesystem_mount_table_entry_t *mt_entry,
+ const void *data
+)
+{
+ char *root_path = strdup("/");
+
+ if (root_path == NULL) {
+ rtems_set_errno_and_return_minus_one(ENOMEM);
+ }
+
+ mt_entry->ops = &rtems_tfs_ops;
+ mt_entry->mt_fs_root->location.handlers = &rtems_tfs_handlers;
+ mt_entry->mt_fs_root->location.node_access = root_path;
+
+ return 0;
+}
+
+/* Initialize the TFS-RTEMS file system
+ */
+int rtems_initialize_tfs_filesystem(
+ const char *path
+)
+{
+ int status;
+
+ if (!path) {
+ printk( "TFS: No mount point specified\n" );
+ return -1;
+ }
+
+ strncpy( TFS_PATHNAME_PREFIX, path, sizeof(TFS_PATHNAME_PREFIX) );
+
+ status = mkdir( TFS_PATHNAME_PREFIX, S_IRWXU | S_IRWXG | S_IRWXO );
+ if ( status == -1 ) {
+ printk( "TFS: Unable to mkdir %s\n", TFS_PATHNAME_PREFIX );
+ return status;
+ }
+
+ if (rtems_filesystem_register( "tfs", rtems_tfs_mount_me ) < 0)
+ return -1;
+
+ status = mount( "umon", TFS_PATHNAME_PREFIX, "tfs", RTEMS_FILESYSTEM_READ_WRITE, NULL);
+
+ if (status < 0) {
+ printk( "TFS: Unable to mount on %s\n", TFS_PATHNAME_PREFIX );
+ perror("TFS mount failed");
+ }
+
+ return(status);
+}
+
+/*
+ * Convert a path to canonical form
+ */
+static void fixPath(char *path)
+{
+ char *inp, *outp, *base;
+
+ outp = inp = path;
+ base = NULL;
+ for (;;) {
+ if (inp[0] == '.') {
+ if (inp[1] == '\0')
+ break;
+ if (inp[1] == '/') {
+ inp += 2;
+ continue;
+ }
+ if (inp[1] == '.') {
+ if (inp[2] == '\0') {
+ if ((base != NULL) && (outp > base)) {
+ outp--;
+ while ((outp > base) && (outp[-1] != '/'))
+ outp--;
+ }
+ break;
+ }
+ if (inp[2] == '/') {
+ inp += 3;
+ if (base == NULL)
+ continue;
+ if (outp > base) {
+ outp--;
+ while ((outp > base) && (outp[-1] != '/'))
+ outp--;
+ }
+ continue;
+ }
+ }
+ }
+ if (base == NULL)
+ base = inp;
+ while (inp[0] != '/') {
+ if ((*outp++ = *inp++) == '\0')
+ return;
+ }
+ *outp++ = '/';
+ while (inp[0] == '/')
+ inp++;
+ }
+ *outp = '\0';
+}
+
+static void rtems_tfs_eval_path(rtems_filesystem_eval_path_context_t *self)
+{
+ int eval_flags = rtems_filesystem_eval_path_get_flags(self);
+
+ if ((eval_flags & RTEMS_FS_MAKE) == 0) {
+ int rw = RTEMS_FS_PERMS_READ | RTEMS_FS_PERMS_WRITE;
+
+ if ((eval_flags & rw) != rw) {
+ rtems_filesystem_location_info_t *currentloc =
+ rtems_filesystem_eval_path_get_currentloc(self);
+ char *current = currentloc->node_access;
+ size_t currentlen = strlen(current);
+ const char *path = rtems_filesystem_eval_path_get_path(self);
+ size_t pathlen = rtems_filesystem_eval_path_get_pathlen(self);
+ size_t len = currentlen + pathlen;
+
+ rtems_filesystem_eval_path_clear_path(self);
+
+ current = realloc(current, len + 1);
+ if (current != NULL) {
+ memcpy(current + currentlen, path, pathlen);
+ current [len] = '\0';
+ if (!rtems_tfs_is_directory(current, len)) {
+ fixPath (current);
+ }
+ currentloc->node_access = current;
+ } else {
+ rtems_filesystem_eval_path_error(self, ENOMEM);
+ }
+ } else {
+ rtems_filesystem_eval_path_error(self, EINVAL);
+ }
+ } else {
+ rtems_filesystem_eval_path_error(self, EIO);
+ }
+}
+
+/*
+ * The routine which does most of the work for the IMFS open handler
+ * The full_path_name here is all text AFTER the TFS_PATHNAME_PREFIX
+ * string, so if the filename is "/TFS/abc", the full_path_name string
+ * is "abc"...
+ *
+ * Attempts to remap the incoming flags to TFS equivalent.
+ * Its not a perfect mapping, but gets pretty close.
+ * A comma-delimited path is supported to allow the user
+ * to specify TFS-stuff (flag string, info string, and a buffer).
+ * For example:
+ * abc,e,script,0x400000
+ * This is a file called "abc" that will have the TFS 'e' flag
+ * and the TFS info field of "script". The storage buffer is
+ * supplied by the user at 0x400000.
+ */
+static int rtems_tfs_open_worker(
+ rtems_libio_t *iop,
+ char *path,
+ int oflag,
+ mode_t mode
+)
+{
+ static int beenhere = 0;
+ long flagmode;
+ int tfdidx, tfd;
+ struct tfdinfo *tip;
+ char *buf, *fstr, *istr, *bstr, pathcopy[TFSNAMESIZE*3+1];
+
+ if (RTEMS_TFS_DEBUG)
+ printk("_open_r(%s,0x%x,0x%" PRIx32 ")\n",path,oflag,mode);
+
+ if (!beenhere) {
+ newlib_tfdlock();
+ for(tfdidx=0;tfdidx<MAXTFDS;tfdidx++)
+ tfdtable[tfdidx].inuse = 0;
+
+ tfdtable[0].inuse = 1; /* fake entry for stdin */
+ tfdtable[1].inuse = 1; /* fake entry for stdout */
+ tfdtable[2].inuse = 1; /* fake entry for stderr */
+ newlib_tfdunlock();
+ beenhere = 1;
+ }
+
+ istr = fstr = bstr = buf = (char *)0;
+
+ /* Copy the incoming path to a local array so that we can safely
+ * modify the string...
+ */
+ if (strlen(path) > TFSNAMESIZE*3) {
+ return(ENAMETOOLONG);
+ }
+ strcpy(pathcopy,path);
+
+ /* The incoming string may have commas that are used to delimit the
+ * name from the TFS flag string, TFS info string and buffer.
+ * Check for the commas and test for maximum string length...
+ */
+ fstr = strchr(pathcopy,',');
+ if (fstr) {
+ *fstr++ = 0;
+ istr = strchr(fstr,',');
+ if (istr) {
+ *istr++ = 0;
+ bstr = strchr(istr,',');
+ if (bstr)
+ *bstr++ = 0;
+ }
+ }
+ if (strlen(pathcopy) > TFSNAMESIZE) {
+ return(ENAMETOOLONG);
+ }
+ if (istr) {
+ if (strlen(istr) > TFSNAMESIZE) {
+ return(ENAMETOOLONG);
+ }
+ }
+
+ /* If O_EXCL and O_CREAT are set, then fail if the file exists...
+ */
+ if ((oflag & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL)) {
+ if (mon_tfsstat((char *)pathcopy)) {
+ return(EEXIST);
+ }
+ }
+
+ /* Only a few flag combinations are supported...
+ * O_RDONLY Simple read-only
+ * O_WRONLY | O_APPEND Each write starts at end of file
+ * O_WRONLY | O_TRUNC If file exists, truncate it
+ * O_WRONLY | O_CREAT Create if it doesn't exist
+ * O_WRONLY | O_CREAT | O_EXCL Fail if file exists
+ */
+ switch(oflag & O_ACCMODE) {
+ case O_RDONLY:
+ flagmode = TFS_RDONLY;
+ break;
+ case O_WRONLY|O_APPEND:
+ flagmode = TFS_APPEND;
+ break;
+ case O_WRONLY|O_TRUNC:
+ case O_WRONLY|O_CREAT|O_TRUNC:
+ mon_tfsunlink((char *)pathcopy);
+ flagmode = TFS_CREATE|TFS_APPEND;
+ break;
+ case O_WRONLY|O_CREAT:
+ case O_WRONLY|O_CREAT|O_APPEND:
+ flagmode = TFS_CREATE|TFS_APPEND;
+ break;
+ case O_RDWR:
+ case O_WRONLY|O_CREAT|O_EXCL:
+ flagmode = TFS_CREATE|TFS_APPEND;
+ break;
+ default:
+ printk("_open_r(): flag 0x%i not supported\n",oflag);
+ return(ENOTSUP);
+ }
+
+ /* Find an open slot in our tfd table:
+ */
+ newlib_tfdlock();
+ for(tfdidx=0;tfdidx<MAXTFDS;tfdidx++) {
+ if (tfdtable[tfdidx].inuse == 0)
+ break;
+ }
+ if (tfdidx == MAXTFDS) {
+ newlib_tfdunlock();
+ return(EMFILE);
+ }
+ tip = &tfdtable[tfdidx];
+ tip->inuse = 1;
+ newlib_tfdunlock();
+
+ /* If file is opened for something other than O_RDONLY, then
+ * we need to allocate a buffer for the file..
+ * WARNING: It is the user's responsibility to make sure that
+ * the file size does not exceed this buffer. Note that the
+ * buffer may be specified as part of the comma-delimited path.
+ */
+ if (flagmode == TFS_RDONLY) {
+ buf = (char *)0;
+ } else {
+ if (bstr)
+ buf = (char *)strtol(bstr,0,0);
+ else
+ buf = malloc(MAXFILESIZE);
+ if (!buf) {
+ newlib_tfdlock();
+ tip->inuse = 0;
+ newlib_tfdunlock();
+ return(ENOMEM);
+ }
+ }
+
+ /* Deal with tfs flags and tfs info fields if necessary:
+ */
+ if (fstr) {
+ long bflag;
+
+ bflag = mon_tfsctrl(TFS_FATOB,(long)fstr,0);
+ if (bflag == -1) {
+ return(EINVAL);
+ }
+ flagmode |= bflag;
+ }
+
+ if (istr)
+ strcpy(tip->info,istr);
+ else
+ tip->info[0] = 0;
+
+ tfd = mon_tfsopen((char *)pathcopy,flagmode,buf);
+ if (tfd >= 0) {
+ tip->tfd = tfd;
+ tip->buf = buf;
+ strcpy(tip->name,pathcopy);
+ iop->data0 = (uint32_t)tfdidx;
+ return(0);
+ } else {
+ printk("%s: %s\n",pathcopy,
+ (char *)mon_tfsctrl(TFS_ERRMSG,tfd,0));
+ }
+
+ if (buf)
+ free(buf);
+
+ newlib_tfdlock();
+ tip->inuse = 0;
+ newlib_tfdunlock();
+ return(EINVAL);
+}
+
+/*
+ * The IMFS open handler
+ */
+static int rtems_tfs_open(
+ rtems_libio_t *iop,
+ const char *new_name,
+ int oflag,
+ mode_t mode
+)
+{
+ char *full_path_name;
+ int err;
+
+ full_path_name = iop->pathinfo.node_access;
+
+ if (RTEMS_TFS_DEBUG)
+ printk("rtems_tfs_open(%s)\n",full_path_name);
+
+ if (rtems_tfs_is_directory(full_path_name, strlen(full_path_name))) {
+ rtems_set_errno_and_return_minus_one (ENOTSUP);
+ }
+
+ err = rtems_tfs_open_worker (iop, full_path_name, oflag, mode);
+ if (err != 0) {
+ rtems_set_errno_and_return_minus_one (err);
+ }
+
+ return err;
+}
+
+/*
+ * Read from an open TFS file...
+ */
+static ssize_t rtems_tfs_read(
+ rtems_libio_t *iop,
+ void *buffer,
+ size_t count
+)
+{
+ int ret, fd;
+
+ fd = (int) iop->data0;
+
+ if (RTEMS_TFS_DEBUG)
+ printk("_read_r(%d,%zi)\n",fd,count);
+
+ if ((fd < 3) || (fd >= MAXTFDS))
+ return(EBADF);
+
+ ret = mon_tfsread(tfdtable[fd].tfd,buffer,count);
+ if (ret == TFSERR_EOF)
+ ret = 0;
+
+ return(ret);
+}
+
+/*
+ * Close the open tfs file.
+ */
+static int rtems_tfs_close(
+ rtems_libio_t *iop
+)
+{
+ int fd;
+ char *info;
+ struct tfdinfo *tip;
+
+ fd = (int)iop->data0;
+
+ if (RTEMS_TFS_DEBUG)
+ printk("rtems_tfs_close(%d)\n",fd);
+
+ if ((fd < 3) || (fd >= MAXTFDS)) {
+ rtems_set_errno_and_return_minus_one (EBADF);
+ }
+
+ tip = &tfdtable[fd];
+
+ if (tip->info[0])
+ info = tip->info;
+ else
+ info = (char *)0;
+
+ mon_tfsclose(tip->tfd,info);
+
+ if (tip->buf)
+ free(tip->buf);
+
+ newlib_tfdlock();
+ tip->inuse = 0;
+ newlib_tfdunlock();
+ return RTEMS_SUCCESSFUL;
+}
+
+static ssize_t rtems_tfs_write(
+ rtems_libio_t *iop,
+ const void *buffer,
+ size_t count
+)
+{
+ int ret, fd;
+
+ fd = (int) iop->data0;
+
+ if (RTEMS_TFS_DEBUG)
+ printk("rtems_tfs_write(%d,%zi)\n",fd,count);
+
+ if ((fd <= 0) || (fd >= MAXTFDS)) {
+ rtems_set_errno_and_return_minus_one (EBADF);
+ }
+
+ ret = mon_tfswrite(tfdtable[fd].tfd,(char *)buffer,count);
+ if (ret < 0)
+ return(-1);
+
+ return(ret);
+}
+
+static off_t rtems_tfs_lseek(
+ rtems_libio_t *iop,
+ off_t offset,
+ int whence
+)
+{
+ int ret, fd;
+
+ fd = (int) iop->data0;
+
+ if (RTEMS_TFS_DEBUG)
+ printk("rtems_tfs_lseek(%d,%ld,%d)\n",fd,(long)offset,whence);
+
+ switch (whence) {
+ case SEEK_END:
+ printk("rtems_tfs_lseek doesn't support SEEK_END\n");
+ return(-1);
+ case SEEK_CUR:
+ whence = TFS_CURRENT;
+ break;
+ case SEEK_SET:
+ whence = TFS_BEGIN;
+ break;
+ }
+ ret = mon_tfsseek(tfdtable[fd].tfd,offset,whence);
+
+ if (ret < 0)
+ return(-1);
+
+ return (off_t)ret;
+}
+
+/*
+ *
+ */
+static int rtems_tfs_ftruncate(
+ rtems_libio_t *iop,
+ off_t count
+)
+{
+ int ret, fd;
+
+ fd = (int) iop->data0;
+ ret = mon_tfstruncate(tfdtable[fd].tfd,count);
+ if (ret != TFS_OKAY)
+ return(-1);
+
+ return(0);
+}
+
+static int rtems_tfs_ioctl(
+ rtems_libio_t *iop,
+ uint32_t cmd,
+ void *buf
+)
+{
+ int ret;
+
+ ret = mon_tfsctrl(cmd,(long)buf,0);
+ if (ret != TFS_OKAY)
+ return(-1);
+
+ return(0);
+}
+
+static int rtems_tfs_fstat(
+ const rtems_filesystem_location_info_t *loc,
+ struct stat *buf
+)
+{
+ const char *path = loc->node_access;
+ size_t pathlen = strlen(path);
+
+ buf->st_mode = S_IRWXU | S_IRWXG | S_IRWXO
+ | (rtems_tfs_is_directory(path, pathlen) ? S_IFDIR : S_IFREG);
+
+ return 0;
+}
+
+static int rtems_tfs_clone_node_info(
+ rtems_filesystem_location_info_t *loc
+)
+{
+ int rv = 0;
+
+ loc->node_access = strdup(loc->node_access);
+
+ if (loc->node_access == NULL) {
+ errno = ENOMEM;
+ rv = -1;
+ }
+
+ return rv;
+}
+
+static void rtems_tfs_free_node_info(
+ const rtems_filesystem_location_info_t *loc
+)
+{
+ free(loc->node_access);
+}
+
+static bool rtems_tfs_are_nodes_equal(
+ const rtems_filesystem_location_info_t *a,
+ const rtems_filesystem_location_info_t *b
+)
+{
+ return strcmp(a->node_access, b->node_access) == 0;
+}
+
+static const rtems_filesystem_operations_table rtems_tfs_ops = {
+ .lock_h = rtems_filesystem_default_lock,
+ .unlock_h = rtems_filesystem_default_unlock,
+ .eval_path_h = rtems_tfs_eval_path,
+ .link_h = rtems_filesystem_default_link,
+ .are_nodes_equal_h = rtems_tfs_are_nodes_equal,
+ .mknod_h = rtems_filesystem_default_mknod,
+ .rmnod_h = rtems_filesystem_default_rmnod,
+ .fchmod_h = rtems_filesystem_default_fchmod,
+ .chown_h = rtems_filesystem_default_chown,
+ .clonenod_h = rtems_tfs_clone_node_info,
+ .freenod_h = rtems_tfs_free_node_info,
+ .mount_h = rtems_filesystem_default_mount,
+ .unmount_h = rtems_filesystem_default_unmount,
+ .fsunmount_me_h = rtems_filesystem_default_fsunmount,
+ .utime_h = rtems_filesystem_default_utime,
+ .symlink_h = rtems_filesystem_default_symlink,
+ .readlink_h = rtems_filesystem_default_readlink,
+ .rename_h = rtems_filesystem_default_rename,
+ .statvfs_h = rtems_filesystem_default_statvfs
+};
+
+static const rtems_filesystem_file_handlers_r rtems_tfs_handlers = {
+ .open_h = rtems_tfs_open,
+ .close_h = rtems_tfs_close,
+ .read_h = rtems_tfs_read,
+ .write_h = rtems_tfs_write,
+ .ioctl_h = rtems_tfs_ioctl,
+ .lseek_h = rtems_tfs_lseek,
+ .fstat_h = rtems_tfs_fstat,
+ .ftruncate_h = rtems_tfs_ftruncate,
+ .fsync_h = rtems_filesystem_default_fsync_or_fdatasync,
+ .fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync,
+ .fcntl_h = rtems_filesystem_default_fcntl,
+ .kqfilter_h = rtems_filesystem_default_kqfilter,
+ .poll_h = rtems_filesystem_default_poll,
+ .readv_h = rtems_filesystem_default_readv,
+ .writev_h = rtems_filesystem_default_writev
+};
diff --git a/bsps/arm/csb337/umon/umoncons.c b/bsps/arm/csb337/umon/umoncons.c
new file mode 100644
index 0000000000..ef49585ef8
--- /dev/null
+++ b/bsps/arm/csb337/umon/umoncons.c
@@ -0,0 +1,131 @@
+/*
+ * uMon Support Output Driver
+ *
+ * COPYRIGHT (c) 1989-2009.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * Modified by Fernando Nicodemos <fgnicodemos@terra.com.br>
+ * from NCB - Sistemas Embarcados Ltda. (Brazil)
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <rtems/umon.h>
+#include <libchip/serial.h>
+#include <libchip/sersupp.h>
+
+/* static function prototypes */
+static int umoncons_first_open(int major, int minor, void *arg);
+static int umoncons_last_close(int major, int minor, void *arg);
+static int umoncons_read(int minor);
+static ssize_t umoncons_write(int minor, const char *buf, size_t len);
+static void umoncons_init(int minor);
+static void umoncons_write_polled(int minor, char c);
+static int umoncons_set_attributes(int minor, const struct termios *t);
+
+/* Pointers to functions for handling the UART. */
+const console_fns umoncons_fns =
+{
+ libchip_serial_default_probe,
+ umoncons_first_open,
+ umoncons_last_close,
+ umoncons_read,
+ umoncons_write,
+ umoncons_init,
+ umoncons_write_polled, /* not used in this driver */
+ umoncons_set_attributes,
+ false /* TRUE if interrupt driven, FALSE if not. */
+};
+
+/*********************************************************************/
+/* Functions called via callbacks (i.e. the ones in uart_fns */
+/*********************************************************************/
+
+/*
+ * This is called the first time each device is opened. Since
+ * the driver is polled, we don't have to do anything. If the driver
+ * were interrupt driven, we'd enable interrupts here.
+*/
+static int umoncons_first_open(int major, int minor, void *arg)
+{
+ return 0;
+}
+
+
+/*
+ * This is called the last time each device is closed. Since
+ * the driver is polled, we don't have to do anything. If the driver
+ * were interrupt driven, we'd disable interrupts here.
+*/
+static int umoncons_last_close(int major, int minor, void *arg)
+{
+ return 0;
+}
+
+
+/*
+ * Read one character from UART.
+ *
+ * return -1 if there's no data, otherwise return
+ * the character in lowest 8 bits of returned int.
+*/
+static int umoncons_read(int minor)
+{
+ if ( !mon_gotachar() )
+ return -1;
+ return mon_getchar();
+}
+
+
+/*
+ * Write buffer to LCD
+ *
+ * return 1 on success, -1 on error
+*/
+static ssize_t umoncons_write(int minor, const char *buf, size_t len)
+{
+ size_t i;
+
+ for ( i=0 ; i<len ; i++ )
+ mon_putchar( buf[i] );
+
+ return len;
+}
+
+
+/* Set up the uMon driver. */
+static void umoncons_init(int minor)
+{
+ rtems_umon_connect();
+}
+
+/* This is used for putchark support */
+static void umoncons_write_polled(int minor, char c)
+{
+ mon_putchar( c );
+}
+
+/* This is for setting baud rate, bits, etc. */
+static int umoncons_set_attributes(int minor, const struct termios *t)
+{
+ return 0;
+}
+
+/***********************************************************************/
+/*
+ * The following functions are not used by TERMIOS, but other RTEMS
+ * functions use them instead.
+ */
+/***********************************************************************/
+/*
+ * Read from UART. This is used in the exit code, and can't
+ * rely on interrupts.
+*/
+int umoncons_poll_read(int minor)
+{
+ if (!mon_gotachar())
+ return -1;
+ return mon_getchar();
+}
diff --git a/bsps/arm/csb337/umon/umonrtemsglue.c b/bsps/arm/csb337/umon/umonrtemsglue.c
new file mode 100644
index 0000000000..54d210c34f
--- /dev/null
+++ b/bsps/arm/csb337/umon/umonrtemsglue.c
@@ -0,0 +1,34 @@
+/*
+ * COPYRIGHT (c) 1989-2009.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * Modified by Fernando Nicodemos <fgnicodemos@terra.com.br>
+ * from NCB - Sistemas Embarcados Ltda. (Brazil)
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+*/
+
+#include <rtems/umon.h>
+
+/* XXX eventually add lock/unlock methods */
+
+static int rtems_umon_connected = 0;
+
+void rtems_umon_connect(void)
+{
+ int(*moncomptr)(int,void *,void *,void *);
+
+ if ( rtems_umon_connected )
+ return;
+
+ rtems_umon_connected = 1;
+
+ moncomptr = rtems_bsp_get_umon_monptr();
+ monConnect(
+ moncomptr, /* monitor base */
+ (void *)0, /* lock */
+ (void *)0 /* unlock */
+ );
+}