diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2018-04-03 16:24:31 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2018-04-09 07:09:46 +0200 |
commit | 671c31fc5d20a82bf39cdcd2a105daa65e0eb555 (patch) | |
tree | 503811ce9bb9e8597c55602773a9b8e350a81c34 /bsps/arm/csb337 | |
parent | Allow rtems-bsps to be run from any path. (diff) | |
download | rtems-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/README | 50 | ||||
-rw-r--r-- | bsps/arm/csb337/umon/doxygen.h | 7 | ||||
-rw-r--r-- | bsps/arm/csb337/umon/monlib.c | 1166 | ||||
-rw-r--r-- | bsps/arm/csb337/umon/tfsDriver.c | 683 | ||||
-rw-r--r-- | bsps/arm/csb337/umon/umoncons.c | 131 | ||||
-rw-r--r-- | bsps/arm/csb337/umon/umonrtemsglue.c | 34 |
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 */ + ); +} |