qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 3/3] vga: compile in hwlib


From: Blue Swirl
Subject: [Qemu-devel] [PATCH 3/3] vga: compile in hwlib
Date: Wed, 25 Jan 2012 19:15:41 +0000

WIP

Signed-off-by: Blue Swirl <address@hidden>
---
NB. This patch is not finished yet.

I was trying the (ugly or impossible even) approach of passing a flag
for endianness (is_be) in vga_init(). However, I noticed that even
with is_be always true, VGA on x86, PPC and Sparc64 all still worked!
What is going on?

My theory is that video memory is accessed (via vram_ptr) in native
host endianness (see for example latched access near vga.c line 937),
perhaps due to performance reasons. This also means that pixel data
handling is strange and so maybe the target CPU endianness cancels out
somehow.

Perhaps the video memory should be always accessed in LE mode.
---
 Makefile.objs     |    1 +
 Makefile.target   |    1 -
 hw/vga.c          |  206 ++++++++++++++++++++++++++++++++++++++++++-----------
 hw/vga_int.h      |    1 +
 hw/vga_template.h |   56 +++++++++++----
 5 files changed, 206 insertions(+), 59 deletions(-)

diff --git a/Makefile.objs b/Makefile.objs
index 9ca6063..716b6a7 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -284,6 +284,7 @@ hw-obj-y += dma-helpers.o sysbus.o isa-bus.o
 hw-obj-y += qdev-addr.o container.o

 # VGA
+hw-obj-$(CONFIG_VGA) += vga.o
 hw-obj-$(CONFIG_VGA_PCI) += vga-pci.o
 hw-obj-$(CONFIG_VGA_ISA) += vga-isa.o
 hw-obj-$(CONFIG_VGA_ISA_MM) += vga-isa-mm.o
diff --git a/Makefile.target b/Makefile.target
index e554d33..0a3c701 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -196,7 +196,6 @@ obj-$(CONFIG_VHOST_NET) += vhost.o
 obj-$(CONFIG_REALLY_VIRTFS) += 9pfs/virtio-9p-device.o
 obj-$(CONFIG_KVM) += kvm.o kvm-all.o
 obj-$(CONFIG_NO_KVM) += kvm-stub.o
-obj-$(CONFIG_VGA) += vga.o
 obj-y += memory.o savevm.o
 LIBS+=-lz

diff --git a/hw/vga.c b/hw/vga.c
index cf9b39f..a2c206f 100644
--- a/hw/vga.c
+++ b/hw/vga.c
@@ -954,6 +954,8 @@ typedef void vga_draw_glyph9_func(uint8_t *d, int linesize,
 typedef void vga_draw_line_func(VGACommonState *s1, uint8_t *d,
                                 const uint8_t *s, int width);

+#undef VGA_BIGENDIAN
+#undef NO_8BIT_FUNCS
 #define DEPTH 8
 #include "vga_template.h"

@@ -978,6 +980,34 @@ typedef void vga_draw_line_func(VGACommonState
*s1, uint8_t *d,
 #define DEPTH 32
 #include "vga_template.h"

+#define VGA_BIGENDIAN 1
+#define NO_8BIT_FUNCS 1
+#define DEPTH 8
+#include "vga_template.h"
+
+#define DEPTH 15
+#include "vga_template.h"
+
+#define BGR_FORMAT
+#define DEPTH 15
+#include "vga_template.h"
+
+#define DEPTH 16
+#include "vga_template.h"
+
+#define BGR_FORMAT
+#define DEPTH 16
+#include "vga_template.h"
+
+#define DEPTH 32
+#include "vga_template.h"
+
+#define BGR_FORMAT
+#define DEPTH 32
+#include "vga_template.h"
+#undef VGA_BIGENDIAN
+#undef NO_8BIT_FUNCS
+
 static unsigned int rgb_to_pixel8_dup(unsigned int r, unsigned int g,
unsigned b)
 {
     unsigned int col;
@@ -1437,7 +1467,91 @@ enum {
     VGA_DRAW_LINE_NB,
 };

-static vga_draw_line_func * const vga_draw_line_table[NB_DEPTHS *
VGA_DRAW_LINE_NB] = {
+static vga_draw_line_func * const
+vga_draw_line_le_table[NB_DEPTHS * VGA_DRAW_LINE_NB] = {
+    vga_draw_line2_8,
+    vga_draw_line2_16,
+    vga_draw_line2_16,
+    vga_draw_line2_32,
+    vga_draw_line2_32,
+    vga_draw_line2_16,
+    vga_draw_line2_16,
+
+    vga_draw_line2d2_8,
+    vga_draw_line2d2_16,
+    vga_draw_line2d2_16,
+    vga_draw_line2d2_32,
+    vga_draw_line2d2_32,
+    vga_draw_line2d2_16,
+    vga_draw_line2d2_16,
+
+    vga_draw_line4_8,
+    vga_draw_line4_16,
+    vga_draw_line4_16,
+    vga_draw_line4_32,
+    vga_draw_line4_32,
+    vga_draw_line4_16,
+    vga_draw_line4_16,
+
+    vga_draw_line4d2_8,
+    vga_draw_line4d2_16,
+    vga_draw_line4d2_16,
+    vga_draw_line4d2_32,
+    vga_draw_line4d2_32,
+    vga_draw_line4d2_16,
+    vga_draw_line4d2_16,
+
+    vga_draw_line8d2_8,
+    vga_draw_line8d2_16,
+    vga_draw_line8d2_16,
+    vga_draw_line8d2_32,
+    vga_draw_line8d2_32,
+    vga_draw_line8d2_16,
+    vga_draw_line8d2_16,
+
+    vga_draw_line8_8,
+    vga_draw_line8_16,
+    vga_draw_line8_16,
+    vga_draw_line8_32,
+    vga_draw_line8_32,
+    vga_draw_line8_16,
+    vga_draw_line8_16,
+
+    vga_draw_line15_8_le,
+    vga_draw_line15_15_le,
+    vga_draw_line15_16_le,
+    vga_draw_line15_32_le,
+    vga_draw_line15_32bgr_le,
+    vga_draw_line15_15bgr_le,
+    vga_draw_line15_16bgr_le,
+
+    vga_draw_line16_8_le,
+    vga_draw_line16_15_le,
+    vga_draw_line16_16_le,
+    vga_draw_line16_32_le,
+    vga_draw_line16_32bgr_le,
+    vga_draw_line16_15bgr_le,
+    vga_draw_line16_16bgr_le,
+
+    vga_draw_line24_8_le,
+    vga_draw_line24_15_le,
+    vga_draw_line24_16_le,
+    vga_draw_line24_32_le,
+    vga_draw_line24_32bgr_le,
+    vga_draw_line24_15bgr_le,
+    vga_draw_line24_16bgr_le,
+
+    vga_draw_line32_8_le,
+    vga_draw_line32_15_le,
+    vga_draw_line32_16_le,
+    vga_draw_line32_32_le,
+    vga_draw_line32_32bgr_le,
+    vga_draw_line32_15bgr_le,
+    vga_draw_line32_16bgr_le,
+};
+
+static vga_draw_line_func * const
+vga_draw_line_be_table[NB_DEPTHS * VGA_DRAW_LINE_NB] = {
     vga_draw_line2_8,
     vga_draw_line2_16,
     vga_draw_line2_16,
@@ -1486,37 +1600,37 @@ static vga_draw_line_func * const
vga_draw_line_table[NB_DEPTHS * VGA_DRAW_LINE_
     vga_draw_line8_16,
     vga_draw_line8_16,

-    vga_draw_line15_8,
-    vga_draw_line15_15,
-    vga_draw_line15_16,
-    vga_draw_line15_32,
-    vga_draw_line15_32bgr,
-    vga_draw_line15_15bgr,
-    vga_draw_line15_16bgr,
-
-    vga_draw_line16_8,
-    vga_draw_line16_15,
-    vga_draw_line16_16,
-    vga_draw_line16_32,
-    vga_draw_line16_32bgr,
-    vga_draw_line16_15bgr,
-    vga_draw_line16_16bgr,
-
-    vga_draw_line24_8,
-    vga_draw_line24_15,
-    vga_draw_line24_16,
-    vga_draw_line24_32,
-    vga_draw_line24_32bgr,
-    vga_draw_line24_15bgr,
-    vga_draw_line24_16bgr,
-
-    vga_draw_line32_8,
-    vga_draw_line32_15,
-    vga_draw_line32_16,
-    vga_draw_line32_32,
-    vga_draw_line32_32bgr,
-    vga_draw_line32_15bgr,
-    vga_draw_line32_16bgr,
+    vga_draw_line15_8_be,
+    vga_draw_line15_15_be,
+    vga_draw_line15_16_be,
+    vga_draw_line15_32_be,
+    vga_draw_line15_32bgr_be,
+    vga_draw_line15_15bgr_be,
+    vga_draw_line15_16bgr_be,
+
+    vga_draw_line16_8_be,
+    vga_draw_line16_15_be,
+    vga_draw_line16_16_be,
+    vga_draw_line16_32_be,
+    vga_draw_line16_32bgr_be,
+    vga_draw_line16_15bgr_be,
+    vga_draw_line16_16bgr_be,
+
+    vga_draw_line24_8_be,
+    vga_draw_line24_15_be,
+    vga_draw_line24_16_be,
+    vga_draw_line24_32_be,
+    vga_draw_line24_32bgr_be,
+    vga_draw_line24_15bgr_be,
+    vga_draw_line24_16bgr_be,
+
+    vga_draw_line32_8_be,
+    vga_draw_line32_15_be,
+    vga_draw_line32_16_be,
+    vga_draw_line32_32_be,
+    vga_draw_line32_32bgr_be,
+    vga_draw_line32_15bgr_be,
+    vga_draw_line32_16bgr_be,
 };

 static int vga_get_bpp(VGACommonState *s)
@@ -1634,18 +1748,21 @@ static void vga_draw_graphic(VGACommonState
*s, int full_update)
         disp_width != s->last_width ||
         height != s->last_height ||
         s->last_depth != depth) {
-#if defined(HOST_WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
-        if (depth == 16 || depth == 32) {
+#if defined(HOST_WORDS_BIGENDIAN)
+        bool host_be = true;
 #else
-        if (depth == 32) {
+        bool host_be = false;
 #endif
+        bool be_match = s->is_be == host_be;
+        if ((be_match && (depth == 16 || depth == 32)) ||
+            (!be_match && depth == 32)) {
             qemu_free_displaysurface(s->ds);
             s->ds->surface =
qemu_create_displaysurface_from(disp_width, height, depth,
                     s->line_offset,
                     s->vram_ptr + (s->start_addr * 4));
-#if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
-            s->ds->surface->pf = qemu_different_endianness_pixelformat(depth);
-#endif
+            if (!be_match) {
+                s->ds->surface->pf =
qemu_different_endianness_pixelformat(depth);
+            }
             dpy_resize(s->ds);
         } else {
             qemu_console_resize(s->ds, disp_width, height);
@@ -1713,7 +1830,13 @@ static void vga_draw_graphic(VGACommonState *s,
int full_update)
             break;
         }
     }
-    vga_draw_line = vga_draw_line_table[v * NB_DEPTHS +
get_depth_index(s->ds)];
+    if (s->is_be) {
+        vga_draw_line = vga_draw_line_be_table[v * NB_DEPTHS +
+                                               get_depth_index(s->ds)];
+    } else {
+        vga_draw_line = vga_draw_line_le_table[v * NB_DEPTHS +
+                                               get_depth_index(s->ds)];
+    }

     if (!is_buffer_shared(s->ds->surface) && s->cursor_invalidate)
         s->cursor_invalidate(s);
@@ -2253,11 +2376,7 @@ static const MemoryRegionPortio vga_portio_list[] = {
 #ifdef CONFIG_BOCHS_VBE
 static const MemoryRegionPortio vbe_portio_list[] = {
     { 0, 1, 2, .read = vbe_ioport_read_index, .write =
vbe_ioport_write_index },
-# ifdef TARGET_I386
-    { 1, 1, 2, .read = vbe_ioport_read_data, .write = vbe_ioport_write_data },
-# else
     { 2, 1, 2, .read = vbe_ioport_read_data, .write = vbe_ioport_write_data },
-# endif
     PORTIO_END_OF_LIST(),
 };
 #endif /* CONFIG_BOCHS_VBE */
@@ -2310,6 +2429,7 @@ void vga_init(VGACommonState *s, MemoryRegion
*address_space,
         portio_list_init(vbe_port_list, vbe_ports, s, "vbe");
         portio_list_add(vbe_port_list, address_space_io, 0x1ce);
     }
+    s->is_be = true;
 }

 void vga_init_vbe(VGACommonState *s, MemoryRegion *system_memory)
diff --git a/hw/vga_int.h b/hw/vga_int.h
index f755582..64cfedf 100644
--- a/hw/vga_int.h
+++ b/hw/vga_int.h
@@ -176,6 +176,7 @@ typedef struct VGACommonState {
     vga_update_retrace_info_fn update_retrace_info;
     union vga_retrace retrace_info;
     uint8_t is_vbe_vmstate;
+    bool is_be; /* XXX */
 } VGACommonState;

 static inline int c6_to_8(int v)
diff --git a/hw/vga_template.h b/hw/vga_template.h
index 7150573..9f8efef 100644
--- a/hw/vga_template.h
+++ b/hw/vga_template.h
@@ -41,7 +41,15 @@
 #define PIXEL_NAME DEPTH
 #endif /* BGR_FORMAT */

+#ifdef VGA_BIGENDIAN
+#define PIXEL_NAME_FUNC glue(PIXEL_NAME, _be)
+#else
+#define PIXEL_NAME_FUNC glue(PIXEL_NAME, _le)
+#endif
+
+
 #if DEPTH != 15 && !defined(BGR_FORMAT)
+#ifndef NO_8BIT_FUNCS

 static inline void glue(vga_draw_glyph_line_, DEPTH)(uint8_t *d,
                                                      uint32_t font_data,
@@ -340,6 +348,7 @@ static void glue(vga_draw_line8_,
DEPTH)(VGACommonState *s1, uint8_t *d,
     }
 }

+#endif /* NO_8BIT_FUNCS */
 #endif /* DEPTH != 15 */


@@ -348,10 +357,12 @@ static void glue(vga_draw_line8_,
DEPTH)(VGACommonState *s1, uint8_t *d,
 /*
  * 15 bit color
  */
-static void glue(vga_draw_line15_, PIXEL_NAME)(VGACommonState *s1, uint8_t *d,
-                                          const uint8_t *s, int width)
+static void glue(vga_draw_line15_, PIXEL_NAME_FUNC)(VGACommonState *s1,
+                                                    uint8_t *d,
+                                                    const uint8_t *s,
+                                                    int width)
 {
-#if DEPTH == 15 && defined(HOST_WORDS_BIGENDIAN) ==
defined(TARGET_WORDS_BIGENDIAN)
+#if DEPTH == 15 && defined(HOST_WORDS_BIGENDIAN) == defined(VGA_BIGENDIAN)
     memcpy(d, s, width * 2);
 #else
     int w;
@@ -359,7 +370,11 @@ static void glue(vga_draw_line15_,
PIXEL_NAME)(VGACommonState *s1, uint8_t *d,

     w = width;
     do {
-        v = lduw_raw((void *)s);
+#ifdef VGA_BIGENDIAN
+        v = lduw_be_p((void *)s);
+#else
+        v = lduw_le_p((void *)s);
+#endif
         r = (v >> 7) & 0xf8;
         g = (v >> 2) & 0xf8;
         b = (v << 3) & 0xf8;
@@ -373,10 +388,12 @@ static void glue(vga_draw_line15_,
PIXEL_NAME)(VGACommonState *s1, uint8_t *d,
 /*
  * 16 bit color
  */
-static void glue(vga_draw_line16_, PIXEL_NAME)(VGACommonState *s1, uint8_t *d,
-                                          const uint8_t *s, int width)
+static void glue(vga_draw_line16_, PIXEL_NAME_FUNC)(VGACommonState *s1,
+                                                    uint8_t *d,
+                                                    const uint8_t *s,
+                                                    int width)
 {
-#if DEPTH == 16 && defined(HOST_WORDS_BIGENDIAN) ==
defined(TARGET_WORDS_BIGENDIAN)
+#if DEPTH == 16 && defined(HOST_WORDS_BIGENDIAN) == defined(VGA_BIGENDIAN)
     memcpy(d, s, width * 2);
 #else
     int w;
@@ -384,7 +401,11 @@ static void glue(vga_draw_line16_,
PIXEL_NAME)(VGACommonState *s1, uint8_t *d,

     w = width;
     do {
-        v = lduw_raw((void *)s);
+#ifdef VGA_BIGENDIAN
+        v = lduw_be_p((void *)s);
+#else
+        v = lduw_le_p((void *)s);
+#endif
         r = (v >> 8) & 0xf8;
         g = (v >> 3) & 0xfc;
         b = (v << 3) & 0xf8;
@@ -398,15 +419,17 @@ static void glue(vga_draw_line16_,
PIXEL_NAME)(VGACommonState *s1, uint8_t *d,
 /*
  * 24 bit color
  */
-static void glue(vga_draw_line24_, PIXEL_NAME)(VGACommonState *s1, uint8_t *d,
-                                          const uint8_t *s, int width)
+static void glue(vga_draw_line24_, PIXEL_NAME_FUNC)(VGACommonState *s1,
+                                                    uint8_t *d,
+                                                    const uint8_t *s,
+                                                    int width)
 {
     int w;
     uint32_t r, g, b;

     w = width;
     do {
-#if defined(TARGET_WORDS_BIGENDIAN)
+#if defined(VGA_BIGENDIAN)
         r = s[0];
         g = s[1];
         b = s[2];
@@ -424,10 +447,12 @@ static void glue(vga_draw_line24_,
PIXEL_NAME)(VGACommonState *s1, uint8_t *d,
 /*
  * 32 bit color
  */
-static void glue(vga_draw_line32_, PIXEL_NAME)(VGACommonState *s1, uint8_t *d,
-                                          const uint8_t *s, int width)
+static void glue(vga_draw_line32_, PIXEL_NAME_FUNC)(VGACommonState *s1,
+                                                    uint8_t *d,
+                                                    const uint8_t *s,
+                                                    int width)
 {
-#if DEPTH == 32 && defined(HOST_WORDS_BIGENDIAN) ==
defined(TARGET_WORDS_BIGENDIAN) && !defined(BGR_FORMAT)
+#if DEPTH == 32 && defined(HOST_WORDS_BIGENDIAN) ==
defined(VGA_BIGENDIAN) && !defined(BGR_FORMAT)
     memcpy(d, s, width * 4);
 #else
     int w;
@@ -435,7 +460,7 @@ static void glue(vga_draw_line32_,
PIXEL_NAME)(VGACommonState *s1, uint8_t *d,

     w = width;
     do {
-#if defined(TARGET_WORDS_BIGENDIAN)
+#if defined(VGA_BIGENDIAN)
         r = s[1];
         g = s[2];
         b = s[3];
@@ -453,6 +478,7 @@ static void glue(vga_draw_line32_,
PIXEL_NAME)(VGACommonState *s1, uint8_t *d,

 #undef PUT_PIXEL2
 #undef DEPTH
+#undef PIXEL_NAME_FUNC
 #undef BPP
 #undef PIXEL_TYPE
 #undef PIXEL_NAME
-- 
1.7.9.rc0

Attachment: 0003-vga-compile-in-hwlib.patch
Description: Text Data


reply via email to

[Prev in Thread] Current Thread [Next in Thread]