xref: /qemu/hw/timer/hpet.c (revision 09ac62682b8d2a8bac36d068f63a31331cc6259a)
1 /*
2  *  High Precision Event Timer emulation
3  *
4  *  Copyright (c) 2007 Alexander Graf
5  *  Copyright (c) 2008 IBM Corporation
6  *
7  *  Authors: Beth Kon <bkon@us.ibm.com>
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
21  *
22  * *****************************************************************
23  *
24  * This driver attempts to emulate an HPET device in software.
25  */
26 
27 #include "qemu/osdep.h"
28 #include "hw/irq.h"
29 #include "qapi/error.h"
30 #include "qemu/error-report.h"
31 #include "qemu/timer.h"
32 #include "hw/qdev-properties.h"
33 #include "hw/timer/hpet.h"
34 #include "hw/sysbus.h"
35 #include "hw/rtc/mc146818rtc.h"
36 #include "hw/rtc/mc146818rtc_regs.h"
37 #include "migration/vmstate.h"
38 #include "hw/timer/i8254.h"
39 #include "exec/address-spaces.h"
40 #include "qom/object.h"
41 #include "trace.h"
42 
43 struct hpet_fw_config hpet_fw_cfg = {.count = UINT8_MAX};
44 
45 #define HPET_MSI_SUPPORT        0
46 
47 OBJECT_DECLARE_SIMPLE_TYPE(HPETState, HPET)
48 
49 struct HPETState;
50 typedef struct HPETTimer {  /* timers */
51     uint8_t tn;             /*timer number*/
52     QEMUTimer *qemu_timer;
53     struct HPETState *state;
54     /* Memory-mapped, software visible timer registers */
55     uint64_t config;        /* configuration/cap */
56     uint64_t cmp;           /* comparator */
57     uint64_t fsb;           /* FSB route */
58     /* Hidden register state */
59     uint64_t cmp64;         /* comparator (extended to counter width) */
60     uint64_t period;        /* Last value written to comparator */
61     uint8_t wrap_flag;      /* timer pop will indicate wrap for one-shot 32-bit
62                              * mode. Next pop will be actual timer expiration.
63                              */
64     uint64_t last;          /* last value armed, to avoid timer storms */
65 } HPETTimer;
66 
67 struct HPETState {
68     /*< private >*/
69     SysBusDevice parent_obj;
70     /*< public >*/
71 
72     MemoryRegion iomem;
73     uint64_t hpet_offset;
74     bool hpet_offset_saved;
75     qemu_irq irqs[HPET_NUM_IRQ_ROUTES];
76     uint32_t flags;
77     uint8_t rtc_irq_level;
78     qemu_irq pit_enabled;
79     uint8_t num_timers;
80     uint32_t intcap;
81     HPETTimer timer[HPET_MAX_TIMERS];
82 
83     /* Memory-mapped, software visible registers */
84     uint64_t capability;        /* capabilities */
85     uint64_t config;            /* configuration */
86     uint64_t isr;               /* interrupt status reg */
87     uint64_t hpet_counter;      /* main counter */
88     uint8_t  hpet_id;           /* instance id */
89 };
90 
91 static uint32_t hpet_in_legacy_mode(HPETState *s)
92 {
93     return s->config & HPET_CFG_LEGACY;
94 }
95 
96 static uint32_t timer_int_route(struct HPETTimer *timer)
97 {
98     return (timer->config & HPET_TN_INT_ROUTE_MASK) >> HPET_TN_INT_ROUTE_SHIFT;
99 }
100 
101 static uint32_t timer_fsb_route(HPETTimer *t)
102 {
103     return t->config & HPET_TN_FSB_ENABLE;
104 }
105 
106 static uint32_t hpet_enabled(HPETState *s)
107 {
108     return s->config & HPET_CFG_ENABLE;
109 }
110 
111 static uint32_t timer_is_periodic(HPETTimer *t)
112 {
113     return t->config & HPET_TN_PERIODIC;
114 }
115 
116 static uint32_t timer_enabled(HPETTimer *t)
117 {
118     return t->config & HPET_TN_ENABLE;
119 }
120 
121 static uint32_t hpet_time_after(uint64_t a, uint64_t b)
122 {
123     return ((int64_t)(b - a) < 0);
124 }
125 
126 static uint64_t ticks_to_ns(uint64_t value)
127 {
128     return value * HPET_CLK_PERIOD;
129 }
130 
131 static uint64_t ns_to_ticks(uint64_t value)
132 {
133     return value / HPET_CLK_PERIOD;
134 }
135 
136 static uint64_t hpet_fixup_reg(uint64_t new, uint64_t old, uint64_t mask)
137 {
138     new &= mask;
139     new |= old & ~mask;
140     return new;
141 }
142 
143 static int activating_bit(uint64_t old, uint64_t new, uint64_t mask)
144 {
145     return (!(old & mask) && (new & mask));
146 }
147 
148 static int deactivating_bit(uint64_t old, uint64_t new, uint64_t mask)
149 {
150     return ((old & mask) && !(new & mask));
151 }
152 
153 static uint64_t hpet_get_ticks(HPETState *s)
154 {
155     return ns_to_ticks(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + s->hpet_offset);
156 }
157 
158 static uint64_t hpet_get_ns(HPETState *s, uint64_t tick)
159 {
160     return ticks_to_ns(tick) - s->hpet_offset;
161 }
162 
163 /*
164  * calculate next value of the general counter that matches the
165  * target (either entirely, or the low 32-bit only depending on
166  * the timer mode).
167  */
168 static uint64_t hpet_calculate_cmp64(HPETTimer *t, uint64_t cur_tick, uint64_t target)
169 {
170     if (t->config & HPET_TN_32BIT) {
171         uint64_t result = deposit64(cur_tick, 0, 32, target);
172         if (result < cur_tick) {
173             result += 0x100000000ULL;
174         }
175         return result;
176     } else {
177         return target;
178     }
179 }
180 
181 static uint64_t hpet_next_wrap(uint64_t cur_tick)
182 {
183     return (cur_tick | 0xffffffffU) + 1;
184 }
185 
186 static void update_irq(struct HPETTimer *timer, int set)
187 {
188     uint64_t mask;
189     HPETState *s;
190     int route;
191 
192     if (timer->tn <= 1 && hpet_in_legacy_mode(timer->state)) {
193         /* if LegacyReplacementRoute bit is set, HPET specification requires
194          * timer0 be routed to IRQ0 in NON-APIC or IRQ2 in the I/O APIC,
195          * timer1 be routed to IRQ8 in NON-APIC or IRQ8 in the I/O APIC.
196          */
197         route = (timer->tn == 0) ? 0 : RTC_ISA_IRQ;
198     } else {
199         route = timer_int_route(timer);
200     }
201     s = timer->state;
202     mask = 1 << timer->tn;
203 
204     if (set && (timer->config & HPET_TN_TYPE_LEVEL)) {
205         /*
206          * If HPET_TN_ENABLE bit is 0, "the timer will still operate and
207          * generate appropriate status bits, but will not cause an interrupt"
208          */
209         s->isr |= mask;
210     } else {
211         s->isr &= ~mask;
212     }
213 
214     if (set && timer_enabled(timer) && hpet_enabled(s)) {
215         if (timer_fsb_route(timer)) {
216             address_space_stl_le(&address_space_memory, timer->fsb >> 32,
217                                  timer->fsb & 0xffffffff, MEMTXATTRS_UNSPECIFIED,
218                                  NULL);
219         } else if (timer->config & HPET_TN_TYPE_LEVEL) {
220             qemu_irq_raise(s->irqs[route]);
221         } else {
222             qemu_irq_pulse(s->irqs[route]);
223         }
224     } else {
225         if (!timer_fsb_route(timer)) {
226             qemu_irq_lower(s->irqs[route]);
227         }
228     }
229 }
230 
231 static int hpet_pre_save(void *opaque)
232 {
233     HPETState *s = opaque;
234 
235     /* save current counter value */
236     if (hpet_enabled(s)) {
237         s->hpet_counter = hpet_get_ticks(s);
238     }
239 
240     return 0;
241 }
242 
243 static int hpet_pre_load(void *opaque)
244 {
245     HPETState *s = opaque;
246 
247     /* version 1 only supports 3, later versions will load the actual value */
248     s->num_timers = HPET_MIN_TIMERS;
249     return 0;
250 }
251 
252 static bool hpet_validate_num_timers(void *opaque, int version_id)
253 {
254     HPETState *s = opaque;
255 
256     if (s->num_timers < HPET_MIN_TIMERS) {
257         return false;
258     } else if (s->num_timers > HPET_MAX_TIMERS) {
259         return false;
260     }
261     return true;
262 }
263 
264 static int hpet_post_load(void *opaque, int version_id)
265 {
266     HPETState *s = opaque;
267     int i;
268 
269     for (i = 0; i < s->num_timers; i++) {
270         HPETTimer *t = &s->timer[i];
271         t->cmp64 = hpet_calculate_cmp64(t, s->hpet_counter, t->cmp);
272         t->last = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) - NANOSECONDS_PER_SECOND;
273     }
274     /* Recalculate the offset between the main counter and guest time */
275     if (!s->hpet_offset_saved) {
276         s->hpet_offset = ticks_to_ns(s->hpet_counter)
277                         - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
278     }
279 
280     /* Push number of timers into capability returned via HPET_ID */
281     s->capability &= ~HPET_ID_NUM_TIM_MASK;
282     s->capability |= (s->num_timers - 1) << HPET_ID_NUM_TIM_SHIFT;
283     hpet_fw_cfg.hpet[s->hpet_id].event_timer_block_id = (uint32_t)s->capability;
284 
285     /* Derive HPET_MSI_SUPPORT from the capability of the first timer. */
286     s->flags &= ~(1 << HPET_MSI_SUPPORT);
287     if (s->timer[0].config & HPET_TN_FSB_CAP) {
288         s->flags |= 1 << HPET_MSI_SUPPORT;
289     }
290     return 0;
291 }
292 
293 static bool hpet_offset_needed(void *opaque)
294 {
295     HPETState *s = opaque;
296 
297     return hpet_enabled(s) && s->hpet_offset_saved;
298 }
299 
300 static bool hpet_rtc_irq_level_needed(void *opaque)
301 {
302     HPETState *s = opaque;
303 
304     return s->rtc_irq_level != 0;
305 }
306 
307 static const VMStateDescription vmstate_hpet_rtc_irq_level = {
308     .name = "hpet/rtc_irq_level",
309     .version_id = 1,
310     .minimum_version_id = 1,
311     .needed = hpet_rtc_irq_level_needed,
312     .fields = (const VMStateField[]) {
313         VMSTATE_UINT8(rtc_irq_level, HPETState),
314         VMSTATE_END_OF_LIST()
315     }
316 };
317 
318 static const VMStateDescription vmstate_hpet_offset = {
319     .name = "hpet/offset",
320     .version_id = 1,
321     .minimum_version_id = 1,
322     .needed = hpet_offset_needed,
323     .fields = (const VMStateField[]) {
324         VMSTATE_UINT64(hpet_offset, HPETState),
325         VMSTATE_END_OF_LIST()
326     }
327 };
328 
329 static const VMStateDescription vmstate_hpet_timer = {
330     .name = "hpet_timer",
331     .version_id = 1,
332     .minimum_version_id = 1,
333     .fields = (const VMStateField[]) {
334         VMSTATE_UINT8(tn, HPETTimer),
335         VMSTATE_UINT64(config, HPETTimer),
336         VMSTATE_UINT64(cmp, HPETTimer),
337         VMSTATE_UINT64(fsb, HPETTimer),
338         VMSTATE_UINT64(period, HPETTimer),
339         VMSTATE_UINT8(wrap_flag, HPETTimer),
340         VMSTATE_TIMER_PTR(qemu_timer, HPETTimer),
341         VMSTATE_END_OF_LIST()
342     }
343 };
344 
345 static const VMStateDescription vmstate_hpet = {
346     .name = "hpet",
347     .version_id = 2,
348     .minimum_version_id = 1,
349     .pre_save = hpet_pre_save,
350     .pre_load = hpet_pre_load,
351     .post_load = hpet_post_load,
352     .fields = (const VMStateField[]) {
353         VMSTATE_UINT64(config, HPETState),
354         VMSTATE_UINT64(isr, HPETState),
355         VMSTATE_UINT64(hpet_counter, HPETState),
356         VMSTATE_UINT8_V(num_timers, HPETState, 2),
357         VMSTATE_VALIDATE("num_timers in range", hpet_validate_num_timers),
358         VMSTATE_STRUCT_VARRAY_UINT8(timer, HPETState, num_timers, 0,
359                                     vmstate_hpet_timer, HPETTimer),
360         VMSTATE_END_OF_LIST()
361     },
362     .subsections = (const VMStateDescription * const []) {
363         &vmstate_hpet_rtc_irq_level,
364         &vmstate_hpet_offset,
365         NULL
366     }
367 };
368 
369 static void hpet_arm(HPETTimer *t, uint64_t tick)
370 {
371     uint64_t ns = hpet_get_ns(t->state, tick);
372 
373     /* Clamp period to reasonable min value (1 us) */
374     if (timer_is_periodic(t) && ns - t->last < 1000) {
375         ns = t->last + 1000;
376     }
377 
378     t->last = ns;
379     timer_mod(t->qemu_timer, ns);
380 }
381 
382 /*
383  * timer expiration callback
384  */
385 static void hpet_timer(void *opaque)
386 {
387     HPETTimer *t = opaque;
388     uint64_t period = t->period;
389     uint64_t cur_tick = hpet_get_ticks(t->state);
390 
391     if (timer_is_periodic(t) && period != 0) {
392         while (hpet_time_after(cur_tick, t->cmp64)) {
393             t->cmp64 += period;
394         }
395         if (t->config & HPET_TN_32BIT) {
396             t->cmp = (uint32_t)t->cmp64;
397         } else {
398             t->cmp = t->cmp64;
399         }
400         hpet_arm(t, t->cmp64);
401     } else if (t->wrap_flag) {
402         t->wrap_flag = 0;
403         hpet_arm(t, t->cmp64);
404     }
405     update_irq(t, 1);
406 }
407 
408 static void hpet_set_timer(HPETTimer *t)
409 {
410     uint64_t cur_tick = hpet_get_ticks(t->state);
411 
412     t->wrap_flag = 0;
413     t->cmp64 = hpet_calculate_cmp64(t, cur_tick, t->cmp);
414     if (t->config & HPET_TN_32BIT) {
415 
416         /* hpet spec says in one-shot 32-bit mode, generate an interrupt when
417          * counter wraps in addition to an interrupt with comparator match.
418          */
419         if (!timer_is_periodic(t) && t->cmp64 > hpet_next_wrap(cur_tick)) {
420             t->wrap_flag = 1;
421             hpet_arm(t, hpet_next_wrap(cur_tick));
422             return;
423         }
424     }
425     hpet_arm(t, t->cmp64);
426 }
427 
428 static void hpet_del_timer(HPETTimer *t)
429 {
430     HPETState *s = t->state;
431     timer_del(t->qemu_timer);
432 
433     if (s->isr & (1 << t->tn)) {
434         /* For level-triggered interrupt, this leaves ISR set but lowers irq.  */
435         update_irq(t, 1);
436     }
437 }
438 
439 static uint64_t hpet_ram_read(void *opaque, hwaddr addr,
440                               unsigned size)
441 {
442     HPETState *s = opaque;
443     int shift = (addr & 4) * 8;
444     uint64_t cur_tick;
445 
446     trace_hpet_ram_read(addr);
447 
448     /*address range of all TN regs*/
449     if (addr >= 0x100 && addr <= 0x3ff) {
450         uint8_t timer_id = (addr - 0x100) / 0x20;
451         HPETTimer *timer = &s->timer[timer_id];
452 
453         if (timer_id > s->num_timers) {
454             trace_hpet_timer_id_out_of_range(timer_id);
455             return 0;
456         }
457 
458         switch (addr & 0x18) {
459         case HPET_TN_CFG: // including interrupt capabilities
460             return timer->config >> shift;
461         case HPET_TN_CMP: // comparator register
462             return timer->cmp >> shift;
463         case HPET_TN_ROUTE:
464             return timer->fsb >> shift;
465         default:
466             trace_hpet_ram_read_invalid();
467             break;
468         }
469     } else {
470         switch (addr & ~4) {
471         case HPET_ID: // including HPET_PERIOD
472             return s->capability >> shift;
473         case HPET_CFG:
474             return s->config >> shift;
475         case HPET_COUNTER:
476             if (hpet_enabled(s)) {
477                 cur_tick = hpet_get_ticks(s);
478             } else {
479                 cur_tick = s->hpet_counter;
480             }
481             trace_hpet_ram_read_reading_counter(addr & 4, cur_tick);
482             return cur_tick >> shift;
483         case HPET_STATUS:
484             return s->isr >> shift;
485         default:
486             trace_hpet_ram_read_invalid();
487             break;
488         }
489     }
490     return 0;
491 }
492 
493 static void hpet_ram_write(void *opaque, hwaddr addr,
494                            uint64_t value, unsigned size)
495 {
496     int i;
497     HPETState *s = opaque;
498     int shift = (addr & 4) * 8;
499     int len = MIN(size * 8, 64 - shift);
500     uint64_t old_val, new_val, cleared;
501 
502     trace_hpet_ram_write(addr, value);
503 
504     /*address range of all TN regs*/
505     if (addr >= 0x100 && addr <= 0x3ff) {
506         uint8_t timer_id = (addr - 0x100) / 0x20;
507         HPETTimer *timer = &s->timer[timer_id];
508 
509         trace_hpet_ram_write_timer_id(timer_id);
510         if (timer_id > s->num_timers) {
511             trace_hpet_timer_id_out_of_range(timer_id);
512             return;
513         }
514         switch (addr & 0x18) {
515         case HPET_TN_CFG:
516             trace_hpet_ram_write_tn_cfg(addr & 4);
517             old_val = timer->config;
518             new_val = deposit64(old_val, shift, len, value);
519             new_val = hpet_fixup_reg(new_val, old_val, HPET_TN_CFG_WRITE_MASK);
520             if (deactivating_bit(old_val, new_val, HPET_TN_TYPE_LEVEL)) {
521                 /*
522                  * Do this before changing timer->config; otherwise, if
523                  * HPET_TN_FSB is set, update_irq will not lower the qemu_irq.
524                  */
525                 update_irq(timer, 0);
526             }
527             timer->config = new_val;
528             if (activating_bit(old_val, new_val, HPET_TN_ENABLE)
529                 && (s->isr & (1 << timer_id))) {
530                 update_irq(timer, 1);
531             }
532             if (new_val & HPET_TN_32BIT) {
533                 timer->cmp = (uint32_t)timer->cmp;
534                 timer->period = (uint32_t)timer->period;
535             }
536             if (hpet_enabled(s)) {
537                 hpet_set_timer(timer);
538             }
539             break;
540         case HPET_TN_CMP: // comparator register
541             if (timer->config & HPET_TN_32BIT) {
542                 /* High 32-bits are zero, leave them untouched.  */
543                 if (shift) {
544                     trace_hpet_ram_write_invalid_tn_cmp();
545                     break;
546                 }
547                 len = 64;
548                 value = (uint32_t) value;
549             }
550             trace_hpet_ram_write_tn_cmp(addr & 4);
551             if (!timer_is_periodic(timer)
552                 || (timer->config & HPET_TN_SETVAL)) {
553                 timer->cmp = deposit64(timer->cmp, shift, len, value);
554             }
555             if (timer_is_periodic(timer)) {
556                 timer->period = deposit64(timer->period, shift, len, value);
557             }
558             timer->config &= ~HPET_TN_SETVAL;
559             if (hpet_enabled(s)) {
560                 hpet_set_timer(timer);
561             }
562             break;
563         case HPET_TN_ROUTE:
564             timer->fsb = deposit64(timer->fsb, shift, len, value);
565             break;
566         default:
567             trace_hpet_ram_write_invalid();
568             break;
569         }
570         return;
571     } else {
572         switch (addr & ~4) {
573         case HPET_ID:
574             return;
575         case HPET_CFG:
576             old_val = s->config;
577             new_val = deposit64(old_val, shift, len, value);
578             new_val = hpet_fixup_reg(new_val, old_val, HPET_CFG_WRITE_MASK);
579             s->config = new_val;
580             if (activating_bit(old_val, new_val, HPET_CFG_ENABLE)) {
581                 /* Enable main counter and interrupt generation. */
582                 s->hpet_offset =
583                     ticks_to_ns(s->hpet_counter) - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
584                 for (i = 0; i < s->num_timers; i++) {
585                     if (timer_enabled(&s->timer[i]) && (s->isr & (1 << i))) {
586                         update_irq(&s->timer[i], 1);
587                     }
588                     hpet_set_timer(&s->timer[i]);
589                 }
590             } else if (deactivating_bit(old_val, new_val, HPET_CFG_ENABLE)) {
591                 /* Halt main counter and disable interrupt generation. */
592                 s->hpet_counter = hpet_get_ticks(s);
593                 for (i = 0; i < s->num_timers; i++) {
594                     hpet_del_timer(&s->timer[i]);
595                 }
596             }
597             /* i8254 and RTC output pins are disabled
598              * when HPET is in legacy mode */
599             if (activating_bit(old_val, new_val, HPET_CFG_LEGACY)) {
600                 qemu_set_irq(s->pit_enabled, 0);
601                 qemu_irq_lower(s->irqs[0]);
602                 qemu_irq_lower(s->irqs[RTC_ISA_IRQ]);
603             } else if (deactivating_bit(old_val, new_val, HPET_CFG_LEGACY)) {
604                 qemu_irq_lower(s->irqs[0]);
605                 qemu_set_irq(s->pit_enabled, 1);
606                 qemu_set_irq(s->irqs[RTC_ISA_IRQ], s->rtc_irq_level);
607             }
608             break;
609         case HPET_STATUS:
610             new_val = value << shift;
611             cleared = new_val & s->isr;
612             for (i = 0; i < s->num_timers; i++) {
613                 if (cleared & (1 << i)) {
614                     update_irq(&s->timer[i], 0);
615                 }
616             }
617             break;
618         case HPET_COUNTER:
619             if (hpet_enabled(s)) {
620                 trace_hpet_ram_write_counter_write_while_enabled();
621             }
622             s->hpet_counter = deposit64(s->hpet_counter, shift, len, value);
623             break;
624         default:
625             trace_hpet_ram_write_invalid();
626             break;
627         }
628     }
629 }
630 
631 static const MemoryRegionOps hpet_ram_ops = {
632     .read = hpet_ram_read,
633     .write = hpet_ram_write,
634     .valid = {
635         .min_access_size = 4,
636         .max_access_size = 8,
637     },
638     .impl = {
639         .min_access_size = 4,
640         .max_access_size = 8,
641     },
642     .endianness = DEVICE_NATIVE_ENDIAN,
643 };
644 
645 static void hpet_reset(DeviceState *d)
646 {
647     HPETState *s = HPET(d);
648     SysBusDevice *sbd = SYS_BUS_DEVICE(d);
649     int i;
650 
651     for (i = 0; i < s->num_timers; i++) {
652         HPETTimer *timer = &s->timer[i];
653 
654         hpet_del_timer(timer);
655         timer->cmp = ~0ULL;
656         timer->config = HPET_TN_PERIODIC_CAP | HPET_TN_SIZE_CAP;
657         if (s->flags & (1 << HPET_MSI_SUPPORT)) {
658             timer->config |= HPET_TN_FSB_CAP;
659         }
660         /* advertise availability of ioapic int */
661         timer->config |=  (uint64_t)s->intcap << 32;
662         timer->period = 0ULL;
663         timer->wrap_flag = 0;
664     }
665 
666     qemu_set_irq(s->pit_enabled, 1);
667     s->hpet_counter = 0ULL;
668     s->hpet_offset = 0ULL;
669     s->config = 0ULL;
670     hpet_fw_cfg.hpet[s->hpet_id].event_timer_block_id = (uint32_t)s->capability;
671     hpet_fw_cfg.hpet[s->hpet_id].address = sbd->mmio[0].addr;
672 
673     /* to document that the RTC lowers its output on reset as well */
674     s->rtc_irq_level = 0;
675 }
676 
677 static void hpet_handle_legacy_irq(void *opaque, int n, int level)
678 {
679     HPETState *s = HPET(opaque);
680 
681     if (n == HPET_LEGACY_PIT_INT) {
682         if (!hpet_in_legacy_mode(s)) {
683             qemu_set_irq(s->irqs[0], level);
684         }
685     } else {
686         s->rtc_irq_level = level;
687         if (!hpet_in_legacy_mode(s)) {
688             qemu_set_irq(s->irqs[RTC_ISA_IRQ], level);
689         }
690     }
691 }
692 
693 static void hpet_init(Object *obj)
694 {
695     SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
696     HPETState *s = HPET(obj);
697 
698     /* HPET Area */
699     memory_region_init_io(&s->iomem, obj, &hpet_ram_ops, s, "hpet", HPET_LEN);
700     sysbus_init_mmio(sbd, &s->iomem);
701 }
702 
703 static void hpet_realize(DeviceState *dev, Error **errp)
704 {
705     SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
706     HPETState *s = HPET(dev);
707     int i;
708     HPETTimer *timer;
709 
710     if (!s->intcap) {
711         warn_report("Hpet's intcap not initialized");
712     }
713     if (hpet_fw_cfg.count == UINT8_MAX) {
714         /* first instance */
715         hpet_fw_cfg.count = 0;
716     }
717 
718     if (hpet_fw_cfg.count == 8) {
719         error_setg(errp, "Only 8 instances of HPET is allowed");
720         return;
721     }
722 
723     s->hpet_id = hpet_fw_cfg.count++;
724 
725     for (i = 0; i < HPET_NUM_IRQ_ROUTES; i++) {
726         sysbus_init_irq(sbd, &s->irqs[i]);
727     }
728 
729     if (s->num_timers < HPET_MIN_TIMERS) {
730         s->num_timers = HPET_MIN_TIMERS;
731     } else if (s->num_timers > HPET_MAX_TIMERS) {
732         s->num_timers = HPET_MAX_TIMERS;
733     }
734     for (i = 0; i < HPET_MAX_TIMERS; i++) {
735         timer = &s->timer[i];
736         timer->qemu_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, hpet_timer, timer);
737         timer->tn = i;
738         timer->state = s;
739     }
740 
741     /* 64-bit General Capabilities and ID Register; LegacyReplacementRoute. */
742     s->capability = 0x8086a001ULL;
743     s->capability |= (s->num_timers - 1) << HPET_ID_NUM_TIM_SHIFT;
744     s->capability |= ((uint64_t)(HPET_CLK_PERIOD * FS_PER_NS) << 32);
745 
746     qdev_init_gpio_in(dev, hpet_handle_legacy_irq, 2);
747     qdev_init_gpio_out(dev, &s->pit_enabled, 1);
748 }
749 
750 static const Property hpet_device_properties[] = {
751     DEFINE_PROP_UINT8("timers", HPETState, num_timers, HPET_MIN_TIMERS),
752     DEFINE_PROP_BIT("msi", HPETState, flags, HPET_MSI_SUPPORT, false),
753     DEFINE_PROP_UINT32(HPET_INTCAP, HPETState, intcap, 0),
754     DEFINE_PROP_BOOL("hpet-offset-saved", HPETState, hpet_offset_saved, true),
755 };
756 
757 static void hpet_device_class_init(ObjectClass *klass, void *data)
758 {
759     DeviceClass *dc = DEVICE_CLASS(klass);
760 
761     dc->realize = hpet_realize;
762     device_class_set_legacy_reset(dc, hpet_reset);
763     dc->vmsd = &vmstate_hpet;
764     device_class_set_props(dc, hpet_device_properties);
765 }
766 
767 static const TypeInfo hpet_device_info = {
768     .name          = TYPE_HPET,
769     .parent        = TYPE_SYS_BUS_DEVICE,
770     .instance_size = sizeof(HPETState),
771     .instance_init = hpet_init,
772     .class_init    = hpet_device_class_init,
773 };
774 
775 static void hpet_register_types(void)
776 {
777     type_register_static(&hpet_device_info);
778 }
779 
780 type_init(hpet_register_types)
781