aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2020-07-02 12:27:01 +0100
committerPeter Maydell <peter.maydell@linaro.org>2020-07-02 12:27:01 +0100
commitd0c8b957ae648f67e3ccb5a14e1edc4ae0bea5db (patch)
tree7f75da7895879436bf21701d2c62147cff6f41cc /hw
parentfc1bff958998910ec8d25db86cd2f53ff125f7ab (diff)
parent8db2a4fd8abf6550479f7a8caa8f655c34238d6a (diff)
downloadqemu-d0c8b957ae648f67e3ccb5a14e1edc4ae0bea5db.zip
qemu-d0c8b957ae648f67e3ccb5a14e1edc4ae0bea5db.tar.gz
qemu-d0c8b957ae648f67e3ccb5a14e1edc4ae0bea5db.tar.bz2
Merge remote-tracking branch 'remotes/kraxel/tags/vga-20200701-pull-request' into staging
vga: bugfixes for ati and sm501, vgabios cleanup. # gpg: Signature made Wed 01 Jul 2020 16:03:48 BST # gpg: using RSA key 4CB6D8EED3E87138 # gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>" [full] # gpg: aka "Gerd Hoffmann <gerd@kraxel.org>" [full] # gpg: aka "Gerd Hoffmann (private) <kraxel@gmail.com>" [full] # Primary key fingerprint: A032 8CFF B93A 17A7 9901 FE7D 4CB6 D8EE D3E8 7138 * remotes/kraxel/tags/vga-20200701-pull-request: configure: vgabios cleanups ati-vga: Add dummy MEM_SDRAM_MODE_REG ati-vga: Do not assert on error ati-vga: Support unaligned access to hardware cursor registers sm501: Fix and optimize overlap check sm501: Convert debug printfs to traces sm501: Do not allow guest to set invalid format sm501: Use stn_he_p/ldn_he_p instead of switch/case sm501: Optimise 1 pixel 2d ops sm501: Introduce variable for commonly used value for better readability sm501: Ignore no-op blits sm501: Drop unneded variable sm501: Fix bounds checks Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw')
-rw-r--r--hw/display/ati.c92
-rw-r--r--hw/display/ati_dbg.c1
-rw-r--r--hw/display/ati_regs.h1
-rw-r--r--hw/display/sm501.c157
-rw-r--r--hw/display/trace-events12
5 files changed, 152 insertions, 111 deletions
diff --git a/hw/display/ati.c b/hw/display/ati.c
index 7216f7e..4c3ad8f 100644
--- a/hw/display/ati.c
+++ b/hw/display/ati.c
@@ -86,8 +86,8 @@ static void ati_vga_switch_mode(ATIVGAState *s)
break;
default:
qemu_log_mask(LOG_UNIMP, "Unsupported bpp value\n");
+ return;
}
- assert(bpp != 0);
DPRINTF("Switching to %dx%d %d %d @ %x\n", h, v, stride, bpp, offs);
vbe_ioport_write_index(&s->vga, 0, VBE_DISPI_INDEX_ENABLE);
vbe_ioport_write_data(&s->vga, 0, VBE_DISPI_DISABLED);
@@ -361,6 +361,11 @@ static uint64_t ati_mm_read(void *opaque, hwaddr addr, unsigned int size)
case MC_STATUS:
val = 5;
break;
+ case MEM_SDRAM_MODE_REG:
+ if (s->dev_id != PCI_DEVICE_ID_ATI_RAGE128_PF) {
+ val = BIT(28) | BIT(20);
+ }
+ break;
case RBBM_STATUS:
case GUI_STAT:
val = 64; /* free CMDFIFO entries */
@@ -389,22 +394,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 +690,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:
diff --git a/hw/display/ati_dbg.c b/hw/display/ati_dbg.c
index 0ebbd36..bd0ecd4 100644
--- a/hw/display/ati_dbg.c
+++ b/hw/display/ati_dbg.c
@@ -42,6 +42,7 @@ static struct ati_regdesc ati_reg_names[] = {
{"MC_FB_LOCATION", 0x0148},
{"MC_AGP_LOCATION", 0x014C},
{"MC_STATUS", 0x0150},
+ {"MEM_SDRAM_MODE_REG", 0x0158},
{"MEM_POWER_MISC", 0x015c},
{"AGP_BASE", 0x0170},
{"AGP_CNTL", 0x0174},
diff --git a/hw/display/ati_regs.h b/hw/display/ati_regs.h
index ebd37ee..d6282b2 100644
--- a/hw/display/ati_regs.h
+++ b/hw/display/ati_regs.h
@@ -60,6 +60,7 @@
#define MC_FB_LOCATION 0x0148
#define MC_AGP_LOCATION 0x014C
#define MC_STATUS 0x0150
+#define MEM_SDRAM_MODE_REG 0x0158
#define MEM_POWER_MISC 0x015c
#define AGP_BASE 0x0170
#define AGP_CNTL 0x0174
diff --git a/hw/display/sm501.c b/hw/display/sm501.c
index a7fc08c..9cccc68 100644
--- a/hw/display/sm501.c
+++ b/hw/display/sm501.c
@@ -39,15 +39,7 @@
#include "qemu/range.h"
#include "ui/pixel_ops.h"
#include "qemu/bswap.h"
-
-/*#define DEBUG_SM501*/
-/*#define DEBUG_BITBLT*/
-
-#ifdef DEBUG_SM501
-#define SM501_DPRINTF(fmt, ...) printf(fmt, ## __VA_ARGS__)
-#else
-#define SM501_DPRINTF(fmt, ...) do {} while (0)
-#endif
+#include "trace.h"
#define MMIO_BASE_OFFSET 0x3e00000
#define MMIO_SIZE 0x200000
@@ -684,10 +676,11 @@ static void sm501_2d_operation(SM501State *s)
{
int cmd = (s->twoD_control >> 16) & 0x1F;
int rtl = s->twoD_control & BIT(27);
- int format = (s->twoD_stretch >> 20) & 0x3;
- int rop_mode = (s->twoD_control >> 15) & 0x1; /* 1 for rop2, else rop3 */
+ int format = (s->twoD_stretch >> 20) & 3;
+ int bypp = 1 << format; /* bytes per pixel */
+ int rop_mode = (s->twoD_control >> 15) & 1; /* 1 for rop2, else rop3 */
/* 1 if rop2 source is the pattern, otherwise the source is the bitmap */
- int rop2_source_is_pattern = (s->twoD_control >> 14) & 0x1;
+ int rop2_source_is_pattern = (s->twoD_control >> 14) & 1;
int rop = s->twoD_control & 0xFF;
unsigned int dst_x = (s->twoD_destination >> 16) & 0x01FFF;
unsigned int dst_y = s->twoD_destination & 0xFFFF;
@@ -697,6 +690,7 @@ static void sm501_2d_operation(SM501State *s)
unsigned int dst_pitch = (s->twoD_pitch >> 16) & 0x1FFF;
int crt = (s->dc_crt_control & SM501_DC_CRT_CONTROL_SEL) ? 1 : 0;
int fb_len = get_width(s, crt) * get_height(s, crt) * get_bpp(s, crt);
+ bool overlap = false;
if ((s->twoD_stretch >> 16) & 0xF) {
qemu_log_mask(LOG_UNIMP, "sm501: only XY addressing is supported.\n");
@@ -723,9 +717,9 @@ static void sm501_2d_operation(SM501State *s)
dst_y -= height - 1;
}
- if (dst_base >= get_local_mem_size(s) || dst_base +
- (dst_x + width + (dst_y + height) * (dst_pitch + width)) *
- (1 << format) >= get_local_mem_size(s)) {
+ if (dst_base >= get_local_mem_size(s) ||
+ dst_base + (dst_x + width + (dst_y + height) * dst_pitch) * bypp >=
+ get_local_mem_size(s)) {
qemu_log_mask(LOG_GUEST_ERROR, "sm501: 2D op dest is outside vram.\n");
return;
}
@@ -749,9 +743,9 @@ static void sm501_2d_operation(SM501State *s)
src_y -= height - 1;
}
- if (src_base >= get_local_mem_size(s) || src_base +
- (src_x + width + (src_y + height) * (src_pitch + width)) *
- (1 << format) >= get_local_mem_size(s)) {
+ if (src_base >= get_local_mem_size(s) ||
+ src_base + (src_x + width + (src_y + height) * src_pitch) * bypp >=
+ get_local_mem_size(s)) {
qemu_log_mask(LOG_GUEST_ERROR,
"sm501: 2D op src is outside vram.\n");
return;
@@ -763,19 +757,9 @@ static void sm501_2d_operation(SM501State *s)
uint8_t *d = s->local_mem + dst_base;
for (y = 0; y < height; y++) {
- i = (dst_x + (dst_y + y) * dst_pitch) * (1 << format);
- for (x = 0; x < width; x++, i += (1 << format)) {
- switch (format) {
- case 0:
- d[i] = ~d[i];
- break;
- case 1:
- *(uint16_t *)&d[i] = ~*(uint16_t *)&d[i];
- break;
- case 2:
- *(uint32_t *)&d[i] = ~*(uint32_t *)&d[i];
- break;
- }
+ i = (dst_x + (dst_y + y) * dst_pitch) * bypp;
+ for (x = 0; x < width; x++, i += bypp) {
+ stn_he_p(&d[i], bypp, ~ldn_he_p(&d[i], bypp));
}
}
} else {
@@ -788,40 +772,57 @@ static void sm501_2d_operation(SM501State *s)
(rop2_source_is_pattern ?
" with pattern source" : ""));
}
- /* Check for overlaps, this could be made more exact */
- uint32_t sb, se, db, de;
- sb = src_base + src_x + src_y * (width + src_pitch);
- se = sb + width + height * (width + src_pitch);
- db = dst_base + dst_x + dst_y * (width + dst_pitch);
- de = db + width + height * (width + dst_pitch);
- if (rtl && ((db >= sb && db <= se) || (de >= sb && de <= se))) {
- /* regions may overlap: copy via temporary */
- int free_buf = 0, llb = width * (1 << format);
- int tmp_stride = DIV_ROUND_UP(llb, sizeof(uint32_t));
+ /* Ignore no-op blits, some guests seem to do this */
+ if (src_base == dst_base && src_pitch == dst_pitch &&
+ src_x == dst_x && src_y == dst_y) {
+ break;
+ }
+ /* Some clients also do 1 pixel blits, avoid overhead for these */
+ if (width == 1 && height == 1) {
+ unsigned int si = (src_x + src_y * src_pitch) * bypp;
+ unsigned int di = (dst_x + dst_y * dst_pitch) * bypp;
+ stn_he_p(&s->local_mem[dst_base + di], bypp,
+ ldn_he_p(&s->local_mem[src_base + si], bypp));
+ break;
+ }
+ /* If reverse blit do simple check for overlaps */
+ if (rtl && src_base == dst_base && src_pitch == dst_pitch) {
+ overlap = (src_x < dst_x + width && src_x + width > dst_x &&
+ src_y < dst_y + height && src_y + height > dst_y);
+ } else if (rtl) {
+ unsigned int sb, se, db, de;
+ sb = src_base + (src_x + src_y * src_pitch) * bypp;
+ se = sb + (width + (height - 1) * src_pitch) * bypp;
+ db = dst_base + (dst_x + dst_y * dst_pitch) * bypp;
+ de = db + (width + (height - 1) * dst_pitch) * bypp;
+ overlap = (db < se && sb < de);
+ }
+ if (overlap) {
+ /* pixman can't do reverse blit: copy via temporary */
+ int tmp_stride = DIV_ROUND_UP(width * bypp, sizeof(uint32_t));
uint32_t *tmp = tmp_buf;
if (tmp_stride * sizeof(uint32_t) * height > sizeof(tmp_buf)) {
tmp = g_malloc(tmp_stride * sizeof(uint32_t) * height);
- free_buf = 1;
}
pixman_blt((uint32_t *)&s->local_mem[src_base], tmp,
- src_pitch * (1 << format) / sizeof(uint32_t),
- tmp_stride, 8 * (1 << format), 8 * (1 << format),
+ src_pitch * bypp / sizeof(uint32_t),
+ tmp_stride, 8 * bypp, 8 * bypp,
src_x, src_y, 0, 0, width, height);
pixman_blt(tmp, (uint32_t *)&s->local_mem[dst_base],
tmp_stride,
- dst_pitch * (1 << format) / sizeof(uint32_t),
- 8 * (1 << format), 8 * (1 << format),
+ dst_pitch * bypp / sizeof(uint32_t),
+ 8 * bypp, 8 * bypp,
0, 0, dst_x, dst_y, width, height);
- if (free_buf) {
+ if (tmp != tmp_buf) {
g_free(tmp);
}
} else {
pixman_blt((uint32_t *)&s->local_mem[src_base],
(uint32_t *)&s->local_mem[dst_base],
- src_pitch * (1 << format) / sizeof(uint32_t),
- dst_pitch * (1 << format) / sizeof(uint32_t),
- 8 * (1 << format), 8 * (1 << format),
+ src_pitch * bypp / sizeof(uint32_t),
+ dst_pitch * bypp / sizeof(uint32_t),
+ 8 * bypp, 8 * bypp,
src_x, src_y, dst_x, dst_y, width, height);
}
}
@@ -837,9 +838,14 @@ static void sm501_2d_operation(SM501State *s)
color = cpu_to_le16(color);
}
- pixman_fill((uint32_t *)&s->local_mem[dst_base],
- dst_pitch * (1 << format) / sizeof(uint32_t),
- 8 * (1 << format), dst_x, dst_y, width, height, color);
+ if (width == 1 && height == 1) {
+ unsigned int i = (dst_x + dst_y * dst_pitch) * bypp;
+ stn_he_p(&s->local_mem[dst_base + i], bypp, color);
+ } else {
+ pixman_fill((uint32_t *)&s->local_mem[dst_base],
+ dst_pitch * bypp / sizeof(uint32_t),
+ 8 * bypp, dst_x, dst_y, width, height, color);
+ }
break;
}
default:
@@ -851,7 +857,7 @@ static void sm501_2d_operation(SM501State *s)
if (dst_base >= get_fb_addr(s, crt) &&
dst_base <= get_fb_addr(s, crt) + fb_len) {
int dst_len = MIN(fb_len, ((dst_y + height - 1) * dst_pitch +
- dst_x + width) * (1 << format));
+ dst_x + width) * bypp);
if (dst_len) {
memory_region_set_dirty(&s->local_mem_region, dst_base, dst_len);
}
@@ -863,7 +869,6 @@ static uint64_t sm501_system_config_read(void *opaque, hwaddr addr,
{
SM501State *s = (SM501State *)opaque;
uint32_t ret = 0;
- SM501_DPRINTF("sm501 system config regs : read addr=%x\n", (int)addr);
switch (addr) {
case SM501_SYSTEM_CONTROL:
@@ -915,7 +920,7 @@ static uint64_t sm501_system_config_read(void *opaque, hwaddr addr,
qemu_log_mask(LOG_UNIMP, "sm501: not implemented system config"
"register read. addr=%" HWADDR_PRIx "\n", addr);
}
-
+ trace_sm501_system_config_read(addr, ret);
return ret;
}
@@ -923,9 +928,8 @@ static void sm501_system_config_write(void *opaque, hwaddr addr,
uint64_t value, unsigned size)
{
SM501State *s = (SM501State *)opaque;
- SM501_DPRINTF("sm501 system config regs : write addr=%x, val=%x\n",
- (uint32_t)addr, (uint32_t)value);
+ trace_sm501_system_config_write((uint32_t)addr, (uint32_t)value);
switch (addr) {
case SM501_SYSTEM_CONTROL:
s->system_control &= 0x10DB0000;
@@ -1011,9 +1015,7 @@ static uint64_t sm501_i2c_read(void *opaque, hwaddr addr, unsigned size)
qemu_log_mask(LOG_UNIMP, "sm501 i2c : not implemented register read."
" addr=0x%" HWADDR_PRIx "\n", addr);
}
-
- SM501_DPRINTF("sm501 i2c regs : read addr=%" HWADDR_PRIx " val=%x\n",
- addr, ret);
+ trace_sm501_i2c_read((uint32_t)addr, ret);
return ret;
}
@@ -1021,9 +1023,8 @@ static void sm501_i2c_write(void *opaque, hwaddr addr, uint64_t value,
unsigned size)
{
SM501State *s = (SM501State *)opaque;
- SM501_DPRINTF("sm501 i2c regs : write addr=%" HWADDR_PRIx
- " val=%" PRIx64 "\n", addr, value);
+ trace_sm501_i2c_write((uint32_t)addr, (uint32_t)value);
switch (addr) {
case SM501_I2C_BYTE_COUNT:
s->i2c_byte_count = value & 0xf;
@@ -1037,25 +1038,19 @@ static void sm501_i2c_write(void *opaque, hwaddr addr, uint64_t value,
s->i2c_status |= (res ? SM501_I2C_STATUS_ERROR : 0);
if (!res) {
int i;
- SM501_DPRINTF("sm501 i2c : transferring %d bytes to 0x%x\n",
- s->i2c_byte_count + 1, s->i2c_addr >> 1);
for (i = 0; i <= s->i2c_byte_count; i++) {
res = i2c_send_recv(s->i2c_bus, &s->i2c_data[i],
!(s->i2c_addr & 1));
if (res) {
- SM501_DPRINTF("sm501 i2c : transfer failed"
- " i=%d, res=%d\n", i, res);
s->i2c_status |= SM501_I2C_STATUS_ERROR;
return;
}
}
if (i) {
- SM501_DPRINTF("sm501 i2c : transferred %d bytes\n", i);
s->i2c_status = SM501_I2C_STATUS_COMPLETE;
}
}
} else {
- SM501_DPRINTF("sm501 i2c : end transfer\n");
i2c_end_transfer(s->i2c_bus);
s->i2c_status &= ~SM501_I2C_STATUS_ERROR;
}
@@ -1095,7 +1090,8 @@ static const MemoryRegionOps sm501_i2c_ops = {
static uint32_t sm501_palette_read(void *opaque, hwaddr addr)
{
SM501State *s = (SM501State *)opaque;
- SM501_DPRINTF("sm501 palette read addr=%x\n", (int)addr);
+
+ trace_sm501_palette_read((uint32_t)addr);
/* TODO : consider BYTE/WORD access */
/* TODO : consider endian */
@@ -1108,8 +1104,8 @@ static void sm501_palette_write(void *opaque, hwaddr addr,
uint32_t value)
{
SM501State *s = (SM501State *)opaque;
- SM501_DPRINTF("sm501 palette write addr=%x, val=%x\n",
- (int)addr, value);
+
+ trace_sm501_palette_write((uint32_t)addr, value);
/* TODO : consider BYTE/WORD access */
/* TODO : consider endian */
@@ -1124,7 +1120,6 @@ static uint64_t sm501_disp_ctrl_read(void *opaque, hwaddr addr,
{
SM501State *s = (SM501State *)opaque;
uint32_t ret = 0;
- SM501_DPRINTF("sm501 disp ctrl regs : read addr=%x\n", (int)addr);
switch (addr) {
@@ -1229,7 +1224,7 @@ static uint64_t sm501_disp_ctrl_read(void *opaque, hwaddr addr,
qemu_log_mask(LOG_UNIMP, "sm501: not implemented disp ctrl register "
"read. addr=%" HWADDR_PRIx "\n", addr);
}
-
+ trace_sm501_disp_ctrl_read((uint32_t)addr, ret);
return ret;
}
@@ -1237,9 +1232,8 @@ static void sm501_disp_ctrl_write(void *opaque, hwaddr addr,
uint64_t value, unsigned size)
{
SM501State *s = (SM501State *)opaque;
- SM501_DPRINTF("sm501 disp ctrl regs : write addr=%x, val=%x\n",
- (unsigned)addr, (unsigned)value);
+ trace_sm501_disp_ctrl_write((uint32_t)addr, (uint32_t)value);
switch (addr) {
case SM501_DC_PANEL_CONTROL:
s->dc_panel_control = value & 0x0FFF73FF;
@@ -1384,7 +1378,6 @@ static uint64_t sm501_2d_engine_read(void *opaque, hwaddr addr,
{
SM501State *s = (SM501State *)opaque;
uint32_t ret = 0;
- SM501_DPRINTF("sm501 2d engine regs : read addr=%x\n", (int)addr);
switch (addr) {
case SM501_2D_SOURCE:
@@ -1454,7 +1447,7 @@ static uint64_t sm501_2d_engine_read(void *opaque, hwaddr addr,
qemu_log_mask(LOG_UNIMP, "sm501: not implemented disp ctrl register "
"read. addr=%" HWADDR_PRIx "\n", addr);
}
-
+ trace_sm501_2d_engine_read((uint32_t)addr, ret);
return ret;
}
@@ -1462,9 +1455,8 @@ static void sm501_2d_engine_write(void *opaque, hwaddr addr,
uint64_t value, unsigned size)
{
SM501State *s = (SM501State *)opaque;
- SM501_DPRINTF("sm501 2d engine regs : write addr=%x, val=%x\n",
- (unsigned)addr, (unsigned)value);
+ trace_sm501_2d_engine_write((uint32_t)addr, (uint32_t)value);
switch (addr) {
case SM501_2D_SOURCE:
s->twoD_source = value;
@@ -1495,6 +1487,9 @@ static void sm501_2d_engine_write(void *opaque, hwaddr addr,
s->twoD_background = value;
break;
case SM501_2D_STRETCH:
+ if (((value >> 20) & 3) == 3) {
+ value &= ~BIT(20);
+ }
s->twoD_stretch = value;
break;
case SM501_2D_COLOR_COMPARE:
@@ -1819,8 +1814,6 @@ static void sm501_init(SM501State *s, DeviceState *dev,
uint32_t local_mem_bytes)
{
s->local_mem_size_index = get_local_mem_size_index(local_mem_bytes);
- SM501_DPRINTF("sm501 local mem size=%x. index=%d\n", get_local_mem_size(s),
- s->local_mem_size_index);
/* local memory */
memory_region_init_ram(&s->local_mem_region, OBJECT(dev), "sm501.local",
diff --git a/hw/display/trace-events b/hw/display/trace-events
index 72d4c98..970d6ba 100644
--- a/hw/display/trace-events
+++ b/hw/display/trace-events
@@ -161,3 +161,15 @@ cg3_write(uint32_t addr, uint32_t val, unsigned size) "write addr:0x%06"PRIx32"
# dpcd.c
dpcd_read(uint32_t addr, uint8_t val) "read addr:0x%"PRIx32" val:0x%02x"
dpcd_write(uint32_t addr, uint8_t val) "write addr:0x%"PRIx32" val:0x%02x"
+
+# sm501.c
+sm501_system_config_read(uint32_t addr, uint32_t val) "addr=0x%x, val=0x%x"
+sm501_system_config_write(uint32_t addr, uint32_t val) "addr=0x%x, val=0x%x"
+sm501_i2c_read(uint32_t addr, uint8_t val) "addr=0x%x, val=0x%x"
+sm501_i2c_write(uint32_t addr, uint32_t val) "addr=0x%x, val=0x%x"
+sm501_palette_read(uint32_t addr) "addr=0x%x"
+sm501_palette_write(uint32_t addr, uint32_t val) "addr=0x%x, val=0x%x"
+sm501_disp_ctrl_read(uint32_t addr, uint32_t val) "addr=0x%x, val=0x%x"
+sm501_disp_ctrl_write(uint32_t addr, uint32_t val) "addr=0x%x, val=0x%x"
+sm501_2d_engine_read(uint32_t addr, uint32_t val) "addr=0x%x, val=0x%x"
+sm501_2d_engine_write(uint32_t addr, uint32_t val) "addr=0x%x, val=0x%x"