forked from Imagelibrary/rtems
2009-06-12 Joel Sherrill <joel.sherrill@OARcorp.com>
* umon/README, umon/cli.h, umon/monlib.c, umon/monlib.h, umon/tfs.h, umon/tfsDriver.c, umon/umonrtemsglue.c: New files.
This commit is contained in:
@@ -1,3 +1,8 @@
|
|||||||
|
2009-06-12 Joel Sherrill <joel.sherrill@OARcorp.com>
|
||||||
|
|
||||||
|
* umon/README, umon/cli.h, umon/monlib.c, umon/monlib.h, umon/tfs.h,
|
||||||
|
umon/tfsDriver.c, umon/umonrtemsglue.c: New files.
|
||||||
|
|
||||||
2009-05-27 Sebastian Huber <sebastian.huber@embedded-brains.de>
|
2009-05-27 Sebastian Huber <sebastian.huber@embedded-brains.de>
|
||||||
|
|
||||||
* tod.h, tod.c: Update for new RTC driver interface.
|
* tod.h, tod.c: Update for new RTC driver interface.
|
||||||
|
|||||||
47
c/src/lib/libbsp/shared/umon/README
Normal file
47
c/src/lib/libbsp/shared/umon/README
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
#
|
||||||
|
# $Id$
|
||||||
|
#
|
||||||
|
|
||||||
|
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
|
||||||
123
c/src/lib/libbsp/shared/umon/cli.h
Normal file
123
c/src/lib/libbsp/shared/umon/cli.h
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
/* cli.h:
|
||||||
|
* Header file for Command Line Interface related stuff.
|
||||||
|
*
|
||||||
|
* 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@lucent.com
|
||||||
|
* Phone: 908-582-2351
|
||||||
|
*/
|
||||||
|
#ifndef _cli_h
|
||||||
|
#define _cli_h
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Command table structure used by the monitor:
|
||||||
|
*/
|
||||||
|
struct monCommand {
|
||||||
|
char *name; /* Name of command seen by user. */
|
||||||
|
int (*func)(int,char **); /* Called when command is invoked. */
|
||||||
|
char **helptxt; /* Help text (see notes below). */
|
||||||
|
long flags; /* Single-bit flags for various uses */
|
||||||
|
/* (see the CMDFLAG_XXX macros). */
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Bits currently assigned to command flags used in the monCommand
|
||||||
|
* structure...
|
||||||
|
*/
|
||||||
|
#define CMDFLAG_NOMONRC 1
|
||||||
|
|
||||||
|
/* Maximum size of a command line:
|
||||||
|
*/
|
||||||
|
#ifndef CMDLINESIZE
|
||||||
|
#define CMDLINESIZE 128
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Maximum number of arguments in a command line:
|
||||||
|
*/
|
||||||
|
#define ARGCNT 24
|
||||||
|
|
||||||
|
/* Definitions for docommand() return values:
|
||||||
|
*
|
||||||
|
* Note that the CMD_SUCCESS, CMD_FAILURE and CMD_PARAM_ERROR are return
|
||||||
|
* values used by the local command code also. The remaining errors
|
||||||
|
* (CMD_LINE_ERROR, CMD_ULVL_DENIED and CMD_NOT_FOUND) are used only by
|
||||||
|
# the docommand() function.
|
||||||
|
*
|
||||||
|
* CMD_SUCCESS:
|
||||||
|
* Everything worked ok.
|
||||||
|
* CMD_FAILURE:
|
||||||
|
* Command parameters were valid, but command itself failed for some other
|
||||||
|
* reason. The docommand() function does not print a message here, it
|
||||||
|
* is assumed that the error message was printed by the local function.
|
||||||
|
* CMD_PARAM_ERROR:
|
||||||
|
* Command line did not parse properly. Control was passed to a
|
||||||
|
* local command function, but argument syntax caused it to choke.
|
||||||
|
* In this case docommand() will print out the generic CLI syntax error
|
||||||
|
* message.
|
||||||
|
* CMD_LINE_ERROR:
|
||||||
|
* Command line itself was invalid. Too many args, invalid shell var
|
||||||
|
* syntax, etc.. Somekind of command line error prior to checking for
|
||||||
|
* the command name-to-function match.
|
||||||
|
* CMD_ULVL_DENIED:
|
||||||
|
* Command's user level is higher than current user level, so access
|
||||||
|
* is denied.
|
||||||
|
* CMD_NOT_FOUND:
|
||||||
|
* Since these same return values are used for each command function
|
||||||
|
* plus the docommand() function, this error indicates that docommand()
|
||||||
|
* could not even find the command in the command table.
|
||||||
|
* CMD_MONRC_DENIED:
|
||||||
|
* The command cannot execute because it is considered illegal
|
||||||
|
* when run from within the monrc file.
|
||||||
|
*/
|
||||||
|
#define CMD_SUCCESS 0
|
||||||
|
#define CMD_FAILURE -1
|
||||||
|
#define CMD_PARAM_ERROR -2
|
||||||
|
#define CMD_LINE_ERROR -3
|
||||||
|
#define CMD_ULVL_DENIED -4
|
||||||
|
#define CMD_NOT_FOUND -5
|
||||||
|
#define CMD_MONRC_DENIED -6
|
||||||
|
|
||||||
|
/* Notes on help text array:
|
||||||
|
* The monitor's CLI processor assumes that every command's help text
|
||||||
|
* array abides by a few basic rules...
|
||||||
|
* First of all, it assumes that every array has AT LEAST two strings.
|
||||||
|
* The first string in the array of strings is assumed to be a one-line
|
||||||
|
* abstract describing the command.
|
||||||
|
* The second string in the array of strings is assumed to be a usage
|
||||||
|
* message that describes the syntax of the arguments needed by the command.
|
||||||
|
* If this second string is an empty string (""), the docommand() prints out
|
||||||
|
* a generic usage string indicating that there are no options or arguements
|
||||||
|
* to apply to the command.
|
||||||
|
* All remaining lines are formatted based on the needs of the individual
|
||||||
|
* command and the final string is a null pointer to let the CLI processor
|
||||||
|
* know where the end is.
|
||||||
|
* Following is an example help text array...
|
||||||
|
*
|
||||||
|
* char *HelpHelp[] = {
|
||||||
|
* "Display command set",
|
||||||
|
* "-[d] [commandname]",
|
||||||
|
* "Options:",
|
||||||
|
* " -d list commands and descriptions",
|
||||||
|
* 0,
|
||||||
|
* };
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#endif
|
||||||
1128
c/src/lib/libbsp/shared/umon/monlib.c
Normal file
1128
c/src/lib/libbsp/shared/umon/monlib.c
Normal file
File diff suppressed because it is too large
Load Diff
262
c/src/lib/libbsp/shared/umon/monlib.h
Normal file
262
c/src/lib/libbsp/shared/umon/monlib.h
Normal file
@@ -0,0 +1,262 @@
|
|||||||
|
/* monlib.h:
|
||||||
|
* This header file is used by both the monitor and the application that
|
||||||
|
* may reside on top of the monitor.
|
||||||
|
* 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@lucent.com
|
||||||
|
* Phone: 908-582-2351
|
||||||
|
*/
|
||||||
|
#ifndef _MONLIB_H_
|
||||||
|
#define _MONLIB_H_
|
||||||
|
|
||||||
|
#include <umon/tfs.h>
|
||||||
|
#include <umon/cli.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The following additions are RTEMS specific.
|
||||||
|
*/
|
||||||
|
#if defined(__rtems__)
|
||||||
|
/*
|
||||||
|
* RTEMS uMonitor wrapper for monConnect(). This will deal with the
|
||||||
|
* getting MONCOMPTR as well as providing the locking routines.
|
||||||
|
*/
|
||||||
|
void rtems_umon_connect(void);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* BSP specific routine to help when calling monConnect(). This
|
||||||
|
* returns the value known to uMon as MONCOMPTR.
|
||||||
|
*/
|
||||||
|
void *rtems_bsp_get_umon_monptr(void);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialize the TFS-RTEMS file system
|
||||||
|
*/
|
||||||
|
int rtems_initialize_tfs_filesystem(
|
||||||
|
const char *path
|
||||||
|
);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern int monConnect(int (*monptr)(int,void *,void *,void *),
|
||||||
|
void (*lock)(void),void (*unlock)(void));
|
||||||
|
extern void mon_getargv(int *argc,char ***argv);
|
||||||
|
extern void mon_intsrestore(unsigned long oldval);
|
||||||
|
extern void mon_appexit(int exit_value);
|
||||||
|
extern void mon_free(char *buffer);
|
||||||
|
extern void mon_profiler(void *pdata);
|
||||||
|
extern void mon_bbc(char *filename, int linenum);
|
||||||
|
extern void mon_warmstart(unsigned long mask);
|
||||||
|
extern void mon_delay(long msec);
|
||||||
|
extern void mon_printpkt(char *buf, int size, int incoming);
|
||||||
|
extern void mon_printmem(char *mem, int size, int ascii);
|
||||||
|
|
||||||
|
|
||||||
|
extern int mon_com(int cmd,void *arg1,void *arg2,void *arg3);
|
||||||
|
extern int mon_timer(int cmd, void * arg);
|
||||||
|
extern int mon_setenv(char *varname,char *value);
|
||||||
|
extern int mon_putchar(char c);
|
||||||
|
extern int mon_getchar(void);
|
||||||
|
extern int mon_gotachar(void);
|
||||||
|
extern int mon_getbytes(char *buf,int count,int block);
|
||||||
|
extern int mon_restart(int restart_value);
|
||||||
|
extern int mon_tfsinit(void);
|
||||||
|
extern int mon_tfsunlink(char *filename);
|
||||||
|
extern int mon_tfslink(char *source, char *target);
|
||||||
|
extern int mon_tfsrun(char **arglist,int verbosity);
|
||||||
|
extern int mon_tfsfstat(char *filename,struct tfshdr *tfp);
|
||||||
|
extern int mon_tfseof(int file_descriptor);
|
||||||
|
extern int mon_tfstruncate(int file_descriptor,long length);
|
||||||
|
extern int mon_tfsread(int file_descriptor,char *buffer,int size);
|
||||||
|
extern int mon_tfswrite(int file_descriptor,char *buffer,int size);
|
||||||
|
extern int mon_tfsopen(char *filename,long mode,char *buffer);
|
||||||
|
extern int mon_tfsclose(int file_descriptor,char *info);
|
||||||
|
extern int mon_tfsseek(int file_descriptor,int offset,int whence);
|
||||||
|
extern int mon_tfsgetline(int file_descriptor,char *buffer,int bufsize);
|
||||||
|
extern int mon_tfsipmod(char *name,char *buffer,int offset,int size);
|
||||||
|
extern int mon_addcommand(struct monCommand *command_list,char *);
|
||||||
|
extern int mon_docommand(char *cmdline,int verbosity);
|
||||||
|
extern int mon_getline(char *buffer,int max,int ledit);
|
||||||
|
extern int mon_decompress(char *src,int srcsize,char *dest);
|
||||||
|
extern int mon_heapextend(char *base,int size);
|
||||||
|
extern int mon_pcicfgwrite(int interface,int bus,int dev,int func,int reg,
|
||||||
|
unsigned long val);
|
||||||
|
extern int mon_tfsadd(char *filename, char *info, char *flags,
|
||||||
|
unsigned char *src, int size);
|
||||||
|
extern int mon_i2cwrite(int interface, int bigaddr, unsigned char *data,
|
||||||
|
int len);
|
||||||
|
extern int mon_i2cread(int interface, int bigaddr, unsigned char *data,
|
||||||
|
int len);
|
||||||
|
extern int mon_sendenetpkt(char *pkt, int len);
|
||||||
|
extern int mon_recvenetpkt(char *pkt, int len);
|
||||||
|
extern int mon_flashoverride(void *flashinfo, int get, int bank);
|
||||||
|
extern int mon_flasherase(int snum);
|
||||||
|
extern int mon_flashwrite(char *dest,char *src, int bytecnt);
|
||||||
|
extern int mon_flashinfo(int snum,int *size, char **base);
|
||||||
|
extern int mon_watchdog(void);
|
||||||
|
extern int mon_timeofday(int cmd, void *arg);
|
||||||
|
|
||||||
|
extern char *mon_getsym(char *symname, char *buf, int bufsize);
|
||||||
|
extern char *mon_getenv(char *varname);
|
||||||
|
extern char *mon_getenvp(void);
|
||||||
|
extern char *mon_version(void);
|
||||||
|
#ifdef MALLOC_DEBUG
|
||||||
|
extern char *mon_malloc(int size,char *file, int line);
|
||||||
|
extern char *mon_realloc(char *buf,int size,char *file, int line);
|
||||||
|
#else
|
||||||
|
extern char *mon_malloc(int size);
|
||||||
|
extern char *mon_realloc(char *buf,int size);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern long mon_tfsctrl(int command,long arg1,long arg2);
|
||||||
|
extern long mon_tfstell(int file_descriptor);
|
||||||
|
extern long mon_portcmd(int cmd, void *arg);
|
||||||
|
|
||||||
|
extern unsigned short mon_xcrc16(char *buffer,long length);
|
||||||
|
|
||||||
|
extern unsigned long mon_intsoff(void);
|
||||||
|
|
||||||
|
extern unsigned long mon_pcicfgread(int interface,int bus,int dev,
|
||||||
|
int func,int reg);
|
||||||
|
|
||||||
|
extern unsigned long mon_pcictrl(int interface, int cmd,
|
||||||
|
unsigned long arg1, unsigned long arg2);
|
||||||
|
|
||||||
|
extern unsigned long mon_i2cctrl(int interface, int cmd,
|
||||||
|
unsigned long arg1, unsigned long arg2);
|
||||||
|
|
||||||
|
extern unsigned long mon_assignhandler(long hnum,
|
||||||
|
unsigned long arg1,unsigned long arg2);
|
||||||
|
|
||||||
|
extern struct tfshdr *mon_tfsnext(struct tfshdr *tfp);
|
||||||
|
extern struct tfshdr *mon_tfsstat(char *filename);
|
||||||
|
|
||||||
|
#if SHOWVARARGS
|
||||||
|
extern void mon_memtrace(char *fmt, ...);
|
||||||
|
extern int mon_printf(char *fmt, ...);
|
||||||
|
extern int mon_cprintf(char *fmt, ...);
|
||||||
|
extern int mon_sprintf(char *,char *fmt, ...);
|
||||||
|
#else
|
||||||
|
extern void mon_memtrace();
|
||||||
|
extern int mon_printf();
|
||||||
|
extern int mon_cprintf();
|
||||||
|
extern int mon_sprintf();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* defines used by monConnect():
|
||||||
|
*/
|
||||||
|
#define GETMONFUNC_PUTCHAR 1
|
||||||
|
#define GETMONFUNC_GETCHAR 2
|
||||||
|
#define GETMONFUNC_GOTACHAR 3
|
||||||
|
#define GETMONFUNC_GETBYTES 4
|
||||||
|
#define GETMONFUNC_PRINTF 5
|
||||||
|
#define GETMONFUNC_CPRINTF 6
|
||||||
|
#define GETMONFUNC_SPRINTF 7
|
||||||
|
#define GETMONFUNC_RESTART 8
|
||||||
|
#define GETMONFUNC_GETENV 9
|
||||||
|
#define GETMONFUNC_SETENV 10
|
||||||
|
#define GETMONFUNC_TFSINIT 11
|
||||||
|
#define GETMONFUNC_TFSADD 12
|
||||||
|
#define GETMONFUNC_TFSUNLINK 13
|
||||||
|
#define GETMONFUNC_TFSRUN 14
|
||||||
|
#define GETMONFUNC_TFSNEXT 15
|
||||||
|
#define GETMONFUNC_TFSSTAT 16
|
||||||
|
#define GETMONFUNC_TFSREAD 17
|
||||||
|
#define GETMONFUNC_TFSWRITE 18
|
||||||
|
#define GETMONFUNC_TFSOPEN 19
|
||||||
|
#define GETMONFUNC_TFSCLOSE 20
|
||||||
|
#define GETMONFUNC_TFSSEEK 21
|
||||||
|
#define GETMONFUNC_TFSGETLINE 22
|
||||||
|
#define GETMONFUNC_TFSIPMOD 23
|
||||||
|
#define GETMONFUNC_TFSCTRL 24
|
||||||
|
#define GETMONFUNC_ADDCOMMAND 25
|
||||||
|
#define GETMONFUNC_DOCOMMAND 26
|
||||||
|
#define GETMONFUNC_GETARGV 27
|
||||||
|
#define GETMONFUNC_CRC16 28
|
||||||
|
#define GETMONFUNC_CRC32 29
|
||||||
|
#define GETMONFUNC_PIOGET 30 /* NA (removed as of 1.0) */
|
||||||
|
#define GETMONFUNC_PIOSET 31 /* NA (removed as of 1.0) */
|
||||||
|
#define GETMONFUNC_PIOCLR 32 /* NA (removed as of 1.0) */
|
||||||
|
#define GETMONFUNC_INTSOFF 33
|
||||||
|
#define GETMONFUNC_INTSRESTORE 34
|
||||||
|
#define GETMONFUNC_APPEXIT 35
|
||||||
|
#define GETMONFUNC_MALLOC 36
|
||||||
|
#define GETMONFUNC_FREE 37
|
||||||
|
#define GETMONFUNC_GETLINE 38
|
||||||
|
#define GETMONFUNC_TFSFSTAT 39
|
||||||
|
#define GETMONFUNC_TFSEOF 40
|
||||||
|
#define GETMONFUNC_DECOMPRESS 41
|
||||||
|
#define GETMONFUNC_TFSTRUNCATE 42
|
||||||
|
#define GETMONFUNC_HEAPXTEND 43
|
||||||
|
#define GETMONFUNC_PROFILER 44
|
||||||
|
#define GETMONFUNC_TFSLINK 45
|
||||||
|
#define GETMONFUNC_BBC 46
|
||||||
|
#define GETMONFUNC_MEMTRACE 47
|
||||||
|
#define GETMONFUNC_TFSTELL 48
|
||||||
|
#define GETMONFUNC_VERSION 49
|
||||||
|
#define GETMONFUNC_WARMSTART 50
|
||||||
|
#define GETMONFUNC_PCICFGREAD 51
|
||||||
|
#define GETMONFUNC_PCICFGWRITE 52
|
||||||
|
#define GETMONFUNC_PCICONTROL 53
|
||||||
|
#define GETMONFUNC_I2CREAD 54
|
||||||
|
#define GETMONFUNC_I2CWRITE 55
|
||||||
|
#define GETMONFUNC_I2CCONTROL 56
|
||||||
|
#define GETMONFUNC_MONDELAY 57
|
||||||
|
#define GETMONFUNC_GETENVP 58
|
||||||
|
#define GETMONFUNC_REALLOC 59
|
||||||
|
#define GETMONFUNC_SENDENETPKT 60
|
||||||
|
#define GETMONFUNC_RECVENETPKT 61
|
||||||
|
#define GETMONFUNC_GETSYM 62
|
||||||
|
#define GETMONFUNC_PRINTPKT 63
|
||||||
|
#define GETMONFUNC_FLASHWRITE 64
|
||||||
|
#define GETMONFUNC_FLASHERASE 65
|
||||||
|
#define GETMONFUNC_FLASHINFO 66
|
||||||
|
#define GETMONFUNC_ASSIGNHDLR 67
|
||||||
|
#define GETMONFUNC_WATCHDOG 68
|
||||||
|
#define GETMONFUNC_PRINTMEM 69
|
||||||
|
#define GETMONFUNC_PORTCMD 70
|
||||||
|
#define GETMONFUNC_TIMEOFDAY 71
|
||||||
|
#define GETMONFUNC_TIMER 72
|
||||||
|
#define GETMONFUNC_FLASHOVRRD 73
|
||||||
|
|
||||||
|
#define CACHEFTYPE_DFLUSH 200
|
||||||
|
#define CACHEFTYPE_IINVALIDATE 201
|
||||||
|
|
||||||
|
#define CHARFUNC_PUTCHAR 300
|
||||||
|
#define CHARFUNC_GETCHAR 301
|
||||||
|
#define CHARFUNC_GOTACHAR 302
|
||||||
|
#define CHARFUNC_RAWMODEON 303
|
||||||
|
#define CHARFUNC_RAWMODEOFF 304
|
||||||
|
|
||||||
|
#define ASSIGNFUNC_GETUSERLEVEL 400
|
||||||
|
|
||||||
|
|
||||||
|
/* Defines used by mon_warmstart():
|
||||||
|
*/
|
||||||
|
#define WARMSTART_IOINIT 0x00000001
|
||||||
|
#define WARMSTART_BSSINIT 0x00000002
|
||||||
|
#define WARMSTART_RUNMONRC 0x00000004
|
||||||
|
#define WARMSTART_MONHEADER 0x00000008
|
||||||
|
#define WARMSTART_TFSAUTOBOOT 0x00000010
|
||||||
|
#define WARMSTART_BOARDINFO 0x00000020
|
||||||
|
#define WARMSTART_ALL 0xffffffff
|
||||||
|
#endif
|
||||||
187
c/src/lib/libbsp/shared/umon/tfs.h
Normal file
187
c/src/lib/libbsp/shared/umon/tfs.h
Normal file
@@ -0,0 +1,187 @@
|
|||||||
|
/* tfs.h:
|
||||||
|
* Header file for TFS transactions, used by both application and monitor.
|
||||||
|
*
|
||||||
|
* 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@lucent.com
|
||||||
|
* Phone: 908-582-2351
|
||||||
|
*/
|
||||||
|
#ifndef _tfs_h
|
||||||
|
#define _tfs_h
|
||||||
|
|
||||||
|
#define TFSINFOSIZE 23 /* Max size of info string (mod4-1). */
|
||||||
|
|
||||||
|
#ifndef TFSNAMESIZE /* This specifies the maximum size of a file */
|
||||||
|
#define TFSNAMESIZE 23 /* name that can be used in TFS. */
|
||||||
|
#endif /* This MUST be some value mod4 - 1. */
|
||||||
|
|
||||||
|
#ifndef TFS_CHANGELOG_FILE /* Information used for change-log */
|
||||||
|
#define TFS_CHANGELOG_SIZE 0 /* facility within tfs. */
|
||||||
|
#define TFS_CHANGELOG_FILE ".tfschlog"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SYMFILE /* This specifies the default filename */
|
||||||
|
#define SYMFILE "symtbl" /* used by the monitor for the symbol */
|
||||||
|
#endif /* table. */
|
||||||
|
|
||||||
|
#define MINUSRLEVEL 0 /* Minimum user level supported. */
|
||||||
|
#define MAXUSRLEVEL 3 /* Maximum user level supported. */
|
||||||
|
|
||||||
|
#ifndef TFS_RESERVED
|
||||||
|
#define TFS_RESERVED 4 /* Number of "reserved" entries (ulong) */
|
||||||
|
#endif /* in the TFS header. */
|
||||||
|
|
||||||
|
|
||||||
|
/* Flags: */
|
||||||
|
#define TFS_EXEC 0x00000001 /* 'e': Executable script. */
|
||||||
|
#define TFS_BRUN 0x00000002 /* 'b': To be executed at boot. */
|
||||||
|
#define TFS_QRYBRUN 0x00000004 /* 'B': To be executed at boot if */
|
||||||
|
/* query passes. */
|
||||||
|
#define TFS_SYMLINK 0x00000008 /* 'l': Symbolic link file. */
|
||||||
|
#define TFS_EBIN 0x00000010 /* 'E': Executable binary (coff/elf/a.out). */
|
||||||
|
#define TFS_CPRS 0x00000040 /* 'c': File is compressed. */
|
||||||
|
#define TFS_IPMOD 0x00000080 /* 'i': File is in-place modifiable. */
|
||||||
|
#define TFS_UNREAD 0x00000100 /* 'u': File is not even readable if the */
|
||||||
|
/* user-level requirement is not met; */
|
||||||
|
/* else, it is read-only. */
|
||||||
|
#define TFS_ULVLMSK 0x00000600 /* User level mask defines 4 access levels: */
|
||||||
|
#define TFS_ULVL0 0x00000000 /* '0' level 0 */
|
||||||
|
#define TFS_ULVL1 0x00000200 /* '1' level 1 */
|
||||||
|
#define TFS_ULVL2 0x00000400 /* '2' level 2 */
|
||||||
|
#define TFS_ULVL3 0x00000600 /* '3' level 3 */
|
||||||
|
#define TFS_NSTALE 0x00000800 /* File is NOT stale, invisible to user.
|
||||||
|
* When this bit is clear, the file is
|
||||||
|
* considered stale (see notes in tfsadd()).
|
||||||
|
* See notes in tfsclose() for this.
|
||||||
|
*/
|
||||||
|
#define TFS_ACTIVE 0x00008000 /* Used to indicate that file is not deleted. */
|
||||||
|
|
||||||
|
#define TFS_ULVLMAX TFS_ULVL3
|
||||||
|
#define TFS_USRLVL(f) ((f->flags & TFS_ULVLMSK) >> 9)
|
||||||
|
|
||||||
|
/* Open modes */
|
||||||
|
#define TFS_RDONLY 0x00010000 /* File is opened for reading. */
|
||||||
|
#define TFS_CREATE 0x00020000 /* File is to be created. Error if file */
|
||||||
|
/* with the same name already exists. */
|
||||||
|
#define TFS_APPEND 0x00040000 /* Append to existing file. If OR'ed */
|
||||||
|
/* with TFS_CREATE, then create if */
|
||||||
|
/* necessary. */
|
||||||
|
#define TFS_ALLFFS 0x00080000 /* File is created with all FFs. */
|
||||||
|
#define TFS_CREATERM 0x00100000 /* File is to be created. If file with */
|
||||||
|
/* same name already exists, then allow */
|
||||||
|
/* tfsadd() to remove it if necessary. */
|
||||||
|
|
||||||
|
/* The function tfsrunrc() will search through the current file set and */
|
||||||
|
/* if the file defined by TFS_RCFILE exists, it will be executed. */
|
||||||
|
/* If this file exists, it will NOT be run by tfsrunboot(). */
|
||||||
|
#define TFS_RCFILE "monrc"
|
||||||
|
|
||||||
|
/* Requests that can be made to tfsctrl(): */
|
||||||
|
#define TFS_ERRMSG 1
|
||||||
|
#define TFS_MEMUSE 2
|
||||||
|
#define TFS_MEMDEAD 3
|
||||||
|
#define TFS_DEFRAG 4
|
||||||
|
#define TFS_TELL 5
|
||||||
|
#define TFS_UNOPEN 7
|
||||||
|
#define TFS_FATOB 8
|
||||||
|
#define TFS_FBTOA 9
|
||||||
|
#define TFS_MEMAVAIL 10
|
||||||
|
#define TFS_TIMEFUNCS 11
|
||||||
|
#define TFS_DOCOMMAND 12
|
||||||
|
#define TFS_INITDEV 13
|
||||||
|
#define TFS_CHECKDEV 14
|
||||||
|
#define TFS_DEFRAGDEV 15
|
||||||
|
#define TFS_DEFRAGOFF 16
|
||||||
|
#define TFS_DEFRAGON 17
|
||||||
|
#define TFS_HEADROOM 18
|
||||||
|
#define TFS_FCOUNT 19
|
||||||
|
|
||||||
|
/* struct tfshdr:
|
||||||
|
* It is in FLASH as part of the file system to record the attributes of
|
||||||
|
* the file at the time of creation.
|
||||||
|
*/
|
||||||
|
struct tfshdr {
|
||||||
|
unsigned short hdrsize; /* Size of this header. */
|
||||||
|
unsigned short hdrvrsn; /* Header version #. */
|
||||||
|
long filsize; /* Size of the file. */
|
||||||
|
long flags; /* Flags describing the file. */
|
||||||
|
unsigned long filcrc; /* 32 bit CRC of file. */
|
||||||
|
unsigned long hdrcrc; /* 32 bit CRC of the header. */
|
||||||
|
unsigned long modtime; /* Time when file was last modified. */
|
||||||
|
struct tfshdr *next; /* Pointer to next file in list. */
|
||||||
|
char name[TFSNAMESIZE+1]; /* Name of file. */
|
||||||
|
char info[TFSINFOSIZE+1]; /* Miscellaneous info field. */
|
||||||
|
#if TFS_RESERVED
|
||||||
|
unsigned long rsvd[TFS_RESERVED];
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
#define TFSHDRSIZ sizeof(struct tfshdr)
|
||||||
|
|
||||||
|
/* TFS error returns. */
|
||||||
|
#define TFS_OKAY 0
|
||||||
|
#define TFSERR_NOFILE -1
|
||||||
|
#define TFSERR_NOSLOT -2
|
||||||
|
#define TFSERR_EOF -3
|
||||||
|
#define TFSERR_BADARG -4
|
||||||
|
#define TFSERR_NOTEXEC -5
|
||||||
|
#define TFSERR_BADCRC -6
|
||||||
|
#define TFSERR_FILEEXISTS -7
|
||||||
|
#define TFSERR_FLASHFAILURE -8
|
||||||
|
#define TFSERR_WRITEMAX -9
|
||||||
|
#define TFSERR_RDONLY -10
|
||||||
|
#define TFSERR_BADFD -11
|
||||||
|
#define TFSERR_BADHDR -12
|
||||||
|
#define TFSERR_CORRUPT -13
|
||||||
|
#define TFSERR_MEMFAIL -14
|
||||||
|
#define TFSERR_NOTIPMOD -16
|
||||||
|
#define TFSERR_MUTEXFAILURE -17
|
||||||
|
#define TFSERR_FLASHFULL -18
|
||||||
|
#define TFSERR_USERDENIED -19
|
||||||
|
#define TFSERR_NAMETOOBIG -20
|
||||||
|
#define TFSERR_FILEINUSE -21
|
||||||
|
#define TFSERR_NOTCPRS -22
|
||||||
|
#define TFSERR_NOTAVAILABLE -23
|
||||||
|
#define TFSERR_BADFLAG -24
|
||||||
|
#define TFSERR_CLEANOFF -25
|
||||||
|
#define TFSERR_FLAKEYSOURCE -26
|
||||||
|
#define TFSERR_BADEXTENSION -27
|
||||||
|
#define TFSERR_MIN -100
|
||||||
|
|
||||||
|
/* TFS seek options. */
|
||||||
|
#define TFS_BEGIN 1
|
||||||
|
#define TFS_CURRENT 2
|
||||||
|
#define TFS_END 3
|
||||||
|
|
||||||
|
/* Macros: */
|
||||||
|
#define TFS_DELETED(fp) (!((fp)->flags & TFS_ACTIVE))
|
||||||
|
#define TFS_FILEEXISTS(fp) ((fp)->flags & TFS_ACTIVE)
|
||||||
|
#define TFS_ISCPRS(fp) ((fp)->flags & TFS_CPRS)
|
||||||
|
#define TFS_ISEXEC(fp) ((fp)->flags & TFS_EXEC)
|
||||||
|
#define TFS_ISBOOT(fp) ((fp)->flags & TFS_BRUN)
|
||||||
|
#define TFS_ISLINK(fp) ((fp)->flags & TFS_SYMLINK)
|
||||||
|
#define TFS_STALE(fp) (!((fp)->flags & TFS_NSTALE))
|
||||||
|
#define TFS_FLAGS(fp) ((fp)->flags)
|
||||||
|
#define TFS_NAME(fp) ((fp)->name)
|
||||||
|
#define TFS_SIZE(fp) ((fp)->filsize)
|
||||||
|
#define TFS_TIME(fp) ((fp)->modtime)
|
||||||
|
#define TFS_INFO(fp) ((fp)->info)
|
||||||
|
#define TFS_NEXT(fp) ((fp)->next)
|
||||||
|
#define TFS_CRC(fp) ((fp)->filcrc)
|
||||||
|
#define TFS_ENTRY(fp) ((fp)->entry)
|
||||||
|
#define TFS_BASE(fp) ((char *)(fp)+(fp)->hdrsize)
|
||||||
|
|
||||||
|
typedef struct tfshdr TFILE;
|
||||||
|
#endif
|
||||||
726
c/src/lib/libbsp/shared/umon/tfsDriver.c
Normal file
726
c/src/lib/libbsp/shared/umon/tfsDriver.c
Normal file
@@ -0,0 +1,726 @@
|
|||||||
|
/*
|
||||||
|
* MicroMonitor TFS Hookup to RTEMS FS
|
||||||
|
*
|
||||||
|
* Initial release: Oct 1, 2004 by Ed Sutter
|
||||||
|
*
|
||||||
|
* 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 updated and merged with RTEMS CVS by Joel Sherrill, 2009.
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#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 <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];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Root node_access value
|
||||||
|
* By using the address of a local static variable
|
||||||
|
* we ensure a unique value for this identifier.
|
||||||
|
*/
|
||||||
|
#define ROOT_NODE_ACCESS (&tfs_mutex)
|
||||||
|
|
||||||
|
/* Number of streams open at the same time
|
||||||
|
*/
|
||||||
|
static rtems_id tfs_mutex;
|
||||||
|
|
||||||
|
extern rtems_filesystem_operations_table rtems_tfs_ops;
|
||||||
|
extern rtems_filesystem_file_handlers_r rtems_tfs_handlers;
|
||||||
|
|
||||||
|
/* Direct copy from the IMFS. Look at this.
|
||||||
|
*/
|
||||||
|
|
||||||
|
rtems_filesystem_limits_and_options_t rtems_tfs_limits_and_options = {
|
||||||
|
5, /* link_max */
|
||||||
|
6, /* max_canon */
|
||||||
|
7, /* max_input */
|
||||||
|
255, /* name_max */
|
||||||
|
255, /* path_max */
|
||||||
|
2, /* pipe_buf */
|
||||||
|
1, /* posix_async_io */
|
||||||
|
2, /* posix_chown_restrictions */
|
||||||
|
3, /* posix_no_trunc */
|
||||||
|
4, /* posix_prio_io */
|
||||||
|
5, /* posix_sync_io */
|
||||||
|
6 /* posix_vdisable */
|
||||||
|
};
|
||||||
|
|
||||||
|
static int rtems_tfs_mount_me(
|
||||||
|
rtems_filesystem_mount_table_entry_t *temp_mt_entry
|
||||||
|
)
|
||||||
|
{
|
||||||
|
rtems_status_code sc;
|
||||||
|
|
||||||
|
temp_mt_entry->mt_fs_root.handlers = &rtems_tfs_handlers;
|
||||||
|
temp_mt_entry->mt_fs_root.ops = &rtems_tfs_ops;
|
||||||
|
|
||||||
|
/* We have no TFS specific data to maintain. This filesystem
|
||||||
|
* may only be mounted once. And we maintain no real filesystem
|
||||||
|
* nodes, so there is no real root.
|
||||||
|
*/
|
||||||
|
|
||||||
|
temp_mt_entry->fs_info = NULL;
|
||||||
|
temp_mt_entry->mt_fs_root.node_access = ROOT_NODE_ACCESS;
|
||||||
|
|
||||||
|
/* These need to be looked at for full POSIX semantics.
|
||||||
|
*/
|
||||||
|
|
||||||
|
temp_mt_entry->pathconf_limits_and_options = rtems_tfs_limits_and_options;
|
||||||
|
|
||||||
|
|
||||||
|
/* Now allocate a semaphore for mutual exclusion.
|
||||||
|
* NOTE: This could be in an fsinfo for this filesystem type.
|
||||||
|
*/
|
||||||
|
|
||||||
|
sc = rtems_semaphore_create (
|
||||||
|
rtems_build_name('U', 'M', 'O', 'N'),
|
||||||
|
1,
|
||||||
|
RTEMS_FIFO |
|
||||||
|
RTEMS_BINARY_SEMAPHORE |
|
||||||
|
RTEMS_NO_INHERIT_PRIORITY |
|
||||||
|
RTEMS_NO_PRIORITY_CEILING |
|
||||||
|
RTEMS_LOCAL,
|
||||||
|
0,
|
||||||
|
&tfs_mutex);
|
||||||
|
|
||||||
|
if (sc != RTEMS_SUCCESSFUL)
|
||||||
|
rtems_set_errno_and_return_minus_one( ENOMEM );
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize the TFS-RTEMS file system
|
||||||
|
*/
|
||||||
|
int rtems_initialize_tfs_filesystem(
|
||||||
|
const char *path
|
||||||
|
)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
rtems_filesystem_mount_table_entry_t *entry;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = mount( &entry, &rtems_tfs_ops, RTEMS_FILESYSTEM_READ_WRITE,
|
||||||
|
NULL, TFS_PATHNAME_PREFIX);
|
||||||
|
|
||||||
|
if (status) {
|
||||||
|
printk( "TFS: Unable to mount on %s\n", TFS_PATHNAME_PREFIX );
|
||||||
|
perror("TFS mount failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
return(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rtems_tfs_evaluate_for_make(
|
||||||
|
const char *path,
|
||||||
|
rtems_filesystem_location_info_t *pathloc,
|
||||||
|
const char **name
|
||||||
|
)
|
||||||
|
{
|
||||||
|
pathloc->node_access = NULL;
|
||||||
|
rtems_set_errno_and_return_minus_one( EIO );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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 int rtems_tfs_eval_path(
|
||||||
|
const char *pathname,
|
||||||
|
int flags,
|
||||||
|
rtems_filesystem_location_info_t *pathloc
|
||||||
|
)
|
||||||
|
{
|
||||||
|
pathloc->handlers = &rtems_tfs_handlers;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Hack to provide the illusion of directories inside the TFS file system.
|
||||||
|
* Paths ending in a / are assumed to be directories.
|
||||||
|
*/
|
||||||
|
if (pathname[strlen(pathname)-1] == '/') {
|
||||||
|
int isRelative = (pathloc->node_access != ROOT_NODE_ACCESS);
|
||||||
|
char *cp;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Reject attempts to open() directories
|
||||||
|
*/
|
||||||
|
if (flags & RTEMS_LIBIO_PERMS_RDWR)
|
||||||
|
rtems_set_errno_and_return_minus_one( EISDIR );
|
||||||
|
if (isRelative) {
|
||||||
|
cp = malloc (strlen(pathloc->node_access)+strlen(pathname)+1);
|
||||||
|
if (cp == NULL)
|
||||||
|
rtems_set_errno_and_return_minus_one( ENOMEM );
|
||||||
|
strcpy (cp, pathloc->node_access);
|
||||||
|
strcat (cp, pathname);
|
||||||
|
} else {
|
||||||
|
cp = strdup (pathname);
|
||||||
|
if (cp == NULL)
|
||||||
|
rtems_set_errno_and_return_minus_one( ENOMEM );
|
||||||
|
}
|
||||||
|
fixPath (cp);
|
||||||
|
pathloc->node_access = cp;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (pathloc->node_access != ROOT_NODE_ACCESS)
|
||||||
|
pathloc->node_access = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Reject it if it's not read-only or write-only.
|
||||||
|
*/
|
||||||
|
flags &= RTEMS_LIBIO_PERMS_READ | RTEMS_LIBIO_PERMS_WRITE;
|
||||||
|
if ((flags != RTEMS_LIBIO_PERMS_READ) && (flags != RTEMS_LIBIO_PERMS_WRITE) )
|
||||||
|
rtems_set_errno_and_return_minus_one( EINVAL );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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,
|
||||||
|
uint32_t flags,
|
||||||
|
uint32_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%" PRIx32 ",0x%" PRIx32 ")\n",path,flags,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 ((flags & (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(flags & 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%" PRIx32 " not supported\n",flags);
|
||||||
|
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->file_info = (void *)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,
|
||||||
|
uint32_t flags,
|
||||||
|
uint32_t mode
|
||||||
|
)
|
||||||
|
{
|
||||||
|
char *full_path_name;
|
||||||
|
char *s1;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
if (RTEMS_TFS_DEBUG)
|
||||||
|
printk("rtems_tfs_open(%s)\n",new_name);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tack the `current directory' on to relative paths.
|
||||||
|
* We know that the current directory ends in a / character.
|
||||||
|
*/
|
||||||
|
if (*new_name == '/') {
|
||||||
|
/*
|
||||||
|
* Skip the TFS filesystem prefix.
|
||||||
|
*/
|
||||||
|
int len = strlen (TFS_PATHNAME_PREFIX);
|
||||||
|
if (strncmp (new_name, TFS_PATHNAME_PREFIX, len))
|
||||||
|
return ENOENT;
|
||||||
|
new_name += len;
|
||||||
|
s1 = "";
|
||||||
|
} else {
|
||||||
|
s1 = rtems_filesystem_current.node_access;
|
||||||
|
}
|
||||||
|
full_path_name = malloc (strlen (s1) + strlen (new_name) + 1);
|
||||||
|
if (full_path_name == NULL)
|
||||||
|
return ENOMEM;
|
||||||
|
strcpy (full_path_name, s1);
|
||||||
|
strcat (full_path_name, new_name);
|
||||||
|
fixPath (full_path_name);
|
||||||
|
err = rtems_tfs_open_worker (iop, full_path_name, flags, mode);
|
||||||
|
free (full_path_name);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Read from an open TFS file...
|
||||||
|
*/
|
||||||
|
static ssize_t rtems_tfs_read(
|
||||||
|
rtems_libio_t *iop,
|
||||||
|
void *buffer,
|
||||||
|
uint32_t count
|
||||||
|
)
|
||||||
|
{
|
||||||
|
int ret, fd;
|
||||||
|
|
||||||
|
fd = (int) iop->file_info;
|
||||||
|
|
||||||
|
if (RTEMS_TFS_DEBUG)
|
||||||
|
printk("_read_r(%d,%" PRId32 ")\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->file_info;
|
||||||
|
|
||||||
|
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,
|
||||||
|
uint32_t count
|
||||||
|
)
|
||||||
|
{
|
||||||
|
int ret, fd;
|
||||||
|
|
||||||
|
fd = (int) iop->file_info;
|
||||||
|
|
||||||
|
if (RTEMS_TFS_DEBUG)
|
||||||
|
printk("rtems_tfs_write(%d,%" PRId32" )\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 rtems_off64_t rtems_tfs_lseek(
|
||||||
|
rtems_libio_t *iop,
|
||||||
|
rtems_off64_t offset,
|
||||||
|
int whence
|
||||||
|
)
|
||||||
|
{
|
||||||
|
int ret, fd;
|
||||||
|
|
||||||
|
fd = (int) iop->file_info;
|
||||||
|
|
||||||
|
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 (rtems_off64_t)ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static int rtems_tfs_ftruncate(
|
||||||
|
rtems_libio_t *iop,
|
||||||
|
rtems_off64_t count
|
||||||
|
)
|
||||||
|
{
|
||||||
|
int ret, fd;
|
||||||
|
|
||||||
|
fd = (int) iop->file_info;
|
||||||
|
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 fd, ret;
|
||||||
|
|
||||||
|
fd = (int) iop->file_info;
|
||||||
|
ret = mon_tfsctrl(cmd,(long)buf,0);
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static rtems_filesystem_node_types_t rtems_tfs_node_type(
|
||||||
|
rtems_filesystem_location_info_t *pathloc
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if ((pathloc->node_access == NULL) ||
|
||||||
|
(pathloc->node_access == ROOT_NODE_ACCESS))
|
||||||
|
return RTEMS_FILESYSTEM_MEMORY_FILE;
|
||||||
|
return RTEMS_FILESYSTEM_DIRECTORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rtems_tfs_free_node_info(
|
||||||
|
|
||||||
|
rtems_filesystem_location_info_t *pathloc)
|
||||||
|
{
|
||||||
|
if (pathloc->node_access && (pathloc->node_access != ROOT_NODE_ACCESS)) {
|
||||||
|
free (pathloc->node_access);
|
||||||
|
pathloc->node_access = NULL;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
rtems_filesystem_operations_table rtems_tfs_ops = {
|
||||||
|
rtems_tfs_eval_path, /* eval_path */
|
||||||
|
rtems_tfs_evaluate_for_make, /* evaluate_for_make */
|
||||||
|
NULL, /* link */
|
||||||
|
NULL, /* unlink */
|
||||||
|
rtems_tfs_node_type, /* node_type */
|
||||||
|
NULL, /* mknod */
|
||||||
|
NULL, /* chown */
|
||||||
|
rtems_tfs_free_node_info, /* freenodinfo */
|
||||||
|
NULL, /* mount */
|
||||||
|
rtems_tfs_mount_me, /* initialize */
|
||||||
|
NULL, /* unmount */
|
||||||
|
NULL, /* fsunmount */
|
||||||
|
NULL, /* utime */
|
||||||
|
NULL, /* evaluate_link */
|
||||||
|
NULL, /* symlink */
|
||||||
|
NULL, /* readlin */
|
||||||
|
};
|
||||||
|
|
||||||
|
rtems_filesystem_file_handlers_r rtems_tfs_handlers = {
|
||||||
|
rtems_tfs_open, /* open */
|
||||||
|
rtems_tfs_close, /* close */
|
||||||
|
rtems_tfs_read, /* read */
|
||||||
|
rtems_tfs_write, /* write */
|
||||||
|
rtems_tfs_ioctl, /* ioctl */
|
||||||
|
rtems_tfs_lseek, /* lseek */
|
||||||
|
NULL, /* fstat */
|
||||||
|
NULL, /* fchmod */
|
||||||
|
rtems_tfs_ftruncate, /* ftruncate */
|
||||||
|
NULL, /* fpathconf */
|
||||||
|
NULL, /* fsync */
|
||||||
|
NULL, /* fdatasync */
|
||||||
|
NULL, /* fcntl */
|
||||||
|
NULL /* rmnod */
|
||||||
|
};
|
||||||
26
c/src/lib/libbsp/shared/umon/umonrtemsglue.c
Normal file
26
c/src/lib/libbsp/shared/umon/umonrtemsglue.c
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* COPYRIGHT (c) 1989-2009.
|
||||||
|
* On-Line Applications Research Corporation (OAR).
|
||||||
|
*
|
||||||
|
* The license and distribution terms for this file may be
|
||||||
|
* found in the file LICENSE in this distribution or at
|
||||||
|
* http://www.rtems.com/license/LICENSE.
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <umon/monlib.h>
|
||||||
|
|
||||||
|
/* XXX eventually add lock/unlock methods */
|
||||||
|
|
||||||
|
void rtems_umon_connect(void)
|
||||||
|
{
|
||||||
|
void *moncomptr;
|
||||||
|
|
||||||
|
moncomptr = rtems_bsp_get_umon_monptr();
|
||||||
|
monConnect(
|
||||||
|
(int(*)())(*(unsigned long *)moncomptr), /* monitor base */
|
||||||
|
(void *)0, /* lock */
|
||||||
|
(void *)0 /* unlock */
|
||||||
|
);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user