Lines Matching +full:addr +full:- +full:mode

4  * Copyright (c) 2003-2004 Fabrice Bellard
44 #define mod_64(x, y) ((x) - (y) * div64_u64(x, y))
56 struct kvm_kpit_channel_state *c = &pit->pit_state.channels[channel]; in pit_set_gate()
58 switch (c->mode) { in pit_set_gate()
69 if (c->gate < val) in pit_set_gate()
70 c->count_load_time = ktime_get(); in pit_set_gate()
74 c->gate = val; in pit_set_gate()
79 return pit->pit_state.channels[channel].gate; in pit_get_gate()
86 struct kvm_kpit_state *ps = &pit->pit_state; in __kpit_elapsed()
88 if (!ps->period) in __kpit_elapsed()
100 remaining = hrtimer_get_remaining(&ps->timer); in __kpit_elapsed()
101 elapsed = ps->period - ktime_to_ns(remaining); in __kpit_elapsed()
112 return ktime_to_ns(ktime_sub(ktime_get(), c->count_load_time)); in kpit_elapsed()
117 struct kvm_kpit_channel_state *c = &pit->pit_state.channels[channel]; in pit_get_count()
124 switch (c->mode) { in pit_get_count()
129 counter = (c->count - d) & 0xffff; in pit_get_count()
133 counter = c->count - (mod_64((2 * d), c->count)); in pit_get_count()
136 counter = c->count - mod_64(d, c->count); in pit_get_count()
144 struct kvm_kpit_channel_state *c = &pit->pit_state.channels[channel]; in pit_get_out()
151 switch (c->mode) { in pit_get_out()
154 out = (d >= c->count); in pit_get_out()
157 out = (d < c->count); in pit_get_out()
160 out = ((mod_64(d, c->count) == 0) && (d != 0)); in pit_get_out()
163 out = (mod_64(d, c->count) < ((c->count + 1) >> 1)); in pit_get_out()
167 out = (d == c->count); in pit_get_out()
176 struct kvm_kpit_channel_state *c = &pit->pit_state.channels[channel]; in pit_latch_count()
178 if (!c->count_latched) { in pit_latch_count()
179 c->latched_count = pit_get_count(pit, channel); in pit_latch_count()
180 c->count_latched = c->rw_mode; in pit_latch_count()
186 struct kvm_kpit_channel_state *c = &pit->pit_state.channels[channel]; in pit_latch_status()
188 if (!c->status_latched) { in pit_latch_status()
190 c->status = ((pit_get_out(pit, channel) << 7) | in pit_latch_status()
191 (c->rw_mode << 4) | in pit_latch_status()
192 (c->mode << 1) | in pit_latch_status()
193 c->bcd); in pit_latch_status()
194 c->status_latched = 1; in pit_latch_status()
209 atomic_set(&ps->irq_ack, 1); in kvm_pit_ack_irq()
214 if (atomic_dec_if_positive(&ps->pending) > 0) in kvm_pit_ack_irq()
215 kthread_queue_work(pit->worker, &pit->expired); in kvm_pit_ack_irq()
220 struct kvm_pit *pit = vcpu->kvm->arch.vpit; in __kvm_migrate_pit_timer()
224 if (vcpu->vcpu_id || !pit) in __kvm_migrate_pit_timer()
227 timer = &pit->pit_state.timer; in __kvm_migrate_pit_timer()
228 mutex_lock(&pit->pit_state.lock); in __kvm_migrate_pit_timer()
231 mutex_unlock(&pit->pit_state.lock); in __kvm_migrate_pit_timer()
236 hrtimer_cancel(&pit->pit_state.timer); in destroy_pit_timer()
237 kthread_flush_work(&pit->expired); in destroy_pit_timer()
243 struct kvm *kvm = pit->kvm; in pit_do_work()
246 struct kvm_kpit_state *ps = &pit->pit_state; in pit_do_work()
248 if (atomic_read(&ps->reinject) && !atomic_xchg(&ps->irq_ack, 0)) in pit_do_work()
251 kvm_set_irq(kvm, pit->irq_source_id, 0, 1, false); in pit_do_work()
252 kvm_set_irq(kvm, pit->irq_source_id, 0, 0, false); in pit_do_work()
255 * Provides NMI watchdog support via Virtual Wire mode. in pit_do_work()
256 * The route is: PIT -> LVT0 in NMI mode. in pit_do_work()
260 * VCPUs and only when LVT0 is in NMI mode. The interrupt can in pit_do_work()
263 if (atomic_read(&kvm->arch.vapics_in_nmi_mode) > 0) in pit_do_work()
273 if (atomic_read(&ps->reinject)) in pit_timer_fn()
274 atomic_inc(&ps->pending); in pit_timer_fn()
276 kthread_queue_work(pt->worker, &pt->expired); in pit_timer_fn()
278 if (ps->is_periodic) { in pit_timer_fn()
279 hrtimer_add_expires_ns(&ps->timer, ps->period); in pit_timer_fn()
287 atomic_set(&pit->pit_state.pending, 0); in kvm_pit_reset_reinject()
288 atomic_set(&pit->pit_state.irq_ack, 1); in kvm_pit_reset_reinject()
293 struct kvm_kpit_state *ps = &pit->pit_state; in kvm_pit_set_reinject()
294 struct kvm *kvm = pit->kvm; in kvm_pit_set_reinject()
296 if (atomic_read(&ps->reinject) == reinject) in kvm_pit_set_reinject()
301 * This cause in-kernel PIT re-inject mode to fail in kvm_pit_set_reinject()
302 * since it checks ps->irq_ack before kvm_set_irq() in kvm_pit_set_reinject()
304 * the pt->worker work iterm and reinject the missed tick. in kvm_pit_set_reinject()
305 * So, deactivate APICv when PIT is in reinject mode. in kvm_pit_set_reinject()
309 /* The initial state is preserved while ps->reinject == 0. */ in kvm_pit_set_reinject()
311 kvm_register_irq_ack_notifier(kvm, &ps->irq_ack_notifier); in kvm_pit_set_reinject()
312 kvm_register_irq_mask_notifier(kvm, 0, &pit->mask_notifier); in kvm_pit_set_reinject()
315 kvm_unregister_irq_ack_notifier(kvm, &ps->irq_ack_notifier); in kvm_pit_set_reinject()
316 kvm_unregister_irq_mask_notifier(kvm, 0, &pit->mask_notifier); in kvm_pit_set_reinject()
319 atomic_set(&ps->reinject, reinject); in kvm_pit_set_reinject()
324 struct kvm_kpit_state *ps = &pit->pit_state; in create_pit_timer()
325 struct kvm *kvm = pit->kvm; in create_pit_timer()
329 ps->flags & KVM_PIT_FLAGS_HPET_LEGACY) in create_pit_timer()
337 hrtimer_cancel(&ps->timer); in create_pit_timer()
338 kthread_flush_work(&pit->expired); in create_pit_timer()
339 ps->period = interval; in create_pit_timer()
340 ps->is_periodic = is_period; in create_pit_timer()
349 if (ps->is_periodic) { in create_pit_timer()
352 if (ps->period < min_period) { in create_pit_timer()
356 ps->period, min_period); in create_pit_timer()
357 ps->period = min_period; in create_pit_timer()
361 hrtimer_start(&ps->timer, ktime_add_ns(ktime_get(), interval), in create_pit_timer()
367 struct kvm_kpit_state *ps = &pit->pit_state; in pit_load_count()
378 ps->channels[channel].count = val; in pit_load_count()
381 ps->channels[channel].count_load_time = ktime_get(); in pit_load_count()
386 * mode 1 is one shot, mode 2 is period, otherwise del timer */ in pit_load_count()
387 switch (ps->channels[0].mode) { in pit_load_count()
390 /* FIXME: enhance mode 4 precision */ in pit_load_count()
408 WARN_ON_ONCE(!mutex_is_locked(&pit->pit_state.lock)); in kvm_pit_load_count()
411 /* save existing mode for later reenablement */ in kvm_pit_load_count()
413 saved_mode = pit->pit_state.channels[0].mode; in kvm_pit_load_count()
414 pit->pit_state.channels[0].mode = 0xff; /* disable timer */ in kvm_pit_load_count()
416 pit->pit_state.channels[0].mode = saved_mode; in kvm_pit_load_count()
432 static inline int pit_in_range(gpa_t addr) in pit_in_range() argument
434 return ((addr >= KVM_PIT_BASE_ADDRESS) && in pit_in_range()
435 (addr < KVM_PIT_BASE_ADDRESS + KVM_PIT_MEM_LENGTH)); in pit_in_range()
440 gpa_t addr, int len, const void *data) in pit_ioport_write() argument
443 struct kvm_kpit_state *pit_state = &pit->pit_state; in pit_ioport_write()
447 if (!pit_in_range(addr)) in pit_ioport_write()
448 return -EOPNOTSUPP; in pit_ioport_write()
451 addr &= KVM_PIT_CHANNEL_MASK; in pit_ioport_write()
453 mutex_lock(&pit_state->lock); in pit_ioport_write()
456 pr_debug("write addr is 0x%x, len is %d, val is 0x%x\n", in pit_ioport_write()
457 (unsigned int)addr, len, val); in pit_ioport_write()
459 if (addr == 3) { in pit_ioport_write()
462 /* Read-Back Command. */ in pit_ioport_write()
473 s = &pit_state->channels[channel]; in pit_ioport_write()
478 s->rw_mode = access; in pit_ioport_write()
479 s->read_state = access; in pit_ioport_write()
480 s->write_state = access; in pit_ioport_write()
481 s->mode = (val >> 1) & 7; in pit_ioport_write()
482 if (s->mode > 5) in pit_ioport_write()
483 s->mode -= 4; in pit_ioport_write()
484 s->bcd = val & 1; in pit_ioport_write()
489 s = &pit_state->channels[addr]; in pit_ioport_write()
490 switch (s->write_state) { in pit_ioport_write()
493 pit_load_count(pit, addr, val); in pit_ioport_write()
496 pit_load_count(pit, addr, val << 8); in pit_ioport_write()
499 s->write_latch = val; in pit_ioport_write()
500 s->write_state = RW_STATE_WORD1; in pit_ioport_write()
503 pit_load_count(pit, addr, s->write_latch | (val << 8)); in pit_ioport_write()
504 s->write_state = RW_STATE_WORD0; in pit_ioport_write()
509 mutex_unlock(&pit_state->lock); in pit_ioport_write()
515 gpa_t addr, int len, void *data) in pit_ioport_read() argument
518 struct kvm_kpit_state *pit_state = &pit->pit_state; in pit_ioport_read()
521 if (!pit_in_range(addr)) in pit_ioport_read()
522 return -EOPNOTSUPP; in pit_ioport_read()
524 addr &= KVM_PIT_CHANNEL_MASK; in pit_ioport_read()
525 if (addr == 3) in pit_ioport_read()
528 s = &pit_state->channels[addr]; in pit_ioport_read()
530 mutex_lock(&pit_state->lock); in pit_ioport_read()
532 if (s->status_latched) { in pit_ioport_read()
533 s->status_latched = 0; in pit_ioport_read()
534 ret = s->status; in pit_ioport_read()
535 } else if (s->count_latched) { in pit_ioport_read()
536 switch (s->count_latched) { in pit_ioport_read()
539 ret = s->latched_count & 0xff; in pit_ioport_read()
540 s->count_latched = 0; in pit_ioport_read()
543 ret = s->latched_count >> 8; in pit_ioport_read()
544 s->count_latched = 0; in pit_ioport_read()
547 ret = s->latched_count & 0xff; in pit_ioport_read()
548 s->count_latched = RW_STATE_MSB; in pit_ioport_read()
552 switch (s->read_state) { in pit_ioport_read()
555 count = pit_get_count(pit, addr); in pit_ioport_read()
559 count = pit_get_count(pit, addr); in pit_ioport_read()
563 count = pit_get_count(pit, addr); in pit_ioport_read()
565 s->read_state = RW_STATE_WORD1; in pit_ioport_read()
568 count = pit_get_count(pit, addr); in pit_ioport_read()
570 s->read_state = RW_STATE_WORD0; in pit_ioport_read()
579 mutex_unlock(&pit_state->lock); in pit_ioport_read()
585 gpa_t addr, int len, const void *data) in speaker_ioport_write() argument
588 struct kvm_kpit_state *pit_state = &pit->pit_state; in speaker_ioport_write()
590 if (addr != KVM_SPEAKER_BASE_ADDRESS) in speaker_ioport_write()
591 return -EOPNOTSUPP; in speaker_ioport_write()
593 mutex_lock(&pit_state->lock); in speaker_ioport_write()
595 pit_state->flags |= KVM_PIT_FLAGS_SPEAKER_DATA_ON; in speaker_ioport_write()
597 pit_state->flags &= ~KVM_PIT_FLAGS_SPEAKER_DATA_ON; in speaker_ioport_write()
599 mutex_unlock(&pit_state->lock); in speaker_ioport_write()
605 gpa_t addr, int len, void *data) in speaker_ioport_read() argument
608 struct kvm_kpit_state *pit_state = &pit->pit_state; in speaker_ioport_read()
611 if (addr != KVM_SPEAKER_BASE_ADDRESS) in speaker_ioport_read()
612 return -EOPNOTSUPP; in speaker_ioport_read()
617 mutex_lock(&pit_state->lock); in speaker_ioport_read()
618 ret = (!!(pit_state->flags & KVM_PIT_FLAGS_SPEAKER_DATA_ON) << 1) | in speaker_ioport_read()
624 mutex_unlock(&pit_state->lock); in speaker_ioport_read()
633 pit->pit_state.flags = 0; in kvm_pit_reset()
635 c = &pit->pit_state.channels[i]; in kvm_pit_reset()
636 c->mode = 0xff; in kvm_pit_reset()
637 c->gate = (i != 2); in kvm_pit_reset()
674 pit->irq_source_id = kvm_request_irq_source_id(kvm); in kvm_create_pit()
675 if (pit->irq_source_id < 0) in kvm_create_pit()
678 mutex_init(&pit->pit_state.lock); in kvm_create_pit()
684 pit->worker = kthread_create_worker(0, "kvm-pit/%d", pid_nr); in kvm_create_pit()
685 if (IS_ERR(pit->worker)) in kvm_create_pit()
688 kthread_init_work(&pit->expired, pit_do_work); in kvm_create_pit()
690 pit->kvm = kvm; in kvm_create_pit()
692 pit_state = &pit->pit_state; in kvm_create_pit()
693 hrtimer_init(&pit_state->timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS); in kvm_create_pit()
694 pit_state->timer.function = pit_timer_fn; in kvm_create_pit()
696 pit_state->irq_ack_notifier.gsi = 0; in kvm_create_pit()
697 pit_state->irq_ack_notifier.irq_acked = kvm_pit_ack_irq; in kvm_create_pit()
698 pit->mask_notifier.func = pit_mask_notifer; in kvm_create_pit()
704 mutex_lock(&kvm->slots_lock); in kvm_create_pit()
705 kvm_iodevice_init(&pit->dev, &pit_dev_ops); in kvm_create_pit()
707 KVM_PIT_MEM_LENGTH, &pit->dev); in kvm_create_pit()
712 kvm_iodevice_init(&pit->speaker_dev, &speaker_dev_ops); in kvm_create_pit()
715 &pit->speaker_dev); in kvm_create_pit()
719 mutex_unlock(&kvm->slots_lock); in kvm_create_pit()
724 kvm_io_bus_unregister_dev(kvm, KVM_PIO_BUS, &pit->dev); in kvm_create_pit()
726 mutex_unlock(&kvm->slots_lock); in kvm_create_pit()
728 kthread_destroy_worker(pit->worker); in kvm_create_pit()
730 kvm_free_irq_source_id(kvm, pit->irq_source_id); in kvm_create_pit()
738 struct kvm_pit *pit = kvm->arch.vpit; in kvm_free_pit()
741 mutex_lock(&kvm->slots_lock); in kvm_free_pit()
742 kvm_io_bus_unregister_dev(kvm, KVM_PIO_BUS, &pit->dev); in kvm_free_pit()
743 kvm_io_bus_unregister_dev(kvm, KVM_PIO_BUS, &pit->speaker_dev); in kvm_free_pit()
744 mutex_unlock(&kvm->slots_lock); in kvm_free_pit()
746 hrtimer_cancel(&pit->pit_state.timer); in kvm_free_pit()
747 kthread_destroy_worker(pit->worker); in kvm_free_pit()
748 kvm_free_irq_source_id(kvm, pit->irq_source_id); in kvm_free_pit()