From: Stanislav Vorobiov Date: Thu, 20 Feb 2014 07:57:39 +0000 (+0400) Subject: VIGS: Fix fence ack losses X-Git-Tag: Tizen_Studio_1.3_Release_p2.3.1~475^2~17 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=6d87db1464ae32f3408a7f92f511567748dd9567;p=sdk%2Femulator%2Fqemu.git VIGS: Fix fence ack losses It's incorrect to have vblank enable/disable flag in INT register, it can cause fence ack losses, consider the following scenario: 1. Fence interrupt is set on host, fence_pending bit is set in INT register 2. vblank is turned off on guest, INT register is being written to and since fence_pending bit is 1 it's CLEARED on host 3. Now guest handles fence IRQ, but fence_pending bit is 0, thus, fence ack is lost The solution is to have separate register - CON and vblank enable/disable bit should be there Change-Id: I1ff97d4cf8cddaec65dfe9d4c1afef3d901b4825 --- diff --git a/hw/vigs/vigs_device.c b/hw/vigs/vigs_device.c index 0f3944d8ac..7b16d3af52 100644 --- a/hw/vigs/vigs_device.c +++ b/hw/vigs/vigs_device.c @@ -71,6 +71,7 @@ typedef struct VIGSState */ QemuConsole *con; + uint32_t reg_con; uint32_t reg_int; } VIGSState; @@ -82,7 +83,7 @@ static void vigs_update_irq(VIGSState *s) { bool raise = false; - if ((s->reg_int & VIGS_REG_INT_VBLANK_ENABLE) && + if ((s->reg_con & VIGS_REG_CON_VBLANK_ENABLE) && (s->reg_int & VIGS_REG_INT_VBLANK_PENDING)) { raise = true; } @@ -122,7 +123,7 @@ static void vigs_hw_update(void *opaque) dpy_gfx_update(s->con, 0, 0, surface_width(ds), surface_height(ds)); - if (s->reg_int & VIGS_REG_INT_VBLANK_ENABLE) { + if (s->reg_con & VIGS_REG_CON_VBLANK_ENABLE) { s->reg_int |= VIGS_REG_INT_VBLANK_PENDING; vigs_update_irq(s); } @@ -140,8 +141,7 @@ static void vigs_dpy_resize(void *user_data, DisplaySurface *ds = qemu_console_surface(s->con); if ((width != surface_width(ds)) || - (height != surface_height(ds))) - { + (height != surface_height(ds))) { qemu_console_resize(s->con, width, height); } } @@ -186,6 +186,8 @@ static uint64_t vigs_io_read(void *opaque, hwaddr offset, VIGSState *s = opaque; switch (offset) { + case VIGS_REG_CON: + return s->reg_con; case VIGS_REG_INT: return s->reg_int; case VIGS_REG_FENCE_LOWER: @@ -209,6 +211,19 @@ static void vigs_io_write(void *opaque, hwaddr offset, case VIGS_REG_EXEC: vigs_server_dispatch(s->server, value); break; + case VIGS_REG_CON: + if (((s->reg_con & VIGS_REG_CON_VBLANK_ENABLE) == 0) && + (value & VIGS_REG_CON_VBLANK_ENABLE)) { + VIGS_LOG_DEBUG("VBLANK On"); + } else if (((value & VIGS_REG_CON_VBLANK_ENABLE) == 0) && + (s->reg_con & VIGS_REG_CON_VBLANK_ENABLE)) { + VIGS_LOG_DEBUG("VBLANK Off"); + } + + s->reg_con = value & VIGS_REG_CON_MASK; + + vigs_update_irq(s); + break; case VIGS_REG_INT: if (value & VIGS_REG_INT_VBLANK_PENDING) { value &= ~VIGS_REG_INT_VBLANK_PENDING; @@ -222,14 +237,6 @@ static void vigs_io_write(void *opaque, hwaddr offset, value |= (s->reg_int & VIGS_REG_INT_FENCE_ACK_PENDING); } - if (((s->reg_int & VIGS_REG_INT_VBLANK_ENABLE) == 0) && - (value & VIGS_REG_INT_VBLANK_ENABLE)) { - VIGS_LOG_DEBUG("VBLANK On"); - } else if (((value & VIGS_REG_INT_VBLANK_ENABLE) == 0) && - (s->reg_int & VIGS_REG_INT_VBLANK_ENABLE)) { - VIGS_LOG_DEBUG("VBLANK Off"); - } - s->reg_int = value & VIGS_REG_INT_MASK; vigs_update_irq(s); @@ -371,6 +378,7 @@ static void vigs_device_reset(DeviceState *d) pci_set_irq(&s->dev.pci_dev, 0); + s->reg_con = 0; s->reg_int = 0; VIGS_LOG_INFO("VIGS reset"); diff --git a/hw/vigs/vigs_regs.h b/hw/vigs/vigs_regs.h index dd069b3c4c..efcb706456 100644 --- a/hw/vigs/vigs_regs.h +++ b/hw/vigs/vigs_regs.h @@ -31,13 +31,16 @@ #define _QEMU_VIGS_REGS_H #define VIGS_REG_EXEC 0 -#define VIGS_REG_INT 8 -#define VIGS_REG_FENCE_LOWER 16 -#define VIGS_REG_FENCE_UPPER 24 +#define VIGS_REG_CON 8 +#define VIGS_REG_INT 16 +#define VIGS_REG_FENCE_LOWER 24 +#define VIGS_REG_FENCE_UPPER 32 -#define VIGS_REG_INT_MASK 7 -#define VIGS_REG_INT_VBLANK_ENABLE 1 -#define VIGS_REG_INT_VBLANK_PENDING 2 -#define VIGS_REG_INT_FENCE_ACK_PENDING 4 +#define VIGS_REG_CON_MASK 1 +#define VIGS_REG_CON_VBLANK_ENABLE 1 + +#define VIGS_REG_INT_MASK 3 +#define VIGS_REG_INT_VBLANK_PENDING 1 +#define VIGS_REG_INT_FENCE_ACK_PENDING 2 #endif