/*
* QEMU 8253/8254 interval timer emulation
- *
+ *
* Copyright (c) 2003-2004 Fabrice Bellard
- *
+ *
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
/* irq handling */
int64_t next_transition_time;
QEMUTimer *irq_timer;
- int irq;
+ qemu_irq irq;
} PITChannelState;
struct PITState {
}
/* return -1 if no transition will occur. */
-static int64_t pit_get_next_transition_time(PITChannelState *s,
+static int64_t pit_get_next_transition_time(PITChannelState *s,
int64_t current_time)
{
uint64_t d, next_time, base;
case 3:
base = (d / s->count) * s->count;
period2 = ((s->count + 1) >> 1);
- if ((d - base) < period2)
+ if ((d - base) < period2)
next_time = base + period2;
else
next_time = base + s->count;
return s->gate;
}
+int pit_get_initial_count(PITState *pit, int channel)
+{
+ PITChannelState *s = &pit->channels[channel];
+ return s->count;
+}
+
+int pit_get_mode(PITState *pit, int channel)
+{
+ PITChannelState *s = &pit->channels[channel];
+ return s->mode;
+}
+
static inline void pit_load_count(PITChannelState *s, int val)
{
if (val == 0)
PITState *pit = opaque;
int ret, count;
PITChannelState *s;
-
+
addr &= 3;
s = &pit->channels[addr];
if (s->status_latched) {
return;
expire_time = pit_get_next_transition_time(s, current_time);
irq_level = pit_get_out1(s, current_time);
- pic_set_irq(s->irq, irq_level);
+ qemu_set_irq(s->irq, irq_level);
#ifdef DEBUG_PIT
printf("irq_level=%d next_delay=%f\n",
- irq_level,
+ irq_level,
(double)(expire_time - current_time) / ticks_per_sec);
#endif
s->next_transition_time = expire_time;
PITState *pit = opaque;
PITChannelState *s;
int i;
-
+
for(i = 0; i < 3; i++) {
s = &pit->channels[i];
qemu_put_be32s(f, &s->count);
PITState *pit = opaque;
PITChannelState *s;
int i;
-
+
if (version_id != 1)
return -EINVAL;
return 0;
}
-PITState *pit_init(int base, int irq)
+static void pit_reset(void *opaque)
{
- PITState *pit = &pit_state;
+ PITState *pit = opaque;
PITChannelState *s;
int i;
for(i = 0;i < 3; i++) {
s = &pit->channels[i];
- if (i == 0) {
- /* the timer 0 is connected to an IRQ */
- s->irq_timer = qemu_new_timer(vm_clock, pit_irq_timer, s);
- s->irq = irq;
- }
s->mode = 3;
s->gate = (i != 2);
pit_load_count(s, 0);
}
+}
+
+PITState *pit_init(int base, qemu_irq irq)
+{
+ PITState *pit = &pit_state;
+ PITChannelState *s;
+
+ s = &pit->channels[0];
+ /* the timer 0 is connected to an IRQ */
+ s->irq_timer = qemu_new_timer(vm_clock, pit_irq_timer, s);
+ s->irq = irq;
register_savevm("i8254", base, 1, pit_save, pit_load, pit);
+ qemu_register_reset(pit_reset, pit);
register_ioport_write(base, 4, 1, pit_ioport_write, pit);
register_ioport_read(base, 3, 1, pit_ioport_read, pit);
+
+ pit_reset(pit);
+
return pit;
}