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 "qemu/module.h"
16 #include "sysemu/kvm.h"
17 #include "migration/register.h"
19 void s390_init_tod(void)
24 obj
= object_new(TYPE_KVM_S390_TOD
);
26 obj
= object_new(TYPE_QEMU_S390_TOD
);
28 object_property_add_child(qdev_get_machine(), TYPE_S390_TOD
, obj
, NULL
);
31 qdev_init_nofail(DEVICE(obj
));
34 S390TODState
*s390_get_todstate(void)
36 static S390TODState
*ts
;
39 ts
= S390_TOD(object_resolve_path_type("", TYPE_S390_TOD
, NULL
));
45 #define S390_TOD_CLOCK_VALUE_MISSING 0x00
46 #define S390_TOD_CLOCK_VALUE_PRESENT 0x01
48 static void s390_tod_save(QEMUFile
*f
, void *opaque
)
50 S390TODState
*td
= opaque
;
51 S390TODClass
*tdc
= S390_TOD_GET_CLASS(td
);
55 tdc
->get(td
, &tod
, &err
);
58 error_printf("Guest clock will not be migrated "
59 "which could cause the guest to hang.");
60 qemu_put_byte(f
, S390_TOD_CLOCK_VALUE_MISSING
);
64 qemu_put_byte(f
, S390_TOD_CLOCK_VALUE_PRESENT
);
65 qemu_put_byte(f
, tod
.high
);
66 qemu_put_be64(f
, tod
.low
);
69 static int s390_tod_load(QEMUFile
*f
, void *opaque
, int version_id
)
71 S390TODState
*td
= opaque
;
72 S390TODClass
*tdc
= S390_TOD_GET_CLASS(td
);
76 if (qemu_get_byte(f
) == S390_TOD_CLOCK_VALUE_MISSING
) {
77 warn_report("Guest clock was not migrated. This could "
78 "cause the guest to hang.");
82 tod
.high
= qemu_get_byte(f
);
83 tod
.low
= qemu_get_be64(f
);
85 tdc
->set(td
, &tod
, &err
);
87 error_report_err(err
);
93 static SaveVMHandlers savevm_tod
= {
94 .save_state
= s390_tod_save
,
95 .load_state
= s390_tod_load
,
98 static void s390_tod_realize(DeviceState
*dev
, Error
**errp
)
100 S390TODState
*td
= S390_TOD(dev
);
102 /* Legacy migration interface */
103 register_savevm_live(NULL
, "todclock", 0, 1, &savevm_tod
, td
);
106 static void s390_tod_class_init(ObjectClass
*oc
, void *data
)
108 DeviceClass
*dc
= DEVICE_CLASS(oc
);
110 dc
->desc
= "TOD (Time Of Day) Clock";
111 dc
->realize
= s390_tod_realize
;
112 set_bit(DEVICE_CATEGORY_MISC
, dc
->categories
);
114 /* We only have one TOD clock in the system attached to the machine */
115 dc
->user_creatable
= false;
118 static TypeInfo s390_tod_info
= {
119 .name
= TYPE_S390_TOD
,
120 .parent
= TYPE_DEVICE
,
121 .instance_size
= sizeof(S390TODState
),
122 .class_init
= s390_tod_class_init
,
123 .class_size
= sizeof(S390TODClass
),
127 static void register_types(void)
129 type_register_static(&s390_tod_info
);
131 type_init(register_types
);