increase max kernel size with initrd
[qemu] / 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 #define pic_set_irq(irq, level) \
49 do { printf("SER: set_irq(%d): %d\n", (irq), (level)); pic_set_irq((irq),(level));} while (0)
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
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
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:
244                 newreg |= 0x8;
245                 break;
246             case 0x20:
247                 clr_rxint(s);
248                 break;
249             case 0x28:
250                 clr_txint(s);
251                 break;
252             case 0x38:
253                 clr_rxint(s);
254                 clr_txint(s);
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;
298             s->rregs[0] |= 4; // Tx buffer empty
299             s->rregs[1] |= 1; // All sent
300             set_txint(s);
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;
328         clr_rxint(s);
329         if (s->type == kbd)
330             ret = get_queue(s);
331         else
332             ret = s->rx;
333         SER_DPRINTF("Read channel %c, ch %d\n", channel? 'b' : 'a', ret);
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 {
353     SER_DPRINTF("put ch %d\n", ch);
354     s->rregs[0] |= 1;
355     s->rx = ch;
356     set_rxint(s);
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
541     qemu_add_mouse_event_handler(sunmouse_event, &s->chn[0], 0);
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 }