ds1225y nvram: Fix some bugs
[qemu/malc.git] / hw / serial.c
blobb70d739622016d98df69f2743338f473f7b3fb04
1 /*
2 * QEMU 16450 UART emulation
4 * Copyright (c) 2003-2004 Fabrice Bellard
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:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
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.
24 #include "hw.h"
25 #include "qemu-char.h"
26 #include "isa.h"
27 #include "pc.h"
29 //#define DEBUG_SERIAL
31 #define UART_LCR_DLAB 0x80 /* Divisor latch access bit */
33 #define UART_IER_MSI 0x08 /* Enable Modem status interrupt */
34 #define UART_IER_RLSI 0x04 /* Enable receiver line status interrupt */
35 #define UART_IER_THRI 0x02 /* Enable Transmitter holding register int. */
36 #define UART_IER_RDI 0x01 /* Enable receiver data interrupt */
38 #define UART_IIR_NO_INT 0x01 /* No interrupts pending */
39 #define UART_IIR_ID 0x06 /* Mask for the interrupt ID */
41 #define UART_IIR_MSI 0x00 /* Modem status interrupt */
42 #define UART_IIR_THRI 0x02 /* Transmitter holding register empty */
43 #define UART_IIR_RDI 0x04 /* Receiver data interrupt */
44 #define UART_IIR_RLSI 0x06 /* Receiver line status interrupt */
47 * These are the definitions for the Modem Control Register
49 #define UART_MCR_LOOP 0x10 /* Enable loopback test mode */
50 #define UART_MCR_OUT2 0x08 /* Out2 complement */
51 #define UART_MCR_OUT1 0x04 /* Out1 complement */
52 #define UART_MCR_RTS 0x02 /* RTS complement */
53 #define UART_MCR_DTR 0x01 /* DTR complement */
56 * These are the definitions for the Modem Status Register
58 #define UART_MSR_DCD 0x80 /* Data Carrier Detect */
59 #define UART_MSR_RI 0x40 /* Ring Indicator */
60 #define UART_MSR_DSR 0x20 /* Data Set Ready */
61 #define UART_MSR_CTS 0x10 /* Clear to Send */
62 #define UART_MSR_DDCD 0x08 /* Delta DCD */
63 #define UART_MSR_TERI 0x04 /* Trailing edge ring indicator */
64 #define UART_MSR_DDSR 0x02 /* Delta DSR */
65 #define UART_MSR_DCTS 0x01 /* Delta CTS */
66 #define UART_MSR_ANY_DELTA 0x0F /* Any of the delta bits! */
68 #define UART_LSR_TEMT 0x40 /* Transmitter empty */
69 #define UART_LSR_THRE 0x20 /* Transmit-hold-register empty */
70 #define UART_LSR_BI 0x10 /* Break interrupt indicator */
71 #define UART_LSR_FE 0x08 /* Frame error indicator */
72 #define UART_LSR_PE 0x04 /* Parity error indicator */
73 #define UART_LSR_OE 0x02 /* Overrun error indicator */
74 #define UART_LSR_DR 0x01 /* Receiver data ready */
76 struct SerialState {
77 uint16_t divider;
78 uint8_t rbr; /* receive register */
79 uint8_t ier;
80 uint8_t iir; /* read only */
81 uint8_t lcr;
82 uint8_t mcr;
83 uint8_t lsr; /* read only */
84 uint8_t msr; /* read only */
85 uint8_t scr;
86 /* NOTE: this hidden state is necessary for tx irq generation as
87 it can be reset while reading iir */
88 int thr_ipending;
89 qemu_irq irq;
90 CharDriverState *chr;
91 int last_break_enable;
92 target_phys_addr_t base;
93 int it_shift;
96 static void serial_receive_byte(SerialState *s, int ch);
98 static void serial_update_irq(SerialState *s)
100 if ((s->lsr & UART_LSR_DR) && (s->ier & UART_IER_RDI)) {
101 s->iir = UART_IIR_RDI;
102 } else if (s->thr_ipending && (s->ier & UART_IER_THRI)) {
103 s->iir = UART_IIR_THRI;
104 } else {
105 s->iir = UART_IIR_NO_INT;
107 if (s->iir != UART_IIR_NO_INT) {
108 qemu_irq_raise(s->irq);
109 } else {
110 qemu_irq_lower(s->irq);
114 static void serial_update_parameters(SerialState *s)
116 int speed, parity, data_bits, stop_bits;
117 QEMUSerialSetParams ssp;
119 if (s->lcr & 0x08) {
120 if (s->lcr & 0x10)
121 parity = 'E';
122 else
123 parity = 'O';
124 } else {
125 parity = 'N';
127 if (s->lcr & 0x04)
128 stop_bits = 2;
129 else
130 stop_bits = 1;
131 data_bits = (s->lcr & 0x03) + 5;
132 if (s->divider == 0)
133 return;
134 speed = 115200 / s->divider;
135 ssp.speed = speed;
136 ssp.parity = parity;
137 ssp.data_bits = data_bits;
138 ssp.stop_bits = stop_bits;
139 qemu_chr_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
140 #if 0
141 printf("speed=%d parity=%c data=%d stop=%d\n",
142 speed, parity, data_bits, stop_bits);
143 #endif
146 static void serial_ioport_write(void *opaque, uint32_t addr, uint32_t val)
148 SerialState *s = opaque;
149 unsigned char ch;
151 addr &= 7;
152 #ifdef DEBUG_SERIAL
153 printf("serial: write addr=0x%02x val=0x%02x\n", addr, val);
154 #endif
155 switch(addr) {
156 default:
157 case 0:
158 if (s->lcr & UART_LCR_DLAB) {
159 s->divider = (s->divider & 0xff00) | val;
160 serial_update_parameters(s);
161 } else {
162 s->thr_ipending = 0;
163 s->lsr &= ~UART_LSR_THRE;
164 serial_update_irq(s);
165 ch = val;
166 if (!(s->mcr & UART_MCR_LOOP)) {
167 /* when not in loopback mode, send the char */
168 qemu_chr_write(s->chr, &ch, 1);
170 s->thr_ipending = 1;
171 s->lsr |= UART_LSR_THRE;
172 s->lsr |= UART_LSR_TEMT;
173 serial_update_irq(s);
174 if (s->mcr & UART_MCR_LOOP) {
175 /* in loopback mode, say that we just received a char */
176 serial_receive_byte(s, ch);
179 break;
180 case 1:
181 if (s->lcr & UART_LCR_DLAB) {
182 s->divider = (s->divider & 0x00ff) | (val << 8);
183 serial_update_parameters(s);
184 } else {
185 s->ier = val & 0x0f;
186 if (s->lsr & UART_LSR_THRE) {
187 s->thr_ipending = 1;
189 serial_update_irq(s);
191 break;
192 case 2:
193 break;
194 case 3:
196 int break_enable;
197 s->lcr = val;
198 serial_update_parameters(s);
199 break_enable = (val >> 6) & 1;
200 if (break_enable != s->last_break_enable) {
201 s->last_break_enable = break_enable;
202 qemu_chr_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_BREAK,
203 &break_enable);
206 break;
207 case 4:
208 s->mcr = val & 0x1f;
209 break;
210 case 5:
211 break;
212 case 6:
213 break;
214 case 7:
215 s->scr = val;
216 break;
220 static uint32_t serial_ioport_read(void *opaque, uint32_t addr)
222 SerialState *s = opaque;
223 uint32_t ret;
225 addr &= 7;
226 switch(addr) {
227 default:
228 case 0:
229 if (s->lcr & UART_LCR_DLAB) {
230 ret = s->divider & 0xff;
231 } else {
232 ret = s->rbr;
233 s->lsr &= ~(UART_LSR_DR | UART_LSR_BI);
234 serial_update_irq(s);
235 if (!(s->mcr & UART_MCR_LOOP)) {
236 /* in loopback mode, don't receive any data */
237 qemu_chr_accept_input(s->chr);
240 break;
241 case 1:
242 if (s->lcr & UART_LCR_DLAB) {
243 ret = (s->divider >> 8) & 0xff;
244 } else {
245 ret = s->ier;
247 break;
248 case 2:
249 ret = s->iir;
250 /* reset THR pending bit */
251 if ((ret & 0x7) == UART_IIR_THRI)
252 s->thr_ipending = 0;
253 serial_update_irq(s);
254 break;
255 case 3:
256 ret = s->lcr;
257 break;
258 case 4:
259 ret = s->mcr;
260 break;
261 case 5:
262 ret = s->lsr;
263 break;
264 case 6:
265 if (s->mcr & UART_MCR_LOOP) {
266 /* in loopback, the modem output pins are connected to the
267 inputs */
268 ret = (s->mcr & 0x0c) << 4;
269 ret |= (s->mcr & 0x02) << 3;
270 ret |= (s->mcr & 0x01) << 5;
271 } else {
272 ret = s->msr;
274 break;
275 case 7:
276 ret = s->scr;
277 break;
279 #ifdef DEBUG_SERIAL
280 printf("serial: read addr=0x%02x val=0x%02x\n", addr, ret);
281 #endif
282 return ret;
285 static int serial_can_receive(SerialState *s)
287 return !(s->lsr & UART_LSR_DR);
290 static void serial_receive_byte(SerialState *s, int ch)
292 s->rbr = ch;
293 s->lsr |= UART_LSR_DR;
294 serial_update_irq(s);
297 static void serial_receive_break(SerialState *s)
299 s->rbr = 0;
300 s->lsr |= UART_LSR_BI | UART_LSR_DR;
301 serial_update_irq(s);
304 static int serial_can_receive1(void *opaque)
306 SerialState *s = opaque;
307 return serial_can_receive(s);
310 static void serial_receive1(void *opaque, const uint8_t *buf, int size)
312 SerialState *s = opaque;
313 serial_receive_byte(s, buf[0]);
316 static void serial_event(void *opaque, int event)
318 SerialState *s = opaque;
319 if (event == CHR_EVENT_BREAK)
320 serial_receive_break(s);
323 static void serial_save(QEMUFile *f, void *opaque)
325 SerialState *s = opaque;
327 qemu_put_be16s(f,&s->divider);
328 qemu_put_8s(f,&s->rbr);
329 qemu_put_8s(f,&s->ier);
330 qemu_put_8s(f,&s->iir);
331 qemu_put_8s(f,&s->lcr);
332 qemu_put_8s(f,&s->mcr);
333 qemu_put_8s(f,&s->lsr);
334 qemu_put_8s(f,&s->msr);
335 qemu_put_8s(f,&s->scr);
338 static int serial_load(QEMUFile *f, void *opaque, int version_id)
340 SerialState *s = opaque;
342 if(version_id > 2)
343 return -EINVAL;
345 if (version_id >= 2)
346 qemu_get_be16s(f, &s->divider);
347 else
348 s->divider = qemu_get_byte(f);
349 qemu_get_8s(f,&s->rbr);
350 qemu_get_8s(f,&s->ier);
351 qemu_get_8s(f,&s->iir);
352 qemu_get_8s(f,&s->lcr);
353 qemu_get_8s(f,&s->mcr);
354 qemu_get_8s(f,&s->lsr);
355 qemu_get_8s(f,&s->msr);
356 qemu_get_8s(f,&s->scr);
358 return 0;
361 static void serial_reset(void *opaque)
363 SerialState *s = opaque;
365 s->divider = 0;
366 s->rbr = 0;
367 s->ier = 0;
368 s->iir = UART_IIR_NO_INT;
369 s->lcr = 0;
370 s->mcr = 0;
371 s->lsr = UART_LSR_TEMT | UART_LSR_THRE;
372 s->msr = UART_MSR_DCD | UART_MSR_DSR | UART_MSR_CTS;
373 s->scr = 0;
375 s->thr_ipending = 0;
376 s->last_break_enable = 0;
377 qemu_irq_lower(s->irq);
380 /* If fd is zero, it means that the serial device uses the console */
381 SerialState *serial_init(int base, qemu_irq irq, CharDriverState *chr)
383 SerialState *s;
385 s = qemu_mallocz(sizeof(SerialState));
386 if (!s)
387 return NULL;
388 s->irq = irq;
390 qemu_register_reset(serial_reset, s);
391 serial_reset(s);
393 register_savevm("serial", base, 2, serial_save, serial_load, s);
395 register_ioport_write(base, 8, 1, serial_ioport_write, s);
396 register_ioport_read(base, 8, 1, serial_ioport_read, s);
397 s->chr = chr;
398 qemu_chr_add_handlers(chr, serial_can_receive1, serial_receive1,
399 serial_event, s);
400 return s;
403 /* Memory mapped interface */
404 uint32_t serial_mm_readb (void *opaque, target_phys_addr_t addr)
406 SerialState *s = opaque;
408 return serial_ioport_read(s, (addr - s->base) >> s->it_shift) & 0xFF;
411 void serial_mm_writeb (void *opaque,
412 target_phys_addr_t addr, uint32_t value)
414 SerialState *s = opaque;
416 serial_ioport_write(s, (addr - s->base) >> s->it_shift, value & 0xFF);
419 uint32_t serial_mm_readw (void *opaque, target_phys_addr_t addr)
421 SerialState *s = opaque;
422 uint32_t val;
424 val = serial_ioport_read(s, (addr - s->base) >> s->it_shift) & 0xFFFF;
425 #ifdef TARGET_WORDS_BIGENDIAN
426 val = bswap16(val);
427 #endif
428 return val;
431 void serial_mm_writew (void *opaque,
432 target_phys_addr_t addr, uint32_t value)
434 SerialState *s = opaque;
435 #ifdef TARGET_WORDS_BIGENDIAN
436 value = bswap16(value);
437 #endif
438 serial_ioport_write(s, (addr - s->base) >> s->it_shift, value & 0xFFFF);
441 uint32_t serial_mm_readl (void *opaque, target_phys_addr_t addr)
443 SerialState *s = opaque;
444 uint32_t val;
446 val = serial_ioport_read(s, (addr - s->base) >> s->it_shift);
447 #ifdef TARGET_WORDS_BIGENDIAN
448 val = bswap32(val);
449 #endif
450 return val;
453 void serial_mm_writel (void *opaque,
454 target_phys_addr_t addr, uint32_t value)
456 SerialState *s = opaque;
457 #ifdef TARGET_WORDS_BIGENDIAN
458 value = bswap32(value);
459 #endif
460 serial_ioport_write(s, (addr - s->base) >> s->it_shift, value);
463 static CPUReadMemoryFunc *serial_mm_read[] = {
464 &serial_mm_readb,
465 &serial_mm_readw,
466 &serial_mm_readl,
469 static CPUWriteMemoryFunc *serial_mm_write[] = {
470 &serial_mm_writeb,
471 &serial_mm_writew,
472 &serial_mm_writel,
475 SerialState *serial_mm_init (target_phys_addr_t base, int it_shift,
476 qemu_irq irq, CharDriverState *chr,
477 int ioregister)
479 SerialState *s;
480 int s_io_memory;
482 s = qemu_mallocz(sizeof(SerialState));
483 if (!s)
484 return NULL;
485 s->irq = irq;
486 s->base = base;
487 s->it_shift = it_shift;
489 qemu_register_reset(serial_reset, s);
490 serial_reset(s);
492 register_savevm("serial", base, 2, serial_save, serial_load, s);
494 if (ioregister) {
495 s_io_memory = cpu_register_io_memory(0, serial_mm_read,
496 serial_mm_write, s);
497 cpu_register_physical_memory(base, 8 << it_shift, s_io_memory);
499 s->chr = chr;
500 qemu_chr_add_handlers(chr, serial_can_receive1, serial_receive1,
501 serial_event, s);
502 return s;