forked from Imagelibrary/rtems
from the application code, this file required more visibility than is given by default to application code.
378 lines
11 KiB
C
378 lines
11 KiB
C
/*
|
|
* @(#)object.c 1.9 - 96/01/03
|
|
*
|
|
*
|
|
* RTEMS Monitor "object" support.
|
|
*
|
|
* Used to traverse object lists and print them out.
|
|
* An object can be an RTEMS object (chain based stuff) or
|
|
* a "misc" object such as a device driver.
|
|
*
|
|
* Each object has its own file in this directory (eg: extension.c)
|
|
* That file provides routines to convert a "native" structure
|
|
* to its canonical form, print a canonical structure, etc.
|
|
*
|
|
* TODO:
|
|
* should allow for non-numeric id's???
|
|
*
|
|
* $Id$
|
|
*/
|
|
|
|
#define __RTEMS_VIOLATE_KERNEL_VISIBILITY__
|
|
#include <rtems.h>
|
|
#include "monitor.h"
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h> /* strtoul() */
|
|
|
|
#include <monitor.h>
|
|
|
|
#define NUMELEMS(arr) (sizeof(arr) / sizeof(arr[0]))
|
|
|
|
/*
|
|
* add:
|
|
* next
|
|
*/
|
|
|
|
rtems_monitor_object_info_t rtems_monitor_object_info[] =
|
|
{
|
|
{ RTEMS_MONITOR_OBJECT_CONFIG,
|
|
(void *) 0,
|
|
sizeof(rtems_monitor_config_t),
|
|
(rtems_monitor_object_next_fn) rtems_monitor_config_next,
|
|
(rtems_monitor_object_canonical_fn) rtems_monitor_config_canonical,
|
|
(rtems_monitor_object_dump_header_fn) rtems_monitor_config_dump_header,
|
|
(rtems_monitor_object_dump_fn) rtems_monitor_config_dump,
|
|
},
|
|
{ RTEMS_MONITOR_OBJECT_MPCI,
|
|
(void *) 0,
|
|
sizeof(rtems_monitor_mpci_t),
|
|
(rtems_monitor_object_next_fn) rtems_monitor_mpci_next,
|
|
(rtems_monitor_object_canonical_fn) rtems_monitor_mpci_canonical,
|
|
(rtems_monitor_object_dump_header_fn) rtems_monitor_mpci_dump_header,
|
|
(rtems_monitor_object_dump_fn) rtems_monitor_mpci_dump,
|
|
},
|
|
{ RTEMS_MONITOR_OBJECT_INIT_TASK,
|
|
(void *) 0,
|
|
sizeof(rtems_monitor_init_task_t),
|
|
(rtems_monitor_object_next_fn) rtems_monitor_init_task_next,
|
|
(rtems_monitor_object_canonical_fn) rtems_monitor_init_task_canonical,
|
|
(rtems_monitor_object_dump_header_fn) rtems_monitor_init_task_dump_header,
|
|
(rtems_monitor_object_dump_fn) rtems_monitor_init_task_dump,
|
|
},
|
|
{ RTEMS_MONITOR_OBJECT_TASK,
|
|
(void *) &_RTEMS_tasks_Information,
|
|
sizeof(rtems_monitor_task_t),
|
|
(rtems_monitor_object_next_fn) rtems_monitor_manager_next,
|
|
(rtems_monitor_object_canonical_fn) rtems_monitor_task_canonical,
|
|
(rtems_monitor_object_dump_header_fn) rtems_monitor_task_dump_header,
|
|
(rtems_monitor_object_dump_fn) rtems_monitor_task_dump,
|
|
},
|
|
{ RTEMS_MONITOR_OBJECT_QUEUE,
|
|
(void *) &_Message_queue_Information,
|
|
sizeof(rtems_monitor_queue_t),
|
|
(rtems_monitor_object_next_fn) rtems_monitor_manager_next,
|
|
(rtems_monitor_object_canonical_fn) rtems_monitor_queue_canonical,
|
|
(rtems_monitor_object_dump_header_fn) rtems_monitor_queue_dump_header,
|
|
(rtems_monitor_object_dump_fn) rtems_monitor_queue_dump,
|
|
},
|
|
{ RTEMS_MONITOR_OBJECT_EXTENSION,
|
|
(void *) &_Extension_Information,
|
|
sizeof(rtems_monitor_extension_t),
|
|
(rtems_monitor_object_next_fn) rtems_monitor_manager_next,
|
|
(rtems_monitor_object_canonical_fn) rtems_monitor_extension_canonical,
|
|
(rtems_monitor_object_dump_header_fn) rtems_monitor_extension_dump_header,
|
|
(rtems_monitor_object_dump_fn) rtems_monitor_extension_dump,
|
|
},
|
|
{ RTEMS_MONITOR_OBJECT_DRIVER,
|
|
(void *) 0,
|
|
sizeof(rtems_monitor_driver_t),
|
|
(rtems_monitor_object_next_fn) rtems_monitor_driver_next,
|
|
(rtems_monitor_object_canonical_fn) rtems_monitor_driver_canonical,
|
|
(rtems_monitor_object_dump_header_fn) rtems_monitor_driver_dump_header,
|
|
(rtems_monitor_object_dump_fn) rtems_monitor_driver_dump,
|
|
},
|
|
{ RTEMS_MONITOR_OBJECT_DNAME,
|
|
/* XXX now that the driver name table is allocated from the */
|
|
/* XXX Workspace, this does not work */
|
|
(void *) 0,
|
|
/* (void *) _IO_Driver_name_table, */
|
|
sizeof(rtems_monitor_dname_t),
|
|
(rtems_monitor_object_next_fn) rtems_monitor_dname_next,
|
|
(rtems_monitor_object_canonical_fn) rtems_monitor_dname_canonical,
|
|
(rtems_monitor_object_dump_header_fn) rtems_monitor_dname_dump_header,
|
|
(rtems_monitor_object_dump_fn) rtems_monitor_dname_dump,
|
|
},
|
|
};
|
|
|
|
/*
|
|
* Allow id's to be specified without the node number or
|
|
* type for convenience.
|
|
*/
|
|
|
|
rtems_id
|
|
rtems_monitor_id_fixup(
|
|
rtems_id id,
|
|
unsigned32 default_node,
|
|
rtems_monitor_object_type_t type
|
|
)
|
|
{
|
|
unsigned32 node;
|
|
|
|
node = rtems_get_node(id);
|
|
if (node == 0)
|
|
{
|
|
if (rtems_get_class(id) != OBJECTS_NO_CLASS)
|
|
type = rtems_get_class(id);
|
|
|
|
id = _Objects_Build_id(type, default_node, rtems_get_index(id));
|
|
}
|
|
return id;
|
|
}
|
|
|
|
|
|
rtems_monitor_object_info_t *
|
|
rtems_monitor_object_lookup(
|
|
rtems_monitor_object_type_t type
|
|
)
|
|
{
|
|
rtems_monitor_object_info_t *p;
|
|
for (p = &rtems_monitor_object_info[0];
|
|
p < &rtems_monitor_object_info[NUMELEMS(rtems_monitor_object_info)];
|
|
p++)
|
|
{
|
|
if (p->type == type)
|
|
return p;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
rtems_id
|
|
rtems_monitor_object_canonical_next_remote(
|
|
rtems_monitor_object_type_t type,
|
|
rtems_id id,
|
|
void *canonical
|
|
)
|
|
{
|
|
rtems_id next_id;
|
|
rtems_status_code status;
|
|
rtems_monitor_server_request_t request;
|
|
rtems_monitor_server_response_t response;
|
|
|
|
/*
|
|
* Send request
|
|
*/
|
|
|
|
request.command = RTEMS_MONITOR_SERVER_CANONICAL;
|
|
request.argument0 = (unsigned32) type;
|
|
request.argument1 = (unsigned32) id;
|
|
|
|
status = rtems_monitor_server_request(rtems_get_node(id), &request, &response);
|
|
if (status != RTEMS_SUCCESSFUL)
|
|
goto failed;
|
|
|
|
/*
|
|
* process response
|
|
*/
|
|
|
|
next_id = (rtems_id) response.result0;
|
|
if (next_id != RTEMS_OBJECT_ID_FINAL)
|
|
(void) memcpy(canonical, &response.payload, response.result1);
|
|
|
|
return next_id;
|
|
|
|
failed:
|
|
return RTEMS_OBJECT_ID_FINAL;
|
|
|
|
}
|
|
|
|
|
|
rtems_id
|
|
rtems_monitor_object_canonical_next(
|
|
rtems_monitor_object_info_t *info,
|
|
rtems_id id,
|
|
void *canonical
|
|
)
|
|
{
|
|
rtems_id next_id;
|
|
void *raw_item;
|
|
|
|
if ( ! _Objects_Is_local_id(id))
|
|
next_id = rtems_monitor_object_canonical_next_remote(info->type,
|
|
id,
|
|
canonical);
|
|
else
|
|
{
|
|
next_id = id;
|
|
|
|
raw_item = (void *) info->next(info->object_information,
|
|
canonical,
|
|
&next_id);
|
|
|
|
if (raw_item)
|
|
{
|
|
info->canonical(canonical, raw_item);
|
|
_Thread_Enable_dispatch();
|
|
}
|
|
}
|
|
return next_id;
|
|
}
|
|
|
|
|
|
/*
|
|
* this is routine server invokes locally to get the type
|
|
*/
|
|
|
|
rtems_id
|
|
rtems_monitor_object_canonical_get(
|
|
rtems_monitor_object_type_t type,
|
|
rtems_id id,
|
|
void *canonical,
|
|
unsigned32 *size_p
|
|
)
|
|
{
|
|
rtems_monitor_object_info_t *info;
|
|
rtems_id next_id;
|
|
|
|
*size_p = 0;
|
|
|
|
info = rtems_monitor_object_lookup(type);
|
|
|
|
if (info == 0)
|
|
return RTEMS_OBJECT_ID_FINAL;
|
|
|
|
next_id = rtems_monitor_object_canonical_next(info, id, canonical);
|
|
*size_p = info->size;
|
|
|
|
return next_id;
|
|
}
|
|
|
|
|
|
void
|
|
rtems_monitor_object_dump_1(
|
|
rtems_monitor_object_info_t *info,
|
|
rtems_id id,
|
|
boolean verbose
|
|
)
|
|
{
|
|
rtems_id next_id;
|
|
rtems_monitor_union_t canonical;
|
|
|
|
if ((next_id = rtems_monitor_object_canonical_next(
|
|
info,
|
|
id,
|
|
&canonical)) != RTEMS_OBJECT_ID_FINAL)
|
|
{
|
|
/*
|
|
* If the one we actually got is the one we wanted, then
|
|
* print it out.
|
|
* For ones that have an id field, this works fine,
|
|
* for all others, always dump it out.
|
|
*
|
|
* HACK: the way we determine whether there is an id is a hack.
|
|
*
|
|
* by the way: the reason we try to not have an id, is that some
|
|
* of the canonical structures are almost too big for shared
|
|
* memory driver (eg: mpci)
|
|
*/
|
|
|
|
if ((info->next != rtems_monitor_manager_next) ||
|
|
(id == canonical.generic.id))
|
|
info->dump(&canonical, verbose);
|
|
}
|
|
}
|
|
|
|
void
|
|
rtems_monitor_object_dump_all(
|
|
rtems_monitor_object_info_t *info,
|
|
boolean verbose
|
|
)
|
|
{
|
|
rtems_id next_id;
|
|
rtems_monitor_union_t canonical;
|
|
|
|
next_id = RTEMS_OBJECT_ID_INITIAL(info->type, rtems_monitor_default_node);
|
|
|
|
while ((next_id = rtems_monitor_object_canonical_next(
|
|
info,
|
|
next_id,
|
|
&canonical)) != RTEMS_OBJECT_ID_FINAL)
|
|
{
|
|
info->dump(&canonical, verbose);
|
|
}
|
|
}
|
|
|
|
void
|
|
rtems_monitor_object_cmd(
|
|
int argc,
|
|
char **argv,
|
|
unsigned32 command_arg,
|
|
boolean verbose
|
|
)
|
|
{
|
|
int arg;
|
|
rtems_monitor_object_info_t *info = 0;
|
|
rtems_monitor_object_type_t type = (rtems_monitor_object_type_t) command_arg;
|
|
|
|
/* what is the default type? */
|
|
type = (rtems_monitor_object_type_t) command_arg;
|
|
|
|
if (argc == 1)
|
|
{
|
|
if (type == RTEMS_MONITOR_OBJECT_INVALID)
|
|
{
|
|
printf("A type must be specified to \"dump all\"\n");
|
|
goto done;
|
|
}
|
|
|
|
info = rtems_monitor_object_lookup(type);
|
|
if (info == 0)
|
|
goto not_found;
|
|
|
|
if (info->dump_header)
|
|
info->dump_header(verbose);
|
|
rtems_monitor_object_dump_all(info, verbose);
|
|
}
|
|
else
|
|
{
|
|
unsigned32 default_node = rtems_monitor_default_node;
|
|
rtems_monitor_object_type_t last_type = RTEMS_MONITOR_OBJECT_INVALID;
|
|
rtems_id id;
|
|
|
|
for (arg=1; argv[arg]; arg++)
|
|
{
|
|
id = (rtems_id) strtoul(argv[arg], 0, 0);
|
|
id = rtems_monitor_id_fixup(id, default_node, type);
|
|
type = (rtems_monitor_object_type_t) rtems_get_class(id);
|
|
|
|
/*
|
|
* Allow the item type to change in the middle
|
|
* of the command. If the type changes, then
|
|
* just dump out a new header and keep on going.
|
|
*/
|
|
if (type != last_type)
|
|
{
|
|
info = rtems_monitor_object_lookup(type);
|
|
if (info == 0)
|
|
goto not_found;
|
|
|
|
if (info->dump_header)
|
|
info->dump_header(verbose);
|
|
}
|
|
|
|
if (info == 0)
|
|
{
|
|
not_found: printf("Invalid or unsupported type %d\n", type);
|
|
goto done;
|
|
}
|
|
|
|
rtems_monitor_object_dump_1(info, id, verbose);
|
|
|
|
default_node = rtems_get_node(id);
|
|
|
|
last_type = type;
|
|
}
|
|
}
|
|
done:
|
|
}
|