aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
Diffstat (limited to 'hw')
-rw-r--r--hw/blizzard.c4
-rw-r--r--hw/cirrus_vga.c4
-rw-r--r--hw/ds1338.c1
-rw-r--r--hw/ioapic.c2
-rw-r--r--hw/irq.c17
-rw-r--r--hw/irq.h5
-rw-r--r--hw/ivshmem.c2
-rw-r--r--hw/mc146818rtc.c33
-rw-r--r--hw/mc146818rtc.h3
-rw-r--r--hw/mc146818rtc_regs.h62
-rw-r--r--hw/milkymist-sysctl.c26
-rw-r--r--hw/milkymist-vgafb.c5
-rw-r--r--hw/omap1.c10
-rw-r--r--hw/omap_lcdc.c5
-rw-r--r--hw/pc.c2
-rw-r--r--hw/pc_piix.c21
-rw-r--r--hw/pci.c1
-rw-r--r--hw/piix_pci.c3
-rw-r--r--hw/pl031.c75
-rw-r--r--hw/ppc440_bamboo.c2
-rw-r--r--hw/ppc_prep.c2
-rw-r--r--hw/ppce500_mpc8544ds.c2
-rw-r--r--hw/ps2.c2
-rw-r--r--hw/pxa2xx.c28
-rw-r--r--hw/qdev-monitor.c16
-rw-r--r--hw/qdev.c27
-rw-r--r--hw/qdev.h2
-rw-r--r--hw/qxl-render.c13
-rw-r--r--hw/qxl.c176
-rw-r--r--hw/scsi-bus.c18
-rw-r--r--hw/scsi-disk.c49
-rw-r--r--hw/serial.c5
-rw-r--r--hw/strongarm.c10
-rw-r--r--hw/sun4m.c12
-rw-r--r--hw/sun4u.c36
-rw-r--r--hw/twl92230.c9
-rw-r--r--hw/vga.c2
-rw-r--r--hw/virtio-scsi.c2
-rw-r--r--hw/xen_console.c3
-rw-r--r--hw/xen_disk.c11
40 files changed, 418 insertions, 290 deletions
diff --git a/hw/blizzard.c b/hw/blizzard.c
index c7d844d105..29074c4fa7 100644
--- a/hw/blizzard.c
+++ b/hw/blizzard.c
@@ -937,9 +937,7 @@ static void blizzard_screen_dump(void *opaque, const char *filename,
{
BlizzardState *s = (BlizzardState *) opaque;
- if (cswitch) {
- blizzard_update_display(opaque);
- }
+ blizzard_update_display(opaque);
if (s && ds_get_data(s->state))
ppm_save(filename, s->state->surface);
}
diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c
index 4edcb94774..afedaa43d3 100644
--- a/hw/cirrus_vga.c
+++ b/hw/cirrus_vga.c
@@ -2767,10 +2767,6 @@ static void cirrus_reset(void *opaque)
}
s->vga.cr[0x27] = s->device_id;
- /* Win2K seems to assume that the pattern buffer is at 0xff
- initially ! */
- memset(s->vga.vram_ptr, 0xff, s->real_vram_size);
-
s->cirrus_hidden_dac_lockindex = 5;
s->cirrus_hidden_dac_data = 0;
}
diff --git a/hw/ds1338.c b/hw/ds1338.c
index 6397f0aa6f..d590d9c007 100644
--- a/hw/ds1338.c
+++ b/hw/ds1338.c
@@ -100,6 +100,7 @@ static int ds1338_send(I2CSlave *i2c, uint8_t data)
break;
case 5:
s->now.tm_mon = from_bcd(data & 0x1f) - 1;
+ break;
case 6:
s->now.tm_year = from_bcd(data) + 100;
break;
diff --git a/hw/ioapic.c b/hw/ioapic.c
index 3fee0114d9..e2e4796bb5 100644
--- a/hw/ioapic.c
+++ b/hw/ioapic.c
@@ -195,7 +195,7 @@ ioapic_mem_write(void *opaque, target_phys_addr_t addr, uint64_t val,
if (size != 4) {
break;
}
- DPRINTF("write: %08x = %08x\n", s->ioregsel, val);
+ DPRINTF("write: %08x = %08" PRIx64 "\n", s->ioregsel, val);
switch (s->ioregsel) {
case IOAPIC_REG_ID:
s->id = (val >> IOAPIC_ID_SHIFT) & IOAPIC_ID_MASK;
diff --git a/hw/irq.c b/hw/irq.c
index 62f766eb6f..d413a0b235 100644
--- a/hw/irq.c
+++ b/hw/irq.c
@@ -104,3 +104,20 @@ qemu_irq *qemu_irq_proxy(qemu_irq **target, int n)
{
return qemu_allocate_irqs(proxy_irq_handler, target, n);
}
+
+void qemu_irq_intercept_in(qemu_irq *gpio_in, qemu_irq_handler handler, int n)
+{
+ int i;
+ qemu_irq *old_irqs = qemu_allocate_irqs(NULL, NULL, n);
+ for (i = 0; i < n; i++) {
+ *old_irqs[i] = *gpio_in[i];
+ gpio_in[i]->handler = handler;
+ gpio_in[i]->opaque = old_irqs;
+ }
+}
+
+void qemu_irq_intercept_out(qemu_irq **gpio_out, qemu_irq_handler handler, int n)
+{
+ qemu_irq *old_irqs = *gpio_out;
+ *gpio_out = qemu_allocate_irqs(handler, old_irqs, n);
+}
diff --git a/hw/irq.h b/hw/irq.h
index 64da2fd601..56c55f0c46 100644
--- a/hw/irq.h
+++ b/hw/irq.h
@@ -38,4 +38,9 @@ qemu_irq qemu_irq_split(qemu_irq irq1, qemu_irq irq2);
*/
qemu_irq *qemu_irq_proxy(qemu_irq **target, int n);
+/* For internal use in qtest. Similar to qemu_irq_split, but operating
+ on an existing vector of qemu_irq. */
+void qemu_irq_intercept_in(qemu_irq *gpio_in, qemu_irq_handler handler, int n);
+void qemu_irq_intercept_out(qemu_irq **gpio_out, qemu_irq_handler handler, int n);
+
#endif
diff --git a/hw/ivshmem.c b/hw/ivshmem.c
index 64e1cd968e..b80aa8f1de 100644
--- a/hw/ivshmem.c
+++ b/hw/ivshmem.c
@@ -565,7 +565,7 @@ static void ivshmem_setup_msi(IVShmemState * s) {
msix_vector_use(&s->dev, i);
}
- /* allocate Qemu char devices for receiving interrupts */
+ /* allocate QEMU char devices for receiving interrupts */
s->eventfd_table = g_malloc0(s->vectors * sizeof(EventfdEntry));
}
diff --git a/hw/mc146818rtc.c b/hw/mc146818rtc.c
index 2b59c36ee6..9c64e0ae25 100644
--- a/hw/mc146818rtc.c
+++ b/hw/mc146818rtc.c
@@ -47,39 +47,6 @@
#define RTC_REINJECT_ON_ACK_COUNT 20
-#define RTC_SECONDS 0
-#define RTC_SECONDS_ALARM 1
-#define RTC_MINUTES 2
-#define RTC_MINUTES_ALARM 3
-#define RTC_HOURS 4
-#define RTC_HOURS_ALARM 5
-#define RTC_ALARM_DONT_CARE 0xC0
-
-#define RTC_DAY_OF_WEEK 6
-#define RTC_DAY_OF_MONTH 7
-#define RTC_MONTH 8
-#define RTC_YEAR 9
-
-#define RTC_REG_A 10
-#define RTC_REG_B 11
-#define RTC_REG_C 12
-#define RTC_REG_D 13
-
-#define REG_A_UIP 0x80
-
-#define REG_B_SET 0x80
-#define REG_B_PIE 0x40
-#define REG_B_AIE 0x20
-#define REG_B_UIE 0x10
-#define REG_B_SQWE 0x08
-#define REG_B_DM 0x04
-#define REG_B_24H 0x02
-
-#define REG_C_UF 0x10
-#define REG_C_IRQF 0x80
-#define REG_C_PF 0x40
-#define REG_C_AF 0x20
-
typedef struct RTCState {
ISADevice dev;
MemoryRegion io;
diff --git a/hw/mc146818rtc.h b/hw/mc146818rtc.h
index f1199300a4..f286b6a12a 100644
--- a/hw/mc146818rtc.h
+++ b/hw/mc146818rtc.h
@@ -2,8 +2,7 @@
#define MC146818RTC_H
#include "isa.h"
-
-#define RTC_ISA_IRQ 8
+#include "mc146818rtc_regs.h"
ISADevice *rtc_init(ISABus *bus, int base_year, qemu_irq intercept_irq);
void rtc_set_memory(ISADevice *dev, int addr, int val);
diff --git a/hw/mc146818rtc_regs.h b/hw/mc146818rtc_regs.h
new file mode 100644
index 0000000000..3ab37709f0
--- /dev/null
+++ b/hw/mc146818rtc_regs.h
@@ -0,0 +1,62 @@
+/*
+ * QEMU MC146818 RTC emulation
+ *
+ * Copyright (c) 2003-2004 Fabrice Bellard
+ *
+ * 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.
+ */
+#ifndef RTC_REGS_H
+#define RTC_REGS_H
+
+#define RTC_ISA_IRQ 8
+
+#define RTC_SECONDS 0
+#define RTC_SECONDS_ALARM 1
+#define RTC_MINUTES 2
+#define RTC_MINUTES_ALARM 3
+#define RTC_HOURS 4
+#define RTC_HOURS_ALARM 5
+#define RTC_ALARM_DONT_CARE 0xC0
+
+#define RTC_DAY_OF_WEEK 6
+#define RTC_DAY_OF_MONTH 7
+#define RTC_MONTH 8
+#define RTC_YEAR 9
+
+#define RTC_REG_A 10
+#define RTC_REG_B 11
+#define RTC_REG_C 12
+#define RTC_REG_D 13
+
+#define REG_A_UIP 0x80
+
+#define REG_B_SET 0x80
+#define REG_B_PIE 0x40
+#define REG_B_AIE 0x20
+#define REG_B_UIE 0x10
+#define REG_B_SQWE 0x08
+#define REG_B_DM 0x04
+#define REG_B_24H 0x02
+
+#define REG_C_UF 0x10
+#define REG_C_IRQF 0x80
+#define REG_C_PF 0x40
+#define REG_C_AF 0x20
+
+#endif
diff --git a/hw/milkymist-sysctl.c b/hw/milkymist-sysctl.c
index a88548e0aa..8878d2bd17 100644
--- a/hw/milkymist-sysctl.c
+++ b/hw/milkymist-sysctl.c
@@ -1,7 +1,7 @@
/*
* QEMU model of the Milkymist System Controller.
*
- * Copyright (c) 2010 Michael Walle <michael@walle.cc>
+ * Copyright (c) 2010-2012 Michael Walle <michael@walle.cc>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -39,20 +39,19 @@ enum {
};
enum {
- R_GPIO_IN = 0,
+ R_GPIO_IN = 0,
R_GPIO_OUT,
R_GPIO_INTEN,
- R_RESERVED0,
- R_TIMER0_CONTROL,
+ R_TIMER0_CONTROL = 4,
R_TIMER0_COMPARE,
R_TIMER0_COUNTER,
- R_RESERVED1,
- R_TIMER1_CONTROL,
+ R_TIMER1_CONTROL = 8,
R_TIMER1_COMPARE,
R_TIMER1_COUNTER,
- R_RESERVED2,
- R_RESERVED3,
- R_ICAP,
+ R_ICAP = 16,
+ R_DBG_SCRATCHPAD = 20,
+ R_DBG_WRITE_LOCK,
+ R_CLK_FREQUENCY = 29,
R_CAPABILITIES,
R_SYSTEM_ID,
R_MAX
@@ -116,6 +115,9 @@ static uint64_t sysctl_read(void *opaque, target_phys_addr_t addr,
case R_TIMER1_CONTROL:
case R_TIMER1_COMPARE:
case R_ICAP:
+ case R_DBG_SCRATCHPAD:
+ case R_DBG_WRITE_LOCK:
+ case R_CLK_FREQUENCY:
case R_CAPABILITIES:
case R_SYSTEM_ID:
r = s->regs[addr];
@@ -145,6 +147,7 @@ static void sysctl_write(void *opaque, target_phys_addr_t addr, uint64_t value,
case R_GPIO_INTEN:
case R_TIMER0_COUNTER:
case R_TIMER1_COUNTER:
+ case R_DBG_SCRATCHPAD:
s->regs[addr] = value;
break;
case R_TIMER0_COMPARE:
@@ -182,11 +185,15 @@ static void sysctl_write(void *opaque, target_phys_addr_t addr, uint64_t value,
case R_ICAP:
sysctl_icap_write(s, value);
break;
+ case R_DBG_WRITE_LOCK:
+ s->regs[addr] = 1;
+ break;
case R_SYSTEM_ID:
qemu_system_reset_request();
break;
case R_GPIO_IN:
+ case R_CLK_FREQUENCY:
case R_CAPABILITIES:
error_report("milkymist_sysctl: write to read-only register 0x"
TARGET_FMT_plx, addr << 2);
@@ -253,6 +260,7 @@ static void milkymist_sysctl_reset(DeviceState *d)
/* defaults */
s->regs[R_ICAP] = ICAP_READY;
s->regs[R_SYSTEM_ID] = s->systemid;
+ s->regs[R_CLK_FREQUENCY] = s->freq_hz;
s->regs[R_CAPABILITIES] = s->capabilities;
s->regs[R_GPIO_IN] = s->strappings;
}
diff --git a/hw/milkymist-vgafb.c b/hw/milkymist-vgafb.c
index 69afd72d8a..cd4365d64b 100644
--- a/hw/milkymist-vgafb.c
+++ b/hw/milkymist-vgafb.c
@@ -2,7 +2,7 @@
/*
* QEMU model of the Milkymist VGA framebuffer.
*
- * Copyright (c) 2010 Michael Walle <michael@walle.cc>
+ * Copyright (c) 2010-2012 Michael Walle <michael@walle.cc>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -54,6 +54,7 @@ enum {
R_BASEADDRESS,
R_BASEADDRESS_ACT,
R_BURST_COUNT,
+ R_DDC,
R_SOURCE_CLOCK,
R_MAX
};
@@ -173,6 +174,7 @@ static uint64_t vgafb_read(void *opaque, target_phys_addr_t addr,
case R_VSCAN:
case R_BASEADDRESS:
case R_BURST_COUNT:
+ case R_DDC:
case R_SOURCE_CLOCK:
r = s->regs[addr];
break;
@@ -211,6 +213,7 @@ static void vgafb_write(void *opaque, target_phys_addr_t addr, uint64_t value,
case R_VSYNC_END:
case R_VSCAN:
case R_BURST_COUNT:
+ case R_DDC:
case R_SOURCE_CLOCK:
s->regs[addr] = value;
break;
diff --git a/hw/omap1.c b/hw/omap1.c
index 2a341bfe7f..80d47f0b85 100644
--- a/hw/omap1.c
+++ b/hw/omap1.c
@@ -2888,7 +2888,7 @@ static void omap_rtc_reset(struct omap_rtc_s *s)
s->pm_am = 0;
s->auto_comp = 0;
s->round = 0;
- s->tick = qemu_get_clock_ms(rt_clock);
+ s->tick = qemu_get_clock_ms(rtc_clock);
memset(&s->alarm_tm, 0, sizeof(s->alarm_tm));
s->alarm_tm.tm_mday = 0x01;
s->status = 1 << 7;
@@ -2909,7 +2909,7 @@ static struct omap_rtc_s *omap_rtc_init(MemoryRegion *system_memory,
s->irq = timerirq;
s->alarm = alarmirq;
- s->clk = qemu_new_timer_ms(rt_clock, omap_rtc_tick, s);
+ s->clk = qemu_new_timer_ms(rtc_clock, omap_rtc_tick, s);
omap_rtc_reset(s);
@@ -3497,9 +3497,9 @@ static void omap_lpg_tick(void *opaque)
struct omap_lpg_s *s = opaque;
if (s->cycle)
- qemu_mod_timer(s->tm, qemu_get_clock_ms(rt_clock) + s->period - s->on);
+ qemu_mod_timer(s->tm, qemu_get_clock_ms(vm_clock) + s->period - s->on);
else
- qemu_mod_timer(s->tm, qemu_get_clock_ms(rt_clock) + s->on);
+ qemu_mod_timer(s->tm, qemu_get_clock_ms(vm_clock) + s->on);
s->cycle = !s->cycle;
printf("%s: LED is %s\n", __FUNCTION__, s->cycle ? "on" : "off");
@@ -3617,7 +3617,7 @@ static struct omap_lpg_s *omap_lpg_init(MemoryRegion *system_memory,
struct omap_lpg_s *s = (struct omap_lpg_s *)
g_malloc0(sizeof(struct omap_lpg_s));
- s->tm = qemu_new_timer_ms(rt_clock, omap_lpg_tick, s);
+ s->tm = qemu_new_timer_ms(vm_clock, omap_lpg_tick, s);
omap_lpg_reset(s);
diff --git a/hw/omap_lcdc.c b/hw/omap_lcdc.c
index f172093876..4a08e9d002 100644
--- a/hw/omap_lcdc.c
+++ b/hw/omap_lcdc.c
@@ -267,9 +267,8 @@ static int ppm_save(const char *filename, uint8_t *data,
static void omap_screen_dump(void *opaque, const char *filename, bool cswitch)
{
struct omap_lcd_panel_s *omap_lcd = opaque;
- if (cswitch) {
- omap_update_display(opaque);
- }
+
+ omap_update_display(opaque);
if (omap_lcd && ds_get_data(omap_lcd->state))
ppm_save(filename, ds_get_data(omap_lcd->state),
omap_lcd->width, omap_lcd->height,
diff --git a/hw/pc.c b/hw/pc.c
index 83a1b5b32b..67f0479f40 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -776,7 +776,7 @@ static void load_linux(void *fw_cfg,
}
/* loader type */
- /* High nybble = B reserved for Qemu; low nybble is revision number.
+ /* High nybble = B reserved for QEMU; low nybble is revision number.
If this code is substantially changed, you may want to consider
incrementing the revision. */
if (protocol >= 0x200)
diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index 3f99f9a7c2..fadca4c710 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -107,6 +107,9 @@ static void ioapic_init(GSIState *gsi_state)
} else {
dev = qdev_create(NULL, "ioapic");
}
+ /* FIXME: this should be under the piix3. */
+ object_property_add_child(object_resolve_path("i440fx", NULL),
+ "ioapic", OBJECT(dev), NULL);
qdev_init_nofail(dev);
d = sysbus_from_qdev(dev);
sysbus_mmio_map(d, 0, 0xfec00000);
@@ -146,7 +149,6 @@ static void pc_init1(MemoryRegion *system_memory,
MemoryRegion *ram_memory;
MemoryRegion *pci_memory;
MemoryRegion *rom_memory;
- DeviceState *dev;
pc_cpus_init(cpu_model);
@@ -224,11 +226,7 @@ static void pc_init1(MemoryRegion *system_memory,
pc_register_ferr_irq(gsi[13]);
- dev = pc_vga_init(isa_bus, pci_enabled ? pci_bus : NULL);
- if (dev) {
- object_property_add_child(object_get_root(), "vga", OBJECT(dev), NULL);
- }
-
+ pc_vga_init(isa_bus, pci_enabled ? pci_bus : NULL);
if (xen_enabled()) {
pci_create_simple(pci_bus, -1, "xen-platform");
}
@@ -255,17 +253,6 @@ static void pc_init1(MemoryRegion *system_memory,
}
idebus[0] = qdev_get_child_bus(&dev->qdev, "ide.0");
idebus[1] = qdev_get_child_bus(&dev->qdev, "ide.1");
-
- /* FIXME there's some major spaghetti here. Somehow we create the
- * devices on the PIIX before we actually create it. We create the
- * PIIX3 deep in the recess of the i440fx creation too and then lose
- * the DeviceState.
- *
- * For now, let's "fix" this by making judicious use of paths. This
- * is not generally the right way to do this.
- */
- object_property_add_child(object_resolve_path("/i440fx/piix3", NULL),
- "rtc", (Object *)rtc_state, NULL);
} else {
for(i = 0; i < MAX_IDE_BUS; i++) {
ISADevice *dev;
diff --git a/hw/pci.c b/hw/pci.c
index bf046bfcad..ed8ec99073 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -841,7 +841,6 @@ static int pci_unregister_device(DeviceState *dev)
pci_unregister_io_regions(pci_dev);
pci_del_option_rom(pci_dev);
- g_free(pci_dev->romfile);
do_pci_unregister_device(pci_dev);
return 0;
}
diff --git a/hw/piix_pci.c b/hw/piix_pci.c
index e0268fe053..179d9a6bb9 100644
--- a/hw/piix_pci.c
+++ b/hw/piix_pci.c
@@ -276,8 +276,8 @@ static PCIBus *i440fx_common_init(const char *device_name,
b = pci_bus_new(&s->busdev.qdev, NULL, pci_address_space,
address_space_io, 0);
s->bus = b;
+ object_property_add_child(qdev_get_machine(), "i440fx", OBJECT(dev), NULL);
qdev_init_nofail(dev);
- object_property_add_child(object_get_root(), "i440fx", OBJECT(dev), NULL);
d = pci_create_simple(b, 0, device_name);
*pi440fx_state = DO_UPCAST(PCII440FXState, dev, d);
@@ -316,7 +316,6 @@ static PCIBus *i440fx_common_init(const char *device_name,
pci_bus_irqs(b, piix3_set_irq, pci_slot_get_pirq, piix3,
PIIX_NUM_PIRQS);
}
- object_property_add_child(OBJECT(dev), "piix3", OBJECT(piix3), NULL);
piix3->pic = pic;
*isa_bus = DO_UPCAST(ISABus, qbus,
qdev_get_child_bus(&piix3->dev.qdev, "isa.0"));
diff --git a/hw/pl031.c b/hw/pl031.c
index 69abc4f345..9602664da6 100644
--- a/hw/pl031.c
+++ b/hw/pl031.c
@@ -13,6 +13,7 @@
#include "sysbus.h"
#include "qemu-timer.h"
+#include "sysemu.h"
//#define DEBUG_PL031
@@ -38,6 +39,11 @@ typedef struct {
QEMUTimer *timer;
qemu_irq irq;
+ /* Needed to preserve the tick_count across migration, even if the
+ * absolute value of the rtc_clock is different on the source and
+ * destination.
+ */
+ uint32_t tick_offset_vmstate;
uint32_t tick_offset;
uint32_t mr;
@@ -47,21 +53,6 @@ typedef struct {
uint32_t is;
} pl031_state;
-static const VMStateDescription vmstate_pl031 = {
- .name = "pl031",
- .version_id = 1,
- .minimum_version_id = 1,
- .fields = (VMStateField[]) {
- VMSTATE_UINT32(tick_offset, pl031_state),
- VMSTATE_UINT32(mr, pl031_state),
- VMSTATE_UINT32(lr, pl031_state),
- VMSTATE_UINT32(cr, pl031_state),
- VMSTATE_UINT32(im, pl031_state),
- VMSTATE_UINT32(is, pl031_state),
- VMSTATE_END_OF_LIST()
- }
-};
-
static const unsigned char pl031_id[] = {
0x31, 0x10, 0x14, 0x00, /* Device ID */
0x0d, 0xf0, 0x05, 0xb1 /* Cell ID */
@@ -83,27 +74,23 @@ static void pl031_interrupt(void * opaque)
static uint32_t pl031_get_count(pl031_state *s)
{
- /* This assumes qemu_get_clock_ns returns the time since the machine was
- created. */
- return s->tick_offset + qemu_get_clock_ns(vm_clock) / get_ticks_per_sec();
+ int64_t now = qemu_get_clock_ns(rtc_clock);
+ return s->tick_offset + now / get_ticks_per_sec();
}
static void pl031_set_alarm(pl031_state *s)
{
- int64_t now;
uint32_t ticks;
- now = qemu_get_clock_ns(vm_clock);
- ticks = s->tick_offset + now / get_ticks_per_sec();
-
/* The timer wraps around. This subtraction also wraps in the same way,
and gives correct results when alarm < now_ticks. */
- ticks = s->mr - ticks;
+ ticks = s->mr - pl031_get_count(s);
DPRINTF("Alarm set in %ud ticks\n", ticks);
if (ticks == 0) {
qemu_del_timer(s->timer);
pl031_interrupt(s);
} else {
+ int64_t now = qemu_get_clock_ns(rtc_clock);
qemu_mod_timer(s->timer, now + (int64_t)ticks * get_ticks_per_sec());
}
}
@@ -205,14 +192,50 @@ static int pl031_init(SysBusDevice *dev)
sysbus_init_mmio(dev, &s->iomem);
sysbus_init_irq(dev, &s->irq);
- /* ??? We assume vm_clock is zero at this point. */
qemu_get_timedate(&tm, 0);
- s->tick_offset = mktimegm(&tm);
+ s->tick_offset = mktimegm(&tm) - qemu_get_clock_ns(rtc_clock) / get_ticks_per_sec();
+
+ s->timer = qemu_new_timer_ns(rtc_clock, pl031_interrupt, s);
+ return 0;
+}
+
+static void pl031_pre_save(void *opaque)
+{
+ pl031_state *s = opaque;
+
+ /* tick_offset is base_time - rtc_clock base time. Instead, we want to
+ * store the base time relative to the vm_clock for backwards-compatibility. */
+ int64_t delta = qemu_get_clock_ns(rtc_clock) - qemu_get_clock_ns(vm_clock);
+ s->tick_offset_vmstate = s->tick_offset + delta / get_ticks_per_sec();
+}
+
+static int pl031_post_load(void *opaque, int version_id)
+{
+ pl031_state *s = opaque;
- s->timer = qemu_new_timer_ns(vm_clock, pl031_interrupt, s);
+ int64_t delta = qemu_get_clock_ns(rtc_clock) - qemu_get_clock_ns(vm_clock);
+ s->tick_offset = s->tick_offset_vmstate - delta / get_ticks_per_sec();
+ pl031_set_alarm(s);
return 0;
}
+static const VMStateDescription vmstate_pl031 = {
+ .name = "pl031",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .pre_save = pl031_pre_save,
+ .post_load = pl031_post_load,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT32(tick_offset_vmstate, pl031_state),
+ VMSTATE_UINT32(mr, pl031_state),
+ VMSTATE_UINT32(lr, pl031_state),
+ VMSTATE_UINT32(cr, pl031_state),
+ VMSTATE_UINT32(im, pl031_state),
+ VMSTATE_UINT32(is, pl031_state),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
static void pl031_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
diff --git a/hw/ppc440_bamboo.c b/hw/ppc440_bamboo.c
index 220c81d06e..f0a3ae49e6 100644
--- a/hw/ppc440_bamboo.c
+++ b/hw/ppc440_bamboo.c
@@ -1,5 +1,5 @@
/*
- * Qemu PowerPC 440 Bamboo board emulation
+ * QEMU PowerPC 440 Bamboo board emulation
*
* Copyright 2007 IBM Corporation.
* Authors:
diff --git a/hw/ppc_prep.c b/hw/ppc_prep.c
index 06d589d97b..9d8e6592e1 100644
--- a/hw/ppc_prep.c
+++ b/hw/ppc_prep.c
@@ -615,8 +615,8 @@ static void ppc_prep_init (ram_addr_t ram_size,
sys = sysbus_from_qdev(dev);
pcihost = DO_UPCAST(PCIHostState, busdev, sys);
pcihost->address_space = get_system_memory();
+ object_property_add_child(qdev_get_machine(), "raven", OBJECT(dev), NULL);
qdev_init_nofail(dev);
- object_property_add_child(object_get_root(), "raven", OBJECT(dev), NULL);
pci_bus = (PCIBus *)qdev_get_child_bus(dev, "pci.0");
if (pci_bus == NULL) {
fprintf(stderr, "Couldn't create PCI host controller.\n");
diff --git a/hw/ppce500_mpc8544ds.c b/hw/ppce500_mpc8544ds.c
index 5ee8cb34c1..f1dfbe181c 100644
--- a/hw/ppce500_mpc8544ds.c
+++ b/hw/ppce500_mpc8544ds.c
@@ -1,5 +1,5 @@
/*
- * Qemu PowerPC MPC8544DS board emualtion
+ * QEMU PowerPC MPC8544DS board emulation
*
* Copyright (C) 2009 Freescale Semiconductor, Inc. All rights reserved.
*
diff --git a/hw/ps2.c b/hw/ps2.c
index b1a67bc625..f93cd24d94 100644
--- a/hw/ps2.c
+++ b/hw/ps2.c
@@ -88,7 +88,7 @@ typedef struct {
typedef struct {
PS2State common;
int scan_enabled;
- /* Qemu uses translated PC scancodes internally. To avoid multiple
+ /* QEMU uses translated PC scancodes internally. To avoid multiple
conversions we do the translation (if any) in the PS/2 emulation
not the keyboard controller. */
int translate;
diff --git a/hw/pxa2xx.c b/hw/pxa2xx.c
index 1d5c35f174..ddaa846882 100644
--- a/hw/pxa2xx.c
+++ b/hw/pxa2xx.c
@@ -875,7 +875,7 @@ static inline void pxa2xx_rtc_int_update(PXA2xxRTCState *s)
static void pxa2xx_rtc_hzupdate(PXA2xxRTCState *s)
{
- int64_t rt = qemu_get_clock_ms(rt_clock);
+ int64_t rt = qemu_get_clock_ms(rtc_clock);
s->last_rcnr += ((rt - s->last_hz) << 15) /
(1000 * ((s->rttr & 0xffff) + 1));
s->last_rdcr += ((rt - s->last_hz) << 15) /
@@ -885,7 +885,7 @@ static void pxa2xx_rtc_hzupdate(PXA2xxRTCState *s)
static void pxa2xx_rtc_swupdate(PXA2xxRTCState *s)
{
- int64_t rt = qemu_get_clock_ms(rt_clock);
+ int64_t rt = qemu_get_clock_ms(rtc_clock);
if (s->rtsr & (1 << 12))
s->last_swcr += (rt - s->last_sw) / 10;
s->last_sw = rt;
@@ -893,7 +893,7 @@ static void pxa2xx_rtc_swupdate(PXA2xxRTCState *s)
static void pxa2xx_rtc_piupdate(PXA2xxRTCState *s)
{
- int64_t rt = qemu_get_clock_ms(rt_clock);
+ int64_t rt = qemu_get_clock_ms(rtc_clock);
if (s->rtsr & (1 << 15))
s->last_swcr += rt - s->last_pi;
s->last_pi = rt;
@@ -1019,16 +1019,16 @@ static uint64_t pxa2xx_rtc_read(void *opaque, target_phys_addr_t addr,
case PIAR:
return s->piar;
case RCNR:
- return s->last_rcnr + ((qemu_get_clock_ms(rt_clock) - s->last_hz) << 15) /
+ return s->last_rcnr + ((qemu_get_clock_ms(rtc_clock) - s->last_hz) << 15) /
(1000 * ((s->rttr & 0xffff) + 1));
case RDCR:
- return s->last_rdcr + ((qemu_get_clock_ms(rt_clock) - s->last_hz) << 15) /
+ return s->last_rdcr + ((qemu_get_clock_ms(rtc_clock) - s->last_hz) << 15) /
(1000 * ((s->rttr & 0xffff) + 1));
case RYCR:
return s->last_rycr;
case SWCR:
if (s->rtsr & (1 << 12))
- return s->last_swcr + (qemu_get_clock_ms(rt_clock) - s->last_sw) / 10;
+ return s->last_swcr + (qemu_get_clock_ms(rtc_clock) - s->last_sw) / 10;
else
return s->last_swcr;
default:
@@ -1168,14 +1168,14 @@ static int pxa2xx_rtc_init(SysBusDevice *dev)
s->last_swcr = (tm.tm_hour << 19) |
(tm.tm_min << 13) | (tm.tm_sec << 7);
s->last_rtcpicr = 0;
- s->last_hz = s->last_sw = s->last_pi = qemu_get_clock_ms(rt_clock);
-
- s->rtc_hz = qemu_new_timer_ms(rt_clock, pxa2xx_rtc_hz_tick, s);
- s->rtc_rdal1 = qemu_new_timer_ms(rt_clock, pxa2xx_rtc_rdal1_tick, s);
- s->rtc_rdal2 = qemu_new_timer_ms(rt_clock, pxa2xx_rtc_rdal2_tick, s);
- s->rtc_swal1 = qemu_new_timer_ms(rt_clock, pxa2xx_rtc_swal1_tick, s);
- s->rtc_swal2 = qemu_new_timer_ms(rt_clock, pxa2xx_rtc_swal2_tick, s);
- s->rtc_pi = qemu_new_timer_ms(rt_clock, pxa2xx_rtc_pi_tick, s);
+ s->last_hz = s->last_sw = s->last_pi = qemu_get_clock_ms(rtc_clock);
+
+ s->rtc_hz = qemu_new_timer_ms(rtc_clock, pxa2xx_rtc_hz_tick, s);
+ s->rtc_rdal1 = qemu_new_timer_ms(rtc_clock, pxa2xx_rtc_rdal1_tick, s);
+ s->rtc_rdal2 = qemu_new_timer_ms(rtc_clock, pxa2xx_rtc_rdal2_tick, s);
+ s->rtc_swal1 = qemu_new_timer_ms(rtc_clock, pxa2xx_rtc_swal1_tick, s);
+ s->rtc_swal2 = qemu_new_timer_ms(rtc_clock, pxa2xx_rtc_swal2_tick, s);
+ s->rtc_pi = qemu_new_timer_ms(rtc_clock, pxa2xx_rtc_pi_tick, s);
sysbus_init_irq(dev, &s->rtc_irq);
diff --git a/hw/qdev-monitor.c b/hw/qdev-monitor.c
index a310cc7b16..4783366cf4 100644
--- a/hw/qdev-monitor.c
+++ b/hw/qdev-monitor.c
@@ -180,9 +180,7 @@ static Object *qdev_get_peripheral(void)
static Object *dev;
if (dev == NULL) {
- dev = object_new("container");
- object_property_add_child(object_get_root(), "peripheral",
- OBJECT(dev), NULL);
+ dev = container_get("/machine/peripheral");
}
return dev;
@@ -193,9 +191,7 @@ static Object *qdev_get_peripheral_anon(void)
static Object *dev;
if (dev == NULL) {
- dev = object_new("container");
- object_property_add_child(object_get_root(), "peripheral-anon",
- OBJECT(dev), NULL);
+ dev = container_get("/machine/peripheral-anon");
}
return dev;
@@ -462,10 +458,6 @@ DeviceState *qdev_device_add(QemuOpts *opts)
qdev_free(qdev);
return NULL;
}
- if (qdev_init(qdev) < 0) {
- qerror_report(QERR_DEVICE_INIT_FAILED, driver);
- return NULL;
- }
if (qdev->id) {
object_property_add_child(qdev_get_peripheral(), qdev->id,
OBJECT(qdev), NULL);
@@ -476,6 +468,10 @@ DeviceState *qdev_device_add(QemuOpts *opts)
OBJECT(qdev), NULL);
g_free(name);
}
+ if (qdev_init(qdev) < 0) {
+ qerror_report(QERR_DEVICE_INIT_FAILED, driver);
+ return NULL;
+ }
qdev->opts = opts;
return qdev;
}
diff --git a/hw/qdev.c b/hw/qdev.c
index ee21d90e80..0d3c0fc49c 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -113,14 +113,14 @@ DeviceState *qdev_create(BusState *bus, const char *name)
return dev;
}
-DeviceState *qdev_try_create(BusState *bus, const char *name)
+DeviceState *qdev_try_create(BusState *bus, const char *type)
{
DeviceState *dev;
- if (object_class_by_name(name) == NULL) {
+ if (object_class_by_name(type) == NULL) {
return NULL;
}
- dev = DEVICE(object_new(name));
+ dev = DEVICE(object_new(type));
if (!dev) {
return NULL;
}
@@ -152,6 +152,16 @@ int qdev_init(DeviceState *dev)
qdev_free(dev);
return rc;
}
+
+ if (!OBJECT(dev)->parent) {
+ static int unattached_count = 0;
+ gchar *name = g_strdup_printf("device[%d]", unattached_count++);
+
+ object_property_add_child(container_get("/machine/unattached"), name,
+ OBJECT(dev), NULL);
+ g_free(name);
+ }
+
if (qdev_get_vmsd(dev)) {
vmstate_register_with_alias_id(dev, -1, qdev_get_vmsd(dev), dev,
dev->instance_id_alias,
@@ -658,6 +668,17 @@ void device_reset(DeviceState *dev)
}
}
+Object *qdev_get_machine(void)
+{
+ static Object *dev;
+
+ if (dev == NULL) {
+ dev = container_get("/machine");
+ }
+
+ return dev;
+}
+
static TypeInfo device_type_info = {
.name = TYPE_DEVICE,
.parent = TYPE_OBJECT,
diff --git a/hw/qdev.h b/hw/qdev.h
index 9cc3f984b2..a8df42f6fa 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -349,6 +349,8 @@ BusInfo *qdev_get_bus_info(DeviceState *dev);
Property *qdev_get_props(DeviceState *dev);
+Object *qdev_get_machine(void);
+
/* FIXME: make this a link<> */
void qdev_set_parent_bus(DeviceState *dev, BusState *bus);
diff --git a/hw/qxl-render.c b/hw/qxl-render.c
index 25857f6a20..28ab182226 100644
--- a/hw/qxl-render.c
+++ b/hw/qxl-render.c
@@ -31,11 +31,10 @@ static void qxl_blit(PCIQXLDevice *qxl, QXLRect *rect)
return;
}
if (!qxl->guest_primary.data) {
- dprint(qxl, 1, "%s: initializing guest_primary.data\n", __func__);
+ trace_qxl_render_blit_guest_primary_initialized();
qxl->guest_primary.data = memory_region_get_ram_ptr(&qxl->vga.vram);
}
- dprint(qxl, 2, "%s: stride %d, [%d, %d, %d, %d]\n", __func__,
- qxl->guest_primary.qxl_stride,
+ trace_qxl_render_blit(qxl->guest_primary.qxl_stride,
rect->left, rect->right, rect->top, rect->bottom);
src = qxl->guest_primary.data;
if (qxl->guest_primary.qxl_stride < 0) {
@@ -107,8 +106,7 @@ static void qxl_render_update_area_unlocked(PCIQXLDevice *qxl)
qxl->guest_primary.data = memory_region_get_ram_ptr(&qxl->vga.vram);
qxl_set_rect_to_surface(qxl, &qxl->dirty[0]);
qxl->num_dirty_rects = 1;
- dprint(qxl, 1, "%s: %dx%d, stride %d, bpp %d, depth %d\n",
- __FUNCTION__,
+ trace_qxl_render_guest_primary_resized(
qxl->guest_primary.surface.width,
qxl->guest_primary.surface.height,
qxl->guest_primary.qxl_stride,
@@ -118,8 +116,6 @@ static void qxl_render_update_area_unlocked(PCIQXLDevice *qxl)
if (surface->width != qxl->guest_primary.surface.width ||
surface->height != qxl->guest_primary.surface.height) {
if (qxl->guest_primary.qxl_stride > 0) {
- dprint(qxl, 1, "%s: using guest_primary for displaysurface\n",
- __func__);
qemu_free_displaysurface(vga->ds);
qemu_create_displaysurface_from(qxl->guest_primary.surface.width,
qxl->guest_primary.surface.height,
@@ -127,8 +123,6 @@ static void qxl_render_update_area_unlocked(PCIQXLDevice *qxl)
qxl->guest_primary.abs_stride,
qxl->guest_primary.data);
} else {
- dprint(qxl, 1, "%s: resizing displaysurface to guest_primary\n",
- __func__);
qemu_resize_displaysurface(vga->ds,
qxl->guest_primary.surface.width,
qxl->guest_primary.surface.height);
@@ -187,6 +181,7 @@ void qxl_render_update_area_bh(void *opaque)
void qxl_render_update_area_done(PCIQXLDevice *qxl, QXLCookie *cookie)
{
qemu_mutex_lock(&qxl->ssd.lock);
+ trace_qxl_render_update_area_done(cookie);
qemu_bh_schedule(qxl->update_area_bh);
qxl->render_update_cookie_num--;
qemu_mutex_unlock(&qxl->ssd.lock);
diff --git a/hw/qxl.c b/hw/qxl.c
index e17b0e31af..47a162e479 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -23,6 +23,7 @@
#include "qemu-queue.h"
#include "monitor.h"
#include "sysemu.h"
+#include "trace.h"
#include "qxl.h"
@@ -143,19 +144,24 @@ void qxl_spice_update_area(PCIQXLDevice *qxl, uint32_t surface_id,
uint32_t clear_dirty_region,
qxl_async_io async, struct QXLCookie *cookie)
{
+ trace_qxl_spice_update_area(qxl->id, surface_id, area->left, area->right,
+ area->top, area->bottom);
+ trace_qxl_spice_update_area_rest(qxl->id, num_dirty_rects,
+ clear_dirty_region);
if (async == QXL_SYNC) {
qxl->ssd.worker->update_area(qxl->ssd.worker, surface_id, area,
dirty_rects, num_dirty_rects, clear_dirty_region);
} else {
assert(cookie != NULL);
spice_qxl_update_area_async(&qxl->ssd.qxl, surface_id, area,
- clear_dirty_region, (uint64_t)cookie);
+ clear_dirty_region, (uintptr_t)cookie);
}
}
static void qxl_spice_destroy_surface_wait_complete(PCIQXLDevice *qxl,
uint32_t id)
{
+ trace_qxl_spice_destroy_surface_wait_complete(qxl->id, id);
qemu_mutex_lock(&qxl->track_lock);
qxl->guest_surfaces.cmds[id] = 0;
qxl->guest_surfaces.count--;
@@ -167,42 +173,48 @@ static void qxl_spice_destroy_surface_wait(PCIQXLDevice *qxl, uint32_t id,
{
QXLCookie *cookie;
+ trace_qxl_spice_destroy_surface_wait(qxl->id, id, async);
if (async) {
cookie = qxl_cookie_new(QXL_COOKIE_TYPE_IO,
QXL_IO_DESTROY_SURFACE_ASYNC);
cookie->u.surface_id = id;
- spice_qxl_destroy_surface_async(&qxl->ssd.qxl, id, (uint64_t)cookie);
+ spice_qxl_destroy_surface_async(&qxl->ssd.qxl, id, (uintptr_t)cookie);
} else {
qxl->ssd.worker->destroy_surface_wait(qxl->ssd.worker, id);
- qxl_spice_destroy_surface_wait_complete(qxl, id);
}
}
static void qxl_spice_flush_surfaces_async(PCIQXLDevice *qxl)
{
+ trace_qxl_spice_flush_surfaces_async(qxl->id, qxl->guest_surfaces.count,
+ qxl->num_free_res);
spice_qxl_flush_surfaces_async(&qxl->ssd.qxl,
- (uint64_t)qxl_cookie_new(QXL_COOKIE_TYPE_IO,
- QXL_IO_FLUSH_SURFACES_ASYNC));
+ (uintptr_t)qxl_cookie_new(QXL_COOKIE_TYPE_IO,
+ QXL_IO_FLUSH_SURFACES_ASYNC));
}
void qxl_spice_loadvm_commands(PCIQXLDevice *qxl, struct QXLCommandExt *ext,
uint32_t count)
{
+ trace_qxl_spice_loadvm_commands(qxl->id, ext, count);
qxl->ssd.worker->loadvm_commands(qxl->ssd.worker, ext, count);
}
void qxl_spice_oom(PCIQXLDevice *qxl)
{
+ trace_qxl_spice_oom(qxl->id);
qxl->ssd.worker->oom(qxl->ssd.worker);
}
void qxl_spice_reset_memslots(PCIQXLDevice *qxl)
{
+ trace_qxl_spice_reset_memslots(qxl->id);
qxl->ssd.worker->reset_memslots(qxl->ssd.worker);
}
static void qxl_spice_destroy_surfaces_complete(PCIQXLDevice *qxl)
{
+ trace_qxl_spice_destroy_surfaces_complete(qxl->id);
qemu_mutex_lock(&qxl->track_lock);
memset(&qxl->guest_surfaces.cmds, 0, sizeof(qxl->guest_surfaces.cmds));
qxl->guest_surfaces.count = 0;
@@ -211,10 +223,11 @@ static void qxl_spice_destroy_surfaces_complete(PCIQXLDevice *qxl)
static void qxl_spice_destroy_surfaces(PCIQXLDevice *qxl, qxl_async_io async)
{
+ trace_qxl_spice_destroy_surfaces(qxl->id, async);
if (async) {
spice_qxl_destroy_surfaces_async(&qxl->ssd.qxl,
- (uint64_t)qxl_cookie_new(QXL_COOKIE_TYPE_IO,
- QXL_IO_DESTROY_ALL_SURFACES_ASYNC));
+ (uintptr_t)qxl_cookie_new(QXL_COOKIE_TYPE_IO,
+ QXL_IO_DESTROY_ALL_SURFACES_ASYNC));
} else {
qxl->ssd.worker->destroy_surfaces(qxl->ssd.worker);
qxl_spice_destroy_surfaces_complete(qxl);
@@ -223,11 +236,13 @@ static void qxl_spice_destroy_surfaces(PCIQXLDevice *qxl, qxl_async_io async)
void qxl_spice_reset_image_cache(PCIQXLDevice *qxl)
{
+ trace_qxl_spice_reset_image_cache(qxl->id);
qxl->ssd.worker->reset_image_cache(qxl->ssd.worker);
}
void qxl_spice_reset_cursor(PCIQXLDevice *qxl)
{
+ trace_qxl_spice_reset_cursor(qxl->id);
qxl->ssd.worker->reset_cursor(qxl->ssd.worker);
qemu_mutex_lock(&qxl->track_lock);
qxl->guest_cursor = 0;
@@ -409,7 +424,7 @@ static void interface_attach_worker(QXLInstance *sin, QXLWorker *qxl_worker)
{
PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
- dprint(qxl, 1, "%s:\n", __FUNCTION__);
+ trace_qxl_interface_attach_worker(qxl->id);
qxl->ssd.worker = qxl_worker;
}
@@ -417,7 +432,7 @@ static void interface_set_compression_level(QXLInstance *sin, int level)
{
PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
- dprint(qxl, 1, "%s: %d\n", __FUNCTION__, level);
+ trace_qxl_interface_set_compression_level(qxl->id, level);
qxl->shadow_rom.compression_level = cpu_to_le32(level);
qxl->rom->compression_level = cpu_to_le32(level);
qxl_rom_set_dirty(qxl);
@@ -427,6 +442,7 @@ static void interface_set_mm_time(QXLInstance *sin, uint32_t mm_time)
{
PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
+ trace_qxl_interface_set_mm_time(qxl->id, mm_time);
qxl->shadow_rom.mm_clock = cpu_to_le32(mm_time);
qxl->rom->mm_clock = cpu_to_le32(mm_time);
qxl_rom_set_dirty(qxl);
@@ -436,7 +452,7 @@ static void interface_get_init_info(QXLInstance *sin, QXLDevInitInfo *info)
{
PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
- dprint(qxl, 1, "%s:\n", __FUNCTION__);
+ trace_qxl_interface_get_init_info(qxl->id);
info->memslot_gen_bits = MEMSLOT_GENERATION_BITS;
info->memslot_id_bits = MEMSLOT_SLOT_BITS;
info->num_memslots = NUM_MEMSLOTS;
@@ -505,9 +521,10 @@ static int interface_get_command(QXLInstance *sin, struct QXLCommandExt *ext)
QXLCommand *cmd;
int notify, ret;
+ trace_qxl_ring_command_check(qxl->id, qxl_mode_to_string(qxl->mode));
+
switch (qxl->mode) {
case QXL_MODE_VGA:
- dprint(qxl, 2, "%s: vga\n", __FUNCTION__);
ret = false;
qemu_mutex_lock(&qxl->ssd.lock);
if (qxl->ssd.update != NULL) {
@@ -518,19 +535,18 @@ static int interface_get_command(QXLInstance *sin, struct QXLCommandExt *ext)
}
qemu_mutex_unlock(&qxl->ssd.lock);
if (ret) {
- dprint(qxl, 2, "%s %s\n", __FUNCTION__, qxl_mode_to_string(qxl->mode));
+ trace_qxl_ring_command_get(qxl->id, qxl_mode_to_string(qxl->mode));
qxl_log_command(qxl, "vga", ext);
}
return ret;
case QXL_MODE_COMPAT:
case QXL_MODE_NATIVE:
case QXL_MODE_UNDEFINED:
- dprint(qxl, 4, "%s: %s\n", __FUNCTION__, qxl_mode_to_string(qxl->mode));
ring = &qxl->ram->cmd_ring;
if (SPICE_RING_IS_EMPTY(ring)) {
return false;
}
- dprint(qxl, 2, "%s: %s\n", __FUNCTION__, qxl_mode_to_string(qxl->mode));
+ trace_qxl_ring_command_get(qxl->id, qxl_mode_to_string(qxl->mode));
SPICE_RING_CONS_ITEM(ring, cmd);
ext->cmd = *cmd;
ext->group_id = MEMSLOT_GROUP_GUEST;
@@ -555,6 +571,7 @@ static int interface_req_cmd_notification(QXLInstance *sin)
PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
int wait = 1;
+ trace_qxl_ring_command_req_notification(qxl->id);
switch (qxl->mode) {
case QXL_MODE_COMPAT:
case QXL_MODE_NATIVE:
@@ -592,10 +609,11 @@ static inline void qxl_push_free_res(PCIQXLDevice *d, int flush)
}
SPICE_RING_PUSH(ring, notify);
- dprint(d, 2, "free: push %d items, notify %s, ring %d/%d [%d,%d]\n",
- d->num_free_res, notify ? "yes" : "no",
- ring->prod - ring->cons, ring->num_items,
- ring->prod, ring->cons);
+ trace_qxl_ring_res_push(d->id, qxl_mode_to_string(d->mode),
+ d->guest_surfaces.count, d->num_free_res,
+ d->last_release, notify ? "yes" : "no");
+ trace_qxl_ring_res_push_rest(d->id, ring->prod - ring->cons,
+ ring->num_items, ring->prod, ring->cons);
if (notify) {
qxl_send_events(d, QXL_INTERRUPT_DISPLAY);
}
@@ -642,7 +660,7 @@ static void interface_release_resource(QXLInstance *sin,
}
qxl->last_release = ext.info;
qxl->num_free_res++;
- dprint(qxl, 3, "%4d\r", qxl->num_free_res);
+ trace_qxl_ring_res_put(qxl->id, qxl->num_free_res);
qxl_push_free_res(qxl, 0);
}
@@ -654,6 +672,8 @@ static int interface_get_cursor_command(QXLInstance *sin, struct QXLCommandExt *
QXLCommand *cmd;
int notify;
+ trace_qxl_ring_cursor_check(qxl->id, qxl_mode_to_string(qxl->mode));
+
switch (qxl->mode) {
case QXL_MODE_COMPAT:
case QXL_MODE_NATIVE:
@@ -677,6 +697,7 @@ static int interface_get_cursor_command(QXLInstance *sin, struct QXLCommandExt *
if (qxl->id == 0) {
qxl_render_cursor(qxl, ext);
}
+ trace_qxl_ring_cursor_get(qxl->id, qxl_mode_to_string(qxl->mode));
return true;
default:
return false;
@@ -689,6 +710,7 @@ static int interface_req_cursor_notification(QXLInstance *sin)
PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
int wait = 1;
+ trace_qxl_ring_cursor_req_notification(qxl->id);
switch (qxl->mode) {
case QXL_MODE_COMPAT:
case QXL_MODE_NATIVE:
@@ -716,7 +738,6 @@ static int interface_flush_resources(QXLInstance *sin)
PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
int ret;
- dprint(qxl, 1, "free: guest flush (have %d)\n", qxl->num_free_res);
ret = qxl->num_free_res;
if (ret) {
qxl_push_free_res(qxl, 1);
@@ -736,14 +757,14 @@ static void interface_async_complete_io(PCIQXLDevice *qxl, QXLCookie *cookie)
qxl->current_async = QXL_UNDEFINED_IO;
qemu_mutex_unlock(&qxl->async_lock);
- dprint(qxl, 2, "async_complete: %d (%p) done\n", current_async, cookie);
+ trace_qxl_interface_async_complete_io(qxl->id, current_async, cookie);
if (!cookie) {
fprintf(stderr, "qxl: %s: error, cookie is NULL\n", __func__);
return;
}
if (cookie && current_async != cookie->io) {
fprintf(stderr,
- "qxl: %s: error: current_async = %d != %ld = cookie->io\n",
+ "qxl: %s: error: current_async = %d != %" PRId64 " = cookie->io\n",
__func__, current_async, cookie->io);
}
switch (current_async) {
@@ -782,11 +803,15 @@ static void interface_update_area_complete(QXLInstance *sin,
qemu_mutex_unlock(&qxl->ssd.lock);
return;
}
+ trace_qxl_interface_update_area_complete(qxl->id, surface_id, dirty->left,
+ dirty->right, dirty->top, dirty->bottom);
+ trace_qxl_interface_update_area_complete_rest(qxl->id, num_updated_rects);
if (qxl->num_dirty_rects + num_updated_rects > QXL_NUM_DIRTY_RECTS) {
/*
* overflow - treat this as a full update. Not expected to be common.
*/
- dprint(qxl, 1, "%s: overflow of dirty rects\n", __func__);
+ trace_qxl_interface_update_area_complete_overflow(qxl->id,
+ QXL_NUM_DIRTY_RECTS);
qxl->guest_primary.resized = 1;
}
if (qxl->guest_primary.resized) {
@@ -802,8 +827,8 @@ static void interface_update_area_complete(QXLInstance *sin,
qxl->dirty[qxl_i++] = dirty[i];
}
qxl->num_dirty_rects += num_updated_rects;
- dprint(qxl, 1, "%s: scheduling update_area_bh, #dirty %d\n",
- __func__, qxl->num_dirty_rects);
+ trace_qxl_interface_update_area_complete_schedule_bh(qxl->id,
+ qxl->num_dirty_rects);
qemu_bh_schedule(qxl->update_area_bh);
qemu_mutex_unlock(&qxl->ssd.lock);
}
@@ -812,7 +837,7 @@ static void interface_update_area_complete(QXLInstance *sin,
static void interface_async_complete(QXLInstance *sin, uint64_t cookie_token)
{
PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
- QXLCookie *cookie = (QXLCookie *)cookie_token;
+ QXLCookie *cookie = (QXLCookie *)(uintptr_t)cookie_token;
switch (cookie->type) {
case QXL_COOKIE_TYPE_IO:
@@ -857,7 +882,7 @@ static void qxl_enter_vga_mode(PCIQXLDevice *d)
if (d->mode == QXL_MODE_VGA) {
return;
}
- dprint(d, 1, "%s\n", __FUNCTION__);
+ trace_qxl_enter_vga_mode(d->id);
qemu_spice_create_host_primary(&d->ssd);
d->mode = QXL_MODE_VGA;
memset(&d->ssd.dirty, 0, sizeof(d->ssd.dirty));
@@ -868,7 +893,7 @@ static void qxl_exit_vga_mode(PCIQXLDevice *d)
if (d->mode != QXL_MODE_VGA) {
return;
}
- dprint(d, 1, "%s\n", __FUNCTION__);
+ trace_qxl_exit_vga_mode(d->id);
qxl_destroy_primary(d, QXL_SYNC);
}
@@ -905,7 +930,7 @@ static void qxl_reset_state(PCIQXLDevice *d)
static void qxl_soft_reset(PCIQXLDevice *d)
{
- dprint(d, 1, "%s:\n", __FUNCTION__);
+ trace_qxl_soft_reset(d->id);
qxl_check_state(d);
if (d->id == 0) {
@@ -917,8 +942,7 @@ static void qxl_soft_reset(PCIQXLDevice *d)
static void qxl_hard_reset(PCIQXLDevice *d, int loadvm)
{
- dprint(d, 1, "%s: start%s\n", __FUNCTION__,
- loadvm ? " (loadvm)" : "");
+ trace_qxl_hard_reset(d->id, loadvm);
qxl_spice_reset_cursor(d);
qxl_spice_reset_image_cache(d);
@@ -933,13 +957,12 @@ static void qxl_hard_reset(PCIQXLDevice *d, int loadvm)
}
qemu_spice_create_host_memslot(&d->ssd);
qxl_soft_reset(d);
-
- dprint(d, 1, "%s: done\n", __FUNCTION__);
}
static void qxl_reset_handler(DeviceState *dev)
{
PCIQXLDevice *d = DO_UPCAST(PCIQXLDevice, pci.qdev, dev);
+
qxl_hard_reset(d, 0);
}
@@ -948,8 +971,8 @@ static void qxl_vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
VGACommonState *vga = opaque;
PCIQXLDevice *qxl = container_of(vga, PCIQXLDevice, vga);
+ trace_qxl_io_write_vga(qxl->id, qxl_mode_to_string(qxl->mode), addr, val);
if (qxl->mode != QXL_MODE_VGA) {
- dprint(qxl, 1, "%s\n", __FUNCTION__);
qxl_destroy_primary(qxl, QXL_SYNC);
qxl_soft_reset(qxl);
}
@@ -990,9 +1013,7 @@ static void qxl_add_memslot(PCIQXLDevice *d, uint32_t slot_id, uint64_t delta,
guest_start = le64_to_cpu(d->guest_slots[slot_id].slot.mem_start);
guest_end = le64_to_cpu(d->guest_slots[slot_id].slot.mem_end);
- dprint(d, 1, "%s: slot %d: guest phys 0x%" PRIx64 " - 0x%" PRIx64 "\n",
- __FUNCTION__, slot_id,
- guest_start, guest_end);
+ trace_qxl_memslot_add_guest(d->id, slot_id, guest_start, guest_end);
PANIC_ON(slot_id >= NUM_MEMSLOTS);
PANIC_ON(guest_start > guest_end);
@@ -1039,10 +1060,6 @@ static void qxl_add_memslot(PCIQXLDevice *d, uint32_t slot_id, uint64_t delta,
memslot.generation = d->rom->slot_generation = 0;
qxl_rom_set_dirty(d);
- dprint(d, 1, "%s: slot %d: host virt 0x%lx - 0x%lx\n",
- __FUNCTION__, memslot.slot_id,
- memslot.virt_start, memslot.virt_end);
-
qemu_spice_add_memslot(&d->ssd, &memslot, async);
d->guest_slots[slot_id].ptr = (void*)memslot.virt_start;
d->guest_slots[slot_id].size = memslot.virt_end - memslot.virt_start;
@@ -1052,21 +1069,19 @@ static void qxl_add_memslot(PCIQXLDevice *d, uint32_t slot_id, uint64_t delta,
static void qxl_del_memslot(PCIQXLDevice *d, uint32_t slot_id)
{
- dprint(d, 1, "%s: slot %d\n", __FUNCTION__, slot_id);
qemu_spice_del_memslot(&d->ssd, MEMSLOT_GROUP_HOST, slot_id);
d->guest_slots[slot_id].active = 0;
}
static void qxl_reset_memslots(PCIQXLDevice *d)
{
- dprint(d, 1, "%s:\n", __FUNCTION__);
qxl_spice_reset_memslots(d);
memset(&d->guest_slots, 0, sizeof(d->guest_slots));
}
static void qxl_reset_surfaces(PCIQXLDevice *d)
{
- dprint(d, 1, "%s:\n", __FUNCTION__);
+ trace_qxl_reset_surfaces(d->id);
d->mode = QXL_MODE_UNDEFINED;
qxl_spice_destroy_surfaces(d, QXL_SYNC);
}
@@ -1108,9 +1123,6 @@ static void qxl_create_guest_primary(PCIQXLDevice *qxl, int loadvm,
assert(qxl->mode != QXL_MODE_NATIVE);
qxl_exit_vga_mode(qxl);
- dprint(qxl, 1, "%s: %dx%d\n", __FUNCTION__,
- le32_to_cpu(sc->width), le32_to_cpu(sc->height));
-
surface.format = le32_to_cpu(sc->format);
surface.height = le32_to_cpu(sc->height);
surface.mem = le64_to_cpu(sc->mem);
@@ -1119,6 +1131,10 @@ static void qxl_create_guest_primary(PCIQXLDevice *qxl, int loadvm,
surface.width = le32_to_cpu(sc->width);
surface.type = le32_to_cpu(sc->type);
surface.flags = le32_to_cpu(sc->flags);
+ trace_qxl_create_guest_primary(qxl->id, sc->width, sc->height, sc->mem,
+ sc->format, sc->position);
+ trace_qxl_create_guest_primary_rest(qxl->id, sc->stride, sc->type,
+ sc->flags);
surface.mouse_mode = true;
surface.group_id = MEMSLOT_GROUP_GUEST;
@@ -1142,7 +1158,7 @@ static int qxl_destroy_primary(PCIQXLDevice *d, qxl_async_io async)
if (d->mode == QXL_MODE_UNDEFINED) {
return 0;
}
- dprint(d, 1, "%s\n", __FUNCTION__);
+ trace_qxl_destroy_primary(d->id);
d->mode = QXL_MODE_UNDEFINED;
qemu_spice_destroy_primary_surface(&d->ssd, 0, async);
qxl_spice_reset_cursor(d);
@@ -1169,8 +1185,8 @@ static void qxl_set_mode(PCIQXLDevice *d, int modenr, int loadvm)
.mem = devmem + d->shadow_rom.draw_area_offset,
};
- dprint(d, 1, "%s: mode %d [ %d x %d @ %d bpp devmem 0x%" PRIx64 " ]\n",
- __func__, modenr, mode->x_res, mode->y_res, mode->bits, devmem);
+ trace_qxl_set_mode(d->id, modenr, mode->x_res, mode->y_res, mode->bits,
+ devmem);
if (!loadvm) {
qxl_hard_reset(d, 0);
}
@@ -1216,8 +1232,8 @@ static void ioport_write(void *opaque, target_phys_addr_t addr,
if (d->mode != QXL_MODE_VGA) {
break;
}
- dprint(d, 1, "%s: unexpected port 0x%x (%s) in vga mode\n",
- __func__, io_port, io_port_to_string(io_port));
+ trace_qxl_io_unexpected_vga_mode(d->id,
+ io_port, io_port_to_string(io_port));
/* be nice to buggy guest drivers */
if (io_port >= QXL_IO_UPDATE_AREA_ASYNC &&
io_port <= QXL_IO_DESTROY_ALL_SURFACES_ASYNC) {
@@ -1259,11 +1275,12 @@ async_common:
}
d->current_async = orig_io_port;
qemu_mutex_unlock(&d->async_lock);
- dprint(d, 2, "start async %d (%"PRId64")\n", io_port, val);
break;
default:
break;
}
+ trace_qxl_io_write(d->id, qxl_mode_to_string(d->mode), addr, val, size,
+ async);
switch (io_port) {
case QXL_IO_UPDATE_AREA:
@@ -1299,7 +1316,6 @@ async_common:
d->oom_running = 0;
break;
case QXL_IO_SET_MODE:
- dprint(d, 1, "QXL_SET_MODE %d\n", (int)val);
qxl_set_mode(d, val, 0);
break;
case QXL_IO_LOG:
@@ -1309,7 +1325,6 @@ async_common:
}
break;
case QXL_IO_RESET:
- dprint(d, 1, "QXL_IO_RESET\n");
qxl_hard_reset(d, 0);
break;
case QXL_IO_MEMSLOT_ADD:
@@ -1337,7 +1352,6 @@ async_common:
async);
goto cancel_async;
}
- dprint(d, 1, "QXL_IO_CREATE_PRIMARY async=%d\n", async);
d->guest_primary.surface = d->ram->create_surface;
qxl_create_guest_primary(d, 0, async);
break;
@@ -1347,11 +1361,9 @@ async_common:
async);
goto cancel_async;
}
- dprint(d, 1, "QXL_IO_DESTROY_PRIMARY (async=%d) (%s)\n", async,
- qxl_mode_to_string(d->mode));
if (!qxl_destroy_primary(d, async)) {
- dprint(d, 1, "QXL_IO_DESTROY_PRIMARY_ASYNC in %s, ignored\n",
- qxl_mode_to_string(d->mode));
+ trace_qxl_io_destroy_primary_ignored(d->id,
+ qxl_mode_to_string(d->mode));
goto cancel_async;
}
break;
@@ -1371,16 +1383,9 @@ async_common:
ring->prod, ring->cons);
}
qxl_push_free_res(d, 1 /* flush */);
- dprint(d, 1, "QXL_IO_FLUSH_RELEASE exit (%s, s#=%d, res#=%d,%p)\n",
- qxl_mode_to_string(d->mode), d->guest_surfaces.count,
- d->num_free_res, d->last_release);
break;
}
case QXL_IO_FLUSH_SURFACES_ASYNC:
- dprint(d, 1, "QXL_IO_FLUSH_SURFACES_ASYNC"
- " (%"PRId64") (%s, s#=%d, res#=%d)\n",
- val, qxl_mode_to_string(d->mode), d->guest_surfaces.count,
- d->num_free_res);
qxl_spice_flush_surfaces_async(d);
break;
case QXL_IO_DESTROY_ALL_SURFACES:
@@ -1406,7 +1411,7 @@ static uint64_t ioport_read(void *opaque, target_phys_addr_t addr,
{
PCIQXLDevice *d = opaque;
- dprint(d, 1, "%s: unexpected\n", __FUNCTION__);
+ trace_qxl_io_read_unexpected(d->id);
return 0xff;
}
@@ -1452,16 +1457,17 @@ static void qxl_send_events(PCIQXLDevice *d, uint32_t events)
static void init_pipe_signaling(PCIQXLDevice *d)
{
- if (pipe(d->pipe) < 0) {
- dprint(d, 1, "%s: pipe creation failed\n", __FUNCTION__);
- return;
- }
- fcntl(d->pipe[0], F_SETFL, O_NONBLOCK);
- fcntl(d->pipe[1], F_SETFL, O_NONBLOCK);
- fcntl(d->pipe[0], F_SETOWN, getpid());
+ if (pipe(d->pipe) < 0) {
+ fprintf(stderr, "%s:%s: qxl pipe creation failed\n",
+ __FILE__, __func__);
+ exit(1);
+ }
+ fcntl(d->pipe[0], F_SETFL, O_NONBLOCK);
+ fcntl(d->pipe[1], F_SETFL, O_NONBLOCK);
+ fcntl(d->pipe[0], F_SETOWN, getpid());
- qemu_thread_get_self(&d->main);
- qemu_set_fd_handler(d->pipe[0], pipe_read, NULL, d);
+ qemu_thread_get_self(&d->main);
+ qemu_set_fd_handler(d->pipe[0], pipe_read, NULL, d);
}
/* graphics console */
@@ -1556,8 +1562,7 @@ static void qxl_dirty_surfaces(PCIQXLDevice *qxl)
surface_offset -= vram_start;
surface_size = cmd->u.surface_create.height *
abs(cmd->u.surface_create.stride);
- dprint(qxl, 3, "%s: dirty surface %d, offset %d, size %d\n", __func__,
- i, (int)surface_offset, surface_size);
+ trace_qxl_surfaces_dirty(qxl->id, i, (int)surface_offset, surface_size);
qxl_set_dirty(&qxl->vram_bar, surface_offset, surface_size);
}
}
@@ -1791,7 +1796,7 @@ static void qxl_pre_save(void *opaque)
PCIQXLDevice* d = opaque;
uint8_t *ram_start = d->vga.vram_ptr;
- dprint(d, 1, "%s:\n", __FUNCTION__);
+ trace_qxl_pre_save(d->id);
if (d->last_release == NULL) {
d->last_release_offset = 0;
} else {
@@ -1804,10 +1809,9 @@ static int qxl_pre_load(void *opaque)
{
PCIQXLDevice* d = opaque;
- dprint(d, 1, "%s: start\n", __FUNCTION__);
+ trace_qxl_pre_load(d->id);
qxl_hard_reset(d, 1);
qxl_exit_vga_mode(d);
- dprint(d, 1, "%s: done\n", __FUNCTION__);
return 0;
}
@@ -1819,7 +1823,6 @@ static void qxl_create_memslots(PCIQXLDevice *d)
if (!d->guest_slots[i].active) {
continue;
}
- dprint(d, 1, "%s: restoring guest slot %d\n", __func__, i);
qxl_add_memslot(d, i, 0, QXL_SYNC);
}
}
@@ -1831,8 +1834,6 @@ static int qxl_post_load(void *opaque, int version)
QXLCommandExt *cmds;
int in, out, newmode;
- dprint(d, 1, "%s: start\n", __FUNCTION__);
-
assert(d->last_release_offset < d->vga.vram_size);
if (d->last_release_offset == 0) {
d->last_release = NULL;
@@ -1842,8 +1843,7 @@ static int qxl_post_load(void *opaque, int version)
d->modes = (QXLModes*)((uint8_t*)d->rom + d->rom->modes_offset);
- dprint(d, 1, "%s: restore mode (%s)\n", __FUNCTION__,
- qxl_mode_to_string(d->mode));
+ trace_qxl_post_load(d->id, qxl_mode_to_string(d->mode));
newmode = d->mode;
d->mode = QXL_MODE_UNDEFINED;
@@ -1885,8 +1885,6 @@ static int qxl_post_load(void *opaque, int version)
qxl_set_mode(d, d->shadow_rom.mode, 1);
break;
}
- dprint(d, 1, "%s: done\n", __FUNCTION__);
-
return 0;
}
diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index 2cb5a18da2..8e76c5d32c 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -7,6 +7,7 @@
#include "trace.h"
#include "dma.h"
+static char *scsibus_get_dev_path(DeviceState *dev);
static char *scsibus_get_fw_dev_path(DeviceState *dev);
static int scsi_req_parse(SCSICommand *cmd, SCSIDevice *dev, uint8_t *buf);
static void scsi_req_dequeue(SCSIRequest *req);
@@ -14,6 +15,7 @@ static void scsi_req_dequeue(SCSIRequest *req);
static struct BusInfo scsi_bus_info = {
.name = "SCSI",
.size = sizeof(SCSIBus),
+ .get_dev_path = scsibus_get_dev_path,
.get_fw_dev_path = scsibus_get_fw_dev_path,
.props = (Property[]) {
DEFINE_PROP_UINT32("channel", SCSIDevice, channel, 0),
@@ -1423,6 +1425,22 @@ void scsi_device_purge_requests(SCSIDevice *sdev, SCSISense sense)
sdev->unit_attention = sense;
}
+static char *scsibus_get_dev_path(DeviceState *dev)
+{
+ SCSIDevice *d = DO_UPCAST(SCSIDevice, qdev, dev);
+ DeviceState *hba = dev->parent_bus->parent;
+ char *id = NULL;
+
+ if (hba && hba->parent_bus && hba->parent_bus->info->get_dev_path) {
+ id = hba->parent_bus->info->get_dev_path(hba);
+ }
+ if (id) {
+ return g_strdup_printf("%s/%d:%d:%d", id, d->channel, d->id, d->lun);
+ } else {
+ return g_strdup_printf("%d:%d:%d", d->channel, d->id, d->lun);
+ }
+}
+
static char *scsibus_get_fw_dev_path(DeviceState *dev)
{
SCSIDevice *d = SCSI_DEVICE(dev);
diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index add399e97b..9949786e52 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -471,8 +471,9 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf)
case 0x83: /* Device identification page, mandatory */
{
- int max_len = 255 - 8;
- int id_len = strlen(bdrv_get_device_name(s->qdev.conf.bs));
+ const char *str = s->serial ?: bdrv_get_device_name(s->qdev.conf.bs);
+ int max_len = s->serial ? 20 : 255 - 8;
+ int id_len = strlen(str);
if (id_len > max_len) {
id_len = max_len;
@@ -486,7 +487,7 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf)
outbuf[buflen++] = 0; // reserved
outbuf[buflen++] = id_len; // length of data following
- memcpy(outbuf+buflen, bdrv_get_device_name(s->qdev.conf.bs), id_len);
+ memcpy(outbuf+buflen, str, id_len);
buflen += id_len;
break;
}
@@ -1152,9 +1153,7 @@ static int scsi_disk_emulate_command(SCSIDiskReq *r)
outbuf = r->iov.iov_base;
switch (req->cmd.buf[0]) {
case TEST_UNIT_READY:
- if (s->tray_open || !bdrv_is_inserted(s->qdev.conf.bs)) {
- goto not_ready;
- }
+ assert(!s->tray_open && bdrv_is_inserted(s->qdev.conf.bs));
break;
case INQUIRY:
buflen = scsi_disk_emulate_inquiry(req, outbuf);
@@ -1209,7 +1208,8 @@ static int scsi_disk_emulate_command(SCSIDiskReq *r)
memset(outbuf, 0, 8);
bdrv_get_geometry(s->qdev.conf.bs, &nb_sectors);
if (!nb_sectors) {
- goto not_ready;
+ scsi_check_condition(r, SENSE_CODE(LUN_NOT_READY));
+ return -1;
}
if ((req->cmd.buf[8] & 1) == 0 && req->cmd.lba) {
goto illegal_request;
@@ -1269,7 +1269,8 @@ static int scsi_disk_emulate_command(SCSIDiskReq *r)
memset(outbuf, 0, req->cmd.xfer);
bdrv_get_geometry(s->qdev.conf.bs, &nb_sectors);
if (!nb_sectors) {
- goto not_ready;
+ scsi_check_condition(r, SENSE_CODE(LUN_NOT_READY));
+ return -1;
}
if ((req->cmd.buf[14] & 1) == 0 && req->cmd.lba) {
goto illegal_request;
@@ -1314,14 +1315,6 @@ static int scsi_disk_emulate_command(SCSIDiskReq *r)
buflen = MIN(buflen, req->cmd.xfer);
return buflen;
-not_ready:
- if (s->tray_open || !bdrv_is_inserted(s->qdev.conf.bs)) {
- scsi_check_condition(r, SENSE_CODE(NO_MEDIUM));
- } else {
- scsi_check_condition(r, SENSE_CODE(LUN_NOT_READY));
- }
- return -1;
-
illegal_request:
if (r->req.status == -1) {
scsi_check_condition(r, SENSE_CODE(INVALID_FIELD));
@@ -1356,6 +1349,30 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t *buf)
#endif
switch (command) {
+ case INQUIRY:
+ case MODE_SENSE:
+ case MODE_SENSE_10:
+ case RESERVE:
+ case RESERVE_10:
+ case RELEASE:
+ case RELEASE_10:
+ case START_STOP:
+ case ALLOW_MEDIUM_REMOVAL:
+ case GET_CONFIGURATION:
+ case GET_EVENT_STATUS_NOTIFICATION:
+ case MECHANISM_STATUS:
+ case REQUEST_SENSE:
+ break;
+
+ default:
+ if (s->tray_open || !bdrv_is_inserted(s->qdev.conf.bs)) {
+ scsi_check_condition(r, SENSE_CODE(NO_MEDIUM));
+ return 0;
+ }
+ break;
+ }
+
+ switch (command) {
case TEST_UNIT_READY:
case INQUIRY:
case MODE_SENSE:
diff --git a/hw/serial.c b/hw/serial.c
index c0ee55d20c..a421d1e7bc 100644
--- a/hw/serial.c
+++ b/hw/serial.c
@@ -327,9 +327,12 @@ static void serial_xmit(void *opaque)
s->tsr = fifo_get(s,XMIT_FIFO);
if (!s->xmit_fifo.count)
s->lsr |= UART_LSR_THRE;
+ } else if ((s->lsr & UART_LSR_THRE)) {
+ return;
} else {
s->tsr = s->thr;
s->lsr |= UART_LSR_THRE;
+ s->lsr &= ~UART_LSR_TEMT;
}
}
@@ -337,7 +340,7 @@ static void serial_xmit(void *opaque)
/* in loopback mode, say that we just received a char */
serial_receive1(s, &s->tsr, 1);
} else if (qemu_chr_fe_write(s->chr, &s->tsr, 1) != 1) {
- if ((s->tsr_retry > 0) && (s->tsr_retry <= MAX_XMIT_RETRY)) {
+ if ((s->tsr_retry >= 0) && (s->tsr_retry <= MAX_XMIT_RETRY)) {
s->tsr_retry++;
qemu_mod_timer(s->transmit_timer, new_xmit_ts + s->char_transmit_time);
return;
diff --git a/hw/strongarm.c b/hw/strongarm.c
index 4d5b60fd1f..1b15f399f1 100644
--- a/hw/strongarm.c
+++ b/hw/strongarm.c
@@ -255,7 +255,7 @@ static inline void strongarm_rtc_int_update(StrongARMRTCState *s)
static void strongarm_rtc_hzupdate(StrongARMRTCState *s)
{
- int64_t rt = qemu_get_clock_ms(rt_clock);
+ int64_t rt = qemu_get_clock_ms(rtc_clock);
s->last_rcnr += ((rt - s->last_hz) << 15) /
(1000 * ((s->rttr & 0xffff) + 1));
s->last_hz = rt;
@@ -308,7 +308,7 @@ static uint64_t strongarm_rtc_read(void *opaque, target_phys_addr_t addr,
return s->rtar;
case RCNR:
return s->last_rcnr +
- ((qemu_get_clock_ms(rt_clock) - s->last_hz) << 15) /
+ ((qemu_get_clock_ms(rtc_clock) - s->last_hz) << 15) /
(1000 * ((s->rttr & 0xffff) + 1));
default:
printf("%s: Bad register 0x" TARGET_FMT_plx "\n", __func__, addr);
@@ -374,10 +374,10 @@ static int strongarm_rtc_init(SysBusDevice *dev)
qemu_get_timedate(&tm, 0);
s->last_rcnr = (uint32_t) mktimegm(&tm);
- s->last_hz = qemu_get_clock_ms(rt_clock);
+ s->last_hz = qemu_get_clock_ms(rtc_clock);
- s->rtc_alarm = qemu_new_timer_ms(rt_clock, strongarm_rtc_alarm_tick, s);
- s->rtc_hz = qemu_new_timer_ms(rt_clock, strongarm_rtc_hz_tick, s);
+ s->rtc_alarm = qemu_new_timer_ms(rtc_clock, strongarm_rtc_alarm_tick, s);
+ s->rtc_hz = qemu_new_timer_ms(rtc_clock, strongarm_rtc_hz_tick, s);
sysbus_init_irq(dev, &s->rtc_irq);
sysbus_init_irq(dev, &s->rtc_hz_irq);
diff --git a/hw/sun4m.c b/hw/sun4m.c
index 7bcbf37e98..34088ad185 100644
--- a/hw/sun4m.c
+++ b/hw/sun4m.c
@@ -932,8 +932,8 @@ static void sun4m_hw_init(const struct sun4m_hwdef *hwdef, ram_addr_t RAM_size,
slavio_serial_ms_kbd_init(hwdef->ms_kb_base, slavio_irq[14],
display_type == DT_NOGRAPHIC, ESCC_CLOCK, 1);
- // Slavio TTYA (base+4, Linux ttyS0) is the first Qemu serial device
- // Slavio TTYB (base+0, Linux ttyS1) is the second Qemu serial device
+ /* Slavio TTYA (base+4, Linux ttyS0) is the first QEMU serial device
+ Slavio TTYB (base+0, Linux ttyS1) is the second QEMU serial device */
escc_init(hwdef->serial_base, slavio_irq[15], slavio_irq[15],
serial_hds[0], serial_hds[1], ESCC_CLOCK, 1);
@@ -1581,8 +1581,8 @@ static void sun4d_hw_init(const struct sun4d_hwdef *hwdef, ram_addr_t RAM_size,
slavio_serial_ms_kbd_init(hwdef->ms_kb_base, sbi_irq[12],
display_type == DT_NOGRAPHIC, ESCC_CLOCK, 1);
- // Slavio TTYA (base+4, Linux ttyS0) is the first Qemu serial device
- // Slavio TTYB (base+0, Linux ttyS1) is the second Qemu serial device
+ /* Slavio TTYA (base+4, Linux ttyS0) is the first QEMU serial device
+ Slavio TTYB (base+0, Linux ttyS1) is the second QEMU serial device */
escc_init(hwdef->serial_base, sbi_irq[12], sbi_irq[12],
serial_hds[0], serial_hds[1], ESCC_CLOCK, 1);
@@ -1762,8 +1762,8 @@ static void sun4c_hw_init(const struct sun4c_hwdef *hwdef, ram_addr_t RAM_size,
slavio_serial_ms_kbd_init(hwdef->ms_kb_base, slavio_irq[1],
display_type == DT_NOGRAPHIC, ESCC_CLOCK, 1);
- // Slavio TTYA (base+4, Linux ttyS0) is the first Qemu serial device
- // Slavio TTYB (base+0, Linux ttyS1) is the second Qemu serial device
+ /* Slavio TTYA (base+4, Linux ttyS0) is the first QEMU serial device
+ Slavio TTYB (base+0, Linux ttyS1) is the second QEMU serial device */
escc_init(hwdef->serial_base, slavio_irq[1],
slavio_irq[1], serial_hds[0], serial_hds[1],
ESCC_CLOCK, 1);
diff --git a/hw/sun4u.c b/hw/sun4u.c
index 237e20c1bf..fe3313890d 100644
--- a/hw/sun4u.c
+++ b/hw/sun4u.c
@@ -248,6 +248,10 @@ void cpu_check_irqs(CPUSPARCState *env)
uint32_t pil = env->pil_in |
(env->softint & ~(SOFTINT_TIMER | SOFTINT_STIMER));
+ /* TT_IVEC has a higher priority (16) than TT_EXTINT (31..17) */
+ if (env->ivec_status & 0x20) {
+ return;
+ }
/* check if TM or SM in SOFTINT are set
setting these also causes interrupt 14 */
if (env->softint & (SOFTINT_TIMER | SOFTINT_STIMER)) {
@@ -275,7 +279,8 @@ void cpu_check_irqs(CPUSPARCState *env)
int old_interrupt = env->interrupt_index;
int new_interrupt = TT_EXTINT | i;
- if (env->tl > 0 && cpu_tsptr(env)->tt > new_interrupt) {
+ if (unlikely(env->tl > 0 && cpu_tsptr(env)->tt > new_interrupt
+ && ((cpu_tsptr(env)->tt & 0x1f0) == TT_EXTINT))) {
CPUIRQ_DPRINTF("Not setting CPU IRQ: TL=%d "
"current %x >= pending %x\n",
env->tl, cpu_tsptr(env)->tt, new_interrupt);
@@ -309,19 +314,22 @@ static void cpu_set_ivec_irq(void *opaque, int irq, int level)
CPUSPARCState *env = opaque;
if (level) {
- CPUIRQ_DPRINTF("Raise IVEC IRQ %d\n", irq);
- env->interrupt_index = TT_IVEC;
- env->pil_in |= 1 << 5;
- env->ivec_status |= 0x20;
- env->ivec_data[0] = (0x1f << 6) | irq;
- env->ivec_data[1] = 0;
- env->ivec_data[2] = 0;
- cpu_interrupt(env, CPU_INTERRUPT_HARD);
- } else {
- CPUIRQ_DPRINTF("Lower IVEC IRQ %d\n", irq);
- env->pil_in &= ~(1 << 5);
- env->ivec_status &= ~0x20;
- cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
+ if (!(env->ivec_status & 0x20)) {
+ CPUIRQ_DPRINTF("Raise IVEC IRQ %d\n", irq);
+ env->halted = 0;
+ env->interrupt_index = TT_IVEC;
+ env->ivec_status |= 0x20;
+ env->ivec_data[0] = (0x1f << 6) | irq;
+ env->ivec_data[1] = 0;
+ env->ivec_data[2] = 0;
+ cpu_interrupt(env, CPU_INTERRUPT_HARD);
+ }
+ } else {
+ if (env->ivec_status & 0x20) {
+ CPUIRQ_DPRINTF("Lower IVEC IRQ %d\n", irq);
+ env->ivec_status &= ~0x20;
+ cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
+ }
}
}
diff --git a/hw/twl92230.c b/hw/twl92230.c
index 22da6f8001..0d70d8498d 100644
--- a/hw/twl92230.c
+++ b/hw/twl92230.c
@@ -22,6 +22,7 @@
#include "hw.h"
#include "qemu-timer.h"
#include "i2c.h"
+#include "sysemu.h"
#include "console.h"
#define VERBOSE 1
@@ -71,14 +72,14 @@ static inline void menelaus_update(MenelausState *s)
static inline void menelaus_rtc_start(MenelausState *s)
{
- s->rtc.next += qemu_get_clock_ms(rt_clock);
+ s->rtc.next += qemu_get_clock_ms(rtc_clock);
qemu_mod_timer(s->rtc.hz_tm, s->rtc.next);
}
static inline void menelaus_rtc_stop(MenelausState *s)
{
qemu_del_timer(s->rtc.hz_tm);
- s->rtc.next -= qemu_get_clock_ms(rt_clock);
+ s->rtc.next -= qemu_get_clock_ms(rtc_clock);
if (s->rtc.next < 1)
s->rtc.next = 1;
}
@@ -781,7 +782,7 @@ static void menelaus_pre_save(void *opaque)
{
MenelausState *s = opaque;
/* Should be <= 1000 */
- s->rtc_next_vmstate = s->rtc.next - qemu_get_clock_ms(rt_clock);
+ s->rtc_next_vmstate = s->rtc.next - qemu_get_clock_ms(rtc_clock);
}
static int menelaus_post_load(void *opaque, int version_id)
@@ -842,7 +843,7 @@ static int twl92230_init(I2CSlave *i2c)
{
MenelausState *s = FROM_I2C_SLAVE(MenelausState, i2c);
- s->rtc.hz_tm = qemu_new_timer_ms(rt_clock, menelaus_rtc_hz, s);
+ s->rtc.hz_tm = qemu_new_timer_ms(rtc_clock, menelaus_rtc_hz, s);
/* Three output pins plus one interrupt pin. */
qdev_init_gpio_out(&i2c->qdev, s->out, 4);
diff --git a/hw/vga.c b/hw/vga.c
index 6dc98f6c2a..f80860caed 100644
--- a/hw/vga.c
+++ b/hw/vga.c
@@ -2415,7 +2415,7 @@ static void vga_screen_dump(void *opaque, const char *filename, bool cswitch)
if (cswitch) {
vga_invalidate_display(s);
- vga_hw_update();
}
+ vga_hw_update();
ppm_save(filename, s->ds->surface);
}
diff --git a/hw/virtio-scsi.c b/hw/virtio-scsi.c
index e607edc915..45d54faeb5 100644
--- a/hw/virtio-scsi.c
+++ b/hw/virtio-scsi.c
@@ -613,5 +613,7 @@ VirtIODevice *virtio_scsi_init(DeviceState *dev, VirtIOSCSIConf *proxyconf)
void virtio_scsi_exit(VirtIODevice *vdev)
{
+ VirtIOSCSI *s = (VirtIOSCSI *)vdev;
+ unregister_savevm(s->qdev, "virtio-scsi", s);
virtio_cleanup(vdev);
}
diff --git a/hw/xen_console.c b/hw/xen_console.c
index edcb31ce66..3794b1972d 100644
--- a/hw/xen_console.c
+++ b/hw/xen_console.c
@@ -248,6 +248,9 @@ static void con_disconnect(struct XenDevice *xendev)
{
struct XenConsole *con = container_of(xendev, struct XenConsole, xendev);
+ if (!xendev->dev) {
+ return;
+ }
if (con->chr)
qemu_chr_add_handlers(con->chr, NULL, NULL, NULL, NULL);
xen_be_unbind_evtchn(&con->xendev);
diff --git a/hw/xen_disk.c b/hw/xen_disk.c
index 68fa36a1cf..9719395b09 100644
--- a/hw/xen_disk.c
+++ b/hw/xen_disk.c
@@ -330,6 +330,9 @@ static void qemu_aio_complete(void *opaque, int ret)
if (ioreq->aio_inflight > 0) {
return;
}
+ if (ioreq->postsync) {
+ bdrv_flush(ioreq->blkdev->bs);
+ }
ioreq->status = ioreq->aio_errors ? BLKIF_RSP_ERROR : BLKIF_RSP_OKAY;
ioreq_unmap(ioreq);
@@ -376,9 +379,6 @@ static int ioreq_runio_qemu_aio(struct ioreq *ioreq)
goto err;
}
- if (ioreq->postsync) {
- bdrv_flush(blkdev->bs); /* FIXME: aio_flush() ??? */
- }
qemu_aio_complete(ioreq, 0);
return 0;
@@ -584,10 +584,10 @@ static int blk_init(struct XenDevice *xendev)
}
/* read-only ? */
+ qflags = BDRV_O_NOCACHE | BDRV_O_CACHE_WB | BDRV_O_NATIVE_AIO;
if (strcmp(blkdev->mode, "w") == 0) {
- qflags = BDRV_O_RDWR;
+ qflags |= BDRV_O_RDWR;
} else {
- qflags = 0;
info |= VDISK_READONLY;
}
@@ -726,6 +726,7 @@ static void blk_disconnect(struct XenDevice *xendev)
if (!blkdev->dinfo) {
/* close/delete only if we created it ourself */
bdrv_close(blkdev->bs);
+ bdrv_detach_dev(blkdev->bs, blkdev);
bdrv_delete(blkdev->bs);
}
blkdev->bs = NULL;