From: Matthew Ogilvie <mmogilvi_qemu@miniinfo.net>
To: qemu-devel@nongnu.org
Cc: Jan Kiszka <jan.kiszka@web.de>,
Matthew Ogilvie <mmogilvi_qemu@miniinfo.net>,
"Maciej W. Rozycki" <macro@linux-mips.org>,
Avi Kivity <avi@redhat.com>
Subject: [Qemu-devel] [PATCH v7 08/10] i8254: add comments about fixing timings
Date: Sun, 25 Nov 2012 14:51:44 -0700 [thread overview]
Message-ID: <1353880306-8004-9-git-send-email-mmogilvi_qemu@miniinfo.net> (raw)
In-Reply-To: <1353880306-8004-1-git-send-email-mmogilvi_qemu@miniinfo.net>
There may be risk of problems with migration if these are just
fixed blindly, but at least comment what it ought to be changed to.
Signed-off-by: Matthew Ogilvie <mmogilvi_qemu@miniinfo.net>
---
hw/i8254.c | 31 ++++++++++++++++++++++++++++++-
hw/i8254_common.c | 40 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 70 insertions(+), 1 deletion(-)
diff --git a/hw/i8254.c b/hw/i8254.c
index bea5f92..982e8e7 100644
--- a/hw/i8254.c
+++ b/hw/i8254.c
@@ -39,6 +39,15 @@ static void pit_irq_timer_update(PITChannelState *s, int64_t current_time);
static int pit_get_count(PITChannelState *s)
{
+ /* FIXME: Add some way to represent a paused timer and return
+ * the paused-at counter value, to better model:
+ * - gate-triggered modes (1 and 5),
+ * - gate-pausable modes,
+ * - [maybe] the "wait until next CLK pulse to load counter" logic,
+ * - [maybe/not clear] half-loaded counter logic for mode 0, and
+ * the "null count" status bit,
+ * - etc.
+ */
uint64_t d;
int counter;
@@ -52,7 +61,11 @@ static int pit_get_count(PITChannelState *s)
counter = (s->count - d) & 0xffff;
break;
case 3:
- /* XXX: may be incorrect for odd counts */
+ /* XXX: may be incorrect for odd counts
+ * FIXME i8254_timing_fixes: fix this by changing it to something
+ * like:
+ * counter = (s->count - ((2 * d) % s->count)) & 0xfffe;
+ */
counter = s->count - ((2 * d) % s->count);
break;
default:
@@ -98,6 +111,22 @@ static inline void pit_load_count(PITChannelState *s, int val)
if (val == 0)
val = 0x10000;
s->count_load_time = qemu_get_clock_ns(vm_clock);
+
+ /* FIXME i8254_timing_fixes:
+ * In gate-triggered one-shot modes, indirectly model some pit_get_out()
+ * cases by setting the load time way back until gate-triggered,
+ * using code such as:
+ *
+ * if (s->mode == 1 || s->mode == 5)
+ * s->count_load_time -= muldiv64(val+2, get_ticks_per_sec(), PIT_FREQ);
+ *
+ * (Generally only affects reading status from channel 2 speaker,
+ * due to hard-wired gates on other channels.)
+ *
+ * FIXME Or this might be redesigned if a paused timer state is added
+ * for pic_get_count().
+ */
+
s->count = val;
pit_irq_timer_update(s, s->count_load_time);
}
diff --git a/hw/i8254_common.c b/hw/i8254_common.c
index a03d7cd..33f352f 100644
--- a/hw/i8254_common.c
+++ b/hw/i8254_common.c
@@ -53,9 +53,30 @@ int pit_get_out(PITChannelState *s, int64_t current_time)
out = (d >= s->count);
break;
case 1:
+ /* FIXME i8254_timing_fixes: There are various problems
+ * with qemu's 8254 model (especially when IRQ0's trailing
+ * edge occurs), but fixing them directly might cause
+ * problems with migration. So just comment the fixes for
+ * now.
+ * (Based on reading timing diagrams in Intel's 8254 spec
+ * sheet, downloadable from
+ * http://bochs.sourceforge.net/techspec/intel-82c54-timer.pdf.gz
+ * or other places.)
+ * FIXME i8254_timing_fixes: Both mode 0 and mode 1 should use
+ * out = (d >= s->count);
+ * So mode 0 can fall-through into a fixed mode 1.
+ * The difference between modes 0 and 1 is in the gate triggering.
+ * See also an adjustment to make to count_load_time
+ * when count is loaded for mode 1.
+ */
out = (d < s->count);
break;
case 2:
+ /* FIXME i8254_timing_fixes: This should simply be:
+ * out = (d % s->count) != (s->count - 1) || s->gate == 0;
+ * Gate is hard-wired 1 for channel 0 (IRQ0), but it can be
+ * adjusted in software for channel 2 (PC speaker).
+ */
if ((d % s->count) == 0 && d != 0) {
out = 1;
} else {
@@ -63,10 +84,21 @@ int pit_get_out(PITChannelState *s, int64_t current_time)
}
break;
case 3:
+ /* FIXME i8254_timing_fixes: This should be:
+ * out = (d % s->count) < ((s->count + 1) >> 1) || s->gate == 0;
+ * Gate is hard-wired 1 for channel 0 (IRQ0), but it can be
+ * adjusted in software for channel 2 (PC speaker).
+ */
out = (d % s->count) < ((s->count + 1) >> 1);
break;
case 4:
case 5:
+ /* FIXME i8254_timing_fixes: The logic is backwards, and should be:
+ * out = (d != s->count);
+ * The difference between modes 4 and 5 is in the gate triggering.
+ * See also an adjustment to make to count_load_time
+ * when count is loaded for mode 5.
+ */
out = (d == s->count);
break;
}
@@ -93,6 +125,14 @@ int64_t pit_get_next_transition_time(PITChannelState *s, int64_t current_time)
break;
case 2:
base = (d / s->count) * s->count;
+ /* FIXME i8254_timing_fixes: The if condition and else case should
+ * be changed to:
+ * if ((d - base) == (s->count - 1)) {
+ * next_time = base + s->count;
+ * } else {
+ * next_time = base + s->count - 1;
+ * }
+ */
if ((d - base) == 0 && d != 0) {
next_time = base + s->count;
} else {
--
1.7.10.2.484.gcd07cc5
next prev parent reply other threads:[~2012-11-25 21:53 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-11-25 21:51 [Qemu-devel] [PATCH v7 00/10] i8254, i8259 and running Microport UNIX (ca 1987) Matthew Ogilvie
2012-11-25 21:51 ` [Qemu-devel] [PATCH v7 01/10] fix some debug printf format strings Matthew Ogilvie
2012-11-25 21:51 ` [Qemu-devel] [PATCH v7 02/10] vl: fix -hdachs/-hda argument order parsing issues Matthew Ogilvie
2012-11-25 21:51 ` [Qemu-devel] [PATCH v7 03/10] qemu-options.hx: mention retrace= VGA option Matthew Ogilvie
2012-11-25 21:51 ` [Qemu-devel] [PATCH v7 04/10] vga: add some optional CGA compatibility hacks Matthew Ogilvie
2012-11-25 21:51 ` [Qemu-devel] [PATCH v7 05/10] i8259: fix so that dropping IRQ level always clears the interrupt request Matthew Ogilvie
2012-11-25 21:51 ` [Qemu-devel] [PATCH v7 06/10] i8259: refactor pic_set_irq level logic Matthew Ogilvie
2012-11-25 21:51 ` [Qemu-devel] [PATCH v7 07/10] i8254/i8259: workaround to make IRQ0 work like before Matthew Ogilvie
2012-11-25 21:51 ` Matthew Ogilvie [this message]
2012-11-25 21:51 ` [Qemu-devel] [PATCH v7 09/10] i8254: prepare for migration compatibility with future fixes Matthew Ogilvie
2012-11-25 21:51 ` [Qemu-devel] [PATCH v7 10/10] FOR FUTURE: fix i8254/i8259 IRQ0 line logic Matthew Ogilvie
2012-12-10 5:14 ` [Qemu-devel] [PATCH v7 00/10] i8254, i8259 and running Microport UNIX (ca 1987) Matthew Ogilvie
2012-12-10 7:15 ` Jan Kiszka
2012-12-10 16:47 ` Anthony Liguori
2012-12-11 6:10 ` Matthew Ogilvie
2012-12-11 11:20 ` Jamie Lokier
2012-12-12 7:25 ` Matthew Ogilvie
2012-12-11 16:19 ` Gleb Natapov
2012-12-12 7:46 ` Matthew Ogilvie
2012-12-12 11:36 ` Gleb Natapov
2012-12-12 11:38 ` Jan Kiszka
2012-12-12 11:41 ` Gleb Natapov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1353880306-8004-9-git-send-email-mmogilvi_qemu@miniinfo.net \
--to=mmogilvi_qemu@miniinfo.net \
--cc=avi@redhat.com \
--cc=jan.kiszka@web.de \
--cc=macro@linux-mips.org \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).