]> Git Repo - qemu.git/blobdiff - hw/vga.c
scsi-disk: support READ DVD STRUCTURE
[qemu.git] / hw / vga.c
index fc45b2af1c6311974fe73644f30e36f2e83f5975..ca79aa157dd0000fefa66c27415e17fef0ef5aed 100644 (file)
--- a/hw/vga.c
+++ b/hw/vga.c
@@ -149,9 +149,53 @@ static uint16_t expand2[256];
 static uint8_t expand4to8[16];
 
 static void vga_screen_dump(void *opaque, const char *filename);
-static char *screen_dump_filename;
+static const char *screen_dump_filename;
 static DisplayChangeListener *screen_dump_dcl;
 
+static void vga_update_memory_access(VGACommonState *s)
+{
+    MemoryRegion *region, *old_region = s->chain4_alias;
+    target_phys_addr_t base, offset, size;
+
+    s->chain4_alias = NULL;
+
+    if ((s->sr[0x02] & 0xf) == 0xf && s->sr[0x04] & 0x08) {
+        offset = 0;
+        switch ((s->gr[6] >> 2) & 3) {
+        case 0:
+            base = 0xa0000;
+            size = 0x20000;
+            break;
+        case 1:
+            base = 0xa0000;
+            size = 0x10000;
+            offset = s->bank_offset;
+            break;
+        case 2:
+            base = 0xb0000;
+            size = 0x8000;
+            break;
+        case 3:
+        default:
+            base = 0xb8000;
+            size = 0x8000;
+            break;
+        }
+        base += isa_mem_base;
+        region = g_malloc(sizeof(*region));
+        memory_region_init_alias(region, "vga.chain4", &s->vram, offset, size);
+        memory_region_add_subregion_overlap(s->legacy_address_space, base,
+                                            region, 2);
+        s->chain4_alias = region;
+    }
+    if (old_region) {
+        memory_region_del_subregion(s->legacy_address_space, old_region);
+        memory_region_destroy(old_region);
+        g_free(old_region);
+        s->plane_updated = 0xf;
+    }
+}
+
 static void vga_dumb_update_retrace_info(VGACommonState *s)
 {
     (void) s;
@@ -168,7 +212,10 @@ static void vga_precise_update_retrace_info(VGACommonState *s)
     int vretr_start_line;
     int vretr_end_line;
 
-    int div2, sldiv2, dots;
+    int dots;
+#if 0
+    int div2, sldiv2;
+#endif
     int clocking_mode;
     int clock_sel;
     const int clk_hz[] = {25175000, 28322000, 25175000, 25175000};
@@ -189,8 +236,6 @@ static void vga_precise_update_retrace_info(VGACommonState *s)
     vretr_end_line = s->cr[0x11] & 0xf;
 
 
-    div2 = (s->cr[0x17] >> 2) & 1;
-    sldiv2 = (s->cr[0x17] >> 3) & 1;
 
     clocking_mode = (s->sr[0x01] >> 3) & 1;
     clock_sel = (s->msr >> 2) & 3;
@@ -215,6 +260,8 @@ static void vga_precise_update_retrace_info(VGACommonState *s)
     r->htotal = htotal_chars;
 
 #if 0
+    div2 = (s->cr[0x17] >> 2) & 1;
+    sldiv2 = (s->cr[0x17] >> 3) & 1;
     printf (
         "hz=%f\n"
         "htotal = %d\n"
@@ -228,7 +275,7 @@ static void vga_precise_update_retrace_info(VGACommonState *s)
         "clocking_mode = %d\n"
         "clock_sel = %d %d\n"
         "dots = %d\n"
-        "ticks/char = %lld\n"
+        "ticks/char = %" PRId64 "\n"
         "\n",
         (double) get_ticks_per_sec() / (r->ticks_per_char * r->total_chars),
         htotal_chars,
@@ -257,7 +304,7 @@ static uint8_t vga_precise_retrace(VGACommonState *s)
         int cur_line, cur_line_char, cur_char;
         int64_t cur_tick;
 
-        cur_tick = qemu_get_clock(vm_clock);
+        cur_tick = qemu_get_clock_ns(vm_clock);
 
         cur_char = (cur_tick / r->ticks_per_char) % r->total_chars;
         cur_line = cur_char / r->htotal;
@@ -442,6 +489,7 @@ void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
 #endif
         s->sr[s->sr_index] = val & sr_mask[s->sr_index];
         if (s->sr_index == 1) s->update_retrace_info(s);
+        vga_update_memory_access(s);
         break;
     case 0x3c7:
         s->dac_read_index = val;
@@ -469,6 +517,7 @@ void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
         printf("vga: write GR%x = 0x%02x\n", s->gr_index, val);
 #endif
         s->gr[s->gr_index] = val & gr_mask[s->gr_index];
+        vga_update_memory_access(s);
         break;
     case 0x3b4:
     case 0x3d4:
@@ -521,7 +570,7 @@ static uint32_t vbe_ioport_read_data(void *opaque, uint32_t addr)
     VGACommonState *s = opaque;
     uint32_t val;
 
-    if (s->vbe_index <= VBE_DISPI_INDEX_NB) {
+    if (s->vbe_index < VBE_DISPI_INDEX_NB) {
         if (s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_GETCAPS) {
             switch(s->vbe_index) {
                 /* XXX: do not hardcode ? */
@@ -541,6 +590,8 @@ static uint32_t vbe_ioport_read_data(void *opaque, uint32_t addr)
         } else {
             val = s->vbe_regs[s->vbe_index];
         }
+    } else if (s->vbe_index == VBE_DISPI_INDEX_VIDEO_MEMORY_64K) {
+        val = s->vram_size / (64 * 1024);
     } else {
         val = 0;
     }
@@ -600,6 +651,7 @@ static void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val)
             }
             s->vbe_regs[s->vbe_index] = val;
             s->bank_offset = (val << 16);
+            vga_update_memory_access(s);
             break;
         case VBE_DISPI_INDEX_ENABLE:
             if ((val & VBE_DISPI_ENABLED) &&
@@ -659,6 +711,7 @@ static void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val)
             }
             s->dac_8bit = (val & VBE_DISPI_8BIT_DAC) > 0;
             s->vbe_regs[s->vbe_index] = val;
+            vga_update_memory_access(s);
             break;
         case VBE_DISPI_INDEX_VIRT_WIDTH:
             {
@@ -702,9 +755,8 @@ static void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val)
 #endif
 
 /* called for accesses between 0xa0000 and 0xc0000 */
-uint32_t vga_mem_readb(void *opaque, a_target_phys_addr addr)
+uint32_t vga_mem_readb(VGACommonState *s, target_phys_addr_t addr)
 {
-    VGACommonState *s = opaque;
     int memory_map_mode, plane;
     uint32_t ret;
 
@@ -758,40 +810,9 @@ uint32_t vga_mem_readb(void *opaque, a_target_phys_addr addr)
     return ret;
 }
 
-static uint32_t vga_mem_readw(void *opaque, a_target_phys_addr addr)
-{
-    uint32_t v;
-#ifdef TARGET_WORDS_BIGENDIAN
-    v = vga_mem_readb(opaque, addr) << 8;
-    v |= vga_mem_readb(opaque, addr + 1);
-#else
-    v = vga_mem_readb(opaque, addr);
-    v |= vga_mem_readb(opaque, addr + 1) << 8;
-#endif
-    return v;
-}
-
-static uint32_t vga_mem_readl(void *opaque, a_target_phys_addr addr)
-{
-    uint32_t v;
-#ifdef TARGET_WORDS_BIGENDIAN
-    v = vga_mem_readb(opaque, addr) << 24;
-    v |= vga_mem_readb(opaque, addr + 1) << 16;
-    v |= vga_mem_readb(opaque, addr + 2) << 8;
-    v |= vga_mem_readb(opaque, addr + 3);
-#else
-    v = vga_mem_readb(opaque, addr);
-    v |= vga_mem_readb(opaque, addr + 1) << 8;
-    v |= vga_mem_readb(opaque, addr + 2) << 16;
-    v |= vga_mem_readb(opaque, addr + 3) << 24;
-#endif
-    return v;
-}
-
 /* called for accesses between 0xa0000 and 0xc0000 */
-void vga_mem_writeb(void *opaque, a_target_phys_addr addr, uint32_t val)
+void vga_mem_writeb(VGACommonState *s, target_phys_addr_t addr, uint32_t val)
 {
-    VGACommonState *s = opaque;
     int memory_map_mode, plane, write_mode, b, func_select, mask;
     uint32_t write_mask, bit_mask, set_mask;
 
@@ -832,7 +853,7 @@ void vga_mem_writeb(void *opaque, a_target_phys_addr addr, uint32_t val)
             printf("vga: chain4: [0x" TARGET_FMT_plx "]\n", addr);
 #endif
             s->plane_updated |= mask; /* only used to detect font change */
-            cpu_physical_memory_set_dirty(s->vram_offset + addr);
+            memory_region_set_dirty(&s->vram, addr);
         }
     } else if (s->gr[5] & 0x10) {
         /* odd/even mode (aka text mode mapping) */
@@ -845,7 +866,7 @@ void vga_mem_writeb(void *opaque, a_target_phys_addr addr, uint32_t val)
             printf("vga: odd/even: [0x" TARGET_FMT_plx "]\n", addr);
 #endif
             s->plane_updated |= mask; /* only used to detect font change */
-            cpu_physical_memory_set_dirty(s->vram_offset + addr);
+            memory_region_set_dirty(&s->vram, addr);
         }
     } else {
         /* standard VGA latched access */
@@ -919,36 +940,10 @@ void vga_mem_writeb(void *opaque, a_target_phys_addr addr, uint32_t val)
         printf("vga: latch: [0x" TARGET_FMT_plx "] mask=0x%08x val=0x%08x\n",
                addr * 4, write_mask, val);
 #endif
-        cpu_physical_memory_set_dirty(s->vram_offset + (addr << 2));
+        memory_region_set_dirty(&s->vram, addr << 2);
     }
 }
 
-static void vga_mem_writew(void *opaque, a_target_phys_addr addr, uint32_t val)
-{
-#ifdef TARGET_WORDS_BIGENDIAN
-    vga_mem_writeb(opaque, addr, (val >> 8) & 0xff);
-    vga_mem_writeb(opaque, addr + 1, val & 0xff);
-#else
-    vga_mem_writeb(opaque, addr, val & 0xff);
-    vga_mem_writeb(opaque, addr + 1, (val >> 8) & 0xff);
-#endif
-}
-
-static void vga_mem_writel(void *opaque, a_target_phys_addr addr, uint32_t val)
-{
-#ifdef TARGET_WORDS_BIGENDIAN
-    vga_mem_writeb(opaque, addr, (val >> 24) & 0xff);
-    vga_mem_writeb(opaque, addr + 1, (val >> 16) & 0xff);
-    vga_mem_writeb(opaque, addr + 2, (val >> 8) & 0xff);
-    vga_mem_writeb(opaque, addr + 3, val & 0xff);
-#else
-    vga_mem_writeb(opaque, addr, val & 0xff);
-    vga_mem_writeb(opaque, addr + 1, (val >> 8) & 0xff);
-    vga_mem_writeb(opaque, addr + 2, (val >> 16) & 0xff);
-    vga_mem_writeb(opaque, addr + 3, (val >> 24) & 0xff);
-#endif
-}
-
 typedef void vga_draw_glyph8_func(uint8_t *d, int linesize,
                              const uint8_t *font_ptr, int h,
                              uint32_t fgcol, uint32_t bgcol);
@@ -1165,7 +1160,7 @@ static inline int get_depth_index(DisplayState *s)
     }
 }
 
-static vga_draw_glyph8_func *vga_draw_glyph8_table[NB_DEPTHS] = {
+static vga_draw_glyph8_func * const vga_draw_glyph8_table[NB_DEPTHS] = {
     vga_draw_glyph8_8,
     vga_draw_glyph8_16,
     vga_draw_glyph8_16,
@@ -1175,7 +1170,7 @@ static vga_draw_glyph8_func *vga_draw_glyph8_table[NB_DEPTHS] = {
     vga_draw_glyph8_16,
 };
 
-static vga_draw_glyph8_func *vga_draw_glyph16_table[NB_DEPTHS] = {
+static vga_draw_glyph8_func * const vga_draw_glyph16_table[NB_DEPTHS] = {
     vga_draw_glyph16_8,
     vga_draw_glyph16_16,
     vga_draw_glyph16_16,
@@ -1185,7 +1180,7 @@ static vga_draw_glyph8_func *vga_draw_glyph16_table[NB_DEPTHS] = {
     vga_draw_glyph16_16,
 };
 
-static vga_draw_glyph9_func *vga_draw_glyph9_table[NB_DEPTHS] = {
+static vga_draw_glyph9_func * const vga_draw_glyph9_table[NB_DEPTHS] = {
     vga_draw_glyph9_8,
     vga_draw_glyph9_16,
     vga_draw_glyph9_16,
@@ -1245,7 +1240,7 @@ static void vga_get_text_resolution(VGACommonState *s, int *pwidth, int *pheight
 
 typedef unsigned int rgb_to_pixel_dup_func(unsigned int r, unsigned int g, unsigned b);
 
-static rgb_to_pixel_dup_func *rgb_to_pixel_dup_table[NB_DEPTHS] = {
+static rgb_to_pixel_dup_func * const rgb_to_pixel_dup_table[NB_DEPTHS] = {
     rgb_to_pixel8_dup,
     rgb_to_pixel15_dup,
     rgb_to_pixel16_dup,
@@ -1266,9 +1261,9 @@ static rgb_to_pixel_dup_func *rgb_to_pixel_dup_table[NB_DEPTHS] = {
 static void vga_draw_text(VGACommonState *s, int full_update)
 {
     int cx, cy, cheight, cw, ch, cattr, height, width, ch_attr;
-    int cx_min, cx_max, linesize, x_incr;
+    int cx_min, cx_max, linesize, x_incr, line, line1;
     uint32_t offset, fgcol, bgcol, v, cursor_offset;
-    uint8_t *d1, *d, *src, *s1, *dest, *cursor_ptr;
+    uint8_t *d1, *d, *src, *dest, *cursor_ptr;
     const uint8_t *font_ptr, *font_base[2];
     int dup9, line_offset, depth_index;
     uint32_t *palette;
@@ -1291,7 +1286,7 @@ static void vga_draw_text(VGACommonState *s, int full_update)
         s->font_offsets[1] = offset;
         full_update = 1;
     }
-    if (s->plane_updated & (1 << 2)) {
+    if (s->plane_updated & (1 << 2) || s->chain4_alias) {
         /* if the plane 2 was modified since the last display, it
            indicates the font may have been modified */
         s->plane_updated = 0;
@@ -1300,10 +1295,8 @@ static void vga_draw_text(VGACommonState *s, int full_update)
     full_update |= update_basic_params(s);
 
     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);
     if ((height * width) > CH_ATTR_SIZE) {
         /* better than nothing: exit if transient size is too big */
         return;
@@ -1353,9 +1346,11 @@ static void vga_draw_text(VGACommonState *s, int full_update)
     dest = ds_get_data(s->ds);
     linesize = ds_get_linesize(s->ds);
     ch_attr_ptr = s->last_ch_attr;
+    line = 0;
+    offset = s->start_addr * 4;
     for(cy = 0; cy < height; cy++) {
         d1 = dest;
-        src = s1;
+        src = s->vram_ptr + offset;
         cx_min = width;
         cx_max = -1;
         for(cx = 0; cx < width; cx++) {
@@ -1418,7 +1413,12 @@ static void vga_draw_text(VGACommonState *s, int full_update)
                        (cx_max - cx_min + 1) * cw, cheight);
         }
         dest += linesize * cheight;
-        s1 += line_offset;
+        line1 = line + cheight;
+        offset += line_offset;
+        if (line < s->line_compare && line1 >= s->line_compare) {
+            offset = 0;
+        }
+        line = line1;
     }
 }
 
@@ -1436,7 +1436,7 @@ enum {
     VGA_DRAW_LINE_NB,
 };
 
-static vga_draw_line_func *vga_draw_line_table[NB_DEPTHS * VGA_DRAW_LINE_NB] = {
+static vga_draw_line_func * const vga_draw_line_table[NB_DEPTHS * VGA_DRAW_LINE_NB] = {
     vga_draw_line2_8,
     vga_draw_line2_16,
     vga_draw_line2_16,
@@ -1567,13 +1567,17 @@ void vga_invalidate_scanlines(VGACommonState *s, int y1, int y2)
 
 static void vga_sync_dirty_bitmap(VGACommonState *s)
 {
-    if (s->map_addr)
-        cpu_physical_sync_dirty_bitmap(s->map_addr, s->map_end);
+    memory_region_sync_dirty_bitmap(&s->vram);
+}
 
-    if (s->lfb_vram_mapped) {
-        cpu_physical_sync_dirty_bitmap(isa_mem_base + 0xa0000, 0xa8000);
-        cpu_physical_sync_dirty_bitmap(isa_mem_base + 0xa8000, 0xb0000);
-    }
+void vga_dirty_log_start(VGACommonState *s)
+{
+    memory_region_set_log(&s->vram, true, DIRTY_MEMORY_VGA);
+}
+
+void vga_dirty_log_stop(VGACommonState *s)
+{
+    memory_region_set_log(&s->vram, false, DIRTY_MEMORY_VGA);
 }
 
 /*
@@ -1583,7 +1587,7 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
 {
     int y1, y, update, linesize, y_start, double_scan, mask, depth;
     int width, height, shift_control, line_offset, bwidth, bits;
-    a_ram_addr page0, page1, page_min, page_max;
+    ram_addr_t page0, page1, page_min, page_max;
     int disp_width, multi_scan, multi_run;
     uint8_t *d;
     uint32_t v, addr1, addr;
@@ -1737,15 +1741,16 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
         if (!(s->cr[0x17] & 2)) {
             addr = (addr & ~0x8000) | ((y1 & 2) << 14);
         }
-        page0 = s->vram_offset + (addr & TARGET_PAGE_MASK);
-        page1 = s->vram_offset + ((addr + bwidth - 1) & TARGET_PAGE_MASK);
+        page0 = addr & TARGET_PAGE_MASK;
+        page1 = (addr + bwidth - 1) & TARGET_PAGE_MASK;
         update = full_update |
-            cpu_physical_memory_get_dirty(page0, VGA_DIRTY_FLAG) |
-            cpu_physical_memory_get_dirty(page1, VGA_DIRTY_FLAG);
+            memory_region_get_dirty(&s->vram, page0, DIRTY_MEMORY_VGA) |
+            memory_region_get_dirty(&s->vram, page1, DIRTY_MEMORY_VGA);
         if ((page1 - page0) > TARGET_PAGE_SIZE) {
             /* if wide line, can use another page */
-            update |= cpu_physical_memory_get_dirty(page0 + TARGET_PAGE_SIZE,
-                                                    VGA_DIRTY_FLAG);
+            update |= memory_region_get_dirty(&s->vram,
+                                              page0 + TARGET_PAGE_SIZE,
+                                              DIRTY_MEMORY_VGA);
         }
         /* explicit invalidation for the hardware cursor */
         update |= (s->invalidated_y_table[y >> 5] >> (y & 0x1f)) & 1;
@@ -1790,8 +1795,10 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
     }
     /* reset modified pages */
     if (page_max >= page_min) {
-        cpu_physical_memory_reset_dirty(page_min, page_max + TARGET_PAGE_SIZE,
-                                        VGA_DIRTY_FLAG);
+        memory_region_reset_dirty(&s->vram,
+                                  page_min,
+                                  page_max + TARGET_PAGE_SIZE - page_min,
+                                  DIRTY_MEMORY_VGA);
     }
     memset(s->invalidated_y_table, 0, ((height + 31) >> 5) * 4);
 }
@@ -1831,11 +1838,12 @@ static void vga_update_display(void *opaque)
     VGACommonState *s = opaque;
     int full_update, graphic_mode;
 
+    qemu_flush_coalesced_mmio_buffer();
+
     if (ds_get_bits_per_pixel(s->ds) == 0) {
         /* nothing to do */
     } else {
-        full_update = s->full_update;
-        s->full_update = 0;
+        full_update = 0;
         if (!(s->ar_index & 0x20)) {
             graphic_mode = GMODE_BLANK;
         } else {
@@ -1865,18 +1873,12 @@ static void vga_invalidate_display(void *opaque)
 {
     VGACommonState *s = opaque;
 
-    s->full_update = 1;
+    s->last_width = -1;
+    s->last_height = -1;
 }
 
 void vga_common_reset(VGACommonState *s)
 {
-    s->lfb_addr = 0;
-    s->lfb_end = 0;
-    s->map_addr = 0;
-    s->map_end = 0;
-    s->lfb_vram_mapped = 0;
-    s->bios_offset = 0;
-    s->bios_size = 0;
     s->sr_index = 0;
     memset(s->sr, '\0', sizeof(s->sr));
     s->gr_index = 0;
@@ -1901,7 +1903,7 @@ void vga_common_reset(VGACommonState *s)
 #ifdef CONFIG_BOCHS_VBE
     s->vbe_index = 0;
     memset(s->vbe_regs, '\0', sizeof(s->vbe_regs));
-    s->vbe_regs[VBE_DISPI_INDEX_ID] = VBE_DISPI_ID0;
+    s->vbe_regs[VBE_DISPI_INDEX_ID] = VBE_DISPI_ID5;
     s->vbe_start_addr = 0;
     s->vbe_line_offset = 0;
     s->vbe_bank_mask = (s->vram_size >> 16) - 1;
@@ -1933,6 +1935,7 @@ void vga_common_reset(VGACommonState *s)
         memset(&s->retrace_info, 0, sizeof (s->retrace_info));
         break;
     }
+    vga_update_memory_access(s);
 }
 
 static void vga_reset(void *opaque)
@@ -1947,16 +1950,18 @@ static void vga_reset(void *opaque)
         ((v & 0x00000800) << 10) | ((v & 0x00007000) >> 1))
 /* relay text rendering to the display driver
  * instead of doing a full vga_update_display() */
-static void vga_update_text(void *opaque, a_console_ch *chardata)
+static void vga_update_text(void *opaque, console_ch_t *chardata)
 {
     VGACommonState *s =  opaque;
     int graphic_mode, i, cursor_offset, cursor_visible;
     int cw, cheight, width, height, size, c_min, c_max;
     uint32_t *src;
-    a_console_ch *dst, val;
+    console_ch_t *dst, val;
     char msg_buffer[80];
     int full_update = 0;
 
+    qemu_flush_coalesced_mmio_buffer();
+
     if (!(s->ar_index & 0x20)) {
         graphic_mode = GMODE_BLANK;
     } else {
@@ -2040,14 +2045,14 @@ static void vga_update_text(void *opaque, a_console_ch *chardata)
 
         if (full_update) {
             for (i = 0; i < size; src ++, dst ++, i ++)
-                console_write_ch(dst, VMEM2CHTYPE(*src));
+                console_write_ch(dst, VMEM2CHTYPE(le32_to_cpu(*src)));
 
             dpy_update(s->ds, 0, 0, width, height);
         } else {
             c_max = 0;
 
             for (i = 0; i < size; src ++, dst ++, i ++) {
-                console_write_ch(&val, VMEM2CHTYPE(*src));
+                console_write_ch(&val, VMEM2CHTYPE(le32_to_cpu(*src)));
                 if (*dst != val) {
                     *dst = val;
                     c_max = i;
@@ -2056,7 +2061,7 @@ static void vga_update_text(void *opaque, a_console_ch *chardata)
             }
             c_min = i;
             for (; i < size; src ++, dst ++, i ++) {
-                console_write_ch(&val, VMEM2CHTYPE(*src));
+                console_write_ch(&val, VMEM2CHTYPE(le32_to_cpu(*src)));
                 if (*dst != val) {
                     *dst = val;
                     c_max = i;
@@ -2107,110 +2112,83 @@ static void vga_update_text(void *opaque, a_console_ch *chardata)
     dpy_update(s->ds, 0, 0, s->last_width, height);
 }
 
-CPUReadMemoryFunc * const vga_mem_read[3] = {
-    vga_mem_readb,
-    vga_mem_readw,
-    vga_mem_readl,
-};
+static uint64_t vga_mem_read(void *opaque, target_phys_addr_t addr,
+                             unsigned size)
+{
+    VGACommonState *s = opaque;
 
-CPUWriteMemoryFunc * const vga_mem_write[3] = {
-    vga_mem_writeb,
-    vga_mem_writew,
-    vga_mem_writel,
-};
+    return vga_mem_readb(s, addr);
+}
 
-void vga_common_save(QEMUFile *f, void *opaque)
+static void vga_mem_write(void *opaque, target_phys_addr_t addr,
+                          uint64_t data, unsigned size)
 {
     VGACommonState *s = opaque;
-    int i;
-
-    qemu_put_be32s(f, &s->latch);
-    qemu_put_8s(f, &s->sr_index);
-    qemu_put_buffer(f, s->sr, 8);
-    qemu_put_8s(f, &s->gr_index);
-    qemu_put_buffer(f, s->gr, 16);
-    qemu_put_8s(f, &s->ar_index);
-    qemu_put_buffer(f, s->ar, 21);
-    qemu_put_be32(f, s->ar_flip_flop);
-    qemu_put_8s(f, &s->cr_index);
-    qemu_put_buffer(f, s->cr, 256);
-    qemu_put_8s(f, &s->msr);
-    qemu_put_8s(f, &s->fcr);
-    qemu_put_byte(f, s->st00);
-    qemu_put_8s(f, &s->st01);
-
-    qemu_put_8s(f, &s->dac_state);
-    qemu_put_8s(f, &s->dac_sub_index);
-    qemu_put_8s(f, &s->dac_read_index);
-    qemu_put_8s(f, &s->dac_write_index);
-    qemu_put_buffer(f, s->dac_cache, 3);
-    qemu_put_buffer(f, s->palette, 768);
-
-    qemu_put_be32(f, s->bank_offset);
-#ifdef CONFIG_BOCHS_VBE
-    qemu_put_byte(f, 1);
-    qemu_put_be16s(f, &s->vbe_index);
-    for(i = 0; i < VBE_DISPI_INDEX_NB; i++)
-        qemu_put_be16s(f, &s->vbe_regs[i]);
-    qemu_put_be32s(f, &s->vbe_start_addr);
-    qemu_put_be32s(f, &s->vbe_line_offset);
-    qemu_put_be32s(f, &s->vbe_bank_mask);
-#else
-    qemu_put_byte(f, 0);
-#endif
+
+    return vga_mem_writeb(s, addr, data);
 }
 
-int vga_common_load(QEMUFile *f, void *opaque, int version_id)
+const MemoryRegionOps vga_mem_ops = {
+    .read = vga_mem_read,
+    .write = vga_mem_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+    .impl = {
+        .min_access_size = 1,
+        .max_access_size = 1,
+    },
+};
+
+static int vga_common_post_load(void *opaque, int version_id)
 {
     VGACommonState *s = opaque;
-    int is_vbe, i;
-
-    if (version_id > 2)
-        return -EINVAL;
-
-    qemu_get_be32s(f, &s->latch);
-    qemu_get_8s(f, &s->sr_index);
-    qemu_get_buffer(f, s->sr, 8);
-    qemu_get_8s(f, &s->gr_index);
-    qemu_get_buffer(f, s->gr, 16);
-    qemu_get_8s(f, &s->ar_index);
-    qemu_get_buffer(f, s->ar, 21);
-    s->ar_flip_flop=qemu_get_be32(f);
-    qemu_get_8s(f, &s->cr_index);
-    qemu_get_buffer(f, s->cr, 256);
-    qemu_get_8s(f, &s->msr);
-    qemu_get_8s(f, &s->fcr);
-    qemu_get_8s(f, &s->st00);
-    qemu_get_8s(f, &s->st01);
-
-    qemu_get_8s(f, &s->dac_state);
-    qemu_get_8s(f, &s->dac_sub_index);
-    qemu_get_8s(f, &s->dac_read_index);
-    qemu_get_8s(f, &s->dac_write_index);
-    qemu_get_buffer(f, s->dac_cache, 3);
-    qemu_get_buffer(f, s->palette, 768);
-
-    s->bank_offset=qemu_get_be32(f);
-    is_vbe = qemu_get_byte(f);
-#ifdef CONFIG_BOCHS_VBE
-    if (!is_vbe)
-        return -EINVAL;
-    qemu_get_be16s(f, &s->vbe_index);
-    for(i = 0; i < VBE_DISPI_INDEX_NB; i++)
-        qemu_get_be16s(f, &s->vbe_regs[i]);
-    qemu_get_be32s(f, &s->vbe_start_addr);
-    qemu_get_be32s(f, &s->vbe_line_offset);
-    qemu_get_be32s(f, &s->vbe_bank_mask);
-#else
-    if (is_vbe)
-        return -EINVAL;
-#endif
 
     /* force refresh */
     s->graphic_mode = -1;
     return 0;
 }
 
+const VMStateDescription vmstate_vga_common = {
+    .name = "vga",
+    .version_id = 2,
+    .minimum_version_id = 2,
+    .minimum_version_id_old = 2,
+    .post_load = vga_common_post_load,
+    .fields      = (VMStateField []) {
+        VMSTATE_UINT32(latch, VGACommonState),
+        VMSTATE_UINT8(sr_index, VGACommonState),
+        VMSTATE_PARTIAL_BUFFER(sr, VGACommonState, 8),
+        VMSTATE_UINT8(gr_index, VGACommonState),
+        VMSTATE_PARTIAL_BUFFER(gr, VGACommonState, 16),
+        VMSTATE_UINT8(ar_index, VGACommonState),
+        VMSTATE_BUFFER(ar, VGACommonState),
+        VMSTATE_INT32(ar_flip_flop, VGACommonState),
+        VMSTATE_UINT8(cr_index, VGACommonState),
+        VMSTATE_BUFFER(cr, VGACommonState),
+        VMSTATE_UINT8(msr, VGACommonState),
+        VMSTATE_UINT8(fcr, VGACommonState),
+        VMSTATE_UINT8(st00, VGACommonState),
+        VMSTATE_UINT8(st01, VGACommonState),
+
+        VMSTATE_UINT8(dac_state, VGACommonState),
+        VMSTATE_UINT8(dac_sub_index, VGACommonState),
+        VMSTATE_UINT8(dac_read_index, VGACommonState),
+        VMSTATE_UINT8(dac_write_index, VGACommonState),
+        VMSTATE_BUFFER(dac_cache, VGACommonState),
+        VMSTATE_BUFFER(palette, VGACommonState),
+
+        VMSTATE_INT32(bank_offset, VGACommonState),
+        VMSTATE_UINT8_EQUAL(is_vbe_vmstate, VGACommonState),
+#ifdef CONFIG_BOCHS_VBE
+        VMSTATE_UINT16(vbe_index, VGACommonState),
+        VMSTATE_UINT16_ARRAY(vbe_regs, VGACommonState, VBE_DISPI_INDEX_NB),
+        VMSTATE_UINT32(vbe_start_addr, VGACommonState),
+        VMSTATE_UINT32(vbe_line_offset, VGACommonState),
+        VMSTATE_UINT32(vbe_bank_mask, VGACommonState),
+#endif
+        VMSTATE_END_OF_LIST()
+    }
+};
+
 void vga_common_init(VGACommonState *s, int vga_ram_size)
 {
     int i, j, v, b;
@@ -2238,8 +2216,13 @@ void vga_common_init(VGACommonState *s, int vga_ram_size)
         expand4to8[i] = v;
     }
 
-    s->vram_offset = qemu_ram_alloc(vga_ram_size);
-    s->vram_ptr = qemu_get_ram_ptr(s->vram_offset);
+#ifdef CONFIG_BOCHS_VBE
+    s->is_vbe_vmstate = 1;
+#else
+    s->is_vbe_vmstate = 0;
+#endif
+    memory_region_init_ram(&s->vram, NULL, "vga.vram", vga_ram_size);
+    s->vram_ptr = memory_region_get_ram_ptr(&s->vram);
     s->vram_size = vga_ram_size;
     s->get_bpp = vga_get_bpp;
     s->get_offsets = vga_get_offsets;
@@ -2259,60 +2242,90 @@ void vga_common_init(VGACommonState *s, int vga_ram_size)
         s->update_retrace_info = vga_precise_update_retrace_info;
         break;
     }
-    vga_reset(s);
+    vga_dirty_log_start(s);
 }
 
-/* used by both ISA and PCI */
-void vga_init(VGACommonState *s)
-{
-    int vga_io_memory;
-
-    qemu_register_reset(vga_reset, s);
-
-    register_ioport_write(0x3c0, 16, 1, vga_ioport_write, s);
-
-    register_ioport_write(0x3b4, 2, 1, vga_ioport_write, s);
-    register_ioport_write(0x3d4, 2, 1, vga_ioport_write, s);
-    register_ioport_write(0x3ba, 1, 1, vga_ioport_write, s);
-    register_ioport_write(0x3da, 1, 1, vga_ioport_write, s);
+static const MemoryRegionPortio vga_portio_list[] = {
+    { 0x04,  2, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3b4 */
+    { 0x0a,  1, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3ba */
+    { 0x10, 16, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3c0 */
+    { 0x24,  2, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3d4 */
+    { 0x2a,  1, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3da */
+    PORTIO_END_OF_LIST(),
+};
 
-    register_ioport_read(0x3c0, 16, 1, vga_ioport_read, s);
+#ifdef CONFIG_BOCHS_VBE
+static const MemoryRegionPortio vbe_portio_list[] = {
+    { 0, 1, 2, .read = vbe_ioport_read_index, .write = vbe_ioport_write_index },
+# ifdef TARGET_I386
+    { 1, 1, 2, .read = vbe_ioport_read_data, .write = vbe_ioport_write_data },
+# else
+    { 2, 1, 2, .read = vbe_ioport_read_data, .write = vbe_ioport_write_data },
+# endif
+    PORTIO_END_OF_LIST(),
+};
+#endif /* CONFIG_BOCHS_VBE */
 
-    register_ioport_read(0x3b4, 2, 1, vga_ioport_read, s);
-    register_ioport_read(0x3d4, 2, 1, vga_ioport_read, s);
-    register_ioport_read(0x3ba, 1, 1, vga_ioport_read, s);
-    register_ioport_read(0x3da, 1, 1, vga_ioport_read, s);
-    s->bank_offset = 0;
+/* Used by both ISA and PCI */
+MemoryRegion *vga_init_io(VGACommonState *s,
+                          const MemoryRegionPortio **vga_ports,
+                          const MemoryRegionPortio **vbe_ports)
+{
+    MemoryRegion *vga_mem;
 
+    *vga_ports = vga_portio_list;
+    *vbe_ports = NULL;
 #ifdef CONFIG_BOCHS_VBE
-#if defined (TARGET_I386)
-    register_ioport_read(0x1ce, 1, 2, vbe_ioport_read_index, s);
-    register_ioport_read(0x1cf, 1, 2, vbe_ioport_read_data, s);
+    *vbe_ports = vbe_portio_list;
+#endif
 
-    register_ioport_write(0x1ce, 1, 2, vbe_ioport_write_index, s);
-    register_ioport_write(0x1cf, 1, 2, vbe_ioport_write_data, s);
+    vga_mem = g_malloc(sizeof(*vga_mem));
+    memory_region_init_io(vga_mem, &vga_mem_ops, s,
+                          "vga-lowmem", 0x20000);
 
-    /* old Bochs IO ports */
-    register_ioport_read(0xff80, 1, 2, vbe_ioport_read_index, s);
-    register_ioport_read(0xff81, 1, 2, vbe_ioport_read_data, s);
+    return vga_mem;
+}
 
-    register_ioport_write(0xff80, 1, 2, vbe_ioport_write_index, s);
-    register_ioport_write(0xff81, 1, 2, vbe_ioport_write_data, s);
-#else
-    register_ioport_read(0x1ce, 1, 2, vbe_ioport_read_index, s);
-    register_ioport_read(0x1d0, 1, 2, vbe_ioport_read_data, s);
+void vga_init(VGACommonState *s, MemoryRegion *address_space,
+              MemoryRegion *address_space_io, bool init_vga_ports)
+{
+    MemoryRegion *vga_io_memory;
+    const MemoryRegionPortio *vga_ports, *vbe_ports;
+    PortioList *vga_port_list = g_new(PortioList, 1);
+    PortioList *vbe_port_list = g_new(PortioList, 1);
 
-    register_ioport_write(0x1ce, 1, 2, vbe_ioport_write_index, s);
-    register_ioport_write(0x1d0, 1, 2, vbe_ioport_write_data, s);
-#endif
-#endif /* CONFIG_BOCHS_VBE */
+    qemu_register_reset(vga_reset, s);
 
-    vga_io_memory = cpu_register_io_memory(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);
+    s->bank_offset = 0;
+
+    s->legacy_address_space = address_space;
+
+    vga_io_memory = vga_init_io(s, &vga_ports, &vbe_ports);
+    memory_region_add_subregion_overlap(address_space,
+                                        isa_mem_base + 0x000a0000,
+                                        vga_io_memory,
+                                        1);
+    memory_region_set_coalescing(vga_io_memory);
+    if (init_vga_ports) {
+        portio_list_init(vga_port_list, vga_ports, s, "vga");
+        portio_list_add(vga_port_list, address_space_io, 0x3b0);
+    }
+    if (vbe_ports) {
+        portio_list_init(vbe_port_list, vbe_ports, s, "vbe");
+        portio_list_add(vbe_port_list, address_space_io, 0x1ce);
+    }
 }
 
+void vga_init_vbe(VGACommonState *s, MemoryRegion *system_memory)
+{
+#ifdef CONFIG_BOCHS_VBE
+    /* XXX: use optimized standard vga accesses */
+    memory_region_add_subregion(system_memory,
+                                VBE_DISPI_LFB_PHYSICAL_ADDRESS,
+                                &s->vram);
+    s->vbe_mapped = 1;
+#endif 
+}
 /********************************************************/
 /* vga screen dump */
 
@@ -2321,7 +2334,6 @@ static void vga_save_dpy_update(DisplayState *ds,
 {
     if (screen_dump_filename) {
         ppm_save(screen_dump_filename, ds->surface);
-        screen_dump_filename = NULL;
     }
 }
 
@@ -2340,15 +2352,19 @@ int ppm_save(const char *filename, struct DisplaySurface *ds)
     uint32_t v;
     int y, x;
     uint8_t r, g, b;
+    int ret;
+    char *linebuf, *pbuf;
 
     f = fopen(filename, "wb");
     if (!f)
         return -1;
     fprintf(f, "P6\n%d %d\n%d\n",
             ds->width, ds->height, 255);
+    linebuf = g_malloc(ds->width * 3);
     d1 = ds->data;
     for(y = 0; y < ds->height; y++) {
         d = d1;
+        pbuf = linebuf;
         for(x = 0; x < ds->width; x++) {
             if (ds->pf.bits_per_pixel == 32)
                 v = *(uint32_t *)d;
@@ -2360,13 +2376,16 @@ int ppm_save(const char *filename, struct DisplaySurface *ds)
                 (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);
+            *pbuf++ = r;
+            *pbuf++ = g;
+            *pbuf++ = b;
             d += ds->pf.bytes_per_pixel;
         }
         d1 += ds->linesize;
+        ret = fwrite(linebuf, 1, pbuf - linebuf, f);
+        (void)ret;
     }
+    g_free(linebuf);
     fclose(f);
     return 0;
 }
@@ -2375,7 +2394,7 @@ static DisplayChangeListener* vga_screen_dump_init(DisplayState *ds)
 {
     DisplayChangeListener *dcl;
 
-    dcl = qemu_mallocz(sizeof(DisplayChangeListener));
+    dcl = g_malloc0(sizeof(DisplayChangeListener));
     dcl->dpy_update = vga_save_dpy_update;
     dcl->dpy_resize = vga_save_dpy_resize;
     dcl->dpy_refresh = vga_save_dpy_refresh;
@@ -2392,8 +2411,8 @@ static void vga_screen_dump(void *opaque, const char *filename)
     if (!screen_dump_dcl)
         screen_dump_dcl = vga_screen_dump_init(s->ds);
 
-    screen_dump_filename = (char *)filename;
+    screen_dump_filename = filename;
     vga_invalidate_display(s);
     vga_hw_update();
+    screen_dump_filename = NULL;
 }
-
This page took 0.053096 seconds and 4 git commands to generate.