qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

tod-tcg.c (2286B)


      1 /*
      2  * TOD (Time Of Day) clock - TCG implementation
      3  *
      4  * Copyright 2018 Red Hat, Inc.
      5  * Author(s): David Hildenbrand <david@redhat.com>
      6  *
      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.
      9  */
     10 
     11 #include "qemu/osdep.h"
     12 #include "qapi/error.h"
     13 #include "hw/s390x/tod.h"
     14 #include "qemu/timer.h"
     15 #include "qemu/cutils.h"
     16 #include "qemu/module.h"
     17 #include "cpu.h"
     18 #include "tcg/tcg_s390x.h"
     19 #include "sysemu/rtc.h"
     20 
     21 static void qemu_s390_tod_get(const S390TODState *td, S390TOD *tod,
     22                               Error **errp)
     23 {
     24     *tod = td->base;
     25 
     26     tod->low += time2tod(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
     27     if (tod->low < td->base.low) {
     28         tod->high++;
     29     }
     30 }
     31 
     32 static void qemu_s390_tod_set(S390TODState *td, const S390TOD *tod,
     33                               Error **errp)
     34 {
     35     CPUState *cpu;
     36 
     37     td->base = *tod;
     38 
     39     td->base.low -= time2tod(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
     40     if (td->base.low > tod->low) {
     41         td->base.high--;
     42     }
     43 
     44     /*
     45      * The TOD has been changed and we have to recalculate the CKC values
     46      * for all CPUs. We do this asynchronously, as "SET CLOCK should be
     47      * issued only while all other activity on all CPUs .. has been
     48      * suspended".
     49      */
     50     CPU_FOREACH(cpu) {
     51         async_run_on_cpu(cpu, tcg_s390_tod_updated, RUN_ON_CPU_NULL);
     52     }
     53 }
     54 
     55 static void qemu_s390_tod_class_init(ObjectClass *oc, void *data)
     56 {
     57     S390TODClass *tdc = S390_TOD_CLASS(oc);
     58 
     59     tdc->get = qemu_s390_tod_get;
     60     tdc->set = qemu_s390_tod_set;
     61 }
     62 
     63 static void qemu_s390_tod_init(Object *obj)
     64 {
     65     S390TODState *td = S390_TOD(obj);
     66     struct tm tm;
     67 
     68     qemu_get_timedate(&tm, 0);
     69     td->base.high = 0;
     70     td->base.low = TOD_UNIX_EPOCH + (time2tod(mktimegm(&tm)) * 1000000000ULL);
     71     if (td->base.low < TOD_UNIX_EPOCH) {
     72         td->base.high += 1;
     73     }
     74 }
     75 
     76 static const TypeInfo qemu_s390_tod_info = {
     77     .name = TYPE_QEMU_S390_TOD,
     78     .parent = TYPE_S390_TOD,
     79     .instance_size = sizeof(S390TODState),
     80     .instance_init = qemu_s390_tod_init,
     81     .class_init = qemu_s390_tod_class_init,
     82     .class_size = sizeof(S390TODClass),
     83 };
     84 
     85 static void register_types(void)
     86 {
     87     type_register_static(&qemu_s390_tod_info);
     88 }
     89 type_init(register_types);