]> xenbits.xensource.com Git - qemu-xen-3.4-testing.git/commitdiff
Merge branch 'upstream'
authorIan Jackson <ian.jackson@eu.citrix.com>
Thu, 12 Mar 2009 19:18:57 +0000 (19:18 +0000)
committerIan Jackson <Ian.Jackson@eu.citrix.com>
Thu, 12 Mar 2009 19:18:57 +0000 (19:18 +0000)
Conflicts:

.gitignore
Makefile.target
block-vpc.c
console.c
console.h
hw/cirrus_vga.c
hw/ide.c
hw/pc.c
hw/pc.h
hw/pci.h
hw/vga.c
hw/vga_int.h
sdl.c
target-ppc/translate_init.c
vl.c
vnc.c

48 files changed:
1  2 
.gitignore
Makefile
Makefile.target
block-qcow2.c
block-raw-posix.c
block-vpc.c
block.c
block.h
configure
console.c
console.h
cutils.c
darwin-user/machload.c
exec-all.h
hw/boards.h
hw/cirrus_vga.c
hw/eepro100.c
hw/ide.c
hw/lsi53c895a.c
hw/mips_mipssim.c
hw/mips_r4k.c
hw/ne2000.c
hw/pc.c
hw/pc.h
hw/pci.c
hw/pci.h
hw/pcnet.c
hw/piix_pci.c
hw/rtl8139.c
hw/scsi-disk.c
hw/serial.c
hw/sun4u.c
hw/vga.c
hw/vga_int.h
hw/vmware_vga.c
hw/xen_machine_fv.c
hw/xen_machine_pv.c
monitor.c
net.c
qemu-char.c
qemu-char.h
qemu-common.h
sdl.c
sysemu.h
vl.c
vnc.c
vnchextile.h
xen-vl-extra.c

diff --cc .gitignore
index fb0617cfdfd4d64084b9b0dfd20ac68b8a798913,773ce51281308f04113257ed508bec948847a2aa..67e8d5d1f51379dbb0fdab14610e827a0d62dba6
@@@ -17,6 -17,6 +17,17 @@@ qemu-nb
  qemu-nbd.8
  qemu-nbd.pod
  .gdbinit
++
++i386-dm/Makefile
++i386-dm/config.mak
++i386-dm/qemu-dm
++i386-dm/gdbstub-xml.c
++qemu-img-xen
++qemu-nbd-xen
++dist
++*.orig
++*~
++
  *.a
  *.aux
  *.cp
diff --cc Makefile
index c8314c6943a44855f3b19508fdef9d615138fff8,4f7a55ae01c613ccfbe7f2e1c4dee252f7b98ce3..c395e773d338f90327cb927aa5ba92306b9074e0
+++ b/Makefile
@@@ -199,15 -184,11 +193,12 @@@ libqemu_user.a: $(USER_OBJS
  ######################################################################
  
  qemu-img$(EXESUF): qemu-img.o qemu-tool.o osdep.o $(BLOCK_OBJS)
-       $(CC) $(LDFLAGS) -o $@ $^ -lz $(LIBS)
- %.o: %.c
-       $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $<
  
  qemu-nbd$(EXESUF):  qemu-nbd.o qemu-tool.o osdep.o $(BLOCK_OBJS)
-       $(CC) $(LDFLAGS) -o $@ $^ -lz $(LIBS)
+ qemu-img$(EXESUF) qemu-nbd$(EXESUF): LIBS += -lz
  
 +
  clean:
  # avoid old build problems by removing potentially incorrect old files
        rm -f config.mak config.h op-i386.h opc-i386.h gen-op-i386.h op-arm.h opc-arm.h gen-op-arm.h
diff --cc Makefile.target
index 7e9cbda6b7cfa327767ada5d4dadb15105c7486f,372d1859310148b7d7a663231e49f4294bc88506..3cc3d3412f5e63d6d3caf83700665b0c7f105daf
@@@ -253,12 -210,7 +212,10 @@@ endi
  
  # libqemu
  
 +-include hookslib.mak
 +-include hookstarget.mak
 +
  libqemu.a: $(LIBOBJS)
-       rm -f $@
-       $(AR) rcs $@ $(LIBOBJS)
  
  translate.o: translate.c cpu.h
  
@@@ -776,11 -717,10 +725,13 @@@ LDFLAGS+=-
  main.o: CFLAGS+=-p
  endif
  
 +-include hooks.mak
 +all: $(PROGS)
 +
+ $(QEMU_PROG): LIBS += $(SDL_LIBS) $(COCOA_LIBS) $(CURSES_LIBS) $(BRLAPI_LIBS) $(VDE_LIBS)
  $(QEMU_PROG): $(OBJS) ../libqemu_common.a libqemu.a
-       $(CC) $(LDFLAGS) -o $@ $^ $(LIBS) $(SDL_LIBS) $(COCOA_LIBS) $(CURSES_LIBS) $(BRLAPI_LIBS) $(VDE_LIBS)
+       $(LINK)
  
  endif # !CONFIG_USER_ONLY
  
diff --cc block-qcow2.c
Simple merge
Simple merge
diff --cc block-vpc.c
Simple merge
diff --cc block.c
Simple merge
diff --cc block.h
Simple merge
diff --cc configure
Simple merge
diff --cc console.c
index 147daf16d2949fe775fe19744e5e528c15770fe8,68ac970654fe9ec1df5b906d252cd06cfa710bc9..859454916e07eac0c4588d43a120bc0d480e4091
+++ b/console.c
@@@ -139,11 -139,11 +139,6 @@@ struct TextConsole 
      TextCell *cells;
      int text_x[2], text_y[2], cursor_invalidate;
  
--    int update_x0;
--    int update_y0;
--    int update_x1;
--    int update_y1;
--
      enum TTYState state;
      int esc_params[MAX_ESC_PARAMS];
      int nb_esc_params;
@@@ -189,7 -195,8 +184,7 @@@ static unsigned int vga_get_color(Displ
  {
      unsigned int r, g, b, color;
  
--    switch(ds_get_bits_per_pixel(ds)) {
 -#if 0
++    switch(ds->depth) {
      case 8:
          r = (rgba >> 16) & 0xff;
          g = (rgba >> 8) & 0xff;
@@@ -222,9 -232,9 +217,9 @@@ static void vga_fill_rect (DisplayStat
      uint8_t *d, *d1;
      int x, y, bpp;
  
--    bpp = (ds_get_bits_per_pixel(ds) + 7) >> 3;
--    d1 = ds_get_data(ds) +
--        ds_get_linesize(ds) * posy + bpp * posx;
++    bpp = (ds->depth + 7) >> 3;
++    d1 = ds->data +
++        ds->linesize * posy + bpp * posx;
      for (y = 0; y < height; y++) {
          d = d1;
          switch(bpp) {
              }
              break;
          }
--        d1 += ds_get_linesize(ds);
++        d1 += ds->linesize;
      }
  }
  
@@@ -258,27 -268,27 +253,27 @@@ static void vga_bitblt(DisplayState *ds
      uint8_t *d;
      int wb, y, bpp;
  
--    bpp = (ds_get_bits_per_pixel(ds) + 7) >> 3;
++    bpp = (ds->depth + 7) >> 3;
      wb = w * bpp;
      if (yd <= ys) {
--        s = ds_get_data(ds) +
--            ds_get_linesize(ds) * ys + bpp * xs;
--        d = ds_get_data(ds) +
--            ds_get_linesize(ds) * yd + bpp * xd;
++        s = ds->data +
++            ds->linesize * ys + bpp * xs;
++        d = ds->data +
++            ds->linesize * yd + bpp * xd;
          for (y = 0; y < h; y++) {
              memmove(d, s, wb);
--            d += ds_get_linesize(ds);
--            s += ds_get_linesize(ds);
++            d += ds->linesize;
++            s += ds->linesize;
          }
      } else {
--        s = ds_get_data(ds) +
--            ds_get_linesize(ds) * (ys + h - 1) + bpp * xs;
--        d = ds_get_data(ds) +
--            ds_get_linesize(ds) * (yd + h - 1) + bpp * xd;
++        s = ds->data +
++            ds->linesize * (ys + h - 1) + bpp * xs;
++        d = ds->data +
++            ds->linesize * (yd + h - 1) + bpp * xd;
         for (y = 0; y < h; y++) {
              memmove(d, s, wb);
--            d -= ds_get_linesize(ds);
--            s -= ds_get_linesize(ds);
++            d -= ds->linesize;
++            s -= ds->linesize;
          }
      }
  }
@@@ -368,7 -378,7 +363,7 @@@ static const uint32_t color_table_rgb[2
  
  static inline unsigned int col_expand(DisplayState *ds, unsigned int col)
  {
--    switch(ds_get_bits_per_pixel(ds)) {
++    switch(ds->depth) {
      case 8:
          col |= col << 8;
          col |= col << 16;
@@@ -438,13 -448,13 +433,13 @@@ static void vga_putcharxy(DisplayState 
          bgcol = color_table[t_attrib->bold][t_attrib->bgcol];
      }
  
--    bpp = (ds_get_bits_per_pixel(ds) + 7) >> 3;
--    d = ds_get_data(ds) +
--        ds_get_linesize(ds) * y * FONT_HEIGHT + bpp * x * FONT_WIDTH;
--    linesize = ds_get_linesize(ds);
++    bpp = (ds->depth + 7) >> 3;
++    d = ds->data +
++        ds->linesize * y * FONT_HEIGHT + bpp * x * FONT_WIDTH;
++    linesize = ds->linesize;
      font_ptr = vgafont16 + FONT_HEIGHT * ch;
      xorcol = bgcol ^ fgcol;
--    switch(ds_get_bits_per_pixel(ds)) {
++    switch(ds->depth) {
      case 8:
          for(i = 0; i < FONT_HEIGHT; i++) {
              font_data = *font_ptr++;
@@@ -524,18 -534,26 +519,6 @@@ static void text_console_resize(TextCon
      s->cells = cells;
  }
  
 -static inline void text_update_xy(TextConsole *s, int x, int y)
 -{
 -    s->text_x[0] = MIN(s->text_x[0], x);
 -    s->text_x[1] = MAX(s->text_x[1], x);
 -    s->text_y[0] = MIN(s->text_y[0], y);
 -    s->text_y[1] = MAX(s->text_y[1], y);
 -}
 -
--static void invalidate_xy(TextConsole *s, int x, int y)
--{
--    if (s->update_x0 > x * FONT_WIDTH)
--        s->update_x0 = x * FONT_WIDTH;
--    if (s->update_y0 > y * FONT_HEIGHT)
--        s->update_y0 = y * FONT_HEIGHT;
--    if (s->update_x1 < (x + 1) * FONT_WIDTH)
--        s->update_x1 = (x + 1) * FONT_WIDTH;
--    if (s->update_y1 < (y + 1) * FONT_HEIGHT)
--        s->update_y1 = (y + 1) * FONT_HEIGHT;
--}
--
  static void update_xy(TextConsole *s, int x, int y)
  {
      TextCell *c;
              c = &s->cells[y1 * s->width + x];
              vga_putcharxy(s->ds, x, y2, c->ch,
                            &(c->t_attrib));
--            invalidate_xy(s, x, y2);
++            dpy_update(s->ds, x * FONT_WIDTH, y2 * FONT_HEIGHT,
++                       FONT_WIDTH, FONT_HEIGHT);
          }
      }
  }
@@@ -561,30 -584,30 +545,22 @@@ static void console_show_cursor(TextCon
      int y, y1;
  
      if (s == active_console) {
--        int x = s->x;
--
--        if (!ds_get_bits_per_pixel(s->ds)) {
--            s->cursor_invalidate = 1;
--            return;
--        }
--
--        if (x >= s->width) {
--            x = s->width - 1;
--        }
          y1 = (s->y_base + s->y) % s->total_height;
          y = y1 - s->y_displayed;
          if (y < 0)
              y += s->total_height;
          if (y < s->height) {
--            c = &s->cells[y1 * s->width + x];
++            c = &s->cells[y1 * s->width + s->x];
              if (show) {
                  TextAttributes t_attrib = s->t_attrib_default;
                  t_attrib.invers = !(t_attrib.invers); /* invert fg and bg */
--                vga_putcharxy(s->ds, x, y, c->ch, &t_attrib);
++                vga_putcharxy(s->ds, s->x, y, c->ch, &t_attrib);
              } else {
--                vga_putcharxy(s->ds, x, y, c->ch, &(c->t_attrib));
++                vga_putcharxy(s->ds, s->x, y, c->ch,
++                              &(c->t_attrib));
              }
--            invalidate_xy(s, x, y);
++            dpy_update(s->ds, s->x * FONT_WIDTH, y * FONT_HEIGHT,
++                       FONT_WIDTH, FONT_HEIGHT);
          }
      }
  }
@@@ -596,8 -619,16 +572,8 @@@ static void console_refresh(TextConsol
  
      if (s != active_console)
          return;
 -    if (!ds_get_bits_per_pixel(s->ds)) {
 -        s->text_x[0] = 0;
 -        s->text_y[0] = 0;
 -        s->text_x[1] = s->width - 1;
 -        s->text_y[1] = s->height - 1;
 -        s->cursor_invalidate = 1;
 -        return;
 -    }
  
--    vga_fill_rect(s->ds, 0, 0, ds_get_width(s->ds), ds_get_height(s->ds),
++    vga_fill_rect(s->ds, 0, 0, s->ds->width, s->ds->height,
                    color_table[0][COLOR_BLACK]);
      y1 = s->y_displayed;
      for(y = 0; y < s->height; y++) {
          if (++y1 == s->total_height)
              y1 = 0;
      }
++    dpy_update(s->ds, 0, 0, s->ds->width, s->ds->height);
      console_show_cursor(s, 1);
--    dpy_update(s->ds, 0, 0, ds_get_width(s->ds), ds_get_height(s->ds));
  }
  
  static void console_scroll(int ydelta)
@@@ -679,10 -718,10 +655,8 @@@ static void console_put_lf(TextConsole 
              vga_fill_rect(s->ds, 0, (s->height - 1) * FONT_HEIGHT,
                            s->width * FONT_WIDTH, FONT_HEIGHT,
                            color_table[0][s->t_attrib_default.bgcol]);
--            s->update_x0 = 0;
--            s->update_y0 = 0;
--            s->update_x1 = s->width * FONT_WIDTH;
--            s->update_y1 = s->height * FONT_HEIGHT;
++            dpy_update(s->ds, 0, 0,
++                       s->width * FONT_WIDTH, s->height * FONT_HEIGHT);
          }
      }
  }
@@@ -1026,21 -1061,21 +1000,20 @@@ void console_select(unsigned int index
  
      if (index >= MAX_CONSOLES)
          return;
--    active_console->g_width = ds_get_width(active_console->ds);
--    active_console->g_height = ds_get_height(active_console->ds);
      s = consoles[index];
      if (s) {
--        DisplayState *ds = s->ds;
          active_console = s;
--        if (ds_get_bits_per_pixel(s->ds)) {
-             ds->surface = qemu_resize_displaysurface(ds, s->g_width,
 -            ds->surface = qemu_resize_displaysurface(ds->surface, s->g_width,
--                    s->g_height, 32, 4 * s->g_width);
++        if (s->console_type == TEXT_CONSOLE) {
++            if (s->g_width != s->ds->width ||
++                s->g_height != s->ds->height) {
++                s->g_width = s->ds->width;
++                s->g_height = s->ds->height;
++                text_console_resize(s);
++            }
++            console_refresh(s);
          } else {
--            s->ds->surface->width = s->width;
--            s->ds->surface->height = s->height;
++            vga_hw_invalidate();
          }
--        dpy_resize(s->ds);
--        vga_hw_invalidate();
      }
  }
  
@@@ -1049,20 -1084,20 +1022,11 @@@ static int console_puts(CharDriverStat
      TextConsole *s = chr->opaque;
      int i;
  
--    s->update_x0 = s->width * FONT_WIDTH;
--    s->update_y0 = s->height * FONT_HEIGHT;
--    s->update_x1 = 0;
--    s->update_y1 = 0;
      console_show_cursor(s, 0);
      for(i = 0; i < len; i++) {
          console_putchar(s, buf[i]);
      }
      console_show_cursor(s, 1);
--    if (ds_get_bits_per_pixel(s->ds) && s->update_x0 < s->update_x1) {
--        dpy_update(s->ds, s->update_x0, s->update_y0,
--                   s->update_x1 - s->update_x0,
--                   s->update_y1 - s->update_y0);
--    }
      return len;
  }
  
@@@ -1156,10 -1191,10 +1120,15 @@@ void kbd_put_keysym(int keysym
  static void text_console_invalidate(void *opaque)
  {
      TextConsole *s = (TextConsole *) opaque;
--    if (!ds_get_bits_per_pixel(s->ds) && s->console_type == TEXT_CONSOLE) {
--        s->g_width = ds_get_width(s->ds);
--        s->g_height = ds_get_height(s->ds);
--        text_console_resize(s);
++
++    if (s->g_width != s->ds->width || s->g_height != s->ds->height) {
++        if (s->console_type == TEXT_CONSOLE_FIXED_SIZE)
++            dpy_resize(s->ds, s->g_width, s->g_height);
++        else {
++            s->g_width = s->ds->width;
++            s->g_height = s->ds->height;
++            text_console_resize(s);
++        }
      }
      console_refresh(s);
  }
@@@ -1191,18 -1226,18 +1160,6 @@@ static void text_console_update(void *o
      }
  }
  
--static TextConsole *get_graphic_console(DisplayState *ds)
--{
--    int i;
--    TextConsole *s;
--    for (i = 0; i < nb_consoles; i++) {
--        s = consoles[i];
--        if (s->console_type == GRAPHIC_CONSOLE && s->ds == ds)
--            return s;
--    }
--    return NULL;
--}
--
  static TextConsole *new_console(DisplayState *ds, console_type_t console_type)
  {
      TextConsole *s;
      } else {
          /* HACK: Put graphical consoles before text consoles.  */
          for (i = nb_consoles; i > 0; i--) {
--            if (consoles[i - 1]->console_type == GRAPHIC_CONSOLE)
++            if (!consoles[i - 1]->console_type == GRAPHIC_CONSOLE)
                  break;
              consoles[i] = consoles[i - 1];
          }
          consoles[i] = s;
--        nb_consoles++;
      }
      return s;
  }
  
--DisplayState *graphic_console_init(vga_hw_update_ptr update,
--                                   vga_hw_invalidate_ptr invalidate,
--                                   vga_hw_screen_dump_ptr screen_dump,
--                                   vga_hw_text_update_ptr text_update,
--                                   void *opaque)
++TextConsole *graphic_console_init(DisplayState *ds, vga_hw_update_ptr update,
++                                  vga_hw_invalidate_ptr invalidate,
++                                  vga_hw_screen_dump_ptr screen_dump,
++                                  vga_hw_text_update_ptr text_update,
++                                  void *opaque)
  {
      TextConsole *s;
--    DisplayState *ds;
--
--    ds = (DisplayState *) qemu_mallocz(sizeof(DisplayState));
--    if (ds == NULL)
--        return NULL;
-     ds->allocator = &default_allocator; 
-     ds->surface = qemu_create_displaysurface(ds, 640, 480, 32, 640 * 4);
 -    ds->surface = qemu_create_displaysurface(640, 480, 32, 640 * 4);
  
      s = new_console(ds, GRAPHIC_CONSOLE);
--    if (s == NULL) {
-         qemu_free_displaysurface(ds);
 -        qemu_free_displaysurface(ds->surface);
--        qemu_free(ds);
--        return NULL;
--    }
++    if (!s)
++      return NULL;
      s->hw_update = update;
      s->hw_invalidate = invalidate;
      s->hw_screen_dump = screen_dump;
      s->hw_text_update = text_update;
      s->hw = opaque;
--
--    register_displaystate(ds);
--    return ds;
++    return s;
  }
  
  int is_graphic_console(void)
@@@ -1287,21 -1321,21 +1231,19 @@@ void console_color_init(DisplayState *d
      }
  }
  
--static int n_text_consoles;
--static CharDriverState *text_consoles[128];
--static char *text_console_strs[128];
--
--static void text_console_do_init(CharDriverState *chr, DisplayState *ds, const char *p)
++CharDriverState *text_console_init(DisplayState *ds, const char *p)
  {
++    CharDriverState *chr;
      TextConsole *s;
--    unsigned width;
--    unsigned height;
      static int color_inited;
  
++    chr = qemu_mallocz(sizeof(CharDriverState));
++    if (!chr)
++        return NULL;
      s = new_console(ds, (p == 0) ? TEXT_CONSOLE : TEXT_CONSOLE_FIXED_SIZE);
      if (!s) {
          free(chr);
--        return;
++        return NULL;
      }
      chr->opaque = s;
      chr->chr_write = console_puts;
      s->out_fifo.buf = s->out_fifo_buf;
      s->out_fifo.buf_size = sizeof(s->out_fifo_buf);
      s->kbd_timer = qemu_new_timer(rt_clock, kbd_send_chars, s);
--    s->ds = ds;
  
      if (!color_inited) {
          color_inited = 1;
--        console_color_init(s->ds);
++        console_color_init(ds);
      }
      s->y_displayed = 0;
      s->y_base = 0;
      s->total_height = DEFAULT_BACKSCROLL;
      s->x = 0;
      s->y = 0;
--    width = ds_get_width(s->ds);
--    height = ds_get_height(s->ds);
--    if (p != 0) {
--        width = strtoul(p, (char **)&p, 10);
--        if (*p == 'C') {
--            p++;
--            width *= FONT_WIDTH;
--        }
--        if (*p == 'x') {
--            p++;
--            height = strtoul(p, (char **)&p, 10);
--            if (*p == 'C') {
--                p++;
--                height *= FONT_HEIGHT;
--            }
--        }
--    }
--    s->g_width = width;
--    s->g_height = height;
--
--    s->hw_invalidate = text_console_invalidate;
--    s->hw_text_update = text_console_update;
--    s->hw = s;
++    s->g_width = s->ds->width;
++    s->g_height = s->ds->height;
  
      /* Set text attribute defaults */
      s->t_attrib_default.bold = 0;
      text_console_resize(s);
  
      qemu_chr_reset(chr);
--    if (chr->init)
--        chr->init(chr);
--}
--
--CharDriverState *text_console_init(const char *p)
--{
--    CharDriverState *chr;
--
--    chr = qemu_mallocz(sizeof(CharDriverState));
--    if (!chr)
--        return NULL;
--
--    if (n_text_consoles == 128) {
--        fprintf(stderr, "Too many text consoles\n");
--        exit(1);
--    }
--    text_consoles[n_text_consoles] = chr;
--    text_console_strs[n_text_consoles] = p ? qemu_strdup(p) : NULL;
--    n_text_consoles++;
  
      return chr;
  }
  
--void text_consoles_set_display(DisplayState *ds)
 -{
 -    int i;
 -
 -    for (i = 0; i < n_text_consoles; i++) {
 -        text_console_do_init(text_consoles[i], ds, text_console_strs[i]);
 -        qemu_free(text_console_strs[i]);
 -    }
 -
 -    n_text_consoles = 0;
 -}
 -
 -void qemu_console_resize(DisplayState *ds, int width, int height)
 -{
 -    TextConsole *s = get_graphic_console(ds);
 -    if (!s) return;
 -
 -    s->g_width = width;
 -    s->g_height = height;
 -    if (is_graphic_console()) {
 -        ds->surface = qemu_resize_displaysurface(ds->surface, width, height, 32, 4 * width);
 -        dpy_resize(ds);
 -    }
 -}
 -
 -void qemu_console_copy(DisplayState *ds, int src_x, int src_y,
 -                       int dst_x, int dst_y, int w, int h)
 -{
 -    if (is_graphic_console()) {
 -        dpy_copy(ds, src_x, src_y, dst_x, dst_y, w, h);
 -    }
 -}
 -
 -PixelFormat qemu_different_endianness_pixelformat(int bpp)
 -{
 -    PixelFormat pf;
 -
 -    memset(&pf, 0x00, sizeof(PixelFormat));
 -
 -    pf.bits_per_pixel = bpp;
 -    pf.bytes_per_pixel = bpp / 8;
 -    pf.depth = bpp == 32 ? 24 : bpp;
 -
 -    switch (bpp) {
 -        case 24:
 -            pf.rmask = 0x000000FF;
 -            pf.gmask = 0x0000FF00;
 -            pf.bmask = 0x00FF0000;
 -            pf.rmax = 255;
 -            pf.gmax = 255;
 -            pf.bmax = 255;
 -            pf.rshift = 0;
 -            pf.gshift = 8;
 -            pf.bshift = 16;
 -            pf.rbits = 8;
 -            pf.gbits = 8;
 -            pf.bbits = 8;
 -            break;
 -        case 32:
 -            pf.rmask = 0x0000FF00;
 -            pf.gmask = 0x00FF0000;
 -            pf.bmask = 0xFF000000;
 -            pf.amask = 0x00000000;
 -            pf.amax = 255;
 -            pf.rmax = 255;
 -            pf.gmax = 255;
 -            pf.bmax = 255;
 -            pf.ashift = 0;
 -            pf.rshift = 8;
 -            pf.gshift = 16;
 -            pf.bshift = 24;
 -            pf.rbits = 8;
 -            pf.gbits = 8;
 -            pf.bbits = 8;
 -            pf.abits = 8;
 -            break;
 -        default:
 -            break;
 -    }
 -    return pf;
 -}
 -
 -PixelFormat qemu_default_pixelformat(int bpp)
++void qemu_console_resize(QEMUConsole *console, int width, int height)
  {
-     int i;
 -    PixelFormat pf;
--
-     for (i = 0; i < n_text_consoles; i++) {
-         text_console_do_init(text_consoles[i], ds, text_console_strs[i]);
-         qemu_free(text_console_strs[i]);
 -    memset(&pf, 0x00, sizeof(PixelFormat));
 -
 -    pf.bits_per_pixel = bpp;
 -    pf.bytes_per_pixel = bpp / 8;
 -    pf.depth = bpp == 32 ? 24 : bpp;
 -
 -    switch (bpp) {
 -        case 16:
 -            pf.rmask = 0x0000F800;
 -            pf.gmask = 0x000007E0;
 -            pf.bmask = 0x0000001F;
 -            pf.rmax = 31;
 -            pf.gmax = 63;
 -            pf.bmax = 31;
 -            pf.rshift = 11;
 -            pf.gshift = 5;
 -            pf.bshift = 0;
 -            pf.rbits = 5;
 -            pf.gbits = 6;
 -            pf.bbits = 5;
 -            break;
 -        case 24:
 -            pf.rmask = 0x00FF0000;
 -            pf.gmask = 0x0000FF00;
 -            pf.bmask = 0x000000FF;
 -            pf.rmax = 255;
 -            pf.gmax = 255;
 -            pf.bmax = 255;
 -            pf.rshift = 16;
 -            pf.gshift = 8;
 -            pf.bshift = 0;
 -            pf.rbits = 8;
 -            pf.gbits = 8;
 -            pf.bbits = 8;
 -        case 32:
 -            pf.rmask = 0x00FF0000;
 -            pf.gmask = 0x0000FF00;
 -            pf.bmask = 0x000000FF;
 -            pf.amax = 255;
 -            pf.rmax = 255;
 -            pf.gmax = 255;
 -            pf.bmax = 255;
 -            pf.ashift = 24;
 -            pf.rshift = 16;
 -            pf.gshift = 8;
 -            pf.bshift = 0;
 -            pf.rbits = 8;
 -            pf.gbits = 8;
 -            pf.bbits = 8;
 -            pf.abits = 8;
 -            break;
 -        default:
 -            break;
--    }
 -    return pf;
 -}
--
-     n_text_consoles = 0;
 -DisplaySurface* qemu_create_displaysurface(int width, int height, int bpp, int linesize)
 -{
 -    DisplaySurface *surface = (DisplaySurface*) qemu_mallocz(sizeof(DisplaySurface));
 -    if (surface == NULL) {
 -        fprintf(stderr, "qemu_create_displaysurface: malloc failed\n");
 -        exit(1);
 -    }
 -
 -    surface->width = width;
 -    surface->height = height;
 -    surface->linesize = linesize;
 -    surface->pf = qemu_default_pixelformat(bpp);
 -#ifdef WORDS_BIGENDIAN
 -    surface->flags = QEMU_ALLOCATED_FLAG | QEMU_BIG_ENDIAN_FLAG;
 -#else
 -    surface->flags = QEMU_ALLOCATED_FLAG;
 -#endif
 -    surface->data = (uint8_t*) qemu_mallocz(surface->linesize * surface->height);
 -    if (surface->data == NULL) {
 -        fprintf(stderr, "qemu_create_displaysurface: malloc failed\n");
 -        exit(1);
 -    }
 -
 -    return surface;
--}
--
- void qemu_console_resize(DisplayState *ds, int width, int height)
 -DisplaySurface* qemu_resize_displaysurface(DisplaySurface *surface,
 -                                          int width, int height, int bpp, int linesize)
--{
-     TextConsole *s = get_graphic_console(ds);
-     if (!s) return;
-     s->g_width = width;
-     s->g_height = height;
-     if (is_graphic_console()) {
-         ds->surface = qemu_resize_displaysurface(ds, width, height, 32, 4 * width);
-         dpy_resize(ds);
 -    surface->width = width;
 -    surface->height = height;
 -    surface->linesize = linesize;
 -    surface->pf = qemu_default_pixelformat(bpp);
 -    if (surface->flags & QEMU_ALLOCATED_FLAG)
 -        surface->data = (uint8_t*) qemu_realloc(surface->data, surface->linesize * surface->height);
 -    else
 -        surface->data = (uint8_t*) qemu_malloc(surface->linesize * surface->height);
 -    if (surface->data == NULL) {
 -        fprintf(stderr, "qemu_resize_displaysurface: malloc failed\n");
 -        exit(1);
++    if (console->g_width != width || console->g_height != height
++        || !console->ds->data) {
++        console->g_width = width;
++        console->g_height = height;
++        if (active_console == console) {
++            dpy_resize(console->ds, width, height);
++        }
      }
 -#ifdef WORDS_BIGENDIAN
 -    surface->flags = QEMU_ALLOCATED_FLAG | QEMU_BIG_ENDIAN_FLAG;
 -#else
 -    surface->flags = QEMU_ALLOCATED_FLAG;
 -#endif
 -
 -    return surface;
  }
  
- void qemu_console_copy(DisplayState *ds, int src_x, int src_y,
 -DisplaySurface* qemu_create_displaysurface_from(int width, int height, int bpp,
 -                                              int linesize, uint8_t *data)
++void qemu_console_copy(QEMUConsole *console, int src_x, int src_y,
 +                int dst_x, int dst_y, int w, int h)
  {
-     if (is_graphic_console()) {
-         dpy_copy(ds, src_x, src_y, dst_x, dst_y, w, h);
-     }
- }
- PixelFormat qemu_different_endianness_pixelformat(int bpp)
- {
-     PixelFormat pf;
-     memset(&pf, 0x00, sizeof(PixelFormat));
-     pf.bits_per_pixel = bpp;
-     pf.bytes_per_pixel = bpp / 8;
-     pf.depth = bpp == 32 ? 24 : bpp;
-     switch (bpp) {
-         case 24:
-             pf.rmask = 0x000000FF;
-             pf.gmask = 0x0000FF00;
-             pf.bmask = 0x00FF0000;
-             pf.rmax = 255;
-             pf.gmax = 255;
-             pf.bmax = 255;
-             pf.rshift = 0;
-             pf.gshift = 8;
-             pf.bshift = 16;
-             pf.rbits = 8;
-             pf.gbits = 8;
-             pf.bbits = 8;
-             break;
-         case 32:
-             pf.rmask = 0x0000FF00;
-             pf.gmask = 0x00FF0000;
-             pf.bmask = 0xFF000000;
-             pf.amask = 0x00000000;
-             pf.amax = 255;
-             pf.rmax = 255;
-             pf.gmax = 255;
-             pf.bmax = 255;
-             pf.ashift = 0;
-             pf.rshift = 8;
-             pf.gshift = 16;
-             pf.bshift = 24;
-             pf.rbits = 8;
-             pf.gbits = 8;
-             pf.bbits = 8;
-             pf.abits = 8;
-             break;
-         default:
-             break;
-     }
-     return pf;
- }
- PixelFormat qemu_default_pixelformat(int bpp)
- {
-     PixelFormat pf;
-     memset(&pf, 0x00, sizeof(PixelFormat));
-     pf.bits_per_pixel = bpp;
-     pf.bytes_per_pixel = bpp / 8;
-     pf.depth = bpp == 32 ? 24 : bpp;
-     switch (bpp) {
-         case 16:
-             pf.rmask = 0x0000F800;
-             pf.gmask = 0x000007E0;
-             pf.bmask = 0x0000001F;
-             pf.rmax = 31;
-             pf.gmax = 63;
-             pf.bmax = 31;
-             pf.rshift = 11;
-             pf.gshift = 5;
-             pf.bshift = 0;
-             pf.rbits = 5;
-             pf.gbits = 6;
-             pf.bbits = 5;
-             break;
-         case 24:
-             pf.rmask = 0x00FF0000;
-             pf.gmask = 0x0000FF00;
-             pf.bmask = 0x000000FF;
-             pf.rmax = 255;
-             pf.gmax = 255;
-             pf.bmax = 255;
-             pf.rshift = 16;
-             pf.gshift = 8;
-             pf.bshift = 0;
-             pf.rbits = 8;
-             pf.gbits = 8;
-             pf.bbits = 8;
-         case 32:
-             pf.rmask = 0x00FF0000;
-             pf.gmask = 0x0000FF00;
-             pf.bmask = 0x000000FF;
-             pf.amax = 255;
-             pf.rmax = 255;
-             pf.gmax = 255;
-             pf.bmax = 255;
-             pf.ashift = 24;
-             pf.rshift = 16;
-             pf.gshift = 8;
-             pf.bshift = 0;
-             pf.rbits = 8;
-             pf.gbits = 8;
-             pf.bbits = 8;
-             pf.abits = 8;
-             break;
-         default:
-             break;
-     }
-     return pf;
- }
- DisplaySurface* defaultallocator_create_displaysurface(int width, int height, int bpp, int linesize)
- {
-     DisplaySurface *surface = (DisplaySurface*) qemu_mallocz(sizeof(DisplaySurface));
-     if (surface == NULL) {
-         fprintf(stderr, "defaultallocator_create_displaysurface: malloc failed\n");
-         exit(1);
-     }
-     surface->width = width;
-     surface->height = height;
-     surface->linesize = linesize;
-     surface->pf = qemu_default_pixelformat(bpp);
- #ifdef WORDS_BIGENDIAN
-     surface->flags = QEMU_ALLOCATED_FLAG | QEMU_BIG_ENDIAN_FLAG;
- #else
-     surface->flags = QEMU_ALLOCATED_FLAG;
- #endif
-     surface->data = (uint8_t*) qemu_mallocz(surface->linesize * surface->height);
-     if (surface->data == NULL) {
-         fprintf(stderr, "defaultallocator_create_displaysurface: malloc failed\n");
-         exit(1);
-     }
-     return surface;
- }
- DisplaySurface* defaultallocator_resize_displaysurface(DisplaySurface *surface,
-                                           int width, int height, int bpp, int linesize)
- {
-     surface->width = width;
-     surface->height = height;
-     surface->linesize = linesize;
-     surface->pf = qemu_default_pixelformat(bpp);
-     if (surface->flags & QEMU_ALLOCATED_FLAG)
-         surface->data = (uint8_t*) qemu_realloc(surface->data, surface->linesize * surface->height);
-     else
-         surface->data = (uint8_t*) qemu_malloc(surface->linesize * surface->height);
-     if (surface->data == NULL) {
-         fprintf(stderr, "defaultallocator_resize_displaysurface: malloc failed\n");
-         exit(1);
-     }
- #ifdef WORDS_BIGENDIAN
-     surface->flags = QEMU_ALLOCATED_FLAG | QEMU_BIG_ENDIAN_FLAG;
- #else
-     surface->flags = QEMU_ALLOCATED_FLAG;
- #endif
-     return surface;
- }
- DisplaySurface* qemu_create_displaysurface_from(int width, int height, int bpp,
-                                               int linesize, uint8_t *data)
- {
--    DisplaySurface *surface = (DisplaySurface*) qemu_mallocz(sizeof(DisplaySurface));
--    if (surface == NULL) {
--        fprintf(stderr, "qemu_create_displaysurface_from: malloc failed\n");
--        exit(1);
++    if (active_console == console) {
++        if (console->ds->dpy_copy)
++            console->ds->dpy_copy(console->ds,
++                            src_x, src_y, dst_x, dst_y, w, h);
++        else {
++            /* TODO */
++            console->ds->dpy_update(console->ds, dst_x, dst_y, w, h);
++        }
      }
--
--    surface->width = width;
--    surface->height = height;
--    surface->linesize = linesize;
--    surface->pf = qemu_default_pixelformat(bpp);
--#ifdef WORDS_BIGENDIAN
--    surface->flags = QEMU_BIG_ENDIAN_FLAG;
--#endif
--    surface->data = data;
--
--    return surface;
--}
--
- void defaultallocator_free_displaysurface(DisplaySurface *surface)
 -void qemu_free_displaysurface(DisplaySurface *surface)
--{
--    if (surface == NULL)
--        return;
--    if (surface->flags & QEMU_ALLOCATED_FLAG)
--        qemu_free(surface->data);
--    qemu_free(surface);
  }
diff --cc console.h
index f9b8e277498440346d87465fef737261ccc0e9ab,4a2f06fbd652cc3e3a5382df989dc8ea96c060be..d0a99c60f1812898ad2b3bcff7b632da58e02a2b
+++ b/console.h
@@@ -92,52 -109,141 +92,27 @@@ struct DisplayState 
      void (*dpy_fill)(struct DisplayState *s, int x, int y,
                       int w, int h, uint32_t c);
      void (*dpy_text_cursor)(struct DisplayState *s, int x, int y);
 -
 -    struct DisplayChangeListener *next;
  };
  
 -struct DisplayState {
 -    struct DisplaySurface *surface;
 -    void *opaque;
 -    struct QEMUTimer *gui_timer;
 -
 -    struct DisplayChangeListener* listeners;
 -
 -    void (*mouse_set)(int x, int y, int on);
 -    void (*cursor_define)(int width, int height, int bpp, int hot_x, int hot_y,
 -                          uint8_t *image, uint8_t *mask);
 -
 -    struct DisplayState *next;
 -};
 -
 -void register_displaystate(DisplayState *ds);
 -DisplayState *get_displaystate(void);
 -DisplaySurface* qemu_create_displaysurface(int width, int height, int bpp, int linesize);
 -DisplaySurface* qemu_resize_displaysurface(DisplaySurface *surface,
 -                                           int width, int height, int bpp, int linesize);
 -DisplaySurface* qemu_create_displaysurface_from(int width, int height, int bpp,
 -                                                int linesize, uint8_t *data);
 -void qemu_free_displaysurface(DisplaySurface *surface);
 -PixelFormat qemu_different_endianness_pixelformat(int bpp);
 -PixelFormat qemu_default_pixelformat(int bpp);
 -
 -static inline int is_buffer_shared(DisplaySurface *surface)
 -{
 -    return (!(surface->flags & QEMU_ALLOCATED_FLAG));
 -}
 -
 -static inline void register_displaychangelistener(DisplayState *ds, DisplayChangeListener *dcl)
 -{
 -    dcl->next = ds->listeners;
 -    ds->listeners = dcl;
 -}
 -
  static inline void dpy_update(DisplayState *s, int x, int y, int w, int h)
  {
 -    struct DisplayChangeListener *dcl = s->listeners;
 -    while (dcl != NULL) {
 -        dcl->dpy_update(s, x, y, w, h);
 -        dcl = dcl->next;
 -    }
 -}
 -
 -static inline void dpy_resize(DisplayState *s)
 -{
 -    struct DisplayChangeListener *dcl = s->listeners;
 -    while (dcl != NULL) {
 -        dcl->dpy_resize(s);
 -        dcl = dcl->next;
 -    }
 +    s->dpy_update(s, x, y, w, h);
  }
  
 -static inline void dpy_setdata(DisplayState *s)
 +static inline void dpy_resize(DisplayState *s, int w, int h)
  {
 -    struct DisplayChangeListener *dcl = s->listeners;
 -    while (dcl != NULL) {
 -        if (dcl->dpy_setdata) dcl->dpy_setdata(s);
 -        dcl = dcl->next;
 -    }
 +    s->dpy_resize(s, w, h);
  }
 -
 -static inline void dpy_refresh(DisplayState *s)
 +static inline void dpy_resize_shared(DisplayState *s, int w, int h, int depth, int linesize, void *pixels)
  {
 -    struct DisplayChangeListener *dcl = s->listeners;
 -    while (dcl != NULL) {
 -        if (dcl->dpy_refresh) dcl->dpy_refresh(s);
 -        dcl = dcl->next;
 -    }
 -}
 -
 -static inline void dpy_copy(struct DisplayState *s, int src_x, int src_y,
 -                             int dst_x, int dst_y, int w, int h) {
 -    struct DisplayChangeListener *dcl = s->listeners;
 -    while (dcl != NULL) {
 -        if (dcl->dpy_copy)
 -            dcl->dpy_copy(s, src_x, src_y, dst_x, dst_y, w, h);
 -        else /* TODO */
 -            dcl->dpy_update(s, dst_x, dst_y, w, h);
 -        dcl = dcl->next;
 -    }
 +    s->dpy_resize_shared(s, w, h, depth, linesize, pixels);
  }
 -
 -static inline void dpy_fill(struct DisplayState *s, int x, int y,
 -                             int w, int h, uint32_t c) {
 -    struct DisplayChangeListener *dcl = s->listeners;
 -    while (dcl != NULL) {
 -        if (dcl->dpy_fill) dcl->dpy_fill(s, x, y, w, h, c);
 -        dcl = dcl->next;
 -    }
 -}
 -
 -static inline void dpy_cursor(struct DisplayState *s, int x, int y) {
 -    struct DisplayChangeListener *dcl = s->listeners;
 -    while (dcl != NULL) {
 -        if (dcl->dpy_text_cursor) dcl->dpy_text_cursor(s, x, y);
 -        dcl = dcl->next;
 -    }
 -}
 -
 -static inline int ds_get_linesize(DisplayState *ds)
 -{
 -    return ds->surface->linesize;
 -}
 -
 -static inline uint8_t* ds_get_data(DisplayState *ds)
 +static inline void dpy_cursor(DisplayState *s, int x, int y)
  {
 -    return ds->surface->data;
 -}
 -
 -static inline int ds_get_width(DisplayState *ds)
 -{
 -    return ds->surface->width;
 -}
 -
 -static inline int ds_get_height(DisplayState *ds)
 -{
 -    return ds->surface->height;
 -}
 -
 -static inline int ds_get_bits_per_pixel(DisplayState *ds)
 -{
 -    return ds->surface->pf.bits_per_pixel;
 -}
 -
 -static inline int ds_get_bytes_per_pixel(DisplayState *ds)
 -{
 -    return ds->surface->pf.bytes_per_pixel;
 +    if (s->dpy_text_cursor)
 +        s->dpy_text_cursor(s, x, y);
  }
  
- static inline int ds_get_linesize(DisplayState *ds)
- {
-     return ds->linesize;
- }
- static inline uint8_t* ds_get_data(DisplayState *ds)
- {
-     return ds->data;
- }
- static inline int ds_get_width(DisplayState *ds)
- {
-     return ds->width;
- }
- static inline int ds_get_height(DisplayState *ds)
- {
-     return ds->height;
- }
- static inline int ds_get_bits_per_pixel(DisplayState *ds)
- {
-     return ds->depth;
- }
  typedef unsigned long console_ch_t;
  static inline void console_write_ch(console_ch_t *dest, uint32_t ch)
  {
diff --cc cutils.c
Simple merge
Simple merge
diff --cc exec-all.h
Simple merge
diff --cc hw/boards.h
Simple merge
diff --cc hw/cirrus_vga.c
index cb22c389121d8e4a5c09ed01455dbdaa5aeaf5e4,d261e40eba1e2be177b903c513c163c06ad1f33a..91d248eb26d536a1a24f293462f4d778437e4af1
@@@ -2648,9 -2625,8 +2640,11 @@@ static CPUWriteMemoryFunc *cirrus_linea
  
  static void map_linear_vram(CirrusVGAState *s)
  {
 +    if (s->lfb_addr && s->lfb_end && s->vram_gmfn != s->lfb_addr) {
 +        set_vram_mapping(s, s->lfb_addr, s->lfb_end);
 +    }
+     vga_dirty_log_stop((VGAState *)s);
      if (!s->map_addr && s->lfb_addr && s->lfb_end) {
          s->map_addr = s->lfb_addr;
          s->map_end = s->lfb_end;
  
  static void unmap_linear_vram(CirrusVGAState *s)
  {
-     if (s->map_addr && s->lfb_addr && s->lfb_end) {
-         vga_dirty_log_stop((VGAState *)s);
 +    if (s->lfb_addr && s->lfb_end && s->vram_gmfn != s->lfb_addr) {
 +        unset_vram_mapping(s);
 +    }
+     vga_dirty_log_stop((VGAState *)s);
+     if (s->map_addr && s->lfb_addr && s->lfb_end)
          s->map_addr = s->map_end = 0;
-     }
  
      cpu_register_physical_memory(isa_mem_base + 0xa0000, 0x20000,
                                   s->vga_io_memory);
@@@ -3348,9 -3253,36 +3310,36 @@@ static void cirrus_init_common(CirrusVG
                                   s->vga_io_memory);
      qemu_register_coalesced_mmio(isa_mem_base + 0x000a0000, 0x20000);
  
+     /* I/O handler for LFB */
+     s->cirrus_linear_io_addr =
+         cpu_register_io_memory(0, cirrus_linear_read, cirrus_linear_write, s);
+     s->cirrus_linear_write = cpu_get_io_memory_write(s->cirrus_linear_io_addr);
+     /* I/O handler for LFB */
+     s->cirrus_linear_bitblt_io_addr =
+         cpu_register_io_memory(0, cirrus_linear_bitblt_read,
+                                cirrus_linear_bitblt_write, s);
+     /* I/O handler for memory-mapped I/O */
+     s->cirrus_mmio_io_addr =
+         cpu_register_io_memory(0, cirrus_mmio_read, cirrus_mmio_write, s);
+     s->real_vram_size =
+         (s->device_id == CIRRUS_ID_CLGD5446) ? 4096 * 1024 : 2048 * 1024;
+     /* XXX: s->vram_size must be a power of two */
+     s->cirrus_addr_mask = s->real_vram_size - 1;
+     s->linear_mmio_mask = s->real_vram_size - 256;
+     s->get_bpp = cirrus_get_bpp;
+     s->get_offsets = cirrus_get_offsets;
+     s->get_resolution = cirrus_get_resolution;
+     s->cursor_invalidate = cirrus_cursor_invalidate;
+     s->cursor_draw_line = cirrus_cursor_draw_line;
      qemu_register_reset(cirrus_reset, s);
      cirrus_reset(s);
 -    register_savevm("cirrus_vga", 0, 2, cirrus_vga_save, cirrus_vga_load, s);
 +    register_savevm("cirrus_vga", 0, 3, cirrus_vga_save, cirrus_vga_load, s);
  }
  
  /***************************************
@@@ -3372,8 -3299,10 +3361,8 @@@ void isa_cirrus_vga_init(uint8_t *vga_r
      s = qemu_mallocz(sizeof(CirrusVGAState));
  
      vga_common_init((VGAState *)s,
-                     ds, vga_ram_base, vga_ram_offset, vga_ram_size);
+                     vga_ram_base, vga_ram_offset, vga_ram_size);
      cirrus_init_common(s, CIRRUS_ID_CLGD5430, 0);
 -    s->ds = graphic_console_init(s->update, s->invalidate,
 -                                 s->screen_dump, s->text_update, s);
      /* XXX ISA-LFB support */
  }
  
@@@ -3430,32 -3373,23 +3439,29 @@@ void pci_cirrus_vga_init(PCIBus *bus, u
      /* setup PCI configuration registers */
      d = (PCICirrusVGAState *)pci_register_device(bus, "Cirrus VGA",
                                                   sizeof(PCICirrusVGAState),
-                                                  -1, NULL, NULL);
+                                                  -1, NULL, pci_cirrus_write_config);
      pci_conf = d->dev.config;
-     pci_conf[0x00] = (uint8_t) (PCI_VENDOR_CIRRUS & 0xff);
-     pci_conf[0x01] = (uint8_t) (PCI_VENDOR_CIRRUS >> 8);
-     pci_conf[0x02] = (uint8_t) (device_id & 0xff);
-     pci_conf[0x03] = (uint8_t) (device_id >> 8);
+     pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_CIRRUS);
+     pci_config_set_device_id(pci_conf, device_id);
      pci_conf[0x04] = PCI_COMMAND_IOACCESS | PCI_COMMAND_MEMACCESS;
-     pci_conf[0x0a] = PCI_CLASS_SUB_VGA;
-     pci_conf[0x0b] = PCI_CLASS_BASE_DISPLAY;
+     pci_config_set_class(pci_conf, PCI_CLASS_DISPLAY_VGA);
      pci_conf[0x0e] = PCI_CLASS_HEADERTYPE_00h;
 +    pci_conf[0x2c] = 0x53; /* subsystem vendor: XenSource */
 +    pci_conf[0x2d] = 0x58;
 +    pci_conf[0x2e] = 0x01; /* subsystem device */
 +    pci_conf[0x2f] = 0x00;
 +
 +    if (vga_ram_size != 4*1024*1024) {
 +        fprintf(stderr, "The -videoram option does not work with the cirrus vga model. Video ram set to 4M. \n");
 +        vga_ram_size = 4*1024*1024;
 +    }
  
      /* setup VGA */
      s = &d->cirrus_vga;
      vga_common_init((VGAState *)s,
-                     ds, vga_ram_base, vga_ram_offset, vga_ram_size);
+                     vga_ram_base, vga_ram_offset, vga_ram_size);
      cirrus_init_common(s, device_id, 1);
  
 -    s->ds = graphic_console_init(s->update, s->invalidate,
 -                                 s->screen_dump, s->text_update, s);
 -
      s->pci_dev = (PCIDevice *)d;
  
      /* setup memory space */
diff --cc hw/eepro100.c
Simple merge
diff --cc hw/ide.c
index 42920b07635866c942b06c27cfad3e4238a67102,bcaee46a7e142fa3410fce27bd32a7668667508e..7031ba1f4956a596f772ec025ab1272562b00dac
+++ b/hw/ide.c
@@@ -503,178 -505,8 +511,179 @@@ typedef struct PCIIDEState 
      int type; /* see IDE_TYPE_xxx */
  } PCIIDEState;
  
 +static PCIIDEState *principal_ide_controller;
 +
 +#if defined(__ia64__)
 +#include <xen/hvm/ioreq.h>
 +
 +struct buffered_piopage *buffered_pio_page;
 +
 +static inline struct pio_buffer *
 +piobuf_by_addr(uint32_t addr)
 +{
 +    if (addr == 0x1F0)
 +        return &buffered_pio_page->pio[PIO_BUFFER_IDE_PRIMARY];
 +    if (addr == 0x170)
 +        return &buffered_pio_page->pio[PIO_BUFFER_IDE_SECONDARY];
 +    return NULL;
 +}
 +
 +static void
 +buffered_pio_init(void)
 +{
 +    struct pio_buffer *p1, *p2;
 +    uint32_t off1, off2;
 +
 +    if (!buffered_pio_page)
 +        return;
 +
 +    p1 = &buffered_pio_page->pio[PIO_BUFFER_IDE_PRIMARY];
 +    p2 = &buffered_pio_page->pio[PIO_BUFFER_IDE_SECONDARY];
 +    off1 = offsetof(struct buffered_piopage, buffer);
 +    off2 = (off1 + TARGET_PAGE_SIZE)/2;
 +
 +    p1->buf_size = off2 - off1;
 +    p1->page_offset = off1;
 +
 +    p2->buf_size = TARGET_PAGE_SIZE - off2;
 +    p2->page_offset = off2;
 +}
 +
 +static inline void
 +__buffered_pio_flush(struct pio_buffer *piobuf, IDEState *s, uint32_t pointer)
 +{
 +    uint8_t *buf = (uint8_t *)buffered_pio_page + piobuf->page_offset;
 +    memcpy(s->data_ptr, buf, pointer);
 +    s->data_ptr += pointer;
 +}
 +
 +static inline void
 +buffered_pio_flush(struct pio_buffer *piobuf)
 +{
 +    IDEState *s = piobuf->opaque;
 +    uint32_t pointer = piobuf->pointer;
 +
 +    if (s != NULL && pointer > 0)
 +        __buffered_pio_flush(piobuf, s, pointer);
 +}
 +
 +static inline void
 +buffered_pio_reset(IDEState *s)
 +{
 +    struct pio_buffer *piobuf;
 +
 +    if ((unsigned)s->drive_serial - 1 < 2)      /* 1,2 */
 +        piobuf = &buffered_pio_page->pio[PIO_BUFFER_IDE_PRIMARY];
 +    else if ((unsigned)s->drive_serial - 3 < 2) /* 3,4 */
 +        piobuf = &buffered_pio_page->pio[PIO_BUFFER_IDE_SECONDARY];
 +    else
 +        return;
 +    buffered_pio_flush(piobuf);
 +    piobuf->pointer = 0;
 +    piobuf->data_end = 0;
 +    piobuf->opaque = NULL;
 +}
 +
 +static inline void
 +buffered_pio_write(IDEState *s, uint32_t addr, int size)
 +{
 +    struct pio_buffer *piobuf = piobuf_by_addr(addr);
 +    int data_end;
 +
 +    if (!piobuf)
 +        return;
 +    buffered_pio_flush(piobuf);
 +    data_end = s->data_end - s->data_ptr - size;
 +    if (data_end <= 0)
 +        data_end = 0;
 +    else if (data_end > piobuf->buf_size)
 +        data_end = piobuf->buf_size;
 +    piobuf->pointer = 0;
 +    piobuf->data_end = data_end;
 +    piobuf->opaque = s;
 +}
 +
 +static inline void
 +buffered_pio_read(IDEState *s, uint32_t addr, int size)
 +{
 +    struct pio_buffer *piobuf = piobuf_by_addr(addr);
 +    int data_end;
 +
 +    if (!piobuf)
 +        return;
 +    s->data_ptr += piobuf->pointer;
 +    data_end = s->data_end - s->data_ptr - size;
 +    if (data_end <= 0) {
 +        data_end = 0;
 +    } else {
 +      uint8_t *buf = (uint8_t *)buffered_pio_page + piobuf->page_offset;
 +        if (data_end > piobuf->buf_size)
 +            data_end = piobuf->buf_size;
 +        memcpy(buf, s->data_ptr + size, data_end);
 +    }
 +    piobuf->pointer = 0;
 +    piobuf->data_end = data_end;
 +    piobuf->opaque = NULL;
 +}
 +
 +/*
 + * buffered pio reads are undone. It results in normal pio when the domain
 + * is restored.
 + * buffered pio writes are handled before saving domain.
 + * However currently pci_ide_save/load() just discards a pending transfer. XXX
 + */
 +static void
 +__handle_buffered_pio(struct pio_buffer *piobuf)
 +{
 +    IDEState *s = piobuf->opaque;
 +    uint32_t pointer = piobuf->pointer;
 +
 +    
 +    if (pointer == 0)
 +        return;/* no buffered pio */
 +
 +    if (s != NULL) {
 +        /* written data are pending in pio_buffer. process it */
 +        __buffered_pio_flush(piobuf, s, pointer);
 +    } else {
 +        /* data are buffered for pio read in pio_buffer.
 +         * undone buffering by buffered_pio_read()
 +         */
 +        if (pointer > s->data_ptr - s->io_buffer)
 +            pointer = s->data_ptr - s->io_buffer;
 +        s->data_ptr -= pointer;
 +    }
 +      
 +    piobuf->pointer = 0;
 +    piobuf->data_end = 0;
 +    piobuf->opaque = NULL;
 +}
 +
 +void
 +handle_buffered_pio(void)
 +{
 +    struct pio_buffer *p1, *p2;
 +
 +    if (!buffered_pio_page)
 +        return;
 +
 +    p1 = &buffered_pio_page->pio[PIO_BUFFER_IDE_PRIMARY];
 +    p2 = &buffered_pio_page->pio[PIO_BUFFER_IDE_SECONDARY];
 +
 +    __handle_buffered_pio(p1);
 +    __handle_buffered_pio(p2);
 +}
 +
 +#else /* !__ia64__ */
 +#define buffered_pio_init()         do {} while (0)
 +#define buffered_pio_reset(I)       do {} while (0)
 +#define buffered_pio_write(I,A,S)   do {} while (0)
 +#define buffered_pio_read(I,A,S)    do {} while (0)
 +#endif
 +
 +
  static void ide_dma_start(IDEState *s, BlockDriverCompletionFunc *dma_cb);
+ static void ide_dma_restart(IDEState *s);
  static void ide_atapi_cmd_read_dma_cb(void *opaque, int ret);
  
  static void padstr(char *str, const char *src, int len)
@@@ -1094,14 -1006,39 +1187,47 @@@ static int dma_buf_rw(BMDMAState *bm, i
      return 1;
  }
  
+ typedef struct {
+     BMDMAState *bm;
+     void (*cb)(void *opaque, int ret);
+     QEMUBH *bh;
+ } MapFailureContinuation;
+ static void reschedule_dma(void *opaque)
+ {
+     MapFailureContinuation *cont = opaque;
+     cont->cb(cont->bm, 0);
+     qemu_bh_delete(cont->bh);
+     qemu_free(cont);
+ }
+ static void continue_after_map_failure(void *opaque)
+ {
+     MapFailureContinuation *cont = opaque;
+     cont->bh = qemu_bh_new(reschedule_dma, opaque);
+     qemu_bh_schedule(cont->bh);
+ }
+ static void wait_for_bounce_buffer(BMDMAState *bmdma,
+                                    void (*cb)(void *opaque, int ret))
+ {
+     MapFailureContinuation *cont = qemu_malloc(sizeof(*cont));
+     cont->bm = bmdma;
+     cont->cb = cb;
+     cpu_register_map_client(cont, continue_after_map_failure);
+ }
 +static void ide_dma_eot(BMDMAState *bm) {
 +    bm->status &= ~BM_STATUS_DMAING;
 +    bm->status |= BM_STATUS_INT;
 +    bm->dma_cb = NULL;
 +    bm->ide_if = NULL;
 +    bm->aiocb = NULL;
 +}
 +
  static void ide_read_dma_cb(void *opaque, int ret)
  {
      BMDMAState *bm = opaque;
@@@ -1177,12 -1121,10 +1308,14 @@@ static void ide_sector_write(IDEState *
      if (n > s->req_nb_sectors)
          n = s->req_nb_sectors;
      ret = bdrv_write(s->bs, sector_num, s->io_buffer, n);
 +    if (ret == 0 && !s->write_cache) {
 +      ret = bdrv_flush(s->bs);
 +    }
++
      if (ret != 0) {
-       ide_rw_error(s);
-       return;
+         if (ide_handle_write_error(s, -ret, BM_STATUS_PIO_RETRY))
+             return;
      }
  
      s->nsector -= n;
      }
  }
  
 +static void ide_write_flush_cb(void *opaque, int ret) {
 +    BMDMAState *bm = opaque;
 +    IDEState *s = bm->ide_if;
 +
 +    if (ret != 0) {
 +      ide_dma_error(s);
 +      return;
 +    }
 +    s->status = READY_STAT | SEEK_STAT;
 +    ide_set_irq(s);
 +    ide_dma_eot(bm);
 +    return;
 +}
 +
+ static void ide_dma_restart_cb(void *opaque, int running, int reason)
+ {
+     BMDMAState *bm = opaque;
+     if (!running)
+         return;
+     if (bm->status & BM_STATUS_DMA_RETRY) {
+         bm->status &= ~BM_STATUS_DMA_RETRY;
+         ide_dma_restart(bm->ide_if);
+     } else if (bm->status & BM_STATUS_PIO_RETRY) {
+         bm->status &= ~BM_STATUS_PIO_RETRY;
+         ide_sector_write(bm->ide_if);
+     }
+ }
  static void ide_write_dma_cb(void *opaque, int ret)
  {
      BMDMAState *bm = opaque;
      int64_t sector_num;
  
      if (ret < 0) {
-       ide_dma_error(s);
-       return;
+         if (ide_handle_write_error(s, -ret,  BM_STATUS_DMA_RETRY))
+             return;
      }
  
 +    if (!s->bs) return; /* ouch! (see ide_flush_cb) */
 +
      n = s->io_buffer_size >> 9;
      sector_num = ide_get_sector(s);
      if (n > 0) {
@@@ -3396,7 -3262,7 +3565,7 @@@ static int pci_ide_load(QEMUFile* f, vo
      PCIIDEState *d = opaque;
      int ret, i;
  
-     if (version_id != 1 && version_id != 2)
 -    if (version_id != 2)
++    if (version_id != 3)
          return -EINVAL;
      ret = pci_device_load(&d->dev, f);
      if (ret < 0)
@@@ -3474,15 -3345,10 +3648,13 @@@ void pci_cmd646_ide_init(PCIBus *bus, B
                                             sizeof(PCIIDEState),
                                             -1,
                                             NULL, NULL);
 +    if (principal_ide_controller)
 +      abort();
 +    principal_ide_controller = d;
      d->type = IDE_TYPE_CMD646;
      pci_conf = d->dev.config;
-     pci_conf[0x00] = 0x95; // CMD646
-     pci_conf[0x01] = 0x10;
-     pci_conf[0x02] = 0x46;
-     pci_conf[0x03] = 0x06;
+     pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_CMD);
+     pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_CMD_646);
  
      pci_conf[0x08] = 0x07; // IDE controller revision
      pci_conf[0x09] = 0x8f;
      ide_init2(&d->ide_if[0], hd_table[0], hd_table[1], irq[0]);
      ide_init2(&d->ide_if[2], hd_table[2], hd_table[3], irq[1]);
  
-     register_savevm("ide", 0, 1, pci_ide_save, pci_ide_load, d);
 -    register_savevm("ide", 0, 2, pci_ide_save, pci_ide_load, d);
++    register_savevm("ide", 0, 3, pci_ide_save, pci_ide_load, d);
      qemu_register_reset(cmd646_reset, d);
      cmd646_reset(d);
  }
@@@ -3557,18 -3419,11 +3728,15 @@@ void pci_piix3_ide_init(PCIBus *bus, Bl
      d->type = IDE_TYPE_PIIX3;
  
      pci_conf = d->dev.config;
-     pci_conf[0x00] = 0x86; // Intel
-     pci_conf[0x01] = 0x80;
-     pci_conf[0x02] = 0x10;
-     pci_conf[0x03] = 0x70;
+     pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_INTEL);
+     pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82371SB_1);
      pci_conf[0x09] = 0x80; // legacy ATA mode
-     pci_conf[0x0a] = 0x01; // class_sub = PCI_IDE
-     pci_conf[0x0b] = 0x01; // class_base = PCI_mass_storage
+     pci_config_set_class(pci_conf, PCI_CLASS_STORAGE_IDE);
      pci_conf[0x0e] = 0x00; // header_type
 +    pci_conf[0x2c] = 0x53; /* subsystem vendor: XenSource */
 +    pci_conf[0x2d] = 0x58;
 +    pci_conf[0x2e] = 0x01; /* subsystem device */
 +    pci_conf[0x2f] = 0x00;
  
      qemu_register_reset(piix3_reset, d);
      piix3_reset(d);
      ide_init_ioport(&d->ide_if[0], 0x1f0, 0x3f6);
      ide_init_ioport(&d->ide_if[2], 0x170, 0x376);
  
 -    register_savevm("ide", 0, 2, pci_ide_save, pci_ide_load, d);
 +    buffered_pio_init();
 +
-     register_savevm("ide", 0, 2, pci_ide_save, pci_ide_load, d);
++    register_savevm("ide", 0, 3, pci_ide_save, pci_ide_load, d);
  }
  
  /* hd_table must contain 4 block drivers */
@@@ -3602,18 -3455,11 +3770,15 @@@ void pci_piix4_ide_init(PCIBus *bus, Bl
      d->type = IDE_TYPE_PIIX4;
  
      pci_conf = d->dev.config;
-     pci_conf[0x00] = 0x86; // Intel
-     pci_conf[0x01] = 0x80;
-     pci_conf[0x02] = 0x11;
-     pci_conf[0x03] = 0x71;
+     pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_INTEL);
+     pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82371AB);
      pci_conf[0x09] = 0x80; // legacy ATA mode
-     pci_conf[0x0a] = 0x01; // class_sub = PCI_IDE
-     pci_conf[0x0b] = 0x01; // class_base = PCI_mass_storage
+     pci_config_set_class(pci_conf, PCI_CLASS_STORAGE_IDE);
      pci_conf[0x0e] = 0x00; // header_type
 +    pci_conf[0x2c] = 0x53; /* subsystem vendor: XenSource */
 +    pci_conf[0x2d] = 0x58;
 +    pci_conf[0x2e] = 0x01; /* subsystem device */
 +    pci_conf[0x2f] = 0x00;
  
      qemu_register_reset(piix3_reset, d);
      piix3_reset(d);
      ide_init_ioport(&d->ide_if[0], 0x1f0, 0x3f6);
      ide_init_ioport(&d->ide_if[2], 0x170, 0x376);
  
 -    register_savevm("ide", 0, 2, pci_ide_save, pci_ide_load, d);
 +    buffered_pio_init();
 +
-     register_savevm("ide", 0, 2, pci_ide_save, pci_ide_load, d);
++    register_savevm("ide", 0, 3, pci_ide_save, pci_ide_load, d);
  }
  
+ #if defined(TARGET_PPC)
  /***********************************************************/
  /* MacIO based PowerPC IDE */
  
diff --cc hw/lsi53c895a.c
Simple merge
Simple merge
diff --cc hw/mips_r4k.c
Simple merge
diff --cc hw/ne2000.c
index 0cb1c4aaf29a68ac722441f868e6b2f295ff296f,1bad3fdf78a52b5f50b589cd38f371896a22cb90..0a25a9d80022289d1ce9ac4a8e569fccc495b1e8
@@@ -822,17 -790,10 +822,14 @@@ void pci_ne2000_init(PCIBus *bus, NICIn
                                                devfn,
                                                NULL, NULL);
      pci_conf = d->dev.config;
-     pci_conf[0x00] = 0xec; // Realtek 8029
-     pci_conf[0x01] = 0x10;
-     pci_conf[0x02] = 0x29;
-     pci_conf[0x03] = 0x80;
-     pci_conf[0x0a] = 0x00; // ethernet network controller
-     pci_conf[0x0b] = 0x02;
+     pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_REALTEK);
+     pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_REALTEK_RTL8029);
+     pci_config_set_class(pci_conf, PCI_CLASS_NETWORK_ETHERNET);
      pci_conf[0x0e] = 0x00; // header_type
 +    pci_conf[0x2c] = 0x53; /* subsystem vendor: XenSource */
 +    pci_conf[0x2d] = 0x58;
 +    pci_conf[0x2e] = 0x01; /* subsystem device */
 +    pci_conf[0x2f] = 0x00;
      pci_conf[0x3d] = 1; // interrupt pin 0
  
      pci_register_io_region(&d->dev, 0, 0x100,
diff --cc hw/pc.c
index 2ffbefdbb9229f13ecb22ebf21c13affd632e5b3,176730e063aba4bbfd149845864553507dc8cd7e..81e0935cdc050d6abe647d741bd21c0ef2f720d4
+++ b/hw/pc.c
@@@ -772,11 -752,10 +772,11 @@@ static void pc_init_ne2k_isa(NICInfo *n
  
  /* PC hardware initialisation */
  static void pc_init1(ram_addr_t ram_size, int vga_ram_size,
-                      const char *boot_device, DisplayState *ds,
+                      const char *boot_device,
                       const char *kernel_filename, const char *kernel_cmdline,
                       const char *initrd_filename,
 -                     int pci_enabled, const char *cpu_model)
 +                     int pci_enabled, const char *cpu_model,
 +                   const char *direct_pci)
  {
      char buf[1024];
      int ret, linux_boot, i;
@@@ -996,22 -968,7 +996,22 @@@ vga_bios_error
          }
      }
  
-     rtc_state = rtc_init(0x70, i8259[8]);
 +#ifdef CONFIG_PASSTHROUGH
 +    /* Pass-through Initialization
 +     * init libpci even direct_pci is null, as can hotplug a dev runtime
 +     */
 +    if ( pci_enabled )
 +    {
 +        rc = pt_init(pci_bus, direct_pci); 
 +        if ( rc < 0 )
 +        {
 +            fprintf(logfile, "Error: Initialization failed for pass-through devices\n");
 +            exit(1);
 +        }
 +    }
 +#endif
 +
+     rtc_state = rtc_init(0x70, i8259[8], 2000);
  
      qemu_register_boot_set(pc_boot_set, rtc_state);
  
@@@ -1177,13 -1115,11 +1177,13 @@@ static void pc_init_pci(ram_addr_t ram_
                          const char *kernel_filename,
                          const char *kernel_cmdline,
                          const char *initrd_filename,
 -                        const char *cpu_model)
 +                        const char *cpu_model,
 +                        const char *direct_pci)
  {
-     pc_init1(ram_size, vga_ram_size, boot_device, ds,
+     pc_init1(ram_size, vga_ram_size, boot_device,
               kernel_filename, kernel_cmdline,
 -             initrd_filename, 1, cpu_model);
 +             initrd_filename, 1, cpu_model,
 +             direct_pci);
  }
  
  static void pc_init_isa(ram_addr_t ram_size, int vga_ram_size,
                          const char *kernel_filename,
                          const char *kernel_cmdline,
                          const char *initrd_filename,
 -                        const char *cpu_model)
 +                        const char *cpu_model,
 +                        const char *direct_pci)
  {
-     pc_init1(ram_size, vga_ram_size, boot_device, ds,
+     pc_init1(ram_size, vga_ram_size, boot_device,
               kernel_filename, kernel_cmdline,
 -             initrd_filename, 0, cpu_model);
 +             initrd_filename, 0, cpu_model,
 +             direct_pci);
 +}
 +
 +/* set CMOS shutdown status register (index 0xF) as S3_resume(0xFE)
 +   BIOS will read it and start S3 resume at POST Entry*/
 +void cmos_set_s3_resume(void)
 +{
 +    if (rtc_state)
 +        rtc_set_memory(rtc_state, 0xF, 0xFE);
  }
  
  /* set CMOS shutdown status register (index 0xF) as S3_resume(0xFE)
diff --cc hw/pc.h
index 0a8f8e3d1108f53b07705a7d5b715d736a1136cc,c67294d0fe0a718378f6f209d6326cb70bba9743..5a43c9582f829d7cf1cfd916c52dce45aed1b555
+++ b/hw/pc.h
@@@ -130,12 -127,18 +131,18 @@@ enum vga_retrace_method 
  
  extern enum vga_retrace_method vga_retrace_method;
  
 -int isa_vga_init(uint8_t *vga_ram_base,
+ #ifndef TARGET_SPARC
+ #define VGA_RAM_SIZE (8192 * 1024)
+ #else
+ #define VGA_RAM_SIZE (9 * 1024 * 1024)
+ #endif
 +int isa_vga_init(DisplayState *ds, uint8_t *vga_ram_base,
                   unsigned long vga_ram_offset, int vga_ram_size);
 -int pci_vga_init(PCIBus *bus, uint8_t *vga_ram_base,
 +int pci_vga_init(PCIBus *bus, DisplayState *ds, uint8_t *vga_ram_base,
                   unsigned long vga_ram_offset, int vga_ram_size,
                   unsigned long vga_bios_offset, int vga_bios_size);
 -int isa_vga_mm_init(uint8_t *vga_ram_base,
 +int isa_vga_mm_init(DisplayState *ds, uint8_t *vga_ram_base,
                      unsigned long vga_ram_offset, int vga_ram_size,
                      target_phys_addr_t vram_base, target_phys_addr_t ctrl_base,
                      int it_shift);
diff --cc hw/pci.c
Simple merge
diff --cc hw/pci.h
index 7645cd43798c88c06b1fab68f8856da4b5613a0a,edb0594924692d5b7baea8de16bb8de801cd4c7e..6136845b2dce95afcd9ea32846ef1e5620bfa776
+++ b/hw/pci.h
@@@ -131,30 -224,27 +229,48 @@@ int pci_bus_num(PCIBus *s)
  void pci_for_each_device(int bus_num, void (*fn)(PCIDevice *d));
  
  void pci_info(void);
- PCIBus *pci_bridge_init(PCIBus *bus, int devfn, uint32_t id,
+ PCIBus *pci_bridge_init(PCIBus *bus, int devfn, uint16_t vid, uint16_t did,
                          pci_map_irq_fn map_irq, const char *name);
  
 +/* PCI slot 6~7 support ACPI PCI hot plug */
 +#define PHP_SLOT_START  (6)
 +#define PHP_SLOT_END    (8)
 +#define PHP_SLOT_LEN    (PHP_SLOT_END - PHP_SLOT_START)
 +#define PHP_TO_PCI_SLOT(x) (x + PHP_SLOT_START)
 +#define PCI_TO_PHP_SLOT(x) (x - PHP_SLOT_START)
 +#define PHP_DEVFN_START (PHP_SLOT_START << 3)
 +#define PHP_DEVFN_END   (PHP_SLOT_END << 3)
 +
 +int insert_to_pci_slot(char*);
 +int test_pci_slot(int);
 +int bdf_to_slot(char*);
 +int power_on_php_slot(int);
 +int power_off_php_slot(int);
 +
 +/* pci_emulation.c */
 +#include "hw/pci_emulation.h"
 + 
 +void do_pci_add(char *devname);
 +void do_pci_del(char *devname);
 +
+ static inline void
+ pci_config_set_vendor_id(uint8_t *pci_config, uint16_t val)
+ {
+     cpu_to_le16wu((uint16_t *)&pci_config[PCI_VENDOR_ID], val);
+ }
+ static inline void
+ pci_config_set_device_id(uint8_t *pci_config, uint16_t val)
+ {
+     cpu_to_le16wu((uint16_t *)&pci_config[PCI_DEVICE_ID], val);
+ }
+ static inline void
+ pci_config_set_class(uint8_t *pci_config, uint16_t val)
+ {
+     cpu_to_le16wu((uint16_t *)&pci_config[PCI_CLASS_DEVICE], val);
+ }
  /* lsi53c895a.c */
  #define LSI_MAX_DEVS 7
  void lsi_scsi_attach(void *opaque, BlockDriverState *bd, int id);
diff --cc hw/pcnet.c
index 3f303305898c5cbc04b3ed7422bcc784596a2259,828d9801952f356dd7b098e2dbdbf3f6e1450793..2e20db063eb90b55809d71245ef63db119f70393
@@@ -1929,9 -1929,8 +1929,9 @@@ static int pcnet_load(QEMUFile *f, voi
      return 0;
  }
  
- static void pcnet_common_init(PCNetState *d, NICInfo *nd, const char *info_str)
+ static void pcnet_common_init(PCNetState *d, NICInfo *nd)
  {
 +    int instance;
      d->poll_timer = qemu_new_timer(vm_clock, pcnet_poll_timer, d);
  
      d->nd = nd;
diff --cc hw/piix_pci.c
index 54c1559bdefa3f8af6b32d1fd747bfefcdefd966,53e20a0ab8ebd05aa71784d0346a6e848244f2ec..36127a4ba112692074ca2b28c149c62f065c469b
@@@ -207,20 -190,15 +207,17 @@@ PCIBus *i440fx_init(PCIDevice **pi440fx
      register_ioport_read(0xcfc, 4, 4, pci_host_data_readl, s);
  
      d = pci_register_device(b, "i440FX", sizeof(PCIDevice), 0,
 -                            NULL, i440fx_write_config);
 +                            NULL, NULL);
  
-     d->config[0x00] = 0x86; // vendor_id
-     d->config[0x01] = 0x80;
-     d->config[0x02] = 0x37; // device_id
-     d->config[0x03] = 0x12;
+     pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_INTEL);
+     pci_config_set_device_id(d->config, PCI_DEVICE_ID_INTEL_82441);
      d->config[0x08] = 0x02; // revision
-     d->config[0x0a] = 0x00; // class_sub = host2pci
-     d->config[0x0b] = 0x06; // class_base = PCI_bridge
+     pci_config_set_class(d->config, PCI_CLASS_BRIDGE_HOST);
      d->config[0x0e] = 0x00; // header_type
  
 +#ifndef CONFIG_DM
      d->config[0x72] = 0x02; /* SMRAM */
 +#endif /* !CONFIG_DM */
  
      register_savevm("I440FX", 0, 2, i440fx_save, i440fx_load, d);
      *pi440fx_state = d;
diff --cc hw/rtl8139.c
Simple merge
diff --cc hw/scsi-disk.c
index d79998340712a1000a7a6fbf1bf063c0272709fb,c4d7d520b8ff450c7777406ed8c893fc88df510e..9745ca334a17006252c4e62cdf47a2f1efbb96b2
@@@ -39,15 -39,11 +39,17 @@@ do { fprintf(stderr, "scsi-disk: " fmt 
  #define STATUS_GOOD            0
  #define STATUS_CHECK_CONDITION 2
  
 +#ifdef CONFIG_STUBDOM
 +#include <xen/io/blkif.h>
 +#define SCSI_DMA_BUF_SIZE    ((BLKIF_MAX_SEGMENTS_PER_REQUEST - 1) * PAGE_SIZE)
 +#else
  #define SCSI_DMA_BUF_SIZE    131072
 +#endif
 +
  #define SCSI_MAX_INQUIRY_LEN 256
  
+ #define SCSI_REQ_STATUS_RETRY 0x01
  typedef struct SCSIRequest {
      SCSIDeviceState *dev;
      uint32_t tag;
diff --cc hw/serial.c
Simple merge
diff --cc hw/sun4u.c
Simple merge
diff --cc hw/vga.c
index 13519255794af03c9f9060183df37510deb39076,bad120ba40469b3fa7fbbe48f65af2b0fcdaec27..d1d61ea16a1ec4574e9cf4e816a3b18a398b88e8
+++ b/hw/vga.c
@@@ -1164,7 -1152,7 +1164,7 @@@ static int update_basic_params(VGAStat
  
  static inline int get_depth_index(DisplayState *s)
  {
--    switch(ds_get_bits_per_pixel(s)) {
++    switch(s->depth) {
      default:
      case 8:
          return 0;
      case 16:
          return 2;
      case 32:
--        return 3;
++        if (s->bgr)
++            return 4;
++        else
++            return 3;
      }
  }
  
@@@ -1245,51 -1276,8 +1248,51 @@@ static void vga_draw_text(VGAState *s, 
      vga_draw_glyph8_func *vga_draw_glyph8;
      vga_draw_glyph9_func *vga_draw_glyph9;
  
 -    vga_dirty_log_stop(s);
 +    /* Disable dirty bit tracking */
 +    xc_hvm_track_dirty_vram(xc_handle, domid, 0, 0, NULL);
 +
 +    /* total width & height */
 +    cheight = (s->cr[9] & 0x1f) + 1;
 +    cw = 8;
 +    if (!(s->sr[1] & 0x01))
 +        cw = 9;
 +    if (s->sr[1] & 0x08)
 +        cw = 16; /* NOTE: no 18 pixel wide */
 +    width = (s->cr[0x01] + 1);
 +    if (s->cr[0x06] == 100) {
 +        /* ugly hack for CGA 160x100x16 - explain me the logic */
 +        height = 100;
 +    } else {
 +        height = s->cr[0x12] |
 +            ((s->cr[0x07] & 0x02) << 7) |
 +            ((s->cr[0x07] & 0x40) << 3);
 +        height = (height + 1) / cheight;
 +    }
 +    if ((height * width) > CH_ATTR_SIZE) {
 +        /* better than nothing: exit if transient size is too big */
 +        return;
 +    }
 +
++    s->last_scr_width = width * cw;
++    s->last_scr_height = height * cheight;
 +    if (width != s->last_width || height != s->last_height ||
 +        cw != s->last_cw || cheight != s->last_ch || s->last_depth) {
-         s->last_scr_width = width * cw;
-         s->last_scr_height = height * cheight;
-         qemu_console_resize(s->ds, s->last_scr_width, s->last_scr_height);
++        dpy_resize(s->ds, s->last_scr_width, s->last_scr_height);
 +        s->last_depth = 0;
-         s->last_width = width;
-         s->last_height = height;
-         s->last_ch = cheight;
-         s->last_cw = cw;
 +        full_update = 1;
 +    }
++    s->last_width = width;
++    s->last_height = height;
++    s->last_ch = cheight;
++    s->last_cw = cw;
 +
 +    s->rgb_to_pixel = 
 +        rgb_to_pixel_dup_table[get_depth_index(s->ds)];
  
-     x_incr = cw * ds_get_bytes_per_pixel(s->ds);
 +    full_update |= update_palette16(s);
 +    palette = s->last_palette;
 +    
++    x_incr = cw * ((s->ds->depth + 7) >> 3);
      /* compute font data address (in plane 2) */
      v = s->sr[3];
      offset = (((v >> 4) & 1) | ((v << 1) & 6)) * 8192 * 4 + 2;
      line_offset = s->line_offset;
      s1 = s->vram_ptr + (s->start_addr * 4);
  
 -    vga_get_text_resolution(s, &width, &height, &cw, &cheight);
 -    x_incr = cw * ((ds_get_bits_per_pixel(s->ds) + 7) >> 3);
 +    /* total width & height */
 +    cheight = (s->cr[9] & 0x1f) + 1;
 +    cw = 8;
 +    if (!(s->sr[1] & 0x01))
 +        cw = 9;
 +    if (s->sr[1] & 0x08)
 +        cw = 16; /* NOTE: no 18 pixel wide */
-     x_incr = cw * ds_get_bytes_per_pixel(s->ds);
++    x_incr = cw * ((s->ds->depth + 7) >> 3);
 +    width = (s->cr[0x01] + 1);
 +    if (s->cr[0x06] == 100) {
 +        /* ugly hack for CGA 160x100x16 - explain me the logic */
 +        height = 100;
 +    } else {
 +        height = s->cr[0x12] |
 +            ((s->cr[0x07] & 0x02) << 7) |
 +            ((s->cr[0x07] & 0x40) << 3);
 +        height = (height + 1) / cheight;
 +    }
      if ((height * width) > CH_ATTR_SIZE) {
          /* better than nothing: exit if transient size is too big */
          return;
      }
  
      if (width != s->last_width || height != s->last_height ||
 -        cw != s->last_cw || cheight != s->last_ch || s->last_depth) {
 +        cw != s->last_cw || cheight != s->last_ch) {
          s->last_scr_width = width * cw;
          s->last_scr_height = height * cheight;
--        qemu_console_resize(s->ds, s->last_scr_width, s->last_scr_height);
 -        s->last_depth = 0;
++        qemu_console_resize(s->console, s->last_scr_width, s->last_scr_height);
          s->last_width = width;
          s->last_height = height;
          s->last_ch = cheight;
          vga_draw_glyph8 = vga_draw_glyph8_table[depth_index];
      vga_draw_glyph9 = vga_draw_glyph9_table[depth_index];
  
--    dest = ds_get_data(s->ds);
--    linesize = ds_get_linesize(s->ds);
++    dest = s->ds->data;
++    linesize = s->ds->linesize;
      ch_attr_ptr = s->last_ch_attr;
      for(cy = 0; cy < height; cy++) {
          d1 = dest;
@@@ -1612,50 -1615,46 +1615,38 @@@ static void vga_draw_graphic(VGAState *
          s->shift_control = shift_control;
          s->double_scan = double_scan;
      }
 +    if (shift_control == 1 && (s->sr[0x01] & 8)) {
 +        disp_width <<= 1;
 +    }
  
-     ds_depth = ds_get_bits_per_pixel(s->ds);
++    ds_depth = s->ds->depth;
      depth = s->get_bpp(s);
-     if (s->line_offset != s->last_line_offset || 
 -    if (s->line_offset != s->last_line_offset ||
--        disp_width != s->last_width ||
--        height != s->last_height ||
--        s->last_depth != depth) {
--#if defined(WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
--        if (depth == 16 || depth == 32) {
--#else
--        if (depth == 32) {
--#endif
--            if (is_graphic_console()) {
-                 qemu_free_displaysurface(s->ds);
 -                qemu_free_displaysurface(s->ds->surface);
--                s->ds->surface = qemu_create_displaysurface_from(disp_width, height, depth,
--                                                               s->line_offset,
--                                                               s->vram_ptr + (s->start_addr * 4));
--#if defined(WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
--                s->ds->surface->pf = qemu_different_endianness_pixelformat(depth);
--#endif
--                dpy_resize(s->ds);
--            } else {
--                qemu_console_resize(s->ds, disp_width, height);
--            }
--        } else {
--            qemu_console_resize(s->ds, disp_width, height);
--        }
++    if (s->ds->dpy_resize_shared) {
++        if (s->line_offset != s->last_line_offset || 
++            disp_width != s->last_width ||
++            height != s->last_height ||
++            s->last_depth != depth) {
++            dpy_resize_shared(s->ds, disp_width, height, depth, s->line_offset, s->vram_ptr + (s->start_addr * 4));
++            s->last_scr_width = disp_width;
++            s->last_scr_height = height;
++            s->last_width = disp_width;
++            s->last_height = height;
++            s->last_line_offset = s->line_offset;
++            s->last_depth = depth;
++            full_update = 1;
++        } else if (s->ds->shared_buf && (full_update || s->ds->data != s->vram_ptr + (s->start_addr * 4)))
++            s->ds->dpy_setdata(s->ds, s->vram_ptr + (s->start_addr * 4));
++    } else if (disp_width != s->last_width ||
++               height != s->last_height) {
++        dpy_resize(s->ds, disp_width, height);
          s->last_scr_width = disp_width;
          s->last_scr_height = height;
          s->last_width = disp_width;
          s->last_height = height;
--        s->last_line_offset = s->line_offset;
--        s->last_depth = depth;
          full_update = 1;
--    } else if (is_graphic_console() && is_buffer_shared(s->ds->surface) &&
--               (full_update || s->ds->surface->data != s->vram_ptr + (s->start_addr * 4))) {
--        s->ds->surface->data = s->vram_ptr + (s->start_addr * 4);
--        dpy_setdata(s->ds);
      }
  
 -    s->rgb_to_pixel =
 +    s->rgb_to_pixel = 
          rgb_to_pixel_dup_table[get_depth_index(s->ds)];
  
      if (shift_control == 0) {
              break;
          }
      }
 -    vga_draw_line = vga_draw_line_table[v * NB_DEPTHS + get_depth_index(s->ds)];
  
 -    if (!is_buffer_shared(s->ds->surface) && s->cursor_invalidate)
 +    vga_draw_line = vga_draw_line_table[v * NB_DEPTHS + get_depth_index(s->ds)];
-     if (!is_buffer_shared(s->ds->surface) && s->cursor_invalidate)
++    if (!s->ds->shared_buf && s->cursor_invalidate)
          s->cursor_invalidate(s);
  
      line_offset = s->line_offset;
      addr1 = (s->start_addr * 4);
      bwidth = (width * bits + 7) / 8;
      y_start = -1;
 -    page_min = 0x7fffffff;
 -    page_max = -1;
 -    d = ds_get_data(s->ds);
 -    linesize = ds_get_linesize(s->ds);
 +    page_min = 0;
 +    page_max = 0;
-     d = ds_get_data(s->ds);
-     linesize = ds_get_linesize(s->ds);
++    d = s->ds->data;
++    linesize = s->ds->linesize;
      y1 = 0;
      for(y = 0; y < height; y++) {
          addr = addr1;
          if (update) {
              if (y_start < 0)
                  y_start = y;
 -            if (page0 < page_min)
 +            if (page_min == 0 || page0 < page_min)
                  page_min = page0;
 -            if (page1 > page_max)
 +            if (page_max == 0 || page1 > page_max)
                  page_max = page1;
-             if (!is_buffer_shared(s->ds->surface)) {
 -            if (!(is_buffer_shared(s->ds->surface))) {
++            if (!s->ds->shared_buf) {
                  vga_draw_line(s, d, s->vram_ptr + addr, width);
                  if (s->cursor_draw_line)
                      s->cursor_draw_line(s, d, y);
@@@ -1856,15 -1807,15 +1847,15 @@@ static void vga_draw_blank(VGAState *s
  
      s->rgb_to_pixel =
          rgb_to_pixel_dup_table[get_depth_index(s->ds)];
--    if (ds_get_bits_per_pixel(s->ds) == 8)
++    if (s->ds->depth == 8)
          val = s->rgb_to_pixel(0, 0, 0);
      else
          val = 0;
-     w = s->last_scr_width * ds_get_bytes_per_pixel(s->ds);
 -    w = s->last_scr_width * ((ds_get_bits_per_pixel(s->ds) + 7) >> 3);
--    d = ds_get_data(s->ds);
++    w = s->last_scr_width * ((s->ds->depth + 7) >> 3);
++    d = s->ds->data;
      for(i = 0; i < s->last_scr_height; i++) {
          memset(d, val, w);
--        d += ds_get_linesize(s->ds);
++        d += s->ds->linesize;
      }
      dpy_update(s->ds, 0, 0,
                 s->last_scr_width, s->last_scr_height);
@@@ -1879,7 -1830,7 +1870,7 @@@ static void vga_update_display(void *op
      VGAState *s = (VGAState *)opaque;
      int full_update, graphic_mode;
  
--    if (ds_get_bits_per_pixel(s->ds) == 0) {
++    if (s->ds->depth == 0) {
          /* nothing to do */
      } else {
          full_update = 0;
@@@ -1989,9 -2003,9 +1980,7 @@@ static void vga_update_text(void *opaqu
              cw != s->last_cw || cheight != s->last_ch) {
              s->last_scr_width = width * cw;
              s->last_scr_height = height * cheight;
--            s->ds->surface->width = width;
--            s->ds->surface->height = height;
--            dpy_resize(s->ds);
++            qemu_console_resize(s->console, width, height);
              s->last_width = width;
              s->last_height = height;
              s->last_ch = cheight;
      s->last_width = 60;
      s->last_height = height = 3;
      dpy_cursor(s->ds, -1, -1);
--    s->ds->surface->width = s->last_width;
--    s->ds->surface->height = height;
--    dpy_resize(s->ds);
++    qemu_console_resize(s->console, s->last_width, height);
  
      for (dst = chardata, i = 0; i < s->last_width * height; i ++)
          console_write_ch(dst ++, ' ');
@@@ -2303,207 -2231,36 +2290,207 @@@ static void vga_map(PCIDevice *pci_dev
      }
  }
  
 -void vga_dirty_log_stop(VGAState *s)
 +/* do the same job as vgabios before vgabios get ready - yeah */
 +void vga_bios_init(VGAState *s)
 +{
 +    uint8_t palette_model[192] = {
 +        0,   0,   0,   0,   0, 170,   0, 170,
 +      0,   0, 170, 170, 170,   0,   0, 170,
 +        0, 170, 170,  85,   0, 170, 170, 170,
 +       85,  85,  85,  85,  85, 255,  85, 255,
 +       85,  85, 255, 255, 255,  85,  85, 255,
 +       85, 255, 255, 255,  85, 255, 255, 255,
 +        0,  21,   0,   0,  21,  42,   0,  63,
 +        0,   0,  63,  42,  42,  21,   0,  42,
 +       21,  42,  42,  63,   0,  42,  63,  42,
 +        0,  21,  21,   0,  21,  63,   0,  63,
 +       21,   0,  63,  63,  42,  21,  21,  42,
 +       21,  63,  42,  63,  21,  42,  63,  63,
 +       21,   0,   0,  21,   0,  42,  21,  42,
 +        0,  21,  42,  42,  63,   0,   0,  63,
 +        0,  42,  63,  42,   0,  63,  42,  42,
 +       21,   0,  21,  21,   0,  63,  21,  42,
 +       21,  21,  42,  63,  63,   0,  21,  63,
 +        0,  63,  63,  42,  21,  63,  42,  63,
 +       21,  21,   0,  21,  21,  42,  21,  63,
 +        0,  21,  63,  42,  63,  21,   0,  63,
 +       21,  42,  63,  63,   0,  63,  63,  42,
 +       21,  21,  21,  21,  21,  63,  21,  63,
 +       21,  21,  63,  63,  63,  21,  21,  63,
 +       21,  63,  63,  63,  21,  63,  63,  63
 +    };
 +
 +    s->latch = 0;
 +
 +    s->sr_index = 3;
 +    s->sr[0] = 3;
 +    s->sr[1] = 0;
 +    s->sr[2] = 3;
 +    s->sr[3] = 0;
 +    s->sr[4] = 2;
 +    s->sr[5] = 0;
 +    s->sr[6] = 0;
 +    s->sr[7] = 0;
 +
 +    s->gr_index = 5;
 +    s->gr[0] = 0;
 +    s->gr[1] = 0;
 +    s->gr[2] = 0;
 +    s->gr[3] = 0;
 +    s->gr[4] = 0;
 +    s->gr[5] = 16;
 +    s->gr[6] = 14;
 +    s->gr[7] = 15;
 +    s->gr[8] = 255;
 +
 +    /* changed by out 0x03c0 */
 +    s->ar_index = 32;
 +    s->ar[0] = 0;
 +    s->ar[1] = 1;
 +    s->ar[2] = 2;
 +    s->ar[3] = 3;
 +    s->ar[4] = 4;
 +    s->ar[5] = 5;
 +    s->ar[6] = 6;
 +    s->ar[7] = 7;
 +    s->ar[8] = 8;
 +    s->ar[9] = 9;
 +    s->ar[10] = 10;
 +    s->ar[11] = 11;
 +    s->ar[12] = 12;
 +    s->ar[13] = 13;
 +    s->ar[14] = 14;
 +    s->ar[15] = 15;
 +    s->ar[16] = 12;
 +    s->ar[17] = 0;
 +    s->ar[18] = 15;
 +    s->ar[19] = 8;
 +    s->ar[20] = 0;
 +
 +    s->ar_flip_flop = 1;
 +
 +    s->cr_index = 15;
 +    s->cr[0] = 95;
 +    s->cr[1] = 79;
 +    s->cr[2] = 80;
 +    s->cr[3] = 130;
 +    s->cr[4] = 85;
 +    s->cr[5] = 129;
 +    s->cr[6] = 191;
 +    s->cr[7] = 31;
 +    s->cr[8] = 0;
 +    s->cr[9] = 79;
 +    s->cr[10] = 14;
 +    s->cr[11] = 15;
 +    s->cr[12] = 0;
 +    s->cr[13] = 0;
 +    s->cr[14] = 5;
 +    s->cr[15] = 160;
 +    s->cr[16] = 156;
 +    s->cr[17] = 142;
 +    s->cr[18] = 143;
 +    s->cr[19] = 40;
 +    s->cr[20] = 31;
 +    s->cr[21] = 150;
 +    s->cr[22] = 185;
 +    s->cr[23] = 163;
 +    s->cr[24] = 255;
 +
 +    s->msr = 103;
 +    s->fcr = 0;
 +    s->st00 = 0;
 +    s->st01 = 0;
 +
 +    /* dac_* & palette will be initialized by os through out 0x03c8 &
 +     * out 0c03c9(1:3) */
 +    s->dac_state = 0;
 +    s->dac_sub_index = 0;
 +    s->dac_read_index = 0;
 +    s->dac_write_index = 16;
 +    s->dac_cache[0] = 255;
 +    s->dac_cache[1] = 255;
 +    s->dac_cache[2] = 255;
 +
 +    /* palette */
 +    memcpy(s->palette, palette_model, 192);
 +
 +    s->bank_offset = 0;
 +    s->graphic_mode = -1;
 +
 +    /* TODO: add vbe support if enabled */
 +}
 +
 +
 +static VGAState *xen_vga_state;
 +
 +/* Allocate video memory in the GPFN space */
 +void xen_vga_populate_vram(uint64_t vram_addr, uint32_t vga_ram_size)
  {
 -    if (kvm_enabled() && s->map_addr)
 -        kvm_log_stop(s->map_addr, s->map_end - s->map_addr);
 +    unsigned long nr_pfn;
 +    xen_pfn_t *pfn_list;
 +    int i;
 +    int rc;
 +
 +    fprintf(logfile, "populating video RAM at %llx\n",
 +          (unsigned long long)vram_addr);
 +
 +    nr_pfn = vga_ram_size >> TARGET_PAGE_BITS;
 +
 +    pfn_list = malloc(sizeof(*pfn_list) * nr_pfn);
 +
 +    for (i = 0; i < nr_pfn; i++)
 +        pfn_list[i] = (vram_addr >> TARGET_PAGE_BITS) + i;
  
 -    if (kvm_enabled() && s->lfb_vram_mapped) {
 -        kvm_log_stop(isa_mem_base + 0xa0000, 0x8000);
 -        kvm_log_stop(isa_mem_base + 0xa8000, 0x8000);
 +    if (xc_domain_memory_populate_physmap(xc_handle, domid, nr_pfn, 0, 0, pfn_list)) {
 +        fprintf(stderr, "Failed to populate video ram\n");
 +        exit(1);
      }
 +    free(pfn_list);
 +
 +    xen_vga_vram_map(vram_addr, vga_ram_size);
 +
 +    /* Win2K seems to assume that the pattern buffer is at 0xff
 +       initially ! */
 +    memset(xen_vga_state->vram_ptr, 0xff, vga_ram_size);
  }
  
 -static void vga_map(PCIDevice *pci_dev, int region_num,
 -                    uint32_t addr, uint32_t size, int type)
 +/* Mapping the video memory from GPFN space  */
 +void xen_vga_vram_map(uint64_t vram_addr, uint32_t vga_ram_size)
  {
 -    PCIVGAState *d = (PCIVGAState *)pci_dev;
 -    VGAState *s = &d->vga_state;
 -    if (region_num == PCI_ROM_SLOT) {
 -        cpu_register_physical_memory(addr, s->bios_size, s->bios_offset);
 -    } else {
 -        cpu_register_physical_memory(addr, s->vram_size, s->vram_offset);
 -    }
 +    unsigned long nr_pfn;
 +    xen_pfn_t *pfn_list;
 +    int i;
 +    void *vram;
  
 -    s->map_addr = addr;
 -    s->map_end = addr + VGA_RAM_SIZE;
 +    fprintf(logfile, "mapping video RAM from %llx\n",
 +          (unsigned long long)vram_addr);
  
 -    vga_dirty_log_start(s);
 +    nr_pfn = vga_ram_size >> TARGET_PAGE_BITS;
 +
 +    pfn_list = malloc(sizeof(*pfn_list) * nr_pfn);
 +
 +    for (i = 0; i < nr_pfn; i++)
 +        pfn_list[i] = (vram_addr >> TARGET_PAGE_BITS) + i;
 +
 +    vram = xc_map_foreign_pages(xc_handle, domid,
 +                                        PROT_READ|PROT_WRITE,
 +                                        pfn_list, nr_pfn);
 +
 +    if (!vram) {
 +        fprintf(stderr, "Failed to map vram nr_pfn=0x%lx vram_addr=%llx: %s\n",
 +                nr_pfn, (unsigned long long)vram_addr, strerror(errno));
 +        exit(1);
 +    }
 +
 +    xen_vga_state->vram_ptr = vram;
 +#ifdef CONFIG_STUBDOM
-     xenfb_pv_display_vram(vram);
++    xenfb_pv_display_start(vram);
 +#endif
  }
  
 -void vga_common_init(VGAState *s, uint8_t *vga_ram_base,
 -                     ram_addr_t vga_ram_offset, int vga_ram_size)
 +/* when used on xen environment, the vga_ram_base is not used */
- void vga_common_init(VGAState *s, uint8_t *vga_ram_base,
++void vga_common_init(VGAState *s, DisplayState *ds, uint8_t *vga_ram_base,
 +                     unsigned long vga_ram_offset, int vga_ram_size)
  {
      int i, j, v, b;
  
          expand4to8[i] = v;
      }
  
 -    s->vram_ptr = vga_ram_base;
 +    vga_reset(s);
 +
 +    xen_vga_state = s;
      s->vram_offset = vga_ram_offset;
      s->vram_size = vga_ram_size;
++    s->ds = ds;
++    ds->palette = s->last_palette;
      s->get_bpp = vga_get_bpp;
      s->get_offsets = vga_get_offsets;
      s->get_resolution = vga_get_resolution;
 -    s->update = vga_update_display;
 -    s->invalidate = vga_invalidate_display;
 -    s->screen_dump = vga_screen_dump;
 -    s->text_update = vga_update_text;
 +
-     s->ds = graphic_console_init(vga_update_display, vga_invalidate_display,
-                                  vga_screen_dump, vga_update_text, s);
 +    if (!restore) {
 +        xen_vga_populate_vram(VRAM_RESERVED_ADDRESS, s->vram_size);
 +        s->vram_gmfn = VRAM_RESERVED_ADDRESS;
 +    }
 +
++    graphic_console_init(s->ds, vga_update_display, vga_invalidate_display,
++                         vga_screen_dump, vga_update_text, s);
++
 +    vga_bios_init(s);
      switch (vga_retrace_method) {
      case VGA_RETRACE_DUMB:
          s->retrace = vga_dumb_retrace;
@@@ -2612,9 -2360,85 +2601,9 @@@ static void vga_init(VGAState *s
      vga_io_memory = cpu_register_io_memory(0, vga_mem_read, vga_mem_write, s);
      cpu_register_physical_memory(isa_mem_base + 0x000a0000, 0x20000,
                                   vga_io_memory);
 -    qemu_register_coalesced_mmio(isa_mem_base + 0x000a0000, 0x20000);
 -}
 -
 -/* Memory mapped interface */
 -static uint32_t vga_mm_readb (void *opaque, target_phys_addr_t addr)
 -{
 -    VGAState *s = opaque;
 -
 -    return vga_ioport_read(s, addr >> s->it_shift) & 0xff;
 -}
 -
 -static void vga_mm_writeb (void *opaque,
 -                           target_phys_addr_t addr, uint32_t value)
 -{
 -    VGAState *s = opaque;
 -
 -    vga_ioport_write(s, addr >> s->it_shift, value & 0xff);
 -}
 -
 -static uint32_t vga_mm_readw (void *opaque, target_phys_addr_t addr)
 -{
 -    VGAState *s = opaque;
 -
 -    return vga_ioport_read(s, addr >> s->it_shift) & 0xffff;
 -}
 -
 -static void vga_mm_writew (void *opaque,
 -                           target_phys_addr_t addr, uint32_t value)
 -{
 -    VGAState *s = opaque;
 -
 -    vga_ioport_write(s, addr >> s->it_shift, value & 0xffff);
 -}
 -
 -static uint32_t vga_mm_readl (void *opaque, target_phys_addr_t addr)
 -{
 -    VGAState *s = opaque;
 -
 -    return vga_ioport_read(s, addr >> s->it_shift);
 -}
 -
 -static void vga_mm_writel (void *opaque,
 -                           target_phys_addr_t addr, uint32_t value)
 -{
 -    VGAState *s = opaque;
 -
 -    vga_ioport_write(s, addr >> s->it_shift, value);
 -}
 -
 -static CPUReadMemoryFunc *vga_mm_read_ctrl[] = {
 -    &vga_mm_readb,
 -    &vga_mm_readw,
 -    &vga_mm_readl,
 -};
 -
 -static CPUWriteMemoryFunc *vga_mm_write_ctrl[] = {
 -    &vga_mm_writeb,
 -    &vga_mm_writew,
 -    &vga_mm_writel,
 -};
 -
 -static void vga_mm_init(VGAState *s, target_phys_addr_t vram_base,
 -                        target_phys_addr_t ctrl_base, int it_shift)
 -{
 -    int s_ioport_ctrl, vga_io_memory;
 -
 -    s->it_shift = it_shift;
 -    s_ioport_ctrl = cpu_register_io_memory(0, vga_mm_read_ctrl, vga_mm_write_ctrl, s);
 -    vga_io_memory = cpu_register_io_memory(0, vga_mem_read, vga_mem_write, s);
 -
 -    register_savevm("vga", 0, 2, vga_save, vga_load, s);
 -
 -    cpu_register_physical_memory(ctrl_base, 0x100000, s_ioport_ctrl);
 -    s->bank_offset = 0;
 -    cpu_register_physical_memory(vram_base + 0x000a0000, 0x20000, vga_io_memory);
 -    qemu_register_coalesced_mmio(vram_base + 0x000a0000, 0x20000);
  }
  
--int isa_vga_init(uint8_t *vga_ram_base,
++int isa_vga_init(DisplayState *ds, uint8_t *vga_ram_base,
                   unsigned long vga_ram_offset, int vga_ram_size)
  {
      VGAState *s;
      s = qemu_mallocz(sizeof(VGAState));
      if (!s)
          return -1;
 +    
 +    if (vga_ram_size > 16*1024*1024) {
 +        fprintf (stderr, "The stdvga/VBE device model has no use for more than 16 Megs of vram. Video ram set to 16M. \n");
 +        vga_ram_size = 16*1024*1024;
 +    }
  
--    vga_common_init(s, vga_ram_base, vga_ram_offset, vga_ram_size);
++    vga_common_init(s, ds, vga_ram_base, vga_ram_offset, vga_ram_size);
      vga_init(s);
  
 -    s->ds = graphic_console_init(s->update, s->invalidate,
 -                                 s->screen_dump, s->text_update, s);
 -
 -#ifdef CONFIG_BOCHS_VBE
 -    /* XXX: use optimized standard vga accesses */
 -    cpu_register_physical_memory(VBE_DISPI_LFB_PHYSICAL_ADDRESS,
 -                                 vga_ram_size, vga_ram_offset);
 -#endif
 -    return 0;
 -}
 -
 -int isa_vga_mm_init(uint8_t *vga_ram_base,
 -                    unsigned long vga_ram_offset, int vga_ram_size,
 -                    target_phys_addr_t vram_base, target_phys_addr_t ctrl_base,
 -                    int it_shift)
 -{
 -    VGAState *s;
 -
 -    s = qemu_mallocz(sizeof(VGAState));
 -    if (!s)
 -        return -1;
 -
 -    vga_common_init(s, vga_ram_base, vga_ram_offset, vga_ram_size);
 -    vga_mm_init(s, vram_base, ctrl_base, it_shift);
 -
 -    s->ds = graphic_console_init(s->update, s->invalidate,
 -                                 s->screen_dump, s->text_update, s);
 -
  #ifdef CONFIG_BOCHS_VBE
      /* XXX: use optimized standard vga accesses */
      cpu_register_physical_memory(VBE_DISPI_LFB_PHYSICAL_ADDRESS,
      return 0;
  }
  
--int pci_vga_init(PCIBus *bus, uint8_t *vga_ram_base,
++int pci_vga_init(PCIBus *bus, DisplayState *ds, uint8_t *vga_ram_base,
                   unsigned long vga_ram_offset, int vga_ram_size,
                   unsigned long vga_bios_offset, int vga_bios_size)
  {
          return -1;
      s = &d->vga_state;
  
 -    vga_common_init(s, vga_ram_base, vga_ram_offset, vga_ram_size);
 -    vga_init(s);
 -
 -    s->ds = graphic_console_init(s->update, s->invalidate,
 -                                 s->screen_dump, s->text_update, s);
 +    if (vga_ram_size > 16*1024*1024) {
 +        fprintf (stderr, "The stdvga/VBE device model has no use for more than 16 Megs of vram. Video ram set to 16M. \n");
 +        vga_ram_size = 16*1024*1024;
 +    }
  
-     vga_common_init(s, vga_ram_base, vga_ram_offset, vga_ram_size);
++    vga_common_init(s, ds, vga_ram_base, vga_ram_offset, vga_ram_size);
 +    vga_init(s);
      s->pci_dev = &d->dev;
  
      pci_conf = d->dev.config;
  /********************************************************/
  /* vga screen dump */
  
++static int vga_save_w, vga_save_h;
++
  static void vga_save_dpy_update(DisplayState *s,
                                  int x, int y, int w, int h)
  {
  }
  
--static void vga_save_dpy_resize(DisplayState *s)
++static void vga_save_dpy_resize(DisplayState *s, int w, int h)
  {
++    s->linesize = w * 4;
++    s->data = qemu_mallocz(h * s->linesize);
++    vga_save_w = w;
++    vga_save_h = h;
  }
  
  static void vga_save_dpy_refresh(DisplayState *s)
  {
  }
  
--int ppm_save(const char *filename, struct DisplaySurface *ds)
++static int ppm_save(const char *filename, uint8_t *data,
++                    int w, int h, int linesize)
  {
      FILE *f;
      uint8_t *d, *d1;
--    uint32_t v;
++    unsigned int v;
      int y, x;
--    uint8_t r, g, b;
  
      f = fopen(filename, "wb");
      if (!f)
          return -1;
      fprintf(f, "P6\n%d %d\n%d\n",
--            ds->width, ds->height, 255);
--    d1 = ds->data;
--    for(y = 0; y < ds->height; y++) {
++            w, h, 255);
++    d1 = data;
++    for(y = 0; y < h; y++) {
          d = d1;
--        for(x = 0; x < ds->width; x++) {
--            if (ds->pf.bits_per_pixel == 32)
--                v = *(uint32_t *)d;
--            else
--                v = (uint32_t) (*(uint16_t *)d);
--            r = ((v >> ds->pf.rshift) & ds->pf.rmax) * 256 /
--                (ds->pf.rmax + 1);
--            g = ((v >> ds->pf.gshift) & ds->pf.gmax) * 256 /
--                (ds->pf.gmax + 1);
--            b = ((v >> ds->pf.bshift) & ds->pf.bmax) * 256 /
--                (ds->pf.bmax + 1);
--            fputc(r, f);
--            fputc(g, f);
--            fputc(b, f);
--            d += ds->pf.bytes_per_pixel;
++        for(x = 0; x < w; x++) {
++            v = *(uint32_t *)d;
++            fputc((v >> 16) & 0xff, f);
++            fputc((v >> 8) & 0xff, f);
++            fputc((v) & 0xff, f);
++            d += 4;
          }
--        d1 += ds->linesize;
++        d1 += linesize;
      }
      fclose(f);
      return 0;
  }
  
 -static void vga_screen_dump_blank(VGAState *s, const char *filename)
 -{
 -    FILE *f;
 -    unsigned int y, x, w, h;
 -
 -    w = s->last_scr_width * sizeof(uint32_t);
 -    h = s->last_scr_height;
 -
 -    f = fopen(filename, "wb");
 -    if (!f)
 -        return;
 -    fprintf(f, "P6\n%d %d\n%d\n", w, h, 255);
 -    for (y = 0; y < h; y++) {
 -        for (x = 0; x < w; x++) {
 -            fputc(0, f);
 -        }
 -    }
 -    fclose(f);
 -}
 -
 -static void vga_screen_dump_common(VGAState *s, const char *filename,
 -                                   int w, int h)
 +/* save the vga display in a PPM image even if no display is
 +   available */
 +static void vga_screen_dump(void *opaque, const char *filename)
  {
 +    VGAState *s = (VGAState *)opaque;
      DisplayState *saved_ds, ds1, *ds = &ds1;
--    DisplayChangeListener dcl;
-     int w, h;
-     s->get_resolution(s, &w, &h);
  
      /* XXX: this is a little hackish */
      vga_invalidate_display(s);
      saved_ds = s->ds;
  
      memset(ds, 0, sizeof(DisplayState));
--    memset(&dcl, 0, sizeof(DisplayChangeListener));
--    dcl.dpy_update = vga_save_dpy_update;
--    dcl.dpy_resize = vga_save_dpy_resize;
--    dcl.dpy_refresh = vga_save_dpy_refresh;
--    register_displaychangelistener(ds, &dcl);
-     ds->surface = qemu_create_displaysurface(ds, w, h, 32, 4 * w);
-  
 -    ds->surface = qemu_create_displaysurface(w, h, 32, 4 * w);
++    ds->dpy_update = vga_save_dpy_update;
++    ds->dpy_resize = vga_save_dpy_resize;
++    ds->dpy_refresh = vga_save_dpy_refresh;
++    ds->depth = 32;
      s->ds = ds;
      s->graphic_mode = -1;
      vga_update_display(s);
  
--    ppm_save(filename, ds->surface);
--
-     qemu_free_displaysurface(ds);
 -    qemu_free_displaysurface(ds->surface);
++    if (ds->data) {
++        ppm_save(filename, ds->data, vga_save_w, vga_save_h,
++                 s->ds->linesize);
++        qemu_free(ds->data);
++    }
      s->ds = saved_ds;
  }
 -
 -static void vga_screen_dump_graphic(VGAState *s, const char *filename)
 -{
 -    int w, h;
 -
 -    s->get_resolution(s, &w, &h);
 -    vga_screen_dump_common(s, filename, w, h);
 -}
 -
 -static void vga_screen_dump_text(VGAState *s, const char *filename)
 -{
 -    int w, h, cwidth, cheight;
 -
 -    vga_get_text_resolution(s, &w, &h, &cwidth, &cheight);
 -    vga_screen_dump_common(s, filename, w * cwidth, h * cheight);
 -}
 -
 -/* save the vga display in a PPM image even if no display is
 -   available */
 -static void vga_screen_dump(void *opaque, const char *filename)
 -{
 -    VGAState *s = (VGAState *)opaque;
 -
 -    if (!(s->ar_index & 0x20))
 -        vga_screen_dump_blank(s, filename);
 -    else if (s->gr[6] & 1)
 -        vga_screen_dump_graphic(s, filename);
 -    else
 -        vga_screen_dump_text(s, filename);
 -}
diff --cc hw/vga_int.h
index c9be893d809a5996da319cbf4cde8d5d34f6ddab,f97e98fc97c006352cbf9ee6db6359dcbc8008db..d914b62ee842eb9aeb22e021694b0d6b75b8e957
@@@ -144,6 -145,6 +144,7 @@@ typedef void (* vga_update_retrace_info
      VGA_STATE_COMMON_BOCHS_VBE                                          \
      /* display refresh support */                                       \
      DisplayState *ds;                                                   \
++    QEMUConsole *console;                                               \
      uint32_t font_offsets[2];                                           \
      int graphic_mode;                                                   \
      uint8_t shift_control;                                              \
@@@ -186,12 -191,18 +187,11 @@@ static inline int c6_to_8(int v
      return (v << 2) | (b << 1) | b;
  }
  
--void vga_common_init(VGAState *s, uint8_t *vga_ram_base,
 -                     ram_addr_t vga_ram_offset, int vga_ram_size);
 -void vga_init(VGAState *s);
 -void vga_reset(void *s);
 -
 -void vga_dirty_log_start(VGAState *s);
 -void vga_dirty_log_stop(VGAState *s);
 -
++void vga_common_init(VGAState *s, DisplayState *ds, uint8_t *vga_ram_base,
 +                     unsigned long vga_ram_offset, int vga_ram_size);
  uint32_t vga_mem_readb(void *opaque, target_phys_addr_t addr);
  void vga_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val);
  void vga_invalidate_scanlines(VGAState *s, int y1, int y2);
--int ppm_save(const char *filename, struct DisplaySurface *ds);
  
  void vga_draw_cursor_line_8(uint8_t *d1, const uint8_t *src1,
                              int poffset, int w,
diff --cc hw/vmware_vga.c
Simple merge
index 976e7e7399324406dca1da67dde3ed837e1c5947,0000000000000000000000000000000000000000..c63d5d566a408809b39ff323166dc49992d9f0b7
mode 100644,000000..100644
--- /dev/null
@@@ -1,302 -1,0 +1,303 @@@
 +/*
 + * QEMU Xen FV Machine
 + *
 + * Copyright (c) 2003-2007 Fabrice Bellard
 + * Copyright (c) 2007 Red Hat
 + *
 + * Permission is hereby granted, free of charge, to any person obtaining a copy
 + * of this software and associated documentation files (the "Software"), to deal
 + * in the Software without restriction, including without limitation the rights
 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 + * copies of the Software, and to permit persons to whom the Software is
 + * furnished to do so, subject to the following conditions:
 + *
 + * The above copyright notice and this permission notice shall be included in
 + * all copies or substantial portions of the Software.
 + *
 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 + * THE SOFTWARE.
 + */
 +
 +#include "hw.h"
 +#include "pc.h"
 +#include "boards.h"
 +#include "exec-all.h"
 +#include "qemu-xen.h"
 +
 +#include <xen/hvm/params.h>
 +#include <sys/mman.h>
 +
 +#if defined(MAPCACHE)
 +
 +#if defined(__i386__) 
 +#define MAX_MCACHE_SIZE    0x40000000 /* 1GB max for x86 */
 +#define MCACHE_BUCKET_SHIFT 16
 +#elif defined(__x86_64__)
 +#define MAX_MCACHE_SIZE    0x1000000000 /* 64GB max for x86_64 */
 +#define MCACHE_BUCKET_SHIFT 20
 +#endif
 +
 +#define MCACHE_BUCKET_SIZE (1UL << MCACHE_BUCKET_SHIFT)
 +
 +#define BITS_PER_LONG (sizeof(long)*8)
 +#define BITS_TO_LONGS(bits) \
 +    (((bits)+BITS_PER_LONG-1)/BITS_PER_LONG)
 +#define DECLARE_BITMAP(name,bits) \
 +    unsigned long name[BITS_TO_LONGS(bits)]
 +#define test_bit(bit,map) \
 +    (!!((map)[(bit)/BITS_PER_LONG] & (1UL << ((bit)%BITS_PER_LONG))))
 +
 +struct map_cache {
 +    unsigned long paddr_index;
 +    uint8_t      *vaddr_base;
 +    DECLARE_BITMAP(valid_mapping, MCACHE_BUCKET_SIZE>>XC_PAGE_SHIFT);
 +};
 +
 +static struct map_cache *mapcache_entry;
 +static unsigned long nr_buckets;
 +
 +/* For most cases (>99.9%), the page address is the same. */
 +static unsigned long last_address_index = ~0UL;
 +static uint8_t      *last_address_vaddr;
 +
 +static int qemu_map_cache_init(void)
 +{
 +    unsigned long size;
 +
 +    nr_buckets = (((MAX_MCACHE_SIZE >> XC_PAGE_SHIFT) +
 +                   (1UL << (MCACHE_BUCKET_SHIFT - XC_PAGE_SHIFT)) - 1) >>
 +                  (MCACHE_BUCKET_SHIFT - XC_PAGE_SHIFT));
 +
 +    /*
 +     * Use mmap() directly: lets us allocate a big hash table with no up-front
 +     * cost in storage space. The OS will allocate memory only for the buckets
 +     * that we actually use. All others will contain all zeroes.
 +     */
 +    size = nr_buckets * sizeof(struct map_cache);
 +    size = (size + XC_PAGE_SIZE - 1) & ~(XC_PAGE_SIZE - 1);
 +    fprintf(logfile, "qemu_map_cache_init nr_buckets = %lx size %lu\n", nr_buckets, size);
 +    mapcache_entry = mmap(NULL, size, PROT_READ|PROT_WRITE,
 +                          MAP_SHARED|MAP_ANON, -1, 0);
 +    if (mapcache_entry == MAP_FAILED) {
 +        errno = ENOMEM;
 +        return -1;
 +    }
 +
 +    return 0;
 +}
 +
 +static void qemu_remap_bucket(struct map_cache *entry,
 +                              unsigned long address_index)
 +{
 +    uint8_t *vaddr_base;
 +    unsigned long pfns[MCACHE_BUCKET_SIZE >> XC_PAGE_SHIFT];
 +    unsigned int i, j;
 +
 +    if (entry->vaddr_base != NULL) {
 +        errno = munmap(entry->vaddr_base, MCACHE_BUCKET_SIZE);
 +        if (errno) {
 +            fprintf(logfile, "unmap fails %d\n", errno);
 +            exit(-1);
 +        }
 +    }
 +
 +    for (i = 0; i < MCACHE_BUCKET_SIZE >> XC_PAGE_SHIFT; i++)
 +        pfns[i] = (address_index << (MCACHE_BUCKET_SHIFT-XC_PAGE_SHIFT)) + i;
 +
 +    vaddr_base = xc_map_foreign_batch(xc_handle, domid, PROT_READ|PROT_WRITE,
 +                                      pfns, MCACHE_BUCKET_SIZE >> XC_PAGE_SHIFT);
 +    if (vaddr_base == NULL) {
 +        fprintf(logfile, "xc_map_foreign_batch error %d\n", errno);
 +        exit(-1);
 +    }
 +
 +    entry->vaddr_base  = vaddr_base;
 +    entry->paddr_index = address_index;
 +
 +    for (i = 0; i < MCACHE_BUCKET_SIZE >> XC_PAGE_SHIFT; i += BITS_PER_LONG) {
 +        unsigned long word = 0;
 +        j = ((i + BITS_PER_LONG) > (MCACHE_BUCKET_SIZE >> XC_PAGE_SHIFT)) ?
 +            (MCACHE_BUCKET_SIZE >> XC_PAGE_SHIFT) % BITS_PER_LONG : BITS_PER_LONG;
 +        while (j > 0)
 +            word = (word << 1) | (((pfns[i + --j] >> 28) & 0xf) != 0xf);
 +        entry->valid_mapping[i / BITS_PER_LONG] = word;
 +    }
 +}
 +
 +uint8_t *qemu_map_cache(target_phys_addr_t phys_addr)
 +{
 +    struct map_cache *entry;
 +    unsigned long address_index  = phys_addr >> MCACHE_BUCKET_SHIFT;
 +    unsigned long address_offset = phys_addr & (MCACHE_BUCKET_SIZE-1);
 +
 +    if (address_index == last_address_index)
 +        return last_address_vaddr + address_offset;
 +
 +    entry = &mapcache_entry[address_index % nr_buckets];
 +
 +    if (entry->vaddr_base == NULL || entry->paddr_index != address_index ||
 +        !test_bit(address_offset>>XC_PAGE_SHIFT, entry->valid_mapping))
 +        qemu_remap_bucket(entry, address_index);
 +
 +    if (!test_bit(address_offset>>XC_PAGE_SHIFT, entry->valid_mapping)) {
 +        last_address_index = ~0UL;
 +        return NULL;
 +    }
 +
 +    last_address_index = address_index;
 +    last_address_vaddr = entry->vaddr_base;
 +
 +    return last_address_vaddr + address_offset;
 +}
 +
 +void qemu_invalidate_map_cache(void)
 +{
 +    unsigned long i;
 +
 +    mapcache_lock();
 +
 +    for (i = 0; i < nr_buckets; i++) {
 +        struct map_cache *entry = &mapcache_entry[i];
 +
 +        if (entry->vaddr_base == NULL)
 +            continue;
 +
 +        errno = munmap(entry->vaddr_base, MCACHE_BUCKET_SIZE);
 +        if (errno) {
 +            fprintf(logfile, "unmap fails %d\n", errno);
 +            exit(-1);
 +        }
 +
 +        entry->paddr_index = 0;
 +        entry->vaddr_base  = NULL;
 +    }
 +
 +    last_address_index =  ~0UL;
 +    last_address_vaddr = NULL;
 +
 +    mapcache_unlock();
 +}
 +
 +#endif /* defined(MAPCACHE) */
 +
 +
 +static void xen_init_fv(ram_addr_t ram_size, int vga_ram_size,
 +                      const char *boot_device, DisplayState *ds,
 +                      const char *kernel_filename,const char *kernel_cmdline,
 +                        const char *initrd_filename, const char *cpu_model,
 +                        const char *direct_pci)
 +{
 +    unsigned long ioreq_pfn;
 +    extern void *shared_page;
 +    extern void *buffered_io_page;
 +#ifdef __ia64__
 +    unsigned long nr_pages;
 +    xen_pfn_t *page_array;
 +    extern void *buffered_pio_page;
 +    int i;
 +#endif
 +
 +#if defined(__i386__) || defined(__x86_64__)
 +
 +    if (qemu_map_cache_init()) {
 +        fprintf(logfile, "qemu_map_cache_init returned: error %d\n", errno);
 +        exit(-1);
 +    }
 +#endif
 +
 +#ifdef CONFIG_STUBDOM /* the hvmop is not supported on older hypervisors */
 +    xc_set_hvm_param(xc_handle, domid, HVM_PARAM_DM_DOMAIN, DOMID_SELF);
 +#endif
 +    xc_get_hvm_param(xc_handle, domid, HVM_PARAM_IOREQ_PFN, &ioreq_pfn);
 +    fprintf(logfile, "shared page at pfn %lx\n", ioreq_pfn);
 +    shared_page = xc_map_foreign_range(xc_handle, domid, XC_PAGE_SIZE,
 +                                       PROT_READ|PROT_WRITE, ioreq_pfn);
 +    if (shared_page == NULL) {
 +        fprintf(logfile, "map shared IO page returned error %d\n", errno);
 +        exit(-1);
 +    }
 +
 +    xc_get_hvm_param(xc_handle, domid, HVM_PARAM_BUFIOREQ_PFN, &ioreq_pfn);
 +    fprintf(logfile, "buffered io page at pfn %lx\n", ioreq_pfn);
 +    buffered_io_page = xc_map_foreign_range(xc_handle, domid, XC_PAGE_SIZE,
 +                                            PROT_READ|PROT_WRITE, ioreq_pfn);
 +    if (buffered_io_page == NULL) {
 +        fprintf(logfile, "map buffered IO page returned error %d\n", errno);
 +        exit(-1);
 +    }
 +
 +#if defined(__ia64__)
 +    xc_get_hvm_param(xc_handle, domid, HVM_PARAM_BUFPIOREQ_PFN, &ioreq_pfn);
 +    fprintf(logfile, "buffered pio page at pfn %lx\n", ioreq_pfn);
 +    buffered_pio_page = xc_map_foreign_range(xc_handle, domid, XC_PAGE_SIZE,
 +                                           PROT_READ|PROT_WRITE, ioreq_pfn);
 +    if (buffered_pio_page == NULL) {
 +        fprintf(logfile, "map buffered PIO page returned error %d\n", errno);
 +        exit(-1);
 +    }
 +
 +    nr_pages = ram_size / XC_PAGE_SIZE;
 +
 +    page_array = (xen_pfn_t *)malloc(nr_pages * sizeof(xen_pfn_t));
 +    if (page_array == NULL) {
 +        fprintf(logfile, "malloc returned error %d\n", errno);
 +        exit(-1);
 +    }
 +
 +    for (i = 0; i < nr_pages; i++)
 +        page_array[i] = i;
 +
 +    /* VTI will not use memory between 3G~4G, so we just pass a legal pfn
 +       to make QEMU map continuous virtual memory space */
 +    if (ram_size > MMIO_START) {
 +        for (i = 0 ; i < (MEM_G >> XC_PAGE_SHIFT); i++)
 +            page_array[(MMIO_START >> XC_PAGE_SHIFT) + i] =
 +                (STORE_PAGE_START >> XC_PAGE_SHIFT); 
 +    }
 +    /* skipping VGA hole, same as above */
 +    if (ram_size > VGA_IO_START) {
 +        for (i = 0 ; i < (VGA_IO_SIZE >> XC_PAGE_SHIFT); i++)
 +            page_array[(VGA_IO_START >> XC_PAGE_SHIFT) + i] =
 +                (STORE_PAGE_START >> XC_PAGE_SHIFT); 
 +    }
 +
 +    phys_ram_base = xc_map_foreign_batch(xc_handle, domid,
 +                                         PROT_READ|PROT_WRITE,
 +                                         page_array, nr_pages);
 +    if (phys_ram_base == 0) {
 +        fprintf(logfile, "xc_map_foreign_batch returned error %d\n", errno);
 +        exit(-1);
 +    }
 +    free(page_array);
 +#endif
 +
 +    timeoffset_get();
 +
 +
 +    pc_machine.init(ram_size, vga_ram_size, boot_device, ds,
 +                  kernel_filename, kernel_cmdline, initrd_filename,
 +                  cpu_model, direct_pci);
 +}
 +
 +QEMUMachine xenfv_machine = {
 +    "xenfv",
 +    "Xen Fully-virtualized PC",
 +    xen_init_fv,
 +    BIOS_SIZE | RAMSIZE_FIXED,
 +    .max_cpus = 1,
++    .nodisk_ok = 1,
 +};
 +
 +/*
 + * Local variables:
 + *  indent-tabs-mode: nil
 + *  c-indent-level: 4
 + *  c-basic-offset: 4
 + *  tab-width: 4
 + * End:
 + */
index 1dcfa31fa8011379b89c9bac518823e9d1dfcdea,0000000000000000000000000000000000000000..4c334d7545a00e7aa5f487f514188baf8426f9a6
mode 100644,000000..100644
--- /dev/null
@@@ -1,89 -1,0 +1,90 @@@
 +/*
 + * QEMU Xen PV Machine
 + *
 + * Copyright (c) 2007 Red Hat
 + *
 + * Permission is hereby granted, free of charge, to any person obtaining a copy
 + * of this software and associated documentation files (the "Software"), to deal
 + * in the Software without restriction, including without limitation the rights
 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 + * copies of the Software, and to permit persons to whom the Software is
 + * furnished to do so, subject to the following conditions:
 + *
 + * The above copyright notice and this permission notice shall be included in
 + * all copies or substantial portions of the Software.
 + *
 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 + * THE SOFTWARE.
 + */
 +
 +#include "hw.h"
 +#include "pc.h"
 +#include "sysemu.h"
 +#include "boards.h"
 +#include "xen_backend.h"
 +
 +int xen_domid;
 +enum xen_mode xen_mode = XEN_EMULATE;
 +
 +extern void init_blktap(void);
 +
 +
 +/* The Xen PV machine currently provides
 + *   - a virtual framebuffer
 + *   - ....
 + */
 +static void xen_init_pv(ram_addr_t ram_size, int vga_ram_size,
 +                      const char *boot_device, DisplayState *ds,
 +                      const char *kernel_filename,
 +                      const char *kernel_cmdline,
 +                      const char *initrd_filename,
 +                      const char *cpu_model,
 +                      const char *direct_pci)
 +{
 +    struct xenfb *xenfb;
 +    extern int domid;
 +    CPUState *env;
 +
 +#ifndef CONFIG_STUBDOM
 +    /* Initialize tapdisk client */
 +    init_blktap();
 +#endif
 +
 +    /* Initialize a dummy CPU */
 +    env = cpu_init(NULL);
 +
 +    /* Initialize backend core & drivers */
 +    if (-1 == xen_be_init()) {
 +        fprintf(stderr, "%s: xen backend core setup failed\n", __FUNCTION__);
 +        exit(1);
 +    }
 +    xen_be_register("console", &xen_console_ops);
 +    xen_be_register("vkbd", &xen_kbdmouse_ops);
 +    xen_be_register("vfb", &xen_framebuffer_ops);
 +
 +    /* setup framebuffer */
 +    xen_set_display(xen_domid, ds);
 +}
 +
 +QEMUMachine xenpv_machine = {
 +    "xenpv",
 +    "Xen Para-virtualized PC",
 +    xen_init_pv,
 +    BIOS_SIZE | RAMSIZE_FIXED,
 +    .max_cpus = 1,
++    .nodisk_ok = 1,
 +};
 +
 +/*
 + * Local variables:
 + *  indent-tabs-mode: nil
 + *  c-indent-level: 4
 + *  c-basic-offset: 4
 + *  tab-width: 4
 + * End:
 + */
diff --cc monitor.c
Simple merge
diff --cc net.c
Simple merge
diff --cc qemu-char.c
Simple merge
diff --cc qemu-char.h
Simple merge
diff --cc qemu-common.h
index 8e5d2eb7b61811e11aa68c515e6732a7f75fe1ee,8aef55867bde4dbd83b85e290ef747e9bdf3eceb..ca145365f372df7f395a0019a26989cc04cad441
@@@ -6,11 -6,11 +6,12 @@@
  #define WIN32_LEAN_AND_MEAN
  #define WINVER 0x0501  /* needed for ipv6 bits */
  #include <windows.h>
++#define NO_UNIX_SOCKETS 1
  #endif
  
- #define noreturn __attribute__ ((__noreturn__))
+ #define QEMU_NORETURN __attribute__ ((__noreturn__))
  
- /* Hack around the mess dyngen-exec.h causes: We need noreturn in files that
+ /* Hack around the mess dyngen-exec.h causes: We need QEMU_NORETURN in files that
     cannot include the following headers without conflicts. This condition has
     to be removed once dyngen is gone. */
  #ifndef __DYNGEN_EXEC_H__
diff --cc sdl.c
index e9256732c4189db7bc528e0e649b255a09aa8621,cfdf85237359b3621f4274384ad76ba4f8a28767..9afd884094a8b8f7200d5b7f8b06da8324a5fd69
--- 1/sdl.c
--- 2/sdl.c
+++ b/sdl.c
  #include <signal.h>
  #endif
  
 -static DisplayChangeListener *dcl;
 -static SDL_Surface *real_screen;
 -static SDL_Surface *guest_screen = NULL;
 +#ifdef CONFIG_OPENGL
 +#include <SDL_opengl.h>
 +#endif
 +
- static DisplayChangeListener *dcl;
- static SDL_Surface *real_screen;
- static SDL_Surface *guest_screen = NULL;
++static SDL_Surface *screen;
++static SDL_Surface *shared = NULL;
  static int gui_grab; /* if true, all keyboard/mouse events are grabbed */
  static int last_vm_running;
  static int gui_saved_grab;
@@@ -52,180 -48,60 +51,281 @@@ static int width, height
  static SDL_Cursor *sdl_cursor_normal;
  static SDL_Cursor *sdl_cursor_hidden;
  static int absolute_enabled = 0;
 -static int guest_cursor = 0;
 -static int guest_x, guest_y;
 -static SDL_Cursor *guest_sprite = 0;
 +static int opengl_enabled;
 +
++static void sdl_colourdepth(DisplayState *ds, int depth);
++
 +#ifdef CONFIG_OPENGL
 +static GLint tex_format;
 +static GLint tex_type;
 +static GLuint texture_ref = 0;
 +static GLint gl_format;
- static uint8_t bgr;
 +
- static void opengl_setdata(DisplayState *ds)
++static void opengl_setdata(DisplayState *ds, void *pixels)
 +{
 +    glEnable(GL_TEXTURE_RECTANGLE_ARB);
 +    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
 +    glClearColor(0, 0, 0, 0);
 +    glDisable(GL_BLEND);
 +    glDisable(GL_LIGHTING);
 +    glDisable(GL_DEPTH_TEST);
 +    glDepthMask(GL_FALSE);
 +    glDisable(GL_CULL_FACE);
-     glViewport( 0, 0, real_screen->w, real_screen->h);
++    glViewport( 0, 0, screen->w, screen->h);
 +    glMatrixMode(GL_PROJECTION);
 +    glLoadIdentity();
-     glOrtho(0, real_screen->w, real_screen->h, 0, -1,1);
++    glOrtho(0, screen->w, screen->h, 0, -1,1);
 +    glMatrixMode(GL_MODELVIEW);
 +    glLoadIdentity();
 +    glClear(GL_COLOR_BUFFER_BIT);
++    ds->data = pixels;
 +
 +    if (texture_ref) {
 +        glDeleteTextures(1, &texture_ref);
 +        texture_ref = 0;
 +    }
 +
 +    glGenTextures(1, &texture_ref);
 +    glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texture_ref);
 +    glPixelStorei(GL_UNPACK_LSB_FIRST, 1);
-     switch (ds_get_bits_per_pixel(ds)) {
++    switch (ds->depth) {
++        case 8:
++            if (ds->palette == NULL) {
++                tex_format = GL_RGB;
++                tex_type = GL_UNSIGNED_BYTE_3_3_2;
++            } else {
++                int i;
++                GLushort paletter[256], paletteg[256], paletteb[256];
++                for (i = 0; i < 256; i++) {
++                    uint8_t rgb = ds->palette[i] >> 16;
++                    paletter[i] = ((rgb & 0xe0) >> 5) * 65535 / 7;
++                    paletteg[i] = ((rgb & 0x1c) >> 2) * 65535 / 7;
++                    paletteb[i] = (rgb & 0x3) * 65535 / 3;
++                }
++                glPixelMapusv(GL_PIXEL_MAP_I_TO_R, 256, paletter);
++                glPixelMapusv(GL_PIXEL_MAP_I_TO_G, 256, paletteg);
++                glPixelMapusv(GL_PIXEL_MAP_I_TO_B, 256, paletteb);
++
++                tex_format = GL_COLOR_INDEX;
++                tex_type = GL_UNSIGNED_BYTE;
++            }
++            break;
 +        case 16:
 +            tex_format = GL_RGB;
 +            tex_type = GL_UNSIGNED_SHORT_5_6_5;
 +            break;
 +        case 24:
 +            tex_format = GL_BGR;
 +            tex_type = GL_UNSIGNED_BYTE;
 +            break;
 +        case 32:
-             if (bgr == (ds->surface->pf.rshift < ds->surface->pf.bshift)) {
++            if (!ds->bgr) {
 +                tex_format = GL_BGRA;
 +                tex_type = GL_UNSIGNED_BYTE;
 +            } else {
 +                tex_format = GL_RGBA;
 +                tex_type = GL_UNSIGNED_BYTE;                
 +            }
 +            break;
 +    }   
-     glPixelStorei(GL_UNPACK_ROW_LENGTH, (ds_get_linesize(ds) / ds_get_bytes_per_pixel(ds)));
-     glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, gl_format, ds_get_width(ds), ds_get_height(ds), 0, tex_format, tex_type, ds_get_data(ds));
++    glPixelStorei(GL_UNPACK_ROW_LENGTH, (ds->linesize * 8) / ds->depth);
++    glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, gl_format, ds->width, ds->height, 0, tex_format, tex_type, pixels);
 +    glTexParameterf(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_PRIORITY, 1.0);
 +    glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
 +    glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
 +    glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
 +    glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
 +    glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
 +}
 +
 +static void opengl_update(DisplayState *ds, int x, int y, int w, int h)
 +{  
-     int bpp = ds_get_bytes_per_pixel(ds);
-     GLvoid *pixels = ds_get_data(ds) + y * ds_get_linesize(ds) + x * bpp;
++    int bpp = ds->depth / 8;
++    GLvoid *pixels = ds->data + y * ds->linesize + x * bpp;
 +    glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texture_ref);
-     glPixelStorei(GL_UNPACK_ROW_LENGTH, ds_get_linesize(ds) / bpp);
++    glPixelStorei(GL_UNPACK_ROW_LENGTH, ds->linesize / bpp);
 +    glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, x, y, w, h, tex_format, tex_type, pixels);
 +    glBegin(GL_QUADS);
 +        glTexCoord2d(0, 0);
 +        glVertex2d(0, 0);
-         glTexCoord2d(ds_get_width(ds), 0);
-         glVertex2d(real_screen->w, 0);
-         glTexCoord2d(ds_get_width(ds), ds_get_height(ds));
-         glVertex2d(real_screen->w, real_screen->h);
-         glTexCoord2d(0, ds_get_height(ds));
-         glVertex2d(0, real_screen->h);
++        glTexCoord2d(ds->width, 0);
++        glVertex2d(screen->w, 0);
++        glTexCoord2d(ds->width, ds->height);
++        glVertex2d(screen->w, screen->h);
++        glTexCoord2d(0, ds->height);
++        glVertex2d(0, screen->h);
 +    glEnd();
 +    glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
 +    SDL_GL_SwapBuffers();
 +}
 +#endif
  
  static void sdl_update(DisplayState *ds, int x, int y, int w, int h)
  {
--    SDL_Rect rec;
--    rec.x = x;
--    rec.y = y;
--    rec.w = w;
--    rec.h = h;
-     //    printf("updating x=%d y=%d w=%d h=%d\n", x, y, w, h);i
-     SDL_BlitSurface(guest_screen, &rec, real_screen, &rec);
-     SDL_UpdateRect(real_screen, x, y, w, h);
+     //    printf("updating x=%d y=%d w=%d h=%d\n", x, y, w, h);
 -
 -    SDL_BlitSurface(guest_screen, &rec, real_screen, &rec);
 -    SDL_UpdateRect(real_screen, x, y, w, h);
++    if (shared) {
++        SDL_Rect rec;
++        rec.x = x;
++        rec.y = y;
++        rec.w = w;
++        rec.h = h;
++        SDL_BlitSurface(shared, &rec, screen, &rec);
++    }
++    SDL_Flip(screen);
  }
  
--static void sdl_setdata(DisplayState *ds)
++static void sdl_setdata(DisplayState *ds, void *pixels)
  {
--    SDL_Rect rec;
--    rec.x = 0;
--    rec.y = 0;
--    rec.w = real_screen->w;
--    rec.h = real_screen->h;
--
--    if (guest_screen != NULL) SDL_FreeSurface(guest_screen);
--
--    guest_screen = SDL_CreateRGBSurfaceFrom(ds_get_data(ds), ds_get_width(ds), ds_get_height(ds),
--                                            ds_get_bits_per_pixel(ds), ds_get_linesize(ds),
--                                            ds->surface->pf.rmask, ds->surface->pf.gmask,
--                                            ds->surface->pf.bmask, ds->surface->pf.amask);
++    uint32_t rmask, gmask, bmask, amask = 0;
++    switch (ds->depth) {
++        case 8:
++            rmask = 0x000000E0;
++            gmask = 0x0000001C;
++            bmask = 0x00000003;
++            break;
++        case 16:
++            rmask = 0x0000F800;
++            gmask = 0x000007E0;
++            bmask = 0x0000001F;
++            break;
++        case 24:
++            rmask = 0x00FF0000;
++            gmask = 0x0000FF00;
++            bmask = 0x000000FF;
++            break;
++        case 32:
++            rmask = 0x00FF0000;
++            gmask = 0x0000FF00;
++            bmask = 0x000000FF;
++            break;
++        default:
++            return;
++    }
++    shared = SDL_CreateRGBSurfaceFrom(pixels, width, height, ds->depth, ds->linesize, rmask , gmask, bmask, amask);
++    if (ds->depth == 8 && ds->palette != NULL) {
++        SDL_Color palette[256];
++        int i;
++        for (i = 0; i < 256; i++) {
++            uint8_t rgb = ds->palette[i] >> 16;
++            palette[i].r = ((rgb & 0xe0) >> 5) * 255 / 7;
++            palette[i].g = ((rgb & 0x1c) >> 2) * 255 / 7;
++            palette[i].b = (rgb & 0x3) * 255 / 3;
++        }
++        SDL_SetColors(shared, palette, 0, 256);
++    }
++    ds->data = pixels;
  }
  
--static void sdl_resize(DisplayState *ds)
++static void sdl_resize_shared(DisplayState *ds, int w, int h, int depth, int linesize, void *pixels)
  {
      int flags;
  
      //    printf("resizing to %d %d\n", w, h);
 -    flags = SDL_HWSURFACE|SDL_ASYNCBLIT|SDL_HWACCEL;
 -    if (gui_fullscreen)
-     if (opengl_enabled)
++    sdl_colourdepth(ds, depth);
++
 +#ifdef CONFIG_OPENGL
-         flags = SDL_HWSURFACE|SDL_ASYNCBLIT|SDL_HWACCEL;
++    if (ds->shared_buf && opengl_enabled)
 +        flags = SDL_OPENGL|SDL_RESIZABLE;
 +    else
 +#endif
-     if (gui_fullscreen)
++        flags = SDL_HWSURFACE|SDL_ASYNCBLIT|SDL_HWACCEL|SDL_DOUBLEBUF|SDL_HWPALETTE;
 +
++    if (gui_fullscreen) {
          flags |= SDL_FULLSCREEN;
++        flags &= ~SDL_RESIZABLE;
++    }
      if (gui_noframe)
          flags |= SDL_NOFRAME;
  
--    width = ds_get_width(ds);
--    height = ds_get_height(ds);
--    real_screen = SDL_SetVideoMode(width, height, 0, flags);
--    if (!real_screen) {
 -        fprintf(stderr, "Could not open SDL display\n");
++    width = w;
++    height = h;
++
++ again:
++    screen = SDL_SetVideoMode(w, h, 0, flags);
++
++    if (!screen) {
++        fprintf(stderr, "Could not open SDL display: %s\n", SDL_GetError());
 +        if (opengl_enabled) {
 +            /* Fallback to SDL */
 +            opengl_enabled = 0;
-             dcl->dpy_update = sdl_update;
-             dcl->dpy_setdata = sdl_setdata;
-             sdl_resize(ds);
++            ds->dpy_update = sdl_update;
++            ds->dpy_setdata = sdl_setdata;
++            ds->dpy_resize_shared = sdl_resize_shared;
++            sdl_resize_shared(ds, w, h, depth, linesize, pixels);
 +            return;
 +        }
-         fprintf(stderr, "Could not open SDL display\n");
          exit(1);
      }
  
- #ifdef CONFIG_OPENGL
-     if (real_screen->format->Bshift > real_screen->format->Rshift) {
-         bgr = 1;
-     } else {
-         bgr = 0;
 -    sdl_setdata(ds);
++    if (!opengl_enabled) {
++        if (!screen->pixels && (flags & SDL_HWSURFACE) && (flags & SDL_FULLSCREEN)) {
++            flags &= ~SDL_HWSURFACE;
++            goto again;
++        }
++
++        if (!screen->pixels) {
++            fprintf(stderr, "Could not open SDL display: %s\n", SDL_GetError());
++            exit(1);
++        }
 +    }
-     switch(real_screen->format->BitsPerPixel) {
++
++    ds->width = w;
++    ds->height = h;
++    if (!ds->shared_buf) {
++        ds->depth = screen->format->BitsPerPixel;
++      if (screen->format->Bshift > screen->format->Rshift) {
++            ds->bgr = 1;
++        } else {
++            ds->bgr = 0;
++        }
++        shared = NULL;
++        ds->data = screen->pixels;
++        ds->linesize = screen->pitch;
++    } else {
++        ds->linesize = linesize;
++#ifdef CONFIG_OPENGL
++        switch(screen->format->BitsPerPixel) {
 +        case 8:
 +            gl_format = GL_RGB;
 +            break;
 +        case 16:
 +            gl_format = GL_RGB;
 +            break;
 +        case 24:
 +            gl_format = GL_RGB;
 +            break;
 +        case 32:
-             if (!real_screen->format->Rshift)
++            if (!screen->format->Rshift)
 +                gl_format = GL_BGRA;
 +            else
 +                gl_format = GL_RGBA;
 +            break;
-     };
++        };
 +#endif
++    }
++    if (ds->shared_buf) ds->dpy_setdata(ds, pixels);
++}
 +
-     dcl->dpy_setdata(ds);
++static void sdl_resize(DisplayState *ds, int w, int h)
++{
++    sdl_resize_shared(ds, w, h, 0, w * (ds->depth / 8), NULL);
++}
++
++static void sdl_colourdepth(DisplayState *ds, int depth)
++{
++    if (!depth || !ds->depth) {
++      ds->shared_buf = 0;
++      ds->dpy_update = sdl_update;
++      return;
++    }
++    ds->shared_buf = 1;
++    ds->depth = depth;
++#ifdef CONFIG_OPENGL
++    if (opengl_enabled) {
++        ds->dpy_update = opengl_update;
++    }
++#endif
  }
  
  /* generic keyboard conversion */
@@@ -423,9 -318,8 +523,9 @@@ static void sdl_send_mouse_event(int dx
            absolute_enabled = 1;
        }
  
 -       dx = x * 0x7FFF / (width - 1);
 -       dy = y * 0x7FFF / (height - 1);
 +      SDL_GetMouseState(&dx, &dy);
-         dx = dx * 0x7FFF / (real_screen->w - 1);
-         dy = dy * 0x7FFF / (real_screen->h - 1);
++        dx = dx * 0x7FFF / (screen->w - 1);
++        dy = dy * 0x7FFF / (screen->h - 1);
      } else if (absolute_enabled) {
        sdl_show_cursor();
        absolute_enabled = 0;
  static void toggle_full_screen(DisplayState *ds)
  {
      gui_fullscreen = !gui_fullscreen;
--    sdl_resize(ds);
++    sdl_resize_shared(ds, ds->width, ds->height, ds->depth, ds->linesize, ds->data);
      if (gui_fullscreen) {
          gui_saved_grab = gui_grab;
          sdl_grab_start();
@@@ -465,7 -367,7 +565,7 @@@ static void sdl_refresh(DisplayState *d
      while (SDL_PollEvent(ev)) {
          switch (ev->type) {
          case SDL_VIDEOEXPOSE:
-             dcl->dpy_update(ds, 0, 0, ds_get_width(ds), ds_get_height(ds));
 -            sdl_update(ds, 0, 0, real_screen->w, real_screen->h);
++            ds->dpy_update(ds, 0, 0, ds->width, ds->height);
              break;
          case SDL_KEYDOWN:
          case SDL_KEYUP:
                  !ev->active.gain && !gui_fullscreen_initial_grab) {
                  sdl_grab_end();
              }
 -            if (ev->active.state & SDL_APPACTIVE) {
 -                if (ev->active.gain) {
 -                    /* Back to default interval */
 -                    dcl->gui_timer_interval = 0;
 -                    dcl->idle = 0;
 -                } else {
 -                    /* Sleeping interval */
 -                    dcl->gui_timer_interval = 500;
 -                    dcl->idle = 1;
 -                }
 +          if (ev->active.state & SDL_APPACTIVE) {
 +              if (ev->active.gain) {
 +                  /* Back to default interval */
-                   dcl->gui_timer_interval = 0;
-                   dcl->idle = 0;
++                  ds->gui_timer_interval = 0;
++                  ds->idle = 0;
 +              } else {
 +                  /* Sleeping interval */
-                   dcl->gui_timer_interval = 500;
-                   dcl->idle = 1;
++                  ds->gui_timer_interval = 500;
++                  ds->idle = 1;
 +              }
 +          }
 +            break;
 +#ifdef CONFIG_OPENGL
 +        case SDL_VIDEORESIZE:
 +        {
-             if (opengl_enabled) {
++            if (ds->shared_buf && opengl_enabled) {
 +                SDL_ResizeEvent *rev = &ev->resize;
-                 real_screen = SDL_SetVideoMode(rev->w, rev->h, 0, SDL_OPENGL|SDL_RESIZABLE);
-                 opengl_setdata(ds);
-                 opengl_update(ds, 0, 0, ds_get_width(ds), ds_get_height(ds));
++                screen = SDL_SetVideoMode(rev->w, rev->h, 0, SDL_OPENGL|SDL_RESIZABLE);
++                opengl_setdata(ds, ds->data);
++                opengl_update(ds, 0, 0, ds->width, ds->height);
              }
              break;
 +        }
 +#endif
          default:
              break;
          }
@@@ -685,27 -636,19 +785,23 @@@ void sdl_display_init(DisplayState *ds
          fprintf(stderr, "Could not initialize SDL - exiting\n");
          exit(1);
      }
 +#ifndef _WIN32
 +    /* NOTE: we still want Ctrl-C to work, so we undo the SDL redirections */
 +    signal(SIGINT, SIG_DFL);
 +    signal(SIGQUIT, SIG_DFL);
 +#endif
  
--    dcl = qemu_mallocz(sizeof(DisplayChangeListener));
--    if (!dcl)
--        exit(1);
--    dcl->dpy_update = sdl_update;
--    dcl->dpy_resize = sdl_resize;
--    dcl->dpy_refresh = sdl_refresh;
--    dcl->dpy_setdata = sdl_setdata;
 -    dcl->dpy_fill = sdl_fill;
 -    ds->mouse_set = sdl_mouse_warp;
 -    ds->cursor_define = sdl_mouse_define;
 -    register_displaychangelistener(ds, dcl);
++    ds->dpy_update = sdl_update;
++    ds->dpy_resize = sdl_resize;
++    ds->dpy_resize_shared = sdl_resize_shared;
++    ds->dpy_refresh = sdl_refresh;
++    ds->dpy_setdata = sdl_setdata;
 +#ifdef CONFIG_OPENGL
-     if (opengl_enabled) {
-         dcl->dpy_update = opengl_update;
-         dcl->dpy_setdata = opengl_setdata;
-     }
++    if (opengl_enabled)
++        ds->dpy_setdata = opengl_setdata;
 +#endif
-     register_displaychangelistener(ds, dcl);
  
++    sdl_resize(ds, 640, 400);
      sdl_update_caption();
      SDL_EnableKeyRepeat(250, 50);
      gui_grab = 0;
diff --cc sysemu.h
Simple merge
diff --cc vl.c
index 7be1ade835f3207e7735ddfcba9907f468dff26f,36765378a4f4e5803c8a2fea4cd8e41bd63a3663..fceec987b2a2be164bb9fec1237935a3b3c15481
--- 1/vl.c
--- 2/vl.c
+++ b/vl.c
  #include "kvm.h"
  #include "balloon.h"
  
- #include <unistd.h>
++#include "hw/pci.h"
++#include "hw/xen.h"
 +#include <stdlib.h>
++
+ #include <unistd.h>
  #include <fcntl.h>
  #include <signal.h>
  #include <time.h>
@@@ -3867,14 -3849,10 +3878,16 @@@ static int main_loop(void
      return ret;
  }
  
 +#else /* CONFIG_DM */
 +void main_loop_prepare(void) {
 +    cur_cpu = first_cpu;
 +}
 +#endif /* !CONFIG_DM */
 +
  static void help(int exitcode)
  {
+     /* Please keep in synch with QEMU_OPTION_ enums, qemu_options[]
+        and qemu-doc.texi */
      printf("QEMU PC emulator version " QEMU_VERSION ", Copyright (c) 2003-2008 Fabrice Bellard\n"
             "usage: %s [options] [disk_image]\n"
             "\n"
             "                use -soundhw ? to get the list of supported cards\n"
             "                use -soundhw all to enable all of them\n"
  #endif
+            "-usb            enable the USB driver (will be the default soon)\n"
+            "-usbdevice name add the host or guest USB device 'name'\n"
+            "-name string    set the name of the guest\n"
+            "-uuid %%08x-%%04x-%%04x-%%04x-%%012x\n"
+            "                specify machine UUID\n"
+            "\n"
+            "Display options:\n"
+            "-nographic      disable graphical output and redirect serial I/Os to console\n"
+ #ifdef CONFIG_CURSES
+            "-curses         use a curses/ncurses interface instead of SDL\n"
+ #endif
+ #ifdef CONFIG_SDL
+            "-no-frame       open SDL window without a frame and window decorations\n"
+            "-alt-grab       use Ctrl-Alt-Shift to grab mouse (instead of Ctrl-Alt)\n"
+            "-no-quit        disable SDL window close capability\n"
+            "-sdl            enable SDL\n"
++#ifdef CONFIG_OPENGL
++           "-disable-opengl disable OpenGL rendering, using SDL"
++#endif
+ #endif
+            "-portrait       rotate graphical output 90 deg left (only PXA LCD)\n"
             "-vga [std|cirrus|vmware|none]\n"
             "                select video card type\n"
-            "-localtime      set the real time clock to local time [default=utc]\n"
             "-full-screen    start in full screen\n"
- #ifdef TARGET_I386
-            "-win2k-hack     use it when installing Windows 2000 to avoid a disk full bug\n"
-            "-rtc-td-hack    use it to fix time drift in Windows ACPI HAL\n"
- #endif
-            "-usb            enable the USB driver (will be the default soon)\n"
-            "-usbdevice name add the host or guest USB device 'name'\n"
  #if defined(TARGET_PPC) || defined(TARGET_SPARC)
             "-g WxH[xDEPTH]  Set the initial graphical resolution and depth\n"
  #endif
  #endif
             "-clock          force the use of the given methods for timer alarm.\n"
             "                To see what timers are available use -clock ?\n"
+            "-localtime      set the real time clock to local time [default=utc]\n"
             "-startdate      select initial date of the clock\n"
             "-icount [N|auto]\n"
-            "                Enable virtual instruction counter with 2^N clock ticks per instruction\n"
+            "                enable virtual instruction counter with 2^N clock ticks per instruction\n"
+            "-echr chr       set terminal escape character instead of ctrl-a\n"
+            "-virtioconsole c\n"
+            "                set virtio console\n"
+            "-show-cursor    show cursor\n"
+ #if defined(TARGET_ARM) || defined(TARGET_M68K)
+            "-semihosting    semihosting mode\n"
+ #endif
+ #if defined(TARGET_ARM)
+            "-old-param      old param mode\n"
+ #endif
+            "-tb-size n      set TB size\n"
+            "-incoming p     prepare for incoming migration, listen on port p\n"
             "\n"
++         "Options specific to the Xen version:\n"
++           "-videoram       set amount of memory available to virtual video adapter\n"
++         "-direct-pci s   specify pci passthrough, with configuration string s\n"
++           "-pciemulation       name:vendorid:deviceid:command:status:revision:classcode:headertype:subvendorid:subsystemid:interruputline:interruputpin\n"
++           "-vncunused      bind the VNC server to an unused port\n"
++           "-std-vga        alias for -vga std\n"
++         "\n"
             "During emulation, the following keys are useful:\n"
             "ctrl-alt-f      toggle full screen\n"
             "ctrl-alt-n      switch to virtual console 'n'\n"
@@@ -4106,6 -4114,11 +4160,19 @@@ enum 
      QEMU_OPTION_append,
      QEMU_OPTION_initrd,
  
++    /* Xen tree: */
++    QEMU_OPTION_disable_opengl,
++    QEMU_OPTION_direct_pci,
++    QEMU_OPTION_pci_emulation,
++    QEMU_OPTION_vncunused,
++    QEMU_OPTION_videoram,
++    QEMU_OPTION_std_vga,
++
+     /* Debug/Expert options: */
+     QEMU_OPTION_serial,
+     QEMU_OPTION_parallel,
+     QEMU_OPTION_monitor,
+     QEMU_OPTION_pidfile,
      QEMU_OPTION_S,
      QEMU_OPTION_s,
      QEMU_OPTION_p,
@@@ -4239,66 -4252,24 +4306,44 @@@ static const QEMUOption qemu_options[] 
  #ifdef CONFIG_KVM
      { "enable-kvm", 0, QEMU_OPTION_enable_kvm },
  #endif
- #if defined(TARGET_PPC) || defined(TARGET_SPARC)
-     { "g", 1, QEMU_OPTION_g },
+     { "no-reboot", 0, QEMU_OPTION_no_reboot },
+     { "no-shutdown", 0, QEMU_OPTION_no_shutdown },
+     { "loadvm", HAS_ARG, QEMU_OPTION_loadvm },
+     { "daemonize", 0, QEMU_OPTION_daemonize },
+     { "option-rom", HAS_ARG, QEMU_OPTION_option_rom },
+ #if defined(TARGET_SPARC) || defined(TARGET_PPC)
+     { "prom-env", HAS_ARG, QEMU_OPTION_prom_env },
  #endif
+     { "clock", HAS_ARG, QEMU_OPTION_clock },
      { "localtime", 0, QEMU_OPTION_localtime },
-     { "std-vga", 0, QEMU_OPTION_std_vga },
-     { "videoram", HAS_ARG, QEMU_OPTION_videoram },
-     { "vga", HAS_ARG, QEMU_OPTION_vga },
+     { "startdate", HAS_ARG, QEMU_OPTION_startdate },
+     { "icount", HAS_ARG, QEMU_OPTION_icount },
      { "echr", HAS_ARG, QEMU_OPTION_echr },
-     { "monitor", HAS_ARG, QEMU_OPTION_monitor },
-     { "domain-name", 1, QEMU_OPTION_domainname },
-     { "serial", HAS_ARG, QEMU_OPTION_serial },
      { "virtioconsole", HAS_ARG, QEMU_OPTION_virtiocon },
-     { "parallel", HAS_ARG, QEMU_OPTION_parallel },
-     { "loadvm", HAS_ARG, QEMU_OPTION_loadvm },
-     { "full-screen", 0, QEMU_OPTION_full_screen },
- #ifdef CONFIG_SDL
-     { "no-frame", 0, QEMU_OPTION_no_frame },
-     { "alt-grab", 0, QEMU_OPTION_alt_grab },
-     { "no-quit", 0, QEMU_OPTION_no_quit },
+     { "show-cursor", 0, QEMU_OPTION_show_cursor },
+ #if defined(TARGET_ARM) || defined(TARGET_M68K)
+     { "semihosting", 0, QEMU_OPTION_semihosting },
  #endif
-     { "vcpus", 1, QEMU_OPTION_vcpus },
++
++    /* Xen tree options: */
++    { "std-vga", 0, QEMU_OPTION_std_vga },
++    { "videoram", HAS_ARG, QEMU_OPTION_videoram },
++    { "d", HAS_ARG, QEMU_OPTION_domid }, /* deprecated; for xend compatibility */
++    { "domid", HAS_ARG, QEMU_OPTION_domid },
++    { "domain-name", 1, QEMU_OPTION_domainname },
 +#ifdef CONFIG_OPENGL
 +    { "disable-opengl", 0, QEMU_OPTION_disable_opengl },
 +#endif
-     { "pidfile", HAS_ARG, QEMU_OPTION_pidfile },
-     { "win2k-hack", 0, QEMU_OPTION_win2k_hack },
-     { "rtc-td-hack", 0, QEMU_OPTION_rtc_td_hack },
-     { "usbdevice", HAS_ARG, QEMU_OPTION_usbdevice },
-     { "smp", HAS_ARG, QEMU_OPTION_smp },
-     { "vnc", HAS_ARG, QEMU_OPTION_vnc },
 +    { "acpi", 0, QEMU_OPTION_acpi }, /* deprecated, for xend compatibility */
 +    { "direct_pci", HAS_ARG, QEMU_OPTION_direct_pci },
 +    { "pciemulation", HAS_ARG, QEMU_OPTION_pci_emulation },
- #ifdef CONFIG_CURSES
-     { "curses", 0, QEMU_OPTION_curses },
- #endif
-     { "uuid", HAS_ARG, QEMU_OPTION_uuid },
 +    { "vncunused", 0, QEMU_OPTION_vncunused },
-     /* temporary options */
-     { "usb", 0, QEMU_OPTION_usb },
-     { "no-acpi", 0, QEMU_OPTION_no_acpi },
-     { "no-hpet", 0, QEMU_OPTION_no_hpet },
-     { "no-reboot", 0, QEMU_OPTION_no_reboot },
-     { "no-shutdown", 0, QEMU_OPTION_no_shutdown },
-     { "show-cursor", 0, QEMU_OPTION_show_cursor },
-     { "daemonize", 0, QEMU_OPTION_daemonize },
-     { "option-rom", HAS_ARG, QEMU_OPTION_option_rom },
- #if defined(TARGET_ARM) || defined(TARGET_M68K)
-     { "semihosting", 0, QEMU_OPTION_semihosting },
- #endif
-     { "name", HAS_ARG, QEMU_OPTION_name },
- #if defined(TARGET_SPARC) || defined(TARGET_PPC)
-     { "prom-env", HAS_ARG, QEMU_OPTION_prom_env },
- #endif
 +#ifdef CONFIG_XEN
 +    { "xen-domid", HAS_ARG, QEMU_OPTION_xen_domid },
 +    { "xen-create", 0, QEMU_OPTION_xen_create },
 +    { "xen-attach", 0, QEMU_OPTION_xen_attach },
 +#endif
 +
  #if defined(TARGET_ARM)
      { "old-param", 0, QEMU_OPTION_old_param },
  #endif
@@@ -4624,35 -4586,7 +4660,34 @@@ int main(int argc, char **argv, char **
      int autostart;
      const char *incoming = NULL;
  
-  #endif
-  
-     qemu_cache_utils_init(envp);
+     qemu_cache_utils_init(envp);
 +    logfile = stderr; /* initial value */
 +
 +#if !defined(__sun__) && !defined(CONFIG_STUBDOM)
 +    /* Maximise rlimits. Needed where default constraints are tight (*BSD). */
 +    if (getrlimit(RLIMIT_STACK, &rl) != 0) {
 +       perror("getrlimit(RLIMIT_STACK)");
 +       exit(1);
 +    }
 +    rl.rlim_cur = rl.rlim_max;
 +    if (setrlimit(RLIMIT_STACK, &rl) != 0)
 +       perror("setrlimit(RLIMIT_STACK)");
 +    if (getrlimit(RLIMIT_DATA, &rl) != 0) {
 +       perror("getrlimit(RLIMIT_DATA)");
 +       exit(1);
 +    }
 +    rl.rlim_cur = rl.rlim_max;
 +    if (setrlimit(RLIMIT_DATA, &rl) != 0)
 +       perror("setrlimit(RLIMIT_DATA)");
 +    rl.rlim_cur = RLIM_INFINITY;
 +    rl.rlim_max = RLIM_INFINITY;
 +    if (setrlimit(RLIMIT_RSS, &rl) != 0)
 +       perror("setrlimit(RLIMIT_RSS)");
 +    rl.rlim_cur = RLIM_INFINITY;
 +    rl.rlim_max = RLIM_INFINITY;
 +    if (setrlimit(RLIMIT_MEMLOCK, &rl) != 0)
 +       perror("setrlimit(RLIMIT_MEMLOCK)");
++#endif
  
      LIST_INIT (&vm_change_state_head);
  #ifndef _WIN32
                  break;
            case QEMU_OPTION_loadvm:
                loadvm = optarg;
-                 restore = 1;
++              restore = 1;
                break;
              case QEMU_OPTION_full_screen:
                  full_screen = 1;
              case QEMU_OPTION_no_quit:
                  no_quit = 1;
                  break;
+             case QEMU_OPTION_sdl:
+                 sdl = 1;
+                 break;
  #endif
-               direct_pci = optarg;
++
++            case QEMU_OPTION_pci_emulation:
++                if (nb_pci_emulation >= MAX_PCI_EMULATION) {
++                    fprintf(stderr, "Too many PCI emulations\n");
++                    exit(1);
++                }
++                pstrcpy(pci_emulation_config_text[nb_pci_emulation],
++                        sizeof(pci_emulation_config_text[0]),
++                        optarg);
++                nb_pci_emulation++;
++                break;
++            case QEMU_OPTION_domid: /* depricated, use -xen-* instead */
++                xen_domid = domid = atoi(optarg);
++                xen_mode  = XEN_ATTACH;
++                fprintf(logfile, "domid: %d\n", domid);
++                break;
++            case QEMU_OPTION_videoram:
++                {
++                    char *ptr;
++                    vga_ram_size = strtol(optarg,&ptr,10);
++                    vga_ram_size *= 1024 * 1024;
++                }
++                break;
++            case QEMU_OPTION_std_vga:
++                cirrus_vga_enabled = 0;
++                vmsvga_enabled = 0;
++                break;
 +            case QEMU_OPTION_disable_opengl:
 +                opengl_enabled = 0;
 +                break;
 +            case QEMU_OPTION_direct_pci:
++               direct_pci = optarg;
 +                break;
 +            case QEMU_OPTION_vcpus:
 +                vcpus = atoi(optarg);
 +                fprintf(logfile, "qemu: the number of cpus is %d\n", vcpus);
 +                break;
 +            case QEMU_OPTION_acpi:
 +                acpi_enabled = 1;
 +                break;
++            case QEMU_OPTION_vncunused:
++                vncunused = 1;
++                break;
++#ifdef CONFIG_XEN
++            case QEMU_OPTION_xen_domid:
++                xen_domid = domid = atoi(optarg);
++                break;
++            case QEMU_OPTION_xen_create:
++                xen_mode = XEN_CREATE;
++                break;
++            case QEMU_OPTION_xen_attach:
++                xen_mode = XEN_ATTACH;
++                break;
++#endif
++
              case QEMU_OPTION_pidfile:
                  pid_file = optarg;
                  break;
              case QEMU_OPTION_semihosting:
                  semihosting_enabled = 1;
                  break;
 +            case QEMU_OPTION_domainname: /* depricated, use -name instead */
              case QEMU_OPTION_name:
-                 qemu_name = optarg;
 +                snprintf(domain_name, sizeof(domain_name),
 +                         "Xen-%s", optarg);
+                 qemu_name = optarg;
                  break;
  #if defined(TARGET_SPARC) || defined(TARGET_PPC)
              case QEMU_OPTION_prom_env:
            exit(1);
        }
      }
  #endif
  
 +#if defined (__ia64__)
 +    if (ram_size > VGA_IO_START)
 +        ram_size += VGA_IO_SIZE; /* skip VGA I/O hole */
 +    if (ram_size > MMIO_START)
 +        ram_size += 1 * MEM_G; /* skip 3G-4G MMIO, LEGACY_IO_SPACE etc. */
 +#endif
 +
      /* init the bluetooth world */
      for (i = 0; i < nb_bt_opts; i++)
          if (bt_parse(bt_opts[i]))
      register_savevm("timer", 0, 2, timer_save, timer_load, NULL);
      register_savevm_live("ram", 0, 3, ram_save_live, NULL, ram_load, NULL);
  
-     /* terminal init */
-     memset(&display_state, 0, sizeof(display_state));
- #ifdef CONFIG_STUBDOM
-     if (xenfb_pv_display_init(ds) == 0) {
-     } else
- #endif
-     if (nographic) {
-         if (curses) {
-             fprintf(stderr, "fatal: -nographic can't be used with -curses\n");
-             exit(1);
-         }
-         /* nearly nothing to do */
-         dumb_display_init(ds);
-     } else if (vnc_display != NULL || vncunused != 0) {
-       int vnc_display_port;
-         char password[20];
-         vnc_display_init(ds);
-         xenstore_read_vncpasswd(domid, password, sizeof(password));
-         vnc_display_password(ds, password);
-         vnc_display_port = vnc_display_open(ds, vnc_display, vncunused);
-         if (vnc_display_port < 0)
-             exit(1);
-       xenstore_write_vncport(vnc_display_port);
-     } else
- #if defined(CONFIG_CURSES)
-     if (curses) {
-         curses_display_init(ds, full_screen);
-     } else
- #endif
-     {
- #if defined(CONFIG_SDL)
-         sdl_display_init(ds, full_screen, no_frame, opengl_enabled);
- #elif defined(CONFIG_COCOA)
-         cocoa_display_init(ds, full_screen);
- #else
-         dumb_display_init(ds);
- #endif
-     }
  #ifndef _WIN32
++#ifndef CONFIG_DM
      /* must be after terminal init, SDL library changes signal handlers */
      termsig_setup();
++#endif
  #endif
  
      /* Maintain compatibility with multiple stdio monitors */
          }
      }
  
-     machine->init(ram_size, vga_ram_size, boot_devices, ds,
+     machine->init(ram_size, vga_ram_size, boot_devices,
 -                  kernel_filename, kernel_cmdline, initrd_filename, cpu_model);
 +                  kernel_filename, kernel_cmdline, initrd_filename, cpu_model,
 +                direct_pci);
  
      /* Set KVM's vcpu state to qemu's initial CPUState. */
      if (kvm_enabled()) {
          }
      }
  
-     if (display_state.dpy_refresh) {
-         display_state.gui_timer = qemu_new_timer(rt_clock, gui_update, &display_state);
-         qemu_mod_timer(display_state.gui_timer, qemu_get_clock(rt_clock));
+     if (!display_state)
+         dumb_display_init();
+     /* just use the first displaystate for the moment */
+     ds = display_state;
+     /* terminal init */
+++#ifdef CONFIG_STUBDOM
+++    if (xenfb_pv_display_init(ds) == 0) {
+++    } else
+++#endif
+     if (nographic) {
+         if (curses) {
+             fprintf(stderr, "fatal: -nographic can't be used with -curses\n");
+             exit(1);
+         }
+     } else { 
+ #if defined(CONFIG_CURSES)
+             if (curses) {
+                 /* At the moment curses cannot be used with other displays */
+                 curses_display_init(ds, full_screen);
+             } else
+ #endif
+             {
 -                if (vnc_display != NULL) {
 -                    vnc_display_init(ds);
 -                    if (vnc_display_open(ds, vnc_display) < 0)
++                if (vnc_display != NULL || vncunused != 0) {
++                  int vnc_display_port;
++                  char password[20];
++                    vnc_display_init(ds, vncunused);
++                  xenstore_read_vncpasswd(domid, password, sizeof(password));
++                  vnc_display_password(ds, password);
++                    vnc_display_port = vnc_display_open(ds, vnc_display, vncunused);
++                  if (vnc_display_port < 0)
+                         exit(1);
++                  xenstore_write_vncport(vnc_display_port);
+                 }
+ #if defined(CONFIG_SDL)
+                 if (sdl || !vnc_display)
 -                    sdl_display_init(ds, full_screen, no_frame);
++                    sdl_display_init(ds, full_screen, no_frame, opengl_enabled);
+ #elif defined(CONFIG_COCOA)
+                 if (sdl || !vnc_display)
+                     cocoa_display_init(ds, full_screen);
+ #endif
+             }
+     }
+     dpy_resize(ds);
+     dcl = ds->listeners;
+     while (dcl != NULL) {
+         if (dcl->dpy_refresh != NULL) {
+             ds->gui_timer = qemu_new_timer(rt_clock, gui_update, ds);
+             qemu_mod_timer(ds->gui_timer, qemu_get_clock(rt_clock));
+         }
+         dcl = dcl->next;
+     }
+     if (nographic || (vnc_display && !sdl)) {
+         nographic_timer = qemu_new_timer(rt_clock, nographic_update, NULL);
+         qemu_mod_timer(nographic_timer, qemu_get_clock(rt_clock));
+     }
+     text_consoles_set_display(display_state);
+     if (monitor_device && monitor_hd)
+         monitor_init(monitor_hd, !nographic);
+     for(i = 0; i < MAX_SERIAL_PORTS; i++) {
+         const char *devname = serial_devices[i];
+         if (devname && strcmp(devname, "none")) {
+             char label[32];
+             snprintf(label, sizeof(label), "serial%d", i);
+             if (strstart(devname, "vc", 0))
+                 qemu_chr_printf(serial_hds[i], "serial%d console\r\n", i);
+         }
+     }
+     for(i = 0; i < MAX_PARALLEL_PORTS; i++) {
+         const char *devname = parallel_devices[i];
+         if (devname && strcmp(devname, "none")) {
+             char label[32];
+             snprintf(label, sizeof(label), "parallel%d", i);
+             if (strstart(devname, "vc", 0))
+                 qemu_chr_printf(parallel_hds[i], "parallel%d console\r\n", i);
+         }
+     }
++    for (i = 0; i < nb_pci_emulation; i++) {
++        if(pci_emulation_add(pci_emulation_config_text[i]) < 0) {
++            fprintf(stderr, "Warning: could not add PCI device %s\n",
++                    pci_emulation_config_text[i]);
++        }
++    }
++
++    if (strlen(direct_pci_str) > 0)
++        direct_pci = direct_pci_str;
++
+     for(i = 0; i < MAX_VIRTIO_CONSOLES; i++) {
+         const char *devname = virtio_consoles[i];
+         if (virtcon_hds[i] && devname) {
+             char label[32];
+             snprintf(label, sizeof(label), "virtcon%d", i);
+             if (strstart(devname, "vc", 0))
+                 qemu_chr_printf(virtcon_hds[i], "virtio console%d\r\n", i);
+         }
      }
  
  #ifdef CONFIG_GDBSTUB
diff --cc vnc.c
index 52e46274ff85fa06ec126e0a1b5b9166811d75e4,0c4d96e25064d63fe0eb4bfb28e161d0766e47a9..02d3b1d16e085a582211ddc8fc7012160648cbbf
--- 1/vnc.c
--- 2/vnc.c
+++ b/vnc.c
@@@ -74,12 -58,12 +74,6 @@@ static void vnc_debug_gnutls_log(int le
  #define VNC_DEBUG(fmt, ...) do { } while (0)
  #endif
  
--#define count_bits(c, v) { \
--    for (c = 0; v; v >>= 1) \
--    { \
--        c += v & 1; \
--    } \
--}
  
  typedef struct Buffer
  {
@@@ -168,19 -96,10 +162,22 @@@ struct VncStat
      int lsock;
      int csock;
      DisplayState *ds;
 -    int need_update;
 -    uint32_t dirty_row[VNC_MAX_HEIGHT][VNC_DIRTY_WORDS];
 -    char *old_data;
 -    uint32_t features;
++    int width;
++    int height;
 +    uint64_t *dirty_row;      /* screen regions which are possibly dirty */
 +    int dirty_pixel_shift;
 +    uint64_t *update_row;     /* outstanding updates */
 +    int has_update;           /* there's outstanding updates in the
 +                               * visible area */
 +
 +    int update_requested;       /* the client requested an update */
 +
 +    uint8_t *old_data;
++    int depth; /* internal VNC frame buffer byte per pixel */
 +    int has_resize;
 +    int has_hextile;
 +    int has_pointer_type_change;
 +    int has_WMVi;
      int absolute;
      int last_x;
      int last_y;
      /* current output mode information */
      VncWritePixels *write_pixels;
      VncSendHextileTile *send_hextile_tile;
--    DisplaySurface clientds, serverds;
 -
 -    CaptureVoiceOut *audio_cap;
 -    struct audsettings as;
++    int pix_bpp, pix_big_endian;
++    int red_shift, red_max, red_shift1, red_max1;
++    int green_shift, green_max, green_shift1, green_max1;
++    int blue_shift, blue_max, blue_shift1, blue_max1;
  
      VncReadEvent *read_handler;
      size_t read_handler_expect;
  };
  
  static VncState *vnc_state; /* needed for info vnc */
--static DisplayChangeListener *dcl;
 +
 +#define DIRTY_PIXEL_BITS 64
 +#define X2DP_DOWN(vs, x) ((x) >> (vs)->dirty_pixel_shift)
 +#define X2DP_UP(vs, x) \
 +  (((x) + (1ULL << (vs)->dirty_pixel_shift) - 1) >> (vs)->dirty_pixel_shift)
 +#define DP2X(vs, x) ((x) << (vs)->dirty_pixel_shift)
  
  void do_info_vnc(void)
  {
@@@ -269,18 -187,11 +268,18 @@@ static void vnc_write_s32(VncState *vs
  static void vnc_write_u16(VncState *vs, uint16_t value);
  static void vnc_write_u8(VncState *vs, uint8_t value);
  static void vnc_flush(VncState *vs);
 +static void _vnc_update_client(void *opaque);
  static void vnc_update_client(void *opaque);
  static void vnc_client_read(void *opaque);
 -
 -static void vnc_colordepth(DisplayState *ds);
 -
 +static void framebuffer_set_updated(VncState *vs, int x, int y, int w, int h);
 +static void pixel_format_message (VncState *vs);
 +static void enqueue_framebuffer_update(VncState *vs, int x, int y, int w, int h, int32_t encoding);
 +static void dequeue_framebuffer_update(VncState *vs);
 +static int is_empty_queue(VncState *vs);
 +static void free_queue(VncState *vs);
- static void vnc_colordepth(DisplayState *ds);
++static void vnc_colourdepth(DisplayState *ds, int depth);
 +
 +#if 0
  static inline void vnc_set_bit(uint32_t *d, int k)
  {
      d[k >> 5] |= 1 << (k & 0x1f);
@@@ -321,42 -232,29 +320,42 @@@ static inline int vnc_and_bits(const ui
      }
      return 0;
  }
 +#endif
  
 -static void vnc_dpy_update(DisplayState *ds, int x, int y, int w, int h)
 +static void set_bits_in_row(VncState *vs, uint64_t *row,
 +                          int x, int y, int w, int h)
  {
 -    VncState *vs = ds->opaque;
 -    int i;
 +    int x1, x2;
 +    uint64_t mask;
  
 -    h += y;
 +    if (w == 0)
 +      return;
  
 -    /* round x down to ensure the loop only spans one 16-pixel block per,
 -       iteration.  otherwise, if (x % 16) != 0, the last iteration may span
 -       two 16-pixel blocks but we only mark the first as dirty
 -    */
 -    w += (x % 16);
 -    x -= (x % 16);
 +    x1 = X2DP_DOWN(vs, x);
 +    x2 = X2DP_UP(vs, x + w);
  
 -    x = MIN(x, vs->serverds.width);
 -    y = MIN(y, vs->serverds.height);
 -    w = MIN(x + w, vs->serverds.width) - x;
 -    h = MIN(h, vs->serverds.height);
 +    if (X2DP_UP(vs, w) != DIRTY_PIXEL_BITS)
 +      mask = ((1ULL << (x2 - x1)) - 1) << x1;
 +    else
 +      mask = ~(0ULL);
  
-     if (h > ds_get_height(vs->ds))
-         h = ds_get_height(vs->ds);
 +    h += y;
++    if (h > vs->ds->height)
++        h = vs->ds->height;
      for (; y < h; y++)
 -      for (i = 0; i < w; i += 16)
 -          vnc_set_bit(vs->dirty_row[y], (x + i) / 16);
 +      row[y] |= mask;
 +}
 +
 +static void vnc_dpy_update(DisplayState *ds, int x, int y, int w, int h)
 +{
 +    VncState *vs = ds->opaque;
 +
-     x = MIN(x, vs->serverds.width);
-     y = MIN(y, vs->serverds.height);
-     w = MIN(w, vs->serverds.width - x);
-     h = MIN(h, vs->serverds.height - y);
++    x = MIN(x, vs->width);
++    y = MIN(y, vs->height);
++    w = MIN(w, vs->width - x);
++    h = MIN(h, vs->height - y);
 +
 +    set_bits_in_row(vs, vs->dirty_row, x, y, w, h);
  }
  
  static void vnc_framebuffer_update(VncState *vs, int x, int y, int w, int h,
      vnc_write_s32(vs, encoding);
  }
  
 -static void buffer_reserve(Buffer *buffer, size_t len)
 -{
 -    if ((buffer->capacity - buffer->offset) < len) {
 -      buffer->capacity += (len + 1024);
 -      buffer->buffer = qemu_realloc(buffer->buffer, buffer->capacity);
 -      if (buffer->buffer == NULL) {
 -          fprintf(stderr, "vnc: out of memory\n");
 -          exit(1);
 -      }
 -    }
 -}
 -
 -static int buffer_empty(Buffer *buffer)
 -{
 -    return buffer->offset == 0;
 -}
 -
 -static uint8_t *buffer_end(Buffer *buffer)
 -{
 -    return buffer->buffer + buffer->offset;
 -}
 -
 -static void buffer_reset(Buffer *buffer)
 -{
 -      buffer->offset = 0;
 -}
 -
 -static void buffer_append(Buffer *buffer, const void *data, size_t len)
 -{
 -    memcpy(buffer->buffer + buffer->offset, data, len);
 -    buffer->offset += len;
 -}
 -
--static void vnc_dpy_resize(DisplayState *ds)
++static void vnc_dpy_resize_shared(DisplayState *ds, int w, int h, int depth, int linesize, void *pixels)
  {
++    static int allocated;
      int size_changed;
      VncState *vs = ds->opaque;
 +    int o;
  
-     vs->old_data = qemu_realloc(vs->old_data, ds_get_height(ds) * ds_get_linesize(ds));
-     vs->dirty_row = qemu_realloc(vs->dirty_row, ds_get_height(ds) * sizeof(vs->dirty_row[0]));
-     vs->update_row = qemu_realloc(vs->update_row, ds_get_height(ds) * sizeof(vs->dirty_row[0]));
 -    vs->old_data = qemu_realloc(vs->old_data, ds_get_linesize(ds) * ds_get_height(ds));
++    vnc_colourdepth(ds, depth);
++    if (!ds->shared_buf) {
++        ds->linesize = w * vs->depth;
++        if (allocated)
++            ds->data = qemu_realloc(ds->data,  h * ds->linesize);
++        else
++            ds->data = malloc(h * ds->linesize);
++        allocated = 1;
++    } else {
++        ds->linesize = linesize;
++        if (allocated) {
++            free(ds->data);
++            allocated = 0;
++        }
++    }
++    vs->old_data = qemu_realloc(vs->old_data, h * ds->linesize);
++    vs->dirty_row = qemu_realloc(vs->dirty_row, h * sizeof(vs->dirty_row[0]));
++    vs->update_row = qemu_realloc(vs->update_row, h * sizeof(vs->dirty_row[0]));
  
-     if (vs->old_data == NULL || vs->dirty_row == NULL || vs->update_row == NULL) {
 -    if (vs->old_data == NULL) {
++    if (ds->data == NULL || vs->old_data == NULL ||
++      vs->dirty_row == NULL || vs->update_row == NULL) {
        fprintf(stderr, "vnc: memory allocation failed\n");
        exit(1);
      }
  
--    if (ds_get_bytes_per_pixel(ds) != vs->serverds.pf.bytes_per_pixel)
++    if (ds->depth != vs->depth * 8) {
++        ds->depth = vs->depth * 8;
          console_color_init(ds);
--    vnc_colordepth(ds);
--    size_changed = ds_get_width(ds) != vs->serverds.width ||
--                   ds_get_height(ds) != vs->serverds.height;
--    vs->serverds = *(ds->surface);
 -    if (size_changed) {
 -        if (vs->csock != -1 && vnc_has_feature(vs, VNC_FEATURE_RESIZE)) {
 -            vnc_write_u8(vs, 0);  /* msg id */
 -            vnc_write_u8(vs, 0);
 -            vnc_write_u16(vs, 1); /* number of rects */
 -            vnc_framebuffer_update(vs, 0, 0, ds_get_width(ds), ds_get_height(ds),
 -                                   VNC_ENCODING_DESKTOPRESIZE);
 -            vnc_flush(vs);
++    }
++    size_changed = ds->width != w || ds->height != h;
++    ds->width = w;
++    ds->height = h;
 +    if (vs->csock != -1 && vs->has_resize && size_changed) {
++        vs->width = ds->width;
++        vs->height = ds->height;
 +        if (vs->update_requested) {
 +          vnc_write_u8(vs, 0);  /* msg id */
 +          vnc_write_u8(vs, 0);
 +          vnc_write_u16(vs, 1); /* number of rects */
-           vnc_framebuffer_update(vs, 0, 0, ds_get_width(ds), ds_get_height(ds), -223);
++          vnc_framebuffer_update(vs, 0, 0, ds->width, ds->height, -223);
 +          vnc_flush(vs);
 +            vs->update_requested--;
 +        } else {
-             enqueue_framebuffer_update(vs, 0, 0, ds_get_width(ds), ds_get_height(ds), -223);
++            enqueue_framebuffer_update(vs, 0, 0, ds->width, ds->height, -223);
          }
      }
-     for (o = DIRTY_PIXEL_BITS; o < ds_get_width(ds); o *= 2)
 +    vs->dirty_pixel_shift = 0;
-     framebuffer_set_updated(vs, 0, 0, ds_get_width(ds), ds_get_height(ds));
++    for (o = DIRTY_PIXEL_BITS; o < ds->width; o *= 2)
 +      vs->dirty_pixel_shift++;
 -    memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row));
 -    memset(vs->old_data, 42, ds_get_linesize(vs->ds) * ds_get_height(vs->ds));
++    framebuffer_set_updated(vs, 0, 0, ds->width, ds->height);
++    if (ds->shared_buf) ds->data = pixels;
++}
++static void vnc_dpy_resize(DisplayState *ds, int w, int h)
++{
++    vnc_dpy_resize_shared(ds, w, h, 0, w * (ds->depth / 8), NULL);
  }
  
  /* fastest code */
@@@ -420,72 -345,72 +445,62 @@@ static void vnc_convert_pixel(VncState 
  {
      uint8_t r, g, b;
  
--    r = ((((v & vs->serverds.pf.rmask) >> vs->serverds.pf.rshift) << vs->clientds.pf.rbits) >>
--        vs->serverds.pf.rbits);
--    g = ((((v & vs->serverds.pf.gmask) >> vs->serverds.pf.gshift) << vs->clientds.pf.gbits) >>
--        vs->serverds.pf.gbits);
--    b = ((((v & vs->serverds.pf.bmask) >> vs->serverds.pf.bshift) << vs->clientds.pf.bbits) >>
--        vs->serverds.pf.bbits);
--    v = (r << vs->clientds.pf.rshift) |
--        (g << vs->clientds.pf.gshift) |
--        (b << vs->clientds.pf.bshift);
--    switch(vs->clientds.pf.bytes_per_pixel) {
++    r = ((v >> vs->red_shift1) & vs->red_max1) * (vs->red_max + 1) / (vs->red_max1 + 1);
++    g = ((v >> vs->green_shift1) & vs->green_max1) * (vs->green_max + 1) / (vs->green_max1 + 1);
++    b = ((v >> vs->blue_shift1) & vs->blue_max1) * (vs->blue_max + 1) / (vs->blue_max1 + 1);
++    switch(vs->pix_bpp) {
      case 1:
-         buf[0] = v; 
 -        buf[0] = v;
++        buf[0] = (r << vs->red_shift) | (g << vs->green_shift) | (b << vs->blue_shift);
          break;
      case 2:
--        if (vs->clientds.flags & QEMU_BIG_ENDIAN_FLAG) {
--            buf[0] = v >> 8;
--            buf[1] = v;
--        } else {
--            buf[1] = v >> 8;
--            buf[0] = v;
++    {
++        uint16_t *p = (uint16_t *) buf;
++        *p = (r << vs->red_shift) | (g << vs->green_shift) | (b << vs->blue_shift);
++        if (vs->pix_big_endian) {
++            *p = htons(*p);
          }
++    }
          break;
      default:
      case 4:
--        if (vs->clientds.flags & QEMU_BIG_ENDIAN_FLAG) {
--            buf[0] = v >> 24;
--            buf[1] = v >> 16;
--            buf[2] = v >> 8;
--            buf[3] = v;
--        } else {
--            buf[3] = v >> 24;
--            buf[2] = v >> 16;
--            buf[1] = v >> 8;
--            buf[0] = v;
++    {
++        uint32_t *p = (uint32_t *) buf;
++        *p = (r << vs->red_shift) | (g << vs->green_shift) | (b << vs->blue_shift);
++        if (vs->pix_big_endian) {
++            *p = htonl(*p);
          }
          break;
      }
++    }
  }
  
  static void vnc_write_pixels_generic(VncState *vs, void *pixels1, int size)
  {
      uint8_t buf[4];
  
--    if (vs->serverds.pf.bytes_per_pixel == 4) {
++    if (vs->depth == 4) {
          uint32_t *pixels = pixels1;
          int n, i;
          n = size >> 2;
          for(i = 0; i < n; i++) {
              vnc_convert_pixel(vs, buf, pixels[i]);
--            vnc_write(vs, buf, vs->clientds.pf.bytes_per_pixel);
++            vnc_write(vs, buf, vs->pix_bpp);
          }
--    } else if (vs->serverds.pf.bytes_per_pixel == 2) {
++    } else if (vs->depth == 2) {
          uint16_t *pixels = pixels1;
          int n, i;
          n = size >> 1;
          for(i = 0; i < n; i++) {
              vnc_convert_pixel(vs, buf, pixels[i]);
--            vnc_write(vs, buf, vs->clientds.pf.bytes_per_pixel);
++            vnc_write(vs, buf, vs->pix_bpp);
          }
--    } else if (vs->serverds.pf.bytes_per_pixel == 1) {
++    } else if (vs->depth == 1) {
          uint8_t *pixels = pixels1;
          int n, i;
          n = size;
          for(i = 0; i < n; i++) {
              vnc_convert_pixel(vs, buf, pixels[i]);
--            vnc_write(vs, buf, vs->clientds.pf.bytes_per_pixel);
++            vnc_write(vs, buf, vs->pix_bpp);
          }
      } else {
          fprintf(stderr, "vnc_write_pixels_generic: VncState color depth not supported\n");
@@@ -497,12 -422,10 +512,12 @@@ static void send_framebuffer_update_raw
      int i;
      uint8_t *row;
  
 -    row = ds_get_data(vs->ds) + y * ds_get_linesize(vs->ds) + x * ds_get_bytes_per_pixel(vs->ds);
 +    vnc_framebuffer_update(vs, x, y, w, h, 0);
 +
-     row = ds_get_data(vs->ds) + y * ds_get_linesize(vs->ds) + x * ds_get_bytes_per_pixel(vs->ds);
++    row = vs->ds->data + y * vs->ds->linesize + x * vs->depth;
      for (i = 0; i < h; i++) {
--      vs->write_pixels(vs, row, w * ds_get_bytes_per_pixel(vs->ds));
--      row += ds_get_linesize(vs->ds);
++      vs->write_pixels(vs, row, w * vs->depth);
++      row += vs->ds->linesize;
      }
  }
  
@@@ -546,12 -469,10 +561,12 @@@ static void send_framebuffer_update_hex
  {
      int i, j;
      int has_fg, has_bg;
 -    uint8_t *last_fg, *last_bg;
 +    void *last_fg, *last_bg;
  
 -    last_fg = (uint8_t *) malloc(vs->serverds.pf.bytes_per_pixel);
 -    last_bg = (uint8_t *) malloc(vs->serverds.pf.bytes_per_pixel);
 +    vnc_framebuffer_update(vs, x, y, w, h, 5);
 +
-     last_fg = (void *) malloc(vs->serverds.pf.bytes_per_pixel);
-     last_bg = (void *) malloc(vs->serverds.pf.bytes_per_pixel);
++    last_fg = (void *) malloc(vs->depth);
++    last_bg = (void *) malloc(vs->depth);
      has_fg = has_bg = 0;
      for (j = y; j < (y + h); j += 16) {
        for (i = x; i < (x + w); i += 16) {
        }
      }
      free(last_fg);
 -    free(last_bg);
 -
 -}
 -
 -static void vnc_zlib_init(VncState *vs)
 -{
 -    int i;
 -    for (i=0; i<(sizeof(vs->zlib_stream) / sizeof(z_stream)); i++)
 -        vs->zlib_stream[i].opaque = NULL;
 +    free(last_bg);    
  }
  
 -static void vnc_zlib_start(VncState *vs)
 +static void send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
  {
 -    buffer_reset(&vs->zlib);
 -
 -    // make the output buffer be the zlib buffer, so we can compress it later
 -    vs->zlib_tmp = vs->output;
 -    vs->output = vs->zlib;
 +      if (vs->has_hextile)
 +          send_framebuffer_update_hextile(vs, x, y, w, h);
 +      else
 +          send_framebuffer_update_raw(vs, x, y, w, h);
  }
  
 -static int vnc_zlib_stop(VncState *vs, int stream_id)
 +static void vnc_copy(DisplayState *ds, int src_x, int src_y, int dst_x, int dst_y, int w, int h)
  {
 -    z_streamp zstream = &vs->zlib_stream[stream_id];
 -    int previous_out;
 -
 -    // switch back to normal output/zlib buffers
 -    vs->zlib = vs->output;
 -    vs->output = vs->zlib_tmp;
 -
 -    // compress the zlib buffer
 -
 -    // initialize the stream
 -    // XXX need one stream per session
 -    if (zstream->opaque != vs) {
 -        int err;
 -
 -        VNC_DEBUG("VNC: initializing zlib stream %d\n", stream_id);
 -        VNC_DEBUG("VNC: opaque = %p | vs = %p\n", zstream->opaque, vs);
 -        zstream->zalloc = Z_NULL;
 -        zstream->zfree = Z_NULL;
 -
 -        err = deflateInit2(zstream, vs->tight_compression, Z_DEFLATED, MAX_WBITS,
 -                           MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY);
 -
 -        if (err != Z_OK) {
 -            fprintf(stderr, "VNC: error initializing zlib\n");
 -            return -1;
 -        }
++    int src, dst;
++    uint8_t *src_row;
++    uint8_t *dst_row;
++    uint8_t *old_row;
++    int y = 0;
++    int pitch = ds->linesize;
 +    VncState *vs = ds->opaque;
 +    int updating_client = 1;
  
 -        zstream->opaque = vs;
++    if (ds->shared_buf) {
++        framebuffer_set_updated(vs, dst_x, dst_y, w, h);
++        return;
+     }
 -    // XXX what to do if tight_compression changed in between?
 +    if (!vs->update_requested ||
 +        src_x < vs->visible_x || src_y < vs->visible_y ||
 +      dst_x < vs->visible_x || dst_y < vs->visible_y ||
 +      (src_x + w) > (vs->visible_x + vs->visible_w) ||
 +      (src_y + h) > (vs->visible_y + vs->visible_h) ||
 +      (dst_x + w) > (vs->visible_x + vs->visible_w) ||
 +      (dst_y + h) > (vs->visible_y + vs->visible_h))
 +      updating_client = 0;
  
 -    // reserve memory in output buffer
 -    buffer_reserve(&vs->output, vs->zlib.offset + 64);
 +    if (updating_client)
-         _vnc_update_client(vs);
++      _vnc_update_client(vs);
 -    // set pointers
 -    zstream->next_in = vs->zlib.buffer;
 -    zstream->avail_in = vs->zlib.offset;
 -    zstream->next_out = vs->output.buffer + vs->output.offset;
 -    zstream->avail_out = vs->output.capacity - vs->output.offset;
 -    zstream->data_type = Z_BINARY;
 -    previous_out = zstream->total_out;
 -
 -    // start encoding
 -    if (deflate(zstream, Z_SYNC_FLUSH) != Z_OK) {
 -        fprintf(stderr, "VNC: error during zlib compression\n");
 -        return -1;
++    if (dst_y > src_y) {
++      y = h - 1;
++      pitch = -pitch;
+     }
 -    vs->output.offset = vs->output.capacity - zstream->avail_out;
 -    return zstream->total_out - previous_out;
 -}
 -
 -static void send_framebuffer_update_zlib(VncState *vs, int x, int y, int w, int h)
 -{
 -    int old_offset, new_offset, bytes_written;
 -
 -    vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_ZLIB);
 -
 -    // remember where we put in the follow-up size
 -    old_offset = vs->output.offset;
 -    vnc_write_s32(vs, 0);
++    src = (ds->linesize * (src_y + y) + vs->depth * src_x);
++    dst = (ds->linesize * (dst_y + y) + vs->depth * dst_x);
 -    // compress the stream
 -    vnc_zlib_start(vs);
 -    send_framebuffer_update_raw(vs, x, y, w, h);
 -    bytes_written = vnc_zlib_stop(vs, 0);
 -
 -    if (bytes_written == -1)
 -        return;
 -
 -    // hack in the size
 -    new_offset = vs->output.offset;
 -    vs->output.offset = old_offset;
 -    vnc_write_u32(vs, bytes_written);
 -    vs->output.offset = new_offset;
 -}
++    src_row = ds->data + src;
++    dst_row = ds->data + dst;
++    old_row = vs->old_data + dst;
 -static void send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
 -{
 -    switch(vs->vnc_encoding) {
 -      case VNC_ENCODING_ZLIB:
 -          send_framebuffer_update_zlib(vs, x, y, w, h);
 -          break;
 -      case VNC_ENCODING_HEXTILE:
 -          vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_HEXTILE);
 -          send_framebuffer_update_hextile(vs, x, y, w, h);
 -          break;
 -      default:
 -          vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_RAW);
 -          send_framebuffer_update_raw(vs, x, y, w, h);
 -          break;
++    for (y = 0; y < h; y++) {
++      memmove(old_row, src_row, w * vs->depth);
++      memmove(dst_row, src_row, w * vs->depth);
++      src_row += pitch;
++      dst_row += pitch;
++      old_row += pitch;
+     }
 -}
 -
 -static void vnc_copy(DisplayState *ds, int src_x, int src_y, int dst_x, int dst_y, int w, int h)
 -{
 -    VncState *vs = ds->opaque;
  
 -    vnc_update_client(vs);
 -
 -    vnc_write_u8(vs, 0);  /* msg id */
 -    vnc_write_u8(vs, 0);
 -    vnc_write_u16(vs, 1); /* number of rects */
 -    vnc_framebuffer_update(vs, dst_x, dst_y, w, h, VNC_ENCODING_COPYRECT);
 -    vnc_write_u16(vs, src_x);
 -    vnc_write_u16(vs, src_y);
 -    vnc_flush(vs);
 +    if (updating_client && vs->csock != -1 && !vs->has_update) {
 +      vnc_write_u8(vs, 0);  /* msg id */
 +      vnc_write_u8(vs, 0);
 +      vnc_write_u16(vs, 1); /* number of rects */
 +      vnc_framebuffer_update(vs, dst_x, dst_y, w, h, 1);
 +      vnc_write_u16(vs, src_x);
 +      vnc_write_u16(vs, src_y);
 +      vnc_flush(vs);
 +        vs->update_requested--;
 +    } else
 +      framebuffer_set_updated(vs, dst_x, dst_y, w, h);
  }
  
 -static int find_dirty_height(VncState *vs, int y, int last_x, int x)
 +static int find_update_height(VncState *vs, int y, int maxy, int last_x, int x)
  {
      int h;
  
      return h;
  }
  
 -static void vnc_update_client(void *opaque)
 +static void _vnc_update_client(void *opaque)
  {
      VncState *vs = opaque;
-     int tile_bytes = vs->serverds.pf.bytes_per_pixel * DP2X(vs, 1);
 +    int64_t now;
 +    int y;
 +    uint8_t *row;
 +    uint8_t *old_row;
 +    uint64_t width_mask;
 +    int n_rectangles;
 +    int saved_offset;
 +    int maxx, maxy;
++    int tile_bytes = vs->depth * DP2X(vs, 1);
 +
 +    if (!vs->update_requested || vs->csock == -1)
 +      return;
 +    while (!is_empty_queue(vs) && vs->update_requested) {
 +        int enc = vs->upqueue.queue_end->enc; 
 +        dequeue_framebuffer_update(vs);
 +        switch (enc) {
 +            case 0x574D5669:
 +                pixel_format_message(vs);
 +                break;
 +            default:
 +                break;
 +        }
 +        vs->update_requested--;
 +    }
 +    if (!vs->update_requested) return;
  
 -    if (vs->need_update && vs->csock != -1) {
 -      int y;
 -      uint8_t *row;
 -      char *old_row;
 -      uint32_t width_mask[VNC_DIRTY_WORDS];
 -      int n_rectangles;
 -      int saved_offset;
 -      int has_dirty = 0;
 -
 -        vga_hw_update();
 -
 -        vnc_set_bits(width_mask, (ds_get_width(vs->ds) / 16), VNC_DIRTY_WORDS);
 -
 -      /* Walk through the dirty map and eliminate tiles that
 -         really aren't dirty */
 -      row = ds_get_data(vs->ds);
 -      old_row = vs->old_data;
 -
 -      for (y = 0; y < ds_get_height(vs->ds); y++) {
 -          if (vnc_and_bits(vs->dirty_row[y], width_mask, VNC_DIRTY_WORDS)) {
 -              int x;
 -              uint8_t *ptr;
 -              char *old_ptr;
 -
 -              ptr = row;
 -              old_ptr = (char*)old_row;
 -
 -              for (x = 0; x < ds_get_width(vs->ds); x += 16) {
 -                  if (memcmp(old_ptr, ptr, 16 * ds_get_bytes_per_pixel(vs->ds)) == 0) {
 -                      vnc_clear_bit(vs->dirty_row[y], (x / 16));
 -                  } else {
 -                      has_dirty = 1;
 -                      memcpy(old_ptr, ptr, 16 * ds_get_bytes_per_pixel(vs->ds));
 -                  }
 +    now = qemu_get_clock(rt_clock);
  
-     if (vs->serverds.width != DP2X(vs, DIRTY_PIXEL_BITS))
-       width_mask = (1ULL << X2DP_UP(vs, ds_get_width(vs->ds))) - 1;
 -                  ptr += 16 * ds_get_bytes_per_pixel(vs->ds);
 -                  old_ptr += 16 * ds_get_bytes_per_pixel(vs->ds);
 -              }
 -          }
++    if (vs->width != DP2X(vs, DIRTY_PIXEL_BITS))
++      width_mask = (1ULL << X2DP_UP(vs, vs->ds->width)) - 1;
 +    else
 +      width_mask = ~(0ULL);
  
 -          row += ds_get_linesize(vs->ds);
 -          old_row += ds_get_linesize(vs->ds);
 -      }
 +    /* Walk through the dirty map and eliminate tiles that really
 +       aren't dirty */
-     row = ds_get_data(vs->ds);
++    row = vs->ds->data;
 +    old_row = vs->old_data;
  
-     for (y = 0; y < ds_get_height(vs->ds); y++) {
 -      if (!has_dirty && !vs->audio_cap) {
 -          qemu_mod_timer(vs->timer, qemu_get_clock(rt_clock) + VNC_REFRESH_INTERVAL);
 -          return;
 -      }
++    for (y = 0; y < vs->ds->height; y++) {
 +      if (vs->dirty_row[y] & width_mask) {
 +          int x;
 +          uint8_t *ptr, *old_ptr;
  
 -      /* Count rectangles */
 -      n_rectangles = 0;
 -      vnc_write_u8(vs, 0);  /* msg id */
 -      vnc_write_u8(vs, 0);
 -      saved_offset = vs->output.offset;
 -      vnc_write_u16(vs, 0);
 +          ptr = row;
 +          old_ptr = old_row;
  
-           for (x = 0; x < X2DP_UP(vs, ds_get_width(vs->ds)); x++) {
 -      for (y = 0; y < vs->serverds.height; y++) {
 -          int x;
 -          int last_x = -1;
 -          for (x = 0; x < vs->serverds.width / 16; x++) {
 -              if (vnc_get_bit(vs->dirty_row[y], x)) {
 -                  if (last_x == -1) {
 -                      last_x = x;
++          for (x = 0; x < X2DP_UP(vs, vs->ds->width); x++) {
 +              if (vs->dirty_row[y] & (1ULL << x)) {
 +                  if (memcmp(old_ptr, ptr, tile_bytes)) {
 +                      vs->has_update = 1;
 +                      vs->update_row[y] |= (1ULL << x);
 +                      memcpy(old_ptr, ptr, tile_bytes);
                    }
 -                  vnc_clear_bit(vs->dirty_row[y], x);
 -              } else {
 -                  if (last_x != -1) {
 -                      int h = find_dirty_height(vs, y, last_x, x);
 -                      send_framebuffer_update(vs, last_x * 16, y, (x - last_x) * 16, h);
 +                  vs->dirty_row[y] &= ~(1ULL << x);
 +              }
 +
 +              ptr += tile_bytes;
 +              old_ptr += tile_bytes;
 +          }
 +      }
 +  
-       row += ds_get_linesize(vs->ds);
-       old_row += ds_get_linesize(vs->ds);
++      row += vs->ds->linesize;
++      old_row += vs->ds->linesize;
 +    }
 +
-     if (!vs->has_update || vs->visible_y >= ds_get_height(vs->ds) ||
-       vs->visible_x >= ds_get_width(vs->ds))
++    if (!vs->has_update || vs->visible_y >= vs->ds->height ||
++      vs->visible_x >= vs->ds->width)
 +      goto backoff;
 +
 +    /* Count rectangles */
 +    n_rectangles = 0;
 +    vnc_write_u8(vs, 0);  /* msg id */
 +    vnc_write_u8(vs, 0);
 +    saved_offset = vs->output.offset;
 +    vnc_write_u16(vs, 0);
 +    
 +    maxy = vs->visible_y + vs->visible_h;
-     if (maxy > ds_get_height(vs->ds))
-       maxy = ds_get_height(vs->ds);
++    if (maxy > vs->ds->height)
++      maxy = vs->ds->height;
 +    maxx = vs->visible_x + vs->visible_w;
-     if (maxx > ds_get_width(vs->ds))
-       maxx = ds_get_width(vs->ds);
++    if (maxx > vs->ds->width)
++      maxx = vs->ds->width;
 +
 +    for (y = vs->visible_y; y < maxy; y++) {
 +      int x;
 +      int last_x = -1;
 +      for (x = X2DP_DOWN(vs, vs->visible_x);
 +           x < X2DP_UP(vs, maxx); x++) {
 +          if (vs->update_row[y] & (1ULL << x)) {
 +              if (last_x == -1)
 +                  last_x = x;
 +              vs->update_row[y] &= ~(1ULL << x);
 +          } else {
 +              if (last_x != -1) {
 +                  int h = find_update_height(vs, y, maxy, last_x, x);
 +                  if (h != 0) {
 +                      send_framebuffer_update(vs, DP2X(vs, last_x), y,
 +                                              DP2X(vs, (x - last_x)), h);
                        n_rectangles++;
                    }
 -                  last_x = -1;
                }
 +              last_x = -1;
            }
 -          if (last_x != -1) {
 -              int h = find_dirty_height(vs, y, last_x, x);
 -              send_framebuffer_update(vs, last_x * 16, y, (x - last_x) * 16, h);
 +      }
 +      if (last_x != -1) {
 +          int h = find_update_height(vs, y, maxy, last_x, x);
 +          if (h != 0) {
 +              send_framebuffer_update(vs, DP2X(vs, last_x), y,
 +                                      DP2X(vs, (x - last_x)), h);
                n_rectangles++;
            }
        }
 -      vs->output.buffer[saved_offset] = (n_rectangles >> 8) & 0xFF;
 -      vs->output.buffer[saved_offset + 1] = n_rectangles & 0xFF;
 -      vnc_flush(vs);
 -
      }
 +    vs->output.buffer[saved_offset] = (n_rectangles >> 8) & 0xFF;
 +    vs->output.buffer[saved_offset + 1] = n_rectangles & 0xFF;
  
 -    if (vs->csock != -1) {
 -        qemu_mod_timer(vs->timer, qemu_get_clock(rt_clock) + VNC_REFRESH_INTERVAL);
 +    if (n_rectangles == 0) {
 +        vs->output.offset = saved_offset - 2;
 +      goto backoff;
 +    } else
 +        vs->update_requested--;
 +
 +    vs->has_update = 0;
 +    vnc_flush(vs);
 +    vs->last_update_time = now;
-     dcl->idle = 0;
++    vs->ds->idle = 0;
 +
 +    vs->timer_interval /= 2;
 +    if (vs->timer_interval < VNC_REFRESH_INTERVAL_BASE)
 +      vs->timer_interval = VNC_REFRESH_INTERVAL_BASE;
 +
 +    return;
 +
 + backoff:
 +    /* No update -> back off a bit */
 +    vs->timer_interval += VNC_REFRESH_INTERVAL_INC;
 +    if (vs->timer_interval > VNC_REFRESH_INTERVAL_MAX) {
 +      vs->timer_interval = VNC_REFRESH_INTERVAL_MAX;
 +      if (now - vs->last_update_time >= VNC_MAX_UPDATE_INTERVAL) {
 +            if (!vs->update_requested) {
-                 dcl->idle = 1;
++                vs->ds->idle = 1;
 +            } else {
 +                /* Send a null update.  If the client is no longer
 +                   interested (e.g. minimised) it'll ignore this, and we
 +                   can stop scanning the buffer until it sends another
 +                   update request. */
 +                /* It turns out that there's a bug in realvncviewer 4.1.2
 +                   which means that if you send a proper null update (with
 +                   no update rectangles), it gets a bit out of sync and
 +                   never sends any further requests, regardless of whether
 +                   it needs one or not.  Fix this by sending a single 1x1
 +                   update rectangle instead. */
 +                vnc_write_u8(vs, 0);
 +                vnc_write_u8(vs, 0);
 +                vnc_write_u16(vs, 1);
 +                send_framebuffer_update(vs, 0, 0, 1, 1);
 +                vnc_flush(vs);
 +                vs->last_update_time = now;
 +                vs->update_requested--;
 +                return;
 +            }
 +      }
      }
 +    qemu_mod_timer(vs->timer, now + vs->timer_interval);
 +    return;
 +}
 +
 +static void vnc_update_client(void *opaque)
 +{
 +    VncState *vs = opaque;
  
 +    vga_hw_update();
 +    _vnc_update_client(vs);
 +}
 +
 +static void vnc_timer_init(VncState *vs)
 +{
 +    if (vs->timer == NULL) {
 +      vs->timer = qemu_new_timer(rt_clock, vnc_update_client, vs);
 +      vs->timer_interval = VNC_REFRESH_INTERVAL_BASE;
 +    }
  }
  
  static int vnc_listen_poll(void *opaque)
@@@ -946,11 -818,10 +992,11 @@@ static int vnc_client_io_error(VncStat
        qemu_set_fd_handler2(vs->csock, NULL, NULL, NULL, NULL);
        closesocket(vs->csock);
        vs->csock = -1;
--      dcl->idle = 1;
++      vs->ds->idle = 1;
        buffer_reset(&vs->input);
        buffer_reset(&vs->output);
 -      vs->need_update = 0;
 +        free_queue(vs);
 +        vs->update_requested = 0;
  #ifdef CONFIG_VNC_TLS
        if (vs->tls_session) {
            gnutls_deinit(vs->tls_session);
@@@ -1161,19 -1031,14 +1207,19 @@@ static void client_cut_text(VncState *v
  
  static void check_pointer_type_change(VncState *vs, int absolute)
  {
 -    if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE) && vs->absolute != absolute) {
 -      vnc_write_u8(vs, 0);
 -      vnc_write_u8(vs, 0);
 -      vnc_write_u16(vs, 1);
 -      vnc_framebuffer_update(vs, absolute, 0,
 -                             ds_get_width(vs->ds), ds_get_height(vs->ds),
 -                               VNC_ENCODING_POINTER_TYPE_CHANGE);
 -      vnc_flush(vs);
 +    if (vs->has_pointer_type_change && vs->absolute != absolute) {
 +        if (vs->update_requested) {
 +          vnc_write_u8(vs, 0);
 +          vnc_write_u8(vs, 0);
 +          vnc_write_u16(vs, 1);
 +          vnc_framebuffer_update(vs, absolute, 0,
-                              ds_get_width(vs->ds), ds_get_height(vs->ds), -257);
++                             vs->ds->width, vs->ds->height, -257);
 +          vnc_flush(vs);
 +            vs->update_requested--;
 +        } else {
 +            enqueue_framebuffer_update(vs, absolute, 0,
-                                ds_get_width(vs->ds), ds_get_height(vs->ds), -257);
++                               vs->ds->width, vs->ds->height, -257);
 +        }
      }
      vs->absolute = absolute;
  }
@@@ -1195,10 -1060,10 +1241,10 @@@ static void pointer_event(VncState *vs
        dz = 1;
  
      if (vs->absolute) {
-         kbd_mouse_event(x * 0x7FFF / (ds_get_width(vs->ds) - 1),
-                         y * 0x7FFF / (ds_get_height(vs->ds) - 1),
 -      kbd_mouse_event(x * 0x7FFF / (ds_get_width(vs->ds) - 1),
 -                      y * 0x7FFF / (ds_get_height(vs->ds) - 1),
++        kbd_mouse_event(x * 0x7FFF / (vs->ds->width - 1),
++                        y * 0x7FFF / (vs->ds->height - 1),
                        dz, buttons);
 -    } else if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE)) {
 +    } else if (vs->has_pointer_type_change) {
        x -= 0x7FFF;
        y -= 0x7FFF;
  
@@@ -1516,114 -1271,136 +1562,116 @@@ static void framebuffer_update_request(
  static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings)
  {
      int i;
 -    unsigned int enc = 0;
  
 -    vnc_zlib_init(vs);
 -    vs->features = 0;
 -    vs->vnc_encoding = 0;
 -    vs->tight_compression = 9;
 -    vs->tight_quality = 9;
 +    vs->has_hextile = 0;
 +    vs->has_resize = 0;
 +    vs->has_pointer_type_change = 0;
 +    vs->has_WMVi = 0;
      vs->absolute = -1;
--    dcl->dpy_copy = NULL;
++    vs->ds->dpy_copy = NULL;
  
      for (i = n_encodings - 1; i >= 0; i--) {
 -        enc = encodings[i];
 -        switch (enc) {
 -        case VNC_ENCODING_RAW:
 -            vs->vnc_encoding = enc;
 -            break;
 -        case VNC_ENCODING_COPYRECT:
 -            dcl->dpy_copy = vnc_copy;
 -            break;
 -        case VNC_ENCODING_HEXTILE:
 -            vs->features |= VNC_FEATURE_HEXTILE_MASK;
 -            vs->vnc_encoding = enc;
 -            break;
 -        case VNC_ENCODING_ZLIB:
 -            vs->features |= VNC_FEATURE_ZLIB_MASK;
 -            vs->vnc_encoding = enc;
 -            break;
 -        case VNC_ENCODING_DESKTOPRESIZE:
 -            vs->features |= VNC_FEATURE_RESIZE_MASK;
 -            break;
 -        case VNC_ENCODING_POINTER_TYPE_CHANGE:
 -            vs->features |= VNC_FEATURE_POINTER_TYPE_CHANGE_MASK;
 -            break;
 -        case VNC_ENCODING_EXT_KEY_EVENT:
 -            send_ext_key_event_ack(vs);
 -            break;
 -        case VNC_ENCODING_AUDIO:
 -            send_ext_audio_ack(vs);
 -            break;
 -        case VNC_ENCODING_WMVi:
 -            vs->features |= VNC_FEATURE_WMVI_MASK;
 -            break;
 -        case VNC_ENCODING_COMPRESSLEVEL0 ... VNC_ENCODING_COMPRESSLEVEL0 + 9:
 -            vs->tight_compression = (enc & 0x0F);
 -            break;
 -        case VNC_ENCODING_QUALITYLEVEL0 ... VNC_ENCODING_QUALITYLEVEL0 + 9:
 -            vs->tight_quality = (enc & 0x0F);
 -            break;
 -        default:
 -            VNC_DEBUG("Unknown encoding: %d (0x%.8x): %d\n", i, enc, enc);
 -            break;
 -        }
 +      switch (encodings[i]) {
 +      case 0: /* Raw */
 +          vs->has_hextile = 0;
 +          break;
 +      case 1: /* CopyRect */
-           dcl->dpy_copy = vnc_copy;
++          vs->ds->dpy_copy = vnc_copy;
 +          break;
 +      case 5: /* Hextile */
 +          vs->has_hextile = 1;
 +          break;
 +      case -223: /* DesktopResize */
 +          vs->has_resize = 1;
 +          break;
 +      case -257:
 +          vs->has_pointer_type_change = 1;
 +          break;
 +        case 0x574D5669:
 +            vs->has_WMVi = 1;
 +      default:
 +          break;
 +      }
      }
  
      check_pointer_type_change(vs, kbd_mouse_is_absolute());
  }
  
--static void set_pixel_conversion(VncState *vs)
--{
--    if ((vs->clientds.flags & QEMU_BIG_ENDIAN_FLAG) ==
--        (vs->ds->surface->flags & QEMU_BIG_ENDIAN_FLAG) && 
--        !memcmp(&(vs->clientds.pf), &(vs->ds->surface->pf), sizeof(PixelFormat))) {
--        vs->write_pixels = vnc_write_pixels_copy;
--        switch (vs->ds->surface->pf.bits_per_pixel) {
--            case 8:
--                vs->send_hextile_tile = send_hextile_tile_8;
--                break;
--            case 16:
--                vs->send_hextile_tile = send_hextile_tile_16;
--                break;
--            case 32:
--                vs->send_hextile_tile = send_hextile_tile_32;
--                break;
--        }
--    } else {
--        vs->write_pixels = vnc_write_pixels_generic;
--        switch (vs->ds->surface->pf.bits_per_pixel) {
--            case 8:
--                vs->send_hextile_tile = send_hextile_tile_generic_8;
--                break;
--            case 16:
--                vs->send_hextile_tile = send_hextile_tile_generic_16;
--                break;
--            case 32:
--                vs->send_hextile_tile = send_hextile_tile_generic_32;
--                break;
--        }
--    }
--}
--
  static void set_pixel_format(VncState *vs,
                             int bits_per_pixel, int depth,
                             int big_endian_flag, int true_color_flag,
                             int red_max, int green_max, int blue_max,
                             int red_shift, int green_shift, int blue_shift)
  {
++    int host_big_endian_flag;
++
++#ifdef WORDS_BIGENDIAN
++    host_big_endian_flag = 1;
++#else
++    host_big_endian_flag = 0;
++#endif
      if (!true_color_flag) {
++    fail:
        vnc_client_error(vs);
          return;
      }
--
--    vs->clientds = vs->serverds;
--    vs->clientds.pf.rmax = red_max;
--    count_bits(vs->clientds.pf.rbits, red_max);
--    vs->clientds.pf.rshift = red_shift;
--    vs->clientds.pf.rmask = red_max << red_shift;
--    vs->clientds.pf.gmax = green_max;
--    count_bits(vs->clientds.pf.gbits, green_max);
--    vs->clientds.pf.gshift = green_shift;
--    vs->clientds.pf.gmask = green_max << green_shift;
--    vs->clientds.pf.bmax = blue_max;
--    count_bits(vs->clientds.pf.bbits, blue_max);
--    vs->clientds.pf.bshift = blue_shift;
--    vs->clientds.pf.bmask = blue_max << blue_shift;
--    vs->clientds.pf.bits_per_pixel = bits_per_pixel;
--    vs->clientds.pf.bytes_per_pixel = bits_per_pixel / 8;
--    vs->clientds.pf.depth = bits_per_pixel == 32 ? 24 : bits_per_pixel;
--    vs->clientds.flags = big_endian_flag ? QEMU_BIG_ENDIAN_FLAG : 0x00;
--
--    set_pixel_conversion(vs);
--
--    vga_hw_invalidate();
--    vga_hw_update();
++    if (bits_per_pixel == 32 &&
++        bits_per_pixel == vs->depth * 8 && 
++        host_big_endian_flag == big_endian_flag &&
++        red_max == 0xff && green_max == 0xff && blue_max == 0xff &&
++        red_shift == 16 && green_shift == 8 && blue_shift == 0) {
++        vs->write_pixels = vnc_write_pixels_copy;
++        vs->send_hextile_tile = send_hextile_tile_32;
++    } else 
++    if (bits_per_pixel == 16 &&
++        bits_per_pixel == vs->depth * 8 && 
++        host_big_endian_flag == big_endian_flag &&
++        red_max == 31 && green_max == 63 && blue_max == 31 &&
++        red_shift == 11 && green_shift == 5 && blue_shift == 0) {
++        vs->write_pixels = vnc_write_pixels_copy;
++        vs->send_hextile_tile = send_hextile_tile_16;
++    } else 
++    if (bits_per_pixel == 8 && 
++        bits_per_pixel == vs->depth * 8 &&
++        red_max == 7 && green_max == 7 && blue_max == 3 &&
++        red_shift == 5 && green_shift == 2 && blue_shift == 0) {
++        vs->depth = 1;
++        vs->write_pixels = vnc_write_pixels_copy;
++        vs->send_hextile_tile = send_hextile_tile_8;
++    } else 
++    {
++        /* generic and slower case */
++        if (bits_per_pixel != 8 &&
++            bits_per_pixel != 16 &&
++            bits_per_pixel != 32)
++            goto fail;
++        if (vs->depth == 4) {
++            vs->send_hextile_tile = send_hextile_tile_generic_32;
++        } else if (vs->depth == 2) {
++            vs->send_hextile_tile = send_hextile_tile_generic_16;
++        } else {
++            vs->send_hextile_tile = send_hextile_tile_generic_8;
++        }
++            
++        vs->pix_big_endian = big_endian_flag;
++        vs->write_pixels = vnc_write_pixels_generic;
++    }
++ 
++    vs->red_shift = red_shift;
++    vs->red_max = red_max;
++    vs->green_shift = green_shift;
++    vs->green_max = green_max;
++    vs->blue_shift = blue_shift;
++    vs->blue_max = blue_max;
++    vs->pix_bpp = bits_per_pixel / 8;
  }
  
  static void pixel_format_message (VncState *vs) {
      char pad[3] = { 0, 0, 0 };
  
--    vnc_write_u8(vs, vs->ds->surface->pf.bits_per_pixel); /* bits-per-pixel */
--    vnc_write_u8(vs, vs->ds->surface->pf.depth); /* depth */
++    vnc_write_u8(vs, vs->depth * 8); /* bits-per-pixel */
++    if (vs->depth == 4) vnc_write_u8(vs, 24); /* depth */
++    else vnc_write_u8(vs, vs->depth * 8); /* depth */
  
  #ifdef WORDS_BIGENDIAN
      vnc_write_u8(vs, 1);             /* big-endian-flag */
      vnc_write_u8(vs, 0);             /* big-endian-flag */
  #endif
      vnc_write_u8(vs, 1);             /* true-color-flag */
--    vnc_write_u16(vs, vs->ds->surface->pf.rmax);     /* red-max */
--    vnc_write_u16(vs, vs->ds->surface->pf.gmax);     /* green-max */
--    vnc_write_u16(vs, vs->ds->surface->pf.bmax);     /* blue-max */
--    vnc_write_u8(vs, vs->ds->surface->pf.rshift);    /* red-shift */
--    vnc_write_u8(vs, vs->ds->surface->pf.gshift);    /* green-shift */
--    vnc_write_u8(vs, vs->ds->surface->pf.bshift);    /* blue-shift */
--    if (vs->ds->surface->pf.bits_per_pixel == 32)
++    if (vs->depth == 4) {
++        vnc_write_u16(vs, 0xFF);     /* red-max */
++        vnc_write_u16(vs, 0xFF);     /* green-max */
++        vnc_write_u16(vs, 0xFF);     /* blue-max */
++        vnc_write_u8(vs, 16);        /* red-shift */
++        vnc_write_u8(vs, 8);         /* green-shift */
++        vnc_write_u8(vs, 0);         /* blue-shift */
          vs->send_hextile_tile = send_hextile_tile_32;
--    else if (vs->ds->surface->pf.bits_per_pixel == 16)
++    } else if (vs->depth == 2) {
++        vnc_write_u16(vs, 31);       /* red-max */
++        vnc_write_u16(vs, 63);       /* green-max */
++        vnc_write_u16(vs, 31);       /* blue-max */
++        vnc_write_u8(vs, 11);        /* red-shift */
++        vnc_write_u8(vs, 5);         /* green-shift */
++        vnc_write_u8(vs, 0);         /* blue-shift */
          vs->send_hextile_tile = send_hextile_tile_16;
--    else if (vs->ds->surface->pf.bits_per_pixel == 8)
++    } else if (vs->depth == 1) {
++        /* XXX: change QEMU pixel 8 bit pixel format to match the VNC one ? */
++        vnc_write_u16(vs, 7);        /* red-max */
++        vnc_write_u16(vs, 7);        /* green-max */
++        vnc_write_u16(vs, 3);        /* blue-max */
++        vnc_write_u8(vs, 5);         /* red-shift */
++        vnc_write_u8(vs, 2);         /* green-shift */
++        vnc_write_u8(vs, 0);         /* blue-shift */
          vs->send_hextile_tile = send_hextile_tile_8;
--    vs->clientds = *(vs->ds->surface);
-     vs->clientds.flags &= ~QEMU_ALLOCATED_FLAG;
 -    vs->clientds.flags |= ~QEMU_ALLOCATED_FLAG;
++    }
++    vs->red_max = vs->red_max1;
++    vs->green_max = vs->green_max1;
++    vs->blue_max = vs->blue_max1;
++    vs->red_shift = vs->red_shift1;
++    vs->green_shift = vs->green_shift1;
++    vs->blue_shift = vs->blue_shift1;
++    vs->pix_bpp = vs->depth * 8;
      vs->write_pixels = vnc_write_pixels_copy;
--
++        
      vnc_write(vs, pad, 3);           /* padding */
  }
  
--static void vnc_dpy_setdata(DisplayState *ds)
++static void vnc_dpy_setdata(DisplayState *ds, void *pixels)
  {
--    /* We don't have to do anything */
++    ds->data = pixels;
  }
  
--static void vnc_colordepth(DisplayState *ds)
++static void vnc_colourdepth(DisplayState *ds, int depth)
  {
++    int host_big_endian_flag;
      struct VncState *vs = ds->opaque;
  
 -    if (vs->csock != -1 && vnc_has_feature(vs, VNC_FEATURE_WMVI)) {
++    switch (depth) {
++        case 24:
++            ds->shared_buf = 0;
++            if (ds->depth == 32) return;
++            depth = 32;
++            break;
++        case 8:
++        case 0:
++            ds->shared_buf = 0;
++            return;
++        default:
++            ds->shared_buf = 1;
++            break;
++    }
++
++#ifdef WORDS_BIGENDIAN
++    host_big_endian_flag = 1;
++#else
++    host_big_endian_flag = 0;
++#endif   
++    
++    switch (depth) {
++        case 8:
++            vs->depth = depth / 8;
++            vs->red_max1 = 7;
++            vs->green_max1 = 7;
++            vs->blue_max1 = 3;
++            vs->red_shift1 = 5;
++            vs->green_shift1 = 2;
++            vs->blue_shift1 = 0;
++            break;
++        case 16:
++            vs->depth = depth / 8;
++            vs->red_max1 = 31;
++            vs->green_max1 = 63;
++            vs->blue_max1 = 31;
++            vs->red_shift1 = 11;
++            vs->green_shift1 = 5;
++            vs->blue_shift1 = 0;
++            break;
++        case 32:
++            vs->depth = 4;
++            vs->red_max1 = 255;
++            vs->green_max1 = 255;
++            vs->blue_max1 = 255;
++            vs->red_shift1 = 16;
++            vs->green_shift1 = 8;
++            vs->blue_shift1 = 0;
++            break;
++        default:
++            return;
++    }
 +    if (vs->switchbpp) {
 +        vnc_client_error(vs);
 +    } else if (vs->csock != -1 && vs->has_WMVi) {
          /* Sending a WMVi message to notify the client*/
 -        vnc_write_u8(vs, 0);  /* msg id */
 -        vnc_write_u8(vs, 0);
 -        vnc_write_u16(vs, 1); /* number of rects */
 -        vnc_framebuffer_update(vs, 0, 0, ds_get_width(ds), ds_get_height(ds),
 -                               VNC_ENCODING_WMVi);
 -        pixel_format_message(vs);
 -        vnc_flush(vs);
 +        if (vs->update_requested) {
 +            vnc_write_u8(vs, 0);  /* msg id */
 +            vnc_write_u8(vs, 0);
 +            vnc_write_u16(vs, 1); /* number of rects */
-             vnc_framebuffer_update(vs, 0, 0, ds_get_width(ds), ds_get_height(ds), 0x574D5669);
++            vnc_framebuffer_update(vs, 0, 0, ds->width, ds->height, 0x574D5669);
 +            pixel_format_message(vs);
 +            vnc_flush(vs);
 +            vs->update_requested--;
 +        } else {
-             enqueue_framebuffer_update(vs, 0, 0, ds_get_width(ds), ds_get_height(ds), 0x574D5669);
++            enqueue_framebuffer_update(vs, 0, 0, ds->width, ds->height, 0x574D5669);
 +        }
      } else {
--        set_pixel_conversion(vs);
++        if (vs->pix_bpp == 4 && vs->depth == 4 &&
++            host_big_endian_flag == vs->pix_big_endian &&
++            vs->red_max == 0xff && vs->green_max == 0xff && vs->blue_max == 0xff &&
++            vs->red_shift == 16 && vs->green_shift == 8 && vs->blue_shift == 0) {
++            vs->write_pixels = vnc_write_pixels_copy;
++            vs->send_hextile_tile = send_hextile_tile_32;
++        } else if (vs->pix_bpp == 2 && vs->depth == 2 &&
++            host_big_endian_flag == vs->pix_big_endian &&
++            vs->red_max == 31 && vs->green_max == 63 && vs->blue_max == 31 &&
++            vs->red_shift == 11 && vs->green_shift == 5 && vs->blue_shift == 0) {
++            vs->write_pixels = vnc_write_pixels_copy;
++            vs->send_hextile_tile = send_hextile_tile_16;
++        } else if (vs->pix_bpp == 1 && vs->depth == 1 &&
++            host_big_endian_flag == vs->pix_big_endian &&
++            vs->red_max == 7 && vs->green_max == 7 && vs->blue_max == 3 &&
++            vs->red_shift == 5 && vs->green_shift == 2 && vs->blue_shift == 0) {
++            vs->write_pixels = vnc_write_pixels_copy;
++            vs->send_hextile_tile = send_hextile_tile_8;
++        } else {
++            if (vs->depth == 4) {
++                vs->send_hextile_tile = send_hextile_tile_generic_32;
++            } else if (vs->depth == 2) {
++                vs->send_hextile_tile = send_hextile_tile_generic_16;
++            } else {
++                vs->send_hextile_tile = send_hextile_tile_generic_8;
++            }
++            vs->write_pixels = vnc_write_pixels_generic;
++        }
      }
  }
  
@@@ -1765,12 -1588,11 +1912,14 @@@ static int protocol_client_msg(VncStat
  
  static int protocol_client_init(VncState *vs, uint8_t *data, size_t len)
  {
 -    char buf[1024];
 -    int size;
 +    size_t l;
  
 -    vnc_write_u16(vs, ds_get_width(vs->ds));
 -    vnc_write_u16(vs, ds_get_height(vs->ds));
 +    vga_hw_update();
 +
-     vnc_write_u16(vs, ds_get_width(vs->ds));
-     vnc_write_u16(vs, ds_get_height(vs->ds));
++    vs->width = vs->ds->width;
++    vs->height = vs->ds->height;
++    vnc_write_u16(vs, vs->ds->width);
++    vnc_write_u16(vs, vs->ds->height);
  
      pixel_format_message(vs);
  
@@@ -2386,19 -2227,7 +2535,19 @@@ static void vnc_listen_read(void *opaqu
  
      vs->csock = accept(vs->lsock, (struct sockaddr *)&addr, &addrlen);
      if (vs->csock != -1) {
 -        vnc_connect(vs);
 +      VNC_DEBUG("New client on socket %d\n", vs->csock);
-       dcl->idle = 0;
++      vs->ds->idle = 0;
 +        socket_set_nonblock(vs->csock);
 +      qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, opaque);
 +      vnc_write(vs, "RFB 003.008\n", 12);
 +      vnc_flush(vs);
 +      vnc_read_when(vs, protocol_version, 12);
-       framebuffer_set_updated(vs, 0, 0, ds_get_width(vs->ds), ds_get_height(vs->ds));
++      framebuffer_set_updated(vs, 0, 0, vs->ds->width, vs->ds->height);
 +      vs->has_resize = 0;
 +      vs->has_hextile = 0;
 +        vs->update_requested = 0;
-       dcl->dpy_copy = NULL;
++      vs->ds->dpy_copy = NULL;
 +      vnc_timer_init(vs);
      }
  }
  
@@@ -2409,12 -2236,12 +2558,11 @@@ void vnc_display_init(DisplayState *ds
      VncState *vs;
  
      vs = qemu_mallocz(sizeof(VncState));
--    dcl = qemu_mallocz(sizeof(DisplayChangeListener));
--    if (!vs || !dcl)
++    if (!vs)
        exit(1);
  
      ds->opaque = vs;
--    dcl->idle = 1;
++    ds->idle = 1;
      vnc_state = vs;
      vs->display = NULL;
      vs->password = NULL;
  
      vs->ds = ds;
  
 -    if (keyboard_layout)
 -        vs->kbd_layout = init_keyboard_layout(keyboard_layout);
 -    else
 -        vs->kbd_layout = init_keyboard_layout("en-us");
 +    if (!keyboard_layout)
 +      keyboard_layout = "en-us";
  
 +    vs->kbd_layout = init_keyboard_layout(keyboard_layout);
      if (!vs->kbd_layout)
        exit(1);
 +    vs->modifiers_state[0x45] = 1; /* NumLock on - on boot */
  
 -    vs->timer = qemu_new_timer(rt_clock, vnc_update_client, vs);
 -
--    dcl->dpy_update = vnc_dpy_update;
--    dcl->dpy_resize = vnc_dpy_resize;
--    dcl->dpy_setdata = vnc_dpy_setdata;
--    dcl->dpy_refresh = NULL;
--    register_displaychangelistener(ds, dcl);
++    vs->ds->data = NULL;
++    vs->ds->dpy_update = vnc_dpy_update;
++    vs->ds->dpy_resize = vnc_dpy_resize;
++    vs->ds->dpy_setdata = vnc_dpy_setdata;
++    vs->ds->dpy_resize_shared = vnc_dpy_resize_shared;
++    vs->ds->dpy_refresh = NULL;
 -    vs->as.freq = 44100;
 -    vs->as.nchannels = 2;
 -    vs->as.fmt = AUD_FMT_S16;
 -    vs->as.endianness = 0;
++    vs->ds->width = 640;
++    vs->ds->height = 400;
++    vs->ds->linesize = 640 * 4;
++    vnc_dpy_resize_shared(ds, ds->width, ds->height, 24, ds->linesize, NULL);
  }
  
  #ifdef CONFIG_VNC_TLS
diff --cc vnchextile.h
Simple merge
diff --cc xen-vl-extra.c
index d01bf4715b8c56175945e0e0931901189debb9af,0000000000000000000000000000000000000000..2bb32eb2d9d1147cef37965072b2c15f5c31d34b
mode 100644,000000..100644
--- /dev/null
@@@ -1,133 -1,0 +1,151 @@@
 +/*
 + * We #include this from vl.c.
 + *
 + * This is a bit yucky, but it means that the line numbers and other
 + * textual differences in vl.c remain small.
 + */
 +/* There is no need for multiple-inclusion protection since
 + * there is only one place where this file is included. */
 +
 +#include "qemu-xen.h"
 +
++
++/* Max number of PCI emulation */
++#define MAX_PCI_EMULATION 32
++
++int restore;
++#ifdef CONFIG_OPENGL
++int opengl_enabled = 1;
++#else
++int opengl_enabled = 0;
++#endif
++static const char *direct_pci;
++static int nb_pci_emulation = 0;
++static char pci_emulation_config_text[MAX_PCI_EMULATION][256];
++PCI_EMULATION_INFO *PciEmulationInfoHead = NULL;
++
++int vncunused;
++
++
 +/* We use simpler state save/load functions for Xen */
 +
 +void do_savevm(const char *name)
 +{
 +    QEMUFile *f;
 +    int saved_vm_running, ret;
 +
 +    f = qemu_fopen(name, "wb");
 +    
 +    /* ??? Should this occur after vm_stop?  */
 +    qemu_aio_flush();
 +
 +    saved_vm_running = vm_running;
 +    vm_stop(0);
 +
 +    if (!f) {
 +        fprintf(logfile, "Failed to open savevm file '%s'\n", name);
 +        goto the_end;
 +    }
 +    
 +    ret = qemu_savevm_state(f);
 +    qemu_fclose(f);
 +
 +    if (ret < 0)
 +        fprintf(logfile, "Error %d while writing VM to savevm file '%s'\n",
 +                ret, name);
 +
 + the_end:
 +    if (saved_vm_running)
 +        vm_start();
 +
 +    return;
 +}
 +void do_loadvm(const char *name)
 +{
 +    QEMUFile *f;
 +    int saved_vm_running, ret;
 +
 +    /* Flush all IO requests so they don't interfere with the new state.  */
 +    qemu_aio_flush();
 +
 +    saved_vm_running = vm_running;
 +    vm_stop(0);
 +
 +    /* restore the VM state */
 +    f = qemu_fopen(name, "rb");
 +    if (!f) {
 +        fprintf(logfile, "Could not open VM state file\n");
 +        goto the_end;
 +    }
 +
 +    ret = qemu_loadvm_state(f);
 +    qemu_fclose(f);
 +    if (ret < 0) {
 +        fprintf(logfile, "Error %d while loading savevm file '%s'\n",
 +                ret, name);
 +        goto the_end; 
 +    }
 +
 +#if 0 
 +    /* del tmp file */
 +    if (unlink(name) == -1)
 +        fprintf(stderr, "delete tmp qemu state file failed.\n");
 +#endif
 +
 +
 + the_end:
 +    if (saved_vm_running)
 +        vm_start();
 +}
 +
 +struct qemu_alarm_timer;
 +static int unix_start_timer(struct qemu_alarm_timer *t) { return 0; }
 +static void unix_stop_timer(struct qemu_alarm_timer *t) { }
 +
 +#ifdef CONFIG_STUBDOM
 +#include <netfront.h>
 +static int tap_open(char *ifname, int ifname_size)
 +{
 +    char nodename[64];
 +    static int num = 1; // 0 is for our own TCP/IP networking
 +    snprintf(nodename, sizeof(nodename), "device/vif/%d", num++);
 +    return netfront_tap_open(nodename);
 +}
 +
 +#undef DEFAULT_NETWORK_SCRIPT
 +#define DEFAULT_NETWORK_SCRIPT ""
 +#undef DEFAULT_NETWORK_DOWN_SCRIPT
 +#define DEFAULT_NETWORK_DOWN_SCRIPT ""
 +#endif
 +
 +#ifdef CONFIG_PASSTHROUGH
 +void do_pci_del(char *devname)
 +{
 +    int pci_slot;
 +    pci_slot = bdf_to_slot(devname);
 +
 +    acpi_php_del(pci_slot);
 +}
 +
 +void do_pci_add(char *devname)
 +{
 +    int pci_slot;
 +
 +    pci_slot = insert_to_pci_slot(devname);
 +
 +    acpi_php_add(pci_slot);
 +}
 +
 +static int pci_emulation_add(char *config_text)
 +{
 +    PCI_EMULATION_INFO *new;
 +    if ((new = qemu_mallocz(sizeof(PCI_EMULATION_INFO))) == NULL) {
 +        return -1;
 +    }
 +    parse_pci_emulation_info(config_text, new);
 +    new->next = PciEmulationInfoHead;
 +    PciEmulationInfoHead = new;
 +    return 0;
 +}
 +
 +#endif