source: rtems/cpukit/libmisc/monitor/mon-monitor.c

Last change on this file was e4cc56a7, checked in by Joel Sherrill <joel@…>, on 03/24/22 at 17:37:47

cpukit/libmisc/monitor/: Manually change to BSD-2 license

This code did not have any copyrights or licenses and a bit
of archeology was needed to determine authorship.

This code was in the initial import into the RTEMS CVS repository when
it was established in May 1995. There was very little, if any, code not
written by OAR Corporation in that initial import. After discussion
with Chris Johns, it was determined that this code was from OAR
Corporation and that he had added a few features later. Both
Chris Johns and OAR Corporation have given permission to relicense.

Updates #3053.

  • Property mode set to 100644
File size: 14.4 KB
Line 
1/* SPDX-License-Identifier: BSD-2-Clause */
2
3/**
4 * @file
5 *
6 * @brief RTEMS monitor main body
7 *
8 *  TODO:
9 *      add stuff to RTEMS api
10 *            rtems_get_name(id)
11 *            rtems_get_type(id)
12 *            rtems_build_id(node, type, num)
13 *      Add a command to dump out info about an arbitrary id when
14 *         types are added to id's
15 *         rtems> id idnum
16 *                idnum: node n, object: whatever, id: whatever
17 *      allow id's to be specified as n:t:id, where 'n:t' is optional
18 *      should have a separate monitor FILE stream (ala the debugger)
19 *      remote request/response stuff should be cleaned up
20 *         maybe we can use real rpc??
21 *      'info' command to print out:
22 *           interrupt stack location, direction and size
23 *           floating point config stuff
24 *           interrupt config stuff
25 */
26
27/*
28 * COPYRIGHT (c) 1989-2022. On-Line Applications Research Corporation (OAR).
29 *
30 * Redistribution and use in source and binary forms, with or without
31 * modification, are permitted provided that the following conditions
32 * are met:
33 * 1. Redistributions of source code must retain the above copyright
34 *    notice, this list of conditions and the following disclaimer.
35 * 2. Redistributions in binary form must reproduce the above copyright
36 *    notice, this list of conditions and the following disclaimer in the
37 *    documentation and/or other materials provided with the distribution.
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
40 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
42 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
43 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
44 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
45 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
46 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
47 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
48 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
49 * POSSIBILITY OF SUCH DAMAGE.
50 */
51#ifdef HAVE_CONFIG_H
52#include "config.h"
53#endif
54
55#include <rtems.h>
56
57#include <stdio.h>
58#include <string.h>
59#include <stdlib.h>
60
61#include <rtems/monitor.h>
62
63/*
64 * Various id's for the monitor
65 * They need to be public variables for access by other agencies
66 * such as debugger and remote servers'
67 */
68
69rtems_id  rtems_monitor_task_id;
70
71uint32_t   rtems_monitor_node;          /* our node number */
72uint32_t   rtems_monitor_default_node;  /* current default for commands */
73
74/*
75 * The rtems symbol table
76 */
77
78rtems_symbol_table_t *rtems_monitor_symbols;
79
80/*
81 * The top-level commands
82 */
83
84static const rtems_monitor_command_entry_t rtems_monitor_commands[] = {
85    { "config",
86      "Show the system configuration.",
87      0,
88      rtems_monitor_object_cmd,
89      { RTEMS_MONITOR_OBJECT_CONFIG },
90      &rtems_monitor_commands[1],
91    },
92    { "itask",
93      "List init tasks for the system",
94      0,
95      rtems_monitor_object_cmd,
96      { RTEMS_MONITOR_OBJECT_INIT_TASK },
97      &rtems_monitor_commands[2],
98    },
99   { "mpci",
100      "Show the MPCI system configuration, if configured.",
101      0,
102      rtems_monitor_object_cmd,
103      { RTEMS_MONITOR_OBJECT_MPCI },
104      &rtems_monitor_commands[3],
105    },
106    { "pause",
107      "Monitor goes to \"sleep\" for specified ticks (default is 1). "
108      "Monitor will resume at end of period or if explicitly awakened\n"
109      "  pause [ticks]",
110      0,
111      rtems_monitor_pause_cmd,
112      { 0 },
113      &rtems_monitor_commands[4],
114    },
115    { "continue",
116      "Put the monitor to sleep waiting for an explicit wakeup from the "
117      "program running.\n",
118      0,
119      rtems_monitor_continue_cmd,
120      { 0 },
121      &rtems_monitor_commands[5],
122    },
123    { "go",
124      "Alias for 'continue'",
125      0,
126      rtems_monitor_continue_cmd,
127      { 0 },
128      &rtems_monitor_commands[6],
129    },
130    { "symbol",
131      "Display value associated with specified symbol. "
132      "Defaults to displaying all known symbols.\n"
133      "  symbol [ symbolname [symbolname ... ] ]",
134      0,
135      rtems_monitor_symbol_cmd,
136      { .symbol_table = &rtems_monitor_symbols },
137      &rtems_monitor_commands[7],
138    },
139    { "extension",
140      "Display information about specified extensions. "
141      "Default is to display information about all extensions on this node.\n"
142      "  extension [id [id ...] ]",
143      0,
144      rtems_monitor_object_cmd,
145      { RTEMS_MONITOR_OBJECT_EXTENSION },
146      &rtems_monitor_commands[8],
147    },
148    { "task",
149      "Display information about the specified tasks. "
150      "Default is to display information about all tasks on this node.\n"
151      "  task [id [id ...] ]",
152      0,
153      rtems_monitor_object_cmd,
154      { RTEMS_MONITOR_OBJECT_TASK },
155      &rtems_monitor_commands[9],
156    },
157    { "queue",
158      "Display information about the specified message queues. "
159      "Default is to display information about all queues on this node.\n"
160      "  queue [id [id ... ] ]",
161      0,
162      rtems_monitor_object_cmd,
163      { RTEMS_MONITOR_OBJECT_QUEUE },
164      &rtems_monitor_commands[10],
165    },
166    { "sema",
167      "sema [id [id ... ] ]\n"
168      "  display information about the specified semaphores\n"
169      "  Default is to display information about all semaphores on this node\n"
170      ,
171      0,
172      rtems_monitor_object_cmd,
173      { RTEMS_MONITOR_OBJECT_SEMAPHORE },
174      &rtems_monitor_commands[11],
175    },
176    { "region",
177      "region [id [id ... ] ]\n"
178      "  display information about the specified regions\n"
179      "  Default is to display information about all regions on this node\n"
180      ,
181      0,
182      rtems_monitor_object_cmd,
183      { RTEMS_MONITOR_OBJECT_REGION },
184      &rtems_monitor_commands[12],
185    },
186    { "part",
187      "part [id [id ... ] ]\n"
188      "  display information about the specified partitions\n"
189      "  Default is to display information about all partitions on this node\n"
190      ,
191      0,
192      rtems_monitor_object_cmd,
193      { RTEMS_MONITOR_OBJECT_PARTITION },
194      &rtems_monitor_commands[13],
195    },
196    { "object",
197      "Display information about specified RTEMS objects. "
198      "Object id's must include 'type' information. "
199      "(which may normally be defaulted)\n"
200      "  object [id [id ...] ]",
201      0,
202      rtems_monitor_object_cmd,
203      { RTEMS_MONITOR_OBJECT_INVALID },
204      &rtems_monitor_commands[14],
205    },
206    { "driver",
207      "Display the RTEMS device driver table.\n"
208      "  driver [ major [ major ... ] ]",
209      0,
210      rtems_monitor_object_cmd,
211      { RTEMS_MONITOR_OBJECT_DRIVER },
212      &rtems_monitor_commands[15],
213    },
214    { "dname",
215      "Displays information about named drivers.\n",
216      0,
217      rtems_monitor_object_cmd,
218      { RTEMS_MONITOR_OBJECT_DNAME },
219      &rtems_monitor_commands[16],
220    },
221    { "fatal",
222      "'exit' with fatal error; default error is RTEMS_TASK_EXITTED\n"
223      "  fatal [status]",
224      0,
225      rtems_monitor_fatal_cmd,
226      { .status_code = RTEMS_TASK_EXITTED },            /* exit value */
227      &rtems_monitor_commands[17],
228    },
229    { "reset",
230      "(SW)Resets the System.",
231      0,
232      rtems_monitor_reset_cmd,
233      { 0 },
234      &rtems_monitor_commands[18],
235    },
236#if defined(RTEMS_MULTIPROCESSING)
237    { "node",
238      "Specify default node number for commands that take id's.\n"
239      "  node [ node number ]",
240      0,
241      rtems_monitor_node_cmd,
242      { 0 },
243      &rtems_monitor_commands[19],
244    },
245  #define RTEMS_MONITOR_POSIX_NEXT 20
246#else
247  #define RTEMS_MONITOR_POSIX_NEXT 19
248#endif
249    { "pthread",
250      "Display information about the specified pthreads. "
251      "Default is to display information about all pthreads on this node.\n"
252      "  pthread [id [id ...] ]",
253      0,
254      rtems_monitor_object_cmd,
255      { RTEMS_MONITOR_OBJECT_PTHREAD },
256      &rtems_monitor_commands[RTEMS_MONITOR_POSIX_NEXT],
257    },
258  #define RTEMS_MONITOR_DEBUGGER_NEXT (RTEMS_MONITOR_POSIX_NEXT + 1)
259#ifdef CPU_INVOKE_DEBUGGER
260    { "debugger",
261      "Enter the debugger, if possible. "
262      "A continue from the debugger will return to the monitor.\n",
263      0,
264      rtems_monitor_debugger_cmd,
265      { 0 },
266      &rtems_monitor_commands[RTEMS_MONITOR_DEBUGGER_NEXT],
267    },
268#endif
269    { "help",
270      "Provide information about commands. "
271      "Default is show basic command summary.\n"
272      "help [ command [ command ] ]",
273      0,
274      rtems_monitor_help_cmd,
275      { .monitor_command_entry = rtems_monitor_commands },
276      NULL
277    }
278};
279
280/*
281 * All registered commands.
282 */
283
284static const rtems_monitor_command_entry_t *rtems_monitor_registered_commands =
285  &rtems_monitor_commands [0];
286
287
288rtems_status_code
289rtems_monitor_suspend(rtems_interval timeout)
290{
291    rtems_event_set event_set;
292    rtems_status_code status;
293
294    status = rtems_event_receive(MONITOR_WAKEUP_EVENT,
295                                 RTEMS_DEFAULT_OPTIONS,
296                                 timeout,
297                                 &event_set);
298    return status;
299}
300
301void __attribute__((weak))
302rtems_monitor_reset_cmd(
303  int argc,
304  char **argv,
305  const rtems_monitor_command_arg_t* command_arg,
306  bool verbose
307)
308{
309
310}
311
312void
313rtems_monitor_wakeup(void)
314{
315    rtems_event_send(rtems_monitor_task_id, MONITOR_WAKEUP_EVENT);
316}
317
318void rtems_monitor_debugger_cmd(
319  int                                argc RTEMS_UNUSED,
320  char                             **argv RTEMS_UNUSED,
321  const rtems_monitor_command_arg_t *command_arg RTEMS_UNUSED,
322  bool                               verbose RTEMS_UNUSED
323)
324{
325#ifdef CPU_INVOKE_DEBUGGER
326    CPU_INVOKE_DEBUGGER;
327#endif
328}
329
330void rtems_monitor_pause_cmd(
331  int                                argc,
332  char                             **argv,
333  const rtems_monitor_command_arg_t *command_arg RTEMS_UNUSED,
334  bool                               verbose RTEMS_UNUSED
335)
336{
337    if (argc == 1)
338        rtems_monitor_suspend(1);
339    else
340        rtems_monitor_suspend(strtoul(argv[1], 0, 0));
341}
342
343void rtems_monitor_fatal_cmd(
344  int                                argc,
345  char                             **argv,
346  const rtems_monitor_command_arg_t *command_arg,
347  bool                               verbose RTEMS_UNUSED
348)
349{
350    if (argc == 1)
351        rtems_fatal_error_occurred(command_arg->status_code);
352    else
353        rtems_fatal_error_occurred(strtoul(argv[1], 0, 0));
354}
355
356void rtems_monitor_continue_cmd(
357  int                                argc RTEMS_UNUSED,
358  char                             **argv RTEMS_UNUSED,
359  const rtems_monitor_command_arg_t *command_arg RTEMS_UNUSED,
360  bool                               verbose RTEMS_UNUSED
361)
362{
363    rtems_monitor_suspend(RTEMS_NO_TIMEOUT);
364}
365
366#if defined(RTEMS_MULTIPROCESSING)
367void rtems_monitor_node_cmd(
368  int                                argc,
369  char                             **argv,
370  const rtems_monitor_command_arg_t *command_arg RTEMS_UNUSED,
371  bool                               verbose RTEMS_UNUSED
372)
373{
374  uint32_t   new_node = rtems_monitor_default_node;
375
376  switch (argc) {
377    case 1:             /* no node, just set back to ours */
378      new_node = rtems_monitor_node;
379      break;
380
381    case 2:
382      new_node = strtoul(argv[1], 0, 0);
383      break;
384
385    default:
386      fprintf(stdout,"invalid syntax, try 'help node'\n");
387      break;
388  }
389
390  if ((new_node >= 1) &&
391    (new_node <= _MPCI_Configuration.maximum_nodes))
392        rtems_monitor_default_node = new_node;
393}
394#endif
395
396
397/*
398 *  Function:   rtems_monitor_symbols_loadup
399 *
400 *  Description:
401 *      Create and load the monitor's symbol table.
402 *      We are reading the output format of 'gnm' which looks like this:
403 *
404 *              400a7068 ? _Rate_monotonic_Information
405 *              400a708c ? _Thread_Dispatch_disable_level
406 *              400a7090 ? _Configuration_Table
407 *
408 *      We ignore the type field.
409 *
410 *  Side Effects:
411 *      Creates and fills in 'rtems_monitor_symbols' table
412 *
413 *  TODO
414 *      there should be a BSP #define or something like that
415 *         to do this;  Assuming stdio is crazy.
416 *      Someday this should know BFD
417 *              Maybe we could get objcopy to just copy the symbol areas
418 *              and copy that down.
419 *
420 */
421
422void
423rtems_monitor_symbols_loadup(void)
424{
425    FILE *fp;
426    char buffer[128];
427
428    if (rtems_monitor_symbols)
429        rtems_symbol_table_destroy(rtems_monitor_symbols);
430
431    rtems_monitor_symbols = rtems_symbol_table_create();
432    if (rtems_monitor_symbols == 0)
433        return;
434
435    fp = fopen("symbols", "r");
436
437    if (fp == 0)
438        return;
439
440    while (fgets(buffer, sizeof(buffer) - 1, fp))
441    {
442        char *symbol;
443        char *value;
444        char *ignored_type;
445
446        value = strtok(buffer, " \t\n");
447        ignored_type = strtok(0, " \t\n");
448        symbol = strtok(0, " \t\n");
449
450        if (symbol && ignored_type && value)
451        {
452            rtems_symbol_t *sp;
453            sp = rtems_symbol_create(rtems_monitor_symbols,
454                                     symbol,
455                                     (uint32_t) strtoul(value, 0, 16));
456            if (sp == 0)
457            {
458                fprintf(stdout,"could not define symbol '%s'\n", symbol);
459                goto done;
460            }
461        }
462        else
463        {
464            fprintf(stdout,"parsing error on '%s'\n", buffer);
465            goto done;
466        }
467    }
468
469done:
470    fclose(fp);
471    return;
472}
473
474/*
475 * User registered commands.
476 */
477
478int
479rtems_monitor_insert_cmd (
480  rtems_monitor_command_entry_t *command
481)
482{
483  const rtems_monitor_command_entry_t *e = rtems_monitor_registered_commands;
484
485  /* Reject empty commands */
486  if (command->command == NULL) {
487    return 0;
488  }
489
490  /* Reject command if already present */
491  while (e->next != NULL) {
492      if (e->command != NULL && strcmp(command->command, e->command) == 0) {
493        return 0;
494      }
495      e = e->next;
496  }
497
498  /* Prepend new command */
499  command->next = rtems_monitor_registered_commands;
500  rtems_monitor_registered_commands = command;
501
502  return 1;
503}
504
505/**
506 * @brief Iterates through all registerd commands.
507 *
508 * For each command the interation routine @a routine is called with the
509 * command entry and the user provided argument @a arg.  It is guaranteed that
510 * the command name and function are not NULL.
511 */
512void rtems_monitor_command_iterate(
513  rtems_monitor_per_command_routine routine,
514  void *arg
515)
516{
517  const rtems_monitor_command_entry_t *e = rtems_monitor_registered_commands;
518
519  while (e != NULL) {
520    if (e->command != NULL && e->command_function != NULL) {
521      if (!routine(e, arg)) {
522        break;
523      }
524    }
525    e = e->next;
526  }
527}
Note: See TracBrowser for help on using the repository browser.