1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27#include "qemu/osdep.h"
28#include "hw/sysbus.h"
29#include "hw/register.h"
30#include "qemu/bitops.h"
31#include "qapi/error.h"
32#include "qemu/log.h"
33#include "qemu/timer.h"
34
35#ifndef ARM_GEN_TIMER_ERR_DEBUG
36#define ARM_GEN_TIMER_ERR_DEBUG 0
37#endif
38
39#define TYPE_ARM_GEN_TIMER "arm.generic-timer"
40
41#define ARM_GEN_TIMER(obj) \
42 OBJECT_CHECK(ARMGenTimer, (obj), TYPE_ARM_GEN_TIMER)
43
44REG32(COUNTER_CONTROL_REGISTER, 0x0)
45 FIELD(COUNTER_CONTROL_REGISTER, EN, 1, 1)
46 FIELD(COUNTER_CONTROL_REGISTER, HDBG, 1, 0)
47REG32(COUNTER_STATUS_REGISTER, 0x4)
48 FIELD(COUNTER_STATUS_REGISTER, DBGH, 1, 1)
49REG32(CURRENT_COUNTER_VALUE_LOWER_REGISTER, 0x8)
50REG32(CURRENT_COUNTER_VALUE_UPPER_REGISTER, 0xc)
51REG32(BASE_FREQUENCY_ID_REGISTER, 0x20)
52
53#define R_MAX (R_BASE_FREQUENCY_ID_REGISTER + 1)
54
55typedef struct ARMGenTimer {
56 SysBusDevice parent_obj;
57 MemoryRegion iomem;
58
59 bool enabled;
60 uint64_t tick_offset;
61
62 uint32_t regs[R_MAX];
63 RegisterInfo regs_info[R_MAX];
64} ARMGenTimer;
65
66static void counter_control_postw(RegisterInfo *reg, uint64_t val64)
67{
68 ARMGenTimer *s = ARM_GEN_TIMER(reg->opaque);
69 bool new_status = extract32(s->regs[R_COUNTER_CONTROL_REGISTER],
70 R_COUNTER_CONTROL_REGISTER_EN_SHIFT,
71 R_COUNTER_CONTROL_REGISTER_EN_LENGTH);
72 uint64_t current_ticks;
73
74 current_ticks = muldiv64(qemu_clock_get_us(QEMU_CLOCK_VIRTUAL),
75 NANOSECONDS_PER_SECOND, 1000000);
76
77 if ((s->enabled && !new_status) ||
78 (!s->enabled && new_status)) {
79
80 s->tick_offset = current_ticks - s->tick_offset;
81 }
82
83 s->enabled = new_status;
84}
85
86static uint64_t couter_low_value_postr(RegisterInfo *reg, uint64_t val64)
87{
88 ARMGenTimer *s = ARM_GEN_TIMER(reg->opaque);
89 uint64_t current_ticks, total_ticks;
90 uint32_t low_ticks;
91
92 if (s->enabled) {
93 current_ticks = muldiv64(qemu_clock_get_us(QEMU_CLOCK_VIRTUAL),
94 NANOSECONDS_PER_SECOND, 1000000);
95 total_ticks = current_ticks - s->tick_offset;
96 low_ticks = (uint32_t) total_ticks;
97 } else {
98
99 low_ticks = (uint32_t) s->tick_offset;
100 }
101
102 return low_ticks;
103}
104
105static uint64_t couter_high_value_postr(RegisterInfo *reg, uint64_t val64)
106{
107 ARMGenTimer *s = ARM_GEN_TIMER(reg->opaque);
108 uint64_t current_ticks, total_ticks;
109 uint32_t high_ticks;
110
111 if (s->enabled) {
112 current_ticks = muldiv64(qemu_clock_get_us(QEMU_CLOCK_VIRTUAL),
113 NANOSECONDS_PER_SECOND, 1000000);
114 total_ticks = current_ticks - s->tick_offset;
115 high_ticks = (uint32_t) (total_ticks >> 32);
116 } else {
117
118 high_ticks = (uint32_t) (s->tick_offset >> 32);
119 }
120
121 return high_ticks;
122}
123
124
125static RegisterAccessInfo arm_gen_timer_regs_info[] = {
126 { .name = "COUNTER_CONTROL_REGISTER",
127 .decode.addr = A_COUNTER_CONTROL_REGISTER,
128 .rsvd = 0xfffffffc,
129 .post_write = counter_control_postw,
130 },{ .name = "COUNTER_STATUS_REGISTER",
131 .decode.addr = A_COUNTER_STATUS_REGISTER,
132 .rsvd = 0xfffffffd, .ro = 0x2,
133 },{ .name = "CURRENT_COUNTER_VALUE_LOWER_REGISTER",
134 .decode.addr = A_CURRENT_COUNTER_VALUE_LOWER_REGISTER,
135 .post_read = couter_low_value_postr,
136 },{ .name = "CURRENT_COUNTER_VALUE_UPPER_REGISTER",
137 .decode.addr = A_CURRENT_COUNTER_VALUE_UPPER_REGISTER,
138 .post_read = couter_high_value_postr,
139 },{ .name = "BASE_FREQUENCY_ID_REGISTER",
140 .decode.addr = A_BASE_FREQUENCY_ID_REGISTER,
141 }
142};
143
144static void arm_gen_timer_reset(DeviceState *dev)
145{
146 ARMGenTimer *s = ARM_GEN_TIMER(dev);
147 unsigned int i;
148
149 for (i = 0; i < ARRAY_SIZE(s->regs_info); ++i) {
150 register_reset(&s->regs_info[i]);
151 }
152
153 s->tick_offset = 0;
154 s->enabled = false;
155}
156
157static uint64_t arm_gen_timer_read(void *opaque, hwaddr addr, unsigned size)
158{
159 ARMGenTimer *s = ARM_GEN_TIMER(opaque);
160 RegisterInfo *r = &s->regs_info[addr / 4];
161
162 if (!r->data) {
163 qemu_log("%s: Decode error: read from %" HWADDR_PRIx "\n",
164 object_get_canonical_path(OBJECT(s)),
165 addr);
166 return 0;
167 }
168 return register_read(r);
169}
170
171static void arm_gen_timer_write(void *opaque, hwaddr addr, uint64_t value,
172 unsigned size)
173{
174 ARMGenTimer *s = ARM_GEN_TIMER(opaque);
175 RegisterInfo *r = &s->regs_info[addr / 4];
176
177 if (!r->data) {
178 qemu_log("%s: Decode error: write to %" HWADDR_PRIx "=%" PRIx64 "\n",
179 object_get_canonical_path(OBJECT(s)),
180 addr, value);
181 return;
182 }
183 register_write(r, value, ~0);
184}
185
186static void arm_gen_timer_access(MemoryTransaction *tr)
187{
188 MemTxAttrs attr = tr->attr;
189 void *opaque = tr->opaque;
190 hwaddr addr = tr->addr;
191 unsigned size = tr->size;
192 uint64_t value = tr->data.u64;;
193 bool is_write = tr->rw;
194
195 if (is_write && !attr.secure) {
196
197 qemu_log_mask(LOG_GUEST_ERROR,
198 "Non secure writes to the system timestamp generator " \
199 "are invalid\n");
200 return;
201 }
202
203 if (is_write) {
204 arm_gen_timer_write(opaque, addr, value, size);
205 } else {
206 tr->data.u64 = arm_gen_timer_read(opaque, addr, size);
207 }
208}
209
210static const MemoryRegionOps arm_gen_timer_ops = {
211 .access = arm_gen_timer_access,
212 .endianness = DEVICE_LITTLE_ENDIAN,
213 .valid = {
214 .min_access_size = 4,
215 .max_access_size = 4,
216 },
217};
218
219static void arm_gen_timer_realize(DeviceState *dev, Error **errp)
220{
221 ARMGenTimer *s = ARM_GEN_TIMER(dev);
222 const char *prefix = object_get_canonical_path(OBJECT(dev));
223 unsigned int i;
224
225 for (i = 0; i < ARRAY_SIZE(arm_gen_timer_regs_info); ++i) {
226 RegisterInfo *r =
227 &s->regs_info[arm_gen_timer_regs_info[i].decode.addr / 4];
228
229 *r = (RegisterInfo) {
230 .data = (uint8_t *)&s->regs[
231 arm_gen_timer_regs_info[i].decode.addr/4],
232 .data_size = sizeof(uint32_t),
233 .access = &arm_gen_timer_regs_info[i],
234 .debug = ARM_GEN_TIMER_ERR_DEBUG,
235 .prefix = prefix,
236 .opaque = s,
237 };
238 }
239}
240
241static void arm_gen_timer_init(Object *obj)
242{
243 ARMGenTimer *s = ARM_GEN_TIMER(obj);
244 SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
245
246 memory_region_init_io(&s->iomem, obj, &arm_gen_timer_ops, s,
247 TYPE_ARM_GEN_TIMER, R_MAX * 4);
248 sysbus_init_mmio(sbd, &s->iomem);
249}
250
251static const VMStateDescription vmstate_arm_gen_timer = {
252 .name = TYPE_ARM_GEN_TIMER,
253 .version_id = 1,
254 .minimum_version_id = 1,
255 .minimum_version_id_old = 1,
256 .fields = (VMStateField[]) {
257 VMSTATE_UINT32_ARRAY(regs, ARMGenTimer, R_MAX),
258 VMSTATE_END_OF_LIST(),
259 }
260};
261
262static void arm_gen_timer_class_init(ObjectClass *klass, void *data)
263{
264 DeviceClass *dc = DEVICE_CLASS(klass);
265
266 dc->reset = arm_gen_timer_reset;
267 dc->realize = arm_gen_timer_realize;
268 dc->vmsd = &vmstate_arm_gen_timer;
269}
270
271static const TypeInfo arm_gen_timer_info = {
272 .name = TYPE_ARM_GEN_TIMER,
273 .parent = TYPE_SYS_BUS_DEVICE,
274 .instance_size = sizeof(ARMGenTimer),
275 .class_init = arm_gen_timer_class_init,
276 .instance_init = arm_gen_timer_init,
277};
278
279static void arm_gen_timer_register_types(void)
280{
281 type_register_static(&arm_gen_timer_info);
282}
283
284type_init(arm_gen_timer_register_types)
285