|
|
1.1 root 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)
1.1.1.2 root 48: #define pic_set_irq(irq, level) \
49: do { printf("SER: set_irq(%d): %d\n", (irq), (level)); pic_set_irq((irq),(level));} while (0)
1.1 root 50: #else
51: #define SER_DPRINTF(fmt, args...)
52: #endif
53: #ifdef DEBUG_KBD
54: #define KBD_DPRINTF(fmt, args...) \
55: do { printf("KBD: " fmt , ##args); } while (0)
56: #else
57: #define KBD_DPRINTF(fmt, args...)
58: #endif
59: #ifdef DEBUG_MOUSE
60: #define MS_DPRINTF(fmt, args...) \
61: do { printf("SER: " fmt , ##args); } while (0)
62: #else
63: #define MS_DPRINTF(fmt, args...)
64: #endif
65:
66: typedef enum {
67: chn_a, chn_b,
68: } chn_id_t;
69:
70: typedef enum {
71: ser, kbd, mouse,
72: } chn_type_t;
73:
74: #define KBD_QUEUE_SIZE 256
75:
76: typedef struct {
77: uint8_t data[KBD_QUEUE_SIZE];
78: int rptr, wptr, count;
79: } KBDQueue;
80:
81: typedef struct ChannelState {
82: int irq;
83: int reg;
84: int rxint, txint;
85: chn_id_t chn; // this channel, A (base+4) or B (base+0)
86: chn_type_t type;
87: struct ChannelState *otherchn;
88: uint8_t rx, tx, wregs[16], rregs[16];
89: KBDQueue queue;
90: CharDriverState *chr;
91: } ChannelState;
92:
93: struct SerialState {
94: struct ChannelState chn[2];
95: };
96:
97: #define SERIAL_MAXADDR 7
98:
99: static void handle_kbd_command(ChannelState *s, int val);
100: static int serial_can_receive(void *opaque);
101: static void serial_receive_byte(ChannelState *s, int ch);
102:
103: static void put_queue(void *opaque, int b)
104: {
105: ChannelState *s = opaque;
106: KBDQueue *q = &s->queue;
107:
108: KBD_DPRINTF("put: 0x%02x\n", b);
109: if (q->count >= KBD_QUEUE_SIZE)
110: return;
111: q->data[q->wptr] = b;
112: if (++q->wptr == KBD_QUEUE_SIZE)
113: q->wptr = 0;
114: q->count++;
115: serial_receive_byte(s, 0);
116: }
117:
118: static uint32_t get_queue(void *opaque)
119: {
120: ChannelState *s = opaque;
121: KBDQueue *q = &s->queue;
122: int val;
123:
124: if (q->count == 0) {
125: return 0;
126: } else {
127: val = q->data[q->rptr];
128: if (++q->rptr == KBD_QUEUE_SIZE)
129: q->rptr = 0;
130: q->count--;
131: }
132: KBD_DPRINTF("get 0x%02x\n", val);
133: if (q->count > 0)
134: serial_receive_byte(s, 0);
135: return val;
136: }
137:
138: static void slavio_serial_update_irq(ChannelState *s)
139: {
140: if ((s->wregs[1] & 1) && // interrupts enabled
141: (((s->wregs[1] & 2) && s->txint == 1) || // tx ints enabled, pending
142: ((((s->wregs[1] & 0x18) == 8) || ((s->wregs[1] & 0x18) == 0x10)) &&
143: s->rxint == 1) || // rx ints enabled, pending
144: ((s->wregs[15] & 0x80) && (s->rregs[0] & 0x80)))) { // break int e&p
145: pic_set_irq(s->irq, 1);
146: } else {
147: pic_set_irq(s->irq, 0);
148: }
149: }
150:
151: static void slavio_serial_reset_chn(ChannelState *s)
152: {
153: int i;
154:
155: s->reg = 0;
156: for (i = 0; i < SERIAL_MAXADDR; i++) {
157: s->rregs[i] = 0;
158: s->wregs[i] = 0;
159: }
160: s->wregs[4] = 4;
161: s->wregs[9] = 0xc0;
162: s->wregs[11] = 8;
163: s->wregs[14] = 0x30;
164: s->wregs[15] = 0xf8;
165: s->rregs[0] = 0x44;
166: s->rregs[1] = 6;
167:
168: s->rx = s->tx = 0;
169: s->rxint = s->txint = 0;
170: }
171:
172: static void slavio_serial_reset(void *opaque)
173: {
174: SerialState *s = opaque;
175: slavio_serial_reset_chn(&s->chn[0]);
176: slavio_serial_reset_chn(&s->chn[1]);
177: }
178:
1.1.1.2 root 179: static inline void clr_rxint(ChannelState *s)
180: {
181: s->rxint = 0;
182: if (s->chn == 0)
183: s->rregs[3] &= ~0x20;
184: else {
185: s->otherchn->rregs[3] &= ~4;
186: }
187: slavio_serial_update_irq(s);
188: }
189:
190: static inline void set_rxint(ChannelState *s)
191: {
192: s->rxint = 1;
193: if (s->chn == 0)
194: s->rregs[3] |= 0x20;
195: else {
196: s->otherchn->rregs[3] |= 4;
197: }
198: slavio_serial_update_irq(s);
199: }
200:
201: static inline void clr_txint(ChannelState *s)
202: {
203: s->txint = 0;
204: if (s->chn == 0)
205: s->rregs[3] &= ~0x10;
206: else {
207: s->otherchn->rregs[3] &= ~2;
208: }
209: slavio_serial_update_irq(s);
210: }
211:
212: static inline void set_txint(ChannelState *s)
213: {
214: s->txint = 1;
215: if (s->chn == 0)
216: s->rregs[3] |= 0x10;
217: else {
218: s->otherchn->rregs[3] |= 2;
219: }
220: slavio_serial_update_irq(s);
221: }
222:
1.1 root 223: static void slavio_serial_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
224: {
225: SerialState *ser = opaque;
226: ChannelState *s;
227: uint32_t saddr;
228: int newreg, channel;
229:
230: val &= 0xff;
231: saddr = (addr & 3) >> 1;
232: channel = (addr & SERIAL_MAXADDR) >> 2;
233: s = &ser->chn[channel];
234: switch (saddr) {
235: case 0:
236: SER_DPRINTF("Write channel %c, reg[%d] = %2.2x\n", channel? 'b' : 'a', s->reg, val & 0xff);
237: newreg = 0;
238: switch (s->reg) {
239: case 0:
240: newreg = val & 7;
241: val &= 0x38;
242: switch (val) {
243: case 8:
1.1.1.2 root 244: newreg |= 0x8;
1.1 root 245: break;
246: case 0x20:
1.1.1.2 root 247: clr_rxint(s);
1.1 root 248: break;
249: case 0x28:
1.1.1.2 root 250: clr_txint(s);
251: break;
252: case 0x38:
253: clr_rxint(s);
254: clr_txint(s);
1.1 root 255: break;
256: default:
257: break;
258: }
259: break;
260: case 1 ... 8:
261: case 10 ... 15:
262: s->wregs[s->reg] = val;
263: break;
264: case 9:
265: switch (val & 0xc0) {
266: case 0:
267: default:
268: break;
269: case 0x40:
270: slavio_serial_reset_chn(&ser->chn[1]);
271: return;
272: case 0x80:
273: slavio_serial_reset_chn(&ser->chn[0]);
274: return;
275: case 0xc0:
276: slavio_serial_reset(ser);
277: return;
278: }
279: break;
280: default:
281: break;
282: }
283: if (s->reg == 0)
284: s->reg = newreg;
285: else
286: s->reg = 0;
287: break;
288: case 1:
289: SER_DPRINTF("Write channel %c, ch %d\n", channel? 'b' : 'a', val);
290: if (s->wregs[5] & 8) { // tx enabled
291: s->tx = val;
292: if (s->chr)
293: qemu_chr_write(s->chr, &s->tx, 1);
294: else if (s->type == kbd) {
295: handle_kbd_command(s, val);
296: }
297: s->txint = 1;
1.1.1.2 root 298: s->rregs[0] |= 4; // Tx buffer empty
299: s->rregs[1] |= 1; // All sent
300: set_txint(s);
1.1 root 301: slavio_serial_update_irq(s);
302: }
303: break;
304: default:
305: break;
306: }
307: }
308:
309: static uint32_t slavio_serial_mem_readb(void *opaque, target_phys_addr_t addr)
310: {
311: SerialState *ser = opaque;
312: ChannelState *s;
313: uint32_t saddr;
314: uint32_t ret;
315: int channel;
316:
317: saddr = (addr & 3) >> 1;
318: channel = (addr & SERIAL_MAXADDR) >> 2;
319: s = &ser->chn[channel];
320: switch (saddr) {
321: case 0:
322: SER_DPRINTF("Read channel %c, reg[%d] = %2.2x\n", channel? 'b' : 'a', s->reg, s->rregs[s->reg]);
323: ret = s->rregs[s->reg];
324: s->reg = 0;
325: return ret;
326: case 1:
327: s->rregs[0] &= ~1;
1.1.1.2 root 328: clr_rxint(s);
1.1 root 329: if (s->type == kbd)
330: ret = get_queue(s);
331: else
332: ret = s->rx;
1.1.1.2 root 333: SER_DPRINTF("Read channel %c, ch %d\n", channel? 'b' : 'a', ret);
1.1 root 334: return ret;
335: default:
336: break;
337: }
338: return 0;
339: }
340:
341: static int serial_can_receive(void *opaque)
342: {
343: ChannelState *s = opaque;
344: if (((s->wregs[3] & 1) == 0) // Rx not enabled
345: || ((s->rregs[0] & 1) == 1)) // char already available
346: return 0;
347: else
348: return 1;
349: }
350:
351: static void serial_receive_byte(ChannelState *s, int ch)
352: {
1.1.1.2 root 353: SER_DPRINTF("put ch %d\n", ch);
1.1 root 354: s->rregs[0] |= 1;
355: s->rx = ch;
1.1.1.2 root 356: set_rxint(s);
1.1 root 357: }
358:
359: static void serial_receive_break(ChannelState *s)
360: {
361: s->rregs[0] |= 0x80;
362: slavio_serial_update_irq(s);
363: }
364:
365: static void serial_receive1(void *opaque, const uint8_t *buf, int size)
366: {
367: ChannelState *s = opaque;
368: serial_receive_byte(s, buf[0]);
369: }
370:
371: static void serial_event(void *opaque, int event)
372: {
373: ChannelState *s = opaque;
374: if (event == CHR_EVENT_BREAK)
375: serial_receive_break(s);
376: }
377:
378: static CPUReadMemoryFunc *slavio_serial_mem_read[3] = {
379: slavio_serial_mem_readb,
380: slavio_serial_mem_readb,
381: slavio_serial_mem_readb,
382: };
383:
384: static CPUWriteMemoryFunc *slavio_serial_mem_write[3] = {
385: slavio_serial_mem_writeb,
386: slavio_serial_mem_writeb,
387: slavio_serial_mem_writeb,
388: };
389:
390: static void slavio_serial_save_chn(QEMUFile *f, ChannelState *s)
391: {
392: qemu_put_be32s(f, &s->irq);
393: qemu_put_be32s(f, &s->reg);
394: qemu_put_be32s(f, &s->rxint);
395: qemu_put_be32s(f, &s->txint);
396: qemu_put_8s(f, &s->rx);
397: qemu_put_8s(f, &s->tx);
398: qemu_put_buffer(f, s->wregs, 16);
399: qemu_put_buffer(f, s->rregs, 16);
400: }
401:
402: static void slavio_serial_save(QEMUFile *f, void *opaque)
403: {
404: SerialState *s = opaque;
405:
406: slavio_serial_save_chn(f, &s->chn[0]);
407: slavio_serial_save_chn(f, &s->chn[1]);
408: }
409:
410: static int slavio_serial_load_chn(QEMUFile *f, ChannelState *s, int version_id)
411: {
412: if (version_id != 1)
413: return -EINVAL;
414:
415: qemu_get_be32s(f, &s->irq);
416: qemu_get_be32s(f, &s->reg);
417: qemu_get_be32s(f, &s->rxint);
418: qemu_get_be32s(f, &s->txint);
419: qemu_get_8s(f, &s->rx);
420: qemu_get_8s(f, &s->tx);
421: qemu_get_buffer(f, s->wregs, 16);
422: qemu_get_buffer(f, s->rregs, 16);
423: return 0;
424: }
425:
426: static int slavio_serial_load(QEMUFile *f, void *opaque, int version_id)
427: {
428: SerialState *s = opaque;
429: int ret;
430:
431: ret = slavio_serial_load_chn(f, &s->chn[0], version_id);
432: if (ret != 0)
433: return ret;
434: ret = slavio_serial_load_chn(f, &s->chn[1], version_id);
435: return ret;
436:
437: }
438:
439: SerialState *slavio_serial_init(int base, int irq, CharDriverState *chr1, CharDriverState *chr2)
440: {
441: int slavio_serial_io_memory, i;
442: SerialState *s;
443:
444: s = qemu_mallocz(sizeof(SerialState));
445: if (!s)
446: return NULL;
447:
448: slavio_serial_io_memory = cpu_register_io_memory(0, slavio_serial_mem_read, slavio_serial_mem_write, s);
449: cpu_register_physical_memory(base, SERIAL_MAXADDR, slavio_serial_io_memory);
450:
451: s->chn[0].chr = chr1;
452: s->chn[1].chr = chr2;
453:
454: for (i = 0; i < 2; i++) {
455: s->chn[i].irq = irq;
456: s->chn[i].chn = 1 - i;
457: s->chn[i].type = ser;
458: if (s->chn[i].chr) {
459: qemu_chr_add_read_handler(s->chn[i].chr, serial_can_receive, serial_receive1, &s->chn[i]);
460: qemu_chr_add_event_handler(s->chn[i].chr, serial_event);
461: }
462: }
463: s->chn[0].otherchn = &s->chn[1];
464: s->chn[1].otherchn = &s->chn[0];
465: register_savevm("slavio_serial", base, 1, slavio_serial_save, slavio_serial_load, s);
466: qemu_register_reset(slavio_serial_reset, s);
467: slavio_serial_reset(s);
468: return s;
469: }
470:
471: static const uint8_t keycodes[128] = {
472: 127, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 43, 53,
473: 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 89, 76, 77, 78,
474: 79, 80, 81, 82, 83, 84, 85, 86, 87, 42, 99, 88, 100, 101, 102, 103,
475: 104, 105, 106, 107, 108, 109, 110, 47, 19, 121, 119, 5, 6, 8, 10, 12,
476: 14, 16, 17, 18, 7, 98, 23, 68, 69, 70, 71, 91, 92, 93, 125, 112,
477: 113, 114, 94, 50, 0, 0, 124, 9, 11, 0, 0, 0, 0, 0, 0, 0,
478: 90, 0, 46, 22, 13, 111, 52, 20, 96, 24, 28, 74, 27, 123, 44, 66,
479: 0, 45, 2, 4, 48, 0, 0, 21, 0, 0, 0, 0, 0, 120, 122, 67,
480: };
481:
482: static void sunkbd_event(void *opaque, int ch)
483: {
484: ChannelState *s = opaque;
485: int release = ch & 0x80;
486:
487: ch = keycodes[ch & 0x7f];
488: KBD_DPRINTF("Keycode %d (%s)\n", ch, release? "release" : "press");
489: put_queue(s, ch | release);
490: }
491:
492: static void handle_kbd_command(ChannelState *s, int val)
493: {
494: KBD_DPRINTF("Command %d\n", val);
495: switch (val) {
496: case 1: // Reset, return type code
497: put_queue(s, 0xff);
498: put_queue(s, 5); // Type 5
499: break;
500: case 7: // Query layout
501: put_queue(s, 0xfe);
502: put_queue(s, 0x20); // XXX, layout?
503: break;
504: default:
505: break;
506: }
507: }
508:
509: static void sunmouse_event(void *opaque,
510: int dx, int dy, int dz, int buttons_state)
511: {
512: ChannelState *s = opaque;
513: int ch;
514:
515: // XXX
516: ch = 0x42;
517: serial_receive_byte(s, ch);
518: }
519:
520: void slavio_serial_ms_kbd_init(int base, int irq)
521: {
522: int slavio_serial_io_memory, i;
523: SerialState *s;
524:
525: s = qemu_mallocz(sizeof(SerialState));
526: if (!s)
527: return;
528: for (i = 0; i < 2; i++) {
529: s->chn[i].irq = irq;
530: s->chn[i].chn = 1 - i;
531: s->chn[i].chr = NULL;
532: }
533: s->chn[0].otherchn = &s->chn[1];
534: s->chn[1].otherchn = &s->chn[0];
535: s->chn[0].type = mouse;
536: s->chn[1].type = kbd;
537:
538: slavio_serial_io_memory = cpu_register_io_memory(0, slavio_serial_mem_read, slavio_serial_mem_write, s);
539: cpu_register_physical_memory(base, SERIAL_MAXADDR, slavio_serial_io_memory);
540:
1.1.1.3 ! root 541: qemu_add_mouse_event_handler(sunmouse_event, &s->chn[0], 0);
1.1 root 542: qemu_add_kbd_event_handler(sunkbd_event, &s->chn[1]);
543: qemu_register_reset(slavio_serial_reset, s);
544: slavio_serial_reset(s);
545: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.