Numerous miscellaneous features incorporated from Tony Bennett

(tbennett@divnc.com) including the following major additions:

  + variable length messages
  + named devices
  + debug monitor
  + association tables/variables
This commit is contained in:
Joel Sherrill
1995-08-17 19:51:51 +00:00
parent 3b438fa4b0
commit b06e68ef1f
151 changed files with 15476 additions and 1815 deletions

View File

@@ -23,31 +23,24 @@ extern "C" {
/* variables */
extern volatile rtems_unsigned32 Clock_driver_ticks;
extern rtems_device_major_number rtems_clock_major;
extern rtems_device_minor_number rtems_clock_minor;
/* functions */
rtems_task Exit_task();
void exit_task_init();
void Install_clock( rtems_isr_entry );
void ReInstall_clock( rtems_isr_entry );
void Clock_exit();
rtems_isr Clock_isr(
rtems_vector_number
);
/* driver entries */
/* default clock driver entry */
#define CLOCK_DRIVER_TABLE_ENTRY \
{ Clock_initialize, NULL, NULL, NULL, NULL, NULL }
{ Clock_initialize, NULL, NULL, NULL, NULL, Clock_control }
rtems_device_driver Clock_initialize(
rtems_device_major_number,
rtems_device_minor_number,
void *,
rtems_id,
rtems_unsigned32 *
void *
);
rtems_device_driver Clock_control(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *pargp
);
#ifdef __cplusplus

View File

@@ -0,0 +1,44 @@
/*
* @(#)assoc.h 1.2 - 95/06/28
*
*
* Rtems associativity routines. Mainly used to convert a value from
* one space to another (eg: our errno's to host errno's and v.v)
*
*
* $Id$
*/
#ifndef _INCLUDE_ASSOC_H
#define _INCLUDE_ASSOC_H
typedef struct {
char *name;
unsigned32 local_value;
unsigned32 remote_value;
} rtems_assoc_t;
/*
* Flag/marker for optional default value in each table
*/
#define RTEMS_ASSOC_DEFAULT_NAME "(default)"
rtems_assoc_t *rtems_assoc_ptr_by_name(rtems_assoc_t *, char *);
rtems_assoc_t *rtems_assoc_ptr_by_value(rtems_assoc_t *, unsigned32);
rtems_assoc_t *rtems_assoc_ptr_by_remote(rtems_assoc_t *, unsigned32);
unsigned32 rtems_assoc_remote_by_local(rtems_assoc_t *, unsigned32);
unsigned32 rtems_assoc_local_by_remote(rtems_assoc_t *, unsigned32);
unsigned32 rtems_assoc_remote_by_name(rtems_assoc_t *, char *);
unsigned32 rtems_assoc_local_by_name(rtems_assoc_t *, char *);
char *rtems_assoc_name_by_local(rtems_assoc_t *, unsigned32);
char *rtems_assoc_name_by_remote(rtems_assoc_t *, unsigned32);
unsigned32 rtems_assoc_remote_by_local_bitfield(rtems_assoc_t *, unsigned32);
char *rtems_assoc_name_by_local_bitfield(rtems_assoc_t *, unsigned32, char *);
char *rtems_assoc_name_by_remote_bitfield(rtems_assoc_t *, unsigned32, char *);
unsigned32 rtems_assoc_local_by_remote_bitfield(rtems_assoc_t *ap, unsigned32);
#endif /* ! _INCLUDE_ASSOC_H */

View File

@@ -0,0 +1,26 @@
/*
* @(#)error.h 1.1 - 95/08/02
*
*
* Defines and externs for rtems error reporting
*
* $Id$
*/
/*
* rtems_error() and rtems_panic() support
*/
#define RTEMS_ERROR_ERRNO (1<<((sizeof(int) * 8) - 2)) /* hi bit; use 'errno' */
#define RTEMS_ERROR_PANIC (RTEMS_ERROR_ERRNO / 2) /* err fatal; no return */
#define RTEMS_ERROR_ABORT (RTEMS_ERROR_ERRNO / 4) /* err is fatal; panic */
#define RTEMS_ERROR_MASK (RTEMS_ERROR_ERRNO | RTEMS_ERROR_ABORT | \
RTEMS_ERROR_PANIC) /* all */
char *rtems_status_text(rtems_status_code);
int rtems_error(int error_code, char *printf_format, ...);
void rtems_panic(char *printf_format, ...);
extern int rtems_panic_in_progress;

View File

@@ -0,0 +1,101 @@
/*
* @(#)libio.h 1.1 - 95/06/02
*
*
* General purpose communication channel for RTEMS to allow UNIX/POSIX
* system call behavior on top of RTEMS IO devices.
*
* TODO
* stat(2)
* unlink(2)
* rename(2)
*
* $Id$
*/
#ifndef _RTEMS_LIBIO_H
#define _RTEMS_LIBIO_H
typedef unsigned32 rtems_libio_offset_t;
/*
* An open file data structure, indexed by 'fd'
* TODO:
* should really have a separate per/file data structure that this
* points to (eg: size, offset, driver, pathname should be in that)
*/
typedef struct {
rtems_driver_name_t *driver;
rtems_libio_offset_t size; /* size of file */
rtems_libio_offset_t offset; /* current offset into the file */
unsigned32 flags;
char *pathname; /* opened pathname */
Objects_Id sem;
unsigned32 data0; /* private to "driver" */
unsigned32 data1; /* ... */
} rtems_libio_t;
/*
* param block for read/write
* Note: it must include 'offset' instead of using iop's offset since
* we can have multiple outstanding i/o's on a device.
*/
typedef struct {
rtems_libio_t *iop;
rtems_libio_offset_t offset;
unsigned8 *buffer;
unsigned32 count;
unsigned32 flags;
unsigned32 bytes_moved;
} rtems_libio_rw_args_t;
/*
* param block for open/close
*/
typedef struct {
rtems_libio_t *iop;
unsigned32 flags;
unsigned32 mode;
} rtems_libio_open_close_args_t;
/*
* param block for ioctl
*/
typedef struct {
rtems_libio_t *iop;
unsigned32 command;
void *buffer;
unsigned32 ioctl_return;
} rtems_libio_ioctl_args_t;
/*
* Values for 'flag'
*/
#define LIBIO_FLAGS_NO_DELAY 0x0001 /* return immediately if no data */
#define LIBIO_FLAGS_READ 0x0002 /* reading */
#define LIBIO_FLAGS_WRITE 0x0004 /* writing */
#define LIBIO_FLAGS_LINE_BUFFERED 0x0008 /* line buffered io (^h, ^u, etc) */
#define LIBIO_FLAGS_OPEN 0x0100 /* device is open */
#define LIBIO_FLAGS_APPEND 0x0200 /* all writes append */
#define LIBIO_FLAGS_CREATE 0x0400 /* create file */
#define LIBIO_FLAGS_READ_WRITE (LIBIO_FLAGS_READ | LIBIO_FLAGS_WRITE)
void rtems_libio_config(rtems_configuration_table *config, unsigned32 max_fds);
void rtems_libio_init(void);
int __open(const char *pathname, unsigned32 flag, unsigned32 mode);
int __close(int fd);
int __read(int fd, void *buffer, unsigned32 count);
int __write(int fd, const void *buffer, unsigned32 count);
int __ioctl(int fd, unsigned32 command, void *buffer);
int __lseek(int fd, rtems_libio_offset_t offset, int whence);
#endif /* _RTEMS_LIBIO_H */

View File

@@ -0,0 +1,258 @@
/*
* @(#)assoc.c 1.4 - 95/08/02
*
*
* assoc.c
* rtems assoc routines
*
* $Id$
*/
#include <rtems.h>
#include "assoc.h"
#include <stdio.h> /* sprintf */
#include <string.h> /* strcat, strcmp */
#define STREQ(a,b) (strcmp((a), (b)) == 0)
#define rtems_assoc_is_default(ap) ((ap)->name && STREQ(ap->name, RTEMS_ASSOC_DEFAULT_NAME))
rtems_assoc_t *
rtems_assoc_ptr_by_name(
rtems_assoc_t *ap,
char *name
)
{
rtems_assoc_t *default_ap = 0;
if (rtems_assoc_is_default(ap))
default_ap = ap++;
for ( ; ap->name; ap++)
if (strcmp(ap->name, name) == 0)
return ap;
return default_ap;
}
rtems_assoc_t *
rtems_assoc_ptr_by_local(
rtems_assoc_t *ap,
unsigned32 local_value
)
{
rtems_assoc_t *default_ap = 0;
if (rtems_assoc_is_default(ap))
default_ap = ap++;
for ( ; ap->name; ap++)
if (ap->local_value == local_value)
return ap;
return default_ap;
}
rtems_assoc_t *
rtems_assoc_ptr_by_remote(
rtems_assoc_t *ap,
unsigned32 remote_value
)
{
rtems_assoc_t *default_ap = 0;
if (rtems_assoc_is_default(ap))
default_ap = ap++;
for ( ; ap->name; ap++)
if (ap->remote_value == remote_value)
return ap;
return default_ap;
}
/*
* Get values
*/
unsigned32
rtems_assoc_remote_by_local(
rtems_assoc_t *ap,
unsigned32 local_value
)
{
rtems_assoc_t *nap;
nap = rtems_assoc_ptr_by_local(ap, local_value);
if (nap)
return nap->remote_value;
return 0;
}
unsigned32
rtems_assoc_local_by_remote(
rtems_assoc_t *ap,
unsigned32 remote_value
)
{
rtems_assoc_t *nap;
nap = rtems_assoc_ptr_by_remote(ap, remote_value);
if (nap)
return nap->local_value;
return 0;
}
unsigned32
rtems_assoc_remote_by_name(
rtems_assoc_t *ap,
char *name
)
{
rtems_assoc_t *nap;
nap = rtems_assoc_ptr_by_name(ap, name);
if (nap)
return nap->remote_value;
return 0;
}
unsigned32
rtems_assoc_local_by_name(
rtems_assoc_t *ap,
char *name
)
{
rtems_assoc_t *nap;
nap = rtems_assoc_ptr_by_name(ap, name);
if (nap)
return nap->local_value;
return 0;
}
/*
* what to return if a value is not found
* this is not reentrant, but it really shouldn't be invoked anyway
*/
char *
rtems_assoc_name_bad(
unsigned32 bad_value
)
{
static char bad_buffer[32];
sprintf(bad_buffer, "< %d [0x%x] >", bad_value, bad_value);
return bad_buffer;
}
char *
rtems_assoc_name_by_local(
rtems_assoc_t *ap,
unsigned32 local_value
)
{
rtems_assoc_t *nap;
nap = rtems_assoc_ptr_by_local(ap, local_value);
if (nap)
return nap->name;
return rtems_assoc_name_bad(local_value);
}
char *
rtems_assoc_name_by_remote(
rtems_assoc_t *ap,
unsigned32 remote_value
)
{
rtems_assoc_t *nap;
nap = rtems_assoc_ptr_by_remote(ap, remote_value);
if (nap)
return nap->name;
return rtems_assoc_name_bad(remote_value);
}
/*
* Bitfield functions assume just 1 bit set in each of remote and local
* entries; they do not check for this.
*/
unsigned32 rtems_assoc_remote_by_local_bitfield(
rtems_assoc_t *ap,
unsigned32 local_value
)
{
unsigned32 b;
unsigned32 remote_value = 0;
for (b = 1; b; b <<= 1)
if (b & local_value)
remote_value |= rtems_assoc_remote_by_local(ap, b);
return remote_value;
}
unsigned32 rtems_assoc_local_by_remote_bitfield(
rtems_assoc_t *ap,
unsigned32 remote_value
)
{
unsigned32 b;
unsigned32 local_value = 0;
for (b = 1; b; b <<= 1)
if (b & remote_value)
local_value |= rtems_assoc_local_by_remote(ap, b);
return local_value;
}
char *rtems_assoc_name_by_remote_bitfield(
rtems_assoc_t *ap,
unsigned32 value,
char *buffer
)
{
unsigned32 b;
*buffer = 0;
for (b = 1; b; b <<= 1)
if (b & value)
{
if (*buffer)
strcat(buffer, " ");
strcat(buffer, rtems_assoc_name_by_remote(ap, b));
}
return buffer;
}
char *rtems_assoc_name_by_local_bitfield(
rtems_assoc_t *ap,
unsigned32 value,
char *buffer
)
{
unsigned32 b;
*buffer = 0;
for (b = 1; b; b <<= 1)
if (b & value)
{
if (*buffer)
strcat(buffer, " ");
strcat(buffer, rtems_assoc_name_by_local(ap, b));
}
return buffer;
}

View File

@@ -0,0 +1,212 @@
/*
* @(#)error.c 1.2 - 95/08/02
*
*
* report errors and panics to RTEMS' stderr.
* Currently just used by RTEMS monitor.
*
*
* $Id$
*/
/*
* These routines provide general purpose error reporting.
* rtems_error reports an error to stderr and allows use of
* printf style formatting. A newline is appended to all messages.
*
* error_flag can be specified as any of the following:
*
* RTEMS_ERROR_ERRNO -- include errno text in output
* RTEMS_ERROR_PANIC -- halts local system after output
* RTEMS_ERROR_ABORT -- abort after output
*
* It can also include a rtems_status value which can be OR'd
* with the above flags. *
*
* EXAMPLE
* #include <rtems.h>
* #include <rtems/error.h>
* rtems_error(0, "stray interrupt %d", intr);
*
* EXAMPLE
* if ((status = rtems_task_create(...)) != RTEMS_SUCCCESSFUL)
* {
* rtems_error(status | RTEMS_ERROR_ABORT,
* "could not create task");
* }
*
* EXAMPLE
* if ((fd = open(pathname, O_RDNLY)) < 0)
* {
* rtems_error(FLOSS_ERROR_ERRNO, "open of '%s' failed", pathname);
* goto failed;
* }
*/
#include <rtems.h>
#include "error.h"
#include "assoc.h"
#include <stdio.h>
#include <stdarg.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h> /* _exit() */
/* bug in hpux <errno.h>: no prototypes unless you are C++ */
#ifdef hpux9
char *strerror(int);
#endif
extern char *rtems_progname;
int rtems_panic_in_progress;
rtems_assoc_t rtems_status_assoc[] = {
{ "successful completion", RTEMS_SUCCESSFUL, },
{ "returned from a thread", RTEMS_TASK_EXITTED, },
{ "multiprocessing not configured", RTEMS_MP_NOT_CONFIGURED, },
{ "invalid object name", RTEMS_INVALID_NAME, },
{ "invalid object id", RTEMS_INVALID_ID, },
{ "too many", RTEMS_TOO_MANY, },
{ "timed out waiting", RTEMS_TIMEOUT, },
{ "object deleted while waiting", RTEMS_OBJECT_WAS_DELETED, },
{ "specified size was invalid", RTEMS_INVALID_SIZE, },
{ "address specified is invalid", RTEMS_INVALID_ADDRESS, },
{ "number was invalid", RTEMS_INVALID_NUMBER, },
{ "item has not been initialized", RTEMS_NOT_DEFINED, },
{ "resources still outstanding", RTEMS_RESOURCE_IN_USE, },
{ "request not satisfied", RTEMS_UNSATISFIED, },
{ "thread is in wrong state", RTEMS_INCORRECT_STATE, },
{ "thread already in state", RTEMS_ALREADY_SUSPENDED, },
{ "illegal on calling thread", RTEMS_ILLEGAL_ON_SELF, },
{ "illegal for remote object", RTEMS_ILLEGAL_ON_REMOTE_OBJECT, },
{ "called from wrong environment", RTEMS_CALLED_FROM_ISR, },
{ "invalid thread priority", RTEMS_INVALID_PRIORITY, },
{ "invalid date/time", RTEMS_INVALID_CLOCK, },
{ "invalid node id", RTEMS_INVALID_NODE, },
{ "directive not configured", RTEMS_NOT_CONFIGURED, },
{ "not owner of resource", RTEMS_NOT_OWNER_OF_RESOURCE , },
{ "directive not implemented", RTEMS_NOT_IMPLEMENTED, },
{ "RTEMS inconsistency detected", RTEMS_INTERNAL_ERROR, },
{ "internal multiprocessing only", RTEMS_PROXY_BLOCKING, },
{ "could not get enough memory", RTEMS_NO_MEMORY, },
{ 0, 0, 0 },
};
char *
rtems_status_text(
rtems_status_code status
)
{
return rtems_assoc_name_by_local(rtems_status_assoc, status);
}
static int rtems_verror(
unsigned32 error_flag,
char *printf_format,
va_list arglist
)
{
int local_errno = 0;
int chars_written = 0;
rtems_status_code status;
if (error_flag & RTEMS_ERROR_PANIC)
{
rtems_panic_in_progress++;
/* disable task switches */
_Thread_Disable_dispatch();
/* don't aggravate things */
if (rtems_panic_in_progress > 2)
return 0;
}
(void) fflush(stdout); /* in case stdout/stderr same */
status = error_flag & ~RTEMS_ERROR_MASK;
if (error_flag & RTEMS_ERROR_ERRNO) /* include errno? */
local_errno = errno;
if (_Configuration_Is_multiprocessing())
fprintf(stderr, "[%d] ", _Configuration_MP_table->node);
if (rtems_progname && *rtems_progname)
chars_written += fprintf(stderr, "%s: ", rtems_progname);
chars_written += vfprintf(stderr, printf_format, arglist);
if (status)
chars_written += fprintf(stderr, " (status: %s)", rtems_status_text(status));
if (local_errno)
if ((local_errno > 0) && *strerror(local_errno))
chars_written += fprintf(stderr, " (errno: %s)", strerror(local_errno));
else
chars_written += fprintf(stderr, " (unknown errno=%d)", local_errno);
chars_written += fprintf(stderr, "\n");
(void) fflush(stderr);
if (error_flag & (RTEMS_ERROR_PANIC | RTEMS_ERROR_ABORT))
{
if (error_flag & RTEMS_ERROR_PANIC)
{
rtems_error(0, "fatal error, exiting");
_exit(local_errno);
}
else
{
rtems_error(0, "fatal error, aborting");
abort();
}
}
return chars_written;
}
/*
* Report an error.
* error_flag is as above; printf_format is a normal
* printf(3) format string, with its concommitant arguments.
*
* Returns the number of characters written.
*/
int rtems_error(
int error_flag,
char *printf_format,
...
)
{
va_list arglist;
int chars_written;
va_start(arglist, printf_format);
chars_written = rtems_verror(error_flag, printf_format, arglist);
va_end(arglist);
return chars_written;
}
/*
* rtems_panic is shorthand for rtems_error(RTEMS_ERROR_PANIC, ...)
*/
void rtems_panic(
char *printf_format,
...
)
{
va_list arglist;
va_start(arglist, printf_format);
(void) rtems_verror(RTEMS_ERROR_PANIC, printf_format, arglist);
va_end(arglist);
}

View File

@@ -0,0 +1,433 @@
/*
* @(#)libio.c 1.1 - 95/06/02
*
*
* Provide UNIX/POSIX-like io system calls for RTEMS using the
* RTEMS IO manager
*
* TODO
*
* $Id$
*/
#include <rtems.h>
#include <rtems/assoc.h> /* assoc.h not included by rtems.h */
#include <fcntl.h> /* O_RDONLY, et.al. */
#if defined(solaris2)
#define O_NDELAY O_NONBLOCK
#endif
#include <errno.h>
#include <string.h> /* strcmp */
#include <unistd.h>
#include <stdlib.h> /* calloc() */
#include "libio.h" /* libio.h not pulled in by rtems */
/*
* Semaphore to protect the io table
*/
Objects_Id rtems_libio_semaphore;
#define RTEMS_LIBIO_SEM rtems_build_name('L', 'B', 'I', 'O')
#define RTEMS_LIBIO_IOP_SEM(n) rtems_build_name('L', 'B', 'I', n)
unsigned32 rtems_libio_number_iops;
rtems_libio_t *rtems_libio_iops;
rtems_libio_t *rtems_libio_last_iop;
#define rtems_libio_iop(fd) ((((unsigned32)(fd)) < rtems_libio_number_iops) ? \
&rtems_libio_iops[fd] : 0)
#define rtems_libio_check_fd(fd) \
do { \
if ((fd) >= rtems_libio_number_iops) \
{ \
errno = EBADF; \
return -1; \
} \
} while (0)
#define rtems_libio_check_buffer(buffer) \
do { \
if ((buffer) == 0) \
{ \
errno = EINVAL; \
return -1; \
} \
} while (0)
#define rtems_libio_check_count(count) \
do { \
if ((count) == 0) \
{ \
return 0; \
} \
} while (0)
#define rtems_libio_check_permissions(iop, flag) \
do { \
if (((iop)->flags & (flag)) == 0) \
{ \
errno = EINVAL; \
return -1; \
} \
} while (0)
void
rtems_libio_config(
rtems_configuration_table *config,
unsigned32 max_fds
)
{
rtems_libio_number_iops = max_fds;
/*
* tweak config to reflect # of semaphores we will need
*/
config->maximum_semaphores += 1; /* one for iop table */
config->maximum_semaphores += max_fds;
}
/*
* Called by bsp startup code to init the libio area.
*/
void
rtems_libio_init(void)
{
rtems_status_code rc;
if (rtems_libio_number_iops > 0)
{
rtems_libio_iops = (rtems_libio_t *) calloc(rtems_libio_number_iops,
sizeof(rtems_libio_t));
if (rtems_libio_iops == NULL)
rtems_fatal_error_occurred(RTEMS_NO_MEMORY);
rtems_libio_last_iop = rtems_libio_iops + (rtems_libio_number_iops - 1);
}
rc = rtems_semaphore_create(RTEMS_LIBIO_SEM,
1,
RTEMS_BINARY_SEMAPHORE | RTEMS_INHERIT_PRIORITY | RTEMS_PRIORITY,
&rtems_libio_semaphore);
if (rc != RTEMS_SUCCESSFUL)
rtems_fatal_error_occurred(rc);
}
/*
* Convert RTEMS status to a UNIX errno
*/
rtems_assoc_t errno_assoc[] = {
{ "OK", RTEMS_SUCCESSFUL, 0 },
{ "TIMEOUT", RTEMS_TIMEOUT, ETIME },
{ "NO MEMORY", RTEMS_NO_MEMORY, ENOMEM },
{ 0, 0, 0 },
};
static unsigned32
rtems_libio_errno(rtems_status_code code)
{
int rc;
if ((rc = rtems_assoc_remote_by_local(errno_assoc, (unsigned32) code)))
{
errno = rc;
return -1;
}
return 0;
}
/*
* Convert UNIX fnctl(2) flags to ones that RTEMS drivers understand
*/
rtems_assoc_t access_modes_assoc[] = {
{ "READ", LIBIO_FLAGS_READ, O_RDONLY },
{ "WRITE", LIBIO_FLAGS_WRITE, O_WRONLY },
{ "READ/WRITE", LIBIO_FLAGS_READ_WRITE, O_RDWR },
{ 0, 0, 0 },
};
rtems_assoc_t status_flags_assoc[] = {
{ "NO DELAY", LIBIO_FLAGS_NO_DELAY, O_NDELAY },
{ "APPEND", LIBIO_FLAGS_APPEND, O_APPEND },
{ "CREATE", LIBIO_FLAGS_CREATE, O_CREAT },
{ 0, 0, 0 },
};
static unsigned32
rtems_libio_fcntl_flags(unsigned32 fcntl_flags)
{
unsigned32 flags = 0;
unsigned32 access_modes;
/*
* Access mode is a small integer
*/
access_modes = fcntl_flags & O_ACCMODE;
fcntl_flags &= ~O_ACCMODE;
flags = rtems_assoc_local_by_remote(access_modes_assoc, access_modes);
/*
* Everything else is single bits
*/
flags |= rtems_assoc_local_by_remote_bitfield(status_flags_assoc, fcntl_flags);
return flags;
}
static rtems_libio_t *
rtems_libio_allocate(void)
{
rtems_libio_t *iop;
rtems_status_code rc;
rtems_semaphore_obtain(rtems_libio_semaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
for (iop = rtems_libio_iops; iop <= rtems_libio_last_iop; iop++)
if ((iop->flags & LIBIO_FLAGS_OPEN) == 0)
{
/*
* Got one; create a semaphore for it
*/
rc = rtems_semaphore_create(RTEMS_LIBIO_IOP_SEM(iop - rtems_libio_iops),
1, RTEMS_BINARY_SEMAPHORE | RTEMS_INHERIT_PRIORITY | RTEMS_PRIORITY,
&iop->sem);
if (rc != RTEMS_SUCCESSFUL)
goto failed;
iop->flags = LIBIO_FLAGS_OPEN;
goto done;
}
failed:
iop = 0;
done:
rtems_semaphore_release(rtems_libio_semaphore);
return iop;
}
static void
rtems_libio_free(rtems_libio_t *iop)
{
rtems_semaphore_obtain(rtems_libio_semaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
if (iop->sem)
rtems_semaphore_delete(iop->sem);
(void) memset(iop, 0, sizeof(*iop));
rtems_semaphore_release(rtems_libio_semaphore);
}
int
__open(
const char *pathname,
unsigned32 flag,
unsigned32 mode)
{
rtems_status_code rc;
rtems_libio_t *iop = 0;
rtems_driver_name_t *np;
rtems_libio_open_close_args_t args;
if ((rc = rtems_io_lookup_name(pathname, &np)) != RTEMS_SUCCESSFUL)
goto done;
iop = rtems_libio_allocate();
if (iop == 0)
{
rc = RTEMS_TOO_MANY;
goto done;
}
iop->driver = np;
iop->pathname = (char *) pathname;
iop->flags |= rtems_libio_fcntl_flags(flag);
args.iop = iop;
args.flags = iop->flags;
args.mode = mode;
rc = rtems_io_open(np->major, np->minor, (void *) &args);
done:
if (rc != RTEMS_SUCCESSFUL)
{
if (iop)
rtems_libio_free(iop);
return rtems_libio_errno(rc);
}
return iop - rtems_libio_iops;
}
int
__close(
int fd
)
{
rtems_status_code rc;
rtems_driver_name_t *np;
rtems_libio_t *iop = rtems_libio_iop(fd);
rtems_libio_open_close_args_t args;
rtems_libio_check_fd(fd);
np = iop->driver;
args.iop = iop;
args.flags = 0;
args.mode = 0;
rc = rtems_io_close(np->major, np->minor, (void *) &args);
if (rc != RTEMS_SUCCESSFUL)
return rtems_libio_errno(rc);
return 0;
}
int
__read(
int fd,
void * buffer,
unsigned32 count
)
{
rtems_status_code rc;
rtems_driver_name_t *np;
rtems_libio_t *iop = rtems_libio_iop(fd);
rtems_libio_rw_args_t args;
rtems_libio_check_fd(fd);
rtems_libio_check_buffer(buffer);
rtems_libio_check_count(count);
rtems_libio_check_permissions(iop, LIBIO_FLAGS_READ);
np = iop->driver;
args.iop = iop;
args.offset = iop->offset;
args.buffer = buffer;
args.count = count;
args.flags = iop->flags;
args.bytes_moved = 0;
rc = rtems_io_read(np->major, np->minor, (void *) &args);
iop->offset += args.bytes_moved;
if (rc != RTEMS_SUCCESSFUL)
return rtems_libio_errno(rc);
return args.bytes_moved;
}
int
__write(
int fd,
const void *buffer,
unsigned32 count
)
{
rtems_status_code rc;
rtems_driver_name_t *np;
rtems_libio_t *iop = rtems_libio_iop(fd);
rtems_libio_rw_args_t args;
rtems_libio_check_fd(fd);
rtems_libio_check_buffer(buffer);
rtems_libio_check_count(count);
rtems_libio_check_permissions(iop, LIBIO_FLAGS_WRITE);
np = iop->driver;
args.iop = iop;
args.offset = iop->offset;
args.buffer = (void *) buffer;
args.count = count;
args.flags = iop->flags;
args.bytes_moved = 0;
rc = rtems_io_write(np->major, np->minor, (void *) &args);
iop->offset += args.bytes_moved;
if (rc != RTEMS_SUCCESSFUL)
return rtems_libio_errno(rc);
return args.bytes_moved;
}
int
__ioctl(
int fd,
unsigned32 command,
void * buffer)
{
rtems_status_code rc;
rtems_driver_name_t *np;
rtems_libio_t *iop = rtems_libio_iop(fd);
rtems_libio_ioctl_args_t args;
rtems_libio_check_fd(fd);
np = iop->driver;
args.iop = iop;
args.command = command;
args.buffer = buffer;
rc = rtems_io_control(np->major, np->minor, (void *) &args);
if (rc != RTEMS_SUCCESSFUL)
return rtems_libio_errno(rc);
return args.ioctl_return;
}
/*
* internal only??
*/
int
__lseek(
int fd,
rtems_libio_offset_t offset,
int whence
)
{
rtems_libio_t *iop = rtems_libio_iop(fd);
rtems_libio_check_fd(fd);
switch (whence)
{
case SEEK_SET:
iop->offset = offset;
break;
case SEEK_CUR:
iop->offset += offset;
break;
case SEEK_END:
iop->offset = iop->size - offset;
break;
default:
errno = EINVAL;
return -1;
}
return 0;
}

View File

@@ -41,14 +41,22 @@ extern "C" {
/*
* The following defines the data types needed to manipulate
* the contents of message buffers.
* Since msgs are variable length we just make a ptr to 1.
*/
typedef struct {
unsigned32 field1;
unsigned32 field2;
unsigned32 field3;
unsigned32 field4;
} Message_queue_Buffer;
unsigned32 size;
#ifndef __cplusplus
/* NOTE: [0] is gcc specific,
* but specifically disallowed by ANSI STD C++
* g++ warns about it, so we #ifdef it out to
* get rid of warnings when compiled by g++.
*/
unsigned32 buffer[0];
#endif
} Message_queue_Buffer;
/*
* The following records define the organization of a message
@@ -68,10 +76,13 @@ typedef struct {
typedef struct {
Objects_Control Object;
Thread_queue_Control Wait_queue;
rtems_attribute attribute_set;
rtems_attribute attribute_set;
unsigned32 maximum_pending_messages;
unsigned32 number_of_pending_messages;
unsigned32 maximum_message_size;
Chain_Control Pending_messages;
Message_queue_Buffer *message_buffers;
Chain_Control Inactive_messages;
} Message_queue_Control;
/*
@@ -81,13 +92,6 @@ typedef struct {
EXTERN Objects_Information _Message_queue_Information;
/*
* The following defines the data structures used to
* manage the pool of inactive message buffers.
*/
EXTERN Chain_Control _Message_queue_Inactive_messages;
/*
* The following enumerated type details the modes in which a message
* may be submitted to a message queue. The message may be posted
@@ -108,8 +112,7 @@ typedef enum {
*/
void _Message_queue_Manager_initialization(
unsigned32 maximum_message_queues,
unsigned32 maximum_messages
unsigned32 maximum_message_queues
);
/*
@@ -126,10 +129,11 @@ void _Message_queue_Manager_initialization(
*/
rtems_status_code rtems_message_queue_create(
Objects_Name name,
unsigned32 count,
Objects_Name name,
unsigned32 count,
unsigned32 max_message_size,
rtems_attribute attribute_set,
Objects_Id *id
Objects_Id *id
);
/*
@@ -183,7 +187,8 @@ rtems_status_code rtems_message_queue_delete(
rtems_status_code rtems_message_queue_send(
Objects_Id id,
void *buffer
void *buffer,
unsigned32 size
);
/*
@@ -204,7 +209,8 @@ rtems_status_code rtems_message_queue_send(
rtems_status_code rtems_message_queue_urgent(
Objects_Id id,
void *buffer
void *buffer,
unsigned32 size
);
/*
@@ -226,6 +232,7 @@ rtems_status_code rtems_message_queue_urgent(
rtems_status_code rtems_message_queue_broadcast(
Objects_Id id,
void *buffer,
unsigned32 size,
unsigned32 *count
);
@@ -246,8 +253,9 @@ rtems_status_code rtems_message_queue_broadcast(
rtems_status_code rtems_message_queue_receive(
Objects_Id id,
void *buffer,
unsigned32 *size_p,
unsigned32 option_set,
rtems_interval timeout
rtems_interval timeout
);
/*
@@ -276,8 +284,9 @@ rtems_status_code rtems_message_queue_flush(
*/
STATIC INLINE void _Message_queue_Copy_buffer (
Message_queue_Buffer *source,
Message_queue_Buffer *destination
void *source,
void *destination,
unsigned32 size
);
/*
@@ -295,7 +304,8 @@ STATIC INLINE void _Message_queue_Copy_buffer (
boolean _Message_queue_Seize(
Message_queue_Control *the_message_queue,
unsigned32 option_set,
Message_queue_Buffer *buffer
void *buffer,
unsigned32 *size_p
);
/*
@@ -322,7 +332,8 @@ unsigned32 _Message_queue_Flush_support(
rtems_status_code _Message_queue_Submit(
Objects_Id id,
Message_queue_Buffer *buffer,
void *buffer,
unsigned32 size,
Message_queue_Submit_types submit_type
);
@@ -336,7 +347,9 @@ rtems_status_code _Message_queue_Submit(
*/
STATIC INLINE Message_queue_Buffer_control *
_Message_queue_Allocate_message_buffer ( void );
_Message_queue_Allocate_message_buffer (
Message_queue_Control *the_message_queue
);
/*
* _Message_queue_Free_message_buffer
@@ -348,6 +361,7 @@ STATIC INLINE Message_queue_Buffer_control *
*/
STATIC INLINE void _Message_queue_Free_message_buffer (
Message_queue_Control *the_message_queue,
Message_queue_Buffer_control *the_message
);
@@ -415,14 +429,17 @@ STATIC INLINE boolean _Message_queue_Is_null (
* the inactive chain of free message queue control blocks.
*/
STATIC INLINE Message_queue_Control *_Message_queue_Allocate ( void );
Message_queue_Control *_Message_queue_Allocate (
unsigned32 count,
unsigned32 max_message_size
);
/*
* _Message_queue_Free
*
* DESCRIPTION:
*
* This routine allocates a message queue control block from
* This routine deallocates a message queue control block into
* the inactive chain of free message queue control blocks.
*/

View File

@@ -55,15 +55,14 @@ typedef enum {
*/
typedef struct {
rtems_packet_prefix Prefix;
rtems_packet_prefix Prefix;
Message_queue_MP_Remote_operations operation;
Objects_Name name;
rtems_option option_set;
rtems_option option_set;
Objects_Id proxy_id;
unsigned32 count;
unsigned32 size;
unsigned32 pad0;
unsigned32 pad1;
unsigned32 pad2;
Message_queue_Buffer Buffer;
} Message_queue_MP_Packet;
@@ -95,9 +94,10 @@ void _Message_queue_MP_Send_process_packet (
rtems_status_code _Message_queue_MP_Send_request_packet (
Message_queue_MP_Remote_operations operation,
Objects_Id message_queue_id,
Message_queue_Buffer *buffer,
rtems_option option_set,
rtems_interval timeout
void *buffer,
unsigned32 *size_p,
rtems_option option_set,
rtems_interval timeout
);
/*

View File

@@ -41,14 +41,22 @@ extern "C" {
/*
* The following defines the data types needed to manipulate
* the contents of message buffers.
* Since msgs are variable length we just make a ptr to 1.
*/
typedef struct {
unsigned32 field1;
unsigned32 field2;
unsigned32 field3;
unsigned32 field4;
} Message_queue_Buffer;
unsigned32 size;
#ifndef __cplusplus
/* NOTE: [0] is gcc specific,
* but specifically disallowed by ANSI STD C++
* g++ warns about it, so we #ifdef it out to
* get rid of warnings when compiled by g++.
*/
unsigned32 buffer[0];
#endif
} Message_queue_Buffer;
/*
* The following records define the organization of a message
@@ -68,10 +76,13 @@ typedef struct {
typedef struct {
Objects_Control Object;
Thread_queue_Control Wait_queue;
rtems_attribute attribute_set;
rtems_attribute attribute_set;
unsigned32 maximum_pending_messages;
unsigned32 number_of_pending_messages;
unsigned32 maximum_message_size;
Chain_Control Pending_messages;
Message_queue_Buffer *message_buffers;
Chain_Control Inactive_messages;
} Message_queue_Control;
/*
@@ -81,13 +92,6 @@ typedef struct {
EXTERN Objects_Information _Message_queue_Information;
/*
* The following defines the data structures used to
* manage the pool of inactive message buffers.
*/
EXTERN Chain_Control _Message_queue_Inactive_messages;
/*
* The following enumerated type details the modes in which a message
* may be submitted to a message queue. The message may be posted
@@ -108,8 +112,7 @@ typedef enum {
*/
void _Message_queue_Manager_initialization(
unsigned32 maximum_message_queues,
unsigned32 maximum_messages
unsigned32 maximum_message_queues
);
/*
@@ -126,10 +129,11 @@ void _Message_queue_Manager_initialization(
*/
rtems_status_code rtems_message_queue_create(
Objects_Name name,
unsigned32 count,
Objects_Name name,
unsigned32 count,
unsigned32 max_message_size,
rtems_attribute attribute_set,
Objects_Id *id
Objects_Id *id
);
/*
@@ -183,7 +187,8 @@ rtems_status_code rtems_message_queue_delete(
rtems_status_code rtems_message_queue_send(
Objects_Id id,
void *buffer
void *buffer,
unsigned32 size
);
/*
@@ -204,7 +209,8 @@ rtems_status_code rtems_message_queue_send(
rtems_status_code rtems_message_queue_urgent(
Objects_Id id,
void *buffer
void *buffer,
unsigned32 size
);
/*
@@ -226,6 +232,7 @@ rtems_status_code rtems_message_queue_urgent(
rtems_status_code rtems_message_queue_broadcast(
Objects_Id id,
void *buffer,
unsigned32 size,
unsigned32 *count
);
@@ -246,8 +253,9 @@ rtems_status_code rtems_message_queue_broadcast(
rtems_status_code rtems_message_queue_receive(
Objects_Id id,
void *buffer,
unsigned32 *size_p,
unsigned32 option_set,
rtems_interval timeout
rtems_interval timeout
);
/*
@@ -276,8 +284,9 @@ rtems_status_code rtems_message_queue_flush(
*/
STATIC INLINE void _Message_queue_Copy_buffer (
Message_queue_Buffer *source,
Message_queue_Buffer *destination
void *source,
void *destination,
unsigned32 size
);
/*
@@ -295,7 +304,8 @@ STATIC INLINE void _Message_queue_Copy_buffer (
boolean _Message_queue_Seize(
Message_queue_Control *the_message_queue,
unsigned32 option_set,
Message_queue_Buffer *buffer
void *buffer,
unsigned32 *size_p
);
/*
@@ -322,7 +332,8 @@ unsigned32 _Message_queue_Flush_support(
rtems_status_code _Message_queue_Submit(
Objects_Id id,
Message_queue_Buffer *buffer,
void *buffer,
unsigned32 size,
Message_queue_Submit_types submit_type
);
@@ -336,7 +347,9 @@ rtems_status_code _Message_queue_Submit(
*/
STATIC INLINE Message_queue_Buffer_control *
_Message_queue_Allocate_message_buffer ( void );
_Message_queue_Allocate_message_buffer (
Message_queue_Control *the_message_queue
);
/*
* _Message_queue_Free_message_buffer
@@ -348,6 +361,7 @@ STATIC INLINE Message_queue_Buffer_control *
*/
STATIC INLINE void _Message_queue_Free_message_buffer (
Message_queue_Control *the_message_queue,
Message_queue_Buffer_control *the_message
);
@@ -415,14 +429,17 @@ STATIC INLINE boolean _Message_queue_Is_null (
* the inactive chain of free message queue control blocks.
*/
STATIC INLINE Message_queue_Control *_Message_queue_Allocate ( void );
Message_queue_Control *_Message_queue_Allocate (
unsigned32 count,
unsigned32 max_message_size
);
/*
* _Message_queue_Free
*
* DESCRIPTION:
*
* This routine allocates a message queue control block from
* This routine deallocates a message queue control block into
* the inactive chain of free message queue control blocks.
*/

View File

@@ -55,15 +55,14 @@ typedef enum {
*/
typedef struct {
rtems_packet_prefix Prefix;
rtems_packet_prefix Prefix;
Message_queue_MP_Remote_operations operation;
Objects_Name name;
rtems_option option_set;
rtems_option option_set;
Objects_Id proxy_id;
unsigned32 count;
unsigned32 size;
unsigned32 pad0;
unsigned32 pad1;
unsigned32 pad2;
Message_queue_Buffer Buffer;
} Message_queue_MP_Packet;
@@ -95,9 +94,10 @@ void _Message_queue_MP_Send_process_packet (
rtems_status_code _Message_queue_MP_Send_request_packet (
Message_queue_MP_Remote_operations operation,
Objects_Id message_queue_id,
Message_queue_Buffer *buffer,
rtems_option option_set,
rtems_interval timeout
void *buffer,
unsigned32 *size_p,
rtems_option option_set,
rtems_interval timeout
);
/*

View File

@@ -82,19 +82,6 @@ STATIC INLINE boolean _Attributes_Is_priority(
return ( attribute_set & RTEMS_PRIORITY );
}
/*PAGE
*
* _Attributes_Is_limit
*
*/
STATIC INLINE boolean _Attributes_Is_limit(
rtems_attribute attribute_set
)
{
return ( attribute_set & RTEMS_LIMIT );
}
/*PAGE
*
* _Attributes_Is_binary_semaphore

View File

@@ -17,6 +17,8 @@
#ifndef __MESSAGE_QUEUE_inl
#define __MESSAGE_QUEUE_inl
#include <rtems/wkspace.h>
/*PAGE
*
* _Message_queue_Copy_buffer
@@ -24,11 +26,12 @@
*/
STATIC INLINE void _Message_queue_Copy_buffer (
Message_queue_Buffer *source,
Message_queue_Buffer *destination
void *source,
void *destination,
unsigned32 size
)
{
*destination = *source;
memcpy(destination, source, size);
}
/*PAGE
@@ -38,10 +41,12 @@ STATIC INLINE void _Message_queue_Copy_buffer (
*/
STATIC INLINE Message_queue_Buffer_control *
_Message_queue_Allocate_message_buffer ( void )
_Message_queue_Allocate_message_buffer (
Message_queue_Control *the_message_queue
)
{
return (Message_queue_Buffer_control *)
_Chain_Get( &_Message_queue_Inactive_messages );
_Chain_Get( &the_message_queue->Inactive_messages );
}
/*PAGE
@@ -51,10 +56,11 @@ STATIC INLINE Message_queue_Buffer_control *
*/
STATIC INLINE void _Message_queue_Free_message_buffer (
Message_queue_Buffer_control *the_message
Message_queue_Control *the_message_queue,
Message_queue_Buffer_control *the_message
)
{
_Chain_Append( &_Message_queue_Inactive_messages, &the_message->Node );
_Chain_Append( &the_message_queue->Inactive_messages, &the_message->Node );
}
/*PAGE
@@ -116,17 +122,6 @@ STATIC INLINE boolean _Message_queue_Is_null (
return ( the_message_queue == NULL );
}
/*PAGE
*
* _Message_queue_Allocate
*
*/
STATIC INLINE Message_queue_Control *_Message_queue_Allocate ( void )
{
return (Message_queue_Control *)
_Objects_Allocate( &_Message_queue_Information );
}
/*PAGE
*
@@ -138,6 +133,12 @@ STATIC INLINE void _Message_queue_Free (
Message_queue_Control *the_message_queue
)
{
if (the_message_queue->message_buffers)
{
_Workspace_Free((void *) the_message_queue->message_buffers);
the_message_queue->message_buffers = 0;
}
_Objects_Free( &_Message_queue_Information, &the_message_queue->Object );
}

View File

@@ -82,19 +82,6 @@ STATIC INLINE boolean _Attributes_Is_priority(
return ( attribute_set & RTEMS_PRIORITY );
}
/*PAGE
*
* _Attributes_Is_limit
*
*/
STATIC INLINE boolean _Attributes_Is_limit(
rtems_attribute attribute_set
)
{
return ( attribute_set & RTEMS_LIMIT );
}
/*PAGE
*
* _Attributes_Is_binary_semaphore

View File

@@ -17,6 +17,8 @@
#ifndef __MESSAGE_QUEUE_inl
#define __MESSAGE_QUEUE_inl
#include <rtems/wkspace.h>
/*PAGE
*
* _Message_queue_Copy_buffer
@@ -24,11 +26,12 @@
*/
STATIC INLINE void _Message_queue_Copy_buffer (
Message_queue_Buffer *source,
Message_queue_Buffer *destination
void *source,
void *destination,
unsigned32 size
)
{
*destination = *source;
memcpy(destination, source, size);
}
/*PAGE
@@ -38,10 +41,12 @@ STATIC INLINE void _Message_queue_Copy_buffer (
*/
STATIC INLINE Message_queue_Buffer_control *
_Message_queue_Allocate_message_buffer ( void )
_Message_queue_Allocate_message_buffer (
Message_queue_Control *the_message_queue
)
{
return (Message_queue_Buffer_control *)
_Chain_Get( &_Message_queue_Inactive_messages );
_Chain_Get( &the_message_queue->Inactive_messages );
}
/*PAGE
@@ -51,10 +56,11 @@ STATIC INLINE Message_queue_Buffer_control *
*/
STATIC INLINE void _Message_queue_Free_message_buffer (
Message_queue_Buffer_control *the_message
Message_queue_Control *the_message_queue,
Message_queue_Buffer_control *the_message
)
{
_Chain_Append( &_Message_queue_Inactive_messages, &the_message->Node );
_Chain_Append( &the_message_queue->Inactive_messages, &the_message->Node );
}
/*PAGE
@@ -116,17 +122,6 @@ STATIC INLINE boolean _Message_queue_Is_null (
return ( the_message_queue == NULL );
}
/*PAGE
*
* _Message_queue_Allocate
*
*/
STATIC INLINE Message_queue_Control *_Message_queue_Allocate ( void )
{
return (Message_queue_Control *)
_Objects_Allocate( &_Message_queue_Information );
}
/*PAGE
*
@@ -138,6 +133,12 @@ STATIC INLINE void _Message_queue_Free (
Message_queue_Control *the_message_queue
)
{
if (the_message_queue->message_buffers)
{
_Workspace_Free((void *) the_message_queue->message_buffers);
the_message_queue->message_buffers = 0;
}
_Objects_Free( &_Message_queue_Information, &the_message_queue->Object );
}

View File

@@ -60,15 +60,6 @@
#define _Attributes_Is_priority( _attribute_set ) \
( (_attribute_set) & RTEMS_PRIORITY )
/*PAGE
*
* _Attributes_Is_limit
*
*/
#define _Attributes_Is_limit( _attribute_set ) \
( (_attribute_set) & RTEMS_LIMIT )
/*PAGE
*
* _Attributes_Is_binary_semaphore

View File

@@ -60,15 +60,6 @@
#define _Attributes_Is_priority( _attribute_set ) \
( (_attribute_set) & RTEMS_PRIORITY )
/*PAGE
*
* _Attributes_Is_limit
*
*/
#define _Attributes_Is_limit( _attribute_set ) \
( (_attribute_set) & RTEMS_LIMIT )
/*PAGE
*
* _Attributes_Is_binary_semaphore

View File

@@ -26,8 +26,7 @@
#include <rtems/wkspace.h>
void _Message_queue_Manager_initialization(
unsigned32 maximum_message_queues,
unsigned32 maximum_messages
unsigned32 maximum_message_queues
)
{
}
@@ -35,7 +34,8 @@ void _Message_queue_Manager_initialization(
rtems_status_code rtems_message_queue_create(
Objects_Name name,
unsigned32 count,
rtems_attribute attribute_set,
unsigned32 max_message_size,
rtems_attribute attribute_set,
Objects_Id *id
)
{
@@ -60,7 +60,8 @@ rtems_status_code rtems_message_queue_delete(
rtems_status_code rtems_message_queue_send(
Objects_Id id,
void *buffer
void *buffer,
unsigned32 size
)
{
return( RTEMS_NOT_CONFIGURED );
@@ -68,7 +69,8 @@ rtems_status_code rtems_message_queue_send(
rtems_status_code rtems_message_queue_urgent(
Objects_Id id,
void *buffer
void *buffer,
unsigned32 size
)
{
return( RTEMS_NOT_CONFIGURED );
@@ -77,6 +79,7 @@ rtems_status_code rtems_message_queue_urgent(
rtems_status_code rtems_message_queue_broadcast(
Objects_Id id,
void *buffer,
unsigned32 size,
unsigned32 *count
)
{
@@ -86,8 +89,9 @@ rtems_status_code rtems_message_queue_broadcast(
rtems_status_code rtems_message_queue_receive(
Objects_Id id,
void *buffer,
unsigned32 *size_p,
unsigned32 option_set,
rtems_interval timeout
rtems_interval timeout
)
{
return( RTEMS_NOT_CONFIGURED );
@@ -110,8 +114,9 @@ unsigned32 _Message_queue_Flush_support(
boolean _Message_queue_Seize(
Message_queue_Control *the_message_queue,
rtems_option option_set,
Message_queue_Buffer *buffer
rtems_option option_set,
void *buffer,
unsigned32 *size_p
)
{
_Thread_Executing->Wait.return_code = RTEMS_UNSATISFIED;
@@ -120,7 +125,8 @@ boolean _Message_queue_Seize(
rtems_status_code _Message_queue_Submit(
Objects_Id id,
Message_queue_Buffer *buffer,
void *buffer,
unsigned32 size,
Message_queue_Submit_types submit_type
)
{

View File

@@ -32,14 +32,14 @@ extern "C" {
*/
typedef struct {
Objects_Name name; /* task name */
unsigned32 stack_size; /* task stack size */
Objects_Name name; /* task name */
unsigned32 stack_size; /* task stack size */
rtems_task_priority initial_priority; /* task priority */
rtems_attribute attribute_set; /* task attributes */
rtems_task_entry entry_point; /* task entry point */
rtems_mode mode_set; /* task initial mode */
unsigned32 argument; /* task argument */
} rtems_initialization_tasks_table;
rtems_attribute attribute_set; /* task attributes */
rtems_task_entry entry_point; /* task entry point */
rtems_mode mode_set; /* task initial mode */
unsigned32 argument; /* task argument */
} rtems_initialization_tasks_table;
/*
*
@@ -56,14 +56,12 @@ typedef struct {
typedef unsigned32 rtems_device_major_number;
typedef unsigned32 rtems_device_minor_number;
typedef void rtems_device_driver;
typedef rtems_status_code rtems_device_driver;
typedef rtems_device_driver ( *rtems_device_driver_entry )(
rtems_device_major_number,
rtems_device_minor_number,
void *,
Objects_Id,
unsigned32 *
void *
);
typedef struct {
@@ -173,12 +171,13 @@ typedef rtems_mpci_entry ( *rtems_mpci_receive_entry )(
typedef struct {
unsigned32 default_timeout; /* in ticks */
unsigned32 maximum_packet_size;
rtems_mpci_initialization_entry initialization;
rtems_mpci_get_packet_entry get_packet;
rtems_mpci_return_packet_entry return_packet;
rtems_mpci_send_entry send_packet;
rtems_mpci_receive_entry receive_packet;
} rtems_mpci_table;
} rtems_mpci_table;
/*
* The following records define the Multiprocessor Configuration
@@ -192,8 +191,7 @@ struct Configuration_Table_MP {
unsigned32 maximum_nodes; /* maximum # nodes in system */
unsigned32 maximum_global_objects; /* maximum # global objects */
unsigned32 maximum_proxies; /* maximum # proxies */
rtems_mpci_table *User_mpci_table;
/* pointer to MPCI table */
rtems_mpci_table *User_mpci_table; /* pointer to MPCI table */
};
/*
@@ -209,25 +207,24 @@ struct Configuration_Table_MP {
*/
struct Configuration_Table {
void *work_space_start;
unsigned32 work_space_size;
unsigned32 maximum_tasks;
unsigned32 maximum_timers;
unsigned32 maximum_semaphores;
unsigned32 maximum_message_queues;
unsigned32 maximum_messages;
unsigned32 maximum_partitions;
unsigned32 maximum_regions;
unsigned32 maximum_ports;
unsigned32 maximum_periods;
unsigned32 maximum_extensions;
unsigned32 microseconds_per_tick;
unsigned32 ticks_per_timeslice;
unsigned32 number_of_initialization_tasks;
void *work_space_start;
unsigned32 work_space_size;
unsigned32 maximum_tasks;
unsigned32 maximum_timers;
unsigned32 maximum_semaphores;
unsigned32 maximum_message_queues;
unsigned32 maximum_partitions;
unsigned32 maximum_regions;
unsigned32 maximum_ports;
unsigned32 maximum_periods;
unsigned32 maximum_extensions;
unsigned32 microseconds_per_tick;
unsigned32 ticks_per_timeslice;
unsigned32 number_of_initialization_tasks;
rtems_initialization_tasks_table *User_initialization_tasks_table;
unsigned32 number_of_device_drivers;
unsigned32 number_of_device_drivers;
rtems_driver_address_table *Device_driver_table;
rtems_extensions_table *User_extension_table;
rtems_extensions_table *User_extension_table;
rtems_multiprocessing_table *User_multiprocessing_table;
};
@@ -244,7 +241,7 @@ extern const rtems_multiprocessing_table
* configuration information.
*/
EXTERN rtems_configuration_table *_Configuration_Table;
EXTERN rtems_configuration_table *_Configuration_Table;
EXTERN rtems_multiprocessing_table *_Configuration_MP_table;
EXTERN rtems_mpci_table *_Configuration_MPCI_table;
@@ -258,7 +255,7 @@ EXTERN rtems_mpci_table *_Configuration_MPCI_table;
*/
STATIC INLINE void _Configuration_Handler_initialization(
rtems_configuration_table *configuration_table,
rtems_configuration_table *configuration_table,
rtems_multiprocessing_table *multiprocessing_table,
rtems_mpci_table *users_mpci_table
);

View File

@@ -10,10 +10,12 @@
* This material may be reproduced by or for the U.S. Government pursuant
* to the copyright license under the clause at DFARS 252.227-7013. This
* notice must appear in all copies of this file and its derivatives.
*
* $Id$
*/
#ifndef __RTEMS_DIRECTIVES_h
#define RTEMS___DIRECTIVES_h
#define __RTEMS_DIRECTIVES_h
#ifdef __cplusplus
extern "C" {
@@ -85,20 +87,24 @@ extern "C" {
#define RTEMS_DUAL_PORTED_MEMORY_EXTERNAL_TO_INTERNAL 63
#define RTEMS_DUAL_PORTED_MEMORY_INTERNAL_TO_EXTERNAL 64
#define RTEMS_IO_INITIALIZE 65
#define RTEMS_IO_OPEN 66
#define RTEMS_IO_CLOSE 67
#define RTEMS_IO_READ 68
#define RTEMS_IO_WRITE 69
#define RTEMS_IO_CONTROL 70
#define RTEMS_FATAL_ERROR_OCCURRED 71
#define RTEMS_RATE_MONOTONIC_CREATE 72
#define RTEMS_RATE_MONOTONIC_NAME_TO_ID 73
#define RTEMS_RATE_MONOTONIC_DELETE 74
#define RTEMS_RATE_MONOTONIC_CANCEL 75
#define RTEMS_RATE_MONOTONIC_PERIOD 76
#define RTEMS_MULTIPROCESSING_ANNOUNCE 77
#define RTEMS_DEBUG_ENABLE 78
#define RTEMS_DEBUG_DISABLE 79
#define RTEMS_IO_REGISTER_NAME 66
#define RTEMS_IO_LOOKUP_NAME 67
#define RTEMS_IO_OPEN 68
#define RTEMS_IO_CLOSE 69
#define RTEMS_IO_READ 70
#define RTEMS_IO_WRITE 71
#define RTEMS_IO_CONTROL 72
#define RTEMS_FATAL_ERROR_OCCURRED 73
#define RTEMS_RATE_MONOTONIC_CREATE 74
#define RTEMS_RATE_MONOTONIC_NAME_TO_ID 75
#define RTEMS_RATE_MONOTONIC_DELETE 76
#define RTEMS_RATE_MONOTONIC_CANCEL 77
#define RTEMS_RATE_MONOTONIC_PERIOD 78
#define RTEMS_MULTIPROCESSING_ANNOUNCE 79
#define RTEMS_DEBUG_ENABLE 80
#define RTEMS_DEBUG_DISABLE 81
#define RTEMS_NUMBER_OF_ENTRY_POINTS 82
#ifdef __cplusplus
}

View File

@@ -34,29 +34,32 @@ extern "C" {
#include <rtems/config.h>
/*
* The following type defines the set of IO operations which are
* recognized by _IO_Handler and can be supported by a RTEMS
* device driver.
*/
typedef enum {
IO_INITIALIZE_OPERATION = 0,
IO_OPEN_OPERATION = 1,
IO_CLOSE_OPERATION = 2,
IO_READ_OPERATION = 3,
IO_WRITE_OPERATION = 4,
IO_CONTROL_OPERATION = 5
} IO_operations;
/*
* The following declare the data required to manage the Device Driver
* Address Table.
*/
EXTERN unsigned32 _IO_Number_of_drivers;
EXTERN unsigned32 _IO_Number_of_drivers;
EXTERN rtems_driver_address_table *_IO_Driver_address_table;
/*
* Table for the io device names
*/
typedef struct {
char *device_name;
unsigned32 device_name_length;
rtems_device_major_number major;
rtems_device_minor_number minor;
} rtems_driver_name_t;
/*XXX this really should be allocated some better way... */
/*XXX it should probably be a chain and use a 'maximum' drivers field
* in config table */
#define RTEMS_MAX_DRIVER_NAMES 20
EXTERN rtems_driver_name_t rtems_driver_name_table[RTEMS_MAX_DRIVER_NAMES];
/*
* _IO_Manager_initialization
*
@@ -70,6 +73,36 @@ STATIC INLINE void _IO_Manager_initialization(
unsigned32 number_of_drivers
);
/*
* rtems_io_register_name
*
* DESCRIPTION:
*
* Associate a name with a driver.
*
*/
rtems_status_code rtems_io_register_name(
char *device_name,
rtems_device_major_number major,
rtems_device_minor_number minor
);
/*
* rtems_io_lookup_name
*
* DESCRIPTION:
*
* Find what driver "owns" this name
*/
rtems_status_code rtems_io_lookup_name(
const char *pathname,
rtems_driver_name_t **rnp
);
/*
* rtems_io_initialize
*
@@ -82,8 +115,7 @@ STATIC INLINE void _IO_Manager_initialization(
rtems_status_code rtems_io_initialize(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *argument,
unsigned32 *return_value
void *argument
);
/*
@@ -98,8 +130,7 @@ rtems_status_code rtems_io_initialize(
rtems_status_code rtems_io_open(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *argument,
unsigned32 *return_value
void *argument
);
/*
@@ -114,8 +145,7 @@ rtems_status_code rtems_io_open(
rtems_status_code rtems_io_close(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *argument,
unsigned32 *return_value
void *argument
);
/*
@@ -130,8 +160,7 @@ rtems_status_code rtems_io_close(
rtems_status_code rtems_io_read(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *argument,
unsigned32 *return_value
void *argument
);
/*
@@ -146,8 +175,7 @@ rtems_status_code rtems_io_read(
rtems_status_code rtems_io_write(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *argument,
unsigned32 *return_value
void *argument
);
/*
@@ -162,8 +190,7 @@ rtems_status_code rtems_io_write(
rtems_status_code rtems_io_control(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *argument,
unsigned32 *return_value
void *argument
);
/*
@@ -177,23 +204,6 @@ rtems_status_code rtems_io_control(
void _IO_Initialize_all_drivers( void );
/*
* _IO_Handler_routine
*
* DESCRIPTION:
*
* This routine provides the common foundation for all of the IO
* Manager's directives.
*/
rtems_status_code _IO_Handler_routine(
IO_operations operation,
rtems_device_major_number major,
rtems_device_minor_number minor,
void *argument,
unsigned32 *return_value
);
#include <rtems/io.inl>
#ifdef __cplusplus

View File

@@ -49,7 +49,7 @@ const char _RTEMS_version[] =
* This table is used by the single entry point code.
*/
const void * _Entry_points[ NUMBER_OF_ENTRY_POINTS + 1 ] = {
const void * _Entry_points[ RTEMS_NUMBER_OF_ENTRY_POINTS ] = {
(void *) rtems_initialize_executive, /* 0 */
(void *) rtems_initialize_executive_early, /* 1 */
(void *) rtems_initialize_executive_late, /* 2 */
@@ -116,20 +116,22 @@ const void * _Entry_points[ NUMBER_OF_ENTRY_POINTS + 1 ] = {
(void *) rtems_port_external_to_internal, /* 63 */
(void *) rtems_port_internal_to_external, /* 64 */
(void *) rtems_io_initialize, /* 65 */
(void *) rtems_io_open, /* 66 */
(void *) rtems_io_close, /* 67 */
(void *) rtems_io_read, /* 68 */
(void *) rtems_io_write, /* 69 */
(void *) rtems_io_control, /* 70 */
(void *) rtems_fatal_error_occurred, /* 71 */
(void *) rtems_rate_monotonic_create, /* 72 */
(void *) rtems_rate_monotonic_ident, /* 73 */
(void *) rtems_rate_monotonic_delete, /* 74 */
(void *) rtems_rate_monotonic_cancel, /* 75 */
(void *) rtems_rate_monotonic_period, /* 76 */
(void *) rtems_multiprocessing_announce, /* 77 */
(void *) rtems_debug_enable, /* 78 */
(void *) rtems_debug_disable /* 79 */
(void *) rtems_io_register_name, /* 66 */
(void *) rtems_io_lookup_name, /* 67 */
(void *) rtems_io_open, /* 68 */
(void *) rtems_io_close, /* 69 */
(void *) rtems_io_read, /* 70 */
(void *) rtems_io_write, /* 71 */
(void *) rtems_io_control, /* 72 */
(void *) rtems_fatal_error_occurred, /* 73 */
(void *) rtems_rate_monotonic_create, /* 74 */
(void *) rtems_rate_monotonic_ident, /* 75 */
(void *) rtems_rate_monotonic_delete, /* 76 */
(void *) rtems_rate_monotonic_cancel, /* 77 */
(void *) rtems_rate_monotonic_period, /* 78 */
(void *) rtems_multiprocessing_announce, /* 79 */
(void *) rtems_debug_enable, /* 80 */
(void *) rtems_debug_disable /* 81 */
};
#ifdef __cplusplus

View File

@@ -32,14 +32,14 @@ extern "C" {
*/
typedef struct {
Objects_Name name; /* task name */
unsigned32 stack_size; /* task stack size */
Objects_Name name; /* task name */
unsigned32 stack_size; /* task stack size */
rtems_task_priority initial_priority; /* task priority */
rtems_attribute attribute_set; /* task attributes */
rtems_task_entry entry_point; /* task entry point */
rtems_mode mode_set; /* task initial mode */
unsigned32 argument; /* task argument */
} rtems_initialization_tasks_table;
rtems_attribute attribute_set; /* task attributes */
rtems_task_entry entry_point; /* task entry point */
rtems_mode mode_set; /* task initial mode */
unsigned32 argument; /* task argument */
} rtems_initialization_tasks_table;
/*
*
@@ -56,14 +56,12 @@ typedef struct {
typedef unsigned32 rtems_device_major_number;
typedef unsigned32 rtems_device_minor_number;
typedef void rtems_device_driver;
typedef rtems_status_code rtems_device_driver;
typedef rtems_device_driver ( *rtems_device_driver_entry )(
rtems_device_major_number,
rtems_device_minor_number,
void *,
Objects_Id,
unsigned32 *
void *
);
typedef struct {
@@ -173,12 +171,13 @@ typedef rtems_mpci_entry ( *rtems_mpci_receive_entry )(
typedef struct {
unsigned32 default_timeout; /* in ticks */
unsigned32 maximum_packet_size;
rtems_mpci_initialization_entry initialization;
rtems_mpci_get_packet_entry get_packet;
rtems_mpci_return_packet_entry return_packet;
rtems_mpci_send_entry send_packet;
rtems_mpci_receive_entry receive_packet;
} rtems_mpci_table;
} rtems_mpci_table;
/*
* The following records define the Multiprocessor Configuration
@@ -192,8 +191,7 @@ struct Configuration_Table_MP {
unsigned32 maximum_nodes; /* maximum # nodes in system */
unsigned32 maximum_global_objects; /* maximum # global objects */
unsigned32 maximum_proxies; /* maximum # proxies */
rtems_mpci_table *User_mpci_table;
/* pointer to MPCI table */
rtems_mpci_table *User_mpci_table; /* pointer to MPCI table */
};
/*
@@ -209,25 +207,24 @@ struct Configuration_Table_MP {
*/
struct Configuration_Table {
void *work_space_start;
unsigned32 work_space_size;
unsigned32 maximum_tasks;
unsigned32 maximum_timers;
unsigned32 maximum_semaphores;
unsigned32 maximum_message_queues;
unsigned32 maximum_messages;
unsigned32 maximum_partitions;
unsigned32 maximum_regions;
unsigned32 maximum_ports;
unsigned32 maximum_periods;
unsigned32 maximum_extensions;
unsigned32 microseconds_per_tick;
unsigned32 ticks_per_timeslice;
unsigned32 number_of_initialization_tasks;
void *work_space_start;
unsigned32 work_space_size;
unsigned32 maximum_tasks;
unsigned32 maximum_timers;
unsigned32 maximum_semaphores;
unsigned32 maximum_message_queues;
unsigned32 maximum_partitions;
unsigned32 maximum_regions;
unsigned32 maximum_ports;
unsigned32 maximum_periods;
unsigned32 maximum_extensions;
unsigned32 microseconds_per_tick;
unsigned32 ticks_per_timeslice;
unsigned32 number_of_initialization_tasks;
rtems_initialization_tasks_table *User_initialization_tasks_table;
unsigned32 number_of_device_drivers;
unsigned32 number_of_device_drivers;
rtems_driver_address_table *Device_driver_table;
rtems_extensions_table *User_extension_table;
rtems_extensions_table *User_extension_table;
rtems_multiprocessing_table *User_multiprocessing_table;
};
@@ -244,7 +241,7 @@ extern const rtems_multiprocessing_table
* configuration information.
*/
EXTERN rtems_configuration_table *_Configuration_Table;
EXTERN rtems_configuration_table *_Configuration_Table;
EXTERN rtems_multiprocessing_table *_Configuration_MP_table;
EXTERN rtems_mpci_table *_Configuration_MPCI_table;
@@ -258,7 +255,7 @@ EXTERN rtems_mpci_table *_Configuration_MPCI_table;
*/
STATIC INLINE void _Configuration_Handler_initialization(
rtems_configuration_table *configuration_table,
rtems_configuration_table *configuration_table,
rtems_multiprocessing_table *multiprocessing_table,
rtems_mpci_table *users_mpci_table
);

View File

@@ -10,10 +10,12 @@
* This material may be reproduced by or for the U.S. Government pursuant
* to the copyright license under the clause at DFARS 252.227-7013. This
* notice must appear in all copies of this file and its derivatives.
*
* $Id$
*/
#ifndef __RTEMS_DIRECTIVES_h
#define RTEMS___DIRECTIVES_h
#define __RTEMS_DIRECTIVES_h
#ifdef __cplusplus
extern "C" {
@@ -85,20 +87,24 @@ extern "C" {
#define RTEMS_DUAL_PORTED_MEMORY_EXTERNAL_TO_INTERNAL 63
#define RTEMS_DUAL_PORTED_MEMORY_INTERNAL_TO_EXTERNAL 64
#define RTEMS_IO_INITIALIZE 65
#define RTEMS_IO_OPEN 66
#define RTEMS_IO_CLOSE 67
#define RTEMS_IO_READ 68
#define RTEMS_IO_WRITE 69
#define RTEMS_IO_CONTROL 70
#define RTEMS_FATAL_ERROR_OCCURRED 71
#define RTEMS_RATE_MONOTONIC_CREATE 72
#define RTEMS_RATE_MONOTONIC_NAME_TO_ID 73
#define RTEMS_RATE_MONOTONIC_DELETE 74
#define RTEMS_RATE_MONOTONIC_CANCEL 75
#define RTEMS_RATE_MONOTONIC_PERIOD 76
#define RTEMS_MULTIPROCESSING_ANNOUNCE 77
#define RTEMS_DEBUG_ENABLE 78
#define RTEMS_DEBUG_DISABLE 79
#define RTEMS_IO_REGISTER_NAME 66
#define RTEMS_IO_LOOKUP_NAME 67
#define RTEMS_IO_OPEN 68
#define RTEMS_IO_CLOSE 69
#define RTEMS_IO_READ 70
#define RTEMS_IO_WRITE 71
#define RTEMS_IO_CONTROL 72
#define RTEMS_FATAL_ERROR_OCCURRED 73
#define RTEMS_RATE_MONOTONIC_CREATE 74
#define RTEMS_RATE_MONOTONIC_NAME_TO_ID 75
#define RTEMS_RATE_MONOTONIC_DELETE 76
#define RTEMS_RATE_MONOTONIC_CANCEL 77
#define RTEMS_RATE_MONOTONIC_PERIOD 78
#define RTEMS_MULTIPROCESSING_ANNOUNCE 79
#define RTEMS_DEBUG_ENABLE 80
#define RTEMS_DEBUG_DISABLE 81
#define RTEMS_NUMBER_OF_ENTRY_POINTS 82
#ifdef __cplusplus
}

View File

@@ -34,29 +34,32 @@ extern "C" {
#include <rtems/config.h>
/*
* The following type defines the set of IO operations which are
* recognized by _IO_Handler and can be supported by a RTEMS
* device driver.
*/
typedef enum {
IO_INITIALIZE_OPERATION = 0,
IO_OPEN_OPERATION = 1,
IO_CLOSE_OPERATION = 2,
IO_READ_OPERATION = 3,
IO_WRITE_OPERATION = 4,
IO_CONTROL_OPERATION = 5
} IO_operations;
/*
* The following declare the data required to manage the Device Driver
* Address Table.
*/
EXTERN unsigned32 _IO_Number_of_drivers;
EXTERN unsigned32 _IO_Number_of_drivers;
EXTERN rtems_driver_address_table *_IO_Driver_address_table;
/*
* Table for the io device names
*/
typedef struct {
char *device_name;
unsigned32 device_name_length;
rtems_device_major_number major;
rtems_device_minor_number minor;
} rtems_driver_name_t;
/*XXX this really should be allocated some better way... */
/*XXX it should probably be a chain and use a 'maximum' drivers field
* in config table */
#define RTEMS_MAX_DRIVER_NAMES 20
EXTERN rtems_driver_name_t rtems_driver_name_table[RTEMS_MAX_DRIVER_NAMES];
/*
* _IO_Manager_initialization
*
@@ -70,6 +73,36 @@ STATIC INLINE void _IO_Manager_initialization(
unsigned32 number_of_drivers
);
/*
* rtems_io_register_name
*
* DESCRIPTION:
*
* Associate a name with a driver.
*
*/
rtems_status_code rtems_io_register_name(
char *device_name,
rtems_device_major_number major,
rtems_device_minor_number minor
);
/*
* rtems_io_lookup_name
*
* DESCRIPTION:
*
* Find what driver "owns" this name
*/
rtems_status_code rtems_io_lookup_name(
const char *pathname,
rtems_driver_name_t **rnp
);
/*
* rtems_io_initialize
*
@@ -82,8 +115,7 @@ STATIC INLINE void _IO_Manager_initialization(
rtems_status_code rtems_io_initialize(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *argument,
unsigned32 *return_value
void *argument
);
/*
@@ -98,8 +130,7 @@ rtems_status_code rtems_io_initialize(
rtems_status_code rtems_io_open(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *argument,
unsigned32 *return_value
void *argument
);
/*
@@ -114,8 +145,7 @@ rtems_status_code rtems_io_open(
rtems_status_code rtems_io_close(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *argument,
unsigned32 *return_value
void *argument
);
/*
@@ -130,8 +160,7 @@ rtems_status_code rtems_io_close(
rtems_status_code rtems_io_read(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *argument,
unsigned32 *return_value
void *argument
);
/*
@@ -146,8 +175,7 @@ rtems_status_code rtems_io_read(
rtems_status_code rtems_io_write(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *argument,
unsigned32 *return_value
void *argument
);
/*
@@ -162,8 +190,7 @@ rtems_status_code rtems_io_write(
rtems_status_code rtems_io_control(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *argument,
unsigned32 *return_value
void *argument
);
/*
@@ -177,23 +204,6 @@ rtems_status_code rtems_io_control(
void _IO_Initialize_all_drivers( void );
/*
* _IO_Handler_routine
*
* DESCRIPTION:
*
* This routine provides the common foundation for all of the IO
* Manager's directives.
*/
rtems_status_code _IO_Handler_routine(
IO_operations operation,
rtems_device_major_number major,
rtems_device_minor_number minor,
void *argument,
unsigned32 *return_value
);
#include <rtems/io.inl>
#ifdef __cplusplus

View File

@@ -49,7 +49,7 @@ const char _RTEMS_version[] =
* This table is used by the single entry point code.
*/
const void * _Entry_points[ NUMBER_OF_ENTRY_POINTS + 1 ] = {
const void * _Entry_points[ RTEMS_NUMBER_OF_ENTRY_POINTS ] = {
(void *) rtems_initialize_executive, /* 0 */
(void *) rtems_initialize_executive_early, /* 1 */
(void *) rtems_initialize_executive_late, /* 2 */
@@ -116,20 +116,22 @@ const void * _Entry_points[ NUMBER_OF_ENTRY_POINTS + 1 ] = {
(void *) rtems_port_external_to_internal, /* 63 */
(void *) rtems_port_internal_to_external, /* 64 */
(void *) rtems_io_initialize, /* 65 */
(void *) rtems_io_open, /* 66 */
(void *) rtems_io_close, /* 67 */
(void *) rtems_io_read, /* 68 */
(void *) rtems_io_write, /* 69 */
(void *) rtems_io_control, /* 70 */
(void *) rtems_fatal_error_occurred, /* 71 */
(void *) rtems_rate_monotonic_create, /* 72 */
(void *) rtems_rate_monotonic_ident, /* 73 */
(void *) rtems_rate_monotonic_delete, /* 74 */
(void *) rtems_rate_monotonic_cancel, /* 75 */
(void *) rtems_rate_monotonic_period, /* 76 */
(void *) rtems_multiprocessing_announce, /* 77 */
(void *) rtems_debug_enable, /* 78 */
(void *) rtems_debug_disable /* 79 */
(void *) rtems_io_register_name, /* 66 */
(void *) rtems_io_lookup_name, /* 67 */
(void *) rtems_io_open, /* 68 */
(void *) rtems_io_close, /* 69 */
(void *) rtems_io_read, /* 70 */
(void *) rtems_io_write, /* 71 */
(void *) rtems_io_control, /* 72 */
(void *) rtems_fatal_error_occurred, /* 73 */
(void *) rtems_rate_monotonic_create, /* 74 */
(void *) rtems_rate_monotonic_ident, /* 75 */
(void *) rtems_rate_monotonic_delete, /* 76 */
(void *) rtems_rate_monotonic_cancel, /* 77 */
(void *) rtems_rate_monotonic_period, /* 78 */
(void *) rtems_multiprocessing_announce, /* 79 */
(void *) rtems_debug_enable, /* 80 */
(void *) rtems_debug_disable /* 81 */
};
#ifdef __cplusplus

View File

@@ -23,11 +23,27 @@ void _IO_Initialize_all_drivers( void )
{
}
rtems_status_code rtems_io_register_name(
char *device_name,
rtems_device_major_number major,
rtems_device_minor_number minor
)
{
return RTEMS_NOT_CONFIGURED;
}
rtems_status_code rtems_io_lookup_name(
const char *pathname,
rtems_driver_name_t **rnp
)
{
return RTEMS_NOT_CONFIGURED;
}
rtems_status_code rtems_io_initialize(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *argument,
unsigned32 *return_value
void *argument
)
{
return( RTEMS_NOT_CONFIGURED );
@@ -36,8 +52,7 @@ rtems_status_code rtems_io_initialize(
rtems_status_code rtems_io_open(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *argument,
unsigned32 *return_value
void *argument
)
{
return( RTEMS_NOT_CONFIGURED );
@@ -46,8 +61,7 @@ rtems_status_code rtems_io_open(
rtems_status_code rtems_io_close(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *argument,
unsigned32 *return_value
void *argument
)
{
return( RTEMS_NOT_CONFIGURED );
@@ -56,8 +70,7 @@ rtems_status_code rtems_io_close(
rtems_status_code rtems_io_read(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *argument,
unsigned32 *return_value
void *argument
)
{
return( RTEMS_NOT_CONFIGURED );
@@ -66,8 +79,7 @@ rtems_status_code rtems_io_read(
rtems_status_code rtems_io_write(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *argument,
unsigned32 *return_value
void *argument
)
{
return( RTEMS_NOT_CONFIGURED );
@@ -76,19 +88,7 @@ rtems_status_code rtems_io_write(
rtems_status_code rtems_io_control(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *argument,
unsigned32 *return_value
)
{
return( RTEMS_NOT_CONFIGURED );
}
rtems_status_code _IO_Handler_routine(
IO_operations operation,
rtems_device_major_number major,
rtems_device_minor_number minor,
void *argument,
unsigned32 *return_value
void *argument
)
{
return( RTEMS_NOT_CONFIGURED );

View File

@@ -177,8 +177,7 @@ rtems_interrupt_level rtems_initialize_executive_early(
_Event_Manager_initialization();
_Message_queue_Manager_initialization(
configuration_table->maximum_message_queues,
configuration_table->maximum_messages
configuration_table->maximum_message_queues
);
_Semaphore_Manager_initialization(

View File

@@ -18,6 +18,9 @@
#include <rtems/io.h>
#include <rtems/isr.h>
#include <rtems/thread.h>
#include <rtems/intr.h>
#include <string.h>
/*PAGE
*
@@ -33,12 +36,82 @@
void _IO_Initialize_all_drivers( void )
{
rtems_device_major_number major;
unsigned32 ignored;
for ( major=0 ; major < _IO_Number_of_drivers ; major ++ )
(void) rtems_io_initialize( major, 0, _Configuration_Table, &ignored );
(void) rtems_io_initialize( major, 0, _Configuration_Table);
}
/*PAGE
*
* rtems_io_register_name
*
* Associate a name with a driver
*
* Input Paramters:
*
* Output Parameters:
*/
rtems_status_code rtems_io_register_name(
char *device_name,
rtems_device_major_number major,
rtems_device_minor_number minor
)
{
rtems_driver_name_t *np;
unsigned32 level;
/* find an empty slot */
for (np = rtems_driver_name_table; np < &rtems_driver_name_table[RTEMS_MAX_DRIVER_NAMES]; np++)
{
rtems_interrupt_disable(level);
if (np->device_name == 0)
{
np->device_name = device_name;
np->device_name_length = strlen(device_name);
np->major = major;
np->minor = minor;
rtems_interrupt_enable(level);
return RTEMS_SUCCESSFUL;
}
rtems_interrupt_enable(level);
}
return RTEMS_TOO_MANY;
}
/*PAGE
*
* rtems_io_lookup_name
*
* Find what driver "owns" this name
*
* Input Paramters:
*
* Output Parameters:
*/
rtems_status_code rtems_io_lookup_name(
const char *pathname,
rtems_driver_name_t **rnp
)
{
rtems_driver_name_t *np;
for (np = rtems_driver_name_table; np < &rtems_driver_name_table[RTEMS_MAX_DRIVER_NAMES]; np++)
if (np->device_name)
if (strncmp(np->device_name, pathname, np->device_name_length) == 0)
{
*rnp = np;
return RTEMS_SUCCESSFUL;
}
*rnp = 0;
return RTEMS_UNSATISFIED;
}
/*PAGE
*
* rtems_io_initialize
@@ -49,27 +122,24 @@ void _IO_Initialize_all_drivers( void )
* major - device driver number
* minor - device number
* argument - pointer to argument(s)
* return_value - pointer to driver's return value
*
* Output Parameters:
* returns - return code
* *return_value - driver's return code
*/
rtems_status_code rtems_io_initialize(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *argument,
unsigned32 *return_value
void *argument
)
{
return _IO_Handler_routine(
IO_INITIALIZE_OPERATION,
major,
minor,
argument,
return_value
);
rtems_device_driver_entry callout;
if ( major >= _IO_Number_of_drivers )
return RTEMS_INVALID_NUMBER;
callout = _IO_Driver_address_table[major].initialization;
return callout ? callout(major, minor, argument) : RTEMS_SUCCESSFUL;
}
/*PAGE
@@ -82,27 +152,24 @@ rtems_status_code rtems_io_initialize(
* major - device driver number
* minor - device number
* argument - pointer to argument(s)
* return_value - pointer to driver's return value
*
* Output Parameters:
* returns - return code
* *return_value - driver's return code
*/
rtems_status_code rtems_io_open(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *argument,
unsigned32 *return_value
void *argument
)
{
return _IO_Handler_routine(
IO_OPEN_OPERATION,
major,
minor,
argument,
return_value
);
rtems_device_driver_entry callout;
if ( major >= _IO_Number_of_drivers )
return RTEMS_INVALID_NUMBER;
callout = _IO_Driver_address_table[major].open;
return callout ? callout(major, minor, argument) : RTEMS_SUCCESSFUL;
}
/*PAGE
@@ -115,27 +182,24 @@ rtems_status_code rtems_io_open(
* major - device driver number
* minor - device number
* argument - pointer to argument(s)
* return_value - pointer to driver's return value
*
* Output Parameters:
* returns - return code
* *return_value - driver's return code
*/
rtems_status_code rtems_io_close(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *argument,
unsigned32 *return_value
void *argument
)
{
return _IO_Handler_routine(
IO_CLOSE_OPERATION,
major,
minor,
argument,
return_value
);
rtems_device_driver_entry callout;
if ( major >= _IO_Number_of_drivers )
return RTEMS_INVALID_NUMBER;
callout = _IO_Driver_address_table[major].close;
return callout ? callout(major, minor, argument) : RTEMS_SUCCESSFUL;
}
/*PAGE
@@ -148,27 +212,24 @@ rtems_status_code rtems_io_close(
* major - device driver number
* minor - device number
* argument - pointer to argument(s)
* return_value - pointer to driver's return value
*
* Output Parameters:
* returns - return code
* *return_value - driver's return code
*/
rtems_status_code rtems_io_read(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *argument,
unsigned32 *return_value
void *argument
)
{
return _IO_Handler_routine(
IO_READ_OPERATION,
major,
minor,
argument,
return_value
);
rtems_device_driver_entry callout;
if ( major >= _IO_Number_of_drivers )
return RTEMS_INVALID_NUMBER;
callout = _IO_Driver_address_table[major].read;
return callout ? callout(major, minor, argument) : RTEMS_SUCCESSFUL;
}
/*PAGE
@@ -181,27 +242,24 @@ rtems_status_code rtems_io_read(
* major - device driver number
* minor - device number
* argument - pointer to argument(s)
* return_value - pointer to driver's return value
*
* Output Parameters:
* returns - return code
* *return_value - driver's return code
*/
rtems_status_code rtems_io_write(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *argument,
unsigned32 *return_value
void *argument
)
{
return _IO_Handler_routine(
IO_WRITE_OPERATION,
major,
minor,
argument,
return_value
);
rtems_device_driver_entry callout;
if ( major >= _IO_Number_of_drivers )
return RTEMS_INVALID_NUMBER;
callout = _IO_Driver_address_table[major].write;
return callout ? callout(major, minor, argument) : RTEMS_SUCCESSFUL;
}
/*PAGE
@@ -214,103 +272,23 @@ rtems_status_code rtems_io_write(
* major - device driver number
* minor - device number
* argument - pointer to argument(s)
* return_value - pointer to driver's return value
*
* Output Parameters:
* returns - return code
* *return_value - driver's return code
*/
rtems_status_code rtems_io_control(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *argument,
unsigned32 *return_value
void *argument
)
{
return _IO_Handler_routine(
IO_CONTROL_OPERATION,
major,
minor,
argument,
return_value
);
rtems_device_driver_entry callout;
if ( major >= _IO_Number_of_drivers )
return RTEMS_INVALID_NUMBER;
callout = _IO_Driver_address_table[major].control;
return callout ? callout(major, minor, argument) : RTEMS_SUCCESSFUL;
}
/*PAGE
*
* _IO_Handler_routine
*
* This routine implements all IO manager directives.
*
* Input Paramters:
* operation - I/O operation to be performed
* major - device driver number
* minor - device number
* argument - pointer to argument(s)
* return_value - pointer to driver's return value
*
* Output Parameters:
* returns - return code
* *return_value - driver's return code
*/
rtems_status_code _IO_Handler_routine(
IO_operations operation,
rtems_device_major_number major,
rtems_device_minor_number minor,
void *argument,
unsigned32 *return_value
)
{
rtems_device_driver_entry io_callout;
/*
* NOTE: There is no range checking as in Ada because:
* + arrays in Ada are not always zero based.
* + with zero based arrays, a comparison of an unsigned
* number being less than zero would be necessary to
* check it as a range. This would cause a warning for
* checking an unsigned number for being negative.
*/
if ( major >= _IO_Number_of_drivers )
return ( RTEMS_INVALID_NUMBER );
switch ( operation ) {
case IO_INITIALIZE_OPERATION:
io_callout = _IO_Driver_address_table[ major ].initialization;
break;
case IO_OPEN_OPERATION:
io_callout = _IO_Driver_address_table[ major ].open;
break;
case IO_CLOSE_OPERATION:
io_callout = _IO_Driver_address_table[ major ].close;
break;
case IO_READ_OPERATION:
io_callout = _IO_Driver_address_table[ major ].read;
break;
case IO_WRITE_OPERATION:
io_callout = _IO_Driver_address_table[ major ].write;
break;
case IO_CONTROL_OPERATION:
io_callout = _IO_Driver_address_table[ major ].control;
break;
default: /* unreached -- only to remove warnings */
io_callout = NULL;
break;
}
if ( io_callout != NULL )
(*io_callout)(
major,
minor,
argument,
_Thread_Executing->Object.id,
return_value
);
else
*return_value = 0;
return( RTEMS_SUCCESSFUL );
}

View File

@@ -99,6 +99,18 @@ EXTERN unsigned32 _Objects_Local_node;
#define RTEMS_SEARCH_LOCAL_NODE 0x7FFFFFFF
#define RTEMS_WHO_AM_I 0
/*
* Parameters and return id's for _Objects_Get_next
*/
#define RTEMS_OBJECT_ID_INITIAL_INDEX (0)
#define RTEMS_OBJECT_ID_FINAL_INDEX (0xffff)
#define RTEMS_OBJECT_ID_INITIAL(node) (_Objects_Build_id( \
node, \
RTEMS_OBJECT_ID_INITIAL_INDEX))
#define RTEMS_OBJECT_ID_FINAL ((Objects_Id) ~0)
/*
* _Objects_Handler_initialization
*
@@ -178,6 +190,22 @@ Objects_Control *_Objects_Get (
Objects_Locations *location
);
/*
* _Objects_Get_next
*
* DESCRIPTION:
*
* Like _Objects_Get, but is used to find "next" open object.
*
*/
Objects_Control *_Objects_Get_next(
Objects_Information *information,
Objects_Id id,
unsigned32 *location_p,
Objects_Id *next_id_p
);
/*
* _Objects_Is_name_valid
*

View File

@@ -78,6 +78,7 @@ typedef void * proc_ptr;
#include <rtems/cpu.h> /* processor specific information */
#include <rtems/status.h> /* RTEMS status codes */
#include <rtems/directives.h>
/*
* Define NULL
@@ -103,6 +104,9 @@ typedef void * proc_ptr;
#define stringify( _x ) # _x
#define RTEMS_offsetof(type, field) \
((unsigned32) &(((type *) 0)->field))
/*
* The following is the extern for the RTEMS version string.
* The contents of this string are CPU specific.
@@ -115,8 +119,7 @@ extern const char _Copyright_Notice[]; /* RTEMS copyright string */
* The jump table of entry points into RTEMS directives.
*/
#define NUMBER_OF_ENTRY_POINTS 79
extern const void * _Entry_points[ NUMBER_OF_ENTRY_POINTS + 1 ];
extern const void * _Entry_points[ RTEMS_NUMBER_OF_ENTRY_POINTS ];
/*
* The following defines the CPU dependent information table.

View File

@@ -115,6 +115,7 @@ typedef struct {
union {
unsigned32 segment_size; /* size of segment requested */
rtems_event_set event_condition;
unsigned32 *message_size_p; /* ptr for return size of message */
} Extra;
void *return_argument; /* address of user return param */
rtems_status_code return_code; /* status for thread awakened */

View File

@@ -99,6 +99,18 @@ EXTERN unsigned32 _Objects_Local_node;
#define RTEMS_SEARCH_LOCAL_NODE 0x7FFFFFFF
#define RTEMS_WHO_AM_I 0
/*
* Parameters and return id's for _Objects_Get_next
*/
#define RTEMS_OBJECT_ID_INITIAL_INDEX (0)
#define RTEMS_OBJECT_ID_FINAL_INDEX (0xffff)
#define RTEMS_OBJECT_ID_INITIAL(node) (_Objects_Build_id( \
node, \
RTEMS_OBJECT_ID_INITIAL_INDEX))
#define RTEMS_OBJECT_ID_FINAL ((Objects_Id) ~0)
/*
* _Objects_Handler_initialization
*
@@ -178,6 +190,22 @@ Objects_Control *_Objects_Get (
Objects_Locations *location
);
/*
* _Objects_Get_next
*
* DESCRIPTION:
*
* Like _Objects_Get, but is used to find "next" open object.
*
*/
Objects_Control *_Objects_Get_next(
Objects_Information *information,
Objects_Id id,
unsigned32 *location_p,
Objects_Id *next_id_p
);
/*
* _Objects_Is_name_valid
*

View File

@@ -115,6 +115,7 @@ typedef struct {
union {
unsigned32 segment_size; /* size of segment requested */
rtems_event_set event_condition;
unsigned32 *message_size_p; /* ptr for return size of message */
} Extra;
void *return_argument; /* address of user return param */
rtems_status_code return_code; /* status for thread awakened */

View File

@@ -78,6 +78,7 @@ typedef void * proc_ptr;
#include <rtems/cpu.h> /* processor specific information */
#include <rtems/status.h> /* RTEMS status codes */
#include <rtems/directives.h>
/*
* Define NULL
@@ -103,6 +104,9 @@ typedef void * proc_ptr;
#define stringify( _x ) # _x
#define RTEMS_offsetof(type, field) \
((unsigned32) &(((type *) 0)->field))
/*
* The following is the extern for the RTEMS version string.
* The contents of this string are CPU specific.
@@ -115,8 +119,7 @@ extern const char _Copyright_Notice[]; /* RTEMS copyright string */
* The jump table of entry points into RTEMS directives.
*/
#define NUMBER_OF_ENTRY_POINTS 79
extern const void * _Entry_points[ NUMBER_OF_ENTRY_POINTS + 1 ];
extern const void * _Entry_points[ RTEMS_NUMBER_OF_ENTRY_POINTS ];
/*
* The following defines the CPU dependent information table.

View File

@@ -12,6 +12,7 @@
*
* $Id$
*/
#include <rtems/system.h>
#include <rtems/chain.h>
#include <rtems/config.h>
@@ -226,3 +227,69 @@ Objects_Control *_Objects_Get(
_Objects_MP_Is_remote( information, id, location, &the_object );
return the_object;
}
/*PAGE
*
* _Objects_Get_next
*
* Like _Objects_Get, but considers the 'id' as a "hint" and
* finds next valid one after that point.
* Mostly used for monitor and debug traversal of an object.
*
* Input parameters:
* information - pointer to entry in table for this class
* id - object id to search for
* location - address of where to store the location
* next_id - address to store next id to try
*
* Output parameters:
* returns - address of object if local
* location - one of the following:
* OBJECTS_ERROR - invalid object ID
* OBJECTS_REMOTE - remote object
* OBJECTS_LOCAL - local object
* next_id - will contain a reasonable "next" id to continue traversal
*
* NOTE:
* assumes can add '1' to an id to get to next index.
*/
Objects_Control *
_Objects_Get_next(
Objects_Information *information,
Objects_Id id,
unsigned32 *location_p,
Objects_Id *next_id_p
)
{
Objects_Control *object;
Objects_Id next_id;
if (rtems_get_index(id) == RTEMS_OBJECT_ID_INITIAL_INDEX)
next_id = information->minimum_id;
else
next_id = id;
do {
/* walked off end of list? */
if (next_id > information->maximum_id)
{
*location_p = OBJECTS_ERROR;
goto final;
}
/* try to grab one */
object = _Objects_Get(information, next_id, location_p);
next_id++;
} while (*location_p != OBJECTS_LOCAL);
*next_id_p = next_id;
return object;
final:
*next_id_p = RTEMS_OBJECT_ID_FINAL;
return 0;
}

View File

@@ -23,31 +23,24 @@ extern "C" {
/* variables */
extern volatile rtems_unsigned32 Clock_driver_ticks;
extern rtems_device_major_number rtems_clock_major;
extern rtems_device_minor_number rtems_clock_minor;
/* functions */
rtems_task Exit_task();
void exit_task_init();
void Install_clock( rtems_isr_entry );
void ReInstall_clock( rtems_isr_entry );
void Clock_exit();
rtems_isr Clock_isr(
rtems_vector_number
);
/* driver entries */
/* default clock driver entry */
#define CLOCK_DRIVER_TABLE_ENTRY \
{ Clock_initialize, NULL, NULL, NULL, NULL, NULL }
{ Clock_initialize, NULL, NULL, NULL, NULL, Clock_control }
rtems_device_driver Clock_initialize(
rtems_device_major_number,
rtems_device_minor_number,
void *,
rtems_id,
rtems_unsigned32 *
void *
);
rtems_device_driver Clock_control(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *pargp
);
#ifdef __cplusplus

View File

@@ -0,0 +1,44 @@
/*
* @(#)assoc.h 1.2 - 95/06/28
*
*
* Rtems associativity routines. Mainly used to convert a value from
* one space to another (eg: our errno's to host errno's and v.v)
*
*
* $Id$
*/
#ifndef _INCLUDE_ASSOC_H
#define _INCLUDE_ASSOC_H
typedef struct {
char *name;
unsigned32 local_value;
unsigned32 remote_value;
} rtems_assoc_t;
/*
* Flag/marker for optional default value in each table
*/
#define RTEMS_ASSOC_DEFAULT_NAME "(default)"
rtems_assoc_t *rtems_assoc_ptr_by_name(rtems_assoc_t *, char *);
rtems_assoc_t *rtems_assoc_ptr_by_value(rtems_assoc_t *, unsigned32);
rtems_assoc_t *rtems_assoc_ptr_by_remote(rtems_assoc_t *, unsigned32);
unsigned32 rtems_assoc_remote_by_local(rtems_assoc_t *, unsigned32);
unsigned32 rtems_assoc_local_by_remote(rtems_assoc_t *, unsigned32);
unsigned32 rtems_assoc_remote_by_name(rtems_assoc_t *, char *);
unsigned32 rtems_assoc_local_by_name(rtems_assoc_t *, char *);
char *rtems_assoc_name_by_local(rtems_assoc_t *, unsigned32);
char *rtems_assoc_name_by_remote(rtems_assoc_t *, unsigned32);
unsigned32 rtems_assoc_remote_by_local_bitfield(rtems_assoc_t *, unsigned32);
char *rtems_assoc_name_by_local_bitfield(rtems_assoc_t *, unsigned32, char *);
char *rtems_assoc_name_by_remote_bitfield(rtems_assoc_t *, unsigned32, char *);
unsigned32 rtems_assoc_local_by_remote_bitfield(rtems_assoc_t *ap, unsigned32);
#endif /* ! _INCLUDE_ASSOC_H */

View File

@@ -0,0 +1,26 @@
/*
* @(#)error.h 1.1 - 95/08/02
*
*
* Defines and externs for rtems error reporting
*
* $Id$
*/
/*
* rtems_error() and rtems_panic() support
*/
#define RTEMS_ERROR_ERRNO (1<<((sizeof(int) * 8) - 2)) /* hi bit; use 'errno' */
#define RTEMS_ERROR_PANIC (RTEMS_ERROR_ERRNO / 2) /* err fatal; no return */
#define RTEMS_ERROR_ABORT (RTEMS_ERROR_ERRNO / 4) /* err is fatal; panic */
#define RTEMS_ERROR_MASK (RTEMS_ERROR_ERRNO | RTEMS_ERROR_ABORT | \
RTEMS_ERROR_PANIC) /* all */
char *rtems_status_text(rtems_status_code);
int rtems_error(int error_code, char *printf_format, ...);
void rtems_panic(char *printf_format, ...);
extern int rtems_panic_in_progress;

View File

@@ -0,0 +1,101 @@
/*
* @(#)libio.h 1.1 - 95/06/02
*
*
* General purpose communication channel for RTEMS to allow UNIX/POSIX
* system call behavior on top of RTEMS IO devices.
*
* TODO
* stat(2)
* unlink(2)
* rename(2)
*
* $Id$
*/
#ifndef _RTEMS_LIBIO_H
#define _RTEMS_LIBIO_H
typedef unsigned32 rtems_libio_offset_t;
/*
* An open file data structure, indexed by 'fd'
* TODO:
* should really have a separate per/file data structure that this
* points to (eg: size, offset, driver, pathname should be in that)
*/
typedef struct {
rtems_driver_name_t *driver;
rtems_libio_offset_t size; /* size of file */
rtems_libio_offset_t offset; /* current offset into the file */
unsigned32 flags;
char *pathname; /* opened pathname */
Objects_Id sem;
unsigned32 data0; /* private to "driver" */
unsigned32 data1; /* ... */
} rtems_libio_t;
/*
* param block for read/write
* Note: it must include 'offset' instead of using iop's offset since
* we can have multiple outstanding i/o's on a device.
*/
typedef struct {
rtems_libio_t *iop;
rtems_libio_offset_t offset;
unsigned8 *buffer;
unsigned32 count;
unsigned32 flags;
unsigned32 bytes_moved;
} rtems_libio_rw_args_t;
/*
* param block for open/close
*/
typedef struct {
rtems_libio_t *iop;
unsigned32 flags;
unsigned32 mode;
} rtems_libio_open_close_args_t;
/*
* param block for ioctl
*/
typedef struct {
rtems_libio_t *iop;
unsigned32 command;
void *buffer;
unsigned32 ioctl_return;
} rtems_libio_ioctl_args_t;
/*
* Values for 'flag'
*/
#define LIBIO_FLAGS_NO_DELAY 0x0001 /* return immediately if no data */
#define LIBIO_FLAGS_READ 0x0002 /* reading */
#define LIBIO_FLAGS_WRITE 0x0004 /* writing */
#define LIBIO_FLAGS_LINE_BUFFERED 0x0008 /* line buffered io (^h, ^u, etc) */
#define LIBIO_FLAGS_OPEN 0x0100 /* device is open */
#define LIBIO_FLAGS_APPEND 0x0200 /* all writes append */
#define LIBIO_FLAGS_CREATE 0x0400 /* create file */
#define LIBIO_FLAGS_READ_WRITE (LIBIO_FLAGS_READ | LIBIO_FLAGS_WRITE)
void rtems_libio_config(rtems_configuration_table *config, unsigned32 max_fds);
void rtems_libio_init(void);
int __open(const char *pathname, unsigned32 flag, unsigned32 mode);
int __close(int fd);
int __read(int fd, void *buffer, unsigned32 count);
int __write(int fd, const void *buffer, unsigned32 count);
int __ioctl(int fd, unsigned32 command, void *buffer);
int __lseek(int fd, rtems_libio_offset_t offset, int whence);
#endif /* _RTEMS_LIBIO_H */

View File

@@ -21,7 +21,9 @@ extern "C" {
#endif
#include <rtems.h>
#include <iosupp.h>
#include <clockdrv.h>
#include <rtems/ttydrv.h>
#include <libcsupport.h>
/*
* Define the time limits for RTEMS Test Suite test durations.
@@ -64,6 +66,18 @@ extern void Clock_delay(rtems_unsigned32 microseconds);
#define delay( microseconds ) \
Clock_delay(microseconds);
/*
* Todo: this should be put somewhere else
*/
#undef CLOCK_DRIVER_TABLE_ENTRY
#define CLOCK_DRIVER_TABLE_ENTRY { Clock_initialize, NULL, NULL, NULL, NULL, Clock_control }
rtems_device_driver Clock_control(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *pargp
);
/*
* We printf() to a buffer if multiprocessing, *or* if this is set.
* ref: src/lib/libbsp/hppa/simhppa/iosupp/consupp.c
@@ -71,8 +85,23 @@ extern void Clock_delay(rtems_unsigned32 microseconds);
extern int use_print_buffer;
/*
* When not doing printf to a buffer, we do printf thru RTEMS libio
* and our tty driver. Set it up so that console is right.
*/
#define CONSOLE_DRIVER_TABLE_ENTRY \
{ tty_initialize, tty_open, tty_close, tty_read, tty_write, tty_control }
/*
* How many libio files we want
*/
#define BSP_LIBIO_MAX_FDS 20
#define HPPA_INTERRUPT_EXTERNAL_MPCI HPPA_INTERRUPT_EXTERNAL_10
rtems_isr_entry set_vector(rtems_isr_entry, rtems_vector_number, int);
void bsp_start( void );
void bsp_cleanup( void );

View File

@@ -1,6 +1,5 @@
/*
* @(#)bspstart.c 1.14 - 95/05/16
*
* @(#)bspstart.c 1.16 - 95/06/28
*/
/* bsp_start()
@@ -24,13 +23,17 @@
* to the copyright license under the clause at DFARS 252.227-7013. This
* notice must appear in all copies of this file and its derivatives.
*
* bspstart.c,v 1.2 1995/05/09 20:17:33 joel Exp
* $Id$
*/
#include <rtems.h>
#include <bsp.h>
#include <rtems/libio.h>
#include <libcsupport.h>
#include <string.h>
#include <fcntl.h>
#ifdef STACK_CHECKER_ON
#include <stackchk.h>
@@ -127,8 +130,17 @@ bsp_libc_init(void)
RTEMS_Malloc_Initialize((void *) heap_start, 64 * 1024, 0);
/*
* Init the RTEMS libio facility to provide UNIX-like system
* calls for use by newlib (ie: provide __open, __close, etc)
* Uses malloc() to get area for the iops, so must be after malloc init
*/
rtems_libio_init();
/*
* Set up for the libc handling.
* XXX; this should allow for case of some other non-clock interrupts
*/
if (BSP_Configuration.ticks_per_timeslice > 0)
@@ -219,6 +231,32 @@ bsp_pretasking_hook(void)
#endif
}
/*
* After drivers are setup, register some "filenames"
* and open stdin, stdout, stderr files
*
* Newlib will automatically associate the files with these
* (it hardcodes the numbers)
*/
void
bsp_postdriver_hook(void)
{
int stdin_fd, stdout_fd, stderr_fd;
if ((stdin_fd = __open("/dev/tty00", O_RDONLY, 0)) == -1)
rtems_fatal_error_occurred('STD0');
if ((stdout_fd = __open("/dev/tty00", O_WRONLY, 0)) == -1)
rtems_fatal_error_occurred('STD1');
if ((stderr_fd = __open("/dev/tty00", O_WRONLY, 0)) == -1)
rtems_fatal_error_occurred('STD2');
if ((stdin_fd != 0) || (stdout_fd != 1) || (stderr_fd != 2))
rtems_fatal_error_occurred('STIO');
}
/*
* Function: bsp_start
* Created: 94/12/6
@@ -289,7 +327,7 @@ bsp_start(void)
Cpu_table.predriver_hook = NULL;
Cpu_table.postdriver_hook = NULL;
Cpu_table.postdriver_hook = bsp_postdriver_hook; /* register drivers */
Cpu_table.idle_task = NULL; /* do not override system IDLE task */
@@ -342,21 +380,27 @@ bsp_start(void)
#endif
#ifdef STACK_CHECKER_ON
/*
* Add 1 extension for stack checker
*/
/*
* Add 1 extension for stack checker
*/
BSP_Configuration.maximum_extensions++;
#endif
#if SIMHPPA_FAST_IDLE
/*
* Add 1 extension for fast idle
*/
/*
* Add 1 extension for fast idle
*/
BSP_Configuration.maximum_extensions++;
#endif
/*
* Tell libio how many fd's we want and allow it to tweak config
*/
rtems_libio_config(&BSP_Configuration, BSP_LIBIO_MAX_FDS);
/*
* Add 1 extension for MPCI_fatal
*/

View File

@@ -16,20 +16,24 @@
* to the copyright license under the clause at DFARS 252.227-7013. This
* notice must appear in all copies of this file and its derivatives.
*
* poll.c,v 1.2 1995/05/09 20:22:57 joel Exp
* $Id$
*/
#include <rtems.h>
#include <rtems/sysstate.h>
#include <rtems/libio.h>
#include "shm.h"
#include "clockdrv.h"
void Shm_Poll()
{
rtems_unsigned32 tmpfront;
rtems_libio_ioctl_args_t args;
Clock_isr( 0 ); /* invoke standard clock ISR */
/* invoke clock isr */
args.iop = 0;
args.command = rtems_build_name('I', 'S', 'R', ' ');
(void) rtems_io_control(rtems_clock_major, rtems_clock_minor, &args);
/*
* Check for msgs only if we are "up"
@@ -39,14 +43,11 @@ void Shm_Poll()
if (_System_state_Is_up(_System_state_Get()))
{
/* enable_tracing(); */
/* ticks += 1; */
Shm_Lock( Shm_Local_receive_queue );
tmpfront = Shm_Local_receive_queue->front;
Shm_Unlock( Shm_Local_receive_queue );
if ( Shm_Convert(tmpfront) != Shm_Locked_queue_End_of_list ) {
rtems_multiprocessing_announce();
Shm_Interrupt_count++;
if ( Shm_Convert(tmpfront) != Shm_Locked_queue_End_of_list )
{
rtems_multiprocessing_announce();
Shm_Interrupt_count++;
}
}
}

View File

@@ -19,10 +19,16 @@
*/
#include <rtems.h>
#include <rtems/libio.h>
#include "shm.h"
#include "clockdrv.h"
rtems_isr Shm_setclockvec()
{
ReInstall_clock( Shm_Poll );
rtems_libio_ioctl_args_t args;
args.iop = 0;
args.command = rtems_build_name('N', 'E', 'W', ' ');
args.buffer = (void *) Shm_Poll;
(void) rtems_io_control(rtems_clock_major, rtems_clock_minor, &args);
}

View File

@@ -20,6 +20,8 @@
#ifndef __SHM_h
#define __SHM_h
#include <clockdrv.h>
#ifdef __cplusplus
extern "C" {
#endif
@@ -518,6 +520,7 @@ extern rtems_mpci_table MPCI_table;
rtems_mpci_table MPCI_table = {
100000, /* default timeout value in ticks */
MAX_PACKET_SIZE, /* maximum packet size */
Shm_Initialization, /* initialization procedure */
Shm_Get_packet, /* get packet procedure */
Shm_Return_packet, /* return packet procedure */

View File

@@ -20,6 +20,8 @@
#ifndef __SHM_h
#define __SHM_h
#include <clockdrv.h>
#ifdef __cplusplus
extern "C" {
#endif
@@ -518,6 +520,7 @@ extern rtems_mpci_table MPCI_table;
rtems_mpci_table MPCI_table = {
100000, /* default timeout value in ticks */
MAX_PACKET_SIZE, /* maximum packet size */
Shm_Initialization, /* initialization procedure */
Shm_Get_packet, /* get packet procedure */
Shm_Return_packet, /* return packet procedure */

View File

@@ -1,7 +1,7 @@
/* Clock
*
* This routine initializes the interval timer on the
* PA-RISC CPU. The tick frequency is specified by the bsp.
* This routine generates clock ticks using standard POSIX services.
* The tick frequency is specified by the bsp.
*
* COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
* On-Line Applications Research Corporation (OAR).
@@ -15,62 +15,44 @@
*/
#include <rtems.h>
#include <rtems/libio.h>
#include <bsp.h>
/*
* In order to get the types and prototypes used in this file under
* Solaris 2.3, it is necessary to pull the following magic.
*/
#if defined(solaris)
#warning "Ignore the undefining __STDC__ warning"
#undef __STDC__
#define __STDC__ 0
#undef _POSIX_C_SOURCE
#endif
#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#include <time.h>
#include <sys/time.h>
extern rtems_configuration_table Configuration;
extern sigset_t UNIX_SIGNAL_MASK;
/*
* Function prototypes
*/
void Install_clock();
void Clock_isr();
void Clock_exit();
/*
* CPU_HPPA_CLICKS_PER_TICK is either a #define or an rtems_unsigned32
* allocated and set by bsp_start()
*/
#ifndef CPU_HPPA_CLICKS_PER_TICK
extern rtems_unsigned32 CPU_HPPA_CLICKS_PER_TICK;
#endif
void Clock_exit(void);
volatile rtems_unsigned32 Clock_driver_ticks;
struct itimerval new;
/*
* These are set by clock driver during its init
*/
rtems_device_driver
Clock_initialize(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *pargp,
rtems_id tid,
rtems_unsigned32 *rval
)
{
Install_clock(Clock_isr);
}
void
ReInstall_clock(rtems_isr_entry new_clock_isr)
{
rtems_unsigned32 isrlevel = 0;
rtems_interrupt_disable(isrlevel);
(void)set_vector(new_clock_isr, SIGALRM, 1);
rtems_interrupt_enable(isrlevel);
}
rtems_device_major_number rtems_clock_major = ~0;
rtems_device_minor_number rtems_clock_minor;
void
Install_clock(rtems_isr_entry clock_isr)
{
struct itimerval new;
Clock_driver_ticks = 0;
new.it_value.tv_sec = 0;
@@ -85,11 +67,20 @@ Install_clock(rtems_isr_entry clock_isr)
atexit(Clock_exit);
}
void
ReInstall_clock(rtems_isr_entry new_clock_isr)
{
rtems_unsigned32 isrlevel = 0;
rtems_interrupt_disable(isrlevel);
(void)set_vector(new_clock_isr, SIGALRM, 1);
rtems_interrupt_enable(isrlevel);
}
void
Clock_isr(int vector)
{
Clock_driver_ticks++;
rtems_clock_tick();
}
@@ -101,6 +92,7 @@ Clock_isr(int vector)
void
Clock_exit(void)
{
struct itimerval new;
struct sigaction act;
/*
@@ -121,3 +113,50 @@ Clock_exit(void)
(void)set_vector(0, SIGALRM, 1);
}
rtems_device_driver
Clock_initialize(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *pargp
)
{
Install_clock((rtems_isr_entry) Clock_isr);
/*
* make major/minor avail to others such as shared memory driver
*/
rtems_clock_major = major;
rtems_clock_minor = minor;
return RTEMS_SUCCESSFUL;
}
rtems_device_driver Clock_control(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *pargp
)
{
rtems_libio_ioctl_args_t *args = pargp;
if (args == 0)
goto done;
/*
* This is hokey, but until we get a defined interface
* to do this, it will just be this simple...
*/
if (args->command == rtems_build_name('I', 'S', 'R', ' '))
{
Clock_isr(SIGALRM);
}
else if (args->command == rtems_build_name('N', 'E', 'W', ' '))
{
ReInstall_clock(args->buffer);
}
done:
return RTEMS_SUCCESSFUL;
}

View File

@@ -28,10 +28,9 @@
rtems_device_driver
console_initialize(rtems_device_major_number major,
rtems_device_minor_number minor,
void * arg,
rtems_id self,
rtems_unsigned32 * status)
void * arg
)
{
*status = RTEMS_SUCCESSFUL;
return RTEMS_SUCCESSFUL;
}

View File

@@ -78,6 +78,20 @@ extern rtems_configuration_table BSP_Configuration;
*/
/* #define INTERRUPT_EXTERNAL_MPCI SIGUSR1 */
/*
* Console driver init
*/
rtems_device_driver console_initialize(
rtems_device_major_number, rtems_device_minor_number minor, void *);
#define CONSOLE_DRIVER_TABLE_ENTRY \
{ console_initialize, NULL, NULL, NULL, NULL, NULL }
/*
* NOTE: Use the standard Clock driver entry
*/
/* functions */

258
c/src/lib/libc/assoc.c Normal file
View File

@@ -0,0 +1,258 @@
/*
* @(#)assoc.c 1.4 - 95/08/02
*
*
* assoc.c
* rtems assoc routines
*
* $Id$
*/
#include <rtems.h>
#include "assoc.h"
#include <stdio.h> /* sprintf */
#include <string.h> /* strcat, strcmp */
#define STREQ(a,b) (strcmp((a), (b)) == 0)
#define rtems_assoc_is_default(ap) ((ap)->name && STREQ(ap->name, RTEMS_ASSOC_DEFAULT_NAME))
rtems_assoc_t *
rtems_assoc_ptr_by_name(
rtems_assoc_t *ap,
char *name
)
{
rtems_assoc_t *default_ap = 0;
if (rtems_assoc_is_default(ap))
default_ap = ap++;
for ( ; ap->name; ap++)
if (strcmp(ap->name, name) == 0)
return ap;
return default_ap;
}
rtems_assoc_t *
rtems_assoc_ptr_by_local(
rtems_assoc_t *ap,
unsigned32 local_value
)
{
rtems_assoc_t *default_ap = 0;
if (rtems_assoc_is_default(ap))
default_ap = ap++;
for ( ; ap->name; ap++)
if (ap->local_value == local_value)
return ap;
return default_ap;
}
rtems_assoc_t *
rtems_assoc_ptr_by_remote(
rtems_assoc_t *ap,
unsigned32 remote_value
)
{
rtems_assoc_t *default_ap = 0;
if (rtems_assoc_is_default(ap))
default_ap = ap++;
for ( ; ap->name; ap++)
if (ap->remote_value == remote_value)
return ap;
return default_ap;
}
/*
* Get values
*/
unsigned32
rtems_assoc_remote_by_local(
rtems_assoc_t *ap,
unsigned32 local_value
)
{
rtems_assoc_t *nap;
nap = rtems_assoc_ptr_by_local(ap, local_value);
if (nap)
return nap->remote_value;
return 0;
}
unsigned32
rtems_assoc_local_by_remote(
rtems_assoc_t *ap,
unsigned32 remote_value
)
{
rtems_assoc_t *nap;
nap = rtems_assoc_ptr_by_remote(ap, remote_value);
if (nap)
return nap->local_value;
return 0;
}
unsigned32
rtems_assoc_remote_by_name(
rtems_assoc_t *ap,
char *name
)
{
rtems_assoc_t *nap;
nap = rtems_assoc_ptr_by_name(ap, name);
if (nap)
return nap->remote_value;
return 0;
}
unsigned32
rtems_assoc_local_by_name(
rtems_assoc_t *ap,
char *name
)
{
rtems_assoc_t *nap;
nap = rtems_assoc_ptr_by_name(ap, name);
if (nap)
return nap->local_value;
return 0;
}
/*
* what to return if a value is not found
* this is not reentrant, but it really shouldn't be invoked anyway
*/
char *
rtems_assoc_name_bad(
unsigned32 bad_value
)
{
static char bad_buffer[32];
sprintf(bad_buffer, "< %d [0x%x] >", bad_value, bad_value);
return bad_buffer;
}
char *
rtems_assoc_name_by_local(
rtems_assoc_t *ap,
unsigned32 local_value
)
{
rtems_assoc_t *nap;
nap = rtems_assoc_ptr_by_local(ap, local_value);
if (nap)
return nap->name;
return rtems_assoc_name_bad(local_value);
}
char *
rtems_assoc_name_by_remote(
rtems_assoc_t *ap,
unsigned32 remote_value
)
{
rtems_assoc_t *nap;
nap = rtems_assoc_ptr_by_remote(ap, remote_value);
if (nap)
return nap->name;
return rtems_assoc_name_bad(remote_value);
}
/*
* Bitfield functions assume just 1 bit set in each of remote and local
* entries; they do not check for this.
*/
unsigned32 rtems_assoc_remote_by_local_bitfield(
rtems_assoc_t *ap,
unsigned32 local_value
)
{
unsigned32 b;
unsigned32 remote_value = 0;
for (b = 1; b; b <<= 1)
if (b & local_value)
remote_value |= rtems_assoc_remote_by_local(ap, b);
return remote_value;
}
unsigned32 rtems_assoc_local_by_remote_bitfield(
rtems_assoc_t *ap,
unsigned32 remote_value
)
{
unsigned32 b;
unsigned32 local_value = 0;
for (b = 1; b; b <<= 1)
if (b & remote_value)
local_value |= rtems_assoc_local_by_remote(ap, b);
return local_value;
}
char *rtems_assoc_name_by_remote_bitfield(
rtems_assoc_t *ap,
unsigned32 value,
char *buffer
)
{
unsigned32 b;
*buffer = 0;
for (b = 1; b; b <<= 1)
if (b & value)
{
if (*buffer)
strcat(buffer, " ");
strcat(buffer, rtems_assoc_name_by_remote(ap, b));
}
return buffer;
}
char *rtems_assoc_name_by_local_bitfield(
rtems_assoc_t *ap,
unsigned32 value,
char *buffer
)
{
unsigned32 b;
*buffer = 0;
for (b = 1; b; b <<= 1)
if (b & value)
{
if (*buffer)
strcat(buffer, " ");
strcat(buffer, rtems_assoc_name_by_local(ap, b));
}
return buffer;
}

44
c/src/lib/libc/assoc.h Normal file
View File

@@ -0,0 +1,44 @@
/*
* @(#)assoc.h 1.2 - 95/06/28
*
*
* Rtems associativity routines. Mainly used to convert a value from
* one space to another (eg: our errno's to host errno's and v.v)
*
*
* $Id$
*/
#ifndef _INCLUDE_ASSOC_H
#define _INCLUDE_ASSOC_H
typedef struct {
char *name;
unsigned32 local_value;
unsigned32 remote_value;
} rtems_assoc_t;
/*
* Flag/marker for optional default value in each table
*/
#define RTEMS_ASSOC_DEFAULT_NAME "(default)"
rtems_assoc_t *rtems_assoc_ptr_by_name(rtems_assoc_t *, char *);
rtems_assoc_t *rtems_assoc_ptr_by_value(rtems_assoc_t *, unsigned32);
rtems_assoc_t *rtems_assoc_ptr_by_remote(rtems_assoc_t *, unsigned32);
unsigned32 rtems_assoc_remote_by_local(rtems_assoc_t *, unsigned32);
unsigned32 rtems_assoc_local_by_remote(rtems_assoc_t *, unsigned32);
unsigned32 rtems_assoc_remote_by_name(rtems_assoc_t *, char *);
unsigned32 rtems_assoc_local_by_name(rtems_assoc_t *, char *);
char *rtems_assoc_name_by_local(rtems_assoc_t *, unsigned32);
char *rtems_assoc_name_by_remote(rtems_assoc_t *, unsigned32);
unsigned32 rtems_assoc_remote_by_local_bitfield(rtems_assoc_t *, unsigned32);
char *rtems_assoc_name_by_local_bitfield(rtems_assoc_t *, unsigned32, char *);
char *rtems_assoc_name_by_remote_bitfield(rtems_assoc_t *, unsigned32, char *);
unsigned32 rtems_assoc_local_by_remote_bitfield(rtems_assoc_t *ap, unsigned32);
#endif /* ! _INCLUDE_ASSOC_H */

212
c/src/lib/libc/error.c Normal file
View File

@@ -0,0 +1,212 @@
/*
* @(#)error.c 1.2 - 95/08/02
*
*
* report errors and panics to RTEMS' stderr.
* Currently just used by RTEMS monitor.
*
*
* $Id$
*/
/*
* These routines provide general purpose error reporting.
* rtems_error reports an error to stderr and allows use of
* printf style formatting. A newline is appended to all messages.
*
* error_flag can be specified as any of the following:
*
* RTEMS_ERROR_ERRNO -- include errno text in output
* RTEMS_ERROR_PANIC -- halts local system after output
* RTEMS_ERROR_ABORT -- abort after output
*
* It can also include a rtems_status value which can be OR'd
* with the above flags. *
*
* EXAMPLE
* #include <rtems.h>
* #include <rtems/error.h>
* rtems_error(0, "stray interrupt %d", intr);
*
* EXAMPLE
* if ((status = rtems_task_create(...)) != RTEMS_SUCCCESSFUL)
* {
* rtems_error(status | RTEMS_ERROR_ABORT,
* "could not create task");
* }
*
* EXAMPLE
* if ((fd = open(pathname, O_RDNLY)) < 0)
* {
* rtems_error(FLOSS_ERROR_ERRNO, "open of '%s' failed", pathname);
* goto failed;
* }
*/
#include <rtems.h>
#include "error.h"
#include "assoc.h"
#include <stdio.h>
#include <stdarg.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h> /* _exit() */
/* bug in hpux <errno.h>: no prototypes unless you are C++ */
#ifdef hpux9
char *strerror(int);
#endif
extern char *rtems_progname;
int rtems_panic_in_progress;
rtems_assoc_t rtems_status_assoc[] = {
{ "successful completion", RTEMS_SUCCESSFUL, },
{ "returned from a thread", RTEMS_TASK_EXITTED, },
{ "multiprocessing not configured", RTEMS_MP_NOT_CONFIGURED, },
{ "invalid object name", RTEMS_INVALID_NAME, },
{ "invalid object id", RTEMS_INVALID_ID, },
{ "too many", RTEMS_TOO_MANY, },
{ "timed out waiting", RTEMS_TIMEOUT, },
{ "object deleted while waiting", RTEMS_OBJECT_WAS_DELETED, },
{ "specified size was invalid", RTEMS_INVALID_SIZE, },
{ "address specified is invalid", RTEMS_INVALID_ADDRESS, },
{ "number was invalid", RTEMS_INVALID_NUMBER, },
{ "item has not been initialized", RTEMS_NOT_DEFINED, },
{ "resources still outstanding", RTEMS_RESOURCE_IN_USE, },
{ "request not satisfied", RTEMS_UNSATISFIED, },
{ "thread is in wrong state", RTEMS_INCORRECT_STATE, },
{ "thread already in state", RTEMS_ALREADY_SUSPENDED, },
{ "illegal on calling thread", RTEMS_ILLEGAL_ON_SELF, },
{ "illegal for remote object", RTEMS_ILLEGAL_ON_REMOTE_OBJECT, },
{ "called from wrong environment", RTEMS_CALLED_FROM_ISR, },
{ "invalid thread priority", RTEMS_INVALID_PRIORITY, },
{ "invalid date/time", RTEMS_INVALID_CLOCK, },
{ "invalid node id", RTEMS_INVALID_NODE, },
{ "directive not configured", RTEMS_NOT_CONFIGURED, },
{ "not owner of resource", RTEMS_NOT_OWNER_OF_RESOURCE , },
{ "directive not implemented", RTEMS_NOT_IMPLEMENTED, },
{ "RTEMS inconsistency detected", RTEMS_INTERNAL_ERROR, },
{ "internal multiprocessing only", RTEMS_PROXY_BLOCKING, },
{ "could not get enough memory", RTEMS_NO_MEMORY, },
{ 0, 0, 0 },
};
char *
rtems_status_text(
rtems_status_code status
)
{
return rtems_assoc_name_by_local(rtems_status_assoc, status);
}
static int rtems_verror(
unsigned32 error_flag,
char *printf_format,
va_list arglist
)
{
int local_errno = 0;
int chars_written = 0;
rtems_status_code status;
if (error_flag & RTEMS_ERROR_PANIC)
{
rtems_panic_in_progress++;
/* disable task switches */
_Thread_Disable_dispatch();
/* don't aggravate things */
if (rtems_panic_in_progress > 2)
return 0;
}
(void) fflush(stdout); /* in case stdout/stderr same */
status = error_flag & ~RTEMS_ERROR_MASK;
if (error_flag & RTEMS_ERROR_ERRNO) /* include errno? */
local_errno = errno;
if (_Configuration_Is_multiprocessing())
fprintf(stderr, "[%d] ", _Configuration_MP_table->node);
if (rtems_progname && *rtems_progname)
chars_written += fprintf(stderr, "%s: ", rtems_progname);
chars_written += vfprintf(stderr, printf_format, arglist);
if (status)
chars_written += fprintf(stderr, " (status: %s)", rtems_status_text(status));
if (local_errno)
if ((local_errno > 0) && *strerror(local_errno))
chars_written += fprintf(stderr, " (errno: %s)", strerror(local_errno));
else
chars_written += fprintf(stderr, " (unknown errno=%d)", local_errno);
chars_written += fprintf(stderr, "\n");
(void) fflush(stderr);
if (error_flag & (RTEMS_ERROR_PANIC | RTEMS_ERROR_ABORT))
{
if (error_flag & RTEMS_ERROR_PANIC)
{
rtems_error(0, "fatal error, exiting");
_exit(local_errno);
}
else
{
rtems_error(0, "fatal error, aborting");
abort();
}
}
return chars_written;
}
/*
* Report an error.
* error_flag is as above; printf_format is a normal
* printf(3) format string, with its concommitant arguments.
*
* Returns the number of characters written.
*/
int rtems_error(
int error_flag,
char *printf_format,
...
)
{
va_list arglist;
int chars_written;
va_start(arglist, printf_format);
chars_written = rtems_verror(error_flag, printf_format, arglist);
va_end(arglist);
return chars_written;
}
/*
* rtems_panic is shorthand for rtems_error(RTEMS_ERROR_PANIC, ...)
*/
void rtems_panic(
char *printf_format,
...
)
{
va_list arglist;
va_start(arglist, printf_format);
(void) rtems_verror(RTEMS_ERROR_PANIC, printf_format, arglist);
va_end(arglist);
}

26
c/src/lib/libc/error.h Normal file
View File

@@ -0,0 +1,26 @@
/*
* @(#)error.h 1.1 - 95/08/02
*
*
* Defines and externs for rtems error reporting
*
* $Id$
*/
/*
* rtems_error() and rtems_panic() support
*/
#define RTEMS_ERROR_ERRNO (1<<((sizeof(int) * 8) - 2)) /* hi bit; use 'errno' */
#define RTEMS_ERROR_PANIC (RTEMS_ERROR_ERRNO / 2) /* err fatal; no return */
#define RTEMS_ERROR_ABORT (RTEMS_ERROR_ERRNO / 4) /* err is fatal; panic */
#define RTEMS_ERROR_MASK (RTEMS_ERROR_ERRNO | RTEMS_ERROR_ABORT | \
RTEMS_ERROR_PANIC) /* all */
char *rtems_status_text(rtems_status_code);
int rtems_error(int error_code, char *printf_format, ...);
void rtems_panic(char *printf_format, ...);
extern int rtems_panic_in_progress;

433
c/src/lib/libc/libio.c Normal file
View File

@@ -0,0 +1,433 @@
/*
* @(#)libio.c 1.1 - 95/06/02
*
*
* Provide UNIX/POSIX-like io system calls for RTEMS using the
* RTEMS IO manager
*
* TODO
*
* $Id$
*/
#include <rtems.h>
#include <rtems/assoc.h> /* assoc.h not included by rtems.h */
#include <fcntl.h> /* O_RDONLY, et.al. */
#if defined(solaris2)
#define O_NDELAY O_NONBLOCK
#endif
#include <errno.h>
#include <string.h> /* strcmp */
#include <unistd.h>
#include <stdlib.h> /* calloc() */
#include "libio.h" /* libio.h not pulled in by rtems */
/*
* Semaphore to protect the io table
*/
Objects_Id rtems_libio_semaphore;
#define RTEMS_LIBIO_SEM rtems_build_name('L', 'B', 'I', 'O')
#define RTEMS_LIBIO_IOP_SEM(n) rtems_build_name('L', 'B', 'I', n)
unsigned32 rtems_libio_number_iops;
rtems_libio_t *rtems_libio_iops;
rtems_libio_t *rtems_libio_last_iop;
#define rtems_libio_iop(fd) ((((unsigned32)(fd)) < rtems_libio_number_iops) ? \
&rtems_libio_iops[fd] : 0)
#define rtems_libio_check_fd(fd) \
do { \
if ((fd) >= rtems_libio_number_iops) \
{ \
errno = EBADF; \
return -1; \
} \
} while (0)
#define rtems_libio_check_buffer(buffer) \
do { \
if ((buffer) == 0) \
{ \
errno = EINVAL; \
return -1; \
} \
} while (0)
#define rtems_libio_check_count(count) \
do { \
if ((count) == 0) \
{ \
return 0; \
} \
} while (0)
#define rtems_libio_check_permissions(iop, flag) \
do { \
if (((iop)->flags & (flag)) == 0) \
{ \
errno = EINVAL; \
return -1; \
} \
} while (0)
void
rtems_libio_config(
rtems_configuration_table *config,
unsigned32 max_fds
)
{
rtems_libio_number_iops = max_fds;
/*
* tweak config to reflect # of semaphores we will need
*/
config->maximum_semaphores += 1; /* one for iop table */
config->maximum_semaphores += max_fds;
}
/*
* Called by bsp startup code to init the libio area.
*/
void
rtems_libio_init(void)
{
rtems_status_code rc;
if (rtems_libio_number_iops > 0)
{
rtems_libio_iops = (rtems_libio_t *) calloc(rtems_libio_number_iops,
sizeof(rtems_libio_t));
if (rtems_libio_iops == NULL)
rtems_fatal_error_occurred(RTEMS_NO_MEMORY);
rtems_libio_last_iop = rtems_libio_iops + (rtems_libio_number_iops - 1);
}
rc = rtems_semaphore_create(RTEMS_LIBIO_SEM,
1,
RTEMS_BINARY_SEMAPHORE | RTEMS_INHERIT_PRIORITY | RTEMS_PRIORITY,
&rtems_libio_semaphore);
if (rc != RTEMS_SUCCESSFUL)
rtems_fatal_error_occurred(rc);
}
/*
* Convert RTEMS status to a UNIX errno
*/
rtems_assoc_t errno_assoc[] = {
{ "OK", RTEMS_SUCCESSFUL, 0 },
{ "TIMEOUT", RTEMS_TIMEOUT, ETIME },
{ "NO MEMORY", RTEMS_NO_MEMORY, ENOMEM },
{ 0, 0, 0 },
};
static unsigned32
rtems_libio_errno(rtems_status_code code)
{
int rc;
if ((rc = rtems_assoc_remote_by_local(errno_assoc, (unsigned32) code)))
{
errno = rc;
return -1;
}
return 0;
}
/*
* Convert UNIX fnctl(2) flags to ones that RTEMS drivers understand
*/
rtems_assoc_t access_modes_assoc[] = {
{ "READ", LIBIO_FLAGS_READ, O_RDONLY },
{ "WRITE", LIBIO_FLAGS_WRITE, O_WRONLY },
{ "READ/WRITE", LIBIO_FLAGS_READ_WRITE, O_RDWR },
{ 0, 0, 0 },
};
rtems_assoc_t status_flags_assoc[] = {
{ "NO DELAY", LIBIO_FLAGS_NO_DELAY, O_NDELAY },
{ "APPEND", LIBIO_FLAGS_APPEND, O_APPEND },
{ "CREATE", LIBIO_FLAGS_CREATE, O_CREAT },
{ 0, 0, 0 },
};
static unsigned32
rtems_libio_fcntl_flags(unsigned32 fcntl_flags)
{
unsigned32 flags = 0;
unsigned32 access_modes;
/*
* Access mode is a small integer
*/
access_modes = fcntl_flags & O_ACCMODE;
fcntl_flags &= ~O_ACCMODE;
flags = rtems_assoc_local_by_remote(access_modes_assoc, access_modes);
/*
* Everything else is single bits
*/
flags |= rtems_assoc_local_by_remote_bitfield(status_flags_assoc, fcntl_flags);
return flags;
}
static rtems_libio_t *
rtems_libio_allocate(void)
{
rtems_libio_t *iop;
rtems_status_code rc;
rtems_semaphore_obtain(rtems_libio_semaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
for (iop = rtems_libio_iops; iop <= rtems_libio_last_iop; iop++)
if ((iop->flags & LIBIO_FLAGS_OPEN) == 0)
{
/*
* Got one; create a semaphore for it
*/
rc = rtems_semaphore_create(RTEMS_LIBIO_IOP_SEM(iop - rtems_libio_iops),
1, RTEMS_BINARY_SEMAPHORE | RTEMS_INHERIT_PRIORITY | RTEMS_PRIORITY,
&iop->sem);
if (rc != RTEMS_SUCCESSFUL)
goto failed;
iop->flags = LIBIO_FLAGS_OPEN;
goto done;
}
failed:
iop = 0;
done:
rtems_semaphore_release(rtems_libio_semaphore);
return iop;
}
static void
rtems_libio_free(rtems_libio_t *iop)
{
rtems_semaphore_obtain(rtems_libio_semaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
if (iop->sem)
rtems_semaphore_delete(iop->sem);
(void) memset(iop, 0, sizeof(*iop));
rtems_semaphore_release(rtems_libio_semaphore);
}
int
__open(
const char *pathname,
unsigned32 flag,
unsigned32 mode)
{
rtems_status_code rc;
rtems_libio_t *iop = 0;
rtems_driver_name_t *np;
rtems_libio_open_close_args_t args;
if ((rc = rtems_io_lookup_name(pathname, &np)) != RTEMS_SUCCESSFUL)
goto done;
iop = rtems_libio_allocate();
if (iop == 0)
{
rc = RTEMS_TOO_MANY;
goto done;
}
iop->driver = np;
iop->pathname = (char *) pathname;
iop->flags |= rtems_libio_fcntl_flags(flag);
args.iop = iop;
args.flags = iop->flags;
args.mode = mode;
rc = rtems_io_open(np->major, np->minor, (void *) &args);
done:
if (rc != RTEMS_SUCCESSFUL)
{
if (iop)
rtems_libio_free(iop);
return rtems_libio_errno(rc);
}
return iop - rtems_libio_iops;
}
int
__close(
int fd
)
{
rtems_status_code rc;
rtems_driver_name_t *np;
rtems_libio_t *iop = rtems_libio_iop(fd);
rtems_libio_open_close_args_t args;
rtems_libio_check_fd(fd);
np = iop->driver;
args.iop = iop;
args.flags = 0;
args.mode = 0;
rc = rtems_io_close(np->major, np->minor, (void *) &args);
if (rc != RTEMS_SUCCESSFUL)
return rtems_libio_errno(rc);
return 0;
}
int
__read(
int fd,
void * buffer,
unsigned32 count
)
{
rtems_status_code rc;
rtems_driver_name_t *np;
rtems_libio_t *iop = rtems_libio_iop(fd);
rtems_libio_rw_args_t args;
rtems_libio_check_fd(fd);
rtems_libio_check_buffer(buffer);
rtems_libio_check_count(count);
rtems_libio_check_permissions(iop, LIBIO_FLAGS_READ);
np = iop->driver;
args.iop = iop;
args.offset = iop->offset;
args.buffer = buffer;
args.count = count;
args.flags = iop->flags;
args.bytes_moved = 0;
rc = rtems_io_read(np->major, np->minor, (void *) &args);
iop->offset += args.bytes_moved;
if (rc != RTEMS_SUCCESSFUL)
return rtems_libio_errno(rc);
return args.bytes_moved;
}
int
__write(
int fd,
const void *buffer,
unsigned32 count
)
{
rtems_status_code rc;
rtems_driver_name_t *np;
rtems_libio_t *iop = rtems_libio_iop(fd);
rtems_libio_rw_args_t args;
rtems_libio_check_fd(fd);
rtems_libio_check_buffer(buffer);
rtems_libio_check_count(count);
rtems_libio_check_permissions(iop, LIBIO_FLAGS_WRITE);
np = iop->driver;
args.iop = iop;
args.offset = iop->offset;
args.buffer = (void *) buffer;
args.count = count;
args.flags = iop->flags;
args.bytes_moved = 0;
rc = rtems_io_write(np->major, np->minor, (void *) &args);
iop->offset += args.bytes_moved;
if (rc != RTEMS_SUCCESSFUL)
return rtems_libio_errno(rc);
return args.bytes_moved;
}
int
__ioctl(
int fd,
unsigned32 command,
void * buffer)
{
rtems_status_code rc;
rtems_driver_name_t *np;
rtems_libio_t *iop = rtems_libio_iop(fd);
rtems_libio_ioctl_args_t args;
rtems_libio_check_fd(fd);
np = iop->driver;
args.iop = iop;
args.command = command;
args.buffer = buffer;
rc = rtems_io_control(np->major, np->minor, (void *) &args);
if (rc != RTEMS_SUCCESSFUL)
return rtems_libio_errno(rc);
return args.ioctl_return;
}
/*
* internal only??
*/
int
__lseek(
int fd,
rtems_libio_offset_t offset,
int whence
)
{
rtems_libio_t *iop = rtems_libio_iop(fd);
rtems_libio_check_fd(fd);
switch (whence)
{
case SEEK_SET:
iop->offset = offset;
break;
case SEEK_CUR:
iop->offset += offset;
break;
case SEEK_END:
iop->offset = iop->size - offset;
break;
default:
errno = EINVAL;
return -1;
}
return 0;
}

101
c/src/lib/libc/libio.h Normal file
View File

@@ -0,0 +1,101 @@
/*
* @(#)libio.h 1.1 - 95/06/02
*
*
* General purpose communication channel for RTEMS to allow UNIX/POSIX
* system call behavior on top of RTEMS IO devices.
*
* TODO
* stat(2)
* unlink(2)
* rename(2)
*
* $Id$
*/
#ifndef _RTEMS_LIBIO_H
#define _RTEMS_LIBIO_H
typedef unsigned32 rtems_libio_offset_t;
/*
* An open file data structure, indexed by 'fd'
* TODO:
* should really have a separate per/file data structure that this
* points to (eg: size, offset, driver, pathname should be in that)
*/
typedef struct {
rtems_driver_name_t *driver;
rtems_libio_offset_t size; /* size of file */
rtems_libio_offset_t offset; /* current offset into the file */
unsigned32 flags;
char *pathname; /* opened pathname */
Objects_Id sem;
unsigned32 data0; /* private to "driver" */
unsigned32 data1; /* ... */
} rtems_libio_t;
/*
* param block for read/write
* Note: it must include 'offset' instead of using iop's offset since
* we can have multiple outstanding i/o's on a device.
*/
typedef struct {
rtems_libio_t *iop;
rtems_libio_offset_t offset;
unsigned8 *buffer;
unsigned32 count;
unsigned32 flags;
unsigned32 bytes_moved;
} rtems_libio_rw_args_t;
/*
* param block for open/close
*/
typedef struct {
rtems_libio_t *iop;
unsigned32 flags;
unsigned32 mode;
} rtems_libio_open_close_args_t;
/*
* param block for ioctl
*/
typedef struct {
rtems_libio_t *iop;
unsigned32 command;
void *buffer;
unsigned32 ioctl_return;
} rtems_libio_ioctl_args_t;
/*
* Values for 'flag'
*/
#define LIBIO_FLAGS_NO_DELAY 0x0001 /* return immediately if no data */
#define LIBIO_FLAGS_READ 0x0002 /* reading */
#define LIBIO_FLAGS_WRITE 0x0004 /* writing */
#define LIBIO_FLAGS_LINE_BUFFERED 0x0008 /* line buffered io (^h, ^u, etc) */
#define LIBIO_FLAGS_OPEN 0x0100 /* device is open */
#define LIBIO_FLAGS_APPEND 0x0200 /* all writes append */
#define LIBIO_FLAGS_CREATE 0x0400 /* create file */
#define LIBIO_FLAGS_READ_WRITE (LIBIO_FLAGS_READ | LIBIO_FLAGS_WRITE)
void rtems_libio_config(rtems_configuration_table *config, unsigned32 max_fds);
void rtems_libio_init(void);
int __open(const char *pathname, unsigned32 flag, unsigned32 mode);
int __close(int fd);
int __read(int fd, void *buffer, unsigned32 count);
int __write(int fd, const void *buffer, unsigned32 count);
int __ioctl(int fd, unsigned32 command, void *buffer);
int __lseek(int fd, rtems_libio_offset_t offset, int whence);
#endif /* _RTEMS_LIBIO_H */

View File

@@ -35,27 +35,6 @@ __isatty(int _fd)
return 1;
}
int
__close(int _fd)
{
/* return value usually ignored anyhow */
return 0;
}
int
__open(const char *filename)
{
/* always fail */
return -1;
}
int
__lseek(int _fd, off_t offset, int whence)
{
/* nothing is ever seekable */
return -1;
}
int stat( const char *path, struct stat *buf )
{
/* always fail */

View File

@@ -14,8 +14,9 @@
* $Id$
*/
#include <rtems.h>
#include <bsp.h>
#include <clockdrv.h>
#include <rtems/libio.h>
#include <stdlib.h> /* for atexit() */
@@ -23,6 +24,13 @@ extern rtems_cpu_table Cpu_table; /* owned by BSP */
typedef unsigned long long hppa_click_count_t;
/*
* These are set by clock driver during its init
*/
rtems_device_major_number rtems_clock_major = ~0;
rtems_device_minor_number rtems_clock_minor;
/*
* CPU_HPPA_CLICKS_PER_TICK is either a #define or an rtems_unsigned32
* allocated and set by bsp_start()
@@ -41,16 +49,7 @@ rtems_unsigned64 Clock_clicks; /* running total of cycles */
rtems_unsigned32 Clock_clicks_interrupt;
rtems_device_driver Clock_initialize(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *pargp,
rtems_id tid,
rtems_unsigned32 *rval
)
{
Install_clock(Clock_isr);
}
void Clock_exit(void);
void
ReInstall_clock(rtems_isr_entry new_clock_isr)
@@ -218,3 +217,48 @@ Clock_delay(rtems_unsigned32 microseconds)
}
}
rtems_device_driver Clock_initialize(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *pargp
)
{
Install_clock(Clock_isr);
/*
* make major/minor avail to others such as shared memory driver
*/
rtems_clock_major = major;
rtems_clock_minor = minor;
return RTEMS_SUCCESSFUL;
}
rtems_device_driver Clock_control(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *pargp
)
{
rtems_libio_ioctl_args_t *args = pargp;
if (args == 0)
goto done;
/*
* This is hokey, but until we get a defined interface
* to do this, it will just be this simple...
*/
if (args->command == rtems_build_name('I', 'S', 'R', ' '))
{
Clock_isr(HPPA_INTERRUPT_EXTERNAL_INTERVAL_TIMER);
}
else if (args->command == rtems_build_name('N', 'E', 'W', ' '))
{
ReInstall_clock(args->buffer);
}
done:
return RTEMS_SUCCESSFUL;
}

View File

@@ -0,0 +1,258 @@
/*
* @(#)assoc.c 1.4 - 95/08/02
*
*
* assoc.c
* rtems assoc routines
*
* $Id$
*/
#include <rtems.h>
#include "assoc.h"
#include <stdio.h> /* sprintf */
#include <string.h> /* strcat, strcmp */
#define STREQ(a,b) (strcmp((a), (b)) == 0)
#define rtems_assoc_is_default(ap) ((ap)->name && STREQ(ap->name, RTEMS_ASSOC_DEFAULT_NAME))
rtems_assoc_t *
rtems_assoc_ptr_by_name(
rtems_assoc_t *ap,
char *name
)
{
rtems_assoc_t *default_ap = 0;
if (rtems_assoc_is_default(ap))
default_ap = ap++;
for ( ; ap->name; ap++)
if (strcmp(ap->name, name) == 0)
return ap;
return default_ap;
}
rtems_assoc_t *
rtems_assoc_ptr_by_local(
rtems_assoc_t *ap,
unsigned32 local_value
)
{
rtems_assoc_t *default_ap = 0;
if (rtems_assoc_is_default(ap))
default_ap = ap++;
for ( ; ap->name; ap++)
if (ap->local_value == local_value)
return ap;
return default_ap;
}
rtems_assoc_t *
rtems_assoc_ptr_by_remote(
rtems_assoc_t *ap,
unsigned32 remote_value
)
{
rtems_assoc_t *default_ap = 0;
if (rtems_assoc_is_default(ap))
default_ap = ap++;
for ( ; ap->name; ap++)
if (ap->remote_value == remote_value)
return ap;
return default_ap;
}
/*
* Get values
*/
unsigned32
rtems_assoc_remote_by_local(
rtems_assoc_t *ap,
unsigned32 local_value
)
{
rtems_assoc_t *nap;
nap = rtems_assoc_ptr_by_local(ap, local_value);
if (nap)
return nap->remote_value;
return 0;
}
unsigned32
rtems_assoc_local_by_remote(
rtems_assoc_t *ap,
unsigned32 remote_value
)
{
rtems_assoc_t *nap;
nap = rtems_assoc_ptr_by_remote(ap, remote_value);
if (nap)
return nap->local_value;
return 0;
}
unsigned32
rtems_assoc_remote_by_name(
rtems_assoc_t *ap,
char *name
)
{
rtems_assoc_t *nap;
nap = rtems_assoc_ptr_by_name(ap, name);
if (nap)
return nap->remote_value;
return 0;
}
unsigned32
rtems_assoc_local_by_name(
rtems_assoc_t *ap,
char *name
)
{
rtems_assoc_t *nap;
nap = rtems_assoc_ptr_by_name(ap, name);
if (nap)
return nap->local_value;
return 0;
}
/*
* what to return if a value is not found
* this is not reentrant, but it really shouldn't be invoked anyway
*/
char *
rtems_assoc_name_bad(
unsigned32 bad_value
)
{
static char bad_buffer[32];
sprintf(bad_buffer, "< %d [0x%x] >", bad_value, bad_value);
return bad_buffer;
}
char *
rtems_assoc_name_by_local(
rtems_assoc_t *ap,
unsigned32 local_value
)
{
rtems_assoc_t *nap;
nap = rtems_assoc_ptr_by_local(ap, local_value);
if (nap)
return nap->name;
return rtems_assoc_name_bad(local_value);
}
char *
rtems_assoc_name_by_remote(
rtems_assoc_t *ap,
unsigned32 remote_value
)
{
rtems_assoc_t *nap;
nap = rtems_assoc_ptr_by_remote(ap, remote_value);
if (nap)
return nap->name;
return rtems_assoc_name_bad(remote_value);
}
/*
* Bitfield functions assume just 1 bit set in each of remote and local
* entries; they do not check for this.
*/
unsigned32 rtems_assoc_remote_by_local_bitfield(
rtems_assoc_t *ap,
unsigned32 local_value
)
{
unsigned32 b;
unsigned32 remote_value = 0;
for (b = 1; b; b <<= 1)
if (b & local_value)
remote_value |= rtems_assoc_remote_by_local(ap, b);
return remote_value;
}
unsigned32 rtems_assoc_local_by_remote_bitfield(
rtems_assoc_t *ap,
unsigned32 remote_value
)
{
unsigned32 b;
unsigned32 local_value = 0;
for (b = 1; b; b <<= 1)
if (b & remote_value)
local_value |= rtems_assoc_local_by_remote(ap, b);
return local_value;
}
char *rtems_assoc_name_by_remote_bitfield(
rtems_assoc_t *ap,
unsigned32 value,
char *buffer
)
{
unsigned32 b;
*buffer = 0;
for (b = 1; b; b <<= 1)
if (b & value)
{
if (*buffer)
strcat(buffer, " ");
strcat(buffer, rtems_assoc_name_by_remote(ap, b));
}
return buffer;
}
char *rtems_assoc_name_by_local_bitfield(
rtems_assoc_t *ap,
unsigned32 value,
char *buffer
)
{
unsigned32 b;
*buffer = 0;
for (b = 1; b; b <<= 1)
if (b & value)
{
if (*buffer)
strcat(buffer, " ");
strcat(buffer, rtems_assoc_name_by_local(ap, b));
}
return buffer;
}

View File

@@ -0,0 +1,44 @@
/*
* @(#)assoc.h 1.2 - 95/06/28
*
*
* Rtems associativity routines. Mainly used to convert a value from
* one space to another (eg: our errno's to host errno's and v.v)
*
*
* $Id$
*/
#ifndef _INCLUDE_ASSOC_H
#define _INCLUDE_ASSOC_H
typedef struct {
char *name;
unsigned32 local_value;
unsigned32 remote_value;
} rtems_assoc_t;
/*
* Flag/marker for optional default value in each table
*/
#define RTEMS_ASSOC_DEFAULT_NAME "(default)"
rtems_assoc_t *rtems_assoc_ptr_by_name(rtems_assoc_t *, char *);
rtems_assoc_t *rtems_assoc_ptr_by_value(rtems_assoc_t *, unsigned32);
rtems_assoc_t *rtems_assoc_ptr_by_remote(rtems_assoc_t *, unsigned32);
unsigned32 rtems_assoc_remote_by_local(rtems_assoc_t *, unsigned32);
unsigned32 rtems_assoc_local_by_remote(rtems_assoc_t *, unsigned32);
unsigned32 rtems_assoc_remote_by_name(rtems_assoc_t *, char *);
unsigned32 rtems_assoc_local_by_name(rtems_assoc_t *, char *);
char *rtems_assoc_name_by_local(rtems_assoc_t *, unsigned32);
char *rtems_assoc_name_by_remote(rtems_assoc_t *, unsigned32);
unsigned32 rtems_assoc_remote_by_local_bitfield(rtems_assoc_t *, unsigned32);
char *rtems_assoc_name_by_local_bitfield(rtems_assoc_t *, unsigned32, char *);
char *rtems_assoc_name_by_remote_bitfield(rtems_assoc_t *, unsigned32, char *);
unsigned32 rtems_assoc_local_by_remote_bitfield(rtems_assoc_t *ap, unsigned32);
#endif /* ! _INCLUDE_ASSOC_H */

View File

@@ -0,0 +1,212 @@
/*
* @(#)error.c 1.2 - 95/08/02
*
*
* report errors and panics to RTEMS' stderr.
* Currently just used by RTEMS monitor.
*
*
* $Id$
*/
/*
* These routines provide general purpose error reporting.
* rtems_error reports an error to stderr and allows use of
* printf style formatting. A newline is appended to all messages.
*
* error_flag can be specified as any of the following:
*
* RTEMS_ERROR_ERRNO -- include errno text in output
* RTEMS_ERROR_PANIC -- halts local system after output
* RTEMS_ERROR_ABORT -- abort after output
*
* It can also include a rtems_status value which can be OR'd
* with the above flags. *
*
* EXAMPLE
* #include <rtems.h>
* #include <rtems/error.h>
* rtems_error(0, "stray interrupt %d", intr);
*
* EXAMPLE
* if ((status = rtems_task_create(...)) != RTEMS_SUCCCESSFUL)
* {
* rtems_error(status | RTEMS_ERROR_ABORT,
* "could not create task");
* }
*
* EXAMPLE
* if ((fd = open(pathname, O_RDNLY)) < 0)
* {
* rtems_error(FLOSS_ERROR_ERRNO, "open of '%s' failed", pathname);
* goto failed;
* }
*/
#include <rtems.h>
#include "error.h"
#include "assoc.h"
#include <stdio.h>
#include <stdarg.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h> /* _exit() */
/* bug in hpux <errno.h>: no prototypes unless you are C++ */
#ifdef hpux9
char *strerror(int);
#endif
extern char *rtems_progname;
int rtems_panic_in_progress;
rtems_assoc_t rtems_status_assoc[] = {
{ "successful completion", RTEMS_SUCCESSFUL, },
{ "returned from a thread", RTEMS_TASK_EXITTED, },
{ "multiprocessing not configured", RTEMS_MP_NOT_CONFIGURED, },
{ "invalid object name", RTEMS_INVALID_NAME, },
{ "invalid object id", RTEMS_INVALID_ID, },
{ "too many", RTEMS_TOO_MANY, },
{ "timed out waiting", RTEMS_TIMEOUT, },
{ "object deleted while waiting", RTEMS_OBJECT_WAS_DELETED, },
{ "specified size was invalid", RTEMS_INVALID_SIZE, },
{ "address specified is invalid", RTEMS_INVALID_ADDRESS, },
{ "number was invalid", RTEMS_INVALID_NUMBER, },
{ "item has not been initialized", RTEMS_NOT_DEFINED, },
{ "resources still outstanding", RTEMS_RESOURCE_IN_USE, },
{ "request not satisfied", RTEMS_UNSATISFIED, },
{ "thread is in wrong state", RTEMS_INCORRECT_STATE, },
{ "thread already in state", RTEMS_ALREADY_SUSPENDED, },
{ "illegal on calling thread", RTEMS_ILLEGAL_ON_SELF, },
{ "illegal for remote object", RTEMS_ILLEGAL_ON_REMOTE_OBJECT, },
{ "called from wrong environment", RTEMS_CALLED_FROM_ISR, },
{ "invalid thread priority", RTEMS_INVALID_PRIORITY, },
{ "invalid date/time", RTEMS_INVALID_CLOCK, },
{ "invalid node id", RTEMS_INVALID_NODE, },
{ "directive not configured", RTEMS_NOT_CONFIGURED, },
{ "not owner of resource", RTEMS_NOT_OWNER_OF_RESOURCE , },
{ "directive not implemented", RTEMS_NOT_IMPLEMENTED, },
{ "RTEMS inconsistency detected", RTEMS_INTERNAL_ERROR, },
{ "internal multiprocessing only", RTEMS_PROXY_BLOCKING, },
{ "could not get enough memory", RTEMS_NO_MEMORY, },
{ 0, 0, 0 },
};
char *
rtems_status_text(
rtems_status_code status
)
{
return rtems_assoc_name_by_local(rtems_status_assoc, status);
}
static int rtems_verror(
unsigned32 error_flag,
char *printf_format,
va_list arglist
)
{
int local_errno = 0;
int chars_written = 0;
rtems_status_code status;
if (error_flag & RTEMS_ERROR_PANIC)
{
rtems_panic_in_progress++;
/* disable task switches */
_Thread_Disable_dispatch();
/* don't aggravate things */
if (rtems_panic_in_progress > 2)
return 0;
}
(void) fflush(stdout); /* in case stdout/stderr same */
status = error_flag & ~RTEMS_ERROR_MASK;
if (error_flag & RTEMS_ERROR_ERRNO) /* include errno? */
local_errno = errno;
if (_Configuration_Is_multiprocessing())
fprintf(stderr, "[%d] ", _Configuration_MP_table->node);
if (rtems_progname && *rtems_progname)
chars_written += fprintf(stderr, "%s: ", rtems_progname);
chars_written += vfprintf(stderr, printf_format, arglist);
if (status)
chars_written += fprintf(stderr, " (status: %s)", rtems_status_text(status));
if (local_errno)
if ((local_errno > 0) && *strerror(local_errno))
chars_written += fprintf(stderr, " (errno: %s)", strerror(local_errno));
else
chars_written += fprintf(stderr, " (unknown errno=%d)", local_errno);
chars_written += fprintf(stderr, "\n");
(void) fflush(stderr);
if (error_flag & (RTEMS_ERROR_PANIC | RTEMS_ERROR_ABORT))
{
if (error_flag & RTEMS_ERROR_PANIC)
{
rtems_error(0, "fatal error, exiting");
_exit(local_errno);
}
else
{
rtems_error(0, "fatal error, aborting");
abort();
}
}
return chars_written;
}
/*
* Report an error.
* error_flag is as above; printf_format is a normal
* printf(3) format string, with its concommitant arguments.
*
* Returns the number of characters written.
*/
int rtems_error(
int error_flag,
char *printf_format,
...
)
{
va_list arglist;
int chars_written;
va_start(arglist, printf_format);
chars_written = rtems_verror(error_flag, printf_format, arglist);
va_end(arglist);
return chars_written;
}
/*
* rtems_panic is shorthand for rtems_error(RTEMS_ERROR_PANIC, ...)
*/
void rtems_panic(
char *printf_format,
...
)
{
va_list arglist;
va_start(arglist, printf_format);
(void) rtems_verror(RTEMS_ERROR_PANIC, printf_format, arglist);
va_end(arglist);
}

View File

@@ -0,0 +1,26 @@
/*
* @(#)error.h 1.1 - 95/08/02
*
*
* Defines and externs for rtems error reporting
*
* $Id$
*/
/*
* rtems_error() and rtems_panic() support
*/
#define RTEMS_ERROR_ERRNO (1<<((sizeof(int) * 8) - 2)) /* hi bit; use 'errno' */
#define RTEMS_ERROR_PANIC (RTEMS_ERROR_ERRNO / 2) /* err fatal; no return */
#define RTEMS_ERROR_ABORT (RTEMS_ERROR_ERRNO / 4) /* err is fatal; panic */
#define RTEMS_ERROR_MASK (RTEMS_ERROR_ERRNO | RTEMS_ERROR_ABORT | \
RTEMS_ERROR_PANIC) /* all */
char *rtems_status_text(rtems_status_code);
int rtems_error(int error_code, char *printf_format, ...);
void rtems_panic(char *printf_format, ...);
extern int rtems_panic_in_progress;

View File

@@ -2,6 +2,96 @@
# $Id$
#
This is a snapshot of a work in process. It is the beginnings of a
debug monitor task and trap handler which is tasking aware.
monitor task
The monitor task is an optional task that knows about RTEMS
data structures and can print out information about them.
It is a work-in-progress and needs many more commands, but
is useful now.
The monitor works best when it is the highest priority task,
so all your other tasks should ideally be at some priority
greater than 1.
To use the monitor:
-------------------
#include <rtems/monitor.h>
...
rtems_monitor_init(0);
The parameter to rtems_monitor_init() tells the monitor whether
to suspend itself on startup. A value of 0 causes the monitor
to immediately enter command mode; a non-zero value causes the
monitor to suspend itself after creation and wait for explicit
wakeup.
rtems_monitor_wakeup();
wakes up a suspended monitor and causes it to reenter command mode.
Monitor commands
----------------
The monitor prompt is 'rtems> '.
Can abbreviate commands to "uniquity"
There is a 'help' command. Here is the output from various
help commands:
Commands (may be abbreviated)
help -- get this message or command specific help
task -- show task information
queue -- show message queue information
symbol -- show entries from symbol table
pause -- pause monitor for a specified number of ticks
fatal -- invoke a fatal RTEMS error
task [id [id ...] ]
display information about the specified tasks.
Default is to display information about all tasks on this node
queue [id [id ... ] ]
display information about the specified message queues
Default is to display information about all queues on this node
symbol [ symbolname [symbolname ... ] ]
display value associated with specified symbol.
Defaults to displaying all known symbols.
pause [ticks]
monitor goes to "sleep" for specified ticks (default is 1)
monitor will resume at end of period or if explicitly awakened
fatal [status]
Invoke 'rtems_fatal_error_occurred' with 'status'
(default is RTEMS_INTERNAL_ERROR)
continue
put the monitor to sleep waiting for an explicit wakeup from the
program running.
Sample output from 'task' command
---------------------------------
rtems> task
ID NAME PRIO STAT MODES EVENTS WAITID WAITARG NOTES
------------------------------------------------------------------------
00010001 UI1 2 READY P:T:nA NONE15: 0x40606348
00010002 RMON 1 READY nP NONE15: 0x40604110
'RMON' is the monitor itself, so we have 1 "user" task.
Its modes are P:T:nA which translate to:
preemptable
timesliced
no ASRS
It has no events.
It has a notepad value for notepad 15 which is 0x40606348
(this is the libc thread state)

View File

@@ -0,0 +1,190 @@
/*
* @(#)command.c 1.5 - 95/08/02
*
*
* Command parsing routines for RTEMS monitor
*
* TODO:
*
* $Id$
*/
#include <rtems.h>
#include "monitor.h"
#include <stdio.h>
#include <string.h>
/*
* make_argv(cp): token-count
* Break up the command line in 'cp' into global argv[] and argc (return
* value).
*/
int
rtems_monitor_make_argv(
char *cp,
int *argc_p,
char **argv)
{
int argc = 0;
while ((cp = strtok(cp, " \t\n\r")))
{
argv[argc++] = cp;
cp = (char *) NULL;
}
argv[argc] = (char *) NULL; /* end of argv */
return *argc_p = argc;
}
/*
* Read and break up a monitor command
*
* We have to loop on the gets call, since it will return NULL under UNIX
* RTEMS when we get a signal (eg: SIGALRM).
*/
int
rtems_monitor_command_read(char *command,
int *argc,
char **argv)
{
extern rtems_configuration_table BSP_Configuration;
static char monitor_prompt[32];
/*
* put node number in the prompt if we are multiprocessing
*/
if (BSP_Configuration.User_multiprocessing_table == 0)
sprintf(monitor_prompt, "%s", MONITOR_PROMPT);
else if (rtems_monitor_default_node != rtems_monitor_node)
sprintf(monitor_prompt, "%d-%s-%d", rtems_monitor_node, MONITOR_PROMPT, rtems_monitor_default_node);
else
sprintf(monitor_prompt, "%d-%s", rtems_monitor_node, MONITOR_PROMPT);
#ifdef RTEMS_UNIX
/* RTEMS on unix gets so many interrupt system calls this is hosed */
printf("%s> ", monitor_prompt);
fflush(stdout);
while (gets(command) == (char *) 0)
;
#else
do
{
printf("%s> ", monitor_prompt);
fflush(stdout);
} while (gets(command) == (char *) 0);
#endif
return rtems_monitor_make_argv(command, argc, argv);
}
/*
* Look up a command in a command table
*
*/
rtems_monitor_command_entry_t *
rtems_monitor_command_lookup(
rtems_monitor_command_entry_t *table,
int argc,
char **argv
)
{
rtems_monitor_command_entry_t *p;
rtems_monitor_command_entry_t *abbreviated_match = 0;
int abbreviated_matches = 0;
char *command;
int command_length;
command = argv[0];
if ((table == 0) || (command == 0))
goto failed;
command_length = strlen(command);
for (p = table; p->command; p++)
if (STREQ(command, p->command)) /* exact match */
goto done;
else if (STRNEQ(command, p->command, command_length))
{
abbreviated_matches++;
abbreviated_match = p;
}
/* no perfect match; is there a non-ambigous abbreviated match? */
if ( ! abbreviated_match)
{
printf("Unrecognized command '%s'; try 'help'\n", command);
goto failed;
}
if (abbreviated_matches > 1)
{
printf("Command '%s' is ambiguous; try 'help'\n", command);
goto failed;
}
p = abbreviated_match;
done:
if (p->command_function == 0)
goto failed;
return p;
failed:
return 0;
}
void
rtems_monitor_command_usage(rtems_monitor_command_entry_t *table,
char *command_string)
{
rtems_monitor_command_entry_t *help = 0;
char *help_command_argv[2];
/* if first entry in table is a usage, then print it out */
if (command_string == 0)
{
if (STREQ(table->command, "--usage--") && table->usage)
help = table;
}
else
{
help_command_argv[0] = command_string;
help_command_argv[1] = 0;
help = rtems_monitor_command_lookup(table, 1, help_command_argv);
}
if (help)
printf("%s\n", help->usage);
}
void
rtems_monitor_help_cmd(
int argc,
char **argv,
unsigned32 command_arg,
boolean verbose
)
{
int arg;
rtems_monitor_command_entry_t *command;
command = (rtems_monitor_command_entry_t *) command_arg;
if (argc == 1)
rtems_monitor_command_usage(command, 0);
else
{
for (arg=1; argv[arg]; arg++)
rtems_monitor_command_usage(command, argv[arg]);
}
}

View File

@@ -0,0 +1,132 @@
/*
* @(#)config.c 1.5 - 95/08/02
*
*
* RTEMS Config display support
*
* TODO
*
* $Id$
*/
#include <rtems.h>
#include "monitor.h"
#include <stdio.h>
#include <stdlib.h> /* strtoul() */
#define DATACOL 15
#define CONTCOL DATACOL /* continued col */
/*
* Fill in entire monitor config table
* for sending to a remote monitor or printing on the local system
*/
void
rtems_monitor_config_canonical(
rtems_monitor_config_t *canonical_config,
void *config_void
)
{
rtems_configuration_table *c = (rtems_configuration_table *) config_void;
canonical_config->work_space_start = c->work_space_start;
canonical_config->work_space_size = c->work_space_size;
canonical_config->maximum_tasks = c->maximum_tasks;
canonical_config->maximum_timers = c->maximum_timers;
canonical_config->maximum_semaphores = c->maximum_semaphores;
canonical_config->maximum_message_queues = c->maximum_message_queues;
canonical_config->maximum_partitions = c->maximum_partitions;
canonical_config->maximum_regions = c->maximum_regions;
canonical_config->maximum_ports = c->maximum_ports;
canonical_config->maximum_periods = c->maximum_periods;
canonical_config->maximum_extensions = c->maximum_extensions;
canonical_config->microseconds_per_tick = c->microseconds_per_tick;
canonical_config->ticks_per_timeslice = c->ticks_per_timeslice;
canonical_config->number_of_initialization_tasks = c->number_of_initialization_tasks;
}
/*
* This is easy, since there is only 1 (altho we could get them from
* other nodes...)
*/
void *
rtems_monitor_config_next(
void *object_info,
rtems_monitor_config_t *canonical_config,
rtems_id *next_id
)
{
rtems_configuration_table *c = _Configuration_Table;
int n = rtems_get_index(*next_id);
if (n >= 1)
goto failed;
_Thread_Disable_dispatch();
*next_id += 1;
return (void *) c;
failed:
*next_id = RTEMS_OBJECT_ID_FINAL;
return 0;
}
void
rtems_monitor_config_dump_header(
boolean verbose
)
{
printf("\
INITIAL (startup) Configuration Info\n");
/*23456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789
0 1 2 3 4 5 6 7 */
rtems_monitor_separator();
}
void
rtems_monitor_config_dump(
rtems_monitor_config_t *monitor_config,
boolean verbose
)
{
unsigned32 length = 0;
length = 0;
length += printf("WORKSPACE");
length += rtems_monitor_pad(DATACOL, length);
length += printf("start: 0x%x; size: 0x%x\n",
(unsigned32) monitor_config->work_space_start,
monitor_config->work_space_size);
length = 0;
length += printf("TIME");
length += rtems_monitor_pad(DATACOL, length);
length += printf("usec/tick: %d; tick/timeslice: %d; tick/sec: %d\n",
monitor_config->microseconds_per_tick,
monitor_config->ticks_per_timeslice,
1000000 / monitor_config->microseconds_per_tick);
length = 0;
length += printf("MAXIMUMS");
length += rtems_monitor_pad(DATACOL, length);
length += printf("tasks: %d; timers: %d; sems: %d; que's: %d; ext's: %d\n",
monitor_config->maximum_tasks,
monitor_config->maximum_timers,
monitor_config->maximum_semaphores,
monitor_config->maximum_message_queues,
monitor_config->maximum_extensions);
length = 0;
length += rtems_monitor_pad(CONTCOL, length);
length += printf("partitions: %d; regions: %d; ports: %d; periods: %d\n",
monitor_config->maximum_partitions,
monitor_config->maximum_regions,
monitor_config->maximum_ports,
monitor_config->maximum_periods);
}

View File

@@ -0,0 +1,113 @@
/*
* @(#)dname.c 1.3 - 95/07/31
*
*
* RTEMS monitor driver names support.
*
* There are 2 "driver" things the monitor knows about.
*
* 1. Regular RTEMS drivers.
* This is a table indexed by major device number and
* containing driver entry points only.
*
* 2. Driver name table.
* A separate table of names for drivers.
* The table converts driver names to a major number
* as index into the driver table and a minor number
* for an argument to driver.
*
* Drivers are displayed with 'driver' command.
* Names are displayed with 'dname' command.
*
* $Id$
*/
#include <rtems.h>
#include "monitor.h"
#include <stdio.h>
#include <stdlib.h> /* strtoul() */
#include <string.h> /* strncpy() */
#define DATACOL 15
#define CONTCOL DATACOL /* continued col */
void
rtems_monitor_dname_canonical(
rtems_monitor_dname_t *canonical_dname,
void *dname_void
)
{
rtems_driver_name_t *np = (rtems_driver_name_t *) dname_void;
(void) strncpy(canonical_dname->name_string, np->device_name, sizeof(canonical_dname->name_string));
canonical_dname->major = np->major;
canonical_dname->minor = np->minor;
}
void *
rtems_monitor_dname_next(
void *object_information,
rtems_monitor_dname_t *canonical_dname,
rtems_id *next_id
)
{
int n = rtems_get_index(*next_id);
rtems_driver_name_t *table = object_information;
rtems_driver_name_t *np = 0;
for (np = table + n ; n<RTEMS_MAX_DRIVER_NAMES; n++, np++)
if (np->device_name)
goto done;
*next_id = RTEMS_OBJECT_ID_FINAL;
return 0;
done:
_Thread_Disable_dispatch();
/*
* dummy up a fake id and name for this item
*/
canonical_dname->id = n;
canonical_dname->name = rtems_build_name('-', '-', '-', '-');
*next_id += 1;
return np;
}
void
rtems_monitor_dname_dump_header(
boolean verbose
)
{
printf("\
Major:Minor Name\n");
/*23456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789
0 1 2 3 4 5 6 7 */
rtems_monitor_separator();
}
void
rtems_monitor_dname_dump(
rtems_monitor_dname_t *monitor_dname,
boolean verbose
)
{
unsigned32 length = 0;
length += rtems_monitor_pad(6, length);
length += rtems_monitor_dump_hex(monitor_dname->major);
length += printf(":");
length += rtems_monitor_dump_hex(monitor_dname->minor);
length += rtems_monitor_pad(16, length);
length += printf("%.*s",
(int) sizeof(monitor_dname->name_string),
(char *) monitor_dname->name_string);
length += printf("\n");
length = 0;
}

View File

@@ -0,0 +1,138 @@
/*
* @(#)driver.c 1.4 - 95/08/02
*
*
* RTEMS monitor IO (device drivers) support
*
* There are 2 "driver" things the monitor knows about.
*
* 1. Regular RTEMS drivers.
* This is a table indexed by major device number and
* containing driver entry points only.
*
* 2. Driver name table.
* A separate table of names for drivers.
* The table converts driver names to a major number
* as index into the driver table and a minor number
* for an argument to driver.
*
* Drivers are displayed with 'driver' command.
* Names are displayed with 'name' command.
*
* $Id$
*/
#include <rtems.h>
#include "monitor.h"
#include <stdio.h>
#include <stdlib.h> /* strtoul() */
#define DATACOL 15
#define CONTCOL DATACOL /* continued col */
void
rtems_monitor_driver_canonical(
rtems_monitor_driver_t *canonical_driver,
void *driver_void
)
{
rtems_driver_address_table *d = (rtems_driver_address_table *) driver_void;
rtems_monitor_symbol_canonical_by_value(&canonical_driver->initialization,
d->initialization);
rtems_monitor_symbol_canonical_by_value(&canonical_driver->open,
d->open);
rtems_monitor_symbol_canonical_by_value(&canonical_driver->close,
d->close);
rtems_monitor_symbol_canonical_by_value(&canonical_driver->read,
d->read);
rtems_monitor_symbol_canonical_by_value(&canonical_driver->write,
d->write);
rtems_monitor_symbol_canonical_by_value(&canonical_driver->control,
d->control);
}
void *
rtems_monitor_driver_next(
void *object_info,
rtems_monitor_driver_t *canonical_driver,
rtems_id *next_id
)
{
rtems_configuration_table *c = _Configuration_Table;
int n = rtems_get_index(*next_id);
if (n >= c->number_of_device_drivers)
goto failed;
_Thread_Disable_dispatch();
/*
* dummy up a fake id and name for this item
*/
canonical_driver->id = n;
canonical_driver->name = rtems_build_name('-', '-', '-', '-');
*next_id += 1;
return (void *) (c->Device_driver_table + n);
failed:
*next_id = RTEMS_OBJECT_ID_FINAL;
return 0;
}
void
rtems_monitor_driver_dump_header(
boolean verbose
)
{
printf("\
Major Entry points\n");
/*23456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789
0 1 2 3 4 5 6 7 */
rtems_monitor_separator();
}
void
rtems_monitor_driver_dump(
rtems_monitor_driver_t *monitor_driver,
boolean verbose
)
{
unsigned32 length = 0;
length += printf(" %d", monitor_driver->id);
length += rtems_monitor_pad(13, length);
length += printf("init: ");
length += rtems_monitor_symbol_dump(&monitor_driver->initialization, verbose);
length += printf("; control: ");
length += rtems_monitor_symbol_dump(&monitor_driver->control, verbose);
length += printf("\n");
length = 0;
length += rtems_monitor_pad(13, length);
length += printf("open: ");
length += rtems_monitor_symbol_dump(&monitor_driver->open, verbose);
length += printf("; close: ");
length += rtems_monitor_symbol_dump(&monitor_driver->close, verbose);
length += printf("\n");
length = 0;
length += rtems_monitor_pad(13, length);
length += printf("read: ");
length += rtems_monitor_symbol_dump(&monitor_driver->read, verbose);
length += printf("; write: ");
length += rtems_monitor_symbol_dump(&monitor_driver->write, verbose);
length += printf("\n");
length = 0;
}

View File

@@ -0,0 +1,101 @@
/*
* @(#)extension.c 1.3 - 95/07/31
*
*
* RTEMS Monitor extension support
*
* $Id$
*/
#include <rtems.h>
#include "monitor.h"
#include <stdio.h>
void
rtems_monitor_extension_canonical(
rtems_monitor_extension_t *canonical_extension,
void *extension_void
)
{
Extension_Control *rtems_extension = (Extension_Control *) extension_void;
rtems_extensions_table *e = &rtems_extension->Extension.Callouts;
rtems_monitor_symbol_canonical_by_value(&canonical_extension->create,
e->rtems_task_create);
rtems_monitor_symbol_canonical_by_value(&canonical_extension->start,
e->rtems_task_start);
rtems_monitor_symbol_canonical_by_value(&canonical_extension->restart,
e->rtems_task_restart);
rtems_monitor_symbol_canonical_by_value(&canonical_extension->delete,
e->rtems_task_delete);
rtems_monitor_symbol_canonical_by_value(&canonical_extension->tswitch,
e->task_switch);
rtems_monitor_symbol_canonical_by_value(&canonical_extension->begin,
e->task_begin);
rtems_monitor_symbol_canonical_by_value(&canonical_extension->exitted,
e->task_exitted);
rtems_monitor_symbol_canonical_by_value(&canonical_extension->fatal,
e->fatal);
}
void
rtems_monitor_extension_dump_header(
boolean verbose
)
{
printf("\
ID NAME\n");
/*23456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789
0 1 2 3 4 5 6 7 */
rtems_monitor_separator();
}
/*
* Dump out the canonical form
*/
void
rtems_monitor_extension_dump(
rtems_monitor_extension_t *monitor_extension,
boolean verbose
)
{
unsigned32 length = 0;
length += rtems_monitor_dump_id(monitor_extension->id);
length += rtems_monitor_pad(11, length);
length += rtems_monitor_dump_name(monitor_extension->name);
length += rtems_monitor_pad(18, length);
length += printf("create: ");
length += rtems_monitor_symbol_dump(&monitor_extension->create, verbose);
length += printf("; start: ");
length += rtems_monitor_symbol_dump(&monitor_extension->start, verbose);
length += printf("; restart: ");
length += rtems_monitor_symbol_dump(&monitor_extension->restart, verbose);
length += printf("\n");
length = 0;
length += rtems_monitor_pad(18, length);
length += printf("delete: ");
length += rtems_monitor_symbol_dump(&monitor_extension->delete, verbose);
length += printf("; switch: ");
length += rtems_monitor_symbol_dump(&monitor_extension->tswitch, verbose);
length += printf("; begin: ");
length += rtems_monitor_symbol_dump(&monitor_extension->begin, verbose);
length += printf("\n");
length = 0;
length += rtems_monitor_pad(18, length);
length += printf("exitted: ");
length += rtems_monitor_symbol_dump(&monitor_extension->exitted, verbose);
length += printf("; fatal: ");
length += rtems_monitor_symbol_dump(&monitor_extension->fatal, verbose);
length += printf("\n");
length = 0;
printf("\n");
}

View File

@@ -0,0 +1,117 @@
/*
* @(#)itask.c 1.4 - 95/08/02
*
*
* RTEMS Monitor init task support
*
* $Id$
*/
#include <rtems.h>
#include "monitor.h"
#include <stdio.h>
/*
* As above, but just for init tasks
*/
void
rtems_monitor_init_task_canonical(
rtems_monitor_init_task_t *canonical_itask,
void *itask_void
)
{
rtems_initialization_tasks_table *rtems_itask = itask_void;
rtems_monitor_symbol_canonical_by_value(&canonical_itask->entry,
rtems_itask->entry_point);
canonical_itask->argument = rtems_itask->argument;
canonical_itask->stack_size = rtems_itask->stack_size;
canonical_itask->priority = rtems_itask->initial_priority;
canonical_itask->modes = rtems_itask->mode_set;
canonical_itask->attributes = rtems_itask->attribute_set;
}
void *
rtems_monitor_init_task_next(
void *object_info,
rtems_monitor_init_task_t *canonical_init_task,
rtems_id *next_id
)
{
rtems_configuration_table *c = _Configuration_Table;
rtems_initialization_tasks_table *itask;
int n = rtems_get_index(*next_id);
if (n >= c->number_of_initialization_tasks)
goto failed;
_Thread_Disable_dispatch();
itask = c->User_initialization_tasks_table + n;
/*
* dummy up a fake id and name for this item
*/
canonical_init_task->id = n;
canonical_init_task->name = itask->name;
*next_id += 1;
return (void *) itask;
failed:
*next_id = RTEMS_OBJECT_ID_FINAL;
return 0;
}
void
rtems_monitor_init_task_dump_header(
boolean verbose
)
{
printf("\
# NAME ENTRY ARGUMENT PRIO MODES ATTRIBUTES STACK SIZE\n");
/*23456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789
0 1 2 3 4 5 6 7 */
rtems_monitor_separator();
}
/*
*/
void
rtems_monitor_init_task_dump(
rtems_monitor_init_task_t *monitor_itask,
boolean verbose
)
{
int length = 0;
length += rtems_monitor_dump_decimal(monitor_itask->id);
length += rtems_monitor_pad(7, length);
length += rtems_monitor_dump_name(monitor_itask->name);
length += rtems_monitor_pad(14, length);
length += rtems_monitor_symbol_dump(&monitor_itask->entry, verbose);
length += rtems_monitor_pad(25, length);
length += printf("%d [0x%x]", monitor_itask->argument, monitor_itask->argument);
length += rtems_monitor_pad(39, length);
length += rtems_monitor_dump_priority(monitor_itask->priority);
length += rtems_monitor_pad(46, length);
length += rtems_monitor_dump_modes(monitor_itask->modes);
length += rtems_monitor_pad(54, length);
length += rtems_monitor_dump_attributes(monitor_itask->attributes);
length += rtems_monitor_pad(66, length);
length += printf("%d [0x%x]", monitor_itask->stack_size, monitor_itask->stack_size);
printf("\n");
}

View File

@@ -0,0 +1,52 @@
/*
* @(#)manager.c 1.2 - 95/07/31
*
*
* RTEMS Monitor "manager" support.
* Used to traverse object (chain) lists and print them out.
* $Id$
*/
#include <rtems.h>
#include "monitor.h"
#include <stdio.h>
#include <monitor.h>
/*
* "next" routine for all objects that are RTEMS manager objects
*/
void *
rtems_monitor_manager_next(
void *table_void,
void *canonical,
rtems_id *next_id
)
{
Objects_Information *table = table_void;
rtems_monitor_generic_t *copy;
Objects_Control *object = 0;
unsigned32 location;
/*
* When we are called, it must be local
*/
if ( ! _Objects_Is_local_id(*next_id))
goto done;
object = _Objects_Get_next(table, *next_id, &location, next_id);
if (object)
{
copy = (rtems_monitor_generic_t *) canonical;
copy->id = object->id;
copy->name = table->name_table[rtems_get_index(copy->id)];
}
done:
return object;
}

View File

@@ -1,125 +1,239 @@
/*
* @(#)monitor.c 1.6 - 95/04/24
* @(#)monitor.c 1.18 - 95/08/02
*
*/
/*
* mon-task.c
*
* Description:
* RTEMS monitor task
*
*
* RTEMS monitor main body
*
* TODO:
* add pause command (monitor sleeps for 'n' ticks, then wakes up)
*
* add stuff to RTEMS api
* rtems_get_name(id)
* rtems_get_type(id)
* rtems_build_id(node, type, num)
* Add a command to dump out info about an arbitrary id when
* types are added to id's
* rtems> id idnum
* idnum: node n, object: whatever, id: whatever
* allow id's to be specified as n:t:id, where 'n:t' is optional
* should have a separate monitor FILE stream (ala the debugger)
* remote request/response stuff should be cleaned up
* maybe we can use real rpc??
*
* $Id$
*/
#include <rtems.h>
/* #include <bsp.h> */
#include "symbols.h"
#include "monitor.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#define STREQ(a,b) (strcmp(a,b) == 0)
#include "monitor.h"
/* set by trap handler */
extern rtems_tcb *debugger_interrupted_task;
extern rtems_context *debugger_interrupted_task_context;
extern rtems_unsigned32 debugger_trap;
/* our task id needs to be public so any debugger can resume us */
rtems_unsigned32 rtems_monitor_task_id;
/*
* Various id's for the monitor
* They need to be public variables for access by other agencies
* such as debugger and remote servers'
*/
rtems_id rtems_monitor_task_id;
unsigned32 rtems_monitor_node; /* our node number */
unsigned32 rtems_monitor_default_node; /* current default for commands */
/*
* The rtems symbol table
*/
rtems_symbol_table_t *rtems_monitor_symbols;
/*
* The top-level commands
*/
#ifndef MONITOR_PROMPT
#define MONITOR_PROMPT "rtems> "
rtems_monitor_command_entry_t rtems_monitor_commands[] = {
{ "--usage--",
"\n"
"RTEMS monitor\n"
"\n"
"Commands (may be abbreviated)\n"
"\n"
" help -- get this message or command specific help\n"
" pause -- pause monitor for a specified number of ticks\n"
" exit -- invoke a fatal RTEMS error\n"
" symbol -- show entries from symbol table\n"
" continue -- put monitor to sleep waiting for explicit wakeup\n"
" config -- show system configuration\n"
" itask -- list init tasks\n"
" mpci -- list mpci config\n"
" task -- show task information\n"
" queue -- show message queue information\n"
" extension -- user extensions\n"
" driver -- show information about named drivers\n"
" object -- generic object information\n"
" node -- specify default node for commands that take id's\n"
#ifdef CPU_INVOKE_DEBUGGER
" debugger -- invoke system debugger\n"
#endif
,
0,
0,
(unsigned32) rtems_monitor_commands,
},
{ "config",
"config\n"
" Show the system configuration.\n",
0,
rtems_monitor_object_cmd,
RTEMS_OBJECT_CONFIG,
},
{ "itask",
"itask\n"
" List init tasks for the system\n",
0,
rtems_monitor_object_cmd,
RTEMS_OBJECT_INIT_TASK,
},
{ "mpci",
"mpci\n"
" Show the MPCI system configuration, if configured.\n",
0,
rtems_monitor_object_cmd,
RTEMS_OBJECT_MPCI,
},
{ "pause",
"pause [ticks]\n"
" monitor goes to \"sleep\" for specified ticks (default is 1)\n"
" monitor will resume at end of period or if explicitly awakened\n",
0,
rtems_monitor_pause_cmd,
0,
},
{ "continue",
"continue\n"
" put the monitor to sleep waiting for an explicit wakeup from the\n"
" program running.\n",
0,
rtems_monitor_continue_cmd,
0,
},
{ "go",
"go\n"
" Alias for 'continue'\n",
0,
rtems_monitor_continue_cmd,
0,
},
{ "node",
"node [ node number ]\n"
" Specify default node number for commands that take id's\n",
0,
rtems_monitor_node_cmd,
0,
},
{ "symbol",
"symbol [ symbolname [symbolname ... ] ]\n"
" display value associated with specified symbol.\n"
" Defaults to displaying all known symbols.\n",
0,
rtems_monitor_symbol_cmd,
(unsigned32) &rtems_monitor_symbols,
},
{ "extension",
"extension [id [id ...] ]\n"
" display information about specified extensions.\n"
" Default is to display information about all extensions on this node\n",
0,
rtems_monitor_object_cmd,
RTEMS_OBJECT_EXTENSION,
},
{ "task",
"task [id [id ...] ]\n"
" display information about the specified tasks.\n"
" Default is to display information about all tasks on this node\n",
0,
rtems_monitor_object_cmd,
RTEMS_OBJECT_TASK,
},
{ "queue",
"queue [id [id ... ] ]\n"
" display information about the specified message queues\n"
" Default is to display information about all queues on this node\n",
0,
rtems_monitor_object_cmd,
RTEMS_OBJECT_QUEUE,
},
{ "object",
"object [id [id ...] ]\n"
" display information about specified RTEMS objects.\n"
" Object id's must include 'type' information.\n"
" (which may normally be defaulted)\n",
0,
rtems_monitor_object_cmd,
RTEMS_OBJECT_INVALID,
},
{ "driver",
"driver [ major [ major ... ] ]\n"
" Display the RTEMS device driver table.\n",
0,
rtems_monitor_object_cmd,
RTEMS_OBJECT_DRIVER,
},
{ "dname",
"dname\n"
" Displays information about named drivers.\n",
0,
rtems_monitor_object_cmd,
RTEMS_OBJECT_DNAME,
},
{ "exit",
"exit [status]\n"
" Invoke 'rtems_fatal_error_occurred' with 'status'\n"
" (default is RTEMS_SUCCESSFUL)\n",
0,
rtems_monitor_fatal_cmd,
RTEMS_SUCCESSFUL,
},
{ "fatal",
"fatal [status]\n"
" 'exit' with fatal error; default error is RTEMS_TASK_EXITTED\n",
0,
rtems_monitor_fatal_cmd,
RTEMS_TASK_EXITTED, /* exit value */
},
{ "quit",
"quit [status]\n"
" Alias for 'exit'\n",
0,
rtems_monitor_fatal_cmd,
RTEMS_SUCCESSFUL, /* exit value */
},
{ "help",
"help [ command [ command ] ]\n"
" provide information about commands\n"
" Default is show basic command summary.\n",
0,
rtems_monitor_help_cmd,
(unsigned32) rtems_monitor_commands,
},
#ifdef CPU_INVOKE_DEBUGGER
{ "debugger",
"debugger\n"
" Enter the debugger, if possible.\n"
" A continue from the debugger will return to the monitor.\n",
0,
CPU_INVOKE_DEBUGGER,
0,
},
#endif
{ 0, 0, 0, 0, 0 },
};
#define MONITOR_WAKEUP_EVENT RTEMS_EVENT_0
/*
* Function: rtems_monitor_init
*
* Description:
* Create the RTEMS monitor task
*
* Parameters:
* 'monitor_suspend' arg is passed as initial arg to monitor task
* If TRUE, monitor will suspend itself as it starts up. Otherwise
* it will begin its command loop.
*
* Returns:
*
*
* Side Effects:
*
*
* Notes:
*
*
* Deficiencies/ToDo:
*
*
*/
/*
* make_argv(cp): token-count
* Break up the command line in 'cp' into global argv[] and argc (return
* value).
*/
int
rtems_monitor_make_argv(
char *cp,
int *argc_p,
char **argv)
{
int argc = 0;
while ((cp = strtok(cp, " \t\n\r")))
{
argv[argc++] = cp;
cp = (char *) NULL;
}
argv[argc] = (char *) NULL; /* end of argv */
return *argc_p = argc;
}
void
rtems_monitor_init(rtems_boolean monitor_suspend)
{
rtems_status_code status;
status = rtems_task_create(rtems_build_name('R', 'M', 'O', 'N'),
1, 0/*stack*/, RTEMS_NO_PREEMPT | RTEMS_INTERRUPT_LEVEL(0), RTEMS_DEFAULT_ATTRIBUTES, &rtems_monitor_task_id);
if (status != RTEMS_SUCCESSFUL)
{
printf("could not create monitor task\n");
goto done;
}
rtems_monitor_symbols_loadup();
status = rtems_task_start(rtems_monitor_task_id, rtems_monitor_task, monitor_suspend);
if (status != RTEMS_SUCCESSFUL)
{
printf("could not start monitor!\n");
goto done;
}
done:
}
rtems_status_code
rtems_monitor_suspend(rtems_interval timeout)
@@ -127,7 +241,10 @@ rtems_monitor_suspend(rtems_interval timeout)
rtems_event_set event_set;
rtems_status_code status;
status = rtems_event_receive(MONITOR_WAKEUP_EVENT, RTEMS_DEFAULT_OPTIONS, timeout, &event_set);
status = rtems_event_receive(MONITOR_WAKEUP_EVENT,
RTEMS_DEFAULT_OPTIONS,
timeout,
&event_set);
return status;
}
@@ -140,93 +257,76 @@ rtems_monitor_wakeup(void)
}
/*
* Read and break up a monitor command
*
* We have to loop on the gets call, since it will return NULL under UNIX
* RTEMS when we get a signal (eg: SIGALRM).
*/
int
rtems_monitor_read_command(char *command,
int *argc,
char **argv)
void
rtems_monitor_pause_cmd(
int argc,
char **argv,
unsigned32 command_arg,
boolean verbose
)
{
printf("%s", MONITOR_PROMPT); fflush(stdout);
while (gets(command) == (char *) 0)
;
return rtems_monitor_make_argv(command, argc, argv);
if (argc == 1)
rtems_monitor_suspend(1);
else
rtems_monitor_suspend(strtoul(argv[1], 0, 0));
}
void
rtems_monitor_task(rtems_task_argument monitor_suspend)
rtems_monitor_fatal_cmd(
int argc,
char **argv,
unsigned32 command_arg,
boolean verbose
)
{
rtems_tcb *debugee = 0;
char command[513];
rtems_context *rp;
rtems_context_fp *fp;
char *cp;
int argc;
char *argv[64];
if ((rtems_boolean) monitor_suspend)
(void) rtems_monitor_suspend(RTEMS_NO_TIMEOUT);
for (;;)
{
extern rtems_tcb * _Thread_Executing;
debugee = _Thread_Executing;
rp = &debugee->Registers;
fp = (rtems_context_fp *) debugee->fp_context; /* possibly 0 */
if (0 == rtems_monitor_read_command(command, &argc, argv))
continue;
if (STREQ(argv[0], "quit"))
rtems_monitor_suspend(RTEMS_NO_TIMEOUT);
else if (STREQ(argv[0], "pause"))
rtems_monitor_suspend(1);
#ifdef CPU_INVOKE_DEBUGGER
else if (STREQ(argv[0], "debug"))
{
CPU_INVOKE_DEBUGGER;
}
#endif
else if (STREQ(argv[0], "symbol"))
{
char *symbol;
char *value;
if (argc != 3)
{
printf("usage: symbol symname symvalue\n");
continue;
}
symbol = argv[1];
value = argv[2];
if (symbol && value)
{
rtems_symbol_t *sp;
sp = rtems_symbol_create(rtems_monitor_symbols,
symbol,
(rtems_unsigned32) strtoul(value, 0, 16));
if (sp)
printf("symbol defined is at %p\n", sp);
else
printf("could not define symbol\n");
}
else
printf("parsing error\n");
}
else
{
printf("Unrecognized command: '%s'\n", argv[0]);
}
}
if (argc == 1)
rtems_fatal_error_occurred(command_arg);
else
rtems_fatal_error_occurred(strtoul(argv[1], 0, 0));
}
void
rtems_monitor_continue_cmd(
int argc,
char **argv,
unsigned32 command_arg,
boolean verbose
)
{
rtems_monitor_suspend(RTEMS_NO_TIMEOUT);
}
void
rtems_monitor_node_cmd(
int argc,
char **argv,
unsigned32 command_arg,
boolean verbose
)
{
unsigned32 new_node = rtems_monitor_default_node;
switch (argc)
{
case 1: /* no node, just set back to ours */
new_node = rtems_monitor_node;
break;
case 2:
new_node = strtoul(argv[1], 0, 0);
break;
default:
printf("invalid syntax, try 'help node'\n");
break;
}
if ((new_node >= 1) && (new_node <= _Configuration_MP_table->maximum_nodes))
rtems_monitor_default_node = new_node;
}
/*
* Function: rtems_monitor_symbols_loadup
*
@@ -266,11 +366,19 @@ rtems_monitor_symbols_loadup(void)
FILE *fp;
char buffer[128];
if (rtems_monitor_symbols)
rtems_symbol_table_destroy(rtems_monitor_symbols);
rtems_monitor_symbols = rtems_symbol_table_create(10);
if (rtems_monitor_symbols == 0)
return;
fp = fdopen(8, "r");
#ifdef simhppa
fp = fdopen(8, "r"); /* don't ask; don't tell */
#else
fp = fopen("symbols", "r");
#endif
if (fp == 0)
return;
@@ -292,16 +400,115 @@ rtems_monitor_symbols_loadup(void)
(rtems_unsigned32) strtoul(value, 0, 16));
if (sp == 0)
{
printf("could not define symbol\n");
printf("could not define symbol '%s'\n", symbol);
goto done;
}
}
else
{
printf("parsing error\n");
printf("parsing error on '%s'\n", buffer);
goto done;
}
}
done:
}
/*
* Main monitor command loop
*/
void
rtems_monitor_task(
rtems_task_argument monitor_flags
)
{
rtems_tcb *debugee = 0;
rtems_context *rp;
rtems_context_fp *fp;
char command_buffer[513];
int argc;
char *argv[64];
boolean verbose = FALSE;
if (monitor_flags & RTEMS_MONITOR_SUSPEND)
(void) rtems_monitor_suspend(RTEMS_NO_TIMEOUT);
for (;;)
{
extern rtems_tcb * _Thread_Executing;
rtems_monitor_command_entry_t *command;
debugee = _Thread_Executing;
rp = &debugee->Registers;
fp = (rtems_context_fp *) debugee->fp_context; /* possibly 0 */
if (0 == rtems_monitor_command_read(command_buffer, &argc, argv))
continue;
if ((command = rtems_monitor_command_lookup(rtems_monitor_commands,
argc,
argv)) == 0)
continue;
command->command_function(argc, argv, command->command_arg, verbose);
fflush(stdout);
}
}
void
rtems_monitor_kill(void)
{
if (rtems_monitor_task_id)
rtems_task_delete(rtems_monitor_task_id);
rtems_monitor_task_id = 0;
rtems_monitor_server_kill();
}
void
rtems_monitor_init(
unsigned32 monitor_flags
)
{
rtems_status_code status;
rtems_monitor_kill();
status = rtems_task_create(RTEMS_MONITOR_NAME,
1,
0 /* default stack */,
RTEMS_INTERRUPT_LEVEL(0),
RTEMS_DEFAULT_ATTRIBUTES,
&rtems_monitor_task_id);
if (status != RTEMS_SUCCESSFUL)
{
rtems_error(status, "could not create monitor task");
goto done;
}
rtems_monitor_node = rtems_get_node(rtems_monitor_task_id);
rtems_monitor_default_node = rtems_monitor_node;
rtems_monitor_symbols_loadup();
if (monitor_flags & RTEMS_MONITOR_GLOBAL)
rtems_monitor_server_init(monitor_flags);
/*
* Start the monitor task itself
*/
status = rtems_task_start(rtems_monitor_task_id,
rtems_monitor_task,
monitor_flags);
if (status != RTEMS_SUCCESSFUL)
{
rtems_error(status, "could not start monitor");
goto done;
}
done:
}

View File

@@ -0,0 +1,161 @@
/*
* @(#)mpci.c 1.6 - 95/08/02
*
*
* RTEMS MPCI Config display support
*
* TODO
*
* $Id$
*/
#include <rtems.h>
#include "monitor.h"
#include <stdio.h>
#include <stdlib.h> /* strtoul() */
#define DATACOL 15
/*
* Fill in entire monitor config table
* for sending to a remote monitor or printing on the local system
*/
void
rtems_monitor_mpci_canonical(
rtems_monitor_mpci_t *canonical_mpci,
void *config_void
)
{
rtems_configuration_table *c = _Configuration_Table;
rtems_multiprocessing_table *m;
rtems_mpci_table *mt;
m = c->User_multiprocessing_table;
if (m == 0)
return;
mt = m->User_mpci_table;
canonical_mpci->node = m->node;
canonical_mpci->maximum_nodes = m->maximum_nodes;
canonical_mpci->maximum_global_objects = m->maximum_global_objects;
canonical_mpci->maximum_proxies = m->maximum_proxies;
canonical_mpci->default_timeout = mt->default_timeout;
canonical_mpci->maximum_packet_size = mt->maximum_packet_size;
rtems_monitor_symbol_canonical_by_value(&canonical_mpci->initialization,
mt->initialization);
rtems_monitor_symbol_canonical_by_value(&canonical_mpci->get_packet,
mt->get_packet);
rtems_monitor_symbol_canonical_by_value(&canonical_mpci->return_packet,
mt->return_packet);
rtems_monitor_symbol_canonical_by_value(&canonical_mpci->send_packet,
mt->send_packet);
rtems_monitor_symbol_canonical_by_value(&canonical_mpci->receive_packet,
mt->receive_packet);
}
/*
* This is easy, since there is only 1 (altho we could get them from
* other nodes...)
*/
void *
rtems_monitor_mpci_next(
void *object_info,
rtems_monitor_mpci_t *canonical_mpci,
rtems_id *next_id
)
{
rtems_configuration_table *c = _Configuration_Table;
int n = rtems_get_index(*next_id);
if (n >= 1)
goto failed;
if ( ! c->User_multiprocessing_table)
goto failed;
_Thread_Disable_dispatch();
*next_id += 1;
return (void *) c;
failed:
*next_id = RTEMS_OBJECT_ID_FINAL;
return 0;
}
void
rtems_monitor_mpci_dump_header(
boolean verbose
)
{
printf("\
max max max default max\n\
node nodes globals proxies timeout pktsize\n");
/*23456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789
0 1 2 3 4 5 6 7 */
rtems_monitor_separator();
}
void
rtems_monitor_mpci_dump(
rtems_monitor_mpci_t *monitor_mpci,
boolean verbose
)
{
unsigned32 length = 0;
length += rtems_monitor_pad(2, length);
length += printf(" %d", monitor_mpci->node);
length += rtems_monitor_pad(11, length);
length += printf("%d", monitor_mpci->maximum_nodes);
length += rtems_monitor_pad(18, length);
length += rtems_monitor_dump_decimal(monitor_mpci->maximum_global_objects);
length += rtems_monitor_pad(28, length);
length += rtems_monitor_dump_decimal(monitor_mpci->maximum_proxies);
length += rtems_monitor_pad(37, length);
length += rtems_monitor_dump_decimal(monitor_mpci->default_timeout);
length += rtems_monitor_pad(46, length);
length += rtems_monitor_dump_decimal(monitor_mpci->maximum_packet_size);
printf("\n");
length = 0;
length += rtems_monitor_pad(DATACOL, length);
length += printf("init: ");
length += rtems_monitor_symbol_dump(&monitor_mpci->initialization, verbose);
printf("\n");
length = 0;
length += rtems_monitor_pad(DATACOL, length);
length += printf("get: ");
length += rtems_monitor_symbol_dump(&monitor_mpci->get_packet, verbose);
length += printf("; return: ");
length += rtems_monitor_symbol_dump(&monitor_mpci->return_packet, verbose);
printf("\n");
length = 0;
length += rtems_monitor_pad(DATACOL, length);
length += printf("send: ");
length += rtems_monitor_symbol_dump(&monitor_mpci->send_packet, verbose);
length += printf("; receive: ");
length += rtems_monitor_symbol_dump(&monitor_mpci->receive_packet, verbose);
printf("\n");
length = 0;
}

View File

@@ -0,0 +1,376 @@
/*
* @(#)object.c 1.7 - 95/08/02
*
*
* RTEMS Monitor "object" support.
*
* Used to traverse object lists and print them out.
* An object can be an RTEMS object (chain based stuff) or
* a "misc" object such as a device driver.
*
* Each object has its own file in this directory (eg: extension.c)
* That file provides routines to convert a "native" structure
* to its canonical form, print a canonical structure, etc.
*
* TODO:
* should allow for non-numeric id's???
*
* $Id$
*/
#include <rtems.h>
#include "monitor.h"
#include <stdio.h>
#include <stdlib.h> /* strtoul() */
#include <monitor.h>
#define NUMELEMS(arr) (sizeof(arr) / sizeof(arr[0]))
/*
* add:
* next
*/
rtems_monitor_object_info_t rtems_monitor_object_info[] =
{
{ RTEMS_OBJECT_CONFIG,
(void *) 0,
sizeof(rtems_monitor_config_t),
(rtems_monitor_object_next_fn) rtems_monitor_config_next,
(rtems_monitor_object_canonical_fn) rtems_monitor_config_canonical,
(rtems_monitor_object_dump_header_fn) rtems_monitor_config_dump_header,
(rtems_monitor_object_dump_fn) rtems_monitor_config_dump,
},
{ RTEMS_OBJECT_MPCI,
(void *) 0,
sizeof(rtems_monitor_mpci_t),
(rtems_monitor_object_next_fn) rtems_monitor_mpci_next,
(rtems_monitor_object_canonical_fn) rtems_monitor_mpci_canonical,
(rtems_monitor_object_dump_header_fn) rtems_monitor_mpci_dump_header,
(rtems_monitor_object_dump_fn) rtems_monitor_mpci_dump,
},
{ RTEMS_OBJECT_INIT_TASK,
(void *) 0,
sizeof(rtems_monitor_init_task_t),
(rtems_monitor_object_next_fn) rtems_monitor_init_task_next,
(rtems_monitor_object_canonical_fn) rtems_monitor_init_task_canonical,
(rtems_monitor_object_dump_header_fn) rtems_monitor_init_task_dump_header,
(rtems_monitor_object_dump_fn) rtems_monitor_init_task_dump,
},
{ RTEMS_OBJECT_TASK,
(void *) &_Thread_Information,
sizeof(rtems_monitor_task_t),
(rtems_monitor_object_next_fn) rtems_monitor_manager_next,
(rtems_monitor_object_canonical_fn) rtems_monitor_task_canonical,
(rtems_monitor_object_dump_header_fn) rtems_monitor_task_dump_header,
(rtems_monitor_object_dump_fn) rtems_monitor_task_dump,
},
{ RTEMS_OBJECT_QUEUE,
(void *) &_Message_queue_Information,
sizeof(rtems_monitor_queue_t),
(rtems_monitor_object_next_fn) rtems_monitor_manager_next,
(rtems_monitor_object_canonical_fn) rtems_monitor_queue_canonical,
(rtems_monitor_object_dump_header_fn) rtems_monitor_queue_dump_header,
(rtems_monitor_object_dump_fn) rtems_monitor_queue_dump,
},
{ RTEMS_OBJECT_EXTENSION,
(void *) &_Extension_Information,
sizeof(rtems_monitor_extension_t),
(rtems_monitor_object_next_fn) rtems_monitor_manager_next,
(rtems_monitor_object_canonical_fn) rtems_monitor_extension_canonical,
(rtems_monitor_object_dump_header_fn) rtems_monitor_extension_dump_header,
(rtems_monitor_object_dump_fn) rtems_monitor_extension_dump,
},
{ RTEMS_OBJECT_DRIVER,
(void *) 0,
sizeof(rtems_monitor_driver_t),
(rtems_monitor_object_next_fn) rtems_monitor_driver_next,
(rtems_monitor_object_canonical_fn) rtems_monitor_driver_canonical,
(rtems_monitor_object_dump_header_fn) rtems_monitor_driver_dump_header,
(rtems_monitor_object_dump_fn) rtems_monitor_driver_dump,
},
{ RTEMS_OBJECT_DNAME,
(void *) &rtems_driver_name_table[0],
sizeof(rtems_monitor_dname_t),
(rtems_monitor_object_next_fn) rtems_monitor_dname_next,
(rtems_monitor_object_canonical_fn) rtems_monitor_dname_canonical,
(rtems_monitor_object_dump_header_fn) rtems_monitor_dname_dump_header,
(rtems_monitor_object_dump_fn) rtems_monitor_dname_dump,
},
};
/*
* Allow id's to be specified without the node number or
* type for convenience.
*/
rtems_id
rtems_monitor_id_fixup(
rtems_id id,
unsigned32 default_node,
rtems_object_type_t type
)
{
unsigned32 node;
node = rtems_get_node(id);
if (node == 0)
{
#if 0
/* XXX Uncomment this when types are added to id's */
if (rtems_get_type(id) != RTEMS_OBJECT_INVALID)
type = rtems_get_type(id);
id = _Objects_Build_id(type, default_node, rtems_get_index(id));
#else
id = _Objects_Build_id(default_node, rtems_get_index(id));
#endif
}
return id;
}
rtems_monitor_object_info_t *
rtems_monitor_object_lookup(
rtems_object_type_t type
)
{
rtems_monitor_object_info_t *p;
for (p = &rtems_monitor_object_info[0];
p < &rtems_monitor_object_info[NUMELEMS(rtems_monitor_object_info)];
p++)
{
if (p->type == type)
return p;
}
return 0;
}
rtems_id
rtems_monitor_object_canonical_next_remote(
rtems_object_type_t type,
rtems_id id,
void *canonical
)
{
rtems_id next_id;
rtems_status_code status;
rtems_monitor_server_request_t request;
rtems_monitor_server_response_t response;
/*
* Send request
*/
request.command = RTEMS_MONITOR_SERVER_CANONICAL;
request.argument0 = (unsigned32) type;
request.argument1 = (unsigned32) id;
status = rtems_monitor_server_request(rtems_get_node(id), &request, &response);
if (status != RTEMS_SUCCESSFUL)
goto failed;
/*
* process response
*/
next_id = (rtems_id) response.result0;
if (next_id != RTEMS_OBJECT_ID_FINAL)
(void) memcpy(canonical, &response.payload, response.result1);
return next_id;
failed:
return RTEMS_OBJECT_ID_FINAL;
}
rtems_id
rtems_monitor_object_canonical_next(
rtems_monitor_object_info_t *info,
rtems_id id,
void *canonical
)
{
rtems_id next_id;
void *raw_item;
if ( ! _Objects_Is_local_id(id))
next_id = rtems_monitor_object_canonical_next_remote(info->type,
id,
canonical);
else
{
next_id = id;
raw_item = (void *) info->next(info->object_information,
canonical,
&next_id);
if (raw_item)
{
info->canonical(canonical, raw_item);
_Thread_Enable_dispatch();
}
}
return next_id;
}
/*
* this is routine server invokes locally to get the type
*/
rtems_id
rtems_monitor_object_canonical_get(
rtems_object_type_t type,
rtems_id id,
void *canonical,
unsigned32 *size_p
)
{
rtems_monitor_object_info_t *info;
rtems_id next_id;
*size_p = 0;
info = rtems_monitor_object_lookup(type);
if (info == 0)
return RTEMS_OBJECT_ID_FINAL;
next_id = rtems_monitor_object_canonical_next(info, id, canonical);
*size_p = info->size;
return next_id;
}
void
rtems_monitor_object_dump_1(
rtems_monitor_object_info_t *info,
rtems_id id,
boolean verbose
)
{
rtems_id next_id;
rtems_monitor_union_t canonical;
if ((next_id = rtems_monitor_object_canonical_next(
info,
id,
&canonical)) != RTEMS_OBJECT_ID_FINAL)
{
/*
* If the one we actually got is the one we wanted, then
* print it out.
* For ones that have an id field, this works fine,
* for all others, always dump it out.
*
* HACK: the way we determine whether there is an id is a hack.
*
* by the way: the reason we try to not have an id, is that some
* of the canonical structures are almost too big for shared
* memory driver (eg: mpci)
*/
if ((info->next != rtems_monitor_manager_next) ||
(id == canonical.generic.id))
info->dump(&canonical, verbose);
}
}
void
rtems_monitor_object_dump_all(
rtems_monitor_object_info_t *info,
boolean verbose
)
{
rtems_id next_id;
rtems_monitor_union_t canonical;
next_id = RTEMS_OBJECT_ID_INITIAL(rtems_monitor_default_node);
while ((next_id = rtems_monitor_object_canonical_next(
info,
next_id,
&canonical)) != RTEMS_OBJECT_ID_FINAL)
{
info->dump(&canonical, verbose);
}
}
void
rtems_monitor_object_cmd(
int argc,
char **argv,
unsigned32 command_arg,
boolean verbose
)
{
int arg;
rtems_monitor_object_info_t *info = 0;
rtems_object_type_t type = (rtems_object_type_t) command_arg;
/* what is the default type? */
type = (rtems_object_type_t) command_arg;
if (argc == 1)
{
if (type == RTEMS_OBJECT_INVALID)
{
printf("A type must be specified to \"dump all\"\n");
goto done;
}
info = rtems_monitor_object_lookup(type);
if (info == 0)
goto not_found;
if (info->dump_header)
info->dump_header(verbose);
rtems_monitor_object_dump_all(info, verbose);
}
else
{
unsigned32 default_node = rtems_monitor_default_node;
rtems_object_type_t last_type = RTEMS_OBJECT_INVALID;
rtems_id id;
for (arg=1; argv[arg]; arg++)
{
id = (rtems_id) strtoul(argv[arg], 0, 0);
id = rtems_monitor_id_fixup(id, default_node, type);
#if 0
type = rtems_get_type(id);
#endif
/*
* Allow the item type to change in the middle
* of the command. If the type changes, then
* just dump out a new header and keep on going.
*/
if (type != last_type)
{
info = rtems_monitor_object_lookup(type);
if (info == 0)
{
not_found: printf("Invalid or unsupported type %d\n", type);
goto done;
}
if (info->dump_header)
info->dump_header(verbose);
}
rtems_monitor_object_dump_1(info, id, verbose);
default_node = rtems_get_node(id);
last_type = type;
}
}
done:
}

View File

@@ -0,0 +1,257 @@
/*
* @(#)prmisc.c 1.9 - 95/08/02
*
*
* Print misc stuff for the monitor dump routines
* Each routine returns the number of characters it output.
*
* TODO:
*
* $Id$
*/
#include <rtems.h>
#include "monitor.h"
#include <rtems/assoc.h>
#include <stdio.h>
#include <ctype.h>
void
rtems_monitor_separator(void)
{
printf("------------------------------------------------------------------------------\n");
}
unsigned32
rtems_monitor_pad(
unsigned32 destination_column,
unsigned32 current_column
)
{
int pad_length;
if (destination_column <= current_column)
pad_length = 1;
else
pad_length = destination_column - current_column;
return printf("%*s", pad_length, "");
}
unsigned32
rtems_monitor_dump_char(rtems_unsigned8 ch)
{
if (isprint(ch))
return printf("%c", ch);
else
return printf("%02x", ch);
}
unsigned32
rtems_monitor_dump_decimal(unsigned32 num)
{
return printf("%4d", num);
}
unsigned32
rtems_monitor_dump_hex(unsigned32 num)
{
return printf("0x%x", num);
}
unsigned32
rtems_monitor_dump_assoc_bitfield(
rtems_assoc_t *ap,
char *separator,
unsigned32 value
)
{
unsigned32 b;
unsigned32 length = 0;
char *name;
for (b = 1; b; b <<= 1)
if (b & value)
{
if (length)
length += printf("%s", separator);
name = rtems_assoc_name_by_local(ap, b);
if (name)
length += printf("%s", name);
else
length += printf("0x%x", b);
}
return length;
}
unsigned32
rtems_monitor_dump_id(rtems_id id)
{
return printf("%08x", id);
}
unsigned32
rtems_monitor_dump_name(rtems_name name)
{
int i;
unsigned32 length = 0;
union {
unsigned32 ui;
char c[4];
} u;
u.ui = (rtems_unsigned32) name;
for (i=0; i<sizeof(u.c); i++)
length += rtems_monitor_dump_char(u.c[i]);
return length;
}
unsigned32
rtems_monitor_dump_priority(rtems_task_priority priority)
{
return printf("%3d", priority);
}
rtems_assoc_t rtems_monitor_state_assoc[] = {
{ "DORM", STATES_DORMANT },
{ "SUSP", STATES_SUSPENDED },
{ "TRANS", STATES_TRANSIENT },
{ "DELAY", STATES_DELAYING },
{ "Wbuf", STATES_WAITING_FOR_BUFFER },
{ "Wseg", STATES_WAITING_FOR_SEGMENT },
{ "Wmsg" , STATES_WAITING_FOR_MESSAGE },
{ "Wevnt", STATES_WAITING_FOR_EVENT },
{ "Wsem", STATES_WAITING_FOR_SEMAPHORE },
{ "Wtime", STATES_WAITING_FOR_TIME },
{ "Wrpc", STATES_WAITING_FOR_RPC_REPLY },
{ "WRATE", STATES_WAITING_FOR_PERIOD },
{ 0, 0, 0 },
};
unsigned32
rtems_monitor_dump_state(States_Control state)
{
unsigned32 length = 0;
if (state == STATES_READY) /* assoc doesn't deal with this as it is 0 */
length += printf("READY");
length += rtems_monitor_dump_assoc_bitfield(rtems_monitor_state_assoc,
":",
state);
return length;
}
rtems_assoc_t rtems_monitor_attribute_assoc[] = {
{ "FL", RTEMS_FLOATING_POINT },
{ "GL", RTEMS_GLOBAL },
{ "PR", RTEMS_PRIORITY },
{ "BI", RTEMS_BINARY_SEMAPHORE },
{ "IN", RTEMS_INHERIT_PRIORITY },
{ 0, 0, 0 },
};
unsigned32
rtems_monitor_dump_attributes(rtems_attribute attributes)
{
unsigned32 length = 0;
if (attributes == RTEMS_DEFAULT_ATTRIBUTES) /* value is 0 */
length += printf("DEFAULT");
length += rtems_monitor_dump_assoc_bitfield(rtems_monitor_attribute_assoc,
":",
attributes);
return length;
}
rtems_assoc_t rtems_monitor_modes_assoc[] = {
{ "nP", RTEMS_NO_PREEMPT },
{ "T", RTEMS_TIMESLICE },
{ "nA", RTEMS_NO_ASR },
{ 0, 0, 0 },
};
unsigned32
rtems_monitor_dump_modes(rtems_mode modes)
{
unsigned32 length = 0;
if (modes == RTEMS_DEFAULT_MODES) /* value is 0 */
length += printf("P:T:nA");
length += rtems_monitor_dump_assoc_bitfield(rtems_monitor_modes_assoc,
":",
modes);
return length;
}
rtems_assoc_t rtems_monitor_events_assoc[] = {
{ "0", RTEMS_EVENT_0 },
{ "1", RTEMS_EVENT_1 },
{ "2", RTEMS_EVENT_2 },
{ "3", RTEMS_EVENT_3 },
{ "4", RTEMS_EVENT_4 },
{ "5", RTEMS_EVENT_5 },
{ "6", RTEMS_EVENT_6 },
{ "7", RTEMS_EVENT_7 },
{ "8", RTEMS_EVENT_8 },
{ "9", RTEMS_EVENT_9 },
{ "10", RTEMS_EVENT_10 },
{ "11", RTEMS_EVENT_11 },
{ "12", RTEMS_EVENT_12 },
{ "13", RTEMS_EVENT_13 },
{ "14", RTEMS_EVENT_14 },
{ "15", RTEMS_EVENT_15 },
{ "16", RTEMS_EVENT_16 },
{ "17", RTEMS_EVENT_17 },
{ "18", RTEMS_EVENT_18 },
{ "19", RTEMS_EVENT_19 },
{ "20", RTEMS_EVENT_20 },
{ "21", RTEMS_EVENT_21 },
{ "22", RTEMS_EVENT_22 },
{ "23", RTEMS_EVENT_23 },
{ "24", RTEMS_EVENT_24 },
{ "25", RTEMS_EVENT_25 },
{ "26", RTEMS_EVENT_26 },
{ "27", RTEMS_EVENT_27 },
{ "28", RTEMS_EVENT_28 },
{ "29", RTEMS_EVENT_29 },
{ "30", RTEMS_EVENT_30 },
{ "31", RTEMS_EVENT_31 },
{ 0, 0, 0 },
};
unsigned32
rtems_monitor_dump_events(rtems_event_set events)
{
unsigned32 length = 0;
if (events == EVENT_SETS_NONE_PENDING) /* value is 0 */
length += printf("NONE");
length += rtems_monitor_dump_assoc_bitfield(rtems_monitor_events_assoc,
":",
events);
return length;
}
unsigned32
rtems_monitor_dump_notepad(unsigned32 *notepad)
{
unsigned32 length = 0;
int i;
for (i=0; i < RTEMS_NUMBER_NOTEPADS; i++)
if (notepad[i])
length += printf("%d: 0x%x ", i, notepad[i]);
return length;
}

View File

@@ -0,0 +1,66 @@
/*
* @(#)queue.c 1.5 - 95/07/31
*
* $Id$
*/
#include <rtems.h>
#include "monitor.h"
#include <stdio.h>
void
rtems_monitor_queue_canonical(
rtems_monitor_queue_t *canonical_queue,
void *queue_void
)
{
Message_queue_Control *rtems_queue = (Message_queue_Control *) queue_void;
canonical_queue->attributes = rtems_queue->attribute_set;
canonical_queue->maximum_message_size = rtems_queue->maximum_message_size;
canonical_queue->maximum_pending_messages = rtems_queue->maximum_pending_messages;
canonical_queue->number_of_pending_messages = rtems_queue->number_of_pending_messages;
}
void
rtems_monitor_queue_dump_header(
boolean verbose
)
{
printf("\
ID NAME ATTRIBUTES PEND MAXPEND MAXSIZE\n");
/*23456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789
0 1 2 3 4 5 6 7 */
rtems_monitor_separator();
}
/*
* Dump out the "next" queue indicated by 'id'.
* Returns next one to check.
* Returns RTEMS_OBJECT_ID_FINAL when all done
*/
void
rtems_monitor_queue_dump(
rtems_monitor_queue_t *monitor_queue,
boolean verbose
)
{
unsigned32 length = 0;
length += rtems_monitor_dump_id(monitor_queue->id);
length += rtems_monitor_pad(11, length);
length += rtems_monitor_dump_name(monitor_queue->name);
length += rtems_monitor_pad(19, length);
length += rtems_monitor_dump_attributes(monitor_queue->attributes);
length += rtems_monitor_pad(31, length);
length += rtems_monitor_dump_decimal(monitor_queue->number_of_pending_messages);
length += rtems_monitor_pad(39, length);
length += rtems_monitor_dump_decimal(monitor_queue->maximum_pending_messages);
length += rtems_monitor_pad(48, length);
length += rtems_monitor_dump_decimal(monitor_queue->maximum_message_size);
printf("\n");
}

View File

@@ -0,0 +1,305 @@
/*
* @(#)server.c 1.3 - 95/08/02
*
*
* RTEMS monitor server (handles requests for info from RTEMS monitors
* running on other nodes)
*
* $Id$
*/
#include <rtems.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include "monitor.h"
/*
* Various id's for the server
*/
rtems_id rtems_monitor_server_task_id;
rtems_id rtems_monitor_server_request_queue_id; /* our server */
rtems_id *rtems_monitor_server_request_queue_ids; /* all servers */
rtems_id rtems_monitor_server_response_queue_id; /* our server */
/*
* Send a request to a server task
*/
rtems_status_code
rtems_monitor_server_request(
unsigned32 server_node,
rtems_monitor_server_request_t *request,
rtems_monitor_server_response_t *response
)
{
rtems_id server_id;
rtems_status_code status;
unsigned32 size;
/*
* What is id of monitor on target node?
* Look it up if we don't know it yet.
*/
server_id = rtems_monitor_server_request_queue_ids[server_node];
if (server_id == 0)
{
status = rtems_message_queue_ident(RTEMS_MONITOR_QUEUE_NAME,
server_node,
&server_id);
if (status != RTEMS_SUCCESSFUL)
{
rtems_error(status, "ident of remote server failed");
goto done;
}
rtems_monitor_server_request_queue_ids[server_node] = server_id;
}
request->return_id = rtems_monitor_server_response_queue_id;
status = rtems_message_queue_send(server_id, request, sizeof(*request));
if (status != RTEMS_SUCCESSFUL)
{
rtems_error(status, "monitor server request send failed");
goto done;
}
/*
* Await response, if requested
*/
if (response)
{
status = rtems_message_queue_receive(rtems_monitor_server_response_queue_id,
response,
&size,
RTEMS_WAIT,
100);
if (status != RTEMS_SUCCESSFUL)
{
rtems_error(status, "server did not respond");
/* maybe server task was restarted; look it up again next time */
rtems_monitor_server_request_queue_ids[server_node] = 0;
goto done;
}
if (response->command != RTEMS_MONITOR_SERVER_RESPONSE)
{
status = RTEMS_INCORRECT_STATE;
goto done;
}
}
done:
return status;
}
/*
* monitor server task
*/
void
rtems_monitor_server_task(
rtems_task_argument monitor_flags
)
{
rtems_monitor_server_request_t request;
rtems_monitor_server_response_t response;
rtems_status_code status;
unsigned32 size;
for (;;)
{
status = rtems_message_queue_receive(
rtems_monitor_server_request_queue_id,
&request,
&size,
RTEMS_WAIT,
(rtems_interval) 0);
if (status != RTEMS_SUCCESSFUL)
{
rtems_error(status, "monitor server msg queue receive error");
goto failed;
}
if (size != sizeof(request))
{
rtems_error(0, "monitor server bad size on receive");
goto failed;
}
switch (request.command)
{
case RTEMS_MONITOR_SERVER_CANONICAL:
{
rtems_object_type_t object_type;
rtems_id id;
rtems_id next_id;
object_type = (rtems_object_type_t) request.argument0;
id = (rtems_id) request.argument1;
next_id = rtems_monitor_object_canonical_get(object_type,
id,
&response.payload,
&size);
response.command = RTEMS_MONITOR_SERVER_RESPONSE;
response.result0 = next_id;
response.result1 = size;
#define SERVER_OVERHEAD (RTEMS_offsetof(rtems_monitor_server_response_t, \
payload))
status = rtems_message_queue_send(request.return_id,
&response,
size + SERVER_OVERHEAD);
if (status != RTEMS_SUCCESSFUL)
{
rtems_error(status, "response send failed");
goto failed;
}
break;
}
default:
{
rtems_error(0, "invalid command to monitor server: %d", request.command);
goto failed;
}
}
}
failed:
rtems_task_delete(RTEMS_SELF);
}
/*
* Kill off any old server
* Not sure if this is useful, but it doesn't help
*/
void
rtems_monitor_server_kill(void)
{
if (rtems_monitor_server_task_id)
rtems_task_delete(rtems_monitor_server_task_id);
rtems_monitor_task_id = 0;
if (rtems_monitor_server_request_queue_id)
rtems_message_queue_delete(rtems_monitor_server_request_queue_id);
rtems_monitor_server_response_queue_id = 0;
if (rtems_monitor_server_response_queue_id)
rtems_message_queue_delete(rtems_monitor_server_response_queue_id);
rtems_monitor_server_request_queue_ids = 0;
if (rtems_monitor_server_request_queue_ids)
free(rtems_monitor_server_request_queue_ids);
rtems_monitor_server_request_queue_ids = 0;
}
void
rtems_monitor_server_init(
unsigned32 monitor_flags
)
{
rtems_status_code status;
if (_Configuration_Is_multiprocessing() &&
(_Configuration_MP_table->maximum_nodes > 1))
{
unsigned32 maximum_nodes = _Configuration_MP_table->maximum_nodes;
/*
* create the msg que our server will listen
* Since we only get msgs from other RTEMS monitors, we just
* need reserve space for 1 msg from each node.
*/
status = rtems_message_queue_create(
RTEMS_MONITOR_QUEUE_NAME,
maximum_nodes,
sizeof(rtems_monitor_server_request_t),
RTEMS_GLOBAL,
&rtems_monitor_server_request_queue_id);
if (status != RTEMS_SUCCESSFUL)
{
rtems_error(status, "could not create monitor server message queue");
goto done;
}
/*
* create the msg que our responses will come on
* Since monitor just does one thing at a time, we only need 1 item
* message queue.
*/
status = rtems_message_queue_create(
RTEMS_MONITOR_RESPONSE_QUEUE_NAME,
1, /* depth */
sizeof(rtems_monitor_server_response_t),
RTEMS_GLOBAL,
&rtems_monitor_server_response_queue_id);
if (status != RTEMS_SUCCESSFUL)
{
rtems_error(status, "could not create monitor response message queue");
goto done;
}
/* need an id for queue of each other server we might talk to */
/* indexed by node, so add 1 to maximum_nodes */
rtems_monitor_server_request_queue_ids =
(rtems_id *) malloc((maximum_nodes + 1) * sizeof(rtems_id));
(void) memset(rtems_monitor_server_request_queue_ids,
0,
(maximum_nodes + 1) * sizeof(rtems_id));
rtems_monitor_server_request_queue_ids[rtems_monitor_node] =
rtems_monitor_server_request_queue_id;
/*
* create the server task
*/
status = rtems_task_create(RTEMS_MONITOR_SERVER_NAME,
1,
0 /* default stack */,
RTEMS_INTERRUPT_LEVEL(0),
RTEMS_DEFAULT_ATTRIBUTES,
&rtems_monitor_server_task_id);
if (status != RTEMS_SUCCESSFUL)
{
rtems_error(status, "could not create monitor server task");
goto done;
}
/*
* Start the server task
*/
status = rtems_task_start(rtems_monitor_server_task_id,
rtems_monitor_server_task,
monitor_flags);
if (status != RTEMS_SUCCESSFUL)
{
rtems_error(status, "could not start monitor server");
goto done;
}
}
done:
}

View File

@@ -1,6 +1,7 @@
/*
* @(#)symbols.c 1.3 - 95/04/24
* @(#)symbols.c 1.10 - 95/08/02
*
* $Id$
*/
/* #define qsort _quicksort */
@@ -21,34 +22,9 @@
#include <stdlib.h>
#include <string.h>
#include "monitor.h"
#include "symbols.h"
extern rtems_symbol_table_t *rtems_monitor_symbols;
#ifdef RTEMS_DEBUG
#define CHK_ADR_PTR(p) \
do { \
if (((p) < rtems_monitor_symbols->addresses) || \
((p) >= (rtems_monitor_symbols->addresses + rtems_monitor_symbols->next))) \
{ \
printf("bad address pointer %p\n", (p)); \
rtems_fatal_error_occurred(RTEMS_INVALID_ADDRESS); \
} \
} while (0)
#define CHK_NAME_PTR(p) \
do { \
if (((p) < rtems_monitor_symbols->symbols) || \
((p) >= (rtems_monitor_symbols->symbols + rtems_monitor_symbols->next))) \
{ \
printf("bad symbol pointer %p\n", (p)); \
rtems_fatal_error_occurred(RTEMS_INVALID_ADDRESS); \
} \
} while (0)
#else
#define CHK_ADR_PTR(p)
#define CHK_NAME_PTR(p)
#endif
rtems_symbol_table_t *
rtems_symbol_table_create()
@@ -178,9 +154,6 @@ rtems_symbol_compare(const void *e1,
s1 = (rtems_symbol_t *) e1;
s2 = (rtems_symbol_t *) e2;
CHK_ADR_PTR(s1);
CHK_ADR_PTR(s2);
if (s1->value < s2->value)
return -1;
if (s1->value > s2->value)
@@ -200,9 +173,6 @@ rtems_symbol_string_compare(const void *e1,
s1 = (rtems_symbol_t *) e1;
s2 = (rtems_symbol_t *) e2;
CHK_NAME_PTR(s1);
CHK_NAME_PTR(s2);
return strcasecmp(s1->name, s2->name);
}
@@ -252,6 +222,9 @@ rtems_symbol_value_lookup(
rtems_unsigned32 best_distance = ~0;
rtems_unsigned32 elements;
if (table == 0)
table = rtems_monitor_symbols;
if ((table == 0) || (table->size == 0))
return 0;
@@ -300,13 +273,14 @@ rtems_symbol_name_lookup(
rtems_symbol_t *sp = 0;
rtems_symbol_t key;
if (table == 0)
table = rtems_monitor_symbols;
if ((table == 0) || (name == 0))
goto done;
if (table->sorted == 0)
{
rtems_symbol_sort(table);
}
/*
* dummy up one for bsearch()
@@ -325,3 +299,192 @@ done:
return sp;
}
void *
rtems_monitor_symbol_next(
void *object_info,
rtems_monitor_symbol_t *canonical,
rtems_id *next_id
)
{
rtems_symbol_table_t *table;
int n = rtems_get_index(*next_id);
table = *(rtems_symbol_table_t **) object_info;
if (table == 0)
goto failed;
if (n >= table->next)
goto failed;
/* NOTE: symbols do not have id and name fields */
if (table->sorted == 0)
rtems_symbol_sort(table);
_Thread_Disable_dispatch();
*next_id += 1;
return (void *) (table->symbols + n);
failed:
*next_id = RTEMS_OBJECT_ID_FINAL;
return 0;
}
void
rtems_monitor_symbol_canonical(
rtems_monitor_symbol_t *canonical_symbol,
rtems_symbol_t *sp
)
{
canonical_symbol->value = sp->value;
canonical_symbol->offset = 0;
strncpy(canonical_symbol->name, sp->name, sizeof(canonical_symbol->name));
}
void
rtems_monitor_symbol_canonical_by_name(
rtems_monitor_symbol_t *canonical_symbol,
char *name
)
{
rtems_symbol_t *sp;
sp = rtems_symbol_name_lookup(0, name);
canonical_symbol->value = sp ? sp->value : 0;
strncpy(canonical_symbol->name, name, sizeof(canonical_symbol->name));
canonical_symbol->offset = 0;
}
void
rtems_monitor_symbol_canonical_by_value(
rtems_monitor_symbol_t *canonical_symbol,
void *value_void_p
)
{
unsigned32 value = (unsigned32) value_void_p;
rtems_symbol_t *sp;
sp = rtems_symbol_value_lookup(0, value);
if (sp)
{
canonical_symbol->value = sp->value;
canonical_symbol->offset = value - sp->value;
strncpy(canonical_symbol->name, sp->name, sizeof(canonical_symbol->name));
}
else
{
canonical_symbol->value = value;
canonical_symbol->offset = 0;
canonical_symbol->name[0] = '\0';
}
}
unsigned32
rtems_monitor_symbol_dump(
rtems_monitor_symbol_t *canonical_symbol,
boolean verbose
)
{
unsigned32 length = 0;
/*
* print the name if it exists AND if value is non-zero
* Ie: don't print some garbage symbol for address 0
*/
if (canonical_symbol->name[0] && (canonical_symbol->value != 0))
{
if (canonical_symbol->offset == 0)
length += printf("%.*s",
sizeof(canonical_symbol->name),
canonical_symbol->name);
else
length += printf("<%.*s+0x%x>",
sizeof(canonical_symbol->name),
canonical_symbol->name,
canonical_symbol->offset);
if (verbose)
length += printf(" [0x%x]", canonical_symbol->value);
}
else
length += printf("[0x%x]", canonical_symbol->value);
return length;
}
void
rtems_monitor_symbol_dump_all(
rtems_symbol_table_t *table,
boolean verbose
)
{
int s;
rtems_symbol_t *sp;
if (table == 0)
{
table = rtems_monitor_symbols;
if (table == 0)
return;
}
if (table->sorted == 0)
rtems_symbol_sort(table);
for (s = 0, sp = table->symbols; s < table->next; s++, sp++)
{
rtems_monitor_symbol_t canonical_symbol;
rtems_monitor_symbol_canonical(&canonical_symbol, sp);
rtems_monitor_symbol_dump(&canonical_symbol, TRUE);
printf("\n");
}
}
/*
* 'symbol' command
*/
void
rtems_monitor_symbol_cmd(
int argc,
char **argv,
unsigned32 command_arg,
boolean verbose
)
{
int arg;
rtems_symbol_table_t *table;
table = *(rtems_symbol_table_t **) command_arg;
if (table == 0)
{
table = rtems_monitor_symbols;
if (table == 0)
return;
}
/*
* Use object command to dump out whole symbol table
*/
if (argc == 1)
rtems_monitor_symbol_dump_all(table, verbose);
else
{
rtems_monitor_symbol_t canonical_symbol;
for (arg=1; argv[arg]; arg++)
{
rtems_monitor_symbol_canonical_by_name(&canonical_symbol, argv[arg]);
rtems_monitor_symbol_dump(&canonical_symbol, verbose);
printf("\n");
}
}
}

View File

@@ -0,0 +1,85 @@
/*
* @(#)task.c 1.9 - 95/08/01
*
*
* RTEMS Monitor task support
*
* $Id$
*/
#include <rtems.h>
#include "monitor.h"
#include <stdio.h>
void
rtems_monitor_task_canonical(
rtems_monitor_task_t *canonical_task,
void *thread_void
)
{
Thread_Control *rtems_thread = (Thread_Control *) thread_void;
canonical_task->entry = rtems_thread->Start.entry_point;
canonical_task->argument = rtems_thread->Start.initial_argument;
canonical_task->stack = rtems_thread->Start.Initial_stack.area;
canonical_task->stack_size = rtems_thread->Start.Initial_stack.size;
canonical_task->priority = rtems_thread->current_priority;
canonical_task->state = rtems_thread->current_state;
canonical_task->wait_id = rtems_thread->Wait.id;
canonical_task->events = rtems_thread->pending_events;
canonical_task->modes = rtems_thread->current_modes;
canonical_task->attributes = rtems_thread->attribute_set;
(void) memcpy(canonical_task->notepad, rtems_thread->Notepads, sizeof(canonical_task->notepad));
(void) memcpy(&canonical_task->wait_args, &rtems_thread->Wait.Extra, sizeof(canonical_task->wait_args));
}
void
rtems_monitor_task_dump_header(
boolean verbose
)
{
printf("\
ID NAME PRIO STAT MODES EVENTS WAITID WAITARG NOTES\n");
/*23456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789
0 1 2 3 4 5 6 7 */
rtems_monitor_separator();
}
/*
*/
void
rtems_monitor_task_dump(
rtems_monitor_task_t *monitor_task,
boolean verbose
)
{
int length = 0;
length += rtems_monitor_dump_id(monitor_task->id);
length += rtems_monitor_pad(11, length);
length += rtems_monitor_dump_name(monitor_task->name);
length += rtems_monitor_pad(18, length);
length += rtems_monitor_dump_priority(monitor_task->priority);
length += rtems_monitor_pad(24, length);
length += rtems_monitor_dump_state(monitor_task->state);
length += rtems_monitor_pad(31, length);
length += rtems_monitor_dump_modes(monitor_task->modes);
length += rtems_monitor_pad(39, length);
length += rtems_monitor_dump_events(monitor_task->events);
if (monitor_task->wait_id)
{
length += rtems_monitor_pad(47, length);
length += rtems_monitor_dump_id(monitor_task->wait_id);
length += rtems_monitor_pad(57, length);
length += rtems_monitor_dump_hex(monitor_task->wait_args);
}
length += rtems_monitor_pad(65, length);
length += rtems_monitor_dump_notepad(monitor_task->notepad);
printf("\n");
}

View File

@@ -1,6 +1,7 @@
/*
* @(#)monitor.h 1.2 - 95/04/24
* @(#)monitor.h 1.14 - 95/08/02
*
* $Id$
*/
/*
@@ -9,28 +10,430 @@
* Description:
* The RTEMS monitor task include file.
*
*
*
* TODO:
*
*/
#ifndef __MONITOR_H
#define __MONITOR_H
#include "symbols.h"
#include <rtems/error.h> /* rtems_error() */
#ifdef __cplusplus
extern "C" {
#endif
void rtems_monitor_init(rtems_boolean monitor_suspend);
void rtems_monitor_wakeup(void);
void rtems_monitor_task(rtems_task_argument monitor_suspend);
void rtems_monitor_symbols_loadup(void);
/*
* XXX this should be in rtems proper when type becomes part of id
*/
typedef enum {
RTEMS_OBJECT_INVALID = 0,
RTEMS_OBJECT_TASK = 1,
RTEMS_OBJECT_EXTENSION = 2,
RTEMS_OBJECT_QUEUE = 3,
RTEMS_OBJECT_SEMAPHORE = 4,
RTEMS_OBJECT_DRIVER = 5,
RTEMS_OBJECT_DNAME = 6,
RTEMS_OBJECT_CONFIG = 7,
RTEMS_OBJECT_INIT_TASK = 8,
RTEMS_OBJECT_MPCI = 9,
RTEMS_OBJECT_PARTITION = 10,
RTEMS_OBJECT_REGION = 11,
RTEMS_OBJECT_PORT = 12,
RTEMS_OBJECT_SYMBOL = 13,
} rtems_object_type_t;
/*
* rtems_monitor_init() flags
*/
#define RTEMS_MONITOR_SUSPEND 0x0001 /* suspend monitor on startup */
#define RTEMS_MONITOR_GLOBAL 0x0002 /* monitor should be global */
/*
* Public interfaces for RTEMS data structures monitor is aware of.
* These are only used by the monitor.
*
* NOTE:
* All the canonical objects that correspond to RTEMS managed "objects"
* must have an identical first portion with 'id' and 'name' fields.
*
* Others do not have that restriction, even tho we would like them to.
* This is because some of the canonical structures are almost too big
* for shared memory driver (eg: mpci) and we are nickel and diming it.
*/
/*
* Type of a pointer that may be a symbol
*/
#define MONITOR_SYMBOL_LEN 20
typedef struct {
char name[MONITOR_SYMBOL_LEN];
unsigned32 value;
unsigned32 offset;
} rtems_monitor_symbol_t;
typedef struct {
rtems_id id;
rtems_name name;
/* end of common portion */
} rtems_monitor_generic_t;
/*
* Task
*/
typedef struct {
rtems_id id;
rtems_name name;
/* end of common portion */
Thread_Entry entry;
unsigned32 argument;
void *stack;
unsigned32 stack_size;
rtems_task_priority priority;
States_Control state;
rtems_event_set events;
rtems_mode modes;
rtems_attribute attributes;
unsigned32 notepad[RTEMS_NUMBER_NOTEPADS];
rtems_id wait_id;
unsigned32 wait_args;
} rtems_monitor_task_t;
/*
* Init task
*/
typedef struct {
rtems_id id; /* not really an id */
rtems_name name;
/* end of common portion */
rtems_monitor_symbol_t entry;
unsigned32 argument;
unsigned32 stack_size;
rtems_task_priority priority;
rtems_mode modes;
rtems_attribute attributes;
} rtems_monitor_init_task_t;
/*
* Message queue
*/
typedef struct {
rtems_id id;
rtems_name name;
/* end of common portion */
rtems_attribute attributes;
unsigned32 number_of_pending_messages;
unsigned32 maximum_pending_messages;
unsigned32 maximum_message_size;
} rtems_monitor_queue_t;
/*
* Extension
*/
typedef struct {
rtems_id id;
rtems_name name;
/* end of common portion */
rtems_monitor_symbol_t create;
rtems_monitor_symbol_t start;
rtems_monitor_symbol_t restart;
rtems_monitor_symbol_t delete;
rtems_monitor_symbol_t tswitch;
rtems_monitor_symbol_t begin;
rtems_monitor_symbol_t exitted;
rtems_monitor_symbol_t fatal;
} rtems_monitor_extension_t;
/*
* Device driver
*/
typedef struct {
rtems_id id; /* not really an id (should be tho) */
rtems_name name; /* ditto */
/* end of common portion */
rtems_monitor_symbol_t initialization; /* initialization procedure */
rtems_monitor_symbol_t open; /* open request procedure */
rtems_monitor_symbol_t close; /* close request procedure */
rtems_monitor_symbol_t read; /* read request procedure */
rtems_monitor_symbol_t write; /* write request procedure */
rtems_monitor_symbol_t control; /* special functions procedure */
} rtems_monitor_driver_t;
typedef struct {
rtems_id id; /* not used for drivers (yet) */
rtems_name name; /* not used for drivers (yet) */
/* end of common portion */
unsigned32 major;
unsigned32 minor;
char name_string[64];
} rtems_monitor_dname_t;
/*
* System config
*/
typedef struct {
void *work_space_start;
unsigned32 work_space_size;
unsigned32 maximum_tasks;
unsigned32 maximum_timers;
unsigned32 maximum_semaphores;
unsigned32 maximum_message_queues;
unsigned32 maximum_partitions;
unsigned32 maximum_regions;
unsigned32 maximum_ports;
unsigned32 maximum_periods;
unsigned32 maximum_extensions;
unsigned32 microseconds_per_tick;
unsigned32 ticks_per_timeslice;
unsigned32 number_of_initialization_tasks;
} rtems_monitor_config_t;
/*
* MPCI config
*/
typedef struct {
unsigned32 node; /* local node number */
unsigned32 maximum_nodes; /* maximum # nodes in system */
unsigned32 maximum_global_objects; /* maximum # global objects */
unsigned32 maximum_proxies; /* maximum # proxies */
unsigned32 default_timeout; /* in ticks */
unsigned32 maximum_packet_size;
rtems_monitor_symbol_t initialization;
rtems_monitor_symbol_t get_packet;
rtems_monitor_symbol_t return_packet;
rtems_monitor_symbol_t send_packet;
rtems_monitor_symbol_t receive_packet;
} rtems_monitor_mpci_t;
/*
* The generic canonical information union
*/
typedef union {
rtems_monitor_generic_t generic;
rtems_monitor_task_t task;
rtems_monitor_queue_t queue;
rtems_monitor_extension_t extension;
rtems_monitor_driver_t driver;
rtems_monitor_dname_t dname;
rtems_monitor_config_t config;
rtems_monitor_mpci_t mpci;
rtems_monitor_init_task_t itask;
} rtems_monitor_union_t;
/*
* Support for talking to other monitors
*/
/*
* Names of other monitors
*/
#define RTEMS_MONITOR_NAME (rtems_build_name('R', 'M', 'O', 'N'))
#define RTEMS_MONITOR_SERVER_NAME (rtems_build_name('R', 'M', 'S', 'V'))
#define RTEMS_MONITOR_QUEUE_NAME (rtems_build_name('R', 'M', 'S', 'Q'))
#define RTEMS_MONITOR_RESPONSE_QUEUE_NAME (rtems_build_name('R', 'M', 'R', 'Q'))
#define RTEMS_MONITOR_SERVER_RESPONSE 0x0001
#define RTEMS_MONITOR_SERVER_CANONICAL 0x0002
typedef struct
{
unsigned32 command;
rtems_id return_id;
unsigned32 argument0;
unsigned32 argument1;
unsigned32 argument2;
unsigned32 argument3;
unsigned32 argument4;
unsigned32 argument5;
} rtems_monitor_server_request_t;
typedef struct
{
unsigned32 command;
unsigned32 result0;
unsigned32 result1;
rtems_monitor_union_t payload;
} rtems_monitor_server_response_t;
extern rtems_id rtems_monitor_task_id;
extern unsigned32 rtems_monitor_node; /* our node number */
extern unsigned32 rtems_monitor_default_node; /* current default for commands */
/*
* Monitor command function and table entry
*/
typedef struct rtems_monitor_command_entry_s rtems_monitor_command_entry_t;
typedef void ( *rtems_monitor_command_function_t )(
int argc,
char **argv,
unsigned32 command_arg,
boolean verbose
);
struct rtems_monitor_command_entry_s {
char *command; /* command name */
char *usage; /* usage string for the command */
unsigned32 arguments_required; /* # of required args */
rtems_monitor_command_function_t command_function;
/* Some argument for the command */
unsigned32 command_arg;
};
typedef void *(*rtems_monitor_object_next_fn)(void *, void *, rtems_id *);
typedef void (*rtems_monitor_object_canonical_fn)(void *, void *);
typedef void (*rtems_monitor_object_dump_header_fn)(boolean);
typedef void (*rtems_monitor_object_dump_fn)(void *, boolean);
typedef struct {
rtems_object_type_t type;
void *object_information;
int size; /* of canonical object */
rtems_monitor_object_next_fn next;
rtems_monitor_object_canonical_fn canonical;
rtems_monitor_object_dump_header_fn dump_header;
rtems_monitor_object_dump_fn dump;
} rtems_monitor_object_info_t;
/* monitor.c */
void rtems_monitor_kill(void);
void rtems_monitor_init(rtems_boolean);
void rtems_monitor_wakeup(void);
void rtems_monitor_pause_cmd(int, char **, unsigned32, boolean);
void rtems_monitor_fatal_cmd(int, char **, unsigned32, boolean);
void rtems_monitor_continue_cmd(int, char **, unsigned32, boolean);
void rtems_monitor_node_cmd(int, char **, unsigned32, boolean);
void rtems_monitor_symbols_loadup(void);
void rtems_monitor_task(rtems_task_argument);
/* server.c */
void rtems_monitor_server_kill(void);
rtems_status_code rtems_monitor_server_request(unsigned32, rtems_monitor_server_request_t *, rtems_monitor_server_response_t *);
void rtems_monitor_server_task(rtems_task_argument);
void rtems_monitor_server_init(unsigned32);
/* command.c */
int rtems_monitor_make_argv(char *, int *, char **);
int rtems_monitor_command_read(char *, int *, char **);
rtems_monitor_command_entry_t *rtems_monitor_command_lookup(
rtems_monitor_command_entry_t * table, int argc, char **argv);
void rtems_monitor_command_usage(rtems_monitor_command_entry_t *, char *);
void rtems_monitor_help_cmd(int, char **, unsigned32, boolean);
/* prmisc.c */
void rtems_monitor_separator(void);
unsigned32 rtems_monitor_pad(unsigned32 dest_col, unsigned32 curr_col);
unsigned32 rtems_monitor_dump_char(unsigned8 ch);
unsigned32 rtems_monitor_dump_decimal(unsigned32 num);
unsigned32 rtems_monitor_dump_hex(unsigned32 num);
unsigned32 rtems_monitor_dump_id(rtems_id id);
unsigned32 rtems_monitor_dump_name(rtems_name name);
unsigned32 rtems_monitor_dump_priority(rtems_task_priority priority);
unsigned32 rtems_monitor_dump_state(States_Control state);
unsigned32 rtems_monitor_dump_modes(rtems_mode modes);
unsigned32 rtems_monitor_dump_attributes(rtems_attribute attributes);
unsigned32 rtems_monitor_dump_events(rtems_event_set events);
unsigned32 rtems_monitor_dump_notepad(unsigned32 *notepad);
/* object.c */
rtems_id rtems_monitor_id_fixup(rtems_id, unsigned32, rtems_object_type_t);
rtems_id rtems_monitor_object_canonical_get(rtems_object_type_t, rtems_id, void *, unsigned32 *size_p);
rtems_id rtems_monitor_object_canonical_next(rtems_monitor_object_info_t *, rtems_id, void *);
void *rtems_monitor_object_next(void *, void *, rtems_id, rtems_id *);
rtems_id rtems_monitor_object_canonical(rtems_id, void *);
void rtems_monitor_object_cmd(int, char **, unsigned32, boolean);
/* manager.c */
void *rtems_monitor_manager_next(void *, void *, rtems_id *);
/* config.c */
void rtems_monitor_config_canonical(rtems_monitor_config_t *, void *);
void *rtems_monitor_config_next(void *, rtems_monitor_config_t *, rtems_id *);
void rtems_monitor_config_dump_header(boolean);
void rtems_monitor_config_dump(rtems_monitor_config_t *, boolean verbose);
/* mpci.c */
void rtems_monitor_mpci_canonical(rtems_monitor_mpci_t *, void *);
void *rtems_monitor_mpci_next(void *, rtems_monitor_mpci_t *, rtems_id *);
void rtems_monitor_mpci_dump_header(boolean);
void rtems_monitor_mpci_dump(rtems_monitor_mpci_t *, boolean verbose);
/* itask.c */
void rtems_monitor_init_task_canonical(rtems_monitor_init_task_t *, void *);
void *rtems_monitor_init_task_next(void *, rtems_monitor_init_task_t *, rtems_id *);
void rtems_monitor_init_task_dump_header(boolean);
void rtems_monitor_init_task_dump(rtems_monitor_init_task_t *, boolean verbose);
/* extension.c */
void rtems_monitor_extension_canonical(rtems_monitor_extension_t *, void *);
void rtems_monitor_extension_dump_header(boolean verbose);
void rtems_monitor_extension_dump(rtems_monitor_extension_t *, boolean);
/* task.c */
void rtems_monitor_task_canonical(rtems_monitor_task_t *, void *);
void rtems_monitor_task_dump_header(boolean verbose);
void rtems_monitor_task_dump(rtems_monitor_task_t *, boolean);
/* queue.c */
void rtems_monitor_queue_canonical(rtems_monitor_queue_t *, void *);
void rtems_monitor_queue_dump_header(boolean verbose);
void rtems_monitor_queue_dump(rtems_monitor_queue_t *, boolean);
/* driver.c */
void *rtems_monitor_driver_next(void *, rtems_monitor_driver_t *, rtems_id *);
void rtems_monitor_driver_canonical(rtems_monitor_driver_t *, void *);
void rtems_monitor_driver_dump_header(boolean);
void rtems_monitor_driver_dump(rtems_monitor_driver_t *, boolean);
/* dname.c */
void *rtems_monitor_dname_next(void *, rtems_monitor_dname_t *, rtems_id *);
void rtems_monitor_dname_canonical(rtems_monitor_dname_t *, void *);
void rtems_monitor_dname_dump_header(boolean);
void rtems_monitor_dname_dump(rtems_monitor_dname_t *, boolean);
/* symbols.c */
rtems_symbol_table_t *rtems_symbol_table_create();
void rtems_symbol_table_destroy(rtems_symbol_table_t *table);
rtems_symbol_t *rtems_symbol_create(rtems_symbol_table_t *, char *, unsigned32);
rtems_symbol_t *rtems_symbol_value_lookup(rtems_symbol_table_t *, unsigned32);
rtems_symbol_t *rtems_symbol_name_lookup(rtems_symbol_table_t *, char *);
void *rtems_monitor_symbol_next(void *object_info, rtems_monitor_symbol_t *, rtems_id *);
void rtems_monitor_symbol_canonical(rtems_monitor_symbol_t *, rtems_symbol_t *);
void rtems_monitor_symbol_canonical_by_name(rtems_monitor_symbol_t *, char *);
void rtems_monitor_symbol_canonical_by_value(rtems_monitor_symbol_t *, void *);
unsigned32 rtems_monitor_symbol_dump(rtems_monitor_symbol_t *, boolean);
void rtems_monitor_symbol_cmd(int, char **, unsigned32, boolean);
extern rtems_unsigned32 rtems_monitor_task_id;
extern rtems_symbol_table_t *rtems_monitor_symbols;
#ifndef MONITOR_PROMPT
#define MONITOR_PROMPT "rtems" /* will have '> ' appended */
#endif
#define MONITOR_WAKEUP_EVENT RTEMS_EVENT_0
#define STREQ(a,b) (strcmp(a,b) == 0)
#define STRNEQ(a,b,n) (strncmp(a,b,n) == 0)
#ifdef __cplusplus
}
#endif

View File

@@ -1,5 +1,8 @@
/*
* File: symbols.h
* @(#)symbols.h 1.3 - 95/06/09
*
*
* RTEMS monitor symbol table functions
*
* Description:
* Entry points for symbol table routines.
@@ -8,6 +11,7 @@
*
* TODO:
*
* $Id$
*/
#ifndef _INCLUDE_SYMBOLS_H
@@ -61,15 +65,6 @@ typedef struct {
} rtems_symbol_table_t;
void rtems_symbol_table_destroy(rtems_symbol_table_t *table);
rtems_symbol_table_t *rtems_symbol_table_create();
rtems_symbol_t *rtems_symbol_create(rtems_symbol_table_t *,
char *, rtems_unsigned32);
rtems_symbol_t *rtems_symbol_value_lookup(rtems_symbol_table_t *,
rtems_unsigned32);
rtems_symbol_t *rtems_symbol_name_lookup(rtems_symbol_table_t *,
char *);
#define rtems_symbol_name(sp) ((sp)->name)
#define rtems_symbol_value(sp) ((sp)->value)

View File

@@ -16,20 +16,24 @@
* to the copyright license under the clause at DFARS 252.227-7013. This
* notice must appear in all copies of this file and its derivatives.
*
* poll.c,v 1.2 1995/05/09 20:22:57 joel Exp
* $Id$
*/
#include <rtems.h>
#include <rtems/sysstate.h>
#include <rtems/libio.h>
#include "shm.h"
#include "clockdrv.h"
void Shm_Poll()
{
rtems_unsigned32 tmpfront;
rtems_libio_ioctl_args_t args;
Clock_isr( 0 ); /* invoke standard clock ISR */
/* invoke clock isr */
args.iop = 0;
args.command = rtems_build_name('I', 'S', 'R', ' ');
(void) rtems_io_control(rtems_clock_major, rtems_clock_minor, &args);
/*
* Check for msgs only if we are "up"
@@ -39,14 +43,11 @@ void Shm_Poll()
if (_System_state_Is_up(_System_state_Get()))
{
/* enable_tracing(); */
/* ticks += 1; */
Shm_Lock( Shm_Local_receive_queue );
tmpfront = Shm_Local_receive_queue->front;
Shm_Unlock( Shm_Local_receive_queue );
if ( Shm_Convert(tmpfront) != Shm_Locked_queue_End_of_list ) {
rtems_multiprocessing_announce();
Shm_Interrupt_count++;
if ( Shm_Convert(tmpfront) != Shm_Locked_queue_End_of_list )
{
rtems_multiprocessing_announce();
Shm_Interrupt_count++;
}
}
}

View File

@@ -19,10 +19,16 @@
*/
#include <rtems.h>
#include <rtems/libio.h>
#include "shm.h"
#include "clockdrv.h"
rtems_isr Shm_setclockvec()
{
ReInstall_clock( Shm_Poll );
rtems_libio_ioctl_args_t args;
args.iop = 0;
args.command = rtems_build_name('N', 'E', 'W', ' ');
args.buffer = (void *) Shm_Poll;
(void) rtems_io_control(rtems_clock_major, rtems_clock_minor, &args);
}

View File

@@ -20,6 +20,8 @@
#ifndef __SHM_h
#define __SHM_h
#include <clockdrv.h>
#ifdef __cplusplus
extern "C" {
#endif
@@ -518,6 +520,7 @@ extern rtems_mpci_table MPCI_table;
rtems_mpci_table MPCI_table = {
100000, /* default timeout value in ticks */
MAX_PACKET_SIZE, /* maximum packet size */
Shm_Initialization, /* initialization procedure */
Shm_Get_packet, /* get packet procedure */
Shm_Return_packet, /* return packet procedure */

258
c/src/libmisc/assoc/assoc.c Normal file
View File

@@ -0,0 +1,258 @@
/*
* @(#)assoc.c 1.4 - 95/08/02
*
*
* assoc.c
* rtems assoc routines
*
* $Id$
*/
#include <rtems.h>
#include "assoc.h"
#include <stdio.h> /* sprintf */
#include <string.h> /* strcat, strcmp */
#define STREQ(a,b) (strcmp((a), (b)) == 0)
#define rtems_assoc_is_default(ap) ((ap)->name && STREQ(ap->name, RTEMS_ASSOC_DEFAULT_NAME))
rtems_assoc_t *
rtems_assoc_ptr_by_name(
rtems_assoc_t *ap,
char *name
)
{
rtems_assoc_t *default_ap = 0;
if (rtems_assoc_is_default(ap))
default_ap = ap++;
for ( ; ap->name; ap++)
if (strcmp(ap->name, name) == 0)
return ap;
return default_ap;
}
rtems_assoc_t *
rtems_assoc_ptr_by_local(
rtems_assoc_t *ap,
unsigned32 local_value
)
{
rtems_assoc_t *default_ap = 0;
if (rtems_assoc_is_default(ap))
default_ap = ap++;
for ( ; ap->name; ap++)
if (ap->local_value == local_value)
return ap;
return default_ap;
}
rtems_assoc_t *
rtems_assoc_ptr_by_remote(
rtems_assoc_t *ap,
unsigned32 remote_value
)
{
rtems_assoc_t *default_ap = 0;
if (rtems_assoc_is_default(ap))
default_ap = ap++;
for ( ; ap->name; ap++)
if (ap->remote_value == remote_value)
return ap;
return default_ap;
}
/*
* Get values
*/
unsigned32
rtems_assoc_remote_by_local(
rtems_assoc_t *ap,
unsigned32 local_value
)
{
rtems_assoc_t *nap;
nap = rtems_assoc_ptr_by_local(ap, local_value);
if (nap)
return nap->remote_value;
return 0;
}
unsigned32
rtems_assoc_local_by_remote(
rtems_assoc_t *ap,
unsigned32 remote_value
)
{
rtems_assoc_t *nap;
nap = rtems_assoc_ptr_by_remote(ap, remote_value);
if (nap)
return nap->local_value;
return 0;
}
unsigned32
rtems_assoc_remote_by_name(
rtems_assoc_t *ap,
char *name
)
{
rtems_assoc_t *nap;
nap = rtems_assoc_ptr_by_name(ap, name);
if (nap)
return nap->remote_value;
return 0;
}
unsigned32
rtems_assoc_local_by_name(
rtems_assoc_t *ap,
char *name
)
{
rtems_assoc_t *nap;
nap = rtems_assoc_ptr_by_name(ap, name);
if (nap)
return nap->local_value;
return 0;
}
/*
* what to return if a value is not found
* this is not reentrant, but it really shouldn't be invoked anyway
*/
char *
rtems_assoc_name_bad(
unsigned32 bad_value
)
{
static char bad_buffer[32];
sprintf(bad_buffer, "< %d [0x%x] >", bad_value, bad_value);
return bad_buffer;
}
char *
rtems_assoc_name_by_local(
rtems_assoc_t *ap,
unsigned32 local_value
)
{
rtems_assoc_t *nap;
nap = rtems_assoc_ptr_by_local(ap, local_value);
if (nap)
return nap->name;
return rtems_assoc_name_bad(local_value);
}
char *
rtems_assoc_name_by_remote(
rtems_assoc_t *ap,
unsigned32 remote_value
)
{
rtems_assoc_t *nap;
nap = rtems_assoc_ptr_by_remote(ap, remote_value);
if (nap)
return nap->name;
return rtems_assoc_name_bad(remote_value);
}
/*
* Bitfield functions assume just 1 bit set in each of remote and local
* entries; they do not check for this.
*/
unsigned32 rtems_assoc_remote_by_local_bitfield(
rtems_assoc_t *ap,
unsigned32 local_value
)
{
unsigned32 b;
unsigned32 remote_value = 0;
for (b = 1; b; b <<= 1)
if (b & local_value)
remote_value |= rtems_assoc_remote_by_local(ap, b);
return remote_value;
}
unsigned32 rtems_assoc_local_by_remote_bitfield(
rtems_assoc_t *ap,
unsigned32 remote_value
)
{
unsigned32 b;
unsigned32 local_value = 0;
for (b = 1; b; b <<= 1)
if (b & remote_value)
local_value |= rtems_assoc_local_by_remote(ap, b);
return local_value;
}
char *rtems_assoc_name_by_remote_bitfield(
rtems_assoc_t *ap,
unsigned32 value,
char *buffer
)
{
unsigned32 b;
*buffer = 0;
for (b = 1; b; b <<= 1)
if (b & value)
{
if (*buffer)
strcat(buffer, " ");
strcat(buffer, rtems_assoc_name_by_remote(ap, b));
}
return buffer;
}
char *rtems_assoc_name_by_local_bitfield(
rtems_assoc_t *ap,
unsigned32 value,
char *buffer
)
{
unsigned32 b;
*buffer = 0;
for (b = 1; b; b <<= 1)
if (b & value)
{
if (*buffer)
strcat(buffer, " ");
strcat(buffer, rtems_assoc_name_by_local(ap, b));
}
return buffer;
}

View File

@@ -0,0 +1,44 @@
/*
* @(#)assoc.h 1.2 - 95/06/28
*
*
* Rtems associativity routines. Mainly used to convert a value from
* one space to another (eg: our errno's to host errno's and v.v)
*
*
* $Id$
*/
#ifndef _INCLUDE_ASSOC_H
#define _INCLUDE_ASSOC_H
typedef struct {
char *name;
unsigned32 local_value;
unsigned32 remote_value;
} rtems_assoc_t;
/*
* Flag/marker for optional default value in each table
*/
#define RTEMS_ASSOC_DEFAULT_NAME "(default)"
rtems_assoc_t *rtems_assoc_ptr_by_name(rtems_assoc_t *, char *);
rtems_assoc_t *rtems_assoc_ptr_by_value(rtems_assoc_t *, unsigned32);
rtems_assoc_t *rtems_assoc_ptr_by_remote(rtems_assoc_t *, unsigned32);
unsigned32 rtems_assoc_remote_by_local(rtems_assoc_t *, unsigned32);
unsigned32 rtems_assoc_local_by_remote(rtems_assoc_t *, unsigned32);
unsigned32 rtems_assoc_remote_by_name(rtems_assoc_t *, char *);
unsigned32 rtems_assoc_local_by_name(rtems_assoc_t *, char *);
char *rtems_assoc_name_by_local(rtems_assoc_t *, unsigned32);
char *rtems_assoc_name_by_remote(rtems_assoc_t *, unsigned32);
unsigned32 rtems_assoc_remote_by_local_bitfield(rtems_assoc_t *, unsigned32);
char *rtems_assoc_name_by_local_bitfield(rtems_assoc_t *, unsigned32, char *);
char *rtems_assoc_name_by_remote_bitfield(rtems_assoc_t *, unsigned32, char *);
unsigned32 rtems_assoc_local_by_remote_bitfield(rtems_assoc_t *ap, unsigned32);
#endif /* ! _INCLUDE_ASSOC_H */

212
c/src/libmisc/error/error.c Normal file
View File

@@ -0,0 +1,212 @@
/*
* @(#)error.c 1.2 - 95/08/02
*
*
* report errors and panics to RTEMS' stderr.
* Currently just used by RTEMS monitor.
*
*
* $Id$
*/
/*
* These routines provide general purpose error reporting.
* rtems_error reports an error to stderr and allows use of
* printf style formatting. A newline is appended to all messages.
*
* error_flag can be specified as any of the following:
*
* RTEMS_ERROR_ERRNO -- include errno text in output
* RTEMS_ERROR_PANIC -- halts local system after output
* RTEMS_ERROR_ABORT -- abort after output
*
* It can also include a rtems_status value which can be OR'd
* with the above flags. *
*
* EXAMPLE
* #include <rtems.h>
* #include <rtems/error.h>
* rtems_error(0, "stray interrupt %d", intr);
*
* EXAMPLE
* if ((status = rtems_task_create(...)) != RTEMS_SUCCCESSFUL)
* {
* rtems_error(status | RTEMS_ERROR_ABORT,
* "could not create task");
* }
*
* EXAMPLE
* if ((fd = open(pathname, O_RDNLY)) < 0)
* {
* rtems_error(FLOSS_ERROR_ERRNO, "open of '%s' failed", pathname);
* goto failed;
* }
*/
#include <rtems.h>
#include "error.h"
#include "assoc.h"
#include <stdio.h>
#include <stdarg.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h> /* _exit() */
/* bug in hpux <errno.h>: no prototypes unless you are C++ */
#ifdef hpux9
char *strerror(int);
#endif
extern char *rtems_progname;
int rtems_panic_in_progress;
rtems_assoc_t rtems_status_assoc[] = {
{ "successful completion", RTEMS_SUCCESSFUL, },
{ "returned from a thread", RTEMS_TASK_EXITTED, },
{ "multiprocessing not configured", RTEMS_MP_NOT_CONFIGURED, },
{ "invalid object name", RTEMS_INVALID_NAME, },
{ "invalid object id", RTEMS_INVALID_ID, },
{ "too many", RTEMS_TOO_MANY, },
{ "timed out waiting", RTEMS_TIMEOUT, },
{ "object deleted while waiting", RTEMS_OBJECT_WAS_DELETED, },
{ "specified size was invalid", RTEMS_INVALID_SIZE, },
{ "address specified is invalid", RTEMS_INVALID_ADDRESS, },
{ "number was invalid", RTEMS_INVALID_NUMBER, },
{ "item has not been initialized", RTEMS_NOT_DEFINED, },
{ "resources still outstanding", RTEMS_RESOURCE_IN_USE, },
{ "request not satisfied", RTEMS_UNSATISFIED, },
{ "thread is in wrong state", RTEMS_INCORRECT_STATE, },
{ "thread already in state", RTEMS_ALREADY_SUSPENDED, },
{ "illegal on calling thread", RTEMS_ILLEGAL_ON_SELF, },
{ "illegal for remote object", RTEMS_ILLEGAL_ON_REMOTE_OBJECT, },
{ "called from wrong environment", RTEMS_CALLED_FROM_ISR, },
{ "invalid thread priority", RTEMS_INVALID_PRIORITY, },
{ "invalid date/time", RTEMS_INVALID_CLOCK, },
{ "invalid node id", RTEMS_INVALID_NODE, },
{ "directive not configured", RTEMS_NOT_CONFIGURED, },
{ "not owner of resource", RTEMS_NOT_OWNER_OF_RESOURCE , },
{ "directive not implemented", RTEMS_NOT_IMPLEMENTED, },
{ "RTEMS inconsistency detected", RTEMS_INTERNAL_ERROR, },
{ "internal multiprocessing only", RTEMS_PROXY_BLOCKING, },
{ "could not get enough memory", RTEMS_NO_MEMORY, },
{ 0, 0, 0 },
};
char *
rtems_status_text(
rtems_status_code status
)
{
return rtems_assoc_name_by_local(rtems_status_assoc, status);
}
static int rtems_verror(
unsigned32 error_flag,
char *printf_format,
va_list arglist
)
{
int local_errno = 0;
int chars_written = 0;
rtems_status_code status;
if (error_flag & RTEMS_ERROR_PANIC)
{
rtems_panic_in_progress++;
/* disable task switches */
_Thread_Disable_dispatch();
/* don't aggravate things */
if (rtems_panic_in_progress > 2)
return 0;
}
(void) fflush(stdout); /* in case stdout/stderr same */
status = error_flag & ~RTEMS_ERROR_MASK;
if (error_flag & RTEMS_ERROR_ERRNO) /* include errno? */
local_errno = errno;
if (_Configuration_Is_multiprocessing())
fprintf(stderr, "[%d] ", _Configuration_MP_table->node);
if (rtems_progname && *rtems_progname)
chars_written += fprintf(stderr, "%s: ", rtems_progname);
chars_written += vfprintf(stderr, printf_format, arglist);
if (status)
chars_written += fprintf(stderr, " (status: %s)", rtems_status_text(status));
if (local_errno)
if ((local_errno > 0) && *strerror(local_errno))
chars_written += fprintf(stderr, " (errno: %s)", strerror(local_errno));
else
chars_written += fprintf(stderr, " (unknown errno=%d)", local_errno);
chars_written += fprintf(stderr, "\n");
(void) fflush(stderr);
if (error_flag & (RTEMS_ERROR_PANIC | RTEMS_ERROR_ABORT))
{
if (error_flag & RTEMS_ERROR_PANIC)
{
rtems_error(0, "fatal error, exiting");
_exit(local_errno);
}
else
{
rtems_error(0, "fatal error, aborting");
abort();
}
}
return chars_written;
}
/*
* Report an error.
* error_flag is as above; printf_format is a normal
* printf(3) format string, with its concommitant arguments.
*
* Returns the number of characters written.
*/
int rtems_error(
int error_flag,
char *printf_format,
...
)
{
va_list arglist;
int chars_written;
va_start(arglist, printf_format);
chars_written = rtems_verror(error_flag, printf_format, arglist);
va_end(arglist);
return chars_written;
}
/*
* rtems_panic is shorthand for rtems_error(RTEMS_ERROR_PANIC, ...)
*/
void rtems_panic(
char *printf_format,
...
)
{
va_list arglist;
va_start(arglist, printf_format);
(void) rtems_verror(RTEMS_ERROR_PANIC, printf_format, arglist);
va_end(arglist);
}

View File

@@ -0,0 +1,26 @@
/*
* @(#)error.h 1.1 - 95/08/02
*
*
* Defines and externs for rtems error reporting
*
* $Id$
*/
/*
* rtems_error() and rtems_panic() support
*/
#define RTEMS_ERROR_ERRNO (1<<((sizeof(int) * 8) - 2)) /* hi bit; use 'errno' */
#define RTEMS_ERROR_PANIC (RTEMS_ERROR_ERRNO / 2) /* err fatal; no return */
#define RTEMS_ERROR_ABORT (RTEMS_ERROR_ERRNO / 4) /* err is fatal; panic */
#define RTEMS_ERROR_MASK (RTEMS_ERROR_ERRNO | RTEMS_ERROR_ABORT | \
RTEMS_ERROR_PANIC) /* all */
char *rtems_status_text(rtems_status_code);
int rtems_error(int error_code, char *printf_format, ...);
void rtems_panic(char *printf_format, ...);
extern int rtems_panic_in_progress;

View File

@@ -2,6 +2,96 @@
# $Id$
#
This is a snapshot of a work in process. It is the beginnings of a
debug monitor task and trap handler which is tasking aware.
monitor task
The monitor task is an optional task that knows about RTEMS
data structures and can print out information about them.
It is a work-in-progress and needs many more commands, but
is useful now.
The monitor works best when it is the highest priority task,
so all your other tasks should ideally be at some priority
greater than 1.
To use the monitor:
-------------------
#include <rtems/monitor.h>
...
rtems_monitor_init(0);
The parameter to rtems_monitor_init() tells the monitor whether
to suspend itself on startup. A value of 0 causes the monitor
to immediately enter command mode; a non-zero value causes the
monitor to suspend itself after creation and wait for explicit
wakeup.
rtems_monitor_wakeup();
wakes up a suspended monitor and causes it to reenter command mode.
Monitor commands
----------------
The monitor prompt is 'rtems> '.
Can abbreviate commands to "uniquity"
There is a 'help' command. Here is the output from various
help commands:
Commands (may be abbreviated)
help -- get this message or command specific help
task -- show task information
queue -- show message queue information
symbol -- show entries from symbol table
pause -- pause monitor for a specified number of ticks
fatal -- invoke a fatal RTEMS error
task [id [id ...] ]
display information about the specified tasks.
Default is to display information about all tasks on this node
queue [id [id ... ] ]
display information about the specified message queues
Default is to display information about all queues on this node
symbol [ symbolname [symbolname ... ] ]
display value associated with specified symbol.
Defaults to displaying all known symbols.
pause [ticks]
monitor goes to "sleep" for specified ticks (default is 1)
monitor will resume at end of period or if explicitly awakened
fatal [status]
Invoke 'rtems_fatal_error_occurred' with 'status'
(default is RTEMS_INTERNAL_ERROR)
continue
put the monitor to sleep waiting for an explicit wakeup from the
program running.
Sample output from 'task' command
---------------------------------
rtems> task
ID NAME PRIO STAT MODES EVENTS WAITID WAITARG NOTES
------------------------------------------------------------------------
00010001 UI1 2 READY P:T:nA NONE15: 0x40606348
00010002 RMON 1 READY nP NONE15: 0x40604110
'RMON' is the monitor itself, so we have 1 "user" task.
Its modes are P:T:nA which translate to:
preemptable
timesliced
no ASRS
It has no events.
It has a notepad value for notepad 15 which is 0x40606348
(this is the libc thread state)

View File

@@ -0,0 +1,190 @@
/*
* @(#)command.c 1.5 - 95/08/02
*
*
* Command parsing routines for RTEMS monitor
*
* TODO:
*
* $Id$
*/
#include <rtems.h>
#include "monitor.h"
#include <stdio.h>
#include <string.h>
/*
* make_argv(cp): token-count
* Break up the command line in 'cp' into global argv[] and argc (return
* value).
*/
int
rtems_monitor_make_argv(
char *cp,
int *argc_p,
char **argv)
{
int argc = 0;
while ((cp = strtok(cp, " \t\n\r")))
{
argv[argc++] = cp;
cp = (char *) NULL;
}
argv[argc] = (char *) NULL; /* end of argv */
return *argc_p = argc;
}
/*
* Read and break up a monitor command
*
* We have to loop on the gets call, since it will return NULL under UNIX
* RTEMS when we get a signal (eg: SIGALRM).
*/
int
rtems_monitor_command_read(char *command,
int *argc,
char **argv)
{
extern rtems_configuration_table BSP_Configuration;
static char monitor_prompt[32];
/*
* put node number in the prompt if we are multiprocessing
*/
if (BSP_Configuration.User_multiprocessing_table == 0)
sprintf(monitor_prompt, "%s", MONITOR_PROMPT);
else if (rtems_monitor_default_node != rtems_monitor_node)
sprintf(monitor_prompt, "%d-%s-%d", rtems_monitor_node, MONITOR_PROMPT, rtems_monitor_default_node);
else
sprintf(monitor_prompt, "%d-%s", rtems_monitor_node, MONITOR_PROMPT);
#ifdef RTEMS_UNIX
/* RTEMS on unix gets so many interrupt system calls this is hosed */
printf("%s> ", monitor_prompt);
fflush(stdout);
while (gets(command) == (char *) 0)
;
#else
do
{
printf("%s> ", monitor_prompt);
fflush(stdout);
} while (gets(command) == (char *) 0);
#endif
return rtems_monitor_make_argv(command, argc, argv);
}
/*
* Look up a command in a command table
*
*/
rtems_monitor_command_entry_t *
rtems_monitor_command_lookup(
rtems_monitor_command_entry_t *table,
int argc,
char **argv
)
{
rtems_monitor_command_entry_t *p;
rtems_monitor_command_entry_t *abbreviated_match = 0;
int abbreviated_matches = 0;
char *command;
int command_length;
command = argv[0];
if ((table == 0) || (command == 0))
goto failed;
command_length = strlen(command);
for (p = table; p->command; p++)
if (STREQ(command, p->command)) /* exact match */
goto done;
else if (STRNEQ(command, p->command, command_length))
{
abbreviated_matches++;
abbreviated_match = p;
}
/* no perfect match; is there a non-ambigous abbreviated match? */
if ( ! abbreviated_match)
{
printf("Unrecognized command '%s'; try 'help'\n", command);
goto failed;
}
if (abbreviated_matches > 1)
{
printf("Command '%s' is ambiguous; try 'help'\n", command);
goto failed;
}
p = abbreviated_match;
done:
if (p->command_function == 0)
goto failed;
return p;
failed:
return 0;
}
void
rtems_monitor_command_usage(rtems_monitor_command_entry_t *table,
char *command_string)
{
rtems_monitor_command_entry_t *help = 0;
char *help_command_argv[2];
/* if first entry in table is a usage, then print it out */
if (command_string == 0)
{
if (STREQ(table->command, "--usage--") && table->usage)
help = table;
}
else
{
help_command_argv[0] = command_string;
help_command_argv[1] = 0;
help = rtems_monitor_command_lookup(table, 1, help_command_argv);
}
if (help)
printf("%s\n", help->usage);
}
void
rtems_monitor_help_cmd(
int argc,
char **argv,
unsigned32 command_arg,
boolean verbose
)
{
int arg;
rtems_monitor_command_entry_t *command;
command = (rtems_monitor_command_entry_t *) command_arg;
if (argc == 1)
rtems_monitor_command_usage(command, 0);
else
{
for (arg=1; argv[arg]; arg++)
rtems_monitor_command_usage(command, argv[arg]);
}
}

View File

@@ -0,0 +1,132 @@
/*
* @(#)config.c 1.5 - 95/08/02
*
*
* RTEMS Config display support
*
* TODO
*
* $Id$
*/
#include <rtems.h>
#include "monitor.h"
#include <stdio.h>
#include <stdlib.h> /* strtoul() */
#define DATACOL 15
#define CONTCOL DATACOL /* continued col */
/*
* Fill in entire monitor config table
* for sending to a remote monitor or printing on the local system
*/
void
rtems_monitor_config_canonical(
rtems_monitor_config_t *canonical_config,
void *config_void
)
{
rtems_configuration_table *c = (rtems_configuration_table *) config_void;
canonical_config->work_space_start = c->work_space_start;
canonical_config->work_space_size = c->work_space_size;
canonical_config->maximum_tasks = c->maximum_tasks;
canonical_config->maximum_timers = c->maximum_timers;
canonical_config->maximum_semaphores = c->maximum_semaphores;
canonical_config->maximum_message_queues = c->maximum_message_queues;
canonical_config->maximum_partitions = c->maximum_partitions;
canonical_config->maximum_regions = c->maximum_regions;
canonical_config->maximum_ports = c->maximum_ports;
canonical_config->maximum_periods = c->maximum_periods;
canonical_config->maximum_extensions = c->maximum_extensions;
canonical_config->microseconds_per_tick = c->microseconds_per_tick;
canonical_config->ticks_per_timeslice = c->ticks_per_timeslice;
canonical_config->number_of_initialization_tasks = c->number_of_initialization_tasks;
}
/*
* This is easy, since there is only 1 (altho we could get them from
* other nodes...)
*/
void *
rtems_monitor_config_next(
void *object_info,
rtems_monitor_config_t *canonical_config,
rtems_id *next_id
)
{
rtems_configuration_table *c = _Configuration_Table;
int n = rtems_get_index(*next_id);
if (n >= 1)
goto failed;
_Thread_Disable_dispatch();
*next_id += 1;
return (void *) c;
failed:
*next_id = RTEMS_OBJECT_ID_FINAL;
return 0;
}
void
rtems_monitor_config_dump_header(
boolean verbose
)
{
printf("\
INITIAL (startup) Configuration Info\n");
/*23456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789
0 1 2 3 4 5 6 7 */
rtems_monitor_separator();
}
void
rtems_monitor_config_dump(
rtems_monitor_config_t *monitor_config,
boolean verbose
)
{
unsigned32 length = 0;
length = 0;
length += printf("WORKSPACE");
length += rtems_monitor_pad(DATACOL, length);
length += printf("start: 0x%x; size: 0x%x\n",
(unsigned32) monitor_config->work_space_start,
monitor_config->work_space_size);
length = 0;
length += printf("TIME");
length += rtems_monitor_pad(DATACOL, length);
length += printf("usec/tick: %d; tick/timeslice: %d; tick/sec: %d\n",
monitor_config->microseconds_per_tick,
monitor_config->ticks_per_timeslice,
1000000 / monitor_config->microseconds_per_tick);
length = 0;
length += printf("MAXIMUMS");
length += rtems_monitor_pad(DATACOL, length);
length += printf("tasks: %d; timers: %d; sems: %d; que's: %d; ext's: %d\n",
monitor_config->maximum_tasks,
monitor_config->maximum_timers,
monitor_config->maximum_semaphores,
monitor_config->maximum_message_queues,
monitor_config->maximum_extensions);
length = 0;
length += rtems_monitor_pad(CONTCOL, length);
length += printf("partitions: %d; regions: %d; ports: %d; periods: %d\n",
monitor_config->maximum_partitions,
monitor_config->maximum_regions,
monitor_config->maximum_ports,
monitor_config->maximum_periods);
}

View File

@@ -0,0 +1,113 @@
/*
* @(#)dname.c 1.3 - 95/07/31
*
*
* RTEMS monitor driver names support.
*
* There are 2 "driver" things the monitor knows about.
*
* 1. Regular RTEMS drivers.
* This is a table indexed by major device number and
* containing driver entry points only.
*
* 2. Driver name table.
* A separate table of names for drivers.
* The table converts driver names to a major number
* as index into the driver table and a minor number
* for an argument to driver.
*
* Drivers are displayed with 'driver' command.
* Names are displayed with 'dname' command.
*
* $Id$
*/
#include <rtems.h>
#include "monitor.h"
#include <stdio.h>
#include <stdlib.h> /* strtoul() */
#include <string.h> /* strncpy() */
#define DATACOL 15
#define CONTCOL DATACOL /* continued col */
void
rtems_monitor_dname_canonical(
rtems_monitor_dname_t *canonical_dname,
void *dname_void
)
{
rtems_driver_name_t *np = (rtems_driver_name_t *) dname_void;
(void) strncpy(canonical_dname->name_string, np->device_name, sizeof(canonical_dname->name_string));
canonical_dname->major = np->major;
canonical_dname->minor = np->minor;
}
void *
rtems_monitor_dname_next(
void *object_information,
rtems_monitor_dname_t *canonical_dname,
rtems_id *next_id
)
{
int n = rtems_get_index(*next_id);
rtems_driver_name_t *table = object_information;
rtems_driver_name_t *np = 0;
for (np = table + n ; n<RTEMS_MAX_DRIVER_NAMES; n++, np++)
if (np->device_name)
goto done;
*next_id = RTEMS_OBJECT_ID_FINAL;
return 0;
done:
_Thread_Disable_dispatch();
/*
* dummy up a fake id and name for this item
*/
canonical_dname->id = n;
canonical_dname->name = rtems_build_name('-', '-', '-', '-');
*next_id += 1;
return np;
}
void
rtems_monitor_dname_dump_header(
boolean verbose
)
{
printf("\
Major:Minor Name\n");
/*23456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789
0 1 2 3 4 5 6 7 */
rtems_monitor_separator();
}
void
rtems_monitor_dname_dump(
rtems_monitor_dname_t *monitor_dname,
boolean verbose
)
{
unsigned32 length = 0;
length += rtems_monitor_pad(6, length);
length += rtems_monitor_dump_hex(monitor_dname->major);
length += printf(":");
length += rtems_monitor_dump_hex(monitor_dname->minor);
length += rtems_monitor_pad(16, length);
length += printf("%.*s",
(int) sizeof(monitor_dname->name_string),
(char *) monitor_dname->name_string);
length += printf("\n");
length = 0;
}

View File

@@ -0,0 +1,138 @@
/*
* @(#)driver.c 1.4 - 95/08/02
*
*
* RTEMS monitor IO (device drivers) support
*
* There are 2 "driver" things the monitor knows about.
*
* 1. Regular RTEMS drivers.
* This is a table indexed by major device number and
* containing driver entry points only.
*
* 2. Driver name table.
* A separate table of names for drivers.
* The table converts driver names to a major number
* as index into the driver table and a minor number
* for an argument to driver.
*
* Drivers are displayed with 'driver' command.
* Names are displayed with 'name' command.
*
* $Id$
*/
#include <rtems.h>
#include "monitor.h"
#include <stdio.h>
#include <stdlib.h> /* strtoul() */
#define DATACOL 15
#define CONTCOL DATACOL /* continued col */
void
rtems_monitor_driver_canonical(
rtems_monitor_driver_t *canonical_driver,
void *driver_void
)
{
rtems_driver_address_table *d = (rtems_driver_address_table *) driver_void;
rtems_monitor_symbol_canonical_by_value(&canonical_driver->initialization,
d->initialization);
rtems_monitor_symbol_canonical_by_value(&canonical_driver->open,
d->open);
rtems_monitor_symbol_canonical_by_value(&canonical_driver->close,
d->close);
rtems_monitor_symbol_canonical_by_value(&canonical_driver->read,
d->read);
rtems_monitor_symbol_canonical_by_value(&canonical_driver->write,
d->write);
rtems_monitor_symbol_canonical_by_value(&canonical_driver->control,
d->control);
}
void *
rtems_monitor_driver_next(
void *object_info,
rtems_monitor_driver_t *canonical_driver,
rtems_id *next_id
)
{
rtems_configuration_table *c = _Configuration_Table;
int n = rtems_get_index(*next_id);
if (n >= c->number_of_device_drivers)
goto failed;
_Thread_Disable_dispatch();
/*
* dummy up a fake id and name for this item
*/
canonical_driver->id = n;
canonical_driver->name = rtems_build_name('-', '-', '-', '-');
*next_id += 1;
return (void *) (c->Device_driver_table + n);
failed:
*next_id = RTEMS_OBJECT_ID_FINAL;
return 0;
}
void
rtems_monitor_driver_dump_header(
boolean verbose
)
{
printf("\
Major Entry points\n");
/*23456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789
0 1 2 3 4 5 6 7 */
rtems_monitor_separator();
}
void
rtems_monitor_driver_dump(
rtems_monitor_driver_t *monitor_driver,
boolean verbose
)
{
unsigned32 length = 0;
length += printf(" %d", monitor_driver->id);
length += rtems_monitor_pad(13, length);
length += printf("init: ");
length += rtems_monitor_symbol_dump(&monitor_driver->initialization, verbose);
length += printf("; control: ");
length += rtems_monitor_symbol_dump(&monitor_driver->control, verbose);
length += printf("\n");
length = 0;
length += rtems_monitor_pad(13, length);
length += printf("open: ");
length += rtems_monitor_symbol_dump(&monitor_driver->open, verbose);
length += printf("; close: ");
length += rtems_monitor_symbol_dump(&monitor_driver->close, verbose);
length += printf("\n");
length = 0;
length += rtems_monitor_pad(13, length);
length += printf("read: ");
length += rtems_monitor_symbol_dump(&monitor_driver->read, verbose);
length += printf("; write: ");
length += rtems_monitor_symbol_dump(&monitor_driver->write, verbose);
length += printf("\n");
length = 0;
}

View File

@@ -0,0 +1,101 @@
/*
* @(#)extension.c 1.3 - 95/07/31
*
*
* RTEMS Monitor extension support
*
* $Id$
*/
#include <rtems.h>
#include "monitor.h"
#include <stdio.h>
void
rtems_monitor_extension_canonical(
rtems_monitor_extension_t *canonical_extension,
void *extension_void
)
{
Extension_Control *rtems_extension = (Extension_Control *) extension_void;
rtems_extensions_table *e = &rtems_extension->Extension.Callouts;
rtems_monitor_symbol_canonical_by_value(&canonical_extension->create,
e->rtems_task_create);
rtems_monitor_symbol_canonical_by_value(&canonical_extension->start,
e->rtems_task_start);
rtems_monitor_symbol_canonical_by_value(&canonical_extension->restart,
e->rtems_task_restart);
rtems_monitor_symbol_canonical_by_value(&canonical_extension->delete,
e->rtems_task_delete);
rtems_monitor_symbol_canonical_by_value(&canonical_extension->tswitch,
e->task_switch);
rtems_monitor_symbol_canonical_by_value(&canonical_extension->begin,
e->task_begin);
rtems_monitor_symbol_canonical_by_value(&canonical_extension->exitted,
e->task_exitted);
rtems_monitor_symbol_canonical_by_value(&canonical_extension->fatal,
e->fatal);
}
void
rtems_monitor_extension_dump_header(
boolean verbose
)
{
printf("\
ID NAME\n");
/*23456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789
0 1 2 3 4 5 6 7 */
rtems_monitor_separator();
}
/*
* Dump out the canonical form
*/
void
rtems_monitor_extension_dump(
rtems_monitor_extension_t *monitor_extension,
boolean verbose
)
{
unsigned32 length = 0;
length += rtems_monitor_dump_id(monitor_extension->id);
length += rtems_monitor_pad(11, length);
length += rtems_monitor_dump_name(monitor_extension->name);
length += rtems_monitor_pad(18, length);
length += printf("create: ");
length += rtems_monitor_symbol_dump(&monitor_extension->create, verbose);
length += printf("; start: ");
length += rtems_monitor_symbol_dump(&monitor_extension->start, verbose);
length += printf("; restart: ");
length += rtems_monitor_symbol_dump(&monitor_extension->restart, verbose);
length += printf("\n");
length = 0;
length += rtems_monitor_pad(18, length);
length += printf("delete: ");
length += rtems_monitor_symbol_dump(&monitor_extension->delete, verbose);
length += printf("; switch: ");
length += rtems_monitor_symbol_dump(&monitor_extension->tswitch, verbose);
length += printf("; begin: ");
length += rtems_monitor_symbol_dump(&monitor_extension->begin, verbose);
length += printf("\n");
length = 0;
length += rtems_monitor_pad(18, length);
length += printf("exitted: ");
length += rtems_monitor_symbol_dump(&monitor_extension->exitted, verbose);
length += printf("; fatal: ");
length += rtems_monitor_symbol_dump(&monitor_extension->fatal, verbose);
length += printf("\n");
length = 0;
printf("\n");
}

View File

@@ -0,0 +1,117 @@
/*
* @(#)itask.c 1.4 - 95/08/02
*
*
* RTEMS Monitor init task support
*
* $Id$
*/
#include <rtems.h>
#include "monitor.h"
#include <stdio.h>
/*
* As above, but just for init tasks
*/
void
rtems_monitor_init_task_canonical(
rtems_monitor_init_task_t *canonical_itask,
void *itask_void
)
{
rtems_initialization_tasks_table *rtems_itask = itask_void;
rtems_monitor_symbol_canonical_by_value(&canonical_itask->entry,
rtems_itask->entry_point);
canonical_itask->argument = rtems_itask->argument;
canonical_itask->stack_size = rtems_itask->stack_size;
canonical_itask->priority = rtems_itask->initial_priority;
canonical_itask->modes = rtems_itask->mode_set;
canonical_itask->attributes = rtems_itask->attribute_set;
}
void *
rtems_monitor_init_task_next(
void *object_info,
rtems_monitor_init_task_t *canonical_init_task,
rtems_id *next_id
)
{
rtems_configuration_table *c = _Configuration_Table;
rtems_initialization_tasks_table *itask;
int n = rtems_get_index(*next_id);
if (n >= c->number_of_initialization_tasks)
goto failed;
_Thread_Disable_dispatch();
itask = c->User_initialization_tasks_table + n;
/*
* dummy up a fake id and name for this item
*/
canonical_init_task->id = n;
canonical_init_task->name = itask->name;
*next_id += 1;
return (void *) itask;
failed:
*next_id = RTEMS_OBJECT_ID_FINAL;
return 0;
}
void
rtems_monitor_init_task_dump_header(
boolean verbose
)
{
printf("\
# NAME ENTRY ARGUMENT PRIO MODES ATTRIBUTES STACK SIZE\n");
/*23456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789
0 1 2 3 4 5 6 7 */
rtems_monitor_separator();
}
/*
*/
void
rtems_monitor_init_task_dump(
rtems_monitor_init_task_t *monitor_itask,
boolean verbose
)
{
int length = 0;
length += rtems_monitor_dump_decimal(monitor_itask->id);
length += rtems_monitor_pad(7, length);
length += rtems_monitor_dump_name(monitor_itask->name);
length += rtems_monitor_pad(14, length);
length += rtems_monitor_symbol_dump(&monitor_itask->entry, verbose);
length += rtems_monitor_pad(25, length);
length += printf("%d [0x%x]", monitor_itask->argument, monitor_itask->argument);
length += rtems_monitor_pad(39, length);
length += rtems_monitor_dump_priority(monitor_itask->priority);
length += rtems_monitor_pad(46, length);
length += rtems_monitor_dump_modes(monitor_itask->modes);
length += rtems_monitor_pad(54, length);
length += rtems_monitor_dump_attributes(monitor_itask->attributes);
length += rtems_monitor_pad(66, length);
length += printf("%d [0x%x]", monitor_itask->stack_size, monitor_itask->stack_size);
printf("\n");
}

View File

@@ -0,0 +1,52 @@
/*
* @(#)manager.c 1.2 - 95/07/31
*
*
* RTEMS Monitor "manager" support.
* Used to traverse object (chain) lists and print them out.
* $Id$
*/
#include <rtems.h>
#include "monitor.h"
#include <stdio.h>
#include <monitor.h>
/*
* "next" routine for all objects that are RTEMS manager objects
*/
void *
rtems_monitor_manager_next(
void *table_void,
void *canonical,
rtems_id *next_id
)
{
Objects_Information *table = table_void;
rtems_monitor_generic_t *copy;
Objects_Control *object = 0;
unsigned32 location;
/*
* When we are called, it must be local
*/
if ( ! _Objects_Is_local_id(*next_id))
goto done;
object = _Objects_Get_next(table, *next_id, &location, next_id);
if (object)
{
copy = (rtems_monitor_generic_t *) canonical;
copy->id = object->id;
copy->name = table->name_table[rtems_get_index(copy->id)];
}
done:
return object;
}

View File

@@ -1,125 +1,239 @@
/*
* @(#)monitor.c 1.6 - 95/04/24
* @(#)monitor.c 1.18 - 95/08/02
*
*/
/*
* mon-task.c
*
* Description:
* RTEMS monitor task
*
*
* RTEMS monitor main body
*
* TODO:
* add pause command (monitor sleeps for 'n' ticks, then wakes up)
*
* add stuff to RTEMS api
* rtems_get_name(id)
* rtems_get_type(id)
* rtems_build_id(node, type, num)
* Add a command to dump out info about an arbitrary id when
* types are added to id's
* rtems> id idnum
* idnum: node n, object: whatever, id: whatever
* allow id's to be specified as n:t:id, where 'n:t' is optional
* should have a separate monitor FILE stream (ala the debugger)
* remote request/response stuff should be cleaned up
* maybe we can use real rpc??
*
* $Id$
*/
#include <rtems.h>
/* #include <bsp.h> */
#include "symbols.h"
#include "monitor.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#define STREQ(a,b) (strcmp(a,b) == 0)
#include "monitor.h"
/* set by trap handler */
extern rtems_tcb *debugger_interrupted_task;
extern rtems_context *debugger_interrupted_task_context;
extern rtems_unsigned32 debugger_trap;
/* our task id needs to be public so any debugger can resume us */
rtems_unsigned32 rtems_monitor_task_id;
/*
* Various id's for the monitor
* They need to be public variables for access by other agencies
* such as debugger and remote servers'
*/
rtems_id rtems_monitor_task_id;
unsigned32 rtems_monitor_node; /* our node number */
unsigned32 rtems_monitor_default_node; /* current default for commands */
/*
* The rtems symbol table
*/
rtems_symbol_table_t *rtems_monitor_symbols;
/*
* The top-level commands
*/
#ifndef MONITOR_PROMPT
#define MONITOR_PROMPT "rtems> "
rtems_monitor_command_entry_t rtems_monitor_commands[] = {
{ "--usage--",
"\n"
"RTEMS monitor\n"
"\n"
"Commands (may be abbreviated)\n"
"\n"
" help -- get this message or command specific help\n"
" pause -- pause monitor for a specified number of ticks\n"
" exit -- invoke a fatal RTEMS error\n"
" symbol -- show entries from symbol table\n"
" continue -- put monitor to sleep waiting for explicit wakeup\n"
" config -- show system configuration\n"
" itask -- list init tasks\n"
" mpci -- list mpci config\n"
" task -- show task information\n"
" queue -- show message queue information\n"
" extension -- user extensions\n"
" driver -- show information about named drivers\n"
" object -- generic object information\n"
" node -- specify default node for commands that take id's\n"
#ifdef CPU_INVOKE_DEBUGGER
" debugger -- invoke system debugger\n"
#endif
,
0,
0,
(unsigned32) rtems_monitor_commands,
},
{ "config",
"config\n"
" Show the system configuration.\n",
0,
rtems_monitor_object_cmd,
RTEMS_OBJECT_CONFIG,
},
{ "itask",
"itask\n"
" List init tasks for the system\n",
0,
rtems_monitor_object_cmd,
RTEMS_OBJECT_INIT_TASK,
},
{ "mpci",
"mpci\n"
" Show the MPCI system configuration, if configured.\n",
0,
rtems_monitor_object_cmd,
RTEMS_OBJECT_MPCI,
},
{ "pause",
"pause [ticks]\n"
" monitor goes to \"sleep\" for specified ticks (default is 1)\n"
" monitor will resume at end of period or if explicitly awakened\n",
0,
rtems_monitor_pause_cmd,
0,
},
{ "continue",
"continue\n"
" put the monitor to sleep waiting for an explicit wakeup from the\n"
" program running.\n",
0,
rtems_monitor_continue_cmd,
0,
},
{ "go",
"go\n"
" Alias for 'continue'\n",
0,
rtems_monitor_continue_cmd,
0,
},
{ "node",
"node [ node number ]\n"
" Specify default node number for commands that take id's\n",
0,
rtems_monitor_node_cmd,
0,
},
{ "symbol",
"symbol [ symbolname [symbolname ... ] ]\n"
" display value associated with specified symbol.\n"
" Defaults to displaying all known symbols.\n",
0,
rtems_monitor_symbol_cmd,
(unsigned32) &rtems_monitor_symbols,
},
{ "extension",
"extension [id [id ...] ]\n"
" display information about specified extensions.\n"
" Default is to display information about all extensions on this node\n",
0,
rtems_monitor_object_cmd,
RTEMS_OBJECT_EXTENSION,
},
{ "task",
"task [id [id ...] ]\n"
" display information about the specified tasks.\n"
" Default is to display information about all tasks on this node\n",
0,
rtems_monitor_object_cmd,
RTEMS_OBJECT_TASK,
},
{ "queue",
"queue [id [id ... ] ]\n"
" display information about the specified message queues\n"
" Default is to display information about all queues on this node\n",
0,
rtems_monitor_object_cmd,
RTEMS_OBJECT_QUEUE,
},
{ "object",
"object [id [id ...] ]\n"
" display information about specified RTEMS objects.\n"
" Object id's must include 'type' information.\n"
" (which may normally be defaulted)\n",
0,
rtems_monitor_object_cmd,
RTEMS_OBJECT_INVALID,
},
{ "driver",
"driver [ major [ major ... ] ]\n"
" Display the RTEMS device driver table.\n",
0,
rtems_monitor_object_cmd,
RTEMS_OBJECT_DRIVER,
},
{ "dname",
"dname\n"
" Displays information about named drivers.\n",
0,
rtems_monitor_object_cmd,
RTEMS_OBJECT_DNAME,
},
{ "exit",
"exit [status]\n"
" Invoke 'rtems_fatal_error_occurred' with 'status'\n"
" (default is RTEMS_SUCCESSFUL)\n",
0,
rtems_monitor_fatal_cmd,
RTEMS_SUCCESSFUL,
},
{ "fatal",
"fatal [status]\n"
" 'exit' with fatal error; default error is RTEMS_TASK_EXITTED\n",
0,
rtems_monitor_fatal_cmd,
RTEMS_TASK_EXITTED, /* exit value */
},
{ "quit",
"quit [status]\n"
" Alias for 'exit'\n",
0,
rtems_monitor_fatal_cmd,
RTEMS_SUCCESSFUL, /* exit value */
},
{ "help",
"help [ command [ command ] ]\n"
" provide information about commands\n"
" Default is show basic command summary.\n",
0,
rtems_monitor_help_cmd,
(unsigned32) rtems_monitor_commands,
},
#ifdef CPU_INVOKE_DEBUGGER
{ "debugger",
"debugger\n"
" Enter the debugger, if possible.\n"
" A continue from the debugger will return to the monitor.\n",
0,
CPU_INVOKE_DEBUGGER,
0,
},
#endif
{ 0, 0, 0, 0, 0 },
};
#define MONITOR_WAKEUP_EVENT RTEMS_EVENT_0
/*
* Function: rtems_monitor_init
*
* Description:
* Create the RTEMS monitor task
*
* Parameters:
* 'monitor_suspend' arg is passed as initial arg to monitor task
* If TRUE, monitor will suspend itself as it starts up. Otherwise
* it will begin its command loop.
*
* Returns:
*
*
* Side Effects:
*
*
* Notes:
*
*
* Deficiencies/ToDo:
*
*
*/
/*
* make_argv(cp): token-count
* Break up the command line in 'cp' into global argv[] and argc (return
* value).
*/
int
rtems_monitor_make_argv(
char *cp,
int *argc_p,
char **argv)
{
int argc = 0;
while ((cp = strtok(cp, " \t\n\r")))
{
argv[argc++] = cp;
cp = (char *) NULL;
}
argv[argc] = (char *) NULL; /* end of argv */
return *argc_p = argc;
}
void
rtems_monitor_init(rtems_boolean monitor_suspend)
{
rtems_status_code status;
status = rtems_task_create(rtems_build_name('R', 'M', 'O', 'N'),
1, 0/*stack*/, RTEMS_NO_PREEMPT | RTEMS_INTERRUPT_LEVEL(0), RTEMS_DEFAULT_ATTRIBUTES, &rtems_monitor_task_id);
if (status != RTEMS_SUCCESSFUL)
{
printf("could not create monitor task\n");
goto done;
}
rtems_monitor_symbols_loadup();
status = rtems_task_start(rtems_monitor_task_id, rtems_monitor_task, monitor_suspend);
if (status != RTEMS_SUCCESSFUL)
{
printf("could not start monitor!\n");
goto done;
}
done:
}
rtems_status_code
rtems_monitor_suspend(rtems_interval timeout)
@@ -127,7 +241,10 @@ rtems_monitor_suspend(rtems_interval timeout)
rtems_event_set event_set;
rtems_status_code status;
status = rtems_event_receive(MONITOR_WAKEUP_EVENT, RTEMS_DEFAULT_OPTIONS, timeout, &event_set);
status = rtems_event_receive(MONITOR_WAKEUP_EVENT,
RTEMS_DEFAULT_OPTIONS,
timeout,
&event_set);
return status;
}
@@ -140,93 +257,76 @@ rtems_monitor_wakeup(void)
}
/*
* Read and break up a monitor command
*
* We have to loop on the gets call, since it will return NULL under UNIX
* RTEMS when we get a signal (eg: SIGALRM).
*/
int
rtems_monitor_read_command(char *command,
int *argc,
char **argv)
void
rtems_monitor_pause_cmd(
int argc,
char **argv,
unsigned32 command_arg,
boolean verbose
)
{
printf("%s", MONITOR_PROMPT); fflush(stdout);
while (gets(command) == (char *) 0)
;
return rtems_monitor_make_argv(command, argc, argv);
if (argc == 1)
rtems_monitor_suspend(1);
else
rtems_monitor_suspend(strtoul(argv[1], 0, 0));
}
void
rtems_monitor_task(rtems_task_argument monitor_suspend)
rtems_monitor_fatal_cmd(
int argc,
char **argv,
unsigned32 command_arg,
boolean verbose
)
{
rtems_tcb *debugee = 0;
char command[513];
rtems_context *rp;
rtems_context_fp *fp;
char *cp;
int argc;
char *argv[64];
if ((rtems_boolean) monitor_suspend)
(void) rtems_monitor_suspend(RTEMS_NO_TIMEOUT);
for (;;)
{
extern rtems_tcb * _Thread_Executing;
debugee = _Thread_Executing;
rp = &debugee->Registers;
fp = (rtems_context_fp *) debugee->fp_context; /* possibly 0 */
if (0 == rtems_monitor_read_command(command, &argc, argv))
continue;
if (STREQ(argv[0], "quit"))
rtems_monitor_suspend(RTEMS_NO_TIMEOUT);
else if (STREQ(argv[0], "pause"))
rtems_monitor_suspend(1);
#ifdef CPU_INVOKE_DEBUGGER
else if (STREQ(argv[0], "debug"))
{
CPU_INVOKE_DEBUGGER;
}
#endif
else if (STREQ(argv[0], "symbol"))
{
char *symbol;
char *value;
if (argc != 3)
{
printf("usage: symbol symname symvalue\n");
continue;
}
symbol = argv[1];
value = argv[2];
if (symbol && value)
{
rtems_symbol_t *sp;
sp = rtems_symbol_create(rtems_monitor_symbols,
symbol,
(rtems_unsigned32) strtoul(value, 0, 16));
if (sp)
printf("symbol defined is at %p\n", sp);
else
printf("could not define symbol\n");
}
else
printf("parsing error\n");
}
else
{
printf("Unrecognized command: '%s'\n", argv[0]);
}
}
if (argc == 1)
rtems_fatal_error_occurred(command_arg);
else
rtems_fatal_error_occurred(strtoul(argv[1], 0, 0));
}
void
rtems_monitor_continue_cmd(
int argc,
char **argv,
unsigned32 command_arg,
boolean verbose
)
{
rtems_monitor_suspend(RTEMS_NO_TIMEOUT);
}
void
rtems_monitor_node_cmd(
int argc,
char **argv,
unsigned32 command_arg,
boolean verbose
)
{
unsigned32 new_node = rtems_monitor_default_node;
switch (argc)
{
case 1: /* no node, just set back to ours */
new_node = rtems_monitor_node;
break;
case 2:
new_node = strtoul(argv[1], 0, 0);
break;
default:
printf("invalid syntax, try 'help node'\n");
break;
}
if ((new_node >= 1) && (new_node <= _Configuration_MP_table->maximum_nodes))
rtems_monitor_default_node = new_node;
}
/*
* Function: rtems_monitor_symbols_loadup
*
@@ -266,11 +366,19 @@ rtems_monitor_symbols_loadup(void)
FILE *fp;
char buffer[128];
if (rtems_monitor_symbols)
rtems_symbol_table_destroy(rtems_monitor_symbols);
rtems_monitor_symbols = rtems_symbol_table_create(10);
if (rtems_monitor_symbols == 0)
return;
fp = fdopen(8, "r");
#ifdef simhppa
fp = fdopen(8, "r"); /* don't ask; don't tell */
#else
fp = fopen("symbols", "r");
#endif
if (fp == 0)
return;
@@ -292,16 +400,115 @@ rtems_monitor_symbols_loadup(void)
(rtems_unsigned32) strtoul(value, 0, 16));
if (sp == 0)
{
printf("could not define symbol\n");
printf("could not define symbol '%s'\n", symbol);
goto done;
}
}
else
{
printf("parsing error\n");
printf("parsing error on '%s'\n", buffer);
goto done;
}
}
done:
}
/*
* Main monitor command loop
*/
void
rtems_monitor_task(
rtems_task_argument monitor_flags
)
{
rtems_tcb *debugee = 0;
rtems_context *rp;
rtems_context_fp *fp;
char command_buffer[513];
int argc;
char *argv[64];
boolean verbose = FALSE;
if (monitor_flags & RTEMS_MONITOR_SUSPEND)
(void) rtems_monitor_suspend(RTEMS_NO_TIMEOUT);
for (;;)
{
extern rtems_tcb * _Thread_Executing;
rtems_monitor_command_entry_t *command;
debugee = _Thread_Executing;
rp = &debugee->Registers;
fp = (rtems_context_fp *) debugee->fp_context; /* possibly 0 */
if (0 == rtems_monitor_command_read(command_buffer, &argc, argv))
continue;
if ((command = rtems_monitor_command_lookup(rtems_monitor_commands,
argc,
argv)) == 0)
continue;
command->command_function(argc, argv, command->command_arg, verbose);
fflush(stdout);
}
}
void
rtems_monitor_kill(void)
{
if (rtems_monitor_task_id)
rtems_task_delete(rtems_monitor_task_id);
rtems_monitor_task_id = 0;
rtems_monitor_server_kill();
}
void
rtems_monitor_init(
unsigned32 monitor_flags
)
{
rtems_status_code status;
rtems_monitor_kill();
status = rtems_task_create(RTEMS_MONITOR_NAME,
1,
0 /* default stack */,
RTEMS_INTERRUPT_LEVEL(0),
RTEMS_DEFAULT_ATTRIBUTES,
&rtems_monitor_task_id);
if (status != RTEMS_SUCCESSFUL)
{
rtems_error(status, "could not create monitor task");
goto done;
}
rtems_monitor_node = rtems_get_node(rtems_monitor_task_id);
rtems_monitor_default_node = rtems_monitor_node;
rtems_monitor_symbols_loadup();
if (monitor_flags & RTEMS_MONITOR_GLOBAL)
rtems_monitor_server_init(monitor_flags);
/*
* Start the monitor task itself
*/
status = rtems_task_start(rtems_monitor_task_id,
rtems_monitor_task,
monitor_flags);
if (status != RTEMS_SUCCESSFUL)
{
rtems_error(status, "could not start monitor");
goto done;
}
done:
}

View File

@@ -0,0 +1,161 @@
/*
* @(#)mpci.c 1.6 - 95/08/02
*
*
* RTEMS MPCI Config display support
*
* TODO
*
* $Id$
*/
#include <rtems.h>
#include "monitor.h"
#include <stdio.h>
#include <stdlib.h> /* strtoul() */
#define DATACOL 15
/*
* Fill in entire monitor config table
* for sending to a remote monitor or printing on the local system
*/
void
rtems_monitor_mpci_canonical(
rtems_monitor_mpci_t *canonical_mpci,
void *config_void
)
{
rtems_configuration_table *c = _Configuration_Table;
rtems_multiprocessing_table *m;
rtems_mpci_table *mt;
m = c->User_multiprocessing_table;
if (m == 0)
return;
mt = m->User_mpci_table;
canonical_mpci->node = m->node;
canonical_mpci->maximum_nodes = m->maximum_nodes;
canonical_mpci->maximum_global_objects = m->maximum_global_objects;
canonical_mpci->maximum_proxies = m->maximum_proxies;
canonical_mpci->default_timeout = mt->default_timeout;
canonical_mpci->maximum_packet_size = mt->maximum_packet_size;
rtems_monitor_symbol_canonical_by_value(&canonical_mpci->initialization,
mt->initialization);
rtems_monitor_symbol_canonical_by_value(&canonical_mpci->get_packet,
mt->get_packet);
rtems_monitor_symbol_canonical_by_value(&canonical_mpci->return_packet,
mt->return_packet);
rtems_monitor_symbol_canonical_by_value(&canonical_mpci->send_packet,
mt->send_packet);
rtems_monitor_symbol_canonical_by_value(&canonical_mpci->receive_packet,
mt->receive_packet);
}
/*
* This is easy, since there is only 1 (altho we could get them from
* other nodes...)
*/
void *
rtems_monitor_mpci_next(
void *object_info,
rtems_monitor_mpci_t *canonical_mpci,
rtems_id *next_id
)
{
rtems_configuration_table *c = _Configuration_Table;
int n = rtems_get_index(*next_id);
if (n >= 1)
goto failed;
if ( ! c->User_multiprocessing_table)
goto failed;
_Thread_Disable_dispatch();
*next_id += 1;
return (void *) c;
failed:
*next_id = RTEMS_OBJECT_ID_FINAL;
return 0;
}
void
rtems_monitor_mpci_dump_header(
boolean verbose
)
{
printf("\
max max max default max\n\
node nodes globals proxies timeout pktsize\n");
/*23456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789
0 1 2 3 4 5 6 7 */
rtems_monitor_separator();
}
void
rtems_monitor_mpci_dump(
rtems_monitor_mpci_t *monitor_mpci,
boolean verbose
)
{
unsigned32 length = 0;
length += rtems_monitor_pad(2, length);
length += printf(" %d", monitor_mpci->node);
length += rtems_monitor_pad(11, length);
length += printf("%d", monitor_mpci->maximum_nodes);
length += rtems_monitor_pad(18, length);
length += rtems_monitor_dump_decimal(monitor_mpci->maximum_global_objects);
length += rtems_monitor_pad(28, length);
length += rtems_monitor_dump_decimal(monitor_mpci->maximum_proxies);
length += rtems_monitor_pad(37, length);
length += rtems_monitor_dump_decimal(monitor_mpci->default_timeout);
length += rtems_monitor_pad(46, length);
length += rtems_monitor_dump_decimal(monitor_mpci->maximum_packet_size);
printf("\n");
length = 0;
length += rtems_monitor_pad(DATACOL, length);
length += printf("init: ");
length += rtems_monitor_symbol_dump(&monitor_mpci->initialization, verbose);
printf("\n");
length = 0;
length += rtems_monitor_pad(DATACOL, length);
length += printf("get: ");
length += rtems_monitor_symbol_dump(&monitor_mpci->get_packet, verbose);
length += printf("; return: ");
length += rtems_monitor_symbol_dump(&monitor_mpci->return_packet, verbose);
printf("\n");
length = 0;
length += rtems_monitor_pad(DATACOL, length);
length += printf("send: ");
length += rtems_monitor_symbol_dump(&monitor_mpci->send_packet, verbose);
length += printf("; receive: ");
length += rtems_monitor_symbol_dump(&monitor_mpci->receive_packet, verbose);
printf("\n");
length = 0;
}

View File

@@ -0,0 +1,376 @@
/*
* @(#)object.c 1.7 - 95/08/02
*
*
* RTEMS Monitor "object" support.
*
* Used to traverse object lists and print them out.
* An object can be an RTEMS object (chain based stuff) or
* a "misc" object such as a device driver.
*
* Each object has its own file in this directory (eg: extension.c)
* That file provides routines to convert a "native" structure
* to its canonical form, print a canonical structure, etc.
*
* TODO:
* should allow for non-numeric id's???
*
* $Id$
*/
#include <rtems.h>
#include "monitor.h"
#include <stdio.h>
#include <stdlib.h> /* strtoul() */
#include <monitor.h>
#define NUMELEMS(arr) (sizeof(arr) / sizeof(arr[0]))
/*
* add:
* next
*/
rtems_monitor_object_info_t rtems_monitor_object_info[] =
{
{ RTEMS_OBJECT_CONFIG,
(void *) 0,
sizeof(rtems_monitor_config_t),
(rtems_monitor_object_next_fn) rtems_monitor_config_next,
(rtems_monitor_object_canonical_fn) rtems_monitor_config_canonical,
(rtems_monitor_object_dump_header_fn) rtems_monitor_config_dump_header,
(rtems_monitor_object_dump_fn) rtems_monitor_config_dump,
},
{ RTEMS_OBJECT_MPCI,
(void *) 0,
sizeof(rtems_monitor_mpci_t),
(rtems_monitor_object_next_fn) rtems_monitor_mpci_next,
(rtems_monitor_object_canonical_fn) rtems_monitor_mpci_canonical,
(rtems_monitor_object_dump_header_fn) rtems_monitor_mpci_dump_header,
(rtems_monitor_object_dump_fn) rtems_monitor_mpci_dump,
},
{ RTEMS_OBJECT_INIT_TASK,
(void *) 0,
sizeof(rtems_monitor_init_task_t),
(rtems_monitor_object_next_fn) rtems_monitor_init_task_next,
(rtems_monitor_object_canonical_fn) rtems_monitor_init_task_canonical,
(rtems_monitor_object_dump_header_fn) rtems_monitor_init_task_dump_header,
(rtems_monitor_object_dump_fn) rtems_monitor_init_task_dump,
},
{ RTEMS_OBJECT_TASK,
(void *) &_Thread_Information,
sizeof(rtems_monitor_task_t),
(rtems_monitor_object_next_fn) rtems_monitor_manager_next,
(rtems_monitor_object_canonical_fn) rtems_monitor_task_canonical,
(rtems_monitor_object_dump_header_fn) rtems_monitor_task_dump_header,
(rtems_monitor_object_dump_fn) rtems_monitor_task_dump,
},
{ RTEMS_OBJECT_QUEUE,
(void *) &_Message_queue_Information,
sizeof(rtems_monitor_queue_t),
(rtems_monitor_object_next_fn) rtems_monitor_manager_next,
(rtems_monitor_object_canonical_fn) rtems_monitor_queue_canonical,
(rtems_monitor_object_dump_header_fn) rtems_monitor_queue_dump_header,
(rtems_monitor_object_dump_fn) rtems_monitor_queue_dump,
},
{ RTEMS_OBJECT_EXTENSION,
(void *) &_Extension_Information,
sizeof(rtems_monitor_extension_t),
(rtems_monitor_object_next_fn) rtems_monitor_manager_next,
(rtems_monitor_object_canonical_fn) rtems_monitor_extension_canonical,
(rtems_monitor_object_dump_header_fn) rtems_monitor_extension_dump_header,
(rtems_monitor_object_dump_fn) rtems_monitor_extension_dump,
},
{ RTEMS_OBJECT_DRIVER,
(void *) 0,
sizeof(rtems_monitor_driver_t),
(rtems_monitor_object_next_fn) rtems_monitor_driver_next,
(rtems_monitor_object_canonical_fn) rtems_monitor_driver_canonical,
(rtems_monitor_object_dump_header_fn) rtems_monitor_driver_dump_header,
(rtems_monitor_object_dump_fn) rtems_monitor_driver_dump,
},
{ RTEMS_OBJECT_DNAME,
(void *) &rtems_driver_name_table[0],
sizeof(rtems_monitor_dname_t),
(rtems_monitor_object_next_fn) rtems_monitor_dname_next,
(rtems_monitor_object_canonical_fn) rtems_monitor_dname_canonical,
(rtems_monitor_object_dump_header_fn) rtems_monitor_dname_dump_header,
(rtems_monitor_object_dump_fn) rtems_monitor_dname_dump,
},
};
/*
* Allow id's to be specified without the node number or
* type for convenience.
*/
rtems_id
rtems_monitor_id_fixup(
rtems_id id,
unsigned32 default_node,
rtems_object_type_t type
)
{
unsigned32 node;
node = rtems_get_node(id);
if (node == 0)
{
#if 0
/* XXX Uncomment this when types are added to id's */
if (rtems_get_type(id) != RTEMS_OBJECT_INVALID)
type = rtems_get_type(id);
id = _Objects_Build_id(type, default_node, rtems_get_index(id));
#else
id = _Objects_Build_id(default_node, rtems_get_index(id));
#endif
}
return id;
}
rtems_monitor_object_info_t *
rtems_monitor_object_lookup(
rtems_object_type_t type
)
{
rtems_monitor_object_info_t *p;
for (p = &rtems_monitor_object_info[0];
p < &rtems_monitor_object_info[NUMELEMS(rtems_monitor_object_info)];
p++)
{
if (p->type == type)
return p;
}
return 0;
}
rtems_id
rtems_monitor_object_canonical_next_remote(
rtems_object_type_t type,
rtems_id id,
void *canonical
)
{
rtems_id next_id;
rtems_status_code status;
rtems_monitor_server_request_t request;
rtems_monitor_server_response_t response;
/*
* Send request
*/
request.command = RTEMS_MONITOR_SERVER_CANONICAL;
request.argument0 = (unsigned32) type;
request.argument1 = (unsigned32) id;
status = rtems_monitor_server_request(rtems_get_node(id), &request, &response);
if (status != RTEMS_SUCCESSFUL)
goto failed;
/*
* process response
*/
next_id = (rtems_id) response.result0;
if (next_id != RTEMS_OBJECT_ID_FINAL)
(void) memcpy(canonical, &response.payload, response.result1);
return next_id;
failed:
return RTEMS_OBJECT_ID_FINAL;
}
rtems_id
rtems_monitor_object_canonical_next(
rtems_monitor_object_info_t *info,
rtems_id id,
void *canonical
)
{
rtems_id next_id;
void *raw_item;
if ( ! _Objects_Is_local_id(id))
next_id = rtems_monitor_object_canonical_next_remote(info->type,
id,
canonical);
else
{
next_id = id;
raw_item = (void *) info->next(info->object_information,
canonical,
&next_id);
if (raw_item)
{
info->canonical(canonical, raw_item);
_Thread_Enable_dispatch();
}
}
return next_id;
}
/*
* this is routine server invokes locally to get the type
*/
rtems_id
rtems_monitor_object_canonical_get(
rtems_object_type_t type,
rtems_id id,
void *canonical,
unsigned32 *size_p
)
{
rtems_monitor_object_info_t *info;
rtems_id next_id;
*size_p = 0;
info = rtems_monitor_object_lookup(type);
if (info == 0)
return RTEMS_OBJECT_ID_FINAL;
next_id = rtems_monitor_object_canonical_next(info, id, canonical);
*size_p = info->size;
return next_id;
}
void
rtems_monitor_object_dump_1(
rtems_monitor_object_info_t *info,
rtems_id id,
boolean verbose
)
{
rtems_id next_id;
rtems_monitor_union_t canonical;
if ((next_id = rtems_monitor_object_canonical_next(
info,
id,
&canonical)) != RTEMS_OBJECT_ID_FINAL)
{
/*
* If the one we actually got is the one we wanted, then
* print it out.
* For ones that have an id field, this works fine,
* for all others, always dump it out.
*
* HACK: the way we determine whether there is an id is a hack.
*
* by the way: the reason we try to not have an id, is that some
* of the canonical structures are almost too big for shared
* memory driver (eg: mpci)
*/
if ((info->next != rtems_monitor_manager_next) ||
(id == canonical.generic.id))
info->dump(&canonical, verbose);
}
}
void
rtems_monitor_object_dump_all(
rtems_monitor_object_info_t *info,
boolean verbose
)
{
rtems_id next_id;
rtems_monitor_union_t canonical;
next_id = RTEMS_OBJECT_ID_INITIAL(rtems_monitor_default_node);
while ((next_id = rtems_monitor_object_canonical_next(
info,
next_id,
&canonical)) != RTEMS_OBJECT_ID_FINAL)
{
info->dump(&canonical, verbose);
}
}
void
rtems_monitor_object_cmd(
int argc,
char **argv,
unsigned32 command_arg,
boolean verbose
)
{
int arg;
rtems_monitor_object_info_t *info = 0;
rtems_object_type_t type = (rtems_object_type_t) command_arg;
/* what is the default type? */
type = (rtems_object_type_t) command_arg;
if (argc == 1)
{
if (type == RTEMS_OBJECT_INVALID)
{
printf("A type must be specified to \"dump all\"\n");
goto done;
}
info = rtems_monitor_object_lookup(type);
if (info == 0)
goto not_found;
if (info->dump_header)
info->dump_header(verbose);
rtems_monitor_object_dump_all(info, verbose);
}
else
{
unsigned32 default_node = rtems_monitor_default_node;
rtems_object_type_t last_type = RTEMS_OBJECT_INVALID;
rtems_id id;
for (arg=1; argv[arg]; arg++)
{
id = (rtems_id) strtoul(argv[arg], 0, 0);
id = rtems_monitor_id_fixup(id, default_node, type);
#if 0
type = rtems_get_type(id);
#endif
/*
* Allow the item type to change in the middle
* of the command. If the type changes, then
* just dump out a new header and keep on going.
*/
if (type != last_type)
{
info = rtems_monitor_object_lookup(type);
if (info == 0)
{
not_found: printf("Invalid or unsupported type %d\n", type);
goto done;
}
if (info->dump_header)
info->dump_header(verbose);
}
rtems_monitor_object_dump_1(info, id, verbose);
default_node = rtems_get_node(id);
last_type = type;
}
}
done:
}

View File

@@ -0,0 +1,257 @@
/*
* @(#)prmisc.c 1.9 - 95/08/02
*
*
* Print misc stuff for the monitor dump routines
* Each routine returns the number of characters it output.
*
* TODO:
*
* $Id$
*/
#include <rtems.h>
#include "monitor.h"
#include <rtems/assoc.h>
#include <stdio.h>
#include <ctype.h>
void
rtems_monitor_separator(void)
{
printf("------------------------------------------------------------------------------\n");
}
unsigned32
rtems_monitor_pad(
unsigned32 destination_column,
unsigned32 current_column
)
{
int pad_length;
if (destination_column <= current_column)
pad_length = 1;
else
pad_length = destination_column - current_column;
return printf("%*s", pad_length, "");
}
unsigned32
rtems_monitor_dump_char(rtems_unsigned8 ch)
{
if (isprint(ch))
return printf("%c", ch);
else
return printf("%02x", ch);
}
unsigned32
rtems_monitor_dump_decimal(unsigned32 num)
{
return printf("%4d", num);
}
unsigned32
rtems_monitor_dump_hex(unsigned32 num)
{
return printf("0x%x", num);
}
unsigned32
rtems_monitor_dump_assoc_bitfield(
rtems_assoc_t *ap,
char *separator,
unsigned32 value
)
{
unsigned32 b;
unsigned32 length = 0;
char *name;
for (b = 1; b; b <<= 1)
if (b & value)
{
if (length)
length += printf("%s", separator);
name = rtems_assoc_name_by_local(ap, b);
if (name)
length += printf("%s", name);
else
length += printf("0x%x", b);
}
return length;
}
unsigned32
rtems_monitor_dump_id(rtems_id id)
{
return printf("%08x", id);
}
unsigned32
rtems_monitor_dump_name(rtems_name name)
{
int i;
unsigned32 length = 0;
union {
unsigned32 ui;
char c[4];
} u;
u.ui = (rtems_unsigned32) name;
for (i=0; i<sizeof(u.c); i++)
length += rtems_monitor_dump_char(u.c[i]);
return length;
}
unsigned32
rtems_monitor_dump_priority(rtems_task_priority priority)
{
return printf("%3d", priority);
}
rtems_assoc_t rtems_monitor_state_assoc[] = {
{ "DORM", STATES_DORMANT },
{ "SUSP", STATES_SUSPENDED },
{ "TRANS", STATES_TRANSIENT },
{ "DELAY", STATES_DELAYING },
{ "Wbuf", STATES_WAITING_FOR_BUFFER },
{ "Wseg", STATES_WAITING_FOR_SEGMENT },
{ "Wmsg" , STATES_WAITING_FOR_MESSAGE },
{ "Wevnt", STATES_WAITING_FOR_EVENT },
{ "Wsem", STATES_WAITING_FOR_SEMAPHORE },
{ "Wtime", STATES_WAITING_FOR_TIME },
{ "Wrpc", STATES_WAITING_FOR_RPC_REPLY },
{ "WRATE", STATES_WAITING_FOR_PERIOD },
{ 0, 0, 0 },
};
unsigned32
rtems_monitor_dump_state(States_Control state)
{
unsigned32 length = 0;
if (state == STATES_READY) /* assoc doesn't deal with this as it is 0 */
length += printf("READY");
length += rtems_monitor_dump_assoc_bitfield(rtems_monitor_state_assoc,
":",
state);
return length;
}
rtems_assoc_t rtems_monitor_attribute_assoc[] = {
{ "FL", RTEMS_FLOATING_POINT },
{ "GL", RTEMS_GLOBAL },
{ "PR", RTEMS_PRIORITY },
{ "BI", RTEMS_BINARY_SEMAPHORE },
{ "IN", RTEMS_INHERIT_PRIORITY },
{ 0, 0, 0 },
};
unsigned32
rtems_monitor_dump_attributes(rtems_attribute attributes)
{
unsigned32 length = 0;
if (attributes == RTEMS_DEFAULT_ATTRIBUTES) /* value is 0 */
length += printf("DEFAULT");
length += rtems_monitor_dump_assoc_bitfield(rtems_monitor_attribute_assoc,
":",
attributes);
return length;
}
rtems_assoc_t rtems_monitor_modes_assoc[] = {
{ "nP", RTEMS_NO_PREEMPT },
{ "T", RTEMS_TIMESLICE },
{ "nA", RTEMS_NO_ASR },
{ 0, 0, 0 },
};
unsigned32
rtems_monitor_dump_modes(rtems_mode modes)
{
unsigned32 length = 0;
if (modes == RTEMS_DEFAULT_MODES) /* value is 0 */
length += printf("P:T:nA");
length += rtems_monitor_dump_assoc_bitfield(rtems_monitor_modes_assoc,
":",
modes);
return length;
}
rtems_assoc_t rtems_monitor_events_assoc[] = {
{ "0", RTEMS_EVENT_0 },
{ "1", RTEMS_EVENT_1 },
{ "2", RTEMS_EVENT_2 },
{ "3", RTEMS_EVENT_3 },
{ "4", RTEMS_EVENT_4 },
{ "5", RTEMS_EVENT_5 },
{ "6", RTEMS_EVENT_6 },
{ "7", RTEMS_EVENT_7 },
{ "8", RTEMS_EVENT_8 },
{ "9", RTEMS_EVENT_9 },
{ "10", RTEMS_EVENT_10 },
{ "11", RTEMS_EVENT_11 },
{ "12", RTEMS_EVENT_12 },
{ "13", RTEMS_EVENT_13 },
{ "14", RTEMS_EVENT_14 },
{ "15", RTEMS_EVENT_15 },
{ "16", RTEMS_EVENT_16 },
{ "17", RTEMS_EVENT_17 },
{ "18", RTEMS_EVENT_18 },
{ "19", RTEMS_EVENT_19 },
{ "20", RTEMS_EVENT_20 },
{ "21", RTEMS_EVENT_21 },
{ "22", RTEMS_EVENT_22 },
{ "23", RTEMS_EVENT_23 },
{ "24", RTEMS_EVENT_24 },
{ "25", RTEMS_EVENT_25 },
{ "26", RTEMS_EVENT_26 },
{ "27", RTEMS_EVENT_27 },
{ "28", RTEMS_EVENT_28 },
{ "29", RTEMS_EVENT_29 },
{ "30", RTEMS_EVENT_30 },
{ "31", RTEMS_EVENT_31 },
{ 0, 0, 0 },
};
unsigned32
rtems_monitor_dump_events(rtems_event_set events)
{
unsigned32 length = 0;
if (events == EVENT_SETS_NONE_PENDING) /* value is 0 */
length += printf("NONE");
length += rtems_monitor_dump_assoc_bitfield(rtems_monitor_events_assoc,
":",
events);
return length;
}
unsigned32
rtems_monitor_dump_notepad(unsigned32 *notepad)
{
unsigned32 length = 0;
int i;
for (i=0; i < RTEMS_NUMBER_NOTEPADS; i++)
if (notepad[i])
length += printf("%d: 0x%x ", i, notepad[i]);
return length;
}

View File

@@ -0,0 +1,66 @@
/*
* @(#)queue.c 1.5 - 95/07/31
*
* $Id$
*/
#include <rtems.h>
#include "monitor.h"
#include <stdio.h>
void
rtems_monitor_queue_canonical(
rtems_monitor_queue_t *canonical_queue,
void *queue_void
)
{
Message_queue_Control *rtems_queue = (Message_queue_Control *) queue_void;
canonical_queue->attributes = rtems_queue->attribute_set;
canonical_queue->maximum_message_size = rtems_queue->maximum_message_size;
canonical_queue->maximum_pending_messages = rtems_queue->maximum_pending_messages;
canonical_queue->number_of_pending_messages = rtems_queue->number_of_pending_messages;
}
void
rtems_monitor_queue_dump_header(
boolean verbose
)
{
printf("\
ID NAME ATTRIBUTES PEND MAXPEND MAXSIZE\n");
/*23456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789
0 1 2 3 4 5 6 7 */
rtems_monitor_separator();
}
/*
* Dump out the "next" queue indicated by 'id'.
* Returns next one to check.
* Returns RTEMS_OBJECT_ID_FINAL when all done
*/
void
rtems_monitor_queue_dump(
rtems_monitor_queue_t *monitor_queue,
boolean verbose
)
{
unsigned32 length = 0;
length += rtems_monitor_dump_id(monitor_queue->id);
length += rtems_monitor_pad(11, length);
length += rtems_monitor_dump_name(monitor_queue->name);
length += rtems_monitor_pad(19, length);
length += rtems_monitor_dump_attributes(monitor_queue->attributes);
length += rtems_monitor_pad(31, length);
length += rtems_monitor_dump_decimal(monitor_queue->number_of_pending_messages);
length += rtems_monitor_pad(39, length);
length += rtems_monitor_dump_decimal(monitor_queue->maximum_pending_messages);
length += rtems_monitor_pad(48, length);
length += rtems_monitor_dump_decimal(monitor_queue->maximum_message_size);
printf("\n");
}

View File

@@ -0,0 +1,305 @@
/*
* @(#)server.c 1.3 - 95/08/02
*
*
* RTEMS monitor server (handles requests for info from RTEMS monitors
* running on other nodes)
*
* $Id$
*/
#include <rtems.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include "monitor.h"
/*
* Various id's for the server
*/
rtems_id rtems_monitor_server_task_id;
rtems_id rtems_monitor_server_request_queue_id; /* our server */
rtems_id *rtems_monitor_server_request_queue_ids; /* all servers */
rtems_id rtems_monitor_server_response_queue_id; /* our server */
/*
* Send a request to a server task
*/
rtems_status_code
rtems_monitor_server_request(
unsigned32 server_node,
rtems_monitor_server_request_t *request,
rtems_monitor_server_response_t *response
)
{
rtems_id server_id;
rtems_status_code status;
unsigned32 size;
/*
* What is id of monitor on target node?
* Look it up if we don't know it yet.
*/
server_id = rtems_monitor_server_request_queue_ids[server_node];
if (server_id == 0)
{
status = rtems_message_queue_ident(RTEMS_MONITOR_QUEUE_NAME,
server_node,
&server_id);
if (status != RTEMS_SUCCESSFUL)
{
rtems_error(status, "ident of remote server failed");
goto done;
}
rtems_monitor_server_request_queue_ids[server_node] = server_id;
}
request->return_id = rtems_monitor_server_response_queue_id;
status = rtems_message_queue_send(server_id, request, sizeof(*request));
if (status != RTEMS_SUCCESSFUL)
{
rtems_error(status, "monitor server request send failed");
goto done;
}
/*
* Await response, if requested
*/
if (response)
{
status = rtems_message_queue_receive(rtems_monitor_server_response_queue_id,
response,
&size,
RTEMS_WAIT,
100);
if (status != RTEMS_SUCCESSFUL)
{
rtems_error(status, "server did not respond");
/* maybe server task was restarted; look it up again next time */
rtems_monitor_server_request_queue_ids[server_node] = 0;
goto done;
}
if (response->command != RTEMS_MONITOR_SERVER_RESPONSE)
{
status = RTEMS_INCORRECT_STATE;
goto done;
}
}
done:
return status;
}
/*
* monitor server task
*/
void
rtems_monitor_server_task(
rtems_task_argument monitor_flags
)
{
rtems_monitor_server_request_t request;
rtems_monitor_server_response_t response;
rtems_status_code status;
unsigned32 size;
for (;;)
{
status = rtems_message_queue_receive(
rtems_monitor_server_request_queue_id,
&request,
&size,
RTEMS_WAIT,
(rtems_interval) 0);
if (status != RTEMS_SUCCESSFUL)
{
rtems_error(status, "monitor server msg queue receive error");
goto failed;
}
if (size != sizeof(request))
{
rtems_error(0, "monitor server bad size on receive");
goto failed;
}
switch (request.command)
{
case RTEMS_MONITOR_SERVER_CANONICAL:
{
rtems_object_type_t object_type;
rtems_id id;
rtems_id next_id;
object_type = (rtems_object_type_t) request.argument0;
id = (rtems_id) request.argument1;
next_id = rtems_monitor_object_canonical_get(object_type,
id,
&response.payload,
&size);
response.command = RTEMS_MONITOR_SERVER_RESPONSE;
response.result0 = next_id;
response.result1 = size;
#define SERVER_OVERHEAD (RTEMS_offsetof(rtems_monitor_server_response_t, \
payload))
status = rtems_message_queue_send(request.return_id,
&response,
size + SERVER_OVERHEAD);
if (status != RTEMS_SUCCESSFUL)
{
rtems_error(status, "response send failed");
goto failed;
}
break;
}
default:
{
rtems_error(0, "invalid command to monitor server: %d", request.command);
goto failed;
}
}
}
failed:
rtems_task_delete(RTEMS_SELF);
}
/*
* Kill off any old server
* Not sure if this is useful, but it doesn't help
*/
void
rtems_monitor_server_kill(void)
{
if (rtems_monitor_server_task_id)
rtems_task_delete(rtems_monitor_server_task_id);
rtems_monitor_task_id = 0;
if (rtems_monitor_server_request_queue_id)
rtems_message_queue_delete(rtems_monitor_server_request_queue_id);
rtems_monitor_server_response_queue_id = 0;
if (rtems_monitor_server_response_queue_id)
rtems_message_queue_delete(rtems_monitor_server_response_queue_id);
rtems_monitor_server_request_queue_ids = 0;
if (rtems_monitor_server_request_queue_ids)
free(rtems_monitor_server_request_queue_ids);
rtems_monitor_server_request_queue_ids = 0;
}
void
rtems_monitor_server_init(
unsigned32 monitor_flags
)
{
rtems_status_code status;
if (_Configuration_Is_multiprocessing() &&
(_Configuration_MP_table->maximum_nodes > 1))
{
unsigned32 maximum_nodes = _Configuration_MP_table->maximum_nodes;
/*
* create the msg que our server will listen
* Since we only get msgs from other RTEMS monitors, we just
* need reserve space for 1 msg from each node.
*/
status = rtems_message_queue_create(
RTEMS_MONITOR_QUEUE_NAME,
maximum_nodes,
sizeof(rtems_monitor_server_request_t),
RTEMS_GLOBAL,
&rtems_monitor_server_request_queue_id);
if (status != RTEMS_SUCCESSFUL)
{
rtems_error(status, "could not create monitor server message queue");
goto done;
}
/*
* create the msg que our responses will come on
* Since monitor just does one thing at a time, we only need 1 item
* message queue.
*/
status = rtems_message_queue_create(
RTEMS_MONITOR_RESPONSE_QUEUE_NAME,
1, /* depth */
sizeof(rtems_monitor_server_response_t),
RTEMS_GLOBAL,
&rtems_monitor_server_response_queue_id);
if (status != RTEMS_SUCCESSFUL)
{
rtems_error(status, "could not create monitor response message queue");
goto done;
}
/* need an id for queue of each other server we might talk to */
/* indexed by node, so add 1 to maximum_nodes */
rtems_monitor_server_request_queue_ids =
(rtems_id *) malloc((maximum_nodes + 1) * sizeof(rtems_id));
(void) memset(rtems_monitor_server_request_queue_ids,
0,
(maximum_nodes + 1) * sizeof(rtems_id));
rtems_monitor_server_request_queue_ids[rtems_monitor_node] =
rtems_monitor_server_request_queue_id;
/*
* create the server task
*/
status = rtems_task_create(RTEMS_MONITOR_SERVER_NAME,
1,
0 /* default stack */,
RTEMS_INTERRUPT_LEVEL(0),
RTEMS_DEFAULT_ATTRIBUTES,
&rtems_monitor_server_task_id);
if (status != RTEMS_SUCCESSFUL)
{
rtems_error(status, "could not create monitor server task");
goto done;
}
/*
* Start the server task
*/
status = rtems_task_start(rtems_monitor_server_task_id,
rtems_monitor_server_task,
monitor_flags);
if (status != RTEMS_SUCCESSFUL)
{
rtems_error(status, "could not start monitor server");
goto done;
}
}
done:
}

Some files were not shown because too many files have changed in this diff Show More