| 83 |
/* NOTE: this hidden state is necessary for tx irq generation as |
/* NOTE: this hidden state is necessary for tx irq generation as |
| 84 |
it can be reset while reading iir */ |
it can be reset while reading iir */ |
| 85 |
int thr_ipending; |
int thr_ipending; |
| 86 |
|
SetIRQFunc *set_irq; |
| 87 |
|
void *irq_opaque; |
| 88 |
int irq; |
int irq; |
| 89 |
CharDriverState *chr; |
CharDriverState *chr; |
| 90 |
int last_break_enable; |
int last_break_enable; |
| 91 |
|
target_ulong base; |
| 92 |
|
int it_shift; |
| 93 |
}; |
}; |
| 94 |
|
|
| 95 |
static void serial_update_irq(SerialState *s) |
static void serial_update_irq(SerialState *s) |
| 102 |
s->iir = UART_IIR_NO_INT; |
s->iir = UART_IIR_NO_INT; |
| 103 |
} |
} |
| 104 |
if (s->iir != UART_IIR_NO_INT) { |
if (s->iir != UART_IIR_NO_INT) { |
| 105 |
pic_set_irq(s->irq, 1); |
s->set_irq(s->irq_opaque, s->irq, 1); |
| 106 |
} else { |
} else { |
| 107 |
pic_set_irq(s->irq, 0); |
s->set_irq(s->irq_opaque, s->irq, 0); |
| 108 |
} |
} |
| 109 |
} |
} |
| 110 |
|
|
| 343 |
} |
} |
| 344 |
|
|
| 345 |
/* If fd is zero, it means that the serial device uses the console */ |
/* If fd is zero, it means that the serial device uses the console */ |
| 346 |
SerialState *serial_init(int base, int irq, CharDriverState *chr) |
SerialState *serial_init(SetIRQFunc *set_irq, void *opaque, |
| 347 |
|
int base, int irq, CharDriverState *chr) |
| 348 |
{ |
{ |
| 349 |
SerialState *s; |
SerialState *s; |
| 350 |
|
|
| 351 |
s = qemu_mallocz(sizeof(SerialState)); |
s = qemu_mallocz(sizeof(SerialState)); |
| 352 |
if (!s) |
if (!s) |
| 353 |
return NULL; |
return NULL; |
| 354 |
|
s->set_irq = set_irq; |
| 355 |
|
s->irq_opaque = opaque; |
| 356 |
s->irq = irq; |
s->irq = irq; |
| 357 |
s->lsr = UART_LSR_TEMT | UART_LSR_THRE; |
s->lsr = UART_LSR_TEMT | UART_LSR_THRE; |
| 358 |
s->iir = UART_IIR_NO_INT; |
s->iir = UART_IIR_NO_INT; |
| 364 |
s->chr = chr; |
s->chr = chr; |
| 365 |
qemu_chr_add_read_handler(chr, serial_can_receive1, serial_receive1, s); |
qemu_chr_add_read_handler(chr, serial_can_receive1, serial_receive1, s); |
| 366 |
qemu_chr_add_event_handler(chr, serial_event); |
qemu_chr_add_event_handler(chr, serial_event); |
| 367 |
|
return s; |
| 368 |
|
} |
| 369 |
|
|
| 370 |
|
/* Memory mapped interface */ |
| 371 |
|
static uint32_t serial_mm_readb (void *opaque, target_phys_addr_t addr) |
| 372 |
|
{ |
| 373 |
|
SerialState *s = opaque; |
| 374 |
|
|
| 375 |
|
return serial_ioport_read(s, (addr - s->base) >> s->it_shift) & 0xFF; |
| 376 |
|
} |
| 377 |
|
|
| 378 |
|
static void serial_mm_writeb (void *opaque, |
| 379 |
|
target_phys_addr_t addr, uint32_t value) |
| 380 |
|
{ |
| 381 |
|
SerialState *s = opaque; |
| 382 |
|
|
| 383 |
|
serial_ioport_write(s, (addr - s->base) >> s->it_shift, value & 0xFF); |
| 384 |
|
} |
| 385 |
|
|
| 386 |
|
static uint32_t serial_mm_readw (void *opaque, target_phys_addr_t addr) |
| 387 |
|
{ |
| 388 |
|
SerialState *s = opaque; |
| 389 |
|
|
| 390 |
|
return serial_ioport_read(s, (addr - s->base) >> s->it_shift) & 0xFFFF; |
| 391 |
|
} |
| 392 |
|
|
| 393 |
|
static void serial_mm_writew (void *opaque, |
| 394 |
|
target_phys_addr_t addr, uint32_t value) |
| 395 |
|
{ |
| 396 |
|
SerialState *s = opaque; |
| 397 |
|
|
| 398 |
|
serial_ioport_write(s, (addr - s->base) >> s->it_shift, value & 0xFFFF); |
| 399 |
|
} |
| 400 |
|
|
| 401 |
|
static uint32_t serial_mm_readl (void *opaque, target_phys_addr_t addr) |
| 402 |
|
{ |
| 403 |
|
SerialState *s = opaque; |
| 404 |
|
|
| 405 |
|
return serial_ioport_read(s, (addr - s->base) >> s->it_shift); |
| 406 |
|
} |
| 407 |
|
|
| 408 |
|
static void serial_mm_writel (void *opaque, |
| 409 |
|
target_phys_addr_t addr, uint32_t value) |
| 410 |
|
{ |
| 411 |
|
SerialState *s = opaque; |
| 412 |
|
|
| 413 |
|
serial_ioport_write(s, (addr - s->base) >> s->it_shift, value); |
| 414 |
|
} |
| 415 |
|
|
| 416 |
|
static CPUReadMemoryFunc *serial_mm_read[] = { |
| 417 |
|
&serial_mm_readb, |
| 418 |
|
&serial_mm_readw, |
| 419 |
|
&serial_mm_readl, |
| 420 |
|
}; |
| 421 |
|
|
| 422 |
|
static CPUWriteMemoryFunc *serial_mm_write[] = { |
| 423 |
|
&serial_mm_writeb, |
| 424 |
|
&serial_mm_writew, |
| 425 |
|
&serial_mm_writel, |
| 426 |
|
}; |
| 427 |
|
|
| 428 |
|
SerialState *serial_mm_init (SetIRQFunc *set_irq, void *opaque, |
| 429 |
|
target_ulong base, int it_shift, |
| 430 |
|
int irq, CharDriverState *chr) |
| 431 |
|
{ |
| 432 |
|
SerialState *s; |
| 433 |
|
int s_io_memory; |
| 434 |
|
|
| 435 |
|
s = qemu_mallocz(sizeof(SerialState)); |
| 436 |
|
if (!s) |
| 437 |
|
return NULL; |
| 438 |
|
s->set_irq = set_irq; |
| 439 |
|
s->irq_opaque = opaque; |
| 440 |
|
s->irq = irq; |
| 441 |
|
s->lsr = UART_LSR_TEMT | UART_LSR_THRE; |
| 442 |
|
s->iir = UART_IIR_NO_INT; |
| 443 |
|
s->base = base; |
| 444 |
|
s->it_shift = it_shift; |
| 445 |
|
|
| 446 |
|
register_savevm("serial", base, 1, serial_save, serial_load, s); |
| 447 |
|
|
| 448 |
|
s_io_memory = cpu_register_io_memory(0, serial_mm_read, |
| 449 |
|
serial_mm_write, s); |
| 450 |
|
cpu_register_physical_memory(base, 8 << it_shift, s_io_memory); |
| 451 |
|
s->chr = chr; |
| 452 |
|
qemu_chr_add_read_handler(chr, serial_can_receive1, serial_receive1, s); |
| 453 |
|
qemu_chr_add_event_handler(chr, serial_event); |
| 454 |
return s; |
return s; |
| 455 |
} |
} |