From patchwork Sat Aug 7 12:12:00 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Volker_R=C3=BCmelin?= X-Patchwork-Id: 1514652 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4Ghh7l3tx9z9s1l for ; Sat, 7 Aug 2021 22:13:07 +1000 (AEST) Received: from localhost ([::1]:45556 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mCLCL-0002RS-8o for incoming@patchwork.ozlabs.org; Sat, 07 Aug 2021 08:13:05 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:48468) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mCLBd-0002CI-Hy for qemu-devel@nongnu.org; Sat, 07 Aug 2021 08:12:21 -0400 Received: from mailout06.t-online.de ([194.25.134.19]:39074) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mCLBb-0003hC-Bx for qemu-devel@nongnu.org; Sat, 07 Aug 2021 08:12:21 -0400 Received: from fwd10.aul.t-online.de (fwd10.aul.t-online.de [172.20.26.152]) by mailout06.t-online.de (Postfix) with SMTP id 6CCBA1AF77; Sat, 7 Aug 2021 14:12:10 +0200 (CEST) Received: from linpower.localnet (XH7Ry+Zc8h8PJvfRmF65zSo89VaSXcq8ITJatkseOGVIHugy07irbrMOwDJ4unggXV@[79.208.26.7]) by fwd10.t-online.de with (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384 encrypted) esmtp id 1mCLBK-0XZ4880; Sat, 7 Aug 2021 14:12:02 +0200 Received: by linpower.localnet (Postfix, from userid 1000) id 2A97D2000A1; Sat, 7 Aug 2021 14:12:02 +0200 (CEST) From: =?utf-8?q?Volker_R=C3=BCmelin?= To: Gerd Hoffmann Subject: [PATCH 1/3] ps2: use the whole ps2 buffer but keep queue size Date: Sat, 7 Aug 2021 14:12:00 +0200 Message-Id: <20210807121202.6294-1-vr_qemu@t-online.de> X-Mailer: git-send-email 2.26.2 In-Reply-To: <4d1c8467-d976-2c0f-ba54-c767df7b8fe7@t-online.de> References: <4d1c8467-d976-2c0f-ba54-c767df7b8fe7@t-online.de> MIME-Version: 1.0 X-ID: XH7Ry+Zc8h8PJvfRmF65zSo89VaSXcq8ITJatkseOGVIHugy07irbrMOwDJ4unggXV X-TOI-EXPURGATEID: 150726::1628338322-00000BB9-372AF816/0/0 CLEAN NORMAL X-TOI-MSGID: 812d4948-d633-4b20-9339-7e34a5604a16 Received-SPF: none client-ip=194.25.134.19; envelope-from=volker.ruemelin@t-online.de; helo=mailout06.t-online.de X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= , qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Extend the used ps2 buffer size to the available buffer size but keep the maximum ps2 queue size. The next patch needs a few bytes of the larger buffer size. Signed-off-by: Volker Rümelin --- hw/input/ps2.c | 69 +++++++++++++++----------------------------------- 1 file changed, 20 insertions(+), 49 deletions(-) diff --git a/hw/input/ps2.c b/hw/input/ps2.c index 8dd482c1f6..23e7befee5 100644 --- a/hw/input/ps2.c +++ b/hw/input/ps2.c @@ -74,7 +74,12 @@ #define MOUSE_STATUS_ENABLED 0x20 #define MOUSE_STATUS_SCALE21 0x10 -#define PS2_QUEUE_SIZE 16 /* Buffer size required by PS/2 protocol */ +/* + * PS/2 buffer size. Keep 256 bytes for compatibility with + * older QEMU versions. + */ +#define PS2_BUFFER_SIZE 256 +#define PS2_QUEUE_SIZE 16 /* Queue size required by PS/2 protocol */ /* Bits for 'modifiers' field in PS2KbdState */ #define MOD_CTRL_L (1 << 0) @@ -85,9 +90,7 @@ #define MOD_ALT_R (1 << 5) typedef struct { - /* Keep the data array 256 bytes long, which compatibility - with older qemu versions. */ - uint8_t data[256]; + uint8_t data[PS2_BUFFER_SIZE]; int rptr, wptr, count; } PS2Queue; @@ -200,8 +203,9 @@ void ps2_queue_noirq(PS2State *s, int b) } q->data[q->wptr] = b; - if (++q->wptr == PS2_QUEUE_SIZE) + if (++q->wptr == PS2_BUFFER_SIZE) { q->wptr = 0; + } q->count++; } @@ -509,13 +513,15 @@ uint32_t ps2_read_data(PS2State *s) (needed for EMM386) */ /* XXX: need a timer to do things correctly */ index = q->rptr - 1; - if (index < 0) - index = PS2_QUEUE_SIZE - 1; + if (index < 0) { + index = PS2_BUFFER_SIZE - 1; + } val = q->data[index]; } else { val = q->data[q->rptr]; - if (++q->rptr == PS2_QUEUE_SIZE) + if (++q->rptr == PS2_BUFFER_SIZE) { q->rptr = 0; + } q->count--; /* reading deasserts IRQ */ s->update_irq(s->update_arg, 0); @@ -926,30 +932,17 @@ static void ps2_common_reset(PS2State *s) static void ps2_common_post_load(PS2State *s) { PS2Queue *q = &s->queue; - uint8_t i, size; - uint8_t tmp_data[PS2_QUEUE_SIZE]; - /* set the useful data buffer queue size, < PS2_QUEUE_SIZE */ - size = q->count; + /* set the useful data buffer queue size <= PS2_QUEUE_SIZE */ if (q->count < 0) { - size = 0; + q->count = 0; } else if (q->count > PS2_QUEUE_SIZE) { - size = PS2_QUEUE_SIZE; - } - - /* move the queue elements to the start of data array */ - for (i = 0; i < size; i++) { - if (q->rptr < 0 || q->rptr >= sizeof(q->data)) { - q->rptr = 0; - } - tmp_data[i] = q->data[q->rptr++]; + q->count = PS2_QUEUE_SIZE; } - memcpy(q->data, tmp_data, size); - /* reset rptr/wptr/count */ - q->rptr = 0; - q->wptr = (size == PS2_QUEUE_SIZE) ? 0 : size; - q->count = size; + /* sanitize rptr and recalculate wptr */ + q->rptr = q->rptr & (PS2_BUFFER_SIZE - 1); + q->wptr = (q->rptr + q->count) & (PS2_BUFFER_SIZE - 1); } static void ps2_kbd_reset(void *opaque) @@ -1053,22 +1046,11 @@ static int ps2_kbd_post_load(void* opaque, int version_id) return 0; } -static int ps2_kbd_pre_save(void *opaque) -{ - PS2KbdState *s = (PS2KbdState *)opaque; - PS2State *ps2 = &s->common; - - ps2_common_post_load(ps2); - - return 0; -} - static const VMStateDescription vmstate_ps2_keyboard = { .name = "ps2kbd", .version_id = 3, .minimum_version_id = 2, .post_load = ps2_kbd_post_load, - .pre_save = ps2_kbd_pre_save, .fields = (VMStateField[]) { VMSTATE_STRUCT(common, PS2KbdState, 0, vmstate_ps2_common, PS2State), VMSTATE_INT32(scan_enabled, PS2KbdState), @@ -1093,22 +1075,11 @@ static int ps2_mouse_post_load(void *opaque, int version_id) return 0; } -static int ps2_mouse_pre_save(void *opaque) -{ - PS2MouseState *s = (PS2MouseState *)opaque; - PS2State *ps2 = &s->common; - - ps2_common_post_load(ps2); - - return 0; -} - static const VMStateDescription vmstate_ps2_mouse = { .name = "ps2mouse", .version_id = 2, .minimum_version_id = 2, .post_load = ps2_mouse_post_load, - .pre_save = ps2_mouse_pre_save, .fields = (VMStateField[]) { VMSTATE_STRUCT(common, PS2MouseState, 0, vmstate_ps2_common, PS2State), VMSTATE_UINT8(mouse_status, PS2MouseState), From patchwork Sat Aug 7 12:12:01 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Volker_R=C3=BCmelin?= X-Patchwork-Id: 1514651 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4Ghh7h13w9z9s1l for ; Sat, 7 Aug 2021 22:13:04 +1000 (AEST) Received: from localhost ([::1]:45222 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mCLCH-0002DH-Rb for incoming@patchwork.ozlabs.org; Sat, 07 Aug 2021 08:13:01 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:48460) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mCLBc-0002B3-Uh for qemu-devel@nongnu.org; Sat, 07 Aug 2021 08:12:20 -0400 Received: from mailout06.t-online.de ([194.25.134.19]:39078) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mCLBa-0003hX-PV for qemu-devel@nongnu.org; Sat, 07 Aug 2021 08:12:20 -0400 Received: from fwd10.aul.t-online.de (fwd10.aul.t-online.de [172.20.26.152]) by mailout06.t-online.de (Postfix) with SMTP id 87A3D1AF78; Sat, 7 Aug 2021 14:12:10 +0200 (CEST) Received: from linpower.localnet (bLtg++ZV8hRDPGUKNVe5Ge3pHiAKZD1f2k08Fgt7kkKTfDMxYIF+9Z5DxyetlFwgSR@[79.208.26.7]) by fwd10.t-online.de with (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384 encrypted) esmtp id 1mCLBN-0adu4W0; Sat, 7 Aug 2021 14:12:05 +0200 Received: by linpower.localnet (Postfix, from userid 1000) id 2C734200617; Sat, 7 Aug 2021 14:12:02 +0200 (CEST) From: =?utf-8?q?Volker_R=C3=BCmelin?= To: Gerd Hoffmann Subject: [PATCH 2/3] ps2: use a separate keyboard command reply queue Date: Sat, 7 Aug 2021 14:12:01 +0200 Message-Id: <20210807121202.6294-2-vr_qemu@t-online.de> X-Mailer: git-send-email 2.26.2 In-Reply-To: <4d1c8467-d976-2c0f-ba54-c767df7b8fe7@t-online.de> References: <4d1c8467-d976-2c0f-ba54-c767df7b8fe7@t-online.de> MIME-Version: 1.0 X-ID: bLtg++ZV8hRDPGUKNVe5Ge3pHiAKZD1f2k08Fgt7kkKTfDMxYIF+9Z5DxyetlFwgSR X-TOI-EXPURGATEID: 150726::1628338325-00000BB9-45238EC9/0/0 CLEAN NORMAL X-TOI-MSGID: 7a3fdae0-9753-47e2-bff6-642d4be9c264 Received-SPF: none client-ip=194.25.134.19; envelope-from=volker.ruemelin@t-online.de; helo=mailout06.t-online.de X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= , qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" A PS/2 keyboard has a separate command reply queue that is independant of the key queue. This prevents that command replies and keyboard input mix. Keyboard command replies take precedence over queued keystrokes. A new keyboard command removes any remaining command replies from the command reply queue. Implement a separate keyboard command reply queue and clear the command reply queue before command execution. This brings the PS/2 keyboard emulation much closer to a real PS/2 keyboard. Resolves: https://gitlab.com/qemu-project/qemu/-/issues/501 Resolves: https://gitlab.com/qemu-project/qemu/-/issues/502 Signed-off-by: Volker Rümelin --- hw/input/ps2.c | 115 ++++++++++++++++++++++++++++++++++++------------- 1 file changed, 84 insertions(+), 31 deletions(-) diff --git a/hw/input/ps2.c b/hw/input/ps2.c index 23e7befee5..8c06fd7fb4 100644 --- a/hw/input/ps2.c +++ b/hw/input/ps2.c @@ -91,7 +91,7 @@ typedef struct { uint8_t data[PS2_BUFFER_SIZE]; - int rptr, wptr, count; + int rptr, wptr, cwptr, count; } PS2Queue; struct PS2State { @@ -186,6 +186,7 @@ static void ps2_reset_queue(PS2State *s) q->rptr = 0; q->wptr = 0; + q->cwptr = -1; q->count = 0; } @@ -198,7 +199,7 @@ void ps2_queue_noirq(PS2State *s, int b) { PS2Queue *q = &s->queue; - if (q->count == PS2_QUEUE_SIZE) { + if (q->count >= PS2_QUEUE_SIZE) { return; } @@ -260,6 +261,63 @@ void ps2_queue_4(PS2State *s, int b1, int b2, int b3, int b4) ps2_raise_irq(s); } +static void ps2_cqueue_data(PS2Queue *q, int b) +{ + q->data[q->cwptr] = b; + if (++q->cwptr >= PS2_BUFFER_SIZE) { + q->cwptr = 0; + } + q->count++; +} + +static void ps2_cqueue_1(PS2State *s, int b1) +{ + PS2Queue *q = &s->queue; + + q->rptr = (q->rptr - 1) & (PS2_BUFFER_SIZE - 1); + q->cwptr = q->rptr; + ps2_cqueue_data(q, b1); + ps2_raise_irq(s); +} + +static void ps2_cqueue_2(PS2State *s, int b1, int b2) +{ + PS2Queue *q = &s->queue; + + q->rptr = (q->rptr - 2) & (PS2_BUFFER_SIZE - 1); + q->cwptr = q->rptr; + ps2_cqueue_data(q, b1); + ps2_cqueue_data(q, b2); + ps2_raise_irq(s); +} + +static void ps2_cqueue_3(PS2State *s, int b1, int b2, int b3) +{ + PS2Queue *q = &s->queue; + + q->rptr = (q->rptr - 3) & (PS2_BUFFER_SIZE - 1); + q->cwptr = q->rptr; + ps2_cqueue_data(q, b1); + ps2_cqueue_data(q, b2); + ps2_cqueue_data(q, b3); + ps2_raise_irq(s); +} + +static void ps2_cqueue_reset(PS2State *s) +{ + PS2Queue *q = &s->queue; + int ccount; + + if (q->cwptr == -1) { + return; + } + + ccount = (q->cwptr - q->rptr) & (PS2_BUFFER_SIZE - 1); + q->count -= ccount; + q->rptr = q->cwptr; + q->cwptr = -1; +} + /* keycode is the untranslated scancode in the current scancode set. */ static void ps2_put_keycode(void *opaque, int keycode) { @@ -523,6 +581,10 @@ uint32_t ps2_read_data(PS2State *s) q->rptr = 0; } q->count--; + if (q->rptr == q->cwptr) { + /* command reply queue is empty */ + q->cwptr = -1; + } /* reading deasserts IRQ */ s->update_irq(s->update_arg, 0); /* reassert IRQs if data left */ @@ -554,92 +616,83 @@ void ps2_write_keyboard(void *opaque, int val) PS2KbdState *s = (PS2KbdState *)opaque; trace_ps2_write_keyboard(opaque, val); + ps2_cqueue_reset(&s->common); switch(s->common.write_cmd) { default: case -1: switch(val) { case 0x00: - ps2_queue(&s->common, KBD_REPLY_ACK); + ps2_cqueue_1(&s->common, KBD_REPLY_ACK); break; case 0x05: - ps2_queue(&s->common, KBD_REPLY_RESEND); + ps2_cqueue_1(&s->common, KBD_REPLY_RESEND); break; case KBD_CMD_GET_ID: /* We emulate a MF2 AT keyboard here */ - if (s->translate) - ps2_queue_3(&s->common, - KBD_REPLY_ACK, - KBD_REPLY_ID, - 0x41); - else - ps2_queue_3(&s->common, - KBD_REPLY_ACK, - KBD_REPLY_ID, - 0x83); + ps2_cqueue_3(&s->common, KBD_REPLY_ACK, KBD_REPLY_ID, + s->translate ? 0x41 : 0x83); break; case KBD_CMD_ECHO: - ps2_queue(&s->common, KBD_CMD_ECHO); + ps2_cqueue_1(&s->common, KBD_CMD_ECHO); break; case KBD_CMD_ENABLE: s->scan_enabled = 1; - ps2_queue(&s->common, KBD_REPLY_ACK); + ps2_cqueue_1(&s->common, KBD_REPLY_ACK); break; case KBD_CMD_SCANCODE: case KBD_CMD_SET_LEDS: case KBD_CMD_SET_RATE: case KBD_CMD_SET_MAKE_BREAK: s->common.write_cmd = val; - ps2_queue(&s->common, KBD_REPLY_ACK); + ps2_cqueue_1(&s->common, KBD_REPLY_ACK); break; case KBD_CMD_RESET_DISABLE: ps2_reset_keyboard(s); s->scan_enabled = 0; - ps2_queue(&s->common, KBD_REPLY_ACK); + ps2_cqueue_1(&s->common, KBD_REPLY_ACK); break; case KBD_CMD_RESET_ENABLE: ps2_reset_keyboard(s); s->scan_enabled = 1; - ps2_queue(&s->common, KBD_REPLY_ACK); + ps2_cqueue_1(&s->common, KBD_REPLY_ACK); break; case KBD_CMD_RESET: ps2_reset_keyboard(s); - ps2_queue_2(&s->common, + ps2_cqueue_2(&s->common, KBD_REPLY_ACK, KBD_REPLY_POR); break; case KBD_CMD_SET_TYPEMATIC: - ps2_queue(&s->common, KBD_REPLY_ACK); + ps2_cqueue_1(&s->common, KBD_REPLY_ACK); break; default: - ps2_queue(&s->common, KBD_REPLY_RESEND); + ps2_cqueue_1(&s->common, KBD_REPLY_RESEND); break; } break; case KBD_CMD_SET_MAKE_BREAK: - ps2_queue(&s->common, KBD_REPLY_ACK); + ps2_cqueue_1(&s->common, KBD_REPLY_ACK); s->common.write_cmd = -1; break; case KBD_CMD_SCANCODE: if (val == 0) { - if (s->common.queue.count <= PS2_QUEUE_SIZE - 2) { - ps2_queue(&s->common, KBD_REPLY_ACK); - ps2_put_keycode(s, s->scancode_set); - } + ps2_cqueue_2(&s->common, KBD_REPLY_ACK, s->translate ? + translate_table[s->scancode_set] : s->scancode_set); } else if (val >= 1 && val <= 3) { s->scancode_set = val; - ps2_queue(&s->common, KBD_REPLY_ACK); + ps2_cqueue_1(&s->common, KBD_REPLY_ACK); } else { - ps2_queue(&s->common, KBD_REPLY_RESEND); + ps2_cqueue_1(&s->common, KBD_REPLY_RESEND); } s->common.write_cmd = -1; break; case KBD_CMD_SET_LEDS: ps2_set_ledstate(s, val); - ps2_queue(&s->common, KBD_REPLY_ACK); + ps2_cqueue_1(&s->common, KBD_REPLY_ACK); s->common.write_cmd = -1; break; case KBD_CMD_SET_RATE: - ps2_queue(&s->common, KBD_REPLY_ACK); + ps2_cqueue_1(&s->common, KBD_REPLY_ACK); s->common.write_cmd = -1; break; } From patchwork Sat Aug 7 12:12:02 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Volker_R=C3=BCmelin?= X-Patchwork-Id: 1514650 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4Ghh7W16XXz9sRK for ; Sat, 7 Aug 2021 22:12:55 +1000 (AEST) Received: from localhost ([::1]:44972 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mCLC8-000238-Q4 for incoming@patchwork.ozlabs.org; Sat, 07 Aug 2021 08:12:52 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:48438) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mCLBW-000230-3Y for qemu-devel@nongnu.org; Sat, 07 Aug 2021 08:12:14 -0400 Received: from mailout02.t-online.de ([194.25.134.17]:53086) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mCLBU-0003cI-20 for qemu-devel@nongnu.org; Sat, 07 Aug 2021 08:12:13 -0400 Received: from fwd23.aul.t-online.de (fwd23.aul.t-online.de [172.20.26.128]) by mailout02.t-online.de (Postfix) with SMTP id C74DB6C23; Sat, 7 Aug 2021 14:12:08 +0200 (CEST) Received: from linpower.localnet (ZB79bcZdrhj8pwH1sDwWcj9Gpe+MYp1yEK6eh4iw8ntgLMm4O-tWKBF6uHaIjTfwfk@[79.208.26.7]) by fwd23.t-online.de with (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384 encrypted) esmtp id 1mCLBP-0RXMfI0; Sat, 7 Aug 2021 14:12:07 +0200 Received: by linpower.localnet (Postfix, from userid 1000) id 2E16A20061B; Sat, 7 Aug 2021 14:12:02 +0200 (CEST) From: =?utf-8?q?Volker_R=C3=BCmelin?= To: Gerd Hoffmann Subject: [PATCH 3/3] ps2: migration support for command reply queue Date: Sat, 7 Aug 2021 14:12:02 +0200 Message-Id: <20210807121202.6294-3-vr_qemu@t-online.de> X-Mailer: git-send-email 2.26.2 In-Reply-To: <4d1c8467-d976-2c0f-ba54-c767df7b8fe7@t-online.de> References: <4d1c8467-d976-2c0f-ba54-c767df7b8fe7@t-online.de> MIME-Version: 1.0 X-ID: ZB79bcZdrhj8pwH1sDwWcj9Gpe+MYp1yEK6eh4iw8ntgLMm4O-tWKBF6uHaIjTfwfk X-TOI-EXPURGATEID: 150726::1628338327-00009563-8EFBA68A/0/0 CLEAN NORMAL X-TOI-MSGID: 252e0015-42f8-4fbb-8df2-c8c3ded7677f Received-SPF: none client-ip=194.25.134.17; envelope-from=volker.ruemelin@t-online.de; helo=mailout02.t-online.de X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= , qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Add migration support for the PS/2 keyboard command reply queue. Signed-off-by: Volker Rümelin --- hw/input/ps2.c | 40 ++++++++++++++++++++++++++++++++++------ 1 file changed, 34 insertions(+), 6 deletions(-) diff --git a/hw/input/ps2.c b/hw/input/ps2.c index 8c06fd7fb4..9376a8f4ce 100644 --- a/hw/input/ps2.c +++ b/hw/input/ps2.c @@ -80,6 +80,7 @@ */ #define PS2_BUFFER_SIZE 256 #define PS2_QUEUE_SIZE 16 /* Queue size required by PS/2 protocol */ +#define PS2_QUEUE_HEADROOM 8 /* Queue size for keyboard command replies */ /* Bits for 'modifiers' field in PS2KbdState */ #define MOD_CTRL_L (1 << 0) @@ -985,17 +986,27 @@ static void ps2_common_reset(PS2State *s) static void ps2_common_post_load(PS2State *s) { PS2Queue *q = &s->queue; + int ccount = 0; - /* set the useful data buffer queue size <= PS2_QUEUE_SIZE */ - if (q->count < 0) { - q->count = 0; - } else if (q->count > PS2_QUEUE_SIZE) { - q->count = PS2_QUEUE_SIZE; + /* limit the number of queued command replies to PS2_QUEUE_HEADROOM */ + if (q->cwptr != -1) { + ccount = (q->cwptr - q->rptr) & (PS2_BUFFER_SIZE - 1); + if (ccount > PS2_QUEUE_HEADROOM) { + ccount = PS2_QUEUE_HEADROOM; + } + } + + /* limit the scancode queue size to PS2_QUEUE_SIZE */ + if (q->count < ccount) { + q->count = ccount; + } else if (q->count > ccount + PS2_QUEUE_SIZE) { + q->count = ccount + PS2_QUEUE_SIZE; } - /* sanitize rptr and recalculate wptr */ + /* sanitize rptr and recalculate wptr and cwptr */ q->rptr = q->rptr & (PS2_BUFFER_SIZE - 1); q->wptr = (q->rptr + q->count) & (PS2_BUFFER_SIZE - 1); + q->cwptr = ccount ? (q->rptr + ccount) & (PS2_BUFFER_SIZE - 1) : -1; } static void ps2_kbd_reset(void *opaque) @@ -1086,6 +1097,22 @@ static const VMStateDescription vmstate_ps2_keyboard_need_high_bit = { } }; +static bool ps2_keyboard_cqueue_needed(void *opaque) +{ + PS2KbdState *s = opaque; + + return s->common.queue.cwptr != -1; /* the queue is mostly empty */ +} + +static const VMStateDescription vmstate_ps2_keyboard_cqueue = { + .name = "ps2kbd/command_reply_queue", + .needed = ps2_keyboard_cqueue_needed, + .fields = (VMStateField[]) { + VMSTATE_INT32(common.queue.cwptr, PS2KbdState), + VMSTATE_END_OF_LIST() + } +}; + static int ps2_kbd_post_load(void* opaque, int version_id) { PS2KbdState *s = (PS2KbdState*)opaque; @@ -1114,6 +1141,7 @@ static const VMStateDescription vmstate_ps2_keyboard = { .subsections = (const VMStateDescription*[]) { &vmstate_ps2_keyboard_ledstate, &vmstate_ps2_keyboard_need_high_bit, + &vmstate_ps2_keyboard_cqueue, NULL } };