[SeaBIOS] [PATCH] ps2: disable the keyboard and mouse before flushing the queue

Kevin O'Connor kevin at koconnor.net
Fri Apr 26 01:08:26 CEST 2013


On Thu, Apr 25, 2013 at 10:33:57AM -0500, Anthony Liguori wrote:
> Kevin O'Connor <kevin at koconnor.net> writes:
> > Thanks.  I don't understand why keyboard/mouse events would be a
> > problem.  Those events should get discarded with the "Discarding ps2
> > data %02x (status=%02x)" message.  (The role of the flush is to make
> > sure there are no i8042 command responses pending - I don't think
> > keyboard/mouse events are a problem.)
> 
> This is much too late.  I think what's happening is:
> 
> >    /* flush incoming keys */
> >    int ret = i8042_flush();
> >    if (ret)
> >        return;
> 
> This drains the PS/2 queue but if the keyboard is enabled, then more
> data can appear in the queue.
> 
> >    // Controller self-test.
> >    u8 param[2];
> >    ret = i8042_command(I8042_CMD_CTL_TEST, param);
> >    if (ret)
> >        return;
> >    if (param[0] != 0x55) {
> >        dprintf(1, "i8042 self test failed (got %x not 0x55)\n", param[0]);
> >        return;
> >    }
> 
> The patch below in QEMU will effectively queue the injected queue
> keycode before the 0x55 that self-test returns.  The command queue is
> shared with the keyboard and the i8042 so if the keyboard is active, you
> may get keyboard data before getting the command responses.

My understanding is that the i8042 has two queues - one for the
results of i8042 commands and one for the keyboard.  Upon sending an
i8042 command any reads from PORT_PS2_DATA will return data from the
i8042 queue until that queue is drained.  Only after that would a read
from PORT_PS2_DATA return data from the keyboard queue.  Otherwise,
I'm not sure how one could ever reliably read the results from an
i8042 command.

The above aside, we can't disable the keyboard before flushing,
because we don't know the i8042 exists at all.  Also, we can't send an
i8042 command without verifying the i8042 is ready for a command (ie,
using i8042_command(I8042_CMD_KBD_DISABLE)).  However, we can't really
do that until we know the i8042 exists - so it's a bit circular.

-Kevin



More information about the SeaBIOS mailing list