source: rtems/c/src/libmisc/monitor/mon-monitor.c @ c64e4ed4

4.104.114.84.95
Last change on this file since c64e4ed4 was c64e4ed4, checked in by Joel Sherrill <joel.sherrill@…>, on 01/15/96 at 21:50:28

updates from Tony Bennett for PA and UNIX ports

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