master
c 1,353 lines 39.9 KB
Raw
1 /*
2 * QEMU PS/2 keyboard/mouse emulation
3 *
4 * Copyright (c) 2003 Fabrice Bellard
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
24
25 #include "qemu/osdep.h"
26 #include "qemu/log.h"
27 #include "hw/core/irq.h"
28 #include "hw/core/sysbus.h"
29 #include "hw/input/ps2.h"
30 #include "migration/vmstate.h"
31 #include "standard-headers/linux/input-event-codes.h"
32 #include "ui/console.h"
33 #include "ui/input.h"
34 #include "system/reset.h"
35 #include "system/runstate.h"
36 #include "qapi/error.h"
37
38 #include "trace.h"
39
40 /* Keyboard Commands */
41 #define KBD_CMD_SET_LEDS 0xED /* Set keyboard leds */
42 #define KBD_CMD_ECHO 0xEE
43 #define KBD_CMD_SCANCODE 0xF0 /* Get/set scancode set */
44 #define KBD_CMD_GET_ID 0xF2 /* get keyboard ID */
45 #define KBD_CMD_SET_RATE 0xF3 /* Set typematic rate */
46 #define KBD_CMD_ENABLE 0xF4 /* Enable scanning */
47 #define KBD_CMD_RESET_DISABLE 0xF5 /* reset and disable scanning */
48 #define KBD_CMD_RESET_ENABLE 0xF6 /* reset and enable scanning */
49 #define KBD_CMD_RESET 0xFF /* Reset */
50 #define KBD_CMD_SET_MAKE_BREAK 0xFC /* Set Make and Break mode */
51 #define KBD_CMD_SET_TYPEMATIC 0xFA /* Set Typematic Make and Break mode */
52
53 /* Keyboard Replies */
54 #define KBD_REPLY_POR 0xAA /* Power on reset */
55 #define KBD_REPLY_ID 0xAB /* Keyboard ID */
56 #define KBD_REPLY_ACK 0xFA /* Command ACK */
57 #define KBD_REPLY_RESEND 0xFE /* Command NACK, send the cmd again */
58
59 /* Mouse Commands */
60 #define AUX_SET_SCALE11 0xE6 /* Set 1:1 scaling */
61 #define AUX_SET_SCALE21 0xE7 /* Set 2:1 scaling */
62 #define AUX_SET_RES 0xE8 /* Set resolution */
63 #define AUX_GET_SCALE 0xE9 /* Get scaling factor */
64 #define AUX_SET_STREAM 0xEA /* Set stream mode */
65 #define AUX_POLL 0xEB /* Poll */
66 #define AUX_RESET_WRAP 0xEC /* Reset wrap mode */
67 #define AUX_SET_WRAP 0xEE /* Set wrap mode */
68 #define AUX_SET_REMOTE 0xF0 /* Set remote mode */
69 #define AUX_GET_TYPE 0xF2 /* Get type */
70 #define AUX_SET_SAMPLE 0xF3 /* Set sample rate */
71 #define AUX_ENABLE_DEV 0xF4 /* Enable aux device */
72 #define AUX_DISABLE_DEV 0xF5 /* Disable aux device */
73 #define AUX_SET_DEFAULT 0xF6
74 #define AUX_RESET 0xFF /* Reset aux device */
75 #define AUX_ACK 0xFA /* Command byte ACK. */
76 #define AUX_RESEND 0xFE /* Command NACK, send the cmd again */
77
78 #define MOUSE_STATUS_REMOTE 0x40
79 #define MOUSE_STATUS_ENABLED 0x20
80 #define MOUSE_STATUS_SCALE21 0x10
81
82 #define PS2_QUEUE_SIZE 16 /* Queue size required by PS/2 protocol */
83 #define PS2_QUEUE_HEADROOM 8 /* Queue size for keyboard command replies */
84
85 /* Bits for 'modifiers' field in PS2KbdState */
86 #define MOD_CTRL_L (1 << 0)
87 #define MOD_SHIFT_L (1 << 1)
88 #define MOD_ALT_L (1 << 2)
89 #define MOD_CTRL_R (1 << 3)
90 #define MOD_SHIFT_R (1 << 4)
91 #define MOD_ALT_R (1 << 5)
92
93 static uint8_t translate_table[256] = {
94 0xff, 0x43, 0x41, 0x3f, 0x3d, 0x3b, 0x3c, 0x58,
95 0x64, 0x44, 0x42, 0x40, 0x3e, 0x0f, 0x29, 0x59,
96 0x65, 0x38, 0x2a, 0x70, 0x1d, 0x10, 0x02, 0x5a,
97 0x66, 0x71, 0x2c, 0x1f, 0x1e, 0x11, 0x03, 0x5b,
98 0x67, 0x2e, 0x2d, 0x20, 0x12, 0x05, 0x04, 0x5c,
99 0x68, 0x39, 0x2f, 0x21, 0x14, 0x13, 0x06, 0x5d,
100 0x69, 0x31, 0x30, 0x23, 0x22, 0x15, 0x07, 0x5e,
101 0x6a, 0x72, 0x32, 0x24, 0x16, 0x08, 0x09, 0x5f,
102 0x6b, 0x33, 0x25, 0x17, 0x18, 0x0b, 0x0a, 0x60,
103 0x6c, 0x34, 0x35, 0x26, 0x27, 0x19, 0x0c, 0x61,
104 0x6d, 0x73, 0x28, 0x74, 0x1a, 0x0d, 0x62, 0x6e,
105 0x3a, 0x36, 0x1c, 0x1b, 0x75, 0x2b, 0x63, 0x76,
106 0x55, 0x56, 0x77, 0x78, 0x79, 0x7a, 0x0e, 0x7b,
107 0x7c, 0x4f, 0x7d, 0x4b, 0x47, 0x7e, 0x7f, 0x6f,
108 0x52, 0x53, 0x50, 0x4c, 0x4d, 0x48, 0x01, 0x45,
109 0x57, 0x4e, 0x51, 0x4a, 0x37, 0x49, 0x46, 0x54,
110 0x80, 0x81, 0x82, 0x41, 0x54, 0x85, 0x86, 0x87,
111 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
112 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
113 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
114 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
115 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
116 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
117 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
118 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
119 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
120 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
121 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
122 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
123 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
124 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
125 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
126 };
127
128 static unsigned int ps2_modifier_bit(unsigned int key)
129 {
130 switch (key) {
131 case KEY_LEFTCTRL:
132 return MOD_CTRL_L;
133 case KEY_RIGHTCTRL:
134 return MOD_CTRL_R;
135 case KEY_LEFTSHIFT:
136 return MOD_SHIFT_L;
137 case KEY_RIGHTSHIFT:
138 return MOD_SHIFT_R;
139 case KEY_LEFTALT:
140 return MOD_ALT_L;
141 case KEY_RIGHTALT:
142 return MOD_ALT_R;
143 default:
144 return 0;
145 }
146 }
147
148 static void ps2_reset_queue(PS2State *s)
149 {
150 PS2Queue *q = &s->queue;
151
152 q->rptr = 0;
153 q->wptr = 0;
154 q->cwptr = -1;
155 q->count = 0;
156 }
157
158 int ps2_queue_empty(PS2State *s)
159 {
160 return s->queue.count == 0;
161 }
162
163 void ps2_queue_noirq(PS2State *s, int b)
164 {
165 PS2Queue *q = &s->queue;
166
167 if (q->count >= PS2_QUEUE_SIZE) {
168 return;
169 }
170
171 q->data[q->wptr] = b;
172 if (++q->wptr == PS2_BUFFER_SIZE) {
173 q->wptr = 0;
174 }
175 q->count++;
176 }
177
178 static void ps2_raise_irq(PS2State *s)
179 {
180 qemu_set_irq(s->irq, 1);
181 }
182
183 static void ps2_lower_irq(PS2State *s)
184 {
185 qemu_set_irq(s->irq, 0);
186 }
187
188 void ps2_queue(PS2State *s, int b)
189 {
190 if (PS2_QUEUE_SIZE - s->queue.count < 1) {
191 return;
192 }
193
194 ps2_queue_noirq(s, b);
195 ps2_raise_irq(s);
196 }
197
198 void ps2_queue_2(PS2State *s, int b1, int b2)
199 {
200 if (PS2_QUEUE_SIZE - s->queue.count < 2) {
201 return;
202 }
203
204 ps2_queue_noirq(s, b1);
205 ps2_queue_noirq(s, b2);
206 ps2_raise_irq(s);
207 }
208
209 void ps2_queue_3(PS2State *s, int b1, int b2, int b3)
210 {
211 if (PS2_QUEUE_SIZE - s->queue.count < 3) {
212 return;
213 }
214
215 ps2_queue_noirq(s, b1);
216 ps2_queue_noirq(s, b2);
217 ps2_queue_noirq(s, b3);
218 ps2_raise_irq(s);
219 }
220
221 void ps2_queue_4(PS2State *s, int b1, int b2, int b3, int b4)
222 {
223 if (PS2_QUEUE_SIZE - s->queue.count < 4) {
224 return;
225 }
226
227 ps2_queue_noirq(s, b1);
228 ps2_queue_noirq(s, b2);
229 ps2_queue_noirq(s, b3);
230 ps2_queue_noirq(s, b4);
231 ps2_raise_irq(s);
232 }
233
234 static void ps2_cqueue_data(PS2Queue *q, int b)
235 {
236 q->data[q->cwptr] = b;
237 if (++q->cwptr >= PS2_BUFFER_SIZE) {
238 q->cwptr = 0;
239 }
240 q->count++;
241 }
242
243 static void ps2_cqueue_1(PS2State *s, int b1)
244 {
245 PS2Queue *q = &s->queue;
246
247 q->rptr = (q->rptr - 1) & (PS2_BUFFER_SIZE - 1);
248 q->cwptr = q->rptr;
249 ps2_cqueue_data(q, b1);
250 ps2_raise_irq(s);
251 }
252
253 static void ps2_cqueue_2(PS2State *s, int b1, int b2)
254 {
255 PS2Queue *q = &s->queue;
256
257 q->rptr = (q->rptr - 2) & (PS2_BUFFER_SIZE - 1);
258 q->cwptr = q->rptr;
259 ps2_cqueue_data(q, b1);
260 ps2_cqueue_data(q, b2);
261 ps2_raise_irq(s);
262 }
263
264 static void ps2_cqueue_3(PS2State *s, int b1, int b2, int b3)
265 {
266 PS2Queue *q = &s->queue;
267
268 q->rptr = (q->rptr - 3) & (PS2_BUFFER_SIZE - 1);
269 q->cwptr = q->rptr;
270 ps2_cqueue_data(q, b1);
271 ps2_cqueue_data(q, b2);
272 ps2_cqueue_data(q, b3);
273 ps2_raise_irq(s);
274 }
275
276 static void ps2_cqueue_reset(PS2State *s)
277 {
278 PS2Queue *q = &s->queue;
279 int ccount;
280
281 if (q->cwptr == -1) {
282 return;
283 }
284
285 ccount = (q->cwptr - q->rptr) & (PS2_BUFFER_SIZE - 1);
286 q->count -= ccount;
287 q->rptr = q->cwptr;
288 q->cwptr = -1;
289 }
290
291 /* keycode is the untranslated scancode in the current scancode set. */
292 static void ps2_put_keycode(void *opaque, int keycode)
293 {
294 PS2KbdState *s = opaque;
295 PS2State *ps = PS2_DEVICE(s);
296
297 trace_ps2_put_keycode(opaque, keycode);
298 qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER, NULL);
299
300 if (s->translate) {
301 if (keycode == 0xf0) {
302 s->need_high_bit = true;
303 } else if (s->need_high_bit) {
304 ps2_queue(ps, translate_table[keycode] | 0x80);
305 s->need_high_bit = false;
306 } else {
307 ps2_queue(ps, translate_table[keycode]);
308 }
309 } else {
310 ps2_queue(ps, keycode);
311 }
312 }
313
314 static void ps2_keyboard_event(DeviceState *dev, QemuConsole *src,
315 QemuInputEvent *evt)
316 {
317 PS2KbdState *s = (PS2KbdState *)dev;
318 uint16_t keycode = 0;
319 int mod;
320
321 /* do not process events while disabled to prevent stream corruption */
322 if (!s->scan_enabled) {
323 return;
324 }
325
326 qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER, NULL);
327 assert(evt->type == INPUT_EVENT_KIND_KEY);
328
329 mod = ps2_modifier_bit(evt->key.key);
330 trace_ps2_keyboard_event(s, evt->key.key, evt->key.down, mod,
331 s->modifiers, s->scancode_set, s->translate);
332 if (evt->key.down) {
333 s->modifiers |= mod;
334 } else {
335 s->modifiers &= ~mod;
336 }
337
338 if (s->scancode_set == 1) {
339 if (evt->key.key == KEY_PAUSE) {
340 if (s->modifiers & (MOD_CTRL_L | MOD_CTRL_R)) {
341 if (evt->key.down) {
342 ps2_put_keycode(s, 0xe0);
343 ps2_put_keycode(s, 0x46);
344 ps2_put_keycode(s, 0xe0);
345 ps2_put_keycode(s, 0xc6);
346 }
347 } else {
348 if (evt->key.down) {
349 ps2_put_keycode(s, 0xe1);
350 ps2_put_keycode(s, 0x1d);
351 ps2_put_keycode(s, 0x45);
352 ps2_put_keycode(s, 0xe1);
353 ps2_put_keycode(s, 0x9d);
354 ps2_put_keycode(s, 0xc5);
355 }
356 }
357 } else if (evt->key.key == KEY_SYSRQ) {
358 if (s->modifiers & MOD_ALT_L) {
359 if (evt->key.down) {
360 ps2_put_keycode(s, 0xb8);
361 ps2_put_keycode(s, 0x38);
362 ps2_put_keycode(s, 0x54);
363 } else {
364 ps2_put_keycode(s, 0xd4);
365 ps2_put_keycode(s, 0xb8);
366 ps2_put_keycode(s, 0x38);
367 }
368 } else if (s->modifiers & MOD_ALT_R) {
369 if (evt->key.down) {
370 ps2_put_keycode(s, 0xe0);
371 ps2_put_keycode(s, 0xb8);
372 ps2_put_keycode(s, 0xe0);
373 ps2_put_keycode(s, 0x38);
374 ps2_put_keycode(s, 0x54);
375 } else {
376 ps2_put_keycode(s, 0xd4);
377 ps2_put_keycode(s, 0xe0);
378 ps2_put_keycode(s, 0xb8);
379 ps2_put_keycode(s, 0xe0);
380 ps2_put_keycode(s, 0x38);
381 }
382 } else if (s->modifiers & (MOD_SHIFT_L | MOD_CTRL_L |
383 MOD_SHIFT_R | MOD_CTRL_R)) {
384 if (evt->key.down) {
385 ps2_put_keycode(s, 0xe0);
386 ps2_put_keycode(s, 0x37);
387 } else {
388 ps2_put_keycode(s, 0xe0);
389 ps2_put_keycode(s, 0xb7);
390 }
391 } else {
392 if (evt->key.down) {
393 ps2_put_keycode(s, 0xe0);
394 ps2_put_keycode(s, 0x2a);
395 ps2_put_keycode(s, 0xe0);
396 ps2_put_keycode(s, 0x37);
397 } else {
398 ps2_put_keycode(s, 0xe0);
399 ps2_put_keycode(s, 0xb7);
400 ps2_put_keycode(s, 0xe0);
401 ps2_put_keycode(s, 0xaa);
402 }
403 }
404 } else if ((evt->key.key == KEY_HANGEUL || evt->key.key == KEY_HANJA)
405 && !evt->key.down) {
406 /* Ignore release for these keys */
407 } else {
408 if (evt->key.key < qemu_input_map_linux_to_atset1_len) {
409 keycode = qemu_input_map_linux_to_atset1[evt->key.key];
410 }
411 if (keycode) {
412 if (keycode & 0xff00) {
413 ps2_put_keycode(s, keycode >> 8);
414 }
415 if (!evt->key.down) {
416 keycode |= 0x80;
417 }
418 ps2_put_keycode(s, keycode & 0xff);
419 } else {
420 qemu_log_mask(LOG_UNIMP,
421 "ps2: ignoring key %u\n", evt->key.key);
422 }
423 }
424 } else if (s->scancode_set == 2) {
425 if (evt->key.key == KEY_PAUSE) {
426 if (s->modifiers & (MOD_CTRL_L | MOD_CTRL_R)) {
427 if (evt->key.down) {
428 ps2_put_keycode(s, 0xe0);
429 ps2_put_keycode(s, 0x7e);
430 ps2_put_keycode(s, 0xe0);
431 ps2_put_keycode(s, 0xf0);
432 ps2_put_keycode(s, 0x7e);
433 }
434 } else {
435 if (evt->key.down) {
436 ps2_put_keycode(s, 0xe1);
437 ps2_put_keycode(s, 0x14);
438 ps2_put_keycode(s, 0x77);
439 ps2_put_keycode(s, 0xe1);
440 ps2_put_keycode(s, 0xf0);
441 ps2_put_keycode(s, 0x14);
442 ps2_put_keycode(s, 0xf0);
443 ps2_put_keycode(s, 0x77);
444 }
445 }
446 } else if (evt->key.key == KEY_SYSRQ) {
447 if (s->modifiers & MOD_ALT_L) {
448 if (evt->key.down) {
449 ps2_put_keycode(s, 0xf0);
450 ps2_put_keycode(s, 0x11);
451 ps2_put_keycode(s, 0x11);
452 ps2_put_keycode(s, 0x84);
453 } else {
454 ps2_put_keycode(s, 0xf0);
455 ps2_put_keycode(s, 0x84);
456 ps2_put_keycode(s, 0xf0);
457 ps2_put_keycode(s, 0x11);
458 ps2_put_keycode(s, 0x11);
459 }
460 } else if (s->modifiers & MOD_ALT_R) {
461 if (evt->key.down) {
462 ps2_put_keycode(s, 0xe0);
463 ps2_put_keycode(s, 0xf0);
464 ps2_put_keycode(s, 0x11);
465 ps2_put_keycode(s, 0xe0);
466 ps2_put_keycode(s, 0x11);
467 ps2_put_keycode(s, 0x84);
468 } else {
469 ps2_put_keycode(s, 0xf0);
470 ps2_put_keycode(s, 0x84);
471 ps2_put_keycode(s, 0xe0);
472 ps2_put_keycode(s, 0xf0);
473 ps2_put_keycode(s, 0x11);
474 ps2_put_keycode(s, 0xe0);
475 ps2_put_keycode(s, 0x11);
476 }
477 } else if (s->modifiers & (MOD_SHIFT_L | MOD_CTRL_L |
478 MOD_SHIFT_R | MOD_CTRL_R)) {
479 if (evt->key.down) {
480 ps2_put_keycode(s, 0xe0);
481 ps2_put_keycode(s, 0x7c);
482 } else {
483 ps2_put_keycode(s, 0xe0);
484 ps2_put_keycode(s, 0xf0);
485 ps2_put_keycode(s, 0x7c);
486 }
487 } else {
488 if (evt->key.down) {
489 ps2_put_keycode(s, 0xe0);
490 ps2_put_keycode(s, 0x12);
491 ps2_put_keycode(s, 0xe0);
492 ps2_put_keycode(s, 0x7c);
493 } else {
494 ps2_put_keycode(s, 0xe0);
495 ps2_put_keycode(s, 0xf0);
496 ps2_put_keycode(s, 0x7c);
497 ps2_put_keycode(s, 0xe0);
498 ps2_put_keycode(s, 0xf0);
499 ps2_put_keycode(s, 0x12);
500 }
501 }
502 } else if ((evt->key.key == KEY_HANGEUL || evt->key.key == KEY_HANJA) &&
503 !evt->key.down) {
504 /* Ignore release for these keys */
505 } else {
506 if (evt->key.key < qemu_input_map_linux_to_atset2_len) {
507 keycode = qemu_input_map_linux_to_atset2[evt->key.key];
508 }
509 if (keycode) {
510 if (keycode & 0xff00) {
511 ps2_put_keycode(s, keycode >> 8);
512 }
513 if (!evt->key.down) {
514 ps2_put_keycode(s, 0xf0);
515 }
516 ps2_put_keycode(s, keycode & 0xff);
517 } else {
518 qemu_log_mask(LOG_UNIMP,
519 "ps2: ignoring key %u\n", evt->key.key);
520 }
521 }
522 } else if (s->scancode_set == 3) {
523 if (evt->key.key < qemu_input_map_linux_to_atset3_len) {
524 keycode = qemu_input_map_linux_to_atset3[evt->key.key];
525 }
526 if (keycode) {
527 /* FIXME: break code should be configured on a key by key basis */
528 if (!evt->key.down) {
529 ps2_put_keycode(s, 0xf0);
530 }
531 ps2_put_keycode(s, keycode);
532 } else {
533 qemu_log_mask(LOG_UNIMP,
534 "ps2: ignoring key %u\n", evt->key.key);
535 }
536 }
537 }
538
539 uint32_t ps2_read_data(PS2State *s)
540 {
541 PS2Queue *q;
542 int val, index;
543
544 trace_ps2_read_data(s);
545 q = &s->queue;
546 if (q->count == 0) {
547 /*
548 * NOTE: if no data left, we return the last keyboard one
549 * (needed for EMM386)
550 */
551 /* XXX: need a timer to do things correctly */
552 index = q->rptr - 1;
553 if (index < 0) {
554 index = PS2_BUFFER_SIZE - 1;
555 }
556 val = q->data[index];
557 } else {
558 val = q->data[q->rptr];
559 if (++q->rptr == PS2_BUFFER_SIZE) {
560 q->rptr = 0;
561 }
562 q->count--;
563 if (q->rptr == q->cwptr) {
564 /* command reply queue is empty */
565 q->cwptr = -1;
566 }
567 /* reading deasserts IRQ */
568 ps2_lower_irq(s);
569 /* reassert IRQs if data left */
570 if (q->count) {
571 ps2_raise_irq(s);
572 }
573 }
574 return val;
575 }
576
577 static void ps2_set_ledstate(PS2KbdState *s, int ledstate)
578 {
579 trace_ps2_set_ledstate(s, ledstate);
580 s->ledstate = ledstate;
581 qemu_input_handler_set_leds_mask(PS2_DEVICE(s)->hs, ledstate);
582 }
583
584 static void ps2_reset_keyboard(PS2KbdState *s)
585 {
586 PS2State *ps2 = PS2_DEVICE(s);
587
588 trace_ps2_reset_keyboard(s);
589 s->scan_enabled = 1;
590 s->scancode_set = 2;
591 ps2_reset_queue(ps2);
592 ps2_set_ledstate(s, 0);
593 }
594
595 void ps2_write_keyboard(PS2KbdState *s, int val)
596 {
597 PS2State *ps2 = PS2_DEVICE(s);
598
599 trace_ps2_write_keyboard(s, val);
600 ps2_cqueue_reset(ps2);
601 switch (ps2->write_cmd) {
602 default:
603 case -1:
604 switch (val) {
605 case 0x00:
606 ps2_cqueue_1(ps2, KBD_REPLY_ACK);
607 break;
608 case 0x05:
609 ps2_cqueue_1(ps2, KBD_REPLY_RESEND);
610 break;
611 case KBD_CMD_GET_ID:
612 /* We emulate a MF2 AT keyboard here */
613 ps2_cqueue_3(ps2, KBD_REPLY_ACK, KBD_REPLY_ID,
614 s->translate ? 0x41 : 0x83);
615 break;
616 case KBD_CMD_ECHO:
617 ps2_cqueue_1(ps2, KBD_CMD_ECHO);
618 break;
619 case KBD_CMD_ENABLE:
620 s->scan_enabled = 1;
621 ps2_cqueue_1(ps2, KBD_REPLY_ACK);
622 break;
623 case KBD_CMD_SCANCODE:
624 case KBD_CMD_SET_LEDS:
625 case KBD_CMD_SET_RATE:
626 case KBD_CMD_SET_MAKE_BREAK:
627 ps2->write_cmd = val;
628 ps2_cqueue_1(ps2, KBD_REPLY_ACK);
629 break;
630 case KBD_CMD_RESET_DISABLE:
631 ps2_reset_keyboard(s);
632 s->scan_enabled = 0;
633 ps2_cqueue_1(ps2, KBD_REPLY_ACK);
634 break;
635 case KBD_CMD_RESET_ENABLE:
636 ps2_reset_keyboard(s);
637 s->scan_enabled = 1;
638 ps2_cqueue_1(ps2, KBD_REPLY_ACK);
639 break;
640 case KBD_CMD_RESET:
641 ps2_reset_keyboard(s);
642 ps2_cqueue_2(ps2,
643 KBD_REPLY_ACK,
644 KBD_REPLY_POR);
645 break;
646 case KBD_CMD_SET_TYPEMATIC:
647 ps2_cqueue_1(ps2, KBD_REPLY_ACK);
648 break;
649 default:
650 /*
651 * A PS/2 device answers every command it is given; an unknown
652 * one draws a resend.
653 */
654 ps2_cqueue_1(ps2, KBD_REPLY_RESEND);
655 break;
656 }
657 break;
658 case KBD_CMD_SET_MAKE_BREAK:
659 ps2_cqueue_1(ps2, KBD_REPLY_ACK);
660 ps2->write_cmd = -1;
661 break;
662 case KBD_CMD_SCANCODE:
663 if (val == 0) {
664 ps2_cqueue_2(ps2, KBD_REPLY_ACK, s->translate ?
665 translate_table[s->scancode_set] : s->scancode_set);
666 } else if (val >= 1 && val <= 3) {
667 s->scancode_set = val;
668 ps2_cqueue_1(ps2, KBD_REPLY_ACK);
669 } else {
670 ps2_cqueue_1(ps2, KBD_REPLY_RESEND);
671 }
672 ps2->write_cmd = -1;
673 break;
674 case KBD_CMD_SET_LEDS:
675 ps2_set_ledstate(s, val);
676 ps2_cqueue_1(ps2, KBD_REPLY_ACK);
677 ps2->write_cmd = -1;
678 break;
679 case KBD_CMD_SET_RATE:
680 ps2_cqueue_1(ps2, KBD_REPLY_ACK);
681 ps2->write_cmd = -1;
682 break;
683 }
684 }
685
686 /*
687 * Set the scancode translation mode.
688 * 0 = raw scancodes.
689 * 1 = translated scancodes (used by qemu internally).
690 */
691
692 void ps2_keyboard_set_translation(PS2KbdState *s, int mode)
693 {
694 trace_ps2_keyboard_set_translation(s, mode);
695 s->translate = mode;
696 }
697
698 static int ps2_mouse_send_packet(PS2MouseState *s)
699 {
700 PS2State *ps2 = PS2_DEVICE(s);
701 /* IMPS/2 and IMEX send 4 bytes, PS2 sends 3 bytes */
702 const int needed = s->mouse_type ? 4 : 3;
703 unsigned int b;
704 int dx1, dy1, dz1, dw1;
705
706 if (PS2_QUEUE_SIZE - ps2->queue.count < needed) {
707 return 0;
708 }
709
710 dx1 = s->mouse_dx;
711 dy1 = s->mouse_dy;
712 dz1 = s->mouse_dz;
713 dw1 = s->mouse_dw;
714 /* XXX: increase range to 8 bits ? */
715 if (dx1 > 127) {
716 dx1 = 127;
717 } else if (dx1 < -127) {
718 dx1 = -127;
719 }
720 if (dy1 > 127) {
721 dy1 = 127;
722 } else if (dy1 < -127) {
723 dy1 = -127;
724 }
725 b = 0x08 | ((dx1 < 0) << 4) | ((dy1 < 0) << 5) | (s->mouse_buttons & 0x07);
726 ps2_queue_noirq(ps2, b);
727 ps2_queue_noirq(ps2, dx1 & 0xff);
728 ps2_queue_noirq(ps2, dy1 & 0xff);
729 /* extra byte for IMPS/2 or IMEX */
730 switch (s->mouse_type) {
731 default:
732 /* Just ignore the wheels if not supported */
733 s->mouse_dz = 0;
734 s->mouse_dw = 0;
735 break;
736 case 3:
737 if (dz1 > 127) {
738 dz1 = 127;
739 } else if (dz1 < -127) {
740 dz1 = -127;
741 }
742 ps2_queue_noirq(ps2, dz1 & 0xff);
743 s->mouse_dz -= dz1;
744 s->mouse_dw = 0;
745 break;
746 case 4:
747 /*
748 * This matches what the Linux kernel expects for exps/2 in
749 * drivers/input/mouse/psmouse-base.c. Note, if you happen to
750 * press/release the 4th or 5th buttons at the same moment as a
751 * horizontal wheel scroll, those button presses will get lost. I'm not
752 * sure what to do about that, since by this point we don't know
753 * whether those buttons actually changed state.
754 */
755 if (dw1 != 0) {
756 if (dw1 > 31) {
757 dw1 = 31;
758 } else if (dw1 < -31) {
759 dw1 = -31;
760 }
761
762 /*
763 * linux kernel expects first 6 bits to represent the value
764 * for horizontal scroll
765 */
766 b = (dw1 & 0x3f) | 0x40;
767 s->mouse_dw -= dw1;
768 } else {
769 if (dz1 > 7) {
770 dz1 = 7;
771 } else if (dz1 < -7) {
772 dz1 = -7;
773 }
774
775 b = (dz1 & 0x0f) | ((s->mouse_buttons & 0x18) << 1);
776 s->mouse_dz -= dz1;
777 }
778 ps2_queue_noirq(ps2, b);
779 break;
780 }
781
782 ps2_raise_irq(ps2);
783
784 trace_ps2_mouse_send_packet(s, dx1, dy1, dz1, b);
785 /* update deltas */
786 s->mouse_dx -= dx1;
787 s->mouse_dy -= dy1;
788
789 return 1;
790 }
791
792 static void ps2_mouse_event(DeviceState *dev, QemuConsole *src,
793 QemuInputEvent *evt)
794 {
795 static const int bmap[INPUT_BUTTON__MAX] = {
796 [INPUT_BUTTON_LEFT] = PS2_MOUSE_BUTTON_LEFT,
797 [INPUT_BUTTON_MIDDLE] = PS2_MOUSE_BUTTON_MIDDLE,
798 [INPUT_BUTTON_RIGHT] = PS2_MOUSE_BUTTON_RIGHT,
799 [INPUT_BUTTON_SIDE] = PS2_MOUSE_BUTTON_SIDE,
800 [INPUT_BUTTON_EXTRA] = PS2_MOUSE_BUTTON_EXTRA,
801 };
802 PS2MouseState *s = (PS2MouseState *)dev;
803
804 /* check if deltas are recorded when disabled */
805 if (!(s->mouse_status & MOUSE_STATUS_ENABLED)) {
806 return;
807 }
808
809 switch (evt->type) {
810 case INPUT_EVENT_KIND_REL:
811 if (evt->rel.axis == INPUT_AXIS_X) {
812 s->mouse_dx += evt->rel.value;
813 } else if (evt->rel.axis == INPUT_AXIS_Y) {
814 s->mouse_dy -= evt->rel.value;
815 }
816 break;
817
818 case INPUT_EVENT_KIND_BTN:
819 if (evt->btn.down) {
820 s->mouse_buttons |= bmap[evt->btn.button];
821 if (evt->btn.button == INPUT_BUTTON_WHEEL_UP) {
822 s->mouse_dz--;
823 } else if (evt->btn.button == INPUT_BUTTON_WHEEL_DOWN) {
824 s->mouse_dz++;
825 }
826
827 if (evt->btn.button == INPUT_BUTTON_WHEEL_RIGHT) {
828 s->mouse_dw--;
829 } else if (evt->btn.button == INPUT_BUTTON_WHEEL_LEFT) {
830 s->mouse_dw++;
831 }
832 } else {
833 s->mouse_buttons &= ~bmap[evt->btn.button];
834 }
835 break;
836
837 default:
838 /* keep gcc happy */
839 break;
840 }
841 }
842
843 static void ps2_mouse_sync(DeviceState *dev)
844 {
845 PS2MouseState *s = (PS2MouseState *)dev;
846
847 /* do not sync while disabled to prevent stream corruption */
848 if (!(s->mouse_status & MOUSE_STATUS_ENABLED)) {
849 return;
850 }
851
852 if (s->mouse_buttons) {
853 qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER, NULL);
854 }
855 if (!(s->mouse_status & MOUSE_STATUS_REMOTE)) {
856 /*
857 * if not remote, send event. Multiple events are sent if
858 * too big deltas
859 */
860 while (ps2_mouse_send_packet(s)) {
861 if (s->mouse_dx == 0 && s->mouse_dy == 0
862 && s->mouse_dz == 0 && s->mouse_dw == 0) {
863 break;
864 }
865 }
866 }
867 }
868
869 void ps2_mouse_fake_event(PS2MouseState *s)
870 {
871 trace_ps2_mouse_fake_event(s);
872 s->mouse_dx++;
873 ps2_mouse_sync(DEVICE(s));
874 }
875
876 void ps2_write_mouse(PS2MouseState *s, int val)
877 {
878 PS2State *ps2 = PS2_DEVICE(s);
879
880 trace_ps2_write_mouse(s, val);
881 switch (ps2->write_cmd) {
882 default:
883 case -1:
884 /* mouse command */
885 if (s->mouse_wrap) {
886 if (val == AUX_RESET_WRAP) {
887 s->mouse_wrap = 0;
888 ps2_queue(ps2, AUX_ACK);
889 return;
890 } else if (val != AUX_RESET) {
891 ps2_queue(ps2, val);
892 return;
893 }
894 }
895 switch (val) {
896 case AUX_SET_SCALE11:
897 s->mouse_status &= ~MOUSE_STATUS_SCALE21;
898 ps2_queue(ps2, AUX_ACK);
899 break;
900 case AUX_SET_SCALE21:
901 s->mouse_status |= MOUSE_STATUS_SCALE21;
902 ps2_queue(ps2, AUX_ACK);
903 break;
904 case AUX_SET_STREAM:
905 s->mouse_status &= ~MOUSE_STATUS_REMOTE;
906 ps2_queue(ps2, AUX_ACK);
907 break;
908 case AUX_SET_WRAP:
909 s->mouse_wrap = 1;
910 ps2_queue(ps2, AUX_ACK);
911 break;
912 case AUX_SET_REMOTE:
913 s->mouse_status |= MOUSE_STATUS_REMOTE;
914 ps2_queue(ps2, AUX_ACK);
915 break;
916 case AUX_GET_TYPE:
917 ps2_queue_2(ps2,
918 AUX_ACK,
919 s->mouse_type);
920 break;
921 case AUX_SET_RES:
922 case AUX_SET_SAMPLE:
923 ps2->write_cmd = val;
924 ps2_queue(ps2, AUX_ACK);
925 break;
926 case AUX_GET_SCALE:
927 ps2_queue_4(ps2,
928 AUX_ACK,
929 s->mouse_status,
930 s->mouse_resolution,
931 s->mouse_sample_rate);
932 break;
933 case AUX_POLL:
934 ps2_queue(ps2, AUX_ACK);
935 ps2_mouse_send_packet(s);
936 break;
937 case AUX_ENABLE_DEV:
938 s->mouse_status |= MOUSE_STATUS_ENABLED;
939 ps2_queue(ps2, AUX_ACK);
940 break;
941 case AUX_DISABLE_DEV:
942 s->mouse_status &= ~MOUSE_STATUS_ENABLED;
943 ps2_queue(ps2, AUX_ACK);
944 break;
945 case AUX_SET_DEFAULT:
946 s->mouse_sample_rate = 100;
947 s->mouse_resolution = 2;
948 s->mouse_status = 0;
949 ps2_queue(ps2, AUX_ACK);
950 break;
951 case AUX_RESET:
952 s->mouse_sample_rate = 100;
953 s->mouse_resolution = 2;
954 s->mouse_status = 0;
955 s->mouse_type = 0;
956 ps2_reset_queue(ps2);
957 ps2_queue_3(ps2,
958 AUX_ACK,
959 0xaa,
960 s->mouse_type);
961 break;
962 default:
963 /*
964 * A PS/2 device answers every command it is given; an unknown
965 * one draws a resend.
966 */
967 ps2_queue(ps2, AUX_RESEND);
968 break;
969 }
970 break;
971 case AUX_SET_SAMPLE:
972 s->mouse_sample_rate = val;
973 /* detect IMPS/2 or IMEX */
974 switch (s->mouse_detect_state) {
975 default:
976 case 0:
977 if (val == 200) {
978 s->mouse_detect_state = 1;
979 }
980 break;
981 case 1:
982 if (val == 100) {
983 s->mouse_detect_state = 2;
984 } else if (val == 200) {
985 s->mouse_detect_state = 3;
986 } else {
987 s->mouse_detect_state = 0;
988 }
989 break;
990 case 2:
991 if (val == 80) {
992 s->mouse_type = 3; /* IMPS/2 */
993 }
994 s->mouse_detect_state = 0;
995 break;
996 case 3:
997 if (val == 80) {
998 s->mouse_type = 4; /* IMEX */
999 }
1000 s->mouse_detect_state = 0;
1001 break;
1002 }
1003 ps2_queue(ps2, AUX_ACK);
1004 ps2->write_cmd = -1;
1005 break;
1006 case AUX_SET_RES:
1007 s->mouse_resolution = val;
1008 ps2_queue(ps2, AUX_ACK);
1009 ps2->write_cmd = -1;
1010 break;
1011 }
1012 }
1013
1014 static void ps2_reset_hold(Object *obj, ResetType type)
1015 {
1016 PS2State *s = PS2_DEVICE(obj);
1017
1018 s->write_cmd = -1;
1019 ps2_reset_queue(s);
1020 }
1021
1022 static void ps2_reset_exit(Object *obj, ResetType type)
1023 {
1024 PS2State *s = PS2_DEVICE(obj);
1025
1026 ps2_lower_irq(s);
1027 }
1028
1029 static void ps2_common_post_load(PS2State *s)
1030 {
1031 PS2Queue *q = &s->queue;
1032 int ccount = 0;
1033
1034 /* limit the number of queued command replies to PS2_QUEUE_HEADROOM */
1035 if (q->cwptr != -1) {
1036 ccount = (q->cwptr - q->rptr) & (PS2_BUFFER_SIZE - 1);
1037 if (ccount > PS2_QUEUE_HEADROOM) {
1038 ccount = PS2_QUEUE_HEADROOM;
1039 }
1040 }
1041
1042 /* limit the scancode queue size to PS2_QUEUE_SIZE */
1043 if (q->count < ccount) {
1044 q->count = ccount;
1045 } else if (q->count > ccount + PS2_QUEUE_SIZE) {
1046 q->count = ccount + PS2_QUEUE_SIZE;
1047 }
1048
1049 /* sanitize rptr and recalculate wptr and cwptr */
1050 q->rptr = q->rptr & (PS2_BUFFER_SIZE - 1);
1051 q->wptr = (q->rptr + q->count) & (PS2_BUFFER_SIZE - 1);
1052 q->cwptr = ccount ? (q->rptr + ccount) & (PS2_BUFFER_SIZE - 1) : -1;
1053 }
1054
1055 static void ps2_kbd_reset_hold(Object *obj, ResetType type)
1056 {
1057 PS2DeviceClass *ps2dc = PS2_DEVICE_GET_CLASS(obj);
1058 PS2KbdState *s = PS2_KBD_DEVICE(obj);
1059
1060 trace_ps2_kbd_reset(s);
1061
1062 if (ps2dc->parent_phases.hold) {
1063 ps2dc->parent_phases.hold(obj, type);
1064 }
1065
1066 s->scan_enabled = 1;
1067 s->translate = 0;
1068 s->scancode_set = 2;
1069 s->modifiers = 0;
1070 }
1071
1072 static void ps2_mouse_reset_hold(Object *obj, ResetType type)
1073 {
1074 PS2DeviceClass *ps2dc = PS2_DEVICE_GET_CLASS(obj);
1075 PS2MouseState *s = PS2_MOUSE_DEVICE(obj);
1076
1077 trace_ps2_mouse_reset(s);
1078
1079 if (ps2dc->parent_phases.hold) {
1080 ps2dc->parent_phases.hold(obj, type);
1081 }
1082
1083 s->mouse_status = 0;
1084 s->mouse_resolution = 0;
1085 s->mouse_sample_rate = 0;
1086 s->mouse_wrap = 0;
1087 s->mouse_type = 0;
1088 s->mouse_detect_state = 0;
1089 s->mouse_dx = 0;
1090 s->mouse_dy = 0;
1091 s->mouse_dz = 0;
1092 s->mouse_dw = 0;
1093 s->mouse_buttons = 0;
1094 }
1095
1096 static const VMStateDescription vmstate_ps2_common = {
1097 .name = "PS2 Common State",
1098 .version_id = 3,
1099 .minimum_version_id = 2,
1100 .fields = (const VMStateField[]) {
1101 VMSTATE_INT32(write_cmd, PS2State),
1102 VMSTATE_INT32(queue.rptr, PS2State),
1103 VMSTATE_INT32(queue.wptr, PS2State),
1104 VMSTATE_INT32(queue.count, PS2State),
1105 VMSTATE_BUFFER(queue.data, PS2State),
1106 VMSTATE_END_OF_LIST()
1107 }
1108 };
1109
1110 static bool ps2_keyboard_ledstate_needed(void *opaque)
1111 {
1112 PS2KbdState *s = opaque;
1113
1114 return s->ledstate != 0; /* 0 is default state */
1115 }
1116
1117 static int ps2_kbd_ledstate_post_load(void *opaque, int version_id)
1118 {
1119 PS2KbdState *s = opaque;
1120
1121 qemu_input_handler_set_leds_mask(PS2_DEVICE(s)->hs, s->ledstate);
1122 return 0;
1123 }
1124
1125 static const VMStateDescription vmstate_ps2_keyboard_ledstate = {
1126 .name = "ps2kbd/ledstate",
1127 .version_id = 3,
1128 .minimum_version_id = 2,
1129 .post_load = ps2_kbd_ledstate_post_load,
1130 .needed = ps2_keyboard_ledstate_needed,
1131 .fields = (const VMStateField[]) {
1132 VMSTATE_INT32(ledstate, PS2KbdState),
1133 VMSTATE_END_OF_LIST()
1134 }
1135 };
1136
1137 static bool ps2_keyboard_need_high_bit_needed(void *opaque)
1138 {
1139 PS2KbdState *s = opaque;
1140 return s->need_high_bit != 0; /* 0 is the usual state */
1141 }
1142
1143 static const VMStateDescription vmstate_ps2_keyboard_need_high_bit = {
1144 .name = "ps2kbd/need_high_bit",
1145 .version_id = 1,
1146 .minimum_version_id = 1,
1147 .needed = ps2_keyboard_need_high_bit_needed,
1148 .fields = (const VMStateField[]) {
1149 VMSTATE_BOOL(need_high_bit, PS2KbdState),
1150 VMSTATE_END_OF_LIST()
1151 }
1152 };
1153
1154 static bool ps2_keyboard_cqueue_needed(void *opaque)
1155 {
1156 PS2KbdState *s = opaque;
1157 PS2State *ps2 = PS2_DEVICE(s);
1158
1159 return ps2->queue.cwptr != -1; /* the queue is mostly empty */
1160 }
1161
1162 static const VMStateDescription vmstate_ps2_keyboard_cqueue = {
1163 .name = "ps2kbd/command_reply_queue",
1164 .needed = ps2_keyboard_cqueue_needed,
1165 .fields = (const VMStateField[]) {
1166 VMSTATE_INT32(parent_obj.queue.cwptr, PS2KbdState),
1167 VMSTATE_END_OF_LIST()
1168 }
1169 };
1170
1171 static int ps2_kbd_post_load(void *opaque, int version_id)
1172 {
1173 PS2KbdState *s = (PS2KbdState *)opaque;
1174 PS2State *ps2 = PS2_DEVICE(s);
1175
1176 if (version_id == 2) {
1177 s->scancode_set = 2;
1178 }
1179
1180 ps2_common_post_load(ps2);
1181
1182 return 0;
1183 }
1184
1185 static const VMStateDescription vmstate_ps2_keyboard = {
1186 .name = "ps2kbd",
1187 .version_id = 3,
1188 .minimum_version_id = 2,
1189 .post_load = ps2_kbd_post_load,
1190 .fields = (const VMStateField[]) {
1191 VMSTATE_STRUCT(parent_obj, PS2KbdState, 0, vmstate_ps2_common,
1192 PS2State),
1193 VMSTATE_INT32(scan_enabled, PS2KbdState),
1194 VMSTATE_INT32(translate, PS2KbdState),
1195 VMSTATE_INT32_V(scancode_set, PS2KbdState, 3),
1196 VMSTATE_END_OF_LIST()
1197 },
1198 .subsections = (const VMStateDescription * const []) {
1199 &vmstate_ps2_keyboard_ledstate,
1200 &vmstate_ps2_keyboard_need_high_bit,
1201 &vmstate_ps2_keyboard_cqueue,
1202 NULL
1203 }
1204 };
1205
1206 static int ps2_mouse_post_load(void *opaque, int version_id)
1207 {
1208 PS2MouseState *s = (PS2MouseState *)opaque;
1209 PS2State *ps2 = PS2_DEVICE(s);
1210
1211 ps2_common_post_load(ps2);
1212
1213 return 0;
1214 }
1215
1216 static const VMStateDescription vmstate_ps2_mouse = {
1217 .name = "ps2mouse",
1218 .version_id = 2,
1219 .minimum_version_id = 2,
1220 .post_load = ps2_mouse_post_load,
1221 .fields = (const VMStateField[]) {
1222 VMSTATE_STRUCT(parent_obj, PS2MouseState, 0, vmstate_ps2_common,
1223 PS2State),
1224 VMSTATE_UINT8(mouse_status, PS2MouseState),
1225 VMSTATE_UINT8(mouse_resolution, PS2MouseState),
1226 VMSTATE_UINT8(mouse_sample_rate, PS2MouseState),
1227 VMSTATE_UINT8(mouse_wrap, PS2MouseState),
1228 VMSTATE_UINT8(mouse_type, PS2MouseState),
1229 VMSTATE_UINT8(mouse_detect_state, PS2MouseState),
1230 VMSTATE_INT32(mouse_dx, PS2MouseState),
1231 VMSTATE_INT32(mouse_dy, PS2MouseState),
1232 VMSTATE_INT32(mouse_dz, PS2MouseState),
1233 VMSTATE_UINT8(mouse_buttons, PS2MouseState),
1234 VMSTATE_END_OF_LIST()
1235 }
1236 };
1237
1238 static const QemuInputHandler ps2_keyboard_handler = {
1239 .name = "QEMU PS/2 Keyboard",
1240 .mask = INPUT_EVENT_MASK_KEY,
1241 .event = ps2_keyboard_event,
1242 };
1243
1244 static void ps2_kbd_realize(DeviceState *dev, Error **errp)
1245 {
1246 PS2State *s = PS2_DEVICE(dev);
1247
1248 s->hs = qemu_input_handler_register(dev, &ps2_keyboard_handler);
1249 }
1250
1251 static void ps2_kbd_unrealize(DeviceState *dev)
1252 {
1253 PS2State *s = PS2_DEVICE(dev);
1254
1255 g_clear_pointer(&s->hs, qemu_input_handler_unregister);
1256 }
1257
1258 static const QemuInputHandler ps2_mouse_handler = {
1259 .name = "QEMU PS/2 Mouse",
1260 .mask = INPUT_EVENT_MASK_BTN | INPUT_EVENT_MASK_REL,
1261 .event = ps2_mouse_event,
1262 .sync = ps2_mouse_sync,
1263 };
1264
1265 static void ps2_mouse_realize(DeviceState *dev, Error **errp)
1266 {
1267 PS2State *s = PS2_DEVICE(dev);
1268
1269 s->hs = qemu_input_handler_register(dev, &ps2_mouse_handler);
1270 }
1271
1272 static void ps2_mouse_unrealize(DeviceState *dev)
1273 {
1274 PS2State *s = PS2_DEVICE(dev);
1275
1276 g_clear_pointer(&s->hs, qemu_input_handler_unregister);
1277 }
1278
1279 static void ps2_kbd_class_init(ObjectClass *klass, const void *data)
1280 {
1281 DeviceClass *dc = DEVICE_CLASS(klass);
1282 ResettableClass *rc = RESETTABLE_CLASS(klass);
1283 PS2DeviceClass *ps2dc = PS2_DEVICE_CLASS(klass);
1284
1285 dc->realize = ps2_kbd_realize;
1286 dc->unrealize = ps2_kbd_unrealize;
1287 resettable_class_set_parent_phases(rc, NULL, ps2_kbd_reset_hold, NULL,
1288 &ps2dc->parent_phases);
1289 dc->vmsd = &vmstate_ps2_keyboard;
1290 }
1291
1292 static const TypeInfo ps2_kbd_info = {
1293 .name = TYPE_PS2_KBD_DEVICE,
1294 .parent = TYPE_PS2_DEVICE,
1295 .instance_size = sizeof(PS2KbdState),
1296 .class_init = ps2_kbd_class_init
1297 };
1298
1299 static void ps2_mouse_class_init(ObjectClass *klass, const void *data)
1300 {
1301 DeviceClass *dc = DEVICE_CLASS(klass);
1302 ResettableClass *rc = RESETTABLE_CLASS(klass);
1303 PS2DeviceClass *ps2dc = PS2_DEVICE_CLASS(klass);
1304
1305 dc->realize = ps2_mouse_realize;
1306 dc->unrealize = ps2_mouse_unrealize;
1307 resettable_class_set_parent_phases(rc, NULL, ps2_mouse_reset_hold, NULL,
1308 &ps2dc->parent_phases);
1309 dc->vmsd = &vmstate_ps2_mouse;
1310 }
1311
1312 static const TypeInfo ps2_mouse_info = {
1313 .name = TYPE_PS2_MOUSE_DEVICE,
1314 .parent = TYPE_PS2_DEVICE,
1315 .instance_size = sizeof(PS2MouseState),
1316 .class_init = ps2_mouse_class_init
1317 };
1318
1319 static void ps2_init(Object *obj)
1320 {
1321 PS2State *s = PS2_DEVICE(obj);
1322
1323 qdev_init_gpio_out(DEVICE(obj), &s->irq, 1);
1324 }
1325
1326 static void ps2_class_init(ObjectClass *klass, const void *data)
1327 {
1328 DeviceClass *dc = DEVICE_CLASS(klass);
1329 ResettableClass *rc = RESETTABLE_CLASS(klass);
1330
1331 rc->phases.hold = ps2_reset_hold;
1332 rc->phases.exit = ps2_reset_exit;
1333 set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
1334 }
1335
1336 static const TypeInfo ps2_info = {
1337 .name = TYPE_PS2_DEVICE,
1338 .parent = TYPE_SYS_BUS_DEVICE,
1339 .instance_init = ps2_init,
1340 .instance_size = sizeof(PS2State),
1341 .class_init = ps2_class_init,
1342 .class_size = sizeof(PS2DeviceClass),
1343 .abstract = true
1344 };
1345
1346 static void ps2_register_types(void)
1347 {
1348 type_register_static(&ps2_info);
1349 type_register_static(&ps2_kbd_info);
1350 type_register_static(&ps2_mouse_info);
1351 }
1352
1353 type_init(ps2_register_types)