mirror of
https://gitlab.com/qemu-project/qemu
synced 2024-11-05 20:35:44 +00:00
Generalize QOM publishing of date and time from mc146818rtc.c
The mc146818rtc driver exposes the current RTC date and time via the "date" property in QOM (which is also aliased to the machine's "rtc-time" property). Currently it uses a custom visitor function rtc_get_date to do this. This patch introduces new helpers to the QOM core to expose struct tm valued properties via a getter function, so that this functionality can be more easily duplicated in other RTC implementations. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Alexander Graf <agraf@suse.de>
This commit is contained in:
parent
b194df478a
commit
8e099d14f5
3 changed files with 96 additions and 41 deletions
|
@ -831,49 +831,12 @@ static const MemoryRegionOps cmos_ops = {
|
|||
.endianness = DEVICE_LITTLE_ENDIAN,
|
||||
};
|
||||
|
||||
static void rtc_get_date(Object *obj, Visitor *v, void *opaque,
|
||||
const char *name, Error **errp)
|
||||
static void rtc_get_date(Object *obj, struct tm *current_tm, Error **errp)
|
||||
{
|
||||
Error *err = NULL;
|
||||
RTCState *s = MC146818_RTC(obj);
|
||||
struct tm current_tm;
|
||||
|
||||
rtc_update_time(s);
|
||||
rtc_get_time(s, ¤t_tm);
|
||||
visit_start_struct(v, NULL, "struct tm", name, 0, &err);
|
||||
if (err) {
|
||||
goto out;
|
||||
}
|
||||
visit_type_int32(v, ¤t_tm.tm_year, "tm_year", &err);
|
||||
if (err) {
|
||||
goto out_end;
|
||||
}
|
||||
visit_type_int32(v, ¤t_tm.tm_mon, "tm_mon", &err);
|
||||
if (err) {
|
||||
goto out_end;
|
||||
}
|
||||
visit_type_int32(v, ¤t_tm.tm_mday, "tm_mday", &err);
|
||||
if (err) {
|
||||
goto out_end;
|
||||
}
|
||||
visit_type_int32(v, ¤t_tm.tm_hour, "tm_hour", &err);
|
||||
if (err) {
|
||||
goto out_end;
|
||||
}
|
||||
visit_type_int32(v, ¤t_tm.tm_min, "tm_min", &err);
|
||||
if (err) {
|
||||
goto out_end;
|
||||
}
|
||||
visit_type_int32(v, ¤t_tm.tm_sec, "tm_sec", &err);
|
||||
if (err) {
|
||||
goto out_end;
|
||||
}
|
||||
out_end:
|
||||
error_propagate(errp, err);
|
||||
err = NULL;
|
||||
visit_end_struct(v, errp);
|
||||
out:
|
||||
error_propagate(errp, err);
|
||||
rtc_get_time(s, current_tm);
|
||||
}
|
||||
|
||||
static void rtc_realizefn(DeviceState *dev, Error **errp)
|
||||
|
@ -932,8 +895,7 @@ static void rtc_realizefn(DeviceState *dev, Error **errp)
|
|||
qdev_set_legacy_instance_id(dev, base, 3);
|
||||
qemu_register_reset(rtc_reset, s);
|
||||
|
||||
object_property_add(OBJECT(s), "date", "struct tm",
|
||||
rtc_get_date, NULL, NULL, s, NULL);
|
||||
object_property_add_tm(OBJECT(s), "date", rtc_get_date, NULL);
|
||||
|
||||
object_property_add_alias(qdev_get_machine(), "rtc-time",
|
||||
OBJECT(s), "date", NULL);
|
||||
|
|
|
@ -1203,6 +1203,20 @@ void object_property_add_bool(Object *obj, const char *name,
|
|||
void (*set)(Object *, bool, Error **),
|
||||
Error **errp);
|
||||
|
||||
/**
|
||||
* object_property_add_tm:
|
||||
* @obj: the object to add a property to
|
||||
* @name: the name of the property
|
||||
* @get: the getter or NULL if the property is write-only.
|
||||
* @errp: if an error occurs, a pointer to an area to store the error
|
||||
*
|
||||
* Add a read-only struct tm valued property using a getter function.
|
||||
* This function will add a property of type 'struct tm'.
|
||||
*/
|
||||
void object_property_add_tm(Object *obj, const char *name,
|
||||
void (*get)(Object *, struct tm *, Error **),
|
||||
Error **errp);
|
||||
|
||||
/**
|
||||
* object_property_add_uint8_ptr:
|
||||
* @obj: the object to add a property to
|
||||
|
|
79
qom/object.c
79
qom/object.c
|
@ -1543,6 +1543,85 @@ void object_property_add_bool(Object *obj, const char *name,
|
|||
}
|
||||
}
|
||||
|
||||
typedef struct TMProperty {
|
||||
void (*get)(Object *, struct tm *, Error **);
|
||||
} TMProperty;
|
||||
|
||||
static void property_get_tm(Object *obj, Visitor *v, void *opaque,
|
||||
const char *name, Error **errp)
|
||||
{
|
||||
TMProperty *prop = opaque;
|
||||
Error *err = NULL;
|
||||
struct tm value;
|
||||
|
||||
prop->get(obj, &value, &err);
|
||||
if (err) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
visit_start_struct(v, NULL, "struct tm", name, 0, &err);
|
||||
if (err) {
|
||||
goto out;
|
||||
}
|
||||
visit_type_int32(v, &value.tm_year, "tm_year", &err);
|
||||
if (err) {
|
||||
goto out_end;
|
||||
}
|
||||
visit_type_int32(v, &value.tm_mon, "tm_mon", &err);
|
||||
if (err) {
|
||||
goto out_end;
|
||||
}
|
||||
visit_type_int32(v, &value.tm_mday, "tm_mday", &err);
|
||||
if (err) {
|
||||
goto out_end;
|
||||
}
|
||||
visit_type_int32(v, &value.tm_hour, "tm_hour", &err);
|
||||
if (err) {
|
||||
goto out_end;
|
||||
}
|
||||
visit_type_int32(v, &value.tm_min, "tm_min", &err);
|
||||
if (err) {
|
||||
goto out_end;
|
||||
}
|
||||
visit_type_int32(v, &value.tm_sec, "tm_sec", &err);
|
||||
if (err) {
|
||||
goto out_end;
|
||||
}
|
||||
out_end:
|
||||
error_propagate(errp, err);
|
||||
err = NULL;
|
||||
visit_end_struct(v, errp);
|
||||
out:
|
||||
error_propagate(errp, err);
|
||||
|
||||
}
|
||||
|
||||
static void property_release_tm(Object *obj, const char *name,
|
||||
void *opaque)
|
||||
{
|
||||
TMProperty *prop = opaque;
|
||||
g_free(prop);
|
||||
}
|
||||
|
||||
void object_property_add_tm(Object *obj, const char *name,
|
||||
void (*get)(Object *, struct tm *, Error **),
|
||||
Error **errp)
|
||||
{
|
||||
Error *local_err = NULL;
|
||||
TMProperty *prop = g_malloc0(sizeof(*prop));
|
||||
|
||||
prop->get = get;
|
||||
|
||||
object_property_add(obj, name, "struct tm",
|
||||
get ? property_get_tm : NULL, NULL,
|
||||
property_release_tm,
|
||||
prop, &local_err);
|
||||
if (local_err) {
|
||||
error_propagate(errp, local_err);
|
||||
g_free(prop);
|
||||
}
|
||||
}
|
||||
|
||||
static char *qdev_get_type(Object *obj, Error **errp)
|
||||
{
|
||||
return g_strdup(object_get_typename(obj));
|
||||
|
|
Loading…
Reference in a new issue