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()
226 timer = &pit->pit_state.timer; in __kvm_migrate_pit_timer()
227 mutex_lock(&pit->pit_state.lock); in __kvm_migrate_pit_timer()
230 mutex_unlock(&pit->pit_state.lock); in __kvm_migrate_pit_timer()
235 hrtimer_cancel(&pit->pit_state.timer); in destroy_pit_timer()
236 kthread_flush_work(&pit->expired); in destroy_pit_timer()
242 struct kvm *kvm = pit->kvm; in pit_do_work()
245 struct kvm_kpit_state *ps = &pit->pit_state; in pit_do_work()
247 if (atomic_read(&ps->reinject) && !atomic_xchg(&ps->irq_ack, 0)) in pit_do_work()
250 kvm_set_irq(kvm, pit->irq_source_id, 0, 1, false); in pit_do_work()
251 kvm_set_irq(kvm, pit->irq_source_id, 0, 0, false); in pit_do_work()
254 * Provides NMI watchdog support via Virtual Wire mode. in pit_do_work()
255 * The route is: PIT -> LVT0 in NMI mode. in pit_do_work()
259 * VCPUs and only when LVT0 is in NMI mode. The interrupt can in pit_do_work()
262 if (atomic_read(&kvm->arch.vapics_in_nmi_mode) > 0) in pit_do_work()
272 if (atomic_read(&ps->reinject)) in pit_timer_fn()
273 atomic_inc(&ps->pending); in pit_timer_fn()
275 kthread_queue_work(pt->worker, &pt->expired); in pit_timer_fn()
277 if (ps->is_periodic) { in pit_timer_fn()
278 hrtimer_add_expires_ns(&ps->timer, ps->period); in pit_timer_fn()
286 atomic_set(&pit->pit_state.pending, 0); in kvm_pit_reset_reinject()
287 atomic_set(&pit->pit_state.irq_ack, 1); in kvm_pit_reset_reinject()
292 struct kvm_kpit_state *ps = &pit->pit_state; in kvm_pit_set_reinject()
293 struct kvm *kvm = pit->kvm; in kvm_pit_set_reinject()
295 if (atomic_read(&ps->reinject) == reinject) in kvm_pit_set_reinject()
300 * This cause in-kernel PIT re-inject mode to fail in kvm_pit_set_reinject()
301 * since it checks ps->irq_ack before kvm_set_irq() in kvm_pit_set_reinject()
303 * the pt->worker work iterm and reinject the missed tick. in kvm_pit_set_reinject()
304 * 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()
316 kvm_unregister_irq_ack_notifier(kvm, &ps->irq_ack_notifier); in kvm_pit_set_reinject()
317 kvm_unregister_irq_mask_notifier(kvm, 0, &pit->mask_notifier); in kvm_pit_set_reinject()
320 atomic_set(&ps->reinject, reinject); in kvm_pit_set_reinject()
325 struct kvm_kpit_state *ps = &pit->pit_state; in create_pit_timer()
326 struct kvm *kvm = pit->kvm; in create_pit_timer()
330 ps->flags & KVM_PIT_FLAGS_HPET_LEGACY) in create_pit_timer()
338 hrtimer_cancel(&ps->timer); in create_pit_timer()
339 kthread_flush_work(&pit->expired); in create_pit_timer()
340 ps->period = interval; in create_pit_timer()
341 ps->is_periodic = is_period; in create_pit_timer()
350 if (ps->is_periodic) { in create_pit_timer()
353 if (ps->period < min_period) { in create_pit_timer()
357 ps->period, min_period); in create_pit_timer()
358 ps->period = min_period; in create_pit_timer()
362 hrtimer_start(&ps->timer, ktime_add_ns(ktime_get(), interval), in create_pit_timer()
368 struct kvm_kpit_state *ps = &pit->pit_state; in pit_load_count()
379 ps->channels[channel].count = val; in pit_load_count()
382 ps->channels[channel].count_load_time = ktime_get(); in pit_load_count()
387 * mode 1 is one shot, mode 2 is period, otherwise del timer */ in pit_load_count()
388 switch (ps->channels[0].mode) { in pit_load_count()
391 /* FIXME: enhance mode 4 precision */ in pit_load_count()
409 WARN_ON_ONCE(!mutex_is_locked(&pit->pit_state.lock)); in kvm_pit_load_count()
412 /* save existing mode for later reenablement */ in kvm_pit_load_count()
414 saved_mode = pit->pit_state.channels[0].mode; in kvm_pit_load_count()
415 pit->pit_state.channels[0].mode = 0xff; /* disable timer */ in kvm_pit_load_count()
417 pit->pit_state.channels[0].mode = saved_mode; in kvm_pit_load_count()
433 static inline int pit_in_range(gpa_t addr) in pit_in_range() argument
435 return ((addr >= KVM_PIT_BASE_ADDRESS) && in pit_in_range()
436 (addr < KVM_PIT_BASE_ADDRESS + KVM_PIT_MEM_LENGTH)); in pit_in_range()
441 gpa_t addr, int len, const void *data) in pit_ioport_write() argument
444 struct kvm_kpit_state *pit_state = &pit->pit_state; in pit_ioport_write()
448 if (!pit_in_range(addr)) in pit_ioport_write()
449 return -EOPNOTSUPP; in pit_ioport_write()
452 addr &= KVM_PIT_CHANNEL_MASK; in pit_ioport_write()
454 mutex_lock(&pit_state->lock); in pit_ioport_write()
457 pr_debug("write addr is 0x%x, len is %d, val is 0x%x\n", in pit_ioport_write()
458 (unsigned int)addr, len, val); in pit_ioport_write()
460 if (addr == 3) { in pit_ioport_write()
463 /* Read-Back Command. */ in pit_ioport_write()
474 s = &pit_state->channels[channel]; in pit_ioport_write()
479 s->rw_mode = access; in pit_ioport_write()
480 s->read_state = access; in pit_ioport_write()
481 s->write_state = access; in pit_ioport_write()
482 s->mode = (val >> 1) & 7; in pit_ioport_write()
483 if (s->mode > 5) in pit_ioport_write()
484 s->mode -= 4; in pit_ioport_write()
485 s->bcd = val & 1; in pit_ioport_write()
490 s = &pit_state->channels[addr]; in pit_ioport_write()
491 switch (s->write_state) { in pit_ioport_write()
494 pit_load_count(pit, addr, val); in pit_ioport_write()
497 pit_load_count(pit, addr, val << 8); in pit_ioport_write()
500 s->write_latch = val; in pit_ioport_write()
501 s->write_state = RW_STATE_WORD1; in pit_ioport_write()
504 pit_load_count(pit, addr, s->write_latch | (val << 8)); in pit_ioport_write()
505 s->write_state = RW_STATE_WORD0; in pit_ioport_write()
510 mutex_unlock(&pit_state->lock); in pit_ioport_write()
516 gpa_t addr, int len, void *data) in pit_ioport_read() argument
519 struct kvm_kpit_state *pit_state = &pit->pit_state; in pit_ioport_read()
522 if (!pit_in_range(addr)) in pit_ioport_read()
523 return -EOPNOTSUPP; in pit_ioport_read()
525 addr &= KVM_PIT_CHANNEL_MASK; in pit_ioport_read()
526 if (addr == 3) in pit_ioport_read()
529 s = &pit_state->channels[addr]; in pit_ioport_read()
531 mutex_lock(&pit_state->lock); in pit_ioport_read()
533 if (s->status_latched) { in pit_ioport_read()
534 s->status_latched = 0; in pit_ioport_read()
535 ret = s->status; in pit_ioport_read()
536 } else if (s->count_latched) { in pit_ioport_read()
537 switch (s->count_latched) { in pit_ioport_read()
540 ret = s->latched_count & 0xff; in pit_ioport_read()
541 s->count_latched = 0; in pit_ioport_read()
544 ret = s->latched_count >> 8; in pit_ioport_read()
545 s->count_latched = 0; in pit_ioport_read()
548 ret = s->latched_count & 0xff; in pit_ioport_read()
549 s->count_latched = RW_STATE_MSB; in pit_ioport_read()
553 switch (s->read_state) { in pit_ioport_read()
556 count = pit_get_count(pit, addr); in pit_ioport_read()
560 count = pit_get_count(pit, addr); in pit_ioport_read()
564 count = pit_get_count(pit, addr); in pit_ioport_read()
566 s->read_state = RW_STATE_WORD1; in pit_ioport_read()
569 count = pit_get_count(pit, addr); in pit_ioport_read()
571 s->read_state = RW_STATE_WORD0; in pit_ioport_read()
580 mutex_unlock(&pit_state->lock); in pit_ioport_read()
586 gpa_t addr, int len, const void *data) in speaker_ioport_write() argument
589 struct kvm_kpit_state *pit_state = &pit->pit_state; in speaker_ioport_write()
591 if (addr != KVM_SPEAKER_BASE_ADDRESS) in speaker_ioport_write()
592 return -EOPNOTSUPP; in speaker_ioport_write()
594 mutex_lock(&pit_state->lock); in speaker_ioport_write()
595 pit_state->speaker_data_on = (val >> 1) & 1; in speaker_ioport_write()
597 mutex_unlock(&pit_state->lock); in speaker_ioport_write()
603 gpa_t addr, int len, void *data) in speaker_ioport_read() argument
606 struct kvm_kpit_state *pit_state = &pit->pit_state; in speaker_ioport_read()
609 if (addr != KVM_SPEAKER_BASE_ADDRESS) in speaker_ioport_read()
610 return -EOPNOTSUPP; in speaker_ioport_read()
615 mutex_lock(&pit_state->lock); in speaker_ioport_read()
616 ret = ((pit_state->speaker_data_on << 1) | pit_get_gate(pit, 2) | in speaker_ioport_read()
621 mutex_unlock(&pit_state->lock); in speaker_ioport_read()
630 pit->pit_state.flags = 0; in kvm_pit_reset()
632 c = &pit->pit_state.channels[i]; in kvm_pit_reset()
633 c->mode = 0xff; in kvm_pit_reset()
634 c->gate = (i != 2); in kvm_pit_reset()
671 pit->irq_source_id = kvm_request_irq_source_id(kvm); in kvm_create_pit()
672 if (pit->irq_source_id < 0) in kvm_create_pit()
675 mutex_init(&pit->pit_state.lock); in kvm_create_pit()
681 pit->worker = kthread_create_worker(0, "kvm-pit/%d", pid_nr); in kvm_create_pit()
682 if (IS_ERR(pit->worker)) in kvm_create_pit()
685 kthread_init_work(&pit->expired, pit_do_work); in kvm_create_pit()
687 pit->kvm = kvm; in kvm_create_pit()
689 pit_state = &pit->pit_state; in kvm_create_pit()
690 hrtimer_init(&pit_state->timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS); in kvm_create_pit()
691 pit_state->timer.function = pit_timer_fn; in kvm_create_pit()
693 pit_state->irq_ack_notifier.gsi = 0; in kvm_create_pit()
694 pit_state->irq_ack_notifier.irq_acked = kvm_pit_ack_irq; in kvm_create_pit()
695 pit->mask_notifier.func = pit_mask_notifer; in kvm_create_pit()
701 mutex_lock(&kvm->slots_lock); in kvm_create_pit()
702 kvm_iodevice_init(&pit->dev, &pit_dev_ops); in kvm_create_pit()
704 KVM_PIT_MEM_LENGTH, &pit->dev); in kvm_create_pit()
709 kvm_iodevice_init(&pit->speaker_dev, &speaker_dev_ops); in kvm_create_pit()
712 &pit->speaker_dev); in kvm_create_pit()
716 mutex_unlock(&kvm->slots_lock); in kvm_create_pit()
721 kvm_io_bus_unregister_dev(kvm, KVM_PIO_BUS, &pit->dev); in kvm_create_pit()
723 mutex_unlock(&kvm->slots_lock); in kvm_create_pit()
725 kthread_destroy_worker(pit->worker); in kvm_create_pit()
727 kvm_free_irq_source_id(kvm, pit->irq_source_id); in kvm_create_pit()
735 struct kvm_pit *pit = kvm->arch.vpit; in kvm_free_pit()
738 mutex_lock(&kvm->slots_lock); in kvm_free_pit()
739 kvm_io_bus_unregister_dev(kvm, KVM_PIO_BUS, &pit->dev); in kvm_free_pit()
740 kvm_io_bus_unregister_dev(kvm, KVM_PIO_BUS, &pit->speaker_dev); in kvm_free_pit()
741 mutex_unlock(&kvm->slots_lock); in kvm_free_pit()
743 hrtimer_cancel(&pit->pit_state.timer); in kvm_free_pit()
744 kthread_destroy_worker(pit->worker); in kvm_free_pit()
745 kvm_free_irq_source_id(kvm, pit->irq_source_id); in kvm_free_pit()