mirror of https://gitee.com/openkylin/qemu.git
cirrus: bugfixes, with some vga cleanups.
-----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.22 (GNU/Linux) iQIcBAABAgAGBQJZ5b5FAAoJEEy22O7T6HE4UugQAK1Y4PabCrOGFs1FYe/tCCvf kMLa7iWRoXWE9gPMArHQ4XURC6sZ54g+MOGZFWp7VdHTdkXsID8BDB60G2h0P5Gg IZxSrw+7k1u7plc/LzjFfwryGsAEm6Buj2FbA79XvMUr+6IS8MH2UpsrP5KJbqsQ 19a0GIYRly92UOmfdiKBH5lZ5XAv2BlPihUFB7gNesZmoQd11opQIwdTixFY9LBs viS5ntrQX1G4rIfuhuyk16TlL+aOX+zk1W0MOoPvASt9s0pv836gJ2dTRkDUHpic 89ORr8QdBE2/ODT9H0aWxKsb/txEKRCuPB+2YIf9JtOCHltCW1sOUdmqcN7jVtU7 rEF6AlF0zTtdRGbzWcEAoXW+FBa9YQtxXtrYNLLkiySE+Wj5BNi0bKRCbRr1APCg pMCruCtp3MYRVZKRVG5WO4Tb1NSoLG5W95iIh5qdGX99bqkJ4hD6R8x/5d6CMVR2 q5iiO1HjOzAkWjhFEbq2NhvSaxaZeGt/Dm6cL/p8hBPSiZzkeJ1AqfvzjOjez3pJ G0MBHkD8o53cdDMrjnwl1zv2pq5aR//4FR1XffpSTeziWpnzu/nxSNIN5oKS3FJ3 4AsePk4CA29Wq4QJUZzf+LgQZIRRBRLhTIuIUL9izq6BRA2QAyCF5QPvxed1jAQ+ HjRYrQEbbY7VPFpZa70T =hdje -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/kraxel/tags/vga-20171017-pull-request' into staging cirrus: bugfixes, with some vga cleanups. # gpg: Signature made Tue 17 Oct 2017 09:24:37 BST # gpg: using RSA key 0x4CB6D8EED3E87138 # gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>" # gpg: aka "Gerd Hoffmann <gerd@kraxel.org>" # gpg: aka "Gerd Hoffmann (private) <kraxel@gmail.com>" # Primary key fingerprint: A032 8CFF B93A 17A7 9901 FE7D 4CB6 D8EE D3E8 7138 * remotes/kraxel/tags/vga-20171017-pull-request: cirrus: fix oob access in mode4and5 write functions vga: add ram_addr_t cast vga: handle cirrus vbe mode wraparounds. vga: drop line_offset variable Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
73b733e690
|
@ -2038,15 +2038,14 @@ static void cirrus_mem_writeb_mode4and5_8bpp(CirrusVGAState * s,
|
|||
unsigned val = mem_value;
|
||||
uint8_t *dst;
|
||||
|
||||
dst = s->vga.vram_ptr + (offset &= s->cirrus_addr_mask);
|
||||
for (x = 0; x < 8; x++) {
|
||||
dst = s->vga.vram_ptr + ((offset + x) & s->cirrus_addr_mask);
|
||||
if (val & 0x80) {
|
||||
*dst = s->cirrus_shadow_gr1;
|
||||
} else if (mode == 5) {
|
||||
*dst = s->cirrus_shadow_gr0;
|
||||
}
|
||||
val <<= 1;
|
||||
dst++;
|
||||
}
|
||||
memory_region_set_dirty(&s->vga.vram, offset, 8);
|
||||
}
|
||||
|
@ -2060,8 +2059,8 @@ static void cirrus_mem_writeb_mode4and5_16bpp(CirrusVGAState * s,
|
|||
unsigned val = mem_value;
|
||||
uint8_t *dst;
|
||||
|
||||
dst = s->vga.vram_ptr + (offset &= s->cirrus_addr_mask);
|
||||
for (x = 0; x < 8; x++) {
|
||||
dst = s->vga.vram_ptr + ((offset + 2 * x) & s->cirrus_addr_mask & ~1);
|
||||
if (val & 0x80) {
|
||||
*dst = s->cirrus_shadow_gr1;
|
||||
*(dst + 1) = s->vga.gr[0x11];
|
||||
|
@ -2070,7 +2069,6 @@ static void cirrus_mem_writeb_mode4and5_16bpp(CirrusVGAState * s,
|
|||
*(dst + 1) = s->vga.gr[0x10];
|
||||
}
|
||||
val <<= 1;
|
||||
dst += 2;
|
||||
}
|
||||
memory_region_set_dirty(&s->vga.vram, offset, 16);
|
||||
}
|
||||
|
|
|
@ -1464,14 +1464,14 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
|
|||
{
|
||||
DisplaySurface *surface = qemu_console_surface(s->con);
|
||||
int y1, y, update, linesize, y_start, double_scan, mask, depth;
|
||||
int width, height, shift_control, line_offset, bwidth, bits;
|
||||
ram_addr_t page0, page1;
|
||||
int width, height, shift_control, bwidth, bits;
|
||||
ram_addr_t page0, page1, region_start, region_end;
|
||||
DirtyBitmapSnapshot *snap = NULL;
|
||||
int disp_width, multi_scan, multi_run;
|
||||
uint8_t *d;
|
||||
uint32_t v, addr1, addr;
|
||||
vga_draw_line_func *vga_draw_line = NULL;
|
||||
bool share_surface;
|
||||
bool share_surface, force_shadow = false;
|
||||
pixman_format_code_t format;
|
||||
#ifdef HOST_WORDS_BIGENDIAN
|
||||
bool byteswap = !s->big_endian_fb;
|
||||
|
@ -1484,6 +1484,15 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
|
|||
s->get_resolution(s, &width, &height);
|
||||
disp_width = width;
|
||||
|
||||
region_start = (s->start_addr * 4);
|
||||
region_end = region_start + (ram_addr_t)s->line_offset * height;
|
||||
if (region_end > s->vbe_size) {
|
||||
/* wraps around (can happen with cirrus vbe modes) */
|
||||
region_start = 0;
|
||||
region_end = s->vbe_size;
|
||||
force_shadow = true;
|
||||
}
|
||||
|
||||
shift_control = (s->gr[VGA_GFX_MODE] >> 5) & 3;
|
||||
double_scan = (s->cr[VGA_CRTC_MAX_SCAN] >> 7);
|
||||
if (shift_control != 1) {
|
||||
|
@ -1523,7 +1532,7 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
|
|||
format = qemu_default_pixman_format(depth, !byteswap);
|
||||
if (format) {
|
||||
share_surface = dpy_gfx_check_format(s->con, format)
|
||||
&& !s->force_shadow;
|
||||
&& !s->force_shadow && !force_shadow;
|
||||
} else {
|
||||
share_surface = false;
|
||||
}
|
||||
|
@ -1614,7 +1623,6 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
|
|||
s->cursor_invalidate(s);
|
||||
}
|
||||
|
||||
line_offset = s->line_offset;
|
||||
#if 0
|
||||
printf("w=%d h=%d v=%d line_offset=%d cr[0x09]=0x%02x cr[0x17]=0x%02x linecmp=%d sr[0x01]=0x%02x\n",
|
||||
width, height, v, line_offset, s->cr[9], s->cr[VGA_CRTC_MODE],
|
||||
|
@ -1628,8 +1636,6 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
|
|||
y1 = 0;
|
||||
|
||||
if (!full_update) {
|
||||
ram_addr_t region_start = addr1;
|
||||
ram_addr_t region_end = addr1 + line_offset * height;
|
||||
vga_sync_dirty_bitmap(s);
|
||||
if (s->line_compare < height) {
|
||||
/* split screen mode */
|
||||
|
@ -1652,10 +1658,17 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
|
|||
addr = (addr & ~0x8000) | ((y1 & 2) << 14);
|
||||
}
|
||||
update = full_update;
|
||||
page0 = addr;
|
||||
page1 = addr + bwidth - 1;
|
||||
page0 = addr & s->vbe_size_mask;
|
||||
page1 = (addr + bwidth - 1) & s->vbe_size_mask;
|
||||
if (full_update) {
|
||||
update = 1;
|
||||
} else if (page1 < page0) {
|
||||
/* scanline wraps from end of video memory to the start */
|
||||
assert(force_shadow);
|
||||
update = memory_region_snapshot_get_dirty(&s->vram, snap,
|
||||
page0, 0);
|
||||
update |= memory_region_snapshot_get_dirty(&s->vram, snap,
|
||||
page1, 0);
|
||||
} else {
|
||||
update = memory_region_snapshot_get_dirty(&s->vram, snap,
|
||||
page0, page1 - page0);
|
||||
|
@ -1681,7 +1694,7 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
|
|||
if (!multi_run) {
|
||||
mask = (s->cr[VGA_CRTC_MODE] & 3) ^ 3;
|
||||
if ((y1 & mask) == mask)
|
||||
addr1 += line_offset;
|
||||
addr1 += s->line_offset;
|
||||
y1++;
|
||||
multi_run = multi_scan;
|
||||
} else {
|
||||
|
|
Loading…
Reference in New Issue