Merge commit 'a1c7273b82dc084d85e2344e0562f5ee4e414d59' into upstream-merge
[qemu/qemu-dev-zwu.git] / hw / i8254.c
blob43ac1066aabb53447c9155b865b9eb7f99198d56
1 /*
2 * QEMU 8253/8254 interval timer emulation
4 * Copyright (c) 2003-2004 Fabrice Bellard
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
24 #include "hw.h"
25 #include "pc.h"
26 #include "isa.h"
27 #include "qemu-timer.h"
28 #include "kvm.h"
29 #include "i8254.h"
31 //#define DEBUG_PIT
33 static PITState pit_state;
35 static void pit_irq_timer_update(PITChannelState *s, int64_t current_time);
37 static int pit_get_count(PITChannelState *s)
39 uint64_t d;
40 int counter;
42 d = muldiv64(qemu_get_clock_ns(vm_clock) - s->count_load_time, PIT_FREQ,
43 get_ticks_per_sec());
44 switch(s->mode) {
45 case 0:
46 case 1:
47 case 4:
48 case 5:
49 counter = (s->count - d) & 0xffff;
50 break;
51 case 3:
52 /* XXX: may be incorrect for odd counts */
53 counter = s->count - ((2 * d) % s->count);
54 break;
55 default:
56 counter = s->count - (d % s->count);
57 break;
59 return counter;
62 /* get pit output bit */
63 static int pit_get_out1(PITChannelState *s, int64_t current_time)
65 uint64_t d;
66 int out;
68 d = muldiv64(current_time - s->count_load_time, PIT_FREQ,
69 get_ticks_per_sec());
70 switch(s->mode) {
71 default:
72 case 0:
73 out = (d >= s->count);
74 break;
75 case 1:
76 out = (d < s->count);
77 break;
78 case 2:
79 if ((d % s->count) == 0 && d != 0)
80 out = 1;
81 else
82 out = 0;
83 break;
84 case 3:
85 out = (d % s->count) < ((s->count + 1) >> 1);
86 break;
87 case 4:
88 case 5:
89 out = (d == s->count);
90 break;
92 return out;
95 int pit_get_out(ISADevice *dev, int channel, int64_t current_time)
97 PITState *pit = DO_UPCAST(PITState, dev, dev);
98 PITChannelState *s = &pit->channels[channel];
99 return pit_get_out1(s, current_time);
102 /* return -1 if no transition will occur. */
103 static int64_t pit_get_next_transition_time(PITChannelState *s,
104 int64_t current_time)
106 uint64_t d, next_time, base;
107 int period2;
109 d = muldiv64(current_time - s->count_load_time, PIT_FREQ,
110 get_ticks_per_sec());
111 switch(s->mode) {
112 default:
113 case 0:
114 case 1:
115 if (d < s->count)
116 next_time = s->count;
117 else
118 return -1;
119 break;
120 case 2:
121 base = (d / s->count) * s->count;
122 if ((d - base) == 0 && d != 0)
123 next_time = base + s->count;
124 else
125 next_time = base + s->count + 1;
126 break;
127 case 3:
128 base = (d / s->count) * s->count;
129 period2 = ((s->count + 1) >> 1);
130 if ((d - base) < period2)
131 next_time = base + period2;
132 else
133 next_time = base + s->count;
134 break;
135 case 4:
136 case 5:
137 if (d < s->count)
138 next_time = s->count;
139 else if (d == s->count)
140 next_time = s->count + 1;
141 else
142 return -1;
143 break;
145 /* convert to timer units */
146 next_time = s->count_load_time + muldiv64(next_time, get_ticks_per_sec(),
147 PIT_FREQ);
148 /* fix potential rounding problems */
149 /* XXX: better solution: use a clock at PIT_FREQ Hz */
150 if (next_time <= current_time)
151 next_time = current_time + 1;
152 return next_time;
155 /* val must be 0 or 1 */
156 void pit_set_gate(ISADevice *dev, int channel, int val)
158 PITState *pit = DO_UPCAST(PITState, dev, dev);
159 PITChannelState *s = &pit->channels[channel];
161 switch(s->mode) {
162 default:
163 case 0:
164 case 4:
165 /* XXX: just disable/enable counting */
166 break;
167 case 1:
168 case 5:
169 if (s->gate < val) {
170 /* restart counting on rising edge */
171 s->count_load_time = qemu_get_clock_ns(vm_clock);
172 pit_irq_timer_update(s, s->count_load_time);
174 break;
175 case 2:
176 case 3:
177 if (s->gate < val) {
178 /* restart counting on rising edge */
179 s->count_load_time = qemu_get_clock_ns(vm_clock);
180 pit_irq_timer_update(s, s->count_load_time);
182 /* XXX: disable/enable counting */
183 break;
185 s->gate = val;
188 int pit_get_gate(ISADevice *dev, int channel)
190 PITState *pit = DO_UPCAST(PITState, dev, dev);
191 PITChannelState *s = &pit->channels[channel];
192 return s->gate;
195 int pit_get_initial_count(ISADevice *dev, int channel)
197 PITState *pit = DO_UPCAST(PITState, dev, dev);
198 PITChannelState *s = &pit->channels[channel];
199 return s->count;
202 int pit_get_mode(ISADevice *dev, int channel)
204 PITState *pit = DO_UPCAST(PITState, dev, dev);
205 PITChannelState *s = &pit->channels[channel];
206 return s->mode;
209 static inline void pit_load_count(PITState *s, int val, int chan)
211 if (val == 0)
212 val = 0x10000;
213 s->channels[chan].count_load_time = qemu_get_clock_ns(vm_clock);
214 s->channels[chan].count = val;
215 #ifdef TARGET_I386
216 if (chan == 0 && pit_state.flags & PIT_FLAGS_HPET_LEGACY) {
217 return;
219 #endif
220 pit_irq_timer_update(&s->channels[chan], s->channels[chan].count_load_time);
223 /* if already latched, do not latch again */
224 static void pit_latch_count(PITChannelState *s)
226 if (!s->count_latched) {
227 s->latched_count = pit_get_count(s);
228 s->count_latched = s->rw_mode;
232 static void pit_ioport_write(void *opaque, uint32_t addr, uint32_t val)
234 PITState *pit = opaque;
235 int channel, access;
236 PITChannelState *s;
238 addr &= 3;
239 if (addr == 3) {
240 channel = val >> 6;
241 if (channel == 3) {
242 /* read back command */
243 for(channel = 0; channel < 3; channel++) {
244 s = &pit->channels[channel];
245 if (val & (2 << channel)) {
246 if (!(val & 0x20)) {
247 pit_latch_count(s);
249 if (!(val & 0x10) && !s->status_latched) {
250 /* status latch */
251 /* XXX: add BCD and null count */
252 s->status = (pit_get_out1(s, qemu_get_clock_ns(vm_clock)) << 7) |
253 (s->rw_mode << 4) |
254 (s->mode << 1) |
255 s->bcd;
256 s->status_latched = 1;
260 } else {
261 s = &pit->channels[channel];
262 access = (val >> 4) & 3;
263 if (access == 0) {
264 pit_latch_count(s);
265 } else {
266 s->rw_mode = access;
267 s->read_state = access;
268 s->write_state = access;
270 s->mode = (val >> 1) & 7;
271 s->bcd = val & 1;
272 /* XXX: update irq timer ? */
275 } else {
276 s = &pit->channels[addr];
277 switch(s->write_state) {
278 default:
279 case RW_STATE_LSB:
280 pit_load_count(pit, val, addr);
281 break;
282 case RW_STATE_MSB:
283 pit_load_count(pit, val << 8, addr);
284 break;
285 case RW_STATE_WORD0:
286 s->write_latch = val;
287 s->write_state = RW_STATE_WORD1;
288 break;
289 case RW_STATE_WORD1:
290 pit_load_count(pit, s->write_latch | (val << 8), addr);
291 s->write_state = RW_STATE_WORD0;
292 break;
297 static uint32_t pit_ioport_read(void *opaque, uint32_t addr)
299 PITState *pit = opaque;
300 int ret, count;
301 PITChannelState *s;
303 addr &= 3;
304 s = &pit->channels[addr];
305 if (s->status_latched) {
306 s->status_latched = 0;
307 ret = s->status;
308 } else if (s->count_latched) {
309 switch(s->count_latched) {
310 default:
311 case RW_STATE_LSB:
312 ret = s->latched_count & 0xff;
313 s->count_latched = 0;
314 break;
315 case RW_STATE_MSB:
316 ret = s->latched_count >> 8;
317 s->count_latched = 0;
318 break;
319 case RW_STATE_WORD0:
320 ret = s->latched_count & 0xff;
321 s->count_latched = RW_STATE_MSB;
322 break;
324 } else {
325 switch(s->read_state) {
326 default:
327 case RW_STATE_LSB:
328 count = pit_get_count(s);
329 ret = count & 0xff;
330 break;
331 case RW_STATE_MSB:
332 count = pit_get_count(s);
333 ret = (count >> 8) & 0xff;
334 break;
335 case RW_STATE_WORD0:
336 count = pit_get_count(s);
337 ret = count & 0xff;
338 s->read_state = RW_STATE_WORD1;
339 break;
340 case RW_STATE_WORD1:
341 count = pit_get_count(s);
342 ret = (count >> 8) & 0xff;
343 s->read_state = RW_STATE_WORD0;
344 break;
347 return ret;
350 /* global counters for time-drift fix */
351 int64_t timer_acks=0, timer_interrupts=0, timer_ints_to_push=0;
353 extern int time_drift_fix;
355 static void pit_irq_timer_update(PITChannelState *s, int64_t current_time)
357 int64_t expire_time;
358 int irq_level;
360 if (!s->irq_timer)
361 return;
362 expire_time = pit_get_next_transition_time(s, current_time);
363 irq_level = pit_get_out1(s, current_time);
364 qemu_set_irq(s->irq, irq_level);
365 if (time_drift_fix && irq_level==1) {
366 /* FIXME: fine tune timer_max_fix (max fix per tick).
367 * Should it be 1 (double time), 2 , 4, 10 ?
368 * Currently setting it to 5% of PIT-ticks-per-second (per PIT-tick)
370 const long pit_ticks_per_sec = (s->count>0) ? (PIT_FREQ/s->count) : 0;
371 const long timer_max_fix = pit_ticks_per_sec/20;
372 const long delta = timer_interrupts - timer_acks;
373 const long max_delta = pit_ticks_per_sec * 60; /* one minute */
374 if ((delta > max_delta) && (pit_ticks_per_sec > 0)) {
375 printf("time drift is too long, %ld seconds were lost\n", delta/pit_ticks_per_sec);
376 timer_acks = timer_interrupts;
377 timer_ints_to_push = 0;
378 } else if (delta > 0) {
379 timer_ints_to_push = MIN(delta, timer_max_fix);
381 timer_interrupts++;
383 #ifdef DEBUG_PIT
384 printf("irq_level=%d next_delay=%f\n",
385 irq_level,
386 (double)(expire_time - current_time) / get_ticks_per_sec());
387 #endif
388 s->next_transition_time = expire_time;
389 if (expire_time != -1) {
390 qemu_mod_timer(s->irq_timer, expire_time);
391 } else {
392 qemu_del_timer(s->irq_timer);
396 static void pit_irq_timer(void *opaque)
398 PITChannelState *s = opaque;
400 pit_irq_timer_update(s, s->next_transition_time);
403 static const VMStateDescription vmstate_pit_channel = {
404 .name = "pit channel",
405 .version_id = 2,
406 .minimum_version_id = 2,
407 .minimum_version_id_old = 2,
408 .fields = (VMStateField []) {
409 VMSTATE_INT32(count, PITChannelState),
410 VMSTATE_UINT16(latched_count, PITChannelState),
411 VMSTATE_UINT8(count_latched, PITChannelState),
412 VMSTATE_UINT8(status_latched, PITChannelState),
413 VMSTATE_UINT8(status, PITChannelState),
414 VMSTATE_UINT8(read_state, PITChannelState),
415 VMSTATE_UINT8(write_state, PITChannelState),
416 VMSTATE_UINT8(write_latch, PITChannelState),
417 VMSTATE_UINT8(rw_mode, PITChannelState),
418 VMSTATE_UINT8(mode, PITChannelState),
419 VMSTATE_UINT8(bcd, PITChannelState),
420 VMSTATE_UINT8(gate, PITChannelState),
421 VMSTATE_INT64(count_load_time, PITChannelState),
422 VMSTATE_INT64(next_transition_time, PITChannelState),
423 VMSTATE_END_OF_LIST()
427 static int pit_load_old(QEMUFile *f, void *opaque, int version_id)
429 PITState *pit = opaque;
430 PITChannelState *s;
431 int i;
433 if (version_id != PIT_SAVEVM_VERSION)
434 return -EINVAL;
436 pit->flags = qemu_get_be32(f);
437 for(i = 0; i < 3; i++) {
438 s = &pit->channels[i];
439 s->count=qemu_get_be32(f);
440 qemu_get_be16s(f, &s->latched_count);
441 qemu_get_8s(f, &s->count_latched);
442 qemu_get_8s(f, &s->status_latched);
443 qemu_get_8s(f, &s->status);
444 qemu_get_8s(f, &s->read_state);
445 qemu_get_8s(f, &s->write_state);
446 qemu_get_8s(f, &s->write_latch);
447 qemu_get_8s(f, &s->rw_mode);
448 qemu_get_8s(f, &s->mode);
449 qemu_get_8s(f, &s->bcd);
450 qemu_get_8s(f, &s->gate);
451 s->count_load_time=qemu_get_be64(f);
452 if (s->irq_timer) {
453 s->next_transition_time=qemu_get_be64(f);
454 qemu_get_timer(f, s->irq_timer);
458 return 0;
461 VMStateDescription vmstate_pit = {
462 .name = "i8254",
463 .version_id = 2,
464 .minimum_version_id = 2,
465 .minimum_version_id_old = 1,
466 .load_state_old = pit_load_old,
467 .fields = (VMStateField []) {
468 VMSTATE_UINT32(flags, PITState),
469 VMSTATE_STRUCT_ARRAY(channels, PITState, 3, 2, vmstate_pit_channel, PITChannelState),
470 VMSTATE_TIMER(channels[0].irq_timer, PITState),
471 VMSTATE_END_OF_LIST()
475 static void pit_reset(DeviceState *dev)
477 PITState *pit = container_of(dev, PITState, dev.qdev);
478 PITChannelState *s;
479 int i;
481 #ifdef TARGET_I386
482 pit->flags &= ~PIT_FLAGS_HPET_LEGACY;
483 #endif
484 for(i = 0;i < 3; i++) {
485 s = &pit->channels[i];
486 s->mode = 3;
487 s->gate = (i != 2);
488 pit_load_count(pit, 0, i);
492 #ifdef TARGET_I386
493 /* When HPET is operating in legacy mode, i8254 timer0 is disabled */
495 void hpet_pit_disable(void)
497 PITChannelState *s = &pit_state.channels[0];
499 if (kvm_enabled() && kvm_pit_in_kernel()) {
500 if (qemu_kvm_has_pit_state2()) {
501 kvm_hpet_disable_kpit();
502 } else {
503 fprintf(stderr, "%s: kvm does not support pit_state2!\n", __FUNCTION__);
504 exit(1);
506 } else {
507 pit_state.flags |= PIT_FLAGS_HPET_LEGACY;
508 if (s->irq_timer) {
509 qemu_del_timer(s->irq_timer);
514 /* When HPET is reset or leaving legacy mode, it must reenable i8254
515 * timer 0
518 void hpet_pit_enable(void)
520 PITState *pit = &pit_state;
521 PITChannelState *s = &pit->channels[0];
523 if (kvm_enabled() && kvm_pit_in_kernel()) {
524 if (qemu_kvm_has_pit_state2()) {
525 kvm_hpet_enable_kpit();
526 } else {
527 fprintf(stderr, "%s: kvm does not support pit_state2!\n", __FUNCTION__);
528 exit(1);
530 } else {
531 pit_state.flags &= ~PIT_FLAGS_HPET_LEGACY;
532 pit_load_count(pit, s->count, 0);
535 #endif
537 static int pit_initfn(ISADevice *dev)
539 PITState *pit = DO_UPCAST(PITState, dev, dev);
540 PITChannelState *s;
542 #ifdef CONFIG_KVM_PIT
543 if (kvm_enabled() && kvm_pit_in_kernel())
544 kvm_pit_init(pit);
545 else {
546 #endif
548 s = &pit->channels[0];
549 /* the timer 0 is connected to an IRQ */
550 s->irq_timer = qemu_new_timer_ns(vm_clock, pit_irq_timer, s);
551 s->irq = isa_get_irq(pit->irq);
553 register_ioport_write(pit->iobase, 4, 1, pit_ioport_write, pit);
554 register_ioport_read(pit->iobase, 3, 1, pit_ioport_read, pit);
555 isa_init_ioport(dev, pit->iobase);
557 #ifdef CONFIG_KVM_PIT
559 #endif
560 qdev_set_legacy_instance_id(&dev->qdev, pit->iobase, 2);
562 return 0;
565 static ISADeviceInfo pit_info = {
566 .qdev.name = "isa-pit",
567 .qdev.size = sizeof(PITState),
568 .qdev.vmsd = &vmstate_pit,
569 .qdev.reset = pit_reset,
570 .qdev.no_user = 1,
571 .init = pit_initfn,
572 .qdev.props = (Property[]) {
573 DEFINE_PROP_UINT32("irq", PITState, irq, -1),
574 DEFINE_PROP_HEX32("iobase", PITState, iobase, -1),
575 DEFINE_PROP_END_OF_LIST(),
579 static void pit_register(void)
581 isa_qdev_register(&pit_info);
583 device_init(pit_register)