summaryrefslogtreecommitdiffstats
path: root/cpukit/libmisc
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/libmisc
parentvariable length messages (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/libmisc')
-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
18 files changed, 3174 insertions, 223 deletions
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)