summaryrefslogtreecommitdiffstats
path: root/cpukit
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>1995-08-17 19:51:51 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>1995-08-17 19:51:51 +0000
commitb06e68ef1f6df69cc86d72356c3a002054a35fad (patch)
tree722b2da3cc83f1cf03019cab8cf895a509eb6801 /cpukit
parent3b438fa4b0284d340b60d865f4afcb76f363bc90 (diff)
downloadrtems-b06e68ef1f6df69cc86d72356c3a002054a35fad.tar.bz2
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
Diffstat (limited to 'cpukit')
-rw-r--r--cpukit/libcsupport/include/clockdrv.h31
-rw-r--r--cpukit/libcsupport/include/rtems/assoc.h44
-rw-r--r--cpukit/libcsupport/include/rtems/error.h26
-rw-r--r--cpukit/libcsupport/include/rtems/libio.h101
-rw-r--r--cpukit/libcsupport/src/assoc.c258
-rw-r--r--cpukit/libcsupport/src/error.c212
-rw-r--r--cpukit/libcsupport/src/libio.c433
-rw-r--r--cpukit/libmisc/monitor/README94
-rw-r--r--cpukit/libmisc/monitor/mon-command.c190
-rw-r--r--cpukit/libmisc/monitor/mon-config.c132
-rw-r--r--cpukit/libmisc/monitor/mon-dname.c113
-rw-r--r--cpukit/libmisc/monitor/mon-driver.c138
-rw-r--r--cpukit/libmisc/monitor/mon-extension.c101
-rw-r--r--cpukit/libmisc/monitor/mon-itask.c117
-rw-r--r--cpukit/libmisc/monitor/mon-manager.c52
-rw-r--r--cpukit/libmisc/monitor/mon-monitor.c545
-rw-r--r--cpukit/libmisc/monitor/mon-mpci.c161
-rw-r--r--cpukit/libmisc/monitor/mon-object.c376
-rw-r--r--cpukit/libmisc/monitor/mon-prmisc.c257
-rw-r--r--cpukit/libmisc/monitor/mon-queue.c66
-rw-r--r--cpukit/libmisc/monitor/mon-server.c305
-rw-r--r--cpukit/libmisc/monitor/mon-symbols.c233
-rw-r--r--cpukit/libmisc/monitor/mon-task.c85
-rw-r--r--cpukit/libmisc/monitor/monitor.h417
-rw-r--r--cpukit/libmisc/monitor/symbols.h15
-rw-r--r--cpukit/rtems/include/rtems/rtems/message.h73
-rw-r--r--cpukit/rtems/include/rtems/rtems/msgmp.h14
-rw-r--r--cpukit/rtems/inline/rtems/rtems/attr.inl13
-rw-r--r--cpukit/rtems/inline/rtems/rtems/message.inl37
-rw-r--r--cpukit/rtems/macros/rtems/rtems/attr.inl9
-rw-r--r--cpukit/sapi/include/rtems/config.h63
-rw-r--r--cpukit/sapi/include/rtems/io.h98
-rw-r--r--cpukit/sapi/src/exinit.c3
-rw-r--r--cpukit/sapi/src/io.c268
-rw-r--r--cpukit/score/include/rtems/score/object.h28
-rw-r--r--cpukit/score/include/rtems/score/thread.h1
-rw-r--r--cpukit/score/include/rtems/system.h7
-rw-r--r--cpukit/score/src/object.c67
38 files changed, 4640 insertions, 543 deletions
diff --git a/cpukit/libcsupport/include/clockdrv.h b/cpukit/libcsupport/include/clockdrv.h
index aad9bd6d3b..258c590e0d 100644
--- a/cpukit/libcsupport/include/clockdrv.h
+++ b/cpukit/libcsupport/include/clockdrv.h
@@ -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
diff --git a/cpukit/libcsupport/include/rtems/assoc.h b/cpukit/libcsupport/include/rtems/assoc.h
new file mode 100644
index 0000000000..c820cfa973
--- /dev/null
+++ b/cpukit/libcsupport/include/rtems/assoc.h
@@ -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 */
diff --git a/cpukit/libcsupport/include/rtems/error.h b/cpukit/libcsupport/include/rtems/error.h
new file mode 100644
index 0000000000..a41f0aa534
--- /dev/null
+++ b/cpukit/libcsupport/include/rtems/error.h
@@ -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;
+
diff --git a/cpukit/libcsupport/include/rtems/libio.h b/cpukit/libcsupport/include/rtems/libio.h
new file mode 100644
index 0000000000..f80a1954a3
--- /dev/null
+++ b/cpukit/libcsupport/include/rtems/libio.h
@@ -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 */
diff --git a/cpukit/libcsupport/src/assoc.c b/cpukit/libcsupport/src/assoc.c
new file mode 100644
index 0000000000..c18359ef8a
--- /dev/null
+++ b/cpukit/libcsupport/src/assoc.c
@@ -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;
+}
diff --git a/cpukit/libcsupport/src/error.c b/cpukit/libcsupport/src/error.c
new file mode 100644
index 0000000000..8cf46f0565
--- /dev/null
+++ b/cpukit/libcsupport/src/error.c
@@ -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);
+}
diff --git a/cpukit/libcsupport/src/libio.c b/cpukit/libcsupport/src/libio.c
new file mode 100644
index 0000000000..ce41643a09
--- /dev/null
+++ b/cpukit/libcsupport/src/libio.c
@@ -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;
+}
diff --git a/cpukit/libmisc/monitor/README b/cpukit/libmisc/monitor/README
index cae39d593c..d5a73da140 100644
--- a/cpukit/libmisc/monitor/README
+++ b/cpukit/libmisc/monitor/README
@@ -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)
diff --git a/cpukit/libmisc/monitor/mon-command.c b/cpukit/libmisc/monitor/mon-command.c
new file mode 100644
index 0000000000..d231b3197a
--- /dev/null
+++ b/cpukit/libmisc/monitor/mon-command.c
@@ -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]);
+ }
+}
diff --git a/cpukit/libmisc/monitor/mon-config.c b/cpukit/libmisc/monitor/mon-config.c
new file mode 100644
index 0000000000..1c3ece086f
--- /dev/null
+++ b/cpukit/libmisc/monitor/mon-config.c
@@ -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);
+}
diff --git a/cpukit/libmisc/monitor/mon-dname.c b/cpukit/libmisc/monitor/mon-dname.c
new file mode 100644
index 0000000000..fd10f3e333
--- /dev/null
+++ b/cpukit/libmisc/monitor/mon-dname.c
@@ -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;
+}
diff --git a/cpukit/libmisc/monitor/mon-driver.c b/cpukit/libmisc/monitor/mon-driver.c
new file mode 100644
index 0000000000..44d94f945c
--- /dev/null
+++ b/cpukit/libmisc/monitor/mon-driver.c
@@ -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;
+}
diff --git a/cpukit/libmisc/monitor/mon-extension.c b/cpukit/libmisc/monitor/mon-extension.c
new file mode 100644
index 0000000000..48dfb96a2d
--- /dev/null
+++ b/cpukit/libmisc/monitor/mon-extension.c
@@ -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");
+}
diff --git a/cpukit/libmisc/monitor/mon-itask.c b/cpukit/libmisc/monitor/mon-itask.c
new file mode 100644
index 0000000000..451f642037
--- /dev/null
+++ b/cpukit/libmisc/monitor/mon-itask.c
@@ -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");
+}
diff --git a/cpukit/libmisc/monitor/mon-manager.c b/cpukit/libmisc/monitor/mon-manager.c
new file mode 100644
index 0000000000..955eaa3b56
--- /dev/null
+++ b/cpukit/libmisc/monitor/mon-manager.c
@@ -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;
+}
+
diff --git a/cpukit/libmisc/monitor/mon-monitor.c b/cpukit/libmisc/monitor/mon-monitor.c
index aa466143f9..5cf80d3ad6 100644
--- a/cpukit/libmisc/monitor/mon-monitor.c
+++ b/cpukit/libmisc/monitor/mon-monitor.c
@@ -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;
-
-
-rtems_symbol_table_t *rtems_monitor_symbols;
-
+/*
+ * Various id's for the monitor
+ * They need to be public variables for access by other agencies
+ * such as debugger and remote servers'
+ */
-#ifndef MONITOR_PROMPT
-#define MONITOR_PROMPT "rtems> "
-#endif
+rtems_id rtems_monitor_task_id;
-#define MONITOR_WAKEUP_EVENT RTEMS_EVENT_0
+unsigned32 rtems_monitor_node; /* our node number */
+unsigned32 rtems_monitor_default_node; /* current default for commands */
/*
- * 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:
- *
- *
+ * The rtems symbol table
*/
+rtems_symbol_table_t *rtems_monitor_symbols;
+
/*
- * make_argv(cp): token-count
- * Break up the command line in 'cp' into global argv[] and argc (return
- * value).
+ * The top-level commands
*/
-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();
+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 },
+};
- 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).
- */
+void
+rtems_monitor_pause_cmd(
+ int argc,
+ char **argv,
+ unsigned32 command_arg,
+ boolean verbose
+)
+{
+ if (argc == 1)
+ rtems_monitor_suspend(1);
+ else
+ rtems_monitor_suspend(strtoul(argv[1], 0, 0));
+}
-int
-rtems_monitor_read_command(char *command,
- int *argc,
- char **argv)
+void
+rtems_monitor_fatal_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_fatal_error_occurred(command_arg);
+ else
+ rtems_fatal_error_occurred(strtoul(argv[1], 0, 0));
}
void
-rtems_monitor_task(rtems_task_argument monitor_suspend)
+rtems_monitor_continue_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];
+ rtems_monitor_suspend(RTEMS_NO_TIMEOUT);
+}
- if ((rtems_boolean) monitor_suspend)
- (void) rtems_monitor_suspend(RTEMS_NO_TIMEOUT);
- for (;;)
+void
+rtems_monitor_node_cmd(
+ int argc,
+ char **argv,
+ unsigned32 command_arg,
+ boolean verbose
+)
+{
+ unsigned32 new_node = rtems_monitor_default_node;
+
+ switch (argc)
{
- 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);
+ case 1: /* no node, just set back to ours */
+ new_node = rtems_monitor_node;
+ break;
-#ifdef CPU_INVOKE_DEBUGGER
- else if (STREQ(argv[0], "debug"))
- {
- CPU_INVOKE_DEBUGGER;
- }
-#endif
- else if (STREQ(argv[0], "symbol"))
- {
- char *symbol;
- char *value;
+ case 2:
+ new_node = strtoul(argv[1], 0, 0);
+ break;
- 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]);
- }
+ 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:
+}
diff --git a/cpukit/libmisc/monitor/mon-mpci.c b/cpukit/libmisc/monitor/mon-mpci.c
new file mode 100644
index 0000000000..99dcea3bf8
--- /dev/null
+++ b/cpukit/libmisc/monitor/mon-mpci.c
@@ -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;
+}
diff --git a/cpukit/libmisc/monitor/mon-object.c b/cpukit/libmisc/monitor/mon-object.c
new file mode 100644
index 0000000000..5add90763e
--- /dev/null
+++ b/cpukit/libmisc/monitor/mon-object.c
@@ -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:
+}
diff --git a/cpukit/libmisc/monitor/mon-prmisc.c b/cpukit/libmisc/monitor/mon-prmisc.c
new file mode 100644
index 0000000000..0a9f9bdf2e
--- /dev/null
+++ b/cpukit/libmisc/monitor/mon-prmisc.c
@@ -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;
+}
diff --git a/cpukit/libmisc/monitor/mon-queue.c b/cpukit/libmisc/monitor/mon-queue.c
new file mode 100644
index 0000000000..d09ac7a337
--- /dev/null
+++ b/cpukit/libmisc/monitor/mon-queue.c
@@ -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");
+}
diff --git a/cpukit/libmisc/monitor/mon-server.c b/cpukit/libmisc/monitor/mon-server.c
new file mode 100644
index 0000000000..e3e2da5069
--- /dev/null
+++ b/cpukit/libmisc/monitor/mon-server.c
@@ -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:
+}
diff --git a/cpukit/libmisc/monitor/mon-symbols.c b/cpukit/libmisc/monitor/mon-symbols.c
index 666860bdab..f0e3ed3bc2 100644
--- a/cpukit/libmisc/monitor/mon-symbols.c
+++ b/cpukit/libmisc/monitor/mon-symbols.c
@@ -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");
+ }
+ }
+}
diff --git a/cpukit/libmisc/monitor/mon-task.c b/cpukit/libmisc/monitor/mon-task.c
new file mode 100644
index 0000000000..4e5b80aed6
--- /dev/null
+++ b/cpukit/libmisc/monitor/mon-task.c
@@ -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");
+}
+
diff --git a/cpukit/libmisc/monitor/monitor.h b/cpukit/libmisc/monitor/monitor.h
index 195aa73695..c9df923928 100644
--- a/cpukit/libmisc/monitor/monitor.h
+++ b/cpukit/libmisc/monitor/monitor.h
@@ -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);
+/*
+ * 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_task(rtems_task_argument monitor_suspend);
+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
diff --git a/cpukit/libmisc/monitor/symbols.h b/cpukit/libmisc/monitor/symbols.h
index 680ac6d2cf..736e7a074b 100644
--- a/cpukit/libmisc/monitor/symbols.h
+++ b/cpukit/libmisc/monitor/symbols.h
@@ -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)
diff --git a/cpukit/rtems/include/rtems/rtems/message.h b/cpukit/rtems/include/rtems/rtems/message.h
index aefcea3c36..04aa6dfb16 100644
--- a/cpukit/rtems/include/rtems/rtems/message.h
+++ b/cpukit/rtems/include/rtems/rtems/message.h
@@ -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;
/*
@@ -82,13 +93,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
* in a send or urgent fashion.
@@ -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.
*/
diff --git a/cpukit/rtems/include/rtems/rtems/msgmp.h b/cpukit/rtems/include/rtems/rtems/msgmp.h
index 486bf00002..d3e40fe123 100644
--- a/cpukit/rtems/include/rtems/rtems/msgmp.h
+++ b/cpukit/rtems/include/rtems/rtems/msgmp.h
@@ -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
);
/*
diff --git a/cpukit/rtems/inline/rtems/rtems/attr.inl b/cpukit/rtems/inline/rtems/rtems/attr.inl
index c657a08211..15a9296b7e 100644
--- a/cpukit/rtems/inline/rtems/rtems/attr.inl
+++ b/cpukit/rtems/inline/rtems/rtems/attr.inl
@@ -84,19 +84,6 @@ STATIC INLINE boolean _Attributes_Is_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
*
*/
diff --git a/cpukit/rtems/inline/rtems/rtems/message.inl b/cpukit/rtems/inline/rtems/rtems/message.inl
index ee8d5f6cb1..18d793d2fe 100644
--- a/cpukit/rtems/inline/rtems/rtems/message.inl
+++ b/cpukit/rtems/inline/rtems/rtems/message.inl
@@ -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 );
}
diff --git a/cpukit/rtems/macros/rtems/rtems/attr.inl b/cpukit/rtems/macros/rtems/rtems/attr.inl
index 602622ca35..97d3463d53 100644
--- a/cpukit/rtems/macros/rtems/rtems/attr.inl
+++ b/cpukit/rtems/macros/rtems/rtems/attr.inl
@@ -62,15 +62,6 @@
/*PAGE
*
- * _Attributes_Is_limit
- *
- */
-
-#define _Attributes_Is_limit( _attribute_set ) \
- ( (_attribute_set) & RTEMS_LIMIT )
-
-/*PAGE
- *
* _Attributes_Is_binary_semaphore
*
*/
diff --git a/cpukit/sapi/include/rtems/config.h b/cpukit/sapi/include/rtems/config.h
index b5080b6133..c2001c8074 100644
--- a/cpukit/sapi/include/rtems/config.h
+++ b/cpukit/sapi/include/rtems/config.h
@@ -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
);
diff --git a/cpukit/sapi/include/rtems/io.h b/cpukit/sapi/include/rtems/io.h
index 43c52cd35d..ef9fc69d03 100644
--- a/cpukit/sapi/include/rtems/io.h
+++ b/cpukit/sapi/include/rtems/io.h
@@ -35,27 +35,30 @@ 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.
+ * The following declare the data required to manage the Device Driver
+ * Address Table.
*/
-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;
+EXTERN unsigned32 _IO_Number_of_drivers;
+EXTERN rtems_driver_address_table *_IO_Driver_address_table;
/*
- * The following declare the data required to manage the Device Driver
- * Address Table.
+ * Table for the io device names
*/
-EXTERN unsigned32 _IO_Number_of_drivers;
-EXTERN rtems_driver_address_table *_IO_Driver_address_table;
+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
@@ -71,6 +74,36 @@ STATIC INLINE void _IO_Manager_initialization(
);
/*
+ * 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
*
* DESCRIPTION:
@@ -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
diff --git a/cpukit/sapi/src/exinit.c b/cpukit/sapi/src/exinit.c
index 984dca68be..2d3261c256 100644
--- a/cpukit/sapi/src/exinit.c
+++ b/cpukit/sapi/src/exinit.c
@@ -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(
diff --git a/cpukit/sapi/src/io.c b/cpukit/sapi/src/io.c
index 916053da7e..4ab45b33f5 100644
--- a/cpukit/sapi/src/io.c
+++ b/cpukit/sapi/src/io.c
@@ -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
- );
-}
-
-/*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_device_driver_entry callout;
+
+ if ( major >= _IO_Number_of_drivers )
+ return RTEMS_INVALID_NUMBER;
-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 );
+ callout = _IO_Driver_address_table[major].control;
+ return callout ? callout(major, minor, argument) : RTEMS_SUCCESSFUL;
}
+
diff --git a/cpukit/score/include/rtems/score/object.h b/cpukit/score/include/rtems/score/object.h
index 50eede9fd7..0553fe901d 100644
--- a/cpukit/score/include/rtems/score/object.h
+++ b/cpukit/score/include/rtems/score/object.h
@@ -100,6 +100,18 @@ EXTERN unsigned32 _Objects_Local_node;
#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
*
* DESCRIPTION:
@@ -179,6 +191,22 @@ Objects_Control *_Objects_Get (
);
/*
+ * _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
*
* DESCRIPTION:
diff --git a/cpukit/score/include/rtems/score/thread.h b/cpukit/score/include/rtems/score/thread.h
index 4a417828a3..953e19ba95 100644
--- a/cpukit/score/include/rtems/score/thread.h
+++ b/cpukit/score/include/rtems/score/thread.h
@@ -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 */
diff --git a/cpukit/score/include/rtems/system.h b/cpukit/score/include/rtems/system.h
index 3ff3772d11..96b0abfff8 100644
--- a/cpukit/score/include/rtems/system.h
+++ b/cpukit/score/include/rtems/system.h
@@ -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.
diff --git a/cpukit/score/src/object.c b/cpukit/score/src/object.c
index 71c365fa1e..29450d4171 100644
--- a/cpukit/score/src/object.c
+++ b/cpukit/score/src/object.c
@@ -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;
+}