]> Git Repo - qemu.git/blob - hw/slavio_serial.c
Save/load PCI-device, PCI-bus and PIIX3 irq-related state (patches by Uri Lublin.
[qemu.git] / hw / slavio_serial.c
1 /*
2  * QEMU Sparc SLAVIO serial port emulation
3  *
4  * Copyright (c) 2003-2005 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 #include "hw.h"
25 #include "sun4m.h"
26 #include "qemu-char.h"
27 #include "console.h"
28
29 /* debug serial */
30 //#define DEBUG_SERIAL
31
32 /* debug keyboard */
33 //#define DEBUG_KBD
34
35 /* debug mouse */
36 //#define DEBUG_MOUSE
37
38 /*
39  * This is the serial port, mouse and keyboard part of chip STP2001
40  * (Slave I/O), also produced as NCR89C105. See
41  * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR89C105.txt
42  *
43  * The serial ports implement full AMD AM8530 or Zilog Z8530 chips,
44  * mouse and keyboard ports don't implement all functions and they are
45  * only asynchronous. There is no DMA.
46  *
47  */
48
49 /*
50  * Modifications:
51  *  2006-Aug-10  Igor Kovalenko :   Renamed KBDQueue to SERIOQueue, implemented
52  *                                  serial mouse queue.
53  *                                  Implemented serial mouse protocol.
54  */
55
56 #ifdef DEBUG_SERIAL
57 #define SER_DPRINTF(fmt, args...) \
58 do { printf("SER: " fmt , ##args); } while (0)
59 #else
60 #define SER_DPRINTF(fmt, args...)
61 #endif
62 #ifdef DEBUG_KBD
63 #define KBD_DPRINTF(fmt, args...) \
64 do { printf("KBD: " fmt , ##args); } while (0)
65 #else
66 #define KBD_DPRINTF(fmt, args...)
67 #endif
68 #ifdef DEBUG_MOUSE
69 #define MS_DPRINTF(fmt, args...) \
70 do { printf("MSC: " fmt , ##args); } while (0)
71 #else
72 #define MS_DPRINTF(fmt, args...)
73 #endif
74
75 typedef enum {
76     chn_a, chn_b,
77 } chn_id_t;
78
79 #define CHN_C(s) ((s)->chn == chn_b? 'b' : 'a')
80
81 typedef enum {
82     ser, kbd, mouse,
83 } chn_type_t;
84
85 #define SERIO_QUEUE_SIZE 256
86
87 typedef struct {
88     uint8_t data[SERIO_QUEUE_SIZE];
89     int rptr, wptr, count;
90 } SERIOQueue;
91
92 typedef struct ChannelState {
93     qemu_irq irq;
94     int reg;
95     int rxint, txint, rxint_under_svc, txint_under_svc;
96     chn_id_t chn; // this channel, A (base+4) or B (base+0)
97     chn_type_t type;
98     struct ChannelState *otherchn;
99     uint8_t rx, tx, wregs[16], rregs[16];
100     SERIOQueue queue;
101     CharDriverState *chr;
102     int e0_mode, led_mode, caps_lock_mode, num_lock_mode;
103     int disabled;
104 } ChannelState;
105
106 struct SerialState {
107     struct ChannelState chn[2];
108 };
109
110 #define SERIAL_MAXADDR 7
111 #define SERIAL_SIZE (SERIAL_MAXADDR + 1)
112
113 static void handle_kbd_command(ChannelState *s, int val);
114 static int serial_can_receive(void *opaque);
115 static void serial_receive_byte(ChannelState *s, int ch);
116 static inline void set_txint(ChannelState *s);
117
118 static void clear_queue(void *opaque)
119 {
120     ChannelState *s = opaque;
121     SERIOQueue *q = &s->queue;
122     q->rptr = q->wptr = q->count = 0;
123 }
124
125 static void put_queue(void *opaque, int b)
126 {
127     ChannelState *s = opaque;
128     SERIOQueue *q = &s->queue;
129
130     SER_DPRINTF("channel %c put: 0x%02x\n", CHN_C(s), b);
131     if (q->count >= SERIO_QUEUE_SIZE)
132         return;
133     q->data[q->wptr] = b;
134     if (++q->wptr == SERIO_QUEUE_SIZE)
135         q->wptr = 0;
136     q->count++;
137     serial_receive_byte(s, 0);
138 }
139
140 static uint32_t get_queue(void *opaque)
141 {
142     ChannelState *s = opaque;
143     SERIOQueue *q = &s->queue;
144     int val;
145
146     if (q->count == 0) {
147         return 0;
148     } else {
149         val = q->data[q->rptr];
150         if (++q->rptr == SERIO_QUEUE_SIZE)
151             q->rptr = 0;
152         q->count--;
153     }
154     SER_DPRINTF("channel %c get 0x%02x\n", CHN_C(s), val);
155     if (q->count > 0)
156         serial_receive_byte(s, 0);
157     return val;
158 }
159
160 static int slavio_serial_update_irq_chn(ChannelState *s)
161 {
162     if ((s->wregs[1] & 1) && // interrupts enabled
163         (((s->wregs[1] & 2) && s->txint == 1) || // tx ints enabled, pending
164          ((((s->wregs[1] & 0x18) == 8) || ((s->wregs[1] & 0x18) == 0x10)) &&
165           s->rxint == 1) || // rx ints enabled, pending
166          ((s->wregs[15] & 0x80) && (s->rregs[0] & 0x80)))) { // break int e&p
167         return 1;
168     }
169     return 0;
170 }
171
172 static void slavio_serial_update_irq(ChannelState *s)
173 {
174     int irq;
175
176     irq = slavio_serial_update_irq_chn(s);
177     irq |= slavio_serial_update_irq_chn(s->otherchn);
178
179     SER_DPRINTF("IRQ = %d\n", irq);
180     qemu_set_irq(s->irq, irq);
181 }
182
183 static void slavio_serial_reset_chn(ChannelState *s)
184 {
185     int i;
186
187     s->reg = 0;
188     for (i = 0; i < SERIAL_SIZE; i++) {
189         s->rregs[i] = 0;
190         s->wregs[i] = 0;
191     }
192     s->wregs[4] = 4;
193     s->wregs[9] = 0xc0;
194     s->wregs[11] = 8;
195     s->wregs[14] = 0x30;
196     s->wregs[15] = 0xf8;
197     if (s->disabled)
198         s->rregs[0] = 0x7c;
199     else
200         s->rregs[0] = 0x44;
201     s->rregs[1] = 6;
202
203     s->rx = s->tx = 0;
204     s->rxint = s->txint = 0;
205     s->rxint_under_svc = s->txint_under_svc = 0;
206     s->e0_mode = s->led_mode = s->caps_lock_mode = s->num_lock_mode = 0;
207     clear_queue(s);
208 }
209
210 static void slavio_serial_reset(void *opaque)
211 {
212     SerialState *s = opaque;
213     slavio_serial_reset_chn(&s->chn[0]);
214     slavio_serial_reset_chn(&s->chn[1]);
215 }
216
217 static inline void clr_rxint(ChannelState *s)
218 {
219     s->rxint = 0;
220     s->rxint_under_svc = 0;
221     if (s->chn == chn_a) {
222         if (s->wregs[9] & 0x10)
223             s->otherchn->rregs[2] = 0x60;
224         else
225             s->otherchn->rregs[2] = 0x06;
226         s->rregs[3] &= ~0x20;
227     } else {
228         if (s->wregs[9] & 0x10)
229             s->rregs[2] = 0x60;
230         else
231             s->rregs[2] = 0x06;
232         s->otherchn->rregs[3] &= ~4;
233     }
234     if (s->txint)
235         set_txint(s);
236     slavio_serial_update_irq(s);
237 }
238
239 static inline void set_rxint(ChannelState *s)
240 {
241     s->rxint = 1;
242     if (!s->txint_under_svc) {
243         s->rxint_under_svc = 1;
244         if (s->chn == chn_a) {
245             if (s->wregs[9] & 0x10)
246                 s->otherchn->rregs[2] = 0x30;
247             else
248                 s->otherchn->rregs[2] = 0x0c;
249         } else {
250             if (s->wregs[9] & 0x10)
251                 s->rregs[2] = 0x20;
252             else
253                 s->rregs[2] = 0x04;
254         }
255     }
256     if (s->chn == chn_a)
257         s->rregs[3] |= 0x20;
258     else
259         s->otherchn->rregs[3] |= 4;
260     slavio_serial_update_irq(s);
261 }
262
263 static inline void clr_txint(ChannelState *s)
264 {
265     s->txint = 0;
266     s->txint_under_svc = 0;
267     if (s->chn == chn_a) {
268         if (s->wregs[9] & 0x10)
269             s->otherchn->rregs[2] = 0x60;
270         else
271             s->otherchn->rregs[2] = 0x06;
272         s->rregs[3] &= ~0x10;
273     } else {
274         if (s->wregs[9] & 0x10)
275             s->rregs[2] = 0x60;
276         else
277             s->rregs[2] = 0x06;
278         s->otherchn->rregs[3] &= ~2;
279     }
280     if (s->rxint)
281         set_rxint(s);
282     slavio_serial_update_irq(s);
283 }
284
285 static inline void set_txint(ChannelState *s)
286 {
287     s->txint = 1;
288     if (!s->rxint_under_svc) {
289         s->txint_under_svc = 1;
290         if (s->chn == chn_a) {
291             if (s->wregs[9] & 0x10)
292                 s->otherchn->rregs[2] = 0x10;
293             else
294                 s->otherchn->rregs[2] = 0x08;
295         } else {
296             s->rregs[2] = 0;
297         }
298     }
299     if (s->chn == chn_a)
300         s->rregs[3] |= 0x10;
301     else
302         s->otherchn->rregs[3] |= 2;
303     slavio_serial_update_irq(s);
304 }
305
306 static void slavio_serial_update_parameters(ChannelState *s)
307 {
308     int speed, parity, data_bits, stop_bits;
309     QEMUSerialSetParams ssp;
310
311     if (!s->chr || s->type != ser)
312         return;
313
314     if (s->wregs[4] & 1) {
315         if (s->wregs[4] & 2)
316             parity = 'E';
317         else
318             parity = 'O';
319     } else {
320         parity = 'N';
321     }
322     if ((s->wregs[4] & 0x0c) == 0x0c)
323         stop_bits = 2;
324     else
325         stop_bits = 1;
326     switch (s->wregs[5] & 0x60) {
327     case 0x00:
328         data_bits = 5;
329         break;
330     case 0x20:
331         data_bits = 7;
332         break;
333     case 0x40:
334         data_bits = 6;
335         break;
336     default:
337     case 0x60:
338         data_bits = 8;
339         break;
340     }
341     speed = 2457600 / ((s->wregs[12] | (s->wregs[13] << 8)) + 2);
342     switch (s->wregs[4] & 0xc0) {
343     case 0x00:
344         break;
345     case 0x40:
346         speed /= 16;
347         break;
348     case 0x80:
349         speed /= 32;
350         break;
351     default:
352     case 0xc0:
353         speed /= 64;
354         break;
355     }
356     ssp.speed = speed;
357     ssp.parity = parity;
358     ssp.data_bits = data_bits;
359     ssp.stop_bits = stop_bits;
360     SER_DPRINTF("channel %c: speed=%d parity=%c data=%d stop=%d\n", CHN_C(s),
361                 speed, parity, data_bits, stop_bits);
362     qemu_chr_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
363 }
364
365 static void slavio_serial_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
366 {
367     SerialState *serial = opaque;
368     ChannelState *s;
369     uint32_t saddr;
370     int newreg, channel;
371
372     val &= 0xff;
373     saddr = (addr & 3) >> 1;
374     channel = (addr & SERIAL_MAXADDR) >> 2;
375     s = &serial->chn[channel];
376     switch (saddr) {
377     case 0:
378         SER_DPRINTF("Write channel %c, reg[%d] = %2.2x\n", CHN_C(s), s->reg, val & 0xff);
379         newreg = 0;
380         switch (s->reg) {
381         case 0:
382             newreg = val & 7;
383             val &= 0x38;
384             switch (val) {
385             case 8:
386                 newreg |= 0x8;
387                 break;
388             case 0x28:
389                 clr_txint(s);
390                 break;
391             case 0x38:
392                 if (s->rxint_under_svc)
393                     clr_rxint(s);
394                 else if (s->txint_under_svc)
395                     clr_txint(s);
396                 break;
397             default:
398                 break;
399             }
400             break;
401         case 1 ... 3:
402         case 6 ... 8:
403         case 10 ... 11:
404         case 14 ... 15:
405             s->wregs[s->reg] = val;
406             break;
407         case 4:
408         case 5:
409         case 12:
410         case 13:
411             s->wregs[s->reg] = val;
412             slavio_serial_update_parameters(s);
413             break;
414         case 9:
415             switch (val & 0xc0) {
416             case 0:
417             default:
418                 break;
419             case 0x40:
420                 slavio_serial_reset_chn(&serial->chn[1]);
421                 return;
422             case 0x80:
423                 slavio_serial_reset_chn(&serial->chn[0]);
424                 return;
425             case 0xc0:
426                 slavio_serial_reset(serial);
427                 return;
428             }
429             break;
430         default:
431             break;
432         }
433         if (s->reg == 0)
434             s->reg = newreg;
435         else
436             s->reg = 0;
437         break;
438     case 1:
439         SER_DPRINTF("Write channel %c, ch %d\n", CHN_C(s), val);
440         s->tx = val;
441         if (s->wregs[5] & 8) { // tx enabled
442             if (s->chr)
443                 qemu_chr_write(s->chr, &s->tx, 1);
444             else if (s->type == kbd && !s->disabled) {
445                 handle_kbd_command(s, val);
446             }
447         }
448         s->rregs[0] |= 4; // Tx buffer empty
449         s->rregs[1] |= 1; // All sent
450         set_txint(s);
451         break;
452     default:
453         break;
454     }
455 }
456
457 static uint32_t slavio_serial_mem_readb(void *opaque, target_phys_addr_t addr)
458 {
459     SerialState *serial = opaque;
460     ChannelState *s;
461     uint32_t saddr;
462     uint32_t ret;
463     int channel;
464
465     saddr = (addr & 3) >> 1;
466     channel = (addr & SERIAL_MAXADDR) >> 2;
467     s = &serial->chn[channel];
468     switch (saddr) {
469     case 0:
470         SER_DPRINTF("Read channel %c, reg[%d] = %2.2x\n", CHN_C(s), s->reg, s->rregs[s->reg]);
471         ret = s->rregs[s->reg];
472         s->reg = 0;
473         return ret;
474     case 1:
475         s->rregs[0] &= ~1;
476         clr_rxint(s);
477         if (s->type == kbd || s->type == mouse)
478             ret = get_queue(s);
479         else
480             ret = s->rx;
481         SER_DPRINTF("Read channel %c, ch %d\n", CHN_C(s), ret);
482         if (s->chr)
483             qemu_chr_accept_input(s->chr);
484         return ret;
485     default:
486         break;
487     }
488     return 0;
489 }
490
491 static int serial_can_receive(void *opaque)
492 {
493     ChannelState *s = opaque;
494     int ret;
495
496     if (((s->wregs[3] & 1) == 0) // Rx not enabled
497         || ((s->rregs[0] & 1) == 1)) // char already available
498         ret = 0;
499     else
500         ret = 1;
501     //SER_DPRINTF("channel %c can receive %d\n", CHN_C(s), ret);
502     return ret;
503 }
504
505 static void serial_receive_byte(ChannelState *s, int ch)
506 {
507     SER_DPRINTF("channel %c put ch %d\n", CHN_C(s), ch);
508     s->rregs[0] |= 1;
509     s->rx = ch;
510     set_rxint(s);
511 }
512
513 static void serial_receive_break(ChannelState *s)
514 {
515     s->rregs[0] |= 0x80;
516     slavio_serial_update_irq(s);
517 }
518
519 static void serial_receive1(void *opaque, const uint8_t *buf, int size)
520 {
521     ChannelState *s = opaque;
522     serial_receive_byte(s, buf[0]);
523 }
524
525 static void serial_event(void *opaque, int event)
526 {
527     ChannelState *s = opaque;
528     if (event == CHR_EVENT_BREAK)
529         serial_receive_break(s);
530 }
531
532 static CPUReadMemoryFunc *slavio_serial_mem_read[3] = {
533     slavio_serial_mem_readb,
534     slavio_serial_mem_readb,
535     slavio_serial_mem_readb,
536 };
537
538 static CPUWriteMemoryFunc *slavio_serial_mem_write[3] = {
539     slavio_serial_mem_writeb,
540     slavio_serial_mem_writeb,
541     slavio_serial_mem_writeb,
542 };
543
544 static void slavio_serial_save_chn(QEMUFile *f, ChannelState *s)
545 {
546     int tmp;
547     tmp = 0;
548     qemu_put_be32s(f, &tmp); /* unused, was IRQ.  */
549     qemu_put_be32s(f, &s->reg);
550     qemu_put_be32s(f, &s->rxint);
551     qemu_put_be32s(f, &s->txint);
552     qemu_put_be32s(f, &s->rxint_under_svc);
553     qemu_put_be32s(f, &s->txint_under_svc);
554     qemu_put_8s(f, &s->rx);
555     qemu_put_8s(f, &s->tx);
556     qemu_put_buffer(f, s->wregs, 16);
557     qemu_put_buffer(f, s->rregs, 16);
558 }
559
560 static void slavio_serial_save(QEMUFile *f, void *opaque)
561 {
562     SerialState *s = opaque;
563
564     slavio_serial_save_chn(f, &s->chn[0]);
565     slavio_serial_save_chn(f, &s->chn[1]);
566 }
567
568 static int slavio_serial_load_chn(QEMUFile *f, ChannelState *s, int version_id)
569 {
570     int tmp;
571
572     if (version_id > 2)
573         return -EINVAL;
574
575     qemu_get_be32s(f, &tmp); /* unused */
576     qemu_get_be32s(f, &s->reg);
577     qemu_get_be32s(f, &s->rxint);
578     qemu_get_be32s(f, &s->txint);
579     if (version_id >= 2) {
580         qemu_get_be32s(f, &s->rxint_under_svc);
581         qemu_get_be32s(f, &s->txint_under_svc);
582     }
583     qemu_get_8s(f, &s->rx);
584     qemu_get_8s(f, &s->tx);
585     qemu_get_buffer(f, s->wregs, 16);
586     qemu_get_buffer(f, s->rregs, 16);
587     return 0;
588 }
589
590 static int slavio_serial_load(QEMUFile *f, void *opaque, int version_id)
591 {
592     SerialState *s = opaque;
593     int ret;
594
595     ret = slavio_serial_load_chn(f, &s->chn[0], version_id);
596     if (ret != 0)
597         return ret;
598     ret = slavio_serial_load_chn(f, &s->chn[1], version_id);
599     return ret;
600
601 }
602
603 SerialState *slavio_serial_init(target_phys_addr_t base, qemu_irq irq,
604                                 CharDriverState *chr1, CharDriverState *chr2)
605 {
606     int slavio_serial_io_memory, i;
607     SerialState *s;
608
609     s = qemu_mallocz(sizeof(SerialState));
610     if (!s)
611         return NULL;
612
613     slavio_serial_io_memory = cpu_register_io_memory(0, slavio_serial_mem_read, slavio_serial_mem_write, s);
614     cpu_register_physical_memory(base, SERIAL_SIZE, slavio_serial_io_memory);
615
616     s->chn[0].chr = chr1;
617     s->chn[1].chr = chr2;
618     s->chn[0].disabled = 0;
619     s->chn[1].disabled = 0;
620
621     for (i = 0; i < 2; i++) {
622         s->chn[i].irq = irq;
623         s->chn[i].chn = 1 - i;
624         s->chn[i].type = ser;
625         if (s->chn[i].chr) {
626             qemu_chr_add_handlers(s->chn[i].chr, serial_can_receive,
627                                   serial_receive1, serial_event, &s->chn[i]);
628         }
629     }
630     s->chn[0].otherchn = &s->chn[1];
631     s->chn[1].otherchn = &s->chn[0];
632     register_savevm("slavio_serial", base, 2, slavio_serial_save, slavio_serial_load, s);
633     qemu_register_reset(slavio_serial_reset, s);
634     slavio_serial_reset(s);
635     return s;
636 }
637
638 static const uint8_t keycodes[128] = {
639     127, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 43, 53,
640     54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 89, 76, 77, 78,
641     79, 80, 81, 82, 83, 84, 85, 86, 87, 42, 99, 88, 100, 101, 102, 103,
642     104, 105, 106, 107, 108, 109, 110, 47, 19, 121, 119, 5, 6, 8, 10, 12,
643     14, 16, 17, 18, 7, 98, 23, 68, 69, 70, 71, 91, 92, 93, 125, 112,
644     113, 114, 94, 50, 0, 0, 124, 9, 11, 0, 0, 0, 0, 0, 0, 0,
645     90, 0, 46, 22, 13, 111, 52, 20, 96, 24, 28, 74, 27, 123, 44, 66,
646     0, 45, 2, 4, 48, 0, 0, 21, 0, 0, 0, 0, 0, 120, 122, 67,
647 };
648
649 static const uint8_t e0_keycodes[128] = {
650     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
651     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 90, 76, 0, 0,
652     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
653     0, 0, 0, 0, 0, 109, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0,
654     0, 0, 0, 0, 0, 0, 0, 68, 69, 70, 0, 91, 0, 93, 0, 112,
655     113, 114, 94, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
656     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
657     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
658 };
659
660 static void sunkbd_event(void *opaque, int ch)
661 {
662     ChannelState *s = opaque;
663     int release = ch & 0x80;
664
665     KBD_DPRINTF("Untranslated keycode %2.2x (%s)\n", ch, release? "release" : "press");
666     switch (ch) {
667     case 58: // Caps lock press
668         s->caps_lock_mode ^= 1;
669         if (s->caps_lock_mode == 2)
670             return; // Drop second press
671         break;
672     case 69: // Num lock press
673         s->num_lock_mode ^= 1;
674         if (s->num_lock_mode == 2)
675             return; // Drop second press
676         break;
677     case 186: // Caps lock release
678         s->caps_lock_mode ^= 2;
679         if (s->caps_lock_mode == 3)
680             return; // Drop first release
681         break;
682     case 197: // Num lock release
683         s->num_lock_mode ^= 2;
684         if (s->num_lock_mode == 3)
685             return; // Drop first release
686         break;
687     case 0xe0:
688         s->e0_mode = 1;
689         return;
690     default:
691         break;
692     }
693     if (s->e0_mode) {
694         s->e0_mode = 0;
695         ch = e0_keycodes[ch & 0x7f];
696     } else {
697         ch = keycodes[ch & 0x7f];
698     }
699     KBD_DPRINTF("Translated keycode %2.2x\n", ch);
700     put_queue(s, ch | release);
701 }
702
703 static void handle_kbd_command(ChannelState *s, int val)
704 {
705     KBD_DPRINTF("Command %d\n", val);
706     if (s->led_mode) { // Ignore led byte
707         s->led_mode = 0;
708         return;
709     }
710     switch (val) {
711     case 1: // Reset, return type code
712         clear_queue(s);
713         put_queue(s, 0xff);
714         put_queue(s, 4); // Type 4
715         put_queue(s, 0x7f);
716         break;
717     case 0xe: // Set leds
718         s->led_mode = 1;
719         break;
720     case 7: // Query layout
721     case 0xf:
722         clear_queue(s);
723         put_queue(s, 0xfe);
724         put_queue(s, 0); // XXX, layout?
725         break;
726     default:
727         break;
728     }
729 }
730
731 static void sunmouse_event(void *opaque,
732                                int dx, int dy, int dz, int buttons_state)
733 {
734     ChannelState *s = opaque;
735     int ch;
736
737     MS_DPRINTF("dx=%d dy=%d buttons=%01x\n", dx, dy, buttons_state);
738
739     ch = 0x80 | 0x7; /* protocol start byte, no buttons pressed */
740
741     if (buttons_state & MOUSE_EVENT_LBUTTON)
742         ch ^= 0x4;
743     if (buttons_state & MOUSE_EVENT_MBUTTON)
744         ch ^= 0x2;
745     if (buttons_state & MOUSE_EVENT_RBUTTON)
746         ch ^= 0x1;
747
748     put_queue(s, ch);
749
750     ch = dx;
751
752     if (ch > 127)
753         ch=127;
754     else if (ch < -127)
755         ch=-127;
756
757     put_queue(s, ch & 0xff);
758
759     ch = -dy;
760
761     if (ch > 127)
762         ch=127;
763     else if (ch < -127)
764         ch=-127;
765
766     put_queue(s, ch & 0xff);
767
768     // MSC protocol specify two extra motion bytes
769
770     put_queue(s, 0);
771     put_queue(s, 0);
772 }
773
774 void slavio_serial_ms_kbd_init(target_phys_addr_t base, qemu_irq irq,
775                                int disabled)
776 {
777     int slavio_serial_io_memory, i;
778     SerialState *s;
779
780     s = qemu_mallocz(sizeof(SerialState));
781     if (!s)
782         return;
783     for (i = 0; i < 2; i++) {
784         s->chn[i].irq = irq;
785         s->chn[i].chn = 1 - i;
786         s->chn[i].chr = NULL;
787     }
788     s->chn[0].otherchn = &s->chn[1];
789     s->chn[1].otherchn = &s->chn[0];
790     s->chn[0].type = mouse;
791     s->chn[1].type = kbd;
792     s->chn[0].disabled = disabled;
793     s->chn[1].disabled = disabled;
794
795     slavio_serial_io_memory = cpu_register_io_memory(0, slavio_serial_mem_read, slavio_serial_mem_write, s);
796     cpu_register_physical_memory(base, SERIAL_SIZE, slavio_serial_io_memory);
797
798     qemu_add_mouse_event_handler(sunmouse_event, &s->chn[0], 0, "QEMU Sun Mouse");
799     qemu_add_kbd_event_handler(sunkbd_event, &s->chn[1]);
800     register_savevm("slavio_serial_mouse", base, 2, slavio_serial_save, slavio_serial_load, s);
801     qemu_register_reset(slavio_serial_reset, s);
802     slavio_serial_reset(s);
803 }
This page took 0.072082 seconds and 4 git commands to generate.