root / hw / slavio_serial.c @ 0443eaf6
History | View | Annotate | Download (8.8 kB)
1 | e80cfcfc | bellard | /*
|
---|---|---|---|
2 | e80cfcfc | bellard | * QEMU Sparc SLAVIO serial port emulation
|
3 | e80cfcfc | bellard | *
|
4 | e80cfcfc | bellard | * Copyright (c) 2003-2004 Fabrice Bellard
|
5 | e80cfcfc | bellard | *
|
6 | e80cfcfc | bellard | * Permission is hereby granted, free of charge, to any person obtaining a copy
|
7 | e80cfcfc | bellard | * of this software and associated documentation files (the "Software"), to deal
|
8 | e80cfcfc | bellard | * in the Software without restriction, including without limitation the rights
|
9 | e80cfcfc | bellard | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
10 | e80cfcfc | bellard | * copies of the Software, and to permit persons to whom the Software is
|
11 | e80cfcfc | bellard | * furnished to do so, subject to the following conditions:
|
12 | e80cfcfc | bellard | *
|
13 | e80cfcfc | bellard | * The above copyright notice and this permission notice shall be included in
|
14 | e80cfcfc | bellard | * all copies or substantial portions of the Software.
|
15 | e80cfcfc | bellard | *
|
16 | e80cfcfc | bellard | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
17 | e80cfcfc | bellard | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
18 | e80cfcfc | bellard | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
19 | e80cfcfc | bellard | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
20 | e80cfcfc | bellard | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
21 | e80cfcfc | bellard | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
22 | e80cfcfc | bellard | * THE SOFTWARE.
|
23 | e80cfcfc | bellard | */
|
24 | e80cfcfc | bellard | #include "vl.h" |
25 | e80cfcfc | bellard | |
26 | e80cfcfc | bellard | //#define DEBUG_SERIAL
|
27 | e80cfcfc | bellard | |
28 | e80cfcfc | bellard | /* debug keyboard */
|
29 | e80cfcfc | bellard | //#define DEBUG_KBD
|
30 | e80cfcfc | bellard | |
31 | e80cfcfc | bellard | /* debug keyboard : only mouse */
|
32 | e80cfcfc | bellard | //#define DEBUG_MOUSE
|
33 | e80cfcfc | bellard | |
34 | e80cfcfc | bellard | /*
|
35 | e80cfcfc | bellard | * This is the serial port, mouse and keyboard part of chip STP2001
|
36 | e80cfcfc | bellard | * (Slave I/O), also produced as NCR89C105. See
|
37 | e80cfcfc | bellard | * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR89C105.txt
|
38 | e80cfcfc | bellard | *
|
39 | e80cfcfc | bellard | * The serial ports implement full AMD AM8530 or Zilog Z8530 chips,
|
40 | e80cfcfc | bellard | * mouse and keyboard ports don't implement all functions and they are
|
41 | e80cfcfc | bellard | * only asynchronous. There is no DMA.
|
42 | e80cfcfc | bellard | *
|
43 | e80cfcfc | bellard | */
|
44 | e80cfcfc | bellard | |
45 | e80cfcfc | bellard | typedef struct ChannelState { |
46 | e80cfcfc | bellard | int irq;
|
47 | e80cfcfc | bellard | int reg;
|
48 | e80cfcfc | bellard | int rxint, txint;
|
49 | e80cfcfc | bellard | uint8_t rx, tx, wregs[16], rregs[16]; |
50 | e80cfcfc | bellard | CharDriverState *chr; |
51 | e80cfcfc | bellard | } ChannelState; |
52 | e80cfcfc | bellard | |
53 | e80cfcfc | bellard | struct SerialState {
|
54 | e80cfcfc | bellard | struct ChannelState chn[2]; |
55 | e80cfcfc | bellard | }; |
56 | e80cfcfc | bellard | |
57 | e80cfcfc | bellard | #define SERIAL_MAXADDR 7 |
58 | e80cfcfc | bellard | |
59 | e80cfcfc | bellard | static void slavio_serial_update_irq(ChannelState *s) |
60 | e80cfcfc | bellard | { |
61 | e80cfcfc | bellard | if ((s->wregs[1] & 1) && // interrupts enabled |
62 | e80cfcfc | bellard | (((s->wregs[1] & 2) && s->txint == 1) || // tx ints enabled, pending |
63 | e80cfcfc | bellard | ((((s->wregs[1] & 0x18) == 8) || ((s->wregs[1] & 0x18) == 0x10)) && |
64 | e80cfcfc | bellard | s->rxint == 1) || // rx ints enabled, pending |
65 | e80cfcfc | bellard | ((s->wregs[15] & 0x80) && (s->rregs[0] & 0x80)))) { // break int e&p |
66 | e80cfcfc | bellard | pic_set_irq(s->irq, 1);
|
67 | e80cfcfc | bellard | } else {
|
68 | e80cfcfc | bellard | pic_set_irq(s->irq, 0);
|
69 | e80cfcfc | bellard | } |
70 | e80cfcfc | bellard | } |
71 | e80cfcfc | bellard | |
72 | e80cfcfc | bellard | static void slavio_serial_reset_chn(ChannelState *s) |
73 | e80cfcfc | bellard | { |
74 | e80cfcfc | bellard | int i;
|
75 | e80cfcfc | bellard | |
76 | e80cfcfc | bellard | s->reg = 0;
|
77 | e80cfcfc | bellard | for (i = 0; i < SERIAL_MAXADDR; i++) { |
78 | e80cfcfc | bellard | s->rregs[i] = 0;
|
79 | e80cfcfc | bellard | s->wregs[i] = 0;
|
80 | e80cfcfc | bellard | } |
81 | e80cfcfc | bellard | s->wregs[4] = 4; |
82 | e80cfcfc | bellard | s->wregs[9] = 0xc0; |
83 | e80cfcfc | bellard | s->wregs[11] = 8; |
84 | e80cfcfc | bellard | s->wregs[14] = 0x30; |
85 | e80cfcfc | bellard | s->wregs[15] = 0xf8; |
86 | e80cfcfc | bellard | s->rregs[0] = 0x44; |
87 | e80cfcfc | bellard | s->rregs[1] = 6; |
88 | e80cfcfc | bellard | |
89 | e80cfcfc | bellard | s->rx = s->tx = 0;
|
90 | e80cfcfc | bellard | s->rxint = s->txint = 0;
|
91 | e80cfcfc | bellard | } |
92 | e80cfcfc | bellard | |
93 | e80cfcfc | bellard | static void slavio_serial_reset(void *opaque) |
94 | e80cfcfc | bellard | { |
95 | e80cfcfc | bellard | SerialState *s = opaque; |
96 | e80cfcfc | bellard | slavio_serial_reset_chn(&s->chn[0]);
|
97 | e80cfcfc | bellard | slavio_serial_reset_chn(&s->chn[1]);
|
98 | e80cfcfc | bellard | } |
99 | e80cfcfc | bellard | |
100 | 3a5c3138 | bellard | static void slavio_serial_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val) |
101 | e80cfcfc | bellard | { |
102 | e80cfcfc | bellard | SerialState *ser = opaque; |
103 | e80cfcfc | bellard | ChannelState *s; |
104 | e80cfcfc | bellard | uint32_t saddr; |
105 | e80cfcfc | bellard | int newreg, channel;
|
106 | e80cfcfc | bellard | |
107 | e80cfcfc | bellard | val &= 0xff;
|
108 | e80cfcfc | bellard | saddr = (addr & 3) >> 1; |
109 | e80cfcfc | bellard | channel = (addr & SERIAL_MAXADDR) >> 2;
|
110 | e80cfcfc | bellard | s = &ser->chn[channel]; |
111 | e80cfcfc | bellard | switch (saddr) {
|
112 | e80cfcfc | bellard | case 0: |
113 | e80cfcfc | bellard | newreg = 0;
|
114 | e80cfcfc | bellard | switch (s->reg) {
|
115 | e80cfcfc | bellard | case 0: |
116 | e80cfcfc | bellard | newreg = val & 7;
|
117 | e80cfcfc | bellard | val &= 0x38;
|
118 | e80cfcfc | bellard | switch (val) {
|
119 | e80cfcfc | bellard | case 8: |
120 | e80cfcfc | bellard | s->reg |= 0x8;
|
121 | e80cfcfc | bellard | break;
|
122 | e80cfcfc | bellard | case 0x20: |
123 | e80cfcfc | bellard | s->rxint = 0;
|
124 | e80cfcfc | bellard | break;
|
125 | e80cfcfc | bellard | case 0x28: |
126 | e80cfcfc | bellard | s->txint = 0;
|
127 | e80cfcfc | bellard | break;
|
128 | e80cfcfc | bellard | default:
|
129 | e80cfcfc | bellard | break;
|
130 | e80cfcfc | bellard | } |
131 | e80cfcfc | bellard | break;
|
132 | e80cfcfc | bellard | case 1 ... 8: |
133 | e80cfcfc | bellard | case 10 ... 15: |
134 | e80cfcfc | bellard | s->wregs[s->reg] = val; |
135 | e80cfcfc | bellard | break;
|
136 | e80cfcfc | bellard | case 9: |
137 | e80cfcfc | bellard | switch (val & 0xc0) { |
138 | e80cfcfc | bellard | case 0: |
139 | e80cfcfc | bellard | default:
|
140 | e80cfcfc | bellard | break;
|
141 | e80cfcfc | bellard | case 0x40: |
142 | e80cfcfc | bellard | slavio_serial_reset_chn(&ser->chn[1]);
|
143 | e80cfcfc | bellard | return;
|
144 | e80cfcfc | bellard | case 0x80: |
145 | e80cfcfc | bellard | slavio_serial_reset_chn(&ser->chn[0]);
|
146 | e80cfcfc | bellard | return;
|
147 | e80cfcfc | bellard | case 0xc0: |
148 | e80cfcfc | bellard | slavio_serial_reset(ser); |
149 | e80cfcfc | bellard | return;
|
150 | e80cfcfc | bellard | } |
151 | e80cfcfc | bellard | break;
|
152 | e80cfcfc | bellard | default:
|
153 | e80cfcfc | bellard | break;
|
154 | e80cfcfc | bellard | } |
155 | e80cfcfc | bellard | if (s->reg == 0) |
156 | e80cfcfc | bellard | s->reg = newreg; |
157 | e80cfcfc | bellard | else
|
158 | e80cfcfc | bellard | s->reg = 0;
|
159 | e80cfcfc | bellard | break;
|
160 | e80cfcfc | bellard | case 1: |
161 | e80cfcfc | bellard | if (s->wregs[5] & 8) { // tx enabled |
162 | e80cfcfc | bellard | s->tx = val; |
163 | e80cfcfc | bellard | if (s->chr)
|
164 | e80cfcfc | bellard | qemu_chr_write(s->chr, &s->tx, 1);
|
165 | e80cfcfc | bellard | s->txint = 1;
|
166 | e80cfcfc | bellard | } |
167 | e80cfcfc | bellard | break;
|
168 | e80cfcfc | bellard | default:
|
169 | e80cfcfc | bellard | break;
|
170 | e80cfcfc | bellard | } |
171 | e80cfcfc | bellard | } |
172 | e80cfcfc | bellard | |
173 | 3a5c3138 | bellard | static uint32_t slavio_serial_mem_readb(void *opaque, target_phys_addr_t addr) |
174 | e80cfcfc | bellard | { |
175 | e80cfcfc | bellard | SerialState *ser = opaque; |
176 | e80cfcfc | bellard | ChannelState *s; |
177 | e80cfcfc | bellard | uint32_t saddr; |
178 | e80cfcfc | bellard | uint32_t ret; |
179 | e80cfcfc | bellard | int channel;
|
180 | e80cfcfc | bellard | |
181 | e80cfcfc | bellard | saddr = (addr & 3) >> 1; |
182 | e80cfcfc | bellard | channel = (addr & SERIAL_MAXADDR) >> 2;
|
183 | e80cfcfc | bellard | s = &ser->chn[channel]; |
184 | e80cfcfc | bellard | switch (saddr) {
|
185 | e80cfcfc | bellard | case 0: |
186 | e80cfcfc | bellard | ret = s->rregs[s->reg]; |
187 | e80cfcfc | bellard | s->reg = 0;
|
188 | e80cfcfc | bellard | return ret;
|
189 | e80cfcfc | bellard | case 1: |
190 | e80cfcfc | bellard | s->rregs[0] &= ~1; |
191 | e80cfcfc | bellard | return s->rx;
|
192 | e80cfcfc | bellard | default:
|
193 | e80cfcfc | bellard | break;
|
194 | e80cfcfc | bellard | } |
195 | e80cfcfc | bellard | return 0; |
196 | e80cfcfc | bellard | } |
197 | e80cfcfc | bellard | |
198 | e80cfcfc | bellard | static int serial_can_receive(void *opaque) |
199 | e80cfcfc | bellard | { |
200 | e80cfcfc | bellard | ChannelState *s = opaque; |
201 | e80cfcfc | bellard | if (((s->wregs[3] & 1) == 0) // Rx not enabled |
202 | e80cfcfc | bellard | || ((s->rregs[0] & 1) == 1)) // char already available |
203 | e80cfcfc | bellard | return 0; |
204 | e80cfcfc | bellard | else
|
205 | e80cfcfc | bellard | return 1; |
206 | e80cfcfc | bellard | } |
207 | e80cfcfc | bellard | |
208 | e80cfcfc | bellard | static void serial_receive_byte(ChannelState *s, int ch) |
209 | e80cfcfc | bellard | { |
210 | e80cfcfc | bellard | s->rregs[0] |= 1; |
211 | e80cfcfc | bellard | s->rx = ch; |
212 | e80cfcfc | bellard | s->rxint = 1;
|
213 | e80cfcfc | bellard | slavio_serial_update_irq(s); |
214 | e80cfcfc | bellard | } |
215 | e80cfcfc | bellard | |
216 | e80cfcfc | bellard | static void serial_receive_break(ChannelState *s) |
217 | e80cfcfc | bellard | { |
218 | e80cfcfc | bellard | s->rregs[0] |= 0x80; |
219 | e80cfcfc | bellard | slavio_serial_update_irq(s); |
220 | e80cfcfc | bellard | } |
221 | e80cfcfc | bellard | |
222 | e80cfcfc | bellard | static void serial_receive1(void *opaque, const uint8_t *buf, int size) |
223 | e80cfcfc | bellard | { |
224 | e80cfcfc | bellard | ChannelState *s = opaque; |
225 | e80cfcfc | bellard | serial_receive_byte(s, buf[0]);
|
226 | e80cfcfc | bellard | } |
227 | e80cfcfc | bellard | |
228 | e80cfcfc | bellard | static void serial_event(void *opaque, int event) |
229 | e80cfcfc | bellard | { |
230 | e80cfcfc | bellard | ChannelState *s = opaque; |
231 | e80cfcfc | bellard | if (event == CHR_EVENT_BREAK)
|
232 | e80cfcfc | bellard | serial_receive_break(s); |
233 | e80cfcfc | bellard | } |
234 | e80cfcfc | bellard | |
235 | e80cfcfc | bellard | static CPUReadMemoryFunc *slavio_serial_mem_read[3] = { |
236 | e80cfcfc | bellard | slavio_serial_mem_readb, |
237 | e80cfcfc | bellard | slavio_serial_mem_readb, |
238 | e80cfcfc | bellard | slavio_serial_mem_readb, |
239 | e80cfcfc | bellard | }; |
240 | e80cfcfc | bellard | |
241 | e80cfcfc | bellard | static CPUWriteMemoryFunc *slavio_serial_mem_write[3] = { |
242 | e80cfcfc | bellard | slavio_serial_mem_writeb, |
243 | e80cfcfc | bellard | slavio_serial_mem_writeb, |
244 | e80cfcfc | bellard | slavio_serial_mem_writeb, |
245 | e80cfcfc | bellard | }; |
246 | e80cfcfc | bellard | |
247 | e80cfcfc | bellard | static void slavio_serial_save_chn(QEMUFile *f, ChannelState *s) |
248 | e80cfcfc | bellard | { |
249 | e80cfcfc | bellard | qemu_put_be32s(f, &s->irq); |
250 | e80cfcfc | bellard | qemu_put_be32s(f, &s->reg); |
251 | e80cfcfc | bellard | qemu_put_be32s(f, &s->rxint); |
252 | e80cfcfc | bellard | qemu_put_be32s(f, &s->txint); |
253 | e80cfcfc | bellard | qemu_put_8s(f, &s->rx); |
254 | e80cfcfc | bellard | qemu_put_8s(f, &s->tx); |
255 | e80cfcfc | bellard | qemu_put_buffer(f, s->wregs, 16);
|
256 | e80cfcfc | bellard | qemu_put_buffer(f, s->rregs, 16);
|
257 | e80cfcfc | bellard | } |
258 | e80cfcfc | bellard | |
259 | e80cfcfc | bellard | static void slavio_serial_save(QEMUFile *f, void *opaque) |
260 | e80cfcfc | bellard | { |
261 | e80cfcfc | bellard | SerialState *s = opaque; |
262 | e80cfcfc | bellard | |
263 | e80cfcfc | bellard | slavio_serial_save_chn(f, &s->chn[0]);
|
264 | e80cfcfc | bellard | slavio_serial_save_chn(f, &s->chn[1]);
|
265 | e80cfcfc | bellard | } |
266 | e80cfcfc | bellard | |
267 | e80cfcfc | bellard | static int slavio_serial_load_chn(QEMUFile *f, ChannelState *s, int version_id) |
268 | e80cfcfc | bellard | { |
269 | e80cfcfc | bellard | if (version_id != 1) |
270 | e80cfcfc | bellard | return -EINVAL;
|
271 | e80cfcfc | bellard | |
272 | e80cfcfc | bellard | qemu_get_be32s(f, &s->irq); |
273 | e80cfcfc | bellard | qemu_get_be32s(f, &s->reg); |
274 | e80cfcfc | bellard | qemu_get_be32s(f, &s->rxint); |
275 | e80cfcfc | bellard | qemu_get_be32s(f, &s->txint); |
276 | e80cfcfc | bellard | qemu_get_8s(f, &s->rx); |
277 | e80cfcfc | bellard | qemu_get_8s(f, &s->tx); |
278 | e80cfcfc | bellard | qemu_get_buffer(f, s->wregs, 16);
|
279 | e80cfcfc | bellard | qemu_get_buffer(f, s->rregs, 16);
|
280 | e80cfcfc | bellard | return 0; |
281 | e80cfcfc | bellard | } |
282 | e80cfcfc | bellard | |
283 | e80cfcfc | bellard | static int slavio_serial_load(QEMUFile *f, void *opaque, int version_id) |
284 | e80cfcfc | bellard | { |
285 | e80cfcfc | bellard | SerialState *s = opaque; |
286 | e80cfcfc | bellard | int ret;
|
287 | e80cfcfc | bellard | |
288 | e80cfcfc | bellard | ret = slavio_serial_load_chn(f, &s->chn[0], version_id);
|
289 | e80cfcfc | bellard | if (ret != 0) |
290 | e80cfcfc | bellard | return ret;
|
291 | e80cfcfc | bellard | ret = slavio_serial_load_chn(f, &s->chn[1], version_id);
|
292 | e80cfcfc | bellard | return ret;
|
293 | e80cfcfc | bellard | |
294 | e80cfcfc | bellard | } |
295 | e80cfcfc | bellard | |
296 | e80cfcfc | bellard | SerialState *slavio_serial_init(int base, int irq, CharDriverState *chr1, CharDriverState *chr2) |
297 | e80cfcfc | bellard | { |
298 | e80cfcfc | bellard | int slavio_serial_io_memory;
|
299 | e80cfcfc | bellard | SerialState *s; |
300 | e80cfcfc | bellard | |
301 | e80cfcfc | bellard | s = qemu_mallocz(sizeof(SerialState));
|
302 | e80cfcfc | bellard | if (!s)
|
303 | e80cfcfc | bellard | return NULL; |
304 | e80cfcfc | bellard | s->chn[0].irq = irq;
|
305 | e80cfcfc | bellard | s->chn[1].irq = irq;
|
306 | e80cfcfc | bellard | s->chn[0].chr = chr1;
|
307 | e80cfcfc | bellard | s->chn[1].chr = chr2;
|
308 | e80cfcfc | bellard | |
309 | e80cfcfc | bellard | slavio_serial_io_memory = cpu_register_io_memory(0, slavio_serial_mem_read, slavio_serial_mem_write, s);
|
310 | e80cfcfc | bellard | cpu_register_physical_memory(base, SERIAL_MAXADDR, slavio_serial_io_memory); |
311 | e80cfcfc | bellard | |
312 | e80cfcfc | bellard | if (chr1) {
|
313 | e80cfcfc | bellard | qemu_chr_add_read_handler(chr1, serial_can_receive, serial_receive1, &s->chn[0]);
|
314 | e80cfcfc | bellard | qemu_chr_add_event_handler(chr1, serial_event); |
315 | e80cfcfc | bellard | } |
316 | e80cfcfc | bellard | if (chr2) {
|
317 | e80cfcfc | bellard | qemu_chr_add_read_handler(chr2, serial_can_receive, serial_receive1, &s->chn[1]);
|
318 | e80cfcfc | bellard | qemu_chr_add_event_handler(chr2, serial_event); |
319 | e80cfcfc | bellard | } |
320 | e80cfcfc | bellard | register_savevm("slavio_serial", base, 1, slavio_serial_save, slavio_serial_load, s); |
321 | e80cfcfc | bellard | qemu_register_reset(slavio_serial_reset, s); |
322 | e80cfcfc | bellard | slavio_serial_reset(s); |
323 | e80cfcfc | bellard | return s;
|
324 | e80cfcfc | bellard | } |
325 | e80cfcfc | bellard | |
326 | e80cfcfc | bellard | static void sunkbd_event(void *opaque, int ch) |
327 | e80cfcfc | bellard | { |
328 | e80cfcfc | bellard | ChannelState *s = opaque; |
329 | e80cfcfc | bellard | // XXX: PC -> Sun Type 5 translation?
|
330 | e80cfcfc | bellard | serial_receive_byte(s, ch); |
331 | e80cfcfc | bellard | } |
332 | e80cfcfc | bellard | |
333 | e80cfcfc | bellard | static void sunmouse_event(void *opaque, |
334 | e80cfcfc | bellard | int dx, int dy, int dz, int buttons_state) |
335 | e80cfcfc | bellard | { |
336 | e80cfcfc | bellard | ChannelState *s = opaque; |
337 | e80cfcfc | bellard | int ch;
|
338 | e80cfcfc | bellard | |
339 | e80cfcfc | bellard | // XXX
|
340 | e80cfcfc | bellard | ch = 0x42;
|
341 | e80cfcfc | bellard | serial_receive_byte(s, ch); |
342 | e80cfcfc | bellard | } |
343 | e80cfcfc | bellard | |
344 | e80cfcfc | bellard | void slavio_serial_ms_kbd_init(int base, int irq) |
345 | e80cfcfc | bellard | { |
346 | e80cfcfc | bellard | int slavio_serial_io_memory;
|
347 | e80cfcfc | bellard | SerialState *s; |
348 | e80cfcfc | bellard | |
349 | e80cfcfc | bellard | s = qemu_mallocz(sizeof(SerialState));
|
350 | e80cfcfc | bellard | if (!s)
|
351 | e80cfcfc | bellard | return;
|
352 | e80cfcfc | bellard | s->chn[0].irq = irq;
|
353 | e80cfcfc | bellard | s->chn[1].irq = irq;
|
354 | e80cfcfc | bellard | s->chn[0].chr = NULL; |
355 | e80cfcfc | bellard | s->chn[1].chr = NULL; |
356 | e80cfcfc | bellard | |
357 | e80cfcfc | bellard | slavio_serial_io_memory = cpu_register_io_memory(0, slavio_serial_mem_read, slavio_serial_mem_write, s);
|
358 | e80cfcfc | bellard | cpu_register_physical_memory(base, SERIAL_MAXADDR, slavio_serial_io_memory); |
359 | e80cfcfc | bellard | |
360 | e80cfcfc | bellard | qemu_add_kbd_event_handler(sunkbd_event, &s->chn[0]);
|
361 | e80cfcfc | bellard | qemu_add_mouse_event_handler(sunmouse_event, &s->chn[1]);
|
362 | e80cfcfc | bellard | qemu_register_reset(slavio_serial_reset, s); |
363 | e80cfcfc | bellard | slavio_serial_reset(s); |
364 | e80cfcfc | bellard | } |