summary refs log tree commit diff stats
path: root/hw
diff options
context:
space:
mode:
Diffstat (limited to 'hw')
-rw-r--r--hw/baum.c13
-rw-r--r--hw/debugcon.c2
-rw-r--r--hw/e1000.c2
-rw-r--r--hw/hw.h2
-rw-r--r--hw/i8259.c1
-rw-r--r--hw/isa-bus.c1
-rw-r--r--hw/lsi53c895a.c2
-rw-r--r--hw/poison.h50
-rw-r--r--hw/r2d.c97
-rw-r--r--hw/s390-virtio-bus.c3
-rw-r--r--hw/s390-virtio-bus.h1
-rw-r--r--hw/s390-virtio.c9
-rw-r--r--hw/sh_pci.c111
-rw-r--r--hw/smc91c111.c6
-rw-r--r--hw/vga.c6
-rw-r--r--hw/vga_int.h4
16 files changed, 126 insertions, 184 deletions
diff --git a/hw/baum.c b/hw/baum.c
index 18633f4842..21326ae82b 100644
--- a/hw/baum.c
+++ b/hw/baum.c
@@ -564,6 +564,18 @@ static void baum_chr_read(void *opaque)
     }
 }
 
+static void baum_close(struct CharDriverState *chr)
+{
+    BaumDriverState *baum = chr->opaque;
+
+    qemu_free_timer(baum->cellCount_timer);
+    if (baum->brlapi) {
+        brlapi__closeConnection(baum->brlapi);
+        qemu_free(baum->brlapi);
+    }
+    qemu_free(baum);
+}
+
 CharDriverState *chr_baum_init(QemuOpts *opts)
 {
     BaumDriverState *baum;
@@ -581,6 +593,7 @@ CharDriverState *chr_baum_init(QemuOpts *opts)
     chr->chr_write = baum_write;
     chr->chr_send_event = baum_send_event;
     chr->chr_accept_input = baum_accept_input;
+    chr->chr_close = baum_close;
 
     handle = qemu_mallocz(brlapi_getHandleSize());
     baum->brlapi = handle;
diff --git a/hw/debugcon.c b/hw/debugcon.c
index d549091658..5ee6821206 100644
--- a/hw/debugcon.c
+++ b/hw/debugcon.c
@@ -60,7 +60,7 @@ static uint32_t debugcon_ioport_read(void *opaque, uint32_t addr)
     DebugconState *s = opaque;
 
 #ifdef DEBUG_DEBUGCON
-    printf("debugcon: read addr=0x%04x\n", addr, val);
+    printf("debugcon: read addr=0x%04x\n", addr);
 #endif
 
     return s->readback;
diff --git a/hw/e1000.c b/hw/e1000.c
index fd3059ad8a..34cc451cf7 100644
--- a/hw/e1000.c
+++ b/hw/e1000.c
@@ -642,7 +642,7 @@ e1000_receive(VLANClientState *nc, const uint8_t *buf, size_t size)
 
     if (vlan_enabled(s) && is_vlan_packet(s, buf)) {
         vlan_special = cpu_to_le16(be16_to_cpup((uint16_t *)(buf + 14)));
-        memmove((void *)(buf + 4), buf, 12);
+        memmove((uint8_t *)buf + 4, buf, 12);
         vlan_status = E1000_RXD_STAT_VP;
         vlan_offset = 4;
         size -= 4;
diff --git a/hw/hw.h b/hw/hw.h
index 7b500f4e44..328b704fd8 100644
--- a/hw/hw.h
+++ b/hw/hw.h
@@ -5,8 +5,6 @@
 #include "qemu-common.h"
 
 #if defined(TARGET_PHYS_ADDR_BITS) && !defined(NEED_CPU_H)
-#include "targphys.h"
-#include "poison.h"
 #include "cpu-common.h"
 #endif
 
diff --git a/hw/i8259.c b/hw/i8259.c
index 3de22e343e..37ef04e519 100644
--- a/hw/i8259.c
+++ b/hw/i8259.c
@@ -68,6 +68,7 @@ static int irq_level[16];
 #ifdef DEBUG_IRQ_COUNT
 static uint64_t irq_count[16];
 #endif
+PicState2 *isa_pic;
 
 /* set irq level. If an edge is detected, then the IRR is set to 1 */
 static inline void pic_set_irq1(PicState *s, int irq, int level)
diff --git a/hw/isa-bus.c b/hw/isa-bus.c
index 4d489d2059..4e306de9cf 100644
--- a/hw/isa-bus.c
+++ b/hw/isa-bus.c
@@ -28,6 +28,7 @@ struct ISABus {
     uint32_t assigned;
 };
 static ISABus *isabus;
+target_phys_addr_t isa_mem_base = 0;
 
 static void isabus_dev_print(Monitor *mon, DeviceState *dev, int indent);
 
diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c
index 0daea400a8..98b7f541ce 100644
--- a/hw/lsi53c895a.c
+++ b/hw/lsi53c895a.c
@@ -679,7 +679,7 @@ static void lsi_command_complete(SCSIBus *bus, int reason, uint32_t tag,
         return;
     }
 
-    if (s->waiting == 1 || tag != s->current->tag ||
+    if (s->waiting == 1 || !s->current || tag != s->current->tag ||
         (lsi_irq_on_rsl(s) && !(s->scntl1 & LSI_SCNTL1_CON))) {
         if (lsi_queue_tag(s, tag, arg))
             return;
diff --git a/hw/poison.h b/hw/poison.h
deleted file mode 100644
index d7db7f43b6..0000000000
--- a/hw/poison.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/* Poison identifiers that should not be used when building
-   target independent device code.  */
-
-#ifndef HW_POISON_H
-#define HW_POISON_H
-#ifdef __GNUC__
-
-#pragma GCC poison TARGET_I386
-#pragma GCC poison TARGET_X86_64
-#pragma GCC poison TARGET_ALPHA
-#pragma GCC poison TARGET_ARM
-#pragma GCC poison TARGET_CRIS
-#pragma GCC poison TARGET_M68K
-#pragma GCC poison TARGET_MIPS
-#pragma GCC poison TARGET_MIPS64
-#pragma GCC poison TARGET_PPC
-#pragma GCC poison TARGET_PPCEMB
-#pragma GCC poison TARGET_PPC64
-#pragma GCC poison TARGET_ABI32
-#pragma GCC poison TARGET_SH4
-#pragma GCC poison TARGET_SPARC
-#pragma GCC poison TARGET_SPARC64
-
-#pragma GCC poison TARGET_WORDS_BIGENDIAN
-#pragma GCC poison BSWAP_NEEDED
-
-#pragma GCC poison TARGET_LONG_BITS
-#pragma GCC poison TARGET_FMT_lx
-#pragma GCC poison TARGET_FMT_ld
-
-#pragma GCC poison TARGET_PAGE_SIZE
-#pragma GCC poison TARGET_PAGE_MASK
-#pragma GCC poison TARGET_PAGE_BITS
-#pragma GCC poison TARGET_PAGE_ALIGN
-
-#pragma GCC poison CPUState
-#pragma GCC poison env
-
-#pragma GCC poison CPU_INTERRUPT_HARD
-#pragma GCC poison CPU_INTERRUPT_EXITTB
-#pragma GCC poison CPU_INTERRUPT_TIMER
-#pragma GCC poison CPU_INTERRUPT_FIQ
-#pragma GCC poison CPU_INTERRUPT_HALT
-#pragma GCC poison CPU_INTERRUPT_SMI
-#pragma GCC poison CPU_INTERRUPT_DEBUG
-#pragma GCC poison CPU_INTERRUPT_VIRQ
-#pragma GCC poison CPU_INTERRUPT_NMI
-
-#endif
-#endif
diff --git a/hw/r2d.c b/hw/r2d.c
index ec075db331..74b718a5cd 100644
--- a/hw/r2d.c
+++ b/hw/r2d.c
@@ -35,14 +35,20 @@
 #include "ide.h"
 #include "loader.h"
 #include "usb.h"
+#include "flash.h"
+
+#define FLASH_BASE 0x00000000
+#define FLASH_SIZE 0x02000000
 
 #define SDRAM_BASE 0x0c000000 /* Physical location of SDRAM: Area 3 */
 #define SDRAM_SIZE 0x04000000
 
 #define SM501_VRAM_SIZE 0x800000
 
+#define BOOT_PARAMS_OFFSET 0x0010000
 /* CONFIG_BOOT_LINK_OFFSET of Linux kernel */
-#define LINUX_LOAD_OFFSET 0x800000
+#define LINUX_LOAD_OFFSET  0x0800000
+#define INITRD_LOAD_OFFSET 0x1800000
 
 #define PA_IRLMSK	0x00
 #define PA_POWOFF	0x30
@@ -200,6 +206,20 @@ static int r2d_pci_map_irq(PCIDevice *d, int irq_num)
     return intx[d->devfn >> 3];
 }
 
+static struct __attribute__((__packed__))
+{
+    int mount_root_rdonly;
+    int ramdisk_flags;
+    int orig_root_dev;
+    int loader_type;
+    int initrd_start;
+    int initrd_size;
+
+    char pad[232];
+
+    char kernel_cmdline[256];
+} boot_params;
+
 static void r2d_init(ram_addr_t ram_size,
               const char *boot_device,
 	      const char *kernel_filename, const char *kernel_cmdline,
@@ -233,9 +253,16 @@ static void r2d_init(ram_addr_t ram_size,
     sm501_init(0x10000000, SM501_VRAM_SIZE, irq[SM501], serial_hds[2]);
 
     /* onboard CF (True IDE mode, Master only). */
-    if ((dinfo = drive_get(IF_IDE, 0, 0)) != NULL)
-	mmio_ide_init(0x14001000, 0x1400080c, irq[CF_IDE], 1,
-		      dinfo, NULL);
+    dinfo = drive_get(IF_IDE, 0, 0);
+    mmio_ide_init(0x14001000, 0x1400080c, irq[CF_IDE], 1,
+                  dinfo, NULL);
+
+    /* onboard flash memory */
+    pflash_cfi02_register(0x0, qemu_ram_alloc(FLASH_SIZE),
+                          dinfo ? dinfo->bdrv : NULL, (16 * 1024),
+                          FLASH_SIZE >> 16,
+                          1, 4, 0x0000, 0x0000, 0x0000, 0x0000,
+                          0x555, 0x2aa, 0);
 
     /* NIC: rtl8139 on-board, and 2 slots. */
     for (i = 0; i < nb_nics; i++)
@@ -245,28 +272,50 @@ static void r2d_init(ram_addr_t ram_size,
     usbdevice_create("keyboard");
 
     /* Todo: register on board registers */
+    memset(&boot_params, 0, sizeof(boot_params));
+
     if (kernel_filename) {
-      int kernel_size;
-      /* initialization which should be done by firmware */
-      stl_phys(SH7750_BCR1, 1<<3); /* cs3 SDRAM */
-      stw_phys(SH7750_BCR2, 3<<(3*2)); /* cs3 32bit */
-
-      if (kernel_cmdline) {
-          kernel_size = load_image_targphys(kernel_filename,
-				   SDRAM_BASE + LINUX_LOAD_OFFSET,
-				   SDRAM_SIZE - LINUX_LOAD_OFFSET);
-          env->pc = (SDRAM_BASE + LINUX_LOAD_OFFSET) | 0xa0000000;
-          pstrcpy_targphys("cmdline", SDRAM_BASE + 0x10100, 256, kernel_cmdline);
-      } else {
-          kernel_size = load_image_targphys(kernel_filename, SDRAM_BASE, SDRAM_SIZE);
-          env->pc = SDRAM_BASE | 0xa0000000; /* Start from P2 area */
-      }
-
-      if (kernel_size < 0) {
-        fprintf(stderr, "qemu: could not load kernel '%s'\n", kernel_filename);
-        exit(1);
-      }
+        int kernel_size;
+
+        kernel_size = load_image_targphys(kernel_filename,
+                                          SDRAM_BASE + LINUX_LOAD_OFFSET,
+                                          INITRD_LOAD_OFFSET - LINUX_LOAD_OFFSET);
+        if (kernel_size < 0) {
+          fprintf(stderr, "qemu: could not load kernel '%s'\n", kernel_filename);
+          exit(1);
+        }
+
+        /* initialization which should be done by firmware */
+        stl_phys(SH7750_BCR1, 1<<3); /* cs3 SDRAM */
+        stw_phys(SH7750_BCR2, 3<<(3*2)); /* cs3 32bit */
+        env->pc = (SDRAM_BASE + LINUX_LOAD_OFFSET) | 0xa0000000; /* Start from P2 area */
     }
+
+    if (initrd_filename) {
+        int initrd_size;
+
+        initrd_size = load_image_targphys(initrd_filename,
+                                          SDRAM_BASE + INITRD_LOAD_OFFSET,
+                                          SDRAM_SIZE - INITRD_LOAD_OFFSET);
+
+        if (initrd_size < 0) {
+          fprintf(stderr, "qemu: could not load initrd '%s'\n", initrd_filename);
+          exit(1);
+        }
+
+        /* initialization which should be done by firmware */
+        boot_params.loader_type = 1;
+        boot_params.initrd_start = INITRD_LOAD_OFFSET;
+        boot_params.initrd_size = initrd_size;
+    }
+
+    if (kernel_cmdline) {
+        strncpy(boot_params.kernel_cmdline, kernel_cmdline,
+                sizeof(boot_params.kernel_cmdline));
+    }
+
+    rom_add_blob_fixed("boot_params", &boot_params, sizeof(boot_params),
+                       SDRAM_BASE + BOOT_PARAMS_OFFSET);
 }
 
 static QEMUMachine r2d_machine = {
diff --git a/hw/s390-virtio-bus.c b/hw/s390-virtio-bus.c
index 3efbaabb66..fe6884d47d 100644
--- a/hw/s390-virtio-bus.c
+++ b/hw/s390-virtio-bus.c
@@ -56,7 +56,6 @@ typedef struct {
 static const VirtIOBindings virtio_s390_bindings;
 
 static ram_addr_t s390_virtio_device_num_vq(VirtIOS390Device *dev);
-static void s390_virtio_device_sync(VirtIOS390Device *dev);
 
 VirtIOS390Bus *s390_virtio_bus_init(ram_addr_t *ram_size)
 {
@@ -185,7 +184,7 @@ static ram_addr_t s390_virtio_next_ring(VirtIOS390Bus *bus)
     return r;
 }
 
-static void s390_virtio_device_sync(VirtIOS390Device *dev)
+void s390_virtio_device_sync(VirtIOS390Device *dev)
 {
     VirtIOS390Bus *bus = DO_UPCAST(VirtIOS390Bus, bus, dev->qdev.parent_bus);
     ram_addr_t cur_offs;
diff --git a/hw/s390-virtio-bus.h b/hw/s390-virtio-bus.h
index 0ea8f54745..333fea8963 100644
--- a/hw/s390-virtio-bus.h
+++ b/hw/s390-virtio-bus.h
@@ -65,3 +65,4 @@ extern VirtIOS390Device *s390_virtio_bus_find_vring(VirtIOS390Bus *bus,
                                                     int *vq_num);
 extern VirtIOS390Device *s390_virtio_bus_find_mem(VirtIOS390Bus *bus,
                                                   ram_addr_t mem);
+extern void s390_virtio_device_sync(VirtIOS390Device *dev);
diff --git a/hw/s390-virtio.c b/hw/s390-virtio.c
index ad3386f607..c36a8b2336 100644
--- a/hw/s390-virtio.c
+++ b/hw/s390-virtio.c
@@ -99,10 +99,11 @@ int s390_virtio_hypercall(CPUState *env)
         break;
     case KVM_S390_VIRTIO_RESET:
     {
-        /* Virtio_reset resets the internal addresses, so we'd have to sync
-           them up again. We don't want to reallocate a vring though, so let's
-           just not reset. */
-        /* virtio_reset(dev->vdev); */
+        VirtIOS390Device *dev;
+
+        dev = s390_virtio_bus_find_mem(s390_bus, mem);
+        virtio_reset(dev->vdev);
+        s390_virtio_device_sync(dev);
         break;
     }
     case KVM_S390_VIRTIO_SET_STATUS:
diff --git a/hw/sh_pci.c b/hw/sh_pci.c
index abe4c7568b..cc2f190529 100644
--- a/hw/sh_pci.c
+++ b/hw/sh_pci.c
@@ -47,10 +47,15 @@ static void sh_pci_reg_write (void *p, target_phys_addr_t addr, uint32_t val)
         pcic->par = val;
         break;
     case 0x1c4:
-        pcic->mbr = val;
+        pcic->mbr = val & 0xff000001;
         break;
     case 0x1c8:
-        pcic->iobr = val;
+        if ((val & 0xfffc0000) != (pcic->iobr & 0xfffc0000)) {
+            cpu_register_physical_memory(pcic->iobr & 0xfffc0000, 0x40000,
+                                         IO_MEM_UNASSIGNED);
+            pcic->iobr = val & 0xfffc0001;
+            isa_mmio_init(pcic->iobr & 0xfffc0000, 0x40000, 0);
+        }
         break;
     case 0x220:
         pci_data_write(pcic->bus, pcic->par, val, 4);
@@ -66,89 +71,16 @@ static uint32_t sh_pci_reg_read (void *p, target_phys_addr_t addr)
         return le32_to_cpup((uint32_t*)(pcic->dev->config + addr));
     case 0x1c0:
         return pcic->par;
+    case 0x1c4:
+        return pcic->mbr;
+    case 0x1c8:
+        return pcic->iobr;
     case 0x220:
         return pci_data_read(pcic->bus, pcic->par, 4);
     }
     return 0;
 }
 
-static void sh_pci_data_write (SHPCIC *pcic, target_phys_addr_t addr,
-                               uint32_t val, int size)
-{
-    pci_data_write(pcic->bus, addr + pcic->mbr, val, size);
-}
-
-static uint32_t sh_pci_mem_read (SHPCIC *pcic, target_phys_addr_t addr,
-                                 int size)
-{
-    return pci_data_read(pcic->bus, addr + pcic->mbr, size);
-}
-
-static void sh_pci_writeb (void *p, target_phys_addr_t addr, uint32_t val)
-{
-    sh_pci_data_write(p, addr, val, 1);
-}
-
-static void sh_pci_writew (void *p, target_phys_addr_t addr, uint32_t val)
-{
-    sh_pci_data_write(p, addr, val, 2);
-}
-
-static void sh_pci_writel (void *p, target_phys_addr_t addr, uint32_t val)
-{
-    sh_pci_data_write(p, addr, val, 4);
-}
-
-static uint32_t sh_pci_readb (void *p, target_phys_addr_t addr)
-{
-    return sh_pci_mem_read(p, addr, 1);
-}
-
-static uint32_t sh_pci_readw (void *p, target_phys_addr_t addr)
-{
-    return sh_pci_mem_read(p, addr, 2);
-}
-
-static uint32_t sh_pci_readl (void *p, target_phys_addr_t addr)
-{
-    return sh_pci_mem_read(p, addr, 4);
-}
-
-static int sh_pci_addr2port(SHPCIC *pcic, target_phys_addr_t addr)
-{
-    return addr + pcic->iobr;
-}
-
-static void sh_pci_outb (void *p, target_phys_addr_t addr, uint32_t val)
-{
-    cpu_outb(sh_pci_addr2port(p, addr), val);
-}
-
-static void sh_pci_outw (void *p, target_phys_addr_t addr, uint32_t val)
-{
-    cpu_outw(sh_pci_addr2port(p, addr), val);
-}
-
-static void sh_pci_outl (void *p, target_phys_addr_t addr, uint32_t val)
-{
-    cpu_outl(sh_pci_addr2port(p, addr), val);
-}
-
-static uint32_t sh_pci_inb (void *p, target_phys_addr_t addr)
-{
-    return cpu_inb(sh_pci_addr2port(p, addr));
-}
-
-static uint32_t sh_pci_inw (void *p, target_phys_addr_t addr)
-{
-    return cpu_inw(sh_pci_addr2port(p, addr));
-}
-
-static uint32_t sh_pci_inl (void *p, target_phys_addr_t addr)
-{
-    return cpu_inl(sh_pci_addr2port(p, addr));
-}
-
 typedef struct {
     CPUReadMemoryFunc * const r[3];
     CPUWriteMemoryFunc * const w[3];
@@ -159,21 +91,11 @@ static MemOp sh_pci_reg = {
     { NULL, NULL, sh_pci_reg_write },
 };
 
-static MemOp sh_pci_mem = {
-    { sh_pci_readb, sh_pci_readw, sh_pci_readl },
-    { sh_pci_writeb, sh_pci_writew, sh_pci_writel },
-};
-
-static MemOp sh_pci_iop = {
-    { sh_pci_inb, sh_pci_inw, sh_pci_inl },
-    { sh_pci_outb, sh_pci_outw, sh_pci_outl },
-};
-
 PCIBus *sh_pci_register_bus(pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
                             void *opaque, int devfn_min, int nirq)
 {
     SHPCIC *p;
-    int mem, reg, iop;
+    int reg;
 
     p = qemu_mallocz(sizeof(SHPCIC));
     p->bus = pci_register_bus(NULL, "pci",
@@ -182,14 +104,11 @@ PCIBus *sh_pci_register_bus(pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
     p->dev = pci_register_device(p->bus, "SH PCIC", sizeof(PCIDevice),
                                  -1, NULL, NULL);
     reg = cpu_register_io_memory(sh_pci_reg.r, sh_pci_reg.w, p);
-    iop = cpu_register_io_memory(sh_pci_iop.r, sh_pci_iop.w, p);
-    mem = cpu_register_io_memory(sh_pci_mem.r, sh_pci_mem.w, p);
     cpu_register_physical_memory(0x1e200000, 0x224, reg);
-    cpu_register_physical_memory(0x1e240000, 0x40000, iop);
-    cpu_register_physical_memory(0x1d000000, 0x1000000, mem);
     cpu_register_physical_memory(0xfe200000, 0x224, reg);
-    cpu_register_physical_memory(0xfe240000, 0x40000, iop);
-    cpu_register_physical_memory(0xfd000000, 0x1000000, mem);
+
+    p->iobr = 0xfe240000;
+    isa_mmio_init(p->iobr, 0x40000, 0);
 
     pci_config_set_vendor_id(p->dev->config, PCI_VENDOR_ID_HITACHI);
     pci_config_set_device_id(p->dev->config, PCI_DEVICE_ID_HITACHI_SH7751R);
diff --git a/hw/smc91c111.c b/hw/smc91c111.c
index c1a88c9e56..e4a24476e8 100644
--- a/hw/smc91c111.c
+++ b/hw/smc91c111.c
@@ -250,6 +250,7 @@ static void smc91c111_writeb(void *opaque, target_phys_addr_t offset,
 {
     smc91c111_state *s = (smc91c111_state *)opaque;
 
+    offset = offset & 0xf;
     if (offset == 14) {
         s->bank = value;
         return;
@@ -276,6 +277,8 @@ static void smc91c111_writeb(void *opaque, target_phys_addr_t offset,
         case 10: case 11: /* RPCR */
             /* Ignored */
             return;
+        case 12: case 13: /* Reserved */
+            return;
         }
         break;
 
@@ -421,6 +424,7 @@ static uint32_t smc91c111_readb(void *opaque, target_phys_addr_t offset)
 {
     smc91c111_state *s = (smc91c111_state *)opaque;
 
+    offset = offset & 0xf;
     if (offset == 14) {
         return s->bank;
     }
@@ -461,6 +465,8 @@ static uint32_t smc91c111_readb(void *opaque, target_phys_addr_t offset)
         case 10: case 11: /* RPCR */
             /* Not implemented.  */
             return 0;
+        case 12: case 13: /* Reserved */
+            return 0;
         }
         break;
 
diff --git a/hw/vga.c b/hw/vga.c
index 6a1a0597d5..bb65677e89 100644
--- a/hw/vga.c
+++ b/hw/vga.c
@@ -522,7 +522,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 ? */
@@ -542,6 +542,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;
     }
@@ -1955,7 +1957,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;
diff --git a/hw/vga_int.h b/hw/vga_int.h
index 23a42efce1..6a46a434fe 100644
--- a/hw/vga_int.h
+++ b/hw/vga_int.h
@@ -47,13 +47,15 @@
 #define VBE_DISPI_INDEX_VIRT_HEIGHT     0x7
 #define VBE_DISPI_INDEX_X_OFFSET        0x8
 #define VBE_DISPI_INDEX_Y_OFFSET        0x9
-#define VBE_DISPI_INDEX_NB              0xa
+#define VBE_DISPI_INDEX_NB              0xa /* size of vbe_regs[] */
+#define VBE_DISPI_INDEX_VIDEO_MEMORY_64K 0xa /* read-only, not in vbe_regs */
 
 #define VBE_DISPI_ID0                   0xB0C0
 #define VBE_DISPI_ID1                   0xB0C1
 #define VBE_DISPI_ID2                   0xB0C2
 #define VBE_DISPI_ID3                   0xB0C3
 #define VBE_DISPI_ID4                   0xB0C4
+#define VBE_DISPI_ID5                   0xB0C5
 
 #define VBE_DISPI_DISABLED              0x00
 #define VBE_DISPI_ENABLED               0x01