serial: split serial.c

Split serial.c into serial.c, serial.h and serial-isa.c.  While being at
creating a serial.h header file move the serial prototypes from pc.h to
the new serial.h.  The latter leads to s/pc.h/serial.h/ in tons of
boards which just want the serial bits from pc.h

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
This commit is contained in:
Gerd Hoffmann 2012-10-17 09:54:19 +02:00 committed by Anthony Liguori
parent ad0b5321f1
commit 488cb996cd
26 changed files with 257 additions and 180 deletions

View File

@ -20,7 +20,7 @@ common-obj-$(CONFIG_M48T59) += m48t59.o
common-obj-$(CONFIG_ESCC) += escc.o
common-obj-$(CONFIG_EMPTY_SLOT) += empty_slot.o
common-obj-$(CONFIG_SERIAL) += serial.o
common-obj-$(CONFIG_SERIAL) += serial.o serial-isa.o
common-obj-$(CONFIG_PARALLEL) += parallel.o
common-obj-$(CONFIG_I8254) += i8254_common.o i8254.o
common-obj-$(CONFIG_PCSPK) += pcspk.o

View File

@ -15,6 +15,7 @@
#include "mc146818rtc.h"
#include "ide.h"
#include "i8254.h"
#include "serial.h"
#define MAX_IDE_BUS 2

View File

@ -21,7 +21,7 @@
#include "net.h"
#include "sysemu.h"
#include "boards.h"
#include "pc.h" /* for the FPGA UART that emulates a 16550 */
#include "serial.h"
#include "imx.h"
/* Memory map for Kzm Emulation Baseboard:

View File

@ -20,6 +20,7 @@
#include "hw.h"
#include "pc.h"
#include "serial.h"
#include "fdc.h"
#include "net.h"
#include "boards.h"

View File

@ -26,6 +26,7 @@
#include "mips.h"
#include "mips_cpudevs.h"
#include "pc.h"
#include "serial.h"
#include "isa.h"
#include "fdc.h"
#include "sysemu.h"

View File

@ -24,6 +24,7 @@
#include "hw.h"
#include "pc.h"
#include "serial.h"
#include "fdc.h"
#include "net.h"
#include "boards.h"

View File

@ -27,7 +27,7 @@
#include "hw.h"
#include "mips.h"
#include "mips_cpudevs.h"
#include "pc.h"
#include "serial.h"
#include "isa.h"
#include "net.h"
#include "sysemu.h"

View File

@ -11,6 +11,7 @@
#include "mips.h"
#include "mips_cpudevs.h"
#include "pc.h"
#include "serial.h"
#include "isa.h"
#include "net.h"
#include "sysemu.h"

View File

@ -15,7 +15,7 @@
#include "net.h"
#include "sysemu.h"
#include "boards.h"
#include "pc.h"
#include "serial.h"
#include "qemu-timer.h"
#include "ptimer.h"
#include "block.h"

View File

@ -20,8 +20,7 @@
#include "qemu-char.h"
#include "hw.h"
#include "omap.h"
/* We use pc-style serial ports. */
#include "pc.h"
#include "serial.h"
#include "exec-memory.h"
/* UARTs */

View File

@ -21,7 +21,8 @@
#include "hw.h"
#include "boards.h"
#include "elf.h"
#include "pc.h"
#include "serial.h"
#include "net.h"
#include "loader.h"
#include "exec-memory.h"
#include "sysemu.h"

View File

@ -23,6 +23,7 @@
*/
#include "hw.h"
#include "pc.h"
#include "serial.h"
#include "apic.h"
#include "fdc.h"
#include "ide.h"

27
hw/pc.h
View File

@ -12,33 +12,6 @@
/* PC-style peripherals (also used by other machines). */
/* serial.c */
SerialState *serial_init(int base, qemu_irq irq, int baudbase,
CharDriverState *chr);
SerialState *serial_mm_init(MemoryRegion *address_space,
target_phys_addr_t base, int it_shift,
qemu_irq irq, int baudbase,
CharDriverState *chr, enum device_endian);
static inline bool serial_isa_init(ISABus *bus, int index,
CharDriverState *chr)
{
ISADevice *dev;
dev = isa_try_create(bus, "isa-serial");
if (!dev) {
return false;
}
qdev_prop_set_uint32(&dev->qdev, "index", index);
qdev_prop_set_chr(&dev->qdev, "chardev", chr);
if (qdev_init(&dev->qdev) < 0) {
return false;
}
return true;
}
void serial_set_frequency(SerialState *s, uint32_t frequency);
/* parallel.c */
static inline bool parallel_init(ISABus *bus, int index, CharDriverState *chr)
{

View File

@ -34,7 +34,7 @@
#include "boards.h"
#include "xilinx.h"
#include "blockdev.h"
#include "pc.h"
#include "serial.h"
#include "exec-memory.h"
#include "ssi.h"

View File

@ -19,7 +19,7 @@
#include "e500.h"
#include "net.h"
#include "hw/hw.h"
#include "hw/pc.h"
#include "hw/serial.h"
#include "hw/pci.h"
#include "hw/boards.h"
#include "sysemu.h"

View File

@ -24,7 +24,7 @@
#include "hw.h"
#include "ppc.h"
#include "ppc405.h"
#include "pc.h"
#include "serial.h"
#include "qemu-timer.h"
#include "sysemu.h"
#include "qemu-log.h"

View File

@ -23,7 +23,7 @@
#include "loader.h"
#include "elf.h"
#include "exec-memory.h"
#include "pc.h"
#include "serial.h"
#include "ppc.h"
#include "ppc405.h"
#include "sysemu.h"

View File

@ -24,6 +24,7 @@
#include "hw.h"
#include "nvram.h"
#include "pc.h"
#include "serial.h"
#include "fdc.h"
#include "net.h"
#include "sysemu.h"

View File

@ -10,7 +10,7 @@
#include "sysbus.h"
#include "pxa.h"
#include "sysemu.h"
#include "pc.h"
#include "serial.h"
#include "i2c.h"
#include "ssi.h"
#include "qemu-char.h"

130
hw/serial-isa.c Normal file
View File

@ -0,0 +1,130 @@
/*
* QEMU 16550A UART emulation
*
* Copyright (c) 2003-2004 Fabrice Bellard
* Copyright (c) 2008 Citrix Systems, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "serial.h"
#include "isa.h"
typedef struct ISASerialState {
ISADevice dev;
uint32_t index;
uint32_t iobase;
uint32_t isairq;
SerialState state;
} ISASerialState;
static const int isa_serial_io[MAX_SERIAL_PORTS] = {
0x3f8, 0x2f8, 0x3e8, 0x2e8
};
static const int isa_serial_irq[MAX_SERIAL_PORTS] = {
4, 3, 4, 3
};
static int serial_isa_initfn(ISADevice *dev)
{
static int index;
ISASerialState *isa = DO_UPCAST(ISASerialState, dev, dev);
SerialState *s = &isa->state;
if (isa->index == -1) {
isa->index = index;
}
if (isa->index >= MAX_SERIAL_PORTS) {
return -1;
}
if (isa->iobase == -1) {
isa->iobase = isa_serial_io[isa->index];
}
if (isa->isairq == -1) {
isa->isairq = isa_serial_irq[isa->index];
}
index++;
s->baudbase = 115200;
isa_init_irq(dev, &s->irq, isa->isairq);
serial_init_core(s);
qdev_set_legacy_instance_id(&dev->qdev, isa->iobase, 3);
memory_region_init_io(&s->io, &serial_io_ops, s, "serial", 8);
isa_register_ioport(dev, &s->io, isa->iobase);
return 0;
}
static const VMStateDescription vmstate_isa_serial = {
.name = "serial",
.version_id = 3,
.minimum_version_id = 2,
.fields = (VMStateField[]) {
VMSTATE_STRUCT(state, ISASerialState, 0, vmstate_serial, SerialState),
VMSTATE_END_OF_LIST()
}
};
static Property serial_isa_properties[] = {
DEFINE_PROP_UINT32("index", ISASerialState, index, -1),
DEFINE_PROP_HEX32("iobase", ISASerialState, iobase, -1),
DEFINE_PROP_UINT32("irq", ISASerialState, isairq, -1),
DEFINE_PROP_CHR("chardev", ISASerialState, state.chr),
DEFINE_PROP_UINT32("wakeup", ISASerialState, state.wakeup, 0),
DEFINE_PROP_END_OF_LIST(),
};
static void serial_isa_class_initfn(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
ic->init = serial_isa_initfn;
dc->vmsd = &vmstate_isa_serial;
dc->props = serial_isa_properties;
}
static TypeInfo serial_isa_info = {
.name = "isa-serial",
.parent = TYPE_ISA_DEVICE,
.instance_size = sizeof(ISASerialState),
.class_init = serial_isa_class_initfn,
};
static void serial_register_types(void)
{
type_register_static(&serial_isa_info);
}
type_init(serial_register_types)
bool serial_isa_init(ISABus *bus, int index, CharDriverState *chr)
{
ISADevice *dev;
dev = isa_try_create(bus, "isa-serial");
if (!dev) {
return false;
}
qdev_prop_set_uint32(&dev->qdev, "index", index);
qdev_prop_set_chr(&dev->qdev, "chardev", chr);
if (qdev_init(&dev->qdev) < 0) {
return false;
}
return true;
}

View File

@ -22,12 +22,10 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "hw.h"
#include "serial.h"
#include "qemu-char.h"
#include "isa.h"
#include "pc.h"
#include "qemu-timer.h"
#include "sysemu.h"
//#define DEBUG_SERIAL
@ -93,8 +91,6 @@
#define UART_FCR_RFR 0x02 /* RCVR Fifo Reset */
#define UART_FCR_FE 0x01 /* FIFO Enable */
#define UART_FIFO_LENGTH 16 /* 16550A Fifo Length */
#define XMIT_FIFO 0
#define RECV_FIFO 1
#define MAX_XMIT_RETRY 4
@ -107,64 +103,6 @@ do { fprintf(stderr, "serial: " fmt , ## __VA_ARGS__); } while (0)
do {} while (0)
#endif
typedef struct SerialFIFO {
uint8_t data[UART_FIFO_LENGTH];
uint8_t count;
uint8_t itl; /* Interrupt Trigger Level */
uint8_t tail;
uint8_t head;
} SerialFIFO;
struct SerialState {
uint16_t divider;
uint8_t rbr; /* receive register */
uint8_t thr; /* transmit holding register */
uint8_t tsr; /* transmit shift register */
uint8_t ier;
uint8_t iir; /* read only */
uint8_t lcr;
uint8_t mcr;
uint8_t lsr; /* read only */
uint8_t msr; /* read only */
uint8_t scr;
uint8_t fcr;
uint8_t fcr_vmstate; /* we can't write directly this value
it has side effects */
/* NOTE: this hidden state is necessary for tx irq generation as
it can be reset while reading iir */
int thr_ipending;
qemu_irq irq;
CharDriverState *chr;
int last_break_enable;
int it_shift;
int baudbase;
int tsr_retry;
uint32_t wakeup;
uint64_t last_xmit_ts; /* Time when the last byte was successfully sent out of the tsr */
SerialFIFO recv_fifo;
SerialFIFO xmit_fifo;
struct QEMUTimer *fifo_timeout_timer;
int timeout_ipending; /* timeout interrupt pending state */
struct QEMUTimer *transmit_timer;
uint64_t char_transmit_time; /* time to transmit a char in ticks*/
int poll_msl;
struct QEMUTimer *modem_status_poll;
MemoryRegion io;
};
typedef struct ISASerialState {
ISADevice dev;
uint32_t index;
uint32_t iobase;
uint32_t isairq;
SerialState state;
} ISASerialState;
static void serial_receive1(void *opaque, const uint8_t *buf, int size);
static void fifo_clear(SerialState *s, int fifo)
@ -687,7 +625,7 @@ static int serial_post_load(void *opaque, int version_id)
return 0;
}
static const VMStateDescription vmstate_serial = {
const VMStateDescription vmstate_serial = {
.name = "serial",
.version_id = 3,
.minimum_version_id = 2,
@ -736,7 +674,7 @@ static void serial_reset(void *opaque)
qemu_irq_lower(s->irq);
}
static void serial_init_core(SerialState *s)
void serial_init_core(SerialState *s)
{
if (!s->chr) {
fprintf(stderr, "Can't create serial device, empty char device\n");
@ -761,54 +699,15 @@ void serial_set_frequency(SerialState *s, uint32_t frequency)
serial_update_parameters(s);
}
static const int isa_serial_io[MAX_SERIAL_PORTS] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 };
static const int isa_serial_irq[MAX_SERIAL_PORTS] = { 4, 3, 4, 3 };
static const MemoryRegionPortio serial_portio[] = {
{ 0, 8, 1, .read = serial_ioport_read, .write = serial_ioport_write },
PORTIO_END_OF_LIST()
};
static const MemoryRegionOps serial_io_ops = {
const MemoryRegionOps serial_io_ops = {
.old_portio = serial_portio
};
static int serial_isa_initfn(ISADevice *dev)
{
static int index;
ISASerialState *isa = DO_UPCAST(ISASerialState, dev, dev);
SerialState *s = &isa->state;
if (isa->index == -1)
isa->index = index;
if (isa->index >= MAX_SERIAL_PORTS)
return -1;
if (isa->iobase == -1)
isa->iobase = isa_serial_io[isa->index];
if (isa->isairq == -1)
isa->isairq = isa_serial_irq[isa->index];
index++;
s->baudbase = 115200;
isa_init_irq(dev, &s->irq, isa->isairq);
serial_init_core(s);
qdev_set_legacy_instance_id(&dev->qdev, isa->iobase, 3);
memory_region_init_io(&s->io, &serial_io_ops, s, "serial", 8);
isa_register_ioport(dev, &s->io, isa->iobase);
return 0;
}
static const VMStateDescription vmstate_isa_serial = {
.name = "serial",
.version_id = 3,
.minimum_version_id = 2,
.fields = (VMStateField []) {
VMSTATE_STRUCT(state, ISASerialState, 0, vmstate_serial, SerialState),
VMSTATE_END_OF_LIST()
}
};
SerialState *serial_init(int base, qemu_irq irq, int baudbase,
CharDriverState *chr)
{
@ -886,35 +785,3 @@ SerialState *serial_mm_init(MemoryRegion *address_space,
serial_update_msl(s);
return s;
}
static Property serial_isa_properties[] = {
DEFINE_PROP_UINT32("index", ISASerialState, index, -1),
DEFINE_PROP_HEX32("iobase", ISASerialState, iobase, -1),
DEFINE_PROP_UINT32("irq", ISASerialState, isairq, -1),
DEFINE_PROP_CHR("chardev", ISASerialState, state.chr),
DEFINE_PROP_UINT32("wakeup", ISASerialState, state.wakeup, 0),
DEFINE_PROP_END_OF_LIST(),
};
static void serial_isa_class_initfn(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
ic->init = serial_isa_initfn;
dc->vmsd = &vmstate_isa_serial;
dc->props = serial_isa_properties;
}
static TypeInfo serial_isa_info = {
.name = "isa-serial",
.parent = TYPE_ISA_DEVICE,
.instance_size = sizeof(ISASerialState),
.class_init = serial_isa_class_initfn,
};
static void serial_register_types(void)
{
type_register_static(&serial_isa_info);
}
type_init(serial_register_types)

98
hw/serial.h Normal file
View File

@ -0,0 +1,98 @@
/*
* QEMU 16550A UART emulation
*
* Copyright (c) 2003-2004 Fabrice Bellard
* Copyright (c) 2008 Citrix Systems, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "hw.h"
#include "sysemu.h"
#include "memory.h"
#define UART_FIFO_LENGTH 16 /* 16550A Fifo Length */
typedef struct SerialFIFO {
uint8_t data[UART_FIFO_LENGTH];
uint8_t count;
uint8_t itl; /* Interrupt Trigger Level */
uint8_t tail;
uint8_t head;
} SerialFIFO;
struct SerialState {
uint16_t divider;
uint8_t rbr; /* receive register */
uint8_t thr; /* transmit holding register */
uint8_t tsr; /* transmit shift register */
uint8_t ier;
uint8_t iir; /* read only */
uint8_t lcr;
uint8_t mcr;
uint8_t lsr; /* read only */
uint8_t msr; /* read only */
uint8_t scr;
uint8_t fcr;
uint8_t fcr_vmstate; /* we can't write directly this value
it has side effects */
/* NOTE: this hidden state is necessary for tx irq generation as
it can be reset while reading iir */
int thr_ipending;
qemu_irq irq;
CharDriverState *chr;
int last_break_enable;
int it_shift;
int baudbase;
int tsr_retry;
uint32_t wakeup;
/* Time when the last byte was successfully sent out of the tsr */
uint64_t last_xmit_ts;
SerialFIFO recv_fifo;
SerialFIFO xmit_fifo;
struct QEMUTimer *fifo_timeout_timer;
int timeout_ipending; /* timeout interrupt pending state */
struct QEMUTimer *transmit_timer;
uint64_t char_transmit_time; /* time to transmit a char in ticks */
int poll_msl;
struct QEMUTimer *modem_status_poll;
MemoryRegion io;
};
extern const VMStateDescription vmstate_serial;
extern const MemoryRegionOps serial_io_ops;
void serial_init_core(SerialState *s);
void serial_set_frequency(SerialState *s, uint32_t frequency);
/* legacy pre qom */
SerialState *serial_init(int base, qemu_irq irq, int baudbase,
CharDriverState *chr);
SerialState *serial_mm_init(MemoryRegion *address_space,
target_phys_addr_t base, int it_shift,
qemu_irq irq, int baudbase,
CharDriverState *chr, enum device_endian end);
/* serial-isa.c */
bool serial_isa_init(ISABus *bus, int index, CharDriverState *chr);

View File

@ -24,7 +24,7 @@
#include <stdio.h>
#include "hw.h"
#include "pc.h"
#include "serial.h"
#include "console.h"
#include "devices.h"
#include "sysbus.h"

View File

@ -25,6 +25,7 @@
#include "pci.h"
#include "apb_pci.h"
#include "pc.h"
#include "serial.h"
#include "nvram.h"
#include "fdc.h"
#include "net.h"

View File

@ -24,7 +24,7 @@
#include "sysbus.h"
#include "hw.h"
#include "pc.h"
#include "serial.h"
#include "net.h"
#include "flash.h"
#include "sysemu.h"

View File

@ -31,7 +31,8 @@
#include "elf.h"
#include "memory.h"
#include "exec-memory.h"
#include "pc.h"
#include "serial.h"
#include "net.h"
#include "sysbus.h"
#include "flash.h"
#include "blockdev.h"