Statistics
| Branch: | Revision:

root / hw / serial.c @ ef845c3b

History | View | Annotate | Download (26.5 kB)

1 80cabfad bellard
/*
2 81174dae aliguori
 * QEMU 16550A UART emulation
3 5fafdf24 ths
 *
4 80cabfad bellard
 * Copyright (c) 2003-2004 Fabrice Bellard
5 81174dae aliguori
 * Copyright (c) 2008 Citrix Systems, Inc.
6 5fafdf24 ths
 *
7 80cabfad bellard
 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 80cabfad bellard
 * of this software and associated documentation files (the "Software"), to deal
9 80cabfad bellard
 * in the Software without restriction, including without limitation the rights
10 80cabfad bellard
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 80cabfad bellard
 * copies of the Software, and to permit persons to whom the Software is
12 80cabfad bellard
 * furnished to do so, subject to the following conditions:
13 80cabfad bellard
 *
14 80cabfad bellard
 * The above copyright notice and this permission notice shall be included in
15 80cabfad bellard
 * all copies or substantial portions of the Software.
16 80cabfad bellard
 *
17 80cabfad bellard
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 80cabfad bellard
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 80cabfad bellard
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 80cabfad bellard
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 80cabfad bellard
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 80cabfad bellard
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 80cabfad bellard
 * THE SOFTWARE.
24 80cabfad bellard
 */
25 87ecb68b pbrook
#include "hw.h"
26 87ecb68b pbrook
#include "qemu-char.h"
27 87ecb68b pbrook
#include "isa.h"
28 87ecb68b pbrook
#include "pc.h"
29 6936bfe5 aurel32
#include "qemu-timer.h"
30 80cabfad bellard
31 80cabfad bellard
//#define DEBUG_SERIAL
32 80cabfad bellard
33 80cabfad bellard
#define UART_LCR_DLAB        0x80        /* Divisor latch access bit */
34 80cabfad bellard
35 80cabfad bellard
#define UART_IER_MSI        0x08        /* Enable Modem status interrupt */
36 80cabfad bellard
#define UART_IER_RLSI        0x04        /* Enable receiver line status interrupt */
37 80cabfad bellard
#define UART_IER_THRI        0x02        /* Enable Transmitter holding register int. */
38 80cabfad bellard
#define UART_IER_RDI        0x01        /* Enable receiver data interrupt */
39 80cabfad bellard
40 80cabfad bellard
#define UART_IIR_NO_INT        0x01        /* No interrupts pending */
41 80cabfad bellard
#define UART_IIR_ID        0x06        /* Mask for the interrupt ID */
42 80cabfad bellard
43 80cabfad bellard
#define UART_IIR_MSI        0x00        /* Modem status interrupt */
44 80cabfad bellard
#define UART_IIR_THRI        0x02        /* Transmitter holding register empty */
45 80cabfad bellard
#define UART_IIR_RDI        0x04        /* Receiver data interrupt */
46 80cabfad bellard
#define UART_IIR_RLSI        0x06        /* Receiver line status interrupt */
47 81174dae aliguori
#define UART_IIR_CTI    0x0C    /* Character Timeout Indication */
48 81174dae aliguori
49 81174dae aliguori
#define UART_IIR_FENF   0x80    /* Fifo enabled, but not functionning */
50 81174dae aliguori
#define UART_IIR_FE     0xC0    /* Fifo enabled */
51 80cabfad bellard
52 80cabfad bellard
/*
53 80cabfad bellard
 * These are the definitions for the Modem Control Register
54 80cabfad bellard
 */
55 80cabfad bellard
#define UART_MCR_LOOP        0x10        /* Enable loopback test mode */
56 80cabfad bellard
#define UART_MCR_OUT2        0x08        /* Out2 complement */
57 80cabfad bellard
#define UART_MCR_OUT1        0x04        /* Out1 complement */
58 80cabfad bellard
#define UART_MCR_RTS        0x02        /* RTS complement */
59 80cabfad bellard
#define UART_MCR_DTR        0x01        /* DTR complement */
60 80cabfad bellard
61 80cabfad bellard
/*
62 80cabfad bellard
 * These are the definitions for the Modem Status Register
63 80cabfad bellard
 */
64 80cabfad bellard
#define UART_MSR_DCD        0x80        /* Data Carrier Detect */
65 80cabfad bellard
#define UART_MSR_RI        0x40        /* Ring Indicator */
66 80cabfad bellard
#define UART_MSR_DSR        0x20        /* Data Set Ready */
67 80cabfad bellard
#define UART_MSR_CTS        0x10        /* Clear to Send */
68 80cabfad bellard
#define UART_MSR_DDCD        0x08        /* Delta DCD */
69 80cabfad bellard
#define UART_MSR_TERI        0x04        /* Trailing edge ring indicator */
70 80cabfad bellard
#define UART_MSR_DDSR        0x02        /* Delta DSR */
71 80cabfad bellard
#define UART_MSR_DCTS        0x01        /* Delta CTS */
72 80cabfad bellard
#define UART_MSR_ANY_DELTA 0x0F        /* Any of the delta bits! */
73 80cabfad bellard
74 80cabfad bellard
#define UART_LSR_TEMT        0x40        /* Transmitter empty */
75 80cabfad bellard
#define UART_LSR_THRE        0x20        /* Transmit-hold-register empty */
76 80cabfad bellard
#define UART_LSR_BI        0x10        /* Break interrupt indicator */
77 80cabfad bellard
#define UART_LSR_FE        0x08        /* Frame error indicator */
78 80cabfad bellard
#define UART_LSR_PE        0x04        /* Parity error indicator */
79 80cabfad bellard
#define UART_LSR_OE        0x02        /* Overrun error indicator */
80 80cabfad bellard
#define UART_LSR_DR        0x01        /* Receiver data ready */
81 81174dae aliguori
#define UART_LSR_INT_ANY 0x1E        /* Any of the lsr-interrupt-triggering status bits */
82 80cabfad bellard
83 81174dae aliguori
/* Interrupt trigger levels. The byte-counts are for 16550A - in newer UARTs the byte-count for each ITL is higher. */
84 81174dae aliguori
85 81174dae aliguori
#define UART_FCR_ITL_1      0x00 /* 1 byte ITL */
86 81174dae aliguori
#define UART_FCR_ITL_2      0x40 /* 4 bytes ITL */
87 81174dae aliguori
#define UART_FCR_ITL_3      0x80 /* 8 bytes ITL */
88 81174dae aliguori
#define UART_FCR_ITL_4      0xC0 /* 14 bytes ITL */
89 81174dae aliguori
90 81174dae aliguori
#define UART_FCR_DMS        0x08    /* DMA Mode Select */
91 81174dae aliguori
#define UART_FCR_XFR        0x04    /* XMIT Fifo Reset */
92 81174dae aliguori
#define UART_FCR_RFR        0x02    /* RCVR Fifo Reset */
93 81174dae aliguori
#define UART_FCR_FE         0x01    /* FIFO Enable */
94 81174dae aliguori
95 81174dae aliguori
#define UART_FIFO_LENGTH    16      /* 16550A Fifo Length */
96 81174dae aliguori
97 81174dae aliguori
#define XMIT_FIFO           0
98 81174dae aliguori
#define RECV_FIFO           1
99 81174dae aliguori
#define MAX_XMIT_RETRY      4
100 81174dae aliguori
101 2b321d69 Juan Quintela
typedef struct SerialFIFO {
102 81174dae aliguori
    uint8_t data[UART_FIFO_LENGTH];
103 81174dae aliguori
    uint8_t count;
104 81174dae aliguori
    uint8_t itl;                        /* Interrupt Trigger Level */
105 81174dae aliguori
    uint8_t tail;
106 81174dae aliguori
    uint8_t head;
107 2b321d69 Juan Quintela
} SerialFIFO;
108 6936bfe5 aurel32
109 b41a2cd1 bellard
struct SerialState {
110 508d92d0 bellard
    uint16_t divider;
111 80cabfad bellard
    uint8_t rbr; /* receive register */
112 81174dae aliguori
    uint8_t thr; /* transmit holding register */
113 81174dae aliguori
    uint8_t tsr; /* transmit shift register */
114 80cabfad bellard
    uint8_t ier;
115 80cabfad bellard
    uint8_t iir; /* read only */
116 80cabfad bellard
    uint8_t lcr;
117 80cabfad bellard
    uint8_t mcr;
118 80cabfad bellard
    uint8_t lsr; /* read only */
119 3e749fe1 bellard
    uint8_t msr; /* read only */
120 80cabfad bellard
    uint8_t scr;
121 81174dae aliguori
    uint8_t fcr;
122 747791f1 Juan Quintela
    uint8_t fcr_vmstate; /* we can't write directly this value
123 747791f1 Juan Quintela
                            it has side effects */
124 80cabfad bellard
    /* NOTE: this hidden state is necessary for tx irq generation as
125 80cabfad bellard
       it can be reset while reading iir */
126 80cabfad bellard
    int thr_ipending;
127 d537cf6c pbrook
    qemu_irq irq;
128 82c643ff bellard
    CharDriverState *chr;
129 f8d179e3 bellard
    int last_break_enable;
130 e5d13e2f bellard
    int it_shift;
131 b6cd0ea1 aurel32
    int baudbase;
132 81174dae aliguori
    int tsr_retry;
133 81174dae aliguori
134 81174dae aliguori
    uint64_t last_xmit_ts;              /* Time when the last byte was successfully sent out of the tsr */
135 81174dae aliguori
    SerialFIFO recv_fifo;
136 81174dae aliguori
    SerialFIFO xmit_fifo;
137 81174dae aliguori
138 81174dae aliguori
    struct QEMUTimer *fifo_timeout_timer;
139 81174dae aliguori
    int timeout_ipending;                   /* timeout interrupt pending state */
140 81174dae aliguori
    struct QEMUTimer *transmit_timer;
141 81174dae aliguori
142 81174dae aliguori
143 81174dae aliguori
    uint64_t char_transmit_time;               /* time to transmit a char in ticks*/
144 81174dae aliguori
    int poll_msl;
145 81174dae aliguori
146 81174dae aliguori
    struct QEMUTimer *modem_status_poll;
147 b41a2cd1 bellard
};
148 80cabfad bellard
149 ac0be998 Gerd Hoffmann
typedef struct ISASerialState {
150 ac0be998 Gerd Hoffmann
    ISADevice dev;
151 ac0be998 Gerd Hoffmann
    uint32_t iobase;
152 ac0be998 Gerd Hoffmann
    uint32_t isairq;
153 ac0be998 Gerd Hoffmann
    SerialState state;
154 ac0be998 Gerd Hoffmann
} ISASerialState;
155 ac0be998 Gerd Hoffmann
156 81174dae aliguori
static void serial_receive1(void *opaque, const uint8_t *buf, int size);
157 b2a5160c balrog
158 81174dae aliguori
static void fifo_clear(SerialState *s, int fifo)
159 80cabfad bellard
{
160 81174dae aliguori
    SerialFIFO *f = (fifo) ? &s->recv_fifo : &s->xmit_fifo;
161 81174dae aliguori
    memset(f->data, 0, UART_FIFO_LENGTH);
162 81174dae aliguori
    f->count = 0;
163 81174dae aliguori
    f->head = 0;
164 81174dae aliguori
    f->tail = 0;
165 80cabfad bellard
}
166 80cabfad bellard
167 81174dae aliguori
static int fifo_put(SerialState *s, int fifo, uint8_t chr)
168 6936bfe5 aurel32
{
169 81174dae aliguori
    SerialFIFO *f = (fifo) ? &s->recv_fifo : &s->xmit_fifo;
170 6936bfe5 aurel32
171 81174dae aliguori
    f->data[f->head++] = chr;
172 6936bfe5 aurel32
173 81174dae aliguori
    if (f->head == UART_FIFO_LENGTH)
174 81174dae aliguori
        f->head = 0;
175 81174dae aliguori
    f->count++;
176 81174dae aliguori
177 81174dae aliguori
    return 1;
178 81174dae aliguori
}
179 81174dae aliguori
180 81174dae aliguori
static uint8_t fifo_get(SerialState *s, int fifo)
181 81174dae aliguori
{
182 81174dae aliguori
    SerialFIFO *f = (fifo) ? &s->recv_fifo : &s->xmit_fifo;
183 81174dae aliguori
    uint8_t c;
184 81174dae aliguori
185 81174dae aliguori
    if(f->count == 0)
186 81174dae aliguori
        return 0;
187 81174dae aliguori
188 81174dae aliguori
    c = f->data[f->tail++];
189 81174dae aliguori
    if (f->tail == UART_FIFO_LENGTH)
190 81174dae aliguori
        f->tail = 0;
191 81174dae aliguori
    f->count--;
192 81174dae aliguori
193 81174dae aliguori
    return c;
194 81174dae aliguori
}
195 6936bfe5 aurel32
196 81174dae aliguori
static void serial_update_irq(SerialState *s)
197 81174dae aliguori
{
198 81174dae aliguori
    uint8_t tmp_iir = UART_IIR_NO_INT;
199 81174dae aliguori
200 81174dae aliguori
    if ((s->ier & UART_IER_RLSI) && (s->lsr & UART_LSR_INT_ANY)) {
201 81174dae aliguori
        tmp_iir = UART_IIR_RLSI;
202 5628a626 balrog
    } else if ((s->ier & UART_IER_RDI) && s->timeout_ipending) {
203 c9a33054 balrog
        /* Note that(s->ier & UART_IER_RDI) can mask this interrupt,
204 c9a33054 balrog
         * this is not in the specification but is observed on existing
205 c9a33054 balrog
         * hardware.  */
206 81174dae aliguori
        tmp_iir = UART_IIR_CTI;
207 2d6ee8e7 Juergen Lock
    } else if ((s->ier & UART_IER_RDI) && (s->lsr & UART_LSR_DR) &&
208 2d6ee8e7 Juergen Lock
               (!(s->fcr & UART_FCR_FE) ||
209 2d6ee8e7 Juergen Lock
                s->recv_fifo.count >= s->recv_fifo.itl)) {
210 2d6ee8e7 Juergen Lock
        tmp_iir = UART_IIR_RDI;
211 81174dae aliguori
    } else if ((s->ier & UART_IER_THRI) && s->thr_ipending) {
212 81174dae aliguori
        tmp_iir = UART_IIR_THRI;
213 81174dae aliguori
    } else if ((s->ier & UART_IER_MSI) && (s->msr & UART_MSR_ANY_DELTA)) {
214 81174dae aliguori
        tmp_iir = UART_IIR_MSI;
215 81174dae aliguori
    }
216 81174dae aliguori
217 81174dae aliguori
    s->iir = tmp_iir | (s->iir & 0xF0);
218 81174dae aliguori
219 81174dae aliguori
    if (tmp_iir != UART_IIR_NO_INT) {
220 81174dae aliguori
        qemu_irq_raise(s->irq);
221 81174dae aliguori
    } else {
222 81174dae aliguori
        qemu_irq_lower(s->irq);
223 6936bfe5 aurel32
    }
224 6936bfe5 aurel32
}
225 6936bfe5 aurel32
226 f8d179e3 bellard
static void serial_update_parameters(SerialState *s)
227 f8d179e3 bellard
{
228 81174dae aliguori
    int speed, parity, data_bits, stop_bits, frame_size;
229 2122c51a bellard
    QEMUSerialSetParams ssp;
230 f8d179e3 bellard
231 81174dae aliguori
    if (s->divider == 0)
232 81174dae aliguori
        return;
233 81174dae aliguori
234 81174dae aliguori
    frame_size = 1;
235 f8d179e3 bellard
    if (s->lcr & 0x08) {
236 f8d179e3 bellard
        if (s->lcr & 0x10)
237 f8d179e3 bellard
            parity = 'E';
238 f8d179e3 bellard
        else
239 f8d179e3 bellard
            parity = 'O';
240 f8d179e3 bellard
    } else {
241 f8d179e3 bellard
            parity = 'N';
242 81174dae aliguori
            frame_size = 0;
243 f8d179e3 bellard
    }
244 5fafdf24 ths
    if (s->lcr & 0x04)
245 f8d179e3 bellard
        stop_bits = 2;
246 f8d179e3 bellard
    else
247 f8d179e3 bellard
        stop_bits = 1;
248 81174dae aliguori
249 f8d179e3 bellard
    data_bits = (s->lcr & 0x03) + 5;
250 81174dae aliguori
    frame_size += data_bits + stop_bits;
251 b6cd0ea1 aurel32
    speed = s->baudbase / s->divider;
252 2122c51a bellard
    ssp.speed = speed;
253 2122c51a bellard
    ssp.parity = parity;
254 2122c51a bellard
    ssp.data_bits = data_bits;
255 2122c51a bellard
    ssp.stop_bits = stop_bits;
256 6ee093c9 Juan Quintela
    s->char_transmit_time =  (get_ticks_per_sec() / speed) * frame_size;
257 2122c51a bellard
    qemu_chr_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
258 2122c51a bellard
#if 0
259 5fafdf24 ths
    printf("speed=%d parity=%c data=%d stop=%d\n",
260 f8d179e3 bellard
           speed, parity, data_bits, stop_bits);
261 f8d179e3 bellard
#endif
262 f8d179e3 bellard
}
263 f8d179e3 bellard
264 81174dae aliguori
static void serial_update_msl(SerialState *s)
265 81174dae aliguori
{
266 81174dae aliguori
    uint8_t omsr;
267 81174dae aliguori
    int flags;
268 81174dae aliguori
269 81174dae aliguori
    qemu_del_timer(s->modem_status_poll);
270 81174dae aliguori
271 81174dae aliguori
    if (qemu_chr_ioctl(s->chr,CHR_IOCTL_SERIAL_GET_TIOCM, &flags) == -ENOTSUP) {
272 81174dae aliguori
        s->poll_msl = -1;
273 81174dae aliguori
        return;
274 81174dae aliguori
    }
275 81174dae aliguori
276 81174dae aliguori
    omsr = s->msr;
277 81174dae aliguori
278 81174dae aliguori
    s->msr = (flags & CHR_TIOCM_CTS) ? s->msr | UART_MSR_CTS : s->msr & ~UART_MSR_CTS;
279 81174dae aliguori
    s->msr = (flags & CHR_TIOCM_DSR) ? s->msr | UART_MSR_DSR : s->msr & ~UART_MSR_DSR;
280 81174dae aliguori
    s->msr = (flags & CHR_TIOCM_CAR) ? s->msr | UART_MSR_DCD : s->msr & ~UART_MSR_DCD;
281 81174dae aliguori
    s->msr = (flags & CHR_TIOCM_RI) ? s->msr | UART_MSR_RI : s->msr & ~UART_MSR_RI;
282 81174dae aliguori
283 81174dae aliguori
    if (s->msr != omsr) {
284 81174dae aliguori
         /* Set delta bits */
285 81174dae aliguori
         s->msr = s->msr | ((s->msr >> 4) ^ (omsr >> 4));
286 81174dae aliguori
         /* UART_MSR_TERI only if change was from 1 -> 0 */
287 81174dae aliguori
         if ((s->msr & UART_MSR_TERI) && !(omsr & UART_MSR_RI))
288 81174dae aliguori
             s->msr &= ~UART_MSR_TERI;
289 81174dae aliguori
         serial_update_irq(s);
290 81174dae aliguori
    }
291 81174dae aliguori
292 81174dae aliguori
    /* The real 16550A apparently has a 250ns response latency to line status changes.
293 81174dae aliguori
       We'll be lazy and poll only every 10ms, and only poll it at all if MSI interrupts are turned on */
294 81174dae aliguori
295 81174dae aliguori
    if (s->poll_msl)
296 6ee093c9 Juan Quintela
        qemu_mod_timer(s->modem_status_poll, qemu_get_clock(vm_clock) + get_ticks_per_sec() / 100);
297 81174dae aliguori
}
298 81174dae aliguori
299 81174dae aliguori
static void serial_xmit(void *opaque)
300 81174dae aliguori
{
301 81174dae aliguori
    SerialState *s = opaque;
302 81174dae aliguori
    uint64_t new_xmit_ts = qemu_get_clock(vm_clock);
303 81174dae aliguori
304 81174dae aliguori
    if (s->tsr_retry <= 0) {
305 81174dae aliguori
        if (s->fcr & UART_FCR_FE) {
306 81174dae aliguori
            s->tsr = fifo_get(s,XMIT_FIFO);
307 81174dae aliguori
            if (!s->xmit_fifo.count)
308 81174dae aliguori
                s->lsr |= UART_LSR_THRE;
309 81174dae aliguori
        } else {
310 81174dae aliguori
            s->tsr = s->thr;
311 81174dae aliguori
            s->lsr |= UART_LSR_THRE;
312 81174dae aliguori
        }
313 81174dae aliguori
    }
314 81174dae aliguori
315 81174dae aliguori
    if (s->mcr & UART_MCR_LOOP) {
316 81174dae aliguori
        /* in loopback mode, say that we just received a char */
317 81174dae aliguori
        serial_receive1(s, &s->tsr, 1);
318 81174dae aliguori
    } else if (qemu_chr_write(s->chr, &s->tsr, 1) != 1) {
319 81174dae aliguori
        if ((s->tsr_retry > 0) && (s->tsr_retry <= MAX_XMIT_RETRY)) {
320 81174dae aliguori
            s->tsr_retry++;
321 81174dae aliguori
            qemu_mod_timer(s->transmit_timer,  new_xmit_ts + s->char_transmit_time);
322 81174dae aliguori
            return;
323 81174dae aliguori
        } else if (s->poll_msl < 0) {
324 81174dae aliguori
            /* If we exceed MAX_XMIT_RETRY and the backend is not a real serial port, then
325 81174dae aliguori
            drop any further failed writes instantly, until we get one that goes through.
326 81174dae aliguori
            This is to prevent guests that log to unconnected pipes or pty's from stalling. */
327 81174dae aliguori
            s->tsr_retry = -1;
328 81174dae aliguori
        }
329 81174dae aliguori
    }
330 81174dae aliguori
    else {
331 81174dae aliguori
        s->tsr_retry = 0;
332 81174dae aliguori
    }
333 81174dae aliguori
334 81174dae aliguori
    s->last_xmit_ts = qemu_get_clock(vm_clock);
335 81174dae aliguori
    if (!(s->lsr & UART_LSR_THRE))
336 81174dae aliguori
        qemu_mod_timer(s->transmit_timer, s->last_xmit_ts + s->char_transmit_time);
337 81174dae aliguori
338 81174dae aliguori
    if (s->lsr & UART_LSR_THRE) {
339 81174dae aliguori
        s->lsr |= UART_LSR_TEMT;
340 81174dae aliguori
        s->thr_ipending = 1;
341 81174dae aliguori
        serial_update_irq(s);
342 81174dae aliguori
    }
343 81174dae aliguori
}
344 81174dae aliguori
345 81174dae aliguori
346 b41a2cd1 bellard
static void serial_ioport_write(void *opaque, uint32_t addr, uint32_t val)
347 80cabfad bellard
{
348 b41a2cd1 bellard
    SerialState *s = opaque;
349 3b46e624 ths
350 80cabfad bellard
    addr &= 7;
351 80cabfad bellard
#ifdef DEBUG_SERIAL
352 80cabfad bellard
    printf("serial: write addr=0x%02x val=0x%02x\n", addr, val);
353 80cabfad bellard
#endif
354 80cabfad bellard
    switch(addr) {
355 80cabfad bellard
    default:
356 80cabfad bellard
    case 0:
357 80cabfad bellard
        if (s->lcr & UART_LCR_DLAB) {
358 80cabfad bellard
            s->divider = (s->divider & 0xff00) | val;
359 f8d179e3 bellard
            serial_update_parameters(s);
360 80cabfad bellard
        } else {
361 81174dae aliguori
            s->thr = (uint8_t) val;
362 81174dae aliguori
            if(s->fcr & UART_FCR_FE) {
363 81174dae aliguori
                  fifo_put(s, XMIT_FIFO, s->thr);
364 80cabfad bellard
            s->thr_ipending = 0;
365 81174dae aliguori
                  s->lsr &= ~UART_LSR_TEMT;
366 80cabfad bellard
            s->lsr &= ~UART_LSR_THRE;
367 b41a2cd1 bellard
            serial_update_irq(s);
368 6936bfe5 aurel32
            } else {
369 81174dae aliguori
                  s->thr_ipending = 0;
370 81174dae aliguori
                  s->lsr &= ~UART_LSR_THRE;
371 81174dae aliguori
                  serial_update_irq(s);
372 6936bfe5 aurel32
            }
373 81174dae aliguori
            serial_xmit(s);
374 80cabfad bellard
        }
375 80cabfad bellard
        break;
376 80cabfad bellard
    case 1:
377 80cabfad bellard
        if (s->lcr & UART_LCR_DLAB) {
378 80cabfad bellard
            s->divider = (s->divider & 0x00ff) | (val << 8);
379 f8d179e3 bellard
            serial_update_parameters(s);
380 80cabfad bellard
        } else {
381 60e336db bellard
            s->ier = val & 0x0f;
382 81174dae aliguori
            /* If the backend device is a real serial port, turn polling of the modem
383 81174dae aliguori
               status lines on physical port on or off depending on UART_IER_MSI state */
384 81174dae aliguori
            if (s->poll_msl >= 0) {
385 81174dae aliguori
                if (s->ier & UART_IER_MSI) {
386 81174dae aliguori
                     s->poll_msl = 1;
387 81174dae aliguori
                     serial_update_msl(s);
388 81174dae aliguori
                } else {
389 81174dae aliguori
                     qemu_del_timer(s->modem_status_poll);
390 81174dae aliguori
                     s->poll_msl = 0;
391 81174dae aliguori
                }
392 81174dae aliguori
            }
393 60e336db bellard
            if (s->lsr & UART_LSR_THRE) {
394 60e336db bellard
                s->thr_ipending = 1;
395 81174dae aliguori
                serial_update_irq(s);
396 60e336db bellard
            }
397 80cabfad bellard
        }
398 80cabfad bellard
        break;
399 80cabfad bellard
    case 2:
400 81174dae aliguori
        val = val & 0xFF;
401 81174dae aliguori
402 81174dae aliguori
        if (s->fcr == val)
403 81174dae aliguori
            break;
404 81174dae aliguori
405 81174dae aliguori
        /* Did the enable/disable flag change? If so, make sure FIFOs get flushed */
406 81174dae aliguori
        if ((val ^ s->fcr) & UART_FCR_FE)
407 81174dae aliguori
            val |= UART_FCR_XFR | UART_FCR_RFR;
408 81174dae aliguori
409 81174dae aliguori
        /* FIFO clear */
410 81174dae aliguori
411 81174dae aliguori
        if (val & UART_FCR_RFR) {
412 81174dae aliguori
            qemu_del_timer(s->fifo_timeout_timer);
413 81174dae aliguori
            s->timeout_ipending=0;
414 81174dae aliguori
            fifo_clear(s,RECV_FIFO);
415 81174dae aliguori
        }
416 81174dae aliguori
417 81174dae aliguori
        if (val & UART_FCR_XFR) {
418 81174dae aliguori
            fifo_clear(s,XMIT_FIFO);
419 81174dae aliguori
        }
420 81174dae aliguori
421 81174dae aliguori
        if (val & UART_FCR_FE) {
422 81174dae aliguori
            s->iir |= UART_IIR_FE;
423 81174dae aliguori
            /* Set RECV_FIFO trigger Level */
424 81174dae aliguori
            switch (val & 0xC0) {
425 81174dae aliguori
            case UART_FCR_ITL_1:
426 81174dae aliguori
                s->recv_fifo.itl = 1;
427 81174dae aliguori
                break;
428 81174dae aliguori
            case UART_FCR_ITL_2:
429 81174dae aliguori
                s->recv_fifo.itl = 4;
430 81174dae aliguori
                break;
431 81174dae aliguori
            case UART_FCR_ITL_3:
432 81174dae aliguori
                s->recv_fifo.itl = 8;
433 81174dae aliguori
                break;
434 81174dae aliguori
            case UART_FCR_ITL_4:
435 81174dae aliguori
                s->recv_fifo.itl = 14;
436 81174dae aliguori
                break;
437 81174dae aliguori
            }
438 81174dae aliguori
        } else
439 81174dae aliguori
            s->iir &= ~UART_IIR_FE;
440 81174dae aliguori
441 81174dae aliguori
        /* Set fcr - or at least the bits in it that are supposed to "stick" */
442 81174dae aliguori
        s->fcr = val & 0xC9;
443 81174dae aliguori
        serial_update_irq(s);
444 80cabfad bellard
        break;
445 80cabfad bellard
    case 3:
446 f8d179e3 bellard
        {
447 f8d179e3 bellard
            int break_enable;
448 f8d179e3 bellard
            s->lcr = val;
449 f8d179e3 bellard
            serial_update_parameters(s);
450 f8d179e3 bellard
            break_enable = (val >> 6) & 1;
451 f8d179e3 bellard
            if (break_enable != s->last_break_enable) {
452 f8d179e3 bellard
                s->last_break_enable = break_enable;
453 5fafdf24 ths
                qemu_chr_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_BREAK,
454 2122c51a bellard
                               &break_enable);
455 f8d179e3 bellard
            }
456 f8d179e3 bellard
        }
457 80cabfad bellard
        break;
458 80cabfad bellard
    case 4:
459 81174dae aliguori
        {
460 81174dae aliguori
            int flags;
461 81174dae aliguori
            int old_mcr = s->mcr;
462 81174dae aliguori
            s->mcr = val & 0x1f;
463 81174dae aliguori
            if (val & UART_MCR_LOOP)
464 81174dae aliguori
                break;
465 81174dae aliguori
466 81174dae aliguori
            if (s->poll_msl >= 0 && old_mcr != s->mcr) {
467 81174dae aliguori
468 81174dae aliguori
                qemu_chr_ioctl(s->chr,CHR_IOCTL_SERIAL_GET_TIOCM, &flags);
469 81174dae aliguori
470 81174dae aliguori
                flags &= ~(CHR_TIOCM_RTS | CHR_TIOCM_DTR);
471 81174dae aliguori
472 81174dae aliguori
                if (val & UART_MCR_RTS)
473 81174dae aliguori
                    flags |= CHR_TIOCM_RTS;
474 81174dae aliguori
                if (val & UART_MCR_DTR)
475 81174dae aliguori
                    flags |= CHR_TIOCM_DTR;
476 81174dae aliguori
477 81174dae aliguori
                qemu_chr_ioctl(s->chr,CHR_IOCTL_SERIAL_SET_TIOCM, &flags);
478 81174dae aliguori
                /* Update the modem status after a one-character-send wait-time, since there may be a response
479 81174dae aliguori
                   from the device/computer at the other end of the serial line */
480 81174dae aliguori
                qemu_mod_timer(s->modem_status_poll, qemu_get_clock(vm_clock) + s->char_transmit_time);
481 81174dae aliguori
            }
482 81174dae aliguori
        }
483 80cabfad bellard
        break;
484 80cabfad bellard
    case 5:
485 80cabfad bellard
        break;
486 80cabfad bellard
    case 6:
487 80cabfad bellard
        break;
488 80cabfad bellard
    case 7:
489 80cabfad bellard
        s->scr = val;
490 80cabfad bellard
        break;
491 80cabfad bellard
    }
492 80cabfad bellard
}
493 80cabfad bellard
494 b41a2cd1 bellard
static uint32_t serial_ioport_read(void *opaque, uint32_t addr)
495 80cabfad bellard
{
496 b41a2cd1 bellard
    SerialState *s = opaque;
497 80cabfad bellard
    uint32_t ret;
498 80cabfad bellard
499 80cabfad bellard
    addr &= 7;
500 80cabfad bellard
    switch(addr) {
501 80cabfad bellard
    default:
502 80cabfad bellard
    case 0:
503 80cabfad bellard
        if (s->lcr & UART_LCR_DLAB) {
504 5fafdf24 ths
            ret = s->divider & 0xff;
505 80cabfad bellard
        } else {
506 81174dae aliguori
            if(s->fcr & UART_FCR_FE) {
507 81174dae aliguori
                ret = fifo_get(s,RECV_FIFO);
508 81174dae aliguori
                if (s->recv_fifo.count == 0)
509 81174dae aliguori
                    s->lsr &= ~(UART_LSR_DR | UART_LSR_BI);
510 81174dae aliguori
                else
511 81174dae aliguori
                    qemu_mod_timer(s->fifo_timeout_timer, qemu_get_clock (vm_clock) + s->char_transmit_time * 4);
512 81174dae aliguori
                s->timeout_ipending = 0;
513 81174dae aliguori
            } else {
514 81174dae aliguori
                ret = s->rbr;
515 81174dae aliguori
                s->lsr &= ~(UART_LSR_DR | UART_LSR_BI);
516 81174dae aliguori
            }
517 b41a2cd1 bellard
            serial_update_irq(s);
518 b2a5160c balrog
            if (!(s->mcr & UART_MCR_LOOP)) {
519 b2a5160c balrog
                /* in loopback mode, don't receive any data */
520 b2a5160c balrog
                qemu_chr_accept_input(s->chr);
521 b2a5160c balrog
            }
522 80cabfad bellard
        }
523 80cabfad bellard
        break;
524 80cabfad bellard
    case 1:
525 80cabfad bellard
        if (s->lcr & UART_LCR_DLAB) {
526 80cabfad bellard
            ret = (s->divider >> 8) & 0xff;
527 80cabfad bellard
        } else {
528 80cabfad bellard
            ret = s->ier;
529 80cabfad bellard
        }
530 80cabfad bellard
        break;
531 80cabfad bellard
    case 2:
532 80cabfad bellard
        ret = s->iir;
533 80cabfad bellard
            s->thr_ipending = 0;
534 b41a2cd1 bellard
        serial_update_irq(s);
535 80cabfad bellard
        break;
536 80cabfad bellard
    case 3:
537 80cabfad bellard
        ret = s->lcr;
538 80cabfad bellard
        break;
539 80cabfad bellard
    case 4:
540 80cabfad bellard
        ret = s->mcr;
541 80cabfad bellard
        break;
542 80cabfad bellard
    case 5:
543 80cabfad bellard
        ret = s->lsr;
544 81174dae aliguori
        /* Clear break interrupt */
545 81174dae aliguori
        if (s->lsr & UART_LSR_BI) {
546 81174dae aliguori
            s->lsr &= ~UART_LSR_BI;
547 81174dae aliguori
            serial_update_irq(s);
548 81174dae aliguori
        }
549 80cabfad bellard
        break;
550 80cabfad bellard
    case 6:
551 80cabfad bellard
        if (s->mcr & UART_MCR_LOOP) {
552 80cabfad bellard
            /* in loopback, the modem output pins are connected to the
553 80cabfad bellard
               inputs */
554 80cabfad bellard
            ret = (s->mcr & 0x0c) << 4;
555 80cabfad bellard
            ret |= (s->mcr & 0x02) << 3;
556 80cabfad bellard
            ret |= (s->mcr & 0x01) << 5;
557 80cabfad bellard
        } else {
558 81174dae aliguori
            if (s->poll_msl >= 0)
559 81174dae aliguori
                serial_update_msl(s);
560 80cabfad bellard
            ret = s->msr;
561 81174dae aliguori
            /* Clear delta bits & msr int after read, if they were set */
562 81174dae aliguori
            if (s->msr & UART_MSR_ANY_DELTA) {
563 81174dae aliguori
                s->msr &= 0xF0;
564 81174dae aliguori
                serial_update_irq(s);
565 81174dae aliguori
            }
566 80cabfad bellard
        }
567 80cabfad bellard
        break;
568 80cabfad bellard
    case 7:
569 80cabfad bellard
        ret = s->scr;
570 80cabfad bellard
        break;
571 80cabfad bellard
    }
572 80cabfad bellard
#ifdef DEBUG_SERIAL
573 80cabfad bellard
    printf("serial: read addr=0x%02x val=0x%02x\n", addr, ret);
574 80cabfad bellard
#endif
575 80cabfad bellard
    return ret;
576 80cabfad bellard
}
577 80cabfad bellard
578 82c643ff bellard
static int serial_can_receive(SerialState *s)
579 80cabfad bellard
{
580 81174dae aliguori
    if(s->fcr & UART_FCR_FE) {
581 81174dae aliguori
        if(s->recv_fifo.count < UART_FIFO_LENGTH)
582 81174dae aliguori
        /* Advertise (fifo.itl - fifo.count) bytes when count < ITL, and 1 if above. If UART_FIFO_LENGTH - fifo.count is
583 81174dae aliguori
        advertised the effect will be to almost always fill the fifo completely before the guest has a chance to respond,
584 81174dae aliguori
        effectively overriding the ITL that the guest has set. */
585 81174dae aliguori
             return (s->recv_fifo.count <= s->recv_fifo.itl) ? s->recv_fifo.itl - s->recv_fifo.count : 1;
586 81174dae aliguori
        else
587 81174dae aliguori
             return 0;
588 81174dae aliguori
    } else {
589 80cabfad bellard
    return !(s->lsr & UART_LSR_DR);
590 81174dae aliguori
    }
591 80cabfad bellard
}
592 80cabfad bellard
593 82c643ff bellard
static void serial_receive_break(SerialState *s)
594 80cabfad bellard
{
595 80cabfad bellard
    s->rbr = 0;
596 40ff1624 Jason Wessel
    /* When the LSR_DR is set a null byte is pushed into the fifo */
597 40ff1624 Jason Wessel
    fifo_put(s, RECV_FIFO, '\0');
598 80cabfad bellard
    s->lsr |= UART_LSR_BI | UART_LSR_DR;
599 b41a2cd1 bellard
    serial_update_irq(s);
600 80cabfad bellard
}
601 80cabfad bellard
602 81174dae aliguori
/* There's data in recv_fifo and s->rbr has not been read for 4 char transmit times */
603 81174dae aliguori
static void fifo_timeout_int (void *opaque) {
604 81174dae aliguori
    SerialState *s = opaque;
605 81174dae aliguori
    if (s->recv_fifo.count) {
606 81174dae aliguori
        s->timeout_ipending = 1;
607 81174dae aliguori
        serial_update_irq(s);
608 81174dae aliguori
    }
609 81174dae aliguori
}
610 81174dae aliguori
611 b41a2cd1 bellard
static int serial_can_receive1(void *opaque)
612 80cabfad bellard
{
613 b41a2cd1 bellard
    SerialState *s = opaque;
614 b41a2cd1 bellard
    return serial_can_receive(s);
615 b41a2cd1 bellard
}
616 b41a2cd1 bellard
617 b41a2cd1 bellard
static void serial_receive1(void *opaque, const uint8_t *buf, int size)
618 b41a2cd1 bellard
{
619 b41a2cd1 bellard
    SerialState *s = opaque;
620 81174dae aliguori
    if(s->fcr & UART_FCR_FE) {
621 81174dae aliguori
        int i;
622 81174dae aliguori
        for (i = 0; i < size; i++) {
623 81174dae aliguori
            fifo_put(s, RECV_FIFO, buf[i]);
624 81174dae aliguori
        }
625 81174dae aliguori
        s->lsr |= UART_LSR_DR;
626 81174dae aliguori
        /* call the timeout receive callback in 4 char transmit time */
627 81174dae aliguori
        qemu_mod_timer(s->fifo_timeout_timer, qemu_get_clock (vm_clock) + s->char_transmit_time * 4);
628 81174dae aliguori
    } else {
629 81174dae aliguori
        s->rbr = buf[0];
630 81174dae aliguori
        s->lsr |= UART_LSR_DR;
631 81174dae aliguori
    }
632 81174dae aliguori
    serial_update_irq(s);
633 b41a2cd1 bellard
}
634 80cabfad bellard
635 82c643ff bellard
static void serial_event(void *opaque, int event)
636 82c643ff bellard
{
637 82c643ff bellard
    SerialState *s = opaque;
638 81174dae aliguori
#ifdef DEBUG_SERIAL
639 81174dae aliguori
    printf("serial: event %x\n", event);
640 81174dae aliguori
#endif
641 82c643ff bellard
    if (event == CHR_EVENT_BREAK)
642 82c643ff bellard
        serial_receive_break(s);
643 82c643ff bellard
}
644 82c643ff bellard
645 d4bfa4d7 Juan Quintela
static void serial_pre_save(void *opaque)
646 8738a8d0 bellard
{
647 d4bfa4d7 Juan Quintela
    SerialState *s = opaque;
648 747791f1 Juan Quintela
    s->fcr_vmstate = s->fcr;
649 8738a8d0 bellard
}
650 8738a8d0 bellard
651 747791f1 Juan Quintela
static int serial_pre_load(void *opaque)
652 8738a8d0 bellard
{
653 8738a8d0 bellard
    SerialState *s = opaque;
654 747791f1 Juan Quintela
    s->fcr_vmstate = 0;
655 747791f1 Juan Quintela
    return 0;
656 747791f1 Juan Quintela
}
657 8738a8d0 bellard
658 e59fb374 Juan Quintela
static int serial_post_load(void *opaque, int version_id)
659 747791f1 Juan Quintela
{
660 747791f1 Juan Quintela
    SerialState *s = opaque;
661 81174dae aliguori
662 81174dae aliguori
    /* Initialize fcr via setter to perform essential side-effects */
663 747791f1 Juan Quintela
    serial_ioport_write(s, 0x02, s->fcr_vmstate);
664 8738a8d0 bellard
    return 0;
665 8738a8d0 bellard
}
666 8738a8d0 bellard
667 747791f1 Juan Quintela
static const VMStateDescription vmstate_serial = {
668 747791f1 Juan Quintela
    .name = "serial",
669 747791f1 Juan Quintela
    .version_id = 3,
670 747791f1 Juan Quintela
    .minimum_version_id = 2,
671 747791f1 Juan Quintela
    .pre_save = serial_pre_save,
672 747791f1 Juan Quintela
    .pre_load = serial_pre_load,
673 747791f1 Juan Quintela
    .post_load = serial_post_load,
674 747791f1 Juan Quintela
    .fields      = (VMStateField []) {
675 747791f1 Juan Quintela
        VMSTATE_UINT16_V(divider, SerialState, 2),
676 747791f1 Juan Quintela
        VMSTATE_UINT8(rbr, SerialState),
677 747791f1 Juan Quintela
        VMSTATE_UINT8(ier, SerialState),
678 747791f1 Juan Quintela
        VMSTATE_UINT8(iir, SerialState),
679 747791f1 Juan Quintela
        VMSTATE_UINT8(lcr, SerialState),
680 747791f1 Juan Quintela
        VMSTATE_UINT8(mcr, SerialState),
681 747791f1 Juan Quintela
        VMSTATE_UINT8(lsr, SerialState),
682 747791f1 Juan Quintela
        VMSTATE_UINT8(msr, SerialState),
683 747791f1 Juan Quintela
        VMSTATE_UINT8(scr, SerialState),
684 747791f1 Juan Quintela
        VMSTATE_UINT8_V(fcr_vmstate, SerialState, 3),
685 747791f1 Juan Quintela
        VMSTATE_END_OF_LIST()
686 747791f1 Juan Quintela
    }
687 747791f1 Juan Quintela
};
688 747791f1 Juan Quintela
689 b2a5160c balrog
static void serial_reset(void *opaque)
690 b2a5160c balrog
{
691 b2a5160c balrog
    SerialState *s = opaque;
692 b2a5160c balrog
693 b2a5160c balrog
    s->rbr = 0;
694 b2a5160c balrog
    s->ier = 0;
695 b2a5160c balrog
    s->iir = UART_IIR_NO_INT;
696 b2a5160c balrog
    s->lcr = 0;
697 b2a5160c balrog
    s->lsr = UART_LSR_TEMT | UART_LSR_THRE;
698 b2a5160c balrog
    s->msr = UART_MSR_DCD | UART_MSR_DSR | UART_MSR_CTS;
699 81174dae aliguori
    /* Default to 9600 baud, no parity, one stop bit */
700 81174dae aliguori
    s->divider = 0x0C;
701 81174dae aliguori
    s->mcr = UART_MCR_OUT2;
702 b2a5160c balrog
    s->scr = 0;
703 81174dae aliguori
    s->tsr_retry = 0;
704 6ee093c9 Juan Quintela
    s->char_transmit_time = (get_ticks_per_sec() / 9600) * 9;
705 81174dae aliguori
    s->poll_msl = 0;
706 81174dae aliguori
707 81174dae aliguori
    fifo_clear(s,RECV_FIFO);
708 81174dae aliguori
    fifo_clear(s,XMIT_FIFO);
709 81174dae aliguori
710 81174dae aliguori
    s->last_xmit_ts = qemu_get_clock(vm_clock);
711 b2a5160c balrog
712 b2a5160c balrog
    s->thr_ipending = 0;
713 b2a5160c balrog
    s->last_break_enable = 0;
714 b2a5160c balrog
    qemu_irq_lower(s->irq);
715 b2a5160c balrog
}
716 b2a5160c balrog
717 ac0be998 Gerd Hoffmann
static void serial_init_core(SerialState *s)
718 81174dae aliguori
{
719 ac0be998 Gerd Hoffmann
    if (!s->chr) {
720 387f4a5a Aurelien Jarno
        fprintf(stderr, "Can't create serial device, empty char device\n");
721 387f4a5a Aurelien Jarno
        exit(1);
722 387f4a5a Aurelien Jarno
    }
723 387f4a5a Aurelien Jarno
724 81174dae aliguori
    s->modem_status_poll = qemu_new_timer(vm_clock, (QEMUTimerCB *) serial_update_msl, s);
725 81174dae aliguori
726 81174dae aliguori
    s->fifo_timeout_timer = qemu_new_timer(vm_clock, (QEMUTimerCB *) fifo_timeout_int, s);
727 81174dae aliguori
    s->transmit_timer = qemu_new_timer(vm_clock, (QEMUTimerCB *) serial_xmit, s);
728 81174dae aliguori
729 a08d4367 Jan Kiszka
    qemu_register_reset(serial_reset, s);
730 81174dae aliguori
    serial_reset(s);
731 81174dae aliguori
732 b47543c4 aurel32
    qemu_chr_add_handlers(s->chr, serial_can_receive1, serial_receive1,
733 b47543c4 aurel32
                          serial_event, s);
734 81174dae aliguori
}
735 81174dae aliguori
736 ac0be998 Gerd Hoffmann
static int serial_isa_initfn(ISADevice *dev)
737 ac0be998 Gerd Hoffmann
{
738 ac0be998 Gerd Hoffmann
    ISASerialState *isa = DO_UPCAST(ISASerialState, dev, dev);
739 ac0be998 Gerd Hoffmann
    SerialState *s = &isa->state;
740 ac0be998 Gerd Hoffmann
741 ac0be998 Gerd Hoffmann
    s->baudbase = 115200;
742 ac0be998 Gerd Hoffmann
    isa_init_irq(dev, &s->irq, isa->isairq);
743 ac0be998 Gerd Hoffmann
    serial_init_core(s);
744 ac0be998 Gerd Hoffmann
    vmstate_register(isa->iobase, &vmstate_serial, s);
745 ac0be998 Gerd Hoffmann
746 ac0be998 Gerd Hoffmann
    register_ioport_write(isa->iobase, 8, 1, serial_ioport_write, s);
747 ac0be998 Gerd Hoffmann
    register_ioport_read(isa->iobase, 8, 1, serial_ioport_read, s);
748 ac0be998 Gerd Hoffmann
    return 0;
749 ac0be998 Gerd Hoffmann
}
750 ac0be998 Gerd Hoffmann
751 ac0be998 Gerd Hoffmann
static const int isa_serial_io[MAX_SERIAL_PORTS] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 };
752 ac0be998 Gerd Hoffmann
static const int isa_serial_irq[MAX_SERIAL_PORTS] = { 4, 3, 4, 3 };
753 ac0be998 Gerd Hoffmann
754 ac0be998 Gerd Hoffmann
SerialState *serial_isa_init(int index, CharDriverState *chr)
755 ac0be998 Gerd Hoffmann
{
756 ac0be998 Gerd Hoffmann
    ISADevice *dev;
757 ac0be998 Gerd Hoffmann
758 ac0be998 Gerd Hoffmann
    dev = isa_create("isa-serial");
759 ac0be998 Gerd Hoffmann
    qdev_prop_set_uint32(&dev->qdev, "iobase", isa_serial_io[index]);
760 ac0be998 Gerd Hoffmann
    qdev_prop_set_uint32(&dev->qdev, "irq", isa_serial_irq[index]);
761 ac0be998 Gerd Hoffmann
    qdev_prop_set_chr(&dev->qdev, "chardev", chr);
762 5c17ca25 Markus Armbruster
    if (qdev_init(&dev->qdev) < 0)
763 ac0be998 Gerd Hoffmann
        return NULL;
764 ac0be998 Gerd Hoffmann
    return &DO_UPCAST(ISASerialState, dev, dev)->state;
765 ac0be998 Gerd Hoffmann
}
766 ac0be998 Gerd Hoffmann
767 b6cd0ea1 aurel32
SerialState *serial_init(int base, qemu_irq irq, int baudbase,
768 b6cd0ea1 aurel32
                         CharDriverState *chr)
769 b41a2cd1 bellard
{
770 b41a2cd1 bellard
    SerialState *s;
771 b41a2cd1 bellard
772 b41a2cd1 bellard
    s = qemu_mallocz(sizeof(SerialState));
773 6936bfe5 aurel32
774 ac0be998 Gerd Hoffmann
    s->irq = irq;
775 ac0be998 Gerd Hoffmann
    s->baudbase = baudbase;
776 ac0be998 Gerd Hoffmann
    s->chr = chr;
777 ac0be998 Gerd Hoffmann
    serial_init_core(s);
778 b41a2cd1 bellard
779 747791f1 Juan Quintela
    vmstate_register(base, &vmstate_serial, s);
780 8738a8d0 bellard
781 b41a2cd1 bellard
    register_ioport_write(base, 8, 1, serial_ioport_write, s);
782 b41a2cd1 bellard
    register_ioport_read(base, 8, 1, serial_ioport_read, s);
783 b41a2cd1 bellard
    return s;
784 80cabfad bellard
}
785 e5d13e2f bellard
786 e5d13e2f bellard
/* Memory mapped interface */
787 c227f099 Anthony Liguori
static uint32_t serial_mm_readb(void *opaque, target_phys_addr_t addr)
788 e5d13e2f bellard
{
789 e5d13e2f bellard
    SerialState *s = opaque;
790 e5d13e2f bellard
791 8da3ff18 pbrook
    return serial_ioport_read(s, addr >> s->it_shift) & 0xFF;
792 e5d13e2f bellard
}
793 e5d13e2f bellard
794 c227f099 Anthony Liguori
static void serial_mm_writeb(void *opaque, target_phys_addr_t addr,
795 802670e6 Blue Swirl
                             uint32_t value)
796 e5d13e2f bellard
{
797 e5d13e2f bellard
    SerialState *s = opaque;
798 e5d13e2f bellard
799 8da3ff18 pbrook
    serial_ioport_write(s, addr >> s->it_shift, value & 0xFF);
800 e5d13e2f bellard
}
801 e5d13e2f bellard
802 c227f099 Anthony Liguori
static uint32_t serial_mm_readw(void *opaque, target_phys_addr_t addr)
803 e5d13e2f bellard
{
804 e5d13e2f bellard
    SerialState *s = opaque;
805 e918ee04 ths
    uint32_t val;
806 e5d13e2f bellard
807 8da3ff18 pbrook
    val = serial_ioport_read(s, addr >> s->it_shift) & 0xFFFF;
808 e918ee04 ths
#ifdef TARGET_WORDS_BIGENDIAN
809 e918ee04 ths
    val = bswap16(val);
810 e918ee04 ths
#endif
811 e918ee04 ths
    return val;
812 e5d13e2f bellard
}
813 e5d13e2f bellard
814 c227f099 Anthony Liguori
static void serial_mm_writew(void *opaque, target_phys_addr_t addr,
815 802670e6 Blue Swirl
                             uint32_t value)
816 e5d13e2f bellard
{
817 e5d13e2f bellard
    SerialState *s = opaque;
818 e918ee04 ths
#ifdef TARGET_WORDS_BIGENDIAN
819 e918ee04 ths
    value = bswap16(value);
820 e918ee04 ths
#endif
821 8da3ff18 pbrook
    serial_ioport_write(s, addr >> s->it_shift, value & 0xFFFF);
822 e5d13e2f bellard
}
823 e5d13e2f bellard
824 c227f099 Anthony Liguori
static uint32_t serial_mm_readl(void *opaque, target_phys_addr_t addr)
825 e5d13e2f bellard
{
826 e5d13e2f bellard
    SerialState *s = opaque;
827 e918ee04 ths
    uint32_t val;
828 e5d13e2f bellard
829 8da3ff18 pbrook
    val = serial_ioport_read(s, addr >> s->it_shift);
830 e918ee04 ths
#ifdef TARGET_WORDS_BIGENDIAN
831 e918ee04 ths
    val = bswap32(val);
832 e918ee04 ths
#endif
833 e918ee04 ths
    return val;
834 e5d13e2f bellard
}
835 e5d13e2f bellard
836 c227f099 Anthony Liguori
static void serial_mm_writel(void *opaque, target_phys_addr_t addr,
837 802670e6 Blue Swirl
                             uint32_t value)
838 e5d13e2f bellard
{
839 e5d13e2f bellard
    SerialState *s = opaque;
840 e918ee04 ths
#ifdef TARGET_WORDS_BIGENDIAN
841 e918ee04 ths
    value = bswap32(value);
842 e918ee04 ths
#endif
843 8da3ff18 pbrook
    serial_ioport_write(s, addr >> s->it_shift, value);
844 e5d13e2f bellard
}
845 e5d13e2f bellard
846 d60efc6b Blue Swirl
static CPUReadMemoryFunc * const serial_mm_read[] = {
847 e5d13e2f bellard
    &serial_mm_readb,
848 e5d13e2f bellard
    &serial_mm_readw,
849 e5d13e2f bellard
    &serial_mm_readl,
850 e5d13e2f bellard
};
851 e5d13e2f bellard
852 d60efc6b Blue Swirl
static CPUWriteMemoryFunc * const serial_mm_write[] = {
853 e5d13e2f bellard
    &serial_mm_writeb,
854 e5d13e2f bellard
    &serial_mm_writew,
855 e5d13e2f bellard
    &serial_mm_writel,
856 e5d13e2f bellard
};
857 e5d13e2f bellard
858 c227f099 Anthony Liguori
SerialState *serial_mm_init (target_phys_addr_t base, int it_shift,
859 b6cd0ea1 aurel32
                             qemu_irq irq, int baudbase,
860 b6cd0ea1 aurel32
                             CharDriverState *chr, int ioregister)
861 e5d13e2f bellard
{
862 e5d13e2f bellard
    SerialState *s;
863 e5d13e2f bellard
    int s_io_memory;
864 e5d13e2f bellard
865 e5d13e2f bellard
    s = qemu_mallocz(sizeof(SerialState));
866 81174dae aliguori
867 e5d13e2f bellard
    s->it_shift = it_shift;
868 ac0be998 Gerd Hoffmann
    s->irq = irq;
869 ac0be998 Gerd Hoffmann
    s->baudbase = baudbase;
870 ac0be998 Gerd Hoffmann
    s->chr = chr;
871 e5d13e2f bellard
872 ac0be998 Gerd Hoffmann
    serial_init_core(s);
873 747791f1 Juan Quintela
    vmstate_register(base, &vmstate_serial, s);
874 e5d13e2f bellard
875 a4bc3afc ths
    if (ioregister) {
876 1eed09cb Avi Kivity
        s_io_memory = cpu_register_io_memory(serial_mm_read,
877 a4bc3afc ths
                                             serial_mm_write, s);
878 a4bc3afc ths
        cpu_register_physical_memory(base, 8 << it_shift, s_io_memory);
879 a4bc3afc ths
    }
880 81174dae aliguori
    serial_update_msl(s);
881 e5d13e2f bellard
    return s;
882 e5d13e2f bellard
}
883 ac0be998 Gerd Hoffmann
884 ac0be998 Gerd Hoffmann
static ISADeviceInfo serial_isa_info = {
885 ac0be998 Gerd Hoffmann
    .qdev.name  = "isa-serial",
886 ac0be998 Gerd Hoffmann
    .qdev.size  = sizeof(ISASerialState),
887 ac0be998 Gerd Hoffmann
    .init       = serial_isa_initfn,
888 ac0be998 Gerd Hoffmann
    .qdev.props = (Property[]) {
889 ac0be998 Gerd Hoffmann
        DEFINE_PROP_HEX32("iobase", ISASerialState, iobase,  0x3f8),
890 ac0be998 Gerd Hoffmann
        DEFINE_PROP_UINT32("irq",   ISASerialState, isairq,  4),
891 ac0be998 Gerd Hoffmann
        DEFINE_PROP_CHR("chardev",  ISASerialState, state.chr),
892 ac0be998 Gerd Hoffmann
        DEFINE_PROP_END_OF_LIST(),
893 ac0be998 Gerd Hoffmann
    },
894 ac0be998 Gerd Hoffmann
};
895 ac0be998 Gerd Hoffmann
896 ac0be998 Gerd Hoffmann
static void serial_register_devices(void)
897 ac0be998 Gerd Hoffmann
{
898 ac0be998 Gerd Hoffmann
    isa_qdev_register(&serial_isa_info);
899 ac0be998 Gerd Hoffmann
}
900 ac0be998 Gerd Hoffmann
901 ac0be998 Gerd Hoffmann
device_init(serial_register_devices)