qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [Bug 1574246] Re: Drunken keyboard in go32v2 programs


From: Kevin O'Connor
Subject: Re: [Qemu-devel] [Bug 1574246] Re: Drunken keyboard in go32v2 programs
Date: Tue, 29 Nov 2016 21:08:06 -0500
User-agent: Mutt/1.7.1 (2016-10-04)

On Wed, May 04, 2016 at 10:38:09AM -0000, felix wrote:
> I compiled the latest git snapshot (tag: v2.6.0-rc4, calling itself
> 2.5.94; with GTK frontend) and could only half-reproduce the bug; keys
> do not longer "jam", but arrow keys are still captured twice. I woudn't
> make much of that difference; this bug seems very timing-sensitive. It
> could be that the GTK frontend adds sufficient latency to the interface
> to avoid triggering it.
> 
> I enabled some debugging switches and recompiled both QEMU and the
> latest git snapshot of SeaBIOS (1.9.0-127; commit
> c8e105a4d5e52e8e7539ab1f2cd07ebe0ae9033a). This is what I got when
> running programs affected by this bug:
> 
> (key press)
> [qemu   ] ps2_queue(0xe0)
> [qemu   ] ps2_queue(0x4d)
> (IRQ1)
> [qemu   ] KBD: kbd: read data=0xe0 ← (***)
> [seabios] handle_09
> [qemu   ] KBD: kbd: read status=0x1d
> [qemu   ] KBD: kbd: read data=0x4d
> [seabios] i8042_command cmd=ae
> [seabios] i8042_wait_write
> [qemu   ] KBD: kbd: read status=0x1c
> [qemu   ] KBD: kbd: write cmd=0xae
> (IRQ1)
> [qemu   ] KBD: kbd: read data=0x4d ← (***)
> [seabios] handle_09
> [qemu   ] KBD: kbd: read status=0x1c
> [qemu   ] KBD: kbd: read data=0x4d
> [seabios] i8042_command cmd=ae
> [seabios] i8042_wait_write
> [qemu   ] KBD: kbd: read status=0x1c
> [qemu   ] KBD: kbd: write cmd=0xae
> 
> Reads marked (***) do not appear when running unaffected programs. So it
> appears something is making reads from the keyboard controller before
> SeaBIOS has a chance to put scancodes in the ring buffer. And indeed:
> DJGPP libc installs a custom IRQ1 handler which does it to detect
> whether it should raise SIGINT in response to Ctrl+C; it can be found in
> the file src/libc/go32/exceptn.S in the djcrx package[1]. Free Pascal
> incorporates this handler into its RTL with almost no changes; it's
> found in rtl/go32v2/exceptn.as[2]. I also noticed I can reproduce this
> bug with Borland Pascal 7; lo and behold, the Turbo Vision library does
> something similar.
> 
> SeaBIOS gets extra confused when I send some mouse events to QEMU (grab
> the mouse, move it around, ungrab); it reacts with a "ps2 keyboard irq
> but found mouse data?!" message and refuses to put keys in the ring
> buffer until the queue of mouse events becomes empty.
> 
> That's the culprit, I think. It also explains why the bug doesn't appear
> under Windows; because port 0x60 reads from DPMI are simulated, they
> don't correspond to actual port 0x60 reads in the guest. I don't know
> what the fix ought be; documentation about the i8042 that I found is
> unclear about what real hardware does in this case.

I know this bug report is old, but I figured I'd add some additional
details.  Normally port 0x60 acts as a queue - each read to the port
pops data off that queue.  However, on real hardware, the keyboard
can't push data faster than one byte every 660us.  Some old DOS
programs relied on this to inspect the next byte prior to the BIOS
actually handling that byte.  (They would read from the queue and
expect the subsequent BIOS read to occur before the next byte could be
queue'd - thus the BIOS would read the same byte.)  Alas, QEMU doesn't
implement this type of delay and therefore the subsequent BIOS read
actually gets the next byte.

> If I'm reading the code correctly, DOSEMU[3] (also the DOSEMU2 fork[4]),
> DOSBox[5], Bochs[6] and VirtualBox[7] keep one value to be read from
> 0x60 at until the next interrupt, avoiding the issue.

Such a change to QEMU might fix the issue.

-Kevin



reply via email to

[Prev in Thread] Current Thread [Next in Thread]