From nobody Sun May 19 09:08:45 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1628602531617934.1594679252383; Tue, 10 Aug 2021 06:35:31 -0700 (PDT) Received: from localhost ([::1]:59058 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mDRuk-0002re-Kb for importer@patchew.org; Tue, 10 Aug 2021 09:35:30 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:41282) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mDRtz-00029D-EI for qemu-devel@nongnu.org; Tue, 10 Aug 2021 09:34:43 -0400 Received: from mailout04.t-online.de ([194.25.134.18]:52384) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mDRtx-0008Rj-Lh for qemu-devel@nongnu.org; Tue, 10 Aug 2021 09:34:43 -0400 Received: from fwd30.aul.t-online.de (fwd30.aul.t-online.de [172.20.26.135]) by mailout04.t-online.de (Postfix) with SMTP id 7D586591; Tue, 10 Aug 2021 15:33:04 +0200 (CEST) Received: from linpower.localnet (XRxAX-ZBYhbCwxuH-MzmYAt1bFAxFC9mFcY0iWuLPOdLEdr9uBR5Dws4KGZasr+QVd@[79.208.26.7]) by fwd30.t-online.de with (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384 encrypted) esmtp id 1mDRsI-2nqCyO0; Tue, 10 Aug 2021 15:32:58 +0200 Received: by linpower.localnet (Postfix, from userid 1000) id 07CAE200624; Tue, 10 Aug 2021 15:32:58 +0200 (CEST) From: =?UTF-8?q?Volker=20R=C3=BCmelin?= To: Gerd Hoffmann Subject: [PATCH v2 1/3] ps2: use the whole ps2 buffer but keep queue size Date: Tue, 10 Aug 2021 15:32:56 +0200 Message-Id: <20210810133258.8231-1-vr_qemu@t-online.de> X-Mailer: git-send-email 2.26.2 In-Reply-To: References: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-ID: XRxAX-ZBYhbCwxuH-MzmYAt1bFAxFC9mFcY0iWuLPOdLEdr9uBR5Dws4KGZasr+QVd X-TOI-EXPURGATEID: 150726::1628602378-0000D63F-DC50462A/0/0 CLEAN NORMAL X-TOI-MSGID: c2e20b6f-f9c0-4451-816d-bdb53509e7b3 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: none client-ip=194.25.134.18; envelope-from=volker.ruemelin@t-online.de; helo=mailout04.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=20Mathieu-Daud=C3=A9?= , qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZM-MESSAGEID: 1628602533773100001 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=C3=BCmelin --- 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 =20 -#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 */ =20 /* Bits for 'modifiers' field in PS2KbdState */ #define MOD_CTRL_L (1 << 0) @@ -85,9 +90,7 @@ #define MOD_ALT_R (1 << 5) =20 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; =20 @@ -200,8 +203,9 @@ void ps2_queue_noirq(PS2State *s, int b) } =20 q->data[q->wptr] =3D b; - if (++q->wptr =3D=3D PS2_QUEUE_SIZE) + if (++q->wptr =3D=3D PS2_BUFFER_SIZE) { q->wptr =3D 0; + } q->count++; } =20 @@ -509,13 +513,15 @@ uint32_t ps2_read_data(PS2State *s) (needed for EMM386) */ /* XXX: need a timer to do things correctly */ index =3D q->rptr - 1; - if (index < 0) - index =3D PS2_QUEUE_SIZE - 1; + if (index < 0) { + index =3D PS2_BUFFER_SIZE - 1; + } val =3D q->data[index]; } else { val =3D q->data[q->rptr]; - if (++q->rptr =3D=3D PS2_QUEUE_SIZE) + if (++q->rptr =3D=3D PS2_BUFFER_SIZE) { q->rptr =3D 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 =3D &s->queue; - uint8_t i, size; - uint8_t tmp_data[PS2_QUEUE_SIZE]; =20 - /* set the useful data buffer queue size, < PS2_QUEUE_SIZE */ - size =3D q->count; + /* set the useful data buffer queue size <=3D PS2_QUEUE_SIZE */ if (q->count < 0) { - size =3D 0; + q->count =3D 0; } else if (q->count > PS2_QUEUE_SIZE) { - size =3D PS2_QUEUE_SIZE; - } - - /* move the queue elements to the start of data array */ - for (i =3D 0; i < size; i++) { - if (q->rptr < 0 || q->rptr >=3D sizeof(q->data)) { - q->rptr =3D 0; - } - tmp_data[i] =3D q->data[q->rptr++]; + q->count =3D PS2_QUEUE_SIZE; } - memcpy(q->data, tmp_data, size); =20 - /* reset rptr/wptr/count */ - q->rptr =3D 0; - q->wptr =3D (size =3D=3D PS2_QUEUE_SIZE) ? 0 : size; - q->count =3D size; + /* sanitize rptr and recalculate wptr */ + q->rptr =3D q->rptr & (PS2_BUFFER_SIZE - 1); + q->wptr =3D (q->rptr + q->count) & (PS2_BUFFER_SIZE - 1); } =20 static void ps2_kbd_reset(void *opaque) @@ -1053,22 +1046,11 @@ static int ps2_kbd_post_load(void* opaque, int vers= ion_id) return 0; } =20 -static int ps2_kbd_pre_save(void *opaque) -{ - PS2KbdState *s =3D (PS2KbdState *)opaque; - PS2State *ps2 =3D &s->common; - - ps2_common_post_load(ps2); - - return 0; -} - static const VMStateDescription vmstate_ps2_keyboard =3D { .name =3D "ps2kbd", .version_id =3D 3, .minimum_version_id =3D 2, .post_load =3D ps2_kbd_post_load, - .pre_save =3D ps2_kbd_pre_save, .fields =3D (VMStateField[]) { VMSTATE_STRUCT(common, PS2KbdState, 0, vmstate_ps2_common, PS2Stat= e), VMSTATE_INT32(scan_enabled, PS2KbdState), @@ -1093,22 +1075,11 @@ static int ps2_mouse_post_load(void *opaque, int ve= rsion_id) return 0; } =20 -static int ps2_mouse_pre_save(void *opaque) -{ - PS2MouseState *s =3D (PS2MouseState *)opaque; - PS2State *ps2 =3D &s->common; - - ps2_common_post_load(ps2); - - return 0; -} - static const VMStateDescription vmstate_ps2_mouse =3D { .name =3D "ps2mouse", .version_id =3D 2, .minimum_version_id =3D 2, .post_load =3D ps2_mouse_post_load, - .pre_save =3D ps2_mouse_pre_save, .fields =3D (VMStateField[]) { VMSTATE_STRUCT(common, PS2MouseState, 0, vmstate_ps2_common, PS2St= ate), VMSTATE_UINT8(mouse_status, PS2MouseState), --=20 2.26.2 From nobody Sun May 19 09:08:45 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1628602583174158.26394949678718; Tue, 10 Aug 2021 06:36:23 -0700 (PDT) Received: from localhost ([::1]:33732 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mDRvZ-0004rb-Kj for importer@patchew.org; Tue, 10 Aug 2021 09:36:21 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:41580) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mDRuq-0003OO-Bo for qemu-devel@nongnu.org; Tue, 10 Aug 2021 09:35:36 -0400 Received: from mailout12.t-online.de ([194.25.134.22]:44128) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mDRuo-0000RP-9g for qemu-devel@nongnu.org; Tue, 10 Aug 2021 09:35:36 -0400 Received: from fwd14.aul.t-online.de (fwd14.aul.t-online.de [172.20.26.242]) by mailout12.t-online.de (Postfix) with SMTP id 22FF12133D; Tue, 10 Aug 2021 15:33:03 +0200 (CEST) Received: from linpower.localnet (r919W6ZJYh5QSVe6O3vCCsbmCRk7kzln-7SWM-yA6EVbnReNC0MNCds63PP45esQy9@[79.208.26.7]) by fwd14.t-online.de with (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384 encrypted) esmtp id 1mDRsL-16ZE6i0; Tue, 10 Aug 2021 15:33:01 +0200 Received: by linpower.localnet (Postfix, from userid 1000) id 09C2020062F; Tue, 10 Aug 2021 15:32:58 +0200 (CEST) From: =?UTF-8?q?Volker=20R=C3=BCmelin?= To: Gerd Hoffmann Subject: [PATCH v2 2/3] ps2: use a separate keyboard command reply queue Date: Tue, 10 Aug 2021 15:32:57 +0200 Message-Id: <20210810133258.8231-2-vr_qemu@t-online.de> X-Mailer: git-send-email 2.26.2 In-Reply-To: References: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-ID: r919W6ZJYh5QSVe6O3vCCsbmCRk7kzln-7SWM-yA6EVbnReNC0MNCds63PP45esQy9 X-TOI-EXPURGATEID: 150726::1628602381-00000BC0-D6DC3461/0/0 CLEAN NORMAL X-TOI-MSGID: 1373138f-7af0-48bf-ab91-1c0d0e9deb5d Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: none client-ip=194.25.134.22; envelope-from=volker.ruemelin@t-online.de; helo=mailout12.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=20Mathieu-Daud=C3=A9?= , qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZM-MESSAGEID: 1628602584628100001 A PS/2 keyboard has a separate command reply queue that is independent 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. The command reply queue is located in a few free bytes directly in front of the scancode queue. Because the scancode queue has a maximum length of 16 bytes there are 240 bytes available for the command reply queue. At the moment only a maximum of 3 bytes are required. For compatibility reasons rptr, wptr and count kept their function. rptr is the start, wptr is the end and count is the length of the entire keyboard queue. The new variable cwptr is the end of the command reply queue or -1 if the queue is empty. To write to the command reply queue, rptr is moved backward by the number of required bytes and the command replies are written to the buffer starting at the new rptr position. After writing, cwptr is at the old rptr position. Copying cwptr to rptr clears the command reply queue. The command reply queue can't overflow because each new keyboard command clears the command reply queue. Resolves: https://gitlab.com/qemu-project/qemu/-/issues/501 Resolves: https://gitlab.com/qemu-project/qemu/-/issues/502 Signed-off-by: Volker R=C3=BCmelin --- 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 @@ =20 typedef struct { uint8_t data[PS2_BUFFER_SIZE]; - int rptr, wptr, count; + int rptr, wptr, cwptr, count; } PS2Queue; =20 struct PS2State { @@ -186,6 +186,7 @@ static void ps2_reset_queue(PS2State *s) =20 q->rptr =3D 0; q->wptr =3D 0; + q->cwptr =3D -1; q->count =3D 0; } =20 @@ -198,7 +199,7 @@ void ps2_queue_noirq(PS2State *s, int b) { PS2Queue *q =3D &s->queue; =20 - if (q->count =3D=3D PS2_QUEUE_SIZE) { + if (q->count >=3D PS2_QUEUE_SIZE) { return; } =20 @@ -260,6 +261,63 @@ void ps2_queue_4(PS2State *s, int b1, int b2, int b3, = int b4) ps2_raise_irq(s); } =20 +static void ps2_cqueue_data(PS2Queue *q, int b) +{ + q->data[q->cwptr] =3D b; + if (++q->cwptr >=3D PS2_BUFFER_SIZE) { + q->cwptr =3D 0; + } + q->count++; +} + +static void ps2_cqueue_1(PS2State *s, int b1) +{ + PS2Queue *q =3D &s->queue; + + q->rptr =3D (q->rptr - 1) & (PS2_BUFFER_SIZE - 1); + q->cwptr =3D q->rptr; + ps2_cqueue_data(q, b1); + ps2_raise_irq(s); +} + +static void ps2_cqueue_2(PS2State *s, int b1, int b2) +{ + PS2Queue *q =3D &s->queue; + + q->rptr =3D (q->rptr - 2) & (PS2_BUFFER_SIZE - 1); + q->cwptr =3D 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 =3D &s->queue; + + q->rptr =3D (q->rptr - 3) & (PS2_BUFFER_SIZE - 1); + q->cwptr =3D 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 =3D &s->queue; + int ccount; + + if (q->cwptr =3D=3D -1) { + return; + } + + ccount =3D (q->cwptr - q->rptr) & (PS2_BUFFER_SIZE - 1); + q->count -=3D ccount; + q->rptr =3D q->cwptr; + q->cwptr =3D -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 =3D 0; } q->count--; + if (q->rptr =3D=3D q->cwptr) { + /* command reply queue is empty */ + q->cwptr =3D -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 =3D (PS2KbdState *)opaque; =20 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 =3D 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 =3D 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 =3D 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 =3D 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 =3D -1; break; case KBD_CMD_SCANCODE: if (val =3D=3D 0) { - if (s->common.queue.count <=3D 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 >=3D 1 && val <=3D 3) { s->scancode_set =3D 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 =3D -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 =3D -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 =3D -1; break; } --=20 2.26.2 From nobody Sun May 19 09:08:45 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1628602460024491.39854670083787; Tue, 10 Aug 2021 06:34:20 -0700 (PDT) Received: from localhost ([::1]:56904 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mDRtb-0001NX-0k for importer@patchew.org; Tue, 10 Aug 2021 09:34:19 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:40952) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mDRso-0000OZ-Ah for qemu-devel@nongnu.org; Tue, 10 Aug 2021 09:33:30 -0400 Received: from mailout05.t-online.de ([194.25.134.82]:38512) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mDRsm-0007pF-Gs for qemu-devel@nongnu.org; Tue, 10 Aug 2021 09:33:30 -0400 Received: from fwd11.aul.t-online.de (fwd11.aul.t-online.de [172.20.27.152]) by mailout05.t-online.de (Postfix) with SMTP id 44A07235CE; Tue, 10 Aug 2021 15:33:05 +0200 (CEST) Received: from linpower.localnet (SrigKqZerh0S-ndaE2hL8a7HYdD0oN533DmzsLzgAlFbsVWGEk0j0EH2Srt-Vwwg00@[79.208.26.7]) by fwd11.t-online.de with (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384 encrypted) esmtp id 1mDRsN-1cKNKi0; Tue, 10 Aug 2021 15:33:03 +0200 Received: by linpower.localnet (Postfix, from userid 1000) id 0B0CD21201E; Tue, 10 Aug 2021 15:32:58 +0200 (CEST) From: =?UTF-8?q?Volker=20R=C3=BCmelin?= To: Gerd Hoffmann Subject: [PATCH v2 3/3] ps2: migration support for command reply queue Date: Tue, 10 Aug 2021 15:32:58 +0200 Message-Id: <20210810133258.8231-3-vr_qemu@t-online.de> X-Mailer: git-send-email 2.26.2 In-Reply-To: References: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-ID: SrigKqZerh0S-ndaE2hL8a7HYdD0oN533DmzsLzgAlFbsVWGEk0j0EH2Srt-Vwwg00 X-TOI-EXPURGATEID: 150726::1628602383-00007FA5-42F16AEF/0/0 CLEAN NORMAL X-TOI-MSGID: 2f005c76-e68d-4fe6-8575-8c63c1ff816f Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: none client-ip=194.25.134.82; envelope-from=volker.ruemelin@t-online.de; helo=mailout05.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=20Mathieu-Daud=C3=A9?= , qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZM-MESSAGEID: 1628602460672100001 Add migration support for the PS/2 keyboard command reply queue. Signed-off-by: Volker R=C3=BCmelin --- 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= */ =20 /* 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 =3D &s->queue; + int ccount =3D 0; =20 - /* set the useful data buffer queue size <=3D PS2_QUEUE_SIZE */ - if (q->count < 0) { - q->count =3D 0; - } else if (q->count > PS2_QUEUE_SIZE) { - q->count =3D PS2_QUEUE_SIZE; + /* limit the number of queued command replies to PS2_QUEUE_HEADROOM */ + if (q->cwptr !=3D -1) { + ccount =3D (q->cwptr - q->rptr) & (PS2_BUFFER_SIZE - 1); + if (ccount > PS2_QUEUE_HEADROOM) { + ccount =3D PS2_QUEUE_HEADROOM; + } + } + + /* limit the scancode queue size to PS2_QUEUE_SIZE */ + if (q->count < ccount) { + q->count =3D ccount; + } else if (q->count > ccount + PS2_QUEUE_SIZE) { + q->count =3D ccount + PS2_QUEUE_SIZE; } =20 - /* sanitize rptr and recalculate wptr */ + /* sanitize rptr and recalculate wptr and cwptr */ q->rptr =3D q->rptr & (PS2_BUFFER_SIZE - 1); q->wptr =3D (q->rptr + q->count) & (PS2_BUFFER_SIZE - 1); + q->cwptr =3D ccount ? (q->rptr + ccount) & (PS2_BUFFER_SIZE - 1) : -1; } =20 static void ps2_kbd_reset(void *opaque) @@ -1086,6 +1097,22 @@ static const VMStateDescription vmstate_ps2_keyboard= _need_high_bit =3D { } }; =20 +static bool ps2_keyboard_cqueue_needed(void *opaque) +{ + PS2KbdState *s =3D opaque; + + return s->common.queue.cwptr !=3D -1; /* the queue is mostly empty */ +} + +static const VMStateDescription vmstate_ps2_keyboard_cqueue =3D { + .name =3D "ps2kbd/command_reply_queue", + .needed =3D ps2_keyboard_cqueue_needed, + .fields =3D (VMStateField[]) { + VMSTATE_INT32(common.queue.cwptr, PS2KbdState), + VMSTATE_END_OF_LIST() + } +}; + static int ps2_kbd_post_load(void* opaque, int version_id) { PS2KbdState *s =3D (PS2KbdState*)opaque; @@ -1114,6 +1141,7 @@ static const VMStateDescription vmstate_ps2_keyboard = =3D { .subsections =3D (const VMStateDescription*[]) { &vmstate_ps2_keyboard_ledstate, &vmstate_ps2_keyboard_need_high_bit, + &vmstate_ps2_keyboard_cqueue, NULL } }; --=20 2.26.2