Skip to content

Commit 4e9bddc

Browse files
Volker Rümelinkraxel
authored andcommitted
ps2: migration support for command reply queue
Add migration support for the PS/2 keyboard command reply queue. Signed-off-by: Volker Rümelin <[email protected]> Message-Id: <[email protected]> Signed-off-by: Gerd Hoffmann <[email protected]>
1 parent 9e24b2d commit 4e9bddc

File tree

1 file changed

+34
-6
lines changed

1 file changed

+34
-6
lines changed

hw/input/ps2.c

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@
8080
*/
8181
#define PS2_BUFFER_SIZE 256
8282
#define PS2_QUEUE_SIZE 16 /* Queue size required by PS/2 protocol */
83+
#define PS2_QUEUE_HEADROOM 8 /* Queue size for keyboard command replies */
8384

8485
/* Bits for 'modifiers' field in PS2KbdState */
8586
#define MOD_CTRL_L (1 << 0)
@@ -985,17 +986,27 @@ static void ps2_common_reset(PS2State *s)
985986
static void ps2_common_post_load(PS2State *s)
986987
{
987988
PS2Queue *q = &s->queue;
989+
int ccount = 0;
988990

989-
/* set the useful data buffer queue size <= PS2_QUEUE_SIZE */
990-
if (q->count < 0) {
991-
q->count = 0;
992-
} else if (q->count > PS2_QUEUE_SIZE) {
993-
q->count = PS2_QUEUE_SIZE;
991+
/* limit the number of queued command replies to PS2_QUEUE_HEADROOM */
992+
if (q->cwptr != -1) {
993+
ccount = (q->cwptr - q->rptr) & (PS2_BUFFER_SIZE - 1);
994+
if (ccount > PS2_QUEUE_HEADROOM) {
995+
ccount = PS2_QUEUE_HEADROOM;
996+
}
997+
}
998+
999+
/* limit the scancode queue size to PS2_QUEUE_SIZE */
1000+
if (q->count < ccount) {
1001+
q->count = ccount;
1002+
} else if (q->count > ccount + PS2_QUEUE_SIZE) {
1003+
q->count = ccount + PS2_QUEUE_SIZE;
9941004
}
9951005

996-
/* sanitize rptr and recalculate wptr */
1006+
/* sanitize rptr and recalculate wptr and cwptr */
9971007
q->rptr = q->rptr & (PS2_BUFFER_SIZE - 1);
9981008
q->wptr = (q->rptr + q->count) & (PS2_BUFFER_SIZE - 1);
1009+
q->cwptr = ccount ? (q->rptr + ccount) & (PS2_BUFFER_SIZE - 1) : -1;
9991010
}
10001011

10011012
static void ps2_kbd_reset(void *opaque)
@@ -1086,6 +1097,22 @@ static const VMStateDescription vmstate_ps2_keyboard_need_high_bit = {
10861097
}
10871098
};
10881099

1100+
static bool ps2_keyboard_cqueue_needed(void *opaque)
1101+
{
1102+
PS2KbdState *s = opaque;
1103+
1104+
return s->common.queue.cwptr != -1; /* the queue is mostly empty */
1105+
}
1106+
1107+
static const VMStateDescription vmstate_ps2_keyboard_cqueue = {
1108+
.name = "ps2kbd/command_reply_queue",
1109+
.needed = ps2_keyboard_cqueue_needed,
1110+
.fields = (VMStateField[]) {
1111+
VMSTATE_INT32(common.queue.cwptr, PS2KbdState),
1112+
VMSTATE_END_OF_LIST()
1113+
}
1114+
};
1115+
10891116
static int ps2_kbd_post_load(void* opaque, int version_id)
10901117
{
10911118
PS2KbdState *s = (PS2KbdState*)opaque;
@@ -1114,6 +1141,7 @@ static const VMStateDescription vmstate_ps2_keyboard = {
11141141
.subsections = (const VMStateDescription*[]) {
11151142
&vmstate_ps2_keyboard_ledstate,
11161143
&vmstate_ps2_keyboard_need_high_bit,
1144+
&vmstate_ps2_keyboard_cqueue,
11171145
NULL
11181146
}
11191147
};

0 commit comments

Comments
 (0)