Revision b41a2cd1 hw/serial.c

b/hw/serial.c
90 90
#define UART_LSR_OE	0x02	/* Overrun error indicator */
91 91
#define UART_LSR_DR	0x01	/* Receiver data ready */
92 92

  
93
typedef struct SerialState {
93
struct SerialState {
94 94
    uint8_t divider;
95 95
    uint8_t rbr; /* receive register */
96 96
    uint8_t ier;
......
104 104
       it can be reset while reading iir */
105 105
    int thr_ipending;
106 106
    int irq;
107
} SerialState;
107
    int out_fd;
108
};
108 109

  
109
SerialState serial_ports[1];
110

  
111
void serial_update_irq(void)
110
static void serial_update_irq(SerialState *s)
112 111
{
113
    SerialState *s = &serial_ports[0];
114

  
115 112
    if ((s->lsr & UART_LSR_DR) && (s->ier & UART_IER_RDI)) {
116 113
        s->iir = UART_IIR_RDI;
117 114
    } else if (s->thr_ipending && (s->ier & UART_IER_THRI)) {
......
126 123
    }
127 124
}
128 125

  
129
void serial_ioport_write(CPUState *env, uint32_t addr, uint32_t val)
126
static void serial_ioport_write(void *opaque, uint32_t addr, uint32_t val)
130 127
{
131
    SerialState *s = &serial_ports[0];
128
    SerialState *s = opaque;
132 129
    unsigned char ch;
133 130
    int ret;
134 131
    
......
144 141
        } else {
145 142
            s->thr_ipending = 0;
146 143
            s->lsr &= ~UART_LSR_THRE;
147
            serial_update_irq();
144
            serial_update_irq(s);
148 145

  
149 146
            ch = val;
150 147
            do {
151
                ret = write(1, &ch, 1);
148
                ret = write(s->out_fd, &ch, 1);
152 149
            } while (ret != 1);
153 150
            s->thr_ipending = 1;
154 151
            s->lsr |= UART_LSR_THRE;
155 152
            s->lsr |= UART_LSR_TEMT;
156
            serial_update_irq();
153
            serial_update_irq(s);
157 154
        }
158 155
        break;
159 156
    case 1:
......
161 158
            s->divider = (s->divider & 0x00ff) | (val << 8);
162 159
        } else {
163 160
            s->ier = val;
164
            serial_update_irq();
161
            serial_update_irq(s);
165 162
        }
166 163
        break;
167 164
    case 2:
......
183 180
    }
184 181
}
185 182

  
186
uint32_t serial_ioport_read(CPUState *env, uint32_t addr)
183
static uint32_t serial_ioport_read(void *opaque, uint32_t addr)
187 184
{
188
    SerialState *s = &serial_ports[0];
185
    SerialState *s = opaque;
189 186
    uint32_t ret;
190 187

  
191 188
    addr &= 7;
......
197 194
        } else {
198 195
            ret = s->rbr;
199 196
            s->lsr &= ~(UART_LSR_DR | UART_LSR_BI);
200
            serial_update_irq();
197
            serial_update_irq(s);
201 198
        }
202 199
        break;
203 200
    case 1:
......
212 209
        /* reset THR pending bit */
213 210
        if ((ret & 0x7) == UART_IIR_THRI)
214 211
            s->thr_ipending = 0;
215
        serial_update_irq();
212
        serial_update_irq(s);
216 213
        break;
217 214
    case 3:
218 215
        ret = s->lcr;
......
244 241
    return ret;
245 242
}
246 243

  
247
int serial_can_receive(void)
244
int serial_can_receive(SerialState *s)
248 245
{
249
    SerialState *s = &serial_ports[0];
250 246
    return !(s->lsr & UART_LSR_DR);
251 247
}
252 248

  
253
void serial_receive_byte(int ch)
249
void serial_receive_byte(SerialState *s, int ch)
254 250
{
255
    SerialState *s = &serial_ports[0];
256

  
257 251
    s->rbr = ch;
258 252
    s->lsr |= UART_LSR_DR;
259
    serial_update_irq();
253
    serial_update_irq(s);
260 254
}
261 255

  
262
void serial_receive_break(void)
256
void serial_receive_break(SerialState *s)
263 257
{
264
    SerialState *s = &serial_ports[0];
265

  
266 258
    s->rbr = 0;
267 259
    s->lsr |= UART_LSR_BI | UART_LSR_DR;
268
    serial_update_irq();
260
    serial_update_irq(s);
269 261
}
270 262

  
271
void serial_init(int base, int irq)
263
static int serial_can_receive1(void *opaque)
272 264
{
273
    SerialState *s = &serial_ports[0];
265
    SerialState *s = opaque;
266
    return serial_can_receive(s);
267
}
268

  
269
static void serial_receive1(void *opaque, const uint8_t *buf, int size)
270
{
271
    SerialState *s = opaque;
272
    serial_receive_byte(s, buf[0]);
273
}
274 274

  
275
/* If fd is zero, it means that the serial device uses the console */
276
SerialState *serial_init(int base, int irq, int fd)
277
{
278
    SerialState *s;
279

  
280
    s = qemu_mallocz(sizeof(SerialState));
281
    if (!s)
282
        return NULL;
275 283
    s->irq = irq;
276 284
    s->lsr = UART_LSR_TEMT | UART_LSR_THRE;
277 285
    s->iir = UART_IIR_NO_INT;
278
    
279
    register_ioport_write(base, 8, serial_ioport_write, 1);
280
    register_ioport_read(base, 8, serial_ioport_read, 1);
286

  
287
    register_ioport_write(base, 8, 1, serial_ioport_write, s);
288
    register_ioport_read(base, 8, 1, serial_ioport_read, s);
289

  
290
    if (fd != 0) {
291
        add_fd_read_handler(fd, serial_can_receive1, serial_receive1, s);
292
        s->out_fd = fd;
293
    } else {
294
        serial_console = s;
295
        s->out_fd = 1;
296
    }
297
    return s;
281 298
}

Also available in: Unified diff