diff --git a/hw/display/goldfish_fb.c b/hw/display/goldfish_fb.c
new file mode 100644
index 0000000..16450b3
--- /dev/null
+++ b/hw/display/goldfish_fb.c
@@ -0,0 +1,675 @@
+/* Copyright (C) 2007-2008 The Android Open Source Project
+**
+** This software is licensed under the terms of the GNU General Public
+** License version 2, as published by the Free Software Foundation, and
+** may be copied, distributed, and modified under those terms.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU General Public License for more details.
+*/
+#include "qemu_file.h"
+#include "android/android.h"
+#include "android/utils/debug.h"
+#include "android/utils/duff.h"
+#include "goldfish_device.h"
+#include "console.h"
+
+/* These values *must* match the platform definitions found under
+ * hardware/libhardware/include/hardware/hardware.h
+ */
+enum {
+    HAL_PIXEL_FORMAT_RGBA_8888          = 1,
+    HAL_PIXEL_FORMAT_RGBX_8888          = 2,
+    HAL_PIXEL_FORMAT_RGB_888            = 3,
+    HAL_PIXEL_FORMAT_RGB_565            = 4,
+    HAL_PIXEL_FORMAT_BGRA_8888          = 5,
+    HAL_PIXEL_FORMAT_RGBA_5551          = 6,
+    HAL_PIXEL_FORMAT_RGBA_4444          = 7,
+};
+
+enum {
+    FB_GET_WIDTH        = 0x00,
+    FB_GET_HEIGHT       = 0x04,
+    FB_INT_STATUS       = 0x08,
+    FB_INT_ENABLE       = 0x0c,
+    FB_SET_BASE         = 0x10,
+    FB_SET_ROTATION     = 0x14,
+    FB_SET_BLANK        = 0x18,
+    FB_GET_PHYS_WIDTH   = 0x1c,
+    FB_GET_PHYS_HEIGHT  = 0x20,
+    FB_GET_FORMAT       = 0x24,
+
+    FB_INT_VSYNC             = 1U << 0,
+    FB_INT_BASE_UPDATE_DONE  = 1U << 1
+};
+
+struct goldfish_fb_state {
+    struct goldfish_device dev;
+    DisplayState*  ds;
+    int      pixel_format;
+    int      bytes_per_pixel;
+    uint32_t fb_base;
+    uint32_t base_valid : 1;
+    uint32_t need_update : 1;
+    uint32_t need_int : 1;
+    uint32_t set_rotation : 2;
+    uint32_t blank : 1;
+    uint32_t int_status;
+    uint32_t int_enable;
+    int      rotation;   /* 0, 1, 2 or 3 */
+    int      dpi;
+};
+
+#define  GOLDFISH_FB_SAVE_VERSION  2
+
+static void goldfish_fb_save(QEMUFile*  f, void*  opaque)
+{
+    struct goldfish_fb_state*  s = opaque;
+
+    DisplayState*  ds = s->ds;
+
+    qemu_put_be32(f, ds->surface->width);
+    qemu_put_be32(f, ds->surface->height);
+    qemu_put_be32(f, ds->surface->linesize);
+    qemu_put_byte(f, 0);
+
+    qemu_put_be32(f, s->fb_base);
+    qemu_put_byte(f, s->base_valid);
+    qemu_put_byte(f, s->need_update);
+    qemu_put_byte(f, s->need_int);
+    qemu_put_byte(f, s->set_rotation);
+    qemu_put_byte(f, s->blank);
+    qemu_put_be32(f, s->int_status);
+    qemu_put_be32(f, s->int_enable);
+    qemu_put_be32(f, s->rotation);
+    qemu_put_be32(f, s->dpi);
+}
+
+static int  goldfish_fb_load(QEMUFile*  f, void*  opaque, int  version_id)
+{
+    struct goldfish_fb_state*  s   = opaque;
+    int                        ret = -1;
+    int                        ds_w, ds_h, ds_pitch, ds_rot;
+
+    if (version_id != GOLDFISH_FB_SAVE_VERSION)
+        goto Exit;
+
+    ds_w     = qemu_get_be32(f);
+    ds_h     = qemu_get_be32(f);
+    ds_pitch = qemu_get_be32(f);
+    ds_rot   = qemu_get_byte(f);
+
+    DisplayState*  ds = s->ds;
+
+    if (ds->surface->width != ds_w ||
+        ds->surface->height != ds_h ||
+        ds->surface->linesize != ds_pitch ||
+        ds_rot != 0)
+    {
+        /* XXX: We should be able to force a resize/rotation from here ? */
+        fprintf(stderr, "%s: framebuffer dimensions mismatch\n", __FUNCTION__);
+        goto Exit;
+    }
+
+    s->fb_base      = qemu_get_be32(f);
+    s->base_valid   = qemu_get_byte(f);
+    s->need_update  = qemu_get_byte(f);
+    s->need_int     = qemu_get_byte(f);
+    s->set_rotation = qemu_get_byte(f);
+    s->blank        = qemu_get_byte(f);
+    s->int_status   = qemu_get_be32(f);
+    s->int_enable   = qemu_get_be32(f);
+    s->rotation     = qemu_get_be32(f);
+    s->dpi          = qemu_get_be32(f);
+
+    /* force a refresh */
+    s->need_update = 1;
+
+    ret = 0;
+Exit:
+    return ret;
+}
+
+/* Type used to record a mapping from display surface pixel format to
+ * HAL pixel format */
+typedef struct {
+    int    pixel_format; /* HAL pixel format */
+    uint8_t bits;
+    uint8_t bytes;
+    uint32_t rmask, gmask, bmask, amask;
+} FbConfig;
+
+
+/* Return the pixel format of the current framebuffer, based on
+ * the current display surface's pixel format.
+ *
+ * Note that you should not call this function from the device initialization
+ * function, because the display surface will change format before the kernel
+ * start.
+ */
+static int goldfish_fb_get_pixel_format(struct goldfish_fb_state *s)
+{
+    if (s->pixel_format >= 0) {
+        return s->pixel_format;
+    }
+    static const FbConfig fb_configs[] = {
+        { HAL_PIXEL_FORMAT_RGB_565, 16, 2, 0xf800, 0x7e0, 0x1f, 0x0 },
+        { HAL_PIXEL_FORMAT_RGBX_8888, 32, 4, 0xff0000, 0xff00, 0xff, 0x0 },
+        { HAL_PIXEL_FORMAT_RGBA_8888, 32, 4, 0xff0000, 0xff00, 0xff, 0xff000000 },
+        { -1, }
+    };
+
+    /* Determine HAL pixel format value based on s->ds */
+    struct PixelFormat* pf = &s->ds->surface->pf;
+    if (VERBOSE_CHECK(init)) {
+        printf("%s:%d: display surface,pixel format:\n", __FUNCTION__, __LINE__);
+        printf("  bits/pixel:  %d\n", pf->bits_per_pixel);
+        printf("  bytes/pixel: %d\n", pf->bytes_per_pixel);
+        printf("  depth:       %d\n", pf->depth);
+        printf("  red:         bits=%d mask=0x%x shift=%d max=0x%x\n",
+            pf->rbits, pf->rmask, pf->rshift, pf->rmax);
+        printf("  green:       bits=%d mask=0x%x shift=%d max=0x%x\n",
+            pf->gbits, pf->gmask, pf->gshift, pf->gmax);
+        printf("  blue:        bits=%d mask=0x%x shift=%d max=0x%x\n",
+            pf->bbits, pf->bmask, pf->bshift, pf->bmax);
+        printf("  alpha:       bits=%d mask=0x%x shift=%d max=0x%x\n",
+            pf->abits, pf->amask, pf->ashift, pf->amax);
+    }
+
+    s->bytes_per_pixel = pf->bytes_per_pixel;
+    int nn;
+    for (nn = 0; fb_configs[nn].pixel_format >= 0; nn++) {
+        const FbConfig* fbc = &fb_configs[nn];
+        if (pf->bits_per_pixel == fbc->bits &&
+            pf->bytes_per_pixel == fbc->bytes &&
+            pf->rmask == fbc->rmask &&
+            pf->gmask == fbc->gmask &&
+            pf->bmask == fbc->bmask &&
+            pf->amask == fbc->amask) {
+            /* We found it */
+            s->pixel_format = fbc->pixel_format;
+            return s->pixel_format;
+        }
+    }
+    fprintf(stderr, "%s:%d: Unsupported display pixel format (depth=%d, bytespp=%d, bitspp=%d)\n",
+                __FUNCTION__, __LINE__,
+                pf->depth,
+                pf->bytes_per_pixel,
+                pf->bits_per_pixel);
+    exit(1);
+    return -1;
+}
+
+static int goldfish_fb_get_bytes_per_pixel(struct goldfish_fb_state *s)
+{
+    if (s->pixel_format < 0) {
+        (void) goldfish_fb_get_pixel_format(s);
+    }
+    return s->bytes_per_pixel;
+}
+
+static int
+pixels_to_mm(int  pixels, int dpi)
+{
+    /* dpi = dots / inch
+    ** inch = dots / dpi
+    ** mm / 25.4 = dots / dpi
+    ** mm = (dots * 25.4)/dpi
+    */
+    return (int)(0.5 + 25.4 * pixels  / dpi);
+}
+
+
+#define  STATS  0
+
+#if STATS
+static int   stats_counter;
+static long  stats_total;
+static int   stats_full_updates;
+static long  stats_total_full_updates;
+#endif
+
+/* This structure is used to hold the inputs for
+ * compute_fb_update_rect_linear below.
+ * This corresponds to the source framebuffer and destination
+ * surface pixel buffers.
+ */
+typedef struct {
+    int            width;
+    int            height;
+    int            bytes_per_pixel;
+    const uint8_t* src_pixels;
+    int            src_pitch;
+    uint8_t*       dst_pixels;
+    int            dst_pitch;
+} FbUpdateState;
+
+/* This structure is used to hold the outputs for
+ * compute_fb_update_rect_linear below.
+ * This corresponds to the smalled bounding rectangle of the
+ * latest framebuffer update.
+ */
+typedef struct {
+    int xmin, ymin, xmax, ymax;
+} FbUpdateRect;
+
+/* Determine the smallest bounding rectangle of pixels which changed
+ * between the source (framebuffer) and destination (surface) pixel
+ * buffers.
+ *
+ * Return 0 if there was no change, otherwise, populate '*rect'
+ * and return 1.
+ *
+ * If 'dirty_base' is not 0, it is a physical address that will be
+ * used to speed-up the check using the VGA dirty bits. In practice
+ * this is only used if your kernel driver does not implement.
+ *
+ * This function assumes that the framebuffers are in linear memory.
+ * This may change later when we want to support larger framebuffers
+ * that exceed the max DMA aperture size though.
+ */
+static int
+compute_fb_update_rect_linear(FbUpdateState*  fbs,
+                              uint32_t        dirty_base,
+                              FbUpdateRect*   rect)
+{
+    int  yy;
+    int  width = fbs->width;
+    const uint8_t* src_line = fbs->src_pixels;
+    uint8_t*       dst_line = fbs->dst_pixels;
+    uint32_t       dirty_addr = dirty_base;
+    rect->xmin = rect->ymin = INT_MAX;
+    rect->xmax = rect->ymax = INT_MIN;
+    for (yy = 0; yy < fbs->height; yy++) {
+        int xx1, xx2;
+        /* If dirty_addr is != 0, then use it as a physical address to
+         * use the VGA dirty bits table to speed up the detection of
+         * changed pixels.
+         */
+        if (dirty_addr != 0) {
+            int  dirty = 0;
+            int  len   = fbs->src_pitch;
+
+            while (len > 0) {
+                int  len2 = TARGET_PAGE_SIZE - (dirty_addr & (TARGET_PAGE_SIZE-1));
+
+                if (len2 > len)
+                    len2 = len;
+
+                dirty |= cpu_physical_memory_get_dirty(dirty_addr, VGA_DIRTY_FLAG);
+                dirty_addr  += len2;
+                len         -= len2;
+            }
+
+            if (!dirty) { /* this line was not modified, skip to next one */
+                goto NEXT_LINE;
+            }
+        }
+
+        /* Then compute actual bounds of the changed pixels, while
+         * copying them from 'src' to 'dst'. This depends on the pixel depth.
+         */
+        switch (fbs->bytes_per_pixel) {
+        case 2:
+        {
+            const uint16_t* src = (const uint16_t*) src_line;
+            uint16_t*       dst = (uint16_t*) dst_line;
+
+            xx1 = 0;
+            DUFF4(width, {
+                uint16_t spix = src[xx1];
+#if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
+                spix = (uint16_t)((spix << 8) | (spix >> 8));
+#endif
+                if (spix != dst[xx1])
+                    break;
+                xx1++;
+            });
+            if (xx1 == width) {
+                break;
+            }
+            xx2 = width-1;
+            DUFF4(xx2-xx1, {
+                if (src[xx2] != dst[xx2])
+                    break;
+                xx2--;
+            });
+#if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
+            /* Convert the guest pixels into host ones */
+            int xx = xx1;
+            DUFF4(xx2-xx1+1,{
+                unsigned   spix = src[xx];
+                dst[xx] = (uint16_t)((spix << 8) | (spix >> 8));
+                xx++;
+            });
+#else
+            memcpy( dst+xx1, src+xx1, (xx2-xx1+1)*2 );
+#endif
+            break;
+        }
+
+        case 3:
+        {
+            xx1 = 0;
+            DUFF4(width, {
+                int xx = xx1*3;
+                if (src_line[xx+0] != dst_line[xx+0] ||
+                    src_line[xx+1] != dst_line[xx+1] ||
+                    src_line[xx+2] != dst_line[xx+2]) {
+                    break;
+                }
+                xx1 ++;
+            });
+            if (xx1 == width) {
+                break;
+            }
+            xx2 = width-1;
+            DUFF4(xx2-xx1,{
+                int xx = xx2*3;
+                if (src_line[xx+0] != dst_line[xx+0] ||
+                    src_line[xx+1] != dst_line[xx+1] ||
+                    src_line[xx+2] != dst_line[xx+2]) {
+                    break;
+                }
+                xx2--;
+            });
+            memcpy( dst_line+xx1*3, src_line+xx1*3, (xx2-xx1+1)*3 );
+            break;
+        }
+
+        case 4:
+        {
+            const uint32_t* src = (const uint32_t*) src_line;
+            uint32_t*       dst = (uint32_t*) dst_line;
+
+            xx1 = 0;
+            DUFF4(width, {
+                uint32_t spix = src[xx1];
+#if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
+                spix = (spix << 16) | (spix >> 16);
+                spix = ((spix << 8) & 0xff00ff00) | ((spix >> 8) & 0x00ff00ff);
+#endif
+                if (spix != dst[xx1]) {
+                    break;
+                }
+                xx1++;
+            });
+            if (xx1 == width) {
+                break;
+            }
+            xx2 = width-1;
+            DUFF4(xx2-xx1,{
+                if (src[xx2] != dst[xx2]) {
+                    break;
+                }
+                xx2--;
+            });
+#if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
+            /* Convert the guest pixels into host ones */
+            int xx = xx1;
+            DUFF4(xx2-xx1+1,{
+                uint32_t   spix = src[xx];
+                spix = (spix << 16) | (spix >> 16);
+                spix = ((spix << 8) & 0xff00ff00) | ((spix >> 8) & 0x00ff00ff);
+                dst[xx] = spix;
+                xx++;
+            })
+#else
+            memcpy( dst+xx1, src+xx1, (xx2-xx1+1)*4 );
+#endif
+            break;
+        }
+        default:
+            return 0;
+        }
+        /* Update bounds if pixels on this line were modified */
+        if (xx1 < width) {
+            if (xx1 < rect->xmin) rect->xmin = xx1;
+            if (xx2 > rect->xmax) rect->xmax = xx2;
+            if (yy < rect->ymin) rect->ymin = yy;
+            if (yy > rect->ymax) rect->ymax = yy;
+        }
+    NEXT_LINE:
+        src_line += fbs->src_pitch;
+        dst_line += fbs->dst_pitch;
+    }
+
+    if (rect->ymin > rect->ymax) { /* nothing changed */
+        return 0;
+    }
+
+    /* Always clear the dirty VGA bits */
+    cpu_physical_memory_reset_dirty(dirty_base + rect->ymin * fbs->src_pitch,
+                                    dirty_base + (rect->ymax+1)* fbs->src_pitch,
+                                    VGA_DIRTY_FLAG);
+    return 1;
+}
+
+
+static void goldfish_fb_update_display(void *opaque)
+{
+    struct goldfish_fb_state *s = (struct goldfish_fb_state *)opaque;
+    uint32_t base;
+    uint8_t*  dst_line;
+    uint8_t*  src_line;
+    int full_update = 0;
+    int  width, height, pitch;
+
+    base = s->fb_base;
+    if(base == 0)
+        return;
+
+    if((s->int_enable & FB_INT_VSYNC) && !(s->int_status & FB_INT_VSYNC)) {
+        s->int_status |= FB_INT_VSYNC;
+        goldfish_device_set_irq(&s->dev, 0, 1);
+    }
+
+    if(s->need_update) {
+        full_update = 1;
+        if(s->need_int) {
+            s->int_status |= FB_INT_BASE_UPDATE_DONE;
+            if(s->int_enable & FB_INT_BASE_UPDATE_DONE)
+                goldfish_device_set_irq(&s->dev, 0, 1);
+        }
+        s->need_int = 0;
+        s->need_update = 0;
+    }
+
+    src_line  = qemu_get_ram_ptr( base );
+
+    dst_line  = s->ds->surface->data;
+    pitch     = s->ds->surface->linesize;
+    width     = s->ds->surface->width;
+    height    = s->ds->surface->height;
+
+    FbUpdateState  fbs;
+    FbUpdateRect   rect;
+
+    fbs.width      = width;
+    fbs.height     = height;
+    fbs.dst_pixels = dst_line;
+    fbs.dst_pitch  = pitch;
+    fbs.bytes_per_pixel = goldfish_fb_get_bytes_per_pixel(s);
+
+    fbs.src_pixels = src_line;
+    fbs.src_pitch  = width*s->ds->surface->pf.bytes_per_pixel;
+
+
+#if STATS
+    if (full_update)
+        stats_full_updates += 1;
+    if (++stats_counter == 120) {
+        stats_total               += stats_counter;
+        stats_total_full_updates  += stats_full_updates;
+
+        printf( "full update stats:  peak %.2f %%  total %.2f %%\n",
+                stats_full_updates*100.0/stats_counter,
+                stats_total_full_updates*100.0/stats_total );
+
+        stats_counter      = 0;
+        stats_full_updates = 0;
+    }
+#endif /* STATS */
+
+    if (s->blank)
+    {
+        memset( dst_line, 0, height*pitch );
+        rect.xmin = 0;
+        rect.ymin = 0;
+        rect.xmax = width-1;
+        rect.ymax = height-1;
+    }
+    else
+    {
+        if (full_update) { /* don't use dirty-bits optimization */
+            base = 0;
+        }
+        if (compute_fb_update_rect_linear(&fbs, base, &rect) == 0) {
+            return;
+        }
+    }
+
+    rect.xmax += 1;
+    rect.ymax += 1;
+#if 0
+    printf("goldfish_fb_update_display (y:%d,h:%d,x=%d,w=%d)\n",
+           rect.ymin, rect.ymax-rect.ymin, rect.xmin, rect.xmax-rect.xmin);
+#endif
+
+    dpy_update(s->ds, rect.xmin, rect.ymin, rect.xmax-rect.xmin, rect.ymax-rect.ymin);
+}
+
+static void goldfish_fb_invalidate_display(void * opaque)
+{
+    // is this called?
+    struct goldfish_fb_state *s = (struct goldfish_fb_state *)opaque;
+    s->need_update = 1;
+}
+
+static uint32_t goldfish_fb_read(void *opaque, target_phys_addr_t offset)
+{
+    uint32_t ret;
+    struct goldfish_fb_state *s = opaque;
+
+    switch(offset) {
+        case FB_GET_WIDTH:
+            ret = ds_get_width(s->ds);
+            //printf("FB_GET_WIDTH => %d\n", ret);
+            return ret;
+
+        case FB_GET_HEIGHT:
+            ret = ds_get_height(s->ds);
+            //printf( "FB_GET_HEIGHT = %d\n", ret);
+            return ret;
+
+        case FB_INT_STATUS:
+            ret = s->int_status & s->int_enable;
+            if(ret) {
+                s->int_status &= ~ret;
+                goldfish_device_set_irq(&s->dev, 0, 0);
+            }
+            return ret;
+
+        case FB_GET_PHYS_WIDTH:
+            ret = pixels_to_mm( ds_get_width(s->ds), s->dpi );
+            //printf( "FB_GET_PHYS_WIDTH => %d\n", ret );
+            return ret;
+
+        case FB_GET_PHYS_HEIGHT:
+            ret = pixels_to_mm( ds_get_height(s->ds), s->dpi );
+            //printf( "FB_GET_PHYS_HEIGHT => %d\n", ret );
+            return ret;
+
+        case FB_GET_FORMAT:
+            return goldfish_fb_get_pixel_format(s);
+
+        default:
+            cpu_abort (cpu_single_env, "goldfish_fb_read: Bad offset %x\n", offset);
+            return 0;
+    }
+}
+
+static void goldfish_fb_write(void *opaque, target_phys_addr_t offset,
+                        uint32_t val)
+{
+    struct goldfish_fb_state *s = opaque;
+
+    switch(offset) {
+        case FB_INT_ENABLE:
+            s->int_enable = val;
+            goldfish_device_set_irq(&s->dev, 0, (s->int_status & s->int_enable));
+            break;
+        case FB_SET_BASE: {
+            int need_resize = !s->base_valid;
+            s->fb_base = val;
+            s->int_status &= ~FB_INT_BASE_UPDATE_DONE;
+            s->need_update = 1;
+            s->need_int = 1;
+            s->base_valid = 1;
+            if(s->set_rotation != s->rotation) {
+                //printf("FB_SET_BASE: rotation : %d => %d\n", s->rotation, s->set_rotation);
+                s->rotation = s->set_rotation;
+                need_resize = 1;
+            }
+            goldfish_device_set_irq(&s->dev, 0, (s->int_status & s->int_enable));
+            if (need_resize) {
+                //printf("FB_SET_BASE: need resize (rotation=%d)\n", s->rotation );
+                dpy_resize(s->ds);
+            }
+            } break;
+        case FB_SET_ROTATION:
+            //printf( "FB_SET_ROTATION %d\n", val);
+            s->set_rotation = val;
+            break;
+        case FB_SET_BLANK:
+            s->blank = val;
+            s->need_update = 1;
+            break;
+        default:
+            cpu_abort (cpu_single_env, "goldfish_fb_write: Bad offset %x\n", offset);
+    }
+}
+
+static CPUReadMemoryFunc *goldfish_fb_readfn[] = {
+   goldfish_fb_read,
+   goldfish_fb_read,
+   goldfish_fb_read
+};
+
+static CPUWriteMemoryFunc *goldfish_fb_writefn[] = {
+   goldfish_fb_write,
+   goldfish_fb_write,
+   goldfish_fb_write
+};
+
+void goldfish_fb_init(int id)
+{
+    struct goldfish_fb_state *s;
+
+    s = (struct goldfish_fb_state *)qemu_mallocz(sizeof(*s));
+    s->dev.name = "goldfish_fb";
+    s->dev.id = id;
+    s->dev.size = 0x1000;
+    s->dev.irq_count = 1;
+
+    s->ds = graphic_console_init(goldfish_fb_update_display,
+                                 goldfish_fb_invalidate_display,
+                                 NULL,
+                                 NULL,
+                                 s);
+
+    s->dpi = 165;  /* XXX: Find better way to get actual value ! */
+
+    /* IMPORTANT: DO NOT COMPUTE s->pixel_format and s->bytes_per_pixel
+     * here because the display surface is going to change later.
+     */
+    s->bytes_per_pixel = 0;
+    s->pixel_format    = -1;
+
+    goldfish_device_add(&s->dev, goldfish_fb_readfn, goldfish_fb_writefn, s);
+
+    register_savevm( "goldfish_fb", 0, GOLDFISH_FB_SAVE_VERSION,
+                     goldfish_fb_save, goldfish_fb_load, s);
+}
