ps2: remove duplicate setting of scancode_set in ps2_kbd_init()
[qemu/armbru.git] / hw / input / ps2.c
blob8018e39b17e59dd05cd6914491e922456f9fa86f
1 /*
2 * QEMU PS/2 keyboard/mouse emulation
4 * Copyright (c) 2003 Fabrice Bellard
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:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
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.
25 #include "qemu/osdep.h"
26 #include "qemu/log.h"
27 #include "hw/sysbus.h"
28 #include "hw/input/ps2.h"
29 #include "migration/vmstate.h"
30 #include "ui/console.h"
31 #include "ui/input.h"
32 #include "sysemu/reset.h"
33 #include "sysemu/runstate.h"
34 #include "qapi/error.h"
36 #include "trace.h"
38 /* Keyboard Commands */
39 #define KBD_CMD_SET_LEDS 0xED /* Set keyboard leds */
40 #define KBD_CMD_ECHO 0xEE
41 #define KBD_CMD_SCANCODE 0xF0 /* Get/set scancode set */
42 #define KBD_CMD_GET_ID 0xF2 /* get keyboard ID */
43 #define KBD_CMD_SET_RATE 0xF3 /* Set typematic rate */
44 #define KBD_CMD_ENABLE 0xF4 /* Enable scanning */
45 #define KBD_CMD_RESET_DISABLE 0xF5 /* reset and disable scanning */
46 #define KBD_CMD_RESET_ENABLE 0xF6 /* reset and enable scanning */
47 #define KBD_CMD_RESET 0xFF /* Reset */
48 #define KBD_CMD_SET_MAKE_BREAK 0xFC /* Set Make and Break mode */
49 #define KBD_CMD_SET_TYPEMATIC 0xFA /* Set Typematic Make and Break mode */
51 /* Keyboard Replies */
52 #define KBD_REPLY_POR 0xAA /* Power on reset */
53 #define KBD_REPLY_ID 0xAB /* Keyboard ID */
54 #define KBD_REPLY_ACK 0xFA /* Command ACK */
55 #define KBD_REPLY_RESEND 0xFE /* Command NACK, send the cmd again */
57 /* Mouse Commands */
58 #define AUX_SET_SCALE11 0xE6 /* Set 1:1 scaling */
59 #define AUX_SET_SCALE21 0xE7 /* Set 2:1 scaling */
60 #define AUX_SET_RES 0xE8 /* Set resolution */
61 #define AUX_GET_SCALE 0xE9 /* Get scaling factor */
62 #define AUX_SET_STREAM 0xEA /* Set stream mode */
63 #define AUX_POLL 0xEB /* Poll */
64 #define AUX_RESET_WRAP 0xEC /* Reset wrap mode */
65 #define AUX_SET_WRAP 0xEE /* Set wrap mode */
66 #define AUX_SET_REMOTE 0xF0 /* Set remote mode */
67 #define AUX_GET_TYPE 0xF2 /* Get type */
68 #define AUX_SET_SAMPLE 0xF3 /* Set sample rate */
69 #define AUX_ENABLE_DEV 0xF4 /* Enable aux device */
70 #define AUX_DISABLE_DEV 0xF5 /* Disable aux device */
71 #define AUX_SET_DEFAULT 0xF6
72 #define AUX_RESET 0xFF /* Reset aux device */
73 #define AUX_ACK 0xFA /* Command byte ACK. */
75 #define MOUSE_STATUS_REMOTE 0x40
76 #define MOUSE_STATUS_ENABLED 0x20
77 #define MOUSE_STATUS_SCALE21 0x10
79 #define PS2_QUEUE_SIZE 16 /* Queue size required by PS/2 protocol */
80 #define PS2_QUEUE_HEADROOM 8 /* Queue size for keyboard command replies */
82 /* Bits for 'modifiers' field in PS2KbdState */
83 #define MOD_CTRL_L (1 << 0)
84 #define MOD_SHIFT_L (1 << 1)
85 #define MOD_ALT_L (1 << 2)
86 #define MOD_CTRL_R (1 << 3)
87 #define MOD_SHIFT_R (1 << 4)
88 #define MOD_ALT_R (1 << 5)
90 static uint8_t translate_table[256] = {
91 0xff, 0x43, 0x41, 0x3f, 0x3d, 0x3b, 0x3c, 0x58,
92 0x64, 0x44, 0x42, 0x40, 0x3e, 0x0f, 0x29, 0x59,
93 0x65, 0x38, 0x2a, 0x70, 0x1d, 0x10, 0x02, 0x5a,
94 0x66, 0x71, 0x2c, 0x1f, 0x1e, 0x11, 0x03, 0x5b,
95 0x67, 0x2e, 0x2d, 0x20, 0x12, 0x05, 0x04, 0x5c,
96 0x68, 0x39, 0x2f, 0x21, 0x14, 0x13, 0x06, 0x5d,
97 0x69, 0x31, 0x30, 0x23, 0x22, 0x15, 0x07, 0x5e,
98 0x6a, 0x72, 0x32, 0x24, 0x16, 0x08, 0x09, 0x5f,
99 0x6b, 0x33, 0x25, 0x17, 0x18, 0x0b, 0x0a, 0x60,
100 0x6c, 0x34, 0x35, 0x26, 0x27, 0x19, 0x0c, 0x61,
101 0x6d, 0x73, 0x28, 0x74, 0x1a, 0x0d, 0x62, 0x6e,
102 0x3a, 0x36, 0x1c, 0x1b, 0x75, 0x2b, 0x63, 0x76,
103 0x55, 0x56, 0x77, 0x78, 0x79, 0x7a, 0x0e, 0x7b,
104 0x7c, 0x4f, 0x7d, 0x4b, 0x47, 0x7e, 0x7f, 0x6f,
105 0x52, 0x53, 0x50, 0x4c, 0x4d, 0x48, 0x01, 0x45,
106 0x57, 0x4e, 0x51, 0x4a, 0x37, 0x49, 0x46, 0x54,
107 0x80, 0x81, 0x82, 0x41, 0x54, 0x85, 0x86, 0x87,
108 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
109 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
110 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
111 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
112 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
113 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
114 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
115 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
116 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
117 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
118 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
119 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
120 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
121 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
122 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
125 static unsigned int ps2_modifier_bit(QKeyCode key)
127 switch (key) {
128 case Q_KEY_CODE_CTRL:
129 return MOD_CTRL_L;
130 case Q_KEY_CODE_CTRL_R:
131 return MOD_CTRL_R;
132 case Q_KEY_CODE_SHIFT:
133 return MOD_SHIFT_L;
134 case Q_KEY_CODE_SHIFT_R:
135 return MOD_SHIFT_R;
136 case Q_KEY_CODE_ALT:
137 return MOD_ALT_L;
138 case Q_KEY_CODE_ALT_R:
139 return MOD_ALT_R;
140 default:
141 return 0;
145 static void ps2_reset_queue(PS2State *s)
147 PS2Queue *q = &s->queue;
149 q->rptr = 0;
150 q->wptr = 0;
151 q->cwptr = -1;
152 q->count = 0;
155 int ps2_queue_empty(PS2State *s)
157 return s->queue.count == 0;
160 void ps2_queue_noirq(PS2State *s, int b)
162 PS2Queue *q = &s->queue;
164 if (q->count >= PS2_QUEUE_SIZE) {
165 return;
168 q->data[q->wptr] = b;
169 if (++q->wptr == PS2_BUFFER_SIZE) {
170 q->wptr = 0;
172 q->count++;
175 void ps2_raise_irq(PS2State *s)
177 s->update_irq(s->update_arg, 1);
180 void ps2_queue(PS2State *s, int b)
182 if (PS2_QUEUE_SIZE - s->queue.count < 1) {
183 return;
186 ps2_queue_noirq(s, b);
187 ps2_raise_irq(s);
190 void ps2_queue_2(PS2State *s, int b1, int b2)
192 if (PS2_QUEUE_SIZE - s->queue.count < 2) {
193 return;
196 ps2_queue_noirq(s, b1);
197 ps2_queue_noirq(s, b2);
198 ps2_raise_irq(s);
201 void ps2_queue_3(PS2State *s, int b1, int b2, int b3)
203 if (PS2_QUEUE_SIZE - s->queue.count < 3) {
204 return;
207 ps2_queue_noirq(s, b1);
208 ps2_queue_noirq(s, b2);
209 ps2_queue_noirq(s, b3);
210 ps2_raise_irq(s);
213 void ps2_queue_4(PS2State *s, int b1, int b2, int b3, int b4)
215 if (PS2_QUEUE_SIZE - s->queue.count < 4) {
216 return;
219 ps2_queue_noirq(s, b1);
220 ps2_queue_noirq(s, b2);
221 ps2_queue_noirq(s, b3);
222 ps2_queue_noirq(s, b4);
223 ps2_raise_irq(s);
226 static void ps2_cqueue_data(PS2Queue *q, int b)
228 q->data[q->cwptr] = b;
229 if (++q->cwptr >= PS2_BUFFER_SIZE) {
230 q->cwptr = 0;
232 q->count++;
235 static void ps2_cqueue_1(PS2State *s, int b1)
237 PS2Queue *q = &s->queue;
239 q->rptr = (q->rptr - 1) & (PS2_BUFFER_SIZE - 1);
240 q->cwptr = q->rptr;
241 ps2_cqueue_data(q, b1);
242 ps2_raise_irq(s);
245 static void ps2_cqueue_2(PS2State *s, int b1, int b2)
247 PS2Queue *q = &s->queue;
249 q->rptr = (q->rptr - 2) & (PS2_BUFFER_SIZE - 1);
250 q->cwptr = q->rptr;
251 ps2_cqueue_data(q, b1);
252 ps2_cqueue_data(q, b2);
253 ps2_raise_irq(s);
256 static void ps2_cqueue_3(PS2State *s, int b1, int b2, int b3)
258 PS2Queue *q = &s->queue;
260 q->rptr = (q->rptr - 3) & (PS2_BUFFER_SIZE - 1);
261 q->cwptr = q->rptr;
262 ps2_cqueue_data(q, b1);
263 ps2_cqueue_data(q, b2);
264 ps2_cqueue_data(q, b3);
265 ps2_raise_irq(s);
268 static void ps2_cqueue_reset(PS2State *s)
270 PS2Queue *q = &s->queue;
271 int ccount;
273 if (q->cwptr == -1) {
274 return;
277 ccount = (q->cwptr - q->rptr) & (PS2_BUFFER_SIZE - 1);
278 q->count -= ccount;
279 q->rptr = q->cwptr;
280 q->cwptr = -1;
283 /* keycode is the untranslated scancode in the current scancode set. */
284 static void ps2_put_keycode(void *opaque, int keycode)
286 PS2KbdState *s = opaque;
287 PS2State *ps = PS2_DEVICE(s);
289 trace_ps2_put_keycode(opaque, keycode);
290 qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER, NULL);
292 if (s->translate) {
293 if (keycode == 0xf0) {
294 s->need_high_bit = true;
295 } else if (s->need_high_bit) {
296 ps2_queue(ps, translate_table[keycode] | 0x80);
297 s->need_high_bit = false;
298 } else {
299 ps2_queue(ps, translate_table[keycode]);
301 } else {
302 ps2_queue(ps, keycode);
306 static void ps2_keyboard_event(DeviceState *dev, QemuConsole *src,
307 InputEvent *evt)
309 PS2KbdState *s = (PS2KbdState *)dev;
310 InputKeyEvent *key = evt->u.key.data;
311 int qcode;
312 uint16_t keycode = 0;
313 int mod;
315 /* do not process events while disabled to prevent stream corruption */
316 if (!s->scan_enabled) {
317 return;
320 qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER, NULL);
321 assert(evt->type == INPUT_EVENT_KIND_KEY);
322 qcode = qemu_input_key_value_to_qcode(key->key);
324 mod = ps2_modifier_bit(qcode);
325 trace_ps2_keyboard_event(s, qcode, key->down, mod,
326 s->modifiers, s->scancode_set, s->translate);
327 if (key->down) {
328 s->modifiers |= mod;
329 } else {
330 s->modifiers &= ~mod;
333 if (s->scancode_set == 1) {
334 if (qcode == Q_KEY_CODE_PAUSE) {
335 if (s->modifiers & (MOD_CTRL_L | MOD_CTRL_R)) {
336 if (key->down) {
337 ps2_put_keycode(s, 0xe0);
338 ps2_put_keycode(s, 0x46);
339 ps2_put_keycode(s, 0xe0);
340 ps2_put_keycode(s, 0xc6);
342 } else {
343 if (key->down) {
344 ps2_put_keycode(s, 0xe1);
345 ps2_put_keycode(s, 0x1d);
346 ps2_put_keycode(s, 0x45);
347 ps2_put_keycode(s, 0xe1);
348 ps2_put_keycode(s, 0x9d);
349 ps2_put_keycode(s, 0xc5);
352 } else if (qcode == Q_KEY_CODE_PRINT) {
353 if (s->modifiers & MOD_ALT_L) {
354 if (key->down) {
355 ps2_put_keycode(s, 0xb8);
356 ps2_put_keycode(s, 0x38);
357 ps2_put_keycode(s, 0x54);
358 } else {
359 ps2_put_keycode(s, 0xd4);
360 ps2_put_keycode(s, 0xb8);
361 ps2_put_keycode(s, 0x38);
363 } else if (s->modifiers & MOD_ALT_R) {
364 if (key->down) {
365 ps2_put_keycode(s, 0xe0);
366 ps2_put_keycode(s, 0xb8);
367 ps2_put_keycode(s, 0xe0);
368 ps2_put_keycode(s, 0x38);
369 ps2_put_keycode(s, 0x54);
370 } else {
371 ps2_put_keycode(s, 0xd4);
372 ps2_put_keycode(s, 0xe0);
373 ps2_put_keycode(s, 0xb8);
374 ps2_put_keycode(s, 0xe0);
375 ps2_put_keycode(s, 0x38);
377 } else if (s->modifiers & (MOD_SHIFT_L | MOD_CTRL_L |
378 MOD_SHIFT_R | MOD_CTRL_R)) {
379 if (key->down) {
380 ps2_put_keycode(s, 0xe0);
381 ps2_put_keycode(s, 0x37);
382 } else {
383 ps2_put_keycode(s, 0xe0);
384 ps2_put_keycode(s, 0xb7);
386 } else {
387 if (key->down) {
388 ps2_put_keycode(s, 0xe0);
389 ps2_put_keycode(s, 0x2a);
390 ps2_put_keycode(s, 0xe0);
391 ps2_put_keycode(s, 0x37);
392 } else {
393 ps2_put_keycode(s, 0xe0);
394 ps2_put_keycode(s, 0xb7);
395 ps2_put_keycode(s, 0xe0);
396 ps2_put_keycode(s, 0xaa);
399 } else {
400 if (qcode < qemu_input_map_qcode_to_atset1_len) {
401 keycode = qemu_input_map_qcode_to_atset1[qcode];
403 if (keycode) {
404 if (keycode & 0xff00) {
405 ps2_put_keycode(s, keycode >> 8);
407 if (!key->down) {
408 keycode |= 0x80;
410 ps2_put_keycode(s, keycode & 0xff);
411 } else {
412 qemu_log_mask(LOG_UNIMP,
413 "ps2: ignoring key with qcode %d\n", qcode);
416 } else if (s->scancode_set == 2) {
417 if (qcode == Q_KEY_CODE_PAUSE) {
418 if (s->modifiers & (MOD_CTRL_L | MOD_CTRL_R)) {
419 if (key->down) {
420 ps2_put_keycode(s, 0xe0);
421 ps2_put_keycode(s, 0x7e);
422 ps2_put_keycode(s, 0xe0);
423 ps2_put_keycode(s, 0xf0);
424 ps2_put_keycode(s, 0x7e);
426 } else {
427 if (key->down) {
428 ps2_put_keycode(s, 0xe1);
429 ps2_put_keycode(s, 0x14);
430 ps2_put_keycode(s, 0x77);
431 ps2_put_keycode(s, 0xe1);
432 ps2_put_keycode(s, 0xf0);
433 ps2_put_keycode(s, 0x14);
434 ps2_put_keycode(s, 0xf0);
435 ps2_put_keycode(s, 0x77);
438 } else if (qcode == Q_KEY_CODE_PRINT) {
439 if (s->modifiers & MOD_ALT_L) {
440 if (key->down) {
441 ps2_put_keycode(s, 0xf0);
442 ps2_put_keycode(s, 0x11);
443 ps2_put_keycode(s, 0x11);
444 ps2_put_keycode(s, 0x84);
445 } else {
446 ps2_put_keycode(s, 0xf0);
447 ps2_put_keycode(s, 0x84);
448 ps2_put_keycode(s, 0xf0);
449 ps2_put_keycode(s, 0x11);
450 ps2_put_keycode(s, 0x11);
452 } else if (s->modifiers & MOD_ALT_R) {
453 if (key->down) {
454 ps2_put_keycode(s, 0xe0);
455 ps2_put_keycode(s, 0xf0);
456 ps2_put_keycode(s, 0x11);
457 ps2_put_keycode(s, 0xe0);
458 ps2_put_keycode(s, 0x11);
459 ps2_put_keycode(s, 0x84);
460 } else {
461 ps2_put_keycode(s, 0xf0);
462 ps2_put_keycode(s, 0x84);
463 ps2_put_keycode(s, 0xe0);
464 ps2_put_keycode(s, 0xf0);
465 ps2_put_keycode(s, 0x11);
466 ps2_put_keycode(s, 0xe0);
467 ps2_put_keycode(s, 0x11);
469 } else if (s->modifiers & (MOD_SHIFT_L | MOD_CTRL_L |
470 MOD_SHIFT_R | MOD_CTRL_R)) {
471 if (key->down) {
472 ps2_put_keycode(s, 0xe0);
473 ps2_put_keycode(s, 0x7c);
474 } else {
475 ps2_put_keycode(s, 0xe0);
476 ps2_put_keycode(s, 0xf0);
477 ps2_put_keycode(s, 0x7c);
479 } else {
480 if (key->down) {
481 ps2_put_keycode(s, 0xe0);
482 ps2_put_keycode(s, 0x12);
483 ps2_put_keycode(s, 0xe0);
484 ps2_put_keycode(s, 0x7c);
485 } else {
486 ps2_put_keycode(s, 0xe0);
487 ps2_put_keycode(s, 0xf0);
488 ps2_put_keycode(s, 0x7c);
489 ps2_put_keycode(s, 0xe0);
490 ps2_put_keycode(s, 0xf0);
491 ps2_put_keycode(s, 0x12);
494 } else {
495 if (qcode < qemu_input_map_qcode_to_atset2_len) {
496 keycode = qemu_input_map_qcode_to_atset2[qcode];
498 if (keycode) {
499 if (keycode & 0xff00) {
500 ps2_put_keycode(s, keycode >> 8);
502 if (!key->down) {
503 ps2_put_keycode(s, 0xf0);
505 ps2_put_keycode(s, keycode & 0xff);
506 } else {
507 qemu_log_mask(LOG_UNIMP,
508 "ps2: ignoring key with qcode %d\n", qcode);
511 } else if (s->scancode_set == 3) {
512 if (qcode < qemu_input_map_qcode_to_atset3_len) {
513 keycode = qemu_input_map_qcode_to_atset3[qcode];
515 if (keycode) {
516 /* FIXME: break code should be configured on a key by key basis */
517 if (!key->down) {
518 ps2_put_keycode(s, 0xf0);
520 ps2_put_keycode(s, keycode);
521 } else {
522 qemu_log_mask(LOG_UNIMP,
523 "ps2: ignoring key with qcode %d\n", qcode);
528 uint32_t ps2_read_data(PS2State *s)
530 PS2Queue *q;
531 int val, index;
533 trace_ps2_read_data(s);
534 q = &s->queue;
535 if (q->count == 0) {
537 * NOTE: if no data left, we return the last keyboard one
538 * (needed for EMM386)
540 /* XXX: need a timer to do things correctly */
541 index = q->rptr - 1;
542 if (index < 0) {
543 index = PS2_BUFFER_SIZE - 1;
545 val = q->data[index];
546 } else {
547 val = q->data[q->rptr];
548 if (++q->rptr == PS2_BUFFER_SIZE) {
549 q->rptr = 0;
551 q->count--;
552 if (q->rptr == q->cwptr) {
553 /* command reply queue is empty */
554 q->cwptr = -1;
556 /* reading deasserts IRQ */
557 s->update_irq(s->update_arg, 0);
558 /* reassert IRQs if data left */
559 if (q->count) {
560 s->update_irq(s->update_arg, 1);
563 return val;
566 static void ps2_set_ledstate(PS2KbdState *s, int ledstate)
568 trace_ps2_set_ledstate(s, ledstate);
569 s->ledstate = ledstate;
570 kbd_put_ledstate(ledstate);
573 static void ps2_reset_keyboard(PS2KbdState *s)
575 PS2State *ps2 = PS2_DEVICE(s);
577 trace_ps2_reset_keyboard(s);
578 s->scan_enabled = 1;
579 s->scancode_set = 2;
580 ps2_reset_queue(ps2);
581 ps2_set_ledstate(s, 0);
584 void ps2_write_keyboard(PS2KbdState *s, int val)
586 PS2State *ps2 = PS2_DEVICE(s);
588 trace_ps2_write_keyboard(s, val);
589 ps2_cqueue_reset(ps2);
590 switch (ps2->write_cmd) {
591 default:
592 case -1:
593 switch (val) {
594 case 0x00:
595 ps2_cqueue_1(ps2, KBD_REPLY_ACK);
596 break;
597 case 0x05:
598 ps2_cqueue_1(ps2, KBD_REPLY_RESEND);
599 break;
600 case KBD_CMD_GET_ID:
601 /* We emulate a MF2 AT keyboard here */
602 ps2_cqueue_3(ps2, KBD_REPLY_ACK, KBD_REPLY_ID,
603 s->translate ? 0x41 : 0x83);
604 break;
605 case KBD_CMD_ECHO:
606 ps2_cqueue_1(ps2, KBD_CMD_ECHO);
607 break;
608 case KBD_CMD_ENABLE:
609 s->scan_enabled = 1;
610 ps2_cqueue_1(ps2, KBD_REPLY_ACK);
611 break;
612 case KBD_CMD_SCANCODE:
613 case KBD_CMD_SET_LEDS:
614 case KBD_CMD_SET_RATE:
615 case KBD_CMD_SET_MAKE_BREAK:
616 ps2->write_cmd = val;
617 ps2_cqueue_1(ps2, KBD_REPLY_ACK);
618 break;
619 case KBD_CMD_RESET_DISABLE:
620 ps2_reset_keyboard(s);
621 s->scan_enabled = 0;
622 ps2_cqueue_1(ps2, KBD_REPLY_ACK);
623 break;
624 case KBD_CMD_RESET_ENABLE:
625 ps2_reset_keyboard(s);
626 s->scan_enabled = 1;
627 ps2_cqueue_1(ps2, KBD_REPLY_ACK);
628 break;
629 case KBD_CMD_RESET:
630 ps2_reset_keyboard(s);
631 ps2_cqueue_2(ps2,
632 KBD_REPLY_ACK,
633 KBD_REPLY_POR);
634 break;
635 case KBD_CMD_SET_TYPEMATIC:
636 ps2_cqueue_1(ps2, KBD_REPLY_ACK);
637 break;
638 default:
639 ps2_cqueue_1(ps2, KBD_REPLY_RESEND);
640 break;
642 break;
643 case KBD_CMD_SET_MAKE_BREAK:
644 ps2_cqueue_1(ps2, KBD_REPLY_ACK);
645 ps2->write_cmd = -1;
646 break;
647 case KBD_CMD_SCANCODE:
648 if (val == 0) {
649 ps2_cqueue_2(ps2, KBD_REPLY_ACK, s->translate ?
650 translate_table[s->scancode_set] : s->scancode_set);
651 } else if (val >= 1 && val <= 3) {
652 s->scancode_set = val;
653 ps2_cqueue_1(ps2, KBD_REPLY_ACK);
654 } else {
655 ps2_cqueue_1(ps2, KBD_REPLY_RESEND);
657 ps2->write_cmd = -1;
658 break;
659 case KBD_CMD_SET_LEDS:
660 ps2_set_ledstate(s, val);
661 ps2_cqueue_1(ps2, KBD_REPLY_ACK);
662 ps2->write_cmd = -1;
663 break;
664 case KBD_CMD_SET_RATE:
665 ps2_cqueue_1(ps2, KBD_REPLY_ACK);
666 ps2->write_cmd = -1;
667 break;
672 * Set the scancode translation mode.
673 * 0 = raw scancodes.
674 * 1 = translated scancodes (used by qemu internally).
677 void ps2_keyboard_set_translation(PS2KbdState *s, int mode)
679 trace_ps2_keyboard_set_translation(s, mode);
680 s->translate = mode;
683 static int ps2_mouse_send_packet(PS2MouseState *s)
685 PS2State *ps2 = PS2_DEVICE(s);
686 /* IMPS/2 and IMEX send 4 bytes, PS2 sends 3 bytes */
687 const int needed = s->mouse_type ? 4 : 3;
688 unsigned int b;
689 int dx1, dy1, dz1, dw1;
691 if (PS2_QUEUE_SIZE - ps2->queue.count < needed) {
692 return 0;
695 dx1 = s->mouse_dx;
696 dy1 = s->mouse_dy;
697 dz1 = s->mouse_dz;
698 dw1 = s->mouse_dw;
699 /* XXX: increase range to 8 bits ? */
700 if (dx1 > 127) {
701 dx1 = 127;
702 } else if (dx1 < -127) {
703 dx1 = -127;
705 if (dy1 > 127) {
706 dy1 = 127;
707 } else if (dy1 < -127) {
708 dy1 = -127;
710 b = 0x08 | ((dx1 < 0) << 4) | ((dy1 < 0) << 5) | (s->mouse_buttons & 0x07);
711 ps2_queue_noirq(ps2, b);
712 ps2_queue_noirq(ps2, dx1 & 0xff);
713 ps2_queue_noirq(ps2, dy1 & 0xff);
714 /* extra byte for IMPS/2 or IMEX */
715 switch (s->mouse_type) {
716 default:
717 /* Just ignore the wheels if not supported */
718 s->mouse_dz = 0;
719 s->mouse_dw = 0;
720 break;
721 case 3:
722 if (dz1 > 127) {
723 dz1 = 127;
724 } else if (dz1 < -127) {
725 dz1 = -127;
727 ps2_queue_noirq(ps2, dz1 & 0xff);
728 s->mouse_dz -= dz1;
729 s->mouse_dw = 0;
730 break;
731 case 4:
733 * This matches what the Linux kernel expects for exps/2 in
734 * drivers/input/mouse/psmouse-base.c. Note, if you happen to
735 * press/release the 4th or 5th buttons at the same moment as a
736 * horizontal wheel scroll, those button presses will get lost. I'm not
737 * sure what to do about that, since by this point we don't know
738 * whether those buttons actually changed state.
740 if (dw1 != 0) {
741 if (dw1 > 31) {
742 dw1 = 31;
743 } else if (dw1 < -31) {
744 dw1 = -31;
748 * linux kernel expects first 6 bits to represent the value
749 * for horizontal scroll
751 b = (dw1 & 0x3f) | 0x40;
752 s->mouse_dw -= dw1;
753 } else {
754 if (dz1 > 7) {
755 dz1 = 7;
756 } else if (dz1 < -7) {
757 dz1 = -7;
760 b = (dz1 & 0x0f) | ((s->mouse_buttons & 0x18) << 1);
761 s->mouse_dz -= dz1;
763 ps2_queue_noirq(ps2, b);
764 break;
767 ps2_raise_irq(ps2);
769 trace_ps2_mouse_send_packet(s, dx1, dy1, dz1, b);
770 /* update deltas */
771 s->mouse_dx -= dx1;
772 s->mouse_dy -= dy1;
774 return 1;
777 static void ps2_mouse_event(DeviceState *dev, QemuConsole *src,
778 InputEvent *evt)
780 static const int bmap[INPUT_BUTTON__MAX] = {
781 [INPUT_BUTTON_LEFT] = PS2_MOUSE_BUTTON_LEFT,
782 [INPUT_BUTTON_MIDDLE] = PS2_MOUSE_BUTTON_MIDDLE,
783 [INPUT_BUTTON_RIGHT] = PS2_MOUSE_BUTTON_RIGHT,
784 [INPUT_BUTTON_SIDE] = PS2_MOUSE_BUTTON_SIDE,
785 [INPUT_BUTTON_EXTRA] = PS2_MOUSE_BUTTON_EXTRA,
787 PS2MouseState *s = (PS2MouseState *)dev;
788 InputMoveEvent *move;
789 InputBtnEvent *btn;
791 /* check if deltas are recorded when disabled */
792 if (!(s->mouse_status & MOUSE_STATUS_ENABLED)) {
793 return;
796 switch (evt->type) {
797 case INPUT_EVENT_KIND_REL:
798 move = evt->u.rel.data;
799 if (move->axis == INPUT_AXIS_X) {
800 s->mouse_dx += move->value;
801 } else if (move->axis == INPUT_AXIS_Y) {
802 s->mouse_dy -= move->value;
804 break;
806 case INPUT_EVENT_KIND_BTN:
807 btn = evt->u.btn.data;
808 if (btn->down) {
809 s->mouse_buttons |= bmap[btn->button];
810 if (btn->button == INPUT_BUTTON_WHEEL_UP) {
811 s->mouse_dz--;
812 } else if (btn->button == INPUT_BUTTON_WHEEL_DOWN) {
813 s->mouse_dz++;
816 if (btn->button == INPUT_BUTTON_WHEEL_RIGHT) {
817 s->mouse_dw--;
818 } else if (btn->button == INPUT_BUTTON_WHEEL_LEFT) {
819 s->mouse_dw++;
821 } else {
822 s->mouse_buttons &= ~bmap[btn->button];
824 break;
826 default:
827 /* keep gcc happy */
828 break;
832 static void ps2_mouse_sync(DeviceState *dev)
834 PS2MouseState *s = (PS2MouseState *)dev;
836 /* do not sync while disabled to prevent stream corruption */
837 if (!(s->mouse_status & MOUSE_STATUS_ENABLED)) {
838 return;
841 if (s->mouse_buttons) {
842 qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER, NULL);
844 if (!(s->mouse_status & MOUSE_STATUS_REMOTE)) {
846 * if not remote, send event. Multiple events are sent if
847 * too big deltas
849 while (ps2_mouse_send_packet(s)) {
850 if (s->mouse_dx == 0 && s->mouse_dy == 0
851 && s->mouse_dz == 0 && s->mouse_dw == 0) {
852 break;
858 void ps2_mouse_fake_event(PS2MouseState *s)
860 trace_ps2_mouse_fake_event(s);
861 s->mouse_dx++;
862 ps2_mouse_sync(DEVICE(s));
865 void ps2_write_mouse(PS2MouseState *s, int val)
867 PS2State *ps2 = PS2_DEVICE(s);
869 trace_ps2_write_mouse(s, val);
870 switch (ps2->write_cmd) {
871 default:
872 case -1:
873 /* mouse command */
874 if (s->mouse_wrap) {
875 if (val == AUX_RESET_WRAP) {
876 s->mouse_wrap = 0;
877 ps2_queue(ps2, AUX_ACK);
878 return;
879 } else if (val != AUX_RESET) {
880 ps2_queue(ps2, val);
881 return;
884 switch (val) {
885 case AUX_SET_SCALE11:
886 s->mouse_status &= ~MOUSE_STATUS_SCALE21;
887 ps2_queue(ps2, AUX_ACK);
888 break;
889 case AUX_SET_SCALE21:
890 s->mouse_status |= MOUSE_STATUS_SCALE21;
891 ps2_queue(ps2, AUX_ACK);
892 break;
893 case AUX_SET_STREAM:
894 s->mouse_status &= ~MOUSE_STATUS_REMOTE;
895 ps2_queue(ps2, AUX_ACK);
896 break;
897 case AUX_SET_WRAP:
898 s->mouse_wrap = 1;
899 ps2_queue(ps2, AUX_ACK);
900 break;
901 case AUX_SET_REMOTE:
902 s->mouse_status |= MOUSE_STATUS_REMOTE;
903 ps2_queue(ps2, AUX_ACK);
904 break;
905 case AUX_GET_TYPE:
906 ps2_queue_2(ps2,
907 AUX_ACK,
908 s->mouse_type);
909 break;
910 case AUX_SET_RES:
911 case AUX_SET_SAMPLE:
912 ps2->write_cmd = val;
913 ps2_queue(ps2, AUX_ACK);
914 break;
915 case AUX_GET_SCALE:
916 ps2_queue_4(ps2,
917 AUX_ACK,
918 s->mouse_status,
919 s->mouse_resolution,
920 s->mouse_sample_rate);
921 break;
922 case AUX_POLL:
923 ps2_queue(ps2, AUX_ACK);
924 ps2_mouse_send_packet(s);
925 break;
926 case AUX_ENABLE_DEV:
927 s->mouse_status |= MOUSE_STATUS_ENABLED;
928 ps2_queue(ps2, AUX_ACK);
929 break;
930 case AUX_DISABLE_DEV:
931 s->mouse_status &= ~MOUSE_STATUS_ENABLED;
932 ps2_queue(ps2, AUX_ACK);
933 break;
934 case AUX_SET_DEFAULT:
935 s->mouse_sample_rate = 100;
936 s->mouse_resolution = 2;
937 s->mouse_status = 0;
938 ps2_queue(ps2, AUX_ACK);
939 break;
940 case AUX_RESET:
941 s->mouse_sample_rate = 100;
942 s->mouse_resolution = 2;
943 s->mouse_status = 0;
944 s->mouse_type = 0;
945 ps2_reset_queue(ps2);
946 ps2_queue_3(ps2,
947 AUX_ACK,
948 0xaa,
949 s->mouse_type);
950 break;
951 default:
952 break;
954 break;
955 case AUX_SET_SAMPLE:
956 s->mouse_sample_rate = val;
957 /* detect IMPS/2 or IMEX */
958 switch (s->mouse_detect_state) {
959 default:
960 case 0:
961 if (val == 200) {
962 s->mouse_detect_state = 1;
964 break;
965 case 1:
966 if (val == 100) {
967 s->mouse_detect_state = 2;
968 } else if (val == 200) {
969 s->mouse_detect_state = 3;
970 } else {
971 s->mouse_detect_state = 0;
973 break;
974 case 2:
975 if (val == 80) {
976 s->mouse_type = 3; /* IMPS/2 */
978 s->mouse_detect_state = 0;
979 break;
980 case 3:
981 if (val == 80) {
982 s->mouse_type = 4; /* IMEX */
984 s->mouse_detect_state = 0;
985 break;
987 ps2_queue(ps2, AUX_ACK);
988 ps2->write_cmd = -1;
989 break;
990 case AUX_SET_RES:
991 s->mouse_resolution = val;
992 ps2_queue(ps2, AUX_ACK);
993 ps2->write_cmd = -1;
994 break;
998 static void ps2_reset(DeviceState *dev)
1000 PS2State *s = PS2_DEVICE(dev);
1002 s->write_cmd = -1;
1003 ps2_reset_queue(s);
1004 s->update_irq(s->update_arg, 0);
1007 static void ps2_common_post_load(PS2State *s)
1009 PS2Queue *q = &s->queue;
1010 int ccount = 0;
1012 /* limit the number of queued command replies to PS2_QUEUE_HEADROOM */
1013 if (q->cwptr != -1) {
1014 ccount = (q->cwptr - q->rptr) & (PS2_BUFFER_SIZE - 1);
1015 if (ccount > PS2_QUEUE_HEADROOM) {
1016 ccount = PS2_QUEUE_HEADROOM;
1020 /* limit the scancode queue size to PS2_QUEUE_SIZE */
1021 if (q->count < ccount) {
1022 q->count = ccount;
1023 } else if (q->count > ccount + PS2_QUEUE_SIZE) {
1024 q->count = ccount + PS2_QUEUE_SIZE;
1027 /* sanitize rptr and recalculate wptr and cwptr */
1028 q->rptr = q->rptr & (PS2_BUFFER_SIZE - 1);
1029 q->wptr = (q->rptr + q->count) & (PS2_BUFFER_SIZE - 1);
1030 q->cwptr = ccount ? (q->rptr + ccount) & (PS2_BUFFER_SIZE - 1) : -1;
1033 static void ps2_kbd_reset(DeviceState *dev)
1035 PS2DeviceClass *ps2dc = PS2_DEVICE_GET_CLASS(dev);
1036 PS2KbdState *s = PS2_KBD_DEVICE(dev);
1038 trace_ps2_kbd_reset(s);
1039 ps2dc->parent_reset(dev);
1041 s->scan_enabled = 1;
1042 s->translate = 0;
1043 s->scancode_set = 2;
1044 s->modifiers = 0;
1047 static void ps2_mouse_reset(DeviceState *dev)
1049 PS2DeviceClass *ps2dc = PS2_DEVICE_GET_CLASS(dev);
1050 PS2MouseState *s = PS2_MOUSE_DEVICE(dev);
1052 trace_ps2_mouse_reset(s);
1053 ps2dc->parent_reset(dev);
1055 s->mouse_status = 0;
1056 s->mouse_resolution = 0;
1057 s->mouse_sample_rate = 0;
1058 s->mouse_wrap = 0;
1059 s->mouse_type = 0;
1060 s->mouse_detect_state = 0;
1061 s->mouse_dx = 0;
1062 s->mouse_dy = 0;
1063 s->mouse_dz = 0;
1064 s->mouse_dw = 0;
1065 s->mouse_buttons = 0;
1068 static const VMStateDescription vmstate_ps2_common = {
1069 .name = "PS2 Common State",
1070 .version_id = 3,
1071 .minimum_version_id = 2,
1072 .fields = (VMStateField[]) {
1073 VMSTATE_INT32(write_cmd, PS2State),
1074 VMSTATE_INT32(queue.rptr, PS2State),
1075 VMSTATE_INT32(queue.wptr, PS2State),
1076 VMSTATE_INT32(queue.count, PS2State),
1077 VMSTATE_BUFFER(queue.data, PS2State),
1078 VMSTATE_END_OF_LIST()
1082 static bool ps2_keyboard_ledstate_needed(void *opaque)
1084 PS2KbdState *s = opaque;
1086 return s->ledstate != 0; /* 0 is default state */
1089 static int ps2_kbd_ledstate_post_load(void *opaque, int version_id)
1091 PS2KbdState *s = opaque;
1093 kbd_put_ledstate(s->ledstate);
1094 return 0;
1097 static const VMStateDescription vmstate_ps2_keyboard_ledstate = {
1098 .name = "ps2kbd/ledstate",
1099 .version_id = 3,
1100 .minimum_version_id = 2,
1101 .post_load = ps2_kbd_ledstate_post_load,
1102 .needed = ps2_keyboard_ledstate_needed,
1103 .fields = (VMStateField[]) {
1104 VMSTATE_INT32(ledstate, PS2KbdState),
1105 VMSTATE_END_OF_LIST()
1109 static bool ps2_keyboard_need_high_bit_needed(void *opaque)
1111 PS2KbdState *s = opaque;
1112 return s->need_high_bit != 0; /* 0 is the usual state */
1115 static const VMStateDescription vmstate_ps2_keyboard_need_high_bit = {
1116 .name = "ps2kbd/need_high_bit",
1117 .version_id = 1,
1118 .minimum_version_id = 1,
1119 .needed = ps2_keyboard_need_high_bit_needed,
1120 .fields = (VMStateField[]) {
1121 VMSTATE_BOOL(need_high_bit, PS2KbdState),
1122 VMSTATE_END_OF_LIST()
1126 static bool ps2_keyboard_cqueue_needed(void *opaque)
1128 PS2KbdState *s = opaque;
1129 PS2State *ps2 = PS2_DEVICE(s);
1131 return ps2->queue.cwptr != -1; /* the queue is mostly empty */
1134 static const VMStateDescription vmstate_ps2_keyboard_cqueue = {
1135 .name = "ps2kbd/command_reply_queue",
1136 .needed = ps2_keyboard_cqueue_needed,
1137 .fields = (VMStateField[]) {
1138 VMSTATE_INT32(parent_obj.queue.cwptr, PS2KbdState),
1139 VMSTATE_END_OF_LIST()
1143 static int ps2_kbd_post_load(void *opaque, int version_id)
1145 PS2KbdState *s = (PS2KbdState *)opaque;
1146 PS2State *ps2 = PS2_DEVICE(s);
1148 if (version_id == 2) {
1149 s->scancode_set = 2;
1152 ps2_common_post_load(ps2);
1154 return 0;
1157 static const VMStateDescription vmstate_ps2_keyboard = {
1158 .name = "ps2kbd",
1159 .version_id = 3,
1160 .minimum_version_id = 2,
1161 .post_load = ps2_kbd_post_load,
1162 .fields = (VMStateField[]) {
1163 VMSTATE_STRUCT(parent_obj, PS2KbdState, 0, vmstate_ps2_common,
1164 PS2State),
1165 VMSTATE_INT32(scan_enabled, PS2KbdState),
1166 VMSTATE_INT32(translate, PS2KbdState),
1167 VMSTATE_INT32_V(scancode_set, PS2KbdState, 3),
1168 VMSTATE_END_OF_LIST()
1170 .subsections = (const VMStateDescription * []) {
1171 &vmstate_ps2_keyboard_ledstate,
1172 &vmstate_ps2_keyboard_need_high_bit,
1173 &vmstate_ps2_keyboard_cqueue,
1174 NULL
1178 static int ps2_mouse_post_load(void *opaque, int version_id)
1180 PS2MouseState *s = (PS2MouseState *)opaque;
1181 PS2State *ps2 = PS2_DEVICE(s);
1183 ps2_common_post_load(ps2);
1185 return 0;
1188 static const VMStateDescription vmstate_ps2_mouse = {
1189 .name = "ps2mouse",
1190 .version_id = 2,
1191 .minimum_version_id = 2,
1192 .post_load = ps2_mouse_post_load,
1193 .fields = (VMStateField[]) {
1194 VMSTATE_STRUCT(parent_obj, PS2MouseState, 0, vmstate_ps2_common,
1195 PS2State),
1196 VMSTATE_UINT8(mouse_status, PS2MouseState),
1197 VMSTATE_UINT8(mouse_resolution, PS2MouseState),
1198 VMSTATE_UINT8(mouse_sample_rate, PS2MouseState),
1199 VMSTATE_UINT8(mouse_wrap, PS2MouseState),
1200 VMSTATE_UINT8(mouse_type, PS2MouseState),
1201 VMSTATE_UINT8(mouse_detect_state, PS2MouseState),
1202 VMSTATE_INT32(mouse_dx, PS2MouseState),
1203 VMSTATE_INT32(mouse_dy, PS2MouseState),
1204 VMSTATE_INT32(mouse_dz, PS2MouseState),
1205 VMSTATE_UINT8(mouse_buttons, PS2MouseState),
1206 VMSTATE_END_OF_LIST()
1210 static QemuInputHandler ps2_keyboard_handler = {
1211 .name = "QEMU PS/2 Keyboard",
1212 .mask = INPUT_EVENT_MASK_KEY,
1213 .event = ps2_keyboard_event,
1216 void *ps2_kbd_init(void (*update_irq)(void *, int), void *update_arg)
1218 DeviceState *dev;
1219 PS2KbdState *s;
1220 PS2State *ps2;
1222 dev = qdev_new(TYPE_PS2_KBD_DEVICE);
1223 sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
1224 s = PS2_KBD_DEVICE(dev);
1225 ps2 = PS2_DEVICE(s);
1227 trace_ps2_kbd_init(s);
1228 ps2->update_irq = update_irq;
1229 ps2->update_arg = update_arg;
1230 vmstate_register(NULL, 0, &vmstate_ps2_keyboard, s);
1231 qemu_input_handler_register((DeviceState *)s,
1232 &ps2_keyboard_handler);
1233 return s;
1236 static QemuInputHandler ps2_mouse_handler = {
1237 .name = "QEMU PS/2 Mouse",
1238 .mask = INPUT_EVENT_MASK_BTN | INPUT_EVENT_MASK_REL,
1239 .event = ps2_mouse_event,
1240 .sync = ps2_mouse_sync,
1243 void *ps2_mouse_init(void (*update_irq)(void *, int), void *update_arg)
1245 DeviceState *dev;
1246 PS2MouseState *s;
1247 PS2State *ps2;
1249 dev = qdev_new(TYPE_PS2_MOUSE_DEVICE);
1250 sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
1251 s = PS2_MOUSE_DEVICE(dev);
1252 ps2 = PS2_DEVICE(s);
1254 trace_ps2_mouse_init(s);
1255 ps2->update_irq = update_irq;
1256 ps2->update_arg = update_arg;
1257 vmstate_register(NULL, 0, &vmstate_ps2_mouse, s);
1258 qemu_input_handler_register((DeviceState *)s,
1259 &ps2_mouse_handler);
1260 return s;
1263 static void ps2_kbd_class_init(ObjectClass *klass, void *data)
1265 DeviceClass *dc = DEVICE_CLASS(klass);
1266 PS2DeviceClass *ps2dc = PS2_DEVICE_CLASS(klass);
1268 device_class_set_parent_reset(dc, ps2_kbd_reset, &ps2dc->parent_reset);
1271 static const TypeInfo ps2_kbd_info = {
1272 .name = TYPE_PS2_KBD_DEVICE,
1273 .parent = TYPE_PS2_DEVICE,
1274 .instance_size = sizeof(PS2KbdState),
1275 .class_init = ps2_kbd_class_init
1278 static void ps2_mouse_class_init(ObjectClass *klass, void *data)
1280 DeviceClass *dc = DEVICE_CLASS(klass);
1281 PS2DeviceClass *ps2dc = PS2_DEVICE_CLASS(klass);
1283 device_class_set_parent_reset(dc, ps2_mouse_reset,
1284 &ps2dc->parent_reset);
1287 static const TypeInfo ps2_mouse_info = {
1288 .name = TYPE_PS2_MOUSE_DEVICE,
1289 .parent = TYPE_PS2_DEVICE,
1290 .instance_size = sizeof(PS2MouseState),
1291 .class_init = ps2_mouse_class_init
1294 static void ps2_class_init(ObjectClass *klass, void *data)
1296 DeviceClass *dc = DEVICE_CLASS(klass);
1298 dc->reset = ps2_reset;
1299 set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
1302 static const TypeInfo ps2_info = {
1303 .name = TYPE_PS2_DEVICE,
1304 .parent = TYPE_SYS_BUS_DEVICE,
1305 .instance_size = sizeof(PS2State),
1306 .class_init = ps2_class_init,
1307 .class_size = sizeof(PS2DeviceClass),
1308 .abstract = true
1311 static void ps2_register_types(void)
1313 type_register_static(&ps2_info);
1314 type_register_static(&ps2_kbd_info);
1315 type_register_static(&ps2_mouse_info);
1318 type_init(ps2_register_types)