Statistics
| Branch: | Revision:

root / hw / serial.c @ b614106a

History | View | Annotate | Download (24.6 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 81174dae aliguori
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 81174dae aliguori
} typedef 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 80cabfad bellard
    /* NOTE: this hidden state is necessary for tx irq generation as
123 80cabfad bellard
       it can be reset while reading iir */
124 80cabfad bellard
    int thr_ipending;
125 d537cf6c pbrook
    qemu_irq irq;
126 82c643ff bellard
    CharDriverState *chr;
127 f8d179e3 bellard
    int last_break_enable;
128 71db710f blueswir1
    target_phys_addr_t base;
129 e5d13e2f bellard
    int it_shift;
130 b6cd0ea1 aurel32
    int baudbase;
131 81174dae aliguori
    int tsr_retry;
132 81174dae aliguori
133 81174dae aliguori
    uint64_t last_xmit_ts;              /* Time when the last byte was successfully sent out of the tsr */
134 81174dae aliguori
    SerialFIFO recv_fifo;
135 81174dae aliguori
    SerialFIFO xmit_fifo;
136 81174dae aliguori
137 81174dae aliguori
    struct QEMUTimer *fifo_timeout_timer;
138 81174dae aliguori
    int timeout_ipending;                   /* timeout interrupt pending state */
139 81174dae aliguori
    struct QEMUTimer *transmit_timer;
140 81174dae aliguori
141 81174dae aliguori
142 81174dae aliguori
    uint64_t char_transmit_time;               /* time to transmit a char in ticks*/
143 81174dae aliguori
    int poll_msl;
144 81174dae aliguori
145 81174dae aliguori
    struct QEMUTimer *modem_status_poll;
146 b41a2cd1 bellard
};
147 80cabfad bellard
148 81174dae aliguori
static void serial_receive1(void *opaque, const uint8_t *buf, int size);
149 b2a5160c balrog
150 81174dae aliguori
static void fifo_clear(SerialState *s, int fifo)
151 80cabfad bellard
{
152 81174dae aliguori
    SerialFIFO *f = (fifo) ? &s->recv_fifo : &s->xmit_fifo;
153 81174dae aliguori
    memset(f->data, 0, UART_FIFO_LENGTH);
154 81174dae aliguori
    f->count = 0;
155 81174dae aliguori
    f->head = 0;
156 81174dae aliguori
    f->tail = 0;
157 80cabfad bellard
}
158 80cabfad bellard
159 81174dae aliguori
static int fifo_put(SerialState *s, int fifo, uint8_t chr)
160 6936bfe5 aurel32
{
161 81174dae aliguori
    SerialFIFO *f = (fifo) ? &s->recv_fifo : &s->xmit_fifo;
162 6936bfe5 aurel32
163 81174dae aliguori
    f->data[f->head++] = chr;
164 6936bfe5 aurel32
165 81174dae aliguori
    if (f->head == UART_FIFO_LENGTH)
166 81174dae aliguori
        f->head = 0;
167 81174dae aliguori
    f->count++;
168 81174dae aliguori
169 81174dae aliguori
    return 1;
170 81174dae aliguori
}
171 81174dae aliguori
172 81174dae aliguori
static uint8_t fifo_get(SerialState *s, int fifo)
173 81174dae aliguori
{
174 81174dae aliguori
    SerialFIFO *f = (fifo) ? &s->recv_fifo : &s->xmit_fifo;
175 81174dae aliguori
    uint8_t c;
176 81174dae aliguori
177 81174dae aliguori
    if(f->count == 0)
178 81174dae aliguori
        return 0;
179 81174dae aliguori
180 81174dae aliguori
    c = f->data[f->tail++];
181 81174dae aliguori
    if (f->tail == UART_FIFO_LENGTH)
182 81174dae aliguori
        f->tail = 0;
183 81174dae aliguori
    f->count--;
184 81174dae aliguori
185 81174dae aliguori
    return c;
186 81174dae aliguori
}
187 6936bfe5 aurel32
188 81174dae aliguori
static void serial_update_irq(SerialState *s)
189 81174dae aliguori
{
190 81174dae aliguori
    uint8_t tmp_iir = UART_IIR_NO_INT;
191 81174dae aliguori
192 81174dae aliguori
    if ((s->ier & UART_IER_RLSI) && (s->lsr & UART_LSR_INT_ANY)) {
193 81174dae aliguori
        tmp_iir = UART_IIR_RLSI;
194 81174dae aliguori
    } else if (s->timeout_ipending) {
195 81174dae aliguori
        tmp_iir = UART_IIR_CTI;
196 81174dae aliguori
    } else if ((s->ier & UART_IER_RDI) && (s->lsr & UART_LSR_DR)) {
197 81174dae aliguori
        if (!(s->fcr & UART_FCR_FE)) {
198 81174dae aliguori
           tmp_iir = UART_IIR_RDI;
199 81174dae aliguori
        } else if (s->recv_fifo.count >= s->recv_fifo.itl) {
200 81174dae aliguori
           tmp_iir = UART_IIR_RDI;
201 81174dae aliguori
        }
202 81174dae aliguori
    } else if ((s->ier & UART_IER_THRI) && s->thr_ipending) {
203 81174dae aliguori
        tmp_iir = UART_IIR_THRI;
204 81174dae aliguori
    } else if ((s->ier & UART_IER_MSI) && (s->msr & UART_MSR_ANY_DELTA)) {
205 81174dae aliguori
        tmp_iir = UART_IIR_MSI;
206 81174dae aliguori
    }
207 81174dae aliguori
208 81174dae aliguori
    s->iir = tmp_iir | (s->iir & 0xF0);
209 81174dae aliguori
210 81174dae aliguori
    if (tmp_iir != UART_IIR_NO_INT) {
211 81174dae aliguori
        qemu_irq_raise(s->irq);
212 81174dae aliguori
    } else {
213 81174dae aliguori
        qemu_irq_lower(s->irq);
214 6936bfe5 aurel32
    }
215 6936bfe5 aurel32
}
216 6936bfe5 aurel32
217 f8d179e3 bellard
static void serial_update_parameters(SerialState *s)
218 f8d179e3 bellard
{
219 81174dae aliguori
    int speed, parity, data_bits, stop_bits, frame_size;
220 2122c51a bellard
    QEMUSerialSetParams ssp;
221 f8d179e3 bellard
222 81174dae aliguori
    if (s->divider == 0)
223 81174dae aliguori
        return;
224 81174dae aliguori
225 81174dae aliguori
    frame_size = 1;
226 f8d179e3 bellard
    if (s->lcr & 0x08) {
227 f8d179e3 bellard
        if (s->lcr & 0x10)
228 f8d179e3 bellard
            parity = 'E';
229 f8d179e3 bellard
        else
230 f8d179e3 bellard
            parity = 'O';
231 f8d179e3 bellard
    } else {
232 f8d179e3 bellard
            parity = 'N';
233 81174dae aliguori
            frame_size = 0;
234 f8d179e3 bellard
    }
235 5fafdf24 ths
    if (s->lcr & 0x04)
236 f8d179e3 bellard
        stop_bits = 2;
237 f8d179e3 bellard
    else
238 f8d179e3 bellard
        stop_bits = 1;
239 81174dae aliguori
240 f8d179e3 bellard
    data_bits = (s->lcr & 0x03) + 5;
241 81174dae aliguori
    frame_size += data_bits + stop_bits;
242 b6cd0ea1 aurel32
    speed = s->baudbase / s->divider;
243 2122c51a bellard
    ssp.speed = speed;
244 2122c51a bellard
    ssp.parity = parity;
245 2122c51a bellard
    ssp.data_bits = data_bits;
246 2122c51a bellard
    ssp.stop_bits = stop_bits;
247 81174dae aliguori
    s->char_transmit_time =  (ticks_per_sec / speed) * frame_size;
248 2122c51a bellard
    qemu_chr_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
249 2122c51a bellard
#if 0
250 5fafdf24 ths
    printf("speed=%d parity=%c data=%d stop=%d\n",
251 f8d179e3 bellard
           speed, parity, data_bits, stop_bits);
252 f8d179e3 bellard
#endif
253 f8d179e3 bellard
}
254 f8d179e3 bellard
255 81174dae aliguori
static void serial_update_msl(SerialState *s)
256 81174dae aliguori
{
257 81174dae aliguori
    uint8_t omsr;
258 81174dae aliguori
    int flags;
259 81174dae aliguori
260 81174dae aliguori
    qemu_del_timer(s->modem_status_poll);
261 81174dae aliguori
262 81174dae aliguori
    if (qemu_chr_ioctl(s->chr,CHR_IOCTL_SERIAL_GET_TIOCM, &flags) == -ENOTSUP) {
263 81174dae aliguori
        s->poll_msl = -1;
264 81174dae aliguori
        return;
265 81174dae aliguori
    }
266 81174dae aliguori
267 81174dae aliguori
    omsr = s->msr;
268 81174dae aliguori
269 81174dae aliguori
    s->msr = (flags & CHR_TIOCM_CTS) ? s->msr | UART_MSR_CTS : s->msr & ~UART_MSR_CTS;
270 81174dae aliguori
    s->msr = (flags & CHR_TIOCM_DSR) ? s->msr | UART_MSR_DSR : s->msr & ~UART_MSR_DSR;
271 81174dae aliguori
    s->msr = (flags & CHR_TIOCM_CAR) ? s->msr | UART_MSR_DCD : s->msr & ~UART_MSR_DCD;
272 81174dae aliguori
    s->msr = (flags & CHR_TIOCM_RI) ? s->msr | UART_MSR_RI : s->msr & ~UART_MSR_RI;
273 81174dae aliguori
274 81174dae aliguori
    if (s->msr != omsr) {
275 81174dae aliguori
         /* Set delta bits */
276 81174dae aliguori
         s->msr = s->msr | ((s->msr >> 4) ^ (omsr >> 4));
277 81174dae aliguori
         /* UART_MSR_TERI only if change was from 1 -> 0 */
278 81174dae aliguori
         if ((s->msr & UART_MSR_TERI) && !(omsr & UART_MSR_RI))
279 81174dae aliguori
             s->msr &= ~UART_MSR_TERI;
280 81174dae aliguori
         serial_update_irq(s);
281 81174dae aliguori
    }
282 81174dae aliguori
283 81174dae aliguori
    /* The real 16550A apparently has a 250ns response latency to line status changes.
284 81174dae aliguori
       We'll be lazy and poll only every 10ms, and only poll it at all if MSI interrupts are turned on */
285 81174dae aliguori
286 81174dae aliguori
    if (s->poll_msl)
287 81174dae aliguori
        qemu_mod_timer(s->modem_status_poll, qemu_get_clock(vm_clock) + ticks_per_sec / 100);
288 81174dae aliguori
}
289 81174dae aliguori
290 81174dae aliguori
static void serial_xmit(void *opaque)
291 81174dae aliguori
{
292 81174dae aliguori
    SerialState *s = opaque;
293 81174dae aliguori
    uint64_t new_xmit_ts = qemu_get_clock(vm_clock);
294 81174dae aliguori
295 81174dae aliguori
    if (s->tsr_retry <= 0) {
296 81174dae aliguori
        if (s->fcr & UART_FCR_FE) {
297 81174dae aliguori
            s->tsr = fifo_get(s,XMIT_FIFO);
298 81174dae aliguori
            if (!s->xmit_fifo.count)
299 81174dae aliguori
                s->lsr |= UART_LSR_THRE;
300 81174dae aliguori
        } else {
301 81174dae aliguori
            s->tsr = s->thr;
302 81174dae aliguori
            s->lsr |= UART_LSR_THRE;
303 81174dae aliguori
        }
304 81174dae aliguori
    }
305 81174dae aliguori
306 81174dae aliguori
    if (s->mcr & UART_MCR_LOOP) {
307 81174dae aliguori
        /* in loopback mode, say that we just received a char */
308 81174dae aliguori
        serial_receive1(s, &s->tsr, 1);
309 81174dae aliguori
    } else if (qemu_chr_write(s->chr, &s->tsr, 1) != 1) {
310 81174dae aliguori
        if ((s->tsr_retry > 0) && (s->tsr_retry <= MAX_XMIT_RETRY)) {
311 81174dae aliguori
            s->tsr_retry++;
312 81174dae aliguori
            qemu_mod_timer(s->transmit_timer,  new_xmit_ts + s->char_transmit_time);
313 81174dae aliguori
            return;
314 81174dae aliguori
        } else if (s->poll_msl < 0) {
315 81174dae aliguori
            /* If we exceed MAX_XMIT_RETRY and the backend is not a real serial port, then
316 81174dae aliguori
            drop any further failed writes instantly, until we get one that goes through.
317 81174dae aliguori
            This is to prevent guests that log to unconnected pipes or pty's from stalling. */
318 81174dae aliguori
            s->tsr_retry = -1;
319 81174dae aliguori
        }
320 81174dae aliguori
    }
321 81174dae aliguori
    else {
322 81174dae aliguori
        s->tsr_retry = 0;
323 81174dae aliguori
    }
324 81174dae aliguori
325 81174dae aliguori
    s->last_xmit_ts = qemu_get_clock(vm_clock);
326 81174dae aliguori
    if (!(s->lsr & UART_LSR_THRE))
327 81174dae aliguori
        qemu_mod_timer(s->transmit_timer, s->last_xmit_ts + s->char_transmit_time);
328 81174dae aliguori
329 81174dae aliguori
    if (s->lsr & UART_LSR_THRE) {
330 81174dae aliguori
        s->lsr |= UART_LSR_TEMT;
331 81174dae aliguori
        s->thr_ipending = 1;
332 81174dae aliguori
        serial_update_irq(s);
333 81174dae aliguori
    }
334 81174dae aliguori
}
335 81174dae aliguori
336 81174dae aliguori
337 b41a2cd1 bellard
static void serial_ioport_write(void *opaque, uint32_t addr, uint32_t val)
338 80cabfad bellard
{
339 b41a2cd1 bellard
    SerialState *s = opaque;
340 3b46e624 ths
341 80cabfad bellard
    addr &= 7;
342 80cabfad bellard
#ifdef DEBUG_SERIAL
343 80cabfad bellard
    printf("serial: write addr=0x%02x val=0x%02x\n", addr, val);
344 80cabfad bellard
#endif
345 80cabfad bellard
    switch(addr) {
346 80cabfad bellard
    default:
347 80cabfad bellard
    case 0:
348 80cabfad bellard
        if (s->lcr & UART_LCR_DLAB) {
349 80cabfad bellard
            s->divider = (s->divider & 0xff00) | val;
350 f8d179e3 bellard
            serial_update_parameters(s);
351 80cabfad bellard
        } else {
352 81174dae aliguori
            s->thr = (uint8_t) val;
353 81174dae aliguori
            if(s->fcr & UART_FCR_FE) {
354 81174dae aliguori
                  fifo_put(s, XMIT_FIFO, s->thr);
355 80cabfad bellard
            s->thr_ipending = 0;
356 81174dae aliguori
                  s->lsr &= ~UART_LSR_TEMT;
357 80cabfad bellard
            s->lsr &= ~UART_LSR_THRE;
358 b41a2cd1 bellard
            serial_update_irq(s);
359 6936bfe5 aurel32
            } else {
360 81174dae aliguori
                  s->thr_ipending = 0;
361 81174dae aliguori
                  s->lsr &= ~UART_LSR_THRE;
362 81174dae aliguori
                  serial_update_irq(s);
363 6936bfe5 aurel32
            }
364 81174dae aliguori
            serial_xmit(s);
365 80cabfad bellard
        }
366 80cabfad bellard
        break;
367 80cabfad bellard
    case 1:
368 80cabfad bellard
        if (s->lcr & UART_LCR_DLAB) {
369 80cabfad bellard
            s->divider = (s->divider & 0x00ff) | (val << 8);
370 f8d179e3 bellard
            serial_update_parameters(s);
371 80cabfad bellard
        } else {
372 60e336db bellard
            s->ier = val & 0x0f;
373 81174dae aliguori
            /* If the backend device is a real serial port, turn polling of the modem
374 81174dae aliguori
               status lines on physical port on or off depending on UART_IER_MSI state */
375 81174dae aliguori
            if (s->poll_msl >= 0) {
376 81174dae aliguori
                if (s->ier & UART_IER_MSI) {
377 81174dae aliguori
                     s->poll_msl = 1;
378 81174dae aliguori
                     serial_update_msl(s);
379 81174dae aliguori
                } else {
380 81174dae aliguori
                     qemu_del_timer(s->modem_status_poll);
381 81174dae aliguori
                     s->poll_msl = 0;
382 81174dae aliguori
                }
383 81174dae aliguori
            }
384 60e336db bellard
            if (s->lsr & UART_LSR_THRE) {
385 60e336db bellard
                s->thr_ipending = 1;
386 81174dae aliguori
                serial_update_irq(s);
387 60e336db bellard
            }
388 80cabfad bellard
        }
389 80cabfad bellard
        break;
390 80cabfad bellard
    case 2:
391 81174dae aliguori
        val = val & 0xFF;
392 81174dae aliguori
393 81174dae aliguori
        if (s->fcr == val)
394 81174dae aliguori
            break;
395 81174dae aliguori
396 81174dae aliguori
        /* Did the enable/disable flag change? If so, make sure FIFOs get flushed */
397 81174dae aliguori
        if ((val ^ s->fcr) & UART_FCR_FE)
398 81174dae aliguori
            val |= UART_FCR_XFR | UART_FCR_RFR;
399 81174dae aliguori
400 81174dae aliguori
        /* FIFO clear */
401 81174dae aliguori
402 81174dae aliguori
        if (val & UART_FCR_RFR) {
403 81174dae aliguori
            qemu_del_timer(s->fifo_timeout_timer);
404 81174dae aliguori
            s->timeout_ipending=0;
405 81174dae aliguori
            fifo_clear(s,RECV_FIFO);
406 81174dae aliguori
        }
407 81174dae aliguori
408 81174dae aliguori
        if (val & UART_FCR_XFR) {
409 81174dae aliguori
            fifo_clear(s,XMIT_FIFO);
410 81174dae aliguori
        }
411 81174dae aliguori
412 81174dae aliguori
        if (val & UART_FCR_FE) {
413 81174dae aliguori
            s->iir |= UART_IIR_FE;
414 81174dae aliguori
            /* Set RECV_FIFO trigger Level */
415 81174dae aliguori
            switch (val & 0xC0) {
416 81174dae aliguori
            case UART_FCR_ITL_1:
417 81174dae aliguori
                s->recv_fifo.itl = 1;
418 81174dae aliguori
                break;
419 81174dae aliguori
            case UART_FCR_ITL_2:
420 81174dae aliguori
                s->recv_fifo.itl = 4;
421 81174dae aliguori
                break;
422 81174dae aliguori
            case UART_FCR_ITL_3:
423 81174dae aliguori
                s->recv_fifo.itl = 8;
424 81174dae aliguori
                break;
425 81174dae aliguori
            case UART_FCR_ITL_4:
426 81174dae aliguori
                s->recv_fifo.itl = 14;
427 81174dae aliguori
                break;
428 81174dae aliguori
            }
429 81174dae aliguori
        } else
430 81174dae aliguori
            s->iir &= ~UART_IIR_FE;
431 81174dae aliguori
432 81174dae aliguori
        /* Set fcr - or at least the bits in it that are supposed to "stick" */
433 81174dae aliguori
        s->fcr = val & 0xC9;
434 81174dae aliguori
        serial_update_irq(s);
435 80cabfad bellard
        break;
436 80cabfad bellard
    case 3:
437 f8d179e3 bellard
        {
438 f8d179e3 bellard
            int break_enable;
439 f8d179e3 bellard
            s->lcr = val;
440 f8d179e3 bellard
            serial_update_parameters(s);
441 f8d179e3 bellard
            break_enable = (val >> 6) & 1;
442 f8d179e3 bellard
            if (break_enable != s->last_break_enable) {
443 f8d179e3 bellard
                s->last_break_enable = break_enable;
444 5fafdf24 ths
                qemu_chr_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_BREAK,
445 2122c51a bellard
                               &break_enable);
446 f8d179e3 bellard
            }
447 f8d179e3 bellard
        }
448 80cabfad bellard
        break;
449 80cabfad bellard
    case 4:
450 81174dae aliguori
        {
451 81174dae aliguori
            int flags;
452 81174dae aliguori
            int old_mcr = s->mcr;
453 81174dae aliguori
            s->mcr = val & 0x1f;
454 81174dae aliguori
            if (val & UART_MCR_LOOP)
455 81174dae aliguori
                break;
456 81174dae aliguori
457 81174dae aliguori
            if (s->poll_msl >= 0 && old_mcr != s->mcr) {
458 81174dae aliguori
459 81174dae aliguori
                qemu_chr_ioctl(s->chr,CHR_IOCTL_SERIAL_GET_TIOCM, &flags);
460 81174dae aliguori
461 81174dae aliguori
                flags &= ~(CHR_TIOCM_RTS | CHR_TIOCM_DTR);
462 81174dae aliguori
463 81174dae aliguori
                if (val & UART_MCR_RTS)
464 81174dae aliguori
                    flags |= CHR_TIOCM_RTS;
465 81174dae aliguori
                if (val & UART_MCR_DTR)
466 81174dae aliguori
                    flags |= CHR_TIOCM_DTR;
467 81174dae aliguori
468 81174dae aliguori
                qemu_chr_ioctl(s->chr,CHR_IOCTL_SERIAL_SET_TIOCM, &flags);
469 81174dae aliguori
                /* Update the modem status after a one-character-send wait-time, since there may be a response
470 81174dae aliguori
                   from the device/computer at the other end of the serial line */
471 81174dae aliguori
                qemu_mod_timer(s->modem_status_poll, qemu_get_clock(vm_clock) + s->char_transmit_time);
472 81174dae aliguori
            }
473 81174dae aliguori
        }
474 80cabfad bellard
        break;
475 80cabfad bellard
    case 5:
476 80cabfad bellard
        break;
477 80cabfad bellard
    case 6:
478 80cabfad bellard
        break;
479 80cabfad bellard
    case 7:
480 80cabfad bellard
        s->scr = val;
481 80cabfad bellard
        break;
482 80cabfad bellard
    }
483 80cabfad bellard
}
484 80cabfad bellard
485 b41a2cd1 bellard
static uint32_t serial_ioport_read(void *opaque, uint32_t addr)
486 80cabfad bellard
{
487 b41a2cd1 bellard
    SerialState *s = opaque;
488 80cabfad bellard
    uint32_t ret;
489 80cabfad bellard
490 80cabfad bellard
    addr &= 7;
491 80cabfad bellard
    switch(addr) {
492 80cabfad bellard
    default:
493 80cabfad bellard
    case 0:
494 80cabfad bellard
        if (s->lcr & UART_LCR_DLAB) {
495 5fafdf24 ths
            ret = s->divider & 0xff;
496 80cabfad bellard
        } else {
497 81174dae aliguori
            if(s->fcr & UART_FCR_FE) {
498 81174dae aliguori
                ret = fifo_get(s,RECV_FIFO);
499 81174dae aliguori
                if (s->recv_fifo.count == 0)
500 81174dae aliguori
                    s->lsr &= ~(UART_LSR_DR | UART_LSR_BI);
501 81174dae aliguori
                else
502 81174dae aliguori
                    qemu_mod_timer(s->fifo_timeout_timer, qemu_get_clock (vm_clock) + s->char_transmit_time * 4);
503 81174dae aliguori
                s->timeout_ipending = 0;
504 81174dae aliguori
            } else {
505 81174dae aliguori
                ret = s->rbr;
506 81174dae aliguori
                s->lsr &= ~(UART_LSR_DR | UART_LSR_BI);
507 81174dae aliguori
            }
508 b41a2cd1 bellard
            serial_update_irq(s);
509 b2a5160c balrog
            if (!(s->mcr & UART_MCR_LOOP)) {
510 b2a5160c balrog
                /* in loopback mode, don't receive any data */
511 b2a5160c balrog
                qemu_chr_accept_input(s->chr);
512 b2a5160c balrog
            }
513 80cabfad bellard
        }
514 80cabfad bellard
        break;
515 80cabfad bellard
    case 1:
516 80cabfad bellard
        if (s->lcr & UART_LCR_DLAB) {
517 80cabfad bellard
            ret = (s->divider >> 8) & 0xff;
518 80cabfad bellard
        } else {
519 80cabfad bellard
            ret = s->ier;
520 80cabfad bellard
        }
521 80cabfad bellard
        break;
522 80cabfad bellard
    case 2:
523 80cabfad bellard
        ret = s->iir;
524 80cabfad bellard
            s->thr_ipending = 0;
525 b41a2cd1 bellard
        serial_update_irq(s);
526 80cabfad bellard
        break;
527 80cabfad bellard
    case 3:
528 80cabfad bellard
        ret = s->lcr;
529 80cabfad bellard
        break;
530 80cabfad bellard
    case 4:
531 80cabfad bellard
        ret = s->mcr;
532 80cabfad bellard
        break;
533 80cabfad bellard
    case 5:
534 80cabfad bellard
        ret = s->lsr;
535 81174dae aliguori
        /* Clear break interrupt */
536 81174dae aliguori
        if (s->lsr & UART_LSR_BI) {
537 81174dae aliguori
            s->lsr &= ~UART_LSR_BI;
538 81174dae aliguori
            serial_update_irq(s);
539 81174dae aliguori
        }
540 80cabfad bellard
        break;
541 80cabfad bellard
    case 6:
542 80cabfad bellard
        if (s->mcr & UART_MCR_LOOP) {
543 80cabfad bellard
            /* in loopback, the modem output pins are connected to the
544 80cabfad bellard
               inputs */
545 80cabfad bellard
            ret = (s->mcr & 0x0c) << 4;
546 80cabfad bellard
            ret |= (s->mcr & 0x02) << 3;
547 80cabfad bellard
            ret |= (s->mcr & 0x01) << 5;
548 80cabfad bellard
        } else {
549 81174dae aliguori
            if (s->poll_msl >= 0)
550 81174dae aliguori
                serial_update_msl(s);
551 80cabfad bellard
            ret = s->msr;
552 81174dae aliguori
            /* Clear delta bits & msr int after read, if they were set */
553 81174dae aliguori
            if (s->msr & UART_MSR_ANY_DELTA) {
554 81174dae aliguori
                s->msr &= 0xF0;
555 81174dae aliguori
                serial_update_irq(s);
556 81174dae aliguori
            }
557 80cabfad bellard
        }
558 80cabfad bellard
        break;
559 80cabfad bellard
    case 7:
560 80cabfad bellard
        ret = s->scr;
561 80cabfad bellard
        break;
562 80cabfad bellard
    }
563 80cabfad bellard
#ifdef DEBUG_SERIAL
564 80cabfad bellard
    printf("serial: read addr=0x%02x val=0x%02x\n", addr, ret);
565 80cabfad bellard
#endif
566 80cabfad bellard
    return ret;
567 80cabfad bellard
}
568 80cabfad bellard
569 82c643ff bellard
static int serial_can_receive(SerialState *s)
570 80cabfad bellard
{
571 81174dae aliguori
    if(s->fcr & UART_FCR_FE) {
572 81174dae aliguori
        if(s->recv_fifo.count < UART_FIFO_LENGTH)
573 81174dae aliguori
        /* Advertise (fifo.itl - fifo.count) bytes when count < ITL, and 1 if above. If UART_FIFO_LENGTH - fifo.count is
574 81174dae aliguori
        advertised the effect will be to almost always fill the fifo completely before the guest has a chance to respond,
575 81174dae aliguori
        effectively overriding the ITL that the guest has set. */
576 81174dae aliguori
             return (s->recv_fifo.count <= s->recv_fifo.itl) ? s->recv_fifo.itl - s->recv_fifo.count : 1;
577 81174dae aliguori
        else
578 81174dae aliguori
             return 0;
579 81174dae aliguori
    } else {
580 80cabfad bellard
    return !(s->lsr & UART_LSR_DR);
581 81174dae aliguori
    }
582 80cabfad bellard
}
583 80cabfad bellard
584 82c643ff bellard
static void serial_receive_break(SerialState *s)
585 80cabfad bellard
{
586 80cabfad bellard
    s->rbr = 0;
587 80cabfad bellard
    s->lsr |= UART_LSR_BI | UART_LSR_DR;
588 b41a2cd1 bellard
    serial_update_irq(s);
589 80cabfad bellard
}
590 80cabfad bellard
591 81174dae aliguori
/* There's data in recv_fifo and s->rbr has not been read for 4 char transmit times */
592 81174dae aliguori
static void fifo_timeout_int (void *opaque) {
593 81174dae aliguori
    SerialState *s = opaque;
594 81174dae aliguori
    if (s->recv_fifo.count) {
595 81174dae aliguori
        s->timeout_ipending = 1;
596 81174dae aliguori
        serial_update_irq(s);
597 81174dae aliguori
    }
598 81174dae aliguori
}
599 81174dae aliguori
600 b41a2cd1 bellard
static int serial_can_receive1(void *opaque)
601 80cabfad bellard
{
602 b41a2cd1 bellard
    SerialState *s = opaque;
603 b41a2cd1 bellard
    return serial_can_receive(s);
604 b41a2cd1 bellard
}
605 b41a2cd1 bellard
606 b41a2cd1 bellard
static void serial_receive1(void *opaque, const uint8_t *buf, int size)
607 b41a2cd1 bellard
{
608 b41a2cd1 bellard
    SerialState *s = opaque;
609 81174dae aliguori
    if(s->fcr & UART_FCR_FE) {
610 81174dae aliguori
        int i;
611 81174dae aliguori
        for (i = 0; i < size; i++) {
612 81174dae aliguori
            fifo_put(s, RECV_FIFO, buf[i]);
613 81174dae aliguori
        }
614 81174dae aliguori
        s->lsr |= UART_LSR_DR;
615 81174dae aliguori
        /* call the timeout receive callback in 4 char transmit time */
616 81174dae aliguori
        qemu_mod_timer(s->fifo_timeout_timer, qemu_get_clock (vm_clock) + s->char_transmit_time * 4);
617 81174dae aliguori
    } else {
618 81174dae aliguori
        s->rbr = buf[0];
619 81174dae aliguori
        s->lsr |= UART_LSR_DR;
620 81174dae aliguori
    }
621 81174dae aliguori
    serial_update_irq(s);
622 b41a2cd1 bellard
}
623 80cabfad bellard
624 82c643ff bellard
static void serial_event(void *opaque, int event)
625 82c643ff bellard
{
626 82c643ff bellard
    SerialState *s = opaque;
627 81174dae aliguori
#ifdef DEBUG_SERIAL
628 81174dae aliguori
    printf("serial: event %x\n", event);
629 81174dae aliguori
#endif
630 82c643ff bellard
    if (event == CHR_EVENT_BREAK)
631 82c643ff bellard
        serial_receive_break(s);
632 82c643ff bellard
}
633 82c643ff bellard
634 8738a8d0 bellard
static void serial_save(QEMUFile *f, void *opaque)
635 8738a8d0 bellard
{
636 8738a8d0 bellard
    SerialState *s = opaque;
637 8738a8d0 bellard
638 508d92d0 bellard
    qemu_put_be16s(f,&s->divider);
639 8738a8d0 bellard
    qemu_put_8s(f,&s->rbr);
640 8738a8d0 bellard
    qemu_put_8s(f,&s->ier);
641 8738a8d0 bellard
    qemu_put_8s(f,&s->iir);
642 8738a8d0 bellard
    qemu_put_8s(f,&s->lcr);
643 8738a8d0 bellard
    qemu_put_8s(f,&s->mcr);
644 8738a8d0 bellard
    qemu_put_8s(f,&s->lsr);
645 8738a8d0 bellard
    qemu_put_8s(f,&s->msr);
646 8738a8d0 bellard
    qemu_put_8s(f,&s->scr);
647 81174dae aliguori
    qemu_put_8s(f,&s->fcr);
648 8738a8d0 bellard
}
649 8738a8d0 bellard
650 8738a8d0 bellard
static int serial_load(QEMUFile *f, void *opaque, int version_id)
651 8738a8d0 bellard
{
652 8738a8d0 bellard
    SerialState *s = opaque;
653 81174dae aliguori
    uint8_t fcr = 0;
654 8738a8d0 bellard
655 81174dae aliguori
    if(version_id > 3)
656 8738a8d0 bellard
        return -EINVAL;
657 8738a8d0 bellard
658 508d92d0 bellard
    if (version_id >= 2)
659 508d92d0 bellard
        qemu_get_be16s(f, &s->divider);
660 508d92d0 bellard
    else
661 508d92d0 bellard
        s->divider = qemu_get_byte(f);
662 8738a8d0 bellard
    qemu_get_8s(f,&s->rbr);
663 8738a8d0 bellard
    qemu_get_8s(f,&s->ier);
664 8738a8d0 bellard
    qemu_get_8s(f,&s->iir);
665 8738a8d0 bellard
    qemu_get_8s(f,&s->lcr);
666 8738a8d0 bellard
    qemu_get_8s(f,&s->mcr);
667 8738a8d0 bellard
    qemu_get_8s(f,&s->lsr);
668 8738a8d0 bellard
    qemu_get_8s(f,&s->msr);
669 8738a8d0 bellard
    qemu_get_8s(f,&s->scr);
670 8738a8d0 bellard
671 81174dae aliguori
    if (version_id >= 3)
672 81174dae aliguori
        qemu_get_8s(f,&fcr);
673 81174dae aliguori
674 81174dae aliguori
    /* Initialize fcr via setter to perform essential side-effects */
675 81174dae aliguori
    serial_ioport_write(s, 0x02, fcr);
676 8738a8d0 bellard
    return 0;
677 8738a8d0 bellard
}
678 8738a8d0 bellard
679 b2a5160c balrog
static void serial_reset(void *opaque)
680 b2a5160c balrog
{
681 b2a5160c balrog
    SerialState *s = opaque;
682 b2a5160c balrog
683 b2a5160c balrog
    s->rbr = 0;
684 b2a5160c balrog
    s->ier = 0;
685 b2a5160c balrog
    s->iir = UART_IIR_NO_INT;
686 b2a5160c balrog
    s->lcr = 0;
687 b2a5160c balrog
    s->lsr = UART_LSR_TEMT | UART_LSR_THRE;
688 b2a5160c balrog
    s->msr = UART_MSR_DCD | UART_MSR_DSR | UART_MSR_CTS;
689 81174dae aliguori
    /* Default to 9600 baud, no parity, one stop bit */
690 81174dae aliguori
    s->divider = 0x0C;
691 81174dae aliguori
    s->mcr = UART_MCR_OUT2;
692 b2a5160c balrog
    s->scr = 0;
693 81174dae aliguori
    s->tsr_retry = 0;
694 81174dae aliguori
    s->char_transmit_time = (ticks_per_sec / 9600) * 9;
695 81174dae aliguori
    s->poll_msl = 0;
696 81174dae aliguori
697 81174dae aliguori
    fifo_clear(s,RECV_FIFO);
698 81174dae aliguori
    fifo_clear(s,XMIT_FIFO);
699 81174dae aliguori
700 81174dae aliguori
    s->last_xmit_ts = qemu_get_clock(vm_clock);
701 b2a5160c balrog
702 b2a5160c balrog
    s->thr_ipending = 0;
703 b2a5160c balrog
    s->last_break_enable = 0;
704 b2a5160c balrog
    qemu_irq_lower(s->irq);
705 b2a5160c balrog
}
706 b2a5160c balrog
707 81174dae aliguori
static void serial_init_core(SerialState *s, qemu_irq irq, int baudbase,
708 81174dae aliguori
                             CharDriverState *chr)
709 81174dae aliguori
{
710 81174dae aliguori
    s->irq = irq;
711 81174dae aliguori
    s->baudbase = baudbase;
712 81174dae aliguori
    s->chr = chr;
713 81174dae aliguori
714 81174dae aliguori
    s->modem_status_poll = qemu_new_timer(vm_clock, (QEMUTimerCB *) serial_update_msl, s);
715 81174dae aliguori
716 81174dae aliguori
    s->fifo_timeout_timer = qemu_new_timer(vm_clock, (QEMUTimerCB *) fifo_timeout_int, s);
717 81174dae aliguori
    s->transmit_timer = qemu_new_timer(vm_clock, (QEMUTimerCB *) serial_xmit, s);
718 81174dae aliguori
719 81174dae aliguori
    qemu_register_reset(serial_reset, s);
720 81174dae aliguori
    serial_reset(s);
721 81174dae aliguori
722 81174dae aliguori
}
723 81174dae aliguori
724 b41a2cd1 bellard
/* If fd is zero, it means that the serial device uses the console */
725 b6cd0ea1 aurel32
SerialState *serial_init(int base, qemu_irq irq, int baudbase,
726 b6cd0ea1 aurel32
                         CharDriverState *chr)
727 b41a2cd1 bellard
{
728 b41a2cd1 bellard
    SerialState *s;
729 b41a2cd1 bellard
730 b41a2cd1 bellard
    s = qemu_mallocz(sizeof(SerialState));
731 b41a2cd1 bellard
    if (!s)
732 b41a2cd1 bellard
        return NULL;
733 6936bfe5 aurel32
734 81174dae aliguori
    serial_init_core(s, irq, baudbase, chr);
735 b41a2cd1 bellard
736 81174dae aliguori
    register_savevm("serial", base, 3, serial_save, serial_load, s);
737 8738a8d0 bellard
738 b41a2cd1 bellard
    register_ioport_write(base, 8, 1, serial_ioport_write, s);
739 b41a2cd1 bellard
    register_ioport_read(base, 8, 1, serial_ioport_read, s);
740 e5b0bc44 pbrook
    qemu_chr_add_handlers(chr, serial_can_receive1, serial_receive1,
741 e5b0bc44 pbrook
                          serial_event, s);
742 b41a2cd1 bellard
    return s;
743 80cabfad bellard
}
744 e5d13e2f bellard
745 e5d13e2f bellard
/* Memory mapped interface */
746 a4bc3afc ths
uint32_t serial_mm_readb (void *opaque, target_phys_addr_t addr)
747 e5d13e2f bellard
{
748 e5d13e2f bellard
    SerialState *s = opaque;
749 e5d13e2f bellard
750 e5d13e2f bellard
    return serial_ioport_read(s, (addr - s->base) >> s->it_shift) & 0xFF;
751 e5d13e2f bellard
}
752 e5d13e2f bellard
753 a4bc3afc ths
void serial_mm_writeb (void *opaque,
754 a4bc3afc ths
                       target_phys_addr_t addr, uint32_t value)
755 e5d13e2f bellard
{
756 e5d13e2f bellard
    SerialState *s = opaque;
757 e5d13e2f bellard
758 e5d13e2f bellard
    serial_ioport_write(s, (addr - s->base) >> s->it_shift, value & 0xFF);
759 e5d13e2f bellard
}
760 e5d13e2f bellard
761 a4bc3afc ths
uint32_t serial_mm_readw (void *opaque, target_phys_addr_t addr)
762 e5d13e2f bellard
{
763 e5d13e2f bellard
    SerialState *s = opaque;
764 e918ee04 ths
    uint32_t val;
765 e5d13e2f bellard
766 e918ee04 ths
    val = serial_ioport_read(s, (addr - s->base) >> s->it_shift) & 0xFFFF;
767 e918ee04 ths
#ifdef TARGET_WORDS_BIGENDIAN
768 e918ee04 ths
    val = bswap16(val);
769 e918ee04 ths
#endif
770 e918ee04 ths
    return val;
771 e5d13e2f bellard
}
772 e5d13e2f bellard
773 a4bc3afc ths
void serial_mm_writew (void *opaque,
774 a4bc3afc ths
                       target_phys_addr_t addr, uint32_t value)
775 e5d13e2f bellard
{
776 e5d13e2f bellard
    SerialState *s = opaque;
777 e918ee04 ths
#ifdef TARGET_WORDS_BIGENDIAN
778 e918ee04 ths
    value = bswap16(value);
779 e918ee04 ths
#endif
780 e5d13e2f bellard
    serial_ioport_write(s, (addr - s->base) >> s->it_shift, value & 0xFFFF);
781 e5d13e2f bellard
}
782 e5d13e2f bellard
783 a4bc3afc ths
uint32_t serial_mm_readl (void *opaque, target_phys_addr_t addr)
784 e5d13e2f bellard
{
785 e5d13e2f bellard
    SerialState *s = opaque;
786 e918ee04 ths
    uint32_t val;
787 e5d13e2f bellard
788 e918ee04 ths
    val = serial_ioport_read(s, (addr - s->base) >> s->it_shift);
789 e918ee04 ths
#ifdef TARGET_WORDS_BIGENDIAN
790 e918ee04 ths
    val = bswap32(val);
791 e918ee04 ths
#endif
792 e918ee04 ths
    return val;
793 e5d13e2f bellard
}
794 e5d13e2f bellard
795 a4bc3afc ths
void serial_mm_writel (void *opaque,
796 a4bc3afc ths
                       target_phys_addr_t addr, uint32_t value)
797 e5d13e2f bellard
{
798 e5d13e2f bellard
    SerialState *s = opaque;
799 e918ee04 ths
#ifdef TARGET_WORDS_BIGENDIAN
800 e918ee04 ths
    value = bswap32(value);
801 e918ee04 ths
#endif
802 e5d13e2f bellard
    serial_ioport_write(s, (addr - s->base) >> s->it_shift, value);
803 e5d13e2f bellard
}
804 e5d13e2f bellard
805 e5d13e2f bellard
static CPUReadMemoryFunc *serial_mm_read[] = {
806 e5d13e2f bellard
    &serial_mm_readb,
807 e5d13e2f bellard
    &serial_mm_readw,
808 e5d13e2f bellard
    &serial_mm_readl,
809 e5d13e2f bellard
};
810 e5d13e2f bellard
811 e5d13e2f bellard
static CPUWriteMemoryFunc *serial_mm_write[] = {
812 e5d13e2f bellard
    &serial_mm_writeb,
813 e5d13e2f bellard
    &serial_mm_writew,
814 e5d13e2f bellard
    &serial_mm_writel,
815 e5d13e2f bellard
};
816 e5d13e2f bellard
817 71db710f blueswir1
SerialState *serial_mm_init (target_phys_addr_t base, int it_shift,
818 b6cd0ea1 aurel32
                             qemu_irq irq, int baudbase,
819 b6cd0ea1 aurel32
                             CharDriverState *chr, int ioregister)
820 e5d13e2f bellard
{
821 e5d13e2f bellard
    SerialState *s;
822 e5d13e2f bellard
    int s_io_memory;
823 e5d13e2f bellard
824 e5d13e2f bellard
    s = qemu_mallocz(sizeof(SerialState));
825 e5d13e2f bellard
    if (!s)
826 e5d13e2f bellard
        return NULL;
827 81174dae aliguori
828 e5d13e2f bellard
    s->base = base;
829 e5d13e2f bellard
    s->it_shift = it_shift;
830 e5d13e2f bellard
831 81174dae aliguori
    serial_init_core(s, irq, baudbase, chr);
832 81174dae aliguori
    register_savevm("serial", base, 3, serial_save, serial_load, s);
833 e5d13e2f bellard
834 a4bc3afc ths
    if (ioregister) {
835 a4bc3afc ths
        s_io_memory = cpu_register_io_memory(0, serial_mm_read,
836 a4bc3afc ths
                                             serial_mm_write, s);
837 a4bc3afc ths
        cpu_register_physical_memory(base, 8 << it_shift, s_io_memory);
838 a4bc3afc ths
    }
839 e5b0bc44 pbrook
    qemu_chr_add_handlers(chr, serial_can_receive1, serial_receive1,
840 e5b0bc44 pbrook
                          serial_event, s);
841 81174dae aliguori
    serial_update_msl(s);
842 e5d13e2f bellard
    return s;
843 e5d13e2f bellard
}