source: rtems/c/src/lib/libmisc/monitor/mon-object.c @ 8389628

4.104.114.84.95
Last change on this file since 8389628 was 8389628, checked in by Joel Sherrill <joel.sherrill@…>, on 04/22/96 at 16:53:46

updates from Tony Bennett

  • Property mode set to 100644
File size: 10.9 KB
Line 
1/*
2 * RTEMS Monitor "object" support.
3 *
4 * Used to traverse object lists and print them out.
5 * An object can be an RTEMS object (chain based stuff) or
6 * a "misc" object such as a device driver.
7 *
8 * Each object has its own file in this directory (eg: extension.c)
9 * That file provides routines to convert a "native" structure
10 * to its canonical form, print a canonical structure, etc.
11 *
12 * TODO:
13 *     should allow for non-numeric id's???
14 *
15 *  $Id$
16 */
17
18#define __RTEMS_VIOLATE_KERNEL_VISIBILITY__
19#include <rtems.h>
20#include "monitor.h"
21
22#include <stdio.h>
23#include <stdlib.h>             /* strtoul() */
24
25#include <monitor.h>
26
27#define NUMELEMS(arr)   (sizeof(arr) / sizeof(arr[0]))
28
29/*
30 * add:
31 *     next
32 */
33
34rtems_monitor_object_info_t rtems_monitor_object_info[] =
35{
36    { RTEMS_MONITOR_OBJECT_CONFIG,
37      (void *) 0,
38      sizeof(rtems_monitor_config_t),
39      (rtems_monitor_object_next_fn)        rtems_monitor_config_next,
40      (rtems_monitor_object_canonical_fn)   rtems_monitor_config_canonical,
41      (rtems_monitor_object_dump_header_fn) rtems_monitor_config_dump_header,
42      (rtems_monitor_object_dump_fn)        rtems_monitor_config_dump,
43    },
44    { RTEMS_MONITOR_OBJECT_MPCI,
45      (void *) 0,
46      sizeof(rtems_monitor_mpci_t),
47      (rtems_monitor_object_next_fn)        rtems_monitor_mpci_next,
48      (rtems_monitor_object_canonical_fn)   rtems_monitor_mpci_canonical,
49      (rtems_monitor_object_dump_header_fn) rtems_monitor_mpci_dump_header,
50      (rtems_monitor_object_dump_fn)        rtems_monitor_mpci_dump,
51    },
52    { RTEMS_MONITOR_OBJECT_INIT_TASK,
53      (void *) 0,
54      sizeof(rtems_monitor_init_task_t),
55      (rtems_monitor_object_next_fn)        rtems_monitor_init_task_next,
56      (rtems_monitor_object_canonical_fn)   rtems_monitor_init_task_canonical,
57      (rtems_monitor_object_dump_header_fn) rtems_monitor_init_task_dump_header,
58      (rtems_monitor_object_dump_fn)        rtems_monitor_init_task_dump,
59    },
60    { RTEMS_MONITOR_OBJECT_TASK,
61      (void *) &_RTEMS_tasks_Information,
62      sizeof(rtems_monitor_task_t),
63      (rtems_monitor_object_next_fn)        rtems_monitor_manager_next,
64      (rtems_monitor_object_canonical_fn)   rtems_monitor_task_canonical,
65      (rtems_monitor_object_dump_header_fn) rtems_monitor_task_dump_header,
66      (rtems_monitor_object_dump_fn)        rtems_monitor_task_dump,
67    },
68    { RTEMS_MONITOR_OBJECT_QUEUE,
69      (void *) &_Message_queue_Information,
70      sizeof(rtems_monitor_queue_t),
71      (rtems_monitor_object_next_fn)        rtems_monitor_manager_next,
72      (rtems_monitor_object_canonical_fn)   rtems_monitor_queue_canonical,
73      (rtems_monitor_object_dump_header_fn) rtems_monitor_queue_dump_header,
74      (rtems_monitor_object_dump_fn)        rtems_monitor_queue_dump,
75    },
76    { RTEMS_MONITOR_OBJECT_EXTENSION,
77      (void *) &_Extension_Information,
78      sizeof(rtems_monitor_extension_t),
79      (rtems_monitor_object_next_fn)        rtems_monitor_manager_next,
80      (rtems_monitor_object_canonical_fn)   rtems_monitor_extension_canonical,
81      (rtems_monitor_object_dump_header_fn) rtems_monitor_extension_dump_header,
82      (rtems_monitor_object_dump_fn)        rtems_monitor_extension_dump,
83    },
84    { RTEMS_MONITOR_OBJECT_DRIVER,
85      (void *) 0,
86      sizeof(rtems_monitor_driver_t),
87      (rtems_monitor_object_next_fn)        rtems_monitor_driver_next,
88      (rtems_monitor_object_canonical_fn)   rtems_monitor_driver_canonical,
89      (rtems_monitor_object_dump_header_fn) rtems_monitor_driver_dump_header,
90      (rtems_monitor_object_dump_fn)        rtems_monitor_driver_dump,
91    },
92    { RTEMS_MONITOR_OBJECT_DNAME,
93      /* XXX now that the driver name table is allocated from the */
94      /* XXX Workspace, this does not work */
95      (void *) 0,
96      /* (void *) _IO_Driver_name_table, */
97      sizeof(rtems_monitor_dname_t),
98      (rtems_monitor_object_next_fn)        rtems_monitor_dname_next,
99      (rtems_monitor_object_canonical_fn)   rtems_monitor_dname_canonical,
100      (rtems_monitor_object_dump_header_fn) rtems_monitor_dname_dump_header,
101      (rtems_monitor_object_dump_fn)        rtems_monitor_dname_dump,
102    },
103};
104
105/*
106 * Allow id's to be specified without the node number or
107 * type for convenience.
108 */
109
110rtems_id
111rtems_monitor_id_fixup(
112    rtems_id            id,
113    unsigned32          default_node,
114    rtems_monitor_object_type_t type
115)
116{
117    unsigned32  node;
118   
119    node = rtems_get_node(id);
120    if (node == 0)
121    {
122        if (rtems_get_class(id) != OBJECTS_NO_CLASS)
123            type = rtems_get_class(id);
124
125        id = _Objects_Build_id(type, default_node, rtems_get_index(id));
126    }
127    return id;
128}
129
130
131rtems_monitor_object_info_t *
132rtems_monitor_object_lookup(
133    rtems_monitor_object_type_t type
134)
135{
136    rtems_monitor_object_info_t *p;
137    for (p = &rtems_monitor_object_info[0];
138         p < &rtems_monitor_object_info[NUMELEMS(rtems_monitor_object_info)];
139         p++)
140    {
141        if (p->type == type)
142            return p;
143    }
144    return 0;
145}
146
147rtems_id
148rtems_monitor_object_canonical_next_remote(
149    rtems_monitor_object_type_t type,
150    rtems_id            id,
151    void               *canonical
152)
153{
154    rtems_id                        next_id;
155    rtems_status_code               status;
156    rtems_monitor_server_request_t  request;
157    rtems_monitor_server_response_t response;
158
159    /*
160     * Send request
161     */
162   
163    request.command = RTEMS_MONITOR_SERVER_CANONICAL;
164    request.argument0 = (unsigned32) type;
165    request.argument1 = (unsigned32) id;
166
167    status = rtems_monitor_server_request(rtems_get_node(id), &request, &response);
168    if (status != RTEMS_SUCCESSFUL)
169        goto failed;
170
171    /*
172     * process response
173     */
174   
175    next_id = (rtems_id) response.result0;
176    if (next_id != RTEMS_OBJECT_ID_FINAL)
177        (void) memcpy(canonical, &response.payload, response.result1);
178
179    return next_id;
180
181failed:
182    return RTEMS_OBJECT_ID_FINAL;
183
184}
185
186
187rtems_id
188rtems_monitor_object_canonical_next(
189    rtems_monitor_object_info_t *info,
190    rtems_id                     id,
191    void                        *canonical
192)
193{
194    rtems_id                     next_id;
195    void                        *raw_item;
196
197    if ( ! _Objects_Is_local_id(id))
198        next_id = rtems_monitor_object_canonical_next_remote(info->type,
199                                                             id,
200                                                             canonical);
201    else
202    {
203        next_id = id;
204       
205        raw_item = (void *) info->next(info->object_information,
206                                       canonical,
207                                       &next_id);
208
209        if (raw_item)
210        {
211            info->canonical(canonical, raw_item);
212            _Thread_Enable_dispatch();
213        }   
214    }   
215    return next_id;
216}
217
218
219/*
220 * this is routine server invokes locally to get the type
221 */
222
223rtems_id
224rtems_monitor_object_canonical_get(
225    rtems_monitor_object_type_t  type,
226    rtems_id             id,
227    void                *canonical,
228    unsigned32          *size_p
229)
230{
231    rtems_monitor_object_info_t *info;
232    rtems_id                     next_id;
233
234    *size_p = 0;
235
236    info = rtems_monitor_object_lookup(type);
237
238    if (info == 0)
239        return RTEMS_OBJECT_ID_FINAL;
240
241    next_id = rtems_monitor_object_canonical_next(info, id, canonical);
242    *size_p = info->size;
243
244    return next_id;
245}
246
247
248void
249rtems_monitor_object_dump_1(
250    rtems_monitor_object_info_t *info,
251    rtems_id                     id,
252    boolean                      verbose
253)
254{
255    rtems_id next_id;
256    rtems_monitor_union_t canonical;
257
258    if ((next_id = rtems_monitor_object_canonical_next(
259                                     info,
260                                     id,
261                                     &canonical)) != RTEMS_OBJECT_ID_FINAL)
262    {
263        /*
264         * If the one we actually got is the one we wanted, then
265         * print it out.
266         * For ones that have an id field, this works fine,
267         * for all others, always dump it out.
268         *
269         * HACK: the way we determine whether there is an id is a hack.
270         *
271         * by the way: the reason we try to not have an id, is that some
272         *   of the canonical structures are almost too big for shared
273         *   memory driver (eg: mpci)
274         */
275       
276        if ((info->next != rtems_monitor_manager_next) ||
277            (id == canonical.generic.id))
278            info->dump(&canonical, verbose);
279    }
280}
281
282void
283rtems_monitor_object_dump_all(
284    rtems_monitor_object_info_t *info,
285    boolean                      verbose
286)
287{
288    rtems_id next_id;
289    rtems_monitor_union_t canonical;
290
291    next_id = RTEMS_OBJECT_ID_INITIAL(info->type, rtems_monitor_default_node);
292
293    while ((next_id = rtems_monitor_object_canonical_next(
294                                         info,
295                                         next_id,
296                                         &canonical)) != RTEMS_OBJECT_ID_FINAL)
297    {
298        info->dump(&canonical, verbose);
299    }
300}
301
302void
303rtems_monitor_object_cmd(
304    int        argc,
305    char     **argv,
306    unsigned32 command_arg,
307    boolean    verbose
308)
309{
310    int arg;
311    rtems_monitor_object_info_t *info = 0;
312    rtems_monitor_object_type_t  type = (rtems_monitor_object_type_t) command_arg;
313   
314    /* what is the default type? */
315    type = (rtems_monitor_object_type_t) command_arg;
316
317    if (argc == 1)
318    {
319        if (type == RTEMS_MONITOR_OBJECT_INVALID)
320        {
321            printf("A type must be specified to \"dump all\"\n");
322            goto done;
323        }
324       
325        info = rtems_monitor_object_lookup(type);
326        if (info == 0)
327            goto not_found;
328
329        if (info->dump_header)
330            info->dump_header(verbose);
331        rtems_monitor_object_dump_all(info, verbose);
332    }
333    else
334    {
335        unsigned32          default_node = rtems_monitor_default_node;
336        rtems_monitor_object_type_t last_type = RTEMS_MONITOR_OBJECT_INVALID;
337        rtems_id            id;
338
339        for (arg=1; argv[arg]; arg++)
340        {
341            id = (rtems_id) strtoul(argv[arg], 0, 16);
342            id = rtems_monitor_id_fixup(id, default_node, type);
343            type = (rtems_monitor_object_type_t) rtems_get_class(id);
344
345            /*
346             * Allow the item type to change in the middle
347             * of the command.  If the type changes, then
348             * just dump out a new header and keep on going.
349             */
350            if (type != last_type)
351            {
352                info = rtems_monitor_object_lookup(type);
353                if (info == 0)
354                    goto not_found;
355           
356                if (info->dump_header)
357                    info->dump_header(verbose);
358            }
359
360            if (info == 0)
361            {
362not_found:      printf("Invalid or unsupported type %d\n", type);
363                goto done;
364            }
365
366            rtems_monitor_object_dump_1(info, id, verbose);
367
368            default_node = rtems_get_node(id);
369           
370            last_type = type;
371        }
372    }
373done:
374}
Note: See TracBrowser for help on using the repository browser.