[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 10/13] ati-vga: Support unaligned access to hardware cursor regist
From: |
Gerd Hoffmann |
Subject: |
[PULL 10/13] ati-vga: Support unaligned access to hardware cursor registers |
Date: |
Wed, 1 Jul 2020 17:04:22 +0200 |
From: BALATON Zoltan <balaton@eik.bme.hu>
This fixes horizontal mouse movement and pointer color with MacOS that
writes these registers with access size less than 4 so previously only
the last portion of access was effective overwriting previous partial
writes.
Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
Message-id:
ba1d5ba97f246e8807f86f1243c2bdc6497dc8f2.1592737958.git.balaton@eik.bme.hu
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
hw/display/ati.c | 85 ++++++++++++++++++++++++++++++++----------------
1 file changed, 57 insertions(+), 28 deletions(-)
diff --git a/hw/display/ati.c b/hw/display/ati.c
index 7216f7e08f87..245130d52f33 100644
--- a/hw/display/ati.c
+++ b/hw/display/ati.c
@@ -389,22 +389,28 @@ static uint64_t ati_mm_read(void *opaque, hwaddr addr,
unsigned int size)
case 0xf00 ... 0xfff:
val = pci_default_read_config(&s->dev, addr - 0xf00, size);
break;
- case CUR_OFFSET:
- val = s->regs.cur_offset;
+ case CUR_OFFSET ... CUR_OFFSET + 3:
+ val = ati_reg_read_offs(s->regs.cur_offset, addr - CUR_OFFSET, size);
break;
- case CUR_HORZ_VERT_POSN:
- val = s->regs.cur_hv_pos;
- val |= s->regs.cur_offset & BIT(31);
+ case CUR_HORZ_VERT_POSN ... CUR_HORZ_VERT_POSN + 3:
+ val = ati_reg_read_offs(s->regs.cur_hv_pos,
+ addr - CUR_HORZ_VERT_POSN, size);
+ if (addr + size > CUR_HORZ_VERT_POSN + 3) {
+ val |= (s->regs.cur_offset & BIT(31)) >> (4 - size);
+ }
break;
- case CUR_HORZ_VERT_OFF:
- val = s->regs.cur_hv_offs;
- val |= s->regs.cur_offset & BIT(31);
+ case CUR_HORZ_VERT_OFF ... CUR_HORZ_VERT_OFF + 3:
+ val = ati_reg_read_offs(s->regs.cur_hv_offs,
+ addr - CUR_HORZ_VERT_OFF, size);
+ if (addr + size > CUR_HORZ_VERT_OFF + 3) {
+ val |= (s->regs.cur_offset & BIT(31)) >> (4 - size);
+ }
break;
- case CUR_CLR0:
- val = s->regs.cur_color0;
+ case CUR_CLR0 ... CUR_CLR0 + 3:
+ val = ati_reg_read_offs(s->regs.cur_color0, addr - CUR_CLR0, size);
break;
- case CUR_CLR1:
- val = s->regs.cur_color1;
+ case CUR_CLR1 ... CUR_CLR1 + 3:
+ val = ati_reg_read_offs(s->regs.cur_color1, addr - CUR_CLR1, size);
break;
case DST_OFFSET:
val = s->regs.dst_offset;
@@ -679,48 +685,71 @@ static void ati_mm_write(void *opaque, hwaddr addr,
case 0xf00 ... 0xfff:
/* read-only copy of PCI config space so ignore writes */
break;
- case CUR_OFFSET:
- if (s->regs.cur_offset != (data & 0x87fffff0)) {
- s->regs.cur_offset = data & 0x87fffff0;
+ case CUR_OFFSET ... CUR_OFFSET + 3:
+ {
+ uint32_t t = s->regs.cur_offset;
+
+ ati_reg_write_offs(&t, addr - CUR_OFFSET, data, size);
+ t &= 0x87fffff0;
+ if (s->regs.cur_offset != t) {
+ s->regs.cur_offset = t;
ati_cursor_define(s);
}
break;
- case CUR_HORZ_VERT_POSN:
- s->regs.cur_hv_pos = data & 0x3fff0fff;
- if (data & BIT(31)) {
- s->regs.cur_offset |= data & BIT(31);
+ }
+ case CUR_HORZ_VERT_POSN ... CUR_HORZ_VERT_POSN + 3:
+ {
+ uint32_t t = s->regs.cur_hv_pos | (s->regs.cur_offset & BIT(31));
+
+ ati_reg_write_offs(&t, addr - CUR_HORZ_VERT_POSN, data, size);
+ s->regs.cur_hv_pos = t & 0x3fff0fff;
+ if (t & BIT(31)) {
+ s->regs.cur_offset |= t & BIT(31);
} else if (s->regs.cur_offset & BIT(31)) {
s->regs.cur_offset &= ~BIT(31);
ati_cursor_define(s);
}
if (!s->cursor_guest_mode &&
- (s->regs.crtc_gen_cntl & CRTC2_CUR_EN) && !(data & BIT(31))) {
+ (s->regs.crtc_gen_cntl & CRTC2_CUR_EN) && !(t & BIT(31))) {
dpy_mouse_set(s->vga.con, s->regs.cur_hv_pos >> 16,
s->regs.cur_hv_pos & 0xffff, 1);
}
break;
+ }
case CUR_HORZ_VERT_OFF:
- s->regs.cur_hv_offs = data & 0x3f003f;
- if (data & BIT(31)) {
- s->regs.cur_offset |= data & BIT(31);
+ {
+ uint32_t t = s->regs.cur_hv_offs | (s->regs.cur_offset & BIT(31));
+
+ ati_reg_write_offs(&t, addr - CUR_HORZ_VERT_OFF, data, size);
+ s->regs.cur_hv_offs = t & 0x3f003f;
+ if (t & BIT(31)) {
+ s->regs.cur_offset |= t & BIT(31);
} else if (s->regs.cur_offset & BIT(31)) {
s->regs.cur_offset &= ~BIT(31);
ati_cursor_define(s);
}
break;
- case CUR_CLR0:
- if (s->regs.cur_color0 != (data & 0xffffff)) {
- s->regs.cur_color0 = data & 0xffffff;
+ }
+ case CUR_CLR0 ... CUR_CLR0 + 3:
+ {
+ uint32_t t = s->regs.cur_color0;
+
+ ati_reg_write_offs(&t, addr - CUR_CLR0, data, size);
+ t &= 0xffffff;
+ if (s->regs.cur_color0 != t) {
+ s->regs.cur_color0 = t;
ati_cursor_define(s);
}
break;
- case CUR_CLR1:
+ }
+ case CUR_CLR1 ... CUR_CLR1 + 3:
/*
* Update cursor unconditionally here because some clients set up
* other registers before actually writing cursor data to memory at
* offset so we would miss cursor change unless always updating here
*/
- s->regs.cur_color1 = data & 0xffffff;
+ ati_reg_write_offs(&s->regs.cur_color1, addr - CUR_CLR1, data, size);
+ s->regs.cur_color1 &= 0xffffff;
ati_cursor_define(s);
break;
case DST_OFFSET:
--
2.18.4
- [PULL 00/13] Vga 20200701 patches, Gerd Hoffmann, 2020/07/01
- [PULL 01/13] sm501: Fix bounds checks, Gerd Hoffmann, 2020/07/01
- [PULL 13/13] configure: vgabios cleanups, Gerd Hoffmann, 2020/07/01
- [PULL 03/13] sm501: Ignore no-op blits, Gerd Hoffmann, 2020/07/01
- [PULL 06/13] sm501: Use stn_he_p/ldn_he_p instead of switch/case, Gerd Hoffmann, 2020/07/01
- [PULL 09/13] sm501: Fix and optimize overlap check, Gerd Hoffmann, 2020/07/01
- [PULL 10/13] ati-vga: Support unaligned access to hardware cursor registers,
Gerd Hoffmann <=
- [PULL 04/13] sm501: Introduce variable for commonly used value for better readability, Gerd Hoffmann, 2020/07/01
- [PULL 08/13] sm501: Convert debug printfs to traces, Gerd Hoffmann, 2020/07/01
- [PULL 02/13] sm501: Drop unneded variable, Gerd Hoffmann, 2020/07/01
- [PULL 12/13] ati-vga: Add dummy MEM_SDRAM_MODE_REG, Gerd Hoffmann, 2020/07/01
- [PULL 11/13] ati-vga: Do not assert on error, Gerd Hoffmann, 2020/07/01
- [PULL 07/13] sm501: Do not allow guest to set invalid format, Gerd Hoffmann, 2020/07/01
- [PULL 05/13] sm501: Optimise 1 pixel 2d ops, Gerd Hoffmann, 2020/07/01
- Re: [PULL 00/13] Vga 20200701 patches, Peter Maydell, 2020/07/02