Each class defines a C struct type to store an instance of the class.
The struct must start with a conf_object_t, and like any Simics configuration object it may also contain any additional configuration parameters required by the specific link.
As usual, if this information needs to be saved in checkpoints, you as the class author are responsible for registering attributes that save and restore it.
typedef struct {
conf_object_t obj;
/* Any link-specific parameters would go here. */
} datagram_link_t;
typedef struct {
conf_object_t obj;
/* Any endpoint-specific state would go here. */
} datagram_link_endpoint_t;
Each link type needs to declare a variable of type link_type_t and fill it with information used by the link library to access functionality that is specific to the link type.
Each of the link_type_t member functions is described in the Link Library API reference.
The link class’s init() method needs to call SIMLINK_init() to attach all link library’s internal information to the link object.
The finalize() method needs to call SIMLINK_finalize().
static conf_object_t *
datagram_link_alloc(conf_class_t *cls)
{
datagram_link_t *dl = MM_ZALLOC(1, datagram_link_t);
return &dl->obj;
}
static void *
datagram_link_init(conf_object_t *obj)
{
datagram_link_t *dl = (datagram_link_t *)obj;
static const link_type_t link_methods = {
.msg_to_attr = msg_to_attr,
.msg_from_attr = msg_from_attr,
.free_msg = free_msg,
.marshal = marshal,
.unmarshal = unmarshal,
.deliver = deliver,
.update_config_value = link_config_value_updated,
.remove_config_value = link_config_value_removed,
};
SIMLINK_init(&dl->obj, &link_methods);
return &dl->obj;
}
static void
datagram_link_finalize(conf_object_t *obj)
{
SIMLINK_finalize(obj);
}
Similarly, the endpoint class’s init() and finalize() methods need to call SIMLINK_endpoint_init() and SIMLINK_endpoint_finalize(), respectively:
static void *
datagram_link_endpoint_init(conf_object_t *obj)
{
datagram_link_endpoint_t *dlep =
(datagram_link_endpoint_t *)obj;
SIMLINK_endpoint_init(&dlep->obj, false);
return dlep;
}
static void
datagram_link_endpoint_finalize(conf_object_t *ep)
{
SIMLINK_endpoint_finalize(ep);
}
Depending on the current configuration, endpoint objects might be created while no device is yet connected. For that reason, device related operations, such as caching an interface, are expected to be done in the
device_changed()callback rather than in thefinalize()function. See alsolink_type_tdocumentation for more information and an example.
The endpoint class also has to have a deinit() function, which has to be, or at least call, SIMLINK_endpoint_disconnect().
After declaring the link class with SIM_create_class(), SIMLINK_register_class() must also be called, with the class as argument.
Similarly, for the endpoint class, SIMLINK_register_endpoint_class() must be called.
It takes two parameters: the endpoint class and the attribute type of a checkpointed in-flight link message.
void
init_local()
{
/* The link library must always be initialised first. */
SIMLINK_init_library();
const class_info_t cl_methods = {
.alloc = datagram_link_alloc,
.init = datagram_link_init,
.finalize = datagram_link_finalize,
.deinit = datagram_link_deinit,
.dealloc = datagram_link_dealloc,
.short_desc = "link that broadcasts byte strings",
.description = "A link that broadcasts byte strings."
};
conf_class_t *cl = SIM_create_class("datagram_link_impl",
&cl_methods);
/* Tell the link library what class represents the link */
SIMLINK_register_class(cl);
const class_info_t epcl_methods = {
.alloc = datagram_link_endpoint_alloc,
.init = datagram_link_endpoint_init,
.finalize = datagram_link_endpoint_finalize,
.deinit = SIMLINK_endpoint_disconnect,
.dealloc = datagram_link_endpoint_dealloc,
.short_desc = "endpoint for datagram links",
.description = "Endpoint for datagram link objects."
};
conf_class_t *epcl = SIM_create_class("datagram_link_endpoint",
&epcl_methods);
static const datagram_link_interface_t dgram_link_if = {
.receive = receive
};
SIM_REGISTER_INTERFACE(epcl, datagram_link, &dgram_link_if);
/* Tell the link library what class we use for endpoints */
SIMLINK_register_endpoint_class(epcl, "d");
}