Instead of providing 4 individual query functions for mode, gate, output and initial counter state, introduce a service that queries all information at once. This comes with tiny additional costs for pcspk_callback but with a much cleaner interface. Also, it will simplify the implementation of the KVM in-kernel PIT model. Signed-off-by: Jan Kiszka <jan.kiszka@xxxxxxxxxxx> --- hw/i8254.c | 35 ++++++++++------------------------- hw/i8254.h | 12 ++++++++---- hw/pcspk.c | 16 +++++++++++----- 3 files changed, 29 insertions(+), 34 deletions(-) diff --git a/hw/i8254.c b/hw/i8254.c index ac5432c..be39c55 100644 --- a/hw/i8254.c +++ b/hw/i8254.c @@ -90,7 +90,7 @@ static int pit_get_count(PITChannelState *s) } /* get pit output bit */ -static int pit_get_out1(PITChannelState *s, int64_t current_time) +static int pit_get_out(PITChannelState *s, int64_t current_time) { uint64_t d; int out; @@ -122,13 +122,6 @@ static int pit_get_out1(PITChannelState *s, int64_t current_time) return out; } -int pit_get_out(ISADevice *dev, int channel, int64_t current_time) -{ - PITState *pit = DO_UPCAST(PITState, dev, dev); - PITChannelState *s = &pit->channels[channel]; - return pit_get_out1(s, current_time); -} - /* return -1 if no transition will occur. */ static int64_t pit_get_next_transition_time(PITChannelState *s, int64_t current_time) @@ -215,25 +208,15 @@ void pit_set_gate(ISADevice *dev, int channel, int val) s->gate = val; } -int pit_get_gate(ISADevice *dev, int channel) -{ - PITState *pit = DO_UPCAST(PITState, dev, dev); - PITChannelState *s = &pit->channels[channel]; - return s->gate; -} - -int pit_get_initial_count(ISADevice *dev, int channel) +void pit_get_channel_info(ISADevice *dev, int channel, PITChannelInfo *info) { PITState *pit = DO_UPCAST(PITState, dev, dev); PITChannelState *s = &pit->channels[channel]; - return s->count; -} -int pit_get_mode(ISADevice *dev, int channel) -{ - PITState *pit = DO_UPCAST(PITState, dev, dev); - PITChannelState *s = &pit->channels[channel]; - return s->mode; + info->gate = s->gate; + info->mode = s->mode; + info->initial_count = s->count; + info->out = pit_get_out(s, qemu_get_clock_ns(vm_clock)); } static inline void pit_load_count(PITChannelState *s, int val) @@ -274,7 +257,9 @@ static void pit_ioport_write(void *opaque, uint32_t addr, uint32_t val) if (!(val & 0x10) && !s->status_latched) { /* status latch */ /* XXX: add BCD and null count */ - s->status = (pit_get_out1(s, qemu_get_clock_ns(vm_clock)) << 7) | + s->status = + (pit_get_out(s, + qemu_get_clock_ns(vm_clock)) << 7) | (s->rw_mode << 4) | (s->mode << 1) | s->bcd; @@ -381,7 +366,7 @@ static void pit_irq_timer_update(PITChannelState *s, int64_t current_time) return; } expire_time = pit_get_next_transition_time(s, current_time); - irq_level = pit_get_out1(s, current_time); + irq_level = pit_get_out(s, current_time); qemu_set_irq(s->irq, irq_level); #ifdef DEBUG_PIT printf("irq_level=%d next_delay=%f\n", diff --git a/hw/i8254.h b/hw/i8254.h index 8ad8e07..a1d2e98 100644 --- a/hw/i8254.h +++ b/hw/i8254.h @@ -30,6 +30,13 @@ #define PIT_FREQ 1193182 +typedef struct PITChannelInfo { + int gate; + int mode; + int initial_count; + int out; +} PITChannelInfo; + static inline ISADevice *pit_init(ISABus *bus, int base, int isa_irq, qemu_irq alt_irq) { @@ -45,9 +52,6 @@ static inline ISADevice *pit_init(ISABus *bus, int base, int isa_irq, } void pit_set_gate(ISADevice *dev, int channel, int val); -int pit_get_gate(ISADevice *dev, int channel); -int pit_get_initial_count(ISADevice *dev, int channel); -int pit_get_mode(ISADevice *dev, int channel); -int pit_get_out(ISADevice *dev, int channel, int64_t current_time); +void pit_get_channel_info(ISADevice *dev, int channel, PITChannelInfo *info); #endif /* !HW_I8254_H */ diff --git a/hw/pcspk.c b/hw/pcspk.c index d406c68..caa21a8 100644 --- a/hw/pcspk.c +++ b/hw/pcspk.c @@ -75,12 +75,16 @@ static inline void generate_samples(PCSpkState *s) static void pcspk_callback(void *opaque, int free) { PCSpkState *s = opaque; + PITChannelInfo ch; unsigned int n; - if (pit_get_mode(s->pit, 2) != 3) + pit_get_channel_info(s->pit, 2, &ch); + + if (ch.mode != 3) { return; + } - n = pit_get_initial_count(s->pit, 2); + n = ch.initial_count; /* avoid frequencies that are not reproducible with sample rate */ if (n < PCSPK_MIN_COUNT) n = 0; @@ -121,12 +125,14 @@ static uint64_t pcspk_io_read(void *opaque, target_phys_addr_t addr, unsigned size) { PCSpkState *s = opaque; - int out; + PITChannelInfo ch; + + pit_get_channel_info(s->pit, 2, &ch); s->dummy_refresh_clock ^= (1 << 4); - out = pit_get_out(s->pit, 2, qemu_get_clock_ns(vm_clock)) << 5; - return pit_get_gate(s->pit, 2) | (s->data_on << 1) | s->dummy_refresh_clock | out; + return ch.gate | (s->data_on << 1) | s->dummy_refresh_clock | + (ch.out << 5); } static void pcspk_io_write(void *opaque, target_phys_addr_t addr, uint64_t val, -- 1.7.3.4 -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html