]>
git.proxmox.com Git - qemu.git/blob - hw/slavio_serial.c
2 * QEMU Sparc SLAVIO serial port emulation
4 * Copyright (c) 2003-2005 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
26 //#define DEBUG_SERIAL
35 * This is the serial port, mouse and keyboard part of chip STP2001
36 * (Slave I/O), also produced as NCR89C105. See
37 * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR89C105.txt
39 * The serial ports implement full AMD AM8530 or Zilog Z8530 chips,
40 * mouse and keyboard ports don't implement all functions and they are
41 * only asynchronous. There is no DMA.
46 #define SER_DPRINTF(fmt, args...) \
47 do { printf("SER: " fmt , ##args); } while (0)
49 #define SER_DPRINTF(fmt, args...)
52 #define KBD_DPRINTF(fmt, args...) \
53 do { printf("KBD: " fmt , ##args); } while (0)
55 #define KBD_DPRINTF(fmt, args...)
58 #define MS_DPRINTF(fmt, args...) \
59 do { printf("SER: " fmt , ##args); } while (0)
61 #define MS_DPRINTF(fmt, args...)
72 #define KBD_QUEUE_SIZE 256
75 uint8_t data
[KBD_QUEUE_SIZE
];
76 int rptr
, wptr
, count
;
79 typedef struct ChannelState
{
83 chn_id_t chn
; // this channel, A (base+4) or B (base+0)
85 struct ChannelState
*otherchn
;
86 uint8_t rx
, tx
, wregs
[16], rregs
[16];
92 struct ChannelState chn
[2];
95 #define SERIAL_MAXADDR 7
97 static void handle_kbd_command(ChannelState
*s
, int val
);
98 static int serial_can_receive(void *opaque
);
99 static void serial_receive_byte(ChannelState
*s
, int ch
);
101 static void put_queue(void *opaque
, int b
)
103 ChannelState
*s
= opaque
;
104 KBDQueue
*q
= &s
->queue
;
106 KBD_DPRINTF("put: 0x%02x\n", b
);
107 if (q
->count
>= KBD_QUEUE_SIZE
)
109 q
->data
[q
->wptr
] = b
;
110 if (++q
->wptr
== KBD_QUEUE_SIZE
)
113 serial_receive_byte(s
, 0);
116 static uint32_t get_queue(void *opaque
)
118 ChannelState
*s
= opaque
;
119 KBDQueue
*q
= &s
->queue
;
125 val
= q
->data
[q
->rptr
];
126 if (++q
->rptr
== KBD_QUEUE_SIZE
)
130 KBD_DPRINTF("get 0x%02x\n", val
);
132 serial_receive_byte(s
, 0);
136 static void slavio_serial_update_irq(ChannelState
*s
)
138 if ((s
->wregs
[1] & 1) && // interrupts enabled
139 (((s
->wregs
[1] & 2) && s
->txint
== 1) || // tx ints enabled, pending
140 ((((s
->wregs
[1] & 0x18) == 8) || ((s
->wregs
[1] & 0x18) == 0x10)) &&
141 s
->rxint
== 1) || // rx ints enabled, pending
142 ((s
->wregs
[15] & 0x80) && (s
->rregs
[0] & 0x80)))) { // break int e&p
143 pic_set_irq(s
->irq
, 1);
145 pic_set_irq(s
->irq
, 0);
149 static void slavio_serial_reset_chn(ChannelState
*s
)
154 for (i
= 0; i
< SERIAL_MAXADDR
; i
++) {
167 s
->rxint
= s
->txint
= 0;
170 static void slavio_serial_reset(void *opaque
)
172 SerialState
*s
= opaque
;
173 slavio_serial_reset_chn(&s
->chn
[0]);
174 slavio_serial_reset_chn(&s
->chn
[1]);
177 static void slavio_serial_mem_writeb(void *opaque
, target_phys_addr_t addr
, uint32_t val
)
179 SerialState
*ser
= opaque
;
185 saddr
= (addr
& 3) >> 1;
186 channel
= (addr
& SERIAL_MAXADDR
) >> 2;
187 s
= &ser
->chn
[channel
];
190 SER_DPRINTF("Write channel %c, reg[%d] = %2.2x\n", channel
? 'b' : 'a', s
->reg
, val
& 0xff);
212 s
->wregs
[s
->reg
] = val
;
215 switch (val
& 0xc0) {
220 slavio_serial_reset_chn(&ser
->chn
[1]);
223 slavio_serial_reset_chn(&ser
->chn
[0]);
226 slavio_serial_reset(ser
);
239 SER_DPRINTF("Write channel %c, ch %d\n", channel
? 'b' : 'a', val
);
240 if (s
->wregs
[5] & 8) { // tx enabled
243 qemu_chr_write(s
->chr
, &s
->tx
, 1);
244 else if (s
->type
== kbd
) {
245 handle_kbd_command(s
, val
);
249 // Interrupts reported only on channel A
253 s
->otherchn
->rregs
[3] |= 2;
255 slavio_serial_update_irq(s
);
263 static uint32_t slavio_serial_mem_readb(void *opaque
, target_phys_addr_t addr
)
265 SerialState
*ser
= opaque
;
271 saddr
= (addr
& 3) >> 1;
272 channel
= (addr
& SERIAL_MAXADDR
) >> 2;
273 s
= &ser
->chn
[channel
];
276 SER_DPRINTF("Read channel %c, reg[%d] = %2.2x\n", channel
? 'b' : 'a', s
->reg
, s
->rregs
[s
->reg
]);
277 ret
= s
->rregs
[s
->reg
];
281 SER_DPRINTF("Read channel %c, ch %d\n", channel
? 'b' : 'a', s
->rx
);
294 static int serial_can_receive(void *opaque
)
296 ChannelState
*s
= opaque
;
297 if (((s
->wregs
[3] & 1) == 0) // Rx not enabled
298 || ((s
->rregs
[0] & 1) == 1)) // char already available
304 static void serial_receive_byte(ChannelState
*s
, int ch
)
307 // Interrupts reported only on channel A
311 s
->otherchn
->rregs
[3] |= 4;
315 slavio_serial_update_irq(s
);
318 static void serial_receive_break(ChannelState
*s
)
321 slavio_serial_update_irq(s
);
324 static void serial_receive1(void *opaque
, const uint8_t *buf
, int size
)
326 ChannelState
*s
= opaque
;
327 serial_receive_byte(s
, buf
[0]);
330 static void serial_event(void *opaque
, int event
)
332 ChannelState
*s
= opaque
;
333 if (event
== CHR_EVENT_BREAK
)
334 serial_receive_break(s
);
337 static CPUReadMemoryFunc
*slavio_serial_mem_read
[3] = {
338 slavio_serial_mem_readb
,
339 slavio_serial_mem_readb
,
340 slavio_serial_mem_readb
,
343 static CPUWriteMemoryFunc
*slavio_serial_mem_write
[3] = {
344 slavio_serial_mem_writeb
,
345 slavio_serial_mem_writeb
,
346 slavio_serial_mem_writeb
,
349 static void slavio_serial_save_chn(QEMUFile
*f
, ChannelState
*s
)
351 qemu_put_be32s(f
, &s
->irq
);
352 qemu_put_be32s(f
, &s
->reg
);
353 qemu_put_be32s(f
, &s
->rxint
);
354 qemu_put_be32s(f
, &s
->txint
);
355 qemu_put_8s(f
, &s
->rx
);
356 qemu_put_8s(f
, &s
->tx
);
357 qemu_put_buffer(f
, s
->wregs
, 16);
358 qemu_put_buffer(f
, s
->rregs
, 16);
361 static void slavio_serial_save(QEMUFile
*f
, void *opaque
)
363 SerialState
*s
= opaque
;
365 slavio_serial_save_chn(f
, &s
->chn
[0]);
366 slavio_serial_save_chn(f
, &s
->chn
[1]);
369 static int slavio_serial_load_chn(QEMUFile
*f
, ChannelState
*s
, int version_id
)
374 qemu_get_be32s(f
, &s
->irq
);
375 qemu_get_be32s(f
, &s
->reg
);
376 qemu_get_be32s(f
, &s
->rxint
);
377 qemu_get_be32s(f
, &s
->txint
);
378 qemu_get_8s(f
, &s
->rx
);
379 qemu_get_8s(f
, &s
->tx
);
380 qemu_get_buffer(f
, s
->wregs
, 16);
381 qemu_get_buffer(f
, s
->rregs
, 16);
385 static int slavio_serial_load(QEMUFile
*f
, void *opaque
, int version_id
)
387 SerialState
*s
= opaque
;
390 ret
= slavio_serial_load_chn(f
, &s
->chn
[0], version_id
);
393 ret
= slavio_serial_load_chn(f
, &s
->chn
[1], version_id
);
398 SerialState
*slavio_serial_init(int base
, int irq
, CharDriverState
*chr1
, CharDriverState
*chr2
)
400 int slavio_serial_io_memory
, i
;
403 s
= qemu_mallocz(sizeof(SerialState
));
407 slavio_serial_io_memory
= cpu_register_io_memory(0, slavio_serial_mem_read
, slavio_serial_mem_write
, s
);
408 cpu_register_physical_memory(base
, SERIAL_MAXADDR
, slavio_serial_io_memory
);
410 s
->chn
[0].chr
= chr1
;
411 s
->chn
[1].chr
= chr2
;
413 for (i
= 0; i
< 2; i
++) {
415 s
->chn
[i
].chn
= 1 - i
;
416 s
->chn
[i
].type
= ser
;
418 qemu_chr_add_read_handler(s
->chn
[i
].chr
, serial_can_receive
, serial_receive1
, &s
->chn
[i
]);
419 qemu_chr_add_event_handler(s
->chn
[i
].chr
, serial_event
);
422 s
->chn
[0].otherchn
= &s
->chn
[1];
423 s
->chn
[1].otherchn
= &s
->chn
[0];
424 register_savevm("slavio_serial", base
, 1, slavio_serial_save
, slavio_serial_load
, s
);
425 qemu_register_reset(slavio_serial_reset
, s
);
426 slavio_serial_reset(s
);
430 static const uint8_t keycodes
[128] = {
431 127, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 43, 53,
432 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 89, 76, 77, 78,
433 79, 80, 81, 82, 83, 84, 85, 86, 87, 42, 99, 88, 100, 101, 102, 103,
434 104, 105, 106, 107, 108, 109, 110, 47, 19, 121, 119, 5, 6, 8, 10, 12,
435 14, 16, 17, 18, 7, 98, 23, 68, 69, 70, 71, 91, 92, 93, 125, 112,
436 113, 114, 94, 50, 0, 0, 124, 9, 11, 0, 0, 0, 0, 0, 0, 0,
437 90, 0, 46, 22, 13, 111, 52, 20, 96, 24, 28, 74, 27, 123, 44, 66,
438 0, 45, 2, 4, 48, 0, 0, 21, 0, 0, 0, 0, 0, 120, 122, 67,
441 static void sunkbd_event(void *opaque
, int ch
)
443 ChannelState
*s
= opaque
;
444 int release
= ch
& 0x80;
446 ch
= keycodes
[ch
& 0x7f];
447 KBD_DPRINTF("Keycode %d (%s)\n", ch
, release
? "release" : "press");
448 put_queue(s
, ch
| release
);
451 static void handle_kbd_command(ChannelState
*s
, int val
)
453 KBD_DPRINTF("Command %d\n", val
);
455 case 1: // Reset, return type code
458 put_queue(s
, 5); // Type 5
460 case 7: // Query layout
462 put_queue(s
, 0x20); // XXX, layout?
469 static void sunmouse_event(void *opaque
,
470 int dx
, int dy
, int dz
, int buttons_state
)
472 ChannelState
*s
= opaque
;
477 serial_receive_byte(s
, ch
);
480 void slavio_serial_ms_kbd_init(int base
, int irq
)
482 int slavio_serial_io_memory
, i
;
485 s
= qemu_mallocz(sizeof(SerialState
));
488 for (i
= 0; i
< 2; i
++) {
490 s
->chn
[i
].chn
= 1 - i
;
491 s
->chn
[i
].chr
= NULL
;
493 s
->chn
[0].otherchn
= &s
->chn
[1];
494 s
->chn
[1].otherchn
= &s
->chn
[0];
495 s
->chn
[0].type
= mouse
;
496 s
->chn
[1].type
= kbd
;
498 slavio_serial_io_memory
= cpu_register_io_memory(0, slavio_serial_mem_read
, slavio_serial_mem_write
, s
);
499 cpu_register_physical_memory(base
, SERIAL_MAXADDR
, slavio_serial_io_memory
);
501 qemu_add_mouse_event_handler(sunmouse_event
, &s
->chn
[0]);
502 qemu_add_kbd_event_handler(sunkbd_event
, &s
->chn
[1]);
503 qemu_register_reset(slavio_serial_reset
, s
);
504 slavio_serial_reset(s
);