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/qemu-file-types.h"
18 #include "migration/register.h"
20 void s390_init_tod(void)
25 obj
= object_new(TYPE_KVM_S390_TOD
);
27 obj
= object_new(TYPE_QEMU_S390_TOD
);
29 object_property_add_child(qdev_get_machine(), TYPE_S390_TOD
, obj
);
32 qdev_init_nofail(DEVICE(obj
));
35 S390TODState
*s390_get_todstate(void)
37 static S390TODState
*ts
;
40 ts
= S390_TOD(object_resolve_path_type("", TYPE_S390_TOD
, NULL
));
46 #define S390_TOD_CLOCK_VALUE_MISSING 0x00
47 #define S390_TOD_CLOCK_VALUE_PRESENT 0x01
49 static void s390_tod_save(QEMUFile
*f
, void *opaque
)
51 S390TODState
*td
= opaque
;
52 S390TODClass
*tdc
= S390_TOD_GET_CLASS(td
);
56 tdc
->get(td
, &tod
, &err
);
59 error_printf("Guest clock will not be migrated "
60 "which could cause the guest to hang.");
61 qemu_put_byte(f
, S390_TOD_CLOCK_VALUE_MISSING
);
65 qemu_put_byte(f
, S390_TOD_CLOCK_VALUE_PRESENT
);
66 qemu_put_byte(f
, tod
.high
);
67 qemu_put_be64(f
, tod
.low
);
70 static int s390_tod_load(QEMUFile
*f
, void *opaque
, int version_id
)
72 S390TODState
*td
= opaque
;
73 S390TODClass
*tdc
= S390_TOD_GET_CLASS(td
);
77 if (qemu_get_byte(f
) == S390_TOD_CLOCK_VALUE_MISSING
) {
78 warn_report("Guest clock was not migrated. This could "
79 "cause the guest to hang.");
83 tod
.high
= qemu_get_byte(f
);
84 tod
.low
= qemu_get_be64(f
);
86 tdc
->set(td
, &tod
, &err
);
88 error_report_err(err
);
94 static SaveVMHandlers savevm_tod
= {
95 .save_state
= s390_tod_save
,
96 .load_state
= s390_tod_load
,
99 static void s390_tod_realize(DeviceState
*dev
, Error
**errp
)
101 S390TODState
*td
= S390_TOD(dev
);
103 /* Legacy migration interface */
104 register_savevm_live("todclock", 0, 1, &savevm_tod
, td
);
107 static void s390_tod_class_init(ObjectClass
*oc
, void *data
)
109 DeviceClass
*dc
= DEVICE_CLASS(oc
);
111 dc
->desc
= "TOD (Time Of Day) Clock";
112 dc
->realize
= s390_tod_realize
;
113 set_bit(DEVICE_CATEGORY_MISC
, dc
->categories
);
115 /* We only have one TOD clock in the system attached to the machine */
116 dc
->user_creatable
= false;
119 static TypeInfo s390_tod_info
= {
120 .name
= TYPE_S390_TOD
,
121 .parent
= TYPE_DEVICE
,
122 .instance_size
= sizeof(S390TODState
),
123 .class_init
= s390_tod_class_init
,
124 .class_size
= sizeof(S390TODClass
),
128 static void register_types(void)
130 type_register_static(&s390_tod_info
);
132 type_init(register_types
);