Merge commit 'd34e8f6e9d3a396c3327aa9807c83f9e1f4a7bd7' into upstream-merge
[qemu-kvm.git] / hw / i8254.c
blob8b2486714807fb7ad355ab4ece9a19237f95b2a4
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 static void pit_irq_timer_update(PITChannelState *s, int64_t current_time)
352 int64_t expire_time;
353 int irq_level;
355 if (!s->irq_timer)
356 return;
357 expire_time = pit_get_next_transition_time(s, current_time);
358 irq_level = pit_get_out1(s, current_time);
359 qemu_set_irq(s->irq, irq_level);
360 #ifdef DEBUG_PIT
361 printf("irq_level=%d next_delay=%f\n",
362 irq_level,
363 (double)(expire_time - current_time) / get_ticks_per_sec());
364 #endif
365 s->next_transition_time = expire_time;
366 if (expire_time != -1)
367 qemu_mod_timer(s->irq_timer, expire_time);
368 else
369 qemu_del_timer(s->irq_timer);
372 static void pit_irq_timer(void *opaque)
374 PITChannelState *s = opaque;
376 pit_irq_timer_update(s, s->next_transition_time);
379 static const VMStateDescription vmstate_pit_channel = {
380 .name = "pit channel",
381 .version_id = 2,
382 .minimum_version_id = 2,
383 .minimum_version_id_old = 2,
384 .fields = (VMStateField []) {
385 VMSTATE_INT32(count, PITChannelState),
386 VMSTATE_UINT16(latched_count, PITChannelState),
387 VMSTATE_UINT8(count_latched, PITChannelState),
388 VMSTATE_UINT8(status_latched, PITChannelState),
389 VMSTATE_UINT8(status, PITChannelState),
390 VMSTATE_UINT8(read_state, PITChannelState),
391 VMSTATE_UINT8(write_state, PITChannelState),
392 VMSTATE_UINT8(write_latch, PITChannelState),
393 VMSTATE_UINT8(rw_mode, PITChannelState),
394 VMSTATE_UINT8(mode, PITChannelState),
395 VMSTATE_UINT8(bcd, PITChannelState),
396 VMSTATE_UINT8(gate, PITChannelState),
397 VMSTATE_INT64(count_load_time, PITChannelState),
398 VMSTATE_INT64(next_transition_time, PITChannelState),
399 VMSTATE_END_OF_LIST()
403 static int pit_load_old(QEMUFile *f, void *opaque, int version_id)
405 PITState *pit = opaque;
406 PITChannelState *s;
407 int i;
409 if (version_id != PIT_SAVEVM_VERSION)
410 return -EINVAL;
412 pit->flags = qemu_get_be32(f);
413 for(i = 0; i < 3; i++) {
414 s = &pit->channels[i];
415 s->count=qemu_get_be32(f);
416 qemu_get_be16s(f, &s->latched_count);
417 qemu_get_8s(f, &s->count_latched);
418 qemu_get_8s(f, &s->status_latched);
419 qemu_get_8s(f, &s->status);
420 qemu_get_8s(f, &s->read_state);
421 qemu_get_8s(f, &s->write_state);
422 qemu_get_8s(f, &s->write_latch);
423 qemu_get_8s(f, &s->rw_mode);
424 qemu_get_8s(f, &s->mode);
425 qemu_get_8s(f, &s->bcd);
426 qemu_get_8s(f, &s->gate);
427 s->count_load_time=qemu_get_be64(f);
428 if (s->irq_timer) {
429 s->next_transition_time=qemu_get_be64(f);
430 qemu_get_timer(f, s->irq_timer);
434 return 0;
437 VMStateDescription vmstate_pit = {
438 .name = "i8254",
439 .version_id = 2,
440 .minimum_version_id = 2,
441 .minimum_version_id_old = 1,
442 .load_state_old = pit_load_old,
443 .fields = (VMStateField []) {
444 VMSTATE_UINT32(flags, PITState),
445 VMSTATE_STRUCT_ARRAY(channels, PITState, 3, 2, vmstate_pit_channel, PITChannelState),
446 VMSTATE_TIMER(channels[0].irq_timer, PITState),
447 VMSTATE_END_OF_LIST()
451 static void pit_reset(DeviceState *dev)
453 PITState *pit = container_of(dev, PITState, dev.qdev);
454 PITChannelState *s;
455 int i;
457 #ifdef TARGET_I386
458 pit->flags &= ~PIT_FLAGS_HPET_LEGACY;
459 #endif
460 for(i = 0;i < 3; i++) {
461 s = &pit->channels[i];
462 s->mode = 3;
463 s->gate = (i != 2);
464 pit_load_count(pit, 0, i);
466 if (vmstate_pit.post_load) {
467 vmstate_pit.post_load(pit, 2);
471 #ifdef TARGET_I386
472 /* When HPET is operating in legacy mode, i8254 timer0 is disabled */
474 void hpet_pit_disable(void)
476 PITChannelState *s = &pit_state.channels[0];
478 if (kvm_enabled() && kvm_irqchip_in_kernel()) {
479 if (kvm_has_pit_state2()) {
480 kvm_hpet_disable_kpit();
481 } else {
482 fprintf(stderr, "%s: kvm does not support pit_state2!\n", __FUNCTION__);
483 exit(1);
485 } else {
486 pit_state.flags |= PIT_FLAGS_HPET_LEGACY;
487 if (s->irq_timer) {
488 qemu_del_timer(s->irq_timer);
493 /* When HPET is reset or leaving legacy mode, it must reenable i8254
494 * timer 0
497 void hpet_pit_enable(void)
499 PITState *pit = &pit_state;
500 PITChannelState *s = &pit->channels[0];
502 if (kvm_enabled() && kvm_irqchip_in_kernel()) {
503 if (kvm_has_pit_state2()) {
504 kvm_hpet_enable_kpit();
505 } else {
506 fprintf(stderr, "%s: kvm does not support pit_state2!\n", __FUNCTION__);
507 exit(1);
509 } else {
510 pit_state.flags &= ~PIT_FLAGS_HPET_LEGACY;
511 pit_load_count(pit, s->count, 0);
514 #endif
516 static const MemoryRegionPortio pit_portio[] = {
517 { 0, 4, 1, .write = pit_ioport_write },
518 { 0, 3, 1, .read = pit_ioport_read },
519 PORTIO_END_OF_LIST()
522 static const MemoryRegionOps pit_ioport_ops = {
523 .old_portio = pit_portio
526 static int pit_initfn(ISADevice *dev)
528 PITState *pit = DO_UPCAST(PITState, dev, dev);
529 PITChannelState *s;
531 #ifdef CONFIG_KVM_PIT
532 if (kvm_enabled() && kvm_irqchip_in_kernel())
533 kvm_pit_init(pit);
534 else {
535 #endif
537 s = &pit->channels[0];
538 /* the timer 0 is connected to an IRQ */
539 s->irq_timer = qemu_new_timer_ns(vm_clock, pit_irq_timer, s);
540 s->irq = isa_get_irq(dev, pit->irq);
542 memory_region_init_io(&pit->ioports, &pit_ioport_ops, pit, "pit", 4);
543 isa_register_ioport(dev, &pit->ioports, pit->iobase);
545 #ifdef CONFIG_KVM_PIT
547 #endif
548 qdev_set_legacy_instance_id(&dev->qdev, pit->iobase, 2);
550 return 0;
553 static void pit_class_initfn(ObjectClass *klass, void *data)
555 ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
556 ic->init = pit_initfn;
559 static DeviceInfo pit_info = {
560 .name = "isa-pit",
561 .size = sizeof(PITState),
562 .vmsd = &vmstate_pit,
563 .reset = pit_reset,
564 .no_user = 1,
565 .class_init = pit_class_initfn,
566 .props = (Property[]) {
567 DEFINE_PROP_UINT32("irq", PITState, irq, -1),
568 DEFINE_PROP_HEX32("iobase", PITState, iobase, -1),
569 DEFINE_PROP_END_OF_LIST(),
573 static void pit_register(void)
575 isa_qdev_register(&pit_info);
577 device_init(pit_register)