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
28
29
30
31
32
33
34#include "qemu/osdep.h"
35#include "qapi/error.h"
36#include "qemu/log.h"
37#include "hw/irq.h"
38#include "hw/qdev-properties.h"
39#include "hw/timer/avr_timer16.h"
40#include "trace.h"
41
42
43#define T16_CRA 0x0
44#define T16_CRB 0x1
45#define T16_CRC 0x2
46#define T16_CNTL 0x4
47#define T16_CNTH 0x5
48#define T16_ICRL 0x6
49#define T16_ICRH 0x7
50#define T16_OCRAL 0x8
51#define T16_OCRAH 0x9
52#define T16_OCRBL 0xa
53#define T16_OCRBH 0xb
54#define T16_OCRCL 0xc
55#define T16_OCRCH 0xd
56
57
58#define T16_CRA_WGM01 0x3
59#define T16_CRA_COMC 0xc
60#define T16_CRA_COMB 0x30
61#define T16_CRA_COMA 0xc0
62#define T16_CRA_OC_CONF \
63 (T16_CRA_COMA | T16_CRA_COMB | T16_CRA_COMC)
64
65#define T16_CRB_CS 0x7
66#define T16_CRB_WGM23 0x18
67#define T16_CRB_ICES 0x40
68#define T16_CRB_ICNC 0x80
69
70#define T16_CRC_FOCC 0x20
71#define T16_CRC_FOCB 0x40
72#define T16_CRC_FOCA 0x80
73
74
75#define T16_INT_TOV 0x1
76#define T16_INT_OCA 0x2
77#define T16_INT_OCB 0x4
78#define T16_INT_OCC 0x8
79#define T16_INT_IC 0x20
80
81
82#define T16_CLKSRC_STOPPED 0
83#define T16_CLKSRC_DIV1 1
84#define T16_CLKSRC_DIV8 2
85#define T16_CLKSRC_DIV64 3
86#define T16_CLKSRC_DIV256 4
87#define T16_CLKSRC_DIV1024 5
88#define T16_CLKSRC_EXT_FALLING 6
89#define T16_CLKSRC_EXT_RISING 7
90
91
92#define T16_MODE_NORMAL 0
93#define T16_MODE_CTC_OCRA 4
94#define T16_MODE_CTC_ICR 12
95
96
97#define CLKSRC(t16) (t16->crb & T16_CRB_CS)
98#define MODE(t16) (((t16->crb & T16_CRB_WGM23) >> 1) | \
99 (t16->cra & T16_CRA_WGM01))
100#define CNT(t16) VAL16(t16->cntl, t16->cnth)
101#define OCRA(t16) VAL16(t16->ocral, t16->ocrah)
102#define OCRB(t16) VAL16(t16->ocrbl, t16->ocrbh)
103#define OCRC(t16) VAL16(t16->ocrcl, t16->ocrch)
104#define ICR(t16) VAL16(t16->icrl, t16->icrh)
105
106
107#define VAL16(l, h) ((h << 8) | l)
108#define DB_PRINT(fmt, args...)
109
110static inline int64_t avr_timer16_ns_to_ticks(AVRTimer16State *t16, int64_t t)
111{
112 if (t16->period_ns == 0) {
113 return 0;
114 }
115 return t / t16->period_ns;
116}
117
118static void avr_timer16_update_cnt(AVRTimer16State *t16)
119{
120 uint16_t cnt;
121 cnt = avr_timer16_ns_to_ticks(t16, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) -
122 t16->reset_time_ns);
123 t16->cntl = (uint8_t)(cnt & 0xff);
124 t16->cnth = (uint8_t)((cnt & 0xff00) >> 8);
125}
126
127static inline void avr_timer16_recalc_reset_time(AVRTimer16State *t16)
128{
129 t16->reset_time_ns = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) -
130 CNT(t16) * t16->period_ns;
131}
132
133static void avr_timer16_clock_reset(AVRTimer16State *t16)
134{
135 t16->cntl = 0;
136 t16->cnth = 0;
137 t16->reset_time_ns = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
138}
139
140static void avr_timer16_clksrc_update(AVRTimer16State *t16)
141{
142 uint16_t divider = 0;
143 switch (CLKSRC(t16)) {
144 case T16_CLKSRC_EXT_FALLING:
145 case T16_CLKSRC_EXT_RISING:
146 qemu_log_mask(LOG_UNIMP, "%s: external clock source unsupported\n",
147 __func__);
148 break;
149 case T16_CLKSRC_STOPPED:
150 break;
151 case T16_CLKSRC_DIV1:
152 divider = 1;
153 break;
154 case T16_CLKSRC_DIV8:
155 divider = 8;
156 break;
157 case T16_CLKSRC_DIV64:
158 divider = 64;
159 break;
160 case T16_CLKSRC_DIV256:
161 divider = 256;
162 break;
163 case T16_CLKSRC_DIV1024:
164 divider = 1024;
165 break;
166 default:
167 break;
168 }
169 if (divider) {
170 t16->freq_hz = t16->cpu_freq_hz / divider;
171 t16->period_ns = NANOSECONDS_PER_SECOND / t16->freq_hz;
172 trace_avr_timer16_clksrc_update(t16->freq_hz, t16->period_ns,
173 (uint64_t)(1e6 / t16->freq_hz));
174 }
175}
176
177static void avr_timer16_set_alarm(AVRTimer16State *t16)
178{
179 if (CLKSRC(t16) == T16_CLKSRC_EXT_FALLING ||
180 CLKSRC(t16) == T16_CLKSRC_EXT_RISING ||
181 CLKSRC(t16) == T16_CLKSRC_STOPPED) {
182
183 return;
184 }
185
186 uint64_t alarm_offset = 0xffff;
187 enum NextInterrupt next_interrupt = OVERFLOW;
188
189 switch (MODE(t16)) {
190 case T16_MODE_NORMAL:
191
192 if (OCRA(t16) < alarm_offset && OCRA(t16) > CNT(t16) &&
193 (t16->imsk & T16_INT_OCA)) {
194 alarm_offset = OCRA(t16);
195 next_interrupt = COMPA;
196 }
197 break;
198 case T16_MODE_CTC_OCRA:
199
200 if (OCRA(t16) < alarm_offset && OCRA(t16) > CNT(t16)) {
201 alarm_offset = OCRA(t16);
202 next_interrupt = COMPA;
203 }
204 break;
205 case T16_MODE_CTC_ICR:
206
207 if (ICR(t16) < alarm_offset && ICR(t16) > CNT(t16)) {
208 alarm_offset = ICR(t16);
209 next_interrupt = CAPT;
210 }
211 if (OCRA(t16) < alarm_offset && OCRA(t16) > CNT(t16) &&
212 (t16->imsk & T16_INT_OCA)) {
213 alarm_offset = OCRA(t16);
214 next_interrupt = COMPA;
215 }
216 break;
217 default:
218 qemu_log_mask(LOG_UNIMP, "%s: pwm modes are unsupported\n",
219 __func__);
220 return;
221 }
222 if (OCRB(t16) < alarm_offset && OCRB(t16) > CNT(t16) &&
223 (t16->imsk & T16_INT_OCB)) {
224 alarm_offset = OCRB(t16);
225 next_interrupt = COMPB;
226 }
227 if (OCRC(t16) < alarm_offset && OCRB(t16) > CNT(t16) &&
228 (t16->imsk & T16_INT_OCC)) {
229 alarm_offset = OCRB(t16);
230 next_interrupt = COMPC;
231 }
232 alarm_offset -= CNT(t16);
233
234 t16->next_interrupt = next_interrupt;
235 uint64_t alarm_ns =
236 t16->reset_time_ns + ((CNT(t16) + alarm_offset) * t16->period_ns);
237 timer_mod(t16->timer, alarm_ns);
238
239 trace_avr_timer16_next_alarm(alarm_offset * t16->period_ns);
240}
241
242static void avr_timer16_interrupt(void *opaque)
243{
244 AVRTimer16State *t16 = opaque;
245 uint8_t mode = MODE(t16);
246
247 avr_timer16_update_cnt(t16);
248
249 if (CLKSRC(t16) == T16_CLKSRC_EXT_FALLING ||
250 CLKSRC(t16) == T16_CLKSRC_EXT_RISING ||
251 CLKSRC(t16) == T16_CLKSRC_STOPPED) {
252
253 return;
254 }
255
256 trace_avr_timer16_interrupt_count(CNT(t16));
257
258
259 if (t16->next_interrupt == OVERFLOW) {
260 trace_avr_timer16_interrupt_overflow("counter 0xffff");
261 avr_timer16_clock_reset(t16);
262 if (t16->imsk & T16_INT_TOV) {
263 t16->ifr |= T16_INT_TOV;
264 qemu_set_irq(t16->ovf_irq, 1);
265 }
266 }
267
268 if (mode == T16_MODE_CTC_OCRA && t16->next_interrupt == COMPA) {
269 trace_avr_timer16_interrupt_overflow("CTC OCRA");
270 avr_timer16_clock_reset(t16);
271 }
272
273 if (mode == T16_MODE_CTC_ICR && t16->next_interrupt == CAPT) {
274 trace_avr_timer16_interrupt_overflow("CTC ICR");
275 avr_timer16_clock_reset(t16);
276 if (t16->imsk & T16_INT_IC) {
277 t16->ifr |= T16_INT_IC;
278 qemu_set_irq(t16->capt_irq, 1);
279 }
280 }
281
282 if (t16->imsk & T16_INT_OCA && t16->next_interrupt == COMPA) {
283 t16->ifr |= T16_INT_OCA;
284 qemu_set_irq(t16->compa_irq, 1);
285 }
286 if (t16->imsk & T16_INT_OCB && t16->next_interrupt == COMPB) {
287 t16->ifr |= T16_INT_OCB;
288 qemu_set_irq(t16->compb_irq, 1);
289 }
290 if (t16->imsk & T16_INT_OCC && t16->next_interrupt == COMPC) {
291 t16->ifr |= T16_INT_OCC;
292 qemu_set_irq(t16->compc_irq, 1);
293 }
294 avr_timer16_set_alarm(t16);
295}
296
297static void avr_timer16_reset(DeviceState *dev)
298{
299 AVRTimer16State *t16 = AVR_TIMER16(dev);
300
301 avr_timer16_clock_reset(t16);
302 avr_timer16_clksrc_update(t16);
303 avr_timer16_set_alarm(t16);
304
305 qemu_set_irq(t16->capt_irq, 0);
306 qemu_set_irq(t16->compa_irq, 0);
307 qemu_set_irq(t16->compb_irq, 0);
308 qemu_set_irq(t16->compc_irq, 0);
309 qemu_set_irq(t16->ovf_irq, 0);
310}
311
312static uint64_t avr_timer16_read(void *opaque, hwaddr offset, unsigned size)
313{
314 assert(size == 1);
315 AVRTimer16State *t16 = opaque;
316 uint8_t retval = 0;
317
318 switch (offset) {
319 case T16_CRA:
320 retval = t16->cra;
321 break;
322 case T16_CRB:
323 retval = t16->crb;
324 break;
325 case T16_CRC:
326 retval = t16->crc;
327 break;
328 case T16_CNTL:
329 avr_timer16_update_cnt(t16);
330 t16->rtmp = t16->cnth;
331 retval = t16->cntl;
332 break;
333 case T16_CNTH:
334 retval = t16->rtmp;
335 break;
336 case T16_ICRL:
337
338
339
340
341
342
343 t16->rtmp = t16->icrh;
344 retval = t16->icrl;
345 break;
346 case T16_ICRH:
347 retval = t16->rtmp;
348 break;
349 case T16_OCRAL:
350 retval = t16->ocral;
351 break;
352 case T16_OCRAH:
353 retval = t16->ocrah;
354 break;
355 case T16_OCRBL:
356 retval = t16->ocrbl;
357 break;
358 case T16_OCRBH:
359 retval = t16->ocrbh;
360 break;
361 case T16_OCRCL:
362 retval = t16->ocrcl;
363 break;
364 case T16_OCRCH:
365 retval = t16->ocrch;
366 break;
367 default:
368 break;
369 }
370 trace_avr_timer16_read(offset, retval);
371
372 return (uint64_t)retval;
373}
374
375static void avr_timer16_write(void *opaque, hwaddr offset,
376 uint64_t val64, unsigned size)
377{
378 assert(size == 1);
379 AVRTimer16State *t16 = opaque;
380 uint8_t val8 = (uint8_t)val64;
381 uint8_t prev_clk_src = CLKSRC(t16);
382
383 trace_avr_timer16_write(offset, val8);
384
385 switch (offset) {
386 case T16_CRA:
387 t16->cra = val8;
388 if (t16->cra & T16_CRA_OC_CONF) {
389 qemu_log_mask(LOG_UNIMP, "%s: output compare pins unsupported\n",
390 __func__);
391 }
392 break;
393 case T16_CRB:
394 t16->crb = val8;
395 if (t16->crb & T16_CRB_ICNC) {
396 qemu_log_mask(LOG_UNIMP,
397 "%s: input capture noise canceller unsupported\n",
398 __func__);
399 }
400 if (t16->crb & T16_CRB_ICES) {
401 qemu_log_mask(LOG_UNIMP, "%s: input capture unsupported\n",
402 __func__);
403 }
404 if (CLKSRC(t16) != prev_clk_src) {
405 avr_timer16_clksrc_update(t16);
406 if (prev_clk_src == T16_CLKSRC_STOPPED) {
407 t16->reset_time_ns = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
408 }
409 }
410 break;
411 case T16_CRC:
412 t16->crc = val8;
413 qemu_log_mask(LOG_UNIMP, "%s: output compare pins unsupported\n",
414 __func__);
415 break;
416 case T16_CNTL:
417
418
419
420
421
422
423
424
425
426
427 t16->cntl = val8;
428 t16->cnth = t16->rtmp;
429 avr_timer16_recalc_reset_time(t16);
430 break;
431 case T16_CNTH:
432 t16->rtmp = val8;
433 break;
434 case T16_ICRL:
435
436 if (MODE(t16) == T16_MODE_CTC_ICR) {
437 t16->icrl = val8;
438 t16->icrh = t16->rtmp;
439 }
440 break;
441 case T16_ICRH:
442 if (MODE(t16) == T16_MODE_CTC_ICR) {
443 t16->rtmp = val8;
444 }
445 break;
446 case T16_OCRAL:
447
448
449
450
451 t16->ocral = val8;
452 break;
453 case T16_OCRAH:
454 t16->ocrah = val8;
455 break;
456 case T16_OCRBL:
457 t16->ocrbl = val8;
458 break;
459 case T16_OCRBH:
460 t16->ocrbh = val8;
461 break;
462 case T16_OCRCL:
463 t16->ocrcl = val8;
464 break;
465 case T16_OCRCH:
466 t16->ocrch = val8;
467 break;
468 default:
469 break;
470 }
471 avr_timer16_set_alarm(t16);
472}
473
474static uint64_t avr_timer16_imsk_read(void *opaque,
475 hwaddr offset,
476 unsigned size)
477{
478 assert(size == 1);
479 AVRTimer16State *t16 = opaque;
480 trace_avr_timer16_read_imsk(offset ? 0 : t16->imsk);
481 if (offset != 0) {
482 return 0;
483 }
484 return t16->imsk;
485}
486
487static void avr_timer16_imsk_write(void *opaque, hwaddr offset,
488 uint64_t val64, unsigned size)
489{
490 assert(size == 1);
491 AVRTimer16State *t16 = opaque;
492 trace_avr_timer16_write_imsk(val64);
493 if (offset != 0) {
494 return;
495 }
496 t16->imsk = (uint8_t)val64;
497}
498
499static uint64_t avr_timer16_ifr_read(void *opaque,
500 hwaddr offset,
501 unsigned size)
502{
503 assert(size == 1);
504 AVRTimer16State *t16 = opaque;
505 trace_avr_timer16_read_ifr(offset ? 0 : t16->ifr);
506 if (offset != 0) {
507 return 0;
508 }
509 return t16->ifr;
510}
511
512static void avr_timer16_ifr_write(void *opaque, hwaddr offset,
513 uint64_t val64, unsigned size)
514{
515 assert(size == 1);
516 AVRTimer16State *t16 = opaque;
517 trace_avr_timer16_write_imsk(val64);
518 if (offset != 0) {
519 return;
520 }
521 t16->ifr = (uint8_t)val64;
522}
523
524static const MemoryRegionOps avr_timer16_ops = {
525 .read = avr_timer16_read,
526 .write = avr_timer16_write,
527 .endianness = DEVICE_NATIVE_ENDIAN,
528 .impl = {.max_access_size = 1}
529};
530
531static const MemoryRegionOps avr_timer16_imsk_ops = {
532 .read = avr_timer16_imsk_read,
533 .write = avr_timer16_imsk_write,
534 .endianness = DEVICE_NATIVE_ENDIAN,
535 .impl = {.max_access_size = 1}
536};
537
538static const MemoryRegionOps avr_timer16_ifr_ops = {
539 .read = avr_timer16_ifr_read,
540 .write = avr_timer16_ifr_write,
541 .endianness = DEVICE_NATIVE_ENDIAN,
542 .impl = {.max_access_size = 1}
543};
544
545static Property avr_timer16_properties[] = {
546 DEFINE_PROP_UINT8("id", struct AVRTimer16State, id, 0),
547 DEFINE_PROP_UINT64("cpu-frequency-hz", struct AVRTimer16State,
548 cpu_freq_hz, 0),
549 DEFINE_PROP_END_OF_LIST(),
550};
551
552static void avr_timer16_pr(void *opaque, int irq, int level)
553{
554 AVRTimer16State *s = AVR_TIMER16(opaque);
555
556 s->enabled = !level;
557
558 if (!s->enabled) {
559 avr_timer16_reset(DEVICE(s));
560 }
561}
562
563static void avr_timer16_init(Object *obj)
564{
565 AVRTimer16State *s = AVR_TIMER16(obj);
566
567 sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->capt_irq);
568 sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->compa_irq);
569 sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->compb_irq);
570 sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->compc_irq);
571 sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->ovf_irq);
572
573 memory_region_init_io(&s->iomem, obj, &avr_timer16_ops,
574 s, "avr-timer16", 0xe);
575 memory_region_init_io(&s->imsk_iomem, obj, &avr_timer16_imsk_ops,
576 s, "avr-timer16-intmask", 0x1);
577 memory_region_init_io(&s->ifr_iomem, obj, &avr_timer16_ifr_ops,
578 s, "avr-timer16-intflag", 0x1);
579
580 sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->iomem);
581 sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->imsk_iomem);
582 sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->ifr_iomem);
583 qdev_init_gpio_in(DEVICE(s), avr_timer16_pr, 1);
584}
585
586static void avr_timer16_realize(DeviceState *dev, Error **errp)
587{
588 AVRTimer16State *s = AVR_TIMER16(dev);
589
590 if (s->cpu_freq_hz == 0) {
591 error_setg(errp, "AVR timer16: cpu-frequency-hz property must be set");
592 return;
593 }
594
595 s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, avr_timer16_interrupt, s);
596 s->enabled = true;
597}
598
599static void avr_timer16_class_init(ObjectClass *klass, void *data)
600{
601 DeviceClass *dc = DEVICE_CLASS(klass);
602
603 dc->reset = avr_timer16_reset;
604 dc->realize = avr_timer16_realize;
605 device_class_set_props(dc, avr_timer16_properties);
606}
607
608static const TypeInfo avr_timer16_info = {
609 .name = TYPE_AVR_TIMER16,
610 .parent = TYPE_SYS_BUS_DEVICE,
611 .instance_size = sizeof(AVRTimer16State),
612 .instance_init = avr_timer16_init,
613 .class_init = avr_timer16_class_init,
614};
615
616static void avr_timer16_register_types(void)
617{
618 type_register_static(&avr_timer16_info);
619}
620
621type_init(avr_timer16_register_types)
622