Commit e7d93956508d86838d508345867ee8d2fe587459

Authored by aurel32
1 parent cf7a2fe2

Add KBD_CMD_SCANCODE command.

(Hervé Poussineau)


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4082 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 34 additions and 5 deletions
hw/ps2.c
@@ -34,6 +34,7 @@ @@ -34,6 +34,7 @@
34 /* Keyboard Commands */ 34 /* Keyboard Commands */
35 #define KBD_CMD_SET_LEDS 0xED /* Set keyboard leds */ 35 #define KBD_CMD_SET_LEDS 0xED /* Set keyboard leds */
36 #define KBD_CMD_ECHO 0xEE 36 #define KBD_CMD_ECHO 0xEE
  37 +#define KBD_CMD_SCANCODE 0xF0 /* Get/set scancode set */
37 #define KBD_CMD_GET_ID 0xF2 /* get keyboard ID */ 38 #define KBD_CMD_GET_ID 0xF2 /* get keyboard ID */
38 #define KBD_CMD_SET_RATE 0xF3 /* Set typematic rate */ 39 #define KBD_CMD_SET_RATE 0xF3 /* Set typematic rate */
39 #define KBD_CMD_ENABLE 0xF4 /* Enable scanning */ 40 #define KBD_CMD_ENABLE 0xF4 /* Enable scanning */
@@ -89,6 +90,7 @@ typedef struct { @@ -89,6 +90,7 @@ typedef struct {
89 conversions we do the translation (if any) in the PS/2 emulation 90 conversions we do the translation (if any) in the PS/2 emulation
90 not the keyboard controller. */ 91 not the keyboard controller. */
91 int translate; 92 int translate;
  93 + int scancode_set; /* 1=XT, 2=AT, 3=PS/2 */
92 } PS2KbdState; 94 } PS2KbdState;
93 95
94 typedef struct { 96 typedef struct {
@@ -131,10 +133,13 @@ void ps2_queue(void *opaque, int b) @@ -131,10 +133,13 @@ void ps2_queue(void *opaque, int b)
131 s->update_irq(s->update_arg, 1); 133 s->update_irq(s->update_arg, 1);
132 } 134 }
133 135
  136 +/* keycode is expressed in scancode set 2 */
134 static void ps2_put_keycode(void *opaque, int keycode) 137 static void ps2_put_keycode(void *opaque, int keycode)
135 { 138 {
136 PS2KbdState *s = opaque; 139 PS2KbdState *s = opaque;
137 - if (!s->translate && keycode < 0xe0) 140 +
  141 + /* XXX: add support for scancode sets 1 and 3 */
  142 + if (!s->translate && keycode < 0xe0 && s->scancode_set == 2)
138 { 143 {
139 if (keycode & 0x80) 144 if (keycode & 0x80)
140 ps2_queue(&s->common, 0xf0); 145 ps2_queue(&s->common, 0xf0);
@@ -174,6 +179,7 @@ uint32_t ps2_read_data(void *opaque) @@ -174,6 +179,7 @@ uint32_t ps2_read_data(void *opaque)
174 static void ps2_reset_keyboard(PS2KbdState *s) 179 static void ps2_reset_keyboard(PS2KbdState *s)
175 { 180 {
176 s->scan_enabled = 1; 181 s->scan_enabled = 1;
  182 + s->scancode_set = 2;
177 } 183 }
178 184
179 void ps2_write_keyboard(void *opaque, int val) 185 void ps2_write_keyboard(void *opaque, int val)
@@ -192,8 +198,9 @@ void ps2_write_keyboard(void *opaque, int val) @@ -192,8 +198,9 @@ void ps2_write_keyboard(void *opaque, int val)
192 break; 198 break;
193 case KBD_CMD_GET_ID: 199 case KBD_CMD_GET_ID:
194 ps2_queue(&s->common, KBD_REPLY_ACK); 200 ps2_queue(&s->common, KBD_REPLY_ACK);
195 - ps2_queue(&s->common, 0xab);  
196 - ps2_queue(&s->common, 0x83); 201 + /* We emulate a MF2 AT keyboard here */
  202 + ps2_put_keycode(s, 0xab);
  203 + ps2_put_keycode(s, 0x83);
197 break; 204 break;
198 case KBD_CMD_ECHO: 205 case KBD_CMD_ECHO:
199 ps2_queue(&s->common, KBD_CMD_ECHO); 206 ps2_queue(&s->common, KBD_CMD_ECHO);
@@ -202,6 +209,7 @@ void ps2_write_keyboard(void *opaque, int val) @@ -202,6 +209,7 @@ void ps2_write_keyboard(void *opaque, int val)
202 s->scan_enabled = 1; 209 s->scan_enabled = 1;
203 ps2_queue(&s->common, KBD_REPLY_ACK); 210 ps2_queue(&s->common, KBD_REPLY_ACK);
204 break; 211 break;
  212 + case KBD_CMD_SCANCODE:
205 case KBD_CMD_SET_LEDS: 213 case KBD_CMD_SET_LEDS:
206 case KBD_CMD_SET_RATE: 214 case KBD_CMD_SET_RATE:
207 s->common.write_cmd = val; 215 s->common.write_cmd = val;
@@ -227,6 +235,21 @@ void ps2_write_keyboard(void *opaque, int val) @@ -227,6 +235,21 @@ void ps2_write_keyboard(void *opaque, int val)
227 break; 235 break;
228 } 236 }
229 break; 237 break;
  238 + case KBD_CMD_SCANCODE:
  239 + if (val == 0) {
  240 + if (s->scancode_set == 1)
  241 + ps2_put_keycode(s, 0x43);
  242 + else if (s->scancode_set == 2)
  243 + ps2_put_keycode(s, 0x41);
  244 + else if (s->scancode_set == 3)
  245 + ps2_put_keycode(s, 0x3f);
  246 + } else {
  247 + if (val >= 1 && val <= 3)
  248 + s->scancode_set = val;
  249 + ps2_queue(&s->common, KBD_REPLY_ACK);
  250 + }
  251 + s->common.write_cmd = -1;
  252 + break;
230 case KBD_CMD_SET_LEDS: 253 case KBD_CMD_SET_LEDS:
231 ps2_queue(&s->common, KBD_REPLY_ACK); 254 ps2_queue(&s->common, KBD_REPLY_ACK);
232 s->common.write_cmd = -1; 255 s->common.write_cmd = -1;
@@ -493,6 +516,7 @@ static void ps2_kbd_save(QEMUFile* f, void* opaque) @@ -493,6 +516,7 @@ static void ps2_kbd_save(QEMUFile* f, void* opaque)
493 ps2_common_save (f, &s->common); 516 ps2_common_save (f, &s->common);
494 qemu_put_be32(f, s->scan_enabled); 517 qemu_put_be32(f, s->scan_enabled);
495 qemu_put_be32(f, s->translate); 518 qemu_put_be32(f, s->translate);
  519 + qemu_put_be32(f, s->scancode_set);
496 } 520 }
497 521
498 static void ps2_mouse_save(QEMUFile* f, void* opaque) 522 static void ps2_mouse_save(QEMUFile* f, void* opaque)
@@ -516,12 +540,16 @@ static int ps2_kbd_load(QEMUFile* f, void* opaque, int version_id) @@ -516,12 +540,16 @@ static int ps2_kbd_load(QEMUFile* f, void* opaque, int version_id)
516 { 540 {
517 PS2KbdState *s = (PS2KbdState*)opaque; 541 PS2KbdState *s = (PS2KbdState*)opaque;
518 542
519 - if (version_id != 2) 543 + if (version_id != 2 && version_id != 3)
520 return -EINVAL; 544 return -EINVAL;
521 545
522 ps2_common_load (f, &s->common); 546 ps2_common_load (f, &s->common);
523 s->scan_enabled=qemu_get_be32(f); 547 s->scan_enabled=qemu_get_be32(f);
524 s->translate=qemu_get_be32(f); 548 s->translate=qemu_get_be32(f);
  549 + if (version_id == 3)
  550 + s->scancode_set=qemu_get_be32(f);
  551 + else
  552 + s->scancode_set=2;
525 return 0; 553 return 0;
526 } 554 }
527 555
@@ -552,8 +580,9 @@ void *ps2_kbd_init(void (*update_irq)(void *, int), void *update_arg) @@ -552,8 +580,9 @@ void *ps2_kbd_init(void (*update_irq)(void *, int), void *update_arg)
552 580
553 s->common.update_irq = update_irq; 581 s->common.update_irq = update_irq;
554 s->common.update_arg = update_arg; 582 s->common.update_arg = update_arg;
  583 + s->scancode_set = 2;
555 ps2_reset(&s->common); 584 ps2_reset(&s->common);
556 - register_savevm("ps2kbd", 0, 2, ps2_kbd_save, ps2_kbd_load, s); 585 + register_savevm("ps2kbd", 0, 3, ps2_kbd_save, ps2_kbd_load, s);
557 qemu_add_kbd_event_handler(ps2_put_keycode, s); 586 qemu_add_kbd_event_handler(ps2_put_keycode, s);
558 qemu_register_reset(ps2_reset, &s->common); 587 qemu_register_reset(ps2_reset, &s->common);
559 return s; 588 return s;