#define KBD_PENDING_KBD 1
#define KBD_PENDING_AUX 2
+#define KBD_PENDING_CTRL_KBD 0x04
+#define KBD_PENDING_CTRL_AUX 0x08
#define KBD_MIGR_TIMER_PENDING 0x1
#define KBD_OBSRC_KBD 0x01
#define KBD_OBSRC_MOUSE 0x02
+#define KBD_OBSRC_CTRL 0x04
typedef struct KBDState {
uint8_t write_cmd; /* if non zero, write data to port 60 is expected */
/* Bitmask of devices with data available. */
uint8_t pending;
uint8_t obdata;
+ uint8_t cbdata;
void *kbd;
void *mouse;
QEMUTimer *throttle_timer;
if (s->pending) {
s->status |= KBD_STAT_OBF;
s->outport |= KBD_OUT_OBF;
- if (s->pending == KBD_PENDING_AUX) {
+ if (s->pending & KBD_PENDING_CTRL_KBD) {
+ s->obsrc = KBD_OBSRC_CTRL;
+ } else if (s->pending & KBD_PENDING_CTRL_AUX) {
s->status |= KBD_STAT_MOUSE_OBF;
s->outport |= KBD_OUT_MOUSE_OBF;
- s->obsrc = KBD_OBSRC_MOUSE;
- } else {
+ s->obsrc = KBD_OBSRC_CTRL;
+ } else if (s->pending & KBD_PENDING_KBD) {
s->obsrc = KBD_OBSRC_KBD;
+ } else {
+ s->status |= KBD_STAT_MOUSE_OBF;
+ s->outport |= KBD_OUT_MOUSE_OBF;
+ s->obsrc = KBD_OBSRC_MOUSE;
}
}
kbd_update_irq_lines(s);
static void kbd_queue(KBDState *s, int b, int aux)
{
- if (aux)
- ps2_queue(s->mouse, b);
- else
- ps2_queue(s->kbd, b);
+ if (s->extended_state) {
+ s->cbdata = b;
+ s->pending &= ~KBD_PENDING_CTRL_KBD & ~KBD_PENDING_CTRL_AUX;
+ s->pending |= aux ? KBD_PENDING_CTRL_AUX : KBD_PENDING_CTRL_KBD;
+ kbd_safe_update_irq(s);
+ } else {
+ ps2_queue(aux ? s->mouse : s->kbd, b);
+ }
+}
+
+static uint8_t kbd_dequeue(KBDState *s)
+{
+ uint8_t b = s->cbdata;
+
+ s->pending &= ~KBD_PENDING_CTRL_KBD & ~KBD_PENDING_CTRL_AUX;
+ if (s->pending) {
+ kbd_update_irq(s);
+ }
+ return b;
}
static void outport_write(KBDState *s, uint32_t val)
s->obdata = ps2_read_data(s->kbd);
} else if (s->obsrc & KBD_OBSRC_MOUSE) {
s->obdata = ps2_read_data(s->mouse);
+ } else if (s->obsrc & KBD_OBSRC_CTRL) {
+ s->obdata = kbd_dequeue(s);
}
}
VMSTATE_UINT32(migration_flags, KBDState),
VMSTATE_UINT32(obsrc, KBDState),
VMSTATE_UINT8(obdata, KBDState),
+ VMSTATE_UINT8(cbdata, KBDState),
VMSTATE_END_OF_LIST()
}
};