mips bios loading fix
[qemu] / hw / vga.c
index db9e74f..b4eacc3 100644 (file)
--- a/hw/vga.c
+++ b/hw/vga.c
 //#define DEBUG_VGA_MEM
 //#define DEBUG_VGA_REG
 
-//#define DEBUG_S3
 //#define DEBUG_BOCHS_VBE
 
-/* S3 VGA is deprecated - another graphic card will be emulated */
-//#define CONFIG_S3VGA
-
 /* force some bits to zero */
 const uint8_t sr_mask[8] = {
     (uint8_t)~0xfc,
@@ -150,6 +146,8 @@ static uint8_t expand4to8[16];
 VGAState *vga_state;
 int vga_io_memory;
 
+static void vga_screen_dump(void *opaque, const char *filename);
+
 static uint32_t vga_ioport_read(void *opaque, uint32_t addr)
 {
     VGAState *s = opaque;
@@ -225,11 +223,6 @@ static uint32_t vga_ioport_read(void *opaque, uint32_t addr)
 #ifdef DEBUG_VGA_REG
             printf("vga: read CR%x = 0x%02x\n", s->cr_index, val);
 #endif
-#ifdef DEBUG_S3
-            if (s->cr_index >= 0x20)
-                printf("S3: CR read index=0x%x val=0x%x\n",
-                       s->cr_index, val);
-#endif
             break;
         case 0x3ba:
         case 0x3da:
@@ -359,43 +352,10 @@ static void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
         case 0x12: /* veritcal display end */
             s->cr[s->cr_index] = val;
             break;
-
-#ifdef CONFIG_S3VGA
-            /* S3 registers */
-        case 0x2d:
-        case 0x2e:
-        case 0x2f:
-        case 0x30:
-            /* chip ID, cannot write */
-            break;
-        case 0x31:
-            /* update start address */
-            {
-                int v;
-                s->cr[s->cr_index] = val;
-                v = (val >> 4) & 3;
-                s->cr[0x69] = (s->cr[69] & ~0x03) | v;
-            }
-            break;
-        case 0x51:
-            /* update start address */
-            {
-                int v;
-                s->cr[s->cr_index] = val;
-                v = val & 3;
-                s->cr[0x69] = (s->cr[69] & ~0x0c) | (v << 2);
-            }
-            break;
-#endif
         default:
             s->cr[s->cr_index] = val;
             break;
         }
-#ifdef DEBUG_S3
-        if (s->cr_index >= 0x20)
-            printf("S3: CR write index=0x%x val=0x%x\n",
-                   s->cr_index, val);
-#endif
         break;
     case 0x3ba:
     case 0x3da:
@@ -848,6 +808,11 @@ static inline unsigned int rgb_to_pixel32(unsigned int r, unsigned int g, unsign
     return (r << 16) | (g << 8) | b;
 }
 
+static inline unsigned int rgb_to_pixel32bgr(unsigned int r, unsigned int g, unsigned b)
+{
+    return (b << 16) | (g << 8) | r;
+}
+
 #define DEPTH 8
 #include "vga_template.h"
 
@@ -860,6 +825,10 @@ static inline unsigned int rgb_to_pixel32(unsigned int r, unsigned int g, unsign
 #define DEPTH 32
 #include "vga_template.h"
 
+#define BGR_FORMAT
+#define DEPTH 32
+#include "vga_template.h"
+
 static unsigned int rgb_to_pixel8_dup(unsigned int r, unsigned int g, unsigned b)
 {
     unsigned int col;
@@ -892,6 +861,13 @@ static unsigned int rgb_to_pixel32_dup(unsigned int r, unsigned int g, unsigned
     return col;
 }
 
+static unsigned int rgb_to_pixel32bgr_dup(unsigned int r, unsigned int g, unsigned b)
+{
+    unsigned int col;
+    col = rgb_to_pixel32bgr(r, g, b);
+    return col;
+}
+
 /* return true if the palette was modified */
 static int update_palette16(VGAState *s)
 {
@@ -954,22 +930,10 @@ static void vga_get_offsets(VGAState *s,
     {  
         /* compute line_offset in bytes */
         line_offset = s->cr[0x13];
-#ifdef CONFIG_S3VGA
-        {
-            uinr32_t v;
-            v = (s->cr[0x51] >> 4) & 3; /* S3 extension */
-            if (v == 0)
-                v = (s->cr[0x43] >> 2) & 1; /* S3 extension */
-            line_offset |= (v << 8);
-        }
-#endif
         line_offset <<= 3;
-        
+
         /* starting address */
         start_addr = s->cr[0x0d] | (s->cr[0x0c] << 8);
-#ifdef CONFIG_S3VGA
-        start_addr |= (s->cr[0x69] & 0x1f) << 16; /* S3 extension */
-#endif
     }
     *pline_offset = line_offset;
     *pstart_addr = start_addr;
@@ -1000,9 +964,11 @@ static int update_basic_params(VGAState *s)
     return full_update;
 }
 
-static inline int get_depth_index(int depth)
+#define NB_DEPTHS 5
+
+static inline int get_depth_index(DisplayState *s)
 {
-    switch(depth) {
+    switch(s->depth) {
     default:
     case 8:
         return 0;
@@ -1011,29 +977,35 @@ static inline int get_depth_index(int depth)
     case 16:
         return 2;
     case 32:
-        return 3;
+        if (s->bgr)
+            return 4;
+        else
+            return 3;
     }
 }
 
-static vga_draw_glyph8_func *vga_draw_glyph8_table[4] = {
+static vga_draw_glyph8_func *vga_draw_glyph8_table[NB_DEPTHS] = {
     vga_draw_glyph8_8,
     vga_draw_glyph8_16,
     vga_draw_glyph8_16,
     vga_draw_glyph8_32,
+    vga_draw_glyph8_32,
 };
 
-static vga_draw_glyph8_func *vga_draw_glyph16_table[4] = {
+static vga_draw_glyph8_func *vga_draw_glyph16_table[NB_DEPTHS] = {
     vga_draw_glyph16_8,
     vga_draw_glyph16_16,
     vga_draw_glyph16_16,
     vga_draw_glyph16_32,
+    vga_draw_glyph16_32,
 };
 
-static vga_draw_glyph9_func *vga_draw_glyph9_table[4] = {
+static vga_draw_glyph9_func *vga_draw_glyph9_table[NB_DEPTHS] = {
     vga_draw_glyph9_8,
     vga_draw_glyph9_16,
     vga_draw_glyph9_16,
     vga_draw_glyph9_32,
+    vga_draw_glyph9_32,
 };
     
 static const uint8_t cursor_glyph[32 * 4] = {
@@ -1155,7 +1127,7 @@ static void vga_draw_text(VGAState *s, int full_update)
     }
     cursor_ptr = s->vram_ptr + (s->start_addr + cursor_offset) * 4;
     
-    depth_index = get_depth_index(s->ds->depth);
+    depth_index = get_depth_index(s->ds);
     if (cw == 16)
         vga_draw_glyph8 = vga_draw_glyph16_table[depth_index];
     else
@@ -1248,56 +1220,76 @@ enum {
     VGA_DRAW_LINE_NB,
 };
 
-static vga_draw_line_func *vga_draw_line_table[4 * VGA_DRAW_LINE_NB] = {
+static vga_draw_line_func *vga_draw_line_table[NB_DEPTHS * VGA_DRAW_LINE_NB] = {
     vga_draw_line2_8,
     vga_draw_line2_16,
     vga_draw_line2_16,
     vga_draw_line2_32,
+    vga_draw_line2_32,
 
     vga_draw_line2d2_8,
     vga_draw_line2d2_16,
     vga_draw_line2d2_16,
     vga_draw_line2d2_32,
+    vga_draw_line2d2_32,
 
     vga_draw_line4_8,
     vga_draw_line4_16,
     vga_draw_line4_16,
     vga_draw_line4_32,
+    vga_draw_line4_32,
 
     vga_draw_line4d2_8,
     vga_draw_line4d2_16,
     vga_draw_line4d2_16,
     vga_draw_line4d2_32,
+    vga_draw_line4d2_32,
 
     vga_draw_line8d2_8,
     vga_draw_line8d2_16,
     vga_draw_line8d2_16,
     vga_draw_line8d2_32,
+    vga_draw_line8d2_32,
 
     vga_draw_line8_8,
     vga_draw_line8_16,
     vga_draw_line8_16,
     vga_draw_line8_32,
+    vga_draw_line8_32,
 
     vga_draw_line15_8,
     vga_draw_line15_15,
     vga_draw_line15_16,
     vga_draw_line15_32,
+    vga_draw_line15_32bgr,
 
     vga_draw_line16_8,
     vga_draw_line16_15,
     vga_draw_line16_16,
     vga_draw_line16_32,
+    vga_draw_line16_32bgr,
 
     vga_draw_line24_8,
     vga_draw_line24_15,
     vga_draw_line24_16,
     vga_draw_line24_32,
+    vga_draw_line24_32bgr,
 
     vga_draw_line32_8,
     vga_draw_line32_15,
     vga_draw_line32_16,
     vga_draw_line32_32,
+    vga_draw_line32_32bgr,
+};
+
+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] = {
+    rgb_to_pixel8_dup,
+    rgb_to_pixel15_dup,
+    rgb_to_pixel16_dup,
+    rgb_to_pixel32_dup,
+    rgb_to_pixel32bgr_dup,
 };
 
 static int vga_get_bpp(VGAState *s)
@@ -1414,7 +1406,7 @@ static void vga_draw_graphic(VGAState *s, int full_update)
             break;
         }
     }
-    vga_draw_line = vga_draw_line_table[v * 4 + get_depth_index(s->ds->depth)];
+    vga_draw_line = vga_draw_line_table[v * NB_DEPTHS + get_depth_index(s->ds)];
 
     if (disp_width != s->last_width ||
         height != s->last_height) {
@@ -1454,11 +1446,13 @@ static void vga_draw_graphic(VGAState *s, int full_update)
         }
         page0 = s->vram_offset + (addr & TARGET_PAGE_MASK);
         page1 = s->vram_offset + ((addr + bwidth - 1) & TARGET_PAGE_MASK);
-        update = full_update | cpu_physical_memory_is_dirty(page0) |
-            cpu_physical_memory_is_dirty(page1);
+        update = full_update | 
+            cpu_physical_memory_get_dirty(page0, VGA_DIRTY_FLAG) |
+            cpu_physical_memory_get_dirty(page1, VGA_DIRTY_FLAG);
         if ((page1 - page0) > TARGET_PAGE_SIZE) {
             /* if wide line, can use another page */
-            update |= cpu_physical_memory_is_dirty(page0 + TARGET_PAGE_SIZE);
+            update |= cpu_physical_memory_get_dirty(page0 + TARGET_PAGE_SIZE, 
+                                                    VGA_DIRTY_FLAG);
         }
         /* explicit invalidation for the hardware cursor */
         update |= (s->invalidated_y_table[y >> 5] >> (y & 0x1f)) & 1;
@@ -1501,7 +1495,8 @@ static void vga_draw_graphic(VGAState *s, int full_update)
     }
     /* reset modified pages */
     if (page_max != -1) {
-        cpu_physical_memory_reset_dirty(page_min, page_max + TARGET_PAGE_SIZE);
+        cpu_physical_memory_reset_dirty(page_min, page_max + TARGET_PAGE_SIZE,
+                                        VGA_DIRTY_FLAG);
     }
     memset(s->invalidated_y_table, 0, ((height + 31) >> 5) * 4);
 }
@@ -1533,29 +1528,16 @@ static void vga_draw_blank(VGAState *s, int full_update)
 #define GMODE_GRAPH    1
 #define GMODE_BLANK 2 
 
-void vga_update_display(void)
+static void vga_update_display(void *opaque)
 {
-    VGAState *s = vga_state;
+    VGAState *s = (VGAState *)opaque;
     int full_update, graphic_mode;
 
     if (s->ds->depth == 0) {
         /* nothing to do */
     } else {
-        switch(s->ds->depth) {
-        case 8:
-            s->rgb_to_pixel = rgb_to_pixel8_dup;
-            break;
-        case 15:
-            s->rgb_to_pixel = rgb_to_pixel15_dup;
-            break;
-        default:
-        case 16:
-            s->rgb_to_pixel = rgb_to_pixel16_dup;
-            break;
-        case 32:
-            s->rgb_to_pixel = rgb_to_pixel32_dup;
-            break;
-        }
+        s->rgb_to_pixel = 
+            rgb_to_pixel_dup_table[get_depth_index(s->ds)];
         
         full_update = 0;
         if (!(s->ar_index & 0x20)) {
@@ -1583,9 +1565,9 @@ void vga_update_display(void)
 }
 
 /* force a full display refresh */
-void vga_invalidate_display(void)
+static void vga_invalidate_display(void *opaque)
 {
-    VGAState *s = vga_state;
+    VGAState *s = (VGAState *)opaque;
     
     s->last_width = -1;
     s->last_height = -1;
@@ -1594,13 +1576,6 @@ void vga_invalidate_display(void)
 static void vga_reset(VGAState *s)
 {
     memset(s, 0, sizeof(VGAState));
-#ifdef CONFIG_S3VGA
-    /* chip ID for 8c968 */
-    s->cr[0x2d] = 0x88;
-    s->cr[0x2e] = 0xb0;
-    s->cr[0x2f] = 0x01; /* XXX: check revision code */
-    s->cr[0x30] = 0xe1;
-#endif
     s->graphic_mode = -1; /* force full update */
 }
 
@@ -1712,8 +1687,11 @@ static void vga_map(PCIDevice *pci_dev, int region_num,
                     uint32_t addr, uint32_t size, int type)
 {
     VGAState *s = vga_state;
-
-    cpu_register_physical_memory(addr, s->vram_size, s->vram_offset);
+    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);
+    }
 }
 
 void vga_common_init(VGAState *s, DisplayState *ds, uint8_t *vga_ram_base, 
@@ -1753,13 +1731,16 @@ void vga_common_init(VGAState *s, DisplayState *ds, uint8_t *vga_ram_base,
     s->get_bpp = vga_get_bpp;
     s->get_offsets = vga_get_offsets;
     s->get_resolution = vga_get_resolution;
+    graphic_console_init(s->ds, vga_update_display, vga_invalidate_display,
+                         vga_screen_dump, s);
     /* XXX: currently needed for display */
     vga_state = s;
 }
 
 
 int vga_initialize(PCIBus *bus, DisplayState *ds, uint8_t *vga_ram_base, 
-                   unsigned long vga_ram_offset, int vga_ram_size)
+                   unsigned long vga_ram_offset, int vga_ram_size,
+                   unsigned long vga_bios_offset, int vga_bios_size)
 {
     VGAState *s;
 
@@ -1834,6 +1815,17 @@ int vga_initialize(PCIBus *bus, DisplayState *ds, uint8_t *vga_ram_base,
         /* XXX: vga_ram_size must be a power of two */
         pci_register_io_region(d, 0, vga_ram_size, 
                                PCI_ADDRESS_SPACE_MEM_PREFETCH, vga_map);
+        if (vga_bios_size != 0) {
+            unsigned int bios_total_size;
+            s->bios_offset = vga_bios_offset;
+            s->bios_size = vga_bios_size;
+            /* must be a power of two */
+            bios_total_size = 1;
+            while (bios_total_size < vga_bios_size)
+                bios_total_size <<= 1;
+            pci_register_io_region(d, PCI_ROM_SLOT, bios_total_size, 
+                                   PCI_ADDRESS_SPACE_MEM_PREFETCH, vga_map);
+        }
     } else {
 #ifdef CONFIG_BOCHS_VBE
         /* XXX: use optimized standard vga accesses */
@@ -1897,13 +1889,13 @@ static int ppm_save(const char *filename, uint8_t *data,
 
 /* save the vga display in a PPM image even if no display is
    available */
-void vga_screen_dump(const char *filename)
+static void vga_screen_dump(void *opaque, const char *filename)
 {
-    VGAState *s = vga_state;
+    VGAState *s = (VGAState *)opaque;
     DisplayState *saved_ds, ds1, *ds = &ds1;
     
     /* XXX: this is a little hackish */
-    vga_invalidate_display();
+    vga_invalidate_display(s);
     saved_ds = s->ds;
 
     memset(ds, 0, sizeof(DisplayState));
@@ -1914,7 +1906,7 @@ void vga_screen_dump(const char *filename)
 
     s->ds = ds;
     s->graphic_mode = -1;
-    vga_update_display();
+    vga_update_display(s);
     
     if (ds->data) {
         ppm_save(filename, ds->data, vga_save_w, vga_save_h,