]>
Commit | Line | Data |
---|---|---|
a0e89303 AT |
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 | ||
12 | #include "qemu/osdep.h" | |
13 | #include "hw/hw.h" | |
14 | #include "hw/sysbus.h" | |
15 | #include "qemu/timer.h" | |
16 | #include "hw/timer/sun4v-rtc.h" | |
17 | ||
18 | //#define DEBUG_SUN4V_RTC | |
19 | ||
20 | #ifdef DEBUG_SUN4V_RTC | |
21 | #define DPRINTF(fmt, ...) \ | |
22 | do { printf("sun4v_rtc: " fmt , ## __VA_ARGS__); } while (0) | |
23 | #else | |
24 | #define DPRINTF(fmt, ...) do {} while (0) | |
25 | #endif | |
26 | ||
27 | #define TYPE_SUN4V_RTC "sun4v_rtc" | |
28 | #define SUN4V_RTC(obj) OBJECT_CHECK(Sun4vRtc, (obj), TYPE_SUN4V_RTC) | |
29 | ||
30 | typedef struct Sun4vRtc { | |
31 | SysBusDevice parent_obj; | |
32 | ||
33 | MemoryRegion iomem; | |
34 | } Sun4vRtc; | |
35 | ||
36 | static uint64_t sun4v_rtc_read(void *opaque, hwaddr addr, | |
37 | unsigned size) | |
38 | { | |
fff54d22 | 39 | uint64_t val = get_clock_realtime() / NANOSECONDS_PER_SECOND; |
a0e89303 AT |
40 | if (!(addr & 4ULL)) { |
41 | /* accessing the high 32 bits */ | |
42 | val >>= 32; | |
43 | } | |
44 | DPRINTF("read from " TARGET_FMT_plx " val %lx\n", addr, val); | |
45 | return val; | |
46 | } | |
47 | ||
48 | static void sun4v_rtc_write(void *opaque, hwaddr addr, | |
49 | uint64_t val, unsigned size) | |
50 | { | |
51 | DPRINTF("write 0x%x to " TARGET_FMT_plx "\n", (unsigned)val, addr); | |
52 | } | |
53 | ||
54 | static const MemoryRegionOps sun4v_rtc_ops = { | |
55 | .read = sun4v_rtc_read, | |
56 | .write = sun4v_rtc_write, | |
57 | .endianness = DEVICE_NATIVE_ENDIAN, | |
58 | }; | |
59 | ||
60 | void sun4v_rtc_init(hwaddr addr) | |
61 | { | |
62 | DeviceState *dev; | |
63 | SysBusDevice *s; | |
64 | ||
65 | dev = qdev_create(NULL, TYPE_SUN4V_RTC); | |
66 | s = SYS_BUS_DEVICE(dev); | |
67 | ||
68 | qdev_init_nofail(dev); | |
69 | ||
70 | sysbus_mmio_map(s, 0, addr); | |
71 | } | |
72 | ||
73 | static int sun4v_rtc_init1(SysBusDevice *dev) | |
74 | { | |
75 | Sun4vRtc *s = SUN4V_RTC(dev); | |
76 | ||
77 | memory_region_init_io(&s->iomem, OBJECT(s), &sun4v_rtc_ops, s, | |
78 | "sun4v-rtc", 0x08ULL); | |
79 | sysbus_init_mmio(dev, &s->iomem); | |
80 | return 0; | |
81 | } | |
82 | ||
83 | static void sun4v_rtc_class_init(ObjectClass *klass, void *data) | |
84 | { | |
85 | SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); | |
86 | ||
87 | k->init = sun4v_rtc_init1; | |
88 | } | |
89 | ||
90 | static const TypeInfo sun4v_rtc_info = { | |
91 | .name = TYPE_SUN4V_RTC, | |
92 | .parent = TYPE_SYS_BUS_DEVICE, | |
93 | .instance_size = sizeof(Sun4vRtc), | |
94 | .class_init = sun4v_rtc_class_init, | |
95 | }; | |
96 | ||
97 | static void sun4v_rtc_register_types(void) | |
98 | { | |
99 | type_register_static(&sun4v_rtc_info); | |
100 | } | |
101 | ||
102 | type_init(sun4v_rtc_register_types) |