sun4v-rtc.c 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. /*
  2. * QEMU sun4v Real Time Clock device
  3. *
  4. * The sun4v_rtc device (sun4v tod clock)
  5. *
  6. * Copyright (c) 2016 Artyom Tarasenko
  7. *
  8. * This code is licensed under the GNU GPL v3 or (at your option) any later
  9. * version.
  10. */
  11. #include "qemu/osdep.h"
  12. #include "hw/sysbus.h"
  13. #include "qapi/error.h"
  14. #include "qemu/module.h"
  15. #include "qemu/timer.h"
  16. #include "hw/rtc/sun4v-rtc.h"
  17. #include "trace.h"
  18. #include "qom/object.h"
  19. #define TYPE_SUN4V_RTC "sun4v_rtc"
  20. OBJECT_DECLARE_SIMPLE_TYPE(Sun4vRtc, SUN4V_RTC)
  21. struct Sun4vRtc {
  22. SysBusDevice parent_obj;
  23. MemoryRegion iomem;
  24. };
  25. static uint64_t sun4v_rtc_read(void *opaque, hwaddr addr,
  26. unsigned size)
  27. {
  28. uint64_t val = get_clock_realtime() / NANOSECONDS_PER_SECOND;
  29. if (!(addr & 4ULL)) {
  30. /* accessing the high 32 bits */
  31. val >>= 32;
  32. }
  33. trace_sun4v_rtc_read(addr, val);
  34. return val;
  35. }
  36. static void sun4v_rtc_write(void *opaque, hwaddr addr,
  37. uint64_t val, unsigned size)
  38. {
  39. trace_sun4v_rtc_write(addr, val);
  40. }
  41. static const MemoryRegionOps sun4v_rtc_ops = {
  42. .read = sun4v_rtc_read,
  43. .write = sun4v_rtc_write,
  44. .endianness = DEVICE_NATIVE_ENDIAN,
  45. };
  46. void sun4v_rtc_init(hwaddr addr)
  47. {
  48. DeviceState *dev;
  49. SysBusDevice *s;
  50. dev = qdev_new(TYPE_SUN4V_RTC);
  51. s = SYS_BUS_DEVICE(dev);
  52. sysbus_realize_and_unref(s, &error_fatal);
  53. sysbus_mmio_map(s, 0, addr);
  54. }
  55. static void sun4v_rtc_realize(DeviceState *dev, Error **errp)
  56. {
  57. SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
  58. Sun4vRtc *s = SUN4V_RTC(dev);
  59. memory_region_init_io(&s->iomem, OBJECT(s), &sun4v_rtc_ops, s,
  60. "sun4v-rtc", 0x08ULL);
  61. sysbus_init_mmio(sbd, &s->iomem);
  62. }
  63. static void sun4v_rtc_class_init(ObjectClass *klass, void *data)
  64. {
  65. DeviceClass *dc = DEVICE_CLASS(klass);
  66. dc->realize = sun4v_rtc_realize;
  67. }
  68. static const TypeInfo sun4v_rtc_info = {
  69. .name = TYPE_SUN4V_RTC,
  70. .parent = TYPE_SYS_BUS_DEVICE,
  71. .instance_size = sizeof(Sun4vRtc),
  72. .class_init = sun4v_rtc_class_init,
  73. };
  74. static void sun4v_rtc_register_types(void)
  75. {
  76. type_register_static(&sun4v_rtc_info);
  77. }
  78. type_init(sun4v_rtc_register_types)