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

4.104.114.84.95
Last change on this file since ca7858bb was ca7858bb, checked in by Joel Sherrill <joel.sherrill@…>, on 07/26/00 at 19:28:11

Port of RTEMS to the Texas Instruments C3x/C4x DSP families including
a BSP (c4xsim) supporting the simulator included with gdb. This port
was done by Joel Sherrill and Jennifer Averett of OAR Corporation.
Also included with this port is a space/time optimization to eliminate
FP context switch management on CPUs without hardware or software FP.

An issue with this port was that sizeof(unsigned32) = sizeof(unsigned8)
on this CPU. This required addressing alignment checks and assumptions
as well as fixing code that assumed sizeof(unsigned32) == 4.

  • Property mode set to 100644
File size: 14.5 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#if (CPU_HARDWARE_FP == TRUE) || (CPU_SOFTWARE_FP == TRUE)
529        fp = (rtems_context_fp *) debugee->fp_context;  /* possibly 0 */
530#else
531        fp = 0;
532#endif
533
534        if (0 == rtems_monitor_command_read(command_buffer, &argc, argv))
535            continue;
536        if ((command = rtems_monitor_command_lookup(rtems_monitor_commands,
537                                                    argc,
538                                                    argv)) == 0)
539        {
540            /* no command */
541            printf("Unrecognised command; try 'help'\n");
542            continue;
543        }
544
545        command->command_function(argc, argv, command->command_arg, verbose);
546
547        fflush(stdout);
548    }
549}
550
551
552void
553rtems_monitor_kill(void)
554{
555    if (rtems_monitor_task_id)
556        rtems_task_delete(rtems_monitor_task_id);
557    rtems_monitor_task_id = 0;
558   
559    rtems_monitor_server_kill();
560}
561
562void
563rtems_monitor_init(
564    unsigned32 monitor_flags
565)
566{
567    rtems_status_code status;
568   
569    rtems_monitor_kill();
570
571    status = rtems_task_create(RTEMS_MONITOR_NAME,
572                               1,
573                               RTEMS_MINIMUM_STACK_SIZE * 2,
574                               RTEMS_INTERRUPT_LEVEL(0),
575                               RTEMS_DEFAULT_ATTRIBUTES,
576                               &rtems_monitor_task_id);
577    if (status != RTEMS_SUCCESSFUL)
578    {
579        rtems_error(status, "could not create monitor task");
580        goto done;
581    }
582
583    rtems_monitor_node = rtems_get_node(rtems_monitor_task_id);
584    rtems_monitor_default_node = rtems_monitor_node;
585
586    rtems_monitor_symbols_loadup();
587
588    if (monitor_flags & RTEMS_MONITOR_GLOBAL)
589        rtems_monitor_server_init(monitor_flags);
590
591    /*
592     * Start the monitor task itself
593     */
594   
595    status = rtems_task_start(rtems_monitor_task_id,
596                              rtems_monitor_task,
597                              monitor_flags);
598    if (status != RTEMS_SUCCESSFUL)
599    {
600        rtems_error(status, "could not start monitor");
601        goto done;
602    }
603
604done:
605}
Note: See TracBrowser for help on using the repository browser.