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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [rtems/] [c/] [src/] [libmisc/] [monitor/] [mon-monitor.c] - Blame information for rev 279

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

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

powered by: WebSVN 2.1.0

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