]> git.proxmox.com Git - qemu.git/blob - hw/slavio_serial.c
new bochs BIOS - 16 bit APM support (initial patch by Struan Bartlett)
[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 "vl.h"
25 /* debug serial */
26 //#define DEBUG_SERIAL
27
28 /* debug keyboard */
29 //#define DEBUG_KBD
30
31 /* debug mouse */
32 //#define DEBUG_MOUSE
33
34 /*
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
38 *
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.
42 *
43 */
44
45 #ifdef DEBUG_SERIAL
46 #define SER_DPRINTF(fmt, args...) \
47 do { printf("SER: " fmt , ##args); } while (0)
48 #else
49 #define SER_DPRINTF(fmt, args...)
50 #endif
51 #ifdef DEBUG_KBD
52 #define KBD_DPRINTF(fmt, args...) \
53 do { printf("KBD: " fmt , ##args); } while (0)
54 #else
55 #define KBD_DPRINTF(fmt, args...)
56 #endif
57 #ifdef DEBUG_MOUSE
58 #define MS_DPRINTF(fmt, args...) \
59 do { printf("SER: " fmt , ##args); } while (0)
60 #else
61 #define MS_DPRINTF(fmt, args...)
62 #endif
63
64 typedef enum {
65 chn_a, chn_b,
66 } chn_id_t;
67
68 typedef enum {
69 ser, kbd, mouse,
70 } chn_type_t;
71
72 #define KBD_QUEUE_SIZE 256
73
74 typedef struct {
75 uint8_t data[KBD_QUEUE_SIZE];
76 int rptr, wptr, count;
77 } KBDQueue;
78
79 typedef struct ChannelState {
80 int irq;
81 int reg;
82 int rxint, txint;
83 chn_id_t chn; // this channel, A (base+4) or B (base+0)
84 chn_type_t type;
85 struct ChannelState *otherchn;
86 uint8_t rx, tx, wregs[16], rregs[16];
87 KBDQueue queue;
88 CharDriverState *chr;
89 } ChannelState;
90
91 struct SerialState {
92 struct ChannelState chn[2];
93 };
94
95 #define SERIAL_MAXADDR 7
96
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);
100
101 static void put_queue(void *opaque, int b)
102 {
103 ChannelState *s = opaque;
104 KBDQueue *q = &s->queue;
105
106 KBD_DPRINTF("put: 0x%02x\n", b);
107 if (q->count >= KBD_QUEUE_SIZE)
108 return;
109 q->data[q->wptr] = b;
110 if (++q->wptr == KBD_QUEUE_SIZE)
111 q->wptr = 0;
112 q->count++;
113 serial_receive_byte(s, 0);
114 }
115
116 static uint32_t get_queue(void *opaque)
117 {
118 ChannelState *s = opaque;
119 KBDQueue *q = &s->queue;
120 int val;
121
122 if (q->count == 0) {
123 return 0;
124 } else {
125 val = q->data[q->rptr];
126 if (++q->rptr == KBD_QUEUE_SIZE)
127 q->rptr = 0;
128 q->count--;
129 }
130 KBD_DPRINTF("get 0x%02x\n", val);
131 if (q->count > 0)
132 serial_receive_byte(s, 0);
133 return val;
134 }
135
136 static void slavio_serial_update_irq(ChannelState *s)
137 {
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);
144 } else {
145 pic_set_irq(s->irq, 0);
146 }
147 }
148
149 static void slavio_serial_reset_chn(ChannelState *s)
150 {
151 int i;
152
153 s->reg = 0;
154 for (i = 0; i < SERIAL_MAXADDR; i++) {
155 s->rregs[i] = 0;
156 s->wregs[i] = 0;
157 }
158 s->wregs[4] = 4;
159 s->wregs[9] = 0xc0;
160 s->wregs[11] = 8;
161 s->wregs[14] = 0x30;
162 s->wregs[15] = 0xf8;
163 s->rregs[0] = 0x44;
164 s->rregs[1] = 6;
165
166 s->rx = s->tx = 0;
167 s->rxint = s->txint = 0;
168 }
169
170 static void slavio_serial_reset(void *opaque)
171 {
172 SerialState *s = opaque;
173 slavio_serial_reset_chn(&s->chn[0]);
174 slavio_serial_reset_chn(&s->chn[1]);
175 }
176
177 static void slavio_serial_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
178 {
179 SerialState *ser = opaque;
180 ChannelState *s;
181 uint32_t saddr;
182 int newreg, channel;
183
184 val &= 0xff;
185 saddr = (addr & 3) >> 1;
186 channel = (addr & SERIAL_MAXADDR) >> 2;
187 s = &ser->chn[channel];
188 switch (saddr) {
189 case 0:
190 SER_DPRINTF("Write channel %c, reg[%d] = %2.2x\n", channel? 'b' : 'a', s->reg, val & 0xff);
191 newreg = 0;
192 switch (s->reg) {
193 case 0:
194 newreg = val & 7;
195 val &= 0x38;
196 switch (val) {
197 case 8:
198 s->reg |= 0x8;
199 break;
200 case 0x20:
201 s->rxint = 0;
202 break;
203 case 0x28:
204 s->txint = 0;
205 break;
206 default:
207 break;
208 }
209 break;
210 case 1 ... 8:
211 case 10 ... 15:
212 s->wregs[s->reg] = val;
213 break;
214 case 9:
215 switch (val & 0xc0) {
216 case 0:
217 default:
218 break;
219 case 0x40:
220 slavio_serial_reset_chn(&ser->chn[1]);
221 return;
222 case 0x80:
223 slavio_serial_reset_chn(&ser->chn[0]);
224 return;
225 case 0xc0:
226 slavio_serial_reset(ser);
227 return;
228 }
229 break;
230 default:
231 break;
232 }
233 if (s->reg == 0)
234 s->reg = newreg;
235 else
236 s->reg = 0;
237 break;
238 case 1:
239 SER_DPRINTF("Write channel %c, ch %d\n", channel? 'b' : 'a', val);
240 if (s->wregs[5] & 8) { // tx enabled
241 s->tx = val;
242 if (s->chr)
243 qemu_chr_write(s->chr, &s->tx, 1);
244 else if (s->type == kbd) {
245 handle_kbd_command(s, val);
246 }
247 s->txint = 1;
248 s->rregs[0] |= 4;
249 // Interrupts reported only on channel A
250 if (s->chn == 0)
251 s->rregs[3] |= 0x10;
252 else {
253 s->otherchn->rregs[3] |= 2;
254 }
255 slavio_serial_update_irq(s);
256 }
257 break;
258 default:
259 break;
260 }
261 }
262
263 static uint32_t slavio_serial_mem_readb(void *opaque, target_phys_addr_t addr)
264 {
265 SerialState *ser = opaque;
266 ChannelState *s;
267 uint32_t saddr;
268 uint32_t ret;
269 int channel;
270
271 saddr = (addr & 3) >> 1;
272 channel = (addr & SERIAL_MAXADDR) >> 2;
273 s = &ser->chn[channel];
274 switch (saddr) {
275 case 0:
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];
278 s->reg = 0;
279 return ret;
280 case 1:
281 SER_DPRINTF("Read channel %c, ch %d\n", channel? 'b' : 'a', s->rx);
282 s->rregs[0] &= ~1;
283 if (s->type == kbd)
284 ret = get_queue(s);
285 else
286 ret = s->rx;
287 return ret;
288 default:
289 break;
290 }
291 return 0;
292 }
293
294 static int serial_can_receive(void *opaque)
295 {
296 ChannelState *s = opaque;
297 if (((s->wregs[3] & 1) == 0) // Rx not enabled
298 || ((s->rregs[0] & 1) == 1)) // char already available
299 return 0;
300 else
301 return 1;
302 }
303
304 static void serial_receive_byte(ChannelState *s, int ch)
305 {
306 s->rregs[0] |= 1;
307 // Interrupts reported only on channel A
308 if (s->chn == 0)
309 s->rregs[3] |= 0x20;
310 else {
311 s->otherchn->rregs[3] |= 4;
312 }
313 s->rx = ch;
314 s->rxint = 1;
315 slavio_serial_update_irq(s);
316 }
317
318 static void serial_receive_break(ChannelState *s)
319 {
320 s->rregs[0] |= 0x80;
321 slavio_serial_update_irq(s);
322 }
323
324 static void serial_receive1(void *opaque, const uint8_t *buf, int size)
325 {
326 ChannelState *s = opaque;
327 serial_receive_byte(s, buf[0]);
328 }
329
330 static void serial_event(void *opaque, int event)
331 {
332 ChannelState *s = opaque;
333 if (event == CHR_EVENT_BREAK)
334 serial_receive_break(s);
335 }
336
337 static CPUReadMemoryFunc *slavio_serial_mem_read[3] = {
338 slavio_serial_mem_readb,
339 slavio_serial_mem_readb,
340 slavio_serial_mem_readb,
341 };
342
343 static CPUWriteMemoryFunc *slavio_serial_mem_write[3] = {
344 slavio_serial_mem_writeb,
345 slavio_serial_mem_writeb,
346 slavio_serial_mem_writeb,
347 };
348
349 static void slavio_serial_save_chn(QEMUFile *f, ChannelState *s)
350 {
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);
359 }
360
361 static void slavio_serial_save(QEMUFile *f, void *opaque)
362 {
363 SerialState *s = opaque;
364
365 slavio_serial_save_chn(f, &s->chn[0]);
366 slavio_serial_save_chn(f, &s->chn[1]);
367 }
368
369 static int slavio_serial_load_chn(QEMUFile *f, ChannelState *s, int version_id)
370 {
371 if (version_id != 1)
372 return -EINVAL;
373
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);
382 return 0;
383 }
384
385 static int slavio_serial_load(QEMUFile *f, void *opaque, int version_id)
386 {
387 SerialState *s = opaque;
388 int ret;
389
390 ret = slavio_serial_load_chn(f, &s->chn[0], version_id);
391 if (ret != 0)
392 return ret;
393 ret = slavio_serial_load_chn(f, &s->chn[1], version_id);
394 return ret;
395
396 }
397
398 SerialState *slavio_serial_init(int base, int irq, CharDriverState *chr1, CharDriverState *chr2)
399 {
400 int slavio_serial_io_memory, i;
401 SerialState *s;
402
403 s = qemu_mallocz(sizeof(SerialState));
404 if (!s)
405 return NULL;
406
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);
409
410 s->chn[0].chr = chr1;
411 s->chn[1].chr = chr2;
412
413 for (i = 0; i < 2; i++) {
414 s->chn[i].irq = irq;
415 s->chn[i].chn = 1 - i;
416 s->chn[i].type = ser;
417 if (s->chn[i].chr) {
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);
420 }
421 }
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);
427 return s;
428 }
429
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,
439 };
440
441 static void sunkbd_event(void *opaque, int ch)
442 {
443 ChannelState *s = opaque;
444 int release = ch & 0x80;
445
446 ch = keycodes[ch & 0x7f];
447 KBD_DPRINTF("Keycode %d (%s)\n", ch, release? "release" : "press");
448 put_queue(s, ch | release);
449 }
450
451 static void handle_kbd_command(ChannelState *s, int val)
452 {
453 KBD_DPRINTF("Command %d\n", val);
454 switch (val) {
455 case 1: // Reset, return type code
456 put_queue(s, 0xff);
457 put_queue(s, 0xff);
458 put_queue(s, 5); // Type 5
459 break;
460 case 7: // Query layout
461 put_queue(s, 0xfe);
462 put_queue(s, 0x20); // XXX, layout?
463 break;
464 default:
465 break;
466 }
467 }
468
469 static void sunmouse_event(void *opaque,
470 int dx, int dy, int dz, int buttons_state)
471 {
472 ChannelState *s = opaque;
473 int ch;
474
475 // XXX
476 ch = 0x42;
477 serial_receive_byte(s, ch);
478 }
479
480 void slavio_serial_ms_kbd_init(int base, int irq)
481 {
482 int slavio_serial_io_memory, i;
483 SerialState *s;
484
485 s = qemu_mallocz(sizeof(SerialState));
486 if (!s)
487 return;
488 for (i = 0; i < 2; i++) {
489 s->chn[i].irq = irq;
490 s->chn[i].chn = 1 - i;
491 s->chn[i].chr = NULL;
492 }
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;
497
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);
500
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);
505 }