source: rtems/cpukit/libmisc/monitor/mon-monitor.c @ 6f6ddc00

4.104.114.84.95
Last change on this file since 6f6ddc00 was 6f6ddc00, checked in by Joel Sherrill <joel.sherrill@…>, on 06/29/00 at 22:33:05

Added RTEMS_CPU_HAS_16_BIT_ADDRESSES constant to disable code
that breaks when the target has 16 bit address space. One of the H8
multilibs is a 16-bit address space CPU. When a real attempt is
made to support this CPU model, the code that assumes an address
is 32 bits will have to change. This constant is probably not
flagging all impacted code.

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