64 bit fix
[qemu] / hw / slavio_serial.c
1 /*
2  * QEMU Sparc SLAVIO serial port emulation
3  * 
4  * Copyright (c) 2003-2004 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
26 //#define DEBUG_SERIAL
27
28 /* debug keyboard */
29 //#define DEBUG_KBD
30
31 /* debug keyboard : only 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 typedef struct ChannelState {
46     int irq;
47     int reg;
48     int rxint, txint;
49     uint8_t rx, tx, wregs[16], rregs[16];
50     CharDriverState *chr;
51 } ChannelState;
52
53 struct SerialState {
54     struct ChannelState chn[2];
55 };
56
57 #define SERIAL_MAXADDR 7
58
59 static void slavio_serial_update_irq(ChannelState *s)
60 {
61     if ((s->wregs[1] & 1) && // interrupts enabled
62         (((s->wregs[1] & 2) && s->txint == 1) || // tx ints enabled, pending
63          ((((s->wregs[1] & 0x18) == 8) || ((s->wregs[1] & 0x18) == 0x10)) &&
64           s->rxint == 1) || // rx ints enabled, pending
65          ((s->wregs[15] & 0x80) && (s->rregs[0] & 0x80)))) { // break int e&p
66         pic_set_irq(s->irq, 1);
67     } else {
68         pic_set_irq(s->irq, 0);
69     }
70 }
71
72 static void slavio_serial_reset_chn(ChannelState *s)
73 {
74     int i;
75
76     s->reg = 0;
77     for (i = 0; i < SERIAL_MAXADDR; i++) {
78         s->rregs[i] = 0;
79         s->wregs[i] = 0;
80     }
81     s->wregs[4] = 4;
82     s->wregs[9] = 0xc0;
83     s->wregs[11] = 8;
84     s->wregs[14] = 0x30;
85     s->wregs[15] = 0xf8;
86     s->rregs[0] = 0x44;
87     s->rregs[1] = 6;
88
89     s->rx = s->tx = 0;
90     s->rxint = s->txint = 0;
91 }
92
93 static void slavio_serial_reset(void *opaque)
94 {
95     SerialState *s = opaque;
96     slavio_serial_reset_chn(&s->chn[0]);
97     slavio_serial_reset_chn(&s->chn[1]);
98 }
99
100 static void slavio_serial_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
101 {
102     SerialState *ser = opaque;
103     ChannelState *s;
104     uint32_t saddr;
105     int newreg, channel;
106
107     val &= 0xff;
108     saddr = (addr & 3) >> 1;
109     channel = (addr & SERIAL_MAXADDR) >> 2;
110     s = &ser->chn[channel];
111     switch (saddr) {
112     case 0:
113         newreg = 0;
114         switch (s->reg) {
115         case 0:
116             newreg = val & 7;
117             val &= 0x38;
118             switch (val) {
119             case 8:
120                 s->reg |= 0x8;
121                 break;
122             case 0x20:
123                 s->rxint = 0;
124                 break;
125             case 0x28:
126                 s->txint = 0;
127                 break;
128             default:
129                 break;
130             }
131             break;
132         case 1 ... 8:
133         case 10 ... 15:
134             s->wregs[s->reg] = val;
135             break;
136         case 9:
137             switch (val & 0xc0) {
138             case 0:
139             default:
140                 break;
141             case 0x40:
142                 slavio_serial_reset_chn(&ser->chn[1]);
143                 return;
144             case 0x80:
145                 slavio_serial_reset_chn(&ser->chn[0]);
146                 return;
147             case 0xc0:
148                 slavio_serial_reset(ser);
149                 return;
150             }
151             break;
152         default:
153             break;
154         }
155         if (s->reg == 0)
156             s->reg = newreg;
157         else
158             s->reg = 0;
159         break;
160     case 1:
161         if (s->wregs[5] & 8) { // tx enabled
162             s->tx = val;
163             if (s->chr)
164                 qemu_chr_write(s->chr, &s->tx, 1);
165             s->txint = 1;
166         }
167         break;
168     default:
169         break;
170     }
171 }
172
173 static uint32_t slavio_serial_mem_readb(void *opaque, target_phys_addr_t addr)
174 {
175     SerialState *ser = opaque;
176     ChannelState *s;
177     uint32_t saddr;
178     uint32_t ret;
179     int channel;
180
181     saddr = (addr & 3) >> 1;
182     channel = (addr & SERIAL_MAXADDR) >> 2;
183     s = &ser->chn[channel];
184     switch (saddr) {
185     case 0:
186         ret = s->rregs[s->reg];
187         s->reg = 0;
188         return ret;
189     case 1:
190         s->rregs[0] &= ~1;
191         return s->rx;
192     default:
193         break;
194     }
195     return 0;
196 }
197
198 static int serial_can_receive(void *opaque)
199 {
200     ChannelState *s = opaque;
201     if (((s->wregs[3] & 1) == 0) // Rx not enabled
202         || ((s->rregs[0] & 1) == 1)) // char already available
203         return 0;
204     else
205         return 1;
206 }
207
208 static void serial_receive_byte(ChannelState *s, int ch)
209 {
210     s->rregs[0] |= 1;
211     s->rx = ch;
212     s->rxint = 1;
213     slavio_serial_update_irq(s);
214 }
215
216 static void serial_receive_break(ChannelState *s)
217 {
218     s->rregs[0] |= 0x80;
219     slavio_serial_update_irq(s);
220 }
221
222 static void serial_receive1(void *opaque, const uint8_t *buf, int size)
223 {
224     ChannelState *s = opaque;
225     serial_receive_byte(s, buf[0]);
226 }
227
228 static void serial_event(void *opaque, int event)
229 {
230     ChannelState *s = opaque;
231     if (event == CHR_EVENT_BREAK)
232         serial_receive_break(s);
233 }
234
235 static CPUReadMemoryFunc *slavio_serial_mem_read[3] = {
236     slavio_serial_mem_readb,
237     slavio_serial_mem_readb,
238     slavio_serial_mem_readb,
239 };
240
241 static CPUWriteMemoryFunc *slavio_serial_mem_write[3] = {
242     slavio_serial_mem_writeb,
243     slavio_serial_mem_writeb,
244     slavio_serial_mem_writeb,
245 };
246
247 static void slavio_serial_save_chn(QEMUFile *f, ChannelState *s)
248 {
249     qemu_put_be32s(f, &s->irq);
250     qemu_put_be32s(f, &s->reg);
251     qemu_put_be32s(f, &s->rxint);
252     qemu_put_be32s(f, &s->txint);
253     qemu_put_8s(f, &s->rx);
254     qemu_put_8s(f, &s->tx);
255     qemu_put_buffer(f, s->wregs, 16);
256     qemu_put_buffer(f, s->rregs, 16);
257 }
258
259 static void slavio_serial_save(QEMUFile *f, void *opaque)
260 {
261     SerialState *s = opaque;
262
263     slavio_serial_save_chn(f, &s->chn[0]);
264     slavio_serial_save_chn(f, &s->chn[1]);
265 }
266
267 static int slavio_serial_load_chn(QEMUFile *f, ChannelState *s, int version_id)
268 {
269     if (version_id != 1)
270         return -EINVAL;
271
272     qemu_get_be32s(f, &s->irq);
273     qemu_get_be32s(f, &s->reg);
274     qemu_get_be32s(f, &s->rxint);
275     qemu_get_be32s(f, &s->txint);
276     qemu_get_8s(f, &s->rx);
277     qemu_get_8s(f, &s->tx);
278     qemu_get_buffer(f, s->wregs, 16);
279     qemu_get_buffer(f, s->rregs, 16);
280     return 0;
281 }
282
283 static int slavio_serial_load(QEMUFile *f, void *opaque, int version_id)
284 {
285     SerialState *s = opaque;
286     int ret;
287
288     ret = slavio_serial_load_chn(f, &s->chn[0], version_id);
289     if (ret != 0)
290         return ret;
291     ret = slavio_serial_load_chn(f, &s->chn[1], version_id);
292     return ret;
293
294 }
295
296 SerialState *slavio_serial_init(int base, int irq, CharDriverState *chr1, CharDriverState *chr2)
297 {
298     int slavio_serial_io_memory;
299     SerialState *s;
300
301     s = qemu_mallocz(sizeof(SerialState));
302     if (!s)
303         return NULL;
304     s->chn[0].irq = irq;
305     s->chn[1].irq = irq;
306     s->chn[0].chr = chr1;
307     s->chn[1].chr = chr2;
308
309     slavio_serial_io_memory = cpu_register_io_memory(0, slavio_serial_mem_read, slavio_serial_mem_write, s);
310     cpu_register_physical_memory(base, SERIAL_MAXADDR, slavio_serial_io_memory);
311
312     if (chr1) {
313         qemu_chr_add_read_handler(chr1, serial_can_receive, serial_receive1, &s->chn[0]);
314         qemu_chr_add_event_handler(chr1, serial_event);
315     }
316     if (chr2) {
317         qemu_chr_add_read_handler(chr2, serial_can_receive, serial_receive1, &s->chn[1]);
318         qemu_chr_add_event_handler(chr2, serial_event);
319     }
320     register_savevm("slavio_serial", base, 1, slavio_serial_save, slavio_serial_load, s);
321     qemu_register_reset(slavio_serial_reset, s);
322     slavio_serial_reset(s);
323     return s;
324 }
325
326 static void sunkbd_event(void *opaque, int ch)
327 {
328     ChannelState *s = opaque;
329     // XXX: PC -> Sun Type 5 translation?
330     serial_receive_byte(s, ch);
331 }
332
333 static void sunmouse_event(void *opaque, 
334                                int dx, int dy, int dz, int buttons_state)
335 {
336     ChannelState *s = opaque;
337     int ch;
338
339     // XXX
340     ch = 0x42;
341     serial_receive_byte(s, ch);
342 }
343
344 void slavio_serial_ms_kbd_init(int base, int irq)
345 {
346     int slavio_serial_io_memory;
347     SerialState *s;
348
349     s = qemu_mallocz(sizeof(SerialState));
350     if (!s)
351         return;
352     s->chn[0].irq = irq;
353     s->chn[1].irq = irq;
354     s->chn[0].chr = NULL;
355     s->chn[1].chr = NULL;
356
357     slavio_serial_io_memory = cpu_register_io_memory(0, slavio_serial_mem_read, slavio_serial_mem_write, s);
358     cpu_register_physical_memory(base, SERIAL_MAXADDR, slavio_serial_io_memory);
359
360     qemu_add_kbd_event_handler(sunkbd_event, &s->chn[0]);
361     qemu_add_mouse_event_handler(sunmouse_event, &s->chn[1]);
362     qemu_register_reset(slavio_serial_reset, s);
363     slavio_serial_reset(s);
364 }