OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rtems-20020807/] [c/] [src/] [libmisc/] [monitor/] [mon-monitor.c] - Blame information for rev 1780

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1026 ivang
/*
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
 *  mon-monitor.c,v 1.14 2002/07/01 22:19:33 joel Exp
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 */
36
extern rtems_tcb       *debugger_interrupted_task;
37
extern rtems_context   *debugger_interrupted_task_context;
38
extern 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
 
46
rtems_id  rtems_monitor_task_id;
47
 
48
unsigned32 rtems_monitor_node;          /* our node number */
49
unsigned32 rtems_monitor_default_node;  /* current default for commands */
50
 
51
/*
52
 * The rtems symbol table
53
 */
54
 
55
rtems_symbol_table_t *rtems_monitor_symbols;
56
 
57
/*
58
 * User registered commands.
59
 */
60
 
61
rtems_monitor_command_entry_t rtems_registered_commands;
62
 
63
/*
64
 * The top-level commands
65
 */
66
 
67
rtems_monitor_command_entry_t rtems_monitor_commands[] = {
68
    { "config",
69
      "Show the system configuration.",
70
      0,
71
      rtems_monitor_object_cmd,
72
      (rtems_monitor_command_arg_t) 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_command_arg_t) 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_command_arg_t) 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
      (rtems_monitor_command_arg_t) &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_command_arg_t) 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_command_arg_t) 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_command_arg_t) 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_command_arg_t) 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_command_arg_t) 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_command_arg_t) 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_monitor_command_arg_t) 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_monitor_command_arg_t) 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_monitor_command_arg_t) 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
      (rtems_monitor_command_arg_t) 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
 
237
rtems_status_code
238
rtems_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
 
250
void
251
rtems_monitor_wakeup(void)
252
{
253
    rtems_status_code status;
254
 
255
    status = rtems_event_send(rtems_monitor_task_id, MONITOR_WAKEUP_EVENT);
256
}
257
 
258
void
259
rtems_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
 
271
void
272
rtems_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
 
285
void
286
rtems_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
 
299
void
300
rtems_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
 
310
void
311
rtems_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
 
367
void
368
rtems_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
 
414
done:
415
    return;
416
}
417
 
418
/*
419
 * User registered commands.
420
 */
421
 
422
int
423
rtems_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
 
446
int
447
rtems_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
 
473
void
474
rtems_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
 
552
void
553
rtems_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
 
562
void
563
rtems_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
        return;
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
        return;
602
    }
603
}

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.