18046f374SDavid Hildenbrand /* 28046f374SDavid Hildenbrand * TOD (Time Of Day) clock 38046f374SDavid Hildenbrand * 48046f374SDavid Hildenbrand * Copyright 2018 Red Hat, Inc. 58046f374SDavid Hildenbrand * Author(s): David Hildenbrand <david@redhat.com> 68046f374SDavid Hildenbrand * 78046f374SDavid Hildenbrand * This work is licensed under the terms of the GNU GPL, version 2 or later. 88046f374SDavid Hildenbrand * See the COPYING file in the top-level directory. 98046f374SDavid Hildenbrand */ 108046f374SDavid Hildenbrand 118046f374SDavid Hildenbrand #ifndef HW_S390_TOD_H 128046f374SDavid Hildenbrand #define HW_S390_TOD_H 138046f374SDavid Hildenbrand 148046f374SDavid Hildenbrand #include "hw/qdev.h" 158046f374SDavid Hildenbrand 168046f374SDavid Hildenbrand typedef struct S390TOD { 178046f374SDavid Hildenbrand uint8_t high; 188046f374SDavid Hildenbrand uint64_t low; 198046f374SDavid Hildenbrand } S390TOD; 208046f374SDavid Hildenbrand 218046f374SDavid Hildenbrand #define TYPE_S390_TOD "s390-tod" 228046f374SDavid Hildenbrand #define S390_TOD(obj) OBJECT_CHECK(S390TODState, (obj), TYPE_S390_TOD) 238046f374SDavid Hildenbrand #define S390_TOD_CLASS(oc) OBJECT_CLASS_CHECK(S390TODClass, (oc), \ 248046f374SDavid Hildenbrand TYPE_S390_TOD) 258046f374SDavid Hildenbrand #define S390_TOD_GET_CLASS(obj) OBJECT_GET_CLASS(S390TODClass, (obj), \ 268046f374SDavid Hildenbrand TYPE_S390_TOD) 278046f374SDavid Hildenbrand #define TYPE_KVM_S390_TOD TYPE_S390_TOD "-kvm" 288046f374SDavid Hildenbrand #define TYPE_QEMU_S390_TOD TYPE_S390_TOD "-qemu" 298046f374SDavid Hildenbrand 308046f374SDavid Hildenbrand typedef struct S390TODState { 318046f374SDavid Hildenbrand /* private */ 328046f374SDavid Hildenbrand DeviceState parent_obj; 337de3b1cdSDavid Hildenbrand 34*9bc9d3d1SDavid Hildenbrand /* 35*9bc9d3d1SDavid Hildenbrand * Used by TCG to remember the time base. Used by KVM to backup the TOD 36*9bc9d3d1SDavid Hildenbrand * while the TOD is stopped. 37*9bc9d3d1SDavid Hildenbrand */ 387de3b1cdSDavid Hildenbrand S390TOD base; 39*9bc9d3d1SDavid Hildenbrand /* Used by KVM to remember if the TOD is stopped and base is valid. */ 40*9bc9d3d1SDavid Hildenbrand bool stopped; 418046f374SDavid Hildenbrand } S390TODState; 428046f374SDavid Hildenbrand 438046f374SDavid Hildenbrand typedef struct S390TODClass { 448046f374SDavid Hildenbrand /* private */ 458046f374SDavid Hildenbrand DeviceClass parent_class; 46*9bc9d3d1SDavid Hildenbrand void (*parent_realize)(DeviceState *dev, Error **errp); 478046f374SDavid Hildenbrand 488046f374SDavid Hildenbrand /* public */ 498046f374SDavid Hildenbrand void (*get)(const S390TODState *td, S390TOD *tod, Error **errp); 508046f374SDavid Hildenbrand void (*set)(S390TODState *td, const S390TOD *tod, Error **errp); 518046f374SDavid Hildenbrand } S390TODClass; 528046f374SDavid Hildenbrand 537de3b1cdSDavid Hildenbrand /* The value of the TOD clock for 1.1.1970. */ 547de3b1cdSDavid Hildenbrand #define TOD_UNIX_EPOCH 0x7d91048bca000000ULL 557de3b1cdSDavid Hildenbrand 567de3b1cdSDavid Hildenbrand /* Converts ns to s390's clock format */ 577de3b1cdSDavid Hildenbrand static inline uint64_t time2tod(uint64_t ns) 587de3b1cdSDavid Hildenbrand { 597de3b1cdSDavid Hildenbrand return (ns << 9) / 125 + (((ns & 0xff10000000000000ull) / 125) << 9); 607de3b1cdSDavid Hildenbrand } 617de3b1cdSDavid Hildenbrand 627de3b1cdSDavid Hildenbrand /* Converts s390's clock format to ns */ 637de3b1cdSDavid Hildenbrand static inline uint64_t tod2time(uint64_t t) 647de3b1cdSDavid Hildenbrand { 657de3b1cdSDavid Hildenbrand return ((t >> 9) * 125) + (((t & 0x1ff) * 125) >> 9); 667de3b1cdSDavid Hildenbrand } 677de3b1cdSDavid Hildenbrand 688046f374SDavid Hildenbrand void s390_init_tod(void); 697de3b1cdSDavid Hildenbrand S390TODState *s390_get_todstate(void); 708046f374SDavid Hildenbrand 718046f374SDavid Hildenbrand #endif 72