]> xenbits.xensource.com Git - xenclient/ioemu.git/commitdiff
- Import the intel rendering driver.
authorJean Guyader <jean.guyader@eu.citrix.com>
Wed, 15 Oct 2008 17:15:24 +0000 (18:15 +0100)
committerJean Guyader <jean.guyader@eu.citrix.com>
Wed, 15 Oct 2008 17:42:58 +0000 (18:42 +0100)
Makefile.target
intel.c [new file with mode: 0644]

index 6e3096d6e9a1a2b7da38987a15c350f46fbd6753..6d8ec0460195ba6b19528187b7a38f6425acd7cd 100644 (file)
@@ -654,6 +654,7 @@ endif
 endif
 
 OBJS+=dom0_driver.o
+OBJS+=intel.o
 
 ifdef CONFIG_SLIRP
 CPPFLAGS+=-I$(SRC_PATH)/slirp
diff --git a/intel.c b/intel.c
new file mode 100644 (file)
index 0000000..4ef272d
--- /dev/null
+++ b/intel.c
@@ -0,0 +1,187 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <assert.h>
+#include <signal.h>
+
+#include "qemu-common.h"
+#include "console.h"
+#include "sysemu.h"
+
+#define INTEL_DEBUG(format, args...)                                    \
+    fprintf (stderr, "intel.c:%d:%s " format , __LINE__, __func__, ## args)
+
+#define TileW           128
+#define TileH           8
+#define IntelFbBase     0xd0000000
+#define IntelMMIOAddr   0xfe400000
+#define TilePitch       16
+
+#define REG_DR_DSPASURF 0x7019C
+#define REG_DR_DSPACNTR 0x70180
+
+static int                      display = 0;
+
+static int                      fd_mem_ro = -1;
+static int                      fd_mem_rw = -1;
+static unsigned char            *intel_mem = NULL;
+static unsigned char            *intel_mmio = NULL;
+
+static inline unsigned int intel_get_reg(unsigned int reg)
+{
+    return *(unsigned int*)(intel_mmio + reg);
+}
+
+static inline unsigned int intel_get_tiled_offset(int x, int y)
+{
+    return 4 * (y * (TilePitch * TileW * TileH) + x * (TileW * TileH));
+}
+
+static inline unsigned int intel_get_offset(DisplayState *ds, int x, int y)
+{
+    return (y * ds->width + x) * 4;
+}
+
+static inline void intel_blit_tile(DisplayState *ds, int x, int y)
+{
+    static const int    solid_line[] = {0, 3, 4, 7};
+    static const int    dashed_line[] = {1, 2, 5, 6};
+    unsigned int        toffset, offset, to, o;
+    unsigned char       *buff;
+    int                 i, j;
+
+    buff = (unsigned char *)(intel_mem + intel_get_reg(REG_DR_DSPASURF));
+
+    /* Copy the lines 0-3-4-7 */
+    toffset = intel_get_tiled_offset(x, y);
+    offset = intel_get_offset(ds, x * TileW, y * TileH);
+    for (i = 0; i < 4; i++)
+    {
+        to = toffset + solid_line[i] * TileW * 4;
+        o = offset + solid_line[i] * ds->width * 4;
+        memcpy(&buff[to], &ds->data[o], TileW * 4);
+    }
+
+    /* Copy the lines 1-2-5-6 */
+    toffset = to = intel_get_tiled_offset(x, y);
+    offset = o = intel_get_offset(ds, x * TileW, y * TileH);
+    for (i = 0; i < 4; i++)
+    {
+        to = toffset + dashed_line[i] * TileW * 4;
+        o = offset + dashed_line[i] * ds->width * 4 + 16 * 4;
+        /* copy the odd one */
+        for (j = 0; j < 4 ; j++)
+        {
+            memcpy(&buff[to], &ds->data[o], 16 * 4);
+            to += 16 * 4;
+            o -= 16 * 4;
+            memcpy(&buff[to], &ds->data[o], 16 * 4);
+            to += 16 * 4;
+            o += 48 * 4;
+        }
+    }
+}
+
+static void intel_update_tiled(DisplayState *ds, int x, int y, int w, int h)
+{
+    int i,j;
+
+    x = x / TileW;
+    y = y / TileH;
+    w = w / TileW + 1;
+    h = h / TileH + 1;
+
+    for (i = 0; i < h; i++)
+        for (j = 0; j < w; j++)
+            if ((y + i) < 128 && (x + j) < 10)
+                intel_blit_tile(ds, j + x, i + y);
+}
+
+static void intel_update(DisplayState *ds, int x, int y, int w, int h)
+{
+   if (intel_get_reg(REG_DR_DSPACNTR) & 0xA)
+       intel_update_tiled(ds, x, y, h, w);
+   else
+   {
+       unsigned char *buff = (unsigned char*)(intel_mem + intel_get_reg(REG_DR_DSPASURF));
+       INTEL_DEBUG("change ds->data %p\n", buff);
+       ds->data = buff;
+   }
+}
+
+static void intel_resize(DisplayState *ds, int w, int h)
+{
+
+    ds->linesize = w * 4;
+    ds->width = w;
+    ds->height = h;
+    if (intel_get_reg(REG_DR_DSPASURF) & 0xA)
+    {
+        INTEL_DEBUG("%d,%d tiled mode\n", w, h);
+        ds->data = realloc(ds->data, 1280 * ds->linesize);
+    }
+    else
+    {
+       unsigned char *buff = (unsigned char*)(intel_mem + intel_get_reg(REG_DR_DSPASURF));
+       INTEL_DEBUG("%d,%d linear mode\n", w, h);
+       INTEL_DEBUG("change ds->data %p\n", buff);
+       ds->data = buff;
+    }
+}
+
+static void intel_refresh(DisplayState *ds)
+{
+    vga_hw_update();
+}
+
+static void intel_init_mapping(void)
+{
+    fd_mem_ro = open("/dev/mem", O_RDONLY);
+    if (fd_mem_ro == -1)
+    {
+        perror("open");
+        exit(1);
+    }
+    fd_mem_rw = open("/dev/mem", O_RDWR);
+    if (fd_mem_rw == -1)
+    {
+        perror("open");
+        exit(1);
+    }
+         
+    intel_mem = mmap(NULL, 0x10000000, PROT_READ | PROT_WRITE, MAP_SHARED,
+                     fd_mem_rw, IntelFbBase);
+    if (intel_mem == MAP_FAILED)
+    {
+        perror("mmap");
+        exit(1);
+    }
+    intel_mmio = mmap(NULL, 1024 * 1024, PROT_READ, MAP_SHARED,
+                      fd_mem_ro, IntelMMIOAddr);
+    if (intel_mem == MAP_FAILED)
+    {
+        perror("mmap");
+        exit(1);
+    }
+}
+
+void intel_display_init(DisplayState *ds)
+{
+    INTEL_DEBUG("\n");
+
+    intel_init_mapping();
+    
+    ds->dpy_update = intel_update;
+    ds->dpy_resize = intel_resize;
+    ds->dpy_refresh = intel_refresh;
+
+    ds->shared_buf = 0;
+    ds->data =  NULL;
+    ds->width = 640;
+    ds->height = 400;
+    ds->linesize = 640 * 4;
+    ds->depth = 32;
+}