2 * TOD (Time Of Day) clock
4 * Copyright 2018 Red Hat, Inc.
5 * Author(s): David Hildenbrand <david@redhat.com>
7 * This work is licensed under the terms of the GNU GPL, version 2 or later.
8 * See the COPYING file in the top-level directory.
11 #include "qemu/osdep.h"
12 #include "hw/s390x/tod.h"
13 #include "qapi/error.h"
14 #include "qemu/error-report.h"
15 #include "sysemu/kvm.h"
16 #include "migration/register.h"
18 void s390_init_tod(void)
23 obj
= object_new(TYPE_KVM_S390_TOD
);
25 obj
= object_new(TYPE_QEMU_S390_TOD
);
27 object_property_add_child(qdev_get_machine(), TYPE_S390_TOD
, obj
, NULL
);
30 qdev_init_nofail(DEVICE(obj
));
33 S390TODState
*s390_get_todstate(void)
35 static S390TODState
*ts
;
38 ts
= S390_TOD(object_resolve_path_type("", TYPE_S390_TOD
, NULL
));
44 #define S390_TOD_CLOCK_VALUE_MISSING 0x00
45 #define S390_TOD_CLOCK_VALUE_PRESENT 0x01
47 static void s390_tod_save(QEMUFile
*f
, void *opaque
)
49 S390TODState
*td
= opaque
;
50 S390TODClass
*tdc
= S390_TOD_GET_CLASS(td
);
54 tdc
->get(td
, &tod
, &err
);
57 error_printf("Guest clock will not be migrated "
58 "which could cause the guest to hang.");
59 qemu_put_byte(f
, S390_TOD_CLOCK_VALUE_MISSING
);
63 qemu_put_byte(f
, S390_TOD_CLOCK_VALUE_PRESENT
);
64 qemu_put_byte(f
, tod
.high
);
65 qemu_put_be64(f
, tod
.low
);
68 static int s390_tod_load(QEMUFile
*f
, void *opaque
, int version_id
)
70 S390TODState
*td
= opaque
;
71 S390TODClass
*tdc
= S390_TOD_GET_CLASS(td
);
75 if (qemu_get_byte(f
) == S390_TOD_CLOCK_VALUE_MISSING
) {
76 warn_report("Guest clock was not migrated. This could "
77 "cause the guest to hang.");
81 tod
.high
= qemu_get_byte(f
);
82 tod
.low
= qemu_get_be64(f
);
84 tdc
->set(td
, &tod
, &err
);
86 error_report_err(err
);
92 static SaveVMHandlers savevm_tod
= {
93 .save_state
= s390_tod_save
,
94 .load_state
= s390_tod_load
,
97 static void s390_tod_realize(DeviceState
*dev
, Error
**errp
)
99 S390TODState
*td
= S390_TOD(dev
);
101 /* Legacy migration interface */
102 register_savevm_live(NULL
, "todclock", 0, 1, &savevm_tod
, td
);
105 static void s390_tod_class_init(ObjectClass
*oc
, void *data
)
107 DeviceClass
*dc
= DEVICE_CLASS(oc
);
109 dc
->desc
= "TOD (Time Of Day) Clock";
110 dc
->realize
= s390_tod_realize
;
111 set_bit(DEVICE_CATEGORY_MISC
, dc
->categories
);
113 /* We only have one TOD clock in the system attached to the machine */
114 dc
->user_creatable
= false;
117 static TypeInfo s390_tod_info
= {
118 .name
= TYPE_S390_TOD
,
119 .parent
= TYPE_DEVICE
,
120 .instance_size
= sizeof(S390TODState
),
121 .class_init
= s390_tod_class_init
,
122 .class_size
= sizeof(S390TODClass
),
126 static void register_types(void)
128 type_register_static(&s390_tod_info
);
130 type_init(register_types
);