source: rtems/c/src/lib/libmisc/monitor/mon-monitor.c @ 8cf88427

4.104.114.84.95
Last change on this file since 8cf88427 was 72c440e, checked in by Joel Sherrill <joel.sherrill@…>, on 01/17/96 at 20:13:45

Update from Tony Bennett (tbennett@…)

  • Property mode set to 100644
File size: 12.9 KB
Line 
1/*
2 *      @(#)monitor.c   1.23 - 96/01/03
3 *     
4 *
5 *
6 * 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' commadn to print out:
22 *           interrupt stack location, direction and size
23 *           floating point config stuff
24 *           interrupt config stuff
25 *
26 *  $Id$
27 */
28
29#include <rtems.h>
30
31#include <stdio.h>
32#include <string.h>
33#include <stdlib.h>
34#include <unistd.h>
35
36#include "monitor.h"
37
38/* set by trap handler */
39extern rtems_tcb       *debugger_interrupted_task;
40extern rtems_context   *debugger_interrupted_task_context;
41extern rtems_unsigned32 debugger_trap;
42
43/*
44 * Various id's for the monitor
45 * They need to be public variables for access by other agencies
46 * such as debugger and remote servers'
47 */
48
49rtems_id  rtems_monitor_task_id;
50
51unsigned32 rtems_monitor_node;          /* our node number */
52unsigned32 rtems_monitor_default_node;  /* current default for commands */
53
54/*
55 * The rtems symbol table
56 */
57
58rtems_symbol_table_t *rtems_monitor_symbols;
59
60/*
61 * The top-level commands
62 */
63
64rtems_monitor_command_entry_t rtems_monitor_commands[] = {
65    { "--usage--",
66      "\n"
67      "RTEMS monitor\n"
68      "\n"
69      "Commands (may be abbreviated)\n"
70      "\n"
71      "  help      -- get this message or command specific help\n"
72      "  pause     -- pause monitor for a specified number of ticks\n"
73      "  exit      -- invoke a fatal RTEMS error\n"
74      "  symbol    -- show entries from symbol table\n"
75      "  continue  -- put monitor to sleep waiting for explicit wakeup\n"
76      "  config    -- show system configuration\n"
77      "  itask     -- list init tasks\n"
78      "  mpci      -- list mpci config\n"
79      "  task      -- show task information\n"
80      "  queue     -- show message queue information\n"
81      "  extension -- user extensions\n"
82      "  driver    -- show information about named drivers\n"
83      "  dname     -- show information about named drivers\n"
84      "  object    -- generic object information\n"
85      "  node      -- specify default node for commands that take id's\n"
86#ifdef CPU_INVOKE_DEBUGGER
87      "  debugger  -- invoke system debugger\n"
88#endif
89      ,
90      0,
91      0,
92      (unsigned32) rtems_monitor_commands,
93    },
94    { "config",
95      "config\n"
96      "  Show the system configuration.\n",
97      0,
98      rtems_monitor_object_cmd,
99      RTEMS_MONITOR_OBJECT_CONFIG,
100    },
101    { "itask",
102      "itask\n"
103      "  List init tasks for the system\n",
104      0,
105      rtems_monitor_object_cmd,
106      RTEMS_MONITOR_OBJECT_INIT_TASK,
107    },
108   { "mpci",
109      "mpci\n"
110      "  Show the MPCI system configuration, if configured.\n",
111      0,
112      rtems_monitor_object_cmd,
113      RTEMS_MONITOR_OBJECT_MPCI,
114    },
115    { "pause",
116      "pause [ticks]\n"
117      "  monitor goes to \"sleep\" for specified ticks (default is 1)\n"
118      "  monitor will resume at end of period or if explicitly awakened\n",
119      0,
120      rtems_monitor_pause_cmd,
121      0,
122    },
123    { "continue",
124      "continue\n"
125      "  put the monitor to sleep waiting for an explicit wakeup from the\n"
126      "  program running.\n",
127      0,
128      rtems_monitor_continue_cmd,
129      0,
130    },
131    { "go",
132      "go\n"
133      "  Alias for 'continue'\n",
134      0,
135      rtems_monitor_continue_cmd,
136      0,
137    },
138    { "node",
139      "node [ node number ]\n"
140      "  Specify default node number for commands that take id's\n",
141      0,
142      rtems_monitor_node_cmd,
143      0,
144    },
145    { "symbol",
146      "symbol [ symbolname [symbolname ... ] ]\n"
147      "  display value associated with specified symbol.\n"
148      "  Defaults to displaying all known symbols.\n",
149      0,
150      rtems_monitor_symbol_cmd,
151      (unsigned32) &rtems_monitor_symbols,
152    },
153    { "extension",
154      "extension [id [id ...] ]\n"
155      "  display information about specified extensions.\n"
156      "  Default is to display information about all extensions on this node\n",
157      0,
158      rtems_monitor_object_cmd,
159      RTEMS_MONITOR_OBJECT_EXTENSION,
160    },
161    { "task",
162      "task [id [id ...] ]\n"
163      "  display information about the specified tasks.\n"
164      "  Default is to display information about all tasks on this node\n",
165      0,
166      rtems_monitor_object_cmd,
167      RTEMS_MONITOR_OBJECT_TASK,
168    },
169    { "queue",
170      "queue [id [id ... ] ]\n"
171      "  display information about the specified message queues\n"
172      "  Default is to display information about all queues on this node\n",
173      0,
174      rtems_monitor_object_cmd,
175      RTEMS_MONITOR_OBJECT_QUEUE,
176    },
177    { "object",
178      "object [id [id ...] ]\n"
179      "  display information about specified RTEMS objects.\n"
180      "  Object id's must include 'type' information.\n"
181      "  (which may normally be defaulted)\n",
182      0,
183      rtems_monitor_object_cmd,
184      RTEMS_MONITOR_OBJECT_INVALID,
185    },
186    { "driver",
187      "driver [ major [ major ... ] ]\n"
188      "  Display the RTEMS device driver table.\n",
189      0,
190      rtems_monitor_object_cmd,
191      RTEMS_MONITOR_OBJECT_DRIVER,
192    },
193    { "dname",
194      "dname\n"
195      "  Displays information about named drivers.\n",
196      0,
197      rtems_monitor_object_cmd,
198      RTEMS_MONITOR_OBJECT_DNAME,
199    },
200    { "exit",
201      "exit [status]\n"
202      "  Invoke 'rtems_fatal_error_occurred' with 'status'\n"
203      "  (default is RTEMS_SUCCESSFUL)\n",
204      0,
205      rtems_monitor_fatal_cmd,
206      RTEMS_SUCCESSFUL,
207    },
208    { "fatal",
209      "fatal [status]\n"
210      "  'exit' with fatal error; default error is RTEMS_TASK_EXITTED\n",
211      0,
212      rtems_monitor_fatal_cmd,
213      RTEMS_TASK_EXITTED,                       /* exit value */
214    },
215    { "quit",
216      "quit [status]\n"
217      "  Alias for 'exit'\n",
218      0,
219      rtems_monitor_fatal_cmd,
220      RTEMS_SUCCESSFUL,                         /* exit value */
221    },
222    { "help",
223      "help [ command [ command ] ]\n"
224      "  provide information about commands\n"
225      "  Default is show basic command summary.\n",
226      0,
227      rtems_monitor_help_cmd,
228      (unsigned32) rtems_monitor_commands,
229    },
230#ifdef CPU_INVOKE_DEBUGGER
231    { "debugger",
232      "debugger\n"
233      "  Enter the debugger, if possible.\n"
234      "  A continue from the debugger will return to the monitor.\n",
235      0,
236      rtems_monitor_debugger_cmd,
237      0,
238    },
239#endif           
240    { 0, 0, 0, 0, 0 },
241};
242
243
244rtems_status_code
245rtems_monitor_suspend(rtems_interval timeout)
246{
247    rtems_event_set event_set;
248    rtems_status_code status;
249   
250    status = rtems_event_receive(MONITOR_WAKEUP_EVENT,
251                                 RTEMS_DEFAULT_OPTIONS,
252                                 timeout,
253                                 &event_set);
254    return status;
255}
256
257void
258rtems_monitor_wakeup(void)
259{
260    rtems_status_code status;
261   
262    status = rtems_event_send(rtems_monitor_task_id, MONITOR_WAKEUP_EVENT);
263}
264
265
266void
267rtems_monitor_pause_cmd(
268    int        argc,
269    char     **argv,
270    unsigned32 command_arg,
271    boolean    verbose
272)
273{
274    if (argc == 1)
275        rtems_monitor_suspend(1);
276    else
277        rtems_monitor_suspend(strtoul(argv[1], 0, 0));
278}
279
280void
281rtems_monitor_fatal_cmd(
282    int     argc,
283    char  **argv,
284    unsigned32 command_arg,
285    boolean verbose
286)
287{
288    if (argc == 1)
289        rtems_fatal_error_occurred(command_arg);
290    else
291        rtems_fatal_error_occurred(strtoul(argv[1], 0, 0));
292}
293
294void
295rtems_monitor_continue_cmd(
296    int     argc,
297    char  **argv,
298    unsigned32 command_arg,
299    boolean verbose
300)
301{
302    rtems_monitor_suspend(RTEMS_NO_TIMEOUT);
303}
304
305void
306rtems_monitor_debugger_cmd(
307    int        argc,
308    char     **argv,
309    unsigned32 command_arg,
310    boolean    verbose
311)
312{
313#ifdef CPU_INVOKE_DEBUGGER
314    CPU_INVOKE_DEBUGGER;
315#endif
316}
317
318void
319rtems_monitor_node_cmd(
320    int     argc,
321    char  **argv,
322    unsigned32 command_arg,
323    boolean verbose
324)
325{
326    unsigned32 new_node = rtems_monitor_default_node;
327   
328    switch (argc)
329    {
330        case 1:                 /* no node, just set back to ours */
331            new_node = rtems_monitor_node;
332            break;
333
334        case 2:
335            new_node = strtoul(argv[1], 0, 0);
336            break;
337
338        default:
339            printf("invalid syntax, try 'help node'\n");
340            break;
341    }
342
343    if ((new_node >= 1) && (new_node <= _Configuration_MP_table->maximum_nodes))
344        rtems_monitor_default_node = new_node;
345}
346
347
348/*
349 *  Function:   rtems_monitor_symbols_loadup
350 *
351 *  Description:
352 *      Create and load the monitor's symbol table.
353 *      We are reading the output format of 'gnm' which looks like this:
354 *
355 *              400a7068 ? _Rate_monotonic_Information
356 *              400a708c ? _Thread_Dispatch_disable_level
357 *              400a7090 ? _Configuration_Table
358 *
359 *      We ignore the type field.
360 *
361 *  Side Effects:
362 *      Creates and fills in 'rtems_monitor_symbols' table
363 *
364 *  TODO
365 *      there should be a BSP #define or something like that
366 *         to do this;  Assuming stdio is crazy.
367 *      Someday this should know BFD
368 *              Maybe we could get objcopy to just copy the symbol areas
369 *              and copy that down.
370 *
371 */
372
373void
374rtems_monitor_symbols_loadup(void)
375{
376    FILE *fp;
377    char buffer[128];
378
379    if (rtems_monitor_symbols)
380        rtems_symbol_table_destroy(rtems_monitor_symbols);
381   
382    rtems_monitor_symbols = rtems_symbol_table_create(10);
383    if (rtems_monitor_symbols == 0)
384        return;
385
386#ifdef SIMHPPA
387    fp = fdopen(8, "r");                /* don't ask; don't tell */
388#else
389    fp = fopen("symbols", "r");
390#endif
391   
392    if (fp == 0)
393        return;
394
395    while (fgets(buffer, sizeof(buffer) - 1, fp))
396    {
397        char *symbol;
398        char *value;
399        char *ignored_type;
400
401        value = strtok(buffer, " \t\n");
402        ignored_type = strtok(0, " \t\n");
403        symbol = strtok(0, " \t\n");
404
405        if (symbol && ignored_type && value)
406        {
407            rtems_symbol_t *sp;
408            sp = rtems_symbol_create(rtems_monitor_symbols,
409                                     symbol,
410                                     (rtems_unsigned32) strtoul(value, 0, 16));
411            if (sp == 0)
412            {
413                printf("could not define symbol '%s'\n", symbol);
414                goto done;
415            }
416        }
417        else
418        {
419            printf("parsing error on '%s'\n", buffer);
420            goto done;
421        }
422    }
423
424done:
425}
426
427
428/*
429 * Main monitor command loop
430 */
431
432void
433rtems_monitor_task(
434    rtems_task_argument monitor_flags
435)
436{
437    rtems_tcb *debugee = 0;
438    rtems_context *rp;
439    rtems_context_fp *fp;
440    char command_buffer[513];
441    int argc;
442    char *argv[64];       
443    boolean verbose = FALSE;
444
445    if (monitor_flags & RTEMS_MONITOR_SUSPEND)
446        (void) rtems_monitor_suspend(RTEMS_NO_TIMEOUT);
447
448    for (;;)
449    {
450        extern rtems_tcb * _Thread_Executing;
451        rtems_monitor_command_entry_t *command;
452
453        debugee = _Thread_Executing;
454        rp = &debugee->Registers;
455        fp = (rtems_context_fp *) debugee->fp_context;  /* possibly 0 */
456
457        if (0 == rtems_monitor_command_read(command_buffer, &argc, argv))
458            continue;
459        if ((command = rtems_monitor_command_lookup(rtems_monitor_commands,
460                                                    argc,
461                                                    argv)) == 0)
462            continue;
463
464        command->command_function(argc, argv, command->command_arg, verbose);
465
466        fflush(stdout);
467    }
468}
469
470
471void
472rtems_monitor_kill(void)
473{
474    if (rtems_monitor_task_id)
475        rtems_task_delete(rtems_monitor_task_id);
476    rtems_monitor_task_id = 0;
477   
478    rtems_monitor_server_kill();
479}
480
481void
482rtems_monitor_init(
483    unsigned32 monitor_flags
484)
485{
486    rtems_status_code status;
487   
488    rtems_monitor_kill();
489
490    status = rtems_task_create(RTEMS_MONITOR_NAME,
491                               1,
492                               0 /* default stack */,
493                               RTEMS_INTERRUPT_LEVEL(0),
494                               RTEMS_DEFAULT_ATTRIBUTES,
495                               &rtems_monitor_task_id);
496    if (status != RTEMS_SUCCESSFUL)
497    {
498        rtems_error(status, "could not create monitor task");
499        goto done;
500    }
501
502    rtems_monitor_node = rtems_get_node(rtems_monitor_task_id);
503    rtems_monitor_default_node = rtems_monitor_node;
504
505    rtems_monitor_symbols_loadup();
506
507    if (monitor_flags & RTEMS_MONITOR_GLOBAL)
508        rtems_monitor_server_init(monitor_flags);
509
510    /*
511     * Start the monitor task itself
512     */
513   
514    status = rtems_task_start(rtems_monitor_task_id,
515                              rtems_monitor_task,
516                              monitor_flags);
517    if (status != RTEMS_SUCCESSFUL)
518    {
519        rtems_error(status, "could not start monitor");
520        goto done;
521    }
522
523done:
524}
Note: See TracBrowser for help on using the repository browser.