summaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
Diffstat (limited to 'hw')
-rw-r--r--hw/arm/fsl-imx25.c2
-rw-r--r--hw/arm/fsl-imx31.c2
-rw-r--r--hw/arm/fsl-imx6.c2
-rw-r--r--hw/arm/nseries.c2
-rw-r--r--hw/arm/omap2.c2
-rw-r--r--hw/arm/pxa2xx.c2
-rw-r--r--hw/arm/virt.c2
-rw-r--r--hw/bt/hci-csr.c64
-rw-r--r--hw/char/escc.c2
-rw-r--r--hw/char/exynos4210_uart.c2
-rw-r--r--hw/char/imx_serial.c2
-rw-r--r--hw/char/mcf_uart.c4
-rw-r--r--hw/char/omap_uart.c6
-rw-r--r--hw/char/parallel.c2
-rw-r--r--hw/char/serial-isa.c2
-rw-r--r--hw/char/serial.c4
-rw-r--r--hw/char/sh_serial.c2
-rw-r--r--hw/char/spapr_vty.c2
-rw-r--r--hw/char/virtio-console.c2
-rw-r--r--hw/core/qdev-properties-system.c4
-rw-r--r--hw/cpu/core.c8
-rw-r--r--hw/display/milkymist-tmu2.c2
-rw-r--r--hw/display/sm501.c2
-rw-r--r--hw/i386/kvmvapic.c6
-rw-r--r--hw/intc/apic_common.c33
-rw-r--r--hw/isa/isa-bus.c2
-rw-r--r--hw/isa/lpc_ich9.c91
-rw-r--r--hw/isa/pc87312.c2
-rw-r--r--hw/lm32/lm32.h4
-rw-r--r--hw/lm32/milkymist-hw.h2
-rw-r--r--hw/mips/mips_malta.c4
-rw-r--r--hw/misc/ivshmem.c2
-rw-r--r--hw/misc/milkymist-pfpu.c2
-rw-r--r--hw/scsi/scsi-generic.c5
-rw-r--r--hw/timer/mc146818rtc.c15
-rw-r--r--hw/usb/ccid-card-passthru.c2
-rw-r--r--hw/usb/dev-serial.c6
-rw-r--r--hw/usb/redirect.c4
38 files changed, 240 insertions, 64 deletions
diff --git a/hw/arm/fsl-imx25.c b/hw/arm/fsl-imx25.c
index 7bb7be76b6..2126f73ca0 100644
--- a/hw/arm/fsl-imx25.c
+++ b/hw/arm/fsl-imx25.c
@@ -118,7 +118,7 @@ static void fsl_imx25_realize(DeviceState *dev, Error **errp)
};
if (i < MAX_SERIAL_PORTS) {
- CharDriverState *chr;
+ Chardev *chr;
chr = serial_hds[i];
diff --git a/hw/arm/fsl-imx31.c b/hw/arm/fsl-imx31.c
index f23672b222..dd1c713ae3 100644
--- a/hw/arm/fsl-imx31.c
+++ b/hw/arm/fsl-imx31.c
@@ -107,7 +107,7 @@ static void fsl_imx31_realize(DeviceState *dev, Error **errp)
};
if (i < MAX_SERIAL_PORTS) {
- CharDriverState *chr;
+ Chardev *chr;
chr = serial_hds[i];
diff --git a/hw/arm/fsl-imx6.c b/hw/arm/fsl-imx6.c
index e93532fb57..76dd8a48ca 100644
--- a/hw/arm/fsl-imx6.c
+++ b/hw/arm/fsl-imx6.c
@@ -187,7 +187,7 @@ static void fsl_imx6_realize(DeviceState *dev, Error **errp)
};
if (i < MAX_SERIAL_PORTS) {
- CharDriverState *chr;
+ Chardev *chr;
chr = serial_hds[i];
diff --git a/hw/arm/nseries.c b/hw/arm/nseries.c
index c86cf80514..503a3b6d24 100644
--- a/hw/arm/nseries.c
+++ b/hw/arm/nseries.c
@@ -786,7 +786,7 @@ static void n8x0_cbus_setup(struct n800_s *s)
static void n8x0_uart_setup(struct n800_s *s)
{
- CharDriverState *radio = uart_hci_init();
+ Chardev *radio = uart_hci_init();
qdev_connect_gpio_out(s->mpu->gpio, N8X0_BT_RESET_GPIO,
csrhci_pins_get(radio)[csrhci_pin_reset]);
diff --git a/hw/arm/omap2.c b/hw/arm/omap2.c
index 6f05c98d3e..cf1b4ba58f 100644
--- a/hw/arm/omap2.c
+++ b/hw/arm/omap2.c
@@ -792,7 +792,7 @@ static const MemoryRegionOps omap_sti_fifo_ops = {
static struct omap_sti_s *omap_sti_init(struct omap_target_agent_s *ta,
MemoryRegion *sysmem,
hwaddr channel_base, qemu_irq irq, omap_clk clk,
- CharDriverState *chr)
+ Chardev *chr)
{
struct omap_sti_s *s = g_new0(struct omap_sti_s, 1);
diff --git a/hw/arm/pxa2xx.c b/hw/arm/pxa2xx.c
index d31b4577f0..cfee3929d9 100644
--- a/hw/arm/pxa2xx.c
+++ b/hw/arm/pxa2xx.c
@@ -2024,7 +2024,7 @@ static PXA2xxFIrState *pxa2xx_fir_init(MemoryRegion *sysmem,
hwaddr base,
qemu_irq irq, qemu_irq rx_dma,
qemu_irq tx_dma,
- CharDriverState *chr)
+ Chardev *chr)
{
DeviceState *dev;
SysBusDevice *sbd;
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 6c9e8985bf..1f216cf3b1 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -613,7 +613,7 @@ static void create_gic(VirtMachineState *vms, qemu_irq *pic)
}
static void create_uart(const VirtMachineState *vms, qemu_irq *pic, int uart,
- MemoryRegion *mem, CharDriverState *chr)
+ MemoryRegion *mem, Chardev *chr)
{
char *nodename;
hwaddr base = vms->memmap[uart].base;
diff --git a/hw/bt/hci-csr.c b/hw/bt/hci-csr.c
index fbb3109cc1..3c193848fc 100644
--- a/hw/bt/hci-csr.c
+++ b/hw/bt/hci-csr.c
@@ -26,13 +26,14 @@
#include "hw/irq.h"
#include "sysemu/bt.h"
#include "hw/bt.h"
+#include "qapi/error.h"
struct csrhci_s {
+ Chardev parent;
int enable;
qemu_irq *pins;
int pin_state;
int modem_state;
- CharDriverState chr;
#define FIFO_LEN 4096
int out_start;
int out_len;
@@ -54,6 +55,9 @@ struct csrhci_s {
struct HCIInfo *hci;
};
+#define TYPE_CHARDEV_HCI "chardev-hci"
+#define HCI_CHARDEV(obj) OBJECT_CHECK(struct csrhci_s, (obj), TYPE_CHARDEV_HCI)
+
/* H4+ packet types */
enum {
H4_CMD_PKT = 1,
@@ -78,7 +82,8 @@ enum {
static inline void csrhci_fifo_wake(struct csrhci_s *s)
{
- CharBackend *be = s->chr.be;
+ Chardev *chr = (Chardev *)s;
+ CharBackend *be = chr->be;
if (!s->enable || !s->out_len)
return;
@@ -311,10 +316,10 @@ static void csrhci_ready_for_next_inpkt(struct csrhci_s *s)
s->in_hdr = INT_MAX;
}
-static int csrhci_write(struct CharDriverState *chr,
+static int csrhci_write(struct Chardev *chr,
const uint8_t *buf, int len)
{
- struct csrhci_s *s = (struct csrhci_s *) chr->opaque;
+ struct csrhci_s *s = (struct csrhci_s *)chr;
int total = 0;
if (!s->enable)
@@ -384,10 +389,10 @@ static void csrhci_out_hci_packet_acl(void *opaque,
csrhci_fifo_wake(s);
}
-static int csrhci_ioctl(struct CharDriverState *chr, int cmd, void *arg)
+static int csrhci_ioctl(struct Chardev *chr, int cmd, void *arg)
{
QEMUSerialSetParams *ssp;
- struct csrhci_s *s = (struct csrhci_s *) chr->opaque;
+ struct csrhci_s *s = (struct csrhci_s *) chr;
int prev_state = s->modem_state;
switch (cmd) {
@@ -453,21 +458,19 @@ static void csrhci_pins(void *opaque, int line, int level)
}
}
-qemu_irq *csrhci_pins_get(CharDriverState *chr)
+qemu_irq *csrhci_pins_get(Chardev *chr)
{
- struct csrhci_s *s = (struct csrhci_s *) chr->opaque;
+ struct csrhci_s *s = (struct csrhci_s *) chr;
return s->pins;
}
-CharDriverState *uart_hci_init(void)
+static void csrhci_open(Chardev *chr,
+ ChardevBackend *backend,
+ bool *be_opened,
+ Error **errp)
{
- struct csrhci_s *s = (struct csrhci_s *)
- g_malloc0(sizeof(struct csrhci_s));
-
- s->chr.opaque = s;
- s->chr.chr_write = csrhci_write;
- s->chr.chr_ioctl = csrhci_ioctl;
+ struct csrhci_s *s = HCI_CHARDEV(chr);
s->hci = qemu_next_hci();
s->hci->opaque = s;
@@ -477,6 +480,35 @@ CharDriverState *uart_hci_init(void)
s->out_tm = timer_new_ns(QEMU_CLOCK_VIRTUAL, csrhci_out_tick, s);
s->pins = qemu_allocate_irqs(csrhci_pins, s, __csrhci_pins);
csrhci_reset(s);
+ *be_opened = false;
+}
+
+static void char_hci_class_init(ObjectClass *oc, void *data)
+{
+ ChardevClass *cc = CHARDEV_CLASS(oc);
+
+ cc->internal = true;
+ cc->open = csrhci_open;
+ cc->chr_write = csrhci_write;
+ cc->chr_ioctl = csrhci_ioctl;
+}
- return &s->chr;
+static const TypeInfo char_hci_type_info = {
+ .name = TYPE_CHARDEV_HCI,
+ .parent = TYPE_CHARDEV,
+ .instance_size = sizeof(struct csrhci_s),
+ .class_init = char_hci_class_init,
+};
+
+Chardev *uart_hci_init(void)
+{
+ return qemu_chardev_new(NULL, TYPE_CHARDEV_HCI,
+ NULL, &error_abort);
}
+
+static void register_types(void)
+{
+ type_register_static(&char_hci_type_info);
+}
+
+type_init(register_types);
diff --git a/hw/char/escc.c b/hw/char/escc.c
index d6662dc77d..9228091cec 100644
--- a/hw/char/escc.c
+++ b/hw/char/escc.c
@@ -689,7 +689,7 @@ static const VMStateDescription vmstate_escc = {
};
MemoryRegion *escc_init(hwaddr base, qemu_irq irqA, qemu_irq irqB,
- CharDriverState *chrA, CharDriverState *chrB,
+ Chardev *chrA, Chardev *chrB,
int clock, int it_shift)
{
DeviceState *dev;
diff --git a/hw/char/exynos4210_uart.c b/hw/char/exynos4210_uart.c
index 0cd3dd3958..7c16e894e2 100644
--- a/hw/char/exynos4210_uart.c
+++ b/hw/char/exynos4210_uart.c
@@ -582,7 +582,7 @@ static const VMStateDescription vmstate_exynos4210_uart = {
DeviceState *exynos4210_uart_create(hwaddr addr,
int fifo_size,
int channel,
- CharDriverState *chr,
+ Chardev *chr,
qemu_irq irq)
{
DeviceState *dev;
diff --git a/hw/char/imx_serial.c b/hw/char/imx_serial.c
index 99545fc359..52e67f8dc9 100644
--- a/hw/char/imx_serial.c
+++ b/hw/char/imx_serial.c
@@ -170,7 +170,7 @@ static void imx_serial_write(void *opaque, hwaddr offset,
uint64_t value, unsigned size)
{
IMXSerialState *s = (IMXSerialState *)opaque;
- CharDriverState *chr = qemu_chr_fe_get_driver(&s->chr);
+ Chardev *chr = qemu_chr_fe_get_driver(&s->chr);
unsigned char ch;
DPRINTF("write(offset=0x%" HWADDR_PRIx ", value = 0x%x) to %s\n",
diff --git a/hw/char/mcf_uart.c b/hw/char/mcf_uart.c
index ecaa091190..80c380e077 100644
--- a/hw/char/mcf_uart.c
+++ b/hw/char/mcf_uart.c
@@ -275,7 +275,7 @@ static void mcf_uart_receive(void *opaque, const uint8_t *buf, int size)
mcf_uart_push_byte(s, buf[0]);
}
-void *mcf_uart_init(qemu_irq irq, CharDriverState *chr)
+void *mcf_uart_init(qemu_irq irq, Chardev *chr)
{
mcf_uart_state *s;
@@ -300,7 +300,7 @@ static const MemoryRegionOps mcf_uart_ops = {
void mcf_uart_mm_init(MemoryRegion *sysmem,
hwaddr base,
qemu_irq irq,
- CharDriverState *chr)
+ Chardev *chr)
{
mcf_uart_state *s;
diff --git a/hw/char/omap_uart.c b/hw/char/omap_uart.c
index 893ab108bc..31ebb1592c 100644
--- a/hw/char/omap_uart.c
+++ b/hw/char/omap_uart.c
@@ -54,7 +54,7 @@ void omap_uart_reset(struct omap_uart_s *s)
struct omap_uart_s *omap_uart_init(hwaddr base,
qemu_irq irq, omap_clk fclk, omap_clk iclk,
qemu_irq txdma, qemu_irq rxdma,
- const char *label, CharDriverState *chr)
+ const char *label, Chardev *chr)
{
struct omap_uart_s *s = g_new0(struct omap_uart_s, 1);
@@ -163,7 +163,7 @@ struct omap_uart_s *omap2_uart_init(MemoryRegion *sysmem,
struct omap_target_agent_s *ta,
qemu_irq irq, omap_clk fclk, omap_clk iclk,
qemu_irq txdma, qemu_irq rxdma,
- const char *label, CharDriverState *chr)
+ const char *label, Chardev *chr)
{
hwaddr base = omap_l4_attach(ta, 0, NULL);
struct omap_uart_s *s = omap_uart_init(base, irq,
@@ -178,7 +178,7 @@ struct omap_uart_s *omap2_uart_init(MemoryRegion *sysmem,
return s;
}
-void omap_uart_attach(struct omap_uart_s *s, CharDriverState *chr)
+void omap_uart_attach(struct omap_uart_s *s, Chardev *chr)
{
/* TODO: Should reuse or destroy current s->serial */
s->serial = serial_mm_init(get_system_memory(), s->base, 2, s->irq,
diff --git a/hw/char/parallel.c b/hw/char/parallel.c
index f2d56666b7..c71a4a0f4f 100644
--- a/hw/char/parallel.c
+++ b/hw/char/parallel.c
@@ -603,7 +603,7 @@ static const MemoryRegionOps parallel_mm_ops = {
/* If fd is zero, it means that the parallel device uses the console */
bool parallel_mm_init(MemoryRegion *address_space,
hwaddr base, int it_shift, qemu_irq irq,
- CharDriverState *chr)
+ Chardev *chr)
{
ParallelState *s;
diff --git a/hw/char/serial-isa.c b/hw/char/serial-isa.c
index 54d3a12f51..d7c5cc11fe 100644
--- a/hw/char/serial-isa.c
+++ b/hw/char/serial-isa.c
@@ -121,7 +121,7 @@ static void serial_register_types(void)
type_init(serial_register_types)
-static void serial_isa_init(ISABus *bus, int index, CharDriverState *chr)
+static void serial_isa_init(ISABus *bus, int index, Chardev *chr)
{
DeviceState *dev;
ISADevice *isadev;
diff --git a/hw/char/serial.c b/hw/char/serial.c
index 67b18eda12..03d890ca24 100644
--- a/hw/char/serial.c
+++ b/hw/char/serial.c
@@ -937,7 +937,7 @@ const MemoryRegionOps serial_io_ops = {
};
SerialState *serial_init(int base, qemu_irq irq, int baudbase,
- CharDriverState *chr, MemoryRegion *system_io)
+ Chardev *chr, MemoryRegion *system_io)
{
SerialState *s;
@@ -993,7 +993,7 @@ static const MemoryRegionOps serial_mm_ops[3] = {
SerialState *serial_mm_init(MemoryRegion *address_space,
hwaddr base, int it_shift,
qemu_irq irq, int baudbase,
- CharDriverState *chr, enum device_endian end)
+ Chardev *chr, enum device_endian end)
{
SerialState *s;
diff --git a/hw/char/sh_serial.c b/hw/char/sh_serial.c
index 9d35564bcf..303eb0a678 100644
--- a/hw/char/sh_serial.c
+++ b/hw/char/sh_serial.c
@@ -356,7 +356,7 @@ static const MemoryRegionOps sh_serial_ops = {
void sh_serial_init(MemoryRegion *sysmem,
hwaddr base, int feat,
- uint32_t freq, CharDriverState *chr,
+ uint32_t freq, Chardev *chr,
qemu_irq eri_source,
qemu_irq rxi_source,
qemu_irq txi_source,
diff --git a/hw/char/spapr_vty.c b/hw/char/spapr_vty.c
index 7c22b8bd0e..e30c8da57c 100644
--- a/hw/char/spapr_vty.c
+++ b/hw/char/spapr_vty.c
@@ -141,7 +141,7 @@ static target_ulong h_get_term_char(PowerPCCPU *cpu, sPAPRMachineState *spapr,
return H_SUCCESS;
}
-void spapr_vty_create(VIOsPAPRBus *bus, CharDriverState *chardev)
+void spapr_vty_create(VIOsPAPRBus *bus, Chardev *chardev)
{
DeviceState *dev;
diff --git a/hw/char/virtio-console.c b/hw/char/virtio-console.c
index 776205b4a9..798d9b69fd 100644
--- a/hw/char/virtio-console.c
+++ b/hw/char/virtio-console.c
@@ -168,7 +168,7 @@ static void virtconsole_realize(DeviceState *dev, Error **errp)
VirtIOSerialPort *port = VIRTIO_SERIAL_PORT(dev);
VirtConsole *vcon = VIRTIO_CONSOLE(dev);
VirtIOSerialPortClass *k = VIRTIO_SERIAL_PORT_GET_CLASS(dev);
- CharDriverState *chr = qemu_chr_fe_get_driver(&vcon->chr);
+ Chardev *chr = qemu_chr_fe_get_driver(&vcon->chr);
if (port->id == 0 && !k->is_console) {
error_setg(errp, "Port number 0 on virtio-serial devices reserved "
diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c
index 1b7ea50e9f..94f4d8bde4 100644
--- a/hw/core/qdev-properties-system.c
+++ b/hw/core/qdev-properties-system.c
@@ -179,7 +179,7 @@ static void set_chr(Object *obj, Visitor *v, const char *name, void *opaque,
Error *local_err = NULL;
Property *prop = opaque;
CharBackend *be = qdev_get_prop_ptr(dev, prop);
- CharDriverState *s;
+ Chardev *s;
char *str;
if (dev->realized) {
@@ -411,7 +411,7 @@ void qdev_prop_set_drive(DeviceState *dev, const char *name,
}
void qdev_prop_set_chr(DeviceState *dev, const char *name,
- CharDriverState *value)
+ Chardev *value)
{
assert(!value || value->label);
object_property_set_str(OBJECT(dev),
diff --git a/hw/cpu/core.c b/hw/cpu/core.c
index eff90c12be..2bf960d6a8 100644
--- a/hw/cpu/core.c
+++ b/hw/cpu/core.c
@@ -72,10 +72,18 @@ static void cpu_core_instance_init(Object *obj)
core->nr_threads = smp_threads;
}
+static void cpu_core_class_init(ObjectClass *oc, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(oc);
+
+ set_bit(DEVICE_CATEGORY_CPU, dc->categories);
+}
+
static const TypeInfo cpu_core_type_info = {
.name = TYPE_CPU_CORE,
.parent = TYPE_DEVICE,
.abstract = true,
+ .class_init = cpu_core_class_init,
.instance_size = sizeof(CPUCore),
.instance_init = cpu_core_instance_init,
};
diff --git a/hw/display/milkymist-tmu2.c b/hw/display/milkymist-tmu2.c
index 920374b985..7528665510 100644
--- a/hw/display/milkymist-tmu2.c
+++ b/hw/display/milkymist-tmu2.c
@@ -85,7 +85,7 @@ struct MilkymistTMU2State {
SysBusDevice parent_obj;
MemoryRegion regs_region;
- CharDriverState *chr;
+ Chardev *chr;
qemu_irq irq;
uint32_t regs[R_MAX];
diff --git a/hw/display/sm501.c b/hw/display/sm501.c
index 5f71012108..040a0b93f2 100644
--- a/hw/display/sm501.c
+++ b/hw/display/sm501.c
@@ -1392,7 +1392,7 @@ static const GraphicHwOps sm501_ops = {
};
void sm501_init(MemoryRegion *address_space_mem, uint32_t base,
- uint32_t local_mem_bytes, qemu_irq irq, CharDriverState *chr)
+ uint32_t local_mem_bytes, qemu_irq irq, Chardev *chr)
{
SM501State * s;
DeviceState *dev;
diff --git a/hw/i386/kvmvapic.c b/hw/i386/kvmvapic.c
index 702e281dc8..7135633863 100644
--- a/hw/i386/kvmvapic.c
+++ b/hw/i386/kvmvapic.c
@@ -413,6 +413,12 @@ static void patch_instruction(VAPICROMState *s, X86CPU *cpu, target_ulong ip)
if (!kvm_enabled()) {
cpu_get_tb_cpu_state(env, &current_pc, &current_cs_base,
&current_flags);
+ /* Account this instruction, because we will exit the tb.
+ This is the first instruction in the block. Therefore
+ there is no need in restoring CPU state. */
+ if (use_icount) {
+ --cs->icount_decr.u16.low;
+ }
}
pause_all_vcpus();
diff --git a/hw/intc/apic_common.c b/hw/intc/apic_common.c
index 3945dfd7b9..17df24c9d0 100644
--- a/hw/intc/apic_common.c
+++ b/hw/intc/apic_common.c
@@ -385,6 +385,25 @@ static bool apic_common_sipi_needed(void *opaque)
return s->wait_for_sipi != 0;
}
+static bool apic_irq_delivered_needed(void *opaque)
+{
+ APICCommonState *s = APIC_COMMON(opaque);
+ return s->cpu == X86_CPU(first_cpu) && apic_irq_delivered != 0;
+}
+
+static void apic_irq_delivered_pre_save(void *opaque)
+{
+ APICCommonState *s = APIC_COMMON(opaque);
+ s->apic_irq_delivered = apic_irq_delivered;
+}
+
+static int apic_irq_delivered_post_load(void *opaque, int version_id)
+{
+ APICCommonState *s = APIC_COMMON(opaque);
+ apic_irq_delivered = s->apic_irq_delivered;
+ return 0;
+}
+
static const VMStateDescription vmstate_apic_common_sipi = {
.name = "apic_sipi",
.version_id = 1,
@@ -397,6 +416,19 @@ static const VMStateDescription vmstate_apic_common_sipi = {
}
};
+static const VMStateDescription vmstate_apic_irq_delivered = {
+ .name = "apic_irq_delivered",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .needed = apic_irq_delivered_needed,
+ .pre_save = apic_irq_delivered_pre_save,
+ .post_load = apic_irq_delivered_post_load,
+ .fields = (VMStateField[]) {
+ VMSTATE_INT32(apic_irq_delivered, APICCommonState),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
static const VMStateDescription vmstate_apic_common = {
.name = "apic",
.version_id = 3,
@@ -431,6 +463,7 @@ static const VMStateDescription vmstate_apic_common = {
},
.subsections = (const VMStateDescription*[]) {
&vmstate_apic_common_sipi,
+ &vmstate_apic_irq_delivered,
NULL
}
};
diff --git a/hw/isa/isa-bus.c b/hw/isa/isa-bus.c
index 0ffbc8dd28..348e0eab9d 100644
--- a/hw/isa/isa-bus.c
+++ b/hw/isa/isa-bus.c
@@ -288,7 +288,7 @@ MemoryRegion *isa_address_space_io(ISADevice *dev)
type_init(isabus_register_types)
-static void parallel_init(ISABus *bus, int index, CharDriverState *chr)
+static void parallel_init(ISABus *bus, int index, Chardev *chr)
{
DeviceState *dev;
ISADevice *isadev;
diff --git a/hw/isa/lpc_ich9.c b/hw/isa/lpc_ich9.c
index 10d1ee8b93..59930dd9d0 100644
--- a/hw/isa/lpc_ich9.c
+++ b/hw/isa/lpc_ich9.c
@@ -48,6 +48,8 @@
#include "exec/address-spaces.h"
#include "sysemu/sysemu.h"
#include "qom/cpu.h"
+#include "hw/nvram/fw_cfg.h"
+#include "qemu/cutils.h"
/*****************************************************************************/
/* ICH9 LPC PCI to ISA bridge */
@@ -360,13 +362,62 @@ static void ich9_set_sci(void *opaque, int irq_num, int level)
}
}
+static void smi_features_ok_callback(void *opaque)
+{
+ ICH9LPCState *lpc = opaque;
+ uint64_t guest_features;
+
+ if (lpc->smi_features_ok) {
+ /* negotiation already complete, features locked */
+ return;
+ }
+
+ memcpy(&guest_features, lpc->smi_guest_features_le, sizeof guest_features);
+ le64_to_cpus(&guest_features);
+ if (guest_features & ~lpc->smi_host_features) {
+ /* guest requests invalid features, leave @features_ok at zero */
+ return;
+ }
+
+ /* valid feature subset requested, lock it down, report success */
+ lpc->smi_negotiated_features = guest_features;
+ lpc->smi_features_ok = 1;
+}
+
void ich9_lpc_pm_init(PCIDevice *lpc_pci, bool smm_enabled)
{
ICH9LPCState *lpc = ICH9_LPC_DEVICE(lpc_pci);
qemu_irq sci_irq;
+ FWCfgState *fw_cfg = fw_cfg_find();
sci_irq = qemu_allocate_irq(ich9_set_sci, lpc, 0);
ich9_pm_init(lpc_pci, &lpc->pm, smm_enabled, sci_irq);
+
+ if (lpc->smi_host_features && fw_cfg) {
+ uint64_t host_features_le;
+
+ host_features_le = cpu_to_le64(lpc->smi_host_features);
+ memcpy(lpc->smi_host_features_le, &host_features_le,
+ sizeof host_features_le);
+ fw_cfg_add_file(fw_cfg, "etc/smi/supported-features",
+ lpc->smi_host_features_le,
+ sizeof lpc->smi_host_features_le);
+
+ /* The other two guest-visible fields are cleared on device reset, we
+ * just link them into fw_cfg here.
+ */
+ fw_cfg_add_file_callback(fw_cfg, "etc/smi/requested-features",
+ NULL, NULL,
+ lpc->smi_guest_features_le,
+ sizeof lpc->smi_guest_features_le,
+ false);
+ fw_cfg_add_file_callback(fw_cfg, "etc/smi/features-ok",
+ smi_features_ok_callback, lpc,
+ &lpc->smi_features_ok,
+ sizeof lpc->smi_features_ok,
+ true);
+ }
+
ich9_lpc_reset(&lpc->d.qdev);
}
@@ -386,7 +437,15 @@ static void ich9_apm_ctrl_changed(uint32_t val, void *arg)
/* SMI_EN = PMBASE + 30. SMI control and enable register */
if (lpc->pm.smi_en & ICH9_PMIO_SMI_EN_APMC_EN) {
- cpu_interrupt(current_cpu, CPU_INTERRUPT_SMI);
+ if (lpc->smi_negotiated_features &
+ (UINT64_C(1) << ICH9_LPC_SMI_F_BROADCAST_BIT)) {
+ CPUState *cs;
+ CPU_FOREACH(cs) {
+ cpu_interrupt(cs, CPU_INTERRUPT_SMI);
+ }
+ } else {
+ cpu_interrupt(current_cpu, CPU_INTERRUPT_SMI);
+ }
}
}
@@ -507,6 +566,10 @@ static void ich9_lpc_reset(DeviceState *qdev)
lpc->sci_level = 0;
lpc->rst_cnt = 0;
+
+ memset(lpc->smi_guest_features_le, 0, sizeof lpc->smi_guest_features_le);
+ lpc->smi_features_ok = 0;
+ lpc->smi_negotiated_features = 0;
}
/* root complex register block is mapped into memory space */
@@ -668,6 +731,29 @@ static const VMStateDescription vmstate_ich9_rst_cnt = {
}
};
+static bool ich9_smi_feat_needed(void *opaque)
+{
+ ICH9LPCState *lpc = opaque;
+
+ return !buffer_is_zero(lpc->smi_guest_features_le,
+ sizeof lpc->smi_guest_features_le) ||
+ lpc->smi_features_ok;
+}
+
+static const VMStateDescription vmstate_ich9_smi_feat = {
+ .name = "ICH9LPC/smi_feat",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .needed = ich9_smi_feat_needed,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT8_ARRAY(smi_guest_features_le, ICH9LPCState,
+ sizeof(uint64_t)),
+ VMSTATE_UINT8(smi_features_ok, ICH9LPCState),
+ VMSTATE_UINT64(smi_negotiated_features, ICH9LPCState),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
static const VMStateDescription vmstate_ich9_lpc = {
.name = "ICH9LPC",
.version_id = 1,
@@ -683,12 +769,15 @@ static const VMStateDescription vmstate_ich9_lpc = {
},
.subsections = (const VMStateDescription*[]) {
&vmstate_ich9_rst_cnt,
+ &vmstate_ich9_smi_feat,
NULL
}
};
static Property ich9_lpc_properties[] = {
DEFINE_PROP_BOOL("noreboot", ICH9LPCState, pin_strap.spkr_hi, true),
+ DEFINE_PROP_BIT64("x-smi-broadcast", ICH9LPCState, smi_host_features,
+ ICH9_LPC_SMI_F_BROADCAST_BIT, true),
DEFINE_PROP_END_OF_LIST(),
};
diff --git a/hw/isa/pc87312.c b/hw/isa/pc87312.c
index b1c1a0acb1..c707d24db4 100644
--- a/hw/isa/pc87312.c
+++ b/hw/isa/pc87312.c
@@ -268,7 +268,7 @@ static void pc87312_realize(DeviceState *dev, Error **errp)
DeviceState *d;
ISADevice *isa;
ISABus *bus;
- CharDriverState *chr;
+ Chardev *chr;
DriveInfo *drive;
char name[5];
int i;
diff --git a/hw/lm32/lm32.h b/hw/lm32/lm32.h
index db9eb29ea4..d1514a61b3 100644
--- a/hw/lm32/lm32.h
+++ b/hw/lm32/lm32.h
@@ -16,7 +16,7 @@ static inline DeviceState *lm32_pic_init(qemu_irq cpu_irq)
return dev;
}
-static inline DeviceState *lm32_juart_init(CharDriverState *chr)
+static inline DeviceState *lm32_juart_init(Chardev *chr)
{
DeviceState *dev;
@@ -29,7 +29,7 @@ static inline DeviceState *lm32_juart_init(CharDriverState *chr)
static inline DeviceState *lm32_uart_create(hwaddr addr,
qemu_irq irq,
- CharDriverState *chr)
+ Chardev *chr)
{
DeviceState *dev;
SysBusDevice *s;
diff --git a/hw/lm32/milkymist-hw.h b/hw/lm32/milkymist-hw.h
index 4418b44ca9..d3be0cfb3a 100644
--- a/hw/lm32/milkymist-hw.h
+++ b/hw/lm32/milkymist-hw.h
@@ -6,7 +6,7 @@
static inline DeviceState *milkymist_uart_create(hwaddr base,
qemu_irq irq,
- CharDriverState *chr)
+ Chardev *chr)
{
DeviceState *dev;
diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c
index cf48f420cc..75877de11c 100644
--- a/hw/mips/mips_malta.c
+++ b/hw/mips/mips_malta.c
@@ -551,10 +551,10 @@ static void malta_fgpa_display_event(void *opaque, int event)
}
static MaltaFPGAState *malta_fpga_init(MemoryRegion *address_space,
- hwaddr base, qemu_irq uart_irq, CharDriverState *uart_chr)
+ hwaddr base, qemu_irq uart_irq, Chardev *uart_chr)
{
MaltaFPGAState *s;
- CharDriverState *chr;
+ Chardev *chr;
s = (MaltaFPGAState *)g_malloc0(sizeof(MaltaFPGAState));
diff --git a/hw/misc/ivshmem.c b/hw/misc/ivshmem.c
index fd14d7a07e..846e903eb2 100644
--- a/hw/misc/ivshmem.c
+++ b/hw/misc/ivshmem.c
@@ -869,7 +869,7 @@ static void ivshmem_common_realize(PCIDevice *dev, Error **errp)
s->ivshmem_bar2 = host_memory_backend_get_memory(s->hostmem,
&error_abort);
} else {
- CharDriverState *chr = qemu_chr_fe_get_driver(&s->server_chr);
+ Chardev *chr = qemu_chr_fe_get_driver(&s->server_chr);
assert(chr);
IVSHMEM_DPRINTF("using shared memory server (socket = %s)\n",
diff --git a/hw/misc/milkymist-pfpu.c b/hw/misc/milkymist-pfpu.c
index 3ca25894f1..86f5e383b0 100644
--- a/hw/misc/milkymist-pfpu.c
+++ b/hw/misc/milkymist-pfpu.c
@@ -125,7 +125,7 @@ struct MilkymistPFPUState {
SysBusDevice parent_obj;
MemoryRegion regs_region;
- CharDriverState *chr;
+ Chardev *chr;
qemu_irq irq;
uint32_t regs[R_MAX];
diff --git a/hw/scsi/scsi-generic.c b/hw/scsi/scsi-generic.c
index 7a588a7ad4..92f091a613 100644
--- a/hw/scsi/scsi-generic.c
+++ b/hw/scsi/scsi-generic.c
@@ -246,7 +246,7 @@ static void scsi_read_data(SCSIRequest *req)
SCSIDevice *s = r->req.dev;
int ret;
- DPRINTF("scsi_read_data 0x%x\n", req->tag);
+ DPRINTF("scsi_read_data tag=0x%x\n", req->tag);
/* The request is used as the AIO opaque value, so add a ref. */
scsi_req_ref(&r->req);
@@ -294,7 +294,7 @@ static void scsi_write_data(SCSIRequest *req)
SCSIDevice *s = r->req.dev;
int ret;
- DPRINTF("scsi_write_data 0x%x\n", req->tag);
+ DPRINTF("scsi_write_data tag=0x%x\n", req->tag);
if (r->len == 0) {
r->len = r->buflen;
scsi_req_data(&r->req, r->len);
@@ -329,6 +329,7 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t *cmd)
int ret;
#ifdef DEBUG_SCSI
+ DPRINTF("Command: data=0x%02x", cmd[0]);
{
int i;
for (i = 1; i < r->req.cmd.len; i++) {
diff --git a/hw/timer/mc146818rtc.c b/hw/timer/mc146818rtc.c
index 637f8722a7..4165450250 100644
--- a/hw/timer/mc146818rtc.c
+++ b/hw/timer/mc146818rtc.c
@@ -27,6 +27,7 @@
#include "hw/hw.h"
#include "qemu/timer.h"
#include "sysemu/sysemu.h"
+#include "sysemu/replay.h"
#include "hw/timer/mc146818rtc.h"
#include "qapi/visitor.h"
#include "qapi-event.h"
@@ -734,10 +735,16 @@ static int rtc_post_load(void *opaque, int version_id)
check_update_timer(s);
}
- uint64_t now = qemu_clock_get_ns(rtc_clock);
- if (now < s->next_periodic_time ||
- now > (s->next_periodic_time + get_max_clock_jump())) {
- periodic_timer_update(s, qemu_clock_get_ns(rtc_clock));
+ /* The periodic timer is deterministic in record/replay mode,
+ * so there is no need to update it after loading the vmstate.
+ * Reading RTC here would misalign record and replay.
+ */
+ if (replay_mode == REPLAY_MODE_NONE) {
+ uint64_t now = qemu_clock_get_ns(rtc_clock);
+ if (now < s->next_periodic_time ||
+ now > (s->next_periodic_time + get_max_clock_jump())) {
+ periodic_timer_update(s, qemu_clock_get_ns(rtc_clock));
+ }
}
#ifdef TARGET_I386
diff --git a/hw/usb/ccid-card-passthru.c b/hw/usb/ccid-card-passthru.c
index 88cb6d8978..daab0d56cf 100644
--- a/hw/usb/ccid-card-passthru.c
+++ b/hw/usb/ccid-card-passthru.c
@@ -264,7 +264,7 @@ static void ccid_card_vscard_handle_message(PassthruState *card,
static void ccid_card_vscard_drop_connection(PassthruState *card)
{
- CharDriverState *chr = qemu_chr_fe_get_driver(&card->cs);
+ Chardev *chr = qemu_chr_fe_get_driver(&card->cs);
qemu_chr_fe_deinit(&card->cs);
qemu_chr_delete(chr);
diff --git a/hw/usb/dev-serial.c b/hw/usb/dev-serial.c
index 6066d9b0f7..6d5137383b 100644
--- a/hw/usb/dev-serial.c
+++ b/hw/usb/dev-serial.c
@@ -483,7 +483,7 @@ static void usb_serial_realize(USBDevice *dev, Error **errp)
{
USBSerialState *s = USB_SERIAL_DEV(dev);
Error *local_err = NULL;
- CharDriverState *chr = qemu_chr_fe_get_driver(&s->cs);
+ Chardev *chr = qemu_chr_fe_get_driver(&s->cs);
usb_desc_create_serial(dev);
usb_desc_init(dev);
@@ -512,7 +512,7 @@ static void usb_serial_realize(USBDevice *dev, Error **errp)
static USBDevice *usb_serial_init(USBBus *bus, const char *filename)
{
USBDevice *dev;
- CharDriverState *cdrv;
+ Chardev *cdrv;
uint32_t vendorid = 0, productid = 0;
char label[32];
static int index;
@@ -564,7 +564,7 @@ static USBDevice *usb_serial_init(USBBus *bus, const char *filename)
static USBDevice *usb_braille_init(USBBus *bus, const char *unused)
{
USBDevice *dev;
- CharDriverState *cdrv;
+ Chardev *cdrv;
cdrv = qemu_chr_new("braille", "braille");
if (!cdrv)
diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
index 4a0ebbfb32..860f5c35eb 100644
--- a/hw/usb/redirect.c
+++ b/hw/usb/redirect.c
@@ -284,7 +284,7 @@ static gboolean usbredir_write_unblocked(GIOChannel *chan, GIOCondition cond,
static int usbredir_write(void *priv, uint8_t *data, int count)
{
USBRedirDevice *dev = priv;
- CharDriverState *chr = qemu_chr_fe_get_driver(&dev->cs);
+ Chardev *chr = qemu_chr_fe_get_driver(&dev->cs);
int r;
if (!chr->be_open) {
@@ -1430,7 +1430,7 @@ static void usbredir_cleanup_device_queues(USBRedirDevice *dev)
static void usbredir_handle_destroy(USBDevice *udev)
{
USBRedirDevice *dev = USB_REDIRECT(udev);
- CharDriverState *chr = qemu_chr_fe_get_driver(&dev->cs);
+ Chardev *chr = qemu_chr_fe_get_driver(&dev->cs);
qemu_chr_fe_deinit(&dev->cs);
qemu_chr_delete(chr);